@rocicorp/zero 1.10.0-canary.2 → 1.10.0-canary.3
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/zero/package.js +1 -1
- package/out/zero/package.js.map +1 -1
- package/out/zero-cache/src/auth/write-authorizer.d.ts.map +1 -1
- package/out/zero-cache/src/auth/write-authorizer.js +8 -1
- package/out/zero-cache/src/auth/write-authorizer.js.map +1 -1
- package/out/zero-cache/src/config/normalize.d.ts.map +1 -1
- package/out/zero-cache/src/config/normalize.js +7 -2
- package/out/zero-cache/src/config/normalize.js.map +1 -1
- package/out/zero-cache/src/config/zero-config.d.ts +14 -4
- package/out/zero-cache/src/config/zero-config.d.ts.map +1 -1
- package/out/zero-cache/src/config/zero-config.js +26 -8
- package/out/zero-cache/src/config/zero-config.js.map +1 -1
- package/out/zero-cache/src/db/transaction-pool.d.ts +5 -2
- package/out/zero-cache/src/db/transaction-pool.d.ts.map +1 -1
- package/out/zero-cache/src/db/transaction-pool.js +5 -3
- package/out/zero-cache/src/db/transaction-pool.js.map +1 -1
- package/out/zero-cache/src/server/change-streamer.d.ts.map +1 -1
- package/out/zero-cache/src/server/change-streamer.js +24 -13
- package/out/zero-cache/src/server/change-streamer.js.map +1 -1
- package/out/zero-cache/src/server/runner/run-worker.js +1 -1
- package/out/zero-cache/src/server/worker-urls.d.ts +0 -1
- package/out/zero-cache/src/server/worker-urls.d.ts.map +1 -1
- package/out/zero-cache/src/server/worker-urls.js +1 -2
- package/out/zero-cache/src/server/worker-urls.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/decommission.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/decommission.js +20 -11
- package/out/zero-cache/src/services/change-source/pg/decommission.js.map +1 -1
- 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 +51 -74
- package/out/zero-cache/src/services/change-source/pg/initial-sync.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/logical-replication/stream.d.ts +20 -0
- package/out/zero-cache/src/services/change-source/pg/logical-replication/stream.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/logical-replication/stream.js +43 -3
- package/out/zero-cache/src/services/change-source/pg/logical-replication/stream.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/replication-slots.d.ts +24 -1
- package/out/zero-cache/src/services/change-source/pg/replication-slots.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/replication-slots.js +35 -5
- package/out/zero-cache/src/services/change-source/pg/replication-slots.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/backup-cleanup-monitor-factory.d.ts +1 -4
- package/out/zero-cache/src/services/change-streamer/backup-cleanup-monitor-factory.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/backup-cleanup-monitor-factory.js +11 -18
- package/out/zero-cache/src/services/change-streamer/backup-cleanup-monitor-factory.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/backup-monitor.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/backup-monitor.js +8 -3
- package/out/zero-cache/src/services/change-streamer/backup-monitor.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/change-log-compare-digest.d.ts +34 -0
- package/out/zero-cache/src/services/change-streamer/change-log-compare-digest.d.ts.map +1 -0
- package/out/zero-cache/src/services/change-streamer/change-log-compare-digest.js +67 -0
- package/out/zero-cache/src/services/change-streamer/change-log-compare-digest.js.map +1 -0
- package/out/zero-cache/src/services/change-streamer/change-streamer-http.d.ts +2 -4
- package/out/zero-cache/src/services/change-streamer/change-streamer-http.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/change-streamer-http.js +8 -2
- 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 +34 -13
- 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 +149 -27
- 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 +3 -9
- 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/shard-sampling.d.ts +11 -0
- package/out/zero-cache/src/services/change-streamer/shard-sampling.d.ts.map +1 -0
- package/out/zero-cache/src/services/change-streamer/shard-sampling.js +19 -0
- package/out/zero-cache/src/services/change-streamer/shard-sampling.js.map +1 -0
- package/out/zero-cache/src/services/change-streamer/snapshot-reservations.d.ts +11 -1
- package/out/zero-cache/src/services/change-streamer/snapshot-reservations.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/snapshot-reservations.js +38 -5
- package/out/zero-cache/src/services/change-streamer/snapshot-reservations.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-catchup.d.ts +25 -1
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-catchup.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-catchup.js +95 -12
- 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-comparator.d.ts +83 -0
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-comparator.d.ts.map +1 -0
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-comparator.js +417 -0
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-comparator.js.map +1 -0
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-read-router.d.ts +73 -0
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-read-router.d.ts.map +1 -0
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-read-router.js +157 -0
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-read-router.js.map +1 -0
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-reader.d.ts +1 -1
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-reader.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-reader.js +8 -3
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-reader.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/storer.d.ts +23 -0
- package/out/zero-cache/src/services/change-streamer/storer.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/storer.js +40 -0
- package/out/zero-cache/src/services/change-streamer/storer.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/vfs-watermark-poller.d.ts +29 -0
- package/out/zero-cache/src/services/change-streamer/vfs-watermark-poller.d.ts.map +1 -0
- package/out/zero-cache/src/services/change-streamer/vfs-watermark-poller.js +154 -0
- package/out/zero-cache/src/services/change-streamer/vfs-watermark-poller.js.map +1 -0
- package/out/zero-cache/src/services/http-service.d.ts +1 -0
- package/out/zero-cache/src/services/http-service.d.ts.map +1 -1
- package/out/zero-cache/src/services/http-service.js +7 -3
- package/out/zero-cache/src/services/http-service.js.map +1 -1
- package/out/zero-cache/src/services/litestream/metrics.d.ts +1 -0
- package/out/zero-cache/src/services/litestream/metrics.d.ts.map +1 -1
- package/out/zero-cache/src/services/litestream/metrics.js +4 -1
- package/out/zero-cache/src/services/litestream/metrics.js.map +1 -1
- package/out/zero-cache/src/services/mutagen/mutagen.d.ts.map +1 -1
- package/out/zero-cache/src/services/mutagen/mutagen.js +1 -1
- package/out/zero-cache/src/services/mutagen/mutagen.js.map +1 -1
- package/out/zero-cache/src/services/replicator/change-log-db.d.ts +10 -0
- package/out/zero-cache/src/services/replicator/change-log-db.d.ts.map +1 -1
- package/out/zero-cache/src/services/replicator/change-log-db.js +15 -1
- package/out/zero-cache/src/services/replicator/change-log-db.js.map +1 -1
- package/out/zero-cache/src/services/replicator/sqlite-change-log-observability.d.ts +3 -2
- package/out/zero-cache/src/services/replicator/sqlite-change-log-observability.d.ts.map +1 -1
- package/out/zero-cache/src/services/replicator/sqlite-change-log-observability.js +8 -6
- package/out/zero-cache/src/services/replicator/sqlite-change-log-observability.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/client-handler.d.ts +3 -2
- package/out/zero-cache/src/services/view-syncer/client-handler.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/client-handler.js +25 -17
- package/out/zero-cache/src/services/view-syncer/client-handler.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/cvr-store.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/cvr-store.js +14 -1
- package/out/zero-cache/src/services/view-syncer/cvr-store.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/view-syncer.d.ts +3 -3
- 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 +6 -2
- package/out/zero-cache/src/services/view-syncer/view-syncer.js.map +1 -1
- package/out/zero-cache/src/types/downstream.d.ts +11 -0
- package/out/zero-cache/src/types/downstream.d.ts.map +1 -0
- package/out/zero-cache/src/types/pg.d.ts.map +1 -1
- package/out/zero-cache/src/types/pg.js +14 -4
- package/out/zero-cache/src/types/pg.js.map +1 -1
- package/out/zero-cache/src/types/poke-chunk.d.ts +18 -0
- package/out/zero-cache/src/types/poke-chunk.d.ts.map +1 -0
- package/out/zero-cache/src/types/poke-chunk.js +57 -0
- package/out/zero-cache/src/types/poke-chunk.js.map +1 -0
- package/out/zero-cache/src/types/processes.js +1 -4
- package/out/zero-cache/src/types/processes.js.map +1 -1
- package/out/zero-cache/src/workers/connection.d.ts +22 -4
- package/out/zero-cache/src/workers/connection.d.ts.map +1 -1
- package/out/zero-cache/src/workers/connection.js +112 -14
- package/out/zero-cache/src/workers/connection.js.map +1 -1
- package/out/zero-client/src/client/version.js +1 -1
- package/out/zero-client/src/client/zero-poke-handler.d.ts +7 -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 +52 -2
- package/out/zero-client/src/client/zero-poke-handler.js.map +1 -1
- package/out/zero-client/src/client/zero.d.ts.map +1 -1
- package/out/zero-client/src/client/zero.js +38 -6
- package/out/zero-client/src/client/zero.js.map +1 -1
- package/out/zero-protocol/src/down.d.ts +1 -1
- package/out/zero-protocol/src/poke.d.ts +89 -7
- package/out/zero-protocol/src/poke.d.ts.map +1 -1
- package/out/zero-protocol/src/poke.js +16 -8
- package/out/zero-protocol/src/poke.js.map +1 -1
- package/out/zero-protocol/src/protocol-version.d.ts +12 -7
- package/out/zero-protocol/src/protocol-version.d.ts.map +1 -1
- package/out/zero-protocol/src/protocol-version.js.map +1 -1
- package/out/zql/src/ivm/memory-source.d.ts +10 -2
- package/out/zql/src/ivm/memory-source.d.ts.map +1 -1
- package/out/zql/src/ivm/memory-source.js +14 -6
- 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 +1 -7
- package/out/zql/src/ivm/stream.js.map +1 -1
- package/out/zql/src/ivm/union-fan-in.d.ts +1 -1
- package/out/zql/src/ivm/union-fan-in.d.ts.map +1 -1
- package/out/zql/src/ivm/union-fan-in.js +11 -2
- package/out/zql/src/ivm/union-fan-in.js.map +1 -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 +1 -1
- package/out/zero-cache/src/server/backup-watermark-poller.js +0 -31
- package/out/zero-cache/src/server/backup-watermark-poller.js.map +0 -1
- package/out/zero-cache/src/services/litestream/vfs-watermark-poller.d.ts +0 -57
- package/out/zero-cache/src/services/litestream/vfs-watermark-poller.d.ts.map +0 -1
- package/out/zero-cache/src/services/litestream/vfs-watermark-poller.js +0 -137
- package/out/zero-cache/src/services/litestream/vfs-watermark-poller.js.map +0 -1
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import { must } from "../../../shared/src/must.js";
|
|
2
|
-
import { parentWorker, singleProcessMode } from "../types/processes.js";
|
|
3
|
-
import { getZeroConfig } from "../config/zero-config.js";
|
|
4
|
-
import { exitAfter, runUntilKilled } from "../services/life-cycle.js";
|
|
5
|
-
import { createLogContext } from "./logging.js";
|
|
6
|
-
import { VfsBackupWatermarkPoller } from "../services/litestream/vfs-watermark-poller.js";
|
|
7
|
-
import { LogContext, consoleLogSink } from "@rocicorp/logger";
|
|
8
|
-
//#region ../zero-cache/src/server/backup-watermark-poller.ts
|
|
9
|
-
var lc = new LogContext("info", {}, consoleLogSink);
|
|
10
|
-
async function runWorker(parent, env, ...argv) {
|
|
11
|
-
const config = getZeroConfig({
|
|
12
|
-
env,
|
|
13
|
-
argv
|
|
14
|
-
});
|
|
15
|
-
lc = createLogContext(config, "backup-watermark-poller");
|
|
16
|
-
const { litestream, replica } = config;
|
|
17
|
-
parent.send(["ready", { ready: true }]);
|
|
18
|
-
await runUntilKilled(lc, parent, new VfsBackupWatermarkPoller(lc, parent, {
|
|
19
|
-
localDbFile: replica.file,
|
|
20
|
-
backupURL: must(litestream.backupURL, "Missing --litestream-backup-url for backup watermark reader"),
|
|
21
|
-
endpoint: litestream.endpoint,
|
|
22
|
-
region: litestream.region,
|
|
23
|
-
extensionPath: litestream.vfsExtensionPath,
|
|
24
|
-
remotePollIntervalMs: litestream.vfsProbeIntervalMs
|
|
25
|
-
}));
|
|
26
|
-
}
|
|
27
|
-
if (!singleProcessMode()) exitAfter(() => lc, () => runWorker(must(parentWorker), process.env, ...process.argv.slice(2)));
|
|
28
|
-
//#endregion
|
|
29
|
-
export { runWorker as default };
|
|
30
|
-
|
|
31
|
-
//# sourceMappingURL=backup-watermark-poller.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"backup-watermark-poller.js","names":[],"sources":["../../../../../zero-cache/src/server/backup-watermark-poller.ts"],"sourcesContent":["import {consoleLogSink, LogContext} from '@rocicorp/logger';\nimport {must} from '../../../shared/src/must.ts';\nimport {getZeroConfig} from '../config/zero-config.ts';\nimport {exitAfter, runUntilKilled} from '../services/life-cycle.ts';\nimport {VfsBackupWatermarkPoller} from '../services/litestream/vfs-watermark-poller.ts';\nimport {\n parentWorker,\n singleProcessMode,\n type Worker,\n} from '../types/processes.ts';\nimport {createLogContext} from './logging.ts';\n\nlet lc = new LogContext('info', {}, consoleLogSink);\n\nexport default async function runWorker(\n parent: Worker,\n env: NodeJS.ProcessEnv,\n ...argv: string[]\n): Promise<void> {\n const config = getZeroConfig({env, argv});\n lc = createLogContext(config, 'backup-watermark-poller');\n const {litestream, replica} = config;\n\n parent.send(['ready', {ready: true}]);\n\n await runUntilKilled(\n lc,\n parent,\n new VfsBackupWatermarkPoller(lc, parent, {\n localDbFile: replica.file,\n backupURL: must(\n litestream.backupURL,\n 'Missing --litestream-backup-url for backup watermark reader',\n ),\n endpoint: litestream.endpoint,\n region: litestream.region,\n extensionPath: litestream.vfsExtensionPath,\n remotePollIntervalMs: litestream.vfsProbeIntervalMs,\n }),\n );\n}\n\n// fork()\nif (!singleProcessMode()) {\n void exitAfter(\n () => lc,\n () => runWorker(must(parentWorker), process.env, ...process.argv.slice(2)),\n );\n}\n"],"mappings":";;;;;;;;AAYA,IAAI,KAAK,IAAI,WAAW,QAAQ,CAAC,GAAG,cAAc;AAElD,eAA8B,UAC5B,QACA,KACA,GAAG,MACY;CACf,MAAM,SAAS,cAAc;EAAC;EAAK;CAAI,CAAC;CACxC,KAAK,iBAAiB,QAAQ,yBAAyB;CACvD,MAAM,EAAC,YAAY,YAAW;CAE9B,OAAO,KAAK,CAAC,SAAS,EAAC,OAAO,KAAI,CAAC,CAAC;CAEpC,MAAM,eACJ,IACA,QACA,IAAI,yBAAyB,IAAI,QAAQ;EACvC,aAAa,QAAQ;EACrB,WAAW,KACT,WAAW,WACX,6DACF;EACA,UAAU,WAAW;EACrB,QAAQ,WAAW;EACnB,eAAe,WAAW;EAC1B,sBAAsB,WAAW;CACnC,CAAC,CACH;AACF;AAGA,IAAI,CAAC,kBAAkB,GACrB,gBACQ,UACA,UAAU,KAAK,YAAY,GAAG,QAAQ,KAAK,GAAG,QAAQ,KAAK,MAAM,CAAC,CAAC,CAC3E"}
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import type { LogContext, LogLevel } from '@rocicorp/logger';
|
|
2
|
-
import { type Worker } from '../../types/processes.ts';
|
|
3
|
-
import type { Service } from '../service.ts';
|
|
4
|
-
type LoadableDatabase = {
|
|
5
|
-
loadExtension(path: string): unknown;
|
|
6
|
-
close(): void;
|
|
7
|
-
};
|
|
8
|
-
type QueryDatabase = {
|
|
9
|
-
prepare(sql: string): {
|
|
10
|
-
get<T>(): T;
|
|
11
|
-
};
|
|
12
|
-
close(): void;
|
|
13
|
-
};
|
|
14
|
-
export type BackupWatermarkUpdate = [
|
|
15
|
-
'backupWatermarkUpdate',
|
|
16
|
-
{
|
|
17
|
-
watermark: string;
|
|
18
|
-
writeTimeMs: number;
|
|
19
|
-
backupTimeMs: number;
|
|
20
|
-
}
|
|
21
|
-
];
|
|
22
|
-
export type VfsBackupWatermarkPollerEnvOptions = {
|
|
23
|
-
readonly backupURL: string;
|
|
24
|
-
readonly remotePollIntervalMs: number;
|
|
25
|
-
readonly endpoint?: string | undefined;
|
|
26
|
-
readonly region?: string | undefined;
|
|
27
|
-
readonly logLevel?: LogLevel | undefined;
|
|
28
|
-
readonly logFile?: string | undefined;
|
|
29
|
-
};
|
|
30
|
-
export type VfsBackupWatermarkPollerOptions = {
|
|
31
|
-
readonly localDbFile: string;
|
|
32
|
-
readonly backupURL: string;
|
|
33
|
-
readonly endpoint?: string | undefined;
|
|
34
|
-
readonly region?: string | undefined;
|
|
35
|
-
readonly extensionPath: string;
|
|
36
|
-
readonly remotePollIntervalMs: number;
|
|
37
|
-
};
|
|
38
|
-
type VfsBackupWatermarkPollerDeps = {
|
|
39
|
-
readonly loaderFactory?: (() => LoadableDatabase) | undefined;
|
|
40
|
-
readonly databaseFactory?: ((lc: LogContext, uri: string) => QueryDatabase) | undefined;
|
|
41
|
-
};
|
|
42
|
-
export declare function buildLitestreamVfsReplicaURL({ backupURL, endpoint, region, }: {
|
|
43
|
-
readonly backupURL: string;
|
|
44
|
-
readonly endpoint?: string | undefined;
|
|
45
|
-
readonly region?: string | undefined;
|
|
46
|
-
}): string;
|
|
47
|
-
export declare function getVfsEnv(options: VfsBackupWatermarkPollerEnvOptions): NodeJS.ProcessEnv;
|
|
48
|
-
export declare class VfsBackupWatermarkPoller implements Service {
|
|
49
|
-
#private;
|
|
50
|
-
readonly id = "backup-watermark-poller";
|
|
51
|
-
constructor(lc: LogContext, parent: Worker, options: VfsBackupWatermarkPollerOptions, deps?: VfsBackupWatermarkPollerDeps);
|
|
52
|
-
checkWatermarks(): void;
|
|
53
|
-
run(): Promise<void>;
|
|
54
|
-
stop(): Promise<void>;
|
|
55
|
-
}
|
|
56
|
-
export {};
|
|
57
|
-
//# sourceMappingURL=vfs-watermark-poller.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"vfs-watermark-poller.d.ts","sourceRoot":"","sources":["../../../../../../zero-cache/src/services/litestream/vfs-watermark-poller.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,UAAU,EAAE,QAAQ,EAAC,MAAM,kBAAkB,CAAC;AAK3D,OAAO,EAAC,KAAK,MAAM,EAAC,MAAM,0BAA0B,CAAC;AAErD,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,eAAe,CAAC;AAI3C,KAAK,gBAAgB,GAAG;IACtB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IACrC,KAAK,IAAI,IAAI,CAAC;CACf,CAAC;AAEF,KAAK,aAAa,GAAG;IACnB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG;QAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAA;KAAC,CAAC;IACpC,KAAK,IAAI,IAAI,CAAC;CACf,CAAC;AAeF,MAAM,MAAM,qBAAqB,GAAG;IAClC,uBAAuB;IACvB;QACE,SAAS,EAAE,MAAM,CAAC;QAClB,WAAW,EAAE,MAAM,CAAC;QACpB,YAAY,EAAE,MAAM,CAAC;KACtB;CACF,CAAC;AAUF,MAAM,MAAM,kCAAkC,GAAG;IAC/C,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,oBAAoB,EAAE,MAAM,CAAC;IACtC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACvC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAErC,QAAQ,CAAC,QAAQ,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAC;IACzC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACvC,CAAC;AAEF,MAAM,MAAM,+BAA+B,GAAG;IAC5C,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACvC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAErC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,oBAAoB,EAAE,MAAM,CAAC;CACvC,CAAC;AAEF,KAAK,4BAA4B,GAAG;IAClC,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC,MAAM,gBAAgB,CAAC,GAAG,SAAS,CAAC;IAC9D,QAAQ,CAAC,eAAe,CAAC,EACrB,CAAC,CAAC,EAAE,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,KAAK,aAAa,CAAC,GAChD,SAAS,CAAC;CACf,CAAC;AAEF,wBAAgB,4BAA4B,CAAC,EAC3C,SAAS,EACT,QAAQ,EACR,MAAM,GACP,EAAE;IACD,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACvC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACtC,GAAG,MAAM,CAiBT;AAED,wBAAgB,SAAS,CACvB,OAAO,EAAE,kCAAkC,GAC1C,MAAM,CAAC,UAAU,CAWnB;AAKD,qBAAa,wBAAyB,YAAW,OAAO;;IACtD,QAAQ,CAAC,EAAE,6BAA6B;gBAatC,EAAE,EAAE,UAAU,EACd,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,+BAA+B,EACxC,IAAI,GAAE,4BAAiC;IAgEzC,eAAe;IAiDT,GAAG;IAkBT,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CAItB"}
|
|
@@ -1,137 +0,0 @@
|
|
|
1
|
-
import { promiseVoid } from "../../../../shared/src/resolved-promises.js";
|
|
2
|
-
import { parse, valita_exports } from "../../../../shared/src/valita.js";
|
|
3
|
-
import "../../types/processes.js";
|
|
4
|
-
import { Database } from "../../../../zqlite/src/db.js";
|
|
5
|
-
import { RunningState } from "../running-state.js";
|
|
6
|
-
import SQLite3Database from "@rocicorp/zero-sqlite3";
|
|
7
|
-
//#region ../zero-cache/src/services/litestream/vfs-watermark-poller.ts
|
|
8
|
-
var DEFAULT_VFS_LOG_LEVEL = "info";
|
|
9
|
-
var watermarkRowSchema = valita_exports.object({
|
|
10
|
-
watermark: valita_exports.string(),
|
|
11
|
-
writeTimeMs: valita_exports.number()
|
|
12
|
-
});
|
|
13
|
-
var watermarkQuerySchema = watermarkRowSchema.extend({ backupTime: valita_exports.string() });
|
|
14
|
-
function buildLitestreamVfsReplicaURL({ backupURL, endpoint, region }) {
|
|
15
|
-
if (endpoint === void 0 && region === void 0) return backupURL;
|
|
16
|
-
const url = new URL(backupURL);
|
|
17
|
-
if (url.protocol !== "s3:") return backupURL;
|
|
18
|
-
if (endpoint !== void 0 && !url.searchParams.has("endpoint")) url.searchParams.set("endpoint", endpoint);
|
|
19
|
-
if (region !== void 0 && !url.searchParams.has("region")) url.searchParams.set("region", region);
|
|
20
|
-
return url.toString();
|
|
21
|
-
}
|
|
22
|
-
function getVfsEnv(options) {
|
|
23
|
-
return {
|
|
24
|
-
LITESTREAM_REPLICA_URL: buildLitestreamVfsReplicaURL(options),
|
|
25
|
-
LITESTREAM_LOG_LEVEL: options.logLevel ?? DEFAULT_VFS_LOG_LEVEL,
|
|
26
|
-
LITESTREAM_LOG_FILE: options.logFile,
|
|
27
|
-
LITESTREAM_POLL_INTERVAL: `${options.remotePollIntervalMs}ms`
|
|
28
|
-
};
|
|
29
|
-
}
|
|
30
|
-
var MIN_CHECK_INTERVAL_MS = 1e3;
|
|
31
|
-
var MAX_CHECK_INTERVAL_MS = 6e4;
|
|
32
|
-
var VfsBackupWatermarkPoller = class {
|
|
33
|
-
id = "backup-watermark-poller";
|
|
34
|
-
#runningState = new RunningState(this.id);
|
|
35
|
-
#lc;
|
|
36
|
-
#parent;
|
|
37
|
-
#loader;
|
|
38
|
-
#localDb;
|
|
39
|
-
#openRemote;
|
|
40
|
-
#remoteDb = null;
|
|
41
|
-
#lastRemoteWatermark = null;
|
|
42
|
-
constructor(lc, parent, options, deps = {}) {
|
|
43
|
-
lc = lc.withContext("component", "vfs-watermark-poller");
|
|
44
|
-
this.#lc = lc;
|
|
45
|
-
this.#parent = parent;
|
|
46
|
-
const { databaseFactory } = deps;
|
|
47
|
-
const openDb = (url, type, schema) => {
|
|
48
|
-
try {
|
|
49
|
-
const db = databaseFactory ? databaseFactory(lc, url) : new Database(lc, url, { readonly: true });
|
|
50
|
-
const stmt = db.prepare(type === "local" ? `
|
|
51
|
-
SELECT stateVersion AS watermark, writeTimeMs FROM "_zero.replicationState"` : `
|
|
52
|
-
SELECT stateVersion AS watermark, writeTimeMs, litestream_time() as backupTime FROM "_zero.replicationState"`);
|
|
53
|
-
return {
|
|
54
|
-
getWatermark: () => parse(stmt.get(), schema),
|
|
55
|
-
close: () => db.close()
|
|
56
|
-
};
|
|
57
|
-
} catch (e) {
|
|
58
|
-
lc.error?.(`error opening ${url}`, e);
|
|
59
|
-
throw e;
|
|
60
|
-
}
|
|
61
|
-
};
|
|
62
|
-
this.#localDb = openDb(options.localDbFile, "local", watermarkRowSchema);
|
|
63
|
-
const loaderFactory = deps.loaderFactory ?? (() => new SQLite3Database(":memory:"));
|
|
64
|
-
const remoteDbURL = `file:zero-backup.db?${new URLSearchParams({
|
|
65
|
-
vfs: "litestream",
|
|
66
|
-
mode: "ro",
|
|
67
|
-
replica_url: buildLitestreamVfsReplicaURL(options),
|
|
68
|
-
poll_interval: `${options.remotePollIntervalMs}ms`
|
|
69
|
-
}).toString()}`;
|
|
70
|
-
lc.info?.(`Loading VFS ${remoteDbURL} at ${options.extensionPath}`);
|
|
71
|
-
this.#loader = loaderFactory();
|
|
72
|
-
this.#loader.loadExtension(options.extensionPath);
|
|
73
|
-
this.#openRemote = () => openDb(remoteDbURL, "remote", watermarkQuerySchema);
|
|
74
|
-
}
|
|
75
|
-
checkWatermarks() {
|
|
76
|
-
const local = this.#localDb.getWatermark();
|
|
77
|
-
if (local.watermark !== this.#lastRemoteWatermark?.watermark) {
|
|
78
|
-
if (!this.#remoteDb) {
|
|
79
|
-
if (this.#lastRemoteWatermark) this.#lc.debug?.(`local and remote watermarks differ. resuming backup polling`, {
|
|
80
|
-
local,
|
|
81
|
-
remote: this.#lastRemoteWatermark
|
|
82
|
-
});
|
|
83
|
-
this.#remoteDb = this.#openRemote();
|
|
84
|
-
}
|
|
85
|
-
const remote = this.#remoteDb.getWatermark();
|
|
86
|
-
if (remote.watermark !== this.#lastRemoteWatermark?.watermark) {
|
|
87
|
-
this.#lc.debug?.(`backup watermark advanced from ${this.#lastRemoteWatermark?.watermark} to ${remote.watermark}`, {
|
|
88
|
-
local,
|
|
89
|
-
remote
|
|
90
|
-
});
|
|
91
|
-
this.#lastRemoteWatermark = remote;
|
|
92
|
-
const { watermark, writeTimeMs, backupTime } = remote;
|
|
93
|
-
const backupTimeMs = new Date(backupTime).getTime();
|
|
94
|
-
this.#parent.send(["backupWatermarkUpdate", {
|
|
95
|
-
watermark,
|
|
96
|
-
writeTimeMs,
|
|
97
|
-
backupTimeMs
|
|
98
|
-
}]);
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
if (local.watermark === this.#lastRemoteWatermark?.watermark) {
|
|
102
|
-
if (this.#remoteDb) {
|
|
103
|
-
this.#lc.debug?.(`local and remote watermarks match. pausing backup polling`, {
|
|
104
|
-
local,
|
|
105
|
-
remote: this.#lastRemoteWatermark
|
|
106
|
-
});
|
|
107
|
-
this.#remoteDb.close();
|
|
108
|
-
this.#remoteDb = null;
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
async run() {
|
|
113
|
-
this.#lc.info?.(`starting backup polling`);
|
|
114
|
-
let interval = MIN_CHECK_INTERVAL_MS;
|
|
115
|
-
while (this.#runningState.shouldRun()) {
|
|
116
|
-
try {
|
|
117
|
-
this.checkWatermarks();
|
|
118
|
-
interval = MIN_CHECK_INTERVAL_MS;
|
|
119
|
-
} catch (e) {
|
|
120
|
-
this.#lc.warn?.(`error checking local and remote watermarks`, e);
|
|
121
|
-
interval = Math.min(MAX_CHECK_INTERVAL_MS, interval * 2);
|
|
122
|
-
}
|
|
123
|
-
await this.#runningState.sleep(interval);
|
|
124
|
-
}
|
|
125
|
-
this.#remoteDb?.close();
|
|
126
|
-
this.#localDb.close();
|
|
127
|
-
this.#loader.close();
|
|
128
|
-
}
|
|
129
|
-
stop() {
|
|
130
|
-
this.#runningState.stop(this.#lc);
|
|
131
|
-
return promiseVoid;
|
|
132
|
-
}
|
|
133
|
-
};
|
|
134
|
-
//#endregion
|
|
135
|
-
export { VfsBackupWatermarkPoller, getVfsEnv };
|
|
136
|
-
|
|
137
|
-
//# sourceMappingURL=vfs-watermark-poller.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"vfs-watermark-poller.js","names":["#runningState","#lc","#parent","#loader","#localDb","#openRemote","#lastRemoteWatermark","#remoteDb"],"sources":["../../../../../../zero-cache/src/services/litestream/vfs-watermark-poller.ts"],"sourcesContent":["import type {LogContext, LogLevel} from '@rocicorp/logger';\nimport Sqlite3Database from '@rocicorp/zero-sqlite3';\nimport {promiseVoid} from '../../../../shared/src/resolved-promises.ts';\nimport * as v from '../../../../shared/src/valita.ts';\nimport {Database} from '../../../../zqlite/src/db.ts';\nimport {type Worker} from '../../types/processes.ts';\nimport {RunningState} from '../running-state.ts';\nimport type {Service} from '../service.ts';\n\nconst DEFAULT_VFS_LOG_LEVEL = 'info';\n\ntype LoadableDatabase = {\n loadExtension(path: string): unknown;\n close(): void;\n};\n\ntype QueryDatabase = {\n prepare(sql: string): {get<T>(): T};\n close(): void;\n};\n\nconst watermarkRowSchema = v.object({\n watermark: v.string(),\n writeTimeMs: v.number(),\n});\n\nconst watermarkQuerySchema = watermarkRowSchema.extend({\n backupTime: v.string(),\n});\n\ntype WatermarkQueryResult = v.Infer<typeof watermarkQuerySchema>;\n\ntype WatermarkRow = v.Infer<typeof watermarkRowSchema>;\n\nexport type BackupWatermarkUpdate = [\n 'backupWatermarkUpdate',\n {\n watermark: string;\n writeTimeMs: number;\n backupTimeMs: number;\n },\n];\n\ntype WatermarkReader<Result extends WatermarkRow> = {\n getWatermark(): Result;\n close(): void;\n};\n\n// Values that must be passed via the ENV to the original process (worker).\n// Some of these will be configurable via the db URI once\n// https://github.com/benbjohnson/litestream/issues/1150 is released.\nexport type VfsBackupWatermarkPollerEnvOptions = {\n readonly backupURL: string;\n readonly remotePollIntervalMs: number;\n readonly endpoint?: string | undefined;\n readonly region?: string | undefined;\n\n readonly logLevel?: LogLevel | undefined;\n readonly logFile?: string | undefined;\n};\n\nexport type VfsBackupWatermarkPollerOptions = {\n readonly localDbFile: string;\n readonly backupURL: string;\n readonly endpoint?: string | undefined;\n readonly region?: string | undefined;\n\n readonly extensionPath: string;\n readonly remotePollIntervalMs: number;\n};\n\ntype VfsBackupWatermarkPollerDeps = {\n readonly loaderFactory?: (() => LoadableDatabase) | undefined;\n readonly databaseFactory?:\n | ((lc: LogContext, uri: string) => QueryDatabase)\n | undefined;\n};\n\nexport function buildLitestreamVfsReplicaURL({\n backupURL,\n endpoint,\n region,\n}: {\n readonly backupURL: string;\n readonly endpoint?: string | undefined;\n readonly region?: string | undefined;\n}): string {\n if (endpoint === undefined && region === undefined) {\n return backupURL;\n }\n\n const url = new URL(backupURL);\n if (url.protocol !== 's3:') {\n return backupURL;\n }\n\n if (endpoint !== undefined && !url.searchParams.has('endpoint')) {\n url.searchParams.set('endpoint', endpoint);\n }\n if (region !== undefined && !url.searchParams.has('region')) {\n url.searchParams.set('region', region);\n }\n return url.toString();\n}\n\nexport function getVfsEnv(\n options: VfsBackupWatermarkPollerEnvOptions,\n): NodeJS.ProcessEnv {\n return {\n LITESTREAM_REPLICA_URL: buildLitestreamVfsReplicaURL(options),\n LITESTREAM_LOG_LEVEL: options.logLevel ?? DEFAULT_VFS_LOG_LEVEL,\n LITESTREAM_LOG_FILE: options.logFile,\n\n // Supported by the rocicorp fork: https://github.com/rocicorp/litestream/pull/20\n // TODO: Remove and use official build when\n // https://github.com/benbjohnson/litestream/pull/1157 is released.\n LITESTREAM_POLL_INTERVAL: `${options.remotePollIntervalMs}ms`,\n };\n}\n\nconst MIN_CHECK_INTERVAL_MS = 1_000;\nconst MAX_CHECK_INTERVAL_MS = 60_000;\n\nexport class VfsBackupWatermarkPoller implements Service {\n readonly id = 'backup-watermark-poller';\n readonly #runningState = new RunningState(this.id);\n readonly #lc: LogContext;\n readonly #parent: Worker;\n readonly #loader: LoadableDatabase;\n\n readonly #localDb: WatermarkReader<WatermarkRow>;\n readonly #openRemote: () => WatermarkReader<WatermarkQueryResult>;\n\n #remoteDb: WatermarkReader<WatermarkQueryResult> | null = null;\n #lastRemoteWatermark: WatermarkQueryResult | null = null;\n\n constructor(\n lc: LogContext,\n parent: Worker,\n options: VfsBackupWatermarkPollerOptions,\n deps: VfsBackupWatermarkPollerDeps = {},\n ) {\n lc = lc.withContext('component', 'vfs-watermark-poller');\n this.#lc = lc;\n this.#parent = parent;\n\n const {databaseFactory} = deps;\n const openDb = <Result extends WatermarkRow>(\n url: string,\n type: 'local' | 'remote',\n schema: v.Type<Result>,\n ) => {\n try {\n const db = databaseFactory\n ? databaseFactory(lc, url)\n : new Database(lc, url, {readonly: true});\n const stmt = db.prepare(\n type === 'local'\n ? /*sql*/ `\n SELECT stateVersion AS watermark, writeTimeMs FROM \"_zero.replicationState\"`\n : /*sql*/ `\n SELECT stateVersion AS watermark, writeTimeMs, litestream_time() as backupTime FROM \"_zero.replicationState\"`,\n );\n return {\n getWatermark: () => v.parse(stmt.get(), schema),\n close: () => db.close(),\n } satisfies WatermarkReader<Result>;\n } catch (e) {\n lc.error?.(`error opening ${url}`, e);\n throw e;\n }\n };\n\n // Open the local (non-VFS) connection before loading the litestream VFS\n // extension. Loading the extension registers a process-global\n // `sqlite3_auto_extension` hook that SQLite invokes on every connection\n // opened *afterward* in this process (even ones that don't reference\n // `vfs=litestream`), and a signature bug in that hook currently causes\n // it to fail such connections. Opening #localDb first sidesteps it,\n // since already-open connections aren't affected by the hook.\n this.#localDb = openDb(options.localDbFile, 'local', watermarkRowSchema);\n\n const loaderFactory =\n deps.loaderFactory ?? (() => new Sqlite3Database(':memory:'));\n\n const dbParams = new URLSearchParams({\n vfs: 'litestream',\n mode: 'ro',\n // Support forthcoming in https://github.com/benbjohnson/litestream/issues/1150\n replica_url: buildLitestreamVfsReplicaURL(options),\n poll_interval: `${options.remotePollIntervalMs}ms`,\n });\n // Note: the filename is arbitrary and only referenced in debug logs.\n const remoteDbURL = `file:zero-backup.db?${dbParams.toString()}`;\n\n lc.info?.(`Loading VFS ${remoteDbURL} at ${options.extensionPath}`);\n this.#loader = loaderFactory();\n this.#loader.loadExtension(options.extensionPath);\n\n this.#openRemote = () =>\n openDb(remoteDbURL, 'remote', watermarkQuerySchema);\n }\n\n // public for testing\n checkWatermarks() {\n const local = this.#localDb.getWatermark();\n if (local.watermark !== this.#lastRemoteWatermark?.watermark) {\n if (!this.#remoteDb) {\n if (this.#lastRemoteWatermark) {\n this.#lc.debug?.(\n `local and remote watermarks differ. resuming backup polling`,\n {local, remote: this.#lastRemoteWatermark},\n );\n }\n this.#remoteDb = this.#openRemote();\n }\n const remote = this.#remoteDb.getWatermark();\n if (remote.watermark !== this.#lastRemoteWatermark?.watermark) {\n this.#lc.debug?.(\n `backup watermark advanced from ${this.#lastRemoteWatermark?.watermark} to ${remote.watermark}`,\n {local, remote},\n );\n this.#lastRemoteWatermark = remote;\n const {watermark, writeTimeMs, backupTime} = remote;\n // Note: litestream_time() returns \"latest\" if no LTX files were\n // loaded:\n //\n // https://github.com/benbjohnson/litestream/blob/6d61ef5d007756d62e473daee4c760ac395a55c6/vfs.go#L2448\n //\n // but in that case the watermark query would have failed, so it\n // follows that litestream_time() should always return a valid\n // timestamp if the watermark query itself succeeded.\n const backupTimeMs = new Date(backupTime).getTime();\n this.#parent.send<BackupWatermarkUpdate>([\n 'backupWatermarkUpdate',\n {watermark, writeTimeMs, backupTimeMs},\n ]);\n }\n }\n // Note: This is not an `else`, as we specifically want to re-check\n // this.#lastRemoteWatermark\n if (local.watermark === this.#lastRemoteWatermark?.watermark) {\n if (this.#remoteDb) {\n this.#lc.debug?.(\n `local and remote watermarks match. pausing backup polling`,\n {local, remote: this.#lastRemoteWatermark},\n );\n this.#remoteDb.close();\n this.#remoteDb = null;\n }\n }\n }\n\n async run() {\n this.#lc.info?.(`starting backup polling`);\n let interval = MIN_CHECK_INTERVAL_MS;\n while (this.#runningState.shouldRun()) {\n try {\n this.checkWatermarks();\n interval = MIN_CHECK_INTERVAL_MS;\n } catch (e) {\n this.#lc.warn?.(`error checking local and remote watermarks`, e);\n interval = Math.min(MAX_CHECK_INTERVAL_MS, interval * 2);\n }\n await this.#runningState.sleep(interval);\n }\n this.#remoteDb?.close();\n this.#localDb.close();\n this.#loader.close();\n }\n\n stop(): Promise<void> {\n this.#runningState.stop(this.#lc);\n return promiseVoid;\n }\n}\n"],"mappings":"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"}
|