atom.io 0.21.1 → 0.22.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/data/dist/index.cjs +136 -63
- package/data/dist/index.d.ts +6 -0
- package/data/dist/index.js +3 -3
- package/data/src/join.ts +135 -51
- package/data/src/struct-family.ts +2 -2
- package/dist/{chunk-RT43TVKP.js → chunk-GVHKIJ3G.js} +1 -1
- package/dist/{chunk-HITX3MO4.js → chunk-JA4V7TJY.js} +135 -62
- package/dist/index.cjs +2 -7
- package/dist/index.d.ts +29 -14
- package/dist/index.js +4 -8
- package/ephemeral/dist/index.cjs +11 -0
- package/ephemeral/dist/index.js +9 -0
- package/ephemeral/package.json +16 -0
- package/ephemeral/src/index.ts +1 -0
- package/eslint-plugin/dist/index.cjs +156 -1
- package/eslint-plugin/dist/index.js +156 -1
- package/eslint-plugin/src/rules/index.ts +1 -0
- package/eslint-plugin/src/rules/lifespan.ts +204 -0
- package/eslint-plugin/src/rules/synchronous-selector-dependencies.ts +1 -65
- package/eslint-plugin/src/walk.ts +73 -0
- package/immortal/dist/index.cjs +100 -0
- package/immortal/dist/index.js +97 -0
- package/immortal/package.json +16 -0
- package/immortal/src/index.ts +2 -0
- package/immortal/src/molecule.ts +134 -0
- package/immortal/src/seek-state.ts +60 -0
- package/internal/dist/index.cjs +186 -146
- package/internal/dist/index.d.ts +29 -13
- package/internal/dist/index.js +185 -146
- package/internal/src/atom/dispose-atom.ts +4 -1
- package/internal/src/families/create-readonly-selector-family.ts +9 -9
- package/internal/src/families/create-regular-atom-family.ts +15 -20
- package/internal/src/families/create-writable-selector-family.ts +6 -7
- package/internal/src/families/find-in-store.ts +11 -5
- package/internal/src/families/index.ts +2 -0
- package/internal/src/families/init-family-member.ts +91 -0
- package/internal/src/families/seek-in-store.ts +106 -0
- package/internal/src/get-state/get-from-store.ts +2 -2
- package/internal/src/mutable/create-mutable-atom-family.ts +17 -23
- package/internal/src/mutable/create-mutable-atom.ts +3 -1
- package/internal/src/mutable/get-json-family.ts +2 -2
- package/internal/src/mutable/get-json-token.ts +27 -12
- package/internal/src/mutable/tracker-family.ts +14 -12
- package/internal/src/not-found-error.ts +11 -3
- package/internal/src/selector/create-readonly-selector.ts +2 -2
- package/internal/src/selector/create-writable-selector.ts +2 -2
- package/internal/src/selector/dispose-selector.ts +40 -23
- package/internal/src/selector/register-selector.ts +8 -5
- package/internal/src/set-state/set-into-store.ts +2 -2
- package/internal/src/store/index.ts +0 -1
- package/internal/src/store/store.ts +18 -5
- package/internal/src/subscribe/subscribe-to-state.ts +2 -2
- package/internal/src/transaction/build-transaction.ts +7 -2
- package/introspection/dist/index.cjs +38 -52
- package/introspection/dist/index.js +38 -52
- package/introspection/src/attach-atom-index.ts +38 -48
- package/introspection/src/attach-selector-index.ts +45 -50
- package/json/dist/index.cjs +38 -4
- package/json/dist/index.js +40 -6
- package/json/src/select-json-family.ts +46 -7
- package/package.json +30 -10
- package/react/dist/index.cjs +1 -1
- package/react/dist/index.js +1 -1
- package/react/src/use-json.ts +1 -1
- package/react-devtools/dist/index.cjs +11 -10
- package/react-devtools/dist/index.js +2 -1
- package/react-devtools/src/StateIndex.tsx +2 -1
- package/react-devtools/src/TimelineIndex.tsx +2 -1
- package/react-devtools/src/TransactionIndex.tsx +7 -7
- package/realtime-client/dist/index.cjs +3 -3
- package/realtime-client/dist/index.js +3 -3
- package/realtime-client/src/pull-mutable-atom-family-member.ts +1 -1
- package/realtime-client/src/pull-mutable-atom.ts +1 -1
- package/realtime-client/src/sync-continuity.ts +1 -2
- package/realtime-react/dist/index.cjs +1 -1
- package/realtime-react/dist/index.js +1 -1
- package/realtime-server/dist/index.cjs +18 -17
- package/realtime-server/dist/index.js +7 -6
- package/realtime-server/src/realtime-continuity-synchronizer.ts +5 -3
- package/realtime-server/src/realtime-mutable-family-provider.ts +2 -1
- package/realtime-server/src/realtime-mutable-provider.ts +1 -1
- package/realtime-testing/dist/index.cjs +6 -2
- package/realtime-testing/dist/index.js +8 -5
- package/realtime-testing/src/setup-realtime-test.tsx +5 -2
- package/src/atom.ts +10 -4
- package/src/index.ts +1 -2
- package/src/selector.ts +10 -4
- package/src/silo.ts +3 -3
- package/src/transaction.ts +5 -2
- package/internal/src/store/withdraw-new-family-member.ts +0 -69
- /package/{src → ephemeral/src}/find-state.ts +0 -0
- /package/src/{dispose.ts → dispose-state.ts} +0 -0
package/internal/dist/index.js
CHANGED
|
@@ -113,7 +113,7 @@ function isChildStore(store) {
|
|
|
113
113
|
|
|
114
114
|
// internal/src/store/store.ts
|
|
115
115
|
var Store = class {
|
|
116
|
-
constructor(
|
|
116
|
+
constructor(config, store = null) {
|
|
117
117
|
this.parent = null;
|
|
118
118
|
this.child = null;
|
|
119
119
|
this.valueMap = /* @__PURE__ */ new Map();
|
|
@@ -142,6 +142,8 @@ var Store = class {
|
|
|
142
142
|
makeContentKey: (...keys) => keys.sort().join(`:`)
|
|
143
143
|
}
|
|
144
144
|
);
|
|
145
|
+
this.molecules = /* @__PURE__ */ new Map();
|
|
146
|
+
this.miscResources = /* @__PURE__ */ new Map();
|
|
145
147
|
this.on = {
|
|
146
148
|
atomCreation: new Subject(),
|
|
147
149
|
atomDisposal: new Subject(),
|
|
@@ -163,7 +165,8 @@ var Store = class {
|
|
|
163
165
|
})
|
|
164
166
|
};
|
|
165
167
|
this.config = {
|
|
166
|
-
name: `IMPLICIT_STORE
|
|
168
|
+
name: `IMPLICIT_STORE`,
|
|
169
|
+
lifespan: `ephemeral`
|
|
167
170
|
};
|
|
168
171
|
this.loggers = [
|
|
169
172
|
new AtomIOLogger(`warn`, (_, __, key) => !key.includes(`\u{1F441}\u200D\u{1F5E8}`))
|
|
@@ -193,9 +196,7 @@ var Store = class {
|
|
|
193
196
|
)
|
|
194
197
|
};
|
|
195
198
|
}
|
|
196
|
-
this.config =
|
|
197
|
-
name
|
|
198
|
-
});
|
|
199
|
+
this.config = __spreadValues(__spreadValues({}, store == null ? void 0 : store.config), config);
|
|
199
200
|
for (const [, family] of store.families) {
|
|
200
201
|
family.install(this);
|
|
201
202
|
}
|
|
@@ -206,7 +207,7 @@ var Store = class {
|
|
|
206
207
|
}
|
|
207
208
|
atom.install(this);
|
|
208
209
|
if (atom.type === `mutable_atom`) {
|
|
209
|
-
const originalJsonToken = getJsonToken(atom);
|
|
210
|
+
const originalJsonToken = getJsonToken(atom, store);
|
|
210
211
|
const originalUpdateToken = getUpdateToken(atom);
|
|
211
212
|
mutableHelpers.add(originalJsonToken.key);
|
|
212
213
|
mutableHelpers.add(originalUpdateToken.key);
|
|
@@ -234,12 +235,18 @@ var IMPLICIT = {
|
|
|
234
235
|
STORE_INTERNAL: void 0,
|
|
235
236
|
get STORE() {
|
|
236
237
|
var _a;
|
|
237
|
-
return (_a = this.STORE_INTERNAL) != null ? _a : this.STORE_INTERNAL = new Store(
|
|
238
|
+
return (_a = this.STORE_INTERNAL) != null ? _a : this.STORE_INTERNAL = new Store({
|
|
239
|
+
name: `IMPLICIT_STORE`,
|
|
240
|
+
lifespan: `ephemeral`
|
|
241
|
+
});
|
|
238
242
|
}
|
|
239
243
|
};
|
|
240
244
|
var clearStore = (store) => {
|
|
241
245
|
const { config } = store;
|
|
242
|
-
|
|
246
|
+
for (const disposable of store.miscResources.values()) {
|
|
247
|
+
disposable[Symbol.dispose]();
|
|
248
|
+
}
|
|
249
|
+
Object.assign(store, new Store(config));
|
|
243
250
|
store.config = config;
|
|
244
251
|
};
|
|
245
252
|
|
|
@@ -280,36 +287,6 @@ function withdraw(token, store) {
|
|
|
280
287
|
throw new NotFoundError(token, store);
|
|
281
288
|
}
|
|
282
289
|
|
|
283
|
-
// internal/src/store/withdraw-new-family-member.ts
|
|
284
|
-
function withdrawOrCreate(token, store) {
|
|
285
|
-
try {
|
|
286
|
-
const state = withdraw(token, store);
|
|
287
|
-
return state;
|
|
288
|
-
} catch (notFoundError) {
|
|
289
|
-
if (token.family) {
|
|
290
|
-
store.logger.info(
|
|
291
|
-
`\u{1F46A}`,
|
|
292
|
-
token.type,
|
|
293
|
-
token.key,
|
|
294
|
-
`creating new family member in store "${store.config.name}"`
|
|
295
|
-
);
|
|
296
|
-
const target = newest(store);
|
|
297
|
-
const family = target.families.get(token.family.key);
|
|
298
|
-
if (family) {
|
|
299
|
-
const jsonSubKey = JSON.parse(token.family.subKey);
|
|
300
|
-
family(jsonSubKey);
|
|
301
|
-
const state = withdraw(token, store);
|
|
302
|
-
return state;
|
|
303
|
-
}
|
|
304
|
-
throw new NotFoundError(
|
|
305
|
-
{ key: token.family.key, type: `${token.type}_family` },
|
|
306
|
-
store
|
|
307
|
-
);
|
|
308
|
-
}
|
|
309
|
-
throw notFoundError;
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
|
-
|
|
313
290
|
// internal/src/get-state/read-or-compute-value.ts
|
|
314
291
|
var readOrComputeValue = (state, target) => {
|
|
315
292
|
if (target.valueMap.has(state.key)) {
|
|
@@ -337,22 +314,17 @@ function createRegularAtomFamily(options, store) {
|
|
|
337
314
|
const subKey = stringifyJson(key);
|
|
338
315
|
const family = { key: options.key, subKey };
|
|
339
316
|
const fullKey = `${options.key}(${subKey})`;
|
|
340
|
-
const
|
|
341
|
-
const
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
default: options.default instanceof Function ? options.default(key) : options.default
|
|
349
|
-
};
|
|
350
|
-
if (options.effects) {
|
|
351
|
-
individualOptions.effects = options.effects(key);
|
|
352
|
-
}
|
|
353
|
-
token = createRegularAtom(individualOptions, family, store);
|
|
354
|
-
subject.next(token);
|
|
317
|
+
const target = newest(store);
|
|
318
|
+
const def = options.default;
|
|
319
|
+
const individualOptions = {
|
|
320
|
+
key: fullKey,
|
|
321
|
+
default: def instanceof Function ? def(key) : def
|
|
322
|
+
};
|
|
323
|
+
if (options.effects) {
|
|
324
|
+
individualOptions.effects = options.effects(key);
|
|
355
325
|
}
|
|
326
|
+
const token = createRegularAtom(individualOptions, family, target);
|
|
327
|
+
subject.next(token);
|
|
356
328
|
return token;
|
|
357
329
|
},
|
|
358
330
|
{
|
|
@@ -362,8 +334,7 @@ function createRegularAtomFamily(options, store) {
|
|
|
362
334
|
install: (s) => createRegularAtomFamily(options, s)
|
|
363
335
|
}
|
|
364
336
|
);
|
|
365
|
-
|
|
366
|
-
target.families.set(options.key, atomFamily);
|
|
337
|
+
store.families.set(options.key, atomFamily);
|
|
367
338
|
return atomFamily;
|
|
368
339
|
}
|
|
369
340
|
|
|
@@ -379,22 +350,20 @@ function createReadonlySelectorFamily(options, store) {
|
|
|
379
350
|
const subject = new Subject();
|
|
380
351
|
const readonlySelectorFamily = Object.assign(
|
|
381
352
|
(key) => {
|
|
382
|
-
const target = newest(store);
|
|
383
353
|
const subKey = stringifyJson(key);
|
|
384
354
|
const family = { key: options.key, subKey };
|
|
385
355
|
const fullKey = `${options.key}(${subKey})`;
|
|
386
|
-
const
|
|
387
|
-
|
|
388
|
-
return deposit(existing);
|
|
389
|
-
}
|
|
390
|
-
return createReadonlySelector(
|
|
356
|
+
const target = newest(store);
|
|
357
|
+
const token = createReadonlySelector(
|
|
391
358
|
{
|
|
392
359
|
key: fullKey,
|
|
393
360
|
get: options.get(key)
|
|
394
361
|
},
|
|
395
362
|
family,
|
|
396
|
-
|
|
363
|
+
target
|
|
397
364
|
);
|
|
365
|
+
subject.next(token);
|
|
366
|
+
return token;
|
|
398
367
|
},
|
|
399
368
|
{
|
|
400
369
|
key: options.key,
|
|
@@ -413,10 +382,7 @@ function createWritableSelectorFamily(options, store) {
|
|
|
413
382
|
const subKey = stringifyJson(key);
|
|
414
383
|
const family = { key: options.key, subKey };
|
|
415
384
|
const fullKey = `${options.key}(${subKey})`;
|
|
416
|
-
const
|
|
417
|
-
if (existing) {
|
|
418
|
-
return deposit(existing);
|
|
419
|
-
}
|
|
385
|
+
const target = newest(store);
|
|
420
386
|
const token = createWritableSelector(
|
|
421
387
|
{
|
|
422
388
|
key: fullKey,
|
|
@@ -424,7 +390,7 @@ function createWritableSelectorFamily(options, store) {
|
|
|
424
390
|
set: options.set(key)
|
|
425
391
|
},
|
|
426
392
|
family,
|
|
427
|
-
|
|
393
|
+
target
|
|
428
394
|
);
|
|
429
395
|
subject.next(token);
|
|
430
396
|
return token;
|
|
@@ -452,10 +418,18 @@ function createSelectorFamily(options, store) {
|
|
|
452
418
|
// internal/src/not-found-error.ts
|
|
453
419
|
var capitalize = (str) => str[0].toUpperCase() + str.slice(1);
|
|
454
420
|
function prettyPrintTokenType(token) {
|
|
455
|
-
|
|
456
|
-
|
|
421
|
+
switch (token.type) {
|
|
422
|
+
case `atom_family`:
|
|
423
|
+
return `Atom Family`;
|
|
424
|
+
case `readonly_selector`:
|
|
425
|
+
return `Readonly Selector`;
|
|
426
|
+
case `readonly_selector_family`:
|
|
427
|
+
return `Readonly Selector Family`;
|
|
428
|
+
case `selector_family`:
|
|
429
|
+
return `Selector Family`;
|
|
430
|
+
default:
|
|
431
|
+
return capitalize(token.type);
|
|
457
432
|
}
|
|
458
|
-
return capitalize(token.type);
|
|
459
433
|
}
|
|
460
434
|
var NotFoundError = class extends Error {
|
|
461
435
|
constructor(token, store) {
|
|
@@ -465,8 +439,8 @@ var NotFoundError = class extends Error {
|
|
|
465
439
|
}
|
|
466
440
|
};
|
|
467
441
|
|
|
468
|
-
// internal/src/families/
|
|
469
|
-
function
|
|
442
|
+
// internal/src/families/init-family-member.ts
|
|
443
|
+
function initFamilyMember(token, key, store) {
|
|
470
444
|
const familyKey = token.key;
|
|
471
445
|
const family = store.families.get(familyKey);
|
|
472
446
|
if (family === void 0) {
|
|
@@ -475,6 +449,44 @@ function findInStore(token, key, store) {
|
|
|
475
449
|
const state = family(key);
|
|
476
450
|
return state;
|
|
477
451
|
}
|
|
452
|
+
function seekInStore(token, key, store) {
|
|
453
|
+
const subKey = stringifyJson(key);
|
|
454
|
+
const fullKey = `${token.key}(${subKey})`;
|
|
455
|
+
const target = newest(store);
|
|
456
|
+
let state;
|
|
457
|
+
switch (token.type) {
|
|
458
|
+
case `atom_family`:
|
|
459
|
+
case `mutable_atom_family`:
|
|
460
|
+
state = target.atoms.get(fullKey);
|
|
461
|
+
break;
|
|
462
|
+
case `selector_family`: {
|
|
463
|
+
state = target.selectors.get(fullKey);
|
|
464
|
+
break;
|
|
465
|
+
}
|
|
466
|
+
case `readonly_selector_family`:
|
|
467
|
+
state = target.readonlySelectors.get(fullKey);
|
|
468
|
+
break;
|
|
469
|
+
}
|
|
470
|
+
if (state) {
|
|
471
|
+
return deposit(state);
|
|
472
|
+
}
|
|
473
|
+
return state;
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
// internal/src/families/find-in-store.ts
|
|
477
|
+
function findInStore(token, key, store) {
|
|
478
|
+
if (store.config.lifespan === `immortal`) {
|
|
479
|
+
throw new Error(
|
|
480
|
+
`Do not use \`find\` or \`findState\` in an immortal store. Prefer \`seek\` or \`seekState\`.`
|
|
481
|
+
);
|
|
482
|
+
}
|
|
483
|
+
let state = seekInStore(token, key, store);
|
|
484
|
+
if (state) {
|
|
485
|
+
return state;
|
|
486
|
+
}
|
|
487
|
+
state = initFamilyMember(token, key, store);
|
|
488
|
+
return state;
|
|
489
|
+
}
|
|
478
490
|
|
|
479
491
|
// internal/src/set-state/become.ts
|
|
480
492
|
var become = (nextVersionOfThing) => (originalThing) => nextVersionOfThing instanceof Function ? nextVersionOfThing(
|
|
@@ -717,7 +729,7 @@ function setIntoStore(token, value, store) {
|
|
|
717
729
|
);
|
|
718
730
|
return;
|
|
719
731
|
}
|
|
720
|
-
const state =
|
|
732
|
+
const state = withdraw(token, store);
|
|
721
733
|
setAtomOrSelector(state, value, store);
|
|
722
734
|
closeOperation(store);
|
|
723
735
|
}
|
|
@@ -803,7 +815,7 @@ var updateSelectorAtoms = (selectorKey, dependency, store) => {
|
|
|
803
815
|
var registerSelector = (selectorKey, store) => ({
|
|
804
816
|
get: (dependency) => {
|
|
805
817
|
const target = newest(store);
|
|
806
|
-
const dependencyState =
|
|
818
|
+
const dependencyState = withdraw(dependency, store);
|
|
807
819
|
const dependencyValue = readOrComputeValue(dependencyState, store);
|
|
808
820
|
store.logger.info(
|
|
809
821
|
`\u{1F50C}`,
|
|
@@ -826,19 +838,20 @@ var registerSelector = (selectorKey, store) => ({
|
|
|
826
838
|
return dependencyValue;
|
|
827
839
|
},
|
|
828
840
|
set: (WritableToken, newValue) => {
|
|
829
|
-
const state =
|
|
841
|
+
const state = withdraw(WritableToken, store);
|
|
830
842
|
setAtomOrSelector(state, newValue, store);
|
|
831
843
|
},
|
|
832
|
-
find: (token, key) => findInStore(token, key, store)
|
|
844
|
+
find: (token, key) => findInStore(token, key, store),
|
|
845
|
+
seek: (token, key) => seekInStore(token, key, store)
|
|
833
846
|
});
|
|
834
847
|
|
|
835
848
|
// internal/src/selector/create-readonly-selector.ts
|
|
836
849
|
var createReadonlySelector = (options, family, store) => {
|
|
837
850
|
const target = newest(store);
|
|
838
851
|
const subject = new Subject();
|
|
839
|
-
const { get, find } = registerSelector(options.key, target);
|
|
852
|
+
const { get, find, seek } = registerSelector(options.key, target);
|
|
840
853
|
const getSelf = () => {
|
|
841
|
-
const value = options.get({ get, find });
|
|
854
|
+
const value = options.get({ get, find, seek });
|
|
842
855
|
cacheValue(options.key, value, subject, newest(store));
|
|
843
856
|
return value;
|
|
844
857
|
};
|
|
@@ -873,8 +886,8 @@ var createWritableSelector = (options, family, store) => {
|
|
|
873
886
|
const target = newest(store);
|
|
874
887
|
const subject = new Subject();
|
|
875
888
|
const transactors = registerSelector(options.key, target);
|
|
876
|
-
const { find, get } = transactors;
|
|
877
|
-
const readonlyTransactors = { find, get };
|
|
889
|
+
const { find, get, seek } = transactors;
|
|
890
|
+
const readonlyTransactors = { find, get, seek };
|
|
878
891
|
const getSelf = () => {
|
|
879
892
|
const value = options.get(readonlyTransactors);
|
|
880
893
|
cacheValue(options.key, value, subject, newest(store));
|
|
@@ -932,32 +945,50 @@ function createStandaloneSelector(options, store) {
|
|
|
932
945
|
|
|
933
946
|
// internal/src/selector/dispose-selector.ts
|
|
934
947
|
function disposeSelector(selectorToken, store) {
|
|
948
|
+
var _a;
|
|
935
949
|
const target = newest(store);
|
|
936
950
|
const { key } = selectorToken;
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
+
const selector = (_a = target.selectors.get(key)) != null ? _a : target.readonlySelectors.get(key);
|
|
952
|
+
if (!selector) {
|
|
953
|
+
store.logger.error(
|
|
954
|
+
`\u274C`,
|
|
955
|
+
`selector`,
|
|
956
|
+
key,
|
|
957
|
+
`Tried to dispose selector, but it does not exist in the store.`
|
|
958
|
+
);
|
|
959
|
+
} else if (!selector.family) {
|
|
960
|
+
store.logger.error(
|
|
961
|
+
`\u274C`,
|
|
962
|
+
`selector`,
|
|
963
|
+
key,
|
|
964
|
+
`Standalone selectors cannot be disposed.`
|
|
965
|
+
);
|
|
966
|
+
} else {
|
|
967
|
+
switch (selectorToken.type) {
|
|
968
|
+
case `selector`:
|
|
969
|
+
target.selectors.delete(key);
|
|
970
|
+
break;
|
|
971
|
+
case `readonly_selector`:
|
|
972
|
+
target.readonlySelectors.delete(key);
|
|
973
|
+
break;
|
|
951
974
|
}
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
975
|
+
target.valueMap.delete(key);
|
|
976
|
+
target.selectorAtoms.delete(key);
|
|
977
|
+
const downstreamTokens = target.selectorGraph.getRelationEntries({ upstreamSelectorKey: key }).filter(([_, { source }]) => source === key).map(
|
|
978
|
+
([downstreamSelectorKey]) => {
|
|
979
|
+
var _a2;
|
|
980
|
+
return (_a2 = target.selectors.get(downstreamSelectorKey)) != null ? _a2 : target.readonlySelectors.get(downstreamSelectorKey);
|
|
981
|
+
}
|
|
982
|
+
);
|
|
983
|
+
for (const downstreamToken of downstreamTokens) {
|
|
984
|
+
if (downstreamToken) {
|
|
985
|
+
disposeSelector(downstreamToken, store);
|
|
986
|
+
}
|
|
956
987
|
}
|
|
988
|
+
target.selectorGraph.delete(key);
|
|
989
|
+
store.logger.info(`\u{1F525}`, selectorToken.type, key, `deleted`);
|
|
990
|
+
store.on.selectorDisposal.next(selectorToken);
|
|
957
991
|
}
|
|
958
|
-
target.selectorGraph.delete(key);
|
|
959
|
-
store.logger.info(`\u{1F525}`, selectorToken.type, key, `deleted`);
|
|
960
|
-
store.on.selectorDisposal.next(selectorToken);
|
|
961
992
|
}
|
|
962
993
|
|
|
963
994
|
// internal/src/subscribe/recall-state.ts
|
|
@@ -1028,7 +1059,7 @@ function subscribeToState(token, handleUpdate, key, store) {
|
|
|
1028
1059
|
handleUpdate(update);
|
|
1029
1060
|
}
|
|
1030
1061
|
}
|
|
1031
|
-
const state =
|
|
1062
|
+
const state = withdraw(token, store);
|
|
1032
1063
|
store.logger.info(`\u{1F440}`, state.type, state.key, `Adding subscription "${key}"`);
|
|
1033
1064
|
const isSelector = state.type === `selector` || state.type === `readonly_selector`;
|
|
1034
1065
|
let dependencyUnsubFunctions = null;
|
|
@@ -1289,37 +1320,41 @@ function createMutableAtom(options, family, store) {
|
|
|
1289
1320
|
};
|
|
1290
1321
|
}
|
|
1291
1322
|
new Tracker(token, store);
|
|
1292
|
-
|
|
1323
|
+
if (!family) {
|
|
1324
|
+
selectJson(token, options, store);
|
|
1325
|
+
}
|
|
1293
1326
|
store.on.atomCreation.next(token);
|
|
1294
1327
|
return token;
|
|
1295
1328
|
}
|
|
1296
1329
|
var FamilyTracker = class {
|
|
1297
|
-
constructor(
|
|
1298
|
-
this.
|
|
1330
|
+
constructor(mutableAtoms, store) {
|
|
1331
|
+
this.latestUpdateAtoms = createRegularAtomFamily(
|
|
1299
1332
|
{
|
|
1300
|
-
key: `*${
|
|
1333
|
+
key: `*${mutableAtoms.key}`,
|
|
1301
1334
|
default: null
|
|
1302
1335
|
},
|
|
1303
1336
|
store
|
|
1304
1337
|
);
|
|
1305
|
-
this.
|
|
1306
|
-
this.
|
|
1338
|
+
this.mutableAtoms = mutableAtoms;
|
|
1339
|
+
this.mutableAtoms.subject.subscribe(
|
|
1307
1340
|
`store=${store.config.name}::tracker-atom-family`,
|
|
1308
1341
|
(atomToken) => {
|
|
1309
1342
|
if (atomToken.family) {
|
|
1310
1343
|
const key = parseJson(atomToken.family.subKey);
|
|
1311
|
-
this.
|
|
1344
|
+
seekInStore(this.latestUpdateAtoms, key, store);
|
|
1312
1345
|
new Tracker(atomToken, store);
|
|
1313
1346
|
}
|
|
1314
1347
|
}
|
|
1315
1348
|
);
|
|
1316
|
-
this.
|
|
1349
|
+
this.latestUpdateAtoms.subject.subscribe(
|
|
1317
1350
|
`store=${store.config.name}::tracker-atom-family`,
|
|
1318
1351
|
(atomToken) => {
|
|
1319
1352
|
if (atomToken.family) {
|
|
1320
1353
|
const key = parseJson(atomToken.family.subKey);
|
|
1321
|
-
const mutableAtomToken = this.
|
|
1322
|
-
|
|
1354
|
+
const mutableAtomToken = seekInStore(this.mutableAtoms, key, store);
|
|
1355
|
+
if (mutableAtomToken) {
|
|
1356
|
+
new Tracker(mutableAtomToken, store);
|
|
1357
|
+
}
|
|
1323
1358
|
}
|
|
1324
1359
|
}
|
|
1325
1360
|
);
|
|
@@ -1334,25 +1369,19 @@ function createMutableAtomFamily(options, store) {
|
|
|
1334
1369
|
const subKey = stringifyJson(key);
|
|
1335
1370
|
const family = { key: options.key, subKey };
|
|
1336
1371
|
const fullKey = `${options.key}(${subKey})`;
|
|
1337
|
-
const
|
|
1338
|
-
const
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
fromJson: options.fromJson,
|
|
1348
|
-
mutable: true
|
|
1349
|
-
};
|
|
1350
|
-
if (options.effects) {
|
|
1351
|
-
individualOptions.effects = options.effects(key);
|
|
1352
|
-
}
|
|
1353
|
-
token = createMutableAtom(individualOptions, family, store);
|
|
1354
|
-
subject.next(token);
|
|
1372
|
+
const target = newest(store);
|
|
1373
|
+
const individualOptions = {
|
|
1374
|
+
key: fullKey,
|
|
1375
|
+
default: () => options.default(key),
|
|
1376
|
+
toJson: options.toJson,
|
|
1377
|
+
fromJson: options.fromJson,
|
|
1378
|
+
mutable: true
|
|
1379
|
+
};
|
|
1380
|
+
if (options.effects) {
|
|
1381
|
+
individualOptions.effects = options.effects(key);
|
|
1355
1382
|
}
|
|
1383
|
+
const token = createMutableAtom(individualOptions, family, target);
|
|
1384
|
+
subject.next(token);
|
|
1356
1385
|
return token;
|
|
1357
1386
|
},
|
|
1358
1387
|
{
|
|
@@ -1364,8 +1393,7 @@ function createMutableAtomFamily(options, store) {
|
|
|
1364
1393
|
fromJson: options.fromJson
|
|
1365
1394
|
}
|
|
1366
1395
|
);
|
|
1367
|
-
|
|
1368
|
-
target.families.set(options.key, atomFamily);
|
|
1396
|
+
store.families.set(options.key, atomFamily);
|
|
1369
1397
|
selectJsonFamily(atomFamily, options, store);
|
|
1370
1398
|
new FamilyTracker(atomFamily, store);
|
|
1371
1399
|
return atomFamily;
|
|
@@ -1380,19 +1408,24 @@ var getJsonFamily = (mutableAtomFamily, store) => {
|
|
|
1380
1408
|
};
|
|
1381
1409
|
|
|
1382
1410
|
// internal/src/mutable/get-json-token.ts
|
|
1383
|
-
var getJsonToken = (mutableAtomToken) => {
|
|
1384
|
-
const key = mutableAtomToken.family ? `${mutableAtomToken.family.key}:JSON(${mutableAtomToken.family.subKey})` : `${mutableAtomToken.key}:JSON`;
|
|
1385
|
-
const jsonToken = {
|
|
1386
|
-
type: `selector`,
|
|
1387
|
-
key
|
|
1388
|
-
};
|
|
1411
|
+
var getJsonToken = (mutableAtomToken, store) => {
|
|
1389
1412
|
if (mutableAtomToken.family) {
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1413
|
+
const target = newest(store);
|
|
1414
|
+
const jsonFamilyKey = `${mutableAtomToken.family.key}:JSON`;
|
|
1415
|
+
const jsonFamilyToken = {
|
|
1416
|
+
key: jsonFamilyKey,
|
|
1417
|
+
type: `selector_family`
|
|
1393
1418
|
};
|
|
1419
|
+
const family = withdraw(jsonFamilyToken, target);
|
|
1420
|
+
const subKey = JSON.parse(mutableAtomToken.family.subKey);
|
|
1421
|
+
const jsonToken = findInStore(family, subKey, store);
|
|
1422
|
+
return jsonToken;
|
|
1394
1423
|
}
|
|
1395
|
-
|
|
1424
|
+
const token = {
|
|
1425
|
+
type: `selector`,
|
|
1426
|
+
key: `${mutableAtomToken.key}:JSON`
|
|
1427
|
+
};
|
|
1428
|
+
return token;
|
|
1396
1429
|
};
|
|
1397
1430
|
|
|
1398
1431
|
// internal/src/mutable/get-update-token.ts
|
|
@@ -1588,8 +1621,10 @@ function disposeAtom(atomToken, store) {
|
|
|
1588
1621
|
`\u274C`,
|
|
1589
1622
|
`atom`,
|
|
1590
1623
|
key,
|
|
1591
|
-
`Tried to
|
|
1624
|
+
`Tried to dispose atom, but it does not exist in the store.`
|
|
1592
1625
|
);
|
|
1626
|
+
} else if (!atom.family) {
|
|
1627
|
+
store.logger.error(`\u274C`, `atom`, key, `Standalone atoms cannot be disposed.`);
|
|
1593
1628
|
} else {
|
|
1594
1629
|
(_a = atom.cleanup) == null ? void 0 : _a.call(atom);
|
|
1595
1630
|
target.atoms.delete(key);
|
|
@@ -1609,6 +1644,7 @@ function disposeAtom(atomToken, store) {
|
|
|
1609
1644
|
if (atomToken.type === `mutable_atom`) {
|
|
1610
1645
|
const updateToken = getUpdateToken(atomToken);
|
|
1611
1646
|
disposeAtom(updateToken, store);
|
|
1647
|
+
store.trackers.delete(key);
|
|
1612
1648
|
}
|
|
1613
1649
|
store.logger.info(`\u{1F525}`, `atom`, key, `deleted`);
|
|
1614
1650
|
store.on.atomDisposal.next(atomToken);
|
|
@@ -1626,7 +1662,7 @@ function getEnvironmentData(store) {
|
|
|
1626
1662
|
|
|
1627
1663
|
// internal/src/get-state/get-from-store.ts
|
|
1628
1664
|
function getFromStore(token, store) {
|
|
1629
|
-
const state =
|
|
1665
|
+
const state = withdraw(token, store);
|
|
1630
1666
|
return readOrComputeValue(state, store);
|
|
1631
1667
|
}
|
|
1632
1668
|
|
|
@@ -2180,7 +2216,9 @@ var buildTransaction = (key, params, store, id) => {
|
|
|
2180
2216
|
makeContentKey: (...keys) => keys.sort().join(`:`)
|
|
2181
2217
|
}),
|
|
2182
2218
|
selectors: new LazyMap(parent.selectors),
|
|
2183
|
-
valueMap: new LazyMap(parent.valueMap)
|
|
2219
|
+
valueMap: new LazyMap(parent.valueMap),
|
|
2220
|
+
molecules: new LazyMap(parent.molecules),
|
|
2221
|
+
miscResources: new LazyMap(parent.miscResources)
|
|
2184
2222
|
};
|
|
2185
2223
|
const epoch = getEpochNumberOfAction(key, store);
|
|
2186
2224
|
const transactionMeta = {
|
|
@@ -2200,6 +2238,7 @@ var buildTransaction = (key, params, store, id) => {
|
|
|
2200
2238
|
},
|
|
2201
2239
|
run: (token, identifier = arbitrary()) => actUponStore(token, identifier, child),
|
|
2202
2240
|
find: (token, k) => findInStore(token, k, child),
|
|
2241
|
+
seek: (token, k) => seekInStore(token, k, child),
|
|
2203
2242
|
env: () => getEnvironmentData(child)
|
|
2204
2243
|
}
|
|
2205
2244
|
};
|
|
@@ -2267,4 +2306,4 @@ function getEpochNumberOfAction(transactionKey, store) {
|
|
|
2267
2306
|
// internal/src/transaction/index.ts
|
|
2268
2307
|
var TRANSACTION_PHASES = [`idle`, `building`, `applying`];
|
|
2269
2308
|
|
|
2270
|
-
export { FamilyTracker, Future, IMPLICIT, LazyMap, NotFoundError, StatefulSubject, Store, Subject, TRANSACTION_PHASES, Tracker, abortTransaction, actUponStore, addAtomToTimeline, applyTransaction, arbitrary, assignTransactionToContinuity, become, buildTransaction, cacheValue, clearStore, closeOperation, createAtomFamily, createMutableAtom, createMutableAtomFamily, createReadonlySelector, createReadonlySelectorFamily, createRegularAtom, createRegularAtomFamily, createSelectorFamily, createStandaloneAtom, createStandaloneSelector, createTimeline, createTransaction, createWritableSelector, deposit, disposeAtom, disposeSelector, evictCachedValue, findInStore, getContinuityKey, getEnvironmentData, getEpochNumberOfAction, getEpochNumberOfContinuity, getFromStore, getJsonFamily, getJsonToken, getSelectorDependencyKeys, getUpdateToken, ingestAtomUpdate, ingestSelectorUpdate, ingestTransactionUpdate, isAtomDefault, isAtomKey, isChildStore, isDone, isMutable, isReadonlySelectorKey, isRootStore, isSelectorKey, isStateKey, isTransceiver, markAtomAsDefault, markAtomAsNotDefault, markDone, newest, openOperation, readCachedValue, readOrComputeValue, registerSelector, setAtomOrSelector, setEpochNumberOfAction, setEpochNumberOfContinuity, setIntoStore, subscribeToRootAtoms, subscribeToState, subscribeToTimeline, subscribeToTransaction, timeTravel, traceAllSelectorAtoms, traceSelectorAtoms, updateSelectorAtoms, withdraw
|
|
2309
|
+
export { FamilyTracker, Future, IMPLICIT, LazyMap, NotFoundError, StatefulSubject, Store, Subject, TRANSACTION_PHASES, Tracker, abortTransaction, actUponStore, addAtomToTimeline, applyTransaction, arbitrary, assignTransactionToContinuity, become, buildTransaction, cacheValue, clearStore, closeOperation, createAtomFamily, createMutableAtom, createMutableAtomFamily, createReadonlySelector, createReadonlySelectorFamily, createRegularAtom, createRegularAtomFamily, createSelectorFamily, createStandaloneAtom, createStandaloneSelector, createTimeline, createTransaction, createWritableSelector, deposit, disposeAtom, disposeSelector, evictCachedValue, findInStore, getContinuityKey, getEnvironmentData, getEpochNumberOfAction, getEpochNumberOfContinuity, getFromStore, getJsonFamily, getJsonToken, getSelectorDependencyKeys, getUpdateToken, ingestAtomUpdate, ingestSelectorUpdate, ingestTransactionUpdate, initFamilyMember, isAtomDefault, isAtomKey, isChildStore, isDone, isMutable, isReadonlySelectorKey, isRootStore, isSelectorKey, isStateKey, isTransceiver, markAtomAsDefault, markAtomAsNotDefault, markDone, newest, openOperation, readCachedValue, readOrComputeValue, registerSelector, seekInStore, setAtomOrSelector, setEpochNumberOfAction, setEpochNumberOfContinuity, setIntoStore, subscribeToRootAtoms, subscribeToState, subscribeToTimeline, subscribeToTransaction, timeTravel, traceAllSelectorAtoms, traceSelectorAtoms, updateSelectorAtoms, withdraw };
|
|
@@ -12,8 +12,10 @@ export function disposeAtom(atomToken: AtomToken<unknown>, store: Store): void {
|
|
|
12
12
|
`❌`,
|
|
13
13
|
`atom`,
|
|
14
14
|
key,
|
|
15
|
-
`Tried to
|
|
15
|
+
`Tried to dispose atom, but it does not exist in the store.`,
|
|
16
16
|
)
|
|
17
|
+
} else if (!atom.family) {
|
|
18
|
+
store.logger.error(`❌`, `atom`, key, `Standalone atoms cannot be disposed.`)
|
|
17
19
|
} else {
|
|
18
20
|
atom.cleanup?.()
|
|
19
21
|
target.atoms.delete(key)
|
|
@@ -35,6 +37,7 @@ export function disposeAtom(atomToken: AtomToken<unknown>, store: Store): void {
|
|
|
35
37
|
if (atomToken.type === `mutable_atom`) {
|
|
36
38
|
const updateToken = getUpdateToken(atomToken)
|
|
37
39
|
disposeAtom(updateToken, store)
|
|
40
|
+
store.trackers.delete(key)
|
|
38
41
|
}
|
|
39
42
|
store.logger.info(`🔥`, `atom`, key, `deleted`)
|
|
40
43
|
store.on.atomDisposal.next(atomToken)
|
|
@@ -10,7 +10,6 @@ import { stringifyJson } from "atom.io/json"
|
|
|
10
10
|
import { newest } from "../lineage"
|
|
11
11
|
import { createReadonlySelector } from "../selector"
|
|
12
12
|
import type { Store } from "../store"
|
|
13
|
-
import { deposit } from "../store"
|
|
14
13
|
import { Subject } from "../subject"
|
|
15
14
|
|
|
16
15
|
export function createReadonlySelectorFamily<T, K extends Json.Serializable>(
|
|
@@ -18,24 +17,25 @@ export function createReadonlySelectorFamily<T, K extends Json.Serializable>(
|
|
|
18
17
|
store: Store,
|
|
19
18
|
): ReadonlySelectorFamily<T, K> {
|
|
20
19
|
const subject = new Subject<ReadonlySelectorToken<T>>()
|
|
20
|
+
|
|
21
21
|
const readonlySelectorFamily = Object.assign(
|
|
22
22
|
(key: K): ReadonlySelectorToken<T> => {
|
|
23
|
-
const target = newest(store)
|
|
24
23
|
const subKey = stringifyJson(key)
|
|
25
24
|
const family: FamilyMetadata = { key: options.key, subKey }
|
|
26
25
|
const fullKey = `${options.key}(${subKey})`
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
}
|
|
31
|
-
return createReadonlySelector(
|
|
26
|
+
const target = newest(store)
|
|
27
|
+
|
|
28
|
+
const token = createReadonlySelector(
|
|
32
29
|
{
|
|
33
30
|
key: fullKey,
|
|
34
31
|
get: options.get(key),
|
|
35
32
|
},
|
|
36
33
|
family,
|
|
37
|
-
|
|
34
|
+
target,
|
|
38
35
|
)
|
|
36
|
+
|
|
37
|
+
subject.next(token)
|
|
38
|
+
return token
|
|
39
39
|
},
|
|
40
40
|
{
|
|
41
41
|
key: options.key,
|
|
@@ -43,7 +43,7 @@ export function createReadonlySelectorFamily<T, K extends Json.Serializable>(
|
|
|
43
43
|
subject,
|
|
44
44
|
install: (s: Store) => createReadonlySelectorFamily(options, s),
|
|
45
45
|
} as const,
|
|
46
|
-
)
|
|
46
|
+
) satisfies ReadonlySelectorFamily<T, K>
|
|
47
47
|
store.families.set(options.key, readonlySelectorFamily)
|
|
48
48
|
return readonlySelectorFamily
|
|
49
49
|
}
|