atom.io 0.38.1 → 0.39.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 (60) hide show
  1. package/dist/internal/index.d.ts +115 -78
  2. package/dist/internal/index.d.ts.map +1 -1
  3. package/dist/internal/index.js +400 -276
  4. package/dist/internal/index.js.map +1 -1
  5. package/dist/main/index.d.ts +45 -35
  6. package/dist/main/index.d.ts.map +1 -1
  7. package/dist/main/index.js.map +1 -1
  8. package/dist/realtime-client/index.js +5 -5
  9. package/dist/realtime-client/index.js.map +1 -1
  10. package/dist/realtime-server/index.js +4 -4
  11. package/dist/realtime-server/index.js.map +1 -1
  12. package/package.json +10 -11
  13. package/src/internal/atom/create-regular-atom.ts +2 -6
  14. package/src/internal/caching.ts +2 -4
  15. package/src/internal/{ingest-updates → events}/ingest-atom-update.ts +4 -5
  16. package/src/internal/{ingest-updates → events}/ingest-creation-disposal.ts +37 -37
  17. package/src/internal/{ingest-updates → events}/ingest-selector-update.ts +5 -5
  18. package/src/internal/events/ingest-transaction-update.ts +45 -0
  19. package/src/internal/families/create-readonly-held-selector-family.ts +1 -1
  20. package/src/internal/families/create-readonly-pure-selector-family.ts +1 -1
  21. package/src/internal/families/create-regular-atom-family.ts +1 -1
  22. package/src/internal/families/create-writable-held-selector-family.ts +1 -1
  23. package/src/internal/families/create-writable-pure-selector-family.ts +1 -1
  24. package/src/internal/families/find-in-store.ts +2 -2
  25. package/src/internal/families/get-family-of-token.ts +1 -0
  26. package/src/internal/families/index.ts +0 -1
  27. package/src/internal/families/mint-in-store.ts +30 -64
  28. package/src/internal/get-state/get-from-store.ts +2 -3
  29. package/src/internal/get-state/read-or-compute-value.ts +4 -14
  30. package/src/internal/get-state/reduce-reference.ts +52 -11
  31. package/src/internal/index.ts +2 -2
  32. package/src/internal/junction.ts +177 -133
  33. package/src/internal/molecule.ts +3 -1
  34. package/src/internal/mutable/create-mutable-atom-family.ts +1 -1
  35. package/src/internal/overlays/index.ts +3 -0
  36. package/src/internal/overlays/map-overlay.ts +86 -0
  37. package/src/internal/{lazy-map.ts → overlays/relations-overlay.ts} +6 -6
  38. package/src/internal/overlays/set-overlay.ts +55 -0
  39. package/src/internal/selector/create-readonly-held-selector.ts +8 -11
  40. package/src/internal/selector/create-readonly-pure-selector.ts +8 -10
  41. package/src/internal/selector/create-writable-held-selector.ts +6 -6
  42. package/src/internal/selector/create-writable-pure-selector.ts +2 -2
  43. package/src/internal/selector/register-selector.ts +3 -4
  44. package/src/internal/set-state/dispatch-state-update.ts +45 -11
  45. package/src/internal/set-state/operate-on-store.ts +7 -7
  46. package/src/internal/set-state/set-atom.ts +1 -1
  47. package/src/internal/set-state/set-selector.ts +1 -1
  48. package/src/internal/store/withdraw.ts +4 -4
  49. package/src/internal/timeline/time-travel.ts +11 -11
  50. package/src/internal/transaction/apply-transaction.ts +5 -5
  51. package/src/internal/transaction/build-transaction.ts +17 -26
  52. package/src/internal/transaction/create-transaction.ts +1 -1
  53. package/src/internal/transaction/is-root-store.ts +2 -2
  54. package/src/main/events.ts +14 -3
  55. package/src/main/logger.ts +43 -32
  56. package/src/realtime-client/continuity/register-and-attempt-confirmed-update.ts +5 -5
  57. package/src/realtime-server/continuity/subscribe-to-continuity-perpectives.ts +4 -4
  58. package/src/internal/families/init-family-member.ts +0 -33
  59. package/src/internal/ingest-updates/ingest-transaction-update.ts +0 -47
  60. /package/src/internal/{ingest-updates → events}/index.ts +0 -0
@@ -0,0 +1,55 @@
1
+ export class SetOverlay<T> extends Set<T> {
2
+ public deleted: Set<T> = new Set()
3
+ public source: Set<T>
4
+
5
+ public constructor(source: Set<T>) {
6
+ super()
7
+ this.source = source
8
+ }
9
+
10
+ public add(value: T): this {
11
+ if (this.source.has(value)) {
12
+ this.deleted.delete(value)
13
+ return this
14
+ }
15
+ return super.add(value)
16
+ }
17
+
18
+ public hasOwn(member: T): boolean {
19
+ return super.has(member)
20
+ }
21
+
22
+ public has(key: T): boolean {
23
+ return !this.deleted.has(key) && (super.has(key) || this.source.has(key))
24
+ }
25
+
26
+ public delete(key: T): boolean {
27
+ if (this.source.has(key)) {
28
+ this.deleted.add(key)
29
+ return true
30
+ }
31
+ return super.delete(key)
32
+ }
33
+
34
+ public clear(): void {
35
+ this.deleted = new Set(this.source)
36
+ super.clear()
37
+ }
38
+
39
+ public *[Symbol.iterator](): SetIterator<T> {
40
+ yield* super[Symbol.iterator]()
41
+ for (const value of this.source) {
42
+ if (!this.deleted.has(value)) {
43
+ yield value
44
+ }
45
+ }
46
+ }
47
+
48
+ public *iterateOwn(): SetIterator<T> {
49
+ yield* super[Symbol.iterator]()
50
+ }
51
+
52
+ public get size(): number {
53
+ return super.size + this.source.size - this.deleted.size
54
+ }
55
+ }
@@ -21,6 +21,8 @@ export function createReadonlyHeldSelector<T extends object>(
21
21
  const covered = new Set<string>()
22
22
  const { key, const: constant } = options
23
23
  const type = `readonly_held_selector` as const
24
+ store.logger.info(`🔨`, type, key, `is being created`)
25
+
24
26
  const { get, find, json } = registerSelector(target, type, key, covered)
25
27
 
26
28
  const getFrom = (innerTarget: Store) => {
@@ -35,6 +37,7 @@ export function createReadonlyHeldSelector<T extends object>(
35
37
  innerTarget.selectorAtoms.delete(key)
36
38
  options.get({ get, find, json }, constant)
37
39
  writeToCache(innerTarget, readonlySelector, constant)
40
+ store.logger.info(`✨`, type, key, `=`, constant)
38
41
  covered.clear()
39
42
  return constant
40
43
  }
@@ -46,17 +49,11 @@ export function createReadonlyHeldSelector<T extends object>(
46
49
  getFrom,
47
50
  install: (s: Store) => createReadonlyHeldSelector(s, options, family),
48
51
  }
49
- if (family) {
50
- readonlySelector.family = family
51
- }
52
+ if (family) readonlySelector.family = family
53
+
52
54
  target.readonlySelectors.set(key, readonlySelector)
53
- store.logger.info(`✨`, type, key, `=`, constant)
54
- const token: ReadonlyHeldSelectorToken<T> = {
55
- key,
56
- type,
57
- }
58
- if (family) {
59
- token.family = family
60
- }
55
+ const token: ReadonlyHeldSelectorToken<T> = { key, type }
56
+ if (family) token.family = family
57
+
61
58
  return token
62
59
  }
@@ -21,6 +21,8 @@ export function createReadonlyPureSelector<T>(
21
21
  const covered = new Set<string>()
22
22
  const key = options.key
23
23
  const type = `readonly_pure_selector` as const
24
+ store.logger.info(`🔨`, type, key, `is being created`)
25
+
24
26
  const { get, find, json } = registerSelector(target, type, key, covered)
25
27
 
26
28
  const getFrom = () => {
@@ -48,16 +50,12 @@ export function createReadonlyPureSelector<T>(
48
50
  getFrom,
49
51
  install: (s: Store) => createReadonlyPureSelector(s, options, family),
50
52
  }
51
- if (family) {
52
- readonlySelector.family = family
53
- }
53
+ if (family) readonlySelector.family = family
54
+
54
55
  target.readonlySelectors.set(key, readonlySelector)
55
- const token: ReadonlyPureSelectorToken<T> = {
56
- key,
57
- type,
58
- }
59
- if (family) {
60
- token.family = family
61
- }
56
+
57
+ const token: ReadonlyPureSelectorToken<T> = { key, type }
58
+ if (family) token.family = family
59
+
62
60
  return token
63
61
  }
@@ -21,6 +21,8 @@ export function createWritableHeldSelector<T extends object>(
21
21
  const covered = new Set<string>()
22
22
  const { key, const: constant } = options
23
23
  const type = `writable_held_selector` as const
24
+ store.logger.info(`🔨`, type, key, `is being created`)
25
+
24
26
  const setterToolkit = registerSelector(target, type, key, covered)
25
27
  const { find, get, json } = setterToolkit
26
28
  const getterToolkit = { find, get, json }
@@ -54,14 +56,12 @@ export function createWritableHeldSelector<T extends object>(
54
56
  setSelf,
55
57
  install: (s: Store) => createWritableHeldSelector(s, options, family),
56
58
  }
57
- if (family) {
58
- mySelector.family = family
59
- }
59
+ if (family) mySelector.family = family
60
+
60
61
  target.writableSelectors.set(key, mySelector)
61
62
 
62
63
  const token: WritableHeldSelectorToken<T> = { key, type }
63
- if (family) {
64
- token.family = family
65
- }
64
+ if (family) token.family = family
65
+
66
66
  return token
67
67
  }
@@ -21,6 +21,8 @@ export function createWritablePureSelector<T>(
21
21
  const covered = new Set<string>()
22
22
  const key = options.key
23
23
  const type = `writable_pure_selector` as const
24
+ store.logger.info(`🔨`, type, key, `is being created`)
25
+
24
26
  const setterToolkit = registerSelector(target, type, key, covered)
25
27
  const { find, get, json } = setterToolkit
26
28
  const getterToolkit = { find, get, json }
@@ -57,8 +59,6 @@ export function createWritablePureSelector<T>(
57
59
  if (family) mySelector.family = family
58
60
 
59
61
  target.writableSelectors.set(key, mySelector)
60
- const initialValue = getFrom(target)
61
- store.logger.info(`✨`, mySelector.type, mySelector.key, `=`, initialValue)
62
62
 
63
63
  const token: WritablePureSelectorToken<T> = { key, type }
64
64
  if (family) token.family = family
@@ -37,11 +37,10 @@ export function registerSelector(
37
37
  | [ReadableToken<any>]
38
38
  ) => {
39
39
  const target = newest(store)
40
- const { token, familyToken, subKey } = reduceReference(store, ...params)
40
+ const { token, family, subKey } = reduceReference(store, ...params)
41
41
  let dependencyValue: unknown
42
- if (`counterfeit` in token && familyToken && subKey) {
43
- const dependencyFamily = withdraw(store, familyToken)
44
- dependencyValue = getFallback(store, token, dependencyFamily, subKey)
42
+ if (`counterfeit` in token && family && subKey) {
43
+ dependencyValue = getFallback(store, token, family, subKey)
45
44
  } else {
46
45
  const dependency = withdraw(store, token)
47
46
  dependencyValue = readOrComputeValue(store, dependency)
@@ -1,11 +1,12 @@
1
- import type {
2
- AtomToken,
3
- AtomUpdateEvent,
4
- StateUpdate,
5
- WritableToken,
6
- } from "atom.io"
1
+ import type { AtomUpdateEvent, StateCreationEvent, StateUpdate } from "atom.io"
7
2
 
8
- import type { MutableAtom, WritableState } from ".."
3
+ import {
4
+ type MutableAtom,
5
+ newest,
6
+ type Subject,
7
+ type WritableFamily,
8
+ type WritableState,
9
+ } from ".."
9
10
  import { hasRole } from "../atom"
10
11
  import { readOrComputeValue } from "../get-state"
11
12
  import type { Transceiver } from "../mutable"
@@ -19,8 +20,43 @@ export function dispatchOrDeferStateUpdate<T>(
19
20
  target: Store & { operation: OpenOperation<any> },
20
21
  state: WritableState<T>,
21
22
  [oldValue, newValue]: [T, T],
22
- _stateIsNewlyCreated: boolean,
23
+ stateIsNewlyCreated: boolean,
24
+ family?: WritableFamily<T, any>,
23
25
  ): void {
26
+ const token = deposit(state)
27
+ if (stateIsNewlyCreated && family) {
28
+ state.subject.next({ newValue })
29
+ const stateCreationEvent: StateCreationEvent<any> = {
30
+ type: `state_creation`,
31
+ subType: `writable`,
32
+ token,
33
+ timestamp: Date.now(),
34
+ value: newValue,
35
+ }
36
+ const familySubject = family.subject as Subject<StateCreationEvent<any>>
37
+ familySubject.next(stateCreationEvent)
38
+ const innerTarget = newest(target)
39
+ if (token.family) {
40
+ if (isRootStore(innerTarget)) {
41
+ switch (token.type) {
42
+ case `atom`:
43
+ case `mutable_atom`:
44
+ target.on.atomCreation.next(token)
45
+ break
46
+ case `writable_pure_selector`:
47
+ case `writable_held_selector`:
48
+ target.on.selectorCreation.next(token)
49
+ break
50
+ }
51
+ } else if (
52
+ isChildStore(innerTarget) &&
53
+ innerTarget.on.transactionApplying.state === null
54
+ ) {
55
+ innerTarget.transactionMeta.update.subEvents.push(stateCreationEvent)
56
+ }
57
+ }
58
+ return /* bailing early here to avoid redundant update */
59
+ }
24
60
  const { key, subject, type } = state
25
61
 
26
62
  const update: StateUpdate<T> = {
@@ -61,13 +97,11 @@ export function dispatchOrDeferStateUpdate<T>(
61
97
 
62
98
  if (isChildStore(target) && (type === `mutable_atom` || type === `atom`)) {
63
99
  if (target.on.transactionApplying.state === null) {
64
- const token: WritableToken<T> = deposit(state)
65
-
66
100
  if (isTransceiver(newValue)) {
67
101
  return
68
102
  }
69
103
  const { timestamp } = target.operation
70
- const atomUpdate: AtomUpdateEvent<AtomToken<T>> = {
104
+ const atomUpdate: AtomUpdateEvent<any> = {
71
105
  type: `atom_update`,
72
106
  token,
73
107
  timestamp,
@@ -1,6 +1,7 @@
1
1
  import type { WritableFamilyToken, WritableToken } from "atom.io"
2
2
  import { type Canonical, parseJson } from "atom.io/json"
3
3
 
4
+ import type { WritableFamily } from ".."
4
5
  import { seekInStore } from "../families"
5
6
  import { getFamilyOfToken } from "../families/get-family-of-token"
6
7
  import { mintInStore, MUST_CREATE } from "../families/mint-in-store"
@@ -32,7 +33,7 @@ export function operateOnStore<T, New extends T>(
32
33
  let existingToken: WritableToken<T> | undefined
33
34
  let brandNewToken: WritableToken<T> | undefined
34
35
  let token: WritableToken<T>
35
- let family: WritableFamilyToken<T, Canonical> | null
36
+ let family: WritableFamily<T, Canonical> | undefined
36
37
  let key: Canonical | null
37
38
  let value: New | typeof RESET_STATE | ((oldValue: T) => New)
38
39
  if (params.length === 2) {
@@ -43,20 +44,18 @@ export function operateOnStore<T, New extends T>(
43
44
  key = parseJson(token.family.subKey)
44
45
  existingToken = seekInStore(store, family, key)
45
46
  if (!existingToken) {
46
- brandNewToken = mintInStore(store, family, key, MUST_CREATE)
47
- token = brandNewToken
47
+ token = brandNewToken = mintInStore(store, family, key, MUST_CREATE)
48
48
  } else {
49
49
  token = existingToken
50
50
  }
51
51
  }
52
52
  } else {
53
- family = params[0]
53
+ family = withdraw(store, params[0])
54
54
  key = params[1]
55
55
  value = params[2]
56
56
  existingToken = seekInStore(store, family, key)
57
57
  if (!existingToken) {
58
- brandNewToken = mintInStore(store, family, key, MUST_CREATE)
59
- token = brandNewToken
58
+ token = brandNewToken = mintInStore(store, family, key, MUST_CREATE)
60
59
  } else {
61
60
  token = existingToken
62
61
  }
@@ -121,8 +120,9 @@ export function operateOnStore<T, New extends T>(
121
120
  } else {
122
121
  protoUpdate = setAtomOrSelector(target, state, value)
123
122
  }
123
+
124
124
  const isNewlyCreated = Boolean(brandNewToken)
125
- dispatchOrDeferStateUpdate(target, state, protoUpdate, isNewlyCreated)
125
+ dispatchOrDeferStateUpdate(target, state, protoUpdate, isNewlyCreated, family)
126
126
 
127
127
  if (opMode === OWN_OP) {
128
128
  closeOperation(target)
@@ -12,7 +12,7 @@ export const setAtom = <T>(
12
12
  ): [oldValue: T, newValue: T] => {
13
13
  const oldValue = readOrComputeValue(target, atom, `mut`)
14
14
  let newValue = become(next)(oldValue)
15
- target.logger.info(`📝`, `atom`, atom.key, `set to`, newValue)
15
+ target.logger.info(`⭐`, `atom`, atom.key, `setting value`, newValue)
16
16
  newValue = writeToCache(target, atom, newValue)
17
17
  markDone(target, atom.key)
18
18
  evictDownstreamFromAtom(target, atom)
@@ -28,7 +28,7 @@ export function setSelector<T>(
28
28
  newValue = constant
29
29
  }
30
30
 
31
- target.logger.info(`📝`, type, key, `setting to`, newValue)
31
+ target.logger.info(`⭐`, type, key, `setting to`, newValue)
32
32
  markDone(target, key)
33
33
  selector.setSelf(newValue)
34
34
  return [oldValue, newValue]
@@ -171,14 +171,14 @@ export function withdraw<T, K extends Canonical>(
171
171
  store: Store,
172
172
  token: SelectorFamilyToken<T, K>,
173
173
  ): SelectorFamily<T, K>
174
- export function withdraw<T, K extends Canonical>(
175
- store: Store,
176
- token: ReadableFamilyToken<T, K>,
177
- ): ReadableFamily<T, K>
178
174
  export function withdraw<T, K extends Canonical>(
179
175
  store: Store,
180
176
  token: WritableFamilyToken<T, K>,
181
177
  ): WritableFamily<T, K>
178
+ export function withdraw<T, K extends Canonical>(
179
+ store: Store,
180
+ token: ReadableFamilyToken<T, K>,
181
+ ): ReadableFamily<T, K>
182
182
 
183
183
  export function withdraw<T extends Fn>(
184
184
  store: Store,
@@ -1,12 +1,12 @@
1
1
  import type { TimelineToken } from "atom.io"
2
2
 
3
3
  import {
4
- ingestAtomUpdate,
4
+ ingestAtomUpdateEvent,
5
5
  ingestCreationEvent,
6
6
  ingestDisposalEvent,
7
- ingestSelectorUpdate,
8
- ingestTransactionUpdate,
9
- } from "../ingest-updates"
7
+ ingestSelectorUpdateEvent,
8
+ ingestTransactionOutcomeEvent,
9
+ } from "../events"
10
10
  import type { Store } from "../store"
11
11
 
12
12
  export const timeTravel = (
@@ -50,28 +50,28 @@ export const timeTravel = (
50
50
  --timelineData.at
51
51
  }
52
52
 
53
- const update = timelineData.history[timelineData.at]
53
+ const event = timelineData.history[timelineData.at]
54
54
  const applying = action === `redo` ? `newValue` : `oldValue`
55
55
 
56
- switch (update.type) {
56
+ switch (event.type) {
57
57
  case `atom_update`: {
58
- ingestAtomUpdate(applying, update, store)
58
+ ingestAtomUpdateEvent(store, event, applying)
59
59
  break
60
60
  }
61
61
  case `selector_update`: {
62
- ingestSelectorUpdate(applying, update, store)
62
+ ingestSelectorUpdateEvent(store, event, applying)
63
63
  break
64
64
  }
65
65
  case `transaction_outcome`: {
66
- ingestTransactionUpdate(applying, update, store)
66
+ ingestTransactionOutcomeEvent(store, event, applying)
67
67
  break
68
68
  }
69
69
  case `state_creation`: {
70
- ingestCreationEvent(update, applying, store)
70
+ ingestCreationEvent(store, event, applying)
71
71
  break
72
72
  }
73
73
  case `state_disposal`: {
74
- ingestDisposalEvent(update, applying, store)
74
+ ingestDisposalEvent(store, event, applying)
75
75
  break
76
76
  }
77
77
  case `molecule_creation`:
@@ -1,4 +1,4 @@
1
- import { ingestTransactionUpdate } from "../ingest-updates"
1
+ import { ingestTransactionOutcomeEvent } from "../events"
2
2
  import { newest } from "../lineage"
3
3
  import type { Store } from "../store"
4
4
  import { withdraw } from "../store"
@@ -6,10 +6,10 @@ import type { Fn } from "../utility-types"
6
6
  import { isChildStore, isRootStore } from "./is-root-store"
7
7
  import { setEpochNumberOfAction } from "./set-epoch-number"
8
8
 
9
- export const applyTransaction = <F extends Fn>(
10
- output: ReturnType<F>,
9
+ export function applyTransaction<F extends Fn>(
11
10
  store: Store,
12
- ): void => {
11
+ output: ReturnType<F>,
12
+ ): void {
13
13
  const child = newest(store)
14
14
  const { parent } = child
15
15
  if (
@@ -38,7 +38,7 @@ export const applyTransaction = <F extends Fn>(
38
38
  updates,
39
39
  )
40
40
 
41
- ingestTransactionUpdate(`newValue`, child.transactionMeta.update, parent)
41
+ ingestTransactionOutcomeEvent(parent, child.transactionMeta.update, `newValue`)
42
42
 
43
43
  if (isRootStore(parent)) {
44
44
  setEpochNumberOfAction(
@@ -11,10 +11,9 @@ import { arbitrary } from "../arbitrary"
11
11
  import { disposeFromStore, findInStore } from "../families"
12
12
  import { getEnvironmentData } from "../get-environment-data"
13
13
  import { getFromStore } from "../get-state"
14
- import { Junction } from "../junction"
15
- import { LazyMap } from "../lazy-map"
16
14
  import { newest } from "../lineage"
17
15
  import { getJsonToken } from "../mutable"
16
+ import { MapOverlay } from "../overlays/map-overlay"
18
17
  import { resetInStore, setIntoStore } from "../set-state"
19
18
  import type { Store } from "../store"
20
19
  import type { Fn } from "../utility-types"
@@ -36,35 +35,27 @@ export const buildTransaction = (
36
35
  loggers: parent.loggers,
37
36
  logger: parent.logger,
38
37
  config: parent.config,
39
- atoms: new LazyMap(parent.atoms),
38
+ atoms: new MapOverlay(parent.atoms),
40
39
  atomsThatAreDefault: new Set(parent.atomsThatAreDefault),
41
- families: new LazyMap(parent.families),
42
- joins: new LazyMap(parent.joins),
40
+ families: new MapOverlay(parent.families),
41
+ joins: new MapOverlay(parent.joins),
43
42
  operation: { open: false },
44
- readonlySelectors: new LazyMap(parent.readonlySelectors),
45
- timelines: new LazyMap(parent.timelines),
46
- timelineTopics: new Junction(parent.timelineTopics.toJSON()),
43
+ readonlySelectors: new MapOverlay(parent.readonlySelectors),
44
+ timelines: new MapOverlay(parent.timelines),
45
+ timelineTopics: parent.timelineTopics.overlay(),
47
46
  trackers: new Map(),
48
- transactions: new LazyMap(parent.transactions),
49
- selectorAtoms: new Junction(parent.selectorAtoms.toJSON()),
50
- selectorGraph: new Junction(parent.selectorGraph.toJSON(), {
51
- makeContentKey: (...keys) => keys.sort().join(`:`),
52
- }),
53
- writableSelectors: new LazyMap(parent.writableSelectors),
54
- valueMap: new LazyMap(parent.valueMap),
47
+ transactions: new MapOverlay(parent.transactions),
48
+ selectorAtoms: parent.selectorAtoms.overlay(),
49
+ selectorGraph: parent.selectorGraph.overlay(),
50
+ writableSelectors: new MapOverlay(parent.writableSelectors),
51
+ valueMap: new MapOverlay(parent.valueMap),
55
52
  defaults: parent.defaults,
56
53
  disposalTraces: store.disposalTraces.copy(),
57
- molecules: new LazyMap(parent.molecules),
58
- moleculeGraph: new Junction(parent.moleculeGraph.toJSON(), {
59
- makeContentKey: parent.moleculeGraph.makeContentKey,
60
- }),
61
- moleculeData: new Junction(parent.moleculeData.toJSON(), {
62
- makeContentKey: parent.moleculeData.makeContentKey,
63
- }),
64
- moleculeJoins: new Junction(parent.moleculeJoins.toJSON(), {
65
- makeContentKey: parent.moleculeJoins.makeContentKey,
66
- }),
67
- miscResources: new LazyMap(parent.miscResources),
54
+ molecules: new MapOverlay(parent.molecules),
55
+ moleculeGraph: parent.moleculeGraph.overlay(),
56
+ moleculeData: parent.moleculeData.overlay(),
57
+ moleculeJoins: parent.moleculeJoins.overlay(),
58
+ miscResources: new MapOverlay(parent.miscResources),
68
59
  }
69
60
  const epoch = getEpochNumberOfAction(store, token.key)
70
61
  const transactionMeta: TransactionProgress<Fn> = {
@@ -37,7 +37,7 @@ export function createTransaction<F extends Fn>(
37
37
  const target = newest(store)
38
38
  const { toolkit } = childStore.transactionMeta
39
39
  const output = options.do(toolkit, ...params)
40
- applyTransaction(output, target)
40
+ applyTransaction<F>(target, output)
41
41
  return output
42
42
  } catch (thrown) {
43
43
  abortTransaction(target)
@@ -1,4 +1,4 @@
1
- import type { LazyMap } from "../lazy-map"
1
+ import type { MapOverlay } from "../overlays/map-overlay"
2
2
  import type { Store } from "../store"
3
3
  import type { Fn } from "../utility-types"
4
4
  import type { TransactionEpoch, TransactionProgress } from "."
@@ -12,7 +12,7 @@ export interface ChildStore extends Store {
12
12
  transactionMeta: TransactionProgress<Fn>
13
13
  parent: ChildStore | RootStore
14
14
  child: ChildStore | null
15
- valueMap: LazyMap<string, any>
15
+ valueMap: MapOverlay<string, any>
16
16
  }
17
17
 
18
18
  export function isRootStore(store: Store): store is RootStore {
@@ -7,11 +7,12 @@ import type {
7
7
  ReadableToken,
8
8
  SelectorToken,
9
9
  TransactionToken,
10
+ WritableToken,
10
11
  } from "./tokens"
11
12
  import type { TokenType } from "./validators"
12
13
 
13
14
  export type StateUpdate<T> = {
14
- readonly oldValue: ViewOf<T>
15
+ readonly oldValue?: ViewOf<T>
15
16
  readonly newValue: ViewOf<T>
16
17
  }
17
18
 
@@ -32,15 +33,25 @@ export type TimelineSelectorUpdateEvent<A extends TimelineManageable> = {
32
33
  export type StateLifecycleEvent<R extends ReadableToken<any>> =
33
34
  | StateCreationEvent<R>
34
35
  | StateDisposalEvent<R>
35
- export type StateCreationEvent<R extends ReadableToken<any>> = {
36
+ export type StateCreationEvent<R extends ReadableToken<any>> =
37
+ | ReadableStateCreationEvent<R>
38
+ | (R extends WritableToken<any> ? WritableStateCreationEvent<R> : never)
39
+ export type ReadableStateCreationEvent<R extends ReadableToken<any>> = {
36
40
  type: `state_creation`
41
+ subType: `readable`
37
42
  token: R
38
43
  timestamp: number
39
44
  }
45
+ export type WritableStateCreationEvent<W extends WritableToken<any>> = {
46
+ type: `state_creation`
47
+ subType: `writable`
48
+ token: W
49
+ timestamp: number
50
+ value?: TokenType<W>
51
+ }
40
52
  export type StateDisposalEvent<R extends ReadableToken<any>> =
41
53
  | AtomDisposalEvent<R>
42
54
  | SelectorDisposalEvent<R>
43
-
44
55
  export type AtomDisposalEvent<R extends ReadableToken<any>> = {
45
56
  type: `state_disposal`
46
57
  subType: `atom`