import { type Maybe } from '../value/maybe.type'; /** * Type of relation change to perform on a collection of models. */ export declare const RelationChange: { /** * Adds a model to the relation. If the model already exists in * the relation, the new one is used. * * Use INSERT to merge the two values together. */ readonly ADD: "add"; /** * Sets the relation to be equal to the input. */ readonly SET: "set"; /** * Variation of SET that performs REMOVE on the collection, and then follows it up with INSERT. * * This can allow the modification function to behave selectively with the items targeted for removal. */ readonly REMOVE_AND_INSERT: "remove_and_insert"; /** * Removes a model from the relation. */ readonly REMOVE: "remove"; /** * Updates an existing relation, if it exists. * The existing object is merged with the update object. */ readonly UPDATE: "update"; /** * Updates an existing relation, if it exists, or creates a new one. */ readonly INSERT: "insert"; }; /** * Union of all valid {@link RelationChange} values. */ export type RelationChangeType = (typeof RelationChange)[keyof typeof RelationChange]; /** * A string-based relation identifier. */ export type RelationString = string; /** * A relation target that is either a string key or an object containing relation data. */ export type RelationObject = RelationString | object; /** * A string identifying the type/category of a relation model. */ export type RelationModelType = string; /** * A unique key identifying a relation model, either a string or number. */ export type RelationKey = string | number; /** * Extracts the unique key from a relation model. */ export type ReadRelationKeyFn = (model: T) => RelationKey; /** * Extracts the model type string from a relation model. */ export type ReadRelationModelTypeFn = (model: T) => RelationModelType; /** * Merges the two input values. The "a" value is usually the existing/incumbent value, while "b" is the new value. */ export type MergeRelationObjectsFn = (a: T, b: T) => T; /** * Whether or not the object is changable as part of this request. */ export type ChangeRelationObjectsMaskFn = (x: T) => boolean; /** * Configuration for modifying a single-type relation collection via {@link ModelRelationUtility}. */ export interface UpdateRelationConfig { readKey: ReadRelationKeyFn; merge: MergeRelationObjectsFn; /** * Whether or not an item should be removed when remove is called. */ shouldRemove?: (x: T) => boolean; /** * Whether or not the item should be considered when performing a change. * * For instance, existing items that are passed to this function and it returns false are unable to be changed, * and new/target items that are passed to this function and it returns false are ignored. */ mask?: ChangeRelationObjectsMaskFn; } /** * Extends {@link UpdateRelationConfig} with a type reader for multi-type relation collections. */ export interface UpdateMiltiTypeRelationConfig extends UpdateRelationConfig { readType: ReadRelationModelTypeFn; } /** * Utility class for modifying a collection of relational objects. * * For instance, a string collection of keys. */ export declare class ModelRelationUtility { /** * Convenience method that modifies a collection of plain string relations. * * @param current - The current string collection. * @param change - The type of relation change to perform. * @param mods - The string values to apply as modifications. * @returns The modified string collection. */ static modifyStringCollection(current: Maybe, change: RelationChangeType, mods: RelationString[]): RelationString[]; /** * Applies a {@link RelationChangeType} operation to a typed collection of relation objects. * Supports single-type and multi-type collections depending on the config. * * @param current - The current collection of relation objects. * @param change - The relation change operation to perform. * @param mods - The modification objects to apply. * @param config - Configuration providing key/type readers, merge function, and optional mask. * @returns The modified collection. */ static modifyCollection(current: Maybe, change: RelationChangeType, mods: T[], config: UpdateMiltiTypeRelationConfig): T[]; static modifyCollection(current: Maybe, change: RelationChangeType, mods: T[], config: UpdateRelationConfig): T[]; /** * The mask results are merged together. * * Order from the "current" is retained. Anything in currentRetain overrides modifiedResults. * * @param current - the original array whose ordering is preserved * @param currentRetain - items from `current` that were excluded from modification and take precedence in the merge * @param modifiedResults - items that were modified or added during the relation change * @param readKey - function that extracts the relation key from each item for ordering * @returns the merged array with original ordering restored */ private static _mergeMaskResults; private static _modifyCollectionWithoutMask; /** * Merges update objects into matching existing items in the collection. Items without a match are ignored. * * @param current - The current collection. * @param update - The objects to merge into matching items. * @param config - Configuration with key/type readers and merge function. * @returns The updated collection. */ static updateCollection(current: T[], update: T[], config: UpdateRelationConfig | UpdateMiltiTypeRelationConfig): T[]; /** * Inserts objects into the collection: merges with existing items that share a key, * and adds new items that have no match. * * @param current - The current collection. * @param update - The objects to insert or merge. * @param config - Configuration with key/type readers and merge function. * @returns The collection with insertions and merges applied. */ static insertCollection(current: T[], update: T[], config: UpdateRelationConfig | UpdateMiltiTypeRelationConfig): T[]; /** * Used to modify a collection which may be multi-type. If readType is provided, the collection is handled as a multi-type map. * * @param current - the current collection of relation objects * @param mods - the modifications to apply to the collection * @param modifyCollection - function that applies modifications to a single-type subset of the collection * @param readType - optional function to read the type from each relation object, enabling multi-type handling * @returns the modified collection with all changes applied */ private static _modifyCollection; private static _modifyMultiTypeCollection; private static _insertSingleTypeCollection; private static _updateSingleTypeCollection; /** * Adds items to the collection, replacing any existing items with the same key. * New items take precedence over existing ones with duplicate keys. * * @param current - The current collection. * @param add - The items to add. * @param readKey - Function to extract the unique key from each item. * @returns The collection with added items. */ static addToCollection(current: Maybe, add: T[], readKey: ReadRelationKeyFn): T[]; /** * Removes items from the collection by matching keys. Optionally uses a `shouldRemove` * predicate to conditionally skip removal of matched items. * * @param current - The current collection. * @param remove - The items whose keys identify which items to remove. * @param readKey - Function to extract the unique key from each item. * @param shouldRemove - Optional predicate that must return true for a matched item to actually be removed. * @returns The collection with matching items removed. */ static removeFromCollection(current: Maybe, remove: T[], readKey: ReadRelationKeyFn, shouldRemove?: (x: T) => boolean): T[]; /** * Removes items from the collection whose keys match any of the given keys to remove. * * @param current - The current collection. * @param keysToRemove - The keys identifying items to remove. * @param readKey - Function to extract the unique key from each item. * @returns The collection with matching items removed. */ static removeKeysFromCollection(current: Maybe, keysToRemove: RelationKey[], readKey: ReadRelationKeyFn): T[]; /** * Removes duplicate items from the collection by key, keeping the first occurrence. * Optionally excludes items whose keys appear in an additional keys list. * * @param relations - The collection to deduplicate. * @param readKey - Function to extract the unique key from each item. * @param additionalKeys - Extra keys to treat as already seen (items with these keys are excluded). * @returns The deduplicated collection. */ static removeDuplicates(relations: Maybe, readKey: ReadRelationKeyFn, additionalKeys?: RelationKey[]): T[]; private static _assertMergeProvided; }