@livestore/common 0.0.0-snapshot-2b8a9de3ec1a701aca891ebc2c98eb328274ae9e → 0.0.0-snapshot-2ef046b02334f52613d31dbe06af53487685edc0
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/.tsbuildinfo +1 -1
- package/dist/adapter-types.d.ts +4 -11
- package/dist/adapter-types.d.ts.map +1 -1
- package/dist/adapter-types.js +0 -6
- package/dist/adapter-types.js.map +1 -1
- package/dist/devtools/devtools-messages-common.d.ts +7 -0
- package/dist/devtools/devtools-messages-common.d.ts.map +1 -1
- package/dist/devtools/devtools-messages-common.js +6 -0
- package/dist/devtools/devtools-messages-common.js.map +1 -1
- package/dist/devtools/devtools-messages-leader.d.ts +1 -1
- package/dist/devtools/devtools-messages-leader.d.ts.map +1 -1
- package/dist/devtools/devtools-messages-leader.js +1 -2
- package/dist/devtools/devtools-messages-leader.js.map +1 -1
- package/dist/leader-thread/LeaderSyncProcessor.d.ts +15 -6
- package/dist/leader-thread/LeaderSyncProcessor.d.ts.map +1 -1
- package/dist/leader-thread/LeaderSyncProcessor.js +199 -189
- package/dist/leader-thread/LeaderSyncProcessor.js.map +1 -1
- package/dist/leader-thread/apply-mutation.d.ts +14 -9
- package/dist/leader-thread/apply-mutation.d.ts.map +1 -1
- package/dist/leader-thread/apply-mutation.js +43 -36
- package/dist/leader-thread/apply-mutation.js.map +1 -1
- package/dist/leader-thread/leader-worker-devtools.d.ts.map +1 -1
- package/dist/leader-thread/leader-worker-devtools.js +2 -5
- package/dist/leader-thread/leader-worker-devtools.js.map +1 -1
- package/dist/leader-thread/make-leader-thread-layer.d.ts.map +1 -1
- package/dist/leader-thread/make-leader-thread-layer.js +21 -33
- package/dist/leader-thread/make-leader-thread-layer.js.map +1 -1
- package/dist/leader-thread/mod.d.ts +1 -1
- package/dist/leader-thread/mod.d.ts.map +1 -1
- package/dist/leader-thread/mod.js +1 -1
- package/dist/leader-thread/mod.js.map +1 -1
- package/dist/leader-thread/mutationlog.d.ts +19 -3
- package/dist/leader-thread/mutationlog.d.ts.map +1 -1
- package/dist/leader-thread/mutationlog.js +105 -12
- package/dist/leader-thread/mutationlog.js.map +1 -1
- package/dist/leader-thread/recreate-db.d.ts.map +1 -1
- package/dist/leader-thread/recreate-db.js +4 -3
- package/dist/leader-thread/recreate-db.js.map +1 -1
- package/dist/leader-thread/types.d.ts +35 -19
- package/dist/leader-thread/types.d.ts.map +1 -1
- package/dist/leader-thread/types.js.map +1 -1
- package/dist/rehydrate-from-mutationlog.d.ts +5 -4
- package/dist/rehydrate-from-mutationlog.d.ts.map +1 -1
- package/dist/rehydrate-from-mutationlog.js +7 -9
- package/dist/rehydrate-from-mutationlog.js.map +1 -1
- package/dist/schema/EventId.d.ts +4 -0
- package/dist/schema/EventId.d.ts.map +1 -1
- package/dist/schema/EventId.js +7 -1
- package/dist/schema/EventId.js.map +1 -1
- package/dist/schema/MutationEvent.d.ts +78 -25
- package/dist/schema/MutationEvent.d.ts.map +1 -1
- package/dist/schema/MutationEvent.js +25 -12
- package/dist/schema/MutationEvent.js.map +1 -1
- package/dist/schema/schema.js +1 -1
- package/dist/schema/schema.js.map +1 -1
- package/dist/schema/system-tables.d.ts +67 -0
- package/dist/schema/system-tables.d.ts.map +1 -1
- package/dist/schema/system-tables.js +12 -1
- package/dist/schema/system-tables.js.map +1 -1
- package/dist/sync/ClientSessionSyncProcessor.d.ts +9 -1
- package/dist/sync/ClientSessionSyncProcessor.d.ts.map +1 -1
- package/dist/sync/ClientSessionSyncProcessor.js +23 -19
- package/dist/sync/ClientSessionSyncProcessor.js.map +1 -1
- package/dist/sync/sync.d.ts +6 -5
- package/dist/sync/sync.d.ts.map +1 -1
- package/dist/sync/sync.js.map +1 -1
- package/dist/sync/syncstate.d.ts +47 -71
- package/dist/sync/syncstate.d.ts.map +1 -1
- package/dist/sync/syncstate.js +76 -112
- package/dist/sync/syncstate.js.map +1 -1
- package/dist/sync/syncstate.test.js +67 -139
- package/dist/sync/syncstate.test.js.map +1 -1
- package/package.json +2 -2
- package/src/adapter-types.ts +3 -12
- package/src/devtools/devtools-messages-common.ts +9 -0
- package/src/devtools/devtools-messages-leader.ts +1 -2
- package/src/leader-thread/LeaderSyncProcessor.ts +372 -348
- package/src/leader-thread/apply-mutation.ts +81 -71
- package/src/leader-thread/leader-worker-devtools.ts +3 -8
- package/src/leader-thread/make-leader-thread-layer.ts +26 -41
- package/src/leader-thread/mod.ts +1 -1
- package/src/leader-thread/mutationlog.ts +166 -13
- package/src/leader-thread/recreate-db.ts +4 -3
- package/src/leader-thread/types.ts +34 -23
- package/src/rehydrate-from-mutationlog.ts +12 -12
- package/src/schema/EventId.ts +8 -1
- package/src/schema/MutationEvent.ts +32 -16
- package/src/schema/schema.ts +1 -1
- package/src/schema/system-tables.ts +20 -1
- package/src/sync/ClientSessionSyncProcessor.ts +33 -25
- package/src/sync/sync.ts +6 -9
- package/src/sync/syncstate.test.ts +130 -208
- package/src/sync/syncstate.ts +76 -123
- package/dist/leader-thread/pull-queue-set.d.ts +0 -7
- package/dist/leader-thread/pull-queue-set.d.ts.map +0 -1
- package/dist/leader-thread/pull-queue-set.js +0 -48
- package/dist/leader-thread/pull-queue-set.js.map +0 -1
- package/src/leader-thread/pull-queue-set.ts +0 -67
|
@@ -17,7 +17,6 @@ class TestEvent extends MutationEvent.EncodedWithMeta {
|
|
|
17
17
|
parentId: EventId.make(parentId),
|
|
18
18
|
mutation: 'a',
|
|
19
19
|
args: payload,
|
|
20
|
-
|
|
21
20
|
clientId: 'static-local-id',
|
|
22
21
|
sessionId: 'static-session-id',
|
|
23
22
|
})
|
|
@@ -47,7 +46,7 @@ const isClientEvent = (event: MutationEvent.EncodedWithMeta) => (event as TestEv
|
|
|
47
46
|
|
|
48
47
|
describe('syncstate', () => {
|
|
49
48
|
describe('merge', () => {
|
|
50
|
-
const
|
|
49
|
+
const merge = ({
|
|
51
50
|
syncState,
|
|
52
51
|
payload,
|
|
53
52
|
ignoreClientEvents = false,
|
|
@@ -57,301 +56,252 @@ describe('syncstate', () => {
|
|
|
57
56
|
ignoreClientEvents?: boolean
|
|
58
57
|
}) => SyncState.merge({ syncState, payload, isClientEvent, isEqualEvent, ignoreClientEvents })
|
|
59
58
|
|
|
60
|
-
describe
|
|
61
|
-
'
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
_tag: 'upstream-rebase',
|
|
76
|
-
rollbackUntil: e_0_0.id,
|
|
77
|
-
newEvents: [e_0_0_e_1_0, e_0_1_e_1_1],
|
|
78
|
-
trimRollbackUntil: trimRollbackUntil ? e_0_1_e_1_1.id : undefined,
|
|
79
|
-
},
|
|
80
|
-
})
|
|
81
|
-
const e_1_0_e_2_0 = e_1_0.rebase_(e_0_0_e_1_0.id)
|
|
82
|
-
expectRebase(result)
|
|
83
|
-
expectEventArraysEqual(result.newSyncState.pending, [e_1_0_e_2_0])
|
|
84
|
-
if (trimRollbackUntil) {
|
|
85
|
-
expectEventArraysEqual(result.newSyncState.rollbackTail, [])
|
|
86
|
-
} else {
|
|
87
|
-
expectEventArraysEqual(result.newSyncState.rollbackTail, [e_0_0_e_1_0, e_0_1_e_1_1])
|
|
88
|
-
}
|
|
89
|
-
expect(result.newSyncState.upstreamHead).toMatchObject(e_0_1_e_1_1.id)
|
|
90
|
-
expect(result.newSyncState.localHead).toMatchObject(e_1_0_e_2_0.id)
|
|
91
|
-
expectEventArraysEqual(result.newEvents, [e_0_0_e_1_0, e_0_1_e_1_1, e_1_0_e_2_0])
|
|
92
|
-
expectEventArraysEqual(result.eventsToRollback, [e_0_0, e_0_1, e_1_0])
|
|
93
|
-
})
|
|
94
|
-
|
|
95
|
-
it('should rollback only to specified point', () => {
|
|
96
|
-
const syncState = new SyncState.SyncState({
|
|
97
|
-
pending: [e_1_0],
|
|
98
|
-
rollbackTail: [e_0_0, e_0_1],
|
|
99
|
-
upstreamHead: EventId.ROOT,
|
|
100
|
-
localHead: e_1_0.id,
|
|
101
|
-
})
|
|
102
|
-
const e_0_1_e_1_0 = e_0_1.rebase_(e_0_0.id)
|
|
103
|
-
const result = update({
|
|
104
|
-
syncState,
|
|
105
|
-
payload: {
|
|
106
|
-
_tag: 'upstream-rebase',
|
|
107
|
-
rollbackUntil: e_0_1.id,
|
|
108
|
-
newEvents: [e_0_1_e_1_0],
|
|
109
|
-
trimRollbackUntil: trimRollbackUntil ? e_0_0.id : undefined,
|
|
110
|
-
},
|
|
111
|
-
})
|
|
112
|
-
const e_1_0_e_2_0 = e_1_0.rebase_(e_0_1_e_1_0.id)
|
|
113
|
-
expectRebase(result)
|
|
114
|
-
expectEventArraysEqual(result.newSyncState.pending, [e_1_0_e_2_0])
|
|
115
|
-
if (trimRollbackUntil) {
|
|
116
|
-
expectEventArraysEqual(result.newSyncState.rollbackTail, [e_0_1_e_1_0])
|
|
117
|
-
} else {
|
|
118
|
-
expectEventArraysEqual(result.newSyncState.rollbackTail, [e_0_0, e_0_1_e_1_0])
|
|
119
|
-
}
|
|
120
|
-
expect(result.newSyncState.upstreamHead).toMatchObject(e_0_1_e_1_0.id)
|
|
121
|
-
expect(result.newSyncState.localHead).toMatchObject(e_1_0_e_2_0.id)
|
|
122
|
-
expectEventArraysEqual(result.newEvents, [e_0_1_e_1_0, e_1_0_e_2_0])
|
|
123
|
-
expectEventArraysEqual(result.eventsToRollback, [e_0_1, e_1_0])
|
|
124
|
-
})
|
|
125
|
-
|
|
126
|
-
it('should work for empty pending', () => {
|
|
127
|
-
const syncState = new SyncState.SyncState({
|
|
128
|
-
pending: [],
|
|
129
|
-
rollbackTail: [e_0_0],
|
|
130
|
-
upstreamHead: EventId.ROOT,
|
|
131
|
-
localHead: e_0_0.id,
|
|
132
|
-
})
|
|
133
|
-
const result = update({
|
|
134
|
-
syncState,
|
|
135
|
-
payload: { _tag: 'upstream-rebase', rollbackUntil: e_0_0.id, newEvents: [e_1_0] },
|
|
136
|
-
})
|
|
137
|
-
expectRebase(result)
|
|
138
|
-
expectEventArraysEqual(result.newSyncState.pending, [])
|
|
139
|
-
expectEventArraysEqual(result.newSyncState.rollbackTail, [e_1_0])
|
|
140
|
-
expect(result.newSyncState.upstreamHead).toMatchObject(e_1_0.id)
|
|
141
|
-
expect(result.newSyncState.localHead).toMatchObject(e_1_0.id)
|
|
142
|
-
expect(result.newEvents).toStrictEqual([e_1_0])
|
|
143
|
-
})
|
|
144
|
-
|
|
145
|
-
it('should fail for empty rollback tail', () => {
|
|
146
|
-
const syncState = new SyncState.SyncState({
|
|
147
|
-
pending: [],
|
|
148
|
-
rollbackTail: [],
|
|
149
|
-
upstreamHead: EventId.ROOT,
|
|
150
|
-
localHead: e_0_0.id,
|
|
151
|
-
})
|
|
152
|
-
const result = update({
|
|
153
|
-
syncState,
|
|
154
|
-
payload: { _tag: 'upstream-rebase', rollbackUntil: e_0_0.id, newEvents: [e_1_0] },
|
|
155
|
-
})
|
|
156
|
-
expect(result).toMatchObject({ _tag: 'unexpected-error' })
|
|
59
|
+
describe('upstream-rebase', () => {
|
|
60
|
+
it('should rollback until start', () => {
|
|
61
|
+
const syncState = new SyncState.SyncState({
|
|
62
|
+
pending: [e_1_0],
|
|
63
|
+
upstreamHead: EventId.ROOT,
|
|
64
|
+
localHead: e_1_0.id,
|
|
65
|
+
})
|
|
66
|
+
const e_0_0_e_1_0 = e_0_0.rebase_(e_1_0.id)
|
|
67
|
+
const e_0_1_e_1_1 = e_0_1.rebase_(e_0_0_e_1_0.id)
|
|
68
|
+
const result = merge({
|
|
69
|
+
syncState,
|
|
70
|
+
payload: SyncState.PayloadUpstreamRebase.make({
|
|
71
|
+
rollbackEvents: [e_0_0, e_0_1],
|
|
72
|
+
newEvents: [e_0_0_e_1_0, e_0_1_e_1_1],
|
|
73
|
+
}),
|
|
157
74
|
})
|
|
75
|
+
const e_1_0_e_2_0 = e_1_0.rebase_(e_0_0_e_1_0.id)
|
|
76
|
+
expectRebase(result)
|
|
77
|
+
expectEventArraysEqual(result.newSyncState.pending, [e_1_0_e_2_0])
|
|
78
|
+
expect(result.newSyncState.upstreamHead).toMatchObject(e_0_1_e_1_1.id)
|
|
79
|
+
expect(result.newSyncState.localHead).toMatchObject(e_1_0_e_2_0.id)
|
|
80
|
+
expectEventArraysEqual(result.newEvents, [e_0_0_e_1_0, e_0_1_e_1_1, e_1_0_e_2_0])
|
|
81
|
+
expectEventArraysEqual(result.rollbackEvents, [e_0_0, e_0_1, e_1_0])
|
|
82
|
+
})
|
|
158
83
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
84
|
+
it('should rollback only to specified point', () => {
|
|
85
|
+
const syncState = new SyncState.SyncState({
|
|
86
|
+
pending: [e_1_0],
|
|
87
|
+
upstreamHead: EventId.ROOT,
|
|
88
|
+
localHead: e_1_0.id,
|
|
89
|
+
})
|
|
90
|
+
const e_0_1_e_1_0 = e_0_1.rebase_(e_0_0.id)
|
|
91
|
+
const result = merge({
|
|
92
|
+
syncState,
|
|
93
|
+
payload: SyncState.PayloadUpstreamRebase.make({
|
|
94
|
+
newEvents: [e_0_1_e_1_0],
|
|
95
|
+
rollbackEvents: [e_0_1],
|
|
96
|
+
}),
|
|
97
|
+
})
|
|
98
|
+
const e_1_0_e_2_0 = e_1_0.rebase_(e_0_1_e_1_0.id)
|
|
99
|
+
expectRebase(result)
|
|
100
|
+
expectEventArraysEqual(result.newSyncState.pending, [e_1_0_e_2_0])
|
|
101
|
+
expect(result.newSyncState.upstreamHead).toMatchObject(e_0_1_e_1_0.id)
|
|
102
|
+
expect(result.newSyncState.localHead).toMatchObject(e_1_0_e_2_0.id)
|
|
103
|
+
expectEventArraysEqual(result.newEvents, [e_0_1_e_1_0, e_1_0_e_2_0])
|
|
104
|
+
expectEventArraysEqual(result.rollbackEvents, [e_0_1, e_1_0])
|
|
105
|
+
})
|
|
106
|
+
|
|
107
|
+
it('should work for empty pending', () => {
|
|
108
|
+
const syncState = new SyncState.SyncState({
|
|
109
|
+
pending: [],
|
|
110
|
+
upstreamHead: EventId.ROOT,
|
|
111
|
+
localHead: e_0_0.id,
|
|
176
112
|
})
|
|
177
|
-
|
|
178
|
-
|
|
113
|
+
const result = merge({
|
|
114
|
+
syncState,
|
|
115
|
+
payload: SyncState.PayloadUpstreamRebase.make({ rollbackEvents: [e_0_0], newEvents: [e_1_0] }),
|
|
116
|
+
})
|
|
117
|
+
expectRebase(result)
|
|
118
|
+
expectEventArraysEqual(result.newSyncState.pending, [])
|
|
119
|
+
expect(result.newSyncState.upstreamHead).toMatchObject(e_1_0.id)
|
|
120
|
+
expect(result.newSyncState.localHead).toMatchObject(e_1_0.id)
|
|
121
|
+
expect(result.newEvents).toStrictEqual([e_1_0])
|
|
122
|
+
})
|
|
123
|
+
|
|
124
|
+
it('should work for empty incoming', () => {
|
|
125
|
+
const syncState = new SyncState.SyncState({
|
|
126
|
+
pending: [],
|
|
127
|
+
upstreamHead: EventId.ROOT,
|
|
128
|
+
localHead: e_0_0.id,
|
|
129
|
+
})
|
|
130
|
+
const result = merge({
|
|
131
|
+
syncState,
|
|
132
|
+
payload: SyncState.PayloadUpstreamRebase.make({ rollbackEvents: [e_0_0], newEvents: [] }),
|
|
133
|
+
})
|
|
134
|
+
expectRebase(result)
|
|
135
|
+
expectEventArraysEqual(result.newSyncState.pending, [])
|
|
136
|
+
expect(result.newSyncState.upstreamHead).toMatchObject(EventId.ROOT)
|
|
137
|
+
expect(result.newSyncState.localHead).toMatchObject(EventId.ROOT)
|
|
138
|
+
expectEventArraysEqual(result.newEvents, [])
|
|
139
|
+
})
|
|
140
|
+
})
|
|
179
141
|
|
|
180
142
|
describe('upstream-advance: advance', () => {
|
|
181
143
|
it('should throw error if newEvents are not sorted in ascending order by eventId (client)', () => {
|
|
182
144
|
const syncState = new SyncState.SyncState({
|
|
183
145
|
pending: [e_0_0],
|
|
184
|
-
rollbackTail: [],
|
|
185
146
|
upstreamHead: EventId.ROOT,
|
|
186
147
|
localHead: e_0_0.id,
|
|
187
148
|
})
|
|
188
|
-
const result =
|
|
149
|
+
const result = merge({ syncState, payload: { _tag: 'upstream-advance', newEvents: [e_0_1, e_0_0] } })
|
|
189
150
|
expect(result).toMatchObject({ _tag: 'unexpected-error' })
|
|
190
151
|
})
|
|
191
152
|
|
|
192
153
|
it('should throw error if newEvents are not sorted in ascending order by eventId (global)', () => {
|
|
193
154
|
const syncState = new SyncState.SyncState({
|
|
194
155
|
pending: [e_0_0],
|
|
195
|
-
rollbackTail: [],
|
|
196
156
|
upstreamHead: EventId.ROOT,
|
|
197
157
|
localHead: e_0_0.id,
|
|
198
158
|
})
|
|
199
|
-
const result =
|
|
159
|
+
const result = merge({ syncState, payload: { _tag: 'upstream-advance', newEvents: [e_1_0, e_0_0] } })
|
|
200
160
|
expect(result).toMatchObject({ _tag: 'unexpected-error' })
|
|
201
161
|
})
|
|
202
162
|
|
|
203
163
|
it('should throw error if incoming event is < expected upstream head', () => {
|
|
204
164
|
const syncState = new SyncState.SyncState({
|
|
205
165
|
pending: [],
|
|
206
|
-
rollbackTail: [],
|
|
207
166
|
upstreamHead: e_1_0.id,
|
|
208
167
|
localHead: e_1_0.id,
|
|
209
168
|
})
|
|
210
|
-
const result =
|
|
169
|
+
const result = merge({ syncState, payload: { _tag: 'upstream-advance', newEvents: [e_0_0] } })
|
|
211
170
|
expect(result).toMatchObject({ _tag: 'unexpected-error' })
|
|
212
171
|
})
|
|
213
172
|
|
|
214
173
|
it('should throw error if incoming event is = expected upstream head', () => {
|
|
215
174
|
const syncState = new SyncState.SyncState({
|
|
216
175
|
pending: [],
|
|
217
|
-
rollbackTail: [],
|
|
218
176
|
upstreamHead: e_1_0.id,
|
|
219
177
|
localHead: e_1_0.id,
|
|
220
178
|
})
|
|
221
|
-
const result =
|
|
179
|
+
const result = merge({ syncState, payload: { _tag: 'upstream-advance', newEvents: [e_1_0] } })
|
|
222
180
|
expect(result).toMatchObject({ _tag: 'unexpected-error' })
|
|
223
181
|
})
|
|
224
182
|
|
|
225
183
|
it('should throw if the parent id of the first incoming event is unknown', () => {
|
|
226
184
|
const syncState = new SyncState.SyncState({
|
|
227
185
|
pending: [],
|
|
228
|
-
rollbackTail: [e_0_0],
|
|
229
186
|
upstreamHead: EventId.ROOT,
|
|
230
187
|
localHead: e_0_0.id,
|
|
231
188
|
})
|
|
232
|
-
const result =
|
|
189
|
+
const result = merge({ syncState, payload: { _tag: 'upstream-advance', newEvents: [e_2_0] } })
|
|
233
190
|
expect(result).toMatchObject({ _tag: 'unexpected-error' })
|
|
234
191
|
})
|
|
235
192
|
|
|
236
|
-
it('should
|
|
193
|
+
it('should confirm pending event when receiving matching event', () => {
|
|
237
194
|
const syncState = new SyncState.SyncState({
|
|
238
195
|
pending: [e_0_0],
|
|
239
|
-
rollbackTail: [],
|
|
240
196
|
upstreamHead: EventId.ROOT,
|
|
241
197
|
localHead: e_0_0.id,
|
|
242
198
|
})
|
|
243
|
-
const result =
|
|
199
|
+
const result = merge({ syncState, payload: { _tag: 'upstream-advance', newEvents: [e_0_0] } })
|
|
244
200
|
|
|
245
201
|
expectAdvance(result)
|
|
246
202
|
expectEventArraysEqual(result.newSyncState.pending, [])
|
|
247
|
-
expectEventArraysEqual(result.newSyncState.rollbackTail, [e_0_0])
|
|
248
203
|
expect(result.newSyncState.upstreamHead).toMatchObject(e_0_0.id)
|
|
249
204
|
expect(result.newSyncState.localHead).toMatchObject(e_0_0.id)
|
|
250
|
-
|
|
205
|
+
expectEventArraysEqual(result.newEvents, [])
|
|
206
|
+
expectEventArraysEqual(result.confirmedEvents, [e_0_0])
|
|
251
207
|
})
|
|
252
208
|
|
|
253
|
-
it('should
|
|
209
|
+
it('should confirm partial pending event when receiving matching event', () => {
|
|
254
210
|
const syncState = new SyncState.SyncState({
|
|
255
211
|
pending: [e_0_0, e_1_0],
|
|
256
|
-
rollbackTail: [],
|
|
257
212
|
upstreamHead: EventId.ROOT,
|
|
258
213
|
localHead: e_1_0.id,
|
|
259
214
|
})
|
|
260
|
-
const result =
|
|
215
|
+
const result = merge({ syncState, payload: { _tag: 'upstream-advance', newEvents: [e_0_0] } })
|
|
261
216
|
|
|
262
217
|
expectAdvance(result)
|
|
263
218
|
expectEventArraysEqual(result.newSyncState.pending, [e_1_0])
|
|
264
|
-
expectEventArraysEqual(result.newSyncState.rollbackTail, [e_0_0])
|
|
265
219
|
expect(result.newSyncState.upstreamHead).toMatchObject(e_0_0.id)
|
|
266
220
|
expect(result.newSyncState.localHead).toMatchObject(e_1_0.id)
|
|
267
|
-
|
|
221
|
+
expectEventArraysEqual(result.newEvents, [])
|
|
222
|
+
expectEventArraysEqual(result.confirmedEvents, [e_0_0])
|
|
268
223
|
})
|
|
269
224
|
|
|
270
|
-
it('should
|
|
225
|
+
it('should confirm pending event and add new event', () => {
|
|
271
226
|
const syncState = new SyncState.SyncState({
|
|
272
227
|
pending: [e_0_0],
|
|
273
|
-
rollbackTail: [],
|
|
274
228
|
upstreamHead: EventId.ROOT,
|
|
275
229
|
localHead: e_0_0.id,
|
|
276
230
|
})
|
|
277
|
-
const result =
|
|
231
|
+
const result = merge({ syncState, payload: { _tag: 'upstream-advance', newEvents: [e_0_0, e_0_1] } })
|
|
278
232
|
|
|
279
233
|
expectAdvance(result)
|
|
280
234
|
expectEventArraysEqual(result.newSyncState.pending, [])
|
|
281
|
-
expectEventArraysEqual(result.newSyncState.rollbackTail, [e_0_0, e_0_1])
|
|
282
235
|
expect(result.newSyncState.upstreamHead).toMatchObject(e_0_1.id)
|
|
283
236
|
expect(result.newSyncState.localHead).toMatchObject(e_0_1.id)
|
|
284
237
|
expect(result.newEvents).toStrictEqual([e_0_1])
|
|
238
|
+
expectEventArraysEqual(result.confirmedEvents, [e_0_0])
|
|
285
239
|
})
|
|
286
240
|
|
|
287
|
-
it('should
|
|
241
|
+
it('should confirm pending event and add multiple new events', () => {
|
|
288
242
|
const syncState = new SyncState.SyncState({
|
|
289
243
|
pending: [e_0_1],
|
|
290
|
-
rollbackTail: [],
|
|
291
244
|
upstreamHead: e_0_0.id,
|
|
292
245
|
localHead: e_0_1.id,
|
|
293
246
|
})
|
|
294
|
-
const result =
|
|
247
|
+
const result = merge({
|
|
295
248
|
syncState,
|
|
296
249
|
payload: { _tag: 'upstream-advance', newEvents: [e_0_1, e_0_2, e_0_3, e_1_0, e_1_1] },
|
|
297
250
|
})
|
|
298
251
|
|
|
299
252
|
expectAdvance(result)
|
|
300
253
|
expectEventArraysEqual(result.newSyncState.pending, [])
|
|
301
|
-
expectEventArraysEqual(result.newSyncState.rollbackTail, [e_0_1, e_0_2, e_0_3, e_1_0, e_1_1])
|
|
302
254
|
expect(result.newSyncState.upstreamHead).toMatchObject(e_1_1.id)
|
|
303
255
|
expect(result.newSyncState.localHead).toMatchObject(e_1_1.id)
|
|
304
256
|
expect(result.newEvents).toStrictEqual([e_0_2, e_0_3, e_1_0, e_1_1])
|
|
257
|
+
expectEventArraysEqual(result.confirmedEvents, [e_0_1])
|
|
305
258
|
})
|
|
306
259
|
|
|
307
260
|
it('should ignore client events (incoming is subset of pending)', () => {
|
|
308
261
|
const syncState = new SyncState.SyncState({
|
|
309
262
|
pending: [e_r_1, e_0_0],
|
|
310
|
-
rollbackTail: [],
|
|
311
263
|
upstreamHead: EventId.ROOT,
|
|
312
264
|
localHead: e_0_0.id,
|
|
313
265
|
})
|
|
314
|
-
const result =
|
|
266
|
+
const result = merge({
|
|
315
267
|
syncState,
|
|
316
268
|
payload: { _tag: 'upstream-advance', newEvents: [e_0_0] },
|
|
317
269
|
ignoreClientEvents: true,
|
|
318
270
|
})
|
|
319
271
|
expectAdvance(result)
|
|
320
272
|
expectEventArraysEqual(result.newSyncState.pending, [])
|
|
321
|
-
expectEventArraysEqual(result.newSyncState.rollbackTail, [e_r_1, e_0_0])
|
|
322
273
|
expect(result.newSyncState.upstreamHead).toMatchObject(e_0_0.id)
|
|
323
274
|
expect(result.newSyncState.localHead).toMatchObject(e_0_0.id)
|
|
324
|
-
|
|
275
|
+
expectEventArraysEqual(result.newEvents, [])
|
|
276
|
+
expectEventArraysEqual(result.confirmedEvents, [e_r_1, e_0_0])
|
|
325
277
|
})
|
|
326
278
|
|
|
327
279
|
it('should ignore client events (incoming is subset of pending case 2)', () => {
|
|
328
280
|
const syncState = new SyncState.SyncState({
|
|
329
281
|
pending: [e_r_1, e_0_0, e_1_0],
|
|
330
|
-
rollbackTail: [],
|
|
331
282
|
upstreamHead: EventId.ROOT,
|
|
332
283
|
localHead: e_0_0.id,
|
|
333
284
|
})
|
|
334
|
-
const result =
|
|
285
|
+
const result = merge({
|
|
335
286
|
syncState,
|
|
336
287
|
payload: { _tag: 'upstream-advance', newEvents: [e_0_0] },
|
|
337
288
|
ignoreClientEvents: true,
|
|
338
289
|
})
|
|
339
290
|
expectAdvance(result)
|
|
340
291
|
expectEventArraysEqual(result.newSyncState.pending, [e_1_0])
|
|
341
|
-
expectEventArraysEqual(result.newSyncState.rollbackTail, [e_r_1, e_0_0])
|
|
342
292
|
expect(result.newSyncState.upstreamHead).toMatchObject(e_0_0.id)
|
|
343
293
|
expect(result.newSyncState.localHead).toMatchObject(e_1_0.id)
|
|
344
|
-
|
|
294
|
+
expectEventArraysEqual(result.newEvents, [])
|
|
295
|
+
expectEventArraysEqual(result.confirmedEvents, [e_r_1, e_0_0])
|
|
345
296
|
})
|
|
346
297
|
|
|
347
298
|
it('should ignore client events (incoming goes beyond pending)', () => {
|
|
348
299
|
const syncState = new SyncState.SyncState({
|
|
349
300
|
pending: [e_r_1, e_0_0, e_0_1],
|
|
350
|
-
rollbackTail: [],
|
|
351
301
|
upstreamHead: EventId.ROOT,
|
|
352
302
|
localHead: e_0_1.id,
|
|
353
303
|
})
|
|
354
|
-
const result =
|
|
304
|
+
const result = merge({
|
|
355
305
|
syncState,
|
|
356
306
|
payload: { _tag: 'upstream-advance', newEvents: [e_0_0, e_1_0] },
|
|
357
307
|
ignoreClientEvents: true,
|
|
@@ -359,20 +309,19 @@ describe('syncstate', () => {
|
|
|
359
309
|
|
|
360
310
|
expectAdvance(result)
|
|
361
311
|
expectEventArraysEqual(result.newSyncState.pending, [])
|
|
362
|
-
expectEventArraysEqual(result.newSyncState.rollbackTail, [e_r_1, e_0_0, e_0_1, e_1_0])
|
|
363
312
|
expect(result.newSyncState.upstreamHead).toMatchObject(e_1_0.id)
|
|
364
313
|
expect(result.newSyncState.localHead).toMatchObject(e_1_0.id)
|
|
365
314
|
expect(result.newEvents).toStrictEqual([e_1_0])
|
|
315
|
+
expectEventArraysEqual(result.confirmedEvents, [e_r_1, e_0_0, e_0_1])
|
|
366
316
|
})
|
|
367
317
|
|
|
368
318
|
it('should fail if incoming event is ≤ local head', () => {
|
|
369
319
|
const syncState = new SyncState.SyncState({
|
|
370
320
|
pending: [],
|
|
371
|
-
rollbackTail: [],
|
|
372
321
|
upstreamHead: e_1_0.id,
|
|
373
322
|
localHead: e_1_0.id,
|
|
374
323
|
})
|
|
375
|
-
const result =
|
|
324
|
+
const result = merge({ syncState, payload: { _tag: 'upstream-advance', newEvents: [e_0_0] } })
|
|
376
325
|
expect(result).toMatchObject({ _tag: 'unexpected-error' })
|
|
377
326
|
})
|
|
378
327
|
})
|
|
@@ -381,60 +330,35 @@ describe('syncstate', () => {
|
|
|
381
330
|
it('should rebase single client event to end', () => {
|
|
382
331
|
const syncState = new SyncState.SyncState({
|
|
383
332
|
pending: [e_0_0],
|
|
384
|
-
rollbackTail: [],
|
|
385
333
|
upstreamHead: EventId.ROOT,
|
|
386
334
|
localHead: e_0_0.id,
|
|
387
335
|
})
|
|
388
|
-
const result =
|
|
336
|
+
const result = merge({ syncState, payload: SyncState.PayloadUpstreamAdvance.make({ newEvents: [e_0_1] }) })
|
|
389
337
|
|
|
390
338
|
const e_0_0_e_0_2 = e_0_0.rebase_(e_0_1.id)
|
|
391
339
|
|
|
392
340
|
expectRebase(result)
|
|
393
341
|
expectEventArraysEqual(result.newSyncState.pending, [e_0_0_e_0_2])
|
|
394
|
-
expectEventArraysEqual(result.newSyncState.rollbackTail, [e_0_1])
|
|
395
342
|
expect(result.newSyncState.upstreamHead).toMatchObject(e_0_1.id)
|
|
396
343
|
expect(result.newSyncState.localHead).toMatchObject(e_0_0_e_0_2.id)
|
|
397
|
-
expectEventArraysEqual(result.
|
|
344
|
+
expectEventArraysEqual(result.rollbackEvents, [e_0_0])
|
|
398
345
|
expectEventArraysEqual(result.newEvents, [e_0_1, e_0_0_e_0_2])
|
|
399
346
|
})
|
|
400
347
|
|
|
401
|
-
it('should rebase different event with same id (no rollback tail)', () => {
|
|
402
|
-
const e_0_0_b = new TestEvent({ global: 0, client: 0 }, EventId.ROOT, '0_0_b', true)
|
|
403
|
-
const syncState = new SyncState.SyncState({
|
|
404
|
-
pending: [e_0_0_b],
|
|
405
|
-
rollbackTail: [],
|
|
406
|
-
upstreamHead: EventId.ROOT,
|
|
407
|
-
localHead: e_0_0_b.id,
|
|
408
|
-
})
|
|
409
|
-
const result = update({ syncState, payload: { _tag: 'upstream-advance', newEvents: [e_0_0] } })
|
|
410
|
-
|
|
411
|
-
const e_0_0_e_1_0 = e_0_0_b.rebase_(e_0_0.id)
|
|
412
|
-
|
|
413
|
-
expectRebase(result)
|
|
414
|
-
expectEventArraysEqual(result.newSyncState.pending, [e_0_0_e_1_0])
|
|
415
|
-
expectEventArraysEqual(result.newSyncState.rollbackTail, [e_0_0])
|
|
416
|
-
expectEventArraysEqual(result.newEvents, [e_0_0, e_0_0_e_1_0])
|
|
417
|
-
expectEventArraysEqual(result.eventsToRollback, [e_0_0_b])
|
|
418
|
-
expect(result.newSyncState.upstreamHead).toMatchObject(e_0_0.id)
|
|
419
|
-
expect(result.newSyncState.localHead).toMatchObject(e_0_0_e_1_0.id)
|
|
420
|
-
})
|
|
421
|
-
|
|
422
348
|
it('should rebase different event with same id', () => {
|
|
423
349
|
const e_1_0_b = new TestEvent({ global: 1, client: 0 }, e_0_0.id, '1_0_b', false)
|
|
424
350
|
const syncState = new SyncState.SyncState({
|
|
425
351
|
pending: [e_1_0_b],
|
|
426
|
-
rollbackTail: [e_0_0, e_0_1],
|
|
427
352
|
upstreamHead: EventId.ROOT,
|
|
428
353
|
localHead: e_1_0_b.id,
|
|
429
354
|
})
|
|
430
|
-
const result =
|
|
355
|
+
const result = merge({ syncState, payload: SyncState.PayloadUpstreamAdvance.make({ newEvents: [e_1_0] }) })
|
|
431
356
|
const e_1_0_e_2_0 = e_1_0_b.rebase_(e_1_0.id)
|
|
432
357
|
|
|
433
358
|
expectRebase(result)
|
|
434
359
|
expectEventArraysEqual(result.newSyncState.pending, [e_1_0_e_2_0])
|
|
435
|
-
expectEventArraysEqual(result.newSyncState.rollbackTail, [e_0_0, e_0_1, e_1_0])
|
|
436
360
|
expectEventArraysEqual(result.newEvents, [e_1_0, e_1_0_e_2_0])
|
|
437
|
-
expectEventArraysEqual(result.
|
|
361
|
+
expectEventArraysEqual(result.rollbackEvents, [e_1_0_b])
|
|
438
362
|
expect(result.newSyncState.upstreamHead).toMatchObject(e_1_0.id)
|
|
439
363
|
expect(result.newSyncState.localHead).toMatchObject(e_1_0_e_2_0.id)
|
|
440
364
|
})
|
|
@@ -442,20 +366,18 @@ describe('syncstate', () => {
|
|
|
442
366
|
it('should rebase single client event to end (more incoming events)', () => {
|
|
443
367
|
const syncState = new SyncState.SyncState({
|
|
444
368
|
pending: [e_0_0],
|
|
445
|
-
rollbackTail: [],
|
|
446
369
|
upstreamHead: EventId.ROOT,
|
|
447
370
|
localHead: e_0_0.id,
|
|
448
371
|
})
|
|
449
|
-
const result =
|
|
372
|
+
const result = merge({
|
|
450
373
|
syncState,
|
|
451
|
-
payload: {
|
|
374
|
+
payload: SyncState.PayloadUpstreamAdvance.make({ newEvents: [e_0_1, e_0_2, e_0_3, e_1_0] }),
|
|
452
375
|
})
|
|
453
376
|
|
|
454
377
|
const e_0_0_e_2_0 = e_0_0.rebase_(e_1_0.id)
|
|
455
378
|
|
|
456
379
|
expectRebase(result)
|
|
457
380
|
expectEventArraysEqual(result.newSyncState.pending, [e_0_0_e_2_0])
|
|
458
|
-
expectEventArraysEqual(result.newSyncState.rollbackTail, [e_0_1, e_0_2, e_0_3, e_1_0])
|
|
459
381
|
expect(result.newSyncState.upstreamHead).toMatchObject(e_1_0.id)
|
|
460
382
|
expect(result.newSyncState.localHead).toMatchObject(e_0_0_e_2_0.id)
|
|
461
383
|
})
|
|
@@ -463,21 +385,19 @@ describe('syncstate', () => {
|
|
|
463
385
|
it('should only rebase divergent events when first event matches', () => {
|
|
464
386
|
const syncState = new SyncState.SyncState({
|
|
465
387
|
pending: [e_0_0, e_0_1],
|
|
466
|
-
rollbackTail: [],
|
|
467
388
|
upstreamHead: EventId.ROOT,
|
|
468
389
|
localHead: e_0_0.id,
|
|
469
390
|
})
|
|
470
|
-
const result =
|
|
391
|
+
const result = merge({
|
|
471
392
|
syncState,
|
|
472
|
-
payload: {
|
|
393
|
+
payload: SyncState.PayloadUpstreamAdvance.make({ newEvents: [e_0_0, e_0_2, e_0_3, e_1_0] }),
|
|
473
394
|
})
|
|
474
395
|
|
|
475
396
|
const e_0_1_e_1_1 = e_0_1.rebase_(e_1_0.id)
|
|
476
397
|
|
|
477
398
|
expectRebase(result)
|
|
478
399
|
expectEventArraysEqual(result.newSyncState.pending, [e_0_1_e_1_1])
|
|
479
|
-
expectEventArraysEqual(result.
|
|
480
|
-
expectEventArraysEqual(result.eventsToRollback, [e_0_1])
|
|
400
|
+
expectEventArraysEqual(result.rollbackEvents, [e_0_1])
|
|
481
401
|
expectEventArraysEqual(result.newEvents, [e_0_2, e_0_3, e_1_0, e_0_1_e_1_1])
|
|
482
402
|
expect(result.newSyncState.upstreamHead).toMatchObject(e_1_0.id)
|
|
483
403
|
expect(result.newSyncState.localHead).toMatchObject(e_0_1_e_1_1.id)
|
|
@@ -486,13 +406,12 @@ describe('syncstate', () => {
|
|
|
486
406
|
it('should rebase all client events when incoming chain starts differently', () => {
|
|
487
407
|
const syncState = new SyncState.SyncState({
|
|
488
408
|
pending: [e_0_0, e_0_1],
|
|
489
|
-
rollbackTail: [],
|
|
490
409
|
upstreamHead: EventId.ROOT,
|
|
491
410
|
localHead: e_0_1.id,
|
|
492
411
|
})
|
|
493
|
-
const result =
|
|
412
|
+
const result = merge({
|
|
494
413
|
syncState,
|
|
495
|
-
payload: {
|
|
414
|
+
payload: SyncState.PayloadUpstreamAdvance.make({ newEvents: [e_0_1, e_0_2, e_0_3, e_1_0] }),
|
|
496
415
|
})
|
|
497
416
|
|
|
498
417
|
const e_0_0_e_1_1 = e_0_0.rebase_(e_1_0.id)
|
|
@@ -500,9 +419,8 @@ describe('syncstate', () => {
|
|
|
500
419
|
|
|
501
420
|
expectRebase(result)
|
|
502
421
|
expectEventArraysEqual(result.newSyncState.pending, [e_0_0_e_1_1, e_0_1_e_1_2])
|
|
503
|
-
expectEventArraysEqual(result.newSyncState.rollbackTail, [e_0_1, e_0_2, e_0_3, e_1_0])
|
|
504
422
|
expectEventArraysEqual(result.newEvents, [e_0_1, e_0_2, e_0_3, e_1_0, e_0_0_e_1_1, e_0_1_e_1_2])
|
|
505
|
-
expectEventArraysEqual(result.
|
|
423
|
+
expectEventArraysEqual(result.rollbackEvents, [e_0_0, e_0_1])
|
|
506
424
|
expect(result.newSyncState.upstreamHead).toMatchObject(e_1_0.id)
|
|
507
425
|
expect(result.newSyncState.localHead).toMatchObject(e_0_1_e_1_2.id)
|
|
508
426
|
})
|
|
@@ -512,18 +430,20 @@ describe('syncstate', () => {
|
|
|
512
430
|
it('should advance with new events', () => {
|
|
513
431
|
const syncState = new SyncState.SyncState({
|
|
514
432
|
pending: [e_0_0],
|
|
515
|
-
rollbackTail: [],
|
|
516
433
|
upstreamHead: EventId.ROOT,
|
|
517
434
|
localHead: e_0_0.id,
|
|
518
435
|
})
|
|
519
|
-
const result =
|
|
436
|
+
const result = merge({
|
|
437
|
+
syncState,
|
|
438
|
+
payload: SyncState.PayloadLocalPush.make({ newEvents: [e_0_1, e_0_2, e_0_3] }),
|
|
439
|
+
})
|
|
520
440
|
|
|
521
441
|
expectAdvance(result)
|
|
522
442
|
expectEventArraysEqual(result.newSyncState.pending, [e_0_0, e_0_1, e_0_2, e_0_3])
|
|
523
|
-
expectEventArraysEqual(result.newSyncState.rollbackTail, [])
|
|
524
443
|
expect(result.newSyncState.upstreamHead).toMatchObject(EventId.ROOT)
|
|
525
444
|
expect(result.newSyncState.localHead).toMatchObject(e_0_3.id)
|
|
526
445
|
expectEventArraysEqual(result.newEvents, [e_0_1, e_0_2, e_0_3])
|
|
446
|
+
expectEventArraysEqual(result.confirmedEvents, [])
|
|
527
447
|
})
|
|
528
448
|
})
|
|
529
449
|
|
|
@@ -531,11 +451,13 @@ describe('syncstate', () => {
|
|
|
531
451
|
it('should reject when new events are greater than pending events', () => {
|
|
532
452
|
const syncState = new SyncState.SyncState({
|
|
533
453
|
pending: [e_0_0, e_0_1],
|
|
534
|
-
rollbackTail: [],
|
|
535
454
|
upstreamHead: EventId.ROOT,
|
|
536
455
|
localHead: e_0_1.id,
|
|
537
456
|
})
|
|
538
|
-
const result =
|
|
457
|
+
const result = merge({
|
|
458
|
+
syncState,
|
|
459
|
+
payload: SyncState.PayloadLocalPush.make({ newEvents: [e_0_1, e_0_2] }),
|
|
460
|
+
})
|
|
539
461
|
|
|
540
462
|
expectReject(result)
|
|
541
463
|
expect(result.expectedMinimumId).toMatchObject(e_0_2.id)
|
|
@@ -568,7 +490,7 @@ function expectAdvance(
|
|
|
568
490
|
function expectRebase(
|
|
569
491
|
result: typeof SyncState.MergeResult.Type,
|
|
570
492
|
): asserts result is typeof SyncState.MergeResultRebase.Type {
|
|
571
|
-
expect(result._tag).toBe('rebase')
|
|
493
|
+
expect(result._tag, `Expected rebase, got ${result}`).toBe('rebase')
|
|
572
494
|
}
|
|
573
495
|
|
|
574
496
|
function expectReject(
|