@vielzeug/arsenal 1.1.2 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +31 -75
- package/dist/_dev.cjs +1 -1
- package/dist/_dev.cjs.map +1 -1
- package/dist/_dev.js +2 -5
- package/dist/_dev.js.map +1 -1
- package/dist/array/chunk.cjs +1 -1
- package/dist/array/chunk.cjs.map +1 -1
- package/dist/array/chunk.d.ts +2 -1
- package/dist/array/chunk.d.ts.map +1 -1
- package/dist/array/chunk.js +5 -7
- package/dist/array/chunk.js.map +1 -1
- package/dist/array/compare.cjs +1 -1
- package/dist/array/compare.cjs.map +1 -1
- package/dist/array/compare.d.ts.map +1 -1
- package/dist/array/compare.js +13 -14
- package/dist/array/compare.js.map +1 -1
- package/dist/array/index.cjs +1 -0
- package/dist/array/index.js +29 -0
- package/dist/array/search.cjs +1 -1
- package/dist/array/search.cjs.map +1 -1
- package/dist/array/search.d.ts +8 -77
- package/dist/array/search.d.ts.map +1 -1
- package/dist/array/search.js +21 -38
- package/dist/array/search.js.map +1 -1
- package/dist/array/sort.cjs +1 -1
- package/dist/array/sort.cjs.map +1 -1
- package/dist/array/sort.d.ts +1 -1
- package/dist/array/sort.d.ts.map +1 -1
- package/dist/array/sort.js +9 -10
- package/dist/array/sort.js.map +1 -1
- package/dist/arsenal.cjs +1 -1
- package/dist/arsenal.cjs.map +1 -1
- package/dist/arsenal.iife.js +1 -1
- package/dist/arsenal.iife.js.map +1 -1
- package/dist/arsenal.js +1 -1
- package/dist/arsenal.js.map +1 -1
- package/dist/async/attempt.cjs +1 -1
- package/dist/async/attempt.cjs.map +1 -1
- package/dist/async/attempt.d.ts +3 -8
- package/dist/async/attempt.d.ts.map +1 -1
- package/dist/async/attempt.js +3 -10
- package/dist/async/attempt.js.map +1 -1
- package/dist/async/index.cjs +1 -0
- package/dist/async/index.d.ts +1 -1
- package/dist/async/index.d.ts.map +1 -1
- package/dist/async/index.js +9 -0
- package/dist/async/parallel.cjs +1 -1
- package/dist/async/parallel.cjs.map +1 -1
- package/dist/async/parallel.d.ts +1 -1
- package/dist/async/parallel.d.ts.map +1 -1
- package/dist/async/parallel.js +15 -16
- package/dist/async/parallel.js.map +1 -1
- package/dist/async/retry.cjs +1 -1
- package/dist/async/retry.cjs.map +1 -1
- package/dist/async/retry.d.ts +1 -1
- package/dist/async/retry.d.ts.map +1 -1
- package/dist/async/retry.js +14 -15
- package/dist/async/retry.js.map +1 -1
- package/dist/async/taskPool.cjs +2 -0
- package/dist/async/taskPool.cjs.map +1 -0
- package/dist/async/taskPool.d.ts +14 -0
- package/dist/async/taskPool.d.ts.map +1 -0
- package/dist/async/taskPool.js +51 -0
- package/dist/async/taskPool.js.map +1 -0
- package/dist/cache/cache.cjs +2 -0
- package/dist/cache/cache.cjs.map +1 -0
- package/dist/cache/cache.d.ts +17 -0
- package/dist/cache/cache.d.ts.map +1 -0
- package/dist/cache/cache.js +59 -0
- package/dist/cache/cache.js.map +1 -0
- package/dist/cache/index.cjs +1 -0
- package/dist/cache/index.d.ts +1 -1
- package/dist/cache/index.d.ts.map +1 -1
- package/dist/cache/index.js +3 -0
- package/dist/cache/memo.cjs +1 -1
- package/dist/cache/memo.cjs.map +1 -1
- package/dist/cache/memo.d.ts +2 -2
- package/dist/cache/memo.js +24 -23
- package/dist/cache/memo.js.map +1 -1
- package/dist/errors.cjs +1 -1
- package/dist/errors.cjs.map +1 -1
- package/dist/errors.d.ts +0 -7
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +2 -2
- package/dist/errors.js.map +1 -1
- package/dist/function/debounce.cjs +1 -1
- package/dist/function/debounce.cjs.map +1 -1
- package/dist/function/debounce.js +15 -17
- package/dist/function/debounce.js.map +1 -1
- package/dist/function/index.cjs +1 -0
- package/dist/function/index.d.ts +0 -2
- package/dist/function/index.d.ts.map +1 -1
- package/dist/function/index.js +8 -0
- package/dist/function/pipe.cjs +1 -1
- package/dist/function/pipe.cjs.map +1 -1
- package/dist/function/pipe.js +1 -1
- package/dist/function/pipe.js.map +1 -1
- package/dist/guards/index.cjs +1 -0
- package/dist/guards/index.d.ts +0 -3
- package/dist/guards/index.d.ts.map +1 -1
- package/dist/guards/index.js +17 -0
- package/dist/guards/isEqual.cjs.map +1 -1
- package/dist/guards/isEqual.js.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +2 -91
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +30 -118
- package/dist/math/allocate.cjs +1 -1
- package/dist/math/allocate.cjs.map +1 -1
- package/dist/math/allocate.d.ts +1 -1
- package/dist/math/allocate.d.ts.map +1 -1
- package/dist/math/allocate.js +13 -14
- package/dist/math/allocate.js.map +1 -1
- package/dist/math/index.cjs +1 -0
- package/dist/math/index.d.ts +0 -3
- package/dist/math/index.d.ts.map +1 -1
- package/dist/math/index.js +17 -0
- package/dist/math/mod.cjs +1 -1
- package/dist/math/mod.cjs.map +1 -1
- package/dist/math/mod.d.ts +1 -1
- package/dist/math/mod.d.ts.map +1 -1
- package/dist/math/mod.js +4 -5
- package/dist/math/mod.js.map +1 -1
- package/dist/math/range.cjs +1 -1
- package/dist/math/range.cjs.map +1 -1
- package/dist/math/range.d.ts +1 -1
- package/dist/math/range.d.ts.map +1 -1
- package/dist/math/range.js +14 -15
- package/dist/math/range.js.map +1 -1
- package/dist/math/sum.cjs +1 -1
- package/dist/math/sum.cjs.map +1 -1
- package/dist/math/sum.d.ts +2 -2
- package/dist/math/sum.d.ts.map +1 -1
- package/dist/math/sum.js +6 -7
- package/dist/math/sum.js.map +1 -1
- package/dist/object/getPath.cjs +1 -1
- package/dist/object/getPath.cjs.map +1 -1
- package/dist/object/getPath.d.ts +12 -42
- package/dist/object/getPath.d.ts.map +1 -1
- package/dist/object/getPath.js +21 -22
- package/dist/object/getPath.js.map +1 -1
- package/dist/object/index.cjs +1 -0
- package/dist/object/index.d.ts +1 -1
- package/dist/object/index.d.ts.map +1 -1
- package/dist/object/index.js +15 -0
- package/dist/object/merge.cjs +1 -1
- package/dist/object/merge.cjs.map +1 -1
- package/dist/object/merge.d.ts +1 -1
- package/dist/object/merge.d.ts.map +1 -1
- package/dist/object/merge.js +2 -3
- package/dist/object/merge.js.map +1 -1
- package/dist/object/prune.cjs +1 -1
- package/dist/object/prune.cjs.map +1 -1
- package/dist/object/prune.d.ts.map +1 -1
- package/dist/object/prune.js +22 -23
- package/dist/object/prune.js.map +1 -1
- package/dist/object/tryParseJson.cjs +2 -0
- package/dist/object/tryParseJson.cjs.map +1 -0
- package/dist/object/tryParseJson.d.ts +9 -0
- package/dist/object/tryParseJson.d.ts.map +1 -0
- package/dist/object/tryParseJson.js +18 -0
- package/dist/object/tryParseJson.js.map +1 -0
- package/dist/random/_index.cjs +2 -0
- package/dist/random/_index.cjs.map +1 -0
- package/dist/random/_index.d.ts +3 -0
- package/dist/random/_index.d.ts.map +1 -0
- package/dist/random/_index.js +10 -0
- package/dist/random/_index.js.map +1 -0
- package/dist/random/draw.cjs +1 -1
- package/dist/random/draw.cjs.map +1 -1
- package/dist/random/draw.d.ts +3 -2
- package/dist/random/draw.d.ts.map +1 -1
- package/dist/random/draw.js +12 -12
- package/dist/random/draw.js.map +1 -1
- package/dist/random/index.cjs +1 -0
- package/dist/random/index.d.ts +1 -0
- package/dist/random/index.d.ts.map +1 -1
- package/dist/random/index.js +5 -0
- package/dist/random/random.cjs +1 -1
- package/dist/random/random.cjs.map +1 -1
- package/dist/random/random.d.ts +2 -1
- package/dist/random/random.d.ts.map +1 -1
- package/dist/random/random.js +5 -6
- package/dist/random/random.js.map +1 -1
- package/dist/random/shuffle.cjs +1 -1
- package/dist/random/shuffle.cjs.map +1 -1
- package/dist/random/shuffle.d.ts +2 -1
- package/dist/random/shuffle.d.ts.map +1 -1
- package/dist/random/shuffle.js +7 -7
- package/dist/random/shuffle.js.map +1 -1
- package/dist/random/source.d.ts +4 -0
- package/dist/random/source.d.ts.map +1 -0
- package/dist/string/index.cjs +1 -0
- package/dist/string/index.d.ts +0 -2
- package/dist/string/index.d.ts.map +1 -1
- package/dist/string/index.js +12 -0
- package/dist/string/similarity.cjs +1 -1
- package/dist/string/similarity.cjs.map +1 -1
- package/dist/string/similarity.d.ts.map +1 -1
- package/dist/string/similarity.js +16 -17
- package/dist/string/similarity.js.map +1 -1
- package/dist/string/truncate.cjs +1 -1
- package/dist/string/truncate.cjs.map +1 -1
- package/dist/string/truncate.d.ts +2 -1
- package/dist/string/truncate.d.ts.map +1 -1
- package/dist/string/truncate.js +10 -11
- package/dist/string/truncate.js.map +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/types.d.ts.map +1 -1
- package/package.json +41 -25
- package/dist/_common/_secureRandomIndex.cjs +0 -2
- package/dist/_common/_secureRandomIndex.cjs.map +0 -1
- package/dist/_common/_secureRandomIndex.d.ts +0 -2
- package/dist/_common/_secureRandomIndex.d.ts.map +0 -1
- package/dist/_common/_secureRandomIndex.js +0 -9
- package/dist/_common/_secureRandomIndex.js.map +0 -1
- package/dist/async/queue.cjs +0 -2
- package/dist/async/queue.cjs.map +0 -1
- package/dist/async/queue.d.ts +0 -42
- package/dist/async/queue.d.ts.map +0 -1
- package/dist/async/queue.js +0 -72
- package/dist/async/queue.js.map +0 -1
- package/dist/cache/stash.cjs +0 -2
- package/dist/cache/stash.cjs.map +0 -1
- package/dist/cache/stash.d.ts +0 -111
- package/dist/cache/stash.d.ts.map +0 -1
- package/dist/cache/stash.js +0 -92
- package/dist/cache/stash.js.map +0 -1
- package/dist/function/constant.cjs +0 -2
- package/dist/function/constant.cjs.map +0 -1
- package/dist/function/constant.d.ts +0 -5
- package/dist/function/constant.d.ts.map +0 -1
- package/dist/function/constant.js +0 -8
- package/dist/function/constant.js.map +0 -1
- package/dist/function/identity.cjs +0 -2
- package/dist/function/identity.cjs.map +0 -1
- package/dist/function/identity.d.ts +0 -5
- package/dist/function/identity.d.ts.map +0 -1
- package/dist/function/identity.js +0 -8
- package/dist/function/identity.js.map +0 -1
- package/dist/guards/isArray.cjs +0 -2
- package/dist/guards/isArray.cjs.map +0 -1
- package/dist/guards/isArray.d.ts +0 -16
- package/dist/guards/isArray.d.ts.map +0 -1
- package/dist/guards/isArray.js +0 -8
- package/dist/guards/isArray.js.map +0 -1
- package/dist/guards/isBoolean.cjs +0 -2
- package/dist/guards/isBoolean.cjs.map +0 -1
- package/dist/guards/isBoolean.d.ts +0 -23
- package/dist/guards/isBoolean.d.ts.map +0 -1
- package/dist/guards/isBoolean.js +0 -8
- package/dist/guards/isBoolean.js.map +0 -1
- package/dist/guards/isString.cjs +0 -2
- package/dist/guards/isString.cjs.map +0 -1
- package/dist/guards/isString.d.ts +0 -15
- package/dist/guards/isString.d.ts.map +0 -1
- package/dist/guards/isString.js +0 -8
- package/dist/guards/isString.js.map +0 -1
- package/dist/math/abs.cjs +0 -2
- package/dist/math/abs.cjs.map +0 -1
- package/dist/math/abs.d.ts +0 -17
- package/dist/math/abs.d.ts.map +0 -1
- package/dist/math/abs.js +0 -8
- package/dist/math/abs.js.map +0 -1
- package/dist/math/max.cjs +0 -2
- package/dist/math/max.cjs.map +0 -1
- package/dist/math/max.d.ts +0 -21
- package/dist/math/max.d.ts.map +0 -1
- package/dist/math/max.js +0 -12
- package/dist/math/max.js.map +0 -1
- package/dist/math/min.cjs +0 -2
- package/dist/math/min.cjs.map +0 -1
- package/dist/math/min.d.ts +0 -21
- package/dist/math/min.d.ts.map +0 -1
- package/dist/math/min.js +0 -12
- package/dist/math/min.js.map +0 -1
- package/dist/object/parseJSON.cjs +0 -2
- package/dist/object/parseJSON.cjs.map +0 -1
- package/dist/object/parseJSON.d.ts +0 -32
- package/dist/object/parseJSON.d.ts.map +0 -1
- package/dist/object/parseJSON.js +0 -16
- package/dist/object/parseJSON.js.map +0 -1
- package/dist/string/endsWith.cjs +0 -2
- package/dist/string/endsWith.cjs.map +0 -1
- package/dist/string/endsWith.d.ts +0 -5
- package/dist/string/endsWith.d.ts.map +0 -1
- package/dist/string/endsWith.js +0 -8
- package/dist/string/endsWith.js.map +0 -1
- package/dist/string/startsWith.cjs +0 -2
- package/dist/string/startsWith.cjs.map +0 -1
- package/dist/string/startsWith.d.ts +0 -5
- package/dist/string/startsWith.d.ts.map +0 -1
- package/dist/string/startsWith.js +0 -8
- package/dist/string/startsWith.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,24 +1,9 @@
|
|
|
1
1
|
# @vielzeug/arsenal
|
|
2
2
|
|
|
3
|
-
> Tree-shakeable, zero-dependency
|
|
3
|
+
> Tree-shakeable, zero-dependency TypeScript utilities with focused category entry points.
|
|
4
4
|
|
|
5
5
|
[](https://www.npmjs.com/package/@vielzeug/arsenal) [](https://opensource.org/licenses/MIT)
|
|
6
6
|
|
|
7
|
-
<details>
|
|
8
|
-
<summary>Quick Reference</summary>
|
|
9
|
-
|
|
10
|
-
**Package:** `@vielzeug/arsenal` · **Category:** Utilities
|
|
11
|
-
|
|
12
|
-
**Key exports:** `chunk`, `debounce`, `throttle`, `allOf`, `clamp`, `isEqual`, `retry`, `sleep`, `stringify`, `fuzzy`, `getPath`, `deepMerge`, `diff`, `stash`, `memo`
|
|
13
|
-
|
|
14
|
-
**When to use:** Tree-shakeable, zero-dependency utility library for arrays, async control flow, objects, strings, functions, math, random, and typed checks.
|
|
15
|
-
|
|
16
|
-
**Related:** [`@vielzeug/coins`](https://www.npmjs.com/package/@vielzeug/coins) · [`@vielzeug/tempo`](https://www.npmjs.com/package/@vielzeug/tempo)
|
|
17
|
-
|
|
18
|
-
</details>
|
|
19
|
-
|
|
20
|
-
`@vielzeug/arsenal` is part of Vielzeug and ships as a zero-dependency TypeScript package with ESM+CJS output.
|
|
21
|
-
|
|
22
7
|
## Installation
|
|
23
8
|
|
|
24
9
|
```sh
|
|
@@ -30,67 +15,38 @@ yarn add @vielzeug/arsenal
|
|
|
30
15
|
## Quick Start
|
|
31
16
|
|
|
32
17
|
```ts
|
|
33
|
-
import {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
{ id: 2, name: 'Bob', role: 'user' },
|
|
52
|
-
];
|
|
53
|
-
const pages = chunk([1, 2, 3, 4, 5], 2);
|
|
54
|
-
const byRole = groupBy(users, (u) => u.role);
|
|
55
|
-
const safe = pick(users[0], ['id', 'name']);
|
|
56
|
-
|
|
57
|
-
const q = queue({ concurrency: 2 });
|
|
58
|
-
await q.add(() => fetch('/api/a'));
|
|
59
|
-
|
|
60
|
-
const data = await retry(() => fetch('/api/health').then((r) => r.json()), {
|
|
61
|
-
times: 3,
|
|
62
|
-
delay: 200,
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
const doubleAll = partial((factor: number, values: number[]) => values.map((n) => n * factor), 2);
|
|
66
|
-
const doubled = filterMap(doubleAll([1, 2, 3]), (n) => (n > 2 ? n : undefined));
|
|
67
|
-
|
|
68
|
-
// Compose predicates — allOf / anyOf / noneOf
|
|
69
|
-
const isWorkingAge = allOf<number>(
|
|
70
|
-
(age) => age >= 18,
|
|
71
|
-
(age) => age < 65,
|
|
72
|
-
);
|
|
73
|
-
const evens = [1, 2, 3, 4].filter(noneOf((n: number) => n % 2 !== 0));
|
|
74
|
-
|
|
75
|
-
// Fuzzy search — filter mode or scored mode
|
|
76
|
-
const filtered = fuzzy(users, 'alice'); // User[]
|
|
77
|
-
const ranked = fuzzy(users, 'alice', { scored: true }); // ScoredResult<User>[]
|
|
78
|
-
// [{ item: { name: 'Alice', ... }, score: 0.91 }, ...]
|
|
79
|
-
|
|
80
|
-
// Deep merge with optional array strategy
|
|
81
|
-
deepMerge({ a: { x: 1 } }, { a: { y: 2 } }); // { a: { x: 1, y: 2 } }
|
|
82
|
-
deepMerge({ tags: ['a'] }, { tags: ['b'] }, { arrayStrategy: 'concat' }); // { tags: ['a', 'b'] }
|
|
83
|
-
|
|
84
|
-
// Structured object diff
|
|
85
|
-
diff({ port: 3000, host: 'localhost' }, { port: 4000 });
|
|
86
|
-
// { added: [], removed: ['host'], changed: { port: { before: 3000, after: 4000 } } }
|
|
87
|
-
|
|
88
|
-
// Deterministic cache keys
|
|
89
|
-
const key = stringify({ sort: 'asc', filter: { role: 'admin' } });
|
|
18
|
+
import { chunk, groupBy, retry } from '@vielzeug/arsenal';
|
|
19
|
+
import { fuzzyFilter } from '@vielzeug/arsenal/array';
|
|
20
|
+
import { taskPool } from '@vielzeug/arsenal/async';
|
|
21
|
+
import { cache } from '@vielzeug/arsenal/cache';
|
|
22
|
+
import { tryParseJson } from '@vielzeug/arsenal/object';
|
|
23
|
+
|
|
24
|
+
const parsed = tryParseJson('{"users":[{"name":"Alice"}]}');
|
|
25
|
+
const users = parsed.ok ? (parsed.value as { users: { name: string }[] }).users : [];
|
|
26
|
+
const matches = fuzzyFilter(users, 'ali', { select: (user) => user.name });
|
|
27
|
+
|
|
28
|
+
const pool = taskPool({ concurrency: 2 });
|
|
29
|
+
const data = await pool.run((signal) => retry(() => fetch('/api', { signal }).then((response) => response.json())));
|
|
30
|
+
|
|
31
|
+
const responses = cache<string, unknown>({ ttlMs: 60_000 });
|
|
32
|
+
const profile = await responses.getOrLoad('/profile', () => fetch('/profile').then((response) => response.json()));
|
|
33
|
+
|
|
34
|
+
console.log(chunk([1, 2, 3], 2), groupBy(matches, (user) => user.name), data, profile);
|
|
35
|
+
pool.dispose();
|
|
90
36
|
```
|
|
91
37
|
|
|
92
|
-
|
|
93
|
-
|
|
38
|
+
## Entry Points
|
|
39
|
+
|
|
40
|
+
- `@vielzeug/arsenal` — curated common utilities
|
|
41
|
+
- `@vielzeug/arsenal/array` — array transforms and fuzzy search
|
|
42
|
+
- `@vielzeug/arsenal/async` — cancellation, retry, task pools, timing
|
|
43
|
+
- `@vielzeug/arsenal/cache` — in-memory cache and memoization
|
|
44
|
+
- `@vielzeug/arsenal/function` — function composition and timing
|
|
45
|
+
- `@vielzeug/arsenal/guards` — type guards and predicates
|
|
46
|
+
- `@vielzeug/arsenal/math` — numeric and statistical helpers
|
|
47
|
+
- `@vielzeug/arsenal/object` — object transforms, paths, hash, JSON parsing result
|
|
48
|
+
- `@vielzeug/arsenal/random` — cryptographic random helpers
|
|
49
|
+
- `@vielzeug/arsenal/string` — text transforms and similarity
|
|
94
50
|
|
|
95
51
|
## Documentation
|
|
96
52
|
|
package/dist/_dev.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
function e(e){}exports.warn=e;
|
|
2
2
|
//# sourceMappingURL=_dev.cjs.map
|
package/dist/_dev.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"_dev.cjs","names":[],"sources":["../src/_dev.ts"],"sourcesContent":["const isDev = !(globalThis as { __ARSENAL_PROD__?: boolean }).__ARSENAL_PROD__;\n\n/** @internal @security Messages may include user data. */\nexport function warn(msg: string): void {\n if (isDev) console.warn(`[@vielzeug/arsenal] ${msg}`);\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"_dev.cjs","names":[],"sources":["../src/_dev.ts"],"sourcesContent":["const isDev = !(globalThis as { __ARSENAL_PROD__?: boolean }).__ARSENAL_PROD__;\n\n/** @internal @security Messages may include user data. */\nexport function warn(msg: string): void {\n if (isDev) console.warn(`[@vielzeug/arsenal] ${msg}`);\n}\n"],"mappings":"AAGA,SAAgB,EAAK,EAAmB,CAExC"}
|
package/dist/_dev.js
CHANGED
package/dist/_dev.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"_dev.js","names":[],"sources":["../src/_dev.ts"],"sourcesContent":["const isDev = !(globalThis as { __ARSENAL_PROD__?: boolean }).__ARSENAL_PROD__;\n\n/** @internal @security Messages may include user data. */\nexport function warn(msg: string): void {\n if (isDev) console.warn(`[@vielzeug/arsenal] ${msg}`);\n}\n"],"mappings":";
|
|
1
|
+
{"version":3,"file":"_dev.js","names":[],"sources":["../src/_dev.ts"],"sourcesContent":["const isDev = !(globalThis as { __ARSENAL_PROD__?: boolean }).__ARSENAL_PROD__;\n\n/** @internal @security Messages may include user data. */\nexport function warn(msg: string): void {\n if (isDev) console.warn(`[@vielzeug/arsenal] ${msg}`);\n}\n"],"mappings":";AAGA,SAAgB,EAAK,GAAmB,CAExC"}
|
package/dist/array/chunk.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
function e(e,t=2){if(!Array.isArray(e)&&typeof e!=`string`)throw TypeError(`chunk: argument must be an array or string`);if(!Number.isInteger(t)||t<1)throw RangeError(`chunk: size must be a positive integer`);return Array.from({length:Math.ceil(e.length/t)},(n,r)=>e.slice(r*t,r*t+t))}exports.chunk=e;
|
|
2
2
|
//# sourceMappingURL=chunk.cjs.map
|
package/dist/array/chunk.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chunk.cjs","names":[],"sources":["../../src/array/chunk.ts"],"sourcesContent":["
|
|
1
|
+
{"version":3,"file":"chunk.cjs","names":[],"sources":["../../src/array/chunk.ts"],"sourcesContent":["/**\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 * ```\n *\n * @param input - The input array or string to be chunked.\n * @param size - The size of each chunk (default 2).\n *\n * @returns An array of chunks.\n *\n * @throws {TypeError} If the input is not an array or string.\n * @throws {RangeError} If the chunk size is not a positive integer.\n */\nexport function chunk(input: string, size?: number): string[];\nexport function chunk<T>(input: T[], size?: number): T[][];\nexport function chunk<T>(input: T[] | string, size = 2): string[] | T[][] {\n if (!Array.isArray(input) && typeof input !== 'string')\n throw new TypeError('chunk: argument must be an array or string');\n\n if (!Number.isInteger(size) || size < 1) throw new RangeError('chunk: size must be a positive integer');\n\n return Array.from({ length: Math.ceil(input.length / size) }, (_, i) => input.slice(i * size, i * size + size)) as\n string[] | T[][];\n}\n"],"mappings":"AAmBA,SAAgB,EAAS,EAAqB,EAAO,EAAqB,CACxE,GAAI,CAAC,MAAM,QAAQ,CAAK,GAAK,OAAO,GAAU,SAC5C,MAAU,UAAU,4CAA4C,EAElE,GAAI,CAAC,OAAO,UAAU,CAAI,GAAK,EAAO,EAAG,MAAU,WAAW,wCAAwC,EAEtG,OAAO,MAAM,KAAK,CAAE,OAAQ,KAAK,KAAK,EAAM,OAAS,CAAI,CAAE,GAAI,EAAG,IAAM,EAAM,MAAM,EAAI,EAAM,EAAI,EAAO,CAAI,CAAC,CAEhH"}
|
package/dist/array/chunk.d.ts
CHANGED
|
@@ -12,7 +12,8 @@
|
|
|
12
12
|
*
|
|
13
13
|
* @returns An array of chunks.
|
|
14
14
|
*
|
|
15
|
-
* @throws {
|
|
15
|
+
* @throws {TypeError} If the input is not an array or string.
|
|
16
|
+
* @throws {RangeError} If the chunk size is not a positive integer.
|
|
16
17
|
*/
|
|
17
18
|
export declare function chunk(input: string, size?: number): string[];
|
|
18
19
|
export declare function chunk<T>(input: T[], size?: number): T[][];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chunk.d.ts","sourceRoot":"","sources":["../../src/array/chunk.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"chunk.d.ts","sourceRoot":"","sources":["../../src/array/chunk.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;AAC9D,wBAAgB,KAAK,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,CAAC,EAAE,EAAE,CAAC"}
|
package/dist/array/chunk.js
CHANGED
|
@@ -1,12 +1,10 @@
|
|
|
1
|
-
import { ArsenalValidationError as e } from "../errors.js";
|
|
2
|
-
import { isString as t } from "../guards/isString.js";
|
|
3
1
|
//#region src/array/chunk.ts
|
|
4
|
-
function
|
|
5
|
-
if (!Array.isArray(
|
|
6
|
-
if (
|
|
7
|
-
return Array.from({ length: Math.ceil(
|
|
2
|
+
function e(e, t = 2) {
|
|
3
|
+
if (!Array.isArray(e) && typeof e != "string") throw TypeError("chunk: argument must be an array or string");
|
|
4
|
+
if (!Number.isInteger(t) || t < 1) throw RangeError("chunk: size must be a positive integer");
|
|
5
|
+
return Array.from({ length: Math.ceil(e.length / t) }, (n, r) => e.slice(r * t, r * t + t));
|
|
8
6
|
}
|
|
9
7
|
//#endregion
|
|
10
|
-
export {
|
|
8
|
+
export { e as chunk };
|
|
11
9
|
|
|
12
10
|
//# sourceMappingURL=chunk.js.map
|
package/dist/array/chunk.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chunk.js","names":[],"sources":["../../src/array/chunk.ts"],"sourcesContent":["
|
|
1
|
+
{"version":3,"file":"chunk.js","names":[],"sources":["../../src/array/chunk.ts"],"sourcesContent":["/**\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 * ```\n *\n * @param input - The input array or string to be chunked.\n * @param size - The size of each chunk (default 2).\n *\n * @returns An array of chunks.\n *\n * @throws {TypeError} If the input is not an array or string.\n * @throws {RangeError} If the chunk size is not a positive integer.\n */\nexport function chunk(input: string, size?: number): string[];\nexport function chunk<T>(input: T[], size?: number): T[][];\nexport function chunk<T>(input: T[] | string, size = 2): string[] | T[][] {\n if (!Array.isArray(input) && typeof input !== 'string')\n throw new TypeError('chunk: argument must be an array or string');\n\n if (!Number.isInteger(size) || size < 1) throw new RangeError('chunk: size must be a positive integer');\n\n return Array.from({ length: Math.ceil(input.length / size) }, (_, i) => input.slice(i * size, i * size + size)) as\n string[] | T[][];\n}\n"],"mappings":";AAmBA,SAAgB,EAAS,GAAqB,IAAO,GAAqB;CACxE,IAAI,CAAC,MAAM,QAAQ,CAAK,KAAK,OAAO,KAAU,UAC5C,MAAU,UAAU,4CAA4C;CAElE,IAAI,CAAC,OAAO,UAAU,CAAI,KAAK,IAAO,GAAG,MAAU,WAAW,wCAAwC;CAEtG,OAAO,MAAM,KAAK,EAAE,QAAQ,KAAK,KAAK,EAAM,SAAS,CAAI,EAAE,IAAI,GAAG,MAAM,EAAM,MAAM,IAAI,GAAM,IAAI,IAAO,CAAI,CAAC;AAEhH"}
|
package/dist/array/compare.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
var e=(e,t)=>{if(e===t)return 0;if(e===void 0)return 1;if(t===void 0)return-1;if(e===null)return t===null?0:-1;if(t===null)return 1;if(typeof e==`string`&&typeof t==`string`)return e.localeCompare(t);if(typeof e==`number`&&typeof t==`number`)return e===t?0:e>t?1:-1;if(e instanceof Date&&t instanceof Date){let n=e.getTime(),r=t.getTime();return n===r?0:n>r?1:-1}throw TypeError(`compare: unsupported types "${typeof e}" and "${typeof t}". Supported: number, string, Date, null, undefined.`)};exports.compare=e;
|
|
2
2
|
//# sourceMappingURL=compare.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compare.cjs","names":[],"sources":["../../src/array/compare.ts"],"sourcesContent":["
|
|
1
|
+
{"version":3,"file":"compare.cjs","names":[],"sources":["../../src/array/compare.ts"],"sourcesContent":["/**\n * Compares two values and returns a number suitable for use as a sort comparator.\n *\n * - Numbers and Dates: returns `0`, `1`, or `-1`.\n * - Strings: delegates to `String.prototype.localeCompare`, which may return any integer\n * (not just `0`, `1`, `-1`) depending on locale and engine.\n * - `null` sorts before all non-null values; `undefined` sorts last.\n *\n * @example\n * ```ts\n * compare('a', 'b'); // negative (locale-dependent)\n * compare(1, 2); // -1\n * compare(new Date('2023-01-01'), new Date('2023-01-02')); // -1\n * compare('a', 'a'); // 0\n * compare(1, 1); // 0\n * compare(new Date('2023-01-01'), new Date('2023-01-01')); // 0\n * ```\n *\n * @param a - The first value to compare.\n * @param b - The second value to compare.\n *\n * @returns A negative number, zero, or a positive number.\n *\n * Pass directly as an `Array.sort` comparator:\n * ```ts\n * [3, 1, 2].sort(compare); // [1, 2, 3]\n * ['banana', 'apple', 'cherry'].sort(compare); // ['apple', 'banana', 'cherry']\n * ```\n */\nexport const compare = (a: unknown, b: unknown): number => {\n if (a === b) return 0;\n\n if (a === undefined) return 1;\n\n if (b === undefined) return -1;\n\n if (a === null) return b === null ? 0 : -1;\n\n if (b === null) return 1;\n\n if (typeof a === 'string' && typeof b === 'string') {\n return a.localeCompare(b);\n }\n\n if (typeof a === 'number' && typeof b === 'number') {\n return a === b ? 0 : a > b ? 1 : -1;\n }\n\n if (a instanceof Date && b instanceof Date) {\n const at = a.getTime();\n const bt = b.getTime();\n\n return at === bt ? 0 : at > bt ? 1 : -1;\n }\n\n throw new TypeError(\n `compare: unsupported types \"${typeof a}\" and \"${typeof b}\". Supported: number, string, Date, null, undefined.`,\n );\n};\n"],"mappings":"AA6BA,IAAa,GAAW,EAAY,IAAuB,CACzD,GAAI,IAAM,EAAG,MAAO,GAEpB,GAAI,IAAM,IAAA,GAAW,MAAO,GAE5B,GAAI,IAAM,IAAA,GAAW,MAAO,GAE5B,GAAI,IAAM,KAAM,OAAO,IAAM,KAAO,EAAI,GAExC,GAAI,IAAM,KAAM,MAAO,GAEvB,GAAI,OAAO,GAAM,UAAY,OAAO,GAAM,SACxC,OAAO,EAAE,cAAc,CAAC,EAG1B,GAAI,OAAO,GAAM,UAAY,OAAO,GAAM,SACxC,OAAO,IAAM,EAAI,EAAI,EAAI,EAAI,EAAI,GAGnC,GAAI,aAAa,MAAQ,aAAa,KAAM,CAC1C,IAAM,EAAK,EAAE,QAAQ,EACf,EAAK,EAAE,QAAQ,EAErB,OAAO,IAAO,EAAK,EAAI,EAAK,EAAK,EAAI,EACvC,CAEA,MAAU,UACR,+BAA+B,OAAO,EAAE,SAAS,OAAO,EAAE,qDAC5D,CACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compare.d.ts","sourceRoot":"","sources":["../../src/array/compare.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"compare.d.ts","sourceRoot":"","sources":["../../src/array/compare.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,eAAO,MAAM,OAAO,GAAI,GAAG,OAAO,EAAE,GAAG,OAAO,KAAG,MA6BhD,CAAC"}
|
package/dist/array/compare.js
CHANGED
|
@@ -1,20 +1,19 @@
|
|
|
1
|
-
import { ArsenalValidationError as e } from "../errors.js";
|
|
2
1
|
//#region src/array/compare.ts
|
|
3
|
-
var
|
|
4
|
-
if (
|
|
5
|
-
if (
|
|
6
|
-
if (
|
|
7
|
-
if (
|
|
8
|
-
if (
|
|
9
|
-
if (typeof
|
|
10
|
-
if (typeof
|
|
11
|
-
if (
|
|
12
|
-
let
|
|
13
|
-
return
|
|
2
|
+
var e = (e, t) => {
|
|
3
|
+
if (e === t) return 0;
|
|
4
|
+
if (e === void 0) return 1;
|
|
5
|
+
if (t === void 0) return -1;
|
|
6
|
+
if (e === null) return t === null ? 0 : -1;
|
|
7
|
+
if (t === null) return 1;
|
|
8
|
+
if (typeof e == "string" && typeof t == "string") return e.localeCompare(t);
|
|
9
|
+
if (typeof e == "number" && typeof t == "number") return e === t ? 0 : e > t ? 1 : -1;
|
|
10
|
+
if (e instanceof Date && t instanceof Date) {
|
|
11
|
+
let n = e.getTime(), r = t.getTime();
|
|
12
|
+
return n === r ? 0 : n > r ? 1 : -1;
|
|
14
13
|
}
|
|
15
|
-
throw
|
|
14
|
+
throw TypeError(`compare: unsupported types "${typeof e}" and "${typeof t}". Supported: number, string, Date, null, undefined.`);
|
|
16
15
|
};
|
|
17
16
|
//#endregion
|
|
18
|
-
export {
|
|
17
|
+
export { e as compare };
|
|
19
18
|
|
|
20
19
|
//# sourceMappingURL=compare.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compare.js","names":[],"sources":["../../src/array/compare.ts"],"sourcesContent":["
|
|
1
|
+
{"version":3,"file":"compare.js","names":[],"sources":["../../src/array/compare.ts"],"sourcesContent":["/**\n * Compares two values and returns a number suitable for use as a sort comparator.\n *\n * - Numbers and Dates: returns `0`, `1`, or `-1`.\n * - Strings: delegates to `String.prototype.localeCompare`, which may return any integer\n * (not just `0`, `1`, `-1`) depending on locale and engine.\n * - `null` sorts before all non-null values; `undefined` sorts last.\n *\n * @example\n * ```ts\n * compare('a', 'b'); // negative (locale-dependent)\n * compare(1, 2); // -1\n * compare(new Date('2023-01-01'), new Date('2023-01-02')); // -1\n * compare('a', 'a'); // 0\n * compare(1, 1); // 0\n * compare(new Date('2023-01-01'), new Date('2023-01-01')); // 0\n * ```\n *\n * @param a - The first value to compare.\n * @param b - The second value to compare.\n *\n * @returns A negative number, zero, or a positive number.\n *\n * Pass directly as an `Array.sort` comparator:\n * ```ts\n * [3, 1, 2].sort(compare); // [1, 2, 3]\n * ['banana', 'apple', 'cherry'].sort(compare); // ['apple', 'banana', 'cherry']\n * ```\n */\nexport const compare = (a: unknown, b: unknown): number => {\n if (a === b) return 0;\n\n if (a === undefined) return 1;\n\n if (b === undefined) return -1;\n\n if (a === null) return b === null ? 0 : -1;\n\n if (b === null) return 1;\n\n if (typeof a === 'string' && typeof b === 'string') {\n return a.localeCompare(b);\n }\n\n if (typeof a === 'number' && typeof b === 'number') {\n return a === b ? 0 : a > b ? 1 : -1;\n }\n\n if (a instanceof Date && b instanceof Date) {\n const at = a.getTime();\n const bt = b.getTime();\n\n return at === bt ? 0 : at > bt ? 1 : -1;\n }\n\n throw new TypeError(\n `compare: unsupported types \"${typeof a}\" and \"${typeof b}\". Supported: number, string, Date, null, undefined.`,\n );\n};\n"],"mappings":";AA6BA,IAAa,KAAW,GAAY,MAAuB;CACzD,IAAI,MAAM,GAAG,OAAO;CAEpB,IAAI,MAAM,KAAA,GAAW,OAAO;CAE5B,IAAI,MAAM,KAAA,GAAW,OAAO;CAE5B,IAAI,MAAM,MAAM,OAAO,MAAM,OAAO,IAAI;CAExC,IAAI,MAAM,MAAM,OAAO;CAEvB,IAAI,OAAO,KAAM,YAAY,OAAO,KAAM,UACxC,OAAO,EAAE,cAAc,CAAC;CAG1B,IAAI,OAAO,KAAM,YAAY,OAAO,KAAM,UACxC,OAAO,MAAM,IAAI,IAAI,IAAI,IAAI,IAAI;CAGnC,IAAI,aAAa,QAAQ,aAAa,MAAM;EAC1C,IAAM,IAAK,EAAE,QAAQ,GACf,IAAK,EAAE,QAAQ;EAErB,OAAO,MAAO,IAAK,IAAI,IAAK,IAAK,IAAI;CACvC;CAEA,MAAU,UACR,+BAA+B,OAAO,EAAE,SAAS,OAAO,EAAE,qDAC5D;AACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./chunk.cjs"),t=require("./compact.cjs"),n=require("./compare.cjs"),r=require("./compareBy.cjs"),i=require("./contains.cjs"),a=require("./countBy.cjs"),o=require("./difference.cjs"),s=require("./drop.cjs"),c=require("./dropLast.cjs"),l=require("./filterMap.cjs"),u=require("./first.cjs"),d=require("./flatten.cjs"),f=require("./groupBy.cjs"),p=require("./indexBy.cjs"),m=require("./intersection.cjs"),h=require("./last.cjs"),g=require("./partition.cjs"),_=require("./replace.cjs"),v=require("./rotate.cjs"),y=require("./search.cjs"),b=require("./sort.cjs"),x=require("./take.cjs"),S=require("./takeLast.cjs"),C=require("./toggle.cjs"),w=require("./union.cjs"),T=require("./uniq.cjs"),E=require("./unzip.cjs"),D=require("./zip.cjs");exports.chunk=e.chunk,exports.compact=t.compact,exports.compare=n.compare,exports.compareBy=r.compareBy,exports.contains=i.contains,exports.countBy=a.countBy,exports.difference=o.difference,exports.drop=s.drop,exports.dropLast=c.dropLast,exports.filterMap=l.filterMap,exports.first=u.first,exports.flatten=d.flatten,exports.fuzzyFilter=y.fuzzyFilter,exports.fuzzyScore=y.fuzzyScore,exports.groupBy=f.groupBy,exports.indexBy=p.indexBy,exports.intersection=m.intersection,exports.last=h.last,exports.partition=g.partition,exports.replace=_.replace,exports.rotate=v.rotate,exports.sort=b.sort,exports.take=x.take,exports.takeLast=S.takeLast,exports.toggle=C.toggle,exports.union=w.union,exports.uniq=T.uniq,exports.unzip=E.unzip,exports.zip=D.zip;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { chunk as e } from "./chunk.js";
|
|
2
|
+
import { compact as t } from "./compact.js";
|
|
3
|
+
import { compare as n } from "./compare.js";
|
|
4
|
+
import { compareBy as r } from "./compareBy.js";
|
|
5
|
+
import { contains as i } from "./contains.js";
|
|
6
|
+
import { countBy as a } from "./countBy.js";
|
|
7
|
+
import { difference as o } from "./difference.js";
|
|
8
|
+
import { drop as s } from "./drop.js";
|
|
9
|
+
import { dropLast as c } from "./dropLast.js";
|
|
10
|
+
import { filterMap as l } from "./filterMap.js";
|
|
11
|
+
import { first as u } from "./first.js";
|
|
12
|
+
import { flatten as d } from "./flatten.js";
|
|
13
|
+
import { groupBy as f } from "./groupBy.js";
|
|
14
|
+
import { indexBy as p } from "./indexBy.js";
|
|
15
|
+
import { intersection as m } from "./intersection.js";
|
|
16
|
+
import { last as h } from "./last.js";
|
|
17
|
+
import { partition as g } from "./partition.js";
|
|
18
|
+
import { replace as _ } from "./replace.js";
|
|
19
|
+
import { rotate as v } from "./rotate.js";
|
|
20
|
+
import { fuzzyFilter as y, fuzzyScore as b } from "./search.js";
|
|
21
|
+
import { sort as x } from "./sort.js";
|
|
22
|
+
import { take as S } from "./take.js";
|
|
23
|
+
import { takeLast as C } from "./takeLast.js";
|
|
24
|
+
import { toggle as w } from "./toggle.js";
|
|
25
|
+
import { union as T } from "./union.js";
|
|
26
|
+
import { uniq as E } from "./uniq.js";
|
|
27
|
+
import { unzip as D } from "./unzip.js";
|
|
28
|
+
import { zip as O } from "./zip.js";
|
|
29
|
+
export { e as chunk, t as compact, n as compare, r as compareBy, i as contains, a as countBy, o as difference, s as drop, c as dropLast, l as filterMap, u as first, d as flatten, y as fuzzyFilter, b as fuzzyScore, f as groupBy, p as indexBy, m as intersection, h as last, g as partition, _ as replace, v as rotate, x as sort, S as take, C as takeLast, w as toggle, T as union, E as uniq, D as unzip, O as zip };
|
package/dist/array/search.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const e=require("../
|
|
1
|
+
const e=require("../string/similarity.cjs");var t=e=>e.normalize(`NFKD`).replace(/\p{M}/gu,``),n=(e,t)=>{let n=t(e);return typeof n==`string`?[n]:n},r=(e,n)=>{let r=e.trim().toLowerCase();return n?t(r):r},i=(r,i,a,o)=>n(r,o).reduce((n,r)=>{let o=a?t(r.toLowerCase()):r.toLowerCase();return Math.max(n,e.similarity(o,i))},0),a=e=>e;function o(e,t,n={}){let{normalize:o=!1,threshold:s=.25}=n,c=`select`in n?n.select:a,l=r(t,o);return l?e.filter(e=>i(e,l,o,c)>=s):[...e]}function s(e,t,n={}){let{normalize:o=!1,threshold:s=.25}=n,c=`select`in n?n.select:a,l=r(t,o);return l?e.map(e=>({item:e,score:i(e,l,o,c)})).filter(e=>e.score>=s).sort((e,t)=>t.score-e.score):e.map(e=>({item:e,score:1}))}exports.fuzzyFilter=o,exports.fuzzyScore=s;
|
|
2
2
|
//# sourceMappingURL=search.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"search.cjs","names":[],"sources":["../../src/array/search.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"file":"search.cjs","names":[],"sources":["../../src/array/search.ts"],"sourcesContent":["import { similarity } from '../string/similarity';\n\nexport type ScoredResult<T> = { item: T; score: number };\n\nexport type FuzzyOptions = {\n normalize?: boolean;\n threshold?: number;\n};\n\nexport type FuzzySelection<T> = FuzzyOptions & {\n select: (item: T) => string | readonly string[];\n};\n\nconst normalizeText = (value: string): string => value.normalize('NFKD').replace(/\\p{M}/gu, '');\n\nconst termsFor = <T>(item: T, select: (item: T) => string | readonly string[]): readonly string[] => {\n const selected = select(item);\n\n return typeof selected === 'string' ? [selected] : selected;\n};\n\nconst prepareQuery = (query: string, normalize: boolean): string => {\n const trimmed = query.trim().toLowerCase();\n\n return normalize ? normalizeText(trimmed) : trimmed;\n};\n\nconst score = <T>(\n item: T,\n query: string,\n normalize: boolean,\n select: (item: T) => string | readonly string[],\n): number => {\n return termsFor(item, select).reduce((best, term) => {\n const value = normalize ? normalizeText(term.toLowerCase()) : term.toLowerCase();\n\n return Math.max(best, similarity(value, query));\n }, 0);\n};\n\nconst stringSelection = (value: string): string => value;\n\nexport function fuzzyFilter(array: readonly string[], query: string, options?: FuzzyOptions): string[];\nexport function fuzzyFilter<T>(array: readonly T[], query: string, options: FuzzySelection<T>): T[];\nexport function fuzzyFilter<T>(\n array: readonly T[],\n query: string,\n options: FuzzyOptions | FuzzySelection<T> = {},\n): T[] {\n const { normalize = false, threshold = 0.25 } = options;\n const select = 'select' in options ? options.select : (stringSelection as (item: T) => string);\n const searchTerm = prepareQuery(query, normalize);\n\n if (!searchTerm) return [...array];\n\n return array.filter((item) => score(item, searchTerm, normalize, select) >= threshold);\n}\n\nexport function fuzzyScore(array: readonly string[], query: string, options?: FuzzyOptions): ScoredResult<string>[];\nexport function fuzzyScore<T>(array: readonly T[], query: string, options: FuzzySelection<T>): ScoredResult<T>[];\nexport function fuzzyScore<T>(\n array: readonly T[],\n query: string,\n options: FuzzyOptions | FuzzySelection<T> = {},\n): ScoredResult<T>[] {\n const { normalize = false, threshold = 0.25 } = options;\n const select = 'select' in options ? options.select : (stringSelection as (item: T) => string);\n const searchTerm = prepareQuery(query, normalize);\n\n if (!searchTerm) return array.map((item) => ({ item, score: 1 }));\n\n return array\n .map((item) => ({ item, score: score(item, searchTerm, normalize, select) }))\n .filter((result) => result.score >= threshold)\n .sort((a, b) => b.score - a.score);\n}\n"],"mappings":"4CAaA,IAAM,EAAiB,GAA0B,EAAM,UAAU,MAAM,CAAC,CAAC,QAAQ,UAAW,EAAE,EAExF,GAAe,EAAS,IAAuE,CACnG,IAAM,EAAW,EAAO,CAAI,EAE5B,OAAO,OAAO,GAAa,SAAW,CAAC,CAAQ,EAAI,CACrD,EAEM,GAAgB,EAAe,IAA+B,CAClE,IAAM,EAAU,EAAM,KAAK,CAAC,CAAC,YAAY,EAEzC,OAAO,EAAY,EAAc,CAAO,EAAI,CAC9C,EAEM,GACJ,EACA,EACA,EACA,IAEO,EAAS,EAAM,CAAM,CAAC,CAAC,QAAQ,EAAM,IAAS,CACnD,IAAM,EAAQ,EAAY,EAAc,EAAK,YAAY,CAAC,EAAI,EAAK,YAAY,EAE/E,OAAO,KAAK,IAAI,EAAM,EAAA,WAAW,EAAO,CAAK,CAAC,CAChD,EAAG,CAAC,EAGA,EAAmB,GAA0B,EAInD,SAAgB,EACd,EACA,EACA,EAA4C,CAAC,EACxC,CACL,GAAM,CAAE,YAAY,GAAO,YAAY,KAAS,EAC1C,EAAS,WAAY,EAAU,EAAQ,OAAU,EACjD,EAAa,EAAa,EAAO,CAAS,EAIhD,OAFK,EAEE,EAAM,OAAQ,GAAS,EAAM,EAAM,EAAY,EAAW,CAAM,GAAK,CAAS,EAF7D,CAAC,GAAG,CAAK,CAGnC,CAIA,SAAgB,EACd,EACA,EACA,EAA4C,CAAC,EAC1B,CACnB,GAAM,CAAE,YAAY,GAAO,YAAY,KAAS,EAC1C,EAAS,WAAY,EAAU,EAAQ,OAAU,EACjD,EAAa,EAAa,EAAO,CAAS,EAIhD,OAFK,EAEE,EACJ,IAAK,IAAU,CAAE,OAAM,MAAO,EAAM,EAAM,EAAY,EAAW,CAAM,CAAE,EAAE,CAAC,CAC5E,OAAQ,GAAW,EAAO,OAAS,CAAS,CAAC,CAC7C,MAAM,EAAG,IAAM,EAAE,MAAQ,EAAE,KAAK,EALX,EAAM,IAAK,IAAU,CAAE,OAAM,MAAO,CAAE,EAAE,CAMlE"}
|
package/dist/array/search.d.ts
CHANGED
|
@@ -2,84 +2,15 @@ export type ScoredResult<T> = {
|
|
|
2
2
|
item: T;
|
|
3
3
|
score: number;
|
|
4
4
|
};
|
|
5
|
-
export type FuzzyOptions
|
|
6
|
-
fields?: ReadonlyArray<keyof T & string>;
|
|
7
|
-
/**
|
|
8
|
-
* Maximum recursive depth for full-tree scanning when `fields` is omitted. Values beyond
|
|
9
|
-
* this depth are not searched. Must be a non-negative integer; silently clamped to
|
|
10
|
-
* `HARD_MAX_SEEK_DEPTH` to bound worst-case recursion on untrusted, deeply-nested input.
|
|
11
|
-
* Default: `10`.
|
|
12
|
-
*/
|
|
13
|
-
maxDepth?: number;
|
|
14
|
-
/** When `true`, applies Unicode NFKD normalization before comparison so accented characters match their base form (é ≈ e). Default: `false`. */
|
|
5
|
+
export type FuzzyOptions = {
|
|
15
6
|
normalize?: boolean;
|
|
16
7
|
threshold?: number;
|
|
17
8
|
};
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
* @example
|
|
26
|
-
* ```ts
|
|
27
|
-
* const data = [{ name: 'John Doe', age: 25 }, { name: 'Jane Doe', age: 30 }];
|
|
28
|
-
*
|
|
29
|
-
* fuzzyFilter(data, 'doe'); // [{ name: 'John Doe' }, { name: 'Jane Doe' }]
|
|
30
|
-
* fuzzyFilter(data, 'john', { fields: ['name'] });
|
|
31
|
-
* ```
|
|
32
|
-
*
|
|
33
|
-
* @param array - The array of items to filter.
|
|
34
|
-
* @param query - The string to search for.
|
|
35
|
-
* @param [options.threshold=0.25] - Similarity threshold between 0 and 1. Higher = stricter.
|
|
36
|
-
* @param [options.fields] - Limit search to these object keys. Searches all values when omitted.
|
|
37
|
-
* @param [options.normalize=false] - NFKD normalization so accented chars match base form (é ≈ e).
|
|
38
|
-
* @param [options.maxDepth=10] - Maximum recursive depth when scanning nested values (ignored when `fields` is set).
|
|
39
|
-
* @throws {ArsenalValidationError} If `maxDepth` is provided and is not a non-negative integer.
|
|
40
|
-
*/
|
|
41
|
-
export declare function fuzzyFilter<T>(array: T[], query: string, options?: FuzzyOptions<T>): T[];
|
|
42
|
-
/**
|
|
43
|
-
* Performs a fuzzy score on an array of items using string similarity.
|
|
44
|
-
* Returns all items with their similarity score, filtered by `threshold`, sorted by score descending.
|
|
45
|
-
* When `query` is empty, all items are returned with score `1`.
|
|
46
|
-
*
|
|
47
|
-
* For a simple filtered list without scores, use `fuzzyFilter`.
|
|
48
|
-
*
|
|
49
|
-
* @example
|
|
50
|
-
* ```ts
|
|
51
|
-
* const data = [{ name: 'John Doe', age: 25 }, { name: 'Jane Doe', age: 30 }];
|
|
52
|
-
*
|
|
53
|
-
* fuzzyScore(data, 'john', { fields: ['name'] });
|
|
54
|
-
* // [{ item: { name: 'John Doe', age: 25 }, score: 0.8 }, ...]
|
|
55
|
-
* ```
|
|
56
|
-
*
|
|
57
|
-
* @param array - The array of items to score.
|
|
58
|
-
* @param query - The string to search for.
|
|
59
|
-
* @param [options.threshold=0.25] - Minimum score to include in results.
|
|
60
|
-
* @param [options.fields] - Limit scoring to these object keys. Scores all values when omitted.
|
|
61
|
-
* @param [options.normalize=false] - NFKD normalization so accented chars match base form (é ≈ e).
|
|
62
|
-
* @param [options.maxDepth=10] - Maximum recursive depth when scanning nested values (ignored when `fields` is set).
|
|
63
|
-
* @throws {ArsenalValidationError} If `maxDepth` is provided and is not a non-negative integer.
|
|
64
|
-
*/
|
|
65
|
-
export declare function fuzzyScore<T>(array: T[], query: string, options?: FuzzyOptions<T>): ScoredResult<T>[];
|
|
66
|
-
/**
|
|
67
|
-
* Fuzzy-searches an array. In filter mode (default) returns `T[]`.
|
|
68
|
-
* Pass `{ scored: true }` to return `ScoredResult<T>[]` sorted by relevance descending.
|
|
69
|
-
*
|
|
70
|
-
* @example
|
|
71
|
-
* ```ts
|
|
72
|
-
* const users = [{ name: 'Alice' }, { name: 'Bob' }];
|
|
73
|
-
*
|
|
74
|
-
* fuzzy(users, 'ali'); // [{ name: 'Alice' }]
|
|
75
|
-
* fuzzy(users, 'ali', { scored: true }); // [{ item: { name: 'Alice' }, score: 0.9 }]
|
|
76
|
-
* fuzzy(users, 'ali', { fields: ['name'] }); // field-restricted
|
|
77
|
-
* ```
|
|
78
|
-
*/
|
|
79
|
-
export declare function fuzzy<T>(array: T[], query: string, options: FuzzyOptions<T> & {
|
|
80
|
-
scored: true;
|
|
81
|
-
}): ScoredResult<T>[];
|
|
82
|
-
export declare function fuzzy<T>(array: T[], query: string, options?: FuzzyOptions<T> & {
|
|
83
|
-
scored?: false;
|
|
84
|
-
}): T[];
|
|
9
|
+
export type FuzzySelection<T> = FuzzyOptions & {
|
|
10
|
+
select: (item: T) => string | readonly string[];
|
|
11
|
+
};
|
|
12
|
+
export declare function fuzzyFilter(array: readonly string[], query: string, options?: FuzzyOptions): string[];
|
|
13
|
+
export declare function fuzzyFilter<T>(array: readonly T[], query: string, options: FuzzySelection<T>): T[];
|
|
14
|
+
export declare function fuzzyScore(array: readonly string[], query: string, options?: FuzzyOptions): ScoredResult<string>[];
|
|
15
|
+
export declare function fuzzyScore<T>(array: readonly T[], query: string, options: FuzzySelection<T>): ScoredResult<T>[];
|
|
85
16
|
//# sourceMappingURL=search.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../src/array/search.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../src/array/search.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,YAAY,CAAC,CAAC,IAAI;IAAE,IAAI,EAAE,CAAC,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEzD,MAAM,MAAM,YAAY,GAAG;IACzB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,cAAc,CAAC,CAAC,IAAI,YAAY,GAAG;IAC7C,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,MAAM,GAAG,SAAS,MAAM,EAAE,CAAC;CACjD,CAAC;AA+BF,wBAAgB,WAAW,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,MAAM,EAAE,CAAC;AACvG,wBAAgB,WAAW,CAAC,CAAC,EAAE,KAAK,EAAE,SAAS,CAAC,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;AAepG,wBAAgB,UAAU,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC;AACpH,wBAAgB,UAAU,CAAC,CAAC,EAAE,KAAK,EAAE,SAAS,CAAC,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,CAAC,CAAC,CAAC,GAAG,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC"}
|
package/dist/array/search.js
CHANGED
|
@@ -1,47 +1,30 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { isString as t } from "../guards/isString.js";
|
|
3
|
-
import { isNil as n } from "../guards/isNil.js";
|
|
4
|
-
import { isNumber as r } from "../guards/isNumber.js";
|
|
5
|
-
import { similarity as i } from "../string/similarity.js";
|
|
1
|
+
import { similarity as e } from "../string/similarity.js";
|
|
6
2
|
//#region src/array/search.ts
|
|
7
|
-
var
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
3
|
+
var t = (e) => e.normalize("NFKD").replace(/\p{M}/gu, ""), n = (e, t) => {
|
|
4
|
+
let n = t(e);
|
|
5
|
+
return typeof n == "string" ? [n] : n;
|
|
6
|
+
}, r = (e, n) => {
|
|
7
|
+
let r = e.trim().toLowerCase();
|
|
8
|
+
return n ? t(r) : r;
|
|
9
|
+
}, i = (r, i, a, o) => n(r, o).reduce((n, r) => {
|
|
10
|
+
let o = a ? t(r.toLowerCase()) : r.toLowerCase();
|
|
11
|
+
return Math.max(n, e(o, i));
|
|
12
|
+
}, 0), a = (e) => e;
|
|
13
|
+
function o(e, t, n = {}) {
|
|
14
|
+
let { normalize: o = !1, threshold: s = .25 } = n, c = "select" in n ? n.select : a, l = r(t, o);
|
|
15
|
+
return l ? e.filter((e) => i(e, l, o, c) >= s) : [...e];
|
|
12
16
|
}
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
return
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
}
|
|
20
|
-
function d(e, t, n = {}) {
|
|
21
|
-
let { fields: r, normalize: i = !1, threshold: a = .25 } = n, o = s(n.maxDepth);
|
|
22
|
-
if (!t) return [...e];
|
|
23
|
-
let l = t.trim().toLowerCase();
|
|
24
|
-
if (!l) return [...e];
|
|
25
|
-
let d = i ? c(l) : l;
|
|
26
|
-
return e.filter((e) => r && r.length > 0 && typeof e == "object" && e ? r.some((t) => u(e[t], d, a, i, o)) : u(e, d, a, i, o));
|
|
27
|
-
}
|
|
28
|
-
function f(e, t, n = {}) {
|
|
29
|
-
let { fields: r, normalize: i = !1, threshold: a = .25 } = n, o = s(n.maxDepth);
|
|
30
|
-
if (!t || !t.trim()) return e.map((e) => ({
|
|
17
|
+
function s(e, t, n = {}) {
|
|
18
|
+
let { normalize: o = !1, threshold: s = .25 } = n, c = "select" in n ? n.select : a, l = r(t, o);
|
|
19
|
+
return l ? e.map((e) => ({
|
|
20
|
+
item: e,
|
|
21
|
+
score: i(e, l, o, c)
|
|
22
|
+
})).filter((e) => e.score >= s).sort((e, t) => t.score - e.score) : e.map((e) => ({
|
|
31
23
|
item: e,
|
|
32
24
|
score: 1
|
|
33
25
|
}));
|
|
34
|
-
let u = t.trim().toLowerCase(), d = i ? c(u) : u;
|
|
35
|
-
return e.map((e) => ({
|
|
36
|
-
item: e,
|
|
37
|
-
score: r && r.length > 0 && typeof e == "object" && e ? r.reduce((t, n) => Math.max(t, l(e[n], d, i, o)), 0) : l(e, d, i, o)
|
|
38
|
-
})).filter(({ score: e }) => e >= a).sort((e, t) => t.score - e.score);
|
|
39
|
-
}
|
|
40
|
-
function p(e, t, n = {}) {
|
|
41
|
-
let { scored: r, ...i } = n;
|
|
42
|
-
return r ? f(e, t, i) : d(e, t, i);
|
|
43
26
|
}
|
|
44
27
|
//#endregion
|
|
45
|
-
export {
|
|
28
|
+
export { o as fuzzyFilter, s as fuzzyScore };
|
|
46
29
|
|
|
47
30
|
//# sourceMappingURL=search.js.map
|