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