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