ts-data-forge
Version:
[](https://www.npmjs.com/package/ts-data-forge) [](https://www.npmjs.com/package/ts-data-forge) [ lookup performance and set operation support.
*
* This interface defines all methods and properties available on ISet instances. All operations
* that modify the set return new ISet instances, preserving immutability. The underlying implementation
* uses JavaScript's native Set for O(1) average-case performance on add, has, and delete operations.
*
* **Immutability Guarantees:**
* - All mutation operations (add, delete) return new ISet instances
* - Original ISet instances are never modified
* - Safe for concurrent access and functional programming patterns
*
* **Performance Characteristics:**
* - has/add/delete: O(1) average case
* - Set operations (union, intersection, difference): O(n)
* - map/filter operations: O(n)
* - Iteration: O(n)
*
* @template K The type of the elements in the set. Must extend MapSetKeyType (string, number, boolean, etc.)
*/
type ISetInterface<K extends MapSetKeyType> = Readonly<{
/** The number of elements in the set. */
size: SizeType.Arr;
/** Checks if the set is empty. */
isEmpty: boolean;
/**
* Checks if an element exists in the set.
* Allows for wider literal types for keys during checking.
* @param key The element to check.
* @returns `true` if the element exists, `false` otherwise.
*/
has: (key: K | (WidenLiteral<K> & {})) => boolean;
/**
* Checks if all elements in the set satisfy a predicate.
* @param predicate A function to test each element.
* @returns `true` if all elements satisfy the predicate, `false` otherwise.
*/
every: ((predicate: (key: K) => boolean) => boolean) &
/**
* Checks if all elements in the set satisfy a type predicate.
* Narrows the type of elements in the set if the predicate returns true for all elements.
* @template L The narrowed type of the elements.
* @param predicate A type predicate function.
* @returns `true` if all elements satisfy the predicate, `false` otherwise.
*/
(<L extends K>(predicate: (key: K) => key is L) => this is ISet<L>);
/**
* Checks if at least one element in the set satisfies a predicate.
* @param predicate A function to test each element.
* @returns `true` if at least one element satisfies the predicate, `false` otherwise.
*/
some: (predicate: (key: K) => boolean) => boolean;
/**
* Adds an element to the set.
* @param key The element to add.
* @returns A new ISet instance with the element added.
*/
add: (key: K) => ISet<K>;
/**
* Deletes an element from the set.
* @param key The element to delete.
* @returns A new ISet instance without the specified element.
*/
delete: (key: K) => ISet<K>;
/**
* Applies a series of mutations to the set.
* @param actions An array of mutation actions (add or delete).
* @returns A new ISet instance with all mutations applied.
*/
withMutations: (actions: readonly Readonly<{
type: 'add';
key: K;
} | {
type: 'delete';
key: K;
}>[]) => ISet<K>;
/**
* Maps the elements of the set to new elements.
* @template K2 The type of the new elements.
* @param mapFn A function that maps an element to a new element.
* @returns A new ISet instance with mapped elements.
*/
map: <K2 extends MapSetKeyType>(mapFn: (key: K) => K2) => ISet<K2>;
/**
* Filters the elements of the set based on a type predicate.
* Narrows the type of elements in the resulting set.
* @template K2 The narrowed type of the elements.
* @param predicate A type predicate function.
* @returns A new ISet instance with elements that satisfy the type predicate.
*/
filter: (<K2 extends K>(predicate: (key: K) => key is K2) => ISet<K2>) &
/**
* Filters the elements of the set based on a predicate.
* @param predicate A function to test each element.
* @returns A new ISet instance with elements that satisfy the predicate.
*/
((predicate: (key: K) => boolean) => ISet<K>);
/**
* Filters the elements of the set by excluding elements for which the predicate returns true.
* @param predicate A function to test each element.
* @returns A new ISet instance with elements for which the predicate returned `false`.
*/
filterNot: (predicate: (key: K) => boolean) => ISet<K>;
/**
* Checks if this set is a subset of another set.
* @param set The other set.
* @returns `true` if this set is a subset of the other set, `false` otherwise.
*/
isSubsetOf: (set: ISet<WidenLiteral<K>>) => boolean;
/**
* Checks if this set is a superset of another set.
* @param set The other set.
* @returns `true` if this set is a superset of the other set, `false` otherwise.
*/
isSupersetOf: (set: ISet<WidenLiteral<K>>) => boolean;
/**
* Returns a new set with elements that are in this set but not in another set.
* @param set The other set.
* @returns A new ISet instance representing the set difference.
*/
subtract: (set: ISet<K>) => ISet<K>;
/**
* Returns a new set with elements that are common to both this set and another set.
* @param set The other set.
* @returns A new ISet instance representing the set intersection.
*/
intersect: (set: ISet<K>) => ISet<K>;
/**
* Returns a new set with all elements from both this set and another set.
* @template K2 The type of elements in the other set.
* @param set The other set.
* @returns A new ISet instance representing the set union.
*/
union: <K2 extends MapSetKeyType>(set: ISet<K2>) => ISet<K | K2>;
/**
* Executes a callback function for each element in the set.
* @param callbackfn A function to execute for each element.
*/
forEach: (callbackfn: (key: K) => void) => void;
/**
* Returns an iterator for the elements in the set (alias for values).
* @returns An iterable iterator of elements.
*/
keys: () => IterableIterator<K>;
/**
* Returns an iterator for the elements in the set.
* @returns An iterable iterator of elements.
*/
values: () => IterableIterator<K>;
/**
* Returns an iterator for the entries (element-element pairs) in the set.
* @returns An iterable iterator of entries.
*/
entries: () => IterableIterator<readonly [K, K]>;
/**
* Converts the elements of the set to an array.
* @returns A readonly array of elements.
*/
toArray: () => readonly K[];
/**
* Returns the underlying readonly JavaScript Set.
* @returns The raw ReadonlySet instance.
*/
toRawSet: () => ReadonlySet<K>;
}>;
/**
* Represents an immutable set with high-performance operations and comprehensive set algebra support.
*
* ISet is a persistent data structure that provides all the functionality of JavaScript's Set
* while maintaining immutability. All operations that would normally mutate the set instead
* return new ISet instances, making it safe for functional programming and concurrent access.
*
* **Key Features:**
* - **Immutable**: All mutation operations return new instances
* - **High Performance**: O(1) average-case for has/add/delete operations
* - **Set Operations**: Full support for union, intersection, difference, subset/superset checks
* - **Type Safe**: Full TypeScript support with generic element types
* - **Iterable**: Implements standard JavaScript iteration protocols
* - **Functional**: Rich API for map, filter, and functional composition
*
* **When to Use:**
* - Managing collections of unique values with immutability guarantees
* - Set algebra operations (unions, intersections, differences)
* - Membership testing with O(1) performance
* - Functional programming patterns requiring immutable collections
*
* @template K The type of the elements in the set. Must extend MapSetKeyType.
*/
export type ISet<K extends MapSetKeyType> = Iterable<K> & ISetInterface<K>;
/**
* Provides utility functions for ISet.
*/
export declare namespace ISet {
/**
* Creates a new ISet instance from an iterable of elements.
*
* This factory function accepts any iterable of elements, including arrays,
* JavaScript Sets, other ISets, or custom iterables. Duplicate elements in the
* input iterable will be automatically deduplicated in the resulting set.
*
* **Performance:** O(n) where n is the number of elements in the iterable.
*
* @template K The type of the elements. Must extend MapSetKeyType.
* @param iterable An iterable of elements (e.g., Array, Set, ISet, etc.)
* @returns A new ISet instance containing all unique elements from the iterable.
*
* @example
* ```typescript
* // From array (duplicates automatically removed)
* const uniqueIds = ISet.create([1, 2, 3, 2, 1]); // Contains: 1, 2, 3
* console.log(uniqueIds.size); // Output: 3
*
* // From JavaScript Set
* const jsSet = new Set(["red", "green", "blue"]);
* const colors = ISet.create(jsSet);
* console.log(colors.has("red")); // Output: true
*
* // From another ISet (creates a copy)
* const originalTags = ISet.create(["typescript", "immutable"]);
* const copiedTags = ISet.create(originalTags);
* console.log(copiedTags.size); // Output: 2
*
* // Empty set
* const emptyPermissions = ISet.create<string>([]);
* console.log(emptyPermissions.isEmpty); // Output: true
*
* // Fluent operations
* const processedNumbers = ISet.create([1, 2, 3, 4, 5])
* .filter(x => x % 2 === 0) // Keep even numbers: 2, 4
* .add(6) // Add 6: 2, 4, 6
* .delete(2); // Remove 2: 4, 6
* console.log(processedNumbers.toArray().toSorted()); // Output: [4, 6]
*
* // From generator function
* function* generatePrimes(): Generator<number> {
* yield 2; yield 3; yield 5; yield 7;
* }
* const primes = ISet.create(generatePrimes());
* console.log(primes.size); // Output: 4
* ```
*/
const create: <K extends MapSetKeyType>(iterable: Iterable<K>) => ISet<K>;
/**
* Checks if two ISet instances are structurally equal.
*
* Two ISets are considered equal if they have the same size and contain exactly the same
* elements. The order of elements does not matter for equality comparison since sets are
* unordered collections. Elements are compared using JavaScript's `===` operator.
*
* **Performance:** O(n) where n is the size of the smaller set.
*
* @template K The type of the elements.
* @param a The first ISet instance to compare.
* @param b The second ISet instance to compare.
* @returns `true` if the sets contain exactly the same elements, `false` otherwise.
*
* @example
* ```typescript
* // Basic equality comparison
* const permissions1 = ISet.create(["read", "write", "execute"]);
* const permissions2 = ISet.create(["execute", "read", "write"]); // Order doesn't matter
* const permissions3 = ISet.create(["read", "write"]);
*
* console.log(ISet.equal(permissions1, permissions2)); // true
* console.log(ISet.equal(permissions1, permissions3)); // false (different sizes)
*
* // With different element types
* const numbers1 = ISet.create([1, 2, 3]);
* const numbers2 = ISet.create([3, 1, 2]);
* const numbers3 = ISet.create([1, 2, 4]); // Different element
*
* console.log(ISet.equal(numbers1, numbers2)); // true
* console.log(ISet.equal(numbers1, numbers3)); // false
*
* // Empty sets
* const empty1 = ISet.create<string>([]);
* const empty2 = ISet.create<string>([]);
* console.log(ISet.equal(empty1, empty2)); // true
*
* // Single element sets
* const single1 = ISet.create(["unique"]);
* const single2 = ISet.create(["unique"]);
* const single3 = ISet.create(["different"]);
*
* console.log(ISet.equal(single1, single2)); // true
* console.log(ISet.equal(single1, single3)); // false
* ```
*/
const equal: <K extends MapSetKeyType>(a: ISet<K>, b: ISet<K>) => boolean;
/**
* Computes the difference between two ISet instances, identifying added and deleted elements.
*
* This function performs a set difference operation to determine what elements were added
* and what elements were deleted when transitioning from the old set to the new set.
* This is useful for change detection, state management, and synchronization scenarios.
*
* **Performance:** O(n + m) where n and m are the sizes of the old and new sets respectively.
*
* @template K The type of the elements.
* @param oldSet The original set representing the previous state.
* @param newSet The new set representing the current state.
* @returns An object with `added` and `deleted` properties, each containing an ISet
* of elements that were added or removed respectively.
*
* @example
* ```typescript
* // User permission changes
* const oldPermissions = ISet.create(["read", "write", "delete"]);
* const newPermissions = ISet.create(["read", "write", "execute", "admin"]);
*
* const permissionDiff = ISet.diff(oldPermissions, newPermissions);
*
* console.log("Permissions removed:", permissionDiff.deleted.toArray());
* // Output: ["delete"]
*
* console.log("Permissions added:", permissionDiff.added.toArray());
* // Output: ["execute", "admin"]
*
* // No changes
* const unchanged1 = ISet.create(["a", "b", "c"]);
* const unchanged2 = ISet.create(["a", "b", "c"]);
* const noDiff = ISet.diff(unchanged1, unchanged2);
*
* console.log(noDiff.added.isEmpty); // true
* console.log(noDiff.deleted.isEmpty); // true
*
* // Complete replacement
* const oldTags = ISet.create(["javascript", "react"]);
* const newTags = ISet.create(["typescript", "vue"]);
* const tagDiff = ISet.diff(oldTags, newTags);
*
* console.log(tagDiff.deleted.toArray()); // ["javascript", "react"]
* console.log(tagDiff.added.toArray()); // ["typescript", "vue"]
* ```
*/
const diff: <K extends MapSetKeyType>(oldSet: ISet<K>, newSet: ISet<K>) => ReadonlyRecord<"added" | "deleted", ISet<K>>;
/**
* Computes the intersection of two ISet instances.
*
* Returns a new set containing only the elements that are present in both input sets.
* This operation is commutative: `intersection(a, b) === intersection(b, a)`.
*
* **Performance:** O(min(n, m)) where n and m are the sizes of the input sets.
*
* @template K The type of the elements.
* @param a The first set.
* @param b The second set.
* @returns A new ISet instance containing elements common to both sets.
*
* @example
* ```typescript
* // Finding common permissions between user and role
* const userPermissions = ISet.create(["read", "write", "delete", "admin"]);
* const rolePermissions = ISet.create(["read", "write", "execute"]);
*
* const commonPermissions = ISet.intersection(userPermissions, rolePermissions);
* console.log(commonPermissions.toArray()); // ["read", "write"]
*
* // No common elements
* const setA = ISet.create([1, 2, 3]);
* const setB = ISet.create([4, 5, 6]);
* const noCommon = ISet.intersection(setA, setB);
* console.log(noCommon.isEmpty); // true
*
* // Complete overlap
* const identical1 = ISet.create(["a", "b", "c"]);
* const identical2 = ISet.create(["a", "b", "c"]);
* const completeOverlap = ISet.intersection(identical1, identical2);
* console.log(ISet.equal(completeOverlap, identical1)); // true
*
* // Intersection with empty set
* const nonEmpty = ISet.create([1, 2, 3]);
* const empty = ISet.create<number>([]);
* const withEmpty = ISet.intersection(nonEmpty, empty);
* console.log(withEmpty.isEmpty); // true
* ```
*/
const intersection: <K extends MapSetKeyType>(a: ISet<K>, b: ISet<K>) => ISet<K>;
/**
* Computes the union of two ISet instances.
*
* Returns a new set containing all elements that are present in either input set.
* Duplicate elements are automatically handled since sets only contain unique values.
* This operation is commutative: `union(a, b) === union(b, a)`.
*
* **Performance:** O(n + m) where n and m are the sizes of the input sets.
*
* @template K1 The type of elements in the first set.
* @template K2 The type of elements in the second set.
* @param a The first set.
* @param b The second set.
* @returns A new ISet instance containing all elements from both sets.
*
* @example
* ```typescript
* // Combining permissions from multiple sources
* const userPermissions = ISet.create(["read", "write"]);
* const rolePermissions = ISet.create(["write", "execute", "admin"]);
*
* const allPermissions = ISet.union(userPermissions, rolePermissions);
* console.log(allPermissions.toArray().toSorted());
* // Output: ["admin", "execute", "read", "write"]
*
* // Union with different types (type widening)
* const numbers = ISet.create([1, 2, 3]);
* const strings = ISet.create(["a", "b"]);
* const mixed = ISet.union(numbers, strings); // ISet<number | string>
* console.log(mixed.size); // 5
*
* // Union with empty set
* const nonEmpty = ISet.create(["item1", "item2"]);
* const empty = ISet.create<string>([]);
* const withEmpty = ISet.union(nonEmpty, empty);
* console.log(ISet.equal(withEmpty, nonEmpty)); // true
*
* // Overlapping sets
* const featuresA = ISet.create(["feature1", "feature2", "feature3"]);
* const featuresB = ISet.create(["feature2", "feature3", "feature4"]);
* const allFeatures = ISet.union(featuresA, featuresB);
* console.log(allFeatures.size); // 4 (duplicates removed)
* ```
*/
const union: <K1 extends MapSetKeyType, K2 extends MapSetKeyType>(a: ISet<K1>, b: ISet<K2>) => ISet<K1 | K2>;
}
export {};
//# sourceMappingURL=iset.d.mts.map