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
package/src/logger.ts CHANGED
@@ -5,42 +5,42 @@ import { IMPLICIT } from "./internal/store"
5
5
 
6
6
  export type Logger = Pick<Console, `error` | `info` | `warn`>
7
7
  export const LOG_LEVELS: ReadonlyArray<keyof Logger> = [
8
- `info`,
9
- `warn`,
10
- `error`,
8
+ `info`,
9
+ `warn`,
10
+ `error`,
11
11
  ] as const
12
12
 
13
13
  export const setLogLevel = (
14
- preferredLevel: `error` | `info` | `warn` | null,
15
- store: Store = IMPLICIT.STORE
14
+ preferredLevel: `error` | `info` | `warn` | null,
15
+ store: Store = IMPLICIT.STORE,
16
16
  ): void => {
17
- const { logger__INTERNAL } = store.config
18
- if (preferredLevel === null) {
19
- store.config.logger = null
20
- } else {
21
- store.config.logger = { ...console }
22
- LOG_LEVELS.forEach((logLevel) => {
23
- if (LOG_LEVELS.indexOf(logLevel) < LOG_LEVELS.indexOf(preferredLevel)) {
24
- /* eslint-disable-next-line @typescript-eslint/no-non-null-assertion */
25
- store.config.logger![logLevel] = doNothing
26
- } else {
27
- /* eslint-disable-next-line @typescript-eslint/no-non-null-assertion */
28
- store.config.logger![logLevel] = logger__INTERNAL[logLevel]
29
- }
30
- })
31
- }
17
+ const { logger__INTERNAL } = store.config
18
+ if (preferredLevel === null) {
19
+ store.config.logger = null
20
+ } else {
21
+ store.config.logger = { ...console }
22
+ LOG_LEVELS.forEach((logLevel) => {
23
+ if (LOG_LEVELS.indexOf(logLevel) < LOG_LEVELS.indexOf(preferredLevel)) {
24
+ // rome-ignore lint/style/noNonNullAssertion: we just set it
25
+ store.config.logger![logLevel] = doNothing
26
+ } else {
27
+ // rome-ignore lint/style/noNonNullAssertion: we just set it
28
+ store.config.logger![logLevel] = logger__INTERNAL[logLevel]
29
+ }
30
+ })
31
+ }
32
32
  }
33
33
 
34
34
  export const useLogger = (
35
- logger: Logger,
36
- store: Store = IMPLICIT.STORE
35
+ logger: Logger,
36
+ store: Store = IMPLICIT.STORE,
37
37
  ): void => {
38
- const currentLogLevel =
39
- store.config.logger === null
40
- ? null
41
- : LOG_LEVELS.find(
42
- (logLevel) => store.config.logger?.[logLevel] !== doNothing
43
- ) ?? null
44
- store.config.logger__INTERNAL = { ...logger }
45
- setLogLevel(currentLogLevel, store)
38
+ const currentLogLevel =
39
+ store.config.logger === null
40
+ ? null
41
+ : LOG_LEVELS.find(
42
+ (logLevel) => store.config.logger?.[logLevel] !== doNothing,
43
+ ) ?? null
44
+ store.config.logger__INTERNAL = { ...logger }
45
+ setLogLevel(currentLogLevel, store)
46
46
  }
@@ -3,12 +3,12 @@ import * as React from "react"
3
3
  import * as AtomIO from "atom.io"
4
4
 
5
5
  export const StoreContext = React.createContext<AtomIO.Store>(
6
- AtomIO.__INTERNAL__.IMPLICIT.STORE
6
+ AtomIO.__INTERNAL__.IMPLICIT.STORE,
7
7
  )
8
8
 
9
9
  export const StoreProvider: React.FC<{
10
- children: React.ReactNode
11
- store?: AtomIO.Store
10
+ children: React.ReactNode
11
+ store?: AtomIO.Store
12
12
  }> = ({ children, store = AtomIO.__INTERNAL__.IMPLICIT.STORE }) => (
13
- <StoreContext.Provider value={store}>{children}</StoreContext.Provider>
13
+ <StoreContext.Provider value={store}>{children}</StoreContext.Provider>
14
14
  )
@@ -7,42 +7,42 @@ import type { Modifier } from "~/packages/anvl/src/function"
7
7
  import { StoreContext } from "./store-context"
8
8
 
9
9
  export type StoreHooks = {
10
- useI: <T>(token: AtomIO.StateToken<T>) => (next: Modifier<T> | T) => void
11
- useO: <T>(token: AtomIO.ReadonlySelectorToken<T> | AtomIO.StateToken<T>) => T
12
- useIO: <T>(token: AtomIO.StateToken<T>) => [T, (next: Modifier<T> | T) => void]
10
+ useI: <T>(token: AtomIO.StateToken<T>) => (next: Modifier<T> | T) => void
11
+ useO: <T>(token: AtomIO.ReadonlySelectorToken<T> | AtomIO.StateToken<T>) => T
12
+ useIO: <T>(token: AtomIO.StateToken<T>) => [T, (next: Modifier<T> | T) => void]
13
13
  }
14
14
  export const storeHooks: StoreHooks = { useI, useO, useIO }
15
15
 
16
16
  export function useI<T>(
17
- token: AtomIO.StateToken<T>
17
+ token: AtomIO.StateToken<T>,
18
18
  ): (next: Modifier<T> | T) => void {
19
- const store = React.useContext(StoreContext)
20
- const update = (next: Modifier<T> | T) => AtomIO.setState(token, next, store)
21
- return update
19
+ const store = React.useContext(StoreContext)
20
+ const update = (next: Modifier<T> | T) => AtomIO.setState(token, next, store)
21
+ return update
22
22
  }
23
23
 
24
24
  export function useO<T>(
25
- token: AtomIO.ReadonlySelectorToken<T> | AtomIO.StateToken<T>
25
+ token: AtomIO.ReadonlySelectorToken<T> | AtomIO.StateToken<T>,
26
26
  ): T {
27
- const store = React.useContext(StoreContext)
28
- return React.useSyncExternalStore<T>(
29
- (observe) => AtomIO.subscribe(token, observe, store),
30
- () => AtomIO.getState(token, store)
31
- )
27
+ const store = React.useContext(StoreContext)
28
+ return React.useSyncExternalStore<T>(
29
+ (observe) => AtomIO.subscribe(token, observe, store),
30
+ () => AtomIO.getState(token, store),
31
+ )
32
32
  }
33
33
 
34
34
  export function useIO<T>(
35
- token: AtomIO.StateToken<T>
35
+ token: AtomIO.StateToken<T>,
36
36
  ): [T, (next: Modifier<T> | T) => void] {
37
- return [useO(token), useI(token)]
37
+ return [useO(token), useI(token)]
38
38
  }
39
39
 
40
40
  export function useStore<T>(
41
- token: AtomIO.StateToken<T>
41
+ token: AtomIO.StateToken<T>,
42
42
  ): [T, (next: Modifier<T> | T) => void]
43
43
  export function useStore<T>(token: AtomIO.ReadonlySelectorToken<T>): T
44
44
  export function useStore<T>(
45
- token: AtomIO.ReadonlySelectorToken<T> | AtomIO.StateToken<T>
45
+ token: AtomIO.ReadonlySelectorToken<T> | AtomIO.StateToken<T>,
46
46
  ): T | [T, (next: Modifier<T> | T) => void] {
47
- return token.type === `readonly_selector` ? useO(token) : useIO(token)
47
+ return token.type === `readonly_selector` ? useO(token) : useIO(token)
48
48
  }
@@ -12,96 +12,97 @@ import { lazyLocalStorageEffect } from "../web-effects"
12
12
  import "./devtools.scss"
13
13
 
14
14
  const { atomTokenIndexState, selectorTokenIndexState } =
15
- __INTERNAL__.META.attachMetaState()
15
+ __INTERNAL__.META.attachMetaState()
16
16
 
17
17
  const devtoolsAreOpenState = atom<boolean>({
18
- key: `👁‍🗨_devtools_are_open`,
19
- default: true,
20
- effects: [lazyLocalStorageEffect(`👁‍🗨_devtools_are_open`)],
18
+ key: `👁‍🗨_devtools_are_open`,
19
+ default: true,
20
+ effects: [lazyLocalStorageEffect(`👁‍🗨_devtools_are_open`)],
21
21
  })
22
22
 
23
23
  export const composeDevtools = (storeHooks: StoreHooks): FC => {
24
- const Devtools: FC = () => {
25
- const constraintsRef = useRef(null)
24
+ const Devtools: FC = () => {
25
+ const constraintsRef = useRef(null)
26
26
 
27
- const [devtoolsAreOpen, setDevtoolsAreOpen] =
28
- storeHooks.useIO(devtoolsAreOpenState)
27
+ const [devtoolsAreOpen, setDevtoolsAreOpen] =
28
+ storeHooks.useIO(devtoolsAreOpenState)
29
29
 
30
- const mouseHasMoved = useRef(false)
30
+ const mouseHasMoved = useRef(false)
31
31
 
32
- return (
33
- <>
34
- <motion.span
35
- ref={constraintsRef}
36
- className="atom_io_devtools_zone"
37
- style={{
38
- position: `fixed`,
39
- top: 0,
40
- left: 0,
41
- right: 0,
42
- bottom: 0,
43
- pointerEvents: `none`,
44
- }}
45
- />
46
- <motion.main
47
- drag
48
- dragConstraints={constraintsRef}
49
- className="atom_io_devtools"
50
- transition={spring}
51
- style={
52
- devtoolsAreOpen
53
- ? {}
54
- : {
55
- backgroundColor: `#0000`,
56
- borderColor: `#0000`,
57
- maxHeight: 28,
58
- maxWidth: 33,
59
- }
60
- }
61
- >
62
- {devtoolsAreOpen ? (
63
- <>
64
- <motion.header>
65
- <h1>atom.io</h1>
66
- </motion.header>
67
- <motion.main>
68
- <LayoutGroup>
69
- <section>
70
- <h2>atoms</h2>
71
- <TokenList
72
- storeHooks={storeHooks}
73
- tokenIndex={atomTokenIndexState}
74
- />
75
- </section>
76
- <section>
77
- <h2>selectors</h2>
78
- <TokenList
79
- storeHooks={storeHooks}
80
- tokenIndex={selectorTokenIndexState}
81
- />
82
- </section>
83
- </LayoutGroup>
84
- </motion.main>
85
- </>
86
- ) : null}
87
- <footer>
88
- <button
89
- onMouseDown={() => (mouseHasMoved.current = false)}
90
- onMouseMove={() => (mouseHasMoved.current = true)}
91
- onMouseUp={() => {
92
- if (!mouseHasMoved.current) {
93
- setDevtoolsAreOpen((open) => !open)
94
- }
95
- }}
96
- >
97
- 👁‍🗨
98
- </button>
99
- </footer>
100
- </motion.main>
101
- </>
102
- )
103
- }
104
- return Devtools
32
+ return (
33
+ <>
34
+ <motion.span
35
+ ref={constraintsRef}
36
+ className="atom_io_devtools_zone"
37
+ style={{
38
+ position: `fixed`,
39
+ top: 0,
40
+ left: 0,
41
+ right: 0,
42
+ bottom: 0,
43
+ pointerEvents: `none`,
44
+ }}
45
+ />
46
+ <motion.main
47
+ drag
48
+ dragConstraints={constraintsRef}
49
+ className="atom_io_devtools"
50
+ transition={spring}
51
+ style={
52
+ devtoolsAreOpen
53
+ ? {}
54
+ : {
55
+ backgroundColor: `#0000`,
56
+ borderColor: `#0000`,
57
+ maxHeight: 28,
58
+ maxWidth: 33,
59
+ }
60
+ }
61
+ >
62
+ {devtoolsAreOpen ? (
63
+ <>
64
+ <motion.header>
65
+ <h1>atom.io</h1>
66
+ </motion.header>
67
+ <motion.main>
68
+ <LayoutGroup>
69
+ <section>
70
+ <h2>atoms</h2>
71
+ <TokenList
72
+ storeHooks={storeHooks}
73
+ tokenIndex={atomTokenIndexState}
74
+ />
75
+ </section>
76
+ <section>
77
+ <h2>selectors</h2>
78
+ <TokenList
79
+ storeHooks={storeHooks}
80
+ tokenIndex={selectorTokenIndexState}
81
+ />
82
+ </section>
83
+ </LayoutGroup>
84
+ </motion.main>
85
+ </>
86
+ ) : null}
87
+ <footer>
88
+ <button
89
+ type="button"
90
+ onMouseDown={() => (mouseHasMoved.current = false)}
91
+ onMouseMove={() => (mouseHasMoved.current = true)}
92
+ onMouseUp={() => {
93
+ if (!mouseHasMoved.current) {
94
+ setDevtoolsAreOpen((open) => !open)
95
+ }
96
+ }}
97
+ >
98
+ 👁‍🗨
99
+ </button>
100
+ </footer>
101
+ </motion.main>
102
+ </>
103
+ )
104
+ }
105
+ return Devtools
105
106
  }
106
107
 
107
108
  export const AtomIODevtools = composeDevtools({ useI, useO, useIO })
@@ -8,66 +8,66 @@ import { ElasticInput } from "~/packages/hamr/src/react-elastic-input"
8
8
  import { JsonEditor } from "~/packages/hamr/src/react-json-editor"
9
9
 
10
10
  export const StateEditor: FC<{
11
- storeHooks: StoreHooks
12
- token: StateToken<unknown>
11
+ storeHooks: StoreHooks
12
+ token: StateToken<unknown>
13
13
  }> = ({ storeHooks, token }) => {
14
- const [data, set] = storeHooks.useIO(token)
15
- return isPlainJson(data) ? (
16
- <JsonEditor data={data} set={set} schema={true} />
17
- ) : (
18
- <div className="json_editor">
19
- <ElasticInput
20
- value={
21
- data instanceof Set
22
- ? `Set { ${JSON.stringify([...data]).slice(1, -1)} }`
23
- : data instanceof Map
24
- ? `Map ` + JSON.stringify([...data])
25
- : Object.getPrototypeOf(data).constructor.name +
26
- ` ` +
27
- JSON.stringify(data)
28
- }
29
- disabled={true}
30
- />
31
- </div>
32
- )
14
+ const [data, set] = storeHooks.useIO(token)
15
+ return isPlainJson(data) ? (
16
+ <JsonEditor data={data} set={set} schema={true} />
17
+ ) : (
18
+ <div className="json_editor">
19
+ <ElasticInput
20
+ value={
21
+ data instanceof Set
22
+ ? `Set { ${JSON.stringify([...data]).slice(1, -1)} }`
23
+ : data instanceof Map
24
+ ? `Map ` + JSON.stringify([...data])
25
+ : Object.getPrototypeOf(data).constructor.name +
26
+ ` ` +
27
+ JSON.stringify(data)
28
+ }
29
+ disabled={true}
30
+ />
31
+ </div>
32
+ )
33
33
  }
34
34
 
35
35
  export const ReadonlySelectorEditor: FC<{
36
- storeHooks: StoreHooks
37
- token: ReadonlySelectorToken<unknown>
36
+ storeHooks: StoreHooks
37
+ token: ReadonlySelectorToken<unknown>
38
38
  }> = ({ storeHooks, token }) => {
39
- const data = storeHooks.useO(token)
40
- return isPlainJson(data) ? (
41
- <JsonEditor
42
- data={data}
43
- set={() => null}
44
- schema={true}
45
- isReadonly={() => true}
46
- />
47
- ) : (
48
- <div className="json_editor">
49
- <ElasticInput
50
- value={
51
- data instanceof Set
52
- ? `Set ` + JSON.stringify([...data])
53
- : data instanceof Map
54
- ? `Map ` + JSON.stringify([...data])
55
- : Object.getPrototypeOf(data).constructor.name +
56
- ` ` +
57
- JSON.stringify(data)
58
- }
59
- disabled={true}
60
- />
61
- </div>
62
- )
39
+ const data = storeHooks.useO(token)
40
+ return isPlainJson(data) ? (
41
+ <JsonEditor
42
+ data={data}
43
+ set={() => null}
44
+ schema={true}
45
+ isReadonly={() => true}
46
+ />
47
+ ) : (
48
+ <div className="json_editor">
49
+ <ElasticInput
50
+ value={
51
+ data instanceof Set
52
+ ? `Set ` + JSON.stringify([...data])
53
+ : data instanceof Map
54
+ ? `Map ` + JSON.stringify([...data])
55
+ : Object.getPrototypeOf(data).constructor.name +
56
+ ` ` +
57
+ JSON.stringify(data)
58
+ }
59
+ disabled={true}
60
+ />
61
+ </div>
62
+ )
63
63
  }
64
64
 
65
65
  export const StoreEditor: FC<{
66
- storeHooks: StoreHooks
67
- token: ReadonlySelectorToken<unknown> | StateToken<unknown>
66
+ storeHooks: StoreHooks
67
+ token: ReadonlySelectorToken<unknown> | StateToken<unknown>
68
68
  }> = ({ storeHooks, token }) => {
69
- if (token.type === `readonly_selector`) {
70
- return <ReadonlySelectorEditor storeHooks={storeHooks} token={token} />
71
- }
72
- return <StateEditor storeHooks={storeHooks} token={token} />
69
+ if (token.type === `readonly_selector`) {
70
+ return <ReadonlySelectorEditor storeHooks={storeHooks} token={token} />
71
+ }
72
+ return <StateEditor storeHooks={storeHooks} token={token} />
73
73
  }
@@ -2,10 +2,10 @@ import type { FC } from "react"
2
2
  import { Fragment } from "react"
3
3
 
4
4
  import type {
5
- AtomToken,
6
- ReadonlySelectorToken,
7
- SelectorToken,
8
- __INTERNAL__,
5
+ AtomToken,
6
+ ReadonlySelectorToken,
7
+ SelectorToken,
8
+ __INTERNAL__,
9
9
  } from "atom.io"
10
10
  import { getState } from "atom.io"
11
11
  import type { StoreHooks } from "atom.io/react"
@@ -15,43 +15,48 @@ import { recordToEntries } from "~/packages/anvl/src/object"
15
15
  import { StoreEditor } from "./StateEditor"
16
16
 
17
17
  export const TokenList: FC<{
18
- storeHooks: StoreHooks
19
- tokenIndex: ReadonlySelectorToken<
20
- __INTERNAL__.META.StateTokenIndex<
21
- | AtomToken<unknown>
22
- | ReadonlySelectorToken<unknown>
23
- | SelectorToken<unknown>
24
- >
25
- >
18
+ storeHooks: StoreHooks
19
+ tokenIndex: ReadonlySelectorToken<
20
+ __INTERNAL__.META.StateTokenIndex<
21
+ | AtomToken<unknown>
22
+ | ReadonlySelectorToken<unknown>
23
+ | SelectorToken<unknown>
24
+ >
25
+ >
26
26
  }> = ({ storeHooks, tokenIndex }) => {
27
- const tokenIds = storeHooks.useO(tokenIndex)
28
- return (
29
- <>
30
- {Object.entries(tokenIds).map(([key, token]) => (
31
- <Fragment key={key}>
32
- {key.startsWith(`👁‍🗨_`) ? null : (
33
- <div className="node">
34
- {`type` in token ? (
35
- <>
36
- <label onClick={() => console.log(token, getState(token))}>
37
- {key}
38
- </label>
39
- <StoreEditor storeHooks={storeHooks} token={token} />
40
- </>
41
- ) : (
42
- recordToEntries(token.familyMembers).map(([key, token]) => (
43
- <>
44
- <label>{key}</label>
45
- <div key={key} className="node">
46
- {key}:<StoreEditor storeHooks={storeHooks} token={token} />
47
- </div>
48
- </>
49
- ))
50
- )}
51
- </div>
52
- )}
53
- </Fragment>
54
- ))}
55
- </>
56
- )
27
+ const tokenIds = storeHooks.useO(tokenIndex)
28
+ return (
29
+ <>
30
+ {Object.entries(tokenIds).map(([key, token]) => {
31
+ let logState: () => void
32
+ return (
33
+ <Fragment key={key}>
34
+ {key.startsWith(`👁‍🗨_`) ? null : (
35
+ <div className="node">
36
+ {`type` in token
37
+ ? ((logState = () => console.log(token, getState(token))),
38
+ (
39
+ <>
40
+ <label onClick={logState} onKeyUp={logState}>
41
+ {key}
42
+ </label>
43
+ <StoreEditor storeHooks={storeHooks} token={token} />
44
+ </>
45
+ ))
46
+ : recordToEntries(token.familyMembers).map(([key, token]) => (
47
+ <>
48
+ <label>{key}</label>
49
+ <div key={key} className="node">
50
+ {key}:
51
+ <StoreEditor storeHooks={storeHooks} token={token} />
52
+ </div>
53
+ </>
54
+ ))}
55
+ </div>
56
+ )}
57
+ </Fragment>
58
+ )
59
+ })}
60
+ </>
61
+ )
57
62
  }