@vielzeug/arsenal 2.0.1 → 2.1.0

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 (113) hide show
  1. package/dist/array/chunk.cjs.map +1 -1
  2. package/dist/array/chunk.js.map +1 -1
  3. package/dist/array/countBy.cjs.map +1 -1
  4. package/dist/array/countBy.d.ts.map +1 -1
  5. package/dist/array/countBy.js.map +1 -1
  6. package/dist/array/difference.cjs.map +1 -1
  7. package/dist/array/difference.d.ts.map +1 -1
  8. package/dist/array/difference.js.map +1 -1
  9. package/dist/array/groupBy.cjs.map +1 -1
  10. package/dist/array/groupBy.d.ts.map +1 -1
  11. package/dist/array/groupBy.js.map +1 -1
  12. package/dist/array/indexBy.cjs.map +1 -1
  13. package/dist/array/indexBy.d.ts.map +1 -1
  14. package/dist/array/indexBy.js.map +1 -1
  15. package/dist/array/intersection.cjs.map +1 -1
  16. package/dist/array/intersection.d.ts.map +1 -1
  17. package/dist/array/intersection.js.map +1 -1
  18. package/dist/array/union.cjs.map +1 -1
  19. package/dist/array/union.d.ts.map +1 -1
  20. package/dist/array/union.js.map +1 -1
  21. package/dist/array/uniq.cjs.map +1 -1
  22. package/dist/array/uniq.d.ts.map +1 -1
  23. package/dist/array/uniq.js.map +1 -1
  24. package/dist/arsenal.cjs +1 -1
  25. package/dist/arsenal.cjs.map +1 -1
  26. package/dist/arsenal.iife.js +1 -1
  27. package/dist/arsenal.iife.js.map +1 -1
  28. package/dist/arsenal.js +1 -1
  29. package/dist/arsenal.js.map +1 -1
  30. package/dist/async/abortable.cjs +2 -0
  31. package/dist/async/abortable.cjs.map +1 -0
  32. package/dist/async/abortable.d.ts +26 -0
  33. package/dist/async/abortable.d.ts.map +1 -0
  34. package/dist/async/abortable.js +12 -0
  35. package/dist/async/abortable.js.map +1 -0
  36. package/dist/async/backoff.cjs +1 -1
  37. package/dist/async/backoff.cjs.map +1 -1
  38. package/dist/async/backoff.js +1 -2
  39. package/dist/async/backoff.js.map +1 -1
  40. package/dist/async/index.cjs +1 -1
  41. package/dist/async/index.d.ts +1 -0
  42. package/dist/async/index.d.ts.map +1 -1
  43. package/dist/async/index.js +9 -8
  44. package/dist/async/taskPool.cjs.map +1 -1
  45. package/dist/async/taskPool.d.ts +4 -4
  46. package/dist/async/taskPool.d.ts.map +1 -1
  47. package/dist/async/taskPool.js.map +1 -1
  48. package/dist/cache/cache.cjs +1 -1
  49. package/dist/cache/cache.cjs.map +1 -1
  50. package/dist/cache/cache.d.ts.map +1 -1
  51. package/dist/cache/cache.js +1 -1
  52. package/dist/cache/cache.js.map +1 -1
  53. package/dist/cache/memo.cjs.map +1 -1
  54. package/dist/cache/memo.d.ts.map +1 -1
  55. package/dist/cache/memo.js.map +1 -1
  56. package/dist/errors.cjs +1 -1
  57. package/dist/errors.cjs.map +1 -1
  58. package/dist/errors.d.ts +0 -1
  59. package/dist/errors.d.ts.map +1 -1
  60. package/dist/errors.js +1 -4
  61. package/dist/errors.js.map +1 -1
  62. package/dist/function/debounce.cjs.map +1 -1
  63. package/dist/function/debounce.d.ts.map +1 -1
  64. package/dist/function/debounce.js.map +1 -1
  65. package/dist/function/pipe.cjs +1 -1
  66. package/dist/function/pipe.cjs.map +1 -1
  67. package/dist/function/pipe.js +1 -1
  68. package/dist/function/pipe.js.map +1 -1
  69. package/dist/function/runAll.cjs +1 -1
  70. package/dist/function/runAll.cjs.map +1 -1
  71. package/dist/function/runAll.js +1 -1
  72. package/dist/function/runAll.js.map +1 -1
  73. package/dist/index.d.ts +1 -1
  74. package/dist/index.d.ts.map +1 -1
  75. package/dist/object/defaults.cjs.map +1 -1
  76. package/dist/object/defaults.d.ts.map +1 -1
  77. package/dist/object/defaults.js.map +1 -1
  78. package/dist/object/diff.cjs.map +1 -1
  79. package/dist/object/diff.d.ts.map +1 -1
  80. package/dist/object/diff.js.map +1 -1
  81. package/dist/object/filterValues.cjs.map +1 -1
  82. package/dist/object/filterValues.d.ts.map +1 -1
  83. package/dist/object/filterValues.js.map +1 -1
  84. package/dist/object/getPath.cjs.map +1 -1
  85. package/dist/object/getPath.d.ts.map +1 -1
  86. package/dist/object/getPath.js.map +1 -1
  87. package/dist/object/mapKeys.cjs.map +1 -1
  88. package/dist/object/mapKeys.d.ts.map +1 -1
  89. package/dist/object/mapKeys.js.map +1 -1
  90. package/dist/object/mapValues.cjs.map +1 -1
  91. package/dist/object/mapValues.d.ts.map +1 -1
  92. package/dist/object/mapValues.js.map +1 -1
  93. package/dist/object/merge.cjs.map +1 -1
  94. package/dist/object/merge.d.ts.map +1 -1
  95. package/dist/object/merge.js.map +1 -1
  96. package/dist/object/omit.cjs.map +1 -1
  97. package/dist/object/omit.d.ts.map +1 -1
  98. package/dist/object/omit.js.map +1 -1
  99. package/dist/object/pick.cjs.map +1 -1
  100. package/dist/object/pick.d.ts.map +1 -1
  101. package/dist/object/pick.js.map +1 -1
  102. package/dist/random/draw.cjs.map +1 -1
  103. package/dist/random/draw.d.ts.map +1 -1
  104. package/dist/random/draw.js.map +1 -1
  105. package/dist/random/random.cjs.map +1 -1
  106. package/dist/random/random.d.ts.map +1 -1
  107. package/dist/random/random.js.map +1 -1
  108. package/dist/random/shuffle.cjs.map +1 -1
  109. package/dist/random/shuffle.d.ts.map +1 -1
  110. package/dist/random/shuffle.js.map +1 -1
  111. package/package.json +32 -27
  112. package/dist/_common/_abortable.d.ts +0 -5
  113. package/dist/_common/_abortable.d.ts.map +0 -1
@@ -49,7 +49,7 @@ function e({ capacity: e = Infinity, now: t = Date.now, ttlMs: n } = {}) {
49
49
  },
50
50
  set: d,
51
51
  get size() {
52
- return u(), r.size;
52
+ return r.size;
53
53
  }
54
54
  };
55
55
  }
@@ -1 +1 @@
1
- {"version":3,"file":"cache.js","names":[],"sources":["../../src/cache/cache.ts"],"sourcesContent":["export type CacheOptions = {\n capacity?: number;\n now?: () => number;\n ttlMs?: number;\n};\n\ntype Entry<T> = {\n expiresAt: number | undefined;\n value: T;\n};\n\nexport interface Cache<K, T> {\n clear(): void;\n delete(key: K): boolean;\n get(key: K): T | undefined;\n getOrLoad(key: K, load: () => Promise<T>): Promise<T>;\n set(key: K, value: T, options?: { ttlMs?: number }): void;\n readonly size: number;\n}\n\nexport function cache<K, T>({ capacity = Infinity, now = Date.now, ttlMs }: CacheOptions = {}): Cache<K, T> {\n if (capacity !== Infinity && (!Number.isInteger(capacity) || capacity < 1)) {\n throw new RangeError(`cache: capacity must be a positive integer or Infinity, got ${capacity}`);\n }\n\n const entries = new Map<K, Entry<T>>();\n const pending = new Map<K, Promise<T>>();\n const revisions = new Map<K, number>();\n let generation = 0;\n\n const advanceRevision = (key: K): number => {\n const revision = (revisions.get(key) ?? 0) + 1;\n\n revisions.set(key, revision);\n\n return revision;\n };\n\n const expiresAt = (duration: number | undefined): number | undefined => {\n if (duration === undefined || duration === Infinity) return undefined;\n\n if (!Number.isFinite(duration) || duration < 0) {\n throw new RangeError(`cache: ttlMs must be a non-negative finite number or Infinity, got ${duration}`);\n }\n\n return now() + duration;\n };\n\n const read = (key: K): T | undefined => {\n const entry = entries.get(key);\n\n if (!entry) return undefined;\n\n if (entry.expiresAt !== undefined && entry.expiresAt <= now()) {\n entries.delete(key);\n\n return undefined;\n }\n\n return entry.value;\n };\n\n const trim = (): void => {\n for (const [key, entry] of entries) {\n if (entry.expiresAt !== undefined && entry.expiresAt <= now()) entries.delete(key);\n }\n\n while (entries.size > capacity) {\n const oldest = entries.keys().next().value;\n\n if (oldest === undefined) return;\n\n entries.delete(oldest);\n }\n };\n\n const set = (key: K, value: T, options: { ttlMs?: number } = {}): void => {\n advanceRevision(key);\n entries.delete(key);\n entries.set(key, { expiresAt: expiresAt(options.ttlMs ?? ttlMs), value });\n trim();\n };\n\n const getOrLoad = (key: K, load: () => Promise<T>): Promise<T> => {\n const cached = read(key);\n\n if (cached !== undefined || entries.has(key)) return Promise.resolve(cached as T);\n\n const existing = pending.get(key);\n\n if (existing) return existing;\n\n const capturedGeneration = generation;\n const capturedRevision = advanceRevision(key);\n const result = load().then(\n (value) => {\n if (pending.get(key) === result) pending.delete(key);\n\n if (generation === capturedGeneration && revisions.get(key) === capturedRevision) {\n set(key, value);\n }\n\n return value;\n },\n (error: unknown) => {\n if (pending.get(key) === result) pending.delete(key);\n\n throw error;\n },\n );\n\n pending.set(key, result);\n\n return result;\n };\n\n return {\n clear: () => {\n generation++;\n entries.clear();\n pending.clear();\n revisions.clear();\n },\n delete: (key) => {\n pending.delete(key);\n advanceRevision(key);\n\n return entries.delete(key);\n },\n get: read,\n getOrLoad,\n set,\n get size() {\n trim();\n\n return entries.size;\n },\n };\n}\n"],"mappings":";AAoBA,SAAgB,EAAY,EAAE,cAAW,UAAU,SAAM,KAAK,KAAK,aAAwB,CAAC,GAAgB;CAC1G,IAAI,MAAa,aAAa,CAAC,OAAO,UAAU,CAAQ,KAAK,IAAW,IACtE,MAAU,WAAW,+DAA+D,GAAU;CAGhG,IAAM,oBAAU,IAAI,IAAiB,GAC/B,oBAAU,IAAI,IAAmB,GACjC,oBAAY,IAAI,IAAe,GACjC,IAAa,GAEX,KAAmB,MAAmB;EAC1C,IAAM,KAAY,EAAU,IAAI,CAAG,KAAK,KAAK;EAI7C,OAFA,EAAU,IAAI,GAAK,CAAQ,GAEpB;CACT,GAEM,KAAa,MAAqD;EAClE,UAAa,KAAA,KAAa,MAAa,UAE3C;OAAI,CAAC,OAAO,SAAS,CAAQ,KAAK,IAAW,GAC3C,MAAU,WAAW,sEAAsE,GAAU;GAGvG,OAAO,EAAI,IAAI;EAHwF;CAIzG,GAEM,KAAQ,MAA0B;EACtC,IAAM,IAAQ,EAAQ,IAAI,CAAG;EAExB,OAEL;OAAI,EAAM,cAAc,KAAA,KAAa,EAAM,aAAa,EAAI,GAAG;IAC7D,EAAQ,OAAO,CAAG;IAElB;GACF;GAEA,OAAO,EAAM;EAFb;CAGF,GAEM,UAAmB;EACvB,KAAK,IAAM,CAAC,GAAK,MAAU,GACzB,AAAI,EAAM,cAAc,KAAA,KAAa,EAAM,aAAa,EAAI,KAAG,EAAQ,OAAO,CAAG;EAGnF,OAAO,EAAQ,OAAO,IAAU;GAC9B,IAAM,IAAS,EAAQ,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC;GAErC,IAAI,MAAW,KAAA,GAAW;GAE1B,EAAQ,OAAO,CAAM;EACvB;CACF,GAEM,KAAO,GAAQ,GAAU,IAA8B,CAAC,MAAY;EAIxE,AAHA,EAAgB,CAAG,GACnB,EAAQ,OAAO,CAAG,GAClB,EAAQ,IAAI,GAAK;GAAE,WAAW,EAAU,EAAQ,SAAS,CAAK;GAAG;EAAM,CAAC,GACxE,EAAK;CACP;CAmCA,OAAO;EACL,aAAa;GAIX,AAHA,KACA,EAAQ,MAAM,GACd,EAAQ,MAAM,GACd,EAAU,MAAM;EAClB;EACA,SAAS,OACP,EAAQ,OAAO,CAAG,GAClB,EAAgB,CAAG,GAEZ,EAAQ,OAAO,CAAG;EAE3B,KAAK;EACL,YA/CiB,GAAQ,MAAuC;GAChE,IAAM,IAAS,EAAK,CAAG;GAEvB,IAAI,MAAW,KAAA,KAAa,EAAQ,IAAI,CAAG,GAAG,OAAO,QAAQ,QAAQ,CAAW;GAEhF,IAAM,IAAW,EAAQ,IAAI,CAAG;GAEhC,IAAI,GAAU,OAAO;GAErB,IAAM,IAAqB,GACrB,IAAmB,EAAgB,CAAG,GACtC,IAAS,EAAK,CAAC,CAAC,MACnB,OACK,EAAQ,IAAI,CAAG,MAAM,KAAQ,EAAQ,OAAO,CAAG,GAE/C,MAAe,KAAsB,EAAU,IAAI,CAAG,MAAM,KAC9D,EAAI,GAAK,CAAK,GAGT,KAER,MAAmB;IAGlB,MAFI,EAAQ,IAAI,CAAG,MAAM,KAAQ,EAAQ,OAAO,CAAG,GAE7C;GACR,CACF;GAIA,OAFA,EAAQ,IAAI,GAAK,CAAM,GAEhB;EACT;EAiBE;EACA,IAAI,OAAO;GAGT,OAFA,EAAK,GAEE,EAAQ;EACjB;CACF;AACF"}
1
+ {"version":3,"file":"cache.js","names":[],"sources":["../../src/cache/cache.ts"],"sourcesContent":["export type CacheOptions = {\n capacity?: number;\n now?: () => number;\n ttlMs?: number;\n};\n\ntype Entry<T> = {\n expiresAt: number | undefined;\n value: T;\n};\n\nexport interface Cache<K, T> {\n clear(): void;\n delete(key: K): boolean;\n get(key: K): T | undefined;\n getOrLoad(key: K, load: () => Promise<T>): Promise<T>;\n set(key: K, value: T, options?: { ttlMs?: number }): void;\n readonly size: number;\n}\n\nexport function cache<K, T>({ capacity = Infinity, now = Date.now, ttlMs }: CacheOptions = {}): Cache<K, T> {\n if (capacity !== Infinity && (!Number.isInteger(capacity) || capacity < 1)) {\n throw new RangeError(`cache: capacity must be a positive integer or Infinity, got ${capacity}`);\n }\n\n const entries = new Map<K, Entry<T>>();\n const pending = new Map<K, Promise<T>>();\n const revisions = new Map<K, number>();\n let generation = 0;\n\n const advanceRevision = (key: K): number => {\n const revision = (revisions.get(key) ?? 0) + 1;\n\n revisions.set(key, revision);\n\n return revision;\n };\n\n const expiresAt = (duration: number | undefined): number | undefined => {\n if (duration === undefined || duration === Infinity) return undefined;\n\n if (!Number.isFinite(duration) || duration < 0) {\n throw new RangeError(`cache: ttlMs must be a non-negative finite number or Infinity, got ${duration}`);\n }\n\n return now() + duration;\n };\n\n const read = (key: K): T | undefined => {\n const entry = entries.get(key);\n\n if (!entry) return undefined;\n\n if (entry.expiresAt !== undefined && entry.expiresAt <= now()) {\n entries.delete(key);\n\n return undefined;\n }\n\n return entry.value;\n };\n\n const trim = (): void => {\n for (const [key, entry] of entries) {\n if (entry.expiresAt !== undefined && entry.expiresAt <= now()) entries.delete(key);\n }\n\n while (entries.size > capacity) {\n const oldest = entries.keys().next().value;\n\n if (oldest === undefined) return;\n\n entries.delete(oldest);\n }\n };\n\n const set = (key: K, value: T, options: { ttlMs?: number } = {}): void => {\n advanceRevision(key);\n entries.delete(key);\n entries.set(key, { expiresAt: expiresAt(options.ttlMs ?? ttlMs), value });\n trim();\n };\n\n const getOrLoad = (key: K, load: () => Promise<T>): Promise<T> => {\n const cached = read(key);\n\n if (cached !== undefined || entries.has(key)) return Promise.resolve(cached as T);\n\n const existing = pending.get(key);\n\n if (existing) return existing;\n\n const capturedGeneration = generation;\n const capturedRevision = advanceRevision(key);\n const result = load().then(\n (value) => {\n if (pending.get(key) === result) pending.delete(key);\n\n if (generation === capturedGeneration && revisions.get(key) === capturedRevision) {\n set(key, value);\n }\n\n return value;\n },\n (error: unknown) => {\n if (pending.get(key) === result) pending.delete(key);\n\n throw error;\n },\n );\n\n pending.set(key, result);\n\n return result;\n };\n\n return {\n clear: () => {\n generation++;\n entries.clear();\n pending.clear();\n revisions.clear();\n },\n delete: (key) => {\n pending.delete(key);\n advanceRevision(key);\n\n return entries.delete(key);\n },\n get: read,\n getOrLoad,\n set,\n get size() {\n return entries.size;\n },\n };\n}\n"],"mappings":";AAoBA,SAAgB,EAAY,EAAE,cAAW,UAAU,SAAM,KAAK,KAAK,aAAwB,CAAC,GAAgB;CAC1G,IAAI,MAAa,aAAa,CAAC,OAAO,UAAU,CAAQ,KAAK,IAAW,IACtE,MAAU,WAAW,+DAA+D,GAAU;CAGhG,IAAM,oBAAU,IAAI,IAAiB,GAC/B,oBAAU,IAAI,IAAmB,GACjC,oBAAY,IAAI,IAAe,GACjC,IAAa,GAEX,KAAmB,MAAmB;EAC1C,IAAM,KAAY,EAAU,IAAI,CAAG,KAAK,KAAK;EAI7C,OAFA,EAAU,IAAI,GAAK,CAAQ,GAEpB;CACT,GAEM,KAAa,MAAqD;EAClE,UAAa,KAAA,KAAa,MAAa,UAE3C;OAAI,CAAC,OAAO,SAAS,CAAQ,KAAK,IAAW,GAC3C,MAAU,WAAW,sEAAsE,GAAU;GAGvG,OAAO,EAAI,IAAI;EAHwF;CAIzG,GAEM,KAAQ,MAA0B;EACtC,IAAM,IAAQ,EAAQ,IAAI,CAAG;EAExB,OAEL;OAAI,EAAM,cAAc,KAAA,KAAa,EAAM,aAAa,EAAI,GAAG;IAC7D,EAAQ,OAAO,CAAG;IAElB;GACF;GAEA,OAAO,EAAM;EAFb;CAGF,GAEM,UAAmB;EACvB,KAAK,IAAM,CAAC,GAAK,MAAU,GACzB,AAAI,EAAM,cAAc,KAAA,KAAa,EAAM,aAAa,EAAI,KAAG,EAAQ,OAAO,CAAG;EAGnF,OAAO,EAAQ,OAAO,IAAU;GAC9B,IAAM,IAAS,EAAQ,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC;GAErC,IAAI,MAAW,KAAA,GAAW;GAE1B,EAAQ,OAAO,CAAM;EACvB;CACF,GAEM,KAAO,GAAQ,GAAU,IAA8B,CAAC,MAAY;EAIxE,AAHA,EAAgB,CAAG,GACnB,EAAQ,OAAO,CAAG,GAClB,EAAQ,IAAI,GAAK;GAAE,WAAW,EAAU,EAAQ,SAAS,CAAK;GAAG;EAAM,CAAC,GACxE,EAAK;CACP;CAmCA,OAAO;EACL,aAAa;GAIX,AAHA,KACA,EAAQ,MAAM,GACd,EAAQ,MAAM,GACd,EAAU,MAAM;EAClB;EACA,SAAS,OACP,EAAQ,OAAO,CAAG,GAClB,EAAgB,CAAG,GAEZ,EAAQ,OAAO,CAAG;EAE3B,KAAK;EACL,YA/CiB,GAAQ,MAAuC;GAChE,IAAM,IAAS,EAAK,CAAG;GAEvB,IAAI,MAAW,KAAA,KAAa,EAAQ,IAAI,CAAG,GAAG,OAAO,QAAQ,QAAQ,CAAW;GAEhF,IAAM,IAAW,EAAQ,IAAI,CAAG;GAEhC,IAAI,GAAU,OAAO;GAErB,IAAM,IAAqB,GACrB,IAAmB,EAAgB,CAAG,GACtC,IAAS,EAAK,CAAC,CAAC,MACnB,OACK,EAAQ,IAAI,CAAG,MAAM,KAAQ,EAAQ,OAAO,CAAG,GAE/C,MAAe,KAAsB,EAAU,IAAI,CAAG,MAAM,KAC9D,EAAI,GAAK,CAAK,GAGT,KAER,MAAmB;IAGlB,MAFI,EAAQ,IAAI,CAAG,MAAM,KAAQ,EAAQ,OAAO,CAAG,GAE7C;GACR,CACF;GAIA,OAFA,EAAQ,IAAI,GAAK,CAAM,GAEhB;EACT;EAiBE;EACA,IAAI,OAAO;GACT,OAAO,EAAQ;EACjB;CACF;AACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"memo.cjs","names":[],"sources":["../../src/cache/memo.ts"],"sourcesContent":["import type { Fn } from '../types';\n\nimport { LruMap } from '../_common/_lruMap';\nimport { ArsenalSerializationError } from '../errors';\n\nexport type MemoOptions<T extends Fn> = {\n key?: (...args: Parameters<T>) => PropertyKey;\n maxSize?: number;\n};\n\nexport type Memoized<T extends Fn> = ((...args: Parameters<T>) => ReturnType<T>) & {\n clear(): void;\n invalidate(...args: Parameters<T>): void;\n readonly size: number;\n};\n\nconst UNDEFINED_SENTINEL = '\\x00undefined\\x00';\nconst NAN_SENTINEL = '\\x00NaN\\x00';\nconst POSITIVE_INFINITY_SENTINEL = '\\x00+Infinity\\x00';\nconst NEGATIVE_INFINITY_SENTINEL = '\\x00-Infinity\\x00';\nconst FUNCTION_SENTINEL = '\\x00function\\x00';\n\nlet functionIdCounter = 0;\nconst functionIds = new WeakMap<Fn, number>();\n\n/** Returns a stable per-identity id for a function so distinct functions never collide as cache keys. */\nfunction idForFunction(fn: Fn): number {\n let id = functionIds.get(fn);\n\n if (id === undefined) {\n id = functionIdCounter++;\n functionIds.set(fn, id);\n }\n\n return id;\n}\n\nconst defaultKey = (args: unknown[]): string => {\n try {\n return JSON.stringify(args, (_, value) => {\n if (value === undefined) return UNDEFINED_SENTINEL;\n\n if (typeof value === 'number' && Number.isNaN(value)) return NAN_SENTINEL;\n\n if (value === Number.POSITIVE_INFINITY) return POSITIVE_INFINITY_SENTINEL;\n\n if (value === Number.NEGATIVE_INFINITY) return NEGATIVE_INFINITY_SENTINEL;\n\n if (typeof value === 'function') return `${FUNCTION_SENTINEL}${idForFunction(value as Fn)}`;\n\n return value;\n });\n } catch (error) {\n const reason = error instanceof Error && error.message ? ` Reason: ${error.message}` : '';\n\n throw new ArsenalSerializationError(\n `[arsenal/memo] Failed to serialize memo arguments. Provide options.key for non-serializable arguments.${reason}`,\n { cause: error },\n );\n }\n};\n\n/** Excludes async functions at the type level so callers cannot accidentally memoize a Promise. */\ntype SyncFn<T extends Fn> = ReturnType<T> extends Promise<unknown> ? never : T;\n\n/**\n * Memoizes a **sync** function with optional LRU eviction by cache size.\n * The returned function exposes `.clear()` and `.invalidate(...args)` methods.\n *\n * **Do not pass async functions.** `memo` caches the raw `Promise` object, not\n * the resolved value — subsequent calls return the same stale Promise. Use\n * `cache.getOrLoad` for async caching with TTL and load deduplication.\n *\n * @example\n * ```ts\n * const add = (x: number, y: number) => x + y;\n * const memoAdd = memo(add, { maxSize: 100 });\n *\n * memoAdd(1, 2); // 3 (computed)\n * memoAdd(1, 2); // 3 (from cache)\n * memoAdd.invalidate(1, 2); // remove specific entry\n * memoAdd.clear(); // wipe entire cache\n * ```\n *\n * @param fn - The sync function to memoize. Must not return a Promise.\n * @param [options.maxSize] - Maximum cache size. Oldest entries evicted when exceeded (LRU). Default: `Infinity`.\n * @param [options.key] - Custom cache key function. Defaults to `JSON.stringify(args)`.\n *\n * @throws {RangeError} If `maxSize` is not a positive integer or `Infinity`.\n */\nexport function memo<T extends Fn>(fn: SyncFn<T>, { key, maxSize = Infinity }: MemoOptions<T> = {}): Memoized<T> {\n if (maxSize !== Infinity && (!Number.isInteger(maxSize) || maxSize < 1)) {\n throw new RangeError(`memo: maxSize must be a positive integer or Infinity, got ${maxSize}`);\n }\n\n const cache = new LruMap<PropertyKey, ReturnType<T>>(maxSize);\n\n const resolveKey = (...args: Parameters<T>): PropertyKey => (key ? key(...args) : defaultKey(args));\n\n const memoized = (...args: Parameters<T>): ReturnType<T> => {\n const cacheKey = resolveKey(...args);\n\n if (cache.has(cacheKey)) {\n const cached = cache.get(cacheKey)!;\n\n cache.set(cacheKey, cached);\n\n return cached;\n }\n\n const value = fn(...args) as ReturnType<T>;\n\n cache.set(cacheKey, value);\n\n return value;\n };\n\n const result = Object.assign(memoized, {\n clear: () => cache.clear(),\n invalidate: (...args: Parameters<T>): void => {\n cache.delete(resolveKey(...args));\n },\n });\n\n Object.defineProperty(result, 'size', { get: () => cache.size });\n\n return result as Memoized<T>;\n}\n"],"mappings":"qEAgBA,IAAM,EAAqB,gBACrB,EAAe,UACf,EAA6B,gBAC7B,EAA6B,gBAC7B,EAAoB,eAEtB,EAAoB,EAClB,EAAc,IAAI,QAGxB,SAAS,EAAc,EAAgB,CACrC,IAAI,EAAK,EAAY,IAAI,CAAE,EAO3B,OALI,IAAO,IAAA,KACT,EAAK,IACL,EAAY,IAAI,EAAI,CAAE,GAGjB,CACT,CAEA,IAAM,EAAc,GAA4B,CAC9C,GAAI,CACF,OAAO,KAAK,UAAU,GAAO,EAAG,IAC1B,IAAU,IAAA,GAAkB,EAE5B,OAAO,GAAU,UAAY,OAAO,MAAM,CAAK,EAAU,EAEzD,IAAU,IAAiC,EAE3C,IAAU,KAAiC,EAE3C,OAAO,GAAU,WAAmB,GAAG,IAAoB,EAAc,CAAW,IAEjF,CACR,CACH,OAAS,EAAO,CACd,IAAM,EAAS,aAAiB,OAAS,EAAM,QAAU,YAAY,EAAM,UAAY,GAEvF,MAAM,IAAI,EAAA,0BACR,yGAAyG,IACzG,CAAE,MAAO,CAAM,CACjB,CACF,CACF,EA8BA,SAAgB,EAAmB,EAAe,CAAE,MAAK,UAAU,KAA6B,CAAC,EAAgB,CAC/G,GAAI,IAAY,MAAa,CAAC,OAAO,UAAU,CAAO,GAAK,EAAU,GACnE,MAAU,WAAW,6DAA6D,GAAS,EAG7F,IAAM,EAAQ,IAAI,EAAA,OAAmC,CAAO,EAEtD,GAAc,GAAG,IAAsC,EAAM,EAAI,GAAG,CAAI,EAAI,EAAW,CAAI,EAoB3F,EAAS,OAAO,QAlBJ,GAAG,IAAuC,CAC1D,IAAM,EAAW,EAAW,GAAG,CAAI,EAEnC,GAAI,EAAM,IAAI,CAAQ,EAAG,CACvB,IAAM,EAAS,EAAM,IAAI,CAAQ,EAIjC,OAFA,EAAM,IAAI,EAAU,CAAM,EAEnB,CACT,CAEA,IAAM,EAAQ,EAAG,GAAG,CAAI,EAIxB,OAFA,EAAM,IAAI,EAAU,CAAK,EAElB,CACT,EAEuC,CACrC,UAAa,EAAM,MAAM,EACzB,YAAa,GAAG,IAA8B,CAC5C,EAAM,OAAO,EAAW,GAAG,CAAI,CAAC,CAClC,CACF,CAAC,EAID,OAFA,OAAO,eAAe,EAAQ,OAAQ,CAAE,QAAW,EAAM,IAAK,CAAC,EAExD,CACT"}
1
+ {"version":3,"file":"memo.cjs","names":[],"sources":["../../src/cache/memo.ts"],"sourcesContent":["import { LruMap } from '../_common/_lruMap';\nimport { ArsenalSerializationError } from '../errors';\nimport type { Fn } from '../types';\n\nexport type MemoOptions<T extends Fn> = {\n key?: (...args: Parameters<T>) => PropertyKey;\n maxSize?: number;\n};\n\nexport type Memoized<T extends Fn> = ((...args: Parameters<T>) => ReturnType<T>) & {\n clear(): void;\n invalidate(...args: Parameters<T>): void;\n readonly size: number;\n};\n\nconst UNDEFINED_SENTINEL = '\\x00undefined\\x00';\nconst NAN_SENTINEL = '\\x00NaN\\x00';\nconst POSITIVE_INFINITY_SENTINEL = '\\x00+Infinity\\x00';\nconst NEGATIVE_INFINITY_SENTINEL = '\\x00-Infinity\\x00';\nconst FUNCTION_SENTINEL = '\\x00function\\x00';\n\nlet functionIdCounter = 0;\nconst functionIds = new WeakMap<Fn, number>();\n\n/** Returns a stable per-identity id for a function so distinct functions never collide as cache keys. */\nfunction idForFunction(fn: Fn): number {\n let id = functionIds.get(fn);\n\n if (id === undefined) {\n id = functionIdCounter++;\n functionIds.set(fn, id);\n }\n\n return id;\n}\n\nconst defaultKey = (args: unknown[]): string => {\n try {\n return JSON.stringify(args, (_, value) => {\n if (value === undefined) return UNDEFINED_SENTINEL;\n\n if (typeof value === 'number' && Number.isNaN(value)) return NAN_SENTINEL;\n\n if (value === Number.POSITIVE_INFINITY) return POSITIVE_INFINITY_SENTINEL;\n\n if (value === Number.NEGATIVE_INFINITY) return NEGATIVE_INFINITY_SENTINEL;\n\n if (typeof value === 'function') return `${FUNCTION_SENTINEL}${idForFunction(value as Fn)}`;\n\n return value;\n });\n } catch (error) {\n const reason = error instanceof Error && error.message ? ` Reason: ${error.message}` : '';\n\n throw new ArsenalSerializationError(\n `[arsenal/memo] Failed to serialize memo arguments. Provide options.key for non-serializable arguments.${reason}`,\n { cause: error },\n );\n }\n};\n\n/** Excludes async functions at the type level so callers cannot accidentally memoize a Promise. */\ntype SyncFn<T extends Fn> = ReturnType<T> extends Promise<unknown> ? never : T;\n\n/**\n * Memoizes a **sync** function with optional LRU eviction by cache size.\n * The returned function exposes `.clear()` and `.invalidate(...args)` methods.\n *\n * **Do not pass async functions.** `memo` caches the raw `Promise` object, not\n * the resolved value — subsequent calls return the same stale Promise. Use\n * `cache.getOrLoad` for async caching with TTL and load deduplication.\n *\n * @example\n * ```ts\n * const add = (x: number, y: number) => x + y;\n * const memoAdd = memo(add, { maxSize: 100 });\n *\n * memoAdd(1, 2); // 3 (computed)\n * memoAdd(1, 2); // 3 (from cache)\n * memoAdd.invalidate(1, 2); // remove specific entry\n * memoAdd.clear(); // wipe entire cache\n * ```\n *\n * @param fn - The sync function to memoize. Must not return a Promise.\n * @param [options.maxSize] - Maximum cache size. Oldest entries evicted when exceeded (LRU). Default: `Infinity`.\n * @param [options.key] - Custom cache key function. Defaults to `JSON.stringify(args)`.\n *\n * @throws {RangeError} If `maxSize` is not a positive integer or `Infinity`.\n */\nexport function memo<T extends Fn>(fn: SyncFn<T>, { key, maxSize = Infinity }: MemoOptions<T> = {}): Memoized<T> {\n if (maxSize !== Infinity && (!Number.isInteger(maxSize) || maxSize < 1)) {\n throw new RangeError(`memo: maxSize must be a positive integer or Infinity, got ${maxSize}`);\n }\n\n const cache = new LruMap<PropertyKey, ReturnType<T>>(maxSize);\n\n const resolveKey = (...args: Parameters<T>): PropertyKey => (key ? key(...args) : defaultKey(args));\n\n const memoized = (...args: Parameters<T>): ReturnType<T> => {\n const cacheKey = resolveKey(...args);\n\n if (cache.has(cacheKey)) {\n const cached = cache.get(cacheKey)!;\n\n cache.set(cacheKey, cached);\n\n return cached;\n }\n\n const value = fn(...args) as ReturnType<T>;\n\n cache.set(cacheKey, value);\n\n return value;\n };\n\n const result = Object.assign(memoized, {\n clear: () => cache.clear(),\n invalidate: (...args: Parameters<T>): void => {\n cache.delete(resolveKey(...args));\n },\n });\n\n Object.defineProperty(result, 'size', { get: () => cache.size });\n\n return result as Memoized<T>;\n}\n"],"mappings":"qEAeA,IAAM,EAAqB,gBACrB,EAAe,UACf,EAA6B,gBAC7B,EAA6B,gBAC7B,EAAoB,eAEtB,EAAoB,EAClB,EAAc,IAAI,QAGxB,SAAS,EAAc,EAAgB,CACrC,IAAI,EAAK,EAAY,IAAI,CAAE,EAO3B,OALI,IAAO,IAAA,KACT,EAAK,IACL,EAAY,IAAI,EAAI,CAAE,GAGjB,CACT,CAEA,IAAM,EAAc,GAA4B,CAC9C,GAAI,CACF,OAAO,KAAK,UAAU,GAAO,EAAG,IAC1B,IAAU,IAAA,GAAkB,EAE5B,OAAO,GAAU,UAAY,OAAO,MAAM,CAAK,EAAU,EAEzD,IAAU,IAAiC,EAE3C,IAAU,KAAiC,EAE3C,OAAO,GAAU,WAAmB,GAAG,IAAoB,EAAc,CAAW,IAEjF,CACR,CACH,OAAS,EAAO,CACd,IAAM,EAAS,aAAiB,OAAS,EAAM,QAAU,YAAY,EAAM,UAAY,GAEvF,MAAM,IAAI,EAAA,0BACR,yGAAyG,IACzG,CAAE,MAAO,CAAM,CACjB,CACF,CACF,EA8BA,SAAgB,EAAmB,EAAe,CAAE,MAAK,UAAU,KAA6B,CAAC,EAAgB,CAC/G,GAAI,IAAY,MAAa,CAAC,OAAO,UAAU,CAAO,GAAK,EAAU,GACnE,MAAU,WAAW,6DAA6D,GAAS,EAG7F,IAAM,EAAQ,IAAI,EAAA,OAAmC,CAAO,EAEtD,GAAc,GAAG,IAAsC,EAAM,EAAI,GAAG,CAAI,EAAI,EAAW,CAAI,EAoB3F,EAAS,OAAO,QAlBJ,GAAG,IAAuC,CAC1D,IAAM,EAAW,EAAW,GAAG,CAAI,EAEnC,GAAI,EAAM,IAAI,CAAQ,EAAG,CACvB,IAAM,EAAS,EAAM,IAAI,CAAQ,EAIjC,OAFA,EAAM,IAAI,EAAU,CAAM,EAEnB,CACT,CAEA,IAAM,EAAQ,EAAG,GAAG,CAAI,EAIxB,OAFA,EAAM,IAAI,EAAU,CAAK,EAElB,CACT,EAEuC,CACrC,UAAa,EAAM,MAAM,EACzB,YAAa,GAAG,IAA8B,CAC5C,EAAM,OAAO,EAAW,GAAG,CAAI,CAAC,CAClC,CACF,CAAC,EAID,OAFA,OAAO,eAAe,EAAQ,OAAQ,CAAE,QAAW,EAAM,IAAK,CAAC,EAExD,CACT"}
@@ -1 +1 @@
1
- {"version":3,"file":"memo.d.ts","sourceRoot":"","sources":["../../src/cache/memo.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,UAAU,CAAC;AAKnC,MAAM,MAAM,WAAW,CAAC,CAAC,SAAS,EAAE,IAAI;IACtC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,KAAK,WAAW,CAAC;IAC9C,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,QAAQ,CAAC,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC,GAAG,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,KAAK,UAAU,CAAC,CAAC,CAAC,CAAC,GAAG;IACjF,KAAK,IAAI,IAAI,CAAC;IACd,UAAU,CAAC,GAAG,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IACzC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB,CAAC;AAgDF,mGAAmG;AACnG,KAAK,MAAM,CAAC,CAAC,SAAS,EAAE,IAAI,UAAU,CAAC,CAAC,CAAC,SAAS,OAAO,CAAC,OAAO,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC;AAE/E;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,GAAG,EAAE,OAAkB,EAAE,GAAE,WAAW,CAAC,CAAC,CAAM,GAAG,QAAQ,CAAC,CAAC,CAAC,CAqC/G"}
1
+ {"version":3,"file":"memo.d.ts","sourceRoot":"","sources":["../../src/cache/memo.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,UAAU,CAAC;AAEnC,MAAM,MAAM,WAAW,CAAC,CAAC,SAAS,EAAE,IAAI;IACtC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,KAAK,WAAW,CAAC;IAC9C,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,QAAQ,CAAC,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC,GAAG,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,KAAK,UAAU,CAAC,CAAC,CAAC,CAAC,GAAG;IACjF,KAAK,IAAI,IAAI,CAAC;IACd,UAAU,CAAC,GAAG,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IACzC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB,CAAC;AAgDF,mGAAmG;AACnG,KAAK,MAAM,CAAC,CAAC,SAAS,EAAE,IAAI,UAAU,CAAC,CAAC,CAAC,SAAS,OAAO,CAAC,OAAO,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC;AAE/E;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,GAAG,EAAE,OAAkB,EAAE,GAAE,WAAW,CAAC,CAAC,CAAM,GAAG,QAAQ,CAAC,CAAC,CAAC,CAqC/G"}
@@ -1 +1 @@
1
- {"version":3,"file":"memo.js","names":[],"sources":["../../src/cache/memo.ts"],"sourcesContent":["import type { Fn } from '../types';\n\nimport { LruMap } from '../_common/_lruMap';\nimport { ArsenalSerializationError } from '../errors';\n\nexport type MemoOptions<T extends Fn> = {\n key?: (...args: Parameters<T>) => PropertyKey;\n maxSize?: number;\n};\n\nexport type Memoized<T extends Fn> = ((...args: Parameters<T>) => ReturnType<T>) & {\n clear(): void;\n invalidate(...args: Parameters<T>): void;\n readonly size: number;\n};\n\nconst UNDEFINED_SENTINEL = '\\x00undefined\\x00';\nconst NAN_SENTINEL = '\\x00NaN\\x00';\nconst POSITIVE_INFINITY_SENTINEL = '\\x00+Infinity\\x00';\nconst NEGATIVE_INFINITY_SENTINEL = '\\x00-Infinity\\x00';\nconst FUNCTION_SENTINEL = '\\x00function\\x00';\n\nlet functionIdCounter = 0;\nconst functionIds = new WeakMap<Fn, number>();\n\n/** Returns a stable per-identity id for a function so distinct functions never collide as cache keys. */\nfunction idForFunction(fn: Fn): number {\n let id = functionIds.get(fn);\n\n if (id === undefined) {\n id = functionIdCounter++;\n functionIds.set(fn, id);\n }\n\n return id;\n}\n\nconst defaultKey = (args: unknown[]): string => {\n try {\n return JSON.stringify(args, (_, value) => {\n if (value === undefined) return UNDEFINED_SENTINEL;\n\n if (typeof value === 'number' && Number.isNaN(value)) return NAN_SENTINEL;\n\n if (value === Number.POSITIVE_INFINITY) return POSITIVE_INFINITY_SENTINEL;\n\n if (value === Number.NEGATIVE_INFINITY) return NEGATIVE_INFINITY_SENTINEL;\n\n if (typeof value === 'function') return `${FUNCTION_SENTINEL}${idForFunction(value as Fn)}`;\n\n return value;\n });\n } catch (error) {\n const reason = error instanceof Error && error.message ? ` Reason: ${error.message}` : '';\n\n throw new ArsenalSerializationError(\n `[arsenal/memo] Failed to serialize memo arguments. Provide options.key for non-serializable arguments.${reason}`,\n { cause: error },\n );\n }\n};\n\n/** Excludes async functions at the type level so callers cannot accidentally memoize a Promise. */\ntype SyncFn<T extends Fn> = ReturnType<T> extends Promise<unknown> ? never : T;\n\n/**\n * Memoizes a **sync** function with optional LRU eviction by cache size.\n * The returned function exposes `.clear()` and `.invalidate(...args)` methods.\n *\n * **Do not pass async functions.** `memo` caches the raw `Promise` object, not\n * the resolved value — subsequent calls return the same stale Promise. Use\n * `cache.getOrLoad` for async caching with TTL and load deduplication.\n *\n * @example\n * ```ts\n * const add = (x: number, y: number) => x + y;\n * const memoAdd = memo(add, { maxSize: 100 });\n *\n * memoAdd(1, 2); // 3 (computed)\n * memoAdd(1, 2); // 3 (from cache)\n * memoAdd.invalidate(1, 2); // remove specific entry\n * memoAdd.clear(); // wipe entire cache\n * ```\n *\n * @param fn - The sync function to memoize. Must not return a Promise.\n * @param [options.maxSize] - Maximum cache size. Oldest entries evicted when exceeded (LRU). Default: `Infinity`.\n * @param [options.key] - Custom cache key function. Defaults to `JSON.stringify(args)`.\n *\n * @throws {RangeError} If `maxSize` is not a positive integer or `Infinity`.\n */\nexport function memo<T extends Fn>(fn: SyncFn<T>, { key, maxSize = Infinity }: MemoOptions<T> = {}): Memoized<T> {\n if (maxSize !== Infinity && (!Number.isInteger(maxSize) || maxSize < 1)) {\n throw new RangeError(`memo: maxSize must be a positive integer or Infinity, got ${maxSize}`);\n }\n\n const cache = new LruMap<PropertyKey, ReturnType<T>>(maxSize);\n\n const resolveKey = (...args: Parameters<T>): PropertyKey => (key ? key(...args) : defaultKey(args));\n\n const memoized = (...args: Parameters<T>): ReturnType<T> => {\n const cacheKey = resolveKey(...args);\n\n if (cache.has(cacheKey)) {\n const cached = cache.get(cacheKey)!;\n\n cache.set(cacheKey, cached);\n\n return cached;\n }\n\n const value = fn(...args) as ReturnType<T>;\n\n cache.set(cacheKey, value);\n\n return value;\n };\n\n const result = Object.assign(memoized, {\n clear: () => cache.clear(),\n invalidate: (...args: Parameters<T>): void => {\n cache.delete(resolveKey(...args));\n },\n });\n\n Object.defineProperty(result, 'size', { get: () => cache.size });\n\n return result as Memoized<T>;\n}\n"],"mappings":";;;AAgBA,IAAM,IAAqB,iBACrB,IAAe,WACf,IAA6B,iBAC7B,IAA6B,iBAC7B,IAAoB,gBAEtB,IAAoB,GAClB,oBAAc,IAAI,QAAoB;AAG5C,SAAS,EAAc,GAAgB;CACrC,IAAI,IAAK,EAAY,IAAI,CAAE;CAO3B,OALI,MAAO,KAAA,MACT,IAAK,KACL,EAAY,IAAI,GAAI,CAAE,IAGjB;AACT;AAEA,IAAM,KAAc,MAA4B;CAC9C,IAAI;EACF,OAAO,KAAK,UAAU,IAAO,GAAG,MAC1B,MAAU,KAAA,IAAkB,IAE5B,OAAO,KAAU,YAAY,OAAO,MAAM,CAAK,IAAU,IAEzD,MAAU,WAAiC,IAE3C,MAAU,YAAiC,IAE3C,OAAO,KAAU,aAAmB,GAAG,IAAoB,EAAc,CAAW,MAEjF,CACR;CACH,SAAS,GAAO;EACd,IAAM,IAAS,aAAiB,SAAS,EAAM,UAAU,YAAY,EAAM,YAAY;EAEvF,MAAM,IAAI,EACR,yGAAyG,KACzG,EAAE,OAAO,EAAM,CACjB;CACF;AACF;AA8BA,SAAgB,EAAmB,GAAe,EAAE,QAAK,aAAU,aAA6B,CAAC,GAAgB;CAC/G,IAAI,MAAY,aAAa,CAAC,OAAO,UAAU,CAAO,KAAK,IAAU,IACnE,MAAU,WAAW,6DAA6D,GAAS;CAG7F,IAAM,IAAQ,IAAI,EAAmC,CAAO,GAEtD,KAAc,GAAG,MAAsC,IAAM,EAAI,GAAG,CAAI,IAAI,EAAW,CAAI,GAoB3F,IAAS,OAAO,QAlBJ,GAAG,MAAuC;EAC1D,IAAM,IAAW,EAAW,GAAG,CAAI;EAEnC,IAAI,EAAM,IAAI,CAAQ,GAAG;GACvB,IAAM,IAAS,EAAM,IAAI,CAAQ;GAIjC,OAFA,EAAM,IAAI,GAAU,CAAM,GAEnB;EACT;EAEA,IAAM,IAAQ,EAAG,GAAG,CAAI;EAIxB,OAFA,EAAM,IAAI,GAAU,CAAK,GAElB;CACT,GAEuC;EACrC,aAAa,EAAM,MAAM;EACzB,aAAa,GAAG,MAA8B;GAC5C,EAAM,OAAO,EAAW,GAAG,CAAI,CAAC;EAClC;CACF,CAAC;CAID,OAFA,OAAO,eAAe,GAAQ,QAAQ,EAAE,WAAW,EAAM,KAAK,CAAC,GAExD;AACT"}
1
+ {"version":3,"file":"memo.js","names":[],"sources":["../../src/cache/memo.ts"],"sourcesContent":["import { LruMap } from '../_common/_lruMap';\nimport { ArsenalSerializationError } from '../errors';\nimport type { Fn } from '../types';\n\nexport type MemoOptions<T extends Fn> = {\n key?: (...args: Parameters<T>) => PropertyKey;\n maxSize?: number;\n};\n\nexport type Memoized<T extends Fn> = ((...args: Parameters<T>) => ReturnType<T>) & {\n clear(): void;\n invalidate(...args: Parameters<T>): void;\n readonly size: number;\n};\n\nconst UNDEFINED_SENTINEL = '\\x00undefined\\x00';\nconst NAN_SENTINEL = '\\x00NaN\\x00';\nconst POSITIVE_INFINITY_SENTINEL = '\\x00+Infinity\\x00';\nconst NEGATIVE_INFINITY_SENTINEL = '\\x00-Infinity\\x00';\nconst FUNCTION_SENTINEL = '\\x00function\\x00';\n\nlet functionIdCounter = 0;\nconst functionIds = new WeakMap<Fn, number>();\n\n/** Returns a stable per-identity id for a function so distinct functions never collide as cache keys. */\nfunction idForFunction(fn: Fn): number {\n let id = functionIds.get(fn);\n\n if (id === undefined) {\n id = functionIdCounter++;\n functionIds.set(fn, id);\n }\n\n return id;\n}\n\nconst defaultKey = (args: unknown[]): string => {\n try {\n return JSON.stringify(args, (_, value) => {\n if (value === undefined) return UNDEFINED_SENTINEL;\n\n if (typeof value === 'number' && Number.isNaN(value)) return NAN_SENTINEL;\n\n if (value === Number.POSITIVE_INFINITY) return POSITIVE_INFINITY_SENTINEL;\n\n if (value === Number.NEGATIVE_INFINITY) return NEGATIVE_INFINITY_SENTINEL;\n\n if (typeof value === 'function') return `${FUNCTION_SENTINEL}${idForFunction(value as Fn)}`;\n\n return value;\n });\n } catch (error) {\n const reason = error instanceof Error && error.message ? ` Reason: ${error.message}` : '';\n\n throw new ArsenalSerializationError(\n `[arsenal/memo] Failed to serialize memo arguments. Provide options.key for non-serializable arguments.${reason}`,\n { cause: error },\n );\n }\n};\n\n/** Excludes async functions at the type level so callers cannot accidentally memoize a Promise. */\ntype SyncFn<T extends Fn> = ReturnType<T> extends Promise<unknown> ? never : T;\n\n/**\n * Memoizes a **sync** function with optional LRU eviction by cache size.\n * The returned function exposes `.clear()` and `.invalidate(...args)` methods.\n *\n * **Do not pass async functions.** `memo` caches the raw `Promise` object, not\n * the resolved value — subsequent calls return the same stale Promise. Use\n * `cache.getOrLoad` for async caching with TTL and load deduplication.\n *\n * @example\n * ```ts\n * const add = (x: number, y: number) => x + y;\n * const memoAdd = memo(add, { maxSize: 100 });\n *\n * memoAdd(1, 2); // 3 (computed)\n * memoAdd(1, 2); // 3 (from cache)\n * memoAdd.invalidate(1, 2); // remove specific entry\n * memoAdd.clear(); // wipe entire cache\n * ```\n *\n * @param fn - The sync function to memoize. Must not return a Promise.\n * @param [options.maxSize] - Maximum cache size. Oldest entries evicted when exceeded (LRU). Default: `Infinity`.\n * @param [options.key] - Custom cache key function. Defaults to `JSON.stringify(args)`.\n *\n * @throws {RangeError} If `maxSize` is not a positive integer or `Infinity`.\n */\nexport function memo<T extends Fn>(fn: SyncFn<T>, { key, maxSize = Infinity }: MemoOptions<T> = {}): Memoized<T> {\n if (maxSize !== Infinity && (!Number.isInteger(maxSize) || maxSize < 1)) {\n throw new RangeError(`memo: maxSize must be a positive integer or Infinity, got ${maxSize}`);\n }\n\n const cache = new LruMap<PropertyKey, ReturnType<T>>(maxSize);\n\n const resolveKey = (...args: Parameters<T>): PropertyKey => (key ? key(...args) : defaultKey(args));\n\n const memoized = (...args: Parameters<T>): ReturnType<T> => {\n const cacheKey = resolveKey(...args);\n\n if (cache.has(cacheKey)) {\n const cached = cache.get(cacheKey)!;\n\n cache.set(cacheKey, cached);\n\n return cached;\n }\n\n const value = fn(...args) as ReturnType<T>;\n\n cache.set(cacheKey, value);\n\n return value;\n };\n\n const result = Object.assign(memoized, {\n clear: () => cache.clear(),\n invalidate: (...args: Parameters<T>): void => {\n cache.delete(resolveKey(...args));\n },\n });\n\n Object.defineProperty(result, 'size', { get: () => cache.size });\n\n return result as Memoized<T>;\n}\n"],"mappings":";;;AAeA,IAAM,IAAqB,iBACrB,IAAe,WACf,IAA6B,iBAC7B,IAA6B,iBAC7B,IAAoB,gBAEtB,IAAoB,GAClB,oBAAc,IAAI,QAAoB;AAG5C,SAAS,EAAc,GAAgB;CACrC,IAAI,IAAK,EAAY,IAAI,CAAE;CAO3B,OALI,MAAO,KAAA,MACT,IAAK,KACL,EAAY,IAAI,GAAI,CAAE,IAGjB;AACT;AAEA,IAAM,KAAc,MAA4B;CAC9C,IAAI;EACF,OAAO,KAAK,UAAU,IAAO,GAAG,MAC1B,MAAU,KAAA,IAAkB,IAE5B,OAAO,KAAU,YAAY,OAAO,MAAM,CAAK,IAAU,IAEzD,MAAU,WAAiC,IAE3C,MAAU,YAAiC,IAE3C,OAAO,KAAU,aAAmB,GAAG,IAAoB,EAAc,CAAW,MAEjF,CACR;CACH,SAAS,GAAO;EACd,IAAM,IAAS,aAAiB,SAAS,EAAM,UAAU,YAAY,EAAM,YAAY;EAEvF,MAAM,IAAI,EACR,yGAAyG,KACzG,EAAE,OAAO,EAAM,CACjB;CACF;AACF;AA8BA,SAAgB,EAAmB,GAAe,EAAE,QAAK,aAAU,aAA6B,CAAC,GAAgB;CAC/G,IAAI,MAAY,aAAa,CAAC,OAAO,UAAU,CAAO,KAAK,IAAU,IACnE,MAAU,WAAW,6DAA6D,GAAS;CAG7F,IAAM,IAAQ,IAAI,EAAmC,CAAO,GAEtD,KAAc,GAAG,MAAsC,IAAM,EAAI,GAAG,CAAI,IAAI,EAAW,CAAI,GAoB3F,IAAS,OAAO,QAlBJ,GAAG,MAAuC;EAC1D,IAAM,IAAW,EAAW,GAAG,CAAI;EAEnC,IAAI,EAAM,IAAI,CAAQ,GAAG;GACvB,IAAM,IAAS,EAAM,IAAI,CAAQ;GAIjC,OAFA,EAAM,IAAI,GAAU,CAAM,GAEnB;EACT;EAEA,IAAM,IAAQ,EAAG,GAAG,CAAI;EAIxB,OAFA,EAAM,IAAI,GAAU,CAAK,GAElB;CACT,GAEuC;EACrC,aAAa,EAAM,MAAM;EACzB,aAAa,GAAG,MAA8B;GAC5C,EAAM,OAAO,EAAW,GAAG,CAAI,CAAC;EAClC;CACF,CAAC;CAID,OAFA,OAAO,eAAe,GAAQ,QAAQ,EAAE,WAAW,EAAM,KAAK,CAAC,GAExD;AACT"}
package/dist/errors.cjs CHANGED
@@ -1,2 +1,2 @@
1
- var e=class e extends Error{constructor(e,t){super(e,t),this.name=new.target.name,Object.setPrototypeOf(this,new.target.prototype)}static is(t){return t instanceof e}},t=class extends e{};exports.ArsenalError=e,exports.ArsenalSerializationError=t;
1
+ var e=class extends Error{constructor(e,t){super(e,t),this.name=new.target.name,Object.setPrototypeOf(this,new.target.prototype)}},t=class extends e{};exports.ArsenalError=e,exports.ArsenalSerializationError=t;
2
2
  //# sourceMappingURL=errors.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"errors.cjs","names":[],"sources":["../src/errors.ts"],"sourcesContent":["/** Base class for all arsenal errors. Use `instanceof ArsenalError` to catch any arsenal-originated error. */\nexport class ArsenalError extends Error {\n constructor(message: string, opts?: ErrorOptions) {\n super(message, opts);\n this.name = new.target.name;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n\n static is(err: unknown): err is ArsenalError {\n return err instanceof ArsenalError;\n }\n}\n\n/**\n * Thrown when converting a value to or from its serialized form fails — e.g. `memo`'s default\n * cache key (`JSON.stringify`) encountering a circular reference, or `hash` encountering an\n * unsupported class instance with `{ onClassInstance: 'throw' }`.\n */\nexport class ArsenalSerializationError extends ArsenalError {}\n"],"mappings":"AACA,IAAa,EAAb,MAAa,UAAqB,KAAM,CACtC,YAAY,EAAiB,EAAqB,CAChD,MAAM,EAAS,CAAI,EACnB,KAAK,KAAO,WAAW,KACvB,OAAO,eAAe,KAAM,WAAW,SAAS,CAClD,CAEA,OAAO,GAAG,EAAmC,CAC3C,OAAO,aAAe,CACxB,CACF,EAOa,EAAb,cAA+C,CAAa,CAAC"}
1
+ {"version":3,"file":"errors.cjs","names":[],"sources":["../src/errors.ts"],"sourcesContent":["/** Base class for all arsenal errors. Use `instanceof ArsenalError` to catch any arsenal-originated error. */\nexport class ArsenalError extends Error {\n constructor(message: string, opts?: ErrorOptions) {\n super(message, opts);\n this.name = new.target.name;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/**\n * Thrown when converting a value to or from its serialized form fails — e.g. `memo`'s default\n * cache key (`JSON.stringify`) encountering a circular reference, or `hash` encountering an\n * unsupported class instance with `{ onClassInstance: 'throw' }`.\n */\nexport class ArsenalSerializationError extends ArsenalError {}\n"],"mappings":"AACA,IAAa,EAAb,cAAkC,KAAM,CACtC,YAAY,EAAiB,EAAqB,CAChD,MAAM,EAAS,CAAI,EACnB,KAAK,KAAO,WAAW,KACvB,OAAO,eAAe,KAAM,WAAW,SAAS,CAClD,CACF,EAOa,EAAb,cAA+C,CAAa,CAAC"}
package/dist/errors.d.ts CHANGED
@@ -1,7 +1,6 @@
1
1
  /** Base class for all arsenal errors. Use `instanceof ArsenalError` to catch any arsenal-originated error. */
2
2
  export declare class ArsenalError extends Error {
3
3
  constructor(message: string, opts?: ErrorOptions);
4
- static is(err: unknown): err is ArsenalError;
5
4
  }
6
5
  /**
7
6
  * Thrown when converting a value to or from its serialized form fails — e.g. `memo`'s default
@@ -1 +1 @@
1
- {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,8GAA8G;AAC9G,qBAAa,YAAa,SAAQ,KAAK;gBACzB,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,YAAY;IAMhD,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,GAAG,GAAG,IAAI,YAAY;CAG7C;AAED;;;;GAIG;AACH,qBAAa,yBAA0B,SAAQ,YAAY;CAAG"}
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,8GAA8G;AAC9G,qBAAa,YAAa,SAAQ,KAAK;gBACzB,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,YAAY;CAKjD;AAED;;;;GAIG;AACH,qBAAa,yBAA0B,SAAQ,YAAY;CAAG"}
package/dist/errors.js CHANGED
@@ -1,11 +1,8 @@
1
1
  //#region src/errors.ts
2
- var e = class e extends Error {
2
+ var e = class extends Error {
3
3
  constructor(e, t) {
4
4
  super(e, t), this.name = new.target.name, Object.setPrototypeOf(this, new.target.prototype);
5
5
  }
6
- static is(t) {
7
- return t instanceof e;
8
- }
9
6
  }, t = class extends e {};
10
7
  //#endregion
11
8
  export { e as ArsenalError, t as ArsenalSerializationError };
@@ -1 +1 @@
1
- {"version":3,"file":"errors.js","names":[],"sources":["../src/errors.ts"],"sourcesContent":["/** Base class for all arsenal errors. Use `instanceof ArsenalError` to catch any arsenal-originated error. */\nexport class ArsenalError extends Error {\n constructor(message: string, opts?: ErrorOptions) {\n super(message, opts);\n this.name = new.target.name;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n\n static is(err: unknown): err is ArsenalError {\n return err instanceof ArsenalError;\n }\n}\n\n/**\n * Thrown when converting a value to or from its serialized form fails — e.g. `memo`'s default\n * cache key (`JSON.stringify`) encountering a circular reference, or `hash` encountering an\n * unsupported class instance with `{ onClassInstance: 'throw' }`.\n */\nexport class ArsenalSerializationError extends ArsenalError {}\n"],"mappings":";AACA,IAAa,IAAb,MAAa,UAAqB,MAAM;CACtC,YAAY,GAAiB,GAAqB;EAGhD,AAFA,MAAM,GAAS,CAAI,GACnB,KAAK,OAAO,WAAW,MACvB,OAAO,eAAe,MAAM,WAAW,SAAS;CAClD;CAEA,OAAO,GAAG,GAAmC;EAC3C,OAAO,aAAe;CACxB;AACF,GAOa,IAAb,cAA+C,EAAa,CAAC"}
1
+ {"version":3,"file":"errors.js","names":[],"sources":["../src/errors.ts"],"sourcesContent":["/** Base class for all arsenal errors. Use `instanceof ArsenalError` to catch any arsenal-originated error. */\nexport class ArsenalError extends Error {\n constructor(message: string, opts?: ErrorOptions) {\n super(message, opts);\n this.name = new.target.name;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/**\n * Thrown when converting a value to or from its serialized form fails — e.g. `memo`'s default\n * cache key (`JSON.stringify`) encountering a circular reference, or `hash` encountering an\n * unsupported class instance with `{ onClassInstance: 'throw' }`.\n */\nexport class ArsenalSerializationError extends ArsenalError {}\n"],"mappings":";AACA,IAAa,IAAb,cAAkC,MAAM;CACtC,YAAY,GAAiB,GAAqB;EAGhD,AAFA,MAAM,GAAS,CAAI,GACnB,KAAK,OAAO,WAAW,MACvB,OAAO,eAAe,MAAM,WAAW,SAAS;CAClD;AACF,GAOa,IAAb,cAA+C,EAAa,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"debounce.cjs","names":[],"sources":["../../src/function/debounce.ts"],"sourcesContent":["import type { Fn } from '../types';\n\nimport { warn } from '../_dev';\n\nexport type DebounceOptions = {\n /** Invoke on the leading edge of the delay window. Default: `false`. */\n leading?: boolean;\n /** Invoke on the trailing edge of the delay window. Default: `true`. */\n trailing?: boolean;\n};\n\nexport type Debounced<T extends Fn> = ((...args: Parameters<T>) => ReturnType<T> | undefined) & {\n cancel(): void;\n flush(): ReturnType<T> | undefined;\n pending(): boolean;\n};\n\n/**\n * Debounces a function. By default only the trailing edge fires (after input settles).\n * Pass `{ leading: true }` to fire immediately on the first call instead.\n * Pass `{ leading: true, trailing: true }` to fire on both edges.\n *\n * Use `flush()` to invoke immediately, `cancel()` to clear, and `pending()` to check\n * whether an invocation is scheduled.\n *\n * @example\n * ```ts\n * // Trailing (default) — fires after input settles\n * const save = debounce(persist, 500);\n *\n * // Leading — fires on the first keystroke, then silences during the window\n * const submit = debounce(sendRequest, 500, { leading: true, trailing: false });\n * ```\n */\nexport function debounce<T extends Fn>(\n fn: T,\n delay = 300,\n options: DebounceOptions = { leading: false, trailing: true },\n): Debounced<T> {\n const leading = options.leading ?? false;\n const trailing = options.trailing ?? true;\n\n if (!leading && !trailing) {\n warn('debounce: both `leading` and `trailing` are false — the wrapped function will never be invoked.');\n }\n\n let timerId: ReturnType<typeof setTimeout> | undefined;\n let lastArgs: Parameters<T> | undefined;\n let lastResult: ReturnType<T> | undefined;\n let leadingFired = false;\n\n const clearTimer = () => {\n if (timerId !== undefined) {\n clearTimeout(timerId);\n timerId = undefined;\n }\n };\n\n const invokeTrailing = () => {\n clearTimer();\n leadingFired = false;\n\n if (!lastArgs) return undefined;\n\n const args = lastArgs;\n\n lastArgs = undefined;\n lastResult = fn(...args) as ReturnType<T>;\n\n return lastResult;\n };\n\n return Object.assign(\n (...args: Parameters<T>): ReturnType<T> | undefined => {\n lastArgs = args;\n\n if (leading && !leadingFired) {\n leadingFired = true;\n lastResult = fn(...args) as ReturnType<T>;\n // Clear args regardless of `trailing` — the leading call already consumed this\n // invocation. The trailing timer below only re-invokes `fn` if a *further* call\n // arrives during the cooldown window and repopulates `lastArgs`.\n lastArgs = undefined;\n\n if (!trailing) {\n // Leading-only: start cooldown — no trailing call needed\n timerId = setTimeout(() => {\n timerId = undefined;\n leadingFired = false;\n }, delay);\n\n return lastResult;\n }\n }\n\n // When leading-only, ignore calls within the cooldown window\n if (leading && !trailing && leadingFired) return lastResult;\n\n clearTimer();\n timerId = setTimeout(invokeTrailing, delay);\n\n return lastResult;\n },\n {\n cancel: () => {\n clearTimer();\n lastArgs = undefined;\n leadingFired = false;\n },\n flush: (): ReturnType<T> | undefined => invokeTrailing(),\n pending: () => timerId !== undefined,\n },\n );\n}\n"],"mappings":"uBAkCA,SAAgB,EACd,EACA,EAAQ,IACR,EAA2B,CAAE,QAAS,GAAO,SAAU,EAAK,EAC9C,CACd,IAAM,EAAU,EAAQ,SAAW,GAC7B,EAAW,EAAQ,UAAY,GAMjC,EACA,EACA,EACA,EAAe,GAEb,MAAmB,CACnB,IAAY,IAAA,KACd,aAAa,CAAO,EACpB,EAAU,IAAA,GAEd,EAEM,MAAuB,CAI3B,GAHA,EAAW,EACX,EAAe,GAEX,CAAC,EAAU,OAEf,IAAM,EAAO,EAKb,MAHA,GAAW,IAAA,GACX,EAAa,EAAG,GAAG,CAAI,EAEhB,CACT,EAEA,OAAO,OAAO,QACX,GAAG,KACF,EAAW,EAEP,GAAW,CAAC,IACd,EAAe,GACf,EAAa,EAAG,GAAG,CAAI,EAIvB,EAAW,IAAA,GAEP,CAAC,IAEH,EAAU,eAAiB,CACzB,EAAU,IAAA,GACV,EAAe,EACjB,EAAG,CAAK,EAED,GAKP,GAAW,CAAC,GAAY,EAAqB,GAEjD,EAAW,EACX,EAAU,WAAW,EAAgB,CAAK,EAEnC,IAET,CACE,WAAc,CACZ,EAAW,EACX,EAAW,IAAA,GACX,EAAe,EACjB,EACA,UAAwC,EAAe,EACvD,YAAe,IAAY,IAAA,EAC7B,CACF,CACF"}
1
+ {"version":3,"file":"debounce.cjs","names":[],"sources":["../../src/function/debounce.ts"],"sourcesContent":["import { warn } from '../_dev';\nimport type { Fn } from '../types';\n\nexport type DebounceOptions = {\n /** Invoke on the leading edge of the delay window. Default: `false`. */\n leading?: boolean;\n /** Invoke on the trailing edge of the delay window. Default: `true`. */\n trailing?: boolean;\n};\n\nexport type Debounced<T extends Fn> = ((...args: Parameters<T>) => ReturnType<T> | undefined) & {\n cancel(): void;\n flush(): ReturnType<T> | undefined;\n pending(): boolean;\n};\n\n/**\n * Debounces a function. By default only the trailing edge fires (after input settles).\n * Pass `{ leading: true }` to fire immediately on the first call instead.\n * Pass `{ leading: true, trailing: true }` to fire on both edges.\n *\n * Use `flush()` to invoke immediately, `cancel()` to clear, and `pending()` to check\n * whether an invocation is scheduled.\n *\n * @example\n * ```ts\n * // Trailing (default) — fires after input settles\n * const save = debounce(persist, 500);\n *\n * // Leading — fires on the first keystroke, then silences during the window\n * const submit = debounce(sendRequest, 500, { leading: true, trailing: false });\n * ```\n */\nexport function debounce<T extends Fn>(\n fn: T,\n delay = 300,\n options: DebounceOptions = { leading: false, trailing: true },\n): Debounced<T> {\n const leading = options.leading ?? false;\n const trailing = options.trailing ?? true;\n\n if (!leading && !trailing) {\n warn('debounce: both `leading` and `trailing` are false — the wrapped function will never be invoked.');\n }\n\n let timerId: ReturnType<typeof setTimeout> | undefined;\n let lastArgs: Parameters<T> | undefined;\n let lastResult: ReturnType<T> | undefined;\n let leadingFired = false;\n\n const clearTimer = () => {\n if (timerId !== undefined) {\n clearTimeout(timerId);\n timerId = undefined;\n }\n };\n\n const invokeTrailing = () => {\n clearTimer();\n leadingFired = false;\n\n if (!lastArgs) return undefined;\n\n const args = lastArgs;\n\n lastArgs = undefined;\n lastResult = fn(...args) as ReturnType<T>;\n\n return lastResult;\n };\n\n return Object.assign(\n (...args: Parameters<T>): ReturnType<T> | undefined => {\n lastArgs = args;\n\n if (leading && !leadingFired) {\n leadingFired = true;\n lastResult = fn(...args) as ReturnType<T>;\n // Clear args regardless of `trailing` — the leading call already consumed this\n // invocation. The trailing timer below only re-invokes `fn` if a *further* call\n // arrives during the cooldown window and repopulates `lastArgs`.\n lastArgs = undefined;\n\n if (!trailing) {\n // Leading-only: start cooldown — no trailing call needed\n timerId = setTimeout(() => {\n timerId = undefined;\n leadingFired = false;\n }, delay);\n\n return lastResult;\n }\n }\n\n // When leading-only, ignore calls within the cooldown window\n if (leading && !trailing && leadingFired) return lastResult;\n\n clearTimer();\n timerId = setTimeout(invokeTrailing, delay);\n\n return lastResult;\n },\n {\n cancel: () => {\n clearTimer();\n lastArgs = undefined;\n leadingFired = false;\n },\n flush: (): ReturnType<T> | undefined => invokeTrailing(),\n pending: () => timerId !== undefined,\n },\n );\n}\n"],"mappings":"uBAiCA,SAAgB,EACd,EACA,EAAQ,IACR,EAA2B,CAAE,QAAS,GAAO,SAAU,EAAK,EAC9C,CACd,IAAM,EAAU,EAAQ,SAAW,GAC7B,EAAW,EAAQ,UAAY,GAMjC,EACA,EACA,EACA,EAAe,GAEb,MAAmB,CACnB,IAAY,IAAA,KACd,aAAa,CAAO,EACpB,EAAU,IAAA,GAEd,EAEM,MAAuB,CAI3B,GAHA,EAAW,EACX,EAAe,GAEX,CAAC,EAAU,OAEf,IAAM,EAAO,EAKb,MAHA,GAAW,IAAA,GACX,EAAa,EAAG,GAAG,CAAI,EAEhB,CACT,EAEA,OAAO,OAAO,QACX,GAAG,KACF,EAAW,EAEP,GAAW,CAAC,IACd,EAAe,GACf,EAAa,EAAG,GAAG,CAAI,EAIvB,EAAW,IAAA,GAEP,CAAC,IAEH,EAAU,eAAiB,CACzB,EAAU,IAAA,GACV,EAAe,EACjB,EAAG,CAAK,EAED,GAKP,GAAW,CAAC,GAAY,EAAqB,GAEjD,EAAW,EACX,EAAU,WAAW,EAAgB,CAAK,EAEnC,IAET,CACE,WAAc,CACZ,EAAW,EACX,EAAW,IAAA,GACX,EAAe,EACjB,EACA,UAAwC,EAAe,EACvD,YAAe,IAAY,IAAA,EAC7B,CACF,CACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"debounce.d.ts","sourceRoot":"","sources":["../../src/function/debounce.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,UAAU,CAAC;AAInC,MAAM,MAAM,eAAe,GAAG;IAC5B,wEAAwE;IACxE,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,wEAAwE;IACxE,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,SAAS,CAAC,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC,GAAG,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,KAAK,UAAU,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,GAAG;IAC9F,MAAM,IAAI,IAAI,CAAC;IACf,KAAK,IAAI,UAAU,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC;IACnC,OAAO,IAAI,OAAO,CAAC;CACpB,CAAC;AAEF;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,QAAQ,CAAC,CAAC,SAAS,EAAE,EACnC,EAAE,EAAE,CAAC,EACL,KAAK,SAAM,EACX,OAAO,GAAE,eAAoD,GAC5D,SAAS,CAAC,CAAC,CAAC,CA2Ed"}
1
+ {"version":3,"file":"debounce.d.ts","sourceRoot":"","sources":["../../src/function/debounce.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,UAAU,CAAC;AAEnC,MAAM,MAAM,eAAe,GAAG;IAC5B,wEAAwE;IACxE,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,wEAAwE;IACxE,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,SAAS,CAAC,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC,GAAG,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,KAAK,UAAU,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,GAAG;IAC9F,MAAM,IAAI,IAAI,CAAC;IACf,KAAK,IAAI,UAAU,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC;IACnC,OAAO,IAAI,OAAO,CAAC;CACpB,CAAC;AAEF;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,QAAQ,CAAC,CAAC,SAAS,EAAE,EACnC,EAAE,EAAE,CAAC,EACL,KAAK,SAAM,EACX,OAAO,GAAE,eAAoD,GAC5D,SAAS,CAAC,CAAC,CAAC,CA2Ed"}
@@ -1 +1 @@
1
- {"version":3,"file":"debounce.js","names":[],"sources":["../../src/function/debounce.ts"],"sourcesContent":["import type { Fn } from '../types';\n\nimport { warn } from '../_dev';\n\nexport type DebounceOptions = {\n /** Invoke on the leading edge of the delay window. Default: `false`. */\n leading?: boolean;\n /** Invoke on the trailing edge of the delay window. Default: `true`. */\n trailing?: boolean;\n};\n\nexport type Debounced<T extends Fn> = ((...args: Parameters<T>) => ReturnType<T> | undefined) & {\n cancel(): void;\n flush(): ReturnType<T> | undefined;\n pending(): boolean;\n};\n\n/**\n * Debounces a function. By default only the trailing edge fires (after input settles).\n * Pass `{ leading: true }` to fire immediately on the first call instead.\n * Pass `{ leading: true, trailing: true }` to fire on both edges.\n *\n * Use `flush()` to invoke immediately, `cancel()` to clear, and `pending()` to check\n * whether an invocation is scheduled.\n *\n * @example\n * ```ts\n * // Trailing (default) — fires after input settles\n * const save = debounce(persist, 500);\n *\n * // Leading — fires on the first keystroke, then silences during the window\n * const submit = debounce(sendRequest, 500, { leading: true, trailing: false });\n * ```\n */\nexport function debounce<T extends Fn>(\n fn: T,\n delay = 300,\n options: DebounceOptions = { leading: false, trailing: true },\n): Debounced<T> {\n const leading = options.leading ?? false;\n const trailing = options.trailing ?? true;\n\n if (!leading && !trailing) {\n warn('debounce: both `leading` and `trailing` are false — the wrapped function will never be invoked.');\n }\n\n let timerId: ReturnType<typeof setTimeout> | undefined;\n let lastArgs: Parameters<T> | undefined;\n let lastResult: ReturnType<T> | undefined;\n let leadingFired = false;\n\n const clearTimer = () => {\n if (timerId !== undefined) {\n clearTimeout(timerId);\n timerId = undefined;\n }\n };\n\n const invokeTrailing = () => {\n clearTimer();\n leadingFired = false;\n\n if (!lastArgs) return undefined;\n\n const args = lastArgs;\n\n lastArgs = undefined;\n lastResult = fn(...args) as ReturnType<T>;\n\n return lastResult;\n };\n\n return Object.assign(\n (...args: Parameters<T>): ReturnType<T> | undefined => {\n lastArgs = args;\n\n if (leading && !leadingFired) {\n leadingFired = true;\n lastResult = fn(...args) as ReturnType<T>;\n // Clear args regardless of `trailing` — the leading call already consumed this\n // invocation. The trailing timer below only re-invokes `fn` if a *further* call\n // arrives during the cooldown window and repopulates `lastArgs`.\n lastArgs = undefined;\n\n if (!trailing) {\n // Leading-only: start cooldown — no trailing call needed\n timerId = setTimeout(() => {\n timerId = undefined;\n leadingFired = false;\n }, delay);\n\n return lastResult;\n }\n }\n\n // When leading-only, ignore calls within the cooldown window\n if (leading && !trailing && leadingFired) return lastResult;\n\n clearTimer();\n timerId = setTimeout(invokeTrailing, delay);\n\n return lastResult;\n },\n {\n cancel: () => {\n clearTimer();\n lastArgs = undefined;\n leadingFired = false;\n },\n flush: (): ReturnType<T> | undefined => invokeTrailing(),\n pending: () => timerId !== undefined,\n },\n );\n}\n"],"mappings":";;AAkCA,SAAgB,EACd,GACA,IAAQ,KACR,IAA2B;CAAE,SAAS;CAAO,UAAU;AAAK,GAC9C;CACd,IAAM,IAAU,EAAQ,WAAW,IAC7B,IAAW,EAAQ,YAAY,IAMjC,GACA,GACA,GACA,IAAe,IAEb,UAAmB;EACvB,AAAI,MAAY,KAAA,MACd,aAAa,CAAO,GACpB,IAAU,KAAA;CAEd,GAEM,UAAuB;EAI3B,IAHA,EAAW,GACX,IAAe,IAEX,CAAC,GAAU;EAEf,IAAM,IAAO;EAKb,OAHA,IAAW,KAAA,GACX,IAAa,EAAG,GAAG,CAAI,GAEhB;CACT;CAEA,OAAO,OAAO,QACX,GAAG,OACF,IAAW,GAEP,KAAW,CAAC,MACd,IAAe,IACf,IAAa,EAAG,GAAG,CAAI,GAIvB,IAAW,KAAA,GAEP,CAAC,MAEH,IAAU,iBAAiB;EAEzB,AADA,IAAU,KAAA,GACV,IAAe;CACjB,GAAG,CAAK,GAED,KAKP,KAAW,CAAC,KAAY,IAAqB,KAEjD,EAAW,GACX,IAAU,WAAW,GAAgB,CAAK,GAEnC,KAET;EACE,cAAc;GAGZ,AAFA,EAAW,GACX,IAAW,KAAA,GACX,IAAe;EACjB;EACA,aAAwC,EAAe;EACvD,eAAe,MAAY,KAAA;CAC7B,CACF;AACF"}
1
+ {"version":3,"file":"debounce.js","names":[],"sources":["../../src/function/debounce.ts"],"sourcesContent":["import { warn } from '../_dev';\nimport type { Fn } from '../types';\n\nexport type DebounceOptions = {\n /** Invoke on the leading edge of the delay window. Default: `false`. */\n leading?: boolean;\n /** Invoke on the trailing edge of the delay window. Default: `true`. */\n trailing?: boolean;\n};\n\nexport type Debounced<T extends Fn> = ((...args: Parameters<T>) => ReturnType<T> | undefined) & {\n cancel(): void;\n flush(): ReturnType<T> | undefined;\n pending(): boolean;\n};\n\n/**\n * Debounces a function. By default only the trailing edge fires (after input settles).\n * Pass `{ leading: true }` to fire immediately on the first call instead.\n * Pass `{ leading: true, trailing: true }` to fire on both edges.\n *\n * Use `flush()` to invoke immediately, `cancel()` to clear, and `pending()` to check\n * whether an invocation is scheduled.\n *\n * @example\n * ```ts\n * // Trailing (default) — fires after input settles\n * const save = debounce(persist, 500);\n *\n * // Leading — fires on the first keystroke, then silences during the window\n * const submit = debounce(sendRequest, 500, { leading: true, trailing: false });\n * ```\n */\nexport function debounce<T extends Fn>(\n fn: T,\n delay = 300,\n options: DebounceOptions = { leading: false, trailing: true },\n): Debounced<T> {\n const leading = options.leading ?? false;\n const trailing = options.trailing ?? true;\n\n if (!leading && !trailing) {\n warn('debounce: both `leading` and `trailing` are false — the wrapped function will never be invoked.');\n }\n\n let timerId: ReturnType<typeof setTimeout> | undefined;\n let lastArgs: Parameters<T> | undefined;\n let lastResult: ReturnType<T> | undefined;\n let leadingFired = false;\n\n const clearTimer = () => {\n if (timerId !== undefined) {\n clearTimeout(timerId);\n timerId = undefined;\n }\n };\n\n const invokeTrailing = () => {\n clearTimer();\n leadingFired = false;\n\n if (!lastArgs) return undefined;\n\n const args = lastArgs;\n\n lastArgs = undefined;\n lastResult = fn(...args) as ReturnType<T>;\n\n return lastResult;\n };\n\n return Object.assign(\n (...args: Parameters<T>): ReturnType<T> | undefined => {\n lastArgs = args;\n\n if (leading && !leadingFired) {\n leadingFired = true;\n lastResult = fn(...args) as ReturnType<T>;\n // Clear args regardless of `trailing` — the leading call already consumed this\n // invocation. The trailing timer below only re-invokes `fn` if a *further* call\n // arrives during the cooldown window and repopulates `lastArgs`.\n lastArgs = undefined;\n\n if (!trailing) {\n // Leading-only: start cooldown — no trailing call needed\n timerId = setTimeout(() => {\n timerId = undefined;\n leadingFired = false;\n }, delay);\n\n return lastResult;\n }\n }\n\n // When leading-only, ignore calls within the cooldown window\n if (leading && !trailing && leadingFired) return lastResult;\n\n clearTimer();\n timerId = setTimeout(invokeTrailing, delay);\n\n return lastResult;\n },\n {\n cancel: () => {\n clearTimer();\n lastArgs = undefined;\n leadingFired = false;\n },\n flush: (): ReturnType<T> | undefined => invokeTrailing(),\n pending: () => timerId !== undefined,\n },\n );\n}\n"],"mappings":";;AAiCA,SAAgB,EACd,GACA,IAAQ,KACR,IAA2B;CAAE,SAAS;CAAO,UAAU;AAAK,GAC9C;CACd,IAAM,IAAU,EAAQ,WAAW,IAC7B,IAAW,EAAQ,YAAY,IAMjC,GACA,GACA,GACA,IAAe,IAEb,UAAmB;EACvB,AAAI,MAAY,KAAA,MACd,aAAa,CAAO,GACpB,IAAU,KAAA;CAEd,GAEM,UAAuB;EAI3B,IAHA,EAAW,GACX,IAAe,IAEX,CAAC,GAAU;EAEf,IAAM,IAAO;EAKb,OAHA,IAAW,KAAA,GACX,IAAa,EAAG,GAAG,CAAI,GAEhB;CACT;CAEA,OAAO,OAAO,QACX,GAAG,OACF,IAAW,GAEP,KAAW,CAAC,MACd,IAAe,IACf,IAAa,EAAG,GAAG,CAAI,GAIvB,IAAW,KAAA,GAEP,CAAC,MAEH,IAAU,iBAAiB;EAEzB,AADA,IAAU,KAAA,GACV,IAAe;CACjB,GAAG,CAAK,GAED,KAKP,KAAW,CAAC,KAAY,IAAqB,KAEjD,EAAW,GACX,IAAU,WAAW,GAAgB,CAAK,GAEnC,KAET;EACE,cAAc;GAGZ,AAFA,EAAW,GACX,IAAW,KAAA,GACX,IAAe;EACjB;EACA,aAAwC,EAAe;EACvD,eAAe,MAAY,KAAA;CAC7B,CACF;AACF"}
@@ -1,2 +1,2 @@
1
- function e(...e){if(e.length===0)return e=>e;let[t,...n]=e;return(...e)=>n.reduce((e,t)=>Reflect.apply(t,void 0,[e]),Reflect.apply(t,void 0,e))}exports.pipe=e;
1
+ function e(...e){if(e.length===0)return e=>e;let[t,...n]=e;return(...e)=>n.reduce((e,t)=>t(e),t(...e))}exports.pipe=e;
2
2
  //# sourceMappingURL=pipe.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"pipe.cjs","names":[],"sources":["../../src/function/pipe.ts"],"sourcesContent":["import type { Fn } from '../types';\n\ntype FirstParameters<T extends readonly Fn[]> = T extends [infer First extends Fn, ...unknown[]]\n ? Parameters<First>\n : never;\ntype LastReturnType<T extends readonly Fn[]> = T extends [...unknown[], infer Last extends Fn]\n ? ReturnType<Last>\n : never;\n\n/**\n * Pipes multiple functions into a single function. It starts from the leftmost function and proceeds to the right.\n *\n * The TypeScript overload captures the input type from the first function and the output type from the last.\n * Intermediate steps are typed as `unknown` at the call site — TypeScript cannot infer a safe chain across\n * heterogeneous function signatures without explicit overloads for every arity.\n *\n * `pipe()` with no arguments returns an identity function `<T>(x: T) => T`.\n *\n * @example\n * ```ts\n * const add = (x: number) => x + 2;\n * const multiply = (x: number) => x * 3;\n * const subtract = (x: number) => x - 4;\n * const pipedFn = pipe(subtract, multiply, add);\n *\n * pipedFn(5); // ((5-4) * 3) + 2 = 5\n *\n * // Zero-arg identity\n * pipe()(42); // 42\n * ```\n *\n * @param fns - List of functions to be piped.\n * @returns A new function that is the pipe of the input functions.\n */\nexport function pipe(): <T>(x: T) => T;\nexport function pipe<T extends readonly [Fn, ...Fn[]]>(...fns: T): (...args: FirstParameters<T>) => LastReturnType<T>;\nexport function pipe(...fns: Fn[]): Fn {\n if (fns.length === 0) return <T>(x: T): T => x;\n\n const [firstFn, ...restFns] = fns;\n\n return (...args: never[]) =>\n restFns.reduce(\n (prev: unknown, fn) => Reflect.apply(fn, undefined, [prev]),\n Reflect.apply(firstFn!, undefined, args),\n );\n}\n"],"mappings":"AAoCA,SAAgB,EAAK,GAAG,EAAe,CACrC,GAAI,EAAI,SAAW,EAAG,MAAW,IAAY,EAE7C,GAAM,CAAC,EAAS,GAAG,GAAW,EAE9B,OAAQ,GAAG,IACT,EAAQ,QACL,EAAe,IAAO,QAAQ,MAAM,EAAI,IAAA,GAAW,CAAC,CAAI,CAAC,EAC1D,QAAQ,MAAM,EAAU,IAAA,GAAW,CAAI,CACzC,CACJ"}
1
+ {"version":3,"file":"pipe.cjs","names":[],"sources":["../../src/function/pipe.ts"],"sourcesContent":["import type { Fn } from '../types';\n\ntype FirstParameters<T extends readonly Fn[]> = T extends [infer First extends Fn, ...unknown[]]\n ? Parameters<First>\n : never;\ntype LastReturnType<T extends readonly Fn[]> = T extends [...unknown[], infer Last extends Fn]\n ? ReturnType<Last>\n : never;\n\n/**\n * Pipes multiple functions into a single function. It starts from the leftmost function and proceeds to the right.\n *\n * The TypeScript overload captures the input type from the first function and the output type from the last.\n * Intermediate steps are typed as `unknown` at the call site — TypeScript cannot infer a safe chain across\n * heterogeneous function signatures without explicit overloads for every arity.\n *\n * `pipe()` with no arguments returns an identity function `<T>(x: T) => T`.\n *\n * @example\n * ```ts\n * const add = (x: number) => x + 2;\n * const multiply = (x: number) => x * 3;\n * const subtract = (x: number) => x - 4;\n * const pipedFn = pipe(subtract, multiply, add);\n *\n * pipedFn(5); // ((5-4) * 3) + 2 = 5\n *\n * // Zero-arg identity\n * pipe()(42); // 42\n * ```\n *\n * @param fns - List of functions to be piped.\n * @returns A new function that is the pipe of the input functions.\n */\nexport function pipe(): <T>(x: T) => T;\nexport function pipe<T extends readonly [Fn, ...Fn[]]>(...fns: T): (...args: FirstParameters<T>) => LastReturnType<T>;\nexport function pipe(...fns: Fn[]): Fn {\n if (fns.length === 0) return <T>(x: T): T => x;\n\n const [firstFn, ...restFns] = fns;\n\n return (...args: never[]) =>\n restFns.reduce<unknown>((prev, fn) => (fn as (x: unknown) => unknown)(prev), firstFn(...args));\n}\n"],"mappings":"AAoCA,SAAgB,EAAK,GAAG,EAAe,CACrC,GAAI,EAAI,SAAW,EAAG,MAAW,IAAY,EAE7C,GAAM,CAAC,EAAS,GAAG,GAAW,EAE9B,OAAQ,GAAG,IACT,EAAQ,QAAiB,EAAM,IAAQ,EAA+B,CAAI,EAAG,EAAQ,GAAG,CAAI,CAAC,CACjG"}
@@ -2,7 +2,7 @@
2
2
  function e(...e) {
3
3
  if (e.length === 0) return (e) => e;
4
4
  let [t, ...n] = e;
5
- return (...e) => n.reduce((e, t) => Reflect.apply(t, void 0, [e]), Reflect.apply(t, void 0, e));
5
+ return (...e) => n.reduce((e, t) => t(e), t(...e));
6
6
  }
7
7
  //#endregion
8
8
  export { e as pipe };
@@ -1 +1 @@
1
- {"version":3,"file":"pipe.js","names":[],"sources":["../../src/function/pipe.ts"],"sourcesContent":["import type { Fn } from '../types';\n\ntype FirstParameters<T extends readonly Fn[]> = T extends [infer First extends Fn, ...unknown[]]\n ? Parameters<First>\n : never;\ntype LastReturnType<T extends readonly Fn[]> = T extends [...unknown[], infer Last extends Fn]\n ? ReturnType<Last>\n : never;\n\n/**\n * Pipes multiple functions into a single function. It starts from the leftmost function and proceeds to the right.\n *\n * The TypeScript overload captures the input type from the first function and the output type from the last.\n * Intermediate steps are typed as `unknown` at the call site — TypeScript cannot infer a safe chain across\n * heterogeneous function signatures without explicit overloads for every arity.\n *\n * `pipe()` with no arguments returns an identity function `<T>(x: T) => T`.\n *\n * @example\n * ```ts\n * const add = (x: number) => x + 2;\n * const multiply = (x: number) => x * 3;\n * const subtract = (x: number) => x - 4;\n * const pipedFn = pipe(subtract, multiply, add);\n *\n * pipedFn(5); // ((5-4) * 3) + 2 = 5\n *\n * // Zero-arg identity\n * pipe()(42); // 42\n * ```\n *\n * @param fns - List of functions to be piped.\n * @returns A new function that is the pipe of the input functions.\n */\nexport function pipe(): <T>(x: T) => T;\nexport function pipe<T extends readonly [Fn, ...Fn[]]>(...fns: T): (...args: FirstParameters<T>) => LastReturnType<T>;\nexport function pipe(...fns: Fn[]): Fn {\n if (fns.length === 0) return <T>(x: T): T => x;\n\n const [firstFn, ...restFns] = fns;\n\n return (...args: never[]) =>\n restFns.reduce(\n (prev: unknown, fn) => Reflect.apply(fn, undefined, [prev]),\n Reflect.apply(firstFn!, undefined, args),\n );\n}\n"],"mappings":";AAoCA,SAAgB,EAAK,GAAG,GAAe;CACrC,IAAI,EAAI,WAAW,GAAG,QAAW,MAAY;CAE7C,IAAM,CAAC,GAAS,GAAG,KAAW;CAE9B,QAAQ,GAAG,MACT,EAAQ,QACL,GAAe,MAAO,QAAQ,MAAM,GAAI,KAAA,GAAW,CAAC,CAAI,CAAC,GAC1D,QAAQ,MAAM,GAAU,KAAA,GAAW,CAAI,CACzC;AACJ"}
1
+ {"version":3,"file":"pipe.js","names":[],"sources":["../../src/function/pipe.ts"],"sourcesContent":["import type { Fn } from '../types';\n\ntype FirstParameters<T extends readonly Fn[]> = T extends [infer First extends Fn, ...unknown[]]\n ? Parameters<First>\n : never;\ntype LastReturnType<T extends readonly Fn[]> = T extends [...unknown[], infer Last extends Fn]\n ? ReturnType<Last>\n : never;\n\n/**\n * Pipes multiple functions into a single function. It starts from the leftmost function and proceeds to the right.\n *\n * The TypeScript overload captures the input type from the first function and the output type from the last.\n * Intermediate steps are typed as `unknown` at the call site — TypeScript cannot infer a safe chain across\n * heterogeneous function signatures without explicit overloads for every arity.\n *\n * `pipe()` with no arguments returns an identity function `<T>(x: T) => T`.\n *\n * @example\n * ```ts\n * const add = (x: number) => x + 2;\n * const multiply = (x: number) => x * 3;\n * const subtract = (x: number) => x - 4;\n * const pipedFn = pipe(subtract, multiply, add);\n *\n * pipedFn(5); // ((5-4) * 3) + 2 = 5\n *\n * // Zero-arg identity\n * pipe()(42); // 42\n * ```\n *\n * @param fns - List of functions to be piped.\n * @returns A new function that is the pipe of the input functions.\n */\nexport function pipe(): <T>(x: T) => T;\nexport function pipe<T extends readonly [Fn, ...Fn[]]>(...fns: T): (...args: FirstParameters<T>) => LastReturnType<T>;\nexport function pipe(...fns: Fn[]): Fn {\n if (fns.length === 0) return <T>(x: T): T => x;\n\n const [firstFn, ...restFns] = fns;\n\n return (...args: never[]) =>\n restFns.reduce<unknown>((prev, fn) => (fn as (x: unknown) => unknown)(prev), firstFn(...args));\n}\n"],"mappings":";AAoCA,SAAgB,EAAK,GAAG,GAAe;CACrC,IAAI,EAAI,WAAW,GAAG,QAAW,MAAY;CAE7C,IAAM,CAAC,GAAS,GAAG,KAAW;CAE9B,QAAQ,GAAG,MACT,EAAQ,QAAiB,GAAM,MAAQ,EAA+B,CAAI,GAAG,EAAQ,GAAG,CAAI,CAAC;AACjG"}
@@ -1,2 +1,2 @@
1
- function e(e,t){let n=[],r=e.length;if(t?.reverse)for(let t=r-1;t>=0;t--)try{e[t]()}catch(e){n.push(e)}else for(let t of e)try{t()}catch(e){n.push(e)}if(n.length>0)throw AggregateError(n,`One or more callbacks failed`)}exports.runAll=e;
1
+ function e(e,t){let n=[],r=e.length;if(t?.reverse)for(let t=r-1;t>=0;t--)try{e[t]?.()}catch(e){n.push(e)}else for(let t of e)try{t()}catch(e){n.push(e)}if(n.length>0)throw AggregateError(n,`One or more callbacks failed`)}exports.runAll=e;
2
2
  //# sourceMappingURL=runAll.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"runAll.cjs","names":[],"sources":["../../src/function/runAll.ts"],"sourcesContent":["/**\n * Runs all functions in `fns`, collecting any thrown errors.\n * - With `reverse: true`, iterates in LIFO order (useful for cleanup/teardown stacks).\n * - Throws an `AggregateError` containing all failures if any function throws.\n *\n * @example\n * ```ts\n * const cleanups = [() => a.dispose(), () => b.dispose()];\n * runAll(cleanups, { reverse: true });\n * ```\n */\nexport function runAll(fns: readonly (() => void)[], opts?: { reverse?: boolean }): void {\n const errors: unknown[] = [];\n const len = fns.length;\n\n if (opts?.reverse) {\n for (let i = len - 1; i >= 0; i--) {\n try {\n fns[i]!();\n } catch (err) {\n errors.push(err);\n }\n }\n } else {\n for (const fn of fns) {\n try {\n fn();\n } catch (err) {\n errors.push(err);\n }\n }\n }\n\n if (errors.length > 0) {\n throw new AggregateError(errors, 'One or more callbacks failed');\n }\n}\n"],"mappings":"AAWA,SAAgB,EAAO,EAA8B,EAAoC,CACvF,IAAM,EAAoB,CAAC,EACrB,EAAM,EAAI,OAEhB,GAAI,GAAM,QACR,IAAK,IAAI,EAAI,EAAM,EAAG,GAAK,EAAG,IAC5B,GAAI,CACF,EAAI,EAAE,CAAE,CACV,OAAS,EAAK,CACZ,EAAO,KAAK,CAAG,CACjB,MAGF,IAAK,IAAM,KAAM,EACf,GAAI,CACF,EAAG,CACL,OAAS,EAAK,CACZ,EAAO,KAAK,CAAG,CACjB,CAIJ,GAAI,EAAO,OAAS,EAClB,MAAU,eAAe,EAAQ,8BAA8B,CAEnE"}
1
+ {"version":3,"file":"runAll.cjs","names":[],"sources":["../../src/function/runAll.ts"],"sourcesContent":["/**\n * Runs all functions in `fns`, collecting any thrown errors.\n * - With `reverse: true`, iterates in LIFO order (useful for cleanup/teardown stacks).\n * - Throws an `AggregateError` containing all failures if any function throws.\n *\n * @example\n * ```ts\n * const cleanups = [() => a.dispose(), () => b.dispose()];\n * runAll(cleanups, { reverse: true });\n * ```\n */\nexport function runAll(fns: readonly (() => void)[], opts?: { reverse?: boolean }): void {\n const errors: unknown[] = [];\n const len = fns.length;\n\n if (opts?.reverse) {\n for (let i = len - 1; i >= 0; i--) {\n try {\n fns[i]?.();\n } catch (err) {\n errors.push(err);\n }\n }\n } else {\n for (const fn of fns) {\n try {\n fn();\n } catch (err) {\n errors.push(err);\n }\n }\n }\n\n if (errors.length > 0) {\n throw new AggregateError(errors, 'One or more callbacks failed');\n }\n}\n"],"mappings":"AAWA,SAAgB,EAAO,EAA8B,EAAoC,CACvF,IAAM,EAAoB,CAAC,EACrB,EAAM,EAAI,OAEhB,GAAI,GAAM,QACR,IAAK,IAAI,EAAI,EAAM,EAAG,GAAK,EAAG,IAC5B,GAAI,CACF,EAAI,EAAE,GAAG,CACX,OAAS,EAAK,CACZ,EAAO,KAAK,CAAG,CACjB,MAGF,IAAK,IAAM,KAAM,EACf,GAAI,CACF,EAAG,CACL,OAAS,EAAK,CACZ,EAAO,KAAK,CAAG,CACjB,CAIJ,GAAI,EAAO,OAAS,EAClB,MAAU,eAAe,EAAQ,8BAA8B,CAEnE"}
@@ -2,7 +2,7 @@
2
2
  function e(e, t) {
3
3
  let n = [], r = e.length;
4
4
  if (t?.reverse) for (let t = r - 1; t >= 0; t--) try {
5
- e[t]();
5
+ e[t]?.();
6
6
  } catch (e) {
7
7
  n.push(e);
8
8
  }
@@ -1 +1 @@
1
- {"version":3,"file":"runAll.js","names":[],"sources":["../../src/function/runAll.ts"],"sourcesContent":["/**\n * Runs all functions in `fns`, collecting any thrown errors.\n * - With `reverse: true`, iterates in LIFO order (useful for cleanup/teardown stacks).\n * - Throws an `AggregateError` containing all failures if any function throws.\n *\n * @example\n * ```ts\n * const cleanups = [() => a.dispose(), () => b.dispose()];\n * runAll(cleanups, { reverse: true });\n * ```\n */\nexport function runAll(fns: readonly (() => void)[], opts?: { reverse?: boolean }): void {\n const errors: unknown[] = [];\n const len = fns.length;\n\n if (opts?.reverse) {\n for (let i = len - 1; i >= 0; i--) {\n try {\n fns[i]!();\n } catch (err) {\n errors.push(err);\n }\n }\n } else {\n for (const fn of fns) {\n try {\n fn();\n } catch (err) {\n errors.push(err);\n }\n }\n }\n\n if (errors.length > 0) {\n throw new AggregateError(errors, 'One or more callbacks failed');\n }\n}\n"],"mappings":";AAWA,SAAgB,EAAO,GAA8B,GAAoC;CACvF,IAAM,IAAoB,CAAC,GACrB,IAAM,EAAI;CAEhB,IAAI,GAAM,SACR,KAAK,IAAI,IAAI,IAAM,GAAG,KAAK,GAAG,KAC5B,IAAI;EACF,EAAI,EAAE,CAAE;CACV,SAAS,GAAK;EACZ,EAAO,KAAK,CAAG;CACjB;MAGF,KAAK,IAAM,KAAM,GACf,IAAI;EACF,EAAG;CACL,SAAS,GAAK;EACZ,EAAO,KAAK,CAAG;CACjB;CAIJ,IAAI,EAAO,SAAS,GAClB,MAAU,eAAe,GAAQ,8BAA8B;AAEnE"}
1
+ {"version":3,"file":"runAll.js","names":[],"sources":["../../src/function/runAll.ts"],"sourcesContent":["/**\n * Runs all functions in `fns`, collecting any thrown errors.\n * - With `reverse: true`, iterates in LIFO order (useful for cleanup/teardown stacks).\n * - Throws an `AggregateError` containing all failures if any function throws.\n *\n * @example\n * ```ts\n * const cleanups = [() => a.dispose(), () => b.dispose()];\n * runAll(cleanups, { reverse: true });\n * ```\n */\nexport function runAll(fns: readonly (() => void)[], opts?: { reverse?: boolean }): void {\n const errors: unknown[] = [];\n const len = fns.length;\n\n if (opts?.reverse) {\n for (let i = len - 1; i >= 0; i--) {\n try {\n fns[i]?.();\n } catch (err) {\n errors.push(err);\n }\n }\n } else {\n for (const fn of fns) {\n try {\n fn();\n } catch (err) {\n errors.push(err);\n }\n }\n }\n\n if (errors.length > 0) {\n throw new AggregateError(errors, 'One or more callbacks failed');\n }\n}\n"],"mappings":";AAWA,SAAgB,EAAO,GAA8B,GAAoC;CACvF,IAAM,IAAoB,CAAC,GACrB,IAAM,EAAI;CAEhB,IAAI,GAAM,SACR,KAAK,IAAI,IAAI,IAAM,GAAG,KAAK,GAAG,KAC5B,IAAI;EACF,EAAI,EAAE,GAAG;CACX,SAAS,GAAK;EACZ,EAAO,KAAK,CAAG;CACjB;MAGF,KAAK,IAAM,KAAM,GACf,IAAI;EACF,EAAG;CACL,SAAS,GAAK;EACZ,EAAO,KAAK,CAAG;CACjB;CAIJ,IAAI,EAAO,SAAS,GAClB,MAAU,eAAe,GAAQ,8BAA8B;AAEnE"}
package/dist/index.d.ts CHANGED
@@ -1,4 +1,3 @@
1
- export * from './errors';
2
1
  export * from './array/chunk';
3
2
  export * from './array/filterMap';
4
3
  export * from './array/groupBy';
@@ -10,6 +9,7 @@ export * from './async/attempt';
10
9
  export * from './async/parallel';
11
10
  export * from './async/retry';
12
11
  export * from './async/sleep';
12
+ export * from './errors';
13
13
  export * from './function/debounce';
14
14
  export * from './function/once';
15
15
  export * from './function/pipe';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,eAAe,CAAC;AAC9B,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC;AAClC,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AACjC,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,qBAAqB,CAAC;AACpC,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,wBAAwB,CAAC;AACvC,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,kBAAkB,CAAC;AACjC,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC;AAClC,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AACjC,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,UAAU,CAAC;AACzB,cAAc,qBAAqB,CAAC;AACpC,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,wBAAwB,CAAC;AACvC,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,kBAAkB,CAAC;AACjC,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,oBAAoB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"defaults.cjs","names":[],"sources":["../../src/object/defaults.ts"],"sourcesContent":["import type { Obj } from '../types';\n\nimport { isUnsafeKey } from '../_common/unsafePaths';\nimport { isPlainObject } from '../guards/isPlainObject';\n\n/**\n * Fills in `undefined` properties in `target` with values from `sources`. First source wins\n * — unlike `shallowMerge`, already-set keys are never overwritten.\n *\n * @example\n * ```ts\n * defaults({ a: 1, b: undefined }, { a: 99, b: 2, c: 3 });\n * // { a: 1, b: 2, c: 3 }\n * ```\n *\n * @param target - The object to fill in.\n * @param sources - One or more partial objects supplying default values.\n * @returns A new object with missing keys filled from `sources`.\n */\nexport function defaults<T extends Obj>(target: T, ...sources: Array<Partial<T>>): T {\n const out = { ...target };\n\n for (const source of sources) {\n if (!isPlainObject(source)) continue;\n\n for (const key of Object.keys(source) as Array<keyof T>) {\n if (isUnsafeKey(key as PropertyKey)) continue;\n\n if (out[key] === undefined) {\n out[key] = source[key] as T[keyof T];\n }\n }\n }\n\n return out;\n}\n"],"mappings":"uFAmBA,SAAgB,EAAwB,EAAW,GAAG,EAA+B,CACnF,IAAM,EAAM,CAAE,GAAG,CAAO,EAExB,IAAK,IAAM,KAAU,EACd,KAAA,cAAc,CAAM,EAEzB,IAAK,IAAM,KAAO,OAAO,KAAK,CAAM,EAC9B,EAAA,YAAY,CAAkB,GAE9B,EAAI,KAAS,IAAA,KACf,EAAI,GAAO,EAAO,IAKxB,OAAO,CACT"}
1
+ {"version":3,"file":"defaults.cjs","names":[],"sources":["../../src/object/defaults.ts"],"sourcesContent":["import { isUnsafeKey } from '../_common/unsafePaths';\nimport { isPlainObject } from '../guards/isPlainObject';\nimport type { Obj } from '../types';\n\n/**\n * Fills in `undefined` properties in `target` with values from `sources`. First source wins\n * — unlike `shallowMerge`, already-set keys are never overwritten.\n *\n * @example\n * ```ts\n * defaults({ a: 1, b: undefined }, { a: 99, b: 2, c: 3 });\n * // { a: 1, b: 2, c: 3 }\n * ```\n *\n * @param target - The object to fill in.\n * @param sources - One or more partial objects supplying default values.\n * @returns A new object with missing keys filled from `sources`.\n */\nexport function defaults<T extends Obj>(target: T, ...sources: Array<Partial<T>>): T {\n const out = { ...target };\n\n for (const source of sources) {\n if (!isPlainObject(source)) continue;\n\n for (const key of Object.keys(source) as Array<keyof T>) {\n if (isUnsafeKey(key as PropertyKey)) continue;\n\n if (out[key] === undefined) {\n out[key] = source[key] as T[keyof T];\n }\n }\n }\n\n return out;\n}\n"],"mappings":"uFAkBA,SAAgB,EAAwB,EAAW,GAAG,EAA+B,CACnF,IAAM,EAAM,CAAE,GAAG,CAAO,EAExB,IAAK,IAAM,KAAU,EACd,KAAA,cAAc,CAAM,EAEzB,IAAK,IAAM,KAAO,OAAO,KAAK,CAAM,EAC9B,EAAA,YAAY,CAAkB,GAE9B,EAAI,KAAS,IAAA,KACf,EAAI,GAAO,EAAO,IAKxB,OAAO,CACT"}
@@ -1 +1 @@
1
- {"version":3,"file":"defaults.d.ts","sourceRoot":"","sources":["../../src/object/defaults.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAKpC;;;;;;;;;;;;;GAaG;AACH,wBAAgB,QAAQ,CAAC,CAAC,SAAS,GAAG,EAAE,MAAM,EAAE,CAAC,EAAE,GAAG,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAgBnF"}
1
+ {"version":3,"file":"defaults.d.ts","sourceRoot":"","sources":["../../src/object/defaults.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAEpC;;;;;;;;;;;;;GAaG;AACH,wBAAgB,QAAQ,CAAC,CAAC,SAAS,GAAG,EAAE,MAAM,EAAE,CAAC,EAAE,GAAG,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAgBnF"}
@@ -1 +1 @@
1
- {"version":3,"file":"defaults.js","names":[],"sources":["../../src/object/defaults.ts"],"sourcesContent":["import type { Obj } from '../types';\n\nimport { isUnsafeKey } from '../_common/unsafePaths';\nimport { isPlainObject } from '../guards/isPlainObject';\n\n/**\n * Fills in `undefined` properties in `target` with values from `sources`. First source wins\n * — unlike `shallowMerge`, already-set keys are never overwritten.\n *\n * @example\n * ```ts\n * defaults({ a: 1, b: undefined }, { a: 99, b: 2, c: 3 });\n * // { a: 1, b: 2, c: 3 }\n * ```\n *\n * @param target - The object to fill in.\n * @param sources - One or more partial objects supplying default values.\n * @returns A new object with missing keys filled from `sources`.\n */\nexport function defaults<T extends Obj>(target: T, ...sources: Array<Partial<T>>): T {\n const out = { ...target };\n\n for (const source of sources) {\n if (!isPlainObject(source)) continue;\n\n for (const key of Object.keys(source) as Array<keyof T>) {\n if (isUnsafeKey(key as PropertyKey)) continue;\n\n if (out[key] === undefined) {\n out[key] = source[key] as T[keyof T];\n }\n }\n }\n\n return out;\n}\n"],"mappings":";;;AAmBA,SAAgB,EAAwB,GAAW,GAAG,GAA+B;CACnF,IAAM,IAAM,EAAE,GAAG,EAAO;CAExB,KAAK,IAAM,KAAU,GACd,MAAc,CAAM,GAEzB,KAAK,IAAM,KAAO,OAAO,KAAK,CAAM,GAC9B,EAAY,CAAkB,KAE9B,EAAI,OAAS,KAAA,MACf,EAAI,KAAO,EAAO;CAKxB,OAAO;AACT"}
1
+ {"version":3,"file":"defaults.js","names":[],"sources":["../../src/object/defaults.ts"],"sourcesContent":["import { isUnsafeKey } from '../_common/unsafePaths';\nimport { isPlainObject } from '../guards/isPlainObject';\nimport type { Obj } from '../types';\n\n/**\n * Fills in `undefined` properties in `target` with values from `sources`. First source wins\n * — unlike `shallowMerge`, already-set keys are never overwritten.\n *\n * @example\n * ```ts\n * defaults({ a: 1, b: undefined }, { a: 99, b: 2, c: 3 });\n * // { a: 1, b: 2, c: 3 }\n * ```\n *\n * @param target - The object to fill in.\n * @param sources - One or more partial objects supplying default values.\n * @returns A new object with missing keys filled from `sources`.\n */\nexport function defaults<T extends Obj>(target: T, ...sources: Array<Partial<T>>): T {\n const out = { ...target };\n\n for (const source of sources) {\n if (!isPlainObject(source)) continue;\n\n for (const key of Object.keys(source) as Array<keyof T>) {\n if (isUnsafeKey(key as PropertyKey)) continue;\n\n if (out[key] === undefined) {\n out[key] = source[key] as T[keyof T];\n }\n }\n }\n\n return out;\n}\n"],"mappings":";;;AAkBA,SAAgB,EAAwB,GAAW,GAAG,GAA+B;CACnF,IAAM,IAAM,EAAE,GAAG,EAAO;CAExB,KAAK,IAAM,KAAU,GACd,MAAc,CAAM,GAEzB,KAAK,IAAM,KAAO,OAAO,KAAK,CAAM,GAC9B,EAAY,CAAkB,KAE9B,EAAI,OAAS,KAAA,MACf,EAAI,KAAO,EAAO;CAKxB,OAAO;AACT"}
@@ -1 +1 @@
1
- {"version":3,"file":"diff.cjs","names":[],"sources":["../../src/object/diff.ts"],"sourcesContent":["import type { Obj } from '../types';\n\nimport { isUnsafeKey } from '../_common/unsafePaths';\nimport { isEqual } from '../guards/isEqual';\n\nexport type DiffResult<T extends Obj> = {\n /** Keys present in `after` but not in `before`. */\n added: Array<keyof T & string>;\n /** Keys present in both objects whose values differ. Maps key → `{ before, after }`. */\n changed: { [K in keyof T]?: { after: T[K]; before: T[K] } };\n /** Keys present in `before` but not in `after`. */\n removed: Array<keyof T & string>;\n};\n\n/**\n * Computes the structural difference between two plain objects.\n * Returns an `{ added, removed, changed }` result — no sentinel symbols needed.\n * Dangerous keys (`__proto__`, `constructor`, `prototype`) are omitted from `changed`.\n *\n * @example\n * ```ts\n * diff({ a: 1, b: 2, c: 3 }, { a: 1, b: 99 });\n * // { added: [], removed: ['c'], changed: { b: { before: 2, after: 99 } } }\n *\n * diff({ x: { n: 1 } }, { x: { n: 2 } });\n * // { added: [], removed: [], changed: { x: { before: { n: 1 }, after: { n: 2 } } } }\n * ```\n *\n * @param before - The original object.\n * @param after - The updated object.\n * @param compareFn - Custom equality function. Defaults to deep `isEqual`.\n */\nexport function diff<T extends Obj>(\n before: T = {} as T,\n after: T = {} as T,\n compareFn: (a: unknown, b: unknown) => boolean = isEqual,\n): DiffResult<T> {\n const added: Array<keyof T & string> = [];\n const removed: Array<keyof T & string> = [];\n const changed: Record<string, { after: unknown; before: unknown }> = {};\n\n const beforeKeys = new Set(Object.keys(before));\n const afterKeys = new Set(Object.keys(after));\n\n for (const key of afterKeys) {\n if (!beforeKeys.has(key)) {\n added.push(key as keyof T & string);\n } else if (!isUnsafeKey(key) && !compareFn(before[key], after[key])) {\n changed[key] = { after: after[key], before: before[key] };\n }\n }\n\n for (const key of beforeKeys) {\n if (!afterKeys.has(key)) {\n removed.push(key as keyof T & string);\n }\n }\n\n return { added, changed: changed as DiffResult<T>['changed'], removed };\n}\n\nexport type ArrayDiff<T> = {\n added: T[];\n removed: T[];\n};\n\nexport type ArrayDiffOptions<T> = {\n compareFn?: (a: T, b: T) => boolean;\n};\n\n/**\n * Computes the set-difference between two arrays.\n * Items present in `after` but not `before` are `added`.\n * Items present in `before` but not `after` are `removed`.\n * Order-independent; uses deep equality by default.\n *\n * @example\n * ```ts\n * diffArrays([1, 2, 3], [2, 3, 4]); // { added: [4], removed: [1] }\n * diffArrays(\n * [{ id: 1 }, { id: 2 }],\n * [{ id: 2 }, { id: 3 }],\n * { compareFn: (a, b) => a.id === b.id },\n * ); // { added: [{ id: 3 }], removed: [{ id: 1 }] }\n * ```\n *\n * @param before - The original array.\n * @param after - The updated array.\n * @param [options.compareFn] - Custom equality function. Defaults to deep `isEqual`.\n * @returns An object with `added` and `removed` arrays.\n */\nexport function diffArrays<T>(before: T[], after: T[], options?: ArrayDiffOptions<T>): ArrayDiff<T> {\n const compareFn = options?.compareFn ?? ((a: T, b: T) => isEqual(a, b));\n\n return {\n added: after.filter((item) => !before.some((b) => compareFn(b, item))),\n removed: before.filter((item) => !after.some((a) => compareFn(item, a))),\n };\n}\n"],"mappings":"iFAgCA,SAAgB,EACd,EAAY,CAAC,EACb,EAAW,CAAC,EACZ,EAAiD,EAAA,QAClC,CACf,IAAM,EAAiC,CAAC,EAClC,EAAmC,CAAC,EACpC,EAA+D,CAAC,EAEhE,EAAa,IAAI,IAAI,OAAO,KAAK,CAAM,CAAC,EACxC,EAAY,IAAI,IAAI,OAAO,KAAK,CAAK,CAAC,EAE5C,IAAK,IAAM,KAAO,EACX,EAAW,IAAI,CAAG,EAEZ,CAAC,EAAA,YAAY,CAAG,GAAK,CAAC,EAAU,EAAO,GAAM,EAAM,EAAI,IAChE,EAAQ,GAAO,CAAE,MAAO,EAAM,GAAM,OAAQ,EAAO,EAAK,GAFxD,EAAM,KAAK,CAAuB,EAMtC,IAAK,IAAM,KAAO,EACX,EAAU,IAAI,CAAG,GACpB,EAAQ,KAAK,CAAuB,EAIxC,MAAO,CAAE,QAAgB,UAAqC,SAAQ,CACxE,CAgCA,SAAgB,EAAc,EAAa,EAAY,EAA6C,CAClG,IAAM,EAAY,GAAS,aAAe,EAAM,IAAS,EAAA,QAAQ,EAAG,CAAC,GAErE,MAAO,CACL,MAAO,EAAM,OAAQ,GAAS,CAAC,EAAO,KAAM,GAAM,EAAU,EAAG,CAAI,CAAC,CAAC,EACrE,QAAS,EAAO,OAAQ,GAAS,CAAC,EAAM,KAAM,GAAM,EAAU,EAAM,CAAC,CAAC,CAAC,CACzE,CACF"}
1
+ {"version":3,"file":"diff.cjs","names":[],"sources":["../../src/object/diff.ts"],"sourcesContent":["import { isUnsafeKey } from '../_common/unsafePaths';\nimport { isEqual } from '../guards/isEqual';\nimport type { Obj } from '../types';\n\nexport type DiffResult<T extends Obj> = {\n /** Keys present in `after` but not in `before`. */\n added: Array<keyof T & string>;\n /** Keys present in both objects whose values differ. Maps key → `{ before, after }`. */\n changed: { [K in keyof T]?: { after: T[K]; before: T[K] } };\n /** Keys present in `before` but not in `after`. */\n removed: Array<keyof T & string>;\n};\n\n/**\n * Computes the structural difference between two plain objects.\n * Returns an `{ added, removed, changed }` result — no sentinel symbols needed.\n * Dangerous keys (`__proto__`, `constructor`, `prototype`) are omitted from `changed`.\n *\n * @example\n * ```ts\n * diff({ a: 1, b: 2, c: 3 }, { a: 1, b: 99 });\n * // { added: [], removed: ['c'], changed: { b: { before: 2, after: 99 } } }\n *\n * diff({ x: { n: 1 } }, { x: { n: 2 } });\n * // { added: [], removed: [], changed: { x: { before: { n: 1 }, after: { n: 2 } } } }\n * ```\n *\n * @param before - The original object.\n * @param after - The updated object.\n * @param compareFn - Custom equality function. Defaults to deep `isEqual`.\n */\nexport function diff<T extends Obj>(\n before: T = {} as T,\n after: T = {} as T,\n compareFn: (a: unknown, b: unknown) => boolean = isEqual,\n): DiffResult<T> {\n const added: Array<keyof T & string> = [];\n const removed: Array<keyof T & string> = [];\n const changed: Record<string, { after: unknown; before: unknown }> = {};\n\n const beforeKeys = new Set(Object.keys(before));\n const afterKeys = new Set(Object.keys(after));\n\n for (const key of afterKeys) {\n if (!beforeKeys.has(key)) {\n added.push(key as keyof T & string);\n } else if (!isUnsafeKey(key) && !compareFn(before[key], after[key])) {\n changed[key] = { after: after[key], before: before[key] };\n }\n }\n\n for (const key of beforeKeys) {\n if (!afterKeys.has(key)) {\n removed.push(key as keyof T & string);\n }\n }\n\n return { added, changed: changed as DiffResult<T>['changed'], removed };\n}\n\nexport type ArrayDiff<T> = {\n added: T[];\n removed: T[];\n};\n\nexport type ArrayDiffOptions<T> = {\n compareFn?: (a: T, b: T) => boolean;\n};\n\n/**\n * Computes the set-difference between two arrays.\n * Items present in `after` but not `before` are `added`.\n * Items present in `before` but not `after` are `removed`.\n * Order-independent; uses deep equality by default.\n *\n * @example\n * ```ts\n * diffArrays([1, 2, 3], [2, 3, 4]); // { added: [4], removed: [1] }\n * diffArrays(\n * [{ id: 1 }, { id: 2 }],\n * [{ id: 2 }, { id: 3 }],\n * { compareFn: (a, b) => a.id === b.id },\n * ); // { added: [{ id: 3 }], removed: [{ id: 1 }] }\n * ```\n *\n * @param before - The original array.\n * @param after - The updated array.\n * @param [options.compareFn] - Custom equality function. Defaults to deep `isEqual`.\n * @returns An object with `added` and `removed` arrays.\n */\nexport function diffArrays<T>(before: T[], after: T[], options?: ArrayDiffOptions<T>): ArrayDiff<T> {\n const compareFn = options?.compareFn ?? ((a: T, b: T) => isEqual(a, b));\n\n return {\n added: after.filter((item) => !before.some((b) => compareFn(b, item))),\n removed: before.filter((item) => !after.some((a) => compareFn(item, a))),\n };\n}\n"],"mappings":"iFA+BA,SAAgB,EACd,EAAY,CAAC,EACb,EAAW,CAAC,EACZ,EAAiD,EAAA,QAClC,CACf,IAAM,EAAiC,CAAC,EAClC,EAAmC,CAAC,EACpC,EAA+D,CAAC,EAEhE,EAAa,IAAI,IAAI,OAAO,KAAK,CAAM,CAAC,EACxC,EAAY,IAAI,IAAI,OAAO,KAAK,CAAK,CAAC,EAE5C,IAAK,IAAM,KAAO,EACX,EAAW,IAAI,CAAG,EAEZ,CAAC,EAAA,YAAY,CAAG,GAAK,CAAC,EAAU,EAAO,GAAM,EAAM,EAAI,IAChE,EAAQ,GAAO,CAAE,MAAO,EAAM,GAAM,OAAQ,EAAO,EAAK,GAFxD,EAAM,KAAK,CAAuB,EAMtC,IAAK,IAAM,KAAO,EACX,EAAU,IAAI,CAAG,GACpB,EAAQ,KAAK,CAAuB,EAIxC,MAAO,CAAE,QAAgB,UAAqC,SAAQ,CACxE,CAgCA,SAAgB,EAAc,EAAa,EAAY,EAA6C,CAClG,IAAM,EAAY,GAAS,aAAe,EAAM,IAAS,EAAA,QAAQ,EAAG,CAAC,GAErE,MAAO,CACL,MAAO,EAAM,OAAQ,GAAS,CAAC,EAAO,KAAM,GAAM,EAAU,EAAG,CAAI,CAAC,CAAC,EACrE,QAAS,EAAO,OAAQ,GAAS,CAAC,EAAM,KAAM,GAAM,EAAU,EAAM,CAAC,CAAC,CAAC,CACzE,CACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"diff.d.ts","sourceRoot":"","sources":["../../src/object/diff.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAKpC,MAAM,MAAM,UAAU,CAAC,CAAC,SAAS,GAAG,IAAI;IACtC,mDAAmD;IACnD,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC;IAC/B,wFAAwF;IACxF,OAAO,EAAE;SAAG,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,EAAE;YAAE,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;YAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAA;SAAE;KAAE,CAAC;IAC5D,mDAAmD;IACnD,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC;CAClC,CAAC;AAEF;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,IAAI,CAAC,CAAC,SAAS,GAAG,EAChC,MAAM,GAAE,CAAW,EACnB,KAAK,GAAE,CAAW,EAClB,SAAS,GAAE,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,KAAK,OAAiB,GACvD,UAAU,CAAC,CAAC,CAAC,CAuBf;AAED,MAAM,MAAM,SAAS,CAAC,CAAC,IAAI;IACzB,KAAK,EAAE,CAAC,EAAE,CAAC;IACX,OAAO,EAAE,CAAC,EAAE,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,gBAAgB,CAAC,CAAC,IAAI;IAChC,SAAS,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,OAAO,CAAC;CACrC,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,OAAO,CAAC,EAAE,gBAAgB,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,CAOlG"}
1
+ {"version":3,"file":"diff.d.ts","sourceRoot":"","sources":["../../src/object/diff.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAEpC,MAAM,MAAM,UAAU,CAAC,CAAC,SAAS,GAAG,IAAI;IACtC,mDAAmD;IACnD,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC;IAC/B,wFAAwF;IACxF,OAAO,EAAE;SAAG,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,EAAE;YAAE,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;YAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAA;SAAE;KAAE,CAAC;IAC5D,mDAAmD;IACnD,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC;CAClC,CAAC;AAEF;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,IAAI,CAAC,CAAC,SAAS,GAAG,EAChC,MAAM,GAAE,CAAW,EACnB,KAAK,GAAE,CAAW,EAClB,SAAS,GAAE,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,KAAK,OAAiB,GACvD,UAAU,CAAC,CAAC,CAAC,CAuBf;AAED,MAAM,MAAM,SAAS,CAAC,CAAC,IAAI;IACzB,KAAK,EAAE,CAAC,EAAE,CAAC;IACX,OAAO,EAAE,CAAC,EAAE,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,gBAAgB,CAAC,CAAC,IAAI;IAChC,SAAS,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,OAAO,CAAC;CACrC,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,OAAO,CAAC,EAAE,gBAAgB,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,CAOlG"}
@@ -1 +1 @@
1
- {"version":3,"file":"diff.js","names":[],"sources":["../../src/object/diff.ts"],"sourcesContent":["import type { Obj } from '../types';\n\nimport { isUnsafeKey } from '../_common/unsafePaths';\nimport { isEqual } from '../guards/isEqual';\n\nexport type DiffResult<T extends Obj> = {\n /** Keys present in `after` but not in `before`. */\n added: Array<keyof T & string>;\n /** Keys present in both objects whose values differ. Maps key → `{ before, after }`. */\n changed: { [K in keyof T]?: { after: T[K]; before: T[K] } };\n /** Keys present in `before` but not in `after`. */\n removed: Array<keyof T & string>;\n};\n\n/**\n * Computes the structural difference between two plain objects.\n * Returns an `{ added, removed, changed }` result — no sentinel symbols needed.\n * Dangerous keys (`__proto__`, `constructor`, `prototype`) are omitted from `changed`.\n *\n * @example\n * ```ts\n * diff({ a: 1, b: 2, c: 3 }, { a: 1, b: 99 });\n * // { added: [], removed: ['c'], changed: { b: { before: 2, after: 99 } } }\n *\n * diff({ x: { n: 1 } }, { x: { n: 2 } });\n * // { added: [], removed: [], changed: { x: { before: { n: 1 }, after: { n: 2 } } } }\n * ```\n *\n * @param before - The original object.\n * @param after - The updated object.\n * @param compareFn - Custom equality function. Defaults to deep `isEqual`.\n */\nexport function diff<T extends Obj>(\n before: T = {} as T,\n after: T = {} as T,\n compareFn: (a: unknown, b: unknown) => boolean = isEqual,\n): DiffResult<T> {\n const added: Array<keyof T & string> = [];\n const removed: Array<keyof T & string> = [];\n const changed: Record<string, { after: unknown; before: unknown }> = {};\n\n const beforeKeys = new Set(Object.keys(before));\n const afterKeys = new Set(Object.keys(after));\n\n for (const key of afterKeys) {\n if (!beforeKeys.has(key)) {\n added.push(key as keyof T & string);\n } else if (!isUnsafeKey(key) && !compareFn(before[key], after[key])) {\n changed[key] = { after: after[key], before: before[key] };\n }\n }\n\n for (const key of beforeKeys) {\n if (!afterKeys.has(key)) {\n removed.push(key as keyof T & string);\n }\n }\n\n return { added, changed: changed as DiffResult<T>['changed'], removed };\n}\n\nexport type ArrayDiff<T> = {\n added: T[];\n removed: T[];\n};\n\nexport type ArrayDiffOptions<T> = {\n compareFn?: (a: T, b: T) => boolean;\n};\n\n/**\n * Computes the set-difference between two arrays.\n * Items present in `after` but not `before` are `added`.\n * Items present in `before` but not `after` are `removed`.\n * Order-independent; uses deep equality by default.\n *\n * @example\n * ```ts\n * diffArrays([1, 2, 3], [2, 3, 4]); // { added: [4], removed: [1] }\n * diffArrays(\n * [{ id: 1 }, { id: 2 }],\n * [{ id: 2 }, { id: 3 }],\n * { compareFn: (a, b) => a.id === b.id },\n * ); // { added: [{ id: 3 }], removed: [{ id: 1 }] }\n * ```\n *\n * @param before - The original array.\n * @param after - The updated array.\n * @param [options.compareFn] - Custom equality function. Defaults to deep `isEqual`.\n * @returns An object with `added` and `removed` arrays.\n */\nexport function diffArrays<T>(before: T[], after: T[], options?: ArrayDiffOptions<T>): ArrayDiff<T> {\n const compareFn = options?.compareFn ?? ((a: T, b: T) => isEqual(a, b));\n\n return {\n added: after.filter((item) => !before.some((b) => compareFn(b, item))),\n removed: before.filter((item) => !after.some((a) => compareFn(item, a))),\n };\n}\n"],"mappings":";;;AAgCA,SAAgB,EACd,IAAY,CAAC,GACb,IAAW,CAAC,GACZ,IAAiD,GAClC;CACf,IAAM,IAAiC,CAAC,GAClC,IAAmC,CAAC,GACpC,IAA+D,CAAC,GAEhE,IAAa,IAAI,IAAI,OAAO,KAAK,CAAM,CAAC,GACxC,IAAY,IAAI,IAAI,OAAO,KAAK,CAAK,CAAC;CAE5C,KAAK,IAAM,KAAO,GAChB,AAAK,EAAW,IAAI,CAAG,IAEZ,CAAC,EAAY,CAAG,KAAK,CAAC,EAAU,EAAO,IAAM,EAAM,EAAI,MAChE,EAAQ,KAAO;EAAE,OAAO,EAAM;EAAM,QAAQ,EAAO;CAAK,KAFxD,EAAM,KAAK,CAAuB;CAMtC,KAAK,IAAM,KAAO,GAChB,AAAK,EAAU,IAAI,CAAG,KACpB,EAAQ,KAAK,CAAuB;CAIxC,OAAO;EAAE;EAAgB;EAAqC;CAAQ;AACxE;AAgCA,SAAgB,EAAc,GAAa,GAAY,GAA6C;CAClG,IAAM,IAAY,GAAS,eAAe,GAAM,MAAS,EAAQ,GAAG,CAAC;CAErE,OAAO;EACL,OAAO,EAAM,QAAQ,MAAS,CAAC,EAAO,MAAM,MAAM,EAAU,GAAG,CAAI,CAAC,CAAC;EACrE,SAAS,EAAO,QAAQ,MAAS,CAAC,EAAM,MAAM,MAAM,EAAU,GAAM,CAAC,CAAC,CAAC;CACzE;AACF"}
1
+ {"version":3,"file":"diff.js","names":[],"sources":["../../src/object/diff.ts"],"sourcesContent":["import { isUnsafeKey } from '../_common/unsafePaths';\nimport { isEqual } from '../guards/isEqual';\nimport type { Obj } from '../types';\n\nexport type DiffResult<T extends Obj> = {\n /** Keys present in `after` but not in `before`. */\n added: Array<keyof T & string>;\n /** Keys present in both objects whose values differ. Maps key → `{ before, after }`. */\n changed: { [K in keyof T]?: { after: T[K]; before: T[K] } };\n /** Keys present in `before` but not in `after`. */\n removed: Array<keyof T & string>;\n};\n\n/**\n * Computes the structural difference between two plain objects.\n * Returns an `{ added, removed, changed }` result — no sentinel symbols needed.\n * Dangerous keys (`__proto__`, `constructor`, `prototype`) are omitted from `changed`.\n *\n * @example\n * ```ts\n * diff({ a: 1, b: 2, c: 3 }, { a: 1, b: 99 });\n * // { added: [], removed: ['c'], changed: { b: { before: 2, after: 99 } } }\n *\n * diff({ x: { n: 1 } }, { x: { n: 2 } });\n * // { added: [], removed: [], changed: { x: { before: { n: 1 }, after: { n: 2 } } } }\n * ```\n *\n * @param before - The original object.\n * @param after - The updated object.\n * @param compareFn - Custom equality function. Defaults to deep `isEqual`.\n */\nexport function diff<T extends Obj>(\n before: T = {} as T,\n after: T = {} as T,\n compareFn: (a: unknown, b: unknown) => boolean = isEqual,\n): DiffResult<T> {\n const added: Array<keyof T & string> = [];\n const removed: Array<keyof T & string> = [];\n const changed: Record<string, { after: unknown; before: unknown }> = {};\n\n const beforeKeys = new Set(Object.keys(before));\n const afterKeys = new Set(Object.keys(after));\n\n for (const key of afterKeys) {\n if (!beforeKeys.has(key)) {\n added.push(key as keyof T & string);\n } else if (!isUnsafeKey(key) && !compareFn(before[key], after[key])) {\n changed[key] = { after: after[key], before: before[key] };\n }\n }\n\n for (const key of beforeKeys) {\n if (!afterKeys.has(key)) {\n removed.push(key as keyof T & string);\n }\n }\n\n return { added, changed: changed as DiffResult<T>['changed'], removed };\n}\n\nexport type ArrayDiff<T> = {\n added: T[];\n removed: T[];\n};\n\nexport type ArrayDiffOptions<T> = {\n compareFn?: (a: T, b: T) => boolean;\n};\n\n/**\n * Computes the set-difference between two arrays.\n * Items present in `after` but not `before` are `added`.\n * Items present in `before` but not `after` are `removed`.\n * Order-independent; uses deep equality by default.\n *\n * @example\n * ```ts\n * diffArrays([1, 2, 3], [2, 3, 4]); // { added: [4], removed: [1] }\n * diffArrays(\n * [{ id: 1 }, { id: 2 }],\n * [{ id: 2 }, { id: 3 }],\n * { compareFn: (a, b) => a.id === b.id },\n * ); // { added: [{ id: 3 }], removed: [{ id: 1 }] }\n * ```\n *\n * @param before - The original array.\n * @param after - The updated array.\n * @param [options.compareFn] - Custom equality function. Defaults to deep `isEqual`.\n * @returns An object with `added` and `removed` arrays.\n */\nexport function diffArrays<T>(before: T[], after: T[], options?: ArrayDiffOptions<T>): ArrayDiff<T> {\n const compareFn = options?.compareFn ?? ((a: T, b: T) => isEqual(a, b));\n\n return {\n added: after.filter((item) => !before.some((b) => compareFn(b, item))),\n removed: before.filter((item) => !after.some((a) => compareFn(item, a))),\n };\n}\n"],"mappings":";;;AA+BA,SAAgB,EACd,IAAY,CAAC,GACb,IAAW,CAAC,GACZ,IAAiD,GAClC;CACf,IAAM,IAAiC,CAAC,GAClC,IAAmC,CAAC,GACpC,IAA+D,CAAC,GAEhE,IAAa,IAAI,IAAI,OAAO,KAAK,CAAM,CAAC,GACxC,IAAY,IAAI,IAAI,OAAO,KAAK,CAAK,CAAC;CAE5C,KAAK,IAAM,KAAO,GAChB,AAAK,EAAW,IAAI,CAAG,IAEZ,CAAC,EAAY,CAAG,KAAK,CAAC,EAAU,EAAO,IAAM,EAAM,EAAI,MAChE,EAAQ,KAAO;EAAE,OAAO,EAAM;EAAM,QAAQ,EAAO;CAAK,KAFxD,EAAM,KAAK,CAAuB;CAMtC,KAAK,IAAM,KAAO,GAChB,AAAK,EAAU,IAAI,CAAG,KACpB,EAAQ,KAAK,CAAuB;CAIxC,OAAO;EAAE;EAAgB;EAAqC;CAAQ;AACxE;AAgCA,SAAgB,EAAc,GAAa,GAAY,GAA6C;CAClG,IAAM,IAAY,GAAS,eAAe,GAAM,MAAS,EAAQ,GAAG,CAAC;CAErE,OAAO;EACL,OAAO,EAAM,QAAQ,MAAS,CAAC,EAAO,MAAM,MAAM,EAAU,GAAG,CAAI,CAAC,CAAC;EACrE,SAAS,EAAO,QAAQ,MAAS,CAAC,EAAM,MAAM,MAAM,EAAU,GAAM,CAAC,CAAC,CAAC;CACzE;AACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"filterValues.cjs","names":[],"sources":["../../src/object/filterValues.ts"],"sourcesContent":["import type { Obj } from '../types';\n\nimport { isUnsafeKey } from '../_common/unsafePaths';\n\n/**\n * Filters object entries using a value predicate. Dangerous keys (`__proto__`, `constructor`,\n * `prototype`) are always skipped.\n *\n * @example\n * ```ts\n * filterValues({ a: 1, b: 2, c: 3 }, (value) => value > 1); // { b: 2, c: 3 }\n * ```\n *\n * @param obj - The source object.\n * @param predicate - Returns `true` to keep an entry.\n * @returns A new object containing only entries for which `predicate` returned `true`.\n */\nexport function filterValues<T extends Obj>(\n obj: T,\n predicate: (value: T[keyof T], key: keyof T, obj: T) => boolean,\n): Partial<T> {\n const out: Partial<T> = {};\n\n for (const key of Object.keys(obj) as Array<keyof T>) {\n if (isUnsafeKey(key as PropertyKey)) continue;\n\n if (predicate(obj[key], key, obj)) {\n out[key] = obj[key];\n }\n }\n\n return out;\n}\n"],"mappings":"8CAiBA,SAAgB,EACd,EACA,EACY,CACZ,IAAM,EAAkB,CAAC,EAEzB,IAAK,IAAM,KAAO,OAAO,KAAK,CAAG,EAC3B,EAAA,YAAY,CAAkB,GAE9B,EAAU,EAAI,GAAM,EAAK,CAAG,IAC9B,EAAI,GAAO,EAAI,IAInB,OAAO,CACT"}
1
+ {"version":3,"file":"filterValues.cjs","names":[],"sources":["../../src/object/filterValues.ts"],"sourcesContent":["import { isUnsafeKey } from '../_common/unsafePaths';\nimport type { Obj } from '../types';\n\n/**\n * Filters object entries using a value predicate. Dangerous keys (`__proto__`, `constructor`,\n * `prototype`) are always skipped.\n *\n * @example\n * ```ts\n * filterValues({ a: 1, b: 2, c: 3 }, (value) => value > 1); // { b: 2, c: 3 }\n * ```\n *\n * @param obj - The source object.\n * @param predicate - Returns `true` to keep an entry.\n * @returns A new object containing only entries for which `predicate` returned `true`.\n */\nexport function filterValues<T extends Obj>(\n obj: T,\n predicate: (value: T[keyof T], key: keyof T, obj: T) => boolean,\n): Partial<T> {\n const out: Partial<T> = {};\n\n for (const key of Object.keys(obj) as Array<keyof T>) {\n if (isUnsafeKey(key as PropertyKey)) continue;\n\n if (predicate(obj[key], key, obj)) {\n out[key] = obj[key];\n }\n }\n\n return out;\n}\n"],"mappings":"8CAgBA,SAAgB,EACd,EACA,EACY,CACZ,IAAM,EAAkB,CAAC,EAEzB,IAAK,IAAM,KAAO,OAAO,KAAK,CAAG,EAC3B,EAAA,YAAY,CAAkB,GAE9B,EAAU,EAAI,GAAM,EAAK,CAAG,IAC9B,EAAI,GAAO,EAAI,IAInB,OAAO,CACT"}
@@ -1 +1 @@
1
- {"version":3,"file":"filterValues.d.ts","sourceRoot":"","sources":["../../src/object/filterValues.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAIpC;;;;;;;;;;;;GAYG;AACH,wBAAgB,YAAY,CAAC,CAAC,SAAS,GAAG,EACxC,GAAG,EAAE,CAAC,EACN,SAAS,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC,KAAK,OAAO,GAC9D,OAAO,CAAC,CAAC,CAAC,CAYZ"}
1
+ {"version":3,"file":"filterValues.d.ts","sourceRoot":"","sources":["../../src/object/filterValues.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAEpC;;;;;;;;;;;;GAYG;AACH,wBAAgB,YAAY,CAAC,CAAC,SAAS,GAAG,EACxC,GAAG,EAAE,CAAC,EACN,SAAS,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC,KAAK,OAAO,GAC9D,OAAO,CAAC,CAAC,CAAC,CAYZ"}
@@ -1 +1 @@
1
- {"version":3,"file":"filterValues.js","names":[],"sources":["../../src/object/filterValues.ts"],"sourcesContent":["import type { Obj } from '../types';\n\nimport { isUnsafeKey } from '../_common/unsafePaths';\n\n/**\n * Filters object entries using a value predicate. Dangerous keys (`__proto__`, `constructor`,\n * `prototype`) are always skipped.\n *\n * @example\n * ```ts\n * filterValues({ a: 1, b: 2, c: 3 }, (value) => value > 1); // { b: 2, c: 3 }\n * ```\n *\n * @param obj - The source object.\n * @param predicate - Returns `true` to keep an entry.\n * @returns A new object containing only entries for which `predicate` returned `true`.\n */\nexport function filterValues<T extends Obj>(\n obj: T,\n predicate: (value: T[keyof T], key: keyof T, obj: T) => boolean,\n): Partial<T> {\n const out: Partial<T> = {};\n\n for (const key of Object.keys(obj) as Array<keyof T>) {\n if (isUnsafeKey(key as PropertyKey)) continue;\n\n if (predicate(obj[key], key, obj)) {\n out[key] = obj[key];\n }\n }\n\n return out;\n}\n"],"mappings":";;AAiBA,SAAgB,EACd,GACA,GACY;CACZ,IAAM,IAAkB,CAAC;CAEzB,KAAK,IAAM,KAAO,OAAO,KAAK,CAAG,GAC3B,EAAY,CAAkB,KAE9B,EAAU,EAAI,IAAM,GAAK,CAAG,MAC9B,EAAI,KAAO,EAAI;CAInB,OAAO;AACT"}
1
+ {"version":3,"file":"filterValues.js","names":[],"sources":["../../src/object/filterValues.ts"],"sourcesContent":["import { isUnsafeKey } from '../_common/unsafePaths';\nimport type { Obj } from '../types';\n\n/**\n * Filters object entries using a value predicate. Dangerous keys (`__proto__`, `constructor`,\n * `prototype`) are always skipped.\n *\n * @example\n * ```ts\n * filterValues({ a: 1, b: 2, c: 3 }, (value) => value > 1); // { b: 2, c: 3 }\n * ```\n *\n * @param obj - The source object.\n * @param predicate - Returns `true` to keep an entry.\n * @returns A new object containing only entries for which `predicate` returned `true`.\n */\nexport function filterValues<T extends Obj>(\n obj: T,\n predicate: (value: T[keyof T], key: keyof T, obj: T) => boolean,\n): Partial<T> {\n const out: Partial<T> = {};\n\n for (const key of Object.keys(obj) as Array<keyof T>) {\n if (isUnsafeKey(key as PropertyKey)) continue;\n\n if (predicate(obj[key], key, obj)) {\n out[key] = obj[key];\n }\n }\n\n return out;\n}\n"],"mappings":";;AAgBA,SAAgB,EACd,GACA,GACY;CACZ,IAAM,IAAkB,CAAC;CAEzB,KAAK,IAAM,KAAO,OAAO,KAAK,CAAG,GAC3B,EAAY,CAAkB,KAE9B,EAAU,EAAI,IAAM,GAAK,CAAG,MAC9B,EAAI,KAAO,EAAI;CAInB,OAAO;AACT"}
@@ -1 +1 @@
1
- {"version":3,"file":"getPath.cjs","names":[],"sources":["../../src/object/getPath.ts"],"sourcesContent":["import type { Obj } from '../types';\n\nimport { UNSAFE_PATH_SEGMENTS } from '../_common/unsafePaths';\n\ntype PathValue<T, P extends string> = P extends `${infer Key}.${infer Rest}`\n ? Key extends keyof T\n ? PathValue<T[Key], Rest>\n : undefined\n : P extends keyof T\n ? T[P]\n : undefined;\n\nfunction pathSegments(path: string): string[] {\n return path\n .replace(/\\[(\\d+)\\]/g, '.$1')\n .replace(/^\\.|\\.$/g, '')\n .split('.')\n .filter(Boolean);\n}\n\nfunction readPath(item: Obj, path: string): unknown {\n let current: unknown = item;\n\n for (const segment of pathSegments(path)) {\n if (UNSAFE_PATH_SEGMENTS.has(segment) || current == null || typeof current !== 'object') return undefined;\n\n current = (current as Record<string, unknown>)[segment];\n\n if (current === undefined) return undefined;\n }\n\n return current;\n}\n\n/**\n * Retrieves a value at a dot-notation or numeric bracket-notation path.\n * Returns `undefined` when the path is missing or contains an unsafe segment.\n * Use `getPathOr` to supply a fallback or `requirePath` to throw on a missing path.\n */\nexport function getPath<T extends Obj, P extends string>(item: T, path: P): PathValue<T, P> | undefined {\n return readPath(item, path) as PathValue<T, P> | undefined;\n}\n\n/**\n * Retrieves a value at a path or returns `fallback` when the path is missing.\n */\nexport function getPathOr<T extends Obj, P extends string, F>(item: T, path: P, fallback: F): PathValue<T, P> | F {\n const value = readPath(item, path);\n\n return (value === undefined ? fallback : value) as PathValue<T, P> | F;\n}\n\n/**\n * Retrieves a value at a path or throws when the path is missing.\n */\nexport function requirePath<T extends Obj, P extends string>(item: T, path: P): Exclude<PathValue<T, P>, undefined> {\n const value = readPath(item, path);\n\n if (value === undefined) throw new TypeError(`Path does not exist: '${path}'`);\n\n return value as Exclude<PathValue<T, P>, undefined>;\n}\n"],"mappings":"8CAYA,SAAS,EAAa,EAAwB,CAC5C,OAAO,EACJ,QAAQ,aAAc,KAAK,CAAC,CAC5B,QAAQ,WAAY,EAAE,CAAC,CACvB,MAAM,GAAG,CAAC,CACV,OAAO,OAAO,CACnB,CAEA,SAAS,EAAS,EAAW,EAAuB,CAClD,IAAI,EAAmB,EAEvB,IAAK,IAAM,KAAW,EAAa,CAAI,EAKrC,GAJI,EAAA,qBAAqB,IAAI,CAAO,GAAwB,OAAO,GAAY,WAAtC,IAEzC,EAAW,EAAoC,GAE3C,IAAY,IAAA,IAAW,OAG7B,OAAO,CACT,CAOA,SAAgB,EAAyC,EAAS,EAAsC,CACtG,OAAO,EAAS,EAAM,CAAI,CAC5B,CAKA,SAAgB,EAA8C,EAAS,EAAS,EAAkC,CAChH,IAAM,EAAQ,EAAS,EAAM,CAAI,EAEjC,OAAQ,IAAU,IAAA,GAAY,EAAW,CAC3C,CAKA,SAAgB,EAA6C,EAAS,EAA8C,CAClH,IAAM,EAAQ,EAAS,EAAM,CAAI,EAEjC,GAAI,IAAU,IAAA,GAAW,MAAU,UAAU,yBAAyB,EAAK,EAAE,EAE7E,OAAO,CACT"}
1
+ {"version":3,"file":"getPath.cjs","names":[],"sources":["../../src/object/getPath.ts"],"sourcesContent":["import { UNSAFE_PATH_SEGMENTS } from '../_common/unsafePaths';\nimport type { Obj } from '../types';\n\ntype PathValue<T, P extends string> = P extends `${infer Key}.${infer Rest}`\n ? Key extends keyof T\n ? PathValue<T[Key], Rest>\n : undefined\n : P extends keyof T\n ? T[P]\n : undefined;\n\nfunction pathSegments(path: string): string[] {\n return path\n .replace(/\\[(\\d+)\\]/g, '.$1')\n .replace(/^\\.|\\.$/g, '')\n .split('.')\n .filter(Boolean);\n}\n\nfunction readPath(item: Obj, path: string): unknown {\n let current: unknown = item;\n\n for (const segment of pathSegments(path)) {\n if (UNSAFE_PATH_SEGMENTS.has(segment) || current == null || typeof current !== 'object') return undefined;\n\n current = (current as Record<string, unknown>)[segment];\n\n if (current === undefined) return undefined;\n }\n\n return current;\n}\n\n/**\n * Retrieves a value at a dot-notation or numeric bracket-notation path.\n * Returns `undefined` when the path is missing or contains an unsafe segment.\n * Use `getPathOr` to supply a fallback or `requirePath` to throw on a missing path.\n */\nexport function getPath<T extends Obj, P extends string>(item: T, path: P): PathValue<T, P> | undefined {\n return readPath(item, path) as PathValue<T, P> | undefined;\n}\n\n/**\n * Retrieves a value at a path or returns `fallback` when the path is missing.\n */\nexport function getPathOr<T extends Obj, P extends string, F>(item: T, path: P, fallback: F): PathValue<T, P> | F {\n const value = readPath(item, path);\n\n return (value === undefined ? fallback : value) as PathValue<T, P> | F;\n}\n\n/**\n * Retrieves a value at a path or throws when the path is missing.\n */\nexport function requirePath<T extends Obj, P extends string>(item: T, path: P): Exclude<PathValue<T, P>, undefined> {\n const value = readPath(item, path);\n\n if (value === undefined) throw new TypeError(`Path does not exist: '${path}'`);\n\n return value as Exclude<PathValue<T, P>, undefined>;\n}\n"],"mappings":"8CAWA,SAAS,EAAa,EAAwB,CAC5C,OAAO,EACJ,QAAQ,aAAc,KAAK,CAAC,CAC5B,QAAQ,WAAY,EAAE,CAAC,CACvB,MAAM,GAAG,CAAC,CACV,OAAO,OAAO,CACnB,CAEA,SAAS,EAAS,EAAW,EAAuB,CAClD,IAAI,EAAmB,EAEvB,IAAK,IAAM,KAAW,EAAa,CAAI,EAKrC,GAJI,EAAA,qBAAqB,IAAI,CAAO,GAAwB,OAAO,GAAY,WAAtC,IAEzC,EAAW,EAAoC,GAE3C,IAAY,IAAA,IAAW,OAG7B,OAAO,CACT,CAOA,SAAgB,EAAyC,EAAS,EAAsC,CACtG,OAAO,EAAS,EAAM,CAAI,CAC5B,CAKA,SAAgB,EAA8C,EAAS,EAAS,EAAkC,CAChH,IAAM,EAAQ,EAAS,EAAM,CAAI,EAEjC,OAAQ,IAAU,IAAA,GAAY,EAAW,CAC3C,CAKA,SAAgB,EAA6C,EAAS,EAA8C,CAClH,IAAM,EAAQ,EAAS,EAAM,CAAI,EAEjC,GAAI,IAAU,IAAA,GAAW,MAAU,UAAU,yBAAyB,EAAK,EAAE,EAE7E,OAAO,CACT"}
@@ -1 +1 @@
1
- {"version":3,"file":"getPath.d.ts","sourceRoot":"","sources":["../../src/object/getPath.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAIpC,KAAK,SAAS,CAAC,CAAC,EAAE,CAAC,SAAS,MAAM,IAAI,CAAC,SAAS,GAAG,MAAM,GAAG,IAAI,MAAM,IAAI,EAAE,GACxE,GAAG,SAAS,MAAM,CAAC,GACjB,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,GACvB,SAAS,GACX,CAAC,SAAS,MAAM,CAAC,GACf,CAAC,CAAC,CAAC,CAAC,GACJ,SAAS,CAAC;AAwBhB;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,CAAC,SAAS,GAAG,EAAE,CAAC,SAAS,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,GAAG,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,SAAS,CAEtG;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,CAAC,SAAS,GAAG,EAAE,CAAC,SAAS,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAIhH;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,GAAG,EAAE,CAAC,SAAS,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,SAAS,CAAC,CAMlH"}
1
+ {"version":3,"file":"getPath.d.ts","sourceRoot":"","sources":["../../src/object/getPath.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAEpC,KAAK,SAAS,CAAC,CAAC,EAAE,CAAC,SAAS,MAAM,IAAI,CAAC,SAAS,GAAG,MAAM,GAAG,IAAI,MAAM,IAAI,EAAE,GACxE,GAAG,SAAS,MAAM,CAAC,GACjB,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,GACvB,SAAS,GACX,CAAC,SAAS,MAAM,CAAC,GACf,CAAC,CAAC,CAAC,CAAC,GACJ,SAAS,CAAC;AAwBhB;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,CAAC,SAAS,GAAG,EAAE,CAAC,SAAS,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,GAAG,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,SAAS,CAEtG;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,CAAC,SAAS,GAAG,EAAE,CAAC,SAAS,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAIhH;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,GAAG,EAAE,CAAC,SAAS,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,SAAS,CAAC,CAMlH"}
@@ -1 +1 @@
1
- {"version":3,"file":"getPath.js","names":[],"sources":["../../src/object/getPath.ts"],"sourcesContent":["import type { Obj } from '../types';\n\nimport { UNSAFE_PATH_SEGMENTS } from '../_common/unsafePaths';\n\ntype PathValue<T, P extends string> = P extends `${infer Key}.${infer Rest}`\n ? Key extends keyof T\n ? PathValue<T[Key], Rest>\n : undefined\n : P extends keyof T\n ? T[P]\n : undefined;\n\nfunction pathSegments(path: string): string[] {\n return path\n .replace(/\\[(\\d+)\\]/g, '.$1')\n .replace(/^\\.|\\.$/g, '')\n .split('.')\n .filter(Boolean);\n}\n\nfunction readPath(item: Obj, path: string): unknown {\n let current: unknown = item;\n\n for (const segment of pathSegments(path)) {\n if (UNSAFE_PATH_SEGMENTS.has(segment) || current == null || typeof current !== 'object') return undefined;\n\n current = (current as Record<string, unknown>)[segment];\n\n if (current === undefined) return undefined;\n }\n\n return current;\n}\n\n/**\n * Retrieves a value at a dot-notation or numeric bracket-notation path.\n * Returns `undefined` when the path is missing or contains an unsafe segment.\n * Use `getPathOr` to supply a fallback or `requirePath` to throw on a missing path.\n */\nexport function getPath<T extends Obj, P extends string>(item: T, path: P): PathValue<T, P> | undefined {\n return readPath(item, path) as PathValue<T, P> | undefined;\n}\n\n/**\n * Retrieves a value at a path or returns `fallback` when the path is missing.\n */\nexport function getPathOr<T extends Obj, P extends string, F>(item: T, path: P, fallback: F): PathValue<T, P> | F {\n const value = readPath(item, path);\n\n return (value === undefined ? fallback : value) as PathValue<T, P> | F;\n}\n\n/**\n * Retrieves a value at a path or throws when the path is missing.\n */\nexport function requirePath<T extends Obj, P extends string>(item: T, path: P): Exclude<PathValue<T, P>, undefined> {\n const value = readPath(item, path);\n\n if (value === undefined) throw new TypeError(`Path does not exist: '${path}'`);\n\n return value as Exclude<PathValue<T, P>, undefined>;\n}\n"],"mappings":";;AAYA,SAAS,EAAa,GAAwB;CAC5C,OAAO,EACJ,QAAQ,cAAc,KAAK,CAAC,CAC5B,QAAQ,YAAY,EAAE,CAAC,CACvB,MAAM,GAAG,CAAC,CACV,OAAO,OAAO;AACnB;AAEA,SAAS,EAAS,GAAW,GAAuB;CAClD,IAAI,IAAmB;CAEvB,KAAK,IAAM,KAAW,EAAa,CAAI,GAKrC,IAJI,EAAqB,IAAI,CAAO,KAAwB,OAAO,KAAY,aAAtC,MAEzC,IAAW,EAAoC,IAE3C,MAAY,KAAA,IAAW;CAG7B,OAAO;AACT;AAOA,SAAgB,EAAyC,GAAS,GAAsC;CACtG,OAAO,EAAS,GAAM,CAAI;AAC5B;AAKA,SAAgB,EAA8C,GAAS,GAAS,GAAkC;CAChH,IAAM,IAAQ,EAAS,GAAM,CAAI;CAEjC,OAAQ,MAAU,KAAA,IAAY,IAAW;AAC3C;AAKA,SAAgB,EAA6C,GAAS,GAA8C;CAClH,IAAM,IAAQ,EAAS,GAAM,CAAI;CAEjC,IAAI,MAAU,KAAA,GAAW,MAAU,UAAU,yBAAyB,EAAK,EAAE;CAE7E,OAAO;AACT"}
1
+ {"version":3,"file":"getPath.js","names":[],"sources":["../../src/object/getPath.ts"],"sourcesContent":["import { UNSAFE_PATH_SEGMENTS } from '../_common/unsafePaths';\nimport type { Obj } from '../types';\n\ntype PathValue<T, P extends string> = P extends `${infer Key}.${infer Rest}`\n ? Key extends keyof T\n ? PathValue<T[Key], Rest>\n : undefined\n : P extends keyof T\n ? T[P]\n : undefined;\n\nfunction pathSegments(path: string): string[] {\n return path\n .replace(/\\[(\\d+)\\]/g, '.$1')\n .replace(/^\\.|\\.$/g, '')\n .split('.')\n .filter(Boolean);\n}\n\nfunction readPath(item: Obj, path: string): unknown {\n let current: unknown = item;\n\n for (const segment of pathSegments(path)) {\n if (UNSAFE_PATH_SEGMENTS.has(segment) || current == null || typeof current !== 'object') return undefined;\n\n current = (current as Record<string, unknown>)[segment];\n\n if (current === undefined) return undefined;\n }\n\n return current;\n}\n\n/**\n * Retrieves a value at a dot-notation or numeric bracket-notation path.\n * Returns `undefined` when the path is missing or contains an unsafe segment.\n * Use `getPathOr` to supply a fallback or `requirePath` to throw on a missing path.\n */\nexport function getPath<T extends Obj, P extends string>(item: T, path: P): PathValue<T, P> | undefined {\n return readPath(item, path) as PathValue<T, P> | undefined;\n}\n\n/**\n * Retrieves a value at a path or returns `fallback` when the path is missing.\n */\nexport function getPathOr<T extends Obj, P extends string, F>(item: T, path: P, fallback: F): PathValue<T, P> | F {\n const value = readPath(item, path);\n\n return (value === undefined ? fallback : value) as PathValue<T, P> | F;\n}\n\n/**\n * Retrieves a value at a path or throws when the path is missing.\n */\nexport function requirePath<T extends Obj, P extends string>(item: T, path: P): Exclude<PathValue<T, P>, undefined> {\n const value = readPath(item, path);\n\n if (value === undefined) throw new TypeError(`Path does not exist: '${path}'`);\n\n return value as Exclude<PathValue<T, P>, undefined>;\n}\n"],"mappings":";;AAWA,SAAS,EAAa,GAAwB;CAC5C,OAAO,EACJ,QAAQ,cAAc,KAAK,CAAC,CAC5B,QAAQ,YAAY,EAAE,CAAC,CACvB,MAAM,GAAG,CAAC,CACV,OAAO,OAAO;AACnB;AAEA,SAAS,EAAS,GAAW,GAAuB;CAClD,IAAI,IAAmB;CAEvB,KAAK,IAAM,KAAW,EAAa,CAAI,GAKrC,IAJI,EAAqB,IAAI,CAAO,KAAwB,OAAO,KAAY,aAAtC,MAEzC,IAAW,EAAoC,IAE3C,MAAY,KAAA,IAAW;CAG7B,OAAO;AACT;AAOA,SAAgB,EAAyC,GAAS,GAAsC;CACtG,OAAO,EAAS,GAAM,CAAI;AAC5B;AAKA,SAAgB,EAA8C,GAAS,GAAS,GAAkC;CAChH,IAAM,IAAQ,EAAS,GAAM,CAAI;CAEjC,OAAQ,MAAU,KAAA,IAAY,IAAW;AAC3C;AAKA,SAAgB,EAA6C,GAAS,GAA8C;CAClH,IAAM,IAAQ,EAAS,GAAM,CAAI;CAEjC,IAAI,MAAU,KAAA,GAAW,MAAU,UAAU,yBAAyB,EAAK,EAAE;CAE7E,OAAO;AACT"}
@@ -1 +1 @@
1
- {"version":3,"file":"mapKeys.cjs","names":[],"sources":["../../src/object/mapKeys.ts"],"sourcesContent":["import type { Obj } from '../types';\n\nimport { isUnsafeKey } from '../_common/unsafePaths';\n\n/**\n * Maps object keys while preserving values. Both the original key and any mapped key that\n * resolve to a dangerous key (`__proto__`, `constructor`, `prototype`) are skipped.\n *\n * @example\n * ```ts\n * mapKeys({ a: 1, b: 2 }, (key) => `x_${String(key)}`); // { x_a: 1, x_b: 2 }\n * ```\n *\n * @param obj - The source object.\n * @param mapper - Function producing the new key for each entry.\n * @returns A new object with mapped keys and the original values.\n */\nexport function mapKeys<T extends Obj>(\n obj: T,\n mapper: (key: keyof T, value: T[keyof T], obj: T) => PropertyKey,\n): Record<PropertyKey, T[keyof T]> {\n const out: Record<PropertyKey, T[keyof T]> = {};\n\n for (const key of Object.keys(obj) as Array<keyof T>) {\n if (isUnsafeKey(key as PropertyKey)) continue;\n\n const mappedKey = mapper(key, obj[key], obj);\n\n if (isUnsafeKey(mappedKey)) continue;\n\n out[mappedKey] = obj[key];\n }\n\n return out;\n}\n"],"mappings":"8CAiBA,SAAgB,EACd,EACA,EACiC,CACjC,IAAM,EAAuC,CAAC,EAE9C,IAAK,IAAM,KAAO,OAAO,KAAK,CAAG,EAAqB,CACpD,GAAI,EAAA,YAAY,CAAkB,EAAG,SAErC,IAAM,EAAY,EAAO,EAAK,EAAI,GAAM,CAAG,EAEvC,EAAA,YAAY,CAAS,IAEzB,EAAI,GAAa,EAAI,GACvB,CAEA,OAAO,CACT"}
1
+ {"version":3,"file":"mapKeys.cjs","names":[],"sources":["../../src/object/mapKeys.ts"],"sourcesContent":["import { isUnsafeKey } from '../_common/unsafePaths';\nimport type { Obj } from '../types';\n\n/**\n * Maps object keys while preserving values. Both the original key and any mapped key that\n * resolve to a dangerous key (`__proto__`, `constructor`, `prototype`) are skipped.\n *\n * @example\n * ```ts\n * mapKeys({ a: 1, b: 2 }, (key) => `x_${String(key)}`); // { x_a: 1, x_b: 2 }\n * ```\n *\n * @param obj - The source object.\n * @param mapper - Function producing the new key for each entry.\n * @returns A new object with mapped keys and the original values.\n */\nexport function mapKeys<T extends Obj>(\n obj: T,\n mapper: (key: keyof T, value: T[keyof T], obj: T) => PropertyKey,\n): Record<PropertyKey, T[keyof T]> {\n const out: Record<PropertyKey, T[keyof T]> = {};\n\n for (const key of Object.keys(obj) as Array<keyof T>) {\n if (isUnsafeKey(key as PropertyKey)) continue;\n\n const mappedKey = mapper(key, obj[key], obj);\n\n if (isUnsafeKey(mappedKey)) continue;\n\n out[mappedKey] = obj[key];\n }\n\n return out;\n}\n"],"mappings":"8CAgBA,SAAgB,EACd,EACA,EACiC,CACjC,IAAM,EAAuC,CAAC,EAE9C,IAAK,IAAM,KAAO,OAAO,KAAK,CAAG,EAAqB,CACpD,GAAI,EAAA,YAAY,CAAkB,EAAG,SAErC,IAAM,EAAY,EAAO,EAAK,EAAI,GAAM,CAAG,EAEvC,EAAA,YAAY,CAAS,IAEzB,EAAI,GAAa,EAAI,GACvB,CAEA,OAAO,CACT"}
@@ -1 +1 @@
1
- {"version":3,"file":"mapKeys.d.ts","sourceRoot":"","sources":["../../src/object/mapKeys.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAIpC;;;;;;;;;;;;GAYG;AACH,wBAAgB,OAAO,CAAC,CAAC,SAAS,GAAG,EACnC,GAAG,EAAE,CAAC,EACN,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,KAAK,WAAW,GAC/D,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAcjC"}
1
+ {"version":3,"file":"mapKeys.d.ts","sourceRoot":"","sources":["../../src/object/mapKeys.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAEpC;;;;;;;;;;;;GAYG;AACH,wBAAgB,OAAO,CAAC,CAAC,SAAS,GAAG,EACnC,GAAG,EAAE,CAAC,EACN,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,KAAK,WAAW,GAC/D,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAcjC"}
@@ -1 +1 @@
1
- {"version":3,"file":"mapKeys.js","names":[],"sources":["../../src/object/mapKeys.ts"],"sourcesContent":["import type { Obj } from '../types';\n\nimport { isUnsafeKey } from '../_common/unsafePaths';\n\n/**\n * Maps object keys while preserving values. Both the original key and any mapped key that\n * resolve to a dangerous key (`__proto__`, `constructor`, `prototype`) are skipped.\n *\n * @example\n * ```ts\n * mapKeys({ a: 1, b: 2 }, (key) => `x_${String(key)}`); // { x_a: 1, x_b: 2 }\n * ```\n *\n * @param obj - The source object.\n * @param mapper - Function producing the new key for each entry.\n * @returns A new object with mapped keys and the original values.\n */\nexport function mapKeys<T extends Obj>(\n obj: T,\n mapper: (key: keyof T, value: T[keyof T], obj: T) => PropertyKey,\n): Record<PropertyKey, T[keyof T]> {\n const out: Record<PropertyKey, T[keyof T]> = {};\n\n for (const key of Object.keys(obj) as Array<keyof T>) {\n if (isUnsafeKey(key as PropertyKey)) continue;\n\n const mappedKey = mapper(key, obj[key], obj);\n\n if (isUnsafeKey(mappedKey)) continue;\n\n out[mappedKey] = obj[key];\n }\n\n return out;\n}\n"],"mappings":";;AAiBA,SAAgB,EACd,GACA,GACiC;CACjC,IAAM,IAAuC,CAAC;CAE9C,KAAK,IAAM,KAAO,OAAO,KAAK,CAAG,GAAqB;EACpD,IAAI,EAAY,CAAkB,GAAG;EAErC,IAAM,IAAY,EAAO,GAAK,EAAI,IAAM,CAAG;EAEvC,EAAY,CAAS,MAEzB,EAAI,KAAa,EAAI;CACvB;CAEA,OAAO;AACT"}
1
+ {"version":3,"file":"mapKeys.js","names":[],"sources":["../../src/object/mapKeys.ts"],"sourcesContent":["import { isUnsafeKey } from '../_common/unsafePaths';\nimport type { Obj } from '../types';\n\n/**\n * Maps object keys while preserving values. Both the original key and any mapped key that\n * resolve to a dangerous key (`__proto__`, `constructor`, `prototype`) are skipped.\n *\n * @example\n * ```ts\n * mapKeys({ a: 1, b: 2 }, (key) => `x_${String(key)}`); // { x_a: 1, x_b: 2 }\n * ```\n *\n * @param obj - The source object.\n * @param mapper - Function producing the new key for each entry.\n * @returns A new object with mapped keys and the original values.\n */\nexport function mapKeys<T extends Obj>(\n obj: T,\n mapper: (key: keyof T, value: T[keyof T], obj: T) => PropertyKey,\n): Record<PropertyKey, T[keyof T]> {\n const out: Record<PropertyKey, T[keyof T]> = {};\n\n for (const key of Object.keys(obj) as Array<keyof T>) {\n if (isUnsafeKey(key as PropertyKey)) continue;\n\n const mappedKey = mapper(key, obj[key], obj);\n\n if (isUnsafeKey(mappedKey)) continue;\n\n out[mappedKey] = obj[key];\n }\n\n return out;\n}\n"],"mappings":";;AAgBA,SAAgB,EACd,GACA,GACiC;CACjC,IAAM,IAAuC,CAAC;CAE9C,KAAK,IAAM,KAAO,OAAO,KAAK,CAAG,GAAqB;EACpD,IAAI,EAAY,CAAkB,GAAG;EAErC,IAAM,IAAY,EAAO,GAAK,EAAI,IAAM,CAAG;EAEvC,EAAY,CAAS,MAEzB,EAAI,KAAa,EAAI;CACvB;CAEA,OAAO;AACT"}
@@ -1 +1 @@
1
- {"version":3,"file":"mapValues.cjs","names":[],"sources":["../../src/object/mapValues.ts"],"sourcesContent":["import type { Obj } from '../types';\n\nimport { isUnsafeKey } from '../_common/unsafePaths';\n\n/**\n * Maps object values while preserving the original keys. Dangerous keys (`__proto__`,\n * `constructor`, `prototype`) are always skipped.\n *\n * @example\n * ```ts\n * mapValues({ a: 1, b: 2 }, (value) => value * 2); // { a: 2, b: 4 }\n * ```\n *\n * @param obj - The source object.\n * @param mapper - Function producing the new value for each entry.\n * @returns A new object with the same keys and mapped values.\n */\nexport function mapValues<T extends Obj, R>(\n obj: T,\n mapper: (value: T[keyof T], key: keyof T, obj: T) => R,\n): { [K in keyof T]: R } {\n const out = {} as { [K in keyof T]: R };\n\n for (const key of Object.keys(obj) as Array<keyof T>) {\n if (isUnsafeKey(key as PropertyKey)) continue;\n\n out[key] = mapper(obj[key], key, obj);\n }\n\n return out;\n}\n"],"mappings":"8CAiBA,SAAgB,EACd,EACA,EACuB,CACvB,IAAM,EAAM,CAAC,EAEb,IAAK,IAAM,KAAO,OAAO,KAAK,CAAG,EAC3B,EAAA,YAAY,CAAkB,IAElC,EAAI,GAAO,EAAO,EAAI,GAAM,EAAK,CAAG,GAGtC,OAAO,CACT"}
1
+ {"version":3,"file":"mapValues.cjs","names":[],"sources":["../../src/object/mapValues.ts"],"sourcesContent":["import { isUnsafeKey } from '../_common/unsafePaths';\nimport type { Obj } from '../types';\n\n/**\n * Maps object values while preserving the original keys. Dangerous keys (`__proto__`,\n * `constructor`, `prototype`) are always skipped.\n *\n * @example\n * ```ts\n * mapValues({ a: 1, b: 2 }, (value) => value * 2); // { a: 2, b: 4 }\n * ```\n *\n * @param obj - The source object.\n * @param mapper - Function producing the new value for each entry.\n * @returns A new object with the same keys and mapped values.\n */\nexport function mapValues<T extends Obj, R>(\n obj: T,\n mapper: (value: T[keyof T], key: keyof T, obj: T) => R,\n): { [K in keyof T]: R } {\n const out = {} as { [K in keyof T]: R };\n\n for (const key of Object.keys(obj) as Array<keyof T>) {\n if (isUnsafeKey(key as PropertyKey)) continue;\n\n out[key] = mapper(obj[key], key, obj);\n }\n\n return out;\n}\n"],"mappings":"8CAgBA,SAAgB,EACd,EACA,EACuB,CACvB,IAAM,EAAM,CAAC,EAEb,IAAK,IAAM,KAAO,OAAO,KAAK,CAAG,EAC3B,EAAA,YAAY,CAAkB,IAElC,EAAI,GAAO,EAAO,EAAI,GAAM,EAAK,CAAG,GAGtC,OAAO,CACT"}
@@ -1 +1 @@
1
- {"version":3,"file":"mapValues.d.ts","sourceRoot":"","sources":["../../src/object/mapValues.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAIpC;;;;;;;;;;;;GAYG;AACH,wBAAgB,SAAS,CAAC,CAAC,SAAS,GAAG,EAAE,CAAC,EACxC,GAAG,EAAE,CAAC,EACN,MAAM,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,GACrD;KAAG,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC;CAAE,CAUvB"}
1
+ {"version":3,"file":"mapValues.d.ts","sourceRoot":"","sources":["../../src/object/mapValues.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAEpC;;;;;;;;;;;;GAYG;AACH,wBAAgB,SAAS,CAAC,CAAC,SAAS,GAAG,EAAE,CAAC,EACxC,GAAG,EAAE,CAAC,EACN,MAAM,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,GACrD;KAAG,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC;CAAE,CAUvB"}
@@ -1 +1 @@
1
- {"version":3,"file":"mapValues.js","names":[],"sources":["../../src/object/mapValues.ts"],"sourcesContent":["import type { Obj } from '../types';\n\nimport { isUnsafeKey } from '../_common/unsafePaths';\n\n/**\n * Maps object values while preserving the original keys. Dangerous keys (`__proto__`,\n * `constructor`, `prototype`) are always skipped.\n *\n * @example\n * ```ts\n * mapValues({ a: 1, b: 2 }, (value) => value * 2); // { a: 2, b: 4 }\n * ```\n *\n * @param obj - The source object.\n * @param mapper - Function producing the new value for each entry.\n * @returns A new object with the same keys and mapped values.\n */\nexport function mapValues<T extends Obj, R>(\n obj: T,\n mapper: (value: T[keyof T], key: keyof T, obj: T) => R,\n): { [K in keyof T]: R } {\n const out = {} as { [K in keyof T]: R };\n\n for (const key of Object.keys(obj) as Array<keyof T>) {\n if (isUnsafeKey(key as PropertyKey)) continue;\n\n out[key] = mapper(obj[key], key, obj);\n }\n\n return out;\n}\n"],"mappings":";;AAiBA,SAAgB,EACd,GACA,GACuB;CACvB,IAAM,IAAM,CAAC;CAEb,KAAK,IAAM,KAAO,OAAO,KAAK,CAAG,GAC3B,EAAY,CAAkB,MAElC,EAAI,KAAO,EAAO,EAAI,IAAM,GAAK,CAAG;CAGtC,OAAO;AACT"}
1
+ {"version":3,"file":"mapValues.js","names":[],"sources":["../../src/object/mapValues.ts"],"sourcesContent":["import { isUnsafeKey } from '../_common/unsafePaths';\nimport type { Obj } from '../types';\n\n/**\n * Maps object values while preserving the original keys. Dangerous keys (`__proto__`,\n * `constructor`, `prototype`) are always skipped.\n *\n * @example\n * ```ts\n * mapValues({ a: 1, b: 2 }, (value) => value * 2); // { a: 2, b: 4 }\n * ```\n *\n * @param obj - The source object.\n * @param mapper - Function producing the new value for each entry.\n * @returns A new object with the same keys and mapped values.\n */\nexport function mapValues<T extends Obj, R>(\n obj: T,\n mapper: (value: T[keyof T], key: keyof T, obj: T) => R,\n): { [K in keyof T]: R } {\n const out = {} as { [K in keyof T]: R };\n\n for (const key of Object.keys(obj) as Array<keyof T>) {\n if (isUnsafeKey(key as PropertyKey)) continue;\n\n out[key] = mapper(obj[key], key, obj);\n }\n\n return out;\n}\n"],"mappings":";;AAgBA,SAAgB,EACd,GACA,GACuB;CACvB,IAAM,IAAM,CAAC;CAEb,KAAK,IAAM,KAAO,OAAO,KAAK,CAAG,GAC3B,EAAY,CAAkB,MAElC,EAAI,KAAO,EAAO,EAAI,IAAM,GAAK,CAAG;CAGtC,OAAO;AACT"}
@@ -1 +1 @@
1
- {"version":3,"file":"merge.cjs","names":[],"sources":["../../src/object/merge.ts"],"sourcesContent":["import type { Obj } from '../types';\n\nimport { isUnsafeKey } from '../_common/unsafePaths';\nimport { isPlainObject } from '../guards/isPlainObject';\n\nexport type DeepMergeOptions = {\n /** How to handle arrays when both source and target contain one. Default: `'replace'`. */\n arrayStrategy?: 'concat' | 'replace';\n};\n\ntype DeepMerge<T, U> = T extends Obj\n ? U extends Obj\n ? {\n [K in keyof T | keyof U]: K extends keyof T\n ? K extends keyof U\n ? DeepMerge<T[K], U[K]>\n : T[K]\n : K extends keyof U\n ? U[K]\n : never;\n }\n : U\n : U;\n\ntype Merge<T extends Obj[]> = T extends [infer First, ...infer Rest]\n ? First extends Obj\n ? Rest extends Obj[]\n ? DeepMerge<First, Merge<Rest>>\n : First\n : Obj\n : Obj;\n\nfunction mergeObjects<T extends Obj, U extends Obj>(target: T, source: U, options: DeepMergeOptions): DeepMerge<T, U> {\n if (!isPlainObject(source)) return source as DeepMerge<T, U>;\n\n const result = { ...target } as DeepMerge<T, U>;\n\n for (const key of Object.keys(source)) {\n // Guard against prototype pollution: skip dangerous keys\n if (isUnsafeKey(key)) {\n continue;\n }\n\n const sourceValue = source[key];\n const targetValue = result[key];\n\n (result as Record<string, unknown>)[key] =\n Array.isArray(sourceValue) && Array.isArray(targetValue)\n ? options.arrayStrategy === 'concat'\n ? [...targetValue, ...sourceValue]\n : sourceValue\n : isPlainObject(sourceValue) && isPlainObject(targetValue)\n ? mergeObjects(targetValue as Obj, sourceValue as Obj, options)\n : sourceValue;\n }\n\n return result;\n}\n\n/**\n * Deeply merges two or more objects. Arrays in source objects **replace** the target array by default.\n * Pass `{ arrayStrategy: 'concat' }` as the last argument to concatenate arrays instead.\n *\n * @example\n * ```ts\n * deepMerge({ a: 1, b: { x: 1 } }, { b: { y: 2 }, c: 3 });\n * // { a: 1, b: { x: 1, y: 2 }, c: 3 }\n *\n * deepMerge({ tags: ['a'] }, { tags: ['b'] });\n * // { tags: ['b'] } ← arrays replaced\n *\n * deepMerge({ tags: ['a'] }, { tags: ['b'] }, { arrayStrategy: 'concat' });\n * // { tags: ['a', 'b'] }\n * ```\n */\nexport function deepMerge<T extends Obj[]>(items: readonly [...T], options: DeepMergeOptions = {}): Merge<T> {\n return items.reduce((acc: Obj, item) => mergeObjects(acc, item, options) as Obj, {} as Obj) as Merge<T>;\n}\n\n/**\n * Shallowly merges two or more objects. Later sources win for duplicate keys.\n * Dangerous keys (`__proto__`, `constructor`, `prototype`) are always skipped.\n *\n * @example\n * ```ts\n * shallowMerge({ a: 1, b: { x: 1 } }, { b: { y: 2 } });\n * // { a: 1, b: { y: 2 } } ← nested object replaced, not merged\n *\n * shallowMerge(defaults, overrides, extras);\n * ```\n */\nexport function shallowMerge<T extends Obj[]>(...items: [...T]): Merge<T> {\n if (items.length === 0) return {} as Merge<T>;\n\n const result: Obj = {};\n\n for (const item of items) {\n for (const key of Object.keys(item)) {\n if (isUnsafeKey(key)) continue;\n\n result[key] = item[key];\n }\n }\n\n return result as Merge<T>;\n}\n"],"mappings":"uFAgCA,SAAS,EAA2C,EAAW,EAAW,EAA4C,CACpH,GAAI,CAAC,EAAA,cAAc,CAAM,EAAG,OAAO,EAEnC,IAAM,EAAS,CAAE,GAAG,CAAO,EAE3B,IAAK,IAAM,KAAO,OAAO,KAAK,CAAM,EAAG,CAErC,GAAI,EAAA,YAAY,CAAG,EACjB,SAGF,IAAM,EAAc,EAAO,GACrB,EAAc,EAAO,GAE3B,EAAoC,GAClC,MAAM,QAAQ,CAAW,GAAK,MAAM,QAAQ,CAAW,EACnD,EAAQ,gBAAkB,SACxB,CAAC,GAAG,EAAa,GAAG,CAAW,EAC/B,EACF,EAAA,cAAc,CAAW,GAAK,EAAA,cAAc,CAAW,EACrD,EAAa,EAAoB,EAAoB,CAAO,EAC5D,CACV,CAEA,OAAO,CACT,CAkBA,SAAgB,EAA2B,EAAwB,EAA4B,CAAC,EAAa,CAC3G,OAAO,EAAM,QAAQ,EAAU,IAAS,EAAa,EAAK,EAAM,CAAO,EAAU,CAAC,CAAQ,CAC5F,CAcA,SAAgB,EAA8B,GAAG,EAAyB,CACxE,GAAI,EAAM,SAAW,EAAG,MAAO,CAAC,EAEhC,IAAM,EAAc,CAAC,EAErB,IAAK,IAAM,KAAQ,EACjB,IAAK,IAAM,KAAO,OAAO,KAAK,CAAI,EAC5B,EAAA,YAAY,CAAG,IAEnB,EAAO,GAAO,EAAK,IAIvB,OAAO,CACT"}
1
+ {"version":3,"file":"merge.cjs","names":[],"sources":["../../src/object/merge.ts"],"sourcesContent":["import { isUnsafeKey } from '../_common/unsafePaths';\nimport { isPlainObject } from '../guards/isPlainObject';\nimport type { Obj } from '../types';\n\nexport type DeepMergeOptions = {\n /** How to handle arrays when both source and target contain one. Default: `'replace'`. */\n arrayStrategy?: 'concat' | 'replace';\n};\n\ntype DeepMerge<T, U> = T extends Obj\n ? U extends Obj\n ? {\n [K in keyof T | keyof U]: K extends keyof T\n ? K extends keyof U\n ? DeepMerge<T[K], U[K]>\n : T[K]\n : K extends keyof U\n ? U[K]\n : never;\n }\n : U\n : U;\n\ntype Merge<T extends Obj[]> = T extends [infer First, ...infer Rest]\n ? First extends Obj\n ? Rest extends Obj[]\n ? DeepMerge<First, Merge<Rest>>\n : First\n : Obj\n : Obj;\n\nfunction mergeObjects<T extends Obj, U extends Obj>(target: T, source: U, options: DeepMergeOptions): DeepMerge<T, U> {\n if (!isPlainObject(source)) return source as DeepMerge<T, U>;\n\n const result = { ...target } as DeepMerge<T, U>;\n\n for (const key of Object.keys(source)) {\n // Guard against prototype pollution: skip dangerous keys\n if (isUnsafeKey(key)) {\n continue;\n }\n\n const sourceValue = source[key];\n const targetValue = result[key];\n\n (result as Record<string, unknown>)[key] =\n Array.isArray(sourceValue) && Array.isArray(targetValue)\n ? options.arrayStrategy === 'concat'\n ? [...targetValue, ...sourceValue]\n : sourceValue\n : isPlainObject(sourceValue) && isPlainObject(targetValue)\n ? mergeObjects(targetValue as Obj, sourceValue as Obj, options)\n : sourceValue;\n }\n\n return result;\n}\n\n/**\n * Deeply merges two or more objects. Arrays in source objects **replace** the target array by default.\n * Pass `{ arrayStrategy: 'concat' }` as the last argument to concatenate arrays instead.\n *\n * @example\n * ```ts\n * deepMerge({ a: 1, b: { x: 1 } }, { b: { y: 2 }, c: 3 });\n * // { a: 1, b: { x: 1, y: 2 }, c: 3 }\n *\n * deepMerge({ tags: ['a'] }, { tags: ['b'] });\n * // { tags: ['b'] } ← arrays replaced\n *\n * deepMerge({ tags: ['a'] }, { tags: ['b'] }, { arrayStrategy: 'concat' });\n * // { tags: ['a', 'b'] }\n * ```\n */\nexport function deepMerge<T extends Obj[]>(items: readonly [...T], options: DeepMergeOptions = {}): Merge<T> {\n return items.reduce((acc: Obj, item) => mergeObjects(acc, item, options) as Obj, {} as Obj) as Merge<T>;\n}\n\n/**\n * Shallowly merges two or more objects. Later sources win for duplicate keys.\n * Dangerous keys (`__proto__`, `constructor`, `prototype`) are always skipped.\n *\n * @example\n * ```ts\n * shallowMerge({ a: 1, b: { x: 1 } }, { b: { y: 2 } });\n * // { a: 1, b: { y: 2 } } ← nested object replaced, not merged\n *\n * shallowMerge(defaults, overrides, extras);\n * ```\n */\nexport function shallowMerge<T extends Obj[]>(...items: [...T]): Merge<T> {\n if (items.length === 0) return {} as Merge<T>;\n\n const result: Obj = {};\n\n for (const item of items) {\n for (const key of Object.keys(item)) {\n if (isUnsafeKey(key)) continue;\n\n result[key] = item[key];\n }\n }\n\n return result as Merge<T>;\n}\n"],"mappings":"uFA+BA,SAAS,EAA2C,EAAW,EAAW,EAA4C,CACpH,GAAI,CAAC,EAAA,cAAc,CAAM,EAAG,OAAO,EAEnC,IAAM,EAAS,CAAE,GAAG,CAAO,EAE3B,IAAK,IAAM,KAAO,OAAO,KAAK,CAAM,EAAG,CAErC,GAAI,EAAA,YAAY,CAAG,EACjB,SAGF,IAAM,EAAc,EAAO,GACrB,EAAc,EAAO,GAE3B,EAAoC,GAClC,MAAM,QAAQ,CAAW,GAAK,MAAM,QAAQ,CAAW,EACnD,EAAQ,gBAAkB,SACxB,CAAC,GAAG,EAAa,GAAG,CAAW,EAC/B,EACF,EAAA,cAAc,CAAW,GAAK,EAAA,cAAc,CAAW,EACrD,EAAa,EAAoB,EAAoB,CAAO,EAC5D,CACV,CAEA,OAAO,CACT,CAkBA,SAAgB,EAA2B,EAAwB,EAA4B,CAAC,EAAa,CAC3G,OAAO,EAAM,QAAQ,EAAU,IAAS,EAAa,EAAK,EAAM,CAAO,EAAU,CAAC,CAAQ,CAC5F,CAcA,SAAgB,EAA8B,GAAG,EAAyB,CACxE,GAAI,EAAM,SAAW,EAAG,MAAO,CAAC,EAEhC,IAAM,EAAc,CAAC,EAErB,IAAK,IAAM,KAAQ,EACjB,IAAK,IAAM,KAAO,OAAO,KAAK,CAAI,EAC5B,EAAA,YAAY,CAAG,IAEnB,EAAO,GAAO,EAAK,IAIvB,OAAO,CACT"}
@@ -1 +1 @@
1
- {"version":3,"file":"merge.d.ts","sourceRoot":"","sources":["../../src/object/merge.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAKpC,MAAM,MAAM,gBAAgB,GAAG;IAC7B,0FAA0F;IAC1F,aAAa,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAC;CACtC,CAAC;AAEF,KAAK,SAAS,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,GAAG,GAChC,CAAC,SAAS,GAAG,GACX;KACG,CAAC,IAAI,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,SAAS,MAAM,CAAC,GACvC,CAAC,SAAS,MAAM,CAAC,GACf,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GACrB,CAAC,CAAC,CAAC,CAAC,GACN,CAAC,SAAS,MAAM,CAAC,GACf,CAAC,CAAC,CAAC,CAAC,GACJ,KAAK;CACZ,GACD,CAAC,GACH,CAAC,CAAC;AAEN,KAAK,KAAK,CAAC,CAAC,SAAS,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,GAChE,KAAK,SAAS,GAAG,GACf,IAAI,SAAS,GAAG,EAAE,GAChB,SAAS,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,GAC7B,KAAK,GACP,GAAG,GACL,GAAG,CAAC;AA6BR;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,SAAS,CAAC,CAAC,SAAS,GAAG,EAAE,EAAE,KAAK,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,GAAE,gBAAqB,GAAG,KAAK,CAAC,CAAC,CAAC,CAE3G;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,YAAY,CAAC,CAAC,SAAS,GAAG,EAAE,EAAE,GAAG,KAAK,EAAE,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAcxE"}
1
+ {"version":3,"file":"merge.d.ts","sourceRoot":"","sources":["../../src/object/merge.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAEpC,MAAM,MAAM,gBAAgB,GAAG;IAC7B,0FAA0F;IAC1F,aAAa,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAC;CACtC,CAAC;AAEF,KAAK,SAAS,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,GAAG,GAChC,CAAC,SAAS,GAAG,GACX;KACG,CAAC,IAAI,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,SAAS,MAAM,CAAC,GACvC,CAAC,SAAS,MAAM,CAAC,GACf,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GACrB,CAAC,CAAC,CAAC,CAAC,GACN,CAAC,SAAS,MAAM,CAAC,GACf,CAAC,CAAC,CAAC,CAAC,GACJ,KAAK;CACZ,GACD,CAAC,GACH,CAAC,CAAC;AAEN,KAAK,KAAK,CAAC,CAAC,SAAS,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,GAChE,KAAK,SAAS,GAAG,GACf,IAAI,SAAS,GAAG,EAAE,GAChB,SAAS,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,GAC7B,KAAK,GACP,GAAG,GACL,GAAG,CAAC;AA6BR;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,SAAS,CAAC,CAAC,SAAS,GAAG,EAAE,EAAE,KAAK,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,GAAE,gBAAqB,GAAG,KAAK,CAAC,CAAC,CAAC,CAE3G;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,YAAY,CAAC,CAAC,SAAS,GAAG,EAAE,EAAE,GAAG,KAAK,EAAE,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAcxE"}