@livestore/common 0.3.0-dev.27 → 0.3.0-dev.28

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 (33) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/devtools/devtools-messages-client-session.d.ts +21 -21
  3. package/dist/devtools/devtools-messages-common.d.ts +6 -6
  4. package/dist/devtools/devtools-messages-leader.d.ts +24 -24
  5. package/dist/leader-thread/LeaderSyncProcessor.d.ts +16 -3
  6. package/dist/leader-thread/LeaderSyncProcessor.d.ts.map +1 -1
  7. package/dist/leader-thread/LeaderSyncProcessor.js +65 -27
  8. package/dist/leader-thread/LeaderSyncProcessor.js.map +1 -1
  9. package/dist/leader-thread/make-leader-thread-layer.d.ts +15 -3
  10. package/dist/leader-thread/make-leader-thread-layer.d.ts.map +1 -1
  11. package/dist/leader-thread/make-leader-thread-layer.js +8 -1
  12. package/dist/leader-thread/make-leader-thread-layer.js.map +1 -1
  13. package/dist/schema/EventId.d.ts.map +1 -1
  14. package/dist/schema/EventId.js +5 -0
  15. package/dist/schema/EventId.js.map +1 -1
  16. package/dist/schema/MutationEvent.js +1 -1
  17. package/dist/schema/MutationEvent.js.map +1 -1
  18. package/dist/sync/syncstate.d.ts.map +1 -1
  19. package/dist/sync/syncstate.js +21 -15
  20. package/dist/sync/syncstate.js.map +1 -1
  21. package/dist/sync/syncstate.test.js +160 -170
  22. package/dist/sync/syncstate.test.js.map +1 -1
  23. package/dist/version.d.ts +1 -1
  24. package/dist/version.js +1 -1
  25. package/package.json +2 -2
  26. package/src/leader-thread/LeaderSyncProcessor.ts +105 -34
  27. package/src/leader-thread/make-leader-thread-layer.ts +34 -12
  28. package/src/schema/EventId.ts +6 -0
  29. package/src/schema/MutationEvent.ts +1 -1
  30. package/src/sync/syncstate.test.ts +160 -171
  31. package/src/sync/syncstate.ts +29 -19
  32. package/src/version.ts +1 -1
  33. package/tmp/pack.tgz +0 -0
@@ -1,4 +1,4 @@
1
- import { casesHandled, shouldNeverHappen } from '@livestore/utils'
1
+ import { casesHandled, LS_DEV, shouldNeverHappen } from '@livestore/utils'
2
2
  import { Match, ReadonlyArray, Schema } from '@livestore/utils/effect'
3
3
 
4
4
  import { UnexpectedError } from '../adapter-types.js'
@@ -172,11 +172,16 @@ export class MergeResult extends Schema.Union(
172
172
  MergeResultUnexpectedError,
173
173
  ) {}
174
174
 
175
- const unexpectedError = (cause: unknown): MergeResultUnexpectedError =>
176
- MergeResultUnexpectedError.make({
175
+ const unexpectedError = (cause: unknown): MergeResultUnexpectedError => {
176
+ if (LS_DEV) {
177
+ debugger
178
+ }
179
+
180
+ return MergeResultUnexpectedError.make({
177
181
  _tag: 'unexpected-error',
178
182
  cause: new UnexpectedError({ cause }),
179
183
  })
184
+ }
180
185
 
181
186
  // TODO Idea: call merge recursively through hierarchy levels
182
187
  /*
@@ -200,6 +205,7 @@ export const merge = ({
200
205
  ignoreClientEvents?: boolean
201
206
  }): typeof MergeResult.Type => {
202
207
  validateSyncState(syncState)
208
+ validatePayload(payload)
203
209
 
204
210
  const mergeContext = MergeContext.make({ payload, syncState })
205
211
 
@@ -269,17 +275,6 @@ export const merge = ({
269
275
  )
270
276
  }
271
277
 
272
- // Validate that the parent id of the first incoming event is known
273
- const knownEventGlobalIds = [...syncState.pending].flatMap((e) => [e.id.global, e.parentId.global])
274
- knownEventGlobalIds.push(syncState.upstreamHead.global)
275
- const firstNewEvent = payload.newEvents[0]!
276
- const hasUnknownParentId = knownEventGlobalIds.includes(firstNewEvent.parentId.global) === false
277
- if (hasUnknownParentId) {
278
- return unexpectedError(
279
- `Incoming events must have a known parent id. Received: [${payload.newEvents.map((e) => EventId.toString(e.id)).join(', ')}]`,
280
- )
281
- }
282
-
283
278
  const newUpstreamHead = payload.newEvents.at(-1)!.id
284
279
 
285
280
  const divergentPendingIndex = findDivergencePoint({
@@ -480,17 +475,30 @@ const rebaseEvents = ({
480
475
  */
481
476
  const _flattenMergeResults = (_updateResults: ReadonlyArray<MergeResult>) => {}
482
477
 
478
+ const validatePayload = (payload: typeof Payload.Type) => {
479
+ for (let i = 1; i < payload.newEvents.length; i++) {
480
+ if (EventId.isGreaterThanOrEqual(payload.newEvents[i - 1]!.id, payload.newEvents[i]!.id)) {
481
+ return unexpectedError(
482
+ `Events must be ordered in monotonically ascending order by eventId. Received: [${payload.newEvents.map((e) => EventId.toString(e.id)).join(', ')}]`,
483
+ )
484
+ }
485
+ }
486
+ }
487
+
483
488
  const validateSyncState = (syncState: SyncState) => {
484
489
  for (let i = 0; i < syncState.pending.length; i++) {
485
490
  const event = syncState.pending[i]!
486
491
  const nextEvent = syncState.pending[i + 1]
487
492
  if (nextEvent === undefined) break // Reached end of chain
488
493
 
489
- if (EventId.isGreaterThan(event.id, nextEvent.id)) {
490
- shouldNeverHappen('Events must be sorted in ascending order by eventId', {
491
- event,
492
- nextEvent,
493
- })
494
+ if (EventId.isGreaterThanOrEqual(event.id, nextEvent.id)) {
495
+ shouldNeverHappen(
496
+ `Events must be ordered in monotonically ascending order by eventId. Received: [${syncState.pending.map((e) => EventId.toString(e.id)).join(', ')}]`,
497
+ {
498
+ event,
499
+ nextEvent,
500
+ },
501
+ )
494
502
  }
495
503
 
496
504
  // If the global id has increased, then the client id must be 0
@@ -521,6 +529,8 @@ const validateSyncState = (syncState: SyncState) => {
521
529
  const validateMergeResult = (mergeResult: typeof MergeResult.Type) => {
522
530
  if (mergeResult._tag === 'unexpected-error' || mergeResult._tag === 'reject') return mergeResult
523
531
 
532
+ validateSyncState(mergeResult.newSyncState)
533
+
524
534
  // Ensure local head is always greater than or equal to upstream head
525
535
  if (EventId.isGreaterThan(mergeResult.newSyncState.upstreamHead, mergeResult.newSyncState.localHead)) {
526
536
  shouldNeverHappen('Local head must be greater than or equal to upstream head', {
package/src/version.ts CHANGED
@@ -2,7 +2,7 @@
2
2
  // import packageJson from '../package.json' with { type: 'json' }
3
3
  // export const liveStoreVersion = packageJson.version
4
4
 
5
- export const liveStoreVersion = '0.3.0-dev.27' as const
5
+ export const liveStoreVersion = '0.3.0-dev.28' as const
6
6
 
7
7
  /**
8
8
  * This version number is incremented whenever the internal storage format changes in a breaking way.
package/tmp/pack.tgz CHANGED
Binary file