atom.io 0.27.4 → 0.28.0
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.
- package/data/dist/index.d.ts +31 -29
- package/data/dist/index.js +65 -81
- package/data/src/dict.ts +9 -12
- package/data/src/join.ts +30 -33
- package/data/src/struct-family.ts +17 -23
- package/data/src/struct.ts +9 -12
- package/dist/{chunk-JRENM6KL.js → chunk-BX3MTH2Z.js} +482 -385
- package/dist/chunk-D52JNVER.js +721 -0
- package/dist/chunk-EUVKUTW3.js +89 -0
- package/dist/index.d.ts +4 -3
- package/dist/index.js +35 -53
- package/ephemeral/dist/index.js +1 -1
- package/ephemeral/src/find-state.ts +1 -1
- package/immortal/dist/index.js +2 -2
- package/immortal/src/seek-state.ts +2 -2
- package/internal/dist/index.d.ts +141 -87
- package/internal/dist/index.js +1 -1
- package/internal/src/atom/create-regular-atom.ts +3 -3
- package/internal/src/atom/create-standalone-atom.ts +7 -5
- package/internal/src/atom/dispose-atom.ts +2 -9
- package/internal/src/families/create-atom-family.ts +5 -5
- package/internal/src/families/create-readonly-selector-family.ts +20 -9
- package/internal/src/families/create-regular-atom-family.ts +15 -6
- package/internal/src/families/create-selector-family.ts +5 -5
- package/internal/src/families/create-writable-selector-family.ts +20 -10
- package/internal/src/families/dispose-from-store.ts +43 -29
- package/internal/src/families/find-in-store.ts +28 -18
- package/internal/src/families/init-family-member.ts +9 -9
- package/internal/src/families/seek-in-store.ts +10 -10
- package/internal/src/get-state/get-from-store.ts +70 -47
- package/internal/src/ingest-updates/ingest-atom-update.ts +1 -1
- package/internal/src/ingest-updates/ingest-creation-disposal.ts +15 -6
- package/internal/src/molecule/create-molecule-family.ts +1 -1
- package/internal/src/molecule/dispose-molecule.ts +7 -18
- package/internal/src/molecule/grow-molecule-in-store.ts +1 -1
- package/internal/src/molecule/make-molecule-in-store.ts +5 -5
- package/internal/src/mutable/create-mutable-atom-family.ts +15 -6
- package/internal/src/mutable/create-mutable-atom.ts +3 -3
- package/internal/src/mutable/get-json-token.ts +2 -2
- package/internal/src/mutable/tracker-family.ts +3 -3
- package/internal/src/mutable/tracker.ts +14 -18
- package/internal/src/pretty-print.ts +1 -16
- package/internal/src/selector/create-readonly-selector.ts +2 -2
- package/internal/src/selector/create-standalone-selector.ts +5 -5
- package/internal/src/selector/create-writable-selector.ts +2 -2
- package/internal/src/selector/dispose-selector.ts +2 -9
- package/internal/src/selector/register-selector.ts +9 -9
- package/internal/src/set-state/set-into-store.ts +23 -33
- package/internal/src/store/circular-buffer.ts +34 -0
- package/internal/src/store/counterfeit.ts +109 -0
- package/internal/src/store/deposit.ts +67 -13
- package/internal/src/store/index.ts +1 -0
- package/internal/src/store/store.ts +4 -1
- package/internal/src/store/withdraw.ts +15 -10
- package/internal/src/subscribe/index.ts +2 -0
- package/internal/src/subscribe/subscribe-in-store.ts +62 -0
- package/internal/src/timeline/time-travel.ts +1 -1
- package/internal/src/transaction/build-transaction.ts +7 -6
- package/introspection/dist/index.d.ts +84 -4
- package/introspection/dist/index.js +1 -413
- package/introspection/src/attach-atom-index.ts +5 -8
- package/introspection/src/attach-introspection-states.ts +7 -4
- package/introspection/src/attach-selector-index.ts +6 -8
- package/introspection/src/attach-timeline-family.ts +25 -28
- package/introspection/src/attach-timeline-index.ts +5 -8
- package/introspection/src/attach-transaction-index.ts +5 -8
- package/introspection/src/attach-transaction-logs.ts +21 -27
- package/introspection/src/attach-type-selectors.ts +26 -0
- package/introspection/src/differ.ts +167 -0
- package/introspection/src/index.ts +2 -0
- package/introspection/src/refinery.ts +100 -0
- package/json/dist/index.d.ts +31 -30
- package/json/dist/index.js +2 -80
- package/json/src/entries.ts +6 -0
- package/json/src/index.ts +47 -6
- package/json/src/select-json-family.ts +4 -4
- package/json/src/select-json.ts +6 -9
- package/package.json +17 -8
- package/react/dist/index.js +7 -7
- package/react/src/parse-state-overloads.ts +2 -2
- package/react/src/use-i.ts +1 -1
- package/react/src/use-json.ts +2 -2
- package/react/src/use-o.ts +2 -2
- package/react-devtools/dist/index.d.ts +1 -91
- package/react-devtools/dist/index.js +285 -414
- package/react-devtools/src/AtomIODevtools.tsx +2 -2
- package/react-devtools/src/StateEditor.tsx +20 -12
- package/react-devtools/src/StateIndex.tsx +8 -26
- package/react-devtools/src/TimelineIndex.tsx +3 -3
- package/react-devtools/src/TransactionIndex.tsx +6 -6
- package/react-devtools/src/Updates.tsx +1 -4
- package/react-devtools/src/index.ts +0 -71
- package/react-devtools/src/store.ts +51 -0
- package/realtime/dist/index.d.ts +7 -7
- package/realtime/dist/index.js +18 -22
- package/realtime/src/realtime-continuity.ts +27 -35
- package/realtime-client/dist/index.js +59 -65
- package/realtime-client/src/pull-atom-family-member.ts +1 -1
- package/realtime-client/src/pull-atom.ts +1 -1
- package/realtime-client/src/pull-mutable-atom-family-member.ts +3 -3
- package/realtime-client/src/pull-mutable-atom.ts +3 -3
- package/realtime-client/src/realtime-client-stores/client-main-store.ts +6 -6
- package/realtime-client/src/sync-continuity.ts +55 -53
- package/realtime-react/dist/index.js +3 -3
- package/realtime-react/src/use-pull-atom-family-member.ts +1 -1
- package/realtime-react/src/use-pull-mutable-family-member.ts +1 -1
- package/realtime-react/src/use-pull-selector-family-member.ts +1 -1
- package/realtime-server/dist/index.js +72 -36
- package/realtime-server/src/realtime-continuity-synchronizer.ts +57 -93
- package/realtime-server/src/realtime-family-provider.ts +3 -3
- package/realtime-server/src/realtime-mutable-family-provider.ts +5 -5
- package/realtime-server/src/realtime-mutable-provider.ts +2 -2
- package/realtime-server/src/realtime-state-provider.ts +1 -1
- package/realtime-server/src/realtime-state-receiver.ts +1 -1
- package/realtime-testing/dist/index.d.ts +2 -0
- package/realtime-testing/dist/index.js +57 -15
- package/realtime-testing/src/setup-realtime-test.tsx +66 -16
- package/src/atom.ts +2 -2
- package/src/dispose-state.ts +2 -2
- package/src/get-state.ts +9 -13
- package/src/molecule.ts +1 -1
- package/src/selector.ts +2 -2
- package/src/set-state.ts +10 -7
- package/src/silo.ts +29 -55
- package/src/subscribe.ts +3 -23
- package/src/timeline.ts +2 -2
- package/web/dist/index.d.ts +9 -0
- package/{dist/chunk-H6EDLPKH.js → web/dist/index.js} +5 -4
- package/web/package.json +13 -0
- package/web/src/index.ts +1 -0
- package/web/src/persist-sync.ts +25 -0
- package/dist/chunk-AK23DRMD.js +0 -21
- package/dist/chunk-IW6WYRS7.js +0 -140
- package/internal/src/families/throw-in-case-of-conflicting-family.ts +0 -18
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { ReadonlySelectorFamilyToken } from "atom.io"
|
|
2
|
+
import type { Store } from "atom.io/internal"
|
|
3
|
+
import { createReadonlySelectorFamily, IMPLICIT } from "atom.io/internal"
|
|
4
|
+
|
|
5
|
+
import { discoverType } from "./refinery"
|
|
6
|
+
|
|
7
|
+
export const attachTypeSelectors = (
|
|
8
|
+
store: Store = IMPLICIT.STORE,
|
|
9
|
+
): ReadonlySelectorFamilyToken<string, string> => {
|
|
10
|
+
const typeSelectors = createReadonlySelectorFamily<string, string>(store, {
|
|
11
|
+
key: `👁🗨 State Type`,
|
|
12
|
+
get:
|
|
13
|
+
(token) =>
|
|
14
|
+
({ get }) => {
|
|
15
|
+
let state: unknown
|
|
16
|
+
try {
|
|
17
|
+
state = get(token as any)
|
|
18
|
+
} catch (error) {
|
|
19
|
+
return `error`
|
|
20
|
+
}
|
|
21
|
+
const typeOfState = discoverType(state)
|
|
22
|
+
return typeOfState
|
|
23
|
+
},
|
|
24
|
+
})
|
|
25
|
+
return typeSelectors
|
|
26
|
+
}
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import { sprawl } from "anvl/object"
|
|
2
|
+
import type { Json } from "atom.io/json"
|
|
3
|
+
|
|
4
|
+
import type { Refinery, Supported } from "./refinery"
|
|
5
|
+
import { discoverType, jsonTreeRefinery, primitiveRefinery } from "./refinery"
|
|
6
|
+
|
|
7
|
+
export function diffNumber(a: number, b: number): Delta {
|
|
8
|
+
const sign = a < b ? `+` : `-`
|
|
9
|
+
return {
|
|
10
|
+
summary: `${sign}${Math.abs(a - b)} (${a} → ${b})`,
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function diffString(a: string, b: string): Delta {
|
|
15
|
+
const sign = a.length < b.length ? `+` : `-`
|
|
16
|
+
return {
|
|
17
|
+
summary: `${sign}${Math.abs(a.length - b.length)} ("${a}" → "${b}")`,
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function diffBoolean(a: boolean, b: boolean): Delta {
|
|
22
|
+
return {
|
|
23
|
+
summary: `${a} → ${b}`,
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function diffObject(
|
|
28
|
+
a: Json.Tree.Object,
|
|
29
|
+
b: Json.Tree.Object,
|
|
30
|
+
recurse: Diff<unknown>,
|
|
31
|
+
): Delta {
|
|
32
|
+
let summary = ``
|
|
33
|
+
const added: Delta[`added`] = []
|
|
34
|
+
const removed: Delta[`removed`] = []
|
|
35
|
+
const changed: Delta[`changed`] = []
|
|
36
|
+
|
|
37
|
+
sprawl(a, (path, nodeA) => {
|
|
38
|
+
let key: string
|
|
39
|
+
for (key of path) {
|
|
40
|
+
const nodeB = b[key]
|
|
41
|
+
if (nodeB === undefined) {
|
|
42
|
+
removed.push([key, JSON.stringify(nodeA)])
|
|
43
|
+
} else {
|
|
44
|
+
const delta = recurse(nodeA, nodeB)
|
|
45
|
+
if (delta.summary !== `No Change`) {
|
|
46
|
+
changed.push([key, delta])
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
sprawl(b, (path, nodeB) => {
|
|
53
|
+
let key: string
|
|
54
|
+
for (key of path) {
|
|
55
|
+
const nodeA = a[key]
|
|
56
|
+
if (nodeA === undefined) {
|
|
57
|
+
added.push([key, JSON.stringify(nodeB)])
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
summary = `~${changed.length} +${added.length} -${removed.length}`
|
|
63
|
+
|
|
64
|
+
return {
|
|
65
|
+
summary,
|
|
66
|
+
added,
|
|
67
|
+
removed,
|
|
68
|
+
changed,
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export function diffArray(
|
|
73
|
+
a: Json.Tree.Array,
|
|
74
|
+
b: Json.Tree.Array,
|
|
75
|
+
recurse: Diff<unknown>,
|
|
76
|
+
): Delta {
|
|
77
|
+
return diffObject(a as any, b as any, recurse)
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
type Delta = {
|
|
81
|
+
summary: string
|
|
82
|
+
added?: [path: string, addedStringifiedValue: string][]
|
|
83
|
+
removed?: [path: string, removedStringifiedValue: string][]
|
|
84
|
+
changed?: [path: string, delta: Delta][]
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
type Diff<T> = (a: T, b: T) => Delta
|
|
88
|
+
type DiffTree<T> = (a: T, b: T, recurse: Differ<any, any>[`diff`]) => Delta
|
|
89
|
+
|
|
90
|
+
export class Differ<
|
|
91
|
+
Leaf extends Record<string, any>,
|
|
92
|
+
Tree extends Record<string, any>,
|
|
93
|
+
> {
|
|
94
|
+
public leafRefinery: Refinery<Leaf>
|
|
95
|
+
public treeRefinery: Refinery<Tree>
|
|
96
|
+
public leafDiffers: { [KL in keyof Leaf]: Diff<Supported<Leaf[KL]>> }
|
|
97
|
+
public treeDiffers: { [KT in keyof Tree]: DiffTree<Supported<Tree[KT]>> }
|
|
98
|
+
|
|
99
|
+
public constructor(
|
|
100
|
+
leafRefinery: Refinery<Leaf>,
|
|
101
|
+
treeRefinery: Refinery<Tree>,
|
|
102
|
+
diffFunctions: {
|
|
103
|
+
[KT in keyof Tree]: DiffTree<Supported<Tree[KT]>>
|
|
104
|
+
} & { [KL in keyof Leaf]: Diff<Supported<Leaf[KL]>> },
|
|
105
|
+
) {
|
|
106
|
+
this.leafRefinery = leafRefinery
|
|
107
|
+
this.treeRefinery = treeRefinery
|
|
108
|
+
this.leafDiffers = {} as any
|
|
109
|
+
this.treeDiffers = {} as any
|
|
110
|
+
for (const key of Object.keys(leafRefinery.supported)) {
|
|
111
|
+
const diffFunction = diffFunctions[key]
|
|
112
|
+
this.leafDiffers[key as keyof Leaf] = diffFunction
|
|
113
|
+
}
|
|
114
|
+
for (const key of Object.keys(treeRefinery.supported)) {
|
|
115
|
+
const diffFunction = diffFunctions[key]
|
|
116
|
+
this.treeDiffers[key as keyof Tree] = diffFunction
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
public diff(a: unknown, b: unknown): Delta {
|
|
121
|
+
if (a === b) {
|
|
122
|
+
return { summary: `No Change` }
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
const aRefined = this.leafRefinery.refine(a) ?? this.treeRefinery.refine(a)
|
|
126
|
+
const bRefined = this.leafRefinery.refine(b) ?? this.treeRefinery.refine(b)
|
|
127
|
+
|
|
128
|
+
if (aRefined !== null && bRefined !== null) {
|
|
129
|
+
if (aRefined.type === bRefined.type) {
|
|
130
|
+
if (aRefined.type in this.leafDiffers) {
|
|
131
|
+
const delta = this.leafDiffers[aRefined.type](
|
|
132
|
+
aRefined.data,
|
|
133
|
+
bRefined.data,
|
|
134
|
+
)
|
|
135
|
+
return delta
|
|
136
|
+
}
|
|
137
|
+
if (aRefined.type in this.treeDiffers) {
|
|
138
|
+
const delta = this.treeDiffers[aRefined.type](
|
|
139
|
+
aRefined.data,
|
|
140
|
+
bRefined.data,
|
|
141
|
+
(x, y) => this.diff(x, y),
|
|
142
|
+
)
|
|
143
|
+
return delta
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
const typeA = discoverType(a)
|
|
148
|
+
const typeB = discoverType(b)
|
|
149
|
+
if (typeA === typeB) {
|
|
150
|
+
return {
|
|
151
|
+
summary: `${typeA} → ${typeB}`,
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
return {
|
|
155
|
+
summary: `Type change: ${typeA} → ${typeB}`,
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
export const prettyJson = new Differ(primitiveRefinery, jsonTreeRefinery, {
|
|
161
|
+
number: diffNumber,
|
|
162
|
+
string: diffString,
|
|
163
|
+
boolean: diffBoolean,
|
|
164
|
+
null: () => ({ summary: `No Change` }),
|
|
165
|
+
object: diffObject,
|
|
166
|
+
array: diffArray,
|
|
167
|
+
})
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import type { Flat } from "atom.io/internal"
|
|
2
|
+
import type { Json } from "atom.io/json"
|
|
3
|
+
|
|
4
|
+
export type Refinement<A, B extends A> = (a: A) => a is B
|
|
5
|
+
|
|
6
|
+
export type ClassSignature = abstract new (...args: any) => any
|
|
7
|
+
|
|
8
|
+
export type RefinementStrategy = ClassSignature | Refinement<unknown, any>
|
|
9
|
+
|
|
10
|
+
export type Supported<Refine extends RefinementStrategy> =
|
|
11
|
+
Refine extends Refinement<unknown, infer T>
|
|
12
|
+
? T
|
|
13
|
+
: Refine extends ClassSignature
|
|
14
|
+
? InstanceType<Refine>
|
|
15
|
+
: never
|
|
16
|
+
|
|
17
|
+
export type RefinementSupport = Record<string, RefinementStrategy>
|
|
18
|
+
|
|
19
|
+
export class Refinery<SupportedTypes extends RefinementSupport> {
|
|
20
|
+
public supported: SupportedTypes
|
|
21
|
+
|
|
22
|
+
public constructor(supported: SupportedTypes) {
|
|
23
|
+
this.supported = supported
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
public refine<T>(input: T):
|
|
27
|
+
| Flat<{
|
|
28
|
+
[K in keyof SupportedTypes]: T extends Supported<SupportedTypes[K]>
|
|
29
|
+
? {
|
|
30
|
+
type: K
|
|
31
|
+
data: Supported<SupportedTypes[K]>
|
|
32
|
+
}
|
|
33
|
+
: Supported<SupportedTypes[K]> extends T
|
|
34
|
+
? {
|
|
35
|
+
type: K
|
|
36
|
+
data: Supported<SupportedTypes[K]>
|
|
37
|
+
}
|
|
38
|
+
: never
|
|
39
|
+
}>[keyof SupportedTypes]
|
|
40
|
+
| (T extends Supported<SupportedTypes[keyof SupportedTypes]>
|
|
41
|
+
? never
|
|
42
|
+
: null) {
|
|
43
|
+
for (const [key, refiner] of Object.entries(this.supported)) {
|
|
44
|
+
try {
|
|
45
|
+
if (
|
|
46
|
+
// @ts-expect-error that's the point
|
|
47
|
+
refiner(input) === true &&
|
|
48
|
+
refiner !== Boolean
|
|
49
|
+
) {
|
|
50
|
+
return { type: key, data: input } as any
|
|
51
|
+
}
|
|
52
|
+
} catch (_) {
|
|
53
|
+
try {
|
|
54
|
+
if (input instanceof refiner) {
|
|
55
|
+
return { type: key, data: input } as any
|
|
56
|
+
}
|
|
57
|
+
} catch (__) {}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return null as any
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export const primitiveRefinery = new Refinery({
|
|
65
|
+
number: (input: unknown): input is number => typeof input === `number`,
|
|
66
|
+
string: (input: unknown): input is string => typeof input === `string`,
|
|
67
|
+
boolean: (input: unknown): input is boolean => typeof input === `boolean`,
|
|
68
|
+
null: (input: unknown): input is null => input === null,
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
export const jsonTreeRefinery = new Refinery({
|
|
72
|
+
object: (input: unknown): input is Json.Tree.Object => {
|
|
73
|
+
if (!input) {
|
|
74
|
+
return false
|
|
75
|
+
}
|
|
76
|
+
const prototype = Object.getPrototypeOf(input)
|
|
77
|
+
return prototype === Object.prototype
|
|
78
|
+
},
|
|
79
|
+
array: (input: unknown): input is Json.Tree.Array => Array.isArray(input),
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
export const jsonRefinery = new Refinery({
|
|
83
|
+
...primitiveRefinery.supported,
|
|
84
|
+
...jsonTreeRefinery.supported,
|
|
85
|
+
})
|
|
86
|
+
|
|
87
|
+
export type JsonType = keyof typeof jsonRefinery.supported
|
|
88
|
+
|
|
89
|
+
export const discoverType = (
|
|
90
|
+
input: unknown,
|
|
91
|
+
): JsonType | `Map` | `Set` | `undefined` | (string & {}) => {
|
|
92
|
+
if (input === undefined) {
|
|
93
|
+
return `undefined`
|
|
94
|
+
}
|
|
95
|
+
const refined = jsonRefinery.refine(input)
|
|
96
|
+
if (refined) {
|
|
97
|
+
return refined.type
|
|
98
|
+
}
|
|
99
|
+
return Object.getPrototypeOf(input).constructor.name
|
|
100
|
+
}
|
package/json/dist/index.d.ts
CHANGED
|
@@ -1,31 +1,6 @@
|
|
|
1
1
|
import { Range, Flat, Store, Transceiver } from 'atom.io/internal';
|
|
2
2
|
import * as AtomIO from 'atom.io';
|
|
3
3
|
|
|
4
|
-
type JsonInterface<T, J extends Serializable = Serializable> = {
|
|
5
|
-
toJson: (t: T) => J;
|
|
6
|
-
fromJson: (json: J) => T;
|
|
7
|
-
};
|
|
8
|
-
|
|
9
|
-
type primitive = boolean | number | string | null;
|
|
10
|
-
|
|
11
|
-
type Serializable = primitive | Readonly<{
|
|
12
|
-
[key: string]: Serializable;
|
|
13
|
-
}> | ReadonlyArray<Serializable>;
|
|
14
|
-
type Object$1<Key extends string = string, Value extends Serializable = Serializable> = Record<Key, Value>;
|
|
15
|
-
type Array<Element extends Serializable = Serializable> = ReadonlyArray<Element>;
|
|
16
|
-
|
|
17
|
-
type json_Array<Element extends Serializable = Serializable> = Array<Element>;
|
|
18
|
-
type json_Serializable = Serializable;
|
|
19
|
-
declare namespace json {
|
|
20
|
-
export type { json_Array as Array, Object$1 as Object, json_Serializable as Serializable };
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
declare const parseJson: <S extends stringified<Serializable>>(str: S | string) => S extends stringified<infer J> ? J : Serializable;
|
|
24
|
-
type stringified<J extends Serializable> = string & {
|
|
25
|
-
__json: J;
|
|
26
|
-
};
|
|
27
|
-
declare const stringifyJson: <J extends Serializable>(json: J) => stringified<J>;
|
|
28
|
-
|
|
29
4
|
type Entries<K extends keyof any = keyof any, V = any> = [K, V][];
|
|
30
5
|
type KeyOfEntries<E extends Entries> = E extends [infer K, any][] ? K : never;
|
|
31
6
|
type ValueOfEntry<E extends Entries, K extends KeyOfEntries<E>> = {
|
|
@@ -35,13 +10,39 @@ type FromEntries<E extends Entries> = Flat<{
|
|
|
35
10
|
[K in KeyOfEntries<E>]: ValueOfEntry<E, K>;
|
|
36
11
|
}>;
|
|
37
12
|
declare function fromEntries<E extends Entries>(entries: E): FromEntries<E>;
|
|
13
|
+
declare function toEntries<T extends object>(obj: T): Entries<keyof T, T[keyof T]>;
|
|
38
14
|
|
|
39
|
-
declare const selectJson: <T, J extends Serializable>(atom: AtomIO.AtomToken<T>, transform: JsonInterface<T, J>, store?: Store) => AtomIO.WritableSelectorToken<J>;
|
|
15
|
+
declare const selectJson: <T, J extends Json.Serializable>(atom: AtomIO.AtomToken<T>, transform: JsonInterface<T, J>, store?: Store) => AtomIO.WritableSelectorToken<J>;
|
|
40
16
|
|
|
41
|
-
declare function selectJsonFamily<T extends Transceiver<any>, J extends Serializable, K extends Canonical>(atomFamilyToken: AtomIO.MutableAtomFamilyToken<T, J, K>, transform: JsonInterface<T, J>, store: Store): AtomIO.WritableSelectorFamilyToken<J, K>;
|
|
42
|
-
declare function selectJsonFamily<T, J extends Serializable, K extends Canonical>(atomFamilyToken: AtomIO.RegularAtomFamilyToken<T, K>, transform: JsonInterface<T, J>, store: Store): AtomIO.WritableSelectorFamilyToken<J, K>;
|
|
17
|
+
declare function selectJsonFamily<T extends Transceiver<any>, J extends Json.Serializable, K extends Canonical>(atomFamilyToken: AtomIO.MutableAtomFamilyToken<T, J, K>, transform: JsonInterface<T, J>, store: Store): AtomIO.WritableSelectorFamilyToken<J, K>;
|
|
18
|
+
declare function selectJsonFamily<T, J extends Json.Serializable, K extends Canonical>(atomFamilyToken: AtomIO.RegularAtomFamilyToken<T, K>, transform: JsonInterface<T, J>, store: Store): AtomIO.WritableSelectorFamilyToken<J, K>;
|
|
43
19
|
|
|
20
|
+
type primitive = boolean | number | string | null;
|
|
21
|
+
declare namespace Json {
|
|
22
|
+
namespace Tree {
|
|
23
|
+
type Array<Element = unknown> = ReadonlyArray<Element>;
|
|
24
|
+
type Object<K extends string = string, V = unknown> = Record<K, V>;
|
|
25
|
+
type Fork = Array | Object;
|
|
26
|
+
type Leaf = primitive;
|
|
27
|
+
type Node = Fork | Leaf;
|
|
28
|
+
}
|
|
29
|
+
type Serializable = primitive | Readonly<{
|
|
30
|
+
[key: string]: Serializable;
|
|
31
|
+
}> | ReadonlyArray<Serializable>;
|
|
32
|
+
type Object<Key extends string = string, Value extends Serializable = Serializable> = Record<Key, Value>;
|
|
33
|
+
type Array<Element extends Serializable = Serializable> = ReadonlyArray<Element>;
|
|
34
|
+
}
|
|
35
|
+
type stringified<J extends Json.Serializable> = string & {
|
|
36
|
+
__json: J;
|
|
37
|
+
};
|
|
38
|
+
declare const parseJson: <S extends stringified<Json.Serializable>>(str: S | string) => S extends stringified<infer J> ? J : Json.Serializable;
|
|
39
|
+
declare const stringifyJson: <J extends Json.Serializable>(json: J) => stringified<J>;
|
|
44
40
|
type Canonical = primitive | ReadonlyArray<Canonical>;
|
|
45
|
-
type JsonIO = (...params: Serializable[]) => Serializable | void;
|
|
41
|
+
type JsonIO = (...params: Json.Serializable[]) => Json.Serializable | void;
|
|
42
|
+
type JsonInterface<T, J extends Json.Serializable = Json.Serializable> = {
|
|
43
|
+
toJson: (t: T) => J;
|
|
44
|
+
fromJson: (json: J) => T;
|
|
45
|
+
};
|
|
46
|
+
declare const isJson: (input: unknown) => input is Json.Tree.Node;
|
|
46
47
|
|
|
47
|
-
export { type Canonical, type Entries, type FromEntries,
|
|
48
|
+
export { type Canonical, type Entries, type FromEntries, Json, type JsonIO, type JsonInterface, type KeyOfEntries, type ValueOfEntry, fromEntries, isJson, parseJson, type primitive, selectJson, selectJsonFamily, type stringified, stringifyJson, toEntries };
|
package/json/dist/index.js
CHANGED
|
@@ -1,82 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
import { createWritableSelectorFamily } from '../../dist/chunk-JRENM6KL.js';
|
|
1
|
+
export { fromEntries, isJson, parseJson, selectJson, selectJsonFamily, stringifyJson, toEntries } from '../../dist/chunk-EUVKUTW3.js';
|
|
2
|
+
import '../../dist/chunk-BX3MTH2Z.js';
|
|
4
3
|
import '../../dist/chunk-IBTHB2PI.js';
|
|
5
4
|
import '../../dist/chunk-XWL6SNVU.js';
|
|
6
|
-
import { createStandaloneSelector, IMPLICIT, growMoleculeInStore, initFamilyMemberInStore, withdraw, seekInStore } from 'atom.io/internal';
|
|
7
|
-
|
|
8
|
-
// json/src/entries.ts
|
|
9
|
-
function fromEntries(entries) {
|
|
10
|
-
return Object.fromEntries(entries);
|
|
11
|
-
}
|
|
12
|
-
var selectJson = (atom, transform, store = IMPLICIT.STORE) => {
|
|
13
|
-
return createStandaloneSelector(
|
|
14
|
-
{
|
|
15
|
-
key: `${atom.key}:JSON`,
|
|
16
|
-
get: ({ get }) => transform.toJson(get(atom)),
|
|
17
|
-
set: ({ set }, newValue) => {
|
|
18
|
-
set(atom, transform.fromJson(newValue));
|
|
19
|
-
}
|
|
20
|
-
},
|
|
21
|
-
store
|
|
22
|
-
);
|
|
23
|
-
};
|
|
24
|
-
function selectJsonFamily(atomFamilyToken, transform, store = IMPLICIT.STORE) {
|
|
25
|
-
const jsonFamily = createWritableSelectorFamily(
|
|
26
|
-
{
|
|
27
|
-
key: `${atomFamilyToken.key}:JSON`,
|
|
28
|
-
get: (key) => ({ seek, get }) => {
|
|
29
|
-
const existingState = seek(atomFamilyToken, key);
|
|
30
|
-
if (existingState) {
|
|
31
|
-
return transform.toJson(get(existingState));
|
|
32
|
-
}
|
|
33
|
-
const stringKey = stringifyJson(key);
|
|
34
|
-
const molecule = store.molecules.get(stringKey);
|
|
35
|
-
if (molecule) {
|
|
36
|
-
const atom = growMoleculeInStore(molecule, atomFamilyToken, store);
|
|
37
|
-
return transform.toJson(get(atom));
|
|
38
|
-
}
|
|
39
|
-
if (store.config.lifespan === `immortal`) {
|
|
40
|
-
throw new Error(`No molecule found for key "${stringKey}"`);
|
|
41
|
-
}
|
|
42
|
-
const newToken = initFamilyMemberInStore(atomFamilyToken, key, store);
|
|
43
|
-
return transform.toJson(get(newToken));
|
|
44
|
-
},
|
|
45
|
-
set: (key) => ({ seek, set }, newValue) => {
|
|
46
|
-
const existingState = seek(atomFamilyToken, key);
|
|
47
|
-
if (existingState) {
|
|
48
|
-
set(existingState, transform.fromJson(newValue));
|
|
49
|
-
} else {
|
|
50
|
-
const stringKey = stringifyJson(key);
|
|
51
|
-
const molecule = store.molecules.get(stringKey);
|
|
52
|
-
if (molecule) {
|
|
53
|
-
const atom = growMoleculeInStore(molecule, atomFamilyToken, store);
|
|
54
|
-
set(atom, transform.fromJson(newValue));
|
|
55
|
-
} else {
|
|
56
|
-
if (store.config.lifespan === `immortal`) {
|
|
57
|
-
throw new Error(`No molecule found for key "${stringKey}"`);
|
|
58
|
-
}
|
|
59
|
-
set(
|
|
60
|
-
initFamilyMemberInStore(atomFamilyToken, key, store),
|
|
61
|
-
transform.fromJson(newValue)
|
|
62
|
-
);
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
},
|
|
67
|
-
store,
|
|
68
|
-
[`mutable`, `json`]
|
|
69
|
-
);
|
|
70
|
-
const atomFamily = withdraw(atomFamilyToken, store);
|
|
71
|
-
atomFamily.subject.subscribe(
|
|
72
|
-
`store=${store.config.name}::json-selector-family`,
|
|
73
|
-
(event) => {
|
|
74
|
-
if (event.token.family) {
|
|
75
|
-
seekInStore(jsonFamily, parseJson(event.token.family.subKey), store);
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
);
|
|
79
|
-
return jsonFamily;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
export { fromEntries, selectJson, selectJsonFamily };
|
package/json/src/entries.ts
CHANGED
|
@@ -17,3 +17,9 @@ export type FromEntries<E extends Entries> = Flat<{
|
|
|
17
17
|
export function fromEntries<E extends Entries>(entries: E): FromEntries<E> {
|
|
18
18
|
return Object.fromEntries(entries) as FromEntries<E>
|
|
19
19
|
}
|
|
20
|
+
|
|
21
|
+
export function toEntries<T extends object>(
|
|
22
|
+
obj: T,
|
|
23
|
+
): Entries<keyof T, T[keyof T]> {
|
|
24
|
+
return Object.entries(obj) as Entries<keyof T, T[keyof T]>
|
|
25
|
+
}
|
package/json/src/index.ts
CHANGED
|
@@ -1,14 +1,55 @@
|
|
|
1
|
-
import type { Json, JsonInterface, stringified } from "~/packages/anvl/src/json"
|
|
2
|
-
import { parseJson, stringifyJson } from "~/packages/anvl/src/json"
|
|
3
|
-
import type { primitive } from "~/packages/anvl/src/primitive"
|
|
4
|
-
|
|
5
1
|
export * from "./entries"
|
|
6
2
|
export * from "./select-json"
|
|
7
3
|
export * from "./select-json-family"
|
|
8
4
|
|
|
9
|
-
export type
|
|
10
|
-
|
|
5
|
+
export type primitive = boolean | number | string | null
|
|
6
|
+
|
|
7
|
+
export namespace Json {
|
|
8
|
+
export namespace Tree {
|
|
9
|
+
export type Array<Element = unknown> = ReadonlyArray<Element>
|
|
10
|
+
export type Object<K extends string = string, V = unknown> = Record<K, V>
|
|
11
|
+
export type Fork = Array | Object
|
|
12
|
+
export type Leaf = primitive
|
|
13
|
+
export type Node = Fork | Leaf
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export type Serializable =
|
|
17
|
+
| primitive
|
|
18
|
+
| Readonly<{ [key: string]: Serializable }>
|
|
19
|
+
| ReadonlyArray<Serializable>
|
|
20
|
+
|
|
21
|
+
export type Object<
|
|
22
|
+
Key extends string = string,
|
|
23
|
+
Value extends Serializable = Serializable,
|
|
24
|
+
> = Record<Key, Value>
|
|
25
|
+
|
|
26
|
+
export type Array<Element extends Serializable = Serializable> =
|
|
27
|
+
ReadonlyArray<Element>
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export type stringified<J extends Json.Serializable> = string & { __json: J }
|
|
31
|
+
|
|
32
|
+
export const parseJson = <S extends stringified<Json.Serializable>>(
|
|
33
|
+
str: S | string,
|
|
34
|
+
): S extends stringified<infer J> ? J : Json.Serializable => JSON.parse(str)
|
|
35
|
+
|
|
36
|
+
export const stringifyJson = <J extends Json.Serializable>(
|
|
37
|
+
json: J,
|
|
38
|
+
): stringified<J> => JSON.stringify(json) as stringified<J>
|
|
11
39
|
|
|
12
40
|
export type Canonical = primitive | ReadonlyArray<Canonical>
|
|
13
41
|
|
|
14
42
|
export type JsonIO = (...params: Json.Serializable[]) => Json.Serializable | void
|
|
43
|
+
|
|
44
|
+
export type JsonInterface<T, J extends Json.Serializable = Json.Serializable> = {
|
|
45
|
+
toJson: (t: T) => J
|
|
46
|
+
fromJson: (json: J) => T
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const JSON_PROTOTYPES = [Array, Boolean, Number, Object, String] as const
|
|
50
|
+
export const isJson = (input: unknown): input is Json.Tree.Node => {
|
|
51
|
+
if (input === null) return true
|
|
52
|
+
if (input === undefined) return false
|
|
53
|
+
const prototype = Object.getPrototypeOf(input)
|
|
54
|
+
return JSON_PROTOTYPES.includes(prototype)
|
|
55
|
+
}
|
|
@@ -42,6 +42,7 @@ export function selectJsonFamily<
|
|
|
42
42
|
store: Store = IMPLICIT.STORE,
|
|
43
43
|
): AtomIO.WritableSelectorFamilyToken<J, K> {
|
|
44
44
|
const jsonFamily = createWritableSelectorFamily<J, K>(
|
|
45
|
+
store,
|
|
45
46
|
{
|
|
46
47
|
key: `${atomFamilyToken.key}:JSON`,
|
|
47
48
|
get:
|
|
@@ -60,7 +61,7 @@ export function selectJsonFamily<
|
|
|
60
61
|
if (store.config.lifespan === `immortal`) {
|
|
61
62
|
throw new Error(`No molecule found for key "${stringKey}"`)
|
|
62
63
|
}
|
|
63
|
-
const newToken = initFamilyMemberInStore(atomFamilyToken, key
|
|
64
|
+
const newToken = initFamilyMemberInStore(store, atomFamilyToken, key)
|
|
64
65
|
return transform.toJson(get(newToken))
|
|
65
66
|
},
|
|
66
67
|
set:
|
|
@@ -80,14 +81,13 @@ export function selectJsonFamily<
|
|
|
80
81
|
throw new Error(`No molecule found for key "${stringKey}"`)
|
|
81
82
|
}
|
|
82
83
|
set(
|
|
83
|
-
initFamilyMemberInStore(atomFamilyToken, key
|
|
84
|
+
initFamilyMemberInStore(store, atomFamilyToken, key),
|
|
84
85
|
transform.fromJson(newValue),
|
|
85
86
|
)
|
|
86
87
|
}
|
|
87
88
|
}
|
|
88
89
|
},
|
|
89
90
|
},
|
|
90
|
-
store,
|
|
91
91
|
[`mutable`, `json`],
|
|
92
92
|
)
|
|
93
93
|
const atomFamily = withdraw(atomFamilyToken, store)
|
|
@@ -95,7 +95,7 @@ export function selectJsonFamily<
|
|
|
95
95
|
`store=${store.config.name}::json-selector-family`,
|
|
96
96
|
(event) => {
|
|
97
97
|
if (event.token.family) {
|
|
98
|
-
seekInStore(jsonFamily, parseJson(event.token.family.subKey) as K
|
|
98
|
+
seekInStore(store, jsonFamily, parseJson(event.token.family.subKey) as K)
|
|
99
99
|
}
|
|
100
100
|
},
|
|
101
101
|
)
|
package/json/src/select-json.ts
CHANGED
|
@@ -9,14 +9,11 @@ export const selectJson = <T, J extends Json.Serializable>(
|
|
|
9
9
|
transform: JsonInterface<T, J>,
|
|
10
10
|
store: Store = IMPLICIT.STORE,
|
|
11
11
|
): AtomIO.WritableSelectorToken<J> => {
|
|
12
|
-
return createStandaloneSelector(
|
|
13
|
-
{
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
set
|
|
17
|
-
set(atom, transform.fromJson(newValue))
|
|
18
|
-
},
|
|
12
|
+
return createStandaloneSelector(store, {
|
|
13
|
+
key: `${atom.key}:JSON`,
|
|
14
|
+
get: ({ get }) => transform.toJson(get(atom)),
|
|
15
|
+
set: ({ set }, newValue) => {
|
|
16
|
+
set(atom, transform.fromJson(newValue))
|
|
19
17
|
},
|
|
20
|
-
|
|
21
|
-
)
|
|
18
|
+
})
|
|
22
19
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "atom.io",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.28.0",
|
|
4
4
|
"description": "Composable and testable reactive data library.",
|
|
5
5
|
"homepage": "https://atom.io.fyi",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -57,18 +57,18 @@
|
|
|
57
57
|
"@types/estree": "1.0.5",
|
|
58
58
|
"@types/http-proxy": "1.17.15",
|
|
59
59
|
"@types/npmlog": "7.0.0",
|
|
60
|
-
"@types/react": "18.3.
|
|
60
|
+
"@types/react": "18.3.4",
|
|
61
61
|
"@types/tmp": "0.2.6",
|
|
62
|
-
"@typescript-eslint/parser": "8.
|
|
63
|
-
"@typescript-eslint/rule-tester": "8.
|
|
62
|
+
"@typescript-eslint/parser": "8.2.0",
|
|
63
|
+
"@typescript-eslint/rule-tester": "8.2.0",
|
|
64
64
|
"@vitest/coverage-v8": "2.0.5",
|
|
65
65
|
"@vitest/ui": "2.0.5",
|
|
66
66
|
"concurrently": "8.2.2",
|
|
67
67
|
"drizzle-kit": "0.24.0",
|
|
68
68
|
"drizzle-orm": "0.33.0",
|
|
69
69
|
"eslint": "9.9.0",
|
|
70
|
-
"framer-motion": "11.3.
|
|
71
|
-
"happy-dom": "
|
|
70
|
+
"framer-motion": "11.3.29",
|
|
71
|
+
"happy-dom": "15.0.0",
|
|
72
72
|
"http-proxy": "1.18.1",
|
|
73
73
|
"npmlog": "7.0.1",
|
|
74
74
|
"postgres": "3.4.4",
|
|
@@ -82,7 +82,7 @@
|
|
|
82
82
|
"tsup": "8.2.4",
|
|
83
83
|
"tsx": "4.17.0",
|
|
84
84
|
"typescript": "5.5.4",
|
|
85
|
-
"vite": "5.4.
|
|
85
|
+
"vite": "5.4.2",
|
|
86
86
|
"vite-tsconfig-paths": "5.0.1",
|
|
87
87
|
"vitest": "2.0.5"
|
|
88
88
|
},
|
|
@@ -135,7 +135,10 @@
|
|
|
135
135
|
"realtime-testing/src",
|
|
136
136
|
"transceivers/set-rtx/dist",
|
|
137
137
|
"transceivers/set-rtx/package.json",
|
|
138
|
-
"transceivers/set-rtx/src"
|
|
138
|
+
"transceivers/set-rtx/src",
|
|
139
|
+
"web/dist",
|
|
140
|
+
"web/package.json",
|
|
141
|
+
"web/src"
|
|
139
142
|
],
|
|
140
143
|
"exports": {
|
|
141
144
|
"./package.json": "./package.json",
|
|
@@ -217,6 +220,11 @@
|
|
|
217
220
|
"./transceivers/set-rtx": {
|
|
218
221
|
"import": "./transceivers/set-rtx/dist/index.js",
|
|
219
222
|
"types": "./transceivers/set-rtx/dist/index.d.ts"
|
|
223
|
+
},
|
|
224
|
+
"./web/package.json": "./web/package.json",
|
|
225
|
+
"./web": {
|
|
226
|
+
"import": "./web/dist/index.js",
|
|
227
|
+
"types": "./web/dist/index.d.ts"
|
|
220
228
|
}
|
|
221
229
|
},
|
|
222
230
|
"scripts": {
|
|
@@ -240,6 +248,7 @@
|
|
|
240
248
|
"build:realtime-server": "cd realtime-server && tsup",
|
|
241
249
|
"build:realtime-testing": "cd realtime-testing && tsup",
|
|
242
250
|
"build:transceivers:set-rtx": "cd transceivers/set-rtx && tsup",
|
|
251
|
+
"build:web": "cd web && tsup",
|
|
243
252
|
"lint:biome": "biome check -- .",
|
|
244
253
|
"lint:eslint": "eslint --flag unstable_ts_config -- .",
|
|
245
254
|
"lint:eslint:build": "bun run build:main",
|