atom.io 0.31.1 → 0.32.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/data/dist/index.d.ts +3 -154
- package/data/dist/index.js +11 -559
- package/data/src/index.ts +0 -2
- package/data/src/struct-family.ts +1 -1
- package/data/src/struct.ts +1 -2
- package/dist/chunk-3PQTWLQQ.js +83 -0
- package/dist/chunk-3ZFTRSNG.js +523 -0
- package/dist/chunk-4LWKCEW3.js +14 -0
- package/dist/chunk-KVI5OBF2.js +153 -0
- package/dist/{chunk-Y5MBNTVU.js → chunk-UQEYZ3OI.js} +1814 -721
- package/dist/chunk-UYYKOGZQ.js +1034 -0
- package/dist/chunk-VRJP2PCU.js +631 -0
- package/dist/chunk-X7SD2NXU.js +108 -0
- package/dist/index.d.ts +137 -12
- package/dist/index.js +1 -228
- package/eslint-plugin/dist/index.d.ts +1 -30
- package/eslint-plugin/dist/index.js +3 -149
- package/eslint-plugin/src/index.ts +0 -1
- package/eslint-plugin/src/rules/explicit-state-types.ts +1 -0
- package/eslint-plugin/src/rules/index.ts +0 -1
- package/eslint-plugin/src/rules/synchronous-selector-dependencies.ts +1 -0
- package/eslint-plugin/src/walk.ts +1 -0
- package/internal/dist/index.d.ts +129 -58
- package/internal/dist/index.js +1 -1
- package/internal/src/atom/create-regular-atom.ts +3 -3
- package/internal/src/atom/dispose-atom.ts +4 -13
- package/internal/src/atom/is-default.ts +3 -3
- package/internal/src/caching.ts +5 -5
- package/internal/src/capitalize.ts +3 -0
- package/internal/src/families/create-readonly-selector-family.ts +5 -6
- package/internal/src/families/create-writable-selector-family.ts +1 -4
- package/internal/src/families/dispose-from-store.ts +3 -13
- package/internal/src/get-state/get-from-store.ts +2 -2
- package/internal/src/get-state/read-or-compute-value.ts +1 -1
- package/internal/src/index.ts +2 -0
- package/internal/src/install-into-store.ts +1 -1
- package/internal/src/join/edit-relations-in-store.ts +32 -0
- package/internal/src/join/find-relations-in-store.ts +124 -0
- package/internal/src/join/get-internal-relations-from-store.ts +14 -0
- package/internal/src/join/get-join.ts +31 -0
- package/internal/src/join/index.ts +5 -0
- package/{data/src/join.ts → internal/src/join/join-internal.ts} +21 -430
- package/internal/src/junction.ts +7 -4
- package/internal/src/keys.ts +7 -7
- package/internal/src/mutable/create-mutable-atom-family.ts +1 -1
- package/internal/src/mutable/create-mutable-atom.ts +3 -3
- package/internal/src/mutable/get-json-token.ts +1 -1
- package/internal/src/mutable/tracker-family.ts +19 -17
- package/internal/src/mutable/tracker.ts +8 -8
- package/internal/src/pretty-print.ts +1 -1
- package/internal/src/selector/create-readonly-selector.ts +3 -7
- package/internal/src/selector/create-writable-selector.ts +4 -4
- package/internal/src/selector/dispose-selector.ts +20 -11
- package/internal/src/selector/get-selector-dependency-keys.ts +1 -1
- package/internal/src/selector/register-selector.ts +6 -9
- package/internal/src/selector/trace-selector-atoms.ts +2 -2
- package/internal/src/set-state/copy-mutable-if-needed.ts +1 -1
- package/internal/src/set-state/emit-update.ts +4 -2
- package/internal/src/set-state/evict-downstream.ts +1 -1
- package/internal/src/set-state/set-atom-or-selector.ts +1 -1
- package/internal/src/set-state/set-atom.ts +10 -10
- package/internal/src/set-state/set-into-store.ts +2 -2
- package/internal/src/set-state/stow-update.ts +1 -1
- package/internal/src/store/store.ts +1 -1
- package/internal/src/store/withdraw.ts +22 -22
- package/internal/src/subscribe/recall-state.ts +1 -1
- package/internal/src/subscribe/subscribe-in-store.ts +3 -3
- package/internal/src/subscribe/subscribe-to-root-atoms.ts +3 -3
- package/internal/src/subscribe/subscribe-to-state.ts +5 -5
- package/internal/src/subscribe/subscribe-to-timeline.ts +3 -3
- package/internal/src/subscribe/subscribe-to-transaction.ts +3 -3
- package/internal/src/timeline/create-timeline.ts +19 -38
- package/internal/src/timeline/time-travel.ts +2 -1
- package/internal/src/transaction/act-upon-store.ts +2 -2
- package/internal/src/transaction/apply-transaction.ts +5 -5
- package/internal/src/transaction/assign-transaction-to-continuity.ts +1 -1
- package/internal/src/transaction/build-transaction.ts +5 -8
- package/internal/src/transaction/create-transaction.ts +3 -3
- package/internal/src/transaction/get-epoch-number.ts +3 -3
- package/internal/src/transaction/set-epoch-number.ts +2 -2
- package/introspection/dist/index.js +2 -620
- package/json/dist/index.d.ts +2 -2
- package/json/dist/index.js +1 -80
- package/json/src/select-json-family.ts +3 -14
- package/package.json +31 -49
- package/react/dist/index.js +2 -82
- package/react/src/use-o.ts +1 -1
- package/react/src/use-tl.ts +2 -2
- package/react-devtools/dist/index.css +16 -14
- package/react-devtools/dist/index.js +31 -18
- package/react-devtools/src/Updates.tsx +12 -0
- package/react-devtools/src/devtools.scss +16 -14
- package/react-devtools/src/json-editor/editors-by-type/utilities/cast-to-json.ts +2 -1
- package/realtime/dist/index.d.ts +1 -2
- package/realtime/dist/index.js +2 -107
- package/realtime/src/realtime-continuity.ts +3 -2
- package/realtime/src/shared-room-store.ts +1 -2
- package/realtime-client/dist/index.d.ts +9 -9
- package/realtime-client/dist/index.js +3 -509
- package/realtime-client/src/continuity/register-and-attempt-confirmed-update.ts +3 -3
- package/realtime-client/src/continuity/use-conceal-state.ts +1 -1
- package/realtime-client/src/pull-atom-family-member.ts +2 -2
- package/realtime-client/src/pull-atom.ts +2 -2
- package/realtime-client/src/pull-mutable-atom-family-member.ts +2 -2
- package/realtime-client/src/pull-mutable-atom.ts +2 -2
- package/realtime-client/src/pull-selector-family-member.ts +4 -4
- package/realtime-client/src/pull-selector.ts +4 -4
- package/realtime-client/src/push-state.ts +5 -10
- package/realtime-client/src/server-action.ts +4 -4
- package/realtime-client/src/sync-continuity.ts +6 -6
- package/realtime-react/dist/index.js +5 -154
- package/realtime-react/src/use-pull-atom-family-member.ts +1 -1
- package/realtime-react/src/use-pull-atom.ts +1 -1
- package/realtime-react/src/use-pull-mutable-atom.ts +1 -1
- package/realtime-react/src/use-pull-mutable-family-member.ts +1 -1
- package/realtime-react/src/use-pull-selector-family-member.ts +1 -1
- package/realtime-react/src/use-pull-selector.ts +1 -1
- package/realtime-react/src/use-push.ts +1 -1
- package/realtime-react/src/use-server-action.ts +2 -2
- package/realtime-react/src/use-sync-continuity.ts +1 -1
- package/realtime-server/dist/index.d.ts +2 -4
- package/realtime-server/dist/index.js +3 -1001
- package/realtime-server/src/continuity/prepare-to-serve-transaction-request.ts +1 -1
- package/realtime-server/src/continuity/prepare-to-sync-realtime-continuity.ts +3 -3
- package/realtime-server/src/continuity/subscribe-to-continuity-actions.ts +2 -2
- package/realtime-server/src/continuity/subscribe-to-continuity-perpectives.ts +2 -2
- package/realtime-server/src/ipc-sockets/child-socket.ts +2 -0
- package/realtime-server/src/realtime-action-receiver.ts +1 -1
- package/realtime-server/src/realtime-family-provider.ts +2 -2
- package/realtime-server/src/realtime-mutable-family-provider.ts +2 -2
- package/realtime-server/src/realtime-mutable-provider.ts +2 -2
- package/realtime-server/src/realtime-server-stores/server-room-external-actions.ts +2 -1
- package/realtime-server/src/realtime-server-stores/server-room-external-store.ts +1 -1
- package/realtime-server/src/realtime-server-stores/server-sync-store.ts +10 -2
- package/realtime-server/src/realtime-server-stores/server-user-store.ts +1 -2
- package/realtime-server/src/realtime-state-provider.ts +2 -2
- package/realtime-testing/dist/index.js +20 -22
- package/realtime-testing/src/setup-realtime-test.tsx +2 -1
- package/src/index.ts +4 -0
- package/src/join.ts +218 -0
- package/src/silo.ts +4 -4
- package/src/timeline.ts +1 -1
- package/src/transaction.ts +4 -8
- package/transceivers/set-rtx/dist/index.d.ts +4 -3
- package/transceivers/set-rtx/dist/index.js +1 -215
- package/transceivers/set-rtx/src/set-rtx.ts +4 -7
- package/web/dist/index.js +1 -15
- package/data/src/until.ts +0 -15
- package/ephemeral/dist/index.d.ts +0 -67
- package/ephemeral/dist/index.js +0 -9
- package/ephemeral/package.json +0 -13
- package/ephemeral/src/index.ts +0 -1
- package/eslint-plugin/src/rules/lifespan.ts +0 -203
- package/immortal/dist/index.d.ts +0 -12
- package/immortal/dist/index.js +0 -9
- package/immortal/package.json +0 -13
- package/immortal/src/index.ts +0 -1
- package/immortal/src/seek-state.ts +0 -60
- package/react-devtools/src/json-editor/assets/Untitled-1.ai +2 -1436
- package/react-devtools/src/json-editor/assets/data-vis.ai +1 -1548
- package/react-devtools/src/json-editor/comp/json-editor-sketches.ai +5 -1449
- /package/{ephemeral/src → src}/find-state.ts +0 -0
|
@@ -1,6 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
// json/src/entries.ts
|
|
2
|
+
function fromEntries(entries) {
|
|
3
|
+
return Object.fromEntries(entries);
|
|
4
|
+
}
|
|
5
|
+
function toEntries(obj) {
|
|
6
|
+
return Object.entries(obj);
|
|
7
|
+
}
|
|
4
8
|
|
|
5
9
|
// internal/src/arbitrary.ts
|
|
6
10
|
function arbitrary(random = Math.random) {
|
|
@@ -50,7 +54,7 @@ var Future = class extends Promise {
|
|
|
50
54
|
);
|
|
51
55
|
} else {
|
|
52
56
|
this.resolve(value);
|
|
53
|
-
this.fate =
|
|
57
|
+
this.fate = void 0;
|
|
54
58
|
}
|
|
55
59
|
}
|
|
56
60
|
};
|
|
@@ -92,6 +96,8 @@ var CircularBuffer = class _CircularBuffer {
|
|
|
92
96
|
return copy;
|
|
93
97
|
}
|
|
94
98
|
};
|
|
99
|
+
|
|
100
|
+
// internal/src/store/counterfeit.ts
|
|
95
101
|
var FAMILY_MEMBER_TOKEN_TYPES = {
|
|
96
102
|
atom_family: `atom`,
|
|
97
103
|
mutable_atom_family: `mutable_atom`,
|
|
@@ -129,349 +135,161 @@ function deposit(state) {
|
|
|
129
135
|
return token;
|
|
130
136
|
}
|
|
131
137
|
|
|
132
|
-
//
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
}
|
|
147
|
-
addRelation(a, b) {
|
|
148
|
-
let aRelations = this.relations.get(a);
|
|
149
|
-
let bRelations = this.relations.get(b);
|
|
150
|
-
if (aRelations) {
|
|
151
|
-
aRelations.add(b);
|
|
152
|
-
} else {
|
|
153
|
-
aRelations = /* @__PURE__ */ new Set([b]);
|
|
154
|
-
this.relations.set(a, aRelations);
|
|
155
|
-
}
|
|
156
|
-
if (bRelations) {
|
|
157
|
-
bRelations.add(a);
|
|
158
|
-
} else {
|
|
159
|
-
bRelations = /* @__PURE__ */ new Set([a]);
|
|
160
|
-
this.relations.set(b, bRelations);
|
|
161
|
-
}
|
|
138
|
+
// src/atom.ts
|
|
139
|
+
function atom(options) {
|
|
140
|
+
return createStandaloneAtom(IMPLICIT.STORE, options);
|
|
141
|
+
}
|
|
142
|
+
function atomFamily(options) {
|
|
143
|
+
return createAtomFamily(IMPLICIT.STORE, options);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// src/dispose-state.ts
|
|
147
|
+
function disposeState(...[token, key]) {
|
|
148
|
+
if (key) {
|
|
149
|
+
disposeFromStore(IMPLICIT.STORE, token, key);
|
|
150
|
+
} else {
|
|
151
|
+
disposeFromStore(IMPLICIT.STORE, token);
|
|
162
152
|
}
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// src/find-state.ts
|
|
156
|
+
function findState(token, key) {
|
|
157
|
+
const state = findInStore(IMPLICIT.STORE, token, key);
|
|
158
|
+
return state;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// src/get-state.ts
|
|
162
|
+
function getState(...params) {
|
|
163
|
+
if (params.length === 2) {
|
|
164
|
+
return getFromStore(IMPLICIT.STORE, ...params);
|
|
178
165
|
}
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
166
|
+
return getFromStore(IMPLICIT.STORE, ...params);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// src/join.ts
|
|
170
|
+
function join(options, defaultContent, store = IMPLICIT.STORE) {
|
|
171
|
+
store.joins.set(options.key, new Join(options, defaultContent, store));
|
|
172
|
+
const token = {
|
|
173
|
+
key: options.key,
|
|
174
|
+
type: `join`,
|
|
175
|
+
a: options.between[0],
|
|
176
|
+
b: options.between[1],
|
|
177
|
+
cardinality: options.cardinality
|
|
178
|
+
};
|
|
179
|
+
return token;
|
|
180
|
+
}
|
|
181
|
+
function findRelations(token, key) {
|
|
182
|
+
return findRelationsInStore(token, key, IMPLICIT.STORE);
|
|
183
|
+
}
|
|
184
|
+
function editRelations(token, change) {
|
|
185
|
+
editRelationsInStore(token, change, IMPLICIT.STORE);
|
|
186
|
+
}
|
|
187
|
+
function getInternalRelations(token) {
|
|
188
|
+
return getInternalRelationsFromStore(token, IMPLICIT.STORE);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// src/logger.ts
|
|
192
|
+
var LOG_LEVELS = [`info`, `warn`, `error`];
|
|
193
|
+
var simpleLog = (logLevel) => (icon, denomination, tokenKey, message, ...rest) => {
|
|
194
|
+
console[logLevel](
|
|
195
|
+
`${icon} ${denomination} "${tokenKey}" ${message}`,
|
|
196
|
+
...rest
|
|
197
|
+
);
|
|
198
|
+
};
|
|
199
|
+
var simpleLogger = {
|
|
200
|
+
error: simpleLog(`error`),
|
|
201
|
+
info: simpleLog(`info`),
|
|
202
|
+
warn: simpleLog(`warn`)
|
|
203
|
+
};
|
|
204
|
+
var AtomIOLogger = class {
|
|
205
|
+
constructor(logLevel, filter, logger = simpleLogger) {
|
|
206
|
+
this.logLevel = logLevel;
|
|
207
|
+
this.filter = filter;
|
|
208
|
+
this.logger = logger;
|
|
209
|
+
}
|
|
210
|
+
error = (...args) => {
|
|
211
|
+
if ((this.filter?.(...args) ?? true) && this.logLevel !== null) {
|
|
212
|
+
this.logger.error(...args);
|
|
184
213
|
}
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
let b = a === undefined ? x : undefined;
|
|
190
|
-
if (xRelationsPrev) {
|
|
191
|
-
for (const y of xRelationsPrev) {
|
|
192
|
-
a ??= y;
|
|
193
|
-
b ??= y;
|
|
194
|
-
const yRelations = this.relations.get(y);
|
|
195
|
-
if (yRelations) {
|
|
196
|
-
if (yRelations.size === 1) {
|
|
197
|
-
this.relations.delete(y);
|
|
198
|
-
} else {
|
|
199
|
-
yRelations.delete(x);
|
|
200
|
-
}
|
|
201
|
-
this.contents.delete(this.makeContentKey(a, b));
|
|
202
|
-
}
|
|
203
|
-
}
|
|
214
|
+
};
|
|
215
|
+
info = (...args) => {
|
|
216
|
+
if ((this.filter?.(...args) ?? true) && this.logLevel === `info`) {
|
|
217
|
+
this.logger.info(...args);
|
|
204
218
|
}
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
yRelations.add(x);
|
|
210
|
-
} else {
|
|
211
|
-
yRelations = (/* @__PURE__ */ new Set()).add(x);
|
|
212
|
-
this.relations.set(y, yRelations);
|
|
213
|
-
}
|
|
219
|
+
};
|
|
220
|
+
warn = (...args) => {
|
|
221
|
+
if ((this.filter?.(...args) ?? true) && this.logLevel !== `error` && this.logLevel !== null) {
|
|
222
|
+
this.logger.warn(...args);
|
|
214
223
|
}
|
|
224
|
+
};
|
|
225
|
+
};
|
|
226
|
+
|
|
227
|
+
// src/realm.ts
|
|
228
|
+
var $claim = Symbol(`claim`);
|
|
229
|
+
var Realm = class {
|
|
230
|
+
store;
|
|
231
|
+
constructor(store = IMPLICIT.STORE) {
|
|
232
|
+
this.store = store;
|
|
233
|
+
makeRootMoleculeInStore(`root`, store);
|
|
234
|
+
}
|
|
235
|
+
allocate(provenance, key, attachmentStyle) {
|
|
236
|
+
return allocateIntoStore(
|
|
237
|
+
this.store,
|
|
238
|
+
provenance,
|
|
239
|
+
key,
|
|
240
|
+
attachmentStyle
|
|
241
|
+
);
|
|
215
242
|
}
|
|
216
|
-
|
|
217
|
-
return this.
|
|
243
|
+
fuse(type, reagentA, reagentB) {
|
|
244
|
+
return fuseWithinStore(this.store, type, reagentA, reagentB);
|
|
218
245
|
}
|
|
219
|
-
|
|
220
|
-
this.
|
|
246
|
+
deallocate(claim) {
|
|
247
|
+
deallocateFromStore(this.store, claim);
|
|
221
248
|
}
|
|
222
|
-
|
|
223
|
-
this.
|
|
249
|
+
claim(newProvenance, claim, exclusive) {
|
|
250
|
+
return claimWithinStore(this.store, newProvenance, claim, exclusive);
|
|
224
251
|
}
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
}
|
|
241
|
-
if (config?.externalStore) {
|
|
242
|
-
const externalStore = config.externalStore;
|
|
243
|
-
this.has = (a, b) => externalStore.has(a, b);
|
|
244
|
-
this.addRelation = (a, b) => {
|
|
245
|
-
externalStore.addRelation(a, b);
|
|
246
|
-
};
|
|
247
|
-
this.deleteRelation = (a, b) => {
|
|
248
|
-
externalStore.deleteRelation(a, b);
|
|
249
|
-
};
|
|
250
|
-
this.replaceRelationsSafely = (a, bs) => {
|
|
251
|
-
externalStore.replaceRelationsSafely(a, bs);
|
|
252
|
-
};
|
|
253
|
-
this.replaceRelationsUnsafely = (a, bs) => {
|
|
254
|
-
externalStore.replaceRelationsUnsafely(a, bs);
|
|
255
|
-
};
|
|
256
|
-
this.getRelatedKeys = (key) => externalStore.getRelatedKeys(
|
|
257
|
-
key
|
|
258
|
-
);
|
|
259
|
-
if (externalStore.getContent) {
|
|
260
|
-
this.getContentInternal = (contentKey) => {
|
|
261
|
-
return externalStore.getContent(contentKey);
|
|
262
|
-
};
|
|
263
|
-
this.setContent = (contentKey, content) => {
|
|
264
|
-
externalStore.setContent(contentKey, content);
|
|
265
|
-
};
|
|
266
|
-
this.deleteContent = (contentKey) => {
|
|
267
|
-
externalStore.deleteContent(contentKey);
|
|
268
|
-
};
|
|
269
|
-
}
|
|
270
|
-
for (const [x, ys] of data.relations ?? []) {
|
|
271
|
-
let a = this.isAType?.(x) ? x : undefined;
|
|
272
|
-
let b = a === undefined ? x : undefined;
|
|
273
|
-
for (const y of ys) {
|
|
274
|
-
a ??= y;
|
|
275
|
-
b ??= y;
|
|
276
|
-
this.addRelation(a, b);
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
for (const [contentKey, content] of data.contents ?? []) {
|
|
280
|
-
this.setContent(contentKey, content);
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
if (config?.warn) {
|
|
284
|
-
this.warn = config.warn;
|
|
285
|
-
}
|
|
252
|
+
};
|
|
253
|
+
var Anarchy = class {
|
|
254
|
+
store;
|
|
255
|
+
realm;
|
|
256
|
+
constructor(store = IMPLICIT.STORE) {
|
|
257
|
+
this.store = store;
|
|
258
|
+
this.realm = new Realm(store);
|
|
259
|
+
}
|
|
260
|
+
allocate(provenance, key, attachmentStyle) {
|
|
261
|
+
allocateIntoStore(
|
|
262
|
+
this.store,
|
|
263
|
+
provenance,
|
|
264
|
+
key,
|
|
265
|
+
attachmentStyle
|
|
266
|
+
);
|
|
286
267
|
}
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
between: [this.a, this.b],
|
|
290
|
-
cardinality: this.cardinality,
|
|
291
|
-
relations: [...this.relations.entries()].map(
|
|
292
|
-
([a, b]) => [a, [...b]]
|
|
293
|
-
),
|
|
294
|
-
contents: [...this.contents.entries()]
|
|
295
|
-
};
|
|
268
|
+
deallocate(key) {
|
|
269
|
+
deallocateFromStore(this.store, key);
|
|
296
270
|
}
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
let b;
|
|
300
|
-
let content;
|
|
301
|
-
switch (params.length) {
|
|
302
|
-
case 1: {
|
|
303
|
-
const relation = params[0];
|
|
304
|
-
a = relation[this.a];
|
|
305
|
-
b = relation[this.b];
|
|
306
|
-
content = undefined;
|
|
307
|
-
break;
|
|
308
|
-
}
|
|
309
|
-
case 2: {
|
|
310
|
-
const zeroth = params[0];
|
|
311
|
-
if (typeof zeroth === `string`) {
|
|
312
|
-
[a, b] = params;
|
|
313
|
-
} else {
|
|
314
|
-
a = zeroth[this.a];
|
|
315
|
-
b = zeroth[this.b];
|
|
316
|
-
content = params[1];
|
|
317
|
-
}
|
|
318
|
-
break;
|
|
319
|
-
}
|
|
320
|
-
default: {
|
|
321
|
-
a = params[0];
|
|
322
|
-
b = params[1];
|
|
323
|
-
content = params[2];
|
|
324
|
-
break;
|
|
325
|
-
}
|
|
326
|
-
}
|
|
327
|
-
switch (this.cardinality) {
|
|
328
|
-
// biome-ignore lint/suspicious/noFallthroughSwitchClause: perfect here
|
|
329
|
-
case `1:1`: {
|
|
330
|
-
const bPrev = this.getRelatedKey(a);
|
|
331
|
-
if (bPrev && bPrev !== b) this.delete(a, bPrev);
|
|
332
|
-
}
|
|
333
|
-
case `1:n`: {
|
|
334
|
-
const aPrev = this.getRelatedKey(b);
|
|
335
|
-
if (aPrev && aPrev !== a) this.delete(aPrev, b);
|
|
336
|
-
}
|
|
337
|
-
}
|
|
338
|
-
if (content) {
|
|
339
|
-
const contentKey = this.makeContentKey(a, b);
|
|
340
|
-
this.setContent(contentKey, content);
|
|
341
|
-
}
|
|
342
|
-
this.addRelation(a, b);
|
|
343
|
-
return this;
|
|
344
|
-
}
|
|
345
|
-
delete(x, b) {
|
|
346
|
-
b = typeof b === `string` ? b : x[this.b];
|
|
347
|
-
const a = (
|
|
348
|
-
// @ts-expect-error we deduce that this.a may index x
|
|
349
|
-
typeof x === `string` ? x : x[this.a]
|
|
350
|
-
);
|
|
351
|
-
if (a === undefined && typeof b === `string`) {
|
|
352
|
-
const bRelations = this.getRelatedKeys(b);
|
|
353
|
-
if (bRelations) {
|
|
354
|
-
for (const bRelation of bRelations) {
|
|
355
|
-
this.delete(bRelation, b);
|
|
356
|
-
}
|
|
357
|
-
}
|
|
358
|
-
}
|
|
359
|
-
if (typeof a === `string` && b === undefined) {
|
|
360
|
-
const aRelations = this.getRelatedKeys(a);
|
|
361
|
-
if (aRelations) {
|
|
362
|
-
for (const aRelation of aRelations) {
|
|
363
|
-
this.delete(a, aRelation);
|
|
364
|
-
}
|
|
365
|
-
}
|
|
366
|
-
}
|
|
367
|
-
if (typeof a === `string` && typeof b === `string`) {
|
|
368
|
-
this.deleteRelation(a, b);
|
|
369
|
-
const contentKey = this.makeContentKey(a, b);
|
|
370
|
-
this.deleteContent(contentKey);
|
|
371
|
-
}
|
|
372
|
-
return this;
|
|
373
|
-
}
|
|
374
|
-
getRelatedKey(key) {
|
|
375
|
-
const relations = this.getRelatedKeys(key);
|
|
376
|
-
if (relations) {
|
|
377
|
-
if (relations.size > 1) {
|
|
378
|
-
this.warn?.(
|
|
379
|
-
`${relations.size} related keys were found for key "${key}": (${[
|
|
380
|
-
...relations
|
|
381
|
-
].map((k) => `"${k}"`).join(`, `)}). Only one related key was expected.`
|
|
382
|
-
);
|
|
383
|
-
}
|
|
384
|
-
let singleRelation;
|
|
385
|
-
for (const relation of relations) {
|
|
386
|
-
singleRelation = relation;
|
|
387
|
-
break;
|
|
388
|
-
}
|
|
389
|
-
return singleRelation;
|
|
390
|
-
}
|
|
391
|
-
}
|
|
392
|
-
replaceRelations(x, relations, config) {
|
|
393
|
-
const hasContent = !Array.isArray(relations);
|
|
394
|
-
const ys = hasContent ? Object.keys(relations) : relations;
|
|
395
|
-
if (config?.reckless) {
|
|
396
|
-
this.replaceRelationsUnsafely(x, ys);
|
|
397
|
-
} else {
|
|
398
|
-
this.replaceRelationsSafely(x, ys);
|
|
399
|
-
}
|
|
400
|
-
if (hasContent) {
|
|
401
|
-
for (const y of ys) {
|
|
402
|
-
const contentKey = this.makeContentKey(x, y);
|
|
403
|
-
const content = relations[y];
|
|
404
|
-
this.setContent(contentKey, content);
|
|
405
|
-
}
|
|
406
|
-
}
|
|
407
|
-
return this;
|
|
408
|
-
}
|
|
409
|
-
getContent(a, b) {
|
|
410
|
-
const contentKey = this.makeContentKey(a, b);
|
|
411
|
-
return this.getContentInternal(contentKey);
|
|
412
|
-
}
|
|
413
|
-
getRelationEntries(input) {
|
|
414
|
-
const a = input[this.a];
|
|
415
|
-
const b = input[this.b];
|
|
416
|
-
if (a !== undefined && b === undefined) {
|
|
417
|
-
const aRelations = this.getRelatedKeys(a);
|
|
418
|
-
if (aRelations) {
|
|
419
|
-
return [...aRelations].map((aRelation) => {
|
|
420
|
-
return [aRelation, this.getContent(a, aRelation)];
|
|
421
|
-
});
|
|
422
|
-
}
|
|
423
|
-
}
|
|
424
|
-
if (a === undefined && b !== undefined) {
|
|
425
|
-
const bRelations = this.getRelatedKeys(b);
|
|
426
|
-
if (bRelations) {
|
|
427
|
-
return [...bRelations].map((bRelation) => {
|
|
428
|
-
return [bRelation, this.getContent(bRelation, b)];
|
|
429
|
-
});
|
|
430
|
-
}
|
|
431
|
-
}
|
|
432
|
-
return [];
|
|
433
|
-
}
|
|
434
|
-
has(a, b) {
|
|
435
|
-
if (b) {
|
|
436
|
-
const setA = this.getRelatedKeys(a);
|
|
437
|
-
return setA?.has(b) ?? false;
|
|
438
|
-
}
|
|
439
|
-
return this.relations.has(a);
|
|
271
|
+
claim(newProvenance, key, exclusive) {
|
|
272
|
+
claimWithinStore(this.store, newProvenance, key, exclusive);
|
|
440
273
|
}
|
|
441
274
|
};
|
|
275
|
+
var T$ = `T$`;
|
|
442
276
|
|
|
443
|
-
//
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
next(value) {
|
|
458
|
-
const subscribers = this.subscribers.values();
|
|
459
|
-
for (const subscriber of subscribers) {
|
|
460
|
-
subscriber(value);
|
|
461
|
-
}
|
|
462
|
-
}
|
|
463
|
-
};
|
|
464
|
-
var StatefulSubject = class extends Subject {
|
|
465
|
-
state;
|
|
466
|
-
constructor(initialState) {
|
|
467
|
-
super();
|
|
468
|
-
this.state = initialState;
|
|
469
|
-
}
|
|
470
|
-
next(value) {
|
|
471
|
-
this.state = value;
|
|
472
|
-
super.next(value);
|
|
277
|
+
// src/selector.ts
|
|
278
|
+
function selector(options) {
|
|
279
|
+
return createStandaloneSelector(IMPLICIT.STORE, options);
|
|
280
|
+
}
|
|
281
|
+
function selectorFamily(options) {
|
|
282
|
+
return createSelectorFamily(IMPLICIT.STORE, options);
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
// src/set-state.ts
|
|
286
|
+
function setState(...params) {
|
|
287
|
+
if (params.length === 2) {
|
|
288
|
+
setIntoStore(IMPLICIT.STORE, ...params);
|
|
289
|
+
} else {
|
|
290
|
+
setIntoStore(IMPLICIT.STORE, ...params);
|
|
473
291
|
}
|
|
474
|
-
}
|
|
292
|
+
}
|
|
475
293
|
|
|
476
294
|
// internal/src/transaction/is-root-store.ts
|
|
477
295
|
function isRootStore(store) {
|
|
@@ -502,8 +320,12 @@ var abortTransaction = (store) => {
|
|
|
502
320
|
target.parent.child = null;
|
|
503
321
|
};
|
|
504
322
|
|
|
323
|
+
// internal/src/capitalize.ts
|
|
324
|
+
function capitalize(string) {
|
|
325
|
+
return string[0].toUpperCase() + string.slice(1);
|
|
326
|
+
}
|
|
327
|
+
|
|
505
328
|
// internal/src/pretty-print.ts
|
|
506
|
-
var capitalize = (str) => str[0].toUpperCase() + str.slice(1);
|
|
507
329
|
function prettyPrintTokenType(token) {
|
|
508
330
|
return token.type.split(`_`).map(capitalize).join(` `);
|
|
509
331
|
}
|
|
@@ -518,9 +340,9 @@ var NotFoundError = class extends Error {
|
|
|
518
340
|
};
|
|
519
341
|
|
|
520
342
|
// internal/src/transaction/act-upon-store.ts
|
|
521
|
-
function actUponStore(token, id
|
|
343
|
+
function actUponStore(store, token, id) {
|
|
522
344
|
return (...parameters) => {
|
|
523
|
-
const tx = withdraw(
|
|
345
|
+
const tx = withdraw(store, token);
|
|
524
346
|
if (tx) {
|
|
525
347
|
return tx.run(parameters, id);
|
|
526
348
|
}
|
|
@@ -532,7 +354,7 @@ function actUponStore(token, id, store) {
|
|
|
532
354
|
var become = (nextVersionOfThing) => (originalThing) => nextVersionOfThing instanceof Function ? nextVersionOfThing(originalThing) : nextVersionOfThing;
|
|
533
355
|
|
|
534
356
|
// internal/src/get-state/read-or-compute-value.ts
|
|
535
|
-
var readOrComputeValue = (
|
|
357
|
+
var readOrComputeValue = (target, state) => {
|
|
536
358
|
if (target.valueMap.has(state.key)) {
|
|
537
359
|
target.logger.info(`\u{1F4D6}`, state.type, state.key, `reading cached value`);
|
|
538
360
|
return readCachedValue(state, target);
|
|
@@ -616,7 +438,7 @@ var markDone = (store, key) => {
|
|
|
616
438
|
};
|
|
617
439
|
|
|
618
440
|
// internal/src/set-state/emit-update.ts
|
|
619
|
-
var emitUpdate = (state, update
|
|
441
|
+
var emitUpdate = (store, state, update) => {
|
|
620
442
|
switch (state.type) {
|
|
621
443
|
case `mutable_atom`:
|
|
622
444
|
store.logger.info(
|
|
@@ -629,7 +451,9 @@ var emitUpdate = (state, update, store) => {
|
|
|
629
451
|
state.subject.subscribers
|
|
630
452
|
);
|
|
631
453
|
break;
|
|
632
|
-
|
|
454
|
+
case `atom`:
|
|
455
|
+
case `selector`:
|
|
456
|
+
case `readonly_selector`:
|
|
633
457
|
store.logger.info(
|
|
634
458
|
`\u{1F4E2}`,
|
|
635
459
|
state.type,
|
|
@@ -646,13 +470,13 @@ var emitUpdate = (state, update, store) => {
|
|
|
646
470
|
};
|
|
647
471
|
|
|
648
472
|
// internal/src/set-state/evict-downstream.ts
|
|
649
|
-
var evictDownStream = (
|
|
473
|
+
var evictDownStream = (store, atom2) => {
|
|
650
474
|
const target = newest(store);
|
|
651
|
-
const downstreamKeys = target.selectorAtoms.getRelatedKeys(
|
|
475
|
+
const downstreamKeys = target.selectorAtoms.getRelatedKeys(atom2.key);
|
|
652
476
|
target.logger.info(
|
|
653
477
|
`\u{1F9F9}`,
|
|
654
|
-
|
|
655
|
-
|
|
478
|
+
atom2.type,
|
|
479
|
+
atom2.key,
|
|
656
480
|
downstreamKeys ? `evicting ${downstreamKeys.size} states downstream:` : `no downstream states`,
|
|
657
481
|
downstreamKeys ?? `to evict`
|
|
658
482
|
);
|
|
@@ -660,8 +484,8 @@ var evictDownStream = (atom, store) => {
|
|
|
660
484
|
if (target.operation.open) {
|
|
661
485
|
target.logger.info(
|
|
662
486
|
`\u{1F9F9}`,
|
|
663
|
-
|
|
664
|
-
|
|
487
|
+
atom2.type,
|
|
488
|
+
atom2.key,
|
|
665
489
|
`[ ${[...target.operation.done].join(`, `)} ] already done`
|
|
666
490
|
);
|
|
667
491
|
}
|
|
@@ -685,7 +509,7 @@ function shouldUpdateBeStowed(key, update) {
|
|
|
685
509
|
}
|
|
686
510
|
return true;
|
|
687
511
|
}
|
|
688
|
-
var stowUpdate = (state, update
|
|
512
|
+
var stowUpdate = (store, state, update) => {
|
|
689
513
|
const { key } = state;
|
|
690
514
|
const target = newest(store);
|
|
691
515
|
if (!isChildStore(target) || target.transactionMeta.phase !== `building`) {
|
|
@@ -723,45 +547,45 @@ var stowUpdate = (state, update, store) => {
|
|
|
723
547
|
};
|
|
724
548
|
|
|
725
549
|
// internal/src/set-state/set-atom.ts
|
|
726
|
-
var setAtom = (
|
|
727
|
-
const oldValue = readOrComputeValue(
|
|
550
|
+
var setAtom = (atom2, next, target) => {
|
|
551
|
+
const oldValue = readOrComputeValue(target, atom2);
|
|
728
552
|
let newValue = oldValue;
|
|
729
|
-
if (
|
|
553
|
+
if (atom2.type === `mutable_atom` && isChildStore(target)) {
|
|
730
554
|
const { parent } = target;
|
|
731
|
-
const copiedValue = copyMutableIfNeeded(
|
|
555
|
+
const copiedValue = copyMutableIfNeeded(target, atom2, parent);
|
|
732
556
|
newValue = copiedValue;
|
|
733
557
|
}
|
|
734
558
|
newValue = become(next)(newValue);
|
|
735
|
-
target.logger.info(`\u{1F4DD}`, `atom`,
|
|
736
|
-
newValue = cacheValue(
|
|
737
|
-
if (isAtomDefault(
|
|
738
|
-
markAtomAsNotDefault(
|
|
559
|
+
target.logger.info(`\u{1F4DD}`, `atom`, atom2.key, `set to`, newValue);
|
|
560
|
+
newValue = cacheValue(target, atom2.key, newValue, atom2.subject);
|
|
561
|
+
if (isAtomDefault(target, atom2.key)) {
|
|
562
|
+
markAtomAsNotDefault(target, atom2.key);
|
|
739
563
|
}
|
|
740
|
-
markDone(target,
|
|
741
|
-
evictDownStream(
|
|
564
|
+
markDone(target, atom2.key);
|
|
565
|
+
evictDownStream(target, atom2);
|
|
742
566
|
const update = { oldValue, newValue };
|
|
743
567
|
if (isRootStore(target)) {
|
|
744
|
-
emitUpdate(
|
|
568
|
+
emitUpdate(target, atom2, update);
|
|
745
569
|
} else if (target.parent) {
|
|
746
570
|
if (target.on.transactionApplying.state === null) {
|
|
747
|
-
stowUpdate(
|
|
748
|
-
} else if (
|
|
749
|
-
const mutableKey =
|
|
571
|
+
stowUpdate(target, atom2, update);
|
|
572
|
+
} else if (atom2.key.startsWith(`*`)) {
|
|
573
|
+
const mutableKey = atom2.key.slice(1);
|
|
750
574
|
const mutableAtom = target.atoms.get(mutableKey);
|
|
751
575
|
let transceiver = target.valueMap.get(mutableKey);
|
|
752
576
|
if (mutableAtom.type === `mutable_atom` && isChildStore(target)) {
|
|
753
577
|
const { parent } = target;
|
|
754
|
-
const copiedValue = copyMutableIfNeeded(mutableAtom, parent
|
|
578
|
+
const copiedValue = copyMutableIfNeeded(target, mutableAtom, parent);
|
|
755
579
|
transceiver = copiedValue;
|
|
756
580
|
}
|
|
757
581
|
const accepted = transceiver.do(update.newValue) === null;
|
|
758
|
-
if (accepted) evictDownStream(
|
|
582
|
+
if (accepted) evictDownStream(target, mutableAtom);
|
|
759
583
|
}
|
|
760
584
|
}
|
|
761
585
|
};
|
|
762
586
|
|
|
763
587
|
// internal/src/set-state/set-atom-or-selector.ts
|
|
764
|
-
var setAtomOrSelector = (state, value
|
|
588
|
+
var setAtomOrSelector = (store, state, value) => {
|
|
765
589
|
switch (state.type) {
|
|
766
590
|
case `atom`:
|
|
767
591
|
case `mutable_atom`:
|
|
@@ -772,6 +596,41 @@ var setAtomOrSelector = (state, value, store) => {
|
|
|
772
596
|
break;
|
|
773
597
|
}
|
|
774
598
|
};
|
|
599
|
+
|
|
600
|
+
// internal/src/subject.ts
|
|
601
|
+
var Subject = class {
|
|
602
|
+
Subscriber;
|
|
603
|
+
subscribers = /* @__PURE__ */ new Map();
|
|
604
|
+
subscribe(key, subscriber) {
|
|
605
|
+
this.subscribers.set(key, subscriber);
|
|
606
|
+
const unsubscribe = () => {
|
|
607
|
+
this.unsubscribe(key);
|
|
608
|
+
};
|
|
609
|
+
return unsubscribe;
|
|
610
|
+
}
|
|
611
|
+
unsubscribe(key) {
|
|
612
|
+
this.subscribers.delete(key);
|
|
613
|
+
}
|
|
614
|
+
next(value) {
|
|
615
|
+
const subscribers = this.subscribers.values();
|
|
616
|
+
for (const subscriber of subscribers) {
|
|
617
|
+
subscriber(value);
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
};
|
|
621
|
+
var StatefulSubject = class extends Subject {
|
|
622
|
+
state;
|
|
623
|
+
constructor(initialState) {
|
|
624
|
+
super();
|
|
625
|
+
this.state = initialState;
|
|
626
|
+
}
|
|
627
|
+
next(value) {
|
|
628
|
+
this.state = value;
|
|
629
|
+
super.next(value);
|
|
630
|
+
}
|
|
631
|
+
};
|
|
632
|
+
|
|
633
|
+
// internal/src/families/create-regular-atom-family.ts
|
|
775
634
|
function createRegularAtomFamily(store, options, internalRoles) {
|
|
776
635
|
const familyToken = {
|
|
777
636
|
key: options.key,
|
|
@@ -806,12 +665,12 @@ function createRegularAtomFamily(store, options, internalRoles) {
|
|
|
806
665
|
subject.next({ type: `state_creation`, token });
|
|
807
666
|
return token;
|
|
808
667
|
};
|
|
809
|
-
const
|
|
668
|
+
const atomFamily2 = Object.assign(familyFunction, familyToken, {
|
|
810
669
|
subject,
|
|
811
670
|
install: (s) => createRegularAtomFamily(s, options),
|
|
812
671
|
internalRoles
|
|
813
672
|
});
|
|
814
|
-
store.families.set(options.key,
|
|
673
|
+
store.families.set(options.key, atomFamily2);
|
|
815
674
|
store.defaults.set(options.key, options.default);
|
|
816
675
|
return familyToken;
|
|
817
676
|
}
|
|
@@ -826,14 +685,14 @@ function createAtomFamily(store, options) {
|
|
|
826
685
|
}
|
|
827
686
|
|
|
828
687
|
// internal/src/keys.ts
|
|
829
|
-
var isAtomKey = (
|
|
830
|
-
var isSelectorKey = (
|
|
831
|
-
var isReadonlySelectorKey = (
|
|
832
|
-
var isStateKey = (
|
|
688
|
+
var isAtomKey = (store, key) => newest(store).atoms.has(key);
|
|
689
|
+
var isSelectorKey = (store, key) => newest(store).selectors.has(key);
|
|
690
|
+
var isReadonlySelectorKey = (store, key) => newest(store).readonlySelectors.has(key);
|
|
691
|
+
var isStateKey = (store, key) => isAtomKey(store, key) || isSelectorKey(store, key) || isReadonlySelectorKey(store, key);
|
|
833
692
|
|
|
834
693
|
// internal/src/selector/get-selector-dependency-keys.ts
|
|
835
694
|
var getSelectorDependencyKeys = (key, store) => {
|
|
836
|
-
const sources = newest(store).selectorGraph.getRelationEntries({ downstreamSelectorKey: key }).filter(([_, { source }]) => source !== key).map(([_, { source }]) => source).filter((source) => isStateKey(
|
|
695
|
+
const sources = newest(store).selectorGraph.getRelationEntries({ downstreamSelectorKey: key }).filter(([_, { source }]) => source !== key).map(([_, { source }]) => source).filter((source) => isStateKey(store, source));
|
|
837
696
|
return sources;
|
|
838
697
|
};
|
|
839
698
|
|
|
@@ -850,7 +709,7 @@ var traceSelectorAtoms = (directDependencyKey, covered, store) => {
|
|
|
850
709
|
continue;
|
|
851
710
|
}
|
|
852
711
|
covered.add(indirectDependencyKey);
|
|
853
|
-
if (!isAtomKey(
|
|
712
|
+
if (!isAtomKey(store, indirectDependencyKey)) {
|
|
854
713
|
indirectDependencyKeys.push(
|
|
855
714
|
...getSelectorDependencyKeys(indirectDependencyKey, store)
|
|
856
715
|
);
|
|
@@ -860,12 +719,12 @@ var traceSelectorAtoms = (directDependencyKey, covered, store) => {
|
|
|
860
719
|
}
|
|
861
720
|
return rootKeys;
|
|
862
721
|
};
|
|
863
|
-
var traceAllSelectorAtoms = (
|
|
864
|
-
const selectorKey =
|
|
722
|
+
var traceAllSelectorAtoms = (selector2, store) => {
|
|
723
|
+
const selectorKey = selector2.key;
|
|
865
724
|
const directDependencyKeys = getSelectorDependencyKeys(selectorKey, store);
|
|
866
725
|
const covered = /* @__PURE__ */ new Set();
|
|
867
726
|
return directDependencyKeys.flatMap(
|
|
868
|
-
(depKey) => isAtomKey(
|
|
727
|
+
(depKey) => isAtomKey(store, depKey) ? depKey : traceSelectorAtoms(depKey, covered, store)
|
|
869
728
|
);
|
|
870
729
|
};
|
|
871
730
|
|
|
@@ -912,8 +771,8 @@ var registerSelector = (selectorKey, covered, store) => ({
|
|
|
912
771
|
} else {
|
|
913
772
|
[dependency] = params;
|
|
914
773
|
}
|
|
915
|
-
const dependencyState = withdraw(
|
|
916
|
-
const dependencyValue = readOrComputeValue(
|
|
774
|
+
const dependencyState = withdraw(store, dependency);
|
|
775
|
+
const dependencyValue = readOrComputeValue(store, dependencyState);
|
|
917
776
|
store.logger.info(
|
|
918
777
|
`\u{1F50C}`,
|
|
919
778
|
`selector`,
|
|
@@ -947,11 +806,10 @@ var registerSelector = (selectorKey, covered, store) => ({
|
|
|
947
806
|
token = findInStore(store, family, key);
|
|
948
807
|
}
|
|
949
808
|
const target = newest(store);
|
|
950
|
-
const state = withdraw(
|
|
951
|
-
setAtomOrSelector(state, value
|
|
809
|
+
const state = withdraw(target, token);
|
|
810
|
+
setAtomOrSelector(target, state, value);
|
|
952
811
|
},
|
|
953
812
|
find: (token, key) => findInStore(store, token, key),
|
|
954
|
-
seek: (token, key) => seekInStore(store, token, key),
|
|
955
813
|
json: (token) => getJsonToken(store, token)
|
|
956
814
|
});
|
|
957
815
|
|
|
@@ -960,14 +818,10 @@ var createReadonlySelector = (store, options, family) => {
|
|
|
960
818
|
const target = newest(store);
|
|
961
819
|
const subject = new Subject();
|
|
962
820
|
const covered = /* @__PURE__ */ new Set();
|
|
963
|
-
const { get, find,
|
|
964
|
-
options.key,
|
|
965
|
-
covered,
|
|
966
|
-
target
|
|
967
|
-
);
|
|
821
|
+
const { get, find, json } = registerSelector(options.key, covered, target);
|
|
968
822
|
const getSelf = () => {
|
|
969
|
-
const value = options.get({ get, find,
|
|
970
|
-
cacheValue(options.key, value, subject
|
|
823
|
+
const value = options.get({ get, find, json });
|
|
824
|
+
cacheValue(newest(store), options.key, value, subject);
|
|
971
825
|
covered.clear();
|
|
972
826
|
return value;
|
|
973
827
|
};
|
|
@@ -1004,11 +858,11 @@ var createWritableSelector = (store, options, family) => {
|
|
|
1004
858
|
const subject = new Subject();
|
|
1005
859
|
const covered = /* @__PURE__ */ new Set();
|
|
1006
860
|
const setterToolkit = registerSelector(options.key, covered, target);
|
|
1007
|
-
const { find, get,
|
|
1008
|
-
const getterToolkit = { find, get,
|
|
861
|
+
const { find, get, json } = setterToolkit;
|
|
862
|
+
const getterToolkit = { find, get, json };
|
|
1009
863
|
const getSelf = (getFn = options.get, innerTarget = newest(store)) => {
|
|
1010
864
|
const value = getFn(getterToolkit);
|
|
1011
|
-
cacheValue(options.key, value, subject
|
|
865
|
+
cacheValue(innerTarget, options.key, value, subject);
|
|
1012
866
|
covered.clear();
|
|
1013
867
|
return value;
|
|
1014
868
|
};
|
|
@@ -1026,7 +880,7 @@ var createWritableSelector = (store, options, family) => {
|
|
|
1026
880
|
newValue,
|
|
1027
881
|
`)`
|
|
1028
882
|
);
|
|
1029
|
-
cacheValue(options.key, newValue, subject
|
|
883
|
+
cacheValue(innerTarget, options.key, newValue, subject);
|
|
1030
884
|
markDone(innerTarget, options.key);
|
|
1031
885
|
if (isRootStore(innerTarget)) {
|
|
1032
886
|
subject.next({ newValue, oldValue });
|
|
@@ -1059,21 +913,21 @@ var createWritableSelector = (store, options, family) => {
|
|
|
1059
913
|
function createStandaloneSelector(store, options) {
|
|
1060
914
|
const isWritable = `set` in options;
|
|
1061
915
|
if (isWritable) {
|
|
1062
|
-
const state2 = createWritableSelector(store, options,
|
|
916
|
+
const state2 = createWritableSelector(store, options, void 0);
|
|
1063
917
|
store.on.selectorCreation.next(state2);
|
|
1064
918
|
return state2;
|
|
1065
919
|
}
|
|
1066
|
-
const state = createReadonlySelector(store, options,
|
|
920
|
+
const state = createReadonlySelector(store, options, void 0);
|
|
1067
921
|
store.on.selectorCreation.next(state);
|
|
1068
922
|
return state;
|
|
1069
923
|
}
|
|
1070
924
|
|
|
1071
925
|
// internal/src/selector/dispose-selector.ts
|
|
1072
|
-
function disposeSelector(
|
|
926
|
+
function disposeSelector(store, selectorToken) {
|
|
1073
927
|
const target = newest(store);
|
|
1074
928
|
const { key } = selectorToken;
|
|
1075
|
-
const
|
|
1076
|
-
if (!
|
|
929
|
+
const selector2 = withdraw(target, selectorToken);
|
|
930
|
+
if (!selector2.family) {
|
|
1077
931
|
store.logger.error(
|
|
1078
932
|
`\u274C`,
|
|
1079
933
|
`selector`,
|
|
@@ -1081,27 +935,35 @@ function disposeSelector(selectorToken, store) {
|
|
|
1081
935
|
`Standalone selectors cannot be disposed.`
|
|
1082
936
|
);
|
|
1083
937
|
} else {
|
|
1084
|
-
const molecule = target.molecules.get(
|
|
938
|
+
const molecule = target.molecules.get(selector2.family.subKey);
|
|
1085
939
|
if (molecule) {
|
|
1086
|
-
target.moleculeData.delete(
|
|
940
|
+
target.moleculeData.delete(selector2.family.subKey, selector2.family.key);
|
|
1087
941
|
}
|
|
942
|
+
let familyToken;
|
|
1088
943
|
switch (selectorToken.type) {
|
|
1089
944
|
case `selector`:
|
|
1090
945
|
{
|
|
1091
946
|
target.selectors.delete(key);
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
947
|
+
familyToken = {
|
|
948
|
+
key: selector2.family.key,
|
|
949
|
+
type: `selector_family`
|
|
950
|
+
};
|
|
951
|
+
const family = withdraw(store, familyToken);
|
|
952
|
+
family.subject.next({
|
|
953
|
+
type: `state_disposal`,
|
|
954
|
+
subType: `selector`,
|
|
955
|
+
token: selectorToken
|
|
956
|
+
});
|
|
1096
957
|
}
|
|
1097
958
|
break;
|
|
1098
959
|
case `readonly_selector`:
|
|
1099
960
|
{
|
|
1100
961
|
target.readonlySelectors.delete(key);
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
962
|
+
familyToken = {
|
|
963
|
+
key: selector2.family.key,
|
|
964
|
+
type: `readonly_selector_family`
|
|
965
|
+
};
|
|
966
|
+
const family = withdraw(store, familyToken);
|
|
1105
967
|
family.subject.next({
|
|
1106
968
|
type: `state_disposal`,
|
|
1107
969
|
subType: `selector`,
|
|
@@ -1167,9 +1029,8 @@ function createReadonlySelectorFamily(store, options, internalRoles) {
|
|
|
1167
1029
|
default: (key) => {
|
|
1168
1030
|
const getFn = options.get(key);
|
|
1169
1031
|
return getFn({
|
|
1170
|
-
get: (...
|
|
1171
|
-
find: (
|
|
1172
|
-
seek: (token, k) => seekInStore(store, token, k),
|
|
1032
|
+
get: (...args) => getFromStore(store, ...args),
|
|
1033
|
+
find: (...args) => findInStore(store, ...args),
|
|
1173
1034
|
json: (token) => getJsonToken(store, token)
|
|
1174
1035
|
});
|
|
1175
1036
|
}
|
|
@@ -1177,6 +1038,8 @@ function createReadonlySelectorFamily(store, options, internalRoles) {
|
|
|
1177
1038
|
store.families.set(options.key, readonlySelectorFamily);
|
|
1178
1039
|
return familyToken;
|
|
1179
1040
|
}
|
|
1041
|
+
|
|
1042
|
+
// internal/src/families/create-writable-selector-family.ts
|
|
1180
1043
|
function createWritableSelectorFamily(store, options, internalRoles) {
|
|
1181
1044
|
const familyToken = {
|
|
1182
1045
|
key: options.key,
|
|
@@ -1211,7 +1074,7 @@ function createWritableSelectorFamily(store, options, internalRoles) {
|
|
|
1211
1074
|
subject.next({ type: `state_creation`, token });
|
|
1212
1075
|
return token;
|
|
1213
1076
|
};
|
|
1214
|
-
const
|
|
1077
|
+
const selectorFamily2 = Object.assign(familyFunction, familyToken, {
|
|
1215
1078
|
internalRoles,
|
|
1216
1079
|
subject,
|
|
1217
1080
|
install: (s) => createWritableSelectorFamily(s, options),
|
|
@@ -1220,12 +1083,11 @@ function createWritableSelectorFamily(store, options, internalRoles) {
|
|
|
1220
1083
|
return getFn({
|
|
1221
1084
|
get: (...ps) => getFromStore(store, ...ps),
|
|
1222
1085
|
find: (token, k) => findInStore(store, token, k),
|
|
1223
|
-
seek: (token, k) => seekInStore(store, token, k),
|
|
1224
1086
|
json: (token) => getJsonToken(store, token)
|
|
1225
1087
|
});
|
|
1226
1088
|
}
|
|
1227
1089
|
});
|
|
1228
|
-
store.families.set(options.key,
|
|
1090
|
+
store.families.set(options.key, selectorFamily2);
|
|
1229
1091
|
return familyToken;
|
|
1230
1092
|
}
|
|
1231
1093
|
|
|
@@ -1241,7 +1103,7 @@ function createSelectorFamily(store, options) {
|
|
|
1241
1103
|
// internal/src/families/init-family-member.ts
|
|
1242
1104
|
function initFamilyMemberInStore(store, token, key) {
|
|
1243
1105
|
const family = store.families.get(token.key);
|
|
1244
|
-
if (family ===
|
|
1106
|
+
if (family === void 0) {
|
|
1245
1107
|
throw new NotFoundError(token, store);
|
|
1246
1108
|
}
|
|
1247
1109
|
const state = family(key);
|
|
@@ -1267,6 +1129,8 @@ function initFamilyMemberInStore(store, token, key) {
|
|
|
1267
1129
|
}
|
|
1268
1130
|
return state;
|
|
1269
1131
|
}
|
|
1132
|
+
|
|
1133
|
+
// internal/src/families/seek-in-store.ts
|
|
1270
1134
|
function seekInStore(store, token, key) {
|
|
1271
1135
|
const subKey = stringifyJson(key);
|
|
1272
1136
|
const fullKey = `${token.key}(${subKey})`;
|
|
@@ -1328,27 +1192,24 @@ function disposeFromStore(store, ...params) {
|
|
|
1328
1192
|
token = maybeToken;
|
|
1329
1193
|
}
|
|
1330
1194
|
try {
|
|
1331
|
-
withdraw(
|
|
1195
|
+
withdraw(store, token);
|
|
1332
1196
|
} catch (thrown) {
|
|
1333
1197
|
store.logger.error(
|
|
1334
1198
|
`\u274C`,
|
|
1335
1199
|
token.type,
|
|
1336
1200
|
token.key,
|
|
1337
1201
|
`could not be disposed because it was not found in the store "${store.config.name}".`
|
|
1338
|
-
// disposal
|
|
1339
|
-
// ? `\n This state was most recently disposed\n${disposal.trace}`
|
|
1340
|
-
// : `No previous disposal trace was found.`,
|
|
1341
1202
|
);
|
|
1342
1203
|
return;
|
|
1343
1204
|
}
|
|
1344
1205
|
switch (token.type) {
|
|
1345
1206
|
case `atom`:
|
|
1346
1207
|
case `mutable_atom`:
|
|
1347
|
-
disposeAtom(
|
|
1208
|
+
disposeAtom(store, token);
|
|
1348
1209
|
break;
|
|
1349
1210
|
case `selector`:
|
|
1350
1211
|
case `readonly_selector`:
|
|
1351
|
-
disposeSelector(
|
|
1212
|
+
disposeSelector(store, token);
|
|
1352
1213
|
break;
|
|
1353
1214
|
}
|
|
1354
1215
|
}
|
|
@@ -1415,8 +1276,8 @@ ${disposal.trace}` : `No previous disposal trace was found.`
|
|
|
1415
1276
|
);
|
|
1416
1277
|
return;
|
|
1417
1278
|
}
|
|
1418
|
-
const state = withdraw(
|
|
1419
|
-
setAtomOrSelector(state, value
|
|
1279
|
+
const state = withdraw(store, token);
|
|
1280
|
+
setAtomOrSelector(store, state, value);
|
|
1420
1281
|
closeOperation(store);
|
|
1421
1282
|
}
|
|
1422
1283
|
|
|
@@ -1543,10 +1404,10 @@ ${disposal.trace}` : `No previous disposal trace for ${stringKey} was found.`
|
|
|
1543
1404
|
);
|
|
1544
1405
|
if (joinKeys) {
|
|
1545
1406
|
for (const joinKey of joinKeys) {
|
|
1546
|
-
const
|
|
1547
|
-
if (
|
|
1548
|
-
|
|
1549
|
-
|
|
1407
|
+
const join2 = store.joins.get(joinKey);
|
|
1408
|
+
if (join2) {
|
|
1409
|
+
join2.relations.delete(molecule.key);
|
|
1410
|
+
join2.molecules.delete(molecule.stringKey);
|
|
1550
1411
|
}
|
|
1551
1412
|
}
|
|
1552
1413
|
}
|
|
@@ -1787,146 +1648,459 @@ function ingestTransactionUpdate(applying, transactionUpdate, store) {
|
|
|
1787
1648
|
case `molecule_disposal`:
|
|
1788
1649
|
ingestMoleculeDisposalEvent(updateFromTransaction, applying, store);
|
|
1789
1650
|
break;
|
|
1790
|
-
case `molecule_transfer`:
|
|
1791
|
-
ingestMoleculeTransferEvent(updateFromTransaction, applying, store);
|
|
1651
|
+
case `molecule_transfer`:
|
|
1652
|
+
ingestMoleculeTransferEvent(updateFromTransaction, applying, store);
|
|
1653
|
+
break;
|
|
1654
|
+
case `transaction_update`:
|
|
1655
|
+
ingestTransactionUpdate(applying, updateFromTransaction, store);
|
|
1656
|
+
break;
|
|
1657
|
+
}
|
|
1658
|
+
}
|
|
1659
|
+
}
|
|
1660
|
+
|
|
1661
|
+
// internal/src/transaction/set-epoch-number.ts
|
|
1662
|
+
function setEpochNumberOfContinuity(store, continuityKey, newEpoch) {
|
|
1663
|
+
const isRoot = isRootStore(store);
|
|
1664
|
+
if (isRoot && continuityKey) {
|
|
1665
|
+
store.transactionMeta.epoch.set(continuityKey, newEpoch);
|
|
1666
|
+
}
|
|
1667
|
+
}
|
|
1668
|
+
function setEpochNumberOfAction(store, transactionKey, newEpoch) {
|
|
1669
|
+
const isRoot = isRootStore(store);
|
|
1670
|
+
if (!isRoot) {
|
|
1671
|
+
return;
|
|
1672
|
+
}
|
|
1673
|
+
const continuityKey = store.transactionMeta.actionContinuities.getRelatedKey(transactionKey);
|
|
1674
|
+
if (continuityKey !== void 0) {
|
|
1675
|
+
store.transactionMeta.epoch.set(continuityKey, newEpoch);
|
|
1676
|
+
}
|
|
1677
|
+
}
|
|
1678
|
+
|
|
1679
|
+
// internal/src/transaction/apply-transaction.ts
|
|
1680
|
+
var applyTransaction = (output, store) => {
|
|
1681
|
+
const child = newest(store);
|
|
1682
|
+
const { parent } = child;
|
|
1683
|
+
if (parent === null || !isChildStore(child) || child.transactionMeta?.phase !== `building`) {
|
|
1684
|
+
store.logger.warn(
|
|
1685
|
+
`\u{1F41E}`,
|
|
1686
|
+
`transaction`,
|
|
1687
|
+
`???`,
|
|
1688
|
+
`applyTransaction called outside of a transaction. This is probably a bug in AtomIO.`
|
|
1689
|
+
);
|
|
1690
|
+
return;
|
|
1691
|
+
}
|
|
1692
|
+
child.transactionMeta.phase = `applying`;
|
|
1693
|
+
child.transactionMeta.update.output = output;
|
|
1694
|
+
parent.child = null;
|
|
1695
|
+
parent.on.transactionApplying.next(child.transactionMeta);
|
|
1696
|
+
const { updates } = child.transactionMeta.update;
|
|
1697
|
+
store.logger.info(
|
|
1698
|
+
`\u{1F6C4}`,
|
|
1699
|
+
`transaction`,
|
|
1700
|
+
child.transactionMeta.update.key,
|
|
1701
|
+
`Applying transaction with ${updates.length} updates:`,
|
|
1702
|
+
updates
|
|
1703
|
+
);
|
|
1704
|
+
ingestTransactionUpdate(`newValue`, child.transactionMeta.update, parent);
|
|
1705
|
+
if (isRootStore(parent)) {
|
|
1706
|
+
setEpochNumberOfAction(
|
|
1707
|
+
parent,
|
|
1708
|
+
child.transactionMeta.update.key,
|
|
1709
|
+
child.transactionMeta.update.epoch
|
|
1710
|
+
);
|
|
1711
|
+
const myTransaction = withdraw(store, {
|
|
1712
|
+
key: child.transactionMeta.update.key,
|
|
1713
|
+
type: `transaction`
|
|
1714
|
+
});
|
|
1715
|
+
myTransaction?.subject.next(child.transactionMeta.update);
|
|
1716
|
+
store.logger.info(
|
|
1717
|
+
`\u{1F6EC}`,
|
|
1718
|
+
`transaction`,
|
|
1719
|
+
child.transactionMeta.update.key,
|
|
1720
|
+
`Finished applying transaction.`
|
|
1721
|
+
);
|
|
1722
|
+
} else if (isChildStore(parent)) {
|
|
1723
|
+
parent.transactionMeta.update.updates.push(child.transactionMeta.update);
|
|
1724
|
+
}
|
|
1725
|
+
parent.on.transactionApplying.next(null);
|
|
1726
|
+
};
|
|
1727
|
+
|
|
1728
|
+
// internal/src/transaction/assign-transaction-to-continuity.ts
|
|
1729
|
+
function assignTransactionToContinuity(store, continuityKey, transactionKey) {
|
|
1730
|
+
const isRoot = isRootStore(store);
|
|
1731
|
+
if (!isRoot) {
|
|
1732
|
+
return;
|
|
1733
|
+
}
|
|
1734
|
+
const { epoch, actionContinuities } = store.transactionMeta;
|
|
1735
|
+
actionContinuities.set(continuityKey, transactionKey);
|
|
1736
|
+
if (!epoch.has(continuityKey)) {
|
|
1737
|
+
epoch.set(continuityKey, -1);
|
|
1738
|
+
}
|
|
1739
|
+
}
|
|
1740
|
+
|
|
1741
|
+
// internal/src/get-environment-data.ts
|
|
1742
|
+
function getEnvironmentData(store) {
|
|
1743
|
+
return {
|
|
1744
|
+
store
|
|
1745
|
+
};
|
|
1746
|
+
}
|
|
1747
|
+
|
|
1748
|
+
// internal/src/get-state/get-from-store.ts
|
|
1749
|
+
function getFromStore(store, ...params) {
|
|
1750
|
+
let token;
|
|
1751
|
+
let family;
|
|
1752
|
+
let key;
|
|
1753
|
+
if (params.length === 1) {
|
|
1754
|
+
token = params[0];
|
|
1755
|
+
} else {
|
|
1756
|
+
family = params[0];
|
|
1757
|
+
key = params[1];
|
|
1758
|
+
token = findInStore(store, family, key);
|
|
1759
|
+
}
|
|
1760
|
+
if (`counterfeit` in token && `family` in token) {
|
|
1761
|
+
family = store.families.get(token.family.key);
|
|
1762
|
+
const subKey = token.family.subKey;
|
|
1763
|
+
const disposal = store.disposalTraces.buffer.find(
|
|
1764
|
+
(item) => item?.key === subKey
|
|
1765
|
+
);
|
|
1766
|
+
store.logger.error(
|
|
1767
|
+
`\u274C`,
|
|
1768
|
+
token.type,
|
|
1769
|
+
token.key,
|
|
1770
|
+
`could not be retrieved because it was not found in the store "${store.config.name}".`,
|
|
1771
|
+
disposal ? `This state was previously disposed:
|
|
1772
|
+
${disposal.trace}` : `No previous disposal trace was found.`
|
|
1773
|
+
);
|
|
1774
|
+
switch (family.type) {
|
|
1775
|
+
case `atom_family`:
|
|
1776
|
+
case `mutable_atom_family`:
|
|
1777
|
+
return store.defaults.get(family.key);
|
|
1778
|
+
case `selector_family`:
|
|
1779
|
+
case `readonly_selector_family`: {
|
|
1780
|
+
if (store.defaults.has(family.key)) {
|
|
1781
|
+
return store.defaults.get(token.family.key);
|
|
1782
|
+
}
|
|
1783
|
+
const defaultValue = withdraw(store, family).default(subKey);
|
|
1784
|
+
store.defaults.set(family.key, defaultValue);
|
|
1785
|
+
return defaultValue;
|
|
1786
|
+
}
|
|
1787
|
+
}
|
|
1788
|
+
}
|
|
1789
|
+
return readOrComputeValue(store, withdraw(store, token));
|
|
1790
|
+
}
|
|
1791
|
+
|
|
1792
|
+
// internal/src/junction.ts
|
|
1793
|
+
var Junction = class {
|
|
1794
|
+
a;
|
|
1795
|
+
b;
|
|
1796
|
+
cardinality;
|
|
1797
|
+
relations = /* @__PURE__ */ new Map();
|
|
1798
|
+
contents = /* @__PURE__ */ new Map();
|
|
1799
|
+
isAType;
|
|
1800
|
+
isBType;
|
|
1801
|
+
isContent;
|
|
1802
|
+
makeContentKey = (a, b) => `${a}:${b}`;
|
|
1803
|
+
warn;
|
|
1804
|
+
getRelatedKeys(key) {
|
|
1805
|
+
return this.relations.get(key);
|
|
1806
|
+
}
|
|
1807
|
+
addRelation(a, b) {
|
|
1808
|
+
let aRelations = this.relations.get(a);
|
|
1809
|
+
let bRelations = this.relations.get(b);
|
|
1810
|
+
if (aRelations) {
|
|
1811
|
+
aRelations.add(b);
|
|
1812
|
+
} else {
|
|
1813
|
+
aRelations = /* @__PURE__ */ new Set([b]);
|
|
1814
|
+
this.relations.set(a, aRelations);
|
|
1815
|
+
}
|
|
1816
|
+
if (bRelations) {
|
|
1817
|
+
bRelations.add(a);
|
|
1818
|
+
} else {
|
|
1819
|
+
bRelations = /* @__PURE__ */ new Set([a]);
|
|
1820
|
+
this.relations.set(b, bRelations);
|
|
1821
|
+
}
|
|
1822
|
+
}
|
|
1823
|
+
deleteRelation(a, b) {
|
|
1824
|
+
const aRelations = this.relations.get(a);
|
|
1825
|
+
if (aRelations) {
|
|
1826
|
+
aRelations.delete(b);
|
|
1827
|
+
if (aRelations.size === 0) {
|
|
1828
|
+
this.relations.delete(a);
|
|
1829
|
+
}
|
|
1830
|
+
const bRelations = this.relations.get(b);
|
|
1831
|
+
if (bRelations) {
|
|
1832
|
+
bRelations.delete(a);
|
|
1833
|
+
if (bRelations.size === 0) {
|
|
1834
|
+
this.relations.delete(b);
|
|
1835
|
+
}
|
|
1836
|
+
}
|
|
1837
|
+
}
|
|
1838
|
+
}
|
|
1839
|
+
replaceRelationsUnsafely(x, ys) {
|
|
1840
|
+
this.relations.set(x, new Set(ys));
|
|
1841
|
+
for (const y of ys) {
|
|
1842
|
+
const yRelations = (/* @__PURE__ */ new Set()).add(x);
|
|
1843
|
+
this.relations.set(y, yRelations);
|
|
1844
|
+
}
|
|
1845
|
+
}
|
|
1846
|
+
replaceRelationsSafely(x, ys) {
|
|
1847
|
+
const xRelationsPrev = this.relations.get(x);
|
|
1848
|
+
let a = this.isAType?.(x) ? x : void 0;
|
|
1849
|
+
let b = a === void 0 ? x : void 0;
|
|
1850
|
+
if (xRelationsPrev) {
|
|
1851
|
+
for (const y of xRelationsPrev) {
|
|
1852
|
+
a ??= y;
|
|
1853
|
+
b ??= y;
|
|
1854
|
+
const yRelations = this.relations.get(y);
|
|
1855
|
+
if (yRelations) {
|
|
1856
|
+
if (yRelations.size === 1) {
|
|
1857
|
+
this.relations.delete(y);
|
|
1858
|
+
} else {
|
|
1859
|
+
yRelations.delete(x);
|
|
1860
|
+
}
|
|
1861
|
+
this.contents.delete(this.makeContentKey(a, b));
|
|
1862
|
+
}
|
|
1863
|
+
}
|
|
1864
|
+
}
|
|
1865
|
+
this.relations.set(x, new Set(ys));
|
|
1866
|
+
for (const y of ys) {
|
|
1867
|
+
let yRelations = this.relations.get(y);
|
|
1868
|
+
if (yRelations) {
|
|
1869
|
+
yRelations.add(x);
|
|
1870
|
+
} else {
|
|
1871
|
+
yRelations = (/* @__PURE__ */ new Set()).add(x);
|
|
1872
|
+
this.relations.set(y, yRelations);
|
|
1873
|
+
}
|
|
1874
|
+
}
|
|
1875
|
+
}
|
|
1876
|
+
getContentInternal(contentKey) {
|
|
1877
|
+
return this.contents.get(contentKey);
|
|
1878
|
+
}
|
|
1879
|
+
setContent(contentKey, content) {
|
|
1880
|
+
this.contents.set(contentKey, content);
|
|
1881
|
+
}
|
|
1882
|
+
deleteContent(contentKey) {
|
|
1883
|
+
this.contents.delete(contentKey);
|
|
1884
|
+
}
|
|
1885
|
+
constructor(data, config) {
|
|
1886
|
+
this.a = data.between[0];
|
|
1887
|
+
this.b = data.between[1];
|
|
1888
|
+
this.cardinality = data.cardinality;
|
|
1889
|
+
if (!config?.externalStore) {
|
|
1890
|
+
this.relations = new Map(
|
|
1891
|
+
data.relations?.map(([x, ys]) => [x, new Set(ys)])
|
|
1892
|
+
);
|
|
1893
|
+
this.contents = new Map(data.contents);
|
|
1894
|
+
}
|
|
1895
|
+
this.isAType = config?.isAType ?? null;
|
|
1896
|
+
this.isBType = config?.isBType ?? null;
|
|
1897
|
+
this.isContent = config?.isContent ?? null;
|
|
1898
|
+
if (config?.makeContentKey) {
|
|
1899
|
+
this.makeContentKey = config.makeContentKey;
|
|
1900
|
+
}
|
|
1901
|
+
if (config?.externalStore) {
|
|
1902
|
+
const externalStore = config.externalStore;
|
|
1903
|
+
this.has = (a, b) => externalStore.has(a, b);
|
|
1904
|
+
this.addRelation = (a, b) => {
|
|
1905
|
+
externalStore.addRelation(a, b);
|
|
1906
|
+
};
|
|
1907
|
+
this.deleteRelation = (a, b) => {
|
|
1908
|
+
externalStore.deleteRelation(a, b);
|
|
1909
|
+
};
|
|
1910
|
+
this.replaceRelationsSafely = (a, bs) => {
|
|
1911
|
+
externalStore.replaceRelationsSafely(a, bs);
|
|
1912
|
+
};
|
|
1913
|
+
this.replaceRelationsUnsafely = (a, bs) => {
|
|
1914
|
+
externalStore.replaceRelationsUnsafely(a, bs);
|
|
1915
|
+
};
|
|
1916
|
+
this.getRelatedKeys = (key) => externalStore.getRelatedKeys(
|
|
1917
|
+
key
|
|
1918
|
+
);
|
|
1919
|
+
if (externalStore.getContent) {
|
|
1920
|
+
this.getContentInternal = (contentKey) => {
|
|
1921
|
+
return externalStore.getContent(contentKey);
|
|
1922
|
+
};
|
|
1923
|
+
this.setContent = (contentKey, content) => {
|
|
1924
|
+
externalStore.setContent(contentKey, content);
|
|
1925
|
+
};
|
|
1926
|
+
this.deleteContent = (contentKey) => {
|
|
1927
|
+
externalStore.deleteContent(contentKey);
|
|
1928
|
+
};
|
|
1929
|
+
}
|
|
1930
|
+
for (const [x, ys] of data.relations ?? []) {
|
|
1931
|
+
let a = this.isAType?.(x) ? x : void 0;
|
|
1932
|
+
let b = a === void 0 ? x : void 0;
|
|
1933
|
+
for (const y of ys) {
|
|
1934
|
+
a ??= y;
|
|
1935
|
+
b ??= y;
|
|
1936
|
+
this.addRelation(a, b);
|
|
1937
|
+
}
|
|
1938
|
+
}
|
|
1939
|
+
for (const [contentKey, content] of data.contents ?? []) {
|
|
1940
|
+
this.setContent(contentKey, content);
|
|
1941
|
+
}
|
|
1942
|
+
}
|
|
1943
|
+
if (config?.warn) {
|
|
1944
|
+
this.warn = config.warn;
|
|
1945
|
+
}
|
|
1946
|
+
}
|
|
1947
|
+
toJSON() {
|
|
1948
|
+
return {
|
|
1949
|
+
between: [this.a, this.b],
|
|
1950
|
+
cardinality: this.cardinality,
|
|
1951
|
+
relations: [...this.relations.entries()].map(
|
|
1952
|
+
([a, b]) => [a, [...b]]
|
|
1953
|
+
),
|
|
1954
|
+
contents: [...this.contents.entries()]
|
|
1955
|
+
};
|
|
1956
|
+
}
|
|
1957
|
+
set(...params) {
|
|
1958
|
+
let a;
|
|
1959
|
+
let b;
|
|
1960
|
+
let content;
|
|
1961
|
+
switch (params.length) {
|
|
1962
|
+
case 1: {
|
|
1963
|
+
const relation = params[0];
|
|
1964
|
+
a = relation[this.a];
|
|
1965
|
+
b = relation[this.b];
|
|
1966
|
+
content = void 0;
|
|
1967
|
+
break;
|
|
1968
|
+
}
|
|
1969
|
+
case 2: {
|
|
1970
|
+
const zeroth = params[0];
|
|
1971
|
+
if (typeof zeroth === `string`) {
|
|
1972
|
+
[a, b] = params;
|
|
1973
|
+
} else {
|
|
1974
|
+
a = zeroth[this.a];
|
|
1975
|
+
b = zeroth[this.b];
|
|
1976
|
+
content = params[1];
|
|
1977
|
+
}
|
|
1978
|
+
break;
|
|
1979
|
+
}
|
|
1980
|
+
default: {
|
|
1981
|
+
a = params[0];
|
|
1982
|
+
b = params[1];
|
|
1983
|
+
content = params[2];
|
|
1792
1984
|
break;
|
|
1793
|
-
|
|
1794
|
-
|
|
1985
|
+
}
|
|
1986
|
+
}
|
|
1987
|
+
switch (this.cardinality) {
|
|
1988
|
+
// biome-ignore lint/suspicious/noFallthroughSwitchClause: perfect here
|
|
1989
|
+
case `1:1`: {
|
|
1990
|
+
const bPrev = this.getRelatedKey(a);
|
|
1991
|
+
if (bPrev && bPrev !== b) this.delete(a, bPrev);
|
|
1992
|
+
}
|
|
1993
|
+
case `1:n`:
|
|
1994
|
+
{
|
|
1995
|
+
const aPrev = this.getRelatedKey(b);
|
|
1996
|
+
if (aPrev && aPrev !== a) this.delete(aPrev, b);
|
|
1997
|
+
}
|
|
1795
1998
|
break;
|
|
1796
1999
|
}
|
|
2000
|
+
if (content) {
|
|
2001
|
+
const contentKey = this.makeContentKey(a, b);
|
|
2002
|
+
this.setContent(contentKey, content);
|
|
2003
|
+
}
|
|
2004
|
+
this.addRelation(a, b);
|
|
2005
|
+
return this;
|
|
1797
2006
|
}
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
if (isRoot && continuityKey) {
|
|
1804
|
-
store.transactionMeta.epoch.set(continuityKey, newEpoch);
|
|
1805
|
-
}
|
|
1806
|
-
}
|
|
1807
|
-
function setEpochNumberOfAction(transactionKey, newEpoch, store) {
|
|
1808
|
-
const isRoot = isRootStore(store);
|
|
1809
|
-
if (!isRoot) {
|
|
1810
|
-
return;
|
|
1811
|
-
}
|
|
1812
|
-
const continuityKey = store.transactionMeta.actionContinuities.getRelatedKey(transactionKey);
|
|
1813
|
-
if (continuityKey !== undefined) {
|
|
1814
|
-
store.transactionMeta.epoch.set(continuityKey, newEpoch);
|
|
1815
|
-
}
|
|
1816
|
-
}
|
|
1817
|
-
|
|
1818
|
-
// internal/src/transaction/apply-transaction.ts
|
|
1819
|
-
var applyTransaction = (output, store) => {
|
|
1820
|
-
const child = newest(store);
|
|
1821
|
-
const { parent } = child;
|
|
1822
|
-
if (parent === null || !isChildStore(child) || child.transactionMeta?.phase !== `building`) {
|
|
1823
|
-
store.logger.warn(
|
|
1824
|
-
`\u{1F41E}`,
|
|
1825
|
-
`transaction`,
|
|
1826
|
-
`???`,
|
|
1827
|
-
`applyTransaction called outside of a transaction. This is probably a bug in AtomIO.`
|
|
1828
|
-
);
|
|
1829
|
-
return;
|
|
1830
|
-
}
|
|
1831
|
-
child.transactionMeta.phase = `applying`;
|
|
1832
|
-
child.transactionMeta.update.output = output;
|
|
1833
|
-
parent.child = null;
|
|
1834
|
-
parent.on.transactionApplying.next(child.transactionMeta);
|
|
1835
|
-
const { updates } = child.transactionMeta.update;
|
|
1836
|
-
store.logger.info(
|
|
1837
|
-
`\u{1F6C4}`,
|
|
1838
|
-
`transaction`,
|
|
1839
|
-
child.transactionMeta.update.key,
|
|
1840
|
-
`Applying transaction with ${updates.length} updates:`,
|
|
1841
|
-
updates
|
|
1842
|
-
);
|
|
1843
|
-
ingestTransactionUpdate(`newValue`, child.transactionMeta.update, parent);
|
|
1844
|
-
if (isRootStore(parent)) {
|
|
1845
|
-
setEpochNumberOfAction(
|
|
1846
|
-
child.transactionMeta.update.key,
|
|
1847
|
-
child.transactionMeta.update.epoch,
|
|
1848
|
-
parent
|
|
1849
|
-
);
|
|
1850
|
-
const myTransaction = withdraw(
|
|
1851
|
-
{ key: child.transactionMeta.update.key, type: `transaction` },
|
|
1852
|
-
store
|
|
1853
|
-
);
|
|
1854
|
-
myTransaction?.subject.next(child.transactionMeta.update);
|
|
1855
|
-
store.logger.info(
|
|
1856
|
-
`\u{1F6EC}`,
|
|
1857
|
-
`transaction`,
|
|
1858
|
-
child.transactionMeta.update.key,
|
|
1859
|
-
`Finished applying transaction.`
|
|
2007
|
+
delete(x, b) {
|
|
2008
|
+
b = typeof b === `string` ? b : x[this.b];
|
|
2009
|
+
const a = (
|
|
2010
|
+
// @ts-expect-error we deduce that this.a may index x
|
|
2011
|
+
typeof x === `string` ? x : x[this.a]
|
|
1860
2012
|
);
|
|
1861
|
-
|
|
1862
|
-
|
|
2013
|
+
if (a === void 0 && typeof b === `string`) {
|
|
2014
|
+
const bRelations = this.getRelatedKeys(b);
|
|
2015
|
+
if (bRelations) {
|
|
2016
|
+
for (const bRelation of bRelations) {
|
|
2017
|
+
this.delete(bRelation, b);
|
|
2018
|
+
}
|
|
2019
|
+
}
|
|
2020
|
+
}
|
|
2021
|
+
if (typeof a === `string` && b === void 0) {
|
|
2022
|
+
const aRelations = this.getRelatedKeys(a);
|
|
2023
|
+
if (aRelations) {
|
|
2024
|
+
for (const aRelation of aRelations) {
|
|
2025
|
+
this.delete(a, aRelation);
|
|
2026
|
+
}
|
|
2027
|
+
}
|
|
2028
|
+
}
|
|
2029
|
+
if (typeof a === `string` && typeof b === `string`) {
|
|
2030
|
+
this.deleteRelation(a, b);
|
|
2031
|
+
const contentKey = this.makeContentKey(a, b);
|
|
2032
|
+
this.deleteContent(contentKey);
|
|
2033
|
+
}
|
|
2034
|
+
return this;
|
|
1863
2035
|
}
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
2036
|
+
getRelatedKey(key) {
|
|
2037
|
+
const relations = this.getRelatedKeys(key);
|
|
2038
|
+
if (relations) {
|
|
2039
|
+
if (relations.size > 1) {
|
|
2040
|
+
this.warn?.(
|
|
2041
|
+
`${relations.size} related keys were found for key "${key}": (${[
|
|
2042
|
+
...relations
|
|
2043
|
+
].map((k) => `"${k}"`).join(`, `)}). Only one related key was expected.`
|
|
2044
|
+
);
|
|
2045
|
+
}
|
|
2046
|
+
let singleRelation;
|
|
2047
|
+
for (const relation of relations) {
|
|
2048
|
+
singleRelation = relation;
|
|
2049
|
+
break;
|
|
2050
|
+
}
|
|
2051
|
+
return singleRelation;
|
|
2052
|
+
}
|
|
1872
2053
|
}
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
2054
|
+
replaceRelations(x, relations, config) {
|
|
2055
|
+
const hasContent = !Array.isArray(relations);
|
|
2056
|
+
const ys = hasContent ? Object.keys(relations) : relations;
|
|
2057
|
+
if (config?.reckless) {
|
|
2058
|
+
this.replaceRelationsUnsafely(x, ys);
|
|
2059
|
+
} else {
|
|
2060
|
+
this.replaceRelationsSafely(x, ys);
|
|
2061
|
+
}
|
|
2062
|
+
if (hasContent) {
|
|
2063
|
+
for (const y of ys) {
|
|
2064
|
+
const contentKey = this.makeContentKey(x, y);
|
|
2065
|
+
const content = relations[y];
|
|
2066
|
+
this.setContent(contentKey, content);
|
|
2067
|
+
}
|
|
2068
|
+
}
|
|
2069
|
+
return this;
|
|
1877
2070
|
}
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
function getEnvironmentData(store) {
|
|
1882
|
-
return {
|
|
1883
|
-
store
|
|
1884
|
-
};
|
|
1885
|
-
}
|
|
1886
|
-
|
|
1887
|
-
// internal/src/get-state/get-from-store.ts
|
|
1888
|
-
function getFromStore(store, ...params) {
|
|
1889
|
-
let token;
|
|
1890
|
-
let family;
|
|
1891
|
-
let key;
|
|
1892
|
-
if (params.length === 1) {
|
|
1893
|
-
token = params[0];
|
|
1894
|
-
} else {
|
|
1895
|
-
family = params[0];
|
|
1896
|
-
key = params[1];
|
|
1897
|
-
token = findInStore(store, family, key);
|
|
2071
|
+
getContent(a, b) {
|
|
2072
|
+
const contentKey = this.makeContentKey(a, b);
|
|
2073
|
+
return this.getContentInternal(contentKey);
|
|
1898
2074
|
}
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
const
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
return store.defaults.get(family.key);
|
|
1917
|
-
case `selector_family`:
|
|
1918
|
-
case `readonly_selector_family`: {
|
|
1919
|
-
if (store.defaults.has(family.key)) {
|
|
1920
|
-
return store.defaults.get(token.family.key);
|
|
1921
|
-
}
|
|
1922
|
-
const defaultValue = withdraw(family, store).default(subKey);
|
|
1923
|
-
store.defaults.set(family.key, defaultValue);
|
|
1924
|
-
return defaultValue;
|
|
2075
|
+
getRelationEntries(input) {
|
|
2076
|
+
const a = input[this.a];
|
|
2077
|
+
const b = input[this.b];
|
|
2078
|
+
if (a !== void 0 && b === void 0) {
|
|
2079
|
+
const aRelations = this.getRelatedKeys(a);
|
|
2080
|
+
if (aRelations) {
|
|
2081
|
+
return [...aRelations].map((aRelation) => {
|
|
2082
|
+
return [aRelation, this.getContent(a, aRelation)];
|
|
2083
|
+
});
|
|
2084
|
+
}
|
|
2085
|
+
}
|
|
2086
|
+
if (a === void 0 && b !== void 0) {
|
|
2087
|
+
const bRelations = this.getRelatedKeys(b);
|
|
2088
|
+
if (bRelations) {
|
|
2089
|
+
return [...bRelations].map((bRelation) => {
|
|
2090
|
+
return [bRelation, this.getContent(bRelation, b)];
|
|
2091
|
+
});
|
|
1925
2092
|
}
|
|
1926
2093
|
}
|
|
2094
|
+
return [];
|
|
1927
2095
|
}
|
|
1928
|
-
|
|
1929
|
-
|
|
2096
|
+
has(a, b) {
|
|
2097
|
+
if (b) {
|
|
2098
|
+
const setA = this.getRelatedKeys(a);
|
|
2099
|
+
return setA?.has(b) ?? false;
|
|
2100
|
+
}
|
|
2101
|
+
return this.relations.has(a);
|
|
2102
|
+
}
|
|
2103
|
+
};
|
|
1930
2104
|
|
|
1931
2105
|
// internal/src/lazy-map.ts
|
|
1932
2106
|
var LazyMap = class extends Map {
|
|
@@ -1944,7 +2118,7 @@ var LazyMap = class extends Map {
|
|
|
1944
2118
|
const value = this.source.get(key);
|
|
1945
2119
|
return value;
|
|
1946
2120
|
}
|
|
1947
|
-
return
|
|
2121
|
+
return void 0;
|
|
1948
2122
|
}
|
|
1949
2123
|
set(key, value) {
|
|
1950
2124
|
this.deleted.delete(key);
|
|
@@ -1963,7 +2137,7 @@ var LazyMap = class extends Map {
|
|
|
1963
2137
|
};
|
|
1964
2138
|
|
|
1965
2139
|
// internal/src/transaction/build-transaction.ts
|
|
1966
|
-
var buildTransaction = (key, params,
|
|
2140
|
+
var buildTransaction = (store, key, params, id) => {
|
|
1967
2141
|
const parent = newest(store);
|
|
1968
2142
|
const childBase = {
|
|
1969
2143
|
parent,
|
|
@@ -2002,26 +2176,25 @@ var buildTransaction = (key, params, store, id) => {
|
|
|
2002
2176
|
}),
|
|
2003
2177
|
miscResources: new LazyMap(parent.miscResources)
|
|
2004
2178
|
};
|
|
2005
|
-
const epoch = getEpochNumberOfAction(
|
|
2179
|
+
const epoch = getEpochNumberOfAction(store, key);
|
|
2006
2180
|
const transactionMeta = {
|
|
2007
2181
|
phase: `building`,
|
|
2008
2182
|
update: {
|
|
2009
2183
|
type: `transaction_update`,
|
|
2010
2184
|
key,
|
|
2011
2185
|
id,
|
|
2012
|
-
epoch: epoch ===
|
|
2186
|
+
epoch: epoch === void 0 ? Number.NaN : epoch + 1,
|
|
2013
2187
|
updates: [],
|
|
2014
2188
|
params,
|
|
2015
|
-
output:
|
|
2189
|
+
output: void 0
|
|
2016
2190
|
},
|
|
2017
2191
|
toolkit: {
|
|
2018
2192
|
get: (...ps) => getFromStore(child, ...ps),
|
|
2019
2193
|
set: (...ps) => {
|
|
2020
2194
|
setIntoStore(child, ...ps);
|
|
2021
2195
|
},
|
|
2022
|
-
run: (token, identifier = arbitrary()) => actUponStore(token, identifier
|
|
2196
|
+
run: (token, identifier = arbitrary()) => actUponStore(child, token, identifier),
|
|
2023
2197
|
find: (token, k) => findInStore(child, token, k),
|
|
2024
|
-
seek: (token, k) => seekInStore(child, token, k),
|
|
2025
2198
|
json: (token) => getJsonToken(child, token),
|
|
2026
2199
|
dispose: (...ps) => {
|
|
2027
2200
|
disposeFromStore(child, ...ps);
|
|
@@ -2044,12 +2217,12 @@ var buildTransaction = (key, params, store, id) => {
|
|
|
2044
2217
|
};
|
|
2045
2218
|
|
|
2046
2219
|
// internal/src/transaction/create-transaction.ts
|
|
2047
|
-
function createTransaction(
|
|
2220
|
+
function createTransaction(store, options) {
|
|
2048
2221
|
const newTransaction = {
|
|
2049
2222
|
key: options.key,
|
|
2050
2223
|
type: `transaction`,
|
|
2051
2224
|
run: (params, id) => {
|
|
2052
|
-
const childStore = buildTransaction(options.key, params,
|
|
2225
|
+
const childStore = buildTransaction(store, options.key, params, id);
|
|
2053
2226
|
try {
|
|
2054
2227
|
const target2 = newest(store);
|
|
2055
2228
|
const { toolkit } = childStore.transactionMeta;
|
|
@@ -2062,7 +2235,7 @@ function createTransaction(options, store) {
|
|
|
2062
2235
|
throw thrown;
|
|
2063
2236
|
}
|
|
2064
2237
|
},
|
|
2065
|
-
install: (s) => createTransaction(
|
|
2238
|
+
install: (s) => createTransaction(s, options),
|
|
2066
2239
|
subject: new Subject()
|
|
2067
2240
|
};
|
|
2068
2241
|
const target = newest(store);
|
|
@@ -2072,26 +2245,138 @@ function createTransaction(options, store) {
|
|
|
2072
2245
|
return token;
|
|
2073
2246
|
}
|
|
2074
2247
|
|
|
2075
|
-
// internal/src/transaction/get-epoch-number.ts
|
|
2076
|
-
function getContinuityKey(
|
|
2077
|
-
const isRoot = isRootStore(store);
|
|
2078
|
-
const continuity = isRoot ? store.transactionMeta.actionContinuities.getRelatedKey(transactionKey) :
|
|
2079
|
-
return continuity;
|
|
2248
|
+
// internal/src/transaction/get-epoch-number.ts
|
|
2249
|
+
function getContinuityKey(store, transactionKey) {
|
|
2250
|
+
const isRoot = isRootStore(store);
|
|
2251
|
+
const continuity = isRoot ? store.transactionMeta.actionContinuities.getRelatedKey(transactionKey) : void 0;
|
|
2252
|
+
return continuity;
|
|
2253
|
+
}
|
|
2254
|
+
function getEpochNumberOfContinuity(store, continuityKey) {
|
|
2255
|
+
const isRoot = isRootStore(store);
|
|
2256
|
+
const epoch = isRoot && continuityKey ? store.transactionMeta.epoch.get(continuityKey) : void 0;
|
|
2257
|
+
return epoch;
|
|
2258
|
+
}
|
|
2259
|
+
function getEpochNumberOfAction(store, transactionKey) {
|
|
2260
|
+
const isRoot = isRootStore(store);
|
|
2261
|
+
const continuity = isRoot ? store.transactionMeta.actionContinuities.getRelatedKey(transactionKey) : void 0;
|
|
2262
|
+
const epoch = isRoot && continuity !== void 0 ? store.transactionMeta.epoch.get(continuity) : void 0;
|
|
2263
|
+
return epoch;
|
|
2264
|
+
}
|
|
2265
|
+
|
|
2266
|
+
// internal/src/transaction/index.ts
|
|
2267
|
+
var TRANSACTION_PHASES = [`idle`, `building`, `applying`];
|
|
2268
|
+
|
|
2269
|
+
// internal/src/install-into-store.ts
|
|
2270
|
+
function installIntoStore(tokens, target, source) {
|
|
2271
|
+
const sourceNewest = newest(source);
|
|
2272
|
+
if (isChildStore(sourceNewest)) {
|
|
2273
|
+
source.logger.error(
|
|
2274
|
+
`\u274C`,
|
|
2275
|
+
`transaction`,
|
|
2276
|
+
sourceNewest.transactionMeta.update.key,
|
|
2277
|
+
`could not install the following tokens into store "${target.config.name} from "${source.config.name}":`,
|
|
2278
|
+
tokens,
|
|
2279
|
+
`${sourceNewest.config.name} is undergoing a transaction.`
|
|
2280
|
+
);
|
|
2281
|
+
return;
|
|
2282
|
+
}
|
|
2283
|
+
const targetNewest = newest(target);
|
|
2284
|
+
if (isChildStore(targetNewest)) {
|
|
2285
|
+
target.logger.error(
|
|
2286
|
+
`\u274C`,
|
|
2287
|
+
`transaction`,
|
|
2288
|
+
targetNewest.transactionMeta.update.key,
|
|
2289
|
+
`could not install the following tokens into store "${target.config.name} from "${source.config.name}":`,
|
|
2290
|
+
tokens,
|
|
2291
|
+
`${targetNewest.config.name} is undergoing a transaction.`
|
|
2292
|
+
);
|
|
2293
|
+
return;
|
|
2294
|
+
}
|
|
2295
|
+
for (const token of tokens) {
|
|
2296
|
+
const resource = withdraw(source, token);
|
|
2297
|
+
resource.install(target);
|
|
2298
|
+
}
|
|
2299
|
+
}
|
|
2300
|
+
|
|
2301
|
+
// src/silo.ts
|
|
2302
|
+
var Silo = class {
|
|
2303
|
+
store;
|
|
2304
|
+
atom;
|
|
2305
|
+
atomFamily;
|
|
2306
|
+
selector;
|
|
2307
|
+
selectorFamily;
|
|
2308
|
+
transaction;
|
|
2309
|
+
timeline;
|
|
2310
|
+
findState;
|
|
2311
|
+
getState;
|
|
2312
|
+
setState;
|
|
2313
|
+
disposeState;
|
|
2314
|
+
subscribe;
|
|
2315
|
+
undo;
|
|
2316
|
+
redo;
|
|
2317
|
+
runTransaction;
|
|
2318
|
+
install;
|
|
2319
|
+
constructor(config, fromStore = null) {
|
|
2320
|
+
const s = this.store = new Store(config, fromStore);
|
|
2321
|
+
this.atom = (options) => createStandaloneAtom(s, options);
|
|
2322
|
+
this.atomFamily = (options) => createAtomFamily(s, options);
|
|
2323
|
+
this.selector = (options) => createStandaloneSelector(s, options);
|
|
2324
|
+
this.selectorFamily = (options) => createSelectorFamily(s, options);
|
|
2325
|
+
this.transaction = (options) => createTransaction(s, options);
|
|
2326
|
+
this.timeline = (options) => createTimeline(s, options);
|
|
2327
|
+
this.findState = (...params) => findInStore(s, ...params);
|
|
2328
|
+
this.getState = (...params) => getFromStore(s, ...params);
|
|
2329
|
+
this.setState = (...params) => {
|
|
2330
|
+
setIntoStore(s, ...params);
|
|
2331
|
+
};
|
|
2332
|
+
this.disposeState = (...params) => {
|
|
2333
|
+
disposeFromStore(s, ...params);
|
|
2334
|
+
};
|
|
2335
|
+
this.subscribe = (...params) => subscribeInStore(s, ...params);
|
|
2336
|
+
this.undo = (token) => {
|
|
2337
|
+
timeTravel(s, `undo`, token);
|
|
2338
|
+
};
|
|
2339
|
+
this.redo = (token) => {
|
|
2340
|
+
timeTravel(s, `redo`, token);
|
|
2341
|
+
};
|
|
2342
|
+
this.runTransaction = (token, id = arbitrary()) => actUponStore(s, token, id);
|
|
2343
|
+
this.install = (tokens, source = IMPLICIT.STORE) => {
|
|
2344
|
+
installIntoStore(tokens, s, source);
|
|
2345
|
+
};
|
|
2346
|
+
}
|
|
2347
|
+
};
|
|
2348
|
+
|
|
2349
|
+
// src/subscribe.ts
|
|
2350
|
+
function subscribe(token, handleUpdate, key = arbitrary()) {
|
|
2351
|
+
return subscribeInStore(IMPLICIT.STORE, token, handleUpdate, key);
|
|
2080
2352
|
}
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
return
|
|
2353
|
+
|
|
2354
|
+
// src/timeline.ts
|
|
2355
|
+
var timeline = (options) => {
|
|
2356
|
+
return createTimeline(IMPLICIT.STORE, options);
|
|
2357
|
+
};
|
|
2358
|
+
var redo = (tl) => {
|
|
2359
|
+
timeTravel(IMPLICIT.STORE, `redo`, tl);
|
|
2360
|
+
};
|
|
2361
|
+
var undo = (tl) => {
|
|
2362
|
+
timeTravel(IMPLICIT.STORE, `undo`, tl);
|
|
2363
|
+
};
|
|
2364
|
+
|
|
2365
|
+
// src/transaction.ts
|
|
2366
|
+
function transaction(options) {
|
|
2367
|
+
return createTransaction(IMPLICIT.STORE, options);
|
|
2085
2368
|
}
|
|
2086
|
-
function
|
|
2087
|
-
|
|
2088
|
-
const continuity = isRoot ? store.transactionMeta.actionContinuities.getRelatedKey(transactionKey) : undefined;
|
|
2089
|
-
const epoch = isRoot && continuity !== undefined ? store.transactionMeta.epoch.get(continuity) : undefined;
|
|
2090
|
-
return epoch;
|
|
2369
|
+
function runTransaction(token, id = arbitrary()) {
|
|
2370
|
+
return actUponStore(IMPLICIT.STORE, token, id);
|
|
2091
2371
|
}
|
|
2092
2372
|
|
|
2093
|
-
//
|
|
2094
|
-
|
|
2373
|
+
// src/validators.ts
|
|
2374
|
+
function isToken(knownToken, unknownToken) {
|
|
2375
|
+
return knownToken.key === unknownToken.key;
|
|
2376
|
+
}
|
|
2377
|
+
function belongsTo(family, unknownToken) {
|
|
2378
|
+
return family.key === unknownToken.family?.key;
|
|
2379
|
+
}
|
|
2095
2380
|
|
|
2096
2381
|
// internal/src/store/store.ts
|
|
2097
2382
|
var Store = class {
|
|
@@ -2218,32 +2503,32 @@ var Store = class {
|
|
|
2218
2503
|
family.install(this);
|
|
2219
2504
|
}
|
|
2220
2505
|
const mutableHelpers = /* @__PURE__ */ new Set();
|
|
2221
|
-
for (const [,
|
|
2222
|
-
if (mutableHelpers.has(
|
|
2506
|
+
for (const [, atom2] of store.atoms) {
|
|
2507
|
+
if (mutableHelpers.has(atom2.key)) {
|
|
2223
2508
|
continue;
|
|
2224
2509
|
}
|
|
2225
|
-
|
|
2226
|
-
if (
|
|
2227
|
-
const originalJsonToken = getJsonToken(store,
|
|
2228
|
-
const originalUpdateToken = getUpdateToken(
|
|
2510
|
+
atom2.install(this);
|
|
2511
|
+
if (atom2.type === `mutable_atom`) {
|
|
2512
|
+
const originalJsonToken = getJsonToken(store, atom2);
|
|
2513
|
+
const originalUpdateToken = getUpdateToken(atom2);
|
|
2229
2514
|
mutableHelpers.add(originalJsonToken.key);
|
|
2230
2515
|
mutableHelpers.add(originalUpdateToken.key);
|
|
2231
2516
|
}
|
|
2232
2517
|
}
|
|
2233
|
-
for (const [,
|
|
2234
|
-
|
|
2518
|
+
for (const [, selector2] of store.readonlySelectors) {
|
|
2519
|
+
selector2.install(this);
|
|
2235
2520
|
}
|
|
2236
|
-
for (const [,
|
|
2237
|
-
if (mutableHelpers.has(
|
|
2521
|
+
for (const [, selector2] of store.selectors) {
|
|
2522
|
+
if (mutableHelpers.has(selector2.key)) {
|
|
2238
2523
|
continue;
|
|
2239
2524
|
}
|
|
2240
|
-
|
|
2525
|
+
selector2.install(this);
|
|
2241
2526
|
}
|
|
2242
2527
|
for (const [, tx] of store.transactions) {
|
|
2243
2528
|
tx.install(this);
|
|
2244
2529
|
}
|
|
2245
|
-
for (const [,
|
|
2246
|
-
|
|
2530
|
+
for (const [, timeline2] of store.timelines) {
|
|
2531
|
+
timeline2.install(this);
|
|
2247
2532
|
}
|
|
2248
2533
|
}
|
|
2249
2534
|
}
|
|
@@ -2269,7 +2554,7 @@ var clearStore = (store) => {
|
|
|
2269
2554
|
};
|
|
2270
2555
|
|
|
2271
2556
|
// internal/src/store/withdraw.ts
|
|
2272
|
-
function withdraw(
|
|
2557
|
+
function withdraw(store, token) {
|
|
2273
2558
|
let withdrawn;
|
|
2274
2559
|
let target = store;
|
|
2275
2560
|
while (target !== null) {
|
|
@@ -2306,45 +2591,47 @@ function withdraw(token, store) {
|
|
|
2306
2591
|
}
|
|
2307
2592
|
|
|
2308
2593
|
// internal/src/subscribe/recall-state.ts
|
|
2309
|
-
var recallState = (
|
|
2594
|
+
var recallState = (store, state) => {
|
|
2310
2595
|
const target = newest(store);
|
|
2311
2596
|
if (target.operation.open) {
|
|
2312
2597
|
return target.operation.prev.get(state.key);
|
|
2313
2598
|
}
|
|
2314
2599
|
return target.valueMap.get(state.key);
|
|
2315
2600
|
};
|
|
2316
|
-
|
|
2601
|
+
|
|
2602
|
+
// internal/src/subscribe/subscribe-in-store.ts
|
|
2603
|
+
function subscribeInStore(store, token, handleUpdate, key = arbitrary()) {
|
|
2317
2604
|
switch (token.type) {
|
|
2318
2605
|
case `atom`:
|
|
2319
2606
|
case `mutable_atom`:
|
|
2320
2607
|
case `readonly_selector`:
|
|
2321
2608
|
case `selector`:
|
|
2322
|
-
return subscribeToState(
|
|
2609
|
+
return subscribeToState(store, token, key, handleUpdate);
|
|
2323
2610
|
case `transaction`:
|
|
2324
|
-
return subscribeToTransaction(
|
|
2611
|
+
return subscribeToTransaction(store, token, key, handleUpdate);
|
|
2325
2612
|
case `timeline`:
|
|
2326
|
-
return subscribeToTimeline(
|
|
2613
|
+
return subscribeToTimeline(store, token, key, handleUpdate);
|
|
2327
2614
|
}
|
|
2328
2615
|
}
|
|
2329
2616
|
|
|
2330
2617
|
// internal/src/subscribe/subscribe-to-root-atoms.ts
|
|
2331
|
-
var subscribeToRootAtoms = (
|
|
2618
|
+
var subscribeToRootAtoms = (store, selector2) => {
|
|
2332
2619
|
const target = newest(store);
|
|
2333
|
-
const dependencySubscriptions = traceAllSelectorAtoms(
|
|
2620
|
+
const dependencySubscriptions = traceAllSelectorAtoms(selector2, store).map(
|
|
2334
2621
|
(atomKey) => {
|
|
2335
|
-
const
|
|
2336
|
-
if (
|
|
2622
|
+
const atom2 = target.atoms.get(atomKey);
|
|
2623
|
+
if (atom2 === void 0) {
|
|
2337
2624
|
throw new Error(
|
|
2338
|
-
`Atom "${atomKey}", a dependency of selector "${
|
|
2625
|
+
`Atom "${atomKey}", a dependency of selector "${selector2.key}", not found in store "${store.config.name}".`
|
|
2339
2626
|
);
|
|
2340
2627
|
}
|
|
2341
|
-
return
|
|
2342
|
-
`${
|
|
2628
|
+
return atom2.subject.subscribe(
|
|
2629
|
+
`${selector2.type}:${selector2.key}`,
|
|
2343
2630
|
(atomChange) => {
|
|
2344
2631
|
store.logger.info(
|
|
2345
2632
|
`\u{1F4E2}`,
|
|
2346
|
-
|
|
2347
|
-
|
|
2633
|
+
selector2.type,
|
|
2634
|
+
selector2.key,
|
|
2348
2635
|
`root`,
|
|
2349
2636
|
atomKey,
|
|
2350
2637
|
`went`,
|
|
@@ -2352,18 +2639,18 @@ var subscribeToRootAtoms = (selector, store) => {
|
|
|
2352
2639
|
`->`,
|
|
2353
2640
|
atomChange.newValue
|
|
2354
2641
|
);
|
|
2355
|
-
const oldValue = recallState(
|
|
2356
|
-
const newValue = readOrComputeValue(
|
|
2642
|
+
const oldValue = recallState(target, selector2);
|
|
2643
|
+
const newValue = readOrComputeValue(target, selector2);
|
|
2357
2644
|
store.logger.info(
|
|
2358
2645
|
`\u2728`,
|
|
2359
|
-
|
|
2360
|
-
|
|
2646
|
+
selector2.type,
|
|
2647
|
+
selector2.key,
|
|
2361
2648
|
`went`,
|
|
2362
2649
|
oldValue,
|
|
2363
2650
|
`->`,
|
|
2364
2651
|
newValue
|
|
2365
2652
|
);
|
|
2366
|
-
|
|
2653
|
+
selector2.subject.next({ newValue, oldValue });
|
|
2367
2654
|
}
|
|
2368
2655
|
);
|
|
2369
2656
|
}
|
|
@@ -2372,7 +2659,7 @@ var subscribeToRootAtoms = (selector, store) => {
|
|
|
2372
2659
|
};
|
|
2373
2660
|
|
|
2374
2661
|
// internal/src/subscribe/subscribe-to-state.ts
|
|
2375
|
-
function
|
|
2662
|
+
function subscribeToState(store, token, key, handleUpdate) {
|
|
2376
2663
|
function safelyHandleUpdate(update) {
|
|
2377
2664
|
if (store.operation.open) {
|
|
2378
2665
|
const unsubscribe2 = store.on.operationClose.subscribe(
|
|
@@ -2386,17 +2673,17 @@ function subscribeToState2(token, handleUpdate, key, store) {
|
|
|
2386
2673
|
handleUpdate(update);
|
|
2387
2674
|
}
|
|
2388
2675
|
}
|
|
2389
|
-
const state = withdraw(
|
|
2676
|
+
const state = withdraw(store, token);
|
|
2390
2677
|
store.logger.info(`\u{1F440}`, state.type, state.key, `Adding subscription "${key}"`);
|
|
2391
2678
|
const isSelector = state.type === `selector` || state.type === `readonly_selector`;
|
|
2392
2679
|
let dependencyUnsubFunctions = null;
|
|
2393
2680
|
let updateHandler = safelyHandleUpdate;
|
|
2394
2681
|
if (isSelector) {
|
|
2395
|
-
dependencyUnsubFunctions = subscribeToRootAtoms(
|
|
2682
|
+
dependencyUnsubFunctions = subscribeToRootAtoms(store, state);
|
|
2396
2683
|
updateHandler = (update) => {
|
|
2397
2684
|
if (dependencyUnsubFunctions) {
|
|
2398
2685
|
dependencyUnsubFunctions.length = 0;
|
|
2399
|
-
dependencyUnsubFunctions.push(...subscribeToRootAtoms(
|
|
2686
|
+
dependencyUnsubFunctions.push(...subscribeToRootAtoms(store, state));
|
|
2400
2687
|
}
|
|
2401
2688
|
safelyHandleUpdate(update);
|
|
2402
2689
|
};
|
|
@@ -2420,8 +2707,8 @@ function subscribeToState2(token, handleUpdate, key, store) {
|
|
|
2420
2707
|
}
|
|
2421
2708
|
|
|
2422
2709
|
// internal/src/subscribe/subscribe-to-timeline.ts
|
|
2423
|
-
var
|
|
2424
|
-
const tl = withdraw(
|
|
2710
|
+
var subscribeToTimeline = (store, token, key, handleUpdate) => {
|
|
2711
|
+
const tl = withdraw(store, token);
|
|
2425
2712
|
store.logger.info(`\u{1F440}`, `timeline`, token.key, `Adding subscription "${key}"`);
|
|
2426
2713
|
const unsubscribe = tl.subject.subscribe(key, handleUpdate);
|
|
2427
2714
|
return () => {
|
|
@@ -2436,8 +2723,8 @@ var subscribeToTimeline2 = (token, handleUpdate, key, store) => {
|
|
|
2436
2723
|
};
|
|
2437
2724
|
|
|
2438
2725
|
// internal/src/subscribe/subscribe-to-transaction.ts
|
|
2439
|
-
var
|
|
2440
|
-
const tx = withdraw(
|
|
2726
|
+
var subscribeToTransaction = (store, token, key, handleUpdate) => {
|
|
2727
|
+
const tx = withdraw(store, token);
|
|
2441
2728
|
store.logger.info(
|
|
2442
2729
|
`\u{1F440}`,
|
|
2443
2730
|
`transaction`,
|
|
@@ -2466,7 +2753,7 @@ var Tracker = class {
|
|
|
2466
2753
|
const familyMetaData = mutableState.family ? {
|
|
2467
2754
|
key: `*${mutableState.family.key}`,
|
|
2468
2755
|
subKey: mutableState.family.subKey
|
|
2469
|
-
} :
|
|
2756
|
+
} : void 0;
|
|
2470
2757
|
const latestUpdateState = createRegularAtom(
|
|
2471
2758
|
store,
|
|
2472
2759
|
{
|
|
@@ -2492,8 +2779,10 @@ var Tracker = class {
|
|
|
2492
2779
|
setIntoStore(target, latestUpdateState, update);
|
|
2493
2780
|
}
|
|
2494
2781
|
);
|
|
2495
|
-
this.unsubscribeFromState =
|
|
2782
|
+
this.unsubscribeFromState = subscribeToState(
|
|
2783
|
+
target,
|
|
2496
2784
|
mutableState,
|
|
2785
|
+
subscriptionKey,
|
|
2497
2786
|
(update) => {
|
|
2498
2787
|
if (update.newValue !== update.oldValue) {
|
|
2499
2788
|
this.unsubscribeFromInnerValue();
|
|
@@ -2504,15 +2793,15 @@ var Tracker = class {
|
|
|
2504
2793
|
}
|
|
2505
2794
|
);
|
|
2506
2795
|
}
|
|
2507
|
-
}
|
|
2508
|
-
subscriptionKey,
|
|
2509
|
-
target
|
|
2796
|
+
}
|
|
2510
2797
|
);
|
|
2511
2798
|
}
|
|
2512
2799
|
updateCore(mutableState, latestUpdateState, target) {
|
|
2513
2800
|
const subscriptionKey = `tracker:${target.config.name}:${isChildStore(target) ? target.transactionMeta.update.key : `main`}:${mutableState.key}`;
|
|
2514
|
-
|
|
2801
|
+
subscribeToState(
|
|
2802
|
+
target,
|
|
2515
2803
|
latestUpdateState,
|
|
2804
|
+
subscriptionKey,
|
|
2516
2805
|
({ newValue, oldValue }) => {
|
|
2517
2806
|
const timelineId = target.timelineTopics.getRelatedKey(
|
|
2518
2807
|
latestUpdateState.key
|
|
@@ -2520,8 +2809,10 @@ var Tracker = class {
|
|
|
2520
2809
|
if (timelineId) {
|
|
2521
2810
|
const timelineData = target.timelines.get(timelineId);
|
|
2522
2811
|
if (timelineData?.timeTraveling) {
|
|
2523
|
-
const unsubscribe2 =
|
|
2812
|
+
const unsubscribe2 = subscribeToTimeline(
|
|
2813
|
+
target,
|
|
2524
2814
|
{ key: timelineId, type: `timeline` },
|
|
2815
|
+
subscriptionKey,
|
|
2525
2816
|
(update) => {
|
|
2526
2817
|
unsubscribe2();
|
|
2527
2818
|
setIntoStore(target, mutableState, (transceiver) => {
|
|
@@ -2532,9 +2823,7 @@ var Tracker = class {
|
|
|
2532
2823
|
}
|
|
2533
2824
|
return transceiver;
|
|
2534
2825
|
});
|
|
2535
|
-
}
|
|
2536
|
-
subscriptionKey,
|
|
2537
|
-
target
|
|
2826
|
+
}
|
|
2538
2827
|
);
|
|
2539
2828
|
return;
|
|
2540
2829
|
}
|
|
@@ -2562,14 +2851,12 @@ var Tracker = class {
|
|
|
2562
2851
|
}
|
|
2563
2852
|
}
|
|
2564
2853
|
);
|
|
2565
|
-
}
|
|
2566
|
-
subscriptionKey,
|
|
2567
|
-
target
|
|
2854
|
+
}
|
|
2568
2855
|
);
|
|
2569
2856
|
}
|
|
2570
2857
|
mutableState;
|
|
2571
2858
|
latestUpdateState;
|
|
2572
|
-
dispose;
|
|
2859
|
+
[Symbol.dispose];
|
|
2573
2860
|
constructor(mutableState, store) {
|
|
2574
2861
|
this.mutableState = mutableState;
|
|
2575
2862
|
const target = newest(store);
|
|
@@ -2577,7 +2864,7 @@ var Tracker = class {
|
|
|
2577
2864
|
this.observeCore(mutableState, this.latestUpdateState, target);
|
|
2578
2865
|
this.updateCore(mutableState, this.latestUpdateState, target);
|
|
2579
2866
|
target.trackers.set(mutableState.key, this);
|
|
2580
|
-
this.dispose = () => {
|
|
2867
|
+
this[Symbol.dispose] = () => {
|
|
2581
2868
|
this.unsubscribeFromInnerValue();
|
|
2582
2869
|
this.unsubscribeFromState();
|
|
2583
2870
|
target.trackers.delete(mutableState.key);
|
|
@@ -2624,8 +2911,8 @@ function createMutableAtom(store, options, family) {
|
|
|
2624
2911
|
}
|
|
2625
2912
|
const initialValue = options.default();
|
|
2626
2913
|
target.atoms.set(newAtom.key, newAtom);
|
|
2627
|
-
markAtomAsDefault(options.key
|
|
2628
|
-
cacheValue(options.key, initialValue, subject
|
|
2914
|
+
markAtomAsDefault(store, options.key);
|
|
2915
|
+
cacheValue(target, options.key, initialValue, subject);
|
|
2629
2916
|
const token = deposit(newAtom);
|
|
2630
2917
|
if (options.effects) {
|
|
2631
2918
|
let effectIndex = 0;
|
|
@@ -2635,7 +2922,7 @@ function createMutableAtom(store, options, family) {
|
|
|
2635
2922
|
setSelf: (next) => {
|
|
2636
2923
|
setIntoStore(store, token, next);
|
|
2637
2924
|
},
|
|
2638
|
-
onSet: (handle) =>
|
|
2925
|
+
onSet: (handle) => subscribeToState(store, token, `effect[${effectIndex}]`, handle)
|
|
2639
2926
|
});
|
|
2640
2927
|
if (cleanup) {
|
|
2641
2928
|
cleanupFunctions.push(cleanup);
|
|
@@ -2654,7 +2941,10 @@ function createMutableAtom(store, options, family) {
|
|
|
2654
2941
|
}
|
|
2655
2942
|
return token;
|
|
2656
2943
|
}
|
|
2944
|
+
|
|
2945
|
+
// internal/src/mutable/tracker-family.ts
|
|
2657
2946
|
var FamilyTracker = class {
|
|
2947
|
+
trackers = /* @__PURE__ */ new Map();
|
|
2658
2948
|
Update;
|
|
2659
2949
|
latestUpdateAtoms;
|
|
2660
2950
|
mutableAtoms;
|
|
@@ -2667,26 +2957,27 @@ var FamilyTracker = class {
|
|
|
2667
2957
|
},
|
|
2668
2958
|
[`mutable`, `updates`]
|
|
2669
2959
|
);
|
|
2670
|
-
this.latestUpdateAtoms = withdraw(
|
|
2960
|
+
this.latestUpdateAtoms = withdraw(store, updateAtoms);
|
|
2671
2961
|
this.mutableAtoms = mutableAtoms;
|
|
2672
2962
|
this.mutableAtoms.subject.subscribe(
|
|
2673
2963
|
`store=${store.config.name}::tracker-atom-family`,
|
|
2674
2964
|
(event) => {
|
|
2675
|
-
|
|
2676
|
-
|
|
2677
|
-
|
|
2678
|
-
|
|
2679
|
-
|
|
2680
|
-
|
|
2681
|
-
|
|
2682
|
-
|
|
2683
|
-
|
|
2684
|
-
|
|
2685
|
-
|
|
2686
|
-
|
|
2687
|
-
|
|
2688
|
-
|
|
2689
|
-
|
|
2965
|
+
const { type, token } = event;
|
|
2966
|
+
if (token.family) {
|
|
2967
|
+
const key = parseJson(token.family.subKey);
|
|
2968
|
+
switch (type) {
|
|
2969
|
+
case `state_creation`:
|
|
2970
|
+
this.trackers.set(key, new Tracker(token, store));
|
|
2971
|
+
break;
|
|
2972
|
+
case `state_disposal`:
|
|
2973
|
+
{
|
|
2974
|
+
const tracker = this.trackers.get(key);
|
|
2975
|
+
if (tracker) {
|
|
2976
|
+
tracker[Symbol.dispose]();
|
|
2977
|
+
this.trackers.delete(key);
|
|
2978
|
+
}
|
|
2979
|
+
}
|
|
2980
|
+
break;
|
|
2690
2981
|
}
|
|
2691
2982
|
}
|
|
2692
2983
|
}
|
|
@@ -2731,16 +3022,16 @@ function createMutableAtomFamily(store, options, internalRoles) {
|
|
|
2731
3022
|
subject.next({ type: `state_creation`, token });
|
|
2732
3023
|
return token;
|
|
2733
3024
|
};
|
|
2734
|
-
const
|
|
3025
|
+
const atomFamily2 = Object.assign(familyFunction, familyToken, {
|
|
2735
3026
|
subject,
|
|
2736
3027
|
install: (s) => createMutableAtomFamily(s, options),
|
|
2737
3028
|
toJson: options.toJson,
|
|
2738
3029
|
fromJson: options.fromJson,
|
|
2739
3030
|
internalRoles
|
|
2740
3031
|
});
|
|
2741
|
-
store.families.set(options.key,
|
|
2742
|
-
selectJsonFamily(
|
|
2743
|
-
new FamilyTracker(
|
|
3032
|
+
store.families.set(options.key, atomFamily2);
|
|
3033
|
+
selectJsonFamily(store, atomFamily2, options);
|
|
3034
|
+
new FamilyTracker(atomFamily2, store);
|
|
2744
3035
|
return familyToken;
|
|
2745
3036
|
}
|
|
2746
3037
|
|
|
@@ -2761,7 +3052,7 @@ var getJsonToken = (store, mutableAtomToken) => {
|
|
|
2761
3052
|
key: jsonFamilyKey,
|
|
2762
3053
|
type: `selector_family`
|
|
2763
3054
|
};
|
|
2764
|
-
const family = withdraw(
|
|
3055
|
+
const family = withdraw(target, jsonFamilyToken);
|
|
2765
3056
|
const subKey = JSON.parse(mutableAtomToken.family.subKey);
|
|
2766
3057
|
const jsonToken = findInStore(store, family, subKey);
|
|
2767
3058
|
return jsonToken;
|
|
@@ -2802,25 +3093,25 @@ function isTransceiver(value) {
|
|
|
2802
3093
|
}
|
|
2803
3094
|
|
|
2804
3095
|
// internal/src/set-state/copy-mutable-if-needed.ts
|
|
2805
|
-
function copyMutableIfNeeded(
|
|
2806
|
-
const originValue = origin.valueMap.get(
|
|
2807
|
-
const targetValue = target.valueMap.get(
|
|
3096
|
+
function copyMutableIfNeeded(target, atom2, origin) {
|
|
3097
|
+
const originValue = origin.valueMap.get(atom2.key);
|
|
3098
|
+
const targetValue = target.valueMap.get(atom2.key);
|
|
2808
3099
|
if (originValue === targetValue) {
|
|
2809
|
-
if (originValue ===
|
|
2810
|
-
return typeof
|
|
2811
|
-
}
|
|
2812
|
-
origin.logger.info(`\u{1F4C3}`, `atom`,
|
|
2813
|
-
const jsonValue =
|
|
2814
|
-
const copiedValue =
|
|
2815
|
-
target.valueMap.set(
|
|
2816
|
-
new Tracker(
|
|
3100
|
+
if (originValue === void 0) {
|
|
3101
|
+
return typeof atom2.default === `function` ? atom2.default() : atom2.default;
|
|
3102
|
+
}
|
|
3103
|
+
origin.logger.info(`\u{1F4C3}`, `atom`, atom2.key, `copying`);
|
|
3104
|
+
const jsonValue = atom2.toJson(originValue);
|
|
3105
|
+
const copiedValue = atom2.fromJson(jsonValue);
|
|
3106
|
+
target.valueMap.set(atom2.key, copiedValue);
|
|
3107
|
+
new Tracker(atom2, origin);
|
|
2817
3108
|
return copiedValue;
|
|
2818
3109
|
}
|
|
2819
3110
|
return targetValue;
|
|
2820
3111
|
}
|
|
2821
3112
|
|
|
2822
3113
|
// internal/src/caching.ts
|
|
2823
|
-
function cacheValue(key, value, subject
|
|
3114
|
+
function cacheValue(target, key, value, subject) {
|
|
2824
3115
|
const currentValue = target.valueMap.get(key);
|
|
2825
3116
|
if (currentValue instanceof Future) {
|
|
2826
3117
|
const future = currentValue;
|
|
@@ -2830,7 +3121,7 @@ function cacheValue(key, value, subject, target) {
|
|
|
2830
3121
|
const future = new Future(value);
|
|
2831
3122
|
target.valueMap.set(key, future);
|
|
2832
3123
|
future.then((resolved) => {
|
|
2833
|
-
cacheValue(key, resolved, subject
|
|
3124
|
+
cacheValue(target, key, resolved, subject);
|
|
2834
3125
|
subject.next({ newValue: resolved, oldValue: future });
|
|
2835
3126
|
}).catch((thrown) => {
|
|
2836
3127
|
target.logger.error(`\u{1F4A5}`, `state`, key, `rejected:`, thrown);
|
|
@@ -2844,7 +3135,7 @@ var readCachedValue = (token, target) => {
|
|
|
2844
3135
|
let value = target.valueMap.get(token.key);
|
|
2845
3136
|
if (token.type === `mutable_atom` && isChildStore(target)) {
|
|
2846
3137
|
const { parent } = target;
|
|
2847
|
-
const copiedValue = copyMutableIfNeeded(token, parent
|
|
3138
|
+
const copiedValue = copyMutableIfNeeded(target, token, parent);
|
|
2848
3139
|
value = copiedValue;
|
|
2849
3140
|
}
|
|
2850
3141
|
return value;
|
|
@@ -2853,9 +3144,9 @@ var evictCachedValue = (key, target) => {
|
|
|
2853
3144
|
const currentValue = target.valueMap.get(key);
|
|
2854
3145
|
if (currentValue instanceof Future) {
|
|
2855
3146
|
const future = currentValue;
|
|
2856
|
-
const
|
|
2857
|
-
if (
|
|
2858
|
-
future.use(
|
|
3147
|
+
const selector2 = target.selectors.get(key) ?? target.readonlySelectors.get(key);
|
|
3148
|
+
if (selector2) {
|
|
3149
|
+
future.use(selector2.get());
|
|
2859
3150
|
}
|
|
2860
3151
|
return;
|
|
2861
3152
|
}
|
|
@@ -2867,15 +3158,15 @@ var evictCachedValue = (key, target) => {
|
|
|
2867
3158
|
};
|
|
2868
3159
|
|
|
2869
3160
|
// internal/src/atom/is-default.ts
|
|
2870
|
-
var isAtomDefault = (
|
|
3161
|
+
var isAtomDefault = (store, key) => {
|
|
2871
3162
|
const core = newest(store);
|
|
2872
3163
|
return core.atomsThatAreDefault.has(key);
|
|
2873
3164
|
};
|
|
2874
|
-
var markAtomAsDefault = (
|
|
3165
|
+
var markAtomAsDefault = (store, key) => {
|
|
2875
3166
|
const core = newest(store);
|
|
2876
3167
|
core.atomsThatAreDefault = new Set(core.atomsThatAreDefault).add(key);
|
|
2877
3168
|
};
|
|
2878
|
-
var markAtomAsNotDefault = (
|
|
3169
|
+
var markAtomAsNotDefault = (store, key) => {
|
|
2879
3170
|
const core = newest(store);
|
|
2880
3171
|
core.atomsThatAreDefault = new Set(newest(store).atomsThatAreDefault);
|
|
2881
3172
|
core.atomsThatAreDefault.delete(key);
|
|
@@ -2923,8 +3214,8 @@ function createRegularAtom(store, options, family) {
|
|
|
2923
3214
|
initialValue = options.default();
|
|
2924
3215
|
}
|
|
2925
3216
|
target.atoms.set(newAtom.key, newAtom);
|
|
2926
|
-
markAtomAsDefault(options.key
|
|
2927
|
-
cacheValue(options.key, initialValue, subject
|
|
3217
|
+
markAtomAsDefault(store, options.key);
|
|
3218
|
+
cacheValue(target, options.key, initialValue, subject);
|
|
2928
3219
|
const token = deposit(newAtom);
|
|
2929
3220
|
if (options.effects) {
|
|
2930
3221
|
let effectIndex = 0;
|
|
@@ -2934,7 +3225,7 @@ function createRegularAtom(store, options, family) {
|
|
|
2934
3225
|
setSelf: (next) => {
|
|
2935
3226
|
setIntoStore(store, token, next);
|
|
2936
3227
|
},
|
|
2937
|
-
onSet: (handle) =>
|
|
3228
|
+
onSet: (handle) => subscribeToState(store, token, `effect[${effectIndex}]`, handle)
|
|
2938
3229
|
});
|
|
2939
3230
|
if (cleanup) {
|
|
2940
3231
|
cleanupFunctions.push(cleanup);
|
|
@@ -2954,33 +3245,33 @@ function createRegularAtom(store, options, family) {
|
|
|
2954
3245
|
function createStandaloneAtom(store, options) {
|
|
2955
3246
|
const isMutable = `mutable` in options;
|
|
2956
3247
|
if (isMutable) {
|
|
2957
|
-
const state2 = createMutableAtom(store, options,
|
|
3248
|
+
const state2 = createMutableAtom(store, options, void 0);
|
|
2958
3249
|
store.on.atomCreation.next(state2);
|
|
2959
3250
|
return state2;
|
|
2960
3251
|
}
|
|
2961
|
-
const state = createRegularAtom(store, options,
|
|
3252
|
+
const state = createRegularAtom(store, options, void 0);
|
|
2962
3253
|
store.on.atomCreation.next(state);
|
|
2963
3254
|
return state;
|
|
2964
3255
|
}
|
|
2965
3256
|
|
|
2966
3257
|
// internal/src/atom/dispose-atom.ts
|
|
2967
|
-
function disposeAtom(
|
|
3258
|
+
function disposeAtom(store, atomToken) {
|
|
2968
3259
|
const target = newest(store);
|
|
2969
3260
|
const { key, family } = atomToken;
|
|
2970
|
-
const
|
|
3261
|
+
const atom2 = withdraw(target, atomToken);
|
|
2971
3262
|
if (!family) {
|
|
2972
3263
|
store.logger.error(`\u274C`, `atom`, key, `Standalone atoms cannot be disposed.`);
|
|
2973
3264
|
} else {
|
|
2974
|
-
|
|
2975
|
-
const lastValue = store.valueMap.get(
|
|
2976
|
-
const
|
|
3265
|
+
atom2.cleanup?.();
|
|
3266
|
+
const lastValue = store.valueMap.get(atom2.key);
|
|
3267
|
+
const atomFamily2 = withdraw(store, { key: family.key, type: `atom_family` });
|
|
2977
3268
|
const disposal = {
|
|
2978
3269
|
type: `state_disposal`,
|
|
2979
3270
|
subType: `atom`,
|
|
2980
3271
|
token: atomToken,
|
|
2981
3272
|
value: lastValue
|
|
2982
3273
|
};
|
|
2983
|
-
|
|
3274
|
+
atomFamily2.subject.next(disposal);
|
|
2984
3275
|
const isChild = isChildStore(target);
|
|
2985
3276
|
target.atoms.delete(key);
|
|
2986
3277
|
target.valueMap.delete(key);
|
|
@@ -2989,14 +3280,14 @@ function disposeAtom(atomToken, store) {
|
|
|
2989
3280
|
store.timelineTopics.delete(key);
|
|
2990
3281
|
if (atomToken.type === `mutable_atom`) {
|
|
2991
3282
|
const updateToken = getUpdateToken(atomToken);
|
|
2992
|
-
disposeAtom(
|
|
3283
|
+
disposeAtom(store, updateToken);
|
|
2993
3284
|
store.trackers.delete(key);
|
|
2994
3285
|
}
|
|
2995
3286
|
store.logger.info(`\u{1F525}`, `atom`, key, `deleted`);
|
|
2996
3287
|
if (isChild && target.transactionMeta.phase === `building`) {
|
|
2997
3288
|
const mostRecentUpdate = target.transactionMeta.update.updates.at(-1);
|
|
2998
3289
|
const wasMoleculeDisposal = mostRecentUpdate?.type === `molecule_disposal`;
|
|
2999
|
-
const updateAlreadyCaptured = wasMoleculeDisposal && mostRecentUpdate.values.some(([k]) => k ===
|
|
3290
|
+
const updateAlreadyCaptured = wasMoleculeDisposal && mostRecentUpdate.values.some(([k]) => k === atom2.family?.key);
|
|
3000
3291
|
if (!updateAlreadyCaptured) {
|
|
3001
3292
|
target.transactionMeta.update.updates.push(disposal);
|
|
3002
3293
|
}
|
|
@@ -3006,8 +3297,746 @@ function disposeAtom(atomToken, store) {
|
|
|
3006
3297
|
}
|
|
3007
3298
|
}
|
|
3008
3299
|
|
|
3300
|
+
// transceivers/set-rtx/src/set-rtx.ts
|
|
3301
|
+
var SetRTX = class _SetRTX extends Set {
|
|
3302
|
+
mode = `record`;
|
|
3303
|
+
subject = new Subject();
|
|
3304
|
+
cacheLimit = 0;
|
|
3305
|
+
cache = [];
|
|
3306
|
+
cacheIdx = -1;
|
|
3307
|
+
cacheUpdateNumber = -1;
|
|
3308
|
+
constructor(values, cacheLimit = 0) {
|
|
3309
|
+
super(values);
|
|
3310
|
+
if (values instanceof _SetRTX) {
|
|
3311
|
+
this.parent = values;
|
|
3312
|
+
this.cacheUpdateNumber = values.cacheUpdateNumber;
|
|
3313
|
+
}
|
|
3314
|
+
if (cacheLimit) {
|
|
3315
|
+
this.cacheLimit = cacheLimit;
|
|
3316
|
+
this.cache = new Array(cacheLimit);
|
|
3317
|
+
this.subscribe(`auto cache`, (update) => {
|
|
3318
|
+
this.cacheIdx++;
|
|
3319
|
+
this.cacheIdx %= this.cacheLimit;
|
|
3320
|
+
this.cache[this.cacheIdx] = update;
|
|
3321
|
+
});
|
|
3322
|
+
}
|
|
3323
|
+
}
|
|
3324
|
+
toJSON() {
|
|
3325
|
+
return {
|
|
3326
|
+
members: [...this],
|
|
3327
|
+
cache: this.cache,
|
|
3328
|
+
cacheLimit: this.cacheLimit,
|
|
3329
|
+
cacheIdx: this.cacheIdx,
|
|
3330
|
+
cacheUpdateNumber: this.cacheUpdateNumber
|
|
3331
|
+
};
|
|
3332
|
+
}
|
|
3333
|
+
static fromJSON(json) {
|
|
3334
|
+
const set = new _SetRTX(json.members, json.cacheLimit);
|
|
3335
|
+
set.cache = json.cache;
|
|
3336
|
+
set.cacheIdx = json.cacheIdx;
|
|
3337
|
+
set.cacheUpdateNumber = json.cacheUpdateNumber;
|
|
3338
|
+
return set;
|
|
3339
|
+
}
|
|
3340
|
+
add(value) {
|
|
3341
|
+
const result = super.add(value);
|
|
3342
|
+
if (this.mode === `record`) {
|
|
3343
|
+
this.cacheUpdateNumber++;
|
|
3344
|
+
this.emit(`add:${stringifyJson(value)}`);
|
|
3345
|
+
}
|
|
3346
|
+
return result;
|
|
3347
|
+
}
|
|
3348
|
+
clear() {
|
|
3349
|
+
const capturedContents = this.mode === `record` ? [...this] : null;
|
|
3350
|
+
super.clear();
|
|
3351
|
+
if (capturedContents) {
|
|
3352
|
+
this.cacheUpdateNumber++;
|
|
3353
|
+
this.emit(`clear:${JSON.stringify(capturedContents)}`);
|
|
3354
|
+
}
|
|
3355
|
+
}
|
|
3356
|
+
delete(value) {
|
|
3357
|
+
const result = super.delete(value);
|
|
3358
|
+
if (this.mode === `record`) {
|
|
3359
|
+
this.cacheUpdateNumber++;
|
|
3360
|
+
this.emit(`del:${stringifyJson(value)}`);
|
|
3361
|
+
}
|
|
3362
|
+
return result;
|
|
3363
|
+
}
|
|
3364
|
+
parent;
|
|
3365
|
+
child = null;
|
|
3366
|
+
transactionUpdates = null;
|
|
3367
|
+
transaction(run) {
|
|
3368
|
+
this.mode = `transaction`;
|
|
3369
|
+
this.transactionUpdates = [];
|
|
3370
|
+
this.child = new _SetRTX(this);
|
|
3371
|
+
const unsubscribe = this.child._subscribe(`transaction`, (update) => {
|
|
3372
|
+
this.transactionUpdates?.push(update);
|
|
3373
|
+
});
|
|
3374
|
+
try {
|
|
3375
|
+
const shouldCommit = run(this.child);
|
|
3376
|
+
if (shouldCommit) {
|
|
3377
|
+
for (const update of this.transactionUpdates) {
|
|
3378
|
+
this.doStep(update);
|
|
3379
|
+
}
|
|
3380
|
+
this.cacheUpdateNumber++;
|
|
3381
|
+
this.emit(`tx:${this.transactionUpdates.join(`;`)}`);
|
|
3382
|
+
}
|
|
3383
|
+
} catch (thrown) {
|
|
3384
|
+
console.warn(
|
|
3385
|
+
`Did not apply transaction to SetRTX; this error was thrown:`,
|
|
3386
|
+
thrown
|
|
3387
|
+
);
|
|
3388
|
+
throw thrown;
|
|
3389
|
+
} finally {
|
|
3390
|
+
unsubscribe();
|
|
3391
|
+
this.child = null;
|
|
3392
|
+
this.transactionUpdates = null;
|
|
3393
|
+
this.mode = `record`;
|
|
3394
|
+
}
|
|
3395
|
+
}
|
|
3396
|
+
_subscribe(key, fn) {
|
|
3397
|
+
return this.subject.subscribe(key, fn);
|
|
3398
|
+
}
|
|
3399
|
+
subscribe(key, fn) {
|
|
3400
|
+
return this.subject.subscribe(key, (update) => {
|
|
3401
|
+
fn(`${this.cacheUpdateNumber}=${update}`);
|
|
3402
|
+
});
|
|
3403
|
+
}
|
|
3404
|
+
emit(update) {
|
|
3405
|
+
this.subject.next(update);
|
|
3406
|
+
}
|
|
3407
|
+
doStep(update) {
|
|
3408
|
+
const typeValueBreak = update.indexOf(`:`);
|
|
3409
|
+
const type = update.substring(0, typeValueBreak);
|
|
3410
|
+
const value = update.substring(typeValueBreak + 1);
|
|
3411
|
+
switch (type) {
|
|
3412
|
+
case `add`:
|
|
3413
|
+
this.add(JSON.parse(value));
|
|
3414
|
+
break;
|
|
3415
|
+
case `clear`:
|
|
3416
|
+
this.clear();
|
|
3417
|
+
break;
|
|
3418
|
+
case `del`:
|
|
3419
|
+
this.delete(JSON.parse(value));
|
|
3420
|
+
break;
|
|
3421
|
+
case `tx`:
|
|
3422
|
+
for (const subUpdate of value.split(`;`)) {
|
|
3423
|
+
this.doStep(subUpdate);
|
|
3424
|
+
}
|
|
3425
|
+
}
|
|
3426
|
+
}
|
|
3427
|
+
getUpdateNumber(update) {
|
|
3428
|
+
const breakpoint = update.indexOf(`=`);
|
|
3429
|
+
return Number(update.substring(0, breakpoint));
|
|
3430
|
+
}
|
|
3431
|
+
do(update) {
|
|
3432
|
+
const breakpoint = update.indexOf(`=`);
|
|
3433
|
+
const updateNumber = Number(update.substring(0, breakpoint));
|
|
3434
|
+
const eventOffset = updateNumber - this.cacheUpdateNumber;
|
|
3435
|
+
const isFuture = eventOffset > 0;
|
|
3436
|
+
if (isFuture) {
|
|
3437
|
+
if (eventOffset === 1) {
|
|
3438
|
+
this.mode = `playback`;
|
|
3439
|
+
const innerUpdate = update.substring(breakpoint + 1);
|
|
3440
|
+
this.doStep(innerUpdate);
|
|
3441
|
+
this.mode = `record`;
|
|
3442
|
+
this.cacheUpdateNumber = updateNumber;
|
|
3443
|
+
return null;
|
|
3444
|
+
}
|
|
3445
|
+
return this.cacheUpdateNumber + 1;
|
|
3446
|
+
}
|
|
3447
|
+
if (Math.abs(eventOffset) < this.cacheLimit) {
|
|
3448
|
+
const eventIdx = this.cacheIdx + eventOffset;
|
|
3449
|
+
const cachedUpdate = this.cache[eventIdx];
|
|
3450
|
+
if (cachedUpdate === update) {
|
|
3451
|
+
return null;
|
|
3452
|
+
}
|
|
3453
|
+
this.mode = `playback`;
|
|
3454
|
+
let done = false;
|
|
3455
|
+
while (!done) {
|
|
3456
|
+
this.cacheIdx %= this.cacheLimit;
|
|
3457
|
+
const u = this.cache[this.cacheIdx];
|
|
3458
|
+
this.cacheIdx--;
|
|
3459
|
+
if (!u) {
|
|
3460
|
+
return `OUT_OF_RANGE`;
|
|
3461
|
+
}
|
|
3462
|
+
this.undo(u);
|
|
3463
|
+
done = this.cacheIdx === eventIdx - 1;
|
|
3464
|
+
}
|
|
3465
|
+
const innerUpdate = update.substring(breakpoint + 1);
|
|
3466
|
+
this.doStep(innerUpdate);
|
|
3467
|
+
this.mode = `record`;
|
|
3468
|
+
this.cacheUpdateNumber = updateNumber;
|
|
3469
|
+
return null;
|
|
3470
|
+
}
|
|
3471
|
+
return `OUT_OF_RANGE`;
|
|
3472
|
+
}
|
|
3473
|
+
undoStep(update) {
|
|
3474
|
+
const breakpoint = update.indexOf(`:`);
|
|
3475
|
+
const type = update.substring(0, breakpoint);
|
|
3476
|
+
const value = update.substring(breakpoint + 1);
|
|
3477
|
+
switch (type) {
|
|
3478
|
+
case `add`:
|
|
3479
|
+
this.delete(JSON.parse(value));
|
|
3480
|
+
break;
|
|
3481
|
+
case `del`:
|
|
3482
|
+
this.add(JSON.parse(value));
|
|
3483
|
+
break;
|
|
3484
|
+
case `clear`: {
|
|
3485
|
+
const values = JSON.parse(value);
|
|
3486
|
+
for (const v of values) this.add(v);
|
|
3487
|
+
break;
|
|
3488
|
+
}
|
|
3489
|
+
case `tx`: {
|
|
3490
|
+
const updates = value.split(`;`);
|
|
3491
|
+
for (let i = updates.length - 1; i >= 0; i--) {
|
|
3492
|
+
this.undoStep(updates[i]);
|
|
3493
|
+
}
|
|
3494
|
+
}
|
|
3495
|
+
}
|
|
3496
|
+
}
|
|
3497
|
+
undo(update) {
|
|
3498
|
+
const breakpoint = update.indexOf(`=`);
|
|
3499
|
+
const updateNumber = Number(update.substring(0, breakpoint));
|
|
3500
|
+
if (updateNumber === this.cacheUpdateNumber) {
|
|
3501
|
+
this.mode = `playback`;
|
|
3502
|
+
const innerUpdate = update.substring(breakpoint + 1);
|
|
3503
|
+
this.undoStep(innerUpdate);
|
|
3504
|
+
this.mode = `record`;
|
|
3505
|
+
this.cacheUpdateNumber--;
|
|
3506
|
+
return null;
|
|
3507
|
+
}
|
|
3508
|
+
return this.cacheUpdateNumber;
|
|
3509
|
+
}
|
|
3510
|
+
};
|
|
3511
|
+
|
|
3512
|
+
// internal/src/join/join-internal.ts
|
|
3513
|
+
var Join = class {
|
|
3514
|
+
toolkit;
|
|
3515
|
+
options;
|
|
3516
|
+
defaultContent;
|
|
3517
|
+
molecules = /* @__PURE__ */ new Map();
|
|
3518
|
+
relations;
|
|
3519
|
+
states;
|
|
3520
|
+
core;
|
|
3521
|
+
transact(toolkit, run) {
|
|
3522
|
+
const originalToolkit = this.toolkit;
|
|
3523
|
+
this.toolkit = toolkit;
|
|
3524
|
+
run(this);
|
|
3525
|
+
this.toolkit = originalToolkit;
|
|
3526
|
+
}
|
|
3527
|
+
store;
|
|
3528
|
+
realm;
|
|
3529
|
+
[Symbol.dispose]() {
|
|
3530
|
+
}
|
|
3531
|
+
constructor(options, defaultContent, store = IMPLICIT.STORE) {
|
|
3532
|
+
this.store = store;
|
|
3533
|
+
this.realm = new Anarchy(store);
|
|
3534
|
+
this.options = options;
|
|
3535
|
+
this.defaultContent = defaultContent;
|
|
3536
|
+
this.store.miscResources.set(`join:${options.key}`, this);
|
|
3537
|
+
this.realm.allocate(`root`, options.key);
|
|
3538
|
+
this.toolkit = {
|
|
3539
|
+
get: (...ps) => getFromStore(store, ...ps),
|
|
3540
|
+
set: (...ps) => {
|
|
3541
|
+
setIntoStore(store, ...ps);
|
|
3542
|
+
},
|
|
3543
|
+
find: (...ps) => findInStore(store, ...ps),
|
|
3544
|
+
json: (token) => getJsonToken(store, token)
|
|
3545
|
+
};
|
|
3546
|
+
const aSide = options.between[0];
|
|
3547
|
+
const bSide = options.between[1];
|
|
3548
|
+
const relatedKeysAtoms = createMutableAtomFamily(
|
|
3549
|
+
store,
|
|
3550
|
+
{
|
|
3551
|
+
key: `${options.key}/relatedKeys`,
|
|
3552
|
+
default: () => new SetRTX(),
|
|
3553
|
+
mutable: true,
|
|
3554
|
+
fromJson: (json) => SetRTX.fromJSON(json),
|
|
3555
|
+
toJson: (set) => set.toJSON()
|
|
3556
|
+
},
|
|
3557
|
+
[`join`, `relations`]
|
|
3558
|
+
);
|
|
3559
|
+
this.core = { relatedKeysAtoms };
|
|
3560
|
+
const getRelatedKeys = ({ get }, key) => get(relatedKeysAtoms, key);
|
|
3561
|
+
const addRelation = ({ set }, a, b) => {
|
|
3562
|
+
if (!this.store.molecules.has(stringifyJson(a))) {
|
|
3563
|
+
this.realm.allocate(options.key, a);
|
|
3564
|
+
}
|
|
3565
|
+
set(relatedKeysAtoms, a, (aKeys) => aKeys.add(b));
|
|
3566
|
+
set(relatedKeysAtoms, b, (bKeys) => bKeys.add(a));
|
|
3567
|
+
};
|
|
3568
|
+
const deleteRelation = ({ set }, a, b) => {
|
|
3569
|
+
set(relatedKeysAtoms, a, (aKeys) => {
|
|
3570
|
+
aKeys.delete(b);
|
|
3571
|
+
return aKeys;
|
|
3572
|
+
});
|
|
3573
|
+
set(relatedKeysAtoms, b, (bKeys) => {
|
|
3574
|
+
bKeys.delete(a);
|
|
3575
|
+
return bKeys;
|
|
3576
|
+
});
|
|
3577
|
+
};
|
|
3578
|
+
const replaceRelationsSafely = (toolkit, a, newRelationsOfA) => {
|
|
3579
|
+
const { find, get, set } = toolkit;
|
|
3580
|
+
const relationsOfAState = find(relatedKeysAtoms, a);
|
|
3581
|
+
const currentRelationsOfA = get(relationsOfAState);
|
|
3582
|
+
for (const currentRelationB of currentRelationsOfA) {
|
|
3583
|
+
const remainsRelated = newRelationsOfA.includes(currentRelationB);
|
|
3584
|
+
if (remainsRelated) {
|
|
3585
|
+
continue;
|
|
3586
|
+
}
|
|
3587
|
+
set(relatedKeysAtoms, currentRelationB, (relationsOfB) => {
|
|
3588
|
+
relationsOfB.delete(a);
|
|
3589
|
+
return relationsOfB;
|
|
3590
|
+
});
|
|
3591
|
+
}
|
|
3592
|
+
set(relationsOfAState, (relationsOfA) => {
|
|
3593
|
+
relationsOfA.transaction((nextRelationsOfA) => {
|
|
3594
|
+
nextRelationsOfA.clear();
|
|
3595
|
+
for (const newRelationB of newRelationsOfA) {
|
|
3596
|
+
const relationsOfB = getRelatedKeys(toolkit, newRelationB);
|
|
3597
|
+
const newRelationBIsAlreadyRelated = relationsOfB.has(a);
|
|
3598
|
+
if (this.relations.cardinality === `1:n`) {
|
|
3599
|
+
const previousOwnersToDispose = [];
|
|
3600
|
+
for (const previousOwner of relationsOfB) {
|
|
3601
|
+
if (previousOwner === a) {
|
|
3602
|
+
continue;
|
|
3603
|
+
}
|
|
3604
|
+
const previousOwnerRelations = getRelatedKeys(
|
|
3605
|
+
toolkit,
|
|
3606
|
+
previousOwner
|
|
3607
|
+
);
|
|
3608
|
+
previousOwnerRelations.delete(newRelationB);
|
|
3609
|
+
if (previousOwnerRelations.size === 0) {
|
|
3610
|
+
previousOwnersToDispose.push(previousOwner);
|
|
3611
|
+
}
|
|
3612
|
+
}
|
|
3613
|
+
if (!newRelationBIsAlreadyRelated && relationsOfB.size > 0) {
|
|
3614
|
+
relationsOfB.clear();
|
|
3615
|
+
}
|
|
3616
|
+
for (const previousOwner of previousOwnersToDispose) {
|
|
3617
|
+
const sorted = [newRelationB, previousOwner].sort();
|
|
3618
|
+
const compositeKey = `"${sorted[0]}:${sorted[1]}"`;
|
|
3619
|
+
this.molecules.delete(compositeKey);
|
|
3620
|
+
}
|
|
3621
|
+
}
|
|
3622
|
+
if (!newRelationBIsAlreadyRelated) {
|
|
3623
|
+
relationsOfB.add(a);
|
|
3624
|
+
}
|
|
3625
|
+
nextRelationsOfA.add(newRelationB);
|
|
3626
|
+
}
|
|
3627
|
+
return true;
|
|
3628
|
+
});
|
|
3629
|
+
return relationsOfA;
|
|
3630
|
+
});
|
|
3631
|
+
};
|
|
3632
|
+
const replaceRelationsUnsafely = (toolkit, a, newRelationsOfA) => {
|
|
3633
|
+
const { set } = toolkit;
|
|
3634
|
+
set(relatedKeysAtoms, a, (relationsOfA) => {
|
|
3635
|
+
relationsOfA.transaction((nextRelationsOfA) => {
|
|
3636
|
+
for (const newRelationB of newRelationsOfA) {
|
|
3637
|
+
nextRelationsOfA.add(newRelationB);
|
|
3638
|
+
}
|
|
3639
|
+
return true;
|
|
3640
|
+
});
|
|
3641
|
+
return relationsOfA;
|
|
3642
|
+
});
|
|
3643
|
+
for (const newRelationB of newRelationsOfA) {
|
|
3644
|
+
set(relatedKeysAtoms, newRelationB, (newRelationsB) => {
|
|
3645
|
+
newRelationsB.add(a);
|
|
3646
|
+
return newRelationsB;
|
|
3647
|
+
});
|
|
3648
|
+
}
|
|
3649
|
+
return true;
|
|
3650
|
+
};
|
|
3651
|
+
const has = (toolkit, a, b) => {
|
|
3652
|
+
const aKeys = getRelatedKeys(toolkit, a);
|
|
3653
|
+
return b ? aKeys.has(b) : aKeys.size > 0;
|
|
3654
|
+
};
|
|
3655
|
+
const baseExternalStoreConfiguration = {
|
|
3656
|
+
getRelatedKeys: (key) => getRelatedKeys(this.toolkit, key),
|
|
3657
|
+
addRelation: (a, b) => {
|
|
3658
|
+
this.store.moleculeJoins.set(
|
|
3659
|
+
a,
|
|
3660
|
+
options.key
|
|
3661
|
+
);
|
|
3662
|
+
this.store.moleculeJoins.set(
|
|
3663
|
+
b,
|
|
3664
|
+
options.key
|
|
3665
|
+
);
|
|
3666
|
+
addRelation(this.toolkit, a, b);
|
|
3667
|
+
},
|
|
3668
|
+
deleteRelation: (a, b) => {
|
|
3669
|
+
deleteRelation(this.toolkit, a, b);
|
|
3670
|
+
},
|
|
3671
|
+
replaceRelationsSafely: (a, bs) => {
|
|
3672
|
+
replaceRelationsSafely(this.toolkit, a, bs);
|
|
3673
|
+
},
|
|
3674
|
+
replaceRelationsUnsafely: (a, bs) => {
|
|
3675
|
+
replaceRelationsUnsafely(this.toolkit, a, bs);
|
|
3676
|
+
},
|
|
3677
|
+
has: (a, b) => has(this.toolkit, a, b)
|
|
3678
|
+
};
|
|
3679
|
+
let externalStore;
|
|
3680
|
+
let contentAtoms;
|
|
3681
|
+
if (defaultContent) {
|
|
3682
|
+
contentAtoms = createRegularAtomFamily(
|
|
3683
|
+
store,
|
|
3684
|
+
{
|
|
3685
|
+
key: `${options.key}/content`,
|
|
3686
|
+
default: defaultContent
|
|
3687
|
+
},
|
|
3688
|
+
[`join`, `content`]
|
|
3689
|
+
);
|
|
3690
|
+
const getContent = ({ get }, key) => get(contentAtoms, key);
|
|
3691
|
+
const setContent = ({ set }, key, content) => {
|
|
3692
|
+
set(contentAtoms, key, content);
|
|
3693
|
+
};
|
|
3694
|
+
const externalStoreWithContentConfiguration = {
|
|
3695
|
+
getContent: (contentKey) => {
|
|
3696
|
+
const content = getContent(this.toolkit, contentKey);
|
|
3697
|
+
return content;
|
|
3698
|
+
},
|
|
3699
|
+
setContent: (contentKey, content) => {
|
|
3700
|
+
setContent(this.toolkit, contentKey, content);
|
|
3701
|
+
},
|
|
3702
|
+
deleteContent: (contentKey) => {
|
|
3703
|
+
this.realm.deallocate(contentKey);
|
|
3704
|
+
}
|
|
3705
|
+
};
|
|
3706
|
+
externalStore = Object.assign(
|
|
3707
|
+
baseExternalStoreConfiguration,
|
|
3708
|
+
externalStoreWithContentConfiguration
|
|
3709
|
+
);
|
|
3710
|
+
} else {
|
|
3711
|
+
externalStore = baseExternalStoreConfiguration;
|
|
3712
|
+
}
|
|
3713
|
+
const relations = new Junction(
|
|
3714
|
+
options,
|
|
3715
|
+
{
|
|
3716
|
+
externalStore,
|
|
3717
|
+
isAType: options.isAType,
|
|
3718
|
+
isBType: options.isBType,
|
|
3719
|
+
makeContentKey: (...args) => {
|
|
3720
|
+
const [a, b] = args;
|
|
3721
|
+
const sorted = args.sort();
|
|
3722
|
+
const compositeKey = `${sorted[0]}:${sorted[1]}`;
|
|
3723
|
+
const aMolecule = store.molecules.get(stringifyJson(a));
|
|
3724
|
+
const bMolecule = store.molecules.get(stringifyJson(b));
|
|
3725
|
+
if (!aMolecule) {
|
|
3726
|
+
this.realm.allocate(options.key, a);
|
|
3727
|
+
}
|
|
3728
|
+
if (!bMolecule) {
|
|
3729
|
+
this.realm.allocate(options.key, b);
|
|
3730
|
+
}
|
|
3731
|
+
this.realm.allocate(a, compositeKey, `all`);
|
|
3732
|
+
this.realm.claim(b, compositeKey);
|
|
3733
|
+
this.store.moleculeJoins.set(compositeKey, options.key);
|
|
3734
|
+
return compositeKey;
|
|
3735
|
+
}
|
|
3736
|
+
}
|
|
3737
|
+
);
|
|
3738
|
+
const createSingleKeySelectorFamily = () => createReadonlySelectorFamily(
|
|
3739
|
+
store,
|
|
3740
|
+
{
|
|
3741
|
+
key: `${options.key}/singleRelatedKey`,
|
|
3742
|
+
get: (key) => ({ get }) => {
|
|
3743
|
+
const relatedKeys = get(relatedKeysAtoms, key);
|
|
3744
|
+
for (const relatedKey of relatedKeys) {
|
|
3745
|
+
return relatedKey;
|
|
3746
|
+
}
|
|
3747
|
+
return null;
|
|
3748
|
+
}
|
|
3749
|
+
},
|
|
3750
|
+
[`join`, `keys`]
|
|
3751
|
+
);
|
|
3752
|
+
const getMultipleKeySelectorFamily = () => {
|
|
3753
|
+
return createReadonlySelectorFamily(
|
|
3754
|
+
store,
|
|
3755
|
+
{
|
|
3756
|
+
key: `${options.key}/multipleRelatedKeys`,
|
|
3757
|
+
get: (key) => ({ get }) => {
|
|
3758
|
+
const jsonFamily = getJsonFamily(relatedKeysAtoms, store);
|
|
3759
|
+
const json = get(jsonFamily, key);
|
|
3760
|
+
return json.members;
|
|
3761
|
+
}
|
|
3762
|
+
},
|
|
3763
|
+
[`join`, `keys`]
|
|
3764
|
+
);
|
|
3765
|
+
};
|
|
3766
|
+
const createSingleEntrySelectorFamily = () => createReadonlySelectorFamily(
|
|
3767
|
+
store,
|
|
3768
|
+
{
|
|
3769
|
+
key: `${options.key}/singleRelatedEntry`,
|
|
3770
|
+
get: (x) => ({ get }) => {
|
|
3771
|
+
const relatedKeys = get(relatedKeysAtoms, x);
|
|
3772
|
+
for (const y of relatedKeys) {
|
|
3773
|
+
let a = relations.isAType?.(x) ? x : void 0;
|
|
3774
|
+
let b = a === void 0 ? x : void 0;
|
|
3775
|
+
a ??= y;
|
|
3776
|
+
b ??= y;
|
|
3777
|
+
const contentKey = relations.makeContentKey(a, b);
|
|
3778
|
+
const content = get(contentAtoms, contentKey);
|
|
3779
|
+
return [y, content];
|
|
3780
|
+
}
|
|
3781
|
+
return null;
|
|
3782
|
+
}
|
|
3783
|
+
},
|
|
3784
|
+
[`join`, `entries`]
|
|
3785
|
+
);
|
|
3786
|
+
const getMultipleEntrySelectorFamily = () => createReadonlySelectorFamily(
|
|
3787
|
+
store,
|
|
3788
|
+
{
|
|
3789
|
+
key: `${options.key}/multipleRelatedEntries`,
|
|
3790
|
+
get: (x) => ({ get }) => {
|
|
3791
|
+
const jsonFamily = getJsonFamily(relatedKeysAtoms, store);
|
|
3792
|
+
const json = get(jsonFamily, x);
|
|
3793
|
+
return json.members.map((y) => {
|
|
3794
|
+
let a = relations.isAType?.(x) ? x : void 0;
|
|
3795
|
+
let b = a === void 0 ? x : void 0;
|
|
3796
|
+
a ??= y;
|
|
3797
|
+
b ??= y;
|
|
3798
|
+
const contentKey = relations.makeContentKey(a, b);
|
|
3799
|
+
const content = get(contentAtoms, contentKey);
|
|
3800
|
+
return [y, content];
|
|
3801
|
+
});
|
|
3802
|
+
}
|
|
3803
|
+
},
|
|
3804
|
+
[`join`, `entries`]
|
|
3805
|
+
);
|
|
3806
|
+
switch (options.cardinality) {
|
|
3807
|
+
case `1:1`: {
|
|
3808
|
+
const singleRelatedKeySelectors = createSingleKeySelectorFamily();
|
|
3809
|
+
const stateKeyA = `${aSide}KeyOf${capitalize(bSide)}`;
|
|
3810
|
+
const stateKeyB = `${bSide}KeyOf${capitalize(aSide)}`;
|
|
3811
|
+
const baseStates = {
|
|
3812
|
+
[stateKeyA]: singleRelatedKeySelectors,
|
|
3813
|
+
[stateKeyB]: singleRelatedKeySelectors
|
|
3814
|
+
};
|
|
3815
|
+
let states;
|
|
3816
|
+
if (defaultContent) {
|
|
3817
|
+
const singleEntrySelectors = createSingleEntrySelectorFamily();
|
|
3818
|
+
const entriesStateKeyA = `${aSide}EntryOf${capitalize(bSide)}`;
|
|
3819
|
+
const entriesStateKeyB = `${bSide}EntryOf${capitalize(aSide)}`;
|
|
3820
|
+
const contentStates = {
|
|
3821
|
+
[entriesStateKeyA]: singleEntrySelectors,
|
|
3822
|
+
[entriesStateKeyB]: singleEntrySelectors
|
|
3823
|
+
};
|
|
3824
|
+
states = Object.assign(baseStates, contentStates);
|
|
3825
|
+
} else {
|
|
3826
|
+
states = baseStates;
|
|
3827
|
+
}
|
|
3828
|
+
this.relations = relations;
|
|
3829
|
+
this.states = states;
|
|
3830
|
+
break;
|
|
3831
|
+
}
|
|
3832
|
+
case `1:n`: {
|
|
3833
|
+
const singleRelatedKeySelectors = createSingleKeySelectorFamily();
|
|
3834
|
+
const multipleRelatedKeysSelectors = getMultipleKeySelectorFamily();
|
|
3835
|
+
const stateKeyA = `${aSide}KeyOf${capitalize(bSide)}`;
|
|
3836
|
+
const stateKeyB = `${bSide}KeysOf${capitalize(aSide)}`;
|
|
3837
|
+
const baseStates = {
|
|
3838
|
+
[stateKeyA]: singleRelatedKeySelectors,
|
|
3839
|
+
[stateKeyB]: multipleRelatedKeysSelectors
|
|
3840
|
+
};
|
|
3841
|
+
let states;
|
|
3842
|
+
if (defaultContent) {
|
|
3843
|
+
const singleRelatedEntrySelectors = createSingleEntrySelectorFamily();
|
|
3844
|
+
const multipleRelatedEntriesSelectors = getMultipleEntrySelectorFamily();
|
|
3845
|
+
const entriesStateKeyA = `${aSide}EntryOf${capitalize(bSide)}`;
|
|
3846
|
+
const entriesStateKeyB = `${bSide}EntriesOf${capitalize(
|
|
3847
|
+
aSide
|
|
3848
|
+
)}`;
|
|
3849
|
+
const contentStates = {
|
|
3850
|
+
[entriesStateKeyA]: singleRelatedEntrySelectors,
|
|
3851
|
+
[entriesStateKeyB]: multipleRelatedEntriesSelectors
|
|
3852
|
+
};
|
|
3853
|
+
states = Object.assign(baseStates, contentStates);
|
|
3854
|
+
} else {
|
|
3855
|
+
states = baseStates;
|
|
3856
|
+
}
|
|
3857
|
+
this.relations = relations;
|
|
3858
|
+
this.states = states;
|
|
3859
|
+
break;
|
|
3860
|
+
}
|
|
3861
|
+
case `n:n`: {
|
|
3862
|
+
const multipleRelatedKeysSelectors = getMultipleKeySelectorFamily();
|
|
3863
|
+
const stateKeyA = `${aSide}KeysOf${capitalize(bSide)}`;
|
|
3864
|
+
const stateKeyB = `${bSide}KeysOf${capitalize(aSide)}`;
|
|
3865
|
+
const baseStates = {
|
|
3866
|
+
[stateKeyA]: multipleRelatedKeysSelectors,
|
|
3867
|
+
[stateKeyB]: multipleRelatedKeysSelectors
|
|
3868
|
+
};
|
|
3869
|
+
let states;
|
|
3870
|
+
if (defaultContent) {
|
|
3871
|
+
const multipleRelatedEntriesSelectors = getMultipleEntrySelectorFamily();
|
|
3872
|
+
const entriesStateKeyA = `${aSide}EntriesOf${capitalize(
|
|
3873
|
+
bSide
|
|
3874
|
+
)}`;
|
|
3875
|
+
const entriesStateKeyB = `${bSide}EntriesOf${capitalize(
|
|
3876
|
+
aSide
|
|
3877
|
+
)}`;
|
|
3878
|
+
const contentStates = {
|
|
3879
|
+
[entriesStateKeyA]: multipleRelatedEntriesSelectors,
|
|
3880
|
+
[entriesStateKeyB]: multipleRelatedEntriesSelectors
|
|
3881
|
+
};
|
|
3882
|
+
states = Object.assign(baseStates, contentStates);
|
|
3883
|
+
} else {
|
|
3884
|
+
states = baseStates;
|
|
3885
|
+
}
|
|
3886
|
+
this.relations = relations;
|
|
3887
|
+
this.states = states;
|
|
3888
|
+
}
|
|
3889
|
+
}
|
|
3890
|
+
}
|
|
3891
|
+
};
|
|
3892
|
+
|
|
3893
|
+
// internal/src/join/get-join.ts
|
|
3894
|
+
function getJoin(token, store) {
|
|
3895
|
+
let myJoin = store.joins.get(token.key);
|
|
3896
|
+
if (myJoin === void 0) {
|
|
3897
|
+
const rootJoinMap = IMPLICIT.STORE.joins;
|
|
3898
|
+
const rootJoin = rootJoinMap.get(token.key);
|
|
3899
|
+
if (rootJoin === void 0) {
|
|
3900
|
+
throw new Error(
|
|
3901
|
+
`Join "${token.key}" not found in store "${store.config.name}"`
|
|
3902
|
+
);
|
|
3903
|
+
}
|
|
3904
|
+
myJoin = new Join(rootJoin.options, rootJoin.defaultContent, store);
|
|
3905
|
+
store.joins.set(token.key, myJoin);
|
|
3906
|
+
}
|
|
3907
|
+
return myJoin;
|
|
3908
|
+
}
|
|
3909
|
+
|
|
3910
|
+
// internal/src/join/edit-relations-in-store.ts
|
|
3911
|
+
function editRelationsInStore(token, change, store) {
|
|
3912
|
+
const myJoin = getJoin(token, store);
|
|
3913
|
+
const target = newest(store);
|
|
3914
|
+
if (isChildStore(target)) {
|
|
3915
|
+
const { toolkit } = target.transactionMeta;
|
|
3916
|
+
myJoin.transact(toolkit, ({ relations }) => {
|
|
3917
|
+
change(relations);
|
|
3918
|
+
});
|
|
3919
|
+
} else {
|
|
3920
|
+
change(myJoin.relations);
|
|
3921
|
+
}
|
|
3922
|
+
}
|
|
3923
|
+
|
|
3924
|
+
// internal/src/join/find-relations-in-store.ts
|
|
3925
|
+
function findRelationsInStore(token, key, store) {
|
|
3926
|
+
const myJoin = getJoin(token, store);
|
|
3927
|
+
let relations;
|
|
3928
|
+
switch (token.cardinality) {
|
|
3929
|
+
case `1:1`: {
|
|
3930
|
+
const keyAB = `${token.a}KeyOf${capitalize(token.b)}`;
|
|
3931
|
+
const keyBA = `${token.b}KeyOf${capitalize(token.a)}`;
|
|
3932
|
+
relations = {
|
|
3933
|
+
get [keyAB]() {
|
|
3934
|
+
const familyAB = myJoin.states[keyAB];
|
|
3935
|
+
const state = findInStore(store, familyAB, key);
|
|
3936
|
+
return state;
|
|
3937
|
+
},
|
|
3938
|
+
get [keyBA]() {
|
|
3939
|
+
const familyBA = myJoin.states[keyBA];
|
|
3940
|
+
const state = findInStore(store, familyBA, key);
|
|
3941
|
+
return state;
|
|
3942
|
+
}
|
|
3943
|
+
};
|
|
3944
|
+
const entryAB = `${token.a}EntryOf${capitalize(token.b)}`;
|
|
3945
|
+
if (entryAB in myJoin.states) {
|
|
3946
|
+
const entryBA = `${token.b}EntryOf${capitalize(token.a)}`;
|
|
3947
|
+
Object.assign(relations, {
|
|
3948
|
+
get [entryAB]() {
|
|
3949
|
+
const familyAB = myJoin.states[entryAB];
|
|
3950
|
+
const state = findInStore(store, familyAB, key);
|
|
3951
|
+
return state;
|
|
3952
|
+
},
|
|
3953
|
+
get [entryBA]() {
|
|
3954
|
+
const familyBA = myJoin.states[entryBA];
|
|
3955
|
+
const state = findInStore(store, familyBA, key);
|
|
3956
|
+
return state;
|
|
3957
|
+
}
|
|
3958
|
+
});
|
|
3959
|
+
}
|
|
3960
|
+
break;
|
|
3961
|
+
}
|
|
3962
|
+
case `1:n`: {
|
|
3963
|
+
const keyAB = `${token.a}KeyOf${capitalize(token.b)}`;
|
|
3964
|
+
const keysBA = `${token.b}KeysOf${capitalize(token.a)}`;
|
|
3965
|
+
relations = {
|
|
3966
|
+
get [keyAB]() {
|
|
3967
|
+
const familyAB = myJoin.states[keyAB];
|
|
3968
|
+
const state = findInStore(store, familyAB, key);
|
|
3969
|
+
return state;
|
|
3970
|
+
},
|
|
3971
|
+
get [keysBA]() {
|
|
3972
|
+
const familyBA = myJoin.states[keysBA];
|
|
3973
|
+
const state = findInStore(store, familyBA, key);
|
|
3974
|
+
return state;
|
|
3975
|
+
}
|
|
3976
|
+
};
|
|
3977
|
+
const entryAB = `${token.a}EntryOf${capitalize(token.b)}`;
|
|
3978
|
+
if (entryAB in myJoin.states) {
|
|
3979
|
+
const entriesBA = `${token.b}EntriesOf${capitalize(token.a)}`;
|
|
3980
|
+
Object.assign(relations, {
|
|
3981
|
+
get [entryAB]() {
|
|
3982
|
+
const familyAB = myJoin.states[entryAB];
|
|
3983
|
+
const state = findInStore(store, familyAB, key);
|
|
3984
|
+
return state;
|
|
3985
|
+
},
|
|
3986
|
+
get [entriesBA]() {
|
|
3987
|
+
const familyBA = myJoin.states[entriesBA];
|
|
3988
|
+
const state = findInStore(store, familyBA, key);
|
|
3989
|
+
return state;
|
|
3990
|
+
}
|
|
3991
|
+
});
|
|
3992
|
+
}
|
|
3993
|
+
break;
|
|
3994
|
+
}
|
|
3995
|
+
case `n:n`: {
|
|
3996
|
+
const keysAB = `${token.a}KeysOf${capitalize(token.b)}`;
|
|
3997
|
+
const keysBA = `${token.b}KeysOf${capitalize(token.a)}`;
|
|
3998
|
+
relations = {
|
|
3999
|
+
get [keysAB]() {
|
|
4000
|
+
const familyAB = myJoin.states[keysAB];
|
|
4001
|
+
const state = findInStore(store, familyAB, key);
|
|
4002
|
+
return state;
|
|
4003
|
+
},
|
|
4004
|
+
get [keysBA]() {
|
|
4005
|
+
const familyBA = myJoin.states[keysBA];
|
|
4006
|
+
const state = findInStore(store, familyBA, key);
|
|
4007
|
+
return state;
|
|
4008
|
+
}
|
|
4009
|
+
};
|
|
4010
|
+
const entriesAB = `${token.a}EntriesOf${capitalize(token.b)}`;
|
|
4011
|
+
if (entriesAB in myJoin.states) {
|
|
4012
|
+
const entriesBA = `${token.b}EntriesOf${capitalize(token.a)}`;
|
|
4013
|
+
Object.assign(relations, {
|
|
4014
|
+
get [entriesAB]() {
|
|
4015
|
+
const familyAB = myJoin.states[entriesAB];
|
|
4016
|
+
const state = findInStore(store, familyAB, key);
|
|
4017
|
+
return state;
|
|
4018
|
+
},
|
|
4019
|
+
get [entriesBA]() {
|
|
4020
|
+
const familyBA = myJoin.states[entriesBA];
|
|
4021
|
+
const state = findInStore(store, familyBA, key);
|
|
4022
|
+
return state;
|
|
4023
|
+
}
|
|
4024
|
+
});
|
|
4025
|
+
}
|
|
4026
|
+
}
|
|
4027
|
+
}
|
|
4028
|
+
return relations;
|
|
4029
|
+
}
|
|
4030
|
+
|
|
4031
|
+
// internal/src/join/get-internal-relations-from-store.ts
|
|
4032
|
+
function getInternalRelationsFromStore(token, store) {
|
|
4033
|
+
const myJoin = getJoin(token, store);
|
|
4034
|
+
const family = myJoin.core.relatedKeysAtoms;
|
|
4035
|
+
return family;
|
|
4036
|
+
}
|
|
4037
|
+
|
|
3009
4038
|
// internal/src/timeline/create-timeline.ts
|
|
3010
|
-
function createTimeline(
|
|
4039
|
+
function createTimeline(store, options, data) {
|
|
3011
4040
|
const tl = {
|
|
3012
4041
|
type: `timeline`,
|
|
3013
4042
|
key: options.key,
|
|
@@ -3017,7 +4046,7 @@ function createTimeline(options, store, data) {
|
|
|
3017
4046
|
transactionKey: null,
|
|
3018
4047
|
...data,
|
|
3019
4048
|
history: data?.history.map((update) => ({ ...update })) ?? [],
|
|
3020
|
-
install: (s) => createTimeline(
|
|
4049
|
+
install: (s) => createTimeline(s, options, tl),
|
|
3021
4050
|
subject: new Subject(),
|
|
3022
4051
|
subscriptions: /* @__PURE__ */ new Map()
|
|
3023
4052
|
};
|
|
@@ -3056,7 +4085,7 @@ function createTimeline(options, store, data) {
|
|
|
3056
4085
|
);
|
|
3057
4086
|
continue;
|
|
3058
4087
|
}
|
|
3059
|
-
addAtomToTimeline(atomToken, tl
|
|
4088
|
+
addAtomToTimeline(store, atomToken, tl);
|
|
3060
4089
|
}
|
|
3061
4090
|
break;
|
|
3062
4091
|
case `atom_family`:
|
|
@@ -3074,7 +4103,7 @@ function createTimeline(options, store, data) {
|
|
|
3074
4103
|
);
|
|
3075
4104
|
continue;
|
|
3076
4105
|
}
|
|
3077
|
-
addAtomFamilyToTimeline(familyToken, tl
|
|
4106
|
+
addAtomFamilyToTimeline(store, familyToken, tl);
|
|
3078
4107
|
}
|
|
3079
4108
|
break;
|
|
3080
4109
|
}
|
|
@@ -3087,20 +4116,20 @@ function createTimeline(options, store, data) {
|
|
|
3087
4116
|
store.on.timelineCreation.next(token);
|
|
3088
4117
|
return token;
|
|
3089
4118
|
}
|
|
3090
|
-
function addAtomToTimeline(atomToken, tl
|
|
3091
|
-
let maybeAtom = withdraw(
|
|
4119
|
+
function addAtomToTimeline(store, atomToken, tl) {
|
|
4120
|
+
let maybeAtom = withdraw(store, atomToken);
|
|
3092
4121
|
if (maybeAtom.type === `mutable_atom`) {
|
|
3093
4122
|
const updateToken = getUpdateToken(maybeAtom);
|
|
3094
|
-
maybeAtom = withdraw(
|
|
4123
|
+
maybeAtom = withdraw(store, updateToken);
|
|
3095
4124
|
}
|
|
3096
|
-
const
|
|
4125
|
+
const atom2 = maybeAtom;
|
|
3097
4126
|
store.timelineTopics.set(
|
|
3098
|
-
{ topicKey:
|
|
4127
|
+
{ topicKey: atom2.key, timelineKey: tl.key },
|
|
3099
4128
|
{ topicType: `atom` }
|
|
3100
4129
|
);
|
|
3101
4130
|
tl.subscriptions.set(
|
|
3102
|
-
|
|
3103
|
-
|
|
4131
|
+
atom2.key,
|
|
4132
|
+
atom2.subject.subscribe(
|
|
3104
4133
|
`timeline`,
|
|
3105
4134
|
function timelineCapturesAtomUpdate(update) {
|
|
3106
4135
|
const target = newest(store);
|
|
@@ -3121,7 +4150,7 @@ function addAtomToTimeline(atomToken, tl, store) {
|
|
|
3121
4150
|
);
|
|
3122
4151
|
if (tl.timeTraveling === null) {
|
|
3123
4152
|
if (txUpdateInProgress) {
|
|
3124
|
-
joinTransaction(tl, txUpdateInProgress
|
|
4153
|
+
joinTransaction(store, tl, txUpdateInProgress);
|
|
3125
4154
|
} else if (currentSelectorKey && currentSelectorTime) {
|
|
3126
4155
|
let latestUpdate = tl.history.at(-1);
|
|
3127
4156
|
if (currentSelectorTime !== tl.selectorTime) {
|
|
@@ -3132,7 +4161,7 @@ function addAtomToTimeline(atomToken, tl, store) {
|
|
|
3132
4161
|
atomUpdates: []
|
|
3133
4162
|
};
|
|
3134
4163
|
latestUpdate.atomUpdates.push({
|
|
3135
|
-
key:
|
|
4164
|
+
key: atom2.key,
|
|
3136
4165
|
type: `atom_update`,
|
|
3137
4166
|
...update
|
|
3138
4167
|
});
|
|
@@ -3152,7 +4181,7 @@ function addAtomToTimeline(atomToken, tl, store) {
|
|
|
3152
4181
|
} else {
|
|
3153
4182
|
if (latestUpdate?.type === `selector_update`) {
|
|
3154
4183
|
latestUpdate.atomUpdates.push({
|
|
3155
|
-
key:
|
|
4184
|
+
key: atom2.key,
|
|
3156
4185
|
type: `atom_update`,
|
|
3157
4186
|
...update
|
|
3158
4187
|
});
|
|
@@ -3183,19 +4212,19 @@ function addAtomToTimeline(atomToken, tl, store) {
|
|
|
3183
4212
|
const atomUpdate = {
|
|
3184
4213
|
type: `atom_update`,
|
|
3185
4214
|
timestamp,
|
|
3186
|
-
key:
|
|
4215
|
+
key: atom2.key,
|
|
3187
4216
|
oldValue: update.oldValue,
|
|
3188
4217
|
newValue: update.newValue
|
|
3189
4218
|
};
|
|
3190
|
-
if (
|
|
3191
|
-
atomUpdate.family =
|
|
4219
|
+
if (atom2.family) {
|
|
4220
|
+
atomUpdate.family = atom2.family;
|
|
3192
4221
|
}
|
|
3193
4222
|
const willCapture = tl.shouldCapture?.(atomUpdate, tl) ?? true;
|
|
3194
4223
|
store.logger.info(
|
|
3195
4224
|
`\u231B`,
|
|
3196
4225
|
`timeline`,
|
|
3197
4226
|
tl.key,
|
|
3198
|
-
`got an atom_update to "${
|
|
4227
|
+
`got an atom_update to "${atom2.key}"`
|
|
3199
4228
|
);
|
|
3200
4229
|
if (willCapture) {
|
|
3201
4230
|
tl.history.push(atomUpdate);
|
|
@@ -3208,8 +4237,8 @@ function addAtomToTimeline(atomToken, tl, store) {
|
|
|
3208
4237
|
)
|
|
3209
4238
|
);
|
|
3210
4239
|
}
|
|
3211
|
-
function addAtomFamilyToTimeline(atomFamilyToken, tl
|
|
3212
|
-
const family = withdraw(
|
|
4240
|
+
function addAtomFamilyToTimeline(store, atomFamilyToken, tl) {
|
|
4241
|
+
const family = withdraw(store, atomFamilyToken);
|
|
3213
4242
|
store.timelineTopics.set(
|
|
3214
4243
|
{ topicKey: family.key, timelineKey: tl.key },
|
|
3215
4244
|
{ topicType: `atom_family` }
|
|
@@ -3219,24 +4248,24 @@ function addAtomFamilyToTimeline(atomFamilyToken, tl, store) {
|
|
|
3219
4248
|
family.subject.subscribe(
|
|
3220
4249
|
`timeline`,
|
|
3221
4250
|
function timelineCapturesStateLifecycleEvent(creationOrDisposal) {
|
|
3222
|
-
handleStateLifecycleEvent(creationOrDisposal, tl
|
|
4251
|
+
handleStateLifecycleEvent(store, creationOrDisposal, tl);
|
|
3223
4252
|
}
|
|
3224
4253
|
)
|
|
3225
4254
|
);
|
|
3226
|
-
for (const
|
|
3227
|
-
if (
|
|
3228
|
-
addAtomToTimeline(
|
|
4255
|
+
for (const atom2 of store.atoms.values()) {
|
|
4256
|
+
if (atom2.family?.key === family.key) {
|
|
4257
|
+
addAtomToTimeline(store, atom2, tl);
|
|
3229
4258
|
}
|
|
3230
4259
|
}
|
|
3231
4260
|
}
|
|
3232
|
-
function joinTransaction(tl, txUpdateInProgress
|
|
4261
|
+
function joinTransaction(store, tl, txUpdateInProgress) {
|
|
3233
4262
|
const currentTxKey = txUpdateInProgress.key;
|
|
3234
4263
|
const currentTxInstanceId = txUpdateInProgress.id;
|
|
3235
4264
|
const currentTxToken = {
|
|
3236
4265
|
key: currentTxKey,
|
|
3237
4266
|
type: `transaction`
|
|
3238
4267
|
};
|
|
3239
|
-
const currentTransaction = withdraw(
|
|
4268
|
+
const currentTransaction = withdraw(store, currentTxToken);
|
|
3240
4269
|
if (currentTxKey && tl.transactionKey === null) {
|
|
3241
4270
|
tl.transactionKey = currentTxKey;
|
|
3242
4271
|
const unsubscribe = currentTransaction.subject.subscribe(
|
|
@@ -3287,7 +4316,8 @@ function filterTransactionUpdates(updates, timelineTopics) {
|
|
|
3287
4316
|
case `molecule_transfer`:
|
|
3288
4317
|
return true;
|
|
3289
4318
|
// always include
|
|
3290
|
-
|
|
4319
|
+
case `atom_update`:
|
|
4320
|
+
case `selector_update`:
|
|
3291
4321
|
key = updateFromTx.key;
|
|
3292
4322
|
familyKey = updateFromTx.family?.key;
|
|
3293
4323
|
break;
|
|
@@ -3310,7 +4340,7 @@ function filterTransactionUpdates(updates, timelineTopics) {
|
|
|
3310
4340
|
return updateFromTx;
|
|
3311
4341
|
});
|
|
3312
4342
|
}
|
|
3313
|
-
function handleStateLifecycleEvent(event, tl
|
|
4343
|
+
function handleStateLifecycleEvent(store, event, tl) {
|
|
3314
4344
|
const timestamp = Date.now();
|
|
3315
4345
|
const timelineEvent = Object.assign(event, {
|
|
3316
4346
|
timestamp
|
|
@@ -3320,7 +4350,7 @@ function handleStateLifecycleEvent(event, tl, store) {
|
|
|
3320
4350
|
if (isChildStore(target)) ; else {
|
|
3321
4351
|
const txUpdateInProgress = target.on.transactionApplying.state;
|
|
3322
4352
|
if (txUpdateInProgress) {
|
|
3323
|
-
joinTransaction(tl, txUpdateInProgress.update
|
|
4353
|
+
joinTransaction(store, tl, txUpdateInProgress.update);
|
|
3324
4354
|
} else {
|
|
3325
4355
|
tl.history.push(timelineEvent);
|
|
3326
4356
|
tl.at = tl.history.length;
|
|
@@ -3330,7 +4360,7 @@ function handleStateLifecycleEvent(event, tl, store) {
|
|
|
3330
4360
|
}
|
|
3331
4361
|
switch (event.type) {
|
|
3332
4362
|
case `state_creation`:
|
|
3333
|
-
addAtomToTimeline(event.token, tl
|
|
4363
|
+
addAtomToTimeline(store, event.token, tl);
|
|
3334
4364
|
break;
|
|
3335
4365
|
case `state_disposal`:
|
|
3336
4366
|
tl.subscriptions.get(event.token.key)?.();
|
|
@@ -3407,4 +4437,67 @@ var timeTravel = (store, action, token) => {
|
|
|
3407
4437
|
);
|
|
3408
4438
|
};
|
|
3409
4439
|
|
|
3410
|
-
|
|
4440
|
+
// json/src/select-json.ts
|
|
4441
|
+
var selectJson = (atom2, transform, store = IMPLICIT.STORE) => {
|
|
4442
|
+
return createStandaloneSelector(store, {
|
|
4443
|
+
key: `${atom2.key}:JSON`,
|
|
4444
|
+
get: ({ get }) => transform.toJson(get(atom2)),
|
|
4445
|
+
set: ({ set }, newValue) => {
|
|
4446
|
+
set(atom2, transform.fromJson(newValue));
|
|
4447
|
+
}
|
|
4448
|
+
});
|
|
4449
|
+
};
|
|
4450
|
+
|
|
4451
|
+
// json/src/select-json-family.ts
|
|
4452
|
+
function selectJsonFamily(store, atomFamilyToken, transform) {
|
|
4453
|
+
const jsonFamily = createWritableSelectorFamily(
|
|
4454
|
+
store,
|
|
4455
|
+
{
|
|
4456
|
+
key: `${atomFamilyToken.key}:JSON`,
|
|
4457
|
+
get: (key) => ({ get }) => {
|
|
4458
|
+
const baseState = get(atomFamilyToken, key);
|
|
4459
|
+
return transform.toJson(baseState);
|
|
4460
|
+
},
|
|
4461
|
+
set: (key) => ({ set }, newValue) => {
|
|
4462
|
+
set(atomFamilyToken, key, transform.fromJson(newValue));
|
|
4463
|
+
}
|
|
4464
|
+
},
|
|
4465
|
+
[`mutable`, `json`]
|
|
4466
|
+
);
|
|
4467
|
+
return jsonFamily;
|
|
4468
|
+
}
|
|
4469
|
+
|
|
4470
|
+
// json/src/index.ts
|
|
4471
|
+
var parseJson = (str) => JSON.parse(str);
|
|
4472
|
+
var stringifyJson = (json) => JSON.stringify(json);
|
|
4473
|
+
var JSON_PROTOTYPES = [
|
|
4474
|
+
Array.prototype,
|
|
4475
|
+
Boolean.prototype,
|
|
4476
|
+
Number.prototype,
|
|
4477
|
+
Object.prototype,
|
|
4478
|
+
String.prototype
|
|
4479
|
+
];
|
|
4480
|
+
var isJson = (input) => {
|
|
4481
|
+
if (input === null) return true;
|
|
4482
|
+
if (input === void 0) return false;
|
|
4483
|
+
const prototype = Object.getPrototypeOf(input);
|
|
4484
|
+
return JSON_PROTOTYPES.includes(prototype);
|
|
4485
|
+
};
|
|
4486
|
+
var JSON_TYPE_NAMES = [
|
|
4487
|
+
`array`,
|
|
4488
|
+
`boolean`,
|
|
4489
|
+
`null`,
|
|
4490
|
+
`number`,
|
|
4491
|
+
`object`,
|
|
4492
|
+
`string`
|
|
4493
|
+
];
|
|
4494
|
+
var JSON_DEFAULTS = {
|
|
4495
|
+
array: [],
|
|
4496
|
+
boolean: false,
|
|
4497
|
+
null: null,
|
|
4498
|
+
number: 0,
|
|
4499
|
+
object: {},
|
|
4500
|
+
string: ``
|
|
4501
|
+
};
|
|
4502
|
+
|
|
4503
|
+
export { $claim, Anarchy, AtomIOLogger, CircularBuffer, FAMILY_MEMBER_TOKEN_TYPES, FamilyTracker, Future, IMPLICIT, JSON_DEFAULTS, JSON_TYPE_NAMES, Join, Junction, LOG_LEVELS, LazyMap, NotFoundError, Realm, SetRTX, Silo, StatefulSubject, Store, Subject, T$, TRANSACTION_PHASES, Tracker, abortTransaction, actUponStore, allocateIntoStore, applyTransaction, arbitrary, assignTransactionToContinuity, atom, atomFamily, become, belongsTo, buildTransaction, cacheValue, capitalize, claimWithinStore, clearStore, closeOperation, counterfeit, createAtomFamily, createMutableAtom, createMutableAtomFamily, createReadonlySelector, createReadonlySelectorFamily, createRegularAtom, createRegularAtomFamily, createSelectorFamily, createStandaloneAtom, createStandaloneSelector, createTimeline, createTransaction, createWritableSelector, deallocateFromStore, deposit, disposeAtom, disposeFromStore, disposeSelector, disposeState, editRelations, editRelationsInStore, evictCachedValue, findInStore, findRelations, findRelationsInStore, findState, fromEntries, fuseWithinStore, getContinuityKey, getEnvironmentData, getEpochNumberOfAction, getEpochNumberOfContinuity, getFromStore, getInternalRelations, getInternalRelationsFromStore, getJoin, getJsonFamily, getJsonToken, getSelectorDependencyKeys, getState, getTrace, getUpdateFamily, getUpdateToken, ingestAtomUpdate, ingestCreationEvent, ingestDisposalEvent, ingestMoleculeCreationEvent, ingestMoleculeDisposalEvent, ingestMoleculeTransferEvent, ingestSelectorUpdate, ingestTransactionUpdate, initFamilyMemberInStore, isAtomDefault, isAtomKey, isChildStore, isDone, isJson, isReadonlySelectorKey, isRootStore, isSelectorKey, isStateKey, isToken, isTransceiver, join, makeRootMoleculeInStore, markAtomAsDefault, markAtomAsNotDefault, markDone, newest, openOperation, parseJson, prettyPrintTokenType, readCachedValue, readOrComputeValue, recallState, redo, registerSelector, runTransaction, seekInStore, selectJson, selectJsonFamily, selector, selectorFamily, setAtomOrSelector, setEpochNumberOfAction, setEpochNumberOfContinuity, setIntoStore, setState, simpleLog, simpleLogger, stringifyJson, subscribe, subscribeInStore, subscribeToRootAtoms, subscribeToState, subscribeToTimeline, subscribeToTransaction, timeTravel, timeline, toEntries, traceAllSelectorAtoms, traceSelectorAtoms, transaction, undo, updateSelectorAtoms, withdraw };
|