@livestore/common 0.3.0-dev.47 → 0.3.0-dev.48

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 (154) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/adapter-types.d.ts +8 -6
  3. package/dist/adapter-types.d.ts.map +1 -1
  4. package/dist/adapter-types.js +2 -2
  5. package/dist/adapter-types.js.map +1 -1
  6. package/dist/devtools/devtools-messages-client-session.d.ts +25 -25
  7. package/dist/devtools/devtools-messages-client-session.js +3 -3
  8. package/dist/devtools/devtools-messages-client-session.js.map +1 -1
  9. package/dist/devtools/devtools-messages-common.d.ts +6 -6
  10. package/dist/devtools/devtools-messages-leader.d.ts +30 -30
  11. package/dist/devtools/devtools-messages-leader.js +3 -3
  12. package/dist/devtools/devtools-messages-leader.js.map +1 -1
  13. package/dist/leader-thread/LeaderSyncProcessor.d.ts.map +1 -1
  14. package/dist/leader-thread/LeaderSyncProcessor.js +27 -25
  15. package/dist/leader-thread/LeaderSyncProcessor.js.map +1 -1
  16. package/dist/leader-thread/eventlog.d.ts +10 -10
  17. package/dist/leader-thread/eventlog.d.ts.map +1 -1
  18. package/dist/leader-thread/eventlog.js +24 -24
  19. package/dist/leader-thread/eventlog.js.map +1 -1
  20. package/dist/leader-thread/leader-worker-devtools.js +1 -1
  21. package/dist/leader-thread/leader-worker-devtools.js.map +1 -1
  22. package/dist/leader-thread/materialize-event.d.ts +3 -3
  23. package/dist/leader-thread/materialize-event.d.ts.map +1 -1
  24. package/dist/leader-thread/materialize-event.js +19 -15
  25. package/dist/leader-thread/materialize-event.js.map +1 -1
  26. package/dist/leader-thread/types.d.ts +4 -4
  27. package/dist/leader-thread/types.d.ts.map +1 -1
  28. package/dist/make-client-session.d.ts +1 -1
  29. package/dist/make-client-session.d.ts.map +1 -1
  30. package/dist/make-client-session.js +2 -1
  31. package/dist/make-client-session.js.map +1 -1
  32. package/dist/materializer-helper.d.ts.map +1 -1
  33. package/dist/materializer-helper.js +4 -2
  34. package/dist/materializer-helper.js.map +1 -1
  35. package/dist/rematerialize-from-eventlog.js +9 -9
  36. package/dist/rematerialize-from-eventlog.js.map +1 -1
  37. package/dist/schema/EventId.d.ts +28 -28
  38. package/dist/schema/EventId.d.ts.map +1 -1
  39. package/dist/schema/EventId.js +9 -9
  40. package/dist/schema/EventId.js.map +1 -1
  41. package/dist/schema/EventId.test.js +5 -5
  42. package/dist/schema/EventId.test.js.map +1 -1
  43. package/dist/schema/EventNumber.d.ts +57 -0
  44. package/dist/schema/EventNumber.d.ts.map +1 -0
  45. package/dist/schema/EventNumber.js +82 -0
  46. package/dist/schema/EventNumber.js.map +1 -0
  47. package/dist/schema/EventNumber.test.d.ts +2 -0
  48. package/dist/schema/EventNumber.test.d.ts.map +1 -0
  49. package/dist/schema/EventNumber.test.js +11 -0
  50. package/dist/schema/EventNumber.test.js.map +1 -0
  51. package/dist/schema/EventSequenceNumber.d.ts +57 -0
  52. package/dist/schema/EventSequenceNumber.d.ts.map +1 -0
  53. package/dist/schema/EventSequenceNumber.js +82 -0
  54. package/dist/schema/EventSequenceNumber.js.map +1 -0
  55. package/dist/schema/EventSequenceNumber.test.d.ts +2 -0
  56. package/dist/schema/EventSequenceNumber.test.d.ts.map +1 -0
  57. package/dist/schema/EventSequenceNumber.test.js +11 -0
  58. package/dist/schema/EventSequenceNumber.test.js.map +1 -0
  59. package/dist/schema/LiveStoreEvent.d.ts +81 -79
  60. package/dist/schema/LiveStoreEvent.d.ts.map +1 -1
  61. package/dist/schema/LiveStoreEvent.js +31 -32
  62. package/dist/schema/LiveStoreEvent.js.map +1 -1
  63. package/dist/schema/mod.d.ts +1 -1
  64. package/dist/schema/mod.d.ts.map +1 -1
  65. package/dist/schema/mod.js +1 -1
  66. package/dist/schema/mod.js.map +1 -1
  67. package/dist/schema/state/sqlite/query-builder/impl.d.ts.map +1 -1
  68. package/dist/schema/state/sqlite/query-builder/impl.js +2 -2
  69. package/dist/schema/state/sqlite/query-builder/impl.js.map +1 -1
  70. package/dist/schema/state/sqlite/query-builder/impl.test.d.ts +3 -3
  71. package/dist/schema/state/sqlite/query-builder/impl.test.js +9 -0
  72. package/dist/schema/state/sqlite/query-builder/impl.test.js.map +1 -1
  73. package/dist/schema/state/sqlite/system-tables.d.ts +52 -52
  74. package/dist/schema/state/sqlite/system-tables.d.ts.map +1 -1
  75. package/dist/schema/state/sqlite/system-tables.js +11 -10
  76. package/dist/schema/state/sqlite/system-tables.js.map +1 -1
  77. package/dist/sync/ClientSessionSyncProcessor.js +6 -6
  78. package/dist/sync/ClientSessionSyncProcessor.js.map +1 -1
  79. package/dist/sync/next/compact-events.js +38 -35
  80. package/dist/sync/next/compact-events.js.map +1 -1
  81. package/dist/sync/next/facts.d.ts +4 -4
  82. package/dist/sync/next/facts.d.ts.map +1 -1
  83. package/dist/sync/next/facts.js +8 -8
  84. package/dist/sync/next/facts.js.map +1 -1
  85. package/dist/sync/next/history-dag-common.d.ts +4 -4
  86. package/dist/sync/next/history-dag-common.d.ts.map +1 -1
  87. package/dist/sync/next/history-dag-common.js +7 -4
  88. package/dist/sync/next/history-dag-common.js.map +1 -1
  89. package/dist/sync/next/history-dag.d.ts +0 -2
  90. package/dist/sync/next/history-dag.d.ts.map +1 -1
  91. package/dist/sync/next/history-dag.js +15 -13
  92. package/dist/sync/next/history-dag.js.map +1 -1
  93. package/dist/sync/next/rebase-events.d.ts.map +1 -1
  94. package/dist/sync/next/rebase-events.js +10 -4
  95. package/dist/sync/next/rebase-events.js.map +1 -1
  96. package/dist/sync/next/test/compact-events.calculator.test.js +13 -13
  97. package/dist/sync/next/test/compact-events.calculator.test.js.map +1 -1
  98. package/dist/sync/next/test/compact-events.test.js +31 -31
  99. package/dist/sync/next/test/compact-events.test.js.map +1 -1
  100. package/dist/sync/next/test/event-fixtures.d.ts +10 -0
  101. package/dist/sync/next/test/event-fixtures.d.ts.map +1 -1
  102. package/dist/sync/next/test/event-fixtures.js +19 -13
  103. package/dist/sync/next/test/event-fixtures.js.map +1 -1
  104. package/dist/sync/sync.d.ts +11 -11
  105. package/dist/sync/sync.d.ts.map +1 -1
  106. package/dist/sync/sync.js +5 -5
  107. package/dist/sync/sync.js.map +1 -1
  108. package/dist/sync/syncstate.d.ts +18 -18
  109. package/dist/sync/syncstate.d.ts.map +1 -1
  110. package/dist/sync/syncstate.js +46 -47
  111. package/dist/sync/syncstate.js.map +1 -1
  112. package/dist/sync/syncstate.test.js +110 -110
  113. package/dist/sync/syncstate.test.js.map +1 -1
  114. package/dist/sync/validate-push-payload.d.ts +2 -2
  115. package/dist/sync/validate-push-payload.d.ts.map +1 -1
  116. package/dist/sync/validate-push-payload.js +4 -4
  117. package/dist/sync/validate-push-payload.js.map +1 -1
  118. package/dist/version.d.ts +2 -2
  119. package/dist/version.js +2 -2
  120. package/package.json +4 -4
  121. package/src/adapter-types.ts +6 -4
  122. package/src/devtools/devtools-messages-client-session.ts +3 -3
  123. package/src/devtools/devtools-messages-leader.ts +3 -3
  124. package/src/leader-thread/LeaderSyncProcessor.ts +36 -29
  125. package/src/leader-thread/eventlog.ts +36 -31
  126. package/src/leader-thread/leader-worker-devtools.ts +1 -1
  127. package/src/leader-thread/materialize-event.ts +21 -17
  128. package/src/leader-thread/types.ts +4 -4
  129. package/src/make-client-session.ts +2 -0
  130. package/src/materializer-helper.ts +5 -2
  131. package/src/rematerialize-from-eventlog.ts +10 -10
  132. package/src/schema/EventSequenceNumber.test.ts +12 -0
  133. package/src/schema/EventSequenceNumber.ts +121 -0
  134. package/src/schema/LiveStoreEvent.ts +66 -65
  135. package/src/schema/mod.ts +1 -1
  136. package/src/schema/state/sqlite/query-builder/impl.test.ts +9 -0
  137. package/src/schema/state/sqlite/query-builder/impl.ts +3 -2
  138. package/src/schema/state/sqlite/system-tables.ts +11 -10
  139. package/src/sync/ClientSessionSyncProcessor.ts +6 -6
  140. package/src/sync/next/compact-events.ts +38 -35
  141. package/src/sync/next/facts.ts +12 -9
  142. package/src/sync/next/history-dag-common.ts +9 -6
  143. package/src/sync/next/history-dag.ts +15 -16
  144. package/src/sync/next/rebase-events.ts +10 -4
  145. package/src/sync/next/test/compact-events.calculator.test.ts +13 -13
  146. package/src/sync/next/test/compact-events.test.ts +31 -31
  147. package/src/sync/next/test/event-fixtures.ts +20 -13
  148. package/src/sync/sync.ts +7 -7
  149. package/src/sync/syncstate.test.ts +112 -112
  150. package/src/sync/syncstate.ts +58 -48
  151. package/src/sync/validate-push-payload.ts +5 -5
  152. package/src/version.ts +2 -2
  153. package/src/schema/EventId.test.ts +0 -12
  154. package/src/schema/EventId.ts +0 -106
@@ -1,6 +1,6 @@
1
+ import { EventSequenceNumber } from '../../schema/mod.js'
1
2
  import { replacesFacts } from './facts.js'
2
3
  import { graphologyDag } from './graphology_.js'
3
- import { eventIdToString } from './history-dag.js'
4
4
  import type { HistoryDag } from './history-dag-common.js'
5
5
  import { emptyHistoryDag } from './history-dag-common.js'
6
6
 
@@ -17,25 +17,25 @@ export const compactEvents = (inputDag: HistoryDag): { dag: HistoryDag; compacte
17
17
  const dag = inputDag.copy()
18
18
  const compactedEventCount = 0
19
19
 
20
- const orderedEventIdStrs = graphologyDag.topologicalSort(dag).reverse()
20
+ const orderedEventSequenceNumberStrs = graphologyDag.topologicalSort(dag).reverse()
21
21
 
22
22
  // drop root
23
- orderedEventIdStrs.pop()
23
+ orderedEventSequenceNumberStrs.pop()
24
24
 
25
- for (const eventIdStr of orderedEventIdStrs) {
26
- if (dag.hasNode(eventIdStr) === false) {
25
+ for (const eventNumStr of orderedEventSequenceNumberStrs) {
26
+ if (dag.hasNode(eventNumStr) === false) {
27
27
  continue
28
28
  }
29
29
 
30
- const subDagsForEvent = Array.from(makeSubDagsForEvent(dag, eventIdStr))
30
+ const subDagsForEvent = Array.from(makeSubDagsForEvent(dag, eventNumStr))
31
31
  for (const subDag of subDagsForEvent) {
32
32
  let shouldRetry = true
33
33
  while (shouldRetry) {
34
- const subDagsInHistory = findSubDagsInHistory(dag, subDag, eventIdStr)
34
+ const subDagsInHistory = findSubDagsInHistory(dag, subDag, eventNumStr)
35
35
 
36
36
  // console.debug(
37
37
  // 'subDagsInHistory',
38
- // eventIdStr,
38
+ // eventNumStr,
39
39
  // 'target',
40
40
  // subDag.nodes(),
41
41
  // 'found',
@@ -65,9 +65,9 @@ export const compactEvents = (inputDag: HistoryDag): { dag: HistoryDag; compacte
65
65
  return { dag, compactedEventCount }
66
66
  }
67
67
 
68
- function* makeSubDagsForEvent(inputDag: HistoryDag, eventIdStr: string): Generator<HistoryDag> {
69
- /** Map from eventIdStr to array of eventIdStrs that are dependencies */
70
- let nextIterationEls: Map<string, string[]> = new Map([[eventIdStr, []]])
68
+ function* makeSubDagsForEvent(inputDag: HistoryDag, eventNumStr: string): Generator<HistoryDag> {
69
+ /** Map from eventNumStr to array of eventNumStrs that are dependencies */
70
+ let nextIterationEls: Map<string, string[]> = new Map([[eventNumStr, []]])
71
71
  let previousDag: HistoryDag | undefined
72
72
 
73
73
  while (nextIterationEls.size > 0) {
@@ -77,19 +77,22 @@ function* makeSubDagsForEvent(inputDag: HistoryDag, eventIdStr: string): Generat
77
77
  const currentIterationEls = new Map(nextIterationEls)
78
78
  nextIterationEls = new Map()
79
79
 
80
- for (const [currentEventIdStr, edgeTargetIdStrs] of currentIterationEls) {
81
- const node = inputDag.getNodeAttributes(currentEventIdStr)
82
- if (subDag.hasNode(currentEventIdStr) === false) {
83
- subDag.addNode(currentEventIdStr, { ...node })
80
+ for (const [currentEventSequenceNumberStr, edgeTargetIdStrs] of currentIterationEls) {
81
+ const node = inputDag.getNodeAttributes(currentEventSequenceNumberStr)
82
+ if (subDag.hasNode(currentEventSequenceNumberStr) === false) {
83
+ subDag.addNode(currentEventSequenceNumberStr, { ...node })
84
84
  }
85
85
  for (const edgeTargetIdStr of edgeTargetIdStrs) {
86
- subDag.addEdge(currentEventIdStr, edgeTargetIdStr, { type: 'facts' })
86
+ subDag.addEdge(currentEventSequenceNumberStr, edgeTargetIdStr, { type: 'facts' })
87
87
  }
88
88
 
89
- for (const depEdge of inputDag.outboundEdgeEntries(currentEventIdStr)) {
89
+ for (const depEdge of inputDag.outboundEdgeEntries(currentEventSequenceNumberStr)) {
90
90
  if (depEdge.attributes.type === 'facts') {
91
- const depEventIdStr = depEdge.target
92
- nextIterationEls.set(depEventIdStr, [...(nextIterationEls.get(depEventIdStr) ?? []), currentEventIdStr])
91
+ const depEventSequenceNumberStr = depEdge.target
92
+ nextIterationEls.set(depEventSequenceNumberStr, [
93
+ ...(nextIterationEls.get(depEventSequenceNumberStr) ?? []),
94
+ currentEventSequenceNumberStr,
95
+ ])
93
96
  }
94
97
  }
95
98
  }
@@ -102,23 +105,23 @@ function* makeSubDagsForEvent(inputDag: HistoryDag, eventIdStr: string): Generat
102
105
  }
103
106
 
104
107
  /**
105
- * Iterates over all events from root to `upToExclEventIdStr`
108
+ * Iterates over all events from root to `upToExclEventSequenceNumberStr`
106
109
  * and collects all valid sub dags that are replaced by `targetSubDag`.
107
110
  */
108
111
  const findSubDagsInHistory = (
109
112
  inputDag: HistoryDag,
110
113
  targetSubDag: HistoryDag,
111
- upToExclEventIdStr: string,
114
+ upToExclEventSequenceNumberStr: string,
112
115
  ): { subDags: HistoryDag[]; allOutsideDependencies: string[][] } => {
113
116
  const subDags: HistoryDag[] = []
114
117
  const allOutsideDependencies: string[][] = []
115
118
 
116
- for (const eventIdStr of graphologyDag.topologicalSort(inputDag)) {
117
- if (eventIdStr === upToExclEventIdStr) {
119
+ for (const eventNumStr of graphologyDag.topologicalSort(inputDag)) {
120
+ if (eventNumStr === upToExclEventSequenceNumberStr) {
118
121
  break
119
122
  }
120
123
 
121
- for (const subDag of makeSubDagsForEvent(inputDag, eventIdStr)) {
124
+ for (const subDag of makeSubDagsForEvent(inputDag, eventNumStr)) {
122
125
  // console.debug('findSubDagsInHistory', 'target', targetSubDag.nodes(), 'subDag', subDag.nodes())
123
126
  if (subDag.size < targetSubDag.size) {
124
127
  continue
@@ -152,9 +155,9 @@ const outsideDependenciesForDag = (subDag: HistoryDag, inputDag: HistoryDag) =>
152
155
  for (const nodeIdStr of subDag.nodes()) {
153
156
  for (const edgeEntry of inputDag.outboundEdgeEntries(nodeIdStr)) {
154
157
  if (edgeEntry.attributes.type === 'facts') {
155
- const depEventIdStr = edgeEntry.target
156
- if (subDag.hasNode(depEventIdStr) === false) {
157
- outsideDependencies.push(depEventIdStr)
158
+ const depEventSequenceNumberStr = edgeEntry.target
159
+ if (subDag.hasNode(depEventSequenceNumberStr) === false) {
160
+ outsideDependencies.push(depEventSequenceNumberStr)
158
161
  }
159
162
  }
160
163
  }
@@ -201,19 +204,19 @@ const dagReplacesDag = (dagA: HistoryDag, dagB: HistoryDag): boolean => {
201
204
  return true
202
205
  }
203
206
 
204
- const removeEvent = (dag: HistoryDag, eventIdStr: string) => {
205
- // console.debug('removing event', eventIdStr)
206
- const event = dag.getNodeAttributes(eventIdStr)
207
- const parentIdStr = eventIdToString(event.parentId)
208
- const childEdges = dag.outboundEdgeEntries(eventIdStr)
207
+ const removeEvent = (dag: HistoryDag, eventNumStr: string) => {
208
+ // console.debug('removing event', eventNumStr)
209
+ const event = dag.getNodeAttributes(eventNumStr)
210
+ const parentSeqNumStr = EventSequenceNumber.toString(event.parentSeqNum)
211
+ const childEdges = dag.outboundEdgeEntries(eventNumStr)
209
212
 
210
213
  for (const childEdge of childEdges) {
211
214
  if (childEdge.attributes.type === 'parent') {
212
215
  const childEvent = dag.getNodeAttributes(childEdge.target)
213
- childEvent.parentId = { ...event.parentId }
214
- dag.addEdge(parentIdStr, eventIdToString(childEvent.id), { type: 'parent' })
216
+ childEvent.parentSeqNum = { ...event.parentSeqNum }
217
+ dag.addEdge(parentSeqNumStr, EventSequenceNumber.toString(childEvent.seqNum), { type: 'parent' })
215
218
  }
216
219
  }
217
220
 
218
- dag.dropNode(eventIdStr)
221
+ dag.dropNode(eventNumStr)
219
222
  }
@@ -7,18 +7,18 @@ import type {
7
7
  EventDefFactsSnapshot,
8
8
  FactsCallback,
9
9
  } from '../../schema/EventDef.js'
10
- import type * as EventId from '../../schema/EventId.js'
10
+ import type * as EventSequenceNumber from '../../schema/EventSequenceNumber.js'
11
11
  import { graphologyDag } from './graphology_.js'
12
12
  import { EMPTY_FACT_VALUE, type HistoryDag, type HistoryDagNode } from './history-dag-common.js'
13
13
 
14
14
  export const factsSnapshotForEvents = (
15
15
  events: HistoryDagNode[],
16
- endEventId: EventId.EventId,
16
+ endEventSequenceNumber: EventSequenceNumber.EventSequenceNumber,
17
17
  ): EventDefFactsSnapshot => {
18
18
  const facts = new Map<string, any>()
19
19
 
20
20
  for (const event of events) {
21
- if (compareEventIds(event.id, endEventId) > 0) {
21
+ if (compareEventSequenceNumbers(event.seqNum, endEventSequenceNumber) > 0) {
22
22
  return facts
23
23
  }
24
24
 
@@ -30,15 +30,15 @@ export const factsSnapshotForEvents = (
30
30
 
31
31
  export const factsSnapshotForDag = (
32
32
  dag: HistoryDag,
33
- endEventId: EventId.EventId | undefined,
33
+ endEventSequenceNumber: EventSequenceNumber.EventSequenceNumber | undefined,
34
34
  ): EventDefFactsSnapshot => {
35
35
  const facts = new Map<string, any>()
36
36
 
37
- const orderedEventIdStrs = graphologyDag.topologicalSort(dag)
37
+ const orderedEventSequenceNumberStrs = graphologyDag.topologicalSort(dag)
38
38
 
39
- for (let i = 0; i < orderedEventIdStrs.length; i++) {
40
- const event = dag.getNodeAttributes(orderedEventIdStrs[i]!)
41
- if (endEventId !== undefined && compareEventIds(event.id, endEventId) > 0) {
39
+ for (let i = 0; i < orderedEventSequenceNumberStrs.length; i++) {
40
+ const event = dag.getNodeAttributes(orderedEventSequenceNumberStrs[i]!)
41
+ if (endEventSequenceNumber !== undefined && compareEventSequenceNumbers(event.seqNum, endEventSequenceNumber) > 0) {
42
42
  return facts
43
43
  }
44
44
 
@@ -226,7 +226,10 @@ export const getFactsGroupForEventArgs = ({
226
226
  return facts
227
227
  }
228
228
 
229
- export const compareEventIds = (a: EventId.EventId, b: EventId.EventId) => {
229
+ export const compareEventSequenceNumbers = (
230
+ a: EventSequenceNumber.EventSequenceNumber,
231
+ b: EventSequenceNumber.EventSequenceNumber,
232
+ ) => {
230
233
  if (a.global !== b.global) {
231
234
  return a.global - b.global
232
235
  }
@@ -1,5 +1,5 @@
1
1
  import type { EventDefFactsGroup } from '../../schema/EventDef.js'
2
- import * as EventId from '../../schema/EventId.js'
2
+ import * as EventSequenceNumber from '../../schema/EventSequenceNumber.js'
3
3
  import { graphology } from './graphology_.js'
4
4
 
5
5
  export const connectionTypeOptions = ['parent', 'facts'] as const
@@ -20,11 +20,14 @@ export const emptyHistoryDag = (): HistoryDag =>
20
20
  })
21
21
 
22
22
  // TODO consider making `ROOT_ID` parent to itself
23
- export const rootParentId = EventId.make({ global: EventId.ROOT.global - 1, client: EventId.clientDefault })
23
+ export const rootParentNum = EventSequenceNumber.make({
24
+ global: EventSequenceNumber.ROOT.global - 1,
25
+ client: EventSequenceNumber.clientDefault,
26
+ })
24
27
 
25
28
  export type HistoryDagNode = {
26
- id: EventId.EventId
27
- parentId: EventId.EventId
29
+ seqNum: EventSequenceNumber.EventSequenceNumber
30
+ parentSeqNum: EventSequenceNumber.EventSequenceNumber
28
31
  name: string
29
32
  args: any
30
33
  /** Facts are being used for conflict detection and history compaction */
@@ -35,8 +38,8 @@ export type HistoryDagNode = {
35
38
  }
36
39
 
37
40
  export const rootEventNode: HistoryDagNode = {
38
- id: EventId.ROOT,
39
- parentId: rootParentId,
41
+ seqNum: EventSequenceNumber.ROOT,
42
+ parentSeqNum: rootParentNum,
40
43
  // unused below
41
44
  name: '__Root__',
42
45
  args: {},
@@ -1,9 +1,6 @@
1
- import type * as EventId from '../../schema/EventId.js'
1
+ import * as EventSequenceNumber from '../../schema/EventSequenceNumber.js'
2
2
  import { factsToString, validateFacts } from './facts.js'
3
- import { emptyHistoryDag, type HistoryDagNode, rootParentId } from './history-dag-common.js'
4
-
5
- export const eventIdToString = (eventId: EventId.EventId) =>
6
- eventId.client === 0 ? eventId.global.toString() : `${eventId.global}.${eventId.client}`
3
+ import { emptyHistoryDag, type HistoryDagNode, rootParentNum } from './history-dag-common.js'
7
4
 
8
5
  export const historyDagFromNodes = (dagNodes: HistoryDagNode[], options?: { skipFactsCheck: boolean }) => {
9
6
  if (options?.skipFactsCheck !== true) {
@@ -21,11 +18,13 @@ export const historyDagFromNodes = (dagNodes: HistoryDagNode[], options?: { skip
21
18
 
22
19
  const dag = emptyHistoryDag()
23
20
 
24
- dagNodes.forEach((node) => dag.addNode(eventIdToString(node.id), node))
21
+ dagNodes.forEach((node) => dag.addNode(EventSequenceNumber.toString(node.seqNum), node))
25
22
 
26
23
  dagNodes.forEach((node) => {
27
- if (eventIdToString(node.parentId) !== eventIdToString(rootParentId)) {
28
- dag.addEdge(eventIdToString(node.parentId), eventIdToString(node.id), { type: 'parent' })
24
+ if (EventSequenceNumber.toString(node.parentSeqNum) !== EventSequenceNumber.toString(rootParentNum)) {
25
+ dag.addEdge(EventSequenceNumber.toString(node.parentSeqNum), EventSequenceNumber.toString(node.seqNum), {
26
+ type: 'parent',
27
+ })
29
28
  }
30
29
  })
31
30
 
@@ -34,28 +33,28 @@ export const historyDagFromNodes = (dagNodes: HistoryDagNode[], options?: { skip
34
33
  for (const factKey of factKeys) {
35
34
  // Find the first ancestor node with a matching fact key (via modifySet or modifyUnset) by traversing the graph backwards via the parent edges
36
35
  const depNode = (() => {
37
- let currentIdStr = eventIdToString(node.id)
36
+ let currentSeqNumStr = EventSequenceNumber.toString(node.seqNum)
38
37
 
39
- while (currentIdStr !== eventIdToString(rootParentId)) {
40
- const parentEdge = dag.inEdges(currentIdStr).find((e) => dag.getEdgeAttribute(e, 'type') === 'parent')
38
+ while (currentSeqNumStr !== EventSequenceNumber.toString(rootParentNum)) {
39
+ const parentEdge = dag.inEdges(currentSeqNumStr).find((e) => dag.getEdgeAttribute(e, 'type') === 'parent')
41
40
  if (!parentEdge) return null
42
41
 
43
- const parentIdStr = dag.source(parentEdge)
44
- const parentNode = dag.getNodeAttributes(parentIdStr)
42
+ const parentSeqNumStr = dag.source(parentEdge)
43
+ const parentNode = dag.getNodeAttributes(parentSeqNumStr)
45
44
 
46
45
  if (parentNode.factsGroup.modifySet.has(factKey) || parentNode.factsGroup.modifyUnset.has(factKey)) {
47
46
  return parentNode
48
47
  }
49
48
 
50
- currentIdStr = parentIdStr
49
+ currentSeqNumStr = parentSeqNumStr
51
50
  }
52
51
 
53
52
  return null
54
53
  })()
55
54
 
56
55
  if (depNode) {
57
- const depNodeIdStr = eventIdToString(depNode.id)
58
- const nodeIdStr = eventIdToString(node.id)
56
+ const depNodeIdStr = EventSequenceNumber.toString(depNode.seqNum)
57
+ const nodeIdStr = EventSequenceNumber.toString(node.seqNum)
59
58
  if (dag.edges(depNodeIdStr, nodeIdStr).filter((e) => dag.getEdgeAttributes(e).type === 'facts').length === 0) {
60
59
  dag.addEdge(depNodeIdStr, nodeIdStr, { type: 'facts' })
61
60
  }
@@ -1,5 +1,5 @@
1
1
  import type { EventDef, EventDefFactsSnapshot } from '../../schema/EventDef.js'
2
- import * as EventId from '../../schema/EventId.js'
2
+ import * as EventSequenceNumber from '../../schema/EventSequenceNumber.js'
3
3
  import type * as LiveStoreEvent from '../../schema/LiveStoreEvent.js'
4
4
  import {
5
5
  applyFactGroups,
@@ -88,13 +88,19 @@ export const rebaseEvents = ({
88
88
  initialSnapshot,
89
89
  }),
90
90
  })
91
- const headGlobalId = newRemoteEvents.at(-1)!.id.global
91
+ const headGlobalId = newRemoteEvents.at(-1)!.seqNum.global
92
92
 
93
93
  return rebasedLocalEvents.map(
94
94
  (event, index) =>
95
95
  ({
96
- id: EventId.make({ global: headGlobalId + index + 1, client: EventId.clientDefault }),
97
- parentId: EventId.make({ global: headGlobalId + index, client: EventId.clientDefault }),
96
+ seqNum: EventSequenceNumber.make({
97
+ global: headGlobalId + index + 1,
98
+ client: EventSequenceNumber.clientDefault,
99
+ }),
100
+ parentSeqNum: EventSequenceNumber.make({
101
+ global: headGlobalId + index,
102
+ client: EventSequenceNumber.clientDefault,
103
+ }),
98
104
  name: event.name,
99
105
  args: event.args,
100
106
  clientId,
@@ -5,7 +5,7 @@ import { describe, expect, it } from 'vitest'
5
5
  import { compactEvents } from '../compact-events.js'
6
6
  import { historyDagFromNodes } from '../history-dag.js'
7
7
  import { customSerializer } from './compact-events.test.js'
8
- import { toEventNodes } from './event-fixtures.js'
8
+ import { printEvent, toEventNodes } from './event-fixtures.js'
9
9
 
10
10
  expect.addSnapshotSerializer(customSerializer)
11
11
 
@@ -15,7 +15,7 @@ const compact = (events: any[]) => {
15
15
 
16
16
  return Array.from(compacted.dag.nodeEntries())
17
17
  .map((_) => _.attributes)
18
- .map(({ factsGroup, ...rest }) => ({ ...rest, facts: factsGroup }))
18
+ .map(printEvent)
19
19
  .slice(1)
20
20
  }
21
21
 
@@ -50,8 +50,8 @@ describe('compactEvents calculator', () => {
50
50
 
51
51
  expect(expected).toMatchInlineSnapshot(`
52
52
  [
53
- { id: 1, parentId: 0, name: "add", args: { value: 1 }, clientId: "client-id", sessionId: "session-id", facts: "" }
54
- { id: 2, parentId: 1, name: "add", args: { value: 1 }, clientId: "client-id", sessionId: "session-id", facts: "" }
53
+ { seqNum: "e1", parentSeqNum: "e0", name: "add", args: { value: 1 }, clientId: "client-id", sessionId: "session-id", facts: "" }
54
+ { seqNum: "e2", parentSeqNum: "e1", name: "add", args: { value: 1 }, clientId: "client-id", sessionId: "session-id", facts: "" }
55
55
  ]
56
56
  `)
57
57
  })
@@ -64,8 +64,8 @@ describe('compactEvents calculator', () => {
64
64
 
65
65
  expect(expected).toMatchInlineSnapshot(`
66
66
  [
67
- { id: 1, parentId: 0, name: "multiply", args: { value: 2 }, clientId: "client-id", sessionId: "session-id", facts: "?multiplyByZero -multiplyByZero" }
68
- { id: 2, parentId: 1, name: "multiply", args: { value: 2 }, clientId: "client-id", sessionId: "session-id", facts: "?multiplyByZero -multiplyByZero" }
67
+ { seqNum: "e1", parentSeqNum: "e0", name: "multiply", args: { value: 2 }, clientId: "client-id", sessionId: "session-id", facts: "?multiplyByZero -multiplyByZero" }
68
+ { seqNum: "e2", parentSeqNum: "e1", name: "multiply", args: { value: 2 }, clientId: "client-id", sessionId: "session-id", facts: "?multiplyByZero -multiplyByZero" }
69
69
  ]
70
70
  `)
71
71
  })
@@ -79,7 +79,7 @@ describe('compactEvents calculator', () => {
79
79
 
80
80
  expect(expected).toMatchInlineSnapshot(`
81
81
  [
82
- { id: 3, parentId: 0, name: "multiply", args: { value: 0 }, clientId: "client-id", sessionId: "session-id", facts: "+multiplyByZero" }
82
+ { seqNum: "e3", parentSeqNum: "e0", name: "multiply", args: { value: 0 }, clientId: "client-id", sessionId: "session-id", facts: "+multiplyByZero" }
83
83
  ]
84
84
  `)
85
85
  })
@@ -94,8 +94,8 @@ describe('compactEvents calculator', () => {
94
94
 
95
95
  expect(expected).toMatchInlineSnapshot(`
96
96
  [
97
- { id: 3, parentId: 0, name: "multiply", args: { value: 0 }, clientId: "client-id", sessionId: "session-id", facts: "+multiplyByZero" }
98
- { id: 4, parentId: 3, name: "add", args: { value: 1 }, clientId: "client-id", sessionId: "session-id", facts: "" }
97
+ { seqNum: "e3", parentSeqNum: "e0", name: "multiply", args: { value: 0 }, clientId: "client-id", sessionId: "session-id", facts: "+multiplyByZero" }
98
+ { seqNum: "e4", parentSeqNum: "e3", name: "add", args: { value: 1 }, clientId: "client-id", sessionId: "session-id", facts: "" }
99
99
  ]
100
100
  `)
101
101
  })
@@ -111,10 +111,10 @@ describe('compactEvents calculator', () => {
111
111
 
112
112
  expect(expected).toMatchInlineSnapshot(`
113
113
  [
114
- { id: 1, parentId: 0, name: "add", args: { value: 1 }, clientId: "client-id", sessionId: "session-id", facts: "" }
115
- { id: 3, parentId: 1, name: "multiply", args: { value: 0 }, clientId: "client-id", sessionId: "session-id", facts: "+multiplyByZero" }
116
- { id: 4, parentId: 3, name: "multiply", args: { value: 2 }, clientId: "client-id", sessionId: "session-id", facts: "?multiplyByZero +multiplyByZero -multiplyByZero" }
117
- { id: 5, parentId: 4, name: "add", args: { value: 1 }, clientId: "client-id", sessionId: "session-id", facts: "" }
114
+ { seqNum: "e1", parentSeqNum: "e0", name: "add", args: { value: 1 }, clientId: "client-id", sessionId: "session-id", facts: "" }
115
+ { seqNum: "e3", parentSeqNum: "e1", name: "multiply", args: { value: 0 }, clientId: "client-id", sessionId: "session-id", facts: "+multiplyByZero" }
116
+ { seqNum: "e4", parentSeqNum: "e3", name: "multiply", args: { value: 2 }, clientId: "client-id", sessionId: "session-id", facts: "?multiplyByZero +multiplyByZero -multiplyByZero" }
117
+ { seqNum: "e5", parentSeqNum: "e4", name: "add", args: { value: 1 }, clientId: "client-id", sessionId: "session-id", facts: "" }
118
118
  ]
119
119
  `)
120
120
  })
@@ -5,7 +5,7 @@ import { compactEvents } from '../compact-events.js'
5
5
  import { historyDagFromNodes } from '../history-dag.js'
6
6
  import type { HistoryDagNode } from '../history-dag-common.js'
7
7
  import { EMPTY_FACT_VALUE } from '../history-dag-common.js'
8
- import { events as eventDefs, toEventNodes } from './event-fixtures.js'
8
+ import { events as eventDefs, printEvent, toEventNodes } from './event-fixtures.js'
9
9
 
10
10
  const customStringify = (value: any): string => {
11
11
  if (value === null) {
@@ -37,7 +37,7 @@ const customStringify = (value: any): string => {
37
37
  const valStr =
38
38
  key === 'facts'
39
39
  ? `"${factsToString(val)}"`
40
- : (key === 'id' || key === 'parentId') && Object.keys(val).length === 2 && val.client === 0
40
+ : (key === 'id' || key === 'parentSeqNum') && Object.keys(val).length === 2 && val.client === 0
41
41
  ? val.global
42
42
  : customStringify(val)
43
43
 
@@ -76,7 +76,7 @@ const compact = (events: any[]) => {
76
76
 
77
77
  return Array.from(compacted.dag.nodeEntries())
78
78
  .map((_) => _.attributes)
79
- .map(({ factsGroup, ...rest }) => ({ ...rest, facts: factsGroup }))
79
+ .map(printEvent)
80
80
  .slice(1)
81
81
  }
82
82
 
@@ -90,8 +90,8 @@ describe('compactEvents todo app', () => {
90
90
 
91
91
  expect(expected).toMatchInlineSnapshot(`
92
92
  [
93
- { id: 1, parentId: 0, name: "createTodo", args: { id: "A", text: "buy milk" }, clientId: "client-id", sessionId: "session-id", facts: "+todo-exists-A +todo-is-writeable-A=true +todo-completed-A=false" }
94
- { id: 3, parentId: 1, name: "todoCompleted", args: { id: "A" }, clientId: "client-id", sessionId: "session-id", facts: "↖todo-exists-A ↖todo-is-writeable-A=true +todo-completed-A=true" }
93
+ { seqNum: "e1", parentSeqNum: "e0", name: "createTodo", args: { id: "A", text: "buy milk" }, clientId: "client-id", sessionId: "session-id", facts: "+todo-exists-A +todo-is-writeable-A=true +todo-completed-A=false" }
94
+ { seqNum: "e3", parentSeqNum: "e1", name: "todoCompleted", args: { id: "A" }, clientId: "client-id", sessionId: "session-id", facts: "↖todo-exists-A ↖todo-is-writeable-A=true +todo-completed-A=true" }
95
95
  ]
96
96
  `)
97
97
  })
@@ -106,10 +106,10 @@ describe('compactEvents todo app', () => {
106
106
 
107
107
  expect(expected).toMatchInlineSnapshot(`
108
108
  [
109
- { id: 1, parentId: 0, name: "createTodo", args: { id: "A", text: "buy milk" }, clientId: "client-id", sessionId: "session-id", facts: "+todo-exists-A +todo-is-writeable-A=true +todo-completed-A=false" }
110
- { id: 2, parentId: 1, name: "toggleTodo", args: { id: "A" }, clientId: "client-id", sessionId: "session-id", facts: "↖todo-exists-A ↖todo-is-writeable-A=true ?todo-completed-A +todo-completed-A=true" }
111
- { id: 3, parentId: 2, name: "toggleTodo", args: { id: "A" }, clientId: "client-id", sessionId: "session-id", facts: "↖todo-exists-A ↖todo-is-writeable-A=true ?todo-completed-A +todo-completed-A=false" }
112
- { id: 4, parentId: 3, name: "toggleTodo", args: { id: "A" }, clientId: "client-id", sessionId: "session-id", facts: "↖todo-exists-A ↖todo-is-writeable-A=true ?todo-completed-A +todo-completed-A=true" }
109
+ { seqNum: "e1", parentSeqNum: "e0", name: "createTodo", args: { id: "A", text: "buy milk" }, clientId: "client-id", sessionId: "session-id", facts: "+todo-exists-A +todo-is-writeable-A=true +todo-completed-A=false" }
110
+ { seqNum: "e2", parentSeqNum: "e1", name: "toggleTodo", args: { id: "A" }, clientId: "client-id", sessionId: "session-id", facts: "↖todo-exists-A ↖todo-is-writeable-A=true ?todo-completed-A +todo-completed-A=true" }
111
+ { seqNum: "e3", parentSeqNum: "e2", name: "toggleTodo", args: { id: "A" }, clientId: "client-id", sessionId: "session-id", facts: "↖todo-exists-A ↖todo-is-writeable-A=true ?todo-completed-A +todo-completed-A=false" }
112
+ { seqNum: "e4", parentSeqNum: "e3", name: "toggleTodo", args: { id: "A" }, clientId: "client-id", sessionId: "session-id", facts: "↖todo-exists-A ↖todo-is-writeable-A=true ?todo-completed-A +todo-completed-A=true" }
113
113
  ]
114
114
  `)
115
115
  })
@@ -126,9 +126,9 @@ describe('compactEvents todo app', () => {
126
126
 
127
127
  expect(expected).toMatchInlineSnapshot(`
128
128
  [
129
- { id: 1, parentId: 0, name: "createTodo", args: { id: "A", text: "buy milk" }, clientId: "client-id", sessionId: "session-id", facts: "+todo-exists-A +todo-is-writeable-A=true +todo-completed-A=false" }
130
- { id: 5, parentId: 1, name: "todoCompleted", args: { id: "A" }, clientId: "client-id", sessionId: "session-id", facts: "↖todo-exists-A ↖todo-is-writeable-A=true +todo-completed-A=true" }
131
- { id: 6, parentId: 5, name: "toggleTodo", args: { id: "A" }, clientId: "client-id", sessionId: "session-id", facts: "↖todo-exists-A ↖todo-is-writeable-A=true ?todo-completed-A +todo-completed-A=false" }
129
+ { seqNum: "e1", parentSeqNum: "e0", name: "createTodo", args: { id: "A", text: "buy milk" }, clientId: "client-id", sessionId: "session-id", facts: "+todo-exists-A +todo-is-writeable-A=true +todo-completed-A=false" }
130
+ { seqNum: "e5", parentSeqNum: "e1", name: "todoCompleted", args: { id: "A" }, clientId: "client-id", sessionId: "session-id", facts: "↖todo-exists-A ↖todo-is-writeable-A=true +todo-completed-A=true" }
131
+ { seqNum: "e6", parentSeqNum: "e5", name: "toggleTodo", args: { id: "A" }, clientId: "client-id", sessionId: "session-id", facts: "↖todo-exists-A ↖todo-is-writeable-A=true ?todo-completed-A +todo-completed-A=false" }
132
132
  ]
133
133
  `)
134
134
  })
@@ -143,10 +143,10 @@ describe('compactEvents todo app', () => {
143
143
 
144
144
  expect(expected).toMatchInlineSnapshot(`
145
145
  [
146
- { id: 1, parentId: 0, name: "createTodo", args: { id: "A", text: "buy milk" }, clientId: "client-id", sessionId: "session-id", facts: "+todo-exists-A +todo-is-writeable-A=true +todo-completed-A=false" }
147
- { id: 2, parentId: 1, name: "setReadonlyTodo", args: { id: "A", readonly: false }, clientId: "client-id", sessionId: "session-id", facts: "↖todo-exists-A +todo-is-writeable-A=true" }
148
- { id: 3, parentId: 2, name: "setTextTodo", args: { id: "A", text: "buy soy milk" }, clientId: "client-id", sessionId: "session-id", facts: "↖todo-exists-A ↖todo-is-writeable-A=true +todo-text-updated-A" }
149
- { id: 4, parentId: 3, name: "setReadonlyTodo", args: { id: "A", readonly: true }, clientId: "client-id", sessionId: "session-id", facts: "↖todo-exists-A +todo-is-writeable-A=false" }
146
+ { seqNum: "e1", parentSeqNum: "e0", name: "createTodo", args: { id: "A", text: "buy milk" }, clientId: "client-id", sessionId: "session-id", facts: "+todo-exists-A +todo-is-writeable-A=true +todo-completed-A=false" }
147
+ { seqNum: "e2", parentSeqNum: "e1", name: "setReadonlyTodo", args: { id: "A", readonly: false }, clientId: "client-id", sessionId: "session-id", facts: "↖todo-exists-A +todo-is-writeable-A=true" }
148
+ { seqNum: "e3", parentSeqNum: "e2", name: "setTextTodo", args: { id: "A", text: "buy soy milk" }, clientId: "client-id", sessionId: "session-id", facts: "↖todo-exists-A ↖todo-is-writeable-A=true +todo-text-updated-A" }
149
+ { seqNum: "e4", parentSeqNum: "e3", name: "setReadonlyTodo", args: { id: "A", readonly: true }, clientId: "client-id", sessionId: "session-id", facts: "↖todo-exists-A +todo-is-writeable-A=false" }
150
150
  ]
151
151
  `)
152
152
  })
@@ -162,11 +162,11 @@ describe('compactEvents todo app', () => {
162
162
 
163
163
  expect(expected).toMatchInlineSnapshot(`
164
164
  [
165
- { id: 1, parentId: 0, name: "createTodo", args: { id: "A", text: "buy milk" }, clientId: "client-id", sessionId: "session-id", facts: "+todo-exists-A +todo-is-writeable-A=true +todo-completed-A=false" }
166
- { id: 2, parentId: 1, name: "setReadonlyTodo", args: { id: "A", readonly: false }, clientId: "client-id", sessionId: "session-id", facts: "↖todo-exists-A +todo-is-writeable-A=true" }
167
- { id: 3, parentId: 2, name: "todoCompleted", args: { id: "A" }, clientId: "client-id", sessionId: "session-id", facts: "↖todo-exists-A ↖todo-is-writeable-A=true +todo-completed-A=true" }
168
- { id: 4, parentId: 3, name: "setTextTodo", args: { id: "A", text: "buy soy milk" }, clientId: "client-id", sessionId: "session-id", facts: "↖todo-exists-A ↖todo-is-writeable-A=true +todo-text-updated-A" }
169
- { id: 5, parentId: 4, name: "setReadonlyTodo", args: { id: "A", readonly: true }, clientId: "client-id", sessionId: "session-id", facts: "↖todo-exists-A +todo-is-writeable-A=false" }
165
+ { seqNum: "e1", parentSeqNum: "e0", name: "createTodo", args: { id: "A", text: "buy milk" }, clientId: "client-id", sessionId: "session-id", facts: "+todo-exists-A +todo-is-writeable-A=true +todo-completed-A=false" }
166
+ { seqNum: "e2", parentSeqNum: "e1", name: "setReadonlyTodo", args: { id: "A", readonly: false }, clientId: "client-id", sessionId: "session-id", facts: "↖todo-exists-A +todo-is-writeable-A=true" }
167
+ { seqNum: "e3", parentSeqNum: "e2", name: "todoCompleted", args: { id: "A" }, clientId: "client-id", sessionId: "session-id", facts: "↖todo-exists-A ↖todo-is-writeable-A=true +todo-completed-A=true" }
168
+ { seqNum: "e4", parentSeqNum: "e3", name: "setTextTodo", args: { id: "A", text: "buy soy milk" }, clientId: "client-id", sessionId: "session-id", facts: "↖todo-exists-A ↖todo-is-writeable-A=true +todo-text-updated-A" }
169
+ { seqNum: "e5", parentSeqNum: "e4", name: "setReadonlyTodo", args: { id: "A", readonly: true }, clientId: "client-id", sessionId: "session-id", facts: "↖todo-exists-A +todo-is-writeable-A=false" }
170
170
  ]
171
171
  `)
172
172
  })
@@ -200,11 +200,11 @@ describe('compactEvents todo app', () => {
200
200
 
201
201
  expect(expected).toMatchInlineSnapshot(`
202
202
  [
203
- { id: 1, parentId: 0, name: "createTodo", args: { id: "A", text: "buy milk" }, clientId: "client-id", sessionId: "session-id", facts: "+todo-exists-A +todo-is-writeable-A=true +todo-completed-A=false" }
204
- { id: 2, parentId: 1, name: "createTodo", args: { id: "B", text: "buy bread" }, clientId: "client-id", sessionId: "session-id", facts: "+todo-exists-B +todo-is-writeable-B=true +todo-completed-B=false" }
205
- { id: 3, parentId: 2, name: "createTodo", args: { id: "C", text: "buy cheese" }, clientId: "client-id", sessionId: "session-id", facts: "+todo-exists-C +todo-is-writeable-C=true +todo-completed-C=false" }
206
- { id: 4, parentId: 3, name: "todoCompleteds", args: { ids: ["A", "B", "C"] }, clientId: "client-id", sessionId: "session-id", facts: "↖todo-exists-A ↖todo-is-writeable-A=true ↖todo-exists-B ↖todo-is-writeable-B=true ↖todo-exists-C ↖todo-is-writeable-C=true +todo-completed-A=true +todo-completed-B=true +todo-completed-C=true" }
207
- { id: 6, parentId: 4, name: "todoCompleted", args: { id: "A" }, clientId: "client-id", sessionId: "session-id", facts: "↖todo-exists-A ↖todo-is-writeable-A=true +todo-completed-A=true" }
203
+ { seqNum: "e1", parentSeqNum: "e0", name: "createTodo", args: { id: "A", text: "buy milk" }, clientId: "client-id", sessionId: "session-id", facts: "+todo-exists-A +todo-is-writeable-A=true +todo-completed-A=false" }
204
+ { seqNum: "e2", parentSeqNum: "e1", name: "createTodo", args: { id: "B", text: "buy bread" }, clientId: "client-id", sessionId: "session-id", facts: "+todo-exists-B +todo-is-writeable-B=true +todo-completed-B=false" }
205
+ { seqNum: "e3", parentSeqNum: "e2", name: "createTodo", args: { id: "C", text: "buy cheese" }, clientId: "client-id", sessionId: "session-id", facts: "+todo-exists-C +todo-is-writeable-C=true +todo-completed-C=false" }
206
+ { seqNum: "e4", parentSeqNum: "e3", name: "todoCompleteds", args: { ids: ["A", "B", "C"] }, clientId: "client-id", sessionId: "session-id", facts: "↖todo-exists-A ↖todo-is-writeable-A=true ↖todo-exists-B ↖todo-is-writeable-B=true ↖todo-exists-C ↖todo-is-writeable-C=true +todo-completed-A=true +todo-completed-B=true +todo-completed-C=true" }
207
+ { seqNum: "e6", parentSeqNum: "e4", name: "todoCompleted", args: { id: "A" }, clientId: "client-id", sessionId: "session-id", facts: "↖todo-exists-A ↖todo-is-writeable-A=true +todo-completed-A=true" }
208
208
  ]
209
209
  `)
210
210
  })
@@ -222,11 +222,11 @@ describe('compactEvents todo app', () => {
222
222
 
223
223
  expect(expected).toMatchInlineSnapshot(`
224
224
  [
225
- { id: 1, parentId: 0, name: "createTodo", args: { id: "A", text: "buy milk" }, clientId: "client-id", sessionId: "session-id", facts: "+todo-exists-A +todo-is-writeable-A=true +todo-completed-A=false" }
226
- { id: 2, parentId: 1, name: "createTodo", args: { id: "B", text: "buy bread" }, clientId: "client-id", sessionId: "session-id", facts: "+todo-exists-B +todo-is-writeable-B=true +todo-completed-B=false" }
227
- { id: 3, parentId: 2, name: "createTodo", args: { id: "C", text: "buy cheese" }, clientId: "client-id", sessionId: "session-id", facts: "+todo-exists-C +todo-is-writeable-C=true +todo-completed-C=false" }
228
- { id: 5, parentId: 3, name: "todoCompleteds", args: { ids: ["A", "B", "C"] }, clientId: "client-id", sessionId: "session-id", facts: "↖todo-exists-A ↖todo-is-writeable-A=true ↖todo-exists-B ↖todo-is-writeable-B=true ↖todo-exists-C ↖todo-is-writeable-C=true +todo-completed-A=true +todo-completed-B=true +todo-completed-C=true" }
229
- { id: 7, parentId: 5, name: "todoCompleted", args: { id: "A" }, clientId: "client-id", sessionId: "session-id", facts: "↖todo-exists-A ↖todo-is-writeable-A=true +todo-completed-A=true" }
225
+ { seqNum: "e1", parentSeqNum: "e0", name: "createTodo", args: { id: "A", text: "buy milk" }, clientId: "client-id", sessionId: "session-id", facts: "+todo-exists-A +todo-is-writeable-A=true +todo-completed-A=false" }
226
+ { seqNum: "e2", parentSeqNum: "e1", name: "createTodo", args: { id: "B", text: "buy bread" }, clientId: "client-id", sessionId: "session-id", facts: "+todo-exists-B +todo-is-writeable-B=true +todo-completed-B=false" }
227
+ { seqNum: "e3", parentSeqNum: "e2", name: "createTodo", args: { id: "C", text: "buy cheese" }, clientId: "client-id", sessionId: "session-id", facts: "+todo-exists-C +todo-is-writeable-C=true +todo-completed-C=false" }
228
+ { seqNum: "e5", parentSeqNum: "e3", name: "todoCompleteds", args: { ids: ["A", "B", "C"] }, clientId: "client-id", sessionId: "session-id", facts: "↖todo-exists-A ↖todo-is-writeable-A=true ↖todo-exists-B ↖todo-is-writeable-B=true ↖todo-exists-C ↖todo-is-writeable-C=true +todo-completed-A=true +todo-completed-B=true +todo-completed-C=true" }
229
+ { seqNum: "e7", parentSeqNum: "e5", name: "todoCompleted", args: { id: "A" }, clientId: "client-id", sessionId: "session-id", facts: "↖todo-exists-A ↖todo-is-writeable-A=true +todo-completed-A=true" }
230
230
  ]
231
231
  `)
232
232
  })