atom.io 0.6.1 → 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 (90) hide show
  1. package/dist/index.d.mts +3 -3
  2. package/dist/index.d.ts +3 -3
  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.js.map +1 -1
  8. package/json/dist/index.mjs.map +1 -1
  9. package/package.json +13 -3
  10. package/react/dist/index.js.map +1 -1
  11. package/react/dist/index.mjs.map +1 -1
  12. package/react-devtools/dist/index.js +32 -18
  13. package/react-devtools/dist/index.js.map +1 -1
  14. package/react-devtools/dist/index.mjs +32 -18
  15. package/react-devtools/dist/index.mjs.map +1 -1
  16. package/realtime/dist/index.js.map +1 -1
  17. package/realtime/dist/index.mjs.map +1 -1
  18. package/realtime-react/dist/index.js.map +1 -1
  19. package/realtime-react/dist/index.mjs.map +1 -1
  20. package/realtime-testing/dist/index.d.mts +49 -0
  21. package/realtime-testing/dist/index.d.ts +49 -0
  22. package/realtime-testing/dist/index.js +153 -0
  23. package/realtime-testing/dist/index.js.map +1 -0
  24. package/realtime-testing/dist/index.mjs +117 -0
  25. package/realtime-testing/dist/index.mjs.map +1 -0
  26. package/realtime-testing/package.json +15 -0
  27. package/src/atom.ts +15 -15
  28. package/src/index.ts +59 -59
  29. package/src/internal/atom-internal.ts +36 -36
  30. package/src/internal/families-internal.ts +114 -114
  31. package/src/internal/get.ts +83 -83
  32. package/src/internal/is-default.ts +17 -17
  33. package/src/internal/meta/attach-meta.ts +7 -7
  34. package/src/internal/meta/meta-state.ts +115 -115
  35. package/src/internal/operation.ts +93 -93
  36. package/src/internal/selector/create-read-write-selector.ts +46 -46
  37. package/src/internal/selector/create-readonly-selector.ts +37 -37
  38. package/src/internal/selector/lookup-selector-sources.ts +9 -9
  39. package/src/internal/selector/register-selector.ts +44 -44
  40. package/src/internal/selector/trace-selector-atoms.ts +30 -30
  41. package/src/internal/selector/update-selector-atoms.ts +25 -25
  42. package/src/internal/selector-internal.ts +37 -37
  43. package/src/internal/set.ts +78 -78
  44. package/src/internal/store.ts +118 -118
  45. package/src/internal/subscribe-internal.ts +62 -62
  46. package/src/internal/time-travel-internal.ts +76 -76
  47. package/src/internal/timeline/add-atom-to-timeline.ts +158 -153
  48. package/src/internal/timeline-internal.ts +80 -80
  49. package/src/internal/transaction/abort-transaction.ts +8 -8
  50. package/src/internal/transaction/apply-transaction.ts +41 -41
  51. package/src/internal/transaction/build-transaction.ts +28 -28
  52. package/src/internal/transaction/index.ts +7 -7
  53. package/src/internal/transaction/redo-transaction.ts +13 -13
  54. package/src/internal/transaction/undo-transaction.ts +13 -13
  55. package/src/internal/transaction-internal.ts +48 -48
  56. package/src/json/select-json.ts +12 -12
  57. package/src/logger.ts +30 -30
  58. package/src/react/store-context.tsx +4 -4
  59. package/src/react/store-hooks.ts +18 -18
  60. package/src/react-devtools/AtomIODevtools.tsx +83 -82
  61. package/src/react-devtools/StateEditor.tsx +53 -53
  62. package/src/react-devtools/TokenList.tsx +47 -42
  63. package/src/react-explorer/AtomIOExplorer.tsx +197 -185
  64. package/src/react-explorer/explorer-effects.ts +11 -11
  65. package/src/react-explorer/explorer-states.ts +186 -193
  66. package/src/react-explorer/index.ts +11 -11
  67. package/src/react-explorer/space-states.ts +48 -50
  68. package/src/react-explorer/view-states.ts +25 -25
  69. package/src/realtime/hook-composition/expose-family.ts +81 -81
  70. package/src/realtime/hook-composition/expose-single.ts +26 -26
  71. package/src/realtime/hook-composition/expose-timeline.ts +60 -0
  72. package/src/realtime/hook-composition/index.ts +2 -2
  73. package/src/realtime/hook-composition/receive-state.ts +18 -18
  74. package/src/realtime/hook-composition/receive-transaction.ts +8 -8
  75. package/src/realtime-react/realtime-context.tsx +17 -17
  76. package/src/realtime-react/realtime-hooks.ts +17 -17
  77. package/src/realtime-react/realtime-state.ts +4 -4
  78. package/src/realtime-react/use-pull-family-member.ts +15 -15
  79. package/src/realtime-react/use-pull-family.ts +13 -13
  80. package/src/realtime-react/use-pull.ts +12 -12
  81. package/src/realtime-react/use-push.ts +15 -15
  82. package/src/realtime-react/use-server-action.ts +21 -21
  83. package/src/realtime-testing/index.ts +1 -0
  84. package/src/realtime-testing/setup-realtime-test.tsx +160 -0
  85. package/src/selector.ts +25 -25
  86. package/src/silo.ts +38 -38
  87. package/src/subscribe.ts +68 -68
  88. package/src/timeline.ts +13 -13
  89. package/src/transaction.ts +28 -28
  90. package/src/web-effects/storage.ts +17 -17
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/realtime-testing/setup-realtime-test.tsx"],"sourcesContent":["import * as http from \"http\"\n\nimport * as React from \"react\"\n\nimport { prettyDOM, render, type RenderResult } from \"@testing-library/react\"\nimport * as AtomIO from \"atom.io\"\nimport * as AR from \"atom.io/react\"\nimport * as RTC from \"atom.io/realtime-react\"\nimport * as RR from \"fp-ts/ReadonlyRecord\"\nimport * as Happy from \"happy-dom\"\nimport * as SocketIO from \"socket.io\"\nimport type { Socket as ClientSocket } from \"socket.io-client\"\nimport { io } from \"socket.io-client\"\n\nexport type TestSetupOptions = {\n\tserver: (tools: { socket: SocketIO.Socket; silo: AtomIO.Silo }) => void\n}\nexport type TestSetupOptions__SingleClient = TestSetupOptions & {\n\tclient: React.FC\n}\nexport type TestSetupOptions__MultiClient<ClientNames extends string> =\n\tTestSetupOptions & {\n\t\tclients: {\n\t\t\t[K in ClientNames]: React.FC\n\t\t}\n\t}\n\nexport type RealtimeTestTools = {\n\tname: string\n\tsilo: AtomIO.Silo\n\tdispose: () => void\n}\nexport type RealtimeTestClient = RealtimeTestTools & {\n\trenderResult: RenderResult\n\tprettyPrint: () => void\n\treconnect: () => void\n\tdisconnect: () => void\n}\nexport type RealtimeTestServer = RealtimeTestTools & {\n\tport: number\n}\n\nexport type RealtimeTestAPI = {\n\tserver: RealtimeTestServer\n\tteardown: () => void\n}\nexport type RealtimeTestAPI__SingleClient = RealtimeTestAPI & {\n\tclient: RealtimeTestClient\n}\nexport type RealtimeTestAPI__MultiClient<ClientNames extends string> =\n\tRealtimeTestAPI & {\n\t\tclients: Record<ClientNames, RealtimeTestClient>\n\t}\n\nexport const setupRealtimeTestServer = (\n\toptions: TestSetupOptions,\n): RealtimeTestServer => {\n\tconst httpServer = http.createServer((_, res) => res.end(`Hello World!`))\n\tconst address = httpServer.listen().address()\n\tconst port =\n\t\ttypeof address === `string` ? 80 : address === null ? null : address.port\n\tif (port === null) throw new Error(`Could not determine port for test server`)\n\tconst server = new SocketIO.Server(httpServer)\n\tconst silo = AtomIO.silo(`SERVER`, AtomIO.__INTERNAL__.IMPLICIT.STORE)\n\n\tserver.on(`connection`, (socket: SocketIO.Socket) => {\n\t\toptions.server({ socket, silo })\n\t})\n\n\tconst dispose = () => {\n\t\tserver.close()\n\t\tAtomIO.__INTERNAL__.clearStore(silo.store)\n\t}\n\n\treturn {\n\t\tname: `SERVER`,\n\t\tsilo,\n\t\tdispose,\n\t\tport,\n\t}\n}\nexport const setupRealtimeTestClient = (\n\toptions: TestSetupOptions__SingleClient,\n\tname: string,\n\tport: number,\n): RealtimeTestClient => {\n\tconst socket: ClientSocket = io(`http://localhost:${port}/`)\n\tconst silo = AtomIO.silo(name, AtomIO.__INTERNAL__.IMPLICIT.STORE)\n\n\tconst { document } = new Happy.Window()\n\tdocument.body.innerHTML = `<div id=\"app\"></div>`\n\tconst renderResult = render(\n\t\t<AR.StoreProvider store={silo.store}>\n\t\t\t<RTC.RealtimeProvider socket={socket}>\n\t\t\t\t<options.client />\n\t\t\t</RTC.RealtimeProvider>\n\t\t</AR.StoreProvider>,\n\t\t{\n\t\t\tcontainer: document.querySelector(`#app`) as unknown as HTMLElement,\n\t\t},\n\t)\n\n\tconst prettyPrint = () => console.log(prettyDOM(renderResult.container))\n\n\tconst disconnect = () => socket.disconnect()\n\tconst reconnect = () => socket.connect()\n\n\tconst dispose = () => {\n\t\tsocket.disconnect()\n\t\tAtomIO.__INTERNAL__.clearStore(silo.store)\n\t}\n\n\treturn {\n\t\tname,\n\t\tsilo,\n\t\trenderResult,\n\t\tprettyPrint,\n\t\tdisconnect,\n\t\treconnect,\n\t\tdispose,\n\t}\n}\n\nexport const singleClient = (\n\toptions: TestSetupOptions__SingleClient,\n): RealtimeTestAPI__SingleClient => {\n\tconst server = setupRealtimeTestServer(options)\n\tconst client = setupRealtimeTestClient(options, `CLIENT`, server.port)\n\n\treturn {\n\t\tclient,\n\t\tserver,\n\t\tteardown: () => {\n\t\t\tclient.dispose()\n\t\t\tserver.dispose()\n\t\t},\n\t}\n}\n\nexport const multiClient = <ClientNames extends string>(\n\toptions: TestSetupOptions__MultiClient<ClientNames>,\n): RealtimeTestAPI__MultiClient<ClientNames> => {\n\tconst server = setupRealtimeTestServer(options)\n\tconst clients = RR.toEntries(options.clients).reduce(\n\t\t(clients, [name, client]) => ({\n\t\t\t...clients,\n\t\t\t[name]: setupRealtimeTestClient({ ...options, client }, name, server.port),\n\t\t}),\n\t\t{} as Record<ClientNames, RealtimeTestClient>,\n\t)\n\n\treturn {\n\t\tclients,\n\t\tserver,\n\t\tteardown: () => {\n\t\t\tRR.toEntries(clients).forEach(([, client]) => client.dispose())\n\t\t\tserver.dispose()\n\t\t},\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAAA,YAAY,UAAU;AAItB,SAAS,WAAW,cAAiC;AACrD,YAAY,YAAY;AACxB,YAAY,QAAQ;AACpB,YAAY,SAAS;AACrB,YAAY,QAAQ;AACpB,YAAY,WAAW;AACvB,YAAY,cAAc;AAE1B,SAAS,UAAU;AAkFf;AAxCG,IAAM,0BAA0B,CACtC,YACwB;AACxB,QAAM,aAAkB,kBAAa,CAAC,GAAG,QAAQ,IAAI,IAAI,cAAc,CAAC;AACxE,QAAM,UAAU,WAAW,OAAO,EAAE,QAAQ;AAC5C,QAAM,OACL,OAAO,YAAY,WAAW,KAAK,YAAY,OAAO,OAAO,QAAQ;AACtE,MAAI,SAAS;AAAM,UAAM,IAAI,MAAM,0CAA0C;AAC7E,QAAM,SAAS,IAAa,gBAAO,UAAU;AAC7C,QAAMA,QAAc,YAAK,UAAiB,oBAAa,SAAS,KAAK;AAErE,SAAO,GAAG,cAAc,CAAC,WAA4B;AACpD,YAAQ,OAAO,EAAE,QAAQ,MAAAA,MAAK,CAAC;AAAA,EAChC,CAAC;AAED,QAAM,UAAU,MAAM;AACrB,WAAO,MAAM;AACb,IAAO,oBAAa,WAAWA,MAAK,KAAK;AAAA,EAC1C;AAEA,SAAO;AAAA,IACN,MAAM;AAAA,IACN,MAAAA;AAAA,IACA;AAAA,IACA;AAAA,EACD;AACD;AACO,IAAM,0BAA0B,CACtC,SACA,MACA,SACwB;AACxB,QAAM,SAAuB,GAAG,oBAAoB,IAAI,GAAG;AAC3D,QAAMA,QAAc,YAAK,MAAa,oBAAa,SAAS,KAAK;AAEjE,QAAM,EAAE,SAAS,IAAI,IAAU,aAAO;AACtC,WAAS,KAAK,YAAY;AAC1B,QAAM,eAAe;AAAA,IACpB,oBAAI,kBAAH,EAAiB,OAAOA,MAAK,OAC7B,8BAAK,sBAAJ,EAAqB,QACrB,8BAAC,QAAQ,QAAR,EAAe,GACjB,GACD;AAAA,IACA;AAAA,MACC,WAAW,SAAS,cAAc,MAAM;AAAA,IACzC;AAAA,EACD;AAEA,QAAM,cAAc,MAAM,QAAQ,IAAI,UAAU,aAAa,SAAS,CAAC;AAEvE,QAAM,aAAa,MAAM,OAAO,WAAW;AAC3C,QAAM,YAAY,MAAM,OAAO,QAAQ;AAEvC,QAAM,UAAU,MAAM;AACrB,WAAO,WAAW;AAClB,IAAO,oBAAa,WAAWA,MAAK,KAAK;AAAA,EAC1C;AAEA,SAAO;AAAA,IACN;AAAA,IACA,MAAAA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACD;AACD;AAEO,IAAM,eAAe,CAC3B,YACmC;AACnC,QAAM,SAAS,wBAAwB,OAAO;AAC9C,QAAM,SAAS,wBAAwB,SAAS,UAAU,OAAO,IAAI;AAErE,SAAO;AAAA,IACN;AAAA,IACA;AAAA,IACA,UAAU,MAAM;AACf,aAAO,QAAQ;AACf,aAAO,QAAQ;AAAA,IAChB;AAAA,EACD;AACD;AAEO,IAAM,cAAc,CAC1B,YAC+C;AAC/C,QAAM,SAAS,wBAAwB,OAAO;AAC9C,QAAM,UAAa,aAAU,QAAQ,OAAO,EAAE;AAAA,IAC7C,CAACC,UAAS,CAAC,MAAM,MAAM,MAAO,iCAC1BA,WAD0B;AAAA,MAE7B,CAAC,IAAI,GAAG,wBAAwB,iCAAK,UAAL,EAAc,OAAO,IAAG,MAAM,OAAO,IAAI;AAAA,IAC1E;AAAA,IACA,CAAC;AAAA,EACF;AAEA,SAAO;AAAA,IACN;AAAA,IACA;AAAA,IACA,UAAU,MAAM;AACf,MAAG,aAAU,OAAO,EAAE,QAAQ,CAAC,CAAC,EAAE,MAAM,MAAM,OAAO,QAAQ,CAAC;AAC9D,aAAO,QAAQ;AAAA,IAChB;AAAA,EACD;AACD;","names":["silo","clients"]}
@@ -0,0 +1,15 @@
1
+ {
2
+ "name": "atom.io-realtime-testing",
3
+ "private": true,
4
+ "main": "dist/index.js",
5
+ "types": "dist/index.d.ts",
6
+ "module": "dist/index.mjs",
7
+ "exports": {
8
+ ".": {
9
+ "types": "./dist/index.d.ts",
10
+ "browser": "./dist/index.mjs",
11
+ "import": "./dist/index.mjs",
12
+ "require": "./dist/index.js"
13
+ }
14
+ }
15
+ }
package/src/atom.ts CHANGED
@@ -6,38 +6,38 @@ import type { AtomToken } from "."
6
6
  import { atomFamily__INTERNAL, atom__INTERNAL } from "./internal"
7
7
 
8
8
  export type Effectors<T> = {
9
- setSelf: <V extends T>(next: V | ((oldValue: T) => V)) => void
10
- onSet: (callback: (options: { newValue: T; oldValue: T }) => void) => void
9
+ setSelf: <V extends T>(next: V | ((oldValue: T) => V)) => void
10
+ onSet: (callback: (options: { newValue: T; oldValue: T }) => void) => void
11
11
  }
12
12
 
13
13
  export type AtomEffect<T> = (tools: Effectors<T>) => void
14
14
 
15
15
  export type AtomOptions<T> = {
16
- key: string
17
- default: T | (() => T)
18
- effects?: AtomEffect<T>[]
16
+ key: string
17
+ default: T | (() => T)
18
+ effects?: AtomEffect<T>[]
19
19
  }
20
20
 
21
21
  export function atom<T>(options: AtomOptions<T>): AtomToken<T> {
22
- return atom__INTERNAL<T>(options)
22
+ return atom__INTERNAL<T>(options)
23
23
  }
24
24
 
25
25
  export type AtomFamilyOptions<T, K extends Serializable> = {
26
- key: string
27
- default: T | ((key: K) => T)
28
- effects?: (key: K) => AtomEffect<T>[]
26
+ key: string
27
+ default: T | ((key: K) => T)
28
+ effects?: (key: K) => AtomEffect<T>[]
29
29
  }
30
30
 
31
31
  export type AtomFamily<T, K extends Serializable = Serializable> = ((
32
- key: K
32
+ key: K,
33
33
  ) => AtomToken<T>) & {
34
- key: string
35
- type: `atom_family`
36
- subject: Rx.Subject<AtomToken<T>>
34
+ key: string
35
+ type: `atom_family`
36
+ subject: Rx.Subject<AtomToken<T>>
37
37
  }
38
38
 
39
39
  export function atomFamily<T, K extends Serializable>(
40
- options: AtomFamilyOptions<T, K>
40
+ options: AtomFamilyOptions<T, K>,
41
41
  ): AtomFamily<T, K> {
42
- return atomFamily__INTERNAL<T, K>(options)
42
+ return atomFamily__INTERNAL<T, K>(options)
43
43
  }
package/src/index.ts CHANGED
@@ -1,14 +1,14 @@
1
1
  import { capitalize } from "~/packages/anvl/src/string/capitalize"
2
2
 
3
3
  import {
4
- IMPLICIT,
5
- closeOperation,
6
- openOperation,
7
- getState__INTERNAL,
8
- setState__INTERNAL,
9
- isAtomDefault,
10
- isSelectorDefault,
11
- withdraw,
4
+ IMPLICIT,
5
+ closeOperation,
6
+ openOperation,
7
+ getState__INTERNAL,
8
+ setState__INTERNAL,
9
+ isAtomDefault,
10
+ isSelectorDefault,
11
+ withdraw,
12
12
  } from "./internal"
13
13
  import * as __INTERNAL__ from "./internal"
14
14
  import type { Store } from "./internal/store"
@@ -25,75 +25,75 @@ export type { Store } from "./internal/store"
25
25
  export type { Serializable } from "~/packages/anvl/src/json"
26
26
 
27
27
  export type AtomToken<_> = {
28
- key: string
29
- type: `atom`
30
- family?: FamilyMetadata
31
- __brand?: _
28
+ key: string
29
+ type: `atom`
30
+ family?: FamilyMetadata
31
+ __brand?: _
32
32
  }
33
33
  export type SelectorToken<_> = {
34
- key: string
35
- type: `selector`
36
- family?: FamilyMetadata
37
- __brand?: _
34
+ key: string
35
+ type: `selector`
36
+ family?: FamilyMetadata
37
+ __brand?: _
38
38
  }
39
39
  export type StateToken<T> = AtomToken<T> | SelectorToken<T>
40
40
 
41
41
  export type ReadonlySelectorToken<_> = {
42
- key: string
43
- type: `readonly_selector`
44
- family?: FamilyMetadata
45
- __brand?: _
42
+ key: string
43
+ type: `readonly_selector`
44
+ family?: FamilyMetadata
45
+ __brand?: _
46
46
  }
47
47
 
48
48
  export type FamilyMetadata = {
49
- key: string
50
- subKey: string
49
+ key: string
50
+ subKey: string
51
51
  }
52
52
 
53
53
  export const getState = <T>(
54
- token: ReadonlySelectorToken<T> | StateToken<T>,
55
- store: Store = IMPLICIT.STORE
54
+ token: ReadonlySelectorToken<T> | StateToken<T>,
55
+ store: Store = IMPLICIT.STORE,
56
56
  ): T => {
57
- const state = withdraw<T>(token, store)
58
- if (state === null) {
59
- throw new Error(
60
- `${capitalize(token.type)} "${token.key}" not found in store "${
61
- store.config.name
62
- }".`
63
- )
64
- }
65
- return getState__INTERNAL(state, store)
57
+ const state = withdraw<T>(token, store)
58
+ if (state === null) {
59
+ throw new Error(
60
+ `${capitalize(token.type)} "${token.key}" not found in store "${
61
+ store.config.name
62
+ }".`,
63
+ )
64
+ }
65
+ return getState__INTERNAL(state, store)
66
66
  }
67
67
 
68
68
  export const setState = <T, New extends T>(
69
- token: StateToken<T>,
70
- value: New | ((oldValue: T) => New),
71
- store: Store = IMPLICIT.STORE
69
+ token: StateToken<T>,
70
+ value: New | ((oldValue: T) => New),
71
+ store: Store = IMPLICIT.STORE,
72
72
  ): void => {
73
- try {
74
- openOperation(token, store)
75
- } catch (thrown) {
76
- if (!(typeof thrown === `symbol`)) {
77
- throw thrown
78
- }
79
- return
80
- }
81
- const state = withdraw(token, store)
82
- if (state === null) {
83
- throw new Error(
84
- `${capitalize(token.type)} "${token.key}" not found in store "${
85
- store.config.name
86
- }".`
87
- )
88
- }
89
- setState__INTERNAL(state, value, store)
90
- closeOperation(store)
73
+ try {
74
+ openOperation(token, store)
75
+ } catch (thrown) {
76
+ if (!(typeof thrown === `symbol`)) {
77
+ throw thrown
78
+ }
79
+ return
80
+ }
81
+ const state = withdraw(token, store)
82
+ if (state === null) {
83
+ throw new Error(
84
+ `${capitalize(token.type)} "${token.key}" not found in store "${
85
+ store.config.name
86
+ }".`,
87
+ )
88
+ }
89
+ setState__INTERNAL(state, value, store)
90
+ closeOperation(store)
91
91
  }
92
92
 
93
93
  export const isDefault = (
94
- token: ReadonlySelectorToken<unknown> | StateToken<unknown>,
95
- store: Store = IMPLICIT.STORE
94
+ token: ReadonlySelectorToken<unknown> | StateToken<unknown>,
95
+ store: Store = IMPLICIT.STORE,
96
96
  ): boolean =>
97
- token.type === `atom`
98
- ? isAtomDefault(token.key, store)
99
- : isSelectorDefault(token.key, store)
97
+ token.type === `atom`
98
+ ? isAtomDefault(token.key, store)
99
+ : isSelectorDefault(token.key, store)
@@ -12,44 +12,44 @@ import { setState, subscribe } from ".."
12
12
  import type { AtomOptions } from "../atom"
13
13
 
14
14
  export type Atom<T> = {
15
- key: string
16
- type: `atom`
17
- family?: FamilyMetadata
18
- subject: Rx.Subject<{ newValue: T; oldValue: T }>
19
- default: T
15
+ key: string
16
+ type: `atom`
17
+ family?: FamilyMetadata
18
+ subject: Rx.Subject<{ newValue: T; oldValue: T }>
19
+ default: T
20
20
  }
21
21
 
22
22
  export function atom__INTERNAL<T>(
23
- options: AtomOptions<T>,
24
- family?: FamilyMetadata,
25
- store: Store = IMPLICIT.STORE
23
+ options: AtomOptions<T>,
24
+ family?: FamilyMetadata,
25
+ store: Store = IMPLICIT.STORE,
26
26
  ): AtomToken<T> {
27
- const core = target(store)
28
- if (hasKeyBeenUsed(options.key, store)) {
29
- store.config.logger?.error?.(
30
- `Key "${options.key}" already exists in the store.`
31
- )
32
- return deposit(core.atoms.get(options.key))
33
- }
34
- const subject = new Rx.Subject<{ newValue: T; oldValue: T }>()
35
- const newAtom = {
36
- ...options,
37
- subject,
38
- type: `atom`,
39
- ...(family && { family }),
40
- } as const
41
- const initialValue =
42
- options.default instanceof Function ? options.default() : options.default
43
- core.atoms = HAMT.set(newAtom.key, newAtom, core.atoms)
44
- markAtomAsDefault(options.key, store)
45
- cacheValue(options.key, initialValue, store)
46
- const token = deposit(newAtom)
47
- options.effects?.forEach((effect) =>
48
- effect({
49
- setSelf: (next) => setState(token, next, store),
50
- onSet: (handle: UpdateHandler<T>) => subscribe(token, handle, store),
51
- })
52
- )
53
- store.subject.atomCreation.next(token)
54
- return token as AtomToken<T>
27
+ const core = target(store)
28
+ if (hasKeyBeenUsed(options.key, store)) {
29
+ store.config.logger?.error?.(
30
+ `Key "${options.key}" already exists in the store.`,
31
+ )
32
+ return deposit(core.atoms.get(options.key))
33
+ }
34
+ const subject = new Rx.Subject<{ newValue: T; oldValue: T }>()
35
+ const newAtom = {
36
+ ...options,
37
+ subject,
38
+ type: `atom`,
39
+ ...(family && { family }),
40
+ } as const
41
+ const initialValue =
42
+ options.default instanceof Function ? options.default() : options.default
43
+ core.atoms = HAMT.set(newAtom.key, newAtom, core.atoms)
44
+ markAtomAsDefault(options.key, store)
45
+ cacheValue(options.key, initialValue, store)
46
+ const token = deposit(newAtom)
47
+ options.effects?.forEach((effect) =>
48
+ effect({
49
+ setSelf: (next) => setState(token, next, store),
50
+ onSet: (handle: UpdateHandler<T>) => subscribe(token, handle, store),
51
+ }),
52
+ )
53
+ store.subject.atomCreation.next(token)
54
+ return token as AtomToken<T>
55
55
  }
@@ -5,138 +5,138 @@ import { stringifyJson } from "~/packages/anvl/src/json"
5
5
 
6
6
  import type { Store } from "."
7
7
  import {
8
- atom__INTERNAL,
9
- withdraw,
10
- selector__INTERNAL,
11
- target,
12
- deposit,
13
- IMPLICIT,
8
+ atom__INTERNAL,
9
+ withdraw,
10
+ selector__INTERNAL,
11
+ target,
12
+ deposit,
13
+ IMPLICIT,
14
14
  } from "."
15
15
  import type {
16
- AtomFamily,
17
- AtomFamilyOptions,
18
- AtomToken,
19
- FamilyMetadata,
20
- ReadonlySelectorFamily,
21
- ReadonlySelectorFamilyOptions,
22
- ReadonlySelectorToken,
23
- SelectorFamily,
24
- SelectorFamilyOptions,
25
- SelectorToken,
16
+ AtomFamily,
17
+ AtomFamilyOptions,
18
+ AtomToken,
19
+ FamilyMetadata,
20
+ ReadonlySelectorFamily,
21
+ ReadonlySelectorFamilyOptions,
22
+ ReadonlySelectorToken,
23
+ SelectorFamily,
24
+ SelectorFamilyOptions,
25
+ SelectorToken,
26
26
  } from ".."
27
27
 
28
28
  export function atomFamily__INTERNAL<T, K extends Serializable>(
29
- options: AtomFamilyOptions<T, K>,
30
- store: Store = IMPLICIT.STORE
29
+ options: AtomFamilyOptions<T, K>,
30
+ store: Store = IMPLICIT.STORE,
31
31
  ): AtomFamily<T, K> {
32
- const subject = new Rx.Subject<AtomToken<T>>()
33
- return Object.assign(
34
- (key: K): AtomToken<T> => {
35
- const subKey = stringifyJson(key)
36
- const family: FamilyMetadata = { key: options.key, subKey }
37
- const fullKey = `${options.key}(${subKey})`
38
- const existing = withdraw({ key: fullKey, type: `atom` }, store)
39
- const token: AtomToken<any> = existing
40
- ? deposit(existing)
41
- : atom__INTERNAL<T>(
42
- {
43
- key: fullKey,
44
- default:
45
- options.default instanceof Function
46
- ? options.default(key)
47
- : options.default,
48
- effects: options.effects?.(key),
49
- },
50
- family,
51
- store
52
- )
53
- subject.next(token)
54
- return token
55
- },
56
- {
57
- key: options.key,
58
- type: `atom_family`,
59
- subject,
60
- } as const
61
- )
32
+ const subject = new Rx.Subject<AtomToken<T>>()
33
+ return Object.assign(
34
+ (key: K): AtomToken<T> => {
35
+ const subKey = stringifyJson(key)
36
+ const family: FamilyMetadata = { key: options.key, subKey }
37
+ const fullKey = `${options.key}(${subKey})`
38
+ const existing = withdraw({ key: fullKey, type: `atom` }, store)
39
+ const token: AtomToken<any> = existing
40
+ ? deposit(existing)
41
+ : atom__INTERNAL<T>(
42
+ {
43
+ key: fullKey,
44
+ default:
45
+ options.default instanceof Function
46
+ ? options.default(key)
47
+ : options.default,
48
+ effects: options.effects?.(key),
49
+ },
50
+ family,
51
+ store,
52
+ )
53
+ subject.next(token)
54
+ return token
55
+ },
56
+ {
57
+ key: options.key,
58
+ type: `atom_family`,
59
+ subject,
60
+ } as const,
61
+ )
62
62
  }
63
63
 
64
64
  export function readonlySelectorFamily__INTERNAL<T, K extends Serializable>(
65
- options: ReadonlySelectorFamilyOptions<T, K>,
66
- store?: Store
65
+ options: ReadonlySelectorFamilyOptions<T, K>,
66
+ store?: Store,
67
67
  ): ReadonlySelectorFamily<T, K> {
68
- const core = target(store)
69
- const subject = new Rx.Subject<ReadonlySelectorToken<T>>()
70
- return Object.assign(
71
- (key: K): ReadonlySelectorToken<T> => {
72
- const subKey = stringifyJson(key)
73
- const family: FamilyMetadata = { key: options.key, subKey }
74
- const fullKey = `${options.key}(${subKey})`
75
- const existing = core.readonlySelectors.get(fullKey)
76
- if (existing) {
77
- return deposit(existing)
78
- }
79
- return selector__INTERNAL<T>(
80
- {
81
- key: fullKey,
82
- get: options.get(key),
83
- },
84
- family,
85
- store
86
- ) as ReadonlySelectorToken<T>
87
- },
88
- {
89
- key: options.key,
90
- type: `readonly_selector_family`,
91
- subject,
92
- } as const
93
- ) as ReadonlySelectorFamily<T, K>
68
+ const core = target(store)
69
+ const subject = new Rx.Subject<ReadonlySelectorToken<T>>()
70
+ return Object.assign(
71
+ (key: K): ReadonlySelectorToken<T> => {
72
+ const subKey = stringifyJson(key)
73
+ const family: FamilyMetadata = { key: options.key, subKey }
74
+ const fullKey = `${options.key}(${subKey})`
75
+ const existing = core.readonlySelectors.get(fullKey)
76
+ if (existing) {
77
+ return deposit(existing)
78
+ }
79
+ return selector__INTERNAL<T>(
80
+ {
81
+ key: fullKey,
82
+ get: options.get(key),
83
+ },
84
+ family,
85
+ store,
86
+ ) as ReadonlySelectorToken<T>
87
+ },
88
+ {
89
+ key: options.key,
90
+ type: `readonly_selector_family`,
91
+ subject,
92
+ } as const,
93
+ ) as ReadonlySelectorFamily<T, K>
94
94
  }
95
95
 
96
96
  export function selectorFamily__INTERNAL<T, K extends Serializable>(
97
- options: SelectorFamilyOptions<T, K>,
98
- store?: Store
97
+ options: SelectorFamilyOptions<T, K>,
98
+ store?: Store,
99
99
  ): SelectorFamily<T, K>
100
100
  export function selectorFamily__INTERNAL<T, K extends Serializable>(
101
- options: ReadonlySelectorFamilyOptions<T, K>,
102
- store?: Store
101
+ options: ReadonlySelectorFamilyOptions<T, K>,
102
+ store?: Store,
103
103
  ): ReadonlySelectorFamily<T, K>
104
104
  export function selectorFamily__INTERNAL<T, K extends Serializable>(
105
- options: ReadonlySelectorFamilyOptions<T, K> | SelectorFamilyOptions<T, K>,
106
- store: Store = IMPLICIT.STORE
105
+ options: ReadonlySelectorFamilyOptions<T, K> | SelectorFamilyOptions<T, K>,
106
+ store: Store = IMPLICIT.STORE,
107
107
  ): ReadonlySelectorFamily<T, K> | SelectorFamily<T, K> {
108
- const isReadonly = !(`set` in options)
108
+ const isReadonly = !(`set` in options)
109
109
 
110
- if (isReadonly) {
111
- return readonlySelectorFamily__INTERNAL(options, store)
112
- }
113
- const core = target(store)
114
- const subject = new Rx.Subject<SelectorToken<T>>()
110
+ if (isReadonly) {
111
+ return readonlySelectorFamily__INTERNAL(options, store)
112
+ }
113
+ const core = target(store)
114
+ const subject = new Rx.Subject<SelectorToken<T>>()
115
115
 
116
- return Object.assign(
117
- (key: K): SelectorToken<T> => {
118
- const subKey = stringifyJson(key)
119
- const family: FamilyMetadata = { key: options.key, subKey }
120
- const fullKey = `${options.key}(${subKey})`
121
- const existing = core.selectors.get(fullKey)
122
- if (existing) {
123
- return deposit(existing)
124
- }
125
- const token = selector__INTERNAL<T>(
126
- {
127
- key: fullKey,
128
- get: options.get(key),
129
- set: options.set(key),
130
- },
131
- family,
132
- store
133
- )
134
- subject.next(token)
135
- return token
136
- },
137
- {
138
- key: options.key,
139
- type: `selector_family`,
140
- } as const
141
- ) as SelectorFamily<T, K>
116
+ return Object.assign(
117
+ (key: K): SelectorToken<T> => {
118
+ const subKey = stringifyJson(key)
119
+ const family: FamilyMetadata = { key: options.key, subKey }
120
+ const fullKey = `${options.key}(${subKey})`
121
+ const existing = core.selectors.get(fullKey)
122
+ if (existing) {
123
+ return deposit(existing)
124
+ }
125
+ const token = selector__INTERNAL<T>(
126
+ {
127
+ key: fullKey,
128
+ get: options.get(key),
129
+ set: options.set(key),
130
+ },
131
+ family,
132
+ store,
133
+ )
134
+ subject.next(token)
135
+ return token
136
+ },
137
+ {
138
+ key: options.key,
139
+ type: `selector_family`,
140
+ } as const,
141
+ ) as SelectorFamily<T, K>
142
142
  }