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
@@ -9,26 +9,26 @@ import { RealtimeContext } from "./realtime-context"
9
9
 
10
10
  const TX_SUBS = new Map<string, number>()
11
11
  export function useServerAction<ƒ extends ƒn>(
12
- token: AtomIO.TransactionToken<ƒ>
12
+ token: AtomIO.TransactionToken<ƒ>,
13
13
  ): (...parameters: Parameters<ƒ>) => ReturnType<ƒ> {
14
- const store = React.useContext(StoreContext)
15
- const { socket } = React.useContext(RealtimeContext)
16
- React.useEffect(() => {
17
- const count = TX_SUBS.get(token.key) ?? 0
18
- TX_SUBS.set(token.key, count + 1)
19
- const unsubscribe =
20
- count === 0
21
- ? AtomIO.subscribeToTransaction(
22
- token,
23
- (update) => socket.emit(`tx:${token.key}`, update),
24
- store
25
- )
26
- : () => null
27
- return () => {
28
- const newCount = TX_SUBS.get(token.key) ?? 0
29
- TX_SUBS.set(token.key, newCount - 1)
30
- unsubscribe()
31
- }
32
- }, [token.key])
33
- return AtomIO.runTransaction(token, store)
14
+ const store = React.useContext(StoreContext)
15
+ const { socket } = React.useContext(RealtimeContext)
16
+ React.useEffect(() => {
17
+ const count = TX_SUBS.get(token.key) ?? 0
18
+ TX_SUBS.set(token.key, count + 1)
19
+ const unsubscribe =
20
+ count === 0
21
+ ? AtomIO.subscribeToTransaction(
22
+ token,
23
+ (update) => socket.emit(`tx:${token.key}`, update),
24
+ store,
25
+ )
26
+ : () => null
27
+ return () => {
28
+ const newCount = TX_SUBS.get(token.key) ?? 0
29
+ TX_SUBS.set(token.key, newCount - 1)
30
+ unsubscribe()
31
+ }
32
+ }, [token.key])
33
+ return AtomIO.runTransaction(token, store)
34
34
  }
@@ -0,0 +1 @@
1
+ export * from "./setup-realtime-test"
@@ -0,0 +1,160 @@
1
+ import * as http from "http"
2
+
3
+ import * as React from "react"
4
+
5
+ import { prettyDOM, render, type RenderResult } from "@testing-library/react"
6
+ import * as AtomIO from "atom.io"
7
+ import * as AR from "atom.io/react"
8
+ import * as RTC from "atom.io/realtime-react"
9
+ import * as RR from "fp-ts/ReadonlyRecord"
10
+ import * as Happy from "happy-dom"
11
+ import * as SocketIO from "socket.io"
12
+ import type { Socket as ClientSocket } from "socket.io-client"
13
+ import { io } from "socket.io-client"
14
+
15
+ export type TestSetupOptions = {
16
+ server: (tools: { socket: SocketIO.Socket; silo: AtomIO.Silo }) => void
17
+ }
18
+ export type TestSetupOptions__SingleClient = TestSetupOptions & {
19
+ client: React.FC
20
+ }
21
+ export type TestSetupOptions__MultiClient<ClientNames extends string> =
22
+ TestSetupOptions & {
23
+ clients: {
24
+ [K in ClientNames]: React.FC
25
+ }
26
+ }
27
+
28
+ export type RealtimeTestTools = {
29
+ name: string
30
+ silo: AtomIO.Silo
31
+ dispose: () => void
32
+ }
33
+ export type RealtimeTestClient = RealtimeTestTools & {
34
+ renderResult: RenderResult
35
+ prettyPrint: () => void
36
+ reconnect: () => void
37
+ disconnect: () => void
38
+ }
39
+ export type RealtimeTestServer = RealtimeTestTools & {
40
+ port: number
41
+ }
42
+
43
+ export type RealtimeTestAPI = {
44
+ server: RealtimeTestServer
45
+ teardown: () => void
46
+ }
47
+ export type RealtimeTestAPI__SingleClient = RealtimeTestAPI & {
48
+ client: RealtimeTestClient
49
+ }
50
+ export type RealtimeTestAPI__MultiClient<ClientNames extends string> =
51
+ RealtimeTestAPI & {
52
+ clients: Record<ClientNames, RealtimeTestClient>
53
+ }
54
+
55
+ export const setupRealtimeTestServer = (
56
+ options: TestSetupOptions,
57
+ ): RealtimeTestServer => {
58
+ const httpServer = http.createServer((_, res) => res.end(`Hello World!`))
59
+ const address = httpServer.listen().address()
60
+ const port =
61
+ typeof address === `string` ? 80 : address === null ? null : address.port
62
+ if (port === null) throw new Error(`Could not determine port for test server`)
63
+ const server = new SocketIO.Server(httpServer)
64
+ const silo = AtomIO.silo(`SERVER`, AtomIO.__INTERNAL__.IMPLICIT.STORE)
65
+
66
+ server.on(`connection`, (socket: SocketIO.Socket) => {
67
+ options.server({ socket, silo })
68
+ })
69
+
70
+ const dispose = () => {
71
+ server.close()
72
+ AtomIO.__INTERNAL__.clearStore(silo.store)
73
+ }
74
+
75
+ return {
76
+ name: `SERVER`,
77
+ silo,
78
+ dispose,
79
+ port,
80
+ }
81
+ }
82
+ export const setupRealtimeTestClient = (
83
+ options: TestSetupOptions__SingleClient,
84
+ name: string,
85
+ port: number,
86
+ ): RealtimeTestClient => {
87
+ const socket: ClientSocket = io(`http://localhost:${port}/`)
88
+ const silo = AtomIO.silo(name, AtomIO.__INTERNAL__.IMPLICIT.STORE)
89
+
90
+ const { document } = new Happy.Window()
91
+ document.body.innerHTML = `<div id="app"></div>`
92
+ const renderResult = render(
93
+ <AR.StoreProvider store={silo.store}>
94
+ <RTC.RealtimeProvider socket={socket}>
95
+ <options.client />
96
+ </RTC.RealtimeProvider>
97
+ </AR.StoreProvider>,
98
+ {
99
+ container: document.querySelector(`#app`) as unknown as HTMLElement,
100
+ },
101
+ )
102
+
103
+ const prettyPrint = () => console.log(prettyDOM(renderResult.container))
104
+
105
+ const disconnect = () => socket.disconnect()
106
+ const reconnect = () => socket.connect()
107
+
108
+ const dispose = () => {
109
+ socket.disconnect()
110
+ AtomIO.__INTERNAL__.clearStore(silo.store)
111
+ }
112
+
113
+ return {
114
+ name,
115
+ silo,
116
+ renderResult,
117
+ prettyPrint,
118
+ disconnect,
119
+ reconnect,
120
+ dispose,
121
+ }
122
+ }
123
+
124
+ export const singleClient = (
125
+ options: TestSetupOptions__SingleClient,
126
+ ): RealtimeTestAPI__SingleClient => {
127
+ const server = setupRealtimeTestServer(options)
128
+ const client = setupRealtimeTestClient(options, `CLIENT`, server.port)
129
+
130
+ return {
131
+ client,
132
+ server,
133
+ teardown: () => {
134
+ client.dispose()
135
+ server.dispose()
136
+ },
137
+ }
138
+ }
139
+
140
+ export const multiClient = <ClientNames extends string>(
141
+ options: TestSetupOptions__MultiClient<ClientNames>,
142
+ ): RealtimeTestAPI__MultiClient<ClientNames> => {
143
+ const server = setupRealtimeTestServer(options)
144
+ const clients = RR.toEntries(options.clients).reduce(
145
+ (clients, [name, client]) => ({
146
+ ...clients,
147
+ [name]: setupRealtimeTestClient({ ...options, client }, name, server.port),
148
+ }),
149
+ {} as Record<ClientNames, RealtimeTestClient>,
150
+ )
151
+
152
+ return {
153
+ clients,
154
+ server,
155
+ teardown: () => {
156
+ RR.toEntries(clients).forEach(([, client]) => client.dispose())
157
+ server.dispose()
158
+ },
159
+ }
160
+ }
package/src/selector.ts CHANGED
@@ -7,59 +7,59 @@ import { selectorFamily__INTERNAL, selector__INTERNAL } from "./internal"
7
7
  import type { Read, Write } from "./transaction"
8
8
 
9
9
  export type SelectorOptions<T> = {
10
- key: string
11
- get: Read<() => T>
12
- set: Write<(newValue: T) => void>
10
+ key: string
11
+ get: Read<() => T>
12
+ set: Write<(newValue: T) => void>
13
13
  }
14
14
  export type ReadonlySelectorOptions<T> = {
15
- key: string
16
- get: Read<() => T>
15
+ key: string
16
+ get: Read<() => T>
17
17
  }
18
18
 
19
19
  export function selector<T>(options: SelectorOptions<T>): SelectorToken<T>
20
20
  export function selector<T>(
21
- options: ReadonlySelectorOptions<T>
21
+ options: ReadonlySelectorOptions<T>,
22
22
  ): ReadonlySelectorToken<T>
23
23
  export function selector<T>(
24
- options: ReadonlySelectorOptions<T> | SelectorOptions<T>
24
+ options: ReadonlySelectorOptions<T> | SelectorOptions<T>,
25
25
  ): ReadonlySelectorToken<T> | SelectorToken<T> {
26
- return selector__INTERNAL(options)
26
+ return selector__INTERNAL(options)
27
27
  }
28
28
 
29
29
  export type SelectorFamilyOptions<T, K extends Serializable> = {
30
- key: string
31
- get: (key: K) => Read<() => T>
32
- set: (key: K) => Write<(newValue: T) => void>
30
+ key: string
31
+ get: (key: K) => Read<() => T>
32
+ set: (key: K) => Write<(newValue: T) => void>
33
33
  }
34
34
  export type ReadonlySelectorFamilyOptions<T, K extends Serializable> = {
35
- key: string
36
- get: (key: K) => Read<() => T>
35
+ key: string
36
+ get: (key: K) => Read<() => T>
37
37
  }
38
38
 
39
39
  export type SelectorFamily<T, K extends Serializable = Serializable> = ((
40
- key: K
40
+ key: K,
41
41
  ) => SelectorToken<T>) & {
42
- key: string
43
- type: `selector_family`
44
- subject: Rx.Subject<SelectorToken<T>>
42
+ key: string
43
+ type: `selector_family`
44
+ subject: Rx.Subject<SelectorToken<T>>
45
45
  }
46
46
 
47
47
  export type ReadonlySelectorFamily<T, K extends Serializable = Serializable> = ((
48
- key: K
48
+ key: K,
49
49
  ) => ReadonlySelectorToken<T>) & {
50
- key: string
51
- type: `readonly_selector_family`
52
- subject: Rx.Subject<ReadonlySelectorToken<T>>
50
+ key: string
51
+ type: `readonly_selector_family`
52
+ subject: Rx.Subject<ReadonlySelectorToken<T>>
53
53
  }
54
54
 
55
55
  export function selectorFamily<T, K extends Serializable>(
56
- options: SelectorFamilyOptions<T, K>
56
+ options: SelectorFamilyOptions<T, K>,
57
57
  ): SelectorFamily<T, K>
58
58
  export function selectorFamily<T, K extends Serializable>(
59
- options: ReadonlySelectorFamilyOptions<T, K>
59
+ options: ReadonlySelectorFamilyOptions<T, K>,
60
60
  ): ReadonlySelectorFamily<T, K>
61
61
  export function selectorFamily<T, K extends Serializable>(
62
- options: ReadonlySelectorFamilyOptions<T, K> | SelectorFamilyOptions<T, K>
62
+ options: ReadonlySelectorFamilyOptions<T, K> | SelectorFamilyOptions<T, K>,
63
63
  ): ReadonlySelectorFamily<T, K> | SelectorFamily<T, K> {
64
- return selectorFamily__INTERNAL(options)
64
+ return selectorFamily__INTERNAL(options)
65
65
  }
package/src/silo.ts CHANGED
@@ -3,15 +3,15 @@ import { getState, setState, subscribe } from "."
3
3
  import type { atom, atomFamily } from "./atom"
4
4
  import type { Store } from "./internal"
5
5
  import {
6
- atomFamily__INTERNAL,
7
- atom__INTERNAL,
8
- createStore,
9
- redo__INTERNAL,
10
- selectorFamily__INTERNAL,
11
- selector__INTERNAL,
12
- timeline__INTERNAL,
13
- transaction__INTERNAL,
14
- undo__INTERNAL,
6
+ atomFamily__INTERNAL,
7
+ atom__INTERNAL,
8
+ createStore,
9
+ redo__INTERNAL,
10
+ selectorFamily__INTERNAL,
11
+ selector__INTERNAL,
12
+ timeline__INTERNAL,
13
+ transaction__INTERNAL,
14
+ undo__INTERNAL,
15
15
  } from "./internal"
16
16
  import type { selector, selectorFamily } from "./selector"
17
17
  import type { transaction } from "./transaction"
@@ -19,35 +19,35 @@ import type { transaction } from "./transaction"
19
19
  export type Silo = ReturnType<typeof silo>
20
20
 
21
21
  export const silo = (
22
- name: string,
23
- fromStore: Store | null = null
22
+ name: string,
23
+ fromStore: Store | null = null,
24
24
  ): {
25
- store: Store
26
- atom: typeof atom
27
- atomFamily: typeof atomFamily
28
- selector: typeof selector
29
- selectorFamily: typeof selectorFamily
30
- transaction: typeof transaction
31
- timeline: typeof timeline
32
- getState: typeof getState
33
- setState: typeof setState
34
- subscribe: typeof subscribe
35
- undo: typeof undo
36
- redo: typeof redo
25
+ store: Store
26
+ atom: typeof atom
27
+ atomFamily: typeof atomFamily
28
+ selector: typeof selector
29
+ selectorFamily: typeof selectorFamily
30
+ transaction: typeof transaction
31
+ timeline: typeof timeline
32
+ getState: typeof getState
33
+ setState: typeof setState
34
+ subscribe: typeof subscribe
35
+ undo: typeof undo
36
+ redo: typeof redo
37
37
  } => {
38
- const store = createStore(name, fromStore)
39
- return {
40
- store,
41
- atom: (options) => atom__INTERNAL(options, undefined, store),
42
- atomFamily: (options) => atomFamily__INTERNAL(options, store),
43
- selector: (options) => selector__INTERNAL(options, undefined, store) as any,
44
- selectorFamily: (options) => selectorFamily__INTERNAL(options, store) as any,
45
- transaction: (options) => transaction__INTERNAL(options, store),
46
- timeline: (options) => timeline__INTERNAL(options, store),
47
- getState: (token) => getState(token, store),
48
- setState: (token, newValue) => setState(token, newValue, store),
49
- subscribe: (token, handler) => subscribe(token, handler, store),
50
- undo: (token) => undo__INTERNAL(token, store),
51
- redo: (token) => redo__INTERNAL(token, store),
52
- }
38
+ const store = createStore(name, fromStore)
39
+ return {
40
+ store,
41
+ atom: (options) => atom__INTERNAL(options, undefined, store),
42
+ atomFamily: (options) => atomFamily__INTERNAL(options, store),
43
+ selector: (options) => selector__INTERNAL(options, undefined, store) as any,
44
+ selectorFamily: (options) => selectorFamily__INTERNAL(options, store) as any,
45
+ transaction: (options) => transaction__INTERNAL(options, store),
46
+ timeline: (options) => timeline__INTERNAL(options, store),
47
+ getState: (token) => getState(token, store),
48
+ setState: (token, newValue) => setState(token, newValue, store),
49
+ subscribe: (token, handler) => subscribe(token, handler, store),
50
+ undo: (token) => undo__INTERNAL(token, store),
51
+ redo: (token) => redo__INTERNAL(token, store),
52
+ }
53
53
  }
package/src/subscribe.ts CHANGED
@@ -1,12 +1,12 @@
1
1
  import type { ƒn } from "~/packages/anvl/src/function"
2
2
 
3
3
  import type {
4
- ReadonlySelectorToken,
5
- StateToken,
6
- TimelineToken,
7
- TimelineUpdate,
8
- TransactionToken,
9
- TransactionUpdate,
4
+ ReadonlySelectorToken,
5
+ StateToken,
6
+ TimelineToken,
7
+ TimelineUpdate,
8
+ TransactionToken,
9
+ TransactionUpdate,
10
10
  } from "."
11
11
  import type { Store } from "./internal"
12
12
  import { IMPLICIT, subscribeToRootAtoms, withdraw } from "./internal"
@@ -16,80 +16,80 @@ export type KeyedStateUpdate<T> = StateUpdate<T> & { key: string }
16
16
  export type UpdateHandler<T> = (update: StateUpdate<T>) => void
17
17
 
18
18
  export const subscribe = <T>(
19
- token: ReadonlySelectorToken<T> | StateToken<T>,
20
- handleUpdate: UpdateHandler<T>,
21
- store: Store = IMPLICIT.STORE
19
+ token: ReadonlySelectorToken<T> | StateToken<T>,
20
+ handleUpdate: UpdateHandler<T>,
21
+ store: Store = IMPLICIT.STORE,
22
22
  ): (() => void) => {
23
- const state = withdraw<T>(token, store)
24
- if (state === null) {
25
- throw new Error(
26
- `State "${token.key}" not found in this store. Did you forget to initialize with the "atom" or "selector" function?`
27
- )
28
- }
29
- const subscription = state.subject.subscribe(handleUpdate)
30
- store.config.logger?.info(`👀 subscribe to "${state.key}"`)
31
- const dependencySubscriptions =
32
- state.type !== `atom` ? subscribeToRootAtoms(state, store) : null
23
+ const state = withdraw<T>(token, store)
24
+ if (state === null) {
25
+ throw new Error(
26
+ `State "${token.key}" not found in this store. Did you forget to initialize with the "atom" or "selector" function?`,
27
+ )
28
+ }
29
+ const subscription = state.subject.subscribe(handleUpdate)
30
+ store.config.logger?.info(`👀 subscribe to "${state.key}"`)
31
+ const dependencySubscriptions =
32
+ state.type !== `atom` ? subscribeToRootAtoms(state, store) : null
33
33
 
34
- const unsubscribe =
35
- dependencySubscriptions === null
36
- ? () => {
37
- store.config.logger?.info(`🙈 unsubscribe from "${state.key}"`)
38
- subscription.unsubscribe()
39
- }
40
- : () => {
41
- store.config.logger?.info(
42
- `🙈 unsubscribe from "${state.key}" and its dependencies`
43
- )
44
- subscription.unsubscribe()
45
- for (const dependencySubscription of dependencySubscriptions) {
46
- dependencySubscription.unsubscribe()
47
- }
48
- }
34
+ const unsubscribe =
35
+ dependencySubscriptions === null
36
+ ? () => {
37
+ store.config.logger?.info(`🙈 unsubscribe from "${state.key}"`)
38
+ subscription.unsubscribe()
39
+ }
40
+ : () => {
41
+ store.config.logger?.info(
42
+ `🙈 unsubscribe from "${state.key}" and its dependencies`,
43
+ )
44
+ subscription.unsubscribe()
45
+ for (const dependencySubscription of dependencySubscriptions) {
46
+ dependencySubscription.unsubscribe()
47
+ }
48
+ }
49
49
 
50
- return unsubscribe
50
+ return unsubscribe
51
51
  }
52
52
 
53
53
  export type TransactionUpdateHandler<ƒ extends ƒn> = (
54
- data: TransactionUpdate<ƒ>
54
+ data: TransactionUpdate<ƒ>,
55
55
  ) => void
56
56
 
57
57
  export const subscribeToTransaction = <ƒ extends ƒn>(
58
- token: TransactionToken<ƒ>,
59
- handleUpdate: TransactionUpdateHandler<ƒ>,
60
- store = IMPLICIT.STORE
58
+ token: TransactionToken<ƒ>,
59
+ handleUpdate: TransactionUpdateHandler<ƒ>,
60
+ store = IMPLICIT.STORE,
61
61
  ): (() => void) => {
62
- const tx = withdraw(token, store)
63
- if (tx === null) {
64
- throw new Error(
65
- `Cannot subscribe to transaction "${token.key}": transaction not found in store "${store.config.name}".`
66
- )
67
- }
68
- store.config.logger?.info(`👀 subscribe to transaction "${token.key}"`)
69
- const subscription = tx.subject.subscribe(handleUpdate)
70
- const unsubscribe = () => {
71
- store.config.logger?.info(`🙈 unsubscribe from transaction "${token.key}"`)
72
- subscription.unsubscribe()
73
- }
74
- return unsubscribe
62
+ const tx = withdraw(token, store)
63
+ if (tx === null) {
64
+ throw new Error(
65
+ `Cannot subscribe to transaction "${token.key}": transaction not found in store "${store.config.name}".`,
66
+ )
67
+ }
68
+ store.config.logger?.info(`👀 subscribe to transaction "${token.key}"`)
69
+ const subscription = tx.subject.subscribe(handleUpdate)
70
+ const unsubscribe = () => {
71
+ store.config.logger?.info(`🙈 unsubscribe from transaction "${token.key}"`)
72
+ subscription.unsubscribe()
73
+ }
74
+ return unsubscribe
75
75
  }
76
76
 
77
77
  export const subscribeToTimeline = (
78
- token: TimelineToken,
79
- handleUpdate: (update: TimelineUpdate) => void,
80
- store = IMPLICIT.STORE
78
+ token: TimelineToken,
79
+ handleUpdate: (update: TimelineUpdate) => void,
80
+ store = IMPLICIT.STORE,
81
81
  ): (() => void) => {
82
- const tl = withdraw(token, store)
83
- if (tl === null) {
84
- throw new Error(
85
- `Cannot subscribe to timeline "${token.key}": timeline not found in store "${store.config.name}".`
86
- )
87
- }
88
- store.config.logger?.info(`👀 subscribe to timeline "${token.key}"`)
89
- const subscription = tl.subject.subscribe(handleUpdate)
90
- const unsubscribe = () => {
91
- store.config.logger?.info(`🙈 unsubscribe from timeline "${token.key}"`)
92
- subscription.unsubscribe()
93
- }
94
- return unsubscribe
82
+ const tl = withdraw(token, store)
83
+ if (tl === null) {
84
+ throw new Error(
85
+ `Cannot subscribe to timeline "${token.key}": timeline not found in store "${store.config.name}".`,
86
+ )
87
+ }
88
+ store.config.logger?.info(`👀 subscribe to timeline "${token.key}"`)
89
+ const subscription = tl.subject.subscribe(handleUpdate)
90
+ const unsubscribe = () => {
91
+ store.config.logger?.info(`🙈 unsubscribe from timeline "${token.key}"`)
92
+ subscription.unsubscribe()
93
+ }
94
+ return unsubscribe
95
95
  }
package/src/timeline.ts CHANGED
@@ -1,35 +1,35 @@
1
1
  import type { AtomFamily, AtomToken } from "."
2
2
  import type {
3
- TimelineAtomUpdate,
4
- TimelineSelectorUpdate,
5
- TimelineTransactionUpdate,
3
+ TimelineAtomUpdate,
4
+ TimelineSelectorUpdate,
5
+ TimelineTransactionUpdate,
6
6
  } from "./internal"
7
7
  import { IMPLICIT } from "./internal"
8
8
  import { redo__INTERNAL, timeline__INTERNAL, undo__INTERNAL } from "./internal/"
9
9
 
10
10
  export type TimelineToken = {
11
- key: string
12
- type: `timeline`
11
+ key: string
12
+ type: `timeline`
13
13
  }
14
14
 
15
15
  export type TimelineOptions = {
16
- key: string
17
- atoms: (AtomFamily<any, any> | AtomToken<any>)[]
16
+ key: string
17
+ atoms: (AtomFamily<any, any> | AtomToken<any>)[]
18
18
  }
19
19
 
20
20
  export type TimelineUpdate =
21
- | TimelineAtomUpdate
22
- | TimelineSelectorUpdate
23
- | TimelineTransactionUpdate
21
+ | TimelineAtomUpdate
22
+ | TimelineSelectorUpdate
23
+ | TimelineTransactionUpdate
24
24
 
25
25
  export const timeline = (options: TimelineOptions): TimelineToken => {
26
- return timeline__INTERNAL(options)
26
+ return timeline__INTERNAL(options)
27
27
  }
28
28
 
29
29
  export const redo = (token: TimelineToken): void => {
30
- return redo__INTERNAL(token, IMPLICIT.STORE)
30
+ redo__INTERNAL(token, IMPLICIT.STORE)
31
31
  }
32
32
 
33
33
  export const undo = (token: TimelineToken): void => {
34
- return undo__INTERNAL(token, IMPLICIT.STORE)
34
+ undo__INTERNAL(token, IMPLICIT.STORE)
35
35
  }