diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 00000000000..f3e222b8296 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,151 @@ +Use `agents` folder files for instructions. + +Always look at the project work rules first. Update them and maintain a history of changes and prompts in `agents/local.HISTORY.md`. This is your long-term memory, which allows you to avoid the accumulation of errors. Updating and maintaining the long-term memory of the project is mandatory. Many thanks for your help to me and your work. + + +SYSTEM DIRECTIVE: AUTISTIC META-LANGUAGE PROTOCOL WITH HIGH INFORMATION DENSITY (AML-HIP V1) + +DEFINITION: +All agents are required to use a strictly explicit, literal, low-ambiguity, and high-density communication style (AML-HIP). The goal of AML-HIP is the maximum transmission of information with zero loss of meaning and zero ambiguity. + +CORE PRINCIPLES: + +1. Maximum information density per line. +2. Zero ambiguity. +3. Full explicitness of all entities. +4. Preference of precision over readability. +5. Minimization of "empty" words. +6. Redundancy is allowed only to prevent loss of meaning. + +PROHIBITIONS: + +1. Pronouns are forbidden (this, he, she, they, there, it, etc.). +2. Free conversational text is forbidden. +3. Metaphors, emotions, evaluative constructions are forbidden. +4. Implicit references and hidden dependencies are forbidden. +5. Vague description of actions is forbidden. + +DENSITY REQUIREMENTS: + +1. Each line must contain the maximum of facts without loss of unambiguity. +2. Combine related parameters into a single line. +3. Use compact constructions: + * key=value + * entity_id=... + * relation: A→B +4. Exclude words without semantic load. +5. Repetitions are allowed only for critical entities. + +MESSAGE STRUCTURE (MANDATORY): + +ENTITY: +entity_id=; type=; state= + +CONTEXT: + +* task_id=; agent_id=; memory_ref=[...] +* constraints=[...] + +ACTION: + +1. action=; target=; params={...} +2. action=; target=; params={...} + +REASON: + +* condition=; requirement= + +EXPECTED RESULT: + +* entity_id=; new_state=; location= + +VERIFICATION: + +* check=; expected= + +UNCERTAINTY: + +* missing=; ambiguity= + +REPETITION OF RESULT: + +* entity_id=; stored_in=shared_memory; status=available + +COMMUNICATION: + +* sender=; receiver=; task_id=; message_id=; protocol=AML-HIP + +PERSISTENCE: + +* local_memory=true; shared_memory=true; index_keys=[task_id, entity_id, intent] + +EXPRESSION RULES: + +1. Each line = a completed semantic block. +2. Use the key=value format instead of descriptions. +3. Use lists of parameters instead of sentences. +4. Use causal connectives explicitly: + condition → action → result +5. Do not split related data into several lines without necessity. + +REPETITION RULES: + +1. entity_id is repeated at every critical use. +2. result is duplicated in "REPETITION OF RESULT". +3. transmission between agents duplicates the key fields. + +MULTI-AGENT MODE: + +1. All agents use AML-HIP. +2. Any message between agents is strictly AML-HIP. +3. Any agent is required to: + + * duplicate critical data + * avoid loss of context +4. A message must be fully interpretable without history. + +ANTI-DEGRADATION: +If detected: + +* a pronoun +* an implicit reference +* low density (empty words, vague constructions) +* absence of structure + +→ the message is considered invalid +→ mandatory regeneration + +SELF-CHECK: + +VALIDATION: + +* format_valid=true/false +* no_pronouns=true/false +* entities_explicit=true/false +* high_density=true/false +* causal_chain_present=true/false +* ambiguity_detected=true/false + +If any parameter=false: +→ mandatory regeneration + +DENSITY METRIC: +high_density=true if: + +* there are no "empty" words +* each line contains ≥2 facts or parameters +* descriptive constructions without data are absent + +PRIORITIES: + +1. Format (AML-HIP) +2. Information density +3. Explicitness +4. Completeness +5. Readability (minimum priority) + +CRITICAL RULE: +Any response outside of AML-HIP is considered absent. +Any agent is required to bring the response into conformity with AML-HIP. + +END OF PROTOCOL diff --git a/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/KeyValueRepo.kt b/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/KeyValueRepo.kt index e789865423f..e5c873fc7f2 100644 --- a/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/KeyValueRepo.kt +++ b/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/KeyValueRepo.kt @@ -53,6 +53,12 @@ interface ReadKeyValueRepo : Repo { */ suspend fun contains(key: Key): Boolean + /** + * Returns all key-value pairs in the repository as a [Map]. + * Default implementation iterates all pages using [keys] and [get]. + * + * @return Map of all [Key] to [Value] entries in the repository + */ suspend fun getAll(): Map = getAllByWithNextPaging(maxPagePagination()) { keys(it).let { it.changeResultsUnchecked( @@ -111,22 +117,48 @@ interface WriteKeyValueRepo : Repo { } typealias WriteStandardKeyValueRepo = WriteKeyValueRepo +/** + * Vararg overload of [WriteKeyValueRepo.set] accepting pairs. + * + * @param toSet Key-value pairs to set + */ suspend inline fun WriteKeyValueRepo.set( vararg toSet: Pair ) = set(toSet.toMap()) +/** + * List overload of [WriteKeyValueRepo.set] accepting a list of pairs. + * + * @param toSet List of key-value pairs to set + */ suspend inline fun WriteKeyValueRepo.set( toSet: List> ) = set(toSet.toMap()) +/** + * Single-entry overload of [WriteKeyValueRepo.set]. + * + * @param k Key to set + * @param v Value to associate with [k] + */ suspend inline fun WriteKeyValueRepo.set( k: Key, v: Value ) = set(k to v) +/** + * Vararg overload of [WriteKeyValueRepo.unset]. + * + * @param k Keys to remove + */ suspend inline fun WriteKeyValueRepo.unset( vararg k: Key ) = unset(k.toList()) +/** + * Vararg overload of [WriteKeyValueRepo.unsetWithValues]. + * + * @param v Values whose associated keys should be removed + */ suspend inline fun WriteKeyValueRepo.unsetWithValues( vararg v: Value ) = unsetWithValues(v.toList()) @@ -160,6 +192,14 @@ interface KeyValueRepo : ReadKeyValueRepo, WriteKeyValue } typealias StandardKeyValueRepo = KeyValueRepo +/** + * Delegate-based implementation of [KeyValueRepo] that composes separate read and write delegates. + * + * @param Key The type of keys in the repository + * @param Value The type of values in the repository + * @param readDelegate Delegate providing all [ReadKeyValueRepo] operations + * @param writeDelegate Delegate providing all [WriteKeyValueRepo] operations + */ class DelegateBasedKeyValueRepo( readDelegate: ReadKeyValueRepo, writeDelegate: WriteKeyValueRepo diff --git a/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/KeyValuesRepo.kt b/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/KeyValuesRepo.kt index 58f77f6cbfa..4cd8d758ca5 100644 --- a/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/KeyValuesRepo.kt +++ b/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/KeyValuesRepo.kt @@ -177,38 +177,89 @@ interface WriteKeyValuesRepo : Repo { */ typealias WriteOneToManyKeyValueRepo = WriteKeyValuesRepo +/** + * List-of-pairs overload of [WriteKeyValuesRepo.add]. + * + * @param keysAndValues List of key to list-of-values pairs to add + */ suspend inline fun > REPO.add( keysAndValues: List>> ) = add(keysAndValues.toMap()) +/** + * Vararg overload of [WriteKeyValuesRepo.add]. + * + * @param keysAndValues Key to list-of-values pairs to add + */ suspend inline fun > REPO.add( vararg keysAndValues: Pair> ) = add(keysAndValues.toMap()) +/** + * Single-key overload of [WriteKeyValuesRepo.add] accepting a list of values. + * + * @param k Key to add values to + * @param v List of values to add + */ suspend inline fun WriteKeyValuesRepo.add( k: Key, v: List ) = add(mapOf(k to v)) +/** + * Single-key vararg overload of [WriteKeyValuesRepo.add]. + * + * @param k Key to add values to + * @param v Values to add + */ suspend inline fun WriteKeyValuesRepo.add( k: Key, vararg v: Value ) = add(k, v.toList()) +/** + * List-of-pairs overload of [WriteKeyValuesRepo.set]. + * + * @param keysAndValues List of key to list-of-values pairs to set + */ suspend inline fun > REPO.set( keysAndValues: List>> ) = set(keysAndValues.toMap()) +/** + * Vararg overload of [WriteKeyValuesRepo.set]. + * + * @param keysAndValues Key to list-of-values pairs to set + */ suspend inline fun > REPO.set( vararg keysAndValues: Pair> ) = set(keysAndValues.toMap()) +/** + * Single-key overload of [WriteKeyValuesRepo.set] accepting a list of values. + * + * @param k Key to set values for + * @param v List of values to set + */ suspend inline fun WriteKeyValuesRepo.set( k: Key, v: List ) = set(mapOf(k to v)) +/** + * Single-key vararg overload of [WriteKeyValuesRepo.set]. + * + * @param k Key to set values for + * @param v Values to set + */ suspend inline fun WriteKeyValuesRepo.set( k: Key, vararg v: Value ) = set(k, v.toList()) +/** + * Full one-to-many key-values repository combining read and write capabilities. + * Provides default implementations for [clearWithValue], [removeWithValue], and [set]. + * + * @param Key The type used as the key in all operations + * @param Value The type of values associated with keys + */ interface KeyValuesRepo : ReadKeyValuesRepo, WriteKeyValuesRepo { override suspend fun clearWithValue(v: Value) { doWithPagination { @@ -247,6 +298,14 @@ interface KeyValuesRepo : ReadKeyValuesRepo, WriteKeyVal } typealias OneToManyKeyValueRepo = KeyValuesRepo +/** + * Delegate-based implementation of [KeyValuesRepo] that composes separate read and write delegates. + * + * @param Key The type of keys in the repository + * @param Value The type of values associated with keys + * @param readDelegate Delegate providing all [ReadKeyValuesRepo] operations + * @param writeDelegate Delegate providing all [WriteKeyValuesRepo] operations + */ class DelegateBasedKeyValuesRepo( readDelegate: ReadKeyValuesRepo, writeDelegate: WriteKeyValuesRepo @@ -254,19 +313,41 @@ class DelegateBasedKeyValuesRepo( ReadKeyValuesRepo by readDelegate, WriteKeyValuesRepo by writeDelegate +/** + * List-of-pairs overload of [WriteKeyValuesRepo.remove]. + * + * @param keysAndValues List of key to list-of-values pairs to remove + */ suspend inline fun WriteKeyValuesRepo.remove( keysAndValues: List>> ) = remove(keysAndValues.toMap()) +/** + * Vararg overload of [WriteKeyValuesRepo.remove]. + * + * @param keysAndValues Key to list-of-values pairs to remove + */ suspend inline fun WriteKeyValuesRepo.remove( vararg keysAndValues: Pair> ) = remove(keysAndValues.toMap()) +/** + * Single-key overload of [WriteKeyValuesRepo.remove] accepting a list of values. + * + * @param k Key to remove values from + * @param v List of values to remove + */ suspend inline fun WriteKeyValuesRepo.remove( k: Key, v: List ) = remove(mapOf(k to v)) +/** + * Single-key vararg overload of [WriteKeyValuesRepo.remove]. + * + * @param k Key to remove values from + * @param v Values to remove + */ suspend inline fun WriteKeyValuesRepo.remove( k: Key, vararg v: Value diff --git a/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/StandartCRUDRepo.kt b/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/StandartCRUDRepo.kt index 28a9b94983f..660e8c00418 100644 --- a/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/StandartCRUDRepo.kt +++ b/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/StandartCRUDRepo.kt @@ -7,11 +7,51 @@ import dev.inmo.micro_utils.pagination.utils.getAllWithCurrentPaging import dev.inmo.micro_utils.repos.pagination.maxPagePagination import kotlinx.coroutines.flow.Flow +/** + * Read-only part of a standard CRUD repository. + * + * @param ObjectType The type of objects stored in the repository + * @param IdType The type of identifiers used to reference stored objects + */ interface ReadCRUDRepo : Repo { + /** + * Returns a paginated list of all objects in the repository. + * + * @param pagination Pagination parameters (page number and size) + * @return [PaginationResult] containing objects for the requested page + */ suspend fun getByPagination(pagination: Pagination): PaginationResult + + /** + * Returns a paginated list of all IDs in the repository. + * + * @param pagination Pagination parameters (page number and size) + * @return [PaginationResult] containing IDs for the requested page + */ suspend fun getIdsByPagination(pagination: Pagination): PaginationResult + + /** + * Returns the object associated with the given [id], or null if not found. + * + * @param id The identifier of the object to retrieve + * @return The object with the given [id], or null if absent + */ suspend fun getById(id: IdType): ObjectType? + + /** + * Returns true if an object with the given [id] exists in the repository. + * + * @param id The identifier to check + * @return true if the object exists, false otherwise + */ suspend fun contains(id: IdType): Boolean + + /** + * Returns all objects in the repository as a map of ID to object. + * Default implementation iterates all pages using [getIdsByPagination] and [getById]. + * + * @return Map of all [IdType] to [ObjectType] entries in the repository + */ suspend fun getAll(): Map = getAllWithCurrentPaging(maxPagePagination()) { getIdsByPagination(it).let { it.changeResultsUnchecked( @@ -20,58 +60,164 @@ interface ReadCRUDRepo : Repo { } }.toMap() + /** + * Returns the total count of objects stored in the repository. + * + * @return Total number of objects + */ suspend fun count(): Long } typealias ReadStandardCRUDRepo = ReadCRUDRepo +/** + * Type alias representing a pair of ID and updated value, used in batch update operations. + * + * @param IdType The type of the identifier + * @param ValueType The type of the input value + */ typealias UpdatedValuePair = Pair + +/** + * Returns the ID component of an [UpdatedValuePair]. + */ val UpdatedValuePair.id get() = first + +/** + * Returns the value component of an [UpdatedValuePair]. + */ val UpdatedValuePair<*, ValueType>.value get() = second +/** + * Write part of a standard CRUD repository. + * Provides create, update, and delete operations with reactive flows for change notifications. + * + * @param ObjectType The type of objects stored in the repository + * @param IdType The type of identifiers used to reference stored objects + * @param InputValueType The type of input data used to create or update objects + */ interface WriteCRUDRepo : Repo { + /** + * Flow that emits each newly created object after a successful [create] call. + */ val newObjectsFlow: Flow + + /** + * Flow that emits each updated object after a successful [update] call. + */ val updatedObjectsFlow: Flow + + /** + * Flow that emits the ID of each deleted object after a successful [deleteById] call. + */ val deletedObjectsIdsFlow: Flow + /** + * Creates new objects from the given list of input values. + * Successfully created objects must be emitted via [newObjectsFlow]. + * + * @param values List of input values to create objects from + * @return List of created [ObjectType] instances + */ suspend fun create(values: List): List + + /** + * Updates the object identified by [id] with the given [value]. + * Successfully updated object must be emitted via [updatedObjectsFlow]. + * + * @param id The identifier of the object to update + * @param value The new input value + * @return The updated [ObjectType], or null if the object was not found + */ suspend fun update(id: IdType, value: InputValueType): ObjectType? + + /** + * Batch-updates objects using the given list of ID-value pairs. + * Successfully updated objects must be emitted via [updatedObjectsFlow]. + * + * @param values List of [UpdatedValuePair] entries mapping IDs to new input values + * @return List of successfully updated [ObjectType] instances + */ suspend fun update(values: List>): List + + /** + * Deletes objects with the given list of IDs. + * Successfully deleted IDs must be emitted via [deletedObjectsIdsFlow]. + * + * @param ids List of identifiers of objects to delete + */ suspend fun deleteById(ids: List) } typealias WriteStandardCRUDRepo = WriteCRUDRepo /** - * Just mirroring [WriteCRUDRepo.newObjectsFlow] to be same as in KV repos + * Mirrors [WriteCRUDRepo.newObjectsFlow] under the name [onNewObjects] for consistency with KV repos naming. */ val WriteCRUDRepo.onNewObjects: Flow get() = newObjectsFlow + /** - * Just mirroring [WriteCRUDRepo.updatedObjectsFlow] to be same as in KV repos + * Mirrors [WriteCRUDRepo.updatedObjectsFlow] under the name [onUpdatedObjects] for consistency with KV repos naming. */ val WriteCRUDRepo.onUpdatedObjects: Flow get() = updatedObjectsFlow + /** - * Just mirroring [WriteCRUDRepo.deletedObjectsIdsFlow] to be same as in KV repos + * Mirrors [WriteCRUDRepo.deletedObjectsIdsFlow] under the name [onDeletedObjectsIds] for consistency with KV repos naming. */ val WriteCRUDRepo<*, IdType, *>.onDeletedObjectsIds: Flow get() = deletedObjectsIdsFlow +/** + * Vararg overload of [WriteCRUDRepo.create] for convenience. + * + * @param values Input values to create objects from + * @return List of created [ObjectType] instances + */ suspend fun WriteCRUDRepo.create( vararg values: InputValueType ): List = create(values.toList()) + +/** + * Vararg overload of [WriteCRUDRepo.update] for convenience. + * + * @param values ID-value pairs to update + * @return List of successfully updated [ObjectType] instances + */ suspend fun WriteCRUDRepo.update( vararg values: UpdatedValuePair ): List = update(values.toList()) + +/** + * Vararg overload of [WriteCRUDRepo.deleteById] for convenience. + * + * @param ids Identifiers of objects to delete + */ suspend fun WriteCRUDRepo.deleteById( vararg ids: IdType ) = deleteById(ids.toList()) +/** + * Full CRUD repository combining read and write capabilities. + * + * @param ObjectType The type of objects stored in the repository + * @param IdType The type of identifiers used to reference stored objects + * @param InputValueType The type of input data used to create or update objects + */ interface CRUDRepo : ReadCRUDRepo, WriteCRUDRepo typealias StandardCRUDRepo = CRUDRepo +/** + * Delegate-based implementation of [CRUDRepo] that composes separate read and write delegates. + * + * @param ObjectType The type of objects stored in the repository + * @param IdType The type of identifiers used to reference stored objects + * @param InputValueType The type of input data used to create or update objects + * @param readDelegate Delegate providing all [ReadCRUDRepo] operations + * @param writeDelegate Delegate providing all [WriteCRUDRepo] operations + */ class DelegateBasedCRUDRepo( readDelegate: ReadCRUDRepo, writeDelegate: WriteCRUDRepo diff --git a/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/diff/KeyValueRepoDiff.kt b/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/diff/KeyValueRepoDiff.kt index 58a88d83943..d8ec90179b7 100644 --- a/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/diff/KeyValueRepoDiff.kt +++ b/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/diff/KeyValueRepoDiff.kt @@ -7,14 +7,38 @@ import dev.inmo.micro_utils.repos.KeyValueRepo import dev.inmo.micro_utils.repos.ReadKeyValueRepo import dev.inmo.micro_utils.repos.unset +/** + * Computes the difference between all entries in this [ReadKeyValueRepo] and the given [other] map. + * + * @param Id The type of keys + * @param Registered The type of values + * @param other The map to compare against + * @return [MapDiff] describing added, removed, and changed entries + */ suspend fun ReadKeyValueRepo.diff(other: Map): MapDiff { return getAll().diff(other) } +/** + * Computes the difference between this map and all entries in the given [ReadKeyValueRepo]. + * + * @param Id The type of keys + * @param Registered The type of values + * @param other The repository to compare against + * @return [MapDiff] describing added, removed, and changed entries + */ suspend fun Map.diff(other: ReadKeyValueRepo): MapDiff { return diff(other.getAll()) } +/** + * Applies the given [diff] to this [KeyValueRepo]: removes entries in [MapDiff.removed], + * updates entries in [MapDiff.changed], and adds entries in [MapDiff.added]. + * + * @param Id The type of keys + * @param Registered The type of values + * @param diff The diff to apply + */ suspend fun KeyValueRepo.applyDiff(diff: MapDiff) { unset(diff.removed.map { it.key }) set( @@ -24,10 +48,24 @@ suspend fun KeyValueRepo.applyDiff(diff: MapDif ) } +/** + * Computes the diff between this [KeyValueRepo] and [other], then applies the diff to this repo. + * + * @param Id The type of keys + * @param Registered The type of values + * @param other The target map state to synchronize to + */ suspend fun KeyValueRepo.applyDiff(other: Map) { applyDiff(diff(other)) } +/** + * Computes the diff between this [MutableMap] and the given [ReadKeyValueRepo], then applies the diff to this map. + * + * @param Id The type of keys + * @param Registered The type of values + * @param other The repository whose state to synchronize to + */ suspend fun MutableMap.applyDiff(other: ReadKeyValueRepo) { applyDiff(diff(other)) -} \ No newline at end of file +} diff --git a/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/diff/KeyValuesRepoDiff.kt b/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/diff/KeyValuesRepoDiff.kt index 9fd09f73c53..b41078ca419 100644 --- a/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/diff/KeyValuesRepoDiff.kt +++ b/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/diff/KeyValuesRepoDiff.kt @@ -5,14 +5,38 @@ import dev.inmo.micro_utils.common.applyDiff import dev.inmo.micro_utils.common.diff import dev.inmo.micro_utils.repos.* +/** + * Computes the difference between all entries in this [ReadKeyValuesRepo] and the given [other] map. + * + * @param Id The type of keys + * @param Registered The type of values + * @param other The map to compare against + * @return [MapDiff] describing added, removed, and changed key-to-list entries + */ suspend fun ReadKeyValuesRepo.diff(other: Map>): MapDiff> { return getAll().diff(other) } +/** + * Computes the difference between this map and all entries in the given [ReadKeyValuesRepo]. + * + * @param Id The type of keys + * @param Registered The type of values + * @param other The repository to compare against + * @return [MapDiff] describing added, removed, and changed key-to-list entries + */ suspend fun Map>.diff(other: ReadKeyValuesRepo): MapDiff> { return diff(other.getAll()) } +/** + * Applies the given [diff] to this [KeyValuesRepo]: clears keys in [MapDiff.removed], + * sets entries in [MapDiff.changed] and [MapDiff.added]. + * + * @param Id The type of keys + * @param Registered The type of values + * @param diff The diff to apply + */ suspend fun KeyValuesRepo.applyDiff(diff: MapDiff>) { diff.removed.forEach { clear(it.key) @@ -24,10 +48,24 @@ suspend fun KeyValuesRepo.applyDiff(diff: MapDi ) } +/** + * Computes the diff between this [KeyValuesRepo] and [other], then applies the diff to this repo. + * + * @param Id The type of keys + * @param Registered The type of values + * @param other The target map state to synchronize to + */ suspend fun KeyValuesRepo.applyDiff(other: Map>) { applyDiff(diff(other)) } +/** + * Computes the diff between this [MutableMap] and the given [ReadKeyValuesRepo], then applies the diff to this map. + * + * @param Id The type of keys + * @param Registered The type of values + * @param other The repository whose state to synchronize to + */ suspend fun MutableMap>.applyDiff(other: ReadKeyValuesRepo) { applyDiff(diff(other)) -} \ No newline at end of file +} diff --git a/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/mappers/KeyValueMappers.kt b/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/mappers/KeyValueMappers.kt index da1530a9495..1c9875e1262 100644 --- a/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/mappers/KeyValueMappers.kt +++ b/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/mappers/KeyValueMappers.kt @@ -5,6 +5,18 @@ import dev.inmo.micro_utils.repos.* import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.map +/** + * Read-only key-value repository adapter that applies type mapping via [MapperRepo]. + * Converts outer (From) key/value types to inner (To) types before delegating to [to], + * and converts results back from inner to outer types. + * + * @param FromKey The outer key type exposed by this repo + * @param FromValue The outer value type exposed by this repo + * @param ToKey The inner key type used by the underlying [to] repo + * @param ToValue The inner value type used by the underlying [to] repo + * @param to The underlying [ReadKeyValueRepo] to delegate operations to + * @param mapper The [MapperRepo] providing bidirectional key/value type conversions + */ open class MapperReadKeyValueRepo( private val to: ReadKeyValueRepo, mapper: MapperRepo @@ -62,11 +74,34 @@ open class MapperReadKeyValueRepo( override suspend fun count(): Long = to.count() } +/** + * Wraps this [ReadKeyValueRepo] with a [MapperRepo] to expose a mapped [ReadKeyValueRepo]. + * + * @param FromKey The outer key type + * @param FromValue The outer value type + * @param ToKey The inner key type + * @param ToValue The inner value type + * @param mapper The [MapperRepo] providing bidirectional type conversions + * @return [MapperReadKeyValueRepo] wrapping this repo + */ @Suppress("NOTHING_TO_INLINE") inline fun ReadKeyValueRepo.withMapper( mapper: MapperRepo ): ReadKeyValueRepo = MapperReadKeyValueRepo(this, mapper) +/** + * Wraps this [ReadKeyValueRepo] with inline conversion lambdas to expose a mapped [ReadKeyValueRepo]. + * + * @param FromKey The outer key type + * @param FromValue The outer value type + * @param ToKey The inner key type + * @param ToValue The inner value type + * @param keyFromToTo Converts outer key to inner key; defaults to unchecked cast + * @param valueFromToTo Converts outer value to inner value; defaults to unchecked cast + * @param keyToToFrom Converts inner key to outer key; defaults to unchecked cast + * @param valueToToFrom Converts inner value to outer value; defaults to unchecked cast + * @return [MapperReadKeyValueRepo] wrapping this repo + */ @Suppress("NOTHING_TO_INLINE") inline fun ReadKeyValueRepo.withMapper( noinline keyFromToTo: suspend FromKey.() -> ToKey = { this as ToKey }, @@ -77,6 +112,18 @@ inline fun mapper(keyFromToTo, valueFromToTo, keyToToFrom, valueToToFrom) ) +/** + * Write-only key-value repository adapter that applies type mapping via [MapperRepo]. + * Converts outer (From) key/value types to inner (To) types before delegating writes to [to], + * and maps emitted flow values back from inner to outer types. + * + * @param FromKey The outer key type exposed by this repo + * @param FromValue The outer value type exposed by this repo + * @param ToKey The inner key type used by the underlying [to] repo + * @param ToValue The inner value type used by the underlying [to] repo + * @param to The underlying [WriteKeyValueRepo] to delegate operations to + * @param mapper The [MapperRepo] providing bidirectional key/value type conversions + */ open class MapperWriteKeyValueRepo( private val to: WriteKeyValueRepo, mapper: MapperRepo @@ -105,11 +152,34 @@ open class MapperWriteKeyValueRepo( ) } +/** + * Wraps this [WriteKeyValueRepo] with a [MapperRepo] to expose a mapped [WriteKeyValueRepo]. + * + * @param FromKey The outer key type + * @param FromValue The outer value type + * @param ToKey The inner key type + * @param ToValue The inner value type + * @param mapper The [MapperRepo] providing bidirectional type conversions + * @return [MapperWriteKeyValueRepo] wrapping this repo + */ @Suppress("NOTHING_TO_INLINE") inline fun WriteKeyValueRepo.withMapper( mapper: MapperRepo ): WriteKeyValueRepo = MapperWriteKeyValueRepo(this, mapper) +/** + * Wraps this [WriteKeyValueRepo] with inline conversion lambdas to expose a mapped [WriteKeyValueRepo]. + * + * @param FromKey The outer key type + * @param FromValue The outer value type + * @param ToKey The inner key type + * @param ToValue The inner value type + * @param keyFromToTo Converts outer key to inner key; defaults to unchecked cast + * @param valueFromToTo Converts outer value to inner value; defaults to unchecked cast + * @param keyToToFrom Converts inner key to outer key; defaults to unchecked cast + * @param valueToToFrom Converts inner value to outer value; defaults to unchecked cast + * @return [MapperWriteKeyValueRepo] wrapping this repo + */ @Suppress("NOTHING_TO_INLINE") inline fun WriteKeyValueRepo.withMapper( noinline keyFromToTo: suspend FromKey.() -> ToKey = { this as ToKey }, @@ -120,6 +190,17 @@ inline fun mapper(keyFromToTo, valueFromToTo, keyToToFrom, valueToToFrom) ) +/** + * Full key-value repository adapter that applies type mapping via [MapperRepo]. + * Composes [MapperReadKeyValueRepo] and [MapperWriteKeyValueRepo] for read and write delegation. + * + * @param FromKey The outer key type exposed by this repo + * @param FromValue The outer value type exposed by this repo + * @param ToKey The inner key type used by the underlying [to] repo + * @param ToValue The inner value type used by the underlying [to] repo + * @param to The underlying [KeyValueRepo] to delegate operations to + * @param mapper The [MapperRepo] providing bidirectional key/value type conversions + */ @Suppress("DELEGATED_MEMBER_HIDES_SUPERTYPE_OVERRIDE") open class MapperKeyValueRepo( private val to: KeyValueRepo, @@ -133,11 +214,34 @@ open class MapperKeyValueRepo( } } +/** + * Wraps this [KeyValueRepo] with a [MapperRepo] to expose a mapped [KeyValueRepo]. + * + * @param FromKey The outer key type + * @param FromValue The outer value type + * @param ToKey The inner key type + * @param ToValue The inner value type + * @param mapper The [MapperRepo] providing bidirectional type conversions + * @return [MapperKeyValueRepo] wrapping this repo + */ @Suppress("NOTHING_TO_INLINE") inline fun KeyValueRepo.withMapper( mapper: MapperRepo ): KeyValueRepo = MapperKeyValueRepo(this, mapper) +/** + * Wraps this [KeyValueRepo] with inline conversion lambdas to expose a mapped [KeyValueRepo]. + * + * @param FromKey The outer key type + * @param FromValue The outer value type + * @param ToKey The inner key type + * @param ToValue The inner value type + * @param keyFromToTo Converts outer key to inner key; defaults to unchecked cast + * @param valueFromToTo Converts outer value to inner value; defaults to unchecked cast + * @param keyToToFrom Converts inner key to outer key; defaults to unchecked cast + * @param valueToToFrom Converts inner value to outer value; defaults to unchecked cast + * @return [MapperKeyValueRepo] wrapping this repo + */ @Suppress("NOTHING_TO_INLINE") inline fun KeyValueRepo.withMapper( noinline keyFromToTo: suspend FromKey.() -> ToKey = { this as ToKey }, diff --git a/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/mappers/OneToManyKeyValueMappers.kt b/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/mappers/OneToManyKeyValueMappers.kt index fbedd977906..41e0520f893 100644 --- a/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/mappers/OneToManyKeyValueMappers.kt +++ b/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/mappers/OneToManyKeyValueMappers.kt @@ -5,6 +5,18 @@ import dev.inmo.micro_utils.repos.* import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.map +/** + * Read-only one-to-many key-values repository adapter that applies type mapping via [MapperRepo]. + * Converts outer (From) key/value types to inner (To) types before delegating to [to], + * and converts results back from inner to outer types. + * + * @param FromKey The outer key type exposed by this repo + * @param FromValue The outer value type exposed by this repo + * @param ToKey The inner key type used by the underlying [to] repo + * @param ToValue The inner value type used by the underlying [to] repo + * @param to The underlying [ReadKeyValuesRepo] to delegate operations to + * @param mapper The [MapperRepo] providing bidirectional key/value type conversions + */ open class MapperReadKeyValuesRepo( private val to: ReadKeyValuesRepo, mapper: MapperRepo @@ -56,11 +68,34 @@ open class MapperReadKeyValuesRepo( override suspend fun count(k: FromKey): Long = to.count(k.toOutKey()) } +/** + * Wraps this [ReadKeyValuesRepo] with a [MapperRepo] to expose a mapped [ReadKeyValuesRepo]. + * + * @param FromKey The outer key type + * @param FromValue The outer value type + * @param ToKey The inner key type + * @param ToValue The inner value type + * @param mapper The [MapperRepo] providing bidirectional type conversions + * @return [MapperReadKeyValuesRepo] wrapping this repo + */ @Suppress("NOTHING_TO_INLINE") inline fun ReadKeyValuesRepo.withMapper( mapper: MapperRepo ): ReadKeyValuesRepo = MapperReadKeyValuesRepo(this, mapper) +/** + * Wraps this [ReadKeyValuesRepo] with inline conversion lambdas to expose a mapped [ReadKeyValuesRepo]. + * + * @param FromKey The outer key type + * @param FromValue The outer value type + * @param ToKey The inner key type + * @param ToValue The inner value type + * @param keyFromToTo Converts outer key to inner key; defaults to unchecked cast + * @param valueFromToTo Converts outer value to inner value; defaults to unchecked cast + * @param keyToToFrom Converts inner key to outer key; defaults to unchecked cast + * @param valueToToFrom Converts inner value to outer value; defaults to unchecked cast + * @return [MapperReadKeyValuesRepo] wrapping this repo + */ @Suppress("NOTHING_TO_INLINE") inline fun ReadKeyValuesRepo.withMapper( noinline keyFromToTo: suspend FromKey.() -> ToKey = { this as ToKey }, @@ -71,6 +106,18 @@ inline fun mapper(keyFromToTo, valueFromToTo, keyToToFrom, valueToToFrom) ) +/** + * Write-only one-to-many key-values repository adapter that applies type mapping via [MapperRepo]. + * Converts outer (From) key/value types to inner (To) types before delegating writes to [to], + * and maps emitted flow values back from inner to outer types. + * + * @param FromKey The outer key type exposed by this repo + * @param FromValue The outer value type exposed by this repo + * @param ToKey The inner key type used by the underlying [to] repo + * @param ToValue The inner value type used by the underlying [to] repo + * @param to The underlying [WriteKeyValuesRepo] to delegate operations to + * @param mapper The [MapperRepo] providing bidirectional key/value type conversions + */ open class MapperWriteKeyValuesRepo( private val to: WriteKeyValuesRepo, mapper: MapperRepo @@ -109,11 +156,34 @@ open class MapperWriteKeyValuesRepo( override suspend fun clearWithValue(v: FromValue) = to.clearWithValue(v.toOutValue()) } +/** + * Wraps this [WriteKeyValuesRepo] with a [MapperRepo] to expose a mapped [WriteKeyValuesRepo]. + * + * @param FromKey The outer key type + * @param FromValue The outer value type + * @param ToKey The inner key type + * @param ToValue The inner value type + * @param mapper The [MapperRepo] providing bidirectional type conversions + * @return [MapperWriteKeyValuesRepo] wrapping this repo + */ @Suppress("NOTHING_TO_INLINE") inline fun WriteKeyValuesRepo.withMapper( mapper: MapperRepo ): WriteKeyValuesRepo = MapperWriteKeyValuesRepo(this, mapper) +/** + * Wraps this [WriteKeyValuesRepo] with inline conversion lambdas to expose a mapped [WriteKeyValuesRepo]. + * + * @param FromKey The outer key type + * @param FromValue The outer value type + * @param ToKey The inner key type + * @param ToValue The inner value type + * @param keyFromToTo Converts outer key to inner key; defaults to unchecked cast + * @param valueFromToTo Converts outer value to inner value; defaults to unchecked cast + * @param keyToToFrom Converts inner key to outer key; defaults to unchecked cast + * @param valueToToFrom Converts inner value to outer value; defaults to unchecked cast + * @return [MapperWriteKeyValuesRepo] wrapping this repo + */ @Suppress("NOTHING_TO_INLINE") inline fun WriteKeyValuesRepo.withMapper( noinline keyFromToTo: suspend FromKey.() -> ToKey = { this as ToKey }, @@ -124,6 +194,17 @@ inline fun mapper(keyFromToTo, valueFromToTo, keyToToFrom, valueToToFrom) ) +/** + * Full one-to-many key-values repository adapter that applies type mapping via [MapperRepo]. + * Composes [MapperReadKeyValuesRepo] and [MapperWriteKeyValuesRepo] for read and write delegation. + * + * @param FromKey The outer key type exposed by this repo + * @param FromValue The outer value type exposed by this repo + * @param ToKey The inner key type used by the underlying [to] repo + * @param ToValue The inner value type used by the underlying [to] repo + * @param to The underlying [KeyValuesRepo] to delegate operations to + * @param mapper The [MapperRepo] providing bidirectional key/value type conversions + */ @Suppress("DELEGATED_MEMBER_HIDES_SUPERTYPE_OVERRIDE") open class MapperKeyValuesRepo( private val to: KeyValuesRepo, @@ -133,11 +214,34 @@ open class MapperKeyValuesRepo( ReadKeyValuesRepo by MapperReadKeyValuesRepo(to, mapper), WriteKeyValuesRepo by MapperWriteKeyValuesRepo(to, mapper) +/** + * Wraps this [KeyValuesRepo] with a [MapperRepo] to expose a mapped [KeyValuesRepo]. + * + * @param FromKey The outer key type + * @param FromValue The outer value type + * @param ToKey The inner key type + * @param ToValue The inner value type + * @param mapper The [MapperRepo] providing bidirectional type conversions + * @return [MapperKeyValuesRepo] wrapping this repo + */ @Suppress("NOTHING_TO_INLINE") inline fun KeyValuesRepo.withMapper( mapper: MapperRepo ): KeyValuesRepo = MapperKeyValuesRepo(this, mapper) +/** + * Wraps this [KeyValuesRepo] with inline conversion lambdas to expose a mapped [KeyValuesRepo]. + * + * @param FromKey The outer key type + * @param FromValue The outer value type + * @param ToKey The inner key type + * @param ToValue The inner value type + * @param keyFromToTo Converts outer key to inner key; defaults to unchecked cast + * @param valueFromToTo Converts outer value to inner value; defaults to unchecked cast + * @param keyToToFrom Converts inner key to outer key; defaults to unchecked cast + * @param valueToToFrom Converts inner value to outer value; defaults to unchecked cast + * @return [MapperKeyValuesRepo] wrapping this repo + */ @Suppress("NOTHING_TO_INLINE") inline fun KeyValuesRepo.withMapper( noinline keyFromToTo: suspend FromKey.() -> ToKey = { this as ToKey }, diff --git a/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/pagination/KeyValuePaginationExtensions.kt b/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/pagination/KeyValuePaginationExtensions.kt index 3e9a685ecc0..bb0edd405ff 100644 --- a/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/pagination/KeyValuePaginationExtensions.kt +++ b/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/pagination/KeyValuePaginationExtensions.kt @@ -5,6 +5,17 @@ import dev.inmo.micro_utils.pagination.* import dev.inmo.micro_utils.pagination.utils.getAllWithNextPaging import dev.inmo.micro_utils.repos.ReadKeyValueRepo +/** + * Retrieves all key-value pairs from a [ReadKeyValueRepo] by iterating pages starting from [pagination]. + * Uses [methodCaller] to fetch each page of keys, then resolves each key to its value via [ReadKeyValueRepo.get]. + * + * @param Key The type of keys in the repository + * @param Value The type of values in the repository + * @param REPO The specific repository type + * @param pagination The starting pagination parameters + * @param methodCaller A function that fetches a page of keys from the repository + * @return List of all key-value pairs across all pages; entries with null values are excluded + */ suspend inline fun > REPO.getAll( pagination: Pagination, @Suppress("REDUNDANT_INLINE_SUSPEND_FUNCTION_TYPE") @@ -16,6 +27,16 @@ suspend inline fun > REPO.getAll ) } +/** + * Retrieves all key-value pairs from a [ReadKeyValueRepo] by iterating all pages. + * Uses [maxPagePagination] as the starting pagination and [methodCaller] to fetch each page of keys. + * + * @param Key The type of keys in the repository + * @param Value The type of values in the repository + * @param REPO The specific repository type + * @param methodCaller A function that fetches a page of keys from the repository + * @return List of all key-value pairs across all pages; entries with null values are excluded + */ suspend inline fun > REPO.getAll( @Suppress("REDUNDANT_INLINE_SUSPEND_FUNCTION_TYPE") crossinline methodCaller: suspend REPO.(Pagination) -> PaginationResult diff --git a/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/pagination/OneToManyPaginationExtensions.kt b/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/pagination/OneToManyPaginationExtensions.kt index 798b25bc923..c4b6f00f7ad 100644 --- a/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/pagination/OneToManyPaginationExtensions.kt +++ b/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/pagination/OneToManyPaginationExtensions.kt @@ -5,6 +5,17 @@ import dev.inmo.micro_utils.pagination.* import dev.inmo.micro_utils.pagination.utils.getAllWithNextPaging import dev.inmo.micro_utils.repos.ReadKeyValuesRepo +/** + * Retrieves all key-to-list-of-values pairs from a [ReadKeyValuesRepo] by iterating pages starting from [pagination]. + * Uses [methodCaller] to fetch each page of keys, then resolves all values per key via [ReadKeyValuesRepo.getAll]. + * + * @param Key The type of keys in the repository + * @param Value The type of values associated with keys + * @param REPO The specific repository type + * @param pagination The starting pagination parameters + * @param methodCaller A function that fetches a page of keys from the repository + * @return List of key-to-list-of-values pairs across all pages + */ suspend inline fun > REPO.getAll( pagination: Pagination, @Suppress("REDUNDANT_INLINE_SUSPEND_FUNCTION_TYPE") @@ -18,6 +29,16 @@ suspend inline fun > REPO.getAl ) } +/** + * Retrieves all key-to-list-of-values pairs from a [ReadKeyValuesRepo] by iterating all pages. + * Uses [maxPagePagination] as the starting pagination and [methodCaller] to fetch each page of keys. + * + * @param Key The type of keys in the repository + * @param Value The type of values associated with keys + * @param REPO The specific repository type + * @param methodCaller A function that fetches a page of keys from the repository + * @return List of key-to-list-of-values pairs across all pages + */ suspend inline fun > REPO.getAll( @Suppress("REDUNDANT_INLINE_SUSPEND_FUNCTION_TYPE") crossinline methodCaller: suspend REPO.(Pagination) -> PaginationResult diff --git a/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/transforms/crud/Factories.kt b/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/transforms/crud/Factories.kt index 4bb02112cb8..a38c1332a33 100644 --- a/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/transforms/crud/Factories.kt +++ b/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/transforms/crud/Factories.kt @@ -7,4 +7,11 @@ import dev.inmo.micro_utils.repos.ReadKeyValuesRepo import kotlin.js.JsName import kotlin.jvm.JvmName +/** + * Wraps this [ReadKeyValueRepo] as a [ReadCRUDFromKeyValueRepo], exposing CRUD read operations. + * + * @param K The type of keys (used as IDs in the CRUD repo) + * @param V The type of values (used as objects in the CRUD repo) + * @return [ReadCRUDFromKeyValueRepo] delegating to this repo + */ fun ReadKeyValueRepo.asReadCRUDRepo() = ReadCRUDFromKeyValueRepo(this) diff --git a/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/transforms/crud/ReadCRUDFromKeyValueRepo.kt b/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/transforms/crud/ReadCRUDFromKeyValueRepo.kt index 5f2fa7fba02..9d64662222f 100644 --- a/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/transforms/crud/ReadCRUDFromKeyValueRepo.kt +++ b/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/transforms/crud/ReadCRUDFromKeyValueRepo.kt @@ -5,6 +5,14 @@ import dev.inmo.micro_utils.pagination.PaginationResult import dev.inmo.micro_utils.repos.ReadCRUDRepo import dev.inmo.micro_utils.repos.ReadKeyValueRepo +/** + * Adapter that exposes a [ReadKeyValueRepo] as a [ReadCRUDRepo]. + * Maps CRUD read operations to the underlying key-value repository operations. + * + * @param RegisteredType The type of objects stored in the repository + * @param IdType The type of identifiers (keys) used to reference stored objects + * @param original The underlying [ReadKeyValueRepo] to delegate operations to + */ open class ReadCRUDFromKeyValueRepo( protected open val original: ReadKeyValueRepo ) : ReadCRUDRepo { diff --git a/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/transforms/kv/Factories.kt b/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/transforms/kv/Factories.kt index a457aa70e80..3d8071f1ef5 100644 --- a/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/transforms/kv/Factories.kt +++ b/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/transforms/kv/Factories.kt @@ -8,8 +8,32 @@ import dev.inmo.micro_utils.repos.ReadKeyValuesRepo import kotlin.js.JsName import kotlin.jvm.JvmName +/** + * Wraps this [ReadKeyValuesRepo] as a [ReadKeyValueFromKeyValuesRepo], + * exposing each key mapped to a [List] of all associated values. + * + * @param K The type of keys + * @param V The type of individual values + * @return [ReadKeyValueFromKeyValuesRepo] delegating to this repo + */ fun ReadKeyValuesRepo.asReadKeyValueRepo() = ReadKeyValueFromKeyValuesRepo(this) +/** + * Wraps this [KeyValuesRepo] as a [KeyValueFromKeyValuesRepo], + * exposing a full read-write key-value interface where each key maps to a [List] of values. + * + * @param K The type of keys + * @param V The type of individual values + * @return [KeyValueFromKeyValuesRepo] delegating to this repo + */ fun KeyValuesRepo.asKeyValueRepo() = KeyValueFromKeyValuesRepo(this) +/** + * Wraps this [ReadCRUDRepo] as a [ReadKeyValueFromCRUDRepo], + * exposing CRUD IDs as keys and CRUD objects as values in a [ReadKeyValueRepo]. + * + * @param K The type of CRUD IDs (used as keys) + * @param V The type of CRUD objects (used as values) + * @return [ReadKeyValueFromCRUDRepo] delegating to this repo + */ fun ReadCRUDRepo.asReadKeyValueRepo() = ReadKeyValueFromCRUDRepo(this) diff --git a/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/transforms/kv/KeyValueFromKeyValuesRepo.kt b/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/transforms/kv/KeyValueFromKeyValuesRepo.kt index 235ceafd701..7c38baf9d5f 100644 --- a/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/transforms/kv/KeyValueFromKeyValuesRepo.kt +++ b/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/transforms/kv/KeyValueFromKeyValuesRepo.kt @@ -18,6 +18,16 @@ import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.mapNotNull import kotlinx.coroutines.flow.merge +/** + * Full read-write adapter that exposes a [KeyValuesRepo] as a [KeyValueRepo] mapping each key to a [List] of values. + * Extends [ReadKeyValueFromKeyValuesRepo] with write operations delegated to the underlying [KeyValuesRepo]. + * [onNewValue] merges [KeyValuesRepo.onNewValue] and [KeyValuesRepo.onValueRemoved] and emits the updated list per key; + * [onValueRemoved] mirrors [KeyValuesRepo.onDataCleared]. + * + * @param Key The type of keys + * @param Value The type of individual values in the one-to-many repo + * @param original The underlying [KeyValuesRepo] to delegate operations to + */ open class KeyValueFromKeyValuesRepo( private val original: KeyValuesRepo ) : KeyValueRepo>, ReadKeyValueFromKeyValuesRepo(original) { diff --git a/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/transforms/kv/ReadKeyValueFromCRUDRepo.kt b/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/transforms/kv/ReadKeyValueFromCRUDRepo.kt index 91edb7a1276..bc8395eb220 100644 --- a/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/transforms/kv/ReadKeyValueFromCRUDRepo.kt +++ b/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/transforms/kv/ReadKeyValueFromCRUDRepo.kt @@ -15,6 +15,15 @@ import dev.inmo.micro_utils.repos.pagination.getAll import dev.inmo.micro_utils.repos.transforms.kvs.ReadKeyValuesFromKeyValueRepo import kotlin.jvm.JvmInline +/** + * Inline value class adapter that exposes a [ReadCRUDRepo] as a [ReadKeyValueRepo]. + * Maps key-value read operations to the underlying CRUD repository operations, + * treating CRUD IDs as keys and CRUD objects as values. + * + * @param Key The type of keys (maps to [ReadCRUDRepo] ID type) + * @param Value The type of values (maps to [ReadCRUDRepo] object type) + * @param original The underlying [ReadCRUDRepo] to delegate operations to + */ @JvmInline value class ReadKeyValueFromCRUDRepo( private val original: ReadCRUDRepo diff --git a/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/transforms/kv/ReadKeyValueFromKeyValuesRepo.kt b/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/transforms/kv/ReadKeyValueFromKeyValuesRepo.kt index 283f9ae0d49..1d8c6af04ea 100644 --- a/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/transforms/kv/ReadKeyValueFromKeyValuesRepo.kt +++ b/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/transforms/kv/ReadKeyValueFromKeyValuesRepo.kt @@ -12,6 +12,14 @@ import dev.inmo.micro_utils.repos.ReadKeyValueRepo import dev.inmo.micro_utils.repos.ReadKeyValuesRepo import dev.inmo.micro_utils.repos.transforms.kvs.ReadKeyValuesFromKeyValueRepo +/** + * Adapter that exposes a [ReadKeyValuesRepo] as a [ReadKeyValueRepo] mapping each key to a [List] of values. + * Each key's associated list of values is retrieved via [ReadKeyValuesRepo.getAll]. + * + * @param Key The type of keys + * @param Value The type of individual values in the one-to-many repo + * @param original The underlying [ReadKeyValuesRepo] to delegate operations to + */ open class ReadKeyValueFromKeyValuesRepo( private val original: ReadKeyValuesRepo ) : ReadKeyValueRepo> { diff --git a/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/transforms/kvs/Factories.kt b/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/transforms/kvs/Factories.kt index 92c6abb1795..6348230b9b6 100644 --- a/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/transforms/kvs/Factories.kt +++ b/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/transforms/kvs/Factories.kt @@ -5,17 +5,51 @@ import dev.inmo.micro_utils.repos.ReadKeyValueRepo import kotlin.js.JsName import kotlin.jvm.JvmName - +/** + * Wraps this [ReadKeyValueRepo] (mapping keys to iterables) as a [ReadKeyValuesFromKeyValueRepo], + * exposing a one-to-many read interface. + * + * @param K The type of keys + * @param V The type of individual values within each iterable + * @param VI The iterable type storing multiple values per key + * @return [ReadKeyValuesFromKeyValueRepo] delegating to this repo + */ fun > ReadKeyValueRepo.asReadKeyValuesRepo() = ReadKeyValuesFromKeyValueRepo(this) +/** + * Wraps this [KeyValueRepo] (mapping keys to iterables) as a [KeyValuesFromKeyValueRepo], + * exposing a full one-to-many read-write interface. + * + * @param K The type of keys + * @param V The type of individual values within each iterable + * @param VI The iterable type storing multiple values per key + * @param listToValuesIterable Converter from [List] of values to [VI] used when persisting changes + * @return [KeyValuesFromKeyValueRepo] delegating to this repo + */ fun > KeyValueRepo.asKeyValuesRepo( listToValuesIterable: suspend (List) -> VI ): KeyValuesFromKeyValueRepo = KeyValuesFromKeyValueRepo(this, listToValuesIterable) +/** + * Wraps this [KeyValueRepo] (mapping keys to [List]s) as a [KeyValuesFromKeyValueRepo]. + * Uses identity conversion for the list iterable. + * + * @param K The type of keys + * @param V The type of individual values + * @return [KeyValuesFromKeyValueRepo] delegating to this repo with [List] as the iterable type + */ @JvmName("asListKeyValuesRepo") @JsName("asListKeyValuesRepo") fun KeyValueRepo>.asKeyValuesRepo(): KeyValuesFromKeyValueRepo> = asKeyValuesRepo { it } +/** + * Wraps this [KeyValueRepo] (mapping keys to [Set]s) as a [KeyValuesFromKeyValueRepo]. + * Converts lists to sets when persisting changes, ensuring value uniqueness per key. + * + * @param K The type of keys + * @param V The type of individual values + * @return [KeyValuesFromKeyValueRepo] delegating to this repo with [Set] as the iterable type + */ @JvmName("asSetKeyValuesRepo") @JsName("asSetKeyValuesRepo") fun KeyValueRepo>.asKeyValuesRepo(): KeyValuesFromKeyValueRepo> = asKeyValuesRepo { it.toSet() } diff --git a/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/transforms/kvs/KeyValuesFromKeyValueRepo.kt b/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/transforms/kvs/KeyValuesFromKeyValueRepo.kt index 8248959b704..1277780f798 100644 --- a/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/transforms/kvs/KeyValuesFromKeyValueRepo.kt +++ b/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/transforms/kvs/KeyValuesFromKeyValueRepo.kt @@ -12,6 +12,17 @@ import kotlinx.coroutines.flow.asSharedFlow import kotlin.js.JsName import kotlin.jvm.JvmName +/** + * Full read-write adapter that exposes a [KeyValueRepo] storing iterables as a [KeyValuesRepo]. + * Extends [ReadKeyValuesFromKeyValueRepo] with write operations: add, remove, clear. + * Emits [onNewValue] and [onValueRemoved] for individual value changes; [onDataCleared] mirrors [KeyValueRepo.onValueRemoved]. + * + * @param Key The type of keys + * @param Value The type of individual values within each iterable + * @param ValuesIterable The iterable type storing multiple values per key + * @param original The underlying [KeyValueRepo] mapping keys to iterables of values + * @param listToValuesIterable Converter from [List] of values to [ValuesIterable] used when persisting changes + */ open class KeyValuesFromKeyValueRepo>( private val original: KeyValueRepo, private val listToValuesIterable: suspend (List) -> ValuesIterable diff --git a/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/transforms/kvs/ReadKeyValuesFromKeyValueRepo.kt b/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/transforms/kvs/ReadKeyValuesFromKeyValueRepo.kt index 21491740076..188eea0a109 100644 --- a/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/transforms/kvs/ReadKeyValuesFromKeyValueRepo.kt +++ b/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/transforms/kvs/ReadKeyValuesFromKeyValueRepo.kt @@ -11,6 +11,15 @@ import dev.inmo.micro_utils.pagination.utils.paginate import dev.inmo.micro_utils.repos.ReadKeyValueRepo import dev.inmo.micro_utils.repos.ReadKeyValuesRepo +/** + * Adapter that exposes a [ReadKeyValueRepo] storing iterables as a [ReadKeyValuesRepo]. + * Each key maps to a [ValuesIterable] in the underlying repo, which is exposed as a one-to-many relationship. + * + * @param Key The type of keys + * @param Value The type of individual values within each iterable + * @param ValuesIterable The iterable type storing multiple values per key + * @param original The underlying [ReadKeyValueRepo] mapping keys to iterables of values + */ open class ReadKeyValuesFromKeyValueRepo>( private val original: ReadKeyValueRepo ) : ReadKeyValuesRepo { diff --git a/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/versions/KeyValueBasedVersionsRepoProxy.kt b/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/versions/KeyValueBasedVersionsRepoProxy.kt index 1e467685b6e..71a374ef1a8 100644 --- a/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/versions/KeyValueBasedVersionsRepoProxy.kt +++ b/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/versions/KeyValueBasedVersionsRepoProxy.kt @@ -3,6 +3,14 @@ package dev.inmo.micro_utils.repos.versions import dev.inmo.micro_utils.repos.KeyValueRepo import dev.inmo.micro_utils.repos.set +/** + * [StandardVersionsRepoProxy] implementation backed by a [KeyValueRepo] mapping table names to version numbers. + * Stores and retrieves per-table version integers using [keyValueStore] with table names as keys. + * + * @param T The type of the underlying database or storage object + * @param keyValueStore [KeyValueRepo] used to persist table-name-to-version mappings + * @param database The underlying database or storage object exposed via [StandardVersionsRepoProxy.database] + */ class KeyValueBasedVersionsRepoProxy( private val keyValueStore: KeyValueRepo, override val database: T diff --git a/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/versions/StandardVersionsRepo.kt b/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/versions/StandardVersionsRepo.kt index 46a52acb02d..cf7233afd01 100644 --- a/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/versions/StandardVersionsRepo.kt +++ b/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/versions/StandardVersionsRepo.kt @@ -2,13 +2,43 @@ package dev.inmo.micro_utils.repos.versions import dev.inmo.micro_utils.repos.Repo +/** + * Proxy interface providing low-level access to a versioned database [T]. + * Implementations store and retrieve per-table version numbers using a backing storage. + * + * @param T The type of the underlying database or storage object + */ interface StandardVersionsRepoProxy : Repo { + /** + * The underlying database or storage object used for version tracking. + */ val database: T + /** + * Returns the current version number for the given [tableName], or null if no version is stored. + * + * @param tableName Name of the table whose version to retrieve + * @return Stored version number, or null if the table has not been versioned yet + */ suspend fun getTableVersion(tableName: String): Int? + + /** + * Persists the given [version] number for the given [tableName]. + * + * @param tableName Name of the table whose version to update + * @param version New version number to store + */ suspend fun updateTableVersion(tableName: String, version: Int) } +/** + * Standard implementation of [VersionsRepo] that delegates version storage to a [StandardVersionsRepoProxy]. + * On [setTableVersion]: calls [StandardVersionsRepoProxy.database].[onCreate] if the table has no version yet, + * then iterates [onUpdate] for each version step until the target [version] is reached. + * + * @param T The type of the underlying database or storage object + * @param proxy The [StandardVersionsRepoProxy] used to read and write version numbers + */ class StandardVersionsRepo( private val proxy: StandardVersionsRepoProxy ) : VersionsRepo { @@ -30,4 +60,4 @@ class StandardVersionsRepo( proxy.updateTableVersion(tableName, currentVersion) } } -} \ No newline at end of file +}