@livestore/common 0.4.0-dev.2 → 0.4.0-dev.20
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 +17 -12
- package/dist/ClientSessionLeaderThreadProxy.d.ts.map +1 -1
- package/dist/ClientSessionLeaderThreadProxy.js.map +1 -1
- package/dist/adapter-types.d.ts +14 -6
- package/dist/adapter-types.d.ts.map +1 -1
- package/dist/adapter-types.js.map +1 -1
- package/dist/debug-info.d.ts.map +1 -1
- package/dist/debug-info.js +33 -6
- package/dist/debug-info.js.map +1 -1
- package/dist/devtools/devtools-messages-client-session.d.ts +28 -23
- package/dist/devtools/devtools-messages-client-session.d.ts.map +1 -1
- package/dist/devtools/devtools-messages-client-session.js +2 -2
- package/dist/devtools/devtools-messages-client-session.js.map +1 -1
- package/dist/devtools/devtools-messages-common.d.ts +7 -14
- package/dist/devtools/devtools-messages-common.d.ts.map +1 -1
- package/dist/devtools/devtools-messages-common.js +1 -6
- package/dist/devtools/devtools-messages-common.js.map +1 -1
- package/dist/devtools/devtools-messages-leader.d.ts +36 -29
- package/dist/devtools/devtools-messages-leader.d.ts.map +1 -1
- package/dist/devtools/devtools-messages-leader.js +8 -8
- package/dist/devtools/devtools-messages-leader.js.map +1 -1
- package/dist/devtools/devtools-sessioninfo.d.ts +14 -2
- package/dist/devtools/devtools-sessioninfo.d.ts.map +1 -1
- package/dist/devtools/devtools-sessioninfo.js +7 -4
- package/dist/devtools/devtools-sessioninfo.js.map +1 -1
- package/dist/devtools/mod.d.ts +13 -2
- package/dist/devtools/mod.d.ts.map +1 -1
- package/dist/devtools/mod.js +10 -3
- package/dist/devtools/mod.js.map +1 -1
- package/dist/errors.d.ts +52 -10
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +25 -6
- package/dist/errors.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/leader-thread/LeaderSyncProcessor.d.ts +8 -4
- package/dist/leader-thread/LeaderSyncProcessor.d.ts.map +1 -1
- package/dist/leader-thread/LeaderSyncProcessor.js +156 -73
- package/dist/leader-thread/LeaderSyncProcessor.js.map +1 -1
- package/dist/leader-thread/eventlog.d.ts +15 -21
- package/dist/leader-thread/eventlog.d.ts.map +1 -1
- package/dist/leader-thread/eventlog.js +18 -18
- package/dist/leader-thread/eventlog.js.map +1 -1
- package/dist/leader-thread/leader-worker-devtools.d.ts +2 -2
- package/dist/leader-thread/leader-worker-devtools.d.ts.map +1 -1
- package/dist/leader-thread/leader-worker-devtools.js +30 -42
- package/dist/leader-thread/leader-worker-devtools.js.map +1 -1
- package/dist/leader-thread/make-leader-thread-layer.d.ts +6 -6
- package/dist/leader-thread/make-leader-thread-layer.d.ts.map +1 -1
- package/dist/leader-thread/make-leader-thread-layer.js +79 -27
- package/dist/leader-thread/make-leader-thread-layer.js.map +1 -1
- package/dist/leader-thread/make-leader-thread-layer.test.d.ts +2 -0
- package/dist/leader-thread/make-leader-thread-layer.test.d.ts.map +1 -0
- package/dist/leader-thread/make-leader-thread-layer.test.js +32 -0
- package/dist/leader-thread/make-leader-thread-layer.test.js.map +1 -0
- package/dist/leader-thread/materialize-event.d.ts +3 -3
- package/dist/leader-thread/materialize-event.d.ts.map +1 -1
- package/dist/leader-thread/materialize-event.js +25 -11
- package/dist/leader-thread/materialize-event.js.map +1 -1
- package/dist/leader-thread/recreate-db.d.ts +2 -3
- package/dist/leader-thread/recreate-db.d.ts.map +1 -1
- package/dist/leader-thread/recreate-db.js +5 -5
- package/dist/leader-thread/recreate-db.js.map +1 -1
- package/dist/leader-thread/shutdown-channel.d.ts +2 -2
- package/dist/leader-thread/shutdown-channel.d.ts.map +1 -1
- package/dist/leader-thread/shutdown-channel.js +2 -2
- package/dist/leader-thread/shutdown-channel.js.map +1 -1
- package/dist/leader-thread/types.d.ts +21 -19
- package/dist/leader-thread/types.d.ts.map +1 -1
- package/dist/leader-thread/types.js.map +1 -1
- package/dist/logging.d.ts +40 -0
- package/dist/logging.d.ts.map +1 -0
- package/dist/logging.js +33 -0
- package/dist/logging.js.map +1 -0
- package/dist/make-client-session.d.ts +5 -3
- package/dist/make-client-session.d.ts.map +1 -1
- package/dist/make-client-session.js +5 -2
- package/dist/make-client-session.js.map +1 -1
- package/dist/materializer-helper.d.ts +6 -6
- package/dist/materializer-helper.d.ts.map +1 -1
- package/dist/materializer-helper.js +20 -4
- package/dist/materializer-helper.js.map +1 -1
- package/dist/rematerialize-from-eventlog.d.ts +2 -2
- package/dist/rematerialize-from-eventlog.d.ts.map +1 -1
- package/dist/rematerialize-from-eventlog.js +29 -20
- package/dist/rematerialize-from-eventlog.js.map +1 -1
- package/dist/schema/EventDef/define.d.ts +147 -0
- package/dist/schema/EventDef/define.d.ts.map +1 -0
- package/dist/schema/EventDef/define.js +139 -0
- package/dist/schema/EventDef/define.js.map +1 -0
- package/dist/schema/EventDef/event-def.d.ts +106 -0
- package/dist/schema/EventDef/event-def.d.ts.map +1 -0
- package/dist/schema/EventDef/event-def.js +2 -0
- package/dist/schema/EventDef/event-def.js.map +1 -0
- package/dist/schema/EventDef/facts.d.ts +118 -0
- package/dist/schema/EventDef/facts.d.ts.map +1 -0
- package/dist/schema/EventDef/facts.js +53 -0
- package/dist/schema/EventDef/facts.js.map +1 -0
- package/dist/schema/EventDef/materializer.d.ts +155 -0
- package/dist/schema/EventDef/materializer.d.ts.map +1 -0
- package/dist/schema/EventDef/materializer.js +83 -0
- package/dist/schema/EventDef/materializer.js.map +1 -0
- package/dist/schema/EventDef/mod.d.ts +5 -0
- package/dist/schema/EventDef/mod.d.ts.map +1 -0
- package/dist/schema/EventDef/mod.js +5 -0
- package/dist/schema/EventDef/mod.js.map +1 -0
- package/dist/schema/EventSequenceNumber/client.d.ts +136 -0
- package/dist/schema/EventSequenceNumber/client.d.ts.map +1 -0
- package/dist/schema/EventSequenceNumber/client.js +193 -0
- package/dist/schema/EventSequenceNumber/client.js.map +1 -0
- package/dist/schema/EventSequenceNumber/global.d.ts +15 -0
- package/dist/schema/EventSequenceNumber/global.d.ts.map +1 -0
- package/dist/schema/EventSequenceNumber/global.js +14 -0
- package/dist/schema/EventSequenceNumber/global.js.map +1 -0
- package/dist/schema/EventSequenceNumber/mod.d.ts +37 -0
- package/dist/schema/EventSequenceNumber/mod.d.ts.map +1 -0
- package/dist/schema/EventSequenceNumber/mod.js +37 -0
- package/dist/schema/EventSequenceNumber/mod.js.map +1 -0
- package/dist/schema/EventSequenceNumber.test.js +43 -43
- package/dist/schema/EventSequenceNumber.test.js.map +1 -1
- package/dist/schema/{LiveStoreEvent.d.ts → LiveStoreEvent/client.d.ts} +89 -106
- package/dist/schema/LiveStoreEvent/client.d.ts.map +1 -0
- package/dist/schema/{LiveStoreEvent.js → LiveStoreEvent/client.js} +74 -58
- package/dist/schema/LiveStoreEvent/client.js.map +1 -0
- package/dist/schema/LiveStoreEvent/for-event-def.d.ts +52 -0
- package/dist/schema/LiveStoreEvent/for-event-def.d.ts.map +1 -0
- package/dist/schema/LiveStoreEvent/for-event-def.js +2 -0
- package/dist/schema/LiveStoreEvent/for-event-def.js.map +1 -0
- package/dist/schema/LiveStoreEvent/global.d.ts +36 -0
- package/dist/schema/LiveStoreEvent/global.d.ts.map +1 -0
- package/dist/schema/LiveStoreEvent/global.js +31 -0
- package/dist/schema/LiveStoreEvent/global.js.map +1 -0
- package/dist/schema/LiveStoreEvent/input.d.ts +46 -0
- package/dist/schema/LiveStoreEvent/input.d.ts.map +1 -0
- package/dist/schema/LiveStoreEvent/input.js +26 -0
- package/dist/schema/LiveStoreEvent/input.js.map +1 -0
- package/dist/schema/LiveStoreEvent/mod.d.ts +5 -0
- package/dist/schema/LiveStoreEvent/mod.d.ts.map +1 -0
- package/dist/schema/LiveStoreEvent/mod.js +5 -0
- package/dist/schema/LiveStoreEvent/mod.js.map +1 -0
- 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 +6 -4
- package/dist/schema/mod.d.ts.map +1 -1
- package/dist/schema/mod.js +5 -4
- package/dist/schema/mod.js.map +1 -1
- package/dist/schema/schema.d.ts +16 -1
- package/dist/schema/schema.d.ts.map +1 -1
- package/dist/schema/schema.js +27 -2
- package/dist/schema/schema.js.map +1 -1
- package/dist/schema/state/sqlite/client-document-def.d.ts +36 -6
- package/dist/schema/state/sqlite/client-document-def.d.ts.map +1 -1
- package/dist/schema/state/sqlite/client-document-def.js +97 -6
- package/dist/schema/state/sqlite/client-document-def.js.map +1 -1
- package/dist/schema/state/sqlite/client-document-def.test.js +16 -0
- package/dist/schema/state/sqlite/client-document-def.test.js.map +1 -1
- package/dist/schema/state/sqlite/column-annotations.d.ts.map +1 -1
- package/dist/schema/state/sqlite/column-annotations.js +14 -6
- package/dist/schema/state/sqlite/column-annotations.js.map +1 -1
- package/dist/schema/state/sqlite/column-annotations.test.js +1 -1
- package/dist/schema/state/sqlite/column-annotations.test.js.map +1 -1
- package/dist/schema/state/sqlite/column-def.js +69 -22
- package/dist/schema/state/sqlite/column-def.js.map +1 -1
- package/dist/schema/state/sqlite/column-def.test.js +46 -7
- package/dist/schema/state/sqlite/column-def.test.js.map +1 -1
- package/dist/schema/state/sqlite/column-spec.d.ts.map +1 -1
- package/dist/schema/state/sqlite/column-spec.js +30 -12
- package/dist/schema/state/sqlite/column-spec.js.map +1 -1
- package/dist/schema/state/sqlite/column-spec.test.js +23 -14
- package/dist/schema/state/sqlite/column-spec.test.js.map +1 -1
- package/dist/schema/state/sqlite/db-schema/ast/sqlite.d.ts +2 -1
- package/dist/schema/state/sqlite/db-schema/ast/sqlite.d.ts.map +1 -1
- package/dist/schema/state/sqlite/db-schema/ast/sqlite.js +23 -6
- package/dist/schema/state/sqlite/db-schema/ast/sqlite.js.map +1 -1
- package/dist/schema/state/sqlite/db-schema/dsl/field-defs.d.ts +14 -8
- package/dist/schema/state/sqlite/db-schema/dsl/field-defs.d.ts.map +1 -1
- package/dist/schema/state/sqlite/db-schema/dsl/field-defs.js +5 -3
- package/dist/schema/state/sqlite/db-schema/dsl/field-defs.js.map +1 -1
- package/dist/schema/state/sqlite/db-schema/dsl/mod.d.ts.map +1 -1
- package/dist/schema/state/sqlite/db-schema/dsl/mod.js +2 -1
- package/dist/schema/state/sqlite/db-schema/dsl/mod.js.map +1 -1
- package/dist/schema/state/sqlite/mod.d.ts +3 -3
- package/dist/schema/state/sqlite/mod.d.ts.map +1 -1
- package/dist/schema/state/sqlite/mod.js +3 -3
- package/dist/schema/state/sqlite/mod.js.map +1 -1
- package/dist/schema/state/sqlite/query-builder/api.d.ts +17 -10
- package/dist/schema/state/sqlite/query-builder/api.d.ts.map +1 -1
- package/dist/schema/state/sqlite/query-builder/astToSql.d.ts.map +1 -1
- package/dist/schema/state/sqlite/query-builder/astToSql.js +22 -15
- package/dist/schema/state/sqlite/query-builder/astToSql.js.map +1 -1
- package/dist/schema/state/sqlite/query-builder/impl.d.ts.map +1 -1
- package/dist/schema/state/sqlite/query-builder/impl.js +6 -3
- package/dist/schema/state/sqlite/query-builder/impl.js.map +1 -1
- package/dist/schema/state/sqlite/query-builder/impl.test.js +252 -88
- package/dist/schema/state/sqlite/query-builder/impl.test.js.map +1 -1
- package/dist/schema/state/sqlite/schema-helpers.d.ts +2 -2
- package/dist/schema/state/sqlite/schema-helpers.d.ts.map +1 -1
- package/dist/schema/state/sqlite/schema-helpers.js +22 -12
- package/dist/schema/state/sqlite/schema-helpers.js.map +1 -1
- package/dist/schema/state/sqlite/schema-helpers.test.d.ts +2 -0
- package/dist/schema/state/sqlite/schema-helpers.test.d.ts.map +1 -0
- package/dist/schema/state/sqlite/schema-helpers.test.js +36 -0
- package/dist/schema/state/sqlite/schema-helpers.test.js.map +1 -0
- package/dist/schema/state/sqlite/{system-tables.d.ts → system-tables/eventlog-tables.d.ts} +63 -456
- package/dist/schema/state/sqlite/system-tables/eventlog-tables.d.ts.map +1 -0
- package/dist/schema/state/sqlite/system-tables/eventlog-tables.js +54 -0
- package/dist/schema/state/sqlite/system-tables/eventlog-tables.js.map +1 -0
- package/dist/schema/state/sqlite/system-tables/mod.d.ts +3 -0
- package/dist/schema/state/sqlite/system-tables/mod.d.ts.map +1 -0
- package/dist/schema/state/sqlite/system-tables/mod.js +3 -0
- package/dist/schema/state/sqlite/system-tables/mod.js.map +1 -0
- package/dist/schema/state/sqlite/system-tables/state-tables.d.ts +456 -0
- package/dist/schema/state/sqlite/system-tables/state-tables.d.ts.map +1 -0
- package/dist/schema/state/sqlite/system-tables/state-tables.js +55 -0
- package/dist/schema/state/sqlite/system-tables/state-tables.js.map +1 -0
- package/dist/schema/state/sqlite/table-def.d.ts +4 -4
- 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/state/sqlite/table-def.js.map +1 -1
- package/dist/schema/state/sqlite/table-def.test.js +80 -0
- package/dist/schema/state/sqlite/table-def.test.js.map +1 -1
- package/dist/schema/unknown-events.d.ts +47 -0
- package/dist/schema/unknown-events.d.ts.map +1 -0
- package/dist/schema/unknown-events.js +69 -0
- package/dist/schema/unknown-events.js.map +1 -0
- package/dist/schema-management/__tests__/migrations-autoincrement-quoting.test.d.ts +2 -0
- package/dist/schema-management/__tests__/migrations-autoincrement-quoting.test.d.ts.map +1 -0
- package/dist/schema-management/__tests__/migrations-autoincrement-quoting.test.js +73 -0
- package/dist/schema-management/__tests__/migrations-autoincrement-quoting.test.js.map +1 -0
- package/dist/schema-management/migrations.d.ts +32 -2
- package/dist/schema-management/migrations.d.ts.map +1 -1
- package/dist/schema-management/migrations.js +37 -5
- package/dist/schema-management/migrations.js.map +1 -1
- package/dist/schema-management/validate-schema.d.ts +3 -3
- package/dist/schema-management/validate-schema.d.ts.map +1 -1
- package/dist/schema-management/validate-schema.js +2 -2
- package/dist/schema-management/validate-schema.js.map +1 -1
- package/dist/sql-queries/sql-queries.d.ts.map +1 -1
- package/dist/sql-queries/sql-queries.js +11 -1
- package/dist/sql-queries/sql-queries.js.map +1 -1
- package/dist/sql-queries/sql-query-builder.d.ts.map +1 -1
- package/dist/sql-queries/sql-query-builder.js +2 -1
- package/dist/sql-queries/sql-query-builder.js.map +1 -1
- package/dist/sqlite-types.d.ts +3 -3
- package/dist/sqlite-types.d.ts.map +1 -1
- package/dist/sync/ClientSessionSyncProcessor.d.ts +11 -13
- package/dist/sync/ClientSessionSyncProcessor.d.ts.map +1 -1
- package/dist/sync/ClientSessionSyncProcessor.js +45 -42
- package/dist/sync/ClientSessionSyncProcessor.js.map +1 -1
- package/dist/sync/errors.d.ts +66 -0
- package/dist/sync/errors.d.ts.map +1 -0
- package/dist/sync/errors.js +36 -0
- package/dist/sync/errors.js.map +1 -0
- package/dist/sync/index.d.ts +3 -0
- package/dist/sync/index.d.ts.map +1 -1
- package/dist/sync/index.js +3 -0
- package/dist/sync/index.js.map +1 -1
- package/dist/sync/mock-sync-backend.d.ts +23 -0
- package/dist/sync/mock-sync-backend.d.ts.map +1 -0
- package/dist/sync/mock-sync-backend.js +114 -0
- package/dist/sync/mock-sync-backend.js.map +1 -0
- package/dist/sync/next/compact-events.d.ts.map +1 -1
- package/dist/sync/next/compact-events.js +6 -7
- package/dist/sync/next/compact-events.js.map +1 -1
- package/dist/sync/next/facts.d.ts +5 -5
- package/dist/sync/next/facts.d.ts.map +1 -1
- package/dist/sync/next/facts.js +1 -2
- package/dist/sync/next/facts.js.map +1 -1
- package/dist/sync/next/history-dag-common.d.ts +54 -15
- package/dist/sync/next/history-dag-common.d.ts.map +1 -1
- package/dist/sync/next/history-dag-common.js +198 -9
- 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 +10 -8
- package/dist/sync/next/history-dag.js.map +1 -1
- package/dist/sync/next/rebase-events.d.ts +5 -5
- package/dist/sync/next/rebase-events.d.ts.map +1 -1
- package/dist/sync/next/rebase-events.js +5 -5
- package/dist/sync/next/rebase-events.js.map +1 -1
- package/dist/sync/next/test/event-fixtures.d.ts +2 -2
- package/dist/sync/next/test/event-fixtures.d.ts.map +1 -1
- package/dist/sync/next/test/event-fixtures.js +9 -9
- package/dist/sync/next/test/event-fixtures.js.map +1 -1
- package/dist/sync/sync-backend-kv.d.ts +7 -0
- package/dist/sync/sync-backend-kv.d.ts.map +1 -0
- package/dist/sync/sync-backend-kv.js +18 -0
- package/dist/sync/sync-backend-kv.js.map +1 -0
- package/dist/sync/sync-backend.d.ts +105 -0
- package/dist/sync/sync-backend.d.ts.map +1 -0
- package/dist/sync/sync-backend.js +61 -0
- package/dist/sync/sync-backend.js.map +1 -0
- package/dist/sync/sync.d.ts +9 -86
- package/dist/sync/sync.d.ts.map +1 -1
- package/dist/sync/sync.js +2 -27
- package/dist/sync/sync.js.map +1 -1
- package/dist/sync/syncstate.d.ts +57 -44
- package/dist/sync/syncstate.d.ts.map +1 -1
- package/dist/sync/syncstate.js +50 -45
- package/dist/sync/syncstate.js.map +1 -1
- package/dist/sync/syncstate.test.js +83 -46
- package/dist/sync/syncstate.test.js.map +1 -1
- package/dist/sync/transport-chunking.d.ts +36 -0
- package/dist/sync/transport-chunking.d.ts.map +1 -0
- package/dist/sync/transport-chunking.js +56 -0
- package/dist/sync/transport-chunking.js.map +1 -0
- 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 +6 -6
- package/dist/sync/validate-push-payload.js.map +1 -1
- package/dist/testing/event-factory.d.ts +68 -0
- package/dist/testing/event-factory.d.ts.map +1 -0
- package/dist/testing/event-factory.js +78 -0
- package/dist/testing/event-factory.js.map +1 -0
- package/dist/testing/mod.d.ts +2 -0
- package/dist/testing/mod.d.ts.map +1 -0
- package/dist/testing/mod.js +2 -0
- package/dist/testing/mod.js.map +1 -0
- package/dist/version.d.ts +16 -6
- package/dist/version.d.ts.map +1 -1
- package/dist/version.js +16 -6
- package/dist/version.js.map +1 -1
- package/package.json +7 -8
- package/src/ClientSessionLeaderThreadProxy.ts +17 -12
- package/src/adapter-types.ts +18 -6
- package/src/debug-info.ts +37 -6
- package/src/devtools/devtools-messages-client-session.ts +2 -2
- package/src/devtools/devtools-messages-common.ts +1 -8
- package/src/devtools/devtools-messages-leader.ts +8 -8
- package/src/devtools/devtools-sessioninfo.ts +8 -5
- package/src/devtools/mod.ts +11 -2
- package/src/errors.ts +38 -11
- package/src/index.ts +2 -1
- package/src/leader-thread/LeaderSyncProcessor.ts +242 -103
- package/src/leader-thread/eventlog.ts +33 -34
- package/src/leader-thread/leader-worker-devtools.ts +50 -54
- package/src/leader-thread/make-leader-thread-layer.test.ts +44 -0
- package/src/leader-thread/make-leader-thread-layer.ts +156 -37
- package/src/leader-thread/materialize-event.ts +37 -12
- package/src/leader-thread/recreate-db.ts +15 -7
- package/src/leader-thread/shutdown-channel.ts +16 -2
- package/src/leader-thread/types.ts +21 -19
- package/src/logging.ts +62 -0
- package/src/make-client-session.ts +9 -3
- package/src/materializer-helper.ts +27 -10
- package/src/rematerialize-from-eventlog.ts +37 -27
- package/src/schema/EventDef/define.ts +201 -0
- package/src/schema/EventDef/event-def.ts +120 -0
- package/src/schema/EventDef/facts.ts +135 -0
- package/src/schema/EventDef/materializer.ts +172 -0
- package/src/schema/EventDef/mod.ts +4 -0
- package/src/schema/EventSequenceNumber/client.ts +257 -0
- package/src/schema/EventSequenceNumber/global.ts +19 -0
- package/src/schema/EventSequenceNumber/mod.ts +37 -0
- package/src/schema/EventSequenceNumber.test.ts +70 -52
- package/src/schema/LiveStoreEvent/client.ts +221 -0
- package/src/schema/LiveStoreEvent/for-event-def.ts +60 -0
- package/src/schema/LiveStoreEvent/global.ts +45 -0
- package/src/schema/LiveStoreEvent/input.ts +63 -0
- package/src/schema/LiveStoreEvent/mod.ts +4 -0
- package/src/schema/events.ts +1 -1
- package/src/schema/mod.ts +6 -4
- package/src/schema/schema.ts +39 -3
- package/src/schema/state/sqlite/client-document-def.test.ts +19 -2
- package/src/schema/state/sqlite/client-document-def.ts +120 -8
- package/src/schema/state/sqlite/column-annotations.test.ts +1 -1
- package/src/schema/state/sqlite/column-annotations.ts +16 -6
- package/src/schema/state/sqlite/column-def.test.ts +60 -7
- package/src/schema/state/sqlite/column-def.ts +88 -21
- package/src/schema/state/sqlite/column-spec.test.ts +29 -16
- package/src/schema/state/sqlite/column-spec.ts +36 -11
- package/src/schema/state/sqlite/db-schema/ast/sqlite.ts +26 -6
- package/src/schema/state/sqlite/db-schema/dsl/field-defs.ts +29 -12
- package/src/schema/state/sqlite/db-schema/dsl/mod.ts +2 -1
- package/src/schema/state/sqlite/mod.ts +4 -3
- package/src/schema/state/sqlite/query-builder/api.ts +19 -10
- package/src/schema/state/sqlite/query-builder/astToSql.ts +23 -14
- package/src/schema/state/sqlite/query-builder/impl.test.ts +305 -92
- package/src/schema/state/sqlite/query-builder/impl.ts +8 -3
- package/src/schema/state/sqlite/schema-helpers.test.ts +44 -0
- package/src/schema/state/sqlite/schema-helpers.ts +28 -20
- package/src/schema/state/sqlite/system-tables/eventlog-tables.ts +64 -0
- package/src/schema/state/sqlite/system-tables/mod.ts +2 -0
- package/src/schema/state/sqlite/system-tables/state-tables.ts +69 -0
- package/src/schema/state/sqlite/table-def.test.ts +101 -0
- package/src/schema/state/sqlite/table-def.ts +9 -8
- package/src/schema/unknown-events.ts +131 -0
- package/src/schema-management/__tests__/migrations-autoincrement-quoting.test.ts +86 -0
- package/src/schema-management/migrations.ts +41 -8
- package/src/schema-management/validate-schema.ts +3 -3
- package/src/sql-queries/sql-queries.ts +9 -1
- package/src/sql-queries/sql-query-builder.ts +2 -1
- package/src/sqlite-types.ts +3 -3
- package/src/sync/ClientSessionSyncProcessor.ts +69 -62
- package/src/sync/errors.ts +38 -0
- package/src/sync/index.ts +3 -0
- package/src/sync/mock-sync-backend.ts +184 -0
- package/src/sync/next/compact-events.ts +6 -7
- package/src/sync/next/facts.ts +7 -9
- package/src/sync/next/history-dag-common.ts +277 -26
- package/src/sync/next/history-dag.ts +16 -10
- package/src/sync/next/rebase-events.ts +11 -11
- package/src/sync/next/test/event-fixtures.ts +11 -11
- package/src/sync/sync-backend-kv.ts +22 -0
- package/src/sync/sync-backend.ts +185 -0
- package/src/sync/sync.ts +9 -91
- package/src/sync/syncstate.test.ts +96 -52
- package/src/sync/syncstate.ts +69 -58
- package/src/sync/transport-chunking.ts +90 -0
- package/src/sync/validate-push-payload.ts +8 -9
- package/src/testing/event-factory.ts +131 -0
- package/src/testing/mod.ts +1 -0
- package/src/version.ts +16 -6
- package/dist/schema/EventDef.d.ts +0 -123
- package/dist/schema/EventDef.d.ts.map +0 -1
- package/dist/schema/EventDef.js +0 -46
- package/dist/schema/EventDef.js.map +0 -1
- package/dist/schema/EventSequenceNumber.d.ts +0 -80
- package/dist/schema/EventSequenceNumber.d.ts.map +0 -1
- package/dist/schema/EventSequenceNumber.js +0 -139
- package/dist/schema/EventSequenceNumber.js.map +0 -1
- package/dist/schema/LiveStoreEvent.d.ts.map +0 -1
- package/dist/schema/LiveStoreEvent.js.map +0 -1
- package/dist/schema/state/sqlite/system-tables.d.ts.map +0 -1
- package/dist/schema/state/sqlite/system-tables.js +0 -79
- package/dist/schema/state/sqlite/system-tables.js.map +0 -1
- package/dist/schema-management/migrations.test.d.ts +0 -2
- package/dist/schema-management/migrations.test.d.ts.map +0 -1
- package/dist/schema-management/migrations.test.js +0 -52
- package/dist/schema-management/migrations.test.js.map +0 -1
- package/dist/sync/next/graphology.d.ts +0 -8
- package/dist/sync/next/graphology.d.ts.map +0 -1
- package/dist/sync/next/graphology.js +0 -30
- package/dist/sync/next/graphology.js.map +0 -1
- package/dist/sync/next/graphology_.d.ts +0 -3
- package/dist/sync/next/graphology_.d.ts.map +0 -1
- package/dist/sync/next/graphology_.js +0 -3
- package/dist/sync/next/graphology_.js.map +0 -1
- package/src/schema/EventDef.ts +0 -219
- package/src/schema/EventSequenceNumber.ts +0 -199
- package/src/schema/LiveStoreEvent.ts +0 -287
- package/src/schema/state/sqlite/system-tables.ts +0 -104
- package/src/sync/next/ambient.d.ts +0 -3
- package/src/sync/next/graphology.ts +0 -41
- package/src/sync/next/graphology_.ts +0 -2
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import {
|
|
2
|
+
type Cause,
|
|
3
|
+
type Effect,
|
|
4
|
+
type HttpClient,
|
|
5
|
+
type KeyValueStore,
|
|
6
|
+
Option,
|
|
7
|
+
Schema,
|
|
8
|
+
type Scope,
|
|
9
|
+
type Stream,
|
|
10
|
+
type SubscriptionRef,
|
|
11
|
+
} from '@livestore/utils/effect'
|
|
12
|
+
import type { UnknownError } from '../adapter-types.ts'
|
|
13
|
+
import type * as LiveStoreEvent from '../schema/LiveStoreEvent/mod.ts'
|
|
14
|
+
import type { EventSequenceNumber } from '../schema/mod.ts'
|
|
15
|
+
import type { InvalidPullError, InvalidPushError, IsOfflineError } from './errors.ts'
|
|
16
|
+
|
|
17
|
+
export * from './sync-backend-kv.ts'
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Those arguments can be used to implement multi-tenancy etc and are passed in from the store.
|
|
21
|
+
*/
|
|
22
|
+
export type MakeBackendArgs<TPayload = Schema.JsonValue> = {
|
|
23
|
+
storeId: string
|
|
24
|
+
clientId: string
|
|
25
|
+
payload: TPayload | undefined
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// TODO rename to `SyncProviderClientConstructor`
|
|
29
|
+
export type SyncBackendConstructor<TSyncMetadata = Schema.JsonValue, TPayload = Schema.JsonValue> = (
|
|
30
|
+
args: MakeBackendArgs<TPayload>,
|
|
31
|
+
) => Effect.Effect<
|
|
32
|
+
SyncBackend<TSyncMetadata>,
|
|
33
|
+
UnknownError,
|
|
34
|
+
Scope.Scope | HttpClient.HttpClient | KeyValueStore.KeyValueStore
|
|
35
|
+
>
|
|
36
|
+
|
|
37
|
+
// TODO add more runtime sync metadata/metrics
|
|
38
|
+
// - latency histogram
|
|
39
|
+
// - number of events pushed/pulled
|
|
40
|
+
// - dynamic sync backend data;
|
|
41
|
+
// - data center location (e.g. colo on CF workers)
|
|
42
|
+
|
|
43
|
+
// TODO rename to `SyncProviderClient`
|
|
44
|
+
export type SyncBackend<TSyncMetadata = Schema.JsonValue> = {
|
|
45
|
+
/**
|
|
46
|
+
* Can be implemented to prepare a connection to the sync backend to speed up the first pull/push.
|
|
47
|
+
*/
|
|
48
|
+
connect: Effect.Effect<void, IsOfflineError | UnknownError, Scope.Scope>
|
|
49
|
+
pull: (
|
|
50
|
+
cursor: Option.Option<{
|
|
51
|
+
eventSequenceNumber: EventSequenceNumber.Global.Type
|
|
52
|
+
/** Metadata is needed by some sync backends */
|
|
53
|
+
metadata: Option.Option<TSyncMetadata>
|
|
54
|
+
}>,
|
|
55
|
+
options?: {
|
|
56
|
+
/**
|
|
57
|
+
* If true, the sync backend will return a stream of events that have been pushed after the cursor.
|
|
58
|
+
*
|
|
59
|
+
* @default false
|
|
60
|
+
*/
|
|
61
|
+
live?: boolean
|
|
62
|
+
},
|
|
63
|
+
) => Stream.Stream<PullResItem<TSyncMetadata>, IsOfflineError | InvalidPullError>
|
|
64
|
+
// TODO support transactions (i.e. group of mutation events which need to be applied together)
|
|
65
|
+
push: (
|
|
66
|
+
/**
|
|
67
|
+
* Constraints for batch:
|
|
68
|
+
* - Number of events: 1-100
|
|
69
|
+
* - sequence numbers must be in ascending order
|
|
70
|
+
* */
|
|
71
|
+
batch: ReadonlyArray<LiveStoreEvent.Global.Encoded>,
|
|
72
|
+
) => Effect.Effect<void, IsOfflineError | InvalidPushError>
|
|
73
|
+
ping: Effect.Effect<void, IsOfflineError | UnknownError | Cause.TimeoutException>
|
|
74
|
+
// TODO also expose latency information additionally to whether the backend is connected
|
|
75
|
+
isConnected: SubscriptionRef.SubscriptionRef<boolean>
|
|
76
|
+
/**
|
|
77
|
+
* Metadata describing the sync backend. (Currently only used by devtools.)
|
|
78
|
+
*/
|
|
79
|
+
metadata: { name: string; description: string } & Record<string, Schema.JsonValue>
|
|
80
|
+
/** Information about the sync backend capabilities. */
|
|
81
|
+
supports: {
|
|
82
|
+
/**
|
|
83
|
+
* Whether the sync backend supports the `hasMore` field in the pull response.
|
|
84
|
+
*/
|
|
85
|
+
pullPageInfoKnown: boolean
|
|
86
|
+
/**
|
|
87
|
+
* Whether the sync backend supports the `live` option for the pull method and thus
|
|
88
|
+
* long-lived, reactive pull streams.
|
|
89
|
+
*/
|
|
90
|
+
pullLive: boolean
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Connectivity metadata emitted by sync backends.
|
|
96
|
+
*/
|
|
97
|
+
export const NetworkStatus = Schema.Struct({
|
|
98
|
+
/** True when the upstream sync backend is reachable and responding to health checks. */
|
|
99
|
+
isConnected: Schema.Boolean,
|
|
100
|
+
/** Unix epoch timestamp (ms) of the latest connectivity state transition. */
|
|
101
|
+
timestampMs: Schema.Number,
|
|
102
|
+
/** Devtools specific metadata describing simulator overrides. */
|
|
103
|
+
devtools: Schema.Struct({
|
|
104
|
+
/** Indicates whether the devtools latch forced the client into an offline state. */
|
|
105
|
+
latchClosed: Schema.Boolean,
|
|
106
|
+
}),
|
|
107
|
+
}).annotations({ title: 'NetworkStatus' })
|
|
108
|
+
|
|
109
|
+
export type NetworkStatus = typeof NetworkStatus.Type
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Runtime type guard for SyncBackend objects.
|
|
113
|
+
* Performs lightweight structural checks on the object shape.
|
|
114
|
+
*/
|
|
115
|
+
export const isSyncBackend = (value: unknown): value is SyncBackend<any> => {
|
|
116
|
+
if (typeof value !== 'object' || value === null) return false
|
|
117
|
+
|
|
118
|
+
const v: any = value
|
|
119
|
+
const hasCoreFns =
|
|
120
|
+
typeof v.connect === 'function' &&
|
|
121
|
+
typeof v.pull === 'function' &&
|
|
122
|
+
typeof v.push === 'function' &&
|
|
123
|
+
typeof v.ping === 'function'
|
|
124
|
+
|
|
125
|
+
const hasSupports =
|
|
126
|
+
typeof v.supports === 'object' &&
|
|
127
|
+
v.supports !== null &&
|
|
128
|
+
typeof v.supports.pullPageInfoKnown === 'boolean' &&
|
|
129
|
+
typeof v.supports.pullLive === 'boolean'
|
|
130
|
+
|
|
131
|
+
const hasMetadata =
|
|
132
|
+
typeof v.metadata === 'object' &&
|
|
133
|
+
v.metadata !== null &&
|
|
134
|
+
typeof v.metadata.name === 'string' &&
|
|
135
|
+
typeof v.metadata.description === 'string'
|
|
136
|
+
|
|
137
|
+
const hasIsConnected = typeof v.isConnected === 'object' && v.isConnected !== null
|
|
138
|
+
|
|
139
|
+
return hasCoreFns && hasSupports && hasMetadata && hasIsConnected
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
export const PullResPageInfo = Schema.Union(
|
|
143
|
+
Schema.TaggedStruct('MoreUnknown', {}),
|
|
144
|
+
Schema.TaggedStruct('MoreKnown', {
|
|
145
|
+
remaining: Schema.Number,
|
|
146
|
+
}),
|
|
147
|
+
Schema.TaggedStruct('NoMore', {}),
|
|
148
|
+
)
|
|
149
|
+
|
|
150
|
+
export type PullResPageInfo = typeof PullResPageInfo.Type
|
|
151
|
+
|
|
152
|
+
export const pageInfoNoMore: PullResPageInfo = { _tag: 'NoMore' } as const
|
|
153
|
+
export const pageInfoMoreUnknown: PullResPageInfo = { _tag: 'MoreUnknown' } as const
|
|
154
|
+
export const pageInfoMoreKnown = (remaining: number): PullResPageInfo => ({ _tag: 'MoreKnown', remaining })
|
|
155
|
+
|
|
156
|
+
export const pullResItemEmpty = <TSyncMetadata = Schema.JsonValue>(): PullResItem<TSyncMetadata> => ({
|
|
157
|
+
batch: [],
|
|
158
|
+
pageInfo: pageInfoNoMore,
|
|
159
|
+
})
|
|
160
|
+
|
|
161
|
+
export interface PullResItem<TSyncMetadata = Schema.JsonValue> {
|
|
162
|
+
batch: ReadonlyArray<{
|
|
163
|
+
eventEncoded: LiveStoreEvent.Global.Encoded
|
|
164
|
+
metadata: Option.Option<TSyncMetadata>
|
|
165
|
+
}>
|
|
166
|
+
pageInfo: PullResPageInfo
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
export const of = <TSyncMetadata = Schema.JsonValue>(obj: SyncBackend<TSyncMetadata>) => obj
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Useful to continue pulling from the last event in the batch.
|
|
173
|
+
*/
|
|
174
|
+
export const cursorFromPullResItem = <TSyncMetadata = Schema.JsonValue>(
|
|
175
|
+
item: PullResItem<TSyncMetadata>,
|
|
176
|
+
): Option.Option<{
|
|
177
|
+
eventSequenceNumber: EventSequenceNumber.Global.Type
|
|
178
|
+
metadata: Option.Option<TSyncMetadata>
|
|
179
|
+
}> => {
|
|
180
|
+
const lastEvent = item.batch.at(-1)
|
|
181
|
+
if (!lastEvent) {
|
|
182
|
+
return Option.none()
|
|
183
|
+
}
|
|
184
|
+
return Option.some({ eventSequenceNumber: lastEvent.eventEncoded.seqNum, metadata: lastEvent.metadata })
|
|
185
|
+
}
|
package/src/sync/sync.ts
CHANGED
|
@@ -1,22 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
export * from './errors.ts'
|
|
2
|
+
export * as SyncBackend from './sync-backend.ts'
|
|
3
3
|
|
|
4
|
-
import type {
|
|
4
|
+
import type { Schema } from '@livestore/utils/effect'
|
|
5
5
|
import type { InitialSyncOptions } from '../leader-thread/types.ts'
|
|
6
|
-
import
|
|
7
|
-
import type * as LiveStoreEvent from '../schema/LiveStoreEvent.ts'
|
|
6
|
+
import type { SyncBackendConstructor } from './sync-backend.ts'
|
|
8
7
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
*/
|
|
12
|
-
export type MakeBackendArgs = {
|
|
13
|
-
storeId: string
|
|
14
|
-
clientId: string
|
|
15
|
-
payload: Schema.JsonValue | undefined
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export type SyncOptions = {
|
|
19
|
-
backend?: SyncBackendConstructor<any>
|
|
8
|
+
export type SyncOptions<TPayload = Schema.JsonValue> = {
|
|
9
|
+
backend?: SyncBackendConstructor<any, TPayload>
|
|
20
10
|
/** @default { _tag: 'Skip' } */
|
|
21
11
|
initialSyncOptions?: InitialSyncOptions
|
|
22
12
|
/**
|
|
@@ -29,81 +19,9 @@ export type SyncOptions = {
|
|
|
29
19
|
* @default 'ignore'
|
|
30
20
|
* */
|
|
31
21
|
onSyncError?: 'shutdown' | 'ignore'
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
// TODO rename to `SyncProviderClientConstructor`
|
|
35
|
-
export type SyncBackendConstructor<TSyncMetadata = Schema.JsonValue> = (
|
|
36
|
-
args: MakeBackendArgs,
|
|
37
|
-
) => Effect.Effect<SyncBackend<TSyncMetadata>, UnexpectedError, Scope.Scope | HttpClient.HttpClient>
|
|
38
|
-
|
|
39
|
-
// TODO add more runtime sync metadata
|
|
40
|
-
// - latency histogram
|
|
41
|
-
// - number of events pushed/pulled
|
|
42
|
-
// - dynamic sync backend data;
|
|
43
|
-
// - data center location (e.g. colo on CF workers)
|
|
44
|
-
|
|
45
|
-
// TODO rename to `SyncProviderClient`
|
|
46
|
-
export type SyncBackend<TSyncMetadata = Schema.JsonValue> = {
|
|
47
22
|
/**
|
|
48
|
-
*
|
|
23
|
+
* Whether the sync backend should reactively pull new events from the sync backend
|
|
24
|
+
* @default true
|
|
49
25
|
*/
|
|
50
|
-
|
|
51
|
-
pull: (
|
|
52
|
-
args: Option.Option<{
|
|
53
|
-
cursor: EventSequenceNumber.EventSequenceNumber
|
|
54
|
-
metadata: Option.Option<TSyncMetadata>
|
|
55
|
-
}>,
|
|
56
|
-
) => Stream.Stream<
|
|
57
|
-
{
|
|
58
|
-
batch: ReadonlyArray<{
|
|
59
|
-
eventEncoded: LiveStoreEvent.AnyEncodedGlobal
|
|
60
|
-
metadata: Option.Option<TSyncMetadata>
|
|
61
|
-
}>
|
|
62
|
-
remaining: number
|
|
63
|
-
},
|
|
64
|
-
IsOfflineError | InvalidPullError,
|
|
65
|
-
HttpClient.HttpClient
|
|
66
|
-
>
|
|
67
|
-
// TODO support transactions (i.e. group of mutation events which need to be applied together)
|
|
68
|
-
push: (
|
|
69
|
-
/**
|
|
70
|
-
* Constraints for batch:
|
|
71
|
-
* - Number of events: 1-100
|
|
72
|
-
* - sequence numbers must be in ascending order
|
|
73
|
-
* */
|
|
74
|
-
batch: ReadonlyArray<LiveStoreEvent.AnyEncodedGlobal>,
|
|
75
|
-
) => Effect.Effect<void, IsOfflineError | InvalidPushError, HttpClient.HttpClient>
|
|
76
|
-
isConnected: SubscriptionRef.SubscriptionRef<boolean>
|
|
77
|
-
/**
|
|
78
|
-
* Metadata describing the sync backend. (Currently only used by devtools.)
|
|
79
|
-
*/
|
|
80
|
-
metadata: { name: string; description: string } & Record<string, Schema.JsonValue>
|
|
26
|
+
livePull?: boolean
|
|
81
27
|
}
|
|
82
|
-
|
|
83
|
-
export class IsOfflineError extends Schema.TaggedError<IsOfflineError>()('IsOfflineError', {}) {}
|
|
84
|
-
|
|
85
|
-
// TODO gt rid of this error in favour of SyncError
|
|
86
|
-
export class InvalidPushError extends Schema.TaggedError<InvalidPushError>()('InvalidPushError', {
|
|
87
|
-
reason: Schema.Union(
|
|
88
|
-
Schema.TaggedStruct('Unexpected', {
|
|
89
|
-
message: Schema.String,
|
|
90
|
-
}),
|
|
91
|
-
Schema.TaggedStruct('ServerAhead', {
|
|
92
|
-
minimumExpectedNum: Schema.Number,
|
|
93
|
-
providedNum: Schema.Number,
|
|
94
|
-
}),
|
|
95
|
-
),
|
|
96
|
-
}) {}
|
|
97
|
-
|
|
98
|
-
// TODO gt rid of this error in favour of SyncError
|
|
99
|
-
export class InvalidPullError extends Schema.TaggedError<InvalidPullError>()('InvalidPullError', {
|
|
100
|
-
message: Schema.String,
|
|
101
|
-
}) {}
|
|
102
|
-
|
|
103
|
-
// TODO gt rid of this error in favour of SyncError
|
|
104
|
-
export class LeaderAheadError extends Schema.TaggedError<LeaderAheadError>()('LeaderAheadError', {
|
|
105
|
-
minimumExpectedNum: EventSequenceNumber.EventSequenceNumber,
|
|
106
|
-
providedNum: EventSequenceNumber.EventSequenceNumber,
|
|
107
|
-
/** Generation number the client session should use for subsequent pushes */
|
|
108
|
-
// nextGeneration: Schema.Number,
|
|
109
|
-
}) {}
|
|
@@ -1,31 +1,33 @@
|
|
|
1
1
|
import { describe, expect, it } from 'vitest'
|
|
2
2
|
|
|
3
|
-
import * as EventSequenceNumber from '../schema/EventSequenceNumber.ts'
|
|
4
|
-
import * as LiveStoreEvent from '../schema/LiveStoreEvent.ts'
|
|
3
|
+
import * as EventSequenceNumber from '../schema/EventSequenceNumber/mod.ts'
|
|
4
|
+
import * as LiveStoreEvent from '../schema/LiveStoreEvent/mod.ts'
|
|
5
5
|
import * as SyncState from './syncstate.ts'
|
|
6
6
|
|
|
7
|
-
class TestEvent extends LiveStoreEvent.EncodedWithMeta {
|
|
8
|
-
public
|
|
9
|
-
public
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
7
|
+
class TestEvent extends LiveStoreEvent.Client.EncodedWithMeta {
|
|
8
|
+
public payload = 'uninitialized'
|
|
9
|
+
public isClient = false
|
|
10
|
+
|
|
11
|
+
static new = (
|
|
12
|
+
seqNum: EventSequenceNumber.Client.CompositeInput,
|
|
13
|
+
parentSeqNum: EventSequenceNumber.Client.CompositeInput,
|
|
13
14
|
payload: string,
|
|
14
15
|
isClient: boolean,
|
|
15
|
-
) {
|
|
16
|
-
|
|
17
|
-
seqNum: EventSequenceNumber.make(seqNum),
|
|
18
|
-
parentSeqNum: EventSequenceNumber.make(parentSeqNum),
|
|
16
|
+
) => {
|
|
17
|
+
const event = new TestEvent({
|
|
18
|
+
seqNum: EventSequenceNumber.Client.Composite.make(seqNum),
|
|
19
|
+
parentSeqNum: EventSequenceNumber.Client.Composite.make(parentSeqNum),
|
|
19
20
|
name: 'a',
|
|
20
21
|
args: payload,
|
|
21
22
|
clientId: 'static-local-id',
|
|
22
23
|
sessionId: 'static-session-id',
|
|
23
24
|
})
|
|
24
|
-
|
|
25
|
-
|
|
25
|
+
event.payload = payload
|
|
26
|
+
event.isClient = isClient
|
|
27
|
+
return event
|
|
26
28
|
}
|
|
27
29
|
|
|
28
|
-
rebase_ = (parentSeqNum: EventSequenceNumber.
|
|
30
|
+
rebase_ = (parentSeqNum: EventSequenceNumber.Client.Composite, rebaseGeneration: number) => {
|
|
29
31
|
return this.rebase({ parentSeqNum, isClient: this.isClient, rebaseGeneration })
|
|
30
32
|
}
|
|
31
33
|
|
|
@@ -34,17 +36,17 @@ class TestEvent extends LiveStoreEvent.EncodedWithMeta {
|
|
|
34
36
|
// toString = () => this.toJSON()
|
|
35
37
|
}
|
|
36
38
|
|
|
37
|
-
const e0_1 = new
|
|
38
|
-
const e1_0 = new
|
|
39
|
-
const e1_1 = new
|
|
40
|
-
const e1_2 = new
|
|
41
|
-
const e1_3 = new
|
|
42
|
-
const e2_0 = new
|
|
43
|
-
const e2_1 = new
|
|
39
|
+
const e0_1 = TestEvent.new({ global: 0, client: 1 }, EventSequenceNumber.Client.ROOT, 'a', true)
|
|
40
|
+
const e1_0 = TestEvent.new({ global: 1, client: 0 }, EventSequenceNumber.Client.ROOT, 'a', false)
|
|
41
|
+
const e1_1 = TestEvent.new({ global: 1, client: 1 }, e1_0.seqNum, 'a', true)
|
|
42
|
+
const e1_2 = TestEvent.new({ global: 1, client: 2 }, e1_1.seqNum, 'a', true)
|
|
43
|
+
const e1_3 = TestEvent.new({ global: 1, client: 3 }, e1_2.seqNum, 'a', true)
|
|
44
|
+
const e2_0 = TestEvent.new({ global: 2, client: 0 }, e1_0.seqNum, 'a', false)
|
|
45
|
+
const e2_1 = TestEvent.new({ global: 2, client: 1 }, e2_0.seqNum, 'a', true)
|
|
44
46
|
|
|
45
|
-
const isEqualEvent = LiveStoreEvent.isEqualEncoded
|
|
47
|
+
const isEqualEvent = LiveStoreEvent.Client.isEqualEncoded
|
|
46
48
|
|
|
47
|
-
const isClientEvent = (event: LiveStoreEvent.EncodedWithMeta) => (event as TestEvent).isClient
|
|
49
|
+
const isClientEvent = (event: LiveStoreEvent.Client.EncodedWithMeta) => (event as TestEvent).isClient
|
|
48
50
|
|
|
49
51
|
describe('syncstate', () => {
|
|
50
52
|
describe('merge', () => {
|
|
@@ -62,7 +64,7 @@ describe('syncstate', () => {
|
|
|
62
64
|
it('should rollback until start', () => {
|
|
63
65
|
const syncState = new SyncState.SyncState({
|
|
64
66
|
pending: [e2_0],
|
|
65
|
-
upstreamHead: EventSequenceNumber.ROOT,
|
|
67
|
+
upstreamHead: EventSequenceNumber.Client.ROOT,
|
|
66
68
|
localHead: e2_0.seqNum,
|
|
67
69
|
})
|
|
68
70
|
const e1_0_e2_0 = e1_0.rebase_(e2_0.seqNum, 0)
|
|
@@ -86,7 +88,7 @@ describe('syncstate', () => {
|
|
|
86
88
|
it('should rollback only to specified point', () => {
|
|
87
89
|
const syncState = new SyncState.SyncState({
|
|
88
90
|
pending: [e2_0],
|
|
89
|
-
upstreamHead: EventSequenceNumber.ROOT,
|
|
91
|
+
upstreamHead: EventSequenceNumber.Client.ROOT,
|
|
90
92
|
localHead: e2_0.seqNum,
|
|
91
93
|
})
|
|
92
94
|
const e1_1_e2_0 = e1_1.rebase_(e1_0.seqNum, 0)
|
|
@@ -109,7 +111,7 @@ describe('syncstate', () => {
|
|
|
109
111
|
it('should work for empty pending', () => {
|
|
110
112
|
const syncState = new SyncState.SyncState({
|
|
111
113
|
pending: [],
|
|
112
|
-
upstreamHead: EventSequenceNumber.ROOT,
|
|
114
|
+
upstreamHead: EventSequenceNumber.Client.ROOT,
|
|
113
115
|
localHead: e1_0.seqNum,
|
|
114
116
|
})
|
|
115
117
|
const result = merge({
|
|
@@ -128,21 +130,21 @@ describe('syncstate', () => {
|
|
|
128
130
|
it('should throw error if newEvents are not sorted in ascending order by event number (client)', () => {
|
|
129
131
|
const syncState = new SyncState.SyncState({
|
|
130
132
|
pending: [e1_0],
|
|
131
|
-
upstreamHead: EventSequenceNumber.ROOT,
|
|
133
|
+
upstreamHead: EventSequenceNumber.Client.ROOT,
|
|
132
134
|
localHead: e1_0.seqNum,
|
|
133
135
|
})
|
|
134
136
|
const result = merge({ syncState, payload: { _tag: 'upstream-advance', newEvents: [e1_1, e1_0] } })
|
|
135
|
-
expect(result).toMatchObject({ _tag: '
|
|
137
|
+
expect(result).toMatchObject({ _tag: 'unknown-error' })
|
|
136
138
|
})
|
|
137
139
|
|
|
138
140
|
it('should throw error if newEvents are not sorted in ascending order by event number (global)', () => {
|
|
139
141
|
const syncState = new SyncState.SyncState({
|
|
140
142
|
pending: [e1_0],
|
|
141
|
-
upstreamHead: EventSequenceNumber.ROOT,
|
|
143
|
+
upstreamHead: EventSequenceNumber.Client.ROOT,
|
|
142
144
|
localHead: e1_0.seqNum,
|
|
143
145
|
})
|
|
144
146
|
const result = merge({ syncState, payload: { _tag: 'upstream-advance', newEvents: [e2_0, e1_0] } })
|
|
145
|
-
expect(result).toMatchObject({ _tag: '
|
|
147
|
+
expect(result).toMatchObject({ _tag: 'unknown-error' })
|
|
146
148
|
})
|
|
147
149
|
|
|
148
150
|
it('should throw error if incoming event is < expected upstream head', () => {
|
|
@@ -152,7 +154,7 @@ describe('syncstate', () => {
|
|
|
152
154
|
localHead: e2_0.seqNum,
|
|
153
155
|
})
|
|
154
156
|
const result = merge({ syncState, payload: { _tag: 'upstream-advance', newEvents: [e1_0] } })
|
|
155
|
-
expect(result).toMatchObject({ _tag: '
|
|
157
|
+
expect(result).toMatchObject({ _tag: 'unknown-error' })
|
|
156
158
|
})
|
|
157
159
|
|
|
158
160
|
it('should throw error if incoming event is = expected upstream head', () => {
|
|
@@ -162,13 +164,13 @@ describe('syncstate', () => {
|
|
|
162
164
|
localHead: e2_0.seqNum,
|
|
163
165
|
})
|
|
164
166
|
const result = merge({ syncState, payload: { _tag: 'upstream-advance', newEvents: [e2_0] } })
|
|
165
|
-
expect(result).toMatchObject({ _tag: '
|
|
167
|
+
expect(result).toMatchObject({ _tag: 'unknown-error' })
|
|
166
168
|
})
|
|
167
169
|
|
|
168
170
|
it('should confirm pending event when receiving matching event', () => {
|
|
169
171
|
const syncState = new SyncState.SyncState({
|
|
170
172
|
pending: [e1_0],
|
|
171
|
-
upstreamHead: EventSequenceNumber.ROOT,
|
|
173
|
+
upstreamHead: EventSequenceNumber.Client.ROOT,
|
|
172
174
|
localHead: e1_0.seqNum,
|
|
173
175
|
})
|
|
174
176
|
const result = merge({ syncState, payload: { _tag: 'upstream-advance', newEvents: [e1_0] } })
|
|
@@ -184,7 +186,7 @@ describe('syncstate', () => {
|
|
|
184
186
|
it('should confirm partial pending event when receiving matching event', () => {
|
|
185
187
|
const syncState = new SyncState.SyncState({
|
|
186
188
|
pending: [e1_0, e2_0],
|
|
187
|
-
upstreamHead: EventSequenceNumber.ROOT,
|
|
189
|
+
upstreamHead: EventSequenceNumber.Client.ROOT,
|
|
188
190
|
localHead: e2_0.seqNum,
|
|
189
191
|
})
|
|
190
192
|
const result = merge({ syncState, payload: { _tag: 'upstream-advance', newEvents: [e1_0] } })
|
|
@@ -200,7 +202,7 @@ describe('syncstate', () => {
|
|
|
200
202
|
it('should confirm pending event and add new event', () => {
|
|
201
203
|
const syncState = new SyncState.SyncState({
|
|
202
204
|
pending: [e1_0],
|
|
203
|
-
upstreamHead: EventSequenceNumber.ROOT,
|
|
205
|
+
upstreamHead: EventSequenceNumber.Client.ROOT,
|
|
204
206
|
localHead: e1_0.seqNum,
|
|
205
207
|
})
|
|
206
208
|
const result = merge({ syncState, payload: { _tag: 'upstream-advance', newEvents: [e1_0, e1_1] } })
|
|
@@ -235,7 +237,7 @@ describe('syncstate', () => {
|
|
|
235
237
|
it('should confirm pending global event while keep pending client events', () => {
|
|
236
238
|
const syncState = new SyncState.SyncState({
|
|
237
239
|
pending: [e1_0, e1_1],
|
|
238
|
-
upstreamHead: EventSequenceNumber.ROOT,
|
|
240
|
+
upstreamHead: EventSequenceNumber.Client.ROOT,
|
|
239
241
|
localHead: e1_1.seqNum,
|
|
240
242
|
})
|
|
241
243
|
const result = merge({
|
|
@@ -254,7 +256,7 @@ describe('syncstate', () => {
|
|
|
254
256
|
it('should ignore client events (incoming is subset of pending)', () => {
|
|
255
257
|
const syncState = new SyncState.SyncState({
|
|
256
258
|
pending: [e0_1, e1_0],
|
|
257
|
-
upstreamHead: EventSequenceNumber.ROOT,
|
|
259
|
+
upstreamHead: EventSequenceNumber.Client.ROOT,
|
|
258
260
|
localHead: e1_0.seqNum,
|
|
259
261
|
})
|
|
260
262
|
const result = merge({
|
|
@@ -273,7 +275,7 @@ describe('syncstate', () => {
|
|
|
273
275
|
it('should ignore client events (incoming is subset of pending case 2)', () => {
|
|
274
276
|
const syncState = new SyncState.SyncState({
|
|
275
277
|
pending: [e0_1, e1_0, e2_0],
|
|
276
|
-
upstreamHead: EventSequenceNumber.ROOT,
|
|
278
|
+
upstreamHead: EventSequenceNumber.Client.ROOT,
|
|
277
279
|
localHead: e1_0.seqNum,
|
|
278
280
|
})
|
|
279
281
|
const result = merge({
|
|
@@ -292,7 +294,7 @@ describe('syncstate', () => {
|
|
|
292
294
|
it('should ignore client events (incoming goes beyond pending)', () => {
|
|
293
295
|
const syncState = new SyncState.SyncState({
|
|
294
296
|
pending: [e0_1, e1_0, e1_1],
|
|
295
|
-
upstreamHead: EventSequenceNumber.ROOT,
|
|
297
|
+
upstreamHead: EventSequenceNumber.Client.ROOT,
|
|
296
298
|
localHead: e1_1.seqNum,
|
|
297
299
|
})
|
|
298
300
|
const result = merge({
|
|
@@ -316,7 +318,7 @@ describe('syncstate', () => {
|
|
|
316
318
|
localHead: e2_0.seqNum,
|
|
317
319
|
})
|
|
318
320
|
const result = merge({ syncState, payload: { _tag: 'upstream-advance', newEvents: [e1_0] } })
|
|
319
|
-
expect(result).toMatchObject({ _tag: '
|
|
321
|
+
expect(result).toMatchObject({ _tag: 'unknown-error' })
|
|
320
322
|
})
|
|
321
323
|
})
|
|
322
324
|
|
|
@@ -324,7 +326,7 @@ describe('syncstate', () => {
|
|
|
324
326
|
it('should rebase single client event to end', () => {
|
|
325
327
|
const syncState = new SyncState.SyncState({
|
|
326
328
|
pending: [e1_0],
|
|
327
|
-
upstreamHead: EventSequenceNumber.ROOT,
|
|
329
|
+
upstreamHead: EventSequenceNumber.Client.ROOT,
|
|
328
330
|
localHead: e1_0.seqNum,
|
|
329
331
|
})
|
|
330
332
|
const result = merge({ syncState, payload: SyncState.PayloadUpstreamAdvance.make({ newEvents: [e1_1] }) })
|
|
@@ -340,10 +342,10 @@ describe('syncstate', () => {
|
|
|
340
342
|
})
|
|
341
343
|
|
|
342
344
|
it('should rebase different event with same id', () => {
|
|
343
|
-
const e2_0_b = new
|
|
345
|
+
const e2_0_b = TestEvent.new({ global: 1, client: 0 }, e1_0.seqNum, '1_0_b', false)
|
|
344
346
|
const syncState = new SyncState.SyncState({
|
|
345
347
|
pending: [e2_0_b],
|
|
346
|
-
upstreamHead: EventSequenceNumber.ROOT,
|
|
348
|
+
upstreamHead: EventSequenceNumber.Client.ROOT,
|
|
347
349
|
localHead: e2_0_b.seqNum,
|
|
348
350
|
})
|
|
349
351
|
const result = merge({ syncState, payload: SyncState.PayloadUpstreamAdvance.make({ newEvents: [e2_0] }) })
|
|
@@ -360,7 +362,7 @@ describe('syncstate', () => {
|
|
|
360
362
|
it('should rebase single client event to end (more incoming events)', () => {
|
|
361
363
|
const syncState = new SyncState.SyncState({
|
|
362
364
|
pending: [e1_0],
|
|
363
|
-
upstreamHead: EventSequenceNumber.ROOT,
|
|
365
|
+
upstreamHead: EventSequenceNumber.Client.ROOT,
|
|
364
366
|
localHead: e1_0.seqNum,
|
|
365
367
|
})
|
|
366
368
|
const result = merge({
|
|
@@ -379,7 +381,7 @@ describe('syncstate', () => {
|
|
|
379
381
|
it('should only rebase divergent events when first event matches', () => {
|
|
380
382
|
const syncState = new SyncState.SyncState({
|
|
381
383
|
pending: [e1_0, e1_1],
|
|
382
|
-
upstreamHead: EventSequenceNumber.ROOT,
|
|
384
|
+
upstreamHead: EventSequenceNumber.Client.ROOT,
|
|
383
385
|
localHead: e1_0.seqNum,
|
|
384
386
|
})
|
|
385
387
|
const result = merge({
|
|
@@ -400,7 +402,7 @@ describe('syncstate', () => {
|
|
|
400
402
|
it('should rebase all client events when incoming chain starts differently', () => {
|
|
401
403
|
const syncState = new SyncState.SyncState({
|
|
402
404
|
pending: [e1_0, e1_1],
|
|
403
|
-
upstreamHead: EventSequenceNumber.ROOT,
|
|
405
|
+
upstreamHead: EventSequenceNumber.Client.ROOT,
|
|
404
406
|
localHead: e1_1.seqNum,
|
|
405
407
|
})
|
|
406
408
|
const result = merge({
|
|
@@ -424,7 +426,7 @@ describe('syncstate', () => {
|
|
|
424
426
|
it('should advance with new events', () => {
|
|
425
427
|
const syncState = new SyncState.SyncState({
|
|
426
428
|
pending: [e1_0],
|
|
427
|
-
upstreamHead: EventSequenceNumber.ROOT,
|
|
429
|
+
upstreamHead: EventSequenceNumber.Client.ROOT,
|
|
428
430
|
localHead: e1_0.seqNum,
|
|
429
431
|
})
|
|
430
432
|
const result = merge({
|
|
@@ -434,18 +436,60 @@ describe('syncstate', () => {
|
|
|
434
436
|
|
|
435
437
|
expectAdvance(result)
|
|
436
438
|
expectEventArraysEqual(result.newSyncState.pending, [e1_0, e1_1, e1_2, e1_3])
|
|
437
|
-
expect(result.newSyncState.upstreamHead).toMatchObject(EventSequenceNumber.ROOT)
|
|
439
|
+
expect(result.newSyncState.upstreamHead).toMatchObject(EventSequenceNumber.Client.ROOT)
|
|
438
440
|
expect(result.newSyncState.localHead).toMatchObject(e1_3.seqNum)
|
|
439
441
|
expectEventArraysEqual(result.newEvents, [e1_1, e1_2, e1_3])
|
|
440
442
|
expectEventArraysEqual(result.confirmedEvents, [])
|
|
441
443
|
})
|
|
444
|
+
|
|
445
|
+
// Leaders can choose to ignore client-only events while still returning them for broadcast.
|
|
446
|
+
// Ensure pending/local head only reflects events that must be pushed upstream.
|
|
447
|
+
it('keeps pending empty when pushing only client-only events that are being ignored', () => {
|
|
448
|
+
const syncState = new SyncState.SyncState({
|
|
449
|
+
pending: [],
|
|
450
|
+
upstreamHead: EventSequenceNumber.Client.ROOT,
|
|
451
|
+
localHead: EventSequenceNumber.Client.ROOT,
|
|
452
|
+
})
|
|
453
|
+
|
|
454
|
+
const result = merge({
|
|
455
|
+
syncState,
|
|
456
|
+
payload: SyncState.PayloadLocalPush.make({ newEvents: [e0_1] }),
|
|
457
|
+
ignoreClientEvents: true,
|
|
458
|
+
})
|
|
459
|
+
|
|
460
|
+
expectAdvance(result)
|
|
461
|
+
expectEventArraysEqual(result.newSyncState.pending, [])
|
|
462
|
+
expect(result.newSyncState.upstreamHead).toMatchObject(EventSequenceNumber.Client.ROOT)
|
|
463
|
+
expect(result.newSyncState.localHead).toMatchObject(EventSequenceNumber.Client.ROOT)
|
|
464
|
+
expectEventArraysEqual(result.newEvents, [e0_1])
|
|
465
|
+
})
|
|
466
|
+
|
|
467
|
+
it('appends only upstream-bound events to pending when ignoring client-only pushes', () => {
|
|
468
|
+
const syncState = new SyncState.SyncState({
|
|
469
|
+
pending: [],
|
|
470
|
+
upstreamHead: EventSequenceNumber.Client.ROOT,
|
|
471
|
+
localHead: EventSequenceNumber.Client.ROOT,
|
|
472
|
+
})
|
|
473
|
+
|
|
474
|
+
const result = merge({
|
|
475
|
+
syncState,
|
|
476
|
+
payload: SyncState.PayloadLocalPush.make({ newEvents: [e0_1, e1_0] }),
|
|
477
|
+
ignoreClientEvents: true,
|
|
478
|
+
})
|
|
479
|
+
|
|
480
|
+
expectAdvance(result)
|
|
481
|
+
expectEventArraysEqual(result.newSyncState.pending, [e1_0])
|
|
482
|
+
expect(result.newSyncState.upstreamHead).toMatchObject(EventSequenceNumber.Client.ROOT)
|
|
483
|
+
expect(result.newSyncState.localHead).toMatchObject(e1_0.seqNum)
|
|
484
|
+
expectEventArraysEqual(result.newEvents, [e0_1, e1_0])
|
|
485
|
+
})
|
|
442
486
|
})
|
|
443
487
|
|
|
444
488
|
describe('reject', () => {
|
|
445
489
|
it('should reject when new events are greater than pending events', () => {
|
|
446
490
|
const syncState = new SyncState.SyncState({
|
|
447
491
|
pending: [e1_0, e1_1],
|
|
448
|
-
upstreamHead: EventSequenceNumber.ROOT,
|
|
492
|
+
upstreamHead: EventSequenceNumber.Client.ROOT,
|
|
449
493
|
localHead: e1_1.seqNum,
|
|
450
494
|
})
|
|
451
495
|
const result = merge({
|
|
@@ -463,8 +507,8 @@ describe('syncstate', () => {
|
|
|
463
507
|
})
|
|
464
508
|
|
|
465
509
|
const expectEventArraysEqual = (
|
|
466
|
-
actual: ReadonlyArray<LiveStoreEvent.EncodedWithMeta>,
|
|
467
|
-
expected: ReadonlyArray<LiveStoreEvent.EncodedWithMeta>,
|
|
510
|
+
actual: ReadonlyArray<LiveStoreEvent.Client.EncodedWithMeta>,
|
|
511
|
+
expected: ReadonlyArray<LiveStoreEvent.Client.EncodedWithMeta>,
|
|
468
512
|
) => {
|
|
469
513
|
expect(actual.length).toBe(expected.length)
|
|
470
514
|
actual.forEach((event, i) => {
|