atom.io 0.31.1 → 0.32.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/data/dist/index.d.ts +867 -101
- package/data/dist/index.js +10 -558
- 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-354XQWHH.js +153 -0
- package/dist/chunk-4LWKCEW3.js +14 -0
- package/dist/chunk-5F2V7S3B.js +83 -0
- package/dist/chunk-ECOMOMUN.js +631 -0
- package/dist/{chunk-Y5MBNTVU.js → chunk-GY2XQYZY.js} +1791 -703
- package/dist/chunk-NF7FJKJD.js +107 -0
- package/dist/chunk-R3ZUK5EH.js +1024 -0
- package/dist/chunk-Z2UJW4NQ.js +523 -0
- package/dist/index.d.ts +622 -26
- package/dist/index.js +1 -228
- package/eslint-plugin/dist/index.d.ts +1 -30
- package/eslint-plugin/dist/index.js +0 -146
- package/eslint-plugin/src/index.ts +0 -1
- package/eslint-plugin/src/rules/index.ts +0 -1
- package/internal/dist/index.d.ts +783 -64
- 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} +20 -429
- 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 +1 -1
- 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 +17 -37
- 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.d.ts +922 -6
- package/introspection/dist/index.js +2 -620
- package/json/dist/index.d.ts +899 -5
- package/json/dist/index.js +1 -80
- package/json/src/select-json-family.ts +3 -14
- package/package.json +24 -42
- package/react/dist/index.d.ts +921 -3
- 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.d.ts +26 -1
- package/react-devtools/dist/index.js +6 -6
- package/react-devtools/src/devtools.scss +16 -14
- package/realtime/dist/index.d.ts +202 -8
- package/realtime/dist/index.js +2 -107
- package/realtime/src/realtime-continuity.ts +2 -2
- package/realtime/src/shared-room-store.ts +1 -2
- package/realtime-client/dist/index.d.ts +960 -22
- 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.d.ts +166 -12
- 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 +971 -28
- 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/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-user-store.ts +1 -2
- package/realtime-server/src/realtime-state-provider.ts +2 -2
- package/realtime-testing/dist/index.d.ts +1091 -3
- 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 +37 -2
- package/transceivers/set-rtx/dist/index.js +1 -215
- package/web/dist/index.d.ts +30 -1
- 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/{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) {
|
|
@@ -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(
|
|
@@ -646,13 +468,13 @@ var emitUpdate = (state, update, store) => {
|
|
|
646
468
|
};
|
|
647
469
|
|
|
648
470
|
// internal/src/set-state/evict-downstream.ts
|
|
649
|
-
var evictDownStream = (
|
|
471
|
+
var evictDownStream = (store, atom2) => {
|
|
650
472
|
const target = newest(store);
|
|
651
|
-
const downstreamKeys = target.selectorAtoms.getRelatedKeys(
|
|
473
|
+
const downstreamKeys = target.selectorAtoms.getRelatedKeys(atom2.key);
|
|
652
474
|
target.logger.info(
|
|
653
475
|
`\u{1F9F9}`,
|
|
654
|
-
|
|
655
|
-
|
|
476
|
+
atom2.type,
|
|
477
|
+
atom2.key,
|
|
656
478
|
downstreamKeys ? `evicting ${downstreamKeys.size} states downstream:` : `no downstream states`,
|
|
657
479
|
downstreamKeys ?? `to evict`
|
|
658
480
|
);
|
|
@@ -660,8 +482,8 @@ var evictDownStream = (atom, store) => {
|
|
|
660
482
|
if (target.operation.open) {
|
|
661
483
|
target.logger.info(
|
|
662
484
|
`\u{1F9F9}`,
|
|
663
|
-
|
|
664
|
-
|
|
485
|
+
atom2.type,
|
|
486
|
+
atom2.key,
|
|
665
487
|
`[ ${[...target.operation.done].join(`, `)} ] already done`
|
|
666
488
|
);
|
|
667
489
|
}
|
|
@@ -685,7 +507,7 @@ function shouldUpdateBeStowed(key, update) {
|
|
|
685
507
|
}
|
|
686
508
|
return true;
|
|
687
509
|
}
|
|
688
|
-
var stowUpdate = (state, update
|
|
510
|
+
var stowUpdate = (store, state, update) => {
|
|
689
511
|
const { key } = state;
|
|
690
512
|
const target = newest(store);
|
|
691
513
|
if (!isChildStore(target) || target.transactionMeta.phase !== `building`) {
|
|
@@ -723,45 +545,45 @@ var stowUpdate = (state, update, store) => {
|
|
|
723
545
|
};
|
|
724
546
|
|
|
725
547
|
// internal/src/set-state/set-atom.ts
|
|
726
|
-
var setAtom = (
|
|
727
|
-
const oldValue = readOrComputeValue(
|
|
548
|
+
var setAtom = (atom2, next, target) => {
|
|
549
|
+
const oldValue = readOrComputeValue(target, atom2);
|
|
728
550
|
let newValue = oldValue;
|
|
729
|
-
if (
|
|
551
|
+
if (atom2.type === `mutable_atom` && isChildStore(target)) {
|
|
730
552
|
const { parent } = target;
|
|
731
|
-
const copiedValue = copyMutableIfNeeded(
|
|
553
|
+
const copiedValue = copyMutableIfNeeded(target, atom2, parent);
|
|
732
554
|
newValue = copiedValue;
|
|
733
555
|
}
|
|
734
556
|
newValue = become(next)(newValue);
|
|
735
|
-
target.logger.info(`\u{1F4DD}`, `atom`,
|
|
736
|
-
newValue = cacheValue(
|
|
737
|
-
if (isAtomDefault(
|
|
738
|
-
markAtomAsNotDefault(
|
|
557
|
+
target.logger.info(`\u{1F4DD}`, `atom`, atom2.key, `set to`, newValue);
|
|
558
|
+
newValue = cacheValue(target, atom2.key, newValue, atom2.subject);
|
|
559
|
+
if (isAtomDefault(target, atom2.key)) {
|
|
560
|
+
markAtomAsNotDefault(target, atom2.key);
|
|
739
561
|
}
|
|
740
|
-
markDone(target,
|
|
741
|
-
evictDownStream(
|
|
562
|
+
markDone(target, atom2.key);
|
|
563
|
+
evictDownStream(target, atom2);
|
|
742
564
|
const update = { oldValue, newValue };
|
|
743
565
|
if (isRootStore(target)) {
|
|
744
|
-
emitUpdate(
|
|
566
|
+
emitUpdate(target, atom2, update);
|
|
745
567
|
} else if (target.parent) {
|
|
746
568
|
if (target.on.transactionApplying.state === null) {
|
|
747
|
-
stowUpdate(
|
|
748
|
-
} else if (
|
|
749
|
-
const mutableKey =
|
|
569
|
+
stowUpdate(target, atom2, update);
|
|
570
|
+
} else if (atom2.key.startsWith(`*`)) {
|
|
571
|
+
const mutableKey = atom2.key.slice(1);
|
|
750
572
|
const mutableAtom = target.atoms.get(mutableKey);
|
|
751
573
|
let transceiver = target.valueMap.get(mutableKey);
|
|
752
574
|
if (mutableAtom.type === `mutable_atom` && isChildStore(target)) {
|
|
753
575
|
const { parent } = target;
|
|
754
|
-
const copiedValue = copyMutableIfNeeded(mutableAtom, parent
|
|
576
|
+
const copiedValue = copyMutableIfNeeded(target, mutableAtom, parent);
|
|
755
577
|
transceiver = copiedValue;
|
|
756
578
|
}
|
|
757
579
|
const accepted = transceiver.do(update.newValue) === null;
|
|
758
|
-
if (accepted) evictDownStream(
|
|
580
|
+
if (accepted) evictDownStream(target, mutableAtom);
|
|
759
581
|
}
|
|
760
582
|
}
|
|
761
583
|
};
|
|
762
584
|
|
|
763
585
|
// internal/src/set-state/set-atom-or-selector.ts
|
|
764
|
-
var setAtomOrSelector = (state, value
|
|
586
|
+
var setAtomOrSelector = (store, state, value) => {
|
|
765
587
|
switch (state.type) {
|
|
766
588
|
case `atom`:
|
|
767
589
|
case `mutable_atom`:
|
|
@@ -772,6 +594,41 @@ var setAtomOrSelector = (state, value, store) => {
|
|
|
772
594
|
break;
|
|
773
595
|
}
|
|
774
596
|
};
|
|
597
|
+
|
|
598
|
+
// internal/src/subject.ts
|
|
599
|
+
var Subject = class {
|
|
600
|
+
Subscriber;
|
|
601
|
+
subscribers = /* @__PURE__ */ new Map();
|
|
602
|
+
subscribe(key, subscriber) {
|
|
603
|
+
this.subscribers.set(key, subscriber);
|
|
604
|
+
const unsubscribe = () => {
|
|
605
|
+
this.unsubscribe(key);
|
|
606
|
+
};
|
|
607
|
+
return unsubscribe;
|
|
608
|
+
}
|
|
609
|
+
unsubscribe(key) {
|
|
610
|
+
this.subscribers.delete(key);
|
|
611
|
+
}
|
|
612
|
+
next(value) {
|
|
613
|
+
const subscribers = this.subscribers.values();
|
|
614
|
+
for (const subscriber of subscribers) {
|
|
615
|
+
subscriber(value);
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
};
|
|
619
|
+
var StatefulSubject = class extends Subject {
|
|
620
|
+
state;
|
|
621
|
+
constructor(initialState) {
|
|
622
|
+
super();
|
|
623
|
+
this.state = initialState;
|
|
624
|
+
}
|
|
625
|
+
next(value) {
|
|
626
|
+
this.state = value;
|
|
627
|
+
super.next(value);
|
|
628
|
+
}
|
|
629
|
+
};
|
|
630
|
+
|
|
631
|
+
// internal/src/families/create-regular-atom-family.ts
|
|
775
632
|
function createRegularAtomFamily(store, options, internalRoles) {
|
|
776
633
|
const familyToken = {
|
|
777
634
|
key: options.key,
|
|
@@ -806,12 +663,12 @@ function createRegularAtomFamily(store, options, internalRoles) {
|
|
|
806
663
|
subject.next({ type: `state_creation`, token });
|
|
807
664
|
return token;
|
|
808
665
|
};
|
|
809
|
-
const
|
|
666
|
+
const atomFamily2 = Object.assign(familyFunction, familyToken, {
|
|
810
667
|
subject,
|
|
811
668
|
install: (s) => createRegularAtomFamily(s, options),
|
|
812
669
|
internalRoles
|
|
813
670
|
});
|
|
814
|
-
store.families.set(options.key,
|
|
671
|
+
store.families.set(options.key, atomFamily2);
|
|
815
672
|
store.defaults.set(options.key, options.default);
|
|
816
673
|
return familyToken;
|
|
817
674
|
}
|
|
@@ -826,14 +683,14 @@ function createAtomFamily(store, options) {
|
|
|
826
683
|
}
|
|
827
684
|
|
|
828
685
|
// internal/src/keys.ts
|
|
829
|
-
var isAtomKey = (
|
|
830
|
-
var isSelectorKey = (
|
|
831
|
-
var isReadonlySelectorKey = (
|
|
832
|
-
var isStateKey = (
|
|
686
|
+
var isAtomKey = (store, key) => newest(store).atoms.has(key);
|
|
687
|
+
var isSelectorKey = (store, key) => newest(store).selectors.has(key);
|
|
688
|
+
var isReadonlySelectorKey = (store, key) => newest(store).readonlySelectors.has(key);
|
|
689
|
+
var isStateKey = (store, key) => isAtomKey(store, key) || isSelectorKey(store, key) || isReadonlySelectorKey(store, key);
|
|
833
690
|
|
|
834
691
|
// internal/src/selector/get-selector-dependency-keys.ts
|
|
835
692
|
var getSelectorDependencyKeys = (key, store) => {
|
|
836
|
-
const sources = newest(store).selectorGraph.getRelationEntries({ downstreamSelectorKey: key }).filter(([_, { source }]) => source !== key).map(([_, { source }]) => source).filter((source) => isStateKey(
|
|
693
|
+
const sources = newest(store).selectorGraph.getRelationEntries({ downstreamSelectorKey: key }).filter(([_, { source }]) => source !== key).map(([_, { source }]) => source).filter((source) => isStateKey(store, source));
|
|
837
694
|
return sources;
|
|
838
695
|
};
|
|
839
696
|
|
|
@@ -850,7 +707,7 @@ var traceSelectorAtoms = (directDependencyKey, covered, store) => {
|
|
|
850
707
|
continue;
|
|
851
708
|
}
|
|
852
709
|
covered.add(indirectDependencyKey);
|
|
853
|
-
if (!isAtomKey(
|
|
710
|
+
if (!isAtomKey(store, indirectDependencyKey)) {
|
|
854
711
|
indirectDependencyKeys.push(
|
|
855
712
|
...getSelectorDependencyKeys(indirectDependencyKey, store)
|
|
856
713
|
);
|
|
@@ -860,12 +717,12 @@ var traceSelectorAtoms = (directDependencyKey, covered, store) => {
|
|
|
860
717
|
}
|
|
861
718
|
return rootKeys;
|
|
862
719
|
};
|
|
863
|
-
var traceAllSelectorAtoms = (
|
|
864
|
-
const selectorKey =
|
|
720
|
+
var traceAllSelectorAtoms = (selector2, store) => {
|
|
721
|
+
const selectorKey = selector2.key;
|
|
865
722
|
const directDependencyKeys = getSelectorDependencyKeys(selectorKey, store);
|
|
866
723
|
const covered = /* @__PURE__ */ new Set();
|
|
867
724
|
return directDependencyKeys.flatMap(
|
|
868
|
-
(depKey) => isAtomKey(
|
|
725
|
+
(depKey) => isAtomKey(store, depKey) ? depKey : traceSelectorAtoms(depKey, covered, store)
|
|
869
726
|
);
|
|
870
727
|
};
|
|
871
728
|
|
|
@@ -912,8 +769,8 @@ var registerSelector = (selectorKey, covered, store) => ({
|
|
|
912
769
|
} else {
|
|
913
770
|
[dependency] = params;
|
|
914
771
|
}
|
|
915
|
-
const dependencyState = withdraw(
|
|
916
|
-
const dependencyValue = readOrComputeValue(
|
|
772
|
+
const dependencyState = withdraw(store, dependency);
|
|
773
|
+
const dependencyValue = readOrComputeValue(store, dependencyState);
|
|
917
774
|
store.logger.info(
|
|
918
775
|
`\u{1F50C}`,
|
|
919
776
|
`selector`,
|
|
@@ -947,11 +804,10 @@ var registerSelector = (selectorKey, covered, store) => ({
|
|
|
947
804
|
token = findInStore(store, family, key);
|
|
948
805
|
}
|
|
949
806
|
const target = newest(store);
|
|
950
|
-
const state = withdraw(
|
|
951
|
-
setAtomOrSelector(state, value
|
|
807
|
+
const state = withdraw(target, token);
|
|
808
|
+
setAtomOrSelector(target, state, value);
|
|
952
809
|
},
|
|
953
810
|
find: (token, key) => findInStore(store, token, key),
|
|
954
|
-
seek: (token, key) => seekInStore(store, token, key),
|
|
955
811
|
json: (token) => getJsonToken(store, token)
|
|
956
812
|
});
|
|
957
813
|
|
|
@@ -960,14 +816,10 @@ var createReadonlySelector = (store, options, family) => {
|
|
|
960
816
|
const target = newest(store);
|
|
961
817
|
const subject = new Subject();
|
|
962
818
|
const covered = /* @__PURE__ */ new Set();
|
|
963
|
-
const { get, find,
|
|
964
|
-
options.key,
|
|
965
|
-
covered,
|
|
966
|
-
target
|
|
967
|
-
);
|
|
819
|
+
const { get, find, json } = registerSelector(options.key, covered, target);
|
|
968
820
|
const getSelf = () => {
|
|
969
|
-
const value = options.get({ get, find,
|
|
970
|
-
cacheValue(options.key, value, subject
|
|
821
|
+
const value = options.get({ get, find, json });
|
|
822
|
+
cacheValue(newest(store), options.key, value, subject);
|
|
971
823
|
covered.clear();
|
|
972
824
|
return value;
|
|
973
825
|
};
|
|
@@ -1004,11 +856,11 @@ var createWritableSelector = (store, options, family) => {
|
|
|
1004
856
|
const subject = new Subject();
|
|
1005
857
|
const covered = /* @__PURE__ */ new Set();
|
|
1006
858
|
const setterToolkit = registerSelector(options.key, covered, target);
|
|
1007
|
-
const { find, get,
|
|
1008
|
-
const getterToolkit = { find, get,
|
|
859
|
+
const { find, get, json } = setterToolkit;
|
|
860
|
+
const getterToolkit = { find, get, json };
|
|
1009
861
|
const getSelf = (getFn = options.get, innerTarget = newest(store)) => {
|
|
1010
862
|
const value = getFn(getterToolkit);
|
|
1011
|
-
cacheValue(options.key, value, subject
|
|
863
|
+
cacheValue(innerTarget, options.key, value, subject);
|
|
1012
864
|
covered.clear();
|
|
1013
865
|
return value;
|
|
1014
866
|
};
|
|
@@ -1026,7 +878,7 @@ var createWritableSelector = (store, options, family) => {
|
|
|
1026
878
|
newValue,
|
|
1027
879
|
`)`
|
|
1028
880
|
);
|
|
1029
|
-
cacheValue(options.key, newValue, subject
|
|
881
|
+
cacheValue(innerTarget, options.key, newValue, subject);
|
|
1030
882
|
markDone(innerTarget, options.key);
|
|
1031
883
|
if (isRootStore(innerTarget)) {
|
|
1032
884
|
subject.next({ newValue, oldValue });
|
|
@@ -1069,11 +921,11 @@ function createStandaloneSelector(store, options) {
|
|
|
1069
921
|
}
|
|
1070
922
|
|
|
1071
923
|
// internal/src/selector/dispose-selector.ts
|
|
1072
|
-
function disposeSelector(
|
|
924
|
+
function disposeSelector(store, selectorToken) {
|
|
1073
925
|
const target = newest(store);
|
|
1074
926
|
const { key } = selectorToken;
|
|
1075
|
-
const
|
|
1076
|
-
if (!
|
|
927
|
+
const selector2 = withdraw(target, selectorToken);
|
|
928
|
+
if (!selector2.family) {
|
|
1077
929
|
store.logger.error(
|
|
1078
930
|
`\u274C`,
|
|
1079
931
|
`selector`,
|
|
@@ -1081,27 +933,35 @@ function disposeSelector(selectorToken, store) {
|
|
|
1081
933
|
`Standalone selectors cannot be disposed.`
|
|
1082
934
|
);
|
|
1083
935
|
} else {
|
|
1084
|
-
const molecule = target.molecules.get(
|
|
936
|
+
const molecule = target.molecules.get(selector2.family.subKey);
|
|
1085
937
|
if (molecule) {
|
|
1086
|
-
target.moleculeData.delete(
|
|
938
|
+
target.moleculeData.delete(selector2.family.subKey, selector2.family.key);
|
|
1087
939
|
}
|
|
940
|
+
let familyToken;
|
|
1088
941
|
switch (selectorToken.type) {
|
|
1089
942
|
case `selector`:
|
|
1090
943
|
{
|
|
1091
944
|
target.selectors.delete(key);
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
945
|
+
familyToken = {
|
|
946
|
+
key: selector2.family.key,
|
|
947
|
+
type: `selector_family`
|
|
948
|
+
};
|
|
949
|
+
const family = withdraw(store, familyToken);
|
|
950
|
+
family.subject.next({
|
|
951
|
+
type: `state_disposal`,
|
|
952
|
+
subType: `selector`,
|
|
953
|
+
token: selectorToken
|
|
954
|
+
});
|
|
1096
955
|
}
|
|
1097
956
|
break;
|
|
1098
957
|
case `readonly_selector`:
|
|
1099
958
|
{
|
|
1100
959
|
target.readonlySelectors.delete(key);
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
960
|
+
familyToken = {
|
|
961
|
+
key: selector2.family.key,
|
|
962
|
+
type: `readonly_selector_family`
|
|
963
|
+
};
|
|
964
|
+
const family = withdraw(store, familyToken);
|
|
1105
965
|
family.subject.next({
|
|
1106
966
|
type: `state_disposal`,
|
|
1107
967
|
subType: `selector`,
|
|
@@ -1167,9 +1027,8 @@ function createReadonlySelectorFamily(store, options, internalRoles) {
|
|
|
1167
1027
|
default: (key) => {
|
|
1168
1028
|
const getFn = options.get(key);
|
|
1169
1029
|
return getFn({
|
|
1170
|
-
get: (...
|
|
1171
|
-
find: (
|
|
1172
|
-
seek: (token, k) => seekInStore(store, token, k),
|
|
1030
|
+
get: (...args) => getFromStore(store, ...args),
|
|
1031
|
+
find: (...args) => findInStore(store, ...args),
|
|
1173
1032
|
json: (token) => getJsonToken(store, token)
|
|
1174
1033
|
});
|
|
1175
1034
|
}
|
|
@@ -1177,6 +1036,8 @@ function createReadonlySelectorFamily(store, options, internalRoles) {
|
|
|
1177
1036
|
store.families.set(options.key, readonlySelectorFamily);
|
|
1178
1037
|
return familyToken;
|
|
1179
1038
|
}
|
|
1039
|
+
|
|
1040
|
+
// internal/src/families/create-writable-selector-family.ts
|
|
1180
1041
|
function createWritableSelectorFamily(store, options, internalRoles) {
|
|
1181
1042
|
const familyToken = {
|
|
1182
1043
|
key: options.key,
|
|
@@ -1211,7 +1072,7 @@ function createWritableSelectorFamily(store, options, internalRoles) {
|
|
|
1211
1072
|
subject.next({ type: `state_creation`, token });
|
|
1212
1073
|
return token;
|
|
1213
1074
|
};
|
|
1214
|
-
const
|
|
1075
|
+
const selectorFamily2 = Object.assign(familyFunction, familyToken, {
|
|
1215
1076
|
internalRoles,
|
|
1216
1077
|
subject,
|
|
1217
1078
|
install: (s) => createWritableSelectorFamily(s, options),
|
|
@@ -1220,12 +1081,11 @@ function createWritableSelectorFamily(store, options, internalRoles) {
|
|
|
1220
1081
|
return getFn({
|
|
1221
1082
|
get: (...ps) => getFromStore(store, ...ps),
|
|
1222
1083
|
find: (token, k) => findInStore(store, token, k),
|
|
1223
|
-
seek: (token, k) => seekInStore(store, token, k),
|
|
1224
1084
|
json: (token) => getJsonToken(store, token)
|
|
1225
1085
|
});
|
|
1226
1086
|
}
|
|
1227
1087
|
});
|
|
1228
|
-
store.families.set(options.key,
|
|
1088
|
+
store.families.set(options.key, selectorFamily2);
|
|
1229
1089
|
return familyToken;
|
|
1230
1090
|
}
|
|
1231
1091
|
|
|
@@ -1267,6 +1127,8 @@ function initFamilyMemberInStore(store, token, key) {
|
|
|
1267
1127
|
}
|
|
1268
1128
|
return state;
|
|
1269
1129
|
}
|
|
1130
|
+
|
|
1131
|
+
// internal/src/families/seek-in-store.ts
|
|
1270
1132
|
function seekInStore(store, token, key) {
|
|
1271
1133
|
const subKey = stringifyJson(key);
|
|
1272
1134
|
const fullKey = `${token.key}(${subKey})`;
|
|
@@ -1328,27 +1190,24 @@ function disposeFromStore(store, ...params) {
|
|
|
1328
1190
|
token = maybeToken;
|
|
1329
1191
|
}
|
|
1330
1192
|
try {
|
|
1331
|
-
withdraw(
|
|
1193
|
+
withdraw(store, token);
|
|
1332
1194
|
} catch (thrown) {
|
|
1333
1195
|
store.logger.error(
|
|
1334
1196
|
`\u274C`,
|
|
1335
1197
|
token.type,
|
|
1336
1198
|
token.key,
|
|
1337
1199
|
`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
1200
|
);
|
|
1342
1201
|
return;
|
|
1343
1202
|
}
|
|
1344
1203
|
switch (token.type) {
|
|
1345
1204
|
case `atom`:
|
|
1346
1205
|
case `mutable_atom`:
|
|
1347
|
-
disposeAtom(
|
|
1206
|
+
disposeAtom(store, token);
|
|
1348
1207
|
break;
|
|
1349
1208
|
case `selector`:
|
|
1350
1209
|
case `readonly_selector`:
|
|
1351
|
-
disposeSelector(
|
|
1210
|
+
disposeSelector(store, token);
|
|
1352
1211
|
break;
|
|
1353
1212
|
}
|
|
1354
1213
|
}
|
|
@@ -1415,8 +1274,8 @@ ${disposal.trace}` : `No previous disposal trace was found.`
|
|
|
1415
1274
|
);
|
|
1416
1275
|
return;
|
|
1417
1276
|
}
|
|
1418
|
-
const state = withdraw(
|
|
1419
|
-
setAtomOrSelector(state, value
|
|
1277
|
+
const state = withdraw(store, token);
|
|
1278
|
+
setAtomOrSelector(store, state, value);
|
|
1420
1279
|
closeOperation(store);
|
|
1421
1280
|
}
|
|
1422
1281
|
|
|
@@ -1543,10 +1402,10 @@ ${disposal.trace}` : `No previous disposal trace for ${stringKey} was found.`
|
|
|
1543
1402
|
);
|
|
1544
1403
|
if (joinKeys) {
|
|
1545
1404
|
for (const joinKey of joinKeys) {
|
|
1546
|
-
const
|
|
1547
|
-
if (
|
|
1548
|
-
|
|
1549
|
-
|
|
1405
|
+
const join2 = store.joins.get(joinKey);
|
|
1406
|
+
if (join2) {
|
|
1407
|
+
join2.relations.delete(molecule.key);
|
|
1408
|
+
join2.molecules.delete(molecule.stringKey);
|
|
1550
1409
|
}
|
|
1551
1410
|
}
|
|
1552
1411
|
}
|
|
@@ -1795,138 +1654,449 @@ function ingestTransactionUpdate(applying, transactionUpdate, store) {
|
|
|
1795
1654
|
break;
|
|
1796
1655
|
}
|
|
1797
1656
|
}
|
|
1798
|
-
}
|
|
1799
|
-
|
|
1800
|
-
// internal/src/transaction/set-epoch-number.ts
|
|
1801
|
-
function setEpochNumberOfContinuity(continuityKey, newEpoch
|
|
1802
|
-
const isRoot = isRootStore(store);
|
|
1803
|
-
if (isRoot && continuityKey) {
|
|
1804
|
-
store.transactionMeta.epoch.set(continuityKey, newEpoch);
|
|
1805
|
-
}
|
|
1806
|
-
}
|
|
1807
|
-
function setEpochNumberOfAction(transactionKey, newEpoch
|
|
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
|
-
|
|
1847
|
-
child.transactionMeta.update.
|
|
1848
|
-
|
|
1849
|
-
);
|
|
1850
|
-
const myTransaction = withdraw(
|
|
1851
|
-
|
|
1852
|
-
|
|
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.`
|
|
1657
|
+
}
|
|
1658
|
+
|
|
1659
|
+
// internal/src/transaction/set-epoch-number.ts
|
|
1660
|
+
function setEpochNumberOfContinuity(store, continuityKey, newEpoch) {
|
|
1661
|
+
const isRoot = isRootStore(store);
|
|
1662
|
+
if (isRoot && continuityKey) {
|
|
1663
|
+
store.transactionMeta.epoch.set(continuityKey, newEpoch);
|
|
1664
|
+
}
|
|
1665
|
+
}
|
|
1666
|
+
function setEpochNumberOfAction(store, transactionKey, newEpoch) {
|
|
1667
|
+
const isRoot = isRootStore(store);
|
|
1668
|
+
if (!isRoot) {
|
|
1669
|
+
return;
|
|
1670
|
+
}
|
|
1671
|
+
const continuityKey = store.transactionMeta.actionContinuities.getRelatedKey(transactionKey);
|
|
1672
|
+
if (continuityKey !== undefined) {
|
|
1673
|
+
store.transactionMeta.epoch.set(continuityKey, newEpoch);
|
|
1674
|
+
}
|
|
1675
|
+
}
|
|
1676
|
+
|
|
1677
|
+
// internal/src/transaction/apply-transaction.ts
|
|
1678
|
+
var applyTransaction = (output, store) => {
|
|
1679
|
+
const child = newest(store);
|
|
1680
|
+
const { parent } = child;
|
|
1681
|
+
if (parent === null || !isChildStore(child) || child.transactionMeta?.phase !== `building`) {
|
|
1682
|
+
store.logger.warn(
|
|
1683
|
+
`\u{1F41E}`,
|
|
1684
|
+
`transaction`,
|
|
1685
|
+
`???`,
|
|
1686
|
+
`applyTransaction called outside of a transaction. This is probably a bug in AtomIO.`
|
|
1687
|
+
);
|
|
1688
|
+
return;
|
|
1689
|
+
}
|
|
1690
|
+
child.transactionMeta.phase = `applying`;
|
|
1691
|
+
child.transactionMeta.update.output = output;
|
|
1692
|
+
parent.child = null;
|
|
1693
|
+
parent.on.transactionApplying.next(child.transactionMeta);
|
|
1694
|
+
const { updates } = child.transactionMeta.update;
|
|
1695
|
+
store.logger.info(
|
|
1696
|
+
`\u{1F6C4}`,
|
|
1697
|
+
`transaction`,
|
|
1698
|
+
child.transactionMeta.update.key,
|
|
1699
|
+
`Applying transaction with ${updates.length} updates:`,
|
|
1700
|
+
updates
|
|
1701
|
+
);
|
|
1702
|
+
ingestTransactionUpdate(`newValue`, child.transactionMeta.update, parent);
|
|
1703
|
+
if (isRootStore(parent)) {
|
|
1704
|
+
setEpochNumberOfAction(
|
|
1705
|
+
parent,
|
|
1706
|
+
child.transactionMeta.update.key,
|
|
1707
|
+
child.transactionMeta.update.epoch
|
|
1708
|
+
);
|
|
1709
|
+
const myTransaction = withdraw(store, {
|
|
1710
|
+
key: child.transactionMeta.update.key,
|
|
1711
|
+
type: `transaction`
|
|
1712
|
+
});
|
|
1713
|
+
myTransaction?.subject.next(child.transactionMeta.update);
|
|
1714
|
+
store.logger.info(
|
|
1715
|
+
`\u{1F6EC}`,
|
|
1716
|
+
`transaction`,
|
|
1717
|
+
child.transactionMeta.update.key,
|
|
1718
|
+
`Finished applying transaction.`
|
|
1719
|
+
);
|
|
1720
|
+
} else if (isChildStore(parent)) {
|
|
1721
|
+
parent.transactionMeta.update.updates.push(child.transactionMeta.update);
|
|
1722
|
+
}
|
|
1723
|
+
parent.on.transactionApplying.next(null);
|
|
1724
|
+
};
|
|
1725
|
+
|
|
1726
|
+
// internal/src/transaction/assign-transaction-to-continuity.ts
|
|
1727
|
+
function assignTransactionToContinuity(store, continuityKey, transactionKey) {
|
|
1728
|
+
const isRoot = isRootStore(store);
|
|
1729
|
+
if (!isRoot) {
|
|
1730
|
+
return;
|
|
1731
|
+
}
|
|
1732
|
+
const { epoch, actionContinuities } = store.transactionMeta;
|
|
1733
|
+
actionContinuities.set(continuityKey, transactionKey);
|
|
1734
|
+
if (!epoch.has(continuityKey)) {
|
|
1735
|
+
epoch.set(continuityKey, -1);
|
|
1736
|
+
}
|
|
1737
|
+
}
|
|
1738
|
+
|
|
1739
|
+
// internal/src/get-environment-data.ts
|
|
1740
|
+
function getEnvironmentData(store) {
|
|
1741
|
+
return {
|
|
1742
|
+
store
|
|
1743
|
+
};
|
|
1744
|
+
}
|
|
1745
|
+
|
|
1746
|
+
// internal/src/get-state/get-from-store.ts
|
|
1747
|
+
function getFromStore(store, ...params) {
|
|
1748
|
+
let token;
|
|
1749
|
+
let family;
|
|
1750
|
+
let key;
|
|
1751
|
+
if (params.length === 1) {
|
|
1752
|
+
token = params[0];
|
|
1753
|
+
} else {
|
|
1754
|
+
family = params[0];
|
|
1755
|
+
key = params[1];
|
|
1756
|
+
token = findInStore(store, family, key);
|
|
1757
|
+
}
|
|
1758
|
+
if (`counterfeit` in token && `family` in token) {
|
|
1759
|
+
family = store.families.get(token.family.key);
|
|
1760
|
+
const subKey = token.family.subKey;
|
|
1761
|
+
const disposal = store.disposalTraces.buffer.find(
|
|
1762
|
+
(item) => item?.key === subKey
|
|
1763
|
+
);
|
|
1764
|
+
store.logger.error(
|
|
1765
|
+
`\u274C`,
|
|
1766
|
+
token.type,
|
|
1767
|
+
token.key,
|
|
1768
|
+
`could not be retrieved because it was not found in the store "${store.config.name}".`,
|
|
1769
|
+
disposal ? `This state was previously disposed:
|
|
1770
|
+
${disposal.trace}` : `No previous disposal trace was found.`
|
|
1771
|
+
);
|
|
1772
|
+
switch (family.type) {
|
|
1773
|
+
case `atom_family`:
|
|
1774
|
+
case `mutable_atom_family`:
|
|
1775
|
+
return store.defaults.get(family.key);
|
|
1776
|
+
case `selector_family`:
|
|
1777
|
+
case `readonly_selector_family`: {
|
|
1778
|
+
if (store.defaults.has(family.key)) {
|
|
1779
|
+
return store.defaults.get(token.family.key);
|
|
1780
|
+
}
|
|
1781
|
+
const defaultValue = withdraw(store, family).default(subKey);
|
|
1782
|
+
store.defaults.set(family.key, defaultValue);
|
|
1783
|
+
return defaultValue;
|
|
1784
|
+
}
|
|
1785
|
+
}
|
|
1786
|
+
}
|
|
1787
|
+
return readOrComputeValue(store, withdraw(store, token));
|
|
1788
|
+
}
|
|
1789
|
+
|
|
1790
|
+
// internal/src/junction.ts
|
|
1791
|
+
var Junction = class {
|
|
1792
|
+
a;
|
|
1793
|
+
b;
|
|
1794
|
+
cardinality;
|
|
1795
|
+
relations = /* @__PURE__ */ new Map();
|
|
1796
|
+
contents = /* @__PURE__ */ new Map();
|
|
1797
|
+
isAType;
|
|
1798
|
+
isBType;
|
|
1799
|
+
isContent;
|
|
1800
|
+
makeContentKey = (a, b) => `${a}:${b}`;
|
|
1801
|
+
warn;
|
|
1802
|
+
getRelatedKeys(key) {
|
|
1803
|
+
return this.relations.get(key);
|
|
1804
|
+
}
|
|
1805
|
+
addRelation(a, b) {
|
|
1806
|
+
let aRelations = this.relations.get(a);
|
|
1807
|
+
let bRelations = this.relations.get(b);
|
|
1808
|
+
if (aRelations) {
|
|
1809
|
+
aRelations.add(b);
|
|
1810
|
+
} else {
|
|
1811
|
+
aRelations = /* @__PURE__ */ new Set([b]);
|
|
1812
|
+
this.relations.set(a, aRelations);
|
|
1813
|
+
}
|
|
1814
|
+
if (bRelations) {
|
|
1815
|
+
bRelations.add(a);
|
|
1816
|
+
} else {
|
|
1817
|
+
bRelations = /* @__PURE__ */ new Set([a]);
|
|
1818
|
+
this.relations.set(b, bRelations);
|
|
1819
|
+
}
|
|
1820
|
+
}
|
|
1821
|
+
deleteRelation(a, b) {
|
|
1822
|
+
const aRelations = this.relations.get(a);
|
|
1823
|
+
if (aRelations) {
|
|
1824
|
+
aRelations.delete(b);
|
|
1825
|
+
if (aRelations.size === 0) {
|
|
1826
|
+
this.relations.delete(a);
|
|
1827
|
+
}
|
|
1828
|
+
const bRelations = this.relations.get(b);
|
|
1829
|
+
if (bRelations) {
|
|
1830
|
+
bRelations.delete(a);
|
|
1831
|
+
if (bRelations.size === 0) {
|
|
1832
|
+
this.relations.delete(b);
|
|
1833
|
+
}
|
|
1834
|
+
}
|
|
1835
|
+
}
|
|
1836
|
+
}
|
|
1837
|
+
replaceRelationsUnsafely(x, ys) {
|
|
1838
|
+
this.relations.set(x, new Set(ys));
|
|
1839
|
+
for (const y of ys) {
|
|
1840
|
+
const yRelations = (/* @__PURE__ */ new Set()).add(x);
|
|
1841
|
+
this.relations.set(y, yRelations);
|
|
1842
|
+
}
|
|
1843
|
+
}
|
|
1844
|
+
replaceRelationsSafely(x, ys) {
|
|
1845
|
+
const xRelationsPrev = this.relations.get(x);
|
|
1846
|
+
let a = this.isAType?.(x) ? x : undefined;
|
|
1847
|
+
let b = a === undefined ? x : undefined;
|
|
1848
|
+
if (xRelationsPrev) {
|
|
1849
|
+
for (const y of xRelationsPrev) {
|
|
1850
|
+
a ??= y;
|
|
1851
|
+
b ??= y;
|
|
1852
|
+
const yRelations = this.relations.get(y);
|
|
1853
|
+
if (yRelations) {
|
|
1854
|
+
if (yRelations.size === 1) {
|
|
1855
|
+
this.relations.delete(y);
|
|
1856
|
+
} else {
|
|
1857
|
+
yRelations.delete(x);
|
|
1858
|
+
}
|
|
1859
|
+
this.contents.delete(this.makeContentKey(a, b));
|
|
1860
|
+
}
|
|
1861
|
+
}
|
|
1862
|
+
}
|
|
1863
|
+
this.relations.set(x, new Set(ys));
|
|
1864
|
+
for (const y of ys) {
|
|
1865
|
+
let yRelations = this.relations.get(y);
|
|
1866
|
+
if (yRelations) {
|
|
1867
|
+
yRelations.add(x);
|
|
1868
|
+
} else {
|
|
1869
|
+
yRelations = (/* @__PURE__ */ new Set()).add(x);
|
|
1870
|
+
this.relations.set(y, yRelations);
|
|
1871
|
+
}
|
|
1872
|
+
}
|
|
1873
|
+
}
|
|
1874
|
+
getContentInternal(contentKey) {
|
|
1875
|
+
return this.contents.get(contentKey);
|
|
1876
|
+
}
|
|
1877
|
+
setContent(contentKey, content) {
|
|
1878
|
+
this.contents.set(contentKey, content);
|
|
1879
|
+
}
|
|
1880
|
+
deleteContent(contentKey) {
|
|
1881
|
+
this.contents.delete(contentKey);
|
|
1882
|
+
}
|
|
1883
|
+
constructor(data, config) {
|
|
1884
|
+
this.a = data.between[0];
|
|
1885
|
+
this.b = data.between[1];
|
|
1886
|
+
this.cardinality = data.cardinality;
|
|
1887
|
+
if (!config?.externalStore) {
|
|
1888
|
+
this.relations = new Map(
|
|
1889
|
+
data.relations?.map(([x, ys]) => [x, new Set(ys)])
|
|
1890
|
+
);
|
|
1891
|
+
this.contents = new Map(data.contents);
|
|
1892
|
+
}
|
|
1893
|
+
this.isAType = config?.isAType ?? null;
|
|
1894
|
+
this.isBType = config?.isBType ?? null;
|
|
1895
|
+
this.isContent = config?.isContent ?? null;
|
|
1896
|
+
if (config?.makeContentKey) {
|
|
1897
|
+
this.makeContentKey = config.makeContentKey;
|
|
1898
|
+
}
|
|
1899
|
+
if (config?.externalStore) {
|
|
1900
|
+
const externalStore = config.externalStore;
|
|
1901
|
+
this.has = (a, b) => externalStore.has(a, b);
|
|
1902
|
+
this.addRelation = (a, b) => {
|
|
1903
|
+
externalStore.addRelation(a, b);
|
|
1904
|
+
};
|
|
1905
|
+
this.deleteRelation = (a, b) => {
|
|
1906
|
+
externalStore.deleteRelation(a, b);
|
|
1907
|
+
};
|
|
1908
|
+
this.replaceRelationsSafely = (a, bs) => {
|
|
1909
|
+
externalStore.replaceRelationsSafely(a, bs);
|
|
1910
|
+
};
|
|
1911
|
+
this.replaceRelationsUnsafely = (a, bs) => {
|
|
1912
|
+
externalStore.replaceRelationsUnsafely(a, bs);
|
|
1913
|
+
};
|
|
1914
|
+
this.getRelatedKeys = (key) => externalStore.getRelatedKeys(
|
|
1915
|
+
key
|
|
1916
|
+
);
|
|
1917
|
+
if (externalStore.getContent) {
|
|
1918
|
+
this.getContentInternal = (contentKey) => {
|
|
1919
|
+
return externalStore.getContent(contentKey);
|
|
1920
|
+
};
|
|
1921
|
+
this.setContent = (contentKey, content) => {
|
|
1922
|
+
externalStore.setContent(contentKey, content);
|
|
1923
|
+
};
|
|
1924
|
+
this.deleteContent = (contentKey) => {
|
|
1925
|
+
externalStore.deleteContent(contentKey);
|
|
1926
|
+
};
|
|
1927
|
+
}
|
|
1928
|
+
for (const [x, ys] of data.relations ?? []) {
|
|
1929
|
+
let a = this.isAType?.(x) ? x : undefined;
|
|
1930
|
+
let b = a === undefined ? x : undefined;
|
|
1931
|
+
for (const y of ys) {
|
|
1932
|
+
a ??= y;
|
|
1933
|
+
b ??= y;
|
|
1934
|
+
this.addRelation(a, b);
|
|
1935
|
+
}
|
|
1936
|
+
}
|
|
1937
|
+
for (const [contentKey, content] of data.contents ?? []) {
|
|
1938
|
+
this.setContent(contentKey, content);
|
|
1939
|
+
}
|
|
1940
|
+
}
|
|
1941
|
+
if (config?.warn) {
|
|
1942
|
+
this.warn = config.warn;
|
|
1943
|
+
}
|
|
1944
|
+
}
|
|
1945
|
+
toJSON() {
|
|
1946
|
+
return {
|
|
1947
|
+
between: [this.a, this.b],
|
|
1948
|
+
cardinality: this.cardinality,
|
|
1949
|
+
relations: [...this.relations.entries()].map(
|
|
1950
|
+
([a, b]) => [a, [...b]]
|
|
1951
|
+
),
|
|
1952
|
+
contents: [...this.contents.entries()]
|
|
1953
|
+
};
|
|
1954
|
+
}
|
|
1955
|
+
set(...params) {
|
|
1956
|
+
let a;
|
|
1957
|
+
let b;
|
|
1958
|
+
let content;
|
|
1959
|
+
switch (params.length) {
|
|
1960
|
+
case 1: {
|
|
1961
|
+
const relation = params[0];
|
|
1962
|
+
a = relation[this.a];
|
|
1963
|
+
b = relation[this.b];
|
|
1964
|
+
content = undefined;
|
|
1965
|
+
break;
|
|
1966
|
+
}
|
|
1967
|
+
case 2: {
|
|
1968
|
+
const zeroth = params[0];
|
|
1969
|
+
if (typeof zeroth === `string`) {
|
|
1970
|
+
[a, b] = params;
|
|
1971
|
+
} else {
|
|
1972
|
+
a = zeroth[this.a];
|
|
1973
|
+
b = zeroth[this.b];
|
|
1974
|
+
content = params[1];
|
|
1975
|
+
}
|
|
1976
|
+
break;
|
|
1977
|
+
}
|
|
1978
|
+
default: {
|
|
1979
|
+
a = params[0];
|
|
1980
|
+
b = params[1];
|
|
1981
|
+
content = params[2];
|
|
1982
|
+
break;
|
|
1983
|
+
}
|
|
1984
|
+
}
|
|
1985
|
+
switch (this.cardinality) {
|
|
1986
|
+
// biome-ignore lint/suspicious/noFallthroughSwitchClause: perfect here
|
|
1987
|
+
case `1:1`: {
|
|
1988
|
+
const bPrev = this.getRelatedKey(a);
|
|
1989
|
+
if (bPrev && bPrev !== b) this.delete(a, bPrev);
|
|
1990
|
+
}
|
|
1991
|
+
case `1:n`: {
|
|
1992
|
+
const aPrev = this.getRelatedKey(b);
|
|
1993
|
+
if (aPrev && aPrev !== a) this.delete(aPrev, b);
|
|
1994
|
+
}
|
|
1995
|
+
}
|
|
1996
|
+
if (content) {
|
|
1997
|
+
const contentKey = this.makeContentKey(a, b);
|
|
1998
|
+
this.setContent(contentKey, content);
|
|
1999
|
+
}
|
|
2000
|
+
this.addRelation(a, b);
|
|
2001
|
+
return this;
|
|
2002
|
+
}
|
|
2003
|
+
delete(x, b) {
|
|
2004
|
+
b = typeof b === `string` ? b : x[this.b];
|
|
2005
|
+
const a = (
|
|
2006
|
+
// @ts-expect-error we deduce that this.a may index x
|
|
2007
|
+
typeof x === `string` ? x : x[this.a]
|
|
1860
2008
|
);
|
|
1861
|
-
|
|
1862
|
-
|
|
2009
|
+
if (a === undefined && typeof b === `string`) {
|
|
2010
|
+
const bRelations = this.getRelatedKeys(b);
|
|
2011
|
+
if (bRelations) {
|
|
2012
|
+
for (const bRelation of bRelations) {
|
|
2013
|
+
this.delete(bRelation, b);
|
|
2014
|
+
}
|
|
2015
|
+
}
|
|
2016
|
+
}
|
|
2017
|
+
if (typeof a === `string` && b === undefined) {
|
|
2018
|
+
const aRelations = this.getRelatedKeys(a);
|
|
2019
|
+
if (aRelations) {
|
|
2020
|
+
for (const aRelation of aRelations) {
|
|
2021
|
+
this.delete(a, aRelation);
|
|
2022
|
+
}
|
|
2023
|
+
}
|
|
2024
|
+
}
|
|
2025
|
+
if (typeof a === `string` && typeof b === `string`) {
|
|
2026
|
+
this.deleteRelation(a, b);
|
|
2027
|
+
const contentKey = this.makeContentKey(a, b);
|
|
2028
|
+
this.deleteContent(contentKey);
|
|
2029
|
+
}
|
|
2030
|
+
return this;
|
|
1863
2031
|
}
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
2032
|
+
getRelatedKey(key) {
|
|
2033
|
+
const relations = this.getRelatedKeys(key);
|
|
2034
|
+
if (relations) {
|
|
2035
|
+
if (relations.size > 1) {
|
|
2036
|
+
this.warn?.(
|
|
2037
|
+
`${relations.size} related keys were found for key "${key}": (${[
|
|
2038
|
+
...relations
|
|
2039
|
+
].map((k) => `"${k}"`).join(`, `)}). Only one related key was expected.`
|
|
2040
|
+
);
|
|
2041
|
+
}
|
|
2042
|
+
let singleRelation;
|
|
2043
|
+
for (const relation of relations) {
|
|
2044
|
+
singleRelation = relation;
|
|
2045
|
+
break;
|
|
2046
|
+
}
|
|
2047
|
+
return singleRelation;
|
|
2048
|
+
}
|
|
1872
2049
|
}
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
2050
|
+
replaceRelations(x, relations, config) {
|
|
2051
|
+
const hasContent = !Array.isArray(relations);
|
|
2052
|
+
const ys = hasContent ? Object.keys(relations) : relations;
|
|
2053
|
+
if (config?.reckless) {
|
|
2054
|
+
this.replaceRelationsUnsafely(x, ys);
|
|
2055
|
+
} else {
|
|
2056
|
+
this.replaceRelationsSafely(x, ys);
|
|
2057
|
+
}
|
|
2058
|
+
if (hasContent) {
|
|
2059
|
+
for (const y of ys) {
|
|
2060
|
+
const contentKey = this.makeContentKey(x, y);
|
|
2061
|
+
const content = relations[y];
|
|
2062
|
+
this.setContent(contentKey, content);
|
|
2063
|
+
}
|
|
2064
|
+
}
|
|
2065
|
+
return this;
|
|
1877
2066
|
}
|
|
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);
|
|
2067
|
+
getContent(a, b) {
|
|
2068
|
+
const contentKey = this.makeContentKey(a, b);
|
|
2069
|
+
return this.getContentInternal(contentKey);
|
|
1898
2070
|
}
|
|
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;
|
|
2071
|
+
getRelationEntries(input) {
|
|
2072
|
+
const a = input[this.a];
|
|
2073
|
+
const b = input[this.b];
|
|
2074
|
+
if (a !== undefined && b === undefined) {
|
|
2075
|
+
const aRelations = this.getRelatedKeys(a);
|
|
2076
|
+
if (aRelations) {
|
|
2077
|
+
return [...aRelations].map((aRelation) => {
|
|
2078
|
+
return [aRelation, this.getContent(a, aRelation)];
|
|
2079
|
+
});
|
|
2080
|
+
}
|
|
2081
|
+
}
|
|
2082
|
+
if (a === undefined && b !== undefined) {
|
|
2083
|
+
const bRelations = this.getRelatedKeys(b);
|
|
2084
|
+
if (bRelations) {
|
|
2085
|
+
return [...bRelations].map((bRelation) => {
|
|
2086
|
+
return [bRelation, this.getContent(bRelation, b)];
|
|
2087
|
+
});
|
|
1925
2088
|
}
|
|
1926
2089
|
}
|
|
2090
|
+
return [];
|
|
1927
2091
|
}
|
|
1928
|
-
|
|
1929
|
-
|
|
2092
|
+
has(a, b) {
|
|
2093
|
+
if (b) {
|
|
2094
|
+
const setA = this.getRelatedKeys(a);
|
|
2095
|
+
return setA?.has(b) ?? false;
|
|
2096
|
+
}
|
|
2097
|
+
return this.relations.has(a);
|
|
2098
|
+
}
|
|
2099
|
+
};
|
|
1930
2100
|
|
|
1931
2101
|
// internal/src/lazy-map.ts
|
|
1932
2102
|
var LazyMap = class extends Map {
|
|
@@ -1963,7 +2133,7 @@ var LazyMap = class extends Map {
|
|
|
1963
2133
|
};
|
|
1964
2134
|
|
|
1965
2135
|
// internal/src/transaction/build-transaction.ts
|
|
1966
|
-
var buildTransaction = (key, params,
|
|
2136
|
+
var buildTransaction = (store, key, params, id) => {
|
|
1967
2137
|
const parent = newest(store);
|
|
1968
2138
|
const childBase = {
|
|
1969
2139
|
parent,
|
|
@@ -2002,7 +2172,7 @@ var buildTransaction = (key, params, store, id) => {
|
|
|
2002
2172
|
}),
|
|
2003
2173
|
miscResources: new LazyMap(parent.miscResources)
|
|
2004
2174
|
};
|
|
2005
|
-
const epoch = getEpochNumberOfAction(
|
|
2175
|
+
const epoch = getEpochNumberOfAction(store, key);
|
|
2006
2176
|
const transactionMeta = {
|
|
2007
2177
|
phase: `building`,
|
|
2008
2178
|
update: {
|
|
@@ -2019,9 +2189,8 @@ var buildTransaction = (key, params, store, id) => {
|
|
|
2019
2189
|
set: (...ps) => {
|
|
2020
2190
|
setIntoStore(child, ...ps);
|
|
2021
2191
|
},
|
|
2022
|
-
run: (token, identifier = arbitrary()) => actUponStore(token, identifier
|
|
2192
|
+
run: (token, identifier = arbitrary()) => actUponStore(child, token, identifier),
|
|
2023
2193
|
find: (token, k) => findInStore(child, token, k),
|
|
2024
|
-
seek: (token, k) => seekInStore(child, token, k),
|
|
2025
2194
|
json: (token) => getJsonToken(child, token),
|
|
2026
2195
|
dispose: (...ps) => {
|
|
2027
2196
|
disposeFromStore(child, ...ps);
|
|
@@ -2044,12 +2213,12 @@ var buildTransaction = (key, params, store, id) => {
|
|
|
2044
2213
|
};
|
|
2045
2214
|
|
|
2046
2215
|
// internal/src/transaction/create-transaction.ts
|
|
2047
|
-
function createTransaction(
|
|
2216
|
+
function createTransaction(store, options) {
|
|
2048
2217
|
const newTransaction = {
|
|
2049
2218
|
key: options.key,
|
|
2050
2219
|
type: `transaction`,
|
|
2051
2220
|
run: (params, id) => {
|
|
2052
|
-
const childStore = buildTransaction(options.key, params,
|
|
2221
|
+
const childStore = buildTransaction(store, options.key, params, id);
|
|
2053
2222
|
try {
|
|
2054
2223
|
const target2 = newest(store);
|
|
2055
2224
|
const { toolkit } = childStore.transactionMeta;
|
|
@@ -2062,7 +2231,7 @@ function createTransaction(options, store) {
|
|
|
2062
2231
|
throw thrown;
|
|
2063
2232
|
}
|
|
2064
2233
|
},
|
|
2065
|
-
install: (s) => createTransaction(
|
|
2234
|
+
install: (s) => createTransaction(s, options),
|
|
2066
2235
|
subject: new Subject()
|
|
2067
2236
|
};
|
|
2068
2237
|
const target = newest(store);
|
|
@@ -2072,26 +2241,138 @@ function createTransaction(options, store) {
|
|
|
2072
2241
|
return token;
|
|
2073
2242
|
}
|
|
2074
2243
|
|
|
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) : undefined;
|
|
2079
|
-
return continuity;
|
|
2244
|
+
// internal/src/transaction/get-epoch-number.ts
|
|
2245
|
+
function getContinuityKey(store, transactionKey) {
|
|
2246
|
+
const isRoot = isRootStore(store);
|
|
2247
|
+
const continuity = isRoot ? store.transactionMeta.actionContinuities.getRelatedKey(transactionKey) : undefined;
|
|
2248
|
+
return continuity;
|
|
2249
|
+
}
|
|
2250
|
+
function getEpochNumberOfContinuity(store, continuityKey) {
|
|
2251
|
+
const isRoot = isRootStore(store);
|
|
2252
|
+
const epoch = isRoot && continuityKey ? store.transactionMeta.epoch.get(continuityKey) : undefined;
|
|
2253
|
+
return epoch;
|
|
2254
|
+
}
|
|
2255
|
+
function getEpochNumberOfAction(store, transactionKey) {
|
|
2256
|
+
const isRoot = isRootStore(store);
|
|
2257
|
+
const continuity = isRoot ? store.transactionMeta.actionContinuities.getRelatedKey(transactionKey) : undefined;
|
|
2258
|
+
const epoch = isRoot && continuity !== undefined ? store.transactionMeta.epoch.get(continuity) : undefined;
|
|
2259
|
+
return epoch;
|
|
2260
|
+
}
|
|
2261
|
+
|
|
2262
|
+
// internal/src/transaction/index.ts
|
|
2263
|
+
var TRANSACTION_PHASES = [`idle`, `building`, `applying`];
|
|
2264
|
+
|
|
2265
|
+
// internal/src/install-into-store.ts
|
|
2266
|
+
function installIntoStore(tokens, target, source) {
|
|
2267
|
+
const sourceNewest = newest(source);
|
|
2268
|
+
if (isChildStore(sourceNewest)) {
|
|
2269
|
+
source.logger.error(
|
|
2270
|
+
`\u274C`,
|
|
2271
|
+
`transaction`,
|
|
2272
|
+
sourceNewest.transactionMeta.update.key,
|
|
2273
|
+
`could not install the following tokens into store "${target.config.name} from "${source.config.name}":`,
|
|
2274
|
+
tokens,
|
|
2275
|
+
`${sourceNewest.config.name} is undergoing a transaction.`
|
|
2276
|
+
);
|
|
2277
|
+
return;
|
|
2278
|
+
}
|
|
2279
|
+
const targetNewest = newest(target);
|
|
2280
|
+
if (isChildStore(targetNewest)) {
|
|
2281
|
+
target.logger.error(
|
|
2282
|
+
`\u274C`,
|
|
2283
|
+
`transaction`,
|
|
2284
|
+
targetNewest.transactionMeta.update.key,
|
|
2285
|
+
`could not install the following tokens into store "${target.config.name} from "${source.config.name}":`,
|
|
2286
|
+
tokens,
|
|
2287
|
+
`${targetNewest.config.name} is undergoing a transaction.`
|
|
2288
|
+
);
|
|
2289
|
+
return;
|
|
2290
|
+
}
|
|
2291
|
+
for (const token of tokens) {
|
|
2292
|
+
const resource = withdraw(source, token);
|
|
2293
|
+
resource.install(target);
|
|
2294
|
+
}
|
|
2295
|
+
}
|
|
2296
|
+
|
|
2297
|
+
// src/silo.ts
|
|
2298
|
+
var Silo = class {
|
|
2299
|
+
store;
|
|
2300
|
+
atom;
|
|
2301
|
+
atomFamily;
|
|
2302
|
+
selector;
|
|
2303
|
+
selectorFamily;
|
|
2304
|
+
transaction;
|
|
2305
|
+
timeline;
|
|
2306
|
+
findState;
|
|
2307
|
+
getState;
|
|
2308
|
+
setState;
|
|
2309
|
+
disposeState;
|
|
2310
|
+
subscribe;
|
|
2311
|
+
undo;
|
|
2312
|
+
redo;
|
|
2313
|
+
runTransaction;
|
|
2314
|
+
install;
|
|
2315
|
+
constructor(config, fromStore = null) {
|
|
2316
|
+
const s = this.store = new Store(config, fromStore);
|
|
2317
|
+
this.atom = (options) => createStandaloneAtom(s, options);
|
|
2318
|
+
this.atomFamily = (options) => createAtomFamily(s, options);
|
|
2319
|
+
this.selector = (options) => createStandaloneSelector(s, options);
|
|
2320
|
+
this.selectorFamily = (options) => createSelectorFamily(s, options);
|
|
2321
|
+
this.transaction = (options) => createTransaction(s, options);
|
|
2322
|
+
this.timeline = (options) => createTimeline(s, options);
|
|
2323
|
+
this.findState = (...params) => findInStore(s, ...params);
|
|
2324
|
+
this.getState = (...params) => getFromStore(s, ...params);
|
|
2325
|
+
this.setState = (...params) => {
|
|
2326
|
+
setIntoStore(s, ...params);
|
|
2327
|
+
};
|
|
2328
|
+
this.disposeState = (...params) => {
|
|
2329
|
+
disposeFromStore(s, ...params);
|
|
2330
|
+
};
|
|
2331
|
+
this.subscribe = (...params) => subscribeInStore(s, ...params);
|
|
2332
|
+
this.undo = (token) => {
|
|
2333
|
+
timeTravel(s, `undo`, token);
|
|
2334
|
+
};
|
|
2335
|
+
this.redo = (token) => {
|
|
2336
|
+
timeTravel(s, `redo`, token);
|
|
2337
|
+
};
|
|
2338
|
+
this.runTransaction = (token, id = arbitrary()) => actUponStore(s, token, id);
|
|
2339
|
+
this.install = (tokens, source = IMPLICIT.STORE) => {
|
|
2340
|
+
installIntoStore(tokens, s, source);
|
|
2341
|
+
};
|
|
2342
|
+
}
|
|
2343
|
+
};
|
|
2344
|
+
|
|
2345
|
+
// src/subscribe.ts
|
|
2346
|
+
function subscribe(token, handleUpdate, key = arbitrary()) {
|
|
2347
|
+
return subscribeInStore(IMPLICIT.STORE, token, handleUpdate, key);
|
|
2080
2348
|
}
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
return
|
|
2349
|
+
|
|
2350
|
+
// src/timeline.ts
|
|
2351
|
+
var timeline = (options) => {
|
|
2352
|
+
return createTimeline(IMPLICIT.STORE, options);
|
|
2353
|
+
};
|
|
2354
|
+
var redo = (tl) => {
|
|
2355
|
+
timeTravel(IMPLICIT.STORE, `redo`, tl);
|
|
2356
|
+
};
|
|
2357
|
+
var undo = (tl) => {
|
|
2358
|
+
timeTravel(IMPLICIT.STORE, `undo`, tl);
|
|
2359
|
+
};
|
|
2360
|
+
|
|
2361
|
+
// src/transaction.ts
|
|
2362
|
+
function transaction(options) {
|
|
2363
|
+
return createTransaction(IMPLICIT.STORE, options);
|
|
2085
2364
|
}
|
|
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;
|
|
2365
|
+
function runTransaction(token, id = arbitrary()) {
|
|
2366
|
+
return actUponStore(IMPLICIT.STORE, token, id);
|
|
2091
2367
|
}
|
|
2092
2368
|
|
|
2093
|
-
//
|
|
2094
|
-
|
|
2369
|
+
// src/validators.ts
|
|
2370
|
+
function isToken(knownToken, unknownToken) {
|
|
2371
|
+
return knownToken.key === unknownToken.key;
|
|
2372
|
+
}
|
|
2373
|
+
function belongsTo(family, unknownToken) {
|
|
2374
|
+
return family.key === unknownToken.family?.key;
|
|
2375
|
+
}
|
|
2095
2376
|
|
|
2096
2377
|
// internal/src/store/store.ts
|
|
2097
2378
|
var Store = class {
|
|
@@ -2218,32 +2499,32 @@ var Store = class {
|
|
|
2218
2499
|
family.install(this);
|
|
2219
2500
|
}
|
|
2220
2501
|
const mutableHelpers = /* @__PURE__ */ new Set();
|
|
2221
|
-
for (const [,
|
|
2222
|
-
if (mutableHelpers.has(
|
|
2502
|
+
for (const [, atom2] of store.atoms) {
|
|
2503
|
+
if (mutableHelpers.has(atom2.key)) {
|
|
2223
2504
|
continue;
|
|
2224
2505
|
}
|
|
2225
|
-
|
|
2226
|
-
if (
|
|
2227
|
-
const originalJsonToken = getJsonToken(store,
|
|
2228
|
-
const originalUpdateToken = getUpdateToken(
|
|
2506
|
+
atom2.install(this);
|
|
2507
|
+
if (atom2.type === `mutable_atom`) {
|
|
2508
|
+
const originalJsonToken = getJsonToken(store, atom2);
|
|
2509
|
+
const originalUpdateToken = getUpdateToken(atom2);
|
|
2229
2510
|
mutableHelpers.add(originalJsonToken.key);
|
|
2230
2511
|
mutableHelpers.add(originalUpdateToken.key);
|
|
2231
2512
|
}
|
|
2232
2513
|
}
|
|
2233
|
-
for (const [,
|
|
2234
|
-
|
|
2514
|
+
for (const [, selector2] of store.readonlySelectors) {
|
|
2515
|
+
selector2.install(this);
|
|
2235
2516
|
}
|
|
2236
|
-
for (const [,
|
|
2237
|
-
if (mutableHelpers.has(
|
|
2517
|
+
for (const [, selector2] of store.selectors) {
|
|
2518
|
+
if (mutableHelpers.has(selector2.key)) {
|
|
2238
2519
|
continue;
|
|
2239
2520
|
}
|
|
2240
|
-
|
|
2521
|
+
selector2.install(this);
|
|
2241
2522
|
}
|
|
2242
2523
|
for (const [, tx] of store.transactions) {
|
|
2243
2524
|
tx.install(this);
|
|
2244
2525
|
}
|
|
2245
|
-
for (const [,
|
|
2246
|
-
|
|
2526
|
+
for (const [, timeline2] of store.timelines) {
|
|
2527
|
+
timeline2.install(this);
|
|
2247
2528
|
}
|
|
2248
2529
|
}
|
|
2249
2530
|
}
|
|
@@ -2269,7 +2550,7 @@ var clearStore = (store) => {
|
|
|
2269
2550
|
};
|
|
2270
2551
|
|
|
2271
2552
|
// internal/src/store/withdraw.ts
|
|
2272
|
-
function withdraw(
|
|
2553
|
+
function withdraw(store, token) {
|
|
2273
2554
|
let withdrawn;
|
|
2274
2555
|
let target = store;
|
|
2275
2556
|
while (target !== null) {
|
|
@@ -2306,45 +2587,47 @@ function withdraw(token, store) {
|
|
|
2306
2587
|
}
|
|
2307
2588
|
|
|
2308
2589
|
// internal/src/subscribe/recall-state.ts
|
|
2309
|
-
var recallState = (
|
|
2590
|
+
var recallState = (store, state) => {
|
|
2310
2591
|
const target = newest(store);
|
|
2311
2592
|
if (target.operation.open) {
|
|
2312
2593
|
return target.operation.prev.get(state.key);
|
|
2313
2594
|
}
|
|
2314
2595
|
return target.valueMap.get(state.key);
|
|
2315
2596
|
};
|
|
2316
|
-
|
|
2597
|
+
|
|
2598
|
+
// internal/src/subscribe/subscribe-in-store.ts
|
|
2599
|
+
function subscribeInStore(store, token, handleUpdate, key = arbitrary()) {
|
|
2317
2600
|
switch (token.type) {
|
|
2318
2601
|
case `atom`:
|
|
2319
2602
|
case `mutable_atom`:
|
|
2320
2603
|
case `readonly_selector`:
|
|
2321
2604
|
case `selector`:
|
|
2322
|
-
return subscribeToState(
|
|
2605
|
+
return subscribeToState(store, token, key, handleUpdate);
|
|
2323
2606
|
case `transaction`:
|
|
2324
|
-
return subscribeToTransaction(
|
|
2607
|
+
return subscribeToTransaction(store, token, key, handleUpdate);
|
|
2325
2608
|
case `timeline`:
|
|
2326
|
-
return subscribeToTimeline(
|
|
2609
|
+
return subscribeToTimeline(store, token, key, handleUpdate);
|
|
2327
2610
|
}
|
|
2328
2611
|
}
|
|
2329
2612
|
|
|
2330
2613
|
// internal/src/subscribe/subscribe-to-root-atoms.ts
|
|
2331
|
-
var subscribeToRootAtoms = (
|
|
2614
|
+
var subscribeToRootAtoms = (store, selector2) => {
|
|
2332
2615
|
const target = newest(store);
|
|
2333
|
-
const dependencySubscriptions = traceAllSelectorAtoms(
|
|
2616
|
+
const dependencySubscriptions = traceAllSelectorAtoms(selector2, store).map(
|
|
2334
2617
|
(atomKey) => {
|
|
2335
|
-
const
|
|
2336
|
-
if (
|
|
2618
|
+
const atom2 = target.atoms.get(atomKey);
|
|
2619
|
+
if (atom2 === undefined) {
|
|
2337
2620
|
throw new Error(
|
|
2338
|
-
`Atom "${atomKey}", a dependency of selector "${
|
|
2621
|
+
`Atom "${atomKey}", a dependency of selector "${selector2.key}", not found in store "${store.config.name}".`
|
|
2339
2622
|
);
|
|
2340
2623
|
}
|
|
2341
|
-
return
|
|
2342
|
-
`${
|
|
2624
|
+
return atom2.subject.subscribe(
|
|
2625
|
+
`${selector2.type}:${selector2.key}`,
|
|
2343
2626
|
(atomChange) => {
|
|
2344
2627
|
store.logger.info(
|
|
2345
2628
|
`\u{1F4E2}`,
|
|
2346
|
-
|
|
2347
|
-
|
|
2629
|
+
selector2.type,
|
|
2630
|
+
selector2.key,
|
|
2348
2631
|
`root`,
|
|
2349
2632
|
atomKey,
|
|
2350
2633
|
`went`,
|
|
@@ -2352,18 +2635,18 @@ var subscribeToRootAtoms = (selector, store) => {
|
|
|
2352
2635
|
`->`,
|
|
2353
2636
|
atomChange.newValue
|
|
2354
2637
|
);
|
|
2355
|
-
const oldValue = recallState(
|
|
2356
|
-
const newValue = readOrComputeValue(
|
|
2638
|
+
const oldValue = recallState(target, selector2);
|
|
2639
|
+
const newValue = readOrComputeValue(target, selector2);
|
|
2357
2640
|
store.logger.info(
|
|
2358
2641
|
`\u2728`,
|
|
2359
|
-
|
|
2360
|
-
|
|
2642
|
+
selector2.type,
|
|
2643
|
+
selector2.key,
|
|
2361
2644
|
`went`,
|
|
2362
2645
|
oldValue,
|
|
2363
2646
|
`->`,
|
|
2364
2647
|
newValue
|
|
2365
2648
|
);
|
|
2366
|
-
|
|
2649
|
+
selector2.subject.next({ newValue, oldValue });
|
|
2367
2650
|
}
|
|
2368
2651
|
);
|
|
2369
2652
|
}
|
|
@@ -2372,7 +2655,7 @@ var subscribeToRootAtoms = (selector, store) => {
|
|
|
2372
2655
|
};
|
|
2373
2656
|
|
|
2374
2657
|
// internal/src/subscribe/subscribe-to-state.ts
|
|
2375
|
-
function
|
|
2658
|
+
function subscribeToState(store, token, key, handleUpdate) {
|
|
2376
2659
|
function safelyHandleUpdate(update) {
|
|
2377
2660
|
if (store.operation.open) {
|
|
2378
2661
|
const unsubscribe2 = store.on.operationClose.subscribe(
|
|
@@ -2386,17 +2669,17 @@ function subscribeToState2(token, handleUpdate, key, store) {
|
|
|
2386
2669
|
handleUpdate(update);
|
|
2387
2670
|
}
|
|
2388
2671
|
}
|
|
2389
|
-
const state = withdraw(
|
|
2672
|
+
const state = withdraw(store, token);
|
|
2390
2673
|
store.logger.info(`\u{1F440}`, state.type, state.key, `Adding subscription "${key}"`);
|
|
2391
2674
|
const isSelector = state.type === `selector` || state.type === `readonly_selector`;
|
|
2392
2675
|
let dependencyUnsubFunctions = null;
|
|
2393
2676
|
let updateHandler = safelyHandleUpdate;
|
|
2394
2677
|
if (isSelector) {
|
|
2395
|
-
dependencyUnsubFunctions = subscribeToRootAtoms(
|
|
2678
|
+
dependencyUnsubFunctions = subscribeToRootAtoms(store, state);
|
|
2396
2679
|
updateHandler = (update) => {
|
|
2397
2680
|
if (dependencyUnsubFunctions) {
|
|
2398
2681
|
dependencyUnsubFunctions.length = 0;
|
|
2399
|
-
dependencyUnsubFunctions.push(...subscribeToRootAtoms(
|
|
2682
|
+
dependencyUnsubFunctions.push(...subscribeToRootAtoms(store, state));
|
|
2400
2683
|
}
|
|
2401
2684
|
safelyHandleUpdate(update);
|
|
2402
2685
|
};
|
|
@@ -2420,8 +2703,8 @@ function subscribeToState2(token, handleUpdate, key, store) {
|
|
|
2420
2703
|
}
|
|
2421
2704
|
|
|
2422
2705
|
// internal/src/subscribe/subscribe-to-timeline.ts
|
|
2423
|
-
var
|
|
2424
|
-
const tl = withdraw(
|
|
2706
|
+
var subscribeToTimeline = (store, token, key, handleUpdate) => {
|
|
2707
|
+
const tl = withdraw(store, token);
|
|
2425
2708
|
store.logger.info(`\u{1F440}`, `timeline`, token.key, `Adding subscription "${key}"`);
|
|
2426
2709
|
const unsubscribe = tl.subject.subscribe(key, handleUpdate);
|
|
2427
2710
|
return () => {
|
|
@@ -2436,8 +2719,8 @@ var subscribeToTimeline2 = (token, handleUpdate, key, store) => {
|
|
|
2436
2719
|
};
|
|
2437
2720
|
|
|
2438
2721
|
// internal/src/subscribe/subscribe-to-transaction.ts
|
|
2439
|
-
var
|
|
2440
|
-
const tx = withdraw(
|
|
2722
|
+
var subscribeToTransaction = (store, token, key, handleUpdate) => {
|
|
2723
|
+
const tx = withdraw(store, token);
|
|
2441
2724
|
store.logger.info(
|
|
2442
2725
|
`\u{1F440}`,
|
|
2443
2726
|
`transaction`,
|
|
@@ -2492,8 +2775,10 @@ var Tracker = class {
|
|
|
2492
2775
|
setIntoStore(target, latestUpdateState, update);
|
|
2493
2776
|
}
|
|
2494
2777
|
);
|
|
2495
|
-
this.unsubscribeFromState =
|
|
2778
|
+
this.unsubscribeFromState = subscribeToState(
|
|
2779
|
+
target,
|
|
2496
2780
|
mutableState,
|
|
2781
|
+
subscriptionKey,
|
|
2497
2782
|
(update) => {
|
|
2498
2783
|
if (update.newValue !== update.oldValue) {
|
|
2499
2784
|
this.unsubscribeFromInnerValue();
|
|
@@ -2504,15 +2789,15 @@ var Tracker = class {
|
|
|
2504
2789
|
}
|
|
2505
2790
|
);
|
|
2506
2791
|
}
|
|
2507
|
-
}
|
|
2508
|
-
subscriptionKey,
|
|
2509
|
-
target
|
|
2792
|
+
}
|
|
2510
2793
|
);
|
|
2511
2794
|
}
|
|
2512
2795
|
updateCore(mutableState, latestUpdateState, target) {
|
|
2513
2796
|
const subscriptionKey = `tracker:${target.config.name}:${isChildStore(target) ? target.transactionMeta.update.key : `main`}:${mutableState.key}`;
|
|
2514
|
-
|
|
2797
|
+
subscribeToState(
|
|
2798
|
+
target,
|
|
2515
2799
|
latestUpdateState,
|
|
2800
|
+
subscriptionKey,
|
|
2516
2801
|
({ newValue, oldValue }) => {
|
|
2517
2802
|
const timelineId = target.timelineTopics.getRelatedKey(
|
|
2518
2803
|
latestUpdateState.key
|
|
@@ -2520,8 +2805,10 @@ var Tracker = class {
|
|
|
2520
2805
|
if (timelineId) {
|
|
2521
2806
|
const timelineData = target.timelines.get(timelineId);
|
|
2522
2807
|
if (timelineData?.timeTraveling) {
|
|
2523
|
-
const unsubscribe2 =
|
|
2808
|
+
const unsubscribe2 = subscribeToTimeline(
|
|
2809
|
+
target,
|
|
2524
2810
|
{ key: timelineId, type: `timeline` },
|
|
2811
|
+
subscriptionKey,
|
|
2525
2812
|
(update) => {
|
|
2526
2813
|
unsubscribe2();
|
|
2527
2814
|
setIntoStore(target, mutableState, (transceiver) => {
|
|
@@ -2532,9 +2819,7 @@ var Tracker = class {
|
|
|
2532
2819
|
}
|
|
2533
2820
|
return transceiver;
|
|
2534
2821
|
});
|
|
2535
|
-
}
|
|
2536
|
-
subscriptionKey,
|
|
2537
|
-
target
|
|
2822
|
+
}
|
|
2538
2823
|
);
|
|
2539
2824
|
return;
|
|
2540
2825
|
}
|
|
@@ -2562,14 +2847,12 @@ var Tracker = class {
|
|
|
2562
2847
|
}
|
|
2563
2848
|
}
|
|
2564
2849
|
);
|
|
2565
|
-
}
|
|
2566
|
-
subscriptionKey,
|
|
2567
|
-
target
|
|
2850
|
+
}
|
|
2568
2851
|
);
|
|
2569
2852
|
}
|
|
2570
2853
|
mutableState;
|
|
2571
2854
|
latestUpdateState;
|
|
2572
|
-
dispose;
|
|
2855
|
+
[Symbol.dispose];
|
|
2573
2856
|
constructor(mutableState, store) {
|
|
2574
2857
|
this.mutableState = mutableState;
|
|
2575
2858
|
const target = newest(store);
|
|
@@ -2577,7 +2860,7 @@ var Tracker = class {
|
|
|
2577
2860
|
this.observeCore(mutableState, this.latestUpdateState, target);
|
|
2578
2861
|
this.updateCore(mutableState, this.latestUpdateState, target);
|
|
2579
2862
|
target.trackers.set(mutableState.key, this);
|
|
2580
|
-
this.dispose = () => {
|
|
2863
|
+
this[Symbol.dispose] = () => {
|
|
2581
2864
|
this.unsubscribeFromInnerValue();
|
|
2582
2865
|
this.unsubscribeFromState();
|
|
2583
2866
|
target.trackers.delete(mutableState.key);
|
|
@@ -2624,8 +2907,8 @@ function createMutableAtom(store, options, family) {
|
|
|
2624
2907
|
}
|
|
2625
2908
|
const initialValue = options.default();
|
|
2626
2909
|
target.atoms.set(newAtom.key, newAtom);
|
|
2627
|
-
markAtomAsDefault(options.key
|
|
2628
|
-
cacheValue(options.key, initialValue, subject
|
|
2910
|
+
markAtomAsDefault(store, options.key);
|
|
2911
|
+
cacheValue(target, options.key, initialValue, subject);
|
|
2629
2912
|
const token = deposit(newAtom);
|
|
2630
2913
|
if (options.effects) {
|
|
2631
2914
|
let effectIndex = 0;
|
|
@@ -2635,7 +2918,7 @@ function createMutableAtom(store, options, family) {
|
|
|
2635
2918
|
setSelf: (next) => {
|
|
2636
2919
|
setIntoStore(store, token, next);
|
|
2637
2920
|
},
|
|
2638
|
-
onSet: (handle) =>
|
|
2921
|
+
onSet: (handle) => subscribeToState(store, token, `effect[${effectIndex}]`, handle)
|
|
2639
2922
|
});
|
|
2640
2923
|
if (cleanup) {
|
|
2641
2924
|
cleanupFunctions.push(cleanup);
|
|
@@ -2654,7 +2937,10 @@ function createMutableAtom(store, options, family) {
|
|
|
2654
2937
|
}
|
|
2655
2938
|
return token;
|
|
2656
2939
|
}
|
|
2940
|
+
|
|
2941
|
+
// internal/src/mutable/tracker-family.ts
|
|
2657
2942
|
var FamilyTracker = class {
|
|
2943
|
+
trackers = /* @__PURE__ */ new Map();
|
|
2658
2944
|
Update;
|
|
2659
2945
|
latestUpdateAtoms;
|
|
2660
2946
|
mutableAtoms;
|
|
@@ -2667,26 +2953,27 @@ var FamilyTracker = class {
|
|
|
2667
2953
|
},
|
|
2668
2954
|
[`mutable`, `updates`]
|
|
2669
2955
|
);
|
|
2670
|
-
this.latestUpdateAtoms = withdraw(
|
|
2956
|
+
this.latestUpdateAtoms = withdraw(store, updateAtoms);
|
|
2671
2957
|
this.mutableAtoms = mutableAtoms;
|
|
2672
2958
|
this.mutableAtoms.subject.subscribe(
|
|
2673
2959
|
`store=${store.config.name}::tracker-atom-family`,
|
|
2674
2960
|
(event) => {
|
|
2675
|
-
|
|
2676
|
-
|
|
2677
|
-
|
|
2678
|
-
|
|
2679
|
-
|
|
2680
|
-
|
|
2681
|
-
|
|
2682
|
-
|
|
2683
|
-
|
|
2684
|
-
|
|
2685
|
-
|
|
2686
|
-
|
|
2687
|
-
|
|
2688
|
-
|
|
2689
|
-
|
|
2961
|
+
const { type, token } = event;
|
|
2962
|
+
if (token.family) {
|
|
2963
|
+
const key = parseJson(token.family.subKey);
|
|
2964
|
+
switch (type) {
|
|
2965
|
+
case `state_creation`:
|
|
2966
|
+
this.trackers.set(key, new Tracker(token, store));
|
|
2967
|
+
break;
|
|
2968
|
+
case `state_disposal`:
|
|
2969
|
+
{
|
|
2970
|
+
const tracker = this.trackers.get(key);
|
|
2971
|
+
if (tracker) {
|
|
2972
|
+
tracker[Symbol.dispose]();
|
|
2973
|
+
this.trackers.delete(key);
|
|
2974
|
+
}
|
|
2975
|
+
}
|
|
2976
|
+
break;
|
|
2690
2977
|
}
|
|
2691
2978
|
}
|
|
2692
2979
|
}
|
|
@@ -2731,16 +3018,16 @@ function createMutableAtomFamily(store, options, internalRoles) {
|
|
|
2731
3018
|
subject.next({ type: `state_creation`, token });
|
|
2732
3019
|
return token;
|
|
2733
3020
|
};
|
|
2734
|
-
const
|
|
3021
|
+
const atomFamily2 = Object.assign(familyFunction, familyToken, {
|
|
2735
3022
|
subject,
|
|
2736
3023
|
install: (s) => createMutableAtomFamily(s, options),
|
|
2737
3024
|
toJson: options.toJson,
|
|
2738
3025
|
fromJson: options.fromJson,
|
|
2739
3026
|
internalRoles
|
|
2740
3027
|
});
|
|
2741
|
-
store.families.set(options.key,
|
|
2742
|
-
selectJsonFamily(
|
|
2743
|
-
new FamilyTracker(
|
|
3028
|
+
store.families.set(options.key, atomFamily2);
|
|
3029
|
+
selectJsonFamily(store, atomFamily2, options);
|
|
3030
|
+
new FamilyTracker(atomFamily2, store);
|
|
2744
3031
|
return familyToken;
|
|
2745
3032
|
}
|
|
2746
3033
|
|
|
@@ -2761,7 +3048,7 @@ var getJsonToken = (store, mutableAtomToken) => {
|
|
|
2761
3048
|
key: jsonFamilyKey,
|
|
2762
3049
|
type: `selector_family`
|
|
2763
3050
|
};
|
|
2764
|
-
const family = withdraw(
|
|
3051
|
+
const family = withdraw(target, jsonFamilyToken);
|
|
2765
3052
|
const subKey = JSON.parse(mutableAtomToken.family.subKey);
|
|
2766
3053
|
const jsonToken = findInStore(store, family, subKey);
|
|
2767
3054
|
return jsonToken;
|
|
@@ -2802,25 +3089,25 @@ function isTransceiver(value) {
|
|
|
2802
3089
|
}
|
|
2803
3090
|
|
|
2804
3091
|
// internal/src/set-state/copy-mutable-if-needed.ts
|
|
2805
|
-
function copyMutableIfNeeded(
|
|
2806
|
-
const originValue = origin.valueMap.get(
|
|
2807
|
-
const targetValue = target.valueMap.get(
|
|
3092
|
+
function copyMutableIfNeeded(target, atom2, origin) {
|
|
3093
|
+
const originValue = origin.valueMap.get(atom2.key);
|
|
3094
|
+
const targetValue = target.valueMap.get(atom2.key);
|
|
2808
3095
|
if (originValue === targetValue) {
|
|
2809
3096
|
if (originValue === undefined) {
|
|
2810
|
-
return typeof
|
|
3097
|
+
return typeof atom2.default === `function` ? atom2.default() : atom2.default;
|
|
2811
3098
|
}
|
|
2812
|
-
origin.logger.info(`\u{1F4C3}`, `atom`,
|
|
2813
|
-
const jsonValue =
|
|
2814
|
-
const copiedValue =
|
|
2815
|
-
target.valueMap.set(
|
|
2816
|
-
new Tracker(
|
|
3099
|
+
origin.logger.info(`\u{1F4C3}`, `atom`, atom2.key, `copying`);
|
|
3100
|
+
const jsonValue = atom2.toJson(originValue);
|
|
3101
|
+
const copiedValue = atom2.fromJson(jsonValue);
|
|
3102
|
+
target.valueMap.set(atom2.key, copiedValue);
|
|
3103
|
+
new Tracker(atom2, origin);
|
|
2817
3104
|
return copiedValue;
|
|
2818
3105
|
}
|
|
2819
3106
|
return targetValue;
|
|
2820
3107
|
}
|
|
2821
3108
|
|
|
2822
3109
|
// internal/src/caching.ts
|
|
2823
|
-
function cacheValue(key, value, subject
|
|
3110
|
+
function cacheValue(target, key, value, subject) {
|
|
2824
3111
|
const currentValue = target.valueMap.get(key);
|
|
2825
3112
|
if (currentValue instanceof Future) {
|
|
2826
3113
|
const future = currentValue;
|
|
@@ -2830,7 +3117,7 @@ function cacheValue(key, value, subject, target) {
|
|
|
2830
3117
|
const future = new Future(value);
|
|
2831
3118
|
target.valueMap.set(key, future);
|
|
2832
3119
|
future.then((resolved) => {
|
|
2833
|
-
cacheValue(key, resolved, subject
|
|
3120
|
+
cacheValue(target, key, resolved, subject);
|
|
2834
3121
|
subject.next({ newValue: resolved, oldValue: future });
|
|
2835
3122
|
}).catch((thrown) => {
|
|
2836
3123
|
target.logger.error(`\u{1F4A5}`, `state`, key, `rejected:`, thrown);
|
|
@@ -2844,7 +3131,7 @@ var readCachedValue = (token, target) => {
|
|
|
2844
3131
|
let value = target.valueMap.get(token.key);
|
|
2845
3132
|
if (token.type === `mutable_atom` && isChildStore(target)) {
|
|
2846
3133
|
const { parent } = target;
|
|
2847
|
-
const copiedValue = copyMutableIfNeeded(token, parent
|
|
3134
|
+
const copiedValue = copyMutableIfNeeded(target, token, parent);
|
|
2848
3135
|
value = copiedValue;
|
|
2849
3136
|
}
|
|
2850
3137
|
return value;
|
|
@@ -2853,9 +3140,9 @@ var evictCachedValue = (key, target) => {
|
|
|
2853
3140
|
const currentValue = target.valueMap.get(key);
|
|
2854
3141
|
if (currentValue instanceof Future) {
|
|
2855
3142
|
const future = currentValue;
|
|
2856
|
-
const
|
|
2857
|
-
if (
|
|
2858
|
-
future.use(
|
|
3143
|
+
const selector2 = target.selectors.get(key) ?? target.readonlySelectors.get(key);
|
|
3144
|
+
if (selector2) {
|
|
3145
|
+
future.use(selector2.get());
|
|
2859
3146
|
}
|
|
2860
3147
|
return;
|
|
2861
3148
|
}
|
|
@@ -2867,15 +3154,15 @@ var evictCachedValue = (key, target) => {
|
|
|
2867
3154
|
};
|
|
2868
3155
|
|
|
2869
3156
|
// internal/src/atom/is-default.ts
|
|
2870
|
-
var isAtomDefault = (
|
|
3157
|
+
var isAtomDefault = (store, key) => {
|
|
2871
3158
|
const core = newest(store);
|
|
2872
3159
|
return core.atomsThatAreDefault.has(key);
|
|
2873
3160
|
};
|
|
2874
|
-
var markAtomAsDefault = (
|
|
3161
|
+
var markAtomAsDefault = (store, key) => {
|
|
2875
3162
|
const core = newest(store);
|
|
2876
3163
|
core.atomsThatAreDefault = new Set(core.atomsThatAreDefault).add(key);
|
|
2877
3164
|
};
|
|
2878
|
-
var markAtomAsNotDefault = (
|
|
3165
|
+
var markAtomAsNotDefault = (store, key) => {
|
|
2879
3166
|
const core = newest(store);
|
|
2880
3167
|
core.atomsThatAreDefault = new Set(newest(store).atomsThatAreDefault);
|
|
2881
3168
|
core.atomsThatAreDefault.delete(key);
|
|
@@ -2923,8 +3210,8 @@ function createRegularAtom(store, options, family) {
|
|
|
2923
3210
|
initialValue = options.default();
|
|
2924
3211
|
}
|
|
2925
3212
|
target.atoms.set(newAtom.key, newAtom);
|
|
2926
|
-
markAtomAsDefault(options.key
|
|
2927
|
-
cacheValue(options.key, initialValue, subject
|
|
3213
|
+
markAtomAsDefault(store, options.key);
|
|
3214
|
+
cacheValue(target, options.key, initialValue, subject);
|
|
2928
3215
|
const token = deposit(newAtom);
|
|
2929
3216
|
if (options.effects) {
|
|
2930
3217
|
let effectIndex = 0;
|
|
@@ -2934,7 +3221,7 @@ function createRegularAtom(store, options, family) {
|
|
|
2934
3221
|
setSelf: (next) => {
|
|
2935
3222
|
setIntoStore(store, token, next);
|
|
2936
3223
|
},
|
|
2937
|
-
onSet: (handle) =>
|
|
3224
|
+
onSet: (handle) => subscribeToState(store, token, `effect[${effectIndex}]`, handle)
|
|
2938
3225
|
});
|
|
2939
3226
|
if (cleanup) {
|
|
2940
3227
|
cleanupFunctions.push(cleanup);
|
|
@@ -2964,23 +3251,23 @@ function createStandaloneAtom(store, options) {
|
|
|
2964
3251
|
}
|
|
2965
3252
|
|
|
2966
3253
|
// internal/src/atom/dispose-atom.ts
|
|
2967
|
-
function disposeAtom(
|
|
3254
|
+
function disposeAtom(store, atomToken) {
|
|
2968
3255
|
const target = newest(store);
|
|
2969
3256
|
const { key, family } = atomToken;
|
|
2970
|
-
const
|
|
3257
|
+
const atom2 = withdraw(target, atomToken);
|
|
2971
3258
|
if (!family) {
|
|
2972
3259
|
store.logger.error(`\u274C`, `atom`, key, `Standalone atoms cannot be disposed.`);
|
|
2973
3260
|
} else {
|
|
2974
|
-
|
|
2975
|
-
const lastValue = store.valueMap.get(
|
|
2976
|
-
const
|
|
3261
|
+
atom2.cleanup?.();
|
|
3262
|
+
const lastValue = store.valueMap.get(atom2.key);
|
|
3263
|
+
const atomFamily2 = withdraw(store, { key: family.key, type: `atom_family` });
|
|
2977
3264
|
const disposal = {
|
|
2978
3265
|
type: `state_disposal`,
|
|
2979
3266
|
subType: `atom`,
|
|
2980
3267
|
token: atomToken,
|
|
2981
3268
|
value: lastValue
|
|
2982
3269
|
};
|
|
2983
|
-
|
|
3270
|
+
atomFamily2.subject.next(disposal);
|
|
2984
3271
|
const isChild = isChildStore(target);
|
|
2985
3272
|
target.atoms.delete(key);
|
|
2986
3273
|
target.valueMap.delete(key);
|
|
@@ -2989,14 +3276,14 @@ function disposeAtom(atomToken, store) {
|
|
|
2989
3276
|
store.timelineTopics.delete(key);
|
|
2990
3277
|
if (atomToken.type === `mutable_atom`) {
|
|
2991
3278
|
const updateToken = getUpdateToken(atomToken);
|
|
2992
|
-
disposeAtom(
|
|
3279
|
+
disposeAtom(store, updateToken);
|
|
2993
3280
|
store.trackers.delete(key);
|
|
2994
3281
|
}
|
|
2995
3282
|
store.logger.info(`\u{1F525}`, `atom`, key, `deleted`);
|
|
2996
3283
|
if (isChild && target.transactionMeta.phase === `building`) {
|
|
2997
3284
|
const mostRecentUpdate = target.transactionMeta.update.updates.at(-1);
|
|
2998
3285
|
const wasMoleculeDisposal = mostRecentUpdate?.type === `molecule_disposal`;
|
|
2999
|
-
const updateAlreadyCaptured = wasMoleculeDisposal && mostRecentUpdate.values.some(([k]) => k ===
|
|
3286
|
+
const updateAlreadyCaptured = wasMoleculeDisposal && mostRecentUpdate.values.some(([k]) => k === atom2.family?.key);
|
|
3000
3287
|
if (!updateAlreadyCaptured) {
|
|
3001
3288
|
target.transactionMeta.update.updates.push(disposal);
|
|
3002
3289
|
}
|
|
@@ -3006,8 +3293,746 @@ function disposeAtom(atomToken, store) {
|
|
|
3006
3293
|
}
|
|
3007
3294
|
}
|
|
3008
3295
|
|
|
3296
|
+
// transceivers/set-rtx/src/set-rtx.ts
|
|
3297
|
+
var SetRTX = class _SetRTX extends Set {
|
|
3298
|
+
mode = `record`;
|
|
3299
|
+
subject = new Subject();
|
|
3300
|
+
cacheLimit = 0;
|
|
3301
|
+
cache = [];
|
|
3302
|
+
cacheIdx = -1;
|
|
3303
|
+
cacheUpdateNumber = -1;
|
|
3304
|
+
constructor(values, cacheLimit = 0) {
|
|
3305
|
+
super(values);
|
|
3306
|
+
if (values instanceof _SetRTX) {
|
|
3307
|
+
this.parent = values;
|
|
3308
|
+
this.cacheUpdateNumber = values.cacheUpdateNumber;
|
|
3309
|
+
}
|
|
3310
|
+
if (cacheLimit) {
|
|
3311
|
+
this.cacheLimit = cacheLimit;
|
|
3312
|
+
this.cache = new Array(cacheLimit);
|
|
3313
|
+
this.subscribe(`auto cache`, (update) => {
|
|
3314
|
+
this.cacheIdx++;
|
|
3315
|
+
this.cacheIdx %= this.cacheLimit;
|
|
3316
|
+
this.cache[this.cacheIdx] = update;
|
|
3317
|
+
});
|
|
3318
|
+
}
|
|
3319
|
+
}
|
|
3320
|
+
toJSON() {
|
|
3321
|
+
return {
|
|
3322
|
+
members: [...this],
|
|
3323
|
+
cache: this.cache,
|
|
3324
|
+
cacheLimit: this.cacheLimit,
|
|
3325
|
+
cacheIdx: this.cacheIdx,
|
|
3326
|
+
cacheUpdateNumber: this.cacheUpdateNumber
|
|
3327
|
+
};
|
|
3328
|
+
}
|
|
3329
|
+
static fromJSON(json) {
|
|
3330
|
+
const set = new _SetRTX(json.members, json.cacheLimit);
|
|
3331
|
+
set.cache = json.cache;
|
|
3332
|
+
set.cacheIdx = json.cacheIdx;
|
|
3333
|
+
set.cacheUpdateNumber = json.cacheUpdateNumber;
|
|
3334
|
+
return set;
|
|
3335
|
+
}
|
|
3336
|
+
add(value) {
|
|
3337
|
+
const result = super.add(value);
|
|
3338
|
+
if (this.mode === `record`) {
|
|
3339
|
+
this.cacheUpdateNumber++;
|
|
3340
|
+
this.emit(`add:${stringifyJson(value)}`);
|
|
3341
|
+
}
|
|
3342
|
+
return result;
|
|
3343
|
+
}
|
|
3344
|
+
clear() {
|
|
3345
|
+
const capturedContents = this.mode === `record` ? [...this] : null;
|
|
3346
|
+
super.clear();
|
|
3347
|
+
if (capturedContents) {
|
|
3348
|
+
this.cacheUpdateNumber++;
|
|
3349
|
+
this.emit(`clear:${JSON.stringify(capturedContents)}`);
|
|
3350
|
+
}
|
|
3351
|
+
}
|
|
3352
|
+
delete(value) {
|
|
3353
|
+
const result = super.delete(value);
|
|
3354
|
+
if (this.mode === `record`) {
|
|
3355
|
+
this.cacheUpdateNumber++;
|
|
3356
|
+
this.emit(`del:${stringifyJson(value)}`);
|
|
3357
|
+
}
|
|
3358
|
+
return result;
|
|
3359
|
+
}
|
|
3360
|
+
parent;
|
|
3361
|
+
child = null;
|
|
3362
|
+
transactionUpdates = null;
|
|
3363
|
+
transaction(run) {
|
|
3364
|
+
this.mode = `transaction`;
|
|
3365
|
+
this.transactionUpdates = [];
|
|
3366
|
+
this.child = new _SetRTX(this);
|
|
3367
|
+
const unsubscribe = this.child._subscribe(`transaction`, (update) => {
|
|
3368
|
+
this.transactionUpdates?.push(update);
|
|
3369
|
+
});
|
|
3370
|
+
try {
|
|
3371
|
+
const shouldCommit = run(this.child);
|
|
3372
|
+
if (shouldCommit) {
|
|
3373
|
+
for (const update of this.transactionUpdates) {
|
|
3374
|
+
this.doStep(update);
|
|
3375
|
+
}
|
|
3376
|
+
this.cacheUpdateNumber++;
|
|
3377
|
+
this.emit(`tx:${this.transactionUpdates.join(`;`)}`);
|
|
3378
|
+
}
|
|
3379
|
+
} catch (thrown) {
|
|
3380
|
+
console.warn(
|
|
3381
|
+
`Did not apply transaction to SetRTX; this error was thrown:`,
|
|
3382
|
+
thrown
|
|
3383
|
+
);
|
|
3384
|
+
throw thrown;
|
|
3385
|
+
} finally {
|
|
3386
|
+
unsubscribe();
|
|
3387
|
+
this.child = null;
|
|
3388
|
+
this.transactionUpdates = null;
|
|
3389
|
+
this.mode = `record`;
|
|
3390
|
+
}
|
|
3391
|
+
}
|
|
3392
|
+
_subscribe(key, fn) {
|
|
3393
|
+
return this.subject.subscribe(key, fn);
|
|
3394
|
+
}
|
|
3395
|
+
subscribe(key, fn) {
|
|
3396
|
+
return this.subject.subscribe(key, (update) => {
|
|
3397
|
+
fn(`${this.cacheUpdateNumber}=${update}`);
|
|
3398
|
+
});
|
|
3399
|
+
}
|
|
3400
|
+
emit(update) {
|
|
3401
|
+
this.subject.next(update);
|
|
3402
|
+
}
|
|
3403
|
+
doStep(update) {
|
|
3404
|
+
const typeValueBreak = update.indexOf(`:`);
|
|
3405
|
+
const type = update.substring(0, typeValueBreak);
|
|
3406
|
+
const value = update.substring(typeValueBreak + 1);
|
|
3407
|
+
switch (type) {
|
|
3408
|
+
case `add`:
|
|
3409
|
+
this.add(JSON.parse(value));
|
|
3410
|
+
break;
|
|
3411
|
+
case `clear`:
|
|
3412
|
+
this.clear();
|
|
3413
|
+
break;
|
|
3414
|
+
case `del`:
|
|
3415
|
+
this.delete(JSON.parse(value));
|
|
3416
|
+
break;
|
|
3417
|
+
case `tx`:
|
|
3418
|
+
for (const subUpdate of value.split(`;`)) {
|
|
3419
|
+
this.doStep(subUpdate);
|
|
3420
|
+
}
|
|
3421
|
+
}
|
|
3422
|
+
}
|
|
3423
|
+
getUpdateNumber(update) {
|
|
3424
|
+
const breakpoint = update.indexOf(`=`);
|
|
3425
|
+
return Number(update.substring(0, breakpoint));
|
|
3426
|
+
}
|
|
3427
|
+
do(update) {
|
|
3428
|
+
const breakpoint = update.indexOf(`=`);
|
|
3429
|
+
const updateNumber = Number(update.substring(0, breakpoint));
|
|
3430
|
+
const eventOffset = updateNumber - this.cacheUpdateNumber;
|
|
3431
|
+
const isFuture = eventOffset > 0;
|
|
3432
|
+
if (isFuture) {
|
|
3433
|
+
if (eventOffset === 1) {
|
|
3434
|
+
this.mode = `playback`;
|
|
3435
|
+
const innerUpdate = update.substring(breakpoint + 1);
|
|
3436
|
+
this.doStep(innerUpdate);
|
|
3437
|
+
this.mode = `record`;
|
|
3438
|
+
this.cacheUpdateNumber = updateNumber;
|
|
3439
|
+
return null;
|
|
3440
|
+
}
|
|
3441
|
+
return this.cacheUpdateNumber + 1;
|
|
3442
|
+
}
|
|
3443
|
+
if (Math.abs(eventOffset) < this.cacheLimit) {
|
|
3444
|
+
const eventIdx = this.cacheIdx + eventOffset;
|
|
3445
|
+
const cachedUpdate = this.cache[eventIdx];
|
|
3446
|
+
if (cachedUpdate === update) {
|
|
3447
|
+
return null;
|
|
3448
|
+
}
|
|
3449
|
+
this.mode = `playback`;
|
|
3450
|
+
let done = false;
|
|
3451
|
+
while (!done) {
|
|
3452
|
+
this.cacheIdx %= this.cacheLimit;
|
|
3453
|
+
const u = this.cache[this.cacheIdx];
|
|
3454
|
+
this.cacheIdx--;
|
|
3455
|
+
if (!u) {
|
|
3456
|
+
return `OUT_OF_RANGE`;
|
|
3457
|
+
}
|
|
3458
|
+
this.undo(u);
|
|
3459
|
+
done = this.cacheIdx === eventIdx - 1;
|
|
3460
|
+
}
|
|
3461
|
+
const innerUpdate = update.substring(breakpoint + 1);
|
|
3462
|
+
this.doStep(innerUpdate);
|
|
3463
|
+
this.mode = `record`;
|
|
3464
|
+
this.cacheUpdateNumber = updateNumber;
|
|
3465
|
+
return null;
|
|
3466
|
+
}
|
|
3467
|
+
return `OUT_OF_RANGE`;
|
|
3468
|
+
}
|
|
3469
|
+
undoStep(update) {
|
|
3470
|
+
const breakpoint = update.indexOf(`:`);
|
|
3471
|
+
const type = update.substring(0, breakpoint);
|
|
3472
|
+
const value = update.substring(breakpoint + 1);
|
|
3473
|
+
switch (type) {
|
|
3474
|
+
case `add`:
|
|
3475
|
+
this.delete(JSON.parse(value));
|
|
3476
|
+
break;
|
|
3477
|
+
case `del`:
|
|
3478
|
+
this.add(JSON.parse(value));
|
|
3479
|
+
break;
|
|
3480
|
+
case `clear`: {
|
|
3481
|
+
const values = JSON.parse(value);
|
|
3482
|
+
for (const v of values) this.add(v);
|
|
3483
|
+
break;
|
|
3484
|
+
}
|
|
3485
|
+
case `tx`: {
|
|
3486
|
+
const updates = value.split(`;`);
|
|
3487
|
+
for (let i = updates.length - 1; i >= 0; i--) {
|
|
3488
|
+
this.undoStep(updates[i]);
|
|
3489
|
+
}
|
|
3490
|
+
}
|
|
3491
|
+
}
|
|
3492
|
+
}
|
|
3493
|
+
undo(update) {
|
|
3494
|
+
const breakpoint = update.indexOf(`=`);
|
|
3495
|
+
const updateNumber = Number(update.substring(0, breakpoint));
|
|
3496
|
+
if (updateNumber === this.cacheUpdateNumber) {
|
|
3497
|
+
this.mode = `playback`;
|
|
3498
|
+
const innerUpdate = update.substring(breakpoint + 1);
|
|
3499
|
+
this.undoStep(innerUpdate);
|
|
3500
|
+
this.mode = `record`;
|
|
3501
|
+
this.cacheUpdateNumber--;
|
|
3502
|
+
return null;
|
|
3503
|
+
}
|
|
3504
|
+
return this.cacheUpdateNumber;
|
|
3505
|
+
}
|
|
3506
|
+
};
|
|
3507
|
+
|
|
3508
|
+
// internal/src/join/join-internal.ts
|
|
3509
|
+
var Join = class {
|
|
3510
|
+
toolkit;
|
|
3511
|
+
options;
|
|
3512
|
+
defaultContent;
|
|
3513
|
+
molecules = /* @__PURE__ */ new Map();
|
|
3514
|
+
relations;
|
|
3515
|
+
states;
|
|
3516
|
+
core;
|
|
3517
|
+
transact(toolkit, run) {
|
|
3518
|
+
const originalToolkit = this.toolkit;
|
|
3519
|
+
this.toolkit = toolkit;
|
|
3520
|
+
run(this);
|
|
3521
|
+
this.toolkit = originalToolkit;
|
|
3522
|
+
}
|
|
3523
|
+
store;
|
|
3524
|
+
realm;
|
|
3525
|
+
[Symbol.dispose]() {
|
|
3526
|
+
}
|
|
3527
|
+
constructor(options, defaultContent, store = IMPLICIT.STORE) {
|
|
3528
|
+
this.store = store;
|
|
3529
|
+
this.realm = new Anarchy(store);
|
|
3530
|
+
this.options = options;
|
|
3531
|
+
this.defaultContent = defaultContent;
|
|
3532
|
+
this.store.miscResources.set(`join:${options.key}`, this);
|
|
3533
|
+
this.realm.allocate(`root`, options.key);
|
|
3534
|
+
this.toolkit = {
|
|
3535
|
+
get: (...ps) => getFromStore(store, ...ps),
|
|
3536
|
+
set: (...ps) => {
|
|
3537
|
+
setIntoStore(store, ...ps);
|
|
3538
|
+
},
|
|
3539
|
+
find: (...ps) => findInStore(store, ...ps),
|
|
3540
|
+
json: (token) => getJsonToken(store, token)
|
|
3541
|
+
};
|
|
3542
|
+
const aSide = options.between[0];
|
|
3543
|
+
const bSide = options.between[1];
|
|
3544
|
+
const relatedKeysAtoms = createMutableAtomFamily(
|
|
3545
|
+
store,
|
|
3546
|
+
{
|
|
3547
|
+
key: `${options.key}/relatedKeys`,
|
|
3548
|
+
default: () => new SetRTX(),
|
|
3549
|
+
mutable: true,
|
|
3550
|
+
fromJson: (json) => SetRTX.fromJSON(json),
|
|
3551
|
+
toJson: (set) => set.toJSON()
|
|
3552
|
+
},
|
|
3553
|
+
[`join`, `relations`]
|
|
3554
|
+
);
|
|
3555
|
+
this.core = { relatedKeysAtoms };
|
|
3556
|
+
const getRelatedKeys = ({ get }, key) => get(relatedKeysAtoms, key);
|
|
3557
|
+
const addRelation = ({ set }, a, b) => {
|
|
3558
|
+
if (!this.store.molecules.has(stringifyJson(a))) {
|
|
3559
|
+
this.realm.allocate(options.key, a);
|
|
3560
|
+
}
|
|
3561
|
+
set(relatedKeysAtoms, a, (aKeys) => aKeys.add(b));
|
|
3562
|
+
set(relatedKeysAtoms, b, (bKeys) => bKeys.add(a));
|
|
3563
|
+
};
|
|
3564
|
+
const deleteRelation = ({ set }, a, b) => {
|
|
3565
|
+
set(relatedKeysAtoms, a, (aKeys) => {
|
|
3566
|
+
aKeys.delete(b);
|
|
3567
|
+
return aKeys;
|
|
3568
|
+
});
|
|
3569
|
+
set(relatedKeysAtoms, b, (bKeys) => {
|
|
3570
|
+
bKeys.delete(a);
|
|
3571
|
+
return bKeys;
|
|
3572
|
+
});
|
|
3573
|
+
};
|
|
3574
|
+
const replaceRelationsSafely = (toolkit, a, newRelationsOfA) => {
|
|
3575
|
+
const { find, get, set } = toolkit;
|
|
3576
|
+
const relationsOfAState = find(relatedKeysAtoms, a);
|
|
3577
|
+
const currentRelationsOfA = get(relationsOfAState);
|
|
3578
|
+
for (const currentRelationB of currentRelationsOfA) {
|
|
3579
|
+
const remainsRelated = newRelationsOfA.includes(currentRelationB);
|
|
3580
|
+
if (remainsRelated) {
|
|
3581
|
+
continue;
|
|
3582
|
+
}
|
|
3583
|
+
set(relatedKeysAtoms, currentRelationB, (relationsOfB) => {
|
|
3584
|
+
relationsOfB.delete(a);
|
|
3585
|
+
return relationsOfB;
|
|
3586
|
+
});
|
|
3587
|
+
}
|
|
3588
|
+
set(relationsOfAState, (relationsOfA) => {
|
|
3589
|
+
relationsOfA.transaction((nextRelationsOfA) => {
|
|
3590
|
+
nextRelationsOfA.clear();
|
|
3591
|
+
for (const newRelationB of newRelationsOfA) {
|
|
3592
|
+
const relationsOfB = getRelatedKeys(toolkit, newRelationB);
|
|
3593
|
+
const newRelationBIsAlreadyRelated = relationsOfB.has(a);
|
|
3594
|
+
if (this.relations.cardinality === `1:n`) {
|
|
3595
|
+
const previousOwnersToDispose = [];
|
|
3596
|
+
for (const previousOwner of relationsOfB) {
|
|
3597
|
+
if (previousOwner === a) {
|
|
3598
|
+
continue;
|
|
3599
|
+
}
|
|
3600
|
+
const previousOwnerRelations = getRelatedKeys(
|
|
3601
|
+
toolkit,
|
|
3602
|
+
previousOwner
|
|
3603
|
+
);
|
|
3604
|
+
previousOwnerRelations.delete(newRelationB);
|
|
3605
|
+
if (previousOwnerRelations.size === 0) {
|
|
3606
|
+
previousOwnersToDispose.push(previousOwner);
|
|
3607
|
+
}
|
|
3608
|
+
}
|
|
3609
|
+
if (!newRelationBIsAlreadyRelated && relationsOfB.size > 0) {
|
|
3610
|
+
relationsOfB.clear();
|
|
3611
|
+
}
|
|
3612
|
+
for (const previousOwner of previousOwnersToDispose) {
|
|
3613
|
+
const sorted = [newRelationB, previousOwner].sort();
|
|
3614
|
+
const compositeKey = `"${sorted[0]}:${sorted[1]}"`;
|
|
3615
|
+
this.molecules.delete(compositeKey);
|
|
3616
|
+
}
|
|
3617
|
+
}
|
|
3618
|
+
if (!newRelationBIsAlreadyRelated) {
|
|
3619
|
+
relationsOfB.add(a);
|
|
3620
|
+
}
|
|
3621
|
+
nextRelationsOfA.add(newRelationB);
|
|
3622
|
+
}
|
|
3623
|
+
return true;
|
|
3624
|
+
});
|
|
3625
|
+
return relationsOfA;
|
|
3626
|
+
});
|
|
3627
|
+
};
|
|
3628
|
+
const replaceRelationsUnsafely = (toolkit, a, newRelationsOfA) => {
|
|
3629
|
+
const { set } = toolkit;
|
|
3630
|
+
set(relatedKeysAtoms, a, (relationsOfA) => {
|
|
3631
|
+
relationsOfA.transaction((nextRelationsOfA) => {
|
|
3632
|
+
for (const newRelationB of newRelationsOfA) {
|
|
3633
|
+
nextRelationsOfA.add(newRelationB);
|
|
3634
|
+
}
|
|
3635
|
+
return true;
|
|
3636
|
+
});
|
|
3637
|
+
return relationsOfA;
|
|
3638
|
+
});
|
|
3639
|
+
for (const newRelationB of newRelationsOfA) {
|
|
3640
|
+
set(relatedKeysAtoms, newRelationB, (newRelationsB) => {
|
|
3641
|
+
newRelationsB.add(a);
|
|
3642
|
+
return newRelationsB;
|
|
3643
|
+
});
|
|
3644
|
+
}
|
|
3645
|
+
return true;
|
|
3646
|
+
};
|
|
3647
|
+
const has = (toolkit, a, b) => {
|
|
3648
|
+
const aKeys = getRelatedKeys(toolkit, a);
|
|
3649
|
+
return b ? aKeys.has(b) : aKeys.size > 0;
|
|
3650
|
+
};
|
|
3651
|
+
const baseExternalStoreConfiguration = {
|
|
3652
|
+
getRelatedKeys: (key) => getRelatedKeys(this.toolkit, key),
|
|
3653
|
+
addRelation: (a, b) => {
|
|
3654
|
+
this.store.moleculeJoins.set(
|
|
3655
|
+
a,
|
|
3656
|
+
options.key
|
|
3657
|
+
);
|
|
3658
|
+
this.store.moleculeJoins.set(
|
|
3659
|
+
b,
|
|
3660
|
+
options.key
|
|
3661
|
+
);
|
|
3662
|
+
addRelation(this.toolkit, a, b);
|
|
3663
|
+
},
|
|
3664
|
+
deleteRelation: (a, b) => {
|
|
3665
|
+
deleteRelation(this.toolkit, a, b);
|
|
3666
|
+
},
|
|
3667
|
+
replaceRelationsSafely: (a, bs) => {
|
|
3668
|
+
replaceRelationsSafely(this.toolkit, a, bs);
|
|
3669
|
+
},
|
|
3670
|
+
replaceRelationsUnsafely: (a, bs) => {
|
|
3671
|
+
replaceRelationsUnsafely(this.toolkit, a, bs);
|
|
3672
|
+
},
|
|
3673
|
+
has: (a, b) => has(this.toolkit, a, b)
|
|
3674
|
+
};
|
|
3675
|
+
let externalStore;
|
|
3676
|
+
let contentAtoms;
|
|
3677
|
+
if (defaultContent) {
|
|
3678
|
+
contentAtoms = createRegularAtomFamily(
|
|
3679
|
+
store,
|
|
3680
|
+
{
|
|
3681
|
+
key: `${options.key}/content`,
|
|
3682
|
+
default: defaultContent
|
|
3683
|
+
},
|
|
3684
|
+
[`join`, `content`]
|
|
3685
|
+
);
|
|
3686
|
+
const getContent = ({ get }, key) => get(contentAtoms, key);
|
|
3687
|
+
const setContent = ({ set }, key, content) => {
|
|
3688
|
+
set(contentAtoms, key, content);
|
|
3689
|
+
};
|
|
3690
|
+
const externalStoreWithContentConfiguration = {
|
|
3691
|
+
getContent: (contentKey) => {
|
|
3692
|
+
const content = getContent(this.toolkit, contentKey);
|
|
3693
|
+
return content;
|
|
3694
|
+
},
|
|
3695
|
+
setContent: (contentKey, content) => {
|
|
3696
|
+
setContent(this.toolkit, contentKey, content);
|
|
3697
|
+
},
|
|
3698
|
+
deleteContent: (contentKey) => {
|
|
3699
|
+
this.realm.deallocate(contentKey);
|
|
3700
|
+
}
|
|
3701
|
+
};
|
|
3702
|
+
externalStore = Object.assign(
|
|
3703
|
+
baseExternalStoreConfiguration,
|
|
3704
|
+
externalStoreWithContentConfiguration
|
|
3705
|
+
);
|
|
3706
|
+
} else {
|
|
3707
|
+
externalStore = baseExternalStoreConfiguration;
|
|
3708
|
+
}
|
|
3709
|
+
const relations = new Junction(
|
|
3710
|
+
options,
|
|
3711
|
+
{
|
|
3712
|
+
externalStore,
|
|
3713
|
+
isAType: options.isAType,
|
|
3714
|
+
isBType: options.isBType,
|
|
3715
|
+
makeContentKey: (...args) => {
|
|
3716
|
+
const [a, b] = args;
|
|
3717
|
+
const sorted = args.sort();
|
|
3718
|
+
const compositeKey = `${sorted[0]}:${sorted[1]}`;
|
|
3719
|
+
const aMolecule = store.molecules.get(stringifyJson(a));
|
|
3720
|
+
const bMolecule = store.molecules.get(stringifyJson(b));
|
|
3721
|
+
if (!aMolecule) {
|
|
3722
|
+
this.realm.allocate(options.key, a);
|
|
3723
|
+
}
|
|
3724
|
+
if (!bMolecule) {
|
|
3725
|
+
this.realm.allocate(options.key, b);
|
|
3726
|
+
}
|
|
3727
|
+
this.realm.allocate(a, compositeKey, `all`);
|
|
3728
|
+
this.realm.claim(b, compositeKey);
|
|
3729
|
+
this.store.moleculeJoins.set(compositeKey, options.key);
|
|
3730
|
+
return compositeKey;
|
|
3731
|
+
}
|
|
3732
|
+
}
|
|
3733
|
+
);
|
|
3734
|
+
const createSingleKeySelectorFamily = () => createReadonlySelectorFamily(
|
|
3735
|
+
store,
|
|
3736
|
+
{
|
|
3737
|
+
key: `${options.key}/singleRelatedKey`,
|
|
3738
|
+
get: (key) => ({ get }) => {
|
|
3739
|
+
const relatedKeys = get(relatedKeysAtoms, key);
|
|
3740
|
+
for (const relatedKey of relatedKeys) {
|
|
3741
|
+
return relatedKey;
|
|
3742
|
+
}
|
|
3743
|
+
return null;
|
|
3744
|
+
}
|
|
3745
|
+
},
|
|
3746
|
+
[`join`, `keys`]
|
|
3747
|
+
);
|
|
3748
|
+
const getMultipleKeySelectorFamily = () => {
|
|
3749
|
+
return createReadonlySelectorFamily(
|
|
3750
|
+
store,
|
|
3751
|
+
{
|
|
3752
|
+
key: `${options.key}/multipleRelatedKeys`,
|
|
3753
|
+
get: (key) => ({ get }) => {
|
|
3754
|
+
const jsonFamily = getJsonFamily(relatedKeysAtoms, store);
|
|
3755
|
+
const json = get(jsonFamily, key);
|
|
3756
|
+
return json.members;
|
|
3757
|
+
}
|
|
3758
|
+
},
|
|
3759
|
+
[`join`, `keys`]
|
|
3760
|
+
);
|
|
3761
|
+
};
|
|
3762
|
+
const createSingleEntrySelectorFamily = () => createReadonlySelectorFamily(
|
|
3763
|
+
store,
|
|
3764
|
+
{
|
|
3765
|
+
key: `${options.key}/singleRelatedEntry`,
|
|
3766
|
+
get: (x) => ({ get }) => {
|
|
3767
|
+
const relatedKeys = get(relatedKeysAtoms, x);
|
|
3768
|
+
for (const y of relatedKeys) {
|
|
3769
|
+
let a = relations.isAType?.(x) ? x : undefined;
|
|
3770
|
+
let b = a === undefined ? x : undefined;
|
|
3771
|
+
a ??= y;
|
|
3772
|
+
b ??= y;
|
|
3773
|
+
const contentKey = relations.makeContentKey(a, b);
|
|
3774
|
+
const content = get(contentAtoms, contentKey);
|
|
3775
|
+
return [y, content];
|
|
3776
|
+
}
|
|
3777
|
+
return null;
|
|
3778
|
+
}
|
|
3779
|
+
},
|
|
3780
|
+
[`join`, `entries`]
|
|
3781
|
+
);
|
|
3782
|
+
const getMultipleEntrySelectorFamily = () => createReadonlySelectorFamily(
|
|
3783
|
+
store,
|
|
3784
|
+
{
|
|
3785
|
+
key: `${options.key}/multipleRelatedEntries`,
|
|
3786
|
+
get: (x) => ({ get }) => {
|
|
3787
|
+
const jsonFamily = getJsonFamily(relatedKeysAtoms, store);
|
|
3788
|
+
const json = get(jsonFamily, x);
|
|
3789
|
+
return json.members.map((y) => {
|
|
3790
|
+
let a = relations.isAType?.(x) ? x : undefined;
|
|
3791
|
+
let b = a === undefined ? x : undefined;
|
|
3792
|
+
a ??= y;
|
|
3793
|
+
b ??= y;
|
|
3794
|
+
const contentKey = relations.makeContentKey(a, b);
|
|
3795
|
+
const content = get(contentAtoms, contentKey);
|
|
3796
|
+
return [y, content];
|
|
3797
|
+
});
|
|
3798
|
+
}
|
|
3799
|
+
},
|
|
3800
|
+
[`join`, `entries`]
|
|
3801
|
+
);
|
|
3802
|
+
switch (options.cardinality) {
|
|
3803
|
+
case `1:1`: {
|
|
3804
|
+
const singleRelatedKeySelectors = createSingleKeySelectorFamily();
|
|
3805
|
+
const stateKeyA = `${aSide}KeyOf${capitalize(bSide)}`;
|
|
3806
|
+
const stateKeyB = `${bSide}KeyOf${capitalize(aSide)}`;
|
|
3807
|
+
const baseStates = {
|
|
3808
|
+
[stateKeyA]: singleRelatedKeySelectors,
|
|
3809
|
+
[stateKeyB]: singleRelatedKeySelectors
|
|
3810
|
+
};
|
|
3811
|
+
let states;
|
|
3812
|
+
if (defaultContent) {
|
|
3813
|
+
const singleEntrySelectors = createSingleEntrySelectorFamily();
|
|
3814
|
+
const entriesStateKeyA = `${aSide}EntryOf${capitalize(bSide)}`;
|
|
3815
|
+
const entriesStateKeyB = `${bSide}EntryOf${capitalize(aSide)}`;
|
|
3816
|
+
const contentStates = {
|
|
3817
|
+
[entriesStateKeyA]: singleEntrySelectors,
|
|
3818
|
+
[entriesStateKeyB]: singleEntrySelectors
|
|
3819
|
+
};
|
|
3820
|
+
states = Object.assign(baseStates, contentStates);
|
|
3821
|
+
} else {
|
|
3822
|
+
states = baseStates;
|
|
3823
|
+
}
|
|
3824
|
+
this.relations = relations;
|
|
3825
|
+
this.states = states;
|
|
3826
|
+
break;
|
|
3827
|
+
}
|
|
3828
|
+
case `1:n`: {
|
|
3829
|
+
const singleRelatedKeySelectors = createSingleKeySelectorFamily();
|
|
3830
|
+
const multipleRelatedKeysSelectors = getMultipleKeySelectorFamily();
|
|
3831
|
+
const stateKeyA = `${aSide}KeyOf${capitalize(bSide)}`;
|
|
3832
|
+
const stateKeyB = `${bSide}KeysOf${capitalize(aSide)}`;
|
|
3833
|
+
const baseStates = {
|
|
3834
|
+
[stateKeyA]: singleRelatedKeySelectors,
|
|
3835
|
+
[stateKeyB]: multipleRelatedKeysSelectors
|
|
3836
|
+
};
|
|
3837
|
+
let states;
|
|
3838
|
+
if (defaultContent) {
|
|
3839
|
+
const singleRelatedEntrySelectors = createSingleEntrySelectorFamily();
|
|
3840
|
+
const multipleRelatedEntriesSelectors = getMultipleEntrySelectorFamily();
|
|
3841
|
+
const entriesStateKeyA = `${aSide}EntryOf${capitalize(bSide)}`;
|
|
3842
|
+
const entriesStateKeyB = `${bSide}EntriesOf${capitalize(
|
|
3843
|
+
aSide
|
|
3844
|
+
)}`;
|
|
3845
|
+
const contentStates = {
|
|
3846
|
+
[entriesStateKeyA]: singleRelatedEntrySelectors,
|
|
3847
|
+
[entriesStateKeyB]: multipleRelatedEntriesSelectors
|
|
3848
|
+
};
|
|
3849
|
+
states = Object.assign(baseStates, contentStates);
|
|
3850
|
+
} else {
|
|
3851
|
+
states = baseStates;
|
|
3852
|
+
}
|
|
3853
|
+
this.relations = relations;
|
|
3854
|
+
this.states = states;
|
|
3855
|
+
break;
|
|
3856
|
+
}
|
|
3857
|
+
default: {
|
|
3858
|
+
const multipleRelatedKeysSelectors = getMultipleKeySelectorFamily();
|
|
3859
|
+
const stateKeyA = `${aSide}KeysOf${capitalize(bSide)}`;
|
|
3860
|
+
const stateKeyB = `${bSide}KeysOf${capitalize(aSide)}`;
|
|
3861
|
+
const baseStates = {
|
|
3862
|
+
[stateKeyA]: multipleRelatedKeysSelectors,
|
|
3863
|
+
[stateKeyB]: multipleRelatedKeysSelectors
|
|
3864
|
+
};
|
|
3865
|
+
let states;
|
|
3866
|
+
if (defaultContent) {
|
|
3867
|
+
const multipleRelatedEntriesSelectors = getMultipleEntrySelectorFamily();
|
|
3868
|
+
const entriesStateKeyA = `${aSide}EntriesOf${capitalize(
|
|
3869
|
+
bSide
|
|
3870
|
+
)}`;
|
|
3871
|
+
const entriesStateKeyB = `${bSide}EntriesOf${capitalize(
|
|
3872
|
+
aSide
|
|
3873
|
+
)}`;
|
|
3874
|
+
const contentStates = {
|
|
3875
|
+
[entriesStateKeyA]: multipleRelatedEntriesSelectors,
|
|
3876
|
+
[entriesStateKeyB]: multipleRelatedEntriesSelectors
|
|
3877
|
+
};
|
|
3878
|
+
states = Object.assign(baseStates, contentStates);
|
|
3879
|
+
} else {
|
|
3880
|
+
states = baseStates;
|
|
3881
|
+
}
|
|
3882
|
+
this.relations = relations;
|
|
3883
|
+
this.states = states;
|
|
3884
|
+
}
|
|
3885
|
+
}
|
|
3886
|
+
}
|
|
3887
|
+
};
|
|
3888
|
+
|
|
3889
|
+
// internal/src/join/get-join.ts
|
|
3890
|
+
function getJoin(token, store) {
|
|
3891
|
+
let myJoin = store.joins.get(token.key);
|
|
3892
|
+
if (myJoin === undefined) {
|
|
3893
|
+
const rootJoinMap = IMPLICIT.STORE.joins;
|
|
3894
|
+
const rootJoin = rootJoinMap.get(token.key);
|
|
3895
|
+
if (rootJoin === undefined) {
|
|
3896
|
+
throw new Error(
|
|
3897
|
+
`Join "${token.key}" not found in store "${store.config.name}"`
|
|
3898
|
+
);
|
|
3899
|
+
}
|
|
3900
|
+
myJoin = new Join(rootJoin.options, rootJoin.defaultContent, store);
|
|
3901
|
+
store.joins.set(token.key, myJoin);
|
|
3902
|
+
}
|
|
3903
|
+
return myJoin;
|
|
3904
|
+
}
|
|
3905
|
+
|
|
3906
|
+
// internal/src/join/edit-relations-in-store.ts
|
|
3907
|
+
function editRelationsInStore(token, change, store) {
|
|
3908
|
+
const myJoin = getJoin(token, store);
|
|
3909
|
+
const target = newest(store);
|
|
3910
|
+
if (isChildStore(target)) {
|
|
3911
|
+
const { toolkit } = target.transactionMeta;
|
|
3912
|
+
myJoin.transact(toolkit, ({ relations }) => {
|
|
3913
|
+
change(relations);
|
|
3914
|
+
});
|
|
3915
|
+
} else {
|
|
3916
|
+
change(myJoin.relations);
|
|
3917
|
+
}
|
|
3918
|
+
}
|
|
3919
|
+
|
|
3920
|
+
// internal/src/join/find-relations-in-store.ts
|
|
3921
|
+
function findRelationsInStore(token, key, store) {
|
|
3922
|
+
const myJoin = getJoin(token, store);
|
|
3923
|
+
let relations;
|
|
3924
|
+
switch (token.cardinality) {
|
|
3925
|
+
case `1:1`: {
|
|
3926
|
+
const keyAB = `${token.a}KeyOf${capitalize(token.b)}`;
|
|
3927
|
+
const keyBA = `${token.b}KeyOf${capitalize(token.a)}`;
|
|
3928
|
+
relations = {
|
|
3929
|
+
get [keyAB]() {
|
|
3930
|
+
const familyAB = myJoin.states[keyAB];
|
|
3931
|
+
const state = findInStore(store, familyAB, key);
|
|
3932
|
+
return state;
|
|
3933
|
+
},
|
|
3934
|
+
get [keyBA]() {
|
|
3935
|
+
const familyBA = myJoin.states[keyBA];
|
|
3936
|
+
const state = findInStore(store, familyBA, key);
|
|
3937
|
+
return state;
|
|
3938
|
+
}
|
|
3939
|
+
};
|
|
3940
|
+
const entryAB = `${token.a}EntryOf${capitalize(token.b)}`;
|
|
3941
|
+
if (entryAB in myJoin.states) {
|
|
3942
|
+
const entryBA = `${token.b}EntryOf${capitalize(token.a)}`;
|
|
3943
|
+
Object.assign(relations, {
|
|
3944
|
+
get [entryAB]() {
|
|
3945
|
+
const familyAB = myJoin.states[entryAB];
|
|
3946
|
+
const state = findInStore(store, familyAB, key);
|
|
3947
|
+
return state;
|
|
3948
|
+
},
|
|
3949
|
+
get [entryBA]() {
|
|
3950
|
+
const familyBA = myJoin.states[entryBA];
|
|
3951
|
+
const state = findInStore(store, familyBA, key);
|
|
3952
|
+
return state;
|
|
3953
|
+
}
|
|
3954
|
+
});
|
|
3955
|
+
}
|
|
3956
|
+
break;
|
|
3957
|
+
}
|
|
3958
|
+
case `1:n`: {
|
|
3959
|
+
const keyAB = `${token.a}KeyOf${capitalize(token.b)}`;
|
|
3960
|
+
const keysBA = `${token.b}KeysOf${capitalize(token.a)}`;
|
|
3961
|
+
relations = {
|
|
3962
|
+
get [keyAB]() {
|
|
3963
|
+
const familyAB = myJoin.states[keyAB];
|
|
3964
|
+
const state = findInStore(store, familyAB, key);
|
|
3965
|
+
return state;
|
|
3966
|
+
},
|
|
3967
|
+
get [keysBA]() {
|
|
3968
|
+
const familyBA = myJoin.states[keysBA];
|
|
3969
|
+
const state = findInStore(store, familyBA, key);
|
|
3970
|
+
return state;
|
|
3971
|
+
}
|
|
3972
|
+
};
|
|
3973
|
+
const entryAB = `${token.a}EntryOf${capitalize(token.b)}`;
|
|
3974
|
+
if (entryAB in myJoin.states) {
|
|
3975
|
+
const entriesBA = `${token.b}EntriesOf${capitalize(token.a)}`;
|
|
3976
|
+
Object.assign(relations, {
|
|
3977
|
+
get [entryAB]() {
|
|
3978
|
+
const familyAB = myJoin.states[entryAB];
|
|
3979
|
+
const state = findInStore(store, familyAB, key);
|
|
3980
|
+
return state;
|
|
3981
|
+
},
|
|
3982
|
+
get [entriesBA]() {
|
|
3983
|
+
const familyBA = myJoin.states[entriesBA];
|
|
3984
|
+
const state = findInStore(store, familyBA, key);
|
|
3985
|
+
return state;
|
|
3986
|
+
}
|
|
3987
|
+
});
|
|
3988
|
+
}
|
|
3989
|
+
break;
|
|
3990
|
+
}
|
|
3991
|
+
case `n:n`: {
|
|
3992
|
+
const keysAB = `${token.a}KeysOf${capitalize(token.b)}`;
|
|
3993
|
+
const keysBA = `${token.b}KeysOf${capitalize(token.a)}`;
|
|
3994
|
+
relations = {
|
|
3995
|
+
get [keysAB]() {
|
|
3996
|
+
const familyAB = myJoin.states[keysAB];
|
|
3997
|
+
const state = findInStore(store, familyAB, key);
|
|
3998
|
+
return state;
|
|
3999
|
+
},
|
|
4000
|
+
get [keysBA]() {
|
|
4001
|
+
const familyBA = myJoin.states[keysBA];
|
|
4002
|
+
const state = findInStore(store, familyBA, key);
|
|
4003
|
+
return state;
|
|
4004
|
+
}
|
|
4005
|
+
};
|
|
4006
|
+
const entriesAB = `${token.a}EntriesOf${capitalize(token.b)}`;
|
|
4007
|
+
if (entriesAB in myJoin.states) {
|
|
4008
|
+
const entriesBA = `${token.b}EntriesOf${capitalize(token.a)}`;
|
|
4009
|
+
Object.assign(relations, {
|
|
4010
|
+
get [entriesAB]() {
|
|
4011
|
+
const familyAB = myJoin.states[entriesAB];
|
|
4012
|
+
const state = findInStore(store, familyAB, key);
|
|
4013
|
+
return state;
|
|
4014
|
+
},
|
|
4015
|
+
get [entriesBA]() {
|
|
4016
|
+
const familyBA = myJoin.states[entriesBA];
|
|
4017
|
+
const state = findInStore(store, familyBA, key);
|
|
4018
|
+
return state;
|
|
4019
|
+
}
|
|
4020
|
+
});
|
|
4021
|
+
}
|
|
4022
|
+
}
|
|
4023
|
+
}
|
|
4024
|
+
return relations;
|
|
4025
|
+
}
|
|
4026
|
+
|
|
4027
|
+
// internal/src/join/get-internal-relations-from-store.ts
|
|
4028
|
+
function getInternalRelationsFromStore(token, store) {
|
|
4029
|
+
const myJoin = getJoin(token, store);
|
|
4030
|
+
const family = myJoin.core.relatedKeysAtoms;
|
|
4031
|
+
return family;
|
|
4032
|
+
}
|
|
4033
|
+
|
|
3009
4034
|
// internal/src/timeline/create-timeline.ts
|
|
3010
|
-
function createTimeline(
|
|
4035
|
+
function createTimeline(store, options, data) {
|
|
3011
4036
|
const tl = {
|
|
3012
4037
|
type: `timeline`,
|
|
3013
4038
|
key: options.key,
|
|
@@ -3017,7 +4042,7 @@ function createTimeline(options, store, data) {
|
|
|
3017
4042
|
transactionKey: null,
|
|
3018
4043
|
...data,
|
|
3019
4044
|
history: data?.history.map((update) => ({ ...update })) ?? [],
|
|
3020
|
-
install: (s) => createTimeline(
|
|
4045
|
+
install: (s) => createTimeline(s, options, tl),
|
|
3021
4046
|
subject: new Subject(),
|
|
3022
4047
|
subscriptions: /* @__PURE__ */ new Map()
|
|
3023
4048
|
};
|
|
@@ -3056,7 +4081,7 @@ function createTimeline(options, store, data) {
|
|
|
3056
4081
|
);
|
|
3057
4082
|
continue;
|
|
3058
4083
|
}
|
|
3059
|
-
addAtomToTimeline(atomToken, tl
|
|
4084
|
+
addAtomToTimeline(store, atomToken, tl);
|
|
3060
4085
|
}
|
|
3061
4086
|
break;
|
|
3062
4087
|
case `atom_family`:
|
|
@@ -3074,7 +4099,7 @@ function createTimeline(options, store, data) {
|
|
|
3074
4099
|
);
|
|
3075
4100
|
continue;
|
|
3076
4101
|
}
|
|
3077
|
-
addAtomFamilyToTimeline(familyToken, tl
|
|
4102
|
+
addAtomFamilyToTimeline(store, familyToken, tl);
|
|
3078
4103
|
}
|
|
3079
4104
|
break;
|
|
3080
4105
|
}
|
|
@@ -3087,20 +4112,20 @@ function createTimeline(options, store, data) {
|
|
|
3087
4112
|
store.on.timelineCreation.next(token);
|
|
3088
4113
|
return token;
|
|
3089
4114
|
}
|
|
3090
|
-
function addAtomToTimeline(atomToken, tl
|
|
3091
|
-
let maybeAtom = withdraw(
|
|
4115
|
+
function addAtomToTimeline(store, atomToken, tl) {
|
|
4116
|
+
let maybeAtom = withdraw(store, atomToken);
|
|
3092
4117
|
if (maybeAtom.type === `mutable_atom`) {
|
|
3093
4118
|
const updateToken = getUpdateToken(maybeAtom);
|
|
3094
|
-
maybeAtom = withdraw(
|
|
4119
|
+
maybeAtom = withdraw(store, updateToken);
|
|
3095
4120
|
}
|
|
3096
|
-
const
|
|
4121
|
+
const atom2 = maybeAtom;
|
|
3097
4122
|
store.timelineTopics.set(
|
|
3098
|
-
{ topicKey:
|
|
4123
|
+
{ topicKey: atom2.key, timelineKey: tl.key },
|
|
3099
4124
|
{ topicType: `atom` }
|
|
3100
4125
|
);
|
|
3101
4126
|
tl.subscriptions.set(
|
|
3102
|
-
|
|
3103
|
-
|
|
4127
|
+
atom2.key,
|
|
4128
|
+
atom2.subject.subscribe(
|
|
3104
4129
|
`timeline`,
|
|
3105
4130
|
function timelineCapturesAtomUpdate(update) {
|
|
3106
4131
|
const target = newest(store);
|
|
@@ -3121,7 +4146,7 @@ function addAtomToTimeline(atomToken, tl, store) {
|
|
|
3121
4146
|
);
|
|
3122
4147
|
if (tl.timeTraveling === null) {
|
|
3123
4148
|
if (txUpdateInProgress) {
|
|
3124
|
-
joinTransaction(tl, txUpdateInProgress
|
|
4149
|
+
joinTransaction(store, tl, txUpdateInProgress);
|
|
3125
4150
|
} else if (currentSelectorKey && currentSelectorTime) {
|
|
3126
4151
|
let latestUpdate = tl.history.at(-1);
|
|
3127
4152
|
if (currentSelectorTime !== tl.selectorTime) {
|
|
@@ -3132,7 +4157,7 @@ function addAtomToTimeline(atomToken, tl, store) {
|
|
|
3132
4157
|
atomUpdates: []
|
|
3133
4158
|
};
|
|
3134
4159
|
latestUpdate.atomUpdates.push({
|
|
3135
|
-
key:
|
|
4160
|
+
key: atom2.key,
|
|
3136
4161
|
type: `atom_update`,
|
|
3137
4162
|
...update
|
|
3138
4163
|
});
|
|
@@ -3152,7 +4177,7 @@ function addAtomToTimeline(atomToken, tl, store) {
|
|
|
3152
4177
|
} else {
|
|
3153
4178
|
if (latestUpdate?.type === `selector_update`) {
|
|
3154
4179
|
latestUpdate.atomUpdates.push({
|
|
3155
|
-
key:
|
|
4180
|
+
key: atom2.key,
|
|
3156
4181
|
type: `atom_update`,
|
|
3157
4182
|
...update
|
|
3158
4183
|
});
|
|
@@ -3183,19 +4208,19 @@ function addAtomToTimeline(atomToken, tl, store) {
|
|
|
3183
4208
|
const atomUpdate = {
|
|
3184
4209
|
type: `atom_update`,
|
|
3185
4210
|
timestamp,
|
|
3186
|
-
key:
|
|
4211
|
+
key: atom2.key,
|
|
3187
4212
|
oldValue: update.oldValue,
|
|
3188
4213
|
newValue: update.newValue
|
|
3189
4214
|
};
|
|
3190
|
-
if (
|
|
3191
|
-
atomUpdate.family =
|
|
4215
|
+
if (atom2.family) {
|
|
4216
|
+
atomUpdate.family = atom2.family;
|
|
3192
4217
|
}
|
|
3193
4218
|
const willCapture = tl.shouldCapture?.(atomUpdate, tl) ?? true;
|
|
3194
4219
|
store.logger.info(
|
|
3195
4220
|
`\u231B`,
|
|
3196
4221
|
`timeline`,
|
|
3197
4222
|
tl.key,
|
|
3198
|
-
`got an atom_update to "${
|
|
4223
|
+
`got an atom_update to "${atom2.key}"`
|
|
3199
4224
|
);
|
|
3200
4225
|
if (willCapture) {
|
|
3201
4226
|
tl.history.push(atomUpdate);
|
|
@@ -3208,8 +4233,8 @@ function addAtomToTimeline(atomToken, tl, store) {
|
|
|
3208
4233
|
)
|
|
3209
4234
|
);
|
|
3210
4235
|
}
|
|
3211
|
-
function addAtomFamilyToTimeline(atomFamilyToken, tl
|
|
3212
|
-
const family = withdraw(
|
|
4236
|
+
function addAtomFamilyToTimeline(store, atomFamilyToken, tl) {
|
|
4237
|
+
const family = withdraw(store, atomFamilyToken);
|
|
3213
4238
|
store.timelineTopics.set(
|
|
3214
4239
|
{ topicKey: family.key, timelineKey: tl.key },
|
|
3215
4240
|
{ topicType: `atom_family` }
|
|
@@ -3219,24 +4244,24 @@ function addAtomFamilyToTimeline(atomFamilyToken, tl, store) {
|
|
|
3219
4244
|
family.subject.subscribe(
|
|
3220
4245
|
`timeline`,
|
|
3221
4246
|
function timelineCapturesStateLifecycleEvent(creationOrDisposal) {
|
|
3222
|
-
handleStateLifecycleEvent(creationOrDisposal, tl
|
|
4247
|
+
handleStateLifecycleEvent(store, creationOrDisposal, tl);
|
|
3223
4248
|
}
|
|
3224
4249
|
)
|
|
3225
4250
|
);
|
|
3226
|
-
for (const
|
|
3227
|
-
if (
|
|
3228
|
-
addAtomToTimeline(
|
|
4251
|
+
for (const atom2 of store.atoms.values()) {
|
|
4252
|
+
if (atom2.family?.key === family.key) {
|
|
4253
|
+
addAtomToTimeline(store, atom2, tl);
|
|
3229
4254
|
}
|
|
3230
4255
|
}
|
|
3231
4256
|
}
|
|
3232
|
-
function joinTransaction(tl, txUpdateInProgress
|
|
4257
|
+
function joinTransaction(store, tl, txUpdateInProgress) {
|
|
3233
4258
|
const currentTxKey = txUpdateInProgress.key;
|
|
3234
4259
|
const currentTxInstanceId = txUpdateInProgress.id;
|
|
3235
4260
|
const currentTxToken = {
|
|
3236
4261
|
key: currentTxKey,
|
|
3237
4262
|
type: `transaction`
|
|
3238
4263
|
};
|
|
3239
|
-
const currentTransaction = withdraw(
|
|
4264
|
+
const currentTransaction = withdraw(store, currentTxToken);
|
|
3240
4265
|
if (currentTxKey && tl.transactionKey === null) {
|
|
3241
4266
|
tl.transactionKey = currentTxKey;
|
|
3242
4267
|
const unsubscribe = currentTransaction.subject.subscribe(
|
|
@@ -3310,7 +4335,7 @@ function filterTransactionUpdates(updates, timelineTopics) {
|
|
|
3310
4335
|
return updateFromTx;
|
|
3311
4336
|
});
|
|
3312
4337
|
}
|
|
3313
|
-
function handleStateLifecycleEvent(event, tl
|
|
4338
|
+
function handleStateLifecycleEvent(store, event, tl) {
|
|
3314
4339
|
const timestamp = Date.now();
|
|
3315
4340
|
const timelineEvent = Object.assign(event, {
|
|
3316
4341
|
timestamp
|
|
@@ -3320,7 +4345,7 @@ function handleStateLifecycleEvent(event, tl, store) {
|
|
|
3320
4345
|
if (isChildStore(target)) ; else {
|
|
3321
4346
|
const txUpdateInProgress = target.on.transactionApplying.state;
|
|
3322
4347
|
if (txUpdateInProgress) {
|
|
3323
|
-
joinTransaction(tl, txUpdateInProgress.update
|
|
4348
|
+
joinTransaction(store, tl, txUpdateInProgress.update);
|
|
3324
4349
|
} else {
|
|
3325
4350
|
tl.history.push(timelineEvent);
|
|
3326
4351
|
tl.at = tl.history.length;
|
|
@@ -3330,7 +4355,7 @@ function handleStateLifecycleEvent(event, tl, store) {
|
|
|
3330
4355
|
}
|
|
3331
4356
|
switch (event.type) {
|
|
3332
4357
|
case `state_creation`:
|
|
3333
|
-
addAtomToTimeline(event.token, tl
|
|
4358
|
+
addAtomToTimeline(store, event.token, tl);
|
|
3334
4359
|
break;
|
|
3335
4360
|
case `state_disposal`:
|
|
3336
4361
|
tl.subscriptions.get(event.token.key)?.();
|
|
@@ -3407,4 +4432,67 @@ var timeTravel = (store, action, token) => {
|
|
|
3407
4432
|
);
|
|
3408
4433
|
};
|
|
3409
4434
|
|
|
3410
|
-
|
|
4435
|
+
// json/src/select-json.ts
|
|
4436
|
+
var selectJson = (atom2, transform, store = IMPLICIT.STORE) => {
|
|
4437
|
+
return createStandaloneSelector(store, {
|
|
4438
|
+
key: `${atom2.key}:JSON`,
|
|
4439
|
+
get: ({ get }) => transform.toJson(get(atom2)),
|
|
4440
|
+
set: ({ set }, newValue) => {
|
|
4441
|
+
set(atom2, transform.fromJson(newValue));
|
|
4442
|
+
}
|
|
4443
|
+
});
|
|
4444
|
+
};
|
|
4445
|
+
|
|
4446
|
+
// json/src/select-json-family.ts
|
|
4447
|
+
function selectJsonFamily(store, atomFamilyToken, transform) {
|
|
4448
|
+
const jsonFamily = createWritableSelectorFamily(
|
|
4449
|
+
store,
|
|
4450
|
+
{
|
|
4451
|
+
key: `${atomFamilyToken.key}:JSON`,
|
|
4452
|
+
get: (key) => ({ get }) => {
|
|
4453
|
+
const baseState = get(atomFamilyToken, key);
|
|
4454
|
+
return transform.toJson(baseState);
|
|
4455
|
+
},
|
|
4456
|
+
set: (key) => ({ set }, newValue) => {
|
|
4457
|
+
set(atomFamilyToken, key, transform.fromJson(newValue));
|
|
4458
|
+
}
|
|
4459
|
+
},
|
|
4460
|
+
[`mutable`, `json`]
|
|
4461
|
+
);
|
|
4462
|
+
return jsonFamily;
|
|
4463
|
+
}
|
|
4464
|
+
|
|
4465
|
+
// json/src/index.ts
|
|
4466
|
+
var parseJson = (str) => JSON.parse(str);
|
|
4467
|
+
var stringifyJson = (json) => JSON.stringify(json);
|
|
4468
|
+
var JSON_PROTOTYPES = [
|
|
4469
|
+
Array.prototype,
|
|
4470
|
+
Boolean.prototype,
|
|
4471
|
+
Number.prototype,
|
|
4472
|
+
Object.prototype,
|
|
4473
|
+
String.prototype
|
|
4474
|
+
];
|
|
4475
|
+
var isJson = (input) => {
|
|
4476
|
+
if (input === null) return true;
|
|
4477
|
+
if (input === undefined) return false;
|
|
4478
|
+
const prototype = Object.getPrototypeOf(input);
|
|
4479
|
+
return JSON_PROTOTYPES.includes(prototype);
|
|
4480
|
+
};
|
|
4481
|
+
var JSON_TYPE_NAMES = [
|
|
4482
|
+
`array`,
|
|
4483
|
+
`boolean`,
|
|
4484
|
+
`null`,
|
|
4485
|
+
`number`,
|
|
4486
|
+
`object`,
|
|
4487
|
+
`string`
|
|
4488
|
+
];
|
|
4489
|
+
var JSON_DEFAULTS = {
|
|
4490
|
+
array: [],
|
|
4491
|
+
boolean: false,
|
|
4492
|
+
null: null,
|
|
4493
|
+
number: 0,
|
|
4494
|
+
object: {},
|
|
4495
|
+
string: ``
|
|
4496
|
+
};
|
|
4497
|
+
|
|
4498
|
+
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 };
|