@rocicorp/zero 1.12.0-canary.8 → 1.12.0-canary.9
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/out/replicache/src/btree/node.d.ts +0 -2
- package/out/replicache/src/btree/node.d.ts.map +1 -1
- package/out/replicache/src/btree/node.js.map +1 -1
- package/out/replicache/src/connection-loop.d.ts.map +1 -1
- package/out/replicache/src/connection-loop.js +1 -1
- package/out/replicache/src/connection-loop.js.map +1 -1
- package/out/replicache/src/db/commit.d.ts +0 -1
- package/out/replicache/src/db/commit.d.ts.map +1 -1
- package/out/replicache/src/db/commit.js +1 -1
- package/out/replicache/src/db/commit.js.map +1 -1
- package/out/replicache/src/db/write.d.ts +0 -2
- package/out/replicache/src/db/write.d.ts.map +1 -1
- package/out/replicache/src/db/write.js +1 -1
- package/out/replicache/src/db/write.js.map +1 -1
- package/out/replicache/src/deleted-clients.d.ts +0 -2
- package/out/replicache/src/deleted-clients.d.ts.map +1 -1
- package/out/replicache/src/deleted-clients.js +1 -1
- package/out/replicache/src/deleted-clients.js.map +1 -1
- package/out/replicache/src/frozen-json.d.ts +0 -1
- package/out/replicache/src/frozen-json.d.ts.map +1 -1
- package/out/replicache/src/frozen-json.js.map +1 -1
- package/out/replicache/src/index-defs.d.ts +0 -2
- package/out/replicache/src/index-defs.d.ts.map +1 -1
- package/out/replicache/src/index-defs.js +1 -1
- package/out/replicache/src/index-defs.js.map +1 -1
- package/out/replicache/src/kv/expo-sqlite/store.d.ts +0 -1
- package/out/replicache/src/kv/expo-sqlite/store.d.ts.map +1 -1
- package/out/replicache/src/kv/expo-sqlite/store.js +1 -1
- package/out/replicache/src/kv/expo-sqlite/store.js.map +1 -1
- package/out/replicache/src/kv/idb-store.js +1 -1
- package/out/replicache/src/kv/idb-store.js.map +1 -1
- package/out/replicache/src/kv/throw-if-closed.d.ts +0 -3
- package/out/replicache/src/kv/throw-if-closed.d.ts.map +1 -1
- package/out/replicache/src/kv/throw-if-closed.js.map +1 -1
- package/out/replicache/src/persist/client-group-gc.d.ts +0 -7
- package/out/replicache/src/persist/client-group-gc.d.ts.map +1 -1
- package/out/replicache/src/persist/client-group-gc.js +1 -1
- package/out/replicache/src/persist/client-group-gc.js.map +1 -1
- package/out/replicache/src/process-scheduler.js +1 -1
- package/out/replicache/src/process-scheduler.js.map +1 -1
- package/out/replicache/src/replicache-impl.d.ts +2 -7
- package/out/replicache/src/replicache-impl.d.ts.map +1 -1
- package/out/replicache/src/replicache-impl.js +1 -1
- package/out/replicache/src/replicache-impl.js.map +1 -1
- package/out/replicache/src/sync/patch.d.ts +0 -5
- package/out/replicache/src/sync/patch.d.ts.map +1 -1
- package/out/replicache/src/sync/patch.js +1 -1
- package/out/replicache/src/sync/patch.js.map +1 -1
- package/out/replicache/src/sync/pull.d.ts +0 -1
- package/out/replicache/src/sync/pull.d.ts.map +1 -1
- package/out/replicache/src/sync/pull.js.map +1 -1
- package/out/replicache/src/sync/push.d.ts +2 -1
- package/out/replicache/src/sync/push.d.ts.map +1 -1
- package/out/replicache/src/sync/push.js.map +1 -1
- package/out/replicache/src/types.d.ts +2 -1
- package/out/replicache/src/types.d.ts.map +1 -1
- package/out/shared/src/asserts.d.ts +0 -5
- package/out/shared/src/asserts.d.ts.map +1 -1
- package/out/shared/src/asserts.js +1 -1
- package/out/shared/src/asserts.js.map +1 -1
- package/out/shared/src/browser-env.d.ts +0 -17
- package/out/shared/src/browser-env.d.ts.map +1 -1
- package/out/shared/src/browser-env.js.map +1 -1
- package/out/shared/src/deep-clone.d.ts +0 -1
- package/out/shared/src/deep-clone.d.ts.map +1 -1
- package/out/shared/src/deep-clone.js +1 -1
- package/out/shared/src/deep-clone.js.map +1 -1
- package/out/shared/src/document-visible.js +1 -1
- package/out/shared/src/document-visible.js.map +1 -1
- package/out/shared/src/expand.d.ts +0 -3
- package/out/shared/src/expand.d.ts.map +1 -1
- package/out/shared/src/immutable.d.ts +1 -1
- package/out/shared/src/immutable.d.ts.map +1 -1
- package/out/shared/src/iterables.d.ts +0 -1
- package/out/shared/src/iterables.d.ts.map +1 -1
- package/out/shared/src/iterables.js.map +1 -1
- package/out/shared/src/logging-test-utils.js +1 -1
- package/out/shared/src/logging-test-utils.js.map +1 -1
- package/out/shared/src/options-types.d.ts +1 -1
- package/out/shared/src/options-types.d.ts.map +1 -1
- package/out/shared/src/options.d.ts +2 -3
- package/out/shared/src/options.d.ts.map +1 -1
- package/out/shared/src/options.js +1 -1
- package/out/shared/src/options.js.map +1 -1
- package/out/shared/src/promise-race.js +1 -1
- package/out/shared/src/promise-race.js.map +1 -1
- package/out/shared/src/queue.js +1 -1
- package/out/shared/src/queue.js.map +1 -1
- package/out/shared/src/resolved-promises.d.ts +0 -4
- package/out/shared/src/resolved-promises.d.ts.map +1 -1
- package/out/shared/src/resolved-promises.js +0 -1
- package/out/shared/src/resolved-promises.js.map +1 -1
- package/out/shared/src/resolver.d.ts +9 -0
- package/out/shared/src/resolver.d.ts.map +1 -0
- package/out/shared/src/resolver.js +6 -0
- package/out/shared/src/resolver.js.map +1 -0
- package/out/shared/src/sleep.js +1 -1
- package/out/shared/src/sleep.js.map +1 -1
- package/out/shared/src/tdigest.d.ts +0 -1
- package/out/shared/src/tdigest.d.ts.map +1 -1
- package/out/shared/src/tdigest.js.map +1 -1
- package/out/z2s/src/sql.d.ts +1 -5
- package/out/z2s/src/sql.d.ts.map +1 -1
- package/out/z2s/src/sql.js.map +1 -1
- package/out/zero/package.js +2 -3
- package/out/zero/package.js.map +1 -1
- package/out/zero/src/zero-cache-dev.js +1 -1
- package/out/zero/src/zero-cache-dev.js.map +1 -1
- package/out/zero-cache/src/config/zero-config.d.ts +14 -11
- package/out/zero-cache/src/config/zero-config.d.ts.map +1 -1
- package/out/zero-cache/src/config/zero-config.js +23 -0
- package/out/zero-cache/src/config/zero-config.js.map +1 -1
- package/out/zero-cache/src/db/migration-lite.js.map +1 -1
- package/out/zero-cache/src/db/migration.js +1 -1
- package/out/zero-cache/src/db/migration.js.map +1 -1
- package/out/zero-cache/src/db/pg-copy-binary.js +1 -1
- package/out/zero-cache/src/db/pg-copy-binary.js.map +1 -1
- package/out/zero-cache/src/db/pg-type-parser.js.map +1 -1
- package/out/zero-cache/src/db/specs.d.ts +3 -4
- package/out/zero-cache/src/db/specs.d.ts.map +1 -1
- package/out/zero-cache/src/db/specs.js +5 -7
- package/out/zero-cache/src/db/specs.js.map +1 -1
- package/out/zero-cache/src/db/transaction-pool.js +2 -2
- package/out/zero-cache/src/db/transaction-pool.js.map +1 -1
- package/out/zero-cache/src/observability/events.js +1 -1
- package/out/zero-cache/src/observability/events.js.map +1 -1
- package/out/zero-cache/src/server/change-streamer.js +1 -1
- package/out/zero-cache/src/server/change-streamer.js.map +1 -1
- package/out/zero-cache/src/server/main.js +1 -1
- package/out/zero-cache/src/server/main.js.map +1 -1
- package/out/zero-cache/src/server/runner/run-worker.js +1 -1
- package/out/zero-cache/src/server/runner/run-worker.js.map +1 -1
- package/out/zero-cache/src/services/change-source/common/backfill-manager.js +1 -1
- package/out/zero-cache/src/services/change-source/common/backfill-manager.js.map +1 -1
- package/out/zero-cache/src/services/change-source/common/change-stream-multiplexer.js +1 -1
- package/out/zero-cache/src/services/change-source/common/change-stream-multiplexer.js.map +1 -1
- package/out/zero-cache/src/services/change-source/common/replica-restore.js.map +1 -1
- package/out/zero-cache/src/services/change-source/custom/change-source.js +1 -1
- package/out/zero-cache/src/services/change-source/custom/change-source.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/backfill-stream.js +1 -1
- package/out/zero-cache/src/services/change-source/pg/backfill-stream.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/change-source.js +1 -1
- package/out/zero-cache/src/services/change-source/pg/change-source.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/initial-sync.js +1 -1
- package/out/zero-cache/src/services/change-source/pg/initial-sync.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/lsn.d.ts +0 -2
- package/out/zero-cache/src/services/change-source/pg/lsn.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/lsn.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/replication-slots.js +1 -1
- package/out/zero-cache/src/services/change-source/pg/replication-slots.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/ddl.d.ts +0 -12
- package/out/zero-cache/src/services/change-source/pg/schema/ddl.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/ddl.js +5 -3
- package/out/zero-cache/src/services/change-source/pg/schema/ddl.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/index-predicate.d.ts +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/index-predicate.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/index-predicate.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/validation.d.ts +0 -1
- package/out/zero-cache/src/services/change-source/pg/schema/validation.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/validation.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/backup-monitor.js +1 -1
- package/out/zero-cache/src/services/change-streamer/backup-monitor.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/broadcast.js +1 -1
- package/out/zero-cache/src/services/change-streamer/broadcast.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/change-streamer-http.js +1 -1
- package/out/zero-cache/src/services/change-streamer/change-streamer-http.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/change-streamer-service.js +1 -1
- package/out/zero-cache/src/services/change-streamer/change-streamer-service.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/change-streamer.js +1 -1
- package/out/zero-cache/src/services/change-streamer/change-streamer.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/drain-tracker.js +1 -1
- package/out/zero-cache/src/services/change-streamer/drain-tracker.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/litestream3-prometheus-poller.js +2 -2
- package/out/zero-cache/src/services/change-streamer/litestream3-prometheus-poller.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/restore-admission.js +2 -2
- package/out/zero-cache/src/services/change-streamer/restore-admission.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/schema/tables.js +1 -1
- package/out/zero-cache/src/services/change-streamer/schema/tables.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/snapshot-message.js +2 -3
- package/out/zero-cache/src/services/change-streamer/snapshot-message.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-catchup.js +2 -2
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-catchup.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-read-router.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/storer.js +1 -1
- package/out/zero-cache/src/services/change-streamer/storer.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/subscribe.js +1 -1
- package/out/zero-cache/src/services/change-streamer/subscribe.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/subscriber.js +1 -1
- package/out/zero-cache/src/services/change-streamer/subscriber.js.map +1 -1
- package/out/zero-cache/src/services/life-cycle.js +1 -1
- package/out/zero-cache/src/services/life-cycle.js.map +1 -1
- package/out/zero-cache/src/services/litestream/commands.js +1 -1
- package/out/zero-cache/src/services/litestream/commands.js.map +1 -1
- package/out/zero-cache/src/services/litestream/metrics.js.map +1 -1
- package/out/zero-cache/src/services/mutagen/mutagen.js +2 -2
- package/out/zero-cache/src/services/mutagen/mutagen.js.map +1 -1
- package/out/zero-cache/src/services/plannerz.d.ts +4 -12
- package/out/zero-cache/src/services/plannerz.d.ts.map +1 -1
- package/out/zero-cache/src/services/plannerz.js +1 -3
- package/out/zero-cache/src/services/plannerz.js.map +1 -1
- package/out/zero-cache/src/services/replicator/change-log-db.js +1 -1
- package/out/zero-cache/src/services/replicator/change-log-db.js.map +1 -1
- package/out/zero-cache/src/services/replicator/change-log-stream-writer.js +1 -1
- package/out/zero-cache/src/services/replicator/change-log-stream-writer.js.map +1 -1
- package/out/zero-cache/src/services/replicator/drain-handler.js +1 -1
- package/out/zero-cache/src/services/replicator/drain-handler.js.map +1 -1
- package/out/zero-cache/src/services/replicator/reporter/recorder.js +1 -1
- package/out/zero-cache/src/services/replicator/reporter/recorder.js.map +1 -1
- package/out/zero-cache/src/services/replicator/reporter/report-schema.d.ts +2 -11
- package/out/zero-cache/src/services/replicator/reporter/report-schema.d.ts.map +1 -1
- package/out/zero-cache/src/services/replicator/reporter/report-schema.js +1 -1
- package/out/zero-cache/src/services/replicator/reporter/report-schema.js.map +1 -1
- package/out/zero-cache/src/services/replicator/schema/change-log.d.ts +0 -10
- package/out/zero-cache/src/services/replicator/schema/change-log.d.ts.map +1 -1
- package/out/zero-cache/src/services/replicator/schema/change-log.js.map +1 -1
- package/out/zero-cache/src/services/replicator/schema/column-metadata.d.ts +0 -7
- package/out/zero-cache/src/services/replicator/schema/column-metadata.d.ts.map +1 -1
- package/out/zero-cache/src/services/replicator/schema/column-metadata.js +1 -1
- package/out/zero-cache/src/services/replicator/schema/column-metadata.js.map +1 -1
- package/out/zero-cache/src/services/replicator/write-worker-client.js +1 -1
- package/out/zero-cache/src/services/replicator/write-worker-client.js.map +1 -1
- package/out/zero-cache/src/services/running-state.js +1 -1
- package/out/zero-cache/src/services/running-state.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/client-handler.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/connection-context-manager.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/cvr-store.js +1 -1
- package/out/zero-cache/src/services/view-syncer/cvr-store.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/cvr.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/drain-coordinator.js +1 -1
- package/out/zero-cache/src/services/view-syncer/drain-coordinator.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/pipeline-driver.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/query-stats.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/row-record-cache.js +1 -1
- package/out/zero-cache/src/services/view-syncer/row-record-cache.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/schema/cvr.js +1 -1
- package/out/zero-cache/src/services/view-syncer/schema/cvr.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/schema/types.js +3 -17
- package/out/zero-cache/src/services/view-syncer/schema/types.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/snapshotter.js +1 -1
- package/out/zero-cache/src/services/view-syncer/snapshotter.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/view-syncer.js +10 -10
- package/out/zero-cache/src/services/view-syncer/view-syncer.js.map +1 -1
- package/out/zero-cache/src/types/lite.d.ts +0 -1
- package/out/zero-cache/src/types/lite.d.ts.map +1 -1
- package/out/zero-cache/src/types/lite.js +2 -2
- package/out/zero-cache/src/types/lite.js.map +1 -1
- package/out/zero-cache/src/types/pg-types.d.ts +0 -40
- package/out/zero-cache/src/types/pg-types.d.ts.map +1 -1
- package/out/zero-cache/src/types/pg-types.js.map +1 -1
- package/out/zero-cache/src/types/poke-chunk.js +1 -1
- package/out/zero-cache/src/types/poke-chunk.js.map +1 -1
- package/out/zero-cache/src/types/row-key.d.ts +0 -5
- package/out/zero-cache/src/types/row-key.d.ts.map +1 -1
- package/out/zero-cache/src/types/row-key.js.map +1 -1
- package/out/zero-cache/src/types/streams.js +1 -1
- package/out/zero-cache/src/types/streams.js.map +1 -1
- package/out/zero-cache/src/types/subscription.js +1 -1
- package/out/zero-cache/src/types/subscription.js.map +1 -1
- package/out/zero-cache/src/types/websocket-handoff.d.ts +0 -6
- package/out/zero-cache/src/types/websocket-handoff.d.ts.map +1 -1
- package/out/zero-cache/src/types/websocket-handoff.js +8 -2
- package/out/zero-cache/src/types/websocket-handoff.js.map +1 -1
- package/out/zero-cache/src/types/ws.d.ts +2 -1
- package/out/zero-cache/src/types/ws.d.ts.map +1 -1
- package/out/zero-cache/src/types/ws.js +1 -1
- package/out/zero-cache/src/types/ws.js.map +1 -1
- package/out/zero-cache/src/workers/connection.js +4 -1
- package/out/zero-cache/src/workers/connection.js.map +1 -1
- package/out/zero-cache/src/workers/mutator.js +1 -1
- package/out/zero-cache/src/workers/mutator.js.map +1 -1
- package/out/zero-cache/src/workers/syncer.js +36 -2
- package/out/zero-cache/src/workers/syncer.js.map +1 -1
- package/out/zero-client/src/client/active-clients-manager.d.ts.map +1 -1
- package/out/zero-client/src/client/active-clients-manager.js +1 -1
- package/out/zero-client/src/client/active-clients-manager.js.map +1 -1
- package/out/zero-client/src/client/connection-manager.js +1 -1
- package/out/zero-client/src/client/connection-manager.js.map +1 -1
- package/out/zero-client/src/client/crud.d.ts +2 -8
- package/out/zero-client/src/client/crud.d.ts.map +1 -1
- package/out/zero-client/src/client/crud.js +1 -1
- package/out/zero-client/src/client/crud.js.map +1 -1
- package/out/zero-client/src/client/custom.d.ts +0 -2
- package/out/zero-client/src/client/custom.d.ts.map +1 -1
- package/out/zero-client/src/client/custom.js +1 -1
- package/out/zero-client/src/client/custom.js.map +1 -1
- package/out/zero-client/src/client/enable-analytics.d.ts +0 -1
- package/out/zero-client/src/client/enable-analytics.d.ts.map +1 -1
- package/out/zero-client/src/client/enable-analytics.js +2 -1
- package/out/zero-client/src/client/enable-analytics.js.map +1 -1
- package/out/zero-client/src/client/error.d.ts +4 -5
- package/out/zero-client/src/client/error.d.ts.map +1 -1
- package/out/zero-client/src/client/error.js.map +1 -1
- package/out/zero-client/src/client/keys.d.ts +0 -1
- package/out/zero-client/src/client/keys.d.ts.map +1 -1
- package/out/zero-client/src/client/keys.js +4 -2
- package/out/zero-client/src/client/keys.js.map +1 -1
- package/out/zero-client/src/client/mutation-tracker.d.ts.map +1 -1
- package/out/zero-client/src/client/mutation-tracker.js +1 -1
- package/out/zero-client/src/client/mutation-tracker.js.map +1 -1
- package/out/zero-client/src/client/options.d.ts +0 -4
- package/out/zero-client/src/client/options.d.ts.map +1 -1
- package/out/zero-client/src/client/options.js.map +1 -1
- package/out/zero-client/src/client/replicache-types.d.ts +3 -2
- package/out/zero-client/src/client/replicache-types.d.ts.map +1 -1
- package/out/zero-client/src/client/version.js +1 -1
- package/out/zero-client/src/client/zero-poke-handler.d.ts +1 -2
- package/out/zero-client/src/client/zero-poke-handler.d.ts.map +1 -1
- package/out/zero-client/src/client/zero-poke-handler.js +1 -1
- package/out/zero-client/src/client/zero-poke-handler.js.map +1 -1
- package/out/zero-client/src/client/zero.d.ts +1 -5
- package/out/zero-client/src/client/zero.d.ts.map +1 -1
- package/out/zero-client/src/client/zero.js +1 -1
- package/out/zero-client/src/client/zero.js.map +1 -1
- package/out/zero-client/src/types/client-state.d.ts +0 -6
- package/out/zero-client/src/types/client-state.d.ts.map +1 -1
- package/out/zero-permissions/src/permissions.d.ts +1 -12
- package/out/zero-permissions/src/permissions.d.ts.map +1 -1
- package/out/zero-permissions/src/permissions.js +1 -2
- package/out/zero-permissions/src/permissions.js.map +1 -1
- package/out/zero-protocol/src/ast.d.ts +0 -4
- package/out/zero-protocol/src/ast.d.ts.map +1 -1
- package/out/zero-protocol/src/ast.js +1 -2
- package/out/zero-protocol/src/ast.js.map +1 -1
- package/out/zero-protocol/src/change-desired-queries.d.ts +0 -20
- package/out/zero-protocol/src/change-desired-queries.d.ts.map +1 -1
- package/out/zero-protocol/src/change-desired-queries.js.map +1 -1
- package/out/zero-protocol/src/client-schema.d.ts +2 -5
- package/out/zero-protocol/src/client-schema.d.ts.map +1 -1
- package/out/zero-protocol/src/client-schema.js +1 -1
- package/out/zero-protocol/src/client-schema.js.map +1 -1
- package/out/zero-protocol/src/close-connection.d.ts +0 -8
- package/out/zero-protocol/src/close-connection.d.ts.map +1 -1
- package/out/zero-protocol/src/close-connection.js +1 -1
- package/out/zero-protocol/src/close-connection.js.map +1 -1
- package/out/zero-protocol/src/connect.d.ts +0 -12
- package/out/zero-protocol/src/connect.d.ts.map +1 -1
- package/out/zero-protocol/src/connect.js +1 -1
- package/out/zero-protocol/src/connect.js.map +1 -1
- package/out/zero-protocol/src/custom-queries.d.ts +3 -17
- package/out/zero-protocol/src/custom-queries.d.ts.map +1 -1
- package/out/zero-protocol/src/custom-queries.js +1 -1
- package/out/zero-protocol/src/custom-queries.js.map +1 -1
- package/out/zero-protocol/src/data.d.ts +0 -1
- package/out/zero-protocol/src/data.d.ts.map +1 -1
- package/out/zero-protocol/src/data.js +1 -1
- package/out/zero-protocol/src/data.js.map +1 -1
- package/out/zero-protocol/src/down.d.ts +27 -27
- package/out/zero-protocol/src/inspect-down.d.ts +82 -84
- package/out/zero-protocol/src/inspect-down.d.ts.map +1 -1
- package/out/zero-protocol/src/inspect-down.js +1 -1
- package/out/zero-protocol/src/inspect-down.js.map +1 -1
- package/out/zero-protocol/src/inspect-up.d.ts +0 -28
- package/out/zero-protocol/src/inspect-up.d.ts.map +1 -1
- package/out/zero-protocol/src/inspect-up.js +1 -1
- package/out/zero-protocol/src/inspect-up.js.map +1 -1
- package/out/zero-protocol/src/mutate-server.d.ts +0 -21
- package/out/zero-protocol/src/mutate-server.d.ts.map +1 -1
- package/out/zero-protocol/src/mutate-server.js +1 -1
- package/out/zero-protocol/src/mutate-server.js.map +1 -1
- package/out/zero-protocol/src/mutation-type-enum.d.ts +0 -1
- package/out/zero-protocol/src/mutation-type-enum.d.ts.map +1 -1
- package/out/zero-protocol/src/mutation-type-enum.js.map +1 -1
- package/out/zero-protocol/src/mutation.d.ts +2 -4
- package/out/zero-protocol/src/mutation.d.ts.map +1 -1
- package/out/zero-protocol/src/mutation.js +1 -1
- package/out/zero-protocol/src/mutation.js.map +1 -1
- package/out/zero-protocol/src/mutations-patch.d.ts +0 -33
- package/out/zero-protocol/src/mutations-patch.d.ts.map +1 -1
- package/out/zero-protocol/src/mutations-patch.js +1 -1
- package/out/zero-protocol/src/mutations-patch.js.map +1 -1
- package/out/zero-protocol/src/ping.d.ts +0 -2
- package/out/zero-protocol/src/ping.d.ts.map +1 -1
- package/out/zero-protocol/src/ping.js +1 -1
- package/out/zero-protocol/src/ping.js.map +1 -1
- package/out/zero-protocol/src/poke.d.ts +3 -2
- package/out/zero-protocol/src/poke.d.ts.map +1 -1
- package/out/zero-protocol/src/poke.js +1 -1
- package/out/zero-protocol/src/poke.js.map +1 -1
- package/out/zero-protocol/src/pong.d.ts +0 -2
- package/out/zero-protocol/src/pong.d.ts.map +1 -1
- package/out/zero-protocol/src/pong.js +1 -1
- package/out/zero-protocol/src/pong.js.map +1 -1
- package/out/zero-protocol/src/pull.d.ts +2 -7
- package/out/zero-protocol/src/pull.d.ts.map +1 -1
- package/out/zero-protocol/src/pull.js +1 -1
- package/out/zero-protocol/src/pull.js.map +1 -1
- package/out/zero-protocol/src/push.d.ts +1 -3
- package/out/zero-protocol/src/push.d.ts.map +1 -1
- package/out/zero-protocol/src/push.js +1 -1
- package/out/zero-protocol/src/push.js.map +1 -1
- package/out/zero-protocol/src/queries-patch.d.ts +0 -16
- package/out/zero-protocol/src/queries-patch.d.ts.map +1 -1
- package/out/zero-protocol/src/queries-patch.js +1 -1
- package/out/zero-protocol/src/queries-patch.js.map +1 -1
- package/out/zero-protocol/src/query-server.d.ts +2 -41
- package/out/zero-protocol/src/query-server.d.ts.map +1 -1
- package/out/zero-protocol/src/query-server.js +1 -1
- package/out/zero-protocol/src/query-server.js.map +1 -1
- package/out/zero-protocol/src/up.d.ts +42 -42
- package/out/zero-protocol/src/version.d.ts +0 -1
- package/out/zero-protocol/src/version.d.ts.map +1 -1
- package/out/zero-protocol/src/version.js.map +1 -1
- package/out/zero-react/src/use-query.js +1 -1
- package/out/zero-react/src/use-query.js.map +1 -1
- package/out/zero-schema/src/builder/relationship-builder.d.ts +0 -2
- package/out/zero-schema/src/builder/relationship-builder.d.ts.map +1 -1
- package/out/zero-schema/src/builder/relationship-builder.js.map +1 -1
- package/out/zero-schema/src/builder/table-builder.d.ts +1 -1
- package/out/zero-schema/src/builder/table-builder.d.ts.map +1 -1
- package/out/zero-schema/src/builder/table-builder.js +1 -1
- package/out/zero-schema/src/builder/table-builder.js.map +1 -1
- package/out/zero-schema/src/schema-config.d.ts +0 -1
- package/out/zero-schema/src/schema-config.d.ts.map +1 -1
- package/out/zero-schema/src/schema-config.js +1 -1
- package/out/zero-schema/src/schema-config.js.map +1 -1
- package/out/zero-schema/src/table-schema.d.ts +3 -11
- package/out/zero-schema/src/table-schema.d.ts.map +1 -1
- package/out/zero-server/src/queries/process-queries.d.ts +2 -4
- package/out/zero-server/src/queries/process-queries.d.ts.map +1 -1
- package/out/zero-server/src/queries/process-queries.js.map +1 -1
- package/out/zero-solid/src/solid-view.d.ts +0 -2
- package/out/zero-solid/src/solid-view.d.ts.map +1 -1
- package/out/zero-solid/src/solid-view.js +1 -1
- package/out/zero-solid/src/solid-view.js.map +1 -1
- package/out/zero-types/src/name-mapper.d.ts +2 -1
- package/out/zero-types/src/name-mapper.d.ts.map +1 -1
- package/out/zero-types/src/name-mapper.js.map +1 -1
- package/out/zero-types/src/schema-value.d.ts +3 -2
- package/out/zero-types/src/schema-value.d.ts.map +1 -1
- package/out/zero-types/src/schema.d.ts +1 -1
- package/out/zero-types/src/schema.d.ts.map +1 -1
- package/out/zql/src/builder/builder.d.ts +1 -11
- package/out/zql/src/builder/builder.d.ts.map +1 -1
- package/out/zql/src/builder/builder.js +1 -1
- package/out/zql/src/builder/builder.js.map +1 -1
- package/out/zql/src/builder/filter.d.ts +0 -1
- package/out/zql/src/builder/filter.d.ts.map +1 -1
- package/out/zql/src/builder/filter.js.map +1 -1
- package/out/zql/src/error.d.ts +0 -5
- package/out/zql/src/error.d.ts.map +1 -1
- package/out/zql/src/error.js.map +1 -1
- package/out/zql/src/ivm/constraint.d.ts +0 -7
- package/out/zql/src/ivm/constraint.d.ts.map +1 -1
- package/out/zql/src/ivm/constraint.js +1 -1
- package/out/zql/src/ivm/constraint.js.map +1 -1
- package/out/zql/src/ivm/data.d.ts +0 -1
- package/out/zql/src/ivm/data.d.ts.map +1 -1
- package/out/zql/src/ivm/data.js.map +1 -1
- package/out/zql/src/ivm/memory-source.d.ts +1 -2
- package/out/zql/src/ivm/memory-source.d.ts.map +1 -1
- package/out/zql/src/ivm/memory-source.js +1 -1
- package/out/zql/src/ivm/memory-source.js.map +1 -1
- package/out/zql/src/ivm/stream.d.ts +0 -1
- package/out/zql/src/ivm/stream.d.ts.map +1 -1
- package/out/zql/src/ivm/stream.js.map +1 -1
- package/out/zql/src/ivm/union-fan-in.d.ts +0 -1
- package/out/zql/src/ivm/union-fan-in.d.ts.map +1 -1
- package/out/zql/src/ivm/union-fan-in.js +1 -1
- package/out/zql/src/ivm/union-fan-in.js.map +1 -1
- package/out/zql/src/ivm/view-apply-change.d.ts +5 -35
- package/out/zql/src/ivm/view-apply-change.d.ts.map +1 -1
- package/out/zql/src/ivm/view-apply-change.js +1 -1
- package/out/zql/src/ivm/view-apply-change.js.map +1 -1
- package/out/zql/src/mutate/crud.d.ts +1 -3
- package/out/zql/src/mutate/crud.d.ts.map +1 -1
- package/out/zql/src/mutate/crud.js +1 -1
- package/out/zql/src/mutate/crud.js.map +1 -1
- package/out/zql/src/mutate/mutator-registry.d.ts +1 -1
- package/out/zql/src/mutate/mutator-registry.d.ts.map +1 -1
- package/out/zql/src/mutate/mutator-registry.js.map +1 -1
- package/out/zql/src/mutate/mutator.d.ts +1 -1
- package/out/zql/src/mutate/mutator.d.ts.map +1 -1
- package/out/zql/src/mutate/mutator.js.map +1 -1
- package/out/zql/src/planner/planner-debug.d.ts +10 -9
- package/out/zql/src/planner/planner-debug.d.ts.map +1 -1
- package/out/zql/src/planner/planner-debug.js.map +1 -1
- package/out/zql/src/planner/planner-node.d.ts +0 -1
- package/out/zql/src/planner/planner-node.d.ts.map +1 -1
- package/out/zql/src/planner/planner-node.js.map +1 -1
- package/out/zql/src/planner/planner-warnings.d.ts +3 -3
- package/out/zql/src/planner/planner-warnings.d.ts.map +1 -1
- package/out/zql/src/planner/planner-warnings.js.map +1 -1
- package/out/zql/src/query/expression.d.ts +0 -22
- package/out/zql/src/query/expression.d.ts.map +1 -1
- package/out/zql/src/query/expression.js +1 -1
- package/out/zql/src/query/expression.js.map +1 -1
- package/out/zql/src/query/query-delegate-base.d.ts +0 -7
- package/out/zql/src/query/query-delegate-base.d.ts.map +1 -1
- package/out/zql/src/query/query-delegate-base.js +2 -2
- package/out/zql/src/query/query-delegate-base.js.map +1 -1
- package/out/zql/src/query/query-delegate.d.ts +1 -4
- package/out/zql/src/query/query-delegate.d.ts.map +1 -1
- package/out/zql/src/query/query-internals.d.ts +0 -3
- package/out/zql/src/query/query-internals.d.ts.map +1 -1
- package/out/zql/src/query/query-internals.js.map +1 -1
- package/out/zql/src/query/query-registry.d.ts +5 -5
- package/out/zql/src/query/query-registry.d.ts.map +1 -1
- package/out/zql/src/query/query-registry.js.map +1 -1
- package/out/zql/src/query/query.d.ts +2 -13
- package/out/zql/src/query/query.d.ts.map +1 -1
- package/out/zql/src/query/runnable-query-impl.d.ts +1 -19
- package/out/zql/src/query/runnable-query-impl.d.ts.map +1 -1
- package/out/zql/src/query/runnable-query-impl.js +1 -1
- package/out/zql/src/query/runnable-query-impl.js.map +1 -1
- package/out/zql/src/query/ttl.d.ts +2 -3
- package/out/zql/src/query/ttl.d.ts.map +1 -1
- package/out/zql/src/query/ttl.js.map +1 -1
- package/out/zqlite/src/query-builder.d.ts +0 -2
- package/out/zqlite/src/query-builder.d.ts.map +1 -1
- package/out/zqlite/src/query-builder.js +1 -1
- package/out/zqlite/src/query-builder.js.map +1 -1
- package/out/zqlite/src/table-source.d.ts +0 -1
- package/out/zqlite/src/table-source.d.ts.map +1 -1
- package/out/zqlite/src/table-source.js +1 -1
- package/out/zqlite/src/table-source.js.map +1 -1
- package/package.json +2 -3
|
@@ -17,7 +17,6 @@ type BaseNode<V> = FrozenTag<readonly [level: number, entries: ReadonlyArray<Ent
|
|
|
17
17
|
export type InternalNode = BaseNode<Hash>;
|
|
18
18
|
export type DataNode = BaseNode<FrozenJSONValue>;
|
|
19
19
|
export declare function makeNodeChunkData<V>(level: number, entries: ReadonlyArray<Entry<V>>, formatVersion: FormatVersion): BaseNode<V>;
|
|
20
|
-
export type Node = DataNode | InternalNode;
|
|
21
20
|
/**
|
|
22
21
|
* Describes the changes that happened to Replicache after a
|
|
23
22
|
* {@link WriteTransaction} was committed.
|
|
@@ -81,7 +80,6 @@ type BinarySearchEntries = readonly Entry<unknown>[];
|
|
|
81
80
|
export declare function binarySearch(key: string, entries: BinarySearchEntries): number;
|
|
82
81
|
export declare function binarySearchFound(i: number, entries: BinarySearchEntries, key: string): boolean;
|
|
83
82
|
export declare function parseBTreeNode(v: unknown, formatVersion: FormatVersion, getSizeOfEntry: <K, V>(key: K, value: V) => number): InternalNode | DataNode;
|
|
84
|
-
export declare function isInternalNode(node: Node): node is InternalNode;
|
|
85
83
|
declare abstract class NodeImpl<Value> {
|
|
86
84
|
#private;
|
|
87
85
|
entries: Array<Entry<Value>>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../../../../../replicache/src/btree/node.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAC,IAAI,EAAC,MAAM,6BAA6B,CAAC;AAEtD,OAAO,EAEL,KAAK,iBAAiB,EAEvB,MAAM,6BAA6B,CAAC;AAGrC,OAAO,KAAK,EAAC,QAAQ,EAAC,MAAM,gBAAgB,CAAC;AAC7C,OAAO,KAAK,aAAa,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,SAAS,EAGf,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAC,KAAK,IAAI,EAA2B,MAAM,YAAY,CAAC;AAC/D,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,WAAW,CAAC;AACzC,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,YAAY,CAAC;AAE3C,KAAK,aAAa,GAAG,IAAI,CAAC,OAAO,aAAa,CAAC,CAAC;AAEhD,MAAM,MAAM,KAAK,CAAC,CAAC,IAAI,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,WAAW,EAAE,MAAM,CAAC,CAAC;AAE7E,eAAO,MAAM,UAAU,IAAI,CAAC;AAC5B,eAAO,MAAM,YAAY,IAAI,CAAC;AAE9B;;GAEG;AACH,KAAK,QAAQ,CAAC,CAAC,IAAI,SAAS,CAC1B,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAC3D,CAAC;AACF,MAAM,MAAM,YAAY,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;AAE1C,MAAM,MAAM,QAAQ,GAAG,QAAQ,CAAC,eAAe,CAAC,CAAC;AAEjD,wBAAgB,iBAAiB,CAAC,CAAC,EACjC,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAChC,aAAa,EAAE,aAAa,GAC3B,QAAQ,CAAC,CAAC,CAAC,CAOb;AAED
|
|
1
|
+
{"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../../../../../replicache/src/btree/node.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node.js","names":["binarySearchWithFunc","skipBTreeNodeAsserts"],"sources":["../../../../../replicache/src/btree/node.ts"],"sourcesContent":["import {compareUTF8} from 'compare-utf8';\nimport {newArray} from '../../../shared/src/arrays.ts';\nimport {\n assert,\n assertArray,\n assertNumber,\n assertString,\n} from '../../../shared/src/asserts.ts';\nimport {binarySearch as binarySearchWithFunc} from '../../../shared/src/binary-search.ts';\nimport type {Enum} from '../../../shared/src/enum.ts';\nimport {joinIterables} from '../../../shared/src/iterables.ts';\nimport {\n type JSONValue,\n type ReadonlyJSONValue,\n assertJSONValue,\n} from '../../../shared/src/json.ts';\nimport {getOrInsertComputed} from '../../../shared/src/map.ts';\nimport {skipBTreeNodeAsserts} from '../config.ts';\nimport type {IndexKey} from '../db/index.ts';\nimport * as FormatVersion from '../format-version-enum.ts';\nimport {\n type FrozenJSONValue,\n type FrozenTag,\n assertDeepFrozen,\n deepFreeze,\n} from '../frozen-json.ts';\nimport {type Hash, emptyHash, newRandomHash} from '../hash.ts';\nimport type {BTreeRead} from './read.ts';\nimport type {BTreeWrite} from './write.ts';\n\ntype FormatVersion = Enum<typeof FormatVersion>;\n\nexport type Entry<V> = readonly [key: string, value: V, sizeOfEntry: number];\n\nexport const NODE_LEVEL = 0;\nexport const NODE_ENTRIES = 1;\n\n/**\n * The type of B+Tree node chunk data\n */\ntype BaseNode<V> = FrozenTag<\n readonly [level: number, entries: ReadonlyArray<Entry<V>>]\n>;\nexport type InternalNode = BaseNode<Hash>;\n\nexport type DataNode = BaseNode<FrozenJSONValue>;\n\nexport function makeNodeChunkData<V>(\n level: number,\n entries: ReadonlyArray<Entry<V>>,\n formatVersion: FormatVersion,\n): BaseNode<V> {\n return deepFreeze([\n level,\n (formatVersion >= FormatVersion.V7\n ? entries\n : entries.map(e => e.slice(0, 2))) as readonly ReadonlyJSONValue[],\n ]) as BaseNode<V>;\n}\n\nexport type Node = DataNode | InternalNode;\n\n/**\n * Describes the changes that happened to Replicache after a\n * {@link WriteTransaction} was committed.\n *\n * @experimental This type is experimental and may change in the future.\n */\nexport type Diff = IndexDiff | NoIndexDiff;\n\n/**\n * @experimental This type is experimental and may change in the future.\n */\nexport type IndexDiff = readonly DiffOperation<IndexKey>[];\n\n/**\n * @experimental This type is experimental and may change in the future.\n */\nexport type NoIndexDiff = readonly DiffOperation<string>[];\n\n/**\n * InternalDiff uses string keys even for the secondary index maps.\n */\nexport type InternalDiff = readonly InternalDiffOperation[];\n\nexport type DiffOperationAdd<Key, Value = ReadonlyJSONValue> = {\n readonly op: 'add';\n readonly key: Key;\n readonly newValue: Value;\n};\n\nexport type DiffOperationDel<Key, Value = ReadonlyJSONValue> = {\n readonly op: 'del';\n readonly key: Key;\n readonly oldValue: Value;\n};\n\nexport type DiffOperationChange<Key, Value = ReadonlyJSONValue> = {\n readonly op: 'change';\n readonly key: Key;\n readonly oldValue: Value;\n readonly newValue: Value;\n};\n\n/**\n * The individual parts describing the changes that happened to the Replicache\n * data. There are three different kinds of operations:\n * - `add`: A new entry was added.\n * - `del`: An entry was deleted.\n * - `change`: An entry was changed.\n *\n * @experimental This type is experimental and may change in the future.\n */\nexport type DiffOperation<Key> =\n | DiffOperationAdd<Key>\n | DiffOperationDel<Key>\n | DiffOperationChange<Key>;\n\n// Duplicated with DiffOperation to make the docs less confusing.\nexport type InternalDiffOperation<Key = string, Value = FrozenJSONValue> =\n | DiffOperationAdd<Key, Value>\n | DiffOperationDel<Key, Value>\n | DiffOperationChange<Key, Value>;\n\n/**\n * Finds the leaf where a key is (if present) or where it should go if not\n * present.\n */\nexport async function findLeaf(\n key: string,\n hash: Hash,\n source: BTreeRead,\n expectedRootHash: Hash,\n): Promise<DataNodeImpl> {\n const node = await source.getNode(hash);\n // The root changed. Try again\n if (expectedRootHash !== source.rootHash) {\n return findLeaf(key, source.rootHash, source, source.rootHash);\n }\n if (isDataNodeImpl(node)) {\n return node;\n }\n const {entries} = node;\n let i = binarySearch(key, entries);\n if (i === entries.length) {\n i--;\n }\n const entry = entries[i];\n return findLeaf(key, entry[1], source, expectedRootHash);\n}\n\ntype BinarySearchEntries = readonly Entry<unknown>[];\n\n/**\n * Does a binary search over entries\n *\n * If the key found then the return value is the index it was found at.\n *\n * If the key was *not* found then the return value is the index where it should\n * be inserted at\n */\nexport function binarySearch(\n key: string,\n entries: BinarySearchEntries,\n): number {\n return binarySearchFrom(key, entries, 0);\n}\n\n/**\n * Binary search starting from a given index.\n */\nfunction binarySearchFrom(\n key: string,\n entries: BinarySearchEntries,\n start: number,\n): number {\n const result = binarySearchWithFunc(entries.length - start, i =>\n compareUTF8(key, entries[start + i][0]),\n );\n return start + result;\n}\n\nexport function binarySearchFound(\n i: number,\n entries: BinarySearchEntries,\n key: string,\n): boolean {\n return i !== entries.length && entries[i][0] === key;\n}\n\nexport function parseBTreeNode(\n v: unknown,\n formatVersion: FormatVersion,\n getSizeOfEntry: <K, V>(key: K, value: V) => number,\n): InternalNode | DataNode {\n if (skipBTreeNodeAsserts && formatVersion >= FormatVersion.V7) {\n return v as InternalNode | DataNode;\n }\n\n assertArray(v);\n assertDeepFrozen(v);\n // Be relaxed about what we accept.\n assert(v.length >= 2, 'Expected node array to have at least 2 elements');\n const [level, entries] = v;\n assertNumber(level);\n assertArray(entries);\n\n const f = level > 0 ? assertString : assertJSONValue;\n\n // For V7 we do not need to change the entries. Just assert that they are correct.\n if (formatVersion >= FormatVersion.V7) {\n for (const e of entries) {\n assertEntry(e, f);\n }\n return v as unknown as InternalNode | DataNode;\n }\n\n const newEntries = entries.map(e => convertNonV7Entry(e, f, getSizeOfEntry));\n return [level, newEntries] as unknown as InternalNode | DataNode;\n}\n\nfunction assertEntry(\n entry: unknown,\n f:\n | ((v: unknown) => asserts v is Hash)\n | ((v: unknown) => asserts v is JSONValue),\n): asserts entry is Entry<Hash | JSONValue> {\n assertArray(entry);\n // Be relaxed about what we accept.\n assert(entry.length >= 3, 'Expected entry array to have at least 3 elements');\n assertString(entry[0]);\n f(entry[1]);\n assertNumber(entry[2]);\n}\n\n/**\n * Converts an entry that was from a format version before V7 to the format\n * wanted by V7.\n */\nfunction convertNonV7Entry(\n entry: unknown,\n f:\n | ((v: unknown) => asserts v is Hash)\n | ((v: unknown) => asserts v is JSONValue),\n getSizeOfEntry: <K, V>(key: K, value: V) => number,\n): Entry<Hash | JSONValue> {\n assertArray(entry);\n assert(entry.length >= 2, 'Expected entry array to have at least 2 elements');\n assertString(entry[0]);\n f(entry[1]);\n const entrySize = getSizeOfEntry(entry[0], entry[1]);\n return [entry[0], entry[1], entrySize] as Entry<Hash | JSONValue>;\n}\n\nexport function isInternalNode(node: Node): node is InternalNode {\n return node[NODE_LEVEL] > 0;\n}\n\nabstract class NodeImpl<Value> {\n entries: Array<Entry<Value>>;\n hash: Hash;\n abstract readonly level: number;\n readonly isMutable: boolean;\n\n #childNodeSize = -1;\n\n constructor(entries: Array<Entry<Value>>, hash: Hash, isMutable: boolean) {\n this.entries = entries;\n this.hash = hash;\n this.isMutable = isMutable;\n }\n\n abstract set(\n key: string,\n value: FrozenJSONValue,\n entrySize: number,\n tree: BTreeWrite,\n ): Promise<NodeImpl<Value>>;\n\n abstract putMany(\n entries: ReadonlyArray<Entry<FrozenJSONValue>>,\n tree: BTreeWrite,\n ): Promise<NodeImpl<Value>>;\n\n abstract del(\n key: string,\n tree: BTreeWrite,\n ): Promise<NodeImpl<Value> | DataNodeImpl>;\n\n maxKey(): string {\n // oxlint-disable-next-line typescript/no-non-null-assertion\n return this.entries.at(-1)![0];\n }\n\n getChildNodeSize(tree: BTreeRead): number {\n if (this.#childNodeSize !== -1) {\n return this.#childNodeSize;\n }\n\n let sum = tree.chunkHeaderSize;\n for (const entry of this.entries) {\n sum += entry[2];\n }\n return (this.#childNodeSize = sum);\n }\n\n protected _updateNode(tree: BTreeWrite) {\n this.#childNodeSize = -1;\n tree.updateNode(\n this as NodeImpl<unknown> as DataNodeImpl | InternalNodeImpl,\n );\n }\n}\n\nexport function toChunkData<V>(\n node: NodeImpl<V>,\n formatVersion: FormatVersion,\n): BaseNode<V> {\n return makeNodeChunkData(node.level, node.entries, formatVersion);\n}\n\nexport class DataNodeImpl extends NodeImpl<FrozenJSONValue> {\n readonly level = 0;\n\n set(\n key: string,\n value: FrozenJSONValue,\n entrySize: number,\n tree: BTreeWrite,\n ): Promise<DataNodeImpl> {\n let deleteCount: number;\n const i = binarySearch(key, this.entries);\n if (!binarySearchFound(i, this.entries, key)) {\n // Not found, insert.\n deleteCount = 0;\n } else {\n deleteCount = 1;\n }\n\n return Promise.resolve(\n this.#splice(tree, i, deleteCount, [key, value, entrySize]),\n );\n }\n\n putMany(\n entries: ReadonlyArray<Entry<FrozenJSONValue>>,\n tree: BTreeWrite,\n ): Promise<DataNodeImpl> {\n if (entries.length === 0) {\n return Promise.resolve(this);\n }\n\n // Merge sorted entries with existing entries\n const merged: Entry<FrozenJSONValue>[] = [];\n let i = 0; // index in this.entries\n let j = 0; // index in entries\n\n while (i < this.entries.length && j < entries.length) {\n const existingEntry = this.entries[i];\n const newEntry = entries[j];\n const cmp = compareUTF8(existingEntry[0], newEntry[0]);\n\n if (cmp < 0) {\n merged.push(existingEntry);\n i++;\n } else if (cmp > 0) {\n merged.push(newEntry);\n j++;\n } else {\n // Same key, new entry wins (update)\n merged.push(newEntry);\n i++;\n j++;\n }\n }\n\n // Add remaining entries\n while (i < this.entries.length) {\n merged.push(this.entries[i]);\n i++;\n }\n while (j < entries.length) {\n merged.push(entries[j]);\n j++;\n }\n\n if (this.isMutable) {\n this.entries = merged;\n this._updateNode(tree);\n return Promise.resolve(this);\n }\n\n return Promise.resolve(tree.newDataNodeImpl(merged));\n }\n\n #splice(\n tree: BTreeWrite,\n start: number,\n deleteCount: number,\n ...items: Entry<FrozenJSONValue>[]\n ): DataNodeImpl {\n if (this.isMutable) {\n this.entries.splice(start, deleteCount, ...items);\n this._updateNode(tree);\n return this;\n }\n\n const entries = readonlySplice(this.entries, start, deleteCount, ...items);\n return tree.newDataNodeImpl(entries);\n }\n\n del(key: string, tree: BTreeWrite): Promise<DataNodeImpl> {\n const i = binarySearch(key, this.entries);\n if (!binarySearchFound(i, this.entries, key)) {\n // Not found. Return this without changes.\n return Promise.resolve(this);\n }\n\n // Found. Create new node or mutate existing one.\n return Promise.resolve(this.#splice(tree, i, 1));\n }\n\n async *keys(_tree: BTreeRead): AsyncGenerator<string, void> {\n for (const entry of this.entries) {\n yield entry[0];\n }\n }\n\n async *entriesIter(\n _tree: BTreeRead,\n ): AsyncGenerator<Entry<FrozenJSONValue>, void> {\n for (const entry of this.entries) {\n yield entry;\n }\n }\n}\n\nfunction readonlySplice<T>(\n array: ReadonlyArray<T>,\n start: number,\n deleteCount: number,\n ...items: T[]\n): T[] {\n const arr = array.slice(0, start);\n for (let i = 0; i < items.length; i++) {\n arr.push(items[i]);\n }\n for (let i = start + deleteCount; i < array.length; i++) {\n arr.push(array[i]);\n }\n return arr;\n}\n\nexport class InternalNodeImpl extends NodeImpl<Hash> {\n readonly level: number;\n\n constructor(\n entries: Array<Entry<Hash>>,\n hash: Hash,\n level: number,\n isMutable: boolean,\n ) {\n super(entries, hash, isMutable);\n this.level = level;\n }\n\n async set(\n key: string,\n value: FrozenJSONValue,\n entrySize: number,\n tree: BTreeWrite,\n ): Promise<InternalNodeImpl> {\n let i = binarySearch(key, this.entries);\n if (i === this.entries.length) {\n // We are going to insert into last (right most) leaf.\n i--;\n }\n\n const childHash = this.entries[i][1];\n const oldChildNode = await tree.getNode(childHash);\n\n const childNode = await oldChildNode.set(key, value, entrySize, tree);\n\n const childNodeSize = childNode.getChildNodeSize(tree);\n if (childNodeSize > tree.maxSize || childNodeSize < tree.minSize) {\n return this.#mergeAndPartition(tree, i, childNode);\n }\n\n const newEntry = createNewInternalEntryForNode(\n childNode,\n tree.getEntrySize,\n );\n return this.#replaceChild(tree, i, newEntry);\n }\n\n async putMany(\n entries: ReadonlyArray<Entry<FrozenJSONValue>>,\n tree: BTreeWrite,\n ): Promise<InternalNodeImpl> {\n if (entries.length === 0) {\n return this;\n }\n\n // Group entries by child index\n // Since entries are sorted, we can restrict the binary search range\n const childGroups: Map<number, Entry<FrozenJSONValue>[]> = new Map();\n\n let searchStart = 0;\n for (const entry of entries) {\n const key = entry[0];\n // Binary search from searchStart to end (entries are sorted)\n let i = binarySearchFrom(key, this.entries, searchStart);\n if (i === this.entries.length) {\n // Insert into last (right most) leaf.\n i--;\n }\n searchStart = i;\n\n getOrInsertComputed(childGroups, i, newArray).push(entry);\n }\n\n // Process each affected child\n const newEntries = [...this.entries];\n const childrenToRebalance: Array<{\n index: number;\n node: DataNodeImpl | InternalNodeImpl;\n }> = [];\n\n for (const [childIndex, childEntries] of childGroups) {\n const childHash = this.entries[childIndex][1];\n const oldChildNode = await tree.getNode(childHash);\n const childNode = await oldChildNode.putMany(childEntries, tree);\n\n const childNodeSize = childNode.getChildNodeSize(tree);\n if (childNodeSize > tree.maxSize || childNodeSize < tree.minSize) {\n childrenToRebalance.push({index: childIndex, node: childNode});\n } else {\n const newEntry = createNewInternalEntryForNode(\n childNode,\n tree.getEntrySize,\n );\n newEntries[childIndex] = newEntry;\n }\n }\n\n // Handle rebalancing - merge adjacent children that need rebalancing\n // into contiguous groups and process each group as one unit.\n //\n // BUG FIX: Previously, each child was rebalanced independently R-to-L.\n // When adjacent children (e.g., indices 0 and 1) both needed rebalancing,\n // child[1] would merge with sibling[0] (the ORIGINAL), then child[0]\n // would merge with the rebalanced result at position 1, duplicating\n // child[0]'s data. The fix groups adjacent indices together.\n if (childrenToRebalance.length > 0) {\n childrenToRebalance.sort((a, b) => a.index - b.index);\n\n // Group adjacent indices into contiguous runs, each extended by one\n // sibling on either side for merge context.\n const groups: Array<{\n nodes: Map<number, DataNodeImpl | InternalNodeImpl>;\n minIndex: number;\n maxIndex: number;\n }> = [];\n\n for (const {index, node} of childrenToRebalance) {\n const lastGroup = groups.at(-1);\n // Adjacent to previous group? (within 1 index of the last group's max)\n if (lastGroup && index <= lastGroup.maxIndex + 1) {\n lastGroup.nodes.set(index, node);\n lastGroup.maxIndex = index;\n } else {\n groups.push({\n nodes: new Map([[index, node]]),\n minIndex: index,\n maxIndex: index,\n });\n }\n }\n\n // Process groups from right to left to maintain indices during splices.\n for (let g = groups.length - 1; g >= 0; g--) {\n const group = groups[g];\n\n // Extend range by one sibling on each side for merge context.\n const startIndex = Math.max(0, group.minIndex - 1);\n const endIndex = Math.min(newEntries.length - 1, group.maxIndex + 1);\n const removeCount = endIndex - startIndex + 1;\n\n // Collect all entries from the range: use the putMany result for\n // indices that were rebalanced, the current newEntries node otherwise.\n type IterableHashEntries = Iterable<Entry<Hash>>;\n const allValues: IterableHashEntries[] = [];\n for (let idx = startIndex; idx <= endIndex; idx++) {\n const rebalancedNode = group.nodes.get(idx);\n if (rebalancedNode) {\n allValues.push(rebalancedNode.entries as IterableHashEntries);\n } else {\n const hash = newEntries[idx][1];\n const existingNode = await tree.getNode(hash);\n allValues.push(existingNode.entries as IterableHashEntries);\n }\n }\n\n const level = this.level - 1;\n const merged = joinIterables(...allValues);\n const rebalanced = partition(\n merged,\n e => e[2],\n tree.minSize - tree.chunkHeaderSize,\n tree.maxSize - tree.chunkHeaderSize,\n entries => {\n const node = tree.newNodeImpl(entries, level);\n return createNewInternalEntryForNode(node, tree.getEntrySize);\n },\n );\n\n newEntries.splice(startIndex, removeCount, ...rebalanced);\n }\n }\n\n if (this.isMutable) {\n this.entries = newEntries;\n this._updateNode(tree);\n return this;\n }\n\n return tree.newInternalNodeImpl(newEntries, this.level);\n }\n\n /**\n * This merges the child node entries with previous or next sibling and then\n * partitions the merged entries.\n */\n async #mergeAndPartition(\n tree: BTreeWrite,\n i: number,\n childNode: DataNodeImpl | InternalNodeImpl,\n ): Promise<InternalNodeImpl> {\n const level = this.level - 1;\n const thisEntries = this.entries;\n\n type IterableHashEntries = Iterable<Entry<Hash>>;\n\n let values: IterableHashEntries;\n let startIndex: number;\n let removeCount: number;\n if (i > 0) {\n const hash = thisEntries[i - 1][1];\n const previousSibling = await tree.getNode(hash);\n values = joinIterables(\n previousSibling.entries as IterableHashEntries,\n childNode.entries as IterableHashEntries,\n );\n startIndex = i - 1;\n removeCount = 2;\n } else if (i < thisEntries.length - 1) {\n const hash = thisEntries[i + 1][1];\n const nextSibling = await tree.getNode(hash);\n values = joinIterables(\n childNode.entries as IterableHashEntries,\n nextSibling.entries as IterableHashEntries,\n );\n startIndex = i;\n removeCount = 2;\n } else {\n values = childNode.entries as IterableHashEntries;\n startIndex = i;\n removeCount = 1;\n }\n\n const newEntries = partition(\n values,\n value => value[2],\n tree.minSize - tree.chunkHeaderSize,\n tree.maxSize - tree.chunkHeaderSize,\n entries => {\n const node = tree.newNodeImpl(entries, level);\n return createNewInternalEntryForNode(node, tree.getEntrySize);\n },\n );\n\n if (this.isMutable) {\n this.entries.splice(startIndex, removeCount, ...newEntries);\n this._updateNode(tree);\n return this;\n }\n\n const entries = readonlySplice(\n thisEntries,\n startIndex,\n removeCount,\n ...newEntries,\n );\n\n return tree.newInternalNodeImpl(entries, this.level);\n }\n\n #replaceChild(\n tree: BTreeWrite,\n index: number,\n newEntry: Entry<Hash>,\n ): InternalNodeImpl {\n if (this.isMutable) {\n this.entries.splice(index, 1, newEntry);\n this._updateNode(tree);\n return this;\n }\n const entries = readonlySplice(this.entries, index, 1, newEntry);\n return tree.newInternalNodeImpl(entries, this.level);\n }\n\n async del(\n key: string,\n tree: BTreeWrite,\n ): Promise<InternalNodeImpl | DataNodeImpl> {\n const i = binarySearch(key, this.entries);\n if (i === this.entries.length) {\n // Key is larger than maxKey of rightmost entry so it is not present.\n return this;\n }\n\n const childHash = this.entries[i][1];\n const oldChildNode = await tree.getNode(childHash);\n const oldHash = oldChildNode.hash;\n\n const childNode = await oldChildNode.del(key, tree);\n if (childNode.hash === oldHash) {\n // Not changed so not found.\n return this;\n }\n\n if (childNode.entries.length === 0) {\n // Subtree is now empty. Remove internal node.\n const entries = readonlySplice(this.entries, i, 1);\n return tree.newInternalNodeImpl(entries, this.level);\n }\n\n if (i === 0 && this.entries.length === 1) {\n // There was only one node at this level and it was removed. We can return\n // the modified subtree.\n return childNode;\n }\n\n // The child node is still a good size.\n if (childNode.getChildNodeSize(tree) > tree.minSize) {\n // No merging needed.\n const entry = createNewInternalEntryForNode(childNode, tree.getEntrySize);\n return this.#replaceChild(tree, i, entry);\n }\n\n // Child node size is too small.\n return this.#mergeAndPartition(tree, i, childNode);\n }\n\n async *keys(tree: BTreeRead): AsyncGenerator<string, void> {\n for (const entry of this.entries) {\n const childNode = await tree.getNode(entry[1]);\n yield* childNode.keys(tree);\n }\n }\n\n async *entriesIter(\n tree: BTreeRead,\n ): AsyncGenerator<Entry<FrozenJSONValue>, void> {\n for (const entry of this.entries) {\n const childNode = await tree.getNode(entry[1]);\n yield* childNode.entriesIter(tree);\n }\n }\n\n getChildren(\n start: number,\n length: number,\n tree: BTreeRead,\n ): Promise<Array<InternalNodeImpl | DataNodeImpl>> {\n const ps: Promise<DataNodeImpl | InternalNodeImpl>[] = [];\n for (let i = start; i < length && i < this.entries.length; i++) {\n ps.push(tree.getNode(this.entries[i][1]));\n }\n return Promise.all(ps);\n }\n\n async getCompositeChildren(\n start: number,\n length: number,\n tree: BTreeRead,\n ): Promise<InternalNodeImpl | DataNodeImpl> {\n const {level} = this;\n\n if (length === 0) {\n return new InternalNodeImpl([], newRandomHash(), level - 1, true);\n }\n\n const output = await this.getChildren(start, start + length, tree);\n\n if (level > 1) {\n const entries: Entry<Hash>[] = [];\n for (const child of output as InternalNodeImpl[]) {\n entries.push(...child.entries);\n }\n return new InternalNodeImpl(entries, newRandomHash(), level - 1, true);\n }\n\n assert(level === 1, 'Expected level to be 1');\n const entries: Entry<FrozenJSONValue>[] = [];\n for (const child of output as DataNodeImpl[]) {\n entries.push(...child.entries);\n }\n return new DataNodeImpl(entries, newRandomHash(), true);\n }\n}\n\nexport function newNodeImpl(\n entries: Array<Entry<FrozenJSONValue>>,\n hash: Hash,\n level: number,\n isMutable: boolean,\n): DataNodeImpl;\nexport function newNodeImpl(\n entries: Array<Entry<Hash>>,\n hash: Hash,\n level: number,\n isMutable: boolean,\n): InternalNodeImpl;\nexport function newNodeImpl(\n entries: Array<Entry<FrozenJSONValue>> | Array<Entry<Hash>>,\n hash: Hash,\n level: number,\n isMutable: boolean,\n): DataNodeImpl | InternalNodeImpl;\nexport function newNodeImpl(\n entries: Array<Entry<FrozenJSONValue>> | Array<Entry<Hash>>,\n hash: Hash,\n level: number,\n isMutable: boolean,\n): DataNodeImpl | InternalNodeImpl {\n if (level === 0) {\n return new DataNodeImpl(\n entries as Entry<FrozenJSONValue>[],\n hash,\n isMutable,\n );\n }\n return new InternalNodeImpl(entries as Entry<Hash>[], hash, level, isMutable);\n}\n\nexport function isDataNodeImpl(\n node: DataNodeImpl | InternalNodeImpl,\n): node is DataNodeImpl {\n return node.level === 0;\n}\n\nexport function partition<T, R>(\n values: Iterable<T>,\n // This is the size of each Entry\n getSizeOfEntry: (v: T) => number,\n min: number,\n max: number,\n create: (entries: T[]) => R,\n): R[] {\n const results: R[] = [];\n let sum = 0;\n let accum: T[] = [];\n // The most recently finalized partition, held back until we know it won't be\n // merged with trailing entries.\n let lastPartition: T[] | null = null;\n let lastSize = 0;\n\n function commitLast() {\n if (lastPartition !== null) {\n results.push(create(lastPartition));\n lastPartition = null;\n }\n }\n\n for (const value of values) {\n const size = getSizeOfEntry(value);\n if (size >= max) {\n if (accum.length > 0) {\n commitLast();\n lastPartition = accum;\n lastSize = sum;\n accum = [];\n sum = 0;\n }\n commitLast();\n lastPartition = [value];\n lastSize = size;\n } else if (sum + size >= min) {\n accum.push(value);\n commitLast();\n lastPartition = accum;\n lastSize = sum + size;\n accum = [];\n sum = 0;\n } else {\n sum += size;\n accum.push(value);\n }\n }\n\n if (sum > 0) {\n if (lastPartition !== null && sum + lastSize <= max) {\n lastPartition.push(...accum);\n commitLast();\n } else {\n commitLast();\n results.push(create(accum));\n }\n } else {\n commitLast();\n }\n\n return results;\n}\n\nexport const emptyDataNode = makeNodeChunkData<ReadonlyJSONValue>(\n 0,\n [],\n FormatVersion.Latest,\n);\nexport const emptyDataNodeImpl = new DataNodeImpl([], emptyHash, false);\n\nexport function createNewInternalEntryForNode(\n node: NodeImpl<unknown>,\n getSizeOfEntry: <K, V>(k: K, v: V) => number,\n): [string, Hash, number] {\n const key = node.maxKey();\n const value = node.hash;\n const size = getSizeOfEntry(key, value);\n return [key, value, size];\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"node.js","names":["binarySearchWithFunc","skipBTreeNodeAsserts"],"sources":["../../../../../replicache/src/btree/node.ts"],"sourcesContent":["import {compareUTF8} from 'compare-utf8';\nimport {newArray} from '../../../shared/src/arrays.ts';\nimport {\n assert,\n assertArray,\n assertNumber,\n assertString,\n} from '../../../shared/src/asserts.ts';\nimport {binarySearch as binarySearchWithFunc} from '../../../shared/src/binary-search.ts';\nimport type {Enum} from '../../../shared/src/enum.ts';\nimport {joinIterables} from '../../../shared/src/iterables.ts';\nimport {\n type JSONValue,\n type ReadonlyJSONValue,\n assertJSONValue,\n} from '../../../shared/src/json.ts';\nimport {getOrInsertComputed} from '../../../shared/src/map.ts';\nimport {skipBTreeNodeAsserts} from '../config.ts';\nimport type {IndexKey} from '../db/index.ts';\nimport * as FormatVersion from '../format-version-enum.ts';\nimport {\n type FrozenJSONValue,\n type FrozenTag,\n assertDeepFrozen,\n deepFreeze,\n} from '../frozen-json.ts';\nimport {type Hash, emptyHash, newRandomHash} from '../hash.ts';\nimport type {BTreeRead} from './read.ts';\nimport type {BTreeWrite} from './write.ts';\n\ntype FormatVersion = Enum<typeof FormatVersion>;\n\nexport type Entry<V> = readonly [key: string, value: V, sizeOfEntry: number];\n\nexport const NODE_LEVEL = 0;\nexport const NODE_ENTRIES = 1;\n\n/**\n * The type of B+Tree node chunk data\n */\ntype BaseNode<V> = FrozenTag<\n readonly [level: number, entries: ReadonlyArray<Entry<V>>]\n>;\nexport type InternalNode = BaseNode<Hash>;\n\nexport type DataNode = BaseNode<FrozenJSONValue>;\n\nexport function makeNodeChunkData<V>(\n level: number,\n entries: ReadonlyArray<Entry<V>>,\n formatVersion: FormatVersion,\n): BaseNode<V> {\n return deepFreeze([\n level,\n (formatVersion >= FormatVersion.V7\n ? entries\n : entries.map(e => e.slice(0, 2))) as readonly ReadonlyJSONValue[],\n ]) as BaseNode<V>;\n}\n\n/**\n * Describes the changes that happened to Replicache after a\n * {@link WriteTransaction} was committed.\n *\n * @experimental This type is experimental and may change in the future.\n */\nexport type Diff = IndexDiff | NoIndexDiff;\n\n/**\n * @experimental This type is experimental and may change in the future.\n */\nexport type IndexDiff = readonly DiffOperation<IndexKey>[];\n\n/**\n * @experimental This type is experimental and may change in the future.\n */\nexport type NoIndexDiff = readonly DiffOperation<string>[];\n\n/**\n * InternalDiff uses string keys even for the secondary index maps.\n */\nexport type InternalDiff = readonly InternalDiffOperation[];\n\nexport type DiffOperationAdd<Key, Value = ReadonlyJSONValue> = {\n readonly op: 'add';\n readonly key: Key;\n readonly newValue: Value;\n};\n\nexport type DiffOperationDel<Key, Value = ReadonlyJSONValue> = {\n readonly op: 'del';\n readonly key: Key;\n readonly oldValue: Value;\n};\n\nexport type DiffOperationChange<Key, Value = ReadonlyJSONValue> = {\n readonly op: 'change';\n readonly key: Key;\n readonly oldValue: Value;\n readonly newValue: Value;\n};\n\n/**\n * The individual parts describing the changes that happened to the Replicache\n * data. There are three different kinds of operations:\n * - `add`: A new entry was added.\n * - `del`: An entry was deleted.\n * - `change`: An entry was changed.\n *\n * @experimental This type is experimental and may change in the future.\n */\nexport type DiffOperation<Key> =\n | DiffOperationAdd<Key>\n | DiffOperationDel<Key>\n | DiffOperationChange<Key>;\n\n// Duplicated with DiffOperation to make the docs less confusing.\nexport type InternalDiffOperation<Key = string, Value = FrozenJSONValue> =\n | DiffOperationAdd<Key, Value>\n | DiffOperationDel<Key, Value>\n | DiffOperationChange<Key, Value>;\n\n/**\n * Finds the leaf where a key is (if present) or where it should go if not\n * present.\n */\nexport async function findLeaf(\n key: string,\n hash: Hash,\n source: BTreeRead,\n expectedRootHash: Hash,\n): Promise<DataNodeImpl> {\n const node = await source.getNode(hash);\n // The root changed. Try again\n if (expectedRootHash !== source.rootHash) {\n return findLeaf(key, source.rootHash, source, source.rootHash);\n }\n if (isDataNodeImpl(node)) {\n return node;\n }\n const {entries} = node;\n let i = binarySearch(key, entries);\n if (i === entries.length) {\n i--;\n }\n const entry = entries[i];\n return findLeaf(key, entry[1], source, expectedRootHash);\n}\n\ntype BinarySearchEntries = readonly Entry<unknown>[];\n\n/**\n * Does a binary search over entries\n *\n * If the key found then the return value is the index it was found at.\n *\n * If the key was *not* found then the return value is the index where it should\n * be inserted at\n */\nexport function binarySearch(\n key: string,\n entries: BinarySearchEntries,\n): number {\n return binarySearchFrom(key, entries, 0);\n}\n\n/**\n * Binary search starting from a given index.\n */\nfunction binarySearchFrom(\n key: string,\n entries: BinarySearchEntries,\n start: number,\n): number {\n const result = binarySearchWithFunc(entries.length - start, i =>\n compareUTF8(key, entries[start + i][0]),\n );\n return start + result;\n}\n\nexport function binarySearchFound(\n i: number,\n entries: BinarySearchEntries,\n key: string,\n): boolean {\n return i !== entries.length && entries[i][0] === key;\n}\n\nexport function parseBTreeNode(\n v: unknown,\n formatVersion: FormatVersion,\n getSizeOfEntry: <K, V>(key: K, value: V) => number,\n): InternalNode | DataNode {\n if (skipBTreeNodeAsserts && formatVersion >= FormatVersion.V7) {\n return v as InternalNode | DataNode;\n }\n\n assertArray(v);\n assertDeepFrozen(v);\n // Be relaxed about what we accept.\n assert(v.length >= 2, 'Expected node array to have at least 2 elements');\n const [level, entries] = v;\n assertNumber(level);\n assertArray(entries);\n\n const f = level > 0 ? assertString : assertJSONValue;\n\n // For V7 we do not need to change the entries. Just assert that they are correct.\n if (formatVersion >= FormatVersion.V7) {\n for (const e of entries) {\n assertEntry(e, f);\n }\n return v as unknown as InternalNode | DataNode;\n }\n\n const newEntries = entries.map(e => convertNonV7Entry(e, f, getSizeOfEntry));\n return [level, newEntries] as unknown as InternalNode | DataNode;\n}\n\nfunction assertEntry(\n entry: unknown,\n f:\n | ((v: unknown) => asserts v is Hash)\n | ((v: unknown) => asserts v is JSONValue),\n): asserts entry is Entry<Hash | JSONValue> {\n assertArray(entry);\n // Be relaxed about what we accept.\n assert(entry.length >= 3, 'Expected entry array to have at least 3 elements');\n assertString(entry[0]);\n f(entry[1]);\n assertNumber(entry[2]);\n}\n\n/**\n * Converts an entry that was from a format version before V7 to the format\n * wanted by V7.\n */\nfunction convertNonV7Entry(\n entry: unknown,\n f:\n | ((v: unknown) => asserts v is Hash)\n | ((v: unknown) => asserts v is JSONValue),\n getSizeOfEntry: <K, V>(key: K, value: V) => number,\n): Entry<Hash | JSONValue> {\n assertArray(entry);\n assert(entry.length >= 2, 'Expected entry array to have at least 2 elements');\n assertString(entry[0]);\n f(entry[1]);\n const entrySize = getSizeOfEntry(entry[0], entry[1]);\n return [entry[0], entry[1], entrySize] as Entry<Hash | JSONValue>;\n}\n\nabstract class NodeImpl<Value> {\n entries: Array<Entry<Value>>;\n hash: Hash;\n abstract readonly level: number;\n readonly isMutable: boolean;\n\n #childNodeSize = -1;\n\n constructor(entries: Array<Entry<Value>>, hash: Hash, isMutable: boolean) {\n this.entries = entries;\n this.hash = hash;\n this.isMutable = isMutable;\n }\n\n abstract set(\n key: string,\n value: FrozenJSONValue,\n entrySize: number,\n tree: BTreeWrite,\n ): Promise<NodeImpl<Value>>;\n\n abstract putMany(\n entries: ReadonlyArray<Entry<FrozenJSONValue>>,\n tree: BTreeWrite,\n ): Promise<NodeImpl<Value>>;\n\n abstract del(\n key: string,\n tree: BTreeWrite,\n ): Promise<NodeImpl<Value> | DataNodeImpl>;\n\n maxKey(): string {\n // oxlint-disable-next-line typescript/no-non-null-assertion\n return this.entries.at(-1)![0];\n }\n\n getChildNodeSize(tree: BTreeRead): number {\n if (this.#childNodeSize !== -1) {\n return this.#childNodeSize;\n }\n\n let sum = tree.chunkHeaderSize;\n for (const entry of this.entries) {\n sum += entry[2];\n }\n return (this.#childNodeSize = sum);\n }\n\n protected _updateNode(tree: BTreeWrite) {\n this.#childNodeSize = -1;\n tree.updateNode(\n this as NodeImpl<unknown> as DataNodeImpl | InternalNodeImpl,\n );\n }\n}\n\nexport function toChunkData<V>(\n node: NodeImpl<V>,\n formatVersion: FormatVersion,\n): BaseNode<V> {\n return makeNodeChunkData(node.level, node.entries, formatVersion);\n}\n\nexport class DataNodeImpl extends NodeImpl<FrozenJSONValue> {\n readonly level = 0;\n\n set(\n key: string,\n value: FrozenJSONValue,\n entrySize: number,\n tree: BTreeWrite,\n ): Promise<DataNodeImpl> {\n let deleteCount: number;\n const i = binarySearch(key, this.entries);\n if (!binarySearchFound(i, this.entries, key)) {\n // Not found, insert.\n deleteCount = 0;\n } else {\n deleteCount = 1;\n }\n\n return Promise.resolve(\n this.#splice(tree, i, deleteCount, [key, value, entrySize]),\n );\n }\n\n putMany(\n entries: ReadonlyArray<Entry<FrozenJSONValue>>,\n tree: BTreeWrite,\n ): Promise<DataNodeImpl> {\n if (entries.length === 0) {\n return Promise.resolve(this);\n }\n\n // Merge sorted entries with existing entries\n const merged: Entry<FrozenJSONValue>[] = [];\n let i = 0; // index in this.entries\n let j = 0; // index in entries\n\n while (i < this.entries.length && j < entries.length) {\n const existingEntry = this.entries[i];\n const newEntry = entries[j];\n const cmp = compareUTF8(existingEntry[0], newEntry[0]);\n\n if (cmp < 0) {\n merged.push(existingEntry);\n i++;\n } else if (cmp > 0) {\n merged.push(newEntry);\n j++;\n } else {\n // Same key, new entry wins (update)\n merged.push(newEntry);\n i++;\n j++;\n }\n }\n\n // Add remaining entries\n while (i < this.entries.length) {\n merged.push(this.entries[i]);\n i++;\n }\n while (j < entries.length) {\n merged.push(entries[j]);\n j++;\n }\n\n if (this.isMutable) {\n this.entries = merged;\n this._updateNode(tree);\n return Promise.resolve(this);\n }\n\n return Promise.resolve(tree.newDataNodeImpl(merged));\n }\n\n #splice(\n tree: BTreeWrite,\n start: number,\n deleteCount: number,\n ...items: Entry<FrozenJSONValue>[]\n ): DataNodeImpl {\n if (this.isMutable) {\n this.entries.splice(start, deleteCount, ...items);\n this._updateNode(tree);\n return this;\n }\n\n const entries = readonlySplice(this.entries, start, deleteCount, ...items);\n return tree.newDataNodeImpl(entries);\n }\n\n del(key: string, tree: BTreeWrite): Promise<DataNodeImpl> {\n const i = binarySearch(key, this.entries);\n if (!binarySearchFound(i, this.entries, key)) {\n // Not found. Return this without changes.\n return Promise.resolve(this);\n }\n\n // Found. Create new node or mutate existing one.\n return Promise.resolve(this.#splice(tree, i, 1));\n }\n\n async *keys(_tree: BTreeRead): AsyncGenerator<string, void> {\n for (const entry of this.entries) {\n yield entry[0];\n }\n }\n\n async *entriesIter(\n _tree: BTreeRead,\n ): AsyncGenerator<Entry<FrozenJSONValue>, void> {\n for (const entry of this.entries) {\n yield entry;\n }\n }\n}\n\nfunction readonlySplice<T>(\n array: ReadonlyArray<T>,\n start: number,\n deleteCount: number,\n ...items: T[]\n): T[] {\n const arr = array.slice(0, start);\n for (let i = 0; i < items.length; i++) {\n arr.push(items[i]);\n }\n for (let i = start + deleteCount; i < array.length; i++) {\n arr.push(array[i]);\n }\n return arr;\n}\n\nexport class InternalNodeImpl extends NodeImpl<Hash> {\n readonly level: number;\n\n constructor(\n entries: Array<Entry<Hash>>,\n hash: Hash,\n level: number,\n isMutable: boolean,\n ) {\n super(entries, hash, isMutable);\n this.level = level;\n }\n\n async set(\n key: string,\n value: FrozenJSONValue,\n entrySize: number,\n tree: BTreeWrite,\n ): Promise<InternalNodeImpl> {\n let i = binarySearch(key, this.entries);\n if (i === this.entries.length) {\n // We are going to insert into last (right most) leaf.\n i--;\n }\n\n const childHash = this.entries[i][1];\n const oldChildNode = await tree.getNode(childHash);\n\n const childNode = await oldChildNode.set(key, value, entrySize, tree);\n\n const childNodeSize = childNode.getChildNodeSize(tree);\n if (childNodeSize > tree.maxSize || childNodeSize < tree.minSize) {\n return this.#mergeAndPartition(tree, i, childNode);\n }\n\n const newEntry = createNewInternalEntryForNode(\n childNode,\n tree.getEntrySize,\n );\n return this.#replaceChild(tree, i, newEntry);\n }\n\n async putMany(\n entries: ReadonlyArray<Entry<FrozenJSONValue>>,\n tree: BTreeWrite,\n ): Promise<InternalNodeImpl> {\n if (entries.length === 0) {\n return this;\n }\n\n // Group entries by child index\n // Since entries are sorted, we can restrict the binary search range\n const childGroups: Map<number, Entry<FrozenJSONValue>[]> = new Map();\n\n let searchStart = 0;\n for (const entry of entries) {\n const key = entry[0];\n // Binary search from searchStart to end (entries are sorted)\n let i = binarySearchFrom(key, this.entries, searchStart);\n if (i === this.entries.length) {\n // Insert into last (right most) leaf.\n i--;\n }\n searchStart = i;\n\n getOrInsertComputed(childGroups, i, newArray).push(entry);\n }\n\n // Process each affected child\n const newEntries = [...this.entries];\n const childrenToRebalance: Array<{\n index: number;\n node: DataNodeImpl | InternalNodeImpl;\n }> = [];\n\n for (const [childIndex, childEntries] of childGroups) {\n const childHash = this.entries[childIndex][1];\n const oldChildNode = await tree.getNode(childHash);\n const childNode = await oldChildNode.putMany(childEntries, tree);\n\n const childNodeSize = childNode.getChildNodeSize(tree);\n if (childNodeSize > tree.maxSize || childNodeSize < tree.minSize) {\n childrenToRebalance.push({index: childIndex, node: childNode});\n } else {\n const newEntry = createNewInternalEntryForNode(\n childNode,\n tree.getEntrySize,\n );\n newEntries[childIndex] = newEntry;\n }\n }\n\n // Handle rebalancing - merge adjacent children that need rebalancing\n // into contiguous groups and process each group as one unit.\n //\n // BUG FIX: Previously, each child was rebalanced independently R-to-L.\n // When adjacent children (e.g., indices 0 and 1) both needed rebalancing,\n // child[1] would merge with sibling[0] (the ORIGINAL), then child[0]\n // would merge with the rebalanced result at position 1, duplicating\n // child[0]'s data. The fix groups adjacent indices together.\n if (childrenToRebalance.length > 0) {\n childrenToRebalance.sort((a, b) => a.index - b.index);\n\n // Group adjacent indices into contiguous runs, each extended by one\n // sibling on either side for merge context.\n const groups: Array<{\n nodes: Map<number, DataNodeImpl | InternalNodeImpl>;\n minIndex: number;\n maxIndex: number;\n }> = [];\n\n for (const {index, node} of childrenToRebalance) {\n const lastGroup = groups.at(-1);\n // Adjacent to previous group? (within 1 index of the last group's max)\n if (lastGroup && index <= lastGroup.maxIndex + 1) {\n lastGroup.nodes.set(index, node);\n lastGroup.maxIndex = index;\n } else {\n groups.push({\n nodes: new Map([[index, node]]),\n minIndex: index,\n maxIndex: index,\n });\n }\n }\n\n // Process groups from right to left to maintain indices during splices.\n for (let g = groups.length - 1; g >= 0; g--) {\n const group = groups[g];\n\n // Extend range by one sibling on each side for merge context.\n const startIndex = Math.max(0, group.minIndex - 1);\n const endIndex = Math.min(newEntries.length - 1, group.maxIndex + 1);\n const removeCount = endIndex - startIndex + 1;\n\n // Collect all entries from the range: use the putMany result for\n // indices that were rebalanced, the current newEntries node otherwise.\n type IterableHashEntries = Iterable<Entry<Hash>>;\n const allValues: IterableHashEntries[] = [];\n for (let idx = startIndex; idx <= endIndex; idx++) {\n const rebalancedNode = group.nodes.get(idx);\n if (rebalancedNode) {\n allValues.push(rebalancedNode.entries as IterableHashEntries);\n } else {\n const hash = newEntries[idx][1];\n const existingNode = await tree.getNode(hash);\n allValues.push(existingNode.entries as IterableHashEntries);\n }\n }\n\n const level = this.level - 1;\n const merged = joinIterables(...allValues);\n const rebalanced = partition(\n merged,\n e => e[2],\n tree.minSize - tree.chunkHeaderSize,\n tree.maxSize - tree.chunkHeaderSize,\n entries => {\n const node = tree.newNodeImpl(entries, level);\n return createNewInternalEntryForNode(node, tree.getEntrySize);\n },\n );\n\n newEntries.splice(startIndex, removeCount, ...rebalanced);\n }\n }\n\n if (this.isMutable) {\n this.entries = newEntries;\n this._updateNode(tree);\n return this;\n }\n\n return tree.newInternalNodeImpl(newEntries, this.level);\n }\n\n /**\n * This merges the child node entries with previous or next sibling and then\n * partitions the merged entries.\n */\n async #mergeAndPartition(\n tree: BTreeWrite,\n i: number,\n childNode: DataNodeImpl | InternalNodeImpl,\n ): Promise<InternalNodeImpl> {\n const level = this.level - 1;\n const thisEntries = this.entries;\n\n type IterableHashEntries = Iterable<Entry<Hash>>;\n\n let values: IterableHashEntries;\n let startIndex: number;\n let removeCount: number;\n if (i > 0) {\n const hash = thisEntries[i - 1][1];\n const previousSibling = await tree.getNode(hash);\n values = joinIterables(\n previousSibling.entries as IterableHashEntries,\n childNode.entries as IterableHashEntries,\n );\n startIndex = i - 1;\n removeCount = 2;\n } else if (i < thisEntries.length - 1) {\n const hash = thisEntries[i + 1][1];\n const nextSibling = await tree.getNode(hash);\n values = joinIterables(\n childNode.entries as IterableHashEntries,\n nextSibling.entries as IterableHashEntries,\n );\n startIndex = i;\n removeCount = 2;\n } else {\n values = childNode.entries as IterableHashEntries;\n startIndex = i;\n removeCount = 1;\n }\n\n const newEntries = partition(\n values,\n value => value[2],\n tree.minSize - tree.chunkHeaderSize,\n tree.maxSize - tree.chunkHeaderSize,\n entries => {\n const node = tree.newNodeImpl(entries, level);\n return createNewInternalEntryForNode(node, tree.getEntrySize);\n },\n );\n\n if (this.isMutable) {\n this.entries.splice(startIndex, removeCount, ...newEntries);\n this._updateNode(tree);\n return this;\n }\n\n const entries = readonlySplice(\n thisEntries,\n startIndex,\n removeCount,\n ...newEntries,\n );\n\n return tree.newInternalNodeImpl(entries, this.level);\n }\n\n #replaceChild(\n tree: BTreeWrite,\n index: number,\n newEntry: Entry<Hash>,\n ): InternalNodeImpl {\n if (this.isMutable) {\n this.entries.splice(index, 1, newEntry);\n this._updateNode(tree);\n return this;\n }\n const entries = readonlySplice(this.entries, index, 1, newEntry);\n return tree.newInternalNodeImpl(entries, this.level);\n }\n\n async del(\n key: string,\n tree: BTreeWrite,\n ): Promise<InternalNodeImpl | DataNodeImpl> {\n const i = binarySearch(key, this.entries);\n if (i === this.entries.length) {\n // Key is larger than maxKey of rightmost entry so it is not present.\n return this;\n }\n\n const childHash = this.entries[i][1];\n const oldChildNode = await tree.getNode(childHash);\n const oldHash = oldChildNode.hash;\n\n const childNode = await oldChildNode.del(key, tree);\n if (childNode.hash === oldHash) {\n // Not changed so not found.\n return this;\n }\n\n if (childNode.entries.length === 0) {\n // Subtree is now empty. Remove internal node.\n const entries = readonlySplice(this.entries, i, 1);\n return tree.newInternalNodeImpl(entries, this.level);\n }\n\n if (i === 0 && this.entries.length === 1) {\n // There was only one node at this level and it was removed. We can return\n // the modified subtree.\n return childNode;\n }\n\n // The child node is still a good size.\n if (childNode.getChildNodeSize(tree) > tree.minSize) {\n // No merging needed.\n const entry = createNewInternalEntryForNode(childNode, tree.getEntrySize);\n return this.#replaceChild(tree, i, entry);\n }\n\n // Child node size is too small.\n return this.#mergeAndPartition(tree, i, childNode);\n }\n\n async *keys(tree: BTreeRead): AsyncGenerator<string, void> {\n for (const entry of this.entries) {\n const childNode = await tree.getNode(entry[1]);\n yield* childNode.keys(tree);\n }\n }\n\n async *entriesIter(\n tree: BTreeRead,\n ): AsyncGenerator<Entry<FrozenJSONValue>, void> {\n for (const entry of this.entries) {\n const childNode = await tree.getNode(entry[1]);\n yield* childNode.entriesIter(tree);\n }\n }\n\n getChildren(\n start: number,\n length: number,\n tree: BTreeRead,\n ): Promise<Array<InternalNodeImpl | DataNodeImpl>> {\n const ps: Promise<DataNodeImpl | InternalNodeImpl>[] = [];\n for (let i = start; i < length && i < this.entries.length; i++) {\n ps.push(tree.getNode(this.entries[i][1]));\n }\n return Promise.all(ps);\n }\n\n async getCompositeChildren(\n start: number,\n length: number,\n tree: BTreeRead,\n ): Promise<InternalNodeImpl | DataNodeImpl> {\n const {level} = this;\n\n if (length === 0) {\n return new InternalNodeImpl([], newRandomHash(), level - 1, true);\n }\n\n const output = await this.getChildren(start, start + length, tree);\n\n if (level > 1) {\n const entries: Entry<Hash>[] = [];\n for (const child of output as InternalNodeImpl[]) {\n entries.push(...child.entries);\n }\n return new InternalNodeImpl(entries, newRandomHash(), level - 1, true);\n }\n\n assert(level === 1, 'Expected level to be 1');\n const entries: Entry<FrozenJSONValue>[] = [];\n for (const child of output as DataNodeImpl[]) {\n entries.push(...child.entries);\n }\n return new DataNodeImpl(entries, newRandomHash(), true);\n }\n}\n\nexport function newNodeImpl(\n entries: Array<Entry<FrozenJSONValue>>,\n hash: Hash,\n level: number,\n isMutable: boolean,\n): DataNodeImpl;\nexport function newNodeImpl(\n entries: Array<Entry<Hash>>,\n hash: Hash,\n level: number,\n isMutable: boolean,\n): InternalNodeImpl;\nexport function newNodeImpl(\n entries: Array<Entry<FrozenJSONValue>> | Array<Entry<Hash>>,\n hash: Hash,\n level: number,\n isMutable: boolean,\n): DataNodeImpl | InternalNodeImpl;\nexport function newNodeImpl(\n entries: Array<Entry<FrozenJSONValue>> | Array<Entry<Hash>>,\n hash: Hash,\n level: number,\n isMutable: boolean,\n): DataNodeImpl | InternalNodeImpl {\n if (level === 0) {\n return new DataNodeImpl(\n entries as Entry<FrozenJSONValue>[],\n hash,\n isMutable,\n );\n }\n return new InternalNodeImpl(entries as Entry<Hash>[], hash, level, isMutable);\n}\n\nexport function isDataNodeImpl(\n node: DataNodeImpl | InternalNodeImpl,\n): node is DataNodeImpl {\n return node.level === 0;\n}\n\nexport function partition<T, R>(\n values: Iterable<T>,\n // This is the size of each Entry\n getSizeOfEntry: (v: T) => number,\n min: number,\n max: number,\n create: (entries: T[]) => R,\n): R[] {\n const results: R[] = [];\n let sum = 0;\n let accum: T[] = [];\n // The most recently finalized partition, held back until we know it won't be\n // merged with trailing entries.\n let lastPartition: T[] | null = null;\n let lastSize = 0;\n\n function commitLast() {\n if (lastPartition !== null) {\n results.push(create(lastPartition));\n lastPartition = null;\n }\n }\n\n for (const value of values) {\n const size = getSizeOfEntry(value);\n if (size >= max) {\n if (accum.length > 0) {\n commitLast();\n lastPartition = accum;\n lastSize = sum;\n accum = [];\n sum = 0;\n }\n commitLast();\n lastPartition = [value];\n lastSize = size;\n } else if (sum + size >= min) {\n accum.push(value);\n commitLast();\n lastPartition = accum;\n lastSize = sum + size;\n accum = [];\n sum = 0;\n } else {\n sum += size;\n accum.push(value);\n }\n }\n\n if (sum > 0) {\n if (lastPartition !== null && sum + lastSize <= max) {\n lastPartition.push(...accum);\n commitLast();\n } else {\n commitLast();\n results.push(create(accum));\n }\n } else {\n commitLast();\n }\n\n return results;\n}\n\nexport const emptyDataNode = makeNodeChunkData<ReadonlyJSONValue>(\n 0,\n [],\n FormatVersion.Latest,\n);\nexport const emptyDataNodeImpl = new DataNodeImpl([], emptyHash, false);\n\nexport function createNewInternalEntryForNode(\n node: NodeImpl<unknown>,\n getSizeOfEntry: <K, V>(k: K, v: V) => number,\n): [string, Hash, number] {\n const key = node.maxKey();\n const value = node.hash;\n const size = getSizeOfEntry(key, value);\n return [key, value, size];\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connection-loop.d.ts","sourceRoot":"","sources":["../../../../replicache/src/connection-loop.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"connection-loop.d.ts","sourceRoot":"","sources":["../../../../replicache/src/connection-loop.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,kBAAkB,CAAC;AACjD,OAAO,KAAK,EAAC,yBAAyB,EAAC,MAAM,sCAAsC,CAAC;AAIpF,eAAO,MAAM,iBAAiB,KAAK,CAAC;AAEpC,eAAO,MAAM,YAAY,KAAK,CAAC;AAC/B,eAAO,MAAM,YAAY,QAAS,CAAC;AAInC,MAAM,WAAW,sBAAsB;IACrC,UAAU,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/B,aAAa,EAAE,MAAM,CAAC;IAEtB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,qBAAa,cAAc;;IA0DzB,YACE,EAAE,EAAE,UAAU,EACd,QAAQ,EAAE,sBAAsB,EAChC,iBAAiB,CAAC,EAAE,yBAAyB,EAM9C;IAED,KAAK,IAAI,IAAI,CAMZ;IAED;;;;OAIG;IACG,IAAI,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,SAAS,GAAG;QAAC,KAAK,EAAE,OAAO,CAAA;KAAC,CAAC,CAiB9D;IAEK,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC,CA8HzB;CAiBF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connection-loop.js","names":[],"sources":["../../../../replicache/src/connection-loop.ts"],"sourcesContent":["import type {LogContext} from '@rocicorp/logger';\nimport {resolver} from '@rocicorp/resolver';\nimport type {DocumentVisibilityWatcher} from '../../shared/src/document-visible.ts';\nimport {sleep} from '../../shared/src/sleep.ts';\n\nexport const DEBOUNCE_DELAY_MS = 10;\n\nexport const MIN_DELAY_MS = 30;\nexport const MAX_DELAY_MS = 60_000;\n\ntype SendRecord = {duration: number; ok: boolean};\n\nexport interface ConnectionLoopDelegate {\n invokeSend(): Promise<boolean>;\n debounceDelay: number;\n // If null, no watchdog timer is used.\n watchdogTimer: number | null;\n maxConnections: number;\n maxDelayMs: number;\n minDelayMs: number;\n}\n\nexport class ConnectionLoop {\n // ConnectionLoop runs a loop sending network requests (either pushes or\n // pulls) to the server. Our goal, generally, is to send requests as fast as\n // we can, but to adjust in case of slowness, network errors, etc. We will\n // send requests in parallel if the server supports it. We also debounce\n // pushes since they frequently happen in series very near to one another\n // (e.g., during drag'n drops).\n //\n // The loop flows through the following states forever, until it is closed:\n //\n // Pending: Wait for event or watchdog\n // |\n // v\n // Debounce: Wait for more events (we debounce pushes)\n // |\n // v\n // Wait for available connection (we limit number of parallel requests\n // allowed)\n // |\n // v\n // Wait to send (if requests are taking too long, we will slow down)\n // |\n // v\n // Send (asynchronously, wrt the loop)\n // |\n // v\n // Back to the pending!\n\n // Controls whether the next iteration of the loop will wait at the pending\n // state.\n #pendingResolver = resolver<void>();\n\n /**\n * This resolver is used to allow us to skip sleeps when we do send(true)\n */\n #skipSleepsResolver = resolver<void>();\n\n /**\n * Resolver for the next send. Never rejects. Returns an error instead since\n * this resolver is used in cases where they might not be someone waiting,\n * and we don't want an unhandled promise rejection in that case.\n */\n #sendResolver = resolver<undefined | {error: unknown}>();\n\n readonly #delegate: ConnectionLoopDelegate;\n #closed = false;\n #abortSignal = new AbortController();\n\n /**\n * Number of pending send calls.\n *\n * We keep track of this because if close happens while we are waiting for the\n * send to resolve we should reject the send promise.\n */\n #sendCounter = 0;\n readonly #lc: LogContext;\n readonly #visibilityWatcher: DocumentVisibilityWatcher | undefined;\n\n constructor(\n lc: LogContext,\n delegate: ConnectionLoopDelegate,\n visibilityWatcher?: DocumentVisibilityWatcher,\n ) {\n this.#lc = lc;\n this.#delegate = delegate;\n this.#visibilityWatcher = visibilityWatcher;\n void this.run();\n }\n\n close(): void {\n this.#closed = true;\n this.#abortSignal.abort();\n if (this.#sendCounter > 0) {\n this.#sendResolver.resolve({error: closeError()});\n }\n }\n\n /**\n *\n * @returns Returns undefined if ok, otherwise it return the error that caused\n * the send to fail.\n */\n async send(now: boolean): Promise<undefined | {error: unknown}> {\n if (this.#closed) {\n return {error: closeError()};\n }\n this.#sendCounter++;\n this.#lc.debug?.('send', now);\n if (now) {\n this.#skipSleepsResolver.resolve();\n } else {\n await this.#visibilityWatcher?.waitForVisible();\n }\n\n this.#pendingResolver.resolve();\n\n const result = await this.#sendResolver.promise;\n this.#sendCounter--;\n return result;\n }\n\n async run(): Promise<void> {\n const sendRecords: SendRecord[] = [];\n\n let recoverResolver = resolver();\n let lastSendTime;\n\n // The number of active connections.\n let counter = 0;\n const delegate = this.#delegate;\n const lc = this.#lc;\n let delay = 0;\n\n lc.debug?.('Starting connection loop');\n\n const sleepMaybeSkip: typeof sleep = ms =>\n Promise.race([this.#skipSleepsResolver.promise, sleep(ms)]);\n\n while (!this.#closed) {\n lc.debug?.(\n didLastSendRequestFail(sendRecords)\n ? 'Last request failed. Trying again'\n : 'Waiting for a send',\n );\n\n // Wait until send is called or until the watchdog timer fires.\n const races = [this.#pendingResolver.promise];\n const t = delegate.watchdogTimer;\n if (t !== null) {\n // Wait for the watchdog timer to fire or the abort signal to be triggered.\n races.push(sleep(t, this.#abortSignal.signal).catch(() => {}));\n }\n await Promise.race(races);\n if (this.#closed) break;\n\n lc.debug?.('Waiting for debounce');\n await sleepMaybeSkip(delegate.debounceDelay);\n if (this.#closed) break;\n lc.debug?.('debounced');\n\n // This resolver is used to wait for incoming push calls.\n this.#pendingResolver = resolver();\n\n if (counter >= delegate.maxConnections) {\n lc.debug?.('Too many request in flight. Waiting until one finishes...');\n await this.#waitUntilAvailableConnection();\n if (this.#closed) break;\n lc.debug?.('...finished');\n }\n\n // We need to delay the next request even if there are no active requests\n // in case of error.\n if (counter > 0 || didLastSendRequestFail(sendRecords)) {\n delay = computeDelayAndUpdateDurations(delay, delegate, sendRecords);\n lc.debug?.(\n didLastSendRequestFail(sendRecords)\n ? 'Last connection errored. Sleeping for'\n : 'More than one outstanding connection (' +\n counter +\n '). Sleeping for',\n delay,\n 'ms',\n );\n } else {\n // We set this to 0 here in case minDelayMs is mutated to a lower value\n // than the old delay so that we still get minDelayMs. This can happen\n // if we get an error during a run where minDelayMs is larger than the\n // current value of minDelayMs.\n delay = 0;\n }\n\n const clampedDelay = Math.min(\n delegate.maxDelayMs,\n Math.max(delegate.minDelayMs, delay),\n );\n if (lastSendTime !== undefined) {\n const timeSinceLastSend = Date.now() - lastSendTime;\n if (clampedDelay > timeSinceLastSend) {\n await Promise.race([\n sleepMaybeSkip(clampedDelay - timeSinceLastSend),\n recoverResolver.promise,\n ]);\n if (this.#closed) break;\n }\n }\n\n counter++;\n void (async () => {\n const start = Date.now();\n let ok: boolean;\n let error: unknown;\n try {\n lastSendTime = start;\n lc.debug?.('Sending request');\n this.#skipSleepsResolver = resolver();\n ok = await delegate.invokeSend();\n lc.debug?.('Send returned', ok);\n } catch (e) {\n lc.debug?.('Send failed', e);\n error = e;\n ok = false;\n }\n if (this.#closed) {\n lc.debug?.('Closed after invokeSend');\n return;\n }\n lc.debug?.('Request done', {duration: Date.now() - start, ok});\n sendRecords.push({duration: Date.now() - start, ok});\n if (recovered(sendRecords)) {\n recoverResolver.resolve();\n recoverResolver = resolver();\n }\n counter--;\n this.#connectionAvailable();\n const sendResolver = this.#sendResolver;\n this.#sendResolver = resolver();\n if (error) {\n sendResolver.resolve({error});\n } else {\n sendResolver.resolve(undefined);\n }\n if (!ok) {\n // Keep trying\n this.#pendingResolver.resolve();\n }\n })();\n }\n }\n\n #waitingConnectionResolve: (() => void) | undefined = undefined;\n\n #connectionAvailable() {\n if (this.#waitingConnectionResolve) {\n const resolve = this.#waitingConnectionResolve;\n this.#waitingConnectionResolve = undefined;\n resolve();\n }\n }\n\n #waitUntilAvailableConnection() {\n const {promise, resolve} = resolver();\n this.#waitingConnectionResolve = resolve;\n return promise;\n }\n}\n\n// Number of connections to remember when computing the new delay.\nconst CONNECTION_MEMORY_COUNT = 9;\n\nfunction closeError() {\n return new Error('Closed');\n}\n\n// Computes a new delay based on the previous requests. We use the median of the\n// previous successful request divided by `maxConnections`. When we get errors\n// we do exponential backoff. As soon as we recover from an error we reset back\n// to delegate.minDelayMs.\nfunction computeDelayAndUpdateDurations(\n delay: number,\n delegate: ConnectionLoopDelegate,\n sendRecords: SendRecord[],\n): number {\n const {length} = sendRecords;\n if (length === 0) {\n return delay;\n }\n\n // oxlint-disable-next-line typescript/no-non-null-assertion\n const {ok} = sendRecords.at(-1)!;\n const {maxConnections, minDelayMs} = delegate;\n\n if (!ok) {\n return delay === 0 ? minDelayMs : delay * 2;\n }\n\n if (length > 1) {\n // length > 1\n const previous: SendRecord = sendRecords[sendRecords.length - 2];\n\n // Prune\n while (sendRecords.length > CONNECTION_MEMORY_COUNT) {\n sendRecords.shift();\n }\n\n if (ok && !previous.ok) {\n // Recovered\n return minDelayMs;\n }\n }\n\n const med = median(\n sendRecords.filter(({ok}) => ok).map(({duration}) => duration),\n );\n\n return (med / maxConnections) | 0;\n}\n\nfunction median(values: number[]) {\n values.sort();\n const {length} = values;\n const half = length >> 1;\n if (length % 2 === 1) {\n return values[half];\n }\n return (values[half - 1] + values[half]) / 2;\n}\n\nfunction didLastSendRequestFail(sendRecords: SendRecord[]) {\n // oxlint-disable-next-line typescript/no-non-null-assertion\n return sendRecords.length > 0 && !sendRecords.at(-1)!.ok;\n}\n\nfunction recovered(sendRecords: SendRecord[]) {\n return (\n sendRecords.length > 1 &&\n !sendRecords[sendRecords.length - 2].ok &&\n // oxlint-disable-next-line typescript/no-non-null-assertion\n sendRecords.at(-1)!.ok\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"connection-loop.js","names":[],"sources":["../../../../replicache/src/connection-loop.ts"],"sourcesContent":["import type {LogContext} from '@rocicorp/logger';\nimport type {DocumentVisibilityWatcher} from '../../shared/src/document-visible.ts';\nimport {resolver} from '../../shared/src/resolver.ts';\nimport {sleep} from '../../shared/src/sleep.ts';\n\nexport const DEBOUNCE_DELAY_MS = 10;\n\nexport const MIN_DELAY_MS = 30;\nexport const MAX_DELAY_MS = 60_000;\n\ntype SendRecord = {duration: number; ok: boolean};\n\nexport interface ConnectionLoopDelegate {\n invokeSend(): Promise<boolean>;\n debounceDelay: number;\n // If null, no watchdog timer is used.\n watchdogTimer: number | null;\n maxConnections: number;\n maxDelayMs: number;\n minDelayMs: number;\n}\n\nexport class ConnectionLoop {\n // ConnectionLoop runs a loop sending network requests (either pushes or\n // pulls) to the server. Our goal, generally, is to send requests as fast as\n // we can, but to adjust in case of slowness, network errors, etc. We will\n // send requests in parallel if the server supports it. We also debounce\n // pushes since they frequently happen in series very near to one another\n // (e.g., during drag'n drops).\n //\n // The loop flows through the following states forever, until it is closed:\n //\n // Pending: Wait for event or watchdog\n // |\n // v\n // Debounce: Wait for more events (we debounce pushes)\n // |\n // v\n // Wait for available connection (we limit number of parallel requests\n // allowed)\n // |\n // v\n // Wait to send (if requests are taking too long, we will slow down)\n // |\n // v\n // Send (asynchronously, wrt the loop)\n // |\n // v\n // Back to the pending!\n\n // Controls whether the next iteration of the loop will wait at the pending\n // state.\n #pendingResolver = resolver<void>();\n\n /**\n * This resolver is used to allow us to skip sleeps when we do send(true)\n */\n #skipSleepsResolver = resolver<void>();\n\n /**\n * Resolver for the next send. Never rejects. Returns an error instead since\n * this resolver is used in cases where they might not be someone waiting,\n * and we don't want an unhandled promise rejection in that case.\n */\n #sendResolver = resolver<undefined | {error: unknown}>();\n\n readonly #delegate: ConnectionLoopDelegate;\n #closed = false;\n #abortSignal = new AbortController();\n\n /**\n * Number of pending send calls.\n *\n * We keep track of this because if close happens while we are waiting for the\n * send to resolve we should reject the send promise.\n */\n #sendCounter = 0;\n readonly #lc: LogContext;\n readonly #visibilityWatcher: DocumentVisibilityWatcher | undefined;\n\n constructor(\n lc: LogContext,\n delegate: ConnectionLoopDelegate,\n visibilityWatcher?: DocumentVisibilityWatcher,\n ) {\n this.#lc = lc;\n this.#delegate = delegate;\n this.#visibilityWatcher = visibilityWatcher;\n void this.run();\n }\n\n close(): void {\n this.#closed = true;\n this.#abortSignal.abort();\n if (this.#sendCounter > 0) {\n this.#sendResolver.resolve({error: closeError()});\n }\n }\n\n /**\n *\n * @returns Returns undefined if ok, otherwise it return the error that caused\n * the send to fail.\n */\n async send(now: boolean): Promise<undefined | {error: unknown}> {\n if (this.#closed) {\n return {error: closeError()};\n }\n this.#sendCounter++;\n this.#lc.debug?.('send', now);\n if (now) {\n this.#skipSleepsResolver.resolve();\n } else {\n await this.#visibilityWatcher?.waitForVisible();\n }\n\n this.#pendingResolver.resolve();\n\n const result = await this.#sendResolver.promise;\n this.#sendCounter--;\n return result;\n }\n\n async run(): Promise<void> {\n const sendRecords: SendRecord[] = [];\n\n let recoverResolver = resolver();\n let lastSendTime;\n\n // The number of active connections.\n let counter = 0;\n const delegate = this.#delegate;\n const lc = this.#lc;\n let delay = 0;\n\n lc.debug?.('Starting connection loop');\n\n const sleepMaybeSkip: typeof sleep = ms =>\n Promise.race([this.#skipSleepsResolver.promise, sleep(ms)]);\n\n while (!this.#closed) {\n lc.debug?.(\n didLastSendRequestFail(sendRecords)\n ? 'Last request failed. Trying again'\n : 'Waiting for a send',\n );\n\n // Wait until send is called or until the watchdog timer fires.\n const races = [this.#pendingResolver.promise];\n const t = delegate.watchdogTimer;\n if (t !== null) {\n // Wait for the watchdog timer to fire or the abort signal to be triggered.\n races.push(sleep(t, this.#abortSignal.signal).catch(() => {}));\n }\n await Promise.race(races);\n if (this.#closed) break;\n\n lc.debug?.('Waiting for debounce');\n await sleepMaybeSkip(delegate.debounceDelay);\n if (this.#closed) break;\n lc.debug?.('debounced');\n\n // This resolver is used to wait for incoming push calls.\n this.#pendingResolver = resolver();\n\n if (counter >= delegate.maxConnections) {\n lc.debug?.('Too many request in flight. Waiting until one finishes...');\n await this.#waitUntilAvailableConnection();\n if (this.#closed) break;\n lc.debug?.('...finished');\n }\n\n // We need to delay the next request even if there are no active requests\n // in case of error.\n if (counter > 0 || didLastSendRequestFail(sendRecords)) {\n delay = computeDelayAndUpdateDurations(delay, delegate, sendRecords);\n lc.debug?.(\n didLastSendRequestFail(sendRecords)\n ? 'Last connection errored. Sleeping for'\n : 'More than one outstanding connection (' +\n counter +\n '). Sleeping for',\n delay,\n 'ms',\n );\n } else {\n // We set this to 0 here in case minDelayMs is mutated to a lower value\n // than the old delay so that we still get minDelayMs. This can happen\n // if we get an error during a run where minDelayMs is larger than the\n // current value of minDelayMs.\n delay = 0;\n }\n\n const clampedDelay = Math.min(\n delegate.maxDelayMs,\n Math.max(delegate.minDelayMs, delay),\n );\n if (lastSendTime !== undefined) {\n const timeSinceLastSend = Date.now() - lastSendTime;\n if (clampedDelay > timeSinceLastSend) {\n await Promise.race([\n sleepMaybeSkip(clampedDelay - timeSinceLastSend),\n recoverResolver.promise,\n ]);\n if (this.#closed) break;\n }\n }\n\n counter++;\n void (async () => {\n const start = Date.now();\n let ok: boolean;\n let error: unknown;\n try {\n lastSendTime = start;\n lc.debug?.('Sending request');\n this.#skipSleepsResolver = resolver();\n ok = await delegate.invokeSend();\n lc.debug?.('Send returned', ok);\n } catch (e) {\n lc.debug?.('Send failed', e);\n error = e;\n ok = false;\n }\n if (this.#closed) {\n lc.debug?.('Closed after invokeSend');\n return;\n }\n lc.debug?.('Request done', {duration: Date.now() - start, ok});\n sendRecords.push({duration: Date.now() - start, ok});\n if (recovered(sendRecords)) {\n recoverResolver.resolve();\n recoverResolver = resolver();\n }\n counter--;\n this.#connectionAvailable();\n const sendResolver = this.#sendResolver;\n this.#sendResolver = resolver();\n if (error) {\n sendResolver.resolve({error});\n } else {\n sendResolver.resolve(undefined);\n }\n if (!ok) {\n // Keep trying\n this.#pendingResolver.resolve();\n }\n })();\n }\n }\n\n #waitingConnectionResolve: (() => void) | undefined = undefined;\n\n #connectionAvailable() {\n if (this.#waitingConnectionResolve) {\n const resolve = this.#waitingConnectionResolve;\n this.#waitingConnectionResolve = undefined;\n resolve();\n }\n }\n\n #waitUntilAvailableConnection() {\n const {promise, resolve} = resolver();\n this.#waitingConnectionResolve = resolve;\n return promise;\n }\n}\n\n// Number of connections to remember when computing the new delay.\nconst CONNECTION_MEMORY_COUNT = 9;\n\nfunction closeError() {\n return new Error('Closed');\n}\n\n// Computes a new delay based on the previous requests. We use the median of the\n// previous successful request divided by `maxConnections`. When we get errors\n// we do exponential backoff. As soon as we recover from an error we reset back\n// to delegate.minDelayMs.\nfunction computeDelayAndUpdateDurations(\n delay: number,\n delegate: ConnectionLoopDelegate,\n sendRecords: SendRecord[],\n): number {\n const {length} = sendRecords;\n if (length === 0) {\n return delay;\n }\n\n // oxlint-disable-next-line typescript/no-non-null-assertion\n const {ok} = sendRecords.at(-1)!;\n const {maxConnections, minDelayMs} = delegate;\n\n if (!ok) {\n return delay === 0 ? minDelayMs : delay * 2;\n }\n\n if (length > 1) {\n // length > 1\n const previous: SendRecord = sendRecords[sendRecords.length - 2];\n\n // Prune\n while (sendRecords.length > CONNECTION_MEMORY_COUNT) {\n sendRecords.shift();\n }\n\n if (ok && !previous.ok) {\n // Recovered\n return minDelayMs;\n }\n }\n\n const med = median(\n sendRecords.filter(({ok}) => ok).map(({duration}) => duration),\n );\n\n return (med / maxConnections) | 0;\n}\n\nfunction median(values: number[]) {\n values.sort();\n const {length} = values;\n const half = length >> 1;\n if (length % 2 === 1) {\n return values[half];\n }\n return (values[half - 1] + values[half]) / 2;\n}\n\nfunction didLastSendRequestFail(sendRecords: SendRecord[]) {\n // oxlint-disable-next-line typescript/no-non-null-assertion\n return sendRecords.length > 0 && !sendRecords.at(-1)!.ok;\n}\n\nfunction recovered(sendRecords: SendRecord[]) {\n return (\n sendRecords.length > 1 &&\n !sendRecords[sendRecords.length - 2].ok &&\n // oxlint-disable-next-line typescript/no-non-null-assertion\n sendRecords.at(-1)!.ok\n );\n}\n"],"mappings":"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"}
|
|
@@ -100,5 +100,4 @@ export type CommitData<M extends Meta> = FrozenTag<{
|
|
|
100
100
|
readonly indexes: readonly IndexRecord[];
|
|
101
101
|
}>;
|
|
102
102
|
export declare function makeCommitData<M extends Meta>(meta: M, valueHash: Hash, indexes: readonly IndexRecord[]): CommitData<M>;
|
|
103
|
-
export declare function assertCommitData(v: unknown): asserts v is CommitData<Meta>;
|
|
104
103
|
//# sourceMappingURL=commit.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"commit.d.ts","sourceRoot":"","sources":["../../../../../replicache/src/db/commit.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"commit.d.ts","sourceRoot":"","sources":["../../../../../replicache/src/db/commit.ts"],"names":[],"mappings":"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"}
|
|
@@ -278,6 +278,6 @@ function validateChunk(chunk) {
|
|
|
278
278
|
}
|
|
279
279
|
}
|
|
280
280
|
//#endregion
|
|
281
|
-
export { Commit, DEFAULT_HEAD_NAME,
|
|
281
|
+
export { Commit, DEFAULT_HEAD_NAME, assertLocalMetaDD31, assertSnapshotCommitDD31, assertSnapshotMetaDD31, baseSnapshotFromCommit, baseSnapshotFromHash, baseSnapshotFromHead, baseSnapshotHashFromHash, commitChain, commitFromHash, commitFromHead, commitIsLocal, commitIsLocalDD31, commitIsSnapshot, compareCookiesForSnapshots, fromChunk, getMutationID, getRefs, isLocalMetaDD31, localMutations, localMutationsDD31, localMutationsGreaterThan, makeCommitData, newLocalDD31, newSnapshotCommitDataDD31, newSnapshotDD31, snapshotMetaParts, toChunkIndexDefinition };
|
|
282
282
|
|
|
283
283
|
//# sourceMappingURL=commit.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"commit.js","names":["skipCommitDataAsserts"],"sources":["../../../../../replicache/src/db/commit.ts"],"sourcesContent":["import {\n assert,\n assertArray,\n assertBoolean,\n assertNumber,\n assertObject,\n assertString,\n unreachable,\n} from '../../../shared/src/asserts.ts';\nimport {assertJSONValue} from '../../../shared/src/json.ts';\nimport {skipCommitDataAsserts} from '../config.ts';\nimport {type FrozenCookie, compareCookies} from '../cookies.ts';\nimport {type Chunk, type CreateChunk, type Refs, toRefs} from '../dag/chunk.ts';\nimport {type MustGetChunk, type Read, mustGetHeadHash} from '../dag/store.ts';\nimport {\n type FrozenJSONValue,\n type FrozenTag,\n assertDeepFrozen,\n deepFreeze,\n} from '../frozen-json.ts';\nimport {type Hash, assertHash} from '../hash.ts';\nimport type {IndexDefinition} from '../index-defs.ts';\nimport type {ClientID} from '../sync/ids.ts';\nimport * as MetaType from './meta-type-enum.ts';\n\nexport const DEFAULT_HEAD_NAME = 'main';\n\nexport function commitIsLocalDD31(\n commit: Commit<Meta>,\n): commit is Commit<LocalMetaDD31> {\n return isLocalMetaDD31(commit.meta);\n}\n\nexport function commitIsLocal(\n commit: Commit<Meta>,\n): commit is Commit<LocalMetaDD31> {\n return commitIsLocalDD31(commit);\n}\n\nexport function commitIsSnapshot(\n commit: Commit<Meta>,\n): commit is Commit<SnapshotMetaDD31> {\n return isSnapshotMetaDD31(commit.meta);\n}\n\nexport class Commit<M extends Meta> {\n readonly chunk: Chunk<CommitData<M>>;\n\n constructor(chunk: Chunk<CommitData<M>>) {\n this.chunk = chunk;\n }\n\n get meta(): M {\n return this.chunk.data.meta;\n }\n\n get valueHash(): Hash {\n // Already validated!\n return this.chunk.data.valueHash;\n }\n\n getMutationID(clientID: ClientID, dagRead: MustGetChunk): Promise<number> {\n return getMutationID(clientID, dagRead, this.meta);\n }\n\n async getNextMutationID(\n clientID: ClientID,\n dagRead: MustGetChunk,\n ): Promise<number> {\n return (await this.getMutationID(clientID, dagRead)) + 1;\n }\n\n get indexes(): readonly IndexRecord[] {\n // Already validated!\n return this.chunk.data.indexes;\n }\n}\n\nexport async function getMutationID(\n clientID: ClientID,\n dagRead: MustGetChunk,\n meta: Meta,\n): Promise<number> {\n switch (meta.type) {\n case MetaType.SnapshotDD31:\n return meta.lastMutationIDs[clientID] ?? 0;\n\n case MetaType.LocalDD31: {\n if (meta.clientID === clientID) {\n return meta.mutationID;\n }\n const {basisHash} = meta;\n const basisCommit = await commitFromHash(basisHash, dagRead);\n return getMutationID(clientID, dagRead, basisCommit.meta);\n }\n\n default:\n unreachable(meta);\n }\n}\n\n/**\n * Returns the set of local commits from the given `fromCommitHash` back to but not\n * including its base snapshot. If `fromCommitHash` is a snapshot, the returned vector\n * will be empty. When, as typical, `fromCommitHash` is the head of the default chain\n * then the returned commits are the set of pending commits, ie the set of local commits\n * that have not yet been pushed to the data layer.\n *\n * The vector of commits is returned in reverse chain order, that is, starting\n * with the commit with hash `fromCommitHash` and walking backwards.\n */\nexport async function localMutations(\n fromCommitHash: Hash,\n dagRead: Read,\n): Promise<Commit<LocalMetaDD31>[]> {\n const commits = await commitChain(fromCommitHash, dagRead);\n // Filter does not deal with type narrowing.\n return commits.filter(c => commitIsLocal(c)) as Commit<LocalMetaDD31>[];\n}\n\nexport async function localMutationsDD31(\n fromCommitHash: Hash,\n dagRead: Read,\n): Promise<Commit<LocalMetaDD31>[]> {\n const commits = await commitChain(fromCommitHash, dagRead);\n // Filter does not deal with type narrowing.\n return commits.filter(c => commitIsLocalDD31(c)) as Commit<LocalMetaDD31>[];\n}\n\nexport async function localMutationsGreaterThan(\n commit: Commit<Meta>,\n mutationIDLimits: Record<ClientID, number>,\n dagRead: Read,\n): Promise<Commit<LocalMetaDD31>[]> {\n const commits: Commit<LocalMetaDD31>[] = [];\n const remainingMutationIDLimits = new Map(Object.entries(mutationIDLimits));\n while (!commitIsSnapshot(commit) && remainingMutationIDLimits.size > 0) {\n if (commitIsLocalDD31(commit)) {\n const {meta} = commit;\n const mutationIDLowerLimit = remainingMutationIDLimits.get(meta.clientID);\n if (mutationIDLowerLimit !== undefined) {\n if (meta.mutationID <= mutationIDLowerLimit) {\n remainingMutationIDLimits.delete(meta.clientID);\n } else {\n commits.push(commit as Commit<LocalMetaDD31>);\n }\n }\n }\n const {basisHash} = commit.meta;\n if (basisHash === null) {\n throw new Error(`Commit ${commit.chunk.hash} has no basis`);\n }\n commit = await commitFromHash(basisHash, dagRead);\n }\n return commits;\n}\n\nexport async function baseSnapshotFromHead(\n name: string,\n dagRead: Read,\n): Promise<Commit<SnapshotMetaDD31>> {\n const hash = await dagRead.getHead(name);\n assert(hash, `Missing head ${name}`);\n return baseSnapshotFromHash(hash, dagRead);\n}\n\nexport async function baseSnapshotHashFromHash(\n hash: Hash,\n dagRead: Read,\n): Promise<Hash> {\n return (await baseSnapshotFromHash(hash, dagRead)).chunk.hash;\n}\n\nexport async function baseSnapshotFromHash(\n hash: Hash,\n dagRead: Read,\n): Promise<Commit<SnapshotMetaDD31>> {\n const commit = await commitFromHash(hash, dagRead);\n return baseSnapshotFromCommit(commit, dagRead);\n}\n\nexport async function baseSnapshotFromCommit(\n commit: Commit<Meta>,\n dagRead: Read,\n): Promise<Commit<SnapshotMetaDD31>> {\n while (!commitIsSnapshot(commit)) {\n const {meta} = commit;\n if (isLocalMetaDD31(meta)) {\n commit = await commitFromHash(meta.baseSnapshotHash, dagRead);\n } else {\n const {basisHash} = meta;\n if (basisHash === null) {\n throw new Error(`Commit ${commit.chunk.hash} has no basis`);\n }\n commit = await commitFromHash(basisHash, dagRead);\n }\n }\n return commit;\n}\n\nexport function snapshotMetaParts(\n c: Commit<SnapshotMetaDD31>,\n clientID: ClientID,\n): [lastMutationID: number, cookie: FrozenCookie | FrozenJSONValue] {\n const m = c.meta;\n const lmid = m.lastMutationIDs[clientID] ?? 0;\n return [lmid, m.cookieJSON];\n}\n\nexport function compareCookiesForSnapshots(\n a: Commit<SnapshotMetaDD31>,\n b: Commit<SnapshotMetaDD31>,\n): number {\n return compareCookies(a.meta.cookieJSON, b.meta.cookieJSON);\n}\n\n/**\n * Returns all commits from the commit with fromCommitHash to its base snapshot,\n * inclusive of both. Resulting vector is in chain-head-first order (so snapshot\n * comes last).\n */\nexport async function commitChain(\n fromCommitHash: Hash,\n dagRead: Read,\n): Promise<Commit<Meta>[]> {\n let commit = await commitFromHash(fromCommitHash, dagRead);\n const commits = [];\n while (!commitIsSnapshot(commit)) {\n const {meta} = commit;\n const {basisHash} = meta;\n if (basisHash === null) {\n throw new Error(`Commit ${commit.chunk.hash} has no basis`);\n }\n commits.push(commit);\n commit = await commitFromHash(basisHash, dagRead);\n }\n commits.push(commit);\n return commits;\n}\n\nexport async function commitFromHash(\n hash: Hash,\n dagRead: MustGetChunk,\n): Promise<Commit<Meta>> {\n const chunk = await dagRead.mustGetChunk(hash);\n return fromChunk(chunk);\n}\n\nexport async function commitFromHead(\n name: string,\n dagRead: Read,\n): Promise<Commit<Meta>> {\n const hash = await mustGetHeadHash(name, dagRead);\n return commitFromHash(hash, dagRead);\n}\n\nexport type LocalMetaDD31 = {\n readonly type: MetaType.LocalDD31;\n readonly basisHash: Hash;\n readonly mutationID: number;\n readonly mutatorName: string;\n readonly mutatorArgsJSON: FrozenJSONValue;\n readonly originalHash: Hash | null;\n readonly timestamp: number;\n readonly clientID: ClientID;\n readonly baseSnapshotHash: Hash;\n};\n\nexport type LocalMeta = LocalMetaDD31;\n\nexport function assertLocalMetaDD31(\n v: Record<string, unknown>,\n): asserts v is LocalMetaDD31 {\n // type already asserted\n assertString(v.clientID);\n assertNumber(v.mutationID);\n assertString(v.mutatorName);\n if (!v.mutatorName) {\n throw new Error('Missing mutator name');\n }\n assertJSONValue(v.mutatorArgsJSON);\n if (v.originalHash !== null) {\n assertHash(v.originalHash);\n }\n assertNumber(v.timestamp);\n}\n\nexport function isLocalMetaDD31(meta: Meta): meta is LocalMetaDD31 {\n return meta.type === MetaType.LocalDD31;\n}\n\nexport function assertLocalCommitDD31(\n c: Commit<Meta>,\n): asserts c is Commit<LocalMetaDD31> {\n assertLocalMetaDD31(c.meta);\n}\n\nexport type SnapshotMetaDD31 = {\n readonly type: MetaType.SnapshotDD31;\n readonly basisHash: Hash | null;\n readonly lastMutationIDs: Record<ClientID, number>;\n readonly cookieJSON: FrozenCookie;\n};\n\nexport type SnapshotMeta = SnapshotMetaDD31;\n\nexport function assertSnapshotMetaDD31(\n v: Record<string, unknown>,\n): asserts v is SnapshotMetaDD31 {\n // type already asserted\n if (v.basisHash !== null) {\n assertHash(v.basisHash);\n }\n assertJSONValue(v.cookieJSON);\n assertLastMutationIDs(v.lastMutationIDs);\n}\n\nfunction assertLastMutationIDs(\n v: unknown,\n): asserts v is Record<ClientID, number> {\n assertObject(v);\n for (const e of Object.values(v)) {\n assertNumber(e);\n }\n}\n\nexport type Meta = LocalMetaDD31 | SnapshotMetaDD31;\n\nexport function assertSnapshotCommitDD31(\n c: Commit<Meta>,\n): asserts c is Commit<SnapshotMetaDD31> {\n assertSnapshotMetaDD31(c.meta);\n}\n\nfunction isSnapshotMetaDD31(meta: Meta): meta is SnapshotMetaDD31 {\n return meta.type === MetaType.SnapshotDD31;\n}\n\nfunction assertMeta(v: unknown): asserts v is Meta {\n assertObject(v);\n assertDeepFrozen(v);\n if (v.basisHash !== null) {\n assertString(v.basisHash);\n }\n\n assertNumber(v.type);\n switch (v.type) {\n case MetaType.LocalDD31:\n assertLocalMetaDD31(v);\n break;\n case MetaType.SnapshotDD31:\n assertSnapshotMetaDD31(v);\n break;\n default:\n throw new Error(`Invalid enum value ${v.type}`);\n }\n}\n\n/**\n * This is the type used for index definitions as defined in the Commit chunk data.\n *\n * Changing this requires a REPLICACHE_FORMAT_VERSION bump.\n */\nexport type ChunkIndexDefinition = {\n readonly name: string;\n readonly keyPrefix: string;\n readonly jsonPointer: string;\n // Used to not exist\n readonly allowEmpty?: boolean;\n};\n\nexport function chunkIndexDefinitionEqualIgnoreName(\n a: ChunkIndexDefinition,\n b: ChunkIndexDefinition,\n): boolean {\n return (\n a.jsonPointer === b.jsonPointer &&\n (a.allowEmpty ?? false) === (b.allowEmpty ?? false) &&\n a.keyPrefix === b.keyPrefix\n );\n}\n\nfunction assertChunkIndexDefinition(\n v: unknown,\n): asserts v is ChunkIndexDefinition {\n assertObject(v);\n assertDeepFrozen(v);\n assertString(v.name);\n assertString(v.keyPrefix);\n assertString(v.jsonPointer);\n if (v.allowEmpty !== undefined) {\n assertBoolean(v.allowEmpty);\n }\n}\n\nexport function toChunkIndexDefinition(\n name: string,\n indexDefinition: IndexDefinition,\n): Required<ChunkIndexDefinition> {\n return {\n name,\n keyPrefix: indexDefinition.prefix ?? '',\n jsonPointer: indexDefinition.jsonPointer,\n allowEmpty: indexDefinition.allowEmpty ?? false,\n };\n}\n\nexport type IndexRecord = {\n readonly definition: ChunkIndexDefinition;\n readonly valueHash: Hash;\n};\n\nfunction assertIndexRecord(v: unknown): asserts v is IndexRecord {\n assertObject(v);\n assertDeepFrozen(v);\n assertChunkIndexDefinition(v.definition);\n assertString(v.valueHash);\n}\n\nfunction assertIndexRecords(v: unknown): asserts v is IndexRecord[] {\n assertArray(v);\n assertDeepFrozen(v);\n for (const ir of v) {\n assertIndexRecord(ir);\n }\n}\n\nexport function newLocalDD31(\n createChunk: CreateChunk,\n basisHash: Hash,\n baseSnapshotHash: Hash,\n mutationID: number,\n mutatorName: string,\n mutatorArgsJSON: FrozenJSONValue,\n originalHash: Hash | null,\n valueHash: Hash,\n indexes: readonly IndexRecord[],\n timestamp: number,\n clientID: ClientID,\n): Commit<LocalMetaDD31> {\n const meta: LocalMetaDD31 = {\n type: MetaType.LocalDD31,\n basisHash,\n baseSnapshotHash,\n mutationID,\n mutatorName,\n mutatorArgsJSON,\n originalHash,\n timestamp,\n clientID,\n };\n return commitFromCommitData(\n createChunk,\n makeCommitData(meta, valueHash, indexes),\n );\n}\n\nexport function newSnapshotDD31(\n createChunk: CreateChunk,\n basisHash: Hash | null,\n lastMutationIDs: Record<ClientID, number>,\n cookieJSON: FrozenCookie,\n valueHash: Hash,\n indexes: readonly IndexRecord[],\n): Commit<SnapshotMetaDD31> {\n return commitFromCommitData(\n createChunk,\n newSnapshotCommitDataDD31(\n basisHash,\n lastMutationIDs,\n cookieJSON,\n valueHash,\n indexes,\n ),\n );\n}\n\nexport function newSnapshotCommitDataDD31(\n basisHash: Hash | null,\n lastMutationIDs: Record<ClientID, number>,\n cookieJSON: FrozenCookie,\n valueHash: Hash,\n indexes: readonly IndexRecord[],\n): CommitData<SnapshotMetaDD31> {\n const meta: SnapshotMetaDD31 = {\n type: MetaType.SnapshotDD31,\n basisHash,\n lastMutationIDs,\n cookieJSON,\n };\n return makeCommitData(meta, valueHash, indexes);\n}\n\nexport function fromChunk(chunk: Chunk): Commit<Meta> {\n validateChunk(chunk);\n return new Commit(chunk);\n}\n\nfunction commitFromCommitData<M extends Meta>(\n createChunk: CreateChunk,\n data: CommitData<M>,\n): Commit<M> {\n return new Commit(createChunk(data, getRefs(data)));\n}\n\nexport function getRefs(data: CommitData<Meta>): Refs {\n const refs: Set<Hash> = new Set();\n refs.add(data.valueHash);\n const {meta} = data;\n switch (meta.type) {\n case MetaType.LocalDD31:\n meta.basisHash && refs.add(meta.basisHash);\n // Local has weak originalHash\n break;\n case MetaType.SnapshotDD31:\n // Snapshot has weak basisHash\n break;\n default:\n unreachable(meta);\n }\n\n for (const index of data.indexes) {\n refs.add(index.valueHash);\n }\n\n return toRefs(refs);\n}\n\nexport type CommitData<M extends Meta> = FrozenTag<{\n readonly meta: M;\n readonly valueHash: Hash;\n readonly indexes: readonly IndexRecord[];\n}>;\n\nexport function makeCommitData<M extends Meta>(\n meta: M,\n valueHash: Hash,\n indexes: readonly IndexRecord[],\n): CommitData<M> {\n return deepFreeze({\n meta,\n valueHash,\n indexes,\n }) as unknown as CommitData<M>;\n}\n\nexport function assertCommitData(v: unknown): asserts v is CommitData<Meta> {\n if (skipCommitDataAsserts) {\n return;\n }\n\n assertObject(v);\n assertDeepFrozen(v);\n assertMeta(v.meta);\n assertString(v.valueHash);\n assertIndexRecords(v.indexes);\n}\n\nfunction validateChunk(chunk: Chunk): asserts chunk is Chunk<CommitData<Meta>> {\n const {data} = chunk;\n assertCommitData(data);\n\n const seen = new Set();\n for (const index of data.indexes) {\n const {name} = index.definition;\n if (seen.has(name)) {\n throw new Error(`Duplicate index ${name}`);\n }\n seen.add(name);\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"commit.js","names":["skipCommitDataAsserts"],"sources":["../../../../../replicache/src/db/commit.ts"],"sourcesContent":["import {\n assert,\n assertArray,\n assertBoolean,\n assertNumber,\n assertObject,\n assertString,\n unreachable,\n} from '../../../shared/src/asserts.ts';\nimport {assertJSONValue} from '../../../shared/src/json.ts';\nimport {skipCommitDataAsserts} from '../config.ts';\nimport {type FrozenCookie, compareCookies} from '../cookies.ts';\nimport {type Chunk, type CreateChunk, type Refs, toRefs} from '../dag/chunk.ts';\nimport {type MustGetChunk, type Read, mustGetHeadHash} from '../dag/store.ts';\nimport {\n type FrozenJSONValue,\n type FrozenTag,\n assertDeepFrozen,\n deepFreeze,\n} from '../frozen-json.ts';\nimport {type Hash, assertHash} from '../hash.ts';\nimport type {IndexDefinition} from '../index-defs.ts';\nimport type {ClientID} from '../sync/ids.ts';\nimport * as MetaType from './meta-type-enum.ts';\n\nexport const DEFAULT_HEAD_NAME = 'main';\n\nexport function commitIsLocalDD31(\n commit: Commit<Meta>,\n): commit is Commit<LocalMetaDD31> {\n return isLocalMetaDD31(commit.meta);\n}\n\nexport function commitIsLocal(\n commit: Commit<Meta>,\n): commit is Commit<LocalMetaDD31> {\n return commitIsLocalDD31(commit);\n}\n\nexport function commitIsSnapshot(\n commit: Commit<Meta>,\n): commit is Commit<SnapshotMetaDD31> {\n return isSnapshotMetaDD31(commit.meta);\n}\n\nexport class Commit<M extends Meta> {\n readonly chunk: Chunk<CommitData<M>>;\n\n constructor(chunk: Chunk<CommitData<M>>) {\n this.chunk = chunk;\n }\n\n get meta(): M {\n return this.chunk.data.meta;\n }\n\n get valueHash(): Hash {\n // Already validated!\n return this.chunk.data.valueHash;\n }\n\n getMutationID(clientID: ClientID, dagRead: MustGetChunk): Promise<number> {\n return getMutationID(clientID, dagRead, this.meta);\n }\n\n async getNextMutationID(\n clientID: ClientID,\n dagRead: MustGetChunk,\n ): Promise<number> {\n return (await this.getMutationID(clientID, dagRead)) + 1;\n }\n\n get indexes(): readonly IndexRecord[] {\n // Already validated!\n return this.chunk.data.indexes;\n }\n}\n\nexport async function getMutationID(\n clientID: ClientID,\n dagRead: MustGetChunk,\n meta: Meta,\n): Promise<number> {\n switch (meta.type) {\n case MetaType.SnapshotDD31:\n return meta.lastMutationIDs[clientID] ?? 0;\n\n case MetaType.LocalDD31: {\n if (meta.clientID === clientID) {\n return meta.mutationID;\n }\n const {basisHash} = meta;\n const basisCommit = await commitFromHash(basisHash, dagRead);\n return getMutationID(clientID, dagRead, basisCommit.meta);\n }\n\n default:\n unreachable(meta);\n }\n}\n\n/**\n * Returns the set of local commits from the given `fromCommitHash` back to but not\n * including its base snapshot. If `fromCommitHash` is a snapshot, the returned vector\n * will be empty. When, as typical, `fromCommitHash` is the head of the default chain\n * then the returned commits are the set of pending commits, ie the set of local commits\n * that have not yet been pushed to the data layer.\n *\n * The vector of commits is returned in reverse chain order, that is, starting\n * with the commit with hash `fromCommitHash` and walking backwards.\n */\nexport async function localMutations(\n fromCommitHash: Hash,\n dagRead: Read,\n): Promise<Commit<LocalMetaDD31>[]> {\n const commits = await commitChain(fromCommitHash, dagRead);\n // Filter does not deal with type narrowing.\n return commits.filter(c => commitIsLocal(c)) as Commit<LocalMetaDD31>[];\n}\n\nexport async function localMutationsDD31(\n fromCommitHash: Hash,\n dagRead: Read,\n): Promise<Commit<LocalMetaDD31>[]> {\n const commits = await commitChain(fromCommitHash, dagRead);\n // Filter does not deal with type narrowing.\n return commits.filter(c => commitIsLocalDD31(c)) as Commit<LocalMetaDD31>[];\n}\n\nexport async function localMutationsGreaterThan(\n commit: Commit<Meta>,\n mutationIDLimits: Record<ClientID, number>,\n dagRead: Read,\n): Promise<Commit<LocalMetaDD31>[]> {\n const commits: Commit<LocalMetaDD31>[] = [];\n const remainingMutationIDLimits = new Map(Object.entries(mutationIDLimits));\n while (!commitIsSnapshot(commit) && remainingMutationIDLimits.size > 0) {\n if (commitIsLocalDD31(commit)) {\n const {meta} = commit;\n const mutationIDLowerLimit = remainingMutationIDLimits.get(meta.clientID);\n if (mutationIDLowerLimit !== undefined) {\n if (meta.mutationID <= mutationIDLowerLimit) {\n remainingMutationIDLimits.delete(meta.clientID);\n } else {\n commits.push(commit as Commit<LocalMetaDD31>);\n }\n }\n }\n const {basisHash} = commit.meta;\n if (basisHash === null) {\n throw new Error(`Commit ${commit.chunk.hash} has no basis`);\n }\n commit = await commitFromHash(basisHash, dagRead);\n }\n return commits;\n}\n\nexport async function baseSnapshotFromHead(\n name: string,\n dagRead: Read,\n): Promise<Commit<SnapshotMetaDD31>> {\n const hash = await dagRead.getHead(name);\n assert(hash, `Missing head ${name}`);\n return baseSnapshotFromHash(hash, dagRead);\n}\n\nexport async function baseSnapshotHashFromHash(\n hash: Hash,\n dagRead: Read,\n): Promise<Hash> {\n return (await baseSnapshotFromHash(hash, dagRead)).chunk.hash;\n}\n\nexport async function baseSnapshotFromHash(\n hash: Hash,\n dagRead: Read,\n): Promise<Commit<SnapshotMetaDD31>> {\n const commit = await commitFromHash(hash, dagRead);\n return baseSnapshotFromCommit(commit, dagRead);\n}\n\nexport async function baseSnapshotFromCommit(\n commit: Commit<Meta>,\n dagRead: Read,\n): Promise<Commit<SnapshotMetaDD31>> {\n while (!commitIsSnapshot(commit)) {\n const {meta} = commit;\n if (isLocalMetaDD31(meta)) {\n commit = await commitFromHash(meta.baseSnapshotHash, dagRead);\n } else {\n const {basisHash} = meta;\n if (basisHash === null) {\n throw new Error(`Commit ${commit.chunk.hash} has no basis`);\n }\n commit = await commitFromHash(basisHash, dagRead);\n }\n }\n return commit;\n}\n\nexport function snapshotMetaParts(\n c: Commit<SnapshotMetaDD31>,\n clientID: ClientID,\n): [lastMutationID: number, cookie: FrozenCookie | FrozenJSONValue] {\n const m = c.meta;\n const lmid = m.lastMutationIDs[clientID] ?? 0;\n return [lmid, m.cookieJSON];\n}\n\nexport function compareCookiesForSnapshots(\n a: Commit<SnapshotMetaDD31>,\n b: Commit<SnapshotMetaDD31>,\n): number {\n return compareCookies(a.meta.cookieJSON, b.meta.cookieJSON);\n}\n\n/**\n * Returns all commits from the commit with fromCommitHash to its base snapshot,\n * inclusive of both. Resulting vector is in chain-head-first order (so snapshot\n * comes last).\n */\nexport async function commitChain(\n fromCommitHash: Hash,\n dagRead: Read,\n): Promise<Commit<Meta>[]> {\n let commit = await commitFromHash(fromCommitHash, dagRead);\n const commits = [];\n while (!commitIsSnapshot(commit)) {\n const {meta} = commit;\n const {basisHash} = meta;\n if (basisHash === null) {\n throw new Error(`Commit ${commit.chunk.hash} has no basis`);\n }\n commits.push(commit);\n commit = await commitFromHash(basisHash, dagRead);\n }\n commits.push(commit);\n return commits;\n}\n\nexport async function commitFromHash(\n hash: Hash,\n dagRead: MustGetChunk,\n): Promise<Commit<Meta>> {\n const chunk = await dagRead.mustGetChunk(hash);\n return fromChunk(chunk);\n}\n\nexport async function commitFromHead(\n name: string,\n dagRead: Read,\n): Promise<Commit<Meta>> {\n const hash = await mustGetHeadHash(name, dagRead);\n return commitFromHash(hash, dagRead);\n}\n\nexport type LocalMetaDD31 = {\n readonly type: MetaType.LocalDD31;\n readonly basisHash: Hash;\n readonly mutationID: number;\n readonly mutatorName: string;\n readonly mutatorArgsJSON: FrozenJSONValue;\n readonly originalHash: Hash | null;\n readonly timestamp: number;\n readonly clientID: ClientID;\n readonly baseSnapshotHash: Hash;\n};\n\nexport type LocalMeta = LocalMetaDD31;\n\nexport function assertLocalMetaDD31(\n v: Record<string, unknown>,\n): asserts v is LocalMetaDD31 {\n // type already asserted\n assertString(v.clientID);\n assertNumber(v.mutationID);\n assertString(v.mutatorName);\n if (!v.mutatorName) {\n throw new Error('Missing mutator name');\n }\n assertJSONValue(v.mutatorArgsJSON);\n if (v.originalHash !== null) {\n assertHash(v.originalHash);\n }\n assertNumber(v.timestamp);\n}\n\nexport function isLocalMetaDD31(meta: Meta): meta is LocalMetaDD31 {\n return meta.type === MetaType.LocalDD31;\n}\n\nexport function assertLocalCommitDD31(\n c: Commit<Meta>,\n): asserts c is Commit<LocalMetaDD31> {\n assertLocalMetaDD31(c.meta);\n}\n\nexport type SnapshotMetaDD31 = {\n readonly type: MetaType.SnapshotDD31;\n readonly basisHash: Hash | null;\n readonly lastMutationIDs: Record<ClientID, number>;\n readonly cookieJSON: FrozenCookie;\n};\n\nexport type SnapshotMeta = SnapshotMetaDD31;\n\nexport function assertSnapshotMetaDD31(\n v: Record<string, unknown>,\n): asserts v is SnapshotMetaDD31 {\n // type already asserted\n if (v.basisHash !== null) {\n assertHash(v.basisHash);\n }\n assertJSONValue(v.cookieJSON);\n assertLastMutationIDs(v.lastMutationIDs);\n}\n\nfunction assertLastMutationIDs(\n v: unknown,\n): asserts v is Record<ClientID, number> {\n assertObject(v);\n for (const e of Object.values(v)) {\n assertNumber(e);\n }\n}\n\nexport type Meta = LocalMetaDD31 | SnapshotMetaDD31;\n\nexport function assertSnapshotCommitDD31(\n c: Commit<Meta>,\n): asserts c is Commit<SnapshotMetaDD31> {\n assertSnapshotMetaDD31(c.meta);\n}\n\nfunction isSnapshotMetaDD31(meta: Meta): meta is SnapshotMetaDD31 {\n return meta.type === MetaType.SnapshotDD31;\n}\n\nfunction assertMeta(v: unknown): asserts v is Meta {\n assertObject(v);\n assertDeepFrozen(v);\n if (v.basisHash !== null) {\n assertString(v.basisHash);\n }\n\n assertNumber(v.type);\n switch (v.type) {\n case MetaType.LocalDD31:\n assertLocalMetaDD31(v);\n break;\n case MetaType.SnapshotDD31:\n assertSnapshotMetaDD31(v);\n break;\n default:\n throw new Error(`Invalid enum value ${v.type}`);\n }\n}\n\n/**\n * This is the type used for index definitions as defined in the Commit chunk data.\n *\n * Changing this requires a REPLICACHE_FORMAT_VERSION bump.\n */\nexport type ChunkIndexDefinition = {\n readonly name: string;\n readonly keyPrefix: string;\n readonly jsonPointer: string;\n // Used to not exist\n readonly allowEmpty?: boolean;\n};\n\nexport function chunkIndexDefinitionEqualIgnoreName(\n a: ChunkIndexDefinition,\n b: ChunkIndexDefinition,\n): boolean {\n return (\n a.jsonPointer === b.jsonPointer &&\n (a.allowEmpty ?? false) === (b.allowEmpty ?? false) &&\n a.keyPrefix === b.keyPrefix\n );\n}\n\nfunction assertChunkIndexDefinition(\n v: unknown,\n): asserts v is ChunkIndexDefinition {\n assertObject(v);\n assertDeepFrozen(v);\n assertString(v.name);\n assertString(v.keyPrefix);\n assertString(v.jsonPointer);\n if (v.allowEmpty !== undefined) {\n assertBoolean(v.allowEmpty);\n }\n}\n\nexport function toChunkIndexDefinition(\n name: string,\n indexDefinition: IndexDefinition,\n): Required<ChunkIndexDefinition> {\n return {\n name,\n keyPrefix: indexDefinition.prefix ?? '',\n jsonPointer: indexDefinition.jsonPointer,\n allowEmpty: indexDefinition.allowEmpty ?? false,\n };\n}\n\nexport type IndexRecord = {\n readonly definition: ChunkIndexDefinition;\n readonly valueHash: Hash;\n};\n\nfunction assertIndexRecord(v: unknown): asserts v is IndexRecord {\n assertObject(v);\n assertDeepFrozen(v);\n assertChunkIndexDefinition(v.definition);\n assertString(v.valueHash);\n}\n\nfunction assertIndexRecords(v: unknown): asserts v is IndexRecord[] {\n assertArray(v);\n assertDeepFrozen(v);\n for (const ir of v) {\n assertIndexRecord(ir);\n }\n}\n\nexport function newLocalDD31(\n createChunk: CreateChunk,\n basisHash: Hash,\n baseSnapshotHash: Hash,\n mutationID: number,\n mutatorName: string,\n mutatorArgsJSON: FrozenJSONValue,\n originalHash: Hash | null,\n valueHash: Hash,\n indexes: readonly IndexRecord[],\n timestamp: number,\n clientID: ClientID,\n): Commit<LocalMetaDD31> {\n const meta: LocalMetaDD31 = {\n type: MetaType.LocalDD31,\n basisHash,\n baseSnapshotHash,\n mutationID,\n mutatorName,\n mutatorArgsJSON,\n originalHash,\n timestamp,\n clientID,\n };\n return commitFromCommitData(\n createChunk,\n makeCommitData(meta, valueHash, indexes),\n );\n}\n\nexport function newSnapshotDD31(\n createChunk: CreateChunk,\n basisHash: Hash | null,\n lastMutationIDs: Record<ClientID, number>,\n cookieJSON: FrozenCookie,\n valueHash: Hash,\n indexes: readonly IndexRecord[],\n): Commit<SnapshotMetaDD31> {\n return commitFromCommitData(\n createChunk,\n newSnapshotCommitDataDD31(\n basisHash,\n lastMutationIDs,\n cookieJSON,\n valueHash,\n indexes,\n ),\n );\n}\n\nexport function newSnapshotCommitDataDD31(\n basisHash: Hash | null,\n lastMutationIDs: Record<ClientID, number>,\n cookieJSON: FrozenCookie,\n valueHash: Hash,\n indexes: readonly IndexRecord[],\n): CommitData<SnapshotMetaDD31> {\n const meta: SnapshotMetaDD31 = {\n type: MetaType.SnapshotDD31,\n basisHash,\n lastMutationIDs,\n cookieJSON,\n };\n return makeCommitData(meta, valueHash, indexes);\n}\n\nexport function fromChunk(chunk: Chunk): Commit<Meta> {\n validateChunk(chunk);\n return new Commit(chunk);\n}\n\nfunction commitFromCommitData<M extends Meta>(\n createChunk: CreateChunk,\n data: CommitData<M>,\n): Commit<M> {\n return new Commit(createChunk(data, getRefs(data)));\n}\n\nexport function getRefs(data: CommitData<Meta>): Refs {\n const refs: Set<Hash> = new Set();\n refs.add(data.valueHash);\n const {meta} = data;\n switch (meta.type) {\n case MetaType.LocalDD31:\n meta.basisHash && refs.add(meta.basisHash);\n // Local has weak originalHash\n break;\n case MetaType.SnapshotDD31:\n // Snapshot has weak basisHash\n break;\n default:\n unreachable(meta);\n }\n\n for (const index of data.indexes) {\n refs.add(index.valueHash);\n }\n\n return toRefs(refs);\n}\n\nexport type CommitData<M extends Meta> = FrozenTag<{\n readonly meta: M;\n readonly valueHash: Hash;\n readonly indexes: readonly IndexRecord[];\n}>;\n\nexport function makeCommitData<M extends Meta>(\n meta: M,\n valueHash: Hash,\n indexes: readonly IndexRecord[],\n): CommitData<M> {\n return deepFreeze({\n meta,\n valueHash,\n indexes,\n }) as unknown as CommitData<M>;\n}\n\nfunction assertCommitData(v: unknown): asserts v is CommitData<Meta> {\n if (skipCommitDataAsserts) {\n return;\n }\n\n assertObject(v);\n assertDeepFrozen(v);\n assertMeta(v.meta);\n assertString(v.valueHash);\n assertIndexRecords(v.indexes);\n}\n\nfunction validateChunk(chunk: Chunk): asserts chunk is Chunk<CommitData<Meta>> {\n const {data} = chunk;\n assertCommitData(data);\n\n const seen = new Set();\n for (const index of data.indexes) {\n const {name} = index.definition;\n if (seen.has(name)) {\n throw new Error(`Duplicate index ${name}`);\n }\n seen.add(name);\n }\n}\n"],"mappings":"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"}
|
|
@@ -44,8 +44,6 @@ export declare class Write extends Read {
|
|
|
44
44
|
}
|
|
45
45
|
export declare function newWriteLocal(basisHash: Hash, mutatorName: string, mutatorArgsJSON: FrozenJSONValue, originalHash: Hash | null, dagWrite: DagWrite, timestamp: number, clientID: ClientID, formatVersion: FormatVersion): Promise<Write>;
|
|
46
46
|
export declare function newWriteSnapshotDD31(basisHash: Hash, lastMutationIDs: Record<ClientID, number>, cookieJSON: FrozenCookie, dagWrite: DagWrite, clientID: ClientID, formatVersion: FormatVersion): Promise<Write>;
|
|
47
|
-
export declare function updateIndexes(lc: LogContext, map: BTreeRead, indexes: Map<string, IndexWrite>, key: string, newVal: FrozenJSONValue | undefined): Promise<void>;
|
|
48
|
-
export declare function readIndexesForWrite(commit: Commit<CommitMeta>, dagWrite: DagWrite, formatVersion: FormatVersion): Map<string, IndexWrite>;
|
|
49
47
|
export declare function createIndexBTree(lc: LogContext, dagWrite: DagWrite, valueMap: BTreeRead, prefix: string, jsonPointer: string, allowEmpty: boolean, formatVersion: FormatVersion): Promise<BTreeWrite>;
|
|
50
48
|
export {};
|
|
51
49
|
//# sourceMappingURL=write.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"write.d.ts","sourceRoot":"","sources":["../../../../../replicache/src/db/write.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"write.d.ts","sourceRoot":"","sources":["../../../../../replicache/src/db/write.ts"],"names":[],"mappings":"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"}
|
|
@@ -143,6 +143,6 @@ function readIndexesForWrite(commit, dagWrite, formatVersion) {
|
|
|
143
143
|
return /* @__PURE__ */ new Map();
|
|
144
144
|
}
|
|
145
145
|
//#endregion
|
|
146
|
-
export { Write, newWriteLocal, newWriteSnapshotDD31
|
|
146
|
+
export { Write, newWriteLocal, newWriteSnapshotDD31 };
|
|
147
147
|
|
|
148
148
|
//# sourceMappingURL=write.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"write.js","names":["commitNewLocalDD31","commitNewSnapshotDD31"],"sources":["../../../../../replicache/src/db/write.ts"],"sourcesContent":["import '../process-env.ts';\nimport type {LogContext} from '@rocicorp/logger';\nimport {assert} from '../../../shared/src/asserts.ts';\nimport type {Enum} from '../../../shared/src/enum.ts';\nimport {diff} from '../btree/diff.ts';\nimport type {InternalDiff} from '../btree/node.ts';\nimport {BTreeRead, allEntriesAsDiff} from '../btree/read.ts';\nimport {BTreeWrite} from '../btree/write.ts';\nimport type {FrozenCookie} from '../cookies.ts';\nimport type {Write as DagWrite} from '../dag/store.ts';\nimport * as FormatVersion from '../format-version-enum.ts';\nimport type {FrozenJSONValue} from '../frozen-json.ts';\nimport {type Hash, emptyHash} from '../hash.ts';\nimport type {DiffComputationConfig} from '../sync/diff.ts';\nimport {DiffsMap} from '../sync/diff.ts';\nimport type {ClientID} from '../sync/ids.ts';\nimport type {Commit} from './commit.ts';\nimport {\n type Meta as CommitMeta,\n type IndexRecord,\n type Meta,\n baseSnapshotHashFromHash,\n commitFromHash,\n newLocalDD31 as commitNewLocalDD31,\n newSnapshotDD31 as commitNewSnapshotDD31,\n getMutationID,\n} from './commit.ts';\nimport * as IndexOperation from './index-operation-enum.ts';\nimport type {IndexRead} from './index.ts';\nimport {IndexWrite, indexValue} from './index.ts';\nimport * as MetaType from './meta-type-enum.ts';\nimport {Read, readIndexesForRead} from './read.ts';\n\ntype FormatVersion = Enum<typeof FormatVersion>;\n\nexport class Write extends Read {\n readonly #dagWrite: DagWrite;\n readonly #basis: Commit<CommitMeta> | undefined;\n readonly #meta: CommitMeta;\n\n declare map: BTreeWrite;\n\n declare readonly indexes: Map<string, IndexWrite>;\n readonly #clientID: ClientID;\n readonly #formatVersion: FormatVersion;\n\n constructor(\n dagWrite: DagWrite,\n map: BTreeWrite,\n basis: Commit<CommitMeta> | undefined,\n meta: CommitMeta,\n indexes: Map<string, IndexWrite>,\n clientID: ClientID,\n formatVersion: FormatVersion,\n ) {\n // TypeScript has trouble\n super(dagWrite, map, indexes);\n this.#dagWrite = dagWrite;\n this.#basis = basis;\n this.#meta = meta;\n this.#clientID = clientID;\n this.#formatVersion = formatVersion;\n\n // TODO(arv): if (DEBUG) { ...\n if (basis === undefined) {\n assert(\n meta.basisHash === emptyHash,\n 'Expected basisHash to be emptyHash when basis is undefined',\n );\n } else {\n assert(\n meta.basisHash === basis.chunk.hash,\n 'Expected meta.basisHash to equal basis.chunk.hash',\n );\n }\n }\n\n /**\n * The value needs to be frozen since it is kept in memory and used later for\n * comparison as well as returned in `get`.\n */\n async put(\n lc: LogContext,\n key: string,\n value: FrozenJSONValue,\n ): Promise<void> {\n if (!process.env.DISABLE_REPLICACHE_INDEXES && this.indexes.size > 0) {\n await updateIndexes(lc, this.map, this.indexes, key, value);\n }\n await this.map.put(key, value);\n }\n\n /**\n * Inserts or updates multiple entries in a single bulk operation. More\n * efficient than calling {@link put} in a loop because it uses\n * {@link BTreeWrite.putMany} to build or merge tree nodes in one pass.\n *\n * `entries` must be sorted in ascending key order.\n */\n async putMany(\n lc: LogContext,\n entries: ReadonlyArray<readonly [string, FrozenJSONValue]>,\n ): Promise<void> {\n if (entries.length === 0) {\n return;\n }\n\n // Update indexes for all entries\n if (!process.env.DISABLE_REPLICACHE_INDEXES && this.indexes.size > 0) {\n // TODO(arv): Indexes can use the optimizePatch pattern too.\n for (const [key, value] of entries) {\n await updateIndexes(lc, this.map, this.indexes, key, value);\n }\n }\n\n // BTreeWrite.putMany handles both empty and non-empty trees optimally\n await this.map.putMany(entries);\n }\n\n getMutationID(): Promise<number> {\n return getMutationID(this.#clientID, this.#dagWrite, this.#meta);\n }\n\n async del(lc: LogContext, key: string): Promise<boolean> {\n if (!process.env.DISABLE_REPLICACHE_INDEXES && this.indexes.size > 0) {\n await updateIndexes(lc, this.map, this.indexes, key, undefined);\n }\n return this.map.del(key);\n }\n\n async clear(): Promise<void> {\n await this.map.clear();\n const ps = [];\n for (const idx of this.indexes.values()) {\n ps.push(idx.clear());\n }\n await Promise.all(ps);\n }\n\n async putCommit(): Promise<Commit<CommitMeta>> {\n const valueHash = await this.map.flush();\n const indexRecords: IndexRecord[] = [];\n\n for (const index of this.indexes.values()) {\n const valueHash = await index.flush();\n const indexRecord: IndexRecord = {\n definition: index.meta.definition,\n valueHash,\n };\n indexRecords.push(indexRecord);\n }\n\n let commit: Commit<Meta>;\n const meta = this.#meta;\n switch (meta.type) {\n case MetaType.LocalDD31: {\n assert(\n this.#formatVersion >= FormatVersion.DD31,\n 'Expected formatVersion >= DD31 for LocalDD31 commit',\n );\n const {\n basisHash,\n mutationID,\n mutatorName,\n mutatorArgsJSON,\n originalHash,\n timestamp,\n } = meta;\n commit = commitNewLocalDD31(\n this.#dagWrite.createChunk,\n basisHash,\n await baseSnapshotHashFromHash(basisHash, this.#dagWrite),\n mutationID,\n mutatorName,\n mutatorArgsJSON,\n originalHash,\n valueHash,\n indexRecords,\n timestamp,\n this.#clientID,\n );\n break;\n }\n\n case MetaType.SnapshotDD31: {\n assert(\n this.#formatVersion > FormatVersion.DD31,\n 'Expected formatVersion > DD31 for SnapshotDD31 commit',\n );\n const {basisHash, lastMutationIDs, cookieJSON} = meta;\n commit = commitNewSnapshotDD31(\n this.#dagWrite.createChunk,\n basisHash,\n lastMutationIDs,\n cookieJSON,\n valueHash,\n indexRecords,\n );\n break;\n }\n }\n await this.#dagWrite.putChunk(commit.chunk);\n return commit;\n }\n\n // Return value is the hash of the new commit.\n async commit(headName: string): Promise<Hash> {\n const commit = await this.putCommit();\n const commitHash = commit.chunk.hash;\n await this.#dagWrite.setHead(headName, commitHash);\n await this.#dagWrite.commit();\n return commitHash;\n }\n\n async commitWithDiffs(\n headName: string,\n diffConfig: DiffComputationConfig,\n ): Promise<[Hash, DiffsMap]> {\n const commit = this.putCommit();\n const diffMap = await this.#generateDiffs(diffConfig);\n const commitHash = (await commit).chunk.hash;\n await this.#dagWrite.setHead(headName, commitHash);\n await this.#dagWrite.commit();\n return [commitHash, diffMap];\n }\n\n async #generateDiffs(diffConfig: DiffComputationConfig): Promise<DiffsMap> {\n const diffsMap = new DiffsMap();\n if (!diffConfig.shouldComputeDiffs()) {\n return diffsMap;\n }\n\n let valueDiff: InternalDiff = [];\n if (this.#basis) {\n const basisMap = new BTreeRead(\n this.#dagWrite,\n this.#formatVersion,\n this.#basis.valueHash,\n );\n valueDiff = await diff(basisMap, this.map);\n }\n diffsMap.set('', valueDiff);\n if (process.env.DISABLE_REPLICACHE_INDEXES) {\n return diffsMap;\n }\n let basisIndexes: Map<string, IndexRead>;\n if (this.#basis) {\n basisIndexes = readIndexesForRead(\n this.#basis,\n this.#dagWrite,\n this.#formatVersion,\n );\n } else {\n basisIndexes = new Map();\n }\n\n for (const [name, index] of this.indexes) {\n if (!diffConfig.shouldComputeDiffsForIndex(name)) {\n continue;\n }\n const basisIndex = basisIndexes.get(name);\n assert(index !== basisIndex, 'Expected index to differ from basisIndex');\n\n const indexDiffResult = await (basisIndex\n ? diff(basisIndex.map, index.map)\n : // No basis. All keys are new.\n allEntriesAsDiff(index.map, 'add'));\n diffsMap.set(name, indexDiffResult);\n }\n\n // Handle indexes in basisIndex but not in this.indexes. All keys are\n // deleted.\n for (const [name, basisIndex] of basisIndexes) {\n if (\n !this.indexes.has(name) &&\n diffConfig.shouldComputeDiffsForIndex(name)\n ) {\n const indexDiffResult = await allEntriesAsDiff(basisIndex.map, 'del');\n diffsMap.set(name, indexDiffResult);\n }\n }\n return diffsMap;\n }\n\n close(): void {\n this.#dagWrite.release();\n }\n}\n\nexport async function newWriteLocal(\n basisHash: Hash,\n mutatorName: string,\n mutatorArgsJSON: FrozenJSONValue,\n originalHash: Hash | null,\n dagWrite: DagWrite,\n timestamp: number,\n clientID: ClientID,\n formatVersion: FormatVersion,\n): Promise<Write> {\n const basis = await commitFromHash(basisHash, dagWrite);\n const bTreeWrite = new BTreeWrite(dagWrite, formatVersion, basis.valueHash);\n const mutationID = await basis.getNextMutationID(clientID, dagWrite);\n const indexes = readIndexesForWrite(basis, dagWrite, formatVersion);\n assert(\n formatVersion >= FormatVersion.DD31,\n 'Expected formatVersion >= DD31 for newWriteLocal',\n );\n return new Write(\n dagWrite,\n bTreeWrite,\n basis,\n\n {\n type: MetaType.LocalDD31,\n basisHash,\n baseSnapshotHash: await baseSnapshotHashFromHash(basisHash, dagWrite),\n mutatorName,\n mutatorArgsJSON,\n mutationID,\n originalHash,\n timestamp,\n clientID,\n },\n indexes,\n clientID,\n formatVersion,\n );\n}\n\nexport async function newWriteSnapshotDD31(\n basisHash: Hash,\n lastMutationIDs: Record<ClientID, number>,\n cookieJSON: FrozenCookie,\n dagWrite: DagWrite,\n clientID: ClientID,\n formatVersion: FormatVersion,\n): Promise<Write> {\n const basis = await commitFromHash(basisHash, dagWrite);\n const bTreeWrite = new BTreeWrite(dagWrite, formatVersion, basis.valueHash);\n return new Write(\n dagWrite,\n bTreeWrite,\n basis,\n {basisHash, type: MetaType.SnapshotDD31, lastMutationIDs, cookieJSON},\n readIndexesForWrite(basis, dagWrite, formatVersion),\n clientID,\n formatVersion,\n );\n}\n\nexport async function updateIndexes(\n lc: LogContext,\n map: BTreeRead,\n indexes: Map<string, IndexWrite>,\n key: string,\n newVal: FrozenJSONValue | undefined,\n): Promise<void> {\n let oldValPromise: Promise<FrozenJSONValue | undefined> | undefined;\n\n const ps: Promise<void>[] = [];\n for (const idx of indexes.values()) {\n const {keyPrefix} = idx.meta.definition;\n if (!keyPrefix || key.startsWith(keyPrefix)) {\n const oldVal = await (oldValPromise ??= map.get(key));\n if (oldVal !== undefined) {\n ps.push(\n indexValue(\n lc,\n idx.map,\n IndexOperation.Remove,\n key,\n oldVal,\n idx.meta.definition.jsonPointer,\n idx.meta.definition.allowEmpty ?? false,\n ),\n );\n }\n if (newVal !== undefined) {\n ps.push(\n indexValue(\n lc,\n idx.map,\n IndexOperation.Add,\n key,\n newVal,\n idx.meta.definition.jsonPointer,\n idx.meta.definition.allowEmpty ?? false,\n ),\n );\n }\n }\n }\n await Promise.all(ps);\n}\n\nexport function readIndexesForWrite(\n commit: Commit<CommitMeta>,\n dagWrite: DagWrite,\n formatVersion: FormatVersion,\n): Map<string, IndexWrite> {\n const m: Map<string, IndexWrite> = new Map();\n if (process.env.DISABLE_REPLICACHE_INDEXES) {\n return m;\n }\n for (const index of commit.indexes) {\n m.set(\n index.definition.name,\n new IndexWrite(\n index,\n new BTreeWrite(dagWrite, formatVersion, index.valueHash),\n ),\n );\n }\n return m;\n}\n\nexport async function createIndexBTree(\n lc: LogContext,\n dagWrite: DagWrite,\n valueMap: BTreeRead,\n prefix: string,\n jsonPointer: string,\n allowEmpty: boolean,\n formatVersion: FormatVersion,\n): Promise<BTreeWrite> {\n const indexMap = new BTreeWrite(dagWrite, formatVersion);\n for await (const entry of valueMap.scan(prefix, false)) {\n const key = entry[0];\n if (!key.startsWith(prefix)) {\n break;\n }\n await indexValue(\n lc,\n indexMap,\n IndexOperation.Add,\n key,\n entry[1],\n jsonPointer,\n allowEmpty,\n );\n }\n return indexMap;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"write.js","names":["commitNewLocalDD31","commitNewSnapshotDD31"],"sources":["../../../../../replicache/src/db/write.ts"],"sourcesContent":["import '../process-env.ts';\nimport type {LogContext} from '@rocicorp/logger';\nimport {assert} from '../../../shared/src/asserts.ts';\nimport type {Enum} from '../../../shared/src/enum.ts';\nimport {diff} from '../btree/diff.ts';\nimport type {InternalDiff} from '../btree/node.ts';\nimport {BTreeRead, allEntriesAsDiff} from '../btree/read.ts';\nimport {BTreeWrite} from '../btree/write.ts';\nimport type {FrozenCookie} from '../cookies.ts';\nimport type {Write as DagWrite} from '../dag/store.ts';\nimport * as FormatVersion from '../format-version-enum.ts';\nimport type {FrozenJSONValue} from '../frozen-json.ts';\nimport {type Hash, emptyHash} from '../hash.ts';\nimport type {DiffComputationConfig} from '../sync/diff.ts';\nimport {DiffsMap} from '../sync/diff.ts';\nimport type {ClientID} from '../sync/ids.ts';\nimport type {Commit} from './commit.ts';\nimport {\n type Meta as CommitMeta,\n type IndexRecord,\n type Meta,\n baseSnapshotHashFromHash,\n commitFromHash,\n newLocalDD31 as commitNewLocalDD31,\n newSnapshotDD31 as commitNewSnapshotDD31,\n getMutationID,\n} from './commit.ts';\nimport * as IndexOperation from './index-operation-enum.ts';\nimport type {IndexRead} from './index.ts';\nimport {IndexWrite, indexValue} from './index.ts';\nimport * as MetaType from './meta-type-enum.ts';\nimport {Read, readIndexesForRead} from './read.ts';\n\ntype FormatVersion = Enum<typeof FormatVersion>;\n\nexport class Write extends Read {\n readonly #dagWrite: DagWrite;\n readonly #basis: Commit<CommitMeta> | undefined;\n readonly #meta: CommitMeta;\n\n declare map: BTreeWrite;\n\n declare readonly indexes: Map<string, IndexWrite>;\n readonly #clientID: ClientID;\n readonly #formatVersion: FormatVersion;\n\n constructor(\n dagWrite: DagWrite,\n map: BTreeWrite,\n basis: Commit<CommitMeta> | undefined,\n meta: CommitMeta,\n indexes: Map<string, IndexWrite>,\n clientID: ClientID,\n formatVersion: FormatVersion,\n ) {\n // TypeScript has trouble\n super(dagWrite, map, indexes);\n this.#dagWrite = dagWrite;\n this.#basis = basis;\n this.#meta = meta;\n this.#clientID = clientID;\n this.#formatVersion = formatVersion;\n\n // TODO(arv): if (DEBUG) { ...\n if (basis === undefined) {\n assert(\n meta.basisHash === emptyHash,\n 'Expected basisHash to be emptyHash when basis is undefined',\n );\n } else {\n assert(\n meta.basisHash === basis.chunk.hash,\n 'Expected meta.basisHash to equal basis.chunk.hash',\n );\n }\n }\n\n /**\n * The value needs to be frozen since it is kept in memory and used later for\n * comparison as well as returned in `get`.\n */\n async put(\n lc: LogContext,\n key: string,\n value: FrozenJSONValue,\n ): Promise<void> {\n if (!process.env.DISABLE_REPLICACHE_INDEXES && this.indexes.size > 0) {\n await updateIndexes(lc, this.map, this.indexes, key, value);\n }\n await this.map.put(key, value);\n }\n\n /**\n * Inserts or updates multiple entries in a single bulk operation. More\n * efficient than calling {@link put} in a loop because it uses\n * {@link BTreeWrite.putMany} to build or merge tree nodes in one pass.\n *\n * `entries` must be sorted in ascending key order.\n */\n async putMany(\n lc: LogContext,\n entries: ReadonlyArray<readonly [string, FrozenJSONValue]>,\n ): Promise<void> {\n if (entries.length === 0) {\n return;\n }\n\n // Update indexes for all entries\n if (!process.env.DISABLE_REPLICACHE_INDEXES && this.indexes.size > 0) {\n // TODO(arv): Indexes can use the optimizePatch pattern too.\n for (const [key, value] of entries) {\n await updateIndexes(lc, this.map, this.indexes, key, value);\n }\n }\n\n // BTreeWrite.putMany handles both empty and non-empty trees optimally\n await this.map.putMany(entries);\n }\n\n getMutationID(): Promise<number> {\n return getMutationID(this.#clientID, this.#dagWrite, this.#meta);\n }\n\n async del(lc: LogContext, key: string): Promise<boolean> {\n if (!process.env.DISABLE_REPLICACHE_INDEXES && this.indexes.size > 0) {\n await updateIndexes(lc, this.map, this.indexes, key, undefined);\n }\n return this.map.del(key);\n }\n\n async clear(): Promise<void> {\n await this.map.clear();\n const ps = [];\n for (const idx of this.indexes.values()) {\n ps.push(idx.clear());\n }\n await Promise.all(ps);\n }\n\n async putCommit(): Promise<Commit<CommitMeta>> {\n const valueHash = await this.map.flush();\n const indexRecords: IndexRecord[] = [];\n\n for (const index of this.indexes.values()) {\n const valueHash = await index.flush();\n const indexRecord: IndexRecord = {\n definition: index.meta.definition,\n valueHash,\n };\n indexRecords.push(indexRecord);\n }\n\n let commit: Commit<Meta>;\n const meta = this.#meta;\n switch (meta.type) {\n case MetaType.LocalDD31: {\n assert(\n this.#formatVersion >= FormatVersion.DD31,\n 'Expected formatVersion >= DD31 for LocalDD31 commit',\n );\n const {\n basisHash,\n mutationID,\n mutatorName,\n mutatorArgsJSON,\n originalHash,\n timestamp,\n } = meta;\n commit = commitNewLocalDD31(\n this.#dagWrite.createChunk,\n basisHash,\n await baseSnapshotHashFromHash(basisHash, this.#dagWrite),\n mutationID,\n mutatorName,\n mutatorArgsJSON,\n originalHash,\n valueHash,\n indexRecords,\n timestamp,\n this.#clientID,\n );\n break;\n }\n\n case MetaType.SnapshotDD31: {\n assert(\n this.#formatVersion > FormatVersion.DD31,\n 'Expected formatVersion > DD31 for SnapshotDD31 commit',\n );\n const {basisHash, lastMutationIDs, cookieJSON} = meta;\n commit = commitNewSnapshotDD31(\n this.#dagWrite.createChunk,\n basisHash,\n lastMutationIDs,\n cookieJSON,\n valueHash,\n indexRecords,\n );\n break;\n }\n }\n await this.#dagWrite.putChunk(commit.chunk);\n return commit;\n }\n\n // Return value is the hash of the new commit.\n async commit(headName: string): Promise<Hash> {\n const commit = await this.putCommit();\n const commitHash = commit.chunk.hash;\n await this.#dagWrite.setHead(headName, commitHash);\n await this.#dagWrite.commit();\n return commitHash;\n }\n\n async commitWithDiffs(\n headName: string,\n diffConfig: DiffComputationConfig,\n ): Promise<[Hash, DiffsMap]> {\n const commit = this.putCommit();\n const diffMap = await this.#generateDiffs(diffConfig);\n const commitHash = (await commit).chunk.hash;\n await this.#dagWrite.setHead(headName, commitHash);\n await this.#dagWrite.commit();\n return [commitHash, diffMap];\n }\n\n async #generateDiffs(diffConfig: DiffComputationConfig): Promise<DiffsMap> {\n const diffsMap = new DiffsMap();\n if (!diffConfig.shouldComputeDiffs()) {\n return diffsMap;\n }\n\n let valueDiff: InternalDiff = [];\n if (this.#basis) {\n const basisMap = new BTreeRead(\n this.#dagWrite,\n this.#formatVersion,\n this.#basis.valueHash,\n );\n valueDiff = await diff(basisMap, this.map);\n }\n diffsMap.set('', valueDiff);\n if (process.env.DISABLE_REPLICACHE_INDEXES) {\n return diffsMap;\n }\n let basisIndexes: Map<string, IndexRead>;\n if (this.#basis) {\n basisIndexes = readIndexesForRead(\n this.#basis,\n this.#dagWrite,\n this.#formatVersion,\n );\n } else {\n basisIndexes = new Map();\n }\n\n for (const [name, index] of this.indexes) {\n if (!diffConfig.shouldComputeDiffsForIndex(name)) {\n continue;\n }\n const basisIndex = basisIndexes.get(name);\n assert(index !== basisIndex, 'Expected index to differ from basisIndex');\n\n const indexDiffResult = await (basisIndex\n ? diff(basisIndex.map, index.map)\n : // No basis. All keys are new.\n allEntriesAsDiff(index.map, 'add'));\n diffsMap.set(name, indexDiffResult);\n }\n\n // Handle indexes in basisIndex but not in this.indexes. All keys are\n // deleted.\n for (const [name, basisIndex] of basisIndexes) {\n if (\n !this.indexes.has(name) &&\n diffConfig.shouldComputeDiffsForIndex(name)\n ) {\n const indexDiffResult = await allEntriesAsDiff(basisIndex.map, 'del');\n diffsMap.set(name, indexDiffResult);\n }\n }\n return diffsMap;\n }\n\n close(): void {\n this.#dagWrite.release();\n }\n}\n\nexport async function newWriteLocal(\n basisHash: Hash,\n mutatorName: string,\n mutatorArgsJSON: FrozenJSONValue,\n originalHash: Hash | null,\n dagWrite: DagWrite,\n timestamp: number,\n clientID: ClientID,\n formatVersion: FormatVersion,\n): Promise<Write> {\n const basis = await commitFromHash(basisHash, dagWrite);\n const bTreeWrite = new BTreeWrite(dagWrite, formatVersion, basis.valueHash);\n const mutationID = await basis.getNextMutationID(clientID, dagWrite);\n const indexes = readIndexesForWrite(basis, dagWrite, formatVersion);\n assert(\n formatVersion >= FormatVersion.DD31,\n 'Expected formatVersion >= DD31 for newWriteLocal',\n );\n return new Write(\n dagWrite,\n bTreeWrite,\n basis,\n\n {\n type: MetaType.LocalDD31,\n basisHash,\n baseSnapshotHash: await baseSnapshotHashFromHash(basisHash, dagWrite),\n mutatorName,\n mutatorArgsJSON,\n mutationID,\n originalHash,\n timestamp,\n clientID,\n },\n indexes,\n clientID,\n formatVersion,\n );\n}\n\nexport async function newWriteSnapshotDD31(\n basisHash: Hash,\n lastMutationIDs: Record<ClientID, number>,\n cookieJSON: FrozenCookie,\n dagWrite: DagWrite,\n clientID: ClientID,\n formatVersion: FormatVersion,\n): Promise<Write> {\n const basis = await commitFromHash(basisHash, dagWrite);\n const bTreeWrite = new BTreeWrite(dagWrite, formatVersion, basis.valueHash);\n return new Write(\n dagWrite,\n bTreeWrite,\n basis,\n {basisHash, type: MetaType.SnapshotDD31, lastMutationIDs, cookieJSON},\n readIndexesForWrite(basis, dagWrite, formatVersion),\n clientID,\n formatVersion,\n );\n}\n\nasync function updateIndexes(\n lc: LogContext,\n map: BTreeRead,\n indexes: Map<string, IndexWrite>,\n key: string,\n newVal: FrozenJSONValue | undefined,\n): Promise<void> {\n let oldValPromise: Promise<FrozenJSONValue | undefined> | undefined;\n\n const ps: Promise<void>[] = [];\n for (const idx of indexes.values()) {\n const {keyPrefix} = idx.meta.definition;\n if (!keyPrefix || key.startsWith(keyPrefix)) {\n const oldVal = await (oldValPromise ??= map.get(key));\n if (oldVal !== undefined) {\n ps.push(\n indexValue(\n lc,\n idx.map,\n IndexOperation.Remove,\n key,\n oldVal,\n idx.meta.definition.jsonPointer,\n idx.meta.definition.allowEmpty ?? false,\n ),\n );\n }\n if (newVal !== undefined) {\n ps.push(\n indexValue(\n lc,\n idx.map,\n IndexOperation.Add,\n key,\n newVal,\n idx.meta.definition.jsonPointer,\n idx.meta.definition.allowEmpty ?? false,\n ),\n );\n }\n }\n }\n await Promise.all(ps);\n}\n\nfunction readIndexesForWrite(\n commit: Commit<CommitMeta>,\n dagWrite: DagWrite,\n formatVersion: FormatVersion,\n): Map<string, IndexWrite> {\n const m: Map<string, IndexWrite> = new Map();\n if (process.env.DISABLE_REPLICACHE_INDEXES) {\n return m;\n }\n for (const index of commit.indexes) {\n m.set(\n index.definition.name,\n new IndexWrite(\n index,\n new BTreeWrite(dagWrite, formatVersion, index.valueHash),\n ),\n );\n }\n return m;\n}\n\nexport async function createIndexBTree(\n lc: LogContext,\n dagWrite: DagWrite,\n valueMap: BTreeRead,\n prefix: string,\n jsonPointer: string,\n allowEmpty: boolean,\n formatVersion: FormatVersion,\n): Promise<BTreeWrite> {\n const indexMap = new BTreeWrite(dagWrite, formatVersion);\n for await (const entry of valueMap.scan(prefix, false)) {\n const key = entry[0];\n if (!key.startsWith(prefix)) {\n break;\n }\n await indexValue(\n lc,\n indexMap,\n IndexOperation.Add,\n key,\n entry[1],\n jsonPointer,\n allowEmpty,\n );\n }\n return indexMap;\n}\n"],"mappings":"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"}
|