atom.io 0.24.4 → 0.24.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +1 -1
- package/internal/dist/index.cjs +1449 -1403
- package/internal/dist/index.d.ts +10 -9
- package/internal/dist/index.js +1450 -1403
- package/internal/src/atom/dispose-atom.ts +5 -1
- package/internal/src/families/init-family-member.ts +11 -8
- package/internal/src/ingest-updates/ingest-creation-disposal.ts +22 -9
- package/internal/src/molecule/dispose-molecule.ts +27 -16
- package/internal/src/molecule/grow-molecule-in-store.ts +2 -6
- package/internal/src/molecule/make-molecule-in-store.ts +21 -15
- package/internal/src/mutable/tracker.ts +1 -1
- package/internal/src/selector/create-writable-selector.ts +9 -8
- package/internal/src/selector/dispose-selector.ts +4 -0
- package/internal/src/selector/register-selector.ts +3 -2
- package/internal/src/set-state/evict-downstream.ts +10 -8
- package/internal/src/store/store.ts +29 -25
- package/internal/src/timeline/create-timeline.ts +404 -104
- package/internal/src/timeline/index.ts +0 -1
- package/internal/src/transaction/apply-transaction.ts +0 -8
- package/internal/src/transaction/build-transaction.ts +2 -1
- package/package.json +1 -1
- package/realtime-server/dist/index.cjs +0 -61
- package/realtime-server/dist/index.js +3 -64
- package/realtime-server/src/realtime-server-stores/index.ts +0 -1
- package/src/transaction.ts +1 -1
- package/internal/src/timeline/add-atom-to-timeline.ts +0 -265
- package/realtime-server/src/realtime-server-stores/realtime-continuity-store.ts +0 -109
package/internal/dist/index.js
CHANGED
|
@@ -112,187 +112,69 @@ function isChildStore(store) {
|
|
|
112
112
|
return `phase` in store.transactionMeta;
|
|
113
113
|
}
|
|
114
114
|
|
|
115
|
-
// internal/src/
|
|
116
|
-
var
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
this.trackers = /* @__PURE__ */ new Map();
|
|
125
|
-
this.families = /* @__PURE__ */ new Map();
|
|
126
|
-
this.timelines = /* @__PURE__ */ new Map();
|
|
127
|
-
this.transactions = /* @__PURE__ */ new Map();
|
|
128
|
-
this.atomsThatAreDefault = /* @__PURE__ */ new Set();
|
|
129
|
-
this.timelineAtoms = new Junction({
|
|
130
|
-
between: [`timelineKey`, `atomKey`],
|
|
131
|
-
cardinality: `1:n`
|
|
132
|
-
});
|
|
133
|
-
this.selectorAtoms = new Junction({
|
|
134
|
-
between: [`selectorKey`, `atomKey`],
|
|
135
|
-
cardinality: `n:n`
|
|
136
|
-
});
|
|
137
|
-
this.selectorGraph = new Junction(
|
|
138
|
-
{
|
|
139
|
-
between: [`upstreamSelectorKey`, `downstreamSelectorKey`],
|
|
140
|
-
cardinality: `n:n`
|
|
141
|
-
},
|
|
142
|
-
{
|
|
143
|
-
makeContentKey: (...keys) => keys.sort().join(`:`)
|
|
144
|
-
}
|
|
115
|
+
// internal/src/transaction/abort-transaction.ts
|
|
116
|
+
var abortTransaction = (store) => {
|
|
117
|
+
const target = newest(store);
|
|
118
|
+
if (!isChildStore(target)) {
|
|
119
|
+
store.logger.warn(
|
|
120
|
+
`\u{1F41E}`,
|
|
121
|
+
`transaction`,
|
|
122
|
+
`???`,
|
|
123
|
+
`abortTransaction called outside of a transaction. This is probably a bug in AtomIO.`
|
|
145
124
|
);
|
|
146
|
-
|
|
147
|
-
this.moleculeFamilies = /* @__PURE__ */ new Map();
|
|
148
|
-
this.miscResources = /* @__PURE__ */ new Map();
|
|
149
|
-
this.on = {
|
|
150
|
-
atomCreation: new Subject(),
|
|
151
|
-
atomDisposal: new Subject(),
|
|
152
|
-
selectorCreation: new Subject(),
|
|
153
|
-
selectorDisposal: new Subject(),
|
|
154
|
-
timelineCreation: new Subject(),
|
|
155
|
-
transactionCreation: new Subject(),
|
|
156
|
-
transactionApplying: new StatefulSubject(
|
|
157
|
-
null
|
|
158
|
-
),
|
|
159
|
-
operationClose: new Subject(),
|
|
160
|
-
moleculeCreationStart: new Subject(),
|
|
161
|
-
moleculeCreationDone: new Subject(),
|
|
162
|
-
moleculeDisposal: new Subject()
|
|
163
|
-
};
|
|
164
|
-
this.operation = { open: false };
|
|
165
|
-
this.transactionMeta = {
|
|
166
|
-
epoch: /* @__PURE__ */ new Map(),
|
|
167
|
-
actionContinuities: new Junction({
|
|
168
|
-
between: [`continuity`, `action`],
|
|
169
|
-
cardinality: `1:n`
|
|
170
|
-
})
|
|
171
|
-
};
|
|
172
|
-
this.config = {
|
|
173
|
-
name: `IMPLICIT_STORE`,
|
|
174
|
-
lifespan: `ephemeral`
|
|
175
|
-
};
|
|
176
|
-
this.loggers = [
|
|
177
|
-
new AtomIOLogger(`warn`, (_, __, key) => !key.includes(`\u{1F441}\u200D\u{1F5E8}`))
|
|
178
|
-
];
|
|
179
|
-
this.logger = {
|
|
180
|
-
error: (...messages) => {
|
|
181
|
-
for (const logger of this.loggers) logger.error(...messages);
|
|
182
|
-
},
|
|
183
|
-
info: (...messages) => {
|
|
184
|
-
for (const logger of this.loggers) logger.info(...messages);
|
|
185
|
-
},
|
|
186
|
-
warn: (...messages) => {
|
|
187
|
-
for (const logger of this.loggers) logger.warn(...messages);
|
|
188
|
-
}
|
|
189
|
-
};
|
|
190
|
-
if (store !== null) {
|
|
191
|
-
this.valueMap = new Map(store == null ? void 0 : store.valueMap);
|
|
192
|
-
this.operation = __spreadValues({}, store == null ? void 0 : store.operation);
|
|
193
|
-
if (isRootStore(store)) {
|
|
194
|
-
this.transactionMeta = {
|
|
195
|
-
epoch: new Map(store == null ? void 0 : store.transactionMeta.epoch),
|
|
196
|
-
actionContinuities: new Junction(
|
|
197
|
-
store == null ? void 0 : store.transactionMeta.actionContinuities.toJSON()
|
|
198
|
-
)
|
|
199
|
-
};
|
|
200
|
-
}
|
|
201
|
-
this.config = __spreadValues(__spreadValues({}, store == null ? void 0 : store.config), config);
|
|
202
|
-
for (const [, family] of store.families) {
|
|
203
|
-
family.install(this);
|
|
204
|
-
}
|
|
205
|
-
const mutableHelpers = /* @__PURE__ */ new Set();
|
|
206
|
-
for (const [, atom] of store.atoms) {
|
|
207
|
-
if (mutableHelpers.has(atom.key)) {
|
|
208
|
-
continue;
|
|
209
|
-
}
|
|
210
|
-
atom.install(this);
|
|
211
|
-
if (atom.type === `mutable_atom`) {
|
|
212
|
-
const originalJsonToken = getJsonToken(atom, store);
|
|
213
|
-
const originalUpdateToken = getUpdateToken(atom);
|
|
214
|
-
mutableHelpers.add(originalJsonToken.key);
|
|
215
|
-
mutableHelpers.add(originalUpdateToken.key);
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
for (const [, selector] of store.readonlySelectors) {
|
|
219
|
-
selector.install(this);
|
|
220
|
-
}
|
|
221
|
-
for (const [, selector] of store.selectors) {
|
|
222
|
-
if (mutableHelpers.has(selector.key)) {
|
|
223
|
-
continue;
|
|
224
|
-
}
|
|
225
|
-
selector.install(this);
|
|
226
|
-
}
|
|
227
|
-
for (const [, tx] of store.transactions) {
|
|
228
|
-
tx.install(this);
|
|
229
|
-
}
|
|
230
|
-
for (const [, timeline] of store.timelines) {
|
|
231
|
-
timeline.install(this);
|
|
232
|
-
}
|
|
233
|
-
}
|
|
125
|
+
return;
|
|
234
126
|
}
|
|
127
|
+
store.logger.info(
|
|
128
|
+
`\u{1FA82}`,
|
|
129
|
+
`transaction`,
|
|
130
|
+
target.transactionMeta.update.key,
|
|
131
|
+
`Aborting transaction`
|
|
132
|
+
);
|
|
133
|
+
target.parent.child = null;
|
|
235
134
|
};
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
135
|
+
|
|
136
|
+
// internal/src/not-found-error.ts
|
|
137
|
+
var capitalize = (str) => str[0].toUpperCase() + str.slice(1);
|
|
138
|
+
function prettyPrintTokenType(token) {
|
|
139
|
+
switch (token.type) {
|
|
140
|
+
case `atom_family`:
|
|
141
|
+
return `Atom Family`;
|
|
142
|
+
case `molecule_family`:
|
|
143
|
+
return `Molecule Family`;
|
|
144
|
+
case `readonly_selector`:
|
|
145
|
+
return `Readonly Selector`;
|
|
146
|
+
case `readonly_selector_family`:
|
|
147
|
+
return `Readonly Selector Family`;
|
|
148
|
+
case `selector_family`:
|
|
149
|
+
return `Selector Family`;
|
|
150
|
+
default:
|
|
151
|
+
return capitalize(token.type);
|
|
244
152
|
}
|
|
245
|
-
}
|
|
246
|
-
var
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
153
|
+
}
|
|
154
|
+
var NotFoundError = class extends Error {
|
|
155
|
+
constructor(token, store) {
|
|
156
|
+
super(
|
|
157
|
+
`${prettyPrintTokenType(token)} "${token.key}" not found in store "${store.config.name}".`
|
|
158
|
+
);
|
|
250
159
|
}
|
|
251
|
-
Object.assign(store, new Store(config));
|
|
252
|
-
store.config = config;
|
|
253
160
|
};
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
withdrawn = target.atoms.get(token.key);
|
|
262
|
-
break;
|
|
263
|
-
case `selector`:
|
|
264
|
-
withdrawn = target.selectors.get(token.key);
|
|
265
|
-
break;
|
|
266
|
-
case `readonly_selector`:
|
|
267
|
-
withdrawn = target.readonlySelectors.get(token.key);
|
|
268
|
-
break;
|
|
269
|
-
case `atom_family`:
|
|
270
|
-
case `mutable_atom_family`:
|
|
271
|
-
case `selector_family`:
|
|
272
|
-
case `readonly_selector_family`:
|
|
273
|
-
withdrawn = target.families.get(token.key);
|
|
274
|
-
break;
|
|
275
|
-
case `timeline`:
|
|
276
|
-
withdrawn = target.timelines.get(token.key);
|
|
277
|
-
break;
|
|
278
|
-
case `transaction`:
|
|
279
|
-
withdrawn = target.transactions.get(token.key);
|
|
280
|
-
break;
|
|
281
|
-
case `molecule`:
|
|
282
|
-
withdrawn = target.molecules.get(stringifyJson(token.key));
|
|
283
|
-
break;
|
|
284
|
-
case `molecule_family`:
|
|
285
|
-
withdrawn = target.moleculeFamilies.get(token.key);
|
|
286
|
-
break;
|
|
287
|
-
}
|
|
288
|
-
if (withdrawn) {
|
|
289
|
-
return withdrawn;
|
|
161
|
+
|
|
162
|
+
// internal/src/transaction/act-upon-store.ts
|
|
163
|
+
function actUponStore(token, id, store) {
|
|
164
|
+
return (...parameters) => {
|
|
165
|
+
const tx = withdraw(token, store);
|
|
166
|
+
if (tx) {
|
|
167
|
+
return tx.run(parameters, id);
|
|
290
168
|
}
|
|
291
|
-
|
|
292
|
-
}
|
|
293
|
-
throw new NotFoundError(token, store);
|
|
169
|
+
throw new NotFoundError(token, store);
|
|
170
|
+
};
|
|
294
171
|
}
|
|
295
172
|
|
|
173
|
+
// internal/src/set-state/become.ts
|
|
174
|
+
var become = (nextVersionOfThing) => (originalThing) => nextVersionOfThing instanceof Function ? nextVersionOfThing(
|
|
175
|
+
originalThing instanceof Function ? originalThing() : originalThing
|
|
176
|
+
) : nextVersionOfThing;
|
|
177
|
+
|
|
296
178
|
// internal/src/get-state/read-or-compute-value.ts
|
|
297
179
|
var readOrComputeValue = (state, target) => {
|
|
298
180
|
if (target.valueMap.has(state.key)) {
|
|
@@ -313,176 +195,6 @@ var readOrComputeValue = (state, target) => {
|
|
|
313
195
|
);
|
|
314
196
|
return state.default instanceof Function ? state.default() : state.default;
|
|
315
197
|
};
|
|
316
|
-
function createRegularAtomFamily(options, store) {
|
|
317
|
-
const subject = new Subject();
|
|
318
|
-
const atomFamily = Object.assign(
|
|
319
|
-
(key) => {
|
|
320
|
-
const subKey = stringifyJson(key);
|
|
321
|
-
const family = { key: options.key, subKey };
|
|
322
|
-
const fullKey = `${options.key}(${subKey})`;
|
|
323
|
-
const target = newest(store);
|
|
324
|
-
const def = options.default;
|
|
325
|
-
const individualOptions = {
|
|
326
|
-
key: fullKey,
|
|
327
|
-
default: def instanceof Function ? def(key) : def
|
|
328
|
-
};
|
|
329
|
-
if (options.effects) {
|
|
330
|
-
individualOptions.effects = options.effects(key);
|
|
331
|
-
}
|
|
332
|
-
const token = createRegularAtom(individualOptions, family, target);
|
|
333
|
-
subject.next({ type: `state_creation`, token });
|
|
334
|
-
return token;
|
|
335
|
-
},
|
|
336
|
-
{
|
|
337
|
-
key: options.key,
|
|
338
|
-
type: `atom_family`,
|
|
339
|
-
subject,
|
|
340
|
-
install: (s) => createRegularAtomFamily(options, s)
|
|
341
|
-
}
|
|
342
|
-
);
|
|
343
|
-
store.families.set(options.key, atomFamily);
|
|
344
|
-
return atomFamily;
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
// internal/src/families/create-atom-family.ts
|
|
348
|
-
function createAtomFamily(options, store) {
|
|
349
|
-
const isMutable2 = `mutable` in options;
|
|
350
|
-
if (isMutable2) {
|
|
351
|
-
return createMutableAtomFamily(options, store);
|
|
352
|
-
}
|
|
353
|
-
return createRegularAtomFamily(options, store);
|
|
354
|
-
}
|
|
355
|
-
function createReadonlySelectorFamily(options, store) {
|
|
356
|
-
const subject = new Subject();
|
|
357
|
-
const readonlySelectorFamily = Object.assign(
|
|
358
|
-
(key) => {
|
|
359
|
-
const subKey = stringifyJson(key);
|
|
360
|
-
const family = { key: options.key, subKey };
|
|
361
|
-
const fullKey = `${options.key}(${subKey})`;
|
|
362
|
-
const target = newest(store);
|
|
363
|
-
const token = createReadonlySelector(
|
|
364
|
-
{
|
|
365
|
-
key: fullKey,
|
|
366
|
-
get: options.get(key)
|
|
367
|
-
},
|
|
368
|
-
family,
|
|
369
|
-
target
|
|
370
|
-
);
|
|
371
|
-
subject.next({ type: `state_creation`, token });
|
|
372
|
-
return token;
|
|
373
|
-
},
|
|
374
|
-
{
|
|
375
|
-
key: options.key,
|
|
376
|
-
type: `readonly_selector_family`,
|
|
377
|
-
subject,
|
|
378
|
-
install: (s) => createReadonlySelectorFamily(options, s)
|
|
379
|
-
}
|
|
380
|
-
);
|
|
381
|
-
store.families.set(options.key, readonlySelectorFamily);
|
|
382
|
-
return readonlySelectorFamily;
|
|
383
|
-
}
|
|
384
|
-
function createWritableSelectorFamily(options, store) {
|
|
385
|
-
const subject = new Subject();
|
|
386
|
-
const selectorFamily = Object.assign(
|
|
387
|
-
(key) => {
|
|
388
|
-
const subKey = stringifyJson(key);
|
|
389
|
-
const family = { key: options.key, subKey };
|
|
390
|
-
const fullKey = `${options.key}(${subKey})`;
|
|
391
|
-
const target = newest(store);
|
|
392
|
-
const token = createWritableSelector(
|
|
393
|
-
{
|
|
394
|
-
key: fullKey,
|
|
395
|
-
get: options.get(key),
|
|
396
|
-
set: options.set(key)
|
|
397
|
-
},
|
|
398
|
-
family,
|
|
399
|
-
target
|
|
400
|
-
);
|
|
401
|
-
subject.next({ type: `state_creation`, token });
|
|
402
|
-
return token;
|
|
403
|
-
},
|
|
404
|
-
{
|
|
405
|
-
key: options.key,
|
|
406
|
-
type: `selector_family`,
|
|
407
|
-
subject,
|
|
408
|
-
install: (s) => createWritableSelectorFamily(options, s)
|
|
409
|
-
}
|
|
410
|
-
);
|
|
411
|
-
store.families.set(options.key, selectorFamily);
|
|
412
|
-
return selectorFamily;
|
|
413
|
-
}
|
|
414
|
-
|
|
415
|
-
// internal/src/families/create-selector-family.ts
|
|
416
|
-
function createSelectorFamily(options, store) {
|
|
417
|
-
const isWritable = `set` in options;
|
|
418
|
-
if (isWritable) {
|
|
419
|
-
return createWritableSelectorFamily(options, store);
|
|
420
|
-
}
|
|
421
|
-
return createReadonlySelectorFamily(options, store);
|
|
422
|
-
}
|
|
423
|
-
|
|
424
|
-
// internal/src/transaction/abort-transaction.ts
|
|
425
|
-
var abortTransaction = (store) => {
|
|
426
|
-
const target = newest(store);
|
|
427
|
-
if (!isChildStore(target)) {
|
|
428
|
-
store.logger.warn(
|
|
429
|
-
`\u{1F41E}`,
|
|
430
|
-
`transaction`,
|
|
431
|
-
`???`,
|
|
432
|
-
`abortTransaction called outside of a transaction. This is probably a bug in AtomIO.`
|
|
433
|
-
);
|
|
434
|
-
return;
|
|
435
|
-
}
|
|
436
|
-
store.logger.info(
|
|
437
|
-
`\u{1FA82}`,
|
|
438
|
-
`transaction`,
|
|
439
|
-
target.transactionMeta.update.key,
|
|
440
|
-
`Aborting transaction`
|
|
441
|
-
);
|
|
442
|
-
target.parent.child = null;
|
|
443
|
-
};
|
|
444
|
-
|
|
445
|
-
// internal/src/not-found-error.ts
|
|
446
|
-
var capitalize = (str) => str[0].toUpperCase() + str.slice(1);
|
|
447
|
-
function prettyPrintTokenType(token) {
|
|
448
|
-
switch (token.type) {
|
|
449
|
-
case `atom_family`:
|
|
450
|
-
return `Atom Family`;
|
|
451
|
-
case `molecule_family`:
|
|
452
|
-
return `Molecule Family`;
|
|
453
|
-
case `readonly_selector`:
|
|
454
|
-
return `Readonly Selector`;
|
|
455
|
-
case `readonly_selector_family`:
|
|
456
|
-
return `Readonly Selector Family`;
|
|
457
|
-
case `selector_family`:
|
|
458
|
-
return `Selector Family`;
|
|
459
|
-
default:
|
|
460
|
-
return capitalize(token.type);
|
|
461
|
-
}
|
|
462
|
-
}
|
|
463
|
-
var NotFoundError = class extends Error {
|
|
464
|
-
constructor(token, store) {
|
|
465
|
-
super(
|
|
466
|
-
`${prettyPrintTokenType(token)} "${token.key}" not found in store "${store.config.name}".`
|
|
467
|
-
);
|
|
468
|
-
}
|
|
469
|
-
};
|
|
470
|
-
|
|
471
|
-
// internal/src/transaction/act-upon-store.ts
|
|
472
|
-
function actUponStore(token, id, store) {
|
|
473
|
-
return (...parameters) => {
|
|
474
|
-
const tx = withdraw(token, store);
|
|
475
|
-
if (tx) {
|
|
476
|
-
return tx.run(parameters, id);
|
|
477
|
-
}
|
|
478
|
-
throw new NotFoundError(token, store);
|
|
479
|
-
};
|
|
480
|
-
}
|
|
481
|
-
|
|
482
|
-
// internal/src/set-state/become.ts
|
|
483
|
-
var become = (nextVersionOfThing) => (originalThing) => nextVersionOfThing instanceof Function ? nextVersionOfThing(
|
|
484
|
-
originalThing instanceof Function ? originalThing() : originalThing
|
|
485
|
-
) : nextVersionOfThing;
|
|
486
198
|
|
|
487
199
|
// internal/src/operation.ts
|
|
488
200
|
var openOperation = (token, store) => {
|
|
@@ -579,8 +291,9 @@ var emitUpdate = (state, update, store) => {
|
|
|
579
291
|
|
|
580
292
|
// internal/src/set-state/evict-downstream.ts
|
|
581
293
|
var evictDownStream = (atom, store) => {
|
|
582
|
-
const
|
|
583
|
-
|
|
294
|
+
const target = newest(store);
|
|
295
|
+
const downstreamKeys = target.selectorAtoms.getRelatedKeys(atom.key);
|
|
296
|
+
target.logger.info(
|
|
584
297
|
`\u{1F9F9}`,
|
|
585
298
|
atom.type,
|
|
586
299
|
atom.key,
|
|
@@ -588,20 +301,20 @@ var evictDownStream = (atom, store) => {
|
|
|
588
301
|
downstreamKeys != null ? downstreamKeys : `to evict`
|
|
589
302
|
);
|
|
590
303
|
if (downstreamKeys) {
|
|
591
|
-
if (
|
|
592
|
-
|
|
304
|
+
if (target.operation.open) {
|
|
305
|
+
target.logger.info(
|
|
593
306
|
`\u{1F9F9}`,
|
|
594
307
|
atom.type,
|
|
595
308
|
atom.key,
|
|
596
|
-
`[ ${[...
|
|
309
|
+
`[ ${[...target.operation.done].join(`, `)} ] already done`
|
|
597
310
|
);
|
|
598
311
|
}
|
|
599
312
|
for (const key of downstreamKeys) {
|
|
600
|
-
if (isDone(key,
|
|
313
|
+
if (isDone(key, target)) {
|
|
601
314
|
continue;
|
|
602
315
|
}
|
|
603
|
-
evictCachedValue(key,
|
|
604
|
-
markDone(key,
|
|
316
|
+
evictCachedValue(key, target);
|
|
317
|
+
markDone(key, target);
|
|
605
318
|
}
|
|
606
319
|
}
|
|
607
320
|
};
|
|
@@ -737,582 +450,463 @@ function ingestAtomUpdate(applying, atomUpdate, store) {
|
|
|
737
450
|
}
|
|
738
451
|
setIntoStore(token, value, store);
|
|
739
452
|
}
|
|
740
|
-
|
|
741
|
-
// internal/src/molecule/create-molecule-family.ts
|
|
742
|
-
function createMoleculeFamily(options, store) {
|
|
743
|
-
var _a;
|
|
453
|
+
function createRegularAtomFamily(options, store) {
|
|
744
454
|
const subject = new Subject();
|
|
745
|
-
const
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
455
|
+
const atomFamily = Object.assign(
|
|
456
|
+
(key) => {
|
|
457
|
+
const subKey = stringifyJson(key);
|
|
458
|
+
const family = { key: options.key, subKey };
|
|
459
|
+
const fullKey = `${options.key}(${subKey})`;
|
|
460
|
+
const target = newest(store);
|
|
461
|
+
const def = options.default;
|
|
462
|
+
const individualOptions = {
|
|
463
|
+
key: fullKey,
|
|
464
|
+
default: def instanceof Function ? def(key) : def
|
|
465
|
+
};
|
|
466
|
+
if (options.effects) {
|
|
467
|
+
individualOptions.effects = options.effects(key);
|
|
468
|
+
}
|
|
469
|
+
const token = createRegularAtom(individualOptions, family, target);
|
|
470
|
+
subject.next({ type: `state_creation`, token });
|
|
471
|
+
return token;
|
|
472
|
+
},
|
|
473
|
+
{
|
|
474
|
+
key: options.key,
|
|
475
|
+
type: `atom_family`,
|
|
476
|
+
subject,
|
|
477
|
+
install: (s) => createRegularAtomFamily(options, s)
|
|
478
|
+
}
|
|
479
|
+
);
|
|
480
|
+
store.families.set(options.key, atomFamily);
|
|
481
|
+
return atomFamily;
|
|
756
482
|
}
|
|
757
483
|
|
|
758
|
-
// internal/src/
|
|
759
|
-
function
|
|
760
|
-
const
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
if (isTransaction) {
|
|
764
|
-
store.transactionMeta.update.updates.push({
|
|
765
|
-
type: `state_creation`,
|
|
766
|
-
token: stateToken
|
|
767
|
-
});
|
|
768
|
-
} else {
|
|
769
|
-
molecule.subject.next({ type: `state_creation`, token: stateToken });
|
|
484
|
+
// internal/src/families/create-atom-family.ts
|
|
485
|
+
function createAtomFamily(options, store) {
|
|
486
|
+
const isMutable2 = `mutable` in options;
|
|
487
|
+
if (isMutable2) {
|
|
488
|
+
return createMutableAtomFamily(options, store);
|
|
770
489
|
}
|
|
771
|
-
return
|
|
490
|
+
return createRegularAtomFamily(options, store);
|
|
772
491
|
}
|
|
773
492
|
|
|
774
|
-
// internal/src/
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
}
|
|
493
|
+
// internal/src/keys.ts
|
|
494
|
+
var isAtomKey = (key, store) => newest(store).atoms.has(key);
|
|
495
|
+
var isSelectorKey = (key, store) => newest(store).selectors.has(key);
|
|
496
|
+
var isReadonlySelectorKey = (key, store) => newest(store).readonlySelectors.has(key);
|
|
497
|
+
var isStateKey = (key, store) => isAtomKey(key, store) || isSelectorKey(key, store) || isReadonlySelectorKey(key, store);
|
|
780
498
|
|
|
781
|
-
// internal/src/
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
const molecule = withdraw(token, store);
|
|
786
|
-
return molecule.instance;
|
|
787
|
-
} catch (_) {
|
|
788
|
-
return void 0;
|
|
789
|
-
}
|
|
790
|
-
}
|
|
791
|
-
const state = withdraw(token, store);
|
|
792
|
-
return readOrComputeValue(state, store);
|
|
793
|
-
}
|
|
794
|
-
var Molecule = class {
|
|
795
|
-
constructor(ctx, key, family) {
|
|
796
|
-
this.key = key;
|
|
797
|
-
this.type = `molecule`;
|
|
798
|
-
this.subject = new Subject();
|
|
799
|
-
this.tokens = /* @__PURE__ */ new Map();
|
|
800
|
-
this.above = /* @__PURE__ */ new Map();
|
|
801
|
-
this.below = /* @__PURE__ */ new Map();
|
|
802
|
-
this.joins = /* @__PURE__ */ new Map();
|
|
803
|
-
this.stringKey = stringifyJson(key);
|
|
804
|
-
if (family) {
|
|
805
|
-
this.family = family;
|
|
806
|
-
}
|
|
807
|
-
if (ctx) {
|
|
808
|
-
if (Array.isArray(ctx)) {
|
|
809
|
-
for (const molecule of ctx) {
|
|
810
|
-
this.above.set(molecule.stringKey, molecule);
|
|
811
|
-
}
|
|
812
|
-
} else {
|
|
813
|
-
this.above.set(ctx.stringKey, ctx);
|
|
814
|
-
}
|
|
815
|
-
}
|
|
816
|
-
}
|
|
499
|
+
// internal/src/selector/get-selector-dependency-keys.ts
|
|
500
|
+
var getSelectorDependencyKeys = (key, store) => {
|
|
501
|
+
const sources = newest(store).selectorGraph.getRelationEntries({ downstreamSelectorKey: key }).filter(([_, { source }]) => source !== key).map(([_, { source }]) => source).filter((source) => isStateKey(source, store));
|
|
502
|
+
return sources;
|
|
817
503
|
};
|
|
818
504
|
|
|
819
|
-
// internal/src/
|
|
820
|
-
|
|
821
|
-
const
|
|
822
|
-
const
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
}
|
|
832
|
-
const stringKey = stringifyJson(ctx.key);
|
|
833
|
-
const molecule2 = store.molecules.get(stringKey);
|
|
834
|
-
if (!molecule2) {
|
|
505
|
+
// internal/src/selector/trace-selector-atoms.ts
|
|
506
|
+
var traceSelectorAtoms = (selectorKey, directDependencyKey, store) => {
|
|
507
|
+
const rootKeys = [];
|
|
508
|
+
const indirectDependencyKeys = getSelectorDependencyKeys(
|
|
509
|
+
directDependencyKey,
|
|
510
|
+
store
|
|
511
|
+
);
|
|
512
|
+
let depth = 0;
|
|
513
|
+
while (indirectDependencyKeys.length > 0) {
|
|
514
|
+
const indirectDependencyKey = indirectDependencyKeys.shift();
|
|
515
|
+
++depth;
|
|
516
|
+
if (depth > 99999) {
|
|
835
517
|
throw new Error(
|
|
836
|
-
`
|
|
518
|
+
`Maximum selector dependency depth exceeded (> 99999) in selector "${selectorKey}". This is likely due to a circular dependency.`
|
|
837
519
|
);
|
|
838
520
|
}
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
521
|
+
if (!isAtomKey(indirectDependencyKey, store)) {
|
|
522
|
+
indirectDependencyKeys.push(
|
|
523
|
+
...getSelectorDependencyKeys(indirectDependencyKey, store)
|
|
524
|
+
);
|
|
525
|
+
} else if (!rootKeys.includes(indirectDependencyKey)) {
|
|
526
|
+
rootKeys.push(indirectDependencyKey);
|
|
527
|
+
}
|
|
846
528
|
}
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
)
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
529
|
+
return rootKeys;
|
|
530
|
+
};
|
|
531
|
+
var traceAllSelectorAtoms = (selector, store) => {
|
|
532
|
+
const selectorKey = selector.key;
|
|
533
|
+
const directDependencyKeys = getSelectorDependencyKeys(selectorKey, store);
|
|
534
|
+
return directDependencyKeys.flatMap(
|
|
535
|
+
(depKey) => isAtomKey(depKey, store) ? depKey : traceSelectorAtoms(selectorKey, depKey, store)
|
|
536
|
+
);
|
|
537
|
+
};
|
|
538
|
+
|
|
539
|
+
// internal/src/selector/update-selector-atoms.ts
|
|
540
|
+
var updateSelectorAtoms = (selectorKey, dependency, store) => {
|
|
541
|
+
const target = newest(store);
|
|
542
|
+
if (dependency.type === `atom` || dependency.type === `mutable_atom`) {
|
|
543
|
+
target.selectorAtoms.set({
|
|
544
|
+
selectorKey,
|
|
545
|
+
atomKey: dependency.key
|
|
546
|
+
});
|
|
547
|
+
store.logger.info(
|
|
548
|
+
`\u{1F50D}`,
|
|
549
|
+
`selector`,
|
|
550
|
+
selectorKey,
|
|
551
|
+
`discovers root atom "${dependency.key}"`
|
|
552
|
+
);
|
|
553
|
+
} else {
|
|
554
|
+
const rootKeys = traceSelectorAtoms(selectorKey, dependency.key, store);
|
|
555
|
+
store.logger.info(
|
|
556
|
+
`\u{1F50D}`,
|
|
557
|
+
`selector`,
|
|
558
|
+
selectorKey,
|
|
559
|
+
`discovers root atoms: [ ${rootKeys.map((key) => `"${key}"`).join(`, `)} ]`
|
|
560
|
+
);
|
|
561
|
+
for (const atomKey of rootKeys) {
|
|
562
|
+
target.selectorAtoms = target.selectorAtoms.set({
|
|
563
|
+
selectorKey,
|
|
564
|
+
atomKey
|
|
565
|
+
});
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
};
|
|
569
|
+
|
|
570
|
+
// internal/src/selector/register-selector.ts
|
|
571
|
+
var registerSelector = (selectorKey, store) => ({
|
|
572
|
+
get: (dependency) => {
|
|
573
|
+
const target = newest(store);
|
|
574
|
+
const dependencyState = withdraw(dependency, store);
|
|
575
|
+
const dependencyValue = readOrComputeValue(dependencyState, store);
|
|
576
|
+
store.logger.info(
|
|
577
|
+
`\u{1F50C}`,
|
|
578
|
+
`selector`,
|
|
579
|
+
selectorKey,
|
|
580
|
+
`registers dependency ( "${dependency.key}" =`,
|
|
581
|
+
dependencyValue,
|
|
582
|
+
`)`
|
|
583
|
+
);
|
|
584
|
+
target.selectorGraph.set(
|
|
585
|
+
{
|
|
586
|
+
upstreamSelectorKey: dependency.key,
|
|
587
|
+
downstreamSelectorKey: selectorKey
|
|
588
|
+
},
|
|
589
|
+
{
|
|
590
|
+
source: dependency.key
|
|
880
591
|
}
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
592
|
+
);
|
|
593
|
+
updateSelectorAtoms(selectorKey, dependency, store);
|
|
594
|
+
return dependencyValue;
|
|
595
|
+
},
|
|
596
|
+
set: (WritableToken, newValue) => {
|
|
597
|
+
const target = newest(store);
|
|
598
|
+
const state = withdraw(WritableToken, target);
|
|
599
|
+
setAtomOrSelector(state, newValue, target);
|
|
600
|
+
},
|
|
601
|
+
find: (token, key) => findInStore(token, key, store),
|
|
602
|
+
seek: (token, key) => seekInStore(token, key, store),
|
|
603
|
+
json: (token) => getJsonToken(token, store)
|
|
604
|
+
});
|
|
605
|
+
|
|
606
|
+
// internal/src/selector/create-readonly-selector.ts
|
|
607
|
+
var createReadonlySelector = (options, family, store) => {
|
|
608
|
+
const target = newest(store);
|
|
609
|
+
const subject = new Subject();
|
|
610
|
+
const { get, find, seek, json } = registerSelector(options.key, target);
|
|
611
|
+
const getSelf = () => {
|
|
612
|
+
const value = options.get({ get, find, seek, json });
|
|
613
|
+
cacheValue(options.key, value, subject, newest(store));
|
|
614
|
+
return value;
|
|
895
615
|
};
|
|
896
|
-
const
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
616
|
+
const readonlySelector = __spreadValues(__spreadProps(__spreadValues({}, options), {
|
|
617
|
+
subject,
|
|
618
|
+
install: (s) => createReadonlySelector(options, family, s),
|
|
619
|
+
get: getSelf,
|
|
620
|
+
type: `readonly_selector`
|
|
621
|
+
}), family && { family });
|
|
622
|
+
target.readonlySelectors.set(options.key, readonlySelector);
|
|
623
|
+
const initialValue = getSelf();
|
|
624
|
+
store.logger.info(
|
|
625
|
+
`\u2728`,
|
|
626
|
+
readonlySelector.type,
|
|
627
|
+
readonlySelector.key,
|
|
628
|
+
`=`,
|
|
629
|
+
initialValue
|
|
630
|
+
);
|
|
631
|
+
const token = {
|
|
632
|
+
key: options.key,
|
|
633
|
+
type: `readonly_selector`
|
|
904
634
|
};
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
target.transactionMeta.update.updates.push(update);
|
|
908
|
-
} else {
|
|
909
|
-
family.subject.next(update);
|
|
635
|
+
if (family) {
|
|
636
|
+
token.family = family;
|
|
910
637
|
}
|
|
911
638
|
return token;
|
|
912
|
-
}
|
|
639
|
+
};
|
|
913
640
|
|
|
914
|
-
// internal/src/
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
641
|
+
// internal/src/selector/create-writable-selector.ts
|
|
642
|
+
var createWritableSelector = (options, family, store) => {
|
|
643
|
+
const target = newest(store);
|
|
644
|
+
const subject = new Subject();
|
|
645
|
+
const transactors = registerSelector(options.key, target);
|
|
646
|
+
const { find, get, seek, json } = transactors;
|
|
647
|
+
const readonlyTransactors = { find, get, seek, json };
|
|
648
|
+
const getSelf = (innerTarget = newest(store)) => {
|
|
649
|
+
const value = options.get(readonlyTransactors);
|
|
650
|
+
cacheValue(options.key, value, subject, innerTarget);
|
|
651
|
+
return value;
|
|
652
|
+
};
|
|
653
|
+
const setSelf = (next) => {
|
|
654
|
+
const innerTarget = newest(store);
|
|
655
|
+
const oldValue = getSelf(innerTarget);
|
|
656
|
+
const newValue = become(next)(oldValue);
|
|
657
|
+
store.logger.info(
|
|
658
|
+
`\u{1F4DD}`,
|
|
659
|
+
`selector`,
|
|
660
|
+
options.key,
|
|
661
|
+
`set (`,
|
|
662
|
+
oldValue,
|
|
663
|
+
`->`,
|
|
664
|
+
newValue,
|
|
665
|
+
`)`
|
|
666
|
+
);
|
|
667
|
+
cacheValue(options.key, newValue, subject, innerTarget);
|
|
668
|
+
markDone(options.key, innerTarget);
|
|
669
|
+
if (isRootStore(innerTarget)) {
|
|
670
|
+
subject.next({ newValue, oldValue });
|
|
924
671
|
}
|
|
672
|
+
options.set(transactors, newValue);
|
|
673
|
+
};
|
|
674
|
+
const mySelector = __spreadValues(__spreadProps(__spreadValues({}, options), {
|
|
675
|
+
subject,
|
|
676
|
+
install: (s) => createWritableSelector(options, family, s),
|
|
677
|
+
get: getSelf,
|
|
678
|
+
set: setSelf,
|
|
679
|
+
type: `selector`
|
|
680
|
+
}), family && { family });
|
|
681
|
+
target.selectors.set(options.key, mySelector);
|
|
682
|
+
const initialValue = getSelf();
|
|
683
|
+
store.logger.info(`\u2728`, mySelector.type, mySelector.key, `=`, initialValue);
|
|
684
|
+
const token = {
|
|
685
|
+
key: options.key,
|
|
686
|
+
type: `selector`
|
|
687
|
+
};
|
|
688
|
+
if (family) {
|
|
689
|
+
token.family = family;
|
|
925
690
|
}
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
break;
|
|
937
|
-
}
|
|
691
|
+
return token;
|
|
692
|
+
};
|
|
693
|
+
|
|
694
|
+
// internal/src/selector/create-standalone-selector.ts
|
|
695
|
+
function createStandaloneSelector(options, store) {
|
|
696
|
+
const isWritable = `set` in options;
|
|
697
|
+
if (isWritable) {
|
|
698
|
+
const state2 = createWritableSelector(options, void 0, store);
|
|
699
|
+
store.on.selectorCreation.next(state2);
|
|
700
|
+
return state2;
|
|
938
701
|
}
|
|
702
|
+
const state = createReadonlySelector(options, void 0, store);
|
|
703
|
+
store.on.selectorCreation.next(state);
|
|
704
|
+
return state;
|
|
939
705
|
}
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
706
|
+
|
|
707
|
+
// internal/src/selector/dispose-selector.ts
|
|
708
|
+
function disposeSelector(selectorToken, store) {
|
|
709
|
+
var _a;
|
|
710
|
+
const target = newest(store);
|
|
711
|
+
const { key } = selectorToken;
|
|
712
|
+
const selector = (_a = target.selectors.get(key)) != null ? _a : target.readonlySelectors.get(key);
|
|
713
|
+
if (!selector) {
|
|
714
|
+
store.logger.info(
|
|
715
|
+
`\u274C`,
|
|
716
|
+
`selector`,
|
|
717
|
+
key,
|
|
718
|
+
`Tried to dispose selector, but it does not exist in the store.`
|
|
719
|
+
);
|
|
720
|
+
} else if (!selector.family) {
|
|
721
|
+
store.logger.error(
|
|
722
|
+
`\u274C`,
|
|
723
|
+
`selector`,
|
|
724
|
+
key,
|
|
725
|
+
`Standalone selectors cannot be disposed.`
|
|
726
|
+
);
|
|
727
|
+
} else {
|
|
728
|
+
const molecule = target.molecules.get(selector.family.subKey);
|
|
729
|
+
if (molecule) {
|
|
730
|
+
molecule.tokens.delete(key);
|
|
731
|
+
}
|
|
732
|
+
switch (selectorToken.type) {
|
|
733
|
+
case `selector`:
|
|
734
|
+
{
|
|
735
|
+
target.selectors.delete(key);
|
|
736
|
+
const family = withdraw(
|
|
737
|
+
{ key: selector.family.key, type: `selector_family` },
|
|
738
|
+
store
|
|
739
|
+
);
|
|
740
|
+
family.subject.next({
|
|
741
|
+
type: `state_disposal`,
|
|
742
|
+
token: selectorToken
|
|
743
|
+
});
|
|
744
|
+
}
|
|
745
|
+
break;
|
|
746
|
+
case `readonly_selector`:
|
|
747
|
+
{
|
|
748
|
+
target.readonlySelectors.delete(key);
|
|
749
|
+
const family = withdraw(
|
|
750
|
+
{ key: selector.family.key, type: `readonly_selector_family` },
|
|
751
|
+
store
|
|
752
|
+
);
|
|
753
|
+
family.subject.next({
|
|
754
|
+
type: `state_disposal`,
|
|
755
|
+
token: selectorToken
|
|
756
|
+
});
|
|
757
|
+
}
|
|
758
|
+
break;
|
|
759
|
+
}
|
|
760
|
+
target.valueMap.delete(key);
|
|
761
|
+
target.selectorAtoms.delete(key);
|
|
762
|
+
const downstreamTokens = target.selectorGraph.getRelationEntries({ upstreamSelectorKey: key }).filter(([_, { source }]) => source === key).map(
|
|
763
|
+
([downstreamSelectorKey]) => {
|
|
764
|
+
var _a2;
|
|
765
|
+
return (_a2 = target.selectors.get(downstreamSelectorKey)) != null ? _a2 : target.readonlySelectors.get(downstreamSelectorKey);
|
|
948
766
|
}
|
|
949
|
-
|
|
950
|
-
|
|
767
|
+
);
|
|
768
|
+
for (const downstreamToken of downstreamTokens) {
|
|
769
|
+
if (downstreamToken) {
|
|
770
|
+
disposeSelector(downstreamToken, store);
|
|
951
771
|
}
|
|
952
|
-
|
|
772
|
+
}
|
|
773
|
+
target.selectorGraph.delete(key);
|
|
774
|
+
store.logger.info(`\u{1F525}`, selectorToken.type, key, `deleted`);
|
|
775
|
+
if (isChildStore(target) && target.transactionMeta.phase === `building`) {
|
|
776
|
+
target.transactionMeta.update.updates.push({
|
|
777
|
+
type: `state_disposal`,
|
|
778
|
+
token: selectorToken
|
|
779
|
+
});
|
|
780
|
+
} else {
|
|
781
|
+
store.on.selectorDisposal.next(selectorToken);
|
|
953
782
|
}
|
|
954
783
|
}
|
|
955
784
|
}
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
785
|
+
|
|
786
|
+
// internal/src/families/create-readonly-selector-family.ts
|
|
787
|
+
function createReadonlySelectorFamily(options, store) {
|
|
788
|
+
const subject = new Subject();
|
|
789
|
+
const readonlySelectorFamily = Object.assign(
|
|
790
|
+
(key) => {
|
|
791
|
+
const subKey = stringifyJson(key);
|
|
792
|
+
const family = { key: options.key, subKey };
|
|
793
|
+
const fullKey = `${options.key}(${subKey})`;
|
|
794
|
+
const target = newest(store);
|
|
795
|
+
const token = createReadonlySelector(
|
|
796
|
+
{
|
|
797
|
+
key: fullKey,
|
|
798
|
+
get: options.get(key)
|
|
799
|
+
},
|
|
800
|
+
family,
|
|
801
|
+
target
|
|
965
802
|
);
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
803
|
+
subject.next({ type: `state_creation`, token });
|
|
804
|
+
return token;
|
|
805
|
+
},
|
|
806
|
+
{
|
|
807
|
+
key: options.key,
|
|
808
|
+
type: `readonly_selector_family`,
|
|
809
|
+
subject,
|
|
810
|
+
install: (s) => createReadonlySelectorFamily(options, s)
|
|
811
|
+
}
|
|
812
|
+
);
|
|
813
|
+
store.families.set(options.key, readonlySelectorFamily);
|
|
814
|
+
return readonlySelectorFamily;
|
|
971
815
|
}
|
|
972
|
-
function
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
816
|
+
function createWritableSelectorFamily(options, store) {
|
|
817
|
+
const subject = new Subject();
|
|
818
|
+
const selectorFamily = Object.assign(
|
|
819
|
+
(key) => {
|
|
820
|
+
const subKey = stringifyJson(key);
|
|
821
|
+
const family = { key: options.key, subKey };
|
|
822
|
+
const fullKey = `${options.key}(${subKey})`;
|
|
823
|
+
const target = newest(store);
|
|
824
|
+
const token = createWritableSelector(
|
|
825
|
+
{
|
|
826
|
+
key: fullKey,
|
|
827
|
+
get: options.get(key),
|
|
828
|
+
set: options.set(key)
|
|
829
|
+
},
|
|
830
|
+
family,
|
|
831
|
+
target
|
|
983
832
|
);
|
|
984
|
-
|
|
985
|
-
|
|
833
|
+
subject.next({ type: `state_creation`, token });
|
|
834
|
+
return token;
|
|
835
|
+
},
|
|
836
|
+
{
|
|
837
|
+
key: options.key,
|
|
838
|
+
type: `selector_family`,
|
|
839
|
+
subject,
|
|
840
|
+
install: (s) => createWritableSelectorFamily(options, s)
|
|
841
|
+
}
|
|
842
|
+
);
|
|
843
|
+
store.families.set(options.key, selectorFamily);
|
|
844
|
+
return selectorFamily;
|
|
986
845
|
}
|
|
987
846
|
|
|
988
|
-
// internal/src/
|
|
989
|
-
function
|
|
990
|
-
const
|
|
991
|
-
|
|
992
|
-
|
|
847
|
+
// internal/src/families/create-selector-family.ts
|
|
848
|
+
function createSelectorFamily(options, store) {
|
|
849
|
+
const isWritable = `set` in options;
|
|
850
|
+
if (isWritable) {
|
|
851
|
+
return createWritableSelectorFamily(options, store);
|
|
993
852
|
}
|
|
853
|
+
return createReadonlySelectorFamily(options, store);
|
|
994
854
|
}
|
|
995
855
|
|
|
996
|
-
// internal/src/
|
|
997
|
-
function
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
case `molecule_creation`:
|
|
1012
|
-
ingestMoleculeCreationEvent(updateFromTransaction, applying, store);
|
|
1013
|
-
break;
|
|
1014
|
-
case `molecule_disposal`:
|
|
1015
|
-
ingestMoleculeDisposalEvent(updateFromTransaction, applying, store);
|
|
1016
|
-
break;
|
|
1017
|
-
case `transaction_update`:
|
|
1018
|
-
ingestTransactionUpdate(applying, updateFromTransaction, store);
|
|
1019
|
-
break;
|
|
856
|
+
// internal/src/molecule/dispose-molecule.ts
|
|
857
|
+
function disposeMolecule(token, store) {
|
|
858
|
+
var _a;
|
|
859
|
+
let molecule;
|
|
860
|
+
try {
|
|
861
|
+
molecule = withdraw(token, store);
|
|
862
|
+
} catch (thrown) {
|
|
863
|
+
if (thrown instanceof Error) {
|
|
864
|
+
store.logger.error(
|
|
865
|
+
`\u{1F41E}`,
|
|
866
|
+
`molecule`,
|
|
867
|
+
JSON.stringify(token.key),
|
|
868
|
+
`Failed to dispose molecule, because it was not found in the store.`,
|
|
869
|
+
thrown.message
|
|
870
|
+
);
|
|
1020
871
|
}
|
|
1021
|
-
}
|
|
1022
|
-
}
|
|
1023
|
-
|
|
1024
|
-
// internal/src/transaction/set-epoch-number.ts
|
|
1025
|
-
function setEpochNumberOfContinuity(continuityKey, newEpoch, store) {
|
|
1026
|
-
const isRoot = isRootStore(store);
|
|
1027
|
-
if (isRoot && continuityKey) {
|
|
1028
|
-
store.transactionMeta.epoch.set(continuityKey, newEpoch);
|
|
1029
|
-
}
|
|
1030
|
-
}
|
|
1031
|
-
function setEpochNumberOfAction(transactionKey, newEpoch, store) {
|
|
1032
|
-
const isRoot = isRootStore(store);
|
|
1033
|
-
if (!isRoot) {
|
|
1034
872
|
return;
|
|
1035
873
|
}
|
|
1036
|
-
const
|
|
1037
|
-
|
|
1038
|
-
|
|
874
|
+
const { family } = token;
|
|
875
|
+
const context = [];
|
|
876
|
+
for (const above of molecule.above.values()) {
|
|
877
|
+
context.push(deposit(above));
|
|
1039
878
|
}
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
var _a;
|
|
1045
|
-
const child = newest(store);
|
|
1046
|
-
const { parent } = child;
|
|
1047
|
-
if (parent === null || !isChildStore(child) || ((_a = child.transactionMeta) == null ? void 0 : _a.phase) !== `building`) {
|
|
1048
|
-
store.logger.warn(
|
|
1049
|
-
`\u{1F41E}`,
|
|
1050
|
-
`transaction`,
|
|
1051
|
-
`???`,
|
|
1052
|
-
`applyTransaction called outside of a transaction. This is probably a bug in AtomIO.`
|
|
1053
|
-
);
|
|
1054
|
-
return;
|
|
1055
|
-
}
|
|
1056
|
-
child.transactionMeta.phase = `applying`;
|
|
1057
|
-
child.transactionMeta.update.output = output;
|
|
1058
|
-
parent.child = null;
|
|
1059
|
-
parent.on.transactionApplying.next(child.transactionMeta);
|
|
1060
|
-
const { updates } = child.transactionMeta.update;
|
|
1061
|
-
store.logger.info(
|
|
1062
|
-
`\u{1F6C4}`,
|
|
1063
|
-
`transaction`,
|
|
1064
|
-
child.transactionMeta.update.key,
|
|
1065
|
-
`Applying transaction with ${updates.length} updates:`,
|
|
1066
|
-
updates
|
|
1067
|
-
);
|
|
1068
|
-
for (const tracker of child.trackers.values()) {
|
|
1069
|
-
const mutableKey = tracker.mutableState.key;
|
|
1070
|
-
if (!parent.atoms.has(mutableKey)) {
|
|
1071
|
-
const atom = child.atoms.get(mutableKey);
|
|
1072
|
-
atom == null ? void 0 : atom.install(parent);
|
|
1073
|
-
}
|
|
1074
|
-
tracker.dispose();
|
|
1075
|
-
}
|
|
1076
|
-
ingestTransactionUpdate(`newValue`, child.transactionMeta.update, parent);
|
|
1077
|
-
if (isRootStore(parent)) {
|
|
1078
|
-
setEpochNumberOfAction(
|
|
1079
|
-
child.transactionMeta.update.key,
|
|
1080
|
-
child.transactionMeta.update.epoch,
|
|
1081
|
-
parent
|
|
1082
|
-
);
|
|
1083
|
-
const myTransaction = withdraw(
|
|
1084
|
-
{ key: child.transactionMeta.update.key, type: `transaction` },
|
|
1085
|
-
store
|
|
1086
|
-
);
|
|
1087
|
-
myTransaction == null ? void 0 : myTransaction.subject.next(child.transactionMeta.update);
|
|
1088
|
-
store.logger.info(
|
|
1089
|
-
`\u{1F6EC}`,
|
|
1090
|
-
`transaction`,
|
|
1091
|
-
child.transactionMeta.update.key,
|
|
1092
|
-
`Finished applying transaction.`
|
|
1093
|
-
);
|
|
1094
|
-
} else if (isChildStore(parent)) {
|
|
1095
|
-
parent.transactionMeta.update.updates.push(child.transactionMeta.update);
|
|
1096
|
-
}
|
|
1097
|
-
parent.on.transactionApplying.next(null);
|
|
1098
|
-
};
|
|
1099
|
-
|
|
1100
|
-
// internal/src/transaction/assign-transaction-to-continuity.ts
|
|
1101
|
-
function assignTransactionToContinuity(continuityKey, transactionKey, store) {
|
|
1102
|
-
const isRoot = isRootStore(store);
|
|
1103
|
-
if (!isRoot) {
|
|
1104
|
-
return;
|
|
1105
|
-
}
|
|
1106
|
-
const { epoch, actionContinuities } = store.transactionMeta;
|
|
1107
|
-
actionContinuities.set(continuityKey, transactionKey);
|
|
1108
|
-
if (!epoch.has(continuityKey)) {
|
|
1109
|
-
epoch.set(continuityKey, -1);
|
|
1110
|
-
}
|
|
1111
|
-
}
|
|
1112
|
-
|
|
1113
|
-
// internal/src/lazy-map.ts
|
|
1114
|
-
var LazyMap = class extends Map {
|
|
1115
|
-
constructor(source) {
|
|
1116
|
-
super();
|
|
1117
|
-
this.source = source;
|
|
1118
|
-
this.deleted = /* @__PURE__ */ new Set();
|
|
1119
|
-
}
|
|
1120
|
-
get(key) {
|
|
1121
|
-
const has = super.has(key);
|
|
1122
|
-
if (has) {
|
|
1123
|
-
return super.get(key);
|
|
1124
|
-
}
|
|
1125
|
-
if (!this.deleted.has(key) && this.source.has(key)) {
|
|
1126
|
-
const value = this.source.get(key);
|
|
1127
|
-
return value;
|
|
1128
|
-
}
|
|
1129
|
-
return void 0;
|
|
1130
|
-
}
|
|
1131
|
-
set(key, value) {
|
|
1132
|
-
this.deleted.delete(key);
|
|
1133
|
-
return super.set(key, value);
|
|
1134
|
-
}
|
|
1135
|
-
hasOwn(key) {
|
|
1136
|
-
return super.has(key);
|
|
1137
|
-
}
|
|
1138
|
-
has(key) {
|
|
1139
|
-
return !this.deleted.has(key) && (super.has(key) || this.source.has(key));
|
|
1140
|
-
}
|
|
1141
|
-
delete(key) {
|
|
1142
|
-
this.deleted.add(key);
|
|
1143
|
-
return super.delete(key);
|
|
1144
|
-
}
|
|
1145
|
-
};
|
|
1146
|
-
|
|
1147
|
-
// internal/src/transaction/build-transaction.ts
|
|
1148
|
-
var buildTransaction = (key, params, store, id) => {
|
|
1149
|
-
const parent = newest(store);
|
|
1150
|
-
const childBase = {
|
|
1151
|
-
parent,
|
|
1152
|
-
child: null,
|
|
1153
|
-
on: parent.on,
|
|
1154
|
-
loggers: parent.loggers,
|
|
1155
|
-
logger: parent.logger,
|
|
1156
|
-
config: parent.config,
|
|
1157
|
-
atoms: new LazyMap(parent.atoms),
|
|
1158
|
-
atomsThatAreDefault: new Set(parent.atomsThatAreDefault),
|
|
1159
|
-
families: new LazyMap(parent.families),
|
|
1160
|
-
operation: { open: false },
|
|
1161
|
-
readonlySelectors: new LazyMap(parent.readonlySelectors),
|
|
1162
|
-
timelines: new LazyMap(parent.timelines),
|
|
1163
|
-
timelineAtoms: new Junction(parent.timelineAtoms.toJSON()),
|
|
1164
|
-
trackers: /* @__PURE__ */ new Map(),
|
|
1165
|
-
transactions: new LazyMap(parent.transactions),
|
|
1166
|
-
selectorAtoms: new Junction(parent.selectorAtoms.toJSON()),
|
|
1167
|
-
selectorGraph: new Junction(parent.selectorGraph.toJSON(), {
|
|
1168
|
-
makeContentKey: (...keys) => keys.sort().join(`:`)
|
|
1169
|
-
}),
|
|
1170
|
-
selectors: new LazyMap(parent.selectors),
|
|
1171
|
-
valueMap: new LazyMap(parent.valueMap),
|
|
1172
|
-
molecules: new LazyMap(parent.molecules),
|
|
1173
|
-
moleculeFamilies: new LazyMap(parent.moleculeFamilies),
|
|
1174
|
-
miscResources: new LazyMap(parent.miscResources)
|
|
1175
|
-
};
|
|
1176
|
-
const epoch = getEpochNumberOfAction(key, store);
|
|
1177
|
-
const transactionMeta = {
|
|
1178
|
-
phase: `building`,
|
|
1179
|
-
update: {
|
|
1180
|
-
type: `transaction_update`,
|
|
1181
|
-
key,
|
|
1182
|
-
id,
|
|
1183
|
-
epoch: epoch === void 0 ? Number.NaN : epoch + 1,
|
|
1184
|
-
updates: [],
|
|
1185
|
-
params,
|
|
1186
|
-
output: void 0
|
|
1187
|
-
},
|
|
1188
|
-
transactors: {
|
|
1189
|
-
get: (token) => getFromStore(token, child),
|
|
1190
|
-
set: (token, value) => {
|
|
1191
|
-
setIntoStore(token, value, child);
|
|
1192
|
-
},
|
|
1193
|
-
run: (token, identifier = arbitrary()) => actUponStore(token, identifier, child),
|
|
1194
|
-
find: (token, k) => findInStore(token, k, child),
|
|
1195
|
-
seek: (token, k) => seekInStore(token, k, child),
|
|
1196
|
-
json: (token) => getJsonToken(token, child),
|
|
1197
|
-
make: (context, family, k, ...args) => makeMoleculeInStore(child, context, family, k, ...args),
|
|
1198
|
-
dispose: (token) => {
|
|
1199
|
-
disposeFromStore(token, child);
|
|
1200
|
-
},
|
|
1201
|
-
env: () => getEnvironmentData(child)
|
|
1202
|
-
}
|
|
1203
|
-
};
|
|
1204
|
-
const child = Object.assign(childBase, {
|
|
1205
|
-
transactionMeta
|
|
1206
|
-
});
|
|
1207
|
-
parent.child = child;
|
|
1208
|
-
store.logger.info(
|
|
1209
|
-
`\u{1F6EB}`,
|
|
1210
|
-
`transaction`,
|
|
1211
|
-
key,
|
|
1212
|
-
`Building transaction with params:`,
|
|
1213
|
-
params
|
|
1214
|
-
);
|
|
1215
|
-
return child;
|
|
1216
|
-
};
|
|
1217
|
-
|
|
1218
|
-
// internal/src/transaction/create-transaction.ts
|
|
1219
|
-
function createTransaction(options, store) {
|
|
1220
|
-
const newTransaction = {
|
|
1221
|
-
key: options.key,
|
|
1222
|
-
type: `transaction`,
|
|
1223
|
-
run: (params, id) => {
|
|
1224
|
-
const childStore = buildTransaction(options.key, params, store, id);
|
|
1225
|
-
try {
|
|
1226
|
-
const target2 = newest(store);
|
|
1227
|
-
const { transactors } = childStore.transactionMeta;
|
|
1228
|
-
const output = options.do(transactors, ...params);
|
|
1229
|
-
applyTransaction(output, target2);
|
|
1230
|
-
return output;
|
|
1231
|
-
} catch (thrown) {
|
|
1232
|
-
abortTransaction(target);
|
|
1233
|
-
store.logger.warn(`\u{1F4A5}`, `transaction`, options.key, `caught:`, thrown);
|
|
1234
|
-
throw thrown;
|
|
1235
|
-
}
|
|
1236
|
-
},
|
|
1237
|
-
install: (s) => createTransaction(options, s),
|
|
1238
|
-
subject: new Subject()
|
|
1239
|
-
};
|
|
1240
|
-
const target = newest(store);
|
|
1241
|
-
target.transactions.set(newTransaction.key, newTransaction);
|
|
1242
|
-
const token = deposit(newTransaction);
|
|
1243
|
-
store.on.transactionCreation.next(token);
|
|
1244
|
-
return token;
|
|
1245
|
-
}
|
|
1246
|
-
|
|
1247
|
-
// internal/src/transaction/get-epoch-number.ts
|
|
1248
|
-
function getContinuityKey(transactionKey, store) {
|
|
1249
|
-
const isRoot = isRootStore(store);
|
|
1250
|
-
const continuity = isRoot ? store.transactionMeta.actionContinuities.getRelatedKey(transactionKey) : void 0;
|
|
1251
|
-
return continuity;
|
|
1252
|
-
}
|
|
1253
|
-
function getEpochNumberOfContinuity(continuityKey, store) {
|
|
1254
|
-
const isRoot = isRootStore(store);
|
|
1255
|
-
const epoch = isRoot && continuityKey ? store.transactionMeta.epoch.get(continuityKey) : void 0;
|
|
1256
|
-
return epoch;
|
|
1257
|
-
}
|
|
1258
|
-
function getEpochNumberOfAction(transactionKey, store) {
|
|
1259
|
-
const isRoot = isRootStore(store);
|
|
1260
|
-
const continuity = isRoot ? store.transactionMeta.actionContinuities.getRelatedKey(transactionKey) : void 0;
|
|
1261
|
-
const epoch = isRoot && continuity !== void 0 ? store.transactionMeta.epoch.get(continuity) : void 0;
|
|
1262
|
-
return epoch;
|
|
1263
|
-
}
|
|
1264
|
-
|
|
1265
|
-
// internal/src/transaction/index.ts
|
|
1266
|
-
var TRANSACTION_PHASES = [`idle`, `building`, `applying`];
|
|
1267
|
-
|
|
1268
|
-
// internal/src/molecule/dispose-molecule.ts
|
|
1269
|
-
function disposeMolecule(token, store) {
|
|
1270
|
-
var _a;
|
|
1271
|
-
let molecule;
|
|
1272
|
-
try {
|
|
1273
|
-
molecule = withdraw(token, store);
|
|
1274
|
-
} catch (thrown) {
|
|
1275
|
-
if (thrown instanceof Error) {
|
|
1276
|
-
store.logger.error(
|
|
1277
|
-
`\u{1F41E}`,
|
|
1278
|
-
`molecule`,
|
|
1279
|
-
JSON.stringify(token.key),
|
|
1280
|
-
`Failed to dispose molecule, because it was not found in the store.`,
|
|
1281
|
-
thrown.message
|
|
1282
|
-
);
|
|
1283
|
-
}
|
|
1284
|
-
return;
|
|
1285
|
-
}
|
|
1286
|
-
const { family } = token;
|
|
1287
|
-
for (const state of molecule.tokens.values()) {
|
|
1288
|
-
disposeFromStore(state, store);
|
|
1289
|
-
}
|
|
1290
|
-
for (const child of molecule.below.values()) {
|
|
1291
|
-
if (((_a = child.family) == null ? void 0 : _a.dependsOn) === `all`) {
|
|
1292
|
-
disposeMolecule(child, store);
|
|
1293
|
-
} else {
|
|
1294
|
-
child.above.delete(molecule.stringKey);
|
|
1295
|
-
if (child.above.size === 0) {
|
|
1296
|
-
disposeMolecule(child, store);
|
|
1297
|
-
}
|
|
1298
|
-
}
|
|
879
|
+
const values = [];
|
|
880
|
+
for (const stateToken of molecule.tokens.values()) {
|
|
881
|
+
const tokenFamily = stateToken.family;
|
|
882
|
+
values.push([tokenFamily.key, store.valueMap.get(stateToken.key)]);
|
|
1299
883
|
}
|
|
1300
|
-
molecule.below.clear();
|
|
1301
884
|
if (family) {
|
|
1302
885
|
const Formula = withdraw(family, store);
|
|
1303
886
|
const disposalEvent = {
|
|
1304
887
|
type: `molecule_disposal`,
|
|
1305
888
|
token,
|
|
1306
889
|
family,
|
|
1307
|
-
context
|
|
1308
|
-
|
|
1309
|
-
var _a2;
|
|
1310
|
-
return (_a2 = t.family) == null ? void 0 : _a2.key;
|
|
1311
|
-
}).filter((k) => typeof k === `string`)
|
|
890
|
+
context,
|
|
891
|
+
values
|
|
1312
892
|
};
|
|
1313
893
|
if (token.family) {
|
|
1314
894
|
disposalEvent.family = token.family;
|
|
1315
895
|
}
|
|
896
|
+
for (const state of molecule.tokens.values()) {
|
|
897
|
+
disposeFromStore(state, store);
|
|
898
|
+
}
|
|
899
|
+
for (const child of molecule.below.values()) {
|
|
900
|
+
if (((_a = child.family) == null ? void 0 : _a.dependsOn) === `all`) {
|
|
901
|
+
disposeMolecule(child, store);
|
|
902
|
+
} else {
|
|
903
|
+
child.above.delete(molecule.stringKey);
|
|
904
|
+
if (child.above.size === 0) {
|
|
905
|
+
disposeMolecule(child, store);
|
|
906
|
+
}
|
|
907
|
+
}
|
|
908
|
+
}
|
|
909
|
+
molecule.below.clear();
|
|
1316
910
|
const isTransaction = isChildStore(store) && store.transactionMeta.phase === `building`;
|
|
1317
911
|
if (isTransaction) {
|
|
1318
912
|
store.transactionMeta.update.updates.push(disposalEvent);
|
|
@@ -1355,13 +949,8 @@ function initFamilyMemberInStore(token, key, store) {
|
|
|
1355
949
|
}
|
|
1356
950
|
const state = family(key);
|
|
1357
951
|
const target = newest(store);
|
|
1358
|
-
if (state.family) {
|
|
1359
|
-
if (
|
|
1360
|
-
target.transactionMeta.update.updates.push({
|
|
1361
|
-
type: `state_creation`,
|
|
1362
|
-
token: state
|
|
1363
|
-
});
|
|
1364
|
-
} else {
|
|
952
|
+
if (state.family && target.moleculeInProgress === null) {
|
|
953
|
+
if (isRootStore(target)) {
|
|
1365
954
|
switch (state.type) {
|
|
1366
955
|
case `atom`:
|
|
1367
956
|
case `mutable_atom`:
|
|
@@ -1372,9 +961,14 @@ function initFamilyMemberInStore(token, key, store) {
|
|
|
1372
961
|
store.on.selectorCreation.next(state);
|
|
1373
962
|
break;
|
|
1374
963
|
}
|
|
1375
|
-
}
|
|
1376
|
-
|
|
1377
|
-
|
|
964
|
+
} else if (isChildStore(target) && target.on.transactionApplying.state === null) {
|
|
965
|
+
target.transactionMeta.update.updates.push({
|
|
966
|
+
type: `state_creation`,
|
|
967
|
+
token: state
|
|
968
|
+
});
|
|
969
|
+
}
|
|
970
|
+
}
|
|
971
|
+
return state;
|
|
1378
972
|
}
|
|
1379
973
|
function seekInStore(token, key, store) {
|
|
1380
974
|
const subKey = stringifyJson(key);
|
|
@@ -1419,291 +1013,715 @@ function findInStore(token, key, store) {
|
|
|
1419
1013
|
return state;
|
|
1420
1014
|
}
|
|
1421
1015
|
|
|
1422
|
-
// internal/src/
|
|
1423
|
-
|
|
1424
|
-
var
|
|
1425
|
-
|
|
1426
|
-
|
|
1016
|
+
// internal/src/molecule/create-molecule-family.ts
|
|
1017
|
+
function createMoleculeFamily(options, store) {
|
|
1018
|
+
var _a;
|
|
1019
|
+
const subject = new Subject();
|
|
1020
|
+
const token = {
|
|
1021
|
+
type: `molecule_family`,
|
|
1022
|
+
key: options.key,
|
|
1023
|
+
dependsOn: (_a = options.dependsOn) != null ? _a : `all`
|
|
1024
|
+
};
|
|
1025
|
+
const family = __spreadProps(__spreadValues({}, token), {
|
|
1026
|
+
subject,
|
|
1027
|
+
new: options.new
|
|
1028
|
+
});
|
|
1029
|
+
store.moleculeFamilies.set(options.key, family);
|
|
1030
|
+
return token;
|
|
1031
|
+
}
|
|
1427
1032
|
|
|
1428
|
-
// internal/src/
|
|
1429
|
-
|
|
1430
|
-
const
|
|
1431
|
-
|
|
1432
|
-
|
|
1033
|
+
// internal/src/molecule/grow-molecule-in-store.ts
|
|
1034
|
+
function growMoleculeInStore(molecule, family, store) {
|
|
1035
|
+
const stateToken = initFamilyMemberInStore(family, molecule.key, store);
|
|
1036
|
+
molecule.tokens.set(stateToken.key, stateToken);
|
|
1037
|
+
const isTransaction = isChildStore(store) && store.transactionMeta.phase === `building`;
|
|
1038
|
+
const moleculeInProgress = store.moleculeInProgress === molecule.key;
|
|
1039
|
+
if (!isTransaction && !moleculeInProgress) {
|
|
1040
|
+
molecule.subject.next({ type: `state_creation`, token: stateToken });
|
|
1041
|
+
}
|
|
1042
|
+
return stateToken;
|
|
1043
|
+
}
|
|
1433
1044
|
|
|
1434
|
-
// internal/src/
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
const indirectDependencyKeys = getSelectorDependencyKeys(
|
|
1438
|
-
directDependencyKey,
|
|
1045
|
+
// internal/src/get-environment-data.ts
|
|
1046
|
+
function getEnvironmentData(store) {
|
|
1047
|
+
return {
|
|
1439
1048
|
store
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1049
|
+
};
|
|
1050
|
+
}
|
|
1051
|
+
|
|
1052
|
+
// internal/src/get-state/get-from-store.ts
|
|
1053
|
+
function getFromStore(token, store) {
|
|
1054
|
+
if (token.type === `molecule`) {
|
|
1055
|
+
try {
|
|
1056
|
+
const molecule = withdraw(token, store);
|
|
1057
|
+
return molecule.instance;
|
|
1058
|
+
} catch (_) {
|
|
1059
|
+
return void 0;
|
|
1449
1060
|
}
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1061
|
+
}
|
|
1062
|
+
const state = withdraw(token, store);
|
|
1063
|
+
return readOrComputeValue(state, store);
|
|
1064
|
+
}
|
|
1065
|
+
var Molecule = class {
|
|
1066
|
+
constructor(ctx, key, family) {
|
|
1067
|
+
this.key = key;
|
|
1068
|
+
this.type = `molecule`;
|
|
1069
|
+
this.subject = new Subject();
|
|
1070
|
+
this.tokens = /* @__PURE__ */ new Map();
|
|
1071
|
+
this.above = /* @__PURE__ */ new Map();
|
|
1072
|
+
this.below = /* @__PURE__ */ new Map();
|
|
1073
|
+
this.joins = /* @__PURE__ */ new Map();
|
|
1074
|
+
this.stringKey = stringifyJson(key);
|
|
1075
|
+
if (family) {
|
|
1076
|
+
this.family = family;
|
|
1077
|
+
}
|
|
1078
|
+
if (ctx) {
|
|
1079
|
+
if (Array.isArray(ctx)) {
|
|
1080
|
+
for (const molecule of ctx) {
|
|
1081
|
+
this.above.set(molecule.stringKey, molecule);
|
|
1082
|
+
}
|
|
1083
|
+
} else {
|
|
1084
|
+
this.above.set(ctx.stringKey, ctx);
|
|
1085
|
+
}
|
|
1456
1086
|
}
|
|
1457
1087
|
}
|
|
1458
|
-
return rootKeys;
|
|
1459
|
-
};
|
|
1460
|
-
var traceAllSelectorAtoms = (selector, store) => {
|
|
1461
|
-
const selectorKey = selector.key;
|
|
1462
|
-
const directDependencyKeys = getSelectorDependencyKeys(selectorKey, store);
|
|
1463
|
-
return directDependencyKeys.flatMap(
|
|
1464
|
-
(depKey) => isAtomKey(depKey, store) ? depKey : traceSelectorAtoms(selectorKey, depKey, store)
|
|
1465
|
-
);
|
|
1466
1088
|
};
|
|
1467
1089
|
|
|
1468
|
-
// internal/src/
|
|
1469
|
-
|
|
1090
|
+
// internal/src/molecule/make-molecule-in-store.ts
|
|
1091
|
+
function makeMoleculeInStore(store, context, familyToken, key, ...params) {
|
|
1470
1092
|
const target = newest(store);
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
const rootKeys = traceSelectorAtoms(selectorKey, dependency.key, store);
|
|
1484
|
-
store.logger.info(
|
|
1485
|
-
`\u{1F50D}`,
|
|
1486
|
-
`selector`,
|
|
1487
|
-
selectorKey,
|
|
1488
|
-
`discovers root atoms: [ ${rootKeys.map((key) => `"${key}"`).join(`, `)} ]`
|
|
1489
|
-
);
|
|
1490
|
-
for (const atomKey of rootKeys) {
|
|
1491
|
-
target.selectorAtoms = target.selectorAtoms.set({
|
|
1492
|
-
selectorKey,
|
|
1493
|
-
atomKey
|
|
1494
|
-
});
|
|
1093
|
+
target.moleculeInProgress = key;
|
|
1094
|
+
const contextArray = Array.isArray(context) ? context : [context];
|
|
1095
|
+
const owners = contextArray.map((ctx) => {
|
|
1096
|
+
if (ctx instanceof Molecule) {
|
|
1097
|
+
return ctx;
|
|
1098
|
+
}
|
|
1099
|
+
const stringKey = stringifyJson(ctx.key);
|
|
1100
|
+
const molecule2 = store.molecules.get(stringKey);
|
|
1101
|
+
if (!molecule2) {
|
|
1102
|
+
throw new Error(
|
|
1103
|
+
`Molecule ${stringKey} not found in store "${store.config.name}"`
|
|
1104
|
+
);
|
|
1495
1105
|
}
|
|
1106
|
+
return molecule2;
|
|
1107
|
+
});
|
|
1108
|
+
const molecule = new Molecule(owners, key, familyToken);
|
|
1109
|
+
target.molecules.set(stringifyJson(key), molecule);
|
|
1110
|
+
for (const owner of owners) {
|
|
1111
|
+
owner.below.set(molecule.stringKey, molecule);
|
|
1496
1112
|
}
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
store
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
{
|
|
1519
|
-
|
|
1113
|
+
const transactors = {
|
|
1114
|
+
get: (t) => getFromStore(t, newest(store)),
|
|
1115
|
+
set: (t, newValue) => {
|
|
1116
|
+
setIntoStore(t, newValue, newest(store));
|
|
1117
|
+
},
|
|
1118
|
+
seek: (t, k) => seekInStore(t, k, newest(store)),
|
|
1119
|
+
json: (t) => getJsonToken(t, newest(store)),
|
|
1120
|
+
run: (t, i = arbitrary()) => actUponStore(t, i, newest(store)),
|
|
1121
|
+
make: (ctx, f, k, ...args) => makeMoleculeInStore(newest(store), ctx, f, k, ...args),
|
|
1122
|
+
dispose: (t) => {
|
|
1123
|
+
disposeFromStore(t, newest(store));
|
|
1124
|
+
},
|
|
1125
|
+
env: () => getEnvironmentData(newest(store)),
|
|
1126
|
+
bond: (f) => growMoleculeInStore(
|
|
1127
|
+
molecule,
|
|
1128
|
+
withdraw(f, store),
|
|
1129
|
+
newest(store)
|
|
1130
|
+
),
|
|
1131
|
+
claim: (below, options) => {
|
|
1132
|
+
const { exclusive } = options;
|
|
1133
|
+
const belowMolecule = newest(store).molecules.get(stringifyJson(below.key));
|
|
1134
|
+
if (belowMolecule) {
|
|
1135
|
+
if (exclusive) {
|
|
1136
|
+
for (const value of belowMolecule.above.values()) {
|
|
1137
|
+
value.below.delete(belowMolecule.stringKey);
|
|
1138
|
+
}
|
|
1139
|
+
belowMolecule.above.clear();
|
|
1140
|
+
belowMolecule.above.set(molecule.stringKey, molecule);
|
|
1141
|
+
molecule.below.set(belowMolecule.stringKey, belowMolecule);
|
|
1142
|
+
} else {
|
|
1143
|
+
belowMolecule.above.set(molecule.stringKey, molecule);
|
|
1144
|
+
molecule.below.set(belowMolecule.stringKey, belowMolecule);
|
|
1145
|
+
}
|
|
1520
1146
|
}
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
var createReadonlySelector = (options, family, store) => {
|
|
1536
|
-
const target = newest(store);
|
|
1537
|
-
const subject = new Subject();
|
|
1538
|
-
const { get, find, seek, json } = registerSelector(options.key, target);
|
|
1539
|
-
const getSelf = () => {
|
|
1540
|
-
const value = options.get({ get, find, seek, json });
|
|
1541
|
-
cacheValue(options.key, value, subject, newest(store));
|
|
1542
|
-
return value;
|
|
1147
|
+
},
|
|
1148
|
+
join: (joinToken) => {
|
|
1149
|
+
const join = getJoin(joinToken, store);
|
|
1150
|
+
join.molecules.set(stringifyJson(key), molecule);
|
|
1151
|
+
molecule.joins.set(joinToken.key, join);
|
|
1152
|
+
return joinToken;
|
|
1153
|
+
},
|
|
1154
|
+
spawn: (f, k, ...p) => makeMoleculeInStore(
|
|
1155
|
+
newest(store),
|
|
1156
|
+
[molecule],
|
|
1157
|
+
withdraw(f, store),
|
|
1158
|
+
k,
|
|
1159
|
+
...p
|
|
1160
|
+
)
|
|
1543
1161
|
};
|
|
1544
|
-
const
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
get: getSelf,
|
|
1548
|
-
type: `readonly_selector`
|
|
1549
|
-
}), family && { family });
|
|
1550
|
-
target.readonlySelectors.set(options.key, readonlySelector);
|
|
1551
|
-
const initialValue = getSelf();
|
|
1552
|
-
store.logger.info(
|
|
1553
|
-
`\u2728`,
|
|
1554
|
-
readonlySelector.type,
|
|
1555
|
-
readonlySelector.key,
|
|
1556
|
-
`=`,
|
|
1557
|
-
initialValue
|
|
1558
|
-
);
|
|
1162
|
+
const family = withdraw(familyToken, store);
|
|
1163
|
+
const Constructor = family.new;
|
|
1164
|
+
molecule.instance = new Constructor(transactors, key, ...params);
|
|
1559
1165
|
const token = {
|
|
1560
|
-
|
|
1561
|
-
|
|
1166
|
+
type: `molecule`,
|
|
1167
|
+
key,
|
|
1168
|
+
family: familyToken
|
|
1562
1169
|
};
|
|
1563
|
-
|
|
1564
|
-
|
|
1170
|
+
const update = {
|
|
1171
|
+
type: `molecule_creation`,
|
|
1172
|
+
token,
|
|
1173
|
+
family: familyToken,
|
|
1174
|
+
context: contextArray,
|
|
1175
|
+
params
|
|
1176
|
+
};
|
|
1177
|
+
if (isRootStore(target)) {
|
|
1178
|
+
family.subject.next(update);
|
|
1179
|
+
} else if (isChildStore(target) && target.on.transactionApplying.state === null) {
|
|
1180
|
+
target.transactionMeta.update.updates.push(update);
|
|
1565
1181
|
}
|
|
1182
|
+
target.moleculeInProgress = null;
|
|
1566
1183
|
return token;
|
|
1567
|
-
}
|
|
1184
|
+
}
|
|
1568
1185
|
|
|
1569
|
-
// internal/src/
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
return value;
|
|
1580
|
-
};
|
|
1581
|
-
const setSelf = (next) => {
|
|
1582
|
-
const oldValue = getSelf();
|
|
1583
|
-
const newValue = become(next)(oldValue);
|
|
1584
|
-
store.logger.info(
|
|
1585
|
-
`\u{1F4DD}`,
|
|
1586
|
-
`selector`,
|
|
1587
|
-
options.key,
|
|
1588
|
-
`set (`,
|
|
1589
|
-
oldValue,
|
|
1590
|
-
`->`,
|
|
1591
|
-
newValue,
|
|
1592
|
-
`)`
|
|
1593
|
-
);
|
|
1594
|
-
cacheValue(options.key, newValue, subject, store);
|
|
1595
|
-
markDone(options.key, store);
|
|
1596
|
-
if (isRootStore(target)) {
|
|
1597
|
-
subject.next({ newValue, oldValue });
|
|
1186
|
+
// internal/src/ingest-updates/ingest-creation-disposal.ts
|
|
1187
|
+
function ingestCreationEvent(update, applying, store) {
|
|
1188
|
+
switch (applying) {
|
|
1189
|
+
case `newValue`: {
|
|
1190
|
+
createInStore(update.token, store);
|
|
1191
|
+
break;
|
|
1192
|
+
}
|
|
1193
|
+
case `oldValue`: {
|
|
1194
|
+
disposeFromStore(update.token, store);
|
|
1195
|
+
break;
|
|
1598
1196
|
}
|
|
1599
|
-
options.set(transactors, newValue);
|
|
1600
|
-
};
|
|
1601
|
-
const mySelector = __spreadValues(__spreadProps(__spreadValues({}, options), {
|
|
1602
|
-
subject,
|
|
1603
|
-
install: (s) => createWritableSelector(options, family, s),
|
|
1604
|
-
get: getSelf,
|
|
1605
|
-
set: setSelf,
|
|
1606
|
-
type: `selector`
|
|
1607
|
-
}), family && { family });
|
|
1608
|
-
target.selectors.set(options.key, mySelector);
|
|
1609
|
-
const initialValue = getSelf();
|
|
1610
|
-
store.logger.info(`\u2728`, mySelector.type, mySelector.key, `=`, initialValue);
|
|
1611
|
-
const token = {
|
|
1612
|
-
key: options.key,
|
|
1613
|
-
type: `selector`
|
|
1614
|
-
};
|
|
1615
|
-
if (family) {
|
|
1616
|
-
token.family = family;
|
|
1617
1197
|
}
|
|
1618
|
-
|
|
1619
|
-
|
|
1198
|
+
}
|
|
1199
|
+
function ingestDisposalEvent(update, applying, store) {
|
|
1200
|
+
switch (applying) {
|
|
1201
|
+
case `newValue`: {
|
|
1202
|
+
disposeFromStore(update.token, store);
|
|
1203
|
+
break;
|
|
1204
|
+
}
|
|
1205
|
+
case `oldValue`: {
|
|
1206
|
+
createInStore(update.token, store);
|
|
1207
|
+
store.valueMap.set(update.token.key, update.value);
|
|
1208
|
+
break;
|
|
1209
|
+
}
|
|
1210
|
+
}
|
|
1211
|
+
}
|
|
1212
|
+
function createInStore(token, store) {
|
|
1213
|
+
if (token.family) {
|
|
1214
|
+
const family = store.families.get(token.family.key);
|
|
1215
|
+
if (family) {
|
|
1216
|
+
const molecule = store.molecules.get(token.family.subKey);
|
|
1217
|
+
if (molecule) {
|
|
1218
|
+
growMoleculeInStore(molecule, family, store);
|
|
1219
|
+
return;
|
|
1220
|
+
}
|
|
1221
|
+
if (store.config.lifespan === `immortal`) {
|
|
1222
|
+
throw new Error(`No molecule found for key "${token.family.subKey}"`);
|
|
1223
|
+
}
|
|
1224
|
+
initFamilyMemberInStore(family, parseJson(token.family.subKey), store);
|
|
1225
|
+
}
|
|
1226
|
+
}
|
|
1227
|
+
}
|
|
1228
|
+
function ingestMoleculeCreationEvent(update, applying, store) {
|
|
1229
|
+
switch (applying) {
|
|
1230
|
+
case `newValue`:
|
|
1231
|
+
makeMoleculeInStore(
|
|
1232
|
+
store,
|
|
1233
|
+
update.context,
|
|
1234
|
+
update.family,
|
|
1235
|
+
update.token.key,
|
|
1236
|
+
...update.params
|
|
1237
|
+
);
|
|
1238
|
+
break;
|
|
1239
|
+
case `oldValue`:
|
|
1240
|
+
disposeFromStore(update.token, store);
|
|
1241
|
+
break;
|
|
1242
|
+
}
|
|
1243
|
+
}
|
|
1244
|
+
function ingestMoleculeDisposalEvent(update, applying, store) {
|
|
1245
|
+
switch (applying) {
|
|
1246
|
+
case `newValue`:
|
|
1247
|
+
disposeFromStore(update.token, store);
|
|
1248
|
+
break;
|
|
1249
|
+
case `oldValue`:
|
|
1250
|
+
{
|
|
1251
|
+
const moleculeToken = makeMoleculeInStore(
|
|
1252
|
+
store,
|
|
1253
|
+
update.context,
|
|
1254
|
+
update.family,
|
|
1255
|
+
update.token.key
|
|
1256
|
+
);
|
|
1257
|
+
for (const [familyKey, value] of update.values) {
|
|
1258
|
+
const memberKey = `${familyKey}(${stringifyJson(moleculeToken.key)})`;
|
|
1259
|
+
const molecule = withdraw(moleculeToken, store);
|
|
1260
|
+
const alreadyCreated = molecule.tokens.has(memberKey);
|
|
1261
|
+
const family = store.families.get(familyKey);
|
|
1262
|
+
if (family && !alreadyCreated) {
|
|
1263
|
+
growMoleculeInStore(molecule, family, store);
|
|
1264
|
+
}
|
|
1265
|
+
store.valueMap.set(memberKey, value);
|
|
1266
|
+
}
|
|
1267
|
+
}
|
|
1268
|
+
break;
|
|
1269
|
+
}
|
|
1270
|
+
}
|
|
1620
1271
|
|
|
1621
|
-
// internal/src/
|
|
1622
|
-
function
|
|
1623
|
-
const
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
store.on.selectorCreation.next(state2);
|
|
1627
|
-
return state2;
|
|
1272
|
+
// internal/src/ingest-updates/ingest-selector-update.ts
|
|
1273
|
+
function ingestSelectorUpdate(applying, selectorUpdate, store) {
|
|
1274
|
+
const updates = applying === `newValue` ? selectorUpdate.atomUpdates : [...selectorUpdate.atomUpdates].reverse();
|
|
1275
|
+
for (const atomUpdate of updates) {
|
|
1276
|
+
ingestAtomUpdate(applying, atomUpdate, store);
|
|
1628
1277
|
}
|
|
1629
|
-
const state = createReadonlySelector(options, void 0, store);
|
|
1630
|
-
store.on.selectorCreation.next(state);
|
|
1631
|
-
return state;
|
|
1632
1278
|
}
|
|
1633
1279
|
|
|
1634
|
-
// internal/src/
|
|
1635
|
-
function
|
|
1280
|
+
// internal/src/ingest-updates/ingest-transaction-update.ts
|
|
1281
|
+
function ingestTransactionUpdate(applying, transactionUpdate, store) {
|
|
1282
|
+
const updates = applying === `newValue` ? transactionUpdate.updates : [...transactionUpdate.updates].reverse();
|
|
1283
|
+
for (const updateFromTransaction of updates) {
|
|
1284
|
+
switch (updateFromTransaction.type) {
|
|
1285
|
+
case `atom_update`:
|
|
1286
|
+
case `selector_update`:
|
|
1287
|
+
ingestAtomUpdate(applying, updateFromTransaction, store);
|
|
1288
|
+
break;
|
|
1289
|
+
case `state_creation`:
|
|
1290
|
+
ingestCreationEvent(updateFromTransaction, applying, store);
|
|
1291
|
+
break;
|
|
1292
|
+
case `state_disposal`:
|
|
1293
|
+
ingestDisposalEvent(updateFromTransaction, applying, store);
|
|
1294
|
+
break;
|
|
1295
|
+
case `molecule_creation`:
|
|
1296
|
+
ingestMoleculeCreationEvent(updateFromTransaction, applying, store);
|
|
1297
|
+
break;
|
|
1298
|
+
case `molecule_disposal`:
|
|
1299
|
+
ingestMoleculeDisposalEvent(updateFromTransaction, applying, store);
|
|
1300
|
+
break;
|
|
1301
|
+
case `transaction_update`:
|
|
1302
|
+
ingestTransactionUpdate(applying, updateFromTransaction, store);
|
|
1303
|
+
break;
|
|
1304
|
+
}
|
|
1305
|
+
}
|
|
1306
|
+
}
|
|
1307
|
+
|
|
1308
|
+
// internal/src/transaction/set-epoch-number.ts
|
|
1309
|
+
function setEpochNumberOfContinuity(continuityKey, newEpoch, store) {
|
|
1310
|
+
const isRoot = isRootStore(store);
|
|
1311
|
+
if (isRoot && continuityKey) {
|
|
1312
|
+
store.transactionMeta.epoch.set(continuityKey, newEpoch);
|
|
1313
|
+
}
|
|
1314
|
+
}
|
|
1315
|
+
function setEpochNumberOfAction(transactionKey, newEpoch, store) {
|
|
1316
|
+
const isRoot = isRootStore(store);
|
|
1317
|
+
if (!isRoot) {
|
|
1318
|
+
return;
|
|
1319
|
+
}
|
|
1320
|
+
const continuityKey = store.transactionMeta.actionContinuities.getRelatedKey(transactionKey);
|
|
1321
|
+
if (continuityKey !== void 0) {
|
|
1322
|
+
store.transactionMeta.epoch.set(continuityKey, newEpoch);
|
|
1323
|
+
}
|
|
1324
|
+
}
|
|
1325
|
+
|
|
1326
|
+
// internal/src/transaction/apply-transaction.ts
|
|
1327
|
+
var applyTransaction = (output, store) => {
|
|
1636
1328
|
var _a;
|
|
1637
|
-
const
|
|
1638
|
-
const {
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
`Tried to dispose selector, but it does not exist in the store.`
|
|
1329
|
+
const child = newest(store);
|
|
1330
|
+
const { parent } = child;
|
|
1331
|
+
if (parent === null || !isChildStore(child) || ((_a = child.transactionMeta) == null ? void 0 : _a.phase) !== `building`) {
|
|
1332
|
+
store.logger.warn(
|
|
1333
|
+
`\u{1F41E}`,
|
|
1334
|
+
`transaction`,
|
|
1335
|
+
`???`,
|
|
1336
|
+
`applyTransaction called outside of a transaction. This is probably a bug in AtomIO.`
|
|
1646
1337
|
);
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1338
|
+
return;
|
|
1339
|
+
}
|
|
1340
|
+
child.transactionMeta.phase = `applying`;
|
|
1341
|
+
child.transactionMeta.update.output = output;
|
|
1342
|
+
parent.child = null;
|
|
1343
|
+
parent.on.transactionApplying.next(child.transactionMeta);
|
|
1344
|
+
const { updates } = child.transactionMeta.update;
|
|
1345
|
+
store.logger.info(
|
|
1346
|
+
`\u{1F6C4}`,
|
|
1347
|
+
`transaction`,
|
|
1348
|
+
child.transactionMeta.update.key,
|
|
1349
|
+
`Applying transaction with ${updates.length} updates:`,
|
|
1350
|
+
updates
|
|
1351
|
+
);
|
|
1352
|
+
ingestTransactionUpdate(`newValue`, child.transactionMeta.update, parent);
|
|
1353
|
+
if (isRootStore(parent)) {
|
|
1354
|
+
setEpochNumberOfAction(
|
|
1355
|
+
child.transactionMeta.update.key,
|
|
1356
|
+
child.transactionMeta.update.epoch,
|
|
1357
|
+
parent
|
|
1653
1358
|
);
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1359
|
+
const myTransaction = withdraw(
|
|
1360
|
+
{ key: child.transactionMeta.update.key, type: `transaction` },
|
|
1361
|
+
store
|
|
1362
|
+
);
|
|
1363
|
+
myTransaction == null ? void 0 : myTransaction.subject.next(child.transactionMeta.update);
|
|
1364
|
+
store.logger.info(
|
|
1365
|
+
`\u{1F6EC}`,
|
|
1366
|
+
`transaction`,
|
|
1367
|
+
child.transactionMeta.update.key,
|
|
1368
|
+
`Finished applying transaction.`
|
|
1369
|
+
);
|
|
1370
|
+
} else if (isChildStore(parent)) {
|
|
1371
|
+
parent.transactionMeta.update.updates.push(child.transactionMeta.update);
|
|
1372
|
+
}
|
|
1373
|
+
parent.on.transactionApplying.next(null);
|
|
1374
|
+
};
|
|
1375
|
+
|
|
1376
|
+
// internal/src/transaction/assign-transaction-to-continuity.ts
|
|
1377
|
+
function assignTransactionToContinuity(continuityKey, transactionKey, store) {
|
|
1378
|
+
const isRoot = isRootStore(store);
|
|
1379
|
+
if (!isRoot) {
|
|
1380
|
+
return;
|
|
1381
|
+
}
|
|
1382
|
+
const { epoch, actionContinuities } = store.transactionMeta;
|
|
1383
|
+
actionContinuities.set(continuityKey, transactionKey);
|
|
1384
|
+
if (!epoch.has(continuityKey)) {
|
|
1385
|
+
epoch.set(continuityKey, -1);
|
|
1386
|
+
}
|
|
1387
|
+
}
|
|
1388
|
+
|
|
1389
|
+
// internal/src/lazy-map.ts
|
|
1390
|
+
var LazyMap = class extends Map {
|
|
1391
|
+
constructor(source) {
|
|
1392
|
+
super();
|
|
1393
|
+
this.source = source;
|
|
1394
|
+
this.deleted = /* @__PURE__ */ new Set();
|
|
1395
|
+
}
|
|
1396
|
+
get(key) {
|
|
1397
|
+
const has = super.has(key);
|
|
1398
|
+
if (has) {
|
|
1399
|
+
return super.get(key);
|
|
1400
|
+
}
|
|
1401
|
+
if (!this.deleted.has(key) && this.source.has(key)) {
|
|
1402
|
+
const value = this.source.get(key);
|
|
1403
|
+
return value;
|
|
1404
|
+
}
|
|
1405
|
+
return void 0;
|
|
1406
|
+
}
|
|
1407
|
+
set(key, value) {
|
|
1408
|
+
this.deleted.delete(key);
|
|
1409
|
+
return super.set(key, value);
|
|
1410
|
+
}
|
|
1411
|
+
hasOwn(key) {
|
|
1412
|
+
return super.has(key);
|
|
1413
|
+
}
|
|
1414
|
+
has(key) {
|
|
1415
|
+
return !this.deleted.has(key) && (super.has(key) || this.source.has(key));
|
|
1416
|
+
}
|
|
1417
|
+
delete(key) {
|
|
1418
|
+
this.deleted.add(key);
|
|
1419
|
+
return super.delete(key);
|
|
1420
|
+
}
|
|
1421
|
+
};
|
|
1422
|
+
|
|
1423
|
+
// internal/src/transaction/build-transaction.ts
|
|
1424
|
+
var buildTransaction = (key, params, store, id) => {
|
|
1425
|
+
const parent = newest(store);
|
|
1426
|
+
const childBase = {
|
|
1427
|
+
parent,
|
|
1428
|
+
child: null,
|
|
1429
|
+
on: parent.on,
|
|
1430
|
+
loggers: parent.loggers,
|
|
1431
|
+
logger: parent.logger,
|
|
1432
|
+
config: parent.config,
|
|
1433
|
+
atoms: new LazyMap(parent.atoms),
|
|
1434
|
+
atomsThatAreDefault: new Set(parent.atomsThatAreDefault),
|
|
1435
|
+
families: new LazyMap(parent.families),
|
|
1436
|
+
operation: { open: false },
|
|
1437
|
+
readonlySelectors: new LazyMap(parent.readonlySelectors),
|
|
1438
|
+
timelines: new LazyMap(parent.timelines),
|
|
1439
|
+
timelineTopics: new Junction(parent.timelineTopics.toJSON()),
|
|
1440
|
+
trackers: /* @__PURE__ */ new Map(),
|
|
1441
|
+
transactions: new LazyMap(parent.transactions),
|
|
1442
|
+
selectorAtoms: new Junction(parent.selectorAtoms.toJSON()),
|
|
1443
|
+
selectorGraph: new Junction(parent.selectorGraph.toJSON(), {
|
|
1444
|
+
makeContentKey: (...keys) => keys.sort().join(`:`)
|
|
1445
|
+
}),
|
|
1446
|
+
selectors: new LazyMap(parent.selectors),
|
|
1447
|
+
valueMap: new LazyMap(parent.valueMap),
|
|
1448
|
+
molecules: new LazyMap(parent.molecules),
|
|
1449
|
+
moleculeFamilies: new LazyMap(parent.moleculeFamilies),
|
|
1450
|
+
moleculeInProgress: parent.moleculeInProgress,
|
|
1451
|
+
miscResources: new LazyMap(parent.miscResources)
|
|
1452
|
+
};
|
|
1453
|
+
const epoch = getEpochNumberOfAction(key, store);
|
|
1454
|
+
const transactionMeta = {
|
|
1455
|
+
phase: `building`,
|
|
1456
|
+
update: {
|
|
1457
|
+
type: `transaction_update`,
|
|
1458
|
+
key,
|
|
1459
|
+
id,
|
|
1460
|
+
epoch: epoch === void 0 ? Number.NaN : epoch + 1,
|
|
1461
|
+
updates: [],
|
|
1462
|
+
params,
|
|
1463
|
+
output: void 0
|
|
1464
|
+
},
|
|
1465
|
+
transactors: {
|
|
1466
|
+
get: (token) => getFromStore(token, child),
|
|
1467
|
+
set: (token, value) => {
|
|
1468
|
+
setIntoStore(token, value, child);
|
|
1469
|
+
},
|
|
1470
|
+
run: (token, identifier = arbitrary()) => actUponStore(token, identifier, child),
|
|
1471
|
+
find: (token, k) => findInStore(token, k, child),
|
|
1472
|
+
seek: (token, k) => seekInStore(token, k, child),
|
|
1473
|
+
json: (token) => getJsonToken(token, child),
|
|
1474
|
+
make: (context, family, k, ...args) => makeMoleculeInStore(child, context, family, k, ...args),
|
|
1475
|
+
dispose: (token) => {
|
|
1476
|
+
disposeFromStore(token, child);
|
|
1477
|
+
},
|
|
1478
|
+
env: () => getEnvironmentData(child)
|
|
1479
|
+
}
|
|
1480
|
+
};
|
|
1481
|
+
const child = Object.assign(childBase, {
|
|
1482
|
+
transactionMeta
|
|
1483
|
+
});
|
|
1484
|
+
parent.child = child;
|
|
1485
|
+
store.logger.info(
|
|
1486
|
+
`\u{1F6EB}`,
|
|
1487
|
+
`transaction`,
|
|
1488
|
+
key,
|
|
1489
|
+
`Building transaction with params:`,
|
|
1490
|
+
params
|
|
1491
|
+
);
|
|
1492
|
+
return child;
|
|
1493
|
+
};
|
|
1494
|
+
|
|
1495
|
+
// internal/src/transaction/create-transaction.ts
|
|
1496
|
+
function createTransaction(options, store) {
|
|
1497
|
+
const newTransaction = {
|
|
1498
|
+
key: options.key,
|
|
1499
|
+
type: `transaction`,
|
|
1500
|
+
run: (params, id) => {
|
|
1501
|
+
const childStore = buildTransaction(options.key, params, store, id);
|
|
1502
|
+
try {
|
|
1503
|
+
const target2 = newest(store);
|
|
1504
|
+
const { transactors } = childStore.transactionMeta;
|
|
1505
|
+
const output = options.do(transactors, ...params);
|
|
1506
|
+
applyTransaction(output, target2);
|
|
1507
|
+
return output;
|
|
1508
|
+
} catch (thrown) {
|
|
1509
|
+
abortTransaction(target);
|
|
1510
|
+
store.logger.warn(`\u{1F4A5}`, `transaction`, options.key, `caught:`, thrown);
|
|
1511
|
+
throw thrown;
|
|
1512
|
+
}
|
|
1513
|
+
},
|
|
1514
|
+
install: (s) => createTransaction(options, s),
|
|
1515
|
+
subject: new Subject()
|
|
1516
|
+
};
|
|
1517
|
+
const target = newest(store);
|
|
1518
|
+
target.transactions.set(newTransaction.key, newTransaction);
|
|
1519
|
+
const token = deposit(newTransaction);
|
|
1520
|
+
store.on.transactionCreation.next(token);
|
|
1521
|
+
return token;
|
|
1522
|
+
}
|
|
1523
|
+
|
|
1524
|
+
// internal/src/transaction/get-epoch-number.ts
|
|
1525
|
+
function getContinuityKey(transactionKey, store) {
|
|
1526
|
+
const isRoot = isRootStore(store);
|
|
1527
|
+
const continuity = isRoot ? store.transactionMeta.actionContinuities.getRelatedKey(transactionKey) : void 0;
|
|
1528
|
+
return continuity;
|
|
1529
|
+
}
|
|
1530
|
+
function getEpochNumberOfContinuity(continuityKey, store) {
|
|
1531
|
+
const isRoot = isRootStore(store);
|
|
1532
|
+
const epoch = isRoot && continuityKey ? store.transactionMeta.epoch.get(continuityKey) : void 0;
|
|
1533
|
+
return epoch;
|
|
1534
|
+
}
|
|
1535
|
+
function getEpochNumberOfAction(transactionKey, store) {
|
|
1536
|
+
const isRoot = isRootStore(store);
|
|
1537
|
+
const continuity = isRoot ? store.transactionMeta.actionContinuities.getRelatedKey(transactionKey) : void 0;
|
|
1538
|
+
const epoch = isRoot && continuity !== void 0 ? store.transactionMeta.epoch.get(continuity) : void 0;
|
|
1539
|
+
return epoch;
|
|
1540
|
+
}
|
|
1541
|
+
|
|
1542
|
+
// internal/src/transaction/index.ts
|
|
1543
|
+
var TRANSACTION_PHASES = [`idle`, `building`, `applying`];
|
|
1544
|
+
|
|
1545
|
+
// internal/src/store/store.ts
|
|
1546
|
+
var Store = class {
|
|
1547
|
+
constructor(config, store = null) {
|
|
1548
|
+
this.parent = null;
|
|
1549
|
+
this.child = null;
|
|
1550
|
+
this.valueMap = /* @__PURE__ */ new Map();
|
|
1551
|
+
this.atoms = /* @__PURE__ */ new Map();
|
|
1552
|
+
this.selectors = /* @__PURE__ */ new Map();
|
|
1553
|
+
this.readonlySelectors = /* @__PURE__ */ new Map();
|
|
1554
|
+
this.atomsThatAreDefault = /* @__PURE__ */ new Set();
|
|
1555
|
+
this.selectorAtoms = new Junction({
|
|
1556
|
+
between: [`selectorKey`, `atomKey`],
|
|
1557
|
+
cardinality: `n:n`
|
|
1558
|
+
});
|
|
1559
|
+
this.selectorGraph = new Junction(
|
|
1560
|
+
{
|
|
1561
|
+
between: [`upstreamSelectorKey`, `downstreamSelectorKey`],
|
|
1562
|
+
cardinality: `n:n`
|
|
1563
|
+
},
|
|
1564
|
+
{
|
|
1565
|
+
makeContentKey: (...keys) => keys.sort().join(`:`)
|
|
1566
|
+
}
|
|
1567
|
+
);
|
|
1568
|
+
this.trackers = /* @__PURE__ */ new Map();
|
|
1569
|
+
this.families = /* @__PURE__ */ new Map();
|
|
1570
|
+
this.transactions = /* @__PURE__ */ new Map();
|
|
1571
|
+
this.transactionMeta = {
|
|
1572
|
+
epoch: /* @__PURE__ */ new Map(),
|
|
1573
|
+
actionContinuities: new Junction({
|
|
1574
|
+
between: [`continuity`, `action`],
|
|
1575
|
+
cardinality: `1:n`
|
|
1576
|
+
})
|
|
1577
|
+
};
|
|
1578
|
+
this.timelines = /* @__PURE__ */ new Map();
|
|
1579
|
+
this.timelineTopics = new Junction({
|
|
1580
|
+
between: [`timelineKey`, `topicKey`],
|
|
1581
|
+
cardinality: `1:n`
|
|
1582
|
+
});
|
|
1583
|
+
this.molecules = /* @__PURE__ */ new Map();
|
|
1584
|
+
this.moleculeFamilies = /* @__PURE__ */ new Map();
|
|
1585
|
+
this.moleculeInProgress = null;
|
|
1586
|
+
this.miscResources = /* @__PURE__ */ new Map();
|
|
1587
|
+
this.on = {
|
|
1588
|
+
atomCreation: new Subject(),
|
|
1589
|
+
atomDisposal: new Subject(),
|
|
1590
|
+
selectorCreation: new Subject(),
|
|
1591
|
+
selectorDisposal: new Subject(),
|
|
1592
|
+
timelineCreation: new Subject(),
|
|
1593
|
+
transactionCreation: new Subject(),
|
|
1594
|
+
transactionApplying: new StatefulSubject(
|
|
1595
|
+
null
|
|
1596
|
+
),
|
|
1597
|
+
operationClose: new Subject(),
|
|
1598
|
+
moleculeCreationStart: new Subject(),
|
|
1599
|
+
moleculeCreationDone: new Subject(),
|
|
1600
|
+
moleculeDisposal: new Subject()
|
|
1601
|
+
};
|
|
1602
|
+
this.operation = { open: false };
|
|
1603
|
+
this.config = {
|
|
1604
|
+
name: `IMPLICIT_STORE`,
|
|
1605
|
+
lifespan: `ephemeral`
|
|
1606
|
+
};
|
|
1607
|
+
this.loggers = [
|
|
1608
|
+
new AtomIOLogger(`warn`, (_, __, key) => !key.includes(`\u{1F441}\u200D\u{1F5E8}`))
|
|
1609
|
+
];
|
|
1610
|
+
this.logger = {
|
|
1611
|
+
error: (...messages) => {
|
|
1612
|
+
for (const logger of this.loggers) logger.error(...messages);
|
|
1613
|
+
},
|
|
1614
|
+
info: (...messages) => {
|
|
1615
|
+
for (const logger of this.loggers) logger.info(...messages);
|
|
1616
|
+
},
|
|
1617
|
+
warn: (...messages) => {
|
|
1618
|
+
for (const logger of this.loggers) logger.warn(...messages);
|
|
1619
|
+
}
|
|
1620
|
+
};
|
|
1621
|
+
if (store !== null) {
|
|
1622
|
+
this.valueMap = new Map(store == null ? void 0 : store.valueMap);
|
|
1623
|
+
this.operation = __spreadValues({}, store == null ? void 0 : store.operation);
|
|
1624
|
+
if (isRootStore(store)) {
|
|
1625
|
+
this.transactionMeta = {
|
|
1626
|
+
epoch: new Map(store == null ? void 0 : store.transactionMeta.epoch),
|
|
1627
|
+
actionContinuities: new Junction(
|
|
1628
|
+
store == null ? void 0 : store.transactionMeta.actionContinuities.toJSON()
|
|
1629
|
+
)
|
|
1630
|
+
};
|
|
1631
|
+
}
|
|
1632
|
+
this.config = __spreadValues(__spreadValues({}, store == null ? void 0 : store.config), config);
|
|
1633
|
+
for (const [, family] of store.families) {
|
|
1634
|
+
family.install(this);
|
|
1635
|
+
}
|
|
1636
|
+
const mutableHelpers = /* @__PURE__ */ new Set();
|
|
1637
|
+
for (const [, atom] of store.atoms) {
|
|
1638
|
+
if (mutableHelpers.has(atom.key)) {
|
|
1639
|
+
continue;
|
|
1667
1640
|
}
|
|
1641
|
+
atom.install(this);
|
|
1642
|
+
if (atom.type === `mutable_atom`) {
|
|
1643
|
+
const originalJsonToken = getJsonToken(atom, store);
|
|
1644
|
+
const originalUpdateToken = getUpdateToken(atom);
|
|
1645
|
+
mutableHelpers.add(originalJsonToken.key);
|
|
1646
|
+
mutableHelpers.add(originalUpdateToken.key);
|
|
1647
|
+
}
|
|
1648
|
+
}
|
|
1649
|
+
for (const [, selector] of store.readonlySelectors) {
|
|
1650
|
+
selector.install(this);
|
|
1651
|
+
}
|
|
1652
|
+
for (const [, selector] of store.selectors) {
|
|
1653
|
+
if (mutableHelpers.has(selector.key)) {
|
|
1654
|
+
continue;
|
|
1655
|
+
}
|
|
1656
|
+
selector.install(this);
|
|
1657
|
+
}
|
|
1658
|
+
for (const [, tx] of store.transactions) {
|
|
1659
|
+
tx.install(this);
|
|
1660
|
+
}
|
|
1661
|
+
for (const [, timeline] of store.timelines) {
|
|
1662
|
+
timeline.install(this);
|
|
1663
|
+
}
|
|
1664
|
+
}
|
|
1665
|
+
}
|
|
1666
|
+
};
|
|
1667
|
+
var IMPLICIT = {
|
|
1668
|
+
STORE_INTERNAL: void 0,
|
|
1669
|
+
get STORE() {
|
|
1670
|
+
var _a;
|
|
1671
|
+
return (_a = this.STORE_INTERNAL) != null ? _a : this.STORE_INTERNAL = new Store({
|
|
1672
|
+
name: `IMPLICIT_STORE`,
|
|
1673
|
+
lifespan: `ephemeral`
|
|
1674
|
+
});
|
|
1675
|
+
}
|
|
1676
|
+
};
|
|
1677
|
+
var clearStore = (store) => {
|
|
1678
|
+
const { config } = store;
|
|
1679
|
+
for (const disposable of store.miscResources.values()) {
|
|
1680
|
+
disposable[Symbol.dispose]();
|
|
1681
|
+
}
|
|
1682
|
+
Object.assign(store, new Store(config));
|
|
1683
|
+
store.config = config;
|
|
1684
|
+
};
|
|
1685
|
+
function withdraw(token, store) {
|
|
1686
|
+
let withdrawn;
|
|
1687
|
+
let target = store;
|
|
1688
|
+
while (target !== null) {
|
|
1689
|
+
switch (token.type) {
|
|
1690
|
+
case `atom`:
|
|
1691
|
+
case `mutable_atom`:
|
|
1692
|
+
withdrawn = target.atoms.get(token.key);
|
|
1693
|
+
break;
|
|
1694
|
+
case `selector`:
|
|
1695
|
+
withdrawn = target.selectors.get(token.key);
|
|
1696
|
+
break;
|
|
1697
|
+
case `readonly_selector`:
|
|
1698
|
+
withdrawn = target.readonlySelectors.get(token.key);
|
|
1699
|
+
break;
|
|
1700
|
+
case `atom_family`:
|
|
1701
|
+
case `mutable_atom_family`:
|
|
1702
|
+
case `selector_family`:
|
|
1703
|
+
case `readonly_selector_family`:
|
|
1704
|
+
withdrawn = target.families.get(token.key);
|
|
1705
|
+
break;
|
|
1706
|
+
case `timeline`:
|
|
1707
|
+
withdrawn = target.timelines.get(token.key);
|
|
1708
|
+
break;
|
|
1709
|
+
case `transaction`:
|
|
1710
|
+
withdrawn = target.transactions.get(token.key);
|
|
1668
1711
|
break;
|
|
1669
|
-
case `
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
store
|
|
1675
|
-
);
|
|
1676
|
-
family.subject.next({
|
|
1677
|
-
type: `state_disposal`,
|
|
1678
|
-
token: selectorToken
|
|
1679
|
-
});
|
|
1680
|
-
}
|
|
1712
|
+
case `molecule`:
|
|
1713
|
+
withdrawn = target.molecules.get(stringifyJson(token.key));
|
|
1714
|
+
break;
|
|
1715
|
+
case `molecule_family`:
|
|
1716
|
+
withdrawn = target.moleculeFamilies.get(token.key);
|
|
1681
1717
|
break;
|
|
1682
1718
|
}
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
const downstreamTokens = target.selectorGraph.getRelationEntries({ upstreamSelectorKey: key }).filter(([_, { source }]) => source === key).map(
|
|
1686
|
-
([downstreamSelectorKey]) => {
|
|
1687
|
-
var _a2;
|
|
1688
|
-
return (_a2 = target.selectors.get(downstreamSelectorKey)) != null ? _a2 : target.readonlySelectors.get(downstreamSelectorKey);
|
|
1689
|
-
}
|
|
1690
|
-
);
|
|
1691
|
-
for (const downstreamToken of downstreamTokens) {
|
|
1692
|
-
if (downstreamToken) {
|
|
1693
|
-
disposeSelector(downstreamToken, store);
|
|
1694
|
-
}
|
|
1695
|
-
}
|
|
1696
|
-
target.selectorGraph.delete(key);
|
|
1697
|
-
store.logger.info(`\u{1F525}`, selectorToken.type, key, `deleted`);
|
|
1698
|
-
if (isChildStore(target) && target.transactionMeta.phase === `building`) {
|
|
1699
|
-
target.transactionMeta.update.updates.push({
|
|
1700
|
-
type: `state_disposal`,
|
|
1701
|
-
token: selectorToken
|
|
1702
|
-
});
|
|
1703
|
-
} else {
|
|
1704
|
-
store.on.selectorDisposal.next(selectorToken);
|
|
1719
|
+
if (withdrawn) {
|
|
1720
|
+
return withdrawn;
|
|
1705
1721
|
}
|
|
1722
|
+
target = target.child;
|
|
1706
1723
|
}
|
|
1724
|
+
throw new NotFoundError(token, store);
|
|
1707
1725
|
}
|
|
1708
1726
|
|
|
1709
1727
|
// internal/src/subscribe/recall-state.ts
|
|
@@ -1900,7 +1918,7 @@ var Tracker = class {
|
|
|
1900
1918
|
subscribeToState(
|
|
1901
1919
|
latestUpdateState,
|
|
1902
1920
|
({ newValue, oldValue }) => {
|
|
1903
|
-
const timelineId = target.
|
|
1921
|
+
const timelineId = target.timelineTopics.getRelatedKey(
|
|
1904
1922
|
latestUpdateState.key
|
|
1905
1923
|
);
|
|
1906
1924
|
if (timelineId) {
|
|
@@ -2351,6 +2369,10 @@ function disposeAtom(atomToken, store) {
|
|
|
2351
2369
|
token: atomToken,
|
|
2352
2370
|
value: lastValue
|
|
2353
2371
|
});
|
|
2372
|
+
const molecule = target.molecules.get(atom.family.subKey);
|
|
2373
|
+
if (molecule) {
|
|
2374
|
+
molecule.tokens.delete(key);
|
|
2375
|
+
}
|
|
2354
2376
|
target.atoms.delete(key);
|
|
2355
2377
|
target.valueMap.delete(key);
|
|
2356
2378
|
const selectorKeys = target.selectorAtoms.getRelatedKeys(key);
|
|
@@ -2364,7 +2386,7 @@ function disposeAtom(atomToken, store) {
|
|
|
2364
2386
|
}
|
|
2365
2387
|
target.selectorAtoms.delete(key);
|
|
2366
2388
|
target.atomsThatAreDefault.delete(key);
|
|
2367
|
-
target.
|
|
2389
|
+
target.timelineTopics.delete(key);
|
|
2368
2390
|
if (atomToken.type === `mutable_atom`) {
|
|
2369
2391
|
const updateToken = getUpdateToken(atomToken);
|
|
2370
2392
|
disposeAtom(updateToken, store);
|
|
@@ -2381,26 +2403,123 @@ function disposeAtom(atomToken, store) {
|
|
|
2381
2403
|
}
|
|
2382
2404
|
}
|
|
2383
2405
|
}
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
|
|
2406
|
+
function createTimeline(options, store, data) {
|
|
2407
|
+
var _a;
|
|
2408
|
+
const tl = __spreadProps(__spreadValues({
|
|
2409
|
+
type: `timeline`,
|
|
2410
|
+
key: options.key,
|
|
2411
|
+
at: 0,
|
|
2412
|
+
timeTraveling: null,
|
|
2413
|
+
selectorTime: null,
|
|
2414
|
+
transactionKey: null
|
|
2415
|
+
}, data), {
|
|
2416
|
+
history: (_a = data == null ? void 0 : data.history.map((update) => __spreadValues({}, update))) != null ? _a : [],
|
|
2417
|
+
install: (s) => createTimeline(options, s, tl),
|
|
2418
|
+
subject: new Subject(),
|
|
2419
|
+
subscriptions: /* @__PURE__ */ new Map()
|
|
2420
|
+
});
|
|
2421
|
+
if (options.shouldCapture) {
|
|
2422
|
+
tl.shouldCapture = options.shouldCapture;
|
|
2423
|
+
}
|
|
2424
|
+
const timelineKey = options.key;
|
|
2425
|
+
const target = newest(store);
|
|
2426
|
+
for (const initialTopic of options.scope) {
|
|
2427
|
+
switch (initialTopic.type) {
|
|
2428
|
+
case `atom`:
|
|
2429
|
+
case `mutable_atom`:
|
|
2430
|
+
{
|
|
2431
|
+
const atomToken = initialTopic;
|
|
2432
|
+
const atomKey = atomToken.key;
|
|
2433
|
+
let existingTimelineKey = target.timelineTopics.getRelatedKey(atomKey);
|
|
2434
|
+
if (`family` in atomToken) {
|
|
2435
|
+
const familyKey = atomToken.family.key;
|
|
2436
|
+
existingTimelineKey = target.timelineTopics.getRelatedKey(familyKey);
|
|
2437
|
+
if (existingTimelineKey) {
|
|
2438
|
+
store.logger.error(
|
|
2439
|
+
`\u274C`,
|
|
2440
|
+
`timeline`,
|
|
2441
|
+
options.key,
|
|
2442
|
+
`Failed to add atom "${atomKey}" because its family "${familyKey}" already belongs to timeline "${existingTimelineKey}"`
|
|
2443
|
+
);
|
|
2444
|
+
continue;
|
|
2445
|
+
}
|
|
2446
|
+
}
|
|
2447
|
+
if (existingTimelineKey) {
|
|
2448
|
+
store.logger.error(
|
|
2449
|
+
`\u274C`,
|
|
2450
|
+
`timeline`,
|
|
2451
|
+
options.key,
|
|
2452
|
+
`Failed to add atom "${atomKey}" because it already belongs to timeline "${existingTimelineKey}"`
|
|
2453
|
+
);
|
|
2454
|
+
continue;
|
|
2455
|
+
}
|
|
2456
|
+
addAtomToTimeline(atomToken, tl, store);
|
|
2457
|
+
}
|
|
2458
|
+
break;
|
|
2459
|
+
case `atom_family`:
|
|
2460
|
+
case `mutable_atom_family`:
|
|
2461
|
+
{
|
|
2462
|
+
const familyToken = initialTopic;
|
|
2463
|
+
const familyKey = familyToken.key;
|
|
2464
|
+
const existingTimelineKey = target.timelineTopics.getRelatedKey(familyKey);
|
|
2465
|
+
if (existingTimelineKey) {
|
|
2466
|
+
store.logger.error(
|
|
2467
|
+
`\u274C`,
|
|
2468
|
+
`timeline`,
|
|
2469
|
+
options.key,
|
|
2470
|
+
`Failed to add atom family "${familyKey}" because it already belongs to timeline "${existingTimelineKey}"`
|
|
2471
|
+
);
|
|
2472
|
+
continue;
|
|
2473
|
+
}
|
|
2474
|
+
addAtomFamilyToTimeline(familyToken, tl, store);
|
|
2475
|
+
}
|
|
2476
|
+
break;
|
|
2477
|
+
case `molecule_family`:
|
|
2478
|
+
{
|
|
2479
|
+
const familyToken = initialTopic;
|
|
2480
|
+
const familyKey = familyToken.key;
|
|
2481
|
+
const existingTimelineKey = target.timelineTopics.getRelatedKey(familyKey);
|
|
2482
|
+
if (existingTimelineKey) {
|
|
2483
|
+
store.logger.error(
|
|
2484
|
+
`\u274C`,
|
|
2485
|
+
`timeline`,
|
|
2486
|
+
options.key,
|
|
2487
|
+
`Failed to add molecule family "${familyKey}" because it already belongs to timeline "${existingTimelineKey}"`
|
|
2488
|
+
);
|
|
2489
|
+
continue;
|
|
2490
|
+
}
|
|
2491
|
+
addMoleculeFamilyToTimeline(familyToken, tl, store);
|
|
2492
|
+
}
|
|
2493
|
+
break;
|
|
2494
|
+
}
|
|
2495
|
+
}
|
|
2496
|
+
store.timelines.set(options.key, tl);
|
|
2497
|
+
const token = {
|
|
2498
|
+
key: timelineKey,
|
|
2499
|
+
type: `timeline`
|
|
2500
|
+
};
|
|
2501
|
+
store.on.timelineCreation.next(token);
|
|
2502
|
+
return token;
|
|
2503
|
+
}
|
|
2504
|
+
function addAtomToTimeline(atomToken, tl, store) {
|
|
2387
2505
|
let maybeAtom = withdraw(atomToken, store);
|
|
2388
2506
|
if (maybeAtom.type === `mutable_atom`) {
|
|
2389
2507
|
const updateToken = getUpdateToken(maybeAtom);
|
|
2390
2508
|
maybeAtom = withdraw(updateToken, store);
|
|
2391
2509
|
}
|
|
2392
2510
|
const atom = maybeAtom;
|
|
2393
|
-
store.
|
|
2511
|
+
store.timelineTopics.set(
|
|
2512
|
+
{ topicKey: atom.key, timelineKey: tl.key },
|
|
2513
|
+
{ topicType: `atom` }
|
|
2514
|
+
);
|
|
2394
2515
|
tl.subscriptions.set(
|
|
2395
2516
|
atom.key,
|
|
2396
2517
|
atom.subject.subscribe(`timeline`, (update) => {
|
|
2397
|
-
var _a, _b, _c, _d, _e
|
|
2518
|
+
var _a, _b, _c, _d, _e;
|
|
2398
2519
|
const target = newest(store);
|
|
2399
2520
|
const currentSelectorKey = store.operation.open && store.operation.token.type === `selector` ? store.operation.token.key : null;
|
|
2400
2521
|
const currentSelectorTime = store.operation.open && store.operation.token.type === `selector` ? store.operation.time : null;
|
|
2401
|
-
const
|
|
2402
|
-
const currentTransactionKey = (_a = transactionApplying.state) == null ? void 0 : _a.update.key;
|
|
2403
|
-
const currentTransactionInstanceId = (_b = transactionApplying.state) == null ? void 0 : _b.update.id;
|
|
2522
|
+
const txUpdateInProgress = (_a = target.on.transactionApplying.state) == null ? void 0 : _a.update;
|
|
2404
2523
|
store.logger.info(
|
|
2405
2524
|
`\u23F3`,
|
|
2406
2525
|
`timeline`,
|
|
@@ -2411,109 +2530,11 @@ var addAtomToTimeline = (atomToken, tl, store) => {
|
|
|
2411
2530
|
update.oldValue,
|
|
2412
2531
|
`->`,
|
|
2413
2532
|
update.newValue,
|
|
2414
|
-
|
|
2533
|
+
txUpdateInProgress ? `in transaction "${txUpdateInProgress.key}"` : currentSelectorKey ? `in selector "${currentSelectorKey}"` : ``
|
|
2415
2534
|
);
|
|
2416
2535
|
if (tl.timeTraveling === null) {
|
|
2417
|
-
if (
|
|
2418
|
-
|
|
2419
|
-
if (mostRecentUpdate === void 0) {
|
|
2420
|
-
throw new Error(
|
|
2421
|
-
`Timeline "${tl.key}" has a selectorTime, but no history. This is most likely a bug in AtomIO.`
|
|
2422
|
-
);
|
|
2423
|
-
}
|
|
2424
|
-
}
|
|
2425
|
-
if (currentTransactionKey) {
|
|
2426
|
-
const txToken = {
|
|
2427
|
-
key: currentTransactionKey,
|
|
2428
|
-
type: `transaction`
|
|
2429
|
-
};
|
|
2430
|
-
const currentTransaction = withdraw(txToken, store);
|
|
2431
|
-
if (tl.transactionKey !== currentTransactionKey) {
|
|
2432
|
-
if (tl.transactionKey) {
|
|
2433
|
-
store.logger.error(
|
|
2434
|
-
`\u{1F41E}`,
|
|
2435
|
-
`timeline`,
|
|
2436
|
-
tl.key,
|
|
2437
|
-
`unable to resolve transaction "${tl.transactionKey}. This is probably a bug in AtomIO.`
|
|
2438
|
-
);
|
|
2439
|
-
}
|
|
2440
|
-
tl.transactionKey = currentTransactionKey;
|
|
2441
|
-
const unsubscribe = currentTransaction.subject.subscribe(
|
|
2442
|
-
`timeline:${tl.key}`,
|
|
2443
|
-
(transactionUpdate) => {
|
|
2444
|
-
var _a2, _b2;
|
|
2445
|
-
unsubscribe();
|
|
2446
|
-
if (tl.timeTraveling === null && currentTransactionInstanceId) {
|
|
2447
|
-
if (tl.at !== tl.history.length) {
|
|
2448
|
-
tl.history.splice(tl.at);
|
|
2449
|
-
}
|
|
2450
|
-
const filterUpdates = (updates2) => updates2.filter((updateFromTx) => {
|
|
2451
|
-
var _a3, _b3;
|
|
2452
|
-
const newestStore = newest(store);
|
|
2453
|
-
if (`updates` in updateFromTx) {
|
|
2454
|
-
return true;
|
|
2455
|
-
}
|
|
2456
|
-
const atomOrFamilyKeys = newestStore.timelineAtoms.getRelatedKeys(tl.key);
|
|
2457
|
-
if (!atomOrFamilyKeys) {
|
|
2458
|
-
return false;
|
|
2459
|
-
}
|
|
2460
|
-
let key;
|
|
2461
|
-
let familyKey;
|
|
2462
|
-
switch (updateFromTx.type) {
|
|
2463
|
-
case `state_creation`:
|
|
2464
|
-
case `state_disposal`:
|
|
2465
|
-
key = updateFromTx.token.key;
|
|
2466
|
-
familyKey = (_a3 = updateFromTx.token.family) == null ? void 0 : _a3.key;
|
|
2467
|
-
break;
|
|
2468
|
-
case `molecule_creation`:
|
|
2469
|
-
case `molecule_disposal`:
|
|
2470
|
-
break;
|
|
2471
|
-
default:
|
|
2472
|
-
key = updateFromTx.key;
|
|
2473
|
-
familyKey = (_b3 = updateFromTx.family) == null ? void 0 : _b3.key;
|
|
2474
|
-
break;
|
|
2475
|
-
}
|
|
2476
|
-
if (key === void 0) {
|
|
2477
|
-
return false;
|
|
2478
|
-
}
|
|
2479
|
-
if (atomOrFamilyKeys.has(key)) {
|
|
2480
|
-
return true;
|
|
2481
|
-
}
|
|
2482
|
-
if (familyKey !== void 0) {
|
|
2483
|
-
return atomOrFamilyKeys.has(familyKey);
|
|
2484
|
-
}
|
|
2485
|
-
return false;
|
|
2486
|
-
}).map((updateFromTx) => {
|
|
2487
|
-
if (`updates` in updateFromTx) {
|
|
2488
|
-
return __spreadProps(__spreadValues({}, updateFromTx), {
|
|
2489
|
-
updates: filterUpdates(updateFromTx.updates)
|
|
2490
|
-
});
|
|
2491
|
-
}
|
|
2492
|
-
return updateFromTx;
|
|
2493
|
-
});
|
|
2494
|
-
const updates = filterUpdates(transactionUpdate.updates);
|
|
2495
|
-
const timelineTransactionUpdate = __spreadProps(__spreadValues({
|
|
2496
|
-
timestamp: Date.now()
|
|
2497
|
-
}, transactionUpdate), {
|
|
2498
|
-
updates
|
|
2499
|
-
});
|
|
2500
|
-
const willCapture = (_b2 = (_a2 = tl.shouldCapture) == null ? void 0 : _a2.call(tl, timelineTransactionUpdate, tl)) != null ? _b2 : true;
|
|
2501
|
-
if (willCapture) {
|
|
2502
|
-
tl.history.push(timelineTransactionUpdate);
|
|
2503
|
-
tl.at = tl.history.length;
|
|
2504
|
-
tl.subject.next(timelineTransactionUpdate);
|
|
2505
|
-
}
|
|
2506
|
-
}
|
|
2507
|
-
tl.transactionKey = null;
|
|
2508
|
-
store.logger.info(
|
|
2509
|
-
`\u231B`,
|
|
2510
|
-
`timeline`,
|
|
2511
|
-
tl.key,
|
|
2512
|
-
`got a transaction_update "${transactionUpdate.key}"`
|
|
2513
|
-
);
|
|
2514
|
-
}
|
|
2515
|
-
);
|
|
2516
|
-
}
|
|
2536
|
+
if (txUpdateInProgress) {
|
|
2537
|
+
joinTransaction(tl, txUpdateInProgress, store);
|
|
2517
2538
|
} else if (currentSelectorKey && currentSelectorTime) {
|
|
2518
2539
|
let latestUpdate = tl.history.at(-1);
|
|
2519
2540
|
if (currentSelectorTime !== tl.selectorTime) {
|
|
@@ -2556,7 +2577,7 @@ var addAtomToTimeline = (atomToken, tl, store) => {
|
|
|
2556
2577
|
}
|
|
2557
2578
|
}
|
|
2558
2579
|
if (latestUpdate) {
|
|
2559
|
-
const willCaptureSelectorUpdate = (
|
|
2580
|
+
const willCaptureSelectorUpdate = (_c = (_b = tl.shouldCapture) == null ? void 0 : _b.call(tl, latestUpdate, tl)) != null ? _c : true;
|
|
2560
2581
|
if (willCaptureSelectorUpdate) {
|
|
2561
2582
|
tl.subject.next(latestUpdate);
|
|
2562
2583
|
} else {
|
|
@@ -2580,7 +2601,7 @@ var addAtomToTimeline = (atomToken, tl, store) => {
|
|
|
2580
2601
|
if (atom.family) {
|
|
2581
2602
|
atomUpdate.family = atom.family;
|
|
2582
2603
|
}
|
|
2583
|
-
const willCapture = (
|
|
2604
|
+
const willCapture = (_e = (_d = tl.shouldCapture) == null ? void 0 : _d.call(tl, atomUpdate, tl)) != null ? _e : true;
|
|
2584
2605
|
store.logger.info(
|
|
2585
2606
|
`\u231B`,
|
|
2586
2607
|
`timeline`,
|
|
@@ -2596,181 +2617,207 @@ var addAtomToTimeline = (atomToken, tl, store) => {
|
|
|
2596
2617
|
}
|
|
2597
2618
|
})
|
|
2598
2619
|
);
|
|
2599
|
-
}
|
|
2600
|
-
function
|
|
2601
|
-
var _a
|
|
2602
|
-
const
|
|
2603
|
-
|
|
2604
|
-
key:
|
|
2605
|
-
|
|
2606
|
-
|
|
2607
|
-
|
|
2608
|
-
|
|
2609
|
-
|
|
2610
|
-
|
|
2611
|
-
|
|
2612
|
-
|
|
2613
|
-
|
|
2614
|
-
|
|
2615
|
-
|
|
2616
|
-
|
|
2620
|
+
}
|
|
2621
|
+
function addAtomFamilyToTimeline(atomFamilyToken, tl, store) {
|
|
2622
|
+
var _a;
|
|
2623
|
+
const family = withdraw(atomFamilyToken, store);
|
|
2624
|
+
store.timelineTopics.set(
|
|
2625
|
+
{ topicKey: family.key, timelineKey: tl.key },
|
|
2626
|
+
{ topicType: `atom_family` }
|
|
2627
|
+
);
|
|
2628
|
+
tl.subscriptions.set(
|
|
2629
|
+
family.key,
|
|
2630
|
+
family.subject.subscribe(`timeline`, (creationOrDisposal) => {
|
|
2631
|
+
handleStateLifecycleEvent(creationOrDisposal, tl, store);
|
|
2632
|
+
})
|
|
2633
|
+
);
|
|
2634
|
+
for (const atom of store.atoms.values()) {
|
|
2635
|
+
if (((_a = atom.family) == null ? void 0 : _a.key) === family.key) {
|
|
2636
|
+
addAtomToTimeline(atom, tl, store);
|
|
2637
|
+
}
|
|
2617
2638
|
}
|
|
2618
|
-
|
|
2619
|
-
|
|
2620
|
-
|
|
2621
|
-
|
|
2622
|
-
|
|
2623
|
-
|
|
2624
|
-
|
|
2625
|
-
|
|
2626
|
-
|
|
2627
|
-
|
|
2628
|
-
|
|
2629
|
-
|
|
2630
|
-
|
|
2631
|
-
|
|
2632
|
-
|
|
2633
|
-
|
|
2634
|
-
|
|
2635
|
-
|
|
2639
|
+
}
|
|
2640
|
+
function addMoleculeFamilyToTimeline(familyToken, tl, store) {
|
|
2641
|
+
store.timelineTopics.set(
|
|
2642
|
+
{ topicKey: familyToken.key, timelineKey: tl.key },
|
|
2643
|
+
{ topicType: `molecule_family` }
|
|
2644
|
+
);
|
|
2645
|
+
const family = store.moleculeFamilies.get(familyToken.key);
|
|
2646
|
+
if (family) {
|
|
2647
|
+
tl.subscriptions.set(
|
|
2648
|
+
familyToken.key,
|
|
2649
|
+
family.subject.subscribe(`timeline:${tl.key}`, (creationOrDisposal) => {
|
|
2650
|
+
var _a, _b, _c, _d;
|
|
2651
|
+
store.logger.info(
|
|
2652
|
+
`\u{1F41E}`,
|
|
2653
|
+
`timeline`,
|
|
2654
|
+
tl.key,
|
|
2655
|
+
`got a molecule creation or disposal`,
|
|
2656
|
+
creationOrDisposal
|
|
2657
|
+
);
|
|
2658
|
+
switch (creationOrDisposal.type) {
|
|
2659
|
+
case `molecule_creation`:
|
|
2660
|
+
{
|
|
2661
|
+
store.timelineTopics.set(
|
|
2662
|
+
{
|
|
2663
|
+
topicKey: creationOrDisposal.token.key,
|
|
2664
|
+
timelineKey: tl.key
|
|
2665
|
+
},
|
|
2666
|
+
{ topicType: `molecule` }
|
|
2667
|
+
);
|
|
2668
|
+
const txUpdateInProgress = (_a = newest(store).on.transactionApplying.state) == null ? void 0 : _a.update;
|
|
2669
|
+
if (txUpdateInProgress) {
|
|
2670
|
+
joinTransaction(tl, txUpdateInProgress, store);
|
|
2671
|
+
} else if (tl.timeTraveling === null) {
|
|
2672
|
+
const event = Object.assign(creationOrDisposal, {
|
|
2673
|
+
timestamp: Date.now()
|
|
2674
|
+
});
|
|
2675
|
+
tl.history.push(event);
|
|
2676
|
+
tl.at = tl.history.length;
|
|
2677
|
+
tl.subject.next(event);
|
|
2636
2678
|
}
|
|
2637
|
-
|
|
2638
|
-
|
|
2639
|
-
|
|
2640
|
-
|
|
2641
|
-
|
|
2642
|
-
|
|
2643
|
-
|
|
2644
|
-
|
|
2645
|
-
|
|
2646
|
-
|
|
2647
|
-
|
|
2648
|
-
|
|
2649
|
-
|
|
2650
|
-
|
|
2651
|
-
|
|
2652
|
-
|
|
2653
|
-
|
|
2654
|
-
}
|
|
2655
|
-
if (`family` in atom) {
|
|
2656
|
-
const familyTimelineKey = target.timelineAtoms.getRelatedKey(
|
|
2657
|
-
atom.family.key
|
|
2658
|
-
);
|
|
2659
|
-
if (familyTimelineKey) {
|
|
2660
|
-
store.logger.error(
|
|
2661
|
-
`\u274C`,
|
|
2662
|
-
`timeline`,
|
|
2663
|
-
options.key,
|
|
2664
|
-
`Failed to add atom "${atom.key}" because its family "${atom.family.key}" already belongs to timeline "${familyTimelineKey}"`
|
|
2679
|
+
const molecule = withdraw(creationOrDisposal.token, store);
|
|
2680
|
+
for (const token of molecule.tokens.values()) {
|
|
2681
|
+
switch (token.type) {
|
|
2682
|
+
case `atom`:
|
|
2683
|
+
case `mutable_atom`:
|
|
2684
|
+
addAtomToTimeline(token, tl, store);
|
|
2685
|
+
break;
|
|
2686
|
+
}
|
|
2687
|
+
}
|
|
2688
|
+
tl.subscriptions.set(
|
|
2689
|
+
molecule.key,
|
|
2690
|
+
molecule.subject.subscribe(
|
|
2691
|
+
`timeline:${tl.key}`,
|
|
2692
|
+
(stateCreationOrDisposal) => {
|
|
2693
|
+
handleStateLifecycleEvent(stateCreationOrDisposal, tl, store);
|
|
2694
|
+
}
|
|
2695
|
+
)
|
|
2665
2696
|
);
|
|
2666
|
-
continue;
|
|
2667
2697
|
}
|
|
2698
|
+
break;
|
|
2699
|
+
case `molecule_disposal`:
|
|
2700
|
+
{
|
|
2701
|
+
const txUpdateInProgress = (_b = newest(store).on.transactionApplying.state) == null ? void 0 : _b.update;
|
|
2702
|
+
if (txUpdateInProgress) {
|
|
2703
|
+
joinTransaction(tl, txUpdateInProgress, store);
|
|
2704
|
+
} else if (tl.timeTraveling === null) {
|
|
2705
|
+
const event = Object.assign(creationOrDisposal, {
|
|
2706
|
+
timestamp: Date.now()
|
|
2707
|
+
});
|
|
2708
|
+
tl.history.push(event);
|
|
2709
|
+
tl.at = tl.history.length;
|
|
2710
|
+
tl.subject.next(event);
|
|
2711
|
+
}
|
|
2712
|
+
const moleculeKey = creationOrDisposal.token.key;
|
|
2713
|
+
(_c = tl.subscriptions.get(moleculeKey)) == null ? void 0 : _c();
|
|
2714
|
+
tl.subscriptions.delete(moleculeKey);
|
|
2715
|
+
for (const [familyKey] of creationOrDisposal.values) {
|
|
2716
|
+
const stateKey = `${familyKey}(${stringifyJson(moleculeKey)})`;
|
|
2717
|
+
(_d = tl.subscriptions.get(stateKey)) == null ? void 0 : _d();
|
|
2718
|
+
tl.subscriptions.delete(stateKey);
|
|
2719
|
+
store.timelineTopics.delete(stateKey);
|
|
2720
|
+
}
|
|
2721
|
+
}
|
|
2722
|
+
break;
|
|
2723
|
+
}
|
|
2724
|
+
})
|
|
2725
|
+
);
|
|
2726
|
+
}
|
|
2727
|
+
}
|
|
2728
|
+
function joinTransaction(tl, txUpdateInProgress, store) {
|
|
2729
|
+
const currentTxKey = txUpdateInProgress.key;
|
|
2730
|
+
const currentTxInstanceId = txUpdateInProgress.id;
|
|
2731
|
+
const currentTxToken = {
|
|
2732
|
+
key: currentTxKey,
|
|
2733
|
+
type: `transaction`
|
|
2734
|
+
};
|
|
2735
|
+
const currentTransaction = withdraw(currentTxToken, store);
|
|
2736
|
+
if (currentTxKey && tl.transactionKey === null) {
|
|
2737
|
+
tl.transactionKey = currentTxKey;
|
|
2738
|
+
const unsubscribe = currentTransaction.subject.subscribe(
|
|
2739
|
+
`timeline:${tl.key}`,
|
|
2740
|
+
(transactionUpdate) => {
|
|
2741
|
+
var _a, _b;
|
|
2742
|
+
unsubscribe();
|
|
2743
|
+
tl.transactionKey = null;
|
|
2744
|
+
if (tl.timeTraveling === null && currentTxInstanceId) {
|
|
2745
|
+
if (tl.at !== tl.history.length) {
|
|
2746
|
+
tl.history.splice(tl.at);
|
|
2668
2747
|
}
|
|
2669
|
-
const
|
|
2670
|
-
|
|
2671
|
-
|
|
2672
|
-
|
|
2673
|
-
|
|
2674
|
-
|
|
2675
|
-
|
|
2676
|
-
|
|
2677
|
-
|
|
2748
|
+
const timelineTopics = store.timelineTopics.getRelatedKeys(tl.key);
|
|
2749
|
+
const updates = filterTransactionUpdates(
|
|
2750
|
+
transactionUpdate.updates,
|
|
2751
|
+
timelineTopics
|
|
2752
|
+
);
|
|
2753
|
+
const timelineTransactionUpdate = __spreadProps(__spreadValues({
|
|
2754
|
+
timestamp: Date.now()
|
|
2755
|
+
}, transactionUpdate), {
|
|
2756
|
+
updates
|
|
2757
|
+
});
|
|
2758
|
+
const willCapture = (_b = (_a = tl.shouldCapture) == null ? void 0 : _a.call(tl, timelineTransactionUpdate, tl)) != null ? _b : true;
|
|
2759
|
+
if (willCapture) {
|
|
2760
|
+
tl.history.push(timelineTransactionUpdate);
|
|
2761
|
+
tl.at = tl.history.length;
|
|
2762
|
+
tl.subject.next(timelineTransactionUpdate);
|
|
2678
2763
|
}
|
|
2679
|
-
addAtomToTimeline(atom, tl, store);
|
|
2680
2764
|
}
|
|
2765
|
+
}
|
|
2766
|
+
);
|
|
2767
|
+
}
|
|
2768
|
+
}
|
|
2769
|
+
function filterTransactionUpdates(updates, timelineTopics) {
|
|
2770
|
+
return updates.filter((updateFromTx) => {
|
|
2771
|
+
if (updateFromTx.type === `transaction_update`) {
|
|
2772
|
+
return true;
|
|
2773
|
+
}
|
|
2774
|
+
let key;
|
|
2775
|
+
switch (updateFromTx.type) {
|
|
2776
|
+
case `state_creation`:
|
|
2777
|
+
case `state_disposal`:
|
|
2778
|
+
case `molecule_creation`:
|
|
2779
|
+
case `molecule_disposal`:
|
|
2780
|
+
key = updateFromTx.token.key;
|
|
2681
2781
|
break;
|
|
2682
|
-
|
|
2683
|
-
|
|
2684
|
-
const family = store.moleculeFamilies.get(tokenOrFamily.key);
|
|
2685
|
-
if (family) {
|
|
2686
|
-
tl.subscriptions.set(
|
|
2687
|
-
tokenOrFamily.key,
|
|
2688
|
-
family.subject.subscribe(
|
|
2689
|
-
`timeline:${options.key}`,
|
|
2690
|
-
(creationOrDisposal) => {
|
|
2691
|
-
var _a2, _b2;
|
|
2692
|
-
switch (creationOrDisposal.type) {
|
|
2693
|
-
case `molecule_creation`:
|
|
2694
|
-
{
|
|
2695
|
-
const molecule = store.molecules.get(
|
|
2696
|
-
stringifyJson(creationOrDisposal.token.key)
|
|
2697
|
-
);
|
|
2698
|
-
if (molecule) {
|
|
2699
|
-
const event = Object.assign(creationOrDisposal, {
|
|
2700
|
-
timestamp: Date.now()
|
|
2701
|
-
});
|
|
2702
|
-
tl.history.push(event);
|
|
2703
|
-
tl.at = tl.history.length;
|
|
2704
|
-
tl.subject.next(event);
|
|
2705
|
-
for (const token2 of molecule.tokens.values()) {
|
|
2706
|
-
switch (token2.type) {
|
|
2707
|
-
case `atom`:
|
|
2708
|
-
case `mutable_atom`:
|
|
2709
|
-
addAtomToTimeline(token2, tl, store);
|
|
2710
|
-
break;
|
|
2711
|
-
}
|
|
2712
|
-
}
|
|
2713
|
-
tl.subscriptions.set(
|
|
2714
|
-
molecule.key,
|
|
2715
|
-
molecule.subject.subscribe(
|
|
2716
|
-
`timeline:${options.key}`,
|
|
2717
|
-
(stateCreationOrDisposal) => {
|
|
2718
|
-
handleStateLifecycleEvent(
|
|
2719
|
-
stateCreationOrDisposal,
|
|
2720
|
-
tl,
|
|
2721
|
-
store
|
|
2722
|
-
);
|
|
2723
|
-
}
|
|
2724
|
-
)
|
|
2725
|
-
);
|
|
2726
|
-
}
|
|
2727
|
-
}
|
|
2728
|
-
break;
|
|
2729
|
-
case `molecule_disposal`:
|
|
2730
|
-
(_a2 = tl.subscriptions.get(creationOrDisposal.token.key)) == null ? void 0 : _a2();
|
|
2731
|
-
tl.subscriptions.delete(creationOrDisposal.token.key);
|
|
2732
|
-
for (const familyKey of creationOrDisposal.familyKeys) {
|
|
2733
|
-
const stateKey = `${familyKey}(${stringifyJson(
|
|
2734
|
-
creationOrDisposal.token.key
|
|
2735
|
-
)})`;
|
|
2736
|
-
(_b2 = tl.subscriptions.get(stateKey)) == null ? void 0 : _b2();
|
|
2737
|
-
tl.subscriptions.delete(stateKey);
|
|
2738
|
-
}
|
|
2739
|
-
break;
|
|
2740
|
-
}
|
|
2741
|
-
}
|
|
2742
|
-
)
|
|
2743
|
-
);
|
|
2744
|
-
}
|
|
2745
|
-
}
|
|
2782
|
+
default:
|
|
2783
|
+
key = updateFromTx.key;
|
|
2746
2784
|
break;
|
|
2747
2785
|
}
|
|
2748
|
-
|
|
2749
|
-
|
|
2750
|
-
|
|
2751
|
-
|
|
2752
|
-
|
|
2753
|
-
|
|
2754
|
-
|
|
2755
|
-
|
|
2786
|
+
return timelineTopics.has(key);
|
|
2787
|
+
}).map((updateFromTx) => {
|
|
2788
|
+
if (`updates` in updateFromTx) {
|
|
2789
|
+
return __spreadProps(__spreadValues({}, updateFromTx), {
|
|
2790
|
+
updates: filterTransactionUpdates(
|
|
2791
|
+
updateFromTx.updates,
|
|
2792
|
+
timelineTopics
|
|
2793
|
+
)
|
|
2794
|
+
});
|
|
2795
|
+
}
|
|
2796
|
+
return updateFromTx;
|
|
2797
|
+
});
|
|
2756
2798
|
}
|
|
2757
2799
|
function handleStateLifecycleEvent(event, tl, store) {
|
|
2758
|
-
var _a;
|
|
2800
|
+
var _a, _b;
|
|
2759
2801
|
const timestamp = Date.now();
|
|
2760
2802
|
const timelineEvent = Object.assign(event, {
|
|
2761
2803
|
timestamp
|
|
2762
2804
|
});
|
|
2763
2805
|
if (!tl.timeTraveling) {
|
|
2764
|
-
|
|
2765
|
-
|
|
2766
|
-
|
|
2806
|
+
const txUpdateInProgress = (_a = newest(store).on.transactionApplying.state) == null ? void 0 : _a.update;
|
|
2807
|
+
if (txUpdateInProgress) {
|
|
2808
|
+
joinTransaction(tl, txUpdateInProgress, store);
|
|
2809
|
+
} else {
|
|
2810
|
+
tl.history.push(timelineEvent);
|
|
2811
|
+
tl.at = tl.history.length;
|
|
2812
|
+
tl.subject.next(timelineEvent);
|
|
2813
|
+
}
|
|
2767
2814
|
}
|
|
2768
2815
|
switch (event.type) {
|
|
2769
2816
|
case `state_creation`:
|
|
2770
2817
|
addAtomToTimeline(event.token, tl, store);
|
|
2771
2818
|
break;
|
|
2772
2819
|
case `state_disposal`:
|
|
2773
|
-
(
|
|
2820
|
+
(_b = tl.subscriptions.get(event.token.key)) == null ? void 0 : _b();
|
|
2774
2821
|
tl.subscriptions.delete(event.token.key);
|
|
2775
2822
|
break;
|
|
2776
2823
|
}
|
|
@@ -2852,4 +2899,4 @@ var timeTravel = (action, token, store) => {
|
|
|
2852
2899
|
);
|
|
2853
2900
|
};
|
|
2854
2901
|
|
|
2855
|
-
export { FamilyTracker, Future, IMPLICIT, LazyMap, Molecule, NotFoundError, StatefulSubject, Store, Subject, TRANSACTION_PHASES, Tracker, abortTransaction, actUponStore,
|
|
2902
|
+
export { FamilyTracker, Future, IMPLICIT, LazyMap, Molecule, NotFoundError, StatefulSubject, Store, Subject, TRANSACTION_PHASES, Tracker, abortTransaction, actUponStore, applyTransaction, arbitrary, assignTransactionToContinuity, become, buildTransaction, cacheValue, clearStore, closeOperation, createAtomFamily, createMoleculeFamily, createMutableAtom, createMutableAtomFamily, createReadonlySelector, createReadonlySelectorFamily, createRegularAtom, createRegularAtomFamily, createSelectorFamily, createStandaloneAtom, createStandaloneSelector, createTimeline, createTransaction, createWritableSelector, deposit, disposeAtom, disposeFromStore, disposeMolecule, disposeSelector, evictCachedValue, findInStore, getContinuityKey, getEnvironmentData, getEpochNumberOfAction, getEpochNumberOfContinuity, getFromStore, getJsonFamily, getJsonToken, getSelectorDependencyKeys, getUpdateToken, growMoleculeInStore, ingestAtomUpdate, ingestCreationEvent, ingestDisposalEvent, ingestMoleculeCreationEvent, ingestMoleculeDisposalEvent, ingestSelectorUpdate, ingestTransactionUpdate, initFamilyMemberInStore, isAtomDefault, isAtomKey, isChildStore, isDone, isMutable, isReadonlySelectorKey, isRootStore, isSelectorKey, isStateKey, isTransceiver, makeMoleculeInStore, markAtomAsDefault, markAtomAsNotDefault, markDone, newest, openOperation, readCachedValue, readOrComputeValue, registerSelector, seekInStore, setAtomOrSelector, setEpochNumberOfAction, setEpochNumberOfContinuity, setIntoStore, subscribeToRootAtoms, subscribeToState, subscribeToTimeline, subscribeToTransaction, timeTravel, traceAllSelectorAtoms, traceSelectorAtoms, updateSelectorAtoms, withdraw };
|