atom.io 0.12.1 → 0.13.0
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/index.cjs.map +1 -1
- package/dist/index.d.cts +6 -3
- package/dist/index.d.ts +6 -3
- package/dist/index.js.map +1 -1
- package/dist/metafile-cjs.json +1 -1
- package/dist/metafile-esm.json +1 -1
- package/internal/dist/index.cjs +1561 -1512
- package/internal/dist/index.cjs.map +1 -1
- package/internal/dist/index.d.cts +24 -14
- package/internal/dist/index.d.ts +24 -14
- package/internal/dist/index.js +1560 -1513
- package/internal/dist/index.js.map +1 -1
- package/internal/dist/metafile-cjs.json +1 -1
- package/internal/dist/metafile-esm.json +1 -1
- package/internal/src/atom/create-atom.ts +4 -4
- package/internal/src/atom/delete-atom.ts +11 -11
- package/internal/src/atom/is-default.ts +5 -5
- package/internal/src/caching.ts +12 -10
- package/internal/src/families/create-atom-family.ts +3 -3
- package/internal/src/families/create-readonly-selector-family.ts +3 -3
- package/internal/src/families/create-selector-family.ts +4 -4
- package/internal/src/index.ts +1 -0
- package/internal/src/keys.ts +4 -4
- package/internal/src/lazy-map.ts +6 -2
- package/internal/src/lineage.ts +18 -0
- package/internal/src/mutable/create-mutable-atom.ts +5 -4
- package/internal/src/mutable/get-json-family.ts +3 -3
- package/internal/src/mutable/tracker.ts +13 -10
- package/internal/src/operation.ts +19 -19
- package/internal/src/selector/create-read-write-selector.ts +5 -4
- package/internal/src/selector/create-readonly-selector.ts +4 -3
- package/internal/src/selector/create-selector.ts +6 -6
- package/internal/src/selector/delete-selector.ts +10 -10
- package/internal/src/selector/get-selector-dependency-keys.ts +2 -2
- package/internal/src/selector/register-selector.ts +4 -4
- package/internal/src/selector/update-selector-atoms.ts +2 -2
- package/internal/src/set-state/copy-mutable-if-needed.ts +4 -3
- package/internal/src/set-state/copy-mutable-in-transaction.ts +10 -16
- package/internal/src/set-state/copy-mutable-into-new-store.ts +1 -1
- package/internal/src/set-state/evict-downstream.ts +5 -5
- package/internal/src/set-state/set-atom.ts +6 -1
- package/internal/src/set-state/stow-update.ts +7 -2
- package/internal/src/store/store.ts +31 -24
- package/internal/src/store/withdraw-new-family-member.ts +3 -4
- package/internal/src/store/withdraw.ts +58 -59
- package/internal/src/subject.ts +14 -0
- package/internal/src/subscribe/recall-state.ts +5 -5
- package/internal/src/timeline/add-atom-to-timeline.ts +37 -27
- package/internal/src/timeline/create-timeline.ts +6 -8
- package/internal/src/timeline/time-travel.ts +22 -4
- package/internal/src/transaction/abort-transaction.ts +5 -3
- package/internal/src/transaction/apply-transaction.ts +80 -58
- package/internal/src/transaction/build-transaction.ts +33 -23
- package/internal/src/transaction/create-transaction.ts +6 -9
- package/internal/src/transaction/index.ts +2 -10
- package/internal/src/transaction/redo-transaction.ts +15 -10
- package/internal/src/transaction/undo-transaction.ts +15 -16
- package/introspection/dist/index.cjs +2 -2
- package/introspection/dist/index.cjs.map +1 -1
- package/introspection/dist/index.js +3 -3
- package/introspection/dist/index.js.map +1 -1
- package/introspection/src/attach-atom-index.ts +2 -2
- package/introspection/src/attach-selector-index.ts +2 -2
- package/package.json +3 -3
- package/react-devtools/dist/index.cjs +22 -8
- package/react-devtools/dist/index.cjs.map +1 -1
- package/react-devtools/dist/index.d.cts +17 -9
- package/react-devtools/dist/index.d.ts +17 -9
- package/react-devtools/dist/index.js +22 -8
- package/react-devtools/dist/index.js.map +1 -1
- package/react-devtools/dist/metafile-cjs.json +1 -1
- package/react-devtools/dist/metafile-esm.json +1 -1
- package/react-devtools/src/Updates.tsx +22 -10
- package/src/transaction.ts +7 -2
- package/transceivers/set-rtx/dist/index.cjs.map +1 -1
- package/transceivers/set-rtx/dist/index.d.cts +2 -2
- package/transceivers/set-rtx/dist/index.d.ts +2 -2
- package/transceivers/set-rtx/dist/index.js.map +1 -1
- package/transceivers/set-rtx/dist/metafile-cjs.json +1 -1
- package/transceivers/set-rtx/dist/metafile-esm.json +1 -1
- package/transceivers/set-rtx/src/set-rtx.ts +3 -3
package/internal/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { getState, setState, subscribe, subscribeToTimeline, AtomIOLogger, runTransaction } from 'atom.io';
|
|
2
2
|
import { selectJson, stringifyJson, parseJson, selectJsonFamily } from 'atom.io/json';
|
|
3
3
|
|
|
4
4
|
var __defProp = Object.defineProperty;
|
|
@@ -40,25 +40,209 @@ var Future = class extends Promise {
|
|
|
40
40
|
}
|
|
41
41
|
};
|
|
42
42
|
|
|
43
|
-
// src/
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
43
|
+
// src/lineage.ts
|
|
44
|
+
function newest(scion) {
|
|
45
|
+
while (scion.child !== null) {
|
|
46
|
+
scion = scion.child;
|
|
47
|
+
}
|
|
48
|
+
return scion;
|
|
49
|
+
}
|
|
50
|
+
function eldest(scion) {
|
|
51
|
+
while (scion.parent !== null) {
|
|
52
|
+
scion = scion.parent;
|
|
53
|
+
}
|
|
54
|
+
return scion;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// src/caching.ts
|
|
58
|
+
function cacheValue(key, value, subject, store) {
|
|
59
|
+
const target = newest(store);
|
|
60
|
+
const currentValue = target.valueMap.get(key);
|
|
61
|
+
if (currentValue instanceof Future) {
|
|
62
|
+
currentValue.cancel();
|
|
63
|
+
}
|
|
64
|
+
if (value instanceof Promise) {
|
|
65
|
+
const future = new Future(value);
|
|
66
|
+
newest(store).valueMap.set(key, future);
|
|
67
|
+
future.then((resolved) => {
|
|
68
|
+
if (future.isCanceled) {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
cacheValue(key, resolved, subject, store);
|
|
72
|
+
subject.next({ newValue: resolved, oldValue: future });
|
|
73
|
+
}).catch((thrown) => {
|
|
74
|
+
if (thrown !== `canceled`) {
|
|
75
|
+
store.logger.error(`\u{1F4A5}`, `state`, key, `rejected:`, thrown);
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
return future;
|
|
79
|
+
}
|
|
80
|
+
target.valueMap.set(key, value);
|
|
81
|
+
return value;
|
|
82
|
+
}
|
|
83
|
+
var readCachedValue = (key, store) => {
|
|
84
|
+
return newest(store).valueMap.get(key);
|
|
85
|
+
};
|
|
86
|
+
var isValueCached = (key, store) => {
|
|
87
|
+
return newest(store).valueMap.has(key);
|
|
88
|
+
};
|
|
89
|
+
var evictCachedValue = (key, store) => {
|
|
90
|
+
const core = newest(store);
|
|
91
|
+
const currentValue = core.valueMap.get(key);
|
|
92
|
+
if (currentValue instanceof Future) {
|
|
93
|
+
currentValue.cancel();
|
|
94
|
+
}
|
|
95
|
+
if (core.operation.open) {
|
|
96
|
+
core.operation.prev.set(key, currentValue);
|
|
97
|
+
}
|
|
98
|
+
core.valueMap.delete(key);
|
|
99
|
+
store.logger.info(`\u{1F5D1}`, `state`, key, `evicted`);
|
|
100
|
+
};
|
|
101
|
+
var Tracker = class {
|
|
102
|
+
constructor(mutableState, store) {
|
|
103
|
+
this.unsubscribeFromInnerValue = null;
|
|
104
|
+
this.mutableState = mutableState;
|
|
105
|
+
const target = newest(store);
|
|
106
|
+
this.latestUpdateState = this.initializeState(mutableState, target);
|
|
107
|
+
this.observeCore(mutableState, this.latestUpdateState, target);
|
|
108
|
+
this.updateCore(mutableState, this.latestUpdateState, target);
|
|
109
|
+
target.trackers.set(mutableState.key, this);
|
|
110
|
+
}
|
|
111
|
+
initializeState(mutableState, store) {
|
|
112
|
+
const latestUpdateStateKey = `*${mutableState.key}`;
|
|
113
|
+
deleteAtom({ type: `atom`, key: latestUpdateStateKey }, store);
|
|
114
|
+
const familyMetaData = mutableState.family ? {
|
|
115
|
+
key: `*${mutableState.family.key}`,
|
|
116
|
+
subKey: mutableState.family.subKey
|
|
117
|
+
} : void 0;
|
|
118
|
+
const latestUpdateState = createAtom(
|
|
119
|
+
{
|
|
120
|
+
key: latestUpdateStateKey,
|
|
121
|
+
default: null
|
|
122
|
+
},
|
|
123
|
+
familyMetaData,
|
|
124
|
+
store
|
|
125
|
+
);
|
|
126
|
+
return latestUpdateState;
|
|
127
|
+
}
|
|
128
|
+
observeCore(mutableState, latestUpdateState, store) {
|
|
129
|
+
const originalInnerValue = getState(mutableState, store);
|
|
130
|
+
const target = newest(store);
|
|
131
|
+
this.unsubscribeFromInnerValue = originalInnerValue.subscribe(
|
|
132
|
+
`tracker:${store.config.name}:${target.transactionMeta === null ? `main` : target.transactionMeta.update.key}`,
|
|
133
|
+
(update) => {
|
|
134
|
+
const unsubscribe = store.subject.operationStatus.subscribe(
|
|
135
|
+
mutableState.key,
|
|
136
|
+
() => {
|
|
137
|
+
unsubscribe();
|
|
138
|
+
setState(latestUpdateState, update, store);
|
|
139
|
+
}
|
|
140
|
+
);
|
|
141
|
+
}
|
|
142
|
+
);
|
|
143
|
+
subscribe(
|
|
144
|
+
mutableState,
|
|
145
|
+
(update) => {
|
|
146
|
+
var _a;
|
|
147
|
+
if (update.newValue !== update.oldValue) {
|
|
148
|
+
(_a = this.unsubscribeFromInnerValue) == null ? void 0 : _a.call(this);
|
|
149
|
+
const target2 = newest(store);
|
|
150
|
+
this.unsubscribeFromInnerValue = update.newValue.subscribe(
|
|
151
|
+
`tracker:${store.config.name}:${target2.transactionMeta === null ? `main` : target2.transactionMeta.update.key}`,
|
|
152
|
+
(update2) => {
|
|
153
|
+
const unsubscribe = store.subject.operationStatus.subscribe(
|
|
154
|
+
mutableState.key,
|
|
155
|
+
() => {
|
|
156
|
+
unsubscribe();
|
|
157
|
+
setState(latestUpdateState, update2, store);
|
|
158
|
+
}
|
|
159
|
+
);
|
|
160
|
+
}
|
|
161
|
+
);
|
|
162
|
+
}
|
|
163
|
+
},
|
|
164
|
+
`${store.config.name}: tracker observing inner value`,
|
|
165
|
+
store
|
|
166
|
+
);
|
|
167
|
+
}
|
|
168
|
+
updateCore(mutableState, latestUpdateState, store) {
|
|
169
|
+
subscribe(
|
|
170
|
+
latestUpdateState,
|
|
171
|
+
({ newValue, oldValue }) => {
|
|
172
|
+
const timelineId = store.timelineAtoms.getRelatedKey(
|
|
173
|
+
latestUpdateState.key
|
|
174
|
+
);
|
|
175
|
+
if (timelineId) {
|
|
176
|
+
const timelineData = store.timelines.get(timelineId);
|
|
177
|
+
if (timelineData == null ? void 0 : timelineData.timeTraveling) {
|
|
178
|
+
const unsubscribe2 = subscribeToTimeline(
|
|
179
|
+
{ key: timelineId, type: `timeline` },
|
|
180
|
+
(update) => {
|
|
181
|
+
unsubscribe2();
|
|
182
|
+
setState(
|
|
183
|
+
mutableState,
|
|
184
|
+
(transceiver) => {
|
|
185
|
+
if (update === `redo` && newValue) {
|
|
186
|
+
transceiver.do(newValue);
|
|
187
|
+
} else if (update === `undo` && oldValue) {
|
|
188
|
+
transceiver.undo(oldValue);
|
|
189
|
+
}
|
|
190
|
+
return transceiver;
|
|
191
|
+
},
|
|
192
|
+
store
|
|
193
|
+
);
|
|
194
|
+
}
|
|
195
|
+
);
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
const unsubscribe = store.subject.operationStatus.subscribe(
|
|
200
|
+
latestUpdateState.key,
|
|
201
|
+
() => {
|
|
202
|
+
unsubscribe();
|
|
203
|
+
const mutable = getState(mutableState, store);
|
|
204
|
+
const updateNumber = mutable.getUpdateNumber(newValue);
|
|
205
|
+
const eventOffset = updateNumber - mutable.cacheUpdateNumber;
|
|
206
|
+
if (newValue && eventOffset === 1) {
|
|
207
|
+
setState(
|
|
208
|
+
mutableState,
|
|
209
|
+
(transceiver) => (transceiver.do(newValue), transceiver),
|
|
210
|
+
store
|
|
211
|
+
);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
);
|
|
215
|
+
},
|
|
216
|
+
`${store.config.name}: tracker observing latest update`,
|
|
217
|
+
store
|
|
51
218
|
);
|
|
52
|
-
return;
|
|
53
219
|
}
|
|
220
|
+
};
|
|
221
|
+
|
|
222
|
+
// src/mutable/create-mutable-atom.ts
|
|
223
|
+
function createMutableAtom(options, store) {
|
|
54
224
|
store.logger.info(
|
|
55
|
-
`\u{
|
|
56
|
-
`
|
|
57
|
-
|
|
58
|
-
`
|
|
225
|
+
`\u{1F527}`,
|
|
226
|
+
`atom`,
|
|
227
|
+
options.key,
|
|
228
|
+
`creating in store "${store.config.name}"`
|
|
59
229
|
);
|
|
60
|
-
|
|
61
|
-
|
|
230
|
+
const coreState = createAtom(options, void 0, store);
|
|
231
|
+
new Tracker(coreState, store);
|
|
232
|
+
const jsonState = selectJson(coreState, options, store);
|
|
233
|
+
const target = newest(store);
|
|
234
|
+
subscribe(
|
|
235
|
+
jsonState,
|
|
236
|
+
() => {
|
|
237
|
+
const trackerHasBeenInitialized = newest(store).trackers.has(coreState.key);
|
|
238
|
+
if (!trackerHasBeenInitialized) {
|
|
239
|
+
new Tracker(coreState, store);
|
|
240
|
+
}
|
|
241
|
+
},
|
|
242
|
+
`tracker-initializer:${store == null ? void 0 : store.config.name}:${target.transactionMeta === null ? `main` : `${target.transactionMeta.update.key}`}`
|
|
243
|
+
);
|
|
244
|
+
return coreState;
|
|
245
|
+
}
|
|
62
246
|
|
|
63
247
|
// src/store/deposit.ts
|
|
64
248
|
function deposit(state) {
|
|
@@ -349,10 +533,22 @@ var Subject = class {
|
|
|
349
533
|
}
|
|
350
534
|
}
|
|
351
535
|
};
|
|
536
|
+
var StatefulSubject = class extends Subject {
|
|
537
|
+
constructor(initialState) {
|
|
538
|
+
super();
|
|
539
|
+
this.state = initialState;
|
|
540
|
+
}
|
|
541
|
+
next(value) {
|
|
542
|
+
this.state = value;
|
|
543
|
+
super.next(value);
|
|
544
|
+
}
|
|
545
|
+
};
|
|
352
546
|
|
|
353
547
|
// src/store/store.ts
|
|
354
548
|
var Store = class {
|
|
355
549
|
constructor(name, store = null) {
|
|
550
|
+
this.parent = null;
|
|
551
|
+
this.child = null;
|
|
356
552
|
this.valueMap = /* @__PURE__ */ new Map();
|
|
357
553
|
this.atoms = /* @__PURE__ */ new Map();
|
|
358
554
|
this.selectors = /* @__PURE__ */ new Map();
|
|
@@ -384,10 +580,11 @@ var Store = class {
|
|
|
384
580
|
selectorCreation: new Subject(),
|
|
385
581
|
transactionCreation: new Subject(),
|
|
386
582
|
timelineCreation: new Subject(),
|
|
583
|
+
transactionApplying: new StatefulSubject(null),
|
|
387
584
|
operationStatus: new Subject()
|
|
388
585
|
};
|
|
389
586
|
this.operation = { open: false };
|
|
390
|
-
this.
|
|
587
|
+
this.transactionMeta = null;
|
|
391
588
|
this.config = {
|
|
392
589
|
name: `IMPLICIT_STORE`
|
|
393
590
|
};
|
|
@@ -411,7 +608,7 @@ var Store = class {
|
|
|
411
608
|
if (store !== null) {
|
|
412
609
|
this.valueMap = new Map(store == null ? void 0 : store.valueMap);
|
|
413
610
|
this.operation = __spreadValues({}, store == null ? void 0 : store.operation);
|
|
414
|
-
this.
|
|
611
|
+
this.transactionMeta = (store == null ? void 0 : store.transactionMeta) ? __spreadValues({}, store == null ? void 0 : store.transactionMeta) : null;
|
|
415
612
|
this.config = __spreadProps(__spreadValues({}, store == null ? void 0 : store.config), {
|
|
416
613
|
name
|
|
417
614
|
});
|
|
@@ -446,1681 +643,1531 @@ var clearStore = (store) => {
|
|
|
446
643
|
store.config = config;
|
|
447
644
|
};
|
|
448
645
|
|
|
449
|
-
// src/
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
646
|
+
// src/store/withdraw.ts
|
|
647
|
+
function withdraw(token, store) {
|
|
648
|
+
var _a, _b, _c, _d;
|
|
649
|
+
const target = newest(store);
|
|
650
|
+
const state = (_d = (_c = (_b = (_a = target.atoms.get(token.key)) != null ? _a : target.selectors.get(token.key)) != null ? _b : target.readonlySelectors.get(token.key)) != null ? _c : target.transactions.get(token.key)) != null ? _d : target.timelines.get(token.key);
|
|
651
|
+
if (state) {
|
|
652
|
+
return state;
|
|
456
653
|
}
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
654
|
+
return void 0;
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
// src/store/withdraw-new-family-member.ts
|
|
658
|
+
function withdrawNewFamilyMember(token, store) {
|
|
659
|
+
if (token.family) {
|
|
463
660
|
store.logger.info(
|
|
464
|
-
`\
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
`
|
|
468
|
-
atomToken.key,
|
|
469
|
-
`went`,
|
|
470
|
-
update.oldValue,
|
|
471
|
-
`->`,
|
|
472
|
-
update.newValue,
|
|
473
|
-
currentTransactionKey ? `in transaction "${currentTransactionKey}"` : currentSelectorKey ? `in selector "${currentSelectorKey}"` : ``
|
|
661
|
+
`\u{1F46A}`,
|
|
662
|
+
token.type,
|
|
663
|
+
token.key,
|
|
664
|
+
`creating new family member in store "${store.config.name}"`
|
|
474
665
|
);
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
(update2) => {
|
|
507
|
-
var _a2, _b2;
|
|
508
|
-
unsubscribe();
|
|
509
|
-
if (tl.timeTraveling === null && currentTransactionTime) {
|
|
510
|
-
if (tl.at !== tl.history.length) {
|
|
511
|
-
tl.history.splice(tl.at);
|
|
512
|
-
}
|
|
513
|
-
const atomUpdates = update2.atomUpdates.filter((atomUpdate) => {
|
|
514
|
-
const core = target(store);
|
|
515
|
-
const atomOrFamilyKeys = core.timelineAtoms.getRelatedKeys(
|
|
516
|
-
tl.key
|
|
517
|
-
);
|
|
518
|
-
return atomOrFamilyKeys ? [...atomOrFamilyKeys].some(
|
|
519
|
-
(key) => {
|
|
520
|
-
var _a3;
|
|
521
|
-
return key === atomUpdate.key || key === ((_a3 = atomUpdate.family) == null ? void 0 : _a3.key);
|
|
522
|
-
}
|
|
523
|
-
) : false;
|
|
524
|
-
});
|
|
525
|
-
const timelineTransactionUpdate = __spreadProps(__spreadValues({
|
|
526
|
-
type: `transaction_update`,
|
|
527
|
-
timestamp: currentTransactionTime
|
|
528
|
-
}, update2), {
|
|
529
|
-
atomUpdates
|
|
530
|
-
});
|
|
531
|
-
const willCapture = (_b2 = (_a2 = tl.shouldCapture) == null ? void 0 : _a2.call(tl, timelineTransactionUpdate, tl)) != null ? _b2 : true;
|
|
532
|
-
if (willCapture) {
|
|
533
|
-
tl.history.push(timelineTransactionUpdate);
|
|
534
|
-
tl.at = tl.history.length;
|
|
535
|
-
tl.subject.next(timelineTransactionUpdate);
|
|
536
|
-
}
|
|
537
|
-
}
|
|
538
|
-
tl.transactionKey = null;
|
|
539
|
-
store.logger.info(
|
|
540
|
-
`\u231B`,
|
|
541
|
-
`timeline`,
|
|
542
|
-
tl.key,
|
|
543
|
-
`got a transaction_update "${update2.key}"`
|
|
544
|
-
);
|
|
545
|
-
}
|
|
546
|
-
);
|
|
547
|
-
}
|
|
548
|
-
} else if (currentSelectorKey && currentSelectorTime) {
|
|
549
|
-
let latestUpdate = tl.history.at(-1);
|
|
550
|
-
if (currentSelectorTime !== tl.selectorTime) {
|
|
551
|
-
latestUpdate = {
|
|
552
|
-
type: `selector_update`,
|
|
553
|
-
timestamp: currentSelectorTime,
|
|
554
|
-
key: currentSelectorKey,
|
|
555
|
-
atomUpdates: []
|
|
556
|
-
};
|
|
557
|
-
latestUpdate.atomUpdates.push(__spreadValues({
|
|
558
|
-
key: atom.key,
|
|
559
|
-
type: `atom_update`
|
|
560
|
-
}, update));
|
|
561
|
-
if (tl.at !== tl.history.length) {
|
|
562
|
-
tl.history.splice(tl.at);
|
|
563
|
-
}
|
|
564
|
-
tl.history.push(latestUpdate);
|
|
565
|
-
store.logger.info(
|
|
566
|
-
`\u231B`,
|
|
567
|
-
`timeline`,
|
|
568
|
-
tl.key,
|
|
569
|
-
`got a selector_update "${currentSelectorKey}" with`,
|
|
570
|
-
latestUpdate.atomUpdates.map((atomUpdate) => atomUpdate.key)
|
|
571
|
-
);
|
|
572
|
-
tl.at = tl.history.length;
|
|
573
|
-
tl.selectorTime = currentSelectorTime;
|
|
574
|
-
} else {
|
|
575
|
-
if ((latestUpdate == null ? void 0 : latestUpdate.type) === `selector_update`) {
|
|
576
|
-
latestUpdate.atomUpdates.push(__spreadValues({
|
|
577
|
-
key: atom.key,
|
|
578
|
-
type: `atom_update`
|
|
579
|
-
}, update));
|
|
580
|
-
store.logger.info(
|
|
581
|
-
`\u231B`,
|
|
582
|
-
`timeline`,
|
|
583
|
-
tl.key,
|
|
584
|
-
`set selector_update "${currentSelectorKey}" to`,
|
|
585
|
-
latestUpdate == null ? void 0 : latestUpdate.atomUpdates.map((atomUpdate) => atomUpdate.key)
|
|
586
|
-
);
|
|
587
|
-
}
|
|
588
|
-
}
|
|
589
|
-
if (latestUpdate) {
|
|
590
|
-
const willCaptureSelectorUpdate = (_b = (_a = tl.shouldCapture) == null ? void 0 : _a.call(tl, latestUpdate, tl)) != null ? _b : true;
|
|
591
|
-
if (willCaptureSelectorUpdate) {
|
|
592
|
-
tl.subject.next(latestUpdate);
|
|
593
|
-
} else {
|
|
594
|
-
tl.history.pop();
|
|
595
|
-
tl.at = tl.history.length;
|
|
596
|
-
}
|
|
597
|
-
}
|
|
598
|
-
} else {
|
|
599
|
-
const timestamp = Date.now();
|
|
600
|
-
tl.selectorTime = null;
|
|
601
|
-
if (tl.at !== tl.history.length) {
|
|
602
|
-
tl.history.splice(tl.at);
|
|
603
|
-
}
|
|
604
|
-
const atomUpdate = {
|
|
605
|
-
type: `atom_update`,
|
|
606
|
-
timestamp,
|
|
607
|
-
key: atom.key,
|
|
608
|
-
oldValue: update.oldValue,
|
|
609
|
-
newValue: update.newValue
|
|
610
|
-
};
|
|
611
|
-
if (atom.family) {
|
|
612
|
-
atomUpdate.family = atom.family;
|
|
613
|
-
}
|
|
614
|
-
const willCapture = (_d = (_c = tl.shouldCapture) == null ? void 0 : _c.call(tl, atomUpdate, tl)) != null ? _d : true;
|
|
615
|
-
store.logger.info(
|
|
616
|
-
`\u231B`,
|
|
617
|
-
`timeline`,
|
|
618
|
-
tl.key,
|
|
619
|
-
`got an atom_update to "${atom.key}"`
|
|
620
|
-
);
|
|
621
|
-
if (willCapture) {
|
|
622
|
-
tl.history.push(atomUpdate);
|
|
623
|
-
tl.at = tl.history.length;
|
|
624
|
-
tl.subject.next(atomUpdate);
|
|
666
|
+
const target = newest(store);
|
|
667
|
+
const family = target.families.get(token.family.key);
|
|
668
|
+
if (family) {
|
|
669
|
+
const jsonSubKey = JSON.parse(token.family.subKey);
|
|
670
|
+
family(jsonSubKey);
|
|
671
|
+
const state = withdraw(token, store);
|
|
672
|
+
return state;
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
return void 0;
|
|
676
|
+
}
|
|
677
|
+
|
|
678
|
+
// src/families/create-atom-family.ts
|
|
679
|
+
function createAtomFamily(options, store) {
|
|
680
|
+
const subject = new Subject();
|
|
681
|
+
const atomFamily = Object.assign(
|
|
682
|
+
(key) => {
|
|
683
|
+
const subKey = stringifyJson(key);
|
|
684
|
+
const family = { key: options.key, subKey };
|
|
685
|
+
const fullKey = `${options.key}(${subKey})`;
|
|
686
|
+
const existing = withdraw({ key: fullKey, type: `atom` }, store);
|
|
687
|
+
let token;
|
|
688
|
+
if (existing) {
|
|
689
|
+
token = deposit(existing);
|
|
690
|
+
} else {
|
|
691
|
+
const individualOptions = {
|
|
692
|
+
key: fullKey,
|
|
693
|
+
default: options.default instanceof Function ? options.default(key) : options.default
|
|
694
|
+
};
|
|
695
|
+
if (options.effects) {
|
|
696
|
+
individualOptions.effects = options.effects(key);
|
|
625
697
|
}
|
|
698
|
+
token = createAtom(individualOptions, family, store);
|
|
699
|
+
subject.next(token);
|
|
626
700
|
}
|
|
701
|
+
return token;
|
|
702
|
+
},
|
|
703
|
+
{
|
|
704
|
+
key: options.key,
|
|
705
|
+
type: `atom_family`,
|
|
706
|
+
subject
|
|
627
707
|
}
|
|
628
|
-
|
|
629
|
-
|
|
708
|
+
);
|
|
709
|
+
const target = newest(store);
|
|
710
|
+
target.families.set(options.key, atomFamily);
|
|
711
|
+
return atomFamily;
|
|
712
|
+
}
|
|
630
713
|
|
|
631
|
-
// src/
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
history: (_a = data == null ? void 0 : data.history.map((update) => __spreadValues({}, update))) != null ? _a : [],
|
|
643
|
-
install: (store2) => createTimeline(options, store2, tl),
|
|
644
|
-
subject: new Subject()
|
|
645
|
-
});
|
|
646
|
-
if (options.shouldCapture) {
|
|
647
|
-
tl.shouldCapture = options.shouldCapture;
|
|
648
|
-
}
|
|
649
|
-
const core = target(store);
|
|
650
|
-
for (const tokenOrFamily of options.atoms) {
|
|
651
|
-
const timelineKey = core.timelineAtoms.getRelatedKey(tokenOrFamily.key);
|
|
652
|
-
if (timelineKey) {
|
|
653
|
-
store.logger.error(
|
|
654
|
-
`\u274C`,
|
|
655
|
-
`timeline`,
|
|
656
|
-
options.key,
|
|
657
|
-
`Failed to add atom "${tokenOrFamily.key}" because it already belongs to timeline "${timelineKey}"`
|
|
658
|
-
);
|
|
659
|
-
continue;
|
|
660
|
-
}
|
|
661
|
-
if (tokenOrFamily.type === `atom_family`) {
|
|
662
|
-
const family = tokenOrFamily;
|
|
663
|
-
family.subject.subscribe(`timeline:${options.key}`, (token2) => {
|
|
664
|
-
addAtomToTimeline(token2, tl, store);
|
|
665
|
-
});
|
|
666
|
-
for (const atom of core.atoms.values()) {
|
|
667
|
-
if (((_b = atom.family) == null ? void 0 : _b.key) === family.key) {
|
|
668
|
-
addAtomToTimeline(atom, tl, store);
|
|
669
|
-
}
|
|
670
|
-
}
|
|
671
|
-
} else {
|
|
672
|
-
const token2 = tokenOrFamily;
|
|
673
|
-
if (`family` in token2 && token2.family) {
|
|
674
|
-
const familyTimelineKey = core.timelineAtoms.getRelatedKey(
|
|
675
|
-
token2.family.key
|
|
676
|
-
);
|
|
677
|
-
if (familyTimelineKey) {
|
|
678
|
-
store.logger.error(
|
|
679
|
-
`\u274C`,
|
|
680
|
-
`timeline`,
|
|
681
|
-
options.key,
|
|
682
|
-
`Failed to add atom "${token2.key}" because its family "${token2.family.key}" already belongs to timeline "${familyTimelineKey}"`
|
|
683
|
-
);
|
|
684
|
-
continue;
|
|
685
|
-
}
|
|
686
|
-
}
|
|
687
|
-
addAtomToTimeline(token2, tl, store);
|
|
688
|
-
}
|
|
689
|
-
core.timelineAtoms = core.timelineAtoms.set({
|
|
690
|
-
atomKey: tokenOrFamily.key,
|
|
691
|
-
timelineKey: options.key
|
|
692
|
-
});
|
|
714
|
+
// src/operation.ts
|
|
715
|
+
var openOperation = (token, store) => {
|
|
716
|
+
const target = newest(store);
|
|
717
|
+
if (target.operation.open) {
|
|
718
|
+
store.logger.error(
|
|
719
|
+
`\u274C`,
|
|
720
|
+
token.type,
|
|
721
|
+
token.key,
|
|
722
|
+
`failed to setState during a setState for "${target.operation.token.key}"`
|
|
723
|
+
);
|
|
724
|
+
return `rejection`;
|
|
693
725
|
}
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
726
|
+
target.operation = {
|
|
727
|
+
open: true,
|
|
728
|
+
done: /* @__PURE__ */ new Set(),
|
|
729
|
+
prev: /* @__PURE__ */ new Map(),
|
|
730
|
+
time: Date.now(),
|
|
731
|
+
token
|
|
698
732
|
};
|
|
699
|
-
store.subject.timelineCreation.next(token);
|
|
700
|
-
return token;
|
|
701
|
-
}
|
|
702
|
-
var timeTravel = (direction, token, store) => {
|
|
703
|
-
const action = direction === `forward` ? `redo` : `undo`;
|
|
704
733
|
store.logger.info(
|
|
705
|
-
|
|
706
|
-
|
|
734
|
+
`\u2B55`,
|
|
735
|
+
token.type,
|
|
707
736
|
token.key,
|
|
708
|
-
|
|
737
|
+
`operation start in store "${store.config.name}"${target.transactionMeta === null ? `` : ` ${target.transactionMeta.phase} "${target.transactionMeta.update.key}"`}`
|
|
709
738
|
);
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
739
|
+
};
|
|
740
|
+
var closeOperation = (store) => {
|
|
741
|
+
const target = newest(store);
|
|
742
|
+
if (target.operation.open) {
|
|
743
|
+
store.logger.info(
|
|
744
|
+
`\u{1F534}`,
|
|
745
|
+
target.operation.token.type,
|
|
746
|
+
target.operation.token.key,
|
|
747
|
+
`operation done in store "${store.config.name}"`
|
|
717
748
|
);
|
|
718
|
-
return;
|
|
719
749
|
}
|
|
720
|
-
|
|
750
|
+
target.operation = { open: false };
|
|
751
|
+
store.subject.operationStatus.next(target.operation);
|
|
752
|
+
};
|
|
753
|
+
var isDone = (key, store) => {
|
|
754
|
+
const target = newest(store);
|
|
755
|
+
if (!target.operation.open) {
|
|
721
756
|
store.logger.warn(
|
|
722
|
-
`\u{
|
|
723
|
-
`
|
|
724
|
-
|
|
725
|
-
`
|
|
757
|
+
`\u{1F41E}`,
|
|
758
|
+
`unknown`,
|
|
759
|
+
key,
|
|
760
|
+
`isDone called outside of an operation. This is probably a bug.`
|
|
726
761
|
);
|
|
727
|
-
return;
|
|
762
|
+
return true;
|
|
728
763
|
}
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
764
|
+
return target.operation.done.has(key);
|
|
765
|
+
};
|
|
766
|
+
var markDone = (key, store) => {
|
|
767
|
+
const target = newest(store);
|
|
768
|
+
if (!target.operation.open) {
|
|
769
|
+
store.logger.warn(
|
|
770
|
+
`\u{1F41E}`,
|
|
771
|
+
`unknown`,
|
|
772
|
+
key,
|
|
773
|
+
`markDone called outside of an operation. This is probably a bug.`
|
|
774
|
+
);
|
|
775
|
+
return;
|
|
732
776
|
}
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
777
|
+
target.operation.done.add(key);
|
|
778
|
+
};
|
|
779
|
+
|
|
780
|
+
// src/set-state/become.ts
|
|
781
|
+
var become = (nextVersionOfThing) => (originalThing) => nextVersionOfThing instanceof Function ? nextVersionOfThing(
|
|
782
|
+
originalThing instanceof Function ? originalThing() : originalThing
|
|
783
|
+
) : nextVersionOfThing;
|
|
784
|
+
|
|
785
|
+
// src/read-or-compute-value.ts
|
|
786
|
+
var readOrComputeValue = (state, store) => {
|
|
787
|
+
if (isValueCached(state.key, store)) {
|
|
788
|
+
store.logger.info(`\u{1F4D6}`, state.type, state.key, `reading cached value`);
|
|
789
|
+
return readCachedValue(state.key, store);
|
|
790
|
+
}
|
|
791
|
+
if (state.type !== `atom`) {
|
|
792
|
+
store.logger.info(`\u{1F9EE}`, state.type, state.key, `computing value`);
|
|
793
|
+
return state.get();
|
|
794
|
+
}
|
|
795
|
+
const fallback = state.default instanceof Function ? state.default() : state.default;
|
|
796
|
+
store.logger.info(
|
|
797
|
+
`\u{1F481}`,
|
|
798
|
+
`atom`,
|
|
799
|
+
state.key,
|
|
800
|
+
`could not find cached value; using default`,
|
|
801
|
+
fallback
|
|
802
|
+
);
|
|
803
|
+
return state.default instanceof Function ? state.default() : state.default;
|
|
804
|
+
};
|
|
805
|
+
|
|
806
|
+
// src/set-state/copy-mutable-if-needed.ts
|
|
807
|
+
function copyMutableIfNeeded(atom, transform, origin, target) {
|
|
808
|
+
const originValue = origin.valueMap.get(atom.key);
|
|
809
|
+
const targetValue = target.valueMap.get(atom.key);
|
|
810
|
+
if (originValue === targetValue) {
|
|
811
|
+
origin.logger.info(`\u{1F4C3}`, `atom`, `${atom.key}`, `copying`);
|
|
812
|
+
const jsonValue = transform.toJson(originValue);
|
|
813
|
+
const copiedValue = transform.fromJson(jsonValue);
|
|
814
|
+
target.valueMap.set(atom.key, copiedValue);
|
|
815
|
+
new Tracker(atom, origin);
|
|
816
|
+
return copiedValue;
|
|
817
|
+
}
|
|
818
|
+
return targetValue;
|
|
819
|
+
}
|
|
820
|
+
|
|
821
|
+
// src/set-state/copy-mutable-in-transaction.ts
|
|
822
|
+
function copyMutableIfWithinTransaction(oldValue, atom, store) {
|
|
823
|
+
const target = newest(store);
|
|
824
|
+
const parent = target.parent;
|
|
825
|
+
if (parent !== null) {
|
|
826
|
+
if (`toJson` in atom && `fromJson` in atom) {
|
|
827
|
+
const copiedValue = copyMutableIfNeeded(atom, atom, parent, target);
|
|
828
|
+
return copiedValue;
|
|
743
829
|
}
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
830
|
+
if (`family` in atom) {
|
|
831
|
+
const family = parent.families.get(atom.family.key);
|
|
832
|
+
if (family && family.type === `atom_family`) {
|
|
833
|
+
const result = copyMutableFamilyMemberWithinTransaction(
|
|
834
|
+
atom,
|
|
835
|
+
family,
|
|
836
|
+
parent,
|
|
837
|
+
target
|
|
838
|
+
);
|
|
839
|
+
if (result) {
|
|
840
|
+
return result;
|
|
841
|
+
}
|
|
749
842
|
}
|
|
750
|
-
break;
|
|
751
843
|
}
|
|
752
844
|
}
|
|
753
|
-
|
|
754
|
-
|
|
845
|
+
return oldValue;
|
|
846
|
+
}
|
|
847
|
+
function copyMutableFamilyMemberWithinTransaction(atom, family, origin, target) {
|
|
848
|
+
if (`toJson` in family && `fromJson` in family) {
|
|
849
|
+
const copyCreated = copyMutableIfNeeded(atom, family, origin, target);
|
|
850
|
+
return copyCreated;
|
|
755
851
|
}
|
|
756
|
-
|
|
757
|
-
|
|
852
|
+
return null;
|
|
853
|
+
}
|
|
854
|
+
|
|
855
|
+
// src/set-state/emit-update.ts
|
|
856
|
+
var emitUpdate = (state, update, store) => {
|
|
758
857
|
store.logger.info(
|
|
759
|
-
`\
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
`
|
|
858
|
+
`\u{1F4E2}`,
|
|
859
|
+
state.type,
|
|
860
|
+
state.key,
|
|
861
|
+
`went (`,
|
|
862
|
+
update.oldValue,
|
|
863
|
+
`->`,
|
|
864
|
+
update.newValue,
|
|
865
|
+
`) subscribers:`,
|
|
866
|
+
state.subject.subscribers
|
|
763
867
|
);
|
|
868
|
+
state.subject.next(update);
|
|
764
869
|
};
|
|
765
870
|
|
|
766
|
-
// src/
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
871
|
+
// src/set-state/evict-downstream.ts
|
|
872
|
+
var evictDownStream = (atom, store) => {
|
|
873
|
+
const target = newest(store);
|
|
874
|
+
const downstreamKeys = target.selectorAtoms.getRelatedKeys(atom.key);
|
|
875
|
+
store.logger.info(
|
|
876
|
+
`\u{1F9F9}`,
|
|
877
|
+
atom.type,
|
|
878
|
+
atom.key,
|
|
879
|
+
downstreamKeys ? `evicting ${downstreamKeys.size} states downstream:` : `no downstream states`,
|
|
880
|
+
downstreamKeys != null ? downstreamKeys : `to evict`
|
|
881
|
+
);
|
|
882
|
+
if (downstreamKeys) {
|
|
883
|
+
if (target.operation.open) {
|
|
778
884
|
store.logger.info(
|
|
779
|
-
`\u{
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
`
|
|
885
|
+
`\u{1F9F9}`,
|
|
886
|
+
atom.type,
|
|
887
|
+
atom.key,
|
|
888
|
+
`[ ${[...target.operation.done].join(`, `)} ] already done`
|
|
783
889
|
);
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
const stateKey = state.key;
|
|
789
|
-
const familyKey = (_i = state.family) == null ? void 0 : _i.key;
|
|
790
|
-
let timelineKey = core.timelineAtoms.getRelatedKey(stateKey);
|
|
791
|
-
if (timelineKey === void 0 && typeof familyKey === `string`) {
|
|
792
|
-
timelineKey = core.timelineAtoms.getRelatedKey(familyKey);
|
|
793
|
-
}
|
|
794
|
-
const timeline = typeof timelineKey === `string` ? store.timelines.get(timelineKey) : void 0;
|
|
795
|
-
if (timeline) {
|
|
796
|
-
addAtomToTimeline(state, timeline, store);
|
|
797
|
-
}
|
|
798
|
-
break;
|
|
799
|
-
}
|
|
800
|
-
case `selector`:
|
|
801
|
-
core.selectors.set(token.key, state);
|
|
802
|
-
break;
|
|
803
|
-
case `readonly_selector`:
|
|
804
|
-
core.readonlySelectors.set(token.key, state);
|
|
805
|
-
break;
|
|
806
|
-
case `transaction`:
|
|
807
|
-
core.transactions.set(token.key, state);
|
|
808
|
-
break;
|
|
809
|
-
case `timeline`:
|
|
810
|
-
core.timelines.set(token.key, state);
|
|
811
|
-
break;
|
|
890
|
+
}
|
|
891
|
+
for (const key of downstreamKeys) {
|
|
892
|
+
if (isDone(key, store)) {
|
|
893
|
+
continue;
|
|
812
894
|
}
|
|
813
|
-
|
|
895
|
+
evictCachedValue(key, store);
|
|
896
|
+
markDone(key, store);
|
|
814
897
|
}
|
|
815
898
|
}
|
|
816
|
-
|
|
817
|
-
}
|
|
899
|
+
};
|
|
818
900
|
|
|
819
|
-
// src/
|
|
820
|
-
function
|
|
821
|
-
if (
|
|
822
|
-
|
|
823
|
-
`\u{1F46A}`,
|
|
824
|
-
token.type,
|
|
825
|
-
token.key,
|
|
826
|
-
`creating new family member in store "${store.config.name}"`
|
|
827
|
-
);
|
|
828
|
-
const core = target(store);
|
|
829
|
-
const family = core.families.get(token.family.key);
|
|
830
|
-
if (family) {
|
|
831
|
-
const jsonSubKey = JSON.parse(token.family.subKey);
|
|
832
|
-
family(jsonSubKey);
|
|
833
|
-
const state = withdraw(token, store);
|
|
834
|
-
return state;
|
|
835
|
-
}
|
|
901
|
+
// src/set-state/stow-update.ts
|
|
902
|
+
function shouldUpdateBeStowed(key, update) {
|
|
903
|
+
if (isTransceiver(update.newValue)) {
|
|
904
|
+
return false;
|
|
836
905
|
}
|
|
837
|
-
|
|
906
|
+
if (key.includes(`\u{1F441}\u200D\u{1F5E8}`)) {
|
|
907
|
+
return false;
|
|
908
|
+
}
|
|
909
|
+
return true;
|
|
838
910
|
}
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
if (
|
|
843
|
-
store.logger.
|
|
911
|
+
var stowUpdate = (state, update, store) => {
|
|
912
|
+
const { key } = state;
|
|
913
|
+
const target = newest(store);
|
|
914
|
+
if (target.transactionMeta === null || target.transactionMeta.phase !== `building`) {
|
|
915
|
+
store.logger.error(
|
|
844
916
|
`\u{1F41E}`,
|
|
845
|
-
`
|
|
846
|
-
|
|
847
|
-
`
|
|
917
|
+
`atom`,
|
|
918
|
+
key,
|
|
919
|
+
`stowUpdate called outside of a transaction. This is probably a bug.`
|
|
848
920
|
);
|
|
849
921
|
return;
|
|
850
922
|
}
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
store.logger.info(
|
|
855
|
-
`\u{1F6C4}`,
|
|
856
|
-
`transaction`,
|
|
857
|
-
store.transactionStatus.key,
|
|
858
|
-
`Applying transaction with ${atomUpdates.length} updates:`,
|
|
859
|
-
atomUpdates
|
|
860
|
-
);
|
|
861
|
-
for (const { key, newValue } of atomUpdates) {
|
|
862
|
-
const token = { key, type: `atom` };
|
|
863
|
-
if (!store.valueMap.has(token.key)) {
|
|
864
|
-
if (token.family) {
|
|
865
|
-
const family = store.families.get(token.family.key);
|
|
866
|
-
if (family) {
|
|
867
|
-
family(token.family.subKey);
|
|
868
|
-
}
|
|
869
|
-
} else {
|
|
870
|
-
const newAtom = store.transactionStatus.core.atoms.get(token.key);
|
|
871
|
-
if (!newAtom) {
|
|
872
|
-
throw new Error(
|
|
873
|
-
`Absurd Error: Atom "${token.key}" not found while copying updates from transaction "${store.transactionStatus.key}" to store "${store.config.name}"`
|
|
874
|
-
);
|
|
875
|
-
}
|
|
876
|
-
store.atoms.set(newAtom.key, newAtom);
|
|
877
|
-
store.valueMap.set(newAtom.key, newAtom.default);
|
|
878
|
-
store.logger.info(
|
|
879
|
-
`\u{1F528}`,
|
|
880
|
-
`transaction`,
|
|
881
|
-
store.transactionStatus.key,
|
|
882
|
-
`Adding atom "${newAtom.key}"`
|
|
883
|
-
);
|
|
884
|
-
}
|
|
885
|
-
}
|
|
886
|
-
setState(token, newValue, store);
|
|
923
|
+
const shouldStow = shouldUpdateBeStowed(key, update);
|
|
924
|
+
if (!shouldStow) {
|
|
925
|
+
return;
|
|
887
926
|
}
|
|
888
|
-
const
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
);
|
|
892
|
-
if (myTransaction === void 0) {
|
|
893
|
-
throw new Error(
|
|
894
|
-
`Transaction "${store.transactionStatus.key}" not found. Absurd. How is this running?`
|
|
895
|
-
);
|
|
927
|
+
const atomUpdate = __spreadValues({ key }, update);
|
|
928
|
+
if (state.family) {
|
|
929
|
+
atomUpdate.family = state.family;
|
|
896
930
|
}
|
|
897
|
-
|
|
898
|
-
key: store.transactionStatus.key,
|
|
899
|
-
atomUpdates,
|
|
900
|
-
output,
|
|
901
|
-
params: store.transactionStatus.params
|
|
902
|
-
});
|
|
931
|
+
target.transactionMeta.update.updates.push(atomUpdate);
|
|
903
932
|
store.logger.info(
|
|
904
|
-
`\u{
|
|
905
|
-
`
|
|
906
|
-
|
|
907
|
-
`
|
|
933
|
+
`\u{1F4C1}`,
|
|
934
|
+
`atom`,
|
|
935
|
+
key,
|
|
936
|
+
`stowed (`,
|
|
937
|
+
update.oldValue,
|
|
938
|
+
`->`,
|
|
939
|
+
update.newValue,
|
|
940
|
+
`)`
|
|
908
941
|
);
|
|
909
|
-
store.transactionStatus = { phase: `idle` };
|
|
910
942
|
};
|
|
911
943
|
|
|
912
|
-
// src/
|
|
913
|
-
var
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
}
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
return super.get(key);
|
|
923
|
-
}
|
|
924
|
-
if (!this.deleted.has(key) && this.source.has(key)) {
|
|
925
|
-
const value = this.source.get(key);
|
|
926
|
-
super.set(key, value);
|
|
927
|
-
return value;
|
|
928
|
-
}
|
|
929
|
-
return void 0;
|
|
930
|
-
}
|
|
931
|
-
_has(key) {
|
|
932
|
-
return super.has(key);
|
|
944
|
+
// src/set-state/set-atom.ts
|
|
945
|
+
var setAtom = (atom, next, store) => {
|
|
946
|
+
const target = newest(store);
|
|
947
|
+
const oldValue = readOrComputeValue(atom, store);
|
|
948
|
+
let newValue = copyMutableIfWithinTransaction(oldValue, atom, store);
|
|
949
|
+
newValue = become(next)(newValue);
|
|
950
|
+
store.logger.info(`\u{1F4DD}`, `atom`, atom.key, `set to`, newValue);
|
|
951
|
+
newValue = cacheValue(atom.key, newValue, atom.subject, store);
|
|
952
|
+
if (isAtomDefault(atom.key, store)) {
|
|
953
|
+
markAtomAsNotDefault(atom.key, store);
|
|
933
954
|
}
|
|
934
|
-
|
|
935
|
-
|
|
955
|
+
markDone(atom.key, store);
|
|
956
|
+
evictDownStream(atom, store);
|
|
957
|
+
const update = { oldValue, newValue };
|
|
958
|
+
if (target.transactionMeta === null || target.transactionMeta.phase === `applying`) {
|
|
959
|
+
emitUpdate(atom, update, store);
|
|
960
|
+
} else {
|
|
961
|
+
stowUpdate(atom, update, store);
|
|
936
962
|
}
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
963
|
+
};
|
|
964
|
+
|
|
965
|
+
// src/set-state/set-atom-or-selector.ts
|
|
966
|
+
var setAtomOrSelector = (state, value, store) => {
|
|
967
|
+
if (state.type === `selector`) {
|
|
968
|
+
state.set(value);
|
|
969
|
+
} else {
|
|
970
|
+
setAtom(state, value, store);
|
|
940
971
|
}
|
|
941
972
|
};
|
|
942
973
|
|
|
943
|
-
// src/
|
|
944
|
-
var
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
operation: { open: false },
|
|
954
|
-
readonlySelectors: new LazyMap(store.readonlySelectors),
|
|
955
|
-
timelines: new LazyMap(store.timelines),
|
|
956
|
-
timelineAtoms: new Junction(store.timelineAtoms.toJSON()),
|
|
957
|
-
trackers: /* @__PURE__ */ new Map(),
|
|
958
|
-
transactions: new LazyMap(store.transactions),
|
|
959
|
-
selectorAtoms: new Junction(store.selectorAtoms.toJSON()),
|
|
960
|
-
selectorGraph: new Junction(store.selectorGraph.toJSON(), {
|
|
961
|
-
makeContentKey: (...keys) => keys.sort().join(`:`)
|
|
962
|
-
}),
|
|
963
|
-
selectors: new LazyMap(store.selectors),
|
|
964
|
-
valueMap: new LazyMap(store.valueMap)
|
|
965
|
-
},
|
|
966
|
-
atomUpdates: [],
|
|
967
|
-
params,
|
|
968
|
-
output: void 0
|
|
969
|
-
};
|
|
970
|
-
store.logger.info(
|
|
971
|
-
`\u{1F6EB}`,
|
|
972
|
-
`transaction`,
|
|
973
|
-
key,
|
|
974
|
-
`Building transaction with params:`,
|
|
975
|
-
params
|
|
976
|
-
);
|
|
974
|
+
// src/keys.ts
|
|
975
|
+
var isAtomKey = (key, store) => newest(store).atoms.has(key);
|
|
976
|
+
var isSelectorKey = (key, store) => newest(store).selectors.has(key);
|
|
977
|
+
var isReadonlySelectorKey = (key, store) => newest(store).readonlySelectors.has(key);
|
|
978
|
+
var isStateKey = (key, store) => isAtomKey(key, store) || isSelectorKey(key, store) || isReadonlySelectorKey(key, store);
|
|
979
|
+
|
|
980
|
+
// src/selector/get-selector-dependency-keys.ts
|
|
981
|
+
var getSelectorDependencyKeys = (key, store) => {
|
|
982
|
+
const sources = newest(store).selectorGraph.getRelationEntries({ downstreamSelectorKey: key }).filter(([_, { source }]) => source !== key).map(([_, { source }]) => source).filter((source) => isStateKey(source, store));
|
|
983
|
+
return sources;
|
|
977
984
|
};
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
);
|
|
992
|
-
applyTransaction(output, store);
|
|
993
|
-
return output;
|
|
994
|
-
} catch (thrown) {
|
|
995
|
-
abortTransaction(store);
|
|
996
|
-
store.logger.warn(`\u{1F4A5}`, `transaction`, options.key, `caught:`, thrown);
|
|
997
|
-
throw thrown;
|
|
998
|
-
}
|
|
999
|
-
},
|
|
1000
|
-
install: (store2) => createTransaction(options, store2),
|
|
1001
|
-
subject: new Subject()
|
|
1002
|
-
};
|
|
1003
|
-
const core = target(store);
|
|
1004
|
-
core.transactions.set(newTransaction.key, newTransaction);
|
|
1005
|
-
const token = deposit(newTransaction);
|
|
1006
|
-
store.subject.transactionCreation.next(token);
|
|
1007
|
-
return token;
|
|
1008
|
-
}
|
|
1009
|
-
var target = (store) => store.transactionStatus.phase === `building` ? store.transactionStatus.core : store;
|
|
1010
|
-
var redoTransactionUpdate = (update, store) => {
|
|
1011
|
-
store.logger.info(`\u23ED\uFE0F`, `transaction`, update.key, `Redo`);
|
|
1012
|
-
for (const { key, newValue } of update.atomUpdates) {
|
|
1013
|
-
const token = { key, type: `atom` };
|
|
1014
|
-
const state = withdraw(token, store);
|
|
1015
|
-
if (state === void 0) {
|
|
985
|
+
|
|
986
|
+
// src/selector/trace-selector-atoms.ts
|
|
987
|
+
var traceSelectorAtoms = (selectorKey, directDependencyKey, store) => {
|
|
988
|
+
const rootKeys = [];
|
|
989
|
+
const indirectDependencyKeys = getSelectorDependencyKeys(
|
|
990
|
+
directDependencyKey,
|
|
991
|
+
store
|
|
992
|
+
);
|
|
993
|
+
let depth = 0;
|
|
994
|
+
while (indirectDependencyKeys.length > 0) {
|
|
995
|
+
const indirectDependencyKey = indirectDependencyKeys.shift();
|
|
996
|
+
++depth;
|
|
997
|
+
if (depth > 99999) {
|
|
1016
998
|
throw new Error(
|
|
1017
|
-
`
|
|
999
|
+
`Maximum selector dependency depth exceeded (> 99999) in selector "${selectorKey}". This is likely due to a circular dependency.`
|
|
1000
|
+
);
|
|
1001
|
+
}
|
|
1002
|
+
if (!isAtomKey(indirectDependencyKey, store)) {
|
|
1003
|
+
indirectDependencyKeys.push(
|
|
1004
|
+
...getSelectorDependencyKeys(indirectDependencyKey, store)
|
|
1018
1005
|
);
|
|
1006
|
+
} else if (!rootKeys.includes(indirectDependencyKey)) {
|
|
1007
|
+
rootKeys.push(indirectDependencyKey);
|
|
1019
1008
|
}
|
|
1020
|
-
setState(state, newValue, store);
|
|
1021
1009
|
}
|
|
1010
|
+
return rootKeys;
|
|
1022
1011
|
};
|
|
1023
|
-
var
|
|
1024
|
-
store
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
update.key,
|
|
1028
|
-
`Undoing transaction update`,
|
|
1029
|
-
update
|
|
1012
|
+
var traceAllSelectorAtoms = (selectorKey, store) => {
|
|
1013
|
+
const directDependencyKeys = getSelectorDependencyKeys(selectorKey, store);
|
|
1014
|
+
return directDependencyKeys.flatMap(
|
|
1015
|
+
(depKey) => isAtomKey(depKey, store) ? depKey : traceSelectorAtoms(selectorKey, depKey, store)
|
|
1030
1016
|
);
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1017
|
+
};
|
|
1018
|
+
|
|
1019
|
+
// src/selector/update-selector-atoms.ts
|
|
1020
|
+
var updateSelectorAtoms = (selectorKey, dependency, store) => {
|
|
1021
|
+
const core = newest(store);
|
|
1022
|
+
if (dependency.type === `atom`) {
|
|
1023
|
+
core.selectorAtoms = core.selectorAtoms.set({
|
|
1024
|
+
selectorKey,
|
|
1025
|
+
atomKey: dependency.key
|
|
1026
|
+
});
|
|
1027
|
+
store.logger.info(
|
|
1028
|
+
`\u{1F50D}`,
|
|
1029
|
+
`selector`,
|
|
1030
|
+
selectorKey,
|
|
1031
|
+
`discovers root atom "${dependency.key}"`
|
|
1032
|
+
);
|
|
1033
|
+
} else {
|
|
1034
|
+
const rootKeys = traceSelectorAtoms(selectorKey, dependency.key, store);
|
|
1035
|
+
store.logger.info(
|
|
1036
|
+
`\u{1F50D}`,
|
|
1037
|
+
`selector`,
|
|
1038
|
+
selectorKey,
|
|
1039
|
+
`discovers root atoms: [ ${rootKeys.map((key) => `"${key}"`).join(`, `)} ]`
|
|
1040
|
+
);
|
|
1041
|
+
for (const atomKey of rootKeys) {
|
|
1042
|
+
core.selectorAtoms = core.selectorAtoms.set({
|
|
1043
|
+
selectorKey,
|
|
1044
|
+
atomKey
|
|
1045
|
+
});
|
|
1046
|
+
}
|
|
1047
|
+
}
|
|
1048
|
+
};
|
|
1049
|
+
|
|
1050
|
+
// src/selector/register-selector.ts
|
|
1051
|
+
var registerSelector = (selectorKey, store) => ({
|
|
1052
|
+
get: (dependency) => {
|
|
1053
|
+
const target = newest(store);
|
|
1054
|
+
const alreadyRegistered = target.selectorGraph.getRelationEntries({ downstreamSelectorKey: selectorKey }).some(([_, { source }]) => source === dependency.key);
|
|
1055
|
+
const dependencyState = withdraw(dependency, store);
|
|
1056
|
+
if (dependencyState === void 0) {
|
|
1057
|
+
throw new Error(
|
|
1058
|
+
`State "${dependency.key}" not found in this store. Did you forget to initialize with the "atom" or "selector" function?`
|
|
1059
|
+
);
|
|
1060
|
+
}
|
|
1061
|
+
const dependencyValue = readOrComputeValue(dependencyState, store);
|
|
1062
|
+
store.logger.info(
|
|
1063
|
+
`\u{1F50C}`,
|
|
1064
|
+
`selector`,
|
|
1065
|
+
selectorKey,
|
|
1066
|
+
`registers dependency ( "${dependency.key}" =`,
|
|
1067
|
+
dependencyValue,
|
|
1068
|
+
`)`
|
|
1069
|
+
);
|
|
1070
|
+
if (!alreadyRegistered) {
|
|
1071
|
+
target.selectorGraph = target.selectorGraph.set(
|
|
1072
|
+
{
|
|
1073
|
+
upstreamSelectorKey: dependency.key,
|
|
1074
|
+
downstreamSelectorKey: selectorKey
|
|
1075
|
+
},
|
|
1076
|
+
{
|
|
1077
|
+
source: dependency.key
|
|
1078
|
+
}
|
|
1079
|
+
);
|
|
1080
|
+
}
|
|
1081
|
+
updateSelectorAtoms(selectorKey, dependency, store);
|
|
1082
|
+
return dependencyValue;
|
|
1083
|
+
},
|
|
1084
|
+
set: (stateToken, newValue) => {
|
|
1085
|
+
const state = withdraw(stateToken, store);
|
|
1034
1086
|
if (state === void 0) {
|
|
1035
1087
|
throw new Error(
|
|
1036
|
-
`State "${
|
|
1088
|
+
`State "${stateToken.key}" not found in this store. Did you forget to initialize with the "atom" or "selector" function?`
|
|
1037
1089
|
);
|
|
1038
1090
|
}
|
|
1039
|
-
|
|
1091
|
+
setAtomOrSelector(state, newValue, store);
|
|
1092
|
+
}
|
|
1093
|
+
});
|
|
1094
|
+
|
|
1095
|
+
// src/selector/create-read-write-selector.ts
|
|
1096
|
+
var createReadWriteSelector = (options, family, store) => {
|
|
1097
|
+
const target = newest(store);
|
|
1098
|
+
const subject = new Subject();
|
|
1099
|
+
const { get, set } = registerSelector(options.key, store);
|
|
1100
|
+
const getSelf = () => {
|
|
1101
|
+
const value = options.get({ get });
|
|
1102
|
+
cacheValue(options.key, value, subject, store);
|
|
1103
|
+
return value;
|
|
1104
|
+
};
|
|
1105
|
+
const setSelf = (next) => {
|
|
1106
|
+
const oldValue = getSelf();
|
|
1107
|
+
const newValue = become(next)(oldValue);
|
|
1108
|
+
store.logger.info(
|
|
1109
|
+
`\u{1F4DD}`,
|
|
1110
|
+
`selector`,
|
|
1111
|
+
options.key,
|
|
1112
|
+
`set (`,
|
|
1113
|
+
oldValue,
|
|
1114
|
+
`->`,
|
|
1115
|
+
newValue,
|
|
1116
|
+
`)`
|
|
1117
|
+
);
|
|
1118
|
+
cacheValue(options.key, newValue, subject, store);
|
|
1119
|
+
markDone(options.key, store);
|
|
1120
|
+
if (target.transactionMeta === null) {
|
|
1121
|
+
subject.next({ newValue, oldValue });
|
|
1122
|
+
}
|
|
1123
|
+
options.set({ get, set }, newValue);
|
|
1124
|
+
};
|
|
1125
|
+
const mySelector = __spreadValues(__spreadProps(__spreadValues({}, options), {
|
|
1126
|
+
subject,
|
|
1127
|
+
install: (s) => createSelector(options, family, s),
|
|
1128
|
+
get: getSelf,
|
|
1129
|
+
set: setSelf,
|
|
1130
|
+
type: `selector`
|
|
1131
|
+
}), family && { family });
|
|
1132
|
+
target.selectors.set(options.key, mySelector);
|
|
1133
|
+
const initialValue = getSelf();
|
|
1134
|
+
store.logger.info(`\u2728`, mySelector.type, mySelector.key, `=`, initialValue);
|
|
1135
|
+
const token = {
|
|
1136
|
+
key: options.key,
|
|
1137
|
+
type: `selector`
|
|
1138
|
+
};
|
|
1139
|
+
if (family) {
|
|
1140
|
+
token.family = family;
|
|
1040
1141
|
}
|
|
1142
|
+
store.subject.selectorCreation.next(token);
|
|
1143
|
+
return token;
|
|
1041
1144
|
};
|
|
1042
1145
|
|
|
1043
|
-
// src/
|
|
1044
|
-
var
|
|
1146
|
+
// src/selector/create-readonly-selector.ts
|
|
1147
|
+
var createReadonlySelector = (options, family, store) => {
|
|
1148
|
+
const target = newest(store);
|
|
1149
|
+
const subject = new Subject();
|
|
1150
|
+
const { get } = registerSelector(options.key, store);
|
|
1151
|
+
const getSelf = () => {
|
|
1152
|
+
const value = options.get({ get });
|
|
1153
|
+
cacheValue(options.key, value, subject, store);
|
|
1154
|
+
return value;
|
|
1155
|
+
};
|
|
1156
|
+
const readonlySelector = __spreadValues(__spreadProps(__spreadValues({}, options), {
|
|
1157
|
+
subject,
|
|
1158
|
+
install: (s) => createSelector(options, family, s),
|
|
1159
|
+
get: getSelf,
|
|
1160
|
+
type: `readonly_selector`
|
|
1161
|
+
}), family && { family });
|
|
1162
|
+
target.readonlySelectors.set(options.key, readonlySelector);
|
|
1163
|
+
const initialValue = getSelf();
|
|
1164
|
+
store.logger.info(
|
|
1165
|
+
`\u2728`,
|
|
1166
|
+
readonlySelector.type,
|
|
1167
|
+
readonlySelector.key,
|
|
1168
|
+
`=`,
|
|
1169
|
+
initialValue
|
|
1170
|
+
);
|
|
1171
|
+
const token = {
|
|
1172
|
+
key: options.key,
|
|
1173
|
+
type: `readonly_selector`
|
|
1174
|
+
};
|
|
1175
|
+
if (family) {
|
|
1176
|
+
token.family = family;
|
|
1177
|
+
}
|
|
1178
|
+
store.subject.selectorCreation.next(token);
|
|
1179
|
+
return token;
|
|
1180
|
+
};
|
|
1045
1181
|
|
|
1046
|
-
// src/
|
|
1047
|
-
function
|
|
1048
|
-
const
|
|
1049
|
-
|
|
1050
|
-
|
|
1182
|
+
// src/selector/create-selector.ts
|
|
1183
|
+
function createSelector(options, family, store) {
|
|
1184
|
+
const target = newest(store);
|
|
1185
|
+
const existingWritable = target.selectors.get(options.key);
|
|
1186
|
+
const existingReadonly = target.readonlySelectors.get(options.key);
|
|
1187
|
+
if (existingWritable || existingReadonly) {
|
|
1188
|
+
store.logger.error(
|
|
1189
|
+
`\u274C`,
|
|
1190
|
+
existingReadonly ? `readonly_selector` : `selector`,
|
|
1191
|
+
options.key,
|
|
1192
|
+
`Tried to create selector, but it already exists in the store. (Ignore if you are in development using hot module replacement.)`
|
|
1193
|
+
);
|
|
1051
1194
|
}
|
|
1052
|
-
if (
|
|
1053
|
-
|
|
1054
|
-
target(store).valueMap.set(key, future);
|
|
1055
|
-
future.then((resolved) => {
|
|
1056
|
-
if (future.isCanceled) {
|
|
1057
|
-
return;
|
|
1058
|
-
}
|
|
1059
|
-
cacheValue(key, resolved, subject, store);
|
|
1060
|
-
subject.next({ newValue: resolved, oldValue: future });
|
|
1061
|
-
}).catch((thrown) => {
|
|
1062
|
-
if (thrown !== `canceled`) {
|
|
1063
|
-
store.logger.error(`\u{1F4A5}`, `state`, key, `rejected:`, thrown);
|
|
1064
|
-
}
|
|
1065
|
-
});
|
|
1066
|
-
return future;
|
|
1195
|
+
if (`set` in options) {
|
|
1196
|
+
return createReadWriteSelector(options, family, store);
|
|
1067
1197
|
}
|
|
1068
|
-
|
|
1069
|
-
return value;
|
|
1198
|
+
return createReadonlySelector(options, family, store);
|
|
1070
1199
|
}
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
const
|
|
1075
|
-
const
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
store.logger.info(`\u{1F5D1}`, `state`, key, `evicted`);
|
|
1084
|
-
};
|
|
1085
|
-
var Tracker = class {
|
|
1086
|
-
constructor(mutableState, store) {
|
|
1087
|
-
this.unsubscribeFromInnerValue = null;
|
|
1088
|
-
this.mutableState = mutableState;
|
|
1089
|
-
this.latestUpdateState = this.initializeState(mutableState, store);
|
|
1090
|
-
this.observeCore(mutableState, this.latestUpdateState, store);
|
|
1091
|
-
this.updateCore(mutableState, this.latestUpdateState, store);
|
|
1092
|
-
const core = target(store);
|
|
1093
|
-
core.trackers.set(mutableState.key, this);
|
|
1094
|
-
}
|
|
1095
|
-
initializeState(mutableState, store) {
|
|
1096
|
-
const latestUpdateStateKey = `*${mutableState.key}`;
|
|
1097
|
-
deleteAtom({ type: `atom`, key: latestUpdateStateKey }, store);
|
|
1098
|
-
const familyMetaData = mutableState.family ? {
|
|
1099
|
-
key: `*${mutableState.family.key}`,
|
|
1100
|
-
subKey: mutableState.family.subKey
|
|
1101
|
-
} : void 0;
|
|
1102
|
-
const latestUpdateState = createAtom(
|
|
1103
|
-
{
|
|
1104
|
-
key: latestUpdateStateKey,
|
|
1105
|
-
default: null
|
|
1106
|
-
},
|
|
1107
|
-
familyMetaData,
|
|
1108
|
-
store
|
|
1109
|
-
);
|
|
1110
|
-
return latestUpdateState;
|
|
1111
|
-
}
|
|
1112
|
-
observeCore(mutableState, latestUpdateState, store) {
|
|
1113
|
-
const originalInnerValue = getState(mutableState, store);
|
|
1114
|
-
this.unsubscribeFromInnerValue = originalInnerValue.subscribe(
|
|
1115
|
-
`tracker:${store.config.name}:${store.transactionStatus.phase === `idle` ? `main` : store.transactionStatus.key}`,
|
|
1116
|
-
(update) => {
|
|
1117
|
-
const unsubscribe = store.subject.operationStatus.subscribe(
|
|
1118
|
-
mutableState.key,
|
|
1119
|
-
() => {
|
|
1120
|
-
unsubscribe();
|
|
1121
|
-
setState(latestUpdateState, update, store);
|
|
1122
|
-
}
|
|
1123
|
-
);
|
|
1124
|
-
}
|
|
1125
|
-
);
|
|
1126
|
-
subscribe(
|
|
1127
|
-
mutableState,
|
|
1128
|
-
(update) => {
|
|
1129
|
-
var _a;
|
|
1130
|
-
if (update.newValue !== update.oldValue) {
|
|
1131
|
-
(_a = this.unsubscribeFromInnerValue) == null ? void 0 : _a.call(this);
|
|
1132
|
-
this.unsubscribeFromInnerValue = update.newValue.subscribe(
|
|
1133
|
-
`tracker:${store.config.name}:${store.transactionStatus.phase === `idle` ? `main` : store.transactionStatus.key}`,
|
|
1134
|
-
(update2) => {
|
|
1135
|
-
const unsubscribe = store.subject.operationStatus.subscribe(
|
|
1136
|
-
mutableState.key,
|
|
1137
|
-
() => {
|
|
1138
|
-
unsubscribe();
|
|
1139
|
-
setState(latestUpdateState, update2, store);
|
|
1140
|
-
}
|
|
1141
|
-
);
|
|
1142
|
-
}
|
|
1143
|
-
);
|
|
1144
|
-
}
|
|
1145
|
-
},
|
|
1146
|
-
`${store.config.name}: tracker observing inner value`,
|
|
1147
|
-
store
|
|
1148
|
-
);
|
|
1200
|
+
|
|
1201
|
+
// src/selector/delete-selector.ts
|
|
1202
|
+
function deleteSelector(selectorToken, store) {
|
|
1203
|
+
const target = newest(store);
|
|
1204
|
+
const { key } = selectorToken;
|
|
1205
|
+
switch (selectorToken.type) {
|
|
1206
|
+
case `selector`:
|
|
1207
|
+
target.selectors.delete(key);
|
|
1208
|
+
break;
|
|
1209
|
+
case `readonly_selector`:
|
|
1210
|
+
target.readonlySelectors.delete(key);
|
|
1211
|
+
break;
|
|
1149
1212
|
}
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
(update) => {
|
|
1163
|
-
unsubscribe2();
|
|
1164
|
-
setState(
|
|
1165
|
-
mutableState,
|
|
1166
|
-
(transceiver) => {
|
|
1167
|
-
if (update === `redo` && newValue) {
|
|
1168
|
-
transceiver.do(newValue);
|
|
1169
|
-
} else if (update === `undo` && oldValue) {
|
|
1170
|
-
transceiver.undo(oldValue);
|
|
1171
|
-
}
|
|
1172
|
-
return transceiver;
|
|
1173
|
-
},
|
|
1174
|
-
store
|
|
1175
|
-
);
|
|
1176
|
-
}
|
|
1177
|
-
);
|
|
1178
|
-
return;
|
|
1179
|
-
}
|
|
1180
|
-
}
|
|
1181
|
-
const unsubscribe = store.subject.operationStatus.subscribe(
|
|
1182
|
-
latestUpdateState.key,
|
|
1183
|
-
() => {
|
|
1184
|
-
unsubscribe();
|
|
1185
|
-
const mutable = getState(mutableState, store);
|
|
1186
|
-
const updateNumber = mutable.getUpdateNumber(newValue);
|
|
1187
|
-
const eventOffset = updateNumber - mutable.cacheUpdateNumber;
|
|
1188
|
-
if (newValue && eventOffset === 1) {
|
|
1189
|
-
setState(
|
|
1190
|
-
mutableState,
|
|
1191
|
-
(transceiver) => (transceiver.do(newValue), transceiver),
|
|
1192
|
-
store
|
|
1193
|
-
);
|
|
1194
|
-
}
|
|
1195
|
-
}
|
|
1196
|
-
);
|
|
1197
|
-
},
|
|
1198
|
-
`${store.config.name}: tracker observing latest update`,
|
|
1199
|
-
store
|
|
1200
|
-
);
|
|
1213
|
+
target.valueMap.delete(key);
|
|
1214
|
+
target.selectorAtoms.delete(key);
|
|
1215
|
+
const downstreamTokens = target.selectorGraph.getRelationEntries({ upstreamSelectorKey: key }).filter(([_, { source }]) => source === key).map(
|
|
1216
|
+
([downstreamSelectorKey]) => {
|
|
1217
|
+
var _a;
|
|
1218
|
+
return (_a = target.selectors.get(downstreamSelectorKey)) != null ? _a : target.readonlySelectors.get(downstreamSelectorKey);
|
|
1219
|
+
}
|
|
1220
|
+
);
|
|
1221
|
+
for (const downstreamToken of downstreamTokens) {
|
|
1222
|
+
if (downstreamToken) {
|
|
1223
|
+
deleteSelector(downstreamToken, store);
|
|
1224
|
+
}
|
|
1201
1225
|
}
|
|
1202
|
-
|
|
1226
|
+
target.selectorGraph.delete(key);
|
|
1227
|
+
store.logger.info(`\u{1F525}`, selectorToken.type, `${key}`, `deleted`);
|
|
1228
|
+
}
|
|
1203
1229
|
|
|
1204
|
-
// src/
|
|
1205
|
-
function
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
jsonState,
|
|
1217
|
-
() => {
|
|
1218
|
-
const trackerHasBeenInitialized = target(store).trackers.has(coreState.key);
|
|
1219
|
-
if (!trackerHasBeenInitialized) {
|
|
1220
|
-
new Tracker(coreState, store);
|
|
1230
|
+
// src/families/create-readonly-selector-family.ts
|
|
1231
|
+
function createReadonlySelectorFamily(options, store) {
|
|
1232
|
+
const subject = new Subject();
|
|
1233
|
+
return Object.assign(
|
|
1234
|
+
(key) => {
|
|
1235
|
+
const target = newest(store);
|
|
1236
|
+
const subKey = stringifyJson(key);
|
|
1237
|
+
const family = { key: options.key, subKey };
|
|
1238
|
+
const fullKey = `${options.key}(${subKey})`;
|
|
1239
|
+
const existing = target.readonlySelectors.get(fullKey);
|
|
1240
|
+
if (existing) {
|
|
1241
|
+
return deposit(existing);
|
|
1221
1242
|
}
|
|
1243
|
+
return createSelector(
|
|
1244
|
+
{
|
|
1245
|
+
key: fullKey,
|
|
1246
|
+
get: options.get(key)
|
|
1247
|
+
},
|
|
1248
|
+
family,
|
|
1249
|
+
store
|
|
1250
|
+
);
|
|
1222
1251
|
},
|
|
1223
|
-
|
|
1252
|
+
{
|
|
1253
|
+
key: options.key,
|
|
1254
|
+
type: `readonly_selector_family`,
|
|
1255
|
+
subject
|
|
1256
|
+
}
|
|
1224
1257
|
);
|
|
1225
|
-
return coreState;
|
|
1226
1258
|
}
|
|
1227
|
-
function
|
|
1259
|
+
function createSelectorFamily(options, store) {
|
|
1260
|
+
const isReadonly = !(`set` in options);
|
|
1261
|
+
if (isReadonly) {
|
|
1262
|
+
return createReadonlySelectorFamily(options, store);
|
|
1263
|
+
}
|
|
1264
|
+
const target = newest(store);
|
|
1228
1265
|
const subject = new Subject();
|
|
1229
|
-
const
|
|
1266
|
+
const selectorFamily = Object.assign(
|
|
1230
1267
|
(key) => {
|
|
1231
1268
|
const subKey = stringifyJson(key);
|
|
1232
1269
|
const family = { key: options.key, subKey };
|
|
1233
1270
|
const fullKey = `${options.key}(${subKey})`;
|
|
1234
|
-
const existing =
|
|
1235
|
-
let token;
|
|
1271
|
+
const existing = target.selectors.get(fullKey);
|
|
1236
1272
|
if (existing) {
|
|
1237
|
-
|
|
1238
|
-
} else {
|
|
1239
|
-
const individualOptions = {
|
|
1240
|
-
key: fullKey,
|
|
1241
|
-
default: options.default instanceof Function ? options.default(key) : options.default
|
|
1242
|
-
};
|
|
1243
|
-
if (options.effects) {
|
|
1244
|
-
individualOptions.effects = options.effects(key);
|
|
1245
|
-
}
|
|
1246
|
-
token = createAtom(individualOptions, family, store);
|
|
1247
|
-
subject.next(token);
|
|
1273
|
+
return deposit(existing);
|
|
1248
1274
|
}
|
|
1275
|
+
const token = createSelector(
|
|
1276
|
+
{
|
|
1277
|
+
key: fullKey,
|
|
1278
|
+
get: options.get(key),
|
|
1279
|
+
set: options.set(key)
|
|
1280
|
+
},
|
|
1281
|
+
family,
|
|
1282
|
+
store
|
|
1283
|
+
);
|
|
1284
|
+
subject.next(token);
|
|
1249
1285
|
return token;
|
|
1250
1286
|
},
|
|
1251
1287
|
{
|
|
1252
1288
|
key: options.key,
|
|
1253
|
-
type: `
|
|
1254
|
-
subject
|
|
1289
|
+
type: `selector_family`
|
|
1255
1290
|
}
|
|
1256
1291
|
);
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
return atomFamily;
|
|
1292
|
+
target.families.set(options.key, selectorFamily);
|
|
1293
|
+
return selectorFamily;
|
|
1260
1294
|
}
|
|
1261
1295
|
|
|
1262
|
-
// src/
|
|
1263
|
-
var
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1296
|
+
// src/mutable/tracker-family.ts
|
|
1297
|
+
var FamilyTracker = class {
|
|
1298
|
+
constructor(findMutableState, store) {
|
|
1299
|
+
this.findLatestUpdateState = createAtomFamily(
|
|
1300
|
+
{
|
|
1301
|
+
key: `*${findMutableState.key}`,
|
|
1302
|
+
default: null
|
|
1303
|
+
},
|
|
1304
|
+
store
|
|
1271
1305
|
);
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
`\u2B55`,
|
|
1283
|
-
token.type,
|
|
1284
|
-
token.key,
|
|
1285
|
-
`operation start in store "${store.config.name}"${store.transactionStatus.phase === `idle` ? `` : ` ${store.transactionStatus.phase} "${store.transactionStatus.key}"`}`
|
|
1286
|
-
);
|
|
1287
|
-
};
|
|
1288
|
-
var closeOperation = (store) => {
|
|
1289
|
-
const core = target(store);
|
|
1290
|
-
if (core.operation.open) {
|
|
1291
|
-
store.logger.info(
|
|
1292
|
-
`\u{1F534}`,
|
|
1293
|
-
core.operation.token.type,
|
|
1294
|
-
core.operation.token.key,
|
|
1295
|
-
`operation done in store "${store.config.name}"`
|
|
1306
|
+
this.findMutableState = findMutableState;
|
|
1307
|
+
this.findMutableState.subject.subscribe(
|
|
1308
|
+
`store=${store.config.name}::tracker-atom-family`,
|
|
1309
|
+
(atomToken) => {
|
|
1310
|
+
if (atomToken.family) {
|
|
1311
|
+
const key = parseJson(atomToken.family.subKey);
|
|
1312
|
+
this.findLatestUpdateState(key);
|
|
1313
|
+
new Tracker(atomToken, store);
|
|
1314
|
+
}
|
|
1315
|
+
}
|
|
1296
1316
|
);
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
`unknown`,
|
|
1307
|
-
key,
|
|
1308
|
-
`isDone called outside of an operation. This is probably a bug.`
|
|
1309
|
-
);
|
|
1310
|
-
return true;
|
|
1311
|
-
}
|
|
1312
|
-
return core.operation.done.has(key);
|
|
1313
|
-
};
|
|
1314
|
-
var markDone = (key, store) => {
|
|
1315
|
-
const core = target(store);
|
|
1316
|
-
if (!core.operation.open) {
|
|
1317
|
-
store.logger.warn(
|
|
1318
|
-
`\u{1F41E}`,
|
|
1319
|
-
`unknown`,
|
|
1320
|
-
key,
|
|
1321
|
-
`markDone called outside of an operation. This is probably a bug.`
|
|
1317
|
+
this.findLatestUpdateState.subject.subscribe(
|
|
1318
|
+
`store=${store.config.name}::tracker-atom-family`,
|
|
1319
|
+
(atomToken) => {
|
|
1320
|
+
if (atomToken.family) {
|
|
1321
|
+
const key = parseJson(atomToken.family.subKey);
|
|
1322
|
+
const mutableAtomToken = this.findMutableState(key);
|
|
1323
|
+
new Tracker(mutableAtomToken, store);
|
|
1324
|
+
}
|
|
1325
|
+
}
|
|
1322
1326
|
);
|
|
1323
|
-
return;
|
|
1324
1327
|
}
|
|
1325
|
-
core.operation.done.add(key);
|
|
1326
1328
|
};
|
|
1327
1329
|
|
|
1328
|
-
// src/
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
)
|
|
1330
|
+
// src/mutable/create-mutable-atom-family.ts
|
|
1331
|
+
function createMutableAtomFamily(options, store) {
|
|
1332
|
+
const coreFamily = Object.assign(
|
|
1333
|
+
createAtomFamily(options, store),
|
|
1334
|
+
options
|
|
1335
|
+
);
|
|
1336
|
+
selectJsonFamily(coreFamily, options);
|
|
1337
|
+
new FamilyTracker(coreFamily, store);
|
|
1338
|
+
return coreFamily;
|
|
1339
|
+
}
|
|
1332
1340
|
|
|
1333
|
-
// src/
|
|
1334
|
-
var
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
if (state.type !== `atom`) {
|
|
1340
|
-
store.logger.info(`\u{1F9EE}`, state.type, state.key, `computing value`);
|
|
1341
|
-
return state.get();
|
|
1342
|
-
}
|
|
1343
|
-
const fallback = state.default instanceof Function ? state.default() : state.default;
|
|
1344
|
-
store.logger.info(
|
|
1345
|
-
`\u{1F481}`,
|
|
1346
|
-
`atom`,
|
|
1347
|
-
state.key,
|
|
1348
|
-
`could not find cached value; using default`,
|
|
1349
|
-
fallback
|
|
1341
|
+
// src/mutable/get-json-family.ts
|
|
1342
|
+
var getJsonFamily = (mutableAtomFamily, store) => {
|
|
1343
|
+
const target = newest(store);
|
|
1344
|
+
const key = `${mutableAtomFamily.key}:JSON`;
|
|
1345
|
+
const jsonFamily = target.families.get(
|
|
1346
|
+
key
|
|
1350
1347
|
);
|
|
1351
|
-
return
|
|
1348
|
+
return jsonFamily;
|
|
1352
1349
|
};
|
|
1353
1350
|
|
|
1354
|
-
// src/
|
|
1355
|
-
|
|
1356
|
-
const
|
|
1357
|
-
const
|
|
1358
|
-
if (
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
return copiedValue;
|
|
1351
|
+
// src/mutable/get-json-token.ts
|
|
1352
|
+
var getJsonToken = (mutableAtomToken) => {
|
|
1353
|
+
const key = mutableAtomToken.family ? `${mutableAtomToken.family.key}:JSON(${mutableAtomToken.family.subKey})` : `${mutableAtomToken.key}:JSON`;
|
|
1354
|
+
const jsonToken = { type: `selector`, key };
|
|
1355
|
+
if (mutableAtomToken.family) {
|
|
1356
|
+
jsonToken.family = {
|
|
1357
|
+
key: `${mutableAtomToken.family.key}:JSON`,
|
|
1358
|
+
subKey: mutableAtomToken.family.subKey
|
|
1359
|
+
};
|
|
1364
1360
|
}
|
|
1365
|
-
return
|
|
1366
|
-
}
|
|
1361
|
+
return jsonToken;
|
|
1362
|
+
};
|
|
1367
1363
|
|
|
1368
|
-
// src/
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
);
|
|
1378
|
-
return copiedValue;
|
|
1379
|
-
}
|
|
1380
|
-
if (`family` in atom) {
|
|
1381
|
-
const family = store.transactionStatus.core.families.get(atom.family.key);
|
|
1382
|
-
if (family && family.type === `atom_family`) {
|
|
1383
|
-
const result = copyMutableFamilyMemberWithinTransaction(
|
|
1384
|
-
atom,
|
|
1385
|
-
family,
|
|
1386
|
-
store,
|
|
1387
|
-
store.transactionStatus.core
|
|
1388
|
-
);
|
|
1389
|
-
if (result) {
|
|
1390
|
-
return result;
|
|
1391
|
-
}
|
|
1392
|
-
}
|
|
1393
|
-
}
|
|
1364
|
+
// src/mutable/get-update-token.ts
|
|
1365
|
+
var getUpdateToken = (mutableAtomToken) => {
|
|
1366
|
+
const key = `*${mutableAtomToken.key}`;
|
|
1367
|
+
const updateToken = { type: `atom`, key };
|
|
1368
|
+
if (mutableAtomToken.family) {
|
|
1369
|
+
updateToken.family = {
|
|
1370
|
+
key: `*${mutableAtomToken.family.key}`,
|
|
1371
|
+
subKey: mutableAtomToken.family.subKey
|
|
1372
|
+
};
|
|
1394
1373
|
}
|
|
1395
|
-
return
|
|
1374
|
+
return updateToken;
|
|
1375
|
+
};
|
|
1376
|
+
|
|
1377
|
+
// src/mutable/is-atom-token-mutable.ts
|
|
1378
|
+
function isAtomTokenMutable(token) {
|
|
1379
|
+
return token.key.endsWith(`::mutable`);
|
|
1396
1380
|
}
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
}
|
|
1402
|
-
return null;
|
|
1381
|
+
|
|
1382
|
+
// src/mutable/transceiver.ts
|
|
1383
|
+
function isTransceiver(value) {
|
|
1384
|
+
return typeof value === `object` && value !== null && `do` in value && `undo` in value && `subscribe` in value;
|
|
1403
1385
|
}
|
|
1404
1386
|
|
|
1405
|
-
// src/
|
|
1406
|
-
var
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1387
|
+
// src/mutable/index.ts
|
|
1388
|
+
var isAtomMutable = (atom) => `isMutable` in atom;
|
|
1389
|
+
|
|
1390
|
+
// src/atom/is-default.ts
|
|
1391
|
+
var isAtomDefault = (key, store) => {
|
|
1392
|
+
const core = newest(store);
|
|
1393
|
+
return core.atomsThatAreDefault.has(key);
|
|
1394
|
+
};
|
|
1395
|
+
var markAtomAsDefault = (key, store) => {
|
|
1396
|
+
const core = newest(store);
|
|
1397
|
+
core.atomsThatAreDefault = new Set(core.atomsThatAreDefault).add(key);
|
|
1398
|
+
};
|
|
1399
|
+
var markAtomAsNotDefault = (key, store) => {
|
|
1400
|
+
const core = newest(store);
|
|
1401
|
+
core.atomsThatAreDefault = new Set(newest(store).atomsThatAreDefault);
|
|
1402
|
+
core.atomsThatAreDefault.delete(key);
|
|
1403
|
+
};
|
|
1404
|
+
var isSelectorDefault = (key, store) => {
|
|
1405
|
+
const rootKeys = traceAllSelectorAtoms(key, store);
|
|
1406
|
+
return rootKeys.every((rootKey) => isAtomDefault(rootKey, store));
|
|
1419
1407
|
};
|
|
1420
1408
|
|
|
1421
|
-
// src/
|
|
1422
|
-
|
|
1423
|
-
const core = target(store);
|
|
1424
|
-
const downstreamKeys = core.selectorAtoms.getRelatedKeys(atom.key);
|
|
1409
|
+
// src/atom/create-atom.ts
|
|
1410
|
+
function createAtom(options, family, store) {
|
|
1425
1411
|
store.logger.info(
|
|
1426
|
-
`\u{
|
|
1427
|
-
atom
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
downstreamKeys != null ? downstreamKeys : `to evict`
|
|
1412
|
+
`\u{1F528}`,
|
|
1413
|
+
`atom`,
|
|
1414
|
+
options.key,
|
|
1415
|
+
`creating in store "${store.config.name}"`
|
|
1431
1416
|
);
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1417
|
+
const target = newest(store);
|
|
1418
|
+
const existing = target.atoms.get(options.key);
|
|
1419
|
+
if (existing) {
|
|
1420
|
+
store.logger.error(
|
|
1421
|
+
`\u274C`,
|
|
1422
|
+
`atom`,
|
|
1423
|
+
options.key,
|
|
1424
|
+
`Tried to create atom, but it already exists in the store.`,
|
|
1425
|
+
`(Ignore if you are in development using hot module replacement.)`
|
|
1426
|
+
);
|
|
1427
|
+
return deposit(existing);
|
|
1428
|
+
}
|
|
1429
|
+
const subject = new Subject();
|
|
1430
|
+
const newAtom = __spreadValues(__spreadProps(__spreadValues({}, options), {
|
|
1431
|
+
type: `atom`,
|
|
1432
|
+
install: (store2) => {
|
|
1433
|
+
store2.logger.info(
|
|
1434
|
+
`\u{1F6E0}\uFE0F`,
|
|
1435
|
+
`atom`,
|
|
1436
|
+
options.key,
|
|
1437
|
+
`installing in store "${store2.config.name}"`
|
|
1439
1438
|
);
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1439
|
+
return `mutable` in options ? createMutableAtom(options, store2) : createAtom(options, void 0, store2);
|
|
1440
|
+
},
|
|
1441
|
+
subject
|
|
1442
|
+
}), family && { family });
|
|
1443
|
+
let initialValue = options.default;
|
|
1444
|
+
if (options.default instanceof Function) {
|
|
1445
|
+
initialValue = options.default();
|
|
1446
|
+
}
|
|
1447
|
+
target.atoms.set(newAtom.key, newAtom);
|
|
1448
|
+
markAtomAsDefault(options.key, store);
|
|
1449
|
+
cacheValue(options.key, initialValue, subject, store);
|
|
1450
|
+
const token = deposit(newAtom);
|
|
1451
|
+
if (options.effects) {
|
|
1452
|
+
let effectIndex = 0;
|
|
1453
|
+
const cleanupFunctions = [];
|
|
1454
|
+
for (const effect of options.effects) {
|
|
1455
|
+
const cleanup = effect({
|
|
1456
|
+
setSelf: (next) => setState(token, next, store),
|
|
1457
|
+
onSet: (handle) => subscribe(token, handle, `effect[${effectIndex}]`, store)
|
|
1458
|
+
});
|
|
1459
|
+
if (cleanup) {
|
|
1460
|
+
cleanupFunctions.push(cleanup);
|
|
1444
1461
|
}
|
|
1445
|
-
|
|
1446
|
-
markDone(key, store);
|
|
1462
|
+
++effectIndex;
|
|
1447
1463
|
}
|
|
1464
|
+
newAtom.cleanup = () => {
|
|
1465
|
+
for (const cleanup of cleanupFunctions) {
|
|
1466
|
+
cleanup();
|
|
1467
|
+
}
|
|
1468
|
+
};
|
|
1448
1469
|
}
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
// src/set-state/stow-update.ts
|
|
1452
|
-
function shouldUpdateBeStowed(key, update) {
|
|
1453
|
-
if (isTransceiver(update.newValue)) {
|
|
1454
|
-
return false;
|
|
1455
|
-
}
|
|
1456
|
-
if (key.includes(`\u{1F441}\u200D\u{1F5E8}`)) {
|
|
1457
|
-
return false;
|
|
1458
|
-
}
|
|
1459
|
-
return true;
|
|
1470
|
+
store.subject.atomCreation.next(token);
|
|
1471
|
+
return token;
|
|
1460
1472
|
}
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1473
|
+
|
|
1474
|
+
// src/atom/delete-atom.ts
|
|
1475
|
+
function deleteAtom(atomToken, store) {
|
|
1476
|
+
var _a, _b;
|
|
1477
|
+
const target = newest(store);
|
|
1478
|
+
const { key } = atomToken;
|
|
1479
|
+
const atom = target.atoms.get(key);
|
|
1480
|
+
if (!atom) {
|
|
1464
1481
|
store.logger.error(
|
|
1465
|
-
`\
|
|
1482
|
+
`\u274C`,
|
|
1466
1483
|
`atom`,
|
|
1467
|
-
key
|
|
1468
|
-
`
|
|
1484
|
+
`${key}`,
|
|
1485
|
+
`Tried to delete atom, but it does not exist in the store.`
|
|
1469
1486
|
);
|
|
1470
|
-
return;
|
|
1471
1487
|
}
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1488
|
+
(_a = atom == null ? void 0 : atom.cleanup) == null ? void 0 : _a.call(atom);
|
|
1489
|
+
target.atoms.delete(key);
|
|
1490
|
+
target.valueMap.delete(key);
|
|
1491
|
+
const selectorKeys = target.selectorAtoms.getRelatedKeys(key);
|
|
1492
|
+
if (selectorKeys) {
|
|
1493
|
+
for (const selectorKey of selectorKeys) {
|
|
1494
|
+
const token = (_b = target.selectors.get(selectorKey)) != null ? _b : target.readonlySelectors.get(selectorKey);
|
|
1495
|
+
if (token) {
|
|
1496
|
+
deleteSelector(token, store);
|
|
1497
|
+
}
|
|
1498
|
+
}
|
|
1479
1499
|
}
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
`stowed (`,
|
|
1486
|
-
update.oldValue,
|
|
1487
|
-
`->`,
|
|
1488
|
-
update.newValue,
|
|
1489
|
-
`)`
|
|
1490
|
-
);
|
|
1491
|
-
};
|
|
1500
|
+
target.selectorAtoms.delete(key);
|
|
1501
|
+
target.atomsThatAreDefault.delete(key);
|
|
1502
|
+
target.timelineAtoms.delete(key);
|
|
1503
|
+
store.logger.info(`\u{1F525}`, `atom`, `${key}`, `deleted`);
|
|
1504
|
+
}
|
|
1492
1505
|
|
|
1493
|
-
// src/
|
|
1494
|
-
var
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
newValue = cacheValue(atom.key, newValue, atom.subject, store);
|
|
1500
|
-
if (isAtomDefault(atom.key, store)) {
|
|
1501
|
-
markAtomAsNotDefault(atom.key, store);
|
|
1506
|
+
// src/lazy-map.ts
|
|
1507
|
+
var LazyMap = class extends Map {
|
|
1508
|
+
constructor(source) {
|
|
1509
|
+
super();
|
|
1510
|
+
this.source = source;
|
|
1511
|
+
this.deleted = /* @__PURE__ */ new Set();
|
|
1502
1512
|
}
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1513
|
+
get(key) {
|
|
1514
|
+
const has = super.has(key);
|
|
1515
|
+
if (has) {
|
|
1516
|
+
return super.get(key);
|
|
1517
|
+
}
|
|
1518
|
+
if (!this.deleted.has(key) && this.source.has(key)) {
|
|
1519
|
+
const value = this.source.get(key);
|
|
1520
|
+
return value;
|
|
1521
|
+
}
|
|
1522
|
+
return void 0;
|
|
1510
1523
|
}
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
}
|
|
1518
|
-
|
|
1524
|
+
set(key, value) {
|
|
1525
|
+
this.deleted.delete(key);
|
|
1526
|
+
return super.set(key, value);
|
|
1527
|
+
}
|
|
1528
|
+
hasOwn(key) {
|
|
1529
|
+
return super.has(key);
|
|
1530
|
+
}
|
|
1531
|
+
has(key) {
|
|
1532
|
+
return !this.deleted.has(key) && (super.has(key) || this.source.has(key));
|
|
1533
|
+
}
|
|
1534
|
+
delete(key) {
|
|
1535
|
+
this.deleted.add(key);
|
|
1536
|
+
return super.delete(key);
|
|
1519
1537
|
}
|
|
1520
1538
|
};
|
|
1521
1539
|
|
|
1522
|
-
// src/
|
|
1523
|
-
var
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
var traceSelectorAtoms = (selectorKey, directDependencyKey, store) => {
|
|
1536
|
-
const rootKeys = [];
|
|
1537
|
-
const indirectDependencyKeys = getSelectorDependencyKeys(
|
|
1538
|
-
directDependencyKey,
|
|
1539
|
-
store
|
|
1540
|
-
);
|
|
1541
|
-
let depth = 0;
|
|
1542
|
-
while (indirectDependencyKeys.length > 0) {
|
|
1543
|
-
const indirectDependencyKey = indirectDependencyKeys.shift();
|
|
1544
|
-
++depth;
|
|
1545
|
-
if (depth > 99999) {
|
|
1546
|
-
throw new Error(
|
|
1547
|
-
`Maximum selector dependency depth exceeded (> 99999) in selector "${selectorKey}". This is likely due to a circular dependency.`
|
|
1548
|
-
);
|
|
1549
|
-
}
|
|
1550
|
-
if (!isAtomKey(indirectDependencyKey, store)) {
|
|
1551
|
-
indirectDependencyKeys.push(
|
|
1552
|
-
...getSelectorDependencyKeys(indirectDependencyKey, store)
|
|
1553
|
-
);
|
|
1554
|
-
} else if (!rootKeys.includes(indirectDependencyKey)) {
|
|
1555
|
-
rootKeys.push(indirectDependencyKey);
|
|
1556
|
-
}
|
|
1540
|
+
// src/not-found-error.ts
|
|
1541
|
+
var capitalize = (str) => str[0].toUpperCase() + str.slice(1);
|
|
1542
|
+
function prettyPrintTokenType(token) {
|
|
1543
|
+
if (token.type === `readonly_selector`) {
|
|
1544
|
+
return `Readonly Selector`;
|
|
1545
|
+
}
|
|
1546
|
+
return capitalize(token.type);
|
|
1547
|
+
}
|
|
1548
|
+
var NotFoundError = class extends Error {
|
|
1549
|
+
constructor(token, store) {
|
|
1550
|
+
super(
|
|
1551
|
+
`${prettyPrintTokenType(token)} "${token.key}" not found in store "${store.config.name}".`
|
|
1552
|
+
);
|
|
1557
1553
|
}
|
|
1558
|
-
return rootKeys;
|
|
1559
|
-
};
|
|
1560
|
-
var traceAllSelectorAtoms = (selectorKey, store) => {
|
|
1561
|
-
const directDependencyKeys = getSelectorDependencyKeys(selectorKey, store);
|
|
1562
|
-
return directDependencyKeys.flatMap(
|
|
1563
|
-
(depKey) => isAtomKey(depKey, store) ? depKey : traceSelectorAtoms(selectorKey, depKey, store)
|
|
1564
|
-
);
|
|
1565
1554
|
};
|
|
1566
1555
|
|
|
1567
|
-
// src/
|
|
1568
|
-
var
|
|
1569
|
-
const
|
|
1570
|
-
if (
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
`\u{1F50D}`,
|
|
1577
|
-
`selector`,
|
|
1578
|
-
selectorKey,
|
|
1579
|
-
`discovers root atom "${dependency.key}"`
|
|
1580
|
-
);
|
|
1581
|
-
} else {
|
|
1582
|
-
const rootKeys = traceSelectorAtoms(selectorKey, dependency.key, store);
|
|
1583
|
-
store.logger.info(
|
|
1584
|
-
`\u{1F50D}`,
|
|
1585
|
-
`selector`,
|
|
1586
|
-
selectorKey,
|
|
1587
|
-
`discovers root atoms: [ ${rootKeys.map((key) => `"${key}"`).join(`, `)} ]`
|
|
1556
|
+
// src/subscribe/recall-state.ts
|
|
1557
|
+
var recallState = (state, store) => {
|
|
1558
|
+
const target = newest(store);
|
|
1559
|
+
if (!target.operation.open) {
|
|
1560
|
+
store.logger.warn(
|
|
1561
|
+
`\u{1F41E}`,
|
|
1562
|
+
state.type,
|
|
1563
|
+
state.key,
|
|
1564
|
+
`recall called outside of an operation. This is probably a bug.`
|
|
1588
1565
|
);
|
|
1589
|
-
|
|
1590
|
-
core.selectorAtoms = core.selectorAtoms.set({
|
|
1591
|
-
selectorKey,
|
|
1592
|
-
atomKey
|
|
1593
|
-
});
|
|
1594
|
-
}
|
|
1566
|
+
return target.valueMap.get(state.key);
|
|
1595
1567
|
}
|
|
1568
|
+
return target.operation.prev.get(state.key);
|
|
1596
1569
|
};
|
|
1597
1570
|
|
|
1598
|
-
// src/
|
|
1599
|
-
var
|
|
1600
|
-
|
|
1601
|
-
const
|
|
1602
|
-
|
|
1603
|
-
const dependencyState = withdraw(dependency, store);
|
|
1604
|
-
if (dependencyState === void 0) {
|
|
1605
|
-
throw new Error(
|
|
1606
|
-
`State "${dependency.key}" not found in this store. Did you forget to initialize with the "atom" or "selector" function?`
|
|
1607
|
-
);
|
|
1608
|
-
}
|
|
1609
|
-
const dependencyValue = readOrComputeValue(dependencyState, store);
|
|
1610
|
-
store.logger.info(
|
|
1611
|
-
`\u{1F50C}`,
|
|
1612
|
-
`selector`,
|
|
1613
|
-
selectorKey,
|
|
1614
|
-
`registers dependency ( "${dependency.key}" =`,
|
|
1615
|
-
dependencyValue,
|
|
1616
|
-
`)`
|
|
1617
|
-
);
|
|
1618
|
-
if (!alreadyRegistered) {
|
|
1619
|
-
core.selectorGraph = core.selectorGraph.set(
|
|
1620
|
-
{
|
|
1621
|
-
upstreamSelectorKey: dependency.key,
|
|
1622
|
-
downstreamSelectorKey: selectorKey
|
|
1623
|
-
},
|
|
1624
|
-
{
|
|
1625
|
-
source: dependency.key
|
|
1626
|
-
}
|
|
1627
|
-
);
|
|
1628
|
-
}
|
|
1629
|
-
updateSelectorAtoms(selectorKey, dependency, store);
|
|
1630
|
-
return dependencyValue;
|
|
1631
|
-
},
|
|
1632
|
-
set: (stateToken, newValue) => {
|
|
1633
|
-
const state = withdraw(stateToken, store);
|
|
1634
|
-
if (state === void 0) {
|
|
1571
|
+
// src/subscribe/subscribe-to-root-atoms.ts
|
|
1572
|
+
var subscribeToRootAtoms = (state, store) => {
|
|
1573
|
+
const dependencySubscriptions = `default` in state ? null : traceAllSelectorAtoms(state.key, store).map((atomKey) => {
|
|
1574
|
+
const atom = store.atoms.get(atomKey);
|
|
1575
|
+
if (atom === void 0) {
|
|
1635
1576
|
throw new Error(
|
|
1636
|
-
`
|
|
1577
|
+
`Atom "${atomKey}", a dependency of selector "${state.key}", not found in store "${store.config.name}".`
|
|
1637
1578
|
);
|
|
1638
1579
|
}
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1580
|
+
return atom.subject.subscribe(
|
|
1581
|
+
`${state.type}:${state.key}`,
|
|
1582
|
+
(atomChange) => {
|
|
1583
|
+
store.logger.info(
|
|
1584
|
+
`\u{1F4E2}`,
|
|
1585
|
+
state.type,
|
|
1586
|
+
state.key,
|
|
1587
|
+
`root`,
|
|
1588
|
+
atomKey,
|
|
1589
|
+
`went`,
|
|
1590
|
+
atomChange.oldValue,
|
|
1591
|
+
`->`,
|
|
1592
|
+
atomChange.newValue
|
|
1593
|
+
);
|
|
1594
|
+
const oldValue = recallState(state, store);
|
|
1595
|
+
const newValue = readOrComputeValue(state, store);
|
|
1596
|
+
store.logger.info(
|
|
1597
|
+
`\u2728`,
|
|
1598
|
+
state.type,
|
|
1599
|
+
state.key,
|
|
1600
|
+
`went`,
|
|
1601
|
+
oldValue,
|
|
1602
|
+
`->`,
|
|
1603
|
+
newValue
|
|
1604
|
+
);
|
|
1605
|
+
state.subject.next({ newValue, oldValue });
|
|
1606
|
+
}
|
|
1664
1607
|
);
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
if (store.transactionStatus.phase === `idle`) {
|
|
1668
|
-
subject.next({ newValue, oldValue });
|
|
1669
|
-
}
|
|
1670
|
-
options.set({ get, set }, newValue);
|
|
1671
|
-
};
|
|
1672
|
-
const mySelector = __spreadValues(__spreadProps(__spreadValues({}, options), {
|
|
1673
|
-
subject,
|
|
1674
|
-
install: (s) => createSelector(options, family, s),
|
|
1675
|
-
get: getSelf,
|
|
1676
|
-
set: setSelf,
|
|
1677
|
-
type: `selector`
|
|
1678
|
-
}), family && { family });
|
|
1679
|
-
core.selectors.set(options.key, mySelector);
|
|
1680
|
-
const initialValue = getSelf();
|
|
1681
|
-
store.logger.info(`\u2728`, mySelector.type, mySelector.key, `=`, initialValue);
|
|
1682
|
-
const token = {
|
|
1683
|
-
key: options.key,
|
|
1684
|
-
type: `selector`
|
|
1685
|
-
};
|
|
1686
|
-
if (family) {
|
|
1687
|
-
token.family = family;
|
|
1688
|
-
}
|
|
1689
|
-
store.subject.selectorCreation.next(token);
|
|
1690
|
-
return token;
|
|
1691
|
-
};
|
|
1692
|
-
|
|
1693
|
-
// src/selector/create-readonly-selector.ts
|
|
1694
|
-
var createReadonlySelector = (options, family, store, core) => {
|
|
1695
|
-
const subject = new Subject();
|
|
1696
|
-
const { get } = registerSelector(options.key, store);
|
|
1697
|
-
const getSelf = () => {
|
|
1698
|
-
const value = options.get({ get });
|
|
1699
|
-
cacheValue(options.key, value, subject, store);
|
|
1700
|
-
return value;
|
|
1701
|
-
};
|
|
1702
|
-
const readonlySelector = __spreadValues(__spreadProps(__spreadValues({}, options), {
|
|
1703
|
-
subject,
|
|
1704
|
-
install: (s) => createSelector(options, family, s),
|
|
1705
|
-
get: getSelf,
|
|
1706
|
-
type: `readonly_selector`
|
|
1707
|
-
}), family && { family });
|
|
1708
|
-
core.readonlySelectors.set(options.key, readonlySelector);
|
|
1709
|
-
const initialValue = getSelf();
|
|
1710
|
-
store.logger.info(
|
|
1711
|
-
`\u2728`,
|
|
1712
|
-
readonlySelector.type,
|
|
1713
|
-
readonlySelector.key,
|
|
1714
|
-
`=`,
|
|
1715
|
-
initialValue
|
|
1716
|
-
);
|
|
1717
|
-
const token = {
|
|
1718
|
-
key: options.key,
|
|
1719
|
-
type: `readonly_selector`
|
|
1720
|
-
};
|
|
1721
|
-
if (family) {
|
|
1722
|
-
token.family = family;
|
|
1723
|
-
}
|
|
1724
|
-
store.subject.selectorCreation.next(token);
|
|
1725
|
-
return token;
|
|
1608
|
+
});
|
|
1609
|
+
return dependencySubscriptions;
|
|
1726
1610
|
};
|
|
1727
1611
|
|
|
1728
|
-
// src/
|
|
1729
|
-
|
|
1730
|
-
const
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
store.logger.error(
|
|
1735
|
-
`\u274C`,
|
|
1736
|
-
existingReadonly ? `readonly_selector` : `selector`,
|
|
1737
|
-
options.key,
|
|
1738
|
-
`Tried to create selector, but it already exists in the store. (Ignore if you are in development using hot module replacement.)`
|
|
1612
|
+
// src/timeline/add-atom-to-timeline.ts
|
|
1613
|
+
var addAtomToTimeline = (atomToken, tl, store) => {
|
|
1614
|
+
const atom = withdraw(atomToken, store);
|
|
1615
|
+
if (atom === void 0) {
|
|
1616
|
+
throw new Error(
|
|
1617
|
+
`Cannot subscribe to atom "${atomToken.key}" because it has not been initialized in store "${store.config.name}"`
|
|
1739
1618
|
);
|
|
1740
1619
|
}
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1620
|
+
atom.subject.subscribe(`timeline`, (update) => {
|
|
1621
|
+
var _a, _b, _c, _d, _e, _f;
|
|
1622
|
+
const target = newest(store);
|
|
1623
|
+
const currentSelectorKey = store.operation.open && store.operation.token.type === `selector` ? store.operation.token.key : null;
|
|
1624
|
+
const currentSelectorTime = store.operation.open && store.operation.token.type === `selector` ? store.operation.time : null;
|
|
1625
|
+
const currentTransactionKey = (_a = target.subject.transactionApplying.state) == null ? void 0 : _a.update.key;
|
|
1626
|
+
const currentTransactionTime = (_b = target.subject.transactionApplying.state) == null ? void 0 : _b.time;
|
|
1627
|
+
store.logger.info(
|
|
1628
|
+
`\u23F3`,
|
|
1629
|
+
`timeline`,
|
|
1630
|
+
tl.key,
|
|
1631
|
+
`atom`,
|
|
1632
|
+
atomToken.key,
|
|
1633
|
+
`went`,
|
|
1634
|
+
update.oldValue,
|
|
1635
|
+
`->`,
|
|
1636
|
+
update.newValue,
|
|
1637
|
+
currentTransactionKey ? `in transaction "${currentTransactionKey}"` : currentSelectorKey ? `in selector "${currentSelectorKey}"` : ``
|
|
1638
|
+
);
|
|
1639
|
+
if (tl.timeTraveling === null) {
|
|
1640
|
+
if (tl.selectorTime && tl.selectorTime !== currentSelectorTime) {
|
|
1641
|
+
const mostRecentUpdate = tl.history.at(-1);
|
|
1642
|
+
if (mostRecentUpdate === void 0) {
|
|
1643
|
+
throw new Error(
|
|
1644
|
+
`Timeline "${tl.key}" has a selectorTime, but no history. This is most likely a bug in AtomIO.`
|
|
1645
|
+
);
|
|
1646
|
+
}
|
|
1647
|
+
}
|
|
1648
|
+
if (currentTransactionKey) {
|
|
1649
|
+
const currentTransaction = withdraw(
|
|
1650
|
+
{ key: currentTransactionKey, type: `transaction` },
|
|
1651
|
+
store
|
|
1652
|
+
);
|
|
1653
|
+
if (currentTransaction === void 0) {
|
|
1654
|
+
throw new Error(
|
|
1655
|
+
`Transaction "${currentTransactionKey}" not found in store "${store.config.name}". This is surprising, because we are in the application phase of "${currentTransactionKey}".`
|
|
1656
|
+
);
|
|
1657
|
+
}
|
|
1658
|
+
if (tl.transactionKey !== currentTransactionKey) {
|
|
1659
|
+
if (tl.transactionKey) {
|
|
1660
|
+
store.logger.error(
|
|
1661
|
+
`\u{1F41E}`,
|
|
1662
|
+
`timeline`,
|
|
1663
|
+
tl.key,
|
|
1664
|
+
`unable to resolve transaction "${tl.transactionKey}. This is probably a bug in AtomIO.`
|
|
1665
|
+
);
|
|
1666
|
+
}
|
|
1667
|
+
tl.transactionKey = currentTransactionKey;
|
|
1668
|
+
const unsubscribe = currentTransaction.subject.subscribe(
|
|
1669
|
+
`timeline:${tl.key}`,
|
|
1670
|
+
(update2) => {
|
|
1671
|
+
var _a2, _b2;
|
|
1672
|
+
unsubscribe();
|
|
1673
|
+
if (tl.timeTraveling === null && currentTransactionTime) {
|
|
1674
|
+
if (tl.at !== tl.history.length) {
|
|
1675
|
+
tl.history.splice(tl.at);
|
|
1676
|
+
}
|
|
1677
|
+
const filterUpdates = (updates2) => updates2.filter((updateFromTx) => {
|
|
1678
|
+
const target2 = newest(store);
|
|
1679
|
+
if (`updates` in updateFromTx) {
|
|
1680
|
+
return true;
|
|
1681
|
+
}
|
|
1682
|
+
const atomOrFamilyKeys = target2.timelineAtoms.getRelatedKeys(tl.key);
|
|
1683
|
+
return atomOrFamilyKeys ? [...atomOrFamilyKeys].some(
|
|
1684
|
+
(key) => {
|
|
1685
|
+
var _a3;
|
|
1686
|
+
return key === updateFromTx.key || key === ((_a3 = updateFromTx.family) == null ? void 0 : _a3.key);
|
|
1687
|
+
}
|
|
1688
|
+
) : false;
|
|
1689
|
+
}).map((updateFromTx) => {
|
|
1690
|
+
if (`updates` in updateFromTx) {
|
|
1691
|
+
return __spreadProps(__spreadValues({}, updateFromTx), {
|
|
1692
|
+
updates: filterUpdates(updateFromTx.updates)
|
|
1693
|
+
});
|
|
1694
|
+
}
|
|
1695
|
+
return updateFromTx;
|
|
1696
|
+
});
|
|
1697
|
+
const updates = filterUpdates(update2.updates);
|
|
1698
|
+
const timelineTransactionUpdate = __spreadProps(__spreadValues({
|
|
1699
|
+
type: `transaction_update`,
|
|
1700
|
+
timestamp: currentTransactionTime
|
|
1701
|
+
}, update2), {
|
|
1702
|
+
updates
|
|
1703
|
+
});
|
|
1704
|
+
const willCapture = (_b2 = (_a2 = tl.shouldCapture) == null ? void 0 : _a2.call(tl, timelineTransactionUpdate, tl)) != null ? _b2 : true;
|
|
1705
|
+
if (willCapture) {
|
|
1706
|
+
tl.history.push(timelineTransactionUpdate);
|
|
1707
|
+
tl.at = tl.history.length;
|
|
1708
|
+
tl.subject.next(timelineTransactionUpdate);
|
|
1709
|
+
}
|
|
1710
|
+
}
|
|
1711
|
+
tl.transactionKey = null;
|
|
1712
|
+
store.logger.info(
|
|
1713
|
+
`\u231B`,
|
|
1714
|
+
`timeline`,
|
|
1715
|
+
tl.key,
|
|
1716
|
+
`got a transaction_update "${update2.key}"`
|
|
1717
|
+
);
|
|
1718
|
+
}
|
|
1719
|
+
);
|
|
1720
|
+
}
|
|
1721
|
+
} else if (currentSelectorKey && currentSelectorTime) {
|
|
1722
|
+
let latestUpdate = tl.history.at(-1);
|
|
1723
|
+
if (currentSelectorTime !== tl.selectorTime) {
|
|
1724
|
+
latestUpdate = {
|
|
1725
|
+
type: `selector_update`,
|
|
1726
|
+
timestamp: currentSelectorTime,
|
|
1727
|
+
key: currentSelectorKey,
|
|
1728
|
+
atomUpdates: []
|
|
1729
|
+
};
|
|
1730
|
+
latestUpdate.atomUpdates.push(__spreadValues({
|
|
1731
|
+
key: atom.key,
|
|
1732
|
+
type: `atom_update`
|
|
1733
|
+
}, update));
|
|
1734
|
+
if (tl.at !== tl.history.length) {
|
|
1735
|
+
tl.history.splice(tl.at);
|
|
1736
|
+
}
|
|
1737
|
+
tl.history.push(latestUpdate);
|
|
1738
|
+
store.logger.info(
|
|
1739
|
+
`\u231B`,
|
|
1740
|
+
`timeline`,
|
|
1741
|
+
tl.key,
|
|
1742
|
+
`got a selector_update "${currentSelectorKey}" with`,
|
|
1743
|
+
latestUpdate.atomUpdates.map((atomUpdate) => atomUpdate.key)
|
|
1744
|
+
);
|
|
1745
|
+
tl.at = tl.history.length;
|
|
1746
|
+
tl.selectorTime = currentSelectorTime;
|
|
1747
|
+
} else {
|
|
1748
|
+
if ((latestUpdate == null ? void 0 : latestUpdate.type) === `selector_update`) {
|
|
1749
|
+
latestUpdate.atomUpdates.push(__spreadValues({
|
|
1750
|
+
key: atom.key,
|
|
1751
|
+
type: `atom_update`
|
|
1752
|
+
}, update));
|
|
1753
|
+
store.logger.info(
|
|
1754
|
+
`\u231B`,
|
|
1755
|
+
`timeline`,
|
|
1756
|
+
tl.key,
|
|
1757
|
+
`set selector_update "${currentSelectorKey}" to`,
|
|
1758
|
+
latestUpdate == null ? void 0 : latestUpdate.atomUpdates.map((atomUpdate) => atomUpdate.key)
|
|
1759
|
+
);
|
|
1760
|
+
}
|
|
1761
|
+
}
|
|
1762
|
+
if (latestUpdate) {
|
|
1763
|
+
const willCaptureSelectorUpdate = (_d = (_c = tl.shouldCapture) == null ? void 0 : _c.call(tl, latestUpdate, tl)) != null ? _d : true;
|
|
1764
|
+
if (willCaptureSelectorUpdate) {
|
|
1765
|
+
tl.subject.next(latestUpdate);
|
|
1766
|
+
} else {
|
|
1767
|
+
tl.history.pop();
|
|
1768
|
+
tl.at = tl.history.length;
|
|
1769
|
+
}
|
|
1770
|
+
}
|
|
1771
|
+
} else {
|
|
1772
|
+
const timestamp = Date.now();
|
|
1773
|
+
tl.selectorTime = null;
|
|
1774
|
+
if (tl.at !== tl.history.length) {
|
|
1775
|
+
tl.history.splice(tl.at);
|
|
1776
|
+
}
|
|
1777
|
+
const atomUpdate = {
|
|
1778
|
+
type: `atom_update`,
|
|
1779
|
+
timestamp,
|
|
1780
|
+
key: atom.key,
|
|
1781
|
+
oldValue: update.oldValue,
|
|
1782
|
+
newValue: update.newValue
|
|
1783
|
+
};
|
|
1784
|
+
if (atom.family) {
|
|
1785
|
+
atomUpdate.family = atom.family;
|
|
1786
|
+
}
|
|
1787
|
+
const willCapture = (_f = (_e = tl.shouldCapture) == null ? void 0 : _e.call(tl, atomUpdate, tl)) != null ? _f : true;
|
|
1788
|
+
store.logger.info(
|
|
1789
|
+
`\u231B`,
|
|
1790
|
+
`timeline`,
|
|
1791
|
+
tl.key,
|
|
1792
|
+
`got an atom_update to "${atom.key}"`
|
|
1793
|
+
);
|
|
1794
|
+
if (willCapture) {
|
|
1795
|
+
tl.history.push(atomUpdate);
|
|
1796
|
+
tl.at = tl.history.length;
|
|
1797
|
+
tl.subject.next(atomUpdate);
|
|
1798
|
+
}
|
|
1788
1799
|
}
|
|
1789
|
-
return createSelector(
|
|
1790
|
-
{
|
|
1791
|
-
key: fullKey,
|
|
1792
|
-
get: options.get(key)
|
|
1793
|
-
},
|
|
1794
|
-
family,
|
|
1795
|
-
store
|
|
1796
|
-
);
|
|
1797
|
-
},
|
|
1798
|
-
{
|
|
1799
|
-
key: options.key,
|
|
1800
|
-
type: `readonly_selector_family`,
|
|
1801
|
-
subject
|
|
1802
1800
|
}
|
|
1803
|
-
);
|
|
1804
|
-
}
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1801
|
+
});
|
|
1802
|
+
};
|
|
1803
|
+
|
|
1804
|
+
// src/timeline/create-timeline.ts
|
|
1805
|
+
function createTimeline(options, store, data) {
|
|
1806
|
+
var _a, _b;
|
|
1807
|
+
const tl = __spreadProps(__spreadValues({
|
|
1808
|
+
type: `timeline`,
|
|
1809
|
+
key: options.key,
|
|
1810
|
+
at: 0,
|
|
1811
|
+
timeTraveling: null,
|
|
1812
|
+
selectorTime: null,
|
|
1813
|
+
transactionKey: null
|
|
1814
|
+
}, data), {
|
|
1815
|
+
history: (_a = data == null ? void 0 : data.history.map((update) => __spreadValues({}, update))) != null ? _a : [],
|
|
1816
|
+
install: (store2) => createTimeline(options, store2, tl),
|
|
1817
|
+
subject: new Subject()
|
|
1818
|
+
});
|
|
1819
|
+
if (options.shouldCapture) {
|
|
1820
|
+
tl.shouldCapture = options.shouldCapture;
|
|
1809
1821
|
}
|
|
1810
|
-
const
|
|
1811
|
-
const
|
|
1812
|
-
|
|
1813
|
-
(
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
return deposit(existing);
|
|
1820
|
-
}
|
|
1821
|
-
const token = createSelector(
|
|
1822
|
-
{
|
|
1823
|
-
key: fullKey,
|
|
1824
|
-
get: options.get(key),
|
|
1825
|
-
set: options.set(key)
|
|
1826
|
-
},
|
|
1827
|
-
family,
|
|
1828
|
-
store
|
|
1822
|
+
const target = newest(store);
|
|
1823
|
+
for (const tokenOrFamily of options.atoms) {
|
|
1824
|
+
const timelineKey = target.timelineAtoms.getRelatedKey(tokenOrFamily.key);
|
|
1825
|
+
if (timelineKey) {
|
|
1826
|
+
store.logger.error(
|
|
1827
|
+
`\u274C`,
|
|
1828
|
+
`timeline`,
|
|
1829
|
+
options.key,
|
|
1830
|
+
`Failed to add atom "${tokenOrFamily.key}" because it already belongs to timeline "${timelineKey}"`
|
|
1829
1831
|
);
|
|
1830
|
-
|
|
1831
|
-
return token;
|
|
1832
|
-
},
|
|
1833
|
-
{
|
|
1834
|
-
key: options.key,
|
|
1835
|
-
type: `selector_family`
|
|
1832
|
+
continue;
|
|
1836
1833
|
}
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
this.findLatestUpdateState = createAtomFamily(
|
|
1846
|
-
{
|
|
1847
|
-
key: `*${findMutableState.key}`,
|
|
1848
|
-
default: null
|
|
1849
|
-
},
|
|
1850
|
-
store
|
|
1851
|
-
);
|
|
1852
|
-
this.findMutableState = findMutableState;
|
|
1853
|
-
this.findMutableState.subject.subscribe(
|
|
1854
|
-
`store=${store.config.name}::tracker-atom-family`,
|
|
1855
|
-
(atomToken) => {
|
|
1856
|
-
if (atomToken.family) {
|
|
1857
|
-
const key = parseJson(atomToken.family.subKey);
|
|
1858
|
-
this.findLatestUpdateState(key);
|
|
1859
|
-
new Tracker(atomToken, store);
|
|
1834
|
+
if (tokenOrFamily.type === `atom_family`) {
|
|
1835
|
+
const family = tokenOrFamily;
|
|
1836
|
+
family.subject.subscribe(`timeline:${options.key}`, (token2) => {
|
|
1837
|
+
addAtomToTimeline(token2, tl, store);
|
|
1838
|
+
});
|
|
1839
|
+
for (const atom of target.atoms.values()) {
|
|
1840
|
+
if (((_b = atom.family) == null ? void 0 : _b.key) === family.key) {
|
|
1841
|
+
addAtomToTimeline(atom, tl, store);
|
|
1860
1842
|
}
|
|
1861
1843
|
}
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
`
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1844
|
+
} else {
|
|
1845
|
+
const token2 = tokenOrFamily;
|
|
1846
|
+
if (`family` in token2 && token2.family) {
|
|
1847
|
+
const familyTimelineKey = target.timelineAtoms.getRelatedKey(
|
|
1848
|
+
token2.family.key
|
|
1849
|
+
);
|
|
1850
|
+
if (familyTimelineKey) {
|
|
1851
|
+
store.logger.error(
|
|
1852
|
+
`\u274C`,
|
|
1853
|
+
`timeline`,
|
|
1854
|
+
options.key,
|
|
1855
|
+
`Failed to add atom "${token2.key}" because its family "${token2.family.key}" already belongs to timeline "${familyTimelineKey}"`
|
|
1856
|
+
);
|
|
1857
|
+
continue;
|
|
1870
1858
|
}
|
|
1871
1859
|
}
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
const coreFamily = Object.assign(
|
|
1879
|
-
createAtomFamily(options, store),
|
|
1880
|
-
options
|
|
1881
|
-
);
|
|
1882
|
-
selectJsonFamily(coreFamily, options);
|
|
1883
|
-
new FamilyTracker(coreFamily, store);
|
|
1884
|
-
return coreFamily;
|
|
1885
|
-
}
|
|
1886
|
-
|
|
1887
|
-
// src/mutable/get-json-family.ts
|
|
1888
|
-
var getJsonFamily = (mutableAtomFamily, store) => {
|
|
1889
|
-
const core = target(store);
|
|
1890
|
-
const key = `${mutableAtomFamily.key}:JSON`;
|
|
1891
|
-
const jsonFamily = core.families.get(
|
|
1892
|
-
key
|
|
1893
|
-
);
|
|
1894
|
-
return jsonFamily;
|
|
1895
|
-
};
|
|
1896
|
-
|
|
1897
|
-
// src/mutable/get-json-token.ts
|
|
1898
|
-
var getJsonToken = (mutableAtomToken) => {
|
|
1899
|
-
const key = mutableAtomToken.family ? `${mutableAtomToken.family.key}:JSON(${mutableAtomToken.family.subKey})` : `${mutableAtomToken.key}:JSON`;
|
|
1900
|
-
const jsonToken = { type: `selector`, key };
|
|
1901
|
-
if (mutableAtomToken.family) {
|
|
1902
|
-
jsonToken.family = {
|
|
1903
|
-
key: `${mutableAtomToken.family.key}:JSON`,
|
|
1904
|
-
subKey: mutableAtomToken.family.subKey
|
|
1905
|
-
};
|
|
1906
|
-
}
|
|
1907
|
-
return jsonToken;
|
|
1908
|
-
};
|
|
1909
|
-
|
|
1910
|
-
// src/mutable/get-update-token.ts
|
|
1911
|
-
var getUpdateToken = (mutableAtomToken) => {
|
|
1912
|
-
const key = `*${mutableAtomToken.key}`;
|
|
1913
|
-
const updateToken = { type: `atom`, key };
|
|
1914
|
-
if (mutableAtomToken.family) {
|
|
1915
|
-
updateToken.family = {
|
|
1916
|
-
key: `*${mutableAtomToken.family.key}`,
|
|
1917
|
-
subKey: mutableAtomToken.family.subKey
|
|
1918
|
-
};
|
|
1860
|
+
addAtomToTimeline(token2, tl, store);
|
|
1861
|
+
}
|
|
1862
|
+
target.timelineAtoms = target.timelineAtoms.set({
|
|
1863
|
+
atomKey: tokenOrFamily.key,
|
|
1864
|
+
timelineKey: options.key
|
|
1865
|
+
});
|
|
1919
1866
|
}
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
// src/mutable/transceiver.ts
|
|
1929
|
-
function isTransceiver(value) {
|
|
1930
|
-
return typeof value === `object` && value !== null && `do` in value && `undo` in value && `subscribe` in value;
|
|
1867
|
+
store.timelines.set(options.key, tl);
|
|
1868
|
+
const token = {
|
|
1869
|
+
key: options.key,
|
|
1870
|
+
type: `timeline`
|
|
1871
|
+
};
|
|
1872
|
+
store.subject.timelineCreation.next(token);
|
|
1873
|
+
return token;
|
|
1931
1874
|
}
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
var isAtomMutable = (atom) => `isMutable` in atom;
|
|
1935
|
-
|
|
1936
|
-
// src/atom/is-default.ts
|
|
1937
|
-
var isAtomDefault = (key, store) => {
|
|
1938
|
-
const core = target(store);
|
|
1939
|
-
return core.atomsThatAreDefault.has(key);
|
|
1940
|
-
};
|
|
1941
|
-
var markAtomAsDefault = (key, store) => {
|
|
1942
|
-
const core = target(store);
|
|
1943
|
-
core.atomsThatAreDefault = new Set(core.atomsThatAreDefault).add(key);
|
|
1944
|
-
};
|
|
1945
|
-
var markAtomAsNotDefault = (key, store) => {
|
|
1946
|
-
const core = target(store);
|
|
1947
|
-
core.atomsThatAreDefault = new Set(target(store).atomsThatAreDefault);
|
|
1948
|
-
core.atomsThatAreDefault.delete(key);
|
|
1949
|
-
};
|
|
1950
|
-
var isSelectorDefault = (key, store) => {
|
|
1951
|
-
const rootKeys = traceAllSelectorAtoms(key, store);
|
|
1952
|
-
return rootKeys.every((rootKey) => isAtomDefault(rootKey, store));
|
|
1953
|
-
};
|
|
1954
|
-
|
|
1955
|
-
// src/atom/create-atom.ts
|
|
1956
|
-
function createAtom(options, family, store) {
|
|
1875
|
+
var timeTravel = (direction, token, store) => {
|
|
1876
|
+
const action = direction === `forward` ? `redo` : `undo`;
|
|
1957
1877
|
store.logger.info(
|
|
1958
|
-
`\
|
|
1959
|
-
`
|
|
1960
|
-
|
|
1961
|
-
|
|
1878
|
+
direction === `forward` ? `\u23E9` : `\u23EA`,
|
|
1879
|
+
`timeline`,
|
|
1880
|
+
token.key,
|
|
1881
|
+
action
|
|
1962
1882
|
);
|
|
1963
|
-
const
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
`Tried to create atom, but it already exists in the store.`,
|
|
1971
|
-
`(Ignore if you are in development using hot module replacement.)`
|
|
1883
|
+
const timelineData = store.timelines.get(token.key);
|
|
1884
|
+
if (!timelineData) {
|
|
1885
|
+
store.logger.error(
|
|
1886
|
+
`\u{1F41E}`,
|
|
1887
|
+
`timeline`,
|
|
1888
|
+
token.key,
|
|
1889
|
+
`Failed to ${action}. This timeline has not been initialized.`
|
|
1972
1890
|
);
|
|
1973
|
-
return
|
|
1891
|
+
return;
|
|
1974
1892
|
}
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
`installing in store "${store2.config.name}"`
|
|
1984
|
-
);
|
|
1985
|
-
return `mutable` in options ? createMutableAtom(options, store2) : createAtom(options, void 0, store2);
|
|
1986
|
-
},
|
|
1987
|
-
subject
|
|
1988
|
-
}), family && { family });
|
|
1989
|
-
let initialValue = options.default;
|
|
1990
|
-
if (options.default instanceof Function) {
|
|
1991
|
-
initialValue = options.default();
|
|
1893
|
+
if (direction === `forward` && timelineData.at === timelineData.history.length || direction === `backward` && timelineData.at === 0) {
|
|
1894
|
+
store.logger.warn(
|
|
1895
|
+
`\u{1F481}`,
|
|
1896
|
+
`timeline`,
|
|
1897
|
+
token.key,
|
|
1898
|
+
`Failed to ${action} at the ${direction === `forward` ? `end` : `beginning`} of timeline "${token.key}". There is nothing to ${action}.`
|
|
1899
|
+
);
|
|
1900
|
+
return;
|
|
1992
1901
|
}
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
const
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
1902
|
+
timelineData.timeTraveling = direction === `forward` ? `into_future` : `into_past`;
|
|
1903
|
+
if (direction === `backward`) {
|
|
1904
|
+
--timelineData.at;
|
|
1905
|
+
}
|
|
1906
|
+
const update = timelineData.history[timelineData.at];
|
|
1907
|
+
const updateValues = (atomUpdate) => {
|
|
1908
|
+
const { key, newValue, oldValue } = atomUpdate;
|
|
1909
|
+
const value = direction === `forward` ? newValue : oldValue;
|
|
1910
|
+
setState({ key, type: `atom` }, value, store);
|
|
1911
|
+
};
|
|
1912
|
+
const updateValuesFromTransactionUpdate = (transactionUpdate) => {
|
|
1913
|
+
const updates = direction === `forward` ? transactionUpdate.updates : [...transactionUpdate.updates].reverse();
|
|
1914
|
+
for (const updateFromTransaction of updates) {
|
|
1915
|
+
if (`newValue` in updateFromTransaction) {
|
|
1916
|
+
updateValues(updateFromTransaction);
|
|
1917
|
+
} else {
|
|
1918
|
+
updateValuesFromTransactionUpdate(updateFromTransaction);
|
|
2007
1919
|
}
|
|
2008
|
-
++effectIndex;
|
|
2009
1920
|
}
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
1921
|
+
};
|
|
1922
|
+
switch (update.type) {
|
|
1923
|
+
case `atom_update`: {
|
|
1924
|
+
updateValues(update);
|
|
1925
|
+
break;
|
|
1926
|
+
}
|
|
1927
|
+
case `selector_update`: {
|
|
1928
|
+
const updates = direction === `forward` ? update.atomUpdates : [...update.atomUpdates].reverse();
|
|
1929
|
+
for (const atomUpdate of updates) {
|
|
1930
|
+
updateValues(atomUpdate);
|
|
2013
1931
|
}
|
|
2014
|
-
|
|
1932
|
+
break;
|
|
1933
|
+
}
|
|
1934
|
+
case `transaction_update`: {
|
|
1935
|
+
updateValuesFromTransactionUpdate(update);
|
|
1936
|
+
break;
|
|
1937
|
+
}
|
|
2015
1938
|
}
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
}
|
|
1939
|
+
if (direction === `forward`) {
|
|
1940
|
+
++timelineData.at;
|
|
1941
|
+
}
|
|
1942
|
+
timelineData.subject.next(action);
|
|
1943
|
+
timelineData.timeTraveling = null;
|
|
1944
|
+
store.logger.info(
|
|
1945
|
+
`\u23F9\uFE0F`,
|
|
1946
|
+
`timeline`,
|
|
1947
|
+
token.key,
|
|
1948
|
+
`"${token.key}" is now at ${timelineData.at} / ${timelineData.history.length}`
|
|
1949
|
+
);
|
|
1950
|
+
};
|
|
2019
1951
|
|
|
2020
|
-
// src/
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
`atom`,
|
|
2030
|
-
`${key}`,
|
|
2031
|
-
`Tried to delete atom, but it does not exist in the store.`
|
|
1952
|
+
// src/transaction/abort-transaction.ts
|
|
1953
|
+
var abortTransaction = (store) => {
|
|
1954
|
+
const target = newest(store);
|
|
1955
|
+
if (target.transactionMeta === null || target.parent === null) {
|
|
1956
|
+
store.logger.warn(
|
|
1957
|
+
`\u{1F41E}`,
|
|
1958
|
+
`transaction`,
|
|
1959
|
+
`???`,
|
|
1960
|
+
`abortTransaction called outside of a transaction. This is probably a bug in AtomIO.`
|
|
2032
1961
|
);
|
|
1962
|
+
return;
|
|
2033
1963
|
}
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
1964
|
+
store.logger.info(
|
|
1965
|
+
`\u{1FA82}`,
|
|
1966
|
+
`transaction`,
|
|
1967
|
+
target.transactionMeta.update.key,
|
|
1968
|
+
`Aborting transaction`
|
|
1969
|
+
);
|
|
1970
|
+
target.parent.child = null;
|
|
1971
|
+
};
|
|
1972
|
+
function ingestAtomUpdate(update, parent, child) {
|
|
1973
|
+
var _a, _b, _c;
|
|
1974
|
+
const { key, newValue } = update;
|
|
1975
|
+
const token = { key, type: `atom` };
|
|
1976
|
+
if (!parent.valueMap.has(token.key)) {
|
|
1977
|
+
if (token.family) {
|
|
1978
|
+
const family = parent.families.get(token.family.key);
|
|
1979
|
+
if (family) {
|
|
1980
|
+
family(token.family.subKey);
|
|
1981
|
+
}
|
|
1982
|
+
} else {
|
|
1983
|
+
const newAtom = child.atoms.get(token.key);
|
|
1984
|
+
if (!newAtom) {
|
|
1985
|
+
throw new Error(
|
|
1986
|
+
`Absurd Error: Atom "${token.key}" not found while copying updates from transaction "${(_a = child.transactionMeta) == null ? void 0 : _a.update.key}" to store "${parent.config.name}"`
|
|
1987
|
+
);
|
|
2043
1988
|
}
|
|
1989
|
+
parent.atoms.set(newAtom.key, newAtom);
|
|
1990
|
+
parent.valueMap.set(newAtom.key, newAtom.default);
|
|
1991
|
+
parent.logger.info(
|
|
1992
|
+
`\u{1F528}`,
|
|
1993
|
+
`transaction`,
|
|
1994
|
+
(_c = (_b = child.transactionMeta) == null ? void 0 : _b.update.key) != null ? _c : `???`,
|
|
1995
|
+
`Adding atom "${newAtom.key}"`
|
|
1996
|
+
);
|
|
2044
1997
|
}
|
|
2045
1998
|
}
|
|
2046
|
-
|
|
2047
|
-
core.atomsThatAreDefault.delete(key);
|
|
2048
|
-
core.timelineAtoms.delete(key);
|
|
2049
|
-
store.logger.info(`\u{1F525}`, `atom`, `${key}`, `deleted`);
|
|
1999
|
+
setState(token, newValue, parent);
|
|
2050
2000
|
}
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2001
|
+
function ingestTransactionUpdate(transactionUpdate, parent, child) {
|
|
2002
|
+
for (const update of transactionUpdate.updates) {
|
|
2003
|
+
if (`newValue` in update) {
|
|
2004
|
+
ingestAtomUpdate(update, parent, child);
|
|
2005
|
+
} else {
|
|
2006
|
+
ingestTransactionUpdate(update, parent, child);
|
|
2007
|
+
}
|
|
2057
2008
|
}
|
|
2058
|
-
return capitalize(token.type);
|
|
2059
2009
|
}
|
|
2060
|
-
var
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
}
|
|
2066
|
-
};
|
|
2067
|
-
|
|
2068
|
-
// src/subscribe/recall-state.ts
|
|
2069
|
-
var recallState = (state, store) => {
|
|
2070
|
-
const core = target(store);
|
|
2071
|
-
if (!core.operation.open) {
|
|
2010
|
+
var applyTransaction = (output, store) => {
|
|
2011
|
+
var _a;
|
|
2012
|
+
const child = newest(store);
|
|
2013
|
+
const { parent } = child;
|
|
2014
|
+
if (parent === null || child.transactionMeta === null || ((_a = child.transactionMeta) == null ? void 0 : _a.phase) !== `building`) {
|
|
2072
2015
|
store.logger.warn(
|
|
2073
2016
|
`\u{1F41E}`,
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
`
|
|
2017
|
+
`transaction`,
|
|
2018
|
+
`???`,
|
|
2019
|
+
`applyTransaction called outside of a transaction. This is probably a bug in AtomIO.`
|
|
2020
|
+
);
|
|
2021
|
+
return;
|
|
2022
|
+
}
|
|
2023
|
+
child.transactionMeta.phase = `applying`;
|
|
2024
|
+
child.transactionMeta.update.output = output;
|
|
2025
|
+
parent.child = null;
|
|
2026
|
+
parent.subject.transactionApplying.next(child.transactionMeta);
|
|
2027
|
+
const { updates } = child.transactionMeta.update;
|
|
2028
|
+
store.logger.info(
|
|
2029
|
+
`\u{1F6C4}`,
|
|
2030
|
+
`transaction`,
|
|
2031
|
+
child.transactionMeta.update.key,
|
|
2032
|
+
`Applying transaction with ${updates.length} updates:`,
|
|
2033
|
+
updates
|
|
2034
|
+
);
|
|
2035
|
+
if (parent.transactionMeta === null) {
|
|
2036
|
+
ingestTransactionUpdate(child.transactionMeta.update, parent, child);
|
|
2037
|
+
const myTransaction = withdraw(
|
|
2038
|
+
{ key: child.transactionMeta.update.key, type: `transaction` },
|
|
2039
|
+
store
|
|
2040
|
+
);
|
|
2041
|
+
myTransaction == null ? void 0 : myTransaction.subject.next(child.transactionMeta.update);
|
|
2042
|
+
store.logger.info(
|
|
2043
|
+
`\u{1F6EC}`,
|
|
2044
|
+
`transaction`,
|
|
2045
|
+
child.transactionMeta.update.key,
|
|
2046
|
+
`Finished applying transaction.`
|
|
2077
2047
|
);
|
|
2078
|
-
|
|
2048
|
+
} else {
|
|
2049
|
+
ingestTransactionUpdate(child.transactionMeta.update, parent, child);
|
|
2050
|
+
parent.transactionMeta.update.updates.push(child.transactionMeta.update);
|
|
2079
2051
|
}
|
|
2080
|
-
|
|
2052
|
+
parent.subject.transactionApplying.next(null);
|
|
2081
2053
|
};
|
|
2082
2054
|
|
|
2083
|
-
// src/
|
|
2084
|
-
var
|
|
2085
|
-
const
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2055
|
+
// src/transaction/build-transaction.ts
|
|
2056
|
+
var buildTransaction = (key, params, store) => {
|
|
2057
|
+
const parent = newest(store);
|
|
2058
|
+
parent.child = {
|
|
2059
|
+
parent,
|
|
2060
|
+
child: null,
|
|
2061
|
+
subject: parent.subject,
|
|
2062
|
+
loggers: parent.loggers,
|
|
2063
|
+
logger: parent.logger,
|
|
2064
|
+
config: parent.config,
|
|
2065
|
+
transactionMeta: {
|
|
2066
|
+
phase: `building`,
|
|
2067
|
+
time: Date.now(),
|
|
2068
|
+
update: {
|
|
2069
|
+
key,
|
|
2070
|
+
updates: [],
|
|
2071
|
+
params,
|
|
2072
|
+
output: void 0
|
|
2073
|
+
}
|
|
2074
|
+
},
|
|
2075
|
+
atoms: new LazyMap(parent.atoms),
|
|
2076
|
+
atomsThatAreDefault: new Set(parent.atomsThatAreDefault),
|
|
2077
|
+
families: new LazyMap(parent.families),
|
|
2078
|
+
operation: { open: false },
|
|
2079
|
+
readonlySelectors: new LazyMap(parent.readonlySelectors),
|
|
2080
|
+
timelines: new LazyMap(parent.timelines),
|
|
2081
|
+
timelineAtoms: new Junction(parent.timelineAtoms.toJSON()),
|
|
2082
|
+
trackers: /* @__PURE__ */ new Map(),
|
|
2083
|
+
transactions: new LazyMap(parent.transactions),
|
|
2084
|
+
selectorAtoms: new Junction(parent.selectorAtoms.toJSON()),
|
|
2085
|
+
selectorGraph: new Junction(parent.selectorGraph.toJSON(), {
|
|
2086
|
+
makeContentKey: (...keys) => keys.sort().join(`:`)
|
|
2087
|
+
}),
|
|
2088
|
+
selectors: new LazyMap(parent.selectors),
|
|
2089
|
+
valueMap: new LazyMap(parent.valueMap)
|
|
2090
|
+
};
|
|
2091
|
+
store.logger.info(
|
|
2092
|
+
`\u{1F6EB}`,
|
|
2093
|
+
`transaction`,
|
|
2094
|
+
key,
|
|
2095
|
+
`Building transaction with params:`,
|
|
2096
|
+
params
|
|
2097
|
+
);
|
|
2098
|
+
};
|
|
2099
|
+
function createTransaction(options, store) {
|
|
2100
|
+
const newTransaction = {
|
|
2101
|
+
key: options.key,
|
|
2102
|
+
type: `transaction`,
|
|
2103
|
+
run: (...params) => {
|
|
2104
|
+
buildTransaction(options.key, params, store);
|
|
2105
|
+
try {
|
|
2106
|
+
const output = options.do(
|
|
2107
|
+
{
|
|
2108
|
+
get: (token2) => getState(token2, store),
|
|
2109
|
+
set: (token2, value) => setState(token2, value, store),
|
|
2110
|
+
run: (token2) => runTransaction(token2, store)
|
|
2111
|
+
},
|
|
2112
|
+
...params
|
|
2105
2113
|
);
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2114
|
+
applyTransaction(output, store);
|
|
2115
|
+
return output;
|
|
2116
|
+
} catch (thrown) {
|
|
2117
|
+
abortTransaction(store);
|
|
2118
|
+
store.logger.warn(`\u{1F4A5}`, `transaction`, options.key, `caught:`, thrown);
|
|
2119
|
+
throw thrown;
|
|
2120
|
+
}
|
|
2121
|
+
},
|
|
2122
|
+
install: (store2) => createTransaction(options, store2),
|
|
2123
|
+
subject: new Subject()
|
|
2124
|
+
};
|
|
2125
|
+
const target = newest(store);
|
|
2126
|
+
target.transactions.set(newTransaction.key, newTransaction);
|
|
2127
|
+
const token = deposit(newTransaction);
|
|
2128
|
+
store.subject.transactionCreation.next(token);
|
|
2129
|
+
return token;
|
|
2130
|
+
}
|
|
2131
|
+
var redoTransactionUpdate = (transactionUpdate, store) => {
|
|
2132
|
+
store.logger.info(`\u23ED\uFE0F`, `transaction`, transactionUpdate.key, `Redo`);
|
|
2133
|
+
for (const update of transactionUpdate.updates) {
|
|
2134
|
+
if (`newValue` in update) {
|
|
2135
|
+
const { key, newValue } = update;
|
|
2136
|
+
const token = { key, type: `atom` };
|
|
2137
|
+
const state = withdraw(token, store);
|
|
2138
|
+
if (state === void 0) {
|
|
2139
|
+
throw new Error(
|
|
2140
|
+
`State "${token.key}" not found in this store. This is surprising, because we are navigating the history of the store.`
|
|
2116
2141
|
);
|
|
2117
|
-
state.subject.next({ newValue, oldValue });
|
|
2118
2142
|
}
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2143
|
+
setState(state, newValue, store);
|
|
2144
|
+
} else {
|
|
2145
|
+
redoTransactionUpdate(update, store);
|
|
2146
|
+
}
|
|
2147
|
+
}
|
|
2148
|
+
};
|
|
2149
|
+
var undoTransactionUpdate = (transactionUpdate, store) => {
|
|
2150
|
+
store.logger.info(`\u23EE\uFE0F`, `transaction`, transactionUpdate.key, `Undo`);
|
|
2151
|
+
for (const update of transactionUpdate.updates.reverse()) {
|
|
2152
|
+
if (`newValue` in update) {
|
|
2153
|
+
const { key, newValue } = update;
|
|
2154
|
+
const token = { key, type: `atom` };
|
|
2155
|
+
const state = withdraw(token, store);
|
|
2156
|
+
if (state === void 0) {
|
|
2157
|
+
throw new Error(
|
|
2158
|
+
`State "${token.key}" not found in this store. This is surprising, because we are navigating the history of the store.`
|
|
2159
|
+
);
|
|
2160
|
+
}
|
|
2161
|
+
setState(state, newValue, store);
|
|
2162
|
+
} else {
|
|
2163
|
+
undoTransactionUpdate(update, store);
|
|
2164
|
+
}
|
|
2165
|
+
}
|
|
2122
2166
|
};
|
|
2123
2167
|
|
|
2124
|
-
|
|
2168
|
+
// src/transaction/index.ts
|
|
2169
|
+
var TRANSACTION_PHASES = [`idle`, `building`, `applying`];
|
|
2170
|
+
|
|
2171
|
+
export { FamilyTracker, Future, IMPLICIT, LazyMap, NotFoundError, StatefulSubject, Store, Subject, TRANSACTION_PHASES, Tracker, abortTransaction, addAtomToTimeline, applyTransaction, become, buildTransaction, cacheValue, clearStore, closeOperation, createAtom, createAtomFamily, createMutableAtom, createMutableAtomFamily, createReadonlySelectorFamily, createSelector, createSelectorFamily, createTimeline, createTransaction, deleteAtom, deleteSelector, deposit, eldest, evictCachedValue, getJsonFamily, getJsonToken, getSelectorDependencyKeys, getUpdateToken, isAtomDefault, isAtomKey, isAtomMutable, isAtomTokenMutable, isDone, isReadonlySelectorKey, isSelectorDefault, isSelectorKey, isStateKey, isTransceiver, isValueCached, markAtomAsDefault, markAtomAsNotDefault, markDone, newest, openOperation, readCachedValue, readOrComputeValue, redoTransactionUpdate, registerSelector, setAtomOrSelector, subscribeToRootAtoms, timeTravel, traceAllSelectorAtoms, traceSelectorAtoms, undoTransactionUpdate, updateSelectorAtoms, withdraw, withdrawNewFamilyMember };
|
|
2125
2172
|
//# sourceMappingURL=out.js.map
|
|
2126
2173
|
//# sourceMappingURL=index.js.map
|