@livestore/common 0.4.0 → 0.5.0-dev.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 +1 -1
- package/dist/ClientSessionLeaderThreadProxy.d.ts.map +1 -1
- package/dist/MaterializationJournal.d.ts +44 -0
- package/dist/MaterializationJournal.d.ts.map +1 -0
- package/dist/MaterializationJournal.js +112 -0
- package/dist/MaterializationJournal.js.map +1 -0
- package/dist/StateHead.d.ts +26 -0
- package/dist/StateHead.d.ts.map +1 -0
- package/dist/StateHead.js +50 -0
- package/dist/StateHead.js.map +1 -0
- package/dist/WorkerTransportError.d.ts +3 -3
- package/dist/WorkerTransportError.d.ts.map +1 -1
- package/dist/WorkerTransportError.js +3 -3
- package/dist/WorkerTransportError.js.map +1 -1
- package/dist/__tests__/fixture.d.ts +1 -1
- package/dist/__tests__/fixture.d.ts.map +1 -1
- package/dist/__tests__/fixture.js +3 -3
- package/dist/__tests__/fixture.js.map +1 -1
- package/dist/adapter-types.d.ts +29 -57
- package/dist/adapter-types.d.ts.map +1 -1
- package/dist/adapter-types.js +20 -37
- package/dist/adapter-types.js.map +1 -1
- package/dist/debug-info.d.ts +56 -56
- package/dist/debug-info.d.ts.map +1 -1
- package/dist/debug-info.js +28 -41
- package/dist/debug-info.js.map +1 -1
- package/dist/defs.d.ts +9 -9
- package/dist/defs.js +2 -2
- package/dist/devtools/devtools-compatibility.test.js +1 -0
- package/dist/devtools/devtools-compatibility.test.js.map +1 -1
- package/dist/devtools/devtools-messages-client-session.d.ts +520 -332
- package/dist/devtools/devtools-messages-client-session.d.ts.map +1 -1
- package/dist/devtools/devtools-messages-client-session.js +76 -74
- package/dist/devtools/devtools-messages-client-session.js.map +1 -1
- package/dist/devtools/devtools-messages-common.d.ts +27 -27
- package/dist/devtools/devtools-messages-common.d.ts.map +1 -1
- package/dist/devtools/devtools-messages-common.js +5 -5
- package/dist/devtools/devtools-messages-common.js.map +1 -1
- package/dist/devtools/devtools-messages-leader.d.ts +405 -343
- package/dist/devtools/devtools-messages-leader.d.ts.map +1 -1
- package/dist/devtools/devtools-messages-leader.js +101 -89
- package/dist/devtools/devtools-messages-leader.js.map +1 -1
- package/dist/devtools/devtools-sessioninfo.d.ts +18 -19
- package/dist/devtools/devtools-sessioninfo.d.ts.map +1 -1
- package/dist/devtools/devtools-sessioninfo.js +8 -5
- package/dist/devtools/devtools-sessioninfo.js.map +1 -1
- package/dist/devtools/mod.d.ts +4 -5
- package/dist/devtools/mod.d.ts.map +1 -1
- package/dist/devtools/mod.js +9 -5
- package/dist/devtools/mod.js.map +1 -1
- package/dist/errors.d.ts +45 -69
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +18 -16
- 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 +66 -18
- package/dist/leader-thread/LeaderSyncProcessor.d.ts.map +1 -1
- package/dist/leader-thread/LeaderSyncProcessor.js +519 -461
- package/dist/leader-thread/LeaderSyncProcessor.js.map +1 -1
- package/dist/leader-thread/RejectedPushError.d.ts +67 -36
- package/dist/leader-thread/RejectedPushError.d.ts.map +1 -1
- package/dist/leader-thread/RejectedPushError.js +24 -5
- package/dist/leader-thread/RejectedPushError.js.map +1 -1
- package/dist/leader-thread/connection.d.ts +1 -0
- package/dist/leader-thread/connection.d.ts.map +1 -1
- package/dist/leader-thread/connection.js +9 -8
- package/dist/leader-thread/connection.js.map +1 -1
- package/dist/leader-thread/eventlog.d.ts +4 -4
- package/dist/leader-thread/eventlog.d.ts.map +1 -1
- package/dist/leader-thread/eventlog.js +6 -6
- package/dist/leader-thread/eventlog.js.map +1 -1
- 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 +33 -17
- package/dist/leader-thread/leader-worker-devtools.js.map +1 -1
- package/dist/leader-thread/make-leader-thread-layer.d.ts +9 -5
- package/dist/leader-thread/make-leader-thread-layer.d.ts.map +1 -1
- package/dist/leader-thread/make-leader-thread-layer.js +25 -35
- package/dist/leader-thread/make-leader-thread-layer.js.map +1 -1
- package/dist/leader-thread/make-leader-thread-layer.test.js +7 -7
- package/dist/leader-thread/make-leader-thread-layer.test.js.map +1 -1
- package/dist/leader-thread/materialize-event.d.ts +2 -1
- package/dist/leader-thread/materialize-event.d.ts.map +1 -1
- package/dist/leader-thread/materialize-event.js +4 -0
- package/dist/leader-thread/materialize-event.js.map +1 -1
- package/dist/leader-thread/recreate-db.d.ts.map +1 -1
- package/dist/leader-thread/recreate-db.js +18 -39
- package/dist/leader-thread/recreate-db.js.map +1 -1
- package/dist/leader-thread/shutdown-channel.d.ts +2 -6
- package/dist/leader-thread/shutdown-channel.d.ts.map +1 -1
- package/dist/leader-thread/shutdown-channel.js +2 -3
- package/dist/leader-thread/shutdown-channel.js.map +1 -1
- package/dist/leader-thread/stream-events.d.ts +4 -7
- package/dist/leader-thread/stream-events.d.ts.map +1 -1
- package/dist/leader-thread/stream-events.js +13 -16
- package/dist/leader-thread/stream-events.js.map +1 -1
- package/dist/leader-thread/types.d.ts +32 -69
- package/dist/leader-thread/types.d.ts.map +1 -1
- package/dist/leader-thread/types.js +5 -5
- package/dist/leader-thread/types.js.map +1 -1
- package/dist/logging.d.ts +5 -30
- package/dist/logging.d.ts.map +1 -1
- package/dist/logging.js +1 -32
- package/dist/logging.js.map +1 -1
- package/dist/make-client-session.d.ts +1 -2
- package/dist/make-client-session.d.ts.map +1 -1
- package/dist/make-client-session.js +3 -3
- package/dist/make-client-session.js.map +1 -1
- package/dist/materializer-helper.d.ts +0 -1
- package/dist/materializer-helper.d.ts.map +1 -1
- package/dist/materializer-helper.js +7 -35
- package/dist/materializer-helper.js.map +1 -1
- package/dist/otel.d.ts +2 -3
- package/dist/otel.d.ts.map +1 -1
- package/dist/otel.js +2 -7
- package/dist/otel.js.map +1 -1
- package/dist/rematerialize-from-eventlog.d.ts.map +1 -1
- package/dist/rematerialize-from-eventlog.js +28 -26
- package/dist/rematerialize-from-eventlog.js.map +1 -1
- package/dist/schema/EventDef/define.d.ts +4 -4
- package/dist/schema/EventDef/define.d.ts.map +1 -1
- package/dist/schema/EventDef/define.js +5 -5
- package/dist/schema/EventDef/define.js.map +1 -1
- package/dist/schema/EventDef/define.test.d.ts +2 -0
- package/dist/schema/EventDef/define.test.d.ts.map +1 -0
- package/dist/schema/EventDef/define.test.js +23 -0
- package/dist/schema/EventDef/define.test.js.map +1 -0
- package/dist/schema/EventDef/deprecated.d.ts +8 -13
- package/dist/schema/EventDef/deprecated.d.ts.map +1 -1
- package/dist/schema/EventDef/deprecated.js +12 -13
- package/dist/schema/EventDef/deprecated.js.map +1 -1
- package/dist/schema/EventDef/deprecated.test.js +1 -1
- package/dist/schema/EventDef/deprecated.test.js.map +1 -1
- package/dist/schema/EventDef/event-def.d.ts +1 -1
- package/dist/schema/EventDef/event-def.d.ts.map +1 -1
- package/dist/schema/EventSequenceNumber/client.d.ts +12 -12
- package/dist/schema/EventSequenceNumber/client.d.ts.map +1 -1
- package/dist/schema/EventSequenceNumber/client.js +8 -9
- package/dist/schema/EventSequenceNumber/client.js.map +1 -1
- package/dist/schema/EventSequenceNumber/global.d.ts +2 -2
- package/dist/schema/EventSequenceNumber/global.d.ts.map +1 -1
- package/dist/schema/EventSequenceNumber/global.js +1 -1
- package/dist/schema/EventSequenceNumber/global.js.map +1 -1
- package/dist/schema/EventSequenceNumber.test.js +5 -5
- package/dist/schema/EventSequenceNumber.test.js.map +1 -1
- package/dist/schema/LiveStoreEvent/client.d.ts +50 -179
- package/dist/schema/LiveStoreEvent/client.d.ts.map +1 -1
- package/dist/schema/LiveStoreEvent/client.js +32 -29
- package/dist/schema/LiveStoreEvent/client.js.map +1 -1
- package/dist/schema/LiveStoreEvent/client.test.js +11 -2
- package/dist/schema/LiveStoreEvent/client.test.js.map +1 -1
- package/dist/schema/LiveStoreEvent/for-event-def.d.ts +7 -7
- package/dist/schema/LiveStoreEvent/for-event-def.d.ts.map +1 -1
- package/dist/schema/LiveStoreEvent/global.d.ts +6 -6
- package/dist/schema/LiveStoreEvent/global.d.ts.map +1 -1
- package/dist/schema/LiveStoreEvent/global.js +1 -1
- package/dist/schema/LiveStoreEvent/global.js.map +1 -1
- package/dist/schema/LiveStoreEvent/input.d.ts +5 -5
- package/dist/schema/LiveStoreEvent/input.d.ts.map +1 -1
- package/dist/schema/LiveStoreEvent/input.js +3 -3
- package/dist/schema/LiveStoreEvent/input.js.map +1 -1
- package/dist/schema/mod.d.ts +1 -0
- package/dist/schema/mod.d.ts.map +1 -1
- package/dist/schema/mod.js +1 -0
- package/dist/schema/mod.js.map +1 -1
- package/dist/schema/schema.d.ts.map +1 -1
- package/dist/schema/schema.js +3 -2
- package/dist/schema/schema.js.map +1 -1
- package/dist/schema/state/sqlite/client-document-def.d.ts +12 -17
- package/dist/schema/state/sqlite/client-document-def.d.ts.map +1 -1
- package/dist/schema/state/sqlite/client-document-def.js +23 -20
- package/dist/schema/state/sqlite/client-document-def.js.map +1 -1
- package/dist/schema/state/sqlite/client-document-def.test.js +29 -8
- package/dist/schema/state/sqlite/client-document-def.test.js.map +1 -1
- package/dist/schema/state/sqlite/column-annotations.d.ts +13 -13
- package/dist/schema/state/sqlite/column-annotations.d.ts.map +1 -1
- package/dist/schema/state/sqlite/column-annotations.js +13 -15
- package/dist/schema/state/sqlite/column-annotations.js.map +1 -1
- package/dist/schema/state/sqlite/column-annotations.test.js +19 -43
- package/dist/schema/state/sqlite/column-annotations.test.js.map +1 -1
- package/dist/schema/state/sqlite/column-def.d.ts +1 -1
- package/dist/schema/state/sqlite/column-def.d.ts.map +1 -1
- package/dist/schema/state/sqlite/column-def.js +57 -31
- package/dist/schema/state/sqlite/column-def.js.map +1 -1
- package/dist/schema/state/sqlite/column-def.test.js +118 -72
- package/dist/schema/state/sqlite/column-def.test.js.map +1 -1
- package/dist/schema/state/sqlite/column-spec.js.map +1 -1
- package/dist/schema/state/sqlite/column-spec.test.js +2 -2
- package/dist/schema/state/sqlite/db-schema/ast/sqlite.d.ts +2 -2
- package/dist/schema/state/sqlite/db-schema/ast/sqlite.d.ts.map +1 -1
- package/dist/schema/state/sqlite/db-schema/ast/sqlite.js +13 -4
- 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 +9 -9
- 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 +8 -13
- 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 +27 -16
- 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 +13 -11
- package/dist/schema/state/sqlite/db-schema/dsl/mod.d.ts.map +1 -1
- package/dist/schema/state/sqlite/db-schema/dsl/mod.js +5 -3
- package/dist/schema/state/sqlite/db-schema/dsl/mod.js.map +1 -1
- package/dist/schema/state/sqlite/mod.d.ts +1 -3
- package/dist/schema/state/sqlite/mod.d.ts.map +1 -1
- package/dist/schema/state/sqlite/mod.js +1 -1
- package/dist/schema/state/sqlite/mod.js.map +1 -1
- package/dist/schema/state/sqlite/persistence.d.ts +11 -0
- package/dist/schema/state/sqlite/persistence.d.ts.map +1 -0
- package/dist/schema/state/sqlite/persistence.js +10 -0
- package/dist/schema/state/sqlite/persistence.js.map +1 -0
- package/dist/schema/state/sqlite/query-builder/api.d.ts +7 -7
- 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 +27 -23
- package/dist/schema/state/sqlite/query-builder/astToSql.js.map +1 -1
- package/dist/schema/state/sqlite/query-builder/impl.d.ts +3 -1
- package/dist/schema/state/sqlite/query-builder/impl.d.ts.map +1 -1
- package/dist/schema/state/sqlite/query-builder/impl.js +16 -14
- package/dist/schema/state/sqlite/query-builder/impl.js.map +1 -1
- package/dist/schema/state/sqlite/query-builder/impl.test.js +362 -596
- package/dist/schema/state/sqlite/query-builder/impl.test.js.map +1 -1
- package/dist/schema/state/sqlite/schema-helpers.js +1 -1
- package/dist/schema/state/sqlite/schema-helpers.js.map +1 -1
- package/dist/schema/state/sqlite/system-tables/eventlog-tables.d.ts +102 -134
- package/dist/schema/state/sqlite/system-tables/eventlog-tables.d.ts.map +1 -1
- package/dist/schema/state/sqlite/system-tables/eventlog-tables.js +2 -2
- package/dist/schema/state/sqlite/system-tables/eventlog-tables.js.map +1 -1
- package/dist/schema/state/sqlite/system-tables/state-tables.d.ts +328 -106
- package/dist/schema/state/sqlite/system-tables/state-tables.d.ts.map +1 -1
- package/dist/schema/state/sqlite/system-tables/state-tables.js +33 -1
- package/dist/schema/state/sqlite/system-tables/state-tables.js.map +1 -1
- package/dist/schema/state/sqlite/table-def.d.ts +16 -19
- package/dist/schema/state/sqlite/table-def.d.ts.map +1 -1
- package/dist/schema/state/sqlite/table-def.js +53 -3
- package/dist/schema/state/sqlite/table-def.js.map +1 -1
- package/dist/schema/state/sqlite/table-def.test.js +153 -36
- package/dist/schema/state/sqlite/table-def.test.js.map +1 -1
- package/dist/schema/unknown-events.d.ts.map +1 -1
- package/dist/schema/unknown-events.js +2 -1
- package/dist/schema/unknown-events.js.map +1 -1
- package/dist/schema-management/__tests__/migrations-autoincrement-quoting.test.js +2 -2
- package/dist/session-id-symbol.d.ts +29 -0
- package/dist/session-id-symbol.d.ts.map +1 -0
- package/dist/session-id-symbol.js +44 -0
- package/dist/session-id-symbol.js.map +1 -0
- package/dist/sql-queries/sql-queries.d.ts.map +1 -1
- package/dist/sql-queries/sql-queries.js +8 -10
- package/dist/sql-queries/sql-queries.js.map +1 -1
- package/dist/sql-queries/types.d.ts +6 -7
- package/dist/sql-queries/types.d.ts.map +1 -1
- package/dist/sql-queries/types.js.map +1 -1
- package/dist/sqlite-db-helper.d.ts +21 -1
- package/dist/sqlite-db-helper.d.ts.map +1 -1
- package/dist/sqlite-db-helper.js +37 -2
- package/dist/sqlite-db-helper.js.map +1 -1
- package/dist/sqlite-types.d.ts +3 -6
- package/dist/sqlite-types.d.ts.map +1 -1
- package/dist/sqlite-types.js +3 -3
- package/dist/sqlite-types.js.map +1 -1
- package/dist/sync/ClientSessionSyncProcessor.d.ts +38 -16
- package/dist/sync/ClientSessionSyncProcessor.d.ts.map +1 -1
- package/dist/sync/ClientSessionSyncProcessor.js +196 -66
- package/dist/sync/ClientSessionSyncProcessor.js.map +1 -1
- package/dist/sync/errors.d.ts +12 -18
- package/dist/sync/errors.d.ts.map +1 -1
- package/dist/sync/errors.js +2 -2
- package/dist/sync/errors.js.map +1 -1
- package/dist/sync/mock-sync-backend.d.ts +2 -3
- package/dist/sync/mock-sync-backend.d.ts.map +1 -1
- package/dist/sync/mock-sync-backend.js +54 -33
- package/dist/sync/mock-sync-backend.js.map +1 -1
- package/dist/sync/mock-sync-backend.test.d.ts +2 -0
- package/dist/sync/mock-sync-backend.test.d.ts.map +1 -0
- package/dist/sync/mock-sync-backend.test.js +49 -0
- package/dist/sync/mock-sync-backend.test.js.map +1 -0
- package/dist/sync/next/history-dag-common.d.ts +4 -0
- package/dist/sync/next/history-dag-common.d.ts.map +1 -1
- package/dist/sync/next/history-dag-common.js +52 -31
- 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 -1
- package/dist/sync/next/history-dag.js.map +1 -1
- package/dist/sync/next/test/compact-events.calculator.test.js +2 -2
- package/dist/sync/next/test/event-fixtures.d.ts +7 -7
- package/dist/sync/next/test/event-fixtures.js +1 -1
- package/dist/sync/next/test/event-fixtures.js.map +1 -1
- package/dist/sync/next/test/history-dag-common.test.d.ts +2 -0
- package/dist/sync/next/test/history-dag-common.test.d.ts.map +1 -0
- package/dist/sync/next/test/history-dag-common.test.js +73 -0
- package/dist/sync/next/test/history-dag-common.test.js.map +1 -0
- package/dist/sync/sync-backend-kv.d.ts.map +1 -1
- package/dist/sync/sync-backend-kv.js +4 -2
- package/dist/sync/sync-backend-kv.js.map +1 -1
- package/dist/sync/sync-backend.d.ts +15 -15
- package/dist/sync/sync-backend.d.ts.map +1 -1
- package/dist/sync/sync-backend.js +9 -5
- package/dist/sync/sync-backend.js.map +1 -1
- package/dist/sync/sync.d.ts +1 -1
- package/dist/sync/sync.d.ts.map +1 -1
- package/dist/sync/syncstate.d.ts +97 -173
- package/dist/sync/syncstate.d.ts.map +1 -1
- package/dist/sync/syncstate.js +34 -37
- package/dist/sync/syncstate.js.map +1 -1
- package/dist/sync/syncstate.test.js +100 -61
- package/dist/sync/syncstate.test.js.map +1 -1
- package/dist/sync/transport-chunking.d.ts +15 -16
- package/dist/sync/transport-chunking.d.ts.map +1 -1
- package/dist/sync/transport-chunking.js +23 -32
- package/dist/sync/transport-chunking.js.map +1 -1
- package/dist/util.d.ts +11 -4
- package/dist/util.d.ts.map +1 -1
- package/dist/util.js +19 -2
- package/dist/util.js.map +1 -1
- package/dist/version.d.ts.map +1 -1
- package/dist/version.js.map +1 -1
- package/package.json +19 -37
- package/src/ClientSessionLeaderThreadProxy.ts +1 -1
- package/src/MaterializationJournal.ts +184 -0
- package/src/StateHead.ts +80 -0
- package/src/WorkerTransportError.ts +4 -4
- package/src/__tests__/fixture.ts +3 -3
- package/src/adapter-types.ts +24 -61
- package/src/debug-info.ts +50 -70
- package/src/defs.ts +2 -2
- package/src/devtools/devtools-compatibility.test.ts +1 -0
- package/src/devtools/devtools-messages-client-session.ts +56 -65
- package/src/devtools/devtools-messages-common.ts +12 -11
- package/src/devtools/devtools-messages-leader.ts +71 -69
- package/src/devtools/devtools-sessioninfo.ts +13 -11
- package/src/devtools/mod.ts +4 -5
- package/src/errors.ts +46 -34
- package/src/index.ts +8 -1
- package/src/leader-thread/LeaderSyncProcessor.ts +794 -691
- package/src/leader-thread/RejectedPushError.ts +40 -27
- package/src/leader-thread/connection.ts +12 -8
- package/src/leader-thread/eventlog.ts +7 -7
- package/src/leader-thread/leader-worker-devtools.ts +37 -19
- package/src/leader-thread/make-leader-thread-layer.test.ts +7 -7
- package/src/leader-thread/make-leader-thread-layer.ts +56 -53
- package/src/leader-thread/materialize-event.ts +13 -8
- package/src/leader-thread/recreate-db.ts +24 -59
- package/src/leader-thread/shutdown-channel.ts +3 -14
- package/src/leader-thread/stream-events.ts +104 -101
- package/src/leader-thread/types.ts +24 -62
- package/src/logging.ts +5 -52
- package/src/make-client-session.ts +6 -6
- package/src/materializer-helper.ts +8 -37
- package/src/otel.ts +5 -14
- package/src/rematerialize-from-eventlog.ts +97 -94
- package/src/schema/EventDef/define.test.ts +28 -0
- package/src/schema/EventDef/define.ts +20 -19
- package/src/schema/EventDef/deprecated.test.ts +1 -8
- package/src/schema/EventDef/deprecated.ts +17 -20
- package/src/schema/EventDef/event-def.ts +2 -4
- package/src/schema/EventSequenceNumber/client.ts +8 -9
- package/src/schema/EventSequenceNumber/global.ts +1 -1
- package/src/schema/EventSequenceNumber.test.ts +5 -5
- package/src/schema/LiveStoreEvent/client.test.ts +17 -4
- package/src/schema/LiveStoreEvent/client.ts +36 -35
- package/src/schema/LiveStoreEvent/for-event-def.ts +7 -7
- package/src/schema/LiveStoreEvent/global.ts +1 -1
- package/src/schema/LiveStoreEvent/input.ts +6 -6
- package/src/schema/mod.ts +1 -0
- package/src/schema/schema.ts +3 -2
- package/src/schema/state/sqlite/client-document-def.test.ts +32 -13
- package/src/schema/state/sqlite/client-document-def.ts +95 -80
- package/src/schema/state/sqlite/column-annotations.test.ts +26 -45
- package/src/schema/state/sqlite/column-annotations.ts +26 -30
- package/src/schema/state/sqlite/column-def.test.ts +132 -77
- package/src/schema/state/sqlite/column-def.ts +72 -37
- package/src/schema/state/sqlite/column-spec.test.ts +2 -2
- package/src/schema/state/sqlite/column-spec.ts +3 -2
- package/src/schema/state/sqlite/db-schema/ast/sqlite.ts +15 -5
- package/src/schema/state/sqlite/db-schema/dsl/__snapshots__/field-defs.test.ts.snap +123 -63
- package/src/schema/state/sqlite/db-schema/dsl/field-defs.test.ts +35 -16
- package/src/schema/state/sqlite/db-schema/dsl/field-defs.ts +25 -31
- package/src/schema/state/sqlite/db-schema/dsl/mod.ts +35 -21
- package/src/schema/state/sqlite/mod.ts +2 -4
- package/src/schema/state/sqlite/persistence.ts +11 -0
- package/src/schema/state/sqlite/query-builder/api.ts +9 -9
- package/src/schema/state/sqlite/query-builder/astToSql.ts +31 -26
- package/src/schema/state/sqlite/query-builder/impl.test.ts +433 -669
- package/src/schema/state/sqlite/query-builder/impl.ts +19 -15
- package/src/schema/state/sqlite/schema-helpers.ts +1 -1
- package/src/schema/state/sqlite/system-tables/eventlog-tables.ts +2 -2
- package/src/schema/state/sqlite/system-tables/state-tables.ts +41 -1
- package/src/schema/state/sqlite/table-def.test.ts +204 -66
- package/src/schema/state/sqlite/table-def.ts +96 -45
- package/src/schema/unknown-events.ts +3 -2
- package/src/schema-management/__tests__/migrations-autoincrement-quoting.test.ts +2 -2
- package/src/session-id-symbol.ts +59 -0
- package/src/sql-queries/sql-queries.ts +8 -12
- package/src/sql-queries/types.ts +6 -7
- package/src/sqlite-db-helper.ts +64 -2
- package/src/sqlite-types.ts +5 -8
- package/src/sync/ClientSessionSyncProcessor.ts +303 -119
- package/src/sync/errors.ts +14 -12
- package/src/sync/mock-sync-backend.test.ts +78 -0
- package/src/sync/mock-sync-backend.ts +93 -47
- package/src/sync/next/history-dag-common.ts +60 -34
- package/src/sync/next/history-dag.ts +4 -1
- package/src/sync/next/test/compact-events.calculator.test.ts +2 -2
- package/src/sync/next/test/event-fixtures.ts +1 -1
- package/src/sync/next/test/history-dag-common.test.ts +87 -0
- package/src/sync/sync-backend-kv.ts +4 -2
- package/src/sync/sync-backend.ts +15 -15
- package/src/sync/sync.ts +1 -1
- package/src/sync/syncstate.test.ts +191 -140
- package/src/sync/syncstate.ts +63 -53
- package/src/sync/transport-chunking.ts +34 -39
- package/src/util.ts +18 -9
- package/src/version.ts +1 -2
- package/dist/sql-queries/misc.d.ts +0 -2
- package/dist/sql-queries/misc.d.ts.map +0 -1
- package/dist/sql-queries/misc.js +0 -2
- package/dist/sql-queries/misc.js.map +0 -1
- package/src/sql-queries/misc.ts +0 -2
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { shouldNeverHappen } from '@livestore/utils'
|
|
2
|
-
import type
|
|
3
|
-
import { Schema } from '@livestore/utils/effect'
|
|
2
|
+
import { type Option, type Types, Schema, SchemaGetter, Struct } from '@livestore/utils/effect'
|
|
4
3
|
|
|
5
|
-
import { SessionIdSymbol } from '../../../
|
|
4
|
+
import { SessionIdSymbol } from '../../../session-id-symbol.ts'
|
|
6
5
|
import { sql } from '../../../util.ts'
|
|
7
6
|
import type { EventDef, Materializer } from '../../EventDef/mod.ts'
|
|
8
7
|
import { defineEvent, defineMaterializer } from '../../EventDef/mod.ts'
|
|
@@ -47,7 +46,7 @@ export const clientDocument = <
|
|
|
47
46
|
...inputOptions
|
|
48
47
|
}: {
|
|
49
48
|
name: TName
|
|
50
|
-
schema: Schema.
|
|
49
|
+
schema: Schema.Codec<TType, TEncoded>
|
|
51
50
|
} & TOptions): ClientDocumentTableDef<
|
|
52
51
|
TName,
|
|
53
52
|
TType,
|
|
@@ -61,6 +60,7 @@ export const clientDocument = <
|
|
|
61
60
|
value: inputOptions.default.value,
|
|
62
61
|
},
|
|
63
62
|
} satisfies ClientDocumentTableOptions<TType>
|
|
63
|
+
const canPartialSet = options.partialSet === true && Schema.getResolvedPropertySignatures(valueSchema).length > 0
|
|
64
64
|
|
|
65
65
|
// Column needs optimistic schema to read historical data formats
|
|
66
66
|
const optimisticColumnSchema = createOptimisticEventSchema({
|
|
@@ -83,7 +83,7 @@ export const clientDocument = <
|
|
|
83
83
|
name,
|
|
84
84
|
valueSchema,
|
|
85
85
|
defaultValue: options.default.value,
|
|
86
|
-
partialSet:
|
|
86
|
+
partialSet: canPartialSet,
|
|
87
87
|
})
|
|
88
88
|
|
|
89
89
|
const setEventDef = (...args: any[]) => {
|
|
@@ -95,8 +95,8 @@ export const clientDocument = <
|
|
|
95
95
|
Object.defineProperty(setEventDef, 'schema', {
|
|
96
96
|
value: Schema.Struct({
|
|
97
97
|
id: Schema.String,
|
|
98
|
-
value:
|
|
99
|
-
}).
|
|
98
|
+
value: canPartialSet === true ? partialStructSchema(valueSchema) : valueSchema,
|
|
99
|
+
}).annotate({ title: `${name}Set:Args` }) as Schema.Codec<any, any>,
|
|
100
100
|
})
|
|
101
101
|
Object.defineProperty(setEventDef, 'options', {
|
|
102
102
|
value: { derived: true, clientOnly: true, facts: undefined, deprecated: undefined },
|
|
@@ -158,6 +158,19 @@ export const mergeDefaultValues = <T>(defaultValues: T, explicitDefaultValues: T
|
|
|
158
158
|
}, {} as any)
|
|
159
159
|
}
|
|
160
160
|
|
|
161
|
+
const partialStructSchema = (schema: Schema.Codec<any, any>): Schema.Codec<any, any> =>
|
|
162
|
+
(schema as unknown as Schema.Struct<Schema.Struct.Fields>).mapFields(
|
|
163
|
+
Struct.map(Schema.optional),
|
|
164
|
+
) as unknown as Schema.Codec<any, any>
|
|
165
|
+
|
|
166
|
+
const pickStructSchema = (
|
|
167
|
+
schema: Schema.Codec<any, any>,
|
|
168
|
+
keys: ReadonlyArray<string>,
|
|
169
|
+
): Schema.Codec<Record<string, unknown>, Record<string, unknown>> =>
|
|
170
|
+
(schema as unknown as Schema.Struct<Schema.Struct.Fields>).mapFields(
|
|
171
|
+
Struct.pick(keys as readonly any[]),
|
|
172
|
+
) as unknown as Schema.Codec<Record<string, unknown>, Record<string, unknown>>
|
|
173
|
+
|
|
161
174
|
/**
|
|
162
175
|
* Creates an optimistic schema that accepts historical event formats
|
|
163
176
|
* and transforms them to the current schema, preserving data and intent.
|
|
@@ -182,88 +195,90 @@ export const createOptimisticEventSchema = ({
|
|
|
182
195
|
defaultValue,
|
|
183
196
|
partialSet,
|
|
184
197
|
}: {
|
|
185
|
-
valueSchema: Schema.
|
|
198
|
+
valueSchema: Schema.Codec<any, any>
|
|
186
199
|
defaultValue: any
|
|
187
200
|
partialSet: boolean
|
|
188
|
-
}) => {
|
|
189
|
-
const
|
|
201
|
+
}): Schema.Codec<any, unknown> => {
|
|
202
|
+
const canPartialSet = partialSet === true && Schema.getResolvedPropertySignatures(valueSchema).length > 0
|
|
203
|
+
const targetSchema = canPartialSet === true ? partialStructSchema(valueSchema) : valueSchema
|
|
190
204
|
// The transform decode must yield values in the target schema's ENCODED shape.
|
|
191
205
|
// This keeps JSON columns consistent when Encoded != Type (e.g. Option).
|
|
192
206
|
const encodeTarget = Schema.encodeSync(targetSchema)
|
|
193
207
|
|
|
194
|
-
return Schema.
|
|
195
|
-
Schema.
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
208
|
+
return Schema.Unknown.pipe(
|
|
209
|
+
Schema.decodeTo(
|
|
210
|
+
targetSchema, // Output current schema
|
|
211
|
+
{
|
|
212
|
+
decode: SchemaGetter.transform((eventValue) => {
|
|
213
|
+
// Try direct decode first (for current schema events)
|
|
214
|
+
try {
|
|
215
|
+
const decoded = Schema.decodeUnknownSync(targetSchema)(eventValue)
|
|
216
|
+
// Re-encode so downstream parseJson/column decoding sees encoded values.
|
|
217
|
+
return encodeTarget(decoded)
|
|
218
|
+
} catch {
|
|
219
|
+
// Optimistic decoding for historical events
|
|
220
|
+
|
|
221
|
+
// Handle null/undefined/non-object cases
|
|
222
|
+
if (typeof eventValue !== 'object' || eventValue === null) {
|
|
223
|
+
console.warn(
|
|
224
|
+
`Client document: Non-object event value, using ${canPartialSet === true ? 'empty partial' : 'defaults'}`,
|
|
225
|
+
)
|
|
226
|
+
return encodeTarget(canPartialSet === true ? {} : defaultValue)
|
|
227
|
+
}
|
|
214
228
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
229
|
+
if (canPartialSet === true) {
|
|
230
|
+
// For partial sets: only preserve fields that exist in new schema
|
|
231
|
+
const partialResult: Record<string, unknown> = {}
|
|
232
|
+
let hasValidFields = false
|
|
233
|
+
|
|
234
|
+
for (const [key, value] of Object.entries(eventValue as Record<string, unknown>)) {
|
|
235
|
+
if (key in defaultValue) {
|
|
236
|
+
partialResult[key] = value
|
|
237
|
+
hasValidFields = true
|
|
238
|
+
}
|
|
239
|
+
// Drop fields that don't exist in new schema
|
|
240
|
+
}
|
|
219
241
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
242
|
+
if (hasValidFields === true) {
|
|
243
|
+
try {
|
|
244
|
+
const decoded = Schema.decodeUnknownSync(targetSchema)(partialResult)
|
|
245
|
+
return encodeTarget(decoded)
|
|
246
|
+
} catch {
|
|
247
|
+
// Even filtered fields don't match schema
|
|
248
|
+
console.warn('Client document: Partial fields incompatible, returning empty partial')
|
|
249
|
+
return encodeTarget({})
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
return encodeTarget({})
|
|
253
|
+
} else {
|
|
254
|
+
// Full set: merge old data with new defaults
|
|
255
|
+
const merged: Record<string, unknown> = { ...defaultValue }
|
|
256
|
+
|
|
257
|
+
// Override defaults with valid fields from old event
|
|
258
|
+
for (const [key, value] of Object.entries(eventValue as Record<string, unknown>)) {
|
|
259
|
+
if (key in defaultValue) {
|
|
260
|
+
merged[key] = value
|
|
261
|
+
}
|
|
262
|
+
// Drop fields that don't exist in new schema
|
|
224
263
|
}
|
|
225
|
-
// Drop fields that don't exist in new schema
|
|
226
|
-
}
|
|
227
264
|
|
|
228
|
-
|
|
265
|
+
// Try to decode the merged value
|
|
229
266
|
try {
|
|
230
|
-
const decoded = Schema.decodeUnknownSync(
|
|
267
|
+
const decoded = Schema.decodeUnknownSync(valueSchema)(merged)
|
|
231
268
|
return encodeTarget(decoded)
|
|
232
269
|
} catch {
|
|
233
|
-
//
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
}
|
|
238
|
-
return encodeTarget({})
|
|
239
|
-
} else {
|
|
240
|
-
// Full set: merge old data with new defaults
|
|
241
|
-
const merged: Record<string, unknown> = { ...defaultValue }
|
|
242
|
-
|
|
243
|
-
// Override defaults with valid fields from old event
|
|
244
|
-
for (const [key, value] of Object.entries(eventValue as Record<string, unknown>)) {
|
|
245
|
-
if (key in defaultValue) {
|
|
246
|
-
merged[key] = value
|
|
270
|
+
// Merged value still doesn't match (e.g., type changes)
|
|
271
|
+
// Fall back to pure defaults
|
|
272
|
+
console.warn('Client document: Could not preserve event data, using defaults')
|
|
273
|
+
return encodeTarget(defaultValue)
|
|
247
274
|
}
|
|
248
|
-
// Drop fields that don't exist in new schema
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
// Try to decode the merged value
|
|
252
|
-
try {
|
|
253
|
-
const decoded = Schema.decodeUnknownSync(valueSchema)(merged)
|
|
254
|
-
return encodeTarget(decoded)
|
|
255
|
-
} catch {
|
|
256
|
-
// Merged value still doesn't match (e.g., type changes)
|
|
257
|
-
// Fall back to pure defaults
|
|
258
|
-
console.warn('Client document: Could not preserve event data, using defaults')
|
|
259
|
-
return encodeTarget(defaultValue)
|
|
260
275
|
}
|
|
261
276
|
}
|
|
262
|
-
}
|
|
277
|
+
}),
|
|
278
|
+
encode: SchemaGetter.passthroughSubtype(),
|
|
263
279
|
},
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
)
|
|
280
|
+
),
|
|
281
|
+
) as Schema.Codec<any, unknown>
|
|
267
282
|
}
|
|
268
283
|
|
|
269
284
|
export const deriveEventAndMaterializer = ({
|
|
@@ -273,16 +288,16 @@ export const deriveEventAndMaterializer = ({
|
|
|
273
288
|
partialSet,
|
|
274
289
|
}: {
|
|
275
290
|
name: string
|
|
276
|
-
valueSchema: Schema.
|
|
291
|
+
valueSchema: Schema.Codec<any, any>
|
|
277
292
|
defaultValue: any
|
|
278
293
|
partialSet: boolean
|
|
279
294
|
}) => {
|
|
280
295
|
const derivedSetEventDef = defineEvent({
|
|
281
296
|
name: `${name}Set`,
|
|
282
297
|
schema: Schema.Struct({
|
|
283
|
-
id: Schema.Union(Schema.String, Schema.
|
|
298
|
+
id: Schema.Union([Schema.String, Schema.UniqueSymbol(SessionIdSymbol)]),
|
|
284
299
|
value: createOptimisticEventSchema({ valueSchema, defaultValue, partialSet }),
|
|
285
|
-
}).
|
|
300
|
+
}).annotate({ title: `${name}Set:Args` }),
|
|
286
301
|
clientOnly: true,
|
|
287
302
|
derived: true,
|
|
288
303
|
})
|
|
@@ -295,7 +310,7 @@ export const deriveEventAndMaterializer = ({
|
|
|
295
310
|
// Override the full value if it's not an object or no partial set is allowed
|
|
296
311
|
const schemaProps = Schema.getResolvedPropertySignatures(valueSchema)
|
|
297
312
|
if (schemaProps.length === 0 || partialSet === false) {
|
|
298
|
-
const valueColJsonSchema = Schema.
|
|
313
|
+
const valueColJsonSchema = Schema.fromJsonString(valueSchema) as Schema.Codec<any, string>
|
|
299
314
|
const encodedInsertValue = Schema.encodeSyncDebug(valueColJsonSchema)(value ?? defaultValue)
|
|
300
315
|
const encodedUpdateValue = Schema.encodeSyncDebug(valueColJsonSchema)(value)
|
|
301
316
|
|
|
@@ -305,7 +320,7 @@ export const deriveEventAndMaterializer = ({
|
|
|
305
320
|
writeTables: new Set([name]),
|
|
306
321
|
}
|
|
307
322
|
} else {
|
|
308
|
-
const valueColJsonSchema = Schema.
|
|
323
|
+
const valueColJsonSchema = Schema.fromJsonString(partialStructSchema(valueSchema)) as Schema.Codec<any, string>
|
|
309
324
|
|
|
310
325
|
const encodedInsertValue = Schema.encodeSyncDebug(valueColJsonSchema)(mergeDefaultValues(defaultValue, value))
|
|
311
326
|
|
|
@@ -313,7 +328,7 @@ export const deriveEventAndMaterializer = ({
|
|
|
313
328
|
const setBindValues: unknown[] = []
|
|
314
329
|
|
|
315
330
|
const keys = Object.keys(value)
|
|
316
|
-
const partialUpdateSchema = valueSchema
|
|
331
|
+
const partialUpdateSchema = pickStructSchema(valueSchema, keys)
|
|
317
332
|
const encodedPartialUpdate = Schema.encodeSyncDebug(partialUpdateSchema)(value)
|
|
318
333
|
|
|
319
334
|
for (const key in encodedPartialUpdate) {
|
|
@@ -525,7 +540,7 @@ export namespace ClientDocumentTableDef {
|
|
|
525
540
|
*/
|
|
526
541
|
readonly set: SetEventDefLike<TName, TType, TOptions>
|
|
527
542
|
readonly Value: TType
|
|
528
|
-
readonly valueSchema: Schema.
|
|
543
|
+
readonly valueSchema: Schema.Codec<TType, TEncoded>
|
|
529
544
|
readonly default: TOptions['default']
|
|
530
545
|
readonly [ClientDocumentTableDefSymbol]: {
|
|
531
546
|
readonly options: TOptions
|
|
@@ -562,7 +577,7 @@ export namespace ClientDocumentTableDef {
|
|
|
562
577
|
id?: string | SessionIdSymbol,
|
|
563
578
|
) => { name: `${TName}Set`; args: { id: string; value: TType } }) & {
|
|
564
579
|
readonly name: `${TName}Set`
|
|
565
|
-
readonly schema: Schema.
|
|
580
|
+
readonly schema: Schema.Codec<any, any>
|
|
566
581
|
readonly Event: {
|
|
567
582
|
readonly name: `${TName}Set`
|
|
568
583
|
readonly args: { id: string; value: TType }
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { describe, expect, test } from 'vitest'
|
|
2
2
|
|
|
3
|
-
import { Schema, SchemaAST } from '@livestore/utils/effect'
|
|
3
|
+
import { Schema, SchemaAST, SchemaTransformation } from '@livestore/utils/effect'
|
|
4
4
|
|
|
5
|
-
import { withColumnType, withPrimaryKey } from './column-annotations.ts'
|
|
5
|
+
import { ColumnType, PrimaryKeyId, withColumnType, withPrimaryKey } from './column-annotations.ts'
|
|
6
6
|
|
|
7
7
|
describe.concurrent('annotations', () => {
|
|
8
8
|
describe('withPrimaryKey', () => {
|
|
@@ -10,16 +10,8 @@ describe.concurrent('annotations', () => {
|
|
|
10
10
|
const schema = Schema.String
|
|
11
11
|
const result = withPrimaryKey(schema)
|
|
12
12
|
|
|
13
|
-
expect(SchemaAST.
|
|
14
|
-
|
|
15
|
-
"_tag": "StringKeyword",
|
|
16
|
-
"annotations": {
|
|
17
|
-
"Symbol(effect/annotation/Description)": "a string",
|
|
18
|
-
"Symbol(effect/annotation/Title)": "string",
|
|
19
|
-
"Symbol(livestore/state/sqlite/annotations/primary-key)": true,
|
|
20
|
-
},
|
|
21
|
-
}
|
|
22
|
-
`)
|
|
13
|
+
expect(SchemaAST.isString(result.ast)).toBe(true)
|
|
14
|
+
expect(Schema.resolveAnnotations(result)?.[PrimaryKeyId]).toBe(true)
|
|
23
15
|
})
|
|
24
16
|
})
|
|
25
17
|
|
|
@@ -30,19 +22,19 @@ describe.concurrent('annotations', () => {
|
|
|
30
22
|
})
|
|
31
23
|
|
|
32
24
|
test('Schema.Number with integer column type', () => {
|
|
33
|
-
expect(() => withColumnType(Schema.
|
|
25
|
+
expect(() => withColumnType(Schema.Finite, 'integer')).not.toThrow()
|
|
34
26
|
})
|
|
35
27
|
|
|
36
28
|
test('Schema.Number with real column type', () => {
|
|
37
|
-
expect(() => withColumnType(Schema.
|
|
29
|
+
expect(() => withColumnType(Schema.Finite, 'real')).not.toThrow()
|
|
38
30
|
})
|
|
39
31
|
|
|
40
32
|
test('Schema.Boolean with integer column type', () => {
|
|
41
33
|
expect(() => withColumnType(Schema.Boolean, 'integer')).not.toThrow()
|
|
42
34
|
})
|
|
43
35
|
|
|
44
|
-
test('Schema.
|
|
45
|
-
expect(() => withColumnType(Schema.
|
|
36
|
+
test('Schema.Uint8Array with blob column type', () => {
|
|
37
|
+
expect(() => withColumnType(Schema.Uint8Array, 'blob')).not.toThrow()
|
|
46
38
|
})
|
|
47
39
|
|
|
48
40
|
test('Schema.Date with text column type', () => {
|
|
@@ -66,15 +58,20 @@ describe.concurrent('annotations', () => {
|
|
|
66
58
|
})
|
|
67
59
|
|
|
68
60
|
test('Union of same type with compatible column type', () => {
|
|
69
|
-
const unionSchema = Schema.
|
|
61
|
+
const unionSchema = Schema.Literals(['a', 'b'])
|
|
70
62
|
expect(() => withColumnType(unionSchema, 'text')).not.toThrow()
|
|
71
63
|
})
|
|
72
64
|
|
|
73
65
|
test('Transformation schema with compatible base type', () => {
|
|
74
|
-
const transformSchema = Schema.
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
66
|
+
const transformSchema = Schema.String.pipe(
|
|
67
|
+
Schema.decodeTo(
|
|
68
|
+
Schema.String,
|
|
69
|
+
SchemaTransformation.transform({
|
|
70
|
+
decode: (s) => s.toUpperCase(),
|
|
71
|
+
encode: (s) => s.toLowerCase(),
|
|
72
|
+
}),
|
|
73
|
+
),
|
|
74
|
+
)
|
|
78
75
|
expect(() => withColumnType(transformSchema, 'text')).not.toThrow()
|
|
79
76
|
})
|
|
80
77
|
})
|
|
@@ -129,8 +126,8 @@ describe.concurrent('annotations', () => {
|
|
|
129
126
|
// )
|
|
130
127
|
// })
|
|
131
128
|
|
|
132
|
-
// test('Schema.
|
|
133
|
-
// expect(() => withColumnType(Schema.
|
|
129
|
+
// test('Schema.Uint8Array with text column type should throw', () => {
|
|
130
|
+
// expect(() => withColumnType(Schema.Uint8Array, 'text')).toThrow(
|
|
134
131
|
// "Schema type 'uint8array' is incompatible with column type 'text'",
|
|
135
132
|
// )
|
|
136
133
|
// })
|
|
@@ -156,7 +153,7 @@ describe.concurrent('annotations', () => {
|
|
|
156
153
|
|
|
157
154
|
describe('complex schemas', () => {
|
|
158
155
|
test('should allow complex schemas that cannot be determined', () => {
|
|
159
|
-
const complexSchema = Schema.Struct({ name: Schema.String, age: Schema.
|
|
156
|
+
const complexSchema = Schema.Struct({ name: Schema.String, age: Schema.Finite })
|
|
160
157
|
expect(() => withColumnType(complexSchema, 'text')).not.toThrow()
|
|
161
158
|
})
|
|
162
159
|
|
|
@@ -180,33 +177,17 @@ describe.concurrent('annotations', () => {
|
|
|
180
177
|
const schema = Schema.String
|
|
181
178
|
const result = withColumnType(schema, 'text')
|
|
182
179
|
|
|
183
|
-
expect(SchemaAST.
|
|
184
|
-
|
|
185
|
-
"_tag": "StringKeyword",
|
|
186
|
-
"annotations": {
|
|
187
|
-
"Symbol(effect/annotation/Description)": "a string",
|
|
188
|
-
"Symbol(effect/annotation/Title)": "string",
|
|
189
|
-
"Symbol(livestore/state/sqlite/annotations/column-type)": "text",
|
|
190
|
-
},
|
|
191
|
-
}
|
|
192
|
-
`)
|
|
180
|
+
expect(SchemaAST.isString(result.ast)).toBe(true)
|
|
181
|
+
expect(Schema.resolveAnnotations(result)?.[ColumnType]).toBe('text')
|
|
193
182
|
})
|
|
194
183
|
|
|
195
184
|
test('should preserve existing annotations', () => {
|
|
196
185
|
const schema = withPrimaryKey(Schema.String)
|
|
197
186
|
const result = withColumnType(schema, 'text')
|
|
198
187
|
|
|
199
|
-
expect(SchemaAST.
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
"annotations": {
|
|
203
|
-
"Symbol(effect/annotation/Description)": "a string",
|
|
204
|
-
"Symbol(effect/annotation/Title)": "string",
|
|
205
|
-
"Symbol(livestore/state/sqlite/annotations/column-type)": "text",
|
|
206
|
-
"Symbol(livestore/state/sqlite/annotations/primary-key)": true,
|
|
207
|
-
},
|
|
208
|
-
}
|
|
209
|
-
`)
|
|
188
|
+
expect(SchemaAST.isString(result.ast)).toBe(true)
|
|
189
|
+
expect(Schema.resolveAnnotations(result)?.[ColumnType]).toBe('text')
|
|
190
|
+
expect(Schema.resolveAnnotations(result)?.[PrimaryKeyId]).toBe(true)
|
|
210
191
|
})
|
|
211
192
|
})
|
|
212
193
|
})
|
|
@@ -1,19 +1,18 @@
|
|
|
1
|
-
import type
|
|
2
|
-
import { dual, Option, SchemaAST } from '@livestore/utils/effect'
|
|
1
|
+
import { type Schema, Function, SchemaAST } from '@livestore/utils/effect'
|
|
3
2
|
|
|
4
3
|
import type { SqliteDsl } from './db-schema/mod.ts'
|
|
5
4
|
|
|
6
|
-
export const PrimaryKeyId =
|
|
5
|
+
export const PrimaryKeyId = 'livestore/state/sqlite/annotations/primary-key'
|
|
7
6
|
|
|
8
|
-
export const ColumnType =
|
|
7
|
+
export const ColumnType = 'livestore/state/sqlite/annotations/column-type'
|
|
9
8
|
|
|
10
|
-
export const Default =
|
|
9
|
+
export const Default = 'livestore/state/sqlite/annotations/default'
|
|
11
10
|
|
|
12
|
-
export const AutoIncrement =
|
|
11
|
+
export const AutoIncrement = 'livestore/state/sqlite/annotations/auto-increment'
|
|
13
12
|
|
|
14
|
-
export const Unique =
|
|
13
|
+
export const Unique = 'livestore/state/sqlite/annotations/unique'
|
|
15
14
|
|
|
16
|
-
// export const Check =
|
|
15
|
+
// export const Check = 'livestore/state/sqlite/annotations/check'
|
|
17
16
|
|
|
18
17
|
/*
|
|
19
18
|
Here are the knobs you can turn per-column when you CREATE TABLE (or ALTER TABLE … ADD COLUMN) in SQLite:
|
|
@@ -26,23 +25,22 @@ Here are the knobs you can turn per-column when you CREATE TABLE (or ALTER TABLE
|
|
|
26
25
|
• COLLATE <name> – per-column collation sequence for text comparison. 
|
|
27
26
|
• REFERENCES tbl(col) [ON UPDATE/DELETE …] – column-local foreign key with its own cascade / restrict / set-null rules. 
|
|
28
27
|
• GENERATED ALWAYS AS (<expr>) [VIRTUAL | STORED] – computed columns (since 3.31). 
|
|
29
|
-
• CONSTRAINT name … – optional label in front of any of the above so you can refer to it in error messages or when dropping/recreating schemas.
|
|
28
|
+
• CONSTRAINT name … – optional label in front of any of the above so you can refer to it in error messages or when dropping/recreating schemas.
|
|
30
29
|
*/
|
|
31
30
|
|
|
32
31
|
/**
|
|
33
32
|
* Adds a primary key annotation to a schema.
|
|
34
33
|
*/
|
|
35
|
-
export const withPrimaryKey = <T extends Schema.
|
|
36
|
-
applyAnnotations(schema, { [PrimaryKeyId]: true })
|
|
34
|
+
export const withPrimaryKey = <T extends Schema.Top>(schema: T) => applyAnnotations(schema, { [PrimaryKeyId]: true })
|
|
37
35
|
|
|
38
36
|
/**
|
|
39
37
|
* Adds a column type annotation to a schema.
|
|
40
38
|
*/
|
|
41
39
|
export const withColumnType: {
|
|
42
|
-
(type: SqliteDsl.FieldColumnType): <T extends Schema.
|
|
40
|
+
(type: SqliteDsl.FieldColumnType): <T extends Schema.Top>(schema: T) => T
|
|
43
41
|
// TODO make type safe
|
|
44
|
-
<T extends Schema.
|
|
45
|
-
} = dual(2, <T extends Schema.
|
|
42
|
+
<T extends Schema.Top>(schema: T, type: SqliteDsl.FieldColumnType): T
|
|
43
|
+
} = Function.dual(2, <T extends Schema.Top>(schema: T, type: SqliteDsl.FieldColumnType) => {
|
|
46
44
|
validateSchemaColumnTypeCompatibility(schema, type)
|
|
47
45
|
return applyAnnotations(schema, { [ColumnType]: type })
|
|
48
46
|
})
|
|
@@ -50,39 +48,37 @@ export const withColumnType: {
|
|
|
50
48
|
/**
|
|
51
49
|
* Adds an auto-increment annotation to a schema.
|
|
52
50
|
*/
|
|
53
|
-
export const withAutoIncrement = <T extends Schema.
|
|
51
|
+
export const withAutoIncrement = <T extends Schema.Top>(schema: T) =>
|
|
54
52
|
applyAnnotations(schema, { [AutoIncrement]: true })
|
|
55
53
|
|
|
56
54
|
/**
|
|
57
55
|
* Adds a unique constraint annotation to a schema.
|
|
58
56
|
*/
|
|
59
|
-
export const withUnique = <T extends Schema.
|
|
57
|
+
export const withUnique = <T extends Schema.Top>(schema: T) => applyAnnotations(schema, { [Unique]: true })
|
|
60
58
|
|
|
61
59
|
/**
|
|
62
60
|
* Adds a default value annotation to a schema.
|
|
63
61
|
*/
|
|
64
62
|
export const withDefault: {
|
|
65
63
|
// TODO make type safe
|
|
66
|
-
<T extends Schema.
|
|
67
|
-
(value: unknown): <T extends Schema.
|
|
68
|
-
} = dual(2, <T extends Schema.
|
|
64
|
+
<T extends Schema.Top>(schema: T, value: unknown): T
|
|
65
|
+
(value: unknown): <T extends Schema.Top>(schema: T) => T
|
|
66
|
+
} = Function.dual(2, <T extends Schema.Top>(schema: T, value: unknown) =>
|
|
67
|
+
applyAnnotations(schema, { [Default]: value }),
|
|
68
|
+
)
|
|
69
69
|
|
|
70
70
|
/**
|
|
71
71
|
* Validates that a schema is compatible with the specified SQLite column type
|
|
72
72
|
*/
|
|
73
|
-
const validateSchemaColumnTypeCompatibility = (
|
|
74
|
-
_schema: Schema.Schema.All,
|
|
75
|
-
_columnType: SqliteDsl.FieldColumnType,
|
|
76
|
-
): void => {
|
|
73
|
+
const validateSchemaColumnTypeCompatibility = (_schema: Schema.Top, _columnType: SqliteDsl.FieldColumnType): void => {
|
|
77
74
|
// TODO actually implement this
|
|
78
75
|
}
|
|
79
76
|
|
|
80
|
-
const applyAnnotations = <T extends Schema.
|
|
81
|
-
const identifier = SchemaAST.
|
|
82
|
-
const shouldPreserveIdentifier =
|
|
83
|
-
const annotations: Record<
|
|
84
|
-
? { ...overrides,
|
|
85
|
-
: overrides
|
|
77
|
+
const applyAnnotations = <T extends Schema.Top>(schema: T, overrides: Record<string, unknown>): T => {
|
|
78
|
+
const identifier = SchemaAST.resolveIdentifier(schema.ast)
|
|
79
|
+
const shouldPreserveIdentifier = identifier !== undefined && !('identifier' in overrides)
|
|
80
|
+
const annotations: Record<string, unknown> =
|
|
81
|
+
shouldPreserveIdentifier === true ? { ...overrides, identifier } : overrides
|
|
86
82
|
|
|
87
|
-
return schema.
|
|
83
|
+
return schema.annotate(annotations) as T
|
|
88
84
|
}
|