@simplysm/core-common 13.0.0-beta.3 → 13.0.0-beta.30

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 (89) hide show
  1. package/README.md +191 -815
  2. package/dist/common.types.js +4 -4
  3. package/dist/errors/argument-error.js +1 -1
  4. package/dist/errors/not-implemented-error.js +1 -1
  5. package/dist/errors/timeout-error.js +1 -1
  6. package/dist/extensions/arr-ext.helpers.js +4 -4
  7. package/dist/extensions/arr-ext.js +9 -9
  8. package/dist/features/debounce-queue.js +2 -2
  9. package/dist/features/serial-queue.js +3 -3
  10. package/dist/index.js +30 -30
  11. package/dist/types/date-only.js +2 -2
  12. package/dist/types/date-time.js +2 -2
  13. package/dist/types/time.js +2 -2
  14. package/dist/types/uuid.js +1 -1
  15. package/dist/utils/bytes.js +1 -1
  16. package/dist/utils/json.js +8 -8
  17. package/dist/utils/obj.js +5 -5
  18. package/dist/utils/primitive.js +5 -5
  19. package/dist/utils/transferable.js +4 -4
  20. package/dist/utils/wait.js +1 -1
  21. package/docs/extensions.md +381 -0
  22. package/docs/features.md +94 -0
  23. package/docs/types.md +338 -0
  24. package/docs/utils.md +631 -0
  25. package/package.json +8 -4
  26. package/.cache/typecheck-browser.tsbuildinfo +0 -1
  27. package/.cache/typecheck-node.tsbuildinfo +0 -1
  28. package/.cache/typecheck-tests-browser.tsbuildinfo +0 -1
  29. package/.cache/typecheck-tests-node.tsbuildinfo +0 -1
  30. package/src/common.types.ts +0 -91
  31. package/src/env.ts +0 -11
  32. package/src/errors/argument-error.ts +0 -40
  33. package/src/errors/not-implemented-error.ts +0 -32
  34. package/src/errors/sd-error.ts +0 -53
  35. package/src/errors/timeout-error.ts +0 -36
  36. package/src/extensions/arr-ext.helpers.ts +0 -53
  37. package/src/extensions/arr-ext.ts +0 -777
  38. package/src/extensions/arr-ext.types.ts +0 -258
  39. package/src/extensions/map-ext.ts +0 -86
  40. package/src/extensions/set-ext.ts +0 -68
  41. package/src/features/debounce-queue.ts +0 -116
  42. package/src/features/event-emitter.ts +0 -112
  43. package/src/features/serial-queue.ts +0 -94
  44. package/src/globals.ts +0 -12
  45. package/src/index.ts +0 -55
  46. package/src/types/date-only.ts +0 -329
  47. package/src/types/date-time.ts +0 -294
  48. package/src/types/lazy-gc-map.ts +0 -244
  49. package/src/types/time.ts +0 -210
  50. package/src/types/uuid.ts +0 -113
  51. package/src/utils/bytes.ts +0 -160
  52. package/src/utils/date-format.ts +0 -239
  53. package/src/utils/json.ts +0 -230
  54. package/src/utils/num.ts +0 -97
  55. package/src/utils/obj.ts +0 -956
  56. package/src/utils/path.ts +0 -40
  57. package/src/utils/primitive.ts +0 -33
  58. package/src/utils/str.ts +0 -252
  59. package/src/utils/template-strings.ts +0 -132
  60. package/src/utils/transferable.ts +0 -269
  61. package/src/utils/wait.ts +0 -40
  62. package/src/utils/xml.ts +0 -105
  63. package/src/zip/sd-zip.ts +0 -218
  64. package/tests/errors/errors.spec.ts +0 -196
  65. package/tests/extensions/array-extension.spec.ts +0 -790
  66. package/tests/extensions/map-extension.spec.ts +0 -147
  67. package/tests/extensions/set-extension.spec.ts +0 -74
  68. package/tests/types/date-only.spec.ts +0 -636
  69. package/tests/types/date-time.spec.ts +0 -391
  70. package/tests/types/lazy-gc-map.spec.ts +0 -692
  71. package/tests/types/time.spec.ts +0 -559
  72. package/tests/types/types.spec.ts +0 -55
  73. package/tests/types/uuid.spec.ts +0 -91
  74. package/tests/utils/bytes-utils.spec.ts +0 -230
  75. package/tests/utils/date-format.spec.ts +0 -371
  76. package/tests/utils/debounce-queue.spec.ts +0 -272
  77. package/tests/utils/json.spec.ts +0 -475
  78. package/tests/utils/number.spec.ts +0 -184
  79. package/tests/utils/object.spec.ts +0 -827
  80. package/tests/utils/path.spec.ts +0 -78
  81. package/tests/utils/primitive.spec.ts +0 -55
  82. package/tests/utils/sd-event-emitter.spec.ts +0 -216
  83. package/tests/utils/serial-queue.spec.ts +0 -365
  84. package/tests/utils/string.spec.ts +0 -294
  85. package/tests/utils/template-strings.spec.ts +0 -96
  86. package/tests/utils/transferable.spec.ts +0 -698
  87. package/tests/utils/wait.spec.ts +0 -145
  88. package/tests/utils/xml.spec.ts +0 -146
  89. package/tests/zip/sd-zip.spec.ts +0 -234
@@ -1,5 +1,5 @@
1
- import { DateTime } from "./types/date-time";
2
- import { DateOnly } from "./types/date-only";
3
- import { Time } from "./types/time";
4
- import { Uuid } from "./types/uuid";
1
+ import { DateTime } from "./types/date-time.js";
2
+ import { DateOnly } from "./types/date-only.js";
3
+ import { Time } from "./types/time.js";
4
+ import { Uuid } from "./types/uuid.js";
5
5
  //# sourceMappingURL=common.types.js.map
@@ -1,5 +1,5 @@
1
1
  import YAML from "yaml";
2
- import { SdError } from "./sd-error";
2
+ import { SdError } from "./sd-error.js";
3
3
  class ArgumentError extends SdError {
4
4
  constructor(arg1, arg2) {
5
5
  const message = typeof arg1 === "string" ? arg1 : void 0;
@@ -1,4 +1,4 @@
1
- import { SdError } from "./sd-error";
1
+ import { SdError } from "./sd-error.js";
2
2
  class NotImplementedError extends SdError {
3
3
  /**
4
4
  * @param message 추가 설명 메시지
@@ -1,4 +1,4 @@
1
- import { SdError } from "./sd-error";
1
+ import { SdError } from "./sd-error.js";
2
2
  class TimeoutError extends SdError {
3
3
  /**
4
4
  * @param count 시도 횟수
@@ -1,7 +1,7 @@
1
- import { DateTime } from "../types/date-time";
2
- import { DateOnly } from "../types/date-only";
3
- import { Time } from "../types/time";
4
- import { ArgumentError } from "../errors/argument-error";
1
+ import { DateTime } from "../types/date-time.js";
2
+ import { DateOnly } from "../types/date-only.js";
3
+ import { Time } from "../types/time.js";
4
+ import { ArgumentError } from "../errors/argument-error.js";
5
5
  function toComparable(value) {
6
6
  if (value instanceof DateOnly || value instanceof DateTime || value instanceof Time) {
7
7
  return value.tick;
@@ -1,12 +1,12 @@
1
- import "./map-ext";
2
- import { objClone, objEqual, objMerge } from "../utils/obj";
3
- import { DateTime } from "../types/date-time";
4
- import { DateOnly } from "../types/date-only";
5
- import { Time } from "../types/time";
6
- import { Uuid } from "../types/uuid";
7
- import { ArgumentError } from "../errors/argument-error";
8
- import { SdError } from "../errors/sd-error";
9
- import { compareForOrder } from "./arr-ext.helpers";
1
+ import "./map-ext.js";
2
+ import { objClone, objEqual, objMerge } from "../utils/obj.js";
3
+ import { DateTime } from "../types/date-time.js";
4
+ import { DateOnly } from "../types/date-only.js";
5
+ import { Time } from "../types/time.js";
6
+ import { Uuid } from "../types/uuid.js";
7
+ import { ArgumentError } from "../errors/argument-error.js";
8
+ import { SdError } from "../errors/sd-error.js";
9
+ import { compareForOrder } from "./arr-ext.helpers.js";
10
10
  const arrayReadonlyExtensions = {
11
11
  single(predicate) {
12
12
  const arr = predicate !== void 0 ? this.filter(predicate) : this;
@@ -1,5 +1,5 @@
1
- import { SdError } from "../errors/sd-error";
2
- import { EventEmitter } from "./event-emitter";
1
+ import { SdError } from "../errors/sd-error.js";
2
+ import { EventEmitter } from "./event-emitter.js";
3
3
  import { createConsola } from "consola";
4
4
  class DebounceQueue extends EventEmitter {
5
5
  /**
@@ -1,7 +1,7 @@
1
- import { SdError } from "../errors/sd-error";
2
- import { EventEmitter } from "./event-emitter";
1
+ import { SdError } from "../errors/sd-error.js";
2
+ import { EventEmitter } from "./event-emitter.js";
3
3
  import { createConsola } from "consola";
4
- import { waitTime } from "../utils/wait";
4
+ import { waitTime } from "../utils/wait.js";
5
5
  class SerialQueue extends EventEmitter {
6
6
  /**
7
7
  * @param _gap 각 작업 사이의 간격 (ms)
package/dist/index.js CHANGED
@@ -1,31 +1,31 @@
1
- import "./extensions/arr-ext";
2
- import "./extensions/set-ext";
3
- import "./extensions/map-ext";
4
- export * from "./env";
5
- export * from "./errors/sd-error";
6
- export * from "./errors/argument-error";
7
- export * from "./errors/not-implemented-error";
8
- export * from "./errors/timeout-error";
9
- export * from "./types/uuid";
10
- export * from "./types/lazy-gc-map";
11
- export * from "./types/date-time";
12
- export * from "./types/date-only";
13
- export * from "./types/time";
14
- export * from "./features/debounce-queue";
15
- export * from "./features/serial-queue";
16
- export * from "./features/event-emitter";
17
- export * from "./utils/date-format";
18
- export * from "./utils/bytes";
19
- export * from "./utils/json";
20
- export * from "./utils/num";
21
- export * from "./utils/obj";
22
- export * from "./utils/primitive";
23
- export * from "./utils/str";
24
- export * from "./utils/template-strings";
25
- export * from "./utils/transferable";
26
- export * from "./utils/wait";
27
- export * from "./utils/xml";
28
- export * from "./utils/path";
29
- export * from "./zip/sd-zip";
30
- export * from "./common.types";
1
+ import "./extensions/arr-ext.js";
2
+ import "./extensions/set-ext.js";
3
+ import "./extensions/map-ext.js";
4
+ export * from "./env.js";
5
+ export * from "./errors/sd-error.js";
6
+ export * from "./errors/argument-error.js";
7
+ export * from "./errors/not-implemented-error.js";
8
+ export * from "./errors/timeout-error.js";
9
+ export * from "./types/uuid.js";
10
+ export * from "./types/lazy-gc-map.js";
11
+ export * from "./types/date-time.js";
12
+ export * from "./types/date-only.js";
13
+ export * from "./types/time.js";
14
+ export * from "./features/debounce-queue.js";
15
+ export * from "./features/serial-queue.js";
16
+ export * from "./features/event-emitter.js";
17
+ export * from "./utils/date-format.js";
18
+ export * from "./utils/bytes.js";
19
+ export * from "./utils/json.js";
20
+ export * from "./utils/num.js";
21
+ export * from "./utils/obj.js";
22
+ export * from "./utils/primitive.js";
23
+ export * from "./utils/str.js";
24
+ export * from "./utils/template-strings.js";
25
+ export * from "./utils/transferable.js";
26
+ export * from "./utils/wait.js";
27
+ export * from "./utils/xml.js";
28
+ export * from "./utils/path.js";
29
+ export * from "./zip/sd-zip.js";
30
+ export * from "./common.types.js";
31
31
  //# sourceMappingURL=index.js.map
@@ -1,5 +1,5 @@
1
- import { ArgumentError } from "../errors/argument-error";
2
- import { formatDate, normalizeMonth } from "../utils/date-format";
1
+ import { ArgumentError } from "../errors/argument-error.js";
2
+ import { formatDate, normalizeMonth } from "../utils/date-format.js";
3
3
  class DateOnly {
4
4
  static MS_PER_DAY = 24 * 60 * 60 * 1e3;
5
5
  date;
@@ -1,5 +1,5 @@
1
- import { ArgumentError } from "../errors/argument-error";
2
- import { convert12To24, formatDate, normalizeMonth } from "../utils/date-format";
1
+ import { ArgumentError } from "../errors/argument-error.js";
2
+ import { convert12To24, formatDate, normalizeMonth } from "../utils/date-format.js";
3
3
  class DateTime {
4
4
  date;
5
5
  constructor(arg1, arg2, arg3, arg4, arg5, arg6, arg7) {
@@ -1,5 +1,5 @@
1
- import { ArgumentError } from "../errors/argument-error";
2
- import { convert12To24, formatDate } from "../utils/date-format";
1
+ import { ArgumentError } from "../errors/argument-error.js";
2
+ import { convert12To24, formatDate } from "../utils/date-format.js";
3
3
  class Time {
4
4
  static MS_PER_DAY = 24 * 60 * 60 * 1e3;
5
5
  _tick;
@@ -1,4 +1,4 @@
1
- import { ArgumentError } from "../errors/argument-error";
1
+ import { ArgumentError } from "../errors/argument-error.js";
2
2
  class Uuid {
3
3
  // 0x00 ~ 0xFF에 대한 hex 문자열 미리 계산 (256개)
4
4
  static _hexTable = Array.from({ length: 256 }, (_, i) => i.toString(16).padStart(2, "0"));
@@ -1,4 +1,4 @@
1
- import { ArgumentError } from "../errors/argument-error";
1
+ import { ArgumentError } from "../errors/argument-error.js";
2
2
  const hexTable = Array.from({ length: 256 }, (_, i) => i.toString(16).padStart(2, "0"));
3
3
  const BASE64_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
4
4
  const BASE64_LOOKUP = Array.from({ length: 256 }, (_, i) => {
@@ -1,11 +1,11 @@
1
- import { DateTime } from "../types/date-time";
2
- import { DateOnly } from "../types/date-only";
3
- import { Time } from "../types/time";
4
- import { Uuid } from "../types/uuid";
5
- import { objNullToUndefined } from "./obj";
6
- import { SdError } from "../errors/sd-error";
7
- import { bytesToHex, bytesFromHex } from "./bytes";
8
- import { env } from "../env";
1
+ import { DateTime } from "../types/date-time.js";
2
+ import { DateOnly } from "../types/date-only.js";
3
+ import { Time } from "../types/time.js";
4
+ import { Uuid } from "../types/uuid.js";
5
+ import { objNullToUndefined } from "./obj.js";
6
+ import { SdError } from "../errors/sd-error.js";
7
+ import { bytesToHex, bytesFromHex } from "./bytes.js";
8
+ import { env } from "../env.js";
9
9
  function jsonStringify(obj, options) {
10
10
  const seen = /* @__PURE__ */ new WeakSet();
11
11
  const convertSpecialTypes = (key, value) => {
package/dist/utils/obj.js CHANGED
@@ -1,8 +1,8 @@
1
- import { DateTime } from "../types/date-time";
2
- import { DateOnly } from "../types/date-only";
3
- import { Time } from "../types/time";
4
- import { Uuid } from "../types/uuid";
5
- import { ArgumentError } from "../errors/argument-error";
1
+ import { DateTime } from "../types/date-time.js";
2
+ import { DateOnly } from "../types/date-only.js";
3
+ import { Time } from "../types/time.js";
4
+ import { Uuid } from "../types/uuid.js";
5
+ import { ArgumentError } from "../errors/argument-error.js";
6
6
  function objClone(source) {
7
7
  return objCloneImpl(source);
8
8
  }
@@ -1,8 +1,8 @@
1
- import { DateTime } from "../types/date-time";
2
- import { DateOnly } from "../types/date-only";
3
- import { Time } from "../types/time";
4
- import { Uuid } from "../types/uuid";
5
- import { ArgumentError } from "../errors/argument-error";
1
+ import { DateTime } from "../types/date-time.js";
2
+ import { DateOnly } from "../types/date-only.js";
3
+ import { Time } from "../types/time.js";
4
+ import { Uuid } from "../types/uuid.js";
5
+ import { ArgumentError } from "../errors/argument-error.js";
6
6
  function getPrimitiveTypeStr(value) {
7
7
  if (typeof value === "string") return "string";
8
8
  if (typeof value === "number") return "number";
@@ -1,7 +1,7 @@
1
- import { DateTime } from "../types/date-time";
2
- import { DateOnly } from "../types/date-only";
3
- import { Time } from "../types/time";
4
- import { Uuid } from "../types/uuid";
1
+ import { DateTime } from "../types/date-time.js";
2
+ import { DateOnly } from "../types/date-only.js";
3
+ import { Time } from "../types/time.js";
4
+ import { Uuid } from "../types/uuid.js";
5
5
  function transferableEncode(obj) {
6
6
  const transferList = [];
7
7
  const ancestors = /* @__PURE__ */ new Set();
@@ -1,4 +1,4 @@
1
- import { TimeoutError } from "../errors/timeout-error";
1
+ import { TimeoutError } from "../errors/timeout-error.js";
2
2
  async function waitUntil(forwarder, milliseconds, maxCount) {
3
3
  let count = 0;
4
4
  while (!await forwarder()) {
@@ -0,0 +1,381 @@
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
+ ```
19
+
20
+ #### first
21
+
22
+ Return first element.
23
+
24
+ ```typescript
25
+ users.first(); // { id: 1, name: "Alice" }
26
+ ```
27
+
28
+ #### last
29
+
30
+ Return last element.
31
+
32
+ ```typescript
33
+ users.last(); // Last user
34
+ ```
35
+
36
+ ---
37
+
38
+ ### Filtering
39
+
40
+ #### filterExists
41
+
42
+ Remove `null`/`undefined`.
43
+
44
+ ```typescript
45
+ [1, null, 2, undefined, 3].filterExists(); // [1, 2, 3]
46
+ ```
47
+
48
+ #### ofType
49
+
50
+ Filter by type (`PrimitiveTypeStr` or constructor).
51
+
52
+ ```typescript
53
+ import "@simplysm/core-common";
54
+ ```
55
+
56
+ #### filterAsync
57
+
58
+ Async filter.
59
+
60
+ ```typescript
61
+ import "@simplysm/core-common";
62
+ ```
63
+
64
+ ---
65
+
66
+ ### Mapping/Transformation
67
+
68
+ #### mapAsync
69
+
70
+ Async mapping (sequential execution).
71
+
72
+ ```typescript
73
+ await ids.mapAsync(async (id) => await fetchUser(id));
74
+ ```
75
+
76
+ #### mapMany
77
+
78
+ flat + filterExists.
79
+
80
+ ```typescript
81
+ import "@simplysm/core-common";
82
+ ```
83
+
84
+ #### mapManyAsync
85
+
86
+ Async mapMany.
87
+
88
+ ```typescript
89
+ import "@simplysm/core-common";
90
+ ```
91
+
92
+ #### parallelAsync
93
+
94
+ Parallel async mapping (`Promise.all`).
95
+
96
+ ```typescript
97
+ await ids.parallelAsync(async (id) => await fetchUser(id));
98
+ ```
99
+
100
+ ---
101
+
102
+ ### Grouping/Transformation
103
+
104
+ #### groupBy
105
+
106
+ Group by key.
107
+
108
+ ```typescript
109
+ const users = [
110
+ { id: 1, name: "Alice", dept: "dev" },
111
+ { id: 2, name: "Bob", dept: "dev" },
112
+ { id: 3, name: "Charlie", dept: "hr" },
113
+ ];
114
+
115
+ users.groupBy((u) => u.dept);
116
+ // [{ key: "dev", values: [...] }, { key: "hr", values: [...] }]
117
+ ```
118
+
119
+ #### toMap
120
+
121
+ Convert to Map (error on duplicate key).
122
+
123
+ ```typescript
124
+ users.toMap((u) => u.id); // Map<number, User>
125
+ ```
126
+
127
+ #### toMapAsync
128
+
129
+ Async Map conversion.
130
+
131
+ ```typescript
132
+ import "@simplysm/core-common";
133
+ ```
134
+
135
+ #### toArrayMap
136
+
137
+ Convert to `Map<K, V[]>`.
138
+
139
+ ```typescript
140
+ users.toArrayMap((u) => u.dept); // Map<string, User[]>
141
+ ```
142
+
143
+ #### toSetMap
144
+
145
+ Convert to `Map<K, Set<V>>`.
146
+
147
+ ```typescript
148
+ import "@simplysm/core-common";
149
+ ```
150
+
151
+ #### toMapValues
152
+
153
+ Aggregate Map by group.
154
+
155
+ ```typescript
156
+ import "@simplysm/core-common";
157
+ ```
158
+
159
+ #### toObject
160
+
161
+ Convert to `Record<string, V>`.
162
+
163
+ ```typescript
164
+ import "@simplysm/core-common";
165
+ ```
166
+
167
+ #### toTree
168
+
169
+ Convert to tree structure.
170
+
171
+ ```typescript
172
+ import "@simplysm/core-common";
173
+ ```
174
+
175
+ ---
176
+
177
+ ### Deduplication
178
+
179
+ #### distinct
180
+
181
+ Remove duplicates (return new array).
182
+
183
+ ```typescript
184
+ [1, 2, 2, 3, 3].distinct(); // [1, 2, 3]
185
+ ```
186
+
187
+ #### distinctThis
188
+
189
+ Remove duplicates (modify original).
190
+
191
+ ```typescript
192
+ import "@simplysm/core-common";
193
+ ```
194
+
195
+ ---
196
+
197
+ ### Sorting
198
+
199
+ #### orderBy
200
+
201
+ Ascending sort (return new array).
202
+
203
+ ```typescript
204
+ users.orderBy((u) => u.name);
205
+ ```
206
+
207
+ #### orderByDesc
208
+
209
+ Descending sort (return new array).
210
+
211
+ ```typescript
212
+ users.orderByDesc((u) => u.id);
213
+ ```
214
+
215
+ #### orderByThis
216
+
217
+ Ascending sort (modify original).
218
+
219
+ ```typescript
220
+ import "@simplysm/core-common";
221
+ ```
222
+
223
+ #### orderByDescThis
224
+
225
+ Descending sort (modify original).
226
+
227
+ ```typescript
228
+ import "@simplysm/core-common";
229
+ ```
230
+
231
+ ---
232
+
233
+ ### Comparison/Merging
234
+
235
+ #### diffs
236
+
237
+ Compare differences between two arrays.
238
+
239
+ ```typescript
240
+ import "@simplysm/core-common";
241
+ ```
242
+
243
+ #### oneWayDiffs
244
+
245
+ One-way diff comparison (create/update/same).
246
+
247
+ ```typescript
248
+ import "@simplysm/core-common";
249
+ ```
250
+
251
+ #### merge
252
+
253
+ Merge arrays.
254
+
255
+ ```typescript
256
+ import "@simplysm/core-common";
257
+ ```
258
+
259
+ ---
260
+
261
+ ### Aggregation
262
+
263
+ #### sum
264
+
265
+ Sum.
266
+
267
+ ```typescript
268
+ import "@simplysm/core-common";
269
+ ```
270
+
271
+ #### min
272
+
273
+ Minimum.
274
+
275
+ ```typescript
276
+ import "@simplysm/core-common";
277
+ ```
278
+
279
+ #### max
280
+
281
+ Maximum.
282
+
283
+ ```typescript
284
+ import "@simplysm/core-common";
285
+ ```
286
+
287
+ ---
288
+
289
+ ### Mutation
290
+
291
+ #### insert
292
+
293
+ Insert at specific position.
294
+
295
+ ```typescript
296
+ import "@simplysm/core-common";
297
+ ```
298
+
299
+ #### remove
300
+
301
+ Remove item.
302
+
303
+ ```typescript
304
+ import "@simplysm/core-common";
305
+ ```
306
+
307
+ #### toggle
308
+
309
+ Remove if exists, add if not.
310
+
311
+ ```typescript
312
+ import "@simplysm/core-common";
313
+ ```
314
+
315
+ #### clear
316
+
317
+ Remove all items.
318
+
319
+ ```typescript
320
+ import "@simplysm/core-common";
321
+ ```
322
+
323
+ #### shuffle
324
+
325
+ Shuffle (return new array).
326
+
327
+ ```typescript
328
+ import "@simplysm/core-common";
329
+ ```
330
+
331
+ ---
332
+
333
+ ## Map extension methods
334
+
335
+ ### getOrCreate
336
+
337
+ If key doesn't exist, set new value and return.
338
+
339
+ ```typescript
340
+ const map = new Map<string, number[]>();
341
+
342
+ // Create and return if value doesn't exist
343
+ const arr = map.getOrCreate("key", []);
344
+ arr.push(1);
345
+
346
+ // Create with factory function (when computation is expensive)
347
+ map.getOrCreate("key2", () => expensiveComputation());
348
+ ```
349
+
350
+ ### update
351
+
352
+ Update value for key using function.
353
+
354
+ ```typescript
355
+ const countMap = new Map<string, number>();
356
+ countMap.update("key", (v) => (v ?? 0) + 1); // Increment counter
357
+ ```
358
+
359
+ ---
360
+
361
+ ## Set extension methods
362
+
363
+ ### adds
364
+
365
+ Add multiple values at once.
366
+
367
+ ```typescript
368
+ const set = new Set<number>([1, 2, 3]);
369
+ set.adds(4, 5, 6); // {1, 2, 3, 4, 5, 6}
370
+ ```
371
+
372
+ ### toggle
373
+
374
+ Toggle value (remove if exists, add if not).
375
+
376
+ ```typescript
377
+ set.toggle(2); // 2 exists so remove -> {1, 3, 4, 5, 6}
378
+ set.toggle(7); // 7 doesn't exist so add -> {1, 3, 4, 5, 6, 7}
379
+ set.toggle(8, "add"); // Force add
380
+ set.toggle(1, "del"); // Force delete
381
+ ```