atom.io 0.28.0 → 0.28.2

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 (75) hide show
  1. package/dist/{chunk-BX3MTH2Z.js → chunk-D3ZPRYEW.js} +15 -23
  2. package/eslint-plugin/dist/index.js +0 -1
  3. package/eslint-plugin/src/walk.ts +0 -1
  4. package/internal/dist/index.d.ts +3 -3
  5. package/internal/dist/index.js +1 -1
  6. package/internal/src/families/dispose-from-store.ts +0 -6
  7. package/internal/src/operation.ts +7 -7
  8. package/internal/src/selector/create-writable-selector.ts +1 -1
  9. package/internal/src/set-state/become.ts +1 -3
  10. package/internal/src/set-state/evict-downstream.ts +2 -2
  11. package/internal/src/set-state/set-atom.ts +1 -1
  12. package/internal/src/set-state/set-into-store.ts +1 -1
  13. package/internal/src/set-state/stow-update.ts +2 -2
  14. package/internal/src/store/store.ts +1 -1
  15. package/introspection/dist/index.d.ts +15 -6
  16. package/introspection/dist/index.js +620 -1
  17. package/introspection/src/attach-atom-index.ts +5 -6
  18. package/introspection/src/attach-introspection-states.ts +5 -6
  19. package/introspection/src/attach-selector-index.ts +6 -7
  20. package/introspection/src/attach-timeline-family.ts +3 -4
  21. package/introspection/src/attach-timeline-index.ts +4 -8
  22. package/introspection/src/attach-transaction-index.ts +4 -8
  23. package/introspection/src/attach-transaction-logs.ts +4 -8
  24. package/introspection/src/attach-type-selectors.ts +13 -6
  25. package/introspection/src/differ.ts +1 -1
  26. package/introspection/src/index.ts +1 -0
  27. package/introspection/src/refinery.ts +9 -7
  28. package/introspection/src/sprawl.ts +42 -0
  29. package/json/dist/index.d.ts +12 -1
  30. package/json/dist/index.js +111 -2
  31. package/json/src/index.ts +36 -1
  32. package/package.json +8 -8
  33. package/react-devtools/dist/index.d.ts +159 -2
  34. package/react-devtools/dist/index.js +260 -663
  35. package/react-devtools/src/AtomIODevtools.tsx +24 -13
  36. package/react-devtools/src/StateEditor.tsx +5 -47
  37. package/react-devtools/src/StateIndex.tsx +18 -11
  38. package/react-devtools/src/TimelineIndex.tsx +9 -6
  39. package/react-devtools/src/TransactionIndex.tsx +9 -11
  40. package/react-devtools/src/Updates.tsx +2 -0
  41. package/react-devtools/src/elastic-input/ElasticInput.tsx +86 -0
  42. package/react-devtools/src/elastic-input/NumberInput.tsx +199 -0
  43. package/react-devtools/src/elastic-input/TextInput.tsx +47 -0
  44. package/react-devtools/src/elastic-input/index.ts +3 -0
  45. package/react-devtools/src/error-boundary/DefaultFallback.tsx +49 -0
  46. package/react-devtools/src/error-boundary/ReactErrorBoundary.tsx +56 -0
  47. package/react-devtools/src/error-boundary/index.ts +2 -0
  48. package/react-devtools/src/index.ts +3 -0
  49. package/react-devtools/src/json-editor/assets/Untitled-1.ai +1436 -2
  50. package/react-devtools/src/json-editor/assets/data-vis.ai +1548 -1
  51. package/react-devtools/src/json-editor/comp/json-editor-sketches.ai +1451 -3
  52. package/react-devtools/src/json-editor/default-components.tsx +101 -0
  53. package/react-devtools/src/json-editor/developer-interface.tsx +81 -0
  54. package/react-devtools/src/json-editor/editors-by-type/array-editor.tsx +38 -0
  55. package/react-devtools/src/json-editor/editors-by-type/non-json.tsx +23 -0
  56. package/react-devtools/src/json-editor/editors-by-type/object-editor.tsx +128 -0
  57. package/react-devtools/src/json-editor/editors-by-type/primitive-editors.tsx +73 -0
  58. package/react-devtools/src/json-editor/editors-by-type/utilities/array-elements.ts +16 -0
  59. package/react-devtools/src/json-editor/editors-by-type/utilities/cast-json.ts +57 -0
  60. package/react-devtools/src/json-editor/editors-by-type/utilities/cast-to-json.ts +156 -0
  61. package/react-devtools/src/json-editor/editors-by-type/utilities/object-properties.ts +106 -0
  62. package/react-devtools/src/json-editor/index.ts +32 -0
  63. package/react-devtools/src/json-editor/json-editor-internal.tsx +128 -0
  64. package/react-devtools/src/json-editor/todo.md +7 -0
  65. package/react-devtools/src/store.ts +70 -46
  66. package/realtime/src/realtime-continuity.ts +3 -2
  67. package/realtime-client/src/pull-atom-family-member.ts +2 -0
  68. package/realtime-client/src/pull-mutable-atom-family-member.ts +2 -0
  69. package/realtime-client/src/pull-selector-family-member.ts +2 -0
  70. package/realtime-server/src/ipc-sockets/child-socket.ts +2 -0
  71. package/realtime-testing/src/setup-realtime-test.tsx +2 -0
  72. package/src/logger.ts +1 -0
  73. package/transceivers/set-rtx/src/set-rtx.ts +1 -0
  74. package/dist/chunk-D52JNVER.js +0 -721
  75. package/dist/chunk-EUVKUTW3.js +0 -89
@@ -0,0 +1,106 @@
1
+ import { become } from "atom.io/internal"
2
+ import type { Json, JsonTypeName } from "atom.io/json"
3
+ import { fromEntries, JSON_DEFAULTS, toEntries } from "atom.io/json"
4
+ import type { MutableRefObject } from "react"
5
+
6
+ import type { SetterOrUpdater } from "../.."
7
+ import { castToJson } from "./cast-to-json"
8
+
9
+ export const makePropertySetters = <T extends Json.Tree.Object>(
10
+ data: T,
11
+ set: SetterOrUpdater<T>,
12
+ ): { [K in keyof T]: SetterOrUpdater<T[K]> } =>
13
+ fromEntries(
14
+ toEntries(data).map(([key, value]) => [
15
+ key,
16
+ (newValue) => {
17
+ set({ ...data, [key]: become(newValue)(value) })
18
+ },
19
+ ]),
20
+ )
21
+
22
+ export const makePropertyRenamers = <T extends Json.Tree.Object>(
23
+ data: T,
24
+ set: SetterOrUpdater<T>,
25
+ stableKeyMapRef: MutableRefObject<{ [Key in keyof T]: keyof T }>,
26
+ ): { [K in keyof T]: (newKey: string) => void } =>
27
+ fromEntries(
28
+ toEntries(data).map(([key, value]) => [
29
+ key,
30
+ (newKey: string) => {
31
+ if (!Object.hasOwn(data, newKey)) {
32
+ set(() => {
33
+ const entries = Object.entries(data)
34
+ const index = entries.findIndex(([k]) => k === key)
35
+ entries[index] = [newKey, value]
36
+ const stableKeyMap = stableKeyMapRef.current
37
+ stableKeyMapRef.current = {
38
+ ...stableKeyMap,
39
+ [newKey]: stableKeyMap[key],
40
+ }
41
+ return Object.fromEntries(entries) as T
42
+ })
43
+ }
44
+ },
45
+ ]),
46
+ )
47
+
48
+ export const makePropertyRemovers = <T extends Json.Tree.Object>(
49
+ data: T,
50
+ set: SetterOrUpdater<T>,
51
+ ): { [K in keyof T]: () => void } =>
52
+ fromEntries(
53
+ toEntries(data).map(([key]) => [
54
+ key,
55
+ () => {
56
+ set(() => {
57
+ const { [key]: _, ...rest } = data
58
+ return rest as T
59
+ })
60
+ },
61
+ ]),
62
+ )
63
+
64
+ export const makePropertyRecasters = <T extends Json.Tree.Object>(
65
+ data: T,
66
+ set: SetterOrUpdater<T>,
67
+ ): { [K in keyof T]: (newType: JsonTypeName) => void } =>
68
+ fromEntries(
69
+ toEntries(data).map(([key, value]) => [
70
+ key,
71
+ (newType: JsonTypeName) => {
72
+ set(() => ({
73
+ ...data,
74
+ [key]: castToJson(value)[newType],
75
+ }))
76
+ },
77
+ ]),
78
+ )
79
+
80
+ export const makePropertyCreationInterface =
81
+ <T extends Json.Tree.Object>(
82
+ data: T,
83
+ set: SetterOrUpdater<T>,
84
+ ): ((
85
+ key: string,
86
+ type: JsonTypeName,
87
+ ) => (value?: Json.Serializable) => void) =>
88
+ (key, type) =>
89
+ (value) => {
90
+ set({ ...data, [key]: value ?? JSON_DEFAULTS[type] })
91
+ }
92
+
93
+ export const makePropertySorter =
94
+ <T extends Json.Tree.Object>(
95
+ data: T,
96
+ set: SetterOrUpdater<T>,
97
+ sortFn?: (a: string, b: string) => number,
98
+ ): (() => void) =>
99
+ () => {
100
+ const sortedKeys = Object.keys(data).sort(sortFn)
101
+ const sortedObj = {} as Record<string, unknown>
102
+ for (const key of sortedKeys) {
103
+ sortedObj[key] = data[key]
104
+ }
105
+ set(sortedObj as T)
106
+ }
@@ -0,0 +1,32 @@
1
+ import type { JsonTypes } from "atom.io/json"
2
+ import type { FC } from "react"
3
+
4
+ import { ArrayEditor } from "./editors-by-type/array-editor"
5
+ import { ObjectEditor } from "./editors-by-type/object-editor"
6
+ import {
7
+ BooleanEditor,
8
+ NullEditor,
9
+ NumberEditor,
10
+ StringEditor,
11
+ } from "./editors-by-type/primitive-editors"
12
+ import type { JsonEditorProps_INTERNAL } from "./json-editor-internal"
13
+
14
+ export * from "./default-components"
15
+ export * from "./developer-interface"
16
+ export * from "./editors-by-type/utilities/cast-to-json"
17
+
18
+ export type SetterOrUpdater<T> = <New extends T>(
19
+ next: New | ((old: T) => New),
20
+ ) => void
21
+
22
+ export const SubEditors: Record<
23
+ keyof JsonTypes,
24
+ FC<JsonEditorProps_INTERNAL<any>>
25
+ > = {
26
+ array: ArrayEditor,
27
+ boolean: BooleanEditor,
28
+ null: NullEditor,
29
+ number: NumberEditor,
30
+ object: ObjectEditor,
31
+ string: StringEditor,
32
+ }
@@ -0,0 +1,128 @@
1
+ import { jsonRefinery } from "atom.io/introspection"
2
+ import type { JsonTypes } from "atom.io/json"
3
+ import { isJson } from "atom.io/json"
4
+ import type { CSSProperties, FC, ReactElement } from "react"
5
+
6
+ import { ElasticInput } from "../elastic-input"
7
+ import type { SetterOrUpdater } from "."
8
+ import { SubEditors } from "."
9
+ import type { JsonEditorComponents } from "./default-components"
10
+ import { NonJsonEditor } from "./editors-by-type/non-json"
11
+
12
+ export type JsonEditorProps_INTERNAL<T> = {
13
+ data: T
14
+ set: SetterOrUpdater<T>
15
+ name?: string | undefined
16
+ rename?: ((newKey: string) => void) | undefined
17
+ remove?: (() => void) | undefined
18
+ recast?: (newType: keyof JsonTypes) => void
19
+ path?: ReadonlyArray<number | string>
20
+ isReadonly?: (path: ReadonlyArray<number | string>) => boolean
21
+ isHidden?: (path: ReadonlyArray<number | string>) => boolean
22
+ className?: string | undefined
23
+ style?: CSSProperties | undefined
24
+ Header?: FC<{ data: T }> | undefined
25
+ Components: JsonEditorComponents
26
+ testid?: string | undefined
27
+ }
28
+
29
+ export const JsonEditor_INTERNAL = <T,>({
30
+ data,
31
+ set,
32
+ name,
33
+ rename,
34
+ remove,
35
+ recast,
36
+ path = [],
37
+ isReadonly = () => false,
38
+ isHidden = () => false,
39
+ className,
40
+ style,
41
+ Header: HeaderDisplay,
42
+ Components,
43
+ testid,
44
+ }: JsonEditorProps_INTERNAL<T>): ReactElement | null => {
45
+ const dataIsJson = isJson(data)
46
+ const refined = jsonRefinery.refine<unknown>(data) ?? {
47
+ type: `non-json`,
48
+ data,
49
+ }
50
+ const SubEditor = dataIsJson ? SubEditors[refined.type] : NonJsonEditor
51
+
52
+ const disabled = isReadonly(path)
53
+
54
+ return isHidden(path) ? null : (
55
+ <Components.ErrorBoundary>
56
+ <Components.EditorWrapper
57
+ className={className}
58
+ style={style}
59
+ testid={testid}
60
+ >
61
+ {remove ? (
62
+ disabled ? (
63
+ <Components.Button disabled testid={`${testid}-delete`}>
64
+ <Components.DeleteIcon />
65
+ </Components.Button>
66
+ ) : (
67
+ <Components.Button
68
+ testid={`${testid}-delete`}
69
+ onClick={() => {
70
+ remove()
71
+ }}
72
+ >
73
+ <Components.DeleteIcon />
74
+ </Components.Button>
75
+ )
76
+ ) : null}
77
+ {HeaderDisplay && <HeaderDisplay data={data} />}
78
+ {rename && (
79
+ <Components.KeyWrapper>
80
+ <ElasticInput
81
+ value={name}
82
+ onChange={
83
+ disabled
84
+ ? undefined
85
+ : (e) => {
86
+ rename(e.target.value)
87
+ }
88
+ }
89
+ disabled={disabled}
90
+ data-testid={`${testid}-rename`}
91
+ />
92
+ </Components.KeyWrapper>
93
+ )}
94
+ <SubEditor
95
+ data={refined.data}
96
+ set={set}
97
+ remove={remove}
98
+ rename={rename}
99
+ path={path}
100
+ isReadonly={isReadonly}
101
+ isHidden={isHidden}
102
+ Components={Components}
103
+ testid={testid}
104
+ />
105
+ {recast && dataIsJson ? (
106
+ <select
107
+ onChange={
108
+ disabled
109
+ ? undefined
110
+ : (e) => {
111
+ recast(e.target.value as keyof JsonTypes)
112
+ }
113
+ }
114
+ value={refined.type}
115
+ disabled={disabled}
116
+ data-testid={`${testid}-recast`}
117
+ >
118
+ {Object.keys(SubEditors).map((type) => (
119
+ <option key={type} value={type}>
120
+ {type}
121
+ </option>
122
+ ))}
123
+ </select>
124
+ ) : null}
125
+ </Components.EditorWrapper>
126
+ </Components.ErrorBoundary>
127
+ )
128
+ }
@@ -0,0 +1,7 @@
1
+
2
+ - [x] add an ErrorBoundary to the Components prop
3
+ - [x] wrap each JsonEditor_INTERNAL in an ErrorBoundary
4
+ - [ ] add display of miscast properties with button to fix
5
+ - [ ] fixing a miscast generates a template from the schema
6
+ - [ ] sort official properties as listed in schema
7
+ - [ ] add extra line break in JSON before unofficial properties
@@ -1,51 +1,75 @@
1
- import { atom, atomFamily } from "atom.io"
1
+ import type { RegularAtomFamilyToken, RegularAtomToken } from "atom.io"
2
+ import {
3
+ createAtomFamily,
4
+ createStandaloneAtom,
5
+ IMPLICIT,
6
+ type Store,
7
+ } from "atom.io/internal"
8
+ import type { IntrospectionStates } from "atom.io/introspection"
2
9
  import { attachIntrospectionStates } from "atom.io/introspection"
3
10
  import { persistSync } from "atom.io/web"
4
-
5
- export const {
6
- atomIndex,
7
- selectorIndex,
8
- transactionIndex,
9
- transactionLogSelectors,
10
- timelineIndex,
11
- timelineSelectors,
12
- typeSelectors,
13
- } = attachIntrospectionStates()
14
-
15
- export const devtoolsAreOpenState = atom<boolean>({
16
- key: `👁‍🗨 Devtools Are Open`,
17
- default: true,
18
- effects:
19
- typeof window === `undefined`
20
- ? []
21
- : [persistSync(window.localStorage, JSON, `👁‍🗨 Devtools Are Open`)],
22
- })
11
+ import { createContext } from "react"
23
12
 
24
13
  type DevtoolsView = `atoms` | `selectors` | `timelines` | `transactions`
25
14
 
26
- export const devtoolsViewSelectionState = atom<DevtoolsView>({
27
- key: `👁‍🗨 Devtools View Selection`,
28
- default: `atoms`,
29
- effects:
30
- typeof window === `undefined`
31
- ? []
32
- : [persistSync(window.localStorage, JSON, `👁‍🗨 Devtools View`)],
33
- })
34
-
35
- export const devtoolsViewOptionsState = atom<DevtoolsView[]>({
36
- key: `👁‍🗨 Devtools View Options`,
37
- default: [`atoms`, `selectors`, `transactions`, `timelines`],
38
- effects:
39
- typeof window === `undefined`
40
- ? []
41
- : [persistSync(window.localStorage, JSON, `👁‍🗨 Devtools View Options`)],
42
- })
43
-
44
- export const viewIsOpenAtoms = atomFamily<boolean, string>({
45
- key: `👁‍🗨 Devtools View Is Open`,
46
- default: false,
47
- effects: (key) =>
48
- typeof window === `undefined`
49
- ? []
50
- : [persistSync(window.localStorage, JSON, key + `:view-is-open`)],
51
- })
15
+ export type DevtoolsStates = {
16
+ devtoolsAreOpenState: RegularAtomToken<boolean>
17
+ devtoolsViewSelectionState: RegularAtomToken<DevtoolsView>
18
+ devtoolsViewOptionsState: RegularAtomToken<DevtoolsView[]>
19
+ viewIsOpenAtoms: RegularAtomFamilyToken<boolean, string>
20
+ }
21
+
22
+ export function attachDevtoolsStates(
23
+ store: Store,
24
+ ): DevtoolsStates & IntrospectionStates & { store: Store } {
25
+ const introspectionStates = attachIntrospectionStates(store)
26
+
27
+ const devtoolsAreOpenState = createStandaloneAtom<boolean>(store, {
28
+ key: `🔍 Devtools Are Open`,
29
+ default: true,
30
+ effects:
31
+ typeof window === `undefined`
32
+ ? []
33
+ : [persistSync(window.localStorage, JSON, `🔍 Devtools Are Open`)],
34
+ })
35
+
36
+ const devtoolsViewSelectionState = createStandaloneAtom<DevtoolsView>(store, {
37
+ key: `🔍 Devtools View Selection`,
38
+ default: `atoms`,
39
+ effects:
40
+ typeof window === `undefined`
41
+ ? []
42
+ : [persistSync(window.localStorage, JSON, `🔍 Devtools View`)],
43
+ })
44
+
45
+ const devtoolsViewOptionsState = createStandaloneAtom<DevtoolsView[]>(store, {
46
+ key: `🔍 Devtools View Options`,
47
+ default: [`atoms`, `selectors`, `transactions`, `timelines`],
48
+ effects:
49
+ typeof window === `undefined`
50
+ ? []
51
+ : [persistSync(window.localStorage, JSON, `🔍 Devtools View Options`)],
52
+ })
53
+
54
+ const viewIsOpenAtoms = createAtomFamily<boolean, string>(store, {
55
+ key: `🔍 Devtools View Is Open`,
56
+ default: false,
57
+ effects: (key) =>
58
+ typeof window === `undefined`
59
+ ? []
60
+ : [persistSync(window.localStorage, JSON, key + `:view-is-open`)],
61
+ })
62
+
63
+ return {
64
+ ...introspectionStates,
65
+ devtoolsAreOpenState,
66
+ devtoolsViewSelectionState,
67
+ devtoolsViewOptionsState,
68
+ viewIsOpenAtoms,
69
+ store,
70
+ }
71
+ }
72
+
73
+ export const DevtoolsContext = createContext<
74
+ DevtoolsStates & IntrospectionStates & { store: Store }
75
+ >(attachDevtoolsStates(IMPLICIT.STORE))
@@ -8,11 +8,12 @@ import type {
8
8
  } from "atom.io"
9
9
  import {
10
10
  assignTransactionToContinuity,
11
- getUpdateToken,
12
11
  IMPLICIT,
13
12
  setEpochNumberOfContinuity,
14
13
  } from "atom.io/internal"
15
- import type { Canonical, Json } from "atom.io/json"
14
+ import type { Canonical } from "atom.io/json"
15
+
16
+ /* eslint-disable no-console */
16
17
 
17
18
  export class InvariantMap<K, V> extends Map<K, V> {
18
19
  public set(key: K, value: V): this {
@@ -4,6 +4,8 @@ import type { Json } from "atom.io/json"
4
4
  import { parseJson } from "atom.io/json"
5
5
  import type { Socket } from "socket.io-client"
6
6
 
7
+ /* eslint-disable no-console */
8
+
7
9
  export function pullAtomFamilyMember<J extends Json.Serializable>(
8
10
  token: AtomIO.RegularAtomToken<J>,
9
11
  socket: Socket,
@@ -5,6 +5,8 @@ import type { Json } from "atom.io/json"
5
5
  import { parseJson } from "atom.io/json"
6
6
  import type { Socket } from "socket.io-client"
7
7
 
8
+ /* eslint-disable no-console */
9
+
8
10
  export function pullMutableAtomFamilyMember<
9
11
  T extends Transceiver<any>,
10
12
  J extends Json.Serializable,
@@ -5,6 +5,8 @@ import type { Socket } from "socket.io-client"
5
5
  import { pullAtomFamilyMember } from "./pull-atom-family-member"
6
6
  import { pullMutableAtomFamilyMember } from "./pull-mutable-atom-family-member"
7
7
 
8
+ /* eslint-disable no-console */
9
+
8
10
  export function pullSelectorFamilyMember<T>(
9
11
  token: AtomIO.SelectorToken<T>,
10
12
  socket: Socket,
@@ -6,6 +6,8 @@ import { parseJson } from "atom.io/json"
6
6
  import type { EventBuffer, Events } from "./custom-socket"
7
7
  import { CustomSocket } from "./custom-socket"
8
8
 
9
+ /* eslint-disable no-console */
10
+
9
11
  export class ChildSocket<
10
12
  I extends Events,
11
13
  O extends Events & {
@@ -26,6 +26,8 @@ import { io } from "socket.io-client"
26
26
 
27
27
  let testNumber = 0
28
28
 
29
+ /* eslint-disable no-console */
30
+
29
31
  function prefixLogger(store: Store, prefix: string) {
30
32
  store.loggers[0] = new AtomIO.AtomIOLogger(`info`, undefined, {
31
33
  info: (...args) => {
package/src/logger.ts CHANGED
@@ -85,6 +85,7 @@ export type Logger = Record<LogLevel, LogFn>
85
85
  export const simpleLog =
86
86
  (logLevel: keyof Logger): LogFn =>
87
87
  (icon, denomination, tokenKey, message, ...rest) => {
88
+ /* eslint-disable-next-line no-console */
88
89
  console[logLevel](
89
90
  `${icon} ${denomination} "${tokenKey}" ${message}`,
90
91
  ...rest,
@@ -110,6 +110,7 @@ export class SetRTX<P extends primitive>
110
110
  this.emit(`tx:${this.transactionUpdates.join(`;`)}`)
111
111
  }
112
112
  } catch (thrown) {
113
+ /* eslint-disable-next-line no-console */
113
114
  console.error(`Failed to apply transaction to SetRTX:`, thrown)
114
115
  throw thrown
115
116
  } finally {