atom.io 0.6.9 → 0.7.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/README.md +21 -2
- package/dist/index.d.mts +34 -421
- package/dist/index.d.ts +34 -421
- package/dist/index.js +248 -23
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +209 -4
- package/dist/index.mjs.map +1 -1
- package/internal/dist/index.d.mts +342 -0
- package/internal/dist/index.d.ts +342 -0
- package/internal/dist/index.js +1873 -0
- package/internal/dist/index.js.map +1 -0
- package/internal/dist/index.mjs +1798 -0
- package/internal/dist/index.mjs.map +1 -0
- package/internal/package.json +15 -0
- package/internal/src/atom/create-atom.ts +75 -0
- package/internal/src/atom/delete-atom.ts +10 -0
- package/internal/src/atom/index.ts +3 -0
- package/internal/src/atom/is-default.ts +37 -0
- package/internal/src/caching.ts +21 -0
- package/internal/src/families/create-atom-family.ts +59 -0
- package/internal/src/families/create-readonly-selector-family.ts +45 -0
- package/internal/src/families/create-selector-family.ts +67 -0
- package/internal/src/families/index.ts +3 -0
- package/internal/src/get-state-internal.ts +23 -0
- package/internal/src/index.ts +13 -0
- package/internal/src/mutable/create-mutable-atom-family.ts +25 -0
- package/internal/src/mutable/create-mutable-atom.ts +49 -0
- package/internal/src/mutable/get-json-token.ts +22 -0
- package/internal/src/mutable/get-update-token.ts +20 -0
- package/internal/src/mutable/index.ts +17 -0
- package/internal/src/mutable/is-atom-token-mutable.ts +7 -0
- package/internal/src/mutable/tracker-family.ts +61 -0
- package/internal/src/mutable/tracker.ts +164 -0
- package/internal/src/mutable/transceiver.ts +110 -0
- package/internal/src/operation.ts +68 -0
- package/internal/src/selector/create-read-write-selector.ts +65 -0
- package/internal/src/selector/create-readonly-selector.ts +49 -0
- package/internal/src/selector/create-selector.ts +65 -0
- package/internal/src/selector/index.ts +5 -0
- package/internal/src/selector/lookup-selector-sources.ts +20 -0
- package/internal/src/selector/register-selector.ts +61 -0
- package/internal/src/selector/trace-selector-atoms.ts +45 -0
- package/internal/src/selector/update-selector-atoms.ts +34 -0
- package/internal/src/set-state/become.ts +10 -0
- package/internal/src/set-state/copy-mutable-if-needed.ts +23 -0
- package/internal/src/set-state/copy-mutable-in-transaction.ts +59 -0
- package/internal/src/set-state/copy-mutable-into-new-store.ts +34 -0
- package/internal/src/set-state/emit-update.ts +23 -0
- package/internal/src/set-state/evict-downstream.ts +39 -0
- package/internal/src/set-state/index.ts +2 -0
- package/internal/src/set-state/set-atom-state.ts +38 -0
- package/internal/src/set-state/set-selector-state.ts +19 -0
- package/internal/src/set-state/set-state-internal.ts +18 -0
- package/internal/src/set-state/stow-update.ts +42 -0
- package/internal/src/store/deposit.ts +43 -0
- package/internal/src/store/index.ts +5 -0
- package/internal/src/store/lookup.ts +26 -0
- package/internal/src/store/store.ts +154 -0
- package/internal/src/store/withdraw-new-family-member.ts +53 -0
- package/internal/src/store/withdraw.ts +113 -0
- package/internal/src/subject.ts +21 -0
- package/internal/src/subscribe/index.ts +1 -0
- package/internal/src/subscribe/recall-state.ts +19 -0
- package/internal/src/subscribe/subscribe-to-root-atoms.ts +47 -0
- package/internal/src/timeline/add-atom-to-timeline.ts +189 -0
- package/internal/src/timeline/index.ts +3 -0
- package/internal/src/timeline/time-travel-internal.ts +91 -0
- package/internal/src/timeline/timeline-internal.ts +115 -0
- package/internal/src/transaction/abort-transaction.ts +12 -0
- package/internal/src/transaction/apply-transaction.ts +64 -0
- package/internal/src/transaction/build-transaction.ts +39 -0
- package/internal/src/transaction/index.ts +26 -0
- package/internal/src/transaction/redo-transaction.ts +22 -0
- package/internal/src/transaction/transaction-internal.ts +64 -0
- package/internal/src/transaction/undo-transaction.ts +22 -0
- package/introspection/dist/index.d.mts +3 -197
- package/introspection/dist/index.d.ts +3 -197
- package/introspection/dist/index.js +329 -4
- package/introspection/dist/index.js.map +1 -1
- package/introspection/dist/index.mjs +310 -4
- package/introspection/dist/index.mjs.map +1 -1
- package/introspection/src/attach-atom-index.ts +84 -0
- package/introspection/src/attach-introspection-states.ts +38 -0
- package/introspection/src/attach-selector-index.ts +90 -0
- package/introspection/src/attach-timeline-family.ts +59 -0
- package/introspection/src/attach-timeline-index.ts +38 -0
- package/introspection/src/attach-transaction-index.ts +40 -0
- package/introspection/src/attach-transaction-logs.ts +43 -0
- package/introspection/src/index.ts +20 -0
- package/json/dist/index.d.mts +10 -2
- package/json/dist/index.d.ts +10 -2
- package/json/dist/index.js +83 -26
- package/json/dist/index.js.map +1 -1
- package/json/dist/index.mjs +74 -3
- package/json/dist/index.mjs.map +1 -1
- package/json/src/index.ts +5 -0
- package/json/src/select-json-family.ts +35 -0
- package/json/src/select-json.ts +22 -0
- package/package.json +103 -63
- package/react/dist/index.d.mts +9 -17
- package/react/dist/index.d.ts +9 -17
- package/react/dist/index.js +44 -27
- package/react/dist/index.js.map +1 -1
- package/react/dist/index.mjs +24 -4
- package/react/dist/index.mjs.map +1 -1
- package/react/src/index.ts +2 -0
- package/react/src/store-context.tsx +12 -0
- package/react/src/store-hooks.ts +36 -0
- package/react-devtools/dist/index.css +50 -1
- package/react-devtools/dist/index.css.map +1 -1
- package/react-devtools/dist/index.d.mts +104 -71
- package/react-devtools/dist/index.d.ts +104 -71
- package/react-devtools/dist/index.js +2806 -44
- package/react-devtools/dist/index.js.map +1 -1
- package/react-devtools/dist/index.mjs +2775 -10
- package/react-devtools/dist/index.mjs.map +1 -1
- package/react-devtools/src/AtomIODevtools.tsx +109 -0
- package/react-devtools/src/Button.tsx +23 -0
- package/react-devtools/src/StateEditor.tsx +75 -0
- package/react-devtools/src/StateIndex.tsx +159 -0
- package/react-devtools/src/TimelineIndex.tsx +88 -0
- package/react-devtools/src/TransactionIndex.tsx +70 -0
- package/react-devtools/src/Updates.tsx +150 -0
- package/react-devtools/src/devtools.scss +310 -0
- package/react-devtools/src/index.ts +72 -0
- package/realtime-react/dist/index.d.mts +8 -22
- package/realtime-react/dist/index.d.ts +8 -22
- package/realtime-react/dist/index.js +87 -32
- package/realtime-react/dist/index.js.map +1 -1
- package/realtime-react/dist/index.mjs +62 -6
- package/realtime-react/dist/index.mjs.map +1 -1
- package/realtime-react/src/index.ts +7 -0
- package/realtime-react/src/realtime-context.tsx +29 -0
- package/realtime-react/src/use-pull-family-member.ts +15 -0
- package/realtime-react/src/use-pull-mutable-family-member.ts +20 -0
- package/realtime-react/src/use-pull-mutable.ts +17 -0
- package/realtime-react/src/use-pull.ts +15 -0
- package/realtime-react/src/use-push.ts +19 -0
- package/realtime-react/src/use-server-action.ts +18 -0
- package/realtime-testing/dist/index.d.mts +49 -0
- package/realtime-testing/dist/index.d.ts +49 -0
- package/realtime-testing/dist/index.js +147 -0
- package/realtime-testing/dist/index.js.map +1 -0
- package/realtime-testing/dist/index.mjs +116 -0
- package/realtime-testing/dist/index.mjs.map +1 -0
- package/realtime-testing/src/index.ts +1 -0
- package/realtime-testing/src/setup-realtime-test.tsx +161 -0
- package/src/atom.ts +64 -9
- package/src/index.ts +36 -32
- package/src/logger.ts +3 -3
- package/src/selector.ts +3 -3
- package/src/silo.ts +29 -20
- package/src/subscribe.ts +3 -3
- package/src/timeline.ts +2 -2
- package/transceivers/set-rtx/dist/index.d.mts +39 -0
- package/transceivers/set-rtx/dist/index.d.ts +39 -0
- package/transceivers/set-rtx/dist/index.js +213 -0
- package/transceivers/set-rtx/dist/index.js.map +1 -0
- package/transceivers/set-rtx/dist/index.mjs +211 -0
- package/transceivers/set-rtx/dist/index.mjs.map +1 -0
- package/{realtime → transceivers/set-rtx}/package.json +1 -1
- package/transceivers/set-rtx/src/index.ts +1 -0
- package/transceivers/set-rtx/src/set-rtx.ts +242 -0
- package/realtime/dist/index.d.mts +0 -23
- package/realtime/dist/index.d.ts +0 -23
- package/realtime/dist/index.js +0 -32
- package/realtime/dist/index.js.map +0 -1
- package/realtime/dist/index.mjs +0 -7
- package/realtime/dist/index.mjs.map +0 -1
|
@@ -0,0 +1,1798 @@
|
|
|
1
|
+
import * as AtomIO from 'atom.io';
|
|
2
|
+
import { setState, getState, subscribe } from 'atom.io';
|
|
3
|
+
import { selectJson, stringifyJson, parseJson, selectJsonFamily } from 'atom.io/json';
|
|
4
|
+
|
|
5
|
+
var __defProp = Object.defineProperty;
|
|
6
|
+
var __defProps = Object.defineProperties;
|
|
7
|
+
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
8
|
+
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
9
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
10
|
+
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
11
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
12
|
+
var __spreadValues = (a, b) => {
|
|
13
|
+
for (var prop in b || (b = {}))
|
|
14
|
+
if (__hasOwnProp.call(b, prop))
|
|
15
|
+
__defNormalProp(a, prop, b[prop]);
|
|
16
|
+
if (__getOwnPropSymbols)
|
|
17
|
+
for (var prop of __getOwnPropSymbols(b)) {
|
|
18
|
+
if (__propIsEnum.call(b, prop))
|
|
19
|
+
__defNormalProp(a, prop, b[prop]);
|
|
20
|
+
}
|
|
21
|
+
return a;
|
|
22
|
+
};
|
|
23
|
+
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
24
|
+
|
|
25
|
+
// src/store/deposit.ts
|
|
26
|
+
function deposit(state) {
|
|
27
|
+
const token = {
|
|
28
|
+
key: state.key,
|
|
29
|
+
type: state.type
|
|
30
|
+
};
|
|
31
|
+
if (`family` in state) {
|
|
32
|
+
token.family = state.family;
|
|
33
|
+
}
|
|
34
|
+
return token;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// src/subject.ts
|
|
38
|
+
var Subject = class {
|
|
39
|
+
constructor() {
|
|
40
|
+
this.subscribers = /* @__PURE__ */ new Map();
|
|
41
|
+
}
|
|
42
|
+
subscribe(key, subscriber) {
|
|
43
|
+
this.subscribers.set(key, subscriber);
|
|
44
|
+
const unsubscribe = () => this.unsubscribe(key);
|
|
45
|
+
return unsubscribe;
|
|
46
|
+
}
|
|
47
|
+
unsubscribe(key) {
|
|
48
|
+
this.subscribers.delete(key);
|
|
49
|
+
}
|
|
50
|
+
next(value) {
|
|
51
|
+
for (const subscriber of this.subscribers.values()) {
|
|
52
|
+
subscriber(value);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
// src/transaction/abort-transaction.ts
|
|
58
|
+
var abortTransaction = (store) => {
|
|
59
|
+
var _a, _b;
|
|
60
|
+
if (store.transactionStatus.phase === `idle`) {
|
|
61
|
+
(_a = store.config.logger) == null ? void 0 : _a.warn(
|
|
62
|
+
`abortTransaction called outside of a transaction. This is probably a bug.`
|
|
63
|
+
);
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
store.transactionStatus = { phase: `idle` };
|
|
67
|
+
(_b = store.config.logger) == null ? void 0 : _b.info(`\u{1FA82}`, `transaction fail`);
|
|
68
|
+
};
|
|
69
|
+
var applyTransaction = (output, store) => {
|
|
70
|
+
var _a, _b, _c, _d, _e;
|
|
71
|
+
if (store.transactionStatus.phase !== `building`) {
|
|
72
|
+
(_a = store.config.logger) == null ? void 0 : _a.warn(
|
|
73
|
+
`abortTransaction called outside of a transaction. This is probably a bug.`
|
|
74
|
+
);
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
store.transactionStatus.phase = `applying`;
|
|
78
|
+
store.transactionStatus.output = output;
|
|
79
|
+
const { atomUpdates } = store.transactionStatus;
|
|
80
|
+
(_b = store.config.logger) == null ? void 0 : _b.info(
|
|
81
|
+
`\u{1F6C3} applying transaction "${store.transactionStatus.key}" with ${atomUpdates.length} updates.`
|
|
82
|
+
);
|
|
83
|
+
(_c = store.config.logger) == null ? void 0 : _c.info(`\u{1F6C3} the updates are:`, atomUpdates);
|
|
84
|
+
for (const { key, newValue } of atomUpdates) {
|
|
85
|
+
const token = { key, type: `atom` };
|
|
86
|
+
if (!store.valueMap.has(token.key)) {
|
|
87
|
+
if (token.family) {
|
|
88
|
+
const family = store.families.get(token.family.key);
|
|
89
|
+
if (family) {
|
|
90
|
+
family(token.family.subKey);
|
|
91
|
+
}
|
|
92
|
+
} else {
|
|
93
|
+
const newAtom = store.transactionStatus.core.atoms.get(token.key);
|
|
94
|
+
if (!newAtom) {
|
|
95
|
+
throw new Error(
|
|
96
|
+
`Absurd Error: Atom "${token.key}" not found while copying updates from transaction "${store.transactionStatus.key}" to store "${store.config.name}"`
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
store.atoms.set(newAtom.key, newAtom);
|
|
100
|
+
store.valueMap.set(newAtom.key, newAtom.default);
|
|
101
|
+
(_d = store.config.logger) == null ? void 0 : _d.info(`\u{1F527}`, `add atom "${newAtom.key}"`);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
setState(token, newValue, store);
|
|
105
|
+
}
|
|
106
|
+
const myTransaction = withdraw(
|
|
107
|
+
{ key: store.transactionStatus.key, type: `transaction` },
|
|
108
|
+
store
|
|
109
|
+
);
|
|
110
|
+
if (myTransaction === null) {
|
|
111
|
+
throw new Error(
|
|
112
|
+
`Transaction "${store.transactionStatus.key}" not found. Absurd. How is this running?`
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
myTransaction.subject.next({
|
|
116
|
+
key: store.transactionStatus.key,
|
|
117
|
+
atomUpdates,
|
|
118
|
+
output,
|
|
119
|
+
params: store.transactionStatus.params
|
|
120
|
+
});
|
|
121
|
+
store.transactionStatus = { phase: `idle` };
|
|
122
|
+
(_e = store.config.logger) == null ? void 0 : _e.info(`\u{1F6EC}`, `transaction "${myTransaction.key}" applied`);
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
// ../../rel8/junction/src/junction.ts
|
|
126
|
+
var Junction = class {
|
|
127
|
+
constructor(data, config) {
|
|
128
|
+
this.relations = /* @__PURE__ */ new Map();
|
|
129
|
+
this.contents = /* @__PURE__ */ new Map();
|
|
130
|
+
this.makeContentKey = (a, b) => `${a}:${b}`;
|
|
131
|
+
var _a, _b;
|
|
132
|
+
this.a = data.between[0];
|
|
133
|
+
this.b = data.between[1];
|
|
134
|
+
this.cardinality = data.cardinality;
|
|
135
|
+
this.relations = new Map((_a = data.relations) == null ? void 0 : _a.map(([a, b]) => [a, new Set(b)]));
|
|
136
|
+
this.contents = new Map(data.contents);
|
|
137
|
+
this.isContent = (_b = config == null ? void 0 : config.isContent) != null ? _b : null;
|
|
138
|
+
if (config == null ? void 0 : config.makeContentKey) {
|
|
139
|
+
this.makeContentKey = config.makeContentKey;
|
|
140
|
+
}
|
|
141
|
+
if (config == null ? void 0 : config.externalStore) {
|
|
142
|
+
const externalStore = config.externalStore;
|
|
143
|
+
this.has = (a, b) => externalStore.has(a, b);
|
|
144
|
+
this.addRelation = (a, b) => {
|
|
145
|
+
externalStore.addRelation(a, b);
|
|
146
|
+
return this;
|
|
147
|
+
};
|
|
148
|
+
this.deleteRelation = (a, b) => {
|
|
149
|
+
externalStore.deleteRelation(a, b);
|
|
150
|
+
return this;
|
|
151
|
+
};
|
|
152
|
+
this.getRelatedKeys = (key) => externalStore.getRelatedKeys(key);
|
|
153
|
+
if (externalStore.getContent) {
|
|
154
|
+
this.getContentInternal = (contentKey) => {
|
|
155
|
+
return externalStore.getContent(contentKey);
|
|
156
|
+
};
|
|
157
|
+
this.setContent = (contentKey, content) => {
|
|
158
|
+
externalStore.setContent(contentKey, content);
|
|
159
|
+
return this;
|
|
160
|
+
};
|
|
161
|
+
this.deleteContent = (contentKey) => {
|
|
162
|
+
externalStore.deleteContent(contentKey);
|
|
163
|
+
return this;
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
getRelatedKeys(key) {
|
|
169
|
+
return this.relations.get(key);
|
|
170
|
+
}
|
|
171
|
+
addRelation(a, b) {
|
|
172
|
+
const aRelations = this.relations.get(a);
|
|
173
|
+
const bRelations = this.relations.get(b);
|
|
174
|
+
if (aRelations) {
|
|
175
|
+
aRelations.add(b);
|
|
176
|
+
} else {
|
|
177
|
+
this.relations.set(a, /* @__PURE__ */ new Set([b]));
|
|
178
|
+
}
|
|
179
|
+
if (bRelations) {
|
|
180
|
+
bRelations.add(a);
|
|
181
|
+
} else {
|
|
182
|
+
this.relations.set(b, /* @__PURE__ */ new Set([a]));
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
deleteRelation(a, b) {
|
|
186
|
+
const aRelations = this.relations.get(a);
|
|
187
|
+
if (aRelations) {
|
|
188
|
+
aRelations.delete(b);
|
|
189
|
+
if (aRelations.size === 0) {
|
|
190
|
+
this.relations.delete(a);
|
|
191
|
+
}
|
|
192
|
+
const bRelations = this.relations.get(b);
|
|
193
|
+
if (bRelations) {
|
|
194
|
+
bRelations.delete(a);
|
|
195
|
+
if (bRelations.size === 0) {
|
|
196
|
+
this.relations.delete(b);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
getContentInternal(contentKey) {
|
|
202
|
+
return this.contents.get(contentKey);
|
|
203
|
+
}
|
|
204
|
+
setContent(contentKey, content) {
|
|
205
|
+
this.contents.set(contentKey, content);
|
|
206
|
+
}
|
|
207
|
+
deleteContent(contentKey) {
|
|
208
|
+
this.contents.delete(contentKey);
|
|
209
|
+
}
|
|
210
|
+
toJSON() {
|
|
211
|
+
return {
|
|
212
|
+
between: [this.a, this.b],
|
|
213
|
+
cardinality: this.cardinality,
|
|
214
|
+
relations: [...this.relations.entries()].map(([a, b]) => [a, [...b]]),
|
|
215
|
+
contents: [...this.contents.entries()]
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
set(a, ...rest) {
|
|
219
|
+
var _a;
|
|
220
|
+
const b = (
|
|
221
|
+
// @ts-expect-error we deduce hereby that this.b may index a
|
|
222
|
+
typeof rest[0] === `string` ? rest[0] : a[this.b]
|
|
223
|
+
);
|
|
224
|
+
const content = ((_a = rest[1]) != null ? _a : typeof rest[0] === `string`) ? void 0 : rest[0];
|
|
225
|
+
a = typeof a === `string` ? a : a[this.a];
|
|
226
|
+
switch (this.cardinality) {
|
|
227
|
+
case `1:1`: {
|
|
228
|
+
const bPrev = this.getRelatedKey(a);
|
|
229
|
+
if (bPrev && bPrev !== b)
|
|
230
|
+
this.delete(bPrev, a);
|
|
231
|
+
}
|
|
232
|
+
case `1:n`: {
|
|
233
|
+
const aPrev = this.getRelatedKey(b);
|
|
234
|
+
if (aPrev && aPrev !== a)
|
|
235
|
+
this.delete(aPrev, b);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
this.addRelation(a, b);
|
|
239
|
+
if (content) {
|
|
240
|
+
const contentKey = this.makeContentKey(a, b);
|
|
241
|
+
this.setContent(contentKey, content);
|
|
242
|
+
}
|
|
243
|
+
return this;
|
|
244
|
+
}
|
|
245
|
+
delete(x, b) {
|
|
246
|
+
b = typeof b === `string` ? b : x[this.b];
|
|
247
|
+
const a = typeof x === `string` ? x : x[this.a];
|
|
248
|
+
if (a === void 0 && typeof b === `string`) {
|
|
249
|
+
const bRelations = this.getRelatedKeys(b);
|
|
250
|
+
if (bRelations) {
|
|
251
|
+
bRelations.forEach((a2) => this.delete(a2, b));
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
if (typeof a === `string` && b === void 0) {
|
|
255
|
+
const aRelations = this.getRelatedKeys(a);
|
|
256
|
+
if (aRelations) {
|
|
257
|
+
aRelations.forEach((b2) => {
|
|
258
|
+
this.delete(a, b2);
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
if (typeof a === `string` && typeof b === `string`) {
|
|
263
|
+
this.deleteRelation(a, b);
|
|
264
|
+
const contentKey = this.makeContentKey(a, b);
|
|
265
|
+
this.deleteContent(contentKey);
|
|
266
|
+
}
|
|
267
|
+
return this;
|
|
268
|
+
}
|
|
269
|
+
getRelatedKey(key) {
|
|
270
|
+
const relations = this.getRelatedKeys(key);
|
|
271
|
+
if (relations) {
|
|
272
|
+
if (relations.size > 1) {
|
|
273
|
+
console.warn(
|
|
274
|
+
`${relations.size} related keys were found for key "${key}": (${[
|
|
275
|
+
...relations
|
|
276
|
+
].map((k) => `"${k}"`).join(`, `)}). Only one related key was expected.`
|
|
277
|
+
);
|
|
278
|
+
}
|
|
279
|
+
for (const relation of relations) {
|
|
280
|
+
return relation;
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
getContent(a, b) {
|
|
285
|
+
const contentKey = this.makeContentKey(a, b);
|
|
286
|
+
return this.getContentInternal(contentKey);
|
|
287
|
+
}
|
|
288
|
+
getRelationEntries(input) {
|
|
289
|
+
const a = input[this.a];
|
|
290
|
+
const b = input[this.b];
|
|
291
|
+
if (a !== void 0 && b === void 0) {
|
|
292
|
+
const aRelations = this.getRelatedKeys(a);
|
|
293
|
+
if (aRelations) {
|
|
294
|
+
return [...aRelations].map((b2) => {
|
|
295
|
+
var _a;
|
|
296
|
+
return [b2, (_a = this.getContent(a, b2)) != null ? _a : null];
|
|
297
|
+
});
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
if (a === void 0 && b !== void 0) {
|
|
301
|
+
const bRelations = this.getRelatedKeys(b);
|
|
302
|
+
if (bRelations) {
|
|
303
|
+
return [...bRelations].map((a2) => {
|
|
304
|
+
var _a;
|
|
305
|
+
return [a2, (_a = this.getContent(a2, b)) != null ? _a : null];
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
return [];
|
|
310
|
+
}
|
|
311
|
+
has(a, b) {
|
|
312
|
+
var _a;
|
|
313
|
+
if (b) {
|
|
314
|
+
const setA = this.getRelatedKeys(a);
|
|
315
|
+
return (_a = setA == null ? void 0 : setA.has(b)) != null ? _a : false;
|
|
316
|
+
}
|
|
317
|
+
return this.relations.has(a);
|
|
318
|
+
}
|
|
319
|
+
};
|
|
320
|
+
|
|
321
|
+
// src/transaction/build-transaction.ts
|
|
322
|
+
var buildTransaction = (key, params, store) => {
|
|
323
|
+
var _a;
|
|
324
|
+
store.transactionStatus = {
|
|
325
|
+
key,
|
|
326
|
+
phase: `building`,
|
|
327
|
+
time: Date.now(),
|
|
328
|
+
core: {
|
|
329
|
+
atoms: new Map(store.atoms),
|
|
330
|
+
atomsThatAreDefault: new Set(store.atomsThatAreDefault),
|
|
331
|
+
families: new Map(store.families),
|
|
332
|
+
operation: { open: false },
|
|
333
|
+
readonlySelectors: new Map(store.readonlySelectors),
|
|
334
|
+
timelines: new Map(store.timelines),
|
|
335
|
+
timelineAtoms: new Junction(store.timelineAtoms.toJSON()),
|
|
336
|
+
trackers: /* @__PURE__ */ new Map(),
|
|
337
|
+
transactions: new Map(store.transactions),
|
|
338
|
+
selectorAtoms: new Junction(store.selectorAtoms.toJSON()),
|
|
339
|
+
selectorGraph: new Junction(store.selectorGraph.toJSON(), {
|
|
340
|
+
makeContentKey: (...keys) => keys.sort().join(`:`)
|
|
341
|
+
}),
|
|
342
|
+
selectors: new Map(store.selectors),
|
|
343
|
+
valueMap: new Map(store.valueMap)
|
|
344
|
+
},
|
|
345
|
+
atomUpdates: [],
|
|
346
|
+
params,
|
|
347
|
+
output: void 0
|
|
348
|
+
};
|
|
349
|
+
(_a = store.config.logger) == null ? void 0 : _a.info(
|
|
350
|
+
`\u{1F6EB}`,
|
|
351
|
+
`transaction "${key}" building in store "${store.config.name}"`
|
|
352
|
+
);
|
|
353
|
+
};
|
|
354
|
+
|
|
355
|
+
// src/transaction/transaction-internal.ts
|
|
356
|
+
function transaction__INTERNAL(options, store = IMPLICIT.STORE) {
|
|
357
|
+
const newTransaction = {
|
|
358
|
+
key: options.key,
|
|
359
|
+
type: `transaction`,
|
|
360
|
+
run: (...params) => {
|
|
361
|
+
var _a;
|
|
362
|
+
buildTransaction(options.key, params, store);
|
|
363
|
+
try {
|
|
364
|
+
const output = options.do(
|
|
365
|
+
{
|
|
366
|
+
get: (token2) => getState(token2, store),
|
|
367
|
+
set: (token2, value) => setState(token2, value, store)
|
|
368
|
+
},
|
|
369
|
+
...params
|
|
370
|
+
);
|
|
371
|
+
applyTransaction(output, store);
|
|
372
|
+
return output;
|
|
373
|
+
} catch (thrown) {
|
|
374
|
+
abortTransaction(store);
|
|
375
|
+
(_a = store.config.logger) == null ? void 0 : _a.error(
|
|
376
|
+
`Transaction "${options.key}" failed in store "${store.config.name}":`,
|
|
377
|
+
thrown
|
|
378
|
+
);
|
|
379
|
+
throw thrown;
|
|
380
|
+
}
|
|
381
|
+
},
|
|
382
|
+
install: (store2) => transaction__INTERNAL(options, store2),
|
|
383
|
+
subject: new Subject()
|
|
384
|
+
};
|
|
385
|
+
const core = target(store);
|
|
386
|
+
core.transactions.set(newTransaction.key, newTransaction);
|
|
387
|
+
const token = deposit(newTransaction);
|
|
388
|
+
store.subject.transactionCreation.next(token);
|
|
389
|
+
return token;
|
|
390
|
+
}
|
|
391
|
+
var target = (store = IMPLICIT.STORE) => store.transactionStatus.phase === `building` ? store.transactionStatus.core : store;
|
|
392
|
+
var redoTransactionUpdate = (update, store) => {
|
|
393
|
+
var _a;
|
|
394
|
+
(_a = store.config.logger) == null ? void 0 : _a.info(` \u23ED redo transaction "${update.key}" (redo)`);
|
|
395
|
+
for (const { key, newValue } of update.atomUpdates) {
|
|
396
|
+
const token = { key, type: `atom` };
|
|
397
|
+
const state = withdraw(token, store);
|
|
398
|
+
if (state === null) {
|
|
399
|
+
throw new Error(
|
|
400
|
+
`State "${token.key}" not found in this store. This is surprising, because we are navigating the history of the store.`
|
|
401
|
+
);
|
|
402
|
+
}
|
|
403
|
+
setState(state, newValue, store);
|
|
404
|
+
}
|
|
405
|
+
};
|
|
406
|
+
var undoTransactionUpdate = (update, store) => {
|
|
407
|
+
var _a;
|
|
408
|
+
(_a = store.config.logger) == null ? void 0 : _a.info(` \u23EE undo transaction "${update.key}" (undo)`);
|
|
409
|
+
for (const { key, oldValue } of update.atomUpdates) {
|
|
410
|
+
const token = { key, type: `atom` };
|
|
411
|
+
const state = withdraw(token, store);
|
|
412
|
+
if (state === null) {
|
|
413
|
+
throw new Error(
|
|
414
|
+
`State "${token.key}" not found in this store. This is surprising, because we are navigating the history of the store.`
|
|
415
|
+
);
|
|
416
|
+
}
|
|
417
|
+
setState(state, oldValue, store);
|
|
418
|
+
}
|
|
419
|
+
};
|
|
420
|
+
|
|
421
|
+
// src/transaction/index.ts
|
|
422
|
+
var TRANSACTION_PHASES = [`idle`, `building`, `applying`];
|
|
423
|
+
|
|
424
|
+
// src/store/lookup.ts
|
|
425
|
+
function lookup(key, store) {
|
|
426
|
+
var _a;
|
|
427
|
+
const core = target(store);
|
|
428
|
+
let type = core.atoms.has(key) ? `atom` : core.selectors.has(key) ? `selector` : core.readonlySelectors.has(key) ? `readonly_selector` : ``;
|
|
429
|
+
if (!type) {
|
|
430
|
+
const errorId = Math.random().toString(36);
|
|
431
|
+
type = `\u{1F6A8} This state could not be found by lookup! Check the console for "${errorId}"`;
|
|
432
|
+
(_a = store.config.logger) == null ? void 0 : _a.error(
|
|
433
|
+
`${errorId}: Key "${key}" does not exist in the store.`
|
|
434
|
+
);
|
|
435
|
+
}
|
|
436
|
+
return { key, type };
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
// src/store/store.ts
|
|
440
|
+
var Store = class {
|
|
441
|
+
constructor(name, store = null) {
|
|
442
|
+
this.valueMap = /* @__PURE__ */ new Map();
|
|
443
|
+
this.atoms = /* @__PURE__ */ new Map();
|
|
444
|
+
this.selectors = /* @__PURE__ */ new Map();
|
|
445
|
+
this.readonlySelectors = /* @__PURE__ */ new Map();
|
|
446
|
+
this.trackers = /* @__PURE__ */ new Map();
|
|
447
|
+
this.families = /* @__PURE__ */ new Map();
|
|
448
|
+
this.timelines = /* @__PURE__ */ new Map();
|
|
449
|
+
this.transactions = /* @__PURE__ */ new Map();
|
|
450
|
+
this.atomsThatAreDefault = /* @__PURE__ */ new Set();
|
|
451
|
+
this.timelineAtoms = new Junction({
|
|
452
|
+
between: [`timelineKey`, `atomKey`],
|
|
453
|
+
cardinality: `1:n`
|
|
454
|
+
});
|
|
455
|
+
this.selectorAtoms = new Junction({
|
|
456
|
+
between: [`selectorKey`, `atomKey`],
|
|
457
|
+
cardinality: `n:n`
|
|
458
|
+
});
|
|
459
|
+
this.selectorGraph = new Junction(
|
|
460
|
+
{
|
|
461
|
+
between: [`upstreamSelectorKey`, `downstreamSelectorKey`],
|
|
462
|
+
cardinality: `n:n`
|
|
463
|
+
},
|
|
464
|
+
{
|
|
465
|
+
makeContentKey: (...keys) => keys.sort().join(`:`)
|
|
466
|
+
}
|
|
467
|
+
);
|
|
468
|
+
this.subject = {
|
|
469
|
+
atomCreation: new Subject(),
|
|
470
|
+
selectorCreation: new Subject(),
|
|
471
|
+
transactionCreation: new Subject(),
|
|
472
|
+
timelineCreation: new Subject(),
|
|
473
|
+
operationStatus: new Subject()
|
|
474
|
+
};
|
|
475
|
+
this.operation = { open: false };
|
|
476
|
+
this.transactionStatus = { phase: `idle` };
|
|
477
|
+
this.config = {
|
|
478
|
+
name: `IMPLICIT_STORE`,
|
|
479
|
+
logger: __spreadProps(__spreadValues({}, console), { info: () => void 0 }),
|
|
480
|
+
logger__INTERNAL: console
|
|
481
|
+
};
|
|
482
|
+
var _a;
|
|
483
|
+
if (store !== null) {
|
|
484
|
+
this.valueMap = new Map(store == null ? void 0 : store.valueMap);
|
|
485
|
+
this.operation = __spreadValues({}, store == null ? void 0 : store.operation);
|
|
486
|
+
this.transactionStatus = __spreadValues({}, store == null ? void 0 : store.transactionStatus);
|
|
487
|
+
this.config = __spreadProps(__spreadValues({}, store == null ? void 0 : store.config), {
|
|
488
|
+
logger__INTERNAL: console,
|
|
489
|
+
logger: __spreadValues(__spreadProps(__spreadValues({}, console), {
|
|
490
|
+
info: () => void 0
|
|
491
|
+
}), (_a = store == null ? void 0 : store.config) == null ? void 0 : _a.logger),
|
|
492
|
+
name
|
|
493
|
+
});
|
|
494
|
+
}
|
|
495
|
+
store == null ? void 0 : store.atoms.forEach((atom) => {
|
|
496
|
+
atom.install(this);
|
|
497
|
+
});
|
|
498
|
+
store == null ? void 0 : store.readonlySelectors.forEach((selector) => {
|
|
499
|
+
selector.install(this);
|
|
500
|
+
});
|
|
501
|
+
store == null ? void 0 : store.selectors.forEach((selector) => {
|
|
502
|
+
selector.install(this);
|
|
503
|
+
});
|
|
504
|
+
store == null ? void 0 : store.transactions.forEach((tx) => {
|
|
505
|
+
tx.install(this);
|
|
506
|
+
});
|
|
507
|
+
store == null ? void 0 : store.timelines.forEach((timeline) => {
|
|
508
|
+
timeline.install(this);
|
|
509
|
+
});
|
|
510
|
+
}
|
|
511
|
+
};
|
|
512
|
+
var IMPLICIT = {
|
|
513
|
+
STORE_INTERNAL: void 0,
|
|
514
|
+
get STORE() {
|
|
515
|
+
var _a;
|
|
516
|
+
return (_a = this.STORE_INTERNAL) != null ? _a : this.STORE_INTERNAL = new Store(`IMPLICIT_STORE`);
|
|
517
|
+
}
|
|
518
|
+
};
|
|
519
|
+
var clearStore = (store = IMPLICIT.STORE) => {
|
|
520
|
+
const { config } = store;
|
|
521
|
+
Object.assign(store, new Store(config.name));
|
|
522
|
+
store.config = config;
|
|
523
|
+
};
|
|
524
|
+
|
|
525
|
+
// src/timeline/add-atom-to-timeline.ts
|
|
526
|
+
var addAtomToTimeline = (atomToken, tl, store = IMPLICIT.STORE) => {
|
|
527
|
+
const atom = withdraw(atomToken, store);
|
|
528
|
+
if (atom === null) {
|
|
529
|
+
throw new Error(
|
|
530
|
+
`Cannot subscribe to atom "${atomToken.key}" because it has not been initialized in store "${store.config.name}"`
|
|
531
|
+
);
|
|
532
|
+
}
|
|
533
|
+
atom.subject.subscribe(`timeline`, (update) => {
|
|
534
|
+
var _a, _b, _c, _d, _e;
|
|
535
|
+
const currentSelectorKey = store.operation.open && store.operation.token.type === `selector` ? store.operation.token.key : null;
|
|
536
|
+
const currentSelectorTime = store.operation.open && store.operation.token.type === `selector` ? store.operation.time : null;
|
|
537
|
+
const currentTransactionKey = store.transactionStatus.phase === `applying` ? store.transactionStatus.key : null;
|
|
538
|
+
const currentTransactionTime = store.transactionStatus.phase === `applying` ? store.transactionStatus.time : null;
|
|
539
|
+
(_a = store.config.logger) == null ? void 0 : _a.info(
|
|
540
|
+
`\u23F3 timeline "${tl.key}" saw atom "${atomToken.key}" go (`,
|
|
541
|
+
update.oldValue,
|
|
542
|
+
`->`,
|
|
543
|
+
update.newValue,
|
|
544
|
+
currentTransactionKey ? `) in transaction "${currentTransactionKey}"` : currentSelectorKey ? `) in selector "${currentSelectorKey}"` : `)`
|
|
545
|
+
);
|
|
546
|
+
if (tl.timeTraveling === null) {
|
|
547
|
+
if (tl.selectorTime && tl.selectorTime !== currentSelectorTime) {
|
|
548
|
+
const mostRecentUpdate = tl.history.at(-1);
|
|
549
|
+
if (mostRecentUpdate === void 0) {
|
|
550
|
+
throw new Error(
|
|
551
|
+
`Timeline "${tl.key}" has a selectorTime, but no history. This is most likely a bug in AtomIO.`
|
|
552
|
+
);
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
if (currentTransactionKey && store.transactionStatus.phase === `applying`) {
|
|
556
|
+
const currentTransaction = withdraw(
|
|
557
|
+
{ key: currentTransactionKey, type: `transaction` },
|
|
558
|
+
store
|
|
559
|
+
);
|
|
560
|
+
if (currentTransaction === null) {
|
|
561
|
+
throw new Error(
|
|
562
|
+
`Transaction "${currentTransactionKey}" not found in store "${store.config.name}". This is surprising, because we are in the application phase of "${currentTransactionKey}".`
|
|
563
|
+
);
|
|
564
|
+
}
|
|
565
|
+
if (tl.transactionKey !== currentTransactionKey) {
|
|
566
|
+
if (tl.transactionKey) {
|
|
567
|
+
(_b = store.config.logger) == null ? void 0 : _b.error(
|
|
568
|
+
`Timeline "${tl.key}" was unable to resolve transaction "${tl.transactionKey}. This is probably a bug.`
|
|
569
|
+
);
|
|
570
|
+
}
|
|
571
|
+
tl.transactionKey = currentTransactionKey;
|
|
572
|
+
const unsubscribe = currentTransaction.subject.subscribe(
|
|
573
|
+
`timeline:${tl.key}`,
|
|
574
|
+
(update2) => {
|
|
575
|
+
var _a2;
|
|
576
|
+
unsubscribe();
|
|
577
|
+
if (tl.timeTraveling === null && currentTransactionTime) {
|
|
578
|
+
if (tl.at !== tl.history.length) {
|
|
579
|
+
tl.history.splice(tl.at);
|
|
580
|
+
}
|
|
581
|
+
const atomUpdates = update2.atomUpdates.filter((atomUpdate) => {
|
|
582
|
+
const core = target(store);
|
|
583
|
+
const atomOrFamilyKeys = core.timelineAtoms.getRelatedKeys(
|
|
584
|
+
tl.key
|
|
585
|
+
);
|
|
586
|
+
return atomOrFamilyKeys ? [...atomOrFamilyKeys].some(
|
|
587
|
+
(key) => {
|
|
588
|
+
var _a3;
|
|
589
|
+
return key === atomUpdate.key || key === ((_a3 = atomUpdate.family) == null ? void 0 : _a3.key);
|
|
590
|
+
}
|
|
591
|
+
) : false;
|
|
592
|
+
});
|
|
593
|
+
const timelineTransactionUpdate = __spreadProps(__spreadValues({
|
|
594
|
+
type: `transaction_update`,
|
|
595
|
+
timestamp: currentTransactionTime
|
|
596
|
+
}, update2), {
|
|
597
|
+
atomUpdates
|
|
598
|
+
});
|
|
599
|
+
tl.history.push(timelineTransactionUpdate);
|
|
600
|
+
tl.at = tl.history.length;
|
|
601
|
+
tl.subject.next(timelineTransactionUpdate);
|
|
602
|
+
}
|
|
603
|
+
tl.transactionKey = null;
|
|
604
|
+
(_a2 = store.config.logger) == null ? void 0 : _a2.info(
|
|
605
|
+
`\u231B timeline "${tl.key}" got a transaction_update "${update2.key}"`
|
|
606
|
+
);
|
|
607
|
+
}
|
|
608
|
+
);
|
|
609
|
+
}
|
|
610
|
+
} else if (currentSelectorKey && currentSelectorTime) {
|
|
611
|
+
let latestUpdate = tl.history.at(-1);
|
|
612
|
+
if (currentSelectorTime !== tl.selectorTime) {
|
|
613
|
+
latestUpdate = {
|
|
614
|
+
type: `selector_update`,
|
|
615
|
+
timestamp: currentSelectorTime,
|
|
616
|
+
key: currentSelectorKey,
|
|
617
|
+
atomUpdates: []
|
|
618
|
+
};
|
|
619
|
+
latestUpdate.atomUpdates.push(__spreadValues({
|
|
620
|
+
key: atom.key,
|
|
621
|
+
type: `atom_update`
|
|
622
|
+
}, update));
|
|
623
|
+
if (tl.at !== tl.history.length) {
|
|
624
|
+
tl.history.splice(tl.at);
|
|
625
|
+
}
|
|
626
|
+
tl.history.push(latestUpdate);
|
|
627
|
+
(_c = store.config.logger) == null ? void 0 : _c.info(
|
|
628
|
+
`\u231B timeline "${tl.key}" got a selector_update "${currentSelectorKey}" with`,
|
|
629
|
+
latestUpdate.atomUpdates.map((atomUpdate) => atomUpdate.key)
|
|
630
|
+
);
|
|
631
|
+
tl.at = tl.history.length;
|
|
632
|
+
tl.selectorTime = currentSelectorTime;
|
|
633
|
+
} else {
|
|
634
|
+
if ((latestUpdate == null ? void 0 : latestUpdate.type) === `selector_update`) {
|
|
635
|
+
latestUpdate.atomUpdates.push(__spreadValues({
|
|
636
|
+
key: atom.key,
|
|
637
|
+
type: `atom_update`
|
|
638
|
+
}, update));
|
|
639
|
+
(_d = store.config.logger) == null ? void 0 : _d.info(
|
|
640
|
+
` \u231B timeline "${tl.key}" set selector_update "${currentSelectorKey}" to`,
|
|
641
|
+
latestUpdate == null ? void 0 : latestUpdate.atomUpdates.map((atomUpdate) => atomUpdate.key)
|
|
642
|
+
);
|
|
643
|
+
}
|
|
644
|
+
}
|
|
645
|
+
if (latestUpdate)
|
|
646
|
+
tl.subject.next(latestUpdate);
|
|
647
|
+
} else {
|
|
648
|
+
const timestamp = Date.now();
|
|
649
|
+
tl.selectorTime = null;
|
|
650
|
+
if (tl.at !== tl.history.length) {
|
|
651
|
+
tl.history.splice(tl.at);
|
|
652
|
+
}
|
|
653
|
+
const atomUpdate = {
|
|
654
|
+
type: `atom_update`,
|
|
655
|
+
timestamp,
|
|
656
|
+
key: atom.key,
|
|
657
|
+
oldValue: update.oldValue,
|
|
658
|
+
newValue: update.newValue
|
|
659
|
+
};
|
|
660
|
+
if (atom.family) {
|
|
661
|
+
atomUpdate.family = atom.family;
|
|
662
|
+
}
|
|
663
|
+
tl.history.push(atomUpdate);
|
|
664
|
+
tl.subject.next(atomUpdate);
|
|
665
|
+
(_e = store.config.logger) == null ? void 0 : _e.info(
|
|
666
|
+
`\u231B timeline "${tl.key}" got an atom_update to "${atom.key}"`
|
|
667
|
+
);
|
|
668
|
+
tl.at = tl.history.length;
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
});
|
|
672
|
+
};
|
|
673
|
+
var redo__INTERNAL = (token, store = IMPLICIT.STORE) => {
|
|
674
|
+
var _a, _b, _c, _d;
|
|
675
|
+
(_a = store.config.logger) == null ? void 0 : _a.info(`\u23E9 redo "${token.key}"`);
|
|
676
|
+
const timelineData = store.timelines.get(token.key);
|
|
677
|
+
if (!timelineData) {
|
|
678
|
+
(_b = store.config.logger) == null ? void 0 : _b.error(
|
|
679
|
+
`Failed to redo on timeline "${token.key}". This timeline has not been initialized.`
|
|
680
|
+
);
|
|
681
|
+
return;
|
|
682
|
+
}
|
|
683
|
+
if (timelineData.at === timelineData.history.length) {
|
|
684
|
+
(_c = store.config.logger) == null ? void 0 : _c.warn(
|
|
685
|
+
`Failed to redo at the end of timeline "${token.key}". There is nothing to redo.`
|
|
686
|
+
);
|
|
687
|
+
return;
|
|
688
|
+
}
|
|
689
|
+
timelineData.timeTraveling = `into_future`;
|
|
690
|
+
const update = timelineData.history[timelineData.at];
|
|
691
|
+
switch (update.type) {
|
|
692
|
+
case `atom_update`: {
|
|
693
|
+
const { key, newValue } = update;
|
|
694
|
+
setState({ key, type: `atom` }, newValue, store);
|
|
695
|
+
break;
|
|
696
|
+
}
|
|
697
|
+
case `selector_update`:
|
|
698
|
+
case `transaction_update`: {
|
|
699
|
+
for (const atomUpdate of update.atomUpdates) {
|
|
700
|
+
const { key, newValue } = atomUpdate;
|
|
701
|
+
setState({ key, type: `atom` }, newValue, store);
|
|
702
|
+
}
|
|
703
|
+
break;
|
|
704
|
+
}
|
|
705
|
+
}
|
|
706
|
+
++timelineData.at;
|
|
707
|
+
timelineData.subject.next(`redo`);
|
|
708
|
+
timelineData.timeTraveling = null;
|
|
709
|
+
(_d = store.config.logger) == null ? void 0 : _d.info(
|
|
710
|
+
`\u23F9\uFE0F "${token.key}" is now at ${timelineData.at} / ${timelineData.history.length}`
|
|
711
|
+
);
|
|
712
|
+
};
|
|
713
|
+
var undo__INTERNAL = (token, store = IMPLICIT.STORE) => {
|
|
714
|
+
var _a, _b, _c, _d;
|
|
715
|
+
(_a = store.config.logger) == null ? void 0 : _a.info(`\u23EA undo "${token.key}"`);
|
|
716
|
+
const timelineData = store.timelines.get(token.key);
|
|
717
|
+
if (!timelineData) {
|
|
718
|
+
(_b = store.config.logger) == null ? void 0 : _b.error(
|
|
719
|
+
`Failed to undo on timeline "${token.key}". This timeline has not been initialized.`
|
|
720
|
+
);
|
|
721
|
+
return;
|
|
722
|
+
}
|
|
723
|
+
if (timelineData.at === 0) {
|
|
724
|
+
(_c = store.config.logger) == null ? void 0 : _c.warn(
|
|
725
|
+
`Failed to undo at the beginning of timeline "${token.key}". There is nothing to undo.`
|
|
726
|
+
);
|
|
727
|
+
return;
|
|
728
|
+
}
|
|
729
|
+
timelineData.timeTraveling = `into_past`;
|
|
730
|
+
--timelineData.at;
|
|
731
|
+
const update = timelineData.history[timelineData.at];
|
|
732
|
+
switch (update.type) {
|
|
733
|
+
case `atom_update`: {
|
|
734
|
+
const { key, oldValue } = update;
|
|
735
|
+
setState({ key, type: `atom` }, oldValue, store);
|
|
736
|
+
break;
|
|
737
|
+
}
|
|
738
|
+
case `selector_update`:
|
|
739
|
+
case `transaction_update`: {
|
|
740
|
+
for (const atomUpdate of [...update.atomUpdates].reverse()) {
|
|
741
|
+
const { key, oldValue } = atomUpdate;
|
|
742
|
+
setState({ key, type: `atom` }, oldValue, store);
|
|
743
|
+
}
|
|
744
|
+
break;
|
|
745
|
+
}
|
|
746
|
+
}
|
|
747
|
+
timelineData.subject.next(`undo`);
|
|
748
|
+
timelineData.timeTraveling = null;
|
|
749
|
+
(_d = store.config.logger) == null ? void 0 : _d.info(
|
|
750
|
+
`\u23F9\uFE0F "${token.key}" is now at ${timelineData.at} / ${timelineData.history.length}`
|
|
751
|
+
);
|
|
752
|
+
};
|
|
753
|
+
|
|
754
|
+
// src/timeline/timeline-internal.ts
|
|
755
|
+
function timeline__INTERNAL(options, store = IMPLICIT.STORE, data = null) {
|
|
756
|
+
var _a, _b, _c;
|
|
757
|
+
const tl = __spreadProps(__spreadValues({
|
|
758
|
+
type: `timeline`,
|
|
759
|
+
key: options.key,
|
|
760
|
+
at: 0,
|
|
761
|
+
timeTraveling: null,
|
|
762
|
+
selectorTime: null,
|
|
763
|
+
transactionKey: null
|
|
764
|
+
}, data), {
|
|
765
|
+
history: (_a = data == null ? void 0 : data.history.map((update) => __spreadValues({}, update))) != null ? _a : [],
|
|
766
|
+
install: (store2) => timeline__INTERNAL(options, store2, tl),
|
|
767
|
+
subject: new Subject()
|
|
768
|
+
});
|
|
769
|
+
const core = target(store);
|
|
770
|
+
for (const tokenOrFamily of options.atoms) {
|
|
771
|
+
const timelineKey = core.timelineAtoms.getRelatedKey(tokenOrFamily.key);
|
|
772
|
+
if (timelineKey) {
|
|
773
|
+
(_b = store.config.logger) == null ? void 0 : _b.error(
|
|
774
|
+
`\u274C Failed to add atom "${tokenOrFamily.key}" to timeline "${options.key}" because it belongs to timeline "${timelineKey}"`
|
|
775
|
+
);
|
|
776
|
+
continue;
|
|
777
|
+
}
|
|
778
|
+
if (tokenOrFamily.type === `atom_family`) {
|
|
779
|
+
const family = tokenOrFamily;
|
|
780
|
+
family.subject.subscribe(`timeline:${options.key}`, (token2) => {
|
|
781
|
+
if (!core.atoms.has(token2.key)) {
|
|
782
|
+
addAtomToTimeline(token2, tl, store);
|
|
783
|
+
}
|
|
784
|
+
});
|
|
785
|
+
} else {
|
|
786
|
+
const token2 = tokenOrFamily;
|
|
787
|
+
if (`family` in token2 && token2.family) {
|
|
788
|
+
const familyTimelineKey = core.timelineAtoms.getRelatedKey(
|
|
789
|
+
token2.family.key
|
|
790
|
+
);
|
|
791
|
+
if (familyTimelineKey) {
|
|
792
|
+
(_c = store.config.logger) == null ? void 0 : _c.error(
|
|
793
|
+
`\u274C Failed to add atom "${token2.key}" to timeline "${options.key}" because its family "${token2.family.key}" belongs to timeline "${familyTimelineKey}"`
|
|
794
|
+
);
|
|
795
|
+
continue;
|
|
796
|
+
}
|
|
797
|
+
}
|
|
798
|
+
addAtomToTimeline(token2, tl, store);
|
|
799
|
+
}
|
|
800
|
+
core.timelineAtoms = core.timelineAtoms.set({
|
|
801
|
+
atomKey: tokenOrFamily.key,
|
|
802
|
+
timelineKey: options.key
|
|
803
|
+
});
|
|
804
|
+
}
|
|
805
|
+
store.timelines.set(options.key, tl);
|
|
806
|
+
const token = {
|
|
807
|
+
key: options.key,
|
|
808
|
+
type: `timeline`
|
|
809
|
+
};
|
|
810
|
+
store.subject.timelineCreation.next(token);
|
|
811
|
+
return token;
|
|
812
|
+
}
|
|
813
|
+
|
|
814
|
+
// src/store/withdraw.ts
|
|
815
|
+
function withdraw(token, store) {
|
|
816
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
|
|
817
|
+
let core = target(store);
|
|
818
|
+
let state = (_d = (_c = (_b = (_a = core.atoms.get(token.key)) != null ? _a : core.selectors.get(token.key)) != null ? _b : core.readonlySelectors.get(token.key)) != null ? _c : core.transactions.get(token.key)) != null ? _d : core.timelines.get(token.key);
|
|
819
|
+
if (state) {
|
|
820
|
+
return state;
|
|
821
|
+
}
|
|
822
|
+
if (store.transactionStatus.phase === `applying`) {
|
|
823
|
+
core = store.transactionStatus.core;
|
|
824
|
+
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);
|
|
825
|
+
if (state) {
|
|
826
|
+
(_i = store.config.logger) == null ? void 0 : _i.info(`\u{1F6E0}\uFE0F add ${token.type} "${token.key}"`);
|
|
827
|
+
switch (state.type) {
|
|
828
|
+
case `atom`: {
|
|
829
|
+
store.atoms.set(token.key, state);
|
|
830
|
+
store.valueMap.set(token.key, state.default);
|
|
831
|
+
const stateKey = state.key;
|
|
832
|
+
const familyKey = (_j = state.family) == null ? void 0 : _j.key;
|
|
833
|
+
let timelineKey = core.timelineAtoms.getRelatedKey(stateKey);
|
|
834
|
+
if (timelineKey === void 0 && typeof familyKey === `string`) {
|
|
835
|
+
timelineKey = core.timelineAtoms.getRelatedKey(familyKey);
|
|
836
|
+
}
|
|
837
|
+
const timeline = typeof timelineKey === `string` ? store.timelines.get(timelineKey) : void 0;
|
|
838
|
+
if (timeline) {
|
|
839
|
+
addAtomToTimeline(state, timeline, store);
|
|
840
|
+
}
|
|
841
|
+
break;
|
|
842
|
+
}
|
|
843
|
+
case `selector`:
|
|
844
|
+
core.selectors.set(token.key, state);
|
|
845
|
+
break;
|
|
846
|
+
case `readonly_selector`:
|
|
847
|
+
core.readonlySelectors.set(token.key, state);
|
|
848
|
+
break;
|
|
849
|
+
case `transaction`:
|
|
850
|
+
core.transactions.set(token.key, state);
|
|
851
|
+
break;
|
|
852
|
+
case `timeline`:
|
|
853
|
+
core.timelines.set(token.key, state);
|
|
854
|
+
break;
|
|
855
|
+
}
|
|
856
|
+
return state;
|
|
857
|
+
}
|
|
858
|
+
}
|
|
859
|
+
return null;
|
|
860
|
+
}
|
|
861
|
+
|
|
862
|
+
// src/store/withdraw-new-family-member.ts
|
|
863
|
+
function withdrawNewFamilyMember(token, store) {
|
|
864
|
+
var _a;
|
|
865
|
+
(_a = store.config.logger) == null ? void 0 : _a.info(
|
|
866
|
+
`\u{1F46A} creating new family member "${token.key}" in store "${store.config.name}"`
|
|
867
|
+
);
|
|
868
|
+
if (token.family) {
|
|
869
|
+
const core = target(store);
|
|
870
|
+
const family = core.families.get(token.family.key);
|
|
871
|
+
if (family) {
|
|
872
|
+
const jsonSubKey = JSON.parse(token.family.subKey);
|
|
873
|
+
family(jsonSubKey);
|
|
874
|
+
const state = withdraw(token, store);
|
|
875
|
+
return state;
|
|
876
|
+
}
|
|
877
|
+
}
|
|
878
|
+
return null;
|
|
879
|
+
}
|
|
880
|
+
|
|
881
|
+
// src/caching.ts
|
|
882
|
+
var cacheValue = (key, value, store = IMPLICIT.STORE) => {
|
|
883
|
+
target(store).valueMap.set(key, value);
|
|
884
|
+
};
|
|
885
|
+
var readCachedValue = (key, store = IMPLICIT.STORE) => target(store).valueMap.get(key);
|
|
886
|
+
var isValueCached = (key, store = IMPLICIT.STORE) => target(store).valueMap.has(key);
|
|
887
|
+
var Tracker = class {
|
|
888
|
+
constructor(mutableState, store = IMPLICIT.STORE) {
|
|
889
|
+
this.unsubscribeFromInnerValue = null;
|
|
890
|
+
this.mutableState = mutableState;
|
|
891
|
+
this.latestUpdateState = this.initializeState(mutableState, store);
|
|
892
|
+
this.observeCore(mutableState, this.latestUpdateState, store);
|
|
893
|
+
this.updateCore(mutableState, this.latestUpdateState, store);
|
|
894
|
+
const core = target(store);
|
|
895
|
+
core.trackers.set(mutableState.key, this);
|
|
896
|
+
}
|
|
897
|
+
initializeState(mutableState, store = IMPLICIT.STORE) {
|
|
898
|
+
const latestUpdateStateKey = `*${mutableState.key}`;
|
|
899
|
+
deleteAtom(latestUpdateStateKey, target(store));
|
|
900
|
+
const familyMetaData = mutableState.family ? {
|
|
901
|
+
key: `*${mutableState.family.key}`,
|
|
902
|
+
subKey: mutableState.family.subKey
|
|
903
|
+
} : void 0;
|
|
904
|
+
const latestUpdateState = createAtom(
|
|
905
|
+
{
|
|
906
|
+
key: latestUpdateStateKey,
|
|
907
|
+
default: null
|
|
908
|
+
},
|
|
909
|
+
familyMetaData,
|
|
910
|
+
store
|
|
911
|
+
);
|
|
912
|
+
return latestUpdateState;
|
|
913
|
+
}
|
|
914
|
+
observeCore(mutableState, latestUpdateState, store = IMPLICIT.STORE) {
|
|
915
|
+
const originalInnerValue = AtomIO.getState(mutableState, store);
|
|
916
|
+
this.unsubscribeFromInnerValue = originalInnerValue.subscribe(
|
|
917
|
+
`tracker:${store.config.name}:${store.transactionStatus.phase === `idle` ? `main` : store.transactionStatus.key}`,
|
|
918
|
+
(update) => {
|
|
919
|
+
const unsubscribe = store.subject.operationStatus.subscribe(
|
|
920
|
+
mutableState.key,
|
|
921
|
+
() => {
|
|
922
|
+
unsubscribe();
|
|
923
|
+
AtomIO.setState(latestUpdateState, update, store);
|
|
924
|
+
}
|
|
925
|
+
);
|
|
926
|
+
}
|
|
927
|
+
);
|
|
928
|
+
AtomIO.subscribe(
|
|
929
|
+
mutableState,
|
|
930
|
+
(update) => {
|
|
931
|
+
var _a;
|
|
932
|
+
if (update.newValue !== update.oldValue) {
|
|
933
|
+
(_a = this.unsubscribeFromInnerValue) == null ? void 0 : _a.call(this);
|
|
934
|
+
this.unsubscribeFromInnerValue = update.newValue.subscribe(
|
|
935
|
+
`tracker:${store.config.name}:${store.transactionStatus.phase === `idle` ? `main` : store.transactionStatus.key}`,
|
|
936
|
+
(update2) => {
|
|
937
|
+
const unsubscribe = store.subject.operationStatus.subscribe(
|
|
938
|
+
mutableState.key,
|
|
939
|
+
() => {
|
|
940
|
+
unsubscribe();
|
|
941
|
+
AtomIO.setState(latestUpdateState, update2, store);
|
|
942
|
+
}
|
|
943
|
+
);
|
|
944
|
+
}
|
|
945
|
+
);
|
|
946
|
+
}
|
|
947
|
+
},
|
|
948
|
+
`${store.config.name}: tracker observing inner value`,
|
|
949
|
+
store
|
|
950
|
+
);
|
|
951
|
+
}
|
|
952
|
+
updateCore(mutableState, latestUpdateState, store = IMPLICIT.STORE) {
|
|
953
|
+
AtomIO.subscribe(
|
|
954
|
+
latestUpdateState,
|
|
955
|
+
({ newValue, oldValue }) => {
|
|
956
|
+
const timelineId = store.timelineAtoms.getRelatedKey(
|
|
957
|
+
latestUpdateState.key
|
|
958
|
+
);
|
|
959
|
+
if (timelineId) {
|
|
960
|
+
const timelineData = store.timelines.get(timelineId);
|
|
961
|
+
if (timelineData == null ? void 0 : timelineData.timeTraveling) {
|
|
962
|
+
const unsubscribe2 = AtomIO.subscribeToTimeline(
|
|
963
|
+
{ key: timelineId, type: `timeline` },
|
|
964
|
+
(update) => {
|
|
965
|
+
unsubscribe2();
|
|
966
|
+
AtomIO.setState(
|
|
967
|
+
mutableState,
|
|
968
|
+
(transceiver) => {
|
|
969
|
+
if (update === `redo` && newValue) {
|
|
970
|
+
transceiver.do(newValue);
|
|
971
|
+
} else if (update === `undo` && oldValue) {
|
|
972
|
+
transceiver.undo(oldValue);
|
|
973
|
+
}
|
|
974
|
+
return transceiver;
|
|
975
|
+
},
|
|
976
|
+
store
|
|
977
|
+
);
|
|
978
|
+
}
|
|
979
|
+
);
|
|
980
|
+
return;
|
|
981
|
+
}
|
|
982
|
+
}
|
|
983
|
+
const unsubscribe = store.subject.operationStatus.subscribe(
|
|
984
|
+
latestUpdateState.key,
|
|
985
|
+
() => {
|
|
986
|
+
unsubscribe();
|
|
987
|
+
if (newValue) {
|
|
988
|
+
AtomIO.setState(
|
|
989
|
+
mutableState,
|
|
990
|
+
(transceiver) => (transceiver.do(newValue), transceiver),
|
|
991
|
+
store
|
|
992
|
+
);
|
|
993
|
+
}
|
|
994
|
+
}
|
|
995
|
+
);
|
|
996
|
+
},
|
|
997
|
+
`${store.config.name}: tracker observing latest update`,
|
|
998
|
+
store
|
|
999
|
+
);
|
|
1000
|
+
}
|
|
1001
|
+
};
|
|
1002
|
+
|
|
1003
|
+
// src/mutable/create-mutable-atom.ts
|
|
1004
|
+
function createMutableAtom(options, store = IMPLICIT.STORE) {
|
|
1005
|
+
var _a;
|
|
1006
|
+
(_a = store.config.logger) == null ? void 0 : _a.info(
|
|
1007
|
+
`\u{1F527} creating mutable atom "${options.key}" in store "${store.config.name}"`
|
|
1008
|
+
);
|
|
1009
|
+
const coreState = createAtom(options, void 0, store);
|
|
1010
|
+
new Tracker(coreState, store);
|
|
1011
|
+
const jsonState = selectJson(coreState, options, store);
|
|
1012
|
+
AtomIO.subscribe(
|
|
1013
|
+
jsonState,
|
|
1014
|
+
() => {
|
|
1015
|
+
var _a2;
|
|
1016
|
+
(_a2 = store.config.logger) == null ? void 0 : _a2.info(
|
|
1017
|
+
`\u{1F50D} tracker-initializer:${store == null ? void 0 : store.config.name}:${store.transactionStatus.phase === `idle` ? `main` : store.transactionStatus.key}`,
|
|
1018
|
+
`Initializing tracker for ${coreState.key}`
|
|
1019
|
+
);
|
|
1020
|
+
const trackerHasBeenInitialized = target(store).trackers.has(coreState.key);
|
|
1021
|
+
if (!trackerHasBeenInitialized) {
|
|
1022
|
+
new Tracker(coreState, store);
|
|
1023
|
+
}
|
|
1024
|
+
},
|
|
1025
|
+
`tracker-initializer:${store == null ? void 0 : store.config.name}:${store.transactionStatus.phase === `idle` ? `main` : store.transactionStatus.key}`
|
|
1026
|
+
);
|
|
1027
|
+
return coreState;
|
|
1028
|
+
}
|
|
1029
|
+
function createAtomFamily(options, store = IMPLICIT.STORE) {
|
|
1030
|
+
const subject = new Subject();
|
|
1031
|
+
const atomFamily = Object.assign(
|
|
1032
|
+
(key) => {
|
|
1033
|
+
const subKey = stringifyJson(key);
|
|
1034
|
+
const family = { key: options.key, subKey };
|
|
1035
|
+
const fullKey = `${options.key}(${subKey})`;
|
|
1036
|
+
const existing = withdraw({ key: fullKey, type: `atom` }, store);
|
|
1037
|
+
let token;
|
|
1038
|
+
if (existing) {
|
|
1039
|
+
token = deposit(existing);
|
|
1040
|
+
} else {
|
|
1041
|
+
const individualOptions = {
|
|
1042
|
+
key: fullKey,
|
|
1043
|
+
default: options.default instanceof Function ? options.default(key) : options.default
|
|
1044
|
+
};
|
|
1045
|
+
if (options.effects) {
|
|
1046
|
+
individualOptions.effects = options.effects(key);
|
|
1047
|
+
}
|
|
1048
|
+
token = createAtom(individualOptions, family, store);
|
|
1049
|
+
subject.next(token);
|
|
1050
|
+
}
|
|
1051
|
+
return token;
|
|
1052
|
+
},
|
|
1053
|
+
{
|
|
1054
|
+
key: options.key,
|
|
1055
|
+
type: `atom_family`,
|
|
1056
|
+
subject
|
|
1057
|
+
}
|
|
1058
|
+
);
|
|
1059
|
+
const core = target(store);
|
|
1060
|
+
core.families.set(options.key, atomFamily);
|
|
1061
|
+
return atomFamily;
|
|
1062
|
+
}
|
|
1063
|
+
|
|
1064
|
+
// src/selector/lookup-selector-sources.ts
|
|
1065
|
+
var lookupSelectorSources = (key, store) => {
|
|
1066
|
+
const sources = target(store).selectorGraph.getRelationEntries({ downstreamSelectorKey: key }).filter(([_, { source }]) => source !== key).map(([_, { source }]) => lookup(source, store));
|
|
1067
|
+
return sources;
|
|
1068
|
+
};
|
|
1069
|
+
|
|
1070
|
+
// src/get-state-internal.ts
|
|
1071
|
+
var getState__INTERNAL = (state, store = IMPLICIT.STORE) => {
|
|
1072
|
+
var _a, _b, _c;
|
|
1073
|
+
if (isValueCached(state.key, store)) {
|
|
1074
|
+
(_a = store.config.logger) == null ? void 0 : _a.info(`>> read "${state.key}"`);
|
|
1075
|
+
return readCachedValue(state.key, store);
|
|
1076
|
+
}
|
|
1077
|
+
if (state.type !== `atom`) {
|
|
1078
|
+
(_b = store.config.logger) == null ? void 0 : _b.info(`-> calc "${state.key}"`);
|
|
1079
|
+
return state.get();
|
|
1080
|
+
}
|
|
1081
|
+
(_c = store.config.logger) == null ? void 0 : _c.error(
|
|
1082
|
+
`Attempted to get atom "${state.key}", which was never initialized in store "${store.config.name}".`
|
|
1083
|
+
);
|
|
1084
|
+
return state.default;
|
|
1085
|
+
};
|
|
1086
|
+
|
|
1087
|
+
// src/set-state/become.ts
|
|
1088
|
+
var become = (nextVersionOfThing) => (originalThing) => nextVersionOfThing instanceof Function ? nextVersionOfThing(
|
|
1089
|
+
originalThing instanceof Function ? originalThing() : originalThing
|
|
1090
|
+
) : nextVersionOfThing;
|
|
1091
|
+
|
|
1092
|
+
// src/operation.ts
|
|
1093
|
+
var openOperation = (token, store) => {
|
|
1094
|
+
var _a, _b;
|
|
1095
|
+
const core = target(store);
|
|
1096
|
+
if (core.operation.open) {
|
|
1097
|
+
(_a = store.config.logger) == null ? void 0 : _a.error(
|
|
1098
|
+
`\u274C failed to setState to "${token.key}" during a setState for "${core.operation.token.key}"`
|
|
1099
|
+
);
|
|
1100
|
+
throw Symbol(`violation`);
|
|
1101
|
+
}
|
|
1102
|
+
core.operation = {
|
|
1103
|
+
open: true,
|
|
1104
|
+
done: /* @__PURE__ */ new Set(),
|
|
1105
|
+
prev: new Map(store.valueMap),
|
|
1106
|
+
time: Date.now(),
|
|
1107
|
+
token
|
|
1108
|
+
};
|
|
1109
|
+
(_b = store.config.logger) == null ? void 0 : _b.info(
|
|
1110
|
+
`\u2B55 operation start from "${token.key}" in store "${store.config.name}"${store.transactionStatus.phase === `idle` ? `` : ` ${store.transactionStatus.phase} "${store.transactionStatus.key}"`}`
|
|
1111
|
+
);
|
|
1112
|
+
};
|
|
1113
|
+
var closeOperation = (store) => {
|
|
1114
|
+
var _a;
|
|
1115
|
+
const core = target(store);
|
|
1116
|
+
core.operation = { open: false };
|
|
1117
|
+
(_a = store.config.logger) == null ? void 0 : _a.info(`\u{1F534} operation done`);
|
|
1118
|
+
store.subject.operationStatus.next(core.operation);
|
|
1119
|
+
};
|
|
1120
|
+
var isDone = (key, store = IMPLICIT.STORE) => {
|
|
1121
|
+
var _a;
|
|
1122
|
+
const core = target(store);
|
|
1123
|
+
if (!core.operation.open) {
|
|
1124
|
+
(_a = store.config.logger) == null ? void 0 : _a.warn(
|
|
1125
|
+
`isDone called outside of an operation. This is probably a bug.`
|
|
1126
|
+
);
|
|
1127
|
+
return true;
|
|
1128
|
+
}
|
|
1129
|
+
return core.operation.done.has(key);
|
|
1130
|
+
};
|
|
1131
|
+
var markDone = (key, store = IMPLICIT.STORE) => {
|
|
1132
|
+
var _a;
|
|
1133
|
+
const core = target(store);
|
|
1134
|
+
if (!core.operation.open) {
|
|
1135
|
+
(_a = store.config.logger) == null ? void 0 : _a.warn(
|
|
1136
|
+
`markDone called outside of an operation. This is probably a bug.`
|
|
1137
|
+
);
|
|
1138
|
+
return;
|
|
1139
|
+
}
|
|
1140
|
+
core.operation.done.add(key);
|
|
1141
|
+
};
|
|
1142
|
+
|
|
1143
|
+
// src/set-state/copy-mutable-if-needed.ts
|
|
1144
|
+
function copyMutableIfNeeded(atom, transform, origin, target3) {
|
|
1145
|
+
var _a;
|
|
1146
|
+
const originValue = origin.valueMap.get(atom.key);
|
|
1147
|
+
const targetValue = target3.valueMap.get(atom.key);
|
|
1148
|
+
if (originValue === targetValue) {
|
|
1149
|
+
(_a = origin.config.logger) == null ? void 0 : _a.info(`\u{1F4C3} copying`, `${atom.key}`);
|
|
1150
|
+
const copiedValue = transform.fromJson(transform.toJson(originValue));
|
|
1151
|
+
target3.valueMap.set(atom.key, copiedValue);
|
|
1152
|
+
new Tracker(atom, origin);
|
|
1153
|
+
return copiedValue;
|
|
1154
|
+
}
|
|
1155
|
+
return targetValue;
|
|
1156
|
+
}
|
|
1157
|
+
|
|
1158
|
+
// src/set-state/copy-mutable-in-transaction.ts
|
|
1159
|
+
function copyMutableIfWithinTransaction(atom, store) {
|
|
1160
|
+
var _a;
|
|
1161
|
+
if (store.transactionStatus.phase === `building` || store.transactionStatus.phase === `applying`) {
|
|
1162
|
+
if (`toJson` in atom && `fromJson` in atom) {
|
|
1163
|
+
(_a = store.config.logger) == null ? void 0 : _a.info(
|
|
1164
|
+
`\u{1F4C4} copyMutableIfWithinTransaction: ${atom.key} is mutable`
|
|
1165
|
+
);
|
|
1166
|
+
const copiedValue = copyMutableIfNeeded(
|
|
1167
|
+
atom,
|
|
1168
|
+
atom,
|
|
1169
|
+
store,
|
|
1170
|
+
store.transactionStatus.core
|
|
1171
|
+
);
|
|
1172
|
+
return copiedValue;
|
|
1173
|
+
}
|
|
1174
|
+
if (`family` in atom) {
|
|
1175
|
+
const family = store.transactionStatus.core.families.get(atom.family.key);
|
|
1176
|
+
if (family && family.type === `atom_family`) {
|
|
1177
|
+
const result = copyMutableFamilyMemberWithinTransaction(
|
|
1178
|
+
atom,
|
|
1179
|
+
family,
|
|
1180
|
+
store,
|
|
1181
|
+
store.transactionStatus.core
|
|
1182
|
+
);
|
|
1183
|
+
if (result) {
|
|
1184
|
+
return result;
|
|
1185
|
+
}
|
|
1186
|
+
}
|
|
1187
|
+
}
|
|
1188
|
+
}
|
|
1189
|
+
return getState__INTERNAL(atom, store);
|
|
1190
|
+
}
|
|
1191
|
+
function copyMutableFamilyMemberWithinTransaction(atom, family, origin, target3) {
|
|
1192
|
+
if (`toJson` in family && `fromJson` in family) {
|
|
1193
|
+
const copyCreated = copyMutableIfNeeded(atom, family, origin, target3);
|
|
1194
|
+
return copyCreated;
|
|
1195
|
+
}
|
|
1196
|
+
return null;
|
|
1197
|
+
}
|
|
1198
|
+
|
|
1199
|
+
// src/set-state/emit-update.ts
|
|
1200
|
+
var emitUpdate = (state, update, store) => {
|
|
1201
|
+
const { key } = state;
|
|
1202
|
+
const { logger } = store.config;
|
|
1203
|
+
logger == null ? void 0 : logger.info(
|
|
1204
|
+
`\u{1F4E2} ${state.type} "${key}" went (`,
|
|
1205
|
+
update.oldValue,
|
|
1206
|
+
`->`,
|
|
1207
|
+
update.newValue,
|
|
1208
|
+
`)`
|
|
1209
|
+
);
|
|
1210
|
+
logger == null ? void 0 : logger.info(`\u{1F4E2} notifying subscribers:`, state.subject.subscribers);
|
|
1211
|
+
state.subject.next(update);
|
|
1212
|
+
};
|
|
1213
|
+
|
|
1214
|
+
// src/set-state/evict-downstream.ts
|
|
1215
|
+
var evictDownStream = (state, store = IMPLICIT.STORE) => {
|
|
1216
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
1217
|
+
const core = target(store);
|
|
1218
|
+
const downstreamKeys = core.selectorAtoms.getRelatedKeys(state.key);
|
|
1219
|
+
(_b = store.config.logger) == null ? void 0 : _b.info(
|
|
1220
|
+
` || ${(_a = downstreamKeys == null ? void 0 : downstreamKeys.size) != null ? _a : `none`} downstream:`,
|
|
1221
|
+
downstreamKeys
|
|
1222
|
+
);
|
|
1223
|
+
if (core.operation.open) {
|
|
1224
|
+
(_c = store.config.logger) == null ? void 0 : _c.info(` ||`, [...core.operation.done], `already done`);
|
|
1225
|
+
}
|
|
1226
|
+
if (downstreamKeys) {
|
|
1227
|
+
for (const key of downstreamKeys) {
|
|
1228
|
+
if (isDone(key, store)) {
|
|
1229
|
+
(_d = store.config.logger) == null ? void 0 : _d.info(` || ${key} already done`);
|
|
1230
|
+
continue;
|
|
1231
|
+
}
|
|
1232
|
+
const state2 = (_e = core.selectors.get(key)) != null ? _e : core.readonlySelectors.get(key);
|
|
1233
|
+
if (!state2) {
|
|
1234
|
+
(_f = store.config.logger) == null ? void 0 : _f.info(
|
|
1235
|
+
` || ${key} was not found in selectors or readonlySelectors`
|
|
1236
|
+
);
|
|
1237
|
+
return;
|
|
1238
|
+
}
|
|
1239
|
+
core.valueMap.delete(key);
|
|
1240
|
+
(_g = store.config.logger) == null ? void 0 : _g.info(` xx evicted "${key}"`);
|
|
1241
|
+
markDone(key, store);
|
|
1242
|
+
}
|
|
1243
|
+
}
|
|
1244
|
+
};
|
|
1245
|
+
|
|
1246
|
+
// src/set-state/stow-update.ts
|
|
1247
|
+
function shouldUpdateBeStowed(key, update) {
|
|
1248
|
+
if (isTransceiver(update.newValue)) {
|
|
1249
|
+
return false;
|
|
1250
|
+
}
|
|
1251
|
+
if (key.includes(`\u{1F441}\u200D\u{1F5E8}`)) {
|
|
1252
|
+
return false;
|
|
1253
|
+
}
|
|
1254
|
+
return true;
|
|
1255
|
+
}
|
|
1256
|
+
var stowUpdate = (state, update, store) => {
|
|
1257
|
+
var _a;
|
|
1258
|
+
const { key } = state;
|
|
1259
|
+
const { logger } = store.config;
|
|
1260
|
+
if (store.transactionStatus.phase !== `building`) {
|
|
1261
|
+
(_a = store.config.logger) == null ? void 0 : _a.warn(
|
|
1262
|
+
`stowUpdate called outside of a transaction. This is probably a bug.`
|
|
1263
|
+
);
|
|
1264
|
+
return;
|
|
1265
|
+
}
|
|
1266
|
+
const shouldStow = shouldUpdateBeStowed(key, update);
|
|
1267
|
+
if (!shouldStow) {
|
|
1268
|
+
return;
|
|
1269
|
+
}
|
|
1270
|
+
const atomUpdate = __spreadValues({ key }, update);
|
|
1271
|
+
if (state.family) {
|
|
1272
|
+
atomUpdate.family = state.family;
|
|
1273
|
+
}
|
|
1274
|
+
store.transactionStatus.atomUpdates.push(atomUpdate);
|
|
1275
|
+
logger == null ? void 0 : logger.info(`\u{1F4DD} ${key} stowed (`, update.oldValue, `->`, update.newValue, `)`);
|
|
1276
|
+
};
|
|
1277
|
+
|
|
1278
|
+
// src/set-state/set-atom-state.ts
|
|
1279
|
+
var setAtomState = (atom, next, store = IMPLICIT.STORE) => {
|
|
1280
|
+
var _a, _b;
|
|
1281
|
+
const oldValue = getState__INTERNAL(atom, store);
|
|
1282
|
+
let newValue = copyMutableIfWithinTransaction(atom, store);
|
|
1283
|
+
newValue = become(next)(newValue);
|
|
1284
|
+
(_a = store.config.logger) == null ? void 0 : _a.info(`<< setting atom "${atom.key}" to`, newValue);
|
|
1285
|
+
cacheValue(atom.key, newValue, store);
|
|
1286
|
+
if (isAtomDefault(atom.key, store)) {
|
|
1287
|
+
markAtomAsNotDefault(atom.key, store);
|
|
1288
|
+
}
|
|
1289
|
+
markDone(atom.key, store);
|
|
1290
|
+
(_b = store.config.logger) == null ? void 0 : _b.info(
|
|
1291
|
+
` || evicting caches downstream from "${atom.key}"`
|
|
1292
|
+
);
|
|
1293
|
+
evictDownStream(atom, store);
|
|
1294
|
+
const update = { oldValue, newValue };
|
|
1295
|
+
if (store.transactionStatus.phase !== `building`) {
|
|
1296
|
+
emitUpdate(atom, update, store);
|
|
1297
|
+
} else {
|
|
1298
|
+
stowUpdate(atom, update, store);
|
|
1299
|
+
}
|
|
1300
|
+
};
|
|
1301
|
+
|
|
1302
|
+
// src/set-state/set-selector-state.ts
|
|
1303
|
+
var setSelectorState = (selector, next, store = IMPLICIT.STORE) => {
|
|
1304
|
+
var _a, _b;
|
|
1305
|
+
const oldValue = getState__INTERNAL(selector, store);
|
|
1306
|
+
const newValue = become(next)(oldValue);
|
|
1307
|
+
(_a = store.config.logger) == null ? void 0 : _a.info(`<< setting selector "${selector.key}" to`, newValue);
|
|
1308
|
+
(_b = store.config.logger) == null ? void 0 : _b.info(` || propagating change made to "${selector.key}"`);
|
|
1309
|
+
selector.set(newValue);
|
|
1310
|
+
};
|
|
1311
|
+
|
|
1312
|
+
// src/set-state/set-state-internal.ts
|
|
1313
|
+
var setState__INTERNAL = (state, value, store = IMPLICIT.STORE) => {
|
|
1314
|
+
if (`set` in state) {
|
|
1315
|
+
setSelectorState(state, value, store);
|
|
1316
|
+
} else {
|
|
1317
|
+
setAtomState(state, value, store);
|
|
1318
|
+
}
|
|
1319
|
+
};
|
|
1320
|
+
|
|
1321
|
+
// src/selector/trace-selector-atoms.ts
|
|
1322
|
+
var traceSelectorAtoms = (selectorKey, dependency, store) => {
|
|
1323
|
+
const roots = [];
|
|
1324
|
+
const sources = lookupSelectorSources(dependency.key, store);
|
|
1325
|
+
let depth = 0;
|
|
1326
|
+
while (sources.length > 0) {
|
|
1327
|
+
const source = sources.shift();
|
|
1328
|
+
++depth;
|
|
1329
|
+
if (depth > 999) {
|
|
1330
|
+
throw new Error(
|
|
1331
|
+
`Maximum selector dependency depth exceeded in selector "${selectorKey}".`
|
|
1332
|
+
);
|
|
1333
|
+
}
|
|
1334
|
+
if (source.type !== `atom`) {
|
|
1335
|
+
sources.push(...lookupSelectorSources(source.key, store));
|
|
1336
|
+
} else {
|
|
1337
|
+
roots.push(source);
|
|
1338
|
+
}
|
|
1339
|
+
}
|
|
1340
|
+
return roots;
|
|
1341
|
+
};
|
|
1342
|
+
var traceAllSelectorAtoms = (selectorKey, store) => {
|
|
1343
|
+
const sources = lookupSelectorSources(selectorKey, store);
|
|
1344
|
+
return sources.flatMap(
|
|
1345
|
+
(source) => source.type === `atom` ? source : traceSelectorAtoms(selectorKey, source, store)
|
|
1346
|
+
);
|
|
1347
|
+
};
|
|
1348
|
+
|
|
1349
|
+
// src/selector/update-selector-atoms.ts
|
|
1350
|
+
var updateSelectorAtoms = (selectorKey, dependency, store) => {
|
|
1351
|
+
var _a, _b;
|
|
1352
|
+
const core = target(store);
|
|
1353
|
+
if (dependency.type === `atom`) {
|
|
1354
|
+
core.selectorAtoms = core.selectorAtoms.set({
|
|
1355
|
+
selectorKey,
|
|
1356
|
+
atomKey: dependency.key
|
|
1357
|
+
});
|
|
1358
|
+
(_a = store.config.logger) == null ? void 0 : _a.info(
|
|
1359
|
+
` || adding root for "${selectorKey}": ${dependency.key}`
|
|
1360
|
+
);
|
|
1361
|
+
return;
|
|
1362
|
+
}
|
|
1363
|
+
const roots = traceSelectorAtoms(selectorKey, dependency, store);
|
|
1364
|
+
(_b = store.config.logger) == null ? void 0 : _b.info(
|
|
1365
|
+
` || adding roots for "${selectorKey}":`,
|
|
1366
|
+
roots.map((r) => r.key)
|
|
1367
|
+
);
|
|
1368
|
+
for (const root of roots) {
|
|
1369
|
+
core.selectorAtoms = core.selectorAtoms.set({
|
|
1370
|
+
selectorKey,
|
|
1371
|
+
atomKey: root.key
|
|
1372
|
+
});
|
|
1373
|
+
}
|
|
1374
|
+
};
|
|
1375
|
+
|
|
1376
|
+
// src/selector/register-selector.ts
|
|
1377
|
+
var registerSelector = (selectorKey, store = IMPLICIT.STORE) => ({
|
|
1378
|
+
get: (dependency) => {
|
|
1379
|
+
var _a, _b;
|
|
1380
|
+
const core = target(store);
|
|
1381
|
+
const alreadyRegistered = core.selectorGraph.getRelationEntries({ downstreamSelectorKey: selectorKey }).some(([_, { source }]) => source === dependency.key);
|
|
1382
|
+
const dependencyState = withdraw(dependency, store);
|
|
1383
|
+
if (dependencyState === null) {
|
|
1384
|
+
throw new Error(
|
|
1385
|
+
`State "${dependency.key}" not found in this store. Did you forget to initialize with the "atom" or "selector" function?`
|
|
1386
|
+
);
|
|
1387
|
+
}
|
|
1388
|
+
const dependencyValue = getState__INTERNAL(dependencyState, store);
|
|
1389
|
+
if (alreadyRegistered) {
|
|
1390
|
+
(_a = store.config.logger) == null ? void 0 : _a.info(
|
|
1391
|
+
` || ${selectorKey} <- ${dependency.key} =`,
|
|
1392
|
+
dependencyValue
|
|
1393
|
+
);
|
|
1394
|
+
} else {
|
|
1395
|
+
(_b = store.config.logger) == null ? void 0 : _b.info(
|
|
1396
|
+
`\u{1F50C} registerSelector "${selectorKey}" <- ( "${dependency.key}" =`,
|
|
1397
|
+
dependencyValue,
|
|
1398
|
+
`)`
|
|
1399
|
+
);
|
|
1400
|
+
core.selectorGraph = core.selectorGraph.set(
|
|
1401
|
+
{
|
|
1402
|
+
upstreamSelectorKey: dependency.key,
|
|
1403
|
+
downstreamSelectorKey: selectorKey
|
|
1404
|
+
},
|
|
1405
|
+
{
|
|
1406
|
+
source: dependency.key
|
|
1407
|
+
}
|
|
1408
|
+
);
|
|
1409
|
+
}
|
|
1410
|
+
updateSelectorAtoms(selectorKey, dependency, store);
|
|
1411
|
+
return dependencyValue;
|
|
1412
|
+
},
|
|
1413
|
+
set: (stateToken, newValue) => {
|
|
1414
|
+
const state = withdraw(stateToken, store);
|
|
1415
|
+
if (state === null) {
|
|
1416
|
+
throw new Error(
|
|
1417
|
+
`State "${stateToken.key}" not found in this store. Did you forget to initialize with the "atom" or "selector" function?`
|
|
1418
|
+
);
|
|
1419
|
+
}
|
|
1420
|
+
setState__INTERNAL(state, newValue, store);
|
|
1421
|
+
}
|
|
1422
|
+
});
|
|
1423
|
+
|
|
1424
|
+
// src/selector/create-read-write-selector.ts
|
|
1425
|
+
var createReadWriteSelector = (options, family, store, core) => {
|
|
1426
|
+
var _a;
|
|
1427
|
+
const subject = new Subject();
|
|
1428
|
+
const { get, set } = registerSelector(options.key, store);
|
|
1429
|
+
const getSelf = () => {
|
|
1430
|
+
const value = options.get({ get });
|
|
1431
|
+
cacheValue(options.key, value, store);
|
|
1432
|
+
return value;
|
|
1433
|
+
};
|
|
1434
|
+
const setSelf = (next) => {
|
|
1435
|
+
var _a2;
|
|
1436
|
+
const oldValue = getSelf();
|
|
1437
|
+
(_a2 = store.config.logger) == null ? void 0 : _a2.info(
|
|
1438
|
+
` <- "${options.key}" went (`,
|
|
1439
|
+
oldValue,
|
|
1440
|
+
`->`,
|
|
1441
|
+
next,
|
|
1442
|
+
`)`
|
|
1443
|
+
);
|
|
1444
|
+
const newValue = become(next)(oldValue);
|
|
1445
|
+
cacheValue(options.key, newValue, store);
|
|
1446
|
+
markDone(options.key, store);
|
|
1447
|
+
if (store.transactionStatus.phase === `idle`) {
|
|
1448
|
+
subject.next({ newValue, oldValue });
|
|
1449
|
+
}
|
|
1450
|
+
options.set({ get, set }, newValue);
|
|
1451
|
+
};
|
|
1452
|
+
const mySelector = __spreadValues(__spreadProps(__spreadValues({}, options), {
|
|
1453
|
+
subject,
|
|
1454
|
+
install: (s) => createSelector(options, family, s),
|
|
1455
|
+
get: getSelf,
|
|
1456
|
+
set: setSelf,
|
|
1457
|
+
type: `selector`
|
|
1458
|
+
}), family && { family });
|
|
1459
|
+
core.selectors.set(options.key, mySelector);
|
|
1460
|
+
const initialValue = getSelf();
|
|
1461
|
+
(_a = store.config.logger) == null ? void 0 : _a.info(` \u2728 "${options.key}" =`, initialValue);
|
|
1462
|
+
const token = {
|
|
1463
|
+
key: options.key,
|
|
1464
|
+
type: `selector`
|
|
1465
|
+
};
|
|
1466
|
+
if (family) {
|
|
1467
|
+
token.family = family;
|
|
1468
|
+
}
|
|
1469
|
+
store.subject.selectorCreation.next(token);
|
|
1470
|
+
return token;
|
|
1471
|
+
};
|
|
1472
|
+
|
|
1473
|
+
// src/selector/create-readonly-selector.ts
|
|
1474
|
+
var createReadonlySelector = (options, family, store, core) => {
|
|
1475
|
+
var _a;
|
|
1476
|
+
const subject = new Subject();
|
|
1477
|
+
const { get } = registerSelector(options.key, store);
|
|
1478
|
+
const getSelf = () => {
|
|
1479
|
+
const value = options.get({ get });
|
|
1480
|
+
cacheValue(options.key, value, store);
|
|
1481
|
+
return value;
|
|
1482
|
+
};
|
|
1483
|
+
const readonlySelector = __spreadValues(__spreadProps(__spreadValues({}, options), {
|
|
1484
|
+
subject,
|
|
1485
|
+
install: (s) => createSelector(options, family, s),
|
|
1486
|
+
get: getSelf,
|
|
1487
|
+
type: `readonly_selector`
|
|
1488
|
+
}), family && { family });
|
|
1489
|
+
core.readonlySelectors.set(options.key, readonlySelector);
|
|
1490
|
+
const initialValue = getSelf();
|
|
1491
|
+
(_a = store.config.logger) == null ? void 0 : _a.info(` \u2728 "${options.key}" =`, initialValue);
|
|
1492
|
+
const token = {
|
|
1493
|
+
key: options.key,
|
|
1494
|
+
type: `readonly_selector`
|
|
1495
|
+
};
|
|
1496
|
+
if (family) {
|
|
1497
|
+
token.family = family;
|
|
1498
|
+
}
|
|
1499
|
+
store.subject.selectorCreation.next(token);
|
|
1500
|
+
return token;
|
|
1501
|
+
};
|
|
1502
|
+
|
|
1503
|
+
// src/selector/create-selector.ts
|
|
1504
|
+
function createSelector(options, family, store = IMPLICIT.STORE) {
|
|
1505
|
+
var _a, _b;
|
|
1506
|
+
const core = target(store);
|
|
1507
|
+
const existingWritable = core.selectors.get(options.key);
|
|
1508
|
+
const existingReadonly = core.readonlySelectors.get(options.key);
|
|
1509
|
+
if (existingWritable || existingReadonly) {
|
|
1510
|
+
(_b = (_a = store.config.logger) == null ? void 0 : _a.error) == null ? void 0 : _b.call(
|
|
1511
|
+
_a,
|
|
1512
|
+
`Tried to create ${existingReadonly ? `readonly selector` : `selector`}`,
|
|
1513
|
+
`"${options.key}", but it already exists in the store.`,
|
|
1514
|
+
`(Ignore if you are using hot module replacement.)`
|
|
1515
|
+
);
|
|
1516
|
+
}
|
|
1517
|
+
if (`set` in options) {
|
|
1518
|
+
return createReadWriteSelector(options, family, store, core);
|
|
1519
|
+
}
|
|
1520
|
+
return createReadonlySelector(options, family, store, core);
|
|
1521
|
+
}
|
|
1522
|
+
|
|
1523
|
+
// src/families/create-readonly-selector-family.ts
|
|
1524
|
+
function createReadonlySelectorFamily(options, store) {
|
|
1525
|
+
const core = target(store);
|
|
1526
|
+
const subject = new Subject();
|
|
1527
|
+
return Object.assign(
|
|
1528
|
+
(key) => {
|
|
1529
|
+
const subKey = stringifyJson(key);
|
|
1530
|
+
const family = { key: options.key, subKey };
|
|
1531
|
+
const fullKey = `${options.key}(${subKey})`;
|
|
1532
|
+
const existing = core.readonlySelectors.get(fullKey);
|
|
1533
|
+
if (existing) {
|
|
1534
|
+
return deposit(existing);
|
|
1535
|
+
}
|
|
1536
|
+
return createSelector(
|
|
1537
|
+
{
|
|
1538
|
+
key: fullKey,
|
|
1539
|
+
get: options.get(key)
|
|
1540
|
+
},
|
|
1541
|
+
family,
|
|
1542
|
+
store
|
|
1543
|
+
);
|
|
1544
|
+
},
|
|
1545
|
+
{
|
|
1546
|
+
key: options.key,
|
|
1547
|
+
type: `readonly_selector_family`,
|
|
1548
|
+
subject
|
|
1549
|
+
}
|
|
1550
|
+
);
|
|
1551
|
+
}
|
|
1552
|
+
function createSelectorFamily(options, store = IMPLICIT.STORE) {
|
|
1553
|
+
const isReadonly = !(`set` in options);
|
|
1554
|
+
if (isReadonly) {
|
|
1555
|
+
return createReadonlySelectorFamily(options, store);
|
|
1556
|
+
}
|
|
1557
|
+
const core = target(store);
|
|
1558
|
+
const subject = new Subject();
|
|
1559
|
+
const selectorFamily = Object.assign(
|
|
1560
|
+
(key) => {
|
|
1561
|
+
const subKey = stringifyJson(key);
|
|
1562
|
+
const family = { key: options.key, subKey };
|
|
1563
|
+
const fullKey = `${options.key}(${subKey})`;
|
|
1564
|
+
const existing = core.selectors.get(fullKey);
|
|
1565
|
+
if (existing) {
|
|
1566
|
+
return deposit(existing);
|
|
1567
|
+
}
|
|
1568
|
+
const token = createSelector(
|
|
1569
|
+
{
|
|
1570
|
+
key: fullKey,
|
|
1571
|
+
get: options.get(key),
|
|
1572
|
+
set: options.set(key)
|
|
1573
|
+
},
|
|
1574
|
+
family,
|
|
1575
|
+
store
|
|
1576
|
+
);
|
|
1577
|
+
subject.next(token);
|
|
1578
|
+
return token;
|
|
1579
|
+
},
|
|
1580
|
+
{
|
|
1581
|
+
key: options.key,
|
|
1582
|
+
type: `selector_family`
|
|
1583
|
+
}
|
|
1584
|
+
);
|
|
1585
|
+
core.families.set(options.key, selectorFamily);
|
|
1586
|
+
return selectorFamily;
|
|
1587
|
+
}
|
|
1588
|
+
|
|
1589
|
+
// src/mutable/tracker-family.ts
|
|
1590
|
+
var FamilyTracker = class {
|
|
1591
|
+
constructor(findMutableState, store = IMPLICIT.STORE) {
|
|
1592
|
+
this.findLatestUpdateState = createAtomFamily(
|
|
1593
|
+
{
|
|
1594
|
+
key: `*${findMutableState.key}`,
|
|
1595
|
+
default: null
|
|
1596
|
+
},
|
|
1597
|
+
store
|
|
1598
|
+
);
|
|
1599
|
+
this.findMutableState = findMutableState;
|
|
1600
|
+
this.findMutableState.subject.subscribe(
|
|
1601
|
+
`store=${store.config.name}::tracker-atom-family`,
|
|
1602
|
+
(atomToken) => {
|
|
1603
|
+
if (atomToken.family) {
|
|
1604
|
+
const key = parseJson(atomToken.family.subKey);
|
|
1605
|
+
this.findLatestUpdateState(key);
|
|
1606
|
+
new Tracker(atomToken, store);
|
|
1607
|
+
}
|
|
1608
|
+
}
|
|
1609
|
+
);
|
|
1610
|
+
this.findLatestUpdateState.subject.subscribe(
|
|
1611
|
+
`store=${store.config.name}::tracker-atom-family`,
|
|
1612
|
+
(atomToken) => {
|
|
1613
|
+
if (atomToken.family) {
|
|
1614
|
+
const key = parseJson(atomToken.family.subKey);
|
|
1615
|
+
const mutableAtomToken = this.findMutableState(key);
|
|
1616
|
+
new Tracker(mutableAtomToken, store);
|
|
1617
|
+
}
|
|
1618
|
+
}
|
|
1619
|
+
);
|
|
1620
|
+
}
|
|
1621
|
+
};
|
|
1622
|
+
|
|
1623
|
+
// src/mutable/create-mutable-atom-family.ts
|
|
1624
|
+
function createMutableAtomFamily(options, store = IMPLICIT.STORE) {
|
|
1625
|
+
const coreFamily = Object.assign(
|
|
1626
|
+
createAtomFamily(options, store),
|
|
1627
|
+
options
|
|
1628
|
+
);
|
|
1629
|
+
selectJsonFamily(coreFamily, options);
|
|
1630
|
+
new FamilyTracker(coreFamily, store);
|
|
1631
|
+
return coreFamily;
|
|
1632
|
+
}
|
|
1633
|
+
|
|
1634
|
+
// src/mutable/get-json-token.ts
|
|
1635
|
+
var getJsonToken = (mutableAtomToken) => {
|
|
1636
|
+
const key = mutableAtomToken.family ? `${mutableAtomToken.family.key}:JSON(${mutableAtomToken.family.subKey})` : `${mutableAtomToken.key}:JSON`;
|
|
1637
|
+
const jsonToken = { type: `selector`, key };
|
|
1638
|
+
if (mutableAtomToken.family) {
|
|
1639
|
+
jsonToken.family = {
|
|
1640
|
+
key: `${mutableAtomToken.family.key}:JSON`,
|
|
1641
|
+
subKey: mutableAtomToken.family.subKey
|
|
1642
|
+
};
|
|
1643
|
+
}
|
|
1644
|
+
return jsonToken;
|
|
1645
|
+
};
|
|
1646
|
+
|
|
1647
|
+
// src/mutable/get-update-token.ts
|
|
1648
|
+
var getUpdateToken = (mutableAtomToken) => {
|
|
1649
|
+
const key = `*${mutableAtomToken.key}`;
|
|
1650
|
+
const updateToken = { type: `atom`, key };
|
|
1651
|
+
if (mutableAtomToken.family) {
|
|
1652
|
+
updateToken.family = {
|
|
1653
|
+
key: `*${mutableAtomToken.family.key}`,
|
|
1654
|
+
subKey: mutableAtomToken.family.subKey
|
|
1655
|
+
};
|
|
1656
|
+
}
|
|
1657
|
+
return updateToken;
|
|
1658
|
+
};
|
|
1659
|
+
|
|
1660
|
+
// src/mutable/is-atom-token-mutable.ts
|
|
1661
|
+
function isAtomTokenMutable(token) {
|
|
1662
|
+
return token.key.endsWith(`::mutable`);
|
|
1663
|
+
}
|
|
1664
|
+
|
|
1665
|
+
// src/mutable/transceiver.ts
|
|
1666
|
+
function isTransceiver(value) {
|
|
1667
|
+
return typeof value === `object` && value !== null && `do` in value && `undo` in value && `subscribe` in value;
|
|
1668
|
+
}
|
|
1669
|
+
|
|
1670
|
+
// src/mutable/index.ts
|
|
1671
|
+
var isAtomMutable = (atom) => `isMutable` in atom;
|
|
1672
|
+
|
|
1673
|
+
// src/atom/is-default.ts
|
|
1674
|
+
var isAtomDefault = (key, store = IMPLICIT.STORE) => {
|
|
1675
|
+
const core = target(store);
|
|
1676
|
+
return core.atomsThatAreDefault.has(key);
|
|
1677
|
+
};
|
|
1678
|
+
var markAtomAsDefault = (key, store = IMPLICIT.STORE) => {
|
|
1679
|
+
const core = target(store);
|
|
1680
|
+
core.atomsThatAreDefault = new Set(core.atomsThatAreDefault).add(key);
|
|
1681
|
+
};
|
|
1682
|
+
var markAtomAsNotDefault = (key, store = IMPLICIT.STORE) => {
|
|
1683
|
+
const core = target(store);
|
|
1684
|
+
core.atomsThatAreDefault = new Set(target(store).atomsThatAreDefault);
|
|
1685
|
+
core.atomsThatAreDefault.delete(key);
|
|
1686
|
+
};
|
|
1687
|
+
var isSelectorDefault = (key, store = IMPLICIT.STORE) => {
|
|
1688
|
+
const roots = traceAllSelectorAtoms(key, store);
|
|
1689
|
+
return roots.every((root) => isAtomDefault(root.key, store));
|
|
1690
|
+
};
|
|
1691
|
+
|
|
1692
|
+
// src/atom/create-atom.ts
|
|
1693
|
+
function createAtom(options, family, store = IMPLICIT.STORE) {
|
|
1694
|
+
var _a, _b, _c, _d, _e;
|
|
1695
|
+
(_b = (_a = store.config.logger) == null ? void 0 : _a.info) == null ? void 0 : _b.call(
|
|
1696
|
+
_a,
|
|
1697
|
+
`\u{1F528} creating atom "${options.key}" in store "${store.config.name}"`
|
|
1698
|
+
);
|
|
1699
|
+
const core = target(store);
|
|
1700
|
+
const existing = core.atoms.get(options.key);
|
|
1701
|
+
if (existing) {
|
|
1702
|
+
(_d = (_c = store.config.logger) == null ? void 0 : _c.error) == null ? void 0 : _d.call(
|
|
1703
|
+
_c,
|
|
1704
|
+
`Tried to create atom "${options.key}",`,
|
|
1705
|
+
`but it already exists in the store.`,
|
|
1706
|
+
`(Ignore if you are using hot module replacement.)`
|
|
1707
|
+
);
|
|
1708
|
+
return deposit(existing);
|
|
1709
|
+
}
|
|
1710
|
+
const subject = new Subject();
|
|
1711
|
+
const newAtom = __spreadValues(__spreadProps(__spreadValues({}, options), {
|
|
1712
|
+
type: `atom`,
|
|
1713
|
+
install: (store2) => {
|
|
1714
|
+
var _a2, _b2;
|
|
1715
|
+
(_b2 = (_a2 = store2.config.logger) == null ? void 0 : _a2.info) == null ? void 0 : _b2.call(
|
|
1716
|
+
_a2,
|
|
1717
|
+
`\u{1F6E0}\uFE0F installing atom "${options.key}" in store "${store2.config.name}"`
|
|
1718
|
+
);
|
|
1719
|
+
return `mutable` in options ? createMutableAtom(options, store2) : createAtom(options, void 0, store2);
|
|
1720
|
+
},
|
|
1721
|
+
subject
|
|
1722
|
+
}), family && { family });
|
|
1723
|
+
const initialValue = options.default instanceof Function ? options.default() : options.default;
|
|
1724
|
+
core.atoms.set(newAtom.key, newAtom);
|
|
1725
|
+
markAtomAsDefault(options.key, store);
|
|
1726
|
+
cacheValue(options.key, initialValue, store);
|
|
1727
|
+
const token = deposit(newAtom);
|
|
1728
|
+
for (const effect of (_e = options.effects) != null ? _e : []) {
|
|
1729
|
+
effect({
|
|
1730
|
+
setSelf: (next) => setState(token, next, store),
|
|
1731
|
+
onSet: (handle) => subscribe(token, handle, `effect[${subject.subscribers.size}]`, store)
|
|
1732
|
+
});
|
|
1733
|
+
}
|
|
1734
|
+
store.subject.atomCreation.next(token);
|
|
1735
|
+
return token;
|
|
1736
|
+
}
|
|
1737
|
+
|
|
1738
|
+
// src/atom/delete-atom.ts
|
|
1739
|
+
function deleteAtom(key, core = IMPLICIT.STORE) {
|
|
1740
|
+
core.atoms.delete(key);
|
|
1741
|
+
core.valueMap.delete(key);
|
|
1742
|
+
core.selectorAtoms.delete(key);
|
|
1743
|
+
core.atomsThatAreDefault.delete(key);
|
|
1744
|
+
core.timelineAtoms.delete(key);
|
|
1745
|
+
}
|
|
1746
|
+
|
|
1747
|
+
// src/subscribe/recall-state.ts
|
|
1748
|
+
var recallState = (state, store = IMPLICIT.STORE) => {
|
|
1749
|
+
var _a;
|
|
1750
|
+
const core = target(store);
|
|
1751
|
+
if (!core.operation.open) {
|
|
1752
|
+
(_a = store.config.logger) == null ? void 0 : _a.warn(
|
|
1753
|
+
`recall called outside of an operation. This is probably a bug.`
|
|
1754
|
+
);
|
|
1755
|
+
return core.valueMap.get(state.key);
|
|
1756
|
+
}
|
|
1757
|
+
return core.operation.prev.get(state.key);
|
|
1758
|
+
};
|
|
1759
|
+
|
|
1760
|
+
// src/subscribe/subscribe-to-root-atoms.ts
|
|
1761
|
+
var subscribeToRootAtoms = (state, store) => {
|
|
1762
|
+
const dependencySubscriptions = `default` in state ? null : traceAllSelectorAtoms(state.key, store).map((atomToken) => {
|
|
1763
|
+
const atom = withdraw(atomToken, store);
|
|
1764
|
+
if (atom === null) {
|
|
1765
|
+
throw new Error(
|
|
1766
|
+
`Atom "${atomToken.key}", a dependency of selector "${state.key}", not found in store "${store.config.name}".`
|
|
1767
|
+
);
|
|
1768
|
+
}
|
|
1769
|
+
return atom.subject.subscribe(
|
|
1770
|
+
`${state.type}:${state.key}`,
|
|
1771
|
+
(atomChange) => {
|
|
1772
|
+
var _a, _b;
|
|
1773
|
+
(_a = store.config.logger) == null ? void 0 : _a.info(
|
|
1774
|
+
`\u{1F4E2} selector "${state.key}" saw root "${atomToken.key}" go (`,
|
|
1775
|
+
atomChange.oldValue,
|
|
1776
|
+
`->`,
|
|
1777
|
+
atomChange.newValue,
|
|
1778
|
+
`)`
|
|
1779
|
+
);
|
|
1780
|
+
const oldValue = recallState(state, store);
|
|
1781
|
+
const newValue = getState__INTERNAL(state, store);
|
|
1782
|
+
(_b = store.config.logger) == null ? void 0 : _b.info(
|
|
1783
|
+
` <- "${state.key}" went (`,
|
|
1784
|
+
oldValue,
|
|
1785
|
+
`->`,
|
|
1786
|
+
newValue,
|
|
1787
|
+
`)`
|
|
1788
|
+
);
|
|
1789
|
+
state.subject.next({ newValue, oldValue });
|
|
1790
|
+
}
|
|
1791
|
+
);
|
|
1792
|
+
});
|
|
1793
|
+
return dependencySubscriptions;
|
|
1794
|
+
};
|
|
1795
|
+
|
|
1796
|
+
export { FamilyTracker, IMPLICIT, Store, Subject, TRANSACTION_PHASES, Tracker, abortTransaction, addAtomToTimeline, applyTransaction, become, buildTransaction, cacheValue, clearStore, closeOperation, createAtom, createAtomFamily, createMutableAtom, createMutableAtomFamily, createReadonlySelectorFamily, createSelector, createSelectorFamily, deleteAtom, deposit, getJsonToken, getState__INTERNAL, getUpdateToken, isAtomDefault, isAtomMutable, isAtomTokenMutable, isDone, isSelectorDefault, isTransceiver, isValueCached, lookup, lookupSelectorSources, markAtomAsDefault, markAtomAsNotDefault, markDone, openOperation, readCachedValue, redoTransactionUpdate, redo__INTERNAL, registerSelector, setState__INTERNAL, subscribeToRootAtoms, target, timeline__INTERNAL, traceAllSelectorAtoms, traceSelectorAtoms, transaction__INTERNAL, undoTransactionUpdate, undo__INTERNAL, updateSelectorAtoms, withdraw, withdrawNewFamilyMember };
|
|
1797
|
+
//# sourceMappingURL=out.js.map
|
|
1798
|
+
//# sourceMappingURL=index.mjs.map
|