atom.io 0.27.5 → 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.
Files changed (67) hide show
  1. package/data/dist/index.d.ts +31 -29
  2. package/data/dist/index.js +16 -17
  3. package/data/src/join.ts +17 -19
  4. package/dist/{chunk-6ABWLAGY.js → chunk-BX3MTH2Z.js} +320 -249
  5. package/dist/chunk-D52JNVER.js +721 -0
  6. package/dist/chunk-EUVKUTW3.js +89 -0
  7. package/dist/index.d.ts +1 -0
  8. package/dist/index.js +3 -1
  9. package/internal/dist/index.d.ts +72 -36
  10. package/internal/dist/index.js +1 -1
  11. package/internal/src/atom/dispose-atom.ts +2 -9
  12. package/internal/src/families/dispose-from-store.ts +35 -18
  13. package/internal/src/families/find-in-store.ts +17 -7
  14. package/internal/src/get-state/get-from-store.ts +41 -32
  15. package/internal/src/ingest-updates/ingest-creation-disposal.ts +10 -1
  16. package/internal/src/molecule/dispose-molecule.ts +6 -17
  17. package/internal/src/pretty-print.ts +1 -16
  18. package/internal/src/selector/dispose-selector.ts +2 -9
  19. package/internal/src/set-state/set-into-store.ts +17 -19
  20. package/internal/src/store/circular-buffer.ts +34 -0
  21. package/internal/src/store/counterfeit.ts +109 -0
  22. package/internal/src/store/deposit.ts +14 -0
  23. package/internal/src/store/index.ts +1 -0
  24. package/internal/src/store/store.ts +3 -0
  25. package/internal/src/store/withdraw.ts +15 -10
  26. package/internal/src/transaction/build-transaction.ts +1 -0
  27. package/introspection/dist/index.d.ts +84 -4
  28. package/introspection/dist/index.js +1 -392
  29. package/introspection/src/attach-introspection-states.ts +7 -4
  30. package/introspection/src/attach-type-selectors.ts +26 -0
  31. package/introspection/src/differ.ts +167 -0
  32. package/introspection/src/index.ts +2 -0
  33. package/introspection/src/refinery.ts +100 -0
  34. package/json/dist/index.d.ts +31 -30
  35. package/json/dist/index.js +2 -77
  36. package/json/src/entries.ts +6 -0
  37. package/json/src/index.ts +47 -6
  38. package/package.json +17 -8
  39. package/react-devtools/dist/index.d.ts +1 -91
  40. package/react-devtools/dist/index.js +285 -414
  41. package/react-devtools/src/AtomIODevtools.tsx +2 -2
  42. package/react-devtools/src/StateEditor.tsx +20 -12
  43. package/react-devtools/src/StateIndex.tsx +8 -26
  44. package/react-devtools/src/TimelineIndex.tsx +3 -3
  45. package/react-devtools/src/TransactionIndex.tsx +6 -6
  46. package/react-devtools/src/Updates.tsx +1 -4
  47. package/react-devtools/src/index.ts +0 -71
  48. package/react-devtools/src/store.ts +51 -0
  49. package/realtime/dist/index.d.ts +7 -7
  50. package/realtime/dist/index.js +18 -22
  51. package/realtime/src/realtime-continuity.ts +27 -35
  52. package/realtime-client/dist/index.js +24 -10
  53. package/realtime-client/src/realtime-client-stores/client-main-store.ts +6 -6
  54. package/realtime-client/src/sync-continuity.ts +28 -6
  55. package/realtime-server/dist/index.js +41 -5
  56. package/realtime-server/src/realtime-continuity-synchronizer.ts +42 -78
  57. package/realtime-testing/dist/index.d.ts +2 -0
  58. package/realtime-testing/dist/index.js +50 -8
  59. package/realtime-testing/src/setup-realtime-test.tsx +59 -9
  60. package/src/silo.ts +7 -3
  61. package/web/dist/index.d.ts +9 -0
  62. package/{dist/chunk-H6EDLPKH.js → web/dist/index.js} +5 -4
  63. package/web/package.json +13 -0
  64. package/web/src/index.ts +1 -0
  65. package/web/src/persist-sync.ts +25 -0
  66. package/dist/chunk-AK23DRMD.js +0 -21
  67. package/dist/chunk-IW6WYRS7.js +0 -140
@@ -11,7 +11,7 @@ import { type Canonical, stringifyJson } from "atom.io/json"
11
11
  import { findInStore, seekInStore } from "../families"
12
12
  import { NotFoundError } from "../not-found-error"
13
13
  import type { Store } from "../store"
14
- import { withdraw } from "../store"
14
+ import { counterfeit, withdraw } from "../store"
15
15
  import { readOrComputeValue } from "./read-or-compute-value"
16
16
 
17
17
  export function getFromStore<T>(store: Store, token: ReadableToken<T>): T
@@ -63,40 +63,49 @@ export function getFromStore(
63
63
  } else {
64
64
  const family = params[0]
65
65
  const key = params[1]
66
- const maybeToken =
67
- family.type === `molecule_family`
68
- ? seekInStore(store, family, key)
69
- : store.config.lifespan === `immortal`
70
- ? seekInStore(store, family, key)
71
- : findInStore(store, family, key)
72
- if (!maybeToken) {
73
- store.logger.error(
74
- `❗`,
75
- family.type,
76
- family.key,
77
- `tried to get member`,
78
- stringifyJson(key),
79
- `but it was not found in store`,
80
- store.config.name,
81
- )
82
- switch (family.type) {
83
- case `atom_family`:
84
- case `mutable_atom_family`:
85
- return store.defaults.get(family.key)
86
- case `selector_family`:
87
- case `readonly_selector_family`: {
88
- if (store.defaults.has(family.key)) {
89
- return store.defaults.get(family.key)
90
- }
91
- const defaultValue = withdraw(family, store).default(key)
92
- store.defaults.set(family.key, defaultValue)
93
- return defaultValue
66
+ let maybeToken: MoleculeToken<any> | ReadableToken<any>
67
+ if (family.type === `molecule_family`) {
68
+ maybeToken = seekInStore(store, family, key) ?? counterfeit(family, key)
69
+ } else {
70
+ maybeToken = findInStore(store, family, key)
71
+ }
72
+ token = maybeToken
73
+ }
74
+ if (`counterfeit` in token && `family` in token) {
75
+ const family =
76
+ token.type === `molecule`
77
+ ? withdraw(token.family, store)
78
+ : // biome-ignore lint/style/noNonNullAssertion: family must be present
79
+ store.families.get(token.family.key)!
80
+ const subKey = token.type === `molecule` ? token.key : token.family.subKey
81
+ const disposal = store.disposalTraces.buffer.find(
82
+ (item) => item?.key === token.key,
83
+ )
84
+ store.logger.error(
85
+ `❌`,
86
+ token.type,
87
+ token.key,
88
+ `could not be retrieved because it was not found in the store "${store.config.name}".`,
89
+ disposal
90
+ ? `This state was previously disposed:\n${disposal.trace}`
91
+ : `No previous disposal trace was found.`,
92
+ )
93
+ switch (family.type) {
94
+ case `atom_family`:
95
+ case `mutable_atom_family`:
96
+ return store.defaults.get(family.key)
97
+ case `selector_family`:
98
+ case `readonly_selector_family`: {
99
+ if (store.defaults.has(family.key)) {
100
+ return store.defaults.get(token.family.key)
94
101
  }
95
- case `molecule_family`:
96
- throw new NotFoundError(family, key, store)
102
+ const defaultValue = withdraw(family, store).default(subKey)
103
+ store.defaults.set(family.key, defaultValue)
104
+ return defaultValue
97
105
  }
106
+ case `molecule_family`:
107
+ throw new NotFoundError(family, subKey, store)
98
108
  }
99
- token = maybeToken
100
109
  }
101
110
  switch (token.type) {
102
111
  case `atom`:
@@ -56,7 +56,16 @@ function createInStore(token: ReadableToken<any>, store: Store): void {
56
56
  return
57
57
  }
58
58
  if (store.config.lifespan === `immortal`) {
59
- throw new Error(`No molecule found for key "${token.family.subKey}"`)
59
+ store.logger.error(
60
+ `🐞`,
61
+ `atom`,
62
+ token.family.key,
63
+ `tried to create member`,
64
+ `"${token.family.subKey}"`,
65
+ `but a molecule with that key was not found in store`,
66
+ `"${store.config.name}"`,
67
+ )
68
+ return
60
69
  }
61
70
  initFamilyMemberInStore(store, family, parseJson(token.family.subKey))
62
71
  }
@@ -15,22 +15,14 @@ export function disposeMolecule<M extends MoleculeConstructor>(
15
15
  store: Store,
16
16
  ): void {
17
17
  let molecule: Molecule<M>
18
- try {
19
- molecule = withdraw(token, store)
20
- } catch (thrown) {
21
- if (thrown instanceof Error) {
22
- store.logger.error(
23
- `🐞`,
24
- `molecule`,
25
- JSON.stringify(token.key),
26
- `Failed to dispose molecule, because it was not found in the store.`,
27
- thrown.message,
28
- )
29
- }
30
- return
31
- }
18
+ molecule = withdraw(token, store)
32
19
  const { family } = token
33
20
 
21
+ for (const join of molecule.joins.values()) {
22
+ join.relations.delete(molecule.key)
23
+ join.molecules.delete(molecule.stringKey)
24
+ }
25
+
34
26
  const context: MoleculeToken<any>[] = []
35
27
  for (const above of molecule.above.values()) {
36
28
  context.push(deposit(above))
@@ -79,9 +71,6 @@ export function disposeMolecule<M extends MoleculeConstructor>(
79
71
  store.molecules.delete(molecule.stringKey)
80
72
  }
81
73
 
82
- for (const join of molecule.joins.values()) {
83
- join.molecules.delete(molecule.stringKey)
84
- }
85
74
  for (const parent of molecule.above.values()) {
86
75
  parent.below.delete(molecule.stringKey)
87
76
  }
@@ -18,20 +18,5 @@ export type AtomIOToken =
18
18
  | TransactionToken<any>
19
19
 
20
20
  export function prettyPrintTokenType(token: AtomIOToken): string {
21
- switch (token.type) {
22
- case `atom_family`:
23
- return `Atom Family`
24
- case `molecule_family`:
25
- return `Molecule Family`
26
- case `mutable_atom_family`:
27
- return `Mutable Atom Family`
28
- case `readonly_selector`:
29
- return `Readonly Selector`
30
- case `readonly_selector_family`:
31
- return `Readonly Selector Family`
32
- case `selector_family`:
33
- return `Selector Family`
34
- default:
35
- return capitalize(token.type)
36
- }
21
+ return token.type.split(`_`).map(capitalize).join(` `)
37
22
  }
@@ -9,15 +9,8 @@ export function disposeSelector(
9
9
  ): void {
10
10
  const target = newest(store)
11
11
  const { key } = selectorToken
12
- const selector = target.selectors.get(key) ?? target.readonlySelectors.get(key)
13
- if (!selector) {
14
- store.logger.info(
15
- `❌`,
16
- `selector`,
17
- key,
18
- `Tried to dispose selector, but it does not exist in the store.`,
19
- )
20
- } else if (!selector.family) {
12
+ const selector = withdraw(selectorToken, target)
13
+ if (!selector.family) {
21
14
  store.logger.error(
22
15
  `❌`,
23
16
  `selector`,
@@ -1,7 +1,7 @@
1
1
  import type { WritableFamilyToken, WritableToken } from "atom.io"
2
2
  import { type Canonical, stringifyJson } from "atom.io/json"
3
3
 
4
- import { findInStore, seekInStore } from "../families"
4
+ import { findInStore } from "../families"
5
5
  import { closeOperation, openOperation } from "../operation"
6
6
  import type { Store } from "../store"
7
7
  import { withdraw } from "../store"
@@ -39,26 +39,24 @@ export function setIntoStore<T, New extends T>(
39
39
  const family = params[0]
40
40
  const key = params[1]
41
41
  value = params[2]
42
- const maybeToken =
43
- store.config.lifespan === `ephemeral`
44
- ? findInStore(store, family, key)
45
- : seekInStore(store, family, key)
46
- if (!maybeToken) {
47
- store.logger.error(
48
- `❗`,
49
- family.type,
50
- family.key,
51
- `tried to set member`,
52
- stringifyJson(key),
53
- `to`,
54
- value,
55
- `but it was not found in store`,
56
- store.config.name,
57
- )
58
- return
59
- }
42
+ const maybeToken = findInStore(store, family, key)
60
43
  token = maybeToken
61
44
  }
45
+ if (`counterfeit` in token) {
46
+ const disposal = store.disposalTraces.buffer.find(
47
+ (item) => item?.key === token.key,
48
+ )
49
+ store.logger.error(
50
+ `❌`,
51
+ token.type,
52
+ token.key,
53
+ `could not be set because it was not found in the store "${store.config.name}".`,
54
+ disposal
55
+ ? `This state was previously disposed:\n${disposal.trace}`
56
+ : `No previous disposal trace was found.`,
57
+ )
58
+ return
59
+ }
62
60
 
63
61
  const rejectionTime = openOperation(token, store)
64
62
  if (rejectionTime) {
@@ -0,0 +1,34 @@
1
+ export class CircularBuffer<T> {
2
+ protected _buffer: T[]
3
+ protected _index = 0
4
+ public constructor(array: T[])
5
+ public constructor(length: number)
6
+ public constructor(lengthOrArray: T[] | number) {
7
+ let length: number
8
+ if (typeof lengthOrArray === `number`) {
9
+ length = lengthOrArray
10
+ } else {
11
+ length = lengthOrArray.length
12
+ }
13
+ this._buffer = Array.from({ length })
14
+ }
15
+
16
+ public get buffer(): ReadonlyArray<T | undefined> {
17
+ return this._buffer
18
+ }
19
+
20
+ public get index(): number {
21
+ return this._index
22
+ }
23
+
24
+ public add(item: T): void {
25
+ this._buffer[this._index] = item
26
+ this._index = (this._index + 1) % this._buffer.length
27
+ }
28
+
29
+ public copy(): CircularBuffer<T> {
30
+ const copy = new CircularBuffer<T>([...this._buffer])
31
+ copy._index = this._index
32
+ return copy
33
+ }
34
+ }
@@ -0,0 +1,109 @@
1
+ import type {
2
+ AtomFamilyToken,
3
+ AtomToken,
4
+ MoleculeConstructor,
5
+ MoleculeFamilyToken,
6
+ MoleculeKey,
7
+ MoleculeToken,
8
+ MutableAtomFamilyToken,
9
+ MutableAtomToken,
10
+ ReadableFamilyToken,
11
+ ReadableToken,
12
+ ReadonlySelectorFamilyToken,
13
+ ReadonlySelectorToken,
14
+ RegularAtomFamilyToken,
15
+ RegularAtomToken,
16
+ SelectorFamilyToken,
17
+ SelectorToken,
18
+ WritableFamilyToken,
19
+ WritableSelectorFamilyToken,
20
+ WritableSelectorToken,
21
+ WritableToken,
22
+ } from "atom.io"
23
+ import type { Canonical, Json } from "atom.io/json"
24
+ import { stringifyJson } from "atom.io/json"
25
+
26
+ import type { Transceiver } from "../mutable"
27
+
28
+ export const FAMILY_MEMBER_TOKEN_TYPES = {
29
+ atom_family: `atom`,
30
+ mutable_atom_family: `mutable_atom`,
31
+ selector_family: `selector`,
32
+ readonly_selector_family: `readonly_selector`,
33
+ molecule_family: `molecule`,
34
+ } as const
35
+
36
+ export function counterfeit<
37
+ T extends Transceiver<any>,
38
+ J extends Json.Serializable,
39
+ K extends Canonical,
40
+ Key extends K,
41
+ >(token: MutableAtomFamilyToken<T, J, K>, key: Key): MutableAtomToken<T, J>
42
+
43
+ export function counterfeit<T, K extends Canonical, Key extends K>(
44
+ token: RegularAtomFamilyToken<T, K>,
45
+ key: Key,
46
+ ): RegularAtomToken<T>
47
+
48
+ export function counterfeit<T, K extends Canonical, Key extends K>(
49
+ token: AtomFamilyToken<T, K>,
50
+ key: Key,
51
+ ): AtomToken<T>
52
+
53
+ export function counterfeit<T, K extends Canonical, Key extends K>(
54
+ token: WritableSelectorFamilyToken<T, K>,
55
+ key: Key,
56
+ ): WritableSelectorToken<T>
57
+
58
+ export function counterfeit<T, K extends Canonical, Key extends K>(
59
+ token: ReadonlySelectorFamilyToken<T, K>,
60
+ key: Key,
61
+ ): ReadonlySelectorToken<T>
62
+
63
+ export function counterfeit<T, K extends Canonical, Key extends K>(
64
+ token: SelectorFamilyToken<T, K>,
65
+ key: Key,
66
+ ): SelectorToken<T>
67
+
68
+ export function counterfeit<T, K extends Canonical, Key extends K>(
69
+ token: WritableFamilyToken<T, K>,
70
+ key: Key,
71
+ ): WritableToken<T>
72
+
73
+ export function counterfeit<T, K extends Canonical, Key extends K>(
74
+ token: ReadableFamilyToken<T, K>,
75
+ key: Key,
76
+ ): ReadableToken<T>
77
+
78
+ export function counterfeit<M extends MoleculeConstructor>(
79
+ token: MoleculeFamilyToken<M>,
80
+ key: MoleculeKey<M>,
81
+ ): MoleculeKey<M>
82
+
83
+ export function counterfeit(
84
+ token: MoleculeFamilyToken<any> | ReadableFamilyToken<any, any>,
85
+ key: Canonical,
86
+ ): MoleculeToken<any> | ReadableToken<any> {
87
+ const subKey = stringifyJson(key)
88
+ const fullKey = `${token.key}(${subKey})`
89
+ const type = FAMILY_MEMBER_TOKEN_TYPES[token.type]
90
+ const stateToken = {
91
+ key: fullKey,
92
+ type,
93
+ } satisfies MoleculeToken<any> | ReadableToken<any>
94
+ if (type === `molecule`) {
95
+ Object.assign(stateToken, {
96
+ key,
97
+ family: token,
98
+ })
99
+ } else {
100
+ Object.assign(stateToken, {
101
+ family: {
102
+ key: token.key,
103
+ subKey,
104
+ },
105
+ })
106
+ }
107
+ Object.assign(stateToken, { counterfeit: true })
108
+ return stateToken
109
+ }
@@ -97,6 +97,20 @@ export function deposit(
97
97
  state: Molecule<any> | ReadableState<any>,
98
98
  ): MoleculeToken<any> | ReadableToken<any>
99
99
 
100
+ export function deposit(
101
+ state:
102
+ | Molecule<any>
103
+ | MoleculeFamily<any>
104
+ | ReadableFamily<any, any>
105
+ | ReadableState<any>
106
+ | Transaction<Func>,
107
+ ):
108
+ | MoleculeFamilyToken<any>
109
+ | MoleculeToken<any>
110
+ | ReadableFamilyToken<any, any>
111
+ | ReadableToken<any>
112
+ | TransactionToken<Func>
113
+
100
114
  export function deposit(
101
115
  state:
102
116
  | Molecule<any>
@@ -1,3 +1,4 @@
1
+ export * from "./counterfeit"
1
2
  export * from "./deposit"
2
3
  export * from "./store"
3
4
  export * from "./withdraw"
@@ -36,6 +36,7 @@ import type {
36
36
  TransactionProgress,
37
37
  } from "../transaction"
38
38
  import { isRootStore } from "../transaction"
39
+ import { CircularBuffer } from "./circular-buffer"
39
40
 
40
41
  export class Store implements Lineage {
41
42
  public parent: Store | null = null
@@ -94,6 +95,8 @@ export class Store implements Lineage {
94
95
  cardinality: `1:n`,
95
96
  })
96
97
 
98
+ public disposalTraces = new CircularBuffer<{ key: string; trace: string }>(100)
99
+
97
100
  public molecules = new Map<string, Molecule<any>>()
98
101
  public moleculeFamilies = new Map<string, MoleculeFamily<any>>()
99
102
  public moleculeInProgress: string | null = null
@@ -155,19 +155,24 @@ export function withdraw<T>(
155
155
  token: TimelineToken<T>,
156
156
  store: Store,
157
157
  ): Timeline<T extends TimelineManageable ? T : never>
158
- export function withdraw<T>(
158
+
159
+ export function withdraw<T, M extends MoleculeConstructor>(
160
+ token: MoleculeToken<M> | ReadableToken<T>,
161
+ store: Store,
162
+ ): Molecule<M> | ReadableState<T>
163
+
164
+ export function withdraw(
159
165
  token:
160
166
  | MoleculeFamilyToken<any>
161
167
  | MoleculeToken<any>
162
- | RegularAtomFamilyToken<T, any>
163
- | RegularAtomToken<T>
164
- | SelectorFamilyToken<T, any>
165
- | SelectorToken<T>
166
- | TimelineToken<T>
167
- | TransactionToken<T extends Func ? T : never>
168
- | (T extends Transceiver<any>
169
- ? MutableAtomFamilyToken<T, any, any> | MutableAtomToken<T, any>
170
- : never),
168
+ | MutableAtomFamilyToken<any, any, any>
169
+ | MutableAtomToken<any, any>
170
+ | RegularAtomFamilyToken<any, any>
171
+ | RegularAtomToken<any>
172
+ | SelectorFamilyToken<any, any>
173
+ | SelectorToken<any>
174
+ | TimelineToken<any>
175
+ | TransactionToken<any>,
171
176
  store: Store,
172
177
  ): Withdrawable {
173
178
  let withdrawn: Withdrawable | undefined
@@ -49,6 +49,7 @@ export const buildTransaction = (
49
49
  selectors: new LazyMap(parent.selectors),
50
50
  valueMap: new LazyMap(parent.valueMap),
51
51
  defaults: parent.defaults,
52
+ disposalTraces: store.disposalTraces.copy(),
52
53
  molecules: new LazyMap(parent.molecules),
53
54
  moleculeFamilies: new LazyMap(parent.moleculeFamilies),
54
55
  moleculeInProgress: parent.moleculeInProgress,
@@ -1,6 +1,7 @@
1
1
  import { AtomToken, SelectorToken, ReadonlySelectorToken, TransactionToken, ReadonlySelectorFamilyToken, TransactionUpdate, TimelineToken, ReadableToken } from 'atom.io';
2
2
  import * as Internal from 'atom.io/internal';
3
- import { Func, Timeline } from 'atom.io/internal';
3
+ import { Func, Timeline, Flat } from 'atom.io/internal';
4
+ import { Json } from 'atom.io/json';
4
5
 
5
6
  type AtomTokenIndex = WritableTokenIndex<AtomToken<unknown>>;
6
7
 
@@ -10,9 +11,10 @@ declare const attachIntrospectionStates: (store?: Internal.Store) => {
10
11
  atomIndex: ReadonlySelectorToken<AtomTokenIndex>;
11
12
  selectorIndex: ReadonlySelectorToken<SelectorTokenIndex>;
12
13
  transactionIndex: ReadonlySelectorToken<TransactionToken<Func>[]>;
13
- findTransactionLogState: ReadonlySelectorFamilyToken<TransactionUpdate<Func>[], string>;
14
+ transactionLogSelectors: ReadonlySelectorFamilyToken<TransactionUpdate<Func>[], string>;
14
15
  timelineIndex: ReadonlySelectorToken<TimelineToken<any>[]>;
15
- findTimelineState: ReadonlySelectorFamilyToken<Timeline<any>, string>;
16
+ timelineSelectors: ReadonlySelectorFamilyToken<Timeline<any>, string>;
17
+ typeSelectors: ReadonlySelectorFamilyToken<string, string>;
16
18
  };
17
19
 
18
20
  type ListResourcesParam = {
@@ -52,10 +54,88 @@ declare class Auditor {
52
54
  [Symbol.dispose](): void;
53
55
  }
54
56
 
57
+ type Refinement<A, B extends A> = (a: A) => a is B;
58
+ type ClassSignature = abstract new (...args: any) => any;
59
+ type RefinementStrategy = ClassSignature | Refinement<unknown, any>;
60
+ type Supported<Refine extends RefinementStrategy> = Refine extends Refinement<unknown, infer T> ? T : Refine extends ClassSignature ? InstanceType<Refine> : never;
61
+ type RefinementSupport = Record<string, RefinementStrategy>;
62
+ declare class Refinery<SupportedTypes extends RefinementSupport> {
63
+ supported: SupportedTypes;
64
+ constructor(supported: SupportedTypes);
65
+ refine<T>(input: T): Flat<{
66
+ [K in keyof SupportedTypes]: T extends Supported<SupportedTypes[K]> ? {
67
+ type: K;
68
+ data: Supported<SupportedTypes[K]>;
69
+ } : Supported<SupportedTypes[K]> extends T ? {
70
+ type: K;
71
+ data: Supported<SupportedTypes[K]>;
72
+ } : never;
73
+ }>[keyof SupportedTypes] | (T extends Supported<SupportedTypes[keyof SupportedTypes]> ? never : null);
74
+ }
75
+ declare const primitiveRefinery: Refinery<{
76
+ number: (input: unknown) => input is number;
77
+ string: (input: unknown) => input is string;
78
+ boolean: (input: unknown) => input is boolean;
79
+ null: (input: unknown) => input is null;
80
+ }>;
81
+ declare const jsonTreeRefinery: Refinery<{
82
+ object: (input: unknown) => input is Json.Tree.Object;
83
+ array: (input: unknown) => input is Json.Tree.Array;
84
+ }>;
85
+ declare const jsonRefinery: Refinery<{
86
+ object: (input: unknown) => input is Json.Tree.Object;
87
+ array: (input: unknown) => input is Json.Tree.Array;
88
+ number: (input: unknown) => input is number;
89
+ string: (input: unknown) => input is string;
90
+ boolean: (input: unknown) => input is boolean;
91
+ null: (input: unknown) => input is null;
92
+ }>;
93
+ type JsonType = keyof typeof jsonRefinery.supported;
94
+ declare const discoverType: (input: unknown) => JsonType | `Map` | `Set` | `undefined` | (string & {});
95
+
96
+ declare function diffNumber(a: number, b: number): Delta;
97
+ declare function diffString(a: string, b: string): Delta;
98
+ declare function diffBoolean(a: boolean, b: boolean): Delta;
99
+ declare function diffObject(a: Json.Tree.Object, b: Json.Tree.Object, recurse: Diff<unknown>): Delta;
100
+ declare function diffArray(a: Json.Tree.Array, b: Json.Tree.Array, recurse: Diff<unknown>): Delta;
101
+ type Delta = {
102
+ summary: string;
103
+ added?: [path: string, addedStringifiedValue: string][];
104
+ removed?: [path: string, removedStringifiedValue: string][];
105
+ changed?: [path: string, delta: Delta][];
106
+ };
107
+ type Diff<T> = (a: T, b: T) => Delta;
108
+ type DiffTree<T> = (a: T, b: T, recurse: Differ<any, any>[`diff`]) => Delta;
109
+ declare class Differ<Leaf extends Record<string, any>, Tree extends Record<string, any>> {
110
+ leafRefinery: Refinery<Leaf>;
111
+ treeRefinery: Refinery<Tree>;
112
+ leafDiffers: {
113
+ [KL in keyof Leaf]: Diff<Supported<Leaf[KL]>>;
114
+ };
115
+ treeDiffers: {
116
+ [KT in keyof Tree]: DiffTree<Supported<Tree[KT]>>;
117
+ };
118
+ constructor(leafRefinery: Refinery<Leaf>, treeRefinery: Refinery<Tree>, diffFunctions: {
119
+ [KT in keyof Tree]: DiffTree<Supported<Tree[KT]>>;
120
+ } & {
121
+ [KL in keyof Leaf]: Diff<Supported<Leaf[KL]>>;
122
+ });
123
+ diff(a: unknown, b: unknown): Delta;
124
+ }
125
+ declare const prettyJson: Differ<{
126
+ number: (input: unknown) => input is number;
127
+ string: (input: unknown) => input is string;
128
+ boolean: (input: unknown) => input is boolean;
129
+ null: (input: unknown) => input is null;
130
+ }, {
131
+ object: (input: unknown) => input is Json.Tree.Object;
132
+ array: (input: unknown) => input is Json.Tree.Array;
133
+ }>;
134
+
55
135
  type FamilyNode<Token extends ReadableToken<unknown>> = {
56
136
  key: string;
57
137
  familyMembers: Map<string, Token>;
58
138
  };
59
139
  type WritableTokenIndex<Token extends ReadableToken<unknown>> = Map<string, FamilyNode<Token> | Token>;
60
140
 
61
- export { Auditor, type FamilyNode, type ListResourcesParam, type WritableTokenIndex, attachIntrospectionStates };
141
+ export { Auditor, type ClassSignature, Differ, type FamilyNode, type JsonType, type ListResourcesParam, type Refinement, type RefinementStrategy, type RefinementSupport, Refinery, type Supported, type WritableTokenIndex, attachIntrospectionStates, diffArray, diffBoolean, diffNumber, diffObject, diffString, discoverType, jsonRefinery, jsonTreeRefinery, prettyJson, primitiveRefinery };