@livestore/common 0.2.0-dev.2 → 0.3.0-dev.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/.tsbuildinfo +1 -1
- package/dist/__tests__/fixture.d.ts +163 -1
- package/dist/__tests__/fixture.d.ts.map +1 -1
- package/dist/__tests__/fixture.js +3 -1
- package/dist/__tests__/fixture.js.map +1 -1
- package/dist/adapter-types.d.ts +53 -38
- package/dist/adapter-types.d.ts.map +1 -1
- package/dist/adapter-types.js +5 -7
- package/dist/adapter-types.js.map +1 -1
- package/dist/bounded-collections.d.ts +2 -2
- package/dist/bounded-collections.d.ts.map +1 -1
- package/dist/debug-info.d.ts +13 -13
- package/dist/derived-mutations.d.ts +1 -1
- package/dist/derived-mutations.d.ts.map +1 -1
- package/dist/devtools/devtools-bridge.d.ts +2 -2
- package/dist/devtools/devtools-bridge.d.ts.map +1 -1
- package/dist/devtools/devtools-messages.d.ts +84 -196
- package/dist/devtools/devtools-messages.d.ts.map +1 -1
- package/dist/devtools/devtools-messages.js +55 -61
- package/dist/devtools/devtools-messages.js.map +1 -1
- package/dist/devtools/index.d.ts.map +1 -1
- package/dist/devtools/index.js +1 -2
- package/dist/devtools/index.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/init-singleton-tables.d.ts +1 -1
- package/dist/init-singleton-tables.d.ts.map +1 -1
- package/dist/leader-thread/apply-mutation.d.ts +8 -0
- package/dist/leader-thread/apply-mutation.d.ts.map +1 -0
- package/dist/leader-thread/apply-mutation.js +95 -0
- package/dist/leader-thread/apply-mutation.js.map +1 -0
- package/dist/leader-thread/connection.d.ts +11 -0
- package/dist/leader-thread/connection.d.ts.map +1 -0
- package/dist/leader-thread/connection.js +44 -0
- package/dist/leader-thread/connection.js.map +1 -0
- package/dist/leader-thread/leader-sync-processor.d.ts +47 -0
- package/dist/leader-thread/leader-sync-processor.d.ts.map +1 -0
- package/dist/leader-thread/leader-sync-processor.js +422 -0
- package/dist/leader-thread/leader-sync-processor.js.map +1 -0
- package/dist/leader-thread/leader-worker-devtools.d.ts +6 -0
- package/dist/leader-thread/leader-worker-devtools.d.ts.map +1 -0
- package/dist/leader-thread/leader-worker-devtools.js +216 -0
- package/dist/leader-thread/leader-worker-devtools.js.map +1 -0
- package/dist/leader-thread/make-leader-thread-layer.d.ts +20 -0
- package/dist/leader-thread/make-leader-thread-layer.d.ts.map +1 -0
- package/dist/leader-thread/make-leader-thread-layer.js +106 -0
- package/dist/leader-thread/make-leader-thread-layer.js.map +1 -0
- package/dist/leader-thread/mod.d.ts +7 -0
- package/dist/leader-thread/mod.d.ts.map +1 -0
- package/dist/leader-thread/mod.js +7 -0
- package/dist/leader-thread/mod.js.map +1 -0
- package/dist/leader-thread/mutationlog.d.ts +23 -0
- package/dist/leader-thread/mutationlog.d.ts.map +1 -0
- package/dist/leader-thread/mutationlog.js +27 -0
- package/dist/leader-thread/mutationlog.js.map +1 -0
- package/dist/leader-thread/pull-queue-set.d.ts +7 -0
- package/dist/leader-thread/pull-queue-set.d.ts.map +1 -0
- package/dist/leader-thread/pull-queue-set.js +39 -0
- package/dist/leader-thread/pull-queue-set.js.map +1 -0
- package/dist/leader-thread/recreate-db.d.ts +7 -0
- package/dist/leader-thread/recreate-db.d.ts.map +1 -0
- package/dist/leader-thread/recreate-db.js +69 -0
- package/dist/leader-thread/recreate-db.js.map +1 -0
- package/dist/leader-thread/shutdown-channel.d.ts +15 -0
- package/dist/leader-thread/shutdown-channel.d.ts.map +1 -0
- package/dist/leader-thread/shutdown-channel.js +7 -0
- package/dist/leader-thread/shutdown-channel.js.map +1 -0
- package/dist/leader-thread/types.d.ts +87 -0
- package/dist/leader-thread/types.d.ts.map +1 -0
- package/dist/leader-thread/types.js +11 -0
- package/dist/leader-thread/types.js.map +1 -0
- package/dist/mutation.d.ts +3 -4
- package/dist/mutation.d.ts.map +1 -1
- package/dist/mutation.js +0 -14
- package/dist/mutation.js.map +1 -1
- package/dist/otel.d.ts +7 -0
- package/dist/otel.d.ts.map +1 -0
- package/dist/otel.js +11 -0
- package/dist/otel.js.map +1 -0
- package/dist/query-builder/api.d.ts +2 -2
- package/dist/query-builder/api.d.ts.map +1 -1
- package/dist/query-builder/api.js.map +1 -1
- package/dist/query-builder/impl.d.ts +1 -1
- package/dist/query-builder/impl.d.ts.map +1 -1
- package/dist/query-builder/impl.js +23 -5
- package/dist/query-builder/impl.js.map +1 -1
- package/dist/query-builder/impl.test.js +30 -1
- package/dist/query-builder/impl.test.js.map +1 -1
- package/dist/query-info.d.ts +1 -1
- package/dist/query-info.d.ts.map +1 -1
- package/dist/rehydrate-from-mutationlog.d.ts +1 -1
- package/dist/rehydrate-from-mutationlog.d.ts.map +1 -1
- package/dist/rehydrate-from-mutationlog.js +6 -6
- package/dist/rehydrate-from-mutationlog.js.map +1 -1
- package/dist/schema/EventId.d.ts +37 -0
- package/dist/schema/EventId.d.ts.map +1 -0
- package/dist/schema/EventId.js +30 -0
- package/dist/schema/EventId.js.map +1 -0
- package/dist/schema/MutationEvent.d.ts +191 -0
- package/dist/schema/MutationEvent.d.ts.map +1 -0
- package/dist/schema/MutationEvent.js +56 -0
- package/dist/schema/MutationEvent.js.map +1 -0
- package/dist/schema/mod.d.ts +8 -0
- package/dist/schema/mod.d.ts.map +1 -0
- package/dist/schema/mod.js +8 -0
- package/dist/schema/mod.js.map +1 -0
- package/dist/schema/mutations.d.ts +3 -123
- package/dist/schema/mutations.d.ts.map +1 -1
- package/dist/schema/mutations.js +0 -26
- package/dist/schema/mutations.js.map +1 -1
- package/dist/schema/{index.d.ts → schema.d.ts} +1 -5
- package/dist/schema/schema.d.ts.map +1 -0
- package/dist/schema/{index.js → schema.js} +1 -5
- package/dist/schema/schema.js.map +1 -0
- package/dist/schema/system-tables.d.ts +55 -29
- package/dist/schema/system-tables.d.ts.map +1 -1
- package/dist/schema/system-tables.js +10 -5
- package/dist/schema/system-tables.js.map +1 -1
- package/dist/schema-management/migrations.d.ts +1 -1
- package/dist/schema-management/migrations.d.ts.map +1 -1
- package/dist/schema-management/migrations.js +6 -1
- package/dist/schema-management/migrations.js.map +1 -1
- package/dist/schema-management/validate-mutation-defs.d.ts +1 -1
- package/dist/schema-management/validate-mutation-defs.d.ts.map +1 -1
- package/dist/sync/client-session-sync-processor.d.ts +45 -0
- package/dist/sync/client-session-sync-processor.d.ts.map +1 -0
- package/dist/sync/client-session-sync-processor.js +131 -0
- package/dist/sync/client-session-sync-processor.js.map +1 -0
- package/dist/sync/index.d.ts +2 -0
- package/dist/sync/index.d.ts.map +1 -1
- package/dist/sync/index.js +2 -0
- package/dist/sync/index.js.map +1 -1
- package/dist/sync/next/compact-events.d.ts +1 -1
- package/dist/sync/next/compact-events.d.ts.map +1 -1
- package/dist/sync/next/compact-events.js +2 -1
- package/dist/sync/next/compact-events.js.map +1 -1
- package/dist/sync/next/facts.d.ts +5 -5
- package/dist/sync/next/facts.d.ts.map +1 -1
- package/dist/sync/next/facts.js +1 -1
- package/dist/sync/next/facts.js.map +1 -1
- package/dist/sync/next/history-dag-common.d.ts +30 -0
- package/dist/sync/next/history-dag-common.d.ts.map +1 -0
- package/dist/sync/next/history-dag-common.js +20 -0
- package/dist/sync/next/history-dag-common.js.map +1 -0
- package/dist/sync/next/history-dag.d.ts +4 -27
- package/dist/sync/next/history-dag.d.ts.map +1 -1
- package/dist/sync/next/history-dag.js +1 -19
- package/dist/sync/next/history-dag.js.map +1 -1
- package/dist/sync/next/mod.d.ts +1 -0
- package/dist/sync/next/mod.d.ts.map +1 -1
- package/dist/sync/next/mod.js +1 -0
- package/dist/sync/next/mod.js.map +1 -1
- package/dist/sync/next/rebase-events.d.ts +3 -2
- package/dist/sync/next/rebase-events.d.ts.map +1 -1
- package/dist/sync/next/rebase-events.js.map +1 -1
- package/dist/sync/next/test/compact-events.test.d.ts.map +1 -1
- package/dist/sync/next/test/compact-events.test.js +2 -1
- package/dist/sync/next/test/compact-events.test.js.map +1 -1
- package/dist/sync/next/test/mutation-fixtures.d.ts +1 -1
- package/dist/sync/next/test/mutation-fixtures.d.ts.map +1 -1
- package/dist/sync/next/test/mutation-fixtures.js +4 -3
- package/dist/sync/next/test/mutation-fixtures.js.map +1 -1
- package/dist/sync/sync.d.ts +33 -12
- package/dist/sync/sync.d.ts.map +1 -1
- package/dist/sync/sync.js +10 -1
- package/dist/sync/sync.js.map +1 -1
- package/dist/sync/syncstate.d.ts +123 -0
- package/dist/sync/syncstate.d.ts.map +1 -0
- package/dist/sync/syncstate.js +248 -0
- package/dist/sync/syncstate.js.map +1 -0
- package/dist/sync/syncstate.test.d.ts +2 -0
- package/dist/sync/syncstate.test.d.ts.map +1 -0
- package/dist/sync/syncstate.test.js +399 -0
- package/dist/sync/syncstate.test.js.map +1 -0
- package/dist/sync/validate-push-payload.d.ts +5 -0
- package/dist/sync/validate-push-payload.d.ts.map +1 -0
- package/dist/sync/validate-push-payload.js +15 -0
- package/dist/sync/validate-push-payload.js.map +1 -0
- package/dist/util.d.ts +2 -2
- package/dist/util.d.ts.map +1 -1
- package/dist/version.d.ts +2 -2
- package/dist/version.d.ts.map +1 -1
- package/dist/version.js +2 -2
- package/dist/version.js.map +1 -1
- package/package.json +13 -6
- package/src/__tests__/fixture.ts +5 -1
- package/src/adapter-types.ts +60 -34
- package/src/derived-mutations.test.ts +1 -1
- package/src/derived-mutations.ts +1 -1
- package/src/devtools/devtools-bridge.ts +2 -2
- package/src/devtools/devtools-messages.ts +70 -74
- package/src/devtools/index.ts +1 -2
- package/src/index.ts +2 -1
- package/src/init-singleton-tables.ts +1 -1
- package/src/leader-thread/apply-mutation.ts +143 -0
- package/src/leader-thread/connection.ts +67 -0
- package/src/leader-thread/leader-sync-processor.ts +666 -0
- package/src/leader-thread/leader-worker-devtools.ts +358 -0
- package/src/leader-thread/make-leader-thread-layer.ts +192 -0
- package/src/leader-thread/mod.ts +6 -0
- package/src/leader-thread/mutationlog.ts +42 -0
- package/src/leader-thread/pull-queue-set.ts +58 -0
- package/src/leader-thread/recreate-db.ts +109 -0
- package/src/leader-thread/shutdown-channel.ts +13 -0
- package/src/leader-thread/types.ts +129 -0
- package/src/mutation.ts +3 -21
- package/src/otel.ts +20 -0
- package/src/query-builder/api.ts +3 -2
- package/src/query-builder/impl.test.ts +35 -1
- package/src/query-builder/impl.ts +23 -6
- package/src/query-info.ts +1 -1
- package/src/rehydrate-from-mutationlog.ts +7 -11
- package/src/schema/EventId.ts +46 -0
- package/src/schema/MutationEvent.ts +161 -0
- package/src/schema/mod.ts +7 -0
- package/src/schema/mutations.ts +5 -126
- package/src/schema/{index.ts → schema.ts} +0 -5
- package/src/schema/system-tables.ts +18 -5
- package/src/schema-management/migrations.ts +9 -2
- package/src/schema-management/validate-mutation-defs.ts +1 -1
- package/src/sync/client-session-sync-processor.ts +207 -0
- package/src/sync/index.ts +2 -0
- package/src/sync/next/compact-events.ts +3 -2
- package/src/sync/next/facts.ts +11 -5
- package/src/sync/next/history-dag-common.ts +44 -0
- package/src/sync/next/history-dag.ts +3 -45
- package/src/sync/next/mod.ts +1 -0
- package/src/sync/next/rebase-events.ts +6 -5
- package/src/sync/next/test/compact-events.test.ts +3 -2
- package/src/sync/next/test/mutation-fixtures.ts +7 -6
- package/src/sync/sync.ts +32 -12
- package/src/sync/syncstate.test.ts +464 -0
- package/src/sync/syncstate.ts +385 -0
- package/src/sync/validate-push-payload.ts +18 -0
- package/src/version.ts +2 -2
- package/dist/schema/index.d.ts.map +0 -1
- package/dist/schema/index.js.map +0 -1
- package/dist/sync/next-mutation-event-id-pair.d.ts +0 -14
- package/dist/sync/next-mutation-event-id-pair.d.ts.map +0 -1
- package/dist/sync/next-mutation-event-id-pair.js +0 -13
- package/dist/sync/next-mutation-event-id-pair.js.map +0 -1
- package/src/sync/next-mutation-event-id-pair.ts +0 -20
@@ -0,0 +1,385 @@
|
|
1
|
+
import { shouldNeverHappen } from '@livestore/utils'
|
2
|
+
import { ReadonlyArray, Schema } from '@livestore/utils/effect'
|
3
|
+
|
4
|
+
import * as EventId from '../schema/EventId.js'
|
5
|
+
import * as MutationEvent from '../schema/MutationEvent.js'
|
6
|
+
|
7
|
+
/**
|
8
|
+
* SyncState represents the current sync state of a sync node relative to an upstream node.
|
9
|
+
* Events flow from local to upstream, with each state maintaining its own event head.
|
10
|
+
*
|
11
|
+
* Event Chain Structure:
|
12
|
+
* ```
|
13
|
+
* +-------------------------+------------------------+
|
14
|
+
* | ROLLBACK TAIL | PENDING EVENTS |
|
15
|
+
* +-------------------------+------------------------+
|
16
|
+
* ▼ ▼
|
17
|
+
* Upstream Head Local Head
|
18
|
+
* Example: (0,0), (0,1), (1,0) (1,1), (1,2), (2,0)
|
19
|
+
* ```
|
20
|
+
*
|
21
|
+
* State:
|
22
|
+
* - **Pending Events**: Events awaiting acknowledgment from the upstream.
|
23
|
+
* - Can be confirmed or rejected by the upstream.
|
24
|
+
* - Subject to rebase if rejected.
|
25
|
+
* - **Rollback Tail**: Events that are kept around temporarily for potential rollback until confirmed by upstream.
|
26
|
+
*
|
27
|
+
* Payloads:
|
28
|
+
* - `PayloadUpstreamRebase`: Upstream has performed a rebase, so downstream must roll back to the specified event
|
29
|
+
* and rebase the pending events on top of the new events.
|
30
|
+
* - `PayloadUpstreamAdvance`: Upstream has advanced, so downstream must rebase the pending events on top of the new events.
|
31
|
+
* - `PayloadUpstreamTrimRollbackTail`: Upstream has advanced, so downstream can trim the rollback tail.
|
32
|
+
* - `PayloadLocalPush`: Local push payload
|
33
|
+
*
|
34
|
+
* Invariants:
|
35
|
+
* 1. **Chain Continuity**: Each event must reference its immediate parent.
|
36
|
+
* 2. **Head Ordering**: Upstream Head ≤ Local Head.
|
37
|
+
* 3. **ID Sequence**: Must follow the pattern (1,0)→(1,1)→(1,2)→(2,0).
|
38
|
+
*
|
39
|
+
* The `updateSyncState` function processes updates to the sync state based on incoming payloads,
|
40
|
+
* handling cases such as upstream rebase, advance, local push, and rollback tail trimming.
|
41
|
+
*/
|
42
|
+
export interface SyncState {
|
43
|
+
pending: ReadonlyArray<MutationEvent.EncodedWithMeta>
|
44
|
+
rollbackTail: ReadonlyArray<MutationEvent.EncodedWithMeta>
|
45
|
+
upstreamHead: EventId.EventId
|
46
|
+
localHead: EventId.EventId
|
47
|
+
}
|
48
|
+
|
49
|
+
export const SyncState = Schema.Struct({
|
50
|
+
pending: Schema.Array(MutationEvent.EncodedWithMeta),
|
51
|
+
rollbackTail: Schema.Array(MutationEvent.EncodedWithMeta),
|
52
|
+
upstreamHead: EventId.EventId,
|
53
|
+
localHead: EventId.EventId,
|
54
|
+
}).annotations({ title: 'SyncState' })
|
55
|
+
|
56
|
+
export class PayloadUpstreamRebase extends Schema.TaggedStruct('upstream-rebase', {
|
57
|
+
/** Rollback until this event in the rollback tail (inclusive). Starting from the end of the rollback tail. */
|
58
|
+
rollbackUntil: EventId.EventId,
|
59
|
+
newEvents: Schema.Array(MutationEvent.EncodedWithMeta),
|
60
|
+
/** Trim rollback tail up to this event (inclusive). */
|
61
|
+
trimRollbackUntil: Schema.optional(EventId.EventId),
|
62
|
+
}) {}
|
63
|
+
|
64
|
+
export class PayloadUpstreamAdvance extends Schema.TaggedStruct('upstream-advance', {
|
65
|
+
newEvents: Schema.Array(MutationEvent.EncodedWithMeta),
|
66
|
+
/** Trim rollback tail up to this event (inclusive). */
|
67
|
+
trimRollbackUntil: Schema.optional(EventId.EventId),
|
68
|
+
}) {}
|
69
|
+
|
70
|
+
export class PayloadLocalPush extends Schema.TaggedStruct('local-push', {
|
71
|
+
newEvents: Schema.Array(MutationEvent.EncodedWithMeta),
|
72
|
+
}) {}
|
73
|
+
|
74
|
+
export class Payload extends Schema.Union(PayloadUpstreamRebase, PayloadUpstreamAdvance, PayloadLocalPush) {}
|
75
|
+
|
76
|
+
export const PayloadUpstream = Schema.Union(PayloadUpstreamRebase, PayloadUpstreamAdvance)
|
77
|
+
|
78
|
+
export type PayloadUpstream = typeof PayloadUpstream.Type
|
79
|
+
|
80
|
+
export type UpdateResultAdvance = {
|
81
|
+
_tag: 'advance'
|
82
|
+
newSyncState: SyncState
|
83
|
+
previousSyncState: SyncState
|
84
|
+
/** Events which weren't pending before the update */
|
85
|
+
newEvents: ReadonlyArray<MutationEvent.EncodedWithMeta>
|
86
|
+
}
|
87
|
+
|
88
|
+
export type UpdateResultRebase = {
|
89
|
+
_tag: 'rebase'
|
90
|
+
newSyncState: SyncState
|
91
|
+
previousSyncState: SyncState
|
92
|
+
/** Events which weren't pending before the update */
|
93
|
+
newEvents: ReadonlyArray<MutationEvent.EncodedWithMeta>
|
94
|
+
eventsToRollback: ReadonlyArray<MutationEvent.EncodedWithMeta>
|
95
|
+
}
|
96
|
+
|
97
|
+
export type UpdateResultReject = {
|
98
|
+
_tag: 'reject'
|
99
|
+
previousSyncState: SyncState
|
100
|
+
/** The minimum id that the new events must have */
|
101
|
+
expectedMinimumId: EventId.EventId
|
102
|
+
}
|
103
|
+
|
104
|
+
export type UpdateResult = UpdateResultAdvance | UpdateResultRebase | UpdateResultReject
|
105
|
+
|
106
|
+
export const updateSyncState = ({
|
107
|
+
syncState,
|
108
|
+
payload,
|
109
|
+
isLocalEvent,
|
110
|
+
isEqualEvent,
|
111
|
+
ignoreLocalEvents = false,
|
112
|
+
}: {
|
113
|
+
syncState: SyncState
|
114
|
+
payload: typeof Payload.Type
|
115
|
+
isLocalEvent: (event: MutationEvent.EncodedWithMeta) => boolean
|
116
|
+
isEqualEvent: (a: MutationEvent.EncodedWithMeta, b: MutationEvent.EncodedWithMeta) => boolean
|
117
|
+
/** This is used in the leader which should ignore local events when receiving an upstream-advance payload */
|
118
|
+
ignoreLocalEvents?: boolean
|
119
|
+
}): UpdateResult => {
|
120
|
+
const trimRollbackTail = (
|
121
|
+
rollbackTail: ReadonlyArray<MutationEvent.EncodedWithMeta>,
|
122
|
+
): ReadonlyArray<MutationEvent.EncodedWithMeta> => {
|
123
|
+
const trimRollbackUntil = payload._tag === 'local-push' ? undefined : payload.trimRollbackUntil
|
124
|
+
if (trimRollbackUntil === undefined) return rollbackTail
|
125
|
+
const index = rollbackTail.findIndex((event) => EventId.isEqual(event.id, trimRollbackUntil))
|
126
|
+
if (index === -1) return []
|
127
|
+
return rollbackTail.slice(index + 1)
|
128
|
+
}
|
129
|
+
|
130
|
+
switch (payload._tag) {
|
131
|
+
case 'upstream-rebase': {
|
132
|
+
// Find the index of the rollback event in the rollback tail
|
133
|
+
const rollbackIndex = syncState.rollbackTail.findIndex((event) =>
|
134
|
+
EventId.isEqual(event.id, payload.rollbackUntil),
|
135
|
+
)
|
136
|
+
if (rollbackIndex === -1) {
|
137
|
+
return shouldNeverHappen(
|
138
|
+
`Rollback event not found in rollback tail. Rollback until: [${payload.rollbackUntil.global},${payload.rollbackUntil.local}]. Rollback tail: [${syncState.rollbackTail.map((e) => e.toString()).join(', ')}]`,
|
139
|
+
)
|
140
|
+
}
|
141
|
+
|
142
|
+
const eventsToRollback = [...syncState.rollbackTail.slice(rollbackIndex), ...syncState.pending]
|
143
|
+
|
144
|
+
// Get the last new event's ID as the new upstream head
|
145
|
+
const newUpstreamHead = payload.newEvents.at(-1)?.id ?? syncState.upstreamHead
|
146
|
+
|
147
|
+
// Rebase pending events on top of the new events
|
148
|
+
const rebasedPending = rebaseEvents({
|
149
|
+
events: syncState.pending,
|
150
|
+
baseEventId: newUpstreamHead,
|
151
|
+
isLocalEvent,
|
152
|
+
})
|
153
|
+
|
154
|
+
return {
|
155
|
+
_tag: 'rebase',
|
156
|
+
newSyncState: {
|
157
|
+
pending: rebasedPending,
|
158
|
+
rollbackTail: trimRollbackTail([...syncState.rollbackTail.slice(0, rollbackIndex), ...payload.newEvents]),
|
159
|
+
upstreamHead: newUpstreamHead,
|
160
|
+
localHead: rebasedPending.at(-1)?.id ?? newUpstreamHead,
|
161
|
+
},
|
162
|
+
previousSyncState: syncState,
|
163
|
+
newEvents: payload.newEvents,
|
164
|
+
eventsToRollback,
|
165
|
+
}
|
166
|
+
}
|
167
|
+
|
168
|
+
case 'upstream-advance': {
|
169
|
+
if (payload.newEvents.length === 0) {
|
170
|
+
return {
|
171
|
+
_tag: 'advance',
|
172
|
+
newSyncState: {
|
173
|
+
pending: syncState.pending,
|
174
|
+
rollbackTail: trimRollbackTail(syncState.rollbackTail),
|
175
|
+
upstreamHead: syncState.upstreamHead,
|
176
|
+
localHead: syncState.localHead,
|
177
|
+
},
|
178
|
+
previousSyncState: syncState,
|
179
|
+
newEvents: [],
|
180
|
+
}
|
181
|
+
}
|
182
|
+
|
183
|
+
// Validate that newEvents are sorted in ascending order by eventId
|
184
|
+
for (let i = 1; i < payload.newEvents.length; i++) {
|
185
|
+
if (EventId.isGreaterThan(payload.newEvents[i - 1]!.id, payload.newEvents[i]!.id)) {
|
186
|
+
return shouldNeverHappen('Events must be sorted in ascending order by eventId')
|
187
|
+
}
|
188
|
+
}
|
189
|
+
|
190
|
+
const newUpstreamHead = payload.newEvents.at(-1)!.id
|
191
|
+
|
192
|
+
const divergentPendingIndex = findDivergencePoint({
|
193
|
+
existingEvents: syncState.pending,
|
194
|
+
incomingEvents: payload.newEvents,
|
195
|
+
isEqualEvent,
|
196
|
+
isLocalEvent,
|
197
|
+
ignoreLocalEvents,
|
198
|
+
})
|
199
|
+
|
200
|
+
if (divergentPendingIndex === -1) {
|
201
|
+
const pendingEventIds = new Set(syncState.pending.map((e) => `${e.id.global},${e.id.local}`))
|
202
|
+
const newEvents = payload.newEvents.filter((e) => !pendingEventIds.has(`${e.id.global},${e.id.local}`))
|
203
|
+
|
204
|
+
// In the case where the incoming events are a subset of the pending events,
|
205
|
+
// we need to split the pending events into two groups:
|
206
|
+
// - pendingMatching: The pending events up to point where they match the incoming events
|
207
|
+
// - pendingRemaining: The pending events after the point where they match the incoming events
|
208
|
+
// The `localIndexOffset` is used to account for the local events that are being ignored
|
209
|
+
let localIndexOffset = 0
|
210
|
+
const [pendingMatching, pendingRemaining] = ReadonlyArray.splitWhere(
|
211
|
+
syncState.pending,
|
212
|
+
(pendingEvent, index) => {
|
213
|
+
if (ignoreLocalEvents && isLocalEvent(pendingEvent)) {
|
214
|
+
localIndexOffset++
|
215
|
+
return false
|
216
|
+
}
|
217
|
+
|
218
|
+
const newEvent = payload.newEvents.at(index - localIndexOffset)
|
219
|
+
if (!newEvent) {
|
220
|
+
return true
|
221
|
+
}
|
222
|
+
return isEqualEvent(pendingEvent, newEvent) === false
|
223
|
+
},
|
224
|
+
)
|
225
|
+
|
226
|
+
const seenEventIds = new Set<string>()
|
227
|
+
const pendingAndNewEvents = [...pendingMatching, ...payload.newEvents].filter((event) => {
|
228
|
+
const eventIdStr = `${event.id.global},${event.id.local}`
|
229
|
+
if (seenEventIds.has(eventIdStr)) {
|
230
|
+
return false
|
231
|
+
}
|
232
|
+
seenEventIds.add(eventIdStr)
|
233
|
+
return true
|
234
|
+
})
|
235
|
+
|
236
|
+
return {
|
237
|
+
_tag: 'advance',
|
238
|
+
newSyncState: {
|
239
|
+
pending: pendingRemaining,
|
240
|
+
rollbackTail: trimRollbackTail([...syncState.rollbackTail, ...pendingAndNewEvents]),
|
241
|
+
upstreamHead: newUpstreamHead,
|
242
|
+
localHead: pendingRemaining.at(-1)?.id ?? newUpstreamHead,
|
243
|
+
},
|
244
|
+
previousSyncState: syncState,
|
245
|
+
newEvents,
|
246
|
+
}
|
247
|
+
} else {
|
248
|
+
const divergentPending = syncState.pending.slice(divergentPendingIndex)
|
249
|
+
const rebasedPending = rebaseEvents({
|
250
|
+
events: divergentPending,
|
251
|
+
baseEventId: newUpstreamHead,
|
252
|
+
isLocalEvent,
|
253
|
+
})
|
254
|
+
|
255
|
+
const divergentNewEventsIndex = findDivergencePoint({
|
256
|
+
existingEvents: payload.newEvents,
|
257
|
+
incomingEvents: syncState.pending,
|
258
|
+
isEqualEvent,
|
259
|
+
isLocalEvent,
|
260
|
+
ignoreLocalEvents,
|
261
|
+
})
|
262
|
+
|
263
|
+
return {
|
264
|
+
_tag: 'rebase',
|
265
|
+
newSyncState: {
|
266
|
+
pending: rebasedPending,
|
267
|
+
rollbackTail: trimRollbackTail([...syncState.rollbackTail, ...payload.newEvents]),
|
268
|
+
upstreamHead: newUpstreamHead,
|
269
|
+
localHead: rebasedPending.at(-1)!.id,
|
270
|
+
},
|
271
|
+
previousSyncState: syncState,
|
272
|
+
newEvents: [...payload.newEvents.slice(divergentNewEventsIndex), ...rebasedPending],
|
273
|
+
eventsToRollback: [...syncState.rollbackTail, ...divergentPending],
|
274
|
+
}
|
275
|
+
}
|
276
|
+
}
|
277
|
+
|
278
|
+
case 'local-push': {
|
279
|
+
if (payload.newEvents.length === 0) {
|
280
|
+
return { _tag: 'advance', newSyncState: syncState, previousSyncState: syncState, newEvents: [] }
|
281
|
+
}
|
282
|
+
|
283
|
+
const newEventsFirst = payload.newEvents.at(0)!
|
284
|
+
const invalidEventId = EventId.isGreaterThan(newEventsFirst.id, syncState.localHead) === false
|
285
|
+
|
286
|
+
if (invalidEventId) {
|
287
|
+
const expectedMinimumId = EventId.nextPair(syncState.localHead, true).id
|
288
|
+
return { _tag: 'reject', previousSyncState: syncState, expectedMinimumId }
|
289
|
+
} else {
|
290
|
+
return {
|
291
|
+
_tag: 'advance',
|
292
|
+
newSyncState: {
|
293
|
+
pending: [...syncState.pending, ...payload.newEvents],
|
294
|
+
rollbackTail: syncState.rollbackTail,
|
295
|
+
upstreamHead: syncState.upstreamHead,
|
296
|
+
localHead: payload.newEvents.at(-1)!.id,
|
297
|
+
},
|
298
|
+
previousSyncState: syncState,
|
299
|
+
newEvents: payload.newEvents,
|
300
|
+
}
|
301
|
+
}
|
302
|
+
}
|
303
|
+
|
304
|
+
// case 'upstream-trim-rollback-tail': {
|
305
|
+
// // Find the index of the new rollback start in the rollback tail
|
306
|
+
// const startIndex = syncState.rollbackTail.findIndex((event) => eventIdsEqual(event.id, payload.trimRollbackUntil))
|
307
|
+
// if (startIndex === -1) {
|
308
|
+
// return shouldNeverHappen('New rollback start event not found in rollback tail')
|
309
|
+
// }
|
310
|
+
|
311
|
+
// // Keep only the events from the start index onwards
|
312
|
+
// const newRollbackTail = syncState.rollbackTail.slice(startIndex)
|
313
|
+
|
314
|
+
// return {
|
315
|
+
// _tag: 'advance',
|
316
|
+
// syncState: {
|
317
|
+
// pending: syncState.pending,
|
318
|
+
// rollbackTail: newRollbackTail,
|
319
|
+
// upstreamHead: syncState.upstreamHead,
|
320
|
+
// localHead: syncState.localHead,
|
321
|
+
// },
|
322
|
+
// newEvents: [],
|
323
|
+
// }
|
324
|
+
// }
|
325
|
+
}
|
326
|
+
}
|
327
|
+
|
328
|
+
/**
|
329
|
+
* Gets the index relative to `existingEvents` where the divergence point is
|
330
|
+
* by comparing each event in `existingEvents` to the corresponding event in `incomingEvents`
|
331
|
+
*/
|
332
|
+
const findDivergencePoint = ({
|
333
|
+
existingEvents,
|
334
|
+
incomingEvents,
|
335
|
+
isEqualEvent,
|
336
|
+
isLocalEvent,
|
337
|
+
ignoreLocalEvents,
|
338
|
+
}: {
|
339
|
+
existingEvents: ReadonlyArray<MutationEvent.EncodedWithMeta>
|
340
|
+
incomingEvents: ReadonlyArray<MutationEvent.EncodedWithMeta>
|
341
|
+
isEqualEvent: (a: MutationEvent.EncodedWithMeta, b: MutationEvent.EncodedWithMeta) => boolean
|
342
|
+
isLocalEvent: (event: MutationEvent.EncodedWithMeta) => boolean
|
343
|
+
ignoreLocalEvents: boolean
|
344
|
+
}): number => {
|
345
|
+
if (ignoreLocalEvents) {
|
346
|
+
const filteredExistingEvents = existingEvents.filter((event) => !isLocalEvent(event))
|
347
|
+
const divergencePointWithoutLocalEvents = findDivergencePoint({
|
348
|
+
existingEvents: filteredExistingEvents,
|
349
|
+
incomingEvents,
|
350
|
+
isEqualEvent,
|
351
|
+
isLocalEvent,
|
352
|
+
ignoreLocalEvents: false,
|
353
|
+
})
|
354
|
+
|
355
|
+
if (divergencePointWithoutLocalEvents === -1) return -1
|
356
|
+
|
357
|
+
const divergencePointEventId = existingEvents[divergencePointWithoutLocalEvents]!.id
|
358
|
+
// Now find the divergence point in the original array
|
359
|
+
return existingEvents.findIndex((event) => EventId.isEqual(event.id, divergencePointEventId))
|
360
|
+
}
|
361
|
+
|
362
|
+
return existingEvents.findIndex((existingEvent, index) => {
|
363
|
+
const incomingEvent = incomingEvents[index]
|
364
|
+
// return !incomingEvent || !isEqualEvent(existingEvent, incomingEvent)
|
365
|
+
return incomingEvent && !isEqualEvent(existingEvent, incomingEvent)
|
366
|
+
})
|
367
|
+
}
|
368
|
+
|
369
|
+
const rebaseEvents = ({
|
370
|
+
events,
|
371
|
+
baseEventId,
|
372
|
+
isLocalEvent,
|
373
|
+
}: {
|
374
|
+
events: ReadonlyArray<MutationEvent.EncodedWithMeta>
|
375
|
+
baseEventId: EventId.EventId
|
376
|
+
isLocalEvent: (event: MutationEvent.EncodedWithMeta) => boolean
|
377
|
+
}): ReadonlyArray<MutationEvent.EncodedWithMeta> => {
|
378
|
+
let prevEventId = baseEventId
|
379
|
+
return events.map((event) => {
|
380
|
+
const isLocal = isLocalEvent(event)
|
381
|
+
const newEvent = event.rebase(prevEventId, isLocal)
|
382
|
+
prevEventId = newEvent.id
|
383
|
+
return newEvent
|
384
|
+
})
|
385
|
+
}
|
@@ -0,0 +1,18 @@
|
|
1
|
+
import { Effect } from '@livestore/utils/effect'
|
2
|
+
|
3
|
+
import type { MutationEvent } from '../schema/mod.js'
|
4
|
+
import { InvalidPushError } from './sync.js'
|
5
|
+
|
6
|
+
// TODO proper batch validation
|
7
|
+
export const validatePushPayload = (batch: ReadonlyArray<MutationEvent.AnyEncoded>, currentEventId: number) =>
|
8
|
+
Effect.gen(function* () {
|
9
|
+
if (batch[0]!.id.global <= currentEventId) {
|
10
|
+
return yield* InvalidPushError.make({
|
11
|
+
reason: {
|
12
|
+
_tag: 'ServerAhead',
|
13
|
+
minimumExpectedId: currentEventId + 1,
|
14
|
+
providedId: batch[0]!.id.global,
|
15
|
+
},
|
16
|
+
})
|
17
|
+
}
|
18
|
+
})
|
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.2.0
|
5
|
+
export const liveStoreVersion = '0.2.0' as const
|
6
6
|
|
7
7
|
/**
|
8
8
|
* This version number is incremented whenever the internal storage format changes in a breaking way.
|
@@ -11,4 +11,4 @@ export const liveStoreVersion = '0.2.0-dev.1' as const
|
|
11
11
|
* While LiveStore is in alpha, this might happen more frequently.
|
12
12
|
* In the future, LiveStore will provide a migration path for older database files to avoid the impression of data loss.
|
13
13
|
*/
|
14
|
-
export const liveStoreStorageFormatVersion =
|
14
|
+
export const liveStoreStorageFormatVersion = 3
|
@@ -1 +0,0 @@
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/schema/index.ts"],"names":[],"mappings":"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"}
|
package/dist/schema/index.js.map
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/schema/index.ts"],"names":[],"mappings":"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"}
|
@@ -1,14 +0,0 @@
|
|
1
|
-
import { Effect } from '@livestore/utils/effect';
|
2
|
-
import type { EventId } from '../adapter-types.js';
|
3
|
-
export declare const makeNextMutationEventIdPair: (currentMutationEventIdRef: {
|
4
|
-
current: EventId;
|
5
|
-
}) => (opts: {
|
6
|
-
localOnly: boolean;
|
7
|
-
}) => Effect.Effect<{
|
8
|
-
id: {
|
9
|
-
global: number;
|
10
|
-
local: number;
|
11
|
-
};
|
12
|
-
parentId: EventId;
|
13
|
-
}, never, never>;
|
14
|
-
//# sourceMappingURL=next-mutation-event-id-pair.d.ts.map
|
@@ -1 +0,0 @@
|
|
1
|
-
{"version":3,"file":"next-mutation-event-id-pair.d.ts","sourceRoot":"","sources":["../../src/sync/next-mutation-event-id-pair.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAA;AAEhD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAElD,eAAO,MAAM,2BAA2B,8BACV;IAAE,OAAO,EAAE,OAAO,CAAA;CAAE,YAAY;IAAE,SAAS,EAAE,OAAO,CAAA;CAAE;;;;;;gBAc9E,CAAA"}
|
@@ -1,13 +0,0 @@
|
|
1
|
-
import { Effect } from '@livestore/utils/effect';
|
2
|
-
export const makeNextMutationEventIdPair = (currentMutationEventIdRef) => (opts) => Effect.gen(function* () {
|
3
|
-
// NOTE we always point to `local: 0` for non-localOnly mutations
|
4
|
-
const parentId = opts.localOnly
|
5
|
-
? currentMutationEventIdRef.current
|
6
|
-
: { global: currentMutationEventIdRef.current.global, local: 0 };
|
7
|
-
const id = opts.localOnly
|
8
|
-
? { global: parentId.global, local: parentId.local + 1 }
|
9
|
-
: { global: parentId.global + 1, local: 0 };
|
10
|
-
currentMutationEventIdRef.current = id;
|
11
|
-
return { id, parentId };
|
12
|
-
});
|
13
|
-
//# sourceMappingURL=next-mutation-event-id-pair.js.map
|
@@ -1 +0,0 @@
|
|
1
|
-
{"version":3,"file":"next-mutation-event-id-pair.js","sourceRoot":"","sources":["../../src/sync/next-mutation-event-id-pair.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAA;AAIhD,MAAM,CAAC,MAAM,2BAA2B,GACtC,CAAC,yBAA+C,EAAE,EAAE,CAAC,CAAC,IAA4B,EAAE,EAAE,CACpF,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IAClB,iEAAiE;IACjE,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS;QAC7B,CAAC,CAAC,yBAAyB,CAAC,OAAO;QACnC,CAAC,CAAC,EAAE,MAAM,EAAE,yBAAyB,CAAC,OAAO,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,CAAA;IAElE,MAAM,EAAE,GAAG,IAAI,CAAC,SAAS;QACvB,CAAC,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,KAAK,EAAE,QAAQ,CAAC,KAAK,GAAG,CAAC,EAAE;QACxD,CAAC,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAA;IAE7C,yBAAyB,CAAC,OAAO,GAAG,EAAE,CAAA;IAEtC,OAAO,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAA;AACzB,CAAC,CAAC,CAAA"}
|
@@ -1,20 +0,0 @@
|
|
1
|
-
import { Effect } from '@livestore/utils/effect'
|
2
|
-
|
3
|
-
import type { EventId } from '../adapter-types.js'
|
4
|
-
|
5
|
-
export const makeNextMutationEventIdPair =
|
6
|
-
(currentMutationEventIdRef: { current: EventId }) => (opts: { localOnly: boolean }) =>
|
7
|
-
Effect.gen(function* () {
|
8
|
-
// NOTE we always point to `local: 0` for non-localOnly mutations
|
9
|
-
const parentId = opts.localOnly
|
10
|
-
? currentMutationEventIdRef.current
|
11
|
-
: { global: currentMutationEventIdRef.current.global, local: 0 }
|
12
|
-
|
13
|
-
const id = opts.localOnly
|
14
|
-
? { global: parentId.global, local: parentId.local + 1 }
|
15
|
-
: { global: parentId.global + 1, local: 0 }
|
16
|
-
|
17
|
-
currentMutationEventIdRef.current = id
|
18
|
-
|
19
|
-
return { id, parentId }
|
20
|
-
})
|