@livestore/common 0.3.0-dev.3 → 0.3.0-dev.31
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/.tsbuildinfo +1 -1
- package/dist/__tests__/fixture.d.ts +83 -221
- package/dist/__tests__/fixture.d.ts.map +1 -1
- package/dist/__tests__/fixture.js +33 -11
- package/dist/__tests__/fixture.js.map +1 -1
- package/dist/adapter-types.d.ts +128 -68
- package/dist/adapter-types.d.ts.map +1 -1
- package/dist/adapter-types.js +36 -7
- package/dist/adapter-types.js.map +1 -1
- package/dist/bounded-collections.d.ts.map +1 -1
- package/dist/debug-info.d.ts +1 -1
- package/dist/debug-info.d.ts.map +1 -1
- package/dist/debug-info.js +1 -0
- package/dist/debug-info.js.map +1 -1
- package/dist/devtools/devtools-messages-client-session.d.ts +389 -0
- package/dist/devtools/devtools-messages-client-session.d.ts.map +1 -0
- package/dist/devtools/devtools-messages-client-session.js +96 -0
- package/dist/devtools/devtools-messages-client-session.js.map +1 -0
- package/dist/devtools/devtools-messages-common.d.ts +68 -0
- package/dist/devtools/devtools-messages-common.d.ts.map +1 -0
- package/dist/devtools/devtools-messages-common.js +60 -0
- package/dist/devtools/devtools-messages-common.js.map +1 -0
- package/dist/devtools/devtools-messages-leader.d.ts +394 -0
- package/dist/devtools/devtools-messages-leader.d.ts.map +1 -0
- package/dist/devtools/devtools-messages-leader.js +147 -0
- package/dist/devtools/devtools-messages-leader.js.map +1 -0
- package/dist/devtools/devtools-messages.d.ts +3 -592
- package/dist/devtools/devtools-messages.d.ts.map +1 -1
- package/dist/devtools/devtools-messages.js +3 -171
- package/dist/devtools/devtools-messages.js.map +1 -1
- package/dist/devtools/devtools-sessioninfo.d.ts +28 -0
- package/dist/devtools/devtools-sessioninfo.d.ts.map +1 -0
- package/dist/devtools/devtools-sessioninfo.js +34 -0
- package/dist/devtools/devtools-sessioninfo.js.map +1 -0
- package/dist/devtools/mod.d.ts +39 -0
- package/dist/devtools/mod.d.ts.map +1 -0
- package/dist/devtools/mod.js +27 -0
- package/dist/devtools/mod.js.map +1 -0
- package/dist/index.d.ts +4 -11
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -7
- package/dist/index.js.map +1 -1
- package/dist/leader-thread/LeaderSyncProcessor.d.ts +62 -0
- package/dist/leader-thread/LeaderSyncProcessor.d.ts.map +1 -0
- package/dist/leader-thread/LeaderSyncProcessor.js +589 -0
- package/dist/leader-thread/LeaderSyncProcessor.js.map +1 -0
- package/dist/leader-thread/apply-event.d.ts +16 -0
- package/dist/leader-thread/apply-event.d.ts.map +1 -0
- package/dist/leader-thread/apply-event.js +103 -0
- package/dist/leader-thread/apply-event.js.map +1 -0
- package/dist/leader-thread/connection.d.ts +34 -6
- package/dist/leader-thread/connection.d.ts.map +1 -1
- package/dist/leader-thread/connection.js +22 -7
- package/dist/leader-thread/connection.js.map +1 -1
- package/dist/leader-thread/eventlog.d.ts +27 -0
- package/dist/leader-thread/eventlog.d.ts.map +1 -0
- package/dist/leader-thread/eventlog.js +123 -0
- package/dist/leader-thread/eventlog.js.map +1 -0
- package/dist/leader-thread/leader-worker-devtools.d.ts +1 -1
- package/dist/leader-thread/leader-worker-devtools.d.ts.map +1 -1
- package/dist/leader-thread/leader-worker-devtools.js +154 -132
- package/dist/leader-thread/leader-worker-devtools.js.map +1 -1
- package/dist/leader-thread/make-leader-thread-layer.d.ts +26 -12
- package/dist/leader-thread/make-leader-thread-layer.d.ts.map +1 -1
- package/dist/leader-thread/make-leader-thread-layer.js +82 -47
- package/dist/leader-thread/make-leader-thread-layer.js.map +1 -1
- package/dist/leader-thread/mod.d.ts +1 -1
- package/dist/leader-thread/mod.d.ts.map +1 -1
- package/dist/leader-thread/mod.js +1 -1
- package/dist/leader-thread/mod.js.map +1 -1
- package/dist/leader-thread/recreate-db.d.ts +4 -2
- package/dist/leader-thread/recreate-db.d.ts.map +1 -1
- package/dist/leader-thread/recreate-db.js +35 -25
- package/dist/leader-thread/recreate-db.js.map +1 -1
- package/dist/leader-thread/shutdown-channel.d.ts +2 -5
- package/dist/leader-thread/shutdown-channel.d.ts.map +1 -1
- package/dist/leader-thread/shutdown-channel.js +2 -4
- package/dist/leader-thread/shutdown-channel.js.map +1 -1
- package/dist/leader-thread/types.d.ts +86 -39
- package/dist/leader-thread/types.d.ts.map +1 -1
- package/dist/leader-thread/types.js +1 -3
- package/dist/leader-thread/types.js.map +1 -1
- package/dist/materializer-helper.d.ts +23 -0
- package/dist/materializer-helper.d.ts.map +1 -0
- package/dist/materializer-helper.js +70 -0
- package/dist/materializer-helper.js.map +1 -0
- package/dist/otel.d.ts +2 -0
- package/dist/otel.d.ts.map +1 -1
- package/dist/otel.js +5 -0
- package/dist/otel.js.map +1 -1
- package/dist/query-builder/api.d.ts +158 -55
- package/dist/query-builder/api.d.ts.map +1 -1
- package/dist/query-builder/api.js +3 -5
- package/dist/query-builder/api.js.map +1 -1
- package/dist/query-builder/astToSql.d.ts +7 -0
- package/dist/query-builder/astToSql.d.ts.map +1 -0
- package/dist/query-builder/astToSql.js +190 -0
- package/dist/query-builder/astToSql.js.map +1 -0
- package/dist/query-builder/impl.d.ts +3 -8
- package/dist/query-builder/impl.d.ts.map +1 -1
- package/dist/query-builder/impl.js +166 -124
- package/dist/query-builder/impl.js.map +1 -1
- package/dist/query-builder/impl.test.d.ts +86 -1
- package/dist/query-builder/impl.test.d.ts.map +1 -1
- package/dist/query-builder/impl.test.js +411 -69
- package/dist/query-builder/impl.test.js.map +1 -1
- package/dist/query-builder/mod.d.ts +7 -0
- package/dist/query-builder/mod.d.ts.map +1 -1
- package/dist/query-builder/mod.js +7 -0
- package/dist/query-builder/mod.js.map +1 -1
- package/dist/rehydrate-from-eventlog.d.ts +14 -0
- package/dist/rehydrate-from-eventlog.d.ts.map +1 -0
- package/dist/rehydrate-from-eventlog.js +65 -0
- package/dist/rehydrate-from-eventlog.js.map +1 -0
- package/dist/schema/EventDef.d.ts +136 -0
- package/dist/schema/EventDef.d.ts.map +1 -0
- package/dist/schema/EventDef.js +58 -0
- package/dist/schema/EventDef.js.map +1 -0
- package/dist/schema/EventId.d.ts +35 -15
- package/dist/schema/EventId.d.ts.map +1 -1
- package/dist/schema/EventId.js +57 -11
- package/dist/schema/EventId.js.map +1 -1
- package/dist/schema/EventId.test.d.ts +2 -0
- package/dist/schema/EventId.test.d.ts.map +1 -0
- package/dist/schema/EventId.test.js +11 -0
- package/dist/schema/EventId.test.js.map +1 -0
- package/dist/schema/LiveStoreEvent.d.ts +255 -0
- package/dist/schema/LiveStoreEvent.d.ts.map +1 -0
- package/dist/schema/LiveStoreEvent.js +118 -0
- package/dist/schema/LiveStoreEvent.js.map +1 -0
- package/dist/schema/client-document-def.d.ts +223 -0
- package/dist/schema/client-document-def.d.ts.map +1 -0
- package/dist/schema/client-document-def.js +170 -0
- package/dist/schema/client-document-def.js.map +1 -0
- package/dist/schema/client-document-def.test.d.ts +2 -0
- package/dist/schema/client-document-def.test.d.ts.map +1 -0
- package/dist/schema/client-document-def.test.js +201 -0
- package/dist/schema/client-document-def.test.js.map +1 -0
- package/dist/schema/db-schema/ast/sqlite.d.ts +69 -0
- package/dist/schema/db-schema/ast/sqlite.d.ts.map +1 -0
- package/dist/schema/db-schema/ast/sqlite.js +71 -0
- package/dist/schema/db-schema/ast/sqlite.js.map +1 -0
- package/dist/schema/db-schema/ast/validate.d.ts +3 -0
- package/dist/schema/db-schema/ast/validate.d.ts.map +1 -0
- package/dist/schema/db-schema/ast/validate.js +12 -0
- package/dist/schema/db-schema/ast/validate.js.map +1 -0
- package/dist/schema/db-schema/dsl/field-defs.d.ts +90 -0
- package/dist/schema/db-schema/dsl/field-defs.d.ts.map +1 -0
- package/dist/schema/db-schema/dsl/field-defs.js +87 -0
- package/dist/schema/db-schema/dsl/field-defs.js.map +1 -0
- package/dist/schema/db-schema/dsl/field-defs.test.d.ts +2 -0
- package/dist/schema/db-schema/dsl/field-defs.test.d.ts.map +1 -0
- package/dist/schema/db-schema/dsl/field-defs.test.js +29 -0
- package/dist/schema/db-schema/dsl/field-defs.test.js.map +1 -0
- package/dist/schema/db-schema/dsl/mod.d.ts +90 -0
- package/dist/schema/db-schema/dsl/mod.d.ts.map +1 -0
- package/dist/schema/db-schema/dsl/mod.js +41 -0
- package/dist/schema/db-schema/dsl/mod.js.map +1 -0
- package/dist/schema/db-schema/hash.d.ts +2 -0
- package/dist/schema/db-schema/hash.d.ts.map +1 -0
- package/dist/schema/db-schema/hash.js +14 -0
- package/dist/schema/db-schema/hash.js.map +1 -0
- package/dist/schema/db-schema/mod.d.ts +3 -0
- package/dist/schema/db-schema/mod.d.ts.map +1 -0
- package/dist/schema/db-schema/mod.js +3 -0
- package/dist/schema/db-schema/mod.js.map +1 -0
- package/dist/schema/events.d.ts +2 -0
- package/dist/schema/events.d.ts.map +1 -0
- package/dist/schema/events.js +2 -0
- package/dist/schema/events.js.map +1 -0
- package/dist/schema/mod.d.ts +5 -3
- package/dist/schema/mod.d.ts.map +1 -1
- package/dist/schema/mod.js +5 -3
- package/dist/schema/mod.js.map +1 -1
- package/dist/schema/schema-helpers.d.ts.map +1 -1
- package/dist/schema/schema-helpers.js +1 -1
- package/dist/schema/schema-helpers.js.map +1 -1
- package/dist/schema/schema.d.ts +30 -23
- package/dist/schema/schema.d.ts.map +1 -1
- package/dist/schema/schema.js +48 -35
- package/dist/schema/schema.js.map +1 -1
- package/dist/schema/sqlite-state.d.ts +12 -0
- package/dist/schema/sqlite-state.d.ts.map +1 -0
- package/dist/schema/sqlite-state.js +36 -0
- package/dist/schema/sqlite-state.js.map +1 -0
- package/dist/schema/system-tables.d.ts +179 -125
- package/dist/schema/system-tables.d.ts.map +1 -1
- package/dist/schema/system-tables.js +76 -41
- package/dist/schema/system-tables.js.map +1 -1
- package/dist/schema/table-def.d.ts +37 -109
- package/dist/schema/table-def.d.ts.map +1 -1
- package/dist/schema/table-def.js +23 -66
- package/dist/schema/table-def.js.map +1 -1
- package/dist/schema/view.d.ts +3 -0
- package/dist/schema/view.d.ts.map +1 -0
- package/dist/schema/view.js +3 -0
- package/dist/schema/view.js.map +1 -0
- package/dist/schema-management/common.d.ts +7 -7
- package/dist/schema-management/common.d.ts.map +1 -1
- package/dist/schema-management/common.js.map +1 -1
- package/dist/schema-management/migrations.d.ts +6 -6
- package/dist/schema-management/migrations.d.ts.map +1 -1
- package/dist/schema-management/migrations.js +19 -14
- package/dist/schema-management/migrations.js.map +1 -1
- package/dist/schema-management/validate-mutation-defs.d.ts +3 -3
- package/dist/schema-management/validate-mutation-defs.d.ts.map +1 -1
- package/dist/schema-management/validate-mutation-defs.js +17 -17
- package/dist/schema-management/validate-mutation-defs.js.map +1 -1
- package/dist/sql-queries/misc.d.ts.map +1 -1
- package/dist/sql-queries/sql-queries.d.ts +1 -1
- package/dist/sql-queries/sql-queries.d.ts.map +1 -1
- package/dist/sql-queries/sql-queries.js.map +1 -1
- package/dist/sql-queries/sql-query-builder.d.ts +1 -1
- package/dist/sql-queries/sql-query-builder.d.ts.map +1 -1
- package/dist/sql-queries/sql-query-builder.js.map +1 -1
- package/dist/sql-queries/types.d.ts +2 -1
- package/dist/sql-queries/types.d.ts.map +1 -1
- package/dist/sql-queries/types.js.map +1 -1
- package/dist/sync/ClientSessionSyncProcessor.d.ts +66 -0
- package/dist/sync/ClientSessionSyncProcessor.d.ts.map +1 -0
- package/dist/sync/ClientSessionSyncProcessor.js +209 -0
- package/dist/sync/ClientSessionSyncProcessor.js.map +1 -0
- package/dist/sync/index.d.ts +1 -1
- package/dist/sync/index.d.ts.map +1 -1
- package/dist/sync/index.js +1 -1
- package/dist/sync/index.js.map +1 -1
- package/dist/sync/next/compact-events.d.ts.map +1 -1
- package/dist/sync/next/facts.d.ts +19 -19
- package/dist/sync/next/facts.d.ts.map +1 -1
- package/dist/sync/next/facts.js +3 -3
- package/dist/sync/next/facts.js.map +1 -1
- package/dist/sync/next/history-dag-common.d.ts +6 -7
- package/dist/sync/next/history-dag-common.d.ts.map +1 -1
- package/dist/sync/next/history-dag-common.js +4 -2
- 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 +2 -2
- package/dist/sync/next/history-dag.js.map +1 -1
- package/dist/sync/next/rebase-events.d.ts +10 -8
- package/dist/sync/next/rebase-events.d.ts.map +1 -1
- package/dist/sync/next/rebase-events.js +11 -8
- package/dist/sync/next/rebase-events.js.map +1 -1
- package/dist/sync/next/test/compact-events.calculator.test.js +38 -33
- package/dist/sync/next/test/compact-events.calculator.test.js.map +1 -1
- package/dist/sync/next/test/compact-events.test.js +76 -76
- package/dist/sync/next/test/compact-events.test.js.map +1 -1
- package/dist/sync/next/test/{mutation-fixtures.d.ts → event-fixtures.d.ts} +29 -29
- package/dist/sync/next/test/event-fixtures.d.ts.map +1 -0
- package/dist/sync/next/test/{mutation-fixtures.js → event-fixtures.js} +67 -36
- package/dist/sync/next/test/event-fixtures.js.map +1 -0
- package/dist/sync/next/test/mod.d.ts +1 -1
- package/dist/sync/next/test/mod.d.ts.map +1 -1
- package/dist/sync/next/test/mod.js +1 -1
- package/dist/sync/next/test/mod.js.map +1 -1
- package/dist/sync/sync.d.ts +55 -20
- package/dist/sync/sync.d.ts.map +1 -1
- package/dist/sync/sync.js +7 -3
- package/dist/sync/sync.js.map +1 -1
- package/dist/sync/syncstate.d.ts +213 -82
- package/dist/sync/syncstate.d.ts.map +1 -1
- package/dist/sync/syncstate.js +319 -120
- package/dist/sync/syncstate.js.map +1 -1
- package/dist/sync/syncstate.test.js +295 -275
- package/dist/sync/syncstate.test.js.map +1 -1
- package/dist/sync/validate-push-payload.d.ts +2 -2
- package/dist/sync/validate-push-payload.d.ts.map +1 -1
- package/dist/sync/validate-push-payload.js +2 -2
- package/dist/sync/validate-push-payload.js.map +1 -1
- package/dist/util.d.ts +2 -2
- package/dist/util.d.ts.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.d.ts.map +1 -1
- package/dist/version.js +1 -1
- package/dist/version.js.map +1 -1
- package/package.json +6 -6
- package/src/__tests__/fixture.ts +36 -15
- package/src/adapter-types.ts +111 -74
- package/src/debug-info.ts +1 -0
- package/src/devtools/devtools-messages-client-session.ts +141 -0
- package/src/devtools/devtools-messages-common.ts +115 -0
- package/src/devtools/devtools-messages-leader.ts +191 -0
- package/src/devtools/devtools-messages.ts +3 -243
- package/src/devtools/devtools-sessioninfo.ts +99 -0
- package/src/devtools/mod.ts +36 -0
- package/src/index.ts +4 -13
- package/src/leader-thread/LeaderSyncProcessor.ts +935 -0
- package/src/leader-thread/apply-event.ts +173 -0
- package/src/leader-thread/connection.ts +54 -9
- package/src/leader-thread/eventlog.ts +199 -0
- package/src/leader-thread/leader-worker-devtools.ts +212 -189
- package/src/leader-thread/make-leader-thread-layer.ts +143 -77
- package/src/leader-thread/mod.ts +1 -1
- package/src/leader-thread/recreate-db.ts +41 -30
- package/src/leader-thread/shutdown-channel.ts +2 -4
- package/src/leader-thread/types.ts +95 -51
- package/src/materializer-helper.ts +110 -0
- package/src/otel.ts +8 -0
- package/src/query-builder/api.ts +236 -85
- package/src/query-builder/astToSql.ts +232 -0
- package/src/query-builder/impl.test.ts +447 -78
- package/src/query-builder/impl.ts +209 -144
- package/src/query-builder/mod.ts +7 -0
- package/src/rehydrate-from-eventlog.ts +114 -0
- package/src/schema/EventDef.ts +216 -0
- package/src/schema/EventId.test.ts +12 -0
- package/src/schema/EventId.ts +75 -15
- package/src/schema/LiveStoreEvent.ts +239 -0
- package/src/schema/client-document-def.test.ts +239 -0
- package/src/schema/client-document-def.ts +444 -0
- package/src/schema/db-schema/ast/sqlite.ts +142 -0
- package/src/schema/db-schema/ast/validate.ts +13 -0
- package/src/schema/db-schema/dsl/__snapshots__/field-defs.test.ts.snap +206 -0
- package/src/schema/db-schema/dsl/field-defs.test.ts +35 -0
- package/src/schema/db-schema/dsl/field-defs.ts +242 -0
- package/src/schema/db-schema/dsl/mod.ts +222 -0
- package/src/schema/db-schema/hash.ts +14 -0
- package/src/schema/db-schema/mod.ts +2 -0
- package/src/schema/events.ts +1 -0
- package/src/schema/mod.ts +5 -3
- package/src/schema/schema-helpers.ts +1 -1
- package/src/schema/schema.ts +84 -62
- package/src/schema/sqlite-state.ts +62 -0
- package/src/schema/system-tables.ts +68 -50
- package/src/schema/table-def.ts +68 -214
- package/src/schema/view.ts +2 -0
- package/src/schema-management/common.ts +7 -7
- package/src/schema-management/migrations.ts +27 -24
- package/src/schema-management/validate-mutation-defs.ts +22 -24
- package/src/sql-queries/sql-queries.ts +1 -1
- package/src/sql-queries/sql-query-builder.ts +1 -2
- package/src/sql-queries/types.ts +3 -1
- package/src/sync/ClientSessionSyncProcessor.ts +332 -0
- package/src/sync/index.ts +1 -1
- package/src/sync/next/facts.ts +32 -33
- package/src/sync/next/history-dag-common.ts +9 -5
- package/src/sync/next/history-dag.ts +2 -2
- package/src/sync/next/rebase-events.ts +22 -16
- package/src/sync/next/test/compact-events.calculator.test.ts +45 -45
- package/src/sync/next/test/compact-events.test.ts +78 -78
- package/src/sync/next/test/event-fixtures.ts +219 -0
- package/src/sync/next/test/mod.ts +1 -1
- package/src/sync/sync.ts +51 -19
- package/src/sync/syncstate.test.ts +335 -308
- package/src/sync/syncstate.ts +394 -212
- package/src/sync/validate-push-payload.ts +7 -4
- package/src/version.ts +1 -1
- package/tmp/pack.tgz +0 -0
- package/tsconfig.json +2 -1
- package/dist/derived-mutations.d.ts +0 -109
- package/dist/derived-mutations.d.ts.map +0 -1
- package/dist/derived-mutations.js +0 -54
- package/dist/derived-mutations.js.map +0 -1
- package/dist/derived-mutations.test.d.ts +0 -2
- package/dist/derived-mutations.test.d.ts.map +0 -1
- package/dist/derived-mutations.test.js +0 -93
- package/dist/derived-mutations.test.js.map +0 -1
- package/dist/devtools/devtools-bridge.d.ts +0 -12
- package/dist/devtools/devtools-bridge.d.ts.map +0 -1
- package/dist/devtools/devtools-bridge.js +0 -2
- package/dist/devtools/devtools-bridge.js.map +0 -1
- package/dist/devtools/index.d.ts +0 -42
- package/dist/devtools/index.d.ts.map +0 -1
- package/dist/devtools/index.js +0 -48
- package/dist/devtools/index.js.map +0 -1
- package/dist/init-singleton-tables.d.ts +0 -4
- package/dist/init-singleton-tables.d.ts.map +0 -1
- package/dist/init-singleton-tables.js +0 -16
- package/dist/init-singleton-tables.js.map +0 -1
- package/dist/leader-thread/apply-mutation.d.ts +0 -8
- package/dist/leader-thread/apply-mutation.d.ts.map +0 -1
- package/dist/leader-thread/apply-mutation.js +0 -95
- package/dist/leader-thread/apply-mutation.js.map +0 -1
- package/dist/leader-thread/leader-sync-processor.d.ts +0 -47
- package/dist/leader-thread/leader-sync-processor.d.ts.map +0 -1
- package/dist/leader-thread/leader-sync-processor.js +0 -422
- package/dist/leader-thread/leader-sync-processor.js.map +0 -1
- package/dist/leader-thread/mutationlog.d.ts +0 -23
- package/dist/leader-thread/mutationlog.d.ts.map +0 -1
- package/dist/leader-thread/mutationlog.js +0 -27
- package/dist/leader-thread/mutationlog.js.map +0 -1
- package/dist/leader-thread/pull-queue-set.d.ts +0 -7
- package/dist/leader-thread/pull-queue-set.d.ts.map +0 -1
- package/dist/leader-thread/pull-queue-set.js +0 -39
- package/dist/leader-thread/pull-queue-set.js.map +0 -1
- package/dist/mutation.d.ts +0 -13
- package/dist/mutation.d.ts.map +0 -1
- package/dist/mutation.js +0 -57
- package/dist/mutation.js.map +0 -1
- package/dist/query-info.d.ts +0 -38
- package/dist/query-info.d.ts.map +0 -1
- package/dist/query-info.js +0 -7
- package/dist/query-info.js.map +0 -1
- package/dist/rehydrate-from-mutationlog.d.ts +0 -14
- package/dist/rehydrate-from-mutationlog.d.ts.map +0 -1
- package/dist/rehydrate-from-mutationlog.js +0 -72
- package/dist/rehydrate-from-mutationlog.js.map +0 -1
- package/dist/schema/MutationEvent.d.ts +0 -191
- package/dist/schema/MutationEvent.d.ts.map +0 -1
- package/dist/schema/MutationEvent.js +0 -56
- package/dist/schema/MutationEvent.js.map +0 -1
- package/dist/schema/mutations.d.ts +0 -107
- package/dist/schema/mutations.d.ts.map +0 -1
- package/dist/schema/mutations.js +0 -42
- package/dist/schema/mutations.js.map +0 -1
- package/dist/sync/client-session-sync-processor.d.ts +0 -45
- package/dist/sync/client-session-sync-processor.d.ts.map +0 -1
- package/dist/sync/client-session-sync-processor.js +0 -131
- package/dist/sync/client-session-sync-processor.js.map +0 -1
- package/dist/sync/next/test/mutation-fixtures.d.ts.map +0 -1
- package/dist/sync/next/test/mutation-fixtures.js.map +0 -1
- package/src/derived-mutations.test.ts +0 -101
- package/src/derived-mutations.ts +0 -166
- package/src/devtools/devtools-bridge.ts +0 -13
- package/src/devtools/index.ts +0 -48
- package/src/init-singleton-tables.ts +0 -24
- package/src/leader-thread/apply-mutation.ts +0 -143
- package/src/leader-thread/leader-sync-processor.ts +0 -666
- package/src/leader-thread/mutationlog.ts +0 -42
- package/src/leader-thread/pull-queue-set.ts +0 -58
- package/src/mutation.ts +0 -81
- package/src/query-info.ts +0 -78
- package/src/rehydrate-from-mutationlog.ts +0 -127
- package/src/schema/MutationEvent.ts +0 -161
- package/src/schema/mutations.ts +0 -192
- package/src/sync/client-session-sync-processor.ts +0 -207
- package/src/sync/next/test/mutation-fixtures.ts +0 -231
@@ -0,0 +1,173 @@
|
|
1
|
+
import { LS_DEV, shouldNeverHappen } from '@livestore/utils'
|
2
|
+
import { Effect, ReadonlyArray, Schema } from '@livestore/utils/effect'
|
3
|
+
|
4
|
+
import type { SqliteDb } from '../adapter-types.js'
|
5
|
+
import { getExecArgsFromEvent } from '../materializer-helper.js'
|
6
|
+
import type { LiveStoreSchema, SessionChangesetMetaRow } from '../schema/mod.js'
|
7
|
+
import {
|
8
|
+
EventId,
|
9
|
+
EVENTLOG_META_TABLE,
|
10
|
+
getEventDef,
|
11
|
+
SESSION_CHANGESET_META_TABLE,
|
12
|
+
sessionChangesetMetaTable,
|
13
|
+
} from '../schema/mod.js'
|
14
|
+
import { insertRow } from '../sql-queries/index.js'
|
15
|
+
import { sql } from '../util.js'
|
16
|
+
import { execSql, execSqlPrepared } from './connection.js'
|
17
|
+
import * as Eventlog from './eventlog.js'
|
18
|
+
import type { ApplyEvent } from './types.js'
|
19
|
+
|
20
|
+
export const makeApplyEvent = ({
|
21
|
+
schema,
|
22
|
+
dbReadModel: db,
|
23
|
+
dbEventlog,
|
24
|
+
}: {
|
25
|
+
schema: LiveStoreSchema
|
26
|
+
dbReadModel: SqliteDb
|
27
|
+
dbEventlog: SqliteDb
|
28
|
+
}): Effect.Effect<ApplyEvent, never> =>
|
29
|
+
Effect.gen(function* () {
|
30
|
+
const eventDefSchemaHashMap = new Map(
|
31
|
+
// TODO Running `Schema.hash` can be a bottleneck for larger schemas. There is an opportunity to run this
|
32
|
+
// at build time and lookup the pre-computed hash at runtime.
|
33
|
+
// Also see https://github.com/Effect-TS/effect/issues/2719
|
34
|
+
[...schema.eventsDefsMap.entries()].map(([k, v]) => [k, Schema.hash(v.schema)] as const),
|
35
|
+
)
|
36
|
+
|
37
|
+
return (eventEncoded, options) =>
|
38
|
+
Effect.gen(function* () {
|
39
|
+
const skipEventlog = options?.skipEventlog ?? false
|
40
|
+
|
41
|
+
const eventName = eventEncoded.name
|
42
|
+
const eventDef = getEventDef(schema, eventName)
|
43
|
+
|
44
|
+
const execArgsArr = getExecArgsFromEvent({
|
45
|
+
eventDef,
|
46
|
+
event: { decoded: undefined, encoded: eventEncoded },
|
47
|
+
})
|
48
|
+
|
49
|
+
// NOTE we might want to bring this back if we want to debug no-op events
|
50
|
+
// const makeExecuteOptions = (statementSql: string, bindValues: any) => ({
|
51
|
+
// onRowsChanged: (rowsChanged: number) => {
|
52
|
+
// if (rowsChanged === 0) {
|
53
|
+
// console.warn(`Event "${eventDef.name}" did not affect any rows:`, statementSql, bindValues)
|
54
|
+
// }
|
55
|
+
// },
|
56
|
+
// })
|
57
|
+
|
58
|
+
// console.group('[@livestore/common:leader-thread:applyEvent]', { eventName })
|
59
|
+
|
60
|
+
const session = db.session()
|
61
|
+
|
62
|
+
for (const { statementSql, bindValues } of execArgsArr) {
|
63
|
+
// console.debug(eventName, statementSql, bindValues)
|
64
|
+
// TODO use cached prepared statements instead of exec
|
65
|
+
yield* execSqlPrepared(db, statementSql, bindValues)
|
66
|
+
}
|
67
|
+
|
68
|
+
const changeset = session.changeset()
|
69
|
+
session.finish()
|
70
|
+
|
71
|
+
// TODO use prepared statements
|
72
|
+
yield* execSql(
|
73
|
+
db,
|
74
|
+
...insertRow({
|
75
|
+
tableName: SESSION_CHANGESET_META_TABLE,
|
76
|
+
columns: sessionChangesetMetaTable.sqliteDef.columns,
|
77
|
+
values: {
|
78
|
+
idGlobal: eventEncoded.id.global,
|
79
|
+
idClient: eventEncoded.id.client,
|
80
|
+
// NOTE the changeset will be empty (i.e. null) for no-op events
|
81
|
+
changeset: changeset ?? null,
|
82
|
+
debug: LS_DEV ? execArgsArr : null,
|
83
|
+
},
|
84
|
+
}),
|
85
|
+
)
|
86
|
+
|
87
|
+
// console.groupEnd()
|
88
|
+
|
89
|
+
// write to eventlog
|
90
|
+
if (skipEventlog === false) {
|
91
|
+
const eventName = eventEncoded.name
|
92
|
+
const eventDefSchemaHash =
|
93
|
+
eventDefSchemaHashMap.get(eventName) ?? shouldNeverHappen(`Unknown event definition: ${eventName}`)
|
94
|
+
|
95
|
+
yield* Eventlog.insertIntoEventlog(
|
96
|
+
eventEncoded,
|
97
|
+
dbEventlog,
|
98
|
+
eventDefSchemaHash,
|
99
|
+
eventEncoded.clientId,
|
100
|
+
eventEncoded.sessionId,
|
101
|
+
)
|
102
|
+
} else {
|
103
|
+
// console.debug('[@livestore/common:leader-thread] skipping eventlog write', mutation, statementSql, bindValues)
|
104
|
+
}
|
105
|
+
|
106
|
+
return {
|
107
|
+
sessionChangeset: changeset
|
108
|
+
? {
|
109
|
+
_tag: 'sessionChangeset' as const,
|
110
|
+
data: changeset,
|
111
|
+
debug: LS_DEV ? execArgsArr : null,
|
112
|
+
}
|
113
|
+
: { _tag: 'no-op' as const },
|
114
|
+
}
|
115
|
+
}).pipe(
|
116
|
+
Effect.withSpan(`@livestore/common:leader-thread:applyEvent`, {
|
117
|
+
attributes: {
|
118
|
+
eventName: eventEncoded.name,
|
119
|
+
mutationId: eventEncoded.id,
|
120
|
+
'span.label': `${EventId.toString(eventEncoded.id)} ${eventEncoded.name}`,
|
121
|
+
},
|
122
|
+
}),
|
123
|
+
// Effect.logDuration('@livestore/common:leader-thread:applyEvent'),
|
124
|
+
)
|
125
|
+
})
|
126
|
+
|
127
|
+
export const rollback = ({
|
128
|
+
db,
|
129
|
+
dbEventlog,
|
130
|
+
eventIdsToRollback,
|
131
|
+
}: {
|
132
|
+
db: SqliteDb
|
133
|
+
dbEventlog: SqliteDb
|
134
|
+
eventIdsToRollback: EventId.EventId[]
|
135
|
+
}) =>
|
136
|
+
Effect.gen(function* () {
|
137
|
+
const rollbackEvents = db
|
138
|
+
.select<SessionChangesetMetaRow>(
|
139
|
+
sql`SELECT * FROM ${SESSION_CHANGESET_META_TABLE} WHERE (idGlobal, idClient) IN (${eventIdsToRollback.map((id) => `(${id.global}, ${id.client})`).join(', ')})`,
|
140
|
+
)
|
141
|
+
.map((_) => ({ id: { global: _.idGlobal, client: _.idClient }, changeset: _.changeset, debug: _.debug }))
|
142
|
+
.toSorted((a, b) => EventId.compare(a.id, b.id))
|
143
|
+
|
144
|
+
// Apply changesets in reverse order
|
145
|
+
for (let i = rollbackEvents.length - 1; i >= 0; i--) {
|
146
|
+
const { changeset } = rollbackEvents[i]!
|
147
|
+
if (changeset !== null) {
|
148
|
+
db.makeChangeset(changeset).invert().apply()
|
149
|
+
}
|
150
|
+
}
|
151
|
+
|
152
|
+
const eventIdPairChunks = ReadonlyArray.chunksOf(100)(
|
153
|
+
eventIdsToRollback.map((id) => `(${id.global}, ${id.client})`),
|
154
|
+
)
|
155
|
+
|
156
|
+
// Delete the changeset rows
|
157
|
+
for (const eventIdPairChunk of eventIdPairChunks) {
|
158
|
+
db.execute(
|
159
|
+
sql`DELETE FROM ${SESSION_CHANGESET_META_TABLE} WHERE (idGlobal, idClient) IN (${eventIdPairChunk.join(', ')})`,
|
160
|
+
)
|
161
|
+
}
|
162
|
+
|
163
|
+
// Delete the eventlog rows
|
164
|
+
for (const eventIdPairChunk of eventIdPairChunks) {
|
165
|
+
dbEventlog.execute(
|
166
|
+
sql`DELETE FROM ${EVENTLOG_META_TABLE} WHERE (idGlobal, idClient) IN (${eventIdPairChunk.join(', ')})`,
|
167
|
+
)
|
168
|
+
}
|
169
|
+
}).pipe(
|
170
|
+
Effect.withSpan('@livestore/common:LeaderSyncProcessor:rollback', {
|
171
|
+
attributes: { count: eventIdsToRollback.length },
|
172
|
+
}),
|
173
|
+
)
|
@@ -1,7 +1,7 @@
|
|
1
1
|
// import type { WaSqlite } from '@livestore/sqlite-wasm'
|
2
2
|
import { Effect } from '@livestore/utils/effect'
|
3
3
|
|
4
|
-
import type {
|
4
|
+
import type { SqliteDb } from '../adapter-types.js'
|
5
5
|
import { SqliteError } from '../adapter-types.js'
|
6
6
|
import type { BindValues } from '../sql-queries/index.js'
|
7
7
|
import type { PreparedBindValues } from '../util.js'
|
@@ -12,21 +12,66 @@ namespace WaSqlite {
|
|
12
12
|
export type SQLiteError = any
|
13
13
|
}
|
14
14
|
|
15
|
-
|
15
|
+
type ConnectionOptions = {
|
16
|
+
/**
|
17
|
+
* The database connection locking mode.
|
18
|
+
*
|
19
|
+
* @remarks
|
20
|
+
*
|
21
|
+
* This **option is ignored** when used on an **in-memory database** as they can only operate in exclusive locking mode.
|
22
|
+
* In-memory databases can’t share state between connections (unless using a
|
23
|
+
* {@link https://www.sqlite.org/sharedcache.html#shared_cache_and_in_memory_databases|shared cache}),
|
24
|
+
* making concurrent access impossible. This is functionally equivalent to exclusive locking.
|
25
|
+
*
|
26
|
+
* @defaultValue
|
27
|
+
* The default is `"NORMAL"` unless it was unless overridden at compile-time using `SQLITE_DEFAULT_LOCKING_MODE`.
|
28
|
+
*
|
29
|
+
* @see {@link https://www.sqlite.org/pragma.html#pragma_locking_mode|`locking_mode` pragma}
|
30
|
+
*/
|
31
|
+
lockingMode?: 'NORMAL' | 'EXCLUSIVE'
|
32
|
+
|
33
|
+
/**
|
34
|
+
* Whether to enforce foreign key constraints.
|
35
|
+
*
|
36
|
+
* @privateRemarks
|
37
|
+
*
|
38
|
+
* We require a value for this option to minimize future problems, as the default value might change in future
|
39
|
+
* versions of SQLite.
|
40
|
+
*
|
41
|
+
* @see {@link https://www.sqlite.org/pragma.html#pragma_foreign_keys|`foreign_keys` pragma}
|
42
|
+
*/
|
43
|
+
foreignKeys: boolean
|
44
|
+
}
|
45
|
+
|
46
|
+
export const configureConnection = (sqliteDb: SqliteDb, { foreignKeys, lockingMode }: ConnectionOptions) =>
|
16
47
|
execSql(
|
17
|
-
|
48
|
+
sqliteDb,
|
49
|
+
// We use the WAL journal mode is significantly faster in most scenarios than the traditional rollback journal mode.
|
50
|
+
// It specifically significantly improves write performance. However, when using the WAL journal mode, transactions
|
51
|
+
// that involve changes against multiple ATTACHed databases are atomic for each database but are not atomic
|
52
|
+
// across all databases as a set. Additionally, it is not possible to change the page size after entering WAL mode,
|
53
|
+
// whether on an empty database or by using VACUUM or the backup API. To change the page size, we must switch to the
|
54
|
+
// rollback journal mode.
|
55
|
+
//
|
56
|
+
// When connected to an in-memory database, the WAL journal mode option is ignored because an in-memory database can
|
57
|
+
// only be in either the MEMORY or OFF options. By default, an in-memory database is in the MEMORY option, which
|
58
|
+
// means that it stores the rollback journal in volatile RAM. This saves disk I/O but at the expense of safety and
|
59
|
+
// integrity. If the thread using SQLite crashes in the middle of a transaction, then the database file will very
|
60
|
+
// likely go corrupt.
|
18
61
|
sql`
|
62
|
+
-- disable WAL until we have it working properly
|
63
|
+
-- PRAGMA journal_mode=WAL;
|
19
64
|
PRAGMA page_size=8192;
|
20
|
-
PRAGMA
|
21
|
-
${
|
65
|
+
PRAGMA foreign_keys=${foreignKeys ? 'ON' : 'OFF'};
|
66
|
+
${lockingMode === undefined ? '' : sql`PRAGMA locking_mode=${lockingMode};`}
|
22
67
|
`,
|
23
68
|
{},
|
24
69
|
)
|
25
70
|
|
26
|
-
export const execSql = (
|
71
|
+
export const execSql = (sqliteDb: SqliteDb, sql: string, bind: BindValues) => {
|
27
72
|
const bindValues = prepareBindValues(bind, sql)
|
28
73
|
return Effect.try({
|
29
|
-
try: () =>
|
74
|
+
try: () => sqliteDb.execute(sql, bindValues),
|
30
75
|
catch: (cause) =>
|
31
76
|
new SqliteError({ cause, query: { bindValues, sql }, code: (cause as WaSqlite.SQLiteError).code }),
|
32
77
|
}).pipe(
|
@@ -48,9 +93,9 @@ export const execSql = (syncDb: SynchronousDatabase, sql: string, bind: BindValu
|
|
48
93
|
// }
|
49
94
|
|
50
95
|
// TODO actually use prepared statements
|
51
|
-
export const execSqlPrepared = (
|
96
|
+
export const execSqlPrepared = (sqliteDb: SqliteDb, sql: string, bindValues: PreparedBindValues) => {
|
52
97
|
return Effect.try({
|
53
|
-
try: () =>
|
98
|
+
try: () => sqliteDb.execute(sql, bindValues),
|
54
99
|
catch: (cause) =>
|
55
100
|
new SqliteError({ cause, query: { bindValues, sql }, code: (cause as WaSqlite.SQLiteError).code }),
|
56
101
|
}).pipe(
|
@@ -0,0 +1,199 @@
|
|
1
|
+
import { LS_DEV, shouldNeverHappen } from '@livestore/utils'
|
2
|
+
import { Effect, Option, Schema } from '@livestore/utils/effect'
|
3
|
+
|
4
|
+
import type { SqliteDb } from '../adapter-types.js'
|
5
|
+
import * as EventId from '../schema/EventId.js'
|
6
|
+
import * as LiveStoreEvent from '../schema/LiveStoreEvent.js'
|
7
|
+
import {
|
8
|
+
EVENTLOG_META_TABLE,
|
9
|
+
eventlogMetaTable,
|
10
|
+
sessionChangesetMetaTable,
|
11
|
+
SYNC_STATUS_TABLE,
|
12
|
+
syncStatusTable,
|
13
|
+
} from '../schema/system-tables.js'
|
14
|
+
import { migrateTable } from '../schema-management/migrations.js'
|
15
|
+
import { insertRow, updateRows } from '../sql-queries/sql-queries.js'
|
16
|
+
import type { PreparedBindValues } from '../util.js'
|
17
|
+
import { prepareBindValues, sql } from '../util.js'
|
18
|
+
import { execSql } from './connection.js'
|
19
|
+
import type { InitialSyncInfo } from './types.js'
|
20
|
+
import { LeaderThreadCtx } from './types.js'
|
21
|
+
|
22
|
+
export const initEventlogDb = (dbEventlog: SqliteDb) =>
|
23
|
+
Effect.gen(function* () {
|
24
|
+
yield* migrateTable({
|
25
|
+
db: dbEventlog,
|
26
|
+
behaviour: 'create-if-not-exists',
|
27
|
+
tableAst: eventlogMetaTable.sqliteDef.ast,
|
28
|
+
skipMetaTable: true,
|
29
|
+
})
|
30
|
+
|
31
|
+
yield* migrateTable({
|
32
|
+
db: dbEventlog,
|
33
|
+
behaviour: 'create-if-not-exists',
|
34
|
+
tableAst: syncStatusTable.sqliteDef.ast,
|
35
|
+
skipMetaTable: true,
|
36
|
+
})
|
37
|
+
|
38
|
+
// Create sync status row if it doesn't exist
|
39
|
+
yield* execSql(
|
40
|
+
dbEventlog,
|
41
|
+
sql`INSERT INTO ${SYNC_STATUS_TABLE} (head)
|
42
|
+
SELECT ${EventId.ROOT.global}
|
43
|
+
WHERE NOT EXISTS (SELECT 1 FROM ${SYNC_STATUS_TABLE})`,
|
44
|
+
{},
|
45
|
+
)
|
46
|
+
})
|
47
|
+
|
48
|
+
/** Exclusive of the "since event" */
|
49
|
+
export const getEventsSince = (
|
50
|
+
since: EventId.EventId,
|
51
|
+
): Effect.Effect<ReadonlyArray<LiveStoreEvent.EncodedWithMeta>, never, LeaderThreadCtx> =>
|
52
|
+
Effect.gen(function* () {
|
53
|
+
const { dbEventlog, dbReadModel } = yield* LeaderThreadCtx
|
54
|
+
|
55
|
+
const query = eventlogMetaTable.where('idGlobal', '>=', since.global).asSql()
|
56
|
+
const pendingEventsRaw = dbEventlog.select(query.query, prepareBindValues(query.bindValues, query.query))
|
57
|
+
const pendingEvents = Schema.decodeUnknownSync(eventlogMetaTable.rowSchema.pipe(Schema.Array))(pendingEventsRaw)
|
58
|
+
|
59
|
+
const sessionChangesetRows = sessionChangesetMetaTable.where('idGlobal', '>=', since.global).asSql()
|
60
|
+
const sessionChangesetRowsRaw = dbReadModel.select(
|
61
|
+
sessionChangesetRows.query,
|
62
|
+
prepareBindValues(sessionChangesetRows.bindValues, sessionChangesetRows.query),
|
63
|
+
)
|
64
|
+
const sessionChangesetRowsDecoded = Schema.decodeUnknownSync(
|
65
|
+
sessionChangesetMetaTable.rowSchema.pipe(Schema.Array),
|
66
|
+
)(sessionChangesetRowsRaw)
|
67
|
+
|
68
|
+
return pendingEvents
|
69
|
+
.map((eventlogEvent) => {
|
70
|
+
const sessionChangeset = sessionChangesetRowsDecoded.find(
|
71
|
+
(readModelEvent) =>
|
72
|
+
readModelEvent.idGlobal === eventlogEvent.idGlobal && readModelEvent.idClient === eventlogEvent.idClient,
|
73
|
+
)
|
74
|
+
return LiveStoreEvent.EncodedWithMeta.make({
|
75
|
+
name: eventlogEvent.name,
|
76
|
+
args: eventlogEvent.argsJson,
|
77
|
+
id: { global: eventlogEvent.idGlobal, client: eventlogEvent.idClient },
|
78
|
+
parentId: { global: eventlogEvent.parentIdGlobal, client: eventlogEvent.parentIdClient },
|
79
|
+
clientId: eventlogEvent.clientId,
|
80
|
+
sessionId: eventlogEvent.sessionId,
|
81
|
+
meta: {
|
82
|
+
sessionChangeset:
|
83
|
+
sessionChangeset && sessionChangeset.changeset !== null
|
84
|
+
? {
|
85
|
+
_tag: 'sessionChangeset' as const,
|
86
|
+
data: sessionChangeset.changeset,
|
87
|
+
debug: sessionChangeset.debug,
|
88
|
+
}
|
89
|
+
: { _tag: 'unset' as const },
|
90
|
+
syncMetadata: eventlogEvent.syncMetadataJson,
|
91
|
+
},
|
92
|
+
})
|
93
|
+
})
|
94
|
+
.filter((_) => EventId.compare(_.id, since) > 0)
|
95
|
+
.sort((a, b) => EventId.compare(a.id, b.id))
|
96
|
+
})
|
97
|
+
|
98
|
+
export const getClientHeadFromDb = (dbEventlog: SqliteDb): EventId.EventId => {
|
99
|
+
const res = dbEventlog.select<{ idGlobal: EventId.GlobalEventId; idClient: EventId.ClientEventId }>(
|
100
|
+
sql`select idGlobal, idClient from ${EVENTLOG_META_TABLE} order by idGlobal DESC, idClient DESC limit 1`,
|
101
|
+
)[0]
|
102
|
+
|
103
|
+
return res ? { global: res.idGlobal, client: res.idClient } : EventId.ROOT
|
104
|
+
}
|
105
|
+
|
106
|
+
export const getBackendHeadFromDb = (dbEventlog: SqliteDb): EventId.GlobalEventId =>
|
107
|
+
dbEventlog.select<{ head: EventId.GlobalEventId }>(sql`select head from ${SYNC_STATUS_TABLE}`)[0]?.head ??
|
108
|
+
EventId.ROOT.global
|
109
|
+
|
110
|
+
// TODO use prepared statements
|
111
|
+
export const updateBackendHead = (dbEventlog: SqliteDb, head: EventId.EventId) =>
|
112
|
+
dbEventlog.execute(sql`UPDATE ${SYNC_STATUS_TABLE} SET head = ${head.global}`)
|
113
|
+
|
114
|
+
export const insertIntoEventlog = (
|
115
|
+
eventEncoded: LiveStoreEvent.EncodedWithMeta,
|
116
|
+
dbEventlog: SqliteDb,
|
117
|
+
eventDefSchemaHash: number,
|
118
|
+
clientId: string,
|
119
|
+
sessionId: string,
|
120
|
+
) =>
|
121
|
+
Effect.gen(function* () {
|
122
|
+
// Check history consistency during LS_DEV
|
123
|
+
if (LS_DEV && eventEncoded.parentId.global !== EventId.ROOT.global) {
|
124
|
+
const parentEventExists =
|
125
|
+
dbEventlog.select<{ count: number }>(
|
126
|
+
`SELECT COUNT(*) as count FROM ${EVENTLOG_META_TABLE} WHERE idGlobal = ? AND idClient = ?`,
|
127
|
+
[eventEncoded.parentId.global, eventEncoded.parentId.client] as any as PreparedBindValues,
|
128
|
+
)[0]!.count === 1
|
129
|
+
|
130
|
+
if (parentEventExists === false) {
|
131
|
+
shouldNeverHappen(
|
132
|
+
`Parent mutation ${eventEncoded.parentId.global},${eventEncoded.parentId.client} does not exist`,
|
133
|
+
)
|
134
|
+
}
|
135
|
+
}
|
136
|
+
|
137
|
+
// TODO use prepared statements
|
138
|
+
yield* execSql(
|
139
|
+
dbEventlog,
|
140
|
+
...insertRow({
|
141
|
+
tableName: EVENTLOG_META_TABLE,
|
142
|
+
columns: eventlogMetaTable.sqliteDef.columns,
|
143
|
+
values: {
|
144
|
+
idGlobal: eventEncoded.id.global,
|
145
|
+
idClient: eventEncoded.id.client,
|
146
|
+
parentIdGlobal: eventEncoded.parentId.global,
|
147
|
+
parentIdClient: eventEncoded.parentId.client,
|
148
|
+
name: eventEncoded.name,
|
149
|
+
argsJson: eventEncoded.args ?? {},
|
150
|
+
clientId,
|
151
|
+
sessionId,
|
152
|
+
schemaHash: eventDefSchemaHash,
|
153
|
+
syncMetadataJson: eventEncoded.meta.syncMetadata,
|
154
|
+
},
|
155
|
+
}),
|
156
|
+
)
|
157
|
+
})
|
158
|
+
|
159
|
+
export const updateSyncMetadata = (items: ReadonlyArray<LiveStoreEvent.EncodedWithMeta>) =>
|
160
|
+
Effect.gen(function* () {
|
161
|
+
const { dbEventlog } = yield* LeaderThreadCtx
|
162
|
+
|
163
|
+
// TODO try to do this in a single query
|
164
|
+
for (let i = 0; i < items.length; i++) {
|
165
|
+
const event = items[i]!
|
166
|
+
|
167
|
+
yield* execSql(
|
168
|
+
dbEventlog,
|
169
|
+
...updateRows({
|
170
|
+
tableName: EVENTLOG_META_TABLE,
|
171
|
+
columns: eventlogMetaTable.sqliteDef.columns,
|
172
|
+
where: { idGlobal: event.id.global, idClient: event.id.client },
|
173
|
+
updateValues: { syncMetadataJson: event.meta.syncMetadata },
|
174
|
+
}),
|
175
|
+
)
|
176
|
+
}
|
177
|
+
})
|
178
|
+
|
179
|
+
export const getSyncBackendCursorInfo = (remoteHead: EventId.GlobalEventId) =>
|
180
|
+
Effect.gen(function* () {
|
181
|
+
const { dbEventlog } = yield* LeaderThreadCtx
|
182
|
+
|
183
|
+
if (remoteHead === EventId.ROOT.global) return Option.none()
|
184
|
+
|
185
|
+
const EventlogQuerySchema = Schema.Struct({
|
186
|
+
syncMetadataJson: Schema.parseJson(Schema.Option(Schema.JsonValue)),
|
187
|
+
}).pipe(Schema.pluck('syncMetadataJson'), Schema.Array, Schema.head)
|
188
|
+
|
189
|
+
const syncMetadataOption = yield* Effect.sync(() =>
|
190
|
+
dbEventlog.select<{ syncMetadataJson: string }>(
|
191
|
+
sql`SELECT syncMetadataJson FROM ${EVENTLOG_META_TABLE} WHERE idGlobal = ${remoteHead} ORDER BY idClient ASC LIMIT 1`,
|
192
|
+
),
|
193
|
+
).pipe(Effect.andThen(Schema.decode(EventlogQuerySchema)), Effect.map(Option.flatten), Effect.orDie)
|
194
|
+
|
195
|
+
return Option.some({
|
196
|
+
cursor: { global: remoteHead, client: EventId.clientDefault },
|
197
|
+
metadata: syncMetadataOption,
|
198
|
+
}) satisfies InitialSyncInfo
|
199
|
+
}).pipe(Effect.withSpan('@livestore/common:eventlog:getSyncBackendCursorInfo', { attributes: { remoteHead } }))
|