atom.io 0.20.3 → 0.21.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/data/dist/index.cjs +4 -4
- package/data/dist/index.js +1 -1
- package/data/src/join.ts +3 -8
- package/dist/{chunk-SMZRGPN6.js → chunk-HITX3MO4.js} +2 -2
- package/dist/chunk-PNIHPILQ.js +8 -0
- package/dist/{chunk-2AIFLP2B.js → chunk-RT43TVKP.js} +2 -2
- package/dist/index.cjs +4 -4
- package/dist/index.d.ts +2 -2
- package/dist/index.js +5 -7
- package/internal/dist/index.cjs +56 -74
- package/internal/dist/index.d.ts +11 -7
- package/internal/dist/index.js +55 -73
- package/internal/src/atom/create-regular-atom.ts +1 -1
- package/internal/src/atom/dispose-atom.ts +42 -0
- package/internal/src/atom/index.ts +1 -1
- package/internal/src/future.ts +6 -20
- package/internal/src/get-state/get-from-store.ts +1 -2
- package/internal/src/mutable/tracker.ts +2 -24
- package/internal/src/operation.ts +0 -1
- package/internal/src/selector/{delete-selector.ts → dispose-selector.ts} +3 -2
- package/internal/src/selector/index.ts +1 -1
- package/internal/src/store/deposit.ts +5 -0
- package/internal/src/store/store.ts +5 -1
- package/internal/src/subscribe/recall-state.ts +3 -3
- package/internal/src/subscribe/subscribe-to-state.ts +16 -3
- package/introspection/dist/index.cjs +251 -119
- package/introspection/dist/index.d.ts +43 -6
- package/introspection/dist/index.js +226 -96
- package/introspection/src/attach-atom-index.ts +68 -47
- package/introspection/src/attach-introspection-states.ts +0 -1
- package/introspection/src/attach-selector-index.ts +76 -59
- package/introspection/src/attach-timeline-family.ts +2 -17
- package/introspection/src/auditor.ts +135 -0
- package/introspection/src/index.ts +8 -18
- package/package.json +12 -12
- package/react-devtools/dist/index.cjs +3 -3
- package/react-devtools/dist/index.d.ts +5 -5
- package/react-devtools/dist/index.js +4 -4
- package/react-devtools/src/StateIndex.tsx +8 -27
- package/realtime-client/dist/index.cjs +1 -1
- package/realtime-client/dist/index.js +1 -1
- package/realtime-client/src/sync-continuity.ts +2 -2
- package/realtime-react/dist/index.cjs +1 -1
- package/realtime-react/dist/index.js +1 -1
- package/realtime-server/dist/index.cjs +2 -2
- package/realtime-server/dist/index.js +1 -1
- package/realtime-testing/dist/index.cjs +4 -4
- package/realtime-testing/dist/index.js +1 -1
- package/src/dispose.ts +3 -3
- package/src/validators.ts +0 -6
- package/internal/src/atom/delete-atom.ts +0 -40
package/internal/dist/index.js
CHANGED
|
@@ -11,44 +11,30 @@ function arbitrary(random = Math.random) {
|
|
|
11
11
|
// internal/src/future.ts
|
|
12
12
|
var Future = class extends Promise {
|
|
13
13
|
constructor(executor) {
|
|
14
|
-
let promise;
|
|
15
14
|
let superResolve;
|
|
16
15
|
let superReject;
|
|
17
16
|
super((resolve, reject) => {
|
|
18
17
|
superResolve = resolve;
|
|
19
18
|
superReject = reject;
|
|
20
|
-
promise = executor instanceof Promise ? executor : new Promise(executor);
|
|
21
|
-
promise.then(
|
|
22
|
-
(value) => {
|
|
23
|
-
if (promise) {
|
|
24
|
-
this.pass(promise, value);
|
|
25
|
-
}
|
|
26
|
-
},
|
|
27
|
-
(reason) => {
|
|
28
|
-
if (promise) {
|
|
29
|
-
this.fail(promise, reason);
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
);
|
|
33
19
|
});
|
|
34
|
-
this.destiny = promise;
|
|
35
20
|
this.resolve = superResolve;
|
|
36
21
|
this.reject = superReject;
|
|
22
|
+
this.use(executor instanceof Promise ? executor : new Promise(executor));
|
|
37
23
|
}
|
|
38
24
|
pass(promise, value) {
|
|
39
|
-
if (promise === this.
|
|
25
|
+
if (promise === this.fate) {
|
|
40
26
|
this.resolve(value);
|
|
41
27
|
}
|
|
42
28
|
}
|
|
43
29
|
fail(promise, reason) {
|
|
44
|
-
if (promise === this.
|
|
30
|
+
if (promise === this.fate) {
|
|
45
31
|
this.reject(reason);
|
|
46
32
|
}
|
|
47
33
|
}
|
|
48
34
|
use(value) {
|
|
49
35
|
if (value instanceof Promise) {
|
|
50
36
|
const promise = value;
|
|
51
|
-
this.
|
|
37
|
+
this.fate = promise;
|
|
52
38
|
promise.then(
|
|
53
39
|
(resolved) => {
|
|
54
40
|
this.pass(promise, resolved);
|
|
@@ -59,7 +45,7 @@ var Future = class extends Promise {
|
|
|
59
45
|
);
|
|
60
46
|
} else {
|
|
61
47
|
this.resolve(value);
|
|
62
|
-
this.
|
|
48
|
+
this.fate = void 0;
|
|
63
49
|
}
|
|
64
50
|
}
|
|
65
51
|
};
|
|
@@ -158,9 +144,11 @@ var Store = class {
|
|
|
158
144
|
);
|
|
159
145
|
this.on = {
|
|
160
146
|
atomCreation: new Subject(),
|
|
147
|
+
atomDisposal: new Subject(),
|
|
161
148
|
selectorCreation: new Subject(),
|
|
162
|
-
|
|
149
|
+
selectorDisposal: new Subject(),
|
|
163
150
|
timelineCreation: new Subject(),
|
|
151
|
+
transactionCreation: new Subject(),
|
|
164
152
|
transactionApplying: new StatefulSubject(
|
|
165
153
|
null
|
|
166
154
|
),
|
|
@@ -942,8 +930,8 @@ function createStandaloneSelector(options, store) {
|
|
|
942
930
|
return createReadonlySelector(options, void 0, store);
|
|
943
931
|
}
|
|
944
932
|
|
|
945
|
-
// internal/src/selector/
|
|
946
|
-
function
|
|
933
|
+
// internal/src/selector/dispose-selector.ts
|
|
934
|
+
function disposeSelector(selectorToken, store) {
|
|
947
935
|
const target = newest(store);
|
|
948
936
|
const { key } = selectorToken;
|
|
949
937
|
switch (selectorToken.type) {
|
|
@@ -964,20 +952,21 @@ function deleteSelector(selectorToken, store) {
|
|
|
964
952
|
);
|
|
965
953
|
for (const downstreamToken of downstreamTokens) {
|
|
966
954
|
if (downstreamToken) {
|
|
967
|
-
|
|
955
|
+
disposeSelector(downstreamToken, store);
|
|
968
956
|
}
|
|
969
957
|
}
|
|
970
958
|
target.selectorGraph.delete(key);
|
|
971
959
|
store.logger.info(`\u{1F525}`, selectorToken.type, key, `deleted`);
|
|
960
|
+
store.on.selectorDisposal.next(selectorToken);
|
|
972
961
|
}
|
|
973
962
|
|
|
974
963
|
// internal/src/subscribe/recall-state.ts
|
|
975
964
|
var recallState = (state, store) => {
|
|
976
965
|
const target = newest(store);
|
|
977
|
-
if (
|
|
978
|
-
return target.
|
|
966
|
+
if (target.operation.open) {
|
|
967
|
+
return target.operation.prev.get(state.key);
|
|
979
968
|
}
|
|
980
|
-
return target.
|
|
969
|
+
return target.valueMap.get(state.key);
|
|
981
970
|
};
|
|
982
971
|
|
|
983
972
|
// internal/src/subscribe/subscribe-to-root-atoms.ts
|
|
@@ -1026,11 +1015,24 @@ var subscribeToRootAtoms = (selector, store) => {
|
|
|
1026
1015
|
|
|
1027
1016
|
// internal/src/subscribe/subscribe-to-state.ts
|
|
1028
1017
|
function subscribeToState(token, handleUpdate, key, store) {
|
|
1018
|
+
function safelyHandleUpdate(update) {
|
|
1019
|
+
if (store.operation.open) {
|
|
1020
|
+
const unsubscribe2 = store.on.operationClose.subscribe(
|
|
1021
|
+
`state subscription ${key}`,
|
|
1022
|
+
() => {
|
|
1023
|
+
unsubscribe2();
|
|
1024
|
+
handleUpdate(update);
|
|
1025
|
+
}
|
|
1026
|
+
);
|
|
1027
|
+
} else {
|
|
1028
|
+
handleUpdate(update);
|
|
1029
|
+
}
|
|
1030
|
+
}
|
|
1029
1031
|
const state = withdrawOrCreate(token, store);
|
|
1030
1032
|
store.logger.info(`\u{1F440}`, state.type, state.key, `Adding subscription "${key}"`);
|
|
1031
1033
|
const isSelector = state.type === `selector` || state.type === `readonly_selector`;
|
|
1032
1034
|
let dependencyUnsubFunctions = null;
|
|
1033
|
-
let updateHandler =
|
|
1035
|
+
let updateHandler = safelyHandleUpdate;
|
|
1034
1036
|
if (isSelector) {
|
|
1035
1037
|
dependencyUnsubFunctions = subscribeToRootAtoms(state, store);
|
|
1036
1038
|
updateHandler = (update) => {
|
|
@@ -1038,7 +1040,7 @@ function subscribeToState(token, handleUpdate, key, store) {
|
|
|
1038
1040
|
dependencyUnsubFunctions.length = 0;
|
|
1039
1041
|
dependencyUnsubFunctions.push(...subscribeToRootAtoms(state, store));
|
|
1040
1042
|
}
|
|
1041
|
-
|
|
1043
|
+
safelyHandleUpdate(update);
|
|
1042
1044
|
};
|
|
1043
1045
|
}
|
|
1044
1046
|
const mainUnsubFunction = state.subject.subscribe(key, updateHandler);
|
|
@@ -1127,18 +1129,7 @@ var Tracker = class {
|
|
|
1127
1129
|
this.unsubscribeFromInnerValue = originalInnerValue.subscribe(
|
|
1128
1130
|
subscriptionKey,
|
|
1129
1131
|
(update) => {
|
|
1130
|
-
|
|
1131
|
-
const unsubscribe = target.on.operationClose.subscribe(
|
|
1132
|
-
subscriptionKey,
|
|
1133
|
-
() => {
|
|
1134
|
-
unsubscribe();
|
|
1135
|
-
setIntoStore(latestUpdateState, update, target);
|
|
1136
|
-
}
|
|
1137
|
-
);
|
|
1138
|
-
} else {
|
|
1139
|
-
setIntoStore(mutableState, (current) => current, target);
|
|
1140
|
-
setIntoStore(latestUpdateState, update, target);
|
|
1141
|
-
}
|
|
1132
|
+
setIntoStore(latestUpdateState, update, target);
|
|
1142
1133
|
}
|
|
1143
1134
|
);
|
|
1144
1135
|
this.unsubscribeFromState = subscribeToState(
|
|
@@ -1149,18 +1140,7 @@ var Tracker = class {
|
|
|
1149
1140
|
this.unsubscribeFromInnerValue = update.newValue.subscribe(
|
|
1150
1141
|
subscriptionKey,
|
|
1151
1142
|
(transceiverUpdate) => {
|
|
1152
|
-
|
|
1153
|
-
const unsubscribe = target.on.operationClose.subscribe(
|
|
1154
|
-
subscriptionKey,
|
|
1155
|
-
() => {
|
|
1156
|
-
unsubscribe();
|
|
1157
|
-
setIntoStore(latestUpdateState, transceiverUpdate, target);
|
|
1158
|
-
}
|
|
1159
|
-
);
|
|
1160
|
-
} else {
|
|
1161
|
-
setIntoStore(mutableState, (current) => current, target);
|
|
1162
|
-
setIntoStore(latestUpdateState, transceiverUpdate, target);
|
|
1163
|
-
}
|
|
1143
|
+
setIntoStore(latestUpdateState, transceiverUpdate, target);
|
|
1164
1144
|
}
|
|
1165
1145
|
);
|
|
1166
1146
|
}
|
|
@@ -1597,8 +1577,8 @@ function createStandaloneAtom(options, store) {
|
|
|
1597
1577
|
return createRegularAtom(options, void 0, store);
|
|
1598
1578
|
}
|
|
1599
1579
|
|
|
1600
|
-
// internal/src/atom/
|
|
1601
|
-
function
|
|
1580
|
+
// internal/src/atom/dispose-atom.ts
|
|
1581
|
+
function disposeAtom(atomToken, store) {
|
|
1602
1582
|
var _a, _b;
|
|
1603
1583
|
const target = newest(store);
|
|
1604
1584
|
const { key } = atomToken;
|
|
@@ -1610,27 +1590,29 @@ function deleteAtom(atomToken, store) {
|
|
|
1610
1590
|
key,
|
|
1611
1591
|
`Tried to delete atom, but it does not exist in the store.`
|
|
1612
1592
|
);
|
|
1613
|
-
}
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1593
|
+
} else {
|
|
1594
|
+
(_a = atom.cleanup) == null ? void 0 : _a.call(atom);
|
|
1595
|
+
target.atoms.delete(key);
|
|
1596
|
+
target.valueMap.delete(key);
|
|
1597
|
+
const selectorKeys = target.selectorAtoms.getRelatedKeys(key);
|
|
1598
|
+
if (selectorKeys) {
|
|
1599
|
+
for (const selectorKey of selectorKeys) {
|
|
1600
|
+
const token = (_b = target.selectors.get(selectorKey)) != null ? _b : target.readonlySelectors.get(selectorKey);
|
|
1601
|
+
if (token) {
|
|
1602
|
+
disposeSelector(token, store);
|
|
1603
|
+
}
|
|
1623
1604
|
}
|
|
1624
1605
|
}
|
|
1606
|
+
target.selectorAtoms.delete(key);
|
|
1607
|
+
target.atomsThatAreDefault.delete(key);
|
|
1608
|
+
target.timelineAtoms.delete(key);
|
|
1609
|
+
if (atomToken.type === `mutable_atom`) {
|
|
1610
|
+
const updateToken = getUpdateToken(atomToken);
|
|
1611
|
+
disposeAtom(updateToken, store);
|
|
1612
|
+
}
|
|
1613
|
+
store.logger.info(`\u{1F525}`, `atom`, key, `deleted`);
|
|
1614
|
+
store.on.atomDisposal.next(atomToken);
|
|
1625
1615
|
}
|
|
1626
|
-
target.selectorAtoms.delete(key);
|
|
1627
|
-
target.atomsThatAreDefault.delete(key);
|
|
1628
|
-
target.timelineAtoms.delete(key);
|
|
1629
|
-
if (atomToken.type === `mutable_atom`) {
|
|
1630
|
-
const updateToken = getUpdateToken(atomToken);
|
|
1631
|
-
deleteAtom(updateToken, store);
|
|
1632
|
-
}
|
|
1633
|
-
store.logger.info(`\u{1F525}`, `atom`, key, `deleted`);
|
|
1634
1616
|
}
|
|
1635
1617
|
|
|
1636
1618
|
// internal/src/get-environment-data.ts
|
|
@@ -2285,4 +2267,4 @@ function getEpochNumberOfAction(transactionKey, store) {
|
|
|
2285
2267
|
// internal/src/transaction/index.ts
|
|
2286
2268
|
var TRANSACTION_PHASES = [`idle`, `building`, `applying`];
|
|
2287
2269
|
|
|
2288
|
-
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,
|
|
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, withdrawOrCreate };
|
|
@@ -16,7 +16,7 @@ import { subscribeToState } from "../subscribe"
|
|
|
16
16
|
import { markAtomAsDefault } from "./is-default"
|
|
17
17
|
|
|
18
18
|
export function createRegularAtom<T>(
|
|
19
|
-
options:
|
|
19
|
+
options: RegularAtomOptions<T>,
|
|
20
20
|
family: FamilyMetadata | undefined,
|
|
21
21
|
store: Store,
|
|
22
22
|
): RegularAtomToken<T> {
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { AtomToken } from "atom.io"
|
|
2
|
+
|
|
3
|
+
import type { Store } from ".."
|
|
4
|
+
import { disposeSelector, getUpdateToken, newest } from ".."
|
|
5
|
+
|
|
6
|
+
export function disposeAtom(atomToken: AtomToken<unknown>, store: Store): void {
|
|
7
|
+
const target = newest(store)
|
|
8
|
+
const { key } = atomToken
|
|
9
|
+
const atom = target.atoms.get(key)
|
|
10
|
+
if (!atom) {
|
|
11
|
+
store.logger.error(
|
|
12
|
+
`❌`,
|
|
13
|
+
`atom`,
|
|
14
|
+
key,
|
|
15
|
+
`Tried to delete atom, but it does not exist in the store.`,
|
|
16
|
+
)
|
|
17
|
+
} else {
|
|
18
|
+
atom.cleanup?.()
|
|
19
|
+
target.atoms.delete(key)
|
|
20
|
+
target.valueMap.delete(key)
|
|
21
|
+
const selectorKeys = target.selectorAtoms.getRelatedKeys(key)
|
|
22
|
+
if (selectorKeys) {
|
|
23
|
+
for (const selectorKey of selectorKeys) {
|
|
24
|
+
const token =
|
|
25
|
+
target.selectors.get(selectorKey) ??
|
|
26
|
+
target.readonlySelectors.get(selectorKey)
|
|
27
|
+
if (token) {
|
|
28
|
+
disposeSelector(token, store)
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
target.selectorAtoms.delete(key)
|
|
33
|
+
target.atomsThatAreDefault.delete(key)
|
|
34
|
+
target.timelineAtoms.delete(key)
|
|
35
|
+
if (atomToken.type === `mutable_atom`) {
|
|
36
|
+
const updateToken = getUpdateToken(atomToken)
|
|
37
|
+
disposeAtom(updateToken, store)
|
|
38
|
+
}
|
|
39
|
+
store.logger.info(`🔥`, `atom`, key, `deleted`)
|
|
40
|
+
store.on.atomDisposal.next(atomToken)
|
|
41
|
+
}
|
|
42
|
+
}
|
package/internal/src/future.ts
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* Can be constructed like a Promise, or from an existing Promise.
|
|
9
9
|
*/
|
|
10
10
|
export class Future<T> extends Promise<T> {
|
|
11
|
-
private
|
|
11
|
+
private fate: Promise<T> | undefined
|
|
12
12
|
private resolve: (value: T) => void
|
|
13
13
|
private reject: (reason?: any) => void
|
|
14
14
|
|
|
@@ -17,38 +17,24 @@ export class Future<T> extends Promise<T> {
|
|
|
17
17
|
| Promise<T>
|
|
18
18
|
| ((resolve: (value: T) => void, reject: (reason?: any) => void) => void),
|
|
19
19
|
) {
|
|
20
|
-
let promise: Promise<T> | undefined
|
|
21
20
|
let superResolve: ((value: T) => void) | undefined
|
|
22
21
|
let superReject: ((reason?: any) => void) | undefined
|
|
23
22
|
super((resolve, reject) => {
|
|
24
23
|
superResolve = resolve
|
|
25
24
|
superReject = reject
|
|
26
|
-
promise = executor instanceof Promise ? executor : new Promise(executor)
|
|
27
|
-
promise.then(
|
|
28
|
-
(value) => {
|
|
29
|
-
if (promise) {
|
|
30
|
-
this.pass(promise, value)
|
|
31
|
-
}
|
|
32
|
-
},
|
|
33
|
-
(reason) => {
|
|
34
|
-
if (promise) {
|
|
35
|
-
this.fail(promise, reason)
|
|
36
|
-
}
|
|
37
|
-
},
|
|
38
|
-
)
|
|
39
25
|
})
|
|
40
|
-
this.destiny = promise
|
|
41
26
|
this.resolve = superResolve as (value: T) => void
|
|
42
27
|
this.reject = superReject as (reason?: any) => void
|
|
28
|
+
this.use(executor instanceof Promise ? executor : new Promise(executor))
|
|
43
29
|
}
|
|
44
30
|
|
|
45
31
|
private pass(promise: Promise<T>, value: T) {
|
|
46
|
-
if (promise === this.
|
|
32
|
+
if (promise === this.fate) {
|
|
47
33
|
this.resolve(value)
|
|
48
34
|
}
|
|
49
35
|
}
|
|
50
36
|
private fail(promise: Promise<T>, reason: any) {
|
|
51
|
-
if (promise === this.
|
|
37
|
+
if (promise === this.fate) {
|
|
52
38
|
this.reject(reason)
|
|
53
39
|
}
|
|
54
40
|
}
|
|
@@ -56,7 +42,7 @@ export class Future<T> extends Promise<T> {
|
|
|
56
42
|
public use(value: Promise<T> | T): void {
|
|
57
43
|
if (value instanceof Promise) {
|
|
58
44
|
const promise = value
|
|
59
|
-
this.
|
|
45
|
+
this.fate = promise
|
|
60
46
|
promise.then(
|
|
61
47
|
(resolved) => {
|
|
62
48
|
this.pass(promise, resolved)
|
|
@@ -67,7 +53,7 @@ export class Future<T> extends Promise<T> {
|
|
|
67
53
|
)
|
|
68
54
|
} else {
|
|
69
55
|
this.resolve(value)
|
|
70
|
-
this.
|
|
56
|
+
this.fate = undefined
|
|
71
57
|
}
|
|
72
58
|
}
|
|
73
59
|
}
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import type { ReadableToken } from "atom.io"
|
|
2
2
|
|
|
3
|
-
import { NotFoundError } from "../not-found-error"
|
|
4
3
|
import type { Store } from "../store"
|
|
5
|
-
import {
|
|
4
|
+
import { withdrawOrCreate } from "../store"
|
|
6
5
|
import { readOrComputeValue } from "./read-or-compute-value"
|
|
7
6
|
|
|
8
7
|
export function getFromStore<T>(token: ReadableToken<T>, store: Store): T {
|
|
@@ -66,18 +66,7 @@ export class Tracker<Mutable extends Transceiver<any>> {
|
|
|
66
66
|
this.unsubscribeFromInnerValue = originalInnerValue.subscribe(
|
|
67
67
|
subscriptionKey,
|
|
68
68
|
(update) => {
|
|
69
|
-
|
|
70
|
-
const unsubscribe = target.on.operationClose.subscribe(
|
|
71
|
-
subscriptionKey,
|
|
72
|
-
() => {
|
|
73
|
-
unsubscribe()
|
|
74
|
-
setIntoStore(latestUpdateState, update, target)
|
|
75
|
-
},
|
|
76
|
-
)
|
|
77
|
-
} else {
|
|
78
|
-
setIntoStore(mutableState, (current) => current, target)
|
|
79
|
-
setIntoStore(latestUpdateState, update, target)
|
|
80
|
-
}
|
|
69
|
+
setIntoStore(latestUpdateState, update, target)
|
|
81
70
|
},
|
|
82
71
|
)
|
|
83
72
|
this.unsubscribeFromState = subscribeToState(
|
|
@@ -88,18 +77,7 @@ export class Tracker<Mutable extends Transceiver<any>> {
|
|
|
88
77
|
this.unsubscribeFromInnerValue = update.newValue.subscribe(
|
|
89
78
|
subscriptionKey,
|
|
90
79
|
(transceiverUpdate) => {
|
|
91
|
-
|
|
92
|
-
const unsubscribe = target.on.operationClose.subscribe(
|
|
93
|
-
subscriptionKey,
|
|
94
|
-
() => {
|
|
95
|
-
unsubscribe()
|
|
96
|
-
setIntoStore(latestUpdateState, transceiverUpdate, target)
|
|
97
|
-
},
|
|
98
|
-
)
|
|
99
|
-
} else {
|
|
100
|
-
setIntoStore(mutableState, (current) => current, target)
|
|
101
|
-
setIntoStore(latestUpdateState, transceiverUpdate, target)
|
|
102
|
-
}
|
|
80
|
+
setIntoStore(latestUpdateState, transceiverUpdate, target)
|
|
103
81
|
},
|
|
104
82
|
)
|
|
105
83
|
}
|
|
@@ -3,7 +3,7 @@ import type { ReadonlySelectorToken, WritableSelectorToken } from "atom.io"
|
|
|
3
3
|
import type { Store } from ".."
|
|
4
4
|
import { newest } from ".."
|
|
5
5
|
|
|
6
|
-
export function
|
|
6
|
+
export function disposeSelector(
|
|
7
7
|
selectorToken: ReadonlySelectorToken<unknown> | WritableSelectorToken<unknown>,
|
|
8
8
|
store: Store,
|
|
9
9
|
): void {
|
|
@@ -29,9 +29,10 @@ export function deleteSelector(
|
|
|
29
29
|
)
|
|
30
30
|
for (const downstreamToken of downstreamTokens) {
|
|
31
31
|
if (downstreamToken) {
|
|
32
|
-
|
|
32
|
+
disposeSelector(downstreamToken, store)
|
|
33
33
|
}
|
|
34
34
|
}
|
|
35
35
|
target.selectorGraph.delete(key)
|
|
36
36
|
store.logger.info(`🔥`, selectorToken.type, key, `deleted`)
|
|
37
|
+
store.on.selectorDisposal.next(selectorToken)
|
|
37
38
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export * from "./create-readonly-selector"
|
|
2
2
|
export * from "./create-standalone-selector"
|
|
3
3
|
export * from "./create-writable-selector"
|
|
4
|
-
export * from "./
|
|
4
|
+
export * from "./dispose-selector"
|
|
5
5
|
export * from "./get-selector-dependency-keys"
|
|
6
6
|
export * from "./register-selector"
|
|
7
7
|
export * from "./trace-selector-atoms"
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type {
|
|
2
|
+
AtomToken,
|
|
2
3
|
Func,
|
|
3
4
|
MutableAtomToken,
|
|
4
5
|
ReadableToken,
|
|
@@ -11,10 +12,12 @@ import type {
|
|
|
11
12
|
} from "atom.io"
|
|
12
13
|
|
|
13
14
|
import type {
|
|
15
|
+
Atom,
|
|
14
16
|
MutableAtom,
|
|
15
17
|
ReadableState,
|
|
16
18
|
ReadonlySelector,
|
|
17
19
|
RegularAtom,
|
|
20
|
+
Selector,
|
|
18
21
|
Transceiver,
|
|
19
22
|
WritableSelector,
|
|
20
23
|
WritableState,
|
|
@@ -25,8 +28,10 @@ export function deposit<T>(state: RegularAtom<T>): RegularAtomToken<T>
|
|
|
25
28
|
export function deposit<T extends Transceiver<any>>(
|
|
26
29
|
state: MutableAtom<T, any>,
|
|
27
30
|
): MutableAtomToken<T, any>
|
|
31
|
+
export function deposit<T>(state: Atom<T>): AtomToken<T>
|
|
28
32
|
export function deposit<T>(state: WritableSelector<T>): WritableSelectorToken<T>
|
|
29
33
|
export function deposit<T>(state: ReadonlySelector<T>): ReadonlySelectorToken<T>
|
|
34
|
+
export function deposit<T>(state: Selector<T>): SelectorToken<T>
|
|
30
35
|
export function deposit<T>(state: WritableState<T>): WritableToken<T>
|
|
31
36
|
export function deposit<T extends Func>(
|
|
32
37
|
state: Transaction<T>,
|
|
@@ -82,11 +82,15 @@ export class Store implements Lineage {
|
|
|
82
82
|
|
|
83
83
|
public on = {
|
|
84
84
|
atomCreation: new Subject<AtomToken<unknown>>(),
|
|
85
|
+
atomDisposal: new Subject<AtomToken<unknown>>(),
|
|
85
86
|
selectorCreation: new Subject<
|
|
86
87
|
ReadonlySelectorToken<unknown> | WritableSelectorToken<unknown>
|
|
87
88
|
>(),
|
|
88
|
-
|
|
89
|
+
selectorDisposal: new Subject<
|
|
90
|
+
ReadonlySelectorToken<unknown> | WritableSelectorToken<unknown>
|
|
91
|
+
>(),
|
|
89
92
|
timelineCreation: new Subject<TimelineToken<unknown>>(),
|
|
93
|
+
transactionCreation: new Subject<TransactionToken<Func>>(),
|
|
90
94
|
transactionApplying: new StatefulSubject<TransactionProgress<Func> | null>(
|
|
91
95
|
null,
|
|
92
96
|
),
|
|
@@ -4,8 +4,8 @@ import type { Store } from "../store"
|
|
|
4
4
|
|
|
5
5
|
export const recallState = <T>(state: ReadableState<T>, store: Store): T => {
|
|
6
6
|
const target = newest(store)
|
|
7
|
-
if (
|
|
8
|
-
return target.
|
|
7
|
+
if (target.operation.open) {
|
|
8
|
+
return target.operation.prev.get(state.key)
|
|
9
9
|
}
|
|
10
|
-
return target.
|
|
10
|
+
return target.valueMap.get(state.key)
|
|
11
11
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ReadableToken, UpdateHandler } from "atom.io"
|
|
1
|
+
import type { ReadableToken, StateUpdate, UpdateHandler } from "atom.io"
|
|
2
2
|
|
|
3
3
|
import type { Store } from "../store"
|
|
4
4
|
import { withdrawOrCreate } from "../store"
|
|
@@ -10,12 +10,25 @@ export function subscribeToState<T>(
|
|
|
10
10
|
key: string,
|
|
11
11
|
store: Store,
|
|
12
12
|
): () => void {
|
|
13
|
+
function safelyHandleUpdate(update: StateUpdate<any>): void {
|
|
14
|
+
if (store.operation.open) {
|
|
15
|
+
const unsubscribe = store.on.operationClose.subscribe(
|
|
16
|
+
`state subscription ${key}`,
|
|
17
|
+
() => {
|
|
18
|
+
unsubscribe()
|
|
19
|
+
handleUpdate(update)
|
|
20
|
+
},
|
|
21
|
+
)
|
|
22
|
+
} else {
|
|
23
|
+
handleUpdate(update)
|
|
24
|
+
}
|
|
25
|
+
}
|
|
13
26
|
const state = withdrawOrCreate(token, store)
|
|
14
27
|
store.logger.info(`👀`, state.type, state.key, `Adding subscription "${key}"`)
|
|
15
28
|
const isSelector =
|
|
16
29
|
state.type === `selector` || state.type === `readonly_selector`
|
|
17
30
|
let dependencyUnsubFunctions: (() => void)[] | null = null
|
|
18
|
-
let updateHandler: UpdateHandler<T> =
|
|
31
|
+
let updateHandler: UpdateHandler<T> = safelyHandleUpdate
|
|
19
32
|
if (isSelector) {
|
|
20
33
|
dependencyUnsubFunctions = subscribeToRootAtoms(state, store)
|
|
21
34
|
updateHandler = (update) => {
|
|
@@ -23,7 +36,7 @@ export function subscribeToState<T>(
|
|
|
23
36
|
dependencyUnsubFunctions.length = 0
|
|
24
37
|
dependencyUnsubFunctions.push(...subscribeToRootAtoms(state, store))
|
|
25
38
|
}
|
|
26
|
-
|
|
39
|
+
safelyHandleUpdate(update)
|
|
27
40
|
}
|
|
28
41
|
}
|
|
29
42
|
const mainUnsubFunction = state.subject.subscribe(key, updateHandler)
|