@livestore/common 0.3.1 → 0.3.2-dev.1
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/ClientSessionLeaderThreadProxy.d.ts +35 -0
- package/dist/ClientSessionLeaderThreadProxy.d.ts.map +1 -0
- package/dist/ClientSessionLeaderThreadProxy.js +6 -0
- package/dist/ClientSessionLeaderThreadProxy.js.map +1 -0
- package/dist/__tests__/fixture.d.ts +4 -4
- package/dist/__tests__/fixture.js +2 -2
- package/dist/adapter-types.d.ts +11 -162
- package/dist/adapter-types.d.ts.map +1 -1
- package/dist/adapter-types.js +5 -49
- package/dist/adapter-types.js.map +1 -1
- package/dist/debug-info.d.ts +2 -2
- package/dist/debug-info.js +2 -2
- package/dist/defs.d.ts +20 -0
- package/dist/defs.d.ts.map +1 -0
- package/dist/defs.js +12 -0
- package/dist/defs.js.map +1 -0
- package/dist/devtools/devtools-messages-client-session.d.ts +29 -27
- package/dist/devtools/devtools-messages-client-session.d.ts.map +1 -1
- package/dist/devtools/devtools-messages-client-session.js +4 -4
- package/dist/devtools/devtools-messages-common.d.ts +6 -6
- package/dist/devtools/devtools-messages-common.d.ts.map +1 -1
- package/dist/devtools/devtools-messages-common.js +1 -1
- package/dist/devtools/devtools-messages-leader.d.ts +37 -35
- package/dist/devtools/devtools-messages-leader.d.ts.map +1 -1
- package/dist/devtools/devtools-messages-leader.js +4 -4
- package/dist/devtools/devtools-messages.d.ts +3 -3
- package/dist/devtools/devtools-messages.d.ts.map +1 -1
- package/dist/devtools/devtools-messages.js +3 -3
- package/dist/devtools/devtools-messages.js.map +1 -1
- package/dist/devtools/mod.d.ts +3 -3
- package/dist/devtools/mod.js +3 -3
- package/dist/errors.d.ts +50 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +36 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +16 -16
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +16 -16
- package/dist/index.js.map +1 -1
- package/dist/leader-thread/LeaderSyncProcessor.d.ts +10 -11
- package/dist/leader-thread/LeaderSyncProcessor.d.ts.map +1 -1
- package/dist/leader-thread/LeaderSyncProcessor.js +122 -132
- package/dist/leader-thread/LeaderSyncProcessor.js.map +1 -1
- package/dist/leader-thread/connection.d.ts +4 -4
- package/dist/leader-thread/connection.js +2 -2
- package/dist/leader-thread/eventlog.d.ts +21 -10
- package/dist/leader-thread/eventlog.d.ts.map +1 -1
- package/dist/leader-thread/eventlog.js +39 -24
- package/dist/leader-thread/eventlog.js.map +1 -1
- package/dist/leader-thread/leader-worker-devtools.d.ts +3 -3
- package/dist/leader-thread/leader-worker-devtools.d.ts.map +1 -1
- package/dist/leader-thread/leader-worker-devtools.js +4 -5
- package/dist/leader-thread/leader-worker-devtools.js.map +1 -1
- package/dist/leader-thread/make-leader-thread-layer.d.ts +7 -7
- package/dist/leader-thread/make-leader-thread-layer.d.ts.map +1 -1
- package/dist/leader-thread/make-leader-thread-layer.js +44 -14
- package/dist/leader-thread/make-leader-thread-layer.js.map +1 -1
- package/dist/leader-thread/materialize-event.d.ts +4 -4
- package/dist/leader-thread/materialize-event.d.ts.map +1 -1
- package/dist/leader-thread/materialize-event.js +14 -8
- package/dist/leader-thread/materialize-event.js.map +1 -1
- package/dist/leader-thread/mod.d.ts +8 -7
- package/dist/leader-thread/mod.d.ts.map +1 -1
- package/dist/leader-thread/mod.js +8 -7
- package/dist/leader-thread/mod.js.map +1 -1
- package/dist/leader-thread/recreate-db.d.ts +14 -7
- package/dist/leader-thread/recreate-db.d.ts.map +1 -1
- package/dist/leader-thread/recreate-db.js +3 -5
- package/dist/leader-thread/recreate-db.js.map +1 -1
- package/dist/leader-thread/shutdown-channel.d.ts +1 -1
- package/dist/leader-thread/shutdown-channel.js +1 -1
- package/dist/leader-thread/types.d.ts +8 -10
- package/dist/leader-thread/types.d.ts.map +1 -1
- package/dist/make-client-session.d.ts +3 -3
- package/dist/make-client-session.d.ts.map +1 -1
- package/dist/make-client-session.js +3 -3
- package/dist/make-client-session.js.map +1 -1
- package/dist/materializer-helper.d.ts +5 -5
- package/dist/materializer-helper.js +5 -5
- package/dist/rematerialize-from-eventlog.d.ts +4 -4
- package/dist/rematerialize-from-eventlog.d.ts.map +1 -1
- package/dist/rematerialize-from-eventlog.js +13 -5
- package/dist/rematerialize-from-eventlog.js.map +1 -1
- package/dist/schema/EventDef.d.ts +5 -5
- package/dist/schema/EventDef.d.ts.map +1 -1
- package/dist/schema/EventDef.js +2 -2
- package/dist/schema/EventDef.js.map +1 -1
- package/dist/schema/EventSequenceNumber.d.ts +20 -2
- package/dist/schema/EventSequenceNumber.d.ts.map +1 -1
- package/dist/schema/EventSequenceNumber.js +71 -19
- package/dist/schema/EventSequenceNumber.js.map +1 -1
- package/dist/schema/EventSequenceNumber.test.js +89 -4
- package/dist/schema/EventSequenceNumber.test.js.map +1 -1
- package/dist/schema/LiveStoreEvent.d.ts +26 -12
- package/dist/schema/LiveStoreEvent.d.ts.map +1 -1
- package/dist/schema/LiveStoreEvent.js +13 -5
- package/dist/schema/LiveStoreEvent.js.map +1 -1
- package/dist/schema/events.d.ts +1 -1
- package/dist/schema/events.d.ts.map +1 -1
- package/dist/schema/events.js +1 -1
- package/dist/schema/events.js.map +1 -1
- package/dist/schema/mod.d.ts +9 -9
- package/dist/schema/mod.d.ts.map +1 -1
- package/dist/schema/mod.js +9 -9
- package/dist/schema/mod.js.map +1 -1
- package/dist/schema/schema.d.ts +4 -4
- package/dist/schema/schema.js +3 -3
- package/dist/schema/state/mod.d.ts +2 -2
- package/dist/schema/state/mod.js +2 -2
- package/dist/schema/state/sqlite/client-document-def.d.ts +5 -5
- package/dist/schema/state/sqlite/client-document-def.d.ts.map +1 -1
- package/dist/schema/state/sqlite/client-document-def.js +6 -6
- package/dist/schema/state/sqlite/client-document-def.js.map +1 -1
- package/dist/schema/state/sqlite/client-document-def.test.js +4 -6
- package/dist/schema/state/sqlite/client-document-def.test.js.map +1 -1
- package/dist/schema/state/sqlite/db-schema/ast/sqlite.js +1 -1
- package/dist/schema/state/sqlite/db-schema/ast/validate.d.ts +1 -1
- package/dist/schema/state/sqlite/db-schema/dsl/field-defs.js +2 -2
- package/dist/schema/state/sqlite/db-schema/dsl/field-defs.js.map +1 -1
- package/dist/schema/state/sqlite/db-schema/dsl/field-defs.test.js +1 -1
- package/dist/schema/state/sqlite/db-schema/dsl/mod.d.ts +3 -3
- package/dist/schema/state/sqlite/db-schema/dsl/mod.d.ts.map +1 -1
- package/dist/schema/state/sqlite/db-schema/dsl/mod.js +1 -1
- package/dist/schema/state/sqlite/db-schema/dsl/mod.js.map +1 -1
- package/dist/schema/state/sqlite/db-schema/hash.d.ts.map +1 -1
- package/dist/schema/state/sqlite/db-schema/hash.js +3 -2
- package/dist/schema/state/sqlite/db-schema/hash.js.map +1 -1
- package/dist/schema/state/sqlite/db-schema/mod.d.ts +2 -2
- package/dist/schema/state/sqlite/db-schema/mod.d.ts.map +1 -1
- package/dist/schema/state/sqlite/db-schema/mod.js +2 -2
- package/dist/schema/state/sqlite/db-schema/mod.js.map +1 -1
- package/dist/schema/state/sqlite/mod.d.ts +7 -7
- package/dist/schema/state/sqlite/mod.d.ts.map +1 -1
- package/dist/schema/state/sqlite/mod.js +7 -7
- package/dist/schema/state/sqlite/mod.js.map +1 -1
- package/dist/schema/state/sqlite/query-builder/api.d.ts +40 -13
- package/dist/schema/state/sqlite/query-builder/api.d.ts.map +1 -1
- package/dist/schema/state/sqlite/query-builder/api.js.map +1 -1
- package/dist/schema/state/sqlite/query-builder/astToSql.d.ts +2 -2
- package/dist/schema/state/sqlite/query-builder/astToSql.js +1 -1
- package/dist/schema/state/sqlite/query-builder/impl.d.ts +2 -2
- package/dist/schema/state/sqlite/query-builder/impl.d.ts.map +1 -1
- package/dist/schema/state/sqlite/query-builder/impl.js +20 -25
- package/dist/schema/state/sqlite/query-builder/impl.js.map +1 -1
- package/dist/schema/state/sqlite/query-builder/impl.test.d.ts +1 -81
- package/dist/schema/state/sqlite/query-builder/impl.test.d.ts.map +1 -1
- package/dist/schema/state/sqlite/query-builder/impl.test.js +36 -22
- package/dist/schema/state/sqlite/query-builder/impl.test.js.map +1 -1
- package/dist/schema/state/sqlite/query-builder/mod.d.ts +2 -2
- package/dist/schema/state/sqlite/query-builder/mod.js +2 -2
- package/dist/schema/state/sqlite/schema-helpers.d.ts +1 -1
- package/dist/schema/state/sqlite/schema-helpers.js +1 -1
- package/dist/schema/state/sqlite/system-tables.d.ts +72 -67
- package/dist/schema/state/sqlite/system-tables.d.ts.map +1 -1
- package/dist/schema/state/sqlite/system-tables.js +11 -20
- package/dist/schema/state/sqlite/system-tables.js.map +1 -1
- package/dist/schema/state/sqlite/table-def.d.ts +3 -3
- package/dist/schema/state/sqlite/table-def.d.ts.map +1 -1
- package/dist/schema/state/sqlite/table-def.js +2 -2
- package/dist/schema-management/common.d.ts +2 -2
- package/dist/schema-management/common.js +1 -1
- package/dist/schema-management/migrations.d.ts +6 -4
- package/dist/schema-management/migrations.d.ts.map +1 -1
- package/dist/schema-management/migrations.js +5 -5
- package/dist/schema-management/migrations.js.map +1 -1
- package/dist/schema-management/validate-schema.d.ts +4 -4
- package/dist/schema-management/validate-schema.js +1 -1
- package/dist/sql-queries/index.d.ts +3 -3
- package/dist/sql-queries/index.js +3 -3
- package/dist/sql-queries/sql-queries.d.ts +2 -2
- package/dist/sql-queries/sql-queries.d.ts.map +1 -1
- package/dist/sql-queries/sql-queries.js +5 -3
- package/dist/sql-queries/sql-queries.js.map +1 -1
- package/dist/sql-queries/sql-query-builder.d.ts +3 -3
- package/dist/sql-queries/sql-query-builder.js +1 -1
- package/dist/sql-queries/types.d.ts +1 -1
- package/dist/sqlite-db-helper.d.ts +2 -2
- package/dist/sqlite-db-helper.js +1 -1
- package/dist/sqlite-types.d.ts +72 -0
- package/dist/sqlite-types.d.ts.map +1 -0
- package/dist/sqlite-types.js +5 -0
- package/dist/sqlite-types.js.map +1 -0
- package/dist/sync/ClientSessionSyncProcessor.d.ts +22 -7
- package/dist/sync/ClientSessionSyncProcessor.d.ts.map +1 -1
- package/dist/sync/ClientSessionSyncProcessor.js +43 -21
- package/dist/sync/ClientSessionSyncProcessor.js.map +1 -1
- package/dist/sync/index.d.ts +3 -3
- package/dist/sync/index.d.ts.map +1 -1
- package/dist/sync/index.js +3 -3
- package/dist/sync/index.js.map +1 -1
- package/dist/sync/next/compact-events.d.ts +1 -1
- package/dist/sync/next/compact-events.js +4 -4
- package/dist/sync/next/facts.d.ts +3 -3
- package/dist/sync/next/facts.js +2 -2
- package/dist/sync/next/graphology.d.ts.map +1 -1
- package/dist/sync/next/graphology.js +0 -6
- package/dist/sync/next/graphology.js.map +1 -1
- package/dist/sync/next/graphology_.d.ts +1 -1
- package/dist/sync/next/graphology_.d.ts.map +1 -1
- package/dist/sync/next/graphology_.js +1 -1
- package/dist/sync/next/graphology_.js.map +1 -1
- package/dist/sync/next/history-dag-common.d.ts +3 -3
- package/dist/sync/next/history-dag-common.js +2 -2
- package/dist/sync/next/history-dag.d.ts +2 -2
- package/dist/sync/next/history-dag.js +3 -3
- package/dist/sync/next/mod.d.ts +5 -5
- package/dist/sync/next/mod.d.ts.map +1 -1
- package/dist/sync/next/mod.js +5 -5
- package/dist/sync/next/mod.js.map +1 -1
- package/dist/sync/next/rebase-events.d.ts +4 -4
- package/dist/sync/next/rebase-events.d.ts.map +1 -1
- package/dist/sync/next/rebase-events.js +3 -2
- package/dist/sync/next/rebase-events.js.map +1 -1
- package/dist/sync/next/test/compact-events.calculator.test.js +4 -4
- package/dist/sync/next/test/compact-events.test.js +5 -5
- package/dist/sync/next/test/compact-events.test.js.map +1 -1
- package/dist/sync/next/test/event-fixtures.d.ts +3 -3
- package/dist/sync/next/test/event-fixtures.d.ts.map +1 -1
- package/dist/sync/next/test/event-fixtures.js +17 -8
- package/dist/sync/next/test/event-fixtures.js.map +1 -1
- package/dist/sync/next/test/mod.d.ts +1 -1
- package/dist/sync/next/test/mod.js +1 -1
- package/dist/sync/sync.d.ts +6 -4
- package/dist/sync/sync.d.ts.map +1 -1
- package/dist/sync/sync.js +4 -1
- package/dist/sync/sync.js.map +1 -1
- package/dist/sync/syncstate.d.ts +14 -5
- package/dist/sync/syncstate.d.ts.map +1 -1
- package/dist/sync/syncstate.js +25 -12
- package/dist/sync/syncstate.js.map +1 -1
- package/dist/sync/syncstate.test.js +20 -21
- package/dist/sync/syncstate.test.js.map +1 -1
- package/dist/sync/validate-push-payload.d.ts +2 -2
- package/dist/sync/validate-push-payload.js +1 -1
- package/dist/util.d.ts.map +1 -1
- package/dist/util.js +0 -1
- package/dist/util.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.d.ts.map +1 -1
- package/dist/version.js +1 -1
- package/dist/version.js.map +1 -1
- package/package.json +6 -5
- package/src/ClientSessionLeaderThreadProxy.ts +40 -0
- package/src/__tests__/fixture.ts +2 -2
- package/src/adapter-types.ts +21 -167
- package/src/debug-info.ts +2 -2
- package/src/defs.ts +17 -0
- package/src/devtools/devtools-messages-client-session.ts +4 -4
- package/src/devtools/devtools-messages-common.ts +1 -1
- package/src/devtools/devtools-messages-leader.ts +4 -4
- package/src/devtools/devtools-messages.ts +3 -3
- package/src/devtools/mod.ts +3 -3
- package/src/errors.ts +49 -0
- package/src/index.ts +16 -16
- package/src/leader-thread/LeaderSyncProcessor.ts +154 -193
- package/src/leader-thread/connection.ts +5 -5
- package/src/leader-thread/eventlog.ts +89 -67
- package/src/leader-thread/leader-worker-devtools.ts +5 -6
- package/src/leader-thread/make-leader-thread-layer.ts +64 -20
- package/src/leader-thread/materialize-event.ts +17 -10
- package/src/leader-thread/mod.ts +8 -7
- package/src/leader-thread/recreate-db.ts +101 -93
- package/src/leader-thread/shutdown-channel.ts +1 -1
- package/src/leader-thread/types.ts +10 -15
- package/src/make-client-session.ts +5 -6
- package/src/materializer-helper.ts +11 -11
- package/src/rematerialize-from-eventlog.ts +16 -8
- package/src/schema/EventDef.ts +8 -6
- package/src/schema/EventSequenceNumber.test.ts +121 -4
- package/src/schema/EventSequenceNumber.ts +95 -23
- package/src/schema/LiveStoreEvent.ts +23 -7
- package/src/schema/events.ts +1 -1
- package/src/schema/mod.ts +9 -9
- package/src/schema/schema.ts +7 -7
- package/src/schema/state/mod.ts +2 -2
- package/src/schema/state/sqlite/client-document-def.test.ts +9 -7
- package/src/schema/state/sqlite/client-document-def.ts +45 -33
- package/src/schema/state/sqlite/db-schema/ast/sqlite.ts +1 -1
- package/src/schema/state/sqlite/db-schema/ast/validate.ts +1 -1
- package/src/schema/state/sqlite/db-schema/dsl/field-defs.test.ts +1 -1
- package/src/schema/state/sqlite/db-schema/dsl/field-defs.ts +2 -2
- package/src/schema/state/sqlite/db-schema/dsl/mod.ts +19 -13
- package/src/schema/state/sqlite/db-schema/hash.ts +3 -4
- package/src/schema/state/sqlite/db-schema/mod.ts +2 -2
- package/src/schema/state/sqlite/mod.ts +13 -13
- package/src/schema/state/sqlite/query-builder/api.ts +43 -13
- package/src/schema/state/sqlite/query-builder/astToSql.ts +4 -4
- package/src/schema/state/sqlite/query-builder/impl.test.ts +63 -23
- package/src/schema/state/sqlite/query-builder/impl.ts +23 -28
- package/src/schema/state/sqlite/query-builder/mod.ts +2 -2
- package/src/schema/state/sqlite/schema-helpers.ts +2 -2
- package/src/schema/state/sqlite/system-tables.ts +12 -25
- package/src/schema/state/sqlite/table-def.ts +4 -4
- package/src/schema-management/common.ts +3 -3
- package/src/schema-management/migrations.ts +11 -9
- package/src/schema-management/validate-schema.ts +4 -4
- package/src/sql-queries/index.ts +3 -3
- package/src/sql-queries/sql-queries.ts +6 -4
- package/src/sql-queries/sql-query-builder.ts +4 -4
- package/src/sql-queries/types.ts +1 -1
- package/src/sqlite-db-helper.ts +3 -3
- package/src/sqlite-types.ts +76 -0
- package/src/sync/ClientSessionSyncProcessor.ts +65 -30
- package/src/sync/index.ts +3 -3
- package/src/sync/next/compact-events.ts +5 -5
- package/src/sync/next/facts.ts +4 -4
- package/src/sync/next/graphology.ts +3 -11
- package/src/sync/next/graphology_.ts +1 -1
- package/src/sync/next/history-dag-common.ts +3 -3
- package/src/sync/next/history-dag.ts +3 -3
- package/src/sync/next/mod.ts +5 -5
- package/src/sync/next/rebase-events.ts +7 -6
- package/src/sync/next/test/compact-events.calculator.test.ts +4 -4
- package/src/sync/next/test/compact-events.test.ts +6 -6
- package/src/sync/next/test/event-fixtures.ts +19 -10
- package/src/sync/next/test/mod.ts +1 -1
- package/src/sync/sync.ts +7 -4
- package/src/sync/syncstate.test.ts +25 -22
- package/src/sync/syncstate.ts +33 -12
- package/src/sync/validate-push-payload.ts +2 -2
- package/src/util.ts +0 -1
- package/src/version.ts +1 -1
@@ -1,15 +1,24 @@
|
|
1
1
|
/// <reference lib="dom" />
|
2
2
|
import { LS_DEV, shouldNeverHappen, TRACE_VERBOSE } from '@livestore/utils'
|
3
|
-
import {
|
4
|
-
|
3
|
+
import {
|
4
|
+
BucketQueue,
|
5
|
+
Effect,
|
6
|
+
FiberHandle,
|
7
|
+
Option,
|
8
|
+
Queue,
|
9
|
+
type Runtime,
|
10
|
+
Schema,
|
11
|
+
type Scope,
|
12
|
+
Stream,
|
13
|
+
Subscribable,
|
14
|
+
} from '@livestore/utils/effect'
|
5
15
|
import * as otel from '@opentelemetry/api'
|
6
16
|
|
7
|
-
import type
|
8
|
-
import * as EventSequenceNumber from '../schema/EventSequenceNumber.
|
9
|
-
import * as LiveStoreEvent from '../schema/LiveStoreEvent.
|
10
|
-
import { getEventDef, type LiveStoreSchema
|
11
|
-
import
|
12
|
-
import * as SyncState from './syncstate.js'
|
17
|
+
import { type ClientSession, SyncError, type UnexpectedError } from '../adapter-types.ts'
|
18
|
+
import * as EventSequenceNumber from '../schema/EventSequenceNumber.ts'
|
19
|
+
import * as LiveStoreEvent from '../schema/LiveStoreEvent.ts'
|
20
|
+
import { getEventDef, type LiveStoreSchema } from '../schema/mod.ts'
|
21
|
+
import * as SyncState from './syncstate.ts'
|
13
22
|
|
14
23
|
/**
|
15
24
|
* Rebase behaviour:
|
@@ -21,6 +30,10 @@ import * as SyncState from './syncstate.js'
|
|
21
30
|
* - We might need to make the rebase behaviour configurable e.g. to let users manually trigger a rebase
|
22
31
|
*
|
23
32
|
* Longer term we should evalutate whether we can unify the ClientSessionSyncProcessor with the LeaderSyncProcessor.
|
33
|
+
*
|
34
|
+
* The session and leader sync processor are different in the following ways:
|
35
|
+
* - The leader sync processor pulls regular LiveStore events, while the session sync processor pulls SyncState.PayloadUpstream items
|
36
|
+
* - The session sync processor has no downstream nodes.
|
24
37
|
*/
|
25
38
|
export const makeClientSessionSyncProcessor = ({
|
26
39
|
schema,
|
@@ -37,7 +50,7 @@ export const makeClientSessionSyncProcessor = ({
|
|
37
50
|
clientSession: ClientSession
|
38
51
|
runtime: Runtime.Runtime<Scope.Scope>
|
39
52
|
materializeEvent: (
|
40
|
-
eventDecoded: LiveStoreEvent.
|
53
|
+
eventDecoded: LiveStoreEvent.AnyDecoded,
|
41
54
|
options: { otelContext: otel.Context; withChangeset: boolean; materializerHashLeader: Option.Option<number> },
|
42
55
|
) => {
|
43
56
|
writeTables: Set<string>
|
@@ -49,6 +62,7 @@ export const makeClientSessionSyncProcessor = ({
|
|
49
62
|
span: otel.Span
|
50
63
|
params: {
|
51
64
|
leaderPushBatchSize: number
|
65
|
+
simulation?: ClientSessionSyncProcessorSimulationParams
|
52
66
|
}
|
53
67
|
/**
|
54
68
|
* Currently only used in the web adapter:
|
@@ -58,6 +72,11 @@ export const makeClientSessionSyncProcessor = ({
|
|
58
72
|
}): ClientSessionSyncProcessor => {
|
59
73
|
const eventSchema = LiveStoreEvent.makeEventDefSchemaMemo(schema)
|
60
74
|
|
75
|
+
const simSleep = <TKey extends keyof ClientSessionSyncProcessorSimulationParams>(
|
76
|
+
key: TKey,
|
77
|
+
key2: keyof ClientSessionSyncProcessorSimulationParams[TKey],
|
78
|
+
) => Effect.sleep((params.simulation?.[key]?.[key2] ?? 0) as number)
|
79
|
+
|
61
80
|
const syncStateRef = {
|
62
81
|
// The initial state is identical to the leader's initial state
|
63
82
|
current: new SyncState.SyncState({
|
@@ -82,7 +101,10 @@ export const makeClientSessionSyncProcessor = ({
|
|
82
101
|
let baseEventSequenceNumber = syncStateRef.current.localHead
|
83
102
|
const encodedEventDefs = batch.map(({ name, args }) => {
|
84
103
|
const eventDef = getEventDef(schema, name)
|
85
|
-
const nextNumPair = EventSequenceNumber.nextPair(
|
104
|
+
const nextNumPair = EventSequenceNumber.nextPair({
|
105
|
+
seqNum: baseEventSequenceNumber,
|
106
|
+
isClient: eventDef.eventDef.options.clientOnly,
|
107
|
+
})
|
86
108
|
baseEventSequenceNumber = nextNumPair.seqNum
|
87
109
|
return new LiveStoreEvent.EncodedWithMeta(
|
88
110
|
Schema.encodeUnknownSync(eventSchema)({
|
@@ -103,7 +125,7 @@ export const makeClientSessionSyncProcessor = ({
|
|
103
125
|
})
|
104
126
|
|
105
127
|
if (mergeResult._tag === 'unexpected-error') {
|
106
|
-
return shouldNeverHappen('Unexpected error in client-session-sync-processor', mergeResult.
|
128
|
+
return shouldNeverHappen('Unexpected error in client-session-sync-processor', mergeResult.message)
|
107
129
|
}
|
108
130
|
|
109
131
|
span.addEvent('local-push', {
|
@@ -155,7 +177,6 @@ export const makeClientSessionSyncProcessor = ({
|
|
155
177
|
const otelContext = otel.trace.setSpan(otel.context.active(), span)
|
156
178
|
|
157
179
|
const boot: ClientSessionSyncProcessor['boot'] = Effect.gen(function* () {
|
158
|
-
// eslint-disable-next-line unicorn/prefer-global-this
|
159
180
|
if (confirmUnsavedChanges && typeof window !== 'undefined' && typeof window.addEventListener === 'function') {
|
160
181
|
const onBeforeUnload = (event: BeforeUnloadEvent) => {
|
161
182
|
if (syncStateRef.current.pending.length > 0) {
|
@@ -184,18 +205,11 @@ export const makeClientSessionSyncProcessor = ({
|
|
184
205
|
|
185
206
|
yield* FiberHandle.run(leaderPushingFiberHandle, backgroundLeaderPushing)
|
186
207
|
|
187
|
-
const getMergeCounter = () =>
|
188
|
-
clientSession.sqliteDb.select<{ mergeCounter: number }>(
|
189
|
-
sql`SELECT mergeCounter FROM ${SystemTables.LEADER_MERGE_COUNTER_TABLE} WHERE id = 0`,
|
190
|
-
)[0]?.mergeCounter ?? 0
|
191
|
-
|
192
208
|
// NOTE We need to lazily call `.pull` as we want the cursor to be updated
|
193
209
|
yield* Stream.suspend(() =>
|
194
|
-
clientSession.leaderThread.events.pull({
|
195
|
-
cursor: { mergeCounter: getMergeCounter(), eventNum: syncStateRef.current.localHead },
|
196
|
-
}),
|
210
|
+
clientSession.leaderThread.events.pull({ cursor: syncStateRef.current.upstreamHead }),
|
197
211
|
).pipe(
|
198
|
-
Stream.tap(({ payload
|
212
|
+
Stream.tap(({ payload }) =>
|
199
213
|
Effect.gen(function* () {
|
200
214
|
// yield* Effect.logDebug('ClientSessionSyncProcessor:pull', payload)
|
201
215
|
|
@@ -211,13 +225,13 @@ export const makeClientSessionSyncProcessor = ({
|
|
211
225
|
})
|
212
226
|
|
213
227
|
if (mergeResult._tag === 'unexpected-error') {
|
214
|
-
return yield*
|
228
|
+
return yield* new SyncError({ cause: mergeResult.message })
|
215
229
|
} else if (mergeResult._tag === 'reject') {
|
216
230
|
return shouldNeverHappen('Unexpected reject in client-session-sync-processor', mergeResult)
|
217
231
|
}
|
218
232
|
|
219
233
|
syncStateRef.current = mergeResult.newSyncState
|
220
|
-
syncStateUpdateQueue.offer(mergeResult.newSyncState)
|
234
|
+
yield* syncStateUpdateQueue.offer(mergeResult.newSyncState)
|
221
235
|
|
222
236
|
if (mergeResult._tag === 'rebase') {
|
223
237
|
span.addEvent('merge:pull:rebase', {
|
@@ -226,25 +240,28 @@ export const makeClientSessionSyncProcessor = ({
|
|
226
240
|
newEventsCount: mergeResult.newEvents.length,
|
227
241
|
rollbackCount: mergeResult.rollbackEvents.length,
|
228
242
|
res: TRACE_VERBOSE ? JSON.stringify(mergeResult) : undefined,
|
229
|
-
|
243
|
+
rebaseGeneration: mergeResult.newSyncState.localHead.rebaseGeneration,
|
230
244
|
})
|
231
245
|
|
232
246
|
debugInfo.rebaseCount++
|
233
247
|
|
248
|
+
if (SIMULATION_ENABLED) yield* simSleep('pull', '1_before_leader_push_fiber_interrupt')
|
249
|
+
|
234
250
|
yield* FiberHandle.clear(leaderPushingFiberHandle)
|
235
251
|
|
252
|
+
if (SIMULATION_ENABLED) yield* simSleep('pull', '2_before_leader_push_queue_clear')
|
253
|
+
|
236
254
|
// Reset the leader push queue since we're rebasing and will push again
|
237
255
|
yield* BucketQueue.clear(leaderPushQueue)
|
238
256
|
|
239
|
-
yield*
|
257
|
+
if (SIMULATION_ENABLED) yield* simSleep('pull', '3_before_rebase_rollback')
|
240
258
|
|
241
259
|
if (LS_DEV) {
|
242
|
-
Effect.logDebug(
|
260
|
+
yield* Effect.logDebug(
|
243
261
|
'merge:pull:rebase: rollback',
|
244
262
|
mergeResult.rollbackEvents.length,
|
245
263
|
...mergeResult.rollbackEvents.slice(0, 10).map((_) => _.toJSON()),
|
246
|
-
|
247
|
-
).pipe(Effect.provide(runtime), Effect.runSync)
|
264
|
+
)
|
248
265
|
}
|
249
266
|
|
250
267
|
for (let i = mergeResult.rollbackEvents.length - 1; i >= 0; i--) {
|
@@ -255,15 +272,19 @@ export const makeClientSessionSyncProcessor = ({
|
|
255
272
|
}
|
256
273
|
}
|
257
274
|
|
258
|
-
|
275
|
+
if (SIMULATION_ENABLED) yield* simSleep('pull', '4_before_leader_push_queue_offer')
|
276
|
+
|
259
277
|
yield* BucketQueue.offerAll(leaderPushQueue, mergeResult.newSyncState.pending)
|
278
|
+
|
279
|
+
if (SIMULATION_ENABLED) yield* simSleep('pull', '5_before_leader_push_fiber_run')
|
280
|
+
|
281
|
+
yield* FiberHandle.run(leaderPushingFiberHandle, backgroundLeaderPushing)
|
260
282
|
} else {
|
261
283
|
span.addEvent('merge:pull:advance', {
|
262
284
|
payloadTag: payload._tag,
|
263
285
|
payload: TRACE_VERBOSE ? JSON.stringify(payload) : undefined,
|
264
286
|
newEventsCount: mergeResult.newEvents.length,
|
265
287
|
res: TRACE_VERBOSE ? JSON.stringify(mergeResult) : undefined,
|
266
|
-
leaderMergeCounter,
|
267
288
|
})
|
268
289
|
|
269
290
|
debugInfo.advanceCount++
|
@@ -356,3 +377,17 @@ export interface ClientSessionSyncProcessor {
|
|
356
377
|
}
|
357
378
|
}
|
358
379
|
}
|
380
|
+
|
381
|
+
// TODO turn this into a build-time "macro" so all simulation snippets are removed for production builds
|
382
|
+
const SIMULATION_ENABLED = true
|
383
|
+
|
384
|
+
export const ClientSessionSyncProcessorSimulationParams = Schema.Struct({
|
385
|
+
pull: Schema.Struct({
|
386
|
+
'1_before_leader_push_fiber_interrupt': Schema.Int.pipe(Schema.between(0, 1000)),
|
387
|
+
'2_before_leader_push_queue_clear': Schema.Int.pipe(Schema.between(0, 1000)),
|
388
|
+
'3_before_rebase_rollback': Schema.Int.pipe(Schema.between(0, 1000)),
|
389
|
+
'4_before_leader_push_queue_offer': Schema.Int.pipe(Schema.between(0, 1000)),
|
390
|
+
'5_before_leader_push_fiber_run': Schema.Int.pipe(Schema.between(0, 1000)),
|
391
|
+
}),
|
392
|
+
})
|
393
|
+
type ClientSessionSyncProcessorSimulationParams = typeof ClientSessionSyncProcessorSimulationParams.Type
|
package/src/sync/index.ts
CHANGED
@@ -1,3 +1,3 @@
|
|
1
|
-
export * from './
|
2
|
-
export * from './
|
3
|
-
export * from './
|
1
|
+
export * from './ClientSessionSyncProcessor.ts'
|
2
|
+
export * from './sync.ts'
|
3
|
+
export * from './validate-push-payload.ts'
|
@@ -1,8 +1,8 @@
|
|
1
|
-
import { EventSequenceNumber } from '../../schema/mod.
|
2
|
-
import { replacesFacts } from './facts.
|
3
|
-
import { graphologyDag } from './graphology_.
|
4
|
-
import type { HistoryDag } from './history-dag-common.
|
5
|
-
import { emptyHistoryDag } from './history-dag-common.
|
1
|
+
import { EventSequenceNumber } from '../../schema/mod.ts'
|
2
|
+
import { replacesFacts } from './facts.ts'
|
3
|
+
import { graphologyDag } from './graphology_.ts'
|
4
|
+
import type { HistoryDag } from './history-dag-common.ts'
|
5
|
+
import { emptyHistoryDag } from './history-dag-common.ts'
|
6
6
|
|
7
7
|
/**
|
8
8
|
* Idea:
|
package/src/sync/next/facts.ts
CHANGED
@@ -6,10 +6,10 @@ import type {
|
|
6
6
|
EventDefFactsGroup,
|
7
7
|
EventDefFactsSnapshot,
|
8
8
|
FactsCallback,
|
9
|
-
} from '../../schema/EventDef.
|
10
|
-
import type * as EventSequenceNumber from '../../schema/EventSequenceNumber.
|
11
|
-
import { graphologyDag } from './graphology_.
|
12
|
-
import { EMPTY_FACT_VALUE, type HistoryDag, type HistoryDagNode } from './history-dag-common.
|
9
|
+
} from '../../schema/EventDef.ts'
|
10
|
+
import type * as EventSequenceNumber from '../../schema/EventSequenceNumber.ts'
|
11
|
+
import { graphologyDag } from './graphology_.ts'
|
12
|
+
import { EMPTY_FACT_VALUE, type HistoryDag, type HistoryDagNode } from './history-dag-common.ts'
|
13
13
|
|
14
14
|
export const factsSnapshotForEvents = (
|
15
15
|
events: HistoryDagNode[],
|
@@ -13,17 +13,9 @@ export declare class IGraph<
|
|
13
13
|
constructor(options?: graphologyTypes.GraphOptions)
|
14
14
|
}
|
15
15
|
|
16
|
-
export const DirectedGraph = class DirectedGraph extends graphology.DirectedGraph {
|
17
|
-
|
18
|
-
|
19
|
-
}
|
20
|
-
} as typeof IGraph
|
21
|
-
|
22
|
-
export const Graph = class Graph extends graphology.Graph {
|
23
|
-
constructor(options?: graphologyTypes.GraphOptions) {
|
24
|
-
super(options)
|
25
|
-
}
|
26
|
-
} as typeof IGraph
|
16
|
+
export const DirectedGraph = class DirectedGraph extends graphology.DirectedGraph {} as typeof IGraph
|
17
|
+
|
18
|
+
export const Graph = class Graph extends graphology.Graph {} as typeof IGraph
|
27
19
|
|
28
20
|
// export const graphology = graphology_ as graphologyTypes
|
29
21
|
|
@@ -1,6 +1,6 @@
|
|
1
|
-
import type { EventDefFactsGroup } from '../../schema/EventDef.
|
2
|
-
import * as EventSequenceNumber from '../../schema/EventSequenceNumber.
|
3
|
-
import { graphology } from './graphology_.
|
1
|
+
import type { EventDefFactsGroup } from '../../schema/EventDef.ts'
|
2
|
+
import * as EventSequenceNumber from '../../schema/EventSequenceNumber.ts'
|
3
|
+
import { graphology } from './graphology_.ts'
|
4
4
|
|
5
5
|
export const connectionTypeOptions = ['parent', 'facts'] as const
|
6
6
|
export type ConnectionType = (typeof connectionTypeOptions)[number]
|
@@ -1,6 +1,6 @@
|
|
1
|
-
import * as EventSequenceNumber from '../../schema/EventSequenceNumber.
|
2
|
-
import { factsToString, validateFacts } from './facts.
|
3
|
-
import { emptyHistoryDag, type HistoryDagNode, rootParentNum } from './history-dag-common.
|
1
|
+
import * as EventSequenceNumber from '../../schema/EventSequenceNumber.ts'
|
2
|
+
import { factsToString, validateFacts } from './facts.ts'
|
3
|
+
import { emptyHistoryDag, type HistoryDagNode, rootParentNum } from './history-dag-common.ts'
|
4
4
|
|
5
5
|
export const historyDagFromNodes = (dagNodes: HistoryDagNode[], options?: { skipFactsCheck: boolean }) => {
|
6
6
|
if (options?.skipFactsCheck !== true) {
|
package/src/sync/next/mod.ts
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
export * from './
|
2
|
-
export * from './
|
3
|
-
export * from './
|
4
|
-
export * from './
|
5
|
-
export * from './rebase-events.
|
1
|
+
export * from './compact-events.ts'
|
2
|
+
export * from './facts.ts'
|
3
|
+
export * from './history-dag.ts'
|
4
|
+
export * from './history-dag-common.ts'
|
5
|
+
export * from './rebase-events.ts'
|
@@ -1,14 +1,14 @@
|
|
1
|
-
import type { EventDef, EventDefFactsSnapshot } from '../../schema/EventDef.
|
2
|
-
import * as EventSequenceNumber from '../../schema/EventSequenceNumber.
|
3
|
-
import type * as LiveStoreEvent from '../../schema/LiveStoreEvent.
|
1
|
+
import type { EventDef, EventDefFactsSnapshot } from '../../schema/EventDef.ts'
|
2
|
+
import * as EventSequenceNumber from '../../schema/EventSequenceNumber.ts'
|
3
|
+
import type * as LiveStoreEvent from '../../schema/LiveStoreEvent.ts'
|
4
4
|
import {
|
5
5
|
applyFactGroups,
|
6
|
-
factsIntersect,
|
7
6
|
type FactValidationResult,
|
7
|
+
factsIntersect,
|
8
8
|
getFactsGroupForEventArgs,
|
9
9
|
validateFacts,
|
10
|
-
} from './facts.
|
11
|
-
import type { HistoryDagNode } from './history-dag-common.
|
10
|
+
} from './facts.ts'
|
11
|
+
import type { HistoryDagNode } from './history-dag-common.ts'
|
12
12
|
|
13
13
|
export type RebaseEventWithConflict = HistoryDagNode & {
|
14
14
|
conflictType: 'overlap' | 'missing-requirement'
|
@@ -38,6 +38,7 @@ export const defaultRebaseFn: RebaseFn = ({ pendingLocalEvents }) => {
|
|
38
38
|
return { rebasedLocalEvents: pendingLocalEvents }
|
39
39
|
}
|
40
40
|
|
41
|
+
// TODO replace in favour of current rebase impl
|
41
42
|
export const rebaseEvents = ({
|
42
43
|
rebaseFn,
|
43
44
|
pendingLocalEvents,
|
@@ -2,10 +2,10 @@ import { defineEvent } from '@livestore/common/schema'
|
|
2
2
|
import { Schema } from '@livestore/utils/effect'
|
3
3
|
import { describe, expect, it } from 'vitest'
|
4
4
|
|
5
|
-
import { compactEvents } from '../compact-events.
|
6
|
-
import { historyDagFromNodes } from '../history-dag.
|
7
|
-
import { customSerializer } from './compact-events.test.
|
8
|
-
import { printEvent, toEventNodes } from './event-fixtures.
|
5
|
+
import { compactEvents } from '../compact-events.ts'
|
6
|
+
import { historyDagFromNodes } from '../history-dag.ts'
|
7
|
+
import { customSerializer } from './compact-events.test.ts'
|
8
|
+
import { printEvent, toEventNodes } from './event-fixtures.ts'
|
9
9
|
|
10
10
|
expect.addSnapshotSerializer(customSerializer)
|
11
11
|
|
@@ -1,11 +1,11 @@
|
|
1
1
|
import type { EventDefFacts } from '@livestore/common/schema'
|
2
2
|
import { describe, expect, it } from 'vitest'
|
3
3
|
|
4
|
-
import { compactEvents } from '../compact-events.
|
5
|
-
import { historyDagFromNodes } from '../history-dag.
|
6
|
-
import type { HistoryDagNode } from '../history-dag-common.
|
7
|
-
import { EMPTY_FACT_VALUE } from '../history-dag-common.
|
8
|
-
import { events as eventDefs, printEvent, toEventNodes } from './event-fixtures.
|
4
|
+
import { compactEvents } from '../compact-events.ts'
|
5
|
+
import { historyDagFromNodes } from '../history-dag.ts'
|
6
|
+
import type { HistoryDagNode } from '../history-dag-common.ts'
|
7
|
+
import { EMPTY_FACT_VALUE } from '../history-dag-common.ts'
|
8
|
+
import { events as eventDefs, printEvent, toEventNodes } from './event-fixtures.ts'
|
9
9
|
|
10
10
|
const customStringify = (value: any): string => {
|
11
11
|
if (value === null) {
|
@@ -64,7 +64,7 @@ const factsSetToString = (facts: EventDefFacts, prefix: string) =>
|
|
64
64
|
export const customSerializer = {
|
65
65
|
test: (val: unknown) => Array.isArray(val),
|
66
66
|
print: (val: unknown[], _serialize: (item: unknown) => string) => {
|
67
|
-
return
|
67
|
+
return `[\n${(val as any[]).map((item) => ` ${customStringify(item)}`).join('\n')}\n]`
|
68
68
|
},
|
69
69
|
} as any
|
70
70
|
|
@@ -1,12 +1,12 @@
|
|
1
1
|
import { Schema } from '@livestore/utils/effect'
|
2
2
|
|
3
|
-
import type { EventDef } from '../../../schema/EventDef.
|
4
|
-
import { defineEvent, defineFacts } from '../../../schema/EventDef.
|
5
|
-
import * as EventSequenceNumber from '../../../schema/EventSequenceNumber.
|
6
|
-
import { factsSnapshotForDag, getFactsGroupForEventArgs } from '../facts.
|
7
|
-
import { historyDagFromNodes } from '../history-dag.
|
8
|
-
import type { HistoryDagNode } from '../history-dag-common.
|
9
|
-
import { rootEventNode } from '../history-dag-common.
|
3
|
+
import type { EventDef } from '../../../schema/EventDef.ts'
|
4
|
+
import { defineEvent, defineFacts } from '../../../schema/EventDef.ts'
|
5
|
+
import * as EventSequenceNumber from '../../../schema/EventSequenceNumber.ts'
|
6
|
+
import { factsSnapshotForDag, getFactsGroupForEventArgs } from '../facts.ts'
|
7
|
+
import { historyDagFromNodes } from '../history-dag.ts'
|
8
|
+
import type { HistoryDagNode } from '../history-dag-common.ts'
|
9
|
+
import { rootEventNode } from '../history-dag-common.ts'
|
10
10
|
|
11
11
|
export const printEvent = ({ seqNum, parentSeqNum, factsGroup, ...rest }: HistoryDagNode) => ({
|
12
12
|
seqNum: EventSequenceNumber.toString(seqNum),
|
@@ -144,7 +144,10 @@ export const toEventNodes = (
|
|
144
144
|
|
145
145
|
const eventNodes = partialEvents.map((partialEvent) => {
|
146
146
|
const eventDef = eventDefs[partialEvent.name]!
|
147
|
-
const eventNum = EventSequenceNumber.nextPair(
|
147
|
+
const eventNum = EventSequenceNumber.nextPair({
|
148
|
+
seqNum: currentEventSequenceNumber,
|
149
|
+
isClient: eventDef.options.clientOnly,
|
150
|
+
}).seqNum
|
148
151
|
currentEventSequenceNumber = eventNum
|
149
152
|
|
150
153
|
const factsSnapshot = factsSnapshotForDag(historyDagFromNodes(nodesAcc, { skipFactsCheck: true }), undefined)
|
@@ -221,8 +224,14 @@ const getParentNum = (eventNum: EventSequenceNumber.EventSequenceNumber): EventS
|
|
221
224
|
const clientParentNum = eventNum.client - 1
|
222
225
|
|
223
226
|
if (clientParentNum < 0) {
|
224
|
-
return EventSequenceNumber.make({
|
227
|
+
return EventSequenceNumber.make({
|
228
|
+
global: globalParentNum - 1,
|
229
|
+
client: EventSequenceNumber.clientDefault,
|
230
|
+
})
|
225
231
|
}
|
226
232
|
|
227
|
-
return EventSequenceNumber.make({
|
233
|
+
return EventSequenceNumber.make({
|
234
|
+
global: globalParentNum,
|
235
|
+
client: clientParentNum,
|
236
|
+
})
|
228
237
|
}
|
@@ -1 +1 @@
|
|
1
|
-
export * from './event-fixtures.
|
1
|
+
export * from './event-fixtures.ts'
|
package/src/sync/sync.ts
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
import type { Effect, HttpClient, Option, Scope, Stream, SubscriptionRef } from '@livestore/utils/effect'
|
2
2
|
import { Schema } from '@livestore/utils/effect'
|
3
3
|
|
4
|
-
import type { UnexpectedError } from '../adapter-types.
|
5
|
-
import type { InitialSyncOptions } from '../leader-thread/types.
|
6
|
-
import * as EventSequenceNumber from '../schema/EventSequenceNumber.
|
7
|
-
import type * as LiveStoreEvent from '../schema/LiveStoreEvent.
|
4
|
+
import type { UnexpectedError } from '../adapter-types.ts'
|
5
|
+
import type { InitialSyncOptions } from '../leader-thread/types.ts'
|
6
|
+
import * as EventSequenceNumber from '../schema/EventSequenceNumber.ts'
|
7
|
+
import type * as LiveStoreEvent from '../schema/LiveStoreEvent.ts'
|
8
8
|
|
9
9
|
/**
|
10
10
|
* Those arguments can be used to implement multi-tenancy etc and are passed in from the store.
|
@@ -80,6 +80,7 @@ export type SyncBackend<TSyncMetadata = Schema.JsonValue> = {
|
|
80
80
|
|
81
81
|
export class IsOfflineError extends Schema.TaggedError<IsOfflineError>()('IsOfflineError', {}) {}
|
82
82
|
|
83
|
+
// TODO gt rid of this error in favour of SyncError
|
83
84
|
export class InvalidPushError extends Schema.TaggedError<InvalidPushError>()('InvalidPushError', {
|
84
85
|
reason: Schema.Union(
|
85
86
|
Schema.TaggedStruct('Unexpected', {
|
@@ -92,10 +93,12 @@ export class InvalidPushError extends Schema.TaggedError<InvalidPushError>()('In
|
|
92
93
|
),
|
93
94
|
}) {}
|
94
95
|
|
96
|
+
// TODO gt rid of this error in favour of SyncError
|
95
97
|
export class InvalidPullError extends Schema.TaggedError<InvalidPullError>()('InvalidPullError', {
|
96
98
|
message: Schema.String,
|
97
99
|
}) {}
|
98
100
|
|
101
|
+
// TODO gt rid of this error in favour of SyncError
|
99
102
|
export class LeaderAheadError extends Schema.TaggedError<LeaderAheadError>()('LeaderAheadError', {
|
100
103
|
minimumExpectedNum: EventSequenceNumber.EventSequenceNumber,
|
101
104
|
providedNum: EventSequenceNumber.EventSequenceNumber,
|
@@ -1,16 +1,17 @@
|
|
1
|
-
/* eslint-disable prefer-arrow/prefer-arrow-functions */
|
2
1
|
import { describe, expect, it } from 'vitest'
|
3
2
|
|
4
|
-
import * as EventSequenceNumber from '../schema/EventSequenceNumber.
|
5
|
-
import * as LiveStoreEvent from '../schema/LiveStoreEvent.
|
6
|
-
import * as SyncState from './syncstate.
|
3
|
+
import * as EventSequenceNumber from '../schema/EventSequenceNumber.ts'
|
4
|
+
import * as LiveStoreEvent from '../schema/LiveStoreEvent.ts'
|
5
|
+
import * as SyncState from './syncstate.ts'
|
7
6
|
|
8
7
|
class TestEvent extends LiveStoreEvent.EncodedWithMeta {
|
8
|
+
public readonly payload: string
|
9
|
+
public readonly isClient: boolean
|
9
10
|
constructor(
|
10
|
-
seqNum: EventSequenceNumber.
|
11
|
-
parentSeqNum: EventSequenceNumber.
|
12
|
-
|
13
|
-
|
11
|
+
seqNum: EventSequenceNumber.EventSequenceNumberInput,
|
12
|
+
parentSeqNum: EventSequenceNumber.EventSequenceNumberInput,
|
13
|
+
payload: string,
|
14
|
+
isClient: boolean,
|
14
15
|
) {
|
15
16
|
super({
|
16
17
|
seqNum: EventSequenceNumber.make(seqNum),
|
@@ -20,10 +21,12 @@ class TestEvent extends LiveStoreEvent.EncodedWithMeta {
|
|
20
21
|
clientId: 'static-local-id',
|
21
22
|
sessionId: 'static-session-id',
|
22
23
|
})
|
24
|
+
this.payload = payload
|
25
|
+
this.isClient = isClient
|
23
26
|
}
|
24
27
|
|
25
|
-
rebase_ = (parentSeqNum: EventSequenceNumber.EventSequenceNumber) => {
|
26
|
-
return this.rebase(parentSeqNum, this.
|
28
|
+
rebase_ = (parentSeqNum: EventSequenceNumber.EventSequenceNumber, rebaseGeneration: number) => {
|
29
|
+
return this.rebase({ parentSeqNum, isClient: this.isClient, rebaseGeneration })
|
27
30
|
}
|
28
31
|
|
29
32
|
// Only used for Vitest printing
|
@@ -41,7 +44,7 @@ const e2_1 = new TestEvent({ global: 2, client: 1 }, e2_0.seqNum, 'a', true)
|
|
41
44
|
|
42
45
|
const isEqualEvent = LiveStoreEvent.isEqualEncoded
|
43
46
|
|
44
|
-
const isClientEvent = (event: LiveStoreEvent.EncodedWithMeta) => (event as TestEvent).
|
47
|
+
const isClientEvent = (event: LiveStoreEvent.EncodedWithMeta) => (event as TestEvent).isClient
|
45
48
|
|
46
49
|
describe('syncstate', () => {
|
47
50
|
describe('merge', () => {
|
@@ -62,8 +65,8 @@ describe('syncstate', () => {
|
|
62
65
|
upstreamHead: EventSequenceNumber.ROOT,
|
63
66
|
localHead: e2_0.seqNum,
|
64
67
|
})
|
65
|
-
const e1_0_e2_0 = e1_0.rebase_(e2_0.seqNum)
|
66
|
-
const e1_1_e2_1 = e1_1.rebase_(e1_0_e2_0.seqNum)
|
68
|
+
const e1_0_e2_0 = e1_0.rebase_(e2_0.seqNum, 0)
|
69
|
+
const e1_1_e2_1 = e1_1.rebase_(e1_0_e2_0.seqNum, 0)
|
67
70
|
const result = merge({
|
68
71
|
syncState,
|
69
72
|
payload: SyncState.PayloadUpstreamRebase.make({
|
@@ -71,7 +74,7 @@ describe('syncstate', () => {
|
|
71
74
|
newEvents: [e1_0_e2_0, e1_1_e2_1],
|
72
75
|
}),
|
73
76
|
})
|
74
|
-
const e2_0_e3_0 = e2_0.rebase_(e1_0_e2_0.seqNum)
|
77
|
+
const e2_0_e3_0 = e2_0.rebase_(e1_0_e2_0.seqNum, 1)
|
75
78
|
expectRebase(result)
|
76
79
|
expectEventArraysEqual(result.newSyncState.pending, [e2_0_e3_0])
|
77
80
|
expect(result.newSyncState.upstreamHead).toMatchObject(e1_1_e2_1.seqNum)
|
@@ -86,7 +89,7 @@ describe('syncstate', () => {
|
|
86
89
|
upstreamHead: EventSequenceNumber.ROOT,
|
87
90
|
localHead: e2_0.seqNum,
|
88
91
|
})
|
89
|
-
const e1_1_e2_0 = e1_1.rebase_(e1_0.seqNum)
|
92
|
+
const e1_1_e2_0 = e1_1.rebase_(e1_0.seqNum, 0)
|
90
93
|
const result = merge({
|
91
94
|
syncState,
|
92
95
|
payload: SyncState.PayloadUpstreamRebase.make({
|
@@ -94,7 +97,7 @@ describe('syncstate', () => {
|
|
94
97
|
rollbackEvents: [e1_1],
|
95
98
|
}),
|
96
99
|
})
|
97
|
-
const e2_0_e3_0 = e2_0.rebase_(e1_1_e2_0.seqNum)
|
100
|
+
const e2_0_e3_0 = e2_0.rebase_(e1_1_e2_0.seqNum, 1)
|
98
101
|
expectRebase(result)
|
99
102
|
expectEventArraysEqual(result.newSyncState.pending, [e2_0_e3_0])
|
100
103
|
expect(result.newSyncState.upstreamHead).toMatchObject(e1_1_e2_0.seqNum)
|
@@ -326,7 +329,7 @@ describe('syncstate', () => {
|
|
326
329
|
})
|
327
330
|
const result = merge({ syncState, payload: SyncState.PayloadUpstreamAdvance.make({ newEvents: [e1_1] }) })
|
328
331
|
|
329
|
-
const e1_0_e1_2 = e1_0.rebase_(e1_1.seqNum)
|
332
|
+
const e1_0_e1_2 = e1_0.rebase_(e1_1.seqNum, 1)
|
330
333
|
|
331
334
|
expectRebase(result)
|
332
335
|
expectEventArraysEqual(result.newSyncState.pending, [e1_0_e1_2])
|
@@ -344,7 +347,7 @@ describe('syncstate', () => {
|
|
344
347
|
localHead: e2_0_b.seqNum,
|
345
348
|
})
|
346
349
|
const result = merge({ syncState, payload: SyncState.PayloadUpstreamAdvance.make({ newEvents: [e2_0] }) })
|
347
|
-
const e2_0_e3_0 = e2_0_b.rebase_(e2_0.seqNum)
|
350
|
+
const e2_0_e3_0 = e2_0_b.rebase_(e2_0.seqNum, 1)
|
348
351
|
|
349
352
|
expectRebase(result)
|
350
353
|
expectEventArraysEqual(result.newSyncState.pending, [e2_0_e3_0])
|
@@ -365,7 +368,7 @@ describe('syncstate', () => {
|
|
365
368
|
payload: SyncState.PayloadUpstreamAdvance.make({ newEvents: [e1_1, e1_2, e1_3, e2_0] }),
|
366
369
|
})
|
367
370
|
|
368
|
-
const e1_0_e3_0 = e1_0.rebase_(e2_0.seqNum)
|
371
|
+
const e1_0_e3_0 = e1_0.rebase_(e2_0.seqNum, 1)
|
369
372
|
|
370
373
|
expectRebase(result)
|
371
374
|
expectEventArraysEqual(result.newSyncState.pending, [e1_0_e3_0])
|
@@ -384,7 +387,7 @@ describe('syncstate', () => {
|
|
384
387
|
payload: SyncState.PayloadUpstreamAdvance.make({ newEvents: [e1_0, e1_2, e1_3, e2_0] }),
|
385
388
|
})
|
386
389
|
|
387
|
-
const e1_1_e2_1 = e1_1.rebase_(e2_0.seqNum)
|
390
|
+
const e1_1_e2_1 = e1_1.rebase_(e2_0.seqNum, 1)
|
388
391
|
|
389
392
|
expectRebase(result)
|
390
393
|
expectEventArraysEqual(result.newSyncState.pending, [e1_1_e2_1])
|
@@ -405,8 +408,8 @@ describe('syncstate', () => {
|
|
405
408
|
payload: SyncState.PayloadUpstreamAdvance.make({ newEvents: [e1_1, e1_2, e1_3, e2_0] }),
|
406
409
|
})
|
407
410
|
|
408
|
-
const e1_0_e2_1 = e1_0.rebase_(e2_0.seqNum)
|
409
|
-
const e1_1_e2_2 = e1_1.rebase_(e1_0_e2_1.seqNum)
|
411
|
+
const e1_0_e2_1 = e1_0.rebase_(e2_0.seqNum, 1)
|
412
|
+
const e1_1_e2_2 = e1_1.rebase_(e1_0_e2_1.seqNum, 1)
|
410
413
|
|
411
414
|
expectRebase(result)
|
412
415
|
expectEventArraysEqual(result.newSyncState.pending, [e1_0_e2_1, e1_1_e2_2])
|