atom.io 0.24.5 → 0.24.7
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 +1439 -1382
- package/internal/dist/index.d.ts +10 -9
- package/internal/dist/index.js +1440 -1382
- 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 +15 -4
- 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/build-transaction.ts +2 -1
- package/package.json +4 -4
- package/src/transaction.ts +1 -1
- package/internal/src/timeline/add-atom-to-timeline.ts +0 -265
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,45 +450,44 @@ 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
|
|
772
|
-
}
|
|
773
|
-
|
|
774
|
-
// internal/src/get-environment-data.ts
|
|
775
|
-
function getEnvironmentData(store) {
|
|
776
|
-
return {
|
|
777
|
-
store
|
|
778
|
-
};
|
|
490
|
+
return createRegularAtomFamily(options, store);
|
|
779
491
|
}
|
|
780
492
|
|
|
781
493
|
// internal/src/get-state/get-from-store.ts
|
|
@@ -791,520 +503,427 @@ function getFromStore(token, store) {
|
|
|
791
503
|
const state = withdraw(token, store);
|
|
792
504
|
return readOrComputeValue(state, store);
|
|
793
505
|
}
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
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
|
-
}
|
|
506
|
+
|
|
507
|
+
// internal/src/keys.ts
|
|
508
|
+
var isAtomKey = (key, store) => newest(store).atoms.has(key);
|
|
509
|
+
var isSelectorKey = (key, store) => newest(store).selectors.has(key);
|
|
510
|
+
var isReadonlySelectorKey = (key, store) => newest(store).readonlySelectors.has(key);
|
|
511
|
+
var isStateKey = (key, store) => isAtomKey(key, store) || isSelectorKey(key, store) || isReadonlySelectorKey(key, store);
|
|
512
|
+
|
|
513
|
+
// internal/src/selector/get-selector-dependency-keys.ts
|
|
514
|
+
var getSelectorDependencyKeys = (key, store) => {
|
|
515
|
+
const sources = newest(store).selectorGraph.getRelationEntries({ downstreamSelectorKey: key }).filter(([_, { source }]) => source !== key).map(([_, { source }]) => source).filter((source) => isStateKey(source, store));
|
|
516
|
+
return sources;
|
|
817
517
|
};
|
|
818
518
|
|
|
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) {
|
|
519
|
+
// internal/src/selector/trace-selector-atoms.ts
|
|
520
|
+
var traceSelectorAtoms = (selectorKey, directDependencyKey, store) => {
|
|
521
|
+
const rootKeys = [];
|
|
522
|
+
const indirectDependencyKeys = getSelectorDependencyKeys(
|
|
523
|
+
directDependencyKey,
|
|
524
|
+
store
|
|
525
|
+
);
|
|
526
|
+
let depth = 0;
|
|
527
|
+
while (indirectDependencyKeys.length > 0) {
|
|
528
|
+
const indirectDependencyKey = indirectDependencyKeys.shift();
|
|
529
|
+
++depth;
|
|
530
|
+
if (depth > 99999) {
|
|
835
531
|
throw new Error(
|
|
836
|
-
`
|
|
532
|
+
`Maximum selector dependency depth exceeded (> 99999) in selector "${selectorKey}". This is likely due to a circular dependency.`
|
|
837
533
|
);
|
|
838
534
|
}
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
535
|
+
if (!isAtomKey(indirectDependencyKey, store)) {
|
|
536
|
+
indirectDependencyKeys.push(
|
|
537
|
+
...getSelectorDependencyKeys(indirectDependencyKey, store)
|
|
538
|
+
);
|
|
539
|
+
} else if (!rootKeys.includes(indirectDependencyKey)) {
|
|
540
|
+
rootKeys.push(indirectDependencyKey);
|
|
541
|
+
}
|
|
846
542
|
}
|
|
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
|
-
|
|
543
|
+
return rootKeys;
|
|
544
|
+
};
|
|
545
|
+
var traceAllSelectorAtoms = (selector, store) => {
|
|
546
|
+
const selectorKey = selector.key;
|
|
547
|
+
const directDependencyKeys = getSelectorDependencyKeys(selectorKey, store);
|
|
548
|
+
return directDependencyKeys.flatMap(
|
|
549
|
+
(depKey) => isAtomKey(depKey, store) ? depKey : traceSelectorAtoms(selectorKey, depKey, store)
|
|
550
|
+
);
|
|
551
|
+
};
|
|
552
|
+
|
|
553
|
+
// internal/src/selector/update-selector-atoms.ts
|
|
554
|
+
var updateSelectorAtoms = (selectorKey, dependency, store) => {
|
|
555
|
+
const target = newest(store);
|
|
556
|
+
if (dependency.type === `atom` || dependency.type === `mutable_atom`) {
|
|
557
|
+
target.selectorAtoms.set({
|
|
558
|
+
selectorKey,
|
|
559
|
+
atomKey: dependency.key
|
|
560
|
+
});
|
|
561
|
+
store.logger.info(
|
|
562
|
+
`\u{1F50D}`,
|
|
563
|
+
`selector`,
|
|
564
|
+
selectorKey,
|
|
565
|
+
`discovers root atom "${dependency.key}"`
|
|
566
|
+
);
|
|
567
|
+
} else {
|
|
568
|
+
const rootKeys = traceSelectorAtoms(selectorKey, dependency.key, store);
|
|
569
|
+
store.logger.info(
|
|
570
|
+
`\u{1F50D}`,
|
|
571
|
+
`selector`,
|
|
572
|
+
selectorKey,
|
|
573
|
+
`discovers root atoms: [ ${rootKeys.map((key) => `"${key}"`).join(`, `)} ]`
|
|
574
|
+
);
|
|
575
|
+
for (const atomKey of rootKeys) {
|
|
576
|
+
target.selectorAtoms = target.selectorAtoms.set({
|
|
577
|
+
selectorKey,
|
|
578
|
+
atomKey
|
|
579
|
+
});
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
};
|
|
583
|
+
|
|
584
|
+
// internal/src/selector/register-selector.ts
|
|
585
|
+
var registerSelector = (selectorKey, store) => ({
|
|
586
|
+
get: (dependency) => {
|
|
587
|
+
const target = newest(store);
|
|
588
|
+
if (dependency.type === `molecule`) {
|
|
589
|
+
return getFromStore(dependency, store);
|
|
590
|
+
}
|
|
591
|
+
const dependencyState = withdraw(dependency, store);
|
|
592
|
+
const dependencyValue = readOrComputeValue(dependencyState, store);
|
|
593
|
+
store.logger.info(
|
|
594
|
+
`\u{1F50C}`,
|
|
595
|
+
`selector`,
|
|
596
|
+
selectorKey,
|
|
597
|
+
`registers dependency ( "${dependency.key}" =`,
|
|
598
|
+
dependencyValue,
|
|
599
|
+
`)`
|
|
600
|
+
);
|
|
601
|
+
target.selectorGraph.set(
|
|
602
|
+
{
|
|
603
|
+
upstreamSelectorKey: dependency.key,
|
|
604
|
+
downstreamSelectorKey: selectorKey
|
|
605
|
+
},
|
|
606
|
+
{
|
|
607
|
+
source: dependency.key
|
|
880
608
|
}
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
609
|
+
);
|
|
610
|
+
updateSelectorAtoms(selectorKey, dependency, store);
|
|
611
|
+
return dependencyValue;
|
|
612
|
+
},
|
|
613
|
+
set: (WritableToken, newValue) => {
|
|
614
|
+
const target = newest(store);
|
|
615
|
+
const state = withdraw(WritableToken, target);
|
|
616
|
+
setAtomOrSelector(state, newValue, target);
|
|
617
|
+
},
|
|
618
|
+
find: (token, key) => findInStore(token, key, store),
|
|
619
|
+
seek: (token, key) => seekInStore(token, key, store),
|
|
620
|
+
json: (token) => getJsonToken(token, store)
|
|
621
|
+
});
|
|
622
|
+
|
|
623
|
+
// internal/src/selector/create-readonly-selector.ts
|
|
624
|
+
var createReadonlySelector = (options, family, store) => {
|
|
625
|
+
const target = newest(store);
|
|
626
|
+
const subject = new Subject();
|
|
627
|
+
const { get, find, seek, json } = registerSelector(options.key, target);
|
|
628
|
+
const getSelf = () => {
|
|
629
|
+
const value = options.get({ get, find, seek, json });
|
|
630
|
+
cacheValue(options.key, value, subject, newest(store));
|
|
631
|
+
return value;
|
|
895
632
|
};
|
|
896
|
-
const
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
633
|
+
const readonlySelector = __spreadValues(__spreadProps(__spreadValues({}, options), {
|
|
634
|
+
subject,
|
|
635
|
+
install: (s) => createReadonlySelector(options, family, s),
|
|
636
|
+
get: getSelf,
|
|
637
|
+
type: `readonly_selector`
|
|
638
|
+
}), family && { family });
|
|
639
|
+
target.readonlySelectors.set(options.key, readonlySelector);
|
|
640
|
+
const initialValue = getSelf();
|
|
641
|
+
store.logger.info(
|
|
642
|
+
`\u2728`,
|
|
643
|
+
readonlySelector.type,
|
|
644
|
+
readonlySelector.key,
|
|
645
|
+
`=`,
|
|
646
|
+
initialValue
|
|
647
|
+
);
|
|
648
|
+
const token = {
|
|
649
|
+
key: options.key,
|
|
650
|
+
type: `readonly_selector`
|
|
904
651
|
};
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
target.transactionMeta.update.updates.push(update);
|
|
908
|
-
} else {
|
|
909
|
-
family.subject.next(update);
|
|
652
|
+
if (family) {
|
|
653
|
+
token.family = family;
|
|
910
654
|
}
|
|
911
655
|
return token;
|
|
912
|
-
}
|
|
656
|
+
};
|
|
913
657
|
|
|
914
|
-
// internal/src/
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
658
|
+
// internal/src/selector/create-writable-selector.ts
|
|
659
|
+
var createWritableSelector = (options, family, store) => {
|
|
660
|
+
const target = newest(store);
|
|
661
|
+
const subject = new Subject();
|
|
662
|
+
const transactors = registerSelector(options.key, target);
|
|
663
|
+
const { find, get, seek, json } = transactors;
|
|
664
|
+
const readonlyTransactors = { find, get, seek, json };
|
|
665
|
+
const getSelf = (innerTarget = newest(store)) => {
|
|
666
|
+
const value = options.get(readonlyTransactors);
|
|
667
|
+
cacheValue(options.key, value, subject, innerTarget);
|
|
668
|
+
return value;
|
|
669
|
+
};
|
|
670
|
+
const setSelf = (next) => {
|
|
671
|
+
const innerTarget = newest(store);
|
|
672
|
+
const oldValue = getSelf(innerTarget);
|
|
673
|
+
const newValue = become(next)(oldValue);
|
|
674
|
+
store.logger.info(
|
|
675
|
+
`\u{1F4DD}`,
|
|
676
|
+
`selector`,
|
|
677
|
+
options.key,
|
|
678
|
+
`set (`,
|
|
679
|
+
oldValue,
|
|
680
|
+
`->`,
|
|
681
|
+
newValue,
|
|
682
|
+
`)`
|
|
683
|
+
);
|
|
684
|
+
cacheValue(options.key, newValue, subject, innerTarget);
|
|
685
|
+
markDone(options.key, innerTarget);
|
|
686
|
+
if (isRootStore(innerTarget)) {
|
|
687
|
+
subject.next({ newValue, oldValue });
|
|
924
688
|
}
|
|
689
|
+
options.set(transactors, newValue);
|
|
690
|
+
};
|
|
691
|
+
const mySelector = __spreadValues(__spreadProps(__spreadValues({}, options), {
|
|
692
|
+
subject,
|
|
693
|
+
install: (s) => createWritableSelector(options, family, s),
|
|
694
|
+
get: getSelf,
|
|
695
|
+
set: setSelf,
|
|
696
|
+
type: `selector`
|
|
697
|
+
}), family && { family });
|
|
698
|
+
target.selectors.set(options.key, mySelector);
|
|
699
|
+
const initialValue = getSelf();
|
|
700
|
+
store.logger.info(`\u2728`, mySelector.type, mySelector.key, `=`, initialValue);
|
|
701
|
+
const token = {
|
|
702
|
+
key: options.key,
|
|
703
|
+
type: `selector`
|
|
704
|
+
};
|
|
705
|
+
if (family) {
|
|
706
|
+
token.family = family;
|
|
707
|
+
}
|
|
708
|
+
return token;
|
|
709
|
+
};
|
|
710
|
+
|
|
711
|
+
// internal/src/selector/create-standalone-selector.ts
|
|
712
|
+
function createStandaloneSelector(options, store) {
|
|
713
|
+
const isWritable = `set` in options;
|
|
714
|
+
if (isWritable) {
|
|
715
|
+
const state2 = createWritableSelector(options, void 0, store);
|
|
716
|
+
store.on.selectorCreation.next(state2);
|
|
717
|
+
return state2;
|
|
925
718
|
}
|
|
719
|
+
const state = createReadonlySelector(options, void 0, store);
|
|
720
|
+
store.on.selectorCreation.next(state);
|
|
721
|
+
return state;
|
|
926
722
|
}
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
723
|
+
|
|
724
|
+
// internal/src/selector/dispose-selector.ts
|
|
725
|
+
function disposeSelector(selectorToken, store) {
|
|
726
|
+
var _a;
|
|
727
|
+
const target = newest(store);
|
|
728
|
+
const { key } = selectorToken;
|
|
729
|
+
const selector = (_a = target.selectors.get(key)) != null ? _a : target.readonlySelectors.get(key);
|
|
730
|
+
if (!selector) {
|
|
731
|
+
store.logger.info(
|
|
732
|
+
`\u274C`,
|
|
733
|
+
`selector`,
|
|
734
|
+
key,
|
|
735
|
+
`Tried to dispose selector, but it does not exist in the store.`
|
|
736
|
+
);
|
|
737
|
+
} else if (!selector.family) {
|
|
738
|
+
store.logger.error(
|
|
739
|
+
`\u274C`,
|
|
740
|
+
`selector`,
|
|
741
|
+
key,
|
|
742
|
+
`Standalone selectors cannot be disposed.`
|
|
743
|
+
);
|
|
744
|
+
} else {
|
|
745
|
+
const molecule = target.molecules.get(selector.family.subKey);
|
|
746
|
+
if (molecule) {
|
|
747
|
+
molecule.tokens.delete(key);
|
|
932
748
|
}
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
749
|
+
switch (selectorToken.type) {
|
|
750
|
+
case `selector`:
|
|
751
|
+
{
|
|
752
|
+
target.selectors.delete(key);
|
|
753
|
+
const family = withdraw(
|
|
754
|
+
{ key: selector.family.key, type: `selector_family` },
|
|
755
|
+
store
|
|
756
|
+
);
|
|
757
|
+
family.subject.next({
|
|
758
|
+
type: `state_disposal`,
|
|
759
|
+
token: selectorToken
|
|
760
|
+
});
|
|
761
|
+
}
|
|
762
|
+
break;
|
|
763
|
+
case `readonly_selector`:
|
|
764
|
+
{
|
|
765
|
+
target.readonlySelectors.delete(key);
|
|
766
|
+
const family = withdraw(
|
|
767
|
+
{ key: selector.family.key, type: `readonly_selector_family` },
|
|
768
|
+
store
|
|
769
|
+
);
|
|
770
|
+
family.subject.next({
|
|
771
|
+
type: `state_disposal`,
|
|
772
|
+
token: selectorToken
|
|
773
|
+
});
|
|
774
|
+
}
|
|
775
|
+
break;
|
|
937
776
|
}
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
const molecule = store.molecules.get(token.family.subKey);
|
|
945
|
-
if (molecule) {
|
|
946
|
-
growMoleculeInStore(molecule, family, store);
|
|
947
|
-
return;
|
|
777
|
+
target.valueMap.delete(key);
|
|
778
|
+
target.selectorAtoms.delete(key);
|
|
779
|
+
const downstreamTokens = target.selectorGraph.getRelationEntries({ upstreamSelectorKey: key }).filter(([_, { source }]) => source === key).map(
|
|
780
|
+
([downstreamSelectorKey]) => {
|
|
781
|
+
var _a2;
|
|
782
|
+
return (_a2 = target.selectors.get(downstreamSelectorKey)) != null ? _a2 : target.readonlySelectors.get(downstreamSelectorKey);
|
|
948
783
|
}
|
|
949
|
-
|
|
950
|
-
|
|
784
|
+
);
|
|
785
|
+
for (const downstreamToken of downstreamTokens) {
|
|
786
|
+
if (downstreamToken) {
|
|
787
|
+
disposeSelector(downstreamToken, store);
|
|
951
788
|
}
|
|
952
|
-
|
|
789
|
+
}
|
|
790
|
+
target.selectorGraph.delete(key);
|
|
791
|
+
store.logger.info(`\u{1F525}`, selectorToken.type, key, `deleted`);
|
|
792
|
+
if (isChildStore(target) && target.transactionMeta.phase === `building`) {
|
|
793
|
+
target.transactionMeta.update.updates.push({
|
|
794
|
+
type: `state_disposal`,
|
|
795
|
+
token: selectorToken
|
|
796
|
+
});
|
|
797
|
+
} else {
|
|
798
|
+
store.on.selectorDisposal.next(selectorToken);
|
|
953
799
|
}
|
|
954
800
|
}
|
|
955
801
|
}
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
802
|
+
|
|
803
|
+
// internal/src/families/create-readonly-selector-family.ts
|
|
804
|
+
function createReadonlySelectorFamily(options, store) {
|
|
805
|
+
const subject = new Subject();
|
|
806
|
+
const readonlySelectorFamily = Object.assign(
|
|
807
|
+
(key) => {
|
|
808
|
+
const subKey = stringifyJson(key);
|
|
809
|
+
const family = { key: options.key, subKey };
|
|
810
|
+
const fullKey = `${options.key}(${subKey})`;
|
|
811
|
+
const target = newest(store);
|
|
812
|
+
const token = createReadonlySelector(
|
|
813
|
+
{
|
|
814
|
+
key: fullKey,
|
|
815
|
+
get: options.get(key)
|
|
816
|
+
},
|
|
817
|
+
family,
|
|
818
|
+
target
|
|
965
819
|
);
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
820
|
+
subject.next({ type: `state_creation`, token });
|
|
821
|
+
return token;
|
|
822
|
+
},
|
|
823
|
+
{
|
|
824
|
+
key: options.key,
|
|
825
|
+
type: `readonly_selector_family`,
|
|
826
|
+
subject,
|
|
827
|
+
install: (s) => createReadonlySelectorFamily(options, s)
|
|
828
|
+
}
|
|
829
|
+
);
|
|
830
|
+
store.families.set(options.key, readonlySelectorFamily);
|
|
831
|
+
return readonlySelectorFamily;
|
|
971
832
|
}
|
|
972
|
-
function
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
833
|
+
function createWritableSelectorFamily(options, store) {
|
|
834
|
+
const subject = new Subject();
|
|
835
|
+
const selectorFamily = Object.assign(
|
|
836
|
+
(key) => {
|
|
837
|
+
const subKey = stringifyJson(key);
|
|
838
|
+
const family = { key: options.key, subKey };
|
|
839
|
+
const fullKey = `${options.key}(${subKey})`;
|
|
840
|
+
const target = newest(store);
|
|
841
|
+
const token = createWritableSelector(
|
|
842
|
+
{
|
|
843
|
+
key: fullKey,
|
|
844
|
+
get: options.get(key),
|
|
845
|
+
set: options.set(key)
|
|
846
|
+
},
|
|
847
|
+
family,
|
|
848
|
+
target
|
|
983
849
|
);
|
|
984
|
-
|
|
985
|
-
|
|
850
|
+
subject.next({ type: `state_creation`, token });
|
|
851
|
+
return token;
|
|
852
|
+
},
|
|
853
|
+
{
|
|
854
|
+
key: options.key,
|
|
855
|
+
type: `selector_family`,
|
|
856
|
+
subject,
|
|
857
|
+
install: (s) => createWritableSelectorFamily(options, s)
|
|
858
|
+
}
|
|
859
|
+
);
|
|
860
|
+
store.families.set(options.key, selectorFamily);
|
|
861
|
+
return selectorFamily;
|
|
986
862
|
}
|
|
987
863
|
|
|
988
|
-
// internal/src/
|
|
989
|
-
function
|
|
990
|
-
const
|
|
991
|
-
|
|
992
|
-
|
|
864
|
+
// internal/src/families/create-selector-family.ts
|
|
865
|
+
function createSelectorFamily(options, store) {
|
|
866
|
+
const isWritable = `set` in options;
|
|
867
|
+
if (isWritable) {
|
|
868
|
+
return createWritableSelectorFamily(options, store);
|
|
993
869
|
}
|
|
870
|
+
return createReadonlySelectorFamily(options, store);
|
|
994
871
|
}
|
|
995
872
|
|
|
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;
|
|
873
|
+
// internal/src/molecule/dispose-molecule.ts
|
|
874
|
+
function disposeMolecule(token, store) {
|
|
875
|
+
var _a;
|
|
876
|
+
let molecule;
|
|
877
|
+
try {
|
|
878
|
+
molecule = withdraw(token, store);
|
|
879
|
+
} catch (thrown) {
|
|
880
|
+
if (thrown instanceof Error) {
|
|
881
|
+
store.logger.error(
|
|
882
|
+
`\u{1F41E}`,
|
|
883
|
+
`molecule`,
|
|
884
|
+
JSON.stringify(token.key),
|
|
885
|
+
`Failed to dispose molecule, because it was not found in the store.`,
|
|
886
|
+
thrown.message
|
|
887
|
+
);
|
|
1020
888
|
}
|
|
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
889
|
return;
|
|
1035
890
|
}
|
|
1036
|
-
const
|
|
1037
|
-
|
|
1038
|
-
|
|
891
|
+
const { family } = token;
|
|
892
|
+
const context = [];
|
|
893
|
+
for (const above of molecule.above.values()) {
|
|
894
|
+
context.push(deposit(above));
|
|
1039
895
|
}
|
|
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;
|
|
896
|
+
const values = [];
|
|
897
|
+
for (const stateToken of molecule.tokens.values()) {
|
|
898
|
+
const tokenFamily = stateToken.family;
|
|
899
|
+
values.push([tokenFamily.key, store.valueMap.get(stateToken.key)]);
|
|
1055
900
|
}
|
|
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
|
-
ingestTransactionUpdate(`newValue`, child.transactionMeta.update, parent);
|
|
1069
|
-
if (isRootStore(parent)) {
|
|
1070
|
-
setEpochNumberOfAction(
|
|
1071
|
-
child.transactionMeta.update.key,
|
|
1072
|
-
child.transactionMeta.update.epoch,
|
|
1073
|
-
parent
|
|
1074
|
-
);
|
|
1075
|
-
const myTransaction = withdraw(
|
|
1076
|
-
{ key: child.transactionMeta.update.key, type: `transaction` },
|
|
1077
|
-
store
|
|
1078
|
-
);
|
|
1079
|
-
myTransaction == null ? void 0 : myTransaction.subject.next(child.transactionMeta.update);
|
|
1080
|
-
store.logger.info(
|
|
1081
|
-
`\u{1F6EC}`,
|
|
1082
|
-
`transaction`,
|
|
1083
|
-
child.transactionMeta.update.key,
|
|
1084
|
-
`Finished applying transaction.`
|
|
1085
|
-
);
|
|
1086
|
-
} else if (isChildStore(parent)) {
|
|
1087
|
-
parent.transactionMeta.update.updates.push(child.transactionMeta.update);
|
|
1088
|
-
}
|
|
1089
|
-
parent.on.transactionApplying.next(null);
|
|
1090
|
-
};
|
|
1091
|
-
|
|
1092
|
-
// internal/src/transaction/assign-transaction-to-continuity.ts
|
|
1093
|
-
function assignTransactionToContinuity(continuityKey, transactionKey, store) {
|
|
1094
|
-
const isRoot = isRootStore(store);
|
|
1095
|
-
if (!isRoot) {
|
|
1096
|
-
return;
|
|
1097
|
-
}
|
|
1098
|
-
const { epoch, actionContinuities } = store.transactionMeta;
|
|
1099
|
-
actionContinuities.set(continuityKey, transactionKey);
|
|
1100
|
-
if (!epoch.has(continuityKey)) {
|
|
1101
|
-
epoch.set(continuityKey, -1);
|
|
1102
|
-
}
|
|
1103
|
-
}
|
|
1104
|
-
|
|
1105
|
-
// internal/src/lazy-map.ts
|
|
1106
|
-
var LazyMap = class extends Map {
|
|
1107
|
-
constructor(source) {
|
|
1108
|
-
super();
|
|
1109
|
-
this.source = source;
|
|
1110
|
-
this.deleted = /* @__PURE__ */ new Set();
|
|
1111
|
-
}
|
|
1112
|
-
get(key) {
|
|
1113
|
-
const has = super.has(key);
|
|
1114
|
-
if (has) {
|
|
1115
|
-
return super.get(key);
|
|
1116
|
-
}
|
|
1117
|
-
if (!this.deleted.has(key) && this.source.has(key)) {
|
|
1118
|
-
const value = this.source.get(key);
|
|
1119
|
-
return value;
|
|
1120
|
-
}
|
|
1121
|
-
return void 0;
|
|
1122
|
-
}
|
|
1123
|
-
set(key, value) {
|
|
1124
|
-
this.deleted.delete(key);
|
|
1125
|
-
return super.set(key, value);
|
|
1126
|
-
}
|
|
1127
|
-
hasOwn(key) {
|
|
1128
|
-
return super.has(key);
|
|
1129
|
-
}
|
|
1130
|
-
has(key) {
|
|
1131
|
-
return !this.deleted.has(key) && (super.has(key) || this.source.has(key));
|
|
1132
|
-
}
|
|
1133
|
-
delete(key) {
|
|
1134
|
-
this.deleted.add(key);
|
|
1135
|
-
return super.delete(key);
|
|
1136
|
-
}
|
|
1137
|
-
};
|
|
1138
|
-
|
|
1139
|
-
// internal/src/transaction/build-transaction.ts
|
|
1140
|
-
var buildTransaction = (key, params, store, id) => {
|
|
1141
|
-
const parent = newest(store);
|
|
1142
|
-
const childBase = {
|
|
1143
|
-
parent,
|
|
1144
|
-
child: null,
|
|
1145
|
-
on: parent.on,
|
|
1146
|
-
loggers: parent.loggers,
|
|
1147
|
-
logger: parent.logger,
|
|
1148
|
-
config: parent.config,
|
|
1149
|
-
atoms: new LazyMap(parent.atoms),
|
|
1150
|
-
atomsThatAreDefault: new Set(parent.atomsThatAreDefault),
|
|
1151
|
-
families: new LazyMap(parent.families),
|
|
1152
|
-
operation: { open: false },
|
|
1153
|
-
readonlySelectors: new LazyMap(parent.readonlySelectors),
|
|
1154
|
-
timelines: new LazyMap(parent.timelines),
|
|
1155
|
-
timelineAtoms: new Junction(parent.timelineAtoms.toJSON()),
|
|
1156
|
-
trackers: /* @__PURE__ */ new Map(),
|
|
1157
|
-
transactions: new LazyMap(parent.transactions),
|
|
1158
|
-
selectorAtoms: new Junction(parent.selectorAtoms.toJSON()),
|
|
1159
|
-
selectorGraph: new Junction(parent.selectorGraph.toJSON(), {
|
|
1160
|
-
makeContentKey: (...keys) => keys.sort().join(`:`)
|
|
1161
|
-
}),
|
|
1162
|
-
selectors: new LazyMap(parent.selectors),
|
|
1163
|
-
valueMap: new LazyMap(parent.valueMap),
|
|
1164
|
-
molecules: new LazyMap(parent.molecules),
|
|
1165
|
-
moleculeFamilies: new LazyMap(parent.moleculeFamilies),
|
|
1166
|
-
miscResources: new LazyMap(parent.miscResources)
|
|
1167
|
-
};
|
|
1168
|
-
const epoch = getEpochNumberOfAction(key, store);
|
|
1169
|
-
const transactionMeta = {
|
|
1170
|
-
phase: `building`,
|
|
1171
|
-
update: {
|
|
1172
|
-
type: `transaction_update`,
|
|
1173
|
-
key,
|
|
1174
|
-
id,
|
|
1175
|
-
epoch: epoch === void 0 ? Number.NaN : epoch + 1,
|
|
1176
|
-
updates: [],
|
|
1177
|
-
params,
|
|
1178
|
-
output: void 0
|
|
1179
|
-
},
|
|
1180
|
-
transactors: {
|
|
1181
|
-
get: (token) => getFromStore(token, child),
|
|
1182
|
-
set: (token, value) => {
|
|
1183
|
-
setIntoStore(token, value, child);
|
|
1184
|
-
},
|
|
1185
|
-
run: (token, identifier = arbitrary()) => actUponStore(token, identifier, child),
|
|
1186
|
-
find: (token, k) => findInStore(token, k, child),
|
|
1187
|
-
seek: (token, k) => seekInStore(token, k, child),
|
|
1188
|
-
json: (token) => getJsonToken(token, child),
|
|
1189
|
-
make: (context, family, k, ...args) => makeMoleculeInStore(child, context, family, k, ...args),
|
|
1190
|
-
dispose: (token) => {
|
|
1191
|
-
disposeFromStore(token, child);
|
|
1192
|
-
},
|
|
1193
|
-
env: () => getEnvironmentData(child)
|
|
1194
|
-
}
|
|
1195
|
-
};
|
|
1196
|
-
const child = Object.assign(childBase, {
|
|
1197
|
-
transactionMeta
|
|
1198
|
-
});
|
|
1199
|
-
parent.child = child;
|
|
1200
|
-
store.logger.info(
|
|
1201
|
-
`\u{1F6EB}`,
|
|
1202
|
-
`transaction`,
|
|
1203
|
-
key,
|
|
1204
|
-
`Building transaction with params:`,
|
|
1205
|
-
params
|
|
1206
|
-
);
|
|
1207
|
-
return child;
|
|
1208
|
-
};
|
|
1209
|
-
|
|
1210
|
-
// internal/src/transaction/create-transaction.ts
|
|
1211
|
-
function createTransaction(options, store) {
|
|
1212
|
-
const newTransaction = {
|
|
1213
|
-
key: options.key,
|
|
1214
|
-
type: `transaction`,
|
|
1215
|
-
run: (params, id) => {
|
|
1216
|
-
const childStore = buildTransaction(options.key, params, store, id);
|
|
1217
|
-
try {
|
|
1218
|
-
const target2 = newest(store);
|
|
1219
|
-
const { transactors } = childStore.transactionMeta;
|
|
1220
|
-
const output = options.do(transactors, ...params);
|
|
1221
|
-
applyTransaction(output, target2);
|
|
1222
|
-
return output;
|
|
1223
|
-
} catch (thrown) {
|
|
1224
|
-
abortTransaction(target);
|
|
1225
|
-
store.logger.warn(`\u{1F4A5}`, `transaction`, options.key, `caught:`, thrown);
|
|
1226
|
-
throw thrown;
|
|
1227
|
-
}
|
|
1228
|
-
},
|
|
1229
|
-
install: (s) => createTransaction(options, s),
|
|
1230
|
-
subject: new Subject()
|
|
1231
|
-
};
|
|
1232
|
-
const target = newest(store);
|
|
1233
|
-
target.transactions.set(newTransaction.key, newTransaction);
|
|
1234
|
-
const token = deposit(newTransaction);
|
|
1235
|
-
store.on.transactionCreation.next(token);
|
|
1236
|
-
return token;
|
|
1237
|
-
}
|
|
1238
|
-
|
|
1239
|
-
// internal/src/transaction/get-epoch-number.ts
|
|
1240
|
-
function getContinuityKey(transactionKey, store) {
|
|
1241
|
-
const isRoot = isRootStore(store);
|
|
1242
|
-
const continuity = isRoot ? store.transactionMeta.actionContinuities.getRelatedKey(transactionKey) : void 0;
|
|
1243
|
-
return continuity;
|
|
1244
|
-
}
|
|
1245
|
-
function getEpochNumberOfContinuity(continuityKey, store) {
|
|
1246
|
-
const isRoot = isRootStore(store);
|
|
1247
|
-
const epoch = isRoot && continuityKey ? store.transactionMeta.epoch.get(continuityKey) : void 0;
|
|
1248
|
-
return epoch;
|
|
1249
|
-
}
|
|
1250
|
-
function getEpochNumberOfAction(transactionKey, store) {
|
|
1251
|
-
const isRoot = isRootStore(store);
|
|
1252
|
-
const continuity = isRoot ? store.transactionMeta.actionContinuities.getRelatedKey(transactionKey) : void 0;
|
|
1253
|
-
const epoch = isRoot && continuity !== void 0 ? store.transactionMeta.epoch.get(continuity) : void 0;
|
|
1254
|
-
return epoch;
|
|
1255
|
-
}
|
|
1256
|
-
|
|
1257
|
-
// internal/src/transaction/index.ts
|
|
1258
|
-
var TRANSACTION_PHASES = [`idle`, `building`, `applying`];
|
|
1259
|
-
|
|
1260
|
-
// internal/src/molecule/dispose-molecule.ts
|
|
1261
|
-
function disposeMolecule(token, store) {
|
|
1262
|
-
var _a;
|
|
1263
|
-
let molecule;
|
|
1264
|
-
try {
|
|
1265
|
-
molecule = withdraw(token, store);
|
|
1266
|
-
} catch (thrown) {
|
|
1267
|
-
if (thrown instanceof Error) {
|
|
1268
|
-
store.logger.error(
|
|
1269
|
-
`\u{1F41E}`,
|
|
1270
|
-
`molecule`,
|
|
1271
|
-
JSON.stringify(token.key),
|
|
1272
|
-
`Failed to dispose molecule, because it was not found in the store.`,
|
|
1273
|
-
thrown.message
|
|
1274
|
-
);
|
|
1275
|
-
}
|
|
1276
|
-
return;
|
|
1277
|
-
}
|
|
1278
|
-
const { family } = token;
|
|
1279
|
-
for (const state of molecule.tokens.values()) {
|
|
1280
|
-
disposeFromStore(state, store);
|
|
1281
|
-
}
|
|
1282
|
-
for (const child of molecule.below.values()) {
|
|
1283
|
-
if (((_a = child.family) == null ? void 0 : _a.dependsOn) === `all`) {
|
|
1284
|
-
disposeMolecule(child, store);
|
|
1285
|
-
} else {
|
|
1286
|
-
child.above.delete(molecule.stringKey);
|
|
1287
|
-
if (child.above.size === 0) {
|
|
1288
|
-
disposeMolecule(child, store);
|
|
1289
|
-
}
|
|
1290
|
-
}
|
|
1291
|
-
}
|
|
1292
|
-
molecule.below.clear();
|
|
1293
901
|
if (family) {
|
|
1294
902
|
const Formula = withdraw(family, store);
|
|
1295
903
|
const disposalEvent = {
|
|
1296
904
|
type: `molecule_disposal`,
|
|
1297
905
|
token,
|
|
1298
906
|
family,
|
|
1299
|
-
context
|
|
1300
|
-
|
|
1301
|
-
var _a2;
|
|
1302
|
-
return (_a2 = t.family) == null ? void 0 : _a2.key;
|
|
1303
|
-
}).filter((k) => typeof k === `string`)
|
|
907
|
+
context,
|
|
908
|
+
values
|
|
1304
909
|
};
|
|
1305
910
|
if (token.family) {
|
|
1306
911
|
disposalEvent.family = token.family;
|
|
1307
912
|
}
|
|
913
|
+
for (const state of molecule.tokens.values()) {
|
|
914
|
+
disposeFromStore(state, store);
|
|
915
|
+
}
|
|
916
|
+
for (const child of molecule.below.values()) {
|
|
917
|
+
if (((_a = child.family) == null ? void 0 : _a.dependsOn) === `all`) {
|
|
918
|
+
disposeMolecule(child, store);
|
|
919
|
+
} else {
|
|
920
|
+
child.above.delete(molecule.stringKey);
|
|
921
|
+
if (child.above.size === 0) {
|
|
922
|
+
disposeMolecule(child, store);
|
|
923
|
+
}
|
|
924
|
+
}
|
|
925
|
+
}
|
|
926
|
+
molecule.below.clear();
|
|
1308
927
|
const isTransaction = isChildStore(store) && store.transactionMeta.phase === `building`;
|
|
1309
928
|
if (isTransaction) {
|
|
1310
929
|
store.transactionMeta.update.updates.push(disposalEvent);
|
|
@@ -1347,13 +966,8 @@ function initFamilyMemberInStore(token, key, store) {
|
|
|
1347
966
|
}
|
|
1348
967
|
const state = family(key);
|
|
1349
968
|
const target = newest(store);
|
|
1350
|
-
if (state.family) {
|
|
1351
|
-
if (
|
|
1352
|
-
target.transactionMeta.update.updates.push({
|
|
1353
|
-
type: `state_creation`,
|
|
1354
|
-
token: state
|
|
1355
|
-
});
|
|
1356
|
-
} else {
|
|
969
|
+
if (state.family && target.moleculeInProgress === null) {
|
|
970
|
+
if (isRootStore(target)) {
|
|
1357
971
|
switch (state.type) {
|
|
1358
972
|
case `atom`:
|
|
1359
973
|
case `mutable_atom`:
|
|
@@ -1364,6 +978,11 @@ function initFamilyMemberInStore(token, key, store) {
|
|
|
1364
978
|
store.on.selectorCreation.next(state);
|
|
1365
979
|
break;
|
|
1366
980
|
}
|
|
981
|
+
} else if (isChildStore(target) && target.on.transactionApplying.state === null) {
|
|
982
|
+
target.transactionMeta.update.updates.push({
|
|
983
|
+
type: `state_creation`,
|
|
984
|
+
token: state
|
|
985
|
+
});
|
|
1367
986
|
}
|
|
1368
987
|
}
|
|
1369
988
|
return state;
|
|
@@ -1411,291 +1030,701 @@ function findInStore(token, key, store) {
|
|
|
1411
1030
|
return state;
|
|
1412
1031
|
}
|
|
1413
1032
|
|
|
1414
|
-
// internal/src/
|
|
1415
|
-
|
|
1416
|
-
var
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1033
|
+
// internal/src/molecule/create-molecule-family.ts
|
|
1034
|
+
function createMoleculeFamily(options, store) {
|
|
1035
|
+
var _a;
|
|
1036
|
+
const subject = new Subject();
|
|
1037
|
+
const token = {
|
|
1038
|
+
type: `molecule_family`,
|
|
1039
|
+
key: options.key,
|
|
1040
|
+
dependsOn: (_a = options.dependsOn) != null ? _a : `all`
|
|
1041
|
+
};
|
|
1042
|
+
const family = __spreadProps(__spreadValues({}, token), {
|
|
1043
|
+
subject,
|
|
1044
|
+
new: options.new
|
|
1045
|
+
});
|
|
1046
|
+
store.moleculeFamilies.set(options.key, family);
|
|
1047
|
+
return token;
|
|
1048
|
+
}
|
|
1049
|
+
|
|
1050
|
+
// internal/src/molecule/grow-molecule-in-store.ts
|
|
1051
|
+
function growMoleculeInStore(molecule, family, store) {
|
|
1052
|
+
const stateToken = initFamilyMemberInStore(family, molecule.key, store);
|
|
1053
|
+
molecule.tokens.set(stateToken.key, stateToken);
|
|
1054
|
+
const isTransaction = isChildStore(store) && store.transactionMeta.phase === `building`;
|
|
1055
|
+
const moleculeInProgress = store.moleculeInProgress === molecule.key;
|
|
1056
|
+
if (!isTransaction && !moleculeInProgress) {
|
|
1057
|
+
molecule.subject.next({ type: `state_creation`, token: stateToken });
|
|
1058
|
+
}
|
|
1059
|
+
return stateToken;
|
|
1060
|
+
}
|
|
1061
|
+
|
|
1062
|
+
// internal/src/get-environment-data.ts
|
|
1063
|
+
function getEnvironmentData(store) {
|
|
1064
|
+
return {
|
|
1431
1065
|
store
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1066
|
+
};
|
|
1067
|
+
}
|
|
1068
|
+
var Molecule = class {
|
|
1069
|
+
constructor(ctx, key, family) {
|
|
1070
|
+
this.key = key;
|
|
1071
|
+
this.type = `molecule`;
|
|
1072
|
+
this.subject = new Subject();
|
|
1073
|
+
this.tokens = /* @__PURE__ */ new Map();
|
|
1074
|
+
this.above = /* @__PURE__ */ new Map();
|
|
1075
|
+
this.below = /* @__PURE__ */ new Map();
|
|
1076
|
+
this.joins = /* @__PURE__ */ new Map();
|
|
1077
|
+
this.stringKey = stringifyJson(key);
|
|
1078
|
+
if (family) {
|
|
1079
|
+
this.family = family;
|
|
1441
1080
|
}
|
|
1442
|
-
if (
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1081
|
+
if (ctx) {
|
|
1082
|
+
if (Array.isArray(ctx)) {
|
|
1083
|
+
for (const molecule of ctx) {
|
|
1084
|
+
this.above.set(molecule.stringKey, molecule);
|
|
1085
|
+
}
|
|
1086
|
+
} else {
|
|
1087
|
+
this.above.set(ctx.stringKey, ctx);
|
|
1088
|
+
}
|
|
1448
1089
|
}
|
|
1449
1090
|
}
|
|
1450
|
-
return rootKeys;
|
|
1451
|
-
};
|
|
1452
|
-
var traceAllSelectorAtoms = (selector, store) => {
|
|
1453
|
-
const selectorKey = selector.key;
|
|
1454
|
-
const directDependencyKeys = getSelectorDependencyKeys(selectorKey, store);
|
|
1455
|
-
return directDependencyKeys.flatMap(
|
|
1456
|
-
(depKey) => isAtomKey(depKey, store) ? depKey : traceSelectorAtoms(selectorKey, depKey, store)
|
|
1457
|
-
);
|
|
1458
1091
|
};
|
|
1459
1092
|
|
|
1460
|
-
// internal/src/
|
|
1461
|
-
|
|
1093
|
+
// internal/src/molecule/make-molecule-in-store.ts
|
|
1094
|
+
function makeMoleculeInStore(store, context, familyToken, key, ...params) {
|
|
1462
1095
|
const target = newest(store);
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
store.logger.info(
|
|
1469
|
-
`\u{1F50D}`,
|
|
1470
|
-
`selector`,
|
|
1471
|
-
selectorKey,
|
|
1472
|
-
`discovers root atom "${dependency.key}"`
|
|
1473
|
-
);
|
|
1474
|
-
} else {
|
|
1475
|
-
const rootKeys = traceSelectorAtoms(selectorKey, dependency.key, store);
|
|
1476
|
-
store.logger.info(
|
|
1477
|
-
`\u{1F50D}`,
|
|
1478
|
-
`selector`,
|
|
1479
|
-
selectorKey,
|
|
1480
|
-
`discovers root atoms: [ ${rootKeys.map((key) => `"${key}"`).join(`, `)} ]`
|
|
1481
|
-
);
|
|
1482
|
-
for (const atomKey of rootKeys) {
|
|
1483
|
-
target.selectorAtoms = target.selectorAtoms.set({
|
|
1484
|
-
selectorKey,
|
|
1485
|
-
atomKey
|
|
1486
|
-
});
|
|
1096
|
+
target.moleculeInProgress = key;
|
|
1097
|
+
const contextArray = Array.isArray(context) ? context : [context];
|
|
1098
|
+
const owners = contextArray.map((ctx) => {
|
|
1099
|
+
if (ctx instanceof Molecule) {
|
|
1100
|
+
return ctx;
|
|
1487
1101
|
}
|
|
1102
|
+
const stringKey = stringifyJson(ctx.key);
|
|
1103
|
+
const molecule2 = store.molecules.get(stringKey);
|
|
1104
|
+
if (!molecule2) {
|
|
1105
|
+
throw new Error(
|
|
1106
|
+
`Molecule ${stringKey} not found in store "${store.config.name}"`
|
|
1107
|
+
);
|
|
1108
|
+
}
|
|
1109
|
+
return molecule2;
|
|
1110
|
+
});
|
|
1111
|
+
const molecule = new Molecule(owners, key, familyToken);
|
|
1112
|
+
target.molecules.set(stringifyJson(key), molecule);
|
|
1113
|
+
for (const owner of owners) {
|
|
1114
|
+
owner.below.set(molecule.stringKey, molecule);
|
|
1488
1115
|
}
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
store
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
{
|
|
1511
|
-
|
|
1116
|
+
const transactors = {
|
|
1117
|
+
get: (t) => getFromStore(t, newest(store)),
|
|
1118
|
+
set: (t, newValue) => {
|
|
1119
|
+
setIntoStore(t, newValue, newest(store));
|
|
1120
|
+
},
|
|
1121
|
+
seek: (t, k) => seekInStore(t, k, newest(store)),
|
|
1122
|
+
json: (t) => getJsonToken(t, newest(store)),
|
|
1123
|
+
run: (t, i = arbitrary()) => actUponStore(t, i, newest(store)),
|
|
1124
|
+
make: (ctx, f, k, ...args) => makeMoleculeInStore(newest(store), ctx, f, k, ...args),
|
|
1125
|
+
dispose: (t) => {
|
|
1126
|
+
disposeFromStore(t, newest(store));
|
|
1127
|
+
},
|
|
1128
|
+
env: () => getEnvironmentData(newest(store)),
|
|
1129
|
+
bond: (f) => growMoleculeInStore(
|
|
1130
|
+
molecule,
|
|
1131
|
+
withdraw(f, store),
|
|
1132
|
+
newest(store)
|
|
1133
|
+
),
|
|
1134
|
+
claim: (below, options) => {
|
|
1135
|
+
const { exclusive } = options;
|
|
1136
|
+
const belowMolecule = newest(store).molecules.get(stringifyJson(below.key));
|
|
1137
|
+
if (belowMolecule) {
|
|
1138
|
+
if (exclusive) {
|
|
1139
|
+
for (const value of belowMolecule.above.values()) {
|
|
1140
|
+
value.below.delete(belowMolecule.stringKey);
|
|
1141
|
+
}
|
|
1142
|
+
belowMolecule.above.clear();
|
|
1143
|
+
belowMolecule.above.set(molecule.stringKey, molecule);
|
|
1144
|
+
molecule.below.set(belowMolecule.stringKey, belowMolecule);
|
|
1145
|
+
} else {
|
|
1146
|
+
belowMolecule.above.set(molecule.stringKey, molecule);
|
|
1147
|
+
molecule.below.set(belowMolecule.stringKey, belowMolecule);
|
|
1148
|
+
}
|
|
1512
1149
|
}
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
var createReadonlySelector = (options, family, store) => {
|
|
1528
|
-
const target = newest(store);
|
|
1529
|
-
const subject = new Subject();
|
|
1530
|
-
const { get, find, seek, json } = registerSelector(options.key, target);
|
|
1531
|
-
const getSelf = () => {
|
|
1532
|
-
const value = options.get({ get, find, seek, json });
|
|
1533
|
-
cacheValue(options.key, value, subject, newest(store));
|
|
1534
|
-
return value;
|
|
1150
|
+
},
|
|
1151
|
+
join: (joinToken) => {
|
|
1152
|
+
const join = getJoin(joinToken, store);
|
|
1153
|
+
join.molecules.set(stringifyJson(key), molecule);
|
|
1154
|
+
molecule.joins.set(joinToken.key, join);
|
|
1155
|
+
return joinToken;
|
|
1156
|
+
},
|
|
1157
|
+
spawn: (f, k, ...p) => makeMoleculeInStore(
|
|
1158
|
+
newest(store),
|
|
1159
|
+
[molecule],
|
|
1160
|
+
withdraw(f, store),
|
|
1161
|
+
k,
|
|
1162
|
+
...p
|
|
1163
|
+
)
|
|
1535
1164
|
};
|
|
1536
|
-
const
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
get: getSelf,
|
|
1540
|
-
type: `readonly_selector`
|
|
1541
|
-
}), family && { family });
|
|
1542
|
-
target.readonlySelectors.set(options.key, readonlySelector);
|
|
1543
|
-
const initialValue = getSelf();
|
|
1544
|
-
store.logger.info(
|
|
1545
|
-
`\u2728`,
|
|
1546
|
-
readonlySelector.type,
|
|
1547
|
-
readonlySelector.key,
|
|
1548
|
-
`=`,
|
|
1549
|
-
initialValue
|
|
1550
|
-
);
|
|
1165
|
+
const family = withdraw(familyToken, store);
|
|
1166
|
+
const Constructor = family.new;
|
|
1167
|
+
molecule.instance = new Constructor(transactors, key, ...params);
|
|
1551
1168
|
const token = {
|
|
1552
|
-
|
|
1553
|
-
|
|
1169
|
+
type: `molecule`,
|
|
1170
|
+
key,
|
|
1171
|
+
family: familyToken
|
|
1554
1172
|
};
|
|
1555
|
-
|
|
1556
|
-
|
|
1173
|
+
const update = {
|
|
1174
|
+
type: `molecule_creation`,
|
|
1175
|
+
token,
|
|
1176
|
+
family: familyToken,
|
|
1177
|
+
context: contextArray,
|
|
1178
|
+
params
|
|
1179
|
+
};
|
|
1180
|
+
if (isRootStore(target)) {
|
|
1181
|
+
family.subject.next(update);
|
|
1182
|
+
} else if (isChildStore(target) && target.on.transactionApplying.state === null) {
|
|
1183
|
+
target.transactionMeta.update.updates.push(update);
|
|
1557
1184
|
}
|
|
1185
|
+
target.moleculeInProgress = null;
|
|
1558
1186
|
return token;
|
|
1559
|
-
}
|
|
1187
|
+
}
|
|
1560
1188
|
|
|
1561
|
-
// internal/src/
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
return value;
|
|
1572
|
-
};
|
|
1573
|
-
const setSelf = (next) => {
|
|
1574
|
-
const oldValue = getSelf();
|
|
1575
|
-
const newValue = become(next)(oldValue);
|
|
1576
|
-
store.logger.info(
|
|
1577
|
-
`\u{1F4DD}`,
|
|
1578
|
-
`selector`,
|
|
1579
|
-
options.key,
|
|
1580
|
-
`set (`,
|
|
1581
|
-
oldValue,
|
|
1582
|
-
`->`,
|
|
1583
|
-
newValue,
|
|
1584
|
-
`)`
|
|
1585
|
-
);
|
|
1586
|
-
cacheValue(options.key, newValue, subject, store);
|
|
1587
|
-
markDone(options.key, store);
|
|
1588
|
-
if (isRootStore(target)) {
|
|
1589
|
-
subject.next({ newValue, oldValue });
|
|
1189
|
+
// internal/src/ingest-updates/ingest-creation-disposal.ts
|
|
1190
|
+
function ingestCreationEvent(update, applying, store) {
|
|
1191
|
+
switch (applying) {
|
|
1192
|
+
case `newValue`: {
|
|
1193
|
+
createInStore(update.token, store);
|
|
1194
|
+
break;
|
|
1195
|
+
}
|
|
1196
|
+
case `oldValue`: {
|
|
1197
|
+
disposeFromStore(update.token, store);
|
|
1198
|
+
break;
|
|
1590
1199
|
}
|
|
1591
|
-
options.set(transactors, newValue);
|
|
1592
|
-
};
|
|
1593
|
-
const mySelector = __spreadValues(__spreadProps(__spreadValues({}, options), {
|
|
1594
|
-
subject,
|
|
1595
|
-
install: (s) => createWritableSelector(options, family, s),
|
|
1596
|
-
get: getSelf,
|
|
1597
|
-
set: setSelf,
|
|
1598
|
-
type: `selector`
|
|
1599
|
-
}), family && { family });
|
|
1600
|
-
target.selectors.set(options.key, mySelector);
|
|
1601
|
-
const initialValue = getSelf();
|
|
1602
|
-
store.logger.info(`\u2728`, mySelector.type, mySelector.key, `=`, initialValue);
|
|
1603
|
-
const token = {
|
|
1604
|
-
key: options.key,
|
|
1605
|
-
type: `selector`
|
|
1606
|
-
};
|
|
1607
|
-
if (family) {
|
|
1608
|
-
token.family = family;
|
|
1609
1200
|
}
|
|
1610
|
-
|
|
1611
|
-
|
|
1201
|
+
}
|
|
1202
|
+
function ingestDisposalEvent(update, applying, store) {
|
|
1203
|
+
switch (applying) {
|
|
1204
|
+
case `newValue`: {
|
|
1205
|
+
disposeFromStore(update.token, store);
|
|
1206
|
+
break;
|
|
1207
|
+
}
|
|
1208
|
+
case `oldValue`: {
|
|
1209
|
+
createInStore(update.token, store);
|
|
1210
|
+
store.valueMap.set(update.token.key, update.value);
|
|
1211
|
+
break;
|
|
1212
|
+
}
|
|
1213
|
+
}
|
|
1214
|
+
}
|
|
1215
|
+
function createInStore(token, store) {
|
|
1216
|
+
if (token.family) {
|
|
1217
|
+
const family = store.families.get(token.family.key);
|
|
1218
|
+
if (family) {
|
|
1219
|
+
const molecule = store.molecules.get(token.family.subKey);
|
|
1220
|
+
if (molecule) {
|
|
1221
|
+
growMoleculeInStore(molecule, family, store);
|
|
1222
|
+
return;
|
|
1223
|
+
}
|
|
1224
|
+
if (store.config.lifespan === `immortal`) {
|
|
1225
|
+
throw new Error(`No molecule found for key "${token.family.subKey}"`);
|
|
1226
|
+
}
|
|
1227
|
+
initFamilyMemberInStore(family, parseJson(token.family.subKey), store);
|
|
1228
|
+
}
|
|
1229
|
+
}
|
|
1230
|
+
}
|
|
1231
|
+
function ingestMoleculeCreationEvent(update, applying, store) {
|
|
1232
|
+
switch (applying) {
|
|
1233
|
+
case `newValue`:
|
|
1234
|
+
makeMoleculeInStore(
|
|
1235
|
+
store,
|
|
1236
|
+
update.context,
|
|
1237
|
+
update.family,
|
|
1238
|
+
update.token.key,
|
|
1239
|
+
...update.params
|
|
1240
|
+
);
|
|
1241
|
+
break;
|
|
1242
|
+
case `oldValue`:
|
|
1243
|
+
disposeFromStore(update.token, store);
|
|
1244
|
+
break;
|
|
1245
|
+
}
|
|
1246
|
+
}
|
|
1247
|
+
function ingestMoleculeDisposalEvent(update, applying, store) {
|
|
1248
|
+
switch (applying) {
|
|
1249
|
+
case `newValue`:
|
|
1250
|
+
disposeFromStore(update.token, store);
|
|
1251
|
+
break;
|
|
1252
|
+
case `oldValue`:
|
|
1253
|
+
{
|
|
1254
|
+
const moleculeToken = makeMoleculeInStore(
|
|
1255
|
+
store,
|
|
1256
|
+
update.context,
|
|
1257
|
+
update.family,
|
|
1258
|
+
update.token.key
|
|
1259
|
+
);
|
|
1260
|
+
for (const [familyKey, value] of update.values) {
|
|
1261
|
+
const memberKey = `${familyKey}(${stringifyJson(moleculeToken.key)})`;
|
|
1262
|
+
const molecule = withdraw(moleculeToken, store);
|
|
1263
|
+
const alreadyCreated = molecule.tokens.has(memberKey);
|
|
1264
|
+
const family = store.families.get(familyKey);
|
|
1265
|
+
if (family && !alreadyCreated) {
|
|
1266
|
+
growMoleculeInStore(molecule, family, store);
|
|
1267
|
+
}
|
|
1268
|
+
store.valueMap.set(memberKey, value);
|
|
1269
|
+
}
|
|
1270
|
+
}
|
|
1271
|
+
break;
|
|
1272
|
+
}
|
|
1273
|
+
}
|
|
1612
1274
|
|
|
1613
|
-
// internal/src/
|
|
1614
|
-
function
|
|
1615
|
-
const
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
store.on.selectorCreation.next(state2);
|
|
1619
|
-
return state2;
|
|
1275
|
+
// internal/src/ingest-updates/ingest-selector-update.ts
|
|
1276
|
+
function ingestSelectorUpdate(applying, selectorUpdate, store) {
|
|
1277
|
+
const updates = applying === `newValue` ? selectorUpdate.atomUpdates : [...selectorUpdate.atomUpdates].reverse();
|
|
1278
|
+
for (const atomUpdate of updates) {
|
|
1279
|
+
ingestAtomUpdate(applying, atomUpdate, store);
|
|
1620
1280
|
}
|
|
1621
|
-
const state = createReadonlySelector(options, void 0, store);
|
|
1622
|
-
store.on.selectorCreation.next(state);
|
|
1623
|
-
return state;
|
|
1624
1281
|
}
|
|
1625
1282
|
|
|
1626
|
-
// internal/src/
|
|
1627
|
-
function
|
|
1283
|
+
// internal/src/ingest-updates/ingest-transaction-update.ts
|
|
1284
|
+
function ingestTransactionUpdate(applying, transactionUpdate, store) {
|
|
1285
|
+
const updates = applying === `newValue` ? transactionUpdate.updates : [...transactionUpdate.updates].reverse();
|
|
1286
|
+
for (const updateFromTransaction of updates) {
|
|
1287
|
+
switch (updateFromTransaction.type) {
|
|
1288
|
+
case `atom_update`:
|
|
1289
|
+
case `selector_update`:
|
|
1290
|
+
ingestAtomUpdate(applying, updateFromTransaction, store);
|
|
1291
|
+
break;
|
|
1292
|
+
case `state_creation`:
|
|
1293
|
+
ingestCreationEvent(updateFromTransaction, applying, store);
|
|
1294
|
+
break;
|
|
1295
|
+
case `state_disposal`:
|
|
1296
|
+
ingestDisposalEvent(updateFromTransaction, applying, store);
|
|
1297
|
+
break;
|
|
1298
|
+
case `molecule_creation`:
|
|
1299
|
+
ingestMoleculeCreationEvent(updateFromTransaction, applying, store);
|
|
1300
|
+
break;
|
|
1301
|
+
case `molecule_disposal`:
|
|
1302
|
+
ingestMoleculeDisposalEvent(updateFromTransaction, applying, store);
|
|
1303
|
+
break;
|
|
1304
|
+
case `transaction_update`:
|
|
1305
|
+
ingestTransactionUpdate(applying, updateFromTransaction, store);
|
|
1306
|
+
break;
|
|
1307
|
+
}
|
|
1308
|
+
}
|
|
1309
|
+
}
|
|
1310
|
+
|
|
1311
|
+
// internal/src/transaction/set-epoch-number.ts
|
|
1312
|
+
function setEpochNumberOfContinuity(continuityKey, newEpoch, store) {
|
|
1313
|
+
const isRoot = isRootStore(store);
|
|
1314
|
+
if (isRoot && continuityKey) {
|
|
1315
|
+
store.transactionMeta.epoch.set(continuityKey, newEpoch);
|
|
1316
|
+
}
|
|
1317
|
+
}
|
|
1318
|
+
function setEpochNumberOfAction(transactionKey, newEpoch, store) {
|
|
1319
|
+
const isRoot = isRootStore(store);
|
|
1320
|
+
if (!isRoot) {
|
|
1321
|
+
return;
|
|
1322
|
+
}
|
|
1323
|
+
const continuityKey = store.transactionMeta.actionContinuities.getRelatedKey(transactionKey);
|
|
1324
|
+
if (continuityKey !== void 0) {
|
|
1325
|
+
store.transactionMeta.epoch.set(continuityKey, newEpoch);
|
|
1326
|
+
}
|
|
1327
|
+
}
|
|
1328
|
+
|
|
1329
|
+
// internal/src/transaction/apply-transaction.ts
|
|
1330
|
+
var applyTransaction = (output, store) => {
|
|
1628
1331
|
var _a;
|
|
1629
|
-
const
|
|
1630
|
-
const {
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
`Tried to dispose selector, but it does not exist in the store.`
|
|
1332
|
+
const child = newest(store);
|
|
1333
|
+
const { parent } = child;
|
|
1334
|
+
if (parent === null || !isChildStore(child) || ((_a = child.transactionMeta) == null ? void 0 : _a.phase) !== `building`) {
|
|
1335
|
+
store.logger.warn(
|
|
1336
|
+
`\u{1F41E}`,
|
|
1337
|
+
`transaction`,
|
|
1338
|
+
`???`,
|
|
1339
|
+
`applyTransaction called outside of a transaction. This is probably a bug in AtomIO.`
|
|
1638
1340
|
);
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1341
|
+
return;
|
|
1342
|
+
}
|
|
1343
|
+
child.transactionMeta.phase = `applying`;
|
|
1344
|
+
child.transactionMeta.update.output = output;
|
|
1345
|
+
parent.child = null;
|
|
1346
|
+
parent.on.transactionApplying.next(child.transactionMeta);
|
|
1347
|
+
const { updates } = child.transactionMeta.update;
|
|
1348
|
+
store.logger.info(
|
|
1349
|
+
`\u{1F6C4}`,
|
|
1350
|
+
`transaction`,
|
|
1351
|
+
child.transactionMeta.update.key,
|
|
1352
|
+
`Applying transaction with ${updates.length} updates:`,
|
|
1353
|
+
updates
|
|
1354
|
+
);
|
|
1355
|
+
ingestTransactionUpdate(`newValue`, child.transactionMeta.update, parent);
|
|
1356
|
+
if (isRootStore(parent)) {
|
|
1357
|
+
setEpochNumberOfAction(
|
|
1358
|
+
child.transactionMeta.update.key,
|
|
1359
|
+
child.transactionMeta.update.epoch,
|
|
1360
|
+
parent
|
|
1645
1361
|
);
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1362
|
+
const myTransaction = withdraw(
|
|
1363
|
+
{ key: child.transactionMeta.update.key, type: `transaction` },
|
|
1364
|
+
store
|
|
1365
|
+
);
|
|
1366
|
+
myTransaction == null ? void 0 : myTransaction.subject.next(child.transactionMeta.update);
|
|
1367
|
+
store.logger.info(
|
|
1368
|
+
`\u{1F6EC}`,
|
|
1369
|
+
`transaction`,
|
|
1370
|
+
child.transactionMeta.update.key,
|
|
1371
|
+
`Finished applying transaction.`
|
|
1372
|
+
);
|
|
1373
|
+
} else if (isChildStore(parent)) {
|
|
1374
|
+
parent.transactionMeta.update.updates.push(child.transactionMeta.update);
|
|
1375
|
+
}
|
|
1376
|
+
parent.on.transactionApplying.next(null);
|
|
1377
|
+
};
|
|
1378
|
+
|
|
1379
|
+
// internal/src/transaction/assign-transaction-to-continuity.ts
|
|
1380
|
+
function assignTransactionToContinuity(continuityKey, transactionKey, store) {
|
|
1381
|
+
const isRoot = isRootStore(store);
|
|
1382
|
+
if (!isRoot) {
|
|
1383
|
+
return;
|
|
1384
|
+
}
|
|
1385
|
+
const { epoch, actionContinuities } = store.transactionMeta;
|
|
1386
|
+
actionContinuities.set(continuityKey, transactionKey);
|
|
1387
|
+
if (!epoch.has(continuityKey)) {
|
|
1388
|
+
epoch.set(continuityKey, -1);
|
|
1389
|
+
}
|
|
1390
|
+
}
|
|
1391
|
+
|
|
1392
|
+
// internal/src/lazy-map.ts
|
|
1393
|
+
var LazyMap = class extends Map {
|
|
1394
|
+
constructor(source) {
|
|
1395
|
+
super();
|
|
1396
|
+
this.source = source;
|
|
1397
|
+
this.deleted = /* @__PURE__ */ new Set();
|
|
1398
|
+
}
|
|
1399
|
+
get(key) {
|
|
1400
|
+
const has = super.has(key);
|
|
1401
|
+
if (has) {
|
|
1402
|
+
return super.get(key);
|
|
1403
|
+
}
|
|
1404
|
+
if (!this.deleted.has(key) && this.source.has(key)) {
|
|
1405
|
+
const value = this.source.get(key);
|
|
1406
|
+
return value;
|
|
1407
|
+
}
|
|
1408
|
+
return void 0;
|
|
1409
|
+
}
|
|
1410
|
+
set(key, value) {
|
|
1411
|
+
this.deleted.delete(key);
|
|
1412
|
+
return super.set(key, value);
|
|
1413
|
+
}
|
|
1414
|
+
hasOwn(key) {
|
|
1415
|
+
return super.has(key);
|
|
1416
|
+
}
|
|
1417
|
+
has(key) {
|
|
1418
|
+
return !this.deleted.has(key) && (super.has(key) || this.source.has(key));
|
|
1419
|
+
}
|
|
1420
|
+
delete(key) {
|
|
1421
|
+
this.deleted.add(key);
|
|
1422
|
+
return super.delete(key);
|
|
1423
|
+
}
|
|
1424
|
+
};
|
|
1425
|
+
|
|
1426
|
+
// internal/src/transaction/build-transaction.ts
|
|
1427
|
+
var buildTransaction = (key, params, store, id) => {
|
|
1428
|
+
const parent = newest(store);
|
|
1429
|
+
const childBase = {
|
|
1430
|
+
parent,
|
|
1431
|
+
child: null,
|
|
1432
|
+
on: parent.on,
|
|
1433
|
+
loggers: parent.loggers,
|
|
1434
|
+
logger: parent.logger,
|
|
1435
|
+
config: parent.config,
|
|
1436
|
+
atoms: new LazyMap(parent.atoms),
|
|
1437
|
+
atomsThatAreDefault: new Set(parent.atomsThatAreDefault),
|
|
1438
|
+
families: new LazyMap(parent.families),
|
|
1439
|
+
operation: { open: false },
|
|
1440
|
+
readonlySelectors: new LazyMap(parent.readonlySelectors),
|
|
1441
|
+
timelines: new LazyMap(parent.timelines),
|
|
1442
|
+
timelineTopics: new Junction(parent.timelineTopics.toJSON()),
|
|
1443
|
+
trackers: /* @__PURE__ */ new Map(),
|
|
1444
|
+
transactions: new LazyMap(parent.transactions),
|
|
1445
|
+
selectorAtoms: new Junction(parent.selectorAtoms.toJSON()),
|
|
1446
|
+
selectorGraph: new Junction(parent.selectorGraph.toJSON(), {
|
|
1447
|
+
makeContentKey: (...keys) => keys.sort().join(`:`)
|
|
1448
|
+
}),
|
|
1449
|
+
selectors: new LazyMap(parent.selectors),
|
|
1450
|
+
valueMap: new LazyMap(parent.valueMap),
|
|
1451
|
+
molecules: new LazyMap(parent.molecules),
|
|
1452
|
+
moleculeFamilies: new LazyMap(parent.moleculeFamilies),
|
|
1453
|
+
moleculeInProgress: parent.moleculeInProgress,
|
|
1454
|
+
miscResources: new LazyMap(parent.miscResources)
|
|
1455
|
+
};
|
|
1456
|
+
const epoch = getEpochNumberOfAction(key, store);
|
|
1457
|
+
const transactionMeta = {
|
|
1458
|
+
phase: `building`,
|
|
1459
|
+
update: {
|
|
1460
|
+
type: `transaction_update`,
|
|
1461
|
+
key,
|
|
1462
|
+
id,
|
|
1463
|
+
epoch: epoch === void 0 ? Number.NaN : epoch + 1,
|
|
1464
|
+
updates: [],
|
|
1465
|
+
params,
|
|
1466
|
+
output: void 0
|
|
1467
|
+
},
|
|
1468
|
+
transactors: {
|
|
1469
|
+
get: (token) => getFromStore(token, child),
|
|
1470
|
+
set: (token, value) => {
|
|
1471
|
+
setIntoStore(token, value, child);
|
|
1472
|
+
},
|
|
1473
|
+
run: (token, identifier = arbitrary()) => actUponStore(token, identifier, child),
|
|
1474
|
+
find: (token, k) => findInStore(token, k, child),
|
|
1475
|
+
seek: (token, k) => seekInStore(token, k, child),
|
|
1476
|
+
json: (token) => getJsonToken(token, child),
|
|
1477
|
+
make: (context, family, k, ...args) => makeMoleculeInStore(child, context, family, k, ...args),
|
|
1478
|
+
dispose: (token) => {
|
|
1479
|
+
disposeFromStore(token, child);
|
|
1480
|
+
},
|
|
1481
|
+
env: () => getEnvironmentData(child)
|
|
1482
|
+
}
|
|
1483
|
+
};
|
|
1484
|
+
const child = Object.assign(childBase, {
|
|
1485
|
+
transactionMeta
|
|
1486
|
+
});
|
|
1487
|
+
parent.child = child;
|
|
1488
|
+
store.logger.info(
|
|
1489
|
+
`\u{1F6EB}`,
|
|
1490
|
+
`transaction`,
|
|
1491
|
+
key,
|
|
1492
|
+
`Building transaction with params:`,
|
|
1493
|
+
params
|
|
1494
|
+
);
|
|
1495
|
+
return child;
|
|
1496
|
+
};
|
|
1497
|
+
|
|
1498
|
+
// internal/src/transaction/create-transaction.ts
|
|
1499
|
+
function createTransaction(options, store) {
|
|
1500
|
+
const newTransaction = {
|
|
1501
|
+
key: options.key,
|
|
1502
|
+
type: `transaction`,
|
|
1503
|
+
run: (params, id) => {
|
|
1504
|
+
const childStore = buildTransaction(options.key, params, store, id);
|
|
1505
|
+
try {
|
|
1506
|
+
const target2 = newest(store);
|
|
1507
|
+
const { transactors } = childStore.transactionMeta;
|
|
1508
|
+
const output = options.do(transactors, ...params);
|
|
1509
|
+
applyTransaction(output, target2);
|
|
1510
|
+
return output;
|
|
1511
|
+
} catch (thrown) {
|
|
1512
|
+
abortTransaction(target);
|
|
1513
|
+
store.logger.warn(`\u{1F4A5}`, `transaction`, options.key, `caught:`, thrown);
|
|
1514
|
+
throw thrown;
|
|
1515
|
+
}
|
|
1516
|
+
},
|
|
1517
|
+
install: (s) => createTransaction(options, s),
|
|
1518
|
+
subject: new Subject()
|
|
1519
|
+
};
|
|
1520
|
+
const target = newest(store);
|
|
1521
|
+
target.transactions.set(newTransaction.key, newTransaction);
|
|
1522
|
+
const token = deposit(newTransaction);
|
|
1523
|
+
store.on.transactionCreation.next(token);
|
|
1524
|
+
return token;
|
|
1525
|
+
}
|
|
1526
|
+
|
|
1527
|
+
// internal/src/transaction/get-epoch-number.ts
|
|
1528
|
+
function getContinuityKey(transactionKey, store) {
|
|
1529
|
+
const isRoot = isRootStore(store);
|
|
1530
|
+
const continuity = isRoot ? store.transactionMeta.actionContinuities.getRelatedKey(transactionKey) : void 0;
|
|
1531
|
+
return continuity;
|
|
1532
|
+
}
|
|
1533
|
+
function getEpochNumberOfContinuity(continuityKey, store) {
|
|
1534
|
+
const isRoot = isRootStore(store);
|
|
1535
|
+
const epoch = isRoot && continuityKey ? store.transactionMeta.epoch.get(continuityKey) : void 0;
|
|
1536
|
+
return epoch;
|
|
1537
|
+
}
|
|
1538
|
+
function getEpochNumberOfAction(transactionKey, store) {
|
|
1539
|
+
const isRoot = isRootStore(store);
|
|
1540
|
+
const continuity = isRoot ? store.transactionMeta.actionContinuities.getRelatedKey(transactionKey) : void 0;
|
|
1541
|
+
const epoch = isRoot && continuity !== void 0 ? store.transactionMeta.epoch.get(continuity) : void 0;
|
|
1542
|
+
return epoch;
|
|
1543
|
+
}
|
|
1544
|
+
|
|
1545
|
+
// internal/src/transaction/index.ts
|
|
1546
|
+
var TRANSACTION_PHASES = [`idle`, `building`, `applying`];
|
|
1547
|
+
|
|
1548
|
+
// internal/src/store/store.ts
|
|
1549
|
+
var Store = class {
|
|
1550
|
+
constructor(config, store = null) {
|
|
1551
|
+
this.parent = null;
|
|
1552
|
+
this.child = null;
|
|
1553
|
+
this.valueMap = /* @__PURE__ */ new Map();
|
|
1554
|
+
this.atoms = /* @__PURE__ */ new Map();
|
|
1555
|
+
this.selectors = /* @__PURE__ */ new Map();
|
|
1556
|
+
this.readonlySelectors = /* @__PURE__ */ new Map();
|
|
1557
|
+
this.atomsThatAreDefault = /* @__PURE__ */ new Set();
|
|
1558
|
+
this.selectorAtoms = new Junction({
|
|
1559
|
+
between: [`selectorKey`, `atomKey`],
|
|
1560
|
+
cardinality: `n:n`
|
|
1561
|
+
});
|
|
1562
|
+
this.selectorGraph = new Junction(
|
|
1563
|
+
{
|
|
1564
|
+
between: [`upstreamSelectorKey`, `downstreamSelectorKey`],
|
|
1565
|
+
cardinality: `n:n`
|
|
1566
|
+
},
|
|
1567
|
+
{
|
|
1568
|
+
makeContentKey: (...keys) => keys.sort().join(`:`)
|
|
1569
|
+
}
|
|
1570
|
+
);
|
|
1571
|
+
this.trackers = /* @__PURE__ */ new Map();
|
|
1572
|
+
this.families = /* @__PURE__ */ new Map();
|
|
1573
|
+
this.transactions = /* @__PURE__ */ new Map();
|
|
1574
|
+
this.transactionMeta = {
|
|
1575
|
+
epoch: /* @__PURE__ */ new Map(),
|
|
1576
|
+
actionContinuities: new Junction({
|
|
1577
|
+
between: [`continuity`, `action`],
|
|
1578
|
+
cardinality: `1:n`
|
|
1579
|
+
})
|
|
1580
|
+
};
|
|
1581
|
+
this.timelines = /* @__PURE__ */ new Map();
|
|
1582
|
+
this.timelineTopics = new Junction({
|
|
1583
|
+
between: [`timelineKey`, `topicKey`],
|
|
1584
|
+
cardinality: `1:n`
|
|
1585
|
+
});
|
|
1586
|
+
this.molecules = /* @__PURE__ */ new Map();
|
|
1587
|
+
this.moleculeFamilies = /* @__PURE__ */ new Map();
|
|
1588
|
+
this.moleculeInProgress = null;
|
|
1589
|
+
this.miscResources = /* @__PURE__ */ new Map();
|
|
1590
|
+
this.on = {
|
|
1591
|
+
atomCreation: new Subject(),
|
|
1592
|
+
atomDisposal: new Subject(),
|
|
1593
|
+
selectorCreation: new Subject(),
|
|
1594
|
+
selectorDisposal: new Subject(),
|
|
1595
|
+
timelineCreation: new Subject(),
|
|
1596
|
+
transactionCreation: new Subject(),
|
|
1597
|
+
transactionApplying: new StatefulSubject(
|
|
1598
|
+
null
|
|
1599
|
+
),
|
|
1600
|
+
operationClose: new Subject(),
|
|
1601
|
+
moleculeCreationStart: new Subject(),
|
|
1602
|
+
moleculeCreationDone: new Subject(),
|
|
1603
|
+
moleculeDisposal: new Subject()
|
|
1604
|
+
};
|
|
1605
|
+
this.operation = { open: false };
|
|
1606
|
+
this.config = {
|
|
1607
|
+
name: `IMPLICIT_STORE`,
|
|
1608
|
+
lifespan: `ephemeral`
|
|
1609
|
+
};
|
|
1610
|
+
this.loggers = [
|
|
1611
|
+
new AtomIOLogger(`warn`, (_, __, key) => !key.includes(`\u{1F441}\u200D\u{1F5E8}`))
|
|
1612
|
+
];
|
|
1613
|
+
this.logger = {
|
|
1614
|
+
error: (...messages) => {
|
|
1615
|
+
for (const logger of this.loggers) logger.error(...messages);
|
|
1616
|
+
},
|
|
1617
|
+
info: (...messages) => {
|
|
1618
|
+
for (const logger of this.loggers) logger.info(...messages);
|
|
1619
|
+
},
|
|
1620
|
+
warn: (...messages) => {
|
|
1621
|
+
for (const logger of this.loggers) logger.warn(...messages);
|
|
1622
|
+
}
|
|
1623
|
+
};
|
|
1624
|
+
if (store !== null) {
|
|
1625
|
+
this.valueMap = new Map(store == null ? void 0 : store.valueMap);
|
|
1626
|
+
this.operation = __spreadValues({}, store == null ? void 0 : store.operation);
|
|
1627
|
+
if (isRootStore(store)) {
|
|
1628
|
+
this.transactionMeta = {
|
|
1629
|
+
epoch: new Map(store == null ? void 0 : store.transactionMeta.epoch),
|
|
1630
|
+
actionContinuities: new Junction(
|
|
1631
|
+
store == null ? void 0 : store.transactionMeta.actionContinuities.toJSON()
|
|
1632
|
+
)
|
|
1633
|
+
};
|
|
1634
|
+
}
|
|
1635
|
+
this.config = __spreadValues(__spreadValues({}, store == null ? void 0 : store.config), config);
|
|
1636
|
+
for (const [, family] of store.families) {
|
|
1637
|
+
family.install(this);
|
|
1638
|
+
}
|
|
1639
|
+
const mutableHelpers = /* @__PURE__ */ new Set();
|
|
1640
|
+
for (const [, atom] of store.atoms) {
|
|
1641
|
+
if (mutableHelpers.has(atom.key)) {
|
|
1642
|
+
continue;
|
|
1643
|
+
}
|
|
1644
|
+
atom.install(this);
|
|
1645
|
+
if (atom.type === `mutable_atom`) {
|
|
1646
|
+
const originalJsonToken = getJsonToken(atom, store);
|
|
1647
|
+
const originalUpdateToken = getUpdateToken(atom);
|
|
1648
|
+
mutableHelpers.add(originalJsonToken.key);
|
|
1649
|
+
mutableHelpers.add(originalUpdateToken.key);
|
|
1650
|
+
}
|
|
1651
|
+
}
|
|
1652
|
+
for (const [, selector] of store.readonlySelectors) {
|
|
1653
|
+
selector.install(this);
|
|
1654
|
+
}
|
|
1655
|
+
for (const [, selector] of store.selectors) {
|
|
1656
|
+
if (mutableHelpers.has(selector.key)) {
|
|
1657
|
+
continue;
|
|
1658
|
+
}
|
|
1659
|
+
selector.install(this);
|
|
1660
|
+
}
|
|
1661
|
+
for (const [, tx] of store.transactions) {
|
|
1662
|
+
tx.install(this);
|
|
1663
|
+
}
|
|
1664
|
+
for (const [, timeline] of store.timelines) {
|
|
1665
|
+
timeline.install(this);
|
|
1666
|
+
}
|
|
1667
|
+
}
|
|
1668
|
+
}
|
|
1669
|
+
};
|
|
1670
|
+
var IMPLICIT = {
|
|
1671
|
+
STORE_INTERNAL: void 0,
|
|
1672
|
+
get STORE() {
|
|
1673
|
+
var _a;
|
|
1674
|
+
return (_a = this.STORE_INTERNAL) != null ? _a : this.STORE_INTERNAL = new Store({
|
|
1675
|
+
name: `IMPLICIT_STORE`,
|
|
1676
|
+
lifespan: `ephemeral`
|
|
1677
|
+
});
|
|
1678
|
+
}
|
|
1679
|
+
};
|
|
1680
|
+
var clearStore = (store) => {
|
|
1681
|
+
const { config } = store;
|
|
1682
|
+
for (const disposable of store.miscResources.values()) {
|
|
1683
|
+
disposable[Symbol.dispose]();
|
|
1684
|
+
}
|
|
1685
|
+
Object.assign(store, new Store(config));
|
|
1686
|
+
store.config = config;
|
|
1687
|
+
};
|
|
1688
|
+
function withdraw(token, store) {
|
|
1689
|
+
let withdrawn;
|
|
1690
|
+
let target = store;
|
|
1691
|
+
while (target !== null) {
|
|
1692
|
+
switch (token.type) {
|
|
1693
|
+
case `atom`:
|
|
1694
|
+
case `mutable_atom`:
|
|
1695
|
+
withdrawn = target.atoms.get(token.key);
|
|
1696
|
+
break;
|
|
1697
|
+
case `selector`:
|
|
1698
|
+
withdrawn = target.selectors.get(token.key);
|
|
1699
|
+
break;
|
|
1700
|
+
case `readonly_selector`:
|
|
1701
|
+
withdrawn = target.readonlySelectors.get(token.key);
|
|
1702
|
+
break;
|
|
1703
|
+
case `atom_family`:
|
|
1704
|
+
case `mutable_atom_family`:
|
|
1705
|
+
case `selector_family`:
|
|
1706
|
+
case `readonly_selector_family`:
|
|
1707
|
+
withdrawn = target.families.get(token.key);
|
|
1708
|
+
break;
|
|
1709
|
+
case `timeline`:
|
|
1710
|
+
withdrawn = target.timelines.get(token.key);
|
|
1711
|
+
break;
|
|
1712
|
+
case `transaction`:
|
|
1713
|
+
withdrawn = target.transactions.get(token.key);
|
|
1660
1714
|
break;
|
|
1661
|
-
case `
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
store
|
|
1667
|
-
);
|
|
1668
|
-
family.subject.next({
|
|
1669
|
-
type: `state_disposal`,
|
|
1670
|
-
token: selectorToken
|
|
1671
|
-
});
|
|
1672
|
-
}
|
|
1715
|
+
case `molecule`:
|
|
1716
|
+
withdrawn = target.molecules.get(stringifyJson(token.key));
|
|
1717
|
+
break;
|
|
1718
|
+
case `molecule_family`:
|
|
1719
|
+
withdrawn = target.moleculeFamilies.get(token.key);
|
|
1673
1720
|
break;
|
|
1674
1721
|
}
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
const downstreamTokens = target.selectorGraph.getRelationEntries({ upstreamSelectorKey: key }).filter(([_, { source }]) => source === key).map(
|
|
1678
|
-
([downstreamSelectorKey]) => {
|
|
1679
|
-
var _a2;
|
|
1680
|
-
return (_a2 = target.selectors.get(downstreamSelectorKey)) != null ? _a2 : target.readonlySelectors.get(downstreamSelectorKey);
|
|
1681
|
-
}
|
|
1682
|
-
);
|
|
1683
|
-
for (const downstreamToken of downstreamTokens) {
|
|
1684
|
-
if (downstreamToken) {
|
|
1685
|
-
disposeSelector(downstreamToken, store);
|
|
1686
|
-
}
|
|
1687
|
-
}
|
|
1688
|
-
target.selectorGraph.delete(key);
|
|
1689
|
-
store.logger.info(`\u{1F525}`, selectorToken.type, key, `deleted`);
|
|
1690
|
-
if (isChildStore(target) && target.transactionMeta.phase === `building`) {
|
|
1691
|
-
target.transactionMeta.update.updates.push({
|
|
1692
|
-
type: `state_disposal`,
|
|
1693
|
-
token: selectorToken
|
|
1694
|
-
});
|
|
1695
|
-
} else {
|
|
1696
|
-
store.on.selectorDisposal.next(selectorToken);
|
|
1722
|
+
if (withdrawn) {
|
|
1723
|
+
return withdrawn;
|
|
1697
1724
|
}
|
|
1725
|
+
target = target.child;
|
|
1698
1726
|
}
|
|
1727
|
+
throw new NotFoundError(token, store);
|
|
1699
1728
|
}
|
|
1700
1729
|
|
|
1701
1730
|
// internal/src/subscribe/recall-state.ts
|
|
@@ -1892,7 +1921,7 @@ var Tracker = class {
|
|
|
1892
1921
|
subscribeToState(
|
|
1893
1922
|
latestUpdateState,
|
|
1894
1923
|
({ newValue, oldValue }) => {
|
|
1895
|
-
const timelineId = target.
|
|
1924
|
+
const timelineId = target.timelineTopics.getRelatedKey(
|
|
1896
1925
|
latestUpdateState.key
|
|
1897
1926
|
);
|
|
1898
1927
|
if (timelineId) {
|
|
@@ -2343,6 +2372,10 @@ function disposeAtom(atomToken, store) {
|
|
|
2343
2372
|
token: atomToken,
|
|
2344
2373
|
value: lastValue
|
|
2345
2374
|
});
|
|
2375
|
+
const molecule = target.molecules.get(atom.family.subKey);
|
|
2376
|
+
if (molecule) {
|
|
2377
|
+
molecule.tokens.delete(key);
|
|
2378
|
+
}
|
|
2346
2379
|
target.atoms.delete(key);
|
|
2347
2380
|
target.valueMap.delete(key);
|
|
2348
2381
|
const selectorKeys = target.selectorAtoms.getRelatedKeys(key);
|
|
@@ -2356,7 +2389,7 @@ function disposeAtom(atomToken, store) {
|
|
|
2356
2389
|
}
|
|
2357
2390
|
target.selectorAtoms.delete(key);
|
|
2358
2391
|
target.atomsThatAreDefault.delete(key);
|
|
2359
|
-
target.
|
|
2392
|
+
target.timelineTopics.delete(key);
|
|
2360
2393
|
if (atomToken.type === `mutable_atom`) {
|
|
2361
2394
|
const updateToken = getUpdateToken(atomToken);
|
|
2362
2395
|
disposeAtom(updateToken, store);
|
|
@@ -2373,26 +2406,123 @@ function disposeAtom(atomToken, store) {
|
|
|
2373
2406
|
}
|
|
2374
2407
|
}
|
|
2375
2408
|
}
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
2409
|
+
function createTimeline(options, store, data) {
|
|
2410
|
+
var _a;
|
|
2411
|
+
const tl = __spreadProps(__spreadValues({
|
|
2412
|
+
type: `timeline`,
|
|
2413
|
+
key: options.key,
|
|
2414
|
+
at: 0,
|
|
2415
|
+
timeTraveling: null,
|
|
2416
|
+
selectorTime: null,
|
|
2417
|
+
transactionKey: null
|
|
2418
|
+
}, data), {
|
|
2419
|
+
history: (_a = data == null ? void 0 : data.history.map((update) => __spreadValues({}, update))) != null ? _a : [],
|
|
2420
|
+
install: (s) => createTimeline(options, s, tl),
|
|
2421
|
+
subject: new Subject(),
|
|
2422
|
+
subscriptions: /* @__PURE__ */ new Map()
|
|
2423
|
+
});
|
|
2424
|
+
if (options.shouldCapture) {
|
|
2425
|
+
tl.shouldCapture = options.shouldCapture;
|
|
2426
|
+
}
|
|
2427
|
+
const timelineKey = options.key;
|
|
2428
|
+
const target = newest(store);
|
|
2429
|
+
for (const initialTopic of options.scope) {
|
|
2430
|
+
switch (initialTopic.type) {
|
|
2431
|
+
case `atom`:
|
|
2432
|
+
case `mutable_atom`:
|
|
2433
|
+
{
|
|
2434
|
+
const atomToken = initialTopic;
|
|
2435
|
+
const atomKey = atomToken.key;
|
|
2436
|
+
let existingTimelineKey = target.timelineTopics.getRelatedKey(atomKey);
|
|
2437
|
+
if (`family` in atomToken) {
|
|
2438
|
+
const familyKey = atomToken.family.key;
|
|
2439
|
+
existingTimelineKey = target.timelineTopics.getRelatedKey(familyKey);
|
|
2440
|
+
if (existingTimelineKey) {
|
|
2441
|
+
store.logger.error(
|
|
2442
|
+
`\u274C`,
|
|
2443
|
+
`timeline`,
|
|
2444
|
+
options.key,
|
|
2445
|
+
`Failed to add atom "${atomKey}" because its family "${familyKey}" already belongs to timeline "${existingTimelineKey}"`
|
|
2446
|
+
);
|
|
2447
|
+
continue;
|
|
2448
|
+
}
|
|
2449
|
+
}
|
|
2450
|
+
if (existingTimelineKey) {
|
|
2451
|
+
store.logger.error(
|
|
2452
|
+
`\u274C`,
|
|
2453
|
+
`timeline`,
|
|
2454
|
+
options.key,
|
|
2455
|
+
`Failed to add atom "${atomKey}" because it already belongs to timeline "${existingTimelineKey}"`
|
|
2456
|
+
);
|
|
2457
|
+
continue;
|
|
2458
|
+
}
|
|
2459
|
+
addAtomToTimeline(atomToken, tl, store);
|
|
2460
|
+
}
|
|
2461
|
+
break;
|
|
2462
|
+
case `atom_family`:
|
|
2463
|
+
case `mutable_atom_family`:
|
|
2464
|
+
{
|
|
2465
|
+
const familyToken = initialTopic;
|
|
2466
|
+
const familyKey = familyToken.key;
|
|
2467
|
+
const existingTimelineKey = target.timelineTopics.getRelatedKey(familyKey);
|
|
2468
|
+
if (existingTimelineKey) {
|
|
2469
|
+
store.logger.error(
|
|
2470
|
+
`\u274C`,
|
|
2471
|
+
`timeline`,
|
|
2472
|
+
options.key,
|
|
2473
|
+
`Failed to add atom family "${familyKey}" because it already belongs to timeline "${existingTimelineKey}"`
|
|
2474
|
+
);
|
|
2475
|
+
continue;
|
|
2476
|
+
}
|
|
2477
|
+
addAtomFamilyToTimeline(familyToken, tl, store);
|
|
2478
|
+
}
|
|
2479
|
+
break;
|
|
2480
|
+
case `molecule_family`:
|
|
2481
|
+
{
|
|
2482
|
+
const familyToken = initialTopic;
|
|
2483
|
+
const familyKey = familyToken.key;
|
|
2484
|
+
const existingTimelineKey = target.timelineTopics.getRelatedKey(familyKey);
|
|
2485
|
+
if (existingTimelineKey) {
|
|
2486
|
+
store.logger.error(
|
|
2487
|
+
`\u274C`,
|
|
2488
|
+
`timeline`,
|
|
2489
|
+
options.key,
|
|
2490
|
+
`Failed to add molecule family "${familyKey}" because it already belongs to timeline "${existingTimelineKey}"`
|
|
2491
|
+
);
|
|
2492
|
+
continue;
|
|
2493
|
+
}
|
|
2494
|
+
addMoleculeFamilyToTimeline(familyToken, tl, store);
|
|
2495
|
+
}
|
|
2496
|
+
break;
|
|
2497
|
+
}
|
|
2498
|
+
}
|
|
2499
|
+
store.timelines.set(options.key, tl);
|
|
2500
|
+
const token = {
|
|
2501
|
+
key: timelineKey,
|
|
2502
|
+
type: `timeline`
|
|
2503
|
+
};
|
|
2504
|
+
store.on.timelineCreation.next(token);
|
|
2505
|
+
return token;
|
|
2506
|
+
}
|
|
2507
|
+
function addAtomToTimeline(atomToken, tl, store) {
|
|
2379
2508
|
let maybeAtom = withdraw(atomToken, store);
|
|
2380
2509
|
if (maybeAtom.type === `mutable_atom`) {
|
|
2381
2510
|
const updateToken = getUpdateToken(maybeAtom);
|
|
2382
2511
|
maybeAtom = withdraw(updateToken, store);
|
|
2383
2512
|
}
|
|
2384
2513
|
const atom = maybeAtom;
|
|
2385
|
-
store.
|
|
2514
|
+
store.timelineTopics.set(
|
|
2515
|
+
{ topicKey: atom.key, timelineKey: tl.key },
|
|
2516
|
+
{ topicType: `atom` }
|
|
2517
|
+
);
|
|
2386
2518
|
tl.subscriptions.set(
|
|
2387
2519
|
atom.key,
|
|
2388
2520
|
atom.subject.subscribe(`timeline`, (update) => {
|
|
2389
|
-
var _a, _b, _c, _d, _e
|
|
2521
|
+
var _a, _b, _c, _d, _e;
|
|
2390
2522
|
const target = newest(store);
|
|
2391
2523
|
const currentSelectorKey = store.operation.open && store.operation.token.type === `selector` ? store.operation.token.key : null;
|
|
2392
2524
|
const currentSelectorTime = store.operation.open && store.operation.token.type === `selector` ? store.operation.time : null;
|
|
2393
|
-
const
|
|
2394
|
-
const currentTransactionKey = (_a = transactionApplying.state) == null ? void 0 : _a.update.key;
|
|
2395
|
-
const currentTransactionInstanceId = (_b = transactionApplying.state) == null ? void 0 : _b.update.id;
|
|
2525
|
+
const txUpdateInProgress = (_a = target.on.transactionApplying.state) == null ? void 0 : _a.update;
|
|
2396
2526
|
store.logger.info(
|
|
2397
2527
|
`\u23F3`,
|
|
2398
2528
|
`timeline`,
|
|
@@ -2403,109 +2533,11 @@ var addAtomToTimeline = (atomToken, tl, store) => {
|
|
|
2403
2533
|
update.oldValue,
|
|
2404
2534
|
`->`,
|
|
2405
2535
|
update.newValue,
|
|
2406
|
-
|
|
2536
|
+
txUpdateInProgress ? `in transaction "${txUpdateInProgress.key}"` : currentSelectorKey ? `in selector "${currentSelectorKey}"` : ``
|
|
2407
2537
|
);
|
|
2408
2538
|
if (tl.timeTraveling === null) {
|
|
2409
|
-
if (
|
|
2410
|
-
|
|
2411
|
-
if (mostRecentUpdate === void 0) {
|
|
2412
|
-
throw new Error(
|
|
2413
|
-
`Timeline "${tl.key}" has a selectorTime, but no history. This is most likely a bug in AtomIO.`
|
|
2414
|
-
);
|
|
2415
|
-
}
|
|
2416
|
-
}
|
|
2417
|
-
if (currentTransactionKey) {
|
|
2418
|
-
const txToken = {
|
|
2419
|
-
key: currentTransactionKey,
|
|
2420
|
-
type: `transaction`
|
|
2421
|
-
};
|
|
2422
|
-
const currentTransaction = withdraw(txToken, store);
|
|
2423
|
-
if (tl.transactionKey !== currentTransactionKey) {
|
|
2424
|
-
if (tl.transactionKey) {
|
|
2425
|
-
store.logger.error(
|
|
2426
|
-
`\u{1F41E}`,
|
|
2427
|
-
`timeline`,
|
|
2428
|
-
tl.key,
|
|
2429
|
-
`unable to resolve transaction "${tl.transactionKey}. This is probably a bug in AtomIO.`
|
|
2430
|
-
);
|
|
2431
|
-
}
|
|
2432
|
-
tl.transactionKey = currentTransactionKey;
|
|
2433
|
-
const unsubscribe = currentTransaction.subject.subscribe(
|
|
2434
|
-
`timeline:${tl.key}`,
|
|
2435
|
-
(transactionUpdate) => {
|
|
2436
|
-
var _a2, _b2;
|
|
2437
|
-
unsubscribe();
|
|
2438
|
-
if (tl.timeTraveling === null && currentTransactionInstanceId) {
|
|
2439
|
-
if (tl.at !== tl.history.length) {
|
|
2440
|
-
tl.history.splice(tl.at);
|
|
2441
|
-
}
|
|
2442
|
-
const filterUpdates = (updates2) => updates2.filter((updateFromTx) => {
|
|
2443
|
-
var _a3, _b3;
|
|
2444
|
-
const newestStore = newest(store);
|
|
2445
|
-
if (`updates` in updateFromTx) {
|
|
2446
|
-
return true;
|
|
2447
|
-
}
|
|
2448
|
-
const atomOrFamilyKeys = newestStore.timelineAtoms.getRelatedKeys(tl.key);
|
|
2449
|
-
if (!atomOrFamilyKeys) {
|
|
2450
|
-
return false;
|
|
2451
|
-
}
|
|
2452
|
-
let key;
|
|
2453
|
-
let familyKey;
|
|
2454
|
-
switch (updateFromTx.type) {
|
|
2455
|
-
case `state_creation`:
|
|
2456
|
-
case `state_disposal`:
|
|
2457
|
-
key = updateFromTx.token.key;
|
|
2458
|
-
familyKey = (_a3 = updateFromTx.token.family) == null ? void 0 : _a3.key;
|
|
2459
|
-
break;
|
|
2460
|
-
case `molecule_creation`:
|
|
2461
|
-
case `molecule_disposal`:
|
|
2462
|
-
break;
|
|
2463
|
-
default:
|
|
2464
|
-
key = updateFromTx.key;
|
|
2465
|
-
familyKey = (_b3 = updateFromTx.family) == null ? void 0 : _b3.key;
|
|
2466
|
-
break;
|
|
2467
|
-
}
|
|
2468
|
-
if (key === void 0) {
|
|
2469
|
-
return false;
|
|
2470
|
-
}
|
|
2471
|
-
if (atomOrFamilyKeys.has(key)) {
|
|
2472
|
-
return true;
|
|
2473
|
-
}
|
|
2474
|
-
if (familyKey !== void 0) {
|
|
2475
|
-
return atomOrFamilyKeys.has(familyKey);
|
|
2476
|
-
}
|
|
2477
|
-
return false;
|
|
2478
|
-
}).map((updateFromTx) => {
|
|
2479
|
-
if (`updates` in updateFromTx) {
|
|
2480
|
-
return __spreadProps(__spreadValues({}, updateFromTx), {
|
|
2481
|
-
updates: filterUpdates(updateFromTx.updates)
|
|
2482
|
-
});
|
|
2483
|
-
}
|
|
2484
|
-
return updateFromTx;
|
|
2485
|
-
});
|
|
2486
|
-
const updates = filterUpdates(transactionUpdate.updates);
|
|
2487
|
-
const timelineTransactionUpdate = __spreadProps(__spreadValues({
|
|
2488
|
-
timestamp: Date.now()
|
|
2489
|
-
}, transactionUpdate), {
|
|
2490
|
-
updates
|
|
2491
|
-
});
|
|
2492
|
-
const willCapture = (_b2 = (_a2 = tl.shouldCapture) == null ? void 0 : _a2.call(tl, timelineTransactionUpdate, tl)) != null ? _b2 : true;
|
|
2493
|
-
if (willCapture) {
|
|
2494
|
-
tl.history.push(timelineTransactionUpdate);
|
|
2495
|
-
tl.at = tl.history.length;
|
|
2496
|
-
tl.subject.next(timelineTransactionUpdate);
|
|
2497
|
-
}
|
|
2498
|
-
}
|
|
2499
|
-
tl.transactionKey = null;
|
|
2500
|
-
store.logger.info(
|
|
2501
|
-
`\u231B`,
|
|
2502
|
-
`timeline`,
|
|
2503
|
-
tl.key,
|
|
2504
|
-
`got a transaction_update "${transactionUpdate.key}"`
|
|
2505
|
-
);
|
|
2506
|
-
}
|
|
2507
|
-
);
|
|
2508
|
-
}
|
|
2539
|
+
if (txUpdateInProgress) {
|
|
2540
|
+
joinTransaction(tl, txUpdateInProgress, store);
|
|
2509
2541
|
} else if (currentSelectorKey && currentSelectorTime) {
|
|
2510
2542
|
let latestUpdate = tl.history.at(-1);
|
|
2511
2543
|
if (currentSelectorTime !== tl.selectorTime) {
|
|
@@ -2548,7 +2580,7 @@ var addAtomToTimeline = (atomToken, tl, store) => {
|
|
|
2548
2580
|
}
|
|
2549
2581
|
}
|
|
2550
2582
|
if (latestUpdate) {
|
|
2551
|
-
const willCaptureSelectorUpdate = (
|
|
2583
|
+
const willCaptureSelectorUpdate = (_c = (_b = tl.shouldCapture) == null ? void 0 : _b.call(tl, latestUpdate, tl)) != null ? _c : true;
|
|
2552
2584
|
if (willCaptureSelectorUpdate) {
|
|
2553
2585
|
tl.subject.next(latestUpdate);
|
|
2554
2586
|
} else {
|
|
@@ -2572,7 +2604,7 @@ var addAtomToTimeline = (atomToken, tl, store) => {
|
|
|
2572
2604
|
if (atom.family) {
|
|
2573
2605
|
atomUpdate.family = atom.family;
|
|
2574
2606
|
}
|
|
2575
|
-
const willCapture = (
|
|
2607
|
+
const willCapture = (_e = (_d = tl.shouldCapture) == null ? void 0 : _d.call(tl, atomUpdate, tl)) != null ? _e : true;
|
|
2576
2608
|
store.logger.info(
|
|
2577
2609
|
`\u231B`,
|
|
2578
2610
|
`timeline`,
|
|
@@ -2588,181 +2620,207 @@ var addAtomToTimeline = (atomToken, tl, store) => {
|
|
|
2588
2620
|
}
|
|
2589
2621
|
})
|
|
2590
2622
|
);
|
|
2591
|
-
}
|
|
2592
|
-
function
|
|
2593
|
-
var _a
|
|
2594
|
-
const
|
|
2595
|
-
|
|
2596
|
-
key:
|
|
2597
|
-
|
|
2598
|
-
|
|
2599
|
-
|
|
2600
|
-
|
|
2601
|
-
|
|
2602
|
-
|
|
2603
|
-
|
|
2604
|
-
|
|
2605
|
-
|
|
2606
|
-
|
|
2607
|
-
|
|
2608
|
-
|
|
2623
|
+
}
|
|
2624
|
+
function addAtomFamilyToTimeline(atomFamilyToken, tl, store) {
|
|
2625
|
+
var _a;
|
|
2626
|
+
const family = withdraw(atomFamilyToken, store);
|
|
2627
|
+
store.timelineTopics.set(
|
|
2628
|
+
{ topicKey: family.key, timelineKey: tl.key },
|
|
2629
|
+
{ topicType: `atom_family` }
|
|
2630
|
+
);
|
|
2631
|
+
tl.subscriptions.set(
|
|
2632
|
+
family.key,
|
|
2633
|
+
family.subject.subscribe(`timeline`, (creationOrDisposal) => {
|
|
2634
|
+
handleStateLifecycleEvent(creationOrDisposal, tl, store);
|
|
2635
|
+
})
|
|
2636
|
+
);
|
|
2637
|
+
for (const atom of store.atoms.values()) {
|
|
2638
|
+
if (((_a = atom.family) == null ? void 0 : _a.key) === family.key) {
|
|
2639
|
+
addAtomToTimeline(atom, tl, store);
|
|
2640
|
+
}
|
|
2609
2641
|
}
|
|
2610
|
-
|
|
2611
|
-
|
|
2612
|
-
|
|
2613
|
-
|
|
2614
|
-
|
|
2615
|
-
|
|
2616
|
-
|
|
2617
|
-
|
|
2618
|
-
|
|
2619
|
-
|
|
2620
|
-
|
|
2621
|
-
|
|
2622
|
-
|
|
2623
|
-
|
|
2624
|
-
|
|
2625
|
-
|
|
2626
|
-
|
|
2627
|
-
|
|
2642
|
+
}
|
|
2643
|
+
function addMoleculeFamilyToTimeline(familyToken, tl, store) {
|
|
2644
|
+
store.timelineTopics.set(
|
|
2645
|
+
{ topicKey: familyToken.key, timelineKey: tl.key },
|
|
2646
|
+
{ topicType: `molecule_family` }
|
|
2647
|
+
);
|
|
2648
|
+
const family = store.moleculeFamilies.get(familyToken.key);
|
|
2649
|
+
if (family) {
|
|
2650
|
+
tl.subscriptions.set(
|
|
2651
|
+
familyToken.key,
|
|
2652
|
+
family.subject.subscribe(`timeline:${tl.key}`, (creationOrDisposal) => {
|
|
2653
|
+
var _a, _b, _c, _d;
|
|
2654
|
+
store.logger.info(
|
|
2655
|
+
`\u{1F41E}`,
|
|
2656
|
+
`timeline`,
|
|
2657
|
+
tl.key,
|
|
2658
|
+
`got a molecule creation or disposal`,
|
|
2659
|
+
creationOrDisposal
|
|
2660
|
+
);
|
|
2661
|
+
switch (creationOrDisposal.type) {
|
|
2662
|
+
case `molecule_creation`:
|
|
2663
|
+
{
|
|
2664
|
+
store.timelineTopics.set(
|
|
2665
|
+
{
|
|
2666
|
+
topicKey: creationOrDisposal.token.key,
|
|
2667
|
+
timelineKey: tl.key
|
|
2668
|
+
},
|
|
2669
|
+
{ topicType: `molecule` }
|
|
2670
|
+
);
|
|
2671
|
+
const txUpdateInProgress = (_a = newest(store).on.transactionApplying.state) == null ? void 0 : _a.update;
|
|
2672
|
+
if (txUpdateInProgress) {
|
|
2673
|
+
joinTransaction(tl, txUpdateInProgress, store);
|
|
2674
|
+
} else if (tl.timeTraveling === null) {
|
|
2675
|
+
const event = Object.assign(creationOrDisposal, {
|
|
2676
|
+
timestamp: Date.now()
|
|
2677
|
+
});
|
|
2678
|
+
tl.history.push(event);
|
|
2679
|
+
tl.at = tl.history.length;
|
|
2680
|
+
tl.subject.next(event);
|
|
2628
2681
|
}
|
|
2629
|
-
|
|
2630
|
-
|
|
2631
|
-
|
|
2632
|
-
|
|
2633
|
-
|
|
2634
|
-
|
|
2635
|
-
|
|
2636
|
-
|
|
2637
|
-
|
|
2638
|
-
|
|
2639
|
-
|
|
2640
|
-
|
|
2641
|
-
|
|
2642
|
-
|
|
2643
|
-
|
|
2644
|
-
|
|
2645
|
-
|
|
2646
|
-
}
|
|
2647
|
-
if (`family` in atom) {
|
|
2648
|
-
const familyTimelineKey = target.timelineAtoms.getRelatedKey(
|
|
2649
|
-
atom.family.key
|
|
2650
|
-
);
|
|
2651
|
-
if (familyTimelineKey) {
|
|
2652
|
-
store.logger.error(
|
|
2653
|
-
`\u274C`,
|
|
2654
|
-
`timeline`,
|
|
2655
|
-
options.key,
|
|
2656
|
-
`Failed to add atom "${atom.key}" because its family "${atom.family.key}" already belongs to timeline "${familyTimelineKey}"`
|
|
2682
|
+
const molecule = withdraw(creationOrDisposal.token, store);
|
|
2683
|
+
for (const token of molecule.tokens.values()) {
|
|
2684
|
+
switch (token.type) {
|
|
2685
|
+
case `atom`:
|
|
2686
|
+
case `mutable_atom`:
|
|
2687
|
+
addAtomToTimeline(token, tl, store);
|
|
2688
|
+
break;
|
|
2689
|
+
}
|
|
2690
|
+
}
|
|
2691
|
+
tl.subscriptions.set(
|
|
2692
|
+
molecule.key,
|
|
2693
|
+
molecule.subject.subscribe(
|
|
2694
|
+
`timeline:${tl.key}`,
|
|
2695
|
+
(stateCreationOrDisposal) => {
|
|
2696
|
+
handleStateLifecycleEvent(stateCreationOrDisposal, tl, store);
|
|
2697
|
+
}
|
|
2698
|
+
)
|
|
2657
2699
|
);
|
|
2658
|
-
continue;
|
|
2659
2700
|
}
|
|
2701
|
+
break;
|
|
2702
|
+
case `molecule_disposal`:
|
|
2703
|
+
{
|
|
2704
|
+
const txUpdateInProgress = (_b = newest(store).on.transactionApplying.state) == null ? void 0 : _b.update;
|
|
2705
|
+
if (txUpdateInProgress) {
|
|
2706
|
+
joinTransaction(tl, txUpdateInProgress, store);
|
|
2707
|
+
} else if (tl.timeTraveling === null) {
|
|
2708
|
+
const event = Object.assign(creationOrDisposal, {
|
|
2709
|
+
timestamp: Date.now()
|
|
2710
|
+
});
|
|
2711
|
+
tl.history.push(event);
|
|
2712
|
+
tl.at = tl.history.length;
|
|
2713
|
+
tl.subject.next(event);
|
|
2714
|
+
}
|
|
2715
|
+
const moleculeKey = creationOrDisposal.token.key;
|
|
2716
|
+
(_c = tl.subscriptions.get(moleculeKey)) == null ? void 0 : _c();
|
|
2717
|
+
tl.subscriptions.delete(moleculeKey);
|
|
2718
|
+
for (const [familyKey] of creationOrDisposal.values) {
|
|
2719
|
+
const stateKey = `${familyKey}(${stringifyJson(moleculeKey)})`;
|
|
2720
|
+
(_d = tl.subscriptions.get(stateKey)) == null ? void 0 : _d();
|
|
2721
|
+
tl.subscriptions.delete(stateKey);
|
|
2722
|
+
store.timelineTopics.delete(stateKey);
|
|
2723
|
+
}
|
|
2724
|
+
}
|
|
2725
|
+
break;
|
|
2726
|
+
}
|
|
2727
|
+
})
|
|
2728
|
+
);
|
|
2729
|
+
}
|
|
2730
|
+
}
|
|
2731
|
+
function joinTransaction(tl, txUpdateInProgress, store) {
|
|
2732
|
+
const currentTxKey = txUpdateInProgress.key;
|
|
2733
|
+
const currentTxInstanceId = txUpdateInProgress.id;
|
|
2734
|
+
const currentTxToken = {
|
|
2735
|
+
key: currentTxKey,
|
|
2736
|
+
type: `transaction`
|
|
2737
|
+
};
|
|
2738
|
+
const currentTransaction = withdraw(currentTxToken, store);
|
|
2739
|
+
if (currentTxKey && tl.transactionKey === null) {
|
|
2740
|
+
tl.transactionKey = currentTxKey;
|
|
2741
|
+
const unsubscribe = currentTransaction.subject.subscribe(
|
|
2742
|
+
`timeline:${tl.key}`,
|
|
2743
|
+
(transactionUpdate) => {
|
|
2744
|
+
var _a, _b;
|
|
2745
|
+
unsubscribe();
|
|
2746
|
+
tl.transactionKey = null;
|
|
2747
|
+
if (tl.timeTraveling === null && currentTxInstanceId) {
|
|
2748
|
+
if (tl.at !== tl.history.length) {
|
|
2749
|
+
tl.history.splice(tl.at);
|
|
2660
2750
|
}
|
|
2661
|
-
const
|
|
2662
|
-
|
|
2663
|
-
|
|
2664
|
-
|
|
2665
|
-
|
|
2666
|
-
|
|
2667
|
-
|
|
2668
|
-
|
|
2669
|
-
|
|
2751
|
+
const timelineTopics = store.timelineTopics.getRelatedKeys(tl.key);
|
|
2752
|
+
const updates = filterTransactionUpdates(
|
|
2753
|
+
transactionUpdate.updates,
|
|
2754
|
+
timelineTopics
|
|
2755
|
+
);
|
|
2756
|
+
const timelineTransactionUpdate = __spreadProps(__spreadValues({
|
|
2757
|
+
timestamp: Date.now()
|
|
2758
|
+
}, transactionUpdate), {
|
|
2759
|
+
updates
|
|
2760
|
+
});
|
|
2761
|
+
const willCapture = (_b = (_a = tl.shouldCapture) == null ? void 0 : _a.call(tl, timelineTransactionUpdate, tl)) != null ? _b : true;
|
|
2762
|
+
if (willCapture) {
|
|
2763
|
+
tl.history.push(timelineTransactionUpdate);
|
|
2764
|
+
tl.at = tl.history.length;
|
|
2765
|
+
tl.subject.next(timelineTransactionUpdate);
|
|
2670
2766
|
}
|
|
2671
|
-
addAtomToTimeline(atom, tl, store);
|
|
2672
2767
|
}
|
|
2768
|
+
}
|
|
2769
|
+
);
|
|
2770
|
+
}
|
|
2771
|
+
}
|
|
2772
|
+
function filterTransactionUpdates(updates, timelineTopics) {
|
|
2773
|
+
return updates.filter((updateFromTx) => {
|
|
2774
|
+
if (updateFromTx.type === `transaction_update`) {
|
|
2775
|
+
return true;
|
|
2776
|
+
}
|
|
2777
|
+
let key;
|
|
2778
|
+
switch (updateFromTx.type) {
|
|
2779
|
+
case `state_creation`:
|
|
2780
|
+
case `state_disposal`:
|
|
2781
|
+
case `molecule_creation`:
|
|
2782
|
+
case `molecule_disposal`:
|
|
2783
|
+
key = updateFromTx.token.key;
|
|
2673
2784
|
break;
|
|
2674
|
-
|
|
2675
|
-
|
|
2676
|
-
const family = store.moleculeFamilies.get(tokenOrFamily.key);
|
|
2677
|
-
if (family) {
|
|
2678
|
-
tl.subscriptions.set(
|
|
2679
|
-
tokenOrFamily.key,
|
|
2680
|
-
family.subject.subscribe(
|
|
2681
|
-
`timeline:${options.key}`,
|
|
2682
|
-
(creationOrDisposal) => {
|
|
2683
|
-
var _a2, _b2;
|
|
2684
|
-
switch (creationOrDisposal.type) {
|
|
2685
|
-
case `molecule_creation`:
|
|
2686
|
-
{
|
|
2687
|
-
const molecule = store.molecules.get(
|
|
2688
|
-
stringifyJson(creationOrDisposal.token.key)
|
|
2689
|
-
);
|
|
2690
|
-
if (molecule) {
|
|
2691
|
-
const event = Object.assign(creationOrDisposal, {
|
|
2692
|
-
timestamp: Date.now()
|
|
2693
|
-
});
|
|
2694
|
-
tl.history.push(event);
|
|
2695
|
-
tl.at = tl.history.length;
|
|
2696
|
-
tl.subject.next(event);
|
|
2697
|
-
for (const token2 of molecule.tokens.values()) {
|
|
2698
|
-
switch (token2.type) {
|
|
2699
|
-
case `atom`:
|
|
2700
|
-
case `mutable_atom`:
|
|
2701
|
-
addAtomToTimeline(token2, tl, store);
|
|
2702
|
-
break;
|
|
2703
|
-
}
|
|
2704
|
-
}
|
|
2705
|
-
tl.subscriptions.set(
|
|
2706
|
-
molecule.key,
|
|
2707
|
-
molecule.subject.subscribe(
|
|
2708
|
-
`timeline:${options.key}`,
|
|
2709
|
-
(stateCreationOrDisposal) => {
|
|
2710
|
-
handleStateLifecycleEvent(
|
|
2711
|
-
stateCreationOrDisposal,
|
|
2712
|
-
tl,
|
|
2713
|
-
store
|
|
2714
|
-
);
|
|
2715
|
-
}
|
|
2716
|
-
)
|
|
2717
|
-
);
|
|
2718
|
-
}
|
|
2719
|
-
}
|
|
2720
|
-
break;
|
|
2721
|
-
case `molecule_disposal`:
|
|
2722
|
-
(_a2 = tl.subscriptions.get(creationOrDisposal.token.key)) == null ? void 0 : _a2();
|
|
2723
|
-
tl.subscriptions.delete(creationOrDisposal.token.key);
|
|
2724
|
-
for (const familyKey of creationOrDisposal.familyKeys) {
|
|
2725
|
-
const stateKey = `${familyKey}(${stringifyJson(
|
|
2726
|
-
creationOrDisposal.token.key
|
|
2727
|
-
)})`;
|
|
2728
|
-
(_b2 = tl.subscriptions.get(stateKey)) == null ? void 0 : _b2();
|
|
2729
|
-
tl.subscriptions.delete(stateKey);
|
|
2730
|
-
}
|
|
2731
|
-
break;
|
|
2732
|
-
}
|
|
2733
|
-
}
|
|
2734
|
-
)
|
|
2735
|
-
);
|
|
2736
|
-
}
|
|
2737
|
-
}
|
|
2785
|
+
default:
|
|
2786
|
+
key = updateFromTx.key;
|
|
2738
2787
|
break;
|
|
2739
2788
|
}
|
|
2740
|
-
|
|
2741
|
-
|
|
2742
|
-
|
|
2743
|
-
|
|
2744
|
-
|
|
2745
|
-
|
|
2746
|
-
|
|
2747
|
-
|
|
2789
|
+
return timelineTopics.has(key);
|
|
2790
|
+
}).map((updateFromTx) => {
|
|
2791
|
+
if (`updates` in updateFromTx) {
|
|
2792
|
+
return __spreadProps(__spreadValues({}, updateFromTx), {
|
|
2793
|
+
updates: filterTransactionUpdates(
|
|
2794
|
+
updateFromTx.updates,
|
|
2795
|
+
timelineTopics
|
|
2796
|
+
)
|
|
2797
|
+
});
|
|
2798
|
+
}
|
|
2799
|
+
return updateFromTx;
|
|
2800
|
+
});
|
|
2748
2801
|
}
|
|
2749
2802
|
function handleStateLifecycleEvent(event, tl, store) {
|
|
2750
|
-
var _a;
|
|
2803
|
+
var _a, _b;
|
|
2751
2804
|
const timestamp = Date.now();
|
|
2752
2805
|
const timelineEvent = Object.assign(event, {
|
|
2753
2806
|
timestamp
|
|
2754
2807
|
});
|
|
2755
2808
|
if (!tl.timeTraveling) {
|
|
2756
|
-
|
|
2757
|
-
|
|
2758
|
-
|
|
2809
|
+
const txUpdateInProgress = (_a = newest(store).on.transactionApplying.state) == null ? void 0 : _a.update;
|
|
2810
|
+
if (txUpdateInProgress) {
|
|
2811
|
+
joinTransaction(tl, txUpdateInProgress, store);
|
|
2812
|
+
} else {
|
|
2813
|
+
tl.history.push(timelineEvent);
|
|
2814
|
+
tl.at = tl.history.length;
|
|
2815
|
+
tl.subject.next(timelineEvent);
|
|
2816
|
+
}
|
|
2759
2817
|
}
|
|
2760
2818
|
switch (event.type) {
|
|
2761
2819
|
case `state_creation`:
|
|
2762
2820
|
addAtomToTimeline(event.token, tl, store);
|
|
2763
2821
|
break;
|
|
2764
2822
|
case `state_disposal`:
|
|
2765
|
-
(
|
|
2823
|
+
(_b = tl.subscriptions.get(event.token.key)) == null ? void 0 : _b();
|
|
2766
2824
|
tl.subscriptions.delete(event.token.key);
|
|
2767
2825
|
break;
|
|
2768
2826
|
}
|
|
@@ -2844,4 +2902,4 @@ var timeTravel = (action, token, store) => {
|
|
|
2844
2902
|
);
|
|
2845
2903
|
};
|
|
2846
2904
|
|
|
2847
|
-
export { FamilyTracker, Future, IMPLICIT, LazyMap, Molecule, NotFoundError, StatefulSubject, Store, Subject, TRANSACTION_PHASES, Tracker, abortTransaction, actUponStore,
|
|
2905
|
+
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 };
|