@livestore/common 0.3.0-dev.9 → 0.3.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/__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 +120 -64
- package/dist/adapter-types.d.ts.map +1 -1
- package/dist/adapter-types.js +39 -8
- package/dist/adapter-types.js.map +1 -1
- package/dist/bounded-collections.d.ts.map +1 -1
- package/dist/debug-info.d.ts +1 -1
- package/dist/debug-info.d.ts.map +1 -1
- package/dist/debug-info.js +1 -0
- package/dist/debug-info.js.map +1 -1
- package/dist/devtools/devtools-messages-client-session.d.ts +390 -0
- package/dist/devtools/devtools-messages-client-session.d.ts.map +1 -0
- package/dist/devtools/devtools-messages-client-session.js +97 -0
- package/dist/devtools/devtools-messages-client-session.js.map +1 -0
- package/dist/devtools/devtools-messages-common.d.ts +68 -0
- package/dist/devtools/devtools-messages-common.d.ts.map +1 -0
- package/dist/devtools/devtools-messages-common.js +60 -0
- package/dist/devtools/devtools-messages-common.js.map +1 -0
- package/dist/devtools/devtools-messages-leader.d.ts +394 -0
- package/dist/devtools/devtools-messages-leader.d.ts.map +1 -0
- package/dist/devtools/devtools-messages-leader.js +147 -0
- package/dist/devtools/devtools-messages-leader.js.map +1 -0
- package/dist/devtools/devtools-messages.d.ts +3 -580
- package/dist/devtools/devtools-messages.d.ts.map +1 -1
- package/dist/devtools/devtools-messages.js +3 -174
- package/dist/devtools/devtools-messages.js.map +1 -1
- package/dist/devtools/devtools-sessioninfo.d.ts +32 -0
- package/dist/devtools/devtools-sessioninfo.d.ts.map +1 -0
- package/dist/devtools/devtools-sessioninfo.js +36 -0
- package/dist/devtools/devtools-sessioninfo.js.map +1 -0
- package/dist/devtools/mod.d.ts +55 -0
- package/dist/devtools/mod.d.ts.map +1 -0
- package/dist/devtools/mod.js +33 -0
- package/dist/devtools/mod.js.map +1 -0
- package/dist/index.d.ts +7 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -9
- package/dist/index.js.map +1 -1
- package/dist/leader-thread/LeaderSyncProcessor.d.ts +36 -11
- package/dist/leader-thread/LeaderSyncProcessor.d.ts.map +1 -1
- package/dist/leader-thread/LeaderSyncProcessor.js +426 -252
- package/dist/leader-thread/LeaderSyncProcessor.js.map +1 -1
- package/dist/leader-thread/connection.d.ts +34 -6
- package/dist/leader-thread/connection.d.ts.map +1 -1
- package/dist/leader-thread/connection.js +22 -7
- package/dist/leader-thread/connection.js.map +1 -1
- package/dist/leader-thread/eventlog.d.ts +27 -0
- package/dist/leader-thread/eventlog.d.ts.map +1 -0
- package/dist/leader-thread/eventlog.js +119 -0
- package/dist/leader-thread/eventlog.js.map +1 -0
- package/dist/leader-thread/leader-worker-devtools.d.ts.map +1 -1
- package/dist/leader-thread/leader-worker-devtools.js +155 -80
- package/dist/leader-thread/leader-worker-devtools.js.map +1 -1
- package/dist/leader-thread/make-leader-thread-layer.d.ts +22 -9
- package/dist/leader-thread/make-leader-thread-layer.d.ts.map +1 -1
- package/dist/leader-thread/make-leader-thread-layer.js +67 -45
- package/dist/leader-thread/make-leader-thread-layer.js.map +1 -1
- package/dist/leader-thread/materialize-event.d.ts +16 -0
- package/dist/leader-thread/materialize-event.d.ts.map +1 -0
- package/dist/leader-thread/materialize-event.js +109 -0
- package/dist/leader-thread/materialize-event.js.map +1 -0
- package/dist/leader-thread/mod.d.ts +1 -1
- package/dist/leader-thread/mod.d.ts.map +1 -1
- package/dist/leader-thread/mod.js +1 -1
- package/dist/leader-thread/mod.js.map +1 -1
- package/dist/leader-thread/recreate-db.d.ts +4 -2
- package/dist/leader-thread/recreate-db.d.ts.map +1 -1
- package/dist/leader-thread/recreate-db.js +28 -32
- 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 +79 -38
- package/dist/leader-thread/types.d.ts.map +1 -1
- package/dist/leader-thread/types.js +1 -3
- package/dist/leader-thread/types.js.map +1 -1
- package/dist/make-client-session.d.ts +23 -0
- package/dist/make-client-session.d.ts.map +1 -0
- package/dist/make-client-session.js +57 -0
- package/dist/make-client-session.js.map +1 -0
- package/dist/materializer-helper.d.ts +23 -0
- package/dist/materializer-helper.d.ts.map +1 -0
- package/dist/materializer-helper.js +86 -0
- package/dist/materializer-helper.js.map +1 -0
- package/dist/otel.d.ts +2 -0
- package/dist/otel.d.ts.map +1 -1
- package/dist/otel.js +5 -0
- package/dist/otel.js.map +1 -1
- package/dist/rematerialize-from-eventlog.d.ts +14 -0
- package/dist/rematerialize-from-eventlog.d.ts.map +1 -0
- package/dist/rematerialize-from-eventlog.js +64 -0
- package/dist/rematerialize-from-eventlog.js.map +1 -0
- package/dist/schema/EventDef.d.ts +146 -0
- package/dist/schema/EventDef.d.ts.map +1 -0
- package/dist/schema/EventDef.js +58 -0
- package/dist/schema/EventDef.js.map +1 -0
- package/dist/schema/EventSequenceNumber.d.ts +57 -0
- package/dist/schema/EventSequenceNumber.d.ts.map +1 -0
- package/dist/schema/EventSequenceNumber.js +82 -0
- package/dist/schema/EventSequenceNumber.js.map +1 -0
- package/dist/schema/EventSequenceNumber.test.d.ts +2 -0
- package/dist/schema/EventSequenceNumber.test.d.ts.map +1 -0
- package/dist/schema/EventSequenceNumber.test.js +11 -0
- package/dist/schema/EventSequenceNumber.test.js.map +1 -0
- package/dist/schema/LiveStoreEvent.d.ts +257 -0
- package/dist/schema/LiveStoreEvent.d.ts.map +1 -0
- package/dist/schema/LiveStoreEvent.js +117 -0
- package/dist/schema/LiveStoreEvent.js.map +1 -0
- package/dist/schema/events.d.ts +2 -0
- package/dist/schema/events.d.ts.map +1 -0
- package/dist/schema/events.js +2 -0
- package/dist/schema/events.js.map +1 -0
- package/dist/schema/mod.d.ts +8 -6
- package/dist/schema/mod.d.ts.map +1 -1
- package/dist/schema/mod.js +8 -6
- package/dist/schema/mod.js.map +1 -1
- package/dist/schema/schema.d.ts +50 -32
- package/dist/schema/schema.d.ts.map +1 -1
- package/dist/schema/schema.js +36 -43
- package/dist/schema/schema.js.map +1 -1
- package/dist/schema/state/mod.d.ts +3 -0
- package/dist/schema/state/mod.d.ts.map +1 -0
- package/dist/schema/state/mod.js +3 -0
- package/dist/schema/state/mod.js.map +1 -0
- package/dist/schema/state/sqlite/client-document-def.d.ts +223 -0
- package/dist/schema/state/sqlite/client-document-def.d.ts.map +1 -0
- package/dist/schema/state/sqlite/client-document-def.js +170 -0
- package/dist/schema/state/sqlite/client-document-def.js.map +1 -0
- package/dist/schema/state/sqlite/client-document-def.test.d.ts +2 -0
- package/dist/schema/state/sqlite/client-document-def.test.d.ts.map +1 -0
- package/dist/schema/state/sqlite/client-document-def.test.js +201 -0
- package/dist/schema/state/sqlite/client-document-def.test.js.map +1 -0
- package/dist/schema/state/sqlite/db-schema/ast/sqlite.d.ts +69 -0
- package/dist/schema/state/sqlite/db-schema/ast/sqlite.d.ts.map +1 -0
- package/dist/schema/state/sqlite/db-schema/ast/sqlite.js +71 -0
- package/dist/schema/state/sqlite/db-schema/ast/sqlite.js.map +1 -0
- package/dist/schema/state/sqlite/db-schema/ast/validate.d.ts +3 -0
- package/dist/schema/state/sqlite/db-schema/ast/validate.d.ts.map +1 -0
- package/dist/schema/state/sqlite/db-schema/ast/validate.js +12 -0
- package/dist/schema/state/sqlite/db-schema/ast/validate.js.map +1 -0
- package/dist/schema/state/sqlite/db-schema/dsl/field-defs.d.ts +90 -0
- package/dist/schema/state/sqlite/db-schema/dsl/field-defs.d.ts.map +1 -0
- package/dist/schema/state/sqlite/db-schema/dsl/field-defs.js +87 -0
- package/dist/schema/state/sqlite/db-schema/dsl/field-defs.js.map +1 -0
- package/dist/schema/state/sqlite/db-schema/dsl/field-defs.test.d.ts +2 -0
- package/dist/schema/state/sqlite/db-schema/dsl/field-defs.test.d.ts.map +1 -0
- package/dist/schema/state/sqlite/db-schema/dsl/field-defs.test.js +29 -0
- package/dist/schema/state/sqlite/db-schema/dsl/field-defs.test.js.map +1 -0
- package/dist/schema/state/sqlite/db-schema/dsl/mod.d.ts +90 -0
- package/dist/schema/state/sqlite/db-schema/dsl/mod.d.ts.map +1 -0
- package/dist/schema/state/sqlite/db-schema/dsl/mod.js +41 -0
- package/dist/schema/state/sqlite/db-schema/dsl/mod.js.map +1 -0
- package/dist/schema/state/sqlite/db-schema/hash.d.ts +2 -0
- package/dist/schema/state/sqlite/db-schema/hash.d.ts.map +1 -0
- package/dist/schema/state/sqlite/db-schema/hash.js +14 -0
- package/dist/schema/state/sqlite/db-schema/hash.js.map +1 -0
- package/dist/schema/state/sqlite/db-schema/mod.d.ts +3 -0
- package/dist/schema/state/sqlite/db-schema/mod.d.ts.map +1 -0
- package/dist/schema/state/sqlite/db-schema/mod.js +3 -0
- package/dist/schema/state/sqlite/db-schema/mod.js.map +1 -0
- package/dist/schema/state/sqlite/mod.d.ts +17 -0
- package/dist/schema/state/sqlite/mod.d.ts.map +1 -0
- package/dist/schema/state/sqlite/mod.js +41 -0
- package/dist/schema/state/sqlite/mod.js.map +1 -0
- package/dist/schema/state/sqlite/query-builder/api.d.ts +294 -0
- package/dist/schema/state/sqlite/query-builder/api.d.ts.map +1 -0
- package/dist/schema/state/sqlite/query-builder/api.js +6 -0
- package/dist/schema/state/sqlite/query-builder/api.js.map +1 -0
- package/dist/schema/state/sqlite/query-builder/astToSql.d.ts +7 -0
- package/dist/schema/state/sqlite/query-builder/astToSql.d.ts.map +1 -0
- package/dist/schema/state/sqlite/query-builder/astToSql.js +190 -0
- package/dist/schema/state/sqlite/query-builder/astToSql.js.map +1 -0
- package/dist/schema/state/sqlite/query-builder/impl.d.ts +7 -0
- package/dist/schema/state/sqlite/query-builder/impl.d.ts.map +1 -0
- package/dist/schema/state/sqlite/query-builder/impl.js +286 -0
- package/dist/schema/state/sqlite/query-builder/impl.js.map +1 -0
- package/dist/schema/state/sqlite/query-builder/impl.test.d.ts +87 -0
- package/dist/schema/state/sqlite/query-builder/impl.test.d.ts.map +1 -0
- package/dist/schema/state/sqlite/query-builder/impl.test.js +563 -0
- package/dist/schema/state/sqlite/query-builder/impl.test.js.map +1 -0
- package/dist/{query-builder → schema/state/sqlite/query-builder}/mod.d.ts +7 -0
- package/dist/schema/state/sqlite/query-builder/mod.d.ts.map +1 -0
- package/dist/{query-builder → schema/state/sqlite/query-builder}/mod.js +7 -0
- package/dist/schema/state/sqlite/query-builder/mod.js.map +1 -0
- package/dist/schema/state/sqlite/schema-helpers.d.ts.map +1 -0
- package/dist/schema/{schema-helpers.js → state/sqlite/schema-helpers.js} +1 -1
- package/dist/schema/state/sqlite/schema-helpers.js.map +1 -0
- package/dist/schema/state/sqlite/system-tables.d.ts +574 -0
- package/dist/schema/state/sqlite/system-tables.d.ts.map +1 -0
- package/dist/schema/state/sqlite/system-tables.js +88 -0
- package/dist/schema/state/sqlite/system-tables.js.map +1 -0
- package/dist/schema/state/sqlite/table-def.d.ts +84 -0
- package/dist/schema/state/sqlite/table-def.d.ts.map +1 -0
- package/dist/schema/state/sqlite/table-def.js +36 -0
- package/dist/schema/state/sqlite/table-def.js.map +1 -0
- package/dist/schema-management/common.d.ts +7 -7
- package/dist/schema-management/common.d.ts.map +1 -1
- package/dist/schema-management/common.js.map +1 -1
- package/dist/schema-management/migrations.d.ts +6 -6
- package/dist/schema-management/migrations.d.ts.map +1 -1
- package/dist/schema-management/migrations.js +27 -18
- package/dist/schema-management/migrations.js.map +1 -1
- package/dist/schema-management/validate-schema.d.ts +8 -0
- package/dist/schema-management/validate-schema.d.ts.map +1 -0
- package/dist/schema-management/validate-schema.js +39 -0
- package/dist/schema-management/validate-schema.js.map +1 -0
- package/dist/sql-queries/misc.d.ts.map +1 -1
- package/dist/sql-queries/sql-queries.d.ts +1 -1
- package/dist/sql-queries/sql-queries.d.ts.map +1 -1
- package/dist/sql-queries/sql-queries.js.map +1 -1
- package/dist/sql-queries/sql-query-builder.d.ts +1 -1
- package/dist/sql-queries/sql-query-builder.d.ts.map +1 -1
- package/dist/sql-queries/sql-query-builder.js.map +1 -1
- package/dist/sql-queries/types.d.ts +2 -1
- package/dist/sql-queries/types.d.ts.map +1 -1
- package/dist/sql-queries/types.js.map +1 -1
- package/dist/sync/ClientSessionSyncProcessor.d.ts +40 -19
- package/dist/sync/ClientSessionSyncProcessor.d.ts.map +1 -1
- package/dist/sync/ClientSessionSyncProcessor.js +149 -73
- package/dist/sync/ClientSessionSyncProcessor.js.map +1 -1
- package/dist/sync/next/compact-events.d.ts.map +1 -1
- package/dist/sync/next/compact-events.js +38 -35
- package/dist/sync/next/compact-events.js.map +1 -1
- package/dist/sync/next/facts.d.ts +21 -21
- package/dist/sync/next/facts.d.ts.map +1 -1
- package/dist/sync/next/facts.js +11 -11
- package/dist/sync/next/facts.js.map +1 -1
- package/dist/sync/next/history-dag-common.d.ts +9 -7
- package/dist/sync/next/history-dag-common.d.ts.map +1 -1
- package/dist/sync/next/history-dag-common.js +10 -5
- package/dist/sync/next/history-dag-common.js.map +1 -1
- package/dist/sync/next/history-dag.d.ts +0 -2
- package/dist/sync/next/history-dag.d.ts.map +1 -1
- package/dist/sync/next/history-dag.js +16 -14
- 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 +18 -10
- package/dist/sync/next/rebase-events.js.map +1 -1
- package/dist/sync/next/test/compact-events.calculator.test.js +39 -34
- package/dist/sync/next/test/compact-events.calculator.test.js.map +1 -1
- package/dist/sync/next/test/compact-events.test.js +77 -77
- 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} +35 -25
- package/dist/sync/next/test/event-fixtures.d.ts.map +1 -0
- package/dist/sync/next/test/{mutation-fixtures.js → event-fixtures.js} +81 -38
- 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 +46 -21
- package/dist/sync/sync.d.ts.map +1 -1
- package/dist/sync/sync.js +10 -6
- package/dist/sync/sync.js.map +1 -1
- package/dist/sync/syncstate.d.ts +193 -84
- package/dist/sync/syncstate.d.ts.map +1 -1
- package/dist/sync/syncstate.js +305 -151
- package/dist/sync/syncstate.js.map +1 -1
- package/dist/sync/syncstate.test.js +267 -303
- 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 +4 -4
- 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 +2 -2
- package/dist/version.d.ts.map +1 -1
- package/dist/version.js +2 -2
- package/dist/version.js.map +1 -1
- package/package.json +10 -4
- package/src/__tests__/fixture.ts +36 -15
- package/src/adapter-types.ts +107 -68
- package/src/debug-info.ts +1 -0
- package/src/devtools/devtools-messages-client-session.ts +142 -0
- package/src/devtools/devtools-messages-common.ts +115 -0
- package/src/devtools/devtools-messages-leader.ts +191 -0
- package/src/devtools/devtools-messages.ts +3 -246
- package/src/devtools/devtools-sessioninfo.ts +101 -0
- package/src/devtools/mod.ts +59 -0
- package/src/index.ts +7 -9
- package/src/leader-thread/LeaderSyncProcessor.ts +664 -394
- package/src/leader-thread/connection.ts +54 -9
- package/src/leader-thread/eventlog.ts +199 -0
- package/src/leader-thread/leader-worker-devtools.ts +227 -104
- package/src/leader-thread/make-leader-thread-layer.ts +121 -72
- package/src/leader-thread/materialize-event.ts +173 -0
- package/src/leader-thread/mod.ts +1 -1
- package/src/leader-thread/recreate-db.ts +33 -38
- package/src/leader-thread/shutdown-channel.ts +2 -4
- package/src/leader-thread/types.ts +84 -46
- package/src/make-client-session.ts +136 -0
- package/src/materializer-helper.ts +138 -0
- package/src/otel.ts +8 -0
- package/src/rematerialize-from-eventlog.ts +117 -0
- package/src/schema/EventDef.ts +227 -0
- package/src/schema/EventSequenceNumber.test.ts +12 -0
- package/src/schema/EventSequenceNumber.ts +121 -0
- package/src/schema/LiveStoreEvent.ts +240 -0
- package/src/schema/events.ts +1 -0
- package/src/schema/mod.ts +8 -6
- package/src/schema/schema.ts +88 -84
- package/src/schema/state/mod.ts +2 -0
- package/src/schema/state/sqlite/client-document-def.test.ts +238 -0
- package/src/schema/state/sqlite/client-document-def.ts +444 -0
- package/src/schema/state/sqlite/db-schema/ast/sqlite.ts +142 -0
- package/src/schema/state/sqlite/db-schema/ast/validate.ts +13 -0
- package/src/schema/state/sqlite/db-schema/dsl/__snapshots__/field-defs.test.ts.snap +206 -0
- package/src/schema/state/sqlite/db-schema/dsl/field-defs.test.ts +35 -0
- package/src/schema/state/sqlite/db-schema/dsl/field-defs.ts +242 -0
- package/src/schema/state/sqlite/db-schema/dsl/mod.ts +222 -0
- package/src/schema/state/sqlite/db-schema/hash.ts +14 -0
- package/src/schema/state/sqlite/db-schema/mod.ts +2 -0
- package/src/schema/state/sqlite/mod.ts +73 -0
- package/src/schema/state/sqlite/query-builder/api.ts +440 -0
- package/src/schema/state/sqlite/query-builder/astToSql.ts +232 -0
- package/src/schema/state/sqlite/query-builder/impl.test.ts +617 -0
- package/src/schema/state/sqlite/query-builder/impl.ts +351 -0
- package/src/{query-builder → schema/state/sqlite/query-builder}/mod.ts +7 -0
- package/src/schema/{schema-helpers.ts → state/sqlite/schema-helpers.ts} +1 -1
- package/src/schema/state/sqlite/system-tables.ts +117 -0
- package/src/schema/state/sqlite/table-def.ts +197 -0
- package/src/schema-management/common.ts +7 -7
- package/src/schema-management/migrations.ts +37 -31
- package/src/schema-management/validate-schema.ts +61 -0
- package/src/sql-queries/sql-queries.ts +1 -1
- package/src/sql-queries/sql-query-builder.ts +1 -2
- package/src/sql-queries/types.ts +3 -1
- package/src/sync/ClientSessionSyncProcessor.ts +218 -94
- package/src/sync/next/compact-events.ts +38 -35
- package/src/sync/next/facts.ts +43 -41
- package/src/sync/next/history-dag-common.ts +17 -10
- package/src/sync/next/history-dag.ts +16 -17
- package/src/sync/next/rebase-events.ts +29 -17
- package/src/sync/next/test/compact-events.calculator.test.ts +46 -46
- package/src/sync/next/test/compact-events.test.ts +79 -79
- package/src/sync/next/test/event-fixtures.ts +226 -0
- package/src/sync/next/test/mod.ts +1 -1
- package/src/sync/sync.ts +46 -21
- package/src/sync/syncstate.test.ts +312 -345
- package/src/sync/syncstate.ts +414 -224
- package/src/sync/validate-push-payload.ts +6 -6
- package/src/version.ts +2 -2
- 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 -13
- package/dist/devtools/devtools-bridge.d.ts.map +0 -1
- package/dist/devtools/devtools-bridge.js +0 -2
- package/dist/devtools/devtools-bridge.js.map +0 -1
- package/dist/devtools/devtools-window-message.d.ts +0 -29
- package/dist/devtools/devtools-window-message.d.ts.map +0 -1
- package/dist/devtools/devtools-window-message.js +0 -33
- package/dist/devtools/devtools-window-message.js.map +0 -1
- package/dist/devtools/index.d.ts +0 -42
- package/dist/devtools/index.d.ts.map +0 -1
- package/dist/devtools/index.js +0 -48
- package/dist/devtools/index.js.map +0 -1
- package/dist/init-singleton-tables.d.ts +0 -4
- package/dist/init-singleton-tables.d.ts.map +0 -1
- package/dist/init-singleton-tables.js +0 -16
- package/dist/init-singleton-tables.js.map +0 -1
- package/dist/leader-thread/apply-mutation.d.ts +0 -11
- package/dist/leader-thread/apply-mutation.d.ts.map +0 -1
- package/dist/leader-thread/apply-mutation.js +0 -107
- 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 -430
- package/dist/leader-thread/leader-sync-processor.js.map +0 -1
- package/dist/leader-thread/mutationlog.d.ts +0 -10
- package/dist/leader-thread/mutationlog.d.ts.map +0 -1
- package/dist/leader-thread/mutationlog.js +0 -28
- 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 -20
- package/dist/mutation.d.ts.map +0 -1
- package/dist/mutation.js +0 -57
- package/dist/mutation.js.map +0 -1
- package/dist/query-builder/api.d.ts +0 -190
- package/dist/query-builder/api.d.ts.map +0 -1
- package/dist/query-builder/api.js +0 -8
- package/dist/query-builder/api.js.map +0 -1
- package/dist/query-builder/impl.d.ts +0 -12
- package/dist/query-builder/impl.d.ts.map +0 -1
- package/dist/query-builder/impl.js +0 -244
- package/dist/query-builder/impl.js.map +0 -1
- package/dist/query-builder/impl.test.d.ts +0 -2
- package/dist/query-builder/impl.test.d.ts.map +0 -1
- package/dist/query-builder/impl.test.js +0 -212
- package/dist/query-builder/impl.test.js.map +0 -1
- package/dist/query-builder/mod.d.ts.map +0 -1
- package/dist/query-builder/mod.js.map +0 -1
- package/dist/query-info.d.ts +0 -38
- package/dist/query-info.d.ts.map +0 -1
- package/dist/query-info.js +0 -7
- package/dist/query-info.js.map +0 -1
- package/dist/rehydrate-from-mutationlog.d.ts +0 -14
- package/dist/rehydrate-from-mutationlog.d.ts.map +0 -1
- package/dist/rehydrate-from-mutationlog.js +0 -66
- package/dist/rehydrate-from-mutationlog.js.map +0 -1
- package/dist/schema/EventId.d.ts +0 -39
- package/dist/schema/EventId.d.ts.map +0 -1
- package/dist/schema/EventId.js +0 -38
- package/dist/schema/EventId.js.map +0 -1
- package/dist/schema/EventId.test.d.ts +0 -2
- package/dist/schema/EventId.test.d.ts.map +0 -1
- package/dist/schema/EventId.test.js +0 -11
- package/dist/schema/EventId.test.js.map +0 -1
- package/dist/schema/MutationEvent.d.ts +0 -167
- package/dist/schema/MutationEvent.d.ts.map +0 -1
- package/dist/schema/MutationEvent.js +0 -72
- package/dist/schema/MutationEvent.js.map +0 -1
- package/dist/schema/MutationEvent.test.d.ts +0 -2
- package/dist/schema/MutationEvent.test.d.ts.map +0 -1
- package/dist/schema/MutationEvent.test.js +0 -2
- package/dist/schema/MutationEvent.test.js.map +0 -1
- package/dist/schema/mutations.d.ts +0 -107
- package/dist/schema/mutations.d.ts.map +0 -1
- package/dist/schema/mutations.js +0 -42
- package/dist/schema/mutations.js.map +0 -1
- package/dist/schema/schema-helpers.d.ts.map +0 -1
- package/dist/schema/schema-helpers.js.map +0 -1
- package/dist/schema/system-tables.d.ts +0 -399
- package/dist/schema/system-tables.d.ts.map +0 -1
- package/dist/schema/system-tables.js +0 -59
- package/dist/schema/system-tables.js.map +0 -1
- package/dist/schema/table-def.d.ts +0 -156
- package/dist/schema/table-def.d.ts.map +0 -1
- package/dist/schema/table-def.js +0 -79
- package/dist/schema/table-def.js.map +0 -1
- package/dist/schema-management/validate-mutation-defs.d.ts +0 -8
- package/dist/schema-management/validate-mutation-defs.d.ts.map +0 -1
- package/dist/schema-management/validate-mutation-defs.js +0 -39
- package/dist/schema-management/validate-mutation-defs.js.map +0 -1
- package/dist/sync/client-session-sync-processor.d.ts +0 -45
- package/dist/sync/client-session-sync-processor.d.ts.map +0 -1
- package/dist/sync/client-session-sync-processor.js +0 -131
- package/dist/sync/client-session-sync-processor.js.map +0 -1
- package/dist/sync/next/test/mutation-fixtures.d.ts.map +0 -1
- package/dist/sync/next/test/mutation-fixtures.js.map +0 -1
- package/src/derived-mutations.test.ts +0 -101
- package/src/derived-mutations.ts +0 -170
- package/src/devtools/devtools-bridge.ts +0 -14
- package/src/devtools/devtools-window-message.ts +0 -27
- package/src/devtools/index.ts +0 -48
- package/src/init-singleton-tables.ts +0 -24
- package/src/leader-thread/apply-mutation.ts +0 -161
- package/src/leader-thread/mutationlog.ts +0 -46
- package/src/leader-thread/pull-queue-set.ts +0 -58
- package/src/mutation.ts +0 -91
- package/src/query-builder/api.ts +0 -289
- package/src/query-builder/impl.test.ts +0 -239
- package/src/query-builder/impl.ts +0 -285
- package/src/query-info.ts +0 -78
- package/src/rehydrate-from-mutationlog.ts +0 -119
- package/src/schema/EventId.test.ts +0 -12
- package/src/schema/EventId.ts +0 -60
- package/src/schema/MutationEvent.ts +0 -185
- package/src/schema/mutations.ts +0 -192
- package/src/schema/system-tables.ts +0 -105
- package/src/schema/table-def.ts +0 -343
- package/src/schema-management/validate-mutation-defs.ts +0 -63
- package/src/sync/next/test/mutation-fixtures.ts +0 -224
- package/tsconfig.json +0 -11
- /package/dist/schema/{schema-helpers.d.ts → state/sqlite/schema-helpers.d.ts} +0 -0
@@ -1,188 +1,284 @@
|
|
1
|
+
/// <reference lib="dom" />
|
1
2
|
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'
|
3
|
+
import type { Runtime, Scope } from '@livestore/utils/effect'
|
4
|
+
import { BucketQueue, Effect, FiberHandle, Queue, Schema, Stream, Subscribable } from '@livestore/utils/effect'
|
4
5
|
import * as otel from '@opentelemetry/api'
|
5
6
|
|
6
|
-
import type {
|
7
|
-
import * as
|
8
|
-
import
|
9
|
-
import
|
10
|
-
import {
|
7
|
+
import type { ClientSession, UnexpectedError } from '../adapter-types.js'
|
8
|
+
import * as EventSequenceNumber from '../schema/EventSequenceNumber.js'
|
9
|
+
import * as LiveStoreEvent from '../schema/LiveStoreEvent.js'
|
10
|
+
import { getEventDef, type LiveStoreSchema, SystemTables } from '../schema/mod.js'
|
11
|
+
import { sql } from '../util.js'
|
12
|
+
import * as SyncState from './syncstate.js'
|
11
13
|
|
12
14
|
/**
|
13
15
|
* Rebase behaviour:
|
14
|
-
* - We continously pull
|
16
|
+
* - We continously pull events from the leader and apply them to the local store.
|
15
17
|
* - If there was a race condition (i.e. the leader and client session have both advacned),
|
16
|
-
* we'll need to rebase the local pending
|
17
|
-
* - The goal is to never block the UI, so we'll interrupt rebasing if a new
|
18
|
-
* - We also want to avoid "backwards-jumping" in the UI, so we'll transactionally apply
|
18
|
+
* we'll need to rebase the local pending events on top of the leader's head.
|
19
|
+
* - The goal is to never block the UI, so we'll interrupt rebasing if a new events is pushed by the client session.
|
20
|
+
* - We also want to avoid "backwards-jumping" in the UI, so we'll transactionally apply state changes during a rebase.
|
19
21
|
* - We might need to make the rebase behaviour configurable e.g. to let users manually trigger a rebase
|
22
|
+
*
|
23
|
+
* Longer term we should evalutate whether we can unify the ClientSessionSyncProcessor with the LeaderSyncProcessor.
|
20
24
|
*/
|
21
25
|
export const makeClientSessionSyncProcessor = ({
|
22
26
|
schema,
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
applyMutation,
|
27
|
+
clientSession,
|
28
|
+
runtime,
|
29
|
+
materializeEvent,
|
27
30
|
rollback,
|
28
31
|
refreshTables,
|
29
32
|
span,
|
33
|
+
params,
|
34
|
+
confirmUnsavedChanges,
|
30
35
|
}: {
|
31
36
|
schema: LiveStoreSchema
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
mutationEventDecoded: MutationEvent.PartialAnyDecoded,
|
37
|
+
clientSession: ClientSession
|
38
|
+
runtime: Runtime.Runtime<Scope.Scope>
|
39
|
+
materializeEvent: (
|
40
|
+
eventDecoded: LiveStoreEvent.PartialAnyDecoded,
|
37
41
|
options: { otelContext: otel.Context; withChangeset: boolean },
|
38
42
|
) => {
|
39
43
|
writeTables: Set<string>
|
40
|
-
sessionChangeset: Uint8Array |
|
44
|
+
sessionChangeset: { _tag: 'sessionChangeset'; data: Uint8Array; debug: any } | { _tag: 'no-op' } | { _tag: 'unset' }
|
41
45
|
}
|
42
46
|
rollback: (changeset: Uint8Array) => void
|
43
47
|
refreshTables: (tables: Set<string>) => void
|
44
48
|
span: otel.Span
|
49
|
+
params: {
|
50
|
+
leaderPushBatchSize: number
|
51
|
+
}
|
52
|
+
/**
|
53
|
+
* Currently only used in the web adapter:
|
54
|
+
* If true, registers a beforeunload event listener to confirm unsaved changes.
|
55
|
+
*/
|
56
|
+
confirmUnsavedChanges: boolean
|
45
57
|
}): ClientSessionSyncProcessor => {
|
46
|
-
const
|
58
|
+
const eventSchema = LiveStoreEvent.makeEventDefSchemaMemo(schema)
|
47
59
|
|
48
60
|
const syncStateRef = {
|
49
|
-
|
50
|
-
|
51
|
-
|
61
|
+
// The initial state is identical to the leader's initial state
|
62
|
+
current: new SyncState.SyncState({
|
63
|
+
localHead: clientSession.leaderThread.initialState.leaderHead,
|
64
|
+
upstreamHead: clientSession.leaderThread.initialState.leaderHead,
|
65
|
+
// Given we're starting with the leader's snapshot, we don't have any pending events intially
|
52
66
|
pending: [],
|
53
|
-
// TODO init rollbackTail from leader to be ready for backend rebasing
|
54
|
-
rollbackTail: [],
|
55
67
|
}),
|
56
68
|
}
|
57
69
|
|
58
|
-
const
|
59
|
-
|
60
|
-
|
61
|
-
|
70
|
+
const syncStateUpdateQueue = Queue.unbounded<SyncState.SyncState>().pipe(Effect.runSync)
|
71
|
+
const isClientEvent = (eventEncoded: LiveStoreEvent.EncodedWithMeta) =>
|
72
|
+
getEventDef(schema, eventEncoded.name).eventDef.options.clientOnly
|
73
|
+
|
74
|
+
/** We're queuing push requests to reduce the number of messages sent to the leader by batching them */
|
75
|
+
const leaderPushQueue = BucketQueue.make<LiveStoreEvent.EncodedWithMeta>().pipe(Effect.runSync)
|
62
76
|
|
63
77
|
const push: ClientSessionSyncProcessor['push'] = (batch, { otelContext }) => {
|
64
78
|
// TODO validate batch
|
65
79
|
|
66
|
-
let
|
67
|
-
const
|
68
|
-
const
|
69
|
-
const
|
70
|
-
|
71
|
-
return new
|
72
|
-
Schema.encodeUnknownSync(
|
80
|
+
let baseEventSequenceNumber = syncStateRef.current.localHead
|
81
|
+
const encodedEventDefs = batch.map(({ name, args }) => {
|
82
|
+
const eventDef = getEventDef(schema, name)
|
83
|
+
const nextNumPair = EventSequenceNumber.nextPair(baseEventSequenceNumber, eventDef.eventDef.options.clientOnly)
|
84
|
+
baseEventSequenceNumber = nextNumPair.seqNum
|
85
|
+
return new LiveStoreEvent.EncodedWithMeta(
|
86
|
+
Schema.encodeUnknownSync(eventSchema)({
|
87
|
+
name,
|
88
|
+
args,
|
89
|
+
...nextNumPair,
|
90
|
+
clientId: clientSession.clientId,
|
91
|
+
sessionId: clientSession.sessionId,
|
92
|
+
}),
|
73
93
|
)
|
74
94
|
})
|
75
95
|
|
76
|
-
const
|
96
|
+
const mergeResult = SyncState.merge({
|
77
97
|
syncState: syncStateRef.current,
|
78
|
-
payload: { _tag: 'local-push', newEvents:
|
79
|
-
|
80
|
-
isEqualEvent:
|
98
|
+
payload: { _tag: 'local-push', newEvents: encodedEventDefs },
|
99
|
+
isClientEvent,
|
100
|
+
isEqualEvent: LiveStoreEvent.isEqualEncoded,
|
81
101
|
})
|
82
102
|
|
103
|
+
if (mergeResult._tag === 'unexpected-error') {
|
104
|
+
return shouldNeverHappen('Unexpected error in client-session-sync-processor', mergeResult.cause)
|
105
|
+
}
|
106
|
+
|
83
107
|
span.addEvent('local-push', {
|
84
|
-
batchSize:
|
85
|
-
|
108
|
+
batchSize: encodedEventDefs.length,
|
109
|
+
mergeResult: TRACE_VERBOSE ? JSON.stringify(mergeResult) : undefined,
|
86
110
|
})
|
87
111
|
|
88
|
-
if (
|
89
|
-
return shouldNeverHappen(`Expected advance, got ${
|
112
|
+
if (mergeResult._tag !== 'advance') {
|
113
|
+
return shouldNeverHappen(`Expected advance, got ${mergeResult._tag}`)
|
90
114
|
}
|
91
115
|
|
92
|
-
syncStateRef.current =
|
116
|
+
syncStateRef.current = mergeResult.newSyncState
|
117
|
+
syncStateUpdateQueue.offer(mergeResult.newSyncState).pipe(Effect.runSync)
|
93
118
|
|
94
119
|
const writeTables = new Set<string>()
|
95
|
-
for (const
|
120
|
+
for (const event of mergeResult.newEvents) {
|
96
121
|
// TODO avoid encoding and decoding here again
|
97
|
-
const
|
98
|
-
const res =
|
122
|
+
const decodedEventDef = Schema.decodeSync(eventSchema)(event)
|
123
|
+
const res = materializeEvent(decodedEventDef, { otelContext, withChangeset: true })
|
99
124
|
for (const table of res.writeTables) {
|
100
125
|
writeTables.add(table)
|
101
126
|
}
|
102
|
-
|
127
|
+
event.meta.sessionChangeset = res.sessionChangeset
|
103
128
|
}
|
104
129
|
|
105
|
-
// console.debug('pushToLeader',
|
106
|
-
|
130
|
+
// console.debug('pushToLeader', encodedEventDefs.length, ...encodedEventDefs.map((_) => _.toJSON()))
|
131
|
+
BucketQueue.offerAll(leaderPushQueue, encodedEventDefs).pipe(Effect.runSync)
|
107
132
|
|
108
133
|
return { writeTables }
|
109
134
|
}
|
110
135
|
|
136
|
+
const debugInfo = {
|
137
|
+
rebaseCount: 0,
|
138
|
+
advanceCount: 0,
|
139
|
+
rejectCount: 0,
|
140
|
+
}
|
141
|
+
|
111
142
|
const otelContext = otel.trace.setSpan(otel.context.active(), span)
|
112
143
|
|
113
144
|
const boot: ClientSessionSyncProcessor['boot'] = Effect.gen(function* () {
|
114
|
-
|
115
|
-
|
145
|
+
// eslint-disable-next-line unicorn/prefer-global-this
|
146
|
+
if (confirmUnsavedChanges && typeof window !== 'undefined' && typeof window.addEventListener === 'function') {
|
147
|
+
const onBeforeUnload = (event: BeforeUnloadEvent) => {
|
148
|
+
if (syncStateRef.current.pending.length > 0) {
|
149
|
+
// Trigger the default browser dialog
|
150
|
+
event.preventDefault()
|
151
|
+
}
|
152
|
+
}
|
153
|
+
|
154
|
+
yield* Effect.acquireRelease(
|
155
|
+
Effect.sync(() => window.addEventListener('beforeunload', onBeforeUnload)),
|
156
|
+
() => Effect.sync(() => window.removeEventListener('beforeunload', onBeforeUnload)),
|
157
|
+
)
|
158
|
+
}
|
159
|
+
|
160
|
+
const leaderPushingFiberHandle = yield* FiberHandle.make()
|
161
|
+
|
162
|
+
const backgroundLeaderPushing = Effect.gen(function* () {
|
163
|
+
const batch = yield* BucketQueue.takeBetween(leaderPushQueue, 1, params.leaderPushBatchSize)
|
164
|
+
yield* clientSession.leaderThread.events.push(batch).pipe(
|
165
|
+
Effect.catchTag('LeaderAheadError', () => {
|
166
|
+
debugInfo.rejectCount++
|
167
|
+
return BucketQueue.clear(leaderPushQueue)
|
168
|
+
}),
|
169
|
+
)
|
170
|
+
}).pipe(Effect.forever, Effect.interruptible, Effect.tapCauseLogPretty)
|
171
|
+
|
172
|
+
yield* FiberHandle.run(leaderPushingFiberHandle, backgroundLeaderPushing)
|
173
|
+
|
174
|
+
const getMergeCounter = () =>
|
175
|
+
clientSession.sqliteDb.select<{ mergeCounter: number }>(
|
176
|
+
sql`SELECT mergeCounter FROM ${SystemTables.LEADER_MERGE_COUNTER_TABLE} WHERE id = 0`,
|
177
|
+
)[0]?.mergeCounter ?? 0
|
178
|
+
|
179
|
+
// NOTE We need to lazily call `.pull` as we want the cursor to be updated
|
180
|
+
yield* Stream.suspend(() =>
|
181
|
+
clientSession.leaderThread.events.pull({
|
182
|
+
cursor: { mergeCounter: getMergeCounter(), eventNum: syncStateRef.current.localHead },
|
183
|
+
}),
|
184
|
+
).pipe(
|
185
|
+
Stream.tap(({ payload, mergeCounter: leaderMergeCounter }) =>
|
116
186
|
Effect.gen(function* () {
|
117
|
-
//
|
187
|
+
// yield* Effect.logDebug('ClientSessionSyncProcessor:pull', payload)
|
188
|
+
|
189
|
+
if (clientSession.devtools.enabled) {
|
190
|
+
yield* clientSession.devtools.pullLatch.await
|
191
|
+
}
|
118
192
|
|
119
|
-
const
|
193
|
+
const mergeResult = SyncState.merge({
|
120
194
|
syncState: syncStateRef.current,
|
121
195
|
payload,
|
122
|
-
|
123
|
-
isEqualEvent:
|
196
|
+
isClientEvent,
|
197
|
+
isEqualEvent: LiveStoreEvent.isEqualEncoded,
|
124
198
|
})
|
125
199
|
|
126
|
-
if (
|
127
|
-
|
128
|
-
|
200
|
+
if (mergeResult._tag === 'unexpected-error') {
|
201
|
+
return yield* Effect.fail(mergeResult.cause)
|
202
|
+
} else if (mergeResult._tag === 'reject') {
|
203
|
+
return shouldNeverHappen('Unexpected reject in client-session-sync-processor', mergeResult)
|
129
204
|
}
|
130
205
|
|
131
|
-
syncStateRef.current =
|
206
|
+
syncStateRef.current = mergeResult.newSyncState
|
207
|
+
syncStateUpdateQueue.offer(mergeResult.newSyncState).pipe(Effect.runSync)
|
132
208
|
|
133
|
-
if (
|
134
|
-
span.addEvent('pull:rebase', {
|
209
|
+
if (mergeResult._tag === 'rebase') {
|
210
|
+
span.addEvent('merge:pull:rebase', {
|
135
211
|
payloadTag: payload._tag,
|
136
212
|
payload: TRACE_VERBOSE ? JSON.stringify(payload) : undefined,
|
137
|
-
newEventsCount:
|
138
|
-
rollbackCount:
|
139
|
-
res: TRACE_VERBOSE ? JSON.stringify(
|
140
|
-
|
213
|
+
newEventsCount: mergeResult.newEvents.length,
|
214
|
+
rollbackCount: mergeResult.rollbackEvents.length,
|
215
|
+
res: TRACE_VERBOSE ? JSON.stringify(mergeResult) : undefined,
|
216
|
+
leaderMergeCounter,
|
141
217
|
})
|
218
|
+
|
219
|
+
debugInfo.rebaseCount++
|
220
|
+
|
221
|
+
yield* FiberHandle.clear(leaderPushingFiberHandle)
|
222
|
+
|
223
|
+
// Reset the leader push queue since we're rebasing and will push again
|
224
|
+
yield* BucketQueue.clear(leaderPushQueue)
|
225
|
+
|
226
|
+
yield* FiberHandle.run(leaderPushingFiberHandle, backgroundLeaderPushing)
|
227
|
+
|
142
228
|
if (LS_DEV) {
|
143
|
-
|
144
|
-
'pull:rebase: rollback',
|
145
|
-
|
146
|
-
...
|
147
|
-
|
229
|
+
Effect.logDebug(
|
230
|
+
'merge:pull:rebase: rollback',
|
231
|
+
mergeResult.rollbackEvents.length,
|
232
|
+
...mergeResult.rollbackEvents.slice(0, 10).map((_) => _.toJSON()),
|
233
|
+
{ leaderMergeCounter },
|
234
|
+
).pipe(Effect.provide(runtime), Effect.runSync)
|
148
235
|
}
|
149
236
|
|
150
|
-
for (let i =
|
151
|
-
const event =
|
152
|
-
if (event.meta.sessionChangeset) {
|
153
|
-
rollback(event.meta.sessionChangeset)
|
154
|
-
event.meta.sessionChangeset =
|
237
|
+
for (let i = mergeResult.rollbackEvents.length - 1; i >= 0; i--) {
|
238
|
+
const event = mergeResult.rollbackEvents[i]!
|
239
|
+
if (event.meta.sessionChangeset._tag !== 'no-op' && event.meta.sessionChangeset._tag !== 'unset') {
|
240
|
+
rollback(event.meta.sessionChangeset.data)
|
241
|
+
event.meta.sessionChangeset = { _tag: 'unset' }
|
155
242
|
}
|
156
243
|
}
|
157
244
|
|
158
|
-
|
245
|
+
yield* BucketQueue.offerAll(leaderPushQueue, mergeResult.newSyncState.pending)
|
159
246
|
} else {
|
160
|
-
span.addEvent('pull:advance', {
|
247
|
+
span.addEvent('merge:pull:advance', {
|
161
248
|
payloadTag: payload._tag,
|
162
249
|
payload: TRACE_VERBOSE ? JSON.stringify(payload) : undefined,
|
163
|
-
newEventsCount:
|
164
|
-
res: TRACE_VERBOSE ? JSON.stringify(
|
165
|
-
|
250
|
+
newEventsCount: mergeResult.newEvents.length,
|
251
|
+
res: TRACE_VERBOSE ? JSON.stringify(mergeResult) : undefined,
|
252
|
+
leaderMergeCounter,
|
166
253
|
})
|
254
|
+
|
255
|
+
debugInfo.advanceCount++
|
167
256
|
}
|
168
257
|
|
169
|
-
if (
|
258
|
+
if (mergeResult.newEvents.length === 0) return
|
170
259
|
|
171
260
|
const writeTables = new Set<string>()
|
172
|
-
for (const
|
173
|
-
|
174
|
-
const
|
261
|
+
for (const event of mergeResult.newEvents) {
|
262
|
+
// TODO apply changeset if available (will require tracking of write tables as well)
|
263
|
+
const decodedEventDef = Schema.decodeSync(eventSchema)(event)
|
264
|
+
const res = materializeEvent(decodedEventDef, { otelContext, withChangeset: true })
|
175
265
|
for (const table of res.writeTables) {
|
176
266
|
writeTables.add(table)
|
177
267
|
}
|
178
268
|
|
179
|
-
|
269
|
+
event.meta.sessionChangeset = res.sessionChangeset
|
180
270
|
}
|
181
271
|
|
182
272
|
refreshTables(writeTables)
|
183
|
-
})
|
273
|
+
}).pipe(
|
274
|
+
Effect.tapCauseLogPretty,
|
275
|
+
Effect.catchAllCause((cause) => clientSession.shutdown(cause)),
|
276
|
+
),
|
184
277
|
),
|
185
278
|
Stream.runDrain,
|
279
|
+
Effect.forever, // NOTE Whenever the leader changes, we need to re-start the stream
|
280
|
+
Effect.interruptible,
|
281
|
+
Effect.withSpan('client-session-sync-processor:pull'),
|
186
282
|
Effect.tapCauseLogPretty,
|
187
283
|
Effect.forkScoped,
|
188
284
|
)
|
@@ -191,18 +287,46 @@ export const makeClientSessionSyncProcessor = ({
|
|
191
287
|
return {
|
192
288
|
push,
|
193
289
|
boot,
|
194
|
-
|
290
|
+
syncState: Subscribable.make({
|
291
|
+
get: Effect.gen(function* () {
|
292
|
+
const syncState = syncStateRef.current
|
293
|
+
if (syncStateRef === undefined) return shouldNeverHappen('Not initialized')
|
294
|
+
return syncState
|
295
|
+
}),
|
296
|
+
changes: Stream.fromQueue(syncStateUpdateQueue),
|
297
|
+
}),
|
298
|
+
debug: {
|
299
|
+
print: () =>
|
300
|
+
Effect.gen(function* () {
|
301
|
+
console.log('debugInfo', debugInfo)
|
302
|
+
console.log('syncState', syncStateRef.current)
|
303
|
+
const pushQueueSize = yield* BucketQueue.size(leaderPushQueue)
|
304
|
+
console.log('pushQueueSize', pushQueueSize)
|
305
|
+
const pushQueueItems = yield* BucketQueue.peekAll(leaderPushQueue)
|
306
|
+
console.log(
|
307
|
+
'pushQueueItems',
|
308
|
+
pushQueueItems.map((_) => _.toJSON()),
|
309
|
+
)
|
310
|
+
}).pipe(Effect.provide(runtime), Effect.runSync),
|
311
|
+
debugInfo: () => debugInfo,
|
312
|
+
},
|
195
313
|
} satisfies ClientSessionSyncProcessor
|
196
314
|
}
|
197
315
|
|
198
316
|
export interface ClientSessionSyncProcessor {
|
199
317
|
push: (
|
200
|
-
batch: ReadonlyArray<
|
318
|
+
batch: ReadonlyArray<LiveStoreEvent.PartialAnyDecoded>,
|
201
319
|
options: { otelContext: otel.Context },
|
202
320
|
) => {
|
203
321
|
writeTables: Set<string>
|
204
322
|
}
|
205
323
|
boot: Effect.Effect<void, UnexpectedError, Scope.Scope>
|
206
|
-
|
207
|
-
|
324
|
+
syncState: Subscribable.Subscribable<SyncState.SyncState>
|
325
|
+
debug: {
|
326
|
+
print: () => void
|
327
|
+
debugInfo: () => {
|
328
|
+
rebaseCount: number
|
329
|
+
advanceCount: number
|
330
|
+
}
|
331
|
+
}
|
208
332
|
}
|
@@ -1,6 +1,6 @@
|
|
1
|
+
import { EventSequenceNumber } from '../../schema/mod.js'
|
1
2
|
import { replacesFacts } from './facts.js'
|
2
3
|
import { graphologyDag } from './graphology_.js'
|
3
|
-
import { eventIdToString } from './history-dag.js'
|
4
4
|
import type { HistoryDag } from './history-dag-common.js'
|
5
5
|
import { emptyHistoryDag } from './history-dag-common.js'
|
6
6
|
|
@@ -17,25 +17,25 @@ export const compactEvents = (inputDag: HistoryDag): { dag: HistoryDag; compacte
|
|
17
17
|
const dag = inputDag.copy()
|
18
18
|
const compactedEventCount = 0
|
19
19
|
|
20
|
-
const
|
20
|
+
const orderedEventSequenceNumberStrs = graphologyDag.topologicalSort(dag).reverse()
|
21
21
|
|
22
22
|
// drop root
|
23
|
-
|
23
|
+
orderedEventSequenceNumberStrs.pop()
|
24
24
|
|
25
|
-
for (const
|
26
|
-
if (dag.hasNode(
|
25
|
+
for (const eventNumStr of orderedEventSequenceNumberStrs) {
|
26
|
+
if (dag.hasNode(eventNumStr) === false) {
|
27
27
|
continue
|
28
28
|
}
|
29
29
|
|
30
|
-
const subDagsForEvent = Array.from(makeSubDagsForEvent(dag,
|
30
|
+
const subDagsForEvent = Array.from(makeSubDagsForEvent(dag, eventNumStr))
|
31
31
|
for (const subDag of subDagsForEvent) {
|
32
32
|
let shouldRetry = true
|
33
33
|
while (shouldRetry) {
|
34
|
-
const subDagsInHistory = findSubDagsInHistory(dag, subDag,
|
34
|
+
const subDagsInHistory = findSubDagsInHistory(dag, subDag, eventNumStr)
|
35
35
|
|
36
36
|
// console.debug(
|
37
37
|
// 'subDagsInHistory',
|
38
|
-
//
|
38
|
+
// eventNumStr,
|
39
39
|
// 'target',
|
40
40
|
// subDag.nodes(),
|
41
41
|
// 'found',
|
@@ -65,9 +65,9 @@ export const compactEvents = (inputDag: HistoryDag): { dag: HistoryDag; compacte
|
|
65
65
|
return { dag, compactedEventCount }
|
66
66
|
}
|
67
67
|
|
68
|
-
function* makeSubDagsForEvent(inputDag: HistoryDag,
|
69
|
-
/** Map from
|
70
|
-
let nextIterationEls: Map<string, string[]> = new Map([[
|
68
|
+
function* makeSubDagsForEvent(inputDag: HistoryDag, eventNumStr: string): Generator<HistoryDag> {
|
69
|
+
/** Map from eventNumStr to array of eventNumStrs that are dependencies */
|
70
|
+
let nextIterationEls: Map<string, string[]> = new Map([[eventNumStr, []]])
|
71
71
|
let previousDag: HistoryDag | undefined
|
72
72
|
|
73
73
|
while (nextIterationEls.size > 0) {
|
@@ -77,19 +77,22 @@ function* makeSubDagsForEvent(inputDag: HistoryDag, eventIdStr: string): Generat
|
|
77
77
|
const currentIterationEls = new Map(nextIterationEls)
|
78
78
|
nextIterationEls = new Map()
|
79
79
|
|
80
|
-
for (const [
|
81
|
-
const node = inputDag.getNodeAttributes(
|
82
|
-
if (subDag.hasNode(
|
83
|
-
subDag.addNode(
|
80
|
+
for (const [currentEventSequenceNumberStr, edgeTargetIdStrs] of currentIterationEls) {
|
81
|
+
const node = inputDag.getNodeAttributes(currentEventSequenceNumberStr)
|
82
|
+
if (subDag.hasNode(currentEventSequenceNumberStr) === false) {
|
83
|
+
subDag.addNode(currentEventSequenceNumberStr, { ...node })
|
84
84
|
}
|
85
85
|
for (const edgeTargetIdStr of edgeTargetIdStrs) {
|
86
|
-
subDag.addEdge(
|
86
|
+
subDag.addEdge(currentEventSequenceNumberStr, edgeTargetIdStr, { type: 'facts' })
|
87
87
|
}
|
88
88
|
|
89
|
-
for (const depEdge of inputDag.outboundEdgeEntries(
|
89
|
+
for (const depEdge of inputDag.outboundEdgeEntries(currentEventSequenceNumberStr)) {
|
90
90
|
if (depEdge.attributes.type === 'facts') {
|
91
|
-
const
|
92
|
-
nextIterationEls.set(
|
91
|
+
const depEventSequenceNumberStr = depEdge.target
|
92
|
+
nextIterationEls.set(depEventSequenceNumberStr, [
|
93
|
+
...(nextIterationEls.get(depEventSequenceNumberStr) ?? []),
|
94
|
+
currentEventSequenceNumberStr,
|
95
|
+
])
|
93
96
|
}
|
94
97
|
}
|
95
98
|
}
|
@@ -102,23 +105,23 @@ function* makeSubDagsForEvent(inputDag: HistoryDag, eventIdStr: string): Generat
|
|
102
105
|
}
|
103
106
|
|
104
107
|
/**
|
105
|
-
* Iterates over all events from root to `
|
108
|
+
* Iterates over all events from root to `upToExclEventSequenceNumberStr`
|
106
109
|
* and collects all valid sub dags that are replaced by `targetSubDag`.
|
107
110
|
*/
|
108
111
|
const findSubDagsInHistory = (
|
109
112
|
inputDag: HistoryDag,
|
110
113
|
targetSubDag: HistoryDag,
|
111
|
-
|
114
|
+
upToExclEventSequenceNumberStr: string,
|
112
115
|
): { subDags: HistoryDag[]; allOutsideDependencies: string[][] } => {
|
113
116
|
const subDags: HistoryDag[] = []
|
114
117
|
const allOutsideDependencies: string[][] = []
|
115
118
|
|
116
|
-
for (const
|
117
|
-
if (
|
119
|
+
for (const eventNumStr of graphologyDag.topologicalSort(inputDag)) {
|
120
|
+
if (eventNumStr === upToExclEventSequenceNumberStr) {
|
118
121
|
break
|
119
122
|
}
|
120
123
|
|
121
|
-
for (const subDag of makeSubDagsForEvent(inputDag,
|
124
|
+
for (const subDag of makeSubDagsForEvent(inputDag, eventNumStr)) {
|
122
125
|
// console.debug('findSubDagsInHistory', 'target', targetSubDag.nodes(), 'subDag', subDag.nodes())
|
123
126
|
if (subDag.size < targetSubDag.size) {
|
124
127
|
continue
|
@@ -152,9 +155,9 @@ const outsideDependenciesForDag = (subDag: HistoryDag, inputDag: HistoryDag) =>
|
|
152
155
|
for (const nodeIdStr of subDag.nodes()) {
|
153
156
|
for (const edgeEntry of inputDag.outboundEdgeEntries(nodeIdStr)) {
|
154
157
|
if (edgeEntry.attributes.type === 'facts') {
|
155
|
-
const
|
156
|
-
if (subDag.hasNode(
|
157
|
-
outsideDependencies.push(
|
158
|
+
const depEventSequenceNumberStr = edgeEntry.target
|
159
|
+
if (subDag.hasNode(depEventSequenceNumberStr) === false) {
|
160
|
+
outsideDependencies.push(depEventSequenceNumberStr)
|
158
161
|
}
|
159
162
|
}
|
160
163
|
}
|
@@ -201,19 +204,19 @@ const dagReplacesDag = (dagA: HistoryDag, dagB: HistoryDag): boolean => {
|
|
201
204
|
return true
|
202
205
|
}
|
203
206
|
|
204
|
-
const removeEvent = (dag: HistoryDag,
|
205
|
-
// console.debug('removing event',
|
206
|
-
const event = dag.getNodeAttributes(
|
207
|
-
const
|
208
|
-
const childEdges = dag.outboundEdgeEntries(
|
207
|
+
const removeEvent = (dag: HistoryDag, eventNumStr: string) => {
|
208
|
+
// console.debug('removing event', eventNumStr)
|
209
|
+
const event = dag.getNodeAttributes(eventNumStr)
|
210
|
+
const parentSeqNumStr = EventSequenceNumber.toString(event.parentSeqNum)
|
211
|
+
const childEdges = dag.outboundEdgeEntries(eventNumStr)
|
209
212
|
|
210
213
|
for (const childEdge of childEdges) {
|
211
214
|
if (childEdge.attributes.type === 'parent') {
|
212
215
|
const childEvent = dag.getNodeAttributes(childEdge.target)
|
213
|
-
childEvent.
|
214
|
-
dag.addEdge(
|
216
|
+
childEvent.parentSeqNum = { ...event.parentSeqNum }
|
217
|
+
dag.addEdge(parentSeqNumStr, EventSequenceNumber.toString(childEvent.seqNum), { type: 'parent' })
|
215
218
|
}
|
216
219
|
}
|
217
220
|
|
218
|
-
dag.dropNode(
|
221
|
+
dag.dropNode(eventNumStr)
|
219
222
|
}
|