ts-data-forge 14.0.0 → 14.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -2
- package/dist/array/impl/array-utils-modification.d.mts +18 -5
- package/dist/array/impl/array-utils-modification.d.mts.map +1 -1
- package/dist/array/impl/array-utils-modification.mjs.map +1 -1
- package/dist/array/impl/array-utils-slice-clamped.d.mts.map +1 -1
- package/dist/array/impl/array-utils-slice-clamped.mjs.map +1 -1
- package/dist/array/impl/array-utils-transformation.d.mts +8 -3
- package/dist/array/impl/array-utils-transformation.d.mts.map +1 -1
- package/dist/array/impl/array-utils-transformation.mjs.map +1 -1
- package/dist/collections/imap.d.mts +1 -1
- package/dist/collections/imap.mjs.map +1 -1
- package/dist/collections/iset-mapped.d.mts +2 -2
- package/dist/collections/iset-mapped.d.mts.map +1 -1
- package/dist/collections/iset-mapped.mjs.map +1 -1
- package/dist/collections/iset.d.mts +2 -2
- package/dist/collections/iset.d.mts.map +1 -1
- package/dist/collections/iset.mjs.map +1 -1
- package/dist/number/num-arithmetic-types.d.mts +2 -2
- package/dist/number/num-arithmetic-types.d.mts.map +1 -1
- package/package.json +4 -5
- package/src/array/impl/array-utils-creation.test.mts +10 -8
- package/src/array/impl/array-utils-length-constraint-preservation.test.mts +2 -2
- package/src/array/impl/array-utils-modification.mts +41 -33
- package/src/array/impl/array-utils-modification.test.mts +52 -0
- package/src/array/impl/array-utils-shape-invariants.test.mts +284 -0
- package/src/array/impl/array-utils-slice-clamped.mts +2 -1
- package/src/array/impl/array-utils-transformation.mts +29 -2
- package/src/array/impl/array-utils-transformation.test.mts +34 -7
- package/src/collections/imap.mts +1 -1
- package/src/collections/iset-mapped.mts +7 -3
- package/src/collections/iset.mts +7 -3
- package/src/collections/iset.test.mts +9 -6
- package/src/number/num-arithmetic-types.mts +8 -4
- package/src/number/num.test.mts +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"imap.mjs","sources":["../../src/collections/imap.mts"],"sourcesContent":["/* eslint-disable unicorn/prefer-iterator-to-array-at-end */\nimport { type WidenLiteral } from 'ts-type-forge';\nimport { Optional, pipe } from '../functional/index.mjs';\nimport { asUint32 } from '../number/index.mjs';\nimport { tp, unknownToString } from '../others/index.mjs';\nimport { type MapSetKeyType, type SizeType } from '../types.mjs';\n\n/**\n * Interface for an immutable map with lookup operations and functional\n * programming patterns.\n *\n * This interface defines all methods and properties available on IMap\n * instances. All operations that modify the map return new IMap instances,\n * preserving immutability. The underlying implementation uses JavaScript's\n * native Map but creates copies on mutations to maintain immutability.\n *\n * **Immutability Guarantees:**\n *\n * - All mutation operations (set, delete, update) return new IMap instances\n * - Original IMap instances are never modified\n * - Safe for concurrent access and functional programming patterns\n *\n * **Performance Characteristics:**\n *\n * - get/has: O(1) average case\n * - set/delete: O(n) due to copying for immutability\n * - map/filter operations: O(n)\n * - iteration: O(n)\n *\n * @template K The type of the keys in the map. Must extend MapSetKeyType\n * (string, number, boolean, etc.)\n * @template V The type of the values in the map.\n */\ntype IMapInterface<K extends MapSetKeyType, V> = Readonly<{\n // Getting information\n\n /**\n * The number of elements in the map.\n *\n * @example\n *\n * ```ts\n * const entries = [\n * ['a', 1],\n * ['b', 2],\n * ] as const satisfies readonly (readonly [string, number])[];\n *\n * const map = IMap.create(entries);\n *\n * assert.isTrue(map.size === 2);\n * ```\n */\n size: SizeType.Arr;\n\n /**\n * Checks if a key exists in the map. Allows for wider literal types for keys\n * during checking.\n *\n * @example\n *\n * ```ts\n * const map = IMap.create<'id' | 'enabled', number | boolean>([\n * ['id', 42],\n * ['enabled', true],\n * ]);\n *\n * assert.isTrue(map.has('id'));\n *\n * assert.isFalse(map.has('missing'));\n * ```\n *\n * @param key The key to check.\n * @returns `true` if the key exists, `false` otherwise.\n */\n has: (key: K | (WidenLiteral<K> & {})) => boolean;\n\n /**\n * Retrieves the value associated with a key.\n *\n * @example\n *\n * ```ts\n * const map = IMap.create([['user', { id: 1 }]]);\n *\n * assert.deepStrictEqual(map.get('user'), Optional.some({ id: 1 }));\n *\n * assert.deepStrictEqual(map.get('missing'), Optional.none);\n * ```\n *\n * @param key The key to retrieve.\n * @returns The value associated with the key wrapped with `Optional.some`, or\n * `Optional.none` if the key does not exist.\n */\n get: (key: K | (WidenLiteral<K> & {})) => Optional<V>;\n\n // Reducing a value\n\n /**\n * Checks if all elements in the map satisfy a predicate. Also supports a\n * type predicate overload that narrows the type of values in the map if the\n * predicate returns true for all elements.\n *\n * @example\n *\n * ```ts\n * const map = IMap.create([\n * ['a', 2],\n * ['b', 4],\n * ]);\n *\n * const allEven = map.every((value) => value % 2 === 0);\n *\n * const isNarrowed = map.every((value): value is 2 | 4 => value % 2 === 0);\n *\n * assert.isTrue(allEven);\n *\n * assert.isTrue(isNarrowed);\n * ```\n *\n * @template W The narrowed type of the values.\n * @param predicate A function to test each key-value pair.\n * @returns `true` if all elements satisfy the predicate, `false` otherwise.\n */\n every: ((predicate: (value: V, key: K) => boolean) => boolean) &\n (<W extends V>(\n predicate: (value: V, key: K) => value is W,\n ) => this is IMap<K, W>);\n\n /**\n * Checks if at least one element in the map satisfies a predicate.\n *\n * @example\n *\n * ```ts\n * const entries = [\n * ['alice', 3],\n * ['bob', 5],\n * ] as const satisfies readonly (readonly [string, number])[];\n *\n * const map = IMap.create(entries);\n *\n * assert.isTrue(map.some((value) => value > 4));\n *\n * assert.isFalse(map.some((value) => value > 10));\n * ```\n *\n * @param predicate A function to test each key-value pair.\n * @returns `true` if at least one element satisfies the predicate, `false`\n * otherwise.\n */\n some: (predicate: (value: V, key: K) => boolean) => boolean;\n\n // Mutation\n\n /**\n * Deletes a key-value pair from the map.\n *\n * @example\n *\n * ```ts\n * const original = IMap.create([\n * ['a', 1],\n * ['b', 2],\n * ]);\n *\n * const withoutB = original.delete('b');\n *\n * assert.deepStrictEqual(original.get('b'), Optional.some(2));\n *\n * assert.deepStrictEqual(withoutB.get('b'), Optional.none);\n *\n * assert.isTrue(original.size === 2);\n *\n * assert.isTrue(withoutB.size === 1);\n * ```\n *\n * @param key The key to delete.\n * @returns A new IMap instance without the specified key.\n */\n delete: (key: K) => IMap<K, V>;\n\n /**\n * Sets a key-value pair in the map.\n *\n * @example\n *\n * ```ts\n * const entries = [['count', 1]] as const satisfies readonly (readonly [\n * 'count' | 'status',\n * number | string,\n * ])[];\n *\n * const base = IMap.create<'count' | 'status', number | string>(entries);\n *\n * const updated = base.set('count', 2);\n *\n * const extended = base.set('status', 'ok');\n *\n * assert.deepStrictEqual(base.get('count'), Optional.some(1));\n *\n * assert.deepStrictEqual(updated.get('count'), Optional.some(2));\n *\n * assert.deepStrictEqual(extended.get('status'), Optional.some('ok'));\n * ```\n *\n * @param key The key to set.\n * @param value The value to associate with the key.\n * @returns A new IMap instance with the specified key-value pair.\n */\n set: (key: K, value: V) => IMap<K, V>;\n\n /**\n * Updates the value associated with a key using an updater function.\n *\n * @example\n *\n * ```ts\n * const entries = [\n * ['alice', 10],\n * ['bob', 8],\n * ] as const satisfies readonly (readonly [\n * 'alice' | 'bob' | 'charlie',\n * number,\n * ])[];\n *\n * const scores = IMap.create<'alice' | 'bob' | 'charlie', number>(entries);\n *\n * const boosted = scores.update('alice', (value) => value + 5);\n *\n * const unchanged = scores.update('charlie', (value) => value + 1);\n *\n * assert.deepStrictEqual(boosted.get('alice'), Optional.some(15));\n *\n * assert.deepStrictEqual(scores.get('alice'), Optional.some(10));\n *\n * assert.isTrue(unchanged === scores);\n * ```\n *\n * @param key The key whose value to update.\n * @param updater A function that takes the current value and returns the new\n * value.\n * @returns A new IMap instance with the updated value.\n */\n update: (key: K, updater: (value: V) => V) => IMap<K, V>;\n\n /**\n * Applies a series of mutations to the map.\n *\n * @example\n *\n * ```ts\n * const entries = [\n * ['a', 1],\n * ['b', 2],\n * ] as const satisfies readonly (readonly ['a' | 'b' | 'c', number])[];\n *\n * const base = IMap.create<'a' | 'b' | 'c', number>(entries);\n *\n * const actions: readonly Readonly<\n * | { type: 'set'; key: 'c'; value: number }\n * | { type: 'update'; key: 'b'; updater: (value: number) => number }\n * | { type: 'delete'; key: 'a' }\n * >[] = [\n * { type: 'set', key: 'c', value: 3 },\n * { type: 'update', key: 'b', updater: (value) => value * 10 },\n * { type: 'delete', key: 'a' },\n * ] as const;\n *\n * const mutated = base.withMutations(actions);\n *\n * assert.deepStrictEqual(mutated.get('c'), Optional.some(3));\n *\n * assert.deepStrictEqual(mutated.get('b'), Optional.some(20));\n *\n * assert.deepStrictEqual(mutated.get('a'), Optional.none);\n *\n * assert.deepStrictEqual(base.get('b'), Optional.some(2));\n * ```\n *\n * @param actions An array of mutation actions (delete, set, or update).\n * @returns A new IMap instance with all mutations applied.\n */\n withMutations: (\n actions: readonly Readonly<\n | { type: 'delete'; key: K }\n | { type: 'set'; key: K; value: V }\n | { type: 'update'; key: K; updater: (value: V) => V }\n >[],\n ) => IMap<K, V>;\n\n // Sequence algorithms\n\n /**\n * Maps the values of the map to new values.\n *\n * @example\n *\n * ```ts\n * const entries = [\n * ['a', 1],\n * ['b', 2],\n * ] as const satisfies readonly (readonly [string, number])[];\n *\n * const map = IMap.create(entries);\n *\n * const doubled = map.map((value) => value * 2);\n *\n * assert.deepStrictEqual(Array.from(doubled), [\n * ['a', 2],\n * ['b', 4],\n * ]);\n * ```\n *\n * @template V2 The type of the new values.\n * @param mapFn A function that maps a value and key to a new value.\n * @returns A new IMap instance with mapped values.\n */\n map: <V2>(mapFn: (value: V, key: K) => V2) => IMap<K, V2>;\n\n /**\n * Maps the keys of the map to new keys.\n *\n * @example\n *\n * ```ts\n * const entries = [\n * ['first', 1],\n * ['second', 2],\n * ] as const satisfies readonly (readonly [string, number])[];\n *\n * const map = IMap.create(entries);\n *\n * const upperKeys = map.mapKeys((key) => key.toUpperCase());\n *\n * assert.deepStrictEqual(Array.from(upperKeys), [\n * ['FIRST', 1],\n * ['SECOND', 2],\n * ]);\n * ```\n *\n * @template K2 The type of the new keys.\n * @param mapFn A function that maps a key to a new key.\n * @returns A new IMap instance with mapped keys and original values.\n */\n mapKeys: <K2 extends MapSetKeyType>(mapFn: (key: K) => K2) => IMap<K2, V>;\n\n /**\n * Maps the entries (key-value pairs) of the map to new entries.\n *\n * @example\n *\n * ```ts\n * const entries = [\n * ['a', 1],\n * ['b', 2],\n * ] as const satisfies readonly (readonly [string, number])[];\n *\n * const map = IMap.create(entries);\n *\n * const swapped = map.mapEntries(\n * ([key, value]) => [value, key] satisfies readonly [number, string],\n * );\n *\n * assert.deepStrictEqual(Array.from(swapped), [\n * [1, 'a'],\n * [2, 'b'],\n * ]);\n * ```\n *\n * @template K2 The type of the new keys in the entries.\n * @template V2 The type of the new values in the entries.\n * @param mapFn A function that maps an entry to a new entry.\n * @returns A new IMap instance with mapped entries.\n */\n mapEntries: <K2 extends MapSetKeyType, V2>(\n mapFn: (entry: readonly [K, V]) => readonly [K2, V2],\n ) => IMap<K2, V2>;\n\n // Side effects\n\n /**\n * Executes a callback function for each key-value pair in the map.\n *\n * @example\n *\n * ```ts\n * const map = IMap.create([\n * ['a', 1],\n * ['b', 2],\n * ]);\n *\n * const mut_entries: (readonly [string, number])[] = [];\n *\n * map.forEach((value, key) => {\n * mut_entries.push([key, value]);\n * });\n *\n * assert.deepStrictEqual(mut_entries, [\n * ['a', 1],\n * ['b', 2],\n * ]);\n * ```\n *\n * @param callbackfn A function to execute for each element.\n */\n forEach: (callbackfn: (value: V, key: K) => void) => void;\n\n // Iterators\n\n /**\n * Returns an iterator for the keys in the map.\n *\n * @example\n *\n * ```ts\n * const entries = [\n * ['a', 1],\n * ['b', 2],\n * ] as const satisfies readonly (readonly [string, number])[];\n *\n * const map = IMap.create(entries);\n *\n * const keys = Array.from(map.keys());\n *\n * assert.deepStrictEqual(keys, ['a', 'b']);\n * ```\n *\n * @returns An iterable iterator of keys.\n */\n keys: () => IterableIterator<K>;\n\n /**\n * Returns an iterator for the values in the map.\n *\n * @example\n *\n * ```ts\n * const entries = [\n * ['a', 1],\n * ['b', 2],\n * ] as const satisfies readonly (readonly [string, number])[];\n *\n * const map = IMap.create(entries);\n *\n * const values = Array.from(map.values());\n *\n * assert.deepStrictEqual(values, [1, 2]);\n * ```\n *\n * @returns An iterable iterator of values.\n */\n values: () => IterableIterator<V>;\n\n /**\n * Returns an iterator for the entries (key-value pairs) in the map.\n *\n * @example\n *\n * ```ts\n * const map = IMap.create([\n * ['a', 1],\n * ['b', 2],\n * ]);\n *\n * const entries = Array.from(map.entries());\n *\n * assert.deepStrictEqual(entries, [\n * ['a', 1],\n * ['b', 2],\n * ]);\n * ```\n *\n * @returns An iterable iterator of entries.\n */\n entries: () => IterableIterator<readonly [K, V]>;\n\n // Conversion\n\n /**\n * Converts the keys of the map to an array.\n *\n * @example\n *\n * ```ts\n * const entries = [\n * ['x', 10],\n * ['y', 20],\n * ] as const satisfies readonly (readonly [string, number])[];\n *\n * const map = IMap.create(entries);\n *\n * assert.deepStrictEqual(map.toKeysArray(), ['x', 'y']);\n * ```\n *\n * @returns A readonly array of keys.\n */\n toKeysArray: () => readonly K[];\n\n /**\n * Converts the values of the map to an array.\n *\n * @example\n *\n * ```ts\n * const entries = [\n * ['x', 10],\n * ['y', 20],\n * ] as const satisfies readonly (readonly [string, number])[];\n *\n * const map = IMap.create(entries);\n *\n * assert.deepStrictEqual(map.toValuesArray(), [10, 20]);\n * ```\n *\n * @returns A readonly array of values.\n */\n toValuesArray: () => readonly V[];\n\n /**\n * Converts the entries (key-value pairs) of the map to an array.\n *\n * @example\n *\n * ```ts\n * const entries = [\n * ['a', 1],\n * ['b', 2],\n * ] as const satisfies readonly (readonly [string, number])[];\n *\n * const map = IMap.create(entries);\n *\n * assert.deepStrictEqual(map.toEntriesArray(), [\n * ['a', 1],\n * ['b', 2],\n * ]);\n * ```\n *\n * @returns A readonly array of entries.\n */\n toEntriesArray: () => readonly (readonly [K, V])[];\n\n /**\n * Converts the map to an array of entries (key-value pairs). Alias for\n * `toEntriesArray`.\n *\n * @example\n *\n * ```ts\n * const entries = [\n * ['k1', 'v1'],\n * ['k2', 'v2'],\n * ] as const satisfies readonly (readonly [string, string])[];\n *\n * const map = IMap.create(entries);\n *\n * assert.deepStrictEqual(map.toArray(), [\n * ['k1', 'v1'],\n * ['k2', 'v2'],\n * ]);\n * ```\n *\n * @returns A readonly array of entries.\n */\n toArray: () => readonly (readonly [K, V])[];\n\n /**\n * Returns the underlying readonly JavaScript Map.\n *\n * @example\n *\n * ```ts\n * const entries = [['key', 1]] as const satisfies readonly (readonly [\n * string,\n * number,\n * ])[];\n *\n * const map = IMap.create(entries);\n *\n * const raw = map.toRawMap();\n *\n * assert.isTrue(isMap(raw));\n *\n * assert.isTrue(raw.get('key') === 1);\n * ```\n *\n * @returns The raw ReadonlyMap instance.\n */\n toRawMap: () => ReadonlyMap<K, V>;\n}>;\n\n/**\n * Represents an immutable map with high-performance operations and functional\n * programming support.\n *\n * IMap is a persistent data structure that provides all the functionality of\n * JavaScript's Map while maintaining immutability. All operations that would\n * normally mutate the map instead return new IMap instances, making it safe for\n * functional programming and concurrent access.\n *\n * **Key Features:**\n *\n * - **Immutable**: All mutation operations return new instances\n * - **Type Safe**: Full TypeScript support with generic key/value types\n * - **Iterable**: Implements standard JavaScript iteration protocols\n * - **Functional**: Rich API for map, filter, reduce-style operations\n *\n * **When to Use:**\n *\n * - State management in functional applications\n * - Caching with immutable guarantees\n * - Data structures that need to be shared across components\n * - When you need Map functionality but want immutability\n *\n * @template K The type of the keys in the map. Must extend MapSetKeyType.\n * @template V The type of the values in the map.\n */\nexport type IMap<K extends MapSetKeyType, V> = Iterable<readonly [K, V]> &\n IMapInterface<K, V>;\n\n/** Provides utility functions for IMap. */\nexport namespace IMap {\n /**\n * Creates a new IMap instance from an iterable of key-value pairs.\n *\n * This factory function accepts any iterable of [key, value] tuples,\n * including arrays, JavaScript Maps, other IMaps, or custom iterables. The\n * resulting IMap will contain all the entries from the input iterable.\n *\n * **Performance:** O(n) where n is the number of entries in the iterable.\n *\n * @example\n *\n * ```ts\n * const map = IMap.create<string, number | string>([\n * ['id', 1],\n * ['status', 'active'],\n * ]);\n *\n * assert.isTrue(map.size === 2);\n *\n * assert.deepStrictEqual(map.get('status'), Optional.some('active'));\n * ```\n *\n * @template K The type of the keys. Must extend MapSetKeyType.\n * @template V The type of the values.\n * @param iterable An iterable of key-value pairs (e.g., Array, Map, IMap,\n * etc.)\n * @returns A new IMap instance containing all entries from the iterable.\n */\n export const create = <K extends MapSetKeyType, V>(\n iterable: Iterable<readonly [K, V]>,\n ): IMap<K, V> => new IMapClass<K, V>(iterable);\n\n /**\n * Checks if two IMap instances are structurally equal.\n *\n * Two IMaps are considered equal if they have the same size and contain\n * exactly the same key-value pairs. The order of entries does not matter for\n * equality comparison. Values are compared using JavaScript's `===`\n * operator.\n *\n * **Performance:** O(n) where n is the size of the smaller map.\n *\n * @example\n *\n * ```ts\n * const first = IMap.create<'a' | 'b', number>([\n * ['a', 1],\n * ['b', 2],\n * ]);\n *\n * const second = IMap.create<'a' | 'b', number>([\n * ['b', 2],\n * ['a', 1],\n * ]);\n *\n * const third = IMap.create<'a' | 'b', number>([\n * ['a', 1],\n * ['b', 3],\n * ]);\n *\n * assert.isTrue(IMap.equal(first, second));\n *\n * assert.isFalse(IMap.equal(first, third));\n * ```\n *\n * @template K The type of the keys.\n * @template V The type of the values.\n * @param a The first IMap instance to compare.\n * @param b The second IMap instance to compare.\n * @returns `true` if the maps contain exactly the same key-value pairs,\n * `false` otherwise.\n */\n export const equal = <K extends MapSetKeyType, V>(\n a: IMap<K, V>,\n b: IMap<K, V>,\n ): boolean =>\n a.size === b.size &&\n a.every(\n (v, k) =>\n pipe(b.get(k)).map((v2) => Optional.isSome(v2) && v2.value === v).value,\n );\n}\n\n/**\n * Internal class implementation for IMap providing immutable map operations.\n *\n * This class implements the IMap interface using JavaScript's native Map as the\n * underlying storage mechanism for optimal performance. All mutation operations\n * create new instances rather than modifying the existing map, ensuring\n * immutability.\n *\n * **Implementation Details:**\n *\n * - Uses Map<K, V> internally for type safety and performance\n * - Implements copy-on-write semantics for efficiency\n * - Provides optional debug messaging for development\n *\n * @template K The type of the keys. Must extend MapSetKeyType.\n * @template V The type of the values.\n * @implements IMap\n * @implements Iterable\n * @internal This class should not be used directly. Use IMap.create() instead.\n */\nclass IMapClass<K extends MapSetKeyType, V>\n implements IMap<K, V>, Iterable<readonly [K, V]>\n{\n readonly #map: ReadonlyMap<K, V>;\n readonly #showNotFoundMessage: boolean;\n\n /**\n * Constructs an IMapClass instance with the given entries.\n *\n * @param iterable An iterable of key-value pairs to populate the map.\n * @param showNotFoundMessage Whether to log warning messages when operations\n * are performed on non-existent keys. Useful for debugging. Defaults to\n * false for production use.\n * @internal Use IMap.create() instead of calling this constructor directly.\n */\n constructor(\n iterable: Iterable<readonly [K, V]>,\n showNotFoundMessage: boolean = false,\n ) {\n this.#map = new Map(iterable);\n\n this.#showNotFoundMessage = showNotFoundMessage;\n }\n\n /** @inheritdoc */\n get size(): SizeType.Arr {\n return asUint32(this.#map.size);\n }\n\n /** @inheritdoc */\n has(key: K | (WidenLiteral<K> & {})): boolean {\n // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n return this.#map.has(key as K);\n }\n\n /** @inheritdoc */\n get(key: K | (WidenLiteral<K> & {})): Optional<V> {\n if (!this.has(key)) return Optional.none;\n\n // eslint-disable-next-line total-functions/no-unsafe-type-assertion, @typescript-eslint/no-non-null-assertion\n return Optional.some(this.#map.get(key as K)!);\n }\n\n /** @inheritdoc */\n every<W extends V>(\n predicate: (value: V, key: K) => value is W,\n ): this is IMap<K, W>;\n\n /** @inheritdoc */\n every(predicate: (value: V, key: K) => boolean): boolean;\n\n /** @inheritdoc */\n every(predicate: (value: V, key: K) => boolean): boolean {\n for (const [k, v] of this.entries()) {\n if (!predicate(v, k)) return false;\n }\n\n return true;\n }\n\n /** @inheritdoc */\n some(predicate: (value: V, key: K) => boolean): boolean {\n for (const [k, v] of this.entries()) {\n if (predicate(v, k)) return true;\n }\n\n return false;\n }\n\n /** @inheritdoc */\n delete(key: K): IMap<K, V> {\n if (!this.has(key)) {\n if (this.#showNotFoundMessage) {\n const keyStr = unknownToString(key);\n\n console.warn(`IMap.delete: key not found: ${keyStr}`);\n }\n\n return this;\n }\n\n return IMap.create(\n Array.from(this.#map).filter(([k]) => !Object.is(k, key)),\n );\n }\n\n /** @inheritdoc */\n set(key: K, value: V): IMap<K, V> {\n const curr = this.get(key);\n\n if (Optional.isSome(curr) && value === curr.value) return this; // has no changes\n\n if (!this.has(key)) {\n return IMap.create([...this.#map, tp(key, value)]);\n }\n\n return IMap.create(\n Array.from(this.#map, ([k, v]) => tp(k, Object.is(k, key) ? value : v)),\n );\n }\n\n /** @inheritdoc */\n update(key: K, updater: (value: V) => V): IMap<K, V> {\n const curr = this.get(key);\n\n if (Optional.isNone(curr)) {\n if (this.#showNotFoundMessage) {\n const keyStr = unknownToString(key);\n\n console.warn(`IMap.update: key not found: ${keyStr}`);\n }\n\n return this;\n }\n\n return IMap.create(\n Array.from(this.#map, ([k, v]) =>\n tp(k, Object.is(k, key) ? updater(curr.value) : v),\n ),\n );\n }\n\n /** @inheritdoc */\n withMutations(\n actions: readonly Readonly<\n | { type: 'delete'; key: K }\n | { type: 'set'; key: K; value: V }\n | { type: 'update'; key: K; updater: (value: V) => V }\n >[],\n ): IMap<K, V> {\n const mut_result = new Map<K, V>(this.#map);\n\n const updateFn = (\n action: Readonly<\n | { type: 'delete'; key: K }\n | { type: 'set'; key: K; value: V }\n | { type: 'update'; key: K; updater: (value: V) => V }\n >,\n ): void => {\n switch (action.type) {\n case 'delete':\n mut_result.delete(action.key);\n\n break;\n\n case 'set':\n mut_result.set(action.key, action.value);\n\n break;\n\n case 'update': {\n const { key } = action;\n\n const curr = mut_result.get(key);\n\n if (!mut_result.has(key) || curr === undefined) {\n if (this.#showNotFoundMessage) {\n const keyStr = unknownToString(key);\n\n console.warn(`IMap.withMutations: key not found: ${keyStr}`);\n }\n\n break;\n }\n\n mut_result.set(key, action.updater(curr));\n\n break;\n }\n }\n };\n\n for (const action of actions) {\n updateFn(action);\n }\n\n return IMap.create(mut_result);\n }\n\n /** @inheritdoc */\n map<V2>(mapFn: (value: V, key: K) => V2): IMap<K, V2> {\n return IMap.create(this.toArray().map(([k, v]) => tp(k, mapFn(v, k))));\n }\n\n /** @inheritdoc */\n mapKeys<K2 extends MapSetKeyType>(mapFn: (key: K) => K2): IMap<K2, V> {\n return IMap.create(this.toArray().map(([k, v]) => tp(mapFn(k), v)));\n }\n\n /** @inheritdoc */\n mapEntries<K2 extends MapSetKeyType, V2>(\n mapFn: (entry: readonly [K, V]) => readonly [K2, V2],\n ): IMap<K2, V2> {\n return IMap.create(this.toArray().map(mapFn));\n }\n\n /** @inheritdoc */\n forEach(callbackfn: (value: V, key: K) => void): void {\n for (const [key, value] of this.#map) {\n callbackfn(value, key);\n }\n }\n\n /**\n * @example\n *\n * ```ts\n * const entries = [\n * ['first', 1],\n * ['second', 2],\n * ] as const satisfies readonly (readonly [string, number])[];\n *\n * const map = IMap.create(entries);\n *\n * const collected = Array.from(map);\n *\n * assert.deepStrictEqual(collected, [\n * ['first', 1],\n * ['second', 2],\n * ]);\n * ```\n *\n * @inheritdoc\n */\n [Symbol.iterator](): Iterator<readonly [K, V]> {\n return this.#map[Symbol.iterator]();\n }\n\n /** @inheritdoc */\n keys(): IterableIterator<K> {\n return this.#map.keys();\n }\n\n /** @inheritdoc */\n values(): IterableIterator<V> {\n return this.#map.values();\n }\n\n /** @inheritdoc */\n entries(): IterableIterator<readonly [K, V]> {\n return this.#map.entries();\n }\n\n /** @inheritdoc */\n toKeysArray(): readonly K[] {\n return Array.from(this.keys());\n }\n\n /** @inheritdoc */\n toValuesArray(): readonly V[] {\n return Array.from(this.values());\n }\n\n /** @inheritdoc */\n toEntriesArray(): readonly (readonly [K, V])[] {\n return Array.from(this.entries());\n }\n\n /** @inheritdoc */\n toArray(): readonly (readonly [K, V])[] {\n return Array.from(this.entries());\n }\n\n /** @inheritdoc */\n toRawMap(): ReadonlyMap<K, V> {\n return this.#map;\n }\n}\n"],"names":["IMap","Optional.isSome","Optional.none","Optional.some","Optional.isNone"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"imap.mjs","sources":["../../src/collections/imap.mts"],"sourcesContent":["/* eslint-disable unicorn/prefer-iterator-to-array-at-end */\nimport { type WidenLiteral } from 'ts-type-forge';\nimport { Optional, pipe } from '../functional/index.mjs';\nimport { asUint32 } from '../number/index.mjs';\nimport { tp, unknownToString } from '../others/index.mjs';\nimport { type MapSetKeyType, type SizeType } from '../types.mjs';\n\n/**\n * Interface for an immutable map with lookup operations and functional\n * programming patterns.\n *\n * This interface defines all methods and properties available on IMap\n * instances. All operations that modify the map return new IMap instances,\n * preserving immutability. The underlying implementation uses JavaScript's\n * native Map but creates copies on mutations to maintain immutability.\n *\n * **Immutability Guarantees:**\n *\n * - All mutation operations (set, delete, update) return new IMap instances\n * - Original IMap instances are never modified\n * - Safe for concurrent access and functional programming patterns\n *\n * **Performance Characteristics:**\n *\n * - get/has: O(1) average case\n * - set/delete: O(n) due to copying for immutability\n * - map/filter operations: O(n)\n * - iteration: O(n)\n *\n * @template K The type of the keys in the map. Must extend MapSetKeyType\n * (string, number, boolean, etc.)\n * @template V The type of the values in the map.\n */\ntype IMapInterface<K extends MapSetKeyType, V> = Readonly<{\n // Getting information\n\n /**\n * The number of elements in the map.\n *\n * @example\n *\n * ```ts\n * const entries = [\n * ['a', 1],\n * ['b', 2],\n * ] as const satisfies readonly (readonly [string, number])[];\n *\n * const map = IMap.create(entries);\n *\n * assert.isTrue(map.size === 2);\n * ```\n */\n size: SizeType.Arr;\n\n /**\n * Checks if a key exists in the map. Allows for wider literal types for keys\n * during checking.\n *\n * @example\n *\n * ```ts\n * const map = IMap.create<'id' | 'enabled', number | boolean>([\n * ['id', 42],\n * ['enabled', true],\n * ]);\n *\n * assert.isTrue(map.has('id'));\n *\n * assert.isFalse(map.has('missing'));\n * ```\n *\n * @param key The key to check.\n * @returns `true` if the key exists, `false` otherwise.\n */\n has: (key: K | (WidenLiteral<K> & {})) => boolean;\n\n /**\n * Retrieves the value associated with a key.\n *\n * @example\n *\n * ```ts\n * const map = IMap.create([['user', { id: 1 }]]);\n *\n * assert.deepStrictEqual(map.get('user'), Optional.some({ id: 1 }));\n *\n * assert.deepStrictEqual(map.get('missing'), Optional.none);\n * ```\n *\n * @param key The key to retrieve.\n * @returns The value associated with the key wrapped with `Optional.some`, or\n * `Optional.none` if the key does not exist.\n */\n get: (key: K | (WidenLiteral<K> & {})) => Optional<V>;\n\n // Reducing a value\n\n /**\n * Checks if all elements in the map satisfy a predicate. Also supports a\n * type predicate overload that narrows the type of values in the map if the\n * predicate returns true for all elements.\n *\n * @example\n *\n * ```ts\n * const map = IMap.create([\n * ['a', 2],\n * ['b', 4],\n * ]);\n *\n * const allEven = map.every((value) => value % 2 === 0);\n *\n * const isNarrowed = map.every((value): value is 2 | 4 => value % 2 === 0);\n *\n * assert.isTrue(allEven);\n *\n * assert.isTrue(isNarrowed);\n * ```\n *\n * @template W The narrowed type of the values.\n * @param predicate A function to test each key-value pair.\n * @returns `true` if all elements satisfy the predicate, `false` otherwise.\n */\n every: ((predicate: (value: V, key: K) => boolean) => boolean) &\n (<W extends V>(\n predicate: (value: V, key: K) => value is W,\n ) => this is IMap<K, W>);\n\n /**\n * Checks if at least one element in the map satisfies a predicate.\n *\n * @example\n *\n * ```ts\n * const entries = [\n * ['alice', 3],\n * ['bob', 5],\n * ] as const satisfies readonly (readonly [string, number])[];\n *\n * const map = IMap.create(entries);\n *\n * assert.isTrue(map.some((value) => value > 4));\n *\n * assert.isFalse(map.some((value) => value > 10));\n * ```\n *\n * @param predicate A function to test each key-value pair.\n * @returns `true` if at least one element satisfies the predicate, `false`\n * otherwise.\n */\n some: (predicate: (value: V, key: K) => boolean) => boolean;\n\n // Mutation\n\n /**\n * Deletes a key-value pair from the map.\n *\n * @example\n *\n * ```ts\n * const original = IMap.create([\n * ['a', 1],\n * ['b', 2],\n * ]);\n *\n * const withoutB = original.delete('b');\n *\n * assert.deepStrictEqual(original.get('b'), Optional.some(2));\n *\n * assert.deepStrictEqual(withoutB.get('b'), Optional.none);\n *\n * assert.isTrue(original.size === 2);\n *\n * assert.isTrue(withoutB.size === 1);\n * ```\n *\n * @param key The key to delete.\n * @returns A new IMap instance without the specified key.\n */\n delete: (key: K) => IMap<K, V>;\n\n /**\n * Sets a key-value pair in the map.\n *\n * @example\n *\n * ```ts\n * const entries = [['count', 1]] as const satisfies readonly (readonly [\n * 'count' | 'status',\n * number | string,\n * ])[];\n *\n * const base = IMap.create<'count' | 'status', number | string>(entries);\n *\n * const updated = base.set('count', 2);\n *\n * const extended = base.set('status', 'ok');\n *\n * assert.deepStrictEqual(base.get('count'), Optional.some(1));\n *\n * assert.deepStrictEqual(updated.get('count'), Optional.some(2));\n *\n * assert.deepStrictEqual(extended.get('status'), Optional.some('ok'));\n * ```\n *\n * @param key The key to set.\n * @param value The value to associate with the key.\n * @returns A new IMap instance with the specified key-value pair.\n */\n set: (key: K, value: V) => IMap<K, V>;\n\n /**\n * Updates the value associated with a key using an updater function.\n *\n * @example\n *\n * ```ts\n * const entries = [\n * ['alice', 10],\n * ['bob', 8],\n * ] as const satisfies readonly (readonly [\n * 'alice' | 'bob' | 'charlie',\n * number,\n * ])[];\n *\n * const scores = IMap.create<'alice' | 'bob' | 'charlie', number>(entries);\n *\n * const boosted = scores.update('alice', (value) => value + 5);\n *\n * const unchanged = scores.update('charlie', (value) => value + 1);\n *\n * assert.deepStrictEqual(boosted.get('alice'), Optional.some(15));\n *\n * assert.deepStrictEqual(scores.get('alice'), Optional.some(10));\n *\n * assert.isTrue(unchanged === scores);\n * ```\n *\n * @param key The key whose value to update.\n * @param updater A function that takes the current value and returns the new\n * value.\n * @returns A new IMap instance with the updated value.\n */\n update: (key: K, updater: (value: V) => V) => IMap<K, V>;\n\n /**\n * Applies a series of mutations to the map.\n *\n * @example\n *\n * ```ts\n * const entries = [\n * ['a', 1],\n * ['b', 2],\n * ] as const satisfies readonly (readonly ['a' | 'b' | 'c', number])[];\n *\n * const base = IMap.create<'a' | 'b' | 'c', number>(entries);\n *\n * const actions: readonly Readonly<\n * | { type: 'set'; key: 'c'; value: number }\n * | { type: 'update'; key: 'b'; updater: (value: number) => number }\n * | { type: 'delete'; key: 'a' }\n * >[] = [\n * { type: 'set', key: 'c', value: 3 },\n * { type: 'update', key: 'b', updater: (value) => value * 10 },\n * { type: 'delete', key: 'a' },\n * ] as const;\n *\n * const mutated = base.withMutations(actions);\n *\n * assert.deepStrictEqual(mutated.get('c'), Optional.some(3));\n *\n * assert.deepStrictEqual(mutated.get('b'), Optional.some(20));\n *\n * assert.deepStrictEqual(mutated.get('a'), Optional.none);\n *\n * assert.deepStrictEqual(base.get('b'), Optional.some(2));\n * ```\n *\n * @param actions An array of mutation actions (delete, set, or update).\n * @returns A new IMap instance with all mutations applied.\n */\n withMutations: (\n actions: readonly Readonly<\n | { type: 'delete'; key: K }\n | { type: 'set'; key: K; value: V }\n | { type: 'update'; key: K; updater: (value: V) => V }\n >[],\n ) => IMap<K, V>;\n\n // Sequence algorithms\n\n /**\n * Maps the values of the map to new values.\n *\n * @example\n *\n * ```ts\n * const entries = [\n * ['a', 1],\n * ['b', 2],\n * ] as const satisfies readonly (readonly [string, number])[];\n *\n * const map = IMap.create(entries);\n *\n * const doubled = map.map((value) => value * 2);\n *\n * assert.deepStrictEqual(Array.from(doubled), [\n * ['a', 2],\n * ['b', 4],\n * ]);\n * ```\n *\n * @template V2 The type of the new values.\n * @param mapFn A function that maps a value and key to a new value.\n * @returns A new IMap instance with mapped values.\n */\n map: <V2>(mapFn: (value: V, key: K) => V2) => IMap<K, V2>;\n\n /**\n * Maps the keys of the map to new keys.\n *\n * @example\n *\n * ```ts\n * const entries = [\n * ['first', 1],\n * ['second', 2],\n * ] as const satisfies readonly (readonly [string, number])[];\n *\n * const map = IMap.create(entries);\n *\n * const upperKeys = map.mapKeys((key) => key.toUpperCase());\n *\n * assert.deepStrictEqual(Array.from(upperKeys), [\n * ['FIRST', 1],\n * ['SECOND', 2],\n * ]);\n * ```\n *\n * @template K2 The type of the new keys.\n * @param mapFn A function that maps a key to a new key.\n * @returns A new IMap instance with mapped keys and original values.\n */\n mapKeys: <K2 extends MapSetKeyType>(mapFn: (key: K) => K2) => IMap<K2, V>;\n\n /**\n * Maps the entries (key-value pairs) of the map to new entries.\n *\n * @example\n *\n * ```ts\n * const entries = [\n * ['a', 1],\n * ['b', 2],\n * ] as const satisfies readonly (readonly [string, number])[];\n *\n * const map = IMap.create(entries);\n *\n * const swapped = map.mapEntries(\n * ([key, value]) => [value, key] satisfies readonly [number, string],\n * );\n *\n * assert.deepStrictEqual(Array.from(swapped), [\n * [1, 'a'],\n * [2, 'b'],\n * ]);\n * ```\n *\n * @template K2 The type of the new keys in the entries.\n * @template V2 The type of the new values in the entries.\n * @param mapFn A function that maps an entry to a new entry.\n * @returns A new IMap instance with mapped entries.\n */\n mapEntries: <K2 extends MapSetKeyType, V2>(\n mapFn: (entry: readonly [K, V]) => readonly [K2, V2],\n ) => IMap<K2, V2>;\n\n // Side effects\n\n /**\n * Executes a callback function for each key-value pair in the map.\n *\n * @example\n *\n * ```ts\n * const map = IMap.create([\n * ['a', 1],\n * ['b', 2],\n * ]);\n *\n * const mut_entries: (readonly [string, number])[] = [];\n *\n * map.forEach((value, key) => {\n * mut_entries.push([key, value]);\n * });\n *\n * assert.deepStrictEqual(mut_entries, [\n * ['a', 1],\n * ['b', 2],\n * ]);\n * ```\n *\n * @param callbackfn A function to execute for each element.\n */\n forEach: (callbackfn: (value: V, key: K) => void) => void;\n\n // Iterators\n\n /**\n * Returns an iterator for the keys in the map.\n *\n * @example\n *\n * ```ts\n * const entries = [\n * ['a', 1],\n * ['b', 2],\n * ] as const satisfies readonly (readonly [string, number])[];\n *\n * const map = IMap.create(entries);\n *\n * const keys = Array.from(map.keys());\n *\n * assert.deepStrictEqual(keys, ['a', 'b']);\n * ```\n *\n * @returns An iterable iterator of keys.\n */\n keys: () => IterableIterator<K>;\n\n /**\n * Returns an iterator for the values in the map.\n *\n * @example\n *\n * ```ts\n * const entries = [\n * ['a', 1],\n * ['b', 2],\n * ] as const satisfies readonly (readonly [string, number])[];\n *\n * const map = IMap.create(entries);\n *\n * const values = Array.from(map.values());\n *\n * assert.deepStrictEqual(values, [1, 2]);\n * ```\n *\n * @returns An iterable iterator of values.\n */\n values: () => IterableIterator<V>;\n\n /**\n * Returns an iterator for the entries (key-value pairs) in the map.\n *\n * @example\n *\n * ```ts\n * const map = IMap.create([\n * ['a', 1],\n * ['b', 2],\n * ]);\n *\n * const entries = Array.from(map.entries());\n *\n * assert.deepStrictEqual(entries, [\n * ['a', 1],\n * ['b', 2],\n * ]);\n * ```\n *\n * @returns An iterable iterator of entries.\n */\n entries: () => IterableIterator<readonly [K, V]>;\n\n // Conversion\n\n /**\n * Converts the keys of the map to an array.\n *\n * @example\n *\n * ```ts\n * const entries = [\n * ['x', 10],\n * ['y', 20],\n * ] as const satisfies readonly (readonly [string, number])[];\n *\n * const map = IMap.create(entries);\n *\n * assert.deepStrictEqual(map.toKeysArray(), ['x', 'y']);\n * ```\n *\n * @returns A readonly array of keys.\n */\n toKeysArray: () => readonly K[];\n\n /**\n * Converts the values of the map to an array.\n *\n * @example\n *\n * ```ts\n * const entries = [\n * ['x', 10],\n * ['y', 20],\n * ] as const satisfies readonly (readonly [string, number])[];\n *\n * const map = IMap.create(entries);\n *\n * assert.deepStrictEqual(map.toValuesArray(), [10, 20]);\n * ```\n *\n * @returns A readonly array of values.\n */\n toValuesArray: () => readonly V[];\n\n /**\n * Converts the entries (key-value pairs) of the map to an array.\n *\n * @example\n *\n * ```ts\n * const entries = [\n * ['a', 1],\n * ['b', 2],\n * ] as const satisfies readonly (readonly [string, number])[];\n *\n * const map = IMap.create(entries);\n *\n * assert.deepStrictEqual(map.toEntriesArray(), [\n * ['a', 1],\n * ['b', 2],\n * ]);\n * ```\n *\n * @returns A readonly array of entries.\n */\n toEntriesArray: () => readonly (readonly [K, V])[];\n\n /**\n * Converts the map to an array of entries (key-value pairs). Alias for\n * `toEntriesArray`.\n *\n * @example\n *\n * ```ts\n * const entries = [\n * ['k1', 'v1'],\n * ['k2', 'v2'],\n * ] as const satisfies readonly FixedLengthTuple<2, string>[];\n *\n * const map = IMap.create(entries);\n *\n * assert.deepStrictEqual(map.toArray(), [\n * ['k1', 'v1'],\n * ['k2', 'v2'],\n * ]);\n * ```\n *\n * @returns A readonly array of entries.\n */\n toArray: () => readonly (readonly [K, V])[];\n\n /**\n * Returns the underlying readonly JavaScript Map.\n *\n * @example\n *\n * ```ts\n * const entries = [['key', 1]] as const satisfies readonly (readonly [\n * string,\n * number,\n * ])[];\n *\n * const map = IMap.create(entries);\n *\n * const raw = map.toRawMap();\n *\n * assert.isTrue(isMap(raw));\n *\n * assert.isTrue(raw.get('key') === 1);\n * ```\n *\n * @returns The raw ReadonlyMap instance.\n */\n toRawMap: () => ReadonlyMap<K, V>;\n}>;\n\n/**\n * Represents an immutable map with high-performance operations and functional\n * programming support.\n *\n * IMap is a persistent data structure that provides all the functionality of\n * JavaScript's Map while maintaining immutability. All operations that would\n * normally mutate the map instead return new IMap instances, making it safe for\n * functional programming and concurrent access.\n *\n * **Key Features:**\n *\n * - **Immutable**: All mutation operations return new instances\n * - **Type Safe**: Full TypeScript support with generic key/value types\n * - **Iterable**: Implements standard JavaScript iteration protocols\n * - **Functional**: Rich API for map, filter, reduce-style operations\n *\n * **When to Use:**\n *\n * - State management in functional applications\n * - Caching with immutable guarantees\n * - Data structures that need to be shared across components\n * - When you need Map functionality but want immutability\n *\n * @template K The type of the keys in the map. Must extend MapSetKeyType.\n * @template V The type of the values in the map.\n */\nexport type IMap<K extends MapSetKeyType, V> = Iterable<readonly [K, V]> &\n IMapInterface<K, V>;\n\n/** Provides utility functions for IMap. */\nexport namespace IMap {\n /**\n * Creates a new IMap instance from an iterable of key-value pairs.\n *\n * This factory function accepts any iterable of [key, value] tuples,\n * including arrays, JavaScript Maps, other IMaps, or custom iterables. The\n * resulting IMap will contain all the entries from the input iterable.\n *\n * **Performance:** O(n) where n is the number of entries in the iterable.\n *\n * @example\n *\n * ```ts\n * const map = IMap.create<string, number | string>([\n * ['id', 1],\n * ['status', 'active'],\n * ]);\n *\n * assert.isTrue(map.size === 2);\n *\n * assert.deepStrictEqual(map.get('status'), Optional.some('active'));\n * ```\n *\n * @template K The type of the keys. Must extend MapSetKeyType.\n * @template V The type of the values.\n * @param iterable An iterable of key-value pairs (e.g., Array, Map, IMap,\n * etc.)\n * @returns A new IMap instance containing all entries from the iterable.\n */\n export const create = <K extends MapSetKeyType, V>(\n iterable: Iterable<readonly [K, V]>,\n ): IMap<K, V> => new IMapClass<K, V>(iterable);\n\n /**\n * Checks if two IMap instances are structurally equal.\n *\n * Two IMaps are considered equal if they have the same size and contain\n * exactly the same key-value pairs. The order of entries does not matter for\n * equality comparison. Values are compared using JavaScript's `===`\n * operator.\n *\n * **Performance:** O(n) where n is the size of the smaller map.\n *\n * @example\n *\n * ```ts\n * const first = IMap.create<'a' | 'b', number>([\n * ['a', 1],\n * ['b', 2],\n * ]);\n *\n * const second = IMap.create<'a' | 'b', number>([\n * ['b', 2],\n * ['a', 1],\n * ]);\n *\n * const third = IMap.create<'a' | 'b', number>([\n * ['a', 1],\n * ['b', 3],\n * ]);\n *\n * assert.isTrue(IMap.equal(first, second));\n *\n * assert.isFalse(IMap.equal(first, third));\n * ```\n *\n * @template K The type of the keys.\n * @template V The type of the values.\n * @param a The first IMap instance to compare.\n * @param b The second IMap instance to compare.\n * @returns `true` if the maps contain exactly the same key-value pairs,\n * `false` otherwise.\n */\n export const equal = <K extends MapSetKeyType, V>(\n a: IMap<K, V>,\n b: IMap<K, V>,\n ): boolean =>\n a.size === b.size &&\n a.every(\n (v, k) =>\n pipe(b.get(k)).map((v2) => Optional.isSome(v2) && v2.value === v).value,\n );\n}\n\n/**\n * Internal class implementation for IMap providing immutable map operations.\n *\n * This class implements the IMap interface using JavaScript's native Map as the\n * underlying storage mechanism for optimal performance. All mutation operations\n * create new instances rather than modifying the existing map, ensuring\n * immutability.\n *\n * **Implementation Details:**\n *\n * - Uses Map<K, V> internally for type safety and performance\n * - Implements copy-on-write semantics for efficiency\n * - Provides optional debug messaging for development\n *\n * @template K The type of the keys. Must extend MapSetKeyType.\n * @template V The type of the values.\n * @implements IMap\n * @implements Iterable\n * @internal This class should not be used directly. Use IMap.create() instead.\n */\nclass IMapClass<K extends MapSetKeyType, V>\n implements IMap<K, V>, Iterable<readonly [K, V]>\n{\n readonly #map: ReadonlyMap<K, V>;\n readonly #showNotFoundMessage: boolean;\n\n /**\n * Constructs an IMapClass instance with the given entries.\n *\n * @param iterable An iterable of key-value pairs to populate the map.\n * @param showNotFoundMessage Whether to log warning messages when operations\n * are performed on non-existent keys. Useful for debugging. Defaults to\n * false for production use.\n * @internal Use IMap.create() instead of calling this constructor directly.\n */\n constructor(\n iterable: Iterable<readonly [K, V]>,\n showNotFoundMessage: boolean = false,\n ) {\n this.#map = new Map(iterable);\n\n this.#showNotFoundMessage = showNotFoundMessage;\n }\n\n /** @inheritdoc */\n get size(): SizeType.Arr {\n return asUint32(this.#map.size);\n }\n\n /** @inheritdoc */\n has(key: K | (WidenLiteral<K> & {})): boolean {\n // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n return this.#map.has(key as K);\n }\n\n /** @inheritdoc */\n get(key: K | (WidenLiteral<K> & {})): Optional<V> {\n if (!this.has(key)) return Optional.none;\n\n // eslint-disable-next-line total-functions/no-unsafe-type-assertion, @typescript-eslint/no-non-null-assertion\n return Optional.some(this.#map.get(key as K)!);\n }\n\n /** @inheritdoc */\n every<W extends V>(\n predicate: (value: V, key: K) => value is W,\n ): this is IMap<K, W>;\n\n /** @inheritdoc */\n every(predicate: (value: V, key: K) => boolean): boolean;\n\n /** @inheritdoc */\n every(predicate: (value: V, key: K) => boolean): boolean {\n for (const [k, v] of this.entries()) {\n if (!predicate(v, k)) return false;\n }\n\n return true;\n }\n\n /** @inheritdoc */\n some(predicate: (value: V, key: K) => boolean): boolean {\n for (const [k, v] of this.entries()) {\n if (predicate(v, k)) return true;\n }\n\n return false;\n }\n\n /** @inheritdoc */\n delete(key: K): IMap<K, V> {\n if (!this.has(key)) {\n if (this.#showNotFoundMessage) {\n const keyStr = unknownToString(key);\n\n console.warn(`IMap.delete: key not found: ${keyStr}`);\n }\n\n return this;\n }\n\n return IMap.create(\n Array.from(this.#map).filter(([k]) => !Object.is(k, key)),\n );\n }\n\n /** @inheritdoc */\n set(key: K, value: V): IMap<K, V> {\n const curr = this.get(key);\n\n if (Optional.isSome(curr) && value === curr.value) return this; // has no changes\n\n if (!this.has(key)) {\n return IMap.create([...this.#map, tp(key, value)]);\n }\n\n return IMap.create(\n Array.from(this.#map, ([k, v]) => tp(k, Object.is(k, key) ? value : v)),\n );\n }\n\n /** @inheritdoc */\n update(key: K, updater: (value: V) => V): IMap<K, V> {\n const curr = this.get(key);\n\n if (Optional.isNone(curr)) {\n if (this.#showNotFoundMessage) {\n const keyStr = unknownToString(key);\n\n console.warn(`IMap.update: key not found: ${keyStr}`);\n }\n\n return this;\n }\n\n return IMap.create(\n Array.from(this.#map, ([k, v]) =>\n tp(k, Object.is(k, key) ? updater(curr.value) : v),\n ),\n );\n }\n\n /** @inheritdoc */\n withMutations(\n actions: readonly Readonly<\n | { type: 'delete'; key: K }\n | { type: 'set'; key: K; value: V }\n | { type: 'update'; key: K; updater: (value: V) => V }\n >[],\n ): IMap<K, V> {\n const mut_result = new Map<K, V>(this.#map);\n\n const updateFn = (\n action: Readonly<\n | { type: 'delete'; key: K }\n | { type: 'set'; key: K; value: V }\n | { type: 'update'; key: K; updater: (value: V) => V }\n >,\n ): void => {\n switch (action.type) {\n case 'delete':\n mut_result.delete(action.key);\n\n break;\n\n case 'set':\n mut_result.set(action.key, action.value);\n\n break;\n\n case 'update': {\n const { key } = action;\n\n const curr = mut_result.get(key);\n\n if (!mut_result.has(key) || curr === undefined) {\n if (this.#showNotFoundMessage) {\n const keyStr = unknownToString(key);\n\n console.warn(`IMap.withMutations: key not found: ${keyStr}`);\n }\n\n break;\n }\n\n mut_result.set(key, action.updater(curr));\n\n break;\n }\n }\n };\n\n for (const action of actions) {\n updateFn(action);\n }\n\n return IMap.create(mut_result);\n }\n\n /** @inheritdoc */\n map<V2>(mapFn: (value: V, key: K) => V2): IMap<K, V2> {\n return IMap.create(this.toArray().map(([k, v]) => tp(k, mapFn(v, k))));\n }\n\n /** @inheritdoc */\n mapKeys<K2 extends MapSetKeyType>(mapFn: (key: K) => K2): IMap<K2, V> {\n return IMap.create(this.toArray().map(([k, v]) => tp(mapFn(k), v)));\n }\n\n /** @inheritdoc */\n mapEntries<K2 extends MapSetKeyType, V2>(\n mapFn: (entry: readonly [K, V]) => readonly [K2, V2],\n ): IMap<K2, V2> {\n return IMap.create(this.toArray().map(mapFn));\n }\n\n /** @inheritdoc */\n forEach(callbackfn: (value: V, key: K) => void): void {\n for (const [key, value] of this.#map) {\n callbackfn(value, key);\n }\n }\n\n /**\n * @example\n *\n * ```ts\n * const entries = [\n * ['first', 1],\n * ['second', 2],\n * ] as const satisfies readonly (readonly [string, number])[];\n *\n * const map = IMap.create(entries);\n *\n * const collected = Array.from(map);\n *\n * assert.deepStrictEqual(collected, [\n * ['first', 1],\n * ['second', 2],\n * ]);\n * ```\n *\n * @inheritdoc\n */\n [Symbol.iterator](): Iterator<readonly [K, V]> {\n return this.#map[Symbol.iterator]();\n }\n\n /** @inheritdoc */\n keys(): IterableIterator<K> {\n return this.#map.keys();\n }\n\n /** @inheritdoc */\n values(): IterableIterator<V> {\n return this.#map.values();\n }\n\n /** @inheritdoc */\n entries(): IterableIterator<readonly [K, V]> {\n return this.#map.entries();\n }\n\n /** @inheritdoc */\n toKeysArray(): readonly K[] {\n return Array.from(this.keys());\n }\n\n /** @inheritdoc */\n toValuesArray(): readonly V[] {\n return Array.from(this.values());\n }\n\n /** @inheritdoc */\n toEntriesArray(): readonly (readonly [K, V])[] {\n return Array.from(this.entries());\n }\n\n /** @inheritdoc */\n toArray(): readonly (readonly [K, V])[] {\n return Array.from(this.entries());\n }\n\n /** @inheritdoc */\n toRawMap(): ReadonlyMap<K, V> {\n return this.#map;\n }\n}\n"],"names":["IMap","Optional.isSome","Optional.none","Optional.some","Optional.isNone"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type ReadonlyRecord, type WidenLiteral } from 'ts-type-forge';
|
|
1
|
+
import { type FixedLengthTuple, type ReadonlyRecord, type WidenLiteral } from 'ts-type-forge';
|
|
2
2
|
import { type MapSetKeyType, type SizeType } from '../types.mjs';
|
|
3
3
|
/**
|
|
4
4
|
* Interface for an immutable set with custom element mapping and membership
|
|
@@ -750,7 +750,7 @@ type ISetMappedInterface<K, KM extends MapSetKeyType> = Readonly<{
|
|
|
750
750
|
*
|
|
751
751
|
* @returns An iterable iterator of entries.
|
|
752
752
|
*/
|
|
753
|
-
entries: () => IterableIterator<
|
|
753
|
+
entries: () => IterableIterator<FixedLengthTuple<2, K>>;
|
|
754
754
|
/**
|
|
755
755
|
* Converts the elements of the set to an array.
|
|
756
756
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"iset-mapped.d.mts","sourceRoot":"","sources":["../../src/collections/iset-mapped.mts"],"names":[],"mappings":"AACA,OAAO,
|
|
1
|
+
{"version":3,"file":"iset-mapped.d.mts","sourceRoot":"","sources":["../../src/collections/iset-mapped.mts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"iset-mapped.mjs","sources":["../../src/collections/iset-mapped.mts"],"sourcesContent":["/* eslint-disable unicorn/prefer-iterator-to-array-at-end */\nimport { type ReadonlyRecord, type WidenLiteral } from 'ts-type-forge';\nimport { asUint32 } from '../number/index.mjs';\nimport { type MapSetKeyType, type SizeType } from '../types.mjs';\n\n/**\n * Interface for an immutable set with custom element mapping and membership\n * testing.\n *\n * ISetMapped allows you to use complex objects as set elements by providing\n * transformation functions that convert between your custom element type `K`\n * and a primitive `MapSetKeyType` `KM` that can be efficiently stored in\n * JavaScript's native Set. This enables set operations on complex elements\n * while maintaining type safety and immutability.\n *\n * **Key Features:**\n *\n * - **Custom Element Types**: Use any type as set elements by providing\n * `toKey`/`fromKey` functions\n * - **Immutable**: All operations return new instances, preserving immutability\n * - **Set Operations**: Full support for union, intersection, difference,\n * subset/superset checks\n * - **Type Safe**: Full TypeScript support with generic element types\n *\n * **Performance Characteristics:**\n *\n * - has: O(1) average case (plus element transformation overhead)\n * - add/delete: O(n) due to copying for immutability (plus element\n * transformation overhead)\n * - set operations (union, intersection, difference): O(n)\n * - map/filter operations: O(n)\n * - iteration: O(n) (plus element transformation overhead)\n *\n * @template K The type of the custom elements in the set.\n * @template KM The type of the mapped primitive keys (string, number, etc.).\n */\ntype ISetMappedInterface<K, KM extends MapSetKeyType> = Readonly<{\n /**\n * Creates a new ISetMapped instance.\n *\n * @param iterable An iterable of elements.\n * @param toKey A function that converts an element of type `K` to `KM`.\n * @param fromKey A function that converts a mapped key of type `KM` back to\n * `K`.\n */\n new (iterable: Iterable<K>, toKey: (a: K) => KM, fromKey: (k: KM) => K): void;\n\n // Getting information\n\n /**\n * The number of elements in the set.\n *\n * @example\n *\n * ```ts\n * type Point = Readonly<{ x: number; tag: string }>;\n *\n * const toKey = (point: Point) => JSON.stringify(point);\n *\n * // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n * const fromKey = (key: string) => JSON.parse(key) as Point;\n *\n * const points: readonly Point[] = [\n * { x: 1, tag: 'a' },\n * { x: 2, tag: 'b' },\n * ] as const;\n *\n * const set = ISetMapped.create<Point, string>(points, toKey, fromKey);\n *\n * assert.isTrue(set.size === 2);\n * ```\n */\n size: SizeType.Arr;\n\n /**\n * Checks if the set is empty.\n *\n * @example\n *\n * ```ts\n * type Point = Readonly<{ x: number; tag: string }>;\n *\n * const toKey = (point: Point) => JSON.stringify(point);\n *\n * // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n * const fromKey = (key: string) => JSON.parse(key) as Point;\n *\n * const empty = ISetMapped.create<Point, string>([], toKey, fromKey);\n *\n * const points = ISetMapped.create<Point, string>(\n * [{ x: 1, tag: 'a' }],\n * toKey,\n * fromKey,\n * );\n *\n * assert.isTrue(empty.isEmpty);\n *\n * assert.isFalse(points.isEmpty);\n * ```\n */\n isEmpty: boolean;\n\n /**\n * Checks if an element exists in the set.\n *\n * @example\n *\n * ```ts\n * type Point = Readonly<{ x: number; tag: string }>;\n *\n * const toKey = (point: Point) => JSON.stringify(point);\n *\n * // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n * const fromKey = (key: string) => JSON.parse(key) as Point;\n *\n * const set = ISetMapped.create<Point, string>(\n * [{ x: 1, tag: 'a' }],\n * toKey,\n * fromKey,\n * );\n *\n * assert.isTrue(set.has({ x: 1, tag: 'a' }));\n *\n * assert.isFalse(set.has({ x: 2, tag: 'b' }));\n * ```\n *\n * @param key The element to check.\n * @returns `true` if the element exists, `false` otherwise.\n */\n has: (key: K | (WidenLiteral<K> & {})) => boolean;\n\n // Reducing a value\n\n /**\n * Checks if all elements in the set satisfy a type predicate. Narrows the\n * type of elements in the set if the predicate returns true for all\n * elements.\n *\n *\n * @example\n *\n * ```ts\n * type Point = Readonly<{ x: number; tag: string }>;\n *\n * const toKey = (point: Point) => JSON.stringify(point);\n *\n * // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n * const fromKey = (key: string) => JSON.parse(key) as Point;\n *\n * const set = ISetMapped.create<Point, string>(\n * [\n * { x: 2, tag: 'even' },\n * { x: 4, tag: 'even' },\n * ],\n * toKey,\n * fromKey,\n * );\n *\n * const allEven = set.every((point) => point.x % 2 === 0);\n *\n * const narrowed = set.every(\n * (point): point is Readonly<{ x: 2 | 4; tag: 'even' }> =>\n * point.x % 2 === 0,\n * );\n *\n * assert.isTrue(allEven);\n *\n * assert.isTrue(narrowed);\n * ```\n *\n * @template L The narrowed type of the elements.\n * @param predicate A function to test each element.\n * @returns `true` if all elements satisfy the predicate, `false` otherwise.\n */\n every: ((predicate: (key: K) => boolean) => boolean) &\n (<L extends K>(\n predicate: (key: K) => key is L,\n ) => this is ISetMapped<L, KM>);\n\n /**\n * Checks if at least one element in the set satisfies a predicate.\n *\n * @example\n *\n * ```ts\n * type Point = Readonly<{ x: number; tag: string }>;\n *\n * const toKey = (point: Point) => JSON.stringify(point);\n *\n * // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n * const fromKey = (key: string) => JSON.parse(key) as Point;\n *\n * const set = ISetMapped.create<Point, string>(\n * [\n * { x: 1, tag: 'a' },\n * { x: 5, tag: 'b' },\n * ],\n * toKey,\n * fromKey,\n * );\n *\n * assert.isTrue(set.some((point) => point.x > 4));\n *\n * assert.isFalse(set.some((point) => point.x > 10));\n * ```\n *\n * @param predicate A function to test each element.\n * @returns `true` if at least one element satisfies the predicate, `false`\n * otherwise.\n */\n some: (predicate: (key: K) => boolean) => boolean;\n\n // Mutation\n\n /**\n * Adds an element to the set.\n *\n * @example\n *\n * ```ts\n * type Point = Readonly<{ x: number; tag: string }>;\n *\n * const toKey = (point: Point) => JSON.stringify(point);\n *\n * // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n * const fromKey = (key: string) => JSON.parse(key) as Point;\n *\n * const base = ISetMapped.create<Point, string>(\n * [{ x: 1, tag: 'a' }],\n * toKey,\n * fromKey,\n * );\n *\n * const withNew = base.add({ x: 2, tag: 'b' });\n *\n * const unchanged = base.add({ x: 1, tag: 'a' });\n *\n * assert.deepStrictEqual(Array.from(withNew), [\n * { x: 1, tag: 'a' },\n * { x: 2, tag: 'b' },\n * ]);\n *\n * assert.isTrue(unchanged === base);\n * ```\n *\n * @param key The element to add.\n * @returns A new ISetMapped instance with the element added.\n */\n add: (key: K) => ISetMapped<K, KM>;\n\n /**\n * Deletes an element from the set.\n *\n * @example\n *\n * ```ts\n * type Point = Readonly<{ x: number; tag: string }>;\n *\n * const toKey = (point: Point) => JSON.stringify(point);\n *\n * // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n * const fromKey = (key: string) => JSON.parse(key) as Point;\n *\n * const base = ISetMapped.create<Point, string>(\n * [\n * { x: 1, tag: 'a' },\n * { x: 2, tag: 'b' },\n * ],\n * toKey,\n * fromKey,\n * );\n *\n * const withoutSecond = base.delete({ x: 2, tag: 'b' });\n *\n * const unchanged = base.delete({ x: 3, tag: 'c' });\n *\n * assert.deepStrictEqual(Array.from(withoutSecond), [{ x: 1, tag: 'a' }]);\n *\n * assert.isTrue(unchanged === base);\n * ```\n *\n * @param key The element to delete.\n * @returns A new ISetMapped instance without the specified element.\n */\n delete: (key: K) => ISetMapped<K, KM>;\n\n /**\n * Applies a series of mutations to the set.\n *\n * @example\n *\n * ```ts\n * type Point = Readonly<{ x: number; tag: string }>;\n *\n * const toKey = (point: Point) => JSON.stringify(point);\n *\n * // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n * const fromKey = (key: string) => JSON.parse(key) as Point;\n *\n * const base = ISetMapped.create<Point, string>(\n * [\n * { x: 1, tag: 'a' },\n * { x: 2, tag: 'b' },\n * ],\n * toKey,\n * fromKey,\n * );\n *\n * const actions: readonly Readonly<\n * { type: 'add'; key: Point } | { type: 'delete'; key: Point }\n * >[] = [\n * { type: 'add', key: { x: 3, tag: 'c' } },\n * { type: 'delete', key: { x: 1, tag: 'a' } },\n * ] as const;\n *\n * const mutated = base.withMutations(actions);\n *\n * assert.deepStrictEqual(Array.from(mutated), [\n * { x: 2, tag: 'b' },\n * { x: 3, tag: 'c' },\n * ]);\n *\n * assert.deepStrictEqual(Array.from(base), [\n * { x: 1, tag: 'a' },\n * { x: 2, tag: 'b' },\n * ]);\n * ```\n *\n * @param actions An array of mutation actions (add or delete).\n * @returns A new ISetMapped instance with all mutations applied.\n */\n withMutations: (\n actions: readonly Readonly<\n { type: 'add'; key: K } | { type: 'delete'; key: K }\n >[],\n ) => ISetMapped<K, KM>;\n\n // Sequence algorithms\n\n /**\n * Maps the elements of the set to new elements. Note: The element type `K`\n * cannot be changed because `toKey` and `fromKey` would become unusable if\n * the mapped type `KM` changes.\n *\n * @example\n *\n * ```ts\n * type Point = Readonly<{ x: number; tag: string }>;\n *\n * const toKey = (point: Point) => JSON.stringify(point);\n *\n * // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n * const fromKey = (key: string) => JSON.parse(key) as Point;\n *\n * const set = ISetMapped.create<Point, string>(\n * [\n * { x: 1, tag: 'a' },\n * { x: 2, tag: 'b' },\n * ],\n * toKey,\n * fromKey,\n * );\n *\n * const shifted = set.map((point) => ({\n * x: point.x + 10,\n * tag: point.tag.toUpperCase(),\n * }));\n *\n * assert.deepStrictEqual(Array.from(shifted), [\n * { x: 11, tag: 'A' },\n * { x: 12, tag: 'B' },\n * ]);\n * ```\n *\n * @param mapFn A function that maps an element to a new element of the same\n * type `K`.\n * @returns A new ISetMapped instance with mapped elements.\n */\n map: (mapFn: (key: K) => K) => ISetMapped<K, KM>;\n\n /**\n * Filters the elements of the set based on a predicate.\n *\n * @example\n *\n * ```ts\n * type Point = Readonly<{ x: number; tag: string }>;\n *\n * const toKey = (point: Point) => JSON.stringify(point);\n *\n * // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n * const fromKey = (key: string) => JSON.parse(key) as Point;\n *\n * const set = ISetMapped.create<Point, string>(\n * [\n * { x: 1, tag: 'a' },\n * { x: 2, tag: 'b' },\n * { x: 3, tag: 'c' },\n * ],\n * toKey,\n * fromKey,\n * );\n *\n * const evenPoints = set.filter((point) => point.x % 2 === 0);\n *\n * assert.deepStrictEqual(Array.from(evenPoints), [{ x: 2, tag: 'b' }]);\n * ```\n *\n * @param predicate A function to test each element.\n * @returns A new ISetMapped instance with elements that satisfy the\n * predicate.\n */\n filter: (predicate: (value: K) => boolean) => ISetMapped<K, KM>;\n\n /**\n * Filters the elements of the set by excluding elements for which the\n * predicate returns true.\n *\n * @example\n *\n * ```ts\n * type Point = Readonly<{ x: number; tag: string }>;\n *\n * const toKey = (point: Point) => JSON.stringify(point);\n *\n * // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n * const fromKey = (key: string) => JSON.parse(key) as Point;\n *\n * const set = ISetMapped.create<Point, string>(\n * [\n * { x: 1, tag: 'a' },\n * { x: 2, tag: 'b' },\n * ],\n * toKey,\n * fromKey,\n * );\n *\n * const withoutEven = set.filterNot((point) => point.x % 2 === 0);\n *\n * assert.deepStrictEqual(Array.from(withoutEven), [{ x: 1, tag: 'a' }]);\n * ```\n *\n * @param predicate A function to test each element.\n * @returns A new ISetMapped instance with elements for which the predicate\n * returned `false`.\n */\n filterNot: (predicate: (key: K) => boolean) => ISetMapped<K, KM>;\n\n // Side effects\n\n /**\n * Executes a callback function for each element in the set.\n *\n * @example\n *\n * ```ts\n * type Point = Readonly<{ x: number; tag: string }>;\n *\n * const toKey = (point: Point) => JSON.stringify(point);\n *\n * // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n * const fromKey = (key: string) => JSON.parse(key) as Point;\n *\n * const set = ISetMapped.create<Point, string>(\n * [\n * { x: 1, tag: 'a' },\n * { x: 2, tag: 'b' },\n * ],\n * toKey,\n * fromKey,\n * );\n *\n * const mut_collected: Point[] = [];\n *\n * set.forEach((point) => {\n * mut_collected.push(point);\n * });\n *\n * assert.deepStrictEqual(mut_collected, [\n * { x: 1, tag: 'a' },\n * { x: 2, tag: 'b' },\n * ]);\n * ```\n *\n * @param callbackfn A function to execute for each element.\n */\n forEach: (callbackfn: (key: K) => void) => void;\n\n // Comparison\n\n /**\n * Checks if this set is a subset of another set.\n *\n * @example\n *\n * ```ts\n * type Point = Readonly<{ x: number; tag: string }>;\n *\n * const toKey = (point: Point) => JSON.stringify(point);\n *\n * // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n * const fromKey = (key: string) => JSON.parse(key) as Point;\n *\n * const subset = ISetMapped.create<Point, string>(\n * [{ x: 1, tag: 'a' }],\n * toKey,\n * fromKey,\n * );\n *\n * const superset = ISetMapped.create<Point, string>(\n * [\n * { x: 1, tag: 'a' },\n * { x: 2, tag: 'b' },\n * ],\n * toKey,\n * fromKey,\n * );\n *\n * assert.isTrue(subset.isSubsetOf(superset));\n *\n * assert.isFalse(superset.isSubsetOf(subset));\n * ```\n *\n * @param set The other set.\n * @returns `true` if this set is a subset of the other set, `false`\n * otherwise.\n */\n isSubsetOf: (set: ISetMapped<K, KM>) => boolean;\n\n /**\n * Checks if this set is a superset of another set.\n *\n * @example\n *\n * ```ts\n * type Point = Readonly<{ x: number; tag: string }>;\n *\n * const toKey = (point: Point) => JSON.stringify(point);\n *\n * // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n * const fromKey = (key: string) => JSON.parse(key) as Point;\n *\n * const superset = ISetMapped.create<Point, string>(\n * [\n * { x: 1, tag: 'a' },\n * { x: 2, tag: 'b' },\n * ],\n * toKey,\n * fromKey,\n * );\n *\n * const subset = ISetMapped.create<Point, string>(\n * [{ x: 2, tag: 'b' }],\n * toKey,\n * fromKey,\n * );\n *\n * assert.isTrue(superset.isSupersetOf(subset));\n *\n * assert.isFalse(subset.isSupersetOf(superset));\n * ```\n *\n * @param set The other set.\n * @returns `true` if this set is a superset of the other set, `false`\n * otherwise.\n */\n isSupersetOf: (set: ISetMapped<K, KM>) => boolean;\n\n /**\n * Returns a new set with elements that are in this set but not in another\n * set.\n *\n * @example\n *\n * ```ts\n * type Point = Readonly<{ x: number; tag: string }>;\n *\n * const toKey = (point: Point) => JSON.stringify(point);\n *\n * // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n * const fromKey = (key: string) => JSON.parse(key) as Point;\n *\n * const left = ISetMapped.create<Point, string>(\n * [\n * { x: 1, tag: 'a' },\n * { x: 2, tag: 'b' },\n * { x: 3, tag: 'c' },\n * ],\n * toKey,\n * fromKey,\n * );\n *\n * const right = ISetMapped.create<Point, string>(\n * [{ x: 2, tag: 'b' }],\n * toKey,\n * fromKey,\n * );\n *\n * const difference = left.subtract(right);\n *\n * assert.deepStrictEqual(Array.from(difference), [\n * { x: 1, tag: 'a' },\n * { x: 3, tag: 'c' },\n * ]);\n * ```\n *\n * @param set The other set.\n * @returns A new ISetMapped instance representing the set difference.\n */\n subtract: (set: ISetMapped<K, KM>) => ISetMapped<K, KM>;\n\n /**\n * Returns a new set with elements that are common to both this set and\n * another set.\n *\n * @example\n *\n * ```ts\n * type Point = Readonly<{ x: number; tag: string }>;\n *\n * const toKey = (point: Point) => JSON.stringify(point);\n *\n * // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n * const fromKey = (key: string) => JSON.parse(key) as Point;\n *\n * const left = ISetMapped.create<Point, string>(\n * [\n * { x: 1, tag: 'a' },\n * { x: 2, tag: 'b' },\n * ],\n * toKey,\n * fromKey,\n * );\n *\n * const right = ISetMapped.create<Point, string>(\n * [{ x: 2, tag: 'b' }],\n * toKey,\n * fromKey,\n * );\n *\n * const intersection = left.intersect(right);\n *\n * assert.deepStrictEqual(Array.from(intersection), [{ x: 2, tag: 'b' }]);\n * ```\n *\n * @param set The other set.\n * @returns A new ISetMapped instance representing the set intersection.\n */\n intersect: (set: ISetMapped<K, KM>) => ISetMapped<K, KM>;\n\n /**\n * Returns a new set with all elements from both this set and another set.\n *\n * @example\n *\n * ```ts\n * type Point = Readonly<{ x: number; tag: string }>;\n *\n * const toKey = (point: Point) => JSON.stringify(point);\n *\n * // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n * const fromKey = (key: string) => JSON.parse(key) as Point;\n *\n * const left = ISetMapped.create<Point, string>(\n * [{ x: 1, tag: 'a' }],\n * toKey,\n * fromKey,\n * );\n *\n * const right = ISetMapped.create<Point, string>(\n * [{ x: 2, tag: 'b' }],\n * toKey,\n * fromKey,\n * );\n *\n * const combined = left.union(right);\n *\n * assert.deepStrictEqual(Array.from(combined), [\n * { x: 1, tag: 'a' },\n * { x: 2, tag: 'b' },\n * ]);\n * ```\n *\n * @param set The other set.\n * @returns A new ISetMapped instance representing the set union.\n */\n union: (set: ISetMapped<K, KM>) => ISetMapped<K, KM>;\n\n // Iterators\n\n /**\n * Returns an iterator for the elements in the set (alias for values).\n *\n * @example\n *\n * ```ts\n * type Point = Readonly<{ x: number; tag: string }>;\n *\n * const toKey = (point: Point) => JSON.stringify(point);\n *\n * // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n * const fromKey = (key: string) => JSON.parse(key) as Point;\n *\n * const set = ISetMapped.create<Point, string>(\n * [\n * { x: 1, tag: 'a' },\n * { x: 2, tag: 'b' },\n * ],\n * toKey,\n * fromKey,\n * );\n *\n * assert.deepStrictEqual(Array.from(set.keys()), [\n * { x: 1, tag: 'a' },\n * { x: 2, tag: 'b' },\n * ]);\n * ```\n *\n * @returns An iterable iterator of elements.\n */\n keys: () => IterableIterator<K>;\n\n /**\n * Returns an iterator for the elements in the set.\n *\n * @example\n *\n * ```ts\n * type Point = Readonly<{ x: number; tag: string }>;\n *\n * const toKey = (point: Point) => JSON.stringify(point);\n *\n * // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n * const fromKey = (key: string) => JSON.parse(key) as Point;\n *\n * const set = ISetMapped.create<Point, string>(\n * [\n * { x: 1, tag: 'a' },\n * { x: 2, tag: 'b' },\n * ],\n * toKey,\n * fromKey,\n * );\n *\n * assert.deepStrictEqual(Array.from(set.values()), [\n * { x: 1, tag: 'a' },\n * { x: 2, tag: 'b' },\n * ]);\n * ```\n *\n * @returns An iterable iterator of elements.\n */\n values: () => IterableIterator<K>;\n\n /**\n * Returns an iterator for the entries (element-element pairs) in the set.\n *\n * @example\n *\n * ```ts\n * type Point = Readonly<{ x: number; tag: string }>;\n *\n * const toKey = (point: Point) => JSON.stringify(point);\n *\n * // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n * const fromKey = (key: string) => JSON.parse(key) as Point;\n *\n * const set = ISetMapped.create<Point, string>(\n * [\n * { x: 1, tag: 'a' },\n * { x: 2, tag: 'b' },\n * ],\n * toKey,\n * fromKey,\n * );\n *\n * assert.deepStrictEqual(Array.from(set.entries()), [\n * [\n * { x: 1, tag: 'a' },\n * { x: 1, tag: 'a' },\n * ],\n * [\n * { x: 2, tag: 'b' },\n * { x: 2, tag: 'b' },\n * ],\n * ]);\n * ```\n *\n * @returns An iterable iterator of entries.\n */\n entries: () => IterableIterator<readonly [K, K]>;\n\n // Conversion\n\n /**\n * Converts the elements of the set to an array.\n *\n * @example\n *\n * ```ts\n * type Point = Readonly<{ x: number; tag: string }>;\n *\n * const toKey = (point: Point) => JSON.stringify(point);\n *\n * // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n * const fromKey = (key: string) => JSON.parse(key) as Point;\n *\n * const set = ISetMapped.create<Point, string>(\n * [\n * { x: 1, tag: 'a' },\n * { x: 2, tag: 'b' },\n * ],\n * toKey,\n * fromKey,\n * );\n *\n * assert.deepStrictEqual(set.toArray(), [\n * { x: 1, tag: 'a' },\n * { x: 2, tag: 'b' },\n * ]);\n * ```\n *\n * @returns A readonly array of elements.\n */\n toArray: () => readonly K[];\n\n /**\n * Returns the underlying readonly JavaScript Set of mapped keys.\n *\n * @example\n *\n * ```ts\n * type Point = Readonly<{ x: number; tag: string }>;\n *\n * const toKey = (point: Point) => JSON.stringify(point);\n *\n * // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n * const fromKey = (key: string) => JSON.parse(key) as Point;\n *\n * const set = ISetMapped.create<Point, string>(\n * [{ x: 1, tag: 'a' }],\n * toKey,\n * fromKey,\n * );\n *\n * const raw = set.toRawSet();\n *\n * assert.isTrue(isSet(raw));\n *\n * assert.isTrue(raw.has(toKey({ x: 1, tag: 'a' })));\n * ```\n *\n * @returns The raw ReadonlySet instance.\n */\n toRawSet: () => ReadonlySet<KM>;\n}>;\n\n/**\n * Represents an immutable set with custom element transformation and\n * high-performance operations.\n *\n * ISetMapped is a specialized persistent data structure that enables using\n * complex objects as set elements while maintaining the performance benefits of\n * JavaScript's native Set. It achieves this by requiring bidirectional\n * transformation functions that convert between your custom element type and a\n * primitive type that can be efficiently stored and compared for uniqueness.\n *\n * **Key Features:**\n *\n * - **Complex Elements**: Use objects, arrays, or any custom type as set elements\n * - **Immutable**: All mutation operations return new instances\n * - **Type Safe**: Full TypeScript support with compile-time element type\n * checking\n * - **Bidirectional**: Maintains ability to reconstruct original elements from\n * mapped keys\n * - **Set Algebra**: Complete support for mathematical set operations\n *\n * **Use Cases:**\n *\n * - Sets of entities with complex identifiers\n * - Deduplication of objects based on specific properties\n * - Performance-critical sets with non-primitive elements\n * - Mathematical set operations on complex data structures\n *\n * @template K The type of the custom elements in the set.\n * @template KM The type of the mapped primitive keys (string, number, etc.).\n */\nexport type ISetMapped<K, KM extends MapSetKeyType> = Iterable<K> &\n Readonly<ISetMappedInterface<K, KM>>;\n\n/** Provides utility functions for ISetMapped. */\nexport namespace ISetMapped {\n /**\n * Creates a new ISetMapped instance with custom element transformation\n * functions.\n *\n * This factory function creates an immutable set that can use complex objects\n * as elements by providing bidirectional transformation functions. The\n * `toKey` function converts your custom element type to a primitive type that\n * can be efficiently stored, while `fromKey` reconstructs the original\n * element type for iteration and access.\n *\n * **Performance:** O(n) where n is the number of elements in the iterable.\n *\n * @example\n *\n * ```ts\n * type Point = Readonly<{ x: number; tag: string }>;\n *\n * const toKey = (point: Point) => JSON.stringify(point);\n *\n * // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n * const fromKey = (key: string) => JSON.parse(key) as Point;\n *\n * const set = ISetMapped.create<Point, string>(\n * [\n * { x: 1, tag: 'a' },\n * { x: 1, tag: 'a' },\n * { x: 2, tag: 'b' },\n * ],\n * toKey,\n * fromKey,\n * );\n *\n * assert.deepStrictEqual(Array.from(set), [\n * { x: 1, tag: 'a' },\n * { x: 2, tag: 'b' },\n * ]);\n * ```\n *\n * @template K The type of the custom elements.\n * @template KM The type of the mapped primitive keys.\n * @param iterable An iterable of elements using the custom element type.\n * @param toKey A function that converts a custom element `K` to a primitive\n * key `KM`. This function must be deterministic and produce unique values\n * for unique elements.\n * @param fromKey A function that converts a primitive key `KM` back to the\n * custom element `K`. This should be the inverse of `toKey`.\n * @returns A new ISetMapped instance containing all unique elements from the\n * iterable.\n */\n export const create = <K, KM extends MapSetKeyType>(\n iterable: Iterable<K>,\n toKey: (a: K) => KM,\n fromKey: (k: KM) => K,\n ): ISetMapped<K, KM> => new ISetMappedClass<K, KM>(iterable, toKey, fromKey);\n\n /**\n * Checks if two ISetMapped instances are structurally equal.\n *\n * Two ISetMapped instances are considered equal if they have the same size\n * and contain exactly the same elements. The comparison is performed on the\n * underlying mapped keys, so the transformation functions themselves don't\n * need to be identical. Elements are compared based on their mapped key\n * representations.\n *\n * **Performance:** O(n) where n is the size of the smaller set.\n *\n * @example\n *\n * ```ts\n * type Point = Readonly<{ x: number; tag: string }>;\n *\n * const toKey = (point: Point) => JSON.stringify(point);\n *\n * // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n * const fromKey = (key: string) => JSON.parse(key) as Point;\n *\n * const first = ISetMapped.create<Point, string>(\n * [\n * { x: 1, tag: 'a' },\n * { x: 2, tag: 'b' },\n * ],\n * toKey,\n * fromKey,\n * );\n *\n * const second = ISetMapped.create<Point, string>(\n * [\n * { x: 2, tag: 'b' },\n * { x: 1, tag: 'a' },\n * ],\n * toKey,\n * fromKey,\n * );\n *\n * const third = ISetMapped.create<Point, string>(\n * [{ x: 3, tag: 'c' }],\n * toKey,\n * fromKey,\n * );\n *\n * assert.isTrue(ISetMapped.equal(first, second));\n *\n * assert.isFalse(ISetMapped.equal(first, third));\n * ```\n *\n * @template K The type of the custom elements.\n * @template KM The type of the mapped primitive keys.\n * @param a The first ISetMapped instance to compare.\n * @param b The second ISetMapped instance to compare.\n * @returns `true` if the sets contain exactly the same elements, `false`\n * otherwise.\n */\n export const equal = <K, KM extends MapSetKeyType>(\n a: ISetMapped<K, KM>,\n b: ISetMapped<K, KM>,\n ): boolean => a.size === b.size && a.every((e) => b.has(e));\n\n /**\n * Computes the difference between two ISetMapped instances.\n *\n * @example\n *\n * ```ts\n * type Point = Readonly<{ x: number; tag: string }>;\n *\n * const toKey = (point: Point) => JSON.stringify(point);\n *\n * // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n * const fromKey = (key: string) => JSON.parse(key) as Point;\n *\n * const previous = ISetMapped.create<Point, string>(\n * [\n * { x: 1, tag: 'a' },\n * { x: 2, tag: 'b' },\n * ],\n * toKey,\n * fromKey,\n * );\n *\n * const current = ISetMapped.create<Point, string>(\n * [\n * { x: 2, tag: 'b' },\n * { x: 3, tag: 'c' },\n * ],\n * toKey,\n * fromKey,\n * );\n *\n * const { added, deleted } = ISetMapped.diff(previous, current);\n *\n * assert.deepStrictEqual(Array.from(added), [{ x: 3, tag: 'c' }]);\n *\n * assert.deepStrictEqual(Array.from(deleted), [{ x: 1, tag: 'a' }]);\n * ```\n *\n * @template K The type of the elements.\n * @template KM The type of the mapped keys.\n * @param oldSet The original set.\n * @param newSet The new set.\n * @returns An object containing sets of added and deleted elements.\n */\n export const diff = <K, KM extends MapSetKeyType>(\n oldSet: ISetMapped<K, KM>,\n newSet: ISetMapped<K, KM>,\n ): ReadonlyRecord<'added' | 'deleted', ISetMapped<K, KM>> =>\n ({\n deleted: oldSet.subtract(newSet),\n added: newSet.subtract(oldSet),\n }) as const;\n\n /**\n * Computes the intersection of two ISetMapped instances.\n *\n * @example\n *\n * ```ts\n * type Point = Readonly<{ x: number; tag: string }>;\n *\n * const toKey = (point: Point) => JSON.stringify(point);\n *\n * // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n * const fromKey = (key: string) => JSON.parse(key) as Point;\n *\n * const left = ISetMapped.create<Point, string>(\n * [\n * { x: 1, tag: 'a' },\n * { x: 2, tag: 'b' },\n * ],\n * toKey,\n * fromKey,\n * );\n *\n * const right = ISetMapped.create<Point, string>(\n * [{ x: 2, tag: 'b' }],\n * toKey,\n * fromKey,\n * );\n *\n * const overlap = ISetMapped.intersection(left, right);\n *\n * assert.deepStrictEqual(Array.from(overlap), [{ x: 2, tag: 'b' }]);\n * ```\n *\n * @template K The type of the elements.\n * @template KM The type of the mapped keys.\n * @param a The first set.\n * @param b The second set.\n * @returns A new ISetMapped instance representing the intersection.\n */\n export const intersection = <K, KM extends MapSetKeyType>(\n a: ISetMapped<K, KM>,\n b: ISetMapped<K, KM>,\n ): ISetMapped<K, KM> => a.intersect(b);\n\n /**\n * Computes the union of two ISetMapped instances.\n *\n * @example\n *\n * ```ts\n * type Point = Readonly<{ x: number; tag: string }>;\n *\n * const toKey = (point: Point) => JSON.stringify(point);\n *\n * // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n * const fromKey = (key: string) => JSON.parse(key) as Point;\n *\n * const left = ISetMapped.create<Point, string>(\n * [{ x: 1, tag: 'a' }],\n * toKey,\n * fromKey,\n * );\n *\n * const right = ISetMapped.create<Point, string>(\n * [{ x: 2, tag: 'b' }],\n * toKey,\n * fromKey,\n * );\n *\n * const combined = ISetMapped.union(left, right);\n *\n * assert.deepStrictEqual(Array.from(combined), [\n * { x: 1, tag: 'a' },\n * { x: 2, tag: 'b' },\n * ]);\n * ```\n *\n * @template K The type of the elements.\n * @template KM The type of the mapped keys.\n * @param a The first set.\n * @param b The second set.\n * @returns A new ISetMapped instance representing the union.\n */\n export const union = <K, KM extends MapSetKeyType>(\n a: ISetMapped<K, KM>,\n b: ISetMapped<K, KM>,\n ): ISetMapped<K, KM> => a.union(b);\n}\n\n/**\n * Internal class implementation for ISetMapped providing immutable set\n * operations with element transformation.\n *\n * This class implements the ISetMapped interface by maintaining a JavaScript\n * Set with primitive keys internally while exposing an API that works with\n * custom element types. The transformation between custom and primitive\n * elements is handled transparently through the provided `toKey` and `fromKey`\n * functions.\n *\n * **Implementation Details:**\n *\n * - Uses ReadonlySet<KM> internally where KM is the primitive key type\n * - Stores transformation functions for bidirectional element conversion\n * - Implements copy-on-write semantics for efficiency\n * - Provides optional debug messaging for development\n *\n * @template K The type of the custom elements.\n * @template KM The type of the mapped primitive keys.\n * @implements ISetMapped\n * @implements Iterable\n * @internal This class should not be used directly. Use ISetMapped.create() instead.\n */\nclass ISetMappedClass<K, KM extends MapSetKeyType>\n implements ISetMapped<K, KM>, Iterable<K>\n{\n readonly #set: ReadonlySet<KM>;\n readonly #toKey: (a: K) => KM;\n readonly #fromKey: (k: KM) => K;\n readonly #showNotFoundMessage: boolean;\n\n /**\n * Constructs an ISetMappedClass instance with custom element transformation.\n *\n * @param iterable An iterable of elements using the custom element type K.\n * @param toKey A function that converts a custom element K to a primitive key\n * KM. Must be deterministic and produce unique values for unique elements.\n * @param fromKey A function that converts a primitive key KM back to the\n * custom element K. Should be the inverse of the toKey function.\n * @param showNotFoundMessage Whether to log warning messages when operations\n * are performed on non-existent elements. Useful for debugging. Defaults to\n * false for production use.\n * @internal Use ISetMapped.create() instead of calling this constructor directly.\n */\n constructor(\n iterable: Iterable<K>,\n toKey: (a: K) => KM,\n fromKey: (k: KM) => K,\n showNotFoundMessage: boolean = false,\n ) {\n this.#set = new Set(Array.from(iterable, toKey));\n\n this.#toKey = toKey;\n\n this.#fromKey = fromKey;\n\n this.#showNotFoundMessage = showNotFoundMessage;\n }\n\n /** @inheritdoc */\n get size(): SizeType.Arr {\n return asUint32(this.#set.size);\n }\n\n /** @inheritdoc */\n get isEmpty(): boolean {\n return this.size === 0;\n }\n\n /** @inheritdoc */\n has(key: K | (WidenLiteral<K> & {})): boolean {\n // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n return this.#set.has(this.#toKey(key as K));\n }\n\n /** @inheritdoc */\n every<L extends K>(\n predicate: (key: K) => key is L,\n ): this is ISetMapped<L, KM>;\n\n /** @inheritdoc */\n every(predicate: (key: K) => boolean): boolean;\n\n /** @inheritdoc */\n every(predicate: (key: K) => boolean): boolean {\n for (const key of this.values()) {\n if (!predicate(key)) return false;\n }\n\n return true;\n }\n\n /** @inheritdoc */\n some(predicate: (key: K) => boolean): boolean {\n for (const key of this.values()) {\n if (predicate(key)) return true;\n }\n\n return false;\n }\n\n /** @inheritdoc */\n add(key: K): ISetMapped<K, KM> {\n if (this.has(key)) return this;\n\n return ISetMapped.create(\n [...this.#set, this.#toKey(key)].map(this.#fromKey),\n this.#toKey,\n this.#fromKey,\n );\n }\n\n /** @inheritdoc */\n delete(key: K): ISetMapped<K, KM> {\n if (!this.has(key)) {\n if (this.#showNotFoundMessage) {\n console.warn(\n `ISetMapped.delete: key not found: ${String(this.#toKey(key))}`,\n );\n }\n\n return this;\n }\n\n const keyMapped = this.#toKey(key);\n\n return ISetMapped.create(\n Array.from(this.#set)\n .filter((k) => !Object.is(k, keyMapped))\n .map(this.#fromKey),\n this.#toKey,\n this.#fromKey,\n );\n }\n\n /** @inheritdoc */\n withMutations(\n actions: readonly Readonly<\n { type: 'add'; key: K } | { type: 'delete'; key: K }\n >[],\n ): ISetMapped<K, KM> {\n const mut_result = new Set<KM>(this.#set);\n\n const updateFn = (\n action: Readonly<{ type: 'add'; key: K } | { type: 'delete'; key: K }>,\n ): void => {\n const key = this.#toKey(action.key);\n\n switch (action.type) {\n case 'delete':\n mut_result.delete(key);\n\n break;\n\n case 'add':\n mut_result.add(key);\n\n break;\n }\n };\n\n for (const action of actions) {\n updateFn(action);\n }\n\n return ISetMapped.create<K, KM>(\n Array.from(mut_result, this.#fromKey),\n this.#toKey,\n this.#fromKey,\n );\n }\n\n /** @inheritdoc */\n map(mapFn: (key: K) => K): ISetMapped<K, KM> {\n return ISetMapped.create(\n this.toArray().map(mapFn),\n this.#toKey,\n this.#fromKey,\n );\n }\n\n /** @inheritdoc */\n filter(predicate: (key: K) => boolean): ISetMapped<K, KM> {\n return ISetMapped.create(\n this.toArray().filter(predicate),\n this.#toKey,\n this.#fromKey,\n );\n }\n\n /** @inheritdoc */\n filterNot(predicate: (key: K) => boolean): ISetMapped<K, KM> {\n return ISetMapped.create(\n this.toArray().filter((k) => !predicate(k)),\n this.#toKey,\n this.#fromKey,\n );\n }\n\n /** @inheritdoc */\n forEach(callbackfn: (key: K) => void): void {\n for (const km of this.#set) {\n callbackfn(this.#fromKey(km));\n }\n }\n\n /** @inheritdoc */\n isSubsetOf(set: ISetMapped<K, KM>): boolean {\n return this.every((k) => set.has(k));\n }\n\n /** @inheritdoc */\n isSupersetOf(set: ISetMapped<K, KM>): boolean {\n return set.every((k) => this.has(k));\n }\n\n /** @inheritdoc */\n subtract(set: ISetMapped<K, KM>): ISetMapped<K, KM> {\n return ISetMapped.create(\n this.toArray().filter((k) => !set.has(k)),\n this.#toKey,\n this.#fromKey,\n );\n }\n\n /** @inheritdoc */\n intersect(set: ISetMapped<K, KM>): ISetMapped<K, KM> {\n return ISetMapped.create(\n this.toArray().filter((k) => set.has(k)),\n this.#toKey,\n this.#fromKey,\n );\n }\n\n /** @inheritdoc */\n union(set: ISetMapped<K, KM>): ISetMapped<K, KM> {\n return ISetMapped.create(\n [...this.values(), ...set.values()],\n this.#toKey,\n this.#fromKey,\n );\n }\n\n /**\n * @example\n *\n * ```ts\n * type Point = Readonly<{ x: number; tag: string }>;\n *\n * const toKey = (point: Point) => JSON.stringify(point);\n *\n * // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n * const fromKey = (key: string) => JSON.parse(key) as Point;\n *\n * const set = ISetMapped.create<Point, string>(\n * [\n * { x: 1, tag: 'a' },\n * { x: 2, tag: 'b' },\n * ],\n * toKey,\n * fromKey,\n * );\n *\n * const collected = Array.from(set);\n *\n * assert.deepStrictEqual(collected, [\n * { x: 1, tag: 'a' },\n * { x: 2, tag: 'b' },\n * ]);\n * ```\n *\n * @inheritdoc\n */\n *[Symbol.iterator](): Iterator<K> {\n for (const k of this.keys()) {\n yield k;\n }\n }\n\n /** @inheritdoc */\n *keys(): IterableIterator<K> {\n for (const km of this.#set) {\n yield this.#fromKey(km);\n }\n }\n\n /** @inheritdoc */\n *values(): IterableIterator<K> {\n for (const km of this.#set) {\n // JavaScript Set's values() is an alias for keys()\n yield this.#fromKey(km);\n }\n }\n\n /** @inheritdoc */\n *entries(): IterableIterator<readonly [K, K]> {\n for (const km of this.#set) {\n // JavaScript Set's entries() yields [value, value]\n const a = this.#fromKey(km);\n\n yield [a, a];\n }\n }\n\n /** @inheritdoc */\n toArray(): readonly K[] {\n return Array.from(this.values());\n }\n\n /** @inheritdoc */\n toRawSet(): ReadonlySet<KM> {\n return this.#set;\n }\n}\n"],"names":["ISetMapped"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA23BO,IAAU;AAAA,CAAV,CAAUA,WAAAA,KAAV;AAkDE,EAAMA,WAAAA,CAAA,MAAA,GAAS,CACpB,QAAA,EACA,KAAA,EACA,YACsB,IAAI,eAAA,CAAuB,QAAA,EAAU,KAAA,EAAO,OAAO,CAAA;AA2DpE,EAAMA,YAAA,KAAA,GAAQ,CACnB,CAAA,EACA,CAAA,KACY,EAAE,IAAA,KAAS,CAAA,CAAE,IAAA,IAAQ,CAAA,CAAE,MAAM,CAAC,CAAA,KAAM,CAAA,CAAE,GAAA,CAAI,CAAC,CAAC,CAAA;AA8CnD,EAAMA,WAAAA,CAAA,IAAA,GAAO,CAClB,MAAA,EACA,MAAA,MAEC;AAAA,IACC,OAAA,EAAS,MAAA,CAAO,QAAA,CAAS,MAAM,CAAA;AAAA,IAC/B,KAAA,EAAO,MAAA,CAAO,QAAA,CAAS,MAAM;AAAA,GAC/B,CAAA;AAyCK,EAAMA,YAAA,YAAA,GAAe,CAC1B,GACA,CAAA,KACsB,CAAA,CAAE,UAAU,CAAC,CAAA;AAyC9B,EAAMA,YAAA,KAAA,GAAQ,CACnB,GACA,CAAA,KACsB,CAAA,CAAE,MAAM,CAAC,CAAA;AAAA,CAAA,EAjQlB,UAAA,KAAA,UAAA,GAAA,EAAA,CAAA,CAAA;AA2RjB,MAAM,eAAA,CAEN;AAAA,EACW,IAAA;AAAA,EACA,MAAA;AAAA,EACA,QAAA;AAAA,EACA,oBAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeT,WAAA,CACE,QAAA,EACA,KAAA,EACA,OAAA,EACA,sBAA+B,KAAA,EAC/B;AACA,IAAA,IAAA,CAAK,OAAO,IAAI,GAAA,CAAI,MAAM,IAAA,CAAK,QAAA,EAAU,KAAK,CAAC,CAAA;AAE/C,IAAA,IAAA,CAAK,MAAA,GAAS,KAAA;AAEd,IAAA,IAAA,CAAK,QAAA,GAAW,OAAA;AAEhB,IAAA,IAAA,CAAK,oBAAA,GAAuB,mBAAA;AAAA,EAC9B;AAAA;AAAA,EAGA,IAAI,IAAA,GAAqB;AACvB,IAAA,OAAO,QAAA,CAAS,IAAA,CAAK,IAAA,CAAK,IAAI,CAAA;AAAA,EAChC;AAAA;AAAA,EAGA,IAAI,OAAA,GAAmB;AACrB,IAAA,OAAO,KAAK,IAAA,KAAS,CAAA;AAAA,EACvB;AAAA;AAAA,EAGA,IAAI,GAAA,EAA0C;AAE5C,IAAA,OAAO,KAAK,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,MAAA,CAAO,GAAQ,CAAC,CAAA;AAAA,EAC5C;AAAA;AAAA,EAWA,MAAM,SAAA,EAAyC;AAC7C,IAAA,KAAA,MAAW,GAAA,IAAO,IAAA,CAAK,MAAA,EAAO,EAAG;AAC/B,MAAA,IAAI,CAAC,SAAA,CAAU,GAAG,CAAA,EAAG,OAAO,KAAA;AAAA,IAC9B;AAEA,IAAA,OAAO,IAAA;AAAA,EACT;AAAA;AAAA,EAGA,KAAK,SAAA,EAAyC;AAC5C,IAAA,KAAA,MAAW,GAAA,IAAO,IAAA,CAAK,MAAA,EAAO,EAAG;AAC/B,MAAA,IAAI,SAAA,CAAU,GAAG,CAAA,EAAG,OAAO,IAAA;AAAA,IAC7B;AAEA,IAAA,OAAO,KAAA;AAAA,EACT;AAAA;AAAA,EAGA,IAAI,GAAA,EAA2B;AAC7B,IAAA,IAAI,IAAA,CAAK,GAAA,CAAI,GAAG,CAAA,EAAG,OAAO,IAAA;AAE1B,IAAA,OAAO,UAAA,CAAW,MAAA;AAAA,MAChB,CAAC,GAAG,IAAA,CAAK,IAAA,EAAM,IAAA,CAAK,MAAA,CAAO,GAAG,CAAC,CAAA,CAAE,GAAA,CAAI,IAAA,CAAK,QAAQ,CAAA;AAAA,MAClD,IAAA,CAAK,MAAA;AAAA,MACL,IAAA,CAAK;AAAA,KACP;AAAA,EACF;AAAA;AAAA,EAGA,OAAO,GAAA,EAA2B;AAChC,IAAA,IAAI,CAAC,IAAA,CAAK,GAAA,CAAI,GAAG,CAAA,EAAG;AAClB,MAAA,IAAI,KAAK,oBAAA,EAAsB;AAC7B,QAAA,OAAA,CAAQ,IAAA;AAAA,UACN,qCAAqC,MAAA,CAAO,IAAA,CAAK,MAAA,CAAO,GAAG,CAAC,CAAC,CAAA;AAAA,SAC/D;AAAA,MACF;AAEA,MAAA,OAAO,IAAA;AAAA,IACT;AAEA,IAAA,MAAM,SAAA,GAAY,IAAA,CAAK,MAAA,CAAO,GAAG,CAAA;AAEjC,IAAA,OAAO,UAAA,CAAW,MAAA;AAAA,MAChB,MAAM,IAAA,CAAK,IAAA,CAAK,IAAI,CAAA,CACjB,OAAO,CAAC,CAAA,KAAM,CAAC,MAAA,CAAO,GAAG,CAAA,EAAG,SAAS,CAAC,CAAA,CACtC,GAAA,CAAI,KAAK,QAAQ,CAAA;AAAA,MACpB,IAAA,CAAK,MAAA;AAAA,MACL,IAAA,CAAK;AAAA,KACP;AAAA,EACF;AAAA;AAAA,EAGA,cACE,OAAA,EAGmB;AACnB,IAAA,MAAM,UAAA,GAAa,IAAI,GAAA,CAAQ,IAAA,CAAK,IAAI,CAAA;AAExC,IAAA,MAAM,QAAA,GAAW,CACf,MAAA,KACS;AACT,MAAA,MAAM,GAAA,GAAM,IAAA,CAAK,MAAA,CAAO,MAAA,CAAO,GAAG,CAAA;AAElC,MAAA,QAAQ,OAAO,IAAA;AAAM,QACnB,KAAK,QAAA;AACH,UAAA,UAAA,CAAW,OAAO,GAAG,CAAA;AAErB,UAAA;AAAA,QAEF,KAAK,KAAA;AACH,UAAA,UAAA,CAAW,IAAI,GAAG,CAAA;AAElB,UAAA;AAAA;AACJ,IACF,CAAA;AAEA,IAAA,KAAA,MAAW,UAAU,OAAA,EAAS;AAC5B,MAAA,QAAA,CAAS,MAAM,CAAA;AAAA,IACjB;AAEA,IAAA,OAAO,UAAA,CAAW,MAAA;AAAA,MAChB,KAAA,CAAM,IAAA,CAAK,UAAA,EAAY,IAAA,CAAK,QAAQ,CAAA;AAAA,MACpC,IAAA,CAAK,MAAA;AAAA,MACL,IAAA,CAAK;AAAA,KACP;AAAA,EACF;AAAA;AAAA,EAGA,IAAI,KAAA,EAAyC;AAC3C,IAAA,OAAO,UAAA,CAAW,MAAA;AAAA,MAChB,IAAA,CAAK,OAAA,EAAQ,CAAE,GAAA,CAAI,KAAK,CAAA;AAAA,MACxB,IAAA,CAAK,MAAA;AAAA,MACL,IAAA,CAAK;AAAA,KACP;AAAA,EACF;AAAA;AAAA,EAGA,OAAO,SAAA,EAAmD;AACxD,IAAA,OAAO,UAAA,CAAW,MAAA;AAAA,MAChB,IAAA,CAAK,OAAA,EAAQ,CAAE,MAAA,CAAO,SAAS,CAAA;AAAA,MAC/B,IAAA,CAAK,MAAA;AAAA,MACL,IAAA,CAAK;AAAA,KACP;AAAA,EACF;AAAA;AAAA,EAGA,UAAU,SAAA,EAAmD;AAC3D,IAAA,OAAO,UAAA,CAAW,MAAA;AAAA,MAChB,IAAA,CAAK,SAAQ,CAAE,MAAA,CAAO,CAAC,CAAA,KAAM,CAAC,SAAA,CAAU,CAAC,CAAC,CAAA;AAAA,MAC1C,IAAA,CAAK,MAAA;AAAA,MACL,IAAA,CAAK;AAAA,KACP;AAAA,EACF;AAAA;AAAA,EAGA,QAAQ,UAAA,EAAoC;AAC1C,IAAA,KAAA,MAAW,EAAA,IAAM,KAAK,IAAA,EAAM;AAC1B,MAAA,UAAA,CAAW,IAAA,CAAK,QAAA,CAAS,EAAE,CAAC,CAAA;AAAA,IAC9B;AAAA,EACF;AAAA;AAAA,EAGA,WAAW,GAAA,EAAiC;AAC1C,IAAA,OAAO,KAAK,KAAA,CAAM,CAAC,MAAM,GAAA,CAAI,GAAA,CAAI,CAAC,CAAC,CAAA;AAAA,EACrC;AAAA;AAAA,EAGA,aAAa,GAAA,EAAiC;AAC5C,IAAA,OAAO,IAAI,KAAA,CAAM,CAAC,MAAM,IAAA,CAAK,GAAA,CAAI,CAAC,CAAC,CAAA;AAAA,EACrC;AAAA;AAAA,EAGA,SAAS,GAAA,EAA2C;AAClD,IAAA,OAAO,UAAA,CAAW,MAAA;AAAA,MAChB,IAAA,CAAK,OAAA,EAAQ,CAAE,MAAA,CAAO,CAAC,MAAM,CAAC,GAAA,CAAI,GAAA,CAAI,CAAC,CAAC,CAAA;AAAA,MACxC,IAAA,CAAK,MAAA;AAAA,MACL,IAAA,CAAK;AAAA,KACP;AAAA,EACF;AAAA;AAAA,EAGA,UAAU,GAAA,EAA2C;AACnD,IAAA,OAAO,UAAA,CAAW,MAAA;AAAA,MAChB,IAAA,CAAK,SAAQ,CAAE,MAAA,CAAO,CAAC,CAAA,KAAM,GAAA,CAAI,GAAA,CAAI,CAAC,CAAC,CAAA;AAAA,MACvC,IAAA,CAAK,MAAA;AAAA,MACL,IAAA,CAAK;AAAA,KACP;AAAA,EACF;AAAA;AAAA,EAGA,MAAM,GAAA,EAA2C;AAC/C,IAAA,OAAO,UAAA,CAAW,MAAA;AAAA,MAChB,CAAC,GAAG,IAAA,CAAK,MAAA,IAAU,GAAG,GAAA,CAAI,QAAQ,CAAA;AAAA,MAClC,IAAA,CAAK,MAAA;AAAA,MACL,IAAA,CAAK;AAAA,KACP;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgCA,EAAE,MAAA,CAAO,QAAQ,CAAA,GAAiB;AAChC,IAAA,KAAA,MAAW,CAAA,IAAK,IAAA,CAAK,IAAA,EAAK,EAAG;AAC3B,MAAA,MAAM,CAAA;AAAA,IACR;AAAA,EACF;AAAA;AAAA,EAGA,CAAC,IAAA,GAA4B;AAC3B,IAAA,KAAA,MAAW,EAAA,IAAM,KAAK,IAAA,EAAM;AAC1B,MAAA,MAAM,IAAA,CAAK,SAAS,EAAE,CAAA;AAAA,IACxB;AAAA,EACF;AAAA;AAAA,EAGA,CAAC,MAAA,GAA8B;AAC7B,IAAA,KAAA,MAAW,EAAA,IAAM,KAAK,IAAA,EAAM;AAE1B,MAAA,MAAM,IAAA,CAAK,SAAS,EAAE,CAAA;AAAA,IACxB;AAAA,EACF;AAAA;AAAA,EAGA,CAAC,OAAA,GAA6C;AAC5C,IAAA,KAAA,MAAW,EAAA,IAAM,KAAK,IAAA,EAAM;AAE1B,MAAA,MAAM,CAAA,GAAI,IAAA,CAAK,QAAA,CAAS,EAAE,CAAA;AAE1B,MAAA,MAAM,CAAC,GAAG,CAAC,CAAA;AAAA,IACb;AAAA,EACF;AAAA;AAAA,EAGA,OAAA,GAAwB;AACtB,IAAA,OAAO,KAAA,CAAM,IAAA,CAAK,IAAA,CAAK,MAAA,EAAQ,CAAA;AAAA,EACjC;AAAA;AAAA,EAGA,QAAA,GAA4B;AAC1B,IAAA,OAAO,IAAA,CAAK,IAAA;AAAA,EACd;AACF;;;;"}
|
|
1
|
+
{"version":3,"file":"iset-mapped.mjs","sources":["../../src/collections/iset-mapped.mts"],"sourcesContent":["/* eslint-disable unicorn/prefer-iterator-to-array-at-end */\nimport {\n type FixedLengthTuple,\n type ReadonlyRecord,\n type WidenLiteral,\n} from 'ts-type-forge';\nimport { asUint32 } from '../number/index.mjs';\nimport { type MapSetKeyType, type SizeType } from '../types.mjs';\n\n/**\n * Interface for an immutable set with custom element mapping and membership\n * testing.\n *\n * ISetMapped allows you to use complex objects as set elements by providing\n * transformation functions that convert between your custom element type `K`\n * and a primitive `MapSetKeyType` `KM` that can be efficiently stored in\n * JavaScript's native Set. This enables set operations on complex elements\n * while maintaining type safety and immutability.\n *\n * **Key Features:**\n *\n * - **Custom Element Types**: Use any type as set elements by providing\n * `toKey`/`fromKey` functions\n * - **Immutable**: All operations return new instances, preserving immutability\n * - **Set Operations**: Full support for union, intersection, difference,\n * subset/superset checks\n * - **Type Safe**: Full TypeScript support with generic element types\n *\n * **Performance Characteristics:**\n *\n * - has: O(1) average case (plus element transformation overhead)\n * - add/delete: O(n) due to copying for immutability (plus element\n * transformation overhead)\n * - set operations (union, intersection, difference): O(n)\n * - map/filter operations: O(n)\n * - iteration: O(n) (plus element transformation overhead)\n *\n * @template K The type of the custom elements in the set.\n * @template KM The type of the mapped primitive keys (string, number, etc.).\n */\ntype ISetMappedInterface<K, KM extends MapSetKeyType> = Readonly<{\n /**\n * Creates a new ISetMapped instance.\n *\n * @param iterable An iterable of elements.\n * @param toKey A function that converts an element of type `K` to `KM`.\n * @param fromKey A function that converts a mapped key of type `KM` back to\n * `K`.\n */\n new (iterable: Iterable<K>, toKey: (a: K) => KM, fromKey: (k: KM) => K): void;\n\n // Getting information\n\n /**\n * The number of elements in the set.\n *\n * @example\n *\n * ```ts\n * type Point = Readonly<{ x: number; tag: string }>;\n *\n * const toKey = (point: Point) => JSON.stringify(point);\n *\n * // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n * const fromKey = (key: string) => JSON.parse(key) as Point;\n *\n * const points: readonly Point[] = [\n * { x: 1, tag: 'a' },\n * { x: 2, tag: 'b' },\n * ] as const;\n *\n * const set = ISetMapped.create<Point, string>(points, toKey, fromKey);\n *\n * assert.isTrue(set.size === 2);\n * ```\n */\n size: SizeType.Arr;\n\n /**\n * Checks if the set is empty.\n *\n * @example\n *\n * ```ts\n * type Point = Readonly<{ x: number; tag: string }>;\n *\n * const toKey = (point: Point) => JSON.stringify(point);\n *\n * // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n * const fromKey = (key: string) => JSON.parse(key) as Point;\n *\n * const empty = ISetMapped.create<Point, string>([], toKey, fromKey);\n *\n * const points = ISetMapped.create<Point, string>(\n * [{ x: 1, tag: 'a' }],\n * toKey,\n * fromKey,\n * );\n *\n * assert.isTrue(empty.isEmpty);\n *\n * assert.isFalse(points.isEmpty);\n * ```\n */\n isEmpty: boolean;\n\n /**\n * Checks if an element exists in the set.\n *\n * @example\n *\n * ```ts\n * type Point = Readonly<{ x: number; tag: string }>;\n *\n * const toKey = (point: Point) => JSON.stringify(point);\n *\n * // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n * const fromKey = (key: string) => JSON.parse(key) as Point;\n *\n * const set = ISetMapped.create<Point, string>(\n * [{ x: 1, tag: 'a' }],\n * toKey,\n * fromKey,\n * );\n *\n * assert.isTrue(set.has({ x: 1, tag: 'a' }));\n *\n * assert.isFalse(set.has({ x: 2, tag: 'b' }));\n * ```\n *\n * @param key The element to check.\n * @returns `true` if the element exists, `false` otherwise.\n */\n has: (key: K | (WidenLiteral<K> & {})) => boolean;\n\n // Reducing a value\n\n /**\n * Checks if all elements in the set satisfy a type predicate. Narrows the\n * type of elements in the set if the predicate returns true for all\n * elements.\n *\n *\n * @example\n *\n * ```ts\n * type Point = Readonly<{ x: number; tag: string }>;\n *\n * const toKey = (point: Point) => JSON.stringify(point);\n *\n * // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n * const fromKey = (key: string) => JSON.parse(key) as Point;\n *\n * const set = ISetMapped.create<Point, string>(\n * [\n * { x: 2, tag: 'even' },\n * { x: 4, tag: 'even' },\n * ],\n * toKey,\n * fromKey,\n * );\n *\n * const allEven = set.every((point) => point.x % 2 === 0);\n *\n * const narrowed = set.every(\n * (point): point is Readonly<{ x: 2 | 4; tag: 'even' }> =>\n * point.x % 2 === 0,\n * );\n *\n * assert.isTrue(allEven);\n *\n * assert.isTrue(narrowed);\n * ```\n *\n * @template L The narrowed type of the elements.\n * @param predicate A function to test each element.\n * @returns `true` if all elements satisfy the predicate, `false` otherwise.\n */\n every: ((predicate: (key: K) => boolean) => boolean) &\n (<L extends K>(\n predicate: (key: K) => key is L,\n ) => this is ISetMapped<L, KM>);\n\n /**\n * Checks if at least one element in the set satisfies a predicate.\n *\n * @example\n *\n * ```ts\n * type Point = Readonly<{ x: number; tag: string }>;\n *\n * const toKey = (point: Point) => JSON.stringify(point);\n *\n * // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n * const fromKey = (key: string) => JSON.parse(key) as Point;\n *\n * const set = ISetMapped.create<Point, string>(\n * [\n * { x: 1, tag: 'a' },\n * { x: 5, tag: 'b' },\n * ],\n * toKey,\n * fromKey,\n * );\n *\n * assert.isTrue(set.some((point) => point.x > 4));\n *\n * assert.isFalse(set.some((point) => point.x > 10));\n * ```\n *\n * @param predicate A function to test each element.\n * @returns `true` if at least one element satisfies the predicate, `false`\n * otherwise.\n */\n some: (predicate: (key: K) => boolean) => boolean;\n\n // Mutation\n\n /**\n * Adds an element to the set.\n *\n * @example\n *\n * ```ts\n * type Point = Readonly<{ x: number; tag: string }>;\n *\n * const toKey = (point: Point) => JSON.stringify(point);\n *\n * // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n * const fromKey = (key: string) => JSON.parse(key) as Point;\n *\n * const base = ISetMapped.create<Point, string>(\n * [{ x: 1, tag: 'a' }],\n * toKey,\n * fromKey,\n * );\n *\n * const withNew = base.add({ x: 2, tag: 'b' });\n *\n * const unchanged = base.add({ x: 1, tag: 'a' });\n *\n * assert.deepStrictEqual(Array.from(withNew), [\n * { x: 1, tag: 'a' },\n * { x: 2, tag: 'b' },\n * ]);\n *\n * assert.isTrue(unchanged === base);\n * ```\n *\n * @param key The element to add.\n * @returns A new ISetMapped instance with the element added.\n */\n add: (key: K) => ISetMapped<K, KM>;\n\n /**\n * Deletes an element from the set.\n *\n * @example\n *\n * ```ts\n * type Point = Readonly<{ x: number; tag: string }>;\n *\n * const toKey = (point: Point) => JSON.stringify(point);\n *\n * // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n * const fromKey = (key: string) => JSON.parse(key) as Point;\n *\n * const base = ISetMapped.create<Point, string>(\n * [\n * { x: 1, tag: 'a' },\n * { x: 2, tag: 'b' },\n * ],\n * toKey,\n * fromKey,\n * );\n *\n * const withoutSecond = base.delete({ x: 2, tag: 'b' });\n *\n * const unchanged = base.delete({ x: 3, tag: 'c' });\n *\n * assert.deepStrictEqual(Array.from(withoutSecond), [{ x: 1, tag: 'a' }]);\n *\n * assert.isTrue(unchanged === base);\n * ```\n *\n * @param key The element to delete.\n * @returns A new ISetMapped instance without the specified element.\n */\n delete: (key: K) => ISetMapped<K, KM>;\n\n /**\n * Applies a series of mutations to the set.\n *\n * @example\n *\n * ```ts\n * type Point = Readonly<{ x: number; tag: string }>;\n *\n * const toKey = (point: Point) => JSON.stringify(point);\n *\n * // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n * const fromKey = (key: string) => JSON.parse(key) as Point;\n *\n * const base = ISetMapped.create<Point, string>(\n * [\n * { x: 1, tag: 'a' },\n * { x: 2, tag: 'b' },\n * ],\n * toKey,\n * fromKey,\n * );\n *\n * const actions: readonly Readonly<\n * { type: 'add'; key: Point } | { type: 'delete'; key: Point }\n * >[] = [\n * { type: 'add', key: { x: 3, tag: 'c' } },\n * { type: 'delete', key: { x: 1, tag: 'a' } },\n * ] as const;\n *\n * const mutated = base.withMutations(actions);\n *\n * assert.deepStrictEqual(Array.from(mutated), [\n * { x: 2, tag: 'b' },\n * { x: 3, tag: 'c' },\n * ]);\n *\n * assert.deepStrictEqual(Array.from(base), [\n * { x: 1, tag: 'a' },\n * { x: 2, tag: 'b' },\n * ]);\n * ```\n *\n * @param actions An array of mutation actions (add or delete).\n * @returns A new ISetMapped instance with all mutations applied.\n */\n withMutations: (\n actions: readonly Readonly<\n { type: 'add'; key: K } | { type: 'delete'; key: K }\n >[],\n ) => ISetMapped<K, KM>;\n\n // Sequence algorithms\n\n /**\n * Maps the elements of the set to new elements. Note: The element type `K`\n * cannot be changed because `toKey` and `fromKey` would become unusable if\n * the mapped type `KM` changes.\n *\n * @example\n *\n * ```ts\n * type Point = Readonly<{ x: number; tag: string }>;\n *\n * const toKey = (point: Point) => JSON.stringify(point);\n *\n * // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n * const fromKey = (key: string) => JSON.parse(key) as Point;\n *\n * const set = ISetMapped.create<Point, string>(\n * [\n * { x: 1, tag: 'a' },\n * { x: 2, tag: 'b' },\n * ],\n * toKey,\n * fromKey,\n * );\n *\n * const shifted = set.map((point) => ({\n * x: point.x + 10,\n * tag: point.tag.toUpperCase(),\n * }));\n *\n * assert.deepStrictEqual(Array.from(shifted), [\n * { x: 11, tag: 'A' },\n * { x: 12, tag: 'B' },\n * ]);\n * ```\n *\n * @param mapFn A function that maps an element to a new element of the same\n * type `K`.\n * @returns A new ISetMapped instance with mapped elements.\n */\n map: (mapFn: (key: K) => K) => ISetMapped<K, KM>;\n\n /**\n * Filters the elements of the set based on a predicate.\n *\n * @example\n *\n * ```ts\n * type Point = Readonly<{ x: number; tag: string }>;\n *\n * const toKey = (point: Point) => JSON.stringify(point);\n *\n * // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n * const fromKey = (key: string) => JSON.parse(key) as Point;\n *\n * const set = ISetMapped.create<Point, string>(\n * [\n * { x: 1, tag: 'a' },\n * { x: 2, tag: 'b' },\n * { x: 3, tag: 'c' },\n * ],\n * toKey,\n * fromKey,\n * );\n *\n * const evenPoints = set.filter((point) => point.x % 2 === 0);\n *\n * assert.deepStrictEqual(Array.from(evenPoints), [{ x: 2, tag: 'b' }]);\n * ```\n *\n * @param predicate A function to test each element.\n * @returns A new ISetMapped instance with elements that satisfy the\n * predicate.\n */\n filter: (predicate: (value: K) => boolean) => ISetMapped<K, KM>;\n\n /**\n * Filters the elements of the set by excluding elements for which the\n * predicate returns true.\n *\n * @example\n *\n * ```ts\n * type Point = Readonly<{ x: number; tag: string }>;\n *\n * const toKey = (point: Point) => JSON.stringify(point);\n *\n * // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n * const fromKey = (key: string) => JSON.parse(key) as Point;\n *\n * const set = ISetMapped.create<Point, string>(\n * [\n * { x: 1, tag: 'a' },\n * { x: 2, tag: 'b' },\n * ],\n * toKey,\n * fromKey,\n * );\n *\n * const withoutEven = set.filterNot((point) => point.x % 2 === 0);\n *\n * assert.deepStrictEqual(Array.from(withoutEven), [{ x: 1, tag: 'a' }]);\n * ```\n *\n * @param predicate A function to test each element.\n * @returns A new ISetMapped instance with elements for which the predicate\n * returned `false`.\n */\n filterNot: (predicate: (key: K) => boolean) => ISetMapped<K, KM>;\n\n // Side effects\n\n /**\n * Executes a callback function for each element in the set.\n *\n * @example\n *\n * ```ts\n * type Point = Readonly<{ x: number; tag: string }>;\n *\n * const toKey = (point: Point) => JSON.stringify(point);\n *\n * // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n * const fromKey = (key: string) => JSON.parse(key) as Point;\n *\n * const set = ISetMapped.create<Point, string>(\n * [\n * { x: 1, tag: 'a' },\n * { x: 2, tag: 'b' },\n * ],\n * toKey,\n * fromKey,\n * );\n *\n * const mut_collected: Point[] = [];\n *\n * set.forEach((point) => {\n * mut_collected.push(point);\n * });\n *\n * assert.deepStrictEqual(mut_collected, [\n * { x: 1, tag: 'a' },\n * { x: 2, tag: 'b' },\n * ]);\n * ```\n *\n * @param callbackfn A function to execute for each element.\n */\n forEach: (callbackfn: (key: K) => void) => void;\n\n // Comparison\n\n /**\n * Checks if this set is a subset of another set.\n *\n * @example\n *\n * ```ts\n * type Point = Readonly<{ x: number; tag: string }>;\n *\n * const toKey = (point: Point) => JSON.stringify(point);\n *\n * // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n * const fromKey = (key: string) => JSON.parse(key) as Point;\n *\n * const subset = ISetMapped.create<Point, string>(\n * [{ x: 1, tag: 'a' }],\n * toKey,\n * fromKey,\n * );\n *\n * const superset = ISetMapped.create<Point, string>(\n * [\n * { x: 1, tag: 'a' },\n * { x: 2, tag: 'b' },\n * ],\n * toKey,\n * fromKey,\n * );\n *\n * assert.isTrue(subset.isSubsetOf(superset));\n *\n * assert.isFalse(superset.isSubsetOf(subset));\n * ```\n *\n * @param set The other set.\n * @returns `true` if this set is a subset of the other set, `false`\n * otherwise.\n */\n isSubsetOf: (set: ISetMapped<K, KM>) => boolean;\n\n /**\n * Checks if this set is a superset of another set.\n *\n * @example\n *\n * ```ts\n * type Point = Readonly<{ x: number; tag: string }>;\n *\n * const toKey = (point: Point) => JSON.stringify(point);\n *\n * // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n * const fromKey = (key: string) => JSON.parse(key) as Point;\n *\n * const superset = ISetMapped.create<Point, string>(\n * [\n * { x: 1, tag: 'a' },\n * { x: 2, tag: 'b' },\n * ],\n * toKey,\n * fromKey,\n * );\n *\n * const subset = ISetMapped.create<Point, string>(\n * [{ x: 2, tag: 'b' }],\n * toKey,\n * fromKey,\n * );\n *\n * assert.isTrue(superset.isSupersetOf(subset));\n *\n * assert.isFalse(subset.isSupersetOf(superset));\n * ```\n *\n * @param set The other set.\n * @returns `true` if this set is a superset of the other set, `false`\n * otherwise.\n */\n isSupersetOf: (set: ISetMapped<K, KM>) => boolean;\n\n /**\n * Returns a new set with elements that are in this set but not in another\n * set.\n *\n * @example\n *\n * ```ts\n * type Point = Readonly<{ x: number; tag: string }>;\n *\n * const toKey = (point: Point) => JSON.stringify(point);\n *\n * // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n * const fromKey = (key: string) => JSON.parse(key) as Point;\n *\n * const left = ISetMapped.create<Point, string>(\n * [\n * { x: 1, tag: 'a' },\n * { x: 2, tag: 'b' },\n * { x: 3, tag: 'c' },\n * ],\n * toKey,\n * fromKey,\n * );\n *\n * const right = ISetMapped.create<Point, string>(\n * [{ x: 2, tag: 'b' }],\n * toKey,\n * fromKey,\n * );\n *\n * const difference = left.subtract(right);\n *\n * assert.deepStrictEqual(Array.from(difference), [\n * { x: 1, tag: 'a' },\n * { x: 3, tag: 'c' },\n * ]);\n * ```\n *\n * @param set The other set.\n * @returns A new ISetMapped instance representing the set difference.\n */\n subtract: (set: ISetMapped<K, KM>) => ISetMapped<K, KM>;\n\n /**\n * Returns a new set with elements that are common to both this set and\n * another set.\n *\n * @example\n *\n * ```ts\n * type Point = Readonly<{ x: number; tag: string }>;\n *\n * const toKey = (point: Point) => JSON.stringify(point);\n *\n * // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n * const fromKey = (key: string) => JSON.parse(key) as Point;\n *\n * const left = ISetMapped.create<Point, string>(\n * [\n * { x: 1, tag: 'a' },\n * { x: 2, tag: 'b' },\n * ],\n * toKey,\n * fromKey,\n * );\n *\n * const right = ISetMapped.create<Point, string>(\n * [{ x: 2, tag: 'b' }],\n * toKey,\n * fromKey,\n * );\n *\n * const intersection = left.intersect(right);\n *\n * assert.deepStrictEqual(Array.from(intersection), [{ x: 2, tag: 'b' }]);\n * ```\n *\n * @param set The other set.\n * @returns A new ISetMapped instance representing the set intersection.\n */\n intersect: (set: ISetMapped<K, KM>) => ISetMapped<K, KM>;\n\n /**\n * Returns a new set with all elements from both this set and another set.\n *\n * @example\n *\n * ```ts\n * type Point = Readonly<{ x: number; tag: string }>;\n *\n * const toKey = (point: Point) => JSON.stringify(point);\n *\n * // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n * const fromKey = (key: string) => JSON.parse(key) as Point;\n *\n * const left = ISetMapped.create<Point, string>(\n * [{ x: 1, tag: 'a' }],\n * toKey,\n * fromKey,\n * );\n *\n * const right = ISetMapped.create<Point, string>(\n * [{ x: 2, tag: 'b' }],\n * toKey,\n * fromKey,\n * );\n *\n * const combined = left.union(right);\n *\n * assert.deepStrictEqual(Array.from(combined), [\n * { x: 1, tag: 'a' },\n * { x: 2, tag: 'b' },\n * ]);\n * ```\n *\n * @param set The other set.\n * @returns A new ISetMapped instance representing the set union.\n */\n union: (set: ISetMapped<K, KM>) => ISetMapped<K, KM>;\n\n // Iterators\n\n /**\n * Returns an iterator for the elements in the set (alias for values).\n *\n * @example\n *\n * ```ts\n * type Point = Readonly<{ x: number; tag: string }>;\n *\n * const toKey = (point: Point) => JSON.stringify(point);\n *\n * // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n * const fromKey = (key: string) => JSON.parse(key) as Point;\n *\n * const set = ISetMapped.create<Point, string>(\n * [\n * { x: 1, tag: 'a' },\n * { x: 2, tag: 'b' },\n * ],\n * toKey,\n * fromKey,\n * );\n *\n * assert.deepStrictEqual(Array.from(set.keys()), [\n * { x: 1, tag: 'a' },\n * { x: 2, tag: 'b' },\n * ]);\n * ```\n *\n * @returns An iterable iterator of elements.\n */\n keys: () => IterableIterator<K>;\n\n /**\n * Returns an iterator for the elements in the set.\n *\n * @example\n *\n * ```ts\n * type Point = Readonly<{ x: number; tag: string }>;\n *\n * const toKey = (point: Point) => JSON.stringify(point);\n *\n * // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n * const fromKey = (key: string) => JSON.parse(key) as Point;\n *\n * const set = ISetMapped.create<Point, string>(\n * [\n * { x: 1, tag: 'a' },\n * { x: 2, tag: 'b' },\n * ],\n * toKey,\n * fromKey,\n * );\n *\n * assert.deepStrictEqual(Array.from(set.values()), [\n * { x: 1, tag: 'a' },\n * { x: 2, tag: 'b' },\n * ]);\n * ```\n *\n * @returns An iterable iterator of elements.\n */\n values: () => IterableIterator<K>;\n\n /**\n * Returns an iterator for the entries (element-element pairs) in the set.\n *\n * @example\n *\n * ```ts\n * type Point = Readonly<{ x: number; tag: string }>;\n *\n * const toKey = (point: Point) => JSON.stringify(point);\n *\n * // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n * const fromKey = (key: string) => JSON.parse(key) as Point;\n *\n * const set = ISetMapped.create<Point, string>(\n * [\n * { x: 1, tag: 'a' },\n * { x: 2, tag: 'b' },\n * ],\n * toKey,\n * fromKey,\n * );\n *\n * assert.deepStrictEqual(Array.from(set.entries()), [\n * [\n * { x: 1, tag: 'a' },\n * { x: 1, tag: 'a' },\n * ],\n * [\n * { x: 2, tag: 'b' },\n * { x: 2, tag: 'b' },\n * ],\n * ]);\n * ```\n *\n * @returns An iterable iterator of entries.\n */\n entries: () => IterableIterator<FixedLengthTuple<2, K>>;\n\n // Conversion\n\n /**\n * Converts the elements of the set to an array.\n *\n * @example\n *\n * ```ts\n * type Point = Readonly<{ x: number; tag: string }>;\n *\n * const toKey = (point: Point) => JSON.stringify(point);\n *\n * // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n * const fromKey = (key: string) => JSON.parse(key) as Point;\n *\n * const set = ISetMapped.create<Point, string>(\n * [\n * { x: 1, tag: 'a' },\n * { x: 2, tag: 'b' },\n * ],\n * toKey,\n * fromKey,\n * );\n *\n * assert.deepStrictEqual(set.toArray(), [\n * { x: 1, tag: 'a' },\n * { x: 2, tag: 'b' },\n * ]);\n * ```\n *\n * @returns A readonly array of elements.\n */\n toArray: () => readonly K[];\n\n /**\n * Returns the underlying readonly JavaScript Set of mapped keys.\n *\n * @example\n *\n * ```ts\n * type Point = Readonly<{ x: number; tag: string }>;\n *\n * const toKey = (point: Point) => JSON.stringify(point);\n *\n * // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n * const fromKey = (key: string) => JSON.parse(key) as Point;\n *\n * const set = ISetMapped.create<Point, string>(\n * [{ x: 1, tag: 'a' }],\n * toKey,\n * fromKey,\n * );\n *\n * const raw = set.toRawSet();\n *\n * assert.isTrue(isSet(raw));\n *\n * assert.isTrue(raw.has(toKey({ x: 1, tag: 'a' })));\n * ```\n *\n * @returns The raw ReadonlySet instance.\n */\n toRawSet: () => ReadonlySet<KM>;\n}>;\n\n/**\n * Represents an immutable set with custom element transformation and\n * high-performance operations.\n *\n * ISetMapped is a specialized persistent data structure that enables using\n * complex objects as set elements while maintaining the performance benefits of\n * JavaScript's native Set. It achieves this by requiring bidirectional\n * transformation functions that convert between your custom element type and a\n * primitive type that can be efficiently stored and compared for uniqueness.\n *\n * **Key Features:**\n *\n * - **Complex Elements**: Use objects, arrays, or any custom type as set elements\n * - **Immutable**: All mutation operations return new instances\n * - **Type Safe**: Full TypeScript support with compile-time element type\n * checking\n * - **Bidirectional**: Maintains ability to reconstruct original elements from\n * mapped keys\n * - **Set Algebra**: Complete support for mathematical set operations\n *\n * **Use Cases:**\n *\n * - Sets of entities with complex identifiers\n * - Deduplication of objects based on specific properties\n * - Performance-critical sets with non-primitive elements\n * - Mathematical set operations on complex data structures\n *\n * @template K The type of the custom elements in the set.\n * @template KM The type of the mapped primitive keys (string, number, etc.).\n */\nexport type ISetMapped<K, KM extends MapSetKeyType> = Iterable<K> &\n Readonly<ISetMappedInterface<K, KM>>;\n\n/** Provides utility functions for ISetMapped. */\nexport namespace ISetMapped {\n /**\n * Creates a new ISetMapped instance with custom element transformation\n * functions.\n *\n * This factory function creates an immutable set that can use complex objects\n * as elements by providing bidirectional transformation functions. The\n * `toKey` function converts your custom element type to a primitive type that\n * can be efficiently stored, while `fromKey` reconstructs the original\n * element type for iteration and access.\n *\n * **Performance:** O(n) where n is the number of elements in the iterable.\n *\n * @example\n *\n * ```ts\n * type Point = Readonly<{ x: number; tag: string }>;\n *\n * const toKey = (point: Point) => JSON.stringify(point);\n *\n * // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n * const fromKey = (key: string) => JSON.parse(key) as Point;\n *\n * const set = ISetMapped.create<Point, string>(\n * [\n * { x: 1, tag: 'a' },\n * { x: 1, tag: 'a' },\n * { x: 2, tag: 'b' },\n * ],\n * toKey,\n * fromKey,\n * );\n *\n * assert.deepStrictEqual(Array.from(set), [\n * { x: 1, tag: 'a' },\n * { x: 2, tag: 'b' },\n * ]);\n * ```\n *\n * @template K The type of the custom elements.\n * @template KM The type of the mapped primitive keys.\n * @param iterable An iterable of elements using the custom element type.\n * @param toKey A function that converts a custom element `K` to a primitive\n * key `KM`. This function must be deterministic and produce unique values\n * for unique elements.\n * @param fromKey A function that converts a primitive key `KM` back to the\n * custom element `K`. This should be the inverse of `toKey`.\n * @returns A new ISetMapped instance containing all unique elements from the\n * iterable.\n */\n export const create = <K, KM extends MapSetKeyType>(\n iterable: Iterable<K>,\n toKey: (a: K) => KM,\n fromKey: (k: KM) => K,\n ): ISetMapped<K, KM> => new ISetMappedClass<K, KM>(iterable, toKey, fromKey);\n\n /**\n * Checks if two ISetMapped instances are structurally equal.\n *\n * Two ISetMapped instances are considered equal if they have the same size\n * and contain exactly the same elements. The comparison is performed on the\n * underlying mapped keys, so the transformation functions themselves don't\n * need to be identical. Elements are compared based on their mapped key\n * representations.\n *\n * **Performance:** O(n) where n is the size of the smaller set.\n *\n * @example\n *\n * ```ts\n * type Point = Readonly<{ x: number; tag: string }>;\n *\n * const toKey = (point: Point) => JSON.stringify(point);\n *\n * // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n * const fromKey = (key: string) => JSON.parse(key) as Point;\n *\n * const first = ISetMapped.create<Point, string>(\n * [\n * { x: 1, tag: 'a' },\n * { x: 2, tag: 'b' },\n * ],\n * toKey,\n * fromKey,\n * );\n *\n * const second = ISetMapped.create<Point, string>(\n * [\n * { x: 2, tag: 'b' },\n * { x: 1, tag: 'a' },\n * ],\n * toKey,\n * fromKey,\n * );\n *\n * const third = ISetMapped.create<Point, string>(\n * [{ x: 3, tag: 'c' }],\n * toKey,\n * fromKey,\n * );\n *\n * assert.isTrue(ISetMapped.equal(first, second));\n *\n * assert.isFalse(ISetMapped.equal(first, third));\n * ```\n *\n * @template K The type of the custom elements.\n * @template KM The type of the mapped primitive keys.\n * @param a The first ISetMapped instance to compare.\n * @param b The second ISetMapped instance to compare.\n * @returns `true` if the sets contain exactly the same elements, `false`\n * otherwise.\n */\n export const equal = <K, KM extends MapSetKeyType>(\n a: ISetMapped<K, KM>,\n b: ISetMapped<K, KM>,\n ): boolean => a.size === b.size && a.every((e) => b.has(e));\n\n /**\n * Computes the difference between two ISetMapped instances.\n *\n * @example\n *\n * ```ts\n * type Point = Readonly<{ x: number; tag: string }>;\n *\n * const toKey = (point: Point) => JSON.stringify(point);\n *\n * // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n * const fromKey = (key: string) => JSON.parse(key) as Point;\n *\n * const previous = ISetMapped.create<Point, string>(\n * [\n * { x: 1, tag: 'a' },\n * { x: 2, tag: 'b' },\n * ],\n * toKey,\n * fromKey,\n * );\n *\n * const current = ISetMapped.create<Point, string>(\n * [\n * { x: 2, tag: 'b' },\n * { x: 3, tag: 'c' },\n * ],\n * toKey,\n * fromKey,\n * );\n *\n * const { added, deleted } = ISetMapped.diff(previous, current);\n *\n * assert.deepStrictEqual(Array.from(added), [{ x: 3, tag: 'c' }]);\n *\n * assert.deepStrictEqual(Array.from(deleted), [{ x: 1, tag: 'a' }]);\n * ```\n *\n * @template K The type of the elements.\n * @template KM The type of the mapped keys.\n * @param oldSet The original set.\n * @param newSet The new set.\n * @returns An object containing sets of added and deleted elements.\n */\n export const diff = <K, KM extends MapSetKeyType>(\n oldSet: ISetMapped<K, KM>,\n newSet: ISetMapped<K, KM>,\n ): ReadonlyRecord<'added' | 'deleted', ISetMapped<K, KM>> =>\n ({\n deleted: oldSet.subtract(newSet),\n added: newSet.subtract(oldSet),\n }) as const;\n\n /**\n * Computes the intersection of two ISetMapped instances.\n *\n * @example\n *\n * ```ts\n * type Point = Readonly<{ x: number; tag: string }>;\n *\n * const toKey = (point: Point) => JSON.stringify(point);\n *\n * // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n * const fromKey = (key: string) => JSON.parse(key) as Point;\n *\n * const left = ISetMapped.create<Point, string>(\n * [\n * { x: 1, tag: 'a' },\n * { x: 2, tag: 'b' },\n * ],\n * toKey,\n * fromKey,\n * );\n *\n * const right = ISetMapped.create<Point, string>(\n * [{ x: 2, tag: 'b' }],\n * toKey,\n * fromKey,\n * );\n *\n * const overlap = ISetMapped.intersection(left, right);\n *\n * assert.deepStrictEqual(Array.from(overlap), [{ x: 2, tag: 'b' }]);\n * ```\n *\n * @template K The type of the elements.\n * @template KM The type of the mapped keys.\n * @param a The first set.\n * @param b The second set.\n * @returns A new ISetMapped instance representing the intersection.\n */\n export const intersection = <K, KM extends MapSetKeyType>(\n a: ISetMapped<K, KM>,\n b: ISetMapped<K, KM>,\n ): ISetMapped<K, KM> => a.intersect(b);\n\n /**\n * Computes the union of two ISetMapped instances.\n *\n * @example\n *\n * ```ts\n * type Point = Readonly<{ x: number; tag: string }>;\n *\n * const toKey = (point: Point) => JSON.stringify(point);\n *\n * // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n * const fromKey = (key: string) => JSON.parse(key) as Point;\n *\n * const left = ISetMapped.create<Point, string>(\n * [{ x: 1, tag: 'a' }],\n * toKey,\n * fromKey,\n * );\n *\n * const right = ISetMapped.create<Point, string>(\n * [{ x: 2, tag: 'b' }],\n * toKey,\n * fromKey,\n * );\n *\n * const combined = ISetMapped.union(left, right);\n *\n * assert.deepStrictEqual(Array.from(combined), [\n * { x: 1, tag: 'a' },\n * { x: 2, tag: 'b' },\n * ]);\n * ```\n *\n * @template K The type of the elements.\n * @template KM The type of the mapped keys.\n * @param a The first set.\n * @param b The second set.\n * @returns A new ISetMapped instance representing the union.\n */\n export const union = <K, KM extends MapSetKeyType>(\n a: ISetMapped<K, KM>,\n b: ISetMapped<K, KM>,\n ): ISetMapped<K, KM> => a.union(b);\n}\n\n/**\n * Internal class implementation for ISetMapped providing immutable set\n * operations with element transformation.\n *\n * This class implements the ISetMapped interface by maintaining a JavaScript\n * Set with primitive keys internally while exposing an API that works with\n * custom element types. The transformation between custom and primitive\n * elements is handled transparently through the provided `toKey` and `fromKey`\n * functions.\n *\n * **Implementation Details:**\n *\n * - Uses ReadonlySet<KM> internally where KM is the primitive key type\n * - Stores transformation functions for bidirectional element conversion\n * - Implements copy-on-write semantics for efficiency\n * - Provides optional debug messaging for development\n *\n * @template K The type of the custom elements.\n * @template KM The type of the mapped primitive keys.\n * @implements ISetMapped\n * @implements Iterable\n * @internal This class should not be used directly. Use ISetMapped.create() instead.\n */\nclass ISetMappedClass<K, KM extends MapSetKeyType>\n implements ISetMapped<K, KM>, Iterable<K>\n{\n readonly #set: ReadonlySet<KM>;\n readonly #toKey: (a: K) => KM;\n readonly #fromKey: (k: KM) => K;\n readonly #showNotFoundMessage: boolean;\n\n /**\n * Constructs an ISetMappedClass instance with custom element transformation.\n *\n * @param iterable An iterable of elements using the custom element type K.\n * @param toKey A function that converts a custom element K to a primitive key\n * KM. Must be deterministic and produce unique values for unique elements.\n * @param fromKey A function that converts a primitive key KM back to the\n * custom element K. Should be the inverse of the toKey function.\n * @param showNotFoundMessage Whether to log warning messages when operations\n * are performed on non-existent elements. Useful for debugging. Defaults to\n * false for production use.\n * @internal Use ISetMapped.create() instead of calling this constructor directly.\n */\n constructor(\n iterable: Iterable<K>,\n toKey: (a: K) => KM,\n fromKey: (k: KM) => K,\n showNotFoundMessage: boolean = false,\n ) {\n this.#set = new Set(Array.from(iterable, toKey));\n\n this.#toKey = toKey;\n\n this.#fromKey = fromKey;\n\n this.#showNotFoundMessage = showNotFoundMessage;\n }\n\n /** @inheritdoc */\n get size(): SizeType.Arr {\n return asUint32(this.#set.size);\n }\n\n /** @inheritdoc */\n get isEmpty(): boolean {\n return this.size === 0;\n }\n\n /** @inheritdoc */\n has(key: K | (WidenLiteral<K> & {})): boolean {\n // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n return this.#set.has(this.#toKey(key as K));\n }\n\n /** @inheritdoc */\n every<L extends K>(\n predicate: (key: K) => key is L,\n ): this is ISetMapped<L, KM>;\n\n /** @inheritdoc */\n every(predicate: (key: K) => boolean): boolean;\n\n /** @inheritdoc */\n every(predicate: (key: K) => boolean): boolean {\n for (const key of this.values()) {\n if (!predicate(key)) return false;\n }\n\n return true;\n }\n\n /** @inheritdoc */\n some(predicate: (key: K) => boolean): boolean {\n for (const key of this.values()) {\n if (predicate(key)) return true;\n }\n\n return false;\n }\n\n /** @inheritdoc */\n add(key: K): ISetMapped<K, KM> {\n if (this.has(key)) return this;\n\n return ISetMapped.create(\n [...this.#set, this.#toKey(key)].map(this.#fromKey),\n this.#toKey,\n this.#fromKey,\n );\n }\n\n /** @inheritdoc */\n delete(key: K): ISetMapped<K, KM> {\n if (!this.has(key)) {\n if (this.#showNotFoundMessage) {\n console.warn(\n `ISetMapped.delete: key not found: ${String(this.#toKey(key))}`,\n );\n }\n\n return this;\n }\n\n const keyMapped = this.#toKey(key);\n\n return ISetMapped.create(\n Array.from(this.#set)\n .filter((k) => !Object.is(k, keyMapped))\n .map(this.#fromKey),\n this.#toKey,\n this.#fromKey,\n );\n }\n\n /** @inheritdoc */\n withMutations(\n actions: readonly Readonly<\n { type: 'add'; key: K } | { type: 'delete'; key: K }\n >[],\n ): ISetMapped<K, KM> {\n const mut_result = new Set<KM>(this.#set);\n\n const updateFn = (\n action: Readonly<{ type: 'add'; key: K } | { type: 'delete'; key: K }>,\n ): void => {\n const key = this.#toKey(action.key);\n\n switch (action.type) {\n case 'delete':\n mut_result.delete(key);\n\n break;\n\n case 'add':\n mut_result.add(key);\n\n break;\n }\n };\n\n for (const action of actions) {\n updateFn(action);\n }\n\n return ISetMapped.create<K, KM>(\n Array.from(mut_result, this.#fromKey),\n this.#toKey,\n this.#fromKey,\n );\n }\n\n /** @inheritdoc */\n map(mapFn: (key: K) => K): ISetMapped<K, KM> {\n return ISetMapped.create(\n this.toArray().map(mapFn),\n this.#toKey,\n this.#fromKey,\n );\n }\n\n /** @inheritdoc */\n filter(predicate: (key: K) => boolean): ISetMapped<K, KM> {\n return ISetMapped.create(\n this.toArray().filter(predicate),\n this.#toKey,\n this.#fromKey,\n );\n }\n\n /** @inheritdoc */\n filterNot(predicate: (key: K) => boolean): ISetMapped<K, KM> {\n return ISetMapped.create(\n this.toArray().filter((k) => !predicate(k)),\n this.#toKey,\n this.#fromKey,\n );\n }\n\n /** @inheritdoc */\n forEach(callbackfn: (key: K) => void): void {\n for (const km of this.#set) {\n callbackfn(this.#fromKey(km));\n }\n }\n\n /** @inheritdoc */\n isSubsetOf(set: ISetMapped<K, KM>): boolean {\n return this.every((k) => set.has(k));\n }\n\n /** @inheritdoc */\n isSupersetOf(set: ISetMapped<K, KM>): boolean {\n return set.every((k) => this.has(k));\n }\n\n /** @inheritdoc */\n subtract(set: ISetMapped<K, KM>): ISetMapped<K, KM> {\n return ISetMapped.create(\n this.toArray().filter((k) => !set.has(k)),\n this.#toKey,\n this.#fromKey,\n );\n }\n\n /** @inheritdoc */\n intersect(set: ISetMapped<K, KM>): ISetMapped<K, KM> {\n return ISetMapped.create(\n this.toArray().filter((k) => set.has(k)),\n this.#toKey,\n this.#fromKey,\n );\n }\n\n /** @inheritdoc */\n union(set: ISetMapped<K, KM>): ISetMapped<K, KM> {\n return ISetMapped.create(\n [...this.values(), ...set.values()],\n this.#toKey,\n this.#fromKey,\n );\n }\n\n /**\n * @example\n *\n * ```ts\n * type Point = Readonly<{ x: number; tag: string }>;\n *\n * const toKey = (point: Point) => JSON.stringify(point);\n *\n * // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n * const fromKey = (key: string) => JSON.parse(key) as Point;\n *\n * const set = ISetMapped.create<Point, string>(\n * [\n * { x: 1, tag: 'a' },\n * { x: 2, tag: 'b' },\n * ],\n * toKey,\n * fromKey,\n * );\n *\n * const collected = Array.from(set);\n *\n * assert.deepStrictEqual(collected, [\n * { x: 1, tag: 'a' },\n * { x: 2, tag: 'b' },\n * ]);\n * ```\n *\n * @inheritdoc\n */\n *[Symbol.iterator](): Iterator<K> {\n for (const k of this.keys()) {\n yield k;\n }\n }\n\n /** @inheritdoc */\n *keys(): IterableIterator<K> {\n for (const km of this.#set) {\n yield this.#fromKey(km);\n }\n }\n\n /** @inheritdoc */\n *values(): IterableIterator<K> {\n for (const km of this.#set) {\n // JavaScript Set's values() is an alias for keys()\n yield this.#fromKey(km);\n }\n }\n\n /** @inheritdoc */\n *entries(): IterableIterator<FixedLengthTuple<2, K>> {\n for (const km of this.#set) {\n // JavaScript Set's entries() yields [value, value]\n const a = this.#fromKey(km);\n\n yield [a, a];\n }\n }\n\n /** @inheritdoc */\n toArray(): readonly K[] {\n return Array.from(this.values());\n }\n\n /** @inheritdoc */\n toRawSet(): ReadonlySet<KM> {\n return this.#set;\n }\n}\n"],"names":["ISetMapped"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type ReadonlyRecord, type WidenLiteral } from 'ts-type-forge';
|
|
1
|
+
import { type FixedLengthTuple, type ReadonlyRecord, type WidenLiteral } from 'ts-type-forge';
|
|
2
2
|
import { type MapSetKeyType, type SizeType } from '../types.mjs';
|
|
3
3
|
/**
|
|
4
4
|
* Interface for an immutable set with membership testing and set operation
|
|
@@ -423,7 +423,7 @@ type ISetInterface<K extends MapSetKeyType> = Readonly<{
|
|
|
423
423
|
*
|
|
424
424
|
* @returns An iterable iterator of entries.
|
|
425
425
|
*/
|
|
426
|
-
entries: () => IterableIterator<
|
|
426
|
+
entries: () => IterableIterator<FixedLengthTuple<2, K>>;
|
|
427
427
|
/**
|
|
428
428
|
* Converts the elements of the set to an array.
|
|
429
429
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"iset.d.mts","sourceRoot":"","sources":["../../src/collections/iset.mts"],"names":[],"mappings":"AACA,OAAO,
|
|
1
|
+
{"version":3,"file":"iset.d.mts","sourceRoot":"","sources":["../../src/collections/iset.mts"],"names":[],"mappings":"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"}
|