atom.io 0.40.0 → 0.40.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/dist/internal/index.d.ts +67 -62
- package/dist/internal/index.d.ts.map +1 -1
- package/dist/internal/index.js +81 -93
- package/dist/internal/index.js.map +1 -1
- package/dist/introspection/index.d.ts +2 -2
- package/dist/introspection/index.d.ts.map +1 -1
- package/dist/introspection/index.js.map +1 -1
- package/dist/main/index.d.ts +14 -11
- package/dist/main/index.d.ts.map +1 -1
- package/dist/main/index.js +16 -13
- package/dist/main/index.js.map +1 -1
- package/dist/react/index.d.ts +3 -3
- package/dist/react/index.d.ts.map +1 -1
- package/dist/react/index.js.map +1 -1
- package/dist/react-devtools/index.js +1 -1
- package/dist/react-devtools/index.js.map +1 -1
- package/dist/realtime-client/index.d.ts +3 -3
- package/dist/realtime-client/index.d.ts.map +1 -1
- package/dist/realtime-client/index.js +3 -4
- package/dist/realtime-client/index.js.map +1 -1
- package/dist/realtime-server/index.d.ts +2 -2
- package/dist/realtime-server/index.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/internal/atom/create-regular-atom.ts +3 -2
- package/src/internal/atom/dispose-atom.ts +6 -6
- package/src/internal/families/create-readonly-held-selector-family.ts +3 -4
- package/src/internal/families/create-readonly-pure-selector-family.ts +4 -9
- package/src/internal/families/create-regular-atom-family.ts +3 -4
- package/src/internal/families/create-selector-family.ts +6 -6
- package/src/internal/families/create-writable-held-selector-family.ts +2 -2
- package/src/internal/families/create-writable-pure-selector-family.ts +3 -7
- package/src/internal/families/dispose-from-store.ts +9 -2
- package/src/internal/get-state/get-from-store.ts +10 -3
- package/src/internal/index.ts +8 -8
- package/src/internal/install-into-store.ts +2 -1
- package/src/internal/join/create-join.ts +2 -2
- package/src/internal/join/find-relations-in-store.ts +2 -2
- package/src/internal/join/get-internal-relations-from-store.ts +2 -2
- package/src/internal/join/get-join.ts +5 -2
- package/src/internal/join/join-internal.ts +15 -20
- package/src/internal/lineage.ts +12 -1
- package/src/internal/molecule.ts +64 -36
- package/src/internal/mutable/create-mutable-atom-family.ts +4 -4
- package/src/internal/mutable/create-mutable-atom.ts +2 -2
- package/src/internal/mutable/tracker-family.ts +3 -3
- package/src/internal/selector/create-readonly-held-selector.ts +2 -2
- package/src/internal/selector/create-readonly-pure-selector.ts +2 -2
- package/src/internal/selector/create-writable-held-selector.ts +2 -2
- package/src/internal/selector/create-writable-pure-selector.ts +2 -2
- package/src/internal/set-state/become.ts +1 -3
- package/src/internal/set-state/dispatch-state-update.ts +1 -1
- package/src/internal/set-state/reset-in-store.ts +11 -13
- package/src/internal/set-state/set-into-store.ts +27 -3
- package/src/internal/store/store.ts +14 -12
- package/src/internal/timeline/create-timeline.ts +6 -5
- package/src/internal/timeline/time-travel.ts +4 -3
- package/src/internal/transaction/abort-transaction.ts +3 -15
- package/src/internal/transaction/act-upon-store.ts +1 -5
- package/src/internal/transaction/apply-transaction.ts +3 -15
- package/src/internal/transaction/assign-transaction-to-continuity.ts +2 -7
- package/src/internal/transaction/build-transaction.ts +2 -3
- package/src/internal/transaction/create-transaction.ts +5 -6
- package/src/internal/transaction/get-epoch-number.ts +1 -7
- package/src/internal/transaction/set-epoch-number.ts +4 -12
- package/src/introspection/attach-introspection-states.ts +4 -2
- package/src/introspection/attach-timeline-family.ts +2 -2
- package/src/introspection/attach-transaction-logs.ts +2 -2
- package/src/introspection/attach-type-selectors.ts +2 -2
- package/src/main/dispose-state.ts +1 -5
- package/src/main/events.ts +1 -3
- package/src/main/get-state.ts +3 -6
- package/src/main/realm.ts +36 -12
- package/src/main/reset-state.ts +1 -5
- package/src/main/set-state.ts +4 -11
- package/src/main/silo.ts +4 -3
- package/src/react/store-context.tsx +3 -3
- package/src/react-devtools/Button.tsx +3 -2
- package/src/react-devtools/TimelineIndex.tsx +0 -2
- package/src/react-devtools/store.ts +2 -2
- package/src/realtime-client/continuity/register-and-attempt-confirmed-update.ts +4 -8
- package/src/realtime-client/sync-continuity.ts +2 -2
- package/src/realtime-server/index.ts +2 -2
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import type { JoinToken } from "atom.io"
|
|
2
2
|
import type { Json } from "atom.io/json"
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import { eldest } from "../lineage"
|
|
5
|
+
import type { Store } from "../store"
|
|
6
|
+
import { IMPLICIT } from "../store"
|
|
5
7
|
import { Join } from "./join-internal"
|
|
6
8
|
|
|
7
9
|
export function getJoin<
|
|
@@ -24,7 +26,8 @@ export function getJoin<
|
|
|
24
26
|
`Join "${token.key}" not found in store "${store.config.name}"`,
|
|
25
27
|
)
|
|
26
28
|
}
|
|
27
|
-
|
|
29
|
+
const root = eldest(store)
|
|
30
|
+
myJoin = new Join(rootJoin.options, rootJoin.defaultContent, root)
|
|
28
31
|
store.joins.set(token.key, myJoin)
|
|
29
32
|
}
|
|
30
33
|
return myJoin
|
|
@@ -13,7 +13,7 @@ import type {
|
|
|
13
13
|
WriterToolkit,
|
|
14
14
|
} from "atom.io"
|
|
15
15
|
import { Anarchy } from "atom.io"
|
|
16
|
-
import type {
|
|
16
|
+
import type { Json } from "atom.io/json"
|
|
17
17
|
import { stringifyJson } from "atom.io/json"
|
|
18
18
|
import { SetRTX } from "atom.io/transceivers/set-rtx"
|
|
19
19
|
|
|
@@ -29,11 +29,11 @@ import type {
|
|
|
29
29
|
ExternalStoreConfiguration,
|
|
30
30
|
} from "../junction"
|
|
31
31
|
import { Junction } from "../junction"
|
|
32
|
-
import type { Molecule } from "../molecule"
|
|
33
32
|
import { createMutableAtomFamily, getJsonFamily, getJsonToken } from "../mutable"
|
|
34
33
|
import { setIntoStore } from "../set-state"
|
|
35
34
|
import type { Store } from "../store"
|
|
36
35
|
import { IMPLICIT } from "../store"
|
|
36
|
+
import type { RootStore } from "../transaction"
|
|
37
37
|
|
|
38
38
|
export type JoinStateFamilies<
|
|
39
39
|
ASide extends string,
|
|
@@ -132,7 +132,6 @@ export class Join<
|
|
|
132
132
|
private toolkit: WriterToolkit
|
|
133
133
|
public options: JoinOptions<ASide, AType, BSide, BType, Cardinality, Content>
|
|
134
134
|
public defaultContent: Content | undefined
|
|
135
|
-
public molecules: Map<string, Molecule<any>> = new Map()
|
|
136
135
|
public relations: Junction<ASide, AType, BSide, BType, Content>
|
|
137
136
|
public states: JoinStateFamilies<
|
|
138
137
|
ASide,
|
|
@@ -163,7 +162,7 @@ export class Join<
|
|
|
163
162
|
public constructor(
|
|
164
163
|
options: JoinOptions<ASide, AType, BSide, BType, Cardinality, Content>,
|
|
165
164
|
defaultContent: Content | undefined,
|
|
166
|
-
store:
|
|
165
|
+
store: RootStore = IMPLICIT.STORE,
|
|
167
166
|
) {
|
|
168
167
|
type AnyKey = AType & BType
|
|
169
168
|
|
|
@@ -225,6 +224,9 @@ export class Join<
|
|
|
225
224
|
bKeys.delete(a)
|
|
226
225
|
return bKeys
|
|
227
226
|
})
|
|
227
|
+
const [x, y] = [a, b].sort()
|
|
228
|
+
const compositeKey = `${x}:${y}`
|
|
229
|
+
this.store.moleculeJoins.delete(compositeKey)
|
|
228
230
|
}
|
|
229
231
|
const replaceRelationsSafely: Write<
|
|
230
232
|
(a: string, newRelationsOfA: string[]) => void
|
|
@@ -267,9 +269,9 @@ export class Join<
|
|
|
267
269
|
relationsOfB.clear()
|
|
268
270
|
}
|
|
269
271
|
for (const previousOwner of previousOwnersToDispose) {
|
|
270
|
-
const
|
|
271
|
-
const compositeKey =
|
|
272
|
-
|
|
272
|
+
const [x, y] = [newRelationB, previousOwner].sort()
|
|
273
|
+
const compositeKey = `${x}:${y}`
|
|
274
|
+
store.moleculeJoins.delete(compositeKey)
|
|
273
275
|
}
|
|
274
276
|
}
|
|
275
277
|
if (!newRelationBIsAlreadyRelated) {
|
|
@@ -310,14 +312,8 @@ export class Join<
|
|
|
310
312
|
const baseExternalStoreConfiguration: BaseExternalStoreConfiguration = {
|
|
311
313
|
getRelatedKeys: (key) => getRelatedKeys(this.toolkit, key),
|
|
312
314
|
addRelation: (a, b) => {
|
|
313
|
-
this.store.moleculeJoins.set(
|
|
314
|
-
|
|
315
|
-
options.key,
|
|
316
|
-
)
|
|
317
|
-
this.store.moleculeJoins.set(
|
|
318
|
-
b as stringified<Canonical> /* 💥 RECONCILE */,
|
|
319
|
-
options.key,
|
|
320
|
-
)
|
|
315
|
+
this.store.moleculeJoins.set(`"${a}"`, options.key)
|
|
316
|
+
this.store.moleculeJoins.set(`"${b}"`, options.key)
|
|
321
317
|
addRelation(this.toolkit, a, b)
|
|
322
318
|
},
|
|
323
319
|
deleteRelation: (a, b) => {
|
|
@@ -364,9 +360,7 @@ export class Join<
|
|
|
364
360
|
setContent: (contentKey: ContentKey, content: Content) => {
|
|
365
361
|
setContent(this.toolkit, contentKey, content)
|
|
366
362
|
},
|
|
367
|
-
deleteContent: (
|
|
368
|
-
this.realm.deallocate(contentKey)
|
|
369
|
-
},
|
|
363
|
+
deleteContent: (_: ContentKey) => {},
|
|
370
364
|
}
|
|
371
365
|
externalStore = Object.assign(
|
|
372
366
|
baseExternalStoreConfiguration,
|
|
@@ -384,8 +378,8 @@ export class Join<
|
|
|
384
378
|
isBType: options.isBType,
|
|
385
379
|
makeContentKey: (...args) => {
|
|
386
380
|
const [a, b] = args
|
|
387
|
-
const
|
|
388
|
-
const compositeKey = `${
|
|
381
|
+
const [x, y] = args.sort()
|
|
382
|
+
const compositeKey = `${x}:${y}`
|
|
389
383
|
const aMolecule = store.molecules.get(stringifyJson(a))
|
|
390
384
|
const bMolecule = store.molecules.get(stringifyJson(b))
|
|
391
385
|
if (!aMolecule) {
|
|
@@ -394,6 +388,7 @@ export class Join<
|
|
|
394
388
|
if (!bMolecule) {
|
|
395
389
|
this.realm.allocate(options.key, b)
|
|
396
390
|
}
|
|
391
|
+
|
|
397
392
|
this.realm.allocate(a, compositeKey, `all`)
|
|
398
393
|
this.realm.claim(b, compositeKey)
|
|
399
394
|
this.store.moleculeJoins.set(compositeKey, options.key)
|
package/src/internal/lineage.ts
CHANGED
|
@@ -4,9 +4,20 @@ export interface Lineage {
|
|
|
4
4
|
child: typeof this | null
|
|
5
5
|
}
|
|
6
6
|
|
|
7
|
-
export function newest<T extends Lineage>(
|
|
7
|
+
export function newest<T extends Lineage>(
|
|
8
|
+
scion: T,
|
|
9
|
+
): Exclude<T[`child`], null> | T {
|
|
8
10
|
while (scion.child !== null) {
|
|
9
11
|
scion = scion.child
|
|
10
12
|
}
|
|
11
13
|
return scion
|
|
12
14
|
}
|
|
15
|
+
|
|
16
|
+
export function eldest<T extends Lineage>(
|
|
17
|
+
scion: T,
|
|
18
|
+
): Exclude<T[`parent`], T[`child`] | null> {
|
|
19
|
+
while (scion.parent !== null) {
|
|
20
|
+
scion = scion.parent
|
|
21
|
+
}
|
|
22
|
+
return scion as Exclude<T[`parent`], T[`child`] | null>
|
|
23
|
+
}
|
package/src/internal/molecule.ts
CHANGED
|
@@ -8,18 +8,20 @@ import type {
|
|
|
8
8
|
MoleculeDisposalEvent,
|
|
9
9
|
MoleculeTransferEvent,
|
|
10
10
|
SingularTypedKey,
|
|
11
|
+
TransactionToken,
|
|
11
12
|
Vassal,
|
|
12
13
|
} from "atom.io"
|
|
13
14
|
import type { Canonical, stringified } from "atom.io/json"
|
|
14
15
|
import { parseJson, stringifyJson } from "atom.io/json"
|
|
15
16
|
|
|
16
|
-
import { disposeFromStore
|
|
17
|
+
import { disposeFromStore } from "./families"
|
|
17
18
|
import { getFromStore } from "./get-state"
|
|
18
19
|
import { getTrace } from "./get-trace"
|
|
19
20
|
import { newest } from "./lineage"
|
|
20
21
|
import type { Store } from "./store"
|
|
21
22
|
import { IMPLICIT } from "./store"
|
|
22
|
-
import {
|
|
23
|
+
import type { RootStore } from "./transaction"
|
|
24
|
+
import { createTransaction, isChildStore } from "./transaction"
|
|
23
25
|
|
|
24
26
|
export type Molecule<K extends Canonical> = {
|
|
25
27
|
readonly key: K
|
|
@@ -135,23 +137,35 @@ export function fuseWithinStore<
|
|
|
135
137
|
return compoundKey
|
|
136
138
|
}
|
|
137
139
|
|
|
140
|
+
export function createDeallocateTX<
|
|
141
|
+
H extends Hierarchy,
|
|
142
|
+
V extends Exclude<Vassal<H>, CompoundTypedKey>,
|
|
143
|
+
>(store: RootStore): TransactionToken<(claim: Claim<V>) => void> {
|
|
144
|
+
return createTransaction(store, {
|
|
145
|
+
key: `[Internal] deallocate`,
|
|
146
|
+
do: (_, claim: Claim<V>): void => {
|
|
147
|
+
deallocateFromStore<H, V>(newest(store), claim)
|
|
148
|
+
},
|
|
149
|
+
})
|
|
150
|
+
}
|
|
151
|
+
|
|
138
152
|
export function deallocateFromStore<H extends Hierarchy, V extends Vassal<H>>(
|
|
139
|
-
|
|
153
|
+
target: Store,
|
|
140
154
|
claim: Claim<V>,
|
|
141
155
|
): void {
|
|
142
156
|
const stringKey = stringifyJson(claim)
|
|
143
157
|
|
|
144
|
-
const molecule =
|
|
158
|
+
const molecule = target.molecules.get(stringKey)
|
|
145
159
|
if (!molecule) {
|
|
146
|
-
const disposal =
|
|
160
|
+
const disposal = target.disposalTraces.buffer.find(
|
|
147
161
|
(item) => item?.key === stringKey,
|
|
148
162
|
)
|
|
149
|
-
|
|
163
|
+
target.logger.error(
|
|
150
164
|
`❌`,
|
|
151
165
|
`key`,
|
|
152
166
|
claim,
|
|
153
167
|
`deallocation failed:`,
|
|
154
|
-
`Could not find allocation for ${stringKey} in store "${
|
|
168
|
+
`Could not find allocation for ${stringKey} in store "${target.config.name}".`,
|
|
155
169
|
disposal
|
|
156
170
|
? `\n This state was most recently deallocated\n${disposal.trace}`
|
|
157
171
|
: `No previous disposal trace for ${stringKey} was found.`,
|
|
@@ -159,45 +173,29 @@ export function deallocateFromStore<H extends Hierarchy, V extends Vassal<H>>(
|
|
|
159
173
|
return
|
|
160
174
|
}
|
|
161
175
|
|
|
162
|
-
const joinKeys =
|
|
163
|
-
molecule.key as string /* 💥 RECONCILE */,
|
|
164
|
-
)
|
|
176
|
+
const joinKeys = target.moleculeJoins.getRelatedKeys(stringKey)
|
|
165
177
|
if (joinKeys) {
|
|
166
178
|
for (const joinKey of joinKeys) {
|
|
167
|
-
const join =
|
|
179
|
+
const join = target.joins.get(joinKey)
|
|
168
180
|
if (join) {
|
|
169
|
-
join.relations.delete(
|
|
170
|
-
join.molecules.delete(molecule.stringKey) // get rid of
|
|
181
|
+
join.relations.delete(claim)
|
|
171
182
|
}
|
|
172
183
|
}
|
|
173
184
|
}
|
|
174
|
-
|
|
185
|
+
target.moleculeJoins.delete(stringKey)
|
|
175
186
|
|
|
176
187
|
const provenance: stringified<Canonical>[] = []
|
|
177
188
|
|
|
178
189
|
const values: [string, any][] = []
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
values,
|
|
183
|
-
provenance,
|
|
184
|
-
timestamp: Date.now(),
|
|
185
|
-
}
|
|
186
|
-
const target = newest(store)
|
|
187
|
-
target.molecules.delete(stringKey)
|
|
188
|
-
const isTransaction =
|
|
189
|
-
isChildStore(target) && target.transactionMeta.phase === `building`
|
|
190
|
-
if (isTransaction) {
|
|
191
|
-
target.transactionMeta.update.subEvents.push(disposalEvent)
|
|
192
|
-
}
|
|
193
|
-
const relatedMolecules = store.moleculeGraph.getRelationEntries({
|
|
194
|
-
downstreamMoleculeKey: molecule.stringKey,
|
|
190
|
+
|
|
191
|
+
const relatedMolecules = target.moleculeGraph.getRelationEntries({
|
|
192
|
+
downstreamMoleculeKey: stringKey,
|
|
195
193
|
})
|
|
196
194
|
if (relatedMolecules) {
|
|
197
195
|
for (const [relatedStringKey, { source }] of relatedMolecules) {
|
|
198
|
-
if (source ===
|
|
196
|
+
if (source === stringKey) {
|
|
199
197
|
const relatedKey = parseJson(relatedStringKey)
|
|
200
|
-
deallocateFromStore<any, any>(
|
|
198
|
+
deallocateFromStore<any, any>(target, relatedKey)
|
|
201
199
|
} else {
|
|
202
200
|
provenance.push(source)
|
|
203
201
|
}
|
|
@@ -208,12 +206,24 @@ export function deallocateFromStore<H extends Hierarchy, V extends Vassal<H>>(
|
|
|
208
206
|
for (const familyKey of familyKeys) {
|
|
209
207
|
// biome-ignore lint/style/noNonNullAssertion: tokens of molecules must have a family
|
|
210
208
|
const family = target.families.get(familyKey)!
|
|
211
|
-
const
|
|
212
|
-
const value = getFromStore(store, token)
|
|
209
|
+
const value = getFromStore(target, family, claim)
|
|
213
210
|
values.push([family.key, value])
|
|
214
|
-
disposeFromStore(
|
|
211
|
+
disposeFromStore(target, family, claim)
|
|
215
212
|
}
|
|
216
213
|
}
|
|
214
|
+
const disposalEvent: MoleculeDisposalEvent = {
|
|
215
|
+
type: `molecule_disposal`,
|
|
216
|
+
key: molecule.key,
|
|
217
|
+
values,
|
|
218
|
+
provenance,
|
|
219
|
+
timestamp: Date.now(),
|
|
220
|
+
}
|
|
221
|
+
target.molecules.delete(stringKey)
|
|
222
|
+
const isTransaction =
|
|
223
|
+
isChildStore(target) && target.transactionMeta.phase === `building`
|
|
224
|
+
if (isTransaction) {
|
|
225
|
+
target.transactionMeta.update.subEvents.push(disposalEvent)
|
|
226
|
+
}
|
|
217
227
|
|
|
218
228
|
target.moleculeGraph.delete(molecule.stringKey)
|
|
219
229
|
target.moleculeJoins.delete(molecule.stringKey)
|
|
@@ -225,8 +235,26 @@ export function deallocateFromStore<H extends Hierarchy, V extends Vassal<H>>(
|
|
|
225
235
|
target.molecules.delete(molecule.stringKey)
|
|
226
236
|
|
|
227
237
|
const trace = getTrace(new Error())
|
|
228
|
-
|
|
238
|
+
target.disposalTraces.add({ key: stringKey, trace })
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
export function createClaimTX<
|
|
242
|
+
H extends Hierarchy,
|
|
243
|
+
V extends Exclude<Vassal<H>, CompoundTypedKey>,
|
|
244
|
+
A extends Above<V, H>,
|
|
245
|
+
>(
|
|
246
|
+
store: RootStore,
|
|
247
|
+
): TransactionToken<
|
|
248
|
+
(newProvenance: A, claim: Claim<V>, exclusive?: `exclusive`) => void
|
|
249
|
+
> {
|
|
250
|
+
return createTransaction(store, {
|
|
251
|
+
key: `[Internal] claim`,
|
|
252
|
+
do: (_, newProvenance, claim, exclusive) => {
|
|
253
|
+
claimWithinStore<H, V, A>(store, newProvenance, claim, exclusive)
|
|
254
|
+
},
|
|
255
|
+
})
|
|
229
256
|
}
|
|
257
|
+
|
|
230
258
|
export function claimWithinStore<
|
|
231
259
|
H extends Hierarchy,
|
|
232
260
|
V extends Exclude<Vassal<H>, CompoundTypedKey>,
|
|
@@ -10,10 +10,10 @@ import { PRETTY_TOKEN_TYPES } from "atom.io"
|
|
|
10
10
|
import type { Canonical } from "atom.io/json"
|
|
11
11
|
import { stringifyJson } from "atom.io/json"
|
|
12
12
|
|
|
13
|
-
import {
|
|
13
|
+
import type { MutableAtomFamily, RootStore } from ".."
|
|
14
|
+
import { createWritablePureSelectorFamily } from ".."
|
|
14
15
|
import { newest } from "../lineage"
|
|
15
16
|
import { createMutableAtom } from "../mutable"
|
|
16
|
-
import type { Store } from "../store"
|
|
17
17
|
import { Subject } from "../subject"
|
|
18
18
|
import { FamilyTracker } from "./tracker-family"
|
|
19
19
|
import type { AsJSON, Transceiver } from "./transceiver"
|
|
@@ -22,7 +22,7 @@ export function createMutableAtomFamily<
|
|
|
22
22
|
T extends Transceiver<any, any, any>,
|
|
23
23
|
K extends Canonical,
|
|
24
24
|
>(
|
|
25
|
-
store:
|
|
25
|
+
store: RootStore,
|
|
26
26
|
options: MutableAtomFamilyOptions<T, K>,
|
|
27
27
|
internalRoles?: string[],
|
|
28
28
|
): MutableAtomFamilyToken<T, K> {
|
|
@@ -67,7 +67,7 @@ export function createMutableAtomFamily<
|
|
|
67
67
|
const atomFamily = Object.assign(familyFunction, familyToken, {
|
|
68
68
|
class: options.class,
|
|
69
69
|
subject,
|
|
70
|
-
install: (s:
|
|
70
|
+
install: (s: RootStore) => createMutableAtomFamily(s, options),
|
|
71
71
|
internalRoles,
|
|
72
72
|
}) satisfies MutableAtomFamily<T, K>
|
|
73
73
|
|
|
@@ -5,7 +5,7 @@ import type {
|
|
|
5
5
|
UpdateHandler,
|
|
6
6
|
} from "atom.io"
|
|
7
7
|
|
|
8
|
-
import type { MutableAtom } from ".."
|
|
8
|
+
import type { MutableAtom, RootStore } from ".."
|
|
9
9
|
import { createStandaloneSelector, resetInStore, setIntoStore } from ".."
|
|
10
10
|
import { newest } from "../lineage"
|
|
11
11
|
import { deposit, type Store } from "../store"
|
|
@@ -45,7 +45,7 @@ export function createMutableAtom<T extends Transceiver<any, any, any>>(
|
|
|
45
45
|
const newAtom: MutableAtom<T> = {
|
|
46
46
|
...options,
|
|
47
47
|
type,
|
|
48
|
-
install: (s:
|
|
48
|
+
install: (s: RootStore) => {
|
|
49
49
|
s.logger.info(`🛠️`, `atom`, key, `installing in store "${s.config.name}"`)
|
|
50
50
|
return createMutableAtom(s, options, family)
|
|
51
51
|
},
|
|
@@ -2,9 +2,9 @@ import type { MutableAtomToken, StateLifecycleEvent } from "atom.io"
|
|
|
2
2
|
import type { Canonical } from "atom.io/json"
|
|
3
3
|
import { parseJson } from "atom.io/json"
|
|
4
4
|
|
|
5
|
-
import type { MutableAtomFamily, RegularAtomFamily } from ".."
|
|
5
|
+
import type { MutableAtomFamily, RegularAtomFamily, RootStore } from ".."
|
|
6
6
|
import { createRegularAtomFamily } from "../families"
|
|
7
|
-
import {
|
|
7
|
+
import { withdraw } from "../store"
|
|
8
8
|
import { Tracker } from "./tracker"
|
|
9
9
|
import type { SignalFrom, Transceiver } from "./transceiver"
|
|
10
10
|
|
|
@@ -17,7 +17,7 @@ export class FamilyTracker<
|
|
|
17
17
|
public readonly latestSignalAtoms: RegularAtomFamily<SignalFrom<T> | null, K>
|
|
18
18
|
public readonly mutableAtoms: MutableAtomFamily<T, K>
|
|
19
19
|
|
|
20
|
-
public constructor(mutableAtoms: MutableAtomFamily<T, K>, store:
|
|
20
|
+
public constructor(mutableAtoms: MutableAtomFamily<T, K>, store: RootStore) {
|
|
21
21
|
const latestSignalAtoms = createRegularAtomFamily<SignalFrom<T> | null, K>(
|
|
22
22
|
store,
|
|
23
23
|
{
|
|
@@ -4,7 +4,7 @@ import type {
|
|
|
4
4
|
ReadonlyHeldSelectorToken,
|
|
5
5
|
} from "atom.io"
|
|
6
6
|
|
|
7
|
-
import type { ReadonlyHeldSelector } from ".."
|
|
7
|
+
import type { ReadonlyHeldSelector, RootStore } from ".."
|
|
8
8
|
import { writeToCache } from "../caching"
|
|
9
9
|
import { newest } from "../lineage"
|
|
10
10
|
import type { Store } from "../store"
|
|
@@ -47,7 +47,7 @@ export function createReadonlyHeldSelector<T extends object>(
|
|
|
47
47
|
type,
|
|
48
48
|
subject,
|
|
49
49
|
getFrom,
|
|
50
|
-
install: (s:
|
|
50
|
+
install: (s: RootStore) => createReadonlyHeldSelector(s, options, family),
|
|
51
51
|
}
|
|
52
52
|
if (family) readonlySelector.family = family
|
|
53
53
|
|
|
@@ -4,7 +4,7 @@ import type {
|
|
|
4
4
|
ReadonlyPureSelectorToken,
|
|
5
5
|
} from "atom.io"
|
|
6
6
|
|
|
7
|
-
import type { ReadonlyPureSelector } from ".."
|
|
7
|
+
import type { ReadonlyPureSelector, RootStore } from ".."
|
|
8
8
|
import { writeToCache } from "../caching"
|
|
9
9
|
import { newest } from "../lineage"
|
|
10
10
|
import type { Store } from "../store"
|
|
@@ -48,7 +48,7 @@ export function createReadonlyPureSelector<T>(
|
|
|
48
48
|
type,
|
|
49
49
|
subject,
|
|
50
50
|
getFrom,
|
|
51
|
-
install: (s:
|
|
51
|
+
install: (s: RootStore) => createReadonlyPureSelector(s, options, family),
|
|
52
52
|
}
|
|
53
53
|
if (family) readonlySelector.family = family
|
|
54
54
|
|
|
@@ -4,7 +4,7 @@ import type {
|
|
|
4
4
|
WritableHeldSelectorToken,
|
|
5
5
|
} from "atom.io"
|
|
6
6
|
|
|
7
|
-
import type { WritableHeldSelector } from ".."
|
|
7
|
+
import type { RootStore, WritableHeldSelector } from ".."
|
|
8
8
|
import { writeToCache } from "../caching"
|
|
9
9
|
import { newest } from "../lineage"
|
|
10
10
|
import type { Store } from "../store"
|
|
@@ -54,7 +54,7 @@ export function createWritableHeldSelector<T extends object>(
|
|
|
54
54
|
subject,
|
|
55
55
|
getFrom,
|
|
56
56
|
setSelf,
|
|
57
|
-
install: (s:
|
|
57
|
+
install: (s: RootStore) => createWritableHeldSelector(s, options, family),
|
|
58
58
|
}
|
|
59
59
|
if (family) mySelector.family = family
|
|
60
60
|
|
|
@@ -4,7 +4,7 @@ import type {
|
|
|
4
4
|
WritablePureSelectorToken,
|
|
5
5
|
} from "atom.io"
|
|
6
6
|
|
|
7
|
-
import type { WritablePureSelector } from ".."
|
|
7
|
+
import type { RootStore, WritablePureSelector } from ".."
|
|
8
8
|
import { writeToCache } from "../caching"
|
|
9
9
|
import { newest } from "../lineage"
|
|
10
10
|
import type { Store } from "../store"
|
|
@@ -54,7 +54,7 @@ export function createWritablePureSelector<T>(
|
|
|
54
54
|
subject,
|
|
55
55
|
getFrom,
|
|
56
56
|
setSelf,
|
|
57
|
-
install: (s:
|
|
57
|
+
install: (s: RootStore) => createWritablePureSelector(s, options, family),
|
|
58
58
|
}
|
|
59
59
|
if (family) mySelector.family = family
|
|
60
60
|
|
|
@@ -28,7 +28,7 @@ export function dispatchOrDeferStateUpdate<T>(
|
|
|
28
28
|
if (stateIsNewlyCreated && family) {
|
|
29
29
|
state.subject.next({ newValue })
|
|
30
30
|
const stateCreationEvent: StateCreationEvent<any> & TimelineEvent<any> = {
|
|
31
|
-
|
|
31
|
+
checkpoint: true,
|
|
32
32
|
type: `state_creation`,
|
|
33
33
|
subType: `writable`,
|
|
34
34
|
token,
|
|
@@ -14,21 +14,19 @@ export function resetInStore<K extends Canonical>(
|
|
|
14
14
|
key: K,
|
|
15
15
|
): void
|
|
16
16
|
|
|
17
|
-
export function resetInStore<T>(
|
|
17
|
+
export function resetInStore<T, K extends Canonical, Key extends K>(
|
|
18
18
|
store: Store,
|
|
19
19
|
...params:
|
|
20
|
-
| [token: WritableFamilyToken<T,
|
|
20
|
+
| [token: WritableFamilyToken<T, K>, key: Key]
|
|
21
|
+
| [token: WritableToken<T>]
|
|
22
|
+
): void
|
|
23
|
+
|
|
24
|
+
export function resetInStore<T, K extends Canonical, Key extends K>(
|
|
25
|
+
store: Store,
|
|
26
|
+
...params:
|
|
27
|
+
| [token: WritableFamilyToken<T, K>, key: Key]
|
|
21
28
|
| [token: WritableToken<T>]
|
|
22
29
|
): void {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
let key: Canonical | null
|
|
26
|
-
if (params.length === 1) {
|
|
27
|
-
token = params[0]
|
|
28
|
-
setIntoStore(store, token, RESET_STATE)
|
|
29
|
-
} else {
|
|
30
|
-
family = params[0]
|
|
31
|
-
key = params[1]
|
|
32
|
-
setIntoStore(store, family, key, RESET_STATE)
|
|
33
|
-
}
|
|
30
|
+
const subParams = [...params, RESET_STATE] as const
|
|
31
|
+
setIntoStore(store, ...subParams)
|
|
34
32
|
}
|
|
@@ -23,12 +23,36 @@ export function setIntoStore<
|
|
|
23
23
|
value: New | typeof RESET_STATE | ((oldValue: T) => New),
|
|
24
24
|
): void
|
|
25
25
|
|
|
26
|
-
export function setIntoStore<
|
|
26
|
+
export function setIntoStore<
|
|
27
|
+
T,
|
|
28
|
+
K extends Canonical,
|
|
29
|
+
New extends T,
|
|
30
|
+
Key extends K,
|
|
31
|
+
>(
|
|
32
|
+
store: Store,
|
|
33
|
+
...params:
|
|
34
|
+
| [
|
|
35
|
+
token: WritableFamilyToken<T, K>,
|
|
36
|
+
key: Key,
|
|
37
|
+
value: New | typeof RESET_STATE | ((oldValue: T) => New),
|
|
38
|
+
]
|
|
39
|
+
| [
|
|
40
|
+
token: WritableToken<T>,
|
|
41
|
+
value: New | typeof RESET_STATE | ((oldValue: T) => New),
|
|
42
|
+
]
|
|
43
|
+
): void
|
|
44
|
+
|
|
45
|
+
export function setIntoStore<
|
|
46
|
+
T,
|
|
47
|
+
K extends Canonical,
|
|
48
|
+
New extends T,
|
|
49
|
+
Key extends K,
|
|
50
|
+
>(
|
|
27
51
|
store: Store,
|
|
28
52
|
...params:
|
|
29
53
|
| [
|
|
30
|
-
token: WritableFamilyToken<T,
|
|
31
|
-
key:
|
|
54
|
+
token: WritableFamilyToken<T, K>,
|
|
55
|
+
key: Key,
|
|
32
56
|
value: New | typeof RESET_STATE | ((oldValue: T) => New),
|
|
33
57
|
]
|
|
34
58
|
| [
|
|
@@ -30,6 +30,8 @@ import type { OperationProgress } from "../operation"
|
|
|
30
30
|
import { StatefulSubject, Subject } from "../subject"
|
|
31
31
|
import type { Timeline } from "../timeline"
|
|
32
32
|
import type {
|
|
33
|
+
ChildStore,
|
|
34
|
+
RootStore,
|
|
33
35
|
Transaction,
|
|
34
36
|
TransactionEpoch,
|
|
35
37
|
TransactionProgress,
|
|
@@ -39,8 +41,8 @@ import type { Fn } from "../utility-types"
|
|
|
39
41
|
import { CircularBuffer } from "./circular-buffer"
|
|
40
42
|
|
|
41
43
|
export class Store implements Lineage {
|
|
42
|
-
public parent:
|
|
43
|
-
public child:
|
|
44
|
+
public parent: ChildStore | RootStore | null = null
|
|
45
|
+
public child: ChildStore | null = null
|
|
44
46
|
|
|
45
47
|
public valueMap: Map<string, any> = new Map()
|
|
46
48
|
public defaults: Map<string, any> = new Map()
|
|
@@ -210,14 +212,14 @@ export class Store implements Lineage {
|
|
|
210
212
|
) {
|
|
211
213
|
continue
|
|
212
214
|
}
|
|
213
|
-
family.install(this)
|
|
215
|
+
family.install(this as RootStore)
|
|
214
216
|
}
|
|
215
217
|
const mutableHelpers = new Set<string>()
|
|
216
218
|
for (const [, atom] of store.atoms) {
|
|
217
219
|
if (mutableHelpers.has(atom.key)) {
|
|
218
220
|
continue
|
|
219
221
|
}
|
|
220
|
-
atom.install(this)
|
|
222
|
+
atom.install(this as RootStore)
|
|
221
223
|
if (atom.type === `mutable_atom`) {
|
|
222
224
|
const originalJsonToken = getJsonToken(store, atom)
|
|
223
225
|
const originalUpdateToken = getUpdateToken(atom)
|
|
@@ -226,19 +228,19 @@ export class Store implements Lineage {
|
|
|
226
228
|
}
|
|
227
229
|
}
|
|
228
230
|
for (const [, selector] of store.readonlySelectors) {
|
|
229
|
-
selector.install(this)
|
|
231
|
+
selector.install(this as RootStore)
|
|
230
232
|
}
|
|
231
233
|
for (const [, selector] of store.writableSelectors) {
|
|
232
234
|
if (mutableHelpers.has(selector.key)) {
|
|
233
235
|
continue
|
|
234
236
|
}
|
|
235
|
-
selector.install(this)
|
|
237
|
+
selector.install(this as RootStore)
|
|
236
238
|
}
|
|
237
239
|
for (const [, tx] of store.transactions) {
|
|
238
|
-
tx.install(this)
|
|
240
|
+
tx.install(this as RootStore)
|
|
239
241
|
}
|
|
240
242
|
for (const [, timeline] of store.timelines) {
|
|
241
|
-
timeline.install(this)
|
|
243
|
+
timeline.install(this as RootStore)
|
|
242
244
|
}
|
|
243
245
|
}
|
|
244
246
|
}
|
|
@@ -258,15 +260,15 @@ export type StoreEventCarrier = {
|
|
|
258
260
|
}
|
|
259
261
|
|
|
260
262
|
declare global {
|
|
261
|
-
var ATOM_IO_IMPLICIT_STORE:
|
|
263
|
+
var ATOM_IO_IMPLICIT_STORE: RootStore | undefined
|
|
262
264
|
}
|
|
263
265
|
|
|
264
|
-
export const IMPLICIT: { readonly STORE:
|
|
265
|
-
get STORE():
|
|
266
|
+
export const IMPLICIT: { readonly STORE: RootStore } = {
|
|
267
|
+
get STORE(): RootStore {
|
|
266
268
|
globalThis.ATOM_IO_IMPLICIT_STORE ??= new Store({
|
|
267
269
|
name: `IMPLICIT_STORE`,
|
|
268
270
|
lifespan: `ephemeral`,
|
|
269
|
-
})
|
|
271
|
+
}) as RootStore
|
|
270
272
|
return globalThis.ATOM_IO_IMPLICIT_STORE
|
|
271
273
|
},
|
|
272
274
|
}
|