atom.io 0.6.2 → 0.6.3

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.
Files changed (110) hide show
  1. package/dist/index.d.mts +2 -2
  2. package/dist/index.d.ts +2 -2
  3. package/dist/index.js +7 -2
  4. package/dist/index.js.map +1 -1
  5. package/dist/index.mjs +7 -2
  6. package/dist/index.mjs.map +1 -1
  7. package/json/dist/index.d.mts +18 -0
  8. package/json/dist/index.d.ts +18 -0
  9. package/json/dist/index.js +51 -0
  10. package/json/dist/index.js.map +1 -0
  11. package/json/dist/index.mjs +15 -0
  12. package/json/dist/index.mjs.map +1 -0
  13. package/package.json +13 -3
  14. package/react/dist/index.d.mts +24 -0
  15. package/react/dist/index.d.ts +24 -0
  16. package/react/dist/index.js +83 -0
  17. package/react/dist/index.js.map +1 -0
  18. package/react/dist/index.mjs +41 -0
  19. package/react/dist/index.mjs.map +1 -0
  20. package/react-devtools/dist/index.css +26 -0
  21. package/react-devtools/dist/index.css.map +1 -0
  22. package/react-devtools/dist/index.d.mts +15 -0
  23. package/react-devtools/dist/index.d.ts +15 -0
  24. package/react-devtools/dist/index.js +1596 -0
  25. package/react-devtools/dist/index.js.map +1 -0
  26. package/react-devtools/dist/index.mjs +1568 -0
  27. package/react-devtools/dist/index.mjs.map +1 -0
  28. package/realtime/dist/index.d.mts +27 -0
  29. package/realtime/dist/index.d.ts +27 -0
  30. package/realtime/dist/index.js +191 -0
  31. package/realtime/dist/index.js.map +1 -0
  32. package/realtime/dist/index.mjs +152 -0
  33. package/realtime/dist/index.mjs.map +1 -0
  34. package/realtime-react/dist/index.d.mts +45 -0
  35. package/realtime-react/dist/index.d.ts +45 -0
  36. package/realtime-react/dist/index.js +213 -0
  37. package/realtime-react/dist/index.js.map +1 -0
  38. package/realtime-react/dist/index.mjs +168 -0
  39. package/realtime-react/dist/index.mjs.map +1 -0
  40. package/realtime-testing/dist/index.d.mts +49 -0
  41. package/realtime-testing/dist/index.d.ts +49 -0
  42. package/realtime-testing/dist/index.js +153 -0
  43. package/realtime-testing/dist/index.js.map +1 -0
  44. package/realtime-testing/dist/index.mjs +117 -0
  45. package/realtime-testing/dist/index.mjs.map +1 -0
  46. package/realtime-testing/package.json +15 -0
  47. package/src/atom.ts +15 -15
  48. package/src/index.ts +59 -59
  49. package/src/internal/atom-internal.ts +36 -36
  50. package/src/internal/families-internal.ts +114 -114
  51. package/src/internal/get.ts +83 -83
  52. package/src/internal/is-default.ts +17 -17
  53. package/src/internal/meta/attach-meta.ts +7 -7
  54. package/src/internal/meta/meta-state.ts +115 -115
  55. package/src/internal/operation.ts +93 -93
  56. package/src/internal/selector/create-read-write-selector.ts +46 -46
  57. package/src/internal/selector/create-readonly-selector.ts +37 -37
  58. package/src/internal/selector/lookup-selector-sources.ts +9 -9
  59. package/src/internal/selector/register-selector.ts +44 -44
  60. package/src/internal/selector/trace-selector-atoms.ts +30 -30
  61. package/src/internal/selector/update-selector-atoms.ts +25 -25
  62. package/src/internal/selector-internal.ts +37 -37
  63. package/src/internal/set.ts +78 -78
  64. package/src/internal/store.ts +118 -118
  65. package/src/internal/subscribe-internal.ts +62 -62
  66. package/src/internal/time-travel-internal.ts +76 -76
  67. package/src/internal/timeline/add-atom-to-timeline.ts +158 -153
  68. package/src/internal/timeline-internal.ts +80 -80
  69. package/src/internal/transaction/abort-transaction.ts +8 -8
  70. package/src/internal/transaction/apply-transaction.ts +41 -41
  71. package/src/internal/transaction/build-transaction.ts +28 -28
  72. package/src/internal/transaction/index.ts +7 -7
  73. package/src/internal/transaction/redo-transaction.ts +13 -13
  74. package/src/internal/transaction/undo-transaction.ts +13 -13
  75. package/src/internal/transaction-internal.ts +48 -48
  76. package/src/json/select-json.ts +12 -12
  77. package/src/logger.ts +30 -30
  78. package/src/react/store-context.tsx +4 -4
  79. package/src/react/store-hooks.ts +18 -18
  80. package/src/react-devtools/AtomIODevtools.tsx +83 -82
  81. package/src/react-devtools/StateEditor.tsx +53 -53
  82. package/src/react-devtools/TokenList.tsx +47 -42
  83. package/src/react-explorer/AtomIOExplorer.tsx +197 -185
  84. package/src/react-explorer/explorer-effects.ts +11 -11
  85. package/src/react-explorer/explorer-states.ts +186 -193
  86. package/src/react-explorer/index.ts +11 -11
  87. package/src/react-explorer/space-states.ts +48 -50
  88. package/src/react-explorer/view-states.ts +25 -25
  89. package/src/realtime/hook-composition/expose-family.ts +81 -81
  90. package/src/realtime/hook-composition/expose-single.ts +26 -26
  91. package/src/realtime/hook-composition/expose-timeline.ts +60 -0
  92. package/src/realtime/hook-composition/index.ts +2 -2
  93. package/src/realtime/hook-composition/receive-state.ts +18 -18
  94. package/src/realtime/hook-composition/receive-transaction.ts +8 -8
  95. package/src/realtime-react/realtime-context.tsx +17 -17
  96. package/src/realtime-react/realtime-hooks.ts +17 -17
  97. package/src/realtime-react/realtime-state.ts +4 -4
  98. package/src/realtime-react/use-pull-family-member.ts +15 -15
  99. package/src/realtime-react/use-pull-family.ts +13 -13
  100. package/src/realtime-react/use-pull.ts +12 -12
  101. package/src/realtime-react/use-push.ts +15 -15
  102. package/src/realtime-react/use-server-action.ts +21 -21
  103. package/src/realtime-testing/index.ts +1 -0
  104. package/src/realtime-testing/setup-realtime-test.tsx +160 -0
  105. package/src/selector.ts +25 -25
  106. package/src/silo.ts +38 -38
  107. package/src/subscribe.ts +68 -68
  108. package/src/timeline.ts +13 -13
  109. package/src/transaction.ts +28 -28
  110. package/src/web-effects/storage.ts +17 -17
@@ -7,147 +7,147 @@ import { doNothing } from "~/packages/anvl/src/function"
7
7
  import { Join } from "~/packages/anvl/src/join"
8
8
 
9
9
  import type {
10
- Atom,
11
- OperationProgress,
12
- ReadonlySelector,
13
- Selector,
14
- TransactionStatus,
15
- Timeline,
16
- Transaction,
10
+ Atom,
11
+ OperationProgress,
12
+ ReadonlySelector,
13
+ Selector,
14
+ TransactionStatus,
15
+ Timeline,
16
+ Transaction,
17
17
  } from "."
18
18
  import type {
19
- AtomToken,
20
- Logger,
21
- ReadonlySelectorToken,
22
- SelectorToken,
23
- TimelineToken,
24
- TransactionToken,
19
+ AtomToken,
20
+ Logger,
21
+ ReadonlySelectorToken,
22
+ SelectorToken,
23
+ TimelineToken,
24
+ TransactionToken,
25
25
  } from ".."
26
26
 
27
27
  export type StoreCore = Pick<
28
- Store,
29
- | `atoms`
30
- | `atomsThatAreDefault`
31
- | `operation`
32
- | `readonlySelectors`
33
- | `selectorAtoms`
34
- | `selectorGraph`
35
- | `selectors`
36
- | `timelineAtoms`
37
- | `timelines`
38
- | `transactions`
39
- | `valueMap`
28
+ Store,
29
+ | `atoms`
30
+ | `atomsThatAreDefault`
31
+ | `operation`
32
+ | `readonlySelectors`
33
+ | `selectorAtoms`
34
+ | `selectorGraph`
35
+ | `selectors`
36
+ | `timelineAtoms`
37
+ | `timelines`
38
+ | `transactions`
39
+ | `valueMap`
40
40
  >
41
41
 
42
42
  export interface Store {
43
- atoms: Hamt<Atom<any>, string>
44
- atomsThatAreDefault: Set<string>
45
- readonlySelectors: Hamt<ReadonlySelector<any>, string>
46
- selectorAtoms: Join<null, `selectorKey`, `atomKey`>
47
- selectorGraph: Join<{ source: string }>
48
- selectors: Hamt<Selector<any>, string>
49
- timelineAtoms: Join<null, `timelineKey`, `atomKey`>
50
- timelines: Hamt<Timeline, string>
51
- transactions: Hamt<Transaction<any>, string>
52
- valueMap: Hamt<any, string>
43
+ atoms: Hamt<Atom<any>, string>
44
+ atomsThatAreDefault: Set<string>
45
+ readonlySelectors: Hamt<ReadonlySelector<any>, string>
46
+ selectorAtoms: Join<null, `selectorKey`, `atomKey`>
47
+ selectorGraph: Join<{ source: string }>
48
+ selectors: Hamt<Selector<any>, string>
49
+ timelineAtoms: Join<null, `timelineKey`, `atomKey`>
50
+ timelines: Hamt<Timeline, string>
51
+ transactions: Hamt<Transaction<any>, string>
52
+ valueMap: Hamt<any, string>
53
53
 
54
- subject: {
55
- atomCreation: Rx.Subject<AtomToken<unknown>>
56
- selectorCreation: Rx.Subject<
57
- ReadonlySelectorToken<unknown> | SelectorToken<unknown>
58
- >
59
- transactionCreation: Rx.Subject<TransactionToken<unknown>>
60
- timelineCreation: Rx.Subject<TimelineToken>
61
- }
54
+ subject: {
55
+ atomCreation: Rx.Subject<AtomToken<unknown>>
56
+ selectorCreation: Rx.Subject<
57
+ ReadonlySelectorToken<unknown> | SelectorToken<unknown>
58
+ >
59
+ transactionCreation: Rx.Subject<TransactionToken<unknown>>
60
+ timelineCreation: Rx.Subject<TimelineToken>
61
+ }
62
62
 
63
- operation: OperationProgress
64
- transactionStatus: TransactionStatus<ƒn>
65
- config: {
66
- name: string
67
- logger: Logger | null
68
- logger__INTERNAL: Logger
69
- }
63
+ operation: OperationProgress
64
+ transactionStatus: TransactionStatus<ƒn>
65
+ config: {
66
+ name: string
67
+ logger: Logger | null
68
+ logger__INTERNAL: Logger
69
+ }
70
70
  }
71
71
 
72
72
  export const createStore = (name: string, store: Store | null = null): Store => {
73
- const copiedStore = {
74
- ...(store ??
75
- (() => ({
76
- atomsThatAreDefault: new Set(),
77
- selectorAtoms: new Join({ relationType: `n:n` })
78
- .from(`selectorKey`)
79
- .to(`atomKey`),
80
- selectorGraph: new Join({ relationType: `n:n` }),
81
- valueMap: HAMT.make<any, string>(),
82
- }))()),
73
+ const copiedStore = {
74
+ ...(store ??
75
+ (() => ({
76
+ atomsThatAreDefault: new Set(),
77
+ selectorAtoms: new Join({ relationType: `n:n` })
78
+ .from(`selectorKey`)
79
+ .to(`atomKey`),
80
+ selectorGraph: new Join({ relationType: `n:n` }),
81
+ valueMap: HAMT.make<any, string>(),
82
+ }))()),
83
83
 
84
- atoms: HAMT.make<Atom<any>, string>(),
85
- readonlySelectors: HAMT.make<ReadonlySelector<any>, string>(),
86
- selectors: HAMT.make<Selector<any>, string>(),
87
- transactions: HAMT.make<Transaction<any>, string>(),
88
- timelines: HAMT.make<Timeline, string>(),
84
+ atoms: HAMT.make<Atom<any>, string>(),
85
+ readonlySelectors: HAMT.make<ReadonlySelector<any>, string>(),
86
+ selectors: HAMT.make<Selector<any>, string>(),
87
+ transactions: HAMT.make<Transaction<any>, string>(),
88
+ timelines: HAMT.make<Timeline, string>(),
89
89
 
90
- timelineAtoms: new Join({ relationType: `1:n` })
91
- .from(`timelineKey`)
92
- .to(`atomKey`),
90
+ timelineAtoms: new Join({ relationType: `1:n` })
91
+ .from(`timelineKey`)
92
+ .to(`atomKey`),
93
93
 
94
- subject: {
95
- atomCreation: new Rx.Subject(),
96
- selectorCreation: new Rx.Subject(),
97
- transactionCreation: new Rx.Subject(),
98
- timelineCreation: new Rx.Subject(),
99
- ...store?.subject,
100
- },
94
+ subject: {
95
+ atomCreation: new Rx.Subject(),
96
+ selectorCreation: new Rx.Subject(),
97
+ transactionCreation: new Rx.Subject(),
98
+ timelineCreation: new Rx.Subject(),
99
+ ...store?.subject,
100
+ },
101
101
 
102
- operation: {
103
- open: false,
104
- ...store?.operation,
105
- },
106
- transactionStatus: {
107
- phase: `idle`,
108
- ...store?.transactionStatus,
109
- },
110
- config: {
111
- logger: {
112
- ...console,
113
- info: doNothing,
114
- ...store?.config?.logger,
115
- },
116
- logger__INTERNAL: console,
117
- ...store?.config,
118
- name,
119
- },
120
- } satisfies Store
102
+ operation: {
103
+ open: false,
104
+ ...store?.operation,
105
+ },
106
+ transactionStatus: {
107
+ phase: `idle`,
108
+ ...store?.transactionStatus,
109
+ },
110
+ config: {
111
+ logger: {
112
+ ...console,
113
+ info: doNothing,
114
+ ...store?.config?.logger,
115
+ },
116
+ logger__INTERNAL: console,
117
+ ...store?.config,
118
+ name,
119
+ },
120
+ } satisfies Store
121
121
 
122
- store?.atoms.forEach((atom) => {
123
- const copiedAtom = { ...atom, subject: new Rx.Subject() } satisfies Atom<any>
124
- copiedStore.atoms = HAMT.set(atom.key, copiedAtom, copiedStore.atoms)
125
- })
126
- store?.readonlySelectors.forEach((selector) => {
127
- selector.install(copiedStore)
128
- })
129
- store?.selectors.forEach((selector) => {
130
- selector.install(copiedStore)
131
- })
132
- store?.transactions.forEach((tx) => {
133
- tx.install(copiedStore)
134
- })
135
- store?.timelines.forEach((timeline) => {
136
- timeline.install(copiedStore)
137
- })
122
+ store?.atoms.forEach((atom) => {
123
+ const copiedAtom = { ...atom, subject: new Rx.Subject() } satisfies Atom<any>
124
+ copiedStore.atoms = HAMT.set(atom.key, copiedAtom, copiedStore.atoms)
125
+ })
126
+ store?.readonlySelectors.forEach((selector) => {
127
+ selector.install(copiedStore)
128
+ })
129
+ store?.selectors.forEach((selector) => {
130
+ selector.install(copiedStore)
131
+ })
132
+ store?.transactions.forEach((tx) => {
133
+ tx.install(copiedStore)
134
+ })
135
+ store?.timelines.forEach((timeline) => {
136
+ timeline.install(copiedStore)
137
+ })
138
138
 
139
- return copiedStore
139
+ return copiedStore
140
140
  }
141
141
 
142
142
  export const IMPLICIT = {
143
- STORE_INTERNAL: undefined as Store | undefined,
144
- get STORE(): Store {
145
- return this.STORE_INTERNAL ?? (this.STORE_INTERNAL = createStore(`DEFAULT`))
146
- },
143
+ STORE_INTERNAL: undefined as Store | undefined,
144
+ get STORE(): Store {
145
+ return this.STORE_INTERNAL ?? (this.STORE_INTERNAL = createStore(`DEFAULT`))
146
+ },
147
147
  }
148
148
 
149
149
  export const clearStore = (store: Store = IMPLICIT.STORE): void => {
150
- const { config } = store
151
- Object.assign(store, createStore(config.name))
152
- store.config = config
150
+ const { config } = store
151
+ Object.assign(store, createStore(config.name))
152
+ store.config = config
153
153
  }
@@ -1,82 +1,82 @@
1
1
  import type { Atom, ReadonlySelector, Selector, Store } from "."
2
2
  import {
3
- getState__INTERNAL,
4
- withdraw,
5
- recallState,
6
- traceAllSelectorAtoms,
3
+ getState__INTERNAL,
4
+ withdraw,
5
+ recallState,
6
+ traceAllSelectorAtoms,
7
7
  } from "."
8
8
  import type { StateUpdate } from ".."
9
9
 
10
10
  export const prepareUpdate = <T>(
11
- state: Atom<T> | ReadonlySelector<T> | Selector<T>,
12
- store: Store
11
+ state: Atom<T> | ReadonlySelector<T> | Selector<T>,
12
+ store: Store,
13
13
  ): StateUpdate<T> => {
14
- const oldValue = recallState(state, store)
15
- const newValue = getState__INTERNAL(state, store)
16
- return { newValue, oldValue }
14
+ const oldValue = recallState(state, store)
15
+ const newValue = getState__INTERNAL(state, store)
16
+ return { newValue, oldValue }
17
17
  }
18
18
 
19
19
  export const stowUpdate = <T>(
20
- state: Atom<T>,
21
- update: StateUpdate<T>,
22
- store: Store
20
+ state: Atom<T>,
21
+ update: StateUpdate<T>,
22
+ store: Store,
23
23
  ): void => {
24
- const { key } = state
25
- const { logger } = store.config
26
- if (store.transactionStatus.phase !== `building`) {
27
- store.config.logger?.warn(
28
- `stowUpdate called outside of a transaction. This is probably a bug.`
29
- )
30
- return
31
- }
32
- store.transactionStatus.atomUpdates.push({ key, ...update })
33
- logger?.info(`📝 ${key} stowed (`, update.oldValue, `->`, update.newValue, `)`)
24
+ const { key } = state
25
+ const { logger } = store.config
26
+ if (store.transactionStatus.phase !== `building`) {
27
+ store.config.logger?.warn(
28
+ `stowUpdate called outside of a transaction. This is probably a bug.`,
29
+ )
30
+ return
31
+ }
32
+ store.transactionStatus.atomUpdates.push({ key, ...update })
33
+ logger?.info(`📝 ${key} stowed (`, update.oldValue, `->`, update.newValue, `)`)
34
34
  }
35
35
 
36
36
  export const emitUpdate = <T>(
37
- state: Atom<T> | ReadonlySelector<T> | Selector<T>,
38
- update: StateUpdate<T>,
39
- store: Store
37
+ state: Atom<T> | ReadonlySelector<T> | Selector<T>,
38
+ update: StateUpdate<T>,
39
+ store: Store,
40
40
  ): void => {
41
- const { key } = state
42
- const { logger } = store.config
43
- logger?.info(
44
- `📢 ${state.type} "${key}" went (`,
45
- update.oldValue,
46
- `->`,
47
- update.newValue,
48
- `)`
49
- )
50
- state.subject.next(update)
41
+ const { key } = state
42
+ const { logger } = store.config
43
+ logger?.info(
44
+ `📢 ${state.type} "${key}" went (`,
45
+ update.oldValue,
46
+ `->`,
47
+ update.newValue,
48
+ `)`,
49
+ )
50
+ state.subject.next(update)
51
51
  }
52
52
 
53
53
  export const subscribeToRootAtoms = <T>(
54
- state: ReadonlySelector<T> | Selector<T>,
55
- store: Store
54
+ state: ReadonlySelector<T> | Selector<T>,
55
+ store: Store,
56
56
  ): { unsubscribe: () => void }[] | null => {
57
- const dependencySubscriptions =
58
- `default` in state
59
- ? null
60
- : traceAllSelectorAtoms(state.key, store).map((atomToken) => {
61
- const atom = withdraw(atomToken, store)
62
- if (atom === null) {
63
- throw new Error(
64
- `Atom "${atomToken.key}", a dependency of selector "${state.key}", not found in store "${store.config.name}".`
65
- )
66
- }
67
- return atom.subject.subscribe((atomChange) => {
68
- store.config.logger?.info(
69
- `📢 selector "${state.key}" saw root "${atomToken.key}" go (`,
70
- atomChange.oldValue,
71
- `->`,
72
- atomChange.newValue,
73
- `)`
74
- )
75
- const oldValue = recallState(state, store)
76
- const newValue = getState__INTERNAL(state, store)
77
- store.config.logger?.info(` <- ${state.key} became`, newValue)
78
- state.subject.next({ newValue, oldValue })
79
- })
80
- })
81
- return dependencySubscriptions
57
+ const dependencySubscriptions =
58
+ `default` in state
59
+ ? null
60
+ : traceAllSelectorAtoms(state.key, store).map((atomToken) => {
61
+ const atom = withdraw(atomToken, store)
62
+ if (atom === null) {
63
+ throw new Error(
64
+ `Atom "${atomToken.key}", a dependency of selector "${state.key}", not found in store "${store.config.name}".`,
65
+ )
66
+ }
67
+ return atom.subject.subscribe((atomChange) => {
68
+ store.config.logger?.info(
69
+ `📢 selector "${state.key}" saw root "${atomToken.key}" go (`,
70
+ atomChange.oldValue,
71
+ `->`,
72
+ atomChange.newValue,
73
+ `)`,
74
+ )
75
+ const oldValue = recallState(state, store)
76
+ const newValue = getState__INTERNAL(state, store)
77
+ store.config.logger?.info(` <- ${state.key} became`, newValue)
78
+ state.subject.next({ newValue, oldValue })
79
+ })
80
+ })
81
+ return dependencySubscriptions
82
82
  }
@@ -4,86 +4,86 @@ import type { TimelineToken } from ".."
4
4
  import { setState } from ".."
5
5
 
6
6
  export const redo__INTERNAL = (
7
- token: TimelineToken,
8
- store: Store = IMPLICIT.STORE
7
+ token: TimelineToken,
8
+ store: Store = IMPLICIT.STORE,
9
9
  ): void => {
10
- store.config.logger?.info(`⏩ redo "${token.key}"`)
11
- const timelineData = store.timelines.get(token.key)
12
- if (!timelineData) {
13
- store.config.logger?.error(
14
- `Failed to redo on timeline "${token.key}". This timeline has not been initialized.`
15
- )
16
- return
17
- }
18
- if (timelineData.at === timelineData.history.length) {
19
- store.config.logger?.warn(
20
- `Failed to redo at the end of timeline "${token.key}". There is nothing to redo.`
21
- )
22
- return
23
- }
24
- timelineData.timeTraveling = true
25
- const update = timelineData.history[timelineData.at]
26
- switch (update.type) {
27
- case `atom_update`: {
28
- const { key, newValue } = update
29
- setState({ key, type: `atom` }, newValue, store)
30
- break
31
- }
32
- case `selector_update`:
33
- case `transaction_update`: {
34
- for (const atomUpdate of update.atomUpdates) {
35
- const { key, newValue } = atomUpdate
36
- setState({ key, type: `atom` }, newValue, store)
37
- }
38
- break
39
- }
40
- }
41
- ++timelineData.at
42
- timelineData.timeTraveling = false
43
- store.config.logger?.info(
44
- `⏹️ "${token.key}" is now at ${timelineData.at} / ${timelineData.history.length}`
45
- )
10
+ store.config.logger?.info(`⏩ redo "${token.key}"`)
11
+ const timelineData = store.timelines.get(token.key)
12
+ if (!timelineData) {
13
+ store.config.logger?.error(
14
+ `Failed to redo on timeline "${token.key}". This timeline has not been initialized.`,
15
+ )
16
+ return
17
+ }
18
+ if (timelineData.at === timelineData.history.length) {
19
+ store.config.logger?.warn(
20
+ `Failed to redo at the end of timeline "${token.key}". There is nothing to redo.`,
21
+ )
22
+ return
23
+ }
24
+ timelineData.timeTraveling = true
25
+ const update = timelineData.history[timelineData.at]
26
+ switch (update.type) {
27
+ case `atom_update`: {
28
+ const { key, newValue } = update
29
+ setState({ key, type: `atom` }, newValue, store)
30
+ break
31
+ }
32
+ case `selector_update`:
33
+ case `transaction_update`: {
34
+ for (const atomUpdate of update.atomUpdates) {
35
+ const { key, newValue } = atomUpdate
36
+ setState({ key, type: `atom` }, newValue, store)
37
+ }
38
+ break
39
+ }
40
+ }
41
+ ++timelineData.at
42
+ timelineData.timeTraveling = false
43
+ store.config.logger?.info(
44
+ `⏹️ "${token.key}" is now at ${timelineData.at} / ${timelineData.history.length}`,
45
+ )
46
46
  }
47
47
 
48
48
  export const undo__INTERNAL = (
49
- token: TimelineToken,
50
- store: Store = IMPLICIT.STORE
49
+ token: TimelineToken,
50
+ store: Store = IMPLICIT.STORE,
51
51
  ): void => {
52
- store.config.logger?.info(`⏪ undo "${token.key}"`)
53
- const timelineData = store.timelines.get(token.key)
54
- if (!timelineData) {
55
- store.config.logger?.error(
56
- `Failed to undo on timeline "${token.key}". This timeline has not been initialized.`
57
- )
58
- return
59
- }
60
- if (timelineData.at === 0) {
61
- store.config.logger?.warn(
62
- `Failed to undo at the beginning of timeline "${token.key}". There is nothing to undo.`
63
- )
64
- return
65
- }
66
- timelineData.timeTraveling = true
52
+ store.config.logger?.info(`⏪ undo "${token.key}"`)
53
+ const timelineData = store.timelines.get(token.key)
54
+ if (!timelineData) {
55
+ store.config.logger?.error(
56
+ `Failed to undo on timeline "${token.key}". This timeline has not been initialized.`,
57
+ )
58
+ return
59
+ }
60
+ if (timelineData.at === 0) {
61
+ store.config.logger?.warn(
62
+ `Failed to undo at the beginning of timeline "${token.key}". There is nothing to undo.`,
63
+ )
64
+ return
65
+ }
66
+ timelineData.timeTraveling = true
67
67
 
68
- --timelineData.at
69
- const update = timelineData.history[timelineData.at]
70
- switch (update.type) {
71
- case `atom_update`: {
72
- const { key, oldValue } = update
73
- setState({ key, type: `atom` }, oldValue, store)
74
- break
75
- }
76
- case `selector_update`:
77
- case `transaction_update`: {
78
- for (const atomUpdate of update.atomUpdates) {
79
- const { key, oldValue } = atomUpdate
80
- setState({ key, type: `atom` }, oldValue, store)
81
- }
82
- break
83
- }
84
- }
85
- timelineData.timeTraveling = false
86
- store.config.logger?.info(
87
- `⏹️ "${token.key}" is now at ${timelineData.at} / ${timelineData.history.length}`
88
- )
68
+ --timelineData.at
69
+ const update = timelineData.history[timelineData.at]
70
+ switch (update.type) {
71
+ case `atom_update`: {
72
+ const { key, oldValue } = update
73
+ setState({ key, type: `atom` }, oldValue, store)
74
+ break
75
+ }
76
+ case `selector_update`:
77
+ case `transaction_update`: {
78
+ for (const atomUpdate of update.atomUpdates) {
79
+ const { key, oldValue } = atomUpdate
80
+ setState({ key, type: `atom` }, oldValue, store)
81
+ }
82
+ break
83
+ }
84
+ }
85
+ timelineData.timeTraveling = false
86
+ store.config.logger?.info(
87
+ `⏹️ "${token.key}" is now at ${timelineData.at} / ${timelineData.history.length}`,
88
+ )
89
89
  }