@livestore/common 0.3.0-dev.3 → 0.3.0-dev.30
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/.tsbuildinfo +1 -1
- package/dist/__tests__/fixture.d.ts +83 -221
- package/dist/__tests__/fixture.d.ts.map +1 -1
- package/dist/__tests__/fixture.js +33 -11
- package/dist/__tests__/fixture.js.map +1 -1
- package/dist/adapter-types.d.ts +128 -68
- package/dist/adapter-types.d.ts.map +1 -1
- package/dist/adapter-types.js +36 -7
- package/dist/adapter-types.js.map +1 -1
- package/dist/bounded-collections.d.ts.map +1 -1
- package/dist/debug-info.d.ts +1 -1
- package/dist/debug-info.d.ts.map +1 -1
- package/dist/debug-info.js +1 -0
- package/dist/debug-info.js.map +1 -1
- package/dist/devtools/devtools-messages-client-session.d.ts +389 -0
- package/dist/devtools/devtools-messages-client-session.d.ts.map +1 -0
- package/dist/devtools/devtools-messages-client-session.js +96 -0
- package/dist/devtools/devtools-messages-client-session.js.map +1 -0
- package/dist/devtools/devtools-messages-common.d.ts +68 -0
- package/dist/devtools/devtools-messages-common.d.ts.map +1 -0
- package/dist/devtools/devtools-messages-common.js +60 -0
- package/dist/devtools/devtools-messages-common.js.map +1 -0
- package/dist/devtools/devtools-messages-leader.d.ts +394 -0
- package/dist/devtools/devtools-messages-leader.d.ts.map +1 -0
- package/dist/devtools/devtools-messages-leader.js +147 -0
- package/dist/devtools/devtools-messages-leader.js.map +1 -0
- package/dist/devtools/devtools-messages.d.ts +3 -592
- package/dist/devtools/devtools-messages.d.ts.map +1 -1
- package/dist/devtools/devtools-messages.js +3 -171
- package/dist/devtools/devtools-messages.js.map +1 -1
- package/dist/devtools/devtools-sessioninfo.d.ts +28 -0
- package/dist/devtools/devtools-sessioninfo.d.ts.map +1 -0
- package/dist/devtools/devtools-sessioninfo.js +34 -0
- package/dist/devtools/devtools-sessioninfo.js.map +1 -0
- package/dist/devtools/mod.d.ts +39 -0
- package/dist/devtools/mod.d.ts.map +1 -0
- package/dist/devtools/mod.js +27 -0
- package/dist/devtools/mod.js.map +1 -0
- package/dist/index.d.ts +4 -11
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -7
- package/dist/index.js.map +1 -1
- package/dist/leader-thread/LeaderSyncProcessor.d.ts +62 -0
- package/dist/leader-thread/LeaderSyncProcessor.d.ts.map +1 -0
- package/dist/leader-thread/LeaderSyncProcessor.js +589 -0
- package/dist/leader-thread/LeaderSyncProcessor.js.map +1 -0
- package/dist/leader-thread/apply-event.d.ts +16 -0
- package/dist/leader-thread/apply-event.d.ts.map +1 -0
- package/dist/leader-thread/apply-event.js +103 -0
- package/dist/leader-thread/apply-event.js.map +1 -0
- package/dist/leader-thread/connection.d.ts +34 -6
- package/dist/leader-thread/connection.d.ts.map +1 -1
- package/dist/leader-thread/connection.js +22 -7
- package/dist/leader-thread/connection.js.map +1 -1
- package/dist/leader-thread/eventlog.d.ts +27 -0
- package/dist/leader-thread/eventlog.d.ts.map +1 -0
- package/dist/leader-thread/eventlog.js +123 -0
- package/dist/leader-thread/eventlog.js.map +1 -0
- package/dist/leader-thread/leader-worker-devtools.d.ts +1 -1
- package/dist/leader-thread/leader-worker-devtools.d.ts.map +1 -1
- package/dist/leader-thread/leader-worker-devtools.js +154 -132
- package/dist/leader-thread/leader-worker-devtools.js.map +1 -1
- package/dist/leader-thread/make-leader-thread-layer.d.ts +26 -12
- package/dist/leader-thread/make-leader-thread-layer.d.ts.map +1 -1
- package/dist/leader-thread/make-leader-thread-layer.js +82 -47
- package/dist/leader-thread/make-leader-thread-layer.js.map +1 -1
- package/dist/leader-thread/mod.d.ts +1 -1
- package/dist/leader-thread/mod.d.ts.map +1 -1
- package/dist/leader-thread/mod.js +1 -1
- package/dist/leader-thread/mod.js.map +1 -1
- package/dist/leader-thread/recreate-db.d.ts +4 -2
- package/dist/leader-thread/recreate-db.d.ts.map +1 -1
- package/dist/leader-thread/recreate-db.js +35 -25
- package/dist/leader-thread/recreate-db.js.map +1 -1
- package/dist/leader-thread/shutdown-channel.d.ts +2 -5
- package/dist/leader-thread/shutdown-channel.d.ts.map +1 -1
- package/dist/leader-thread/shutdown-channel.js +2 -4
- package/dist/leader-thread/shutdown-channel.js.map +1 -1
- package/dist/leader-thread/types.d.ts +86 -39
- package/dist/leader-thread/types.d.ts.map +1 -1
- package/dist/leader-thread/types.js +1 -3
- package/dist/leader-thread/types.js.map +1 -1
- package/dist/materializer-helper.d.ts +23 -0
- package/dist/materializer-helper.d.ts.map +1 -0
- package/dist/materializer-helper.js +70 -0
- package/dist/materializer-helper.js.map +1 -0
- package/dist/otel.d.ts +2 -0
- package/dist/otel.d.ts.map +1 -1
- package/dist/otel.js +5 -0
- package/dist/otel.js.map +1 -1
- package/dist/query-builder/api.d.ts +158 -55
- package/dist/query-builder/api.d.ts.map +1 -1
- package/dist/query-builder/api.js +3 -5
- package/dist/query-builder/api.js.map +1 -1
- package/dist/query-builder/astToSql.d.ts +7 -0
- package/dist/query-builder/astToSql.d.ts.map +1 -0
- package/dist/query-builder/astToSql.js +190 -0
- package/dist/query-builder/astToSql.js.map +1 -0
- package/dist/query-builder/impl.d.ts +3 -8
- package/dist/query-builder/impl.d.ts.map +1 -1
- package/dist/query-builder/impl.js +166 -124
- package/dist/query-builder/impl.js.map +1 -1
- package/dist/query-builder/impl.test.d.ts +86 -1
- package/dist/query-builder/impl.test.d.ts.map +1 -1
- package/dist/query-builder/impl.test.js +411 -69
- package/dist/query-builder/impl.test.js.map +1 -1
- package/dist/query-builder/mod.d.ts +7 -0
- package/dist/query-builder/mod.d.ts.map +1 -1
- package/dist/query-builder/mod.js +7 -0
- package/dist/query-builder/mod.js.map +1 -1
- package/dist/rehydrate-from-eventlog.d.ts +14 -0
- package/dist/rehydrate-from-eventlog.d.ts.map +1 -0
- package/dist/rehydrate-from-eventlog.js +65 -0
- package/dist/rehydrate-from-eventlog.js.map +1 -0
- package/dist/schema/EventDef.d.ts +136 -0
- package/dist/schema/EventDef.d.ts.map +1 -0
- package/dist/schema/EventDef.js +58 -0
- package/dist/schema/EventDef.js.map +1 -0
- package/dist/schema/EventId.d.ts +35 -15
- package/dist/schema/EventId.d.ts.map +1 -1
- package/dist/schema/EventId.js +57 -11
- package/dist/schema/EventId.js.map +1 -1
- package/dist/schema/EventId.test.d.ts +2 -0
- package/dist/schema/EventId.test.d.ts.map +1 -0
- package/dist/schema/EventId.test.js +11 -0
- package/dist/schema/EventId.test.js.map +1 -0
- package/dist/schema/LiveStoreEvent.d.ts +255 -0
- package/dist/schema/LiveStoreEvent.d.ts.map +1 -0
- package/dist/schema/LiveStoreEvent.js +118 -0
- package/dist/schema/LiveStoreEvent.js.map +1 -0
- package/dist/schema/client-document-def.d.ts +223 -0
- package/dist/schema/client-document-def.d.ts.map +1 -0
- package/dist/schema/client-document-def.js +170 -0
- package/dist/schema/client-document-def.js.map +1 -0
- package/dist/schema/client-document-def.test.d.ts +2 -0
- package/dist/schema/client-document-def.test.d.ts.map +1 -0
- package/dist/schema/client-document-def.test.js +201 -0
- package/dist/schema/client-document-def.test.js.map +1 -0
- package/dist/schema/db-schema/ast/sqlite.d.ts +69 -0
- package/dist/schema/db-schema/ast/sqlite.d.ts.map +1 -0
- package/dist/schema/db-schema/ast/sqlite.js +71 -0
- package/dist/schema/db-schema/ast/sqlite.js.map +1 -0
- package/dist/schema/db-schema/ast/validate.d.ts +3 -0
- package/dist/schema/db-schema/ast/validate.d.ts.map +1 -0
- package/dist/schema/db-schema/ast/validate.js +12 -0
- package/dist/schema/db-schema/ast/validate.js.map +1 -0
- package/dist/schema/db-schema/dsl/field-defs.d.ts +90 -0
- package/dist/schema/db-schema/dsl/field-defs.d.ts.map +1 -0
- package/dist/schema/db-schema/dsl/field-defs.js +87 -0
- package/dist/schema/db-schema/dsl/field-defs.js.map +1 -0
- package/dist/schema/db-schema/dsl/field-defs.test.d.ts +2 -0
- package/dist/schema/db-schema/dsl/field-defs.test.d.ts.map +1 -0
- package/dist/schema/db-schema/dsl/field-defs.test.js +29 -0
- package/dist/schema/db-schema/dsl/field-defs.test.js.map +1 -0
- package/dist/schema/db-schema/dsl/mod.d.ts +90 -0
- package/dist/schema/db-schema/dsl/mod.d.ts.map +1 -0
- package/dist/schema/db-schema/dsl/mod.js +41 -0
- package/dist/schema/db-schema/dsl/mod.js.map +1 -0
- package/dist/schema/db-schema/hash.d.ts +2 -0
- package/dist/schema/db-schema/hash.d.ts.map +1 -0
- package/dist/schema/db-schema/hash.js +14 -0
- package/dist/schema/db-schema/hash.js.map +1 -0
- package/dist/schema/db-schema/mod.d.ts +3 -0
- package/dist/schema/db-schema/mod.d.ts.map +1 -0
- package/dist/schema/db-schema/mod.js +3 -0
- package/dist/schema/db-schema/mod.js.map +1 -0
- package/dist/schema/events.d.ts +2 -0
- package/dist/schema/events.d.ts.map +1 -0
- package/dist/schema/events.js +2 -0
- package/dist/schema/events.js.map +1 -0
- package/dist/schema/mod.d.ts +5 -3
- package/dist/schema/mod.d.ts.map +1 -1
- package/dist/schema/mod.js +5 -3
- package/dist/schema/mod.js.map +1 -1
- package/dist/schema/schema-helpers.d.ts.map +1 -1
- package/dist/schema/schema-helpers.js +1 -1
- package/dist/schema/schema-helpers.js.map +1 -1
- package/dist/schema/schema.d.ts +30 -23
- package/dist/schema/schema.d.ts.map +1 -1
- package/dist/schema/schema.js +48 -35
- package/dist/schema/schema.js.map +1 -1
- package/dist/schema/sqlite-state.d.ts +12 -0
- package/dist/schema/sqlite-state.d.ts.map +1 -0
- package/dist/schema/sqlite-state.js +36 -0
- package/dist/schema/sqlite-state.js.map +1 -0
- package/dist/schema/system-tables.d.ts +179 -125
- package/dist/schema/system-tables.d.ts.map +1 -1
- package/dist/schema/system-tables.js +76 -41
- package/dist/schema/system-tables.js.map +1 -1
- package/dist/schema/table-def.d.ts +37 -109
- package/dist/schema/table-def.d.ts.map +1 -1
- package/dist/schema/table-def.js +23 -66
- package/dist/schema/table-def.js.map +1 -1
- package/dist/schema/view.d.ts +3 -0
- package/dist/schema/view.d.ts.map +1 -0
- package/dist/schema/view.js +3 -0
- package/dist/schema/view.js.map +1 -0
- package/dist/schema-management/common.d.ts +7 -7
- package/dist/schema-management/common.d.ts.map +1 -1
- package/dist/schema-management/common.js.map +1 -1
- package/dist/schema-management/migrations.d.ts +6 -6
- package/dist/schema-management/migrations.d.ts.map +1 -1
- package/dist/schema-management/migrations.js +19 -14
- package/dist/schema-management/migrations.js.map +1 -1
- package/dist/schema-management/validate-mutation-defs.d.ts +3 -3
- package/dist/schema-management/validate-mutation-defs.d.ts.map +1 -1
- package/dist/schema-management/validate-mutation-defs.js +17 -17
- package/dist/schema-management/validate-mutation-defs.js.map +1 -1
- package/dist/sql-queries/misc.d.ts.map +1 -1
- package/dist/sql-queries/sql-queries.d.ts +1 -1
- package/dist/sql-queries/sql-queries.d.ts.map +1 -1
- package/dist/sql-queries/sql-queries.js.map +1 -1
- package/dist/sql-queries/sql-query-builder.d.ts +1 -1
- package/dist/sql-queries/sql-query-builder.d.ts.map +1 -1
- package/dist/sql-queries/sql-query-builder.js.map +1 -1
- package/dist/sql-queries/types.d.ts +2 -1
- package/dist/sql-queries/types.d.ts.map +1 -1
- package/dist/sql-queries/types.js.map +1 -1
- package/dist/sync/ClientSessionSyncProcessor.d.ts +66 -0
- package/dist/sync/ClientSessionSyncProcessor.d.ts.map +1 -0
- package/dist/sync/ClientSessionSyncProcessor.js +209 -0
- package/dist/sync/ClientSessionSyncProcessor.js.map +1 -0
- package/dist/sync/index.d.ts +1 -1
- package/dist/sync/index.d.ts.map +1 -1
- package/dist/sync/index.js +1 -1
- package/dist/sync/index.js.map +1 -1
- package/dist/sync/next/compact-events.d.ts.map +1 -1
- package/dist/sync/next/facts.d.ts +19 -19
- package/dist/sync/next/facts.d.ts.map +1 -1
- package/dist/sync/next/facts.js +3 -3
- package/dist/sync/next/facts.js.map +1 -1
- package/dist/sync/next/history-dag-common.d.ts +6 -7
- package/dist/sync/next/history-dag-common.d.ts.map +1 -1
- package/dist/sync/next/history-dag-common.js +4 -2
- package/dist/sync/next/history-dag-common.js.map +1 -1
- package/dist/sync/next/history-dag.d.ts.map +1 -1
- package/dist/sync/next/history-dag.js +2 -2
- package/dist/sync/next/history-dag.js.map +1 -1
- package/dist/sync/next/rebase-events.d.ts +10 -8
- package/dist/sync/next/rebase-events.d.ts.map +1 -1
- package/dist/sync/next/rebase-events.js +11 -8
- package/dist/sync/next/rebase-events.js.map +1 -1
- package/dist/sync/next/test/compact-events.calculator.test.js +38 -33
- package/dist/sync/next/test/compact-events.calculator.test.js.map +1 -1
- package/dist/sync/next/test/compact-events.test.js +76 -76
- package/dist/sync/next/test/compact-events.test.js.map +1 -1
- package/dist/sync/next/test/{mutation-fixtures.d.ts → event-fixtures.d.ts} +29 -29
- package/dist/sync/next/test/event-fixtures.d.ts.map +1 -0
- package/dist/sync/next/test/{mutation-fixtures.js → event-fixtures.js} +67 -36
- package/dist/sync/next/test/event-fixtures.js.map +1 -0
- package/dist/sync/next/test/mod.d.ts +1 -1
- package/dist/sync/next/test/mod.d.ts.map +1 -1
- package/dist/sync/next/test/mod.js +1 -1
- package/dist/sync/next/test/mod.js.map +1 -1
- package/dist/sync/sync.d.ts +55 -20
- package/dist/sync/sync.d.ts.map +1 -1
- package/dist/sync/sync.js +7 -3
- package/dist/sync/sync.js.map +1 -1
- package/dist/sync/syncstate.d.ts +213 -82
- package/dist/sync/syncstate.d.ts.map +1 -1
- package/dist/sync/syncstate.js +319 -120
- package/dist/sync/syncstate.js.map +1 -1
- package/dist/sync/syncstate.test.js +295 -275
- package/dist/sync/syncstate.test.js.map +1 -1
- package/dist/sync/validate-push-payload.d.ts +2 -2
- package/dist/sync/validate-push-payload.d.ts.map +1 -1
- package/dist/sync/validate-push-payload.js +2 -2
- package/dist/sync/validate-push-payload.js.map +1 -1
- package/dist/util.d.ts +2 -2
- package/dist/util.d.ts.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.d.ts.map +1 -1
- package/dist/version.js +1 -1
- package/dist/version.js.map +1 -1
- package/package.json +6 -6
- package/src/__tests__/fixture.ts +36 -15
- package/src/adapter-types.ts +111 -74
- package/src/debug-info.ts +1 -0
- package/src/devtools/devtools-messages-client-session.ts +141 -0
- package/src/devtools/devtools-messages-common.ts +115 -0
- package/src/devtools/devtools-messages-leader.ts +191 -0
- package/src/devtools/devtools-messages.ts +3 -243
- package/src/devtools/devtools-sessioninfo.ts +99 -0
- package/src/devtools/mod.ts +36 -0
- package/src/index.ts +4 -13
- package/src/leader-thread/LeaderSyncProcessor.ts +935 -0
- package/src/leader-thread/apply-event.ts +173 -0
- package/src/leader-thread/connection.ts +54 -9
- package/src/leader-thread/eventlog.ts +199 -0
- package/src/leader-thread/leader-worker-devtools.ts +212 -189
- package/src/leader-thread/make-leader-thread-layer.ts +143 -77
- package/src/leader-thread/mod.ts +1 -1
- package/src/leader-thread/recreate-db.ts +41 -30
- package/src/leader-thread/shutdown-channel.ts +2 -4
- package/src/leader-thread/types.ts +95 -51
- package/src/materializer-helper.ts +110 -0
- package/src/otel.ts +8 -0
- package/src/query-builder/api.ts +236 -85
- package/src/query-builder/astToSql.ts +232 -0
- package/src/query-builder/impl.test.ts +447 -78
- package/src/query-builder/impl.ts +209 -144
- package/src/query-builder/mod.ts +7 -0
- package/src/rehydrate-from-eventlog.ts +114 -0
- package/src/schema/EventDef.ts +216 -0
- package/src/schema/EventId.test.ts +12 -0
- package/src/schema/EventId.ts +75 -15
- package/src/schema/LiveStoreEvent.ts +239 -0
- package/src/schema/client-document-def.test.ts +239 -0
- package/src/schema/client-document-def.ts +444 -0
- package/src/schema/db-schema/ast/sqlite.ts +142 -0
- package/src/schema/db-schema/ast/validate.ts +13 -0
- package/src/schema/db-schema/dsl/__snapshots__/field-defs.test.ts.snap +206 -0
- package/src/schema/db-schema/dsl/field-defs.test.ts +35 -0
- package/src/schema/db-schema/dsl/field-defs.ts +242 -0
- package/src/schema/db-schema/dsl/mod.ts +222 -0
- package/src/schema/db-schema/hash.ts +14 -0
- package/src/schema/db-schema/mod.ts +2 -0
- package/src/schema/events.ts +1 -0
- package/src/schema/mod.ts +5 -3
- package/src/schema/schema-helpers.ts +1 -1
- package/src/schema/schema.ts +84 -62
- package/src/schema/sqlite-state.ts +62 -0
- package/src/schema/system-tables.ts +68 -50
- package/src/schema/table-def.ts +68 -214
- package/src/schema/view.ts +2 -0
- package/src/schema-management/common.ts +7 -7
- package/src/schema-management/migrations.ts +27 -24
- package/src/schema-management/validate-mutation-defs.ts +22 -24
- package/src/sql-queries/sql-queries.ts +1 -1
- package/src/sql-queries/sql-query-builder.ts +1 -2
- package/src/sql-queries/types.ts +3 -1
- package/src/sync/ClientSessionSyncProcessor.ts +332 -0
- package/src/sync/index.ts +1 -1
- package/src/sync/next/facts.ts +32 -33
- package/src/sync/next/history-dag-common.ts +9 -5
- package/src/sync/next/history-dag.ts +2 -2
- package/src/sync/next/rebase-events.ts +22 -16
- package/src/sync/next/test/compact-events.calculator.test.ts +45 -45
- package/src/sync/next/test/compact-events.test.ts +78 -78
- package/src/sync/next/test/event-fixtures.ts +219 -0
- package/src/sync/next/test/mod.ts +1 -1
- package/src/sync/sync.ts +51 -19
- package/src/sync/syncstate.test.ts +335 -308
- package/src/sync/syncstate.ts +394 -212
- package/src/sync/validate-push-payload.ts +7 -4
- package/src/version.ts +1 -1
- package/tmp/pack.tgz +0 -0
- package/tsconfig.json +2 -1
- package/dist/derived-mutations.d.ts +0 -109
- package/dist/derived-mutations.d.ts.map +0 -1
- package/dist/derived-mutations.js +0 -54
- package/dist/derived-mutations.js.map +0 -1
- package/dist/derived-mutations.test.d.ts +0 -2
- package/dist/derived-mutations.test.d.ts.map +0 -1
- package/dist/derived-mutations.test.js +0 -93
- package/dist/derived-mutations.test.js.map +0 -1
- package/dist/devtools/devtools-bridge.d.ts +0 -12
- package/dist/devtools/devtools-bridge.d.ts.map +0 -1
- package/dist/devtools/devtools-bridge.js +0 -2
- package/dist/devtools/devtools-bridge.js.map +0 -1
- package/dist/devtools/index.d.ts +0 -42
- package/dist/devtools/index.d.ts.map +0 -1
- package/dist/devtools/index.js +0 -48
- package/dist/devtools/index.js.map +0 -1
- package/dist/init-singleton-tables.d.ts +0 -4
- package/dist/init-singleton-tables.d.ts.map +0 -1
- package/dist/init-singleton-tables.js +0 -16
- package/dist/init-singleton-tables.js.map +0 -1
- package/dist/leader-thread/apply-mutation.d.ts +0 -8
- package/dist/leader-thread/apply-mutation.d.ts.map +0 -1
- package/dist/leader-thread/apply-mutation.js +0 -95
- package/dist/leader-thread/apply-mutation.js.map +0 -1
- package/dist/leader-thread/leader-sync-processor.d.ts +0 -47
- package/dist/leader-thread/leader-sync-processor.d.ts.map +0 -1
- package/dist/leader-thread/leader-sync-processor.js +0 -422
- package/dist/leader-thread/leader-sync-processor.js.map +0 -1
- package/dist/leader-thread/mutationlog.d.ts +0 -23
- package/dist/leader-thread/mutationlog.d.ts.map +0 -1
- package/dist/leader-thread/mutationlog.js +0 -27
- package/dist/leader-thread/mutationlog.js.map +0 -1
- package/dist/leader-thread/pull-queue-set.d.ts +0 -7
- package/dist/leader-thread/pull-queue-set.d.ts.map +0 -1
- package/dist/leader-thread/pull-queue-set.js +0 -39
- package/dist/leader-thread/pull-queue-set.js.map +0 -1
- package/dist/mutation.d.ts +0 -13
- package/dist/mutation.d.ts.map +0 -1
- package/dist/mutation.js +0 -57
- package/dist/mutation.js.map +0 -1
- package/dist/query-info.d.ts +0 -38
- package/dist/query-info.d.ts.map +0 -1
- package/dist/query-info.js +0 -7
- package/dist/query-info.js.map +0 -1
- package/dist/rehydrate-from-mutationlog.d.ts +0 -14
- package/dist/rehydrate-from-mutationlog.d.ts.map +0 -1
- package/dist/rehydrate-from-mutationlog.js +0 -72
- package/dist/rehydrate-from-mutationlog.js.map +0 -1
- package/dist/schema/MutationEvent.d.ts +0 -191
- package/dist/schema/MutationEvent.d.ts.map +0 -1
- package/dist/schema/MutationEvent.js +0 -56
- package/dist/schema/MutationEvent.js.map +0 -1
- package/dist/schema/mutations.d.ts +0 -107
- package/dist/schema/mutations.d.ts.map +0 -1
- package/dist/schema/mutations.js +0 -42
- package/dist/schema/mutations.js.map +0 -1
- package/dist/sync/client-session-sync-processor.d.ts +0 -45
- package/dist/sync/client-session-sync-processor.d.ts.map +0 -1
- package/dist/sync/client-session-sync-processor.js +0 -131
- package/dist/sync/client-session-sync-processor.js.map +0 -1
- package/dist/sync/next/test/mutation-fixtures.d.ts.map +0 -1
- package/dist/sync/next/test/mutation-fixtures.js.map +0 -1
- package/src/derived-mutations.test.ts +0 -101
- package/src/derived-mutations.ts +0 -166
- package/src/devtools/devtools-bridge.ts +0 -13
- package/src/devtools/index.ts +0 -48
- package/src/init-singleton-tables.ts +0 -24
- package/src/leader-thread/apply-mutation.ts +0 -143
- package/src/leader-thread/leader-sync-processor.ts +0 -666
- package/src/leader-thread/mutationlog.ts +0 -42
- package/src/leader-thread/pull-queue-set.ts +0 -58
- package/src/mutation.ts +0 -81
- package/src/query-info.ts +0 -78
- package/src/rehydrate-from-mutationlog.ts +0 -127
- package/src/schema/MutationEvent.ts +0 -161
- package/src/schema/mutations.ts +0 -192
- package/src/sync/client-session-sync-processor.ts +0 -207
- package/src/sync/next/test/mutation-fixtures.ts +0 -231
package/src/schema/mutations.ts
DELETED
@@ -1,192 +0,0 @@
|
|
1
|
-
import { Schema } from '@livestore/utils/effect'
|
2
|
-
|
3
|
-
import type { BindValues } from '../sql-queries/sql-queries.js'
|
4
|
-
import type * as EventId from './EventId.js'
|
5
|
-
|
6
|
-
export type MutationDefMap = Map<string | 'livestore.RawSql', MutationDef.Any>
|
7
|
-
export type MutationDefRecord = {
|
8
|
-
'livestore.RawSql': RawSqlMutation
|
9
|
-
[name: string]: MutationDef.Any
|
10
|
-
}
|
11
|
-
|
12
|
-
export type InternalMutationSchema<TRecord extends MutationDefRecord = MutationDefRecord> = {
|
13
|
-
_DefRecord: TRecord
|
14
|
-
|
15
|
-
map: Map<keyof TRecord, TRecord[keyof TRecord]>
|
16
|
-
schemaHashMap: Map<keyof TRecord, number>
|
17
|
-
}
|
18
|
-
|
19
|
-
export type MutationDefSqlResult<TTo> =
|
20
|
-
| SingleOrReadonlyArray<string>
|
21
|
-
| ((args: TTo) => SingleOrReadonlyArray<
|
22
|
-
| string
|
23
|
-
| {
|
24
|
-
sql: string
|
25
|
-
/** Note args need to be manually encoded to `BindValues` when returning this argument */
|
26
|
-
bindValues: BindValues
|
27
|
-
writeTables?: ReadonlySet<string>
|
28
|
-
}
|
29
|
-
>)
|
30
|
-
|
31
|
-
export type SingleOrReadonlyArray<T> = T | ReadonlyArray<T>
|
32
|
-
|
33
|
-
export type MutationDef<TName extends string, TFrom, TTo> = {
|
34
|
-
name: TName
|
35
|
-
schema: Schema.Schema<TTo, TFrom>
|
36
|
-
sql: MutationDefSqlResult<NoInfer<TTo>>
|
37
|
-
options: {
|
38
|
-
/** Warning: This feature is not fully implemented yet */
|
39
|
-
historyId: string
|
40
|
-
/**
|
41
|
-
* When set to true, the mutation won't be synced over the network
|
42
|
-
*/
|
43
|
-
localOnly: boolean
|
44
|
-
/** Warning: This feature is not fully implemented yet */
|
45
|
-
facts: FactsCallback<TTo> | undefined
|
46
|
-
}
|
47
|
-
|
48
|
-
/** Helper function to construct a partial mutation event */
|
49
|
-
(
|
50
|
-
args: TTo,
|
51
|
-
options?: {
|
52
|
-
id?: number
|
53
|
-
},
|
54
|
-
): {
|
55
|
-
mutation: TName
|
56
|
-
args: TTo
|
57
|
-
// TODO remove/clean up after sync-next is fully implemented
|
58
|
-
id?: EventId.EventId
|
59
|
-
}
|
60
|
-
}
|
61
|
-
|
62
|
-
export type FactsCallback<TTo> = (
|
63
|
-
args: TTo,
|
64
|
-
currentFacts: MutationEventFacts,
|
65
|
-
) => {
|
66
|
-
modify: {
|
67
|
-
set: Iterable<MutationEventFactInput>
|
68
|
-
unset: Iterable<MutationEventFactInput>
|
69
|
-
}
|
70
|
-
require: Iterable<MutationEventFactInput>
|
71
|
-
}
|
72
|
-
|
73
|
-
export namespace MutationDef {
|
74
|
-
export type Any = MutationDef<string, any, any>
|
75
|
-
}
|
76
|
-
|
77
|
-
export type MutationEventKey = string
|
78
|
-
export type MutationEventFact = string
|
79
|
-
export type MutationEventFacts = ReadonlyMap<string, any>
|
80
|
-
|
81
|
-
export type MutationEventFactsGroup = {
|
82
|
-
modifySet: MutationEventFacts
|
83
|
-
modifyUnset: MutationEventFacts
|
84
|
-
|
85
|
-
/**
|
86
|
-
* Events on independent "dependency" branches are commutative which can facilitate more prioritized syncing
|
87
|
-
*/
|
88
|
-
depRequire: MutationEventFacts
|
89
|
-
depRead: MutationEventFacts
|
90
|
-
}
|
91
|
-
|
92
|
-
export type MutationEventFactsSnapshot = Map<string, any>
|
93
|
-
|
94
|
-
export type MutationEventFactInput = string | readonly [string, any]
|
95
|
-
|
96
|
-
export const defineFacts = <
|
97
|
-
TRecord extends Record<string, MutationEventFactInput | ((...args: any[]) => MutationEventFactInput)>,
|
98
|
-
>(
|
99
|
-
record: TRecord,
|
100
|
-
): TRecord => record
|
101
|
-
|
102
|
-
export type DefineMutationOptions<TTo> = {
|
103
|
-
// TODO actually implement this
|
104
|
-
onError?: (error: any) => void
|
105
|
-
historyId?: string
|
106
|
-
/** Warning: This feature is not fully implemented yet */
|
107
|
-
facts?: (
|
108
|
-
args: TTo,
|
109
|
-
currentFacts: MutationEventFacts,
|
110
|
-
) => {
|
111
|
-
modify?: {
|
112
|
-
set?: Iterable<MutationEventFactInput>
|
113
|
-
unset?: Iterable<MutationEventFactInput>
|
114
|
-
}
|
115
|
-
/**
|
116
|
-
* Two purposes: constrain history and constrain compaction
|
117
|
-
*/
|
118
|
-
require?: Iterable<MutationEventFactInput>
|
119
|
-
}
|
120
|
-
/**
|
121
|
-
* When set to true, the mutation won't be synced over the network
|
122
|
-
*/
|
123
|
-
localOnly?: boolean
|
124
|
-
}
|
125
|
-
|
126
|
-
// TODO possibly also allow for mutation event subsumption behaviour
|
127
|
-
export const defineMutation = <TName extends string, TFrom, TTo>(
|
128
|
-
name: TName,
|
129
|
-
schema: Schema.Schema<TTo, TFrom>,
|
130
|
-
sql: MutationDefSqlResult<NoInfer<TTo>>,
|
131
|
-
options?: DefineMutationOptions<TTo>,
|
132
|
-
): MutationDef<TName, TFrom, TTo> => {
|
133
|
-
const makePartialEvent = (
|
134
|
-
args: TTo,
|
135
|
-
options?: {
|
136
|
-
id?: EventId.EventId
|
137
|
-
},
|
138
|
-
) => ({ mutation: name, args, ...options })
|
139
|
-
|
140
|
-
Object.defineProperty(makePartialEvent, 'name', { value: name })
|
141
|
-
Object.defineProperty(makePartialEvent, 'schema', { value: schema })
|
142
|
-
Object.defineProperty(makePartialEvent, 'sql', { value: sql })
|
143
|
-
Object.defineProperty(makePartialEvent, 'options', {
|
144
|
-
value: {
|
145
|
-
historyId: options?.historyId ?? 'main',
|
146
|
-
localOnly: options?.localOnly ?? false,
|
147
|
-
facts: options?.facts
|
148
|
-
? (args, currentFacts) => {
|
149
|
-
const res = options.facts!(args, currentFacts)
|
150
|
-
return {
|
151
|
-
modify: {
|
152
|
-
set: res.modify?.set ? new Set(res.modify.set) : new Set(),
|
153
|
-
unset: res.modify?.unset ? new Set(res.modify.unset) : new Set(),
|
154
|
-
},
|
155
|
-
require: res.require ? new Set(res.require) : new Set(),
|
156
|
-
}
|
157
|
-
}
|
158
|
-
: undefined,
|
159
|
-
} satisfies MutationDef.Any['options'],
|
160
|
-
})
|
161
|
-
|
162
|
-
return makePartialEvent as MutationDef<TName, TFrom, TTo>
|
163
|
-
}
|
164
|
-
|
165
|
-
export const makeMutationDefRecord = <TInputRecord extends Record<string, MutationDef.Any>>(
|
166
|
-
inputRecord: TInputRecord,
|
167
|
-
): {
|
168
|
-
[K in TInputRecord[keyof TInputRecord]['name']]: Extract<TInputRecord[keyof TInputRecord], { name: K }>
|
169
|
-
} => {
|
170
|
-
const result: any = {}
|
171
|
-
|
172
|
-
for (const [name, def] of Object.entries(inputRecord)) {
|
173
|
-
result[name] = def
|
174
|
-
}
|
175
|
-
|
176
|
-
result['livestore.RawSql'] = rawSqlMutation
|
177
|
-
|
178
|
-
return result
|
179
|
-
}
|
180
|
-
|
181
|
-
export const rawSqlMutation = defineMutation(
|
182
|
-
'livestore.RawSql',
|
183
|
-
Schema.Struct({
|
184
|
-
sql: Schema.String,
|
185
|
-
bindValues: Schema.optional(Schema.Record({ key: Schema.String, value: Schema.Any })),
|
186
|
-
writeTables: Schema.optional(Schema.ReadonlySet(Schema.String)),
|
187
|
-
}),
|
188
|
-
({ sql, bindValues, writeTables }) => ({ sql, bindValues: bindValues ?? {}, writeTables }),
|
189
|
-
)
|
190
|
-
|
191
|
-
export type RawSqlMutation = typeof rawSqlMutation
|
192
|
-
export type RawSqlMutationEvent = ReturnType<typeof rawSqlMutation>
|
@@ -1,207 +0,0 @@
|
|
1
|
-
import { LS_DEV, shouldNeverHappen, TRACE_VERBOSE } from '@livestore/utils'
|
2
|
-
import type { Scope } from '@livestore/utils/effect'
|
3
|
-
import { Effect, Schema, Stream } from '@livestore/utils/effect'
|
4
|
-
import * as otel from '@opentelemetry/api'
|
5
|
-
|
6
|
-
import type { Coordinator, UnexpectedError } from '../adapter-types.js'
|
7
|
-
import * as EventId from '../schema/EventId.js'
|
8
|
-
import { type LiveStoreSchema } from '../schema/mod.js'
|
9
|
-
import * as MutationEvent from '../schema/MutationEvent.js'
|
10
|
-
import type { SyncState } from './syncstate.js'
|
11
|
-
import { updateSyncState } from './syncstate.js'
|
12
|
-
|
13
|
-
/**
|
14
|
-
* Rebase behaviour:
|
15
|
-
* - We continously pull mutations from the leader and apply them to the local store.
|
16
|
-
* - If there was a race condition (i.e. the leader and client session have both advacned),
|
17
|
-
* we'll need to rebase the local pending mutations on top of the leader's head.
|
18
|
-
* - The goal is to never block the UI, so we'll interrupt rebasing if a new mutations is pushed by the client session.
|
19
|
-
* - We also want to avoid "backwards-jumping" in the UI, so we'll transactionally apply a read model changes during a rebase.
|
20
|
-
* - We might need to make the rebase behaviour configurable e.g. to let users manually trigger a rebase
|
21
|
-
*/
|
22
|
-
export const makeClientSessionSyncProcessor = ({
|
23
|
-
schema,
|
24
|
-
initialLeaderHead,
|
25
|
-
pushToLeader,
|
26
|
-
pullFromLeader,
|
27
|
-
applyMutation,
|
28
|
-
rollback,
|
29
|
-
refreshTables,
|
30
|
-
span,
|
31
|
-
}: {
|
32
|
-
schema: LiveStoreSchema
|
33
|
-
initialLeaderHead: EventId.EventId
|
34
|
-
pushToLeader: (batch: ReadonlyArray<MutationEvent.AnyEncoded>) => void
|
35
|
-
pullFromLeader: Coordinator['mutations']['pull']
|
36
|
-
applyMutation: (
|
37
|
-
mutationEventDecoded: MutationEvent.PartialAny,
|
38
|
-
options: { otelContext: otel.Context; withChangeset: boolean },
|
39
|
-
) => {
|
40
|
-
writeTables: Set<string>
|
41
|
-
sessionChangeset: Uint8Array | undefined
|
42
|
-
}
|
43
|
-
rollback: (changeset: Uint8Array) => void
|
44
|
-
refreshTables: (tables: Set<string>) => void
|
45
|
-
// rebaseBehaviour: 'auto-rebase' | 'manual-rebase'
|
46
|
-
span: otel.Span
|
47
|
-
}): ClientSessionSyncProcessor => {
|
48
|
-
const mutationEventSchema = MutationEvent.makeMutationEventSchemaMemo(schema)
|
49
|
-
|
50
|
-
const syncStateRef = {
|
51
|
-
current: {
|
52
|
-
localHead: initialLeaderHead,
|
53
|
-
upstreamHead: initialLeaderHead,
|
54
|
-
pending: [],
|
55
|
-
// TODO init rollbackTail from leader to be ready for backend rebasing
|
56
|
-
rollbackTail: [],
|
57
|
-
} as SyncState,
|
58
|
-
}
|
59
|
-
|
60
|
-
const isLocalEvent = (mutationEventEncoded: MutationEvent.EncodedWithMeta) => {
|
61
|
-
const mutationDef = schema.mutations.get(mutationEventEncoded.mutation)!
|
62
|
-
return mutationDef.options.localOnly
|
63
|
-
}
|
64
|
-
|
65
|
-
const push: ClientSessionSyncProcessor['push'] = (batch, { otelContext }) => {
|
66
|
-
// TODO validate batch
|
67
|
-
|
68
|
-
let baseEventId = syncStateRef.current.localHead
|
69
|
-
const encodedMutationEvents = batch.map((mutationEvent) => {
|
70
|
-
const mutationDef = schema.mutations.get(mutationEvent.mutation)!
|
71
|
-
const nextIdPair = EventId.nextPair(baseEventId, mutationDef.options.localOnly)
|
72
|
-
baseEventId = nextIdPair.id
|
73
|
-
return new MutationEvent.EncodedWithMeta(
|
74
|
-
Schema.encodeUnknownSync(mutationEventSchema)({ ...mutationEvent, ...nextIdPair }),
|
75
|
-
)
|
76
|
-
})
|
77
|
-
|
78
|
-
const updateResult = updateSyncState({
|
79
|
-
syncState: syncStateRef.current,
|
80
|
-
payload: { _tag: 'local-push', newEvents: encodedMutationEvents },
|
81
|
-
isLocalEvent,
|
82
|
-
isEqualEvent: MutationEvent.isEqualEncoded,
|
83
|
-
})
|
84
|
-
|
85
|
-
span.addEvent('local-push', {
|
86
|
-
batchSize: encodedMutationEvents.length,
|
87
|
-
updateResult: TRACE_VERBOSE ? JSON.stringify(updateResult) : undefined,
|
88
|
-
})
|
89
|
-
|
90
|
-
if (updateResult._tag !== 'advance') {
|
91
|
-
return shouldNeverHappen(`Expected advance, got ${updateResult._tag}`)
|
92
|
-
}
|
93
|
-
|
94
|
-
syncStateRef.current = updateResult.newSyncState
|
95
|
-
|
96
|
-
const writeTables = new Set<string>()
|
97
|
-
for (const mutationEvent of updateResult.newEvents) {
|
98
|
-
// TODO avoid encoding and decoding here again
|
99
|
-
const decodedMutationEvent = Schema.decodeSync(mutationEventSchema)(mutationEvent)
|
100
|
-
const res = applyMutation(decodedMutationEvent, { otelContext, withChangeset: true })
|
101
|
-
for (const table of res.writeTables) {
|
102
|
-
writeTables.add(table)
|
103
|
-
}
|
104
|
-
mutationEvent.meta.sessionChangeset = res.sessionChangeset
|
105
|
-
}
|
106
|
-
|
107
|
-
pushToLeader(encodedMutationEvents)
|
108
|
-
|
109
|
-
return { writeTables }
|
110
|
-
}
|
111
|
-
|
112
|
-
const otelContext = otel.trace.setSpan(otel.context.active(), span)
|
113
|
-
|
114
|
-
const boot: ClientSessionSyncProcessor['boot'] = Effect.gen(function* () {
|
115
|
-
yield* pullFromLeader.pipe(
|
116
|
-
Stream.tap(({ payload, remaining }) =>
|
117
|
-
Effect.gen(function* () {
|
118
|
-
// console.log('pulled payload from leader', { payload, remaining })
|
119
|
-
|
120
|
-
const updateResult = updateSyncState({
|
121
|
-
syncState: syncStateRef.current,
|
122
|
-
payload,
|
123
|
-
isLocalEvent,
|
124
|
-
isEqualEvent: MutationEvent.isEqualEncoded,
|
125
|
-
})
|
126
|
-
|
127
|
-
if (updateResult._tag === 'reject') {
|
128
|
-
debugger
|
129
|
-
throw new Error('TODO: implement reject in client-session-sync-queue for pull')
|
130
|
-
}
|
131
|
-
|
132
|
-
syncStateRef.current = updateResult.newSyncState
|
133
|
-
|
134
|
-
if (updateResult._tag === 'rebase') {
|
135
|
-
span.addEvent('pull:rebase', {
|
136
|
-
payloadTag: payload._tag,
|
137
|
-
payload: TRACE_VERBOSE ? JSON.stringify(payload) : undefined,
|
138
|
-
newEventsCount: updateResult.newEvents.length,
|
139
|
-
rollbackCount: updateResult.eventsToRollback.length,
|
140
|
-
res: TRACE_VERBOSE ? JSON.stringify(updateResult) : undefined,
|
141
|
-
remaining,
|
142
|
-
})
|
143
|
-
if (LS_DEV) {
|
144
|
-
console.debug(
|
145
|
-
'pull:rebase: rollback',
|
146
|
-
updateResult.eventsToRollback.length,
|
147
|
-
...updateResult.eventsToRollback.map((_) => _.toJSON()),
|
148
|
-
)
|
149
|
-
}
|
150
|
-
|
151
|
-
for (let i = updateResult.eventsToRollback.length - 1; i >= 0; i--) {
|
152
|
-
const event = updateResult.eventsToRollback[i]!
|
153
|
-
if (event.meta.sessionChangeset) {
|
154
|
-
rollback(event.meta.sessionChangeset)
|
155
|
-
event.meta.sessionChangeset = undefined
|
156
|
-
}
|
157
|
-
}
|
158
|
-
} else {
|
159
|
-
span.addEvent('pull:advance', {
|
160
|
-
payloadTag: payload._tag,
|
161
|
-
payload: TRACE_VERBOSE ? JSON.stringify(payload) : undefined,
|
162
|
-
newEventsCount: updateResult.newEvents.length,
|
163
|
-
res: TRACE_VERBOSE ? JSON.stringify(updateResult) : undefined,
|
164
|
-
remaining,
|
165
|
-
})
|
166
|
-
}
|
167
|
-
|
168
|
-
if (updateResult.newEvents.length === 0) return
|
169
|
-
|
170
|
-
const writeTables = new Set<string>()
|
171
|
-
for (const mutationEvent of updateResult.newEvents) {
|
172
|
-
const decodedMutationEvent = Schema.decodeSync(mutationEventSchema)(mutationEvent)
|
173
|
-
const res = applyMutation(decodedMutationEvent, { otelContext, withChangeset: true })
|
174
|
-
for (const table of res.writeTables) {
|
175
|
-
writeTables.add(table)
|
176
|
-
}
|
177
|
-
|
178
|
-
mutationEvent.meta.sessionChangeset = res.sessionChangeset
|
179
|
-
}
|
180
|
-
|
181
|
-
refreshTables(writeTables)
|
182
|
-
}),
|
183
|
-
),
|
184
|
-
Stream.runDrain,
|
185
|
-
Effect.tapCauseLogPretty,
|
186
|
-
Effect.forkScoped,
|
187
|
-
)
|
188
|
-
})
|
189
|
-
|
190
|
-
return {
|
191
|
-
push,
|
192
|
-
boot,
|
193
|
-
syncStateRef,
|
194
|
-
} satisfies ClientSessionSyncProcessor
|
195
|
-
}
|
196
|
-
|
197
|
-
export interface ClientSessionSyncProcessor {
|
198
|
-
push: (
|
199
|
-
batch: ReadonlyArray<MutationEvent.PartialAny>,
|
200
|
-
options: { otelContext: otel.Context },
|
201
|
-
) => {
|
202
|
-
writeTables: Set<string>
|
203
|
-
}
|
204
|
-
boot: Effect.Effect<void, UnexpectedError, Scope.Scope>
|
205
|
-
|
206
|
-
syncStateRef: { current: SyncState }
|
207
|
-
}
|
@@ -1,231 +0,0 @@
|
|
1
|
-
import { Schema } from '@livestore/utils/effect'
|
2
|
-
|
3
|
-
import * as EventId from '../../../schema/EventId.js'
|
4
|
-
import type { MutationDef } from '../../../schema/mutations.js'
|
5
|
-
import { defineFacts, defineMutation } from '../../../schema/mutations.js'
|
6
|
-
import { factsSnapshotForDag, getFactsGroupForMutationArgs } from '../facts.js'
|
7
|
-
import { historyDagFromNodes } from '../history-dag.js'
|
8
|
-
import type { HistoryDagNode } from '../history-dag-common.js'
|
9
|
-
import { rootEventNode } from '../history-dag-common.js'
|
10
|
-
|
11
|
-
/** Used for conflict detection and event history compaction */
|
12
|
-
export const facts = defineFacts({
|
13
|
-
todoExists: (id: string) => `todo-exists-${id}`,
|
14
|
-
todoIsWriteable: (id: string, writeable: boolean) => [`todo-is-writeable-${id}`, writeable],
|
15
|
-
todoCompleted: (id: string, completed: boolean) => [`todo-completed-${id}`, completed],
|
16
|
-
todoTextUpdated: (id: string) => `todo-text-updated-${id}`,
|
17
|
-
inputValue: (id: string) => `input-value-${id}`,
|
18
|
-
})
|
19
|
-
|
20
|
-
export const mutations = {
|
21
|
-
createTodo: defineMutation(
|
22
|
-
'createTodo',
|
23
|
-
Schema.Struct({ id: Schema.String, text: Schema.String }),
|
24
|
-
'INSERT INTO todos (id, text) VALUES ($id, $text)',
|
25
|
-
{
|
26
|
-
facts: ({ id }) => ({
|
27
|
-
modify: {
|
28
|
-
set: [facts.todoExists(id), facts.todoIsWriteable(id, true), facts.todoCompleted(id, false)],
|
29
|
-
},
|
30
|
-
}),
|
31
|
-
},
|
32
|
-
),
|
33
|
-
upsertTodo: defineMutation(
|
34
|
-
'upsertTodo',
|
35
|
-
Schema.Struct({ id: Schema.String, text: Schema.optional(Schema.String) }),
|
36
|
-
'INSERT INTO todos (id, text) VALUES ($id, $text) ON CONFLICT (id) DO UPDATE SET text = $text',
|
37
|
-
{
|
38
|
-
facts: ({ id }, currentFacts) =>
|
39
|
-
// TODO enable an API along the lines of `map.has(key, value)`
|
40
|
-
currentFacts.has(facts.todoExists(id)) && currentFacts.get(facts.todoIsWriteable(id, true)[0]) === false
|
41
|
-
? { require: [facts.todoExists(id), facts.todoIsWriteable(id, true)] }
|
42
|
-
: { modify: { set: [facts.todoExists(id), facts.todoIsWriteable(id, true), facts.todoTextUpdated(id)] } },
|
43
|
-
},
|
44
|
-
),
|
45
|
-
completeTodo: defineMutation(
|
46
|
-
'completeTodo',
|
47
|
-
Schema.Struct({ id: Schema.String }),
|
48
|
-
// consider `RETURNING` to validate before applying facts
|
49
|
-
'UPDATE todos SET completed = true WHERE id = $id',
|
50
|
-
{
|
51
|
-
// prewrite assertions from DB
|
52
|
-
// enables more concurrency
|
53
|
-
// turning database inside out
|
54
|
-
// similar to upsert semantics
|
55
|
-
facts: ({ id }) => ({
|
56
|
-
require: [facts.todoExists(id), facts.todoIsWriteable(id, true)],
|
57
|
-
modify: { set: [facts.todoCompleted(id, true)] },
|
58
|
-
}),
|
59
|
-
},
|
60
|
-
),
|
61
|
-
uncompleteTodo: defineMutation(
|
62
|
-
'uncompleteTodo',
|
63
|
-
Schema.Struct({ id: Schema.String }),
|
64
|
-
'UPDATE todos SET completed = false WHERE id = $id',
|
65
|
-
{
|
66
|
-
facts: ({ id }) => ({
|
67
|
-
require: [facts.todoExists(id), facts.todoIsWriteable(id, true)],
|
68
|
-
modify: { set: [facts.todoCompleted(id, false)] },
|
69
|
-
}),
|
70
|
-
},
|
71
|
-
),
|
72
|
-
completeTodos: defineMutation(
|
73
|
-
'completeTodos',
|
74
|
-
Schema.Struct({ ids: Schema.Array(Schema.String) }),
|
75
|
-
'UPDATE todos SET completed = true WHERE id IN ($ids:csv)',
|
76
|
-
{
|
77
|
-
facts: ({ ids }) => ({
|
78
|
-
require: ids.flatMap((id) => [facts.todoExists(id), facts.todoIsWriteable(id, true)]),
|
79
|
-
modify: { set: ids.map((id) => facts.todoCompleted(id, true)) },
|
80
|
-
}),
|
81
|
-
},
|
82
|
-
),
|
83
|
-
toggleTodo: defineMutation(
|
84
|
-
'toggleTodo',
|
85
|
-
Schema.Struct({ id: Schema.String }),
|
86
|
-
'UPDATE todos SET completed = NOT completed WHERE id = $id',
|
87
|
-
{
|
88
|
-
facts: ({ id }, currentFacts) => {
|
89
|
-
const currentIsCompleted = currentFacts.get(facts.todoCompleted(id, true)[0]) === true
|
90
|
-
return {
|
91
|
-
require: [facts.todoExists(id), facts.todoIsWriteable(id, true)],
|
92
|
-
modify: {
|
93
|
-
// remove: [facts.todoCompleted(id, currentIsCompleted)],
|
94
|
-
set: [facts.todoCompleted(id, !currentIsCompleted)],
|
95
|
-
},
|
96
|
-
}
|
97
|
-
},
|
98
|
-
},
|
99
|
-
),
|
100
|
-
setReadonlyTodo: defineMutation(
|
101
|
-
'setReadonlyTodo',
|
102
|
-
Schema.Struct({ id: Schema.String, readonly: Schema.Boolean }),
|
103
|
-
'UPDATE todos SET readonly = $readonly WHERE id = $id',
|
104
|
-
{
|
105
|
-
facts: ({ id, readonly }) => ({
|
106
|
-
require: [facts.todoExists(id)],
|
107
|
-
modify: { set: [facts.todoIsWriteable(id, !readonly)] },
|
108
|
-
}),
|
109
|
-
},
|
110
|
-
),
|
111
|
-
setTextTodo: defineMutation(
|
112
|
-
'setTextTodo',
|
113
|
-
Schema.Struct({ id: Schema.String, text: Schema.String }),
|
114
|
-
'UPDATE todos SET text = $text WHERE id = $id',
|
115
|
-
{
|
116
|
-
facts: ({ id }) => ({
|
117
|
-
require: [facts.todoExists(id), facts.todoIsWriteable(id, true)],
|
118
|
-
modify: { set: [facts.todoTextUpdated(id)] },
|
119
|
-
}),
|
120
|
-
},
|
121
|
-
),
|
122
|
-
setInputValue: defineMutation(
|
123
|
-
'setInputValue',
|
124
|
-
Schema.Struct({ id: Schema.String, text: Schema.String }),
|
125
|
-
'UPDATE todos SET text = $text WHERE id = $id',
|
126
|
-
{
|
127
|
-
localOnly: true,
|
128
|
-
facts: ({ id }) => ({ modify: { set: [facts.inputValue(id)] } }),
|
129
|
-
},
|
130
|
-
),
|
131
|
-
}
|
132
|
-
|
133
|
-
export type PartialEvent = { mutation: string; args: any }
|
134
|
-
|
135
|
-
export const toEventNodes = (
|
136
|
-
partialEvents: PartialEvent[],
|
137
|
-
mutationDefs: Record<string, MutationDef.Any>,
|
138
|
-
): HistoryDagNode[] => {
|
139
|
-
const nodesAcc: HistoryDagNode[] = [rootEventNode]
|
140
|
-
|
141
|
-
let currentEventId: EventId.EventId = EventId.ROOT
|
142
|
-
|
143
|
-
const getNextEventId = (mutationDef: MutationDef.Any): EventId.EventId => {
|
144
|
-
if (mutationDef.options.localOnly) {
|
145
|
-
return { global: currentEventId.global, local: currentEventId.local + 1 }
|
146
|
-
}
|
147
|
-
return { global: currentEventId.global + 1, local: 0 }
|
148
|
-
}
|
149
|
-
|
150
|
-
const eventNodes = partialEvents.map((partialEvent) => {
|
151
|
-
const mutationDef = mutationDefs[partialEvent.mutation]!
|
152
|
-
const eventId = getNextEventId(mutationDef)
|
153
|
-
currentEventId = eventId
|
154
|
-
|
155
|
-
const factsSnapshot = factsSnapshotForDag(historyDagFromNodes(nodesAcc, { skipFactsCheck: true }), undefined)
|
156
|
-
// console.log('factsSnapshot', eventId, factsSnapshot)
|
157
|
-
// const depRead: MutationEventFactsSnapshot = new Map<string, any>()
|
158
|
-
// const factsSnapshotProxy = new Proxy(factsSnapshot, {
|
159
|
-
// get: (target, prop) => {
|
160
|
-
// if (prop === 'has') {
|
161
|
-
// return (key: string) => {
|
162
|
-
// depRead.set(key, EMPTY_FACT_VALUE)
|
163
|
-
// return target.has(key)
|
164
|
-
// }
|
165
|
-
// } else if (prop === 'get') {
|
166
|
-
// return (key: string) => {
|
167
|
-
// depRead.set(key, EMPTY_FACT_VALUE)
|
168
|
-
// return target.get(key)
|
169
|
-
// }
|
170
|
-
// }
|
171
|
-
|
172
|
-
// notYetImplemented(`toEventNodes: ${prop.toString()} is not yet implemented`)
|
173
|
-
// },
|
174
|
-
// })
|
175
|
-
|
176
|
-
// const factsRes = mutationDef.options.facts?.(partialEvent.args, factsSnapshotProxy)
|
177
|
-
// console.log('factsRes', factsRes?.modify, factsRes?.require)
|
178
|
-
// const iterableToMap = (iterable: Iterable<MutationEventFactInput>) => {
|
179
|
-
// const map = new Map()
|
180
|
-
// for (const item of iterable) {
|
181
|
-
// if (typeof item === 'string') {
|
182
|
-
// map.set(item, EMPTY_FACT_VALUE)
|
183
|
-
// } else {
|
184
|
-
// map.set(item[0], item[1])
|
185
|
-
// }
|
186
|
-
// }
|
187
|
-
// return map
|
188
|
-
// }
|
189
|
-
// const facts = {
|
190
|
-
// modifyAdd: factsRes?.modify.add ? iterableToMap(factsRes.modify.add) : new Map(),
|
191
|
-
// modifyRemove: factsRes?.modify.remove ? iterableToMap(factsRes.modify.remove) : new Map(),
|
192
|
-
// depRequire: factsRes?.require ? iterableToMap(factsRes.require) : new Map(),
|
193
|
-
// depRead,
|
194
|
-
// } satisfies MutationEventFactsGroup
|
195
|
-
|
196
|
-
// applyFactGroup(facts, factsSnapshot)
|
197
|
-
|
198
|
-
const facts = getFactsGroupForMutationArgs({
|
199
|
-
factsCallback: mutationDef.options.facts,
|
200
|
-
args: partialEvent.args,
|
201
|
-
currentFacts: factsSnapshot,
|
202
|
-
})
|
203
|
-
|
204
|
-
const node = {
|
205
|
-
id: eventId,
|
206
|
-
parentId: getParentId(eventId),
|
207
|
-
mutation: partialEvent.mutation,
|
208
|
-
args: partialEvent.args,
|
209
|
-
factsGroup: facts,
|
210
|
-
} satisfies HistoryDagNode
|
211
|
-
nodesAcc.push(node)
|
212
|
-
return node
|
213
|
-
})
|
214
|
-
|
215
|
-
eventNodes.unshift(rootEventNode as never)
|
216
|
-
|
217
|
-
// console.log('eventNodes', eventNodes)
|
218
|
-
|
219
|
-
return eventNodes
|
220
|
-
}
|
221
|
-
|
222
|
-
const getParentId = (eventId: EventId.EventId): EventId.EventId => {
|
223
|
-
const globalParentId = eventId.global
|
224
|
-
const localParentId = eventId.local - 1
|
225
|
-
|
226
|
-
if (localParentId < 0) {
|
227
|
-
return { global: globalParentId - 1, local: 0 }
|
228
|
-
}
|
229
|
-
|
230
|
-
return { global: globalParentId, local: localParentId }
|
231
|
-
}
|