atom.io 0.36.2 → 0.37.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/dist/data/index.d.ts.map +1 -1
- package/dist/data/index.js.map +1 -1
- package/dist/eslint-plugin/index.js +1 -2
- package/dist/eslint-plugin/index.js.map +1 -1
- package/dist/internal/index.d.ts +66 -98
- package/dist/internal/index.d.ts.map +1 -1
- package/dist/internal/index.js +544 -507
- 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 +1 -1
- package/dist/introspection/index.js.map +1 -1
- package/dist/json/index.d.ts +2 -1
- package/dist/json/index.d.ts.map +1 -1
- package/dist/json/index.js.map +1 -1
- package/dist/main/index.d.ts +154 -139
- package/dist/main/index.d.ts.map +1 -1
- package/dist/main/index.js.map +1 -1
- package/dist/react/index.d.ts.map +1 -1
- package/dist/react/index.js.map +1 -1
- package/dist/react-devtools/index.d.ts.map +1 -1
- package/dist/react-devtools/index.js +54 -56
- package/dist/react-devtools/index.js.map +1 -1
- package/dist/realtime/index.d.ts.map +1 -1
- package/dist/realtime/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 +6 -6
- package/dist/realtime-client/index.js.map +1 -1
- package/dist/realtime-react/index.d.ts.map +1 -1
- package/dist/realtime-react/index.js.map +1 -1
- package/dist/realtime-server/index.d.ts +5 -5
- package/dist/realtime-server/index.d.ts.map +1 -1
- package/dist/realtime-server/index.js +10 -12
- package/dist/realtime-server/index.js.map +1 -1
- package/dist/realtime-testing/index.d.ts.map +1 -1
- package/dist/realtime-testing/index.js.map +1 -1
- package/dist/transceivers/set-rtx/index.d.ts +1 -1
- package/dist/transceivers/set-rtx/index.d.ts.map +1 -1
- package/dist/transceivers/set-rtx/index.js +1 -3
- package/dist/transceivers/set-rtx/index.js.map +1 -1
- package/dist/use-o-DXPncKmZ.js.map +1 -1
- package/dist/web/index.d.ts +2 -2
- package/dist/web/index.d.ts.map +1 -1
- package/dist/web/index.js.map +1 -1
- package/package.json +14 -14
- package/src/internal/atom/dispose-atom.ts +5 -4
- package/src/internal/caching.ts +3 -3
- package/src/internal/families/create-readonly-held-selector-family.ts +3 -5
- package/src/internal/families/create-readonly-pure-selector-family.ts +3 -5
- package/src/internal/families/create-regular-atom-family.ts +3 -6
- package/src/internal/families/create-writable-held-selector-family.ts +3 -5
- package/src/internal/families/create-writable-pure-selector-family.ts +3 -5
- package/src/internal/families/find-in-store.ts +17 -34
- package/src/internal/families/init-family-member.ts +5 -87
- package/src/internal/families/mint-in-store.ts +74 -0
- package/src/internal/get-state/read-or-compute-value.ts +4 -2
- package/src/internal/index.ts +19 -18
- package/src/internal/ingest-updates/ingest-atom-update.ts +7 -7
- package/src/internal/ingest-updates/ingest-creation-disposal.ts +11 -11
- package/src/internal/ingest-updates/ingest-selector-update.ts +8 -4
- package/src/internal/ingest-updates/ingest-transaction-update.ts +5 -6
- package/src/internal/install-into-store.ts +2 -2
- package/src/internal/join/join-internal.ts +1 -1
- package/src/internal/molecule.ts +12 -9
- package/src/internal/mutable/create-mutable-atom-family.ts +3 -6
- package/src/internal/mutable/tracker.ts +2 -2
- package/src/internal/mutable/transceiver.ts +6 -4
- package/src/internal/operation.ts +17 -14
- package/src/internal/selector/create-readonly-held-selector.ts +9 -7
- package/src/internal/selector/create-readonly-pure-selector.ts +8 -5
- package/src/internal/selector/create-writable-held-selector.ts +12 -21
- package/src/internal/selector/create-writable-pure-selector.ts +16 -29
- package/src/internal/selector/dispose-selector.ts +6 -1
- package/src/internal/selector/get-selector-dependency-keys.ts +2 -6
- package/src/internal/selector/register-selector.ts +64 -74
- package/src/internal/selector/trace-selector-atoms.ts +2 -2
- package/src/internal/selector/update-selector-atoms.ts +2 -2
- package/src/internal/set-state/dispatch-state-update.ts +101 -0
- package/src/internal/set-state/operate-on-store.ts +126 -0
- package/src/internal/set-state/reset-atom-or-selector.ts +24 -15
- package/src/internal/set-state/set-atom-or-selector.ts +9 -4
- package/src/internal/set-state/set-atom.ts +4 -49
- package/src/internal/set-state/set-into-store.ts +11 -77
- package/src/internal/set-state/set-selector.ts +35 -0
- package/src/internal/store/store.ts +4 -4
- package/src/internal/subscribe/subscribe-in-store.ts +3 -3
- package/src/internal/subscribe/subscribe-to-timeline.ts +2 -2
- package/src/internal/timeline/create-timeline.ts +57 -101
- package/src/internal/timeline/time-travel.ts +1 -1
- package/src/internal/transaction/abort-transaction.ts +1 -1
- package/src/internal/transaction/apply-transaction.ts +7 -7
- package/src/internal/transaction/build-transaction.ts +10 -9
- package/src/internal/transaction/create-transaction.ts +4 -3
- package/src/internal/transaction/index.ts +6 -2
- package/src/introspection/attach-introspection-states.ts +2 -2
- package/src/introspection/attach-transaction-logs.ts +13 -6
- package/src/json/index.ts +3 -1
- package/src/main/atom.ts +2 -1
- package/src/main/events.ts +109 -0
- package/src/main/get-state.ts +1 -1
- package/src/main/index.ts +3 -0
- package/src/main/subscribe.ts +9 -19
- package/src/main/timeline.ts +3 -21
- package/src/main/transaction.ts +0 -65
- package/src/main/validators.ts +8 -2
- package/src/react-devtools/TimelineIndex.tsx +1 -1
- package/src/react-devtools/TransactionIndex.tsx +5 -3
- package/src/react-devtools/Updates.tsx +54 -46
- package/src/realtime-client/continuity/register-and-attempt-confirmed-update.ts +20 -10
- package/src/realtime-client/realtime-client-stores/client-sync-store.ts +4 -4
- package/src/realtime-client/sync-continuity.ts +1 -1
- package/src/realtime-server/continuity/prepare-to-serve-transaction-request.ts +14 -8
- package/src/realtime-server/continuity/prepare-to-track-client-acknowledgement.ts +5 -2
- package/src/realtime-server/continuity/subscribe-to-continuity-actions.ts +1 -1
- package/src/realtime-server/realtime-action-receiver.ts +6 -3
- package/src/realtime-server/realtime-server-stores/server-sync-store.ts +13 -16
- package/src/transceivers/set-rtx/set-rtx.ts +1 -3
- package/src/web/persist-sync.ts +2 -2
- package/src/internal/set-state/emit-update.ts +0 -40
package/src/internal/index.ts
CHANGED
|
@@ -9,9 +9,10 @@ import type {
|
|
|
9
9
|
ReadonlyPureSelectorToken,
|
|
10
10
|
RegularAtomFamilyToken,
|
|
11
11
|
RegularAtomToken,
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
StateCreationEvent,
|
|
13
|
+
StateDisposalEvent,
|
|
14
14
|
StateLifecycleEvent,
|
|
15
|
+
StateUpdate,
|
|
15
16
|
WritableHeldSelectorFamilyToken,
|
|
16
17
|
WritableHeldSelectorToken,
|
|
17
18
|
WritablePureSelectorFamilyToken,
|
|
@@ -62,7 +63,7 @@ export type AtomIOState = {
|
|
|
62
63
|
key: string
|
|
63
64
|
family?: FamilyMetadata
|
|
64
65
|
install: (store: Store) => void
|
|
65
|
-
subject: Subject<
|
|
66
|
+
subject: Subject<StateUpdate<any>>
|
|
66
67
|
}
|
|
67
68
|
export type RegularAtom<T> = Flat<
|
|
68
69
|
AtomIOState & {
|
|
@@ -87,28 +88,28 @@ export type WritableHeldSelector<T> = Flat<
|
|
|
87
88
|
AtomIOState & {
|
|
88
89
|
type: `writable_held_selector`
|
|
89
90
|
const: T
|
|
90
|
-
|
|
91
|
-
|
|
91
|
+
getFrom: (target: Store) => T
|
|
92
|
+
setSelf: (newValue: T) => void
|
|
92
93
|
}
|
|
93
94
|
>
|
|
94
95
|
export type ReadonlyHeldSelector<T> = Flat<
|
|
95
96
|
AtomIOState & {
|
|
96
97
|
type: `readonly_held_selector`
|
|
97
98
|
const: T
|
|
98
|
-
|
|
99
|
+
getFrom: (target: Store) => T
|
|
99
100
|
}
|
|
100
101
|
>
|
|
101
102
|
export type WritablePureSelector<T> = Flat<
|
|
102
103
|
AtomIOState & {
|
|
103
104
|
type: `writable_pure_selector`
|
|
104
|
-
|
|
105
|
-
|
|
105
|
+
getFrom: (target: Store) => T
|
|
106
|
+
setSelf: (newValue: T) => void
|
|
106
107
|
}
|
|
107
108
|
>
|
|
108
109
|
export type ReadonlyPureSelector<T> = Flat<
|
|
109
110
|
AtomIOState & {
|
|
110
111
|
type: `readonly_pure_selector`
|
|
111
|
-
|
|
112
|
+
getFrom: (target: Store) => T
|
|
112
113
|
}
|
|
113
114
|
>
|
|
114
115
|
export type ReadonlySelector<T> =
|
|
@@ -135,7 +136,7 @@ export type RegularAtomFamily<T, K extends Canonical> =
|
|
|
135
136
|
(key: K): RegularAtomToken<T>
|
|
136
137
|
install: (store: Store) => void
|
|
137
138
|
internalRoles: string[] | undefined
|
|
138
|
-
subject: Subject<
|
|
139
|
+
subject: Subject<StateCreationEvent<AtomToken<T>> | StateDisposalEvent<AtomToken<T>>>
|
|
139
140
|
}
|
|
140
141
|
|
|
141
142
|
// biome-ignore format: intersection
|
|
@@ -167,8 +168,8 @@ export type WritablePureSelectorFamily<T, K extends Canonical> =
|
|
|
167
168
|
install: (store: Store) => void
|
|
168
169
|
internalRoles: string[] | undefined
|
|
169
170
|
subject: Subject<
|
|
170
|
-
|
|
|
171
|
-
|
|
|
171
|
+
| StateCreationEvent<WritablePureSelectorToken<T>>
|
|
172
|
+
| StateDisposalEvent<WritablePureSelectorToken<T>>
|
|
172
173
|
>
|
|
173
174
|
}
|
|
174
175
|
>
|
|
@@ -183,8 +184,8 @@ export type WritableHeldSelectorFamily<T , K extends Canonical> =
|
|
|
183
184
|
install: (store: Store) => void
|
|
184
185
|
internalRoles: string[] | undefined
|
|
185
186
|
subject: Subject<
|
|
186
|
-
|
|
|
187
|
-
|
|
|
187
|
+
| StateCreationEvent<WritableHeldSelectorToken<T>>
|
|
188
|
+
| StateDisposalEvent<WritableHeldSelectorToken<T>>
|
|
188
189
|
>
|
|
189
190
|
}
|
|
190
191
|
>
|
|
@@ -199,8 +200,8 @@ export type ReadonlyPureSelectorFamily<T, K extends Canonical> =
|
|
|
199
200
|
install: (store: Store) => void
|
|
200
201
|
internalRoles: string[] | undefined
|
|
201
202
|
subject: Subject<
|
|
202
|
-
|
|
|
203
|
-
|
|
|
203
|
+
| StateCreationEvent<ReadonlyPureSelectorToken<T>>
|
|
204
|
+
| StateDisposalEvent<ReadonlyPureSelectorToken<T>>
|
|
204
205
|
>
|
|
205
206
|
}
|
|
206
207
|
>
|
|
@@ -215,8 +216,8 @@ export type ReadonlyHeldSelectorFamily<T , K extends Canonical> =
|
|
|
215
216
|
install: (store: Store) => void
|
|
216
217
|
internalRoles: string[] | undefined
|
|
217
218
|
subject: Subject<
|
|
218
|
-
|
|
|
219
|
-
|
|
|
219
|
+
| StateCreationEvent<ReadonlyHeldSelectorToken<T>>
|
|
220
|
+
| StateDisposalEvent<ReadonlyHeldSelectorToken<T>>
|
|
220
221
|
>
|
|
221
222
|
}
|
|
222
223
|
>
|
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { AtomUpdateEvent } from "atom.io"
|
|
2
2
|
|
|
3
3
|
import { setIntoStore } from "../set-state"
|
|
4
4
|
import type { Store } from "../store"
|
|
5
5
|
|
|
6
6
|
export function ingestAtomUpdate(
|
|
7
7
|
applying: `newValue` | `oldValue`,
|
|
8
|
-
atomUpdate:
|
|
8
|
+
atomUpdate: AtomUpdateEvent<any>,
|
|
9
9
|
store: Store,
|
|
10
10
|
): void {
|
|
11
|
-
const {
|
|
11
|
+
const {
|
|
12
|
+
token,
|
|
13
|
+
update: { newValue, oldValue },
|
|
14
|
+
} = atomUpdate
|
|
12
15
|
const value = applying === `newValue` ? newValue : oldValue
|
|
13
|
-
|
|
14
|
-
if (atomUpdate.family) {
|
|
15
|
-
Object.assign(token, { family: atomUpdate.family })
|
|
16
|
-
}
|
|
16
|
+
|
|
17
17
|
setIntoStore(store, token, value)
|
|
18
18
|
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import type {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
MoleculeCreationEvent,
|
|
3
|
+
MoleculeDisposalEvent,
|
|
4
|
+
MoleculeTransferEvent,
|
|
5
5
|
ReadableToken,
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
StateCreationEvent,
|
|
7
|
+
StateDisposalEvent,
|
|
8
8
|
} from "atom.io"
|
|
9
9
|
import { parseJson, stringifyJson } from "atom.io/json"
|
|
10
10
|
|
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
import type { Store } from "../store"
|
|
18
18
|
|
|
19
19
|
export function ingestCreationEvent(
|
|
20
|
-
update:
|
|
20
|
+
update: StateCreationEvent<any>,
|
|
21
21
|
applying: `newValue` | `oldValue`,
|
|
22
22
|
store: Store,
|
|
23
23
|
): void {
|
|
@@ -34,7 +34,7 @@ export function ingestCreationEvent(
|
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
export function ingestDisposalEvent(
|
|
37
|
-
update:
|
|
37
|
+
update: StateDisposalEvent<ReadableToken<any>>,
|
|
38
38
|
applying: `newValue` | `oldValue`,
|
|
39
39
|
store: Store,
|
|
40
40
|
): void {
|
|
@@ -54,7 +54,7 @@ export function ingestDisposalEvent(
|
|
|
54
54
|
}
|
|
55
55
|
|
|
56
56
|
function createInStore(
|
|
57
|
-
update:
|
|
57
|
+
update: StateCreationEvent<any> | StateDisposalEvent<any>,
|
|
58
58
|
store: Store,
|
|
59
59
|
): void {
|
|
60
60
|
const { family: familyMeta } = update.token
|
|
@@ -67,7 +67,7 @@ function createInStore(
|
|
|
67
67
|
}
|
|
68
68
|
|
|
69
69
|
export function ingestMoleculeCreationEvent(
|
|
70
|
-
update:
|
|
70
|
+
update: MoleculeCreationEvent,
|
|
71
71
|
applying: `newValue` | `oldValue`,
|
|
72
72
|
store: Store,
|
|
73
73
|
): void {
|
|
@@ -82,7 +82,7 @@ export function ingestMoleculeCreationEvent(
|
|
|
82
82
|
}
|
|
83
83
|
}
|
|
84
84
|
export function ingestMoleculeDisposalEvent(
|
|
85
|
-
update:
|
|
85
|
+
update: MoleculeDisposalEvent,
|
|
86
86
|
applying: `newValue` | `oldValue`,
|
|
87
87
|
store: Store,
|
|
88
88
|
): void {
|
|
@@ -108,7 +108,7 @@ export function ingestMoleculeDisposalEvent(
|
|
|
108
108
|
}
|
|
109
109
|
}
|
|
110
110
|
export function ingestMoleculeTransferEvent(
|
|
111
|
-
update:
|
|
111
|
+
update: MoleculeTransferEvent,
|
|
112
112
|
applying: `newValue` | `oldValue`,
|
|
113
113
|
store: Store,
|
|
114
114
|
): void {
|
|
@@ -1,15 +1,19 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {
|
|
2
|
+
AtomOnly,
|
|
3
|
+
AtomUpdateEvent,
|
|
4
|
+
TimelineManageable,
|
|
5
|
+
TimelineSelectorUpdateEvent,
|
|
6
|
+
} from "atom.io"
|
|
2
7
|
|
|
3
8
|
import type { Store } from "../store"
|
|
4
|
-
import type { TimelineAtomUpdate, TimelineSelectorUpdate } from "../timeline"
|
|
5
9
|
import { ingestAtomUpdate } from "./ingest-atom-update"
|
|
6
10
|
|
|
7
11
|
export function ingestSelectorUpdate(
|
|
8
12
|
applying: `newValue` | `oldValue`,
|
|
9
|
-
selectorUpdate:
|
|
13
|
+
selectorUpdate: TimelineSelectorUpdateEvent<any>,
|
|
10
14
|
store: Store,
|
|
11
15
|
): void {
|
|
12
|
-
let updates:
|
|
16
|
+
let updates: AtomUpdateEvent<AtomOnly<TimelineManageable>>[]
|
|
13
17
|
if (applying === `newValue`) {
|
|
14
18
|
updates = selectorUpdate.atomUpdates
|
|
15
19
|
} else {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { TransactionOutcomeEvent } from "atom.io"
|
|
2
2
|
|
|
3
3
|
import type { Store } from "../store"
|
|
4
4
|
import { ingestAtomUpdate } from "./ingest-atom-update"
|
|
@@ -12,17 +12,16 @@ import {
|
|
|
12
12
|
|
|
13
13
|
export function ingestTransactionUpdate(
|
|
14
14
|
applying: `newValue` | `oldValue`,
|
|
15
|
-
transactionUpdate:
|
|
15
|
+
transactionUpdate: TransactionOutcomeEvent<any>,
|
|
16
16
|
store: Store,
|
|
17
17
|
): void {
|
|
18
18
|
const updates =
|
|
19
19
|
applying === `newValue`
|
|
20
|
-
? transactionUpdate.
|
|
21
|
-
: [...transactionUpdate.
|
|
20
|
+
? transactionUpdate.subEvents
|
|
21
|
+
: [...transactionUpdate.subEvents].reverse()
|
|
22
22
|
for (const updateFromTransaction of updates) {
|
|
23
23
|
switch (updateFromTransaction.type) {
|
|
24
24
|
case `atom_update`:
|
|
25
|
-
case `selector_update`:
|
|
26
25
|
ingestAtomUpdate(applying, updateFromTransaction, store)
|
|
27
26
|
break
|
|
28
27
|
case `state_creation`:
|
|
@@ -40,7 +39,7 @@ export function ingestTransactionUpdate(
|
|
|
40
39
|
case `molecule_transfer`:
|
|
41
40
|
ingestMoleculeTransferEvent(updateFromTransaction, applying, store)
|
|
42
41
|
break
|
|
43
|
-
case `
|
|
42
|
+
case `transaction_outcome`:
|
|
44
43
|
ingestTransactionUpdate(applying, updateFromTransaction, store)
|
|
45
44
|
break
|
|
46
45
|
}
|
|
@@ -22,7 +22,7 @@ export function installIntoStore(
|
|
|
22
22
|
source.logger.error(
|
|
23
23
|
`❌`,
|
|
24
24
|
`transaction`,
|
|
25
|
-
sourceNewest.transactionMeta.update.key,
|
|
25
|
+
sourceNewest.transactionMeta.update.token.key,
|
|
26
26
|
`could not install the following tokens into store "${target.config.name} from "${source.config.name}":`,
|
|
27
27
|
tokens,
|
|
28
28
|
`${sourceNewest.config.name} is undergoing a transaction.`,
|
|
@@ -34,7 +34,7 @@ export function installIntoStore(
|
|
|
34
34
|
target.logger.error(
|
|
35
35
|
`❌`,
|
|
36
36
|
`transaction`,
|
|
37
|
-
targetNewest.transactionMeta.update.key,
|
|
37
|
+
targetNewest.transactionMeta.update.token.key,
|
|
38
38
|
`could not install the following tokens into store "${target.config.name} from "${source.config.name}":`,
|
|
39
39
|
tokens,
|
|
40
40
|
`${targetNewest.config.name} is undergoing a transaction.`,
|
|
@@ -8,6 +8,7 @@ import type {
|
|
|
8
8
|
ReadonlyPureSelectorFamilyToken,
|
|
9
9
|
RegularAtomFamilyToken,
|
|
10
10
|
setState,
|
|
11
|
+
ViewOf,
|
|
11
12
|
Write,
|
|
12
13
|
WriterToolkit,
|
|
13
14
|
} from "atom.io"
|
|
@@ -29,7 +30,6 @@ import type {
|
|
|
29
30
|
} from "../junction"
|
|
30
31
|
import { Junction } from "../junction"
|
|
31
32
|
import type { Molecule } from "../molecule"
|
|
32
|
-
import type { ViewOf } from "../mutable"
|
|
33
33
|
import { createMutableAtomFamily, getJsonFamily, getJsonToken } from "../mutable"
|
|
34
34
|
import { setIntoStore } from "../set-state"
|
|
35
35
|
import type { Store } from "../store"
|
package/src/internal/molecule.ts
CHANGED
|
@@ -4,9 +4,9 @@ import type {
|
|
|
4
4
|
CompoundFrom,
|
|
5
5
|
CompoundTypedKey,
|
|
6
6
|
Hierarchy,
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
MoleculeCreationEvent,
|
|
8
|
+
MoleculeDisposalEvent,
|
|
9
|
+
MoleculeTransferEvent,
|
|
10
10
|
SingularTypedKey,
|
|
11
11
|
Vassal,
|
|
12
12
|
} from "atom.io"
|
|
@@ -77,15 +77,16 @@ export function allocateIntoStore<
|
|
|
77
77
|
target.molecules.set(stringKey, { key, stringKey, dependsOn })
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
-
const creationEvent:
|
|
80
|
+
const creationEvent: MoleculeCreationEvent = {
|
|
81
81
|
type: `molecule_creation`,
|
|
82
82
|
key,
|
|
83
83
|
provenance: origin,
|
|
84
|
+
timestamp: Date.now(),
|
|
84
85
|
}
|
|
85
86
|
const isTransaction =
|
|
86
87
|
isChildStore(target) && target.transactionMeta.phase === `building`
|
|
87
88
|
if (isTransaction) {
|
|
88
|
-
target.transactionMeta.update.
|
|
89
|
+
target.transactionMeta.update.subEvents.push(creationEvent)
|
|
89
90
|
} else {
|
|
90
91
|
target.on.moleculeCreation.next(creationEvent)
|
|
91
92
|
}
|
|
@@ -174,18 +175,19 @@ export function deallocateFromStore<H extends Hierarchy, V extends Vassal<H>>(
|
|
|
174
175
|
const provenance: stringified<Canonical>[] = []
|
|
175
176
|
|
|
176
177
|
const values: [string, any][] = []
|
|
177
|
-
const disposalEvent:
|
|
178
|
+
const disposalEvent: MoleculeDisposalEvent = {
|
|
178
179
|
type: `molecule_disposal`,
|
|
179
180
|
key: molecule.key,
|
|
180
181
|
values,
|
|
181
182
|
provenance,
|
|
183
|
+
timestamp: Date.now(),
|
|
182
184
|
}
|
|
183
185
|
const target = newest(store)
|
|
184
186
|
target.molecules.delete(stringKey)
|
|
185
187
|
const isTransaction =
|
|
186
188
|
isChildStore(target) && target.transactionMeta.phase === `building`
|
|
187
189
|
if (isTransaction) {
|
|
188
|
-
target.transactionMeta.update.
|
|
190
|
+
target.transactionMeta.update.subEvents.push(disposalEvent)
|
|
189
191
|
}
|
|
190
192
|
const relatedMolecules = store.moleculeGraph.getRelationEntries({
|
|
191
193
|
downstreamMoleculeKey: molecule.stringKey,
|
|
@@ -290,17 +292,18 @@ export function claimWithinStore<
|
|
|
290
292
|
source: newProvenanceMolecule.stringKey,
|
|
291
293
|
},
|
|
292
294
|
)
|
|
293
|
-
const transferEvent:
|
|
295
|
+
const transferEvent: MoleculeTransferEvent = {
|
|
294
296
|
type: `molecule_transfer`,
|
|
295
297
|
key: molecule.key,
|
|
296
298
|
exclusive: Boolean(exclusive),
|
|
297
299
|
from: priorProvenance,
|
|
298
300
|
to: [newProvenanceMolecule.key],
|
|
301
|
+
timestamp: Date.now(),
|
|
299
302
|
}
|
|
300
303
|
const isTransaction =
|
|
301
304
|
isChildStore(target) && target.transactionMeta.phase === `building`
|
|
302
305
|
if (isTransaction) {
|
|
303
|
-
target.transactionMeta.update.
|
|
306
|
+
target.transactionMeta.update.subEvents.push(transferEvent)
|
|
304
307
|
}
|
|
305
308
|
|
|
306
309
|
return claim
|
|
@@ -4,8 +4,7 @@ import type {
|
|
|
4
4
|
MutableAtomFamilyToken,
|
|
5
5
|
MutableAtomOptions,
|
|
6
6
|
MutableAtomToken,
|
|
7
|
-
|
|
8
|
-
StateDisposal,
|
|
7
|
+
StateLifecycleEvent,
|
|
9
8
|
} from "atom.io"
|
|
10
9
|
import type { Canonical } from "atom.io/json"
|
|
11
10
|
import { stringifyJson } from "atom.io/json"
|
|
@@ -48,9 +47,7 @@ export function createMutableAtomFamily<
|
|
|
48
47
|
)
|
|
49
48
|
}
|
|
50
49
|
|
|
51
|
-
const subject = new Subject<
|
|
52
|
-
StateCreation<MutableAtomToken<T>> | StateDisposal<MutableAtomToken<T>>
|
|
53
|
-
>()
|
|
50
|
+
const subject = new Subject<StateLifecycleEvent<MutableAtomToken<T>>>()
|
|
54
51
|
|
|
55
52
|
const familyFunction = (key: K): MutableAtomToken<T> => {
|
|
56
53
|
const subKey = stringifyJson(key)
|
|
@@ -68,7 +65,7 @@ export function createMutableAtomFamily<
|
|
|
68
65
|
|
|
69
66
|
const token = createMutableAtom(target, individualOptions, family)
|
|
70
67
|
|
|
71
|
-
subject.next({ type: `state_creation`, token })
|
|
68
|
+
subject.next({ type: `state_creation`, token, timestamp: Date.now() })
|
|
72
69
|
return token
|
|
73
70
|
}
|
|
74
71
|
|
|
@@ -58,7 +58,7 @@ export class Tracker<T extends Transceiver<any, any, any>> {
|
|
|
58
58
|
const stateKey = mutableState.key
|
|
59
59
|
const storeName = target.config.name
|
|
60
60
|
const storeStatus = isChildStore(target)
|
|
61
|
-
? target.transactionMeta.update.key
|
|
61
|
+
? target.transactionMeta.update.token.key
|
|
62
62
|
: `main`
|
|
63
63
|
const subscriptionKey = `tracker:${storeName}:${storeStatus}:${stateKey}`
|
|
64
64
|
const trackerCapturesOutboundSignal = (update: SignalFrom<T>) => {
|
|
@@ -91,7 +91,7 @@ export class Tracker<T extends Transceiver<any, any, any>> {
|
|
|
91
91
|
target: Store,
|
|
92
92
|
): void {
|
|
93
93
|
const subscriptionKey = `tracker:${target.config.name}:${
|
|
94
|
-
isChildStore(target) ? target.transactionMeta.update.key : `main`
|
|
94
|
+
isChildStore(target) ? target.transactionMeta.update.token.key : `main`
|
|
95
95
|
}:${mutableState.key}`
|
|
96
96
|
subscribeToState(
|
|
97
97
|
target,
|
|
@@ -5,12 +5,12 @@ export interface Transceiver<
|
|
|
5
5
|
S extends Json.Serializable,
|
|
6
6
|
J extends Json.Serializable,
|
|
7
7
|
> {
|
|
8
|
+
READONLY_VIEW: V
|
|
8
9
|
do: (update: S) => number | `OUT_OF_RANGE` | null
|
|
9
10
|
undo: (update: S) => void
|
|
10
11
|
subscribe: (key: string, fn: (update: S) => void) => () => void
|
|
11
12
|
cacheUpdateNumber: number
|
|
12
13
|
getUpdateNumber: (update: S) => number
|
|
13
|
-
view: () => V
|
|
14
14
|
toJSON: () => J
|
|
15
15
|
}
|
|
16
16
|
|
|
@@ -30,14 +30,16 @@ export function isTransceiver(
|
|
|
30
30
|
value !== null &&
|
|
31
31
|
`do` in value &&
|
|
32
32
|
`undo` in value &&
|
|
33
|
-
`subscribe` in value
|
|
33
|
+
`subscribe` in value &&
|
|
34
|
+
`cacheUpdateNumber` in value &&
|
|
35
|
+
`getUpdateNumber` in value &&
|
|
36
|
+
`READONLY_VIEW` in value &&
|
|
37
|
+
`toJSON` in value
|
|
34
38
|
)
|
|
35
39
|
}
|
|
36
40
|
|
|
37
41
|
export type TransceiverMode = `playback` | `record` | `transaction`
|
|
38
42
|
|
|
39
|
-
export type ViewOf<T> = T extends Transceiver<infer V, any, any> ? V : T
|
|
40
|
-
|
|
41
43
|
export type SignalFrom<T extends Transceiver<any, any, any>> =
|
|
42
44
|
T extends Transceiver<any, infer S, any> ? S : never
|
|
43
45
|
|
|
@@ -4,21 +4,22 @@ import type { Store } from "./store"
|
|
|
4
4
|
import { isChildStore } from "./transaction/is-root-store"
|
|
5
5
|
|
|
6
6
|
export type OperationProgress =
|
|
7
|
+
| OpenOperation<any>
|
|
7
8
|
| {
|
|
8
9
|
open: false
|
|
9
10
|
}
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
11
|
+
export type OpenOperation<R extends ReadableToken<any> = ReadableToken<any>> = {
|
|
12
|
+
open: true
|
|
13
|
+
token: R
|
|
14
|
+
done: Set<string>
|
|
15
|
+
prev: Map<string, any>
|
|
16
|
+
timestamp: number
|
|
17
|
+
}
|
|
17
18
|
|
|
18
|
-
export
|
|
19
|
+
export function openOperation(
|
|
19
20
|
store: Store,
|
|
20
21
|
token: ReadableToken<any>,
|
|
21
|
-
): number |
|
|
22
|
+
): number | (Store & { operation: OpenOperation }) {
|
|
22
23
|
if (store.operation.open) {
|
|
23
24
|
const rejectionTime = performance.now()
|
|
24
25
|
store.logger.info(
|
|
@@ -33,7 +34,7 @@ export const openOperation = (
|
|
|
33
34
|
open: true,
|
|
34
35
|
done: new Set(),
|
|
35
36
|
prev: new Map(),
|
|
36
|
-
|
|
37
|
+
timestamp: Date.now(),
|
|
37
38
|
token,
|
|
38
39
|
}
|
|
39
40
|
store.logger.info(
|
|
@@ -41,13 +42,15 @@ export const openOperation = (
|
|
|
41
42
|
token.type,
|
|
42
43
|
token.key,
|
|
43
44
|
`operation start in store "${store.config.name}"${
|
|
44
|
-
|
|
45
|
-
?
|
|
46
|
-
:
|
|
45
|
+
isChildStore(store)
|
|
46
|
+
? ` ${store.transactionMeta.phase} "${store.transactionMeta.update.token.key}"`
|
|
47
|
+
: ``
|
|
47
48
|
}`,
|
|
48
49
|
)
|
|
50
|
+
return store as Store & { operation: OpenOperation }
|
|
49
51
|
}
|
|
50
|
-
|
|
52
|
+
|
|
53
|
+
export function closeOperation(store: Store): void {
|
|
51
54
|
if (store.operation.open) {
|
|
52
55
|
store.logger.info(
|
|
53
56
|
`🔴`,
|
|
@@ -11,19 +11,19 @@ import type { Store } from "../store"
|
|
|
11
11
|
import { Subject } from "../subject"
|
|
12
12
|
import { registerSelector } from "./register-selector"
|
|
13
13
|
|
|
14
|
-
export
|
|
14
|
+
export function createReadonlyHeldSelector<T extends object>(
|
|
15
15
|
store: Store,
|
|
16
16
|
options: ReadonlyHeldSelectorOptions<T>,
|
|
17
17
|
family: FamilyMetadata | undefined,
|
|
18
|
-
): ReadonlyHeldSelectorToken<T>
|
|
18
|
+
): ReadonlyHeldSelectorToken<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
22
|
const { key, const: constant } = options
|
|
23
23
|
const type = `readonly_held_selector` as const
|
|
24
24
|
const { get, find, json } = registerSelector(target, type, key, covered)
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
|
|
26
|
+
const getFrom = (innerTarget: Store) => {
|
|
27
27
|
const upstreamStates = innerTarget.selectorGraph.getRelationEntries({
|
|
28
28
|
downstreamSelectorKey: key,
|
|
29
29
|
})
|
|
@@ -34,7 +34,7 @@ export const createReadonlyHeldSelector = <T extends object>(
|
|
|
34
34
|
}
|
|
35
35
|
innerTarget.selectorAtoms.delete(key)
|
|
36
36
|
options.get({ get, find, json }, constant)
|
|
37
|
-
writeToCache(
|
|
37
|
+
writeToCache(innerTarget, readonlySelector, constant)
|
|
38
38
|
covered.clear()
|
|
39
39
|
return constant
|
|
40
40
|
}
|
|
@@ -43,9 +43,11 @@ export const createReadonlyHeldSelector = <T extends object>(
|
|
|
43
43
|
...options,
|
|
44
44
|
type,
|
|
45
45
|
subject,
|
|
46
|
+
getFrom,
|
|
46
47
|
install: (s: Store) => createReadonlyHeldSelector(s, options, family),
|
|
47
|
-
|
|
48
|
-
|
|
48
|
+
}
|
|
49
|
+
if (family) {
|
|
50
|
+
readonlySelector.family = family
|
|
49
51
|
}
|
|
50
52
|
target.readonlySelectors.set(key, readonlySelector)
|
|
51
53
|
store.logger.info(`✨`, type, key, `=`, constant)
|
|
@@ -11,18 +11,19 @@ import type { Store } from "../store"
|
|
|
11
11
|
import { Subject } from "../subject"
|
|
12
12
|
import { registerSelector } from "./register-selector"
|
|
13
13
|
|
|
14
|
-
export
|
|
14
|
+
export function createReadonlyPureSelector<T>(
|
|
15
15
|
store: Store,
|
|
16
16
|
options: ReadonlyPureSelectorOptions<T>,
|
|
17
17
|
family: FamilyMetadata | undefined,
|
|
18
|
-
): ReadonlyPureSelectorToken<T>
|
|
18
|
+
): ReadonlyPureSelectorToken<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
22
|
const key = options.key
|
|
23
23
|
const type = `readonly_pure_selector` as const
|
|
24
24
|
const { get, find, json } = registerSelector(target, type, key, covered)
|
|
25
|
-
|
|
25
|
+
|
|
26
|
+
const getFrom = () => {
|
|
26
27
|
const innerTarget = newest(store)
|
|
27
28
|
const upstreamStates = innerTarget.selectorGraph.getRelationEntries({
|
|
28
29
|
downstreamSelectorKey: key,
|
|
@@ -44,9 +45,11 @@ export const createReadonlyPureSelector = <T>(
|
|
|
44
45
|
...options,
|
|
45
46
|
type,
|
|
46
47
|
subject,
|
|
48
|
+
getFrom,
|
|
47
49
|
install: (s: Store) => createReadonlyPureSelector(s, options, family),
|
|
48
|
-
|
|
49
|
-
|
|
50
|
+
}
|
|
51
|
+
if (family) {
|
|
52
|
+
readonlySelector.family = family
|
|
50
53
|
}
|
|
51
54
|
target.readonlySelectors.set(key, readonlySelector)
|
|
52
55
|
const token: ReadonlyPureSelectorToken<T> = {
|
|
@@ -7,18 +7,15 @@ import type {
|
|
|
7
7
|
import type { WritableHeldSelector } from ".."
|
|
8
8
|
import { writeToCache } from "../caching"
|
|
9
9
|
import { newest } from "../lineage"
|
|
10
|
-
import { markDone } from "../operation"
|
|
11
|
-
import { become } from "../set-state"
|
|
12
10
|
import type { Store } from "../store"
|
|
13
11
|
import { Subject } from "../subject"
|
|
14
|
-
import { isRootStore } from "../transaction"
|
|
15
12
|
import { registerSelector } from "./register-selector"
|
|
16
13
|
|
|
17
|
-
export
|
|
14
|
+
export function createWritableHeldSelector<T extends object>(
|
|
18
15
|
store: Store,
|
|
19
16
|
options: WritableHeldSelectorOptions<T>,
|
|
20
17
|
family: FamilyMetadata | undefined,
|
|
21
|
-
): WritableHeldSelectorToken<T>
|
|
18
|
+
): WritableHeldSelectorToken<T> {
|
|
22
19
|
const target = newest(store)
|
|
23
20
|
const subject = new Subject<{ newValue: T; oldValue: T }>()
|
|
24
21
|
const covered = new Set<string>()
|
|
@@ -28,7 +25,7 @@ export const createWritableHeldSelector = <T extends object>(
|
|
|
28
25
|
const { find, get, json } = setterToolkit
|
|
29
26
|
const getterToolkit = { find, get, json }
|
|
30
27
|
|
|
31
|
-
const
|
|
28
|
+
const getFrom = (innerTarget: Store): T => {
|
|
32
29
|
const upstreamStates = innerTarget.selectorGraph.getRelationEntries({
|
|
33
30
|
downstreamSelectorKey: key,
|
|
34
31
|
})
|
|
@@ -38,33 +35,27 @@ export const createWritableHeldSelector = <T extends object>(
|
|
|
38
35
|
}
|
|
39
36
|
}
|
|
40
37
|
innerTarget.selectorAtoms.delete(key)
|
|
41
|
-
|
|
38
|
+
options.get(getterToolkit, constant)
|
|
42
39
|
writeToCache(innerTarget, mySelector, constant)
|
|
43
40
|
store.logger.info(`✨`, type, key, `=`, constant)
|
|
44
41
|
covered.clear()
|
|
45
42
|
return constant
|
|
46
43
|
}
|
|
47
44
|
|
|
48
|
-
const setSelf = (
|
|
49
|
-
|
|
50
|
-
const oldValue = getSelf(options.get, innerTarget)
|
|
51
|
-
const newValue = become(next)(oldValue)
|
|
52
|
-
store.logger.info(`📝`, type, key, `set (`, oldValue, `->`, newValue, `)`)
|
|
53
|
-
writeToCache(innerTarget, mySelector, newValue)
|
|
54
|
-
markDone(innerTarget, key)
|
|
55
|
-
if (isRootStore(innerTarget)) {
|
|
56
|
-
subject.next({ newValue, oldValue })
|
|
57
|
-
}
|
|
58
|
-
options.set(setterToolkit, newValue)
|
|
45
|
+
const setSelf = (): void => {
|
|
46
|
+
options.set(setterToolkit, constant)
|
|
59
47
|
}
|
|
48
|
+
|
|
60
49
|
const mySelector: WritableHeldSelector<T> = {
|
|
61
50
|
...options,
|
|
62
51
|
type,
|
|
63
52
|
subject,
|
|
53
|
+
getFrom,
|
|
54
|
+
setSelf,
|
|
64
55
|
install: (s: Store) => createWritableHeldSelector(s, options, family),
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
56
|
+
}
|
|
57
|
+
if (family) {
|
|
58
|
+
mySelector.family = family
|
|
68
59
|
}
|
|
69
60
|
target.writableSelectors.set(key, mySelector)
|
|
70
61
|
|