atom.io 0.24.8 → 0.25.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 (37) hide show
  1. package/data/dist/index.cjs +40 -62
  2. package/data/dist/index.d.ts +3 -3
  3. package/data/dist/index.js +41 -63
  4. package/data/src/join.ts +47 -64
  5. package/dist/index.cjs +26 -8
  6. package/dist/index.d.ts +37 -15
  7. package/dist/index.js +27 -9
  8. package/internal/dist/index.cjs +204 -104
  9. package/internal/dist/index.d.ts +10 -5
  10. package/internal/dist/index.js +205 -105
  11. package/internal/src/families/dispose-from-store.ts +56 -3
  12. package/internal/src/get-state/get-from-store.ts +58 -25
  13. package/internal/src/molecule/make-molecule-in-store.ts +59 -23
  14. package/internal/src/not-found-error.ts +29 -6
  15. package/internal/src/selector/create-writable-selector.ts +5 -5
  16. package/internal/src/selector/register-selector.ts +58 -9
  17. package/internal/src/set-state/set-into-store.ts +48 -1
  18. package/internal/src/store/store.ts +4 -4
  19. package/internal/src/transaction/build-transaction.ts +10 -9
  20. package/internal/src/transaction/create-transaction.ts +2 -2
  21. package/internal/src/transaction/index.ts +2 -2
  22. package/package.json +5 -5
  23. package/react/dist/index.cjs +4 -1
  24. package/react/dist/index.js +5 -2
  25. package/react/src/use-o.ts +11 -3
  26. package/realtime/dist/index.cjs +0 -1
  27. package/realtime/dist/index.js +0 -1
  28. package/realtime/src/realtime-continuity.ts +0 -1
  29. package/realtime-server/dist/index.cjs +7 -7
  30. package/realtime-server/dist/index.js +7 -7
  31. package/realtime-server/src/realtime-server-stores/server-room-external-actions.ts +7 -7
  32. package/src/dispose-state.ts +32 -3
  33. package/src/get-state.ts +37 -4
  34. package/src/molecule.ts +20 -7
  35. package/src/set-state.ts +19 -2
  36. package/src/silo.ts +11 -4
  37. package/src/transaction.ts +9 -17
@@ -1,4 +1,5 @@
1
1
  import type {
2
+ CtorToolkit,
2
3
  MK,
3
4
  MoleculeConstructor,
4
5
  MoleculeCreation,
@@ -6,10 +7,9 @@ import type {
6
7
  MoleculeKey,
7
8
  MoleculeParams,
8
9
  MoleculeToken,
9
- MoleculeTransactors,
10
10
  ReadableFamilyToken,
11
11
  } from "atom.io"
12
- import { getJoin, type JoinToken } from "atom.io/data"
12
+ import { findRelations, getJoin, type JoinToken } from "atom.io/data"
13
13
  import type { seekState } from "atom.io/immortal"
14
14
  import { stringifyJson } from "atom.io/json"
15
15
 
@@ -26,6 +26,10 @@ import { actUponStore, isChildStore, isRootStore } from "../transaction"
26
26
  import { growMoleculeInStore } from "./grow-molecule-in-store"
27
27
  import { Molecule } from "./molecule-internal"
28
28
 
29
+ function capitalize<S extends string>(string: S): Capitalize<S> {
30
+ return (string[0].toUpperCase() + string.slice(1)) as Capitalize<S>
31
+ }
32
+
29
33
  export function makeMoleculeInStore<M extends MoleculeConstructor>(
30
34
  store: Store,
31
35
  context: MoleculeToken<M> | MoleculeToken<M>[],
@@ -34,33 +38,34 @@ export function makeMoleculeInStore<M extends MoleculeConstructor>(
34
38
  ...params: MoleculeParams<M>
35
39
  ): MoleculeToken<M> {
36
40
  const target = newest(store)
41
+ const stringKey = stringifyJson(key)
37
42
 
38
- target.moleculeInProgress = key
43
+ target.moleculeInProgress = stringKey
39
44
 
40
45
  const contextArray = Array.isArray(context) ? context : [context]
41
46
  const owners = contextArray.map<Molecule<M>>((ctx) => {
42
47
  if (ctx instanceof Molecule) {
43
48
  return ctx
44
49
  }
45
- const stringKey = stringifyJson(ctx.key)
46
- const molecule = store.molecules.get(stringKey)
50
+ const ctxStringKey = stringifyJson(ctx.key)
51
+ const molecule = store.molecules.get(ctxStringKey)
47
52
 
48
53
  if (!molecule) {
49
54
  throw new Error(
50
- `Molecule ${stringKey} not found in store "${store.config.name}"`,
55
+ `Molecule ${ctxStringKey} not found in store "${store.config.name}"`,
51
56
  )
52
57
  }
53
58
  return molecule
54
59
  })
55
60
 
56
61
  const molecule = new Molecule(owners, key, familyToken)
57
- target.molecules.set(stringifyJson(key), molecule)
62
+ target.molecules.set(stringKey, molecule)
58
63
  for (const owner of owners) {
59
64
  owner.below.set(molecule.stringKey, molecule)
60
65
  }
61
66
 
62
- const transactors = {
63
- get: (t) => getFromStore(t, newest(store)),
67
+ const toolkit = {
68
+ get: (t) => getFromStore(t, undefined, newest(store)),
64
69
  set: (t, newValue) => {
65
70
  setIntoStore(t, newValue, newest(store))
66
71
  },
@@ -73,12 +78,49 @@ export function makeMoleculeInStore<M extends MoleculeConstructor>(
73
78
  disposeFromStore(t, newest(store))
74
79
  },
75
80
  env: () => getEnvironmentData(newest(store)),
76
- bond: ((f: ReadableFamilyToken<any, any>) =>
77
- growMoleculeInStore(
78
- molecule,
79
- withdraw(f, store),
80
- newest(store),
81
- )) as MoleculeTransactors<MK<M>>[`bond`],
81
+ bond: ((
82
+ token: JoinToken<any, any, any, any> | ReadableFamilyToken<any, any>,
83
+ maybeRole,
84
+ ) => {
85
+ if (token.type === `join`) {
86
+ const { as: role } = maybeRole
87
+ const join = getJoin(token, store)
88
+ join.molecules.set(stringKey, molecule)
89
+ molecule.joins.set(token.key, join)
90
+ const unsubFromFamily = family.subject.subscribe(
91
+ `join:${token.key}-${stringKey}`,
92
+ (event) => {
93
+ if (
94
+ event.type === `molecule_disposal` &&
95
+ stringifyJson(event.token.key) === stringKey
96
+ ) {
97
+ unsubFromFamily()
98
+ join.molecules.delete(stringKey)
99
+ }
100
+ },
101
+ )
102
+
103
+ if (role === null) {
104
+ return
105
+ }
106
+ const otherRole = token.a === role ? token.b : token.a
107
+ const relations = findRelations(token, key)
108
+ const relatedKeys =
109
+ relations[
110
+ `${otherRole}KeysOf${capitalize(role)}` as keyof typeof relations
111
+ ]
112
+ const relatedEntries =
113
+ relations[
114
+ `${otherRole}EntriesOf${capitalize(role)}` as keyof typeof relations
115
+ ]
116
+ let tokens = { relatedKeys }
117
+ if (relatedEntries) {
118
+ tokens = Object.assign(tokens, { relatedEntries })
119
+ }
120
+ return tokens
121
+ }
122
+ return growMoleculeInStore(molecule, withdraw(token, store), newest(store))
123
+ }) as CtorToolkit<MK<M>>[`bond`],
82
124
  claim: (below, options) => {
83
125
  const { exclusive } = options
84
126
  const belowMolecule = newest(store).molecules.get(stringifyJson(below.key))
@@ -96,12 +138,6 @@ export function makeMoleculeInStore<M extends MoleculeConstructor>(
96
138
  }
97
139
  }
98
140
  },
99
- join: <J extends JoinToken<any, any, any, any>>(joinToken: J) => {
100
- const join = getJoin(joinToken, store)
101
- join.molecules.set(stringifyJson(key), molecule)
102
- molecule.joins.set(joinToken.key, join)
103
- return joinToken
104
- },
105
141
  spawn: (f: MoleculeFamilyToken<any>, k: any, ...p: any[]) =>
106
142
  makeMoleculeInStore(
107
143
  newest(store),
@@ -110,12 +146,12 @@ export function makeMoleculeInStore<M extends MoleculeConstructor>(
110
146
  k,
111
147
  ...p,
112
148
  ),
113
- } satisfies MoleculeTransactors<MK<M>>
149
+ } satisfies CtorToolkit<MK<M>>
114
150
 
115
151
  const family = withdraw(familyToken, store)
116
152
  const Constructor = family.new
117
153
 
118
- molecule.instance = new Constructor(transactors, key, ...params)
154
+ molecule.instance = new Constructor(toolkit, key, ...params)
119
155
 
120
156
  const token = {
121
157
  type: `molecule`,
@@ -6,6 +6,7 @@ import type {
6
6
  TimelineToken,
7
7
  TransactionToken,
8
8
  } from "atom.io"
9
+ import { type Json, stringifyJson } from "atom.io/json"
9
10
 
10
11
  import type { Store } from "./store"
11
12
 
@@ -37,11 +38,33 @@ function prettyPrintTokenType(token: AtomIOToken) {
37
38
  }
38
39
 
39
40
  export class NotFoundError extends Error {
40
- public constructor(token: AtomIOToken, store: Store) {
41
- super(
42
- `${prettyPrintTokenType(token)} "${token.key}" not found in store "${
43
- store.config.name
44
- }".`,
45
- )
41
+ public constructor(token: AtomIOToken, store: Store)
42
+ public constructor(
43
+ familyToken: AtomIOToken,
44
+ key: Json.Serializable,
45
+ store: Store,
46
+ )
47
+ public constructor(
48
+ ...params:
49
+ | [token: AtomIOToken, key: Json.Serializable, store: Store]
50
+ | [token: AtomIOToken, store: Store]
51
+ ) {
52
+ const token: AtomIOToken = params[0]
53
+ const store: Store = params.length === 2 ? params[1] : params[2]
54
+
55
+ if (params.length === 2) {
56
+ super(
57
+ `${prettyPrintTokenType(token)} "${token.key}" not found in store "${
58
+ store.config.name
59
+ }".`,
60
+ )
61
+ } else {
62
+ const key = params[1]
63
+ super(
64
+ `${prettyPrintTokenType(token)} "${token.key}" member ${stringifyJson(key)} not found in store "${
65
+ store.config.name
66
+ }".`,
67
+ )
68
+ }
46
69
  }
47
70
  }
@@ -22,12 +22,12 @@ export const createWritableSelector = <T>(
22
22
  const target = newest(store)
23
23
  const subject = new Subject<{ newValue: T; oldValue: T }>()
24
24
  const covered = new Set<string>()
25
- const transactors = registerSelector(options.key, covered, target)
26
- const { find, get, seek, json } = transactors
27
- const readonlyTransactors = { find, get, seek, json }
25
+ const toolkit = registerSelector(options.key, covered, target)
26
+ const { find, get, seek, json } = toolkit
27
+ const getterToolkit = { find, get, seek, json }
28
28
 
29
29
  const getSelf = (innerTarget = newest(store)): T => {
30
- const value = options.get(readonlyTransactors)
30
+ const value = options.get(getterToolkit)
31
31
  cacheValue(options.key, value, subject, innerTarget)
32
32
  covered.clear()
33
33
  return value
@@ -52,7 +52,7 @@ export const createWritableSelector = <T>(
52
52
  if (isRootStore(innerTarget)) {
53
53
  subject.next({ newValue, oldValue })
54
54
  }
55
- options.set(transactors, newValue)
55
+ options.set(toolkit, newValue)
56
56
  }
57
57
  const mySelector: WritableSelector<T> = {
58
58
  ...options,
@@ -1,17 +1,24 @@
1
1
  import type {
2
2
  MoleculeConstructor,
3
+ MoleculeFamilyToken,
3
4
  MoleculeToken,
5
+ ReadableFamilyToken,
4
6
  ReadableToken,
5
- Transactors,
7
+ setState,
8
+ SetterToolkit,
9
+ WritableSelectorFamilyToken,
10
+ WritableToken,
6
11
  } from "atom.io"
7
12
  import type { findState } from "atom.io/ephemeral"
8
13
  import type { seekState } from "atom.io/immortal"
14
+ import type { Json } from "atom.io/json"
9
15
 
10
16
  import { findInStore, seekInStore } from "../families"
11
17
  import { getFromStore } from "../get-state"
12
18
  import { readOrComputeValue } from "../get-state/read-or-compute-value"
13
19
  import { newest } from "../lineage"
14
20
  import { getJsonToken } from "../mutable"
21
+ import { NotFoundError } from "../not-found-error"
15
22
  import { setAtomOrSelector } from "../set-state"
16
23
  import type { Store } from "../store"
17
24
  import { withdraw } from "../store"
@@ -21,15 +28,31 @@ export const registerSelector = (
21
28
  selectorKey: string,
22
29
  covered: Set<string>,
23
30
  store: Store,
24
- ): Transactors => ({
25
- get: (dependency: MoleculeToken<MoleculeConstructor> | ReadableToken<any>) => {
31
+ ): SetterToolkit => ({
32
+ get: (
33
+ dependency:
34
+ | MoleculeFamilyToken<any>
35
+ | MoleculeToken<MoleculeConstructor>
36
+ | ReadableFamilyToken<any, any>
37
+ | ReadableToken<any>,
38
+ key?: Json.Serializable,
39
+ ) => {
26
40
  const target = newest(store)
27
41
 
42
+ if (key) {
43
+ switch (dependency.type) {
44
+ case `molecule_family`:
45
+ return getFromStore(dependency, key, store)
46
+ case `atom_family`:
47
+ dependency = seekInStore(dependency, key, store) as any
48
+ }
49
+ }
50
+
28
51
  if (dependency.type === `molecule`) {
29
52
  return getFromStore(dependency, store)
30
53
  }
31
54
 
32
- const dependencyState = withdraw(dependency, store)
55
+ const dependencyState = withdraw(dependency as ReadableToken<any>, store)
33
56
  const dependencyValue = readOrComputeValue(dependencyState, store)
34
57
 
35
58
  store.logger.info(
@@ -50,14 +73,40 @@ export const registerSelector = (
50
73
  source: dependency.key,
51
74
  },
52
75
  )
53
- updateSelectorAtoms(selectorKey, dependency, covered, store)
76
+ updateSelectorAtoms(selectorKey, dependency as any, covered, store)
54
77
  return dependencyValue
55
78
  },
56
- set: (WritableToken, newValue) => {
79
+ set: (<T, New extends T>(
80
+ ...params:
81
+ | [
82
+ token: WritableSelectorFamilyToken<T, any>,
83
+ key: Json.Serializable,
84
+ value: New | ((oldValue: any) => New),
85
+ ]
86
+ | [token: WritableToken<T>, value: New | ((oldValue: T) => New)]
87
+ ) => {
88
+ let token: WritableToken<T>
89
+ let value: New | ((oldValue: T) => New)
90
+ if (params.length === 2) {
91
+ token = params[0]
92
+ value = params[1]
93
+ } else {
94
+ const family = params[0]
95
+ const key = params[1]
96
+ value = params[2]
97
+ const maybeToken =
98
+ store.config.lifespan === `ephemeral`
99
+ ? findInStore(family, key, store)
100
+ : seekInStore(family, key, store)
101
+ if (!maybeToken) {
102
+ throw new NotFoundError(family, key, store)
103
+ }
104
+ token = maybeToken
105
+ }
57
106
  const target = newest(store)
58
- const state = withdraw(WritableToken, target)
59
- setAtomOrSelector(state, newValue, target)
60
- },
107
+ const state = withdraw(token, target)
108
+ setAtomOrSelector(state, value, target)
109
+ }) as typeof setState,
61
110
  find: ((token, key) => findInStore(token, key, store)) as typeof findState,
62
111
  seek: ((token, key) => seekInStore(token, key, store)) as typeof seekState,
63
112
  json: (token) => getJsonToken(token, store),
@@ -1,5 +1,8 @@
1
- import type { WritableToken } from "atom.io"
1
+ import type { WritableFamilyToken, WritableToken } from "atom.io"
2
+ import type { Json } from "atom.io/json"
2
3
 
4
+ import { findInStore, seekInStore } from "../families"
5
+ import { NotFoundError } from "../not-found-error"
3
6
  import { closeOperation, openOperation } from "../operation"
4
7
  import type { Store } from "../store"
5
8
  import { withdraw } from "../store"
@@ -9,7 +12,51 @@ export function setIntoStore<T, New extends T>(
9
12
  token: WritableToken<T>,
10
13
  value: New | ((oldValue: T) => New),
11
14
  store: Store,
15
+ ): void
16
+
17
+ export function setIntoStore<T, K extends Json.Serializable, New extends T>(
18
+ token: WritableFamilyToken<T, K>,
19
+ key: K,
20
+ value: New | ((oldValue: T) => New),
21
+ store: Store,
22
+ ): void
23
+
24
+ export function setIntoStore<T, New extends T>(
25
+ ...params:
26
+ | [
27
+ token: WritableFamilyToken<T, Json.Serializable>,
28
+ key: Json.Serializable,
29
+ value: New | ((oldValue: T) => New),
30
+ store: Store,
31
+ ]
32
+ | [
33
+ token: WritableToken<T>,
34
+ value: New | ((oldValue: T) => New),
35
+ store: Store,
36
+ ]
12
37
  ): void {
38
+ let token: WritableToken<T>
39
+ let value: New | ((oldValue: T) => New)
40
+ let store: Store
41
+ if (params.length === 3) {
42
+ token = params[0]
43
+ value = params[1]
44
+ store = params[2]
45
+ } else {
46
+ const family = params[0]
47
+ const key = params[1]
48
+ value = params[2]
49
+ store = params[3]
50
+ const maybeToken =
51
+ store.config.lifespan === `ephemeral`
52
+ ? findInStore(family, key, store)
53
+ : seekInStore(family, key, store)
54
+ if (!maybeToken) {
55
+ throw new NotFoundError(family, key, store)
56
+ }
57
+ token = maybeToken
58
+ }
59
+
13
60
  const rejectionTime = openOperation(token, store)
14
61
  if (rejectionTime) {
15
62
  const unsubscribe = store.on.operationClose.subscribe(
@@ -143,6 +143,10 @@ export class Store implements Lineage {
143
143
  }
144
144
 
145
145
  public constructor(config: Store[`config`], store: Store | null = null) {
146
+ this.config = {
147
+ ...store?.config,
148
+ ...config,
149
+ }
146
150
  if (store !== null) {
147
151
  this.valueMap = new Map(store?.valueMap)
148
152
  this.operation = { ...store?.operation }
@@ -155,10 +159,6 @@ export class Store implements Lineage {
155
159
  }
156
160
  }
157
161
 
158
- this.config = {
159
- ...store?.config,
160
- ...config,
161
- }
162
162
  for (const [, family] of store.families) {
163
163
  family.install(this)
164
164
  }
@@ -1,4 +1,4 @@
1
- import type { Func } from "atom.io"
1
+ import type { disposeState, Func, getState, setState } from "atom.io"
2
2
  import type { findState } from "atom.io/ephemeral"
3
3
  import type { seekState } from "atom.io/immortal"
4
4
 
@@ -64,11 +64,12 @@ export const buildTransaction = (
64
64
  params,
65
65
  output: undefined,
66
66
  },
67
- transactors: {
68
- get: (token) => getFromStore(token, child),
69
- set: (token, value) => {
70
- setIntoStore(token, value, child)
71
- },
67
+ toolkit: {
68
+ get: ((...ps: Parameters<typeof getState>) =>
69
+ getFromStore(...ps, child)) as typeof getState,
70
+ set: ((...ps: Parameters<typeof setState>) => {
71
+ setIntoStore(...ps, child)
72
+ }) as typeof setState,
72
73
  run: (token, identifier = arbitrary()) =>
73
74
  actUponStore(token, identifier, child),
74
75
  find: ((token, k) => findInStore(token, k, child)) as typeof findState,
@@ -76,9 +77,9 @@ export const buildTransaction = (
76
77
  json: (token) => getJsonToken(token, child),
77
78
  make: (context, family, k, ...args) =>
78
79
  makeMoleculeInStore(child, context, family, k, ...args),
79
- dispose: (token) => {
80
- disposeFromStore(token, child)
81
- },
80
+ dispose: ((...ps: Parameters<typeof disposeState>) => {
81
+ disposeFromStore(...ps, child)
82
+ }) as typeof disposeState,
82
83
  env: () => getEnvironmentData(child),
83
84
  },
84
85
  }
@@ -32,8 +32,8 @@ export function createTransaction<F extends Func>(
32
32
  const childStore = buildTransaction(options.key, params, store, id)
33
33
  try {
34
34
  const target = newest(store)
35
- const { transactors } = childStore.transactionMeta
36
- const output = options.do(transactors, ...params)
35
+ const { toolkit } = childStore.transactionMeta
36
+ const output = options.do(toolkit, ...params)
37
37
  applyTransaction(output, target)
38
38
  return output
39
39
  } catch (thrown) {
@@ -1,4 +1,4 @@
1
- import type { Func, TransactionUpdate, TransactorsWithRunAndEnv } from "atom.io"
1
+ import type { ActorToolkit, Func, TransactionUpdate } from "atom.io"
2
2
  import type { Junction } from "rel8/junction"
3
3
 
4
4
  export * from "./abort-transaction"
@@ -17,7 +17,7 @@ export type TransactionPhase = (typeof TRANSACTION_PHASES)[number]
17
17
  export type TransactionProgress<F extends Func> = {
18
18
  phase: `applying` | `building`
19
19
  update: TransactionUpdate<F>
20
- transactors: TransactorsWithRunAndEnv
20
+ toolkit: ActorToolkit
21
21
  }
22
22
 
23
23
  export type TransactionEpoch = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "atom.io",
3
- "version": "0.24.8",
3
+ "version": "0.25.0",
4
4
  "description": "Composable and testable reactive data library.",
5
5
  "homepage": "https://atom.io.fyi",
6
6
  "sideEffects": false,
@@ -64,7 +64,7 @@
64
64
  "drizzle-kit": "0.22.7",
65
65
  "drizzle-orm": "0.31.2",
66
66
  "eslint": "npm:eslint@8.57.0",
67
- "eslint-v9": "npm:eslint@9.5.0",
67
+ "eslint-v9": "npm:eslint@9.6.0",
68
68
  "framer-motion": "11.2.12",
69
69
  "happy-dom": "14.12.3",
70
70
  "http-proxy": "1.18.1",
@@ -79,7 +79,7 @@
79
79
  "tmp": "0.2.3",
80
80
  "tsup": "8.1.0",
81
81
  "typescript": "5.5.2",
82
- "vite": "5.3.1",
82
+ "vite": "5.3.2",
83
83
  "vite-tsconfig-paths": "4.3.2",
84
84
  "vitest": "1.6.0"
85
85
  },
@@ -250,7 +250,7 @@
250
250
  }
251
251
  },
252
252
  "scripts": {
253
- "manifest": "tsx __scripts__/manifest-build.node",
253
+ "manifest": "tsx __scripts__/manifest-build.node.ts",
254
254
  "clean:build": "find . -type d -name 'dist' -not -path '*/node_modules/*' | xargs rm -rf",
255
255
  "build": "bun run clean:build && concurrently \"npm:build:*\"",
256
256
  "build:main": "tsup",
@@ -279,7 +279,7 @@
279
279
  "test:coverage": "vitest run --coverage",
280
280
  "test:once": "bun run test:manifest && cross-env IMPORT=dist vitest run",
281
281
  "test:once:public": "cross-env IMPORT=dist vitest run public",
282
- "test:manifest": "tsx __scripts__/manifest-test.node",
282
+ "test:manifest": "tsx __scripts__/manifest-test.node.ts",
283
283
  "test:semver": "bun ../break-check/src/break-check.x.ts --verbose"
284
284
  }
285
285
  }
@@ -41,7 +41,10 @@ function useI(token, key) {
41
41
  }
42
42
  function useO(token, key) {
43
43
  const store = React5__namespace.useContext(StoreContext);
44
- const stateToken = token.type === `atom_family` || token.type === `mutable_atom_family` || token.type === `selector_family` || token.type === `readonly_selector_family` ? internal.findInStore(token, key, store) : token;
44
+ const stateToken = token.type === `atom_family` || token.type === `mutable_atom_family` || token.type === `selector_family` || token.type === `readonly_selector_family` ? internal.seekInStore(token, key, store) : token;
45
+ if (!stateToken) {
46
+ throw new internal.NotFoundError(token, store);
47
+ }
45
48
  const id = React5__namespace.useId();
46
49
  return React5__namespace.useSyncExternalStore(
47
50
  (dispatch) => internal.subscribeToState(stateToken, dispatch, `use-o:${id}`, store),
@@ -1,5 +1,5 @@
1
1
  import '../../dist/chunk-S4N6XNPH.js';
2
- import { IMPLICIT, findInStore, setIntoStore, subscribeToState, getFromStore, getJsonToken, withdraw, subscribeToTimeline } from 'atom.io/internal';
2
+ import { IMPLICIT, findInStore, setIntoStore, seekInStore, NotFoundError, subscribeToState, getFromStore, getJsonToken, withdraw, subscribeToTimeline } from 'atom.io/internal';
3
3
  import * as React5 from 'react';
4
4
  import { jsx } from 'react/jsx-runtime';
5
5
  import { undo, redo } from 'atom.io';
@@ -19,7 +19,10 @@ function useI(token, key) {
19
19
  }
20
20
  function useO(token, key) {
21
21
  const store = React5.useContext(StoreContext);
22
- const stateToken = token.type === `atom_family` || token.type === `mutable_atom_family` || token.type === `selector_family` || token.type === `readonly_selector_family` ? findInStore(token, key, store) : token;
22
+ const stateToken = token.type === `atom_family` || token.type === `mutable_atom_family` || token.type === `selector_family` || token.type === `readonly_selector_family` ? seekInStore(token, key, store) : token;
23
+ if (!stateToken) {
24
+ throw new NotFoundError(token, store);
25
+ }
23
26
  const id = React5.useId();
24
27
  return React5.useSyncExternalStore(
25
28
  (dispatch) => subscribeToState(stateToken, dispatch, `use-o:${id}`, store),
@@ -1,5 +1,10 @@
1
1
  import type { ReadableFamilyToken, ReadableToken } from "atom.io"
2
- import { findInStore, getFromStore, subscribeToState } from "atom.io/internal"
2
+ import {
3
+ getFromStore,
4
+ NotFoundError,
5
+ seekInStore,
6
+ subscribeToState,
7
+ } from "atom.io/internal"
3
8
  import type { Json } from "atom.io/json"
4
9
  import * as React from "react"
5
10
 
@@ -17,13 +22,16 @@ export function useO<T, K extends Json.Serializable>(
17
22
  key?: K,
18
23
  ): T {
19
24
  const store = React.useContext(StoreContext)
20
- const stateToken: ReadableToken<any> =
25
+ const stateToken: ReadableToken<any> | undefined =
21
26
  token.type === `atom_family` ||
22
27
  token.type === `mutable_atom_family` ||
23
28
  token.type === `selector_family` ||
24
29
  token.type === `readonly_selector_family`
25
- ? findInStore(token, key as K, store)
30
+ ? seekInStore(token, key as K, store)
26
31
  : token
32
+ if (!stateToken) {
33
+ throw new NotFoundError(token, store)
34
+ }
27
35
  const id = React.useId()
28
36
  return React.useSyncExternalStore<T>(
29
37
  (dispatch) => subscribeToState(stateToken, dispatch, `use-o:${id}`, store),
@@ -24,7 +24,6 @@ var InvariantMap = class extends Map {
24
24
  var _SyncGroup = class _SyncGroup {
25
25
  constructor(key) {
26
26
  this.key = key;
27
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
28
27
  this.type = `continuity`;
29
28
  this.globals = [];
30
29
  this.actions = [];
@@ -22,7 +22,6 @@ var InvariantMap = class extends Map {
22
22
  var _SyncGroup = class _SyncGroup {
23
23
  constructor(key) {
24
24
  this.key = key;
25
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
26
25
  this.type = `continuity`;
27
26
  this.globals = [];
28
27
  this.actions = [];
@@ -51,7 +51,6 @@ export type ContinuityToken = {
51
51
  }
52
52
 
53
53
  export class SyncGroup {
54
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
55
54
  protected type = `continuity` as const
56
55
 
57
56
  protected globals: AtomToken<any>[] = []
@@ -410,41 +410,41 @@ var createRoomTX = AtomIO__namespace.transaction({
410
410
  });
411
411
  var joinRoomTX = AtomIO__namespace.transaction({
412
412
  key: `joinRoom`,
413
- do: (transactors, roomId, userId, enteredAtEpoch) => {
413
+ do: (tools, roomId, userId, enteredAtEpoch) => {
414
414
  const meta = { enteredAtEpoch };
415
415
  data.editRelationsInStore(
416
416
  realtime.usersInRooms,
417
417
  (relations) => {
418
418
  relations.set({ room: roomId, user: userId }, meta);
419
419
  },
420
- transactors.env().store
420
+ tools.env().store
421
421
  );
422
422
  return meta;
423
423
  }
424
424
  });
425
425
  var leaveRoomTX = AtomIO__namespace.transaction({
426
426
  key: `leaveRoom`,
427
- do: (transactors, roomId, userId) => {
427
+ do: (tools, roomId, userId) => {
428
428
  data.editRelationsInStore(
429
429
  realtime.usersInRooms,
430
430
  (relations) => {
431
431
  relations.delete({ room: roomId, user: userId });
432
432
  },
433
- transactors.env().store
433
+ tools.env().store
434
434
  );
435
435
  }
436
436
  });
437
437
  var destroyRoomTX = AtomIO__namespace.transaction({
438
438
  key: `destroyRoom`,
439
- do: (transactors, roomId) => {
439
+ do: (tools, roomId) => {
440
440
  data.editRelationsInStore(
441
441
  realtime.usersInRooms,
442
442
  (relations) => {
443
443
  relations.delete({ room: roomId });
444
444
  },
445
- transactors.env().store
445
+ tools.env().store
446
446
  );
447
- transactors.set(realtime.roomIndex, (s) => (s.delete(roomId), s));
447
+ tools.set(realtime.roomIndex, (s) => (s.delete(roomId), s));
448
448
  }
449
449
  });
450
450
  function redactTransactionUpdateContent(visibleStateKeys, updates) {