atom.io 0.33.21 → 0.34.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/dist/eslint-plugin/index.js +1 -2
- package/dist/eslint-plugin/index.js.map +1 -1
- package/dist/internal/index.d.ts +10 -6
- package/dist/internal/index.d.ts.map +1 -1
- package/dist/internal/index.js +1262 -1253
- package/dist/internal/index.js.map +1 -1
- package/dist/json/index.d.ts +3 -0
- package/dist/json/index.d.ts.map +1 -1
- package/dist/json/index.js.map +1 -1
- package/dist/main/index.d.ts +405 -23
- package/dist/main/index.d.ts.map +1 -1
- package/dist/main/index.js +107 -11
- package/dist/main/index.js.map +1 -1
- package/dist/realtime-client/index.js +6 -10
- package/dist/realtime-client/index.js.map +1 -1
- package/dist/realtime-server/index.js +1 -1
- package/dist/realtime-server/index.js.map +1 -1
- package/dist/realtime-testing/index.d.ts.map +1 -1
- package/dist/realtime-testing/index.js +0 -1
- package/dist/realtime-testing/index.js.map +1 -1
- package/package.json +6 -6
- package/src/internal/atom/create-regular-atom.ts +6 -7
- package/src/internal/caching.ts +9 -9
- package/src/internal/future.ts +3 -0
- package/src/internal/get-state/read-or-compute-value.ts +12 -7
- package/src/internal/join/create-join.ts +27 -0
- package/src/internal/join/index.ts +1 -0
- package/src/internal/junction.ts +2 -0
- package/src/internal/mutable/create-mutable-atom.ts +2 -4
- package/src/internal/selector/create-readonly-held-selector.ts +10 -0
- package/src/internal/selector/create-readonly-pure-selector.ts +13 -4
- package/src/internal/selector/create-writable-held-selector.ts +11 -2
- package/src/internal/selector/create-writable-pure-selector.ts +11 -1
- package/src/internal/selector/trace-selector-atoms.ts +18 -40
- package/src/internal/selector/update-selector-atoms.ts +5 -5
- package/src/internal/set-state/evict-downstream.ts +2 -2
- package/src/internal/set-state/reset-atom-or-selector.ts +3 -3
- package/src/internal/store/store.ts +0 -1
- package/src/internal/subscribe/subscribe-to-root-atoms.ts +42 -38
- package/src/internal/subscribe/subscribe-to-state.ts +23 -11
- package/src/json/index.ts +3 -0
- package/src/main/atom.ts +54 -13
- package/src/main/dispose-state.ts +8 -2
- package/src/main/find-state.ts +44 -14
- package/src/main/get-state.ts +2 -2
- package/src/main/index.ts +8 -0
- package/src/main/join.ts +79 -22
- package/src/main/realm.ts +50 -4
- package/src/main/selector.ts +116 -6
- package/src/main/subscribe.ts +31 -1
- package/src/main/timeline.ts +17 -0
- package/src/main/transaction.ts +39 -3
- package/src/realtime-client/realtime-client-stores/client-sync-store.ts +2 -2
- package/src/realtime-testing/setup-realtime-test.tsx +0 -5
package/dist/internal/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { arbitrary as arbitrary$1, subscribeToState as subscribeToState$1, subscribeToTimeline as subscribeToTimeline$1, subscribeToTransaction as subscribeToTransaction$1 } from "atom.io/internal";
|
|
1
|
+
import { Join as Join$1, arbitrary as arbitrary$1, subscribeToState as subscribeToState$1, subscribeToTimeline as subscribeToTimeline$1, subscribeToTransaction as subscribeToTransaction$1 } from "atom.io/internal";
|
|
2
2
|
import { parseJson, selectJson, selectJsonFamily, stringifyJson } from "atom.io/json";
|
|
3
3
|
import { Anarchy, AtomIOLogger } from "atom.io";
|
|
4
4
|
import { SetRTX } from "atom.io/transceivers/set-rtx";
|
|
@@ -8,61 +8,6 @@ function arbitrary(random = Math.random) {
|
|
|
8
8
|
return random().toString(36).slice(2);
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
//#endregion
|
|
12
|
-
//#region src/internal/future.ts
|
|
13
|
-
/**
|
|
14
|
-
* A Promise whose incoming value can be hot swapped.
|
|
15
|
-
* @internal
|
|
16
|
-
* @private
|
|
17
|
-
* @typeParam T The type of the value that the promise will resolve to.
|
|
18
|
-
*
|
|
19
|
-
* @remarks
|
|
20
|
-
* Can be constructed like a Promise, or from an existing Promise.
|
|
21
|
-
*/
|
|
22
|
-
var Future = class extends Promise {
|
|
23
|
-
fate;
|
|
24
|
-
resolve;
|
|
25
|
-
reject;
|
|
26
|
-
done = false;
|
|
27
|
-
constructor(executor) {
|
|
28
|
-
let superResolve;
|
|
29
|
-
let superReject;
|
|
30
|
-
super((resolve, reject) => {
|
|
31
|
-
superResolve = resolve;
|
|
32
|
-
superReject = reject;
|
|
33
|
-
});
|
|
34
|
-
this.resolve = superResolve;
|
|
35
|
-
this.reject = superReject;
|
|
36
|
-
this.use(executor instanceof Promise ? executor : new Promise(executor));
|
|
37
|
-
}
|
|
38
|
-
pass(promise, value) {
|
|
39
|
-
if (promise === this.fate) {
|
|
40
|
-
this.resolve(value);
|
|
41
|
-
this.done = true;
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
fail(promise, reason) {
|
|
45
|
-
if (promise === this.fate) {
|
|
46
|
-
this.reject(reason);
|
|
47
|
-
this.done = true;
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
use(value) {
|
|
51
|
-
if (value instanceof Promise) {
|
|
52
|
-
const promise = value;
|
|
53
|
-
this.fate = promise;
|
|
54
|
-
promise.then((resolved) => {
|
|
55
|
-
this.pass(promise, resolved);
|
|
56
|
-
}, (reason) => {
|
|
57
|
-
this.fail(promise, reason);
|
|
58
|
-
});
|
|
59
|
-
} else {
|
|
60
|
-
this.resolve(value);
|
|
61
|
-
this.fate = void 0;
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
};
|
|
65
|
-
|
|
66
11
|
//#endregion
|
|
67
12
|
//#region src/internal/lineage.ts
|
|
68
13
|
function newest(scion) {
|
|
@@ -300,12 +245,11 @@ var Junction = class {
|
|
|
300
245
|
}
|
|
301
246
|
break;
|
|
302
247
|
}
|
|
303
|
-
default:
|
|
248
|
+
default:
|
|
304
249
|
a = params[0];
|
|
305
250
|
b = params[1];
|
|
306
251
|
content = params[2];
|
|
307
252
|
break;
|
|
308
|
-
}
|
|
309
253
|
}
|
|
310
254
|
switch (this.cardinality) {
|
|
311
255
|
case `1:1`: {
|
|
@@ -432,85 +376,107 @@ var StatefulSubject = class extends Subject {
|
|
|
432
376
|
};
|
|
433
377
|
|
|
434
378
|
//#endregion
|
|
435
|
-
//#region src/internal/
|
|
436
|
-
|
|
437
|
-
return `epoch` in store.transactionMeta;
|
|
438
|
-
}
|
|
439
|
-
function isChildStore(store) {
|
|
440
|
-
return `phase` in store.transactionMeta;
|
|
441
|
-
}
|
|
442
|
-
|
|
443
|
-
//#endregion
|
|
444
|
-
//#region src/internal/transaction/abort-transaction.ts
|
|
445
|
-
const abortTransaction = (store) => {
|
|
379
|
+
//#region src/internal/subscribe/recall-state.ts
|
|
380
|
+
const recallState = (store, state) => {
|
|
446
381
|
const target = newest(store);
|
|
447
|
-
if (
|
|
448
|
-
|
|
449
|
-
return;
|
|
450
|
-
}
|
|
451
|
-
store.logger.info(`🪂`, `transaction`, target.transactionMeta.update.key, `Aborting transaction`);
|
|
452
|
-
target.parent.child = null;
|
|
382
|
+
if (target.operation.open) return target.operation.prev.get(state.key);
|
|
383
|
+
return target.valueMap.get(state.key);
|
|
453
384
|
};
|
|
454
385
|
|
|
455
386
|
//#endregion
|
|
456
|
-
//#region src/internal/
|
|
457
|
-
function
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
387
|
+
//#region src/internal/subscribe/subscribe-in-store.ts
|
|
388
|
+
function subscribeInStore(store, token, handleUpdate, key = arbitrary$1()) {
|
|
389
|
+
switch (token.type) {
|
|
390
|
+
case `atom`:
|
|
391
|
+
case `mutable_atom`:
|
|
392
|
+
case `readonly_pure_selector`:
|
|
393
|
+
case `readonly_held_selector`:
|
|
394
|
+
case `writable_pure_selector`:
|
|
395
|
+
case `writable_held_selector`: return subscribeToState$1(store, token, key, handleUpdate);
|
|
396
|
+
case `transaction`: return subscribeToTransaction$1(store, token, key, handleUpdate);
|
|
397
|
+
case `timeline`: return subscribeToTimeline$1(store, token, key, handleUpdate);
|
|
398
|
+
}
|
|
465
399
|
}
|
|
466
400
|
|
|
467
401
|
//#endregion
|
|
468
|
-
//#region src/internal/
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
402
|
+
//#region src/internal/future.ts
|
|
403
|
+
/**
|
|
404
|
+
* A Promise whose incoming value can be hot swapped.
|
|
405
|
+
* @internal
|
|
406
|
+
* @private
|
|
407
|
+
* @typeParam T The type of the value that the promise will resolve to.
|
|
408
|
+
*
|
|
409
|
+
* @remarks
|
|
410
|
+
* Can be constructed like a Promise, or from an existing Promise.
|
|
411
|
+
*/
|
|
412
|
+
var Future = class extends Promise {
|
|
413
|
+
fate;
|
|
414
|
+
resolve;
|
|
415
|
+
reject;
|
|
416
|
+
done = false;
|
|
417
|
+
constructor(executor) {
|
|
418
|
+
let superResolve;
|
|
419
|
+
let superReject;
|
|
420
|
+
super((resolve, reject) => {
|
|
421
|
+
superResolve = resolve;
|
|
422
|
+
superReject = reject;
|
|
423
|
+
});
|
|
424
|
+
this.resolve = superResolve;
|
|
425
|
+
this.reject = superReject;
|
|
426
|
+
this.use(executor instanceof Promise ? executor : new Promise(executor));
|
|
427
|
+
}
|
|
428
|
+
pass(promise, value) {
|
|
429
|
+
if (promise === this.fate) {
|
|
430
|
+
this.resolve(value);
|
|
431
|
+
this.done = true;
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
fail(promise, reason) {
|
|
435
|
+
if (promise === this.fate) {
|
|
436
|
+
this.reject(reason);
|
|
437
|
+
this.done = true;
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
use(value) {
|
|
441
|
+
if (this === value) return;
|
|
442
|
+
if (value instanceof Promise) {
|
|
443
|
+
const promise = value;
|
|
444
|
+
this.fate = promise;
|
|
445
|
+
promise.then((resolved) => {
|
|
446
|
+
this.pass(promise, resolved);
|
|
447
|
+
}, (reason) => {
|
|
448
|
+
this.fail(promise, reason);
|
|
449
|
+
});
|
|
450
|
+
} else {
|
|
451
|
+
this.resolve(value);
|
|
452
|
+
this.fate = void 0;
|
|
453
|
+
}
|
|
472
454
|
}
|
|
473
455
|
};
|
|
474
456
|
|
|
475
457
|
//#endregion
|
|
476
|
-
//#region src/internal/
|
|
477
|
-
function
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
458
|
+
//#region src/internal/set-state/copy-mutable-if-needed.ts
|
|
459
|
+
function copyMutableIfNeeded(target, atom$1, origin) {
|
|
460
|
+
const originValue = origin.valueMap.get(atom$1.key);
|
|
461
|
+
const targetValue = target.valueMap.get(atom$1.key);
|
|
462
|
+
if (originValue !== targetValue) return targetValue;
|
|
463
|
+
if (originValue === void 0) return atom$1.default();
|
|
464
|
+
origin.logger.info(`📃`, `atom`, atom$1.key, `copying`);
|
|
465
|
+
const jsonValue = atom$1.toJson(originValue);
|
|
466
|
+
const copiedValue = atom$1.fromJson(jsonValue);
|
|
467
|
+
target.valueMap.set(atom$1.key, copiedValue);
|
|
468
|
+
new Tracker(atom$1, origin);
|
|
469
|
+
return copiedValue;
|
|
483
470
|
}
|
|
484
471
|
|
|
485
472
|
//#endregion
|
|
486
|
-
//#region src/internal/
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
target.logger.info(`📖`, state.type, state.key, `reading cached value`);
|
|
494
|
-
return readCachedValue(state, target);
|
|
495
|
-
}
|
|
496
|
-
switch (state.type) {
|
|
497
|
-
case `readonly_held_selector`:
|
|
498
|
-
case `readonly_pure_selector`:
|
|
499
|
-
case `writable_held_selector`:
|
|
500
|
-
case `writable_pure_selector`:
|
|
501
|
-
target.logger.info(`🧮`, state.type, state.key, `computing value`);
|
|
502
|
-
return state.get();
|
|
503
|
-
case `atom`:
|
|
504
|
-
case `mutable_atom`: {
|
|
505
|
-
const def = state.default;
|
|
506
|
-
let fallback;
|
|
507
|
-
if (def instanceof Function) fallback = def();
|
|
508
|
-
else fallback = def;
|
|
509
|
-
target.logger.info(`💁`, `atom`, state.key, `could not find cached value; using default`, fallback);
|
|
510
|
-
return fallback;
|
|
511
|
-
}
|
|
512
|
-
}
|
|
513
|
-
};
|
|
473
|
+
//#region src/internal/transaction/is-root-store.ts
|
|
474
|
+
function isRootStore(store) {
|
|
475
|
+
return `epoch` in store.transactionMeta;
|
|
476
|
+
}
|
|
477
|
+
function isChildStore(store) {
|
|
478
|
+
return `phase` in store.transactionMeta;
|
|
479
|
+
}
|
|
514
480
|
|
|
515
481
|
//#endregion
|
|
516
482
|
//#region src/internal/operation.ts
|
|
@@ -549,22 +515,6 @@ const markDone = (store, key) => {
|
|
|
549
515
|
store.operation.done.add(key);
|
|
550
516
|
};
|
|
551
517
|
|
|
552
|
-
//#endregion
|
|
553
|
-
//#region src/internal/set-state/emit-update.ts
|
|
554
|
-
const emitUpdate = (store, state, update) => {
|
|
555
|
-
switch (state.type) {
|
|
556
|
-
case `mutable_atom`:
|
|
557
|
-
store.logger.info(`📢`, state.type, state.key, `is now (`, update.newValue, `) subscribers:`, state.subject.subscribers);
|
|
558
|
-
break;
|
|
559
|
-
case `atom`:
|
|
560
|
-
case `writable_pure_selector`:
|
|
561
|
-
case `readonly_pure_selector`:
|
|
562
|
-
case `writable_held_selector`:
|
|
563
|
-
case `readonly_held_selector`: store.logger.info(`📢`, state.type, state.key, `went (`, update.oldValue, `->`, update.newValue, `) subscribers:`, state.subject.subscribers);
|
|
564
|
-
}
|
|
565
|
-
state.subject.next(update);
|
|
566
|
-
};
|
|
567
|
-
|
|
568
518
|
//#endregion
|
|
569
519
|
//#region src/internal/set-state/evict-downstream.ts
|
|
570
520
|
function evictDownStream(store, atom$1) {
|
|
@@ -575,7 +525,7 @@ function evictDownStream(store, atom$1) {
|
|
|
575
525
|
if (target.operation.open) target.logger.info(`🧹`, atom$1.type, atom$1.key, `[ ${[...target.operation.done].join(`, `)} ] already done`);
|
|
576
526
|
for (const key of downstreamKeys) {
|
|
577
527
|
if (isDone(target, key)) continue;
|
|
578
|
-
evictCachedValue(
|
|
528
|
+
evictCachedValue(target, key);
|
|
579
529
|
markDone(target, key);
|
|
580
530
|
}
|
|
581
531
|
}
|
|
@@ -585,81 +535,117 @@ function evictDownStreamFromSelector(store, selector) {
|
|
|
585
535
|
const relationEntries = target.selectorGraph.getRelationEntries({ upstreamSelectorKey: selector.key }).filter(([_, { source }]) => source === selector.key);
|
|
586
536
|
for (const [downstreamSelectorKey] of relationEntries) {
|
|
587
537
|
if (isDone(target, downstreamSelectorKey)) continue;
|
|
588
|
-
evictCachedValue(
|
|
538
|
+
evictCachedValue(target, downstreamSelectorKey);
|
|
589
539
|
markDone(target, downstreamSelectorKey);
|
|
590
540
|
}
|
|
591
541
|
}
|
|
592
542
|
|
|
593
543
|
//#endregion
|
|
594
|
-
//#region src/internal/
|
|
595
|
-
|
|
596
|
-
const
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
newValue = cacheValue(target, atom$1.key, newValue, atom$1.subject);
|
|
606
|
-
markDone(target, atom$1.key);
|
|
607
|
-
evictDownStream(target, atom$1);
|
|
608
|
-
const update = {
|
|
609
|
-
oldValue,
|
|
610
|
-
newValue
|
|
611
|
-
};
|
|
612
|
-
if (!isChildStore(target)) {
|
|
613
|
-
emitUpdate(target, atom$1, update);
|
|
614
|
-
return;
|
|
544
|
+
//#region src/internal/caching.ts
|
|
545
|
+
function cacheValue(target, key, value, subject) {
|
|
546
|
+
const currentValue = target.valueMap.get(key);
|
|
547
|
+
if (currentValue instanceof Future && !currentValue.done) {
|
|
548
|
+
const future = currentValue;
|
|
549
|
+
if (value instanceof Promise) {
|
|
550
|
+
future.use(value);
|
|
551
|
+
return future;
|
|
552
|
+
}
|
|
553
|
+
target.valueMap.set(key, value);
|
|
554
|
+
return value;
|
|
615
555
|
}
|
|
616
|
-
if (
|
|
617
|
-
const
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
556
|
+
if (value instanceof Promise) {
|
|
557
|
+
const future = new Future(value);
|
|
558
|
+
target.valueMap.set(key, future);
|
|
559
|
+
future.then(function handleResolvedFuture(resolved) {
|
|
560
|
+
const current = target.valueMap.get(key);
|
|
561
|
+
if (current === future) {
|
|
562
|
+
cacheValue(target, key, resolved, subject);
|
|
563
|
+
const atom$1 = target.atoms.get(key);
|
|
564
|
+
if (atom$1) {
|
|
565
|
+
openOperation(target, atom$1);
|
|
566
|
+
evictDownStream(target, atom$1);
|
|
567
|
+
closeOperation(target);
|
|
568
|
+
} else {
|
|
569
|
+
const selector = target.writableSelectors.get(key) ?? target.readonlySelectors.get(key);
|
|
570
|
+
if (selector) {
|
|
571
|
+
openOperation(target, selector);
|
|
572
|
+
evictDownStreamFromSelector(target, selector);
|
|
573
|
+
closeOperation(target);
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
subject.next({
|
|
577
|
+
newValue: resolved,
|
|
578
|
+
oldValue: future
|
|
579
|
+
});
|
|
580
|
+
}
|
|
581
|
+
}).catch((thrown) => {
|
|
582
|
+
target.logger.error(`💥`, `state`, key, `rejected:`, thrown);
|
|
583
|
+
});
|
|
584
|
+
return future;
|
|
585
|
+
}
|
|
586
|
+
target.valueMap.set(key, value);
|
|
587
|
+
return value;
|
|
588
|
+
}
|
|
589
|
+
const readCachedValue = (state, target) => {
|
|
590
|
+
target.logger.info(`📖`, state.type, state.key, `reading cached value`);
|
|
591
|
+
let value = target.valueMap.get(state.key);
|
|
592
|
+
if (state.type === `mutable_atom` && isChildStore(target)) {
|
|
593
|
+
const { parent } = target;
|
|
594
|
+
const copiedValue = copyMutableIfNeeded(target, state, parent);
|
|
595
|
+
value = copiedValue;
|
|
596
|
+
}
|
|
597
|
+
return value;
|
|
598
|
+
};
|
|
599
|
+
const evictCachedValue = (target, key) => {
|
|
600
|
+
const currentValue = target.valueMap.get(key);
|
|
601
|
+
if (currentValue instanceof Future) {
|
|
602
|
+
const selector = target.writableSelectors.get(key) ?? target.readonlySelectors.get(key);
|
|
603
|
+
if (selector) selector.get();
|
|
604
|
+
return;
|
|
638
605
|
}
|
|
606
|
+
if (target.operation.open) target.operation.prev.set(key, currentValue);
|
|
607
|
+
target.valueMap.delete(key);
|
|
608
|
+
target.logger.info(`🗑`, `state`, key, `evicted`);
|
|
639
609
|
};
|
|
640
610
|
|
|
641
611
|
//#endregion
|
|
642
|
-
//#region src/internal/
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
if (def instanceof Function) def = def();
|
|
646
|
-
setAtom(store, state, def);
|
|
647
|
-
}
|
|
648
|
-
function resetAtomOrSelector(store, state) {
|
|
612
|
+
//#region src/internal/get-state/read-or-compute-value.ts
|
|
613
|
+
const readOrComputeValue = (target, state) => {
|
|
614
|
+
if (target.valueMap.has(state.key)) return readCachedValue(state, target);
|
|
649
615
|
switch (state.type) {
|
|
650
|
-
case `
|
|
651
|
-
case `
|
|
652
|
-
resetAtom(store, state);
|
|
653
|
-
break;
|
|
654
|
-
case `writable_pure_selector`:
|
|
616
|
+
case `readonly_held_selector`:
|
|
617
|
+
case `readonly_pure_selector`:
|
|
655
618
|
case `writable_held_selector`:
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
619
|
+
case `writable_pure_selector`:
|
|
620
|
+
target.logger.info(`🧮`, state.type, state.key, `computing value`);
|
|
621
|
+
return state.get();
|
|
622
|
+
case `atom`:
|
|
623
|
+
case `mutable_atom`: {
|
|
624
|
+
const def = state.default;
|
|
625
|
+
let defaultValue;
|
|
626
|
+
if (def instanceof Function) defaultValue = def();
|
|
627
|
+
else defaultValue = def;
|
|
628
|
+
const cachedValue = cacheValue(target, state.key, defaultValue, state.subject);
|
|
629
|
+
target.logger.info(`💁`, `atom`, state.key, `could not find cached value; using default`, defaultValue);
|
|
630
|
+
return cachedValue;
|
|
631
|
+
}
|
|
661
632
|
}
|
|
662
|
-
}
|
|
633
|
+
};
|
|
634
|
+
|
|
635
|
+
//#endregion
|
|
636
|
+
//#region src/internal/subscribe/subscribe-to-root-atoms.ts
|
|
637
|
+
const subscribeToRootDependency = (target, selector, atom$1) => {
|
|
638
|
+
return atom$1.subject.subscribe(`${selector.type}:${selector.key}`, (atomChange) => {
|
|
639
|
+
target.logger.info(`📢`, selector.type, selector.key, `root`, atom$1.key, `went`, atomChange.oldValue, `->`, atomChange.newValue);
|
|
640
|
+
const oldValue = recallState(target, selector);
|
|
641
|
+
const newValue = readOrComputeValue(target, selector);
|
|
642
|
+
target.logger.info(`✨`, selector.type, selector.key, `went`, oldValue, `->`, newValue);
|
|
643
|
+
selector.subject.next({
|
|
644
|
+
newValue,
|
|
645
|
+
oldValue
|
|
646
|
+
});
|
|
647
|
+
});
|
|
648
|
+
};
|
|
663
649
|
|
|
664
650
|
//#endregion
|
|
665
651
|
//#region src/internal/families/create-regular-atom-family.ts
|
|
@@ -711,65 +697,255 @@ function createAtomFamily(store, options) {
|
|
|
711
697
|
}
|
|
712
698
|
|
|
713
699
|
//#endregion
|
|
714
|
-
//#region src/internal/
|
|
715
|
-
const
|
|
716
|
-
const isSelectorKey = (store, key) => newest(store).writableSelectors.has(key);
|
|
717
|
-
const isReadonlySelectorKey = (store, key) => newest(store).readonlySelectors.has(key);
|
|
718
|
-
const isStateKey = (store, key) => isAtomKey(store, key) || isSelectorKey(store, key) || isReadonlySelectorKey(store, key);
|
|
700
|
+
//#region src/internal/set-state/become.ts
|
|
701
|
+
const become = (nextVersionOfThing) => (originalThing) => nextVersionOfThing instanceof Function ? nextVersionOfThing(originalThing) : nextVersionOfThing;
|
|
719
702
|
|
|
720
703
|
//#endregion
|
|
721
|
-
//#region src/internal/
|
|
722
|
-
const
|
|
723
|
-
|
|
724
|
-
|
|
704
|
+
//#region src/internal/set-state/emit-update.ts
|
|
705
|
+
const emitUpdate = (store, state, update) => {
|
|
706
|
+
switch (state.type) {
|
|
707
|
+
case `mutable_atom`:
|
|
708
|
+
store.logger.info(`📢`, state.type, state.key, `is now (`, update.newValue, `) subscribers:`, state.subject.subscribers);
|
|
709
|
+
break;
|
|
710
|
+
case `atom`:
|
|
711
|
+
case `writable_pure_selector`:
|
|
712
|
+
case `readonly_pure_selector`:
|
|
713
|
+
case `writable_held_selector`:
|
|
714
|
+
case `readonly_held_selector`: store.logger.info(`📢`, state.type, state.key, `went (`, update.oldValue, `->`, update.newValue, `) subscribers:`, state.subject.subscribers);
|
|
715
|
+
}
|
|
716
|
+
state.subject.next(update);
|
|
725
717
|
};
|
|
726
718
|
|
|
727
719
|
//#endregion
|
|
728
|
-
//#region src/internal/
|
|
729
|
-
const
|
|
730
|
-
const
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
const
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
const
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
720
|
+
//#region src/internal/set-state/set-atom.ts
|
|
721
|
+
const setAtom = (target, atom$1, next) => {
|
|
722
|
+
const oldValue = readOrComputeValue(target, atom$1);
|
|
723
|
+
let newValue = oldValue;
|
|
724
|
+
if (atom$1.type === `mutable_atom` && isChildStore(target)) {
|
|
725
|
+
const { parent } = target;
|
|
726
|
+
const copiedValue = copyMutableIfNeeded(target, atom$1, parent);
|
|
727
|
+
newValue = copiedValue;
|
|
728
|
+
}
|
|
729
|
+
newValue = become(next)(newValue);
|
|
730
|
+
target.logger.info(`📝`, `atom`, atom$1.key, `set to`, newValue);
|
|
731
|
+
newValue = cacheValue(target, atom$1.key, newValue, atom$1.subject);
|
|
732
|
+
markDone(target, atom$1.key);
|
|
733
|
+
evictDownStream(target, atom$1);
|
|
734
|
+
const update = {
|
|
735
|
+
oldValue,
|
|
736
|
+
newValue
|
|
737
|
+
};
|
|
738
|
+
if (!isChildStore(target)) {
|
|
739
|
+
emitUpdate(target, atom$1, update);
|
|
740
|
+
return;
|
|
741
|
+
}
|
|
742
|
+
if (target.on.transactionApplying.state === null) {
|
|
743
|
+
const { key } = atom$1;
|
|
744
|
+
if (isTransceiver(update.newValue)) return;
|
|
745
|
+
const atomUpdate = {
|
|
746
|
+
type: `atom_update`,
|
|
747
|
+
key,
|
|
748
|
+
...update
|
|
749
|
+
};
|
|
750
|
+
if (atom$1.family) atomUpdate.family = atom$1.family;
|
|
751
|
+
target.transactionMeta.update.updates.push(atomUpdate);
|
|
752
|
+
target.logger.info(`📁`, `atom`, key, `stowed (`, update.oldValue, `->`, update.newValue, `)`);
|
|
753
|
+
} else if (atom$1.key.startsWith(`*`)) {
|
|
754
|
+
const mutableKey = atom$1.key.slice(1);
|
|
755
|
+
const mutableAtom = target.atoms.get(mutableKey);
|
|
756
|
+
let transceiver = target.valueMap.get(mutableKey);
|
|
757
|
+
if (mutableAtom.type === `mutable_atom` && isChildStore(target)) {
|
|
758
|
+
const { parent } = target;
|
|
759
|
+
const copiedValue = copyMutableIfNeeded(target, mutableAtom, parent);
|
|
760
|
+
transceiver = copiedValue;
|
|
761
|
+
}
|
|
762
|
+
const accepted = transceiver.do(update.newValue) === null;
|
|
763
|
+
if (accepted) evictDownStream(target, mutableAtom);
|
|
764
|
+
}
|
|
746
765
|
};
|
|
747
766
|
|
|
748
767
|
//#endregion
|
|
749
|
-
//#region src/internal/
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
768
|
+
//#region src/internal/set-state/reset-atom-or-selector.ts
|
|
769
|
+
function resetAtom(store, state) {
|
|
770
|
+
let def = state.default;
|
|
771
|
+
if (def instanceof Function) def = def();
|
|
772
|
+
setAtom(store, state, def);
|
|
773
|
+
}
|
|
774
|
+
function resetAtomOrSelector(store, state) {
|
|
775
|
+
switch (state.type) {
|
|
776
|
+
case `atom`:
|
|
777
|
+
case `mutable_atom`:
|
|
778
|
+
resetAtom(store, state);
|
|
779
|
+
break;
|
|
780
|
+
case `writable_pure_selector`:
|
|
781
|
+
case `writable_held_selector`:
|
|
782
|
+
{
|
|
783
|
+
const atoms = traceRootSelectorAtoms(store, state.key);
|
|
784
|
+
for (const atom$1 of atoms.values()) resetAtom(store, atom$1);
|
|
785
|
+
}
|
|
786
|
+
break;
|
|
787
|
+
}
|
|
788
|
+
}
|
|
789
|
+
|
|
790
|
+
//#endregion
|
|
791
|
+
//#region src/internal/families/get-family-of-token.ts
|
|
792
|
+
function getFamilyOfToken(store, token) {
|
|
793
|
+
if (token.family) {
|
|
794
|
+
const family = store.families.get(token.family.key);
|
|
795
|
+
if (family) return family;
|
|
796
|
+
}
|
|
797
|
+
}
|
|
798
|
+
|
|
799
|
+
//#endregion
|
|
800
|
+
//#region src/internal/set-state/reset-in-store.ts
|
|
801
|
+
function resetInStore(store, ...params) {
|
|
802
|
+
let token;
|
|
803
|
+
let family;
|
|
804
|
+
let key;
|
|
805
|
+
if (params.length === 1) {
|
|
806
|
+
token = params[0];
|
|
807
|
+
family = getFamilyOfToken(store, token) ?? null;
|
|
808
|
+
if (family) {
|
|
809
|
+
key = token.family ? parseJson(token.family.subKey) : null;
|
|
810
|
+
token = findInStore(store, family, key);
|
|
811
|
+
}
|
|
759
812
|
} else {
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
813
|
+
family = params[0];
|
|
814
|
+
key = params[1];
|
|
815
|
+
token = findInStore(store, family, key);
|
|
816
|
+
}
|
|
817
|
+
if (`counterfeit` in token && `family` in token) {
|
|
818
|
+
const subKey = token.family.subKey;
|
|
819
|
+
const disposal = store.disposalTraces.buffer.find((item) => item?.key === subKey);
|
|
820
|
+
store.logger.error(`❌`, token.type, token.key, `could not be reset because it was not found in the store "${store.config.name}".`, disposal ? `This state was previously disposed:\n${disposal.trace}` : `No previous disposal trace was found.`);
|
|
821
|
+
return;
|
|
822
|
+
}
|
|
823
|
+
const rejectionTime = openOperation(store, token);
|
|
824
|
+
if (rejectionTime) {
|
|
825
|
+
const unsubscribe = store.on.operationClose.subscribe(`waiting to reset "${token.key}" at T-${rejectionTime}`, () => {
|
|
826
|
+
unsubscribe();
|
|
827
|
+
store.logger.info(`🟢`, token.type, token.key, `resuming deferred resetState from T-${rejectionTime}`);
|
|
828
|
+
resetInStore(store, token);
|
|
765
829
|
});
|
|
830
|
+
return;
|
|
831
|
+
}
|
|
832
|
+
const state = withdraw(store, token);
|
|
833
|
+
resetAtomOrSelector(store, state);
|
|
834
|
+
closeOperation(store);
|
|
835
|
+
}
|
|
836
|
+
|
|
837
|
+
//#endregion
|
|
838
|
+
//#region src/internal/set-state/set-atom-or-selector.ts
|
|
839
|
+
const setAtomOrSelector = (store, state, value) => {
|
|
840
|
+
switch (state.type) {
|
|
841
|
+
case `atom`:
|
|
842
|
+
case `mutable_atom`:
|
|
843
|
+
setAtom(store, state, value);
|
|
844
|
+
break;
|
|
845
|
+
case `writable_pure_selector`:
|
|
846
|
+
case `writable_held_selector`:
|
|
847
|
+
state.set(value);
|
|
848
|
+
break;
|
|
766
849
|
}
|
|
767
|
-
covered.add(dependencyKey);
|
|
768
850
|
};
|
|
769
851
|
|
|
770
852
|
//#endregion
|
|
771
|
-
//#region src/internal/
|
|
772
|
-
|
|
853
|
+
//#region src/internal/set-state/set-into-store.ts
|
|
854
|
+
function setIntoStore(store, ...params) {
|
|
855
|
+
let token;
|
|
856
|
+
let family;
|
|
857
|
+
let key;
|
|
858
|
+
let value;
|
|
859
|
+
if (params.length === 2) {
|
|
860
|
+
token = params[0];
|
|
861
|
+
value = params[1];
|
|
862
|
+
family = getFamilyOfToken(store, token) ?? null;
|
|
863
|
+
if (family) {
|
|
864
|
+
key = token.family ? parseJson(token.family.subKey) : null;
|
|
865
|
+
token = findInStore(store, family, key);
|
|
866
|
+
}
|
|
867
|
+
} else {
|
|
868
|
+
family = params[0];
|
|
869
|
+
key = params[1];
|
|
870
|
+
value = params[2];
|
|
871
|
+
token = findInStore(store, family, key);
|
|
872
|
+
}
|
|
873
|
+
if (`counterfeit` in token && `family` in token) {
|
|
874
|
+
const subKey = token.family.subKey;
|
|
875
|
+
const disposal = store.disposalTraces.buffer.find((item) => item?.key === subKey);
|
|
876
|
+
store.logger.error(`❌`, token.type, token.key, `could not be set because it was not found in the store "${store.config.name}".`, disposal ? `This state was previously disposed:\n${disposal.trace}` : `No previous disposal trace was found.`);
|
|
877
|
+
return;
|
|
878
|
+
}
|
|
879
|
+
const rejectionTime = openOperation(store, token);
|
|
880
|
+
if (rejectionTime) {
|
|
881
|
+
const unsubscribe = store.on.operationClose.subscribe(`waiting to set "${token.key}" at T-${rejectionTime}`, () => {
|
|
882
|
+
unsubscribe();
|
|
883
|
+
store.logger.info(`🟢`, token.type, token.key, `resuming deferred setState from T-${rejectionTime}`);
|
|
884
|
+
setIntoStore(store, token, value);
|
|
885
|
+
});
|
|
886
|
+
return;
|
|
887
|
+
}
|
|
888
|
+
const state = withdraw(store, token);
|
|
889
|
+
setAtomOrSelector(store, state, value);
|
|
890
|
+
closeOperation(store);
|
|
891
|
+
}
|
|
892
|
+
|
|
893
|
+
//#endregion
|
|
894
|
+
//#region src/internal/keys.ts
|
|
895
|
+
const isAtomKey = (store, key) => newest(store).atoms.has(key);
|
|
896
|
+
const isSelectorKey = (store, key) => newest(store).writableSelectors.has(key);
|
|
897
|
+
const isReadonlySelectorKey = (store, key) => newest(store).readonlySelectors.has(key);
|
|
898
|
+
const isStateKey = (store, key) => isAtomKey(store, key) || isSelectorKey(store, key) || isReadonlySelectorKey(store, key);
|
|
899
|
+
|
|
900
|
+
//#endregion
|
|
901
|
+
//#region src/internal/selector/get-selector-dependency-keys.ts
|
|
902
|
+
const getSelectorDependencyKeys = (store, key) => {
|
|
903
|
+
const sources = newest(store).selectorGraph.getRelationEntries({ downstreamSelectorKey: key }).filter(([_, { source }]) => source !== key).map(([_, { source }]) => source).filter((source) => isStateKey(store, source));
|
|
904
|
+
return sources;
|
|
905
|
+
};
|
|
906
|
+
|
|
907
|
+
//#endregion
|
|
908
|
+
//#region src/internal/selector/trace-selector-atoms.ts
|
|
909
|
+
const traceRootSelectorAtoms = (store, selectorKey, covered = /* @__PURE__ */ new Set()) => {
|
|
910
|
+
const dependencies = getSelectorDependencyKeys(store, selectorKey);
|
|
911
|
+
const roots = /* @__PURE__ */ new Map();
|
|
912
|
+
while (dependencies.length > 0) {
|
|
913
|
+
const dependencyKey = dependencies.pop();
|
|
914
|
+
if (covered.has(dependencyKey)) continue;
|
|
915
|
+
covered.add(dependencyKey);
|
|
916
|
+
if (isAtomKey(store, dependencyKey)) {
|
|
917
|
+
const atom$1 = store.atoms.get(dependencyKey);
|
|
918
|
+
roots.set(atom$1.key, atom$1);
|
|
919
|
+
} else dependencies.push(...getSelectorDependencyKeys(store, dependencyKey));
|
|
920
|
+
}
|
|
921
|
+
return roots;
|
|
922
|
+
};
|
|
923
|
+
|
|
924
|
+
//#endregion
|
|
925
|
+
//#region src/internal/selector/update-selector-atoms.ts
|
|
926
|
+
const updateSelectorAtoms = (store, selectorType, selectorKey, dependency, covered) => {
|
|
927
|
+
const target = newest(store);
|
|
928
|
+
const { type: dependencyType, key: dependencyKey } = dependency;
|
|
929
|
+
if (dependencyType === `atom` || dependencyType === `mutable_atom`) {
|
|
930
|
+
target.selectorAtoms.set({
|
|
931
|
+
selectorKey,
|
|
932
|
+
atomKey: dependencyKey
|
|
933
|
+
});
|
|
934
|
+
store.logger.info(`🔍`, selectorType, selectorKey, `discovers root atom "${dependencyKey}"`);
|
|
935
|
+
} else {
|
|
936
|
+
const rootKeys = traceRootSelectorAtoms(store, dependencyKey, covered);
|
|
937
|
+
store.logger.info(`🔍`, selectorType, selectorKey, `discovers root atoms: [ ${[...rootKeys.values()].map((root) => `"${root.key}"`).join(`, `)} ]`);
|
|
938
|
+
for (const { key: atomKey } of rootKeys.values()) target.selectorAtoms = target.selectorAtoms.set({
|
|
939
|
+
selectorKey,
|
|
940
|
+
atomKey
|
|
941
|
+
});
|
|
942
|
+
}
|
|
943
|
+
covered.add(dependencyKey);
|
|
944
|
+
};
|
|
945
|
+
|
|
946
|
+
//#endregion
|
|
947
|
+
//#region src/internal/selector/register-selector.ts
|
|
948
|
+
const registerSelector = (store, selectorType, selectorKey, covered) => ({
|
|
773
949
|
get: (...params) => {
|
|
774
950
|
const target = newest(store);
|
|
775
951
|
let dependency;
|
|
@@ -818,6 +994,10 @@ const createReadonlyHeldSelector = (store, options, family) => {
|
|
|
818
994
|
const type = `readonly_held_selector`;
|
|
819
995
|
const { get, find, json } = registerSelector(target, type, key, covered);
|
|
820
996
|
const getSelf = () => {
|
|
997
|
+
const innerTarget = newest(store);
|
|
998
|
+
const upstreamStates = innerTarget.selectorGraph.getRelationEntries({ downstreamSelectorKey: key });
|
|
999
|
+
for (const [downstreamSelectorKey, { source }] of upstreamStates) if (source !== key) innerTarget.selectorGraph.delete(downstreamSelectorKey, key);
|
|
1000
|
+
innerTarget.selectorAtoms.delete(key);
|
|
821
1001
|
options.get({
|
|
822
1002
|
get,
|
|
823
1003
|
find,
|
|
@@ -855,14 +1035,19 @@ const createReadonlyPureSelector = (store, options, family) => {
|
|
|
855
1035
|
const type = `readonly_pure_selector`;
|
|
856
1036
|
const { get, find, json } = registerSelector(target, type, key, covered);
|
|
857
1037
|
const getSelf = () => {
|
|
1038
|
+
const innerTarget = newest(store);
|
|
1039
|
+
const upstreamStates = innerTarget.selectorGraph.getRelationEntries({ downstreamSelectorKey: key });
|
|
1040
|
+
for (const [downstreamSelectorKey, { source }] of upstreamStates) if (source !== key) innerTarget.selectorGraph.delete(downstreamSelectorKey, key);
|
|
1041
|
+
innerTarget.selectorAtoms.delete(key);
|
|
858
1042
|
const value = options.get({
|
|
859
1043
|
get,
|
|
860
1044
|
find,
|
|
861
1045
|
json
|
|
862
1046
|
});
|
|
863
|
-
cacheValue(
|
|
1047
|
+
const cached = cacheValue(innerTarget, key, value, subject);
|
|
1048
|
+
store.logger.info(`✨`, type, key, `=`, cached);
|
|
864
1049
|
covered.clear();
|
|
865
|
-
return
|
|
1050
|
+
return cached;
|
|
866
1051
|
};
|
|
867
1052
|
const readonlySelector = {
|
|
868
1053
|
...options,
|
|
@@ -873,8 +1058,6 @@ const createReadonlyPureSelector = (store, options, family) => {
|
|
|
873
1058
|
...family && { family }
|
|
874
1059
|
};
|
|
875
1060
|
target.readonlySelectors.set(key, readonlySelector);
|
|
876
|
-
const initialValue = getSelf();
|
|
877
|
-
store.logger.info(`✨`, type, key, `=`, initialValue);
|
|
878
1061
|
const token = {
|
|
879
1062
|
key,
|
|
880
1063
|
type
|
|
@@ -884,639 +1067,66 @@ const createReadonlyPureSelector = (store, options, family) => {
|
|
|
884
1067
|
};
|
|
885
1068
|
|
|
886
1069
|
//#endregion
|
|
887
|
-
//#region src/internal/
|
|
888
|
-
const
|
|
1070
|
+
//#region src/internal/transaction/abort-transaction.ts
|
|
1071
|
+
const abortTransaction = (store) => {
|
|
889
1072
|
const target = newest(store);
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
const getterToolkit = {
|
|
897
|
-
find,
|
|
898
|
-
get,
|
|
899
|
-
json
|
|
900
|
-
};
|
|
901
|
-
const getSelf = (getFn = options.get, innerTarget = newest(store)) => {
|
|
902
|
-
getFn(getterToolkit, constant);
|
|
903
|
-
cacheValue(innerTarget, key, constant, subject);
|
|
904
|
-
covered.clear();
|
|
905
|
-
return constant;
|
|
906
|
-
};
|
|
907
|
-
const setSelf = (next) => {
|
|
908
|
-
const innerTarget = newest(store);
|
|
909
|
-
const oldValue = getSelf(options.get, innerTarget);
|
|
910
|
-
const newValue = become(next)(oldValue);
|
|
911
|
-
store.logger.info(`📝`, type, key, `set (`, oldValue, `->`, newValue, `)`);
|
|
912
|
-
cacheValue(innerTarget, key, newValue, subject);
|
|
913
|
-
markDone(innerTarget, key);
|
|
914
|
-
if (isRootStore(innerTarget)) subject.next({
|
|
915
|
-
newValue,
|
|
916
|
-
oldValue
|
|
917
|
-
});
|
|
918
|
-
options.set(setterToolkit, newValue);
|
|
919
|
-
};
|
|
920
|
-
const mySelector = {
|
|
921
|
-
...options,
|
|
922
|
-
type,
|
|
923
|
-
subject,
|
|
924
|
-
install: (s) => createWritableHeldSelector(s, options, family),
|
|
925
|
-
get: getSelf,
|
|
926
|
-
set: setSelf,
|
|
927
|
-
...family && { family }
|
|
928
|
-
};
|
|
929
|
-
target.writableSelectors.set(key, mySelector);
|
|
930
|
-
const initialValue = getSelf();
|
|
931
|
-
store.logger.info(`✨`, type, key, `=`, initialValue);
|
|
932
|
-
const token = {
|
|
933
|
-
key,
|
|
934
|
-
type
|
|
935
|
-
};
|
|
936
|
-
if (family) token.family = family;
|
|
937
|
-
return token;
|
|
1073
|
+
if (!isChildStore(target)) {
|
|
1074
|
+
store.logger.warn(`🐞`, `transaction`, `???`, `abortTransaction called outside of a transaction. This is probably a bug in AtomIO.`);
|
|
1075
|
+
return;
|
|
1076
|
+
}
|
|
1077
|
+
store.logger.info(`🪂`, `transaction`, target.transactionMeta.update.key, `Aborting transaction`);
|
|
1078
|
+
target.parent.child = null;
|
|
938
1079
|
};
|
|
939
1080
|
|
|
940
1081
|
//#endregion
|
|
941
|
-
//#region src/internal/
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
const
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
markDone(innerTarget, options.key);
|
|
968
|
-
if (isRootStore(innerTarget)) subject.next({
|
|
969
|
-
newValue,
|
|
970
|
-
oldValue
|
|
971
|
-
});
|
|
972
|
-
options.set(setterToolkit, newValue);
|
|
973
|
-
};
|
|
974
|
-
const mySelector = {
|
|
975
|
-
...options,
|
|
976
|
-
type,
|
|
977
|
-
subject,
|
|
978
|
-
install: (s) => createWritablePureSelector(s, options, family),
|
|
979
|
-
get: getSelf,
|
|
980
|
-
set: setSelf,
|
|
981
|
-
...family && { family }
|
|
1082
|
+
//#region src/internal/capitalize.ts
|
|
1083
|
+
function capitalize(string) {
|
|
1084
|
+
return string[0].toUpperCase() + string.slice(1);
|
|
1085
|
+
}
|
|
1086
|
+
|
|
1087
|
+
//#endregion
|
|
1088
|
+
//#region src/internal/pretty-print.ts
|
|
1089
|
+
function prettyPrintTokenType(token) {
|
|
1090
|
+
return token.type.split(`_`).map(capitalize).join(` `);
|
|
1091
|
+
}
|
|
1092
|
+
|
|
1093
|
+
//#endregion
|
|
1094
|
+
//#region src/internal/not-found-error.ts
|
|
1095
|
+
var NotFoundError = class extends Error {
|
|
1096
|
+
constructor(token, store) {
|
|
1097
|
+
super(`${prettyPrintTokenType(token)} ${stringifyJson(token.key)} not found in store "${store.config.name}".`);
|
|
1098
|
+
}
|
|
1099
|
+
};
|
|
1100
|
+
|
|
1101
|
+
//#endregion
|
|
1102
|
+
//#region src/internal/transaction/act-upon-store.ts
|
|
1103
|
+
function actUponStore(store, token, id) {
|
|
1104
|
+
return (...parameters) => {
|
|
1105
|
+
const tx = withdraw(store, token);
|
|
1106
|
+
if (tx) return tx.run(parameters, id);
|
|
1107
|
+
throw new NotFoundError(token, store);
|
|
982
1108
|
};
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
1109
|
+
}
|
|
1110
|
+
|
|
1111
|
+
//#endregion
|
|
1112
|
+
//#region src/internal/ingest-updates/ingest-atom-update.ts
|
|
1113
|
+
function ingestAtomUpdate(applying, atomUpdate, store) {
|
|
1114
|
+
const { key, newValue, oldValue } = atomUpdate;
|
|
1115
|
+
const value = applying === `newValue` ? newValue : oldValue;
|
|
986
1116
|
const token = {
|
|
987
1117
|
key,
|
|
988
|
-
type
|
|
1118
|
+
type: `atom`
|
|
989
1119
|
};
|
|
990
|
-
if (family) token.family
|
|
991
|
-
|
|
992
|
-
}
|
|
1120
|
+
if (atomUpdate.family) Object.assign(token, { family: atomUpdate.family });
|
|
1121
|
+
setIntoStore(store, token, value);
|
|
1122
|
+
}
|
|
993
1123
|
|
|
994
1124
|
//#endregion
|
|
995
|
-
//#region src/internal/
|
|
996
|
-
function
|
|
997
|
-
const
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
const state$1 = createWritableHeldSelector(store, options, void 0);
|
|
1001
|
-
store.on.selectorCreation.next(state$1);
|
|
1002
|
-
return state$1;
|
|
1003
|
-
}
|
|
1004
|
-
if (isHeld) {
|
|
1005
|
-
const state$1 = createReadonlyHeldSelector(store, options, void 0);
|
|
1006
|
-
store.on.selectorCreation.next(state$1);
|
|
1007
|
-
return state$1;
|
|
1008
|
-
}
|
|
1009
|
-
if (isWritable) {
|
|
1010
|
-
const state$1 = createWritablePureSelector(store, options, void 0);
|
|
1011
|
-
store.on.selectorCreation.next(state$1);
|
|
1012
|
-
return state$1;
|
|
1013
|
-
}
|
|
1014
|
-
const state = createReadonlyPureSelector(store, options, void 0);
|
|
1015
|
-
store.on.selectorCreation.next(state);
|
|
1016
|
-
return state;
|
|
1017
|
-
}
|
|
1018
|
-
|
|
1019
|
-
//#endregion
|
|
1020
|
-
//#region src/internal/selector/dispose-selector.ts
|
|
1021
|
-
function disposeSelector(store, selectorToken) {
|
|
1022
|
-
const target = newest(store);
|
|
1023
|
-
const { key, type } = selectorToken;
|
|
1024
|
-
const selector = withdraw(target, selectorToken);
|
|
1025
|
-
if (!selector.family) store.logger.error(`❌`, type, key, `Standalone selectors cannot be disposed.`);
|
|
1026
|
-
else {
|
|
1027
|
-
const molecule = target.molecules.get(selector.family.subKey);
|
|
1028
|
-
if (molecule) target.moleculeData.delete(selector.family.subKey, selector.family.key);
|
|
1029
|
-
let familyToken;
|
|
1030
|
-
switch (selectorToken.type) {
|
|
1031
|
-
case `writable_held_selector`:
|
|
1032
|
-
{
|
|
1033
|
-
target.writableSelectors.delete(key);
|
|
1034
|
-
familyToken = {
|
|
1035
|
-
key: selector.family.key,
|
|
1036
|
-
type: `writable_held_selector_family`
|
|
1037
|
-
};
|
|
1038
|
-
const family = withdraw(store, familyToken);
|
|
1039
|
-
family.subject.next({
|
|
1040
|
-
type: `state_disposal`,
|
|
1041
|
-
subType: `selector`,
|
|
1042
|
-
token: selectorToken
|
|
1043
|
-
});
|
|
1044
|
-
}
|
|
1045
|
-
break;
|
|
1046
|
-
case `writable_pure_selector`:
|
|
1047
|
-
{
|
|
1048
|
-
target.writableSelectors.delete(key);
|
|
1049
|
-
familyToken = {
|
|
1050
|
-
key: selector.family.key,
|
|
1051
|
-
type: `writable_pure_selector_family`
|
|
1052
|
-
};
|
|
1053
|
-
const family = withdraw(store, familyToken);
|
|
1054
|
-
family.subject.next({
|
|
1055
|
-
type: `state_disposal`,
|
|
1056
|
-
subType: `selector`,
|
|
1057
|
-
token: selectorToken
|
|
1058
|
-
});
|
|
1059
|
-
}
|
|
1060
|
-
break;
|
|
1061
|
-
case `readonly_held_selector`:
|
|
1062
|
-
{
|
|
1063
|
-
target.readonlySelectors.delete(key);
|
|
1064
|
-
familyToken = {
|
|
1065
|
-
key: selector.family.key,
|
|
1066
|
-
type: `readonly_held_selector_family`
|
|
1067
|
-
};
|
|
1068
|
-
const family = withdraw(store, familyToken);
|
|
1069
|
-
family.subject.next({
|
|
1070
|
-
type: `state_disposal`,
|
|
1071
|
-
subType: `selector`,
|
|
1072
|
-
token: selectorToken
|
|
1073
|
-
});
|
|
1074
|
-
}
|
|
1075
|
-
break;
|
|
1076
|
-
case `readonly_pure_selector`:
|
|
1077
|
-
{
|
|
1078
|
-
target.readonlySelectors.delete(key);
|
|
1079
|
-
familyToken = {
|
|
1080
|
-
key: selector.family.key,
|
|
1081
|
-
type: `readonly_pure_selector_family`
|
|
1082
|
-
};
|
|
1083
|
-
const family = withdraw(store, familyToken);
|
|
1084
|
-
family.subject.next({
|
|
1085
|
-
type: `state_disposal`,
|
|
1086
|
-
subType: `selector`,
|
|
1087
|
-
token: selectorToken
|
|
1088
|
-
});
|
|
1089
|
-
}
|
|
1090
|
-
break;
|
|
1091
|
-
}
|
|
1092
|
-
target.valueMap.delete(key);
|
|
1093
|
-
target.selectorAtoms.delete(key);
|
|
1094
|
-
target.selectorGraph.delete(key);
|
|
1095
|
-
store.logger.info(`🔥`, selectorToken.type, key, `deleted`);
|
|
1096
|
-
if (isChildStore(target) && target.transactionMeta.phase === `building`) target.transactionMeta.update.updates.push({
|
|
1097
|
-
type: `state_disposal`,
|
|
1098
|
-
subType: `selector`,
|
|
1099
|
-
token: selectorToken
|
|
1100
|
-
});
|
|
1101
|
-
else store.on.selectorDisposal.next(selectorToken);
|
|
1102
|
-
}
|
|
1103
|
-
}
|
|
1104
|
-
|
|
1105
|
-
//#endregion
|
|
1106
|
-
//#region src/internal/families/create-readonly-pure-selector-family.ts
|
|
1107
|
-
function createReadonlyPureSelectorFamily(store, options, internalRoles) {
|
|
1108
|
-
const familyKey = options.key;
|
|
1109
|
-
const type = `readonly_pure_selector_family`;
|
|
1110
|
-
const familyToken = {
|
|
1111
|
-
key: familyKey,
|
|
1112
|
-
type
|
|
1113
|
-
};
|
|
1114
|
-
const existing = store.families.get(familyKey);
|
|
1115
|
-
if (existing) store.logger.error(`❗`, type, familyKey, `Overwriting an existing ${prettyPrintTokenType(existing)} "${existing.key}" in store "${store.config.name}". You can safely ignore this warning if it is due to hot module replacement.`);
|
|
1116
|
-
const subject = new Subject();
|
|
1117
|
-
const familyFunction = (key) => {
|
|
1118
|
-
const subKey = stringifyJson(key);
|
|
1119
|
-
const family = {
|
|
1120
|
-
key: familyKey,
|
|
1121
|
-
subKey
|
|
1122
|
-
};
|
|
1123
|
-
const fullKey = `${familyKey}(${subKey})`;
|
|
1124
|
-
const target = newest(store);
|
|
1125
|
-
const token = createReadonlyPureSelector(target, {
|
|
1126
|
-
key: fullKey,
|
|
1127
|
-
get: options.get(key)
|
|
1128
|
-
}, family);
|
|
1129
|
-
subject.next({
|
|
1130
|
-
type: `state_creation`,
|
|
1131
|
-
token
|
|
1132
|
-
});
|
|
1133
|
-
return token;
|
|
1134
|
-
};
|
|
1135
|
-
const readonlySelectorFamily = Object.assign(familyFunction, familyToken, {
|
|
1136
|
-
internalRoles,
|
|
1137
|
-
subject,
|
|
1138
|
-
install: (s) => createReadonlyPureSelectorFamily(s, options),
|
|
1139
|
-
default: (key) => {
|
|
1140
|
-
const getFn = options.get(key);
|
|
1141
|
-
return getFn({
|
|
1142
|
-
get: ((...args) => getFromStore(store, ...args)),
|
|
1143
|
-
find: ((...args) => findInStore(store, ...args)),
|
|
1144
|
-
json: (token) => getJsonToken(store, token)
|
|
1145
|
-
});
|
|
1146
|
-
}
|
|
1147
|
-
});
|
|
1148
|
-
store.families.set(familyKey, readonlySelectorFamily);
|
|
1149
|
-
return familyToken;
|
|
1150
|
-
}
|
|
1151
|
-
|
|
1152
|
-
//#endregion
|
|
1153
|
-
//#region src/internal/families/create-readonly-held-selector-family.ts
|
|
1154
|
-
function createReadonlyHeldSelectorFamily(store, options, internalRoles) {
|
|
1155
|
-
const familyKey = options.key;
|
|
1156
|
-
const type = `readonly_held_selector_family`;
|
|
1157
|
-
const familyToken = {
|
|
1158
|
-
key: familyKey,
|
|
1159
|
-
type
|
|
1160
|
-
};
|
|
1161
|
-
const existing = store.families.get(familyKey);
|
|
1162
|
-
if (existing) store.logger.error(`❗`, type, familyKey, `Overwriting an existing ${prettyPrintTokenType(existing)} "${existing.key}" in store "${store.config.name}". You can safely ignore this warning if it is due to hot module replacement.`);
|
|
1163
|
-
const subject = new Subject();
|
|
1164
|
-
const familyFunction = (key) => {
|
|
1165
|
-
const subKey = stringifyJson(key);
|
|
1166
|
-
const family = {
|
|
1167
|
-
key: familyKey,
|
|
1168
|
-
subKey
|
|
1169
|
-
};
|
|
1170
|
-
const fullKey = `${familyKey}(${subKey})`;
|
|
1171
|
-
const target = newest(store);
|
|
1172
|
-
const token = createReadonlyHeldSelector(target, {
|
|
1173
|
-
key: fullKey,
|
|
1174
|
-
const: options.const(key),
|
|
1175
|
-
get: options.get(key)
|
|
1176
|
-
}, family);
|
|
1177
|
-
subject.next({
|
|
1178
|
-
type: `state_creation`,
|
|
1179
|
-
token
|
|
1180
|
-
});
|
|
1181
|
-
return token;
|
|
1182
|
-
};
|
|
1183
|
-
const readonlySelectorFamily = Object.assign(familyFunction, familyToken, {
|
|
1184
|
-
internalRoles,
|
|
1185
|
-
subject,
|
|
1186
|
-
install: (s) => createReadonlyHeldSelectorFamily(s, options),
|
|
1187
|
-
default: options.const
|
|
1188
|
-
});
|
|
1189
|
-
store.families.set(familyKey, readonlySelectorFamily);
|
|
1190
|
-
return familyToken;
|
|
1191
|
-
}
|
|
1192
|
-
|
|
1193
|
-
//#endregion
|
|
1194
|
-
//#region src/internal/families/create-writable-held-selector-family.ts
|
|
1195
|
-
function createWritableHeldSelectorFamily(store, options, internalRoles) {
|
|
1196
|
-
const familyKey = options.key;
|
|
1197
|
-
const type = `writable_held_selector_family`;
|
|
1198
|
-
const familyToken = {
|
|
1199
|
-
key: familyKey,
|
|
1200
|
-
type
|
|
1201
|
-
};
|
|
1202
|
-
const existing = store.families.get(familyKey);
|
|
1203
|
-
if (existing) store.logger.error(`❗`, type, familyKey, `Overwriting an existing ${prettyPrintTokenType(existing)} "${existing.key}" in store "${store.config.name}". You can safely ignore this warning if it is due to hot module replacement.`);
|
|
1204
|
-
const subject = new Subject();
|
|
1205
|
-
const familyFunction = (key) => {
|
|
1206
|
-
const subKey = stringifyJson(key);
|
|
1207
|
-
const family = {
|
|
1208
|
-
key: familyKey,
|
|
1209
|
-
subKey
|
|
1210
|
-
};
|
|
1211
|
-
const fullKey = `${familyKey}(${subKey})`;
|
|
1212
|
-
const target = newest(store);
|
|
1213
|
-
const token = createWritableHeldSelector(target, {
|
|
1214
|
-
key: fullKey,
|
|
1215
|
-
const: options.const(key),
|
|
1216
|
-
get: options.get(key),
|
|
1217
|
-
set: options.set(key)
|
|
1218
|
-
}, family);
|
|
1219
|
-
subject.next({
|
|
1220
|
-
type: `state_creation`,
|
|
1221
|
-
token
|
|
1222
|
-
});
|
|
1223
|
-
return token;
|
|
1224
|
-
};
|
|
1225
|
-
const selectorFamily$1 = Object.assign(familyFunction, familyToken, {
|
|
1226
|
-
internalRoles,
|
|
1227
|
-
subject,
|
|
1228
|
-
install: (s) => createWritableHeldSelectorFamily(s, options),
|
|
1229
|
-
default: options.const
|
|
1230
|
-
});
|
|
1231
|
-
store.families.set(familyKey, selectorFamily$1);
|
|
1232
|
-
return familyToken;
|
|
1233
|
-
}
|
|
1234
|
-
|
|
1235
|
-
//#endregion
|
|
1236
|
-
//#region src/internal/families/create-writable-pure-selector-family.ts
|
|
1237
|
-
function createWritablePureSelectorFamily(store, options, internalRoles) {
|
|
1238
|
-
const familyKey = options.key;
|
|
1239
|
-
const type = `writable_pure_selector_family`;
|
|
1240
|
-
const familyToken = {
|
|
1241
|
-
key: familyKey,
|
|
1242
|
-
type
|
|
1243
|
-
};
|
|
1244
|
-
const existing = store.families.get(familyKey);
|
|
1245
|
-
if (existing) store.logger.error(`❗`, type, familyKey, `Overwriting an existing ${prettyPrintTokenType(existing)} "${existing.key}" in store "${store.config.name}". You can safely ignore this warning if it is due to hot module replacement.`);
|
|
1246
|
-
const subject = new Subject();
|
|
1247
|
-
const familyFunction = (key) => {
|
|
1248
|
-
const subKey = stringifyJson(key);
|
|
1249
|
-
const family = {
|
|
1250
|
-
key: familyKey,
|
|
1251
|
-
subKey
|
|
1252
|
-
};
|
|
1253
|
-
const fullKey = `${familyKey}(${subKey})`;
|
|
1254
|
-
const target = newest(store);
|
|
1255
|
-
const token = createWritablePureSelector(target, {
|
|
1256
|
-
key: fullKey,
|
|
1257
|
-
get: options.get(key),
|
|
1258
|
-
set: options.set(key)
|
|
1259
|
-
}, family);
|
|
1260
|
-
subject.next({
|
|
1261
|
-
type: `state_creation`,
|
|
1262
|
-
token
|
|
1263
|
-
});
|
|
1264
|
-
return token;
|
|
1265
|
-
};
|
|
1266
|
-
const selectorFamily$1 = Object.assign(familyFunction, familyToken, {
|
|
1267
|
-
internalRoles,
|
|
1268
|
-
subject,
|
|
1269
|
-
install: (s) => createWritablePureSelectorFamily(s, options),
|
|
1270
|
-
default: (key) => {
|
|
1271
|
-
const getFn = options.get(key);
|
|
1272
|
-
return getFn({
|
|
1273
|
-
get: ((...args) => getFromStore(store, ...args)),
|
|
1274
|
-
find: ((...args) => findInStore(store, ...args)),
|
|
1275
|
-
json: (token) => getJsonToken(store, token)
|
|
1276
|
-
});
|
|
1277
|
-
}
|
|
1278
|
-
});
|
|
1279
|
-
store.families.set(familyKey, selectorFamily$1);
|
|
1280
|
-
return familyToken;
|
|
1281
|
-
}
|
|
1282
|
-
|
|
1283
|
-
//#endregion
|
|
1284
|
-
//#region src/internal/families/create-selector-family.ts
|
|
1285
|
-
function createSelectorFamily(store, options) {
|
|
1286
|
-
const isWritable = `set` in options;
|
|
1287
|
-
const isHeld = `const` in options;
|
|
1288
|
-
if (isHeld && isWritable) return createWritableHeldSelectorFamily(store, options, void 0);
|
|
1289
|
-
if (isHeld) return createReadonlyHeldSelectorFamily(store, options, void 0);
|
|
1290
|
-
if (isWritable) return createWritablePureSelectorFamily(store, options);
|
|
1291
|
-
return createReadonlyPureSelectorFamily(store, options);
|
|
1292
|
-
}
|
|
1293
|
-
|
|
1294
|
-
//#endregion
|
|
1295
|
-
//#region src/internal/families/init-family-member.ts
|
|
1296
|
-
function initFamilyMemberInStore(store, token, key) {
|
|
1297
|
-
const family = store.families.get(token.key);
|
|
1298
|
-
if (family === void 0) throw new NotFoundError(token, store);
|
|
1299
|
-
const state = family(key);
|
|
1300
|
-
const target = newest(store);
|
|
1301
|
-
if (state.family) {
|
|
1302
|
-
if (isRootStore(target)) switch (state.type) {
|
|
1303
|
-
case `atom`:
|
|
1304
|
-
case `mutable_atom`:
|
|
1305
|
-
store.on.atomCreation.next(state);
|
|
1306
|
-
break;
|
|
1307
|
-
case `writable_pure_selector`:
|
|
1308
|
-
case `readonly_pure_selector`:
|
|
1309
|
-
case `writable_held_selector`:
|
|
1310
|
-
case `readonly_held_selector`:
|
|
1311
|
-
store.on.selectorCreation.next(state);
|
|
1312
|
-
break;
|
|
1313
|
-
}
|
|
1314
|
-
else if (isChildStore(target) && target.on.transactionApplying.state === null) target.transactionMeta.update.updates.push({
|
|
1315
|
-
type: `state_creation`,
|
|
1316
|
-
token: state
|
|
1317
|
-
});
|
|
1318
|
-
}
|
|
1319
|
-
return state;
|
|
1320
|
-
}
|
|
1321
|
-
|
|
1322
|
-
//#endregion
|
|
1323
|
-
//#region src/internal/families/seek-in-store.ts
|
|
1324
|
-
function seekInStore(store, token, key) {
|
|
1325
|
-
const subKey = stringifyJson(key);
|
|
1326
|
-
const fullKey = `${token.key}(${subKey})`;
|
|
1327
|
-
const target = newest(store);
|
|
1328
|
-
let state;
|
|
1329
|
-
switch (token.type) {
|
|
1330
|
-
case `atom_family`:
|
|
1331
|
-
case `mutable_atom_family`:
|
|
1332
|
-
state = target.atoms.get(fullKey);
|
|
1333
|
-
break;
|
|
1334
|
-
case `writable_held_selector_family`:
|
|
1335
|
-
case `writable_pure_selector_family`:
|
|
1336
|
-
state = target.writableSelectors.get(fullKey);
|
|
1337
|
-
break;
|
|
1338
|
-
case `readonly_held_selector_family`:
|
|
1339
|
-
case `readonly_pure_selector_family`:
|
|
1340
|
-
state = target.readonlySelectors.get(fullKey);
|
|
1341
|
-
break;
|
|
1342
|
-
}
|
|
1343
|
-
if (state) return deposit(state);
|
|
1344
|
-
return state;
|
|
1345
|
-
}
|
|
1346
|
-
|
|
1347
|
-
//#endregion
|
|
1348
|
-
//#region src/internal/families/find-in-store.ts
|
|
1349
|
-
function findInStore(store, token, key) {
|
|
1350
|
-
let state = seekInStore(store, token, key);
|
|
1351
|
-
if (state) return state;
|
|
1352
|
-
const stringKey = stringifyJson(key);
|
|
1353
|
-
const molecule = store.molecules.get(stringKey);
|
|
1354
|
-
if (!molecule && store.config.lifespan === `immortal`) {
|
|
1355
|
-
const fakeToken = counterfeit(token, key);
|
|
1356
|
-
store.logger.error(`❌`, fakeToken.type, fakeToken.key, `was not found in store "${store.config.name}"; returned a counterfeit token.`);
|
|
1357
|
-
return fakeToken;
|
|
1358
|
-
}
|
|
1359
|
-
state = initFamilyMemberInStore(store, token, key);
|
|
1360
|
-
if (molecule) {
|
|
1361
|
-
const target = newest(store);
|
|
1362
|
-
target.moleculeData.set(stringKey, token.key);
|
|
1363
|
-
}
|
|
1364
|
-
return state;
|
|
1365
|
-
}
|
|
1366
|
-
|
|
1367
|
-
//#endregion
|
|
1368
|
-
//#region src/internal/families/dispose-from-store.ts
|
|
1369
|
-
function disposeFromStore(store, ...params) {
|
|
1370
|
-
let token;
|
|
1371
|
-
if (params.length === 1) token = params[0];
|
|
1372
|
-
else {
|
|
1373
|
-
const family = params[0];
|
|
1374
|
-
const key = params[1];
|
|
1375
|
-
const maybeToken = findInStore(store, family, key);
|
|
1376
|
-
token = maybeToken;
|
|
1377
|
-
}
|
|
1378
|
-
try {
|
|
1379
|
-
withdraw(store, token);
|
|
1380
|
-
} catch (_) {
|
|
1381
|
-
store.logger.error(`❌`, token.type, token.key, `could not be disposed because it was not found in the store "${store.config.name}".`);
|
|
1382
|
-
return;
|
|
1383
|
-
}
|
|
1384
|
-
switch (token.type) {
|
|
1385
|
-
case `atom`:
|
|
1386
|
-
case `mutable_atom`:
|
|
1387
|
-
disposeAtom(store, token);
|
|
1388
|
-
break;
|
|
1389
|
-
case `writable_pure_selector`:
|
|
1390
|
-
case `readonly_pure_selector`:
|
|
1391
|
-
case `writable_held_selector`:
|
|
1392
|
-
case `readonly_held_selector`:
|
|
1393
|
-
disposeSelector(store, token);
|
|
1394
|
-
break;
|
|
1395
|
-
}
|
|
1396
|
-
}
|
|
1397
|
-
|
|
1398
|
-
//#endregion
|
|
1399
|
-
//#region src/internal/families/get-family-of-token.ts
|
|
1400
|
-
function getFamilyOfToken(store, token) {
|
|
1401
|
-
if (token.family) {
|
|
1402
|
-
const family = store.families.get(token.family.key);
|
|
1403
|
-
if (family) return family;
|
|
1404
|
-
}
|
|
1405
|
-
}
|
|
1406
|
-
|
|
1407
|
-
//#endregion
|
|
1408
|
-
//#region src/internal/set-state/reset-in-store.ts
|
|
1409
|
-
function resetInStore(store, ...params) {
|
|
1410
|
-
let token;
|
|
1411
|
-
let family;
|
|
1412
|
-
let key;
|
|
1413
|
-
if (params.length === 1) {
|
|
1414
|
-
token = params[0];
|
|
1415
|
-
family = getFamilyOfToken(store, token) ?? null;
|
|
1416
|
-
if (family) {
|
|
1417
|
-
key = token.family ? parseJson(token.family.subKey) : null;
|
|
1418
|
-
token = findInStore(store, family, key);
|
|
1419
|
-
}
|
|
1420
|
-
} else {
|
|
1421
|
-
family = params[0];
|
|
1422
|
-
key = params[1];
|
|
1423
|
-
token = findInStore(store, family, key);
|
|
1424
|
-
}
|
|
1425
|
-
if (`counterfeit` in token && `family` in token) {
|
|
1426
|
-
const subKey = token.family.subKey;
|
|
1427
|
-
const disposal = store.disposalTraces.buffer.find((item) => item?.key === subKey);
|
|
1428
|
-
store.logger.error(`❌`, token.type, token.key, `could not be reset because it was not found in the store "${store.config.name}".`, disposal ? `This state was previously disposed:\n${disposal.trace}` : `No previous disposal trace was found.`);
|
|
1429
|
-
return;
|
|
1430
|
-
}
|
|
1431
|
-
const rejectionTime = openOperation(store, token);
|
|
1432
|
-
if (rejectionTime) {
|
|
1433
|
-
const unsubscribe = store.on.operationClose.subscribe(`waiting to reset "${token.key}" at T-${rejectionTime}`, () => {
|
|
1434
|
-
unsubscribe();
|
|
1435
|
-
store.logger.info(`🟢`, token.type, token.key, `resuming deferred resetState from T-${rejectionTime}`);
|
|
1436
|
-
resetInStore(store, token);
|
|
1437
|
-
});
|
|
1438
|
-
return;
|
|
1439
|
-
}
|
|
1440
|
-
const state = withdraw(store, token);
|
|
1441
|
-
resetAtomOrSelector(store, state);
|
|
1442
|
-
closeOperation(store);
|
|
1443
|
-
}
|
|
1444
|
-
|
|
1445
|
-
//#endregion
|
|
1446
|
-
//#region src/internal/set-state/set-atom-or-selector.ts
|
|
1447
|
-
const setAtomOrSelector = (store, state, value) => {
|
|
1448
|
-
switch (state.type) {
|
|
1449
|
-
case `atom`:
|
|
1450
|
-
case `mutable_atom`:
|
|
1451
|
-
setAtom(store, state, value);
|
|
1452
|
-
break;
|
|
1453
|
-
case `writable_pure_selector`:
|
|
1454
|
-
case `writable_held_selector`:
|
|
1455
|
-
state.set(value);
|
|
1456
|
-
break;
|
|
1457
|
-
}
|
|
1458
|
-
};
|
|
1459
|
-
|
|
1460
|
-
//#endregion
|
|
1461
|
-
//#region src/internal/set-state/set-into-store.ts
|
|
1462
|
-
function setIntoStore(store, ...params) {
|
|
1463
|
-
let token;
|
|
1464
|
-
let family;
|
|
1465
|
-
let key;
|
|
1466
|
-
let value;
|
|
1467
|
-
if (params.length === 2) {
|
|
1468
|
-
token = params[0];
|
|
1469
|
-
value = params[1];
|
|
1470
|
-
family = getFamilyOfToken(store, token) ?? null;
|
|
1471
|
-
if (family) {
|
|
1472
|
-
key = token.family ? parseJson(token.family.subKey) : null;
|
|
1473
|
-
token = findInStore(store, family, key);
|
|
1474
|
-
}
|
|
1475
|
-
} else {
|
|
1476
|
-
family = params[0];
|
|
1477
|
-
key = params[1];
|
|
1478
|
-
value = params[2];
|
|
1479
|
-
token = findInStore(store, family, key);
|
|
1480
|
-
}
|
|
1481
|
-
if (`counterfeit` in token && `family` in token) {
|
|
1482
|
-
const subKey = token.family.subKey;
|
|
1483
|
-
const disposal = store.disposalTraces.buffer.find((item) => item?.key === subKey);
|
|
1484
|
-
store.logger.error(`❌`, token.type, token.key, `could not be set because it was not found in the store "${store.config.name}".`, disposal ? `This state was previously disposed:\n${disposal.trace}` : `No previous disposal trace was found.`);
|
|
1485
|
-
return;
|
|
1486
|
-
}
|
|
1487
|
-
const rejectionTime = openOperation(store, token);
|
|
1488
|
-
if (rejectionTime) {
|
|
1489
|
-
const unsubscribe = store.on.operationClose.subscribe(`waiting to set "${token.key}" at T-${rejectionTime}`, () => {
|
|
1490
|
-
unsubscribe();
|
|
1491
|
-
store.logger.info(`🟢`, token.type, token.key, `resuming deferred setState from T-${rejectionTime}`);
|
|
1492
|
-
setIntoStore(store, token, value);
|
|
1493
|
-
});
|
|
1494
|
-
return;
|
|
1495
|
-
}
|
|
1496
|
-
const state = withdraw(store, token);
|
|
1497
|
-
setAtomOrSelector(store, state, value);
|
|
1498
|
-
closeOperation(store);
|
|
1499
|
-
}
|
|
1500
|
-
|
|
1501
|
-
//#endregion
|
|
1502
|
-
//#region src/internal/ingest-updates/ingest-atom-update.ts
|
|
1503
|
-
function ingestAtomUpdate(applying, atomUpdate, store) {
|
|
1504
|
-
const { key, newValue, oldValue } = atomUpdate;
|
|
1505
|
-
const value = applying === `newValue` ? newValue : oldValue;
|
|
1506
|
-
const token = {
|
|
1507
|
-
key,
|
|
1508
|
-
type: `atom`
|
|
1509
|
-
};
|
|
1510
|
-
if (atomUpdate.family) Object.assign(token, { family: atomUpdate.family });
|
|
1511
|
-
setIntoStore(store, token, value);
|
|
1512
|
-
}
|
|
1513
|
-
|
|
1514
|
-
//#endregion
|
|
1515
|
-
//#region src/internal/get-trace.ts
|
|
1516
|
-
function getTrace(error) {
|
|
1517
|
-
const { stack } = error;
|
|
1518
|
-
if (stack) return `\n` + stack.split(`\n`)?.slice(1)?.join(`\n`);
|
|
1519
|
-
return ``;
|
|
1125
|
+
//#region src/internal/get-trace.ts
|
|
1126
|
+
function getTrace(error) {
|
|
1127
|
+
const { stack } = error;
|
|
1128
|
+
if (stack) return `\n` + stack.split(`\n`)?.slice(1)?.join(`\n`);
|
|
1129
|
+
return ``;
|
|
1520
1130
|
}
|
|
1521
1131
|
|
|
1522
1132
|
//#endregion
|
|
@@ -1661,27 +1271,23 @@ function claimWithinStore(store, newProvenance, claim, exclusive) {
|
|
|
1661
1271
|
//#region src/internal/ingest-updates/ingest-creation-disposal.ts
|
|
1662
1272
|
function ingestCreationEvent(update, applying, store) {
|
|
1663
1273
|
switch (applying) {
|
|
1664
|
-
case `newValue`:
|
|
1274
|
+
case `newValue`:
|
|
1665
1275
|
createInStore(update, store);
|
|
1666
1276
|
break;
|
|
1667
|
-
|
|
1668
|
-
case `oldValue`: {
|
|
1277
|
+
case `oldValue`:
|
|
1669
1278
|
disposeFromStore(store, update.token);
|
|
1670
1279
|
break;
|
|
1671
|
-
}
|
|
1672
1280
|
}
|
|
1673
1281
|
}
|
|
1674
1282
|
function ingestDisposalEvent(update, applying, store) {
|
|
1675
1283
|
switch (applying) {
|
|
1676
|
-
case `newValue`:
|
|
1284
|
+
case `newValue`:
|
|
1677
1285
|
disposeFromStore(store, update.token);
|
|
1678
1286
|
break;
|
|
1679
|
-
|
|
1680
|
-
case `oldValue`: {
|
|
1287
|
+
case `oldValue`:
|
|
1681
1288
|
createInStore(update, store);
|
|
1682
1289
|
if (update.subType === `atom`) store.valueMap.set(update.token.key, update.value);
|
|
1683
1290
|
break;
|
|
1684
|
-
}
|
|
1685
1291
|
}
|
|
1686
1292
|
}
|
|
1687
1293
|
function createInStore(update, store) {
|
|
@@ -1830,59 +1436,25 @@ const applyTransaction = (output, store) => {
|
|
|
1830
1436
|
type: `transaction`
|
|
1831
1437
|
});
|
|
1832
1438
|
myTransaction?.subject.next(child.transactionMeta.update);
|
|
1833
|
-
store.logger.info(`🛬`, `transaction`, child.transactionMeta.update.key, `Finished applying transaction.`);
|
|
1834
|
-
} else if (isChildStore(parent)) parent.transactionMeta.update.updates.push(child.transactionMeta.update);
|
|
1835
|
-
parent.on.transactionApplying.next(null);
|
|
1836
|
-
};
|
|
1837
|
-
|
|
1838
|
-
//#endregion
|
|
1839
|
-
//#region src/internal/transaction/assign-transaction-to-continuity.ts
|
|
1840
|
-
function assignTransactionToContinuity(store, continuityKey, transactionKey) {
|
|
1841
|
-
const isRoot = isRootStore(store);
|
|
1842
|
-
if (!isRoot) return;
|
|
1843
|
-
const { epoch, actionContinuities } = store.transactionMeta;
|
|
1844
|
-
actionContinuities.set(continuityKey, transactionKey);
|
|
1845
|
-
if (!epoch.has(continuityKey)) epoch.set(continuityKey, -1);
|
|
1846
|
-
}
|
|
1847
|
-
|
|
1848
|
-
//#endregion
|
|
1849
|
-
//#region src/internal/get-environment-data.ts
|
|
1850
|
-
function getEnvironmentData(store) {
|
|
1851
|
-
return { store };
|
|
1852
|
-
}
|
|
1853
|
-
|
|
1854
|
-
//#endregion
|
|
1855
|
-
//#region src/internal/get-state/get-from-store.ts
|
|
1856
|
-
function getFromStore(store, ...params) {
|
|
1857
|
-
let token;
|
|
1858
|
-
let family;
|
|
1859
|
-
let key;
|
|
1860
|
-
if (params.length === 1) token = params[0];
|
|
1861
|
-
else {
|
|
1862
|
-
family = params[0];
|
|
1863
|
-
key = params[1];
|
|
1864
|
-
token = findInStore(store, family, key);
|
|
1865
|
-
}
|
|
1866
|
-
if (`counterfeit` in token && `family` in token) {
|
|
1867
|
-
family = store.families.get(token.family.key);
|
|
1868
|
-
const subKey = token.family.subKey;
|
|
1869
|
-
const disposal = store.disposalTraces.buffer.find((item) => item?.key === subKey);
|
|
1870
|
-
store.logger.error(`❌`, token.type, token.key, `could not be retrieved because it was not found in the store "${store.config.name}".`, disposal ? `This state was previously disposed:\n${disposal.trace}` : `No previous disposal trace was found.`);
|
|
1871
|
-
switch (family.type) {
|
|
1872
|
-
case `atom_family`:
|
|
1873
|
-
case `mutable_atom_family`: return store.defaults.get(family.key);
|
|
1874
|
-
case `readonly_pure_selector_family`:
|
|
1875
|
-
case `writable_pure_selector_family`:
|
|
1876
|
-
case `readonly_held_selector_family`:
|
|
1877
|
-
case `writable_held_selector_family`: {
|
|
1878
|
-
if (store.defaults.has(family.key)) return store.defaults.get(token.family.key);
|
|
1879
|
-
const defaultValue = withdraw(store, family).default(subKey);
|
|
1880
|
-
store.defaults.set(family.key, defaultValue);
|
|
1881
|
-
return defaultValue;
|
|
1882
|
-
}
|
|
1883
|
-
}
|
|
1884
|
-
}
|
|
1885
|
-
return readOrComputeValue(store, withdraw(store, token));
|
|
1439
|
+
store.logger.info(`🛬`, `transaction`, child.transactionMeta.update.key, `Finished applying transaction.`);
|
|
1440
|
+
} else if (isChildStore(parent)) parent.transactionMeta.update.updates.push(child.transactionMeta.update);
|
|
1441
|
+
parent.on.transactionApplying.next(null);
|
|
1442
|
+
};
|
|
1443
|
+
|
|
1444
|
+
//#endregion
|
|
1445
|
+
//#region src/internal/transaction/assign-transaction-to-continuity.ts
|
|
1446
|
+
function assignTransactionToContinuity(store, continuityKey, transactionKey) {
|
|
1447
|
+
const isRoot = isRootStore(store);
|
|
1448
|
+
if (!isRoot) return;
|
|
1449
|
+
const { epoch, actionContinuities } = store.transactionMeta;
|
|
1450
|
+
actionContinuities.set(continuityKey, transactionKey);
|
|
1451
|
+
if (!epoch.has(continuityKey)) epoch.set(continuityKey, -1);
|
|
1452
|
+
}
|
|
1453
|
+
|
|
1454
|
+
//#endregion
|
|
1455
|
+
//#region src/internal/get-environment-data.ts
|
|
1456
|
+
function getEnvironmentData(store) {
|
|
1457
|
+
return { store };
|
|
1886
1458
|
}
|
|
1887
1459
|
|
|
1888
1460
|
//#endregion
|
|
@@ -1980,264 +1552,604 @@ const buildTransaction = (store, key, params, id) => {
|
|
|
1980
1552
|
}),
|
|
1981
1553
|
env: () => getEnvironmentData(child)
|
|
1982
1554
|
}
|
|
1983
|
-
};
|
|
1984
|
-
const child = Object.assign(childBase, { transactionMeta });
|
|
1985
|
-
parent.child = child;
|
|
1986
|
-
store.logger.info(`🛫`, `transaction`, key, `Building transaction with params:`, params);
|
|
1987
|
-
return child;
|
|
1988
|
-
};
|
|
1555
|
+
};
|
|
1556
|
+
const child = Object.assign(childBase, { transactionMeta });
|
|
1557
|
+
parent.child = child;
|
|
1558
|
+
store.logger.info(`🛫`, `transaction`, key, `Building transaction with params:`, params);
|
|
1559
|
+
return child;
|
|
1560
|
+
};
|
|
1561
|
+
|
|
1562
|
+
//#endregion
|
|
1563
|
+
//#region src/internal/transaction/create-transaction.ts
|
|
1564
|
+
function createTransaction(store, options) {
|
|
1565
|
+
const { key } = options;
|
|
1566
|
+
const transactionAlreadyExists = store.transactions.has(key);
|
|
1567
|
+
const newTransaction = {
|
|
1568
|
+
key,
|
|
1569
|
+
type: `transaction`,
|
|
1570
|
+
run: (params, id) => {
|
|
1571
|
+
const childStore = buildTransaction(store, key, params, id);
|
|
1572
|
+
try {
|
|
1573
|
+
const target$1 = newest(store);
|
|
1574
|
+
const { toolkit } = childStore.transactionMeta;
|
|
1575
|
+
const output = options.do(toolkit, ...params);
|
|
1576
|
+
applyTransaction(output, target$1);
|
|
1577
|
+
return output;
|
|
1578
|
+
} catch (thrown) {
|
|
1579
|
+
abortTransaction(target);
|
|
1580
|
+
store.logger.warn(`💥`, `transaction`, key, `caught:`, thrown);
|
|
1581
|
+
throw thrown;
|
|
1582
|
+
}
|
|
1583
|
+
},
|
|
1584
|
+
install: (s) => createTransaction(s, options),
|
|
1585
|
+
subject: new Subject()
|
|
1586
|
+
};
|
|
1587
|
+
const target = newest(store);
|
|
1588
|
+
target.transactions.set(key, newTransaction);
|
|
1589
|
+
const token = deposit(newTransaction);
|
|
1590
|
+
if (!transactionAlreadyExists) store.on.transactionCreation.next(token);
|
|
1591
|
+
return token;
|
|
1592
|
+
}
|
|
1593
|
+
|
|
1594
|
+
//#endregion
|
|
1595
|
+
//#region src/internal/transaction/index.ts
|
|
1596
|
+
const TRANSACTION_PHASES = [
|
|
1597
|
+
`idle`,
|
|
1598
|
+
`building`,
|
|
1599
|
+
`applying`
|
|
1600
|
+
];
|
|
1601
|
+
|
|
1602
|
+
//#endregion
|
|
1603
|
+
//#region src/internal/selector/create-writable-held-selector.ts
|
|
1604
|
+
const createWritableHeldSelector = (store, options, family) => {
|
|
1605
|
+
const target = newest(store);
|
|
1606
|
+
const subject = new Subject();
|
|
1607
|
+
const covered = /* @__PURE__ */ new Set();
|
|
1608
|
+
const { key, const: constant } = options;
|
|
1609
|
+
const type = `writable_held_selector`;
|
|
1610
|
+
const setterToolkit = registerSelector(target, type, key, covered);
|
|
1611
|
+
const { find, get, json } = setterToolkit;
|
|
1612
|
+
const getterToolkit = {
|
|
1613
|
+
find,
|
|
1614
|
+
get,
|
|
1615
|
+
json
|
|
1616
|
+
};
|
|
1617
|
+
const getSelf = (getFn = options.get, innerTarget = newest(store)) => {
|
|
1618
|
+
const upstreamStates = innerTarget.selectorGraph.getRelationEntries({ downstreamSelectorKey: key });
|
|
1619
|
+
for (const [downstreamSelectorKey, { source }] of upstreamStates) if (source !== key) innerTarget.selectorGraph.delete(downstreamSelectorKey, key);
|
|
1620
|
+
innerTarget.selectorAtoms.delete(key);
|
|
1621
|
+
getFn(getterToolkit, constant);
|
|
1622
|
+
cacheValue(innerTarget, key, constant, subject);
|
|
1623
|
+
store.logger.info(`✨`, type, key, `=`, constant);
|
|
1624
|
+
covered.clear();
|
|
1625
|
+
return constant;
|
|
1626
|
+
};
|
|
1627
|
+
const setSelf = (next) => {
|
|
1628
|
+
const innerTarget = newest(store);
|
|
1629
|
+
const oldValue = getSelf(options.get, innerTarget);
|
|
1630
|
+
const newValue = become(next)(oldValue);
|
|
1631
|
+
store.logger.info(`📝`, type, key, `set (`, oldValue, `->`, newValue, `)`);
|
|
1632
|
+
cacheValue(innerTarget, key, newValue, subject);
|
|
1633
|
+
markDone(innerTarget, key);
|
|
1634
|
+
if (isRootStore(innerTarget)) subject.next({
|
|
1635
|
+
newValue,
|
|
1636
|
+
oldValue
|
|
1637
|
+
});
|
|
1638
|
+
options.set(setterToolkit, newValue);
|
|
1639
|
+
};
|
|
1640
|
+
const mySelector = {
|
|
1641
|
+
...options,
|
|
1642
|
+
type,
|
|
1643
|
+
subject,
|
|
1644
|
+
install: (s) => createWritableHeldSelector(s, options, family),
|
|
1645
|
+
get: getSelf,
|
|
1646
|
+
set: setSelf,
|
|
1647
|
+
...family && { family }
|
|
1648
|
+
};
|
|
1649
|
+
target.writableSelectors.set(key, mySelector);
|
|
1650
|
+
const token = {
|
|
1651
|
+
key,
|
|
1652
|
+
type
|
|
1653
|
+
};
|
|
1654
|
+
if (family) token.family = family;
|
|
1655
|
+
return token;
|
|
1656
|
+
};
|
|
1657
|
+
|
|
1658
|
+
//#endregion
|
|
1659
|
+
//#region src/internal/selector/create-writable-pure-selector.ts
|
|
1660
|
+
const createWritablePureSelector = (store, options, family) => {
|
|
1661
|
+
const target = newest(store);
|
|
1662
|
+
const subject = new Subject();
|
|
1663
|
+
const covered = /* @__PURE__ */ new Set();
|
|
1664
|
+
const key = options.key;
|
|
1665
|
+
const type = `writable_pure_selector`;
|
|
1666
|
+
const setterToolkit = registerSelector(target, type, key, covered);
|
|
1667
|
+
const { find, get, json } = setterToolkit;
|
|
1668
|
+
const getterToolkit = {
|
|
1669
|
+
find,
|
|
1670
|
+
get,
|
|
1671
|
+
json
|
|
1672
|
+
};
|
|
1673
|
+
const getSelf = (getFn = options.get, innerTarget = newest(store)) => {
|
|
1674
|
+
const upstreamStates = innerTarget.selectorGraph.getRelationEntries({ downstreamSelectorKey: key });
|
|
1675
|
+
for (const [downstreamSelectorKey, { source }] of upstreamStates) if (source !== key) innerTarget.selectorGraph.delete(downstreamSelectorKey, key);
|
|
1676
|
+
innerTarget.selectorAtoms.delete(key);
|
|
1677
|
+
const value = getFn(getterToolkit);
|
|
1678
|
+
const cached = cacheValue(innerTarget, key, value, subject);
|
|
1679
|
+
store.logger.info(`✨`, type, key, `=`, cached);
|
|
1680
|
+
covered.clear();
|
|
1681
|
+
return value;
|
|
1682
|
+
};
|
|
1683
|
+
const setSelf = (next) => {
|
|
1684
|
+
const innerTarget = newest(store);
|
|
1685
|
+
const oldValue = getSelf(options.get, innerTarget);
|
|
1686
|
+
const newValue = become(next)(oldValue);
|
|
1687
|
+
store.logger.info(`📝`, type, key, `set (`, oldValue, `->`, newValue, `)`);
|
|
1688
|
+
cacheValue(innerTarget, options.key, newValue, subject);
|
|
1689
|
+
markDone(innerTarget, options.key);
|
|
1690
|
+
if (isRootStore(innerTarget)) subject.next({
|
|
1691
|
+
newValue,
|
|
1692
|
+
oldValue
|
|
1693
|
+
});
|
|
1694
|
+
options.set(setterToolkit, newValue);
|
|
1695
|
+
};
|
|
1696
|
+
const mySelector = {
|
|
1697
|
+
...options,
|
|
1698
|
+
type,
|
|
1699
|
+
subject,
|
|
1700
|
+
install: (s) => createWritablePureSelector(s, options, family),
|
|
1701
|
+
get: getSelf,
|
|
1702
|
+
set: setSelf,
|
|
1703
|
+
...family && { family }
|
|
1704
|
+
};
|
|
1705
|
+
target.writableSelectors.set(key, mySelector);
|
|
1706
|
+
const initialValue = getSelf();
|
|
1707
|
+
store.logger.info(`✨`, mySelector.type, mySelector.key, `=`, initialValue);
|
|
1708
|
+
const token = {
|
|
1709
|
+
key,
|
|
1710
|
+
type
|
|
1711
|
+
};
|
|
1712
|
+
if (family) token.family = family;
|
|
1713
|
+
return token;
|
|
1714
|
+
};
|
|
1715
|
+
|
|
1716
|
+
//#endregion
|
|
1717
|
+
//#region src/internal/selector/create-standalone-selector.ts
|
|
1718
|
+
function createStandaloneSelector(store, options) {
|
|
1719
|
+
const isWritable = `set` in options;
|
|
1720
|
+
const isHeld = `const` in options;
|
|
1721
|
+
if (isHeld && isWritable) {
|
|
1722
|
+
const state$1 = createWritableHeldSelector(store, options, void 0);
|
|
1723
|
+
store.on.selectorCreation.next(state$1);
|
|
1724
|
+
return state$1;
|
|
1725
|
+
}
|
|
1726
|
+
if (isHeld) {
|
|
1727
|
+
const state$1 = createReadonlyHeldSelector(store, options, void 0);
|
|
1728
|
+
store.on.selectorCreation.next(state$1);
|
|
1729
|
+
return state$1;
|
|
1730
|
+
}
|
|
1731
|
+
if (isWritable) {
|
|
1732
|
+
const state$1 = createWritablePureSelector(store, options, void 0);
|
|
1733
|
+
store.on.selectorCreation.next(state$1);
|
|
1734
|
+
return state$1;
|
|
1735
|
+
}
|
|
1736
|
+
const state = createReadonlyPureSelector(store, options, void 0);
|
|
1737
|
+
store.on.selectorCreation.next(state);
|
|
1738
|
+
return state;
|
|
1739
|
+
}
|
|
1740
|
+
|
|
1741
|
+
//#endregion
|
|
1742
|
+
//#region src/internal/selector/dispose-selector.ts
|
|
1743
|
+
function disposeSelector(store, selectorToken) {
|
|
1744
|
+
const target = newest(store);
|
|
1745
|
+
const { key, type } = selectorToken;
|
|
1746
|
+
const selector = withdraw(target, selectorToken);
|
|
1747
|
+
if (!selector.family) store.logger.error(`❌`, type, key, `Standalone selectors cannot be disposed.`);
|
|
1748
|
+
else {
|
|
1749
|
+
const molecule = target.molecules.get(selector.family.subKey);
|
|
1750
|
+
if (molecule) target.moleculeData.delete(selector.family.subKey, selector.family.key);
|
|
1751
|
+
let familyToken;
|
|
1752
|
+
switch (selectorToken.type) {
|
|
1753
|
+
case `writable_held_selector`:
|
|
1754
|
+
{
|
|
1755
|
+
target.writableSelectors.delete(key);
|
|
1756
|
+
familyToken = {
|
|
1757
|
+
key: selector.family.key,
|
|
1758
|
+
type: `writable_held_selector_family`
|
|
1759
|
+
};
|
|
1760
|
+
const family = withdraw(store, familyToken);
|
|
1761
|
+
family.subject.next({
|
|
1762
|
+
type: `state_disposal`,
|
|
1763
|
+
subType: `selector`,
|
|
1764
|
+
token: selectorToken
|
|
1765
|
+
});
|
|
1766
|
+
}
|
|
1767
|
+
break;
|
|
1768
|
+
case `writable_pure_selector`:
|
|
1769
|
+
{
|
|
1770
|
+
target.writableSelectors.delete(key);
|
|
1771
|
+
familyToken = {
|
|
1772
|
+
key: selector.family.key,
|
|
1773
|
+
type: `writable_pure_selector_family`
|
|
1774
|
+
};
|
|
1775
|
+
const family = withdraw(store, familyToken);
|
|
1776
|
+
family.subject.next({
|
|
1777
|
+
type: `state_disposal`,
|
|
1778
|
+
subType: `selector`,
|
|
1779
|
+
token: selectorToken
|
|
1780
|
+
});
|
|
1781
|
+
}
|
|
1782
|
+
break;
|
|
1783
|
+
case `readonly_held_selector`:
|
|
1784
|
+
{
|
|
1785
|
+
target.readonlySelectors.delete(key);
|
|
1786
|
+
familyToken = {
|
|
1787
|
+
key: selector.family.key,
|
|
1788
|
+
type: `readonly_held_selector_family`
|
|
1789
|
+
};
|
|
1790
|
+
const family = withdraw(store, familyToken);
|
|
1791
|
+
family.subject.next({
|
|
1792
|
+
type: `state_disposal`,
|
|
1793
|
+
subType: `selector`,
|
|
1794
|
+
token: selectorToken
|
|
1795
|
+
});
|
|
1796
|
+
}
|
|
1797
|
+
break;
|
|
1798
|
+
case `readonly_pure_selector`:
|
|
1799
|
+
{
|
|
1800
|
+
target.readonlySelectors.delete(key);
|
|
1801
|
+
familyToken = {
|
|
1802
|
+
key: selector.family.key,
|
|
1803
|
+
type: `readonly_pure_selector_family`
|
|
1804
|
+
};
|
|
1805
|
+
const family = withdraw(store, familyToken);
|
|
1806
|
+
family.subject.next({
|
|
1807
|
+
type: `state_disposal`,
|
|
1808
|
+
subType: `selector`,
|
|
1809
|
+
token: selectorToken
|
|
1810
|
+
});
|
|
1811
|
+
}
|
|
1812
|
+
break;
|
|
1813
|
+
}
|
|
1814
|
+
target.valueMap.delete(key);
|
|
1815
|
+
target.selectorAtoms.delete(key);
|
|
1816
|
+
target.selectorGraph.delete(key);
|
|
1817
|
+
store.logger.info(`🔥`, selectorToken.type, key, `deleted`);
|
|
1818
|
+
if (isChildStore(target) && target.transactionMeta.phase === `building`) target.transactionMeta.update.updates.push({
|
|
1819
|
+
type: `state_disposal`,
|
|
1820
|
+
subType: `selector`,
|
|
1821
|
+
token: selectorToken
|
|
1822
|
+
});
|
|
1823
|
+
else store.on.selectorDisposal.next(selectorToken);
|
|
1824
|
+
}
|
|
1825
|
+
}
|
|
1989
1826
|
|
|
1990
1827
|
//#endregion
|
|
1991
|
-
//#region src/internal/
|
|
1992
|
-
function
|
|
1993
|
-
const
|
|
1994
|
-
const
|
|
1995
|
-
const
|
|
1996
|
-
key,
|
|
1997
|
-
type
|
|
1998
|
-
run: (params, id) => {
|
|
1999
|
-
const childStore = buildTransaction(store, key, params, id);
|
|
2000
|
-
try {
|
|
2001
|
-
const target$1 = newest(store);
|
|
2002
|
-
const { toolkit } = childStore.transactionMeta;
|
|
2003
|
-
const output = options.do(toolkit, ...params);
|
|
2004
|
-
applyTransaction(output, target$1);
|
|
2005
|
-
return output;
|
|
2006
|
-
} catch (thrown) {
|
|
2007
|
-
abortTransaction(target);
|
|
2008
|
-
store.logger.warn(`💥`, `transaction`, key, `caught:`, thrown);
|
|
2009
|
-
throw thrown;
|
|
2010
|
-
}
|
|
2011
|
-
},
|
|
2012
|
-
install: (s) => createTransaction(s, options),
|
|
2013
|
-
subject: new Subject()
|
|
1828
|
+
//#region src/internal/families/create-readonly-pure-selector-family.ts
|
|
1829
|
+
function createReadonlyPureSelectorFamily(store, options, internalRoles) {
|
|
1830
|
+
const familyKey = options.key;
|
|
1831
|
+
const type = `readonly_pure_selector_family`;
|
|
1832
|
+
const familyToken = {
|
|
1833
|
+
key: familyKey,
|
|
1834
|
+
type
|
|
2014
1835
|
};
|
|
2015
|
-
const
|
|
2016
|
-
|
|
2017
|
-
const
|
|
2018
|
-
|
|
2019
|
-
|
|
1836
|
+
const existing = store.families.get(familyKey);
|
|
1837
|
+
if (existing) store.logger.error(`❗`, type, familyKey, `Overwriting an existing ${prettyPrintTokenType(existing)} "${existing.key}" in store "${store.config.name}". You can safely ignore this warning if it is due to hot module replacement.`);
|
|
1838
|
+
const subject = new Subject();
|
|
1839
|
+
const familyFunction = (key) => {
|
|
1840
|
+
const subKey = stringifyJson(key);
|
|
1841
|
+
const family = {
|
|
1842
|
+
key: familyKey,
|
|
1843
|
+
subKey
|
|
1844
|
+
};
|
|
1845
|
+
const fullKey = `${familyKey}(${subKey})`;
|
|
1846
|
+
const target = newest(store);
|
|
1847
|
+
const token = createReadonlyPureSelector(target, {
|
|
1848
|
+
key: fullKey,
|
|
1849
|
+
get: options.get(key)
|
|
1850
|
+
}, family);
|
|
1851
|
+
subject.next({
|
|
1852
|
+
type: `state_creation`,
|
|
1853
|
+
token
|
|
1854
|
+
});
|
|
1855
|
+
return token;
|
|
1856
|
+
};
|
|
1857
|
+
const readonlySelectorFamily = Object.assign(familyFunction, familyToken, {
|
|
1858
|
+
internalRoles,
|
|
1859
|
+
subject,
|
|
1860
|
+
install: (s) => createReadonlyPureSelectorFamily(s, options),
|
|
1861
|
+
default: (key) => {
|
|
1862
|
+
const getFn = options.get(key);
|
|
1863
|
+
return getFn({
|
|
1864
|
+
get: ((...args) => getFromStore(store, ...args)),
|
|
1865
|
+
find: ((...args) => findInStore(store, ...args)),
|
|
1866
|
+
json: (token) => getJsonToken(store, token)
|
|
1867
|
+
});
|
|
1868
|
+
}
|
|
1869
|
+
});
|
|
1870
|
+
store.families.set(familyKey, readonlySelectorFamily);
|
|
1871
|
+
return familyToken;
|
|
2020
1872
|
}
|
|
2021
1873
|
|
|
2022
1874
|
//#endregion
|
|
2023
|
-
//#region src/internal/
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
`
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
//#endregion
|
|
2031
|
-
//#region src/internal/store/store.ts
|
|
2032
|
-
var Store = class {
|
|
2033
|
-
parent = null;
|
|
2034
|
-
child = null;
|
|
2035
|
-
valueMap = /* @__PURE__ */ new Map();
|
|
2036
|
-
defaults = /* @__PURE__ */ new Map();
|
|
2037
|
-
atoms = /* @__PURE__ */ new Map();
|
|
2038
|
-
writableSelectors = /* @__PURE__ */ new Map();
|
|
2039
|
-
readonlySelectors = /* @__PURE__ */ new Map();
|
|
2040
|
-
atomsThatAreDefault = /* @__PURE__ */ new Set();
|
|
2041
|
-
selectorAtoms = new Junction({
|
|
2042
|
-
between: [`selectorKey`, `atomKey`],
|
|
2043
|
-
cardinality: `n:n`
|
|
2044
|
-
});
|
|
2045
|
-
selectorGraph = new Junction({
|
|
2046
|
-
between: [`upstreamSelectorKey`, `downstreamSelectorKey`],
|
|
2047
|
-
cardinality: `n:n`
|
|
2048
|
-
}, { makeContentKey: (...keys) => keys.sort().join(`:`) });
|
|
2049
|
-
trackers = /* @__PURE__ */ new Map();
|
|
2050
|
-
families = /* @__PURE__ */ new Map();
|
|
2051
|
-
joins = /* @__PURE__ */ new Map();
|
|
2052
|
-
transactions = /* @__PURE__ */ new Map();
|
|
2053
|
-
transactionMeta = {
|
|
2054
|
-
epoch: /* @__PURE__ */ new Map(),
|
|
2055
|
-
actionContinuities: new Junction({
|
|
2056
|
-
between: [`continuity`, `action`],
|
|
2057
|
-
cardinality: `1:n`
|
|
2058
|
-
})
|
|
1875
|
+
//#region src/internal/families/create-readonly-held-selector-family.ts
|
|
1876
|
+
function createReadonlyHeldSelectorFamily(store, options, internalRoles) {
|
|
1877
|
+
const familyKey = options.key;
|
|
1878
|
+
const type = `readonly_held_selector_family`;
|
|
1879
|
+
const familyToken = {
|
|
1880
|
+
key: familyKey,
|
|
1881
|
+
type
|
|
2059
1882
|
};
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
1883
|
+
const existing = store.families.get(familyKey);
|
|
1884
|
+
if (existing) store.logger.error(`❗`, type, familyKey, `Overwriting an existing ${prettyPrintTokenType(existing)} "${existing.key}" in store "${store.config.name}". You can safely ignore this warning if it is due to hot module replacement.`);
|
|
1885
|
+
const subject = new Subject();
|
|
1886
|
+
const familyFunction = (key) => {
|
|
1887
|
+
const subKey = stringifyJson(key);
|
|
1888
|
+
const family = {
|
|
1889
|
+
key: familyKey,
|
|
1890
|
+
subKey
|
|
1891
|
+
};
|
|
1892
|
+
const fullKey = `${familyKey}(${subKey})`;
|
|
1893
|
+
const target = newest(store);
|
|
1894
|
+
const token = createReadonlyHeldSelector(target, {
|
|
1895
|
+
key: fullKey,
|
|
1896
|
+
const: options.const(key),
|
|
1897
|
+
get: options.get(key)
|
|
1898
|
+
}, family);
|
|
1899
|
+
subject.next({
|
|
1900
|
+
type: `state_creation`,
|
|
1901
|
+
token
|
|
1902
|
+
});
|
|
1903
|
+
return token;
|
|
1904
|
+
};
|
|
1905
|
+
const readonlySelectorFamily = Object.assign(familyFunction, familyToken, {
|
|
1906
|
+
internalRoles,
|
|
1907
|
+
subject,
|
|
1908
|
+
install: (s) => createReadonlyHeldSelectorFamily(s, options),
|
|
1909
|
+
default: options.const
|
|
2064
1910
|
});
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
cardinality: `n:n`
|
|
2078
|
-
}, { makeContentKey: (...keys) => keys.sort().join(`:`) });
|
|
2079
|
-
miscResources = /* @__PURE__ */ new Map();
|
|
2080
|
-
on = {
|
|
2081
|
-
atomCreation: new Subject(),
|
|
2082
|
-
atomDisposal: new Subject(),
|
|
2083
|
-
selectorCreation: new Subject(),
|
|
2084
|
-
selectorDisposal: new Subject(),
|
|
2085
|
-
timelineCreation: new Subject(),
|
|
2086
|
-
transactionCreation: new Subject(),
|
|
2087
|
-
transactionApplying: new StatefulSubject(null),
|
|
2088
|
-
operationClose: new Subject(),
|
|
2089
|
-
moleculeCreation: new Subject(),
|
|
2090
|
-
moleculeDisposal: new Subject()
|
|
1911
|
+
store.families.set(familyKey, readonlySelectorFamily);
|
|
1912
|
+
return familyToken;
|
|
1913
|
+
}
|
|
1914
|
+
|
|
1915
|
+
//#endregion
|
|
1916
|
+
//#region src/internal/families/create-writable-held-selector-family.ts
|
|
1917
|
+
function createWritableHeldSelectorFamily(store, options, internalRoles) {
|
|
1918
|
+
const familyKey = options.key;
|
|
1919
|
+
const type = `writable_held_selector_family`;
|
|
1920
|
+
const familyToken = {
|
|
1921
|
+
key: familyKey,
|
|
1922
|
+
type
|
|
2091
1923
|
};
|
|
2092
|
-
|
|
2093
|
-
config
|
|
2094
|
-
|
|
2095
|
-
|
|
1924
|
+
const existing = store.families.get(familyKey);
|
|
1925
|
+
if (existing) store.logger.error(`❗`, type, familyKey, `Overwriting an existing ${prettyPrintTokenType(existing)} "${existing.key}" in store "${store.config.name}". You can safely ignore this warning if it is due to hot module replacement.`);
|
|
1926
|
+
const subject = new Subject();
|
|
1927
|
+
const familyFunction = (key) => {
|
|
1928
|
+
const subKey = stringifyJson(key);
|
|
1929
|
+
const family = {
|
|
1930
|
+
key: familyKey,
|
|
1931
|
+
subKey
|
|
1932
|
+
};
|
|
1933
|
+
const fullKey = `${familyKey}(${subKey})`;
|
|
1934
|
+
const target = newest(store);
|
|
1935
|
+
const token = createWritableHeldSelector(target, {
|
|
1936
|
+
key: fullKey,
|
|
1937
|
+
const: options.const(key),
|
|
1938
|
+
get: options.get(key),
|
|
1939
|
+
set: options.set(key)
|
|
1940
|
+
}, family);
|
|
1941
|
+
subject.next({
|
|
1942
|
+
type: `state_creation`,
|
|
1943
|
+
token
|
|
1944
|
+
});
|
|
1945
|
+
return token;
|
|
2096
1946
|
};
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
1947
|
+
const selectorFamily$1 = Object.assign(familyFunction, familyToken, {
|
|
1948
|
+
internalRoles,
|
|
1949
|
+
subject,
|
|
1950
|
+
install: (s) => createWritableHeldSelectorFamily(s, options),
|
|
1951
|
+
default: options.const
|
|
1952
|
+
});
|
|
1953
|
+
store.families.set(familyKey, selectorFamily$1);
|
|
1954
|
+
return familyToken;
|
|
1955
|
+
}
|
|
1956
|
+
|
|
1957
|
+
//#endregion
|
|
1958
|
+
//#region src/internal/families/create-writable-pure-selector-family.ts
|
|
1959
|
+
function createWritablePureSelectorFamily(store, options, internalRoles) {
|
|
1960
|
+
const familyKey = options.key;
|
|
1961
|
+
const type = `writable_pure_selector_family`;
|
|
1962
|
+
const familyToken = {
|
|
1963
|
+
key: familyKey,
|
|
1964
|
+
type
|
|
2108
1965
|
};
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
1966
|
+
const existing = store.families.get(familyKey);
|
|
1967
|
+
if (existing) store.logger.error(`❗`, type, familyKey, `Overwriting an existing ${prettyPrintTokenType(existing)} "${existing.key}" in store "${store.config.name}". You can safely ignore this warning if it is due to hot module replacement.`);
|
|
1968
|
+
const subject = new Subject();
|
|
1969
|
+
const familyFunction = (key) => {
|
|
1970
|
+
const subKey = stringifyJson(key);
|
|
1971
|
+
const family = {
|
|
1972
|
+
key: familyKey,
|
|
1973
|
+
subKey
|
|
2113
1974
|
};
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
if (mutableHelpers.has(selector.key)) continue;
|
|
2139
|
-
selector.install(this);
|
|
2140
|
-
}
|
|
2141
|
-
for (const [, tx] of store.transactions) tx.install(this);
|
|
2142
|
-
for (const [, timeline] of store.timelines) timeline.install(this);
|
|
1975
|
+
const fullKey = `${familyKey}(${subKey})`;
|
|
1976
|
+
const target = newest(store);
|
|
1977
|
+
const token = createWritablePureSelector(target, {
|
|
1978
|
+
key: fullKey,
|
|
1979
|
+
get: options.get(key),
|
|
1980
|
+
set: options.set(key)
|
|
1981
|
+
}, family);
|
|
1982
|
+
subject.next({
|
|
1983
|
+
type: `state_creation`,
|
|
1984
|
+
token
|
|
1985
|
+
});
|
|
1986
|
+
return token;
|
|
1987
|
+
};
|
|
1988
|
+
const selectorFamily$1 = Object.assign(familyFunction, familyToken, {
|
|
1989
|
+
internalRoles,
|
|
1990
|
+
subject,
|
|
1991
|
+
install: (s) => createWritablePureSelectorFamily(s, options),
|
|
1992
|
+
default: (key) => {
|
|
1993
|
+
const getFn = options.get(key);
|
|
1994
|
+
return getFn({
|
|
1995
|
+
get: ((...args) => getFromStore(store, ...args)),
|
|
1996
|
+
find: ((...args) => findInStore(store, ...args)),
|
|
1997
|
+
json: (token) => getJsonToken(store, token)
|
|
1998
|
+
});
|
|
2143
1999
|
}
|
|
2144
|
-
}
|
|
2145
|
-
};
|
|
2146
|
-
const IMPLICIT = { get STORE() {
|
|
2147
|
-
globalThis.ATOM_IO_IMPLICIT_STORE ??= new Store({
|
|
2148
|
-
name: `IMPLICIT_STORE`,
|
|
2149
|
-
lifespan: `ephemeral`
|
|
2150
2000
|
});
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
const { config } = store;
|
|
2155
|
-
for (const disposable of store.miscResources.values()) disposable[Symbol.dispose]();
|
|
2156
|
-
Object.assign(store, new Store(config));
|
|
2157
|
-
store.config = config;
|
|
2158
|
-
};
|
|
2001
|
+
store.families.set(familyKey, selectorFamily$1);
|
|
2002
|
+
return familyToken;
|
|
2003
|
+
}
|
|
2159
2004
|
|
|
2160
2005
|
//#endregion
|
|
2161
|
-
//#region src/internal/
|
|
2162
|
-
function
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2006
|
+
//#region src/internal/families/create-selector-family.ts
|
|
2007
|
+
function createSelectorFamily(store, options) {
|
|
2008
|
+
const isWritable = `set` in options;
|
|
2009
|
+
const isHeld = `const` in options;
|
|
2010
|
+
if (isHeld && isWritable) return createWritableHeldSelectorFamily(store, options, void 0);
|
|
2011
|
+
if (isHeld) return createReadonlyHeldSelectorFamily(store, options, void 0);
|
|
2012
|
+
if (isWritable) return createWritablePureSelectorFamily(store, options);
|
|
2013
|
+
return createReadonlyPureSelectorFamily(store, options);
|
|
2014
|
+
}
|
|
2015
|
+
|
|
2016
|
+
//#endregion
|
|
2017
|
+
//#region src/internal/families/init-family-member.ts
|
|
2018
|
+
function initFamilyMemberInStore(store, token, key) {
|
|
2019
|
+
const family = store.families.get(token.key);
|
|
2020
|
+
if (family === void 0) throw new NotFoundError(token, store);
|
|
2021
|
+
const state = family(key);
|
|
2022
|
+
const target = newest(store);
|
|
2023
|
+
if (state.family) {
|
|
2024
|
+
if (isRootStore(target)) switch (state.type) {
|
|
2167
2025
|
case `atom`:
|
|
2168
2026
|
case `mutable_atom`:
|
|
2169
|
-
|
|
2027
|
+
store.on.atomCreation.next(state);
|
|
2170
2028
|
break;
|
|
2171
2029
|
case `writable_pure_selector`:
|
|
2172
|
-
case `writable_held_selector`:
|
|
2173
|
-
withdrawn = target.writableSelectors.get(token.key);
|
|
2174
|
-
break;
|
|
2175
2030
|
case `readonly_pure_selector`:
|
|
2031
|
+
case `writable_held_selector`:
|
|
2176
2032
|
case `readonly_held_selector`:
|
|
2177
|
-
|
|
2178
|
-
break;
|
|
2179
|
-
case `atom_family`:
|
|
2180
|
-
case `mutable_atom_family`:
|
|
2181
|
-
case `writable_pure_selector_family`:
|
|
2182
|
-
case `readonly_pure_selector_family`:
|
|
2183
|
-
case `writable_held_selector_family`:
|
|
2184
|
-
case `readonly_held_selector_family`:
|
|
2185
|
-
withdrawn = target.families.get(token.key);
|
|
2186
|
-
break;
|
|
2187
|
-
case `timeline`:
|
|
2188
|
-
withdrawn = target.timelines.get(token.key);
|
|
2189
|
-
break;
|
|
2190
|
-
case `transaction`:
|
|
2191
|
-
withdrawn = target.transactions.get(token.key);
|
|
2033
|
+
store.on.selectorCreation.next(state);
|
|
2192
2034
|
break;
|
|
2193
2035
|
}
|
|
2194
|
-
if (
|
|
2195
|
-
|
|
2036
|
+
else if (isChildStore(target) && target.on.transactionApplying.state === null) target.transactionMeta.update.updates.push({
|
|
2037
|
+
type: `state_creation`,
|
|
2038
|
+
token: state
|
|
2039
|
+
});
|
|
2196
2040
|
}
|
|
2197
|
-
|
|
2041
|
+
return state;
|
|
2198
2042
|
}
|
|
2199
2043
|
|
|
2200
2044
|
//#endregion
|
|
2201
|
-
//#region src/internal/
|
|
2202
|
-
|
|
2045
|
+
//#region src/internal/families/seek-in-store.ts
|
|
2046
|
+
function seekInStore(store, token, key) {
|
|
2047
|
+
const subKey = stringifyJson(key);
|
|
2048
|
+
const fullKey = `${token.key}(${subKey})`;
|
|
2203
2049
|
const target = newest(store);
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
|
|
2050
|
+
let state;
|
|
2051
|
+
switch (token.type) {
|
|
2052
|
+
case `atom_family`:
|
|
2053
|
+
case `mutable_atom_family`:
|
|
2054
|
+
state = target.atoms.get(fullKey);
|
|
2055
|
+
break;
|
|
2056
|
+
case `writable_held_selector_family`:
|
|
2057
|
+
case `writable_pure_selector_family`:
|
|
2058
|
+
state = target.writableSelectors.get(fullKey);
|
|
2059
|
+
break;
|
|
2060
|
+
case `readonly_held_selector_family`:
|
|
2061
|
+
case `readonly_pure_selector_family`:
|
|
2062
|
+
state = target.readonlySelectors.get(fullKey);
|
|
2063
|
+
break;
|
|
2064
|
+
}
|
|
2065
|
+
if (state) return deposit(state);
|
|
2066
|
+
return state;
|
|
2067
|
+
}
|
|
2207
2068
|
|
|
2208
2069
|
//#endregion
|
|
2209
|
-
//#region src/internal/
|
|
2210
|
-
function
|
|
2070
|
+
//#region src/internal/families/find-in-store.ts
|
|
2071
|
+
function findInStore(store, token, key) {
|
|
2072
|
+
let state = seekInStore(store, token, key);
|
|
2073
|
+
if (state) return state;
|
|
2074
|
+
const stringKey = stringifyJson(key);
|
|
2075
|
+
const molecule = store.molecules.get(stringKey);
|
|
2076
|
+
if (!molecule && store.config.lifespan === `immortal`) {
|
|
2077
|
+
const fakeToken = counterfeit(token, key);
|
|
2078
|
+
store.logger.error(`❌`, fakeToken.type, fakeToken.key, `was not found in store "${store.config.name}"; returned a counterfeit token.`);
|
|
2079
|
+
return fakeToken;
|
|
2080
|
+
}
|
|
2081
|
+
state = initFamilyMemberInStore(store, token, key);
|
|
2082
|
+
if (molecule) {
|
|
2083
|
+
const target = newest(store);
|
|
2084
|
+
target.moleculeData.set(stringKey, token.key);
|
|
2085
|
+
}
|
|
2086
|
+
return state;
|
|
2087
|
+
}
|
|
2088
|
+
|
|
2089
|
+
//#endregion
|
|
2090
|
+
//#region src/internal/families/dispose-from-store.ts
|
|
2091
|
+
function disposeFromStore(store, ...params) {
|
|
2092
|
+
let token;
|
|
2093
|
+
if (params.length === 1) token = params[0];
|
|
2094
|
+
else {
|
|
2095
|
+
const family = params[0];
|
|
2096
|
+
const key = params[1];
|
|
2097
|
+
const maybeToken = findInStore(store, family, key);
|
|
2098
|
+
token = maybeToken;
|
|
2099
|
+
}
|
|
2100
|
+
try {
|
|
2101
|
+
withdraw(store, token);
|
|
2102
|
+
} catch (_) {
|
|
2103
|
+
store.logger.error(`❌`, token.type, token.key, `could not be disposed because it was not found in the store "${store.config.name}".`);
|
|
2104
|
+
return;
|
|
2105
|
+
}
|
|
2211
2106
|
switch (token.type) {
|
|
2212
2107
|
case `atom`:
|
|
2213
2108
|
case `mutable_atom`:
|
|
2109
|
+
disposeAtom(store, token);
|
|
2110
|
+
break;
|
|
2111
|
+
case `writable_pure_selector`:
|
|
2214
2112
|
case `readonly_pure_selector`:
|
|
2113
|
+
case `writable_held_selector`:
|
|
2215
2114
|
case `readonly_held_selector`:
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
case `transaction`: return subscribeToTransaction$1(store, token, key, handleUpdate);
|
|
2219
|
-
case `timeline`: return subscribeToTimeline$1(store, token, key, handleUpdate);
|
|
2115
|
+
disposeSelector(store, token);
|
|
2116
|
+
break;
|
|
2220
2117
|
}
|
|
2221
2118
|
}
|
|
2222
2119
|
|
|
2223
2120
|
//#endregion
|
|
2224
|
-
//#region src/internal/
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2121
|
+
//#region src/internal/get-state/get-from-store.ts
|
|
2122
|
+
function getFromStore(store, ...params) {
|
|
2123
|
+
let token;
|
|
2124
|
+
let family;
|
|
2125
|
+
let key;
|
|
2126
|
+
if (params.length === 1) token = params[0];
|
|
2127
|
+
else {
|
|
2128
|
+
family = params[0];
|
|
2129
|
+
key = params[1];
|
|
2130
|
+
token = findInStore(store, family, key);
|
|
2131
|
+
}
|
|
2132
|
+
if (`counterfeit` in token && `family` in token) {
|
|
2133
|
+
family = store.families.get(token.family.key);
|
|
2134
|
+
const subKey = token.family.subKey;
|
|
2135
|
+
const disposal = store.disposalTraces.buffer.find((item) => item?.key === subKey);
|
|
2136
|
+
store.logger.error(`❌`, token.type, token.key, `could not be retrieved because it was not found in the store "${store.config.name}".`, disposal ? `This state was previously disposed:\n${disposal.trace}` : `No previous disposal trace was found.`);
|
|
2137
|
+
switch (family.type) {
|
|
2138
|
+
case `atom_family`:
|
|
2139
|
+
case `mutable_atom_family`: return store.defaults.get(family.key);
|
|
2140
|
+
case `readonly_pure_selector_family`:
|
|
2141
|
+
case `writable_pure_selector_family`:
|
|
2142
|
+
case `readonly_held_selector_family`:
|
|
2143
|
+
case `writable_held_selector_family`: {
|
|
2144
|
+
if (store.defaults.has(family.key)) return store.defaults.get(token.family.key);
|
|
2145
|
+
const defaultValue = withdraw(store, family).default(subKey);
|
|
2146
|
+
store.defaults.set(family.key, defaultValue);
|
|
2147
|
+
return defaultValue;
|
|
2148
|
+
}
|
|
2149
|
+
}
|
|
2150
|
+
}
|
|
2151
|
+
return readOrComputeValue(store, withdraw(store, token));
|
|
2152
|
+
}
|
|
2241
2153
|
|
|
2242
2154
|
//#endregion
|
|
2243
2155
|
//#region src/internal/subscribe/subscribe-to-state.ts
|
|
@@ -2253,15 +2165,22 @@ function subscribeToState(store, token, key, handleUpdate) {
|
|
|
2253
2165
|
const state = withdraw(store, token);
|
|
2254
2166
|
store.logger.info(`👀`, state.type, state.key, `Adding subscription "${key}"`);
|
|
2255
2167
|
const isSelector = state.type === `writable_pure_selector` || state.type === `readonly_pure_selector`;
|
|
2256
|
-
|
|
2168
|
+
const rootSubs = /* @__PURE__ */ new Map();
|
|
2257
2169
|
let updateHandler = safelyHandleUpdate;
|
|
2258
2170
|
if (isSelector) {
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2171
|
+
readOrComputeValue(store, state);
|
|
2172
|
+
for (const [atomKey, atom$1] of traceRootSelectorAtoms(store, state.key)) rootSubs.set(atomKey, subscribeToRootDependency(store, state, atom$1));
|
|
2173
|
+
updateHandler = function updateRootsBeforeHandlingUpdate(update) {
|
|
2174
|
+
const dependencies = traceRootSelectorAtoms(store, state.key);
|
|
2175
|
+
for (const [previousRootKey, unsub] of rootSubs) {
|
|
2176
|
+
const currentRoot = dependencies.get(previousRootKey);
|
|
2177
|
+
if (currentRoot) dependencies.delete(previousRootKey);
|
|
2178
|
+
else {
|
|
2179
|
+
unsub();
|
|
2180
|
+
rootSubs.delete(previousRootKey);
|
|
2181
|
+
}
|
|
2264
2182
|
}
|
|
2183
|
+
for (const [atomKey, atom$1] of dependencies) rootSubs.set(atomKey, subscribeToRootDependency(store, state, atom$1));
|
|
2265
2184
|
safelyHandleUpdate(update);
|
|
2266
2185
|
};
|
|
2267
2186
|
}
|
|
@@ -2269,7 +2188,7 @@ function subscribeToState(store, token, key, handleUpdate) {
|
|
|
2269
2188
|
const unsubscribe = () => {
|
|
2270
2189
|
store.logger.info(`🙈`, state.type, state.key, `Removing subscription "${key}"`);
|
|
2271
2190
|
mainUnsubFunction();
|
|
2272
|
-
|
|
2191
|
+
for (const unsubFromDependency of rootSubs.values()) unsubFromDependency();
|
|
2273
2192
|
};
|
|
2274
2193
|
return unsubscribe;
|
|
2275
2194
|
}
|
|
@@ -2395,7 +2314,7 @@ var Tracker = class {
|
|
|
2395
2314
|
function createMutableAtom(store, options, family) {
|
|
2396
2315
|
store.logger.info(`🔨`, `atom`, options.key, `creating in store "${store.config.name}"`);
|
|
2397
2316
|
const target = newest(store);
|
|
2398
|
-
const { key
|
|
2317
|
+
const { key } = options;
|
|
2399
2318
|
const existing = target.atoms.get(key);
|
|
2400
2319
|
const type = `mutable_atom`;
|
|
2401
2320
|
if (existing && existing.type === type) {
|
|
@@ -2413,9 +2332,7 @@ function createMutableAtom(store, options, family) {
|
|
|
2413
2332
|
subject
|
|
2414
2333
|
};
|
|
2415
2334
|
if (family) newAtom.family = family;
|
|
2416
|
-
const initialValue = def();
|
|
2417
2335
|
target.atoms.set(newAtom.key, newAtom);
|
|
2418
|
-
cacheValue(target, key, initialValue, subject);
|
|
2419
2336
|
const token = deposit(newAtom);
|
|
2420
2337
|
if (options.effects) {
|
|
2421
2338
|
let effectIndex = 0;
|
|
@@ -2586,93 +2503,179 @@ function isTransceiver(value) {
|
|
|
2586
2503
|
}
|
|
2587
2504
|
|
|
2588
2505
|
//#endregion
|
|
2589
|
-
//#region src/internal/
|
|
2590
|
-
|
|
2591
|
-
|
|
2592
|
-
|
|
2593
|
-
|
|
2594
|
-
|
|
2595
|
-
|
|
2596
|
-
|
|
2597
|
-
|
|
2598
|
-
|
|
2599
|
-
new
|
|
2600
|
-
|
|
2601
|
-
|
|
2602
|
-
|
|
2603
|
-
|
|
2604
|
-
|
|
2605
|
-
|
|
2606
|
-
|
|
2607
|
-
|
|
2608
|
-
|
|
2609
|
-
|
|
2610
|
-
|
|
2611
|
-
|
|
2506
|
+
//#region src/internal/store/store.ts
|
|
2507
|
+
var Store = class {
|
|
2508
|
+
parent = null;
|
|
2509
|
+
child = null;
|
|
2510
|
+
valueMap = /* @__PURE__ */ new Map();
|
|
2511
|
+
defaults = /* @__PURE__ */ new Map();
|
|
2512
|
+
atoms = /* @__PURE__ */ new Map();
|
|
2513
|
+
writableSelectors = /* @__PURE__ */ new Map();
|
|
2514
|
+
readonlySelectors = /* @__PURE__ */ new Map();
|
|
2515
|
+
atomsThatAreDefault = /* @__PURE__ */ new Set();
|
|
2516
|
+
selectorAtoms = new Junction({
|
|
2517
|
+
between: [`selectorKey`, `atomKey`],
|
|
2518
|
+
cardinality: `n:n`
|
|
2519
|
+
});
|
|
2520
|
+
selectorGraph = new Junction({
|
|
2521
|
+
between: [`upstreamSelectorKey`, `downstreamSelectorKey`],
|
|
2522
|
+
cardinality: `n:n`
|
|
2523
|
+
}, { makeContentKey: (...keys) => keys.sort().join(`:`) });
|
|
2524
|
+
trackers = /* @__PURE__ */ new Map();
|
|
2525
|
+
families = /* @__PURE__ */ new Map();
|
|
2526
|
+
joins = /* @__PURE__ */ new Map();
|
|
2527
|
+
transactions = /* @__PURE__ */ new Map();
|
|
2528
|
+
transactionMeta = {
|
|
2529
|
+
epoch: /* @__PURE__ */ new Map(),
|
|
2530
|
+
actionContinuities: new Junction({
|
|
2531
|
+
between: [`continuity`, `action`],
|
|
2532
|
+
cardinality: `1:n`
|
|
2533
|
+
})
|
|
2534
|
+
};
|
|
2535
|
+
timelines = /* @__PURE__ */ new Map();
|
|
2536
|
+
timelineTopics = new Junction({
|
|
2537
|
+
between: [`timelineKey`, `topicKey`],
|
|
2538
|
+
cardinality: `1:n`
|
|
2539
|
+
});
|
|
2540
|
+
disposalTraces = new CircularBuffer(100);
|
|
2541
|
+
molecules = /* @__PURE__ */ new Map();
|
|
2542
|
+
moleculeJoins = new Junction({
|
|
2543
|
+
between: [`moleculeKey`, `joinKey`],
|
|
2544
|
+
cardinality: `n:n`
|
|
2545
|
+
}, { makeContentKey: (...keys) => keys.sort().join(`:`) });
|
|
2546
|
+
moleculeGraph = new Junction({
|
|
2547
|
+
between: [`upstreamMoleculeKey`, `downstreamMoleculeKey`],
|
|
2548
|
+
cardinality: `n:n`
|
|
2549
|
+
}, { makeContentKey: (...keys) => keys.sort().join(`:`) });
|
|
2550
|
+
moleculeData = new Junction({
|
|
2551
|
+
between: [`moleculeKey`, `stateFamilyKey`],
|
|
2552
|
+
cardinality: `n:n`
|
|
2553
|
+
}, { makeContentKey: (...keys) => keys.sort().join(`:`) });
|
|
2554
|
+
miscResources = /* @__PURE__ */ new Map();
|
|
2555
|
+
on = {
|
|
2556
|
+
atomCreation: new Subject(),
|
|
2557
|
+
atomDisposal: new Subject(),
|
|
2558
|
+
selectorCreation: new Subject(),
|
|
2559
|
+
selectorDisposal: new Subject(),
|
|
2560
|
+
timelineCreation: new Subject(),
|
|
2561
|
+
transactionCreation: new Subject(),
|
|
2562
|
+
transactionApplying: new StatefulSubject(null),
|
|
2563
|
+
operationClose: new Subject(),
|
|
2564
|
+
moleculeCreation: new Subject(),
|
|
2565
|
+
moleculeDisposal: new Subject()
|
|
2566
|
+
};
|
|
2567
|
+
operation = { open: false };
|
|
2568
|
+
config = {
|
|
2569
|
+
name: `IMPLICIT_STORE`,
|
|
2570
|
+
lifespan: `ephemeral`
|
|
2571
|
+
};
|
|
2572
|
+
loggers = [new AtomIOLogger(`warn`, (_, __, key) => !isReservedIntrospectionKey(key))];
|
|
2573
|
+
logger = {
|
|
2574
|
+
error: (...messages) => {
|
|
2575
|
+
for (const logger of this.loggers) logger.error(...messages);
|
|
2576
|
+
},
|
|
2577
|
+
info: (...messages) => {
|
|
2578
|
+
for (const logger of this.loggers) logger.info(...messages);
|
|
2579
|
+
},
|
|
2580
|
+
warn: (...messages) => {
|
|
2581
|
+
for (const logger of this.loggers) logger.warn(...messages);
|
|
2612
2582
|
}
|
|
2613
|
-
|
|
2614
|
-
|
|
2615
|
-
|
|
2616
|
-
|
|
2617
|
-
|
|
2618
|
-
|
|
2619
|
-
|
|
2620
|
-
|
|
2621
|
-
if (
|
|
2622
|
-
|
|
2623
|
-
|
|
2624
|
-
|
|
2625
|
-
|
|
2626
|
-
|
|
2627
|
-
|
|
2628
|
-
|
|
2629
|
-
|
|
2630
|
-
|
|
2631
|
-
|
|
2632
|
-
|
|
2633
|
-
|
|
2634
|
-
|
|
2583
|
+
};
|
|
2584
|
+
constructor(config, store = null) {
|
|
2585
|
+
this.config = {
|
|
2586
|
+
...store?.config,
|
|
2587
|
+
...config
|
|
2588
|
+
};
|
|
2589
|
+
if (store !== null) {
|
|
2590
|
+
this.operation = { ...store?.operation };
|
|
2591
|
+
if (isRootStore(store)) this.transactionMeta = {
|
|
2592
|
+
epoch: new Map(store?.transactionMeta.epoch),
|
|
2593
|
+
actionContinuities: new Junction(store?.transactionMeta.actionContinuities.toJSON())
|
|
2594
|
+
};
|
|
2595
|
+
for (const [, family] of store.families) {
|
|
2596
|
+
if (family.internalRoles?.includes(`mutable`) || family.internalRoles?.includes(`join`)) continue;
|
|
2597
|
+
family.install(this);
|
|
2598
|
+
}
|
|
2599
|
+
const mutableHelpers = /* @__PURE__ */ new Set();
|
|
2600
|
+
for (const [, atom$1] of store.atoms) {
|
|
2601
|
+
if (mutableHelpers.has(atom$1.key)) continue;
|
|
2602
|
+
atom$1.install(this);
|
|
2603
|
+
if (atom$1.type === `mutable_atom`) {
|
|
2604
|
+
const originalJsonToken = getJsonToken(store, atom$1);
|
|
2605
|
+
const originalUpdateToken = getUpdateToken(atom$1);
|
|
2606
|
+
mutableHelpers.add(originalJsonToken.key);
|
|
2607
|
+
mutableHelpers.add(originalUpdateToken.key);
|
|
2635
2608
|
}
|
|
2636
|
-
subject.next({
|
|
2637
|
-
newValue: resolved,
|
|
2638
|
-
oldValue: future
|
|
2639
|
-
});
|
|
2640
2609
|
}
|
|
2641
|
-
|
|
2642
|
-
|
|
2643
|
-
|
|
2644
|
-
|
|
2645
|
-
|
|
2646
|
-
|
|
2647
|
-
|
|
2648
|
-
}
|
|
2649
|
-
const readCachedValue = (token, target) => {
|
|
2650
|
-
let value = target.valueMap.get(token.key);
|
|
2651
|
-
if (token.type === `mutable_atom` && isChildStore(target)) {
|
|
2652
|
-
const { parent } = target;
|
|
2653
|
-
const copiedValue = copyMutableIfNeeded(target, token, parent);
|
|
2654
|
-
value = copiedValue;
|
|
2610
|
+
for (const [, selector] of store.readonlySelectors) selector.install(this);
|
|
2611
|
+
for (const [, selector] of store.writableSelectors) {
|
|
2612
|
+
if (mutableHelpers.has(selector.key)) continue;
|
|
2613
|
+
selector.install(this);
|
|
2614
|
+
}
|
|
2615
|
+
for (const [, tx] of store.transactions) tx.install(this);
|
|
2616
|
+
for (const [, timeline] of store.timelines) timeline.install(this);
|
|
2617
|
+
}
|
|
2655
2618
|
}
|
|
2656
|
-
return value;
|
|
2657
2619
|
};
|
|
2658
|
-
const
|
|
2659
|
-
|
|
2660
|
-
|
|
2661
|
-
|
|
2662
|
-
|
|
2663
|
-
|
|
2664
|
-
|
|
2665
|
-
|
|
2666
|
-
|
|
2667
|
-
|
|
2668
|
-
|
|
2620
|
+
const IMPLICIT = { get STORE() {
|
|
2621
|
+
globalThis.ATOM_IO_IMPLICIT_STORE ??= new Store({
|
|
2622
|
+
name: `IMPLICIT_STORE`,
|
|
2623
|
+
lifespan: `ephemeral`
|
|
2624
|
+
});
|
|
2625
|
+
return globalThis.ATOM_IO_IMPLICIT_STORE;
|
|
2626
|
+
} };
|
|
2627
|
+
const clearStore = (store) => {
|
|
2628
|
+
const { config } = store;
|
|
2629
|
+
for (const disposable of store.miscResources.values()) disposable[Symbol.dispose]();
|
|
2630
|
+
Object.assign(store, new Store(config));
|
|
2631
|
+
store.config = config;
|
|
2669
2632
|
};
|
|
2670
2633
|
|
|
2634
|
+
//#endregion
|
|
2635
|
+
//#region src/internal/store/withdraw.ts
|
|
2636
|
+
function withdraw(store, token) {
|
|
2637
|
+
let withdrawn;
|
|
2638
|
+
let target = store;
|
|
2639
|
+
while (target !== null) {
|
|
2640
|
+
switch (token.type) {
|
|
2641
|
+
case `atom`:
|
|
2642
|
+
case `mutable_atom`:
|
|
2643
|
+
withdrawn = target.atoms.get(token.key);
|
|
2644
|
+
break;
|
|
2645
|
+
case `writable_pure_selector`:
|
|
2646
|
+
case `writable_held_selector`:
|
|
2647
|
+
withdrawn = target.writableSelectors.get(token.key);
|
|
2648
|
+
break;
|
|
2649
|
+
case `readonly_pure_selector`:
|
|
2650
|
+
case `readonly_held_selector`:
|
|
2651
|
+
withdrawn = target.readonlySelectors.get(token.key);
|
|
2652
|
+
break;
|
|
2653
|
+
case `atom_family`:
|
|
2654
|
+
case `mutable_atom_family`:
|
|
2655
|
+
case `writable_pure_selector_family`:
|
|
2656
|
+
case `readonly_pure_selector_family`:
|
|
2657
|
+
case `writable_held_selector_family`:
|
|
2658
|
+
case `readonly_held_selector_family`:
|
|
2659
|
+
withdrawn = target.families.get(token.key);
|
|
2660
|
+
break;
|
|
2661
|
+
case `timeline`:
|
|
2662
|
+
withdrawn = target.timelines.get(token.key);
|
|
2663
|
+
break;
|
|
2664
|
+
case `transaction`:
|
|
2665
|
+
withdrawn = target.transactions.get(token.key);
|
|
2666
|
+
break;
|
|
2667
|
+
}
|
|
2668
|
+
if (withdrawn) return withdrawn;
|
|
2669
|
+
target = target.child;
|
|
2670
|
+
}
|
|
2671
|
+
throw new NotFoundError(token, store);
|
|
2672
|
+
}
|
|
2673
|
+
|
|
2671
2674
|
//#endregion
|
|
2672
2675
|
//#region src/internal/atom/create-regular-atom.ts
|
|
2673
2676
|
function createRegularAtom(store, options, family) {
|
|
2674
2677
|
const type = `atom`;
|
|
2675
|
-
const { key
|
|
2678
|
+
const { key } = options;
|
|
2676
2679
|
store.logger.info(`🔨`, `atom`, key, `creating in store "${store.config.name}"`);
|
|
2677
2680
|
const target = newest(store);
|
|
2678
2681
|
const existing = target.atoms.get(key);
|
|
@@ -2691,10 +2694,7 @@ function createRegularAtom(store, options, family) {
|
|
|
2691
2694
|
subject
|
|
2692
2695
|
};
|
|
2693
2696
|
if (family) newAtom.family = family;
|
|
2694
|
-
let initialValue = def;
|
|
2695
|
-
if (def instanceof Function) initialValue = def();
|
|
2696
2697
|
target.atoms.set(key, newAtom);
|
|
2697
|
-
cacheValue(target, key, initialValue, subject);
|
|
2698
2698
|
const token = deposit(newAtom);
|
|
2699
2699
|
if (options.effects) {
|
|
2700
2700
|
let effectIndex = 0;
|
|
@@ -2802,6 +2802,20 @@ function installIntoStore(tokens, target, source) {
|
|
|
2802
2802
|
}
|
|
2803
2803
|
}
|
|
2804
2804
|
|
|
2805
|
+
//#endregion
|
|
2806
|
+
//#region src/internal/join/create-join.ts
|
|
2807
|
+
function createJoin(store, options, defaultContent) {
|
|
2808
|
+
store.joins.set(options.key, new Join$1(options, defaultContent, store));
|
|
2809
|
+
const token = {
|
|
2810
|
+
key: options.key,
|
|
2811
|
+
type: `join`,
|
|
2812
|
+
a: options.between[0],
|
|
2813
|
+
b: options.between[1],
|
|
2814
|
+
cardinality: options.cardinality
|
|
2815
|
+
};
|
|
2816
|
+
return token;
|
|
2817
|
+
}
|
|
2818
|
+
|
|
2805
2819
|
//#endregion
|
|
2806
2820
|
//#region src/internal/join/join-internal.ts
|
|
2807
2821
|
var Join = class {
|
|
@@ -3513,26 +3527,21 @@ const timeTravel = (store, action, token) => {
|
|
|
3513
3527
|
const update = timelineData.history[timelineData.at];
|
|
3514
3528
|
const applying = action === `redo` ? `newValue` : `oldValue`;
|
|
3515
3529
|
switch (update.type) {
|
|
3516
|
-
case `atom_update`:
|
|
3530
|
+
case `atom_update`:
|
|
3517
3531
|
ingestAtomUpdate(applying, update, store);
|
|
3518
3532
|
break;
|
|
3519
|
-
|
|
3520
|
-
case `selector_update`: {
|
|
3533
|
+
case `selector_update`:
|
|
3521
3534
|
ingestSelectorUpdate(applying, update, store);
|
|
3522
3535
|
break;
|
|
3523
|
-
|
|
3524
|
-
case `transaction_update`: {
|
|
3536
|
+
case `transaction_update`:
|
|
3525
3537
|
ingestTransactionUpdate(applying, update, store);
|
|
3526
3538
|
break;
|
|
3527
|
-
|
|
3528
|
-
case `state_creation`: {
|
|
3539
|
+
case `state_creation`:
|
|
3529
3540
|
ingestCreationEvent(update, applying, store);
|
|
3530
3541
|
break;
|
|
3531
|
-
|
|
3532
|
-
case `state_disposal`: {
|
|
3542
|
+
case `state_disposal`:
|
|
3533
3543
|
ingestDisposalEvent(update, applying, store);
|
|
3534
3544
|
break;
|
|
3535
|
-
}
|
|
3536
3545
|
case `molecule_creation`:
|
|
3537
3546
|
case `molecule_disposal`:
|
|
3538
3547
|
}
|
|
@@ -3543,5 +3552,5 @@ const timeTravel = (store, action, token) => {
|
|
|
3543
3552
|
};
|
|
3544
3553
|
|
|
3545
3554
|
//#endregion
|
|
3546
|
-
export { CircularBuffer, FAMILY_MEMBER_TOKEN_TYPES, FamilyTracker, Future, IMPLICIT, Join, Junction, LazyMap, NotFoundError, StatefulSubject, Store, Subject, TRANSACTION_PHASES, Tracker, abortTransaction, actUponStore, allocateIntoStore, applyTransaction, arbitrary, assignTransactionToContinuity, become, buildTransaction, cacheValue, capitalize, claimWithinStore, clearStore, closeOperation, counterfeit, createAtomFamily, createMutableAtom, createMutableAtomFamily, createReadonlyHeldSelector, createReadonlyPureSelector, createReadonlyPureSelectorFamily, createRegularAtom, createRegularAtomFamily, createSelectorFamily, createStandaloneAtom, createStandaloneSelector, createTimeline, createTransaction, createWritableHeldSelector, createWritablePureSelector, createWritablePureSelectorFamily, deallocateFromStore, deposit, disposeAtom, disposeFromStore, disposeSelector, editRelationsInStore, evictCachedValue, findInStore, findRelationsInStore, fuseWithinStore, getContinuityKey, getEnvironmentData, getEpochNumberOfAction, getEpochNumberOfContinuity, getFromStore, getInternalRelationsFromStore, getJoin, getJsonFamily, getJsonToken, getSelectorDependencyKeys, getTrace, getUpdateFamily, getUpdateToken, ingestAtomUpdate, ingestCreationEvent, ingestDisposalEvent, ingestMoleculeCreationEvent, ingestMoleculeDisposalEvent, ingestMoleculeTransferEvent, ingestSelectorUpdate, ingestTransactionUpdate, initFamilyMemberInStore, installIntoStore, isAtomKey, isChildStore, isDone, isReadonlySelectorKey, isReservedIntrospectionKey, isRootStore, isSelectorKey, isStateKey, isTransceiver, makeRootMoleculeInStore, markDone, newest, openOperation, prettyPrintTokenType, readCachedValue, readOrComputeValue, recallState, registerSelector, resetAtomOrSelector, resetInStore, seekInStore, setAtomOrSelector, setEpochNumberOfAction, setEpochNumberOfContinuity, setIntoStore, subscribeInStore,
|
|
3555
|
+
export { CircularBuffer, FAMILY_MEMBER_TOKEN_TYPES, FamilyTracker, Future, IMPLICIT, Join, Junction, LazyMap, NotFoundError, StatefulSubject, Store, Subject, TRANSACTION_PHASES, Tracker, abortTransaction, actUponStore, allocateIntoStore, applyTransaction, arbitrary, assignTransactionToContinuity, become, buildTransaction, cacheValue, capitalize, claimWithinStore, clearStore, closeOperation, counterfeit, createAtomFamily, createJoin, createMutableAtom, createMutableAtomFamily, createReadonlyHeldSelector, createReadonlyPureSelector, createReadonlyPureSelectorFamily, createRegularAtom, createRegularAtomFamily, createSelectorFamily, createStandaloneAtom, createStandaloneSelector, createTimeline, createTransaction, createWritableHeldSelector, createWritablePureSelector, createWritablePureSelectorFamily, deallocateFromStore, deposit, disposeAtom, disposeFromStore, disposeSelector, editRelationsInStore, evictCachedValue, findInStore, findRelationsInStore, fuseWithinStore, getContinuityKey, getEnvironmentData, getEpochNumberOfAction, getEpochNumberOfContinuity, getFromStore, getInternalRelationsFromStore, getJoin, getJsonFamily, getJsonToken, getSelectorDependencyKeys, getTrace, getUpdateFamily, getUpdateToken, ingestAtomUpdate, ingestCreationEvent, ingestDisposalEvent, ingestMoleculeCreationEvent, ingestMoleculeDisposalEvent, ingestMoleculeTransferEvent, ingestSelectorUpdate, ingestTransactionUpdate, initFamilyMemberInStore, installIntoStore, isAtomKey, isChildStore, isDone, isReadonlySelectorKey, isReservedIntrospectionKey, isRootStore, isSelectorKey, isStateKey, isTransceiver, makeRootMoleculeInStore, markDone, newest, openOperation, prettyPrintTokenType, readCachedValue, readOrComputeValue, recallState, registerSelector, resetAtomOrSelector, resetInStore, seekInStore, setAtomOrSelector, setEpochNumberOfAction, setEpochNumberOfContinuity, setIntoStore, subscribeInStore, subscribeToRootDependency, subscribeToState, subscribeToTimeline, subscribeToTransaction, timeTravel, traceRootSelectorAtoms, updateSelectorAtoms, withdraw };
|
|
3547
3556
|
//# sourceMappingURL=index.js.map
|