@livestore/common 0.3.0-dev.2 → 0.3.0-dev.21
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 +21 -21
- package/dist/adapter-types.d.ts +97 -53
- package/dist/adapter-types.d.ts.map +1 -1
- package/dist/adapter-types.js +17 -0
- package/dist/adapter-types.js.map +1 -1
- package/dist/bounded-collections.d.ts +1 -1
- package/dist/bounded-collections.d.ts.map +1 -1
- package/dist/debug-info.d.ts +1 -1
- package/dist/debug-info.d.ts.map +1 -1
- package/dist/derived-mutations.d.ts +5 -5
- package/dist/derived-mutations.d.ts.map +1 -1
- package/dist/derived-mutations.js +3 -3
- package/dist/derived-mutations.js.map +1 -1
- package/dist/derived-mutations.test.js.map +1 -1
- package/dist/devtools/devtools-messages-client-session.d.ts +389 -0
- package/dist/devtools/devtools-messages-client-session.d.ts.map +1 -0
- package/dist/devtools/devtools-messages-client-session.js +96 -0
- package/dist/devtools/devtools-messages-client-session.js.map +1 -0
- package/dist/devtools/devtools-messages-common.d.ts +61 -0
- package/dist/devtools/devtools-messages-common.d.ts.map +1 -0
- package/dist/devtools/devtools-messages-common.js +54 -0
- package/dist/devtools/devtools-messages-common.js.map +1 -0
- package/dist/devtools/devtools-messages-leader.d.ts +393 -0
- package/dist/devtools/devtools-messages-leader.d.ts.map +1 -0
- package/dist/devtools/devtools-messages-leader.js +148 -0
- package/dist/devtools/devtools-messages-leader.js.map +1 -0
- package/dist/devtools/devtools-messages.d.ts +3 -592
- package/dist/devtools/devtools-messages.d.ts.map +1 -1
- package/dist/devtools/devtools-messages.js +3 -171
- package/dist/devtools/devtools-messages.js.map +1 -1
- package/dist/devtools/devtools-sessioninfo.d.ts +28 -0
- package/dist/devtools/devtools-sessioninfo.d.ts.map +1 -0
- package/dist/devtools/devtools-sessioninfo.js +34 -0
- package/dist/devtools/devtools-sessioninfo.js.map +1 -0
- package/dist/devtools/devtools-sessions-channel.d.ts +28 -0
- package/dist/devtools/devtools-sessions-channel.d.ts.map +1 -0
- package/dist/devtools/devtools-sessions-channel.js +34 -0
- package/dist/devtools/devtools-sessions-channel.js.map +1 -0
- package/dist/devtools/index.d.ts +35 -38
- package/dist/devtools/index.d.ts.map +1 -1
- package/dist/devtools/index.js +20 -45
- package/dist/devtools/index.js.map +1 -1
- package/dist/devtools/mod.d.ts +39 -0
- package/dist/devtools/mod.d.ts.map +1 -0
- package/dist/devtools/mod.js +27 -0
- package/dist/devtools/mod.js.map +1 -0
- package/dist/index.d.ts +2 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/init-singleton-tables.d.ts +2 -2
- package/dist/init-singleton-tables.d.ts.map +1 -1
- package/dist/init-singleton-tables.js.map +1 -1
- package/dist/leader-thread/LeaderSyncProcessor.d.ts +39 -0
- package/dist/leader-thread/LeaderSyncProcessor.d.ts.map +1 -0
- package/dist/leader-thread/LeaderSyncProcessor.js +527 -0
- package/dist/leader-thread/LeaderSyncProcessor.js.map +1 -0
- package/dist/leader-thread/apply-mutation.d.ts +5 -2
- package/dist/leader-thread/apply-mutation.d.ts.map +1 -1
- package/dist/leader-thread/apply-mutation.js +55 -35
- package/dist/leader-thread/apply-mutation.js.map +1 -1
- package/dist/leader-thread/connection.d.ts +34 -6
- package/dist/leader-thread/connection.d.ts.map +1 -1
- package/dist/leader-thread/connection.js +22 -7
- package/dist/leader-thread/connection.js.map +1 -1
- package/dist/leader-thread/leader-worker-devtools.d.ts +1 -1
- package/dist/leader-thread/leader-worker-devtools.d.ts.map +1 -1
- package/dist/leader-thread/leader-worker-devtools.js +147 -124
- package/dist/leader-thread/leader-worker-devtools.js.map +1 -1
- package/dist/leader-thread/make-leader-thread-layer.d.ts +12 -11
- package/dist/leader-thread/make-leader-thread-layer.d.ts.map +1 -1
- package/dist/leader-thread/make-leader-thread-layer.js +55 -18
- package/dist/leader-thread/make-leader-thread-layer.js.map +1 -1
- package/dist/leader-thread/mutationlog.d.ts +6 -19
- package/dist/leader-thread/mutationlog.d.ts.map +1 -1
- package/dist/leader-thread/mutationlog.js +12 -9
- package/dist/leader-thread/mutationlog.js.map +1 -1
- package/dist/leader-thread/pull-queue-set.d.ts +3 -3
- package/dist/leader-thread/pull-queue-set.d.ts.map +1 -1
- package/dist/leader-thread/pull-queue-set.js +9 -0
- package/dist/leader-thread/pull-queue-set.js.map +1 -1
- package/dist/leader-thread/recreate-db.d.ts +4 -2
- package/dist/leader-thread/recreate-db.d.ts.map +1 -1
- package/dist/leader-thread/recreate-db.js +32 -21
- package/dist/leader-thread/recreate-db.js.map +1 -1
- package/dist/leader-thread/shutdown-channel.d.ts +2 -5
- package/dist/leader-thread/shutdown-channel.d.ts.map +1 -1
- package/dist/leader-thread/shutdown-channel.js +2 -4
- package/dist/leader-thread/shutdown-channel.js.map +1 -1
- package/dist/leader-thread/types.d.ts +58 -26
- package/dist/leader-thread/types.d.ts.map +1 -1
- package/dist/leader-thread/types.js +1 -3
- package/dist/leader-thread/types.js.map +1 -1
- package/dist/mutation.d.ts +9 -2
- package/dist/mutation.d.ts.map +1 -1
- package/dist/mutation.js +5 -5
- package/dist/mutation.js.map +1 -1
- package/dist/otel.d.ts +2 -0
- package/dist/otel.d.ts.map +1 -1
- package/dist/otel.js +5 -0
- package/dist/otel.js.map +1 -1
- package/dist/query-builder/api.d.ts +3 -3
- package/dist/query-builder/api.d.ts.map +1 -1
- package/dist/query-builder/impl.d.ts +4 -4
- package/dist/query-builder/impl.d.ts.map +1 -1
- package/dist/query-builder/impl.js.map +1 -1
- package/dist/query-builder/impl.test.js +16 -1
- package/dist/query-builder/impl.test.js.map +1 -1
- package/dist/query-info.d.ts +3 -3
- package/dist/query-info.d.ts.map +1 -1
- package/dist/rehydrate-from-mutationlog.d.ts +5 -5
- package/dist/rehydrate-from-mutationlog.d.ts.map +1 -1
- package/dist/rehydrate-from-mutationlog.js +23 -27
- package/dist/rehydrate-from-mutationlog.js.map +1 -1
- package/dist/schema/EventId.d.ts +27 -16
- package/dist/schema/EventId.d.ts.map +1 -1
- package/dist/schema/EventId.js +36 -11
- package/dist/schema/EventId.js.map +1 -1
- package/dist/schema/EventId.test.d.ts +2 -0
- package/dist/schema/EventId.test.d.ts.map +1 -0
- package/dist/schema/EventId.test.js +11 -0
- package/dist/schema/EventId.test.js.map +1 -0
- package/dist/schema/MutationEvent.d.ts +76 -82
- package/dist/schema/MutationEvent.d.ts.map +1 -1
- package/dist/schema/MutationEvent.js +53 -20
- package/dist/schema/MutationEvent.js.map +1 -1
- package/dist/schema/db-schema/ast/sqlite.d.ts +69 -0
- package/dist/schema/db-schema/ast/sqlite.d.ts.map +1 -0
- package/dist/schema/db-schema/ast/sqlite.js +71 -0
- package/dist/schema/db-schema/ast/sqlite.js.map +1 -0
- package/dist/schema/db-schema/ast/validate.d.ts +3 -0
- package/dist/schema/db-schema/ast/validate.d.ts.map +1 -0
- package/dist/schema/db-schema/ast/validate.js +12 -0
- package/dist/schema/db-schema/ast/validate.js.map +1 -0
- package/dist/schema/db-schema/dsl/field-defs.d.ts +90 -0
- package/dist/schema/db-schema/dsl/field-defs.d.ts.map +1 -0
- package/dist/schema/db-schema/dsl/field-defs.js +87 -0
- package/dist/schema/db-schema/dsl/field-defs.js.map +1 -0
- package/dist/schema/db-schema/dsl/field-defs.test.d.ts +2 -0
- package/dist/schema/db-schema/dsl/field-defs.test.d.ts.map +1 -0
- package/dist/schema/db-schema/dsl/field-defs.test.js +29 -0
- package/dist/schema/db-schema/dsl/field-defs.test.js.map +1 -0
- package/dist/schema/db-schema/dsl/mod.d.ts +88 -0
- package/dist/schema/db-schema/dsl/mod.d.ts.map +1 -0
- package/dist/schema/db-schema/dsl/mod.js +35 -0
- package/dist/schema/db-schema/dsl/mod.js.map +1 -0
- package/dist/schema/db-schema/hash.d.ts +2 -0
- package/dist/schema/db-schema/hash.d.ts.map +1 -0
- package/dist/schema/db-schema/hash.js +14 -0
- package/dist/schema/db-schema/hash.js.map +1 -0
- package/dist/schema/db-schema/mod.d.ts +3 -0
- package/dist/schema/db-schema/mod.d.ts.map +1 -0
- package/dist/schema/db-schema/mod.js +3 -0
- package/dist/schema/db-schema/mod.js.map +1 -0
- package/dist/schema/mod.d.ts +1 -0
- package/dist/schema/mod.d.ts.map +1 -1
- package/dist/schema/mod.js +1 -0
- package/dist/schema/mod.js.map +1 -1
- package/dist/schema/mutations.d.ts +8 -9
- package/dist/schema/mutations.d.ts.map +1 -1
- package/dist/schema/mutations.js +2 -2
- package/dist/schema/mutations.js.map +1 -1
- package/dist/schema/schema-helpers.d.ts.map +1 -1
- package/dist/schema/schema-helpers.js +1 -1
- package/dist/schema/schema-helpers.js.map +1 -1
- package/dist/schema/schema.d.ts +5 -2
- package/dist/schema/schema.d.ts.map +1 -1
- package/dist/schema/schema.js +20 -9
- package/dist/schema/schema.js.map +1 -1
- package/dist/schema/system-tables.d.ts +65 -47
- package/dist/schema/system-tables.d.ts.map +1 -1
- package/dist/schema/system-tables.js +24 -13
- package/dist/schema/system-tables.js.map +1 -1
- package/dist/schema/table-def.d.ts +18 -24
- package/dist/schema/table-def.d.ts.map +1 -1
- package/dist/schema/table-def.js +3 -4
- package/dist/schema/table-def.js.map +1 -1
- package/dist/schema-management/common.d.ts +3 -3
- package/dist/schema-management/common.d.ts.map +1 -1
- package/dist/schema-management/common.js.map +1 -1
- package/dist/schema-management/migrations.d.ts +6 -6
- package/dist/schema-management/migrations.d.ts.map +1 -1
- package/dist/schema-management/migrations.js +13 -8
- package/dist/schema-management/migrations.js.map +1 -1
- package/dist/schema-management/validate-mutation-defs.d.ts.map +1 -1
- package/dist/schema-management/validate-mutation-defs.js +2 -2
- package/dist/schema-management/validate-mutation-defs.js.map +1 -1
- package/dist/sql-queries/misc.d.ts.map +1 -1
- package/dist/sql-queries/sql-queries.d.ts +1 -1
- package/dist/sql-queries/sql-queries.d.ts.map +1 -1
- package/dist/sql-queries/sql-queries.js.map +1 -1
- package/dist/sql-queries/sql-query-builder.d.ts +1 -1
- package/dist/sql-queries/sql-query-builder.d.ts.map +1 -1
- package/dist/sql-queries/sql-query-builder.js.map +1 -1
- package/dist/sql-queries/types.d.ts +2 -1
- package/dist/sql-queries/types.d.ts.map +1 -1
- package/dist/sql-queries/types.js.map +1 -1
- package/dist/sync/{client-session-sync-processor.d.ts → ClientSessionSyncProcessor.d.ts} +25 -14
- package/dist/sync/ClientSessionSyncProcessor.d.ts.map +1 -0
- package/dist/sync/ClientSessionSyncProcessor.js +199 -0
- package/dist/sync/ClientSessionSyncProcessor.js.map +1 -0
- package/dist/sync/index.d.ts +1 -1
- package/dist/sync/index.d.ts.map +1 -1
- package/dist/sync/index.js +1 -1
- package/dist/sync/index.js.map +1 -1
- package/dist/sync/next/compact-events.d.ts.map +1 -1
- 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 +3 -4
- package/dist/sync/next/history-dag-common.d.ts.map +1 -1
- package/dist/sync/next/history-dag-common.js +3 -1
- package/dist/sync/next/history-dag-common.js.map +1 -1
- package/dist/sync/next/history-dag.d.ts.map +1 -1
- package/dist/sync/next/history-dag.js +1 -1
- package/dist/sync/next/history-dag.js.map +1 -1
- package/dist/sync/next/rebase-events.d.ts +6 -4
- package/dist/sync/next/rebase-events.d.ts.map +1 -1
- package/dist/sync/next/rebase-events.js +6 -3
- package/dist/sync/next/rebase-events.js.map +1 -1
- package/dist/sync/next/test/compact-events.calculator.test.js +12 -12
- package/dist/sync/next/test/compact-events.calculator.test.js.map +1 -1
- package/dist/sync/next/test/compact-events.test.js +43 -43
- package/dist/sync/next/test/compact-events.test.js.map +1 -1
- package/dist/sync/next/test/mutation-fixtures.d.ts +4 -4
- package/dist/sync/next/test/mutation-fixtures.d.ts.map +1 -1
- package/dist/sync/next/test/mutation-fixtures.js +12 -16
- package/dist/sync/next/test/mutation-fixtures.js.map +1 -1
- package/dist/sync/sync.d.ts +31 -16
- package/dist/sync/sync.d.ts.map +1 -1
- package/dist/sync/sync.js +7 -3
- package/dist/sync/sync.js.map +1 -1
- package/dist/sync/syncstate.d.ts +177 -44
- package/dist/sync/syncstate.d.ts.map +1 -1
- package/dist/sync/syncstate.js +188 -56
- package/dist/sync/syncstate.js.map +1 -1
- package/dist/sync/syncstate.test.js +162 -92
- 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.d.ts.map +1 -1
- package/dist/sync/validate-push-payload.js +2 -2
- package/dist/sync/validate-push-payload.js.map +1 -1
- package/dist/util.d.ts +2 -2
- package/dist/util.d.ts.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 -6
- package/src/adapter-types.ts +80 -56
- package/src/derived-mutations.test.ts +1 -1
- package/src/derived-mutations.ts +13 -9
- package/src/devtools/devtools-messages-client-session.ts +141 -0
- package/src/devtools/devtools-messages-common.ts +106 -0
- package/src/devtools/devtools-messages-leader.ts +192 -0
- package/src/devtools/devtools-messages.ts +3 -243
- package/src/devtools/devtools-sessioninfo.ts +99 -0
- package/src/devtools/mod.ts +36 -0
- package/src/index.ts +2 -8
- package/src/init-singleton-tables.ts +2 -2
- package/src/leader-thread/LeaderSyncProcessor.ts +833 -0
- package/src/leader-thread/apply-mutation.ts +87 -43
- package/src/leader-thread/connection.ts +54 -9
- package/src/leader-thread/leader-worker-devtools.ts +199 -174
- package/src/leader-thread/make-leader-thread-layer.ts +89 -35
- package/src/leader-thread/mutationlog.ts +20 -14
- package/src/leader-thread/pull-queue-set.ts +10 -1
- package/src/leader-thread/recreate-db.ts +38 -25
- package/src/leader-thread/shutdown-channel.ts +2 -4
- package/src/leader-thread/types.ts +68 -34
- package/src/mutation.ts +17 -7
- package/src/otel.ts +8 -0
- package/src/query-builder/api.ts +4 -4
- package/src/query-builder/impl.test.ts +22 -1
- package/src/query-builder/impl.ts +2 -2
- package/src/query-info.ts +3 -3
- package/src/rehydrate-from-mutationlog.ts +28 -34
- package/src/schema/EventId.test.ts +12 -0
- package/src/schema/EventId.ts +49 -15
- package/src/schema/MutationEvent.ts +78 -31
- package/src/schema/db-schema/ast/sqlite.ts +142 -0
- package/src/schema/db-schema/ast/validate.ts +13 -0
- package/src/schema/db-schema/dsl/__snapshots__/field-defs.test.ts.snap +206 -0
- package/src/schema/db-schema/dsl/field-defs.test.ts +35 -0
- package/src/schema/db-schema/dsl/field-defs.ts +242 -0
- package/src/schema/db-schema/dsl/mod.ts +195 -0
- package/src/schema/db-schema/hash.ts +14 -0
- package/src/schema/db-schema/mod.ts +2 -0
- package/src/schema/mod.ts +1 -0
- package/src/schema/mutations.ts +10 -20
- package/src/schema/schema-helpers.ts +1 -1
- package/src/schema/schema.ts +22 -10
- package/src/schema/system-tables.ts +24 -13
- package/src/schema/table-def.ts +17 -17
- package/src/schema-management/common.ts +3 -3
- package/src/schema-management/migrations.ts +19 -15
- package/src/schema-management/validate-mutation-defs.ts +2 -2
- package/src/sql-queries/sql-queries.ts +1 -1
- package/src/sql-queries/sql-query-builder.ts +1 -2
- package/src/sql-queries/types.ts +3 -1
- package/src/sync/ClientSessionSyncProcessor.ts +313 -0
- package/src/sync/index.ts +1 -1
- package/src/sync/next/facts.ts +1 -1
- package/src/sync/next/history-dag-common.ts +5 -1
- package/src/sync/next/history-dag.ts +1 -1
- package/src/sync/next/rebase-events.ts +13 -7
- package/src/sync/next/test/compact-events.calculator.test.ts +12 -12
- package/src/sync/next/test/compact-events.test.ts +43 -43
- package/src/sync/next/test/mutation-fixtures.ts +16 -19
- package/src/sync/sync.ts +26 -10
- package/src/sync/syncstate.test.ts +178 -98
- package/src/sync/syncstate.ts +170 -83
- package/src/sync/validate-push-payload.ts +7 -4
- package/src/version.ts +1 -1
- package/tmp/pack.tgz +0 -0
- package/tsconfig.json +1 -1
- package/dist/devtools/devtools-bridge.d.ts +0 -12
- package/dist/devtools/devtools-bridge.d.ts.map +0 -1
- package/dist/devtools/devtools-bridge.js +0 -2
- package/dist/devtools/devtools-bridge.js.map +0 -1
- package/dist/leader-thread/leader-sync-processor.d.ts +0 -47
- package/dist/leader-thread/leader-sync-processor.d.ts.map +0 -1
- package/dist/leader-thread/leader-sync-processor.js +0 -422
- package/dist/leader-thread/leader-sync-processor.js.map +0 -1
- package/dist/sync/client-session-sync-processor.d.ts.map +0 -1
- package/dist/sync/client-session-sync-processor.js +0 -131
- package/dist/sync/client-session-sync-processor.js.map +0 -1
- package/src/devtools/devtools-bridge.ts +0 -13
- package/src/devtools/index.ts +0 -48
- package/src/leader-thread/leader-sync-processor.ts +0 -666
- package/src/sync/client-session-sync-processor.ts +0 -207
package/dist/sync/syncstate.d.ts
CHANGED
@@ -1,6 +1,43 @@
|
|
1
1
|
import { Schema } from '@livestore/utils/effect';
|
2
|
-
import
|
2
|
+
import { UnexpectedError } from '../adapter-types.js';
|
3
3
|
import * as MutationEvent from '../schema/MutationEvent.js';
|
4
|
+
declare const SyncState_base: Schema.Class<SyncState, {
|
5
|
+
pending: Schema.Array$<typeof MutationEvent.EncodedWithMeta>;
|
6
|
+
rollbackTail: Schema.Array$<typeof MutationEvent.EncodedWithMeta>;
|
7
|
+
upstreamHead: Schema.Struct<{
|
8
|
+
global: Schema.BrandSchema<number & import("effect/Brand").Brand<"GlobalEventId">, number, never>;
|
9
|
+
client: Schema.BrandSchema<number & import("effect/Brand").Brand<"ClientEventId">, number, never>;
|
10
|
+
}>;
|
11
|
+
localHead: Schema.Struct<{
|
12
|
+
global: Schema.BrandSchema<number & import("effect/Brand").Brand<"GlobalEventId">, number, never>;
|
13
|
+
client: Schema.BrandSchema<number & import("effect/Brand").Brand<"ClientEventId">, number, never>;
|
14
|
+
}>;
|
15
|
+
}, Schema.Struct.Encoded<{
|
16
|
+
pending: Schema.Array$<typeof MutationEvent.EncodedWithMeta>;
|
17
|
+
rollbackTail: Schema.Array$<typeof MutationEvent.EncodedWithMeta>;
|
18
|
+
upstreamHead: Schema.Struct<{
|
19
|
+
global: Schema.BrandSchema<number & import("effect/Brand").Brand<"GlobalEventId">, number, never>;
|
20
|
+
client: Schema.BrandSchema<number & import("effect/Brand").Brand<"ClientEventId">, number, never>;
|
21
|
+
}>;
|
22
|
+
localHead: Schema.Struct<{
|
23
|
+
global: Schema.BrandSchema<number & import("effect/Brand").Brand<"GlobalEventId">, number, never>;
|
24
|
+
client: Schema.BrandSchema<number & import("effect/Brand").Brand<"ClientEventId">, number, never>;
|
25
|
+
}>;
|
26
|
+
}>, never, {
|
27
|
+
readonly pending: readonly MutationEvent.EncodedWithMeta[];
|
28
|
+
} & {
|
29
|
+
readonly upstreamHead: {
|
30
|
+
readonly global: number & import("effect/Brand").Brand<"GlobalEventId">;
|
31
|
+
readonly client: number & import("effect/Brand").Brand<"ClientEventId">;
|
32
|
+
};
|
33
|
+
} & {
|
34
|
+
readonly localHead: {
|
35
|
+
readonly global: number & import("effect/Brand").Brand<"GlobalEventId">;
|
36
|
+
readonly client: number & import("effect/Brand").Brand<"ClientEventId">;
|
37
|
+
};
|
38
|
+
} & {
|
39
|
+
readonly rollbackTail: readonly MutationEvent.EncodedWithMeta[];
|
40
|
+
}, {}, {}>;
|
4
41
|
/**
|
5
42
|
* SyncState represents the current sync state of a sync node relative to an upstream node.
|
6
43
|
* Events flow from local to upstream, with each state maintaining its own event head.
|
@@ -36,35 +73,20 @@ import * as MutationEvent from '../schema/MutationEvent.js';
|
|
36
73
|
* The `updateSyncState` function processes updates to the sync state based on incoming payloads,
|
37
74
|
* handling cases such as upstream rebase, advance, local push, and rollback tail trimming.
|
38
75
|
*/
|
39
|
-
export
|
40
|
-
|
41
|
-
rollbackTail: ReadonlyArray<MutationEvent.EncodedWithMeta>;
|
42
|
-
upstreamHead: EventId.EventId;
|
43
|
-
localHead: EventId.EventId;
|
76
|
+
export declare class SyncState extends SyncState_base {
|
77
|
+
toJSON: () => any;
|
44
78
|
}
|
45
|
-
export declare const SyncState: Schema.Struct<{
|
46
|
-
pending: Schema.Array$<typeof MutationEvent.EncodedWithMeta>;
|
47
|
-
rollbackTail: Schema.Array$<typeof MutationEvent.EncodedWithMeta>;
|
48
|
-
upstreamHead: Schema.Struct<{
|
49
|
-
global: typeof Schema.Number;
|
50
|
-
local: typeof Schema.Number;
|
51
|
-
}>;
|
52
|
-
localHead: Schema.Struct<{
|
53
|
-
global: typeof Schema.Number;
|
54
|
-
local: typeof Schema.Number;
|
55
|
-
}>;
|
56
|
-
}>;
|
57
79
|
declare const PayloadUpstreamRebase_base: Schema.TaggedStruct<"upstream-rebase", {
|
58
80
|
/** Rollback until this event in the rollback tail (inclusive). Starting from the end of the rollback tail. */
|
59
81
|
rollbackUntil: Schema.Struct<{
|
60
|
-
global:
|
61
|
-
|
82
|
+
global: Schema.BrandSchema<number & import("effect/Brand").Brand<"GlobalEventId">, number, never>;
|
83
|
+
client: Schema.BrandSchema<number & import("effect/Brand").Brand<"ClientEventId">, number, never>;
|
62
84
|
}>;
|
63
85
|
newEvents: Schema.Array$<typeof MutationEvent.EncodedWithMeta>;
|
64
86
|
/** Trim rollback tail up to this event (inclusive). */
|
65
87
|
trimRollbackUntil: Schema.optional<Schema.Struct<{
|
66
|
-
global:
|
67
|
-
|
88
|
+
global: Schema.BrandSchema<number & import("effect/Brand").Brand<"GlobalEventId">, number, never>;
|
89
|
+
client: Schema.BrandSchema<number & import("effect/Brand").Brand<"ClientEventId">, number, never>;
|
68
90
|
}>>;
|
69
91
|
}>;
|
70
92
|
export declare class PayloadUpstreamRebase extends PayloadUpstreamRebase_base {
|
@@ -73,8 +95,8 @@ declare const PayloadUpstreamAdvance_base: Schema.TaggedStruct<"upstream-advance
|
|
73
95
|
newEvents: Schema.Array$<typeof MutationEvent.EncodedWithMeta>;
|
74
96
|
/** Trim rollback tail up to this event (inclusive). */
|
75
97
|
trimRollbackUntil: Schema.optional<Schema.Struct<{
|
76
|
-
global:
|
77
|
-
|
98
|
+
global: Schema.BrandSchema<number & import("effect/Brand").Brand<"GlobalEventId">, number, never>;
|
99
|
+
client: Schema.BrandSchema<number & import("effect/Brand").Brand<"ClientEventId">, number, never>;
|
78
100
|
}>>;
|
79
101
|
}>;
|
80
102
|
export declare class PayloadUpstreamAdvance extends PayloadUpstreamAdvance_base {
|
@@ -89,28 +111,139 @@ export declare class Payload extends Payload_base {
|
|
89
111
|
}
|
90
112
|
export declare const PayloadUpstream: Schema.Union<[typeof PayloadUpstreamRebase, typeof PayloadUpstreamAdvance]>;
|
91
113
|
export type PayloadUpstream = typeof PayloadUpstream.Type;
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
114
|
+
declare const UpdateContext_base: Schema.Class<UpdateContext, {
|
115
|
+
payload: typeof Payload;
|
116
|
+
syncState: typeof SyncState;
|
117
|
+
}, Schema.Struct.Encoded<{
|
118
|
+
payload: typeof Payload;
|
119
|
+
syncState: typeof SyncState;
|
120
|
+
}>, never, {
|
121
|
+
readonly payload: {
|
122
|
+
readonly _tag: "upstream-rebase";
|
123
|
+
readonly rollbackUntil: {
|
124
|
+
readonly global: number & import("effect/Brand").Brand<"GlobalEventId">;
|
125
|
+
readonly client: number & import("effect/Brand").Brand<"ClientEventId">;
|
126
|
+
};
|
127
|
+
readonly newEvents: readonly MutationEvent.EncodedWithMeta[];
|
128
|
+
readonly trimRollbackUntil?: {
|
129
|
+
readonly global: number & import("effect/Brand").Brand<"GlobalEventId">;
|
130
|
+
readonly client: number & import("effect/Brand").Brand<"ClientEventId">;
|
131
|
+
} | undefined;
|
132
|
+
} | {
|
133
|
+
readonly _tag: "upstream-advance";
|
134
|
+
readonly newEvents: readonly MutationEvent.EncodedWithMeta[];
|
135
|
+
readonly trimRollbackUntil?: {
|
136
|
+
readonly global: number & import("effect/Brand").Brand<"GlobalEventId">;
|
137
|
+
readonly client: number & import("effect/Brand").Brand<"ClientEventId">;
|
138
|
+
} | undefined;
|
139
|
+
} | {
|
140
|
+
readonly _tag: "local-push";
|
141
|
+
readonly newEvents: readonly MutationEvent.EncodedWithMeta[];
|
142
|
+
};
|
143
|
+
} & {
|
144
|
+
readonly syncState: SyncState;
|
145
|
+
}, {}, {}>;
|
146
|
+
/** Only used for debugging purposes */
|
147
|
+
export declare class UpdateContext extends UpdateContext_base {
|
148
|
+
toJSON: () => any;
|
149
|
+
}
|
150
|
+
declare const UpdateResultAdvance_base: Schema.Class<UpdateResultAdvance, {
|
151
|
+
_tag: Schema.Literal<["advance"]>;
|
152
|
+
newSyncState: typeof SyncState;
|
153
|
+
/** Events which weren't pending before the update */
|
154
|
+
newEvents: Schema.Array$<typeof MutationEvent.EncodedWithMeta>;
|
155
|
+
updateContext: typeof UpdateContext;
|
156
|
+
}, Schema.Struct.Encoded<{
|
157
|
+
_tag: Schema.Literal<["advance"]>;
|
158
|
+
newSyncState: typeof SyncState;
|
96
159
|
/** Events which weren't pending before the update */
|
97
|
-
newEvents:
|
98
|
-
|
99
|
-
|
100
|
-
_tag:
|
101
|
-
|
102
|
-
|
160
|
+
newEvents: Schema.Array$<typeof MutationEvent.EncodedWithMeta>;
|
161
|
+
updateContext: typeof UpdateContext;
|
162
|
+
}>, never, {
|
163
|
+
readonly _tag: "advance";
|
164
|
+
} & {
|
165
|
+
readonly newEvents: readonly MutationEvent.EncodedWithMeta[];
|
166
|
+
} & {
|
167
|
+
readonly newSyncState: SyncState;
|
168
|
+
} & {
|
169
|
+
readonly updateContext: UpdateContext;
|
170
|
+
}, {}, {}>;
|
171
|
+
export declare class UpdateResultAdvance extends UpdateResultAdvance_base {
|
172
|
+
toJSON: () => any;
|
173
|
+
}
|
174
|
+
declare const UpdateResultRebase_base: Schema.Class<UpdateResultRebase, {
|
175
|
+
_tag: Schema.Literal<["rebase"]>;
|
176
|
+
newSyncState: typeof SyncState;
|
177
|
+
/** Events which weren't pending before the update */
|
178
|
+
newEvents: Schema.Array$<typeof MutationEvent.EncodedWithMeta>;
|
179
|
+
eventsToRollback: Schema.Array$<typeof MutationEvent.EncodedWithMeta>;
|
180
|
+
updateContext: typeof UpdateContext;
|
181
|
+
}, Schema.Struct.Encoded<{
|
182
|
+
_tag: Schema.Literal<["rebase"]>;
|
183
|
+
newSyncState: typeof SyncState;
|
103
184
|
/** Events which weren't pending before the update */
|
104
|
-
newEvents:
|
105
|
-
eventsToRollback:
|
106
|
-
|
107
|
-
|
108
|
-
_tag:
|
109
|
-
|
185
|
+
newEvents: Schema.Array$<typeof MutationEvent.EncodedWithMeta>;
|
186
|
+
eventsToRollback: Schema.Array$<typeof MutationEvent.EncodedWithMeta>;
|
187
|
+
updateContext: typeof UpdateContext;
|
188
|
+
}>, never, {
|
189
|
+
readonly _tag: "rebase";
|
190
|
+
} & {
|
191
|
+
readonly newEvents: readonly MutationEvent.EncodedWithMeta[];
|
192
|
+
} & {
|
193
|
+
readonly newSyncState: SyncState;
|
194
|
+
} & {
|
195
|
+
readonly updateContext: UpdateContext;
|
196
|
+
} & {
|
197
|
+
readonly eventsToRollback: readonly MutationEvent.EncodedWithMeta[];
|
198
|
+
}, {}, {}>;
|
199
|
+
export declare class UpdateResultRebase extends UpdateResultRebase_base {
|
200
|
+
toJSON: () => any;
|
201
|
+
}
|
202
|
+
declare const UpdateResultReject_base: Schema.Class<UpdateResultReject, {
|
203
|
+
_tag: Schema.Literal<["reject"]>;
|
204
|
+
/** The minimum id that the new events must have */
|
205
|
+
expectedMinimumId: Schema.Struct<{
|
206
|
+
global: Schema.BrandSchema<number & import("effect/Brand").Brand<"GlobalEventId">, number, never>;
|
207
|
+
client: Schema.BrandSchema<number & import("effect/Brand").Brand<"ClientEventId">, number, never>;
|
208
|
+
}>;
|
209
|
+
updateContext: typeof UpdateContext;
|
210
|
+
}, Schema.Struct.Encoded<{
|
211
|
+
_tag: Schema.Literal<["reject"]>;
|
110
212
|
/** The minimum id that the new events must have */
|
111
|
-
expectedMinimumId:
|
112
|
-
|
113
|
-
|
213
|
+
expectedMinimumId: Schema.Struct<{
|
214
|
+
global: Schema.BrandSchema<number & import("effect/Brand").Brand<"GlobalEventId">, number, never>;
|
215
|
+
client: Schema.BrandSchema<number & import("effect/Brand").Brand<"ClientEventId">, number, never>;
|
216
|
+
}>;
|
217
|
+
updateContext: typeof UpdateContext;
|
218
|
+
}>, never, {
|
219
|
+
readonly _tag: "reject";
|
220
|
+
} & {
|
221
|
+
readonly updateContext: UpdateContext;
|
222
|
+
} & {
|
223
|
+
readonly expectedMinimumId: {
|
224
|
+
readonly global: number & import("effect/Brand").Brand<"GlobalEventId">;
|
225
|
+
readonly client: number & import("effect/Brand").Brand<"ClientEventId">;
|
226
|
+
};
|
227
|
+
}, {}, {}>;
|
228
|
+
export declare class UpdateResultReject extends UpdateResultReject_base {
|
229
|
+
toJSON: () => any;
|
230
|
+
}
|
231
|
+
declare const UpdateResultUnexpectedError_base: Schema.Class<UpdateResultUnexpectedError, {
|
232
|
+
_tag: Schema.Literal<["unexpected-error"]>;
|
233
|
+
cause: typeof UnexpectedError;
|
234
|
+
}, Schema.Struct.Encoded<{
|
235
|
+
_tag: Schema.Literal<["unexpected-error"]>;
|
236
|
+
cause: typeof UnexpectedError;
|
237
|
+
}>, never, {
|
238
|
+
readonly _tag: "unexpected-error";
|
239
|
+
} & {
|
240
|
+
readonly cause: UnexpectedError;
|
241
|
+
}, {}, {}>;
|
242
|
+
export declare class UpdateResultUnexpectedError extends UpdateResultUnexpectedError_base {
|
243
|
+
}
|
244
|
+
declare const UpdateResult_base: Schema.Union<[typeof UpdateResultAdvance, typeof UpdateResultRebase, typeof UpdateResultReject, typeof UpdateResultUnexpectedError]>;
|
245
|
+
export declare class UpdateResult extends UpdateResult_base {
|
246
|
+
}
|
114
247
|
export declare const updateSyncState: ({ syncState, payload, isLocalEvent, isEqualEvent, ignoreLocalEvents, }: {
|
115
248
|
syncState: SyncState;
|
116
249
|
payload: typeof Payload.Type;
|
@@ -118,6 +251,6 @@ export declare const updateSyncState: ({ syncState, payload, isLocalEvent, isEqu
|
|
118
251
|
isEqualEvent: (a: MutationEvent.EncodedWithMeta, b: MutationEvent.EncodedWithMeta) => boolean;
|
119
252
|
/** This is used in the leader which should ignore local events when receiving an upstream-advance payload */
|
120
253
|
ignoreLocalEvents?: boolean;
|
121
|
-
}) => UpdateResult;
|
254
|
+
}) => typeof UpdateResult.Type;
|
122
255
|
export {};
|
123
256
|
//# sourceMappingURL=syncstate.d.ts.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"syncstate.d.ts","sourceRoot":"","sources":["../../src/sync/syncstate.ts"],"names":[],"mappings":"AACA,OAAO,
|
1
|
+
{"version":3,"file":"syncstate.d.ts","sourceRoot":"","sources":["../../src/sync/syncstate.ts"],"names":[],"mappings":"AACA,OAAO,EAAwB,MAAM,EAAE,MAAM,yBAAyB,CAAA;AAEtE,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAA;AAErD,OAAO,KAAK,aAAa,MAAM,4BAA4B,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAE3D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,qBAAa,SAAU,SAAQ,cAK7B;IACA,MAAM,QAAO,GAAG,CAOf;CACF;;IAGC,8GAA8G;;;;;;IAG9G,uDAAuD;;;;;;AAJzD,qBAAa,qBAAsB,SAAQ,0BAMzC;CAAG;;;IAIH,uDAAuD;;;;;;AAFzD,qBAAa,sBAAuB,SAAQ,2BAI1C;CAAG;;;;AAEL,qBAAa,gBAAiB,SAAQ,qBAEpC;CAAG;;AAEL,qBAAa,OAAQ,SAAQ,YAA6E;CAAG;AAE7G,eAAO,MAAM,eAAe,6EAA8D,CAAA;AAE1F,MAAM,MAAM,eAAe,GAAG,OAAO,eAAe,CAAC,IAAI,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEzD,uCAAuC;AACvC,qBAAa,aAAc,SAAQ,kBAGjC;IACA,MAAM,QAAO,GAAG,CAoBf;CACF;;;;IAKC,qDAAqD;;;;;;IAArD,qDAAqD;;;;;;;;;;;;AAHvD,qBAAa,mBAAoB,SAAQ,wBAMvC;IACA,MAAM,QAAO,GAAG,CAOf;CACF;;;;IAKC,qDAAqD;;;;;;;IAArD,qDAAqD;;;;;;;;;;;;;;;AAHvD,qBAAa,kBAAmB,SAAQ,uBAOtC;IACA,MAAM,QAAO,GAAG,CAQf;CACF;;;IAIC,mDAAmD;;;;;;;;IAAnD,mDAAmD;;;;;;;;;;;;;;;;AAFrD,qBAAa,kBAAmB,SAAQ,uBAKtC;IACA,MAAM,QAAO,GAAG,CAMf;CACF;;;;;;;;;;;;AAED,qBAAa,2BAA4B,SAAQ,gCAK/C;CAAG;;AAEL,qBAAa,YAAa,SAAQ,iBAKjC;CAAG;AAQJ,eAAO,MAAM,eAAe,GAAI,wEAM7B;IACD,SAAS,EAAE,SAAS,CAAA;IACpB,OAAO,EAAE,OAAO,OAAO,CAAC,IAAI,CAAA;IAC5B,YAAY,EAAE,CAAC,KAAK,EAAE,aAAa,CAAC,eAAe,KAAK,OAAO,CAAA;IAC/D,YAAY,EAAE,CAAC,CAAC,EAAE,aAAa,CAAC,eAAe,EAAE,CAAC,EAAE,aAAa,CAAC,eAAe,KAAK,OAAO,CAAA;IAC7F,6GAA6G;IAC7G,iBAAiB,CAAC,EAAE,OAAO,CAAA;CAC5B,KAAG,OAAO,YAAY,CAAC,IAiNvB,CAAA"}
|
package/dist/sync/syncstate.js
CHANGED
@@ -1,13 +1,58 @@
|
|
1
|
-
import {
|
2
|
-
import { ReadonlyArray, Schema } from '@livestore/utils/effect';
|
1
|
+
import { casesHandled } from '@livestore/utils';
|
2
|
+
import { Match, ReadonlyArray, Schema } from '@livestore/utils/effect';
|
3
|
+
import { UnexpectedError } from '../adapter-types.js';
|
3
4
|
import * as EventId from '../schema/EventId.js';
|
4
5
|
import * as MutationEvent from '../schema/MutationEvent.js';
|
5
|
-
|
6
|
+
/**
|
7
|
+
* SyncState represents the current sync state of a sync node relative to an upstream node.
|
8
|
+
* Events flow from local to upstream, with each state maintaining its own event head.
|
9
|
+
*
|
10
|
+
* Event Chain Structure:
|
11
|
+
* ```
|
12
|
+
* +-------------------------+------------------------+
|
13
|
+
* | ROLLBACK TAIL | PENDING EVENTS |
|
14
|
+
* +-------------------------+------------------------+
|
15
|
+
* ▼ ▼
|
16
|
+
* Upstream Head Local Head
|
17
|
+
* Example: (0,0), (0,1), (1,0) (1,1), (1,2), (2,0)
|
18
|
+
* ```
|
19
|
+
*
|
20
|
+
* State:
|
21
|
+
* - **Pending Events**: Events awaiting acknowledgment from the upstream.
|
22
|
+
* - Can be confirmed or rejected by the upstream.
|
23
|
+
* - Subject to rebase if rejected.
|
24
|
+
* - **Rollback Tail**: Events that are kept around temporarily for potential rollback until confirmed by upstream.
|
25
|
+
*
|
26
|
+
* Payloads:
|
27
|
+
* - `PayloadUpstreamRebase`: Upstream has performed a rebase, so downstream must roll back to the specified event
|
28
|
+
* and rebase the pending events on top of the new events.
|
29
|
+
* - `PayloadUpstreamAdvance`: Upstream has advanced, so downstream must rebase the pending events on top of the new events.
|
30
|
+
* - `PayloadUpstreamTrimRollbackTail`: Upstream has advanced, so downstream can trim the rollback tail.
|
31
|
+
* - `PayloadLocalPush`: Local push payload
|
32
|
+
*
|
33
|
+
* Invariants:
|
34
|
+
* 1. **Chain Continuity**: Each event must reference its immediate parent.
|
35
|
+
* 2. **Head Ordering**: Upstream Head ≤ Local Head.
|
36
|
+
* 3. **ID Sequence**: Must follow the pattern (1,0)→(1,1)→(1,2)→(2,0).
|
37
|
+
*
|
38
|
+
* The `updateSyncState` function processes updates to the sync state based on incoming payloads,
|
39
|
+
* handling cases such as upstream rebase, advance, local push, and rollback tail trimming.
|
40
|
+
*/
|
41
|
+
export class SyncState extends Schema.Class('SyncState')({
|
6
42
|
pending: Schema.Array(MutationEvent.EncodedWithMeta),
|
7
43
|
rollbackTail: Schema.Array(MutationEvent.EncodedWithMeta),
|
8
44
|
upstreamHead: EventId.EventId,
|
9
45
|
localHead: EventId.EventId,
|
10
|
-
})
|
46
|
+
}) {
|
47
|
+
toJSON = () => {
|
48
|
+
return {
|
49
|
+
pending: this.pending.map((e) => e.toJSON()),
|
50
|
+
rollbackTail: this.rollbackTail.map((e) => e.toJSON()),
|
51
|
+
upstreamHead: `(${this.upstreamHead.global},${this.upstreamHead.client})`,
|
52
|
+
localHead: `(${this.localHead.global},${this.localHead.client})`,
|
53
|
+
};
|
54
|
+
};
|
55
|
+
}
|
11
56
|
export class PayloadUpstreamRebase extends Schema.TaggedStruct('upstream-rebase', {
|
12
57
|
/** Rollback until this event in the rollback tail (inclusive). Starting from the end of the rollback tail. */
|
13
58
|
rollbackUntil: EventId.EventId,
|
@@ -29,6 +74,87 @@ export class PayloadLocalPush extends Schema.TaggedStruct('local-push', {
|
|
29
74
|
export class Payload extends Schema.Union(PayloadUpstreamRebase, PayloadUpstreamAdvance, PayloadLocalPush) {
|
30
75
|
}
|
31
76
|
export const PayloadUpstream = Schema.Union(PayloadUpstreamRebase, PayloadUpstreamAdvance);
|
77
|
+
/** Only used for debugging purposes */
|
78
|
+
export class UpdateContext extends Schema.Class('UpdateContext')({
|
79
|
+
payload: Payload,
|
80
|
+
syncState: SyncState,
|
81
|
+
}) {
|
82
|
+
toJSON = () => {
|
83
|
+
const payload = Match.value(this.payload).pipe(Match.tag('local-push', () => ({
|
84
|
+
_tag: 'local-push',
|
85
|
+
newEvents: this.payload.newEvents.map((e) => e.toJSON()),
|
86
|
+
})), Match.tag('upstream-advance', () => ({
|
87
|
+
_tag: 'upstream-advance',
|
88
|
+
newEvents: this.payload.newEvents.map((e) => e.toJSON()),
|
89
|
+
})), Match.tag('upstream-rebase', () => ({
|
90
|
+
_tag: 'upstream-rebase',
|
91
|
+
newEvents: this.payload.newEvents.map((e) => e.toJSON()),
|
92
|
+
})), Match.exhaustive);
|
93
|
+
return {
|
94
|
+
payload,
|
95
|
+
syncState: this.syncState.toJSON(),
|
96
|
+
};
|
97
|
+
};
|
98
|
+
}
|
99
|
+
export class UpdateResultAdvance extends Schema.Class('UpdateResultAdvance')({
|
100
|
+
_tag: Schema.Literal('advance'),
|
101
|
+
newSyncState: SyncState,
|
102
|
+
/** Events which weren't pending before the update */
|
103
|
+
newEvents: Schema.Array(MutationEvent.EncodedWithMeta),
|
104
|
+
updateContext: UpdateContext,
|
105
|
+
}) {
|
106
|
+
toJSON = () => {
|
107
|
+
return {
|
108
|
+
_tag: this._tag,
|
109
|
+
newSyncState: this.newSyncState.toJSON(),
|
110
|
+
newEvents: this.newEvents.map((e) => e.toJSON()),
|
111
|
+
updateContext: this.updateContext.toJSON(),
|
112
|
+
};
|
113
|
+
};
|
114
|
+
}
|
115
|
+
export class UpdateResultRebase extends Schema.Class('UpdateResultRebase')({
|
116
|
+
_tag: Schema.Literal('rebase'),
|
117
|
+
newSyncState: SyncState,
|
118
|
+
/** Events which weren't pending before the update */
|
119
|
+
newEvents: Schema.Array(MutationEvent.EncodedWithMeta),
|
120
|
+
eventsToRollback: Schema.Array(MutationEvent.EncodedWithMeta),
|
121
|
+
updateContext: UpdateContext,
|
122
|
+
}) {
|
123
|
+
toJSON = () => {
|
124
|
+
return {
|
125
|
+
_tag: this._tag,
|
126
|
+
newSyncState: this.newSyncState.toJSON(),
|
127
|
+
newEvents: this.newEvents.map((e) => e.toJSON()),
|
128
|
+
eventsToRollback: this.eventsToRollback.map((e) => e.toJSON()),
|
129
|
+
updateContext: this.updateContext.toJSON(),
|
130
|
+
};
|
131
|
+
};
|
132
|
+
}
|
133
|
+
export class UpdateResultReject extends Schema.Class('UpdateResultReject')({
|
134
|
+
_tag: Schema.Literal('reject'),
|
135
|
+
/** The minimum id that the new events must have */
|
136
|
+
expectedMinimumId: EventId.EventId,
|
137
|
+
updateContext: UpdateContext,
|
138
|
+
}) {
|
139
|
+
toJSON = () => {
|
140
|
+
return {
|
141
|
+
_tag: this._tag,
|
142
|
+
expectedMinimumId: `(${this.expectedMinimumId.global},${this.expectedMinimumId.client})`,
|
143
|
+
updateContext: this.updateContext.toJSON(),
|
144
|
+
};
|
145
|
+
};
|
146
|
+
}
|
147
|
+
export class UpdateResultUnexpectedError extends Schema.Class('UpdateResultUnexpectedError')({
|
148
|
+
_tag: Schema.Literal('unexpected-error'),
|
149
|
+
cause: UnexpectedError,
|
150
|
+
}) {
|
151
|
+
}
|
152
|
+
export class UpdateResult extends Schema.Union(UpdateResultAdvance, UpdateResultRebase, UpdateResultReject, UpdateResultUnexpectedError) {
|
153
|
+
}
|
154
|
+
const unexpectedError = (cause) => UpdateResultUnexpectedError.make({
|
155
|
+
_tag: 'unexpected-error',
|
156
|
+
cause: new UnexpectedError({ cause }),
|
157
|
+
});
|
32
158
|
export const updateSyncState = ({ syncState, payload, isLocalEvent, isEqualEvent, ignoreLocalEvents = false, }) => {
|
33
159
|
const trimRollbackTail = (rollbackTail) => {
|
34
160
|
const trimRollbackUntil = payload._tag === 'local-push' ? undefined : payload.trimRollbackUntil;
|
@@ -39,12 +165,13 @@ export const updateSyncState = ({ syncState, payload, isLocalEvent, isEqualEvent
|
|
39
165
|
return [];
|
40
166
|
return rollbackTail.slice(index + 1);
|
41
167
|
};
|
168
|
+
const updateContext = UpdateContext.make({ payload, syncState });
|
42
169
|
switch (payload._tag) {
|
43
170
|
case 'upstream-rebase': {
|
44
171
|
// Find the index of the rollback event in the rollback tail
|
45
172
|
const rollbackIndex = syncState.rollbackTail.findIndex((event) => EventId.isEqual(event.id, payload.rollbackUntil));
|
46
173
|
if (rollbackIndex === -1) {
|
47
|
-
return
|
174
|
+
return unexpectedError(`Rollback event not found in rollback tail. Rollback until: [${payload.rollbackUntil.global},${payload.rollbackUntil.client}]. Rollback tail: [${syncState.rollbackTail.map((e) => e.toString()).join(', ')}]`);
|
48
175
|
}
|
49
176
|
const eventsToRollback = [...syncState.rollbackTail.slice(rollbackIndex), ...syncState.pending];
|
50
177
|
// Get the last new event's ID as the new upstream head
|
@@ -55,39 +182,43 @@ export const updateSyncState = ({ syncState, payload, isLocalEvent, isEqualEvent
|
|
55
182
|
baseEventId: newUpstreamHead,
|
56
183
|
isLocalEvent,
|
57
184
|
});
|
58
|
-
return {
|
185
|
+
return UpdateResultRebase.make({
|
59
186
|
_tag: 'rebase',
|
60
|
-
newSyncState: {
|
187
|
+
newSyncState: new SyncState({
|
61
188
|
pending: rebasedPending,
|
62
189
|
rollbackTail: trimRollbackTail([...syncState.rollbackTail.slice(0, rollbackIndex), ...payload.newEvents]),
|
63
190
|
upstreamHead: newUpstreamHead,
|
64
191
|
localHead: rebasedPending.at(-1)?.id ?? newUpstreamHead,
|
65
|
-
},
|
66
|
-
|
67
|
-
newEvents: payload.newEvents,
|
192
|
+
}),
|
193
|
+
newEvents: [...payload.newEvents, ...rebasedPending],
|
68
194
|
eventsToRollback,
|
69
|
-
|
195
|
+
updateContext,
|
196
|
+
});
|
70
197
|
}
|
71
198
|
case 'upstream-advance': {
|
72
199
|
if (payload.newEvents.length === 0) {
|
73
|
-
return {
|
200
|
+
return UpdateResultAdvance.make({
|
74
201
|
_tag: 'advance',
|
75
|
-
newSyncState: {
|
202
|
+
newSyncState: new SyncState({
|
76
203
|
pending: syncState.pending,
|
77
204
|
rollbackTail: trimRollbackTail(syncState.rollbackTail),
|
78
205
|
upstreamHead: syncState.upstreamHead,
|
79
206
|
localHead: syncState.localHead,
|
80
|
-
},
|
81
|
-
previousSyncState: syncState,
|
207
|
+
}),
|
82
208
|
newEvents: [],
|
83
|
-
|
209
|
+
updateContext,
|
210
|
+
});
|
84
211
|
}
|
85
212
|
// Validate that newEvents are sorted in ascending order by eventId
|
86
213
|
for (let i = 1; i < payload.newEvents.length; i++) {
|
87
214
|
if (EventId.isGreaterThan(payload.newEvents[i - 1].id, payload.newEvents[i].id)) {
|
88
|
-
return
|
215
|
+
return unexpectedError(`Events must be sorted in ascending order by eventId. Received: [${payload.newEvents.map((e) => `(${e.id.global},${e.id.client})`).join(', ')}]`);
|
89
216
|
}
|
90
217
|
}
|
218
|
+
// Validate that incoming events are larger than upstream head
|
219
|
+
if (EventId.isGreaterThan(syncState.upstreamHead, payload.newEvents[0].id)) {
|
220
|
+
return unexpectedError(`Incoming events must be greater than upstream head. Expected greater than: [${syncState.upstreamHead.global},${syncState.upstreamHead.client}]. Received: [${payload.newEvents.map((e) => `(${e.id.global},${e.id.client})`).join(', ')}]`);
|
221
|
+
}
|
91
222
|
const newUpstreamHead = payload.newEvents.at(-1).id;
|
92
223
|
const divergentPendingIndex = findDivergencePoint({
|
93
224
|
existingEvents: syncState.pending,
|
@@ -97,8 +228,8 @@ export const updateSyncState = ({ syncState, payload, isLocalEvent, isEqualEvent
|
|
97
228
|
ignoreLocalEvents,
|
98
229
|
});
|
99
230
|
if (divergentPendingIndex === -1) {
|
100
|
-
const pendingEventIds = new Set(syncState.pending.map((e) => `${e.id.global},${e.id.
|
101
|
-
const newEvents = payload.newEvents.filter((e) => !pendingEventIds.has(`${e.id.global},${e.id.
|
231
|
+
const pendingEventIds = new Set(syncState.pending.map((e) => `${e.id.global},${e.id.client}`));
|
232
|
+
const newEvents = payload.newEvents.filter((e) => !pendingEventIds.has(`${e.id.global},${e.id.client}`));
|
102
233
|
// In the case where the incoming events are a subset of the pending events,
|
103
234
|
// we need to split the pending events into two groups:
|
104
235
|
// - pendingMatching: The pending events up to point where they match the incoming events
|
@@ -118,24 +249,24 @@ export const updateSyncState = ({ syncState, payload, isLocalEvent, isEqualEvent
|
|
118
249
|
});
|
119
250
|
const seenEventIds = new Set();
|
120
251
|
const pendingAndNewEvents = [...pendingMatching, ...payload.newEvents].filter((event) => {
|
121
|
-
const eventIdStr = `${event.id.global},${event.id.
|
252
|
+
const eventIdStr = `${event.id.global},${event.id.client}`;
|
122
253
|
if (seenEventIds.has(eventIdStr)) {
|
123
254
|
return false;
|
124
255
|
}
|
125
256
|
seenEventIds.add(eventIdStr);
|
126
257
|
return true;
|
127
258
|
});
|
128
|
-
return {
|
259
|
+
return UpdateResultAdvance.make({
|
129
260
|
_tag: 'advance',
|
130
|
-
newSyncState: {
|
261
|
+
newSyncState: new SyncState({
|
131
262
|
pending: pendingRemaining,
|
132
263
|
rollbackTail: trimRollbackTail([...syncState.rollbackTail, ...pendingAndNewEvents]),
|
133
264
|
upstreamHead: newUpstreamHead,
|
134
265
|
localHead: pendingRemaining.at(-1)?.id ?? newUpstreamHead,
|
135
|
-
},
|
136
|
-
previousSyncState: syncState,
|
266
|
+
}),
|
137
267
|
newEvents,
|
138
|
-
|
268
|
+
updateContext,
|
269
|
+
});
|
139
270
|
}
|
140
271
|
else {
|
141
272
|
const divergentPending = syncState.pending.slice(divergentPendingIndex);
|
@@ -151,63 +282,56 @@ export const updateSyncState = ({ syncState, payload, isLocalEvent, isEqualEvent
|
|
151
282
|
isLocalEvent,
|
152
283
|
ignoreLocalEvents,
|
153
284
|
});
|
154
|
-
return {
|
285
|
+
return UpdateResultRebase.make({
|
155
286
|
_tag: 'rebase',
|
156
|
-
newSyncState: {
|
287
|
+
newSyncState: new SyncState({
|
157
288
|
pending: rebasedPending,
|
158
289
|
rollbackTail: trimRollbackTail([...syncState.rollbackTail, ...payload.newEvents]),
|
159
290
|
upstreamHead: newUpstreamHead,
|
160
291
|
localHead: rebasedPending.at(-1).id,
|
161
|
-
},
|
162
|
-
previousSyncState: syncState,
|
292
|
+
}),
|
163
293
|
newEvents: [...payload.newEvents.slice(divergentNewEventsIndex), ...rebasedPending],
|
164
294
|
eventsToRollback: [...syncState.rollbackTail, ...divergentPending],
|
165
|
-
|
295
|
+
updateContext,
|
296
|
+
});
|
166
297
|
}
|
167
298
|
}
|
168
299
|
case 'local-push': {
|
169
300
|
if (payload.newEvents.length === 0) {
|
170
|
-
return {
|
301
|
+
return UpdateResultAdvance.make({
|
302
|
+
_tag: 'advance',
|
303
|
+
newSyncState: syncState,
|
304
|
+
newEvents: [],
|
305
|
+
updateContext,
|
306
|
+
});
|
171
307
|
}
|
172
308
|
const newEventsFirst = payload.newEvents.at(0);
|
173
309
|
const invalidEventId = EventId.isGreaterThan(newEventsFirst.id, syncState.localHead) === false;
|
174
310
|
if (invalidEventId) {
|
175
311
|
const expectedMinimumId = EventId.nextPair(syncState.localHead, true).id;
|
176
|
-
return {
|
312
|
+
return UpdateResultReject.make({
|
313
|
+
_tag: 'reject',
|
314
|
+
expectedMinimumId,
|
315
|
+
updateContext,
|
316
|
+
});
|
177
317
|
}
|
178
318
|
else {
|
179
|
-
return {
|
319
|
+
return UpdateResultAdvance.make({
|
180
320
|
_tag: 'advance',
|
181
|
-
newSyncState: {
|
321
|
+
newSyncState: new SyncState({
|
182
322
|
pending: [...syncState.pending, ...payload.newEvents],
|
183
323
|
rollbackTail: syncState.rollbackTail,
|
184
324
|
upstreamHead: syncState.upstreamHead,
|
185
325
|
localHead: payload.newEvents.at(-1).id,
|
186
|
-
},
|
187
|
-
previousSyncState: syncState,
|
326
|
+
}),
|
188
327
|
newEvents: payload.newEvents,
|
189
|
-
|
328
|
+
updateContext,
|
329
|
+
});
|
190
330
|
}
|
191
331
|
}
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
// if (startIndex === -1) {
|
196
|
-
// return shouldNeverHappen('New rollback start event not found in rollback tail')
|
197
|
-
// }
|
198
|
-
// // Keep only the events from the start index onwards
|
199
|
-
// const newRollbackTail = syncState.rollbackTail.slice(startIndex)
|
200
|
-
// return {
|
201
|
-
// _tag: 'advance',
|
202
|
-
// syncState: {
|
203
|
-
// pending: syncState.pending,
|
204
|
-
// rollbackTail: newRollbackTail,
|
205
|
-
// upstreamHead: syncState.upstreamHead,
|
206
|
-
// localHead: syncState.localHead,
|
207
|
-
// },
|
208
|
-
// newEvents: [],
|
209
|
-
// }
|
210
|
-
// }
|
332
|
+
default: {
|
333
|
+
casesHandled(payload);
|
334
|
+
}
|
211
335
|
}
|
212
336
|
};
|
213
337
|
/**
|
@@ -245,4 +369,12 @@ const rebaseEvents = ({ events, baseEventId, isLocalEvent, }) => {
|
|
245
369
|
return newEvent;
|
246
370
|
});
|
247
371
|
};
|
372
|
+
/**
|
373
|
+
* TODO: Implement this
|
374
|
+
*
|
375
|
+
* In certain scenarios e.g. when the client session has a queue of upstream update results,
|
376
|
+
* it could make sense to "flatten" update results into a single update result which the client session
|
377
|
+
* can process more efficiently which avoids push-threshing
|
378
|
+
*/
|
379
|
+
const _flattenUpdateResults = (_updateResults) => { };
|
248
380
|
//# sourceMappingURL=syncstate.js.map
|