atom.io 0.12.1 → 0.14.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/index.cjs +9 -74
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +9 -6
- package/dist/index.d.ts +9 -6
- package/dist/index.js +11 -74
- package/dist/index.js.map +1 -1
- package/dist/metafile-cjs.json +1 -1
- package/dist/metafile-esm.json +1 -1
- package/internal/dist/index.cjs +1700 -1579
- package/internal/dist/index.cjs.map +1 -1
- package/internal/dist/index.d.cts +32 -15
- package/internal/dist/index.d.ts +32 -15
- package/internal/dist/index.js +1695 -1579
- package/internal/dist/index.js.map +1 -1
- package/internal/dist/metafile-cjs.json +1 -1
- package/internal/dist/metafile-esm.json +1 -1
- package/internal/src/atom/create-atom.ts +7 -6
- package/internal/src/atom/delete-atom.ts +11 -11
- package/internal/src/atom/is-default.ts +5 -5
- package/internal/src/caching.ts +12 -10
- package/internal/src/families/create-atom-family.ts +3 -3
- package/internal/src/families/create-readonly-selector-family.ts +3 -3
- package/internal/src/families/create-selector-family.ts +4 -4
- package/internal/src/index.ts +1 -0
- package/internal/src/keys.ts +4 -4
- package/internal/src/lazy-map.ts +6 -2
- package/internal/src/lineage.ts +18 -0
- package/internal/src/mutable/create-mutable-atom.ts +8 -6
- package/internal/src/mutable/get-json-family.ts +3 -3
- package/internal/src/mutable/tracker.ts +18 -13
- package/internal/src/operation.ts +19 -19
- package/internal/src/selector/create-read-write-selector.ts +5 -4
- package/internal/src/selector/create-readonly-selector.ts +4 -3
- package/internal/src/selector/create-selector.ts +6 -6
- package/internal/src/selector/delete-selector.ts +10 -10
- package/internal/src/selector/get-selector-dependency-keys.ts +2 -2
- package/internal/src/selector/register-selector.ts +4 -4
- package/internal/src/selector/update-selector-atoms.ts +4 -4
- package/internal/src/set-state/copy-mutable-if-needed.ts +4 -3
- package/internal/src/set-state/copy-mutable-in-transaction.ts +10 -16
- package/internal/src/set-state/copy-mutable-into-new-store.ts +1 -1
- package/internal/src/set-state/evict-downstream.ts +5 -5
- package/internal/src/set-state/set-atom.ts +6 -1
- package/internal/src/set-state/stow-update.ts +7 -2
- package/internal/src/store/store.ts +31 -24
- package/internal/src/store/withdraw-new-family-member.ts +3 -4
- package/internal/src/store/withdraw.ts +58 -59
- package/internal/src/subject.ts +14 -0
- package/internal/src/subscribe/index.ts +3 -0
- package/internal/src/subscribe/recall-state.ts +5 -11
- package/internal/src/subscribe/subscribe-to-state.ts +47 -0
- package/internal/src/subscribe/subscribe-to-timeline.ts +28 -0
- package/internal/src/subscribe/subscribe-to-transaction.ts +33 -0
- package/internal/src/timeline/add-atom-to-timeline.ts +37 -27
- package/internal/src/timeline/create-timeline.ts +6 -8
- package/internal/src/timeline/time-travel.ts +22 -4
- package/internal/src/transaction/abort-transaction.ts +5 -3
- package/internal/src/transaction/apply-transaction.ts +80 -58
- package/internal/src/transaction/build-transaction.ts +33 -23
- package/internal/src/transaction/create-transaction.ts +6 -9
- package/internal/src/transaction/index.ts +2 -10
- package/internal/src/transaction/redo-transaction.ts +15 -10
- package/internal/src/transaction/undo-transaction.ts +15 -16
- package/introspection/dist/index.cjs +2 -2
- package/introspection/dist/index.cjs.map +1 -1
- package/introspection/dist/index.js +3 -3
- package/introspection/dist/index.js.map +1 -1
- package/introspection/src/attach-atom-index.ts +2 -2
- package/introspection/src/attach-selector-index.ts +2 -2
- package/package.json +8 -8
- package/react/dist/index.cjs +39 -1
- package/react/dist/index.cjs.map +1 -1
- package/react/dist/index.d.cts +9 -2
- package/react/dist/index.d.ts +9 -2
- package/react/dist/index.js +41 -4
- package/react/dist/index.js.map +1 -1
- package/react/dist/metafile-cjs.json +1 -1
- package/react/dist/metafile-esm.json +1 -1
- package/react/src/store-hooks.ts +52 -3
- package/react-devtools/dist/index.cjs +22 -8
- package/react-devtools/dist/index.cjs.map +1 -1
- package/react-devtools/dist/index.d.cts +17 -9
- package/react-devtools/dist/index.d.ts +17 -9
- package/react-devtools/dist/index.js +22 -8
- package/react-devtools/dist/index.js.map +1 -1
- package/react-devtools/dist/metafile-cjs.json +1 -1
- package/react-devtools/dist/metafile-esm.json +1 -1
- package/react-devtools/src/Updates.tsx +22 -10
- package/realtime-client/dist/index.cjs +8 -7
- package/realtime-client/dist/index.cjs.map +1 -1
- package/realtime-client/dist/index.d.cts +3 -2
- package/realtime-client/dist/index.d.ts +3 -2
- package/realtime-client/dist/index.js +3 -2
- package/realtime-client/dist/index.js.map +1 -1
- package/realtime-client/dist/metafile-cjs.json +1 -1
- package/realtime-client/dist/metafile-esm.json +1 -1
- package/realtime-client/src/use-push.ts +4 -4
- package/realtime-client/src/use-server-action.ts +4 -4
- package/realtime-server/dist/index.cjs +46 -25
- package/realtime-server/dist/index.cjs.map +1 -1
- package/realtime-server/dist/index.d.cts +5 -5
- package/realtime-server/dist/index.d.ts +5 -5
- package/realtime-server/dist/index.js +38 -17
- package/realtime-server/dist/index.js.map +1 -1
- package/realtime-server/dist/metafile-cjs.json +1 -1
- package/realtime-server/dist/metafile-esm.json +1 -1
- package/realtime-server/src/hook-composition/expose-family.ts +7 -3
- package/realtime-server/src/hook-composition/expose-mutable-family.ts +13 -5
- package/realtime-server/src/hook-composition/expose-mutable.ts +11 -3
- package/realtime-server/src/hook-composition/expose-single.ts +6 -2
- package/realtime-server/src/hook-composition/receive-transaction.ts +14 -5
- package/src/subscribe.ts +37 -91
- package/src/transaction.ts +7 -2
- package/transceivers/set-rtx/dist/index.cjs.map +1 -1
- package/transceivers/set-rtx/dist/index.d.cts +2 -2
- package/transceivers/set-rtx/dist/index.d.ts +2 -2
- package/transceivers/set-rtx/dist/index.js.map +1 -1
- package/transceivers/set-rtx/dist/metafile-cjs.json +1 -1
- package/transceivers/set-rtx/dist/metafile-esm.json +1 -1
- package/transceivers/set-rtx/src/set-rtx.ts +3 -3
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
import type { TransactionUpdate, ƒn } from "atom.io"
|
|
1
2
|
import type { AtomToken, TimelineUpdate } from "atom.io"
|
|
2
3
|
|
|
4
|
+
import { newest } from "../lineage"
|
|
3
5
|
import type { Store } from "../store"
|
|
4
6
|
import { withdraw } from "../store"
|
|
5
|
-
import { target } from "../transaction"
|
|
6
7
|
import type {
|
|
7
8
|
Timeline,
|
|
8
9
|
TimelineAtomUpdate,
|
|
@@ -21,6 +22,7 @@ export const addAtomToTimeline = (
|
|
|
21
22
|
)
|
|
22
23
|
}
|
|
23
24
|
atom.subject.subscribe(`timeline`, (update) => {
|
|
25
|
+
const target = newest(store)
|
|
24
26
|
const currentSelectorKey =
|
|
25
27
|
store.operation.open && store.operation.token.type === `selector`
|
|
26
28
|
? store.operation.token.key
|
|
@@ -30,13 +32,8 @@ export const addAtomToTimeline = (
|
|
|
30
32
|
? store.operation.time
|
|
31
33
|
: null
|
|
32
34
|
const currentTransactionKey =
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
: null
|
|
36
|
-
const currentTransactionTime =
|
|
37
|
-
store.transactionStatus.phase === `applying`
|
|
38
|
-
? store.transactionStatus.time
|
|
39
|
-
: null
|
|
35
|
+
target.subject.transactionApplying.state?.update.key
|
|
36
|
+
const currentTransactionTime = target.subject.transactionApplying.state?.time
|
|
40
37
|
|
|
41
38
|
store.logger.info(
|
|
42
39
|
`⏳`,
|
|
@@ -54,7 +51,6 @@ export const addAtomToTimeline = (
|
|
|
54
51
|
? `in selector "${currentSelectorKey}"`
|
|
55
52
|
: ``,
|
|
56
53
|
)
|
|
57
|
-
|
|
58
54
|
if (tl.timeTraveling === null) {
|
|
59
55
|
if (tl.selectorTime && tl.selectorTime !== currentSelectorTime) {
|
|
60
56
|
const mostRecentUpdate: TimelineUpdate | undefined = tl.history.at(-1)
|
|
@@ -64,10 +60,7 @@ export const addAtomToTimeline = (
|
|
|
64
60
|
)
|
|
65
61
|
}
|
|
66
62
|
}
|
|
67
|
-
if (
|
|
68
|
-
currentTransactionKey &&
|
|
69
|
-
store.transactionStatus.phase === `applying`
|
|
70
|
-
) {
|
|
63
|
+
if (currentTransactionKey) {
|
|
71
64
|
const currentTransaction = withdraw(
|
|
72
65
|
{ key: currentTransactionKey, type: `transaction` },
|
|
73
66
|
store,
|
|
@@ -96,26 +89,43 @@ export const addAtomToTimeline = (
|
|
|
96
89
|
tl.history.splice(tl.at)
|
|
97
90
|
}
|
|
98
91
|
|
|
99
|
-
const
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
92
|
+
const filterUpdates = (
|
|
93
|
+
updates: TransactionUpdate<ƒn>[`updates`],
|
|
94
|
+
) =>
|
|
95
|
+
updates
|
|
96
|
+
.filter((updateFromTx) => {
|
|
97
|
+
const target = newest(store)
|
|
98
|
+
if (`updates` in updateFromTx) {
|
|
99
|
+
return true
|
|
100
|
+
}
|
|
101
|
+
const atomOrFamilyKeys =
|
|
102
|
+
target.timelineAtoms.getRelatedKeys(tl.key)
|
|
103
|
+
|
|
104
|
+
return atomOrFamilyKeys
|
|
105
|
+
? [...atomOrFamilyKeys].some(
|
|
106
|
+
(key) =>
|
|
107
|
+
key === updateFromTx.key ||
|
|
108
|
+
key === updateFromTx.family?.key,
|
|
109
|
+
)
|
|
110
|
+
: false
|
|
111
|
+
})
|
|
112
|
+
.map((updateFromTx) => {
|
|
113
|
+
if (`updates` in updateFromTx) {
|
|
114
|
+
return {
|
|
115
|
+
...updateFromTx,
|
|
116
|
+
updates: filterUpdates(updateFromTx.updates),
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
return updateFromTx
|
|
120
|
+
})
|
|
104
121
|
|
|
105
|
-
|
|
106
|
-
? [...atomOrFamilyKeys].some(
|
|
107
|
-
(key) =>
|
|
108
|
-
key === atomUpdate.key ||
|
|
109
|
-
key === atomUpdate.family?.key,
|
|
110
|
-
)
|
|
111
|
-
: false
|
|
112
|
-
})
|
|
122
|
+
const updates = filterUpdates(update.updates)
|
|
113
123
|
|
|
114
124
|
const timelineTransactionUpdate: TimelineTransactionUpdate = {
|
|
115
125
|
type: `transaction_update`,
|
|
116
126
|
timestamp: currentTransactionTime,
|
|
117
127
|
...update,
|
|
118
|
-
|
|
128
|
+
updates,
|
|
119
129
|
}
|
|
120
130
|
const willCapture =
|
|
121
131
|
tl.shouldCapture?.(timelineTransactionUpdate, tl) ?? true
|
|
@@ -8,9 +8,9 @@ import type {
|
|
|
8
8
|
ƒn,
|
|
9
9
|
} from "atom.io"
|
|
10
10
|
|
|
11
|
+
import { newest } from "../lineage"
|
|
11
12
|
import type { Store } from "../store"
|
|
12
13
|
import { Subject } from "../subject"
|
|
13
|
-
import { target } from "../transaction"
|
|
14
14
|
import { addAtomToTimeline } from "./add-atom-to-timeline"
|
|
15
15
|
|
|
16
16
|
export type TimelineAtomUpdate = StateUpdate<unknown> & {
|
|
@@ -71,9 +71,9 @@ export function createTimeline(
|
|
|
71
71
|
tl.shouldCapture = options.shouldCapture
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
-
const
|
|
74
|
+
const target = newest(store)
|
|
75
75
|
for (const tokenOrFamily of options.atoms) {
|
|
76
|
-
const timelineKey =
|
|
76
|
+
const timelineKey = target.timelineAtoms.getRelatedKey(tokenOrFamily.key)
|
|
77
77
|
if (timelineKey) {
|
|
78
78
|
store.logger.error(
|
|
79
79
|
`❌`,
|
|
@@ -86,11 +86,9 @@ export function createTimeline(
|
|
|
86
86
|
if (tokenOrFamily.type === `atom_family`) {
|
|
87
87
|
const family = tokenOrFamily
|
|
88
88
|
family.subject.subscribe(`timeline:${options.key}`, (token) => {
|
|
89
|
-
// if (!core.atoms.has(token.key)) {
|
|
90
89
|
addAtomToTimeline(token, tl, store)
|
|
91
|
-
// }
|
|
92
90
|
})
|
|
93
|
-
for (const atom of
|
|
91
|
+
for (const atom of target.atoms.values()) {
|
|
94
92
|
if (atom.family?.key === family.key) {
|
|
95
93
|
addAtomToTimeline(atom, tl, store)
|
|
96
94
|
}
|
|
@@ -98,7 +96,7 @@ export function createTimeline(
|
|
|
98
96
|
} else {
|
|
99
97
|
const token = tokenOrFamily
|
|
100
98
|
if (`family` in token && token.family) {
|
|
101
|
-
const familyTimelineKey =
|
|
99
|
+
const familyTimelineKey = target.timelineAtoms.getRelatedKey(
|
|
102
100
|
token.family.key,
|
|
103
101
|
)
|
|
104
102
|
if (familyTimelineKey) {
|
|
@@ -113,7 +111,7 @@ export function createTimeline(
|
|
|
113
111
|
}
|
|
114
112
|
addAtomToTimeline(token, tl, store)
|
|
115
113
|
}
|
|
116
|
-
|
|
114
|
+
target.timelineAtoms = target.timelineAtoms.set({
|
|
117
115
|
atomKey: tokenOrFamily.key,
|
|
118
116
|
timelineKey: options.key,
|
|
119
117
|
})
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { TimelineToken } from "atom.io"
|
|
1
|
+
import type { KeyedStateUpdate, TimelineToken, TransactionUpdate } from "atom.io"
|
|
2
2
|
import { setState } from "atom.io"
|
|
3
3
|
|
|
4
4
|
import type { Store } from "../store"
|
|
@@ -50,19 +50,33 @@ export const timeTravel = (
|
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
const update = timelineData.history[timelineData.at]
|
|
53
|
-
const updateValues = (atomUpdate: any) => {
|
|
53
|
+
const updateValues = (atomUpdate: KeyedStateUpdate<any>) => {
|
|
54
54
|
const { key, newValue, oldValue } = atomUpdate
|
|
55
55
|
const value = direction === `forward` ? newValue : oldValue
|
|
56
56
|
setState({ key, type: `atom` }, value, store)
|
|
57
57
|
}
|
|
58
|
+
const updateValuesFromTransactionUpdate = (
|
|
59
|
+
transactionUpdate: TransactionUpdate<any>,
|
|
60
|
+
) => {
|
|
61
|
+
const updates =
|
|
62
|
+
direction === `forward`
|
|
63
|
+
? transactionUpdate.updates
|
|
64
|
+
: [...transactionUpdate.updates].reverse()
|
|
65
|
+
for (const updateFromTransaction of updates) {
|
|
66
|
+
if (`newValue` in updateFromTransaction) {
|
|
67
|
+
updateValues(updateFromTransaction)
|
|
68
|
+
} else {
|
|
69
|
+
updateValuesFromTransactionUpdate(updateFromTransaction)
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
58
73
|
|
|
59
74
|
switch (update.type) {
|
|
60
75
|
case `atom_update`: {
|
|
61
76
|
updateValues(update)
|
|
62
77
|
break
|
|
63
78
|
}
|
|
64
|
-
case `selector_update`:
|
|
65
|
-
case `transaction_update`: {
|
|
79
|
+
case `selector_update`: {
|
|
66
80
|
const updates =
|
|
67
81
|
direction === `forward`
|
|
68
82
|
? update.atomUpdates
|
|
@@ -72,6 +86,10 @@ export const timeTravel = (
|
|
|
72
86
|
}
|
|
73
87
|
break
|
|
74
88
|
}
|
|
89
|
+
case `transaction_update`: {
|
|
90
|
+
updateValuesFromTransactionUpdate(update)
|
|
91
|
+
break
|
|
92
|
+
}
|
|
75
93
|
}
|
|
76
94
|
|
|
77
95
|
if (direction === `forward`) {
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
import { newest } from "../lineage"
|
|
1
2
|
import type { Store } from "../store"
|
|
2
3
|
|
|
3
4
|
export const abortTransaction = (store: Store): void => {
|
|
4
|
-
|
|
5
|
+
const target = newest(store)
|
|
6
|
+
if (target.transactionMeta === null || target.parent === null) {
|
|
5
7
|
store.logger.warn(
|
|
6
8
|
`🐞`,
|
|
7
9
|
`transaction`,
|
|
@@ -13,8 +15,8 @@ export const abortTransaction = (store: Store): void => {
|
|
|
13
15
|
store.logger.info(
|
|
14
16
|
`🪂`,
|
|
15
17
|
`transaction`,
|
|
16
|
-
|
|
18
|
+
target.transactionMeta.update.key,
|
|
17
19
|
`Aborting transaction`,
|
|
18
20
|
)
|
|
19
|
-
|
|
21
|
+
target.parent.child = null
|
|
20
22
|
}
|
|
@@ -1,14 +1,67 @@
|
|
|
1
|
-
import type { AtomToken, ƒn } from "atom.io"
|
|
2
|
-
import { setState
|
|
1
|
+
import type { AtomToken, KeyedStateUpdate, TransactionUpdate, ƒn } from "atom.io"
|
|
2
|
+
import { setState } from "atom.io"
|
|
3
3
|
|
|
4
|
+
import { newest } from "../lineage"
|
|
4
5
|
import { withdraw } from "../store"
|
|
5
6
|
import type { Store } from "../store"
|
|
6
7
|
|
|
8
|
+
function ingestAtomUpdate(
|
|
9
|
+
update: KeyedStateUpdate<any>,
|
|
10
|
+
parent: Store,
|
|
11
|
+
child: Store,
|
|
12
|
+
): void {
|
|
13
|
+
const { key, newValue } = update
|
|
14
|
+
const token: AtomToken<unknown> = { key, type: `atom` }
|
|
15
|
+
if (!parent.valueMap.has(token.key)) {
|
|
16
|
+
if (token.family) {
|
|
17
|
+
const family = parent.families.get(token.family.key)
|
|
18
|
+
if (family) {
|
|
19
|
+
family(token.family.subKey)
|
|
20
|
+
}
|
|
21
|
+
} else {
|
|
22
|
+
const newAtom = child.atoms.get(token.key)
|
|
23
|
+
if (!newAtom) {
|
|
24
|
+
throw new Error(
|
|
25
|
+
`Absurd Error: Atom "${token.key}" not found while copying updates from transaction "${child.transactionMeta?.update.key}" to store "${parent.config.name}"`,
|
|
26
|
+
)
|
|
27
|
+
}
|
|
28
|
+
parent.atoms.set(newAtom.key, newAtom)
|
|
29
|
+
parent.valueMap.set(newAtom.key, newAtom.default)
|
|
30
|
+
parent.logger.info(
|
|
31
|
+
`🔨`,
|
|
32
|
+
`transaction`,
|
|
33
|
+
child.transactionMeta?.update.key ?? `???`,
|
|
34
|
+
`Adding atom "${newAtom.key}"`,
|
|
35
|
+
)
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
setState(token, newValue, parent)
|
|
39
|
+
}
|
|
40
|
+
function ingestTransactionUpdate(
|
|
41
|
+
transactionUpdate: TransactionUpdate<any>,
|
|
42
|
+
parent: Store,
|
|
43
|
+
child: Store,
|
|
44
|
+
): void {
|
|
45
|
+
for (const update of transactionUpdate.updates) {
|
|
46
|
+
if (`newValue` in update) {
|
|
47
|
+
ingestAtomUpdate(update, parent, child)
|
|
48
|
+
} else {
|
|
49
|
+
ingestTransactionUpdate(update, parent, child)
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
7
54
|
export const applyTransaction = <ƒ extends ƒn>(
|
|
8
55
|
output: ReturnType<ƒ>,
|
|
9
56
|
store: Store,
|
|
10
57
|
): void => {
|
|
11
|
-
|
|
58
|
+
const child = newest(store)
|
|
59
|
+
const { parent } = child
|
|
60
|
+
if (
|
|
61
|
+
parent === null ||
|
|
62
|
+
child.transactionMeta === null ||
|
|
63
|
+
child.transactionMeta?.phase !== `building`
|
|
64
|
+
) {
|
|
12
65
|
store.logger.warn(
|
|
13
66
|
`🐞`,
|
|
14
67
|
`transaction`,
|
|
@@ -17,65 +70,34 @@ export const applyTransaction = <ƒ extends ƒn>(
|
|
|
17
70
|
)
|
|
18
71
|
return
|
|
19
72
|
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
73
|
+
child.transactionMeta.phase = `applying`
|
|
74
|
+
child.transactionMeta.update.output = output
|
|
75
|
+
parent.child = null
|
|
76
|
+
parent.subject.transactionApplying.next(child.transactionMeta)
|
|
77
|
+
const { updates } = child.transactionMeta.update
|
|
23
78
|
store.logger.info(
|
|
24
79
|
`🛄`,
|
|
25
80
|
`transaction`,
|
|
26
|
-
|
|
27
|
-
`Applying transaction with ${
|
|
28
|
-
|
|
81
|
+
child.transactionMeta.update.key,
|
|
82
|
+
`Applying transaction with ${updates.length} updates:`,
|
|
83
|
+
updates,
|
|
29
84
|
)
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
const family = store.families.get(token.family.key)
|
|
36
|
-
if (family) {
|
|
37
|
-
family(token.family.subKey)
|
|
38
|
-
}
|
|
39
|
-
} else {
|
|
40
|
-
const newAtom = store.transactionStatus.core.atoms.get(token.key)
|
|
41
|
-
if (!newAtom) {
|
|
42
|
-
throw new Error(
|
|
43
|
-
`Absurd Error: Atom "${token.key}" not found while copying updates from transaction "${store.transactionStatus.key}" to store "${store.config.name}"`,
|
|
44
|
-
)
|
|
45
|
-
}
|
|
46
|
-
store.atoms.set(newAtom.key, newAtom)
|
|
47
|
-
store.valueMap.set(newAtom.key, newAtom.default)
|
|
48
|
-
store.logger.info(
|
|
49
|
-
`🔨`,
|
|
50
|
-
`transaction`,
|
|
51
|
-
store.transactionStatus.key,
|
|
52
|
-
`Adding atom "${newAtom.key}"`,
|
|
53
|
-
)
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
// if (store.transactionStatus.key === `dealCards`) debugger
|
|
57
|
-
setState(token, newValue, store)
|
|
58
|
-
}
|
|
59
|
-
const myTransaction = withdraw<ƒ>(
|
|
60
|
-
{ key: store.transactionStatus.key, type: `transaction` },
|
|
61
|
-
store,
|
|
62
|
-
)
|
|
63
|
-
if (myTransaction === undefined) {
|
|
64
|
-
throw new Error(
|
|
65
|
-
`Transaction "${store.transactionStatus.key}" not found. Absurd. How is this running?`,
|
|
85
|
+
if (parent.transactionMeta === null) {
|
|
86
|
+
ingestTransactionUpdate(child.transactionMeta.update, parent, child)
|
|
87
|
+
const myTransaction = withdraw<ƒ>(
|
|
88
|
+
{ key: child.transactionMeta.update.key, type: `transaction` },
|
|
89
|
+
store,
|
|
66
90
|
)
|
|
91
|
+
myTransaction?.subject.next(child.transactionMeta.update)
|
|
92
|
+
store.logger.info(
|
|
93
|
+
`🛬`,
|
|
94
|
+
`transaction`,
|
|
95
|
+
child.transactionMeta.update.key,
|
|
96
|
+
`Finished applying transaction.`,
|
|
97
|
+
)
|
|
98
|
+
} else {
|
|
99
|
+
ingestTransactionUpdate(child.transactionMeta.update, parent, child)
|
|
100
|
+
parent.transactionMeta.update.updates.push(child.transactionMeta.update)
|
|
67
101
|
}
|
|
68
|
-
|
|
69
|
-
key: store.transactionStatus.key,
|
|
70
|
-
atomUpdates,
|
|
71
|
-
output,
|
|
72
|
-
params: store.transactionStatus.params as Parameters<ƒ>,
|
|
73
|
-
})
|
|
74
|
-
store.logger.info(
|
|
75
|
-
`🛬`,
|
|
76
|
-
`transaction`,
|
|
77
|
-
store.transactionStatus.key,
|
|
78
|
-
`Finished applying transaction.`,
|
|
79
|
-
)
|
|
80
|
-
store.transactionStatus = { phase: `idle` }
|
|
102
|
+
parent.subject.transactionApplying.next(null)
|
|
81
103
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Junction } from "~/packages/rel8/junction/src"
|
|
2
2
|
|
|
3
3
|
import { LazyMap } from "../lazy-map"
|
|
4
|
+
import { newest } from "../lineage"
|
|
4
5
|
import type { Store } from "../store"
|
|
5
6
|
|
|
6
7
|
export const buildTransaction = (
|
|
@@ -8,30 +9,39 @@ export const buildTransaction = (
|
|
|
8
9
|
params: any[],
|
|
9
10
|
store: Store,
|
|
10
11
|
): void => {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
}),
|
|
29
|
-
selectors: new LazyMap(store.selectors),
|
|
30
|
-
valueMap: new LazyMap(store.valueMap),
|
|
12
|
+
const parent = newest(store)
|
|
13
|
+
parent.child = {
|
|
14
|
+
parent,
|
|
15
|
+
child: null,
|
|
16
|
+
subject: parent.subject,
|
|
17
|
+
loggers: parent.loggers,
|
|
18
|
+
logger: parent.logger,
|
|
19
|
+
config: parent.config,
|
|
20
|
+
transactionMeta: {
|
|
21
|
+
phase: `building`,
|
|
22
|
+
time: Date.now(),
|
|
23
|
+
update: {
|
|
24
|
+
key,
|
|
25
|
+
updates: [],
|
|
26
|
+
params,
|
|
27
|
+
output: undefined,
|
|
28
|
+
},
|
|
31
29
|
},
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
30
|
+
atoms: new LazyMap(parent.atoms),
|
|
31
|
+
atomsThatAreDefault: new Set(parent.atomsThatAreDefault),
|
|
32
|
+
families: new LazyMap(parent.families),
|
|
33
|
+
operation: { open: false },
|
|
34
|
+
readonlySelectors: new LazyMap(parent.readonlySelectors),
|
|
35
|
+
timelines: new LazyMap(parent.timelines),
|
|
36
|
+
timelineAtoms: new Junction(parent.timelineAtoms.toJSON()),
|
|
37
|
+
trackers: new Map(),
|
|
38
|
+
transactions: new LazyMap(parent.transactions),
|
|
39
|
+
selectorAtoms: new Junction(parent.selectorAtoms.toJSON()),
|
|
40
|
+
selectorGraph: new Junction(parent.selectorGraph.toJSON(), {
|
|
41
|
+
makeContentKey: (...keys) => keys.sort().join(`:`),
|
|
42
|
+
}),
|
|
43
|
+
selectors: new LazyMap(parent.selectors),
|
|
44
|
+
valueMap: new LazyMap(parent.valueMap),
|
|
35
45
|
}
|
|
36
46
|
store.logger.info(
|
|
37
47
|
`🛫`,
|
|
@@ -4,10 +4,11 @@ import type {
|
|
|
4
4
|
TransactionUpdate,
|
|
5
5
|
ƒn,
|
|
6
6
|
} from "atom.io"
|
|
7
|
-
import { getState, setState } from "atom.io"
|
|
7
|
+
import { getState, runTransaction, setState } from "atom.io"
|
|
8
8
|
|
|
9
|
+
import { newest } from "../lineage"
|
|
9
10
|
import { deposit } from "../store"
|
|
10
|
-
import type { Store
|
|
11
|
+
import type { Store } from "../store"
|
|
11
12
|
import { Subject } from "../subject"
|
|
12
13
|
import { abortTransaction } from "./abort-transaction"
|
|
13
14
|
import { applyTransaction } from "./apply-transaction"
|
|
@@ -35,6 +36,7 @@ export function createTransaction<ƒ extends ƒn>(
|
|
|
35
36
|
{
|
|
36
37
|
get: (token) => getState(token, store),
|
|
37
38
|
set: (token, value) => setState(token, value, store),
|
|
39
|
+
run: (token) => runTransaction(token, store),
|
|
38
40
|
},
|
|
39
41
|
...params,
|
|
40
42
|
)
|
|
@@ -49,14 +51,9 @@ export function createTransaction<ƒ extends ƒn>(
|
|
|
49
51
|
install: (store) => createTransaction(options, store),
|
|
50
52
|
subject: new Subject(),
|
|
51
53
|
}
|
|
52
|
-
const
|
|
53
|
-
|
|
54
|
+
const target = newest(store)
|
|
55
|
+
target.transactions.set(newTransaction.key, newTransaction)
|
|
54
56
|
const token = deposit(newTransaction)
|
|
55
57
|
store.subject.transactionCreation.next(token)
|
|
56
58
|
return token
|
|
57
59
|
}
|
|
58
|
-
|
|
59
|
-
export const target = (store: Store): StoreCore =>
|
|
60
|
-
store.transactionStatus.phase === `building`
|
|
61
|
-
? store.transactionStatus.core
|
|
62
|
-
: store
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import type { TransactionUpdate, ƒn } from "atom.io"
|
|
2
2
|
|
|
3
|
-
import type { StoreCore } from ".."
|
|
4
|
-
|
|
5
3
|
export * from "./abort-transaction"
|
|
6
4
|
export * from "./apply-transaction"
|
|
7
5
|
export * from "./build-transaction"
|
|
@@ -12,14 +10,8 @@ export * from "./undo-transaction"
|
|
|
12
10
|
export const TRANSACTION_PHASES = [`idle`, `building`, `applying`] as const
|
|
13
11
|
export type TransactionPhase = (typeof TRANSACTION_PHASES)[number]
|
|
14
12
|
|
|
15
|
-
export type
|
|
13
|
+
export type TransactionMeta<ƒ extends ƒn> = {
|
|
16
14
|
phase: `applying` | `building`
|
|
17
15
|
time: number
|
|
18
|
-
|
|
19
|
-
}
|
|
20
|
-
export type TransactionIdle = {
|
|
21
|
-
phase: `idle`
|
|
16
|
+
update: TransactionUpdate<ƒ>
|
|
22
17
|
}
|
|
23
|
-
export type TransactionStatus<ƒ extends ƒn> =
|
|
24
|
-
| TransactionIdle
|
|
25
|
-
| TransactionUpdateInProgress<ƒ>
|
|
@@ -5,18 +5,23 @@ import { withdraw } from "../store"
|
|
|
5
5
|
import type { Store } from "../store"
|
|
6
6
|
|
|
7
7
|
export const redoTransactionUpdate = <ƒ extends ƒn>(
|
|
8
|
-
|
|
8
|
+
transactionUpdate: TransactionUpdate<ƒ>,
|
|
9
9
|
store: Store,
|
|
10
10
|
): void => {
|
|
11
|
-
store.logger.info(`⏭️`, `transaction`,
|
|
12
|
-
for (const
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
11
|
+
store.logger.info(`⏭️`, `transaction`, transactionUpdate.key, `Redo`)
|
|
12
|
+
for (const update of transactionUpdate.updates) {
|
|
13
|
+
if (`newValue` in update) {
|
|
14
|
+
const { key, newValue } = update
|
|
15
|
+
const token: AtomToken<unknown> = { key, type: `atom` }
|
|
16
|
+
const state = withdraw(token, store)
|
|
17
|
+
if (state === undefined) {
|
|
18
|
+
throw new Error(
|
|
19
|
+
`State "${token.key}" not found in this store. This is surprising, because we are navigating the history of the store.`,
|
|
20
|
+
)
|
|
21
|
+
}
|
|
22
|
+
setState(state, newValue, store)
|
|
23
|
+
} else {
|
|
24
|
+
redoTransactionUpdate(update, store)
|
|
19
25
|
}
|
|
20
|
-
setState(state, newValue, store)
|
|
21
26
|
}
|
|
22
27
|
}
|
|
@@ -5,24 +5,23 @@ import { withdraw } from "../store"
|
|
|
5
5
|
import type { Store } from "../store"
|
|
6
6
|
|
|
7
7
|
export const undoTransactionUpdate = <ƒ extends ƒn>(
|
|
8
|
-
|
|
8
|
+
transactionUpdate: TransactionUpdate<ƒ>,
|
|
9
9
|
store: Store,
|
|
10
10
|
): void => {
|
|
11
|
-
store.logger.info(
|
|
12
|
-
|
|
13
|
-
`
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
)
|
|
11
|
+
store.logger.info(`⏮️`, `transaction`, transactionUpdate.key, `Undo`)
|
|
12
|
+
for (const update of transactionUpdate.updates.reverse()) {
|
|
13
|
+
if (`newValue` in update) {
|
|
14
|
+
const { key, newValue } = update
|
|
15
|
+
const token: AtomToken<unknown> = { key, type: `atom` }
|
|
16
|
+
const state = withdraw(token, store)
|
|
17
|
+
if (state === undefined) {
|
|
18
|
+
throw new Error(
|
|
19
|
+
`State "${token.key}" not found in this store. This is surprising, because we are navigating the history of the store.`,
|
|
20
|
+
)
|
|
21
|
+
}
|
|
22
|
+
setState(state, newValue, store)
|
|
23
|
+
} else {
|
|
24
|
+
undoTransactionUpdate(update, store)
|
|
25
25
|
}
|
|
26
|
-
setState(state, oldValue, store)
|
|
27
26
|
}
|
|
28
27
|
}
|
|
@@ -81,7 +81,7 @@ var attachAtomIndex = (store = Internal.IMPLICIT.STORE) => {
|
|
|
81
81
|
[key]: atomToken
|
|
82
82
|
});
|
|
83
83
|
});
|
|
84
|
-
if (Internal.
|
|
84
|
+
if (Internal.newest(store).operation.open) {
|
|
85
85
|
const unsubscribe = store.subject.operationStatus.subscribe(
|
|
86
86
|
`introspection: waiting to update atom index`,
|
|
87
87
|
() => {
|
|
@@ -153,7 +153,7 @@ var attachSelectorIndex = (store = Internal.IMPLICIT.STORE) => {
|
|
|
153
153
|
[key]: selectorToken
|
|
154
154
|
});
|
|
155
155
|
});
|
|
156
|
-
if (Internal.
|
|
156
|
+
if (Internal.newest(store).operation.open) {
|
|
157
157
|
const unsubscribe = store.subject.operationStatus.subscribe(
|
|
158
158
|
`introspection: waiting to update selector index`,
|
|
159
159
|
() => {
|