ts-data-forge 13.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.
Files changed (93) hide show
  1. package/README.md +4 -3
  2. package/dist/array/impl/array-utils-creation.d.mts +2 -2
  3. package/dist/array/impl/array-utils-creation.d.mts.map +1 -1
  4. package/dist/array/impl/array-utils-creation.mjs.map +1 -1
  5. package/dist/array/impl/array-utils-length-bounded-array-cast.d.mts +56 -29
  6. package/dist/array/impl/array-utils-length-bounded-array-cast.d.mts.map +1 -1
  7. package/dist/array/impl/array-utils-length-bounded-array-cast.mjs +23 -15
  8. package/dist/array/impl/array-utils-length-bounded-array-cast.mjs.map +1 -1
  9. package/dist/array/impl/array-utils-length-bounded-array-guard.d.mts +126 -28
  10. package/dist/array/impl/array-utils-length-bounded-array-guard.d.mts.map +1 -1
  11. package/dist/array/impl/array-utils-length-bounded-array-guard.mjs +39 -5
  12. package/dist/array/impl/array-utils-length-bounded-array-guard.mjs.map +1 -1
  13. package/dist/array/impl/array-utils-length-bounded-tuple-cast.d.mts +167 -0
  14. package/dist/array/impl/array-utils-length-bounded-tuple-cast.d.mts.map +1 -0
  15. package/dist/array/impl/array-utils-length-bounded-tuple-cast.mjs +87 -0
  16. package/dist/array/impl/array-utils-length-bounded-tuple-cast.mjs.map +1 -0
  17. package/dist/array/impl/array-utils-length-bounded-tuple-guard.d.mts +135 -0
  18. package/dist/array/impl/array-utils-length-bounded-tuple-guard.d.mts.map +1 -0
  19. package/dist/array/impl/array-utils-length-bounded-tuple-guard.mjs +41 -0
  20. package/dist/array/impl/array-utils-length-bounded-tuple-guard.mjs.map +1 -0
  21. package/dist/array/impl/array-utils-modification.d.mts +45 -18
  22. package/dist/array/impl/array-utils-modification.d.mts.map +1 -1
  23. package/dist/array/impl/array-utils-modification.mjs.map +1 -1
  24. package/dist/array/impl/array-utils-reducing-value.d.mts +3 -3
  25. package/dist/array/impl/array-utils-reducing-value.d.mts.map +1 -1
  26. package/dist/array/impl/array-utils-reducing-value.mjs +1 -1
  27. package/dist/array/impl/array-utils-reducing-value.mjs.map +1 -1
  28. package/dist/array/impl/array-utils-slice-clamped.d.mts.map +1 -1
  29. package/dist/array/impl/array-utils-slice-clamped.mjs.map +1 -1
  30. package/dist/array/impl/array-utils-slicing.d.mts +11 -11
  31. package/dist/array/impl/array-utils-slicing.d.mts.map +1 -1
  32. package/dist/array/impl/array-utils-slicing.mjs +1 -1
  33. package/dist/array/impl/array-utils-slicing.mjs.map +1 -1
  34. package/dist/array/impl/array-utils-transformation.d.mts +36 -19
  35. package/dist/array/impl/array-utils-transformation.d.mts.map +1 -1
  36. package/dist/array/impl/array-utils-transformation.mjs +2 -2
  37. package/dist/array/impl/array-utils-transformation.mjs.map +1 -1
  38. package/dist/array/impl/array-utils-validation.d.mts +2 -124
  39. package/dist/array/impl/array-utils-validation.d.mts.map +1 -1
  40. package/dist/array/impl/array-utils-validation.mjs +1 -7
  41. package/dist/array/impl/array-utils-validation.mjs.map +1 -1
  42. package/dist/array/impl/index.d.mts +2 -0
  43. package/dist/array/impl/index.d.mts.map +1 -1
  44. package/dist/array/impl/index.mjs +5 -3
  45. package/dist/array/impl/index.mjs.map +1 -1
  46. package/dist/collections/imap.d.mts +1 -1
  47. package/dist/collections/imap.mjs.map +1 -1
  48. package/dist/collections/iset-mapped.d.mts +2 -2
  49. package/dist/collections/iset-mapped.d.mts.map +1 -1
  50. package/dist/collections/iset-mapped.mjs.map +1 -1
  51. package/dist/collections/iset.d.mts +2 -2
  52. package/dist/collections/iset.d.mts.map +1 -1
  53. package/dist/collections/iset.mjs.map +1 -1
  54. package/dist/number/num-arithmetic-types.d.mts +2 -2
  55. package/dist/number/num-arithmetic-types.d.mts.map +1 -1
  56. package/dist/object/object.mjs +1 -1
  57. package/dist/string/str.d.mts +44 -44
  58. package/dist/string/str.d.mts.map +1 -1
  59. package/dist/string/str.mjs +17 -17
  60. package/dist/string/str.mjs.map +1 -1
  61. package/package.json +4 -5
  62. package/src/array/impl/array-utils-creation.mts +7 -3
  63. package/src/array/impl/array-utils-creation.test.mts +10 -8
  64. package/src/array/impl/array-utils-length-bounded-array-cast.mts +88 -50
  65. package/src/array/impl/array-utils-length-bounded-array-cast.test.mts +40 -13
  66. package/src/array/impl/array-utils-length-bounded-array-guard.mts +248 -39
  67. package/src/array/impl/array-utils-length-bounded-array-guard.test.mts +135 -24
  68. package/src/array/impl/array-utils-length-bounded-tuple-cast.mts +364 -0
  69. package/src/array/impl/array-utils-length-bounded-tuple-cast.test.mts +207 -0
  70. package/src/array/impl/array-utils-length-bounded-tuple-guard.mts +266 -0
  71. package/src/array/impl/array-utils-length-bounded-tuple-guard.test.mts +441 -0
  72. package/src/array/impl/array-utils-length-constraint-preservation.test.mts +287 -0
  73. package/src/array/impl/array-utils-modification.mts +84 -61
  74. package/src/array/impl/array-utils-modification.test.mts +145 -6
  75. package/src/array/impl/array-utils-reducing-value.mts +5 -5
  76. package/src/array/impl/array-utils-shape-invariants.test.mts +284 -0
  77. package/src/array/impl/array-utils-slice-clamped.mts +2 -1
  78. package/src/array/impl/array-utils-slicing.mts +65 -43
  79. package/src/array/impl/array-utils-slicing.test.mts +55 -0
  80. package/src/array/impl/array-utils-transformation.mts +91 -37
  81. package/src/array/impl/array-utils-transformation.test.mts +96 -23
  82. package/src/array/impl/array-utils-validation.mts +2 -162
  83. package/src/array/impl/array-utils-validation.test.mts +0 -371
  84. package/src/array/impl/index.mts +2 -0
  85. package/src/collections/imap.mts +1 -1
  86. package/src/collections/iset-mapped.mts +7 -3
  87. package/src/collections/iset.mts +7 -3
  88. package/src/collections/iset.test.mts +9 -6
  89. package/src/collections/queue.test.mts +1 -1
  90. package/src/number/num-arithmetic-types.mts +8 -4
  91. package/src/number/num.test.mts +2 -2
  92. package/src/string/str.mts +69 -69
  93. package/src/string/str.test.mts +40 -40
@@ -1 +1 @@
1
- {"version":3,"file":"array-utils-transformation.mjs","sources":["../../../src/array/impl/array-utils-transformation.mts"],"sourcesContent":["import {\n type FixedLengthTuple,\n type IsFixedLengthList,\n type List,\n type NonEmptyArray,\n type NonEmptyTuple,\n type PositiveInt,\n type PositiveUint32,\n type Primitive,\n type SafeUintWithSmallInt,\n type WithSmallInt,\n} from 'ts-type-forge';\nimport { IMap } from '../../collections/index.mjs';\nimport { expectType } from '../../expect-type.mjs';\nimport { asPositiveUint32, asUint32, Uint32 } from '../../number/index.mjs';\nimport { castMutable, tp } from '../../others/index.mjs';\nimport {\n type ArrayIndex,\n type MapSetKeyType,\n type SizeType,\n} from '../../types.mjs';\nimport { newArray, seq } from './array-utils-creation.mjs';\nimport { size } from './array-utils-size.mjs';\nimport { isNonEmpty } from './array-utils-validation.mjs';\n\n/**\n * Creates a new array by transforming each element with a mapping function.\n *\n * @example\n *\n * ```ts\n * const numbers = [1, 2, 3] as const;\n *\n * const doubled = Arr.map(numbers, (value) => value * 2);\n *\n * const indexed = Arr.map<number, string>(\n * (value, index) => `${index}:${value}`,\n * )(numbers);\n *\n * assert.deepStrictEqual(doubled, [2, 4, 6]);\n *\n * assert.deepStrictEqual(indexed, ['0:1', '1:2', '2:3']);\n * ```\n */\nexport function map<const Ar extends readonly unknown[], B>(\n array: Ar,\n mapFn: (a: Ar[number], index: ArrayIndex<Ar>) => B,\n): Readonly<{ [K in keyof Ar]: B }>;\n\n// curried version\nexport function map<A, B>(\n mapFn: (a: A, index: SizeType.Arr) => B,\n): <const Ar extends readonly A[]>(\n array: Ar,\n) => Readonly<{ [K in keyof Ar]: B }>;\n\nexport function map<A, B>(\n ...args:\n | readonly [array: readonly A[], mapFn: (a: A, index: SizeType.Arr) => B]\n | readonly [mapFn: (a: A, index: SizeType.Arr) => B]\n): readonly B[] | ((array: readonly A[]) => readonly B[]) {\n switch (args.length) {\n case 2: {\n const [array, mapFn] = args;\n\n // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n return array.map(mapFn as never);\n }\n\n case 1: {\n const [mapFn] = args;\n\n return (array: readonly A[]) => map(array, mapFn);\n }\n }\n}\n\n/**\n * Returns an array of successively reduced values from an array.\n *\n * @example\n *\n * ```ts\n * const changes = [5, -2, 3] as const;\n *\n * const runningTotals = Arr.scan(\n * changes,\n * (total, change) => total + change,\n * 0,\n * );\n *\n * const runningTotalsFromCurried = Arr.scan(\n * (total: number, change: number) => total + change,\n * 10,\n * )([-5, 15]);\n *\n * const expectedTotals = [0, 5, 3, 6] as const;\n *\n * const expectedCurriedTotals = [10, 5, 20] as const;\n *\n * assert.deepStrictEqual<readonly number[]>(runningTotals, expectedTotals);\n *\n * assert.deepStrictEqual<readonly number[]>(\n * runningTotalsFromCurried,\n * expectedCurriedTotals,\n * );\n * ```\n */\nexport function scan<const Ar extends readonly unknown[], S>(\n array: Ar,\n reducer: (\n accumulator: S,\n currentValue: Ar[number],\n currentIndex: ArrayIndex<Ar>,\n ) => S,\n init: S,\n): NonEmptyArray<S>;\n\nexport function scan<E, S>(\n reducer: (accumulator: S, currentValue: E, currentIndex: SizeType.Arr) => S,\n init: S,\n): (array: readonly E[]) => NonEmptyArray<S>;\n\nexport function scan<E, S>(\n ...args:\n | readonly [\n array: readonly E[],\n reducer: (\n accumulator: S,\n currentValue: E,\n currentIndex: SizeType.Arr,\n ) => S,\n init: S,\n ]\n | readonly [\n reducer: (\n accumulator: S,\n currentValue: E,\n currentIndex: SizeType.Arr,\n ) => S,\n init: S,\n ]\n): NonEmptyTuple<S> | ((array: readonly E[]) => NonEmptyTuple<S>) {\n switch (args.length) {\n case 3:\n return scanImpl(...args);\n\n case 2:\n return (array) => scanImpl(array, ...args);\n }\n}\n\nconst scanImpl = <E, S>(\n array: readonly E[],\n reducer: (accumulator: S, currentValue: E, currentIndex: SizeType.Arr) => S,\n init: S,\n): NonEmptyTuple<S> => {\n const mut_result = castMutable<NonEmptyTuple<S>>(\n newArray<PositiveUint32, S>(asPositiveUint32(array.length + 1), init),\n );\n\n let mut_acc = init;\n\n for (const [index, value] of array.entries()) {\n mut_acc = reducer(mut_acc, value, asUint32(index));\n\n mut_result[index + 1] = mut_acc;\n }\n\n return mut_result;\n};\n\n/**\n * Reverses an array.\n *\n * @example\n *\n * ```ts\n * const tuple = [1, 'two', true] as const;\n *\n * const reversed = Arr.toReversed(tuple);\n *\n * const expected = [true, 'two', 1] as const;\n *\n * assert.deepStrictEqual(reversed, expected);\n * ```\n */\nexport const toReversed = <const Ar extends readonly unknown[]>(\n array: Ar,\n): List.Reverse<Ar> =>\n // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n array.toReversed() as never;\n\n/**\n * Sorts an array.\n *\n * @example\n *\n * ```ts\n * const numbers = [3, 1, 2] as const;\n *\n * const words = ['banana', 'apple', 'cherry'] as const;\n *\n * const ascendingNumbers = Arr.toSorted(numbers);\n *\n * const alphabetical = Arr.toSorted(words, (left, right) =>\n * left.localeCompare(right),\n * );\n *\n * const expectedNumbers = [1, 2, 3] as const;\n *\n * const expectedWords = ['apple', 'banana', 'cherry'] as const;\n *\n * assert.deepStrictEqual(ascendingNumbers, expectedNumbers);\n *\n * assert.deepStrictEqual(alphabetical, expectedWords);\n * ```\n */\nexport const toSorted = <const Ar extends readonly unknown[]>(\n ...[array, comparator]: Ar extends readonly number[]\n ? readonly [\n array: Ar,\n // If the array elements are mapped to numbers, comparator is optional.\n comparator?: (x: Ar[number], y: Ar[number]) => number,\n ]\n : readonly [array: Ar, comparator: (x: Ar[number], y: Ar[number]) => number]\n): IsFixedLengthList<Ar> extends true\n ? FixedLengthTuple<Ar['length'], Ar[number]>\n : Ar extends NonEmptyTuple<unknown>\n ? NonEmptyArray<Ar[number]>\n : readonly Ar[number][] =>\n // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n array.toSorted(\n // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n (comparator as ((x: unknown, y: unknown) => number) | undefined) ??\n // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n ((x, y) => (x as number) - (y as number)),\n ) as never;\n\n/**\n * Sorts an array by a mapped value.\n *\n * @example\n *\n * ```ts\n * const projects = [\n * { name: 'compiler', issues: 7 },\n * { name: 'docs', issues: 2 },\n * { name: 'ui', issues: 5 },\n * ] as const;\n *\n * const byIssueCount = Arr.toSortedBy(projects, (project) => project.issues);\n *\n * const byIssueCountDescending = Arr.toSortedBy(\n * projects,\n * (project) => project.issues,\n * (left, right) => right - left,\n * );\n *\n * const expectedByIssues = [\n * { name: 'docs', issues: 2 },\n * { name: 'ui', issues: 5 },\n * { name: 'compiler', issues: 7 },\n * ] as const;\n *\n * const expectedByIssueCountDescending = [\n * { name: 'compiler', issues: 7 },\n * { name: 'ui', issues: 5 },\n * { name: 'docs', issues: 2 },\n * ] as const;\n *\n * assert.deepStrictEqual(byIssueCount, expectedByIssues);\n *\n * assert.deepStrictEqual(\n * byIssueCountDescending,\n * expectedByIssueCountDescending,\n * );\n * ```\n */\nexport function toSortedBy<const Ar extends readonly unknown[]>(\n array: Ar,\n comparatorValueMapper: (value: Ar[number]) => number,\n // If the array elements are mapped to numbers, comparator is optional.\n comparator?: (x: number, y: number) => number,\n): IsFixedLengthList<Ar> extends true\n ? FixedLengthTuple<Ar['length'], Ar[number]>\n : Ar extends NonEmptyTuple<unknown>\n ? NonEmptyArray<Ar[number]>\n : readonly Ar[number][];\n\nexport function toSortedBy<const Ar extends readonly unknown[], const V>(\n array: Ar,\n comparatorValueMapper: (value: Ar[number]) => V,\n comparator: (x: V, y: V) => number,\n): IsFixedLengthList<Ar> extends true\n ? FixedLengthTuple<Ar['length'], Ar[number]>\n : Ar extends NonEmptyTuple<unknown>\n ? NonEmptyArray<Ar[number]>\n : readonly Ar[number][];\n\nexport function toSortedBy<E, const V>(\n array: readonly E[],\n comparatorValueMapper: (value: E) => V,\n comparator?: (x: V, y: V) => number,\n): readonly E[] {\n return array.toSorted((x, y) =>\n comparator === undefined\n ? // This branch assumes V is number if comparator is undefined.\n // The overloads should handle this, but explicit cast might be needed if V is not number.\n // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n (comparatorValueMapper(x) as number) -\n // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n (comparatorValueMapper(y) as number)\n : comparator(comparatorValueMapper(x), comparatorValueMapper(y)),\n );\n}\n\n/**\n * Filters an array based on a predicate function.\n *\n * @example\n *\n * ```ts\n * const numbers = [1, 2, 3, 4] as const;\n *\n * const evens = Arr.filter(numbers, (value) => value % 2 === 0);\n *\n * const greaterThanTwo = Arr.filter<number>((value) => value > 2)(numbers);\n *\n * assert.deepStrictEqual(evens, [2, 4]);\n *\n * assert.deepStrictEqual(greaterThanTwo, [3, 4]);\n * ```\n */\n// Type guard overloads\nexport function filter<\n const Ar extends readonly unknown[],\n S extends Ar[number],\n>(\n array: Ar,\n predicate: (a: Ar[number], index: ArrayIndex<Ar>) => a is S,\n): readonly S[];\n\nexport function filter<E, S extends E>(\n predicate: (a: E, index: SizeType.Arr) => a is S,\n): (array: readonly E[]) => readonly S[];\n\n// Regular boolean predicate overloads\nexport function filter<const Ar extends readonly unknown[]>(\n array: Ar,\n predicate: (a: Ar[number], index: ArrayIndex<Ar>) => boolean,\n): readonly Ar[number][];\n\nexport function filter<E>(\n predicate: (a: E, index: SizeType.Arr) => boolean,\n): (array: readonly E[]) => readonly E[];\n\nexport function filter<E>(\n ...args:\n | readonly [\n array: readonly E[],\n predicate: (a: E, index: SizeType.Arr) => boolean,\n ]\n | readonly [predicate: (a: E, index: SizeType.Arr) => boolean]\n): readonly E[] | ((array: readonly E[]) => readonly E[]) {\n switch (args.length) {\n case 2:\n return filterImpl(...args);\n\n case 1:\n return (array) => filterImpl(array, ...args);\n }\n}\n\nconst filterImpl = <E,>(\n array: readonly E[],\n predicate: (a: E, index: SizeType.Arr) => boolean,\n): readonly E[] => array.filter((a, i) => predicate(a, asUint32(i)));\n\n/**\n * Filters an array by excluding elements for which the predicate returns true.\n *\n * @example\n *\n * ```ts\n * const names = ['Ada', 'Grace', 'Linus'] as const;\n *\n * const notAda = Arr.filterNot(names, (name) => name === 'Ada');\n *\n * const notShort = Arr.filterNot<string>((name) => name.length <= 4)(names);\n *\n * assert.deepStrictEqual(notAda, ['Grace', 'Linus']);\n *\n * assert.deepStrictEqual(notShort, ['Grace', 'Linus']);\n * ```\n */\nexport function filterNot<const Ar extends readonly unknown[]>(\n array: Ar,\n predicate: (a: Ar[number], index: ArrayIndex<Ar>) => boolean,\n): readonly Ar[number][];\n\nexport function filterNot<E>(\n predicate: (a: E, index: SizeType.Arr) => boolean,\n): (array: readonly E[]) => readonly E[];\n\nexport function filterNot<E>(\n ...args:\n | readonly [\n array: readonly E[],\n predicate: (a: E, index: SizeType.Arr) => boolean,\n ]\n | readonly [predicate: (a: E, index: SizeType.Arr) => boolean]\n): readonly E[] | ((array: readonly E[]) => readonly E[]) {\n switch (args.length) {\n case 2:\n return filterNotImpl(...args);\n\n case 1:\n return (array) => filterNotImpl(array, ...args);\n }\n}\n\nconst filterNotImpl = <E,>(\n array: readonly E[],\n predicate: (a: E, index: SizeType.Arr) => boolean,\n): readonly E[] => array.filter((a, i) => !predicate(a, asUint32(i)));\n\n/**\n * Creates a new array with unique elements.\n *\n * @example\n *\n * ```ts\n * const letters = ['a', 'b', 'a', 'c', 'b'] as const;\n *\n * const uniqueLetters = Arr.uniq(letters);\n *\n * const expected = ['a', 'b', 'c'] as const;\n *\n * assert.deepStrictEqual<readonly string[]>(uniqueLetters, expected);\n * ```\n */\nexport const uniq = <const Ar extends readonly Primitive[]>(\n array: Ar,\n): Ar extends NonEmptyTuple<unknown>\n ? NonEmptyArray<Ar[number]>\n : readonly Ar[number][] =>\n // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n Array.from(new Set(array)) as never;\n\n/**\n * Creates a new array with unique elements based on a mapped value.\n *\n * @example\n *\n * ```ts\n * const people = [\n * { id: 1, name: 'Ada' },\n * { id: 2, name: 'Brian' },\n * { id: 1, name: 'Alan' },\n * { id: 3, name: 'Grace' },\n * ] as const;\n *\n * const uniqueById = Arr.uniqBy(people, (person) => person.id);\n *\n * const expected = [\n * { id: 1, name: 'Ada' },\n * { id: 2, name: 'Brian' },\n * { id: 3, name: 'Grace' },\n * ] as const;\n *\n * assert.deepStrictEqual<readonly Readonly<{ id: number; name: string }>[]>(\n * uniqueById,\n * expected,\n * );\n * ```\n */\nexport const uniqBy = <\n const Ar extends readonly unknown[],\n P extends Primitive,\n>(\n array: Ar,\n mapFn: (value: Ar[number]) => P,\n): Ar extends NonEmptyTuple<unknown>\n ? NonEmptyArray<Ar[number]>\n : readonly Ar[number][] => {\n const mut_mappedValues = new Set<P>();\n\n // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n return array.filter((val) => {\n const mappedValue = mapFn(val);\n\n if (mut_mappedValues.has(mappedValue)) return false;\n\n mut_mappedValues.add(mappedValue);\n\n return true;\n }) satisfies readonly Ar[number][] as never;\n};\n\n/**\n * Flattens nested arrays up to the specified depth.\n *\n * @example\n *\n * ```ts\n * const nested = [\n * [1, 2],\n * [3, 4],\n * ] as const;\n *\n * const flatOnce = Arr.flat(nested, 1);\n *\n * const flatCurried = Arr.flat()(nested);\n *\n * assert.deepStrictEqual(flatOnce, [1, 2, 3, 4]);\n *\n * assert.deepStrictEqual(flatCurried, [1, 2, 3, 4]);\n * ```\n */\nexport function flat<\n const Ar extends readonly unknown[],\n D extends SafeUintWithSmallInt = 1,\n>(array: Ar, depth?: D): readonly FlatArray<Ar, D>[];\n\nexport function flat<D extends SafeUintWithSmallInt = 1>(\n depth?: number,\n): <const Ar extends readonly unknown[]>(\n array: Ar,\n) => readonly FlatArray<Ar, D>[];\n\nexport function flat<E, D extends SafeUintWithSmallInt = 1>(\n ...args: readonly [array: readonly E[], depth?: D] | readonly [depth?: D]\n): readonly unknown[] | ((array: readonly unknown[]) => readonly unknown[]) {\n switch (args.length) {\n case 2:\n return flatImpl(...args);\n\n case 1: {\n const [arrayOrDepth] = args;\n\n if (typeof arrayOrDepth === 'number') {\n const depth = arrayOrDepth as SafeUintWithSmallInt | undefined;\n\n return (array) => flatImpl(array, depth);\n }\n\n if (arrayOrDepth === undefined) {\n return (array) => flatImpl(array, 1);\n }\n\n expectType<typeof arrayOrDepth, readonly E[]>('=');\n\n return arrayOrDepth.flat();\n }\n\n case 0:\n return (array) => flatImpl(array, 1);\n }\n}\n\nconst flatImpl = (\n array: readonly unknown[],\n depth?: SafeUintWithSmallInt,\n): readonly unknown[] => array.flat(depth);\n\n/**\n * Maps each element and flattens the result.\n *\n * @example\n *\n * ```ts\n * const words = ['Ada', 'AI'] as const;\n *\n * const characters = Arr.flatMap(words, (word) => word.split(''));\n *\n * const labeled = Arr.flatMap<string, string>((word, index) =>\n * word.split('').map((char) => `${index}-${char}`),\n * )(words);\n *\n * assert.deepStrictEqual(characters, ['A', 'd', 'a', 'A', 'I']);\n *\n * assert.deepStrictEqual(labeled, ['0-A', '0-d', '0-a', '1-A', '1-I']);\n * ```\n */\nexport function flatMap<const Ar extends readonly unknown[], B>(\n array: Ar,\n mapFn: (a: Ar[number], index: ArrayIndex<Ar>) => readonly B[],\n): readonly B[];\n\nexport function flatMap<A, B>(\n mapFn: (a: A, index: SizeType.Arr) => readonly B[],\n): (array: readonly A[]) => readonly B[];\n\nexport function flatMap<A, B>(\n ...args:\n | readonly [\n array: readonly A[],\n mapFn: (a: A, index: SizeType.Arr) => readonly B[],\n ]\n | readonly [mapFn: (a: A, index: SizeType.Arr) => readonly B[]]\n): readonly B[] | ((array: readonly A[]) => readonly B[]) {\n switch (args.length) {\n case 2: {\n const [array, mapFn] = args;\n\n return array.flatMap((a, i) => mapFn(a, asUint32(i)));\n }\n\n case 1: {\n const [mapFn] = args;\n\n return (array: readonly A[]) => flatMap(array, mapFn);\n }\n }\n}\n\n/**\n * Partitions an array into sub-arrays of a specified size.\n *\n * @example\n *\n * ```ts\n * const values = [1, 2, 3, 4, 5] as const;\n *\n * const pairs = Arr.partition(values, 2);\n *\n * const triples = Arr.partition(3)(values);\n *\n * const expectedPairs = [[1, 2], [3, 4], [5]] as const;\n *\n * assert.deepStrictEqual(pairs, expectedPairs);\n *\n * assert.deepStrictEqual(triples, [\n * [1, 2, 3],\n * [4, 5],\n * ]);\n *\n * const pairs2 = Arr.chunk([1, 2, 3, 4, 5, 6], 2);\n *\n * assert.deepStrictEqual(pairs2, [\n * [1, 2],\n * [3, 4],\n * [5, 6],\n * ]);\n * ```\n */\nexport function partition<\n N extends WithSmallInt<PositiveInt & SizeType.Arr>,\n E,\n>(array: readonly E[], chunkSize: N): readonly (readonly E[])[];\n\nexport function partition<N extends WithSmallInt<PositiveInt & SizeType.Arr>>(\n chunkSize: N,\n): <E>(array: readonly E[]) => readonly (readonly E[])[];\n\nexport function partition<\n N extends WithSmallInt<PositiveInt & SizeType.Arr>,\n E,\n>(\n ...args:\n readonly [array: readonly E[], chunkSize: N] | readonly [chunkSize: N]\n):\n | readonly (readonly E[])[]\n | ((array: readonly E[]) => readonly (readonly E[])[]) {\n switch (args.length) {\n case 2:\n return partitionImpl(...args);\n\n case 1:\n return (array) => partitionImpl(array, ...args);\n }\n}\n\nconst partitionImpl = <N extends WithSmallInt<PositiveInt & SizeType.Arr>, E>(\n array: readonly E[],\n chunkSize: N,\n): readonly (readonly E[])[] =>\n chunkSize < 2\n ? ([] as const)\n : // eslint-disable-next-line total-functions/no-partial-division\n seq(asUint32(Math.ceil(array.length / chunkSize))).map((i: Uint32) =>\n array.slice(chunkSize * i, chunkSize * (i + 1)),\n );\n\n/**\n * Concatenates two arrays.\n *\n * The exact tuple shape is preserved. Additionally, when either input is known\n * to be non-empty (a non-empty tuple or a branded `NonEmptyArray`), the result\n * is branded as non-empty so it is assignable to `NonEmptyArray`.\n *\n * @example\n *\n * ```ts\n * const numbers = [1, 2] as const;\n *\n * const words = ['three', 'four'] as const;\n *\n * const combined = Arr.concat(numbers, words);\n *\n * // Because at least one input is non-empty, the result is assignable to\n * // NonEmptyArray.\n * const nonEmpty: NonEmptyArray<number | string> = combined;\n *\n * const expectedCombined = [1, 2, 'three', 'four'] as const;\n *\n * assert.deepStrictEqual<readonly (number | string)[]>(\n * combined,\n * expectedCombined,\n * );\n *\n * assert.isTrue(nonEmpty.length >= 1);\n * ```\n */\nexport const concat = <\n const Ar1 extends readonly unknown[],\n const Ar2 extends readonly unknown[],\n>(\n array1: Ar1,\n array2: Ar2,\n): ConcatResult<Ar1, Ar2> =>\n // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n [...array1, ...array2] as never;\n\n/**\n * Return type of {@link concat}: the concatenated tuple `readonly [...Ar1,\n * ...Ar2]`, additionally branded as {@link NonEmptyArray} when either input is\n * a non-empty tuple (a plain non-empty tuple or a branded `NonEmptyArray`,\n * both of which extend `NonEmptyTuple<unknown>`).\n */\ntype ConcatResult<\n Ar1 extends readonly unknown[],\n Ar2 extends readonly unknown[],\n> =\n Ar1 extends NonEmptyTuple<unknown>\n ? readonly [...Ar1, ...Ar2] & NonEmptyArray<Ar1[number] | Ar2[number]>\n : Ar2 extends NonEmptyTuple<unknown>\n ? readonly [...Ar1, ...Ar2] & NonEmptyArray<Ar1[number] | Ar2[number]>\n : readonly [...Ar1, ...Ar2];\n\n/**\n * Groups elements by a key derived from each element.\n *\n * @example\n *\n * ```ts\n * const animals = ['ant', 'bat', 'cat', 'dove'] as const;\n *\n * const groupedByLength = Arr.groupBy(animals, (animal) => animal.length);\n *\n * const groupedByFirstLetter = Arr.groupBy((animal: string) => animal.at(0))(\n * animals,\n * );\n *\n * assert.deepStrictEqual(\n * groupedByLength.get(3),\n * Optional.some(['ant', 'bat', 'cat'] as const),\n * );\n *\n * assert.deepStrictEqual(\n * groupedByLength.get(4),\n * Optional.some(['dove'] as const),\n * );\n *\n * assert.deepStrictEqual(groupedByLength.get(5), Optional.none);\n *\n * assert.deepStrictEqual(\n * groupedByFirstLetter.get('a'),\n * Optional.some(['ant'] as const),\n * );\n *\n * assert.deepStrictEqual(\n * groupedByFirstLetter.get('d'),\n * Optional.some(['dove'] as const),\n * );\n * ```\n */\nexport function groupBy<\n const Ar extends readonly unknown[],\n G extends MapSetKeyType,\n>(\n array: Ar,\n grouper: (value: Ar[number], index: ArrayIndex<Ar>) => G,\n): IMap<G, readonly Ar[number][]>;\n\nexport function groupBy<E, G extends MapSetKeyType>(\n grouper: (value: E, index: SizeType.Arr) => G,\n): (array: readonly E[]) => IMap<G, readonly E[]>;\n\nexport function groupBy<E, G extends MapSetKeyType>(\n ...args:\n | readonly [\n array: readonly E[],\n grouper: (value: E, index: SizeType.Arr) => G,\n ]\n | readonly [grouper: (value: E, index: SizeType.Arr) => G]\n): IMap<G, readonly E[]> | ((array: readonly E[]) => IMap<G, readonly E[]>) {\n switch (args.length) {\n case 2: {\n const [array, grouper] = args;\n\n const mut_groups = new Map<G, E[]>(); // Store mutable arrays internally\n\n for (const [index, e] of array.entries()) {\n const key = grouper(e, asUint32(index)); // Ensure index is treated as SizeType.Arr\n\n const mut_group = mut_groups.get(key);\n\n if (mut_group !== undefined) {\n mut_group.push(e);\n } else {\n mut_groups.set(key, [e]);\n }\n }\n\n // Cast to IMap<G, readonly A[]> for the public interface\n return IMap.create<G, readonly E[]>(mut_groups);\n }\n\n case 1: {\n const [grouper] = args;\n\n return (array: readonly E[]) => groupBy(array, grouper);\n }\n }\n}\n\n/**\n * Creates an array of tuples by pairing corresponding elements from two arrays.\n *\n * @example\n *\n * ```ts\n * const letters = ['a', 'b', 'c'] as const;\n *\n * const numbers = [1, 2, 3] as const;\n *\n * const pairs = Arr.zip(letters, numbers);\n *\n * const expectedPairs = [\n * ['a', 1],\n * ['b', 2],\n * ['c', 3],\n * ] as const;\n *\n * assert.deepStrictEqual(pairs, expectedPairs);\n * ```\n */\nexport const zip = <\n const Ar1 extends readonly unknown[],\n const Ar2 extends readonly unknown[],\n>(\n array1: Ar1,\n array2: Ar2,\n): List.Zip<Ar1, Ar2> =>\n // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n seq(Uint32.min(size(array1), size(array2))).map((i: Uint32) =>\n // Non-null assertion is safe here because `i` is always within bounds of both arrays up to the length of the shorter one.\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n tp(array1[i]!, array2[i]!),\n ) as unknown as List.Zip<Ar1, Ar2>;\n\n/**\n * Alias for `partition`.\n *\n * @see {@link partition}\n */\nexport const chunk = partition;\n\n/**\n * Computes the cartesian product of arrays.\n * cartesianProduct([[1,2], [3,4]]) => [[1,3], [1,4], [2,3], [2,4]]\n *\n * @example\n *\n *\n * ```ts\n * const sizes = ['S', 'M'] as const;\n *\n * const colors = ['red', 'blue'] as const;\n *\n * const combinations = Arr.cartesianProduct([sizes, colors]);\n *\n * const expectedCombinations = [\n * ['S', 'red'],\n * ['S', 'blue'],\n * ['M', 'red'],\n * ['M', 'blue'],\n * ] as const;\n *\n * assert.deepStrictEqual(combinations, expectedCombinations);\n * ```\n */\nexport const cartesianProduct = <T,>(\n arrays: readonly (readonly T[])[],\n): readonly (readonly T[])[] => {\n if (!isNonEmpty(arrays)) return [[]];\n\n const [first, ...rest] = arrays;\n\n // If first array is empty, the result is empty\n if (!isNonEmpty(first)) return [];\n\n const restProduct = cartesianProduct(rest);\n\n return first.flatMap((item) => restProduct.map((prod) => [item, ...prod]));\n};\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"array-utils-transformation.mjs","sources":["../../../src/array/impl/array-utils-transformation.mts"],"sourcesContent":["import {\n type BoundedLengthArray,\n type ChangeArrayElement,\n type ConstrainedList,\n type FixedLengthTuple,\n type HasLengthConstraint,\n type IsFixedLengthList,\n type NonEmptyArray,\n type NonEmptyTuple,\n type PositiveInt,\n type PositiveUint32,\n type Primitive,\n type SafeUintWithSmallInt,\n type SupportedLength,\n type UnknownBrand,\n type WithSmallInt,\n} from 'ts-type-forge';\nimport { IMap } from '../../collections/index.mjs';\nimport { expectType } from '../../expect-type.mjs';\nimport { asPositiveUint32, asUint32, Uint32 } from '../../number/index.mjs';\nimport { castMutable, tp } from '../../others/index.mjs';\nimport {\n type ArrayIndex,\n type MapSetKeyType,\n type SizeType,\n} from '../../types.mjs';\nimport { newArray, seq } from './array-utils-creation.mjs';\nimport { isNonEmpty } from './array-utils-length-bounded-array-guard.mjs';\nimport { size } from './array-utils-size.mjs';\n\n/**\n * Creates a new array by transforming each element with a mapping function.\n *\n * @example\n *\n * ```ts\n * const numbers = [1, 2, 3] as const;\n *\n * const doubled = Arr.map(numbers, (value) => value * 2);\n *\n * const indexed = Arr.map<number, string>(\n * (value, index) => `${index}:${value}`,\n * )(numbers);\n *\n * assert.deepStrictEqual(doubled, [2, 4, 6]);\n *\n * assert.deepStrictEqual(indexed, ['0:1', '1:2', '2:3']);\n * ```\n */\nexport function map<const Ar extends readonly unknown[] & UnknownBrand, B>(\n array: Ar,\n mapFn: (a: Ar[number], index: ArrayIndex<Ar>) => B,\n): ChangeArrayElement<Ar, B>;\n\n// A plain array or tuple carries no length brand, so the homomorphic mapping\n// is the whole answer. Stating it directly — rather than going through\n// `ChangeArrayElement`, whose `HasLengthConstraint` test a *generic* `Ar`\n// cannot decide — is what keeps `map` usable inside a function that is itself\n// generic over the tuple: a deferred conditional is not assignable to the\n// caller's own `{ [K in keyof Ar]: B }`, while this is.\nexport function map<const Ar extends readonly unknown[], B>(\n array: Ar,\n mapFn: (a: Ar[number], index: ArrayIndex<Ar>) => B,\n): Readonly<{ [K in keyof Ar]: B }>;\n\n// curried version\n//\n// The two cases have to be overloads *of the returned function*, not two\n// overloads of `map` itself: both curried signatures take the same single\n// argument, so overload resolution would always pick the first and the second\n// would be dead.\n//\n// Spelled as an intersection of two function types rather than one object type\n// carrying two call signatures — the `convert-to-readonly` codemod wraps an\n// inline object type in `Readonly<…>`, and a mapped type drops call\n// signatures, which would leave the curried form with none at all.\nexport function map<A, B>(\n mapFn: (a: A, index: SizeType.Arr) => B,\n): (<const Ar extends readonly A[] & UnknownBrand>(\n array: Ar,\n) => ChangeArrayElement<Ar, B>) &\n (<const Ar extends readonly A[]>(\n array: Ar,\n ) => Readonly<{ [K in keyof Ar]: B }>);\n\nexport function map<A, B>(\n ...args:\n | readonly [array: readonly A[], mapFn: (a: A, index: SizeType.Arr) => B]\n | readonly [mapFn: (a: A, index: SizeType.Arr) => B]\n): readonly B[] | ((array: readonly A[]) => readonly B[]) {\n switch (args.length) {\n case 2: {\n const [array, mapFn] = args;\n\n // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n return array.map(mapFn as never);\n }\n\n case 1: {\n const [mapFn] = args;\n\n return (array: readonly A[]) => map(array, mapFn);\n }\n }\n}\n\n/**\n * Returns an array of successively reduced values from an array.\n *\n * @example\n *\n * ```ts\n * const changes = [5, -2, 3] as const;\n *\n * const runningTotals = Arr.scan(\n * changes,\n * (total, change) => total + change,\n * 0,\n * );\n *\n * const runningTotalsFromCurried = Arr.scan(\n * (total: number, change: number) => total + change,\n * 10,\n * )([-5, 15]);\n *\n * const expectedTotals = [0, 5, 3, 6] as const;\n *\n * const expectedCurriedTotals = [10, 5, 20] as const;\n *\n * assert.deepStrictEqual<readonly number[]>(runningTotals, expectedTotals);\n *\n * assert.deepStrictEqual<readonly number[]>(\n * runningTotalsFromCurried,\n * expectedCurriedTotals,\n * );\n * ```\n */\nexport function scan<const Ar extends readonly unknown[], S>(\n array: Ar,\n reducer: (\n accumulator: S,\n currentValue: Ar[number],\n currentIndex: ArrayIndex<Ar>,\n ) => S,\n init: S,\n): NonEmptyArray<S>;\n\nexport function scan<E, S>(\n reducer: (accumulator: S, currentValue: E, currentIndex: SizeType.Arr) => S,\n init: S,\n): (array: readonly E[]) => NonEmptyArray<S>;\n\nexport function scan<E, S>(\n ...args:\n | readonly [\n array: readonly E[],\n reducer: (\n accumulator: S,\n currentValue: E,\n currentIndex: SizeType.Arr,\n ) => S,\n init: S,\n ]\n | readonly [\n reducer: (\n accumulator: S,\n currentValue: E,\n currentIndex: SizeType.Arr,\n ) => S,\n init: S,\n ]\n): NonEmptyTuple<S> | ((array: readonly E[]) => NonEmptyTuple<S>) {\n switch (args.length) {\n case 3:\n return scanImpl(...args);\n\n case 2:\n return (array) => scanImpl(array, ...args);\n }\n}\n\nconst scanImpl = <E, S>(\n array: readonly E[],\n reducer: (accumulator: S, currentValue: E, currentIndex: SizeType.Arr) => S,\n init: S,\n): NonEmptyTuple<S> => {\n const mut_result = castMutable<NonEmptyTuple<S>>(\n newArray<PositiveUint32, S>(asPositiveUint32(array.length + 1), init),\n );\n\n let mut_acc = init;\n\n for (const [index, value] of array.entries()) {\n mut_acc = reducer(mut_acc, value, asUint32(index));\n\n mut_result[index + 1] = mut_acc;\n }\n\n return mut_result;\n};\n\n/**\n * Reverses an array.\n *\n * @example\n *\n * ```ts\n * const tuple = [1, 'two', true] as const;\n *\n * const reversed = Arr.toReversed(tuple);\n *\n * const expected = [true, 'two', 1] as const;\n *\n * assert.deepStrictEqual(reversed, expected);\n * ```\n */\nexport const toReversed = <const Ar extends readonly unknown[]>(\n array: Ar,\n): ConstrainedList.Reverse<Ar> =>\n // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n array.toReversed() as never;\n\n/**\n * Sorts an array.\n *\n * @example\n *\n * ```ts\n * const numbers = [3, 1, 2] as const;\n *\n * const words = ['banana', 'apple', 'cherry'] as const;\n *\n * const ascendingNumbers = Arr.toSorted(numbers);\n *\n * const alphabetical = Arr.toSorted(words, (left, right) =>\n * left.localeCompare(right),\n * );\n *\n * const expectedNumbers = [1, 2, 3] as const;\n *\n * const expectedWords = ['apple', 'banana', 'cherry'] as const;\n *\n * assert.deepStrictEqual(ascendingNumbers, expectedNumbers);\n *\n * assert.deepStrictEqual(alphabetical, expectedWords);\n * ```\n */\nexport const toSorted = <const Ar extends readonly unknown[]>(\n ...[array, comparator]: Ar extends readonly number[]\n ? readonly [\n array: Ar,\n // If the array elements are mapped to numbers, comparator is optional.\n comparator?: (x: Ar[number], y: Ar[number]) => number,\n ]\n : readonly [array: Ar, comparator: (x: Ar[number], y: Ar[number]) => number]\n): HasLengthConstraint<Ar> extends true\n ? ChangeArrayElement<Ar, Ar[number]>\n : IsFixedLengthList<Ar> extends true\n ? FixedLengthTuple<Ar['length'], Ar[number]>\n : Ar extends NonEmptyTuple<unknown>\n ? NonEmptyArray<Ar[number]>\n : readonly Ar[number][] =>\n // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n array.toSorted(\n // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n (comparator as ((x: unknown, y: unknown) => number) | undefined) ??\n // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n ((x, y) => (x as number) - (y as number)),\n ) as never;\n\n/**\n * Sorts an array by a mapped value.\n *\n * @example\n *\n * ```ts\n * const projects = [\n * { name: 'compiler', issues: 7 },\n * { name: 'docs', issues: 2 },\n * { name: 'ui', issues: 5 },\n * ] as const;\n *\n * const byIssueCount = Arr.toSortedBy(projects, (project) => project.issues);\n *\n * const byIssueCountDescending = Arr.toSortedBy(\n * projects,\n * (project) => project.issues,\n * (left, right) => right - left,\n * );\n *\n * const expectedByIssues = [\n * { name: 'docs', issues: 2 },\n * { name: 'ui', issues: 5 },\n * { name: 'compiler', issues: 7 },\n * ] as const;\n *\n * const expectedByIssueCountDescending = [\n * { name: 'compiler', issues: 7 },\n * { name: 'ui', issues: 5 },\n * { name: 'docs', issues: 2 },\n * ] as const;\n *\n * assert.deepStrictEqual(byIssueCount, expectedByIssues);\n *\n * assert.deepStrictEqual(\n * byIssueCountDescending,\n * expectedByIssueCountDescending,\n * );\n * ```\n */\nexport function toSortedBy<const Ar extends readonly unknown[]>(\n array: Ar,\n comparatorValueMapper: (value: Ar[number]) => number,\n // If the array elements are mapped to numbers, comparator is optional.\n comparator?: (x: number, y: number) => number,\n): HasLengthConstraint<Ar> extends true\n ? ChangeArrayElement<Ar, Ar[number]>\n : IsFixedLengthList<Ar> extends true\n ? FixedLengthTuple<Ar['length'], Ar[number]>\n : Ar extends NonEmptyTuple<unknown>\n ? NonEmptyArray<Ar[number]>\n : readonly Ar[number][];\n\nexport function toSortedBy<const Ar extends readonly unknown[], const V>(\n array: Ar,\n comparatorValueMapper: (value: Ar[number]) => V,\n comparator: (x: V, y: V) => number,\n): HasLengthConstraint<Ar> extends true\n ? ChangeArrayElement<Ar, Ar[number]>\n : IsFixedLengthList<Ar> extends true\n ? FixedLengthTuple<Ar['length'], Ar[number]>\n : Ar extends NonEmptyTuple<unknown>\n ? NonEmptyArray<Ar[number]>\n : readonly Ar[number][];\n\nexport function toSortedBy<E, const V>(\n array: readonly E[],\n comparatorValueMapper: (value: E) => V,\n comparator?: (x: V, y: V) => number,\n): readonly E[] {\n return array.toSorted((x, y) =>\n comparator === undefined\n ? // This branch assumes V is number if comparator is undefined.\n // The overloads should handle this, but explicit cast might be needed if V is not number.\n // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n (comparatorValueMapper(x) as number) -\n // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n (comparatorValueMapper(y) as number)\n : comparator(comparatorValueMapper(x), comparatorValueMapper(y)),\n );\n}\n\n/**\n * Filters an array based on a predicate function.\n *\n * @example\n *\n * ```ts\n * const numbers = [1, 2, 3, 4] as const;\n *\n * const evens = Arr.filter(numbers, (value) => value % 2 === 0);\n *\n * const greaterThanTwo = Arr.filter<number>((value) => value > 2)(numbers);\n *\n * assert.deepStrictEqual(evens, [2, 4]);\n *\n * assert.deepStrictEqual(greaterThanTwo, [3, 4]);\n * ```\n */\n// Type guard overloads\nexport function filter<\n const Ar extends readonly unknown[],\n S extends Ar[number],\n>(\n array: Ar,\n predicate: (a: Ar[number], index: ArrayIndex<Ar>) => a is S,\n): readonly S[];\n\nexport function filter<E, S extends E>(\n predicate: (a: E, index: SizeType.Arr) => a is S,\n): (array: readonly E[]) => readonly S[];\n\n// Regular boolean predicate overloads\nexport function filter<const Ar extends readonly unknown[]>(\n array: Ar,\n predicate: (a: Ar[number], index: ArrayIndex<Ar>) => boolean,\n): readonly Ar[number][];\n\nexport function filter<E>(\n predicate: (a: E, index: SizeType.Arr) => boolean,\n): (array: readonly E[]) => readonly E[];\n\nexport function filter<E>(\n ...args:\n | readonly [\n array: readonly E[],\n predicate: (a: E, index: SizeType.Arr) => boolean,\n ]\n | readonly [predicate: (a: E, index: SizeType.Arr) => boolean]\n): readonly E[] | ((array: readonly E[]) => readonly E[]) {\n switch (args.length) {\n case 2:\n return filterImpl(...args);\n\n case 1:\n return (array) => filterImpl(array, ...args);\n }\n}\n\nconst filterImpl = <E,>(\n array: readonly E[],\n predicate: (a: E, index: SizeType.Arr) => boolean,\n): readonly E[] => array.filter((a, i) => predicate(a, asUint32(i)));\n\n/**\n * Filters an array by excluding elements for which the predicate returns true.\n *\n * @example\n *\n * ```ts\n * const names = ['Ada', 'Grace', 'Linus'] as const;\n *\n * const notAda = Arr.filterNot(names, (name) => name === 'Ada');\n *\n * const notShort = Arr.filterNot<string>((name) => name.length <= 4)(names);\n *\n * assert.deepStrictEqual(notAda, ['Grace', 'Linus']);\n *\n * assert.deepStrictEqual(notShort, ['Grace', 'Linus']);\n * ```\n */\nexport function filterNot<const Ar extends readonly unknown[]>(\n array: Ar,\n predicate: (a: Ar[number], index: ArrayIndex<Ar>) => boolean,\n): readonly Ar[number][];\n\nexport function filterNot<E>(\n predicate: (a: E, index: SizeType.Arr) => boolean,\n): (array: readonly E[]) => readonly E[];\n\nexport function filterNot<E>(\n ...args:\n | readonly [\n array: readonly E[],\n predicate: (a: E, index: SizeType.Arr) => boolean,\n ]\n | readonly [predicate: (a: E, index: SizeType.Arr) => boolean]\n): readonly E[] | ((array: readonly E[]) => readonly E[]) {\n switch (args.length) {\n case 2:\n return filterNotImpl(...args);\n\n case 1:\n return (array) => filterNotImpl(array, ...args);\n }\n}\n\nconst filterNotImpl = <E,>(\n array: readonly E[],\n predicate: (a: E, index: SizeType.Arr) => boolean,\n): readonly E[] => array.filter((a, i) => !predicate(a, asUint32(i)));\n\n/**\n * Creates a new array with unique elements.\n *\n * @example\n *\n * ```ts\n * const letters = ['a', 'b', 'a', 'c', 'b'] as const;\n *\n * const uniqueLetters = Arr.uniq(letters);\n *\n * const expected = ['a', 'b', 'c'] as const;\n *\n * assert.deepStrictEqual<readonly string[]>(uniqueLetters, expected);\n * ```\n */\nexport const uniq = <const Ar extends readonly Primitive[]>(\n array: Ar,\n): Ar extends NonEmptyTuple<unknown>\n ? NonEmptyArray<Ar[number]>\n : readonly Ar[number][] =>\n // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n Array.from(new Set(array)) as never;\n\n/**\n * Creates a new array with unique elements based on a mapped value.\n *\n * @example\n *\n * ```ts\n * const people = [\n * { id: 1, name: 'Ada' },\n * { id: 2, name: 'Brian' },\n * { id: 1, name: 'Alan' },\n * { id: 3, name: 'Grace' },\n * ] as const;\n *\n * const uniqueById = Arr.uniqBy(people, (person) => person.id);\n *\n * const expected = [\n * { id: 1, name: 'Ada' },\n * { id: 2, name: 'Brian' },\n * { id: 3, name: 'Grace' },\n * ] as const;\n *\n * assert.deepStrictEqual<readonly Readonly<{ id: number; name: string }>[]>(\n * uniqueById,\n * expected,\n * );\n * ```\n */\nexport const uniqBy = <\n const Ar extends readonly unknown[],\n P extends Primitive,\n>(\n array: Ar,\n mapFn: (value: Ar[number]) => P,\n): Ar extends NonEmptyTuple<unknown>\n ? NonEmptyArray<Ar[number]>\n : readonly Ar[number][] => {\n const mut_mappedValues = new Set<P>();\n\n // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n return array.filter((val) => {\n const mappedValue = mapFn(val);\n\n if (mut_mappedValues.has(mappedValue)) return false;\n\n mut_mappedValues.add(mappedValue);\n\n return true;\n }) satisfies readonly Ar[number][] as never;\n};\n\n/**\n * Flattens nested arrays up to the specified depth.\n *\n * @example\n *\n * ```ts\n * const nested = [\n * [1, 2],\n * [3, 4],\n * ] as const;\n *\n * const flatOnce = Arr.flat(nested, 1);\n *\n * const flatCurried = Arr.flat()(nested);\n *\n * assert.deepStrictEqual(flatOnce, [1, 2, 3, 4]);\n *\n * assert.deepStrictEqual(flatCurried, [1, 2, 3, 4]);\n * ```\n */\nexport function flat<\n const Ar extends readonly unknown[],\n D extends SafeUintWithSmallInt = 1,\n>(array: Ar, depth?: D): readonly FlatArray<Ar, D>[];\n\nexport function flat<D extends SafeUintWithSmallInt = 1>(\n depth?: number,\n): <const Ar extends readonly unknown[]>(\n array: Ar,\n) => readonly FlatArray<Ar, D>[];\n\nexport function flat<E, D extends SafeUintWithSmallInt = 1>(\n ...args: readonly [array: readonly E[], depth?: D] | readonly [depth?: D]\n): readonly unknown[] | ((array: readonly unknown[]) => readonly unknown[]) {\n switch (args.length) {\n case 2:\n return flatImpl(...args);\n\n case 1: {\n const [arrayOrDepth] = args;\n\n if (typeof arrayOrDepth === 'number') {\n const depth = arrayOrDepth as SafeUintWithSmallInt | undefined;\n\n return (array) => flatImpl(array, depth);\n }\n\n if (arrayOrDepth === undefined) {\n return (array) => flatImpl(array, 1);\n }\n\n expectType<typeof arrayOrDepth, readonly E[]>('=');\n\n return arrayOrDepth.flat();\n }\n\n case 0:\n return (array) => flatImpl(array, 1);\n }\n}\n\nconst flatImpl = (\n array: readonly unknown[],\n depth?: SafeUintWithSmallInt,\n): readonly unknown[] => array.flat(depth);\n\n/**\n * Maps each element and flattens the result.\n *\n * @example\n *\n * ```ts\n * const words = ['Ada', 'AI'] as const;\n *\n * const characters = Arr.flatMap(words, (word) => word.split(''));\n *\n * const labeled = Arr.flatMap<string, string>((word, index) =>\n * word.split('').map((char) => `${index}-${char}`),\n * )(words);\n *\n * assert.deepStrictEqual(characters, ['A', 'd', 'a', 'A', 'I']);\n *\n * assert.deepStrictEqual(labeled, ['0-A', '0-d', '0-a', '1-A', '1-I']);\n * ```\n */\nexport function flatMap<const Ar extends readonly unknown[], B>(\n array: Ar,\n mapFn: (a: Ar[number], index: ArrayIndex<Ar>) => readonly B[],\n): readonly B[];\n\nexport function flatMap<A, B>(\n mapFn: (a: A, index: SizeType.Arr) => readonly B[],\n): (array: readonly A[]) => readonly B[];\n\nexport function flatMap<A, B>(\n ...args:\n | readonly [\n array: readonly A[],\n mapFn: (a: A, index: SizeType.Arr) => readonly B[],\n ]\n | readonly [mapFn: (a: A, index: SizeType.Arr) => readonly B[]]\n): readonly B[] | ((array: readonly A[]) => readonly B[]) {\n switch (args.length) {\n case 2: {\n const [array, mapFn] = args;\n\n return array.flatMap((a, i) => mapFn(a, asUint32(i)));\n }\n\n case 1: {\n const [mapFn] = args;\n\n return (array: readonly A[]) => flatMap(array, mapFn);\n }\n }\n}\n\n/**\n * Partitions an array into sub-arrays of a specified size.\n *\n * @example\n *\n * ```ts\n * const values = [1, 2, 3, 4, 5] as const;\n *\n * const pairs = Arr.partition(values, 2);\n *\n * const triples = Arr.partition(3)(values);\n *\n * // Every chunk is branded `BoundedLengthArray<1, N, …>` — `partition` never\n * // emits an empty chunk — so the expected values are annotated with the\n * // unbranded type.\n * const expectedPairs = [[1, 2], [3, 4], [5]] as const;\n *\n * assert.deepStrictEqual<readonly (readonly number[])[]>(\n * pairs,\n * expectedPairs,\n * );\n *\n * assert.deepStrictEqual<readonly (readonly number[])[]>(triples, [\n * [1, 2, 3],\n * [4, 5],\n * ]);\n *\n * const pairs2 = Arr.chunk([1, 2, 3, 4, 5, 6], 2);\n *\n * assert.deepStrictEqual<readonly (readonly number[])[]>(pairs2, [\n * [1, 2],\n * [3, 4],\n * [5, 6],\n * ]);\n * ```\n */\nexport function partition<\n E,\n N extends WithSmallInt<PositiveInt & SizeType.Arr>,\n>(array: readonly E[], chunkSize: N): readonly PartitionChunk<N, E>[];\n\nexport function partition<N extends WithSmallInt<PositiveInt & SizeType.Arr>>(\n chunkSize: N,\n): <E>(array: readonly E[]) => readonly PartitionChunk<N, E>[];\n\nexport function partition<\n E,\n N extends WithSmallInt<PositiveInt & SizeType.Arr>,\n>(\n ...args:\n readonly [array: readonly E[], chunkSize: N] | readonly [chunkSize: N]\n):\n | readonly (readonly E[])[]\n | ((array: readonly E[]) => readonly (readonly E[])[]) {\n switch (args.length) {\n case 2:\n return partitionImpl(...args);\n\n case 1:\n return (array) => partitionImpl(array, ...args);\n }\n}\n\n/**\n * Element type of {@link partition}'s result: a chunk holds between 1 and `N`\n * elements. The lower bound is what makes this worth spelling out — `partition`\n * never emits an empty chunk, so indexed access into a chunk is not\n * `undefined` at position `0`, unlike with a plain `readonly E[]`.\n *\n * Falls back to {@link NonEmptyArray} when `N` is not a bound the brand can\n * express, which keeps that lower bound in every case.\n */\ntype PartitionChunk<N, E> = N extends SupportedLength\n ? BoundedLengthArray<1, N, E>\n : NonEmptyArray<E>;\n\nconst partitionImpl = <E, N extends WithSmallInt<PositiveInt & SizeType.Arr>>(\n array: readonly E[],\n chunkSize: N,\n): readonly (readonly E[])[] =>\n chunkSize < 2\n ? ([] as const)\n : // eslint-disable-next-line total-functions/no-partial-division\n seq(asUint32(Math.ceil(array.length / chunkSize))).map((i: Uint32) =>\n array.slice(chunkSize * i, chunkSize * (i + 1)),\n );\n\n/**\n * Alias for `partition`.\n *\n * @see {@link partition}\n */\nexport const chunk = partition;\n\n/**\n * Concatenates two arrays.\n *\n * The exact tuple shape is preserved. Additionally, when either input is known\n * to be non-empty (a non-empty tuple or a branded `NonEmptyArray`), the result\n * is branded as non-empty so it is assignable to `NonEmptyArray`.\n *\n * @example\n *\n * ```ts\n * const numbers = [1, 2] as const;\n *\n * const words = ['three', 'four'] as const;\n *\n * const combined = Arr.concat(numbers, words);\n *\n * // Because at least one input is non-empty, the result is assignable to\n * // NonEmptyArray.\n * const nonEmpty: NonEmptyArray<number | string> = combined;\n *\n * const expectedCombined = [1, 2, 'three', 'four'] as const;\n *\n * assert.deepStrictEqual<readonly (number | string)[]>(\n * combined,\n * expectedCombined,\n * );\n *\n * assert.isTrue(nonEmpty.length >= 1);\n * ```\n */\nexport const concat = <\n const Ar1 extends readonly unknown[],\n const Ar2 extends readonly unknown[],\n>(\n array1: Ar1,\n array2: Ar2,\n): ConcatResult<Ar1, Ar2> =>\n // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n [...array1, ...array2] as never;\n\n/**\n * Return type of {@link concat}: the concatenated tuple `readonly [...Ar1,\n * ...Ar2]`, additionally branded as {@link NonEmptyArray} when either input is\n * a non-empty tuple (a plain non-empty tuple or a branded `NonEmptyArray`,\n * both of which extend `NonEmptyTuple<unknown>`).\n */\ntype ConcatResult<\n Ar1 extends readonly unknown[],\n Ar2 extends readonly unknown[],\n> =\n Ar1 extends NonEmptyTuple<unknown>\n ? readonly [...Ar1, ...Ar2] & NonEmptyArray<Ar1[number] | Ar2[number]>\n : Ar2 extends NonEmptyTuple<unknown>\n ? readonly [...Ar1, ...Ar2] & NonEmptyArray<Ar1[number] | Ar2[number]>\n : readonly [...Ar1, ...Ar2];\n\n/**\n * Groups elements by a key derived from each element.\n *\n * @example\n *\n * ```ts\n * const animals = ['ant', 'bat', 'cat', 'dove'] as const;\n *\n * const groupedByLength = Arr.groupBy(animals, (animal) => animal.length);\n *\n * const groupedByFirstLetter = Arr.groupBy((animal: string) => animal.at(0))(\n * animals,\n * );\n *\n * assert.deepStrictEqual(\n * groupedByLength.get(3),\n * Optional.some(['ant', 'bat', 'cat'] as const),\n * );\n *\n * assert.deepStrictEqual(\n * groupedByLength.get(4),\n * Optional.some(['dove'] as const),\n * );\n *\n * assert.deepStrictEqual(groupedByLength.get(5), Optional.none);\n *\n * assert.deepStrictEqual(\n * groupedByFirstLetter.get('a'),\n * Optional.some(['ant'] as const),\n * );\n *\n * assert.deepStrictEqual(\n * groupedByFirstLetter.get('d'),\n * Optional.some(['dove'] as const),\n * );\n * ```\n */\nexport function groupBy<\n const Ar extends readonly unknown[],\n G extends MapSetKeyType,\n>(\n array: Ar,\n grouper: (value: Ar[number], index: ArrayIndex<Ar>) => G,\n): IMap<G, readonly Ar[number][]>;\n\nexport function groupBy<E, G extends MapSetKeyType>(\n grouper: (value: E, index: SizeType.Arr) => G,\n): (array: readonly E[]) => IMap<G, readonly E[]>;\n\nexport function groupBy<E, G extends MapSetKeyType>(\n ...args:\n | readonly [\n array: readonly E[],\n grouper: (value: E, index: SizeType.Arr) => G,\n ]\n | readonly [grouper: (value: E, index: SizeType.Arr) => G]\n): IMap<G, readonly E[]> | ((array: readonly E[]) => IMap<G, readonly E[]>) {\n switch (args.length) {\n case 2: {\n const [array, grouper] = args;\n\n const mut_groups = new Map<G, E[]>(); // Store mutable arrays internally\n\n for (const [index, e] of array.entries()) {\n const key = grouper(e, asUint32(index)); // Ensure index is treated as SizeType.Arr\n\n const mut_group = mut_groups.get(key);\n\n if (mut_group !== undefined) {\n mut_group.push(e);\n } else {\n mut_groups.set(key, [e]);\n }\n }\n\n // Cast to IMap<G, readonly A[]> for the public interface\n return IMap.create<G, readonly E[]>(mut_groups);\n }\n\n case 1: {\n const [grouper] = args;\n\n return (array: readonly E[]) => groupBy(array, grouper);\n }\n }\n}\n\n/**\n * Creates an array of tuples by pairing corresponding elements from two arrays.\n *\n * @example\n *\n * ```ts\n * const letters = ['a', 'b', 'c'] as const;\n *\n * const numbers = [1, 2, 3] as const;\n *\n * const pairs = Arr.zip(letters, numbers);\n *\n * const expectedPairs = [\n * ['a', 1],\n * ['b', 2],\n * ['c', 3],\n * ] as const;\n *\n * assert.deepStrictEqual(pairs, expectedPairs);\n * ```\n */\nexport const zip = <\n const Ar1 extends readonly unknown[],\n const Ar2 extends readonly unknown[],\n>(\n array1: Ar1,\n array2: Ar2,\n): ConstrainedList.Zip<Ar1, Ar2> =>\n // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n seq(Uint32.min(size(array1), size(array2))).map((i: Uint32) =>\n // Non-null assertion is safe here because `i` is always within bounds of both arrays up to the length of the shorter one.\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n tp(array1[i]!, array2[i]!),\n ) as unknown as ConstrainedList.Zip<Ar1, Ar2>;\n\n/**\n * Computes the cartesian product of arrays.\n * cartesianProduct([[1,2], [3,4]]) => [[1,3], [1,4], [2,3], [2,4]]\n *\n * @example\n *\n *\n * ```ts\n * const sizes = ['S', 'M'] as const;\n *\n * const colors = ['red', 'blue'] as const;\n *\n * const combinations = Arr.cartesianProduct([sizes, colors]);\n *\n * const expectedCombinations = [\n * ['S', 'red'],\n * ['S', 'blue'],\n * ['M', 'red'],\n * ['M', 'blue'],\n * ] as const;\n *\n * assert.deepStrictEqual(combinations, expectedCombinations);\n * ```\n */\nexport const cartesianProduct = <T,>(\n arrays: readonly (readonly T[])[],\n): readonly (readonly T[])[] => {\n if (!isNonEmpty(arrays)) return [[]];\n\n const [first, ...rest] = arrays;\n\n // If first array is empty, the result is empty\n if (!isNonEmpty(first)) return [];\n\n const restProduct = cartesianProduct(rest);\n\n return first.flatMap((item) => restProduct.map((prod) => [item, ...prod]));\n};\n"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { type BoolOr, type BoundedLengthTuple, type FixedLengthArray, type FixedLengthTuple, type MaxLengthTuple, type MinLengthArray, type MinLengthTuple, type TypeEq } from 'ts-type-forge';
1
+ import { type BoolOr, type IsAny, type IsUnknown } from 'ts-type-forge';
2
2
  import { type ArrayIndex, type SizeType } from '../../types.mjs';
3
3
  /**
4
4
  * Type guard that checks if a value is an array.
@@ -20,130 +20,8 @@ import { type ArrayIndex, type SizeType } from '../../types.mjs';
20
20
  * ```
21
21
  */
22
22
  export declare const isArray: <E>(value: E) => value is FilterArray<E>;
23
- type FilterArray<T> = T extends T ? BoolOr<TypeEq<T, unknown>, TypeEq<T, any>> extends true ? Cast<readonly unknown[], T> : T extends readonly unknown[] ? T : never : never;
23
+ type FilterArray<T> = T extends T ? BoolOr<IsUnknown<T>, IsAny<T>> extends true ? Cast<readonly unknown[], T> : T extends readonly unknown[] ? T : never : never;
24
24
  type Cast<A, B> = A extends B ? A : never;
25
- /**
26
- * Type guard that checks if an array is empty.
27
- *
28
- * @example
29
- *
30
- * ```ts
31
- * const emptyNumbers: readonly number[] = [] as const;
32
- *
33
- * const words = ['Ada', 'Lovelace'] as const;
34
- *
35
- * assert.isTrue(Arr.isEmpty(emptyNumbers));
36
- *
37
- * assert.isFalse(Arr.isEmpty(words));
38
- *
39
- * if (Arr.isEmpty(emptyNumbers)) {
40
- * // `isEmpty` narrows to the branded `FixedLengthArray<0, number>`, so the
41
- * // expected value is annotated with the unbranded type.
42
- * assert.deepStrictEqual<readonly number[]>(emptyNumbers, []);
43
- * }
44
- * ```
45
- */
46
- export declare const isEmpty: <Xs extends readonly unknown[]>(array: Xs) => array is FixedLengthArray<0, Xs[number]> & Xs;
47
- /**
48
- * Type guard that checks if an array is non-empty.
49
- *
50
- * @example
51
- *
52
- * ```ts
53
- * const users: readonly Readonly<{ id: number }>[] = [{ id: 1 }] as const;
54
- *
55
- * const emptyUsers: readonly Readonly<{ id: number }>[] = [] as const;
56
- *
57
- * assert.isTrue(Arr.isNonEmpty(users));
58
- *
59
- * assert.isFalse(Arr.isNonEmpty(emptyUsers));
60
- *
61
- * if (Arr.isNonEmpty(users)) {
62
- * assert.deepStrictEqual(users[0], { id: 1 });
63
- * }
64
- * ```
65
- */
66
- export declare const isNonEmpty: <Xs extends readonly unknown[]>(array: Xs) => array is MinLengthArray<1, Xs[number]> & Xs;
67
- /**
68
- * Checks if an array has a specific length.
69
- *
70
- * @example
71
- *
72
- * ```ts
73
- * const pair: readonly number[] = [1, 2] as const;
74
- *
75
- * const triple: readonly number[] = [1, 2, 3] as const;
76
- *
77
- * assert.isTrue(Arr.isFixedLengthTuple(pair, 2));
78
- *
79
- * assert.isFalse(Arr.isFixedLengthTuple(triple, 2));
80
- *
81
- * if (Arr.isFixedLengthTuple(pair, 2)) {
82
- * assert.deepStrictEqual(pair, [1, 2]);
83
- * }
84
- * ```
85
- */
86
- export declare const isFixedLengthTuple: <E, N extends SizeType.ArgArr>(array: readonly E[], len: N) => array is FixedLengthTuple<N, E>;
87
- /**
88
- * Checks if an array has at least a specific length.
89
- *
90
- * @example
91
- *
92
- * ```ts
93
- * const queue: readonly string[] = ['task-1', 'task-2'] as const;
94
- *
95
- * const emptyQueue: readonly string[] = [] as const;
96
- *
97
- * assert.isTrue(Arr.isMinLengthTuple(queue, 1));
98
- *
99
- * assert.isFalse(Arr.isMinLengthTuple(emptyQueue, 1));
100
- *
101
- * if (Arr.isMinLengthTuple(queue, 1)) {
102
- * assert.isTrue(queue[0] === 'task-1');
103
- * }
104
- * ```
105
- */
106
- export declare const isMinLengthTuple: <E, N extends SizeType.ArgArr>(array: readonly E[], len: N) => array is MinLengthTuple<N, E>;
107
- /**
108
- * Checks if an array has at most a specific length.
109
- *
110
- * @example
111
- *
112
- * ```ts
113
- * const pair: readonly number[] = [1, 2] as const;
114
- *
115
- * const triple: readonly number[] = [1, 2, 3] as const;
116
- *
117
- * assert.isTrue(Arr.isMaxLengthTuple(pair, 2));
118
- *
119
- * assert.isFalse(Arr.isMaxLengthTuple(triple, 2));
120
- *
121
- * if (Arr.isMaxLengthTuple(pair, 2)) {
122
- * assert.isTrue(pair.length <= 2);
123
- * }
124
- * ```
125
- */
126
- export declare const isMaxLengthTuple: <E, N extends SizeType.ArgArr>(array: readonly E[], len: N) => array is MaxLengthTuple<N, E>;
127
- /**
128
- * Checks if an array's length is within a specific inclusive range.
129
- *
130
- * @example
131
- *
132
- * ```ts
133
- * const pair: readonly number[] = [1, 2] as const;
134
- *
135
- * const quad: readonly number[] = [1, 2, 3, 4] as const;
136
- *
137
- * assert.isTrue(Arr.isBoundedLengthTuple(pair, 1, 3));
138
- *
139
- * assert.isFalse(Arr.isBoundedLengthTuple(quad, 1, 3));
140
- *
141
- * if (Arr.isBoundedLengthTuple(pair, 1, 3)) {
142
- * assert.isTrue(pair.length >= 1 && pair.length <= 3);
143
- * }
144
- * ```
145
- */
146
- export declare const isBoundedLengthTuple: <E, Min extends SizeType.ArgArr, Max extends SizeType.ArgArr>(array: readonly E[], min: Min, max: Max) => array is BoundedLengthTuple<Min, Max, E>;
147
25
  /**
148
26
  * Tests whether all elements in an array pass a test implemented by a predicate.
149
27
  *
@@ -1 +1 @@
1
- {"version":3,"file":"array-utils-validation.d.mts","sourceRoot":"","sources":["../../../src/array/impl/array-utils-validation.mts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,MAAM,EACX,KAAK,kBAAkB,EACvB,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,MAAM,EACZ,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAE,KAAK,UAAU,EAAE,KAAK,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAEjE;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,OAAO,GAAI,CAAC,SAAU,CAAC,KAAG,KAAK,IAAI,WAAW,CAAC,CAAC,CACvC,CAAC;AAEvB,KAAK,WAAW,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,GAE7B,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,SAAS,IAAI,GACrD,IAAI,CAAC,SAAS,OAAO,EAAE,EAAE,CAAC,CAAC,GAC3B,CAAC,SAAS,SAAS,OAAO,EAAE,GAC1B,CAAC,GACD,KAAK,GACT,KAAK,CAAC;AAEV,KAAK,IAAI,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;AAI1C;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,OAAO,GAAI,EAAE,SAAS,SAAS,OAAO,EAAE,SAC5C,EAAE,KACR,KAAK,IAAI,gBAAgB,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,GAAG,EAAwB,CAAC;AAEvE;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,UAAU,GAAI,EAAE,SAAS,SAAS,OAAO,EAAE,SAC/C,EAAE,KACR,KAAK,IAAI,cAAc,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,GAAG,EAAsB,CAAC;AAEnE;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,kBAAkB,GAAI,CAAC,EAAE,CAAC,SAAS,QAAQ,CAAC,MAAM,SACtD,SAAS,CAAC,EAAE,OACd,CAAC,KACL,KAAK,IAAI,gBAAgB,CAAC,CAAC,EAAE,CAAC,CAAyB,CAAC;AAE3D;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,gBAAgB,GAAI,CAAC,EAAE,CAAC,SAAS,QAAQ,CAAC,MAAM,SACpD,SAAS,CAAC,EAAE,OACd,CAAC,KACL,KAAK,IAAI,cAAc,CAAC,CAAC,EAAE,CAAC,CAAwB,CAAC;AAExD;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,gBAAgB,GAAI,CAAC,EAAE,CAAC,SAAS,QAAQ,CAAC,MAAM,SACpD,SAAS,CAAC,EAAE,OACd,CAAC,KACL,KAAK,IAAI,cAAc,CAAC,CAAC,EAAE,CAAC,CAAwB,CAAC;AAExD;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,oBAAoB,GAC/B,CAAC,EACD,GAAG,SAAS,QAAQ,CAAC,MAAM,EAC3B,GAAG,SAAS,QAAQ,CAAC,MAAM,SAEpB,SAAS,CAAC,EAAE,OACd,GAAG,OACH,GAAG,KACP,KAAK,IAAI,kBAAkB,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,CACE,CAAC;AAE7C;;;;;;;;;;;;;;;;;;GAkBG;AAEH,wBAAgB,KAAK,CAAC,CAAC,EAAE,CAAC,SAAS,CAAC,EAClC,KAAK,EAAE,SAAS,CAAC,EAAE,EACnB,SAAS,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,QAAQ,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,GAC/C,KAAK,IAAI,SAAS,CAAC,EAAE,CAAC;AAEzB,wBAAgB,KAAK,CAAC,CAAC,EAAE,CAAC,SAAS,CAAC,EAClC,SAAS,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,QAAQ,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,GAC/C,CAAC,KAAK,EAAE,SAAS,CAAC,EAAE,KAAK,KAAK,IAAI,SAAS,CAAC,EAAE,CAAC;AAGlD,wBAAgB,KAAK,CAAC,KAAK,CAAC,EAAE,SAAS,SAAS,OAAO,EAAE,EACvD,KAAK,EAAE,EAAE,EACT,SAAS,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,UAAU,CAAC,EAAE,CAAC,KAAK,OAAO,GAC3D,OAAO,CAAC;AAEX,wBAAgB,KAAK,CAAC,CAAC,EACrB,SAAS,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,QAAQ,CAAC,GAAG,KAAK,OAAO,GAChD,CAAC,KAAK,EAAE,SAAS,CAAC,EAAE,KAAK,OAAO,CAAC;AAwBpC;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,IAAI,CAAC,KAAK,CAAC,EAAE,SAAS,SAAS,OAAO,EAAE,EACtD,KAAK,EAAE,EAAE,EACT,SAAS,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,UAAU,CAAC,EAAE,CAAC,KAAK,OAAO,GAC3D,OAAO,CAAC;AAEX,wBAAgB,IAAI,CAAC,CAAC,EACpB,SAAS,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,QAAQ,CAAC,GAAG,KAAK,OAAO,GAChD,CAAC,KAAK,EAAE,SAAS,CAAC,EAAE,KAAK,OAAO,CAAC;AAwBpC;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,cAAc,GAAI,CAAC,SACvB,SAAS,CAAC,EAAE,SACZ,QAAQ,CAAC,MAAM,KACrB,OAAgD,CAAC"}
1
+ {"version":3,"file":"array-utils-validation.d.mts","sourceRoot":"","sources":["../../../src/array/impl/array-utils-validation.mts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,MAAM,EAAE,KAAK,KAAK,EAAE,KAAK,SAAS,EAAE,MAAM,eAAe,CAAC;AAExE,OAAO,EAAE,KAAK,UAAU,EAAE,KAAK,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAEjE;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,OAAO,GAAI,CAAC,SAAU,CAAC,KAAG,KAAK,IAAI,WAAW,CAAC,CAAC,CACvC,CAAC;AAEvB,KAAK,WAAW,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,GAC7B,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,IAAI,GACzC,IAAI,CAAC,SAAS,OAAO,EAAE,EAAE,CAAC,CAAC,GAC3B,CAAC,SAAS,SAAS,OAAO,EAAE,GAC1B,CAAC,GACD,KAAK,GACT,KAAK,CAAC;AAEV,KAAK,IAAI,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;AAI1C;;;;;;;;;;;;;;;;;;GAkBG;AAEH,wBAAgB,KAAK,CAAC,CAAC,EAAE,CAAC,SAAS,CAAC,EAClC,KAAK,EAAE,SAAS,CAAC,EAAE,EACnB,SAAS,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,QAAQ,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,GAC/C,KAAK,IAAI,SAAS,CAAC,EAAE,CAAC;AAEzB,wBAAgB,KAAK,CAAC,CAAC,EAAE,CAAC,SAAS,CAAC,EAClC,SAAS,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,QAAQ,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,GAC/C,CAAC,KAAK,EAAE,SAAS,CAAC,EAAE,KAAK,KAAK,IAAI,SAAS,CAAC,EAAE,CAAC;AAGlD,wBAAgB,KAAK,CAAC,KAAK,CAAC,EAAE,SAAS,SAAS,OAAO,EAAE,EACvD,KAAK,EAAE,EAAE,EACT,SAAS,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,UAAU,CAAC,EAAE,CAAC,KAAK,OAAO,GAC3D,OAAO,CAAC;AAEX,wBAAgB,KAAK,CAAC,CAAC,EACrB,SAAS,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,QAAQ,CAAC,GAAG,KAAK,OAAO,GAChD,CAAC,KAAK,EAAE,SAAS,CAAC,EAAE,KAAK,OAAO,CAAC;AAwBpC;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,IAAI,CAAC,KAAK,CAAC,EAAE,SAAS,SAAS,OAAO,EAAE,EACtD,KAAK,EAAE,EAAE,EACT,SAAS,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,UAAU,CAAC,EAAE,CAAC,KAAK,OAAO,GAC3D,OAAO,CAAC;AAEX,wBAAgB,IAAI,CAAC,CAAC,EACpB,SAAS,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,QAAQ,CAAC,GAAG,KAAK,OAAO,GAChD,CAAC,KAAK,EAAE,SAAS,CAAC,EAAE,KAAK,OAAO,CAAC;AAwBpC;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,cAAc,GAAI,CAAC,SACvB,SAAS,CAAC,EAAE,SACZ,QAAQ,CAAC,MAAM,KACrB,OAAgD,CAAC"}
@@ -36,12 +36,6 @@ import { Num } from '../../number/num.mjs';
36
36
  import '../../number/refined-number-utils.mjs';
37
37
 
38
38
  const isArray = (value) => Array.isArray(value);
39
- const isEmpty = (array) => array.length === 0;
40
- const isNonEmpty = (array) => array.length > 0;
41
- const isFixedLengthTuple = (array, len) => array.length === len;
42
- const isMinLengthTuple = (array, len) => array.length >= len;
43
- const isMaxLengthTuple = (array, len) => array.length <= len;
44
- const isBoundedLengthTuple = (array, min, max) => array.length >= min && array.length <= max;
45
39
  function every(...args) {
46
40
  switch (args.length) {
47
41
  case 2:
@@ -62,5 +56,5 @@ function some(...args) {
62
56
  const someImpl = (array, predicate) => array.some((a, i) => predicate(a, asUint32(i)));
63
57
  const indexIsInRange = (array, index) => Num.isInRange(0, array.length)(index);
64
58
 
65
- export { every, indexIsInRange, isArray, isBoundedLengthTuple, isEmpty, isFixedLengthTuple, isMaxLengthTuple, isMinLengthTuple, isNonEmpty, some };
59
+ export { every, indexIsInRange, isArray, some };
66
60
  //# sourceMappingURL=array-utils-validation.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"array-utils-validation.mjs","sources":["../../../src/array/impl/array-utils-validation.mts"],"sourcesContent":["import {\n type BoolOr,\n type BoundedLengthTuple,\n type FixedLengthArray,\n type FixedLengthTuple,\n type MaxLengthTuple,\n type MinLengthArray,\n type MinLengthTuple,\n type TypeEq,\n} from 'ts-type-forge';\nimport { asUint32, Num } from '../../number/index.mjs';\nimport { type ArrayIndex, type SizeType } from '../../types.mjs';\n\n/**\n * Type guard that checks if a value is an array.\n *\n * @example\n *\n * ```ts\n * const maybeArray: unknown = [1, 2, 3] as const;\n *\n * const maybeValue: unknown = 'Ada';\n *\n * assert.isTrue(Arr.isArray(maybeArray));\n *\n * assert.isFalse(Arr.isArray(maybeValue));\n *\n * if (Arr.isArray(maybeArray)) {\n * assert.deepStrictEqual(maybeArray, [1, 2, 3]);\n * }\n * ```\n */\nexport const isArray = <E,>(value: E): value is FilterArray<E> =>\n Array.isArray(value);\n\ntype FilterArray<T> = T extends T\n ? // eslint-disable-next-line @typescript-eslint/no-explicit-any\n BoolOr<TypeEq<T, unknown>, TypeEq<T, any>> extends true\n ? Cast<readonly unknown[], T>\n : T extends readonly unknown[]\n ? T\n : never // Exclude non-array types\n : never;\n\ntype Cast<A, B> = A extends B ? A : never;\n\n// validation\n\n/**\n * Type guard that checks if an array is empty.\n *\n * @example\n *\n * ```ts\n * const emptyNumbers: readonly number[] = [] as const;\n *\n * const words = ['Ada', 'Lovelace'] as const;\n *\n * assert.isTrue(Arr.isEmpty(emptyNumbers));\n *\n * assert.isFalse(Arr.isEmpty(words));\n *\n * if (Arr.isEmpty(emptyNumbers)) {\n * // `isEmpty` narrows to the branded `FixedLengthArray<0, number>`, so the\n * // expected value is annotated with the unbranded type.\n * assert.deepStrictEqual<readonly number[]>(emptyNumbers, []);\n * }\n * ```\n */\nexport const isEmpty = <Xs extends readonly unknown[]>(\n array: Xs,\n): array is FixedLengthArray<0, Xs[number]> & Xs => array.length === 0;\n\n/**\n * Type guard that checks if an array is non-empty.\n *\n * @example\n *\n * ```ts\n * const users: readonly Readonly<{ id: number }>[] = [{ id: 1 }] as const;\n *\n * const emptyUsers: readonly Readonly<{ id: number }>[] = [] as const;\n *\n * assert.isTrue(Arr.isNonEmpty(users));\n *\n * assert.isFalse(Arr.isNonEmpty(emptyUsers));\n *\n * if (Arr.isNonEmpty(users)) {\n * assert.deepStrictEqual(users[0], { id: 1 });\n * }\n * ```\n */\nexport const isNonEmpty = <Xs extends readonly unknown[]>(\n array: Xs,\n): array is MinLengthArray<1, Xs[number]> & Xs => array.length > 0;\n\n/**\n * Checks if an array has a specific length.\n *\n * @example\n *\n * ```ts\n * const pair: readonly number[] = [1, 2] as const;\n *\n * const triple: readonly number[] = [1, 2, 3] as const;\n *\n * assert.isTrue(Arr.isFixedLengthTuple(pair, 2));\n *\n * assert.isFalse(Arr.isFixedLengthTuple(triple, 2));\n *\n * if (Arr.isFixedLengthTuple(pair, 2)) {\n * assert.deepStrictEqual(pair, [1, 2]);\n * }\n * ```\n */\nexport const isFixedLengthTuple = <E, N extends SizeType.ArgArr>(\n array: readonly E[],\n len: N,\n): array is FixedLengthTuple<N, E> => array.length === len;\n\n/**\n * Checks if an array has at least a specific length.\n *\n * @example\n *\n * ```ts\n * const queue: readonly string[] = ['task-1', 'task-2'] as const;\n *\n * const emptyQueue: readonly string[] = [] as const;\n *\n * assert.isTrue(Arr.isMinLengthTuple(queue, 1));\n *\n * assert.isFalse(Arr.isMinLengthTuple(emptyQueue, 1));\n *\n * if (Arr.isMinLengthTuple(queue, 1)) {\n * assert.isTrue(queue[0] === 'task-1');\n * }\n * ```\n */\nexport const isMinLengthTuple = <E, N extends SizeType.ArgArr>(\n array: readonly E[],\n len: N,\n): array is MinLengthTuple<N, E> => array.length >= len;\n\n/**\n * Checks if an array has at most a specific length.\n *\n * @example\n *\n * ```ts\n * const pair: readonly number[] = [1, 2] as const;\n *\n * const triple: readonly number[] = [1, 2, 3] as const;\n *\n * assert.isTrue(Arr.isMaxLengthTuple(pair, 2));\n *\n * assert.isFalse(Arr.isMaxLengthTuple(triple, 2));\n *\n * if (Arr.isMaxLengthTuple(pair, 2)) {\n * assert.isTrue(pair.length <= 2);\n * }\n * ```\n */\nexport const isMaxLengthTuple = <E, N extends SizeType.ArgArr>(\n array: readonly E[],\n len: N,\n): array is MaxLengthTuple<N, E> => array.length <= len;\n\n/**\n * Checks if an array's length is within a specific inclusive range.\n *\n * @example\n *\n * ```ts\n * const pair: readonly number[] = [1, 2] as const;\n *\n * const quad: readonly number[] = [1, 2, 3, 4] as const;\n *\n * assert.isTrue(Arr.isBoundedLengthTuple(pair, 1, 3));\n *\n * assert.isFalse(Arr.isBoundedLengthTuple(quad, 1, 3));\n *\n * if (Arr.isBoundedLengthTuple(pair, 1, 3)) {\n * assert.isTrue(pair.length >= 1 && pair.length <= 3);\n * }\n * ```\n */\nexport const isBoundedLengthTuple = <\n E,\n Min extends SizeType.ArgArr,\n Max extends SizeType.ArgArr,\n>(\n array: readonly E[],\n min: Min,\n max: Max,\n): array is BoundedLengthTuple<Min, Max, E> =>\n array.length >= min && array.length <= max;\n\n/**\n * Tests whether all elements in an array pass a test implemented by a predicate.\n *\n * @example\n *\n * ```ts\n * const numbers = [2, 4, 6] as const;\n *\n * const words = ['Ada', 'Grace'] as const;\n *\n * const allEven = Arr.every(numbers, (value) => value % 2 === 0);\n *\n * const allStartWithA = Arr.every(words, (value) => value.startsWith('A'));\n *\n * assert.isTrue(allEven);\n *\n * assert.isFalse(allStartWithA);\n * ```\n */\n// Type guard overloads - narrow the entire array type\nexport function every<E, S extends E>(\n array: readonly E[],\n predicate: (a: E, index: SizeType.Arr) => a is S,\n): array is readonly S[];\n\nexport function every<E, S extends E>(\n predicate: (a: E, index: SizeType.Arr) => a is S,\n): (array: readonly E[]) => array is readonly S[];\n\n// Regular boolean predicate overloads\nexport function every<const Ar extends readonly unknown[]>(\n array: Ar,\n predicate: (a: Ar[number], index: ArrayIndex<Ar>) => boolean,\n): boolean;\n\nexport function every<E>(\n predicate: (a: E, index: SizeType.Arr) => boolean,\n): (array: readonly E[]) => boolean;\n\nexport function every<E>(\n ...args:\n | readonly [\n array: readonly E[],\n predicate: (a: E, index: SizeType.Arr) => boolean,\n ]\n | readonly [predicate: (a: E, index: SizeType.Arr) => boolean]\n): boolean | ((array: readonly E[]) => boolean) {\n switch (args.length) {\n case 2:\n return everyImpl(...args);\n\n case 1:\n return (array) => everyImpl(array, ...args);\n }\n}\n\nconst everyImpl = <E,>(\n array: readonly E[],\n predicate: (a: E, index: SizeType.Arr) => boolean,\n): boolean => array.every((a, i) => predicate(a, asUint32(i)));\n\n/**\n * Tests whether at least one element in an array passes a test implemented by a predicate.\n *\n * @example\n *\n * ```ts\n * const numbers = [1, 3, 5] as const;\n *\n * const words = ['Ada', 'Grace'] as const;\n *\n * const hasEven = Arr.some(numbers, (value) => value % 2 === 0);\n *\n * const hasShortName = Arr.some(words, (value) => value.length <= 3);\n *\n * assert.isFalse(hasEven);\n *\n * assert.isTrue(hasShortName);\n * ```\n */\nexport function some<const Ar extends readonly unknown[]>(\n array: Ar,\n predicate: (a: Ar[number], index: ArrayIndex<Ar>) => boolean,\n): boolean;\n\nexport function some<E>(\n predicate: (a: E, index: SizeType.Arr) => boolean,\n): (array: readonly E[]) => boolean;\n\nexport function some<E>(\n ...args:\n | readonly [\n array: readonly E[],\n predicate: (a: E, index: SizeType.Arr) => boolean,\n ]\n | readonly [predicate: (a: E, index: SizeType.Arr) => boolean]\n): boolean | ((array: readonly E[]) => boolean) {\n switch (args.length) {\n case 2:\n return someImpl(...args);\n\n case 1:\n return (array) => someImpl(array, ...args);\n }\n}\n\nconst someImpl = <E,>(\n array: readonly E[],\n predicate: (a: E, index: SizeType.Arr) => boolean,\n): boolean => array.some((a, i) => predicate(a, asUint32(i)));\n\n/**\n * Checks if an index is within the valid range of an array.\n *\n * @example\n *\n * ```ts\n * const items = ['Ada', 'Grace', 'Katherine'] as const;\n *\n * assert.isTrue(Arr.indexIsInRange(items, 1));\n *\n * assert.isFalse(Arr.indexIsInRange(items, 3));\n *\n * if (Arr.indexIsInRange(items, 2)) {\n * assert.isTrue(items[2] === 'Katherine');\n * }\n * ```\n */\nexport const indexIsInRange = <E,>(\n array: readonly E[],\n index: SizeType.ArgArr,\n): boolean => Num.isInRange(0, array.length)(index);\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgCO,MAAM,OAAA,GAAU,CAAK,KAAA,KAC1B,KAAA,CAAM,QAAQ,KAAK;AAoCd,MAAM,OAAA,GAAU,CACrB,KAAA,KACkD,KAAA,CAAM,MAAA,KAAW;AAqB9D,MAAM,UAAA,GAAa,CACxB,KAAA,KACgD,KAAA,CAAM,MAAA,GAAS;AAqB1D,MAAM,kBAAA,GAAqB,CAChC,KAAA,EACA,GAAA,KACoC,MAAM,MAAA,KAAW;AAqBhD,MAAM,gBAAA,GAAmB,CAC9B,KAAA,EACA,GAAA,KACkC,MAAM,MAAA,IAAU;AAqB7C,MAAM,gBAAA,GAAmB,CAC9B,KAAA,EACA,GAAA,KACkC,MAAM,MAAA,IAAU;AAqB7C,MAAM,oBAAA,GAAuB,CAKlC,KAAA,EACA,GAAA,EACA,QAEA,KAAA,CAAM,MAAA,IAAU,GAAA,IAAO,KAAA,CAAM,MAAA,IAAU;AAyClC,SAAS,SACX,IAAA,EAM2C;AAC9C,EAAA,QAAQ,KAAK,MAAA;AAAQ,IACnB,KAAK,CAAA;AACH,MAAA,OAAO,SAAA,CAAU,GAAG,IAAI,CAAA;AAAA,IAE1B,KAAK,CAAA;AACH,MAAA,OAAO,CAAC,KAAA,KAAU,SAAA,CAAU,KAAA,EAAO,GAAG,IAAI,CAAA;AAAA;AAEhD;AAEA,MAAM,SAAA,GAAY,CAChB,KAAA,EACA,SAAA,KACY,MAAM,KAAA,CAAM,CAAC,CAAA,EAAG,CAAA,KAAM,SAAA,CAAU,CAAA,EAAG,QAAA,CAAS,CAAC,CAAC,CAAC,CAAA;AA8BtD,SAAS,QACX,IAAA,EAM2C;AAC9C,EAAA,QAAQ,KAAK,MAAA;AAAQ,IACnB,KAAK,CAAA;AACH,MAAA,OAAO,QAAA,CAAS,GAAG,IAAI,CAAA;AAAA,IAEzB,KAAK,CAAA;AACH,MAAA,OAAO,CAAC,KAAA,KAAU,QAAA,CAAS,KAAA,EAAO,GAAG,IAAI,CAAA;AAAA;AAE/C;AAEA,MAAM,QAAA,GAAW,CACf,KAAA,EACA,SAAA,KACY,MAAM,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAM,SAAA,CAAU,CAAA,EAAG,QAAA,CAAS,CAAC,CAAC,CAAC,CAAA;AAmBrD,MAAM,cAAA,GAAiB,CAC5B,KAAA,EACA,KAAA,KACY,GAAA,CAAI,UAAU,CAAA,EAAG,KAAA,CAAM,MAAM,CAAA,CAAE,KAAK;;;;"}
1
+ {"version":3,"file":"array-utils-validation.mjs","sources":["../../../src/array/impl/array-utils-validation.mts"],"sourcesContent":["import { type BoolOr, type IsAny, type IsUnknown } from 'ts-type-forge';\nimport { asUint32, Num } from '../../number/index.mjs';\nimport { type ArrayIndex, type SizeType } from '../../types.mjs';\n\n/**\n * Type guard that checks if a value is an array.\n *\n * @example\n *\n * ```ts\n * const maybeArray: unknown = [1, 2, 3] as const;\n *\n * const maybeValue: unknown = 'Ada';\n *\n * assert.isTrue(Arr.isArray(maybeArray));\n *\n * assert.isFalse(Arr.isArray(maybeValue));\n *\n * if (Arr.isArray(maybeArray)) {\n * assert.deepStrictEqual(maybeArray, [1, 2, 3]);\n * }\n * ```\n */\nexport const isArray = <E,>(value: E): value is FilterArray<E> =>\n Array.isArray(value);\n\ntype FilterArray<T> = T extends T\n ? BoolOr<IsUnknown<T>, IsAny<T>> extends true\n ? Cast<readonly unknown[], T>\n : T extends readonly unknown[]\n ? T\n : never // Exclude non-array types\n : never;\n\ntype Cast<A, B> = A extends B ? A : never;\n\n// validation\n\n/**\n * Tests whether all elements in an array pass a test implemented by a predicate.\n *\n * @example\n *\n * ```ts\n * const numbers = [2, 4, 6] as const;\n *\n * const words = ['Ada', 'Grace'] as const;\n *\n * const allEven = Arr.every(numbers, (value) => value % 2 === 0);\n *\n * const allStartWithA = Arr.every(words, (value) => value.startsWith('A'));\n *\n * assert.isTrue(allEven);\n *\n * assert.isFalse(allStartWithA);\n * ```\n */\n// Type guard overloads - narrow the entire array type\nexport function every<E, S extends E>(\n array: readonly E[],\n predicate: (a: E, index: SizeType.Arr) => a is S,\n): array is readonly S[];\n\nexport function every<E, S extends E>(\n predicate: (a: E, index: SizeType.Arr) => a is S,\n): (array: readonly E[]) => array is readonly S[];\n\n// Regular boolean predicate overloads\nexport function every<const Ar extends readonly unknown[]>(\n array: Ar,\n predicate: (a: Ar[number], index: ArrayIndex<Ar>) => boolean,\n): boolean;\n\nexport function every<E>(\n predicate: (a: E, index: SizeType.Arr) => boolean,\n): (array: readonly E[]) => boolean;\n\nexport function every<E>(\n ...args:\n | readonly [\n array: readonly E[],\n predicate: (a: E, index: SizeType.Arr) => boolean,\n ]\n | readonly [predicate: (a: E, index: SizeType.Arr) => boolean]\n): boolean | ((array: readonly E[]) => boolean) {\n switch (args.length) {\n case 2:\n return everyImpl(...args);\n\n case 1:\n return (array) => everyImpl(array, ...args);\n }\n}\n\nconst everyImpl = <E,>(\n array: readonly E[],\n predicate: (a: E, index: SizeType.Arr) => boolean,\n): boolean => array.every((a, i) => predicate(a, asUint32(i)));\n\n/**\n * Tests whether at least one element in an array passes a test implemented by a predicate.\n *\n * @example\n *\n * ```ts\n * const numbers = [1, 3, 5] as const;\n *\n * const words = ['Ada', 'Grace'] as const;\n *\n * const hasEven = Arr.some(numbers, (value) => value % 2 === 0);\n *\n * const hasShortName = Arr.some(words, (value) => value.length <= 3);\n *\n * assert.isFalse(hasEven);\n *\n * assert.isTrue(hasShortName);\n * ```\n */\nexport function some<const Ar extends readonly unknown[]>(\n array: Ar,\n predicate: (a: Ar[number], index: ArrayIndex<Ar>) => boolean,\n): boolean;\n\nexport function some<E>(\n predicate: (a: E, index: SizeType.Arr) => boolean,\n): (array: readonly E[]) => boolean;\n\nexport function some<E>(\n ...args:\n | readonly [\n array: readonly E[],\n predicate: (a: E, index: SizeType.Arr) => boolean,\n ]\n | readonly [predicate: (a: E, index: SizeType.Arr) => boolean]\n): boolean | ((array: readonly E[]) => boolean) {\n switch (args.length) {\n case 2:\n return someImpl(...args);\n\n case 1:\n return (array) => someImpl(array, ...args);\n }\n}\n\nconst someImpl = <E,>(\n array: readonly E[],\n predicate: (a: E, index: SizeType.Arr) => boolean,\n): boolean => array.some((a, i) => predicate(a, asUint32(i)));\n\n/**\n * Checks if an index is within the valid range of an array.\n *\n * @example\n *\n * ```ts\n * const items = ['Ada', 'Grace', 'Katherine'] as const;\n *\n * assert.isTrue(Arr.indexIsInRange(items, 1));\n *\n * assert.isFalse(Arr.indexIsInRange(items, 3));\n *\n * if (Arr.indexIsInRange(items, 2)) {\n * assert.isTrue(items[2] === 'Katherine');\n * }\n * ```\n */\nexport const indexIsInRange = <E,>(\n array: readonly E[],\n index: SizeType.ArgArr,\n): boolean => Num.isInRange(0, array.length)(index);\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAuBO,MAAM,OAAA,GAAU,CAAK,KAAA,KAC1B,KAAA,CAAM,QAAQ,KAAK;AAqDd,SAAS,SACX,IAAA,EAM2C;AAC9C,EAAA,QAAQ,KAAK,MAAA;AAAQ,IACnB,KAAK,CAAA;AACH,MAAA,OAAO,SAAA,CAAU,GAAG,IAAI,CAAA;AAAA,IAE1B,KAAK,CAAA;AACH,MAAA,OAAO,CAAC,KAAA,KAAU,SAAA,CAAU,KAAA,EAAO,GAAG,IAAI,CAAA;AAAA;AAEhD;AAEA,MAAM,SAAA,GAAY,CAChB,KAAA,EACA,SAAA,KACY,MAAM,KAAA,CAAM,CAAC,CAAA,EAAG,CAAA,KAAM,SAAA,CAAU,CAAA,EAAG,QAAA,CAAS,CAAC,CAAC,CAAC,CAAA;AA8BtD,SAAS,QACX,IAAA,EAM2C;AAC9C,EAAA,QAAQ,KAAK,MAAA;AAAQ,IACnB,KAAK,CAAA;AACH,MAAA,OAAO,QAAA,CAAS,GAAG,IAAI,CAAA;AAAA,IAEzB,KAAK,CAAA;AACH,MAAA,OAAO,CAAC,KAAA,KAAU,QAAA,CAAS,KAAA,EAAO,GAAG,IAAI,CAAA;AAAA;AAE/C;AAEA,MAAM,QAAA,GAAW,CACf,KAAA,EACA,SAAA,KACY,MAAM,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAM,SAAA,CAAU,CAAA,EAAG,QAAA,CAAS,CAAC,CAAC,CAAC,CAAA;AAmBrD,MAAM,cAAA,GAAiB,CAC5B,KAAA,EACA,KAAA,KACY,GAAA,CAAI,UAAU,CAAA,EAAG,KAAA,CAAM,MAAM,CAAA,CAAE,KAAK;;;;"}
@@ -3,6 +3,8 @@ export * from './array-utils-element-access.mjs';
3
3
  export * from './array-utils-iterators.mjs';
4
4
  export * from './array-utils-length-bounded-array-cast.mjs';
5
5
  export * from './array-utils-length-bounded-array-guard.mjs';
6
+ export * from './array-utils-length-bounded-tuple-cast.mjs';
7
+ export * from './array-utils-length-bounded-tuple-guard.mjs';
6
8
  export * from './array-utils-modification.mjs';
7
9
  export * from './array-utils-reducing-value.mjs';
8
10
  export * from './array-utils-search.mjs';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","sourceRoot":"","sources":["../../../src/array/impl/index.mts"],"names":[],"mappings":"AAAA,cAAc,4BAA4B,CAAC;AAC3C,cAAc,kCAAkC,CAAC;AACjD,cAAc,6BAA6B,CAAC;AAC5C,cAAc,6CAA6C,CAAC;AAC5D,cAAc,8CAA8C,CAAC;AAC7D,cAAc,gCAAgC,CAAC;AAC/C,cAAc,kCAAkC,CAAC;AACjD,cAAc,0BAA0B,CAAC;AACzC,cAAc,0BAA0B,CAAC;AACzC,cAAc,wBAAwB,CAAC;AACvC,cAAc,iCAAiC,CAAC;AAChD,cAAc,2BAA2B,CAAC;AAC1C,cAAc,kCAAkC,CAAC;AACjD,cAAc,8BAA8B,CAAC"}
1
+ {"version":3,"file":"index.d.mts","sourceRoot":"","sources":["../../../src/array/impl/index.mts"],"names":[],"mappings":"AAAA,cAAc,4BAA4B,CAAC;AAC3C,cAAc,kCAAkC,CAAC;AACjD,cAAc,6BAA6B,CAAC;AAC5C,cAAc,6CAA6C,CAAC;AAC5D,cAAc,8CAA8C,CAAC;AAC7D,cAAc,6CAA6C,CAAC;AAC5D,cAAc,8CAA8C,CAAC;AAC7D,cAAc,gCAAgC,CAAC;AAC/C,cAAc,kCAAkC,CAAC;AACjD,cAAc,0BAA0B,CAAC;AACzC,cAAc,0BAA0B,CAAC;AACzC,cAAc,wBAAwB,CAAC;AACvC,cAAc,iCAAiC,CAAC;AAChD,cAAc,2BAA2B,CAAC;AAC1C,cAAc,kCAAkC,CAAC;AACjD,cAAc,8BAA8B,CAAC"}
@@ -1,8 +1,10 @@
1
1
  export { copy, create, generate, generateAsync, newArray, range, seq, zeros } from './array-utils-creation.mjs';
2
2
  export { at, first, head, last } from './array-utils-element-access.mjs';
3
3
  export { entries, indices, keys, values } from './array-utils-iterators.mjs';
4
- export { asBoundedLengthArray, asFixedLengthArray, asMaxLengthArray, asMinLengthArray, asNonEmptyArray } from './array-utils-length-bounded-array-cast.mjs';
5
- export { isBoundedLengthArray, isFixedLengthArray, isMaxLengthArray, isMinLengthArray } from './array-utils-length-bounded-array-guard.mjs';
4
+ export { asBoundedLengthArray, asEmptyArray, asFixedLengthArray, asMaxLengthArray, asMinLengthArray, asNonEmptyArray } from './array-utils-length-bounded-array-cast.mjs';
5
+ export { isBoundedLengthArray, isEmpty, isFixedLengthArray, isMaxLengthArray, isMinLengthArray, isNonEmpty } from './array-utils-length-bounded-array-guard.mjs';
6
+ export { asBoundedLengthTuple, asEmptyTuple, asFixedLengthTuple, asMaxLengthTuple, asMinLengthTuple, asNonEmptyTuple } from './array-utils-length-bounded-tuple-cast.mjs';
7
+ export { isBoundedLengthTuple, isEmptyTuple, isFixedLengthTuple, isMaxLengthTuple, isMinLengthTuple, isNonEmptyTuple } from './array-utils-length-bounded-tuple-guard.mjs';
6
8
  export { set, toFilled, toInserted, toPushed, toRangeFilled, toRemoved, toUnshifted, toUpdated } from './array-utils-modification.mjs';
7
9
  export { count, countBy, foldl, foldr, join, max, maxBy, min, minBy, reduce, reduceRight, sum, sumBy } from './array-utils-reducing-value.mjs';
8
10
  export { find, findIndex, findLast, findLastIndex, indexOf, indexOfFrom, lastIndexOf, lastIndexOfFrom } from './array-utils-search.mjs';
@@ -11,5 +13,5 @@ export { length, size } from './array-utils-size.mjs';
11
13
  export { sliceClamped } from './array-utils-slice-clamped.mjs';
12
14
  export { butLast, drop, rest, skip, skipLast, tail, take, takeLast } from './array-utils-slicing.mjs';
13
15
  export { cartesianProduct, chunk, concat, filter, filterNot, flat, flatMap, groupBy, map, partition, scan, toReversed, toSorted, toSortedBy, uniq, uniqBy, zip } from './array-utils-transformation.mjs';
14
- export { every, indexIsInRange, isArray, isBoundedLengthTuple, isEmpty, isFixedLengthTuple, isMaxLengthTuple, isMinLengthTuple, isNonEmpty, some } from './array-utils-validation.mjs';
16
+ export { every, indexIsInRange, isArray, some } from './array-utils-validation.mjs';
15
17
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;"}
@@ -512,7 +512,7 @@ type IMapInterface<K extends MapSetKeyType, V> = Readonly<{
512
512
  * const entries = [
513
513
  * ['k1', 'v1'],
514
514
  * ['k2', 'v2'],
515
- * ] as const satisfies readonly (readonly [string, string])[];
515
+ * ] as const satisfies readonly FixedLengthTuple<2, string>[];
516
516
  *
517
517
  * const map = IMap.create(entries);
518
518
  *
@@ -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<readonly [K, K]>;
753
+ entries: () => IterableIterator<FixedLengthTuple<2, K>>;
754
754
  /**
755
755
  * Converts the elements of the set to an array.
756
756
  *