@livestore/common 0.3.0-dev.24 → 0.3.0-dev.26
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 -2
- package/dist/adapter-types.d.ts.map +1 -1
- package/dist/adapter-types.js +1 -1
- package/dist/adapter-types.js.map +1 -1
- package/dist/devtools/devtools-messages-client-session.d.ts +21 -21
- package/dist/devtools/devtools-messages-common.d.ts +6 -6
- package/dist/devtools/devtools-messages-leader.d.ts +24 -24
- package/dist/leader-thread/LeaderSyncProcessor.d.ts +2 -1
- package/dist/leader-thread/LeaderSyncProcessor.d.ts.map +1 -1
- package/dist/leader-thread/LeaderSyncProcessor.js +39 -37
- package/dist/leader-thread/LeaderSyncProcessor.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 +1 -0
- package/dist/leader-thread/make-leader-thread-layer.js.map +1 -1
- package/dist/leader-thread/mutationlog.d.ts +1 -0
- package/dist/leader-thread/mutationlog.d.ts.map +1 -1
- package/dist/leader-thread/mutationlog.js +1 -0
- package/dist/leader-thread/mutationlog.js.map +1 -1
- package/dist/schema/MutationEvent.d.ts +17 -1
- package/dist/schema/MutationEvent.d.ts.map +1 -1
- package/dist/schema/MutationEvent.js +18 -2
- package/dist/schema/MutationEvent.js.map +1 -1
- package/dist/sync/ClientSessionSyncProcessor.d.ts +2 -0
- package/dist/sync/ClientSessionSyncProcessor.d.ts.map +1 -1
- package/dist/sync/ClientSessionSyncProcessor.js +36 -33
- package/dist/sync/ClientSessionSyncProcessor.js.map +1 -1
- package/dist/sync/sync.d.ts +10 -0
- package/dist/sync/sync.d.ts.map +1 -1
- package/dist/sync/sync.js.map +1 -1
- package/dist/sync/syncstate.d.ts +38 -16
- package/dist/sync/syncstate.d.ts.map +1 -1
- package/dist/sync/syncstate.js +110 -40
- package/dist/sync/syncstate.js.map +1 -1
- package/dist/sync/syncstate.test.js +60 -29
- package/dist/sync/syncstate.test.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +2 -2
- package/src/adapter-types.ts +4 -2
- package/src/leader-thread/LeaderSyncProcessor.ts +42 -38
- package/src/leader-thread/make-leader-thread-layer.ts +1 -0
- package/src/leader-thread/mutationlog.ts +1 -0
- package/src/schema/MutationEvent.ts +18 -2
- package/src/sync/ClientSessionSyncProcessor.ts +39 -33
- package/src/sync/sync.ts +10 -0
- package/src/sync/syncstate.test.ts +72 -38
- package/src/sync/syncstate.ts +138 -58
- package/src/version.ts +1 -1
- package/tmp/pack.tgz +0 -0
package/src/sync/sync.ts
CHANGED
@@ -19,6 +19,16 @@ export type SyncOptions = {
|
|
19
19
|
backend?: SyncBackendConstructor<any>
|
20
20
|
/** @default { _tag: 'Skip' } */
|
21
21
|
initialSyncOptions?: InitialSyncOptions
|
22
|
+
/**
|
23
|
+
* What to do if there is an error during sync.
|
24
|
+
*
|
25
|
+
* Options:
|
26
|
+
* `shutdown` will stop the sync processor and cause the app to crash.
|
27
|
+
* `ignore` will log the error and let the app continue running acting as if it was offline.
|
28
|
+
*
|
29
|
+
* @default 'ignore'
|
30
|
+
* */
|
31
|
+
onSyncError?: 'shutdown' | 'ignore'
|
22
32
|
}
|
23
33
|
|
24
34
|
export type SyncBackendConstructor<TSyncMetadata = Schema.JsonValue> = (
|
@@ -39,22 +39,23 @@ const e_0_2 = new TestEvent({ global: 0, client: 2 }, e_0_1.id, 'a', true)
|
|
39
39
|
const e_0_3 = new TestEvent({ global: 0, client: 3 }, e_0_2.id, 'a', true)
|
40
40
|
const e_1_0 = new TestEvent({ global: 1, client: 0 }, e_0_0.id, 'a', false)
|
41
41
|
const e_1_1 = new TestEvent({ global: 1, client: 1 }, e_1_0.id, 'a', true)
|
42
|
+
const e_2_0 = new TestEvent({ global: 2, client: 0 }, e_1_0.id, 'a', false)
|
42
43
|
|
43
44
|
const isEqualEvent = MutationEvent.isEqualEncoded
|
44
45
|
|
45
|
-
const
|
46
|
+
const isClientEvent = (event: MutationEvent.EncodedWithMeta) => (event as TestEvent).isLocal
|
46
47
|
|
47
48
|
describe('syncstate', () => {
|
48
|
-
describe('
|
49
|
-
const
|
49
|
+
describe('merge', () => {
|
50
|
+
const update = ({
|
50
51
|
syncState,
|
51
52
|
payload,
|
52
|
-
|
53
|
+
ignoreClientEvents = false,
|
53
54
|
}: {
|
54
55
|
syncState: SyncState.SyncState
|
55
56
|
payload: typeof SyncState.Payload.Type
|
56
|
-
|
57
|
-
}) => SyncState.
|
57
|
+
ignoreClientEvents?: boolean
|
58
|
+
}) => SyncState.merge({ syncState, payload, isClientEvent, isEqualEvent, ignoreClientEvents })
|
58
59
|
|
59
60
|
describe.each([{ trimRollbackUntil: false }, { trimRollbackUntil: true }])(
|
60
61
|
'upstream-rebase (trimRollbackUntil: $trimRollbackUntil)',
|
@@ -68,7 +69,7 @@ describe('syncstate', () => {
|
|
68
69
|
})
|
69
70
|
const e_0_0_e_1_0 = e_0_0.rebase_(e_1_0.id)
|
70
71
|
const e_0_1_e_1_1 = e_0_1.rebase_(e_0_0_e_1_0.id)
|
71
|
-
const result =
|
72
|
+
const result = update({
|
72
73
|
syncState,
|
73
74
|
payload: {
|
74
75
|
_tag: 'upstream-rebase',
|
@@ -99,7 +100,7 @@ describe('syncstate', () => {
|
|
99
100
|
localHead: e_1_0.id,
|
100
101
|
})
|
101
102
|
const e_0_1_e_1_0 = e_0_1.rebase_(e_0_0.id)
|
102
|
-
const result =
|
103
|
+
const result = update({
|
103
104
|
syncState,
|
104
105
|
payload: {
|
105
106
|
_tag: 'upstream-rebase',
|
@@ -129,7 +130,7 @@ describe('syncstate', () => {
|
|
129
130
|
upstreamHead: EventId.ROOT,
|
130
131
|
localHead: e_0_0.id,
|
131
132
|
})
|
132
|
-
const result =
|
133
|
+
const result = update({
|
133
134
|
syncState,
|
134
135
|
payload: { _tag: 'upstream-rebase', rollbackUntil: e_0_0.id, newEvents: [e_1_0] },
|
135
136
|
})
|
@@ -148,7 +149,7 @@ describe('syncstate', () => {
|
|
148
149
|
upstreamHead: EventId.ROOT,
|
149
150
|
localHead: e_0_0.id,
|
150
151
|
})
|
151
|
-
const result =
|
152
|
+
const result = update({
|
152
153
|
syncState,
|
153
154
|
payload: { _tag: 'upstream-rebase', rollbackUntil: e_0_0.id, newEvents: [e_1_0] },
|
154
155
|
})
|
@@ -162,7 +163,7 @@ describe('syncstate', () => {
|
|
162
163
|
upstreamHead: EventId.ROOT,
|
163
164
|
localHead: e_0_0.id,
|
164
165
|
})
|
165
|
-
const result =
|
166
|
+
const result = update({
|
166
167
|
syncState,
|
167
168
|
payload: { _tag: 'upstream-rebase', rollbackUntil: e_0_0.id, newEvents: [] },
|
168
169
|
})
|
@@ -184,7 +185,7 @@ describe('syncstate', () => {
|
|
184
185
|
upstreamHead: EventId.ROOT,
|
185
186
|
localHead: e_0_0.id,
|
186
187
|
})
|
187
|
-
const result =
|
188
|
+
const result = update({ syncState, payload: { _tag: 'upstream-advance', newEvents: [e_0_1, e_0_0] } })
|
188
189
|
expect(result).toMatchObject({ _tag: 'unexpected-error' })
|
189
190
|
})
|
190
191
|
|
@@ -195,7 +196,40 @@ describe('syncstate', () => {
|
|
195
196
|
upstreamHead: EventId.ROOT,
|
196
197
|
localHead: e_0_0.id,
|
197
198
|
})
|
198
|
-
const result =
|
199
|
+
const result = update({ syncState, payload: { _tag: 'upstream-advance', newEvents: [e_1_0, e_0_0] } })
|
200
|
+
expect(result).toMatchObject({ _tag: 'unexpected-error' })
|
201
|
+
})
|
202
|
+
|
203
|
+
it('should throw error if incoming event is < expected upstream head', () => {
|
204
|
+
const syncState = new SyncState.SyncState({
|
205
|
+
pending: [],
|
206
|
+
rollbackTail: [],
|
207
|
+
upstreamHead: e_1_0.id,
|
208
|
+
localHead: e_1_0.id,
|
209
|
+
})
|
210
|
+
const result = update({ syncState, payload: { _tag: 'upstream-advance', newEvents: [e_0_0] } })
|
211
|
+
expect(result).toMatchObject({ _tag: 'unexpected-error' })
|
212
|
+
})
|
213
|
+
|
214
|
+
it('should throw error if incoming event is = expected upstream head', () => {
|
215
|
+
const syncState = new SyncState.SyncState({
|
216
|
+
pending: [],
|
217
|
+
rollbackTail: [],
|
218
|
+
upstreamHead: e_1_0.id,
|
219
|
+
localHead: e_1_0.id,
|
220
|
+
})
|
221
|
+
const result = update({ syncState, payload: { _tag: 'upstream-advance', newEvents: [e_1_0] } })
|
222
|
+
expect(result).toMatchObject({ _tag: 'unexpected-error' })
|
223
|
+
})
|
224
|
+
|
225
|
+
it('should throw if the parent id of the first incoming event is unknown', () => {
|
226
|
+
const syncState = new SyncState.SyncState({
|
227
|
+
pending: [],
|
228
|
+
rollbackTail: [e_0_0],
|
229
|
+
upstreamHead: EventId.ROOT,
|
230
|
+
localHead: e_0_0.id,
|
231
|
+
})
|
232
|
+
const result = update({ syncState, payload: { _tag: 'upstream-advance', newEvents: [e_2_0] } })
|
199
233
|
expect(result).toMatchObject({ _tag: 'unexpected-error' })
|
200
234
|
})
|
201
235
|
|
@@ -206,7 +240,7 @@ describe('syncstate', () => {
|
|
206
240
|
upstreamHead: EventId.ROOT,
|
207
241
|
localHead: e_0_0.id,
|
208
242
|
})
|
209
|
-
const result =
|
243
|
+
const result = update({ syncState, payload: { _tag: 'upstream-advance', newEvents: [e_0_0] } })
|
210
244
|
|
211
245
|
expectAdvance(result)
|
212
246
|
expectEventArraysEqual(result.newSyncState.pending, [])
|
@@ -223,7 +257,7 @@ describe('syncstate', () => {
|
|
223
257
|
upstreamHead: EventId.ROOT,
|
224
258
|
localHead: e_1_0.id,
|
225
259
|
})
|
226
|
-
const result =
|
260
|
+
const result = update({ syncState, payload: { _tag: 'upstream-advance', newEvents: [e_0_0] } })
|
227
261
|
|
228
262
|
expectAdvance(result)
|
229
263
|
expectEventArraysEqual(result.newSyncState.pending, [e_1_0])
|
@@ -240,7 +274,7 @@ describe('syncstate', () => {
|
|
240
274
|
upstreamHead: EventId.ROOT,
|
241
275
|
localHead: e_0_0.id,
|
242
276
|
})
|
243
|
-
const result =
|
277
|
+
const result = update({ syncState, payload: { _tag: 'upstream-advance', newEvents: [e_0_0, e_0_1] } })
|
244
278
|
|
245
279
|
expectAdvance(result)
|
246
280
|
expectEventArraysEqual(result.newSyncState.pending, [])
|
@@ -257,7 +291,7 @@ describe('syncstate', () => {
|
|
257
291
|
upstreamHead: e_0_0.id,
|
258
292
|
localHead: e_0_1.id,
|
259
293
|
})
|
260
|
-
const result =
|
294
|
+
const result = update({
|
261
295
|
syncState,
|
262
296
|
payload: { _tag: 'upstream-advance', newEvents: [e_0_1, e_0_2, e_0_3, e_1_0, e_1_1] },
|
263
297
|
})
|
@@ -277,10 +311,10 @@ describe('syncstate', () => {
|
|
277
311
|
upstreamHead: EventId.ROOT,
|
278
312
|
localHead: e_0_0.id,
|
279
313
|
})
|
280
|
-
const result =
|
314
|
+
const result = update({
|
281
315
|
syncState,
|
282
316
|
payload: { _tag: 'upstream-advance', newEvents: [e_0_0] },
|
283
|
-
|
317
|
+
ignoreClientEvents: true,
|
284
318
|
})
|
285
319
|
expectAdvance(result)
|
286
320
|
expectEventArraysEqual(result.newSyncState.pending, [])
|
@@ -297,10 +331,10 @@ describe('syncstate', () => {
|
|
297
331
|
upstreamHead: EventId.ROOT,
|
298
332
|
localHead: e_0_0.id,
|
299
333
|
})
|
300
|
-
const result =
|
334
|
+
const result = update({
|
301
335
|
syncState,
|
302
336
|
payload: { _tag: 'upstream-advance', newEvents: [e_0_0] },
|
303
|
-
|
337
|
+
ignoreClientEvents: true,
|
304
338
|
})
|
305
339
|
expectAdvance(result)
|
306
340
|
expectEventArraysEqual(result.newSyncState.pending, [e_1_0])
|
@@ -317,10 +351,10 @@ describe('syncstate', () => {
|
|
317
351
|
upstreamHead: EventId.ROOT,
|
318
352
|
localHead: e_0_1.id,
|
319
353
|
})
|
320
|
-
const result =
|
354
|
+
const result = update({
|
321
355
|
syncState,
|
322
356
|
payload: { _tag: 'upstream-advance', newEvents: [e_0_0, e_1_0] },
|
323
|
-
|
357
|
+
ignoreClientEvents: true,
|
324
358
|
})
|
325
359
|
|
326
360
|
expectAdvance(result)
|
@@ -338,7 +372,7 @@ describe('syncstate', () => {
|
|
338
372
|
upstreamHead: e_1_0.id,
|
339
373
|
localHead: e_1_0.id,
|
340
374
|
})
|
341
|
-
const result =
|
375
|
+
const result = update({ syncState, payload: { _tag: 'upstream-advance', newEvents: [e_0_0] } })
|
342
376
|
expect(result).toMatchObject({ _tag: 'unexpected-error' })
|
343
377
|
})
|
344
378
|
})
|
@@ -351,7 +385,7 @@ describe('syncstate', () => {
|
|
351
385
|
upstreamHead: EventId.ROOT,
|
352
386
|
localHead: e_0_0.id,
|
353
387
|
})
|
354
|
-
const result =
|
388
|
+
const result = update({ syncState, payload: { _tag: 'upstream-advance', newEvents: [e_0_1] } })
|
355
389
|
|
356
390
|
const e_0_0_e_0_2 = e_0_0.rebase_(e_0_1.id)
|
357
391
|
|
@@ -372,7 +406,7 @@ describe('syncstate', () => {
|
|
372
406
|
upstreamHead: EventId.ROOT,
|
373
407
|
localHead: e_0_0_b.id,
|
374
408
|
})
|
375
|
-
const result =
|
409
|
+
const result = update({ syncState, payload: { _tag: 'upstream-advance', newEvents: [e_0_0] } })
|
376
410
|
|
377
411
|
const e_0_0_e_1_0 = e_0_0_b.rebase_(e_0_0.id)
|
378
412
|
|
@@ -393,7 +427,7 @@ describe('syncstate', () => {
|
|
393
427
|
upstreamHead: EventId.ROOT,
|
394
428
|
localHead: e_1_0_b.id,
|
395
429
|
})
|
396
|
-
const result =
|
430
|
+
const result = update({ syncState, payload: { _tag: 'upstream-advance', newEvents: [e_1_0] } })
|
397
431
|
const e_1_0_e_2_0 = e_1_0_b.rebase_(e_1_0.id)
|
398
432
|
|
399
433
|
expectRebase(result)
|
@@ -412,7 +446,7 @@ describe('syncstate', () => {
|
|
412
446
|
upstreamHead: EventId.ROOT,
|
413
447
|
localHead: e_0_0.id,
|
414
448
|
})
|
415
|
-
const result =
|
449
|
+
const result = update({
|
416
450
|
syncState,
|
417
451
|
payload: { _tag: 'upstream-advance', newEvents: [e_0_1, e_0_2, e_0_3, e_1_0] },
|
418
452
|
})
|
@@ -433,7 +467,7 @@ describe('syncstate', () => {
|
|
433
467
|
upstreamHead: EventId.ROOT,
|
434
468
|
localHead: e_0_0.id,
|
435
469
|
})
|
436
|
-
const result =
|
470
|
+
const result = update({
|
437
471
|
syncState,
|
438
472
|
payload: { _tag: 'upstream-advance', newEvents: [e_0_0, e_0_2, e_0_3, e_1_0] },
|
439
473
|
})
|
@@ -456,7 +490,7 @@ describe('syncstate', () => {
|
|
456
490
|
upstreamHead: EventId.ROOT,
|
457
491
|
localHead: e_0_1.id,
|
458
492
|
})
|
459
|
-
const result =
|
493
|
+
const result = update({
|
460
494
|
syncState,
|
461
495
|
payload: { _tag: 'upstream-advance', newEvents: [e_0_1, e_0_2, e_0_3, e_1_0] },
|
462
496
|
})
|
@@ -482,7 +516,7 @@ describe('syncstate', () => {
|
|
482
516
|
upstreamHead: EventId.ROOT,
|
483
517
|
localHead: e_0_0.id,
|
484
518
|
})
|
485
|
-
const result =
|
519
|
+
const result = update({ syncState, payload: { _tag: 'local-push', newEvents: [e_0_1, e_0_2, e_0_3] } })
|
486
520
|
|
487
521
|
expectAdvance(result)
|
488
522
|
expectEventArraysEqual(result.newSyncState.pending, [e_0_0, e_0_1, e_0_2, e_0_3])
|
@@ -501,7 +535,7 @@ describe('syncstate', () => {
|
|
501
535
|
upstreamHead: EventId.ROOT,
|
502
536
|
localHead: e_0_1.id,
|
503
537
|
})
|
504
|
-
const result =
|
538
|
+
const result = update({ syncState, payload: { _tag: 'local-push', newEvents: [e_0_1, e_0_2] } })
|
505
539
|
|
506
540
|
expectReject(result)
|
507
541
|
expect(result.expectedMinimumId).toMatchObject(e_0_2.id)
|
@@ -526,19 +560,19 @@ const expectEventArraysEqual = (
|
|
526
560
|
}
|
527
561
|
|
528
562
|
function expectAdvance(
|
529
|
-
result: typeof SyncState.
|
530
|
-
): asserts result is typeof SyncState.
|
563
|
+
result: typeof SyncState.MergeResult.Type,
|
564
|
+
): asserts result is typeof SyncState.MergeResultAdvance.Type {
|
531
565
|
expect(result._tag).toBe('advance')
|
532
566
|
}
|
533
567
|
|
534
568
|
function expectRebase(
|
535
|
-
result: typeof SyncState.
|
536
|
-
): asserts result is typeof SyncState.
|
569
|
+
result: typeof SyncState.MergeResult.Type,
|
570
|
+
): asserts result is typeof SyncState.MergeResultRebase.Type {
|
537
571
|
expect(result._tag).toBe('rebase')
|
538
572
|
}
|
539
573
|
|
540
574
|
function expectReject(
|
541
|
-
result: typeof SyncState.
|
542
|
-
): asserts result is typeof SyncState.
|
575
|
+
result: typeof SyncState.MergeResult.Type,
|
576
|
+
): asserts result is typeof SyncState.MergeResultReject.Type {
|
543
577
|
expect(result._tag).toBe('reject')
|
544
578
|
}
|