@simplysm/core-common 13.0.69 → 13.0.71
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 +66 -267
- package/dist/common.types.d.ts +14 -14
- package/dist/errors/argument-error.d.ts +10 -10
- package/dist/errors/argument-error.d.ts.map +1 -1
- package/dist/errors/argument-error.js +2 -2
- package/dist/errors/argument-error.js.map +1 -1
- package/dist/errors/not-implemented-error.d.ts +8 -8
- package/dist/errors/not-implemented-error.js +2 -2
- package/dist/errors/not-implemented-error.js.map +1 -1
- package/dist/errors/sd-error.d.ts +10 -10
- package/dist/errors/sd-error.d.ts.map +1 -1
- package/dist/errors/timeout-error.d.ts +10 -10
- package/dist/errors/timeout-error.js +3 -3
- package/dist/errors/timeout-error.js.map +1 -1
- package/dist/extensions/arr-ext.d.ts +2 -2
- package/dist/extensions/arr-ext.helpers.d.ts +8 -8
- package/dist/extensions/arr-ext.helpers.js +1 -1
- package/dist/extensions/arr-ext.helpers.js.map +1 -1
- package/dist/extensions/arr-ext.js +13 -13
- package/dist/extensions/arr-ext.js.map +1 -1
- package/dist/extensions/arr-ext.types.d.ts +57 -57
- package/dist/extensions/arr-ext.types.d.ts.map +1 -1
- package/dist/extensions/map-ext.d.ts +16 -16
- package/dist/extensions/set-ext.d.ts +11 -11
- package/dist/features/debounce-queue.d.ts +17 -15
- package/dist/features/debounce-queue.d.ts.map +1 -1
- package/dist/features/debounce-queue.js +6 -6
- package/dist/features/debounce-queue.js.map +1 -1
- package/dist/features/event-emitter.d.ts +20 -20
- package/dist/features/event-emitter.js +17 -17
- package/dist/features/serial-queue.d.ts +11 -11
- package/dist/features/serial-queue.js +5 -5
- package/dist/features/serial-queue.js.map +1 -1
- package/dist/globals.d.ts +4 -4
- package/dist/types/date-only.d.ts +64 -64
- package/dist/types/date-only.d.ts.map +1 -1
- package/dist/types/date-only.js +63 -63
- package/dist/types/date-time.d.ts +37 -37
- package/dist/types/date-time.d.ts.map +1 -1
- package/dist/types/date-time.js +54 -37
- package/dist/types/date-time.js.map +1 -1
- package/dist/types/lazy-gc-map.d.ts +26 -26
- package/dist/types/lazy-gc-map.d.ts.map +1 -1
- package/dist/types/lazy-gc-map.js +26 -26
- package/dist/types/lazy-gc-map.js.map +1 -1
- package/dist/types/time.d.ts +25 -25
- package/dist/types/time.d.ts.map +1 -1
- package/dist/types/time.js +25 -25
- package/dist/types/time.js.map +1 -1
- package/dist/types/uuid.d.ts +11 -11
- package/dist/types/uuid.d.ts.map +1 -1
- package/dist/types/uuid.js +12 -12
- package/dist/types/uuid.js.map +1 -1
- package/dist/utils/bytes.d.ts +17 -17
- package/dist/utils/bytes.js +4 -4
- package/dist/utils/bytes.js.map +1 -1
- package/dist/utils/date-format.d.ts +45 -45
- package/dist/utils/date-format.js +1 -1
- package/dist/utils/date-format.js.map +1 -1
- package/dist/utils/error.d.ts +4 -4
- package/dist/utils/json.d.ts +17 -17
- package/dist/utils/json.js +3 -3
- package/dist/utils/json.js.map +1 -1
- package/dist/utils/num.d.ts +23 -23
- package/dist/utils/obj.d.ts +111 -111
- package/dist/utils/obj.d.ts.map +1 -1
- package/dist/utils/obj.js +3 -3
- package/dist/utils/obj.js.map +1 -1
- package/dist/utils/path.d.ts +10 -10
- package/dist/utils/primitive.d.ts +5 -5
- package/dist/utils/primitive.js +1 -1
- package/dist/utils/primitive.js.map +1 -1
- package/dist/utils/str.d.ts +46 -46
- package/dist/utils/str.d.ts.map +1 -1
- package/dist/utils/str.js +5 -5
- package/dist/utils/str.js.map +1 -1
- package/dist/utils/template-strings.d.ts +26 -26
- package/dist/utils/transferable.d.ts +18 -18
- package/dist/utils/transferable.js +1 -1
- package/dist/utils/transferable.js.map +1 -1
- package/dist/utils/wait.d.ts +9 -9
- package/dist/utils/xml.d.ts +13 -13
- package/dist/utils/xml.d.ts.map +1 -1
- package/dist/utils/xml.js +1 -0
- package/dist/utils/xml.js.map +1 -1
- package/dist/zip/sd-zip.d.ts +22 -22
- package/dist/zip/sd-zip.js +16 -16
- package/package.json +4 -4
- package/src/common.types.ts +17 -17
- package/src/errors/argument-error.ts +15 -15
- package/src/errors/not-implemented-error.ts +9 -9
- package/src/errors/sd-error.ts +12 -12
- package/src/errors/timeout-error.ts +12 -12
- package/src/extensions/arr-ext.helpers.ts +10 -10
- package/src/extensions/arr-ext.ts +57 -57
- package/src/extensions/arr-ext.types.ts +59 -59
- package/src/extensions/map-ext.ts +16 -16
- package/src/extensions/set-ext.ts +11 -11
- package/src/features/debounce-queue.ts +21 -19
- package/src/features/event-emitter.ts +25 -25
- package/src/features/serial-queue.ts +13 -13
- package/src/globals.ts +4 -4
- package/src/index.ts +1 -1
- package/src/types/date-only.ts +83 -83
- package/src/types/date-time.ts +64 -44
- package/src/types/lazy-gc-map.ts +45 -45
- package/src/types/time.ts +34 -34
- package/src/types/uuid.ts +17 -17
- package/src/utils/bytes.ts +35 -35
- package/src/utils/date-format.ts +65 -65
- package/src/utils/error.ts +4 -4
- package/src/utils/json.ts +39 -39
- package/src/utils/num.ts +23 -23
- package/src/utils/obj.ts +138 -138
- package/src/utils/path.ts +10 -10
- package/src/utils/primitive.ts +6 -6
- package/src/utils/str.ts +260 -261
- package/src/utils/template-strings.ts +29 -29
- package/src/utils/transferable.ts +284 -284
- package/src/utils/wait.ts +10 -10
- package/src/utils/xml.ts +20 -19
- package/src/zip/sd-zip.ts +25 -25
- package/tests/errors/errors.spec.ts +80 -0
- package/tests/extensions/array-extension.spec.ts +796 -0
- package/tests/extensions/map-extension.spec.ts +147 -0
- package/tests/extensions/set-extension.spec.ts +74 -0
- package/tests/types/date-only.spec.ts +638 -0
- package/tests/types/date-time.spec.ts +391 -0
- package/tests/types/lazy-gc-map.spec.ts +692 -0
- package/tests/types/time.spec.ts +559 -0
- package/tests/types/uuid.spec.ts +74 -0
- package/tests/utils/bytes-utils.spec.ts +230 -0
- package/tests/utils/date-format.spec.ts +373 -0
- package/tests/utils/debounce-queue.spec.ts +272 -0
- package/tests/utils/json.spec.ts +486 -0
- package/tests/utils/number.spec.ts +157 -0
- package/tests/utils/object.spec.ts +829 -0
- package/tests/utils/path.spec.ts +78 -0
- package/tests/utils/primitive.spec.ts +43 -0
- package/tests/utils/sd-event-emitter.spec.ts +216 -0
- package/tests/utils/serial-queue.spec.ts +365 -0
- package/tests/utils/string.spec.ts +281 -0
- package/tests/utils/template-strings.spec.ts +57 -0
- package/tests/utils/transferable.spec.ts +703 -0
- package/tests/utils/wait.spec.ts +145 -0
- package/tests/utils/xml.spec.ts +146 -0
- package/tests/zip/sd-zip.spec.ts +238 -0
- package/docs/extensions.md +0 -503
- package/docs/features.md +0 -109
- package/docs/types.md +0 -486
- package/docs/utils.md +0 -780
package/docs/extensions.md
DELETED
|
@@ -1,503 +0,0 @@
|
|
|
1
|
-
# Extensions
|
|
2
|
-
|
|
3
|
-
Array, Map, Set prototype extensions. Activated by `import "@simplysm/core-common"`.
|
|
4
|
-
|
|
5
|
-
## Array extension methods
|
|
6
|
-
|
|
7
|
-
### Query
|
|
8
|
-
|
|
9
|
-
#### single
|
|
10
|
-
|
|
11
|
-
Return single element (error if 2+).
|
|
12
|
-
|
|
13
|
-
```typescript
|
|
14
|
-
import "@simplysm/core-common";
|
|
15
|
-
|
|
16
|
-
const users = [{ id: 1, name: "Alice" }];
|
|
17
|
-
users.single((u) => u.id === 1); // { id: 1, name: "Alice" }
|
|
18
|
-
users.single(); // Returns the only element (throws if 2+)
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
#### first
|
|
22
|
-
|
|
23
|
-
Return first element.
|
|
24
|
-
|
|
25
|
-
```typescript
|
|
26
|
-
users.first(); // First element (or undefined)
|
|
27
|
-
users.first((u) => u.id > 0); // First matching element
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
#### last
|
|
31
|
-
|
|
32
|
-
Return last element.
|
|
33
|
-
|
|
34
|
-
```typescript
|
|
35
|
-
users.last(); // Last element (or undefined)
|
|
36
|
-
users.last((u) => u.id > 0); // Last matching element
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
---
|
|
40
|
-
|
|
41
|
-
### Filtering
|
|
42
|
-
|
|
43
|
-
#### filterExists
|
|
44
|
-
|
|
45
|
-
Remove `null`/`undefined`.
|
|
46
|
-
|
|
47
|
-
```typescript
|
|
48
|
-
[1, null, 2, undefined, 3].filterExists(); // [1, 2, 3]
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
#### ofType
|
|
52
|
-
|
|
53
|
-
Filter by type (`PrimitiveTypeStr` or constructor).
|
|
54
|
-
|
|
55
|
-
```typescript
|
|
56
|
-
import "@simplysm/core-common";
|
|
57
|
-
|
|
58
|
-
// Filter by PrimitiveTypeStr
|
|
59
|
-
mixed.ofType("string"); // string[]
|
|
60
|
-
mixed.ofType("DateTime"); // DateTime[]
|
|
61
|
-
|
|
62
|
-
// Filter by constructor
|
|
63
|
-
mixed.ofType(MyClass); // MyClass[]
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
#### filterAsync
|
|
67
|
-
|
|
68
|
-
Async filter (sequential execution).
|
|
69
|
-
|
|
70
|
-
```typescript
|
|
71
|
-
import "@simplysm/core-common";
|
|
72
|
-
|
|
73
|
-
const activeUsers = await users.filterAsync(async (u) => await isActive(u.id));
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
---
|
|
77
|
-
|
|
78
|
-
### Mapping/Transformation
|
|
79
|
-
|
|
80
|
-
#### mapAsync
|
|
81
|
-
|
|
82
|
-
Async mapping (sequential execution).
|
|
83
|
-
|
|
84
|
-
```typescript
|
|
85
|
-
await ids.mapAsync(async (id) => await fetchUser(id));
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
#### mapMany
|
|
89
|
-
|
|
90
|
-
Flatten nested arrays and remove null/undefined.
|
|
91
|
-
|
|
92
|
-
```typescript
|
|
93
|
-
import "@simplysm/core-common";
|
|
94
|
-
|
|
95
|
-
// Flatten existing nested array
|
|
96
|
-
[[1, 2], [3, 4]].mapMany(); // [1, 2, 3, 4]
|
|
97
|
-
|
|
98
|
-
// Map then flatten
|
|
99
|
-
users.mapMany((u) => u.tags); // all tags from all users
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
#### mapManyAsync
|
|
103
|
-
|
|
104
|
-
Async mapMany (sequential execution).
|
|
105
|
-
|
|
106
|
-
```typescript
|
|
107
|
-
import "@simplysm/core-common";
|
|
108
|
-
|
|
109
|
-
await groups.mapManyAsync(async (g) => await fetchMembers(g.id));
|
|
110
|
-
```
|
|
111
|
-
|
|
112
|
-
#### parallelAsync
|
|
113
|
-
|
|
114
|
-
Parallel async mapping (`Promise.all`).
|
|
115
|
-
|
|
116
|
-
```typescript
|
|
117
|
-
await ids.parallelAsync(async (id) => await fetchUser(id));
|
|
118
|
-
```
|
|
119
|
-
|
|
120
|
-
---
|
|
121
|
-
|
|
122
|
-
### Grouping/Transformation
|
|
123
|
-
|
|
124
|
-
#### groupBy
|
|
125
|
-
|
|
126
|
-
Group by key. Supports primitive keys (O(n)) and object keys (O(n²)).
|
|
127
|
-
|
|
128
|
-
```typescript
|
|
129
|
-
const users = [
|
|
130
|
-
{ id: 1, name: "Alice", dept: "dev" },
|
|
131
|
-
{ id: 2, name: "Bob", dept: "dev" },
|
|
132
|
-
{ id: 3, name: "Charlie", dept: "hr" },
|
|
133
|
-
];
|
|
134
|
-
|
|
135
|
-
users.groupBy((u) => u.dept);
|
|
136
|
-
// [{ key: "dev", values: [...] }, { key: "hr", values: [...] }]
|
|
137
|
-
|
|
138
|
-
// With value selector
|
|
139
|
-
users.groupBy((u) => u.dept, (u) => u.name);
|
|
140
|
-
// [{ key: "dev", values: ["Alice", "Bob"] }, { key: "hr", values: ["Charlie"] }]
|
|
141
|
-
```
|
|
142
|
-
|
|
143
|
-
#### toMap
|
|
144
|
-
|
|
145
|
-
Convert to Map (throws on duplicate key).
|
|
146
|
-
|
|
147
|
-
```typescript
|
|
148
|
-
users.toMap((u) => u.id); // Map<number, User>
|
|
149
|
-
users.toMap((u) => u.id, (u) => u.name); // Map<number, string>
|
|
150
|
-
```
|
|
151
|
-
|
|
152
|
-
#### toMapAsync
|
|
153
|
-
|
|
154
|
-
Async Map conversion (sequential execution).
|
|
155
|
-
|
|
156
|
-
```typescript
|
|
157
|
-
import "@simplysm/core-common";
|
|
158
|
-
|
|
159
|
-
await items.toMapAsync(async (item) => await resolveKey(item));
|
|
160
|
-
```
|
|
161
|
-
|
|
162
|
-
#### toArrayMap
|
|
163
|
-
|
|
164
|
-
Convert to `Map<K, V[]>`.
|
|
165
|
-
|
|
166
|
-
```typescript
|
|
167
|
-
users.toArrayMap((u) => u.dept); // Map<string, User[]>
|
|
168
|
-
```
|
|
169
|
-
|
|
170
|
-
#### toSetMap
|
|
171
|
-
|
|
172
|
-
Convert to `Map<K, Set<V>>`.
|
|
173
|
-
|
|
174
|
-
```typescript
|
|
175
|
-
import "@simplysm/core-common";
|
|
176
|
-
|
|
177
|
-
users.toSetMap((u) => u.dept); // Map<string, Set<User>>
|
|
178
|
-
```
|
|
179
|
-
|
|
180
|
-
#### toMapValues
|
|
181
|
-
|
|
182
|
-
Group by key and aggregate each group with a value selector.
|
|
183
|
-
|
|
184
|
-
```typescript
|
|
185
|
-
import "@simplysm/core-common";
|
|
186
|
-
|
|
187
|
-
// Sum scores per department
|
|
188
|
-
users.toMapValues(
|
|
189
|
-
(u) => u.dept,
|
|
190
|
-
(group) => group.sum((u) => u.score),
|
|
191
|
-
); // Map<string, number>
|
|
192
|
-
```
|
|
193
|
-
|
|
194
|
-
#### toObject
|
|
195
|
-
|
|
196
|
-
Convert to `Record<string, V>` (throws on duplicate key).
|
|
197
|
-
|
|
198
|
-
```typescript
|
|
199
|
-
import "@simplysm/core-common";
|
|
200
|
-
|
|
201
|
-
users.toObject((u) => u.name); // Record<string, User>
|
|
202
|
-
users.toObject((u) => u.name, (u) => u.id); // Record<string, number>
|
|
203
|
-
```
|
|
204
|
-
|
|
205
|
-
#### toTree
|
|
206
|
-
|
|
207
|
-
Convert flat array to tree structure.
|
|
208
|
-
|
|
209
|
-
```typescript
|
|
210
|
-
import "@simplysm/core-common";
|
|
211
|
-
|
|
212
|
-
interface Category { id: number; parentId?: number; name: string }
|
|
213
|
-
|
|
214
|
-
const tree = categories.toTree("id", "parentId");
|
|
215
|
-
// Nodes with null/undefined parentId become roots
|
|
216
|
-
// Each node gains a `children: TreeArray<Category>[]` property
|
|
217
|
-
```
|
|
218
|
-
|
|
219
|
-
---
|
|
220
|
-
|
|
221
|
-
### Deduplication
|
|
222
|
-
|
|
223
|
-
#### distinct
|
|
224
|
-
|
|
225
|
-
Remove duplicates (return new array).
|
|
226
|
-
|
|
227
|
-
```typescript
|
|
228
|
-
// Primitive values
|
|
229
|
-
[1, 2, 2, 3, 3].distinct(); // [1, 2, 3]
|
|
230
|
-
|
|
231
|
-
// Object deep equality (O(n²))
|
|
232
|
-
objects.distinct();
|
|
233
|
-
|
|
234
|
-
// Reference equality (O(n)) — fastest
|
|
235
|
-
objects.distinct(true);
|
|
236
|
-
objects.distinct({ matchAddress: true });
|
|
237
|
-
|
|
238
|
-
// Custom key function (O(n)) — recommended for large arrays of objects
|
|
239
|
-
objects.distinct({ keyFn: (item) => item.id });
|
|
240
|
-
```
|
|
241
|
-
|
|
242
|
-
#### distinctThis
|
|
243
|
-
|
|
244
|
-
Remove duplicates (modify original array).
|
|
245
|
-
|
|
246
|
-
```typescript
|
|
247
|
-
import "@simplysm/core-common";
|
|
248
|
-
|
|
249
|
-
const arr = [1, 2, 2, 3];
|
|
250
|
-
arr.distinctThis(); // arr is now [1, 2, 3]
|
|
251
|
-
|
|
252
|
-
// Same options as distinct
|
|
253
|
-
arr.distinctThis({ keyFn: (item) => item.id });
|
|
254
|
-
```
|
|
255
|
-
|
|
256
|
-
---
|
|
257
|
-
|
|
258
|
-
### Sorting
|
|
259
|
-
|
|
260
|
-
#### orderBy
|
|
261
|
-
|
|
262
|
-
Ascending sort (return new array).
|
|
263
|
-
|
|
264
|
-
```typescript
|
|
265
|
-
users.orderBy((u) => u.name); // Sort by name ascending
|
|
266
|
-
numbers.orderBy(); // Sort numbers ascending
|
|
267
|
-
```
|
|
268
|
-
|
|
269
|
-
#### orderByDesc
|
|
270
|
-
|
|
271
|
-
Descending sort (return new array).
|
|
272
|
-
|
|
273
|
-
```typescript
|
|
274
|
-
users.orderByDesc((u) => u.id);
|
|
275
|
-
```
|
|
276
|
-
|
|
277
|
-
#### orderByThis
|
|
278
|
-
|
|
279
|
-
Ascending sort (modify original array).
|
|
280
|
-
|
|
281
|
-
```typescript
|
|
282
|
-
import "@simplysm/core-common";
|
|
283
|
-
|
|
284
|
-
arr.orderByThis((item) => item.name);
|
|
285
|
-
```
|
|
286
|
-
|
|
287
|
-
#### orderByDescThis
|
|
288
|
-
|
|
289
|
-
Descending sort (modify original array).
|
|
290
|
-
|
|
291
|
-
```typescript
|
|
292
|
-
import "@simplysm/core-common";
|
|
293
|
-
|
|
294
|
-
arr.orderByDescThis((item) => item.score);
|
|
295
|
-
```
|
|
296
|
-
|
|
297
|
-
---
|
|
298
|
-
|
|
299
|
-
### Comparison/Merging
|
|
300
|
-
|
|
301
|
-
#### diffs
|
|
302
|
-
|
|
303
|
-
Compare differences between two arrays. Returns INSERT/DELETE/UPDATE entries.
|
|
304
|
-
|
|
305
|
-
```typescript
|
|
306
|
-
import "@simplysm/core-common";
|
|
307
|
-
|
|
308
|
-
const result = oldList.diffs(newList, { keys: ["id"] });
|
|
309
|
-
for (const diff of result) {
|
|
310
|
-
if (diff.source === undefined) { /* target-only: INSERT */ }
|
|
311
|
-
else if (diff.target === undefined) { /* source-only: DELETE */ }
|
|
312
|
-
else { /* both exist: UPDATE */ }
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
// Exclude certain fields from equality check
|
|
316
|
-
oldList.diffs(newList, { keys: ["id"], excludes: ["updatedAt"] });
|
|
317
|
-
```
|
|
318
|
-
|
|
319
|
-
#### oneWayDiffs
|
|
320
|
-
|
|
321
|
-
One-way diff comparison (create/update/same). Compares current items against original items.
|
|
322
|
-
|
|
323
|
-
```typescript
|
|
324
|
-
import "@simplysm/core-common";
|
|
325
|
-
|
|
326
|
-
const diffs = currentItems.oneWayDiffs(originalItems, "id");
|
|
327
|
-
// { type: "create", item, orgItem: undefined }
|
|
328
|
-
// { type: "update", item, orgItem }
|
|
329
|
-
// { type: "same", item, orgItem } (only when includeSame: true)
|
|
330
|
-
|
|
331
|
-
// With options
|
|
332
|
-
currentItems.oneWayDiffs(originalItems, "id", {
|
|
333
|
-
includeSame: true, // Include unchanged items in result
|
|
334
|
-
excludes: ["updatedAt"], // Ignore these fields when checking for changes
|
|
335
|
-
includes: ["name"], // Only compare these fields
|
|
336
|
-
});
|
|
337
|
-
|
|
338
|
-
// Pass a pre-built Map for O(1) lookup
|
|
339
|
-
const orgMap = originalItems.toMap((item) => item.id);
|
|
340
|
-
currentItems.oneWayDiffs(orgMap, "id");
|
|
341
|
-
```
|
|
342
|
-
|
|
343
|
-
#### merge
|
|
344
|
-
|
|
345
|
-
Merge arrays: apply target changes onto source.
|
|
346
|
-
|
|
347
|
-
```typescript
|
|
348
|
-
import "@simplysm/core-common";
|
|
349
|
-
|
|
350
|
-
const merged = source.merge(target, { keys: ["id"] });
|
|
351
|
-
// Items present in both: merged with objMerge
|
|
352
|
-
// Items only in target: appended
|
|
353
|
-
// Items only in source: kept as-is
|
|
354
|
-
```
|
|
355
|
-
|
|
356
|
-
---
|
|
357
|
-
|
|
358
|
-
### Aggregation
|
|
359
|
-
|
|
360
|
-
#### sum
|
|
361
|
-
|
|
362
|
-
Sum values.
|
|
363
|
-
|
|
364
|
-
```typescript
|
|
365
|
-
import "@simplysm/core-common";
|
|
366
|
-
|
|
367
|
-
[1, 2, 3].sum(); // 6
|
|
368
|
-
users.sum((u) => u.score); // total score
|
|
369
|
-
```
|
|
370
|
-
|
|
371
|
-
#### min
|
|
372
|
-
|
|
373
|
-
Minimum value.
|
|
374
|
-
|
|
375
|
-
```typescript
|
|
376
|
-
import "@simplysm/core-common";
|
|
377
|
-
|
|
378
|
-
[3, 1, 2].min(); // 1
|
|
379
|
-
users.min((u) => u.age); // youngest age
|
|
380
|
-
```
|
|
381
|
-
|
|
382
|
-
#### max
|
|
383
|
-
|
|
384
|
-
Maximum value.
|
|
385
|
-
|
|
386
|
-
```typescript
|
|
387
|
-
import "@simplysm/core-common";
|
|
388
|
-
|
|
389
|
-
[3, 1, 2].max(); // 3
|
|
390
|
-
users.max((u) => u.score); // highest score
|
|
391
|
-
```
|
|
392
|
-
|
|
393
|
-
---
|
|
394
|
-
|
|
395
|
-
### Mutation
|
|
396
|
-
|
|
397
|
-
#### insert
|
|
398
|
-
|
|
399
|
-
Insert at specific position (modify original).
|
|
400
|
-
|
|
401
|
-
```typescript
|
|
402
|
-
import "@simplysm/core-common";
|
|
403
|
-
|
|
404
|
-
const arr = [1, 2, 3];
|
|
405
|
-
arr.insert(1, 10, 11); // [1, 10, 11, 2, 3]
|
|
406
|
-
```
|
|
407
|
-
|
|
408
|
-
#### remove
|
|
409
|
-
|
|
410
|
-
Remove item or items matching predicate (modify original).
|
|
411
|
-
|
|
412
|
-
```typescript
|
|
413
|
-
import "@simplysm/core-common";
|
|
414
|
-
|
|
415
|
-
arr.remove(2); // Remove by value
|
|
416
|
-
arr.remove((item) => item > 2); // Remove by predicate
|
|
417
|
-
```
|
|
418
|
-
|
|
419
|
-
#### toggle
|
|
420
|
-
|
|
421
|
-
Toggle item — remove if exists, add if not (modify original).
|
|
422
|
-
|
|
423
|
-
```typescript
|
|
424
|
-
import "@simplysm/core-common";
|
|
425
|
-
|
|
426
|
-
arr.toggle(3); // removes 3 if present, adds if not
|
|
427
|
-
```
|
|
428
|
-
|
|
429
|
-
#### clear
|
|
430
|
-
|
|
431
|
-
Remove all items (modify original).
|
|
432
|
-
|
|
433
|
-
```typescript
|
|
434
|
-
import "@simplysm/core-common";
|
|
435
|
-
|
|
436
|
-
arr.clear(); // arr is now []
|
|
437
|
-
```
|
|
438
|
-
|
|
439
|
-
#### shuffle
|
|
440
|
-
|
|
441
|
-
Shuffle (return new array).
|
|
442
|
-
|
|
443
|
-
```typescript
|
|
444
|
-
import "@simplysm/core-common";
|
|
445
|
-
|
|
446
|
-
[1, 2, 3, 4, 5].shuffle(); // random order
|
|
447
|
-
```
|
|
448
|
-
|
|
449
|
-
---
|
|
450
|
-
|
|
451
|
-
## Map extension methods
|
|
452
|
-
|
|
453
|
-
### getOrCreate
|
|
454
|
-
|
|
455
|
-
If key doesn't exist, set new value and return.
|
|
456
|
-
|
|
457
|
-
```typescript
|
|
458
|
-
const map = new Map<string, number[]>();
|
|
459
|
-
|
|
460
|
-
// Direct value
|
|
461
|
-
map.getOrCreate("key", []);
|
|
462
|
-
|
|
463
|
-
// Factory function (called only when key is missing)
|
|
464
|
-
map.getOrCreate("key", () => expensiveComputation());
|
|
465
|
-
```
|
|
466
|
-
|
|
467
|
-
> **Note:** If the Map value type is a function (e.g., `Map<string, () => void>`), wrap the function in a factory to store it as a value: `map.getOrCreate("key", () => myFn)`.
|
|
468
|
-
|
|
469
|
-
### update
|
|
470
|
-
|
|
471
|
-
Update value for key using function. The update function receives `undefined` if the key doesn't exist.
|
|
472
|
-
|
|
473
|
-
```typescript
|
|
474
|
-
const countMap = new Map<string, number>();
|
|
475
|
-
countMap.update("key", (v) => (v ?? 0) + 1); // Increment counter
|
|
476
|
-
|
|
477
|
-
const arrayMap = new Map<string, string[]>();
|
|
478
|
-
arrayMap.update("key", (v) => [...(v ?? []), "item"]); // Append to array
|
|
479
|
-
```
|
|
480
|
-
|
|
481
|
-
---
|
|
482
|
-
|
|
483
|
-
## Set extension methods
|
|
484
|
-
|
|
485
|
-
### adds
|
|
486
|
-
|
|
487
|
-
Add multiple values at once.
|
|
488
|
-
|
|
489
|
-
```typescript
|
|
490
|
-
const set = new Set<number>([1, 2, 3]);
|
|
491
|
-
set.adds(4, 5, 6); // {1, 2, 3, 4, 5, 6}
|
|
492
|
-
```
|
|
493
|
-
|
|
494
|
-
### toggle
|
|
495
|
-
|
|
496
|
-
Toggle value (remove if exists, add if not). Optionally force add or delete.
|
|
497
|
-
|
|
498
|
-
```typescript
|
|
499
|
-
set.toggle(2); // 2 exists → remove
|
|
500
|
-
set.toggle(7); // 7 not exists → add
|
|
501
|
-
set.toggle(8, "add"); // Force add regardless of current state
|
|
502
|
-
set.toggle(1, "del"); // Force delete regardless of current state
|
|
503
|
-
```
|
package/docs/features.md
DELETED
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
# Features
|
|
2
|
-
|
|
3
|
-
Async operation control and event handling classes. All support `using` statements or `dispose()`.
|
|
4
|
-
|
|
5
|
-
## DebounceQueue
|
|
6
|
-
|
|
7
|
-
Async debounce queue (executes only last request).
|
|
8
|
-
|
|
9
|
-
```typescript
|
|
10
|
-
import { DebounceQueue } from "@simplysm/core-common";
|
|
11
|
-
|
|
12
|
-
using queue = new DebounceQueue(300); // 300ms debounce delay
|
|
13
|
-
|
|
14
|
-
// Error handling
|
|
15
|
-
queue.on("error", (err) => console.error(err));
|
|
16
|
-
|
|
17
|
-
// Only last call is executed after the delay
|
|
18
|
-
queue.run(() => console.log("1")); // Ignored
|
|
19
|
-
queue.run(() => console.log("2")); // Ignored
|
|
20
|
-
queue.run(() => console.log("3")); // Executed after 300ms
|
|
21
|
-
|
|
22
|
-
// Omit delay for immediate execution (next event loop tick)
|
|
23
|
-
const immediate = new DebounceQueue();
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
> **Note:** A request added while the queue is running is executed immediately after the current run completes (no additional delay). This prevents requests from being lost.
|
|
27
|
-
|
|
28
|
-
---
|
|
29
|
-
|
|
30
|
-
## SerialQueue
|
|
31
|
-
|
|
32
|
-
Async serial queue (sequential execution). Each task starts only after the previous one completes.
|
|
33
|
-
|
|
34
|
-
```typescript
|
|
35
|
-
import { SerialQueue } from "@simplysm/core-common";
|
|
36
|
-
|
|
37
|
-
using queue = new SerialQueue(100); // 100ms gap between tasks (optional, default 0)
|
|
38
|
-
|
|
39
|
-
queue.on("error", (err) => console.error(err));
|
|
40
|
-
|
|
41
|
-
queue.run(async () => { await fetch("/api/1"); });
|
|
42
|
-
queue.run(async () => { await fetch("/api/2"); }); // Runs after #1 completes
|
|
43
|
-
queue.run(async () => { await fetch("/api/3"); }); // Runs after #2 completes
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
> **Note:** Errors in a task are caught and emitted (or logged). Subsequent tasks continue regardless.
|
|
47
|
-
|
|
48
|
-
---
|
|
49
|
-
|
|
50
|
-
## EventEmitter
|
|
51
|
-
|
|
52
|
-
EventTarget wrapper with type-safe events.
|
|
53
|
-
|
|
54
|
-
```typescript
|
|
55
|
-
import { EventEmitter } from "@simplysm/core-common";
|
|
56
|
-
|
|
57
|
-
interface MyEvents {
|
|
58
|
-
data: string;
|
|
59
|
-
error: Error;
|
|
60
|
-
done: void;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
class MyService extends EventEmitter<MyEvents> {
|
|
64
|
-
process(): void {
|
|
65
|
-
this.emit("data", "result data");
|
|
66
|
-
this.emit("done"); // void type called without arguments
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
const service = new MyService();
|
|
71
|
-
const listener = (data: string) => console.log(data);
|
|
72
|
-
service.on("data", listener); // Register listener (type: string inferred)
|
|
73
|
-
service.off("data", listener); // Remove specific listener
|
|
74
|
-
service.listenerCount("data"); // Number of registered listeners
|
|
75
|
-
service.dispose(); // Remove all listeners
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
---
|
|
79
|
-
|
|
80
|
-
## ZipArchive
|
|
81
|
-
|
|
82
|
-
ZIP file compression/decompression utility. Resources can be auto-cleaned with `await using`.
|
|
83
|
-
|
|
84
|
-
```typescript
|
|
85
|
-
import { ZipArchive } from "@simplysm/core-common";
|
|
86
|
-
|
|
87
|
-
// Read ZIP file
|
|
88
|
-
await using archive = new ZipArchive(zipBytes);
|
|
89
|
-
|
|
90
|
-
// Get single file
|
|
91
|
-
const content = await archive.get("file.txt"); // Uint8Array | undefined
|
|
92
|
-
const exists = await archive.exists("data.json"); // boolean
|
|
93
|
-
|
|
94
|
-
// Extract all files (with optional progress callback)
|
|
95
|
-
const files = await archive.extractAll((progress) => {
|
|
96
|
-
// progress: { fileName: string; totalSize: number; extractedSize: number }
|
|
97
|
-
const pct = Math.round((progress.extractedSize / progress.totalSize) * 100);
|
|
98
|
-
console.log(`${progress.fileName}: ${pct}%`);
|
|
99
|
-
});
|
|
100
|
-
// files: Map<string, Uint8Array | undefined>
|
|
101
|
-
|
|
102
|
-
// Create ZIP file
|
|
103
|
-
await using newArchive = new ZipArchive();
|
|
104
|
-
newArchive.write("file.txt", textBytes);
|
|
105
|
-
newArchive.write("data.json", jsonBytes);
|
|
106
|
-
const zipBytes = await newArchive.compress();
|
|
107
|
-
```
|
|
108
|
-
|
|
109
|
-
> **Note:** `compress()` loads all files into memory first. Be mindful of memory usage for large archives.
|