@livestore/common 0.4.0-dev.8 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/.tsbuildinfo +1 -1
- package/dist/ClientSessionLeaderThreadProxy.d.ts +27 -12
- package/dist/ClientSessionLeaderThreadProxy.d.ts.map +1 -1
- package/dist/ClientSessionLeaderThreadProxy.js.map +1 -1
- package/dist/WorkerTransportError.d.ts +11 -0
- package/dist/WorkerTransportError.d.ts.map +1 -0
- package/dist/WorkerTransportError.js +11 -0
- package/dist/WorkerTransportError.js.map +1 -0
- package/dist/adapter-types.d.ts +37 -7
- package/dist/adapter-types.d.ts.map +1 -1
- package/dist/adapter-types.js +27 -1
- package/dist/adapter-types.js.map +1 -1
- package/dist/bounded-collections.d.ts.map +1 -1
- package/dist/bounded-collections.js +6 -4
- package/dist/bounded-collections.js.map +1 -1
- package/dist/debug-info.d.ts.map +1 -1
- package/dist/debug-info.js +33 -6
- package/dist/debug-info.js.map +1 -1
- package/dist/devtools/devtools-compatibility.test.d.ts +2 -0
- package/dist/devtools/devtools-compatibility.test.d.ts.map +1 -0
- package/dist/devtools/devtools-compatibility.test.js +15 -0
- package/dist/devtools/devtools-compatibility.test.js.map +1 -0
- package/dist/devtools/devtools-messages-client-session.d.ts +55 -24
- package/dist/devtools/devtools-messages-client-session.d.ts.map +1 -1
- package/dist/devtools/devtools-messages-client-session.js +22 -5
- package/dist/devtools/devtools-messages-client-session.js.map +1 -1
- package/dist/devtools/devtools-messages-common.d.ts +11 -14
- package/dist/devtools/devtools-messages-common.d.ts.map +1 -1
- package/dist/devtools/devtools-messages-common.js +7 -9
- package/dist/devtools/devtools-messages-common.js.map +1 -1
- package/dist/devtools/devtools-messages-leader.d.ts +65 -30
- package/dist/devtools/devtools-messages-leader.d.ts.map +1 -1
- package/dist/devtools/devtools-messages-leader.js +29 -11
- package/dist/devtools/devtools-messages-leader.js.map +1 -1
- package/dist/devtools/devtools-sessioninfo.d.ts +14 -2
- package/dist/devtools/devtools-sessioninfo.d.ts.map +1 -1
- package/dist/devtools/devtools-sessioninfo.js +7 -4
- package/dist/devtools/devtools-sessioninfo.js.map +1 -1
- package/dist/devtools/mod.d.ts +13 -2
- package/dist/devtools/mod.d.ts.map +1 -1
- package/dist/devtools/mod.js +10 -3
- package/dist/devtools/mod.js.map +1 -1
- package/dist/errors.d.ts +48 -18
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +20 -12
- package/dist/errors.js.map +1 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -1
- package/dist/leader-thread/LeaderSyncProcessor.d.ts +53 -6
- package/dist/leader-thread/LeaderSyncProcessor.d.ts.map +1 -1
- package/dist/leader-thread/LeaderSyncProcessor.js +325 -257
- package/dist/leader-thread/LeaderSyncProcessor.js.map +1 -1
- package/dist/leader-thread/RejectedPushError.d.ts +107 -0
- package/dist/leader-thread/RejectedPushError.d.ts.map +1 -0
- package/dist/leader-thread/RejectedPushError.js +78 -0
- package/dist/leader-thread/RejectedPushError.js.map +1 -0
- package/dist/leader-thread/connection.js +1 -1
- package/dist/leader-thread/connection.js.map +1 -1
- package/dist/leader-thread/eventlog.d.ts +19 -14
- package/dist/leader-thread/eventlog.d.ts.map +1 -1
- package/dist/leader-thread/eventlog.js +78 -18
- package/dist/leader-thread/eventlog.js.map +1 -1
- package/dist/leader-thread/leader-worker-devtools.d.ts +1 -2
- package/dist/leader-thread/leader-worker-devtools.d.ts.map +1 -1
- package/dist/leader-thread/leader-worker-devtools.js +90 -58
- package/dist/leader-thread/leader-worker-devtools.js.map +1 -1
- package/dist/leader-thread/make-leader-thread-layer.d.ts +15 -7
- package/dist/leader-thread/make-leader-thread-layer.d.ts.map +1 -1
- package/dist/leader-thread/make-leader-thread-layer.js +49 -17
- package/dist/leader-thread/make-leader-thread-layer.js.map +1 -1
- package/dist/leader-thread/make-leader-thread-layer.test.d.ts +2 -0
- package/dist/leader-thread/make-leader-thread-layer.test.d.ts.map +1 -0
- package/dist/leader-thread/make-leader-thread-layer.test.js +32 -0
- package/dist/leader-thread/make-leader-thread-layer.test.js.map +1 -0
- package/dist/leader-thread/materialize-event.d.ts +1 -1
- package/dist/leader-thread/materialize-event.d.ts.map +1 -1
- package/dist/leader-thread/materialize-event.js +28 -9
- package/dist/leader-thread/materialize-event.js.map +1 -1
- package/dist/leader-thread/mod.d.ts +1 -0
- package/dist/leader-thread/mod.d.ts.map +1 -1
- package/dist/leader-thread/mod.js +1 -0
- package/dist/leader-thread/mod.js.map +1 -1
- package/dist/leader-thread/recreate-db.d.ts +2 -2
- package/dist/leader-thread/recreate-db.d.ts.map +1 -1
- package/dist/leader-thread/recreate-db.js +6 -6
- package/dist/leader-thread/recreate-db.js.map +1 -1
- package/dist/leader-thread/shutdown-channel.d.ts +2 -2
- package/dist/leader-thread/shutdown-channel.d.ts.map +1 -1
- package/dist/leader-thread/shutdown-channel.js +2 -2
- package/dist/leader-thread/shutdown-channel.js.map +1 -1
- package/dist/leader-thread/stream-events.d.ts +56 -0
- package/dist/leader-thread/stream-events.d.ts.map +1 -0
- package/dist/leader-thread/stream-events.js +167 -0
- package/dist/leader-thread/stream-events.js.map +1 -0
- package/dist/leader-thread/types.d.ts +95 -17
- package/dist/leader-thread/types.d.ts.map +1 -1
- package/dist/leader-thread/types.js +13 -0
- package/dist/leader-thread/types.js.map +1 -1
- package/dist/logging.d.ts +40 -0
- package/dist/logging.d.ts.map +1 -0
- package/dist/logging.js +33 -0
- package/dist/logging.js.map +1 -0
- package/dist/make-client-session.d.ts +5 -3
- package/dist/make-client-session.d.ts.map +1 -1
- package/dist/make-client-session.js +7 -4
- package/dist/make-client-session.js.map +1 -1
- package/dist/materializer-helper.d.ts +6 -6
- package/dist/materializer-helper.d.ts.map +1 -1
- package/dist/materializer-helper.js +18 -8
- package/dist/materializer-helper.js.map +1 -1
- package/dist/otel.d.ts +2 -1
- package/dist/otel.d.ts.map +1 -1
- package/dist/otel.js +7 -2
- package/dist/otel.js.map +1 -1
- package/dist/rematerialize-from-eventlog.d.ts +3 -3
- package/dist/rematerialize-from-eventlog.d.ts.map +1 -1
- package/dist/rematerialize-from-eventlog.js +40 -29
- package/dist/rematerialize-from-eventlog.js.map +1 -1
- package/dist/schema/EventDef/define.d.ts +161 -0
- package/dist/schema/EventDef/define.d.ts.map +1 -0
- package/dist/schema/EventDef/define.js +140 -0
- package/dist/schema/EventDef/define.js.map +1 -0
- package/dist/schema/EventDef/deprecated.d.ts +99 -0
- package/dist/schema/EventDef/deprecated.d.ts.map +1 -0
- package/dist/schema/EventDef/deprecated.js +144 -0
- package/dist/schema/EventDef/deprecated.js.map +1 -0
- package/dist/schema/EventDef/deprecated.test.d.ts +2 -0
- package/dist/schema/EventDef/deprecated.test.d.ts.map +1 -0
- package/dist/schema/EventDef/deprecated.test.js +95 -0
- package/dist/schema/EventDef/deprecated.test.js.map +1 -0
- package/dist/schema/EventDef/event-def.d.ts +110 -0
- package/dist/schema/EventDef/event-def.d.ts.map +1 -0
- package/dist/schema/EventDef/event-def.js +2 -0
- package/dist/schema/EventDef/event-def.js.map +1 -0
- package/dist/schema/EventDef/facts.d.ts +118 -0
- package/dist/schema/EventDef/facts.d.ts.map +1 -0
- package/dist/schema/EventDef/facts.js +53 -0
- package/dist/schema/EventDef/facts.js.map +1 -0
- package/dist/schema/EventDef/materializer.d.ts +155 -0
- package/dist/schema/EventDef/materializer.d.ts.map +1 -0
- package/dist/schema/EventDef/materializer.js +83 -0
- package/dist/schema/EventDef/materializer.js.map +1 -0
- package/dist/schema/EventDef/mod.d.ts +6 -0
- package/dist/schema/EventDef/mod.d.ts.map +1 -0
- package/dist/schema/EventDef/mod.js +6 -0
- package/dist/schema/EventDef/mod.js.map +1 -0
- package/dist/schema/EventSequenceNumber/client.d.ts +136 -0
- package/dist/schema/EventSequenceNumber/client.d.ts.map +1 -0
- package/dist/schema/EventSequenceNumber/client.js +193 -0
- package/dist/schema/EventSequenceNumber/client.js.map +1 -0
- package/dist/schema/EventSequenceNumber/global.d.ts +15 -0
- package/dist/schema/EventSequenceNumber/global.d.ts.map +1 -0
- package/dist/schema/EventSequenceNumber/global.js +14 -0
- package/dist/schema/EventSequenceNumber/global.js.map +1 -0
- package/dist/schema/EventSequenceNumber/mod.d.ts +37 -0
- package/dist/schema/EventSequenceNumber/mod.d.ts.map +1 -0
- package/dist/schema/EventSequenceNumber/mod.js +37 -0
- package/dist/schema/EventSequenceNumber/mod.js.map +1 -0
- package/dist/schema/EventSequenceNumber.test.js +44 -44
- package/dist/schema/EventSequenceNumber.test.js.map +1 -1
- package/dist/schema/{LiveStoreEvent.d.ts → LiveStoreEvent/client.d.ts} +102 -111
- package/dist/schema/LiveStoreEvent/client.d.ts.map +1 -0
- package/dist/schema/LiveStoreEvent/client.js +176 -0
- package/dist/schema/LiveStoreEvent/client.js.map +1 -0
- package/dist/schema/LiveStoreEvent/client.test.d.ts +2 -0
- package/dist/schema/LiveStoreEvent/client.test.d.ts.map +1 -0
- package/dist/schema/LiveStoreEvent/client.test.js +111 -0
- package/dist/schema/LiveStoreEvent/client.test.js.map +1 -0
- package/dist/schema/LiveStoreEvent/for-event-def.d.ts +52 -0
- package/dist/schema/LiveStoreEvent/for-event-def.d.ts.map +1 -0
- package/dist/schema/LiveStoreEvent/for-event-def.js +2 -0
- package/dist/schema/LiveStoreEvent/for-event-def.js.map +1 -0
- package/dist/schema/LiveStoreEvent/global.d.ts +36 -0
- package/dist/schema/LiveStoreEvent/global.d.ts.map +1 -0
- package/dist/schema/LiveStoreEvent/global.js +31 -0
- package/dist/schema/LiveStoreEvent/global.js.map +1 -0
- package/dist/schema/LiveStoreEvent/input.d.ts +46 -0
- package/dist/schema/LiveStoreEvent/input.d.ts.map +1 -0
- package/dist/schema/LiveStoreEvent/input.js +26 -0
- package/dist/schema/LiveStoreEvent/input.js.map +1 -0
- package/dist/schema/LiveStoreEvent/mod.d.ts +5 -0
- package/dist/schema/LiveStoreEvent/mod.d.ts.map +1 -0
- package/dist/schema/LiveStoreEvent/mod.js +5 -0
- package/dist/schema/LiveStoreEvent/mod.js.map +1 -0
- package/dist/schema/events.d.ts +1 -1
- package/dist/schema/events.d.ts.map +1 -1
- package/dist/schema/events.js +1 -1
- package/dist/schema/events.js.map +1 -1
- package/dist/schema/mod.d.ts +6 -4
- package/dist/schema/mod.d.ts.map +1 -1
- package/dist/schema/mod.js +5 -4
- package/dist/schema/mod.js.map +1 -1
- package/dist/schema/schema.d.ts +16 -1
- package/dist/schema/schema.d.ts.map +1 -1
- package/dist/schema/schema.js +32 -4
- package/dist/schema/schema.js.map +1 -1
- package/dist/schema/state/sqlite/client-document-def.d.ts +2 -1
- package/dist/schema/state/sqlite/client-document-def.d.ts.map +1 -1
- package/dist/schema/state/sqlite/client-document-def.js +36 -15
- package/dist/schema/state/sqlite/client-document-def.js.map +1 -1
- package/dist/schema/state/sqlite/client-document-def.test.js +121 -2
- package/dist/schema/state/sqlite/client-document-def.test.js.map +1 -1
- package/dist/schema/state/sqlite/column-annotations.d.ts.map +1 -1
- package/dist/schema/state/sqlite/column-annotations.js +1 -1
- package/dist/schema/state/sqlite/column-annotations.js.map +1 -1
- package/dist/schema/state/sqlite/column-annotations.test.js +2 -2
- package/dist/schema/state/sqlite/column-annotations.test.js.map +1 -1
- package/dist/schema/state/sqlite/column-def.d.ts.map +1 -1
- package/dist/schema/state/sqlite/column-def.js +96 -47
- package/dist/schema/state/sqlite/column-def.js.map +1 -1
- package/dist/schema/state/sqlite/column-def.test.js +51 -12
- package/dist/schema/state/sqlite/column-def.test.js.map +1 -1
- package/dist/schema/state/sqlite/column-spec.d.ts.map +1 -1
- package/dist/schema/state/sqlite/column-spec.js +30 -12
- package/dist/schema/state/sqlite/column-spec.js.map +1 -1
- package/dist/schema/state/sqlite/column-spec.test.js +24 -15
- package/dist/schema/state/sqlite/column-spec.test.js.map +1 -1
- package/dist/schema/state/sqlite/db-schema/ast/sqlite.js +2 -2
- package/dist/schema/state/sqlite/db-schema/ast/sqlite.js.map +1 -1
- package/dist/schema/state/sqlite/db-schema/dsl/field-defs.d.ts +16 -10
- package/dist/schema/state/sqlite/db-schema/dsl/field-defs.d.ts.map +1 -1
- package/dist/schema/state/sqlite/db-schema/dsl/field-defs.js +15 -4
- package/dist/schema/state/sqlite/db-schema/dsl/field-defs.js.map +1 -1
- package/dist/schema/state/sqlite/db-schema/dsl/field-defs.test.js +1 -1
- package/dist/schema/state/sqlite/db-schema/dsl/field-defs.test.js.map +1 -1
- package/dist/schema/state/sqlite/db-schema/dsl/mod.d.ts +1 -1
- package/dist/schema/state/sqlite/db-schema/dsl/mod.d.ts.map +1 -1
- package/dist/schema/state/sqlite/db-schema/dsl/mod.js +1 -1
- package/dist/schema/state/sqlite/db-schema/dsl/mod.js.map +1 -1
- package/dist/schema/state/sqlite/mod.d.ts +2 -2
- package/dist/schema/state/sqlite/mod.d.ts.map +1 -1
- package/dist/schema/state/sqlite/mod.js +5 -7
- package/dist/schema/state/sqlite/mod.js.map +1 -1
- package/dist/schema/state/sqlite/query-builder/api.d.ts +51 -22
- package/dist/schema/state/sqlite/query-builder/api.d.ts.map +1 -1
- package/dist/schema/state/sqlite/query-builder/astToSql.d.ts.map +1 -1
- package/dist/schema/state/sqlite/query-builder/astToSql.js +99 -22
- package/dist/schema/state/sqlite/query-builder/astToSql.js.map +1 -1
- package/dist/schema/state/sqlite/query-builder/impl.d.ts +1 -1
- package/dist/schema/state/sqlite/query-builder/impl.d.ts.map +1 -1
- package/dist/schema/state/sqlite/query-builder/impl.js +28 -15
- package/dist/schema/state/sqlite/query-builder/impl.js.map +1 -1
- package/dist/schema/state/sqlite/query-builder/impl.test.js +231 -93
- package/dist/schema/state/sqlite/query-builder/impl.test.js.map +1 -1
- package/dist/schema/state/sqlite/schema-helpers.d.ts +2 -2
- package/dist/schema/state/sqlite/schema-helpers.d.ts.map +1 -1
- package/dist/schema/state/sqlite/schema-helpers.js +24 -14
- package/dist/schema/state/sqlite/schema-helpers.js.map +1 -1
- package/dist/schema/state/sqlite/schema-helpers.test.d.ts +2 -0
- package/dist/schema/state/sqlite/schema-helpers.test.d.ts.map +1 -0
- package/dist/schema/state/sqlite/schema-helpers.test.js +36 -0
- package/dist/schema/state/sqlite/schema-helpers.test.js.map +1 -0
- package/dist/schema/state/sqlite/{system-tables.d.ts → system-tables/eventlog-tables.d.ts} +21 -450
- package/dist/schema/state/sqlite/system-tables/eventlog-tables.d.ts.map +1 -0
- package/dist/schema/state/sqlite/system-tables/eventlog-tables.js +54 -0
- package/dist/schema/state/sqlite/system-tables/eventlog-tables.js.map +1 -0
- package/dist/schema/state/sqlite/system-tables/mod.d.ts +3 -0
- package/dist/schema/state/sqlite/system-tables/mod.d.ts.map +1 -0
- package/dist/schema/state/sqlite/system-tables/mod.js +3 -0
- package/dist/schema/state/sqlite/system-tables/mod.js.map +1 -0
- package/dist/schema/state/sqlite/system-tables/state-tables.d.ts +456 -0
- package/dist/schema/state/sqlite/system-tables/state-tables.d.ts.map +1 -0
- package/dist/schema/state/sqlite/system-tables/state-tables.js +55 -0
- package/dist/schema/state/sqlite/system-tables/state-tables.js.map +1 -0
- package/dist/schema/state/sqlite/table-def.d.ts +5 -3
- package/dist/schema/state/sqlite/table-def.d.ts.map +1 -1
- package/dist/schema/state/sqlite/table-def.js +1 -1
- package/dist/schema/state/sqlite/table-def.js.map +1 -1
- package/dist/schema/state/sqlite/table-def.test.js +92 -3
- package/dist/schema/state/sqlite/table-def.test.js.map +1 -1
- package/dist/schema/unknown-events.d.ts +47 -0
- package/dist/schema/unknown-events.d.ts.map +1 -0
- package/dist/schema/unknown-events.js +69 -0
- package/dist/schema/unknown-events.js.map +1 -0
- package/dist/schema-management/__tests__/migrations-autoincrement-quoting.test.d.ts +2 -0
- package/dist/schema-management/__tests__/migrations-autoincrement-quoting.test.d.ts.map +1 -0
- package/dist/schema-management/__tests__/migrations-autoincrement-quoting.test.js +73 -0
- package/dist/schema-management/__tests__/migrations-autoincrement-quoting.test.js.map +1 -0
- package/dist/schema-management/common.js +2 -2
- package/dist/schema-management/common.js.map +1 -1
- package/dist/schema-management/migrations.d.ts +32 -2
- package/dist/schema-management/migrations.d.ts.map +1 -1
- package/dist/schema-management/migrations.js +38 -6
- package/dist/schema-management/migrations.js.map +1 -1
- package/dist/schema-management/validate-schema.d.ts +3 -3
- package/dist/schema-management/validate-schema.d.ts.map +1 -1
- package/dist/schema-management/validate-schema.js +2 -2
- package/dist/schema-management/validate-schema.js.map +1 -1
- package/dist/sql-queries/sql-queries.d.ts.map +1 -1
- package/dist/sql-queries/sql-queries.js +18 -6
- package/dist/sql-queries/sql-queries.js.map +1 -1
- package/dist/sql-queries/sql-query-builder.d.ts.map +1 -1
- package/dist/sql-queries/sql-query-builder.js.map +1 -1
- package/dist/sqlite-db-helper.js +3 -3
- package/dist/sqlite-db-helper.js.map +1 -1
- package/dist/sqlite-types.d.ts +5 -5
- package/dist/sqlite-types.d.ts.map +1 -1
- package/dist/sqlite-types.js.map +1 -1
- package/dist/sync/ClientSessionSyncProcessor.d.ts +12 -12
- package/dist/sync/ClientSessionSyncProcessor.d.ts.map +1 -1
- package/dist/sync/ClientSessionSyncProcessor.js +99 -114
- package/dist/sync/ClientSessionSyncProcessor.js.map +1 -1
- package/dist/sync/errors.d.ts +0 -33
- package/dist/sync/errors.d.ts.map +1 -1
- package/dist/sync/errors.js +5 -22
- package/dist/sync/errors.js.map +1 -1
- package/dist/sync/index.d.ts +2 -0
- package/dist/sync/index.d.ts.map +1 -1
- package/dist/sync/index.js +2 -0
- package/dist/sync/index.js.map +1 -1
- package/dist/sync/mock-sync-backend.d.ts +10 -8
- package/dist/sync/mock-sync-backend.d.ts.map +1 -1
- package/dist/sync/mock-sync-backend.js +71 -69
- package/dist/sync/mock-sync-backend.js.map +1 -1
- package/dist/sync/next/compact-events.d.ts.map +1 -1
- package/dist/sync/next/compact-events.js +11 -12
- package/dist/sync/next/compact-events.js.map +1 -1
- package/dist/sync/next/facts.d.ts +5 -5
- package/dist/sync/next/facts.d.ts.map +1 -1
- package/dist/sync/next/facts.js +7 -8
- package/dist/sync/next/facts.js.map +1 -1
- package/dist/sync/next/history-dag-common.d.ts +54 -15
- package/dist/sync/next/history-dag-common.d.ts.map +1 -1
- package/dist/sync/next/history-dag-common.js +198 -9
- package/dist/sync/next/history-dag-common.js.map +1 -1
- package/dist/sync/next/history-dag.d.ts.map +1 -1
- package/dist/sync/next/history-dag.js +11 -11
- package/dist/sync/next/history-dag.js.map +1 -1
- package/dist/sync/next/rebase-events.d.ts +5 -5
- package/dist/sync/next/rebase-events.d.ts.map +1 -1
- package/dist/sync/next/rebase-events.js +6 -6
- package/dist/sync/next/rebase-events.js.map +1 -1
- package/dist/sync/next/test/compact-events.calculator.test.js +2 -2
- package/dist/sync/next/test/compact-events.calculator.test.js.map +1 -1
- package/dist/sync/next/test/compact-events.test.d.ts.map +1 -1
- package/dist/sync/next/test/compact-events.test.js +2 -2
- package/dist/sync/next/test/compact-events.test.js.map +1 -1
- package/dist/sync/next/test/event-fixtures.d.ts +2 -2
- package/dist/sync/next/test/event-fixtures.d.ts.map +1 -1
- package/dist/sync/next/test/event-fixtures.js +11 -11
- package/dist/sync/next/test/event-fixtures.js.map +1 -1
- package/dist/sync/sync-backend-kv.d.ts +3 -3
- package/dist/sync/sync-backend-kv.d.ts.map +1 -1
- package/dist/sync/sync-backend-kv.js +3 -3
- package/dist/sync/sync-backend-kv.js.map +1 -1
- package/dist/sync/sync-backend.d.ts +33 -13
- package/dist/sync/sync-backend.d.ts.map +1 -1
- package/dist/sync/sync-backend.js +38 -1
- package/dist/sync/sync-backend.js.map +1 -1
- package/dist/sync/sync.d.ts +23 -2
- package/dist/sync/sync.d.ts.map +1 -1
- package/dist/sync/syncstate.d.ts +55 -55
- package/dist/sync/syncstate.d.ts.map +1 -1
- package/dist/sync/syncstate.js +80 -98
- package/dist/sync/syncstate.js.map +1 -1
- package/dist/sync/syncstate.test.js +221 -132
- package/dist/sync/syncstate.test.js.map +1 -1
- package/dist/sync/transport-chunking.d.ts +36 -0
- package/dist/sync/transport-chunking.d.ts.map +1 -0
- package/dist/sync/transport-chunking.js +56 -0
- package/dist/sync/transport-chunking.js.map +1 -0
- package/dist/sync/validate-push-payload.d.ts +2 -2
- package/dist/sync/validate-push-payload.d.ts.map +1 -1
- package/dist/sync/validate-push-payload.js +4 -6
- package/dist/sync/validate-push-payload.js.map +1 -1
- package/dist/testing/event-factory.d.ts +68 -0
- package/dist/testing/event-factory.d.ts.map +1 -0
- package/dist/testing/event-factory.js +78 -0
- package/dist/testing/event-factory.js.map +1 -0
- package/dist/testing/mod.d.ts +2 -0
- package/dist/testing/mod.d.ts.map +1 -0
- package/dist/testing/mod.js +2 -0
- package/dist/testing/mod.js.map +1 -0
- package/dist/util.js +2 -2
- package/dist/util.js.map +1 -1
- package/dist/version.d.ts +24 -5
- package/dist/version.d.ts.map +1 -1
- package/dist/version.js +25 -8
- package/dist/version.js.map +1 -1
- package/package.json +69 -16
- package/src/ClientSessionLeaderThreadProxy.ts +27 -12
- package/src/WorkerTransportError.ts +12 -0
- package/src/adapter-types.ts +50 -7
- package/src/bounded-collections.ts +6 -5
- package/src/debug-info.ts +37 -6
- package/src/devtools/devtools-compatibility.test.ts +18 -0
- package/src/devtools/devtools-messages-client-session.ts +22 -4
- package/src/devtools/devtools-messages-common.ts +7 -12
- package/src/devtools/devtools-messages-leader.ts +29 -10
- package/src/devtools/devtools-sessioninfo.ts +8 -5
- package/src/devtools/mod.ts +11 -2
- package/src/errors.ts +32 -24
- package/src/index.ts +4 -1
- package/src/leader-thread/LeaderSyncProcessor.ts +523 -373
- package/src/leader-thread/RejectedPushError.ts +106 -0
- package/src/leader-thread/connection.ts +1 -1
- package/src/leader-thread/eventlog.ts +112 -39
- package/src/leader-thread/leader-worker-devtools.ts +201 -120
- package/src/leader-thread/make-leader-thread-layer.test.ts +44 -0
- package/src/leader-thread/make-leader-thread-layer.ts +125 -40
- package/src/leader-thread/materialize-event.ts +40 -10
- package/src/leader-thread/mod.ts +1 -0
- package/src/leader-thread/recreate-db.ts +7 -7
- package/src/leader-thread/shutdown-channel.ts +4 -8
- package/src/leader-thread/stream-events.ts +206 -0
- package/src/leader-thread/types.ts +68 -18
- package/src/logging.ts +62 -0
- package/src/make-client-session.ts +11 -5
- package/src/materializer-helper.ts +27 -16
- package/src/otel.ts +13 -2
- package/src/rematerialize-from-eventlog.ts +61 -51
- package/src/schema/EventDef/define.ts +217 -0
- package/src/schema/EventDef/deprecated.test.ts +129 -0
- package/src/schema/EventDef/deprecated.ts +175 -0
- package/src/schema/EventDef/event-def.ts +125 -0
- package/src/schema/EventDef/facts.ts +135 -0
- package/src/schema/EventDef/materializer.ts +172 -0
- package/src/schema/EventDef/mod.ts +5 -0
- package/src/schema/EventSequenceNumber/client.ts +257 -0
- package/src/schema/EventSequenceNumber/global.ts +19 -0
- package/src/schema/EventSequenceNumber/mod.ts +37 -0
- package/src/schema/EventSequenceNumber.test.ts +72 -53
- package/src/schema/LiveStoreEvent/client.test.ts +129 -0
- package/src/schema/LiveStoreEvent/client.ts +235 -0
- package/src/schema/LiveStoreEvent/for-event-def.ts +60 -0
- package/src/schema/LiveStoreEvent/global.ts +45 -0
- package/src/schema/LiveStoreEvent/input.ts +63 -0
- package/src/schema/LiveStoreEvent/mod.ts +4 -0
- package/src/schema/events.ts +1 -1
- package/src/schema/mod.ts +6 -4
- package/src/schema/schema.ts +46 -5
- package/src/schema/state/sqlite/client-document-def.test.ts +144 -5
- package/src/schema/state/sqlite/client-document-def.ts +47 -34
- package/src/schema/state/sqlite/column-annotations.test.ts +3 -2
- package/src/schema/state/sqlite/column-annotations.ts +2 -1
- package/src/schema/state/sqlite/column-def.test.ts +66 -12
- package/src/schema/state/sqlite/column-def.ts +119 -47
- package/src/schema/state/sqlite/column-spec.test.ts +32 -17
- package/src/schema/state/sqlite/column-spec.ts +37 -11
- package/src/schema/state/sqlite/db-schema/ast/sqlite.ts +2 -2
- package/src/schema/state/sqlite/db-schema/dsl/field-defs.test.ts +2 -1
- package/src/schema/state/sqlite/db-schema/dsl/field-defs.ts +41 -15
- package/src/schema/state/sqlite/db-schema/dsl/mod.ts +13 -19
- package/src/schema/state/sqlite/mod.ts +7 -8
- package/src/schema/state/sqlite/query-builder/api.ts +55 -17
- package/src/schema/state/sqlite/query-builder/astToSql.ts +110 -21
- package/src/schema/state/sqlite/query-builder/impl.test.ts +267 -93
- package/src/schema/state/sqlite/query-builder/impl.ts +26 -13
- package/src/schema/state/sqlite/schema-helpers.test.ts +44 -0
- package/src/schema/state/sqlite/schema-helpers.ts +30 -22
- package/src/schema/state/sqlite/system-tables/eventlog-tables.ts +64 -0
- package/src/schema/state/sqlite/system-tables/mod.ts +2 -0
- package/src/schema/state/sqlite/system-tables/state-tables.ts +69 -0
- package/src/schema/state/sqlite/table-def.test.ts +114 -3
- package/src/schema/state/sqlite/table-def.ts +16 -22
- package/src/schema/unknown-events.ts +131 -0
- package/src/schema-management/__tests__/migrations-autoincrement-quoting.test.ts +88 -0
- package/src/schema-management/common.ts +2 -2
- package/src/schema-management/migrations.ts +42 -9
- package/src/schema-management/validate-schema.ts +3 -3
- package/src/sql-queries/sql-queries.ts +18 -6
- package/src/sql-queries/sql-query-builder.ts +1 -0
- package/src/sqlite-db-helper.ts +3 -3
- package/src/sqlite-types.ts +6 -5
- package/src/sync/ClientSessionSyncProcessor.ts +152 -142
- package/src/sync/errors.ts +12 -24
- package/src/sync/index.ts +2 -0
- package/src/sync/mock-sync-backend.ts +146 -104
- package/src/sync/next/compact-events.ts +10 -11
- package/src/sync/next/facts.ts +13 -14
- package/src/sync/next/history-dag-common.ts +280 -26
- package/src/sync/next/history-dag.ts +17 -13
- package/src/sync/next/rebase-events.ts +12 -12
- package/src/sync/next/test/compact-events.calculator.test.ts +3 -2
- package/src/sync/next/test/compact-events.test.ts +4 -3
- package/src/sync/next/test/event-fixtures.ts +13 -13
- package/src/sync/sync-backend-kv.ts +4 -3
- package/src/sync/sync-backend.ts +66 -17
- package/src/sync/sync.ts +24 -2
- package/src/sync/syncstate.test.ts +583 -419
- package/src/sync/syncstate.ts +127 -122
- package/src/sync/transport-chunking.ts +90 -0
- package/src/sync/validate-push-payload.ts +6 -8
- package/src/testing/event-factory.ts +131 -0
- package/src/testing/mod.ts +1 -0
- package/src/util.ts +2 -2
- package/src/version.ts +33 -8
- package/dist/schema/EventDef.d.ts +0 -126
- package/dist/schema/EventDef.d.ts.map +0 -1
- package/dist/schema/EventDef.js +0 -46
- package/dist/schema/EventDef.js.map +0 -1
- package/dist/schema/EventSequenceNumber.d.ts +0 -80
- package/dist/schema/EventSequenceNumber.d.ts.map +0 -1
- package/dist/schema/EventSequenceNumber.js +0 -139
- package/dist/schema/EventSequenceNumber.js.map +0 -1
- package/dist/schema/LiveStoreEvent.d.ts.map +0 -1
- package/dist/schema/LiveStoreEvent.js +0 -147
- package/dist/schema/LiveStoreEvent.js.map +0 -1
- package/dist/schema/state/sqlite/system-tables.d.ts.map +0 -1
- package/dist/schema/state/sqlite/system-tables.js +0 -81
- package/dist/schema/state/sqlite/system-tables.js.map +0 -1
- package/dist/sync/next/graphology.d.ts +0 -8
- package/dist/sync/next/graphology.d.ts.map +0 -1
- package/dist/sync/next/graphology.js +0 -30
- package/dist/sync/next/graphology.js.map +0 -1
- package/dist/sync/next/graphology_.d.ts +0 -3
- package/dist/sync/next/graphology_.d.ts.map +0 -1
- package/dist/sync/next/graphology_.js +0 -3
- package/dist/sync/next/graphology_.js.map +0 -1
- package/src/schema/EventDef.ts +0 -222
- package/src/schema/EventSequenceNumber.ts +0 -199
- package/src/schema/LiveStoreEvent.ts +0 -286
- package/src/schema/state/sqlite/system-tables.ts +0 -106
- package/src/sync/next/ambient.d.ts +0 -3
- package/src/sync/next/graphology.ts +0 -41
- package/src/sync/next/graphology_.ts +0 -2
|
@@ -9,7 +9,7 @@ import { astToSql } from './astToSql.ts'
|
|
|
9
9
|
export const makeQueryBuilder = <TResult, TTableDef extends TableDefBase>(
|
|
10
10
|
tableDef: TTableDef,
|
|
11
11
|
ast: QueryBuilderAst = emptyAst(tableDef),
|
|
12
|
-
): QueryBuilder<TResult, TTableDef
|
|
12
|
+
): QueryBuilder<TResult, TTableDef> => {
|
|
13
13
|
const api = {
|
|
14
14
|
select() {
|
|
15
15
|
assertSelectQueryBuilderAst(ast)
|
|
@@ -18,6 +18,7 @@ export const makeQueryBuilder = <TResult, TTableDef extends TableDefBase>(
|
|
|
18
18
|
|
|
19
19
|
// Pluck if there's only one column selected
|
|
20
20
|
if (params.length === 1) {
|
|
21
|
+
// oxlint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- arguments-based overload dispatch requires manual narrowing
|
|
21
22
|
const [col] = params as any as [string]
|
|
22
23
|
return makeQueryBuilder(tableDef, {
|
|
23
24
|
...ast,
|
|
@@ -26,8 +27,10 @@ export const makeQueryBuilder = <TResult, TTableDef extends TableDefBase>(
|
|
|
26
27
|
})
|
|
27
28
|
}
|
|
28
29
|
|
|
30
|
+
// oxlint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- arguments-based overload dispatch requires manual narrowing
|
|
29
31
|
const columns = params as unknown as ReadonlyArray<string>
|
|
30
32
|
|
|
33
|
+
// oxlint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- query builder return type depends on AST state; consumer type safety enforced by api.ts
|
|
31
34
|
return makeQueryBuilder(tableDef, {
|
|
32
35
|
...ast,
|
|
33
36
|
resultSchemaSingle:
|
|
@@ -35,7 +38,6 @@ export const makeQueryBuilder = <TResult, TTableDef extends TableDefBase>(
|
|
|
35
38
|
select: { columns },
|
|
36
39
|
}) as any
|
|
37
40
|
},
|
|
38
|
-
// biome-ignore lint/complexity/useArrowFunction: prefer function over arrow function for this case
|
|
39
41
|
where: function () {
|
|
40
42
|
if (ast._tag === 'InsertQuery') return invalidQueryBuilder('Cannot use where with insert')
|
|
41
43
|
if (ast._tag === 'RowQuery') return invalidQueryBuilder('Cannot use where with row')
|
|
@@ -45,7 +47,8 @@ export const makeQueryBuilder = <TResult, TTableDef extends TableDefBase>(
|
|
|
45
47
|
const newOps = Object.entries(params)
|
|
46
48
|
.filter(([, value]) => value !== undefined)
|
|
47
49
|
.map<QueryBuilderAst.Where>(([col, value]) =>
|
|
48
|
-
Predicate.hasProperty(value, 'op') && Predicate.hasProperty(value, 'value')
|
|
50
|
+
Predicate.hasProperty(value, 'op') === true && Predicate.hasProperty(value, 'value') === true
|
|
51
|
+
// oxlint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- where clause construction; shape validated at runtime
|
|
49
52
|
? ({ col, op: value.op, value: value.value } as any)
|
|
50
53
|
: { col, op: '=', value },
|
|
51
54
|
)
|
|
@@ -55,6 +58,7 @@ export const makeQueryBuilder = <TResult, TTableDef extends TableDefBase>(
|
|
|
55
58
|
case 'SelectQuery':
|
|
56
59
|
case 'UpdateQuery':
|
|
57
60
|
case 'DeleteQuery': {
|
|
61
|
+
// oxlint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- query builder return type depends on AST state; consumer type safety enforced by api.ts
|
|
58
62
|
return makeQueryBuilder(tableDef, {
|
|
59
63
|
...ast,
|
|
60
64
|
where: [...ast.where, ...newOps],
|
|
@@ -75,6 +79,7 @@ export const makeQueryBuilder = <TResult, TTableDef extends TableDefBase>(
|
|
|
75
79
|
case 'SelectQuery':
|
|
76
80
|
case 'UpdateQuery':
|
|
77
81
|
case 'DeleteQuery': {
|
|
82
|
+
// oxlint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- query builder return type depends on AST state; consumer type safety enforced by api.ts
|
|
78
83
|
return makeQueryBuilder(tableDef, {
|
|
79
84
|
...ast,
|
|
80
85
|
where: [...ast.where, { col, op, value }],
|
|
@@ -92,6 +97,7 @@ export const makeQueryBuilder = <TResult, TTableDef extends TableDefBase>(
|
|
|
92
97
|
if (arguments.length === 0 || arguments.length > 2) return invalidQueryBuilder()
|
|
93
98
|
|
|
94
99
|
if (arguments.length === 1) {
|
|
100
|
+
// oxlint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- arguments-based overload dispatch requires manual narrowing
|
|
95
101
|
const params = arguments[0] as QueryBuilder.OrderByParams<TTableDef>
|
|
96
102
|
return makeQueryBuilder(tableDef, {
|
|
97
103
|
...ast,
|
|
@@ -99,8 +105,10 @@ export const makeQueryBuilder = <TResult, TTableDef extends TableDefBase>(
|
|
|
99
105
|
})
|
|
100
106
|
}
|
|
101
107
|
|
|
108
|
+
// oxlint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- arguments-based overload dispatch requires manual narrowing
|
|
102
109
|
const [col, direction] = arguments as any as [keyof TTableDef['sqliteDef']['columns'] & string, 'asc' | 'desc']
|
|
103
110
|
|
|
111
|
+
// oxlint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- query builder return type depends on AST state; consumer type safety enforced by api.ts
|
|
104
112
|
return makeQueryBuilder(tableDef, {
|
|
105
113
|
...ast,
|
|
106
114
|
orderBy: [...ast.orderBy, { col, direction }],
|
|
@@ -117,7 +125,7 @@ export const makeQueryBuilder = <TResult, TTableDef extends TableDefBase>(
|
|
|
117
125
|
return makeQueryBuilder(tableDef, { ...ast, offset: Option.some(offset) })
|
|
118
126
|
},
|
|
119
127
|
count: () => {
|
|
120
|
-
if (isRowQuery(ast) || ast._tag === 'InsertQuery' || ast._tag === 'UpdateQuery' || ast._tag === 'DeleteQuery')
|
|
128
|
+
if (isRowQuery(ast) === true || ast._tag === 'InsertQuery' || ast._tag === 'UpdateQuery' || ast._tag === 'DeleteQuery')
|
|
121
129
|
return invalidQueryBuilder()
|
|
122
130
|
|
|
123
131
|
return makeQueryBuilder(tableDef, {
|
|
@@ -172,6 +180,7 @@ export const makeQueryBuilder = <TResult, TTableDef extends TableDefBase>(
|
|
|
172
180
|
insert: (values) => {
|
|
173
181
|
const filteredValues = Object.fromEntries(Object.entries(values).filter(([, value]) => value !== undefined))
|
|
174
182
|
|
|
183
|
+
// oxlint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- query builder return type depends on AST state; consumer type safety enforced by api.ts
|
|
175
184
|
return makeQueryBuilder(tableDef, {
|
|
176
185
|
_tag: 'InsertQuery',
|
|
177
186
|
tableDef,
|
|
@@ -186,7 +195,7 @@ export const makeQueryBuilder = <TResult, TTableDef extends TableDefBase>(
|
|
|
186
195
|
action: 'ignore' | 'replace' | 'update',
|
|
187
196
|
updateValues?: Record<string, unknown>,
|
|
188
197
|
) => {
|
|
189
|
-
const targets = Array.isArray(targetOrTargets) ? targetOrTargets : [targetOrTargets]
|
|
198
|
+
const targets = Array.isArray(targetOrTargets) === true ? targetOrTargets : [targetOrTargets]
|
|
190
199
|
|
|
191
200
|
assertInsertQueryBuilderAst(ast)
|
|
192
201
|
|
|
@@ -200,6 +209,7 @@ export const makeQueryBuilder = <TResult, TTableDef extends TableDefBase>(
|
|
|
200
209
|
Match.exhaustive,
|
|
201
210
|
)
|
|
202
211
|
|
|
212
|
+
// oxlint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- query builder return type depends on AST state; consumer type safety enforced by api.ts
|
|
203
213
|
return makeQueryBuilder(tableDef, {
|
|
204
214
|
...ast,
|
|
205
215
|
onConflict,
|
|
@@ -209,6 +219,7 @@ export const makeQueryBuilder = <TResult, TTableDef extends TableDefBase>(
|
|
|
209
219
|
returning: (...columns) => {
|
|
210
220
|
assertWriteQueryBuilderAst(ast)
|
|
211
221
|
|
|
222
|
+
// oxlint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- query builder return type depends on AST state; consumer type safety enforced by api.ts
|
|
212
223
|
return makeQueryBuilder(tableDef, {
|
|
213
224
|
...ast,
|
|
214
225
|
returning: columns,
|
|
@@ -222,6 +233,7 @@ export const makeQueryBuilder = <TResult, TTableDef extends TableDefBase>(
|
|
|
222
233
|
// Preserve where clauses if coming from a SelectQuery
|
|
223
234
|
const whereClause = ast._tag === 'SelectQuery' ? ast.where : []
|
|
224
235
|
|
|
236
|
+
// oxlint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- query builder return type depends on AST state; consumer type safety enforced by api.ts
|
|
225
237
|
return makeQueryBuilder(tableDef, {
|
|
226
238
|
_tag: 'UpdateQuery',
|
|
227
239
|
tableDef,
|
|
@@ -236,6 +248,7 @@ export const makeQueryBuilder = <TResult, TTableDef extends TableDefBase>(
|
|
|
236
248
|
// Preserve where clauses if coming from a SelectQuery
|
|
237
249
|
const whereClause = ast._tag === 'SelectQuery' ? ast.where : []
|
|
238
250
|
|
|
251
|
+
// oxlint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- query builder return type depends on AST state; consumer type safety enforced by api.ts
|
|
239
252
|
return makeQueryBuilder(tableDef, {
|
|
240
253
|
_tag: 'DeleteQuery',
|
|
241
254
|
tableDef,
|
|
@@ -249,6 +262,7 @@ export const makeQueryBuilder = <TResult, TTableDef extends TableDefBase>(
|
|
|
249
262
|
return {
|
|
250
263
|
[QueryBuilderTypeId]: QueryBuilderTypeId,
|
|
251
264
|
[QueryBuilderAstSymbol]: ast,
|
|
265
|
+
// oxlint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- phantom type field for generic inference only
|
|
252
266
|
ResultType: 'only-for-type-inference' as TResult,
|
|
253
267
|
asSql: () => astToSql(ast),
|
|
254
268
|
toString: () => {
|
|
@@ -278,19 +292,19 @@ const emptyAst = (tableDef: TableDefBase): QueryBuilderAst.SelectQuery => ({
|
|
|
278
292
|
|
|
279
293
|
// Helper functions
|
|
280
294
|
|
|
281
|
-
|
|
295
|
+
const assertSelectQueryBuilderAst: (ast: QueryBuilderAst) => asserts ast is QueryBuilderAst.SelectQuery = (ast) => {
|
|
282
296
|
if (ast._tag !== 'SelectQuery') {
|
|
283
297
|
return shouldNeverHappen(`Expected SelectQuery but got ${ast._tag}`)
|
|
284
298
|
}
|
|
285
299
|
}
|
|
286
300
|
|
|
287
|
-
|
|
301
|
+
const assertInsertQueryBuilderAst: (ast: QueryBuilderAst) => asserts ast is QueryBuilderAst.InsertQuery = (ast) => {
|
|
288
302
|
if (ast._tag !== 'InsertQuery') {
|
|
289
303
|
return shouldNeverHappen(`Expected InsertQuery but got ${ast._tag}`)
|
|
290
304
|
}
|
|
291
305
|
}
|
|
292
306
|
|
|
293
|
-
|
|
307
|
+
const assertWriteQueryBuilderAst: (ast: QueryBuilderAst) => asserts ast is QueryBuilderAst.WriteQuery = (ast) => {
|
|
294
308
|
if (ast._tag !== 'InsertQuery' && ast._tag !== 'UpdateQuery' && ast._tag !== 'DeleteQuery') {
|
|
295
309
|
return shouldNeverHappen(`Expected WriteQuery but got ${ast._tag}`)
|
|
296
310
|
}
|
|
@@ -299,7 +313,7 @@ function assertWriteQueryBuilderAst(ast: QueryBuilderAst): asserts ast is QueryB
|
|
|
299
313
|
const isRowQuery = (ast: QueryBuilderAst): ast is QueryBuilderAst.RowQuery => ast._tag === 'RowQuery'
|
|
300
314
|
|
|
301
315
|
export const invalidQueryBuilder = (msg?: string) => {
|
|
302
|
-
return shouldNeverHappen(`Invalid query builder${msg ? `: ${msg}` : ''}`)
|
|
316
|
+
return shouldNeverHappen(`Invalid query builder${msg !== undefined ? `: ${msg}` : ''}`)
|
|
303
317
|
}
|
|
304
318
|
|
|
305
319
|
export const getResultSchema = (qb: QueryBuilder<any, any, any>): Schema.Schema<any> => {
|
|
@@ -329,7 +343,7 @@ export const getResultSchema = (qb: QueryBuilder<any, any, any>): Schema.Schema<
|
|
|
329
343
|
case 'UpdateQuery':
|
|
330
344
|
case 'DeleteQuery': {
|
|
331
345
|
// For write operations with RETURNING clause, we need to return the appropriate schema
|
|
332
|
-
if (queryAst.returning && queryAst.returning.length > 0) {
|
|
346
|
+
if (queryAst.returning !== undefined && queryAst.returning.length > 0) {
|
|
333
347
|
// Create a schema for the returned columns
|
|
334
348
|
return queryAst.tableDef.rowSchema.pipe(Schema.pick(...queryAst.returning), Schema.Array)
|
|
335
349
|
}
|
|
@@ -345,8 +359,7 @@ export const getResultSchema = (qb: QueryBuilder<any, any, any>): Schema.Schema<
|
|
|
345
359
|
Schema.headOrElse(),
|
|
346
360
|
)
|
|
347
361
|
}
|
|
348
|
-
default:
|
|
349
|
-
casesHandled(queryAst)
|
|
350
|
-
}
|
|
362
|
+
default:
|
|
363
|
+
return casesHandled(queryAst)
|
|
351
364
|
}
|
|
352
365
|
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest'
|
|
2
|
+
|
|
3
|
+
import * as State from '../mod.ts'
|
|
4
|
+
import { getDefaultValuesDecoded, getDefaultValuesEncoded } from './schema-helpers.ts'
|
|
5
|
+
|
|
6
|
+
describe('schema-helpers', () => {
|
|
7
|
+
it('resolves thunk defaults when decoding values', () => {
|
|
8
|
+
let counter = 0
|
|
9
|
+
const table = State.SQLite.table({
|
|
10
|
+
name: 'sessions',
|
|
11
|
+
columns: {
|
|
12
|
+
id: State.SQLite.text({ primaryKey: true }),
|
|
13
|
+
token: State.SQLite.text({ default: () => `token-${++counter}` }),
|
|
14
|
+
},
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
expect(counter).toBe(0)
|
|
18
|
+
|
|
19
|
+
const firstDefaults = getDefaultValuesDecoded(table)
|
|
20
|
+
const secondDefaults = getDefaultValuesDecoded(table)
|
|
21
|
+
|
|
22
|
+
expect(firstDefaults.token).toBe('token-1')
|
|
23
|
+
expect(secondDefaults.token).toBe('token-2')
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
it('resolves thunk defaults when encoding values', () => {
|
|
27
|
+
let counter = 0
|
|
28
|
+
const table = State.SQLite.table({
|
|
29
|
+
name: 'sessions_encoded',
|
|
30
|
+
columns: {
|
|
31
|
+
id: State.SQLite.text({ primaryKey: true }),
|
|
32
|
+
token: State.SQLite.text({ default: () => `encoded-${++counter}` }),
|
|
33
|
+
},
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
expect(counter).toBe(0)
|
|
37
|
+
|
|
38
|
+
const firstDefaults = getDefaultValuesEncoded(table)
|
|
39
|
+
const secondDefaults = getDefaultValuesEncoded(table)
|
|
40
|
+
|
|
41
|
+
expect(firstDefaults.token).toBe('encoded-1')
|
|
42
|
+
expect(secondDefaults.token).toBe('encoded-2')
|
|
43
|
+
})
|
|
44
|
+
})
|
|
@@ -2,9 +2,9 @@ import { shouldNeverHappen } from '@livestore/utils'
|
|
|
2
2
|
import { pipe, ReadonlyRecord, Schema } from '@livestore/utils/effect'
|
|
3
3
|
|
|
4
4
|
import { SqliteDsl } from './db-schema/mod.ts'
|
|
5
|
-
import type {
|
|
5
|
+
import type { TableDefBase } from './table-def.ts'
|
|
6
6
|
|
|
7
|
-
export const getDefaultValuesEncoded = <TTableDef extends
|
|
7
|
+
export const getDefaultValuesEncoded = <TTableDef extends TableDefBase>(
|
|
8
8
|
tableDef: TTableDef,
|
|
9
9
|
fallbackValues?: Record<string, any>,
|
|
10
10
|
) =>
|
|
@@ -13,17 +13,21 @@ export const getDefaultValuesEncoded = <TTableDef extends TableDef>(
|
|
|
13
13
|
ReadonlyRecord.filter((col, key) => {
|
|
14
14
|
if (fallbackValues?.[key] !== undefined) return true
|
|
15
15
|
if (key === 'id') return false
|
|
16
|
-
return col!.default._tag === 'None' || SqliteDsl.isSqlDefaultValue(col!.default.value)
|
|
16
|
+
return col!.default._tag === 'None' || !SqliteDsl.isSqlDefaultValue(col!.default.value)
|
|
17
|
+
}),
|
|
18
|
+
ReadonlyRecord.map((column, columnName) => {
|
|
19
|
+
if (fallbackValues?.[columnName] !== undefined) return fallbackValues[columnName]
|
|
20
|
+
if (column!.default._tag === 'None') {
|
|
21
|
+
return column!.nullable === true
|
|
22
|
+
? null
|
|
23
|
+
: shouldNeverHappen(`Column ${columnName} has no default value and is not nullable`)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const defaultValue = column!.default.value
|
|
27
|
+
const resolvedDefault = SqliteDsl.resolveColumnDefault(defaultValue)
|
|
28
|
+
|
|
29
|
+
return Schema.encodeSync(column!.schema)(resolvedDefault)
|
|
17
30
|
}),
|
|
18
|
-
ReadonlyRecord.map((column, columnName) =>
|
|
19
|
-
fallbackValues?.[columnName] === undefined
|
|
20
|
-
? column!.default._tag === 'None'
|
|
21
|
-
? column!.nullable === true
|
|
22
|
-
? null
|
|
23
|
-
: shouldNeverHappen(`Column ${columnName} has no default value and is not nullable`)
|
|
24
|
-
: Schema.encodeSync(column!.schema)(column!.default.value)
|
|
25
|
-
: fallbackValues[columnName],
|
|
26
|
-
),
|
|
27
31
|
)
|
|
28
32
|
|
|
29
33
|
export const getDefaultValuesDecoded = <TTableDef extends TableDefBase>(
|
|
@@ -35,15 +39,19 @@ export const getDefaultValuesDecoded = <TTableDef extends TableDefBase>(
|
|
|
35
39
|
ReadonlyRecord.filter((col, key) => {
|
|
36
40
|
if (fallbackValues?.[key] !== undefined) return true
|
|
37
41
|
if (key === 'id') return false
|
|
38
|
-
return col!.default._tag === 'None' || SqliteDsl.isSqlDefaultValue(col!.default.value)
|
|
42
|
+
return col!.default._tag === 'None' || !SqliteDsl.isSqlDefaultValue(col!.default.value)
|
|
43
|
+
}),
|
|
44
|
+
ReadonlyRecord.map((column, columnName) => {
|
|
45
|
+
if (fallbackValues?.[columnName] !== undefined) return fallbackValues[columnName]
|
|
46
|
+
if (column!.default._tag === 'None') {
|
|
47
|
+
return column!.nullable === true
|
|
48
|
+
? null
|
|
49
|
+
: shouldNeverHappen(`Column ${columnName} has no default value and is not nullable`)
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const defaultValue = column!.default.value
|
|
53
|
+
const resolvedDefault = SqliteDsl.resolveColumnDefault(defaultValue)
|
|
54
|
+
|
|
55
|
+
return Schema.validateSync(column!.schema)(resolvedDefault)
|
|
39
56
|
}),
|
|
40
|
-
ReadonlyRecord.map((column, columnName) =>
|
|
41
|
-
fallbackValues?.[columnName] === undefined
|
|
42
|
-
? column!.default._tag === 'None'
|
|
43
|
-
? column!.nullable === true
|
|
44
|
-
? null
|
|
45
|
-
: shouldNeverHappen(`Column ${columnName} has no default value and is not nullable`)
|
|
46
|
-
: Schema.validateSync(column!.schema)(column!.default.value)
|
|
47
|
-
: fallbackValues[columnName],
|
|
48
|
-
),
|
|
49
57
|
)
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { Schema } from '@livestore/utils/effect'
|
|
2
|
+
|
|
3
|
+
import * as EventSequenceNumber from '../../../EventSequenceNumber/mod.ts'
|
|
4
|
+
import { SqliteDsl } from '../db-schema/mod.ts'
|
|
5
|
+
import { table } from '../table-def.ts'
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* EVENTLOG DATABASE SYSTEM TABLES
|
|
9
|
+
*
|
|
10
|
+
* ⚠️ CRITICAL: NEVER modify eventlog schemas without bumping `liveStoreStorageFormatVersion`!
|
|
11
|
+
* Eventlog is the source of truth - schema changes cause permanent data loss.
|
|
12
|
+
*
|
|
13
|
+
* TODO: Implement proper eventlog versioning system to prevent accidental data loss
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
export const EVENTLOG_META_TABLE = 'eventlog'
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Main client-side event log storing all events (global and local/rebased).
|
|
20
|
+
*/
|
|
21
|
+
export const eventlogMetaTable = table({
|
|
22
|
+
name: EVENTLOG_META_TABLE,
|
|
23
|
+
columns: {
|
|
24
|
+
// TODO Adjust modeling so a global event never needs a client id component
|
|
25
|
+
seqNumGlobal: SqliteDsl.integer({ primaryKey: true, schema: EventSequenceNumber.Global.Schema }),
|
|
26
|
+
seqNumClient: SqliteDsl.integer({ primaryKey: true, schema: EventSequenceNumber.Client.Schema }),
|
|
27
|
+
seqNumRebaseGeneration: SqliteDsl.integer({ primaryKey: true }),
|
|
28
|
+
parentSeqNumGlobal: SqliteDsl.integer({ schema: EventSequenceNumber.Global.Schema }),
|
|
29
|
+
parentSeqNumClient: SqliteDsl.integer({ schema: EventSequenceNumber.Client.Schema }),
|
|
30
|
+
parentSeqNumRebaseGeneration: SqliteDsl.integer({}),
|
|
31
|
+
/** Event definition name */
|
|
32
|
+
name: SqliteDsl.text({}),
|
|
33
|
+
argsJson: SqliteDsl.text({ schema: Schema.parseJson(Schema.Any) }),
|
|
34
|
+
clientId: SqliteDsl.text({}),
|
|
35
|
+
sessionId: SqliteDsl.text({}),
|
|
36
|
+
schemaHash: SqliteDsl.integer({}),
|
|
37
|
+
syncMetadataJson: SqliteDsl.text({ schema: Schema.parseJson(Schema.Option(Schema.JsonValue)) }),
|
|
38
|
+
},
|
|
39
|
+
indexes: [
|
|
40
|
+
{ columns: ['seqNumGlobal'], name: 'idx_eventlog_seqNumGlobal' },
|
|
41
|
+
{ columns: ['seqNumGlobal', 'seqNumClient', 'seqNumRebaseGeneration'], name: 'idx_eventlog_seqNum' },
|
|
42
|
+
],
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
export type EventlogMetaRow = typeof eventlogMetaTable.Type
|
|
46
|
+
|
|
47
|
+
export const SYNC_STATUS_TABLE = '__livestore_sync_status'
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Tracks sync status including the remote head position and backend identity.
|
|
51
|
+
*/
|
|
52
|
+
// TODO support sync backend identity (to detect if sync backend changes)
|
|
53
|
+
export const syncStatusTable = table({
|
|
54
|
+
name: SYNC_STATUS_TABLE,
|
|
55
|
+
columns: {
|
|
56
|
+
head: SqliteDsl.integer({ primaryKey: true }),
|
|
57
|
+
// Null means the sync backend is not yet connected and we haven't yet seen a backend ID
|
|
58
|
+
backendId: SqliteDsl.text({ nullable: true }),
|
|
59
|
+
},
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
export type SyncStatusRow = typeof syncStatusTable.Type
|
|
63
|
+
|
|
64
|
+
export const eventlogSystemTables = [eventlogMetaTable, syncStatusTable] as const
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import * as EventSequenceNumber from '../../../EventSequenceNumber/mod.ts'
|
|
2
|
+
import { SqliteDsl } from '../db-schema/mod.ts'
|
|
3
|
+
import { table } from '../table-def.ts'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* STATE DATABASE SYSTEM TABLES
|
|
7
|
+
*
|
|
8
|
+
* ⚠️ SAFE TO CHANGE: State tables are automatically rebuilt from eventlog when schema changes.
|
|
9
|
+
* No need to bump `liveStoreStorageFormatVersion` (uses hash-based migration via SqliteAst.hash()).
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
export const SCHEMA_META_TABLE = '__livestore_schema'
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Tracks schema hashes for user-defined tables to detect schema changes.
|
|
16
|
+
*/
|
|
17
|
+
export const schemaMetaTable = table({
|
|
18
|
+
name: SCHEMA_META_TABLE,
|
|
19
|
+
columns: {
|
|
20
|
+
tableName: SqliteDsl.text({ primaryKey: true }),
|
|
21
|
+
schemaHash: SqliteDsl.integer({ nullable: false }),
|
|
22
|
+
/** ISO date format */
|
|
23
|
+
updatedAt: SqliteDsl.text({ nullable: false }),
|
|
24
|
+
},
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
export type SchemaMetaRow = typeof schemaMetaTable.Type
|
|
28
|
+
|
|
29
|
+
export const SCHEMA_EVENT_DEFS_META_TABLE = '__livestore_schema_event_defs'
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Tracks schema hashes for event definitions to detect event schema changes.
|
|
33
|
+
*/
|
|
34
|
+
export const schemaEventDefsMetaTable = table({
|
|
35
|
+
name: SCHEMA_EVENT_DEFS_META_TABLE,
|
|
36
|
+
columns: {
|
|
37
|
+
eventName: SqliteDsl.text({ primaryKey: true }),
|
|
38
|
+
schemaHash: SqliteDsl.integer({ nullable: false }),
|
|
39
|
+
/** ISO date format */
|
|
40
|
+
updatedAt: SqliteDsl.text({ nullable: false }),
|
|
41
|
+
},
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
export type SchemaEventDefsMetaRow = typeof schemaEventDefsMetaTable.Type
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Table which stores SQLite changeset blobs which is used for rolling back
|
|
48
|
+
* read-model state during rebasing.
|
|
49
|
+
*/
|
|
50
|
+
export const SESSION_CHANGESET_META_TABLE = '__livestore_session_changeset'
|
|
51
|
+
|
|
52
|
+
export const sessionChangesetMetaTable = table({
|
|
53
|
+
name: SESSION_CHANGESET_META_TABLE,
|
|
54
|
+
columns: {
|
|
55
|
+
// TODO bring back primary key
|
|
56
|
+
seqNumGlobal: SqliteDsl.integer({ schema: EventSequenceNumber.Global.Schema }),
|
|
57
|
+
seqNumClient: SqliteDsl.integer({ schema: EventSequenceNumber.Client.Schema }),
|
|
58
|
+
seqNumRebaseGeneration: SqliteDsl.integer({}),
|
|
59
|
+
changeset: SqliteDsl.blob({ nullable: true }),
|
|
60
|
+
debug: SqliteDsl.json({ nullable: true }),
|
|
61
|
+
},
|
|
62
|
+
indexes: [{ columns: ['seqNumGlobal', 'seqNumClient'], name: 'idx_session_changeset_id' }],
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
export type SessionChangesetMetaRow = typeof sessionChangesetMetaTable.Type
|
|
66
|
+
|
|
67
|
+
export const stateSystemTables = [schemaMetaTable, schemaEventDefsMetaTable, sessionChangesetMetaTable] as const
|
|
68
|
+
|
|
69
|
+
export const isStateSystemTable = (tableName: string) => stateSystemTables.some((_) => _.sqliteDef.name === tableName)
|
|
@@ -1,5 +1,8 @@
|
|
|
1
|
+
import { objectToString } from '@livestore/utils'
|
|
2
|
+
|
|
1
3
|
import { Schema } from '@livestore/utils/effect'
|
|
2
|
-
import { describe, expect, it } from 'vitest'
|
|
4
|
+
import { describe, expect, expectTypeOf, it } from 'vitest'
|
|
5
|
+
|
|
3
6
|
import { State } from '../../mod.ts'
|
|
4
7
|
|
|
5
8
|
describe('table function overloads', () => {
|
|
@@ -79,11 +82,11 @@ describe('table function overloads', () => {
|
|
|
79
82
|
expect(todosTable.sqliteDef.columns).toHaveProperty('optionalComplex')
|
|
80
83
|
|
|
81
84
|
expect(todosTable.sqliteDef.columns.optionalBoolean.nullable).toBe(true)
|
|
82
|
-
expect(todosTable.sqliteDef.columns.optionalBoolean.schema
|
|
85
|
+
expect(objectToString(todosTable.sqliteDef.columns.optionalBoolean.schema)).toBe('(number <-> boolean) | null')
|
|
83
86
|
expect((todosTable.rowSchema as any).fields.optionalBoolean.toString()).toBe('(number <-> boolean) | null')
|
|
84
87
|
|
|
85
88
|
expect(todosTable.sqliteDef.columns.optionalComplex.nullable).toBe(true)
|
|
86
|
-
expect(todosTable.sqliteDef.columns.optionalComplex.schema
|
|
89
|
+
expect(objectToString(todosTable.sqliteDef.columns.optionalComplex.schema)).toBe(
|
|
87
90
|
'(parseJson <-> { readonly color: string } | undefined) | null',
|
|
88
91
|
)
|
|
89
92
|
expect((todosTable.rowSchema as any).fields.optionalComplex.toString()).toBe(
|
|
@@ -91,6 +94,22 @@ describe('table function overloads', () => {
|
|
|
91
94
|
)
|
|
92
95
|
})
|
|
93
96
|
|
|
97
|
+
it('should allow explicit first two generic arguments without options generic', () => {
|
|
98
|
+
const columns = {
|
|
99
|
+
id: State.SQLite.text({ primaryKey: true }),
|
|
100
|
+
text: State.SQLite.text({ default: '' }),
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const todosTable = State.SQLite.table<'todos', typeof columns>({
|
|
104
|
+
name: 'todos',
|
|
105
|
+
columns,
|
|
106
|
+
})
|
|
107
|
+
|
|
108
|
+
expect(todosTable.sqliteDef.name).toBe('todos')
|
|
109
|
+
expect(todosTable.sqliteDef.columns).toHaveProperty('id')
|
|
110
|
+
expect(todosTable.sqliteDef.columns).toHaveProperty('text')
|
|
111
|
+
})
|
|
112
|
+
|
|
94
113
|
it('should work with schema parameter', () => {
|
|
95
114
|
const TodoSchema = Schema.Struct({
|
|
96
115
|
id: Schema.String,
|
|
@@ -300,4 +319,96 @@ describe('table function overloads', () => {
|
|
|
300
319
|
expect(userTable.sqliteDef.columns.metadata.columnType).toBe('text')
|
|
301
320
|
expect(userTable.sqliteDef.columns.metadata.nullable).toBe(true)
|
|
302
321
|
})
|
|
322
|
+
|
|
323
|
+
it('should allow omitting nullable fields in insert()', () => {
|
|
324
|
+
const UserSchema = Schema.Struct({
|
|
325
|
+
id: Schema.String.pipe(State.SQLite.withPrimaryKey),
|
|
326
|
+
undefined: Schema.Undefined,
|
|
327
|
+
null: Schema.Null,
|
|
328
|
+
undefinedOrString: Schema.UndefinedOr(Schema.String),
|
|
329
|
+
nullOrString: Schema.NullOr(Schema.String),
|
|
330
|
+
optionalString: Schema.optional(Schema.String),
|
|
331
|
+
optionalNullOrString: Schema.optional(Schema.NullOr(Schema.String)),
|
|
332
|
+
})
|
|
333
|
+
|
|
334
|
+
const usersTable = State.SQLite.table({
|
|
335
|
+
name: 'users',
|
|
336
|
+
schema: UserSchema,
|
|
337
|
+
})
|
|
338
|
+
|
|
339
|
+
// Non-nullable fields (id) are required — omitting id should be rejected
|
|
340
|
+
expectTypeOf<{ undefined: undefined }>().not.toExtend<Parameters<typeof usersTable.insert>[0]>()
|
|
341
|
+
|
|
342
|
+
// Nullable fields (NullOr, optional+NullOr) are omittable — SQL defaults to NULL
|
|
343
|
+
expectTypeOf(usersTable.insert)
|
|
344
|
+
.toBeCallableWith({ id: '1' })
|
|
345
|
+
.toBeCallableWith({ id: '1', undefined: undefined })
|
|
346
|
+
.toBeCallableWith({ id: '1', undefined: undefined, null: null })
|
|
347
|
+
.toBeCallableWith({ id: '1', undefined: undefined, null: null, undefinedOrString: undefined })
|
|
348
|
+
.toBeCallableWith({ id: '1', undefined: undefined, null: null, undefinedOrString: 'string' })
|
|
349
|
+
.toBeCallableWith({ id: '1', undefined: undefined, null: null, undefinedOrString: 'string', nullOrString: null })
|
|
350
|
+
.toBeCallableWith({ id: '1', undefined: undefined, null: null, undefinedOrString: 'string', nullOrString: 'string' })
|
|
351
|
+
.toBeCallableWith({ id: '1', undefined: undefined, null: null, undefinedOrString: 'string', nullOrString: 'string', optionalString: 'string' })
|
|
352
|
+
.toBeCallableWith({ id: '1', undefined: undefined, null: null, undefinedOrString: 'string', nullOrString: 'string', optionalString: 'string', optionalNullOrString: null })
|
|
353
|
+
.toBeCallableWith({ id: '1', undefined: undefined, null: null, undefinedOrString: 'string', nullOrString: 'string', optionalString: 'string', optionalNullOrString: 'string' })
|
|
354
|
+
|
|
355
|
+
expect(() => usersTable.insert({ id: '1' }).asSql()).not.toThrow()
|
|
356
|
+
expect(() => usersTable.insert({ id: '1', undefined: undefined }).asSql()).not.toThrow()
|
|
357
|
+
expect(() => usersTable.insert({ id: '1', undefined: undefined, null: null }).asSql()).not.toThrow()
|
|
358
|
+
expect(() => usersTable.insert({ id: '1', undefined: undefined, null: null, undefinedOrString: undefined }).asSql()).not.toThrow()
|
|
359
|
+
expect(() => usersTable.insert({ id: '1', undefined: undefined, null: null, undefinedOrString: 'string' }).asSql()).not.toThrow()
|
|
360
|
+
expect(() => usersTable.insert({ id: '1', undefined: undefined, null: null, undefinedOrString: 'string', nullOrString: null }).asSql()).not.toThrow()
|
|
361
|
+
expect(() => usersTable.insert({ id: '1', undefined: undefined, null: null, undefinedOrString: 'string', nullOrString: 'string' }).asSql()).not.toThrow()
|
|
362
|
+
expect(() => usersTable.insert({ id: '1', undefined: undefined, null: null, undefinedOrString: 'string', nullOrString: 'string', optionalString: 'string' }).asSql()).not.toThrow()
|
|
363
|
+
expect(() => usersTable.insert({ id: '1', undefined: undefined, null: null, undefinedOrString: 'string', nullOrString: 'string', optionalString: 'string', optionalNullOrString: null }).asSql()).not.toThrow()
|
|
364
|
+
expect(() => usersTable.insert({ id: '1', undefined: undefined, null: null, undefinedOrString: 'string', nullOrString: 'string', optionalString: 'string', optionalNullOrString: 'string' }).asSql()).not.toThrow()
|
|
365
|
+
})
|
|
366
|
+
|
|
367
|
+
it('supports discriminated unions with parsed JSON payloads', () => {
|
|
368
|
+
const CircleDataSchema = Schema.Struct({
|
|
369
|
+
radius: Schema.Number,
|
|
370
|
+
})
|
|
371
|
+
const CircleSchema = Schema.Struct({
|
|
372
|
+
kind: Schema.Literal('circle'),
|
|
373
|
+
data: Schema.parseJson(CircleDataSchema),
|
|
374
|
+
})
|
|
375
|
+
|
|
376
|
+
const SquareDataSchema = Schema.Struct({
|
|
377
|
+
sideLength: Schema.Number,
|
|
378
|
+
})
|
|
379
|
+
const SquareSchema = Schema.Struct({
|
|
380
|
+
kind: Schema.Literal('square'),
|
|
381
|
+
data: Schema.parseJson(SquareDataSchema),
|
|
382
|
+
})
|
|
383
|
+
|
|
384
|
+
const ShapeSchema = Schema.Union(CircleSchema, SquareSchema)
|
|
385
|
+
|
|
386
|
+
const shapes = State.SQLite.table({
|
|
387
|
+
name: 'shapes',
|
|
388
|
+
schema: ShapeSchema,
|
|
389
|
+
})
|
|
390
|
+
|
|
391
|
+
expect(shapes.sqliteDef.columns.kind.columnType).toBe('text')
|
|
392
|
+
|
|
393
|
+
const kindSchema = objectToString(shapes.sqliteDef.columns.kind.schema)
|
|
394
|
+
expect(kindSchema).toContain('"circle" | "square"')
|
|
395
|
+
|
|
396
|
+
expect(() =>
|
|
397
|
+
shapes
|
|
398
|
+
.insert({
|
|
399
|
+
kind: 'square',
|
|
400
|
+
data: { sideLength: 10 },
|
|
401
|
+
})
|
|
402
|
+
.asSql(),
|
|
403
|
+
).not.toThrow()
|
|
404
|
+
|
|
405
|
+
expect(() =>
|
|
406
|
+
shapes
|
|
407
|
+
.insert({
|
|
408
|
+
kind: 'circle',
|
|
409
|
+
data: { radius: 5 },
|
|
410
|
+
})
|
|
411
|
+
.asSql(),
|
|
412
|
+
).not.toThrow()
|
|
413
|
+
})
|
|
303
414
|
})
|
|
@@ -168,10 +168,7 @@ export function table<
|
|
|
168
168
|
name: TName
|
|
169
169
|
schema: TSchema
|
|
170
170
|
} & Partial<TOptionsInput>,
|
|
171
|
-
): TableDef<
|
|
172
|
-
SqliteTableDefForSchemaInput<TName, Schema.Schema.Type<TSchema>, Schema.Schema.Encoded<TSchema>, TSchema>,
|
|
173
|
-
TableOptions
|
|
174
|
-
>
|
|
171
|
+
): TableDef<SqliteTableDefForSchemaInput<TName, Schema.Schema.Type<TSchema>, Schema.Schema.Encoded<TSchema>, TSchema>>
|
|
175
172
|
|
|
176
173
|
// Overload 3: With schema and no name (uses schema annotations)
|
|
177
174
|
export function table<
|
|
@@ -181,10 +178,7 @@ export function table<
|
|
|
181
178
|
args: {
|
|
182
179
|
schema: TSchema
|
|
183
180
|
} & Partial<TOptionsInput>,
|
|
184
|
-
): TableDef<
|
|
185
|
-
SqliteTableDefForSchemaInput<string, Schema.Schema.Type<TSchema>, Schema.Schema.Encoded<TSchema>, TSchema>,
|
|
186
|
-
TableOptions
|
|
187
|
-
>
|
|
181
|
+
): TableDef<SqliteTableDefForSchemaInput<string, Schema.Schema.Type<TSchema>, Schema.Schema.Encoded<TSchema>, TSchema>>
|
|
188
182
|
|
|
189
183
|
// Implementation
|
|
190
184
|
export function table<
|
|
@@ -216,9 +210,7 @@ export function table<
|
|
|
216
210
|
if ('columns' in args) {
|
|
217
211
|
tableName = args.name
|
|
218
212
|
const columnOrColumns = args.columns
|
|
219
|
-
columns = (
|
|
220
|
-
SqliteDsl.isColumnDefinition(columnOrColumns) ? { value: columnOrColumns } : columnOrColumns
|
|
221
|
-
) as SqliteDsl.Columns
|
|
213
|
+
columns = SqliteDsl.isColumnDefinition(columnOrColumns) === true ? { value: columnOrColumns } : columnOrColumns
|
|
222
214
|
additionalIndexes = []
|
|
223
215
|
} else if ('schema' in args) {
|
|
224
216
|
const result = schemaFieldsToColumns(Schema.getResolvedPropertySignatures(args.schema))
|
|
@@ -377,18 +369,20 @@ export type ToColumns<TColumns extends SqliteDsl.Columns | SqliteDsl.ColumnDefin
|
|
|
377
369
|
: never
|
|
378
370
|
|
|
379
371
|
export declare namespace SchemaToColumns {
|
|
372
|
+
/** Checks if `null` or `undefined` is assignable to `T`, matching the runtime nullable detection. */
|
|
373
|
+
type IsNullable<T> = null extends T ? true : undefined extends T ? true : false
|
|
374
|
+
|
|
380
375
|
// Type helper to create column definition with proper schema
|
|
381
|
-
export type ColumnDefForType<TEncoded, TType> = SqliteDsl.ColumnDefinition<TEncoded, TType
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
: SqliteDsl.Columns
|
|
376
|
+
export type ColumnDefForType<TEncoded, TType> = SqliteDsl.ColumnDefinition<TEncoded, TType, IsNullable<TEncoded>>
|
|
377
|
+
|
|
378
|
+
export type FromTypes<TType, TEncoded> =
|
|
379
|
+
TEncoded extends Record<string, any>
|
|
380
|
+
? {
|
|
381
|
+
[K in keyof TEncoded]-?: ColumnDefForType<TEncoded[K],
|
|
382
|
+
TType extends Record<string, any> ? (K extends keyof TType ? TType[K] : TEncoded[K]) : TEncoded[K]
|
|
383
|
+
>
|
|
384
|
+
}
|
|
385
|
+
: SqliteDsl.Columns
|
|
392
386
|
}
|
|
393
387
|
|
|
394
388
|
export declare namespace TableDefInput {
|