@rocicorp/zero 1.11.0-canary.13 → 1.11.0-canary.14
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/analyze-query/src/analyze-cli.js +2 -2
- package/out/analyze-query/src/analyze-cli.js.map +1 -1
- package/out/ast-to-zql/src/ast-to-zql.d.ts +8 -1
- package/out/ast-to-zql/src/ast-to-zql.d.ts.map +1 -1
- package/out/ast-to-zql/src/ast-to-zql.js +25 -25
- package/out/ast-to-zql/src/ast-to-zql.js.map +1 -1
- package/out/otel/src/log-options.d.ts +16 -0
- package/out/otel/src/log-options.d.ts.map +1 -1
- package/out/otel/src/log-options.js +54 -1
- package/out/otel/src/log-options.js.map +1 -1
- package/out/replicache/src/get-kv-store-provider.d.ts +1 -1
- package/out/replicache/src/get-kv-store-provider.d.ts.map +1 -1
- package/out/replicache/src/get-kv-store-provider.js +4 -4
- package/out/replicache/src/get-kv-store-provider.js.map +1 -1
- package/out/replicache/src/kv/idb-store.d.ts +10 -1
- package/out/replicache/src/kv/idb-store.d.ts.map +1 -1
- package/out/replicache/src/kv/idb-store.js +18 -2
- package/out/replicache/src/kv/idb-store.js.map +1 -1
- package/out/replicache/src/kv/mem-fallback-store.d.ts +54 -0
- package/out/replicache/src/kv/mem-fallback-store.d.ts.map +1 -0
- package/out/replicache/src/kv/mem-fallback-store.js +177 -0
- package/out/replicache/src/kv/mem-fallback-store.js.map +1 -0
- package/out/replicache/src/kv/op-sqlite/store.js +3 -3
- package/out/replicache/src/kv/op-sqlite/store.js.map +1 -1
- package/out/replicache/src/kv/sqlite-store.d.ts +9 -0
- package/out/replicache/src/kv/sqlite-store.d.ts.map +1 -1
- package/out/replicache/src/kv/sqlite-store.js +86 -6
- package/out/replicache/src/kv/sqlite-store.js.map +1 -1
- package/out/replicache/src/new-client-channel.js.map +1 -1
- package/out/replicache/src/persist/collect-idb-databases.d.ts +17 -3
- package/out/replicache/src/persist/collect-idb-databases.d.ts.map +1 -1
- package/out/replicache/src/persist/collect-idb-databases.js +81 -11
- package/out/replicache/src/persist/collect-idb-databases.js.map +1 -1
- package/out/replicache/src/persist/idb-databases-store-db-name.js +1 -1
- package/out/replicache/src/persist/idb-databases-store-db-name.js.map +1 -1
- package/out/replicache/src/persist/persist.d.ts.map +1 -1
- package/out/replicache/src/persist/persist.js +6 -3
- package/out/replicache/src/persist/persist.js.map +1 -1
- package/out/replicache/src/replicache-impl.d.ts +43 -3
- package/out/replicache/src/replicache-impl.d.ts.map +1 -1
- package/out/replicache/src/replicache-impl.js +135 -17
- package/out/replicache/src/replicache-impl.js.map +1 -1
- package/out/replicache/src/storage-failure.d.ts +37 -0
- package/out/replicache/src/storage-failure.d.ts.map +1 -0
- package/out/replicache/src/storage-failure.js +31 -0
- package/out/replicache/src/storage-failure.js.map +1 -0
- package/out/shared/src/random-values.js +12 -1
- package/out/shared/src/random-values.js.map +1 -1
- package/out/zero/package.js +1 -1
- package/out/zero/package.js.map +1 -1
- package/out/zero/src/zero.js +2 -1
- package/out/zero-cache/src/config/zero-config.d.ts +26 -0
- package/out/zero-cache/src/config/zero-config.d.ts.map +1 -1
- package/out/zero-cache/src/config/zero-config.js +36 -0
- package/out/zero-cache/src/config/zero-config.js.map +1 -1
- package/out/zero-cache/src/observability/log-throttle.d.ts +44 -0
- package/out/zero-cache/src/observability/log-throttle.d.ts.map +1 -0
- package/out/zero-cache/src/observability/log-throttle.js +76 -0
- package/out/zero-cache/src/observability/log-throttle.js.map +1 -0
- package/out/zero-cache/src/scripts/permissions.d.ts +16 -0
- package/out/zero-cache/src/scripts/permissions.d.ts.map +1 -1
- package/out/zero-cache/src/server/runner/zero-dispatcher.d.ts.map +1 -1
- package/out/zero-cache/src/server/runner/zero-dispatcher.js +2 -0
- package/out/zero-cache/src/server/runner/zero-dispatcher.js.map +1 -1
- package/out/zero-cache/src/server/syncer.d.ts.map +1 -1
- package/out/zero-cache/src/server/syncer.js +20 -2
- package/out/zero-cache/src/server/syncer.js.map +1 -1
- package/out/zero-cache/src/services/change-source/common/backfill-manager.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/common/backfill-manager.js +27 -15
- package/out/zero-cache/src/services/change-source/common/backfill-manager.js.map +1 -1
- package/out/zero-cache/src/services/change-source/common/replica-schema.d.ts +1 -0
- package/out/zero-cache/src/services/change-source/common/replica-schema.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/common/replica-schema.js +15 -3
- package/out/zero-cache/src/services/change-source/common/replica-schema.js.map +1 -1
- package/out/zero-cache/src/services/change-source/custom/change-source.js +2 -2
- 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.d.ts +9 -0
- package/out/zero-cache/src/services/change-source/pg/backfill-stream.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/backfill-stream.js +204 -18
- package/out/zero-cache/src/services/change-source/pg/backfill-stream.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/initial-sync.d.ts +11 -2
- package/out/zero-cache/src/services/change-source/pg/initial-sync.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/initial-sync.js +11 -2
- package/out/zero-cache/src/services/change-source/pg/initial-sync.js.map +1 -1
- package/out/zero-cache/src/services/change-source/protocol/backfill-progress.d.ts +68 -0
- package/out/zero-cache/src/services/change-source/protocol/backfill-progress.d.ts.map +1 -0
- package/out/zero-cache/src/services/change-source/protocol/backfill-progress.js +141 -0
- package/out/zero-cache/src/services/change-source/protocol/backfill-progress.js.map +1 -0
- package/out/zero-cache/src/services/change-source/protocol/current/data.d.ts +43 -0
- package/out/zero-cache/src/services/change-source/protocol/current/data.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/protocol/current/data.js +10 -1
- package/out/zero-cache/src/services/change-source/protocol/current/data.js.map +1 -1
- package/out/zero-cache/src/services/change-source/protocol/current/downstream.d.ts +57 -0
- package/out/zero-cache/src/services/change-source/protocol/current/downstream.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/protocol/current/upstream.d.ts +20 -6
- package/out/zero-cache/src/services/change-source/protocol/current/upstream.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/protocol/current/upstream.js +17 -7
- package/out/zero-cache/src/services/change-source/protocol/current/upstream.js.map +1 -1
- package/out/zero-cache/src/services/change-source/protocol/current.js +2 -1
- package/out/zero-cache/src/services/change-streamer/backfill-state-tracker.d.ts +66 -0
- package/out/zero-cache/src/services/change-streamer/backfill-state-tracker.d.ts.map +1 -0
- package/out/zero-cache/src/services/change-streamer/backfill-state-tracker.js +154 -0
- package/out/zero-cache/src/services/change-streamer/backfill-state-tracker.js.map +1 -0
- package/out/zero-cache/src/services/change-streamer/backfill-state.d.ts +50 -0
- package/out/zero-cache/src/services/change-streamer/backfill-state.d.ts.map +1 -0
- package/out/zero-cache/src/services/change-streamer/backfill-state.js +268 -0
- package/out/zero-cache/src/services/change-streamer/backfill-state.js.map +1 -0
- package/out/zero-cache/src/services/change-streamer/change-streamer-http.js +7 -6
- 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.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/change-streamer-service.js +20 -4
- 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.d.ts +26 -1
- package/out/zero-cache/src/services/change-streamer/change-streamer.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/change-streamer.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/storer.d.ts.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.d.ts +88 -0
- package/out/zero-cache/src/services/change-streamer/subscribe.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/subscribe.js +9 -1
- package/out/zero-cache/src/services/change-streamer/subscribe.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/subscriber.d.ts +29 -0
- package/out/zero-cache/src/services/change-streamer/subscriber.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/subscriber.js +34 -0
- package/out/zero-cache/src/services/change-streamer/subscriber.js.map +1 -1
- package/out/zero-cache/src/services/plannerz.d.ts +159 -0
- package/out/zero-cache/src/services/plannerz.d.ts.map +1 -0
- package/out/zero-cache/src/services/plannerz.js +263 -0
- package/out/zero-cache/src/services/plannerz.js.map +1 -0
- package/out/zero-cache/src/services/replicator/change-log-cookies.js +1 -1
- package/out/zero-cache/src/services/replicator/change-log-cookies.js.map +1 -1
- package/out/zero-cache/src/services/replicator/change-processor.d.ts.map +1 -1
- package/out/zero-cache/src/services/replicator/change-processor.js +44 -12
- package/out/zero-cache/src/services/replicator/change-processor.js.map +1 -1
- package/out/zero-cache/src/services/replicator/incremental-sync.d.ts.map +1 -1
- package/out/zero-cache/src/services/replicator/incremental-sync.js +4 -3
- package/out/zero-cache/src/services/replicator/incremental-sync.js.map +1 -1
- package/out/zero-cache/src/services/replicator/schema/backfilling.d.ts +23 -2
- package/out/zero-cache/src/services/replicator/schema/backfilling.d.ts.map +1 -1
- package/out/zero-cache/src/services/replicator/schema/backfilling.js +54 -2
- package/out/zero-cache/src/services/replicator/schema/backfilling.js.map +1 -1
- package/out/zero-cache/src/services/replicator/write-worker-client.d.ts +11 -3
- package/out/zero-cache/src/services/replicator/write-worker-client.d.ts.map +1 -1
- package/out/zero-cache/src/services/replicator/write-worker-client.js.map +1 -1
- package/out/zero-cache/src/services/replicator/write-worker.js +5 -1
- package/out/zero-cache/src/services/replicator/write-worker.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/deferred-writes-budget.d.ts +81 -0
- package/out/zero-cache/src/services/view-syncer/deferred-writes-budget.d.ts.map +1 -0
- package/out/zero-cache/src/services/view-syncer/deferred-writes-budget.js +128 -0
- package/out/zero-cache/src/services/view-syncer/deferred-writes-budget.js.map +1 -0
- package/out/zero-cache/src/services/view-syncer/inspect-handler.js +1 -1
- package/out/zero-cache/src/services/view-syncer/pipeline-driver.d.ts +36 -1
- package/out/zero-cache/src/services/view-syncer/pipeline-driver.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/pipeline-driver.js +362 -20
- package/out/zero-cache/src/services/view-syncer/pipeline-driver.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/plan-warnings.d.ts +7 -0
- package/out/zero-cache/src/services/view-syncer/plan-warnings.d.ts.map +1 -0
- package/out/zero-cache/src/services/view-syncer/plan-warnings.js +35 -0
- package/out/zero-cache/src/services/view-syncer/plan-warnings.js.map +1 -0
- package/out/zero-cache/src/services/view-syncer/query-shape.d.ts +25 -0
- package/out/zero-cache/src/services/view-syncer/query-shape.d.ts.map +1 -0
- package/out/zero-cache/src/services/view-syncer/query-shape.js +28 -0
- package/out/zero-cache/src/services/view-syncer/query-shape.js.map +1 -0
- package/out/zero-cache/src/services/view-syncer/query-stats.d.ts +77 -0
- package/out/zero-cache/src/services/view-syncer/query-stats.d.ts.map +1 -0
- package/out/zero-cache/src/services/view-syncer/query-stats.js +206 -0
- package/out/zero-cache/src/services/view-syncer/query-stats.js.map +1 -0
- package/out/zero-cache/src/services/view-syncer/snapshotter.d.ts +11 -1
- package/out/zero-cache/src/services/view-syncer/snapshotter.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/snapshotter.js +7 -1
- package/out/zero-cache/src/services/view-syncer/snapshotter.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/view-syncer.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/view-syncer.js +49 -3
- package/out/zero-cache/src/services/view-syncer/view-syncer.js.map +1 -1
- package/out/zero-cache/src/workers/connection.js +3 -3
- package/out/zero-cache/src/workers/connection.js.map +1 -1
- package/out/zero-cache/src/workers/syncer.js +2 -2
- package/out/zero-cache/src/workers/syncer.js.map +1 -1
- package/out/zero-client/src/client/options.d.ts +29 -0
- 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/version.js +1 -1
- package/out/zero-client/src/client/zero.d.ts.map +1 -1
- package/out/zero-client/src/client/zero.js +8 -23
- package/out/zero-client/src/client/zero.js.map +1 -1
- package/out/zero-client/src/mod.d.ts +1 -0
- package/out/zero-client/src/mod.d.ts.map +1 -1
- package/out/zero-client/src/mod.js +1 -0
- package/out/zero-protocol/src/down.d.ts +2 -2
- package/out/zero-react/src/zero.js +1 -0
- package/out/zero-solid/src/zero.js +1 -0
- package/out/zql/src/builder/builder.d.ts +6 -0
- package/out/zql/src/builder/builder.d.ts.map +1 -1
- package/out/zql/src/builder/builder.js +4 -3
- package/out/zql/src/builder/builder.js.map +1 -1
- package/out/zql/src/ivm/memory-source.d.ts +13 -0
- 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/planner/planner-builder.d.ts +12 -1
- package/out/zql/src/planner/planner-builder.d.ts.map +1 -1
- package/out/zql/src/planner/planner-builder.js +8 -1
- package/out/zql/src/planner/planner-builder.js.map +1 -1
- package/out/zql/src/planner/planner-connection.d.ts +43 -0
- package/out/zql/src/planner/planner-connection.d.ts.map +1 -1
- package/out/zql/src/planner/planner-connection.js +31 -4
- package/out/zql/src/planner/planner-connection.js.map +1 -1
- package/out/zql/src/planner/planner-graph.d.ts +10 -0
- package/out/zql/src/planner/planner-graph.d.ts.map +1 -1
- package/out/zql/src/planner/planner-graph.js +14 -0
- package/out/zql/src/planner/planner-graph.js.map +1 -1
- package/out/zql/src/planner/planner-warnings.d.ts +83 -0
- package/out/zql/src/planner/planner-warnings.d.ts.map +1 -0
- package/out/zql/src/planner/planner-warnings.js +78 -0
- package/out/zql/src/planner/planner-warnings.js.map +1 -0
- package/out/zql/src/query/measure-push-operator.d.ts.map +1 -1
- package/out/zql/src/query/measure-push-operator.js +30 -8
- package/out/zql/src/query/measure-push-operator.js.map +1 -1
- package/out/zqlite/src/pending-delta.d.ts +110 -0
- package/out/zqlite/src/pending-delta.d.ts.map +1 -0
- package/out/zqlite/src/pending-delta.js +278 -0
- package/out/zqlite/src/pending-delta.js.map +1 -0
- package/out/zqlite/src/query-delegate.d.ts.map +1 -1
- package/out/zqlite/src/query-delegate.js +5 -1
- package/out/zqlite/src/query-delegate.js.map +1 -1
- package/out/zqlite/src/sqlite-cost-model.d.ts.map +1 -1
- package/out/zqlite/src/sqlite-cost-model.js +52 -1
- package/out/zqlite/src/sqlite-cost-model.js.map +1 -1
- package/out/zqlite/src/sqlite-stat-fanout.d.ts.map +1 -1
- package/out/zqlite/src/sqlite-stat-fanout.js +2 -26
- package/out/zqlite/src/sqlite-stat-fanout.js.map +1 -1
- package/out/zqlite/src/sqlite-stat4-sample.d.ts +37 -0
- package/out/zqlite/src/sqlite-stat4-sample.d.ts.map +1 -0
- package/out/zqlite/src/sqlite-stat4-sample.js +61 -0
- package/out/zqlite/src/sqlite-stat4-sample.js.map +1 -0
- package/out/zqlite/src/table-source.d.ts +68 -0
- package/out/zqlite/src/table-source.d.ts.map +1 -1
- package/out/zqlite/src/table-source.js +206 -7
- package/out/zqlite/src/table-source.js.map +1 -1
- package/package.json +1 -1
- package/out/replicache/src/kv/idb-store-with-mem-fallback.d.ts +0 -35
- package/out/replicache/src/kv/idb-store-with-mem-fallback.d.ts.map +0 -1
- package/out/replicache/src/kv/idb-store-with-mem-fallback.js +0 -83
- package/out/replicache/src/kv/idb-store-with-mem-fallback.js.map +0 -1
- package/out/zero-cache/src/services/change-source/pg/backfill-resume.d.ts +0 -156
- package/out/zero-cache/src/services/change-source/pg/backfill-resume.d.ts.map +0 -1
- package/out/zero-cache/src/services/change-source/pg/backfill-resume.js +0 -15
- package/out/zero-cache/src/services/change-source/pg/backfill-resume.js.map +0 -1
|
@@ -3,8 +3,9 @@ import { assertCookie } from "./cookies.js";
|
|
|
3
3
|
import { isClientStateNotFoundResponse, isVersionNotSupportedResponse } from "./error-responses.js";
|
|
4
4
|
import { getDefaultPuller, isDefaultPuller } from "./get-default-puller.js";
|
|
5
5
|
import { getBrowserGlobal } from "../../shared/src/browser-env.js";
|
|
6
|
-
import { promiseVoid } from "../../shared/src/resolved-promises.js";
|
|
6
|
+
import { promiseFalse, promiseVoid } from "../../shared/src/resolved-promises.js";
|
|
7
7
|
import { deepFreeze } from "./frozen-json.js";
|
|
8
|
+
import { getStorageFailure } from "./storage-failure.js";
|
|
8
9
|
import { makeIDBName } from "./make-idb-name.js";
|
|
9
10
|
import { AbortError } from "../../shared/src/abort-error.js";
|
|
10
11
|
import { InvalidRefCountError } from "./dag/invalid-ref-count-error.js";
|
|
@@ -19,6 +20,7 @@ import { disableClientGroup } from "./persist/client-groups.js";
|
|
|
19
20
|
import { makeClientID } from "./persist/make-client-id.js";
|
|
20
21
|
import { ClientStateNotFoundError, hasClientState, initClientV6 } from "./persist/clients.js";
|
|
21
22
|
import { getKVStoreProvider } from "./get-kv-store-provider.js";
|
|
23
|
+
import { MemFallbackStoreProvider } from "./kv/mem-fallback-store.js";
|
|
22
24
|
import { createLogContext } from "./log-options.js";
|
|
23
25
|
import { IDBDatabasesStore } from "./persist/idb-databases-store.js";
|
|
24
26
|
import { COLLECT_IDB_INTERVAL, INITIAL_COLLECT_IDB_DELAY, dropDatabaseInternal, initCollectIDBDatabases } from "./persist/collect-idb-databases.js";
|
|
@@ -100,12 +102,12 @@ var ReplicacheImpl = class {
|
|
|
100
102
|
return makeIDBName(this.name, this.schemaVersion);
|
|
101
103
|
}
|
|
102
104
|
/**
|
|
103
|
-
* The KV store backing this instance.
|
|
104
|
-
*
|
|
105
|
-
*
|
|
105
|
+
* The KV store backing this instance. It is a memory store once a storage
|
|
106
|
+
* failure while opening moved the instance onto memory (see
|
|
107
|
+
* `onStorageFailure`).
|
|
106
108
|
*/
|
|
107
109
|
get kvStore() {
|
|
108
|
-
return this.#perKVStore;
|
|
110
|
+
return this.#perKVStore.backing;
|
|
109
111
|
}
|
|
110
112
|
set auth(auth) {
|
|
111
113
|
if (this.#zero) this.#zero.auth = auth;
|
|
@@ -171,6 +173,16 @@ var ReplicacheImpl = class {
|
|
|
171
173
|
#lc;
|
|
172
174
|
#zero;
|
|
173
175
|
#closeAbortController = new AbortController();
|
|
176
|
+
/**
|
|
177
|
+
* Aborted on close AND on a storage failure after the open. The store-using
|
|
178
|
+
* background processes (heartbeat, client and client-group GC, database
|
|
179
|
+
* collection, mutation recovery, the new-client channel's store read) run
|
|
180
|
+
* on this signal, so the first detected failure stops them instead of
|
|
181
|
+
* letting each retry the fault at its interval and log `Error running.`
|
|
182
|
+
* every time. A failure during the open moves the stores onto memory
|
|
183
|
+
* instead, where they keep running.
|
|
184
|
+
*/
|
|
185
|
+
#storeProcessesAbortController = new AbortController();
|
|
174
186
|
#persistLock = new Lock();
|
|
175
187
|
#enableScheduledPersist;
|
|
176
188
|
#enableScheduledRefresh;
|
|
@@ -217,6 +229,51 @@ var ReplicacheImpl = class {
|
|
|
217
229
|
*/
|
|
218
230
|
onClientStateNotFound = reload;
|
|
219
231
|
/**
|
|
232
|
+
* `onStorageFailure` is called once, the first time the local kv store
|
|
233
|
+
* reports that its storage has failed rather than its data, by throwing a
|
|
234
|
+
* {@link StorageFailureError}: the device is out of space (`full`), the
|
|
235
|
+
* database cannot be opened (`cannot-open`), or a read or write to it failed
|
|
236
|
+
* (`io-error`). The SQLite stores and the IndexedDB store report these; a
|
|
237
|
+
* custom `StoreProvider` can throw a `StorageFailureError` itself.
|
|
238
|
+
*
|
|
239
|
+
* A failure while the instance is opening moves it onto memory for the
|
|
240
|
+
* session, where it runs as with `kvStore: 'mem'`: it persists and
|
|
241
|
+
* refreshes against the memory stores, and nothing reaches the disk.
|
|
242
|
+
*
|
|
243
|
+
* A failure after that stops persisting and refreshing: a rebuild would
|
|
244
|
+
* open the same failing storage, and a wipe would destroy an intact replica
|
|
245
|
+
* for a fault that is not in the data. Queries and mutations keep running
|
|
246
|
+
* against what the in-memory dag holds, and mutations keep pushing to the
|
|
247
|
+
* server, but nothing is persisted locally until the app creates a new
|
|
248
|
+
* instance. A read that needs a chunk the in-memory dag has not loaded from
|
|
249
|
+
* the store yet, or has since evicted from its cache, still goes to the
|
|
250
|
+
* store and fails the way any store read does; that failure reaches its
|
|
251
|
+
* caller and is not reclassified here. An invalid ref count reported while
|
|
252
|
+
* the store is failing with `cannot-open` or `io-error` is NOT treated as
|
|
253
|
+
* corruption (the database is not dropped and {@link onClientStateNotFound}
|
|
254
|
+
* is not called), because a store that cannot complete a read or write is
|
|
255
|
+
* what produces such readings. A `full` disk keeps the drop: a torn write
|
|
256
|
+
* there is real corruption, and deleting the database is also what frees
|
|
257
|
+
* the space.
|
|
258
|
+
*
|
|
259
|
+
* After the open, the failure is detected when a transaction on the store
|
|
260
|
+
* fails to begin or to commit, whichever caller ran it (`persist()`, the
|
|
261
|
+
* heartbeat, garbage collection, ...), and when `persist()` or `refresh()`
|
|
262
|
+
* fails. The background maintenance processes (heartbeat, client and
|
|
263
|
+
* client-group GC, database collection, mutation recovery) stop on it
|
|
264
|
+
* instead of retrying against the store at their interval.
|
|
265
|
+
*
|
|
266
|
+
* There is no default behavior other than logging. An app that shows a
|
|
267
|
+
* "free up space" or "restart" screen can do so from here.
|
|
268
|
+
*/
|
|
269
|
+
onStorageFailure = null;
|
|
270
|
+
/**
|
|
271
|
+
* Set the first time the kv store reports a storage failure. Read by every
|
|
272
|
+
* path that writes the perdag so none of them retries against storage
|
|
273
|
+
* that has failed.
|
|
274
|
+
*/
|
|
275
|
+
#storageFailure;
|
|
276
|
+
/**
|
|
220
277
|
* `onUpdateNeeded` is called when a code update is needed.
|
|
221
278
|
*
|
|
222
279
|
* A code update can be needed because:
|
|
@@ -268,8 +325,9 @@ var ReplicacheImpl = class {
|
|
|
268
325
|
name,
|
|
269
326
|
"replicache version": version
|
|
270
327
|
});
|
|
328
|
+
this.#closeAbortController.signal.addEventListener("abort", () => this.#storeProcessesAbortController.abort(), { once: true });
|
|
271
329
|
this.#subscriptions = new SubscriptionsManagerImpl(this.#queryInternal, this.#lc, this.#closeAbortController.signal);
|
|
272
|
-
const kvStoreProvider = getKVStoreProvider(this.#lc, options.kvStore);
|
|
330
|
+
const kvStoreProvider = new MemFallbackStoreProvider(getKVStoreProvider(this.#lc, options.kvStore), (failure) => this.#onMemFallBack(failure), (failure) => this.#handleStorageFailure(failure));
|
|
273
331
|
this.#kvStoreProvider = kvStoreProvider;
|
|
274
332
|
const perKVStore = kvStoreProvider.create(this.idbName);
|
|
275
333
|
this.#perKVStore = perKVStore;
|
|
@@ -294,12 +352,19 @@ var ReplicacheImpl = class {
|
|
|
294
352
|
this.#onPersist = initOnPersistChannel(this.name, this.#closeAbortController.signal, (persistInfo) => {
|
|
295
353
|
this.#handlePersist(persistInfo);
|
|
296
354
|
});
|
|
297
|
-
this.#open(indexes, enableClientGroupForking, enableMutationRecovery, clientMaxAgeMs, profileIDResolver.resolve, clientGroupIDResolver.resolve, readyResolver.resolve, onClientsDeleted)
|
|
298
|
-
|
|
355
|
+
const open = () => this.#open(indexes, enableClientGroupForking, enableMutationRecovery, clientMaxAgeMs, profileIDResolver.resolve, clientGroupIDResolver.resolve, readyResolver.resolve, onClientsDeleted);
|
|
356
|
+
open().catch((e) => {
|
|
299
357
|
if (e instanceof InvalidRefCountError) {
|
|
358
|
+
this.#openFailed.resolve();
|
|
300
359
|
this.#lc.debug?.("Open failed because the persistent store is corrupt");
|
|
301
360
|
return;
|
|
302
361
|
}
|
|
362
|
+
if (!this.#closed && this.#kvStoreProvider.fallBack(e)) return open().catch((e) => {
|
|
363
|
+
this.#openFailed.resolve();
|
|
364
|
+
if (this.#closed) this.#lc.debug?.("Open on memory ended by close", e);
|
|
365
|
+
else this.#lc.error?.("Open failed again on memory", e);
|
|
366
|
+
});
|
|
367
|
+
this.#openFailed.resolve();
|
|
303
368
|
throw e;
|
|
304
369
|
});
|
|
305
370
|
}
|
|
@@ -316,12 +381,13 @@ var ReplicacheImpl = class {
|
|
|
316
381
|
if (dbOpenMs > SLOW_DB_OPEN_THRESHOLD_MS) this.#lc.warn?.(`Opening the database took ${Math.round(dbOpenMs)}ms`, { name: this.idbName });
|
|
317
382
|
else this.#lc.debug?.("Opened the database in", Math.round(dbOpenMs), "ms");
|
|
318
383
|
await this.#zero?.init(headHash, this.memdag);
|
|
384
|
+
this.#kvStoreProvider.opened();
|
|
319
385
|
resolveReady();
|
|
320
386
|
if (this.#enablePullAndPushInOpen) {
|
|
321
387
|
this.pull().catch(noop);
|
|
322
388
|
this.push().catch(noop);
|
|
323
389
|
}
|
|
324
|
-
const { signal } = this.#
|
|
390
|
+
const { signal } = this.#storeProcessesAbortController;
|
|
325
391
|
startHeartbeats(clientID, this.perdag, () => {
|
|
326
392
|
this.#clientStateNotFoundOnClient(clientID);
|
|
327
393
|
}, HEARTBEAT_INTERVAL, this.#lc, signal);
|
|
@@ -336,7 +402,7 @@ var ReplicacheImpl = class {
|
|
|
336
402
|
getBrowserGlobal("document")?.addEventListener("visibilitychange", this.#onVisibilityChange);
|
|
337
403
|
}
|
|
338
404
|
#onVisibilityChange = async () => {
|
|
339
|
-
if (this.#closed) return;
|
|
405
|
+
if (this.#closed || this.#storageFailure !== void 0) return;
|
|
340
406
|
if (getBrowserGlobal("document")?.visibilityState !== "visible") return;
|
|
341
407
|
await this.#checkForClientStateNotFoundAndCallHandler();
|
|
342
408
|
};
|
|
@@ -653,7 +719,7 @@ var ReplicacheImpl = class {
|
|
|
653
719
|
return this.#persistLock.withLock(async () => {
|
|
654
720
|
const { clientID } = this;
|
|
655
721
|
await this.#ready;
|
|
656
|
-
if (this.#closed) return;
|
|
722
|
+
if (this.#closed || this.#storageFailure) return;
|
|
657
723
|
try {
|
|
658
724
|
await persistDD31(this.#lc, clientID, this.memdag, this.perdag, this.#mutatorRegistry, () => this.#closed, 7, this.#zero?.getTxData);
|
|
659
725
|
} catch (e) {
|
|
@@ -662,7 +728,12 @@ var ReplicacheImpl = class {
|
|
|
662
728
|
await this.#handleInvalidRefCount(e);
|
|
663
729
|
return;
|
|
664
730
|
} else if (this.#closed) this.#lc.debug?.("Exception persisting during close", e);
|
|
665
|
-
else
|
|
731
|
+
else {
|
|
732
|
+
const failure = getStorageFailure(e);
|
|
733
|
+
if (failure === void 0) throw e;
|
|
734
|
+
this.#handleStorageFailure(failure);
|
|
735
|
+
return;
|
|
736
|
+
}
|
|
666
737
|
}
|
|
667
738
|
const clientGroupID = await this.#clientGroupIDPromise;
|
|
668
739
|
assert(clientGroupID, "Expected clientGroupID to be defined");
|
|
@@ -675,7 +746,7 @@ var ReplicacheImpl = class {
|
|
|
675
746
|
async refresh() {
|
|
676
747
|
await this.#ready;
|
|
677
748
|
const { clientID } = this;
|
|
678
|
-
if (this.#closed || !this.#enableRefresh()) return;
|
|
749
|
+
if (this.#closed || this.#storageFailure || !this.#enableRefresh()) return;
|
|
679
750
|
let refreshResult;
|
|
680
751
|
try {
|
|
681
752
|
refreshResult = await refresh(this.#lc, this.memdag, this.perdag, clientID, this.#mutatorRegistry, this.#subscriptions, () => this.closed, 7, this.#zero);
|
|
@@ -683,7 +754,12 @@ var ReplicacheImpl = class {
|
|
|
683
754
|
if (e instanceof ClientStateNotFoundError) this.#clientStateNotFoundOnClient(clientID);
|
|
684
755
|
else if (e instanceof InvalidRefCountError) await this.#handleInvalidRefCount(e);
|
|
685
756
|
else if (this.#closed) this.#lc.debug?.("Exception refreshing during close", e);
|
|
686
|
-
else
|
|
757
|
+
else {
|
|
758
|
+
const failure = getStorageFailure(e);
|
|
759
|
+
if (failure === void 0) throw e;
|
|
760
|
+
this.#handleStorageFailure(failure);
|
|
761
|
+
return;
|
|
762
|
+
}
|
|
687
763
|
}
|
|
688
764
|
if (refreshResult !== void 0) await this.#subscriptions.fire(refreshResult.diffs);
|
|
689
765
|
}
|
|
@@ -701,6 +777,42 @@ var ReplicacheImpl = class {
|
|
|
701
777
|
*/
|
|
702
778
|
#corruptDatabaseRecovery;
|
|
703
779
|
/**
|
|
780
|
+
* A storage failure after the open. Records the first one, stops the
|
|
781
|
+
* store-using background processes, logs it once and tells the app. Later
|
|
782
|
+
* failures of the same instance are the same fault and are not reported
|
|
783
|
+
* again; the scheduled persist and refresh stop asking.
|
|
784
|
+
*/
|
|
785
|
+
#handleStorageFailure(failure) {
|
|
786
|
+
if (this.#storageFailure !== void 0) return;
|
|
787
|
+
this.#storageFailure = failure;
|
|
788
|
+
this.#storeProcessesAbortController.abort();
|
|
789
|
+
this.#lc.warn?.(`Local store storage failed (${failure.kind}) for ${this.idbName}; persistence is stopped for this instance`, failure);
|
|
790
|
+
this.#fireOnStorageFailure(failure);
|
|
791
|
+
}
|
|
792
|
+
/**
|
|
793
|
+
* A storage failure during the open: the stores have moved onto memory, so
|
|
794
|
+
* the instance runs on them for the session, as with `kvStore: 'mem'`.
|
|
795
|
+
* Reported on a
|
|
796
|
+
* later microtask: the SQLite stores open in `create`, while the
|
|
797
|
+
* constructor is still running and before the app can attach the callback.
|
|
798
|
+
*/
|
|
799
|
+
#onMemFallBack(failure) {
|
|
800
|
+
this.#lc.warn?.(`Local store storage failed (${failure.kind}) opening ${this.idbName}; running this instance in memory`, failure);
|
|
801
|
+
queueMicrotask(() => this.#fireOnStorageFailure(failure));
|
|
802
|
+
}
|
|
803
|
+
/**
|
|
804
|
+
* The app's callback must not be able to stop the recovery around it: in
|
|
805
|
+
* the open path, a throw here would skip the open on memory and leave the
|
|
806
|
+
* instance never ready.
|
|
807
|
+
*/
|
|
808
|
+
#fireOnStorageFailure(failure) {
|
|
809
|
+
try {
|
|
810
|
+
this.onStorageFailure?.(failure);
|
|
811
|
+
} catch (e) {
|
|
812
|
+
this.#lc.error?.("onStorageFailure threw", e);
|
|
813
|
+
}
|
|
814
|
+
}
|
|
815
|
+
/**
|
|
704
816
|
* Installed on the dag store that writes to our database. The store calls
|
|
705
817
|
* it after the failing transaction has been released, so dropping the
|
|
706
818
|
* database from here does not race with the rollback.
|
|
@@ -728,6 +840,10 @@ var ReplicacheImpl = class {
|
|
|
728
840
|
* something we don't expect to ever happen.
|
|
729
841
|
*/
|
|
730
842
|
#handleInvalidRefCount(e) {
|
|
843
|
+
if (this.#storageFailure !== void 0 && this.#storageFailure.kind !== "full") {
|
|
844
|
+
this.#lc.warn?.(`Invalid ref count while the local store is failing (${this.#storageFailure.kind}); not dropping database ${this.idbName}`, e);
|
|
845
|
+
return promiseVoid;
|
|
846
|
+
}
|
|
731
847
|
if (this.#corruptDatabaseRecovery === void 0) {
|
|
732
848
|
this.#lc.error?.(`Client state is corrupt on client, clientID: ${this.clientID}. Dropping database ${this.idbName}`, e);
|
|
733
849
|
this.#corruptDatabaseRecovery = this.#dropDatabaseAndFireOnClientStateNotFound();
|
|
@@ -774,7 +890,7 @@ var ReplicacheImpl = class {
|
|
|
774
890
|
this.onUpdateNeeded?.(reason);
|
|
775
891
|
}
|
|
776
892
|
async #schedulePersist() {
|
|
777
|
-
if (!this.#enableScheduledPersist) return;
|
|
893
|
+
if (!this.#enableScheduledPersist || this.#storageFailure) return;
|
|
778
894
|
await this.#schedule("persist", this.#persistScheduler);
|
|
779
895
|
}
|
|
780
896
|
async #handlePersist(persistInfo) {
|
|
@@ -783,7 +899,7 @@ var ReplicacheImpl = class {
|
|
|
783
899
|
if (persistInfo.clientGroupID === clientGroupID) this.#scheduleRefresh();
|
|
784
900
|
}
|
|
785
901
|
async #scheduleRefresh() {
|
|
786
|
-
if (!this.#enableScheduledRefresh) return;
|
|
902
|
+
if (!this.#enableScheduledRefresh || this.#storageFailure) return;
|
|
787
903
|
await this.#schedule("refresh from storage", this.#refreshScheduler);
|
|
788
904
|
}
|
|
789
905
|
async #schedule(name, scheduler) {
|
|
@@ -941,7 +1057,9 @@ var ReplicacheImpl = class {
|
|
|
941
1057
|
if (ex instanceof ChunkNotFoundError && await this.#checkForClientStateNotFoundAndCallHandler()) return new ClientStateNotFoundError(this.clientID);
|
|
942
1058
|
return ex;
|
|
943
1059
|
}
|
|
944
|
-
recoverMutations() {
|
|
1060
|
+
recoverMutations() {
|
|
1061
|
+
if (this.#storeProcessesAbortController.signal.aborted) return promiseFalse;
|
|
1062
|
+
}
|
|
945
1063
|
/**
|
|
946
1064
|
* List of pending mutations. The order of this is from oldest to newest.
|
|
947
1065
|
*
|