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.
- package/dist/internal/index.d.ts +115 -78
- package/dist/internal/index.d.ts.map +1 -1
- package/dist/internal/index.js +400 -276
- package/dist/internal/index.js.map +1 -1
- package/dist/main/index.d.ts +45 -35
- package/dist/main/index.d.ts.map +1 -1
- package/dist/main/index.js.map +1 -1
- package/dist/realtime-client/index.js +5 -5
- package/dist/realtime-client/index.js.map +1 -1
- package/dist/realtime-server/index.js +4 -4
- package/dist/realtime-server/index.js.map +1 -1
- package/package.json +10 -11
- package/src/internal/atom/create-regular-atom.ts +2 -6
- package/src/internal/caching.ts +2 -4
- package/src/internal/{ingest-updates → events}/ingest-atom-update.ts +4 -5
- package/src/internal/{ingest-updates → events}/ingest-creation-disposal.ts +37 -37
- package/src/internal/{ingest-updates → events}/ingest-selector-update.ts +5 -5
- package/src/internal/events/ingest-transaction-update.ts +45 -0
- package/src/internal/families/create-readonly-held-selector-family.ts +1 -1
- package/src/internal/families/create-readonly-pure-selector-family.ts +1 -1
- package/src/internal/families/create-regular-atom-family.ts +1 -1
- package/src/internal/families/create-writable-held-selector-family.ts +1 -1
- package/src/internal/families/create-writable-pure-selector-family.ts +1 -1
- package/src/internal/families/find-in-store.ts +2 -2
- package/src/internal/families/get-family-of-token.ts +1 -0
- package/src/internal/families/index.ts +0 -1
- package/src/internal/families/mint-in-store.ts +30 -64
- package/src/internal/get-state/get-from-store.ts +2 -3
- package/src/internal/get-state/read-or-compute-value.ts +4 -14
- package/src/internal/get-state/reduce-reference.ts +52 -11
- package/src/internal/index.ts +2 -2
- package/src/internal/junction.ts +177 -133
- package/src/internal/molecule.ts +3 -1
- package/src/internal/mutable/create-mutable-atom-family.ts +1 -1
- package/src/internal/overlays/index.ts +3 -0
- package/src/internal/overlays/map-overlay.ts +86 -0
- package/src/internal/{lazy-map.ts → overlays/relations-overlay.ts} +6 -6
- package/src/internal/overlays/set-overlay.ts +55 -0
- package/src/internal/selector/create-readonly-held-selector.ts +8 -11
- package/src/internal/selector/create-readonly-pure-selector.ts +8 -10
- package/src/internal/selector/create-writable-held-selector.ts +6 -6
- package/src/internal/selector/create-writable-pure-selector.ts +2 -2
- package/src/internal/selector/register-selector.ts +3 -4
- package/src/internal/set-state/dispatch-state-update.ts +45 -11
- package/src/internal/set-state/operate-on-store.ts +7 -7
- package/src/internal/set-state/set-atom.ts +1 -1
- package/src/internal/set-state/set-selector.ts +1 -1
- package/src/internal/store/withdraw.ts +4 -4
- package/src/internal/timeline/time-travel.ts +11 -11
- package/src/internal/transaction/apply-transaction.ts +5 -5
- package/src/internal/transaction/build-transaction.ts +17 -26
- package/src/internal/transaction/create-transaction.ts +1 -1
- package/src/internal/transaction/is-root-store.ts +2 -2
- package/src/main/events.ts +14 -3
- package/src/main/logger.ts +43 -32
- package/src/realtime-client/continuity/register-and-attempt-confirmed-update.ts +5 -5
- package/src/realtime-server/continuity/subscribe-to-continuity-perpectives.ts +4 -4
- package/src/internal/families/init-family-member.ts +0 -33
- package/src/internal/ingest-updates/ingest-transaction-update.ts +0 -47
- /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
|
-
|
|
51
|
-
}
|
|
52
|
+
if (family) readonlySelector.family = family
|
|
53
|
+
|
|
52
54
|
target.readonlySelectors.set(key, readonlySelector)
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
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
|
-
|
|
53
|
-
}
|
|
53
|
+
if (family) readonlySelector.family = family
|
|
54
|
+
|
|
54
55
|
target.readonlySelectors.set(key, readonlySelector)
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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,
|
|
40
|
+
const { token, family, subKey } = reduceReference(store, ...params)
|
|
41
41
|
let dependencyValue: unknown
|
|
42
|
-
if (`counterfeit` in token &&
|
|
43
|
-
|
|
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
|
|
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
|
-
|
|
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<
|
|
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:
|
|
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(
|
|
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(
|
|
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
|
-
|
|
4
|
+
ingestAtomUpdateEvent,
|
|
5
5
|
ingestCreationEvent,
|
|
6
6
|
ingestDisposalEvent,
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
} from "../
|
|
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
|
|
53
|
+
const event = timelineData.history[timelineData.at]
|
|
54
54
|
const applying = action === `redo` ? `newValue` : `oldValue`
|
|
55
55
|
|
|
56
|
-
switch (
|
|
56
|
+
switch (event.type) {
|
|
57
57
|
case `atom_update`: {
|
|
58
|
-
|
|
58
|
+
ingestAtomUpdateEvent(store, event, applying)
|
|
59
59
|
break
|
|
60
60
|
}
|
|
61
61
|
case `selector_update`: {
|
|
62
|
-
|
|
62
|
+
ingestSelectorUpdateEvent(store, event, applying)
|
|
63
63
|
break
|
|
64
64
|
}
|
|
65
65
|
case `transaction_outcome`: {
|
|
66
|
-
|
|
66
|
+
ingestTransactionOutcomeEvent(store, event, applying)
|
|
67
67
|
break
|
|
68
68
|
}
|
|
69
69
|
case `state_creation`: {
|
|
70
|
-
ingestCreationEvent(
|
|
70
|
+
ingestCreationEvent(store, event, applying)
|
|
71
71
|
break
|
|
72
72
|
}
|
|
73
73
|
case `state_disposal`: {
|
|
74
|
-
ingestDisposalEvent(
|
|
74
|
+
ingestDisposalEvent(store, event, applying)
|
|
75
75
|
break
|
|
76
76
|
}
|
|
77
77
|
case `molecule_creation`:
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
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
|
|
10
|
-
output: ReturnType<F>,
|
|
9
|
+
export function applyTransaction<F extends Fn>(
|
|
11
10
|
store: Store,
|
|
12
|
-
|
|
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
|
-
|
|
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
|
|
38
|
+
atoms: new MapOverlay(parent.atoms),
|
|
40
39
|
atomsThatAreDefault: new Set(parent.atomsThatAreDefault),
|
|
41
|
-
families: new
|
|
42
|
-
joins: new
|
|
40
|
+
families: new MapOverlay(parent.families),
|
|
41
|
+
joins: new MapOverlay(parent.joins),
|
|
43
42
|
operation: { open: false },
|
|
44
|
-
readonlySelectors: new
|
|
45
|
-
timelines: new
|
|
46
|
-
timelineTopics:
|
|
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
|
|
49
|
-
selectorAtoms:
|
|
50
|
-
selectorGraph:
|
|
51
|
-
|
|
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
|
|
58
|
-
moleculeGraph:
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
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(
|
|
40
|
+
applyTransaction<F>(target, output)
|
|
41
41
|
return output
|
|
42
42
|
} catch (thrown) {
|
|
43
43
|
abortTransaction(target)
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
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:
|
|
15
|
+
valueMap: MapOverlay<string, any>
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
export function isRootStore(store: Store): store is RootStore {
|
package/src/main/events.ts
CHANGED
|
@@ -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
|
|
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`
|