atom.io 0.6.8 → 0.6.9

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 (130) hide show
  1. package/dist/index.d.mts +226 -258
  2. package/dist/index.d.ts +226 -258
  3. package/dist/index.js +28 -1917
  4. package/dist/index.js.map +1 -1
  5. package/dist/index.mjs +5 -1877
  6. package/dist/index.mjs.map +1 -1
  7. package/introspection/dist/index.d.mts +117 -171
  8. package/introspection/dist/index.d.ts +117 -171
  9. package/introspection/dist/index.js +6 -346
  10. package/introspection/dist/index.js.map +1 -1
  11. package/introspection/dist/index.mjs +5 -324
  12. package/introspection/dist/index.mjs.map +1 -1
  13. package/json/dist/index.d.mts +32 -1
  14. package/json/dist/index.d.ts +32 -1
  15. package/json/dist/index.js +31 -48
  16. package/json/dist/index.js.map +1 -1
  17. package/json/dist/index.mjs +6 -14
  18. package/json/dist/index.mjs.map +1 -1
  19. package/package.json +22 -14
  20. package/react/dist/index.js +34 -83
  21. package/react/dist/index.js.map +1 -1
  22. package/react/dist/index.mjs +7 -43
  23. package/react/dist/index.mjs.map +1 -1
  24. package/react-devtools/dist/index.css +1 -50
  25. package/react-devtools/dist/index.css.map +1 -1
  26. package/react-devtools/dist/index.d.mts +124 -188
  27. package/react-devtools/dist/index.d.ts +124 -188
  28. package/react-devtools/dist/index.js +56 -4674
  29. package/react-devtools/dist/index.js.map +1 -1
  30. package/react-devtools/dist/index.mjs +19 -4642
  31. package/react-devtools/dist/index.mjs.map +1 -1
  32. package/realtime/dist/index.d.mts +1 -3
  33. package/realtime/dist/index.d.ts +1 -3
  34. package/realtime/dist/index.js +26 -184
  35. package/realtime/dist/index.js.map +1 -1
  36. package/realtime/dist/index.mjs +4 -148
  37. package/realtime/dist/index.mjs.map +1 -1
  38. package/realtime-react/dist/index.d.mts +2 -4
  39. package/realtime-react/dist/index.d.ts +2 -4
  40. package/realtime-react/dist/index.js +41 -214
  41. package/realtime-react/dist/index.js.map +1 -1
  42. package/realtime-react/dist/index.mjs +9 -169
  43. package/realtime-react/dist/index.mjs.map +1 -1
  44. package/src/atom.ts +4 -3
  45. package/src/index.ts +12 -9
  46. package/src/logger.ts +5 -5
  47. package/src/selector.ts +3 -3
  48. package/src/silo.ts +36 -39
  49. package/src/subscribe.ts +24 -19
  50. package/src/timeline.ts +9 -4
  51. package/src/transaction.ts +3 -4
  52. package/src/internal/atom-internal.ts +0 -54
  53. package/src/internal/families-internal.ts +0 -144
  54. package/src/internal/get.ts +0 -129
  55. package/src/internal/index.ts +0 -15
  56. package/src/internal/is-default.ts +0 -35
  57. package/src/internal/operation.ts +0 -139
  58. package/src/internal/selector/create-read-write-selector.ts +0 -68
  59. package/src/internal/selector/create-readonly-selector.ts +0 -48
  60. package/src/internal/selector/index.ts +0 -4
  61. package/src/internal/selector/lookup-selector-sources.ts +0 -16
  62. package/src/internal/selector/register-selector.ts +0 -57
  63. package/src/internal/selector/trace-selector-atoms.ts +0 -43
  64. package/src/internal/selector/update-selector-atoms.ts +0 -33
  65. package/src/internal/selector-internal.ts +0 -58
  66. package/src/internal/set.ts +0 -99
  67. package/src/internal/store.ts +0 -151
  68. package/src/internal/subscribe-internal.ts +0 -88
  69. package/src/internal/time-travel-internal.ts +0 -91
  70. package/src/internal/timeline/add-atom-to-timeline.ts +0 -168
  71. package/src/internal/timeline/index.ts +0 -1
  72. package/src/internal/timeline-internal.ts +0 -107
  73. package/src/internal/transaction/abort-transaction.ts +0 -12
  74. package/src/internal/transaction/apply-transaction.ts +0 -57
  75. package/src/internal/transaction/build-transaction.ts +0 -33
  76. package/src/internal/transaction/index.ts +0 -25
  77. package/src/internal/transaction/redo-transaction.ts +0 -23
  78. package/src/internal/transaction/undo-transaction.ts +0 -23
  79. package/src/internal/transaction-internal.ts +0 -61
  80. package/src/introspection/attach-atom-index.ts +0 -73
  81. package/src/introspection/attach-introspection-states.ts +0 -42
  82. package/src/introspection/attach-selector-index.ts +0 -77
  83. package/src/introspection/attach-timeline-family.ts +0 -59
  84. package/src/introspection/attach-timeline-index.ts +0 -36
  85. package/src/introspection/attach-transaction-index.ts +0 -38
  86. package/src/introspection/attach-transaction-logs.ts +0 -40
  87. package/src/introspection/index.ts +0 -20
  88. package/src/json/index.ts +0 -1
  89. package/src/json/select-json.ts +0 -18
  90. package/src/react/index.ts +0 -2
  91. package/src/react/store-context.tsx +0 -13
  92. package/src/react/store-hooks.ts +0 -47
  93. package/src/react-devtools/AtomIODevtools.tsx +0 -107
  94. package/src/react-devtools/Button.tsx +0 -24
  95. package/src/react-devtools/StateEditor.tsx +0 -74
  96. package/src/react-devtools/StateIndex.tsx +0 -156
  97. package/src/react-devtools/TimelineIndex.tsx +0 -92
  98. package/src/react-devtools/TransactionIndex.tsx +0 -70
  99. package/src/react-devtools/Updates.tsx +0 -145
  100. package/src/react-devtools/devtools.scss +0 -310
  101. package/src/react-devtools/index.ts +0 -72
  102. package/src/react-explorer/AtomIOExplorer.tsx +0 -218
  103. package/src/react-explorer/explorer-effects.ts +0 -20
  104. package/src/react-explorer/explorer-states.ts +0 -217
  105. package/src/react-explorer/index.ts +0 -23
  106. package/src/react-explorer/space-states.ts +0 -72
  107. package/src/react-explorer/view-states.ts +0 -41
  108. package/src/realtime/README.md +0 -33
  109. package/src/realtime/hook-composition/expose-family.ts +0 -101
  110. package/src/realtime/hook-composition/expose-single.ts +0 -38
  111. package/src/realtime/hook-composition/expose-timeline.ts +0 -60
  112. package/src/realtime/hook-composition/index.ts +0 -12
  113. package/src/realtime/hook-composition/receive-state.ts +0 -29
  114. package/src/realtime/hook-composition/receive-transaction.ts +0 -18
  115. package/src/realtime/index.ts +0 -1
  116. package/src/realtime-react/index.ts +0 -3
  117. package/src/realtime-react/realtime-context.tsx +0 -30
  118. package/src/realtime-react/realtime-hooks.ts +0 -39
  119. package/src/realtime-react/realtime-state.ts +0 -10
  120. package/src/realtime-react/use-pull-family-member.ts +0 -26
  121. package/src/realtime-react/use-pull-family.ts +0 -24
  122. package/src/realtime-react/use-pull.ts +0 -24
  123. package/src/realtime-react/use-push.ts +0 -27
  124. package/src/realtime-react/use-server-action.ts +0 -33
  125. package/src/realtime-testing/index.ts +0 -1
  126. package/src/realtime-testing/setup-realtime-test.tsx +0 -159
  127. package/src/tracker/index.ts +0 -3
  128. package/src/tracker/tracker.ts +0 -61
  129. package/src/web-effects/index.ts +0 -1
  130. package/src/web-effects/storage.ts +0 -30
@@ -1,151 +0,0 @@
1
- import type { ƒn } from "~/packages/anvl/src/function"
2
- import { doNothing } from "~/packages/anvl/src/function"
3
- import { Join } from "~/packages/anvl/src/join"
4
-
5
- import { Subject } from "."
6
- import type {
7
- Atom,
8
- OperationProgress,
9
- ReadonlySelector,
10
- Selector,
11
- TransactionStatus,
12
- Timeline,
13
- Transaction,
14
- } from "."
15
- import type {
16
- AtomToken,
17
- Logger,
18
- ReadonlySelectorToken,
19
- SelectorToken,
20
- TimelineToken,
21
- TransactionToken,
22
- } from ".."
23
-
24
- export type StoreCore = Pick<
25
- Store,
26
- | `atoms`
27
- | `atomsThatAreDefault`
28
- | `operation`
29
- | `readonlySelectors`
30
- | `selectorAtoms`
31
- | `selectorGraph`
32
- | `selectors`
33
- | `timelineAtoms`
34
- | `timelines`
35
- | `transactions`
36
- | `valueMap`
37
- >
38
-
39
- export interface Store {
40
- atoms: Map<string, Atom<any>>
41
- atomsThatAreDefault: Set<string>
42
- readonlySelectors: Map<string, ReadonlySelector<any>>
43
- selectorAtoms: Join<null, `selectorKey`, `atomKey`>
44
- selectorGraph: Join<{ source: string }>
45
- selectors: Map<string, Selector<any>>
46
- timelineAtoms: Join<null, `timelineKey`, `atomKey`>
47
- timelines: Map<string, Timeline>
48
- transactions: Map<string, Transaction<any>>
49
- valueMap: Map<string, any>
50
-
51
- subject: {
52
- atomCreation: Subject<AtomToken<unknown>>
53
- selectorCreation: Subject<
54
- ReadonlySelectorToken<unknown> | SelectorToken<unknown>
55
- >
56
- transactionCreation: Subject<TransactionToken<ƒn>>
57
- timelineCreation: Subject<TimelineToken>
58
- operationStatus: Subject<OperationProgress>
59
- }
60
-
61
- operation: OperationProgress
62
- transactionStatus: TransactionStatus<ƒn>
63
- config: {
64
- name: string
65
- logger: Logger | null
66
- logger__INTERNAL: Logger
67
- }
68
- }
69
-
70
- export const createStore = (name: string, store: Store | null = null): Store => {
71
- const created = {
72
- ...(store ??
73
- (() => ({
74
- atomsThatAreDefault: new Set(),
75
- selectorAtoms: new Join({ relationType: `n:n` })
76
- .from(`selectorKey`)
77
- .to(`atomKey`),
78
- selectorGraph: new Join({ relationType: `n:n` }),
79
- }))()),
80
-
81
- valueMap: new Map(store?.valueMap),
82
- atoms: new Map(),
83
- readonlySelectors: new Map(),
84
- selectors: new Map(),
85
- transactions: new Map(),
86
- timelines: new Map(),
87
-
88
- timelineAtoms: new Join({ relationType: `1:n` })
89
- .from(`timelineKey`)
90
- .to(`atomKey`),
91
-
92
- subject: {
93
- atomCreation: new Subject(),
94
- selectorCreation: new Subject(),
95
- transactionCreation: new Subject(),
96
- timelineCreation: new Subject(),
97
- operationStatus: new Subject(),
98
- },
99
-
100
- operation: {
101
- open: false,
102
- ...store?.operation,
103
- },
104
- transactionStatus: {
105
- phase: `idle`,
106
- ...store?.transactionStatus,
107
- },
108
- config: {
109
- logger: {
110
- ...console,
111
- info: doNothing,
112
- ...store?.config?.logger,
113
- },
114
- logger__INTERNAL: console,
115
- ...store?.config,
116
- name,
117
- },
118
- } satisfies Store
119
-
120
- store?.atoms.forEach((atom) => {
121
- const copiedAtom = { ...atom, subject: new Subject() } satisfies Atom<any>
122
- created.atoms.set(atom.key, copiedAtom)
123
- })
124
- store?.readonlySelectors.forEach((selector) => {
125
- selector.install(created)
126
- })
127
- store?.selectors.forEach((selector) => {
128
- selector.install(created)
129
- })
130
- store?.transactions.forEach((tx) => {
131
- tx.install(created)
132
- })
133
- store?.timelines.forEach((timeline) => {
134
- timeline.install(created)
135
- })
136
-
137
- return created
138
- }
139
-
140
- export const IMPLICIT = {
141
- STORE_INTERNAL: undefined as Store | undefined,
142
- get STORE(): Store {
143
- return this.STORE_INTERNAL ?? (this.STORE_INTERNAL = createStore(`DEFAULT`))
144
- },
145
- }
146
-
147
- export const clearStore = (store: Store = IMPLICIT.STORE): void => {
148
- const { config } = store
149
- Object.assign(store, createStore(config.name))
150
- store.config = config
151
- }
@@ -1,88 +0,0 @@
1
- import type { Atom, ReadonlySelector, Selector, Store } from "."
2
- import {
3
- getState__INTERNAL,
4
- withdraw,
5
- recallState,
6
- traceAllSelectorAtoms,
7
- } from "."
8
- import type { StateUpdate } from ".."
9
-
10
- export const prepareUpdate = <T>(
11
- state: Atom<T> | ReadonlySelector<T> | Selector<T>,
12
- store: Store,
13
- ): StateUpdate<T> => {
14
- const oldValue = recallState(state, store)
15
- const newValue = getState__INTERNAL(state, store)
16
- return { newValue, oldValue }
17
- }
18
-
19
- export const stowUpdate = <T>(
20
- state: Atom<T>,
21
- update: StateUpdate<T>,
22
- store: Store,
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, `)`)
34
- }
35
-
36
- export const emitUpdate = <T>(
37
- state: Atom<T> | ReadonlySelector<T> | Selector<T>,
38
- update: StateUpdate<T>,
39
- store: Store,
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)
51
- }
52
-
53
- export const subscribeToRootAtoms = <T>(
54
- state: ReadonlySelector<T> | Selector<T>,
55
- store: Store,
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(
78
- ` <- "${state.key}" went (`,
79
- oldValue,
80
- `->`,
81
- newValue,
82
- `)`,
83
- )
84
- state.subject.next({ newValue, oldValue })
85
- })
86
- })
87
- return dependencySubscriptions
88
- }
@@ -1,91 +0,0 @@
1
- import type { Store } from "."
2
- import { IMPLICIT } from "."
3
- import type { TimelineToken } from ".."
4
- import { setState } from ".."
5
-
6
- export const redo__INTERNAL = (
7
- token: TimelineToken,
8
- store: Store = IMPLICIT.STORE,
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 = `into_future`
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.subject.next(`redo`)
43
- timelineData.timeTraveling = null
44
- store.config.logger?.info(
45
- `⏹️ "${token.key}" is now at ${timelineData.at} / ${timelineData.history.length}`,
46
- )
47
- }
48
-
49
- export const undo__INTERNAL = (
50
- token: TimelineToken,
51
- store: Store = IMPLICIT.STORE,
52
- ): void => {
53
- store.config.logger?.info(`⏪ undo "${token.key}"`)
54
- const timelineData = store.timelines.get(token.key)
55
- if (!timelineData) {
56
- store.config.logger?.error(
57
- `Failed to undo on timeline "${token.key}". This timeline has not been initialized.`,
58
- )
59
- return
60
- }
61
- if (timelineData.at === 0) {
62
- store.config.logger?.warn(
63
- `Failed to undo at the beginning of timeline "${token.key}". There is nothing to undo.`,
64
- )
65
- return
66
- }
67
- timelineData.timeTraveling = `into_past`
68
-
69
- --timelineData.at
70
- const update = timelineData.history[timelineData.at]
71
- switch (update.type) {
72
- case `atom_update`: {
73
- const { key, oldValue } = update
74
- setState({ key, type: `atom` }, oldValue, store)
75
- break
76
- }
77
- case `selector_update`:
78
- case `transaction_update`: {
79
- for (const atomUpdate of update.atomUpdates) {
80
- const { key, oldValue } = atomUpdate
81
- setState({ key, type: `atom` }, oldValue, store)
82
- }
83
- break
84
- }
85
- }
86
- timelineData.subject.next(`undo`)
87
- timelineData.timeTraveling = null
88
- store.config.logger?.info(
89
- `⏹️ "${token.key}" is now at ${timelineData.at} / ${timelineData.history.length}`,
90
- )
91
- }
@@ -1,168 +0,0 @@
1
- import { IMPLICIT, withdraw } from ".."
2
- import type {
3
- Timeline,
4
- Store,
5
- TimelineTransactionUpdate,
6
- TimelineAtomUpdate,
7
- } from ".."
8
- import type { AtomFamily, AtomToken, TimelineUpdate } from "../.."
9
-
10
- export const addAtomToTimeline = (
11
- atomToken: AtomToken<any>,
12
- atoms: (AtomFamily<any> | AtomToken<any>)[],
13
- tl: Timeline,
14
- store: Store = IMPLICIT.STORE,
15
- ): void => {
16
- const atom = withdraw(atomToken, store)
17
- if (atom === null) {
18
- throw new Error(
19
- `Cannot subscribe to atom "${atomToken.key}" because it has not been initialized in store "${store.config.name}"`,
20
- )
21
- }
22
- atom.subject.subscribe((update) => {
23
- const currentSelectorKey =
24
- store.operation.open && store.operation.token.type === `selector`
25
- ? store.operation.token.key
26
- : null
27
- const currentSelectorTime =
28
- store.operation.open && store.operation.token.type === `selector`
29
- ? store.operation.time
30
- : null
31
- const currentTransactionKey =
32
- store.transactionStatus.phase === `applying`
33
- ? store.transactionStatus.key
34
- : null
35
- const currentTransactionTime =
36
- store.transactionStatus.phase === `applying`
37
- ? store.transactionStatus.time
38
- : null
39
-
40
- store.config.logger?.info(
41
- `⏳ timeline "${tl.key}" saw atom "${atomToken.key}" go (`,
42
- update.oldValue,
43
- `->`,
44
- update.newValue,
45
- currentTransactionKey
46
- ? `) in transaction "${currentTransactionKey}"`
47
- : currentSelectorKey
48
- ? `) in selector "${currentSelectorKey}"`
49
- : `)`,
50
- )
51
-
52
- if (tl.timeTraveling === null) {
53
- if (tl.selectorTime && tl.selectorTime !== currentSelectorTime) {
54
- const mostRecentUpdate: TimelineUpdate | undefined = tl.history.at(-1)
55
- if (mostRecentUpdate === undefined) {
56
- throw new Error(
57
- `Timeline "${tl.key}" has a selectorTime, but no history. This is most likely a bug in AtomIO.`,
58
- )
59
- }
60
- }
61
- if (
62
- currentTransactionKey &&
63
- store.transactionStatus.phase === `applying`
64
- ) {
65
- const currentTransaction = withdraw(
66
- { key: currentTransactionKey, type: `transaction` },
67
- store,
68
- )
69
- if (currentTransaction === null) {
70
- throw new Error(
71
- `Transaction "${currentTransactionKey}" not found in store "${store.config.name}". This is surprising, because we are in the application phase of "${currentTransactionKey}".`,
72
- )
73
- }
74
- if (tl.transactionKey !== currentTransactionKey) {
75
- if (tl.transactionKey) {
76
- store.config.logger?.error(
77
- `Timeline "${tl.key}" was unable to resolve transaction "${tl.transactionKey}. This is probably a bug.`,
78
- )
79
- }
80
- tl.transactionKey = currentTransactionKey
81
- const subscription = currentTransaction.subject.subscribe((update) => {
82
- subscription.unsubscribe()
83
- if (tl.timeTraveling === null && currentTransactionTime) {
84
- if (tl.at !== tl.history.length) {
85
- tl.history.splice(tl.at)
86
- }
87
- const timelineTransactionUpdate: TimelineTransactionUpdate = {
88
- type: `transaction_update`,
89
- timestamp: currentTransactionTime,
90
- ...update,
91
- atomUpdates: update.atomUpdates.filter((atomUpdate) =>
92
- atoms.some((atom) => atom.key === atomUpdate.key),
93
- ),
94
- }
95
- tl.history.push(timelineTransactionUpdate)
96
- tl.at = tl.history.length
97
- tl.subject.next(timelineTransactionUpdate)
98
- }
99
- tl.transactionKey = null
100
- store.config.logger?.info(
101
- `⌛ timeline "${tl.key}" got a transaction_update "${update.key}"`,
102
- )
103
- })
104
- }
105
- } else if (currentSelectorKey && currentSelectorTime) {
106
- let latestUpdate: TimelineUpdate | undefined = tl.history.at(-1)
107
-
108
- if (currentSelectorTime !== tl.selectorTime) {
109
- latestUpdate = {
110
- type: `selector_update`,
111
- timestamp: currentSelectorTime,
112
- key: currentSelectorKey,
113
- atomUpdates: [],
114
- }
115
- latestUpdate.atomUpdates.push({
116
- key: atom.key,
117
- type: `atom_update`,
118
- ...update,
119
- })
120
- if (tl.at !== tl.history.length) {
121
- tl.history.splice(tl.at)
122
- }
123
- tl.history.push(latestUpdate)
124
-
125
- store.config.logger?.info(
126
- `⌛ timeline "${tl.key}" got a selector_update "${currentSelectorKey}" with`,
127
- latestUpdate.atomUpdates.map((atomUpdate) => atomUpdate.key),
128
- )
129
-
130
- tl.at = tl.history.length
131
- tl.selectorTime = currentSelectorTime
132
- } else {
133
- if (latestUpdate?.type === `selector_update`) {
134
- latestUpdate.atomUpdates.push({
135
- key: atom.key,
136
- type: `atom_update`,
137
- ...update,
138
- })
139
- store.config.logger?.info(
140
- ` ⌛ timeline "${tl.key}" set selector_update "${currentSelectorKey}" to`,
141
- latestUpdate?.atomUpdates.map((atomUpdate) => atomUpdate.key),
142
- )
143
- }
144
- }
145
- if (latestUpdate) tl.subject.next(latestUpdate)
146
- } else {
147
- const timestamp = Date.now()
148
- tl.selectorTime = null
149
- if (tl.at !== tl.history.length) {
150
- tl.history.splice(tl.at)
151
- }
152
- const atomUpdate: TimelineAtomUpdate = {
153
- type: `atom_update`,
154
- timestamp,
155
- key: atom.key,
156
- oldValue: update.oldValue,
157
- newValue: update.newValue,
158
- }
159
- tl.history.push(atomUpdate)
160
- tl.subject.next(atomUpdate)
161
- store.config.logger?.info(
162
- `⌛ timeline "${tl.key}" got an atom_update to "${atom.key}"`,
163
- )
164
- tl.at = tl.history.length
165
- }
166
- }
167
- })
168
- }
@@ -1 +0,0 @@
1
- export * from "./add-atom-to-timeline"
@@ -1,107 +0,0 @@
1
- import type { ƒn } from "~/packages/anvl/src/function"
2
-
3
- import type { Store } from "."
4
- import { Subject, target, IMPLICIT } from "."
5
- import { addAtomToTimeline } from "./timeline/add-atom-to-timeline"
6
- import type {
7
- StateUpdate,
8
- TimelineOptions,
9
- TimelineToken,
10
- TimelineUpdate,
11
- TransactionUpdate,
12
- } from ".."
13
-
14
- export type TimelineAtomUpdate = StateUpdate<unknown> & {
15
- key: string
16
- type: `atom_update`
17
- timestamp: number
18
- }
19
- export type TimelineSelectorUpdate = {
20
- key: string
21
- type: `selector_update`
22
- timestamp: number
23
- atomUpdates: Omit<TimelineAtomUpdate, `timestamp`>[]
24
- }
25
- export type TimelineTransactionUpdate = TransactionUpdate<ƒn> & {
26
- key: string
27
- type: `transaction_update`
28
- timestamp: number
29
- }
30
-
31
- export type Timeline = {
32
- key: string
33
- at: number
34
- timeTraveling: `into_future` | `into_past` | null
35
- history: TimelineUpdate[]
36
- selectorTime: number | null
37
- transactionKey: string | null
38
- install: (store: Store) => void
39
- subject: Subject<
40
- | TimelineAtomUpdate
41
- | TimelineSelectorUpdate
42
- | TimelineTransactionUpdate
43
- | `redo`
44
- | `undo`
45
- >
46
- }
47
-
48
- export function timeline__INTERNAL(
49
- options: TimelineOptions,
50
- store: Store = IMPLICIT.STORE,
51
- data: Timeline | null = null,
52
- ): TimelineToken {
53
- const tl: Timeline = {
54
- key: options.key,
55
- at: 0,
56
- timeTraveling: null,
57
- selectorTime: null,
58
- transactionKey: null,
59
- ...data,
60
- history: data?.history.map((update) => ({ ...update })) ?? [],
61
- install: (store) => timeline__INTERNAL(options, store, tl),
62
- subject: new Subject(),
63
- }
64
-
65
- const core = target(store)
66
- for (const tokenOrFamily of options.atoms) {
67
- const timelineKey = core.timelineAtoms.getRelatedId(tokenOrFamily.key)
68
- if (timelineKey) {
69
- store.config.logger?.error(
70
- `❌ Failed to add atom "${tokenOrFamily.key}" to timeline "${options.key}" because it belongs to timeline "${timelineKey}"`,
71
- )
72
- continue
73
- }
74
- if (tokenOrFamily.type === `atom_family`) {
75
- const family = tokenOrFamily
76
- family.subject.subscribe((token) =>
77
- addAtomToTimeline(token, options.atoms, tl, store),
78
- )
79
- } else {
80
- const token = tokenOrFamily
81
- if (`family` in token && token.family) {
82
- const familyTimelineKey = core.timelineAtoms.getRelatedId(
83
- token.family.key,
84
- )
85
- if (familyTimelineKey) {
86
- store.config.logger?.error(
87
- `❌ Failed to add atom "${token.key}" to timeline "${options.key}" because its family "${token.family.key}" belongs to timeline "${familyTimelineKey}"`,
88
- )
89
- continue
90
- }
91
- }
92
- addAtomToTimeline(token, options.atoms, tl, store)
93
- }
94
- core.timelineAtoms = core.timelineAtoms.set({
95
- atomKey: tokenOrFamily.key,
96
- timelineKey: options.key,
97
- })
98
- }
99
-
100
- store.timelines.set(options.key, tl)
101
- const token: TimelineToken = {
102
- key: options.key,
103
- type: `timeline`,
104
- }
105
- store.subject.timelineCreation.next(token)
106
- return token
107
- }
@@ -1,12 +0,0 @@
1
- import type { Store } from ".."
2
-
3
- export const abortTransaction = (store: Store): void => {
4
- if (store.transactionStatus.phase === `idle`) {
5
- store.config.logger?.warn(
6
- `abortTransaction called outside of a transaction. This is probably a bug.`,
7
- )
8
- return
9
- }
10
- store.transactionStatus = { phase: `idle` }
11
- store.config.logger?.info(`🪂`, `transaction fail`)
12
- }
@@ -1,57 +0,0 @@
1
- import type { ƒn } from "~/packages/anvl/src/function"
2
-
3
- import type { Store } from ".."
4
- import { withdraw } from ".."
5
- import type { AtomToken } from "../.."
6
- import { setState } from "../.."
7
-
8
- export const applyTransaction = <ƒ extends ƒn>(
9
- output: ReturnType<ƒ>,
10
- store: Store,
11
- ): void => {
12
- if (store.transactionStatus.phase !== `building`) {
13
- store.config.logger?.warn(
14
- `abortTransaction called outside of a transaction. This is probably a bug.`,
15
- )
16
- return
17
- }
18
- store.config.logger?.info(
19
- `🛃 apply transaction "${store.transactionStatus.key}"`,
20
- )
21
- store.transactionStatus.phase = `applying`
22
- store.transactionStatus.output = output
23
- const { atomUpdates } = store.transactionStatus
24
-
25
- for (const { key, newValue } of atomUpdates) {
26
- const token: AtomToken<unknown> = { key, type: `atom` }
27
- if (!store.valueMap.has(token.key)) {
28
- const newAtom = store.transactionStatus.core.atoms.get(token.key)
29
- if (!newAtom) {
30
- throw new Error(
31
- `Absurd Error: Atom "${token.key}" not found while copying updates from transaction "${store.transactionStatus.key}" to store "${store.config.name}"`,
32
- )
33
- }
34
- store.atoms.set(newAtom.key, newAtom)
35
- store.valueMap.set(newAtom.key, newAtom.default)
36
- store.config.logger?.info(`🔧`, `add atom "${newAtom.key}"`)
37
- }
38
- setState(token, newValue, store)
39
- }
40
- const myTransaction = withdraw<ƒ>(
41
- { key: store.transactionStatus.key, type: `transaction` },
42
- store,
43
- )
44
- if (myTransaction === null) {
45
- throw new Error(
46
- `Transaction "${store.transactionStatus.key}" not found. Absurd. How is this running?`,
47
- )
48
- }
49
- myTransaction.subject.next({
50
- key: store.transactionStatus.key,
51
- atomUpdates,
52
- output,
53
- params: store.transactionStatus.params as Parameters<ƒ>,
54
- })
55
- store.transactionStatus = { phase: `idle` }
56
- store.config.logger?.info(`🛬`, `transaction done`)
57
- }