atom.io 0.31.0 → 0.32.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/data/dist/index.d.ts +867 -101
- package/data/dist/index.js +10 -558
- package/data/src/index.ts +0 -2
- package/data/src/struct-family.ts +1 -1
- package/data/src/struct.ts +1 -2
- package/dist/chunk-354XQWHH.js +153 -0
- package/dist/chunk-4LWKCEW3.js +14 -0
- package/dist/chunk-5F2V7S3B.js +83 -0
- package/dist/chunk-ECOMOMUN.js +631 -0
- package/dist/{chunk-42UH5F5Q.js → chunk-GY2XQYZY.js} +2051 -755
- package/dist/chunk-NF7FJKJD.js +107 -0
- package/dist/chunk-R3ZUK5EH.js +1024 -0
- package/dist/chunk-Z2UJW4NQ.js +523 -0
- package/dist/index.d.ts +855 -127
- package/dist/index.js +1 -143
- package/eslint-plugin/dist/index.d.ts +1 -30
- package/eslint-plugin/dist/index.js +0 -146
- package/eslint-plugin/src/index.ts +0 -1
- package/eslint-plugin/src/rules/index.ts +0 -1
- package/internal/dist/index.d.ts +794 -70
- package/internal/dist/index.js +1 -2
- package/internal/src/atom/create-regular-atom.ts +3 -3
- package/internal/src/atom/dispose-atom.ts +4 -13
- package/internal/src/atom/is-default.ts +3 -3
- package/internal/src/caching.ts +5 -5
- package/internal/src/capitalize.ts +3 -0
- package/internal/src/families/create-readonly-selector-family.ts +5 -6
- package/internal/src/families/create-writable-selector-family.ts +1 -4
- package/internal/src/families/dispose-from-store.ts +3 -13
- package/internal/src/families/find-in-store.ts +1 -6
- package/internal/src/get-state/get-from-store.ts +2 -2
- package/internal/src/get-state/read-or-compute-value.ts +1 -1
- package/internal/src/index.ts +19 -9
- package/internal/src/ingest-updates/ingest-creation-disposal.ts +2 -3
- package/internal/src/install-into-store.ts +48 -0
- package/internal/src/join/edit-relations-in-store.ts +32 -0
- package/internal/src/join/find-relations-in-store.ts +124 -0
- package/internal/src/join/get-internal-relations-from-store.ts +14 -0
- package/internal/src/join/get-join.ts +31 -0
- package/internal/src/join/index.ts +5 -0
- package/{data/src/join.ts → internal/src/join/join-internal.ts} +20 -429
- package/internal/src/keys.ts +7 -7
- package/internal/src/molecule.ts +299 -0
- package/internal/src/mutable/create-mutable-atom-family.ts +1 -1
- package/internal/src/mutable/create-mutable-atom.ts +3 -3
- package/internal/src/mutable/get-json-token.ts +1 -1
- package/internal/src/mutable/tracker-family.ts +19 -17
- package/internal/src/mutable/tracker.ts +8 -8
- package/internal/src/not-found-error.ts +8 -30
- package/internal/src/pretty-print.ts +2 -13
- package/internal/src/selector/create-readonly-selector.ts +3 -7
- package/internal/src/selector/create-writable-selector.ts +4 -4
- package/internal/src/selector/dispose-selector.ts +20 -11
- package/internal/src/selector/get-selector-dependency-keys.ts +1 -1
- package/internal/src/selector/register-selector.ts +7 -17
- package/internal/src/selector/trace-selector-atoms.ts +2 -2
- package/internal/src/set-state/copy-mutable-if-needed.ts +1 -1
- package/internal/src/set-state/emit-update.ts +1 -1
- package/internal/src/set-state/evict-downstream.ts +1 -1
- package/internal/src/set-state/set-atom-or-selector.ts +1 -1
- package/internal/src/set-state/set-atom.ts +10 -10
- package/internal/src/set-state/set-into-store.ts +2 -2
- package/internal/src/set-state/stow-update.ts +1 -1
- package/internal/src/store/deposit.ts +10 -8
- package/internal/src/store/store.ts +1 -1
- package/internal/src/store/withdraw.ts +34 -53
- package/internal/src/subscribe/recall-state.ts +1 -1
- package/internal/src/subscribe/subscribe-in-store.ts +3 -3
- package/internal/src/subscribe/subscribe-to-root-atoms.ts +3 -3
- package/internal/src/subscribe/subscribe-to-state.ts +5 -5
- package/internal/src/subscribe/subscribe-to-timeline.ts +3 -3
- package/internal/src/subscribe/subscribe-to-transaction.ts +3 -3
- package/internal/src/timeline/create-timeline.ts +17 -37
- package/internal/src/transaction/act-upon-store.ts +2 -2
- package/internal/src/transaction/apply-transaction.ts +5 -5
- package/internal/src/transaction/assign-transaction-to-continuity.ts +1 -1
- package/internal/src/transaction/build-transaction.ts +5 -8
- package/internal/src/transaction/create-transaction.ts +3 -3
- package/internal/src/transaction/get-epoch-number.ts +3 -3
- package/internal/src/transaction/set-epoch-number.ts +2 -2
- package/introspection/dist/index.d.ts +922 -6
- package/introspection/dist/index.js +2 -620
- package/json/dist/index.d.ts +899 -5
- package/json/dist/index.js +1 -81
- package/json/src/select-json-family.ts +3 -14
- package/package.json +27 -45
- package/react/dist/index.d.ts +921 -3
- package/react/dist/index.js +2 -82
- package/react/src/use-o.ts +1 -1
- package/react/src/use-tl.ts +2 -2
- package/react-devtools/dist/index.css +16 -14
- package/react-devtools/dist/index.d.ts +26 -1
- package/react-devtools/dist/index.js +6 -6
- package/react-devtools/src/devtools.scss +16 -14
- package/realtime/dist/index.d.ts +202 -8
- package/realtime/dist/index.js +2 -107
- package/realtime/src/realtime-continuity.ts +2 -2
- package/realtime/src/shared-room-store.ts +1 -2
- package/realtime-client/dist/index.d.ts +960 -22
- package/realtime-client/dist/index.js +3 -509
- package/realtime-client/src/continuity/register-and-attempt-confirmed-update.ts +3 -3
- package/realtime-client/src/continuity/use-conceal-state.ts +1 -1
- package/realtime-client/src/pull-atom-family-member.ts +2 -2
- package/realtime-client/src/pull-atom.ts +2 -2
- package/realtime-client/src/pull-mutable-atom-family-member.ts +2 -2
- package/realtime-client/src/pull-mutable-atom.ts +2 -2
- package/realtime-client/src/pull-selector-family-member.ts +4 -4
- package/realtime-client/src/pull-selector.ts +4 -4
- package/realtime-client/src/push-state.ts +5 -10
- package/realtime-client/src/server-action.ts +4 -4
- package/realtime-client/src/sync-continuity.ts +6 -6
- package/realtime-react/dist/index.d.ts +166 -12
- package/realtime-react/dist/index.js +5 -154
- package/realtime-react/src/use-pull-atom-family-member.ts +1 -1
- package/realtime-react/src/use-pull-atom.ts +1 -1
- package/realtime-react/src/use-pull-mutable-atom.ts +1 -1
- package/realtime-react/src/use-pull-mutable-family-member.ts +1 -1
- package/realtime-react/src/use-pull-selector-family-member.ts +1 -1
- package/realtime-react/src/use-pull-selector.ts +1 -1
- package/realtime-react/src/use-push.ts +1 -1
- package/realtime-react/src/use-server-action.ts +2 -2
- package/realtime-react/src/use-sync-continuity.ts +1 -1
- package/realtime-server/dist/index.d.ts +971 -28
- package/realtime-server/dist/index.js +3 -1001
- package/realtime-server/src/continuity/prepare-to-serve-transaction-request.ts +1 -1
- package/realtime-server/src/continuity/prepare-to-sync-realtime-continuity.ts +3 -3
- package/realtime-server/src/continuity/subscribe-to-continuity-actions.ts +2 -2
- package/realtime-server/src/continuity/subscribe-to-continuity-perpectives.ts +2 -2
- package/realtime-server/src/ipc-sockets/child-socket.ts +0 -1
- package/realtime-server/src/realtime-action-receiver.ts +1 -1
- package/realtime-server/src/realtime-family-provider.ts +2 -2
- package/realtime-server/src/realtime-mutable-family-provider.ts +2 -2
- package/realtime-server/src/realtime-mutable-provider.ts +2 -2
- package/realtime-server/src/realtime-server-stores/server-room-external-actions.ts +2 -1
- package/realtime-server/src/realtime-server-stores/server-room-external-store.ts +1 -1
- package/realtime-server/src/realtime-server-stores/server-user-store.ts +1 -2
- package/realtime-server/src/realtime-state-provider.ts +2 -2
- package/realtime-testing/dist/index.d.ts +1091 -3
- package/realtime-testing/dist/index.js +23 -26
- package/realtime-testing/src/setup-realtime-test.tsx +6 -5
- package/src/atom.ts +53 -29
- package/src/dispose-state.ts +12 -2
- package/{ephemeral/src → src}/find-state.ts +35 -25
- package/src/get-state.ts +16 -0
- package/src/index.ts +77 -3
- package/src/join.ts +218 -0
- package/src/realm.ts +169 -0
- package/src/selector.ts +20 -0
- package/src/set-state.ts +16 -8
- package/src/silo.ts +13 -7
- package/src/timeline.ts +1 -1
- package/src/transaction.ts +4 -8
- package/transceivers/set-rtx/dist/index.d.ts +37 -2
- package/transceivers/set-rtx/dist/index.js +1 -212
- package/transceivers/set-rtx/src/set-rtx.ts +4 -1
- package/web/dist/index.d.ts +30 -1
- package/web/dist/index.js +1 -15
- package/data/src/until.ts +0 -15
- package/dist/chunk-ICGFFQ3H.js +0 -272
- package/ephemeral/dist/index.d.ts +0 -57
- package/ephemeral/dist/index.js +0 -9
- package/ephemeral/package.json +0 -13
- package/ephemeral/src/index.ts +0 -1
- package/eslint-plugin/src/rules/lifespan.ts +0 -203
- package/immortal/dist/index.d.ts +0 -12
- package/immortal/dist/index.js +0 -9
- package/immortal/package.json +0 -13
- package/immortal/src/index.ts +0 -1
- package/immortal/src/seek-state.ts +0 -60
- package/src/allocate.ts +0 -443
- package/src/molecule.ts +0 -16
package/internal/src/molecule.ts
CHANGED
|
@@ -1,7 +1,306 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
Above,
|
|
3
|
+
Claim,
|
|
4
|
+
CompoundFrom,
|
|
5
|
+
CompoundTypedKey,
|
|
6
|
+
Hierarchy,
|
|
7
|
+
MoleculeCreation,
|
|
8
|
+
MoleculeDisposal,
|
|
9
|
+
MoleculeTransfer,
|
|
10
|
+
SingularTypedKey,
|
|
11
|
+
Vassal,
|
|
12
|
+
} from "atom.io"
|
|
1
13
|
import type { Canonical, stringified } from "atom.io/json"
|
|
14
|
+
import { parseJson, stringifyJson } from "atom.io/json"
|
|
15
|
+
|
|
16
|
+
import { disposeFromStore, findInStore } from "./families"
|
|
17
|
+
import { getTrace } from "./get-trace"
|
|
18
|
+
import { newest } from "./lineage"
|
|
19
|
+
import type { Store } from "./store"
|
|
20
|
+
import { IMPLICIT } from "./store"
|
|
21
|
+
import { isChildStore } from "./transaction"
|
|
2
22
|
|
|
3
23
|
export type Molecule<K extends Canonical> = {
|
|
4
24
|
readonly key: K
|
|
5
25
|
readonly stringKey: stringified<K>
|
|
6
26
|
readonly dependsOn: `all` | `any`
|
|
7
27
|
}
|
|
28
|
+
|
|
29
|
+
export function makeRootMoleculeInStore<S extends string>(
|
|
30
|
+
key: S,
|
|
31
|
+
store: Store = IMPLICIT.STORE,
|
|
32
|
+
): S {
|
|
33
|
+
const molecule = {
|
|
34
|
+
key,
|
|
35
|
+
stringKey: stringifyJson(key),
|
|
36
|
+
dependsOn: `any`,
|
|
37
|
+
} satisfies Molecule<S>
|
|
38
|
+
store.molecules.set(stringifyJson(key), molecule)
|
|
39
|
+
return key
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function allocateIntoStore<
|
|
43
|
+
H extends Hierarchy,
|
|
44
|
+
V extends Vassal<H>,
|
|
45
|
+
A extends Above<V, H>,
|
|
46
|
+
>(
|
|
47
|
+
store: Store,
|
|
48
|
+
provenance: A,
|
|
49
|
+
key: V,
|
|
50
|
+
dependsOn: `all` | `any` = `any`,
|
|
51
|
+
): Claim<V> {
|
|
52
|
+
const origin = provenance as Canonical | [Canonical, Canonical]
|
|
53
|
+
const stringKey = stringifyJson(key)
|
|
54
|
+
const invalidKeys: stringified<Canonical>[] = []
|
|
55
|
+
const target = newest(store)
|
|
56
|
+
|
|
57
|
+
if (Array.isArray(origin)) {
|
|
58
|
+
for (const formerClaim of origin) {
|
|
59
|
+
const claimString = stringifyJson(formerClaim)
|
|
60
|
+
const claim = target.molecules.get(claimString)
|
|
61
|
+
if (claim) {
|
|
62
|
+
store.moleculeGraph.set(claimString, stringKey, { source: claimString })
|
|
63
|
+
} else {
|
|
64
|
+
invalidKeys.push(claimString)
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
} else {
|
|
68
|
+
const claimString = stringifyJson(origin)
|
|
69
|
+
const claim = target.molecules.get(claimString)
|
|
70
|
+
if (claim) {
|
|
71
|
+
store.moleculeGraph.set(claimString, stringKey, { source: claimString })
|
|
72
|
+
} else {
|
|
73
|
+
invalidKeys.push(claimString)
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
if (invalidKeys.length === 0) {
|
|
77
|
+
target.molecules.set(stringKey, { key, stringKey, dependsOn })
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const creationEvent: MoleculeCreation = {
|
|
81
|
+
type: `molecule_creation`,
|
|
82
|
+
key,
|
|
83
|
+
provenance: origin,
|
|
84
|
+
}
|
|
85
|
+
const isTransaction =
|
|
86
|
+
isChildStore(target) && target.transactionMeta.phase === `building`
|
|
87
|
+
if (isTransaction) {
|
|
88
|
+
target.transactionMeta.update.updates.push(creationEvent)
|
|
89
|
+
} else {
|
|
90
|
+
target.on.moleculeCreation.next(creationEvent)
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
for (const claim of invalidKeys) {
|
|
94
|
+
const disposal = store.disposalTraces.buffer.find(
|
|
95
|
+
(item) => item?.key === claim,
|
|
96
|
+
)
|
|
97
|
+
store.logger.error(
|
|
98
|
+
`❌`,
|
|
99
|
+
`molecule`,
|
|
100
|
+
key,
|
|
101
|
+
`allocation failed:`,
|
|
102
|
+
`Could not allocate to ${claim} in store "${store.config.name}".`,
|
|
103
|
+
disposal
|
|
104
|
+
? `\n ${claim} was most recently disposed\n${disposal.trace}`
|
|
105
|
+
: `No previous disposal trace for ${claim} was found.`,
|
|
106
|
+
)
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
return key as Claim<V>
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export function fuseWithinStore<
|
|
113
|
+
H extends Hierarchy,
|
|
114
|
+
C extends CompoundFrom<H>,
|
|
115
|
+
T extends C extends CompoundTypedKey<infer t, any, any> ? t : never,
|
|
116
|
+
A extends C extends CompoundTypedKey<any, infer a, any> ? a : never,
|
|
117
|
+
B extends C extends CompoundTypedKey<any, any, infer b> ? b : never,
|
|
118
|
+
>(
|
|
119
|
+
store: Store,
|
|
120
|
+
type: T,
|
|
121
|
+
sideA: SingularTypedKey<A>,
|
|
122
|
+
sideB: SingularTypedKey<B>,
|
|
123
|
+
): Claim<CompoundTypedKey<T, A, B>> {
|
|
124
|
+
const compoundKey: CompoundTypedKey<T, A, B> =
|
|
125
|
+
`T$--${type}==${sideA}++${sideB}`
|
|
126
|
+
const above = [sideA, sideB] as Above<Vassal<H>, H>
|
|
127
|
+
allocateIntoStore<H, Vassal<H>, Above<Vassal<H>, H>>(
|
|
128
|
+
store,
|
|
129
|
+
above,
|
|
130
|
+
compoundKey as Vassal<H>,
|
|
131
|
+
`all`,
|
|
132
|
+
)
|
|
133
|
+
return compoundKey
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export function deallocateFromStore<H extends Hierarchy, V extends Vassal<H>>(
|
|
137
|
+
store: Store,
|
|
138
|
+
claim: Claim<V>,
|
|
139
|
+
): void {
|
|
140
|
+
const stringKey = stringifyJson(claim)
|
|
141
|
+
|
|
142
|
+
const molecule = store.molecules.get(stringKey)
|
|
143
|
+
if (!molecule) {
|
|
144
|
+
const disposal = store.disposalTraces.buffer.find(
|
|
145
|
+
(item) => item?.key === stringKey,
|
|
146
|
+
)
|
|
147
|
+
store.logger.error(
|
|
148
|
+
`❌`,
|
|
149
|
+
`molecule`,
|
|
150
|
+
claim,
|
|
151
|
+
`deallocation failed:`,
|
|
152
|
+
`Could not find allocation for ${stringKey} in store "${store.config.name}".`,
|
|
153
|
+
disposal
|
|
154
|
+
? `\n This state was most recently deallocated\n${disposal.trace}`
|
|
155
|
+
: `No previous disposal trace for ${stringKey} was found.`,
|
|
156
|
+
)
|
|
157
|
+
return
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
const joinKeys = store.moleculeJoins.getRelatedKeys(
|
|
161
|
+
molecule.key as string /* 💥 RECONCILE */,
|
|
162
|
+
)
|
|
163
|
+
if (joinKeys) {
|
|
164
|
+
for (const joinKey of joinKeys) {
|
|
165
|
+
const join = store.joins.get(joinKey)
|
|
166
|
+
if (join) {
|
|
167
|
+
join.relations.delete(molecule.key)
|
|
168
|
+
join.molecules.delete(molecule.stringKey) // get rid of
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
store.moleculeJoins.delete(molecule.stringKey)
|
|
173
|
+
|
|
174
|
+
const provenance: stringified<Canonical>[] = []
|
|
175
|
+
|
|
176
|
+
const values: [string, any][] = []
|
|
177
|
+
const disposalEvent: MoleculeDisposal = {
|
|
178
|
+
type: `molecule_disposal`,
|
|
179
|
+
key: molecule.key,
|
|
180
|
+
values,
|
|
181
|
+
provenance,
|
|
182
|
+
}
|
|
183
|
+
const target = newest(store)
|
|
184
|
+
target.molecules.delete(stringKey)
|
|
185
|
+
const isTransaction =
|
|
186
|
+
isChildStore(target) && target.transactionMeta.phase === `building`
|
|
187
|
+
if (isTransaction) {
|
|
188
|
+
target.transactionMeta.update.updates.push(disposalEvent)
|
|
189
|
+
}
|
|
190
|
+
const relatedMolecules = store.moleculeGraph.getRelationEntries({
|
|
191
|
+
downstreamMoleculeKey: molecule.stringKey,
|
|
192
|
+
})
|
|
193
|
+
if (relatedMolecules) {
|
|
194
|
+
for (const [relatedStringKey, { source }] of relatedMolecules) {
|
|
195
|
+
if (source === molecule.stringKey) {
|
|
196
|
+
const relatedKey = parseJson(relatedStringKey)
|
|
197
|
+
deallocateFromStore<any, any>(store, relatedKey)
|
|
198
|
+
} else {
|
|
199
|
+
provenance.push(source)
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
const familyKeys = target.moleculeData.getRelatedKeys(molecule.stringKey)
|
|
204
|
+
if (familyKeys) {
|
|
205
|
+
for (const familyKey of familyKeys) {
|
|
206
|
+
// biome-ignore lint/style/noNonNullAssertion: tokens of molecules must have a family
|
|
207
|
+
const family = target.families.get(familyKey)!
|
|
208
|
+
const token = findInStore(store, family, molecule.key)
|
|
209
|
+
values.push([family.key, token])
|
|
210
|
+
disposeFromStore(store, token)
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
target.moleculeGraph.delete(molecule.stringKey)
|
|
215
|
+
target.moleculeJoins.delete(molecule.stringKey)
|
|
216
|
+
target.moleculeData.delete(molecule.stringKey)
|
|
217
|
+
|
|
218
|
+
if (!isTransaction) {
|
|
219
|
+
target.on.moleculeDisposal.next(disposalEvent)
|
|
220
|
+
}
|
|
221
|
+
target.molecules.delete(molecule.stringKey)
|
|
222
|
+
|
|
223
|
+
const trace = getTrace(new Error())
|
|
224
|
+
store.disposalTraces.add({ key: stringKey, trace })
|
|
225
|
+
}
|
|
226
|
+
export function claimWithinStore<
|
|
227
|
+
H extends Hierarchy,
|
|
228
|
+
V extends Exclude<Vassal<H>, CompoundTypedKey>,
|
|
229
|
+
A extends Above<V, H>,
|
|
230
|
+
>(
|
|
231
|
+
store: Store,
|
|
232
|
+
newProvenance: A,
|
|
233
|
+
claim: Claim<V>,
|
|
234
|
+
exclusive?: `exclusive`,
|
|
235
|
+
): Claim<V> {
|
|
236
|
+
const stringKey = stringifyJson(claim)
|
|
237
|
+
const target = newest(store)
|
|
238
|
+
const molecule = target.molecules.get(stringKey)
|
|
239
|
+
if (!molecule) {
|
|
240
|
+
const disposal = store.disposalTraces.buffer.find(
|
|
241
|
+
(item) => item?.key === stringKey,
|
|
242
|
+
)
|
|
243
|
+
store.logger.error(
|
|
244
|
+
`❌`,
|
|
245
|
+
`molecule`,
|
|
246
|
+
claim,
|
|
247
|
+
`claim failed:`,
|
|
248
|
+
`Could not allocate to ${stringKey} in store "${store.config.name}".`,
|
|
249
|
+
disposal
|
|
250
|
+
? `\n ${stringKey} was most recently disposed\n${disposal.trace}`
|
|
251
|
+
: `No previous disposal trace for ${stringKey} was found.`,
|
|
252
|
+
)
|
|
253
|
+
return claim
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
const newProvenanceKey = stringifyJson(newProvenance as Canonical)
|
|
257
|
+
const newProvenanceMolecule = target.molecules.get(newProvenanceKey)
|
|
258
|
+
if (!newProvenanceMolecule) {
|
|
259
|
+
const disposal = store.disposalTraces.buffer.find(
|
|
260
|
+
(item) => item?.key === newProvenanceKey,
|
|
261
|
+
)
|
|
262
|
+
store.logger.error(
|
|
263
|
+
`❌`,
|
|
264
|
+
`molecule`,
|
|
265
|
+
claim,
|
|
266
|
+
`claim failed:`,
|
|
267
|
+
`Could not allocate to ${newProvenanceKey} in store "${store.config.name}".`,
|
|
268
|
+
disposal
|
|
269
|
+
? `\n ${newProvenanceKey} was most recently disposed\n${disposal.trace}`
|
|
270
|
+
: `No previous disposal trace for ${newProvenanceKey} was found.`,
|
|
271
|
+
)
|
|
272
|
+
return claim
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
const priorProvenance = store.moleculeGraph
|
|
276
|
+
.getRelationEntries({
|
|
277
|
+
downstreamMoleculeKey: molecule.stringKey,
|
|
278
|
+
})
|
|
279
|
+
.filter(([, { source }]) => source !== stringKey)
|
|
280
|
+
.map(([key]) => parseJson(key))
|
|
281
|
+
if (exclusive) {
|
|
282
|
+
target.moleculeGraph.delete(stringKey)
|
|
283
|
+
}
|
|
284
|
+
target.moleculeGraph.set(
|
|
285
|
+
{
|
|
286
|
+
upstreamMoleculeKey: newProvenanceMolecule.stringKey,
|
|
287
|
+
downstreamMoleculeKey: molecule.stringKey,
|
|
288
|
+
},
|
|
289
|
+
{
|
|
290
|
+
source: newProvenanceMolecule.stringKey,
|
|
291
|
+
},
|
|
292
|
+
)
|
|
293
|
+
const transferEvent: MoleculeTransfer = {
|
|
294
|
+
type: `molecule_transfer`,
|
|
295
|
+
key: molecule.key,
|
|
296
|
+
from: priorProvenance,
|
|
297
|
+
to: [newProvenanceMolecule.key],
|
|
298
|
+
}
|
|
299
|
+
const isTransaction =
|
|
300
|
+
isChildStore(target) && target.transactionMeta.phase === `building`
|
|
301
|
+
if (isTransaction) {
|
|
302
|
+
target.transactionMeta.update.updates.push(transferEvent)
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
return claim
|
|
306
|
+
}
|
|
@@ -80,7 +80,7 @@ export function createMutableAtomFamily<
|
|
|
80
80
|
}) satisfies MutableAtomFamily<T, J, K>
|
|
81
81
|
|
|
82
82
|
store.families.set(options.key, atomFamily)
|
|
83
|
-
selectJsonFamily(atomFamily, options
|
|
83
|
+
selectJsonFamily(store, atomFamily, options)
|
|
84
84
|
new FamilyTracker(atomFamily, store)
|
|
85
85
|
return familyToken
|
|
86
86
|
}
|
|
@@ -61,8 +61,8 @@ export function createMutableAtom<
|
|
|
61
61
|
}
|
|
62
62
|
const initialValue = options.default()
|
|
63
63
|
target.atoms.set(newAtom.key, newAtom)
|
|
64
|
-
markAtomAsDefault(options.key
|
|
65
|
-
cacheValue(options.key, initialValue, subject
|
|
64
|
+
markAtomAsDefault(store, options.key)
|
|
65
|
+
cacheValue(target, options.key, initialValue, subject)
|
|
66
66
|
const token = deposit(newAtom)
|
|
67
67
|
if (options.effects) {
|
|
68
68
|
let effectIndex = 0
|
|
@@ -73,7 +73,7 @@ export function createMutableAtom<
|
|
|
73
73
|
setIntoStore(store, token, next)
|
|
74
74
|
},
|
|
75
75
|
onSet: (handle: UpdateHandler<T>) =>
|
|
76
|
-
subscribeToState(
|
|
76
|
+
subscribeToState(store, token, `effect[${effectIndex}]`, handle),
|
|
77
77
|
})
|
|
78
78
|
if (cleanup) {
|
|
79
79
|
cleanupFunctions.push(cleanup)
|
|
@@ -27,7 +27,7 @@ export const getJsonToken = <
|
|
|
27
27
|
key: jsonFamilyKey,
|
|
28
28
|
type: `selector_family`,
|
|
29
29
|
}
|
|
30
|
-
const family = withdraw(
|
|
30
|
+
const family = withdraw(target, jsonFamilyToken)
|
|
31
31
|
const subKey = JSON.parse(mutableAtomToken.family.subKey)
|
|
32
32
|
const jsonToken = findInStore(store, family, subKey)
|
|
33
33
|
return jsonToken
|
|
@@ -2,7 +2,7 @@ import type { Canonical } from "atom.io/json"
|
|
|
2
2
|
import { parseJson } from "atom.io/json"
|
|
3
3
|
|
|
4
4
|
import type { MutableAtomFamily, RegularAtomFamily } from ".."
|
|
5
|
-
import { createRegularAtomFamily
|
|
5
|
+
import { createRegularAtomFamily } from "../families"
|
|
6
6
|
import { type Store, withdraw } from "../store"
|
|
7
7
|
import { Tracker } from "./tracker"
|
|
8
8
|
import type { Transceiver } from "./transceiver"
|
|
@@ -11,6 +11,7 @@ export class FamilyTracker<
|
|
|
11
11
|
Core extends Transceiver<any>,
|
|
12
12
|
FamilyMemberKey extends Canonical,
|
|
13
13
|
> {
|
|
14
|
+
private trackers: Map<FamilyMemberKey, Tracker<Core>> = new Map()
|
|
14
15
|
private readonly Update: Core extends Transceiver<infer Signal>
|
|
15
16
|
? Signal
|
|
16
17
|
: never
|
|
@@ -36,26 +37,27 @@ export class FamilyTracker<
|
|
|
36
37
|
},
|
|
37
38
|
[`mutable`, `updates`],
|
|
38
39
|
)
|
|
39
|
-
this.latestUpdateAtoms = withdraw(
|
|
40
|
+
this.latestUpdateAtoms = withdraw(store, updateAtoms)
|
|
40
41
|
this.mutableAtoms = mutableAtoms
|
|
41
42
|
this.mutableAtoms.subject.subscribe(
|
|
42
43
|
`store=${store.config.name}::tracker-atom-family`,
|
|
43
44
|
(event) => {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
45
|
+
const { type, token } = event
|
|
46
|
+
if (token.family) {
|
|
47
|
+
const key = parseJson(token.family.subKey)
|
|
48
|
+
switch (type) {
|
|
49
|
+
case `state_creation`:
|
|
50
|
+
this.trackers.set(key, new Tracker<Core>(token, store))
|
|
51
|
+
break
|
|
52
|
+
case `state_disposal`:
|
|
53
|
+
{
|
|
54
|
+
const tracker = this.trackers.get(key)
|
|
55
|
+
if (tracker) {
|
|
56
|
+
tracker[Symbol.dispose]()
|
|
57
|
+
this.trackers.delete(key)
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
break
|
|
59
61
|
}
|
|
60
62
|
}
|
|
61
63
|
},
|
|
@@ -70,7 +70,9 @@ export class Tracker<Mutable extends Transceiver<any>> {
|
|
|
70
70
|
},
|
|
71
71
|
)
|
|
72
72
|
this.unsubscribeFromState = subscribeToState(
|
|
73
|
+
target,
|
|
73
74
|
mutableState,
|
|
75
|
+
subscriptionKey,
|
|
74
76
|
(update) => {
|
|
75
77
|
if (update.newValue !== update.oldValue) {
|
|
76
78
|
this.unsubscribeFromInnerValue()
|
|
@@ -82,8 +84,6 @@ export class Tracker<Mutable extends Transceiver<any>> {
|
|
|
82
84
|
)
|
|
83
85
|
}
|
|
84
86
|
},
|
|
85
|
-
subscriptionKey,
|
|
86
|
-
target,
|
|
87
87
|
)
|
|
88
88
|
}
|
|
89
89
|
|
|
@@ -96,7 +96,9 @@ export class Tracker<Mutable extends Transceiver<any>> {
|
|
|
96
96
|
isChildStore(target) ? target.transactionMeta.update.key : `main`
|
|
97
97
|
}:${mutableState.key}`
|
|
98
98
|
subscribeToState(
|
|
99
|
+
target,
|
|
99
100
|
latestUpdateState,
|
|
101
|
+
subscriptionKey,
|
|
100
102
|
({ newValue, oldValue }) => {
|
|
101
103
|
const timelineId = target.timelineTopics.getRelatedKey(
|
|
102
104
|
latestUpdateState.key,
|
|
@@ -106,7 +108,9 @@ export class Tracker<Mutable extends Transceiver<any>> {
|
|
|
106
108
|
const timelineData = target.timelines.get(timelineId)
|
|
107
109
|
if (timelineData?.timeTraveling) {
|
|
108
110
|
const unsubscribe = subscribeToTimeline(
|
|
111
|
+
target,
|
|
109
112
|
{ key: timelineId, type: `timeline` },
|
|
113
|
+
subscriptionKey,
|
|
110
114
|
(update) => {
|
|
111
115
|
unsubscribe()
|
|
112
116
|
setIntoStore(target, mutableState, (transceiver) => {
|
|
@@ -118,8 +122,6 @@ export class Tracker<Mutable extends Transceiver<any>> {
|
|
|
118
122
|
return transceiver
|
|
119
123
|
})
|
|
120
124
|
},
|
|
121
|
-
subscriptionKey,
|
|
122
|
-
target,
|
|
123
125
|
)
|
|
124
126
|
return
|
|
125
127
|
}
|
|
@@ -152,15 +154,13 @@ export class Tracker<Mutable extends Transceiver<any>> {
|
|
|
152
154
|
},
|
|
153
155
|
)
|
|
154
156
|
},
|
|
155
|
-
subscriptionKey,
|
|
156
|
-
target,
|
|
157
157
|
)
|
|
158
158
|
}
|
|
159
159
|
|
|
160
160
|
public mutableState: MutableAtomToken<Mutable, Json.Serializable>
|
|
161
161
|
public latestUpdateState: RegularAtomToken<typeof this.Update | null>
|
|
162
162
|
|
|
163
|
-
public dispose: () => void
|
|
163
|
+
public [Symbol.dispose]: () => void
|
|
164
164
|
|
|
165
165
|
public constructor(
|
|
166
166
|
mutableState: MutableAtomToken<Mutable, Json.Serializable>,
|
|
@@ -172,7 +172,7 @@ export class Tracker<Mutable extends Transceiver<any>> {
|
|
|
172
172
|
this.observeCore(mutableState, this.latestUpdateState, target)
|
|
173
173
|
this.updateCore(mutableState, this.latestUpdateState, target)
|
|
174
174
|
target.trackers.set(mutableState.key, this)
|
|
175
|
-
this.dispose = () => {
|
|
175
|
+
this[Symbol.dispose] = () => {
|
|
176
176
|
this.unsubscribeFromInnerValue()
|
|
177
177
|
this.unsubscribeFromState()
|
|
178
178
|
target.trackers.delete(mutableState.key)
|
|
@@ -1,37 +1,15 @@
|
|
|
1
|
-
import
|
|
1
|
+
import type { AtomIOToken } from "atom.io"
|
|
2
|
+
import { stringifyJson } from "atom.io/json"
|
|
2
3
|
|
|
3
|
-
import type { AtomIOToken } from "./pretty-print"
|
|
4
4
|
import { prettyPrintTokenType } from "./pretty-print"
|
|
5
5
|
import type { Store } from "./store"
|
|
6
6
|
|
|
7
7
|
export class NotFoundError extends Error {
|
|
8
|
-
public constructor(token: AtomIOToken, store: Store)
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
public constructor(
|
|
15
|
-
...params:
|
|
16
|
-
| [token: AtomIOToken, key: Json.Serializable, store: Store]
|
|
17
|
-
| [token: AtomIOToken, store: Store]
|
|
18
|
-
) {
|
|
19
|
-
const token: AtomIOToken = params[0]
|
|
20
|
-
const store: Store = params.length === 2 ? params[1] : params[2]
|
|
21
|
-
|
|
22
|
-
if (params.length === 2) {
|
|
23
|
-
super(
|
|
24
|
-
`${prettyPrintTokenType(token)} ${stringifyJson(token.key)} not found in store "${
|
|
25
|
-
store.config.name
|
|
26
|
-
}".`,
|
|
27
|
-
)
|
|
28
|
-
} else {
|
|
29
|
-
const key = params[1]
|
|
30
|
-
super(
|
|
31
|
-
`${prettyPrintTokenType(token)} "${token.key}" member ${stringifyJson(key)} not found in store "${
|
|
32
|
-
store.config.name
|
|
33
|
-
}".`,
|
|
34
|
-
)
|
|
35
|
-
}
|
|
8
|
+
public constructor(token: AtomIOToken, store: Store) {
|
|
9
|
+
super(
|
|
10
|
+
`${prettyPrintTokenType(token)} ${stringifyJson(token.key)} not found in store "${
|
|
11
|
+
store.config.name
|
|
12
|
+
}".`,
|
|
13
|
+
)
|
|
36
14
|
}
|
|
37
15
|
}
|
|
@@ -1,17 +1,6 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
ReadableFamilyToken,
|
|
3
|
-
ReadableToken,
|
|
4
|
-
TimelineToken,
|
|
5
|
-
TransactionToken,
|
|
6
|
-
} from "atom.io"
|
|
1
|
+
import type { AtomIOToken } from "atom.io"
|
|
7
2
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
export type AtomIOToken =
|
|
11
|
-
| ReadableFamilyToken<any, any>
|
|
12
|
-
| ReadableToken<any>
|
|
13
|
-
| TimelineToken<any>
|
|
14
|
-
| TransactionToken<any>
|
|
3
|
+
import { capitalize } from "./capitalize"
|
|
15
4
|
|
|
16
5
|
export function prettyPrintTokenType(token: AtomIOToken): string {
|
|
17
6
|
return token.type.split(`_`).map(capitalize).join(` `)
|
|
@@ -19,14 +19,10 @@ export const createReadonlySelector = <T>(
|
|
|
19
19
|
const target = newest(store)
|
|
20
20
|
const subject = new Subject<{ newValue: T; oldValue: T }>()
|
|
21
21
|
const covered = new Set<string>()
|
|
22
|
-
const { get, find,
|
|
23
|
-
options.key,
|
|
24
|
-
covered,
|
|
25
|
-
target,
|
|
26
|
-
)
|
|
22
|
+
const { get, find, json } = registerSelector(options.key, covered, target)
|
|
27
23
|
const getSelf = () => {
|
|
28
|
-
const value = options.get({ get, find,
|
|
29
|
-
cacheValue(options.key, value, subject
|
|
24
|
+
const value = options.get({ get, find, json })
|
|
25
|
+
cacheValue(newest(store), options.key, value, subject)
|
|
30
26
|
covered.clear()
|
|
31
27
|
return value
|
|
32
28
|
}
|
|
@@ -23,12 +23,12 @@ export const createWritableSelector = <T>(
|
|
|
23
23
|
const subject = new Subject<{ newValue: T; oldValue: T }>()
|
|
24
24
|
const covered = new Set<string>()
|
|
25
25
|
const setterToolkit = registerSelector(options.key, covered, target)
|
|
26
|
-
const { find, get,
|
|
27
|
-
const getterToolkit = { find, get,
|
|
26
|
+
const { find, get, json } = setterToolkit
|
|
27
|
+
const getterToolkit = { find, get, json }
|
|
28
28
|
|
|
29
29
|
const getSelf = (getFn = options.get, innerTarget = newest(store)): T => {
|
|
30
30
|
const value = getFn(getterToolkit)
|
|
31
|
-
cacheValue(options.key, value, subject
|
|
31
|
+
cacheValue(innerTarget, options.key, value, subject)
|
|
32
32
|
covered.clear()
|
|
33
33
|
return value
|
|
34
34
|
}
|
|
@@ -47,7 +47,7 @@ export const createWritableSelector = <T>(
|
|
|
47
47
|
newValue,
|
|
48
48
|
`)`,
|
|
49
49
|
)
|
|
50
|
-
cacheValue(options.key, newValue, subject
|
|
50
|
+
cacheValue(innerTarget, options.key, newValue, subject)
|
|
51
51
|
markDone(innerTarget, options.key)
|
|
52
52
|
if (isRootStore(innerTarget)) {
|
|
53
53
|
subject.next({ newValue, oldValue })
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { SelectorFamilyToken, SelectorToken } from "atom.io"
|
|
2
2
|
|
|
3
3
|
import type { Store } from ".."
|
|
4
4
|
import { isChildStore, newest, withdraw } from ".."
|
|
5
5
|
|
|
6
6
|
export function disposeSelector(
|
|
7
|
-
selectorToken: ReadonlySelectorToken<unknown> | WritableSelectorToken<unknown>,
|
|
8
7
|
store: Store,
|
|
8
|
+
selectorToken: SelectorToken<unknown>,
|
|
9
9
|
): void {
|
|
10
10
|
const target = newest(store)
|
|
11
11
|
const { key } = selectorToken
|
|
12
|
-
const selector = withdraw(
|
|
12
|
+
const selector = withdraw(target, selectorToken)
|
|
13
13
|
if (!selector.family) {
|
|
14
14
|
store.logger.error(
|
|
15
15
|
`❌`,
|
|
@@ -22,23 +22,31 @@ export function disposeSelector(
|
|
|
22
22
|
if (molecule) {
|
|
23
23
|
target.moleculeData.delete(selector.family.subKey, selector.family.key)
|
|
24
24
|
}
|
|
25
|
+
let familyToken: SelectorFamilyToken<any, any>
|
|
25
26
|
switch (selectorToken.type) {
|
|
26
27
|
case `selector`:
|
|
27
28
|
{
|
|
28
29
|
target.selectors.delete(key)
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
30
|
+
familyToken = {
|
|
31
|
+
key: selector.family.key,
|
|
32
|
+
type: `selector_family`,
|
|
33
|
+
}
|
|
34
|
+
const family = withdraw(store, familyToken)
|
|
35
|
+
family.subject.next({
|
|
36
|
+
type: `state_disposal`,
|
|
37
|
+
subType: `selector`,
|
|
38
|
+
token: selectorToken,
|
|
39
|
+
})
|
|
33
40
|
}
|
|
34
41
|
break
|
|
35
42
|
case `readonly_selector`:
|
|
36
43
|
{
|
|
37
44
|
target.readonlySelectors.delete(key)
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
45
|
+
familyToken = {
|
|
46
|
+
key: selector.family.key,
|
|
47
|
+
type: `readonly_selector_family`,
|
|
48
|
+
}
|
|
49
|
+
const family = withdraw(store, familyToken)
|
|
42
50
|
family.subject.next({
|
|
43
51
|
type: `state_disposal`,
|
|
44
52
|
subType: `selector`,
|
|
@@ -47,6 +55,7 @@ export function disposeSelector(
|
|
|
47
55
|
}
|
|
48
56
|
break
|
|
49
57
|
}
|
|
58
|
+
|
|
50
59
|
target.valueMap.delete(key)
|
|
51
60
|
target.selectorAtoms.delete(key)
|
|
52
61
|
target.selectorGraph.delete(key)
|
|
@@ -15,6 +15,6 @@ export const getSelectorDependencyKeys = (
|
|
|
15
15
|
.selectorGraph.getRelationEntries({ downstreamSelectorKey: key })
|
|
16
16
|
.filter(([_, { source }]) => source !== key)
|
|
17
17
|
.map(([_, { source }]) => source)
|
|
18
|
-
.filter((source) => isStateKey(
|
|
18
|
+
.filter((source) => isStateKey(store, source))
|
|
19
19
|
return sources
|
|
20
20
|
}
|