atom.io 0.33.21 → 0.34.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 (28) hide show
  1. package/dist/internal/index.d.ts +5 -6
  2. package/dist/internal/index.d.ts.map +1 -1
  3. package/dist/internal/index.js +1252 -1247
  4. package/dist/internal/index.js.map +1 -1
  5. package/dist/realtime-client/index.js +2 -2
  6. package/dist/realtime-client/index.js.map +1 -1
  7. package/dist/realtime-testing/index.d.ts.map +1 -1
  8. package/dist/realtime-testing/index.js +0 -1
  9. package/dist/realtime-testing/index.js.map +1 -1
  10. package/package.json +1 -1
  11. package/src/internal/atom/create-regular-atom.ts +6 -7
  12. package/src/internal/caching.ts +9 -9
  13. package/src/internal/future.ts +3 -0
  14. package/src/internal/get-state/read-or-compute-value.ts +12 -7
  15. package/src/internal/mutable/create-mutable-atom.ts +2 -4
  16. package/src/internal/selector/create-readonly-held-selector.ts +10 -0
  17. package/src/internal/selector/create-readonly-pure-selector.ts +13 -4
  18. package/src/internal/selector/create-writable-held-selector.ts +11 -2
  19. package/src/internal/selector/create-writable-pure-selector.ts +11 -1
  20. package/src/internal/selector/trace-selector-atoms.ts +18 -40
  21. package/src/internal/selector/update-selector-atoms.ts +5 -5
  22. package/src/internal/set-state/evict-downstream.ts +2 -2
  23. package/src/internal/set-state/reset-atom-or-selector.ts +3 -3
  24. package/src/internal/store/store.ts +0 -1
  25. package/src/internal/subscribe/subscribe-to-root-atoms.ts +42 -38
  26. package/src/internal/subscribe/subscribe-to-state.ts +23 -11
  27. package/src/realtime-client/realtime-client-stores/client-sync-store.ts +2 -2
  28. package/src/realtime-testing/setup-realtime-test.tsx +0 -5
@@ -2,7 +2,7 @@ import type { ReadonlyPureSelectorToken, WritableToken } from "atom.io"
2
2
 
3
3
  import { newest } from "../lineage"
4
4
  import type { Store } from "../store"
5
- import { traceSelectorAtoms } from "./trace-selector-atoms"
5
+ import { traceRootSelectorAtoms } from "./trace-selector-atoms"
6
6
 
7
7
  export const updateSelectorAtoms = (
8
8
  store: Store,
@@ -29,16 +29,16 @@ export const updateSelectorAtoms = (
29
29
  `discovers root atom "${dependencyKey}"`,
30
30
  )
31
31
  } else {
32
- const rootKeys = traceSelectorAtoms(store, dependencyKey, covered)
32
+ const rootKeys = traceRootSelectorAtoms(store, dependencyKey, covered)
33
33
  store.logger.info(
34
34
  `🔍`,
35
35
  selectorType,
36
36
  selectorKey,
37
- `discovers root atoms: [ ${rootKeys
38
- .map((key) => `"${key}"`)
37
+ `discovers root atoms: [ ${[...rootKeys.values()]
38
+ .map((root) => `"${root.key}"`)
39
39
  .join(`, `)} ]`,
40
40
  )
41
- for (const atomKey of rootKeys) {
41
+ for (const { key: atomKey } of rootKeys.values()) {
42
42
  target.selectorAtoms = target.selectorAtoms.set({
43
43
  selectorKey,
44
44
  atomKey,
@@ -29,7 +29,7 @@ export function evictDownStream(store: Store, atom: Atom<any>): void {
29
29
  if (isDone(target, key)) {
30
30
  continue
31
31
  }
32
- evictCachedValue(key, target)
32
+ evictCachedValue(target, key)
33
33
  markDone(target, key)
34
34
  }
35
35
  }
@@ -49,7 +49,7 @@ export function evictDownStreamFromSelector(
49
49
  if (isDone(target, downstreamSelectorKey)) {
50
50
  continue
51
51
  }
52
- evictCachedValue(downstreamSelectorKey, target)
52
+ evictCachedValue(target, downstreamSelectorKey)
53
53
  markDone(target, downstreamSelectorKey)
54
54
  }
55
55
  }
@@ -1,5 +1,5 @@
1
1
  import type { Atom, WritableState } from ".."
2
- import { traceAllSelectorAtoms } from ".."
2
+ import { traceRootSelectorAtoms } from ".."
3
3
  import type { Store } from "../store"
4
4
  import { setAtom } from "./set-atom"
5
5
 
@@ -23,8 +23,8 @@ export function resetAtomOrSelector(
23
23
  case `writable_pure_selector`:
24
24
  case `writable_held_selector`:
25
25
  {
26
- const atoms = traceAllSelectorAtoms(state, store)
27
- for (const atom of atoms) {
26
+ const atoms = traceRootSelectorAtoms(store, state.key)
27
+ for (const atom of atoms.values()) {
28
28
  resetAtom(store, atom)
29
29
  }
30
30
  }
@@ -193,7 +193,6 @@ export class Store implements Lineage {
193
193
  ...config,
194
194
  }
195
195
  if (store !== null) {
196
- this.valueMap = new Map(store?.valueMap)
197
196
  this.operation = { ...store?.operation }
198
197
  if (isRootStore(store)) {
199
198
  this.transactionMeta = {
@@ -1,46 +1,50 @@
1
- import type { Selector } from ".."
1
+ import type { Atom, Selector } from ".."
2
2
  import { readOrComputeValue } from "../get-state/read-or-compute-value"
3
- import { newest } from "../lineage"
4
- import { traceAllSelectorAtoms } from "../selector"
5
3
  import type { Store } from "../store"
6
4
  import { recallState } from "./recall-state"
7
5
 
8
- export const subscribeToRootAtoms = <T>(
9
- store: Store,
10
- selector: Selector<T>,
11
- ): (() => void)[] => {
12
- const target = newest(store)
13
- const dependencySubscriptions = traceAllSelectorAtoms(selector, store).map(
14
- (atom) => {
15
- return atom.subject.subscribe(
16
- `${selector.type}:${selector.key}`,
17
- (atomChange) => {
18
- store.logger.info(
19
- `📢`,
20
- selector.type,
21
- selector.key,
22
- `root`,
23
- atom.key,
24
- `went`,
25
- atomChange.oldValue,
26
- `->`,
27
- atomChange.newValue,
28
- )
29
- const oldValue = recallState(target, selector)
30
- const newValue = readOrComputeValue(target, selector)
31
- store.logger.info(
32
- `✨`,
33
- selector.type,
34
- selector.key,
35
- `went`,
36
- oldValue,
37
- `->`,
38
- newValue,
39
- )
40
- selector.subject.next({ newValue, oldValue })
41
- },
6
+ export const subscribeToRootDependency = (
7
+ target: Store,
8
+ selector: Selector<any>,
9
+ atom: Atom<any>,
10
+ ): (() => void) => {
11
+ return atom.subject.subscribe(
12
+ `${selector.type}:${selector.key}`,
13
+ (atomChange) => {
14
+ target.logger.info(
15
+ `📢`,
16
+ selector.type,
17
+ selector.key,
18
+ `root`,
19
+ atom.key,
20
+ `went`,
21
+ atomChange.oldValue,
22
+ `->`,
23
+ atomChange.newValue,
42
24
  )
25
+ const oldValue = recallState(target, selector)
26
+ const newValue = readOrComputeValue(target, selector)
27
+ target.logger.info(
28
+ `✨`,
29
+ selector.type,
30
+ selector.key,
31
+ `went`,
32
+ oldValue,
33
+ `->`,
34
+ newValue,
35
+ )
36
+ selector.subject.next({ newValue, oldValue })
43
37
  },
44
38
  )
45
- return dependencySubscriptions
46
39
  }
40
+
41
+ // export const subscribeToRootAtoms = (
42
+ // store: Store,
43
+ // selector: Selector<any>,
44
+ // ): (() => void)[] => {
45
+ // const target = newest(store)
46
+ // const dependencySubscriptions = traceAllSelectorAtoms(selector, store).map(
47
+ // (atom) => subscribeToRootDependency(target, selector, atom),
48
+ // )
49
+ // return dependencySubscriptions
50
+ // }
@@ -1,8 +1,10 @@
1
1
  import type { ReadableToken, StateUpdate, UpdateHandler } from "atom.io"
2
2
 
3
+ import { readOrComputeValue } from "../get-state"
4
+ import { traceRootSelectorAtoms } from "../selector"
3
5
  import type { Store } from "../store"
4
6
  import { withdraw } from "../store"
5
- import { subscribeToRootAtoms } from "./subscribe-to-root-atoms"
7
+ import { subscribeToRootDependency } from "./subscribe-to-root-atoms"
6
8
 
7
9
  export function subscribeToState<T>(
8
10
  store: Store,
@@ -28,14 +30,26 @@ export function subscribeToState<T>(
28
30
  const isSelector =
29
31
  state.type === `writable_pure_selector` ||
30
32
  state.type === `readonly_pure_selector`
31
- let dependencyUnsubFunctions: (() => void)[] | null = null
33
+ const rootSubs = new Map<string, () => void>()
32
34
  let updateHandler: UpdateHandler<T> = safelyHandleUpdate
33
35
  if (isSelector) {
34
- dependencyUnsubFunctions = subscribeToRootAtoms(store, state)
35
- updateHandler = (update) => {
36
- if (dependencyUnsubFunctions) {
37
- dependencyUnsubFunctions.length = 0
38
- dependencyUnsubFunctions.push(...subscribeToRootAtoms(store, state))
36
+ readOrComputeValue(store, state)
37
+ for (const [atomKey, atom] of traceRootSelectorAtoms(store, state.key)) {
38
+ rootSubs.set(atomKey, subscribeToRootDependency(store, state, atom))
39
+ }
40
+ updateHandler = function updateRootsBeforeHandlingUpdate(update) {
41
+ const dependencies = traceRootSelectorAtoms(store, state.key)
42
+ for (const [previousRootKey, unsub] of rootSubs) {
43
+ const currentRoot = dependencies.get(previousRootKey)
44
+ if (currentRoot) {
45
+ dependencies.delete(previousRootKey)
46
+ } else {
47
+ unsub()
48
+ rootSubs.delete(previousRootKey)
49
+ }
50
+ }
51
+ for (const [atomKey, atom] of dependencies) {
52
+ rootSubs.set(atomKey, subscribeToRootDependency(store, state, atom))
39
53
  }
40
54
  safelyHandleUpdate(update)
41
55
  }
@@ -49,10 +63,8 @@ export function subscribeToState<T>(
49
63
  `Removing subscription "${key}"`,
50
64
  )
51
65
  mainUnsubFunction()
52
- if (dependencyUnsubFunctions) {
53
- for (const unsubFromDependency of dependencyUnsubFunctions) {
54
- unsubFromDependency()
55
- }
66
+ for (const unsubFromDependency of rootSubs.values()) {
67
+ unsubFromDependency()
56
68
  }
57
69
  }
58
70
 
@@ -4,12 +4,12 @@ export const optimisticUpdateQueue: AtomIO.RegularAtomToken<
4
4
  AtomIO.TransactionUpdate<any>[]
5
5
  > = AtomIO.atom<AtomIO.TransactionUpdate<any>[]>({
6
6
  key: `updateQueue`,
7
- default: [],
7
+ default: () => [],
8
8
  })
9
9
 
10
10
  export const confirmedUpdateQueue: AtomIO.RegularAtomToken<
11
11
  AtomIO.TransactionUpdate<any>[]
12
12
  > = AtomIO.atom<AtomIO.TransactionUpdate<any>[]>({
13
13
  key: `serverConfirmedUpdateQueue`,
14
- default: [],
14
+ default: () => [],
15
15
  })
@@ -192,11 +192,6 @@ export const setupRealtimeTestClient = (
192
192
  auth: { token: `test`, username: `${name}-${testNumber}` },
193
193
  })
194
194
  const silo = new AtomIO.Silo({ name, lifespan: `ephemeral` }, IMPLICIT.STORE)
195
- for (const [key, value] of silo.store.valueMap.entries()) {
196
- if (Array.isArray(value)) {
197
- silo.store.valueMap.set(key, [...value])
198
- }
199
- }
200
195
  silo.setState(RTC.myUsernameState, `${name}-${testNumber}`)
201
196
 
202
197
  const { document } = new Happy.Window()