@vielzeug/toolkit 1.0.12 → 1.0.14

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 (166) hide show
  1. package/dist/array/{sortBy.cjs → arrange.cjs} +2 -2
  2. package/dist/array/arrange.cjs.map +1 -0
  3. package/dist/array/arrange.js +6 -0
  4. package/dist/array/arrange.js.map +1 -0
  5. package/dist/array/chunk.cjs +1 -1
  6. package/dist/array/chunk.cjs.map +1 -1
  7. package/dist/array/chunk.js +15 -12
  8. package/dist/array/chunk.js.map +1 -1
  9. package/dist/array/group.cjs +1 -1
  10. package/dist/array/group.cjs.map +1 -1
  11. package/dist/array/group.js +9 -9
  12. package/dist/array/group.js.map +1 -1
  13. package/dist/array/list.cjs +1 -1
  14. package/dist/array/list.cjs.map +1 -1
  15. package/dist/array/list.js +87 -50
  16. package/dist/array/list.js.map +1 -1
  17. package/dist/array/pick.cjs.map +1 -1
  18. package/dist/array/pick.js.map +1 -1
  19. package/dist/array/remoteList.cjs +2 -0
  20. package/dist/array/remoteList.cjs.map +1 -0
  21. package/dist/array/remoteList.js +123 -0
  22. package/dist/array/remoteList.js.map +1 -0
  23. package/dist/date/expires.cjs.map +1 -1
  24. package/dist/date/expires.js.map +1 -1
  25. package/dist/date/interval.cjs.map +1 -1
  26. package/dist/date/interval.js.map +1 -1
  27. package/dist/date/timeDiff.cjs +1 -1
  28. package/dist/date/timeDiff.cjs.map +1 -1
  29. package/dist/date/timeDiff.js +10 -12
  30. package/dist/date/timeDiff.js.map +1 -1
  31. package/dist/function/curry.cjs +1 -1
  32. package/dist/function/curry.cjs.map +1 -1
  33. package/dist/function/curry.js +3 -3
  34. package/dist/function/curry.js.map +1 -1
  35. package/dist/function/debounce.cjs +1 -1
  36. package/dist/function/debounce.cjs.map +1 -1
  37. package/dist/function/debounce.js +22 -5
  38. package/dist/function/debounce.js.map +1 -1
  39. package/dist/function/memo.cjs +1 -1
  40. package/dist/function/memo.cjs.map +1 -1
  41. package/dist/function/memo.js +14 -13
  42. package/dist/function/memo.js.map +1 -1
  43. package/dist/function/parallel.cjs +2 -0
  44. package/dist/function/parallel.cjs.map +1 -0
  45. package/dist/function/parallel.js +28 -0
  46. package/dist/function/parallel.js.map +1 -0
  47. package/dist/function/proxy.cjs.map +1 -1
  48. package/dist/function/proxy.js.map +1 -1
  49. package/dist/function/prune.cjs +2 -0
  50. package/dist/function/prune.cjs.map +1 -0
  51. package/dist/function/prune.js +30 -0
  52. package/dist/function/prune.js.map +1 -0
  53. package/dist/function/retry.cjs +1 -1
  54. package/dist/function/retry.cjs.map +1 -1
  55. package/dist/function/retry.js +13 -13
  56. package/dist/function/retry.js.map +1 -1
  57. package/dist/function/sleep.cjs +1 -1
  58. package/dist/function/sleep.cjs.map +1 -1
  59. package/dist/function/sleep.js +8 -3
  60. package/dist/function/sleep.js.map +1 -1
  61. package/dist/function/throttle.cjs +1 -1
  62. package/dist/function/throttle.cjs.map +1 -1
  63. package/dist/function/throttle.js +33 -6
  64. package/dist/function/throttle.js.map +1 -1
  65. package/dist/index.cjs +1 -1
  66. package/dist/index.d.ts +455 -95
  67. package/dist/index.js +218 -194
  68. package/dist/index.js.map +1 -1
  69. package/dist/math/abs.cjs +2 -0
  70. package/dist/math/abs.cjs.map +1 -0
  71. package/dist/math/abs.js +7 -0
  72. package/dist/math/abs.js.map +1 -0
  73. package/dist/math/add.cjs +2 -0
  74. package/dist/math/add.cjs.map +1 -0
  75. package/dist/math/add.js +9 -0
  76. package/dist/math/add.js.map +1 -0
  77. package/dist/math/allocate.cjs +2 -0
  78. package/dist/math/allocate.cjs.map +1 -0
  79. package/dist/math/allocate.js +29 -0
  80. package/dist/math/allocate.js.map +1 -0
  81. package/dist/math/average.cjs +1 -1
  82. package/dist/math/average.cjs.map +1 -1
  83. package/dist/math/average.js +18 -12
  84. package/dist/math/average.js.map +1 -1
  85. package/dist/math/distribute.cjs +2 -0
  86. package/dist/math/distribute.cjs.map +1 -0
  87. package/dist/math/distribute.js +18 -0
  88. package/dist/math/distribute.js.map +1 -0
  89. package/dist/math/divide.cjs +2 -0
  90. package/dist/math/divide.cjs.map +1 -0
  91. package/dist/math/divide.js +11 -0
  92. package/dist/math/divide.js.map +1 -0
  93. package/dist/math/median.cjs.map +1 -1
  94. package/dist/math/median.js.map +1 -1
  95. package/dist/math/multiply.cjs +2 -0
  96. package/dist/math/multiply.cjs.map +1 -0
  97. package/dist/math/multiply.js +9 -0
  98. package/dist/math/multiply.js.map +1 -0
  99. package/dist/math/range.cjs +1 -1
  100. package/dist/math/range.cjs.map +1 -1
  101. package/dist/math/range.js +14 -6
  102. package/dist/math/range.js.map +1 -1
  103. package/dist/math/subtract.cjs +2 -0
  104. package/dist/math/subtract.cjs.map +1 -0
  105. package/dist/math/subtract.js +9 -0
  106. package/dist/math/subtract.js.map +1 -0
  107. package/dist/math/sum.cjs +1 -1
  108. package/dist/math/sum.cjs.map +1 -1
  109. package/dist/math/sum.js +11 -18
  110. package/dist/math/sum.js.map +1 -1
  111. package/dist/money/currency.cjs +2 -0
  112. package/dist/money/currency.cjs.map +1 -0
  113. package/dist/money/currency.js +49 -0
  114. package/dist/money/currency.js.map +1 -0
  115. package/dist/money/exchange.cjs +2 -0
  116. package/dist/money/exchange.cjs.map +1 -0
  117. package/dist/money/exchange.js +13 -0
  118. package/dist/money/exchange.js.map +1 -0
  119. package/dist/object/clone.cjs +1 -1
  120. package/dist/object/clone.cjs.map +1 -1
  121. package/dist/object/clone.js +13 -3
  122. package/dist/object/clone.js.map +1 -1
  123. package/dist/object/merge.cjs +1 -1
  124. package/dist/object/merge.cjs.map +1 -1
  125. package/dist/object/merge.js +11 -15
  126. package/dist/object/merge.js.map +1 -1
  127. package/dist/object/parseJSON.cjs.map +1 -1
  128. package/dist/object/parseJSON.js.map +1 -1
  129. package/dist/object/path.cjs.map +1 -1
  130. package/dist/object/path.js.map +1 -1
  131. package/dist/object/seek.cjs +1 -1
  132. package/dist/object/seek.cjs.map +1 -1
  133. package/dist/object/seek.js +8 -6
  134. package/dist/object/seek.js.map +1 -1
  135. package/dist/random/uuid.cjs +1 -1
  136. package/dist/random/uuid.cjs.map +1 -1
  137. package/dist/random/uuid.js +6 -3
  138. package/dist/random/uuid.js.map +1 -1
  139. package/dist/string/camelCase.cjs +1 -1
  140. package/dist/string/camelCase.cjs.map +1 -1
  141. package/dist/string/camelCase.js +3 -3
  142. package/dist/string/camelCase.js.map +1 -1
  143. package/dist/string/similarity.cjs +1 -1
  144. package/dist/string/similarity.cjs.map +1 -1
  145. package/dist/string/similarity.js +24 -21
  146. package/dist/string/similarity.js.map +1 -1
  147. package/dist/string/truncate.cjs +1 -1
  148. package/dist/string/truncate.cjs.map +1 -1
  149. package/dist/string/truncate.js +14 -5
  150. package/dist/string/truncate.js.map +1 -1
  151. package/dist/typed/is.cjs +1 -1
  152. package/dist/typed/is.cjs.map +1 -1
  153. package/dist/typed/is.js +30 -31
  154. package/dist/typed/is.js.map +1 -1
  155. package/dist/typed/isEmpty.cjs +1 -1
  156. package/dist/typed/isEmpty.cjs.map +1 -1
  157. package/dist/typed/isEmpty.js +6 -6
  158. package/dist/typed/isEmpty.js.map +1 -1
  159. package/dist/typed/isEqual.cjs +1 -1
  160. package/dist/typed/isEqual.cjs.map +1 -1
  161. package/dist/typed/isEqual.js +22 -17
  162. package/dist/typed/isEqual.js.map +1 -1
  163. package/package.json +1 -1
  164. package/dist/array/sortBy.cjs.map +0 -1
  165. package/dist/array/sortBy.js +0 -6
  166. package/dist/array/sortBy.js.map +0 -1
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("../function/compareBy.cjs"),o=(r,e)=>[...r].sort(t.compareBy(e));exports.sortBy=o;
2
- //# sourceMappingURL=sortBy.cjs.map
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("../function/compareBy.cjs"),o=(r,e)=>[...r].sort(t.compareBy(e));exports.arrange=o;
2
+ //# sourceMappingURL=arrange.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"arrange.cjs","sources":["../../src/array/arrange.ts"],"sourcesContent":["import { compareBy } from '../function/compareBy';\n\n/**\n * Arranges (sorts) an array of objects based on multiple selectors.\n *\n * @example\n * ```ts\n * const data = [\n * { name: 'Alice', age: 30 },\n * { name: 'Bob', age: 25 },\n * { name: 'Charlie', age: 35 },\n * { name: 'Alice', age: 25 },\n * { name: 'Bob', age: 30 },\n * { name: 'Charlie', age: 30 },\n * ].arrange(data, { name: 'asc', age: 'desc' }); // [ { name: 'Alice', age: 30 }, { name: 'Alice', age: 25 }, { name: 'Bob', age: 30 }, { name: 'Bob', age: 25 }, { name: 'Charlie', age: 35 }, { name: 'Charlie', age: 30 } ]\n * ```\n *\n * @param array - The array to sort.\n * @param selectors - An object where keys are the properties to sort by and values are 'asc' or 'desc'.\n * @returns A new sorted array.\n */\nexport const arrange = <T>(array: T[], selectors: Partial<Record<keyof T, 'asc' | 'desc'>>) => {\n return [...array].sort(compareBy(selectors));\n};\n"],"names":["arrange","array","selectors","compareBy"],"mappings":"6HAqBaA,EAAU,CAAIC,EAAYC,IAC9B,CAAC,GAAGD,CAAK,EAAE,KAAKE,EAAAA,UAAUD,CAAS,CAAC"}
@@ -0,0 +1,6 @@
1
+ import { compareBy as t } from "../function/compareBy.js";
2
+ const a = (r, o) => [...r].sort(t(o));
3
+ export {
4
+ a as arrange
5
+ };
6
+ //# sourceMappingURL=arrange.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"arrange.js","sources":["../../src/array/arrange.ts"],"sourcesContent":["import { compareBy } from '../function/compareBy';\n\n/**\n * Arranges (sorts) an array of objects based on multiple selectors.\n *\n * @example\n * ```ts\n * const data = [\n * { name: 'Alice', age: 30 },\n * { name: 'Bob', age: 25 },\n * { name: 'Charlie', age: 35 },\n * { name: 'Alice', age: 25 },\n * { name: 'Bob', age: 30 },\n * { name: 'Charlie', age: 30 },\n * ].arrange(data, { name: 'asc', age: 'desc' }); // [ { name: 'Alice', age: 30 }, { name: 'Alice', age: 25 }, { name: 'Bob', age: 30 }, { name: 'Bob', age: 25 }, { name: 'Charlie', age: 35 }, { name: 'Charlie', age: 30 } ]\n * ```\n *\n * @param array - The array to sort.\n * @param selectors - An object where keys are the properties to sort by and values are 'asc' or 'desc'.\n * @returns A new sorted array.\n */\nexport const arrange = <T>(array: T[], selectors: Partial<Record<keyof T, 'asc' | 'desc'>>) => {\n return [...array].sort(compareBy(selectors));\n};\n"],"names":["arrange","array","selectors","compareBy"],"mappings":";AAqBO,MAAMA,IAAU,CAAIC,GAAYC,MAC9B,CAAC,GAAGD,CAAK,EAAE,KAAKE,EAAUD,CAAS,CAAC;"}
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const l=require("../function/assert.cjs"),y=require("../typed/isArray.cjs"),o=require("../typed/isString.cjs");function h(r,e=2,c={}){l.assert(y.isArray(r)||o.isString(r),"Argument must be an array or string.",{args:{input:r},type:TypeError});const{overlap:g=!1,pad:n=" "}=c;if(o.isString(r)&&g){const t=`${n}${r}${n}`;return Array.from({length:t.length-e+1},(a,s)=>t.slice(s,s+e))}return Array.from({length:Math.ceil(r.length/e)},(t,a)=>r.slice(a*e,a*e+e))}exports.chunk=h;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o=require("../function/assert.cjs"),u=require("../typed/isArray.cjs"),c=require("../typed/isString.cjs");function y(e,r=2,g={}){o.assert(u.isArray(e)||c.isString(e),"Argument must be an array or string.",{args:{input:e},type:TypeError}),o.assert(r>=1,"Chunk size must be at least 1.",{args:{size:r},type:RangeError});const{overlap:l=!1,pad:a=" "}=g;if(c.isString(e)&&l){const s=a+e+a,t=s.length-r+1;return Array.from({length:t},(h,n)=>s.slice(n,n+r))}return Array.from({length:Math.ceil(e.length/r)},(s,t)=>e.slice(t*r,t*r+r))}exports.chunk=y;
2
2
  //# sourceMappingURL=chunk.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"chunk.cjs","sources":["../../src/array/chunk.ts"],"sourcesContent":["import { assert } from '../function/assert';\nimport { isArray } from '../typed/isArray';\nimport { isString } from '../typed/isString';\n\ntype ChunkOptions = {\n overlap?: boolean;\n pad?: string;\n};\n\ntype ChunkResult<T> = (T extends string ? string : T[])[];\n\n/**\n * Splits an array or string into chunks of a specified size.\n *\n * @example\n * ```ts\n * chunk([1, 2, 3, 4, 5], 2) // [[1, 2], [3, 4], [5]]\n * chunk(\"hello\", 2) // [\"he\", \"ll\", \"o\"]\n * chunk(\"hello\", 2, { overlap: true }) // [\" h\", \"he\", \"el\", \"ll\", \"lo\", \"o \"]\n * ```\n *\n * @param input - The input array or string to be chunked.\n * @param size - The size of each chunk.\n * @param [options] - Additional options for chunking.\n * @param [options.overlap] -\n * @param [options.pad] -\n *\n * @returns An array of chunks.\n *\n * @throws {RangeError} If the chunk size is invalid.\n * @throws {TypeError} If the input type is invalid.\n */\nexport function chunk<T>(input: T[] | string, size = 2, options: ChunkOptions = {}): ChunkResult<T> {\n assert(isArray(input as T[]) || isString(input), 'Argument must be an array or string.', {\n args: { input },\n type: TypeError,\n });\n\n const { overlap = false, pad = ' ' } = options;\n\n if (isString(input) && overlap) {\n const padded = `${pad}${input}${pad}`;\n return Array.from({ length: padded.length - size + 1 }, (_, i) => padded.slice(i, i + size)) as ChunkResult<T>;\n }\n\n return Array.from({ length: Math.ceil(input.length / size) }, (_, i) =>\n input.slice(i * size, i * size + size),\n ) as ChunkResult<T>;\n}\n"],"names":["chunk","input","size","options","assert","isArray","isString","overlap","pad","padded","_","i"],"mappings":"+LAgCO,SAASA,EAASC,EAAqBC,EAAO,EAAGC,EAAwB,CAAA,EAAoB,CAClGC,EAAAA,OAAOC,EAAAA,QAAQJ,CAAY,GAAKK,EAAAA,SAASL,CAAK,EAAG,uCAAwC,CACvF,KAAM,CAAE,MAAAA,CAAA,EACR,KAAM,SAAA,CACP,EAED,KAAM,CAAE,QAAAM,EAAU,GAAO,IAAAC,EAAM,KAAQL,EAEvC,GAAIG,EAAAA,SAASL,CAAK,GAAKM,EAAS,CAC9B,MAAME,EAAS,GAAGD,CAAG,GAAGP,CAAK,GAAGO,CAAG,GACnC,OAAO,MAAM,KAAK,CAAE,OAAQC,EAAO,OAASP,EAAO,CAAA,EAAK,CAACQ,EAAGC,IAAMF,EAAO,MAAME,EAAGA,EAAIT,CAAI,CAAC,CAC7F,CAEA,OAAO,MAAM,KAAK,CAAE,OAAQ,KAAK,KAAKD,EAAM,OAASC,CAAI,CAAA,EAAK,CAACQ,EAAGC,IAChEV,EAAM,MAAMU,EAAIT,EAAMS,EAAIT,EAAOA,CAAI,CAAA,CAEzC"}
1
+ {"version":3,"file":"chunk.cjs","sources":["../../src/array/chunk.ts"],"sourcesContent":["import { assert } from '../function/assert';\nimport { isArray } from '../typed/isArray';\nimport { isString } from '../typed/isString';\n\n// #region ChunkTypes\ntype ChunkOptions = {\n overlap?: boolean;\n pad?: string;\n};\n\ntype ChunkResult<T> = (T extends string ? string : T[])[];\n// #endregion ChunkTypes\n\n/**\n * Splits an array or string into chunks of a specified size.\n *\n * @example\n * ```ts\n * chunk([1, 2, 3, 4, 5], 2) // [[1, 2], [3, 4], [5]]\n * chunk(\"hello\", 2) // [\"he\", \"ll\", \"o\"]\n * chunk(\"hello\", 2, { overlap: true }) // [\" h\", \"he\", \"el\", \"ll\", \"lo\", \"o \"]\n * ```\n *\n * @param input - The input array or string to be chunked.\n * @param size - The size of each chunk.\n * @param [options] - Additional options for chunking.\n * @param [options.overlap] -\n * @param [options.pad] -\n *\n * @returns An array of chunks.\n *\n * @throws {RangeError} If the chunk size is invalid.\n * @throws {TypeError} If the input type is invalid.\n */\nexport function chunk<T>(input: T[] | string, size = 2, options: ChunkOptions = {}): ChunkResult<T> {\n assert(isArray(input as T[]) || isString(input), 'Argument must be an array or string.', {\n args: { input },\n type: TypeError,\n });\n\n assert(size >= 1, 'Chunk size must be at least 1.', {\n args: { size },\n type: RangeError,\n });\n\n const { overlap = false, pad = ' ' } = options;\n\n if (isString(input) && overlap) {\n const padded = pad + input + pad;\n const numChunks = padded.length - size + 1;\n return Array.from({ length: numChunks }, (_, i) => padded.slice(i, i + size)) as ChunkResult<T>;\n }\n\n return Array.from({ length: Math.ceil(input.length / size) }, (_, i) =>\n input.slice(i * size, i * size + size),\n ) as ChunkResult<T>;\n}\n"],"names":["chunk","input","size","options","assert","isArray","isString","overlap","pad","padded","numChunks","_","i"],"mappings":"+LAkCO,SAASA,EAASC,EAAqBC,EAAO,EAAGC,EAAwB,CAAA,EAAoB,CAClGC,EAAAA,OAAOC,EAAAA,QAAQJ,CAAY,GAAKK,EAAAA,SAASL,CAAK,EAAG,uCAAwC,CACvF,KAAM,CAAE,MAAAA,CAAA,EACR,KAAM,SAAA,CACP,EAEDG,SAAOF,GAAQ,EAAG,iCAAkC,CAClD,KAAM,CAAE,KAAAA,CAAA,EACR,KAAM,UAAA,CACP,EAED,KAAM,CAAE,QAAAK,EAAU,GAAO,IAAAC,EAAM,KAAQL,EAEvC,GAAIG,EAAAA,SAASL,CAAK,GAAKM,EAAS,CAC9B,MAAME,EAASD,EAAMP,EAAQO,EACvBE,EAAYD,EAAO,OAASP,EAAO,EACzC,OAAO,MAAM,KAAK,CAAE,OAAQQ,GAAa,CAACC,EAAGC,IAAMH,EAAO,MAAMG,EAAGA,EAAIV,CAAI,CAAC,CAC9E,CAEA,OAAO,MAAM,KAAK,CAAE,OAAQ,KAAK,KAAKD,EAAM,OAASC,CAAI,CAAA,EAAK,CAACS,EAAGC,IAChEX,EAAM,MAAMW,EAAIV,EAAMU,EAAIV,EAAOA,CAAI,CAAA,CAEzC"}
@@ -1,22 +1,25 @@
1
- import { assert as g } from "../function/assert.js";
1
+ import { assert as m } from "../function/assert.js";
2
2
  import { isArray as c } from "../typed/isArray.js";
3
- import { isString as l } from "../typed/isString.js";
4
- function d(r, o = 2, n = {}) {
5
- g(c(r) || l(r), "Argument must be an array or string.", {
6
- args: { input: r },
3
+ import { isString as s } from "../typed/isString.js";
4
+ function p(t, r = 2, g = {}) {
5
+ m(c(t) || s(t), "Argument must be an array or string.", {
6
+ args: { input: t },
7
7
  type: TypeError
8
+ }), m(r >= 1, "Chunk size must be at least 1.", {
9
+ args: { size: r },
10
+ type: RangeError
8
11
  });
9
- const { overlap: f = !1, pad: e = " " } = n;
10
- if (l(r) && f) {
11
- const t = `${e}${r}${e}`;
12
- return Array.from({ length: t.length - o + 1 }, (a, m) => t.slice(m, m + o));
12
+ const { overlap: l = !1, pad: e = " " } = g;
13
+ if (s(t) && l) {
14
+ const o = e + t + e, a = o.length - r + 1;
15
+ return Array.from({ length: a }, (f, n) => o.slice(n, n + r));
13
16
  }
14
17
  return Array.from(
15
- { length: Math.ceil(r.length / o) },
16
- (t, a) => r.slice(a * o, a * o + o)
18
+ { length: Math.ceil(t.length / r) },
19
+ (o, a) => t.slice(a * r, a * r + r)
17
20
  );
18
21
  }
19
22
  export {
20
- d as chunk
23
+ p as chunk
21
24
  };
22
25
  //# sourceMappingURL=chunk.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"chunk.js","sources":["../../src/array/chunk.ts"],"sourcesContent":["import { assert } from '../function/assert';\nimport { isArray } from '../typed/isArray';\nimport { isString } from '../typed/isString';\n\ntype ChunkOptions = {\n overlap?: boolean;\n pad?: string;\n};\n\ntype ChunkResult<T> = (T extends string ? string : T[])[];\n\n/**\n * Splits an array or string into chunks of a specified size.\n *\n * @example\n * ```ts\n * chunk([1, 2, 3, 4, 5], 2) // [[1, 2], [3, 4], [5]]\n * chunk(\"hello\", 2) // [\"he\", \"ll\", \"o\"]\n * chunk(\"hello\", 2, { overlap: true }) // [\" h\", \"he\", \"el\", \"ll\", \"lo\", \"o \"]\n * ```\n *\n * @param input - The input array or string to be chunked.\n * @param size - The size of each chunk.\n * @param [options] - Additional options for chunking.\n * @param [options.overlap] -\n * @param [options.pad] -\n *\n * @returns An array of chunks.\n *\n * @throws {RangeError} If the chunk size is invalid.\n * @throws {TypeError} If the input type is invalid.\n */\nexport function chunk<T>(input: T[] | string, size = 2, options: ChunkOptions = {}): ChunkResult<T> {\n assert(isArray(input as T[]) || isString(input), 'Argument must be an array or string.', {\n args: { input },\n type: TypeError,\n });\n\n const { overlap = false, pad = ' ' } = options;\n\n if (isString(input) && overlap) {\n const padded = `${pad}${input}${pad}`;\n return Array.from({ length: padded.length - size + 1 }, (_, i) => padded.slice(i, i + size)) as ChunkResult<T>;\n }\n\n return Array.from({ length: Math.ceil(input.length / size) }, (_, i) =>\n input.slice(i * size, i * size + size),\n ) as ChunkResult<T>;\n}\n"],"names":["chunk","input","size","options","assert","isArray","isString","overlap","pad","padded","_","i"],"mappings":";;;AAgCO,SAASA,EAASC,GAAqBC,IAAO,GAAGC,IAAwB,CAAA,GAAoB;AAClG,EAAAC,EAAOC,EAAQJ,CAAY,KAAKK,EAASL,CAAK,GAAG,wCAAwC;AAAA,IACvF,MAAM,EAAE,OAAAA,EAAA;AAAA,IACR,MAAM;AAAA,EAAA,CACP;AAED,QAAM,EAAE,SAAAM,IAAU,IAAO,KAAAC,IAAM,QAAQL;AAEvC,MAAIG,EAASL,CAAK,KAAKM,GAAS;AAC9B,UAAME,IAAS,GAAGD,CAAG,GAAGP,CAAK,GAAGO,CAAG;AACnC,WAAO,MAAM,KAAK,EAAE,QAAQC,EAAO,SAASP,IAAO,EAAA,GAAK,CAACQ,GAAGC,MAAMF,EAAO,MAAME,GAAGA,IAAIT,CAAI,CAAC;AAAA,EAC7F;AAEA,SAAO,MAAM;AAAA,IAAK,EAAE,QAAQ,KAAK,KAAKD,EAAM,SAASC,CAAI,EAAA;AAAA,IAAK,CAACQ,GAAGC,MAChEV,EAAM,MAAMU,IAAIT,GAAMS,IAAIT,IAAOA,CAAI;AAAA,EAAA;AAEzC;"}
1
+ {"version":3,"file":"chunk.js","sources":["../../src/array/chunk.ts"],"sourcesContent":["import { assert } from '../function/assert';\nimport { isArray } from '../typed/isArray';\nimport { isString } from '../typed/isString';\n\n// #region ChunkTypes\ntype ChunkOptions = {\n overlap?: boolean;\n pad?: string;\n};\n\ntype ChunkResult<T> = (T extends string ? string : T[])[];\n// #endregion ChunkTypes\n\n/**\n * Splits an array or string into chunks of a specified size.\n *\n * @example\n * ```ts\n * chunk([1, 2, 3, 4, 5], 2) // [[1, 2], [3, 4], [5]]\n * chunk(\"hello\", 2) // [\"he\", \"ll\", \"o\"]\n * chunk(\"hello\", 2, { overlap: true }) // [\" h\", \"he\", \"el\", \"ll\", \"lo\", \"o \"]\n * ```\n *\n * @param input - The input array or string to be chunked.\n * @param size - The size of each chunk.\n * @param [options] - Additional options for chunking.\n * @param [options.overlap] -\n * @param [options.pad] -\n *\n * @returns An array of chunks.\n *\n * @throws {RangeError} If the chunk size is invalid.\n * @throws {TypeError} If the input type is invalid.\n */\nexport function chunk<T>(input: T[] | string, size = 2, options: ChunkOptions = {}): ChunkResult<T> {\n assert(isArray(input as T[]) || isString(input), 'Argument must be an array or string.', {\n args: { input },\n type: TypeError,\n });\n\n assert(size >= 1, 'Chunk size must be at least 1.', {\n args: { size },\n type: RangeError,\n });\n\n const { overlap = false, pad = ' ' } = options;\n\n if (isString(input) && overlap) {\n const padded = pad + input + pad;\n const numChunks = padded.length - size + 1;\n return Array.from({ length: numChunks }, (_, i) => padded.slice(i, i + size)) as ChunkResult<T>;\n }\n\n return Array.from({ length: Math.ceil(input.length / size) }, (_, i) =>\n input.slice(i * size, i * size + size),\n ) as ChunkResult<T>;\n}\n"],"names":["chunk","input","size","options","assert","isArray","isString","overlap","pad","padded","numChunks","_","i"],"mappings":";;;AAkCO,SAASA,EAASC,GAAqBC,IAAO,GAAGC,IAAwB,CAAA,GAAoB;AAClG,EAAAC,EAAOC,EAAQJ,CAAY,KAAKK,EAASL,CAAK,GAAG,wCAAwC;AAAA,IACvF,MAAM,EAAE,OAAAA,EAAA;AAAA,IACR,MAAM;AAAA,EAAA,CACP,GAEDG,EAAOF,KAAQ,GAAG,kCAAkC;AAAA,IAClD,MAAM,EAAE,MAAAA,EAAA;AAAA,IACR,MAAM;AAAA,EAAA,CACP;AAED,QAAM,EAAE,SAAAK,IAAU,IAAO,KAAAC,IAAM,QAAQL;AAEvC,MAAIG,EAASL,CAAK,KAAKM,GAAS;AAC9B,UAAME,IAASD,IAAMP,IAAQO,GACvBE,IAAYD,EAAO,SAASP,IAAO;AACzC,WAAO,MAAM,KAAK,EAAE,QAAQQ,KAAa,CAACC,GAAGC,MAAMH,EAAO,MAAMG,GAAGA,IAAIV,CAAI,CAAC;AAAA,EAC9E;AAEA,SAAO,MAAM;AAAA,IAAK,EAAE,QAAQ,KAAK,KAAKD,EAAM,SAASC,CAAI,EAAA;AAAA,IAAK,CAACS,GAAGC,MAChEX,EAAM,MAAMW,IAAIV,GAAMU,IAAIV,IAAOA,CAAI;AAAA,EAAA;AAEzC;"}
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const c=require("../function/assert.cjs"),n=require("../typed/isArray.cjs");function u(r,o){c.assert(n.isArray(r),n.IS_ARRAY_ERROR_MSG,{args:{array:r},type:TypeError});const t={},i=typeof o=="function"?o:e=>e[o];for(const e of r){const s=i(e)||"_";t[s]||(t[s]=[]),t[s].push(e)}return t}u.fp=!0;exports.group=u;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const f=require("../function/assert.cjs"),u=require("../typed/isArray.cjs");function i(e,o){f.assert(u.isArray(e),u.IS_ARRAY_ERROR_MSG,{args:{array:e},type:TypeError});const t={},c=typeof o=="function"?o:r=>r[o];for(const r of e){const n=c(r),s=n==null?"_":String(n);t[s]||(t[s]=[]),t[s].push(r)}return t}i.fp=!0;exports.group=i;
2
2
  //# sourceMappingURL=group.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"group.cjs","sources":["../../src/array/group.ts"],"sourcesContent":["import { assert } from '../function/assert';\nimport { IS_ARRAY_ERROR_MSG, isArray } from '../typed/isArray';\nimport type { Selector } from '../types';\n\n/**\n * Groups the elements of an array based on the given key.\n *\n * @example\n * ```ts\n * const data = [{ a: 2 }, { a: 1 }];\n * group(data, 'a') // { '1': [{ a: 2 }], '2': [{ a: 1 }] };\n * ```\n *\n * @param array - The array to group.\n * @param selector - The function to generate the key for each element. It can be a string representing the key or a function that returns the key.\n *\n * @returns an object with keys as the grouped values and values as arrays of elements.\n *\n * @throws {TypeError} If the provided array is not an array.\n */\nexport function group<T, K extends keyof T, R extends T[K] extends string ? T[K] : never>(\n array: T[],\n selector: Selector<T>,\n): Record<R, T[]> {\n assert(isArray(array), IS_ARRAY_ERROR_MSG, { args: { array }, type: TypeError });\n\n const result = {} as Record<R, T[]>;\n const getKey = typeof selector === 'function' ? selector : (item: T) => item[selector];\n\n for (const item of array) {\n const key = (getKey(item) || '_') as R;\n\n if (!result[key]) {\n result[key] = [];\n }\n result[key].push(item);\n }\n\n return result;\n}\n\ngroup.fp = true;\n"],"names":["group","array","selector","assert","isArray","IS_ARRAY_ERROR_MSG","result","getKey","item","key"],"mappings":"4JAoBO,SAASA,EACdC,EACAC,EACgB,CAChBC,EAAAA,OAAOC,EAAAA,QAAQH,CAAK,EAAGI,qBAAoB,CAAE,KAAM,CAAE,MAAAJ,CAAA,EAAS,KAAM,UAAW,EAE/E,MAAMK,EAAS,CAAA,EACTC,EAAS,OAAOL,GAAa,WAAaA,EAAYM,GAAYA,EAAKN,CAAQ,EAErF,UAAWM,KAAQP,EAAO,CACxB,MAAMQ,EAAOF,EAAOC,CAAI,GAAK,IAExBF,EAAOG,CAAG,IACbH,EAAOG,CAAG,EAAI,CAAA,GAEhBH,EAAOG,CAAG,EAAE,KAAKD,CAAI,CACvB,CAEA,OAAOF,CACT,CAEAN,EAAM,GAAK"}
1
+ {"version":3,"file":"group.cjs","sources":["../../src/array/group.ts"],"sourcesContent":["import { assert } from '../function/assert';\nimport { IS_ARRAY_ERROR_MSG, isArray } from '../typed/isArray';\nimport type { Selector } from '../types';\n\n/**\n * Groups the elements of an array based on the given key.\n *\n * @example\n * ```ts\n * const data = [{ a: 2 }, { a: 1 }];\n * group(data, 'a') // { '1': [{ a: 2 }], '2': [{ a: 1 }] };\n * ```\n *\n * @param array - The array to group.\n * @param selector - The function to generate the key for each element. It can be a string representing the key or a function that returns the key.\n *\n * @returns an object with keys as the grouped values and values as arrays of elements.\n *\n * @throws {TypeError} If the provided array is not an array.\n */\nexport function group<T, _K extends keyof T, R extends string | number | symbol>(\n array: T[],\n selector: Selector<T>,\n): Record<R, T[]> {\n assert(isArray(array), IS_ARRAY_ERROR_MSG, { args: { array }, type: TypeError });\n\n const result = {} as Record<R, T[]>;\n const getKey = typeof selector === 'function' ? selector : (item: T) => item[selector];\n\n for (const item of array) {\n const rawKey = getKey(item);\n const key = (rawKey === undefined || rawKey === null ? '_' : String(rawKey)) as R;\n\n if (!result[key]) {\n result[key] = [];\n }\n result[key].push(item);\n }\n\n return result;\n}\n\ngroup.fp = true;\n"],"names":["group","array","selector","assert","isArray","IS_ARRAY_ERROR_MSG","result","getKey","item","rawKey","key"],"mappings":"4JAoBO,SAASA,EACdC,EACAC,EACgB,CAChBC,EAAAA,OAAOC,EAAAA,QAAQH,CAAK,EAAGI,qBAAoB,CAAE,KAAM,CAAE,MAAAJ,CAAA,EAAS,KAAM,UAAW,EAE/E,MAAMK,EAAS,CAAA,EACTC,EAAS,OAAOL,GAAa,WAAaA,EAAYM,GAAYA,EAAKN,CAAQ,EAErF,UAAWM,KAAQP,EAAO,CACxB,MAAMQ,EAASF,EAAOC,CAAI,EACpBE,EAA+BD,GAAW,KAAO,IAAM,OAAOA,CAAM,EAErEH,EAAOI,CAAG,IACbJ,EAAOI,CAAG,EAAI,CAAA,GAEhBJ,EAAOI,CAAG,EAAE,KAAKF,CAAI,CACvB,CAEA,OAAOF,CACT,CAEAN,EAAM,GAAK"}
@@ -1,16 +1,16 @@
1
- import { assert as e } from "../function/assert.js";
2
- import { IS_ARRAY_ERROR_MSG as s, isArray as i } from "../typed/isArray.js";
3
- function u(r, f) {
4
- e(i(r), s, { args: { array: r }, type: TypeError });
5
- const t = {}, p = typeof f == "function" ? f : (o) => o[f];
1
+ import { assert as p } from "../function/assert.js";
2
+ import { IS_ARRAY_ERROR_MSG as s, isArray as u } from "../typed/isArray.js";
3
+ function c(r, n) {
4
+ p(u(r), s, { args: { array: r }, type: TypeError });
5
+ const t = {}, i = typeof n == "function" ? n : (o) => o[n];
6
6
  for (const o of r) {
7
- const n = p(o) || "_";
8
- t[n] || (t[n] = []), t[n].push(o);
7
+ const e = i(o), f = e == null ? "_" : String(e);
8
+ t[f] || (t[f] = []), t[f].push(o);
9
9
  }
10
10
  return t;
11
11
  }
12
- u.fp = !0;
12
+ c.fp = !0;
13
13
  export {
14
- u as group
14
+ c as group
15
15
  };
16
16
  //# sourceMappingURL=group.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"group.js","sources":["../../src/array/group.ts"],"sourcesContent":["import { assert } from '../function/assert';\nimport { IS_ARRAY_ERROR_MSG, isArray } from '../typed/isArray';\nimport type { Selector } from '../types';\n\n/**\n * Groups the elements of an array based on the given key.\n *\n * @example\n * ```ts\n * const data = [{ a: 2 }, { a: 1 }];\n * group(data, 'a') // { '1': [{ a: 2 }], '2': [{ a: 1 }] };\n * ```\n *\n * @param array - The array to group.\n * @param selector - The function to generate the key for each element. It can be a string representing the key or a function that returns the key.\n *\n * @returns an object with keys as the grouped values and values as arrays of elements.\n *\n * @throws {TypeError} If the provided array is not an array.\n */\nexport function group<T, K extends keyof T, R extends T[K] extends string ? T[K] : never>(\n array: T[],\n selector: Selector<T>,\n): Record<R, T[]> {\n assert(isArray(array), IS_ARRAY_ERROR_MSG, { args: { array }, type: TypeError });\n\n const result = {} as Record<R, T[]>;\n const getKey = typeof selector === 'function' ? selector : (item: T) => item[selector];\n\n for (const item of array) {\n const key = (getKey(item) || '_') as R;\n\n if (!result[key]) {\n result[key] = [];\n }\n result[key].push(item);\n }\n\n return result;\n}\n\ngroup.fp = true;\n"],"names":["group","array","selector","assert","isArray","IS_ARRAY_ERROR_MSG","result","getKey","item","key"],"mappings":";;AAoBO,SAASA,EACdC,GACAC,GACgB;AAChB,EAAAC,EAAOC,EAAQH,CAAK,GAAGI,GAAoB,EAAE,MAAM,EAAE,OAAAJ,EAAA,GAAS,MAAM,WAAW;AAE/E,QAAMK,IAAS,CAAA,GACTC,IAAS,OAAOL,KAAa,aAAaA,IAAW,CAACM,MAAYA,EAAKN,CAAQ;AAErF,aAAWM,KAAQP,GAAO;AACxB,UAAMQ,IAAOF,EAAOC,CAAI,KAAK;AAE7B,IAAKF,EAAOG,CAAG,MACbH,EAAOG,CAAG,IAAI,CAAA,IAEhBH,EAAOG,CAAG,EAAE,KAAKD,CAAI;AAAA,EACvB;AAEA,SAAOF;AACT;AAEAN,EAAM,KAAK;"}
1
+ {"version":3,"file":"group.js","sources":["../../src/array/group.ts"],"sourcesContent":["import { assert } from '../function/assert';\nimport { IS_ARRAY_ERROR_MSG, isArray } from '../typed/isArray';\nimport type { Selector } from '../types';\n\n/**\n * Groups the elements of an array based on the given key.\n *\n * @example\n * ```ts\n * const data = [{ a: 2 }, { a: 1 }];\n * group(data, 'a') // { '1': [{ a: 2 }], '2': [{ a: 1 }] };\n * ```\n *\n * @param array - The array to group.\n * @param selector - The function to generate the key for each element. It can be a string representing the key or a function that returns the key.\n *\n * @returns an object with keys as the grouped values and values as arrays of elements.\n *\n * @throws {TypeError} If the provided array is not an array.\n */\nexport function group<T, _K extends keyof T, R extends string | number | symbol>(\n array: T[],\n selector: Selector<T>,\n): Record<R, T[]> {\n assert(isArray(array), IS_ARRAY_ERROR_MSG, { args: { array }, type: TypeError });\n\n const result = {} as Record<R, T[]>;\n const getKey = typeof selector === 'function' ? selector : (item: T) => item[selector];\n\n for (const item of array) {\n const rawKey = getKey(item);\n const key = (rawKey === undefined || rawKey === null ? '_' : String(rawKey)) as R;\n\n if (!result[key]) {\n result[key] = [];\n }\n result[key].push(item);\n }\n\n return result;\n}\n\ngroup.fp = true;\n"],"names":["group","array","selector","assert","isArray","IS_ARRAY_ERROR_MSG","result","getKey","item","rawKey","key"],"mappings":";;AAoBO,SAASA,EACdC,GACAC,GACgB;AAChB,EAAAC,EAAOC,EAAQH,CAAK,GAAGI,GAAoB,EAAE,MAAM,EAAE,OAAAJ,EAAA,GAAS,MAAM,WAAW;AAE/E,QAAMK,IAAS,CAAA,GACTC,IAAS,OAAOL,KAAa,aAAaA,IAAW,CAACM,MAAYA,EAAKN,CAAQ;AAErF,aAAWM,KAAQP,GAAO;AACxB,UAAMQ,IAASF,EAAOC,CAAI,GACpBE,IAA+BD,KAAW,OAAO,MAAM,OAAOA,CAAM;AAE1E,IAAKH,EAAOI,CAAG,MACbJ,EAAOI,CAAG,IAAI,CAAA,IAEhBJ,EAAOI,CAAG,EAAE,KAAKF,CAAI;AAAA,EACvB;AAEA,SAAOF;AACT;AAEAN,EAAM,KAAK;"}
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const p=require("../function/debounce.cjs"),d=require("./chunk.cjs"),x=require("./search.cjs"),T=10,b=.5,y=1;function f(s,i,e){const a=e?[...s].sort(e):[...s];return d.chunk(a,i)}function m(s,i,e=""){return(e?x.search(s,e,b):s).filter(i)}function D(s,i={}){let{limit:e=T,filterFn:a=()=>!0,sortFn:o}=i,c=[...s],t=0,h="",l=m(c,a),n=f(l,e,o);const u=()=>(l=m(c,a,h),n=f(l,e,o),t=Math.max(0,Math.min(t,n.length-1)),n[t]??[]);return{get current(){return n[t]??[]},set data(r){c=[...r],t=0,u()},filter(r){return a=r,t=0,u()},set limit(r){e=Math.max(y,r),u()},get meta(){return{end:Math.min(e*(t+1),l.length),isEmpty:l.length===0,isFirst:t===0,isLast:t===n.length-1,limit:e,page:t+1,pages:Math.ceil(l.length/e),start:Math.max(0,e*t+1),total:l.length}},next(){t<n.length-1&&t++},set page(r){const g=r-1,M=g<0?n.length+g:g;t=Math.max(0,Math.min(M,n.length-1))},get pages(){return n},prev(){t>0&&t--},reset(){return t=0,h="",a=i.filterFn??(()=>!0),u()},search:p.debounce(r=>(h=r,u())),sort(r){return o=r,u()},*[Symbol.iterator](){for(const r of n)yield r}}}exports.list=D;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const Q=require("./search.cjs");function j(S,i={}){const T=new Set,M={debounceMs:300,limit:10,searchTone:.5};let x=[...S],n=Math.max(1,i.limit??M.limit),m=i.filterFn??(()=>!0),u=i.sortFn;const y=i.searchFn??((t,e,o)=>Q.search([...t],e,o)),v=i.searchTone??M.searchTone;let c="",s=0,h=[];const d=()=>{for(const t of T)t()},g=()=>{let t=x;c&&(t=y(t,c,v)),m&&(t=t.filter(m)),t=u?[...t].sort(u):[...t];const e=Math.max(1,Math.ceil(t.length/n));s=Math.min(s,e-1),h=t},D=()=>{if(!h.length)return[];const t=s*n;return h.slice(t,t+n)},r=()=>{g(),d()};let F;const L=(t,e)=>{F&&clearTimeout(F),F=setTimeout(()=>{c=t,F=void 0,r()},e)};return g(),{batch(t){let e=n,o=m,l=u,f=c,b=x,p=s;const w=(a,E,O)=>Math.max(0,Math.min(a,Math.max(0,Math.ceil(E/O)-1)));t({goTo:a=>{p=w(a-1,h.length,e)},setData:a=>{b=[...a],p=0},setFilter:a=>{o=a},setLimit:a=>{e=Math.max(1,a)},setQuery:a=>{f=a,p=0},setSort:a=>{l=a}}),n=e,m=o,u=l,c=f,x=b,s=p,r()},get current(){return D()},goTo(t){const e=Math.max(1,Math.ceil(h.length/n));s=Math.max(0,Math.min(t-1,e-1)),d()},get meta(){const t=h.length,e=Math.max(1,Math.ceil(t/n)),o=t===0,l=Math.min(s+1,e),f=o?0:(l-1)*n+1;return{end:o?0:Math.min(l*n,t),isEmpty:o,isFirst:l<=1,isLast:l>=e,limit:n,page:l,pages:e,start:f,total:t}},next(){const t=Math.max(1,Math.ceil(h.length/n));s<t-1&&(s++,d())},prev(){s>0&&(s--,d())},reset(){n=Math.max(1,i.limit??M.limit),m=i.filterFn??(()=>!0),u=i.sortFn,c="",s=0,r()},search(t,e){c=t,s=0,e?.immediate?r():L(t,i.debounceMs??M.debounceMs)},setData(t){x=[...t],s=0,r()},setFilter(t){m=t,s=0,r()},setLimit(t){n=Math.max(1,t),s=0,r()},setSort(t){u=t,r()},subscribe(t){return T.add(t),()=>T.delete(t)}}}exports.list=j;
2
2
  //# sourceMappingURL=list.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"list.cjs","sources":["../../src/array/list.ts"],"sourcesContent":["import { debounce } from '../function/debounce';\nimport type { Predicate } from '../types';\nimport { chunk } from './chunk';\nimport { search } from './search';\n\ntype Config<T> = {\n filterFn?: Predicate<T>;\n limit?: number;\n sortFn?: (a: T, b: T) => number;\n};\n\nconst DEFAULT_LIMIT = 10;\nconst DEFAULT_SEARCH_TONE = 0.5;\nconst MIN_LIMIT = 1;\n\nfunction getPages<T>(data: T[], size: number, sortFn: Config<T>['sortFn']): T[][] {\n const sortedData = sortFn ? [...data].sort(sortFn) : [...data];\n return chunk<T>(sortedData, size) as T[][];\n}\n\nfunction getData<T>(data: T[], currentFilterFn: Predicate<T>, query = ''): T[] {\n const searchResults = query ? search(data, query, DEFAULT_SEARCH_TONE) : data;\n return searchResults.filter(currentFilterFn) as T[];\n}\n\nexport function list<T>(initialData: T[], config: Config<T> = {}) {\n let { limit = DEFAULT_LIMIT, filterFn = () => true, sortFn } = config;\n let rawData = [...initialData];\n let offset = 0;\n let query = '';\n let data = getData(rawData, filterFn);\n let pages = getPages(data, limit, sortFn);\n\n const update = () => {\n data = getData(rawData, filterFn, query);\n pages = getPages(data, limit, sortFn);\n offset = Math.max(0, Math.min(offset, pages.length - 1));\n return pages[offset] ?? [];\n };\n\n return {\n get current() {\n return pages[offset] ?? [];\n },\n set data(newData: T[]) {\n rawData = [...newData];\n offset = 0;\n update();\n },\n filter(predicate: (item: T) => boolean) {\n filterFn = predicate;\n offset = 0;\n return update();\n },\n set limit(newLimit: number) {\n limit = Math.max(MIN_LIMIT, newLimit);\n update();\n },\n get meta() {\n return {\n end: Math.min(limit * (offset + 1), data.length),\n isEmpty: data.length === 0,\n isFirst: offset === 0,\n isLast: offset === pages.length - 1,\n limit: limit,\n page: offset + 1,\n pages: Math.ceil(data.length / limit),\n start: Math.max(0, limit * offset + 1),\n total: data.length,\n };\n },\n next() {\n if (offset < pages.length - 1) {\n offset++;\n }\n },\n set page(page: number) {\n const index = page - 1;\n const value = index < 0 ? pages.length + index : index;\n offset = Math.max(0, Math.min(value, pages.length - 1));\n },\n get pages() {\n return pages;\n },\n prev() {\n if (offset > 0) {\n offset--;\n }\n },\n reset() {\n offset = 0;\n query = '';\n filterFn = config.filterFn ?? (() => true);\n return update();\n },\n search: debounce((str: string) => {\n query = str;\n return update();\n }),\n sort(fn?: (a: T, b: T) => number) {\n sortFn = fn;\n return update();\n },\n *[Symbol.iterator]() {\n for (const page of pages) {\n yield page;\n }\n },\n };\n}\n"],"names":["DEFAULT_LIMIT","DEFAULT_SEARCH_TONE","MIN_LIMIT","getPages","data","size","sortFn","sortedData","chunk","getData","currentFilterFn","query","search","list","initialData","config","limit","filterFn","rawData","offset","pages","update","newData","predicate","newLimit","page","index","value","debounce","str","fn"],"mappings":"+KAWMA,EAAgB,GAChBC,EAAsB,GACtBC,EAAY,EAElB,SAASC,EAAYC,EAAWC,EAAcC,EAAoC,CAChF,MAAMC,EAAaD,EAAS,CAAC,GAAGF,CAAI,EAAE,KAAKE,CAAM,EAAI,CAAC,GAAGF,CAAI,EAC7D,OAAOI,EAAAA,MAASD,EAAYF,CAAI,CAClC,CAEA,SAASI,EAAWL,EAAWM,EAA+BC,EAAQ,GAAS,CAE7E,OADsBA,EAAQC,EAAAA,OAAOR,EAAMO,EAAOV,CAAmB,EAAIG,GACpD,OAAOM,CAAe,CAC7C,CAEO,SAASG,EAAQC,EAAkBC,EAAoB,GAAI,CAChE,GAAI,CAAE,MAAAC,EAAQhB,EAAe,SAAAiB,EAAW,IAAM,GAAM,OAAAX,GAAWS,EAC3DG,EAAU,CAAC,GAAGJ,CAAW,EACzBK,EAAS,EACTR,EAAQ,GACRP,EAAOK,EAAQS,EAASD,CAAQ,EAChCG,EAAQjB,EAASC,EAAMY,EAAOV,CAAM,EAExC,MAAMe,EAAS,KACbjB,EAAOK,EAAQS,EAASD,EAAUN,CAAK,EACvCS,EAAQjB,EAASC,EAAMY,EAAOV,CAAM,EACpCa,EAAS,KAAK,IAAI,EAAG,KAAK,IAAIA,EAAQC,EAAM,OAAS,CAAC,CAAC,EAChDA,EAAMD,CAAM,GAAK,CAAA,GAG1B,MAAO,CACL,IAAI,SAAU,CACZ,OAAOC,EAAMD,CAAM,GAAK,CAAA,CAC1B,EACA,IAAI,KAAKG,EAAc,CACrBJ,EAAU,CAAC,GAAGI,CAAO,EACrBH,EAAS,EACTE,EAAA,CACF,EACA,OAAOE,EAAiC,CACtC,OAAAN,EAAWM,EACXJ,EAAS,EACFE,EAAA,CACT,EACA,IAAI,MAAMG,EAAkB,CAC1BR,EAAQ,KAAK,IAAId,EAAWsB,CAAQ,EACpCH,EAAA,CACF,EACA,IAAI,MAAO,CACT,MAAO,CACL,IAAK,KAAK,IAAIL,GAASG,EAAS,GAAIf,EAAK,MAAM,EAC/C,QAASA,EAAK,SAAW,EACzB,QAASe,IAAW,EACpB,OAAQA,IAAWC,EAAM,OAAS,EAClC,MAAAJ,EACA,KAAMG,EAAS,EACf,MAAO,KAAK,KAAKf,EAAK,OAASY,CAAK,EACpC,MAAO,KAAK,IAAI,EAAGA,EAAQG,EAAS,CAAC,EACrC,MAAOf,EAAK,MAAA,CAEhB,EACA,MAAO,CACDe,EAASC,EAAM,OAAS,GAC1BD,GAEJ,EACA,IAAI,KAAKM,EAAc,CACrB,MAAMC,EAAQD,EAAO,EACfE,EAAQD,EAAQ,EAAIN,EAAM,OAASM,EAAQA,EACjDP,EAAS,KAAK,IAAI,EAAG,KAAK,IAAIQ,EAAOP,EAAM,OAAS,CAAC,CAAC,CACxD,EACA,IAAI,OAAQ,CACV,OAAOA,CACT,EACA,MAAO,CACDD,EAAS,GACXA,GAEJ,EACA,OAAQ,CACN,OAAAA,EAAS,EACTR,EAAQ,GACRM,EAAWF,EAAO,WAAa,IAAM,IAC9BM,EAAA,CACT,EACA,OAAQO,EAAAA,SAAUC,IAChBlB,EAAQkB,EACDR,EAAA,EACR,EACD,KAAKS,EAA6B,CAChC,OAAAxB,EAASwB,EACFT,EAAA,CACT,EACA,EAAE,OAAO,QAAQ,GAAI,CACnB,UAAWI,KAAQL,EACjB,MAAMK,CAEV,CAAA,CAEJ"}
1
+ {"version":3,"file":"list.cjs","sources":["../../src/array/list.ts"],"sourcesContent":["import type { Predicate, Sorter } from '../types';\nimport { search as defaultSearch } from './search';\n\n// #region Meta\nexport type Meta = Readonly<{\n end: number; // inclusive\n isEmpty: boolean;\n isFirst: boolean;\n isLast: boolean;\n limit: number;\n page: number; // 1-based\n pages: number;\n start: number; // 1-based\n total: number;\n}>;\n// #endregion Meta\n\n// #region List\nexport type List<T, F, S> = {\n readonly current: readonly T[];\n readonly meta: Meta;\n subscribe(listener: () => void): () => void;\n\n goTo(page: number): void;\n next(): void;\n prev(): void;\n reset(): void;\n search(query: string, opts?: { immediate?: boolean }): void;\n setData?(data: readonly T[]): void; // implemented by local\n setFilter(filter: F): void;\n setLimit(n: number): void;\n setSort(sort?: S): void;\n\n // Batch updates across properties in one recompute/refetch\n batch(\n mutator: (ctx: {\n setLimit(n: number): void;\n setFilter(f: F): void;\n setSort(s?: S): void;\n setQuery(q: string): void;\n setData?(d: readonly T[]): void; // local-only\n goTo(p: number): void; // 1-based\n }) => void,\n ): void;\n};\n// #endregion List\n\n// #region LocalConfig\ntype LocalConfig<T> = Readonly<{\n debounceMs?: number;\n filterFn?: Predicate<T>;\n limit?: number;\n searchFn?: (items: readonly T[], query: string, tone: number) => readonly T[];\n searchTone?: number;\n sortFn?: Sorter<T>;\n}>;\n// #endregion LocalConfig\n\nexport function list<T>(initialData: readonly T[], cfg: LocalConfig<T> = {}): List<T, Predicate<T>, Sorter<T>> {\n const listeners = new Set<() => void>();\n\n const DEFAULTS = { debounceMs: 300, limit: 10, searchTone: 0.5 } as const;\n\n let rawData: readonly T[] = [...initialData];\n let limit = Math.max(1, cfg.limit ?? DEFAULTS.limit);\n let filterFn: Predicate<T> = cfg.filterFn ?? (() => true);\n let sortFn: Sorter<T> | undefined = cfg.sortFn;\n const searchFn = cfg.searchFn ?? ((items: readonly T[], q: string, t: number) => defaultSearch([...items], q, t));\n const searchTone = cfg.searchTone ?? DEFAULTS.searchTone;\n\n let query = '';\n let offset = 0;\n let view: readonly T[] = [];\n\n const notify = () => {\n for (const l of listeners) {\n l();\n }\n };\n\n const recompute = () => {\n let arr = rawData;\n\n if (query) arr = searchFn(arr, query, searchTone);\n if (filterFn) arr = arr.filter(filterFn);\n arr = sortFn ? [...arr].sort(sortFn) : [...arr];\n\n const pages = Math.max(1, Math.ceil(arr.length / limit));\n offset = Math.min(offset, pages - 1);\n view = arr;\n };\n\n const slice = (): readonly T[] => {\n if (!view.length) return [];\n const start = offset * limit;\n return view.slice(start, start + limit);\n };\n\n const update = () => {\n recompute();\n notify();\n };\n\n let timer: ReturnType<typeof setTimeout> | undefined;\n const debouncedSearch = (q: string, ms: number) => {\n if (timer) clearTimeout(timer);\n timer = setTimeout(() => {\n query = q;\n timer = undefined;\n void update();\n }, ms);\n };\n\n // initial compute\n recompute();\n\n return {\n batch(mutator) {\n let nextLimit = limit;\n let nextFilter = filterFn;\n let nextSort = sortFn;\n let nextQuery = query;\n let nextData = rawData;\n let nextOffset = offset;\n\n const clamp = (i: number, total: number, lim: number) =>\n Math.max(0, Math.min(i, Math.max(0, Math.ceil(total / lim) - 1)));\n\n mutator({\n goTo: (p) => {\n nextOffset = clamp(p - 1, view.length, nextLimit);\n },\n setData: (d) => {\n nextData = [...d];\n nextOffset = 0;\n },\n setFilter: (f) => {\n nextFilter = f;\n },\n setLimit: (n) => {\n nextLimit = Math.max(1, n);\n },\n setQuery: (q) => {\n nextQuery = q;\n nextOffset = 0;\n },\n setSort: (s) => {\n nextSort = s;\n },\n });\n\n // apply once\n limit = nextLimit;\n filterFn = nextFilter;\n sortFn = nextSort;\n query = nextQuery;\n rawData = nextData;\n offset = nextOffset;\n\n update();\n },\n get current() {\n return slice();\n },\n goTo(page) {\n const pages = Math.max(1, Math.ceil(view.length / limit));\n offset = Math.max(0, Math.min(page - 1, pages - 1));\n notify();\n },\n get meta() {\n const total = view.length;\n const pages = Math.max(1, Math.ceil(total / limit));\n const isEmpty = total === 0;\n const page = Math.min(offset + 1, pages);\n const start = isEmpty ? 0 : (page - 1) * limit + 1;\n const end = isEmpty ? 0 : Math.min(page * limit, total);\n return {\n end,\n isEmpty,\n isFirst: page <= 1,\n isLast: page >= pages,\n limit,\n page,\n pages,\n start,\n total,\n };\n },\n next() {\n const pages = Math.max(1, Math.ceil(view.length / limit));\n if (offset < pages - 1) {\n offset++;\n notify();\n }\n },\n prev() {\n if (offset > 0) {\n offset--;\n notify();\n }\n },\n reset() {\n limit = Math.max(1, cfg.limit ?? DEFAULTS.limit);\n filterFn = cfg.filterFn ?? (() => true);\n sortFn = cfg.sortFn;\n query = '';\n offset = 0;\n update();\n },\n search(q, opts) {\n query = q;\n offset = 0;\n if (opts?.immediate) {\n update();\n } else {\n debouncedSearch(q, cfg.debounceMs ?? DEFAULTS.debounceMs);\n }\n },\n setData(data) {\n rawData = [...data];\n offset = 0;\n update();\n },\n setFilter(f) {\n filterFn = f;\n offset = 0;\n update();\n },\n setLimit(n) {\n limit = Math.max(1, n);\n offset = 0;\n update();\n },\n setSort(s) {\n sortFn = s;\n update();\n },\n subscribe(listener) {\n listeners.add(listener);\n return () => listeners.delete(listener);\n },\n };\n}\n"],"names":["list","initialData","cfg","listeners","DEFAULTS","rawData","limit","filterFn","sortFn","searchFn","items","q","t","defaultSearch","searchTone","query","offset","view","notify","l","recompute","arr","pages","slice","start","update","timer","debouncedSearch","ms","mutator","nextLimit","nextFilter","nextSort","nextQuery","nextData","nextOffset","clamp","i","total","lim","p","d","f","n","s","page","isEmpty","opts","data","listener"],"mappings":"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"}
@@ -1,70 +1,107 @@
1
- import { debounce as M } from "../function/debounce.js";
2
- import { chunk as x } from "./chunk.js";
3
- import { search as d } from "./search.js";
4
- const D = 10, E = 0.5, F = 1;
5
- function m(a, o, e) {
6
- const s = e ? [...a].sort(e) : [...a];
7
- return x(s, o);
8
- }
9
- function f(a, o, e = "") {
10
- return (e ? d(a, e, E) : a).filter(o);
11
- }
12
- function _(a, o = {}) {
13
- let { limit: e = D, filterFn: s = () => !0, sortFn: u } = o, h = [...a], t = 0, g = "", l = f(h, s), n = m(l, e, u);
14
- const i = () => (l = f(h, s, g), n = m(l, e, u), t = Math.max(0, Math.min(t, n.length - 1)), n[t] ?? []);
15
- return {
16
- get current() {
17
- return n[t] ?? [];
18
- },
19
- set data(r) {
20
- h = [...r], t = 0, i();
1
+ import { search as A } from "./search.js";
2
+ function U(S, i = {}) {
3
+ const T = /* @__PURE__ */ new Set(), u = { debounceMs: 300, limit: 10, searchTone: 0.5 };
4
+ let x = [...S], a = Math.max(1, i.limit ?? u.limit), m = i.filterFn ?? (() => !0), M = i.sortFn;
5
+ const y = i.searchFn ?? ((t, e, o) => A([...t], e, o)), D = i.searchTone ?? u.searchTone;
6
+ let c = "", n = 0, h = [];
7
+ const d = () => {
8
+ for (const t of T)
9
+ t();
10
+ }, g = () => {
11
+ let t = x;
12
+ c && (t = y(t, c, D)), m && (t = t.filter(m)), t = M ? [...t].sort(M) : [...t];
13
+ const e = Math.max(1, Math.ceil(t.length / a));
14
+ n = Math.min(n, e - 1), h = t;
15
+ }, L = () => {
16
+ if (!h.length) return [];
17
+ const t = n * a;
18
+ return h.slice(t, t + a);
19
+ }, r = () => {
20
+ g(), d();
21
+ };
22
+ let F;
23
+ const v = (t, e) => {
24
+ F && clearTimeout(F), F = setTimeout(() => {
25
+ c = t, F = void 0, r();
26
+ }, e);
27
+ };
28
+ return g(), {
29
+ batch(t) {
30
+ let e = a, o = m, l = M, f = c, b = x, p = n;
31
+ const w = (s, E, Q) => Math.max(0, Math.min(s, Math.max(0, Math.ceil(E / Q) - 1)));
32
+ t({
33
+ goTo: (s) => {
34
+ p = w(s - 1, h.length, e);
35
+ },
36
+ setData: (s) => {
37
+ b = [...s], p = 0;
38
+ },
39
+ setFilter: (s) => {
40
+ o = s;
41
+ },
42
+ setLimit: (s) => {
43
+ e = Math.max(1, s);
44
+ },
45
+ setQuery: (s) => {
46
+ f = s, p = 0;
47
+ },
48
+ setSort: (s) => {
49
+ l = s;
50
+ }
51
+ }), a = e, m = o, M = l, c = f, x = b, n = p, r();
21
52
  },
22
- filter(r) {
23
- return s = r, t = 0, i();
53
+ get current() {
54
+ return L();
24
55
  },
25
- set limit(r) {
26
- e = Math.max(F, r), i();
56
+ goTo(t) {
57
+ const e = Math.max(1, Math.ceil(h.length / a));
58
+ n = Math.max(0, Math.min(t - 1, e - 1)), d();
27
59
  },
28
60
  get meta() {
61
+ const t = h.length, e = Math.max(1, Math.ceil(t / a)), o = t === 0, l = Math.min(n + 1, e), f = o ? 0 : (l - 1) * a + 1;
29
62
  return {
30
- end: Math.min(e * (t + 1), l.length),
31
- isEmpty: l.length === 0,
32
- isFirst: t === 0,
33
- isLast: t === n.length - 1,
34
- limit: e,
35
- page: t + 1,
36
- pages: Math.ceil(l.length / e),
37
- start: Math.max(0, e * t + 1),
38
- total: l.length
63
+ end: o ? 0 : Math.min(l * a, t),
64
+ isEmpty: o,
65
+ isFirst: l <= 1,
66
+ isLast: l >= e,
67
+ limit: a,
68
+ page: l,
69
+ pages: e,
70
+ start: f,
71
+ total: t
39
72
  };
40
73
  },
41
74
  next() {
42
- t < n.length - 1 && t++;
43
- },
44
- set page(r) {
45
- const c = r - 1, p = c < 0 ? n.length + c : c;
46
- t = Math.max(0, Math.min(p, n.length - 1));
47
- },
48
- get pages() {
49
- return n;
75
+ const t = Math.max(1, Math.ceil(h.length / a));
76
+ n < t - 1 && (n++, d());
50
77
  },
51
78
  prev() {
52
- t > 0 && t--;
79
+ n > 0 && (n--, d());
53
80
  },
54
81
  reset() {
55
- return t = 0, g = "", s = o.filterFn ?? (() => !0), i();
82
+ a = Math.max(1, i.limit ?? u.limit), m = i.filterFn ?? (() => !0), M = i.sortFn, c = "", n = 0, r();
83
+ },
84
+ search(t, e) {
85
+ c = t, n = 0, e?.immediate ? r() : v(t, i.debounceMs ?? u.debounceMs);
86
+ },
87
+ setData(t) {
88
+ x = [...t], n = 0, r();
89
+ },
90
+ setFilter(t) {
91
+ m = t, n = 0, r();
92
+ },
93
+ setLimit(t) {
94
+ a = Math.max(1, t), n = 0, r();
56
95
  },
57
- search: M((r) => (g = r, i())),
58
- sort(r) {
59
- return u = r, i();
96
+ setSort(t) {
97
+ M = t, r();
60
98
  },
61
- *[Symbol.iterator]() {
62
- for (const r of n)
63
- yield r;
99
+ subscribe(t) {
100
+ return T.add(t), () => T.delete(t);
64
101
  }
65
102
  };
66
103
  }
67
104
  export {
68
- _ as list
105
+ U as list
69
106
  };
70
107
  //# sourceMappingURL=list.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"list.js","sources":["../../src/array/list.ts"],"sourcesContent":["import { debounce } from '../function/debounce';\nimport type { Predicate } from '../types';\nimport { chunk } from './chunk';\nimport { search } from './search';\n\ntype Config<T> = {\n filterFn?: Predicate<T>;\n limit?: number;\n sortFn?: (a: T, b: T) => number;\n};\n\nconst DEFAULT_LIMIT = 10;\nconst DEFAULT_SEARCH_TONE = 0.5;\nconst MIN_LIMIT = 1;\n\nfunction getPages<T>(data: T[], size: number, sortFn: Config<T>['sortFn']): T[][] {\n const sortedData = sortFn ? [...data].sort(sortFn) : [...data];\n return chunk<T>(sortedData, size) as T[][];\n}\n\nfunction getData<T>(data: T[], currentFilterFn: Predicate<T>, query = ''): T[] {\n const searchResults = query ? search(data, query, DEFAULT_SEARCH_TONE) : data;\n return searchResults.filter(currentFilterFn) as T[];\n}\n\nexport function list<T>(initialData: T[], config: Config<T> = {}) {\n let { limit = DEFAULT_LIMIT, filterFn = () => true, sortFn } = config;\n let rawData = [...initialData];\n let offset = 0;\n let query = '';\n let data = getData(rawData, filterFn);\n let pages = getPages(data, limit, sortFn);\n\n const update = () => {\n data = getData(rawData, filterFn, query);\n pages = getPages(data, limit, sortFn);\n offset = Math.max(0, Math.min(offset, pages.length - 1));\n return pages[offset] ?? [];\n };\n\n return {\n get current() {\n return pages[offset] ?? [];\n },\n set data(newData: T[]) {\n rawData = [...newData];\n offset = 0;\n update();\n },\n filter(predicate: (item: T) => boolean) {\n filterFn = predicate;\n offset = 0;\n return update();\n },\n set limit(newLimit: number) {\n limit = Math.max(MIN_LIMIT, newLimit);\n update();\n },\n get meta() {\n return {\n end: Math.min(limit * (offset + 1), data.length),\n isEmpty: data.length === 0,\n isFirst: offset === 0,\n isLast: offset === pages.length - 1,\n limit: limit,\n page: offset + 1,\n pages: Math.ceil(data.length / limit),\n start: Math.max(0, limit * offset + 1),\n total: data.length,\n };\n },\n next() {\n if (offset < pages.length - 1) {\n offset++;\n }\n },\n set page(page: number) {\n const index = page - 1;\n const value = index < 0 ? pages.length + index : index;\n offset = Math.max(0, Math.min(value, pages.length - 1));\n },\n get pages() {\n return pages;\n },\n prev() {\n if (offset > 0) {\n offset--;\n }\n },\n reset() {\n offset = 0;\n query = '';\n filterFn = config.filterFn ?? (() => true);\n return update();\n },\n search: debounce((str: string) => {\n query = str;\n return update();\n }),\n sort(fn?: (a: T, b: T) => number) {\n sortFn = fn;\n return update();\n },\n *[Symbol.iterator]() {\n for (const page of pages) {\n yield page;\n }\n },\n };\n}\n"],"names":["DEFAULT_LIMIT","DEFAULT_SEARCH_TONE","MIN_LIMIT","getPages","data","size","sortFn","sortedData","chunk","getData","currentFilterFn","query","search","list","initialData","config","limit","filterFn","rawData","offset","pages","update","newData","predicate","newLimit","page","index","value","debounce","str","fn"],"mappings":";;;AAWA,MAAMA,IAAgB,IAChBC,IAAsB,KACtBC,IAAY;AAElB,SAASC,EAAYC,GAAWC,GAAcC,GAAoC;AAChF,QAAMC,IAAaD,IAAS,CAAC,GAAGF,CAAI,EAAE,KAAKE,CAAM,IAAI,CAAC,GAAGF,CAAI;AAC7D,SAAOI,EAASD,GAAYF,CAAI;AAClC;AAEA,SAASI,EAAWL,GAAWM,GAA+BC,IAAQ,IAAS;AAE7E,UADsBA,IAAQC,EAAOR,GAAMO,GAAOV,CAAmB,IAAIG,GACpD,OAAOM,CAAe;AAC7C;AAEO,SAASG,EAAQC,GAAkBC,IAAoB,IAAI;AAChE,MAAI,EAAE,OAAAC,IAAQhB,GAAe,UAAAiB,IAAW,MAAM,IAAM,QAAAX,MAAWS,GAC3DG,IAAU,CAAC,GAAGJ,CAAW,GACzBK,IAAS,GACTR,IAAQ,IACRP,IAAOK,EAAQS,GAASD,CAAQ,GAChCG,IAAQjB,EAASC,GAAMY,GAAOV,CAAM;AAExC,QAAMe,IAAS,OACbjB,IAAOK,EAAQS,GAASD,GAAUN,CAAK,GACvCS,IAAQjB,EAASC,GAAMY,GAAOV,CAAM,GACpCa,IAAS,KAAK,IAAI,GAAG,KAAK,IAAIA,GAAQC,EAAM,SAAS,CAAC,CAAC,GAChDA,EAAMD,CAAM,KAAK,CAAA;AAG1B,SAAO;AAAA,IACL,IAAI,UAAU;AACZ,aAAOC,EAAMD,CAAM,KAAK,CAAA;AAAA,IAC1B;AAAA,IACA,IAAI,KAAKG,GAAc;AACrB,MAAAJ,IAAU,CAAC,GAAGI,CAAO,GACrBH,IAAS,GACTE,EAAA;AAAA,IACF;AAAA,IACA,OAAOE,GAAiC;AACtC,aAAAN,IAAWM,GACXJ,IAAS,GACFE,EAAA;AAAA,IACT;AAAA,IACA,IAAI,MAAMG,GAAkB;AAC1B,MAAAR,IAAQ,KAAK,IAAId,GAAWsB,CAAQ,GACpCH,EAAA;AAAA,IACF;AAAA,IACA,IAAI,OAAO;AACT,aAAO;AAAA,QACL,KAAK,KAAK,IAAIL,KAASG,IAAS,IAAIf,EAAK,MAAM;AAAA,QAC/C,SAASA,EAAK,WAAW;AAAA,QACzB,SAASe,MAAW;AAAA,QACpB,QAAQA,MAAWC,EAAM,SAAS;AAAA,QAClC,OAAAJ;AAAA,QACA,MAAMG,IAAS;AAAA,QACf,OAAO,KAAK,KAAKf,EAAK,SAASY,CAAK;AAAA,QACpC,OAAO,KAAK,IAAI,GAAGA,IAAQG,IAAS,CAAC;AAAA,QACrC,OAAOf,EAAK;AAAA,MAAA;AAAA,IAEhB;AAAA,IACA,OAAO;AACL,MAAIe,IAASC,EAAM,SAAS,KAC1BD;AAAA,IAEJ;AAAA,IACA,IAAI,KAAKM,GAAc;AACrB,YAAMC,IAAQD,IAAO,GACfE,IAAQD,IAAQ,IAAIN,EAAM,SAASM,IAAQA;AACjD,MAAAP,IAAS,KAAK,IAAI,GAAG,KAAK,IAAIQ,GAAOP,EAAM,SAAS,CAAC,CAAC;AAAA,IACxD;AAAA,IACA,IAAI,QAAQ;AACV,aAAOA;AAAA,IACT;AAAA,IACA,OAAO;AACL,MAAID,IAAS,KACXA;AAAA,IAEJ;AAAA,IACA,QAAQ;AACN,aAAAA,IAAS,GACTR,IAAQ,IACRM,IAAWF,EAAO,aAAa,MAAM,KAC9BM,EAAA;AAAA,IACT;AAAA,IACA,QAAQO,EAAS,CAACC,OAChBlB,IAAQkB,GACDR,EAAA,EACR;AAAA,IACD,KAAKS,GAA6B;AAChC,aAAAxB,IAASwB,GACFT,EAAA;AAAA,IACT;AAAA,IACA,EAAE,OAAO,QAAQ,IAAI;AACnB,iBAAWI,KAAQL;AACjB,cAAMK;AAAA,IAEV;AAAA,EAAA;AAEJ;"}
1
+ {"version":3,"file":"list.js","sources":["../../src/array/list.ts"],"sourcesContent":["import type { Predicate, Sorter } from '../types';\nimport { search as defaultSearch } from './search';\n\n// #region Meta\nexport type Meta = Readonly<{\n end: number; // inclusive\n isEmpty: boolean;\n isFirst: boolean;\n isLast: boolean;\n limit: number;\n page: number; // 1-based\n pages: number;\n start: number; // 1-based\n total: number;\n}>;\n// #endregion Meta\n\n// #region List\nexport type List<T, F, S> = {\n readonly current: readonly T[];\n readonly meta: Meta;\n subscribe(listener: () => void): () => void;\n\n goTo(page: number): void;\n next(): void;\n prev(): void;\n reset(): void;\n search(query: string, opts?: { immediate?: boolean }): void;\n setData?(data: readonly T[]): void; // implemented by local\n setFilter(filter: F): void;\n setLimit(n: number): void;\n setSort(sort?: S): void;\n\n // Batch updates across properties in one recompute/refetch\n batch(\n mutator: (ctx: {\n setLimit(n: number): void;\n setFilter(f: F): void;\n setSort(s?: S): void;\n setQuery(q: string): void;\n setData?(d: readonly T[]): void; // local-only\n goTo(p: number): void; // 1-based\n }) => void,\n ): void;\n};\n// #endregion List\n\n// #region LocalConfig\ntype LocalConfig<T> = Readonly<{\n debounceMs?: number;\n filterFn?: Predicate<T>;\n limit?: number;\n searchFn?: (items: readonly T[], query: string, tone: number) => readonly T[];\n searchTone?: number;\n sortFn?: Sorter<T>;\n}>;\n// #endregion LocalConfig\n\nexport function list<T>(initialData: readonly T[], cfg: LocalConfig<T> = {}): List<T, Predicate<T>, Sorter<T>> {\n const listeners = new Set<() => void>();\n\n const DEFAULTS = { debounceMs: 300, limit: 10, searchTone: 0.5 } as const;\n\n let rawData: readonly T[] = [...initialData];\n let limit = Math.max(1, cfg.limit ?? DEFAULTS.limit);\n let filterFn: Predicate<T> = cfg.filterFn ?? (() => true);\n let sortFn: Sorter<T> | undefined = cfg.sortFn;\n const searchFn = cfg.searchFn ?? ((items: readonly T[], q: string, t: number) => defaultSearch([...items], q, t));\n const searchTone = cfg.searchTone ?? DEFAULTS.searchTone;\n\n let query = '';\n let offset = 0;\n let view: readonly T[] = [];\n\n const notify = () => {\n for (const l of listeners) {\n l();\n }\n };\n\n const recompute = () => {\n let arr = rawData;\n\n if (query) arr = searchFn(arr, query, searchTone);\n if (filterFn) arr = arr.filter(filterFn);\n arr = sortFn ? [...arr].sort(sortFn) : [...arr];\n\n const pages = Math.max(1, Math.ceil(arr.length / limit));\n offset = Math.min(offset, pages - 1);\n view = arr;\n };\n\n const slice = (): readonly T[] => {\n if (!view.length) return [];\n const start = offset * limit;\n return view.slice(start, start + limit);\n };\n\n const update = () => {\n recompute();\n notify();\n };\n\n let timer: ReturnType<typeof setTimeout> | undefined;\n const debouncedSearch = (q: string, ms: number) => {\n if (timer) clearTimeout(timer);\n timer = setTimeout(() => {\n query = q;\n timer = undefined;\n void update();\n }, ms);\n };\n\n // initial compute\n recompute();\n\n return {\n batch(mutator) {\n let nextLimit = limit;\n let nextFilter = filterFn;\n let nextSort = sortFn;\n let nextQuery = query;\n let nextData = rawData;\n let nextOffset = offset;\n\n const clamp = (i: number, total: number, lim: number) =>\n Math.max(0, Math.min(i, Math.max(0, Math.ceil(total / lim) - 1)));\n\n mutator({\n goTo: (p) => {\n nextOffset = clamp(p - 1, view.length, nextLimit);\n },\n setData: (d) => {\n nextData = [...d];\n nextOffset = 0;\n },\n setFilter: (f) => {\n nextFilter = f;\n },\n setLimit: (n) => {\n nextLimit = Math.max(1, n);\n },\n setQuery: (q) => {\n nextQuery = q;\n nextOffset = 0;\n },\n setSort: (s) => {\n nextSort = s;\n },\n });\n\n // apply once\n limit = nextLimit;\n filterFn = nextFilter;\n sortFn = nextSort;\n query = nextQuery;\n rawData = nextData;\n offset = nextOffset;\n\n update();\n },\n get current() {\n return slice();\n },\n goTo(page) {\n const pages = Math.max(1, Math.ceil(view.length / limit));\n offset = Math.max(0, Math.min(page - 1, pages - 1));\n notify();\n },\n get meta() {\n const total = view.length;\n const pages = Math.max(1, Math.ceil(total / limit));\n const isEmpty = total === 0;\n const page = Math.min(offset + 1, pages);\n const start = isEmpty ? 0 : (page - 1) * limit + 1;\n const end = isEmpty ? 0 : Math.min(page * limit, total);\n return {\n end,\n isEmpty,\n isFirst: page <= 1,\n isLast: page >= pages,\n limit,\n page,\n pages,\n start,\n total,\n };\n },\n next() {\n const pages = Math.max(1, Math.ceil(view.length / limit));\n if (offset < pages - 1) {\n offset++;\n notify();\n }\n },\n prev() {\n if (offset > 0) {\n offset--;\n notify();\n }\n },\n reset() {\n limit = Math.max(1, cfg.limit ?? DEFAULTS.limit);\n filterFn = cfg.filterFn ?? (() => true);\n sortFn = cfg.sortFn;\n query = '';\n offset = 0;\n update();\n },\n search(q, opts) {\n query = q;\n offset = 0;\n if (opts?.immediate) {\n update();\n } else {\n debouncedSearch(q, cfg.debounceMs ?? DEFAULTS.debounceMs);\n }\n },\n setData(data) {\n rawData = [...data];\n offset = 0;\n update();\n },\n setFilter(f) {\n filterFn = f;\n offset = 0;\n update();\n },\n setLimit(n) {\n limit = Math.max(1, n);\n offset = 0;\n update();\n },\n setSort(s) {\n sortFn = s;\n update();\n },\n subscribe(listener) {\n listeners.add(listener);\n return () => listeners.delete(listener);\n },\n };\n}\n"],"names":["list","initialData","cfg","listeners","DEFAULTS","rawData","limit","filterFn","sortFn","searchFn","items","q","t","defaultSearch","searchTone","query","offset","view","notify","l","recompute","arr","pages","slice","start","update","timer","debouncedSearch","ms","mutator","nextLimit","nextFilter","nextSort","nextQuery","nextData","nextOffset","clamp","i","total","lim","p","d","f","n","page","isEmpty","opts","data","s","listener"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"pick.cjs","sources":["../../src/array/pick.ts"],"sourcesContent":["import { assert } from '../function/assert';\nimport { IS_ARRAY_ERROR_MSG, isArray } from '../typed/isArray';\nimport { isNil } from '../typed/isNil';\nimport type { CallbackDynamic, Predicate, Result } from '../types';\n\n/**\n * Picks the first element from an array that satisfies a predicate function\n *\n * @example\n * ```ts\n * const arr = [1, 2, 3, 4];\n * pick(arr, x => x * x, x => x > 2) // 9\n * await pick(arr, async x => x * x, x => x > 2) // 9\n * ```\n *\n * @param array - The array to search.\n * @param callback - A function that is called for each element in the array.\n * @param predicate - A function that is called to validate each element in the array.\n *\n * @return The first element that satisfies the predicate, or undefined if no such element is found.\n *\n * @throws {TypeError} If the first argument is not an array.\n */\nexport function pick<T, R, C extends CallbackDynamic<T, R>>(\n array: T[],\n callback: C,\n predicate?: Predicate<T>,\n): Result<C> | undefined {\n assert(isArray(array), IS_ARRAY_ERROR_MSG, { args: { array }, type: TypeError });\n\n const isValid = predicate ?? ((value: T) => !isNil(value));\n\n for (let index = 0; index < array.length; index++) {\n if (isValid(array[index], index, array)) {\n return callback(array[index], index, array) as Result<C>;\n }\n }\n\n return undefined;\n}\n\npick.fp = true;\n"],"names":["pick","array","callback","predicate","assert","isArray","IS_ARRAY_ERROR_MSG","isValid","value","isNil","index"],"mappings":"4LAuBO,SAASA,EACdC,EACAC,EACAC,EACuB,CACvBC,EAAAA,OAAOC,EAAAA,QAAQJ,CAAK,EAAGK,qBAAoB,CAAE,KAAM,CAAE,MAAAL,CAAA,EAAS,KAAM,UAAW,EAE/E,MAAMM,EAAUJ,IAAeK,GAAa,CAACC,EAAAA,MAAMD,CAAK,GAExD,QAASE,EAAQ,EAAGA,EAAQT,EAAM,OAAQS,IACxC,GAAIH,EAAQN,EAAMS,CAAK,EAAGA,EAAOT,CAAK,EACpC,OAAOC,EAASD,EAAMS,CAAK,EAAGA,EAAOT,CAAK,CAKhD,CAEAD,EAAK,GAAK"}
1
+ {"version":3,"file":"pick.cjs","sources":["../../src/array/pick.ts"],"sourcesContent":["import { assert } from '../function/assert';\nimport { IS_ARRAY_ERROR_MSG, isArray } from '../typed/isArray';\nimport { isNil } from '../typed/isNil';\n\n/**\n * Picks the first element from an array that satisfies a predicate function\n *\n * @example\n * ```ts\n * const arr = [1, 2, 3, 4];\n * pick(arr, x => x * x, x => x > 2) // 9\n * await pick(arr, async x => x * x, x => x > 2) // 9\n * ```\n *\n * @param array - The array to search.\n * @param callback - A function that is called for each element in the array.\n * @param predicate - A function that is called to validate each element in the array.\n *\n * @return The first element that satisfies the predicate, or undefined if no such element is found.\n *\n * @throws {TypeError} If the first argument is not an array.\n */\nexport function pick<T, R = T>(\n array: T[],\n callback: (item: T, index: number, array: T[]) => R,\n predicate?: (item: T, index: number, array: T[]) => boolean,\n): R | undefined {\n assert(isArray(array), IS_ARRAY_ERROR_MSG, { args: { array }, type: TypeError });\n\n const isValid = predicate ?? ((value: T) => !isNil(value));\n\n for (let index = 0; index < array.length; index++) {\n if (isValid(array[index], index, array)) {\n return callback(array[index], index, array);\n }\n }\n\n return undefined;\n}\n\npick.fp = true;\n"],"names":["pick","array","callback","predicate","assert","isArray","IS_ARRAY_ERROR_MSG","isValid","value","isNil","index"],"mappings":"4LAsBO,SAASA,EACdC,EACAC,EACAC,EACe,CACfC,EAAAA,OAAOC,EAAAA,QAAQJ,CAAK,EAAGK,qBAAoB,CAAE,KAAM,CAAE,MAAAL,CAAA,EAAS,KAAM,UAAW,EAE/E,MAAMM,EAAUJ,IAAeK,GAAa,CAACC,EAAAA,MAAMD,CAAK,GAExD,QAASE,EAAQ,EAAGA,EAAQT,EAAM,OAAQS,IACxC,GAAIH,EAAQN,EAAMS,CAAK,EAAGA,EAAOT,CAAK,EACpC,OAAOC,EAASD,EAAMS,CAAK,EAAGA,EAAOT,CAAK,CAKhD,CAEAD,EAAK,GAAK"}
@@ -1 +1 @@
1
- {"version":3,"file":"pick.js","sources":["../../src/array/pick.ts"],"sourcesContent":["import { assert } from '../function/assert';\nimport { IS_ARRAY_ERROR_MSG, isArray } from '../typed/isArray';\nimport { isNil } from '../typed/isNil';\nimport type { CallbackDynamic, Predicate, Result } from '../types';\n\n/**\n * Picks the first element from an array that satisfies a predicate function\n *\n * @example\n * ```ts\n * const arr = [1, 2, 3, 4];\n * pick(arr, x => x * x, x => x > 2) // 9\n * await pick(arr, async x => x * x, x => x > 2) // 9\n * ```\n *\n * @param array - The array to search.\n * @param callback - A function that is called for each element in the array.\n * @param predicate - A function that is called to validate each element in the array.\n *\n * @return The first element that satisfies the predicate, or undefined if no such element is found.\n *\n * @throws {TypeError} If the first argument is not an array.\n */\nexport function pick<T, R, C extends CallbackDynamic<T, R>>(\n array: T[],\n callback: C,\n predicate?: Predicate<T>,\n): Result<C> | undefined {\n assert(isArray(array), IS_ARRAY_ERROR_MSG, { args: { array }, type: TypeError });\n\n const isValid = predicate ?? ((value: T) => !isNil(value));\n\n for (let index = 0; index < array.length; index++) {\n if (isValid(array[index], index, array)) {\n return callback(array[index], index, array) as Result<C>;\n }\n }\n\n return undefined;\n}\n\npick.fp = true;\n"],"names":["pick","array","callback","predicate","assert","isArray","IS_ARRAY_ERROR_MSG","isValid","value","isNil","index"],"mappings":";;;AAuBO,SAASA,EACdC,GACAC,GACAC,GACuB;AACvB,EAAAC,EAAOC,EAAQJ,CAAK,GAAGK,GAAoB,EAAE,MAAM,EAAE,OAAAL,EAAA,GAAS,MAAM,WAAW;AAE/E,QAAMM,IAAUJ,MAAc,CAACK,MAAa,CAACC,EAAMD,CAAK;AAExD,WAASE,IAAQ,GAAGA,IAAQT,EAAM,QAAQS;AACxC,QAAIH,EAAQN,EAAMS,CAAK,GAAGA,GAAOT,CAAK;AACpC,aAAOC,EAASD,EAAMS,CAAK,GAAGA,GAAOT,CAAK;AAKhD;AAEAD,EAAK,KAAK;"}
1
+ {"version":3,"file":"pick.js","sources":["../../src/array/pick.ts"],"sourcesContent":["import { assert } from '../function/assert';\nimport { IS_ARRAY_ERROR_MSG, isArray } from '../typed/isArray';\nimport { isNil } from '../typed/isNil';\n\n/**\n * Picks the first element from an array that satisfies a predicate function\n *\n * @example\n * ```ts\n * const arr = [1, 2, 3, 4];\n * pick(arr, x => x * x, x => x > 2) // 9\n * await pick(arr, async x => x * x, x => x > 2) // 9\n * ```\n *\n * @param array - The array to search.\n * @param callback - A function that is called for each element in the array.\n * @param predicate - A function that is called to validate each element in the array.\n *\n * @return The first element that satisfies the predicate, or undefined if no such element is found.\n *\n * @throws {TypeError} If the first argument is not an array.\n */\nexport function pick<T, R = T>(\n array: T[],\n callback: (item: T, index: number, array: T[]) => R,\n predicate?: (item: T, index: number, array: T[]) => boolean,\n): R | undefined {\n assert(isArray(array), IS_ARRAY_ERROR_MSG, { args: { array }, type: TypeError });\n\n const isValid = predicate ?? ((value: T) => !isNil(value));\n\n for (let index = 0; index < array.length; index++) {\n if (isValid(array[index], index, array)) {\n return callback(array[index], index, array);\n }\n }\n\n return undefined;\n}\n\npick.fp = true;\n"],"names":["pick","array","callback","predicate","assert","isArray","IS_ARRAY_ERROR_MSG","isValid","value","isNil","index"],"mappings":";;;AAsBO,SAASA,EACdC,GACAC,GACAC,GACe;AACf,EAAAC,EAAOC,EAAQJ,CAAK,GAAGK,GAAoB,EAAE,MAAM,EAAE,OAAAL,EAAA,GAAS,MAAM,WAAW;AAE/E,QAAMM,IAAUJ,MAAc,CAACK,MAAa,CAACC,EAAMD,CAAK;AAExD,WAASE,IAAQ,GAAGA,IAAQT,EAAM,QAAQS;AACxC,QAAIH,EAAQN,EAAMS,CAAK,GAAGA,GAAOT,CAAK;AACpC,aAAOC,EAASD,EAAMS,CAAK,GAAGA,GAAOT,CAAK;AAKhD;AAEAD,EAAK,KAAK;"}
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});function Q(r){const y=new Set,b=Math.max(1,r.limit??10),O=r.debounceMs??300;let a=1,n=b,h="",u=r.initialFilter,d=r.initialSort,M=[],c=0,f=!1,x=null;const m=new Map,w=new Map,v=t=>JSON.stringify(t),F=()=>({filter:u,limit:n,page:a,search:h||void 0,sort:d}),p=t=>{M=t.items,c=t.total??0;const e=Math.max(1,Math.ceil(c/n));a=Math.min(Math.max(1,a),e)},L=()=>{for(const t of y)t()},P=async t=>{const e=v(t);if(m.has(e)){p(m.get(e));return}if(w.has(e)){await w.get(e),p(m.get(e));return}f=!0,x=null,L();const s=r.fetch(t).then(l=>{m.set(e,l),p(l)}).catch(l=>{x=l?.message??"Request failed",M=[],c=0}).finally(()=>{w.delete(e),f=!1,L()});w.set(e,s),await s},i=async()=>{await P(F())};let g;const k=()=>{g&&clearTimeout(g),g=setTimeout(()=>{g=void 0,i()},O)};return{async batch(t){let e=a,s=n,l=h,S=u,T=d;t({goTo:o=>{e=Math.max(1,o|0)},setFilter:o=>{S=o,e=1},setLimit:o=>{s=Math.max(1,o),e=1},setQuery:o=>{l=o,e=1},setSort:o=>{T=o,e=1}}),a=e,n=s,h=l,u=S,d=T,await i()},get current(){return M},async goTo(t){a=Math.max(1,t|0),await i()},invalidate(){m.clear()},get meta(){const t=c===0,e=Math.max(1,Math.ceil(c/n)),s=Math.min(a,e),l=t?0:(s-1)*n+1;return{end:t?0:Math.min(s*n,c),error:x,isEmpty:t,isFirst:s<=1,isLast:s>=e,limit:n,loading:f,page:s,pages:e,start:l,total:c}},async next(){a+=1,await i()},async prev(){a=Math.max(1,a-1),await i()},async refresh(){m.delete(v(F())),await i()},async reset(){a=1,n=b,h="",u=r.initialFilter,d=r.initialSort,m.clear(),await i()},async search(t,e){h=t,a=1,e?.immediate?await i():k()},async setFilter(t){u=t,a=1,await i()},async setLimit(t){n=Math.max(1,t),a=1,await i()},async setSort(t){d=t,a=1,await i()},subscribe(t){return y.add(t),y.size===1&&M.length===0&&!f&&i(),()=>y.delete(t)}}}exports.remoteList=Q;
2
+ //# sourceMappingURL=remoteList.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remoteList.cjs","sources":["../../src/array/remoteList.ts"],"sourcesContent":["// #region RemoteMeta\nexport type RemoteMeta = Readonly<{\n end: number; // inclusive\n error: string | null;\n isEmpty: boolean;\n isFirst: boolean;\n isLast: boolean;\n limit: number;\n loading: boolean;\n page: number; // 1-based\n pages: number;\n start: number; // 1-based\n total: number;\n}>;\n// #endregion RemoteMeta\n\n// #region RemoteList\nexport type RemoteList<T, F, S> = {\n readonly current: readonly T[];\n readonly meta: RemoteMeta;\n subscribe(listener: () => void): () => void;\n\n goTo(page: number): Promise<void>;\n invalidate?(): void;\n next(): Promise<void>;\n prev(): Promise<void>;\n refresh(): Promise<void>;\n reset(): Promise<void>;\n search(query: string, opts?: { immediate?: boolean }): Promise<void>;\n setFilter(filter: F): Promise<void>;\n setLimit(n: number): Promise<void>;\n setSort(sort?: S): Promise<void>;\n\n // Batch updates across properties in one recompute/refetch\n batch(\n mutator: (ctx: {\n setLimit(n: number): void;\n setFilter(f: F): void;\n setSort(s?: S): void;\n setQuery(q: string): void;\n setData?(d: readonly T[]): void; // local-only\n goTo(p: number): void; // 1-based\n }) => void,\n ): Promise<void>;\n};\n// #endregion RemoteList\n\n// #region RemoteConfig\ntype RemoteQuery<F, S> = Readonly<{\n filter?: F;\n limit: number;\n page: number; // 1-based\n search?: string;\n sort?: S;\n}>;\n\ntype RemoteResult<T> = Readonly<{ items: readonly T[]; total: number }>;\n\ntype RemoteConfig<T, F, S> = Readonly<{\n debounceMs?: number;\n fetch: (q: RemoteQuery<F, S>) => Promise<RemoteResult<T>>;\n initialFilter?: F;\n initialSort?: S;\n limit?: number;\n}>;\n// #endregion RemoteConfig\n\nexport function remoteList<T, F = Record<string, unknown>, S = { key?: string; dir?: 'asc' | 'desc' }>(\n cfg: RemoteConfig<T, F, S>,\n): RemoteList<T, F, S> {\n const listeners = new Set<() => void>();\n\n const limitDefault = Math.max(1, cfg.limit ?? 10);\n const debounceMs = cfg.debounceMs ?? 300;\n\n let page = 1;\n let limit = limitDefault;\n let search = '';\n let filter = cfg.initialFilter as F | undefined;\n let sort = cfg.initialSort as S | undefined;\n\n let items: readonly T[] = [];\n let total = 0;\n let loading = false;\n let error: string | null = null;\n\n const cache = new Map<string, RemoteResult<T>>();\n const inflight = new Map<string, Promise<void>>();\n\n const keyOf = (q: RemoteQuery<F, S>) => JSON.stringify(q);\n const queryOf = (): RemoteQuery<F, S> => ({\n filter,\n limit,\n page,\n search: search || undefined,\n sort,\n });\n\n const assign = (res: RemoteResult<T>) => {\n items = res.items;\n total = res.total ?? 0;\n const pages = Math.max(1, Math.ceil(total / limit));\n page = Math.min(Math.max(1, page), pages);\n };\n\n const notify = () => {\n for (const l of listeners) {\n l();\n }\n };\n\n const fetchQuery = async (q: RemoteQuery<F, S>) => {\n const k = keyOf(q);\n if (cache.has(k)) {\n assign(cache.get(k)!);\n return;\n }\n if (inflight.has(k)) {\n await inflight.get(k);\n assign(cache.get(k)!);\n return;\n }\n loading = true;\n error = null;\n notify();\n const p = cfg\n .fetch(q)\n .then((res) => {\n cache.set(k, res);\n assign(res);\n })\n .catch((e) => {\n error = e?.message ?? 'Request failed';\n items = [];\n total = 0;\n })\n .finally(() => {\n inflight.delete(k);\n loading = false;\n notify();\n });\n inflight.set(k, p);\n await p;\n };\n\n const update = async () => {\n await fetchQuery(queryOf());\n };\n\n // debounced search\n let timer: ReturnType<typeof setTimeout> | undefined;\n const debounced = () => {\n if (timer) clearTimeout(timer);\n timer = setTimeout(() => {\n timer = undefined;\n void update();\n }, debounceMs);\n };\n\n // initial fetch is on the first subscriber or call to refresh; up to you\n return {\n async batch(mutator) {\n // Stage local copies\n let nextPage = page;\n let nextLimit = limit;\n let nextSearch = search;\n let nextFilter = filter as F | undefined;\n let nextSort = sort as S | undefined;\n\n mutator({\n goTo: (p: number) => {\n nextPage = Math.max(1, p | 0);\n },\n setFilter: (f: F) => {\n nextFilter = f;\n nextPage = 1;\n },\n setLimit: (n) => {\n nextLimit = Math.max(1, n);\n nextPage = 1;\n },\n setQuery: (q: string) => {\n nextSearch = q;\n nextPage = 1;\n },\n setSort: (s?: S) => {\n nextSort = s;\n nextPage = 1;\n },\n });\n\n // Apply and update at once\n page = nextPage;\n limit = nextLimit;\n search = nextSearch;\n filter = nextFilter;\n sort = nextSort;\n\n await update();\n },\n get current() {\n return items;\n },\n async goTo(p) {\n page = Math.max(1, p | 0);\n await update();\n },\n invalidate() {\n cache.clear();\n },\n get meta() {\n const isEmpty = total === 0;\n const pages = Math.max(1, Math.ceil(total / limit));\n const safePage = Math.min(page, pages);\n const start = isEmpty ? 0 : (safePage - 1) * limit + 1;\n const end = isEmpty ? 0 : Math.min(safePage * limit, total);\n return {\n end,\n error,\n isEmpty,\n isFirst: safePage <= 1,\n isLast: safePage >= pages,\n limit,\n loading,\n page: safePage,\n pages,\n start,\n total,\n };\n },\n async next() {\n page += 1;\n await update();\n },\n async prev() {\n page = Math.max(1, page - 1);\n await update();\n },\n async refresh() {\n cache.delete(keyOf(queryOf()));\n await update();\n },\n async reset() {\n page = 1;\n limit = limitDefault;\n search = '';\n filter = cfg.initialFilter as F | undefined;\n sort = cfg.initialSort as S | undefined;\n cache.clear();\n await update();\n },\n async search(q, opts) {\n search = q;\n page = 1;\n if (opts?.immediate) await update();\n else debounced();\n },\n async setFilter(f) {\n filter = f;\n page = 1;\n await update();\n },\n async setLimit(n) {\n limit = Math.max(1, n);\n page = 1;\n await update();\n },\n async setSort(s) {\n sort = s;\n page = 1;\n await update();\n },\n subscribe(listener) {\n listeners.add(listener);\n // optional: trigger an initial load on the first subscription\n if (listeners.size === 1 && items.length === 0 && !loading) {\n void update();\n }\n return () => listeners.delete(listener);\n },\n };\n}\n"],"names":["remoteList","cfg","listeners","limitDefault","debounceMs","page","limit","search","filter","sort","items","total","loading","error","cache","inflight","keyOf","q","queryOf","assign","res","pages","notify","l","fetchQuery","k","p","e","update","timer","debounced","mutator","nextPage","nextLimit","nextSearch","nextFilter","nextSort","f","n","s","isEmpty","safePage","start","opts","listener"],"mappings":"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"}