atom.io 0.27.3 → 0.27.5

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 (96) hide show
  1. package/data/dist/index.js +57 -72
  2. package/data/src/dict.ts +9 -12
  3. package/data/src/join.ts +25 -26
  4. package/data/src/struct-family.ts +17 -23
  5. package/data/src/struct.ts +9 -12
  6. package/dist/{chunk-ETCFHO7J.js → chunk-6ABWLAGY.js} +246 -159
  7. package/dist/index.d.ts +4 -4
  8. package/dist/index.js +33 -53
  9. package/ephemeral/dist/index.js +1 -1
  10. package/ephemeral/src/find-state.ts +1 -1
  11. package/immortal/dist/index.js +2 -2
  12. package/immortal/src/seek-state.ts +2 -2
  13. package/internal/dist/index.d.ts +88 -73
  14. package/internal/dist/index.js +1 -1
  15. package/internal/src/atom/create-regular-atom.ts +3 -3
  16. package/internal/src/atom/create-standalone-atom.ts +7 -5
  17. package/internal/src/families/create-atom-family.ts +5 -5
  18. package/internal/src/families/create-readonly-selector-family.ts +35 -7
  19. package/internal/src/families/create-regular-atom-family.ts +16 -6
  20. package/internal/src/families/create-selector-family.ts +5 -5
  21. package/internal/src/families/create-writable-selector-family.ts +35 -8
  22. package/internal/src/families/dispose-from-store.ts +22 -16
  23. package/internal/src/families/find-in-store.ts +11 -11
  24. package/internal/src/families/init-family-member.ts +9 -9
  25. package/internal/src/families/seek-in-store.ts +10 -13
  26. package/internal/src/get-state/get-from-store.ts +58 -20
  27. package/internal/src/get-state/read-or-compute-value.ts +1 -1
  28. package/internal/src/index.ts +5 -3
  29. package/internal/src/ingest-updates/ingest-atom-update.ts +1 -1
  30. package/internal/src/ingest-updates/ingest-creation-disposal.ts +5 -5
  31. package/internal/src/molecule/create-molecule-family.ts +1 -1
  32. package/internal/src/molecule/dispose-molecule.ts +1 -1
  33. package/internal/src/molecule/grow-molecule-in-store.ts +1 -1
  34. package/internal/src/molecule/make-molecule-in-store.ts +5 -5
  35. package/internal/src/mutable/create-mutable-atom-family.ts +15 -6
  36. package/internal/src/mutable/create-mutable-atom.ts +3 -3
  37. package/internal/src/mutable/get-json-token.ts +2 -2
  38. package/internal/src/mutable/tracker-family.ts +3 -3
  39. package/internal/src/mutable/tracker.ts +14 -18
  40. package/internal/src/selector/create-readonly-selector.ts +2 -2
  41. package/internal/src/selector/create-standalone-selector.ts +5 -5
  42. package/internal/src/selector/create-writable-selector.ts +8 -8
  43. package/internal/src/selector/register-selector.ts +9 -9
  44. package/internal/src/set-state/set-into-store.ts +21 -18
  45. package/internal/src/store/deposit.ts +62 -21
  46. package/internal/src/store/store.ts +2 -1
  47. package/internal/src/subscribe/index.ts +2 -0
  48. package/internal/src/subscribe/subscribe-in-store.ts +62 -0
  49. package/internal/src/timeline/time-travel.ts +1 -1
  50. package/internal/src/transaction/build-transaction.ts +7 -6
  51. package/introspection/dist/index.js +66 -87
  52. package/introspection/src/attach-atom-index.ts +5 -8
  53. package/introspection/src/attach-selector-index.ts +6 -8
  54. package/introspection/src/attach-timeline-family.ts +25 -28
  55. package/introspection/src/attach-timeline-index.ts +5 -8
  56. package/introspection/src/attach-transaction-index.ts +5 -8
  57. package/introspection/src/attach-transaction-logs.ts +21 -27
  58. package/json/dist/index.js +12 -15
  59. package/json/src/select-json-family.ts +4 -4
  60. package/json/src/select-json.ts +6 -9
  61. package/package.json +4 -4
  62. package/react/dist/index.js +7 -7
  63. package/react/src/parse-state-overloads.ts +2 -2
  64. package/react/src/use-i.ts +1 -1
  65. package/react/src/use-json.ts +2 -2
  66. package/react/src/use-o.ts +2 -2
  67. package/realtime-client/dist/index.js +35 -55
  68. package/realtime-client/src/pull-atom-family-member.ts +1 -1
  69. package/realtime-client/src/pull-atom.ts +1 -1
  70. package/realtime-client/src/pull-mutable-atom-family-member.ts +3 -3
  71. package/realtime-client/src/pull-mutable-atom.ts +3 -3
  72. package/realtime-client/src/sync-continuity.ts +27 -47
  73. package/realtime-react/dist/index.js +3 -3
  74. package/realtime-react/src/use-pull-atom-family-member.ts +1 -1
  75. package/realtime-react/src/use-pull-mutable-family-member.ts +1 -1
  76. package/realtime-react/src/use-pull-selector-family-member.ts +1 -1
  77. package/realtime-server/dist/index.js +32 -32
  78. package/realtime-server/src/realtime-continuity-synchronizer.ts +16 -16
  79. package/realtime-server/src/realtime-family-provider.ts +3 -3
  80. package/realtime-server/src/realtime-mutable-family-provider.ts +5 -5
  81. package/realtime-server/src/realtime-mutable-provider.ts +2 -2
  82. package/realtime-server/src/realtime-state-provider.ts +1 -1
  83. package/realtime-server/src/realtime-state-receiver.ts +1 -1
  84. package/realtime-testing/dist/index.js +7 -7
  85. package/realtime-testing/src/setup-realtime-test.tsx +7 -7
  86. package/src/atom.ts +2 -2
  87. package/src/dispose-state.ts +2 -2
  88. package/src/get-state.ts +9 -13
  89. package/src/logger.ts +4 -0
  90. package/src/molecule.ts +1 -1
  91. package/src/selector.ts +2 -2
  92. package/src/set-state.ts +10 -7
  93. package/src/silo.ts +23 -53
  94. package/src/subscribe.ts +3 -23
  95. package/src/timeline.ts +2 -2
  96. package/internal/src/families/throw-in-case-of-conflicting-family.ts +0 -18
@@ -10,7 +10,7 @@ export const readOrComputeValue = <T>(
10
10
  target.logger.info(`📖`, state.type, state.key, `reading cached value`)
11
11
  return readCachedValue(state, target)
12
12
  }
13
- if (state.type !== `atom` && state.type !== `mutable_atom`) {
13
+ if (state.type === `selector` || state.type === `readonly_selector`) {
14
14
  target.logger.info(`🧮`, state.type, state.key, `computing value`)
15
15
  return state.get()
16
16
  }
@@ -3,6 +3,7 @@ import type {
3
3
  FamilyMetadata,
4
4
  MutableAtomFamilyToken,
5
5
  MutableAtomToken,
6
+ ReadonlySelectorFamilyToken,
6
7
  ReadonlySelectorToken,
7
8
  RegularAtomFamilyToken,
8
9
  RegularAtomToken,
@@ -113,8 +114,9 @@ export type AtomFamily<T, K extends Canonical = Canonical> =
113
114
  // biome-ignore format: intersection
114
115
  export type WritableSelectorFamily<T, K extends Canonical> =
115
116
  & WritableSelectorFamilyToken<T, K>
117
+ & ((key: K) => WritableSelectorToken<T>)
116
118
  & {
117
- (key: K): WritableSelectorToken<T>
119
+ default: (key: K) => T,
118
120
  subject: Subject<StateCreation<WritableSelectorToken<T>> | StateDisposal<WritableSelectorToken<T>>>
119
121
  install: (store: Store) => void
120
122
  internalRoles : string[] | undefined
@@ -122,10 +124,10 @@ export type WritableSelectorFamily<T, K extends Canonical> =
122
124
 
123
125
  // biome-ignore format: intersection
124
126
  export type ReadonlySelectorFamily<T, K extends Canonical> =
127
+ & ReadonlySelectorFamilyToken<T, K>
125
128
  & ((key: K) => ReadonlySelectorToken<T>)
126
129
  & {
127
- key: string
128
- type: `readonly_selector_family`
130
+ default: (key: K) => T,
129
131
  subject: Subject<StateCreation<ReadonlySelectorToken<T>> | StateDisposal<ReadonlySelectorToken<T>>>
130
132
  install: (store: Store) => void
131
133
  internalRoles : string[] | undefined
@@ -14,5 +14,5 @@ export function ingestAtomUpdate(
14
14
  if (atomUpdate.family) {
15
15
  Object.assign(token, { family: atomUpdate.family })
16
16
  }
17
- setIntoStore(token, value, store)
17
+ setIntoStore(store, token, value)
18
18
  }
@@ -22,7 +22,7 @@ export function ingestCreationEvent(
22
22
  break
23
23
  }
24
24
  case `oldValue`: {
25
- disposeFromStore(update.token, store)
25
+ disposeFromStore(store, update.token)
26
26
  break
27
27
  }
28
28
  }
@@ -35,7 +35,7 @@ export function ingestDisposalEvent(
35
35
  ): void {
36
36
  switch (applying) {
37
37
  case `newValue`: {
38
- disposeFromStore(update.token, store)
38
+ disposeFromStore(store, update.token)
39
39
  break
40
40
  }
41
41
  case `oldValue`: {
@@ -58,7 +58,7 @@ function createInStore(token: ReadableToken<any>, store: Store): void {
58
58
  if (store.config.lifespan === `immortal`) {
59
59
  throw new Error(`No molecule found for key "${token.family.subKey}"`)
60
60
  }
61
- initFamilyMemberInStore(family, parseJson(token.family.subKey), store)
61
+ initFamilyMemberInStore(store, family, parseJson(token.family.subKey))
62
62
  }
63
63
  }
64
64
  }
@@ -79,7 +79,7 @@ export function ingestMoleculeCreationEvent(
79
79
  )
80
80
  break
81
81
  case `oldValue`:
82
- disposeFromStore(update.token, store)
82
+ disposeFromStore(store, update.token)
83
83
  break
84
84
  }
85
85
  }
@@ -90,7 +90,7 @@ export function ingestMoleculeDisposalEvent(
90
90
  ): void {
91
91
  switch (applying) {
92
92
  case `newValue`:
93
- disposeFromStore(update.token, store)
93
+ disposeFromStore(store, update.token)
94
94
  break
95
95
  case `oldValue`:
96
96
  {
@@ -10,8 +10,8 @@ import type { Store } from "../store"
10
10
  import { Subject } from "../subject"
11
11
 
12
12
  export function createMoleculeFamily<M extends MoleculeConstructor>(
13
- options: MoleculeFamilyOptions<M>,
14
13
  store: Store,
14
+ options: MoleculeFamilyOptions<M>,
15
15
  ): MoleculeFamilyToken<M> {
16
16
  const subject = new Subject<MoleculeCreation<M>>()
17
17
 
@@ -55,7 +55,7 @@ export function disposeMolecule<M extends MoleculeConstructor>(
55
55
  disposalEvent.family = token.family
56
56
  }
57
57
  for (const state of molecule.tokens.values()) {
58
- disposeFromStore(state, store)
58
+ disposeFromStore(store, state)
59
59
  }
60
60
  for (const child of molecule.below.values()) {
61
61
  if (child.family?.dependsOn === `all`) {
@@ -83,7 +83,7 @@ export function growMoleculeInStore(
83
83
  family: ReadableFamilyToken<any, any>,
84
84
  store: Store,
85
85
  ): ReadableToken<any> {
86
- const stateToken = initFamilyMemberInStore(family, molecule.key, store)
86
+ const stateToken = initFamilyMemberInStore(store, family, molecule.key)
87
87
  molecule.tokens.set(stateToken.key, stateToken)
88
88
  const isTransaction =
89
89
  isChildStore(store) && store.transactionMeta.phase === `building`
@@ -68,17 +68,17 @@ export function makeMoleculeInStore<M extends MoleculeConstructor>(
68
68
 
69
69
  const toolkit = {
70
70
  get: ((...ps: Parameters<typeof getState>) =>
71
- getFromStore(...ps, newest(rootStore))) as typeof getState,
71
+ getFromStore(newest(rootStore), ...ps)) as typeof getState,
72
72
  set: ((...ps: Parameters<typeof setState>) => {
73
- setIntoStore(...ps, newest(rootStore))
73
+ setIntoStore(newest(rootStore), ...ps)
74
74
  }) as typeof setState,
75
- seek: ((t, k) => seekInStore(t, k, newest(rootStore))) as typeof seekState,
76
- json: (t) => getJsonToken(t, newest(rootStore)),
75
+ seek: ((t, k) => seekInStore(newest(rootStore), t, k)) as typeof seekState,
76
+ json: (t) => getJsonToken(newest(rootStore), t),
77
77
  run: (t, i = arbitrary()) => actUponStore(t, i, newest(store)),
78
78
  make: (ctx, f, k, ...args) =>
79
79
  makeMoleculeInStore(newest(rootStore), ctx, f, k, ...args),
80
80
  dispose: (t) => {
81
- disposeFromStore(t, newest(rootStore))
81
+ disposeFromStore(newest(rootStore), t)
82
82
  },
83
83
  env: () => getEnvironmentData(newest(rootStore)),
84
84
  bond: ((
@@ -10,8 +10,7 @@ import type {
10
10
  import type { Json } from "atom.io/json"
11
11
  import { selectJsonFamily, stringifyJson } from "atom.io/json"
12
12
 
13
- import type { MutableAtomFamily } from ".."
14
- import { throwInCaseOfConflictingFamily } from "../families/throw-in-case-of-conflicting-family"
13
+ import { type MutableAtomFamily, prettyPrintTokenType } from ".."
15
14
  import { newest } from "../lineage"
16
15
  import { createMutableAtom } from "../mutable"
17
16
  import type { Store } from "../store"
@@ -24,8 +23,8 @@ export function createMutableAtomFamily<
24
23
  J extends Json.Serializable,
25
24
  K extends string,
26
25
  >(
27
- options: MutableAtomFamilyOptions<T, J, K>,
28
26
  store: Store,
27
+ options: MutableAtomFamilyOptions<T, J, K>,
29
28
  internalRoles?: string[],
30
29
  ): MutableAtomFamilyToken<T, J, K> {
31
30
  const familyToken = {
@@ -33,7 +32,17 @@ export function createMutableAtomFamily<
33
32
  type: `mutable_atom_family`,
34
33
  } as const satisfies MutableAtomFamilyToken<T, J, K>
35
34
 
36
- throwInCaseOfConflictingFamily(familyToken, store)
35
+ const existing = store.families.get(options.key)
36
+ if (existing) {
37
+ store.logger.error(
38
+ `❗`,
39
+ `mutable_atom_family`,
40
+ options.key,
41
+ `Overwriting an existing ${prettyPrintTokenType(
42
+ existing,
43
+ )} "${existing.key}" in store "${store.config.name}". You can safely ignore this warning if it is due to hot module replacement.`,
44
+ )
45
+ }
37
46
 
38
47
  const subject = new Subject<
39
48
  StateCreation<MutableAtomToken<T, J>> | StateDisposal<MutableAtomToken<T, J>>
@@ -56,7 +65,7 @@ export function createMutableAtomFamily<
56
65
  individualOptions.effects = options.effects(key)
57
66
  }
58
67
 
59
- const token = createMutableAtom(individualOptions, family, target)
68
+ const token = createMutableAtom(target, individualOptions, family)
60
69
 
61
70
  subject.next({ type: `state_creation`, token })
62
71
  return token
@@ -64,7 +73,7 @@ export function createMutableAtomFamily<
64
73
 
65
74
  const atomFamily = Object.assign(familyFunction, familyToken, {
66
75
  subject,
67
- install: (s: Store) => createMutableAtomFamily(options, s),
76
+ install: (s: Store) => createMutableAtomFamily(s, options),
68
77
  toJson: options.toJson,
69
78
  fromJson: options.fromJson,
70
79
  internalRoles,
@@ -20,9 +20,9 @@ export function createMutableAtom<
20
20
  T extends Transceiver<any>,
21
21
  J extends Json.Serializable,
22
22
  >(
23
+ store: Store,
23
24
  options: MutableAtomOptions<T, J>,
24
25
  family: FamilyMetadata | undefined,
25
- store: Store,
26
26
  ): MutableAtomToken<T, J> {
27
27
  store.logger.info(
28
28
  `🔨`,
@@ -52,7 +52,7 @@ export function createMutableAtom<
52
52
  options.key,
53
53
  `installing in store "${s.config.name}"`,
54
54
  )
55
- return createMutableAtom(options, family, s)
55
+ return createMutableAtom(s, options, family)
56
56
  },
57
57
  subject,
58
58
  } as const
@@ -70,7 +70,7 @@ export function createMutableAtom<
70
70
  for (const effect of options.effects) {
71
71
  const cleanup = effect({
72
72
  setSelf: (next) => {
73
- setIntoStore(token, next, store)
73
+ setIntoStore(store, token, next)
74
74
  },
75
75
  onSet: (handle: UpdateHandler<T>) =>
76
76
  subscribeToState(token, handle, `effect[${effectIndex}]`, store),
@@ -14,8 +14,8 @@ export const getJsonToken = <
14
14
  Core extends Transceiver<any>,
15
15
  SerializableCore extends Json.Serializable,
16
16
  >(
17
- mutableAtomToken: MutableAtomToken<Core, SerializableCore>,
18
17
  store: Store,
18
+ mutableAtomToken: MutableAtomToken<Core, SerializableCore>,
19
19
  ): WritableSelectorToken<SerializableCore> => {
20
20
  if (mutableAtomToken.family) {
21
21
  const target = newest(store)
@@ -29,7 +29,7 @@ export const getJsonToken = <
29
29
  }
30
30
  const family = withdraw(jsonFamilyToken, target)
31
31
  const subKey = JSON.parse(mutableAtomToken.family.subKey)
32
- const jsonToken = findInStore(family, subKey, store)
32
+ const jsonToken = findInStore(store, family, subKey)
33
33
  return jsonToken
34
34
  }
35
35
  const token: WritableSelectorToken<SerializableCore> = {
@@ -29,11 +29,11 @@ export class FamilyTracker<
29
29
  typeof this.Update | null,
30
30
  FamilyMemberKey
31
31
  >(
32
+ store,
32
33
  {
33
34
  key: `*${mutableAtoms.key}`,
34
35
  default: null,
35
36
  },
36
- store,
37
37
  [`mutable`, `updates`],
38
38
  )
39
39
  this.latestUpdateAtoms = withdraw(updateAtoms, store)
@@ -43,7 +43,7 @@ export class FamilyTracker<
43
43
  (event) => {
44
44
  if (event.token.family) {
45
45
  const key = parseJson(event.token.family.subKey) as FamilyMemberKey
46
- seekInStore(this.latestUpdateAtoms, key, store)
46
+ seekInStore(store, this.latestUpdateAtoms, key)
47
47
  new Tracker<Core>(event.token, store)
48
48
  }
49
49
  },
@@ -53,7 +53,7 @@ export class FamilyTracker<
53
53
  (event) => {
54
54
  if (event.token.family) {
55
55
  const key = parseJson(event.token.family.subKey) as FamilyMemberKey
56
- const mutableAtomToken = seekInStore(this.mutableAtoms, key, store)
56
+ const mutableAtomToken = seekInStore(store, this.mutableAtoms, key)
57
57
  if (mutableAtomToken) {
58
58
  new Tracker<Core>(mutableAtomToken, store)
59
59
  }
@@ -37,12 +37,12 @@ export class Tracker<Mutable extends Transceiver<any>> {
37
37
  const latestUpdateState = createRegularAtom<
38
38
  (Mutable extends Transceiver<infer Signal> ? Signal : never) | null
39
39
  >(
40
+ store,
40
41
  {
41
42
  key: latestUpdateStateKey,
42
43
  default: null,
43
44
  },
44
45
  familyMetaData,
45
- store,
46
46
  )
47
47
  if (store.parent?.valueMap.has(latestUpdateStateKey)) {
48
48
  const parentValue = store.parent.valueMap.get(latestUpdateStateKey)
@@ -62,11 +62,11 @@ export class Tracker<Mutable extends Transceiver<any>> {
62
62
  const subscriptionKey = `tracker:${target.config.name}:${
63
63
  isChildStore(target) ? target.transactionMeta.update.key : `main`
64
64
  }:${mutableState.key}`
65
- const originalInnerValue = getFromStore(mutableState, target)
65
+ const originalInnerValue = getFromStore(target, mutableState)
66
66
  this.unsubscribeFromInnerValue = originalInnerValue.subscribe(
67
67
  subscriptionKey,
68
68
  (update) => {
69
- setIntoStore(latestUpdateState, update, target)
69
+ setIntoStore(target, latestUpdateState, update)
70
70
  },
71
71
  )
72
72
  this.unsubscribeFromState = subscribeToState(
@@ -77,7 +77,7 @@ export class Tracker<Mutable extends Transceiver<any>> {
77
77
  this.unsubscribeFromInnerValue = update.newValue.subscribe(
78
78
  subscriptionKey,
79
79
  (transceiverUpdate) => {
80
- setIntoStore(latestUpdateState, transceiverUpdate, target)
80
+ setIntoStore(target, latestUpdateState, transceiverUpdate)
81
81
  },
82
82
  )
83
83
  }
@@ -109,18 +109,14 @@ export class Tracker<Mutable extends Transceiver<any>> {
109
109
  { key: timelineId, type: `timeline` },
110
110
  (update) => {
111
111
  unsubscribe()
112
- setIntoStore(
113
- mutableState,
114
- (transceiver) => {
115
- if (update === `redo` && newValue) {
116
- transceiver.do(newValue)
117
- } else if (update === `undo` && oldValue) {
118
- transceiver.undo(oldValue)
119
- }
120
- return transceiver
121
- },
122
- target,
123
- )
112
+ setIntoStore(target, mutableState, (transceiver) => {
113
+ if (update === `redo` && newValue) {
114
+ transceiver.do(newValue)
115
+ } else if (update === `undo` && oldValue) {
116
+ transceiver.undo(oldValue)
117
+ }
118
+ return transceiver
119
+ })
124
120
  },
125
121
  subscriptionKey,
126
122
  target,
@@ -133,15 +129,15 @@ export class Tracker<Mutable extends Transceiver<any>> {
133
129
  subscriptionKey,
134
130
  () => {
135
131
  unsubscribe()
136
- const mutable = getFromStore(mutableState, target)
132
+ const mutable = getFromStore(target, mutableState)
137
133
  const updateNumber =
138
134
  newValue === null ? -1 : mutable.getUpdateNumber(newValue)
139
135
  const eventOffset = updateNumber - mutable.cacheUpdateNumber
140
136
  if (newValue && eventOffset === 1) {
141
137
  setIntoStore(
138
+ target,
142
139
  mutableState,
143
140
  (transceiver) => (transceiver.do(newValue), transceiver),
144
- target,
145
141
  )
146
142
  } else {
147
143
  target.logger.info(
@@ -12,9 +12,9 @@ import { Subject } from "../subject"
12
12
  import { registerSelector } from "./register-selector"
13
13
 
14
14
  export const createReadonlySelector = <T>(
15
+ store: Store,
15
16
  options: ReadonlySelectorOptions<T>,
16
17
  family: FamilyMetadata | undefined,
17
- store: Store,
18
18
  ): ReadonlySelectorToken<T> => {
19
19
  const target = newest(store)
20
20
  const subject = new Subject<{ newValue: T; oldValue: T }>()
@@ -34,7 +34,7 @@ export const createReadonlySelector = <T>(
34
34
  const readonlySelector: ReadonlySelector<T> = {
35
35
  ...options,
36
36
  subject,
37
- install: (s: Store) => createReadonlySelector(options, family, s),
37
+ install: (s: Store) => createReadonlySelector(s, options, family),
38
38
  get: getSelf,
39
39
  type: `readonly_selector`,
40
40
  ...(family && { family }),
@@ -10,25 +10,25 @@ import { createReadonlySelector } from "./create-readonly-selector"
10
10
  import { createWritableSelector } from "./create-writable-selector"
11
11
 
12
12
  export function createStandaloneSelector<T>(
13
- options: WritableSelectorOptions<T>,
14
13
  store: Store,
14
+ options: WritableSelectorOptions<T>,
15
15
  ): WritableSelectorToken<T>
16
16
  export function createStandaloneSelector<T>(
17
- options: ReadonlySelectorOptions<T>,
18
17
  store: Store,
18
+ options: ReadonlySelectorOptions<T>,
19
19
  ): ReadonlySelectorToken<T>
20
20
  export function createStandaloneSelector<T>(
21
- options: ReadonlySelectorOptions<T> | WritableSelectorOptions<T>,
22
21
  store: Store,
22
+ options: ReadonlySelectorOptions<T> | WritableSelectorOptions<T>,
23
23
  ): ReadonlySelectorToken<T> | WritableSelectorToken<T> {
24
24
  const isWritable = `set` in options
25
25
 
26
26
  if (isWritable) {
27
- const state = createWritableSelector(options, undefined, store)
27
+ const state = createWritableSelector(store, options, undefined)
28
28
  store.on.selectorCreation.next(state)
29
29
  return state
30
30
  }
31
- const state = createReadonlySelector(options, undefined, store)
31
+ const state = createReadonlySelector(store, options, undefined)
32
32
  store.on.selectorCreation.next(state)
33
33
  return state
34
34
  }
@@ -15,19 +15,19 @@ import { isRootStore } from "../transaction"
15
15
  import { registerSelector } from "./register-selector"
16
16
 
17
17
  export const createWritableSelector = <T>(
18
+ store: Store,
18
19
  options: WritableSelectorOptions<T>,
19
20
  family: FamilyMetadata | undefined,
20
- store: Store,
21
21
  ): WritableSelectorToken<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 toolkit = registerSelector(options.key, covered, target)
26
- const { find, get, seek, json } = toolkit
25
+ const setterToolkit = registerSelector(options.key, covered, target)
26
+ const { find, get, seek, json } = setterToolkit
27
27
  const getterToolkit = { find, get, seek, json }
28
28
 
29
- const getSelf = (innerTarget = newest(store)): T => {
30
- const value = options.get(getterToolkit)
29
+ const getSelf = (getFn = options.get, innerTarget = newest(store)): T => {
30
+ const value = getFn(getterToolkit)
31
31
  cacheValue(options.key, value, subject, innerTarget)
32
32
  covered.clear()
33
33
  return value
@@ -35,7 +35,7 @@ export const createWritableSelector = <T>(
35
35
 
36
36
  const setSelf = (next: T | ((oldValue: T) => T)): void => {
37
37
  const innerTarget = newest(store)
38
- const oldValue = getSelf(innerTarget)
38
+ const oldValue = getSelf(options.get, innerTarget)
39
39
  const newValue = become(next)(oldValue)
40
40
  store.logger.info(
41
41
  `📝`,
@@ -52,12 +52,12 @@ export const createWritableSelector = <T>(
52
52
  if (isRootStore(innerTarget)) {
53
53
  subject.next({ newValue, oldValue })
54
54
  }
55
- options.set(toolkit, newValue)
55
+ options.set(setterToolkit, newValue)
56
56
  }
57
57
  const mySelector: WritableSelector<T> = {
58
58
  ...options,
59
59
  subject,
60
- install: (s: Store) => createWritableSelector(options, family, s),
60
+ install: (s: Store) => createWritableSelector(s, options, family),
61
61
  get: getSelf,
62
62
  set: setSelf,
63
63
  type: `selector`,
@@ -43,12 +43,12 @@ export const registerSelector = (
43
43
  const [family, key] = params
44
44
  switch (family.type) {
45
45
  case `molecule_family`:
46
- return getFromStore(family, key, store)
46
+ return getFromStore(store, family, key)
47
47
  default:
48
48
  if (store.config.lifespan === `ephemeral`) {
49
- dependency = findInStore(family, key, store)
49
+ dependency = findInStore(store, family, key)
50
50
  } else {
51
- const maybeDependency = seekInStore(family, key, store)
51
+ const maybeDependency = seekInStore(store, family, key)
52
52
  if (maybeDependency) {
53
53
  dependency = maybeDependency
54
54
  } else {
@@ -61,7 +61,7 @@ export const registerSelector = (
61
61
  }
62
62
 
63
63
  if (dependency.type === `molecule`) {
64
- return getFromStore(dependency, store)
64
+ return getFromStore(store, dependency)
65
65
  }
66
66
 
67
67
  const dependencyState = withdraw(dependency, store)
@@ -108,8 +108,8 @@ export const registerSelector = (
108
108
  value = params[2]
109
109
  const maybeToken =
110
110
  store.config.lifespan === `ephemeral`
111
- ? findInStore(family, key, store)
112
- : seekInStore(family, key, store)
111
+ ? findInStore(store, family, key)
112
+ : seekInStore(store, family, key)
113
113
  if (!maybeToken) {
114
114
  throw new NotFoundError(family, key, store)
115
115
  }
@@ -119,7 +119,7 @@ export const registerSelector = (
119
119
  const state = withdraw(token, target)
120
120
  setAtomOrSelector(state, value, target)
121
121
  }) as typeof setState,
122
- find: ((token, key) => findInStore(token, key, store)) as typeof findState,
123
- seek: ((token, key) => seekInStore(token, key, store)) as typeof seekState,
124
- json: (token) => getJsonToken(token, store),
122
+ find: ((token, key) => findInStore(store, token, key)) as typeof findState,
123
+ seek: ((token, key) => seekInStore(store, token, key)) as typeof seekState,
124
+ json: (token) => getJsonToken(store, token),
125
125
  })
@@ -1,58 +1,61 @@
1
1
  import type { WritableFamilyToken, WritableToken } from "atom.io"
2
- import type { Canonical } from "atom.io/json"
2
+ import { type Canonical, stringifyJson } from "atom.io/json"
3
3
 
4
4
  import { findInStore, seekInStore } from "../families"
5
- import { NotFoundError } from "../not-found-error"
6
5
  import { closeOperation, openOperation } from "../operation"
7
6
  import type { Store } from "../store"
8
7
  import { withdraw } from "../store"
9
8
  import { setAtomOrSelector } from "./set-atom-or-selector"
10
9
 
11
10
  export function setIntoStore<T, New extends T>(
11
+ store: Store,
12
12
  token: WritableToken<T>,
13
13
  value: New | ((oldValue: T) => New),
14
- store: Store,
15
14
  ): void
16
15
 
17
16
  export function setIntoStore<T, K extends Canonical, New extends T>(
17
+ store: Store,
18
18
  token: WritableFamilyToken<T, K>,
19
19
  key: K,
20
20
  value: New | ((oldValue: T) => New),
21
- store: Store,
22
21
  ): void
23
22
 
24
23
  export function setIntoStore<T, New extends T>(
24
+ store: Store,
25
25
  ...params:
26
26
  | [
27
27
  token: WritableFamilyToken<T, Canonical>,
28
28
  key: Canonical,
29
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
30
  ]
31
+ | [token: WritableToken<T>, value: New | ((oldValue: T) => New)]
37
32
  ): void {
38
33
  let token: WritableToken<T>
39
34
  let value: New | ((oldValue: T) => New)
40
- let store: Store
41
- if (params.length === 3) {
35
+ if (params.length === 2) {
42
36
  token = params[0]
43
37
  value = params[1]
44
- store = params[2]
45
38
  } else {
46
39
  const family = params[0]
47
40
  const key = params[1]
48
41
  value = params[2]
49
- store = params[3]
50
42
  const maybeToken =
51
43
  store.config.lifespan === `ephemeral`
52
- ? findInStore(family, key, store)
53
- : seekInStore(family, key, store)
44
+ ? findInStore(store, family, key)
45
+ : seekInStore(store, family, key)
54
46
  if (!maybeToken) {
55
- throw new NotFoundError(family, key, store)
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
56
59
  }
57
60
  token = maybeToken
58
61
  }
@@ -69,7 +72,7 @@ export function setIntoStore<T, New extends T>(
69
72
  token.key,
70
73
  `resuming deferred setState from T-${rejectionTime}`,
71
74
  )
72
- setIntoStore(token, value, store)
75
+ setIntoStore(store, token, value)
73
76
  },
74
77
  )
75
78
  return