atom.io 0.21.0 → 0.22.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 (99) hide show
  1. package/data/dist/index.cjs +139 -66
  2. package/data/dist/index.d.ts +6 -0
  3. package/data/dist/index.js +3 -3
  4. package/data/src/join.ts +135 -56
  5. package/data/src/struct-family.ts +2 -2
  6. package/dist/{chunk-RT43TVKP.js → chunk-GVHKIJ3G.js} +1 -1
  7. package/dist/{chunk-KGZGBCYS.js → chunk-JA4V7TJY.js} +135 -62
  8. package/dist/index.cjs +2 -7
  9. package/dist/index.d.ts +29 -14
  10. package/dist/index.js +4 -8
  11. package/ephemeral/dist/index.cjs +11 -0
  12. package/ephemeral/dist/index.js +9 -0
  13. package/ephemeral/package.json +16 -0
  14. package/ephemeral/src/index.ts +1 -0
  15. package/eslint-plugin/dist/index.cjs +156 -1
  16. package/eslint-plugin/dist/index.js +156 -1
  17. package/eslint-plugin/src/rules/index.ts +1 -0
  18. package/eslint-plugin/src/rules/lifespan.ts +204 -0
  19. package/eslint-plugin/src/rules/synchronous-selector-dependencies.ts +1 -65
  20. package/eslint-plugin/src/walk.ts +73 -0
  21. package/immortal/dist/index.cjs +100 -0
  22. package/immortal/dist/index.js +97 -0
  23. package/immortal/package.json +16 -0
  24. package/immortal/src/index.ts +2 -0
  25. package/immortal/src/molecule.ts +134 -0
  26. package/immortal/src/seek-state.ts +60 -0
  27. package/internal/dist/index.cjs +211 -194
  28. package/internal/dist/index.d.ts +30 -14
  29. package/internal/dist/index.js +210 -194
  30. package/internal/src/atom/dispose-atom.ts +4 -1
  31. package/internal/src/families/create-readonly-selector-family.ts +9 -9
  32. package/internal/src/families/create-regular-atom-family.ts +15 -20
  33. package/internal/src/families/create-writable-selector-family.ts +6 -7
  34. package/internal/src/families/find-in-store.ts +11 -5
  35. package/internal/src/families/index.ts +2 -0
  36. package/internal/src/families/init-family-member.ts +91 -0
  37. package/internal/src/families/seek-in-store.ts +106 -0
  38. package/internal/src/future.ts +6 -20
  39. package/internal/src/get-state/get-from-store.ts +2 -3
  40. package/internal/src/mutable/create-mutable-atom-family.ts +17 -23
  41. package/internal/src/mutable/create-mutable-atom.ts +3 -1
  42. package/internal/src/mutable/get-json-family.ts +2 -2
  43. package/internal/src/mutable/get-json-token.ts +27 -12
  44. package/internal/src/mutable/tracker-family.ts +14 -12
  45. package/internal/src/mutable/tracker.ts +2 -24
  46. package/internal/src/not-found-error.ts +11 -3
  47. package/internal/src/operation.ts +0 -1
  48. package/internal/src/selector/create-readonly-selector.ts +2 -2
  49. package/internal/src/selector/create-writable-selector.ts +2 -2
  50. package/internal/src/selector/dispose-selector.ts +40 -23
  51. package/internal/src/selector/register-selector.ts +8 -5
  52. package/internal/src/set-state/set-into-store.ts +2 -2
  53. package/internal/src/store/index.ts +0 -1
  54. package/internal/src/store/store.ts +18 -5
  55. package/internal/src/subscribe/recall-state.ts +3 -3
  56. package/internal/src/subscribe/subscribe-to-state.ts +18 -5
  57. package/internal/src/transaction/build-transaction.ts +7 -2
  58. package/introspection/dist/index.cjs +39 -65
  59. package/introspection/dist/index.js +39 -65
  60. package/introspection/src/attach-atom-index.ts +38 -48
  61. package/introspection/src/attach-introspection-states.ts +0 -1
  62. package/introspection/src/attach-selector-index.ts +45 -50
  63. package/introspection/src/attach-timeline-family.ts +2 -17
  64. package/json/dist/index.cjs +38 -4
  65. package/json/dist/index.js +40 -6
  66. package/json/src/select-json-family.ts +46 -7
  67. package/package.json +31 -11
  68. package/react/dist/index.cjs +1 -1
  69. package/react/dist/index.js +1 -1
  70. package/react/src/use-json.ts +1 -1
  71. package/react-devtools/dist/index.cjs +11 -10
  72. package/react-devtools/dist/index.js +2 -1
  73. package/react-devtools/src/StateIndex.tsx +2 -1
  74. package/react-devtools/src/TimelineIndex.tsx +2 -1
  75. package/react-devtools/src/TransactionIndex.tsx +7 -7
  76. package/realtime-client/dist/index.cjs +3 -3
  77. package/realtime-client/dist/index.js +3 -3
  78. package/realtime-client/src/pull-mutable-atom-family-member.ts +1 -1
  79. package/realtime-client/src/pull-mutable-atom.ts +1 -1
  80. package/realtime-client/src/sync-continuity.ts +1 -2
  81. package/realtime-react/dist/index.cjs +1 -1
  82. package/realtime-react/dist/index.js +1 -1
  83. package/realtime-server/dist/index.cjs +18 -17
  84. package/realtime-server/dist/index.js +7 -6
  85. package/realtime-server/src/realtime-continuity-synchronizer.ts +5 -3
  86. package/realtime-server/src/realtime-mutable-family-provider.ts +2 -1
  87. package/realtime-server/src/realtime-mutable-provider.ts +1 -1
  88. package/realtime-testing/dist/index.cjs +6 -2
  89. package/realtime-testing/dist/index.js +8 -5
  90. package/realtime-testing/src/setup-realtime-test.tsx +5 -2
  91. package/src/atom.ts +10 -4
  92. package/src/index.ts +1 -2
  93. package/src/selector.ts +10 -4
  94. package/src/silo.ts +3 -3
  95. package/src/transaction.ts +5 -2
  96. package/src/validators.ts +0 -6
  97. package/internal/src/store/withdraw-new-family-member.ts +0 -69
  98. /package/{src → ephemeral/src}/find-state.ts +0 -0
  99. /package/src/{dispose.ts → dispose-state.ts} +0 -0
@@ -12,8 +12,10 @@ export function disposeAtom(atomToken: AtomToken<unknown>, store: Store): void {
12
12
  `❌`,
13
13
  `atom`,
14
14
  key,
15
- `Tried to delete atom, but it does not exist in the store.`,
15
+ `Tried to dispose atom, but it does not exist in the store.`,
16
16
  )
17
+ } else if (!atom.family) {
18
+ store.logger.error(`❌`, `atom`, key, `Standalone atoms cannot be disposed.`)
17
19
  } else {
18
20
  atom.cleanup?.()
19
21
  target.atoms.delete(key)
@@ -35,6 +37,7 @@ export function disposeAtom(atomToken: AtomToken<unknown>, store: Store): void {
35
37
  if (atomToken.type === `mutable_atom`) {
36
38
  const updateToken = getUpdateToken(atomToken)
37
39
  disposeAtom(updateToken, store)
40
+ store.trackers.delete(key)
38
41
  }
39
42
  store.logger.info(`🔥`, `atom`, key, `deleted`)
40
43
  store.on.atomDisposal.next(atomToken)
@@ -10,7 +10,6 @@ import { stringifyJson } from "atom.io/json"
10
10
  import { newest } from "../lineage"
11
11
  import { createReadonlySelector } from "../selector"
12
12
  import type { Store } from "../store"
13
- import { deposit } from "../store"
14
13
  import { Subject } from "../subject"
15
14
 
16
15
  export function createReadonlySelectorFamily<T, K extends Json.Serializable>(
@@ -18,24 +17,25 @@ export function createReadonlySelectorFamily<T, K extends Json.Serializable>(
18
17
  store: Store,
19
18
  ): ReadonlySelectorFamily<T, K> {
20
19
  const subject = new Subject<ReadonlySelectorToken<T>>()
20
+
21
21
  const readonlySelectorFamily = Object.assign(
22
22
  (key: K): ReadonlySelectorToken<T> => {
23
- const target = newest(store)
24
23
  const subKey = stringifyJson(key)
25
24
  const family: FamilyMetadata = { key: options.key, subKey }
26
25
  const fullKey = `${options.key}(${subKey})`
27
- const existing = target.readonlySelectors.get(fullKey)
28
- if (existing) {
29
- return deposit(existing)
30
- }
31
- return createReadonlySelector(
26
+ const target = newest(store)
27
+
28
+ const token = createReadonlySelector(
32
29
  {
33
30
  key: fullKey,
34
31
  get: options.get(key),
35
32
  },
36
33
  family,
37
- store,
34
+ target,
38
35
  )
36
+
37
+ subject.next(token)
38
+ return token
39
39
  },
40
40
  {
41
41
  key: options.key,
@@ -43,7 +43,7 @@ export function createReadonlySelectorFamily<T, K extends Json.Serializable>(
43
43
  subject,
44
44
  install: (s: Store) => createReadonlySelectorFamily(options, s),
45
45
  } as const,
46
- ) as ReadonlySelectorFamily<T, K>
46
+ ) satisfies ReadonlySelectorFamily<T, K>
47
47
  store.families.set(options.key, readonlySelectorFamily)
48
48
  return readonlySelectorFamily
49
49
  }
@@ -18,30 +18,26 @@ export function createRegularAtomFamily<T, K extends Json.Serializable>(
18
18
  store: Store,
19
19
  ): RegularAtomFamily<T, K> {
20
20
  const subject = new Subject<RegularAtomToken<T>>()
21
+
21
22
  const atomFamily: RegularAtomFamily<T, K> = Object.assign(
22
23
  (key: K): RegularAtomToken<any> => {
23
24
  const subKey = stringifyJson(key)
24
25
  const family: FamilyMetadata = { key: options.key, subKey }
25
26
  const fullKey = `${options.key}(${subKey})`
26
27
  const target = newest(store)
27
- const atomAlreadyCreated = target.atoms.has(fullKey)
28
- let token: RegularAtomToken<any>
29
- if (atomAlreadyCreated) {
30
- token = { type: `atom`, key: fullKey, family }
31
- } else {
32
- const individualOptions: RegularAtomOptions<any> = {
33
- key: fullKey,
34
- default:
35
- options.default instanceof Function
36
- ? options.default(key)
37
- : options.default,
38
- }
39
- if (options.effects) {
40
- individualOptions.effects = options.effects(key)
41
- }
42
- token = createRegularAtom(individualOptions, family, store)
43
- subject.next(token)
28
+
29
+ const def = options.default
30
+ const individualOptions: RegularAtomOptions<T> = {
31
+ key: fullKey,
32
+ default: def instanceof Function ? def(key) : def,
33
+ }
34
+ if (options.effects) {
35
+ individualOptions.effects = options.effects(key)
44
36
  }
37
+
38
+ const token = createRegularAtom(individualOptions, family, target)
39
+
40
+ subject.next(token)
45
41
  return token
46
42
  },
47
43
  {
@@ -50,8 +46,7 @@ export function createRegularAtomFamily<T, K extends Json.Serializable>(
50
46
  subject,
51
47
  install: (s: Store) => createRegularAtomFamily(options, s),
52
48
  } as const,
53
- )
54
- const target = newest(store)
55
- target.families.set(options.key, atomFamily)
49
+ ) satisfies RegularAtomFamily<T, K>
50
+ store.families.set(options.key, atomFamily)
56
51
  return atomFamily
57
52
  }
@@ -7,9 +7,9 @@ import type {
7
7
  import type { Json } from "atom.io/json"
8
8
  import { stringifyJson } from "atom.io/json"
9
9
 
10
+ import { newest } from "../lineage"
10
11
  import { createWritableSelector } from "../selector"
11
12
  import type { Store } from "../store"
12
- import { deposit } from "../store"
13
13
  import { Subject } from "../subject"
14
14
 
15
15
  export function createWritableSelectorFamily<T, K extends Json.Serializable>(
@@ -23,10 +23,8 @@ export function createWritableSelectorFamily<T, K extends Json.Serializable>(
23
23
  const subKey = stringifyJson(key)
24
24
  const family: FamilyMetadata = { key: options.key, subKey }
25
25
  const fullKey = `${options.key}(${subKey})`
26
- const existing = store.selectors.get(fullKey)
27
- if (existing) {
28
- return deposit(existing)
29
- }
26
+ const target = newest(store)
27
+
30
28
  const token = createWritableSelector(
31
29
  {
32
30
  key: fullKey,
@@ -34,8 +32,9 @@ export function createWritableSelectorFamily<T, K extends Json.Serializable>(
34
32
  set: options.set(key),
35
33
  },
36
34
  family,
37
- store,
35
+ target,
38
36
  )
37
+
39
38
  subject.next(token)
40
39
  return token
41
40
  },
@@ -45,7 +44,7 @@ export function createWritableSelectorFamily<T, K extends Json.Serializable>(
45
44
  subject,
46
45
  install: (s: Store) => createWritableSelectorFamily(options, s),
47
46
  } as const,
48
- ) as WritableSelectorFamily<T, K>
47
+ ) satisfies WritableSelectorFamily<T, K>
49
48
  store.families.set(options.key, selectorFamily)
50
49
  return selectorFamily
51
50
  }
@@ -21,6 +21,8 @@ import type { Json } from "atom.io/json"
21
21
  import type { Transceiver } from "../mutable"
22
22
  import { NotFoundError } from "../not-found-error"
23
23
  import type { Store } from "../store"
24
+ import { initFamilyMember } from "./init-family-member"
25
+ import { seekInStore } from "./seek-in-store"
24
26
 
25
27
  export function findInStore<
26
28
  T extends Transceiver<any>,
@@ -80,11 +82,15 @@ export function findInStore(
80
82
  key: Json.Serializable,
81
83
  store: Store,
82
84
  ): ReadableToken<any> {
83
- const familyKey = token.key
84
- const family = store.families.get(familyKey)
85
- if (family === undefined) {
86
- throw new NotFoundError(token, store)
85
+ if (store.config.lifespan === `immortal`) {
86
+ throw new Error(
87
+ `Do not use \`find\` or \`findState\` in an immortal store. Prefer \`seek\` or \`seekState\`.`,
88
+ )
87
89
  }
88
- const state = family(key)
90
+ let state = seekInStore(token, key, store)
91
+ if (state) {
92
+ return state
93
+ }
94
+ state = initFamilyMember(token, key, store)
89
95
  return state
90
96
  }
@@ -3,3 +3,5 @@ export * from "./create-readonly-selector-family"
3
3
  export * from "./create-regular-atom-family"
4
4
  export * from "./create-selector-family"
5
5
  export * from "./find-in-store"
6
+ export * from "./init-family-member"
7
+ export * from "./seek-in-store"
@@ -0,0 +1,91 @@
1
+ import type {
2
+ AtomFamilyToken,
3
+ AtomToken,
4
+ MutableAtomFamilyToken,
5
+ MutableAtomToken,
6
+ ReadableFamilyToken,
7
+ ReadableToken,
8
+ ReadonlySelectorFamilyToken,
9
+ ReadonlySelectorToken,
10
+ RegularAtomFamilyToken,
11
+ RegularAtomToken,
12
+ SelectorFamilyToken,
13
+ SelectorToken,
14
+ WritableFamilyToken,
15
+ WritableSelectorFamilyToken,
16
+ WritableSelectorToken,
17
+ WritableToken,
18
+ } from "atom.io"
19
+ import type { Json } from "atom.io/json"
20
+
21
+ import type { Transceiver } from "../mutable"
22
+ import { NotFoundError } from "../not-found-error"
23
+ import type { Store } from "../store"
24
+ import { seekInStore } from "./seek-in-store"
25
+
26
+ export function initFamilyMember<
27
+ T extends Transceiver<any>,
28
+ J extends Json.Serializable,
29
+ K extends Json.Serializable,
30
+ Key extends K,
31
+ >(
32
+ token: MutableAtomFamilyToken<T, J, K>,
33
+ key: Key,
34
+ store: Store,
35
+ ): MutableAtomToken<T, J>
36
+
37
+ export function initFamilyMember<T, K extends Json.Serializable, Key extends K>(
38
+ token: RegularAtomFamilyToken<T, K>,
39
+ key: Key,
40
+ store: Store,
41
+ ): RegularAtomToken<T>
42
+
43
+ export function initFamilyMember<T, K extends Json.Serializable, Key extends K>(
44
+ token: AtomFamilyToken<T, K>,
45
+ key: Key,
46
+ store: Store,
47
+ ): AtomToken<T>
48
+
49
+ export function initFamilyMember<T, K extends Json.Serializable, Key extends K>(
50
+ token: WritableSelectorFamilyToken<T, K>,
51
+ key: Key,
52
+ store: Store,
53
+ ): WritableSelectorToken<T>
54
+
55
+ export function initFamilyMember<T, K extends Json.Serializable, Key extends K>(
56
+ token: ReadonlySelectorFamilyToken<T, K>,
57
+ key: Key,
58
+ store: Store,
59
+ ): ReadonlySelectorToken<T>
60
+
61
+ export function initFamilyMember<T, K extends Json.Serializable, Key extends K>(
62
+ token: SelectorFamilyToken<T, K>,
63
+ key: Key,
64
+ store: Store,
65
+ ): SelectorToken<T>
66
+
67
+ export function initFamilyMember<T, K extends Json.Serializable, Key extends K>(
68
+ token: WritableFamilyToken<T, K>,
69
+ key: Key,
70
+ store: Store,
71
+ ): WritableToken<T>
72
+
73
+ export function initFamilyMember<T, K extends Json.Serializable, Key extends K>(
74
+ token: ReadableFamilyToken<T, K>,
75
+ key: Key,
76
+ store: Store,
77
+ ): ReadableToken<T>
78
+
79
+ export function initFamilyMember(
80
+ token: ReadableFamilyToken<any, any>,
81
+ key: Json.Serializable,
82
+ store: Store,
83
+ ): ReadableToken<any> {
84
+ const familyKey = token.key
85
+ const family = store.families.get(familyKey)
86
+ if (family === undefined) {
87
+ throw new NotFoundError(token, store)
88
+ }
89
+ const state = family(key)
90
+ return state
91
+ }
@@ -0,0 +1,106 @@
1
+ import type {
2
+ AtomFamilyToken,
3
+ AtomToken,
4
+ MutableAtomFamilyToken,
5
+ MutableAtomToken,
6
+ ReadableFamilyToken,
7
+ ReadableToken,
8
+ ReadonlySelectorFamilyToken,
9
+ ReadonlySelectorToken,
10
+ RegularAtomFamilyToken,
11
+ RegularAtomToken,
12
+ SelectorFamilyToken,
13
+ SelectorToken,
14
+ WritableFamilyToken,
15
+ WritableSelectorFamilyToken,
16
+ WritableSelectorToken,
17
+ WritableToken,
18
+ } from "atom.io"
19
+ import { type Json, stringifyJson } from "atom.io/json"
20
+
21
+ import type { ReadableState } from ".."
22
+ import { newest } from "../lineage"
23
+ import type { Transceiver } from "../mutable"
24
+ import { deposit, type Store } from "../store"
25
+
26
+ export function seekInStore<
27
+ T extends Transceiver<any>,
28
+ J extends Json.Serializable,
29
+ K extends Json.Serializable,
30
+ Key extends K,
31
+ >(
32
+ token: MutableAtomFamilyToken<T, J, K>,
33
+ key: Key,
34
+ store: Store,
35
+ ): MutableAtomToken<T, J> | undefined
36
+
37
+ export function seekInStore<T, K extends Json.Serializable, Key extends K>(
38
+ token: RegularAtomFamilyToken<T, K>,
39
+ key: Key,
40
+ store: Store,
41
+ ): RegularAtomToken<T> | undefined
42
+
43
+ export function seekInStore<T, K extends Json.Serializable, Key extends K>(
44
+ token: AtomFamilyToken<T, K>,
45
+ key: Key,
46
+ store: Store,
47
+ ): AtomToken<T> | undefined
48
+
49
+ export function seekInStore<T, K extends Json.Serializable, Key extends K>(
50
+ token: WritableSelectorFamilyToken<T, K>,
51
+ key: Key,
52
+ store: Store,
53
+ ): WritableSelectorToken<T> | undefined
54
+
55
+ export function seekInStore<T, K extends Json.Serializable, Key extends K>(
56
+ token: ReadonlySelectorFamilyToken<T, K>,
57
+ key: Key,
58
+ store: Store,
59
+ ): ReadonlySelectorToken<T> | undefined
60
+
61
+ export function seekInStore<T, K extends Json.Serializable, Key extends K>(
62
+ token: SelectorFamilyToken<T, K>,
63
+ key: Key,
64
+ store: Store,
65
+ ): SelectorToken<T> | undefined
66
+
67
+ export function seekInStore<T, K extends Json.Serializable, Key extends K>(
68
+ token: WritableFamilyToken<T, K>,
69
+ key: Key,
70
+ store: Store,
71
+ ): WritableToken<T> | undefined
72
+
73
+ export function seekInStore<T, K extends Json.Serializable, Key extends K>(
74
+ token: ReadableFamilyToken<T, K>,
75
+ key: Key,
76
+ store: Store,
77
+ ): ReadableToken<T> | undefined
78
+
79
+ export function seekInStore(
80
+ token: ReadableFamilyToken<any, any>,
81
+ key: Json.Serializable,
82
+ store: Store,
83
+ ): ReadableToken<any> | undefined {
84
+ const subKey = stringifyJson(key)
85
+ const fullKey = `${token.key}(${subKey})`
86
+ const target = newest(store)
87
+ let state: ReadableState<any> | undefined
88
+ switch (token.type) {
89
+ case `atom_family`:
90
+ case `mutable_atom_family`:
91
+ state = target.atoms.get(fullKey)
92
+ break
93
+
94
+ case `selector_family`: {
95
+ state = target.selectors.get(fullKey)
96
+ break
97
+ }
98
+ case `readonly_selector_family`:
99
+ state = target.readonlySelectors.get(fullKey)
100
+ break
101
+ }
102
+ if (state) {
103
+ return deposit(state)
104
+ }
105
+ return state
106
+ }
@@ -8,7 +8,7 @@
8
8
  * Can be constructed like a Promise, or from an existing Promise.
9
9
  */
10
10
  export class Future<T> extends Promise<T> {
11
- private destiny: Promise<T> | undefined
11
+ private fate: Promise<T> | undefined
12
12
  private resolve: (value: T) => void
13
13
  private reject: (reason?: any) => void
14
14
 
@@ -17,38 +17,24 @@ export class Future<T> extends Promise<T> {
17
17
  | Promise<T>
18
18
  | ((resolve: (value: T) => void, reject: (reason?: any) => void) => void),
19
19
  ) {
20
- let promise: Promise<T> | undefined
21
20
  let superResolve: ((value: T) => void) | undefined
22
21
  let superReject: ((reason?: any) => void) | undefined
23
22
  super((resolve, reject) => {
24
23
  superResolve = resolve
25
24
  superReject = reject
26
- promise = executor instanceof Promise ? executor : new Promise(executor)
27
- promise.then(
28
- (value) => {
29
- if (promise) {
30
- this.pass(promise, value)
31
- }
32
- },
33
- (reason) => {
34
- if (promise) {
35
- this.fail(promise, reason)
36
- }
37
- },
38
- )
39
25
  })
40
- this.destiny = promise
41
26
  this.resolve = superResolve as (value: T) => void
42
27
  this.reject = superReject as (reason?: any) => void
28
+ this.use(executor instanceof Promise ? executor : new Promise(executor))
43
29
  }
44
30
 
45
31
  private pass(promise: Promise<T>, value: T) {
46
- if (promise === this.destiny) {
32
+ if (promise === this.fate) {
47
33
  this.resolve(value)
48
34
  }
49
35
  }
50
36
  private fail(promise: Promise<T>, reason: any) {
51
- if (promise === this.destiny) {
37
+ if (promise === this.fate) {
52
38
  this.reject(reason)
53
39
  }
54
40
  }
@@ -56,7 +42,7 @@ export class Future<T> extends Promise<T> {
56
42
  public use(value: Promise<T> | T): void {
57
43
  if (value instanceof Promise) {
58
44
  const promise = value
59
- this.destiny = promise
45
+ this.fate = promise
60
46
  promise.then(
61
47
  (resolved) => {
62
48
  this.pass(promise, resolved)
@@ -67,7 +53,7 @@ export class Future<T> extends Promise<T> {
67
53
  )
68
54
  } else {
69
55
  this.resolve(value)
70
- this.destiny = undefined
56
+ this.fate = undefined
71
57
  }
72
58
  }
73
59
  }
@@ -1,11 +1,10 @@
1
1
  import type { ReadableToken } from "atom.io"
2
2
 
3
- import { NotFoundError } from "../not-found-error"
4
3
  import type { Store } from "../store"
5
- import { withdraw, withdrawOrCreate } from "../store"
4
+ import { withdraw } from "../store"
6
5
  import { readOrComputeValue } from "./read-or-compute-value"
7
6
 
8
7
  export function getFromStore<T>(token: ReadableToken<T>, store: Store): T {
9
- const state = withdrawOrCreate(token, store)
8
+ const state = withdraw(token, store)
10
9
  return readOrComputeValue(state, store)
11
10
  }
@@ -24,32 +24,28 @@ export function createMutableAtomFamily<
24
24
  store: Store,
25
25
  ): MutableAtomFamily<T, J, K> {
26
26
  const subject = new Subject<MutableAtomToken<T, J>>()
27
- const atomFamily: MutableAtomFamily<T, J, K> = Object.assign(
27
+
28
+ const atomFamily = Object.assign(
28
29
  (key: K): MutableAtomToken<T, J> => {
29
30
  const subKey = stringifyJson(key)
30
31
  const family: FamilyMetadata = { key: options.key, subKey }
31
32
  const fullKey = `${options.key}(${subKey})`
32
33
  const target = newest(store)
33
- const atomAlreadyCreated = target.atoms.has(fullKey)
34
- let token: MutableAtomToken<T, J>
35
- if (atomAlreadyCreated) {
36
- token = { type: `mutable_atom`, key: fullKey, family }
37
- } else {
38
- const individualOptions: MutableAtomOptions<T, J> = {
39
- key: fullKey,
40
- default: () => options.default(key),
41
- toJson: options.toJson,
42
- fromJson: options.fromJson,
43
- mutable: true,
44
- }
45
- if (options.effects) {
46
- individualOptions.effects = options.effects(key)
47
- }
48
-
49
- token = createMutableAtom(individualOptions, family, store)
50
34
 
51
- subject.next(token)
35
+ const individualOptions: MutableAtomOptions<T, J> = {
36
+ key: fullKey,
37
+ default: () => options.default(key),
38
+ toJson: options.toJson,
39
+ fromJson: options.fromJson,
40
+ mutable: true,
41
+ }
42
+ if (options.effects) {
43
+ individualOptions.effects = options.effects(key)
52
44
  }
45
+
46
+ const token = createMutableAtom(individualOptions, family, target)
47
+
48
+ subject.next(token)
53
49
  return token
54
50
  },
55
51
  {
@@ -60,10 +56,8 @@ export function createMutableAtomFamily<
60
56
  toJson: options.toJson,
61
57
  fromJson: options.fromJson,
62
58
  } as const,
63
- )
64
-
65
- const target = newest(store)
66
- target.families.set(options.key, atomFamily)
59
+ ) satisfies MutableAtomFamily<T, J, K>
60
+ store.families.set(options.key, atomFamily)
67
61
  selectJsonFamily(atomFamily, options, store)
68
62
  new FamilyTracker(atomFamily, store)
69
63
  return atomFamily
@@ -88,7 +88,9 @@ export function createMutableAtom<
88
88
  }
89
89
 
90
90
  new Tracker(token, store)
91
- selectJson(token, options, store)
91
+ if (!family) {
92
+ selectJson(token, options, store)
93
+ }
92
94
 
93
95
  store.on.atomCreation.next(token)
94
96
 
@@ -1,4 +1,4 @@
1
- import type { MutableAtomFamily, WritableSelectorFamily } from "atom.io"
1
+ import type { MutableAtomFamilyToken, WritableSelectorFamily } from "atom.io"
2
2
  import type { Json } from "atom.io/json"
3
3
 
4
4
  import { newest } from "../lineage"
@@ -10,7 +10,7 @@ export const getJsonFamily = <
10
10
  SerializableCore extends Json.Serializable,
11
11
  Key extends string,
12
12
  >(
13
- mutableAtomFamily: MutableAtomFamily<Core, SerializableCore, Key>,
13
+ mutableAtomFamily: MutableAtomFamilyToken<Core, SerializableCore, Key>,
14
14
  store: Store,
15
15
  ): WritableSelectorFamily<SerializableCore, Key> => {
16
16
  const target = newest(store)
@@ -1,6 +1,14 @@
1
- import type { MutableAtomToken, WritableSelectorToken } from "atom.io"
1
+ import type {
2
+ MutableAtomToken,
3
+ WritableSelectorFamily,
4
+ WritableSelectorFamilyToken,
5
+ WritableSelectorToken,
6
+ } from "atom.io"
2
7
  import type { Json } from "atom.io/json"
3
8
 
9
+ import { findInStore } from "../families"
10
+ import { newest } from "../lineage"
11
+ import { type Store, withdraw } from "../store"
4
12
  import type { Transceiver } from "./transceiver"
5
13
 
6
14
  export const getJsonToken = <
@@ -8,19 +16,26 @@ export const getJsonToken = <
8
16
  SerializableCore extends Json.Serializable,
9
17
  >(
10
18
  mutableAtomToken: MutableAtomToken<Core, SerializableCore>,
19
+ store: Store,
11
20
  ): WritableSelectorToken<SerializableCore> => {
12
- const key = mutableAtomToken.family
13
- ? `${mutableAtomToken.family.key}:JSON(${mutableAtomToken.family.subKey})`
14
- : `${mutableAtomToken.key}:JSON`
15
- const jsonToken: WritableSelectorToken<SerializableCore> = {
16
- type: `selector`,
17
- key,
18
- }
19
21
  if (mutableAtomToken.family) {
20
- jsonToken.family = {
21
- key: `${mutableAtomToken.family.key}:JSON`,
22
- subKey: mutableAtomToken.family.subKey,
22
+ const target = newest(store)
23
+ const jsonFamilyKey = `${mutableAtomToken.family.key}:JSON`
24
+ const jsonFamilyToken: WritableSelectorFamilyToken<
25
+ SerializableCore,
26
+ string
27
+ > = {
28
+ key: jsonFamilyKey,
29
+ type: `selector_family`,
23
30
  }
31
+ const family = withdraw(jsonFamilyToken, target)
32
+ const subKey = JSON.parse(mutableAtomToken.family.subKey)
33
+ const jsonToken = findInStore(family, subKey, store)
34
+ return jsonToken
35
+ }
36
+ const token: WritableSelectorToken<SerializableCore> = {
37
+ type: `selector`,
38
+ key: `${mutableAtomToken.key}:JSON`,
24
39
  }
25
- return jsonToken
40
+ return token
26
41
  }