UNPKG

alistair

Version:
538 lines (532 loc) 14.2 kB
'use strict'; var chunkMPTPBO7T_cjs = require('../chunk-MPTPBO7T.cjs'); // Copyright 2026 Alistair Smith https://github.com/alii/alistair // src/structs/immutable-map.ts var ImmutableMap = class _ImmutableMap { /** * Internal Map instance used for storage * @private */ map = /* @__PURE__ */ new Map(); /** * A shared empty immutable map instance. Using `never` type ensures * it can be safely cast to ImmutableMap<K, V> for any K and V. * * @example * ```typescript * const emptyStringMap = ImmutableMap.Empty as ImmutableMap<string, number>; * const emptyUserMap = ImmutableMap.Empty as ImmutableMap<UserId, User>; * ``` */ static Empty = new _ImmutableMap(); /** * Creates a new ImmutableMap instance, optionally from an iterable * * This is perfect for usage with `useState` as React calls the `.from()` function * when initializing the state, but TypeScript lets us set the generic types * inline. * * @example * ```typescript * const [map, setMap] = useState(ImmutableMap.from<string, number>); * ``` * * @param iterable - Optional iterable of initial [key, value] pairs * @returns A new ImmutableMap instance */ static from = (iterable) => new _ImmutableMap(iterable); /** * Returns the number of key/value pairs in the map * * @example * ```typescript * const map = new ImmutableMap([['a', 1], ['b', 2]]); * console.log(map.size); // 2 * ``` */ get size() { return this.map.size; } /** * Creates a new ImmutableMap instance * * @param iterable - Optional iterable of initial [key, value] pairs * * @example * ```typescript * const map1 = new ImmutableMap([['a', 1], ['b', 2]]); * const map2 = new ImmutableMap(new Map([['x', 10], ['y', 20]])); * const empty = new ImmutableMap<string, number>(); * ``` */ constructor(iterable) { this.map = new Map(iterable); } /** * Creates a new map with the specified key/value pair added or updated * * @param key - The key to set * @param value - The value to associate with the key * @returns A new ImmutableMap containing the new key/value pair * * @example * ```typescript * const map1 = new ImmutableMap([['a', 1]]); * const map2 = map1.set('b', 2); * const map3 = map2.set('a', 10); // Updates existing key * * console.log(map1.get('b')); // undefined * console.log(map2.get('b')); // 2 * console.log(map3.get('a')); // 10 * ``` */ set(key, value) { return this.mutate((map) => { map.set(key, value); }); } /** * Retrieves the value associated with a key * * @param key - The key to look up * @returns The value associated with the key, or undefined if the key doesn't exist * * @example * ```typescript * const map = new ImmutableMap([['a', 1], ['b', 2]]); * console.log(map.get('a')); // 1 * console.log(map.get('x')); // undefined * ``` */ get(key) { return this.map.get(key); } /** * Checks if a key exists in the map * * @param key - The key to check * @returns `true` if the key exists, `false` otherwise * * @example * ```typescript * const map = new ImmutableMap([['a', 1], ['b', 2]]); * console.log(map.has('a')); // true * console.log(map.has('x')); // false * ``` */ has(key) { return this.map.has(key); } /** * Creates a new map with the specified key removed * * @param key - The key to remove * @returns A new ImmutableMap with the key/value pair removed * * @example * ```typescript * const map1 = new ImmutableMap([['a', 1], ['b', 2]]); * const map2 = map1.delete('a'); * * console.log(map1.has('a')); // true * console.log(map2.has('a')); // false * ``` */ delete(key) { return this.mutate((map) => { map.delete(key); }); } /** * Creates a new empty map * * @returns A new empty ImmutableMap * * @example * ```typescript * const map1 = new ImmutableMap([['a', 1], ['b', 2]]); * const map2 = map1.clear(); * * console.log(map1.size); // 2 * console.log(map2.size); // 0 * ``` */ clear() { return _ImmutableMap.Empty; } /** * Executes a callback for each key/value pair in the map * * @param callbackfn - Function to execute for each entry * @param thisArg - Value to use as `this` when executing the callback * * @example * ```typescript * const map = new ImmutableMap([['a', 1], ['b', 2]]); * const results: string[] = []; * map.forEach((value, key) => { * results.push(`${key}=${value}`); * }); * console.log(results); // ['a=1', 'b=2'] * ``` */ forEach(callbackfn, thisArg) { this.map.forEach(callbackfn, thisArg); } /** * Returns an iterator of the map's keys * * @returns An iterator containing the keys * * @example * ```typescript * const map = new ImmutableMap([['a', 1], ['b', 2]]); * const keys = [...map.keys()]; * console.log(keys); // ['a', 'b'] * ``` */ keys() { return this.map.keys(); } /** * Returns an iterator of the map's values * * @returns An iterator containing the values * * @example * ```typescript * const map = new ImmutableMap([['a', 1], ['b', 2]]); * const values = [...map.values()]; * console.log(values); // [1, 2] * ``` */ values() { return this.map.values(); } /** * Returns an iterator of the map's entries * * @returns An iterator containing [key, value] pairs * * @example * ```typescript * const map = new ImmutableMap([['a', 1], ['b', 2]]); * for (const [key, value] of map.entries()) { * console.log(`${key}=${value}`); // Logs: 'a=1', then 'b=2' * } * ``` */ entries() { return this.map.entries(); } /** * Implements the iterable protocol, allowing the map to be used with for...of loops * * @returns An iterator containing [key, value] pairs * * @example * ```typescript * const map = new ImmutableMap([['a', 1], ['b', 2]]); * for (const [key, value] of map) { * console.log(`${key}=${value}`); // Logs: 'a=1', then 'b=2' * } * ``` */ [Symbol.iterator]() { return this.map[Symbol.iterator](); } /** * Customizes the string tag for the ImmutableMap instance * Used in Object.prototype.toString.call(immutableMap) * * @example * ```typescript * const map = new ImmutableMap(); * console.log(Object.prototype.toString.call(map)); // '[object ImmutableMap]' * ``` */ get [Symbol.toStringTag]() { return "ImmutableMap"; } /** * Internal helper method for creating new instances when performing * mutations. This ensures immutability while allowing reuse of logic. * * @param fn - Function that performs the mutation on the cloned map * @returns A new ImmutableMap instance with the mutation applied * @private */ mutate(fn) { const clone = new _ImmutableMap(this.map); fn(clone.map); return clone; } }; // src/structs/immutable-set.ts var ImmutableSet = class _ImmutableSet { /** * Internal Set instance used for storage * @private */ set = /* @__PURE__ */ new Set(); /** * A shared empty immutable set instance. Using `never` type ensures * it can be safely cast to ImmutableSet<T> for any T. * * @example * ```typescript * const emptyStrings = ImmutableSet.Empty as ImmutableSet<string>; * const emptyNumbers = ImmutableSet.Empty as ImmutableSet<number>; * ``` * * You can also use this */ static Empty = new _ImmutableSet(); /** * Creates a new ImmutableSet instance, optionally from an iterable * * This is perfect for usage with `useState` as React calls the `.from()` function * when initializing the state, but TypeScript lets us set the generic type * inline. * * ```typescript * const [set, setState] = useState(ImmutableSet.from<string>); * ``` * * @param iterable - Optional iterable of initial values * @returns A new ImmutableSet instance */ static from = (iterable) => new _ImmutableSet(iterable); /** * Creates a new ImmutableSet instance * * @param iterable - Optional iterable of initial values * * @example * ```typescript * const set1 = new ImmutableSet(['a', 'b', 'c']); * const set2 = new ImmutableSet(new Set([1, 2, 3])); * const empty = new ImmutableSet<string>(); * ``` */ constructor(iterable) { this.set = new Set(iterable); } /** * Internal helper method for creating new instances when performing * mutations. This ensures immutability while allowing reuse of logic. * * @param fn - Function that performs the mutation on the cloned set * @returns A new ImmutableSet instance with the mutation applied * @private */ mutate(fn) { const clone = new _ImmutableSet(this.set); fn(clone.set); return clone; } /** * Creates a new set with the specified value added * * @param value - The value to add * @returns A new ImmutableSet containing the added value * * @example * ```typescript * const set1 = new ImmutableSet(['a', 'b']); * const set2 = set1.add('c'); * console.log([...set2]); // ['a', 'b', 'c'] * console.log(set1 === set2); // false * ``` */ add(value) { return this.mutate((set) => { set.add(value); }); } /** * Creates a new empty set, discarding all current values * * @returns The empty ImmutableSet singleton instance * * @example * ```typescript * const set1 = new ImmutableSet(['a', 'b']); * const set2 = set1.clear(); * console.log(set2.size); // 0 * console.log(set2 === ImmutableSet.Empty); // true * ``` */ clear() { return _ImmutableSet.Empty; } /** * Creates a new set with the specified value removed * * @param value - The value to remove * @returns A new ImmutableSet with the value removed * * @example * ```typescript * const set1 = new ImmutableSet(['a', 'b', 'c']); * const set2 = set1.delete('b'); * console.log([...set2]); // ['a', 'c'] * console.log(set1.has('b')); // true * ``` */ delete(value) { return this.mutate((set) => { set.delete(value); }); } /** * Executes a callback for each value in the set * * @param callbackfn - Function to execute for each value * @param thisArg - Value to use as `this` when executing the callback * * @example * ```typescript * const set = new ImmutableSet(['a', 'b', 'c']); * const results: string[] = []; * set.forEach(value => results.push(value.toUpperCase())); * console.log(results); // ['A', 'B', 'C'] * ``` */ forEach(callbackfn, thisArg) { return this.set.forEach(callbackfn, thisArg); } /** * Toggles a value in the set, adding it if it doesn't exist or removing it if it does * * @param value - The value to toggle * @returns A new ImmutableSet with the value toggled * * @example * ```typescript * const set = new ImmutableSet(['a', 'b']); * const set2 = set.toggle('c'); * console.log([...set2]); // ['a', 'b', 'c'] * ``` * * This is super helpful with React state management because the methods return a new instance * and it means React knows the state has changed. * * ```tsx * const [state, setState] = useState(ImmutableSet.from<string>) * <button onClick={() => setState(old => old.toggle('c'))}>Toggle c</button> * ``` */ toggle(value) { return this.has(value) ? this.delete(value) : this.add(value); } /** * Checks if a value exists in the set * * @param value - The value to check * @returns `true` if the value exists, `false` otherwise * * @example * ```typescript * const set = new ImmutableSet(['a', 'b']); * console.log(set.has('a')); // true * console.log(set.has('c')); // false * ``` */ has(value) { return this.set.has(value); } /** * Returns an iterator of [value, value] pairs * * @returns An iterator containing pairs of values * * @example * ```typescript * const set = new ImmutableSet(['a', 'b']); * for (const [value1, value2] of set.entries()) { * console.log(value1 === value2); // true * } * ``` */ entries() { return this.set.entries(); } /** * Returns an iterator of values (identical to values()) * * @returns An iterator containing the values * * @example * ```typescript * const set = new ImmutableSet(['a', 'b']); * const keys = [...set.keys()]; * console.log(keys); // ['a', 'b'] * ``` */ keys() { return this.set.keys(); } /** * Returns an iterator of values * * @returns An iterator containing the values * * @example * ```typescript * const set = new ImmutableSet(['a', 'b']); * const values = [...set.values()]; * console.log(values); // ['a', 'b'] * ``` */ values() { return this.set.values(); } /** * Implements the iterable protocol, allowing the set to be used with for...of loops * * @returns An iterator containing the values * * @example * ```typescript * const set = new ImmutableSet(['a', 'b']); * for (const value of set) { * console.log(value); // 'a', then 'b' * } * ``` */ [Symbol.iterator]() { return this.set[Symbol.iterator](); } /** * Customizes the string tag for the ImmutableSet instance * Used in Object.prototype.toString.call(immutableSet) * * @example * ```typescript * const set = new ImmutableSet(); * console.log(Object.prototype.toString.call(set)); // '[object ImmutableSet]' * ``` */ get [Symbol.toStringTag]() { return "ImmutableSet"; } /** * Returns the number of values in the set * * @example * ```typescript * const set = new ImmutableSet(['a', 'b']); * console.log(set.size); // 2 * ``` */ get size() { return this.set.size; } }; Object.defineProperty(exports, "StrictMap", { enumerable: true, get: function () { return chunkMPTPBO7T_cjs.StrictMap; } }); exports.ImmutableMap = ImmutableMap; exports.ImmutableSet = ImmutableSet;