@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
|
@@ -1,13 +1,30 @@
|
|
|
1
|
-
import { shouldNeverHappen } from '@livestore/utils'
|
|
2
|
-
import type { HttpClient,
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
import { omitUndefineds, shouldNeverHappen } from '@livestore/utils'
|
|
2
|
+
import type { HttpClient, Scope } from '@livestore/utils/effect'
|
|
3
|
+
import {
|
|
4
|
+
Deferred,
|
|
5
|
+
Effect,
|
|
6
|
+
KeyValueStore,
|
|
7
|
+
Layer,
|
|
8
|
+
PlatformError,
|
|
9
|
+
Queue,
|
|
10
|
+
Schema,
|
|
11
|
+
Stream,
|
|
12
|
+
Subscribable,
|
|
13
|
+
SubscriptionRef,
|
|
14
|
+
} from '@livestore/utils/effect'
|
|
15
|
+
import {
|
|
16
|
+
type BootStatus,
|
|
17
|
+
type MakeSqliteDb,
|
|
18
|
+
type MaterializerHashMismatchError,
|
|
19
|
+
type SqliteDb,
|
|
20
|
+
type SqliteError,
|
|
21
|
+
UnknownError,
|
|
22
|
+
} from '../adapter-types.ts'
|
|
23
|
+
import type { MigrationsReport } from '../defs.ts'
|
|
7
24
|
import type * as Devtools from '../devtools/mod.ts'
|
|
8
25
|
import type { LiveStoreSchema } from '../schema/mod.ts'
|
|
9
26
|
import { EventSequenceNumber, LiveStoreEvent, SystemTables } from '../schema/mod.ts'
|
|
10
|
-
import type { InvalidPullError, IsOfflineError, SyncOptions } from '../sync/sync.ts'
|
|
27
|
+
import type { InvalidPullError, IsOfflineError, SyncBackend, SyncOptions } from '../sync/sync.ts'
|
|
11
28
|
import { SyncState } from '../sync/syncstate.ts'
|
|
12
29
|
import { sql } from '../util.ts'
|
|
13
30
|
import * as Eventlog from './eventlog.ts'
|
|
@@ -17,6 +34,7 @@ import { makeMaterializeEvent } from './materialize-event.ts'
|
|
|
17
34
|
import { recreateDb } from './recreate-db.ts'
|
|
18
35
|
import type { ShutdownChannel } from './shutdown-channel.ts'
|
|
19
36
|
import type {
|
|
37
|
+
DevtoolsContext,
|
|
20
38
|
DevtoolsOptions,
|
|
21
39
|
InitialBlockingSyncContext,
|
|
22
40
|
InitialSyncOptions,
|
|
@@ -27,7 +45,8 @@ import { LeaderThreadCtx } from './types.ts'
|
|
|
27
45
|
|
|
28
46
|
export interface MakeLeaderThreadLayerParams {
|
|
29
47
|
storeId: string
|
|
30
|
-
|
|
48
|
+
syncPayloadSchema: Schema.Schema<any> | undefined
|
|
49
|
+
syncPayloadEncoded: Schema.JsonValue | undefined
|
|
31
50
|
clientId: string
|
|
32
51
|
schema: LiveStoreSchema
|
|
33
52
|
makeSqliteDb: MakeSqliteDb
|
|
@@ -53,7 +72,8 @@ export const makeLeaderThreadLayer = ({
|
|
|
53
72
|
schema,
|
|
54
73
|
storeId,
|
|
55
74
|
clientId,
|
|
56
|
-
|
|
75
|
+
syncPayloadSchema = Schema.JsonValue,
|
|
76
|
+
syncPayloadEncoded,
|
|
57
77
|
makeSqliteDb,
|
|
58
78
|
syncOptions,
|
|
59
79
|
dbState,
|
|
@@ -62,8 +82,11 @@ export const makeLeaderThreadLayer = ({
|
|
|
62
82
|
shutdownChannel,
|
|
63
83
|
params,
|
|
64
84
|
testing,
|
|
65
|
-
}: MakeLeaderThreadLayerParams): Layer.Layer<LeaderThreadCtx,
|
|
85
|
+
}: MakeLeaderThreadLayerParams): Layer.Layer<LeaderThreadCtx, UnknownError, Scope.Scope | HttpClient.HttpClient> =>
|
|
66
86
|
Effect.gen(function* () {
|
|
87
|
+
const syncPayloadDecoded =
|
|
88
|
+
syncPayloadEncoded === undefined ? undefined : yield* Schema.decodeUnknown(syncPayloadSchema)(syncPayloadEncoded)
|
|
89
|
+
|
|
67
90
|
const bootStatusQueue = yield* Queue.unbounded<BootStatus>().pipe(Effect.acquireRelease(Queue.shutdown))
|
|
68
91
|
|
|
69
92
|
const dbEventlogMissing = !hasEventlogTables(dbEventlog)
|
|
@@ -71,10 +94,45 @@ export const makeLeaderThreadLayer = ({
|
|
|
71
94
|
// Either happens on initial boot or if schema changes
|
|
72
95
|
const dbStateMissing = !hasStateTables(dbState)
|
|
73
96
|
|
|
97
|
+
yield* Eventlog.initEventlogDb(dbEventlog)
|
|
98
|
+
|
|
74
99
|
const syncBackend =
|
|
75
100
|
syncOptions?.backend === undefined
|
|
76
101
|
? undefined
|
|
77
|
-
: yield* syncOptions.backend({ storeId, clientId, payload:
|
|
102
|
+
: yield* syncOptions.backend({ storeId, clientId, payload: syncPayloadDecoded }).pipe(
|
|
103
|
+
Effect.provide(
|
|
104
|
+
Layer.succeed(
|
|
105
|
+
KeyValueStore.KeyValueStore,
|
|
106
|
+
KeyValueStore.makeStringOnly({
|
|
107
|
+
get: (_key) =>
|
|
108
|
+
Effect.sync(() => Eventlog.getBackendIdFromDb(dbEventlog)).pipe(
|
|
109
|
+
Effect.catchAllDefect((cause) =>
|
|
110
|
+
PlatformError.BadArgument.make({
|
|
111
|
+
method: 'getBackendIdFromDb',
|
|
112
|
+
description: 'Failed to get backendId',
|
|
113
|
+
module: 'KeyValueStore',
|
|
114
|
+
cause,
|
|
115
|
+
}),
|
|
116
|
+
),
|
|
117
|
+
),
|
|
118
|
+
set: (_key, value) =>
|
|
119
|
+
Effect.sync(() => Eventlog.updateBackendId(dbEventlog, value)).pipe(
|
|
120
|
+
Effect.catchAllDefect((cause) =>
|
|
121
|
+
PlatformError.BadArgument.make({
|
|
122
|
+
method: 'updateBackendId',
|
|
123
|
+
module: 'KeyValueStore',
|
|
124
|
+
description: 'Failed to update backendId',
|
|
125
|
+
cause,
|
|
126
|
+
}),
|
|
127
|
+
),
|
|
128
|
+
),
|
|
129
|
+
clear: Effect.dieMessage(`Not implemented. Should never be used.`),
|
|
130
|
+
remove: () => Effect.dieMessage(`Not implemented. Should never be used.`),
|
|
131
|
+
size: Effect.dieMessage(`Not implemented. Should never be used.`),
|
|
132
|
+
}),
|
|
133
|
+
),
|
|
134
|
+
),
|
|
135
|
+
)
|
|
78
136
|
|
|
79
137
|
if (syncBackend !== undefined) {
|
|
80
138
|
// We're already connecting to the sync backend concurrently
|
|
@@ -86,18 +144,29 @@ export const makeLeaderThreadLayer = ({
|
|
|
86
144
|
bootStatusQueue,
|
|
87
145
|
})
|
|
88
146
|
|
|
147
|
+
const materializeEvent = yield* makeMaterializeEvent({ schema, dbState, dbEventlog })
|
|
148
|
+
|
|
149
|
+
// Recreate state database if needed BEFORE creating sync processor
|
|
150
|
+
// This ensures all system tables exist before any queries are made
|
|
151
|
+
const { migrationsReport } = dbStateMissing
|
|
152
|
+
? yield* recreateDb({ dbState, dbEventlog, schema, bootStatusQueue, materializeEvent })
|
|
153
|
+
: { migrationsReport: { migrations: [] } }
|
|
154
|
+
|
|
89
155
|
const syncProcessor = yield* makeLeaderSyncProcessor({
|
|
90
156
|
schema,
|
|
91
157
|
dbState,
|
|
92
158
|
initialSyncState: getInitialSyncState({ dbEventlog, dbState, dbEventlogMissing }),
|
|
93
159
|
initialBlockingSyncContext,
|
|
94
160
|
onError: syncOptions?.onSyncError ?? 'ignore',
|
|
161
|
+
livePull: syncOptions?.livePull ?? true,
|
|
95
162
|
params: {
|
|
96
|
-
|
|
97
|
-
|
|
163
|
+
...omitUndefineds({
|
|
164
|
+
localPushBatchSize: params?.localPushBatchSize,
|
|
165
|
+
backendPushBatchSize: params?.backendPushBatchSize,
|
|
166
|
+
}),
|
|
98
167
|
},
|
|
99
168
|
testing: {
|
|
100
|
-
delays: testing?.syncProcessor?.delays,
|
|
169
|
+
...omitUndefineds({ delays: testing?.syncProcessor?.delays }),
|
|
101
170
|
},
|
|
102
171
|
})
|
|
103
172
|
|
|
@@ -113,7 +182,7 @@ export const makeLeaderThreadLayer = ({
|
|
|
113
182
|
}
|
|
114
183
|
: { enabled: false as const }
|
|
115
184
|
|
|
116
|
-
const
|
|
185
|
+
const networkStatus = yield* makeNetworkStatusSubscribable({ syncBackend, devtoolsContext })
|
|
117
186
|
|
|
118
187
|
const ctx = {
|
|
119
188
|
schema,
|
|
@@ -123,7 +192,7 @@ export const makeLeaderThreadLayer = ({
|
|
|
123
192
|
dbState,
|
|
124
193
|
dbEventlog,
|
|
125
194
|
makeSqliteDb,
|
|
126
|
-
eventSchema: LiveStoreEvent.
|
|
195
|
+
eventSchema: LiveStoreEvent.Client.makeSchema(schema),
|
|
127
196
|
shutdownStateSubRef: yield* SubscriptionRef.make<ShutdownState>('running'),
|
|
128
197
|
shutdownChannel,
|
|
129
198
|
syncBackend,
|
|
@@ -131,6 +200,7 @@ export const makeLeaderThreadLayer = ({
|
|
|
131
200
|
materializeEvent,
|
|
132
201
|
extraIncomingMessagesQueue,
|
|
133
202
|
devtools: devtoolsContext,
|
|
203
|
+
networkStatus,
|
|
134
204
|
// State will be set during `bootLeaderThread`
|
|
135
205
|
initialState: {} as any as LeaderThreadCtx['Type']['initialState'],
|
|
136
206
|
} satisfies typeof LeaderThreadCtx.Service
|
|
@@ -141,7 +211,7 @@ export const makeLeaderThreadLayer = ({
|
|
|
141
211
|
const layer = Layer.succeed(LeaderThreadCtx, ctx)
|
|
142
212
|
|
|
143
213
|
ctx.initialState = yield* bootLeaderThread({
|
|
144
|
-
|
|
214
|
+
migrationsReport,
|
|
145
215
|
initialBlockingSyncContext,
|
|
146
216
|
devtoolsOptions,
|
|
147
217
|
}).pipe(Effect.provide(layer))
|
|
@@ -150,7 +220,7 @@ export const makeLeaderThreadLayer = ({
|
|
|
150
220
|
}).pipe(
|
|
151
221
|
Effect.withSpan('@livestore/common:leader-thread:boot'),
|
|
152
222
|
Effect.withSpanScoped('@livestore/common:leader-thread'),
|
|
153
|
-
|
|
223
|
+
UnknownError.mapToUnknownError,
|
|
154
224
|
Effect.tapCauseLogPretty,
|
|
155
225
|
Layer.unwrapScoped,
|
|
156
226
|
)
|
|
@@ -187,10 +257,12 @@ const getInitialSyncState = ({
|
|
|
187
257
|
dbEventlogMissing: boolean
|
|
188
258
|
}) => {
|
|
189
259
|
const initialBackendHead = dbEventlogMissing
|
|
190
|
-
? EventSequenceNumber.ROOT.global
|
|
260
|
+
? EventSequenceNumber.Client.ROOT.global
|
|
191
261
|
: Eventlog.getBackendHeadFromDb(dbEventlog)
|
|
192
262
|
|
|
193
|
-
const initialLocalHead = dbEventlogMissing
|
|
263
|
+
const initialLocalHead = dbEventlogMissing
|
|
264
|
+
? EventSequenceNumber.Client.ROOT
|
|
265
|
+
: Eventlog.getClientHeadFromDb(dbEventlog)
|
|
194
266
|
|
|
195
267
|
if (initialBackendHead > initialLocalHead.global) {
|
|
196
268
|
return shouldNeverHappen(
|
|
@@ -202,8 +274,8 @@ const getInitialSyncState = ({
|
|
|
202
274
|
localHead: initialLocalHead,
|
|
203
275
|
upstreamHead: {
|
|
204
276
|
global: initialBackendHead,
|
|
205
|
-
client: EventSequenceNumber.
|
|
206
|
-
rebaseGeneration: EventSequenceNumber.
|
|
277
|
+
client: EventSequenceNumber.Client.DEFAULT,
|
|
278
|
+
rebaseGeneration: EventSequenceNumber.Client.REBASE_GENERATION_DEFAULT,
|
|
207
279
|
},
|
|
208
280
|
pending: dbEventlogMissing
|
|
209
281
|
? []
|
|
@@ -212,7 +284,7 @@ const getInitialSyncState = ({
|
|
|
212
284
|
dbState,
|
|
213
285
|
since: {
|
|
214
286
|
global: initialBackendHead,
|
|
215
|
-
client: EventSequenceNumber.
|
|
287
|
+
client: EventSequenceNumber.Client.DEFAULT,
|
|
216
288
|
rebaseGeneration: initialLocalHead.rebaseGeneration,
|
|
217
289
|
},
|
|
218
290
|
}),
|
|
@@ -244,12 +316,12 @@ const makeInitialBlockingSyncContext = ({
|
|
|
244
316
|
|
|
245
317
|
return {
|
|
246
318
|
blockingDeferred,
|
|
247
|
-
update: ({ processed,
|
|
319
|
+
update: ({ processed, pageInfo }) =>
|
|
248
320
|
Effect.gen(function* () {
|
|
249
321
|
if (ctx.isDone === true) return
|
|
250
322
|
|
|
251
|
-
if (ctx.total === -1) {
|
|
252
|
-
ctx.total = remaining + processed
|
|
323
|
+
if (ctx.total === -1 && pageInfo._tag === 'MoreKnown') {
|
|
324
|
+
ctx.total = pageInfo.remaining + processed
|
|
253
325
|
}
|
|
254
326
|
|
|
255
327
|
ctx.processedEvents += processed
|
|
@@ -258,7 +330,7 @@ const makeInitialBlockingSyncContext = ({
|
|
|
258
330
|
progress: { done: ctx.processedEvents, total: ctx.total },
|
|
259
331
|
})
|
|
260
332
|
|
|
261
|
-
if (
|
|
333
|
+
if (pageInfo._tag === 'NoMore' && blockingDeferred !== undefined) {
|
|
262
334
|
yield* Deferred.succeed(blockingDeferred, void 0)
|
|
263
335
|
ctx.isDone = true
|
|
264
336
|
}
|
|
@@ -271,26 +343,20 @@ const makeInitialBlockingSyncContext = ({
|
|
|
271
343
|
* It also starts various background processes (e.g. syncing)
|
|
272
344
|
*/
|
|
273
345
|
const bootLeaderThread = ({
|
|
274
|
-
|
|
346
|
+
migrationsReport,
|
|
275
347
|
initialBlockingSyncContext,
|
|
276
348
|
devtoolsOptions,
|
|
277
349
|
}: {
|
|
278
|
-
|
|
350
|
+
migrationsReport: MigrationsReport
|
|
279
351
|
initialBlockingSyncContext: InitialBlockingSyncContext
|
|
280
352
|
devtoolsOptions: DevtoolsOptions
|
|
281
353
|
}): Effect.Effect<
|
|
282
354
|
LeaderThreadCtx['Type']['initialState'],
|
|
283
|
-
|
|
355
|
+
UnknownError | SqliteError | IsOfflineError | InvalidPullError | MaterializerHashMismatchError,
|
|
284
356
|
LeaderThreadCtx | Scope.Scope | HttpClient.HttpClient
|
|
285
357
|
> =>
|
|
286
358
|
Effect.gen(function* () {
|
|
287
|
-
const {
|
|
288
|
-
|
|
289
|
-
yield* Eventlog.initEventlogDb(dbEventlog)
|
|
290
|
-
|
|
291
|
-
const { migrationsReport } = dbStateMissing
|
|
292
|
-
? yield* recreateDb({ dbState, dbEventlog, schema, bootStatusQueue, materializeEvent })
|
|
293
|
-
: { migrationsReport: { migrations: [] } }
|
|
359
|
+
const { bootStatusQueue, syncProcessor } = yield* LeaderThreadCtx
|
|
294
360
|
|
|
295
361
|
// NOTE the sync processor depends on the dbs being initialized properly
|
|
296
362
|
const { initialLeaderHead } = yield* syncProcessor.boot
|
|
@@ -313,3 +379,56 @@ const bootLeaderThread = ({
|
|
|
313
379
|
|
|
314
380
|
return { migrationsReport, leaderHead: initialLeaderHead }
|
|
315
381
|
})
|
|
382
|
+
|
|
383
|
+
/** @internal */
|
|
384
|
+
export const makeNetworkStatusSubscribable = ({
|
|
385
|
+
syncBackend,
|
|
386
|
+
devtoolsContext,
|
|
387
|
+
}: {
|
|
388
|
+
syncBackend: SyncBackend.SyncBackend | undefined
|
|
389
|
+
devtoolsContext: DevtoolsContext
|
|
390
|
+
}): Effect.Effect<Subscribable.Subscribable<SyncBackend.NetworkStatus>, never, Scope.Scope> =>
|
|
391
|
+
Effect.gen(function* () {
|
|
392
|
+
const initialIsConnected = syncBackend !== undefined ? yield* SubscriptionRef.get(syncBackend.isConnected) : false
|
|
393
|
+
const initialLatchClosed =
|
|
394
|
+
devtoolsContext.enabled === true
|
|
395
|
+
? (yield* SubscriptionRef.get(devtoolsContext.syncBackendLatchState)).latchClosed
|
|
396
|
+
: false
|
|
397
|
+
|
|
398
|
+
const networkStatusRef = yield* SubscriptionRef.make<SyncBackend.NetworkStatus>({
|
|
399
|
+
isConnected: initialIsConnected,
|
|
400
|
+
timestampMs: Date.now(),
|
|
401
|
+
devtools: { latchClosed: initialLatchClosed },
|
|
402
|
+
})
|
|
403
|
+
|
|
404
|
+
const updateNetworkStatus = (patch: { isConnected?: boolean; latchClosed?: boolean }) =>
|
|
405
|
+
SubscriptionRef.update(networkStatusRef, (previous) => ({
|
|
406
|
+
isConnected: patch.isConnected ?? previous.isConnected,
|
|
407
|
+
timestampMs: Date.now(),
|
|
408
|
+
devtools: {
|
|
409
|
+
latchClosed: patch.latchClosed ?? previous.devtools.latchClosed,
|
|
410
|
+
},
|
|
411
|
+
}))
|
|
412
|
+
|
|
413
|
+
if (syncBackend !== undefined) {
|
|
414
|
+
yield* syncBackend.isConnected.changes.pipe(
|
|
415
|
+
Stream.tap((isConnected) => updateNetworkStatus({ isConnected })),
|
|
416
|
+
Stream.runDrain,
|
|
417
|
+
Effect.interruptible,
|
|
418
|
+
Effect.tapCauseLogPretty,
|
|
419
|
+
Effect.forkScoped,
|
|
420
|
+
)
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
if (devtoolsContext.enabled === true) {
|
|
424
|
+
yield* devtoolsContext.syncBackendLatchState.changes.pipe(
|
|
425
|
+
Stream.tap(({ latchClosed }) => updateNetworkStatus({ latchClosed })),
|
|
426
|
+
Stream.runDrain,
|
|
427
|
+
Effect.interruptible,
|
|
428
|
+
Effect.tapCauseLogPretty,
|
|
429
|
+
Effect.forkScoped,
|
|
430
|
+
)
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
return Subscribable.fromSubscriptionRef(networkStatusRef)
|
|
434
|
+
})
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
import { isDevEnv, LS_DEV, shouldNeverHappen } from '@livestore/utils'
|
|
2
2
|
import { Effect, Option, ReadonlyArray, Schema } from '@livestore/utils/effect'
|
|
3
3
|
|
|
4
|
-
import { type SqliteDb
|
|
4
|
+
import { MaterializeError, MaterializerHashMismatchError, type SqliteDb } from '../adapter-types.ts'
|
|
5
5
|
import { getExecStatementsFromMaterializer, hashMaterializerResults } from '../materializer-helper.ts'
|
|
6
6
|
import type { LiveStoreSchema } from '../schema/mod.ts'
|
|
7
|
-
import { EventSequenceNumber,
|
|
7
|
+
import { EventSequenceNumber, resolveEventDef, SystemTables, UNKNOWN_EVENT_SCHEMA_HASH } from '../schema/mod.ts'
|
|
8
8
|
import { insertRow } from '../sql-queries/index.ts'
|
|
9
9
|
import { sql } from '../util.ts'
|
|
10
10
|
import { execSql, execSqlPrepared } from './connection.ts'
|
|
11
11
|
import * as Eventlog from './eventlog.ts'
|
|
12
12
|
import type { MaterializeEvent } from './types.ts'
|
|
13
13
|
|
|
14
|
+
// TODO refactor `makeMaterializeEvent` to not return an Effect for the constructor as it's not needed
|
|
14
15
|
export const makeMaterializeEvent = ({
|
|
15
16
|
schema,
|
|
16
17
|
dbState,
|
|
@@ -19,7 +20,7 @@ export const makeMaterializeEvent = ({
|
|
|
19
20
|
schema: LiveStoreSchema
|
|
20
21
|
dbState: SqliteDb
|
|
21
22
|
dbEventlog: SqliteDb
|
|
22
|
-
}): Effect.Effect<MaterializeEvent
|
|
23
|
+
}): Effect.Effect<MaterializeEvent> =>
|
|
23
24
|
Effect.gen(function* () {
|
|
24
25
|
const eventDefSchemaHashMap = new Map(
|
|
25
26
|
// TODO Running `Schema.hash` can be a bottleneck for larger schemas. There is an opportunity to run this
|
|
@@ -32,8 +33,34 @@ export const makeMaterializeEvent = ({
|
|
|
32
33
|
Effect.gen(function* () {
|
|
33
34
|
const skipEventlog = options?.skipEventlog ?? false
|
|
34
35
|
|
|
35
|
-
const
|
|
36
|
-
|
|
36
|
+
const resolution = yield* resolveEventDef(schema, {
|
|
37
|
+
operation: '@livestore/common:leader-thread:materializeEvent',
|
|
38
|
+
event: eventEncoded,
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
if (resolution._tag === 'unknown') {
|
|
42
|
+
// Unknown events still enter the eventlog so newer clients can replay
|
|
43
|
+
// them once they learn the schema. We skip materialization to keep the
|
|
44
|
+
// local state consistent with the knowledge of the current client.
|
|
45
|
+
if (skipEventlog === false) {
|
|
46
|
+
yield* Eventlog.insertIntoEventlog(
|
|
47
|
+
eventEncoded,
|
|
48
|
+
dbEventlog,
|
|
49
|
+
UNKNOWN_EVENT_SCHEMA_HASH,
|
|
50
|
+
eventEncoded.clientId,
|
|
51
|
+
eventEncoded.sessionId,
|
|
52
|
+
)
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
dbState.debug.head = eventEncoded.seqNum
|
|
56
|
+
|
|
57
|
+
return {
|
|
58
|
+
sessionChangeset: { _tag: 'no-op' as const },
|
|
59
|
+
hash: Option.none(),
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const { eventDef, materializer } = resolution
|
|
37
64
|
|
|
38
65
|
const execArgsArr = getExecStatementsFromMaterializer({
|
|
39
66
|
eventDef,
|
|
@@ -49,10 +76,7 @@ export const makeMaterializeEvent = ({
|
|
|
49
76
|
eventEncoded.meta.materializerHashSession._tag === 'Some' &&
|
|
50
77
|
eventEncoded.meta.materializerHashSession.value !== materializerHash.value
|
|
51
78
|
) {
|
|
52
|
-
yield*
|
|
53
|
-
cause: `Materializer hash mismatch detected for event "${eventEncoded.name}".`,
|
|
54
|
-
note: `Please make sure your event materializer is a pure function without side effects.`,
|
|
55
|
-
})
|
|
79
|
+
return yield* MaterializerHashMismatchError.make({ eventName: eventEncoded.name })
|
|
56
80
|
}
|
|
57
81
|
|
|
58
82
|
// NOTE we might want to bring this back if we want to debug no-op events
|
|
@@ -126,11 +150,12 @@ export const makeMaterializeEvent = ({
|
|
|
126
150
|
hash: materializerHash,
|
|
127
151
|
}
|
|
128
152
|
}).pipe(
|
|
153
|
+
Effect.mapError((cause) => MaterializeError.make({ cause })),
|
|
129
154
|
Effect.withSpan(`@livestore/common:leader-thread:materializeEvent`, {
|
|
130
155
|
attributes: {
|
|
131
156
|
eventName: eventEncoded.name,
|
|
132
157
|
eventNum: eventEncoded.seqNum,
|
|
133
|
-
'span.label': `${EventSequenceNumber.toString(eventEncoded.seqNum)} ${eventEncoded.name}`,
|
|
158
|
+
'span.label': `${EventSequenceNumber.Client.toString(eventEncoded.seqNum)} ${eventEncoded.name}`,
|
|
134
159
|
},
|
|
135
160
|
}),
|
|
136
161
|
// Effect.logDuration('@livestore/common:leader-thread:materializeEvent'),
|
|
@@ -144,7 +169,7 @@ export const rollback = ({
|
|
|
144
169
|
}: {
|
|
145
170
|
dbState: SqliteDb
|
|
146
171
|
dbEventlog: SqliteDb
|
|
147
|
-
eventNumsToRollback: EventSequenceNumber.
|
|
172
|
+
eventNumsToRollback: EventSequenceNumber.Client.Composite[]
|
|
148
173
|
}) =>
|
|
149
174
|
Effect.gen(function* () {
|
|
150
175
|
const rollbackEvents = dbState
|
|
@@ -160,7 +185,7 @@ export const rollback = ({
|
|
|
160
185
|
changeset: _.changeset,
|
|
161
186
|
debug: _.debug,
|
|
162
187
|
}))
|
|
163
|
-
.toSorted((a, b) => EventSequenceNumber.compare(a.seqNum, b.seqNum))
|
|
188
|
+
.toSorted((a, b) => EventSequenceNumber.Client.compare(a.seqNum, b.seqNum))
|
|
164
189
|
|
|
165
190
|
// Apply changesets in reverse order
|
|
166
191
|
for (let i = rollbackEvents.length - 1; i >= 0; i--) {
|
|
@@ -2,8 +2,16 @@ import { casesHandled } from '@livestore/utils'
|
|
|
2
2
|
import { Effect, Queue } from '@livestore/utils/effect'
|
|
3
3
|
|
|
4
4
|
import type { MigrationsReport } from '../defs.ts'
|
|
5
|
-
import
|
|
6
|
-
|
|
5
|
+
import {
|
|
6
|
+
type BootStatus,
|
|
7
|
+
type MaterializeError,
|
|
8
|
+
type MigrationHooks,
|
|
9
|
+
migrateDb,
|
|
10
|
+
rematerializeFromEventlog,
|
|
11
|
+
type SqliteDb,
|
|
12
|
+
type SqliteError,
|
|
13
|
+
UnknownError,
|
|
14
|
+
} from '../index.ts'
|
|
7
15
|
import type { LiveStoreSchema } from '../schema/mod.ts'
|
|
8
16
|
import { configureConnection } from './connection.ts'
|
|
9
17
|
import type { MaterializeEvent } from './types.ts'
|
|
@@ -20,7 +28,7 @@ export const recreateDb = ({
|
|
|
20
28
|
schema: LiveStoreSchema
|
|
21
29
|
bootStatusQueue: Queue.Queue<BootStatus>
|
|
22
30
|
materializeEvent: MaterializeEvent
|
|
23
|
-
}): Effect.Effect<{ migrationsReport: MigrationsReport },
|
|
31
|
+
}): Effect.Effect<{ migrationsReport: MigrationsReport }, UnknownError | MaterializeError | SqliteError> =>
|
|
24
32
|
Effect.gen(function* () {
|
|
25
33
|
const migrationOptions = schema.state.sqlite.migrations
|
|
26
34
|
let migrationsReport: MigrationsReport
|
|
@@ -40,7 +48,7 @@ export const recreateDb = ({
|
|
|
40
48
|
|
|
41
49
|
const initDb = (hooks: Partial<MigrationHooks> | undefined) =>
|
|
42
50
|
Effect.gen(function* () {
|
|
43
|
-
yield* Effect.tryAll(() => hooks?.init?.(tmpDb)).pipe(
|
|
51
|
+
yield* Effect.tryAll(() => hooks?.init?.(tmpDb)).pipe(UnknownError.mapToUnknownError)
|
|
44
52
|
|
|
45
53
|
const migrationsReport = yield* migrateDb({
|
|
46
54
|
db: tmpDb,
|
|
@@ -49,7 +57,7 @@ export const recreateDb = ({
|
|
|
49
57
|
Queue.offer(bootStatusQueue, { stage: 'migrating', progress: { done, total } }),
|
|
50
58
|
})
|
|
51
59
|
|
|
52
|
-
yield* Effect.tryAll(() => hooks?.pre?.(tmpDb)).pipe(
|
|
60
|
+
yield* Effect.tryAll(() => hooks?.pre?.(tmpDb)).pipe(UnknownError.mapToUnknownError)
|
|
53
61
|
|
|
54
62
|
return { migrationsReport, tmpDb }
|
|
55
63
|
})
|
|
@@ -70,7 +78,7 @@ export const recreateDb = ({
|
|
|
70
78
|
Queue.offer(bootStatusQueue, { stage: 'rehydrating', progress: { done, total } }),
|
|
71
79
|
})
|
|
72
80
|
|
|
73
|
-
yield* Effect.tryAll(() => hooks?.post?.(initResult.tmpDb)).pipe(
|
|
81
|
+
yield* Effect.tryAll(() => hooks?.post?.(initResult.tmpDb)).pipe(UnknownError.mapToUnknownError)
|
|
74
82
|
|
|
75
83
|
break
|
|
76
84
|
}
|
|
@@ -80,7 +88,7 @@ export const recreateDb = ({
|
|
|
80
88
|
migrationsReport = { migrations: [] }
|
|
81
89
|
|
|
82
90
|
const newDbData = yield* Effect.tryAll(() => migrationOptions.migrate(oldDbData)).pipe(
|
|
83
|
-
|
|
91
|
+
UnknownError.mapToUnknownError,
|
|
84
92
|
)
|
|
85
93
|
|
|
86
94
|
tmpDb.import(newDbData)
|
|
@@ -1,9 +1,23 @@
|
|
|
1
1
|
import type { WebChannel } from '@livestore/utils/effect'
|
|
2
2
|
import { Schema } from '@livestore/utils/effect'
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
IntentionalShutdownCause,
|
|
6
|
+
InvalidPullError,
|
|
7
|
+
InvalidPushError,
|
|
8
|
+
IsOfflineError,
|
|
9
|
+
MaterializeError,
|
|
10
|
+
UnknownError,
|
|
11
|
+
} from '../index.ts'
|
|
5
12
|
|
|
6
|
-
export class All extends Schema.Union(
|
|
13
|
+
export class All extends Schema.Union(
|
|
14
|
+
IntentionalShutdownCause,
|
|
15
|
+
UnknownError,
|
|
16
|
+
IsOfflineError,
|
|
17
|
+
InvalidPushError,
|
|
18
|
+
InvalidPullError,
|
|
19
|
+
MaterializeError,
|
|
20
|
+
) {}
|
|
7
21
|
|
|
8
22
|
/**
|
|
9
23
|
* Used internally by an adapter to shutdown gracefully.
|
|
@@ -13,7 +13,7 @@ import { Context, Schema } from '@livestore/utils/effect'
|
|
|
13
13
|
import type { MeshNode } from '@livestore/webmesh'
|
|
14
14
|
|
|
15
15
|
import type { MigrationsReport } from '../defs.ts'
|
|
16
|
-
import type {
|
|
16
|
+
import type { MaterializeError } from '../errors.ts'
|
|
17
17
|
import type {
|
|
18
18
|
BootStatus,
|
|
19
19
|
Devtools,
|
|
@@ -22,7 +22,7 @@ import type {
|
|
|
22
22
|
PersistenceInfo,
|
|
23
23
|
SqliteDb,
|
|
24
24
|
SyncBackend,
|
|
25
|
-
|
|
25
|
+
UnknownError,
|
|
26
26
|
} from '../index.ts'
|
|
27
27
|
import type { EventSequenceNumber, LiveStoreEvent, LiveStoreSchema } from '../schema/mod.ts'
|
|
28
28
|
import type * as SyncState from '../sync/syncstate.ts'
|
|
@@ -43,7 +43,7 @@ export const InitialSyncOptions = Schema.Union(InitialSyncOptionsSkip, InitialSy
|
|
|
43
43
|
export type InitialSyncOptions = typeof InitialSyncOptions.Type
|
|
44
44
|
|
|
45
45
|
export type InitialSyncInfo = Option.Option<{
|
|
46
|
-
|
|
46
|
+
eventSequenceNumber: EventSequenceNumber.Global.Type
|
|
47
47
|
metadata: Option.Option<Schema.JsonValue>
|
|
48
48
|
}>
|
|
49
49
|
|
|
@@ -66,7 +66,7 @@ export type DevtoolsOptions =
|
|
|
66
66
|
persistenceInfo: PersistenceInfoPair
|
|
67
67
|
mode: 'proxy' | 'direct'
|
|
68
68
|
},
|
|
69
|
-
|
|
69
|
+
UnknownError,
|
|
70
70
|
Scope.Scope | HttpClient.HttpClient | LeaderThreadCtx
|
|
71
71
|
>
|
|
72
72
|
}
|
|
@@ -96,13 +96,13 @@ export class LeaderThreadCtx extends Context.Tag('LeaderThreadCtx')<
|
|
|
96
96
|
// TODO we should find a more elegant way to handle cases which need this ref for their implementation
|
|
97
97
|
shutdownStateSubRef: SubscriptionRef.SubscriptionRef<ShutdownState>
|
|
98
98
|
shutdownChannel: ShutdownChannel
|
|
99
|
-
eventSchema: LiveStoreEvent.
|
|
99
|
+
eventSchema: LiveStoreEvent.ForEventDef.ForRecord<any>
|
|
100
100
|
devtools: DevtoolsContext
|
|
101
|
-
syncBackend: SyncBackend | undefined
|
|
101
|
+
syncBackend: SyncBackend.SyncBackend | undefined
|
|
102
102
|
syncProcessor: LeaderSyncProcessor
|
|
103
103
|
materializeEvent: MaterializeEvent
|
|
104
104
|
initialState: {
|
|
105
|
-
leaderHead: EventSequenceNumber.
|
|
105
|
+
leaderHead: EventSequenceNumber.Client.Composite
|
|
106
106
|
migrationsReport: MigrationsReport
|
|
107
107
|
}
|
|
108
108
|
/**
|
|
@@ -111,11 +111,12 @@ export class LeaderThreadCtx extends Context.Tag('LeaderThreadCtx')<
|
|
|
111
111
|
* This is currently separated from `.devtools` as it also needs to work when devtools are disabled
|
|
112
112
|
*/
|
|
113
113
|
extraIncomingMessagesQueue: Queue.Queue<Devtools.Leader.MessageToApp>
|
|
114
|
+
networkStatus: Subscribable.Subscribable<SyncBackend.NetworkStatus>
|
|
114
115
|
}
|
|
115
116
|
>() {}
|
|
116
117
|
|
|
117
118
|
export type MaterializeEvent = (
|
|
118
|
-
eventEncoded: LiveStoreEvent.EncodedWithMeta,
|
|
119
|
+
eventEncoded: LiveStoreEvent.Client.EncodedWithMeta,
|
|
119
120
|
options?: {
|
|
120
121
|
/** Needed for rematerializeFromEventlog */
|
|
121
122
|
skipEventlog?: boolean
|
|
@@ -125,31 +126,32 @@ export type MaterializeEvent = (
|
|
|
125
126
|
sessionChangeset: { _tag: 'sessionChangeset'; data: Uint8Array<ArrayBuffer>; debug: any } | { _tag: 'no-op' }
|
|
126
127
|
hash: Option.Option<number>
|
|
127
128
|
},
|
|
128
|
-
|
|
129
|
+
MaterializeError
|
|
129
130
|
>
|
|
130
131
|
|
|
131
132
|
export type InitialBlockingSyncContext = {
|
|
132
133
|
blockingDeferred: Deferred.Deferred<void> | undefined
|
|
133
|
-
update: (_: {
|
|
134
|
+
update: (_: { pageInfo: SyncBackend.PullResPageInfo; processed: number }) => Effect.Effect<void>
|
|
134
135
|
}
|
|
135
136
|
|
|
136
137
|
export interface LeaderSyncProcessor {
|
|
137
138
|
/** Used by client sessions to subscribe to upstream sync state changes */
|
|
138
139
|
pull: (args: {
|
|
139
|
-
cursor: EventSequenceNumber.
|
|
140
|
-
}) => Stream.Stream<{ payload: typeof SyncState.PayloadUpstream.Type },
|
|
140
|
+
cursor: EventSequenceNumber.Client.Composite
|
|
141
|
+
}) => Stream.Stream<{ payload: typeof SyncState.PayloadUpstream.Type }, UnknownError>
|
|
141
142
|
/** The `pullQueue` API can be used instead of `pull` when more convenient */
|
|
142
143
|
pullQueue: (args: {
|
|
143
|
-
cursor: EventSequenceNumber.
|
|
144
|
-
}) => Effect.Effect<Queue.Queue<{ payload: typeof SyncState.PayloadUpstream.Type }>,
|
|
144
|
+
cursor: EventSequenceNumber.Client.Composite
|
|
145
|
+
}) => Effect.Effect<Queue.Queue<{ payload: typeof SyncState.PayloadUpstream.Type }>, UnknownError, Scope.Scope>
|
|
145
146
|
|
|
146
147
|
/** Used by client sessions to push events to the leader thread */
|
|
147
148
|
push: (
|
|
148
149
|
/** `batch` needs to follow the same rules as `batch` in `SyncBackend.push` */
|
|
149
|
-
batch: ReadonlyArray<LiveStoreEvent.EncodedWithMeta>,
|
|
150
|
+
batch: ReadonlyArray<LiveStoreEvent.Client.EncodedWithMeta>,
|
|
150
151
|
options?: {
|
|
151
152
|
/**
|
|
152
153
|
* If true, the effect will only finish when the local push has been processed (i.e. succeeded or was rejected).
|
|
154
|
+
* `true` doesn't mean the events have been pushed to the sync backend.
|
|
153
155
|
* @default false
|
|
154
156
|
*/
|
|
155
157
|
waitForProcessing?: boolean
|
|
@@ -158,14 +160,14 @@ export interface LeaderSyncProcessor {
|
|
|
158
160
|
|
|
159
161
|
/** Currently only used by devtools which don't provide their own event numbers */
|
|
160
162
|
pushPartial: (args: {
|
|
161
|
-
event: LiveStoreEvent.
|
|
163
|
+
event: LiveStoreEvent.Input.Encoded
|
|
162
164
|
clientId: string
|
|
163
165
|
sessionId: string
|
|
164
|
-
}) => Effect.Effect<void,
|
|
166
|
+
}) => Effect.Effect<void, UnknownError>
|
|
165
167
|
|
|
166
168
|
boot: Effect.Effect<
|
|
167
|
-
{ initialLeaderHead: EventSequenceNumber.
|
|
168
|
-
|
|
169
|
+
{ initialLeaderHead: EventSequenceNumber.Client.Composite },
|
|
170
|
+
UnknownError,
|
|
169
171
|
LeaderThreadCtx | Scope.Scope | HttpClient.HttpClient
|
|
170
172
|
>
|
|
171
173
|
syncState: Subscribable.Subscribable<SyncState.SyncState>
|