@livestore/common 0.3.0-dev.4 → 0.3.0-dev.41
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 +132 -75
- 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 +390 -0
- package/dist/devtools/devtools-messages-client-session.d.ts.map +1 -0
- package/dist/devtools/devtools-messages-client-session.js +97 -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 +32 -0
- package/dist/devtools/devtools-sessioninfo.d.ts.map +1 -0
- package/dist/devtools/devtools-sessioninfo.js +36 -0
- package/dist/devtools/devtools-sessioninfo.js.map +1 -0
- package/dist/devtools/mod.d.ts +55 -0
- package/dist/devtools/mod.d.ts.map +1 -0
- package/dist/devtools/mod.js +33 -0
- package/dist/devtools/mod.js.map +1 -0
- package/dist/index.d.ts +7 -13
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -9
- 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 +593 -0
- package/dist/leader-thread/LeaderSyncProcessor.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 +119 -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 +165 -134
- 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 +76 -48
- package/dist/leader-thread/make-leader-thread-layer.js.map +1 -1
- package/dist/leader-thread/materialize-event.d.ts +16 -0
- package/dist/leader-thread/materialize-event.d.ts.map +1 -0
- package/dist/leader-thread/materialize-event.js +105 -0
- package/dist/leader-thread/materialize-event.js.map +1 -0
- 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 +33 -31
- 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 +89 -40
- 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/make-client-session.d.ts +21 -0
- package/dist/make-client-session.d.ts.map +1 -0
- package/dist/make-client-session.js +51 -0
- package/dist/make-client-session.js.map +1 -0
- package/dist/materializer-helper.d.ts +23 -0
- package/dist/materializer-helper.d.ts.map +1 -0
- package/dist/materializer-helper.js +84 -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/rematerialize-from-eventlog.d.ts +14 -0
- package/dist/rematerialize-from-eventlog.d.ts.map +1 -0
- package/dist/rematerialize-from-eventlog.js +64 -0
- package/dist/rematerialize-from-eventlog.js.map +1 -0
- package/dist/schema/EventDef.d.ts +146 -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/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 +7 -5
- package/dist/schema/mod.d.ts.map +1 -1
- package/dist/schema/mod.js +7 -5
- package/dist/schema/mod.js.map +1 -1
- package/dist/schema/schema.d.ts +48 -30
- package/dist/schema/schema.d.ts.map +1 -1
- package/dist/schema/schema.js +36 -43
- package/dist/schema/schema.js.map +1 -1
- package/dist/schema/state/mod.d.ts +3 -0
- package/dist/schema/state/mod.d.ts.map +1 -0
- package/dist/schema/state/mod.js +3 -0
- package/dist/schema/state/mod.js.map +1 -0
- package/dist/schema/state/sqlite/client-document-def.d.ts +223 -0
- package/dist/schema/state/sqlite/client-document-def.d.ts.map +1 -0
- package/dist/schema/state/sqlite/client-document-def.js +170 -0
- package/dist/schema/state/sqlite/client-document-def.js.map +1 -0
- package/dist/schema/state/sqlite/client-document-def.test.d.ts +2 -0
- package/dist/schema/state/sqlite/client-document-def.test.d.ts.map +1 -0
- package/dist/schema/state/sqlite/client-document-def.test.js +201 -0
- package/dist/schema/state/sqlite/client-document-def.test.js.map +1 -0
- package/dist/schema/state/sqlite/db-schema/ast/sqlite.d.ts +69 -0
- package/dist/schema/state/sqlite/db-schema/ast/sqlite.d.ts.map +1 -0
- package/dist/schema/state/sqlite/db-schema/ast/sqlite.js +71 -0
- package/dist/schema/state/sqlite/db-schema/ast/sqlite.js.map +1 -0
- package/dist/schema/state/sqlite/db-schema/ast/validate.d.ts +3 -0
- package/dist/schema/state/sqlite/db-schema/ast/validate.d.ts.map +1 -0
- package/dist/schema/state/sqlite/db-schema/ast/validate.js +12 -0
- package/dist/schema/state/sqlite/db-schema/ast/validate.js.map +1 -0
- package/dist/schema/state/sqlite/db-schema/dsl/field-defs.d.ts +90 -0
- package/dist/schema/state/sqlite/db-schema/dsl/field-defs.d.ts.map +1 -0
- package/dist/schema/state/sqlite/db-schema/dsl/field-defs.js +87 -0
- package/dist/schema/state/sqlite/db-schema/dsl/field-defs.js.map +1 -0
- package/dist/schema/state/sqlite/db-schema/dsl/field-defs.test.d.ts +2 -0
- package/dist/schema/state/sqlite/db-schema/dsl/field-defs.test.d.ts.map +1 -0
- package/dist/schema/state/sqlite/db-schema/dsl/field-defs.test.js +29 -0
- package/dist/schema/state/sqlite/db-schema/dsl/field-defs.test.js.map +1 -0
- package/dist/schema/state/sqlite/db-schema/dsl/mod.d.ts +90 -0
- package/dist/schema/state/sqlite/db-schema/dsl/mod.d.ts.map +1 -0
- package/dist/schema/state/sqlite/db-schema/dsl/mod.js +41 -0
- package/dist/schema/state/sqlite/db-schema/dsl/mod.js.map +1 -0
- package/dist/schema/state/sqlite/db-schema/hash.d.ts +2 -0
- package/dist/schema/state/sqlite/db-schema/hash.d.ts.map +1 -0
- package/dist/schema/state/sqlite/db-schema/hash.js +14 -0
- package/dist/schema/state/sqlite/db-schema/hash.js.map +1 -0
- package/dist/schema/state/sqlite/db-schema/mod.d.ts +3 -0
- package/dist/schema/state/sqlite/db-schema/mod.d.ts.map +1 -0
- package/dist/schema/state/sqlite/db-schema/mod.js +3 -0
- package/dist/schema/state/sqlite/db-schema/mod.js.map +1 -0
- package/dist/schema/state/sqlite/mod.d.ts +17 -0
- package/dist/schema/state/sqlite/mod.d.ts.map +1 -0
- package/dist/schema/state/sqlite/mod.js +41 -0
- package/dist/schema/state/sqlite/mod.js.map +1 -0
- package/dist/schema/state/sqlite/query-builder/api.d.ts +294 -0
- package/dist/schema/state/sqlite/query-builder/api.d.ts.map +1 -0
- package/dist/schema/state/sqlite/query-builder/api.js +6 -0
- package/dist/schema/state/sqlite/query-builder/api.js.map +1 -0
- package/dist/schema/state/sqlite/query-builder/astToSql.d.ts +7 -0
- package/dist/schema/state/sqlite/query-builder/astToSql.d.ts.map +1 -0
- package/dist/schema/state/sqlite/query-builder/astToSql.js +190 -0
- package/dist/schema/state/sqlite/query-builder/astToSql.js.map +1 -0
- package/dist/schema/state/sqlite/query-builder/impl.d.ts +7 -0
- package/dist/schema/state/sqlite/query-builder/impl.d.ts.map +1 -0
- package/dist/schema/state/sqlite/query-builder/impl.js +286 -0
- package/dist/schema/state/sqlite/query-builder/impl.js.map +1 -0
- package/dist/schema/state/sqlite/query-builder/impl.test.d.ts +87 -0
- package/dist/schema/state/sqlite/query-builder/impl.test.d.ts.map +1 -0
- package/dist/schema/state/sqlite/query-builder/impl.test.js +554 -0
- package/dist/schema/state/sqlite/query-builder/impl.test.js.map +1 -0
- package/dist/{query-builder → schema/state/sqlite/query-builder}/mod.d.ts +7 -0
- package/dist/schema/state/sqlite/query-builder/mod.d.ts.map +1 -0
- package/dist/{query-builder → schema/state/sqlite/query-builder}/mod.js +7 -0
- package/dist/schema/state/sqlite/query-builder/mod.js.map +1 -0
- package/dist/schema/state/sqlite/schema-helpers.d.ts.map +1 -0
- package/dist/schema/{schema-helpers.js → state/sqlite/schema-helpers.js} +1 -1
- package/dist/schema/state/sqlite/schema-helpers.js.map +1 -0
- package/dist/schema/state/sqlite/system-tables.d.ts +574 -0
- package/dist/schema/state/sqlite/system-tables.d.ts.map +1 -0
- package/dist/schema/state/sqlite/system-tables.js +87 -0
- package/dist/schema/state/sqlite/system-tables.js.map +1 -0
- package/dist/schema/state/sqlite/table-def.d.ts +84 -0
- package/dist/schema/state/sqlite/table-def.d.ts.map +1 -0
- package/dist/schema/state/sqlite/table-def.js +36 -0
- package/dist/schema/state/sqlite/table-def.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 +33 -24
- package/dist/schema-management/migrations.js.map +1 -1
- package/dist/schema-management/validate-schema.d.ts +8 -0
- package/dist/schema-management/validate-schema.d.ts.map +1 -0
- package/dist/schema-management/validate-schema.js +39 -0
- package/dist/schema-management/validate-schema.js.map +1 -0
- 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} +25 -25
- 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 +13 -6
- package/src/__tests__/fixture.ts +36 -15
- package/src/adapter-types.ts +116 -83
- package/src/debug-info.ts +1 -0
- package/src/devtools/devtools-messages-client-session.ts +142 -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 +101 -0
- package/src/devtools/mod.ts +59 -0
- package/src/index.ts +7 -15
- package/src/leader-thread/LeaderSyncProcessor.ts +933 -0
- package/src/leader-thread/connection.ts +54 -9
- package/src/leader-thread/eventlog.ts +194 -0
- package/src/leader-thread/leader-worker-devtools.ts +235 -191
- package/src/leader-thread/make-leader-thread-layer.ts +138 -78
- package/src/leader-thread/materialize-event.ts +169 -0
- package/src/leader-thread/mod.ts +1 -1
- package/src/leader-thread/recreate-db.ts +38 -39
- package/src/leader-thread/shutdown-channel.ts +2 -4
- package/src/leader-thread/types.ts +98 -53
- package/src/make-client-session.ts +119 -0
- package/src/materializer-helper.ts +135 -0
- package/src/otel.ts +8 -0
- package/src/rematerialize-from-eventlog.ts +117 -0
- package/src/schema/EventDef.ts +227 -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/events.ts +1 -0
- package/src/schema/mod.ts +7 -5
- package/src/schema/schema.ts +85 -81
- package/src/schema/state/mod.ts +2 -0
- package/src/schema/state/sqlite/client-document-def.test.ts +238 -0
- package/src/schema/state/sqlite/client-document-def.ts +444 -0
- package/src/schema/state/sqlite/db-schema/ast/sqlite.ts +142 -0
- package/src/schema/state/sqlite/db-schema/ast/validate.ts +13 -0
- package/src/schema/state/sqlite/db-schema/dsl/__snapshots__/field-defs.test.ts.snap +206 -0
- package/src/schema/state/sqlite/db-schema/dsl/field-defs.test.ts +35 -0
- package/src/schema/state/sqlite/db-schema/dsl/field-defs.ts +242 -0
- package/src/schema/state/sqlite/db-schema/dsl/mod.ts +222 -0
- package/src/schema/state/sqlite/db-schema/hash.ts +14 -0
- package/src/schema/state/sqlite/db-schema/mod.ts +2 -0
- package/src/schema/state/sqlite/mod.ts +73 -0
- package/src/schema/state/sqlite/query-builder/api.ts +440 -0
- package/src/schema/state/sqlite/query-builder/astToSql.ts +232 -0
- package/src/schema/state/sqlite/query-builder/impl.test.ts +608 -0
- package/src/schema/state/sqlite/query-builder/impl.ts +350 -0
- package/src/{query-builder → schema/state/sqlite/query-builder}/mod.ts +7 -0
- package/src/schema/{schema-helpers.ts → state/sqlite/schema-helpers.ts} +1 -1
- package/src/schema/state/sqlite/system-tables.ts +116 -0
- package/src/schema/state/sqlite/table-def.ts +197 -0
- package/src/schema-management/common.ts +7 -7
- package/src/schema-management/migrations.ts +43 -37
- package/src/schema-management/validate-schema.ts +61 -0
- 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/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/devtools-window-message.d.ts +0 -29
- package/dist/devtools/devtools-window-message.d.ts.map +0 -1
- package/dist/devtools/devtools-window-message.js +0 -33
- package/dist/devtools/devtools-window-message.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-builder/api.d.ts +0 -190
- package/dist/query-builder/api.d.ts.map +0 -1
- package/dist/query-builder/api.js +0 -8
- package/dist/query-builder/api.js.map +0 -1
- package/dist/query-builder/impl.d.ts +0 -12
- package/dist/query-builder/impl.d.ts.map +0 -1
- package/dist/query-builder/impl.js +0 -244
- package/dist/query-builder/impl.js.map +0 -1
- package/dist/query-builder/impl.test.d.ts +0 -2
- package/dist/query-builder/impl.test.d.ts.map +0 -1
- package/dist/query-builder/impl.test.js +0 -212
- package/dist/query-builder/impl.test.js.map +0 -1
- package/dist/query-builder/mod.d.ts.map +0 -1
- package/dist/query-builder/mod.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/schema/schema-helpers.d.ts.map +0 -1
- package/dist/schema/schema-helpers.js.map +0 -1
- package/dist/schema/system-tables.d.ts +0 -399
- package/dist/schema/system-tables.d.ts.map +0 -1
- package/dist/schema/system-tables.js +0 -51
- package/dist/schema/system-tables.js.map +0 -1
- package/dist/schema/table-def.d.ts +0 -156
- package/dist/schema/table-def.d.ts.map +0 -1
- package/dist/schema/table-def.js +0 -79
- package/dist/schema/table-def.js.map +0 -1
- package/dist/schema-management/validate-mutation-defs.d.ts +0 -8
- package/dist/schema-management/validate-mutation-defs.d.ts.map +0 -1
- package/dist/schema-management/validate-mutation-defs.js +0 -39
- package/dist/schema-management/validate-mutation-defs.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/devtools-window-message.ts +0 -27
- 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-builder/api.ts +0 -289
- package/src/query-builder/impl.test.ts +0 -239
- package/src/query-builder/impl.ts +0 -285
- 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/schema/system-tables.ts +0 -97
- package/src/schema/table-def.ts +0 -343
- package/src/schema-management/validate-mutation-defs.ts +0 -63
- package/src/sync/client-session-sync-processor.ts +0 -207
- package/src/sync/next/test/mutation-fixtures.ts +0 -231
- package/tsconfig.json +0 -11
- /package/dist/schema/{schema-helpers.d.ts → state/sqlite/schema-helpers.d.ts} +0 -0
@@ -0,0 +1,350 @@
|
|
1
|
+
import { casesHandled, shouldNeverHappen } from '@livestore/utils'
|
2
|
+
import { Match, Option, Predicate, Schema } from '@livestore/utils/effect'
|
3
|
+
|
4
|
+
import type { TableDefBase } from '../table-def.js'
|
5
|
+
import type { QueryBuilder, QueryBuilderAst } from './api.js'
|
6
|
+
import { QueryBuilderAstSymbol, QueryBuilderTypeId } from './api.js'
|
7
|
+
import { astToSql } from './astToSql.js'
|
8
|
+
export const makeQueryBuilder = <TResult, TTableDef extends TableDefBase>(
|
9
|
+
tableDef: TTableDef,
|
10
|
+
ast: QueryBuilderAst = emptyAst(tableDef),
|
11
|
+
): QueryBuilder<TResult, TTableDef, never> => {
|
12
|
+
const api = {
|
13
|
+
// eslint-disable-next-line prefer-arrow/prefer-arrow-functions
|
14
|
+
select() {
|
15
|
+
assertSelectQueryBuilderAst(ast)
|
16
|
+
|
17
|
+
// eslint-disable-next-line prefer-rest-params
|
18
|
+
const params = [...arguments]
|
19
|
+
|
20
|
+
// Pluck if there's only one column selected
|
21
|
+
if (params.length === 1) {
|
22
|
+
const [col] = params as any as [string]
|
23
|
+
return makeQueryBuilder(tableDef, {
|
24
|
+
...ast,
|
25
|
+
resultSchemaSingle: ast.resultSchemaSingle.pipe(Schema.pluck(col)),
|
26
|
+
select: { columns: [col] },
|
27
|
+
})
|
28
|
+
}
|
29
|
+
|
30
|
+
const columns = params as unknown as ReadonlyArray<string>
|
31
|
+
|
32
|
+
return makeQueryBuilder(tableDef, {
|
33
|
+
...ast,
|
34
|
+
resultSchemaSingle:
|
35
|
+
columns.length === 0 ? ast.resultSchemaSingle : ast.resultSchemaSingle.pipe(Schema.pick(...columns)),
|
36
|
+
select: { columns },
|
37
|
+
}) as any
|
38
|
+
},
|
39
|
+
// eslint-disable-next-line prefer-arrow/prefer-arrow-functions
|
40
|
+
where: function () {
|
41
|
+
if (ast._tag === 'InsertQuery') return invalidQueryBuilder('Cannot use where with insert')
|
42
|
+
if (ast._tag === 'RowQuery') return invalidQueryBuilder('Cannot use where with row')
|
43
|
+
|
44
|
+
if (arguments.length === 1) {
|
45
|
+
// eslint-disable-next-line prefer-rest-params
|
46
|
+
const params = arguments[0]
|
47
|
+
const newOps = Object.entries(params)
|
48
|
+
.filter(([, value]) => value !== undefined)
|
49
|
+
.map<QueryBuilderAst.Where>(([col, value]) =>
|
50
|
+
Predicate.hasProperty(value, 'op') && Predicate.hasProperty(value, 'value')
|
51
|
+
? ({ col, op: value.op, value: value.value } as any)
|
52
|
+
: { col, op: '=', value },
|
53
|
+
)
|
54
|
+
|
55
|
+
switch (ast._tag) {
|
56
|
+
case 'CountQuery':
|
57
|
+
case 'SelectQuery':
|
58
|
+
case 'UpdateQuery':
|
59
|
+
case 'DeleteQuery': {
|
60
|
+
return makeQueryBuilder(tableDef, {
|
61
|
+
...ast,
|
62
|
+
where: [...ast.where, ...newOps],
|
63
|
+
}) as any
|
64
|
+
}
|
65
|
+
default: {
|
66
|
+
return casesHandled(ast)
|
67
|
+
}
|
68
|
+
}
|
69
|
+
}
|
70
|
+
|
71
|
+
// eslint-disable-next-line prefer-rest-params
|
72
|
+
const [col, opOrValue, valueOrUndefined] = arguments
|
73
|
+
const op = valueOrUndefined === undefined ? '=' : opOrValue
|
74
|
+
const value = valueOrUndefined === undefined ? opOrValue : valueOrUndefined
|
75
|
+
|
76
|
+
switch (ast._tag) {
|
77
|
+
case 'CountQuery':
|
78
|
+
case 'SelectQuery':
|
79
|
+
case 'UpdateQuery':
|
80
|
+
case 'DeleteQuery': {
|
81
|
+
return makeQueryBuilder(tableDef, {
|
82
|
+
...ast,
|
83
|
+
where: [...ast.where, { col, op, value }],
|
84
|
+
}) as any
|
85
|
+
}
|
86
|
+
default: {
|
87
|
+
return casesHandled(ast)
|
88
|
+
}
|
89
|
+
}
|
90
|
+
},
|
91
|
+
// eslint-disable-next-line prefer-arrow/prefer-arrow-functions
|
92
|
+
orderBy() {
|
93
|
+
assertSelectQueryBuilderAst(ast)
|
94
|
+
|
95
|
+
if (arguments.length === 0 || arguments.length > 2) return invalidQueryBuilder()
|
96
|
+
|
97
|
+
if (arguments.length === 1) {
|
98
|
+
// eslint-disable-next-line prefer-rest-params
|
99
|
+
const params = arguments[0] as QueryBuilder.OrderByParams<TTableDef>
|
100
|
+
return makeQueryBuilder(tableDef, {
|
101
|
+
...ast,
|
102
|
+
orderBy: [...ast.orderBy, ...params],
|
103
|
+
})
|
104
|
+
}
|
105
|
+
|
106
|
+
// eslint-disable-next-line prefer-rest-params
|
107
|
+
const [col, direction] = arguments as any as [keyof TTableDef['sqliteDef']['columns'] & string, 'asc' | 'desc']
|
108
|
+
|
109
|
+
return makeQueryBuilder(tableDef, {
|
110
|
+
...ast,
|
111
|
+
orderBy: [...ast.orderBy, { col, direction }],
|
112
|
+
}) as any
|
113
|
+
},
|
114
|
+
limit: (limit) => {
|
115
|
+
assertSelectQueryBuilderAst(ast)
|
116
|
+
|
117
|
+
return makeQueryBuilder(tableDef, { ...ast, limit: Option.some(limit) })
|
118
|
+
},
|
119
|
+
offset: (offset) => {
|
120
|
+
assertSelectQueryBuilderAst(ast)
|
121
|
+
|
122
|
+
return makeQueryBuilder(tableDef, { ...ast, offset: Option.some(offset) })
|
123
|
+
},
|
124
|
+
count: () => {
|
125
|
+
if (isRowQuery(ast)) return invalidQueryBuilder()
|
126
|
+
|
127
|
+
return makeQueryBuilder(tableDef, {
|
128
|
+
_tag: 'CountQuery',
|
129
|
+
tableDef,
|
130
|
+
where: [],
|
131
|
+
resultSchema: Schema.Struct({ count: Schema.Number }).pipe(
|
132
|
+
Schema.pluck('count'),
|
133
|
+
Schema.Array,
|
134
|
+
Schema.headOrElse(),
|
135
|
+
),
|
136
|
+
})
|
137
|
+
},
|
138
|
+
first: (options) => {
|
139
|
+
assertSelectQueryBuilderAst(ast)
|
140
|
+
|
141
|
+
if (ast.limit._tag === 'Some') return invalidQueryBuilder(`.first() can't be called after .limit()`)
|
142
|
+
|
143
|
+
return makeQueryBuilder(tableDef, {
|
144
|
+
...ast,
|
145
|
+
limit: Option.some(1),
|
146
|
+
pickFirst:
|
147
|
+
options?.fallback !== undefined && options.fallback !== 'throws' ? { fallback: options.fallback } : 'throws',
|
148
|
+
})
|
149
|
+
},
|
150
|
+
// // eslint-disable-next-line prefer-arrow/prefer-arrow-functions
|
151
|
+
// getOrCreate() {
|
152
|
+
// if (tableDef.options.isClientDocumentTable === false) {
|
153
|
+
// return invalidQueryBuilder(`getOrCreate() is not allowed when table is not a client document table`)
|
154
|
+
// }
|
155
|
+
|
156
|
+
// // eslint-disable-next-line prefer-rest-params
|
157
|
+
// const params = [...arguments]
|
158
|
+
|
159
|
+
// let id: string | number
|
160
|
+
|
161
|
+
// // TODO refactor to handle default id
|
162
|
+
// id = params[0] as string | number
|
163
|
+
// if (id === undefined) {
|
164
|
+
// invalidQueryBuilder(`Id missing for row query on non-singleton table ${tableDef.sqliteDef.name}`)
|
165
|
+
// }
|
166
|
+
|
167
|
+
// // TODO validate all required columns are present and values are matching the schema
|
168
|
+
// const insertValues: Record<string, unknown> = params[1]?.insertValues ?? {}
|
169
|
+
|
170
|
+
// return makeQueryBuilder(tableDef, {
|
171
|
+
// _tag: 'RowQuery',
|
172
|
+
// id,
|
173
|
+
// tableDef,
|
174
|
+
// insertValues,
|
175
|
+
// }) as any
|
176
|
+
// },
|
177
|
+
insert: (values) => {
|
178
|
+
const filteredValues = Object.fromEntries(Object.entries(values).filter(([, value]) => value !== undefined))
|
179
|
+
|
180
|
+
return makeQueryBuilder(tableDef, {
|
181
|
+
_tag: 'InsertQuery',
|
182
|
+
tableDef,
|
183
|
+
values: filteredValues,
|
184
|
+
onConflict: undefined,
|
185
|
+
returning: undefined,
|
186
|
+
resultSchema: Schema.Void,
|
187
|
+
}) as any
|
188
|
+
},
|
189
|
+
onConflict: (
|
190
|
+
targetOrTargets: string | string[],
|
191
|
+
action: 'ignore' | 'replace' | 'update',
|
192
|
+
updateValues?: Record<string, unknown>,
|
193
|
+
) => {
|
194
|
+
const targets = Array.isArray(targetOrTargets) ? targetOrTargets : [targetOrTargets]
|
195
|
+
|
196
|
+
assertInsertQueryBuilderAst(ast)
|
197
|
+
|
198
|
+
const onConflict = Match.value(action).pipe(
|
199
|
+
Match.when('ignore', () => ({ targets, action: { _tag: 'ignore' } }) satisfies QueryBuilderAst.OnConflict),
|
200
|
+
Match.when('replace', () => ({ targets, action: { _tag: 'replace' } }) satisfies QueryBuilderAst.OnConflict),
|
201
|
+
Match.when(
|
202
|
+
'update',
|
203
|
+
() => ({ targets, action: { _tag: 'update', update: updateValues! } }) satisfies QueryBuilderAst.OnConflict,
|
204
|
+
),
|
205
|
+
Match.exhaustive,
|
206
|
+
)
|
207
|
+
|
208
|
+
return makeQueryBuilder(tableDef, {
|
209
|
+
...ast,
|
210
|
+
onConflict,
|
211
|
+
}) as any
|
212
|
+
},
|
213
|
+
|
214
|
+
returning: (...columns) => {
|
215
|
+
assertWriteQueryBuilderAst(ast)
|
216
|
+
|
217
|
+
return makeQueryBuilder(tableDef, {
|
218
|
+
...ast,
|
219
|
+
returning: columns,
|
220
|
+
resultSchema: tableDef.rowSchema.pipe(Schema.pick(...columns), Schema.Array),
|
221
|
+
}) as any
|
222
|
+
},
|
223
|
+
|
224
|
+
update: (values) => {
|
225
|
+
const filteredValues = Object.fromEntries(Object.entries(values).filter(([, value]) => value !== undefined))
|
226
|
+
|
227
|
+
return makeQueryBuilder(tableDef, {
|
228
|
+
_tag: 'UpdateQuery',
|
229
|
+
tableDef,
|
230
|
+
values: filteredValues,
|
231
|
+
where: [],
|
232
|
+
returning: undefined,
|
233
|
+
resultSchema: Schema.Void,
|
234
|
+
}) as any
|
235
|
+
},
|
236
|
+
|
237
|
+
delete: () => {
|
238
|
+
return makeQueryBuilder(tableDef, {
|
239
|
+
_tag: 'DeleteQuery',
|
240
|
+
tableDef,
|
241
|
+
where: [],
|
242
|
+
returning: undefined,
|
243
|
+
resultSchema: Schema.Void,
|
244
|
+
}) as any
|
245
|
+
},
|
246
|
+
} satisfies QueryBuilder.ApiFull<TResult, TTableDef, never>
|
247
|
+
|
248
|
+
return {
|
249
|
+
[QueryBuilderTypeId]: QueryBuilderTypeId,
|
250
|
+
[QueryBuilderAstSymbol]: ast,
|
251
|
+
['ResultType']: 'only-for-type-inference' as TResult,
|
252
|
+
asSql: () => astToSql(ast),
|
253
|
+
toString: () => {
|
254
|
+
try {
|
255
|
+
return astToSql(ast).query
|
256
|
+
} catch (cause) {
|
257
|
+
console.debug(`QueryBuilder.toString(): Error converting query builder to string`, cause, ast)
|
258
|
+
return `Error converting query builder to string`
|
259
|
+
}
|
260
|
+
},
|
261
|
+
...api,
|
262
|
+
} satisfies QueryBuilder<TResult, TTableDef>
|
263
|
+
}
|
264
|
+
|
265
|
+
const emptyAst = (tableDef: TableDefBase): QueryBuilderAst.SelectQuery => ({
|
266
|
+
_tag: 'SelectQuery',
|
267
|
+
columns: [],
|
268
|
+
pickFirst: false,
|
269
|
+
select: { columns: [] },
|
270
|
+
orderBy: [],
|
271
|
+
offset: Option.none(),
|
272
|
+
limit: Option.none(),
|
273
|
+
tableDef,
|
274
|
+
where: [],
|
275
|
+
resultSchemaSingle: tableDef.rowSchema,
|
276
|
+
})
|
277
|
+
|
278
|
+
// Helper functions
|
279
|
+
// eslint-disable-next-line prefer-arrow/prefer-arrow-functions
|
280
|
+
function assertSelectQueryBuilderAst(ast: QueryBuilderAst): asserts ast is QueryBuilderAst.SelectQuery {
|
281
|
+
if (ast._tag !== 'SelectQuery') {
|
282
|
+
return shouldNeverHappen('Expected SelectQuery but got ' + ast._tag)
|
283
|
+
}
|
284
|
+
}
|
285
|
+
|
286
|
+
// eslint-disable-next-line prefer-arrow/prefer-arrow-functions
|
287
|
+
function assertInsertQueryBuilderAst(ast: QueryBuilderAst): asserts ast is QueryBuilderAst.InsertQuery {
|
288
|
+
if (ast._tag !== 'InsertQuery') {
|
289
|
+
return shouldNeverHappen('Expected InsertQuery but got ' + ast._tag)
|
290
|
+
}
|
291
|
+
}
|
292
|
+
|
293
|
+
// eslint-disable-next-line prefer-arrow/prefer-arrow-functions
|
294
|
+
function assertWriteQueryBuilderAst(ast: QueryBuilderAst): asserts ast is QueryBuilderAst.WriteQuery {
|
295
|
+
if (ast._tag !== 'InsertQuery' && ast._tag !== 'UpdateQuery' && ast._tag !== 'DeleteQuery') {
|
296
|
+
return shouldNeverHappen('Expected WriteQuery but got ' + ast._tag)
|
297
|
+
}
|
298
|
+
}
|
299
|
+
|
300
|
+
const isRowQuery = (ast: QueryBuilderAst): ast is QueryBuilderAst.RowQuery => ast._tag === 'RowQuery'
|
301
|
+
|
302
|
+
export const invalidQueryBuilder = (msg?: string) => {
|
303
|
+
return shouldNeverHappen('Invalid query builder' + (msg ? `: ${msg}` : ''))
|
304
|
+
}
|
305
|
+
|
306
|
+
export const getResultSchema = (qb: QueryBuilder<any, any, any>): Schema.Schema<any> => {
|
307
|
+
const queryAst = qb[QueryBuilderAstSymbol]
|
308
|
+
switch (queryAst._tag) {
|
309
|
+
case 'SelectQuery': {
|
310
|
+
const arraySchema = Schema.Array(queryAst.resultSchemaSingle)
|
311
|
+
if (queryAst.pickFirst === false) {
|
312
|
+
return arraySchema
|
313
|
+
} else if (queryAst.pickFirst === 'throws') {
|
314
|
+
// Will throw if the array is empty
|
315
|
+
return arraySchema.pipe(Schema.headOrElse())
|
316
|
+
} else {
|
317
|
+
const fallbackValue = queryAst.pickFirst.fallback()
|
318
|
+
return Schema.Union(arraySchema, Schema.Tuple(Schema.Literal(fallbackValue))).pipe(
|
319
|
+
Schema.headOrElse(() => fallbackValue),
|
320
|
+
)
|
321
|
+
}
|
322
|
+
}
|
323
|
+
case 'CountQuery': {
|
324
|
+
return Schema.Struct({ count: Schema.Number }).pipe(Schema.pluck('count'), Schema.Array, Schema.headOrElse())
|
325
|
+
}
|
326
|
+
case 'InsertQuery':
|
327
|
+
case 'UpdateQuery':
|
328
|
+
case 'DeleteQuery': {
|
329
|
+
// For write operations with RETURNING clause, we need to return the appropriate schema
|
330
|
+
if (queryAst.returning && queryAst.returning.length > 0) {
|
331
|
+
// Create a schema for the returned columns
|
332
|
+
return queryAst.tableDef.rowSchema.pipe(Schema.pick(...queryAst.returning), Schema.Array)
|
333
|
+
}
|
334
|
+
|
335
|
+
// For write operations without RETURNING, the result is the number of affected rows
|
336
|
+
return Schema.Number
|
337
|
+
}
|
338
|
+
case 'RowQuery': {
|
339
|
+
return queryAst.tableDef.rowSchema.pipe(
|
340
|
+
Schema.pluck('value'),
|
341
|
+
Schema.annotations({ title: `${queryAst.tableDef.sqliteDef.name}.value` }),
|
342
|
+
Schema.Array,
|
343
|
+
Schema.headOrElse(),
|
344
|
+
)
|
345
|
+
}
|
346
|
+
default: {
|
347
|
+
casesHandled(queryAst)
|
348
|
+
}
|
349
|
+
}
|
350
|
+
}
|
@@ -7,4 +7,11 @@ export * from './impl.js'
|
|
7
7
|
* - Close abstraction to SQLite to provide a simple & convenient API with predictable behaviour
|
8
8
|
* - Use table schema definitions to parse, map & validate query results
|
9
9
|
* - Implementation detail: Separate type-level & AST-based runtime implementation
|
10
|
+
*
|
11
|
+
* Currently not supported (not exhaustive list):
|
12
|
+
* - Assumes a `id` column as primary key
|
13
|
+
* - Composite primary keys
|
14
|
+
*
|
15
|
+
* Other known limitations
|
16
|
+
* - Doesn't exclude all invalid query patterns on type level `e.g. `db.todos.returning('id')`
|
10
17
|
*/
|
@@ -1,7 +1,7 @@
|
|
1
|
-
import { SqliteDsl } from '@livestore/db-schema'
|
2
1
|
import { shouldNeverHappen } from '@livestore/utils'
|
3
2
|
import { pipe, ReadonlyRecord, Schema } from '@livestore/utils/effect'
|
4
3
|
|
4
|
+
import { SqliteDsl } from './db-schema/mod.js'
|
5
5
|
import type { TableDef, TableDefBase } from './table-def.js'
|
6
6
|
|
7
7
|
export const getDefaultValuesEncoded = <TTableDef extends TableDef>(
|
@@ -0,0 +1,116 @@
|
|
1
|
+
import { Schema } from '@livestore/utils/effect'
|
2
|
+
|
3
|
+
import * as EventId from '../../EventId.js'
|
4
|
+
import { SqliteDsl } from './db-schema/mod.js'
|
5
|
+
import { table } from './table-def.js'
|
6
|
+
|
7
|
+
/// Read model DB
|
8
|
+
|
9
|
+
export const SCHEMA_META_TABLE = '__livestore_schema'
|
10
|
+
|
11
|
+
export const schemaMetaTable = table({
|
12
|
+
name: SCHEMA_META_TABLE,
|
13
|
+
columns: {
|
14
|
+
tableName: SqliteDsl.text({ primaryKey: true }),
|
15
|
+
schemaHash: SqliteDsl.integer({ nullable: false }),
|
16
|
+
/** ISO date format */
|
17
|
+
updatedAt: SqliteDsl.text({ nullable: false }),
|
18
|
+
},
|
19
|
+
})
|
20
|
+
|
21
|
+
export type SchemaMetaRow = typeof schemaMetaTable.Type
|
22
|
+
|
23
|
+
export const SCHEMA_EVENT_DEFS_META_TABLE = '__livestore_schema_event_defs'
|
24
|
+
|
25
|
+
export const schemaEventDefsMetaTable = table({
|
26
|
+
name: SCHEMA_EVENT_DEFS_META_TABLE,
|
27
|
+
columns: {
|
28
|
+
eventName: SqliteDsl.text({ primaryKey: true }),
|
29
|
+
schemaHash: SqliteDsl.integer({ nullable: false }),
|
30
|
+
/** ISO date format */
|
31
|
+
updatedAt: SqliteDsl.text({ nullable: false }),
|
32
|
+
},
|
33
|
+
})
|
34
|
+
|
35
|
+
export type SchemaEventDefsMetaRow = typeof schemaEventDefsMetaTable.Type
|
36
|
+
|
37
|
+
/**
|
38
|
+
* Table which stores SQLite changeset blobs which is used for rolling back
|
39
|
+
* read-model state during rebasing.
|
40
|
+
*/
|
41
|
+
export const SESSION_CHANGESET_META_TABLE = '__livestore_session_changeset'
|
42
|
+
|
43
|
+
export const sessionChangesetMetaTable = table({
|
44
|
+
name: SESSION_CHANGESET_META_TABLE,
|
45
|
+
columns: {
|
46
|
+
// TODO bring back primary key
|
47
|
+
idGlobal: SqliteDsl.integer({ schema: EventId.GlobalEventId }),
|
48
|
+
idClient: SqliteDsl.integer({ schema: EventId.ClientEventId }),
|
49
|
+
changeset: SqliteDsl.blob({ nullable: true }),
|
50
|
+
debug: SqliteDsl.json({ nullable: true }),
|
51
|
+
},
|
52
|
+
indexes: [{ columns: ['idGlobal', 'idClient'], name: 'idx_session_changeset_id' }],
|
53
|
+
})
|
54
|
+
|
55
|
+
export type SessionChangesetMetaRow = typeof sessionChangesetMetaTable.Type
|
56
|
+
|
57
|
+
export const LEADER_MERGE_COUNTER_TABLE = '__livestore_leader_merge_counter'
|
58
|
+
|
59
|
+
export const leaderMergeCounterTable = table({
|
60
|
+
name: LEADER_MERGE_COUNTER_TABLE,
|
61
|
+
columns: {
|
62
|
+
id: SqliteDsl.integer({ primaryKey: true, schema: Schema.Literal(0) }),
|
63
|
+
mergeCounter: SqliteDsl.integer({ primaryKey: true }),
|
64
|
+
},
|
65
|
+
})
|
66
|
+
|
67
|
+
export type LeaderMergeCounterRow = typeof leaderMergeCounterTable.Type
|
68
|
+
|
69
|
+
export const stateSystemTables = [
|
70
|
+
schemaMetaTable,
|
71
|
+
schemaEventDefsMetaTable,
|
72
|
+
sessionChangesetMetaTable,
|
73
|
+
leaderMergeCounterTable,
|
74
|
+
]
|
75
|
+
|
76
|
+
export const isStateSystemTable = (tableName: string) => stateSystemTables.some((_) => _.sqliteDef.name === tableName)
|
77
|
+
|
78
|
+
/// Eventlog DB
|
79
|
+
|
80
|
+
export const EVENTLOG_META_TABLE = 'eventlog'
|
81
|
+
|
82
|
+
export const eventlogMetaTable = table({
|
83
|
+
name: EVENTLOG_META_TABLE,
|
84
|
+
columns: {
|
85
|
+
// TODO Adjust modeling so a global event never needs a client id component
|
86
|
+
idGlobal: SqliteDsl.integer({ primaryKey: true, schema: EventId.GlobalEventId }),
|
87
|
+
idClient: SqliteDsl.integer({ primaryKey: true, schema: EventId.ClientEventId }),
|
88
|
+
parentIdGlobal: SqliteDsl.integer({ schema: EventId.GlobalEventId }),
|
89
|
+
parentIdClient: SqliteDsl.integer({ schema: EventId.ClientEventId }),
|
90
|
+
name: SqliteDsl.text({}),
|
91
|
+
argsJson: SqliteDsl.text({ schema: Schema.parseJson(Schema.Any) }),
|
92
|
+
clientId: SqliteDsl.text({}),
|
93
|
+
sessionId: SqliteDsl.text({}),
|
94
|
+
schemaHash: SqliteDsl.integer({}),
|
95
|
+
syncMetadataJson: SqliteDsl.text({ schema: Schema.parseJson(Schema.Option(Schema.JsonValue)) }),
|
96
|
+
},
|
97
|
+
indexes: [
|
98
|
+
{ columns: ['idGlobal'], name: 'idx_eventlog_idGlobal' },
|
99
|
+
{ columns: ['idGlobal', 'idClient'], name: 'idx_eventlog_id' },
|
100
|
+
],
|
101
|
+
})
|
102
|
+
|
103
|
+
export type EventlogMetaRow = typeof eventlogMetaTable.Type
|
104
|
+
|
105
|
+
export const SYNC_STATUS_TABLE = '__livestore_sync_status'
|
106
|
+
|
107
|
+
export const syncStatusTable = table({
|
108
|
+
name: SYNC_STATUS_TABLE,
|
109
|
+
columns: {
|
110
|
+
head: SqliteDsl.integer({ primaryKey: true }),
|
111
|
+
},
|
112
|
+
})
|
113
|
+
|
114
|
+
export type SyncStatusRow = typeof syncStatusTable.Type
|
115
|
+
|
116
|
+
export const eventlogSystemTables = [eventlogMetaTable, syncStatusTable]
|
@@ -0,0 +1,197 @@
|
|
1
|
+
import { type Nullable } from '@livestore/utils'
|
2
|
+
import type { Schema, Types } from '@livestore/utils/effect'
|
3
|
+
|
4
|
+
import { SqliteDsl } from './db-schema/mod.js'
|
5
|
+
import type { QueryBuilder } from './query-builder/mod.js'
|
6
|
+
import { makeQueryBuilder, QueryBuilderAstSymbol, QueryBuilderTypeId } from './query-builder/mod.js'
|
7
|
+
|
8
|
+
export const { blob, boolean, column, datetime, integer, isColumnDefinition, json, real, text } = SqliteDsl
|
9
|
+
|
10
|
+
export type StateType = 'singleton' | 'dynamic'
|
11
|
+
|
12
|
+
export type DefaultSqliteTableDef = SqliteDsl.TableDefinition<string, SqliteDsl.Columns>
|
13
|
+
export type DefaultSqliteTableDefConstrained = SqliteDsl.TableDefinition<string, SqliteDsl.ConstraintColumns>
|
14
|
+
|
15
|
+
// TODO use to hide table def internals
|
16
|
+
export const TableDefInternalsSymbol = Symbol('TableDefInternals')
|
17
|
+
export type TableDefInternalsSymbol = typeof TableDefInternalsSymbol
|
18
|
+
|
19
|
+
export type TableDefBase<
|
20
|
+
TSqliteDef extends DefaultSqliteTableDef = DefaultSqliteTableDefConstrained,
|
21
|
+
TOptions extends TableOptions = TableOptions,
|
22
|
+
> = {
|
23
|
+
sqliteDef: TSqliteDef
|
24
|
+
options: TOptions
|
25
|
+
// Derived from `sqliteDef`, so only exposed for convenience
|
26
|
+
rowSchema: SqliteDsl.StructSchemaForColumns<TSqliteDef['columns']>
|
27
|
+
insertSchema: SqliteDsl.InsertStructSchemaForColumns<TSqliteDef['columns']>
|
28
|
+
}
|
29
|
+
|
30
|
+
export type TableDef<
|
31
|
+
TSqliteDef extends DefaultSqliteTableDef = DefaultSqliteTableDefConstrained,
|
32
|
+
TOptions extends TableOptions = TableOptions,
|
33
|
+
// NOTE we're not using `SqliteDsl.StructSchemaForColumns<TSqliteDef['columns']>`
|
34
|
+
// as we don't want the alias type for users to show up, so we're redefining it here
|
35
|
+
TSchema = Schema.Schema<
|
36
|
+
SqliteDsl.AnyIfConstained<
|
37
|
+
TSqliteDef['columns'],
|
38
|
+
{ readonly [K in keyof TSqliteDef['columns']]: TSqliteDef['columns'][K]['schema']['Type'] }
|
39
|
+
>,
|
40
|
+
SqliteDsl.AnyIfConstained<
|
41
|
+
TSqliteDef['columns'],
|
42
|
+
{ readonly [K in keyof TSqliteDef['columns']]: TSqliteDef['columns'][K]['schema']['Encoded'] }
|
43
|
+
>
|
44
|
+
>,
|
45
|
+
> = {
|
46
|
+
sqliteDef: TSqliteDef
|
47
|
+
options: TOptions
|
48
|
+
// Derived from `sqliteDef`, so only exposed for convenience
|
49
|
+
rowSchema: TSchema
|
50
|
+
insertSchema: SqliteDsl.InsertStructSchemaForColumns<TSqliteDef['columns']>
|
51
|
+
// query: QueryBuilder<ReadonlyArray<Schema.Schema.Type<TSchema>>, TableDefBase<TSqliteDef & {}, TOptions>>
|
52
|
+
readonly Type: Schema.Schema.Type<TSchema>
|
53
|
+
readonly Encoded: Schema.Schema.Encoded<TSchema>
|
54
|
+
} & QueryBuilder<ReadonlyArray<Schema.Schema.Type<TSchema>>, TableDefBase<TSqliteDef & {}, TOptions>>
|
55
|
+
|
56
|
+
export type TableOptionsInput = Partial<{
|
57
|
+
indexes: SqliteDsl.Index[]
|
58
|
+
}>
|
59
|
+
|
60
|
+
export namespace TableDef {
|
61
|
+
export type Any = TableDef<any, any>
|
62
|
+
}
|
63
|
+
|
64
|
+
export type TableOptions = {
|
65
|
+
/** Derived based on whether the table definition has one or more columns (besides the `id` column) */
|
66
|
+
readonly isClientDocumentTable: boolean
|
67
|
+
}
|
68
|
+
|
69
|
+
export const table = <
|
70
|
+
TName extends string,
|
71
|
+
TColumns extends SqliteDsl.Columns | SqliteDsl.ColumnDefinition<any, any>,
|
72
|
+
const TOptionsInput extends TableOptionsInput = TableOptionsInput,
|
73
|
+
>(
|
74
|
+
args: {
|
75
|
+
name: TName
|
76
|
+
columns: TColumns
|
77
|
+
} & Partial<TOptionsInput>,
|
78
|
+
): TableDef<SqliteTableDefForInput<TName, TColumns>, WithDefaults<TColumns>> => {
|
79
|
+
const { name, columns: columnOrColumns, ...options } = args
|
80
|
+
const tablePath = name
|
81
|
+
|
82
|
+
const options_: TableOptions = {
|
83
|
+
isClientDocumentTable: false,
|
84
|
+
}
|
85
|
+
|
86
|
+
const columns = (
|
87
|
+
SqliteDsl.isColumnDefinition(columnOrColumns) ? { value: columnOrColumns } : columnOrColumns
|
88
|
+
) as SqliteDsl.Columns
|
89
|
+
|
90
|
+
const sqliteDef = SqliteDsl.table(tablePath, columns, options?.indexes ?? [])
|
91
|
+
|
92
|
+
const rowSchema = SqliteDsl.structSchemaForTable(sqliteDef)
|
93
|
+
const insertSchema = SqliteDsl.insertStructSchemaForTable(sqliteDef)
|
94
|
+
const tableDef = {
|
95
|
+
sqliteDef,
|
96
|
+
options: options_,
|
97
|
+
rowSchema,
|
98
|
+
insertSchema,
|
99
|
+
} satisfies TableDefBase
|
100
|
+
|
101
|
+
const query = makeQueryBuilder(tableDef)
|
102
|
+
// tableDef.query = query
|
103
|
+
|
104
|
+
// NOTE we're currently patching the existing tableDef object
|
105
|
+
// as it's being used as part of the query builder API
|
106
|
+
for (const key of Object.keys(query)) {
|
107
|
+
// @ts-expect-error TODO properly implement this
|
108
|
+
tableDef[key] = query[key]
|
109
|
+
}
|
110
|
+
|
111
|
+
// @ts-expect-error TODO properly type this
|
112
|
+
tableDef[QueryBuilderAstSymbol] = query[QueryBuilderAstSymbol]
|
113
|
+
// @ts-expect-error TODO properly type this
|
114
|
+
tableDef[QueryBuilderTypeId] = query[QueryBuilderTypeId]
|
115
|
+
|
116
|
+
return tableDef as any
|
117
|
+
}
|
118
|
+
|
119
|
+
export namespace FromTable {
|
120
|
+
// TODO this sometimes doesn't preserve the order of columns
|
121
|
+
export type RowDecoded<TTableDef extends TableDefBase> = Types.Simplify<
|
122
|
+
Nullable<Pick<RowDecodedAll<TTableDef>, NullableColumnNames<TTableDef>>> &
|
123
|
+
Omit<RowDecodedAll<TTableDef>, NullableColumnNames<TTableDef>>
|
124
|
+
>
|
125
|
+
|
126
|
+
export type NullableColumnNames<TTableDef extends TableDefBase> = FromColumns.NullableColumnNames<
|
127
|
+
TTableDef['sqliteDef']['columns']
|
128
|
+
>
|
129
|
+
|
130
|
+
export type Columns<TTableDef extends TableDefBase> = {
|
131
|
+
[K in keyof TTableDef['sqliteDef']['columns']]: TTableDef['sqliteDef']['columns'][K]['columnType']
|
132
|
+
}
|
133
|
+
|
134
|
+
export type RowEncodeNonNullable<TTableDef extends TableDefBase> = {
|
135
|
+
[K in keyof TTableDef['sqliteDef']['columns']]: Schema.Schema.Encoded<
|
136
|
+
TTableDef['sqliteDef']['columns'][K]['schema']
|
137
|
+
>
|
138
|
+
}
|
139
|
+
|
140
|
+
export type RowEncoded<TTableDef extends TableDefBase> = Types.Simplify<
|
141
|
+
Nullable<Pick<RowEncodeNonNullable<TTableDef>, NullableColumnNames<TTableDef>>> &
|
142
|
+
Omit<RowEncodeNonNullable<TTableDef>, NullableColumnNames<TTableDef>>
|
143
|
+
>
|
144
|
+
|
145
|
+
export type RowDecodedAll<TTableDef extends TableDefBase> = {
|
146
|
+
[K in keyof TTableDef['sqliteDef']['columns']]: Schema.Schema.Type<TTableDef['sqliteDef']['columns'][K]['schema']>
|
147
|
+
}
|
148
|
+
}
|
149
|
+
|
150
|
+
export namespace FromColumns {
|
151
|
+
// TODO this sometimes doesn't preserve the order of columns
|
152
|
+
export type RowDecoded<TColumns extends SqliteDsl.Columns> = Types.Simplify<
|
153
|
+
Nullable<Pick<RowDecodedAll<TColumns>, NullableColumnNames<TColumns>>> &
|
154
|
+
Omit<RowDecodedAll<TColumns>, NullableColumnNames<TColumns>>
|
155
|
+
>
|
156
|
+
|
157
|
+
export type RowDecodedAll<TColumns extends SqliteDsl.Columns> = {
|
158
|
+
[K in keyof TColumns]: Schema.Schema.Type<TColumns[K]['schema']>
|
159
|
+
}
|
160
|
+
|
161
|
+
export type RowEncoded<TColumns extends SqliteDsl.Columns> = Types.Simplify<
|
162
|
+
Nullable<Pick<RowEncodeNonNullable<TColumns>, NullableColumnNames<TColumns>>> &
|
163
|
+
Omit<RowEncodeNonNullable<TColumns>, NullableColumnNames<TColumns>>
|
164
|
+
>
|
165
|
+
|
166
|
+
export type RowEncodeNonNullable<TColumns extends SqliteDsl.Columns> = {
|
167
|
+
[K in keyof TColumns]: Schema.Schema.Encoded<TColumns[K]['schema']>
|
168
|
+
}
|
169
|
+
|
170
|
+
export type NullableColumnNames<TColumns extends SqliteDsl.Columns> = keyof {
|
171
|
+
[K in keyof TColumns as TColumns[K]['default'] extends true ? K : never]: {}
|
172
|
+
}
|
173
|
+
|
174
|
+
export type RequiredInsertColumnNames<TColumns extends SqliteDsl.Columns> =
|
175
|
+
SqliteDsl.FromColumns.RequiredInsertColumnNames<TColumns>
|
176
|
+
|
177
|
+
export type InsertRowDecoded<TColumns extends SqliteDsl.Columns> = SqliteDsl.FromColumns.InsertRowDecoded<TColumns>
|
178
|
+
}
|
179
|
+
|
180
|
+
type SqliteTableDefForInput<
|
181
|
+
TName extends string,
|
182
|
+
TColumns extends SqliteDsl.Columns | SqliteDsl.ColumnDefinition<any, any>,
|
183
|
+
> = SqliteDsl.TableDefinition<TName, PrettifyFlat<ToColumns<TColumns>>>
|
184
|
+
|
185
|
+
type WithDefaults<TColumns extends SqliteDsl.Columns | SqliteDsl.ColumnDefinition<any, any>> = {
|
186
|
+
isClientDocumentTable: false
|
187
|
+
requiredInsertColumnNames: SqliteDsl.FromColumns.RequiredInsertColumnNames<ToColumns<TColumns>>
|
188
|
+
}
|
189
|
+
|
190
|
+
export type PrettifyFlat<T> = T extends infer U ? { [K in keyof U]: U[K] } : never
|
191
|
+
|
192
|
+
type ToColumns<TColumns extends SqliteDsl.Columns | SqliteDsl.ColumnDefinition<any, any>> =
|
193
|
+
TColumns extends SqliteDsl.Columns
|
194
|
+
? TColumns
|
195
|
+
: TColumns extends SqliteDsl.ColumnDefinition<any, any>
|
196
|
+
? { value: TColumns }
|
197
|
+
: never
|