@the-w1zard/dx 1.0.8 → 1.0.10

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/src/map.js DELETED
@@ -1,495 +0,0 @@
1
- export const rv = (v) => typeof v === "function" ? v() : v;
2
- export const sameValue = (a, b) => Object.is(a, b) || (a instanceof Date && b instanceof Date && +a === +b);
3
- export class M2I extends Map {
4
- // public g = this.get;
5
- // public h = this.has;
6
- // public d = this.delete;
7
- // public c = this.clear
8
- f = this.forEach; // [FOR EACH]
9
- #subs;
10
- #hist;
11
- #histLimit = 0;
12
- #strict = false;
13
- #iterating = 0;
14
- #batching = 0;
15
- #pending;
16
- #derived;
17
- #dependents;
18
- #emit(e) {
19
- if (this.#batching > 0) {
20
- // coalesce: last write per key wins, keep prev from first event
21
- const pending = this.#pending.get(e.k);
22
- this.#pending.set(e.k, pending ? { ...e, prev: pending.prev, batch: true } : { ...e, batch: true });
23
- return;
24
- }
25
- this.#record(e);
26
- this.#subs?.forEach((sub) => {
27
- try {
28
- sub(e);
29
- }
30
- catch (err) {
31
- process.emitWarning(err);
32
- }
33
- });
34
- }
35
- #record(e) {
36
- if (!this.#hist)
37
- return;
38
- this.#hist.push(e);
39
- if (this.#hist.length > this.#histLimit) {
40
- this.#hist.splice(0, this.#hist.length - this.#histLimit);
41
- }
42
- }
43
- #invalidate(k) {
44
- const deps = this.#dependents?.get(k);
45
- if (!deps)
46
- return;
47
- for (const dk of deps) {
48
- const d = this.#derived?.get(dk);
49
- if (!d || d.dirty)
50
- continue;
51
- d.dirty = true;
52
- this.#emit({ op: "dirty", k: dk, has: d.has });
53
- }
54
- }
55
- #computeDerived(k, d) {
56
- const vals = d.deps.map((dep) => this.g(dep));
57
- const next = d.fn(...vals);
58
- const had = d.has;
59
- const prev = d.value;
60
- d.value = next;
61
- d.has = true;
62
- d.dirty = false;
63
- if (!had || !sameValue(prev, next)) {
64
- this.#emit({
65
- op: had ? "upd" : "set",
66
- k,
67
- v: next,
68
- prev: prev,
69
- has: true,
70
- });
71
- }
72
- return next;
73
- }
74
- #assertNotIterating(op) {
75
- if (this.#strict && this.#iterating > 0) {
76
- throw new Error(`M2.${op}() during iteration. Use filterKV(), collect keys first, or disable $strict().`);
77
- }
78
- }
79
- [Symbol.iterator]() { return this.entries(); }
80
- on(fn) {
81
- (this.#subs ??= new Set()).add(fn);
82
- return () => this.off(fn);
83
- }
84
- off(fn) {
85
- this.#subs?.delete(fn);
86
- }
87
- batch(fn) {
88
- this.#batching++;
89
- this.#pending ??= new M2I();
90
- try {
91
- fn();
92
- }
93
- finally {
94
- this.#batching--;
95
- if (this.#batching === 0) {
96
- const events = [...this.#pending.values()];
97
- this.#pending = undefined;
98
- for (const e of events) {
99
- this.#record(e);
100
- this.#subs?.forEach(sub => sub(e));
101
- }
102
- }
103
- }
104
- return this;
105
- }
106
- s(v, k) {
107
- this.#assertNotIterating("s");
108
- const next = rv(v);
109
- const has = this.h(k);
110
- const prev = has ? this.g(k) : undefined;
111
- super.set(k, next);
112
- this.#invalidate(k);
113
- this.#emit({
114
- op: "set",
115
- k,
116
- v: next,
117
- prev: prev,
118
- has,
119
- });
120
- return this;
121
- }
122
- mutate(k, fn) {
123
- this.#assertNotIterating("mutate");
124
- if (!this.h(k))
125
- return undefined;
126
- const old = this.g(k);
127
- const next = fn(old, true);
128
- this.s(next, k);
129
- return next;
130
- }
131
- d(k) {
132
- this.#assertNotIterating("delete");
133
- if (!this.h(k))
134
- return false;
135
- const prev = this.g(k);
136
- const out = super.delete(k);
137
- this.#invalidate(k);
138
- this.#emit({
139
- op: "del",
140
- k,
141
- prev,
142
- has: false,
143
- });
144
- return out;
145
- }
146
- c() {
147
- this.#assertNotIterating("clear");
148
- const entries = [...this.entries()];
149
- super.clear();
150
- for (const [k, prev] of entries) {
151
- this.#invalidate(k);
152
- this.#emit({ op: "del", k, prev, has: false });
153
- }
154
- }
155
- dv(k, deps, fn) {
156
- (this.#derived ??= new M2I())
157
- .set(k, {
158
- deps,
159
- fn,
160
- dirty: true,
161
- has: false,
162
- });
163
- for (const dep of deps) {
164
- (this.#dependents ??= new M2I())
165
- .getOrM(() => new Set(), dep)
166
- .add(k);
167
- }
168
- return this;
169
- }
170
- dirty(...keys) {
171
- for (const k of keys) {
172
- const d = this.#derived?.get(k);
173
- if (d && !d.dirty) {
174
- d.dirty = true;
175
- this.#emit({ op: "dirty", k, has: d.has });
176
- }
177
- }
178
- return this;
179
- }
180
- g(k) {
181
- const d = this.#derived?.get(k);
182
- if (d) {
183
- if (d.dirty || !d.has)
184
- return this.#computeDerived(k, d);
185
- return d.value;
186
- }
187
- return super.get(k);
188
- }
189
- h(k) {
190
- const d = this.#derived?.get(k);
191
- if (d) {
192
- if (d.dirty || !d.has)
193
- this.#computeDerived(k, d);
194
- return true;
195
- }
196
- return super.has(k);
197
- }
198
- $debug(limit = 256) {
199
- this.#hist ??= [];
200
- this.#histLimit = limit;
201
- return this;
202
- }
203
- $strict() {
204
- this.#strict = true;
205
- return this;
206
- }
207
- $history() {
208
- return this.#hist ? [...this.#hist] : [];
209
- }
210
- $why(k) {
211
- if (!this.#hist)
212
- return undefined;
213
- for (let i = this.#hist.length - 1; i >= 0; i--) {
214
- if (Object.is(this.#hist[i].k, k))
215
- return this.#hist[i];
216
- }
217
- return undefined;
218
- }
219
- $diff(other) {
220
- const add = [];
221
- const del = [];
222
- const chg = [];
223
- for (const [k, v] of this) {
224
- if (!other.has(k)) {
225
- add.push([k, v]);
226
- }
227
- else if (!Object.is(other.get(k), v)) {
228
- chg.push([k, v, other.get(k)]);
229
- }
230
- }
231
- for (const k of other.keys()) {
232
- if (!this.has(k))
233
- del.push(k);
234
- }
235
- return { add, del, chg };
236
- }
237
- *entries() {
238
- this.#iterating++;
239
- try {
240
- for (const entry of super.entries())
241
- yield entry;
242
- }
243
- finally {
244
- this.#iterating--;
245
- }
246
- }
247
- *keys() {
248
- this.#iterating++;
249
- try {
250
- for (const k of super.keys())
251
- yield k;
252
- }
253
- finally {
254
- this.#iterating--;
255
- }
256
- }
257
- *values() {
258
- this.#iterating++;
259
- try {
260
- for (const v of super.values())
261
- yield v;
262
- }
263
- finally {
264
- this.#iterating--;
265
- }
266
- }
267
- swap(value, key) {
268
- const next = rv(value);
269
- const previous = this.has(key) ? this.get(key) : next;
270
- this.s(next, key);
271
- return previous;
272
- }
273
- take(k) {
274
- const value = this.g(k);
275
- this.d(k);
276
- return value;
277
- }
278
- peek(k) {
279
- return this.h(k) ? this.g(k) : false;
280
- }
281
- getOrI(value, k) {
282
- if (this.h(k))
283
- return this.g(k);
284
- const next = rv(value);
285
- this.s(next, k);
286
- return next;
287
- }
288
- getOrM(make, k) {
289
- if (this.h(k))
290
- return this.g(k);
291
- const value = make();
292
- this.s(value, k);
293
- return value;
294
- }
295
- update(k, fn, initial) {
296
- const has = this.h(k);
297
- const old = has
298
- ? this.g(k)
299
- : initial === undefined
300
- ? undefined
301
- : rv(initial);
302
- const next = rv(fn(old, has));
303
- this.s(next, k);
304
- return next;
305
- }
306
- setIfAbsent(value, k) {
307
- if (this.h(k))
308
- return false;
309
- const next = rv(value);
310
- this.s(next, k);
311
- return true;
312
- }
313
- setIfPresent(value, k) {
314
- if (!this.h(k))
315
- return false;
316
- const next = rv(value);
317
- this.s(next, k);
318
- return true;
319
- }
320
- replace(value, k) {
321
- const next = rv(value);
322
- return this.setIfPresent(next, k);
323
- }
324
- inc(key, by = 1) {
325
- return this.update(key, (old) => ((old ?? 0) + by), 0);
326
- }
327
- touch(k) {
328
- return this.setIfAbsent(undefined, k);
329
- }
330
- mapValues(fn) {
331
- const out = new M2I();
332
- for (const [k, v] of this)
333
- out.s(fn(v, k), k);
334
- return out;
335
- }
336
- mapKeys(fn) {
337
- const out = new M2I();
338
- for (const [k, v] of this)
339
- out.s(v, fn(v, k));
340
- return out;
341
- }
342
- filterKV(pred) {
343
- for (const [k, v] of this) {
344
- if (!pred(v, k))
345
- this.d(k);
346
- }
347
- return this;
348
- }
349
- filterKeys(pred) {
350
- return this.filterKV(pred);
351
- }
352
- partition(pred) {
353
- const yes = new M2I();
354
- const no = new M2I();
355
- for (const [k, v] of this) {
356
- (pred(v, k) ? yes : no).s(v, k);
357
- }
358
- return [yes, no];
359
- }
360
- find(pred) {
361
- for (const [k, v] of this) {
362
- if (pred(v, k))
363
- return [k, v];
364
- }
365
- return undefined;
366
- }
367
- findKey(pred) {
368
- for (const [k, v] of this) {
369
- if (pred(v, k))
370
- return k;
371
- }
372
- return undefined;
373
- }
374
- findValue(pred) {
375
- for (const [k, v] of this) {
376
- if (pred(v, k))
377
- return v;
378
- }
379
- return undefined;
380
- }
381
- some(pred) {
382
- for (const [k, v] of this) {
383
- if (pred(v, k))
384
- return true;
385
- }
386
- return false;
387
- }
388
- every(pred) {
389
- for (const [k, v] of this) {
390
- if (!pred(v, k))
391
- return false;
392
- }
393
- return true;
394
- }
395
- reduce(fn, initial) {
396
- let acc = initial;
397
- for (const [k, v] of this)
398
- acc = fn(acc, v, k);
399
- return acc;
400
- }
401
- forEachKV(fn) {
402
- for (const [k, v] of this)
403
- fn(v, k, this);
404
- }
405
- invert() {
406
- const out = new M2I();
407
- for (const [k, v] of this)
408
- out.s(k, v);
409
- return out;
410
- }
411
- unique(fn) {
412
- const out = new M2I();
413
- for (const [k, v] of this) {
414
- const key = (fn ? fn(v, k) : v);
415
- if (!out.h(key))
416
- out.s(v, key);
417
- }
418
- return out;
419
- }
420
- pick(keys) {
421
- const out = new M2I();
422
- for (const k of keys) {
423
- if (this.h(k))
424
- out.s(this.g(k), k);
425
- }
426
- return out;
427
- }
428
- omit(keys) {
429
- const omitted = new Set(keys);
430
- const out = new M2I();
431
- for (const [k, v] of this) {
432
- if (!omitted.has(k))
433
- out.s(v, k);
434
- }
435
- return out;
436
- }
437
- merge(other) {
438
- for (const [k, v] of other) {
439
- const n = rv(v);
440
- this.s(n, k);
441
- }
442
- return this;
443
- }
444
- clearAndSet(entries) {
445
- return this.batch(() => {
446
- this.clear();
447
- for (const [k, v] of entries) {
448
- const n = rv(v);
449
- this.s(n, k);
450
- }
451
- });
452
- }
453
- toObject() {
454
- const out = {};
455
- for (const [k, v] of this)
456
- out[k] = v;
457
- return out;
458
- }
459
- toValues() { return A2.from(this.values()); } // [TOVALUES]
460
- toKeys() { return A2.from(this.keys()); } // [TOKEYS]
461
- toArray() { return A2.from(this.entries()); } // [TOARRAY]
462
- group(fn) {
463
- const out = new M2I();
464
- for (const [k, v] of this)
465
- out.getOrM(() => new A2(), fn(v, k)).push(v);
466
- return out;
467
- }
468
- clone() {
469
- return new M2I(this);
470
- }
471
- equals(other) {
472
- if (other === this)
473
- return true;
474
- if (this.size !== other.size)
475
- return false;
476
- for (const [k, v] of this) {
477
- if (!other.has(k) || !sameValue(other.get(k), v))
478
- return false;
479
- }
480
- return true;
481
- }
482
- static fromObject(obj) {
483
- return new M2I(Object.entries(obj));
484
- }
485
- static fromEntries(entries) {
486
- return new M2I(entries);
487
- }
488
- static from(map) {
489
- return new M2I(map);
490
- }
491
- }
492
- globalThis.M2 = M2I;
493
- /* ====================================================================================================
494
-
495
- ============================================================= ⇦✦──⇦✦──✦──✦──← 'pew pew' 🧙 [STORE] */