@rocicorp/zero 1.11.3 → 1.11.5
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/sync/request-id.js +2 -2
- package/out/replicache/src/sync/request-id.js.map +1 -1
- package/out/shared/src/bigint-json.d.ts.map +1 -1
- package/out/shared/src/bigint-json.js +1 -0
- package/out/shared/src/bigint-json.js.map +1 -1
- package/out/shared/src/headers.d.ts +12 -0
- package/out/shared/src/headers.d.ts.map +1 -0
- package/out/shared/src/headers.js +20 -0
- package/out/shared/src/headers.js.map +1 -0
- package/out/shared/src/random-uint64.d.ts.map +1 -1
- package/out/shared/src/random-uint64.js +2 -2
- package/out/shared/src/random-uint64.js.map +1 -1
- package/out/shared/src/random-values.d.ts +14 -1
- package/out/shared/src/random-values.d.ts.map +1 -1
- package/out/shared/src/random-values.js +24 -4
- 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-cache/src/auth/auth.d.ts.map +1 -1
- package/out/zero-cache/src/auth/auth.js +5 -0
- package/out/zero-cache/src/auth/auth.js.map +1 -1
- package/out/zero-cache/src/config/zero-config.d.ts +21 -0
- package/out/zero-cache/src/config/zero-config.d.ts.map +1 -1
- package/out/zero-cache/src/config/zero-config.js +47 -9
- package/out/zero-cache/src/config/zero-config.js.map +1 -1
- package/out/zero-cache/src/custom-queries/transform-query.js +2 -2
- package/out/zero-cache/src/custom-queries/transform-query.js.map +1 -1
- package/out/zero-cache/src/db/pg-to-lite.d.ts.map +1 -1
- package/out/zero-cache/src/db/pg-to-lite.js +3 -2
- package/out/zero-cache/src/db/pg-to-lite.js.map +1 -1
- package/out/zero-cache/src/db/pg-type-parser.d.ts +13 -0
- package/out/zero-cache/src/db/pg-type-parser.d.ts.map +1 -1
- package/out/zero-cache/src/db/pg-type-parser.js +55 -2
- package/out/zero-cache/src/db/pg-type-parser.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 +5 -2
- package/out/zero-cache/src/server/change-streamer.js.map +1 -1
- package/out/zero-cache/src/server/inspector-delegate.d.ts +2 -25
- package/out/zero-cache/src/server/inspector-delegate.d.ts.map +1 -1
- package/out/zero-cache/src/server/inspector-delegate.js +6 -29
- package/out/zero-cache/src/server/inspector-delegate.js.map +1 -1
- package/out/zero-cache/src/server/main.d.ts.map +1 -1
- package/out/zero-cache/src/server/main.js +5 -0
- package/out/zero-cache/src/server/main.js.map +1 -1
- package/out/zero-cache/src/server/replicator.d.ts.map +1 -1
- package/out/zero-cache/src/server/replicator.js +3 -2
- package/out/zero-cache/src/server/replicator.js.map +1 -1
- package/out/zero-cache/src/server/syncer.d.ts.map +1 -1
- package/out/zero-cache/src/server/syncer.js +5 -4
- package/out/zero-cache/src/server/syncer.js.map +1 -1
- package/out/zero-cache/src/server/worker-dispatcher.d.ts.map +1 -1
- package/out/zero-cache/src/server/worker-dispatcher.js +2 -1
- package/out/zero-cache/src/server/worker-dispatcher.js.map +1 -1
- package/out/zero-cache/src/services/admin-auth.d.ts +22 -0
- package/out/zero-cache/src/services/admin-auth.d.ts.map +1 -0
- package/out/zero-cache/src/services/admin-auth.js +42 -0
- package/out/zero-cache/src/services/admin-auth.js.map +1 -0
- package/out/zero-cache/src/services/auth-attempt-counter.d.ts +33 -0
- package/out/zero-cache/src/services/auth-attempt-counter.d.ts.map +1 -0
- package/out/zero-cache/src/services/auth-attempt-counter.js +61 -0
- package/out/zero-cache/src/services/auth-attempt-counter.js.map +1 -0
- package/out/zero-cache/src/services/change-source/pg/backfill-stream.js +1 -1
- package/out/zero-cache/src/services/change-source/pg/change-source.d.ts +7 -1
- package/out/zero-cache/src/services/change-source/pg/change-source.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/change-source.js +110 -13
- 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/logical-replication/stream.js +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/ddl.d.ts +15 -8
- 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 +38 -5
- 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/init.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/init.js +10 -1
- package/out/zero-cache/src/services/change-source/pg/schema/init.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/shard.d.ts +4 -0
- package/out/zero-cache/src/services/change-source/pg/schema/shard.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/shard.js +10 -3
- package/out/zero-cache/src/services/change-source/pg/schema/shard.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/change-streamer-http.d.ts +7 -1
- 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 +23 -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.js +2 -2
- 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 +30 -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 +10 -3
- package/out/zero-cache/src/services/change-streamer/change-streamer.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/subscribe.d.ts +1 -0
- package/out/zero-cache/src/services/change-streamer/subscribe.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/subscriber.d.ts +1 -1
- package/out/zero-cache/src/services/change-streamer/subscriber.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/subscriber.js.map +1 -1
- package/out/zero-cache/src/services/heapz.d.ts.map +1 -1
- package/out/zero-cache/src/services/heapz.js +4 -5
- package/out/zero-cache/src/services/heapz.js.map +1 -1
- package/out/zero-cache/src/services/mutagen/pusher.js +1 -1
- package/out/zero-cache/src/services/mutagen/pusher.js.map +1 -1
- package/out/zero-cache/src/services/plannerz.d.ts.map +1 -1
- package/out/zero-cache/src/services/plannerz.js +3 -7
- package/out/zero-cache/src/services/plannerz.js.map +1 -1
- package/out/zero-cache/src/services/profz.d.ts.map +1 -1
- package/out/zero-cache/src/services/profz.js +4 -13
- package/out/zero-cache/src/services/profz.js.map +1 -1
- package/out/zero-cache/src/services/replicator/change-processor.js +1 -2
- 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 +3 -3
- package/out/zero-cache/src/services/replicator/incremental-sync.js.map +1 -1
- package/out/zero-cache/src/services/statz.d.ts.map +1 -1
- package/out/zero-cache/src/services/statz.js +2 -7
- package/out/zero-cache/src/services/statz.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/client-handler.d.ts +16 -0
- 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 +22 -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.d.ts +29 -4
- package/out/zero-cache/src/services/view-syncer/connection-context-manager.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/connection-context-manager.js +40 -2
- 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.d.ts +10 -2
- 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 +54 -17
- package/out/zero-cache/src/services/view-syncer/cvr-store.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/cvr.d.ts +8 -0
- package/out/zero-cache/src/services/view-syncer/cvr.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/cvr.js +11 -0
- package/out/zero-cache/src/services/view-syncer/cvr.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/inspect-auth-limiter.d.ts +35 -0
- package/out/zero-cache/src/services/view-syncer/inspect-auth-limiter.d.ts.map +1 -0
- package/out/zero-cache/src/services/view-syncer/inspect-auth-limiter.js +107 -0
- package/out/zero-cache/src/services/view-syncer/inspect-auth-limiter.js.map +1 -0
- package/out/zero-cache/src/services/view-syncer/inspect-handler.d.ts +2 -2
- package/out/zero-cache/src/services/view-syncer/inspect-handler.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/inspect-handler.js +11 -6
- package/out/zero-cache/src/services/view-syncer/inspect-handler.js.map +1 -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 +2 -1
- package/out/zero-cache/src/services/view-syncer/pipeline-driver.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/schema/cvr.d.ts +9 -0
- package/out/zero-cache/src/services/view-syncer/schema/cvr.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/schema/cvr.js +4 -1
- package/out/zero-cache/src/services/view-syncer/schema/cvr.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/schema/init.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/schema/init.js +3 -0
- package/out/zero-cache/src/services/view-syncer/schema/init.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/snapshotter.js +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 +96 -44
- package/out/zero-cache/src/services/view-syncer/view-syncer.js.map +1 -1
- package/out/zero-cache/src/types/client-group-log-id.d.ts +9 -0
- package/out/zero-cache/src/types/client-group-log-id.d.ts.map +1 -0
- package/out/zero-cache/src/types/client-group-log-id.js +16 -0
- package/out/zero-cache/src/types/client-group-log-id.js.map +1 -0
- package/out/zero-cache/src/types/lite.d.ts.map +1 -1
- package/out/zero-cache/src/types/lite.js +1 -0
- package/out/zero-cache/src/types/lite.js.map +1 -1
- package/out/zero-cache/src/types/pg.d.ts +13 -2
- package/out/zero-cache/src/types/pg.d.ts.map +1 -1
- package/out/zero-cache/src/types/pg.js +2 -2
- package/out/zero-cache/src/types/pg.js.map +1 -1
- package/out/zero-cache/src/workers/connection.d.ts +1 -0
- package/out/zero-cache/src/workers/connection.d.ts.map +1 -1
- package/out/zero-cache/src/workers/connection.js +5 -1
- package/out/zero-cache/src/workers/connection.js.map +1 -1
- package/out/zero-cache/src/workers/syncer-ws-message-handler.d.ts.map +1 -1
- package/out/zero-cache/src/workers/syncer-ws-message-handler.js +12 -3
- package/out/zero-cache/src/workers/syncer-ws-message-handler.js.map +1 -1
- package/out/zero-cache/src/workers/syncer.d.ts.map +1 -1
- package/out/zero-cache/src/workers/syncer.js +15 -14
- package/out/zero-cache/src/workers/syncer.js.map +1 -1
- package/out/zero-client/src/client/inspector/inspector.d.ts +4 -0
- package/out/zero-client/src/client/inspector/inspector.d.ts.map +1 -1
- package/out/zero-client/src/client/inspector/inspector.js +4 -0
- package/out/zero-client/src/client/inspector/inspector.js.map +1 -1
- package/out/zero-client/src/client/inspector/lazy-inspector.d.ts +10 -2
- package/out/zero-client/src/client/inspector/lazy-inspector.d.ts.map +1 -1
- package/out/zero-client/src/client/inspector/lazy-inspector.js +38 -31
- package/out/zero-client/src/client/inspector/lazy-inspector.js.map +1 -1
- package/out/zero-client/src/client/inspector/query.d.ts +2 -2
- package/out/zero-client/src/client/inspector/query.d.ts.map +1 -1
- package/out/zero-client/src/client/inspector/query.js +4 -4
- package/out/zero-client/src/client/inspector/query.js.map +1 -1
- package/out/zero-client/src/client/version.js +1 -1
- package/out/zero-client/src/util/nanoid.js +2 -2
- package/out/zero-client/src/util/nanoid.js.map +1 -1
- package/out/zero-server/src/process-mutations.d.ts +10 -0
- package/out/zero-server/src/process-mutations.d.ts.map +1 -1
- package/out/zero-server/src/process-mutations.js +38 -5
- package/out/zero-server/src/process-mutations.js.map +1 -1
- package/package.json +1 -1
|
@@ -27,6 +27,7 @@ import "./initial-sync.js";
|
|
|
27
27
|
import { streamBackfill } from "./backfill-stream.js";
|
|
28
28
|
import { ReplicationSlotCleanupMonitor } from "./replication-slot-cleanup-monitor.js";
|
|
29
29
|
import { registerReplicationSlotHealthMetrics } from "./replication-slot-health.js";
|
|
30
|
+
import { timingSafeEqual } from "node:crypto";
|
|
30
31
|
import { nanoid } from "nanoid";
|
|
31
32
|
import postgres from "postgres";
|
|
32
33
|
import { PG_ADMIN_SHUTDOWN, PG_INSUFFICIENT_PRIVILEGE } from "@drdgvhbh/postgres-error-codes";
|
|
@@ -118,7 +119,8 @@ var PostgresChangeSource = class {
|
|
|
118
119
|
*/
|
|
119
120
|
const isTransactionalMessage = (lsn, msg) => {
|
|
120
121
|
if (msg.tag === "message" && msg.prefix === this.#lagReporter?.messagePrefix) {
|
|
121
|
-
|
|
122
|
+
const status = this.#lagReporter.processLagReportMessage(msg, lsn);
|
|
123
|
+
if (status) changes.pushStatus(status);
|
|
122
124
|
return false;
|
|
123
125
|
}
|
|
124
126
|
const status = this.#lagReporter?.checkCurrentLSN(lsn);
|
|
@@ -325,6 +327,10 @@ var LagReporter = class LagReporter {
|
|
|
325
327
|
description: "Number of replication lag reports retried because the expected report was not received before the next report interval.",
|
|
326
328
|
unit: "{report}"
|
|
327
329
|
});
|
|
330
|
+
#lagReportsIgnored = getOrCreateCounter("replication", "lag_reports_ignored", {
|
|
331
|
+
description: "Number of messages with the lag report prefix ignored because their content could not be parsed as a lag report.",
|
|
332
|
+
unit: "{message}"
|
|
333
|
+
});
|
|
328
334
|
#pgVersion;
|
|
329
335
|
#expectingLagReport = null;
|
|
330
336
|
#lastAcceptedSendTimeMs = 0;
|
|
@@ -475,10 +481,22 @@ var LagReporter = class LagReporter {
|
|
|
475
481
|
* XLogData header), rather than the `messageLsn` of the message itself,
|
|
476
482
|
* which is not guaranteed to be comparable to other stream LSNs (e.g. on
|
|
477
483
|
* Aurora). See {@link initiateLagReport}.
|
|
484
|
+
* @returns the status to send downstream, or `undefined` if the message is
|
|
485
|
+
* not a lag report. Any session that can call
|
|
486
|
+
* `pg_logical_emit_message()` can emit a message with the lag report
|
|
487
|
+
* prefix; one that cannot be parsed carries no report and is ignored,
|
|
488
|
+
* as a message of an unknown prefix would be, rather than failing the
|
|
489
|
+
* stream (which would replay it from the same position).
|
|
478
490
|
*/
|
|
479
491
|
processLagReportMessage(msg, lsn) {
|
|
480
492
|
assert(msg.prefix === this.messagePrefix, `unexpected message prefix: ${msg.prefix}`);
|
|
481
|
-
|
|
493
|
+
let report;
|
|
494
|
+
try {
|
|
495
|
+
report = parseLogicalMessageContent(this.#lc, msg, lagReportSchema);
|
|
496
|
+
} catch {
|
|
497
|
+
this.#lagReportsIgnored.add(1);
|
|
498
|
+
return;
|
|
499
|
+
}
|
|
482
500
|
return this.#processLagReport(report, majorVersionToString(lsn));
|
|
483
501
|
}
|
|
484
502
|
#processLagReport(report, watermark) {
|
|
@@ -643,9 +661,50 @@ var ChangeMaker = class {
|
|
|
643
661
|
default: throw new Error(`Unexpected message type ${stringify(msg)}`);
|
|
644
662
|
}
|
|
645
663
|
}
|
|
664
|
+
/**
|
|
665
|
+
* Any session that can call `pg_logical_emit_message()` can emit a message
|
|
666
|
+
* with the shard's ddl prefix. Only events that carry the shard's secret,
|
|
667
|
+
* which the upstream functions read from a table in the shard's schema
|
|
668
|
+
* (see `createEventFunctionStatements()`), are applied. Events emitted
|
|
669
|
+
* before the secret was installed (by functions that predate it) are
|
|
670
|
+
* accepted without one.
|
|
671
|
+
*
|
|
672
|
+
* @returns why the event cannot be verified, or `undefined` if it can.
|
|
673
|
+
*/
|
|
674
|
+
#ddlEventOriginProblem(lsn, json, ddlSecret, ddlSecretLsn) {
|
|
675
|
+
const secret = field(json, "secret");
|
|
676
|
+
if (typeof secret === "string") {
|
|
677
|
+
if (equalSecrets(secret, ddlSecret)) return;
|
|
678
|
+
} else if ((secret === void 0 || secret === null) && ddlSecretLsn && lsn <= toBigInt(ddlSecretLsn)) return;
|
|
679
|
+
return `the event does not carry the secret of the ${upstreamSchema(this.#shard)} schema's event functions (secret ${typeof secret === "string" ? "mismatch" : "absent"}, installed at ${ddlSecretLsn ?? "unknown"})`;
|
|
680
|
+
}
|
|
646
681
|
#lastReplicationEvent;
|
|
682
|
+
#ddlEventsIgnored = getOrCreateCounter("replication", "ddl_events_ignored", {
|
|
683
|
+
description: "Number of ddl messages ignored because they were not emitted by the shard's upstream functions (missing or wrong secret, or not valid JSON).",
|
|
684
|
+
unit: "{message}"
|
|
685
|
+
});
|
|
647
686
|
#handleDdlMessage(lc, lsn, msg) {
|
|
648
|
-
const
|
|
687
|
+
const { ddlSecret, ddlSecretLsn } = this.#shardConfig;
|
|
688
|
+
assert(ddlSecret, "shard config has no ddl event secret");
|
|
689
|
+
const content = decodeLogicalMessage(msg);
|
|
690
|
+
let json;
|
|
691
|
+
let problem;
|
|
692
|
+
try {
|
|
693
|
+
json = JSON.parse(content);
|
|
694
|
+
} catch (e) {
|
|
695
|
+
problem = `not valid JSON: ${String(e)}`;
|
|
696
|
+
}
|
|
697
|
+
problem ??= this.#ddlEventOriginProblem(lsn, json, ddlSecret, ddlSecretLsn);
|
|
698
|
+
if (problem !== void 0) {
|
|
699
|
+
this.#ddlEventsIgnored.add(1);
|
|
700
|
+
lc.warn?.(`ignoring ${msg.prefix} message at ${fromBigInt(lsn)} (not emitted by the shard's upstream functions; replication continues): ${problem}`, describeUnverifiedMessage(json));
|
|
701
|
+
lc.debug?.(`ignored ${msg.prefix} message content`, { content: content.substring(0, 4096) });
|
|
702
|
+
return [];
|
|
703
|
+
}
|
|
704
|
+
const event = validateLogicalMessage(lc, msg, json, replicationEventSchema, () => stringify(field(json, "secret") === void 0 ? json : {
|
|
705
|
+
...json,
|
|
706
|
+
secret: "<redacted>"
|
|
707
|
+
}));
|
|
649
708
|
lc = lc.withContext("lsn", fromBigInt(lsn)).withContext("tag", event.event.tag).withContext("query", event.context.query);
|
|
650
709
|
if (event.previousSchema) warnForSkippedIndexes(lc, event.previousSchema, this.#skippedIndexWarnings);
|
|
651
710
|
if (event.schema) warnForSkippedIndexes(lc, event.schema, this.#skippedIndexWarnings);
|
|
@@ -999,8 +1058,7 @@ function summarizeSchemaForLog(schema) {
|
|
|
999
1058
|
};
|
|
1000
1059
|
}
|
|
1001
1060
|
function summarizeReplicationEventForLog(event) {
|
|
1002
|
-
const { schema, ...
|
|
1003
|
-
const { previousSchema, ...eventWithoutSchemas } = rest;
|
|
1061
|
+
const { schema, previousSchema, secret: _, ...eventWithoutSchemas } = event;
|
|
1004
1062
|
return {
|
|
1005
1063
|
...eventWithoutSchemas,
|
|
1006
1064
|
...schema !== void 0 && { schema: summarizeSchemaForLog(schema) },
|
|
@@ -1029,20 +1087,59 @@ var ShutdownSignal = class extends AbortError {
|
|
|
1029
1087
|
super("shutdown signal received (e.g. another zero-cache taking over the replication stream)", { cause });
|
|
1030
1088
|
}
|
|
1031
1089
|
};
|
|
1090
|
+
function decodeLogicalMessage({ content }) {
|
|
1091
|
+
return content instanceof Buffer ? content.toString("utf-8") : new TextDecoder().decode(content);
|
|
1092
|
+
}
|
|
1032
1093
|
function parseLogicalMessageContent(lc, msg, schema) {
|
|
1033
|
-
const
|
|
1034
|
-
|
|
1094
|
+
const str = decodeLogicalMessage(msg);
|
|
1095
|
+
let json;
|
|
1096
|
+
try {
|
|
1097
|
+
json = JSON.parse(str);
|
|
1098
|
+
} catch (e) {
|
|
1099
|
+
return failParse(lc, msg, e, str);
|
|
1100
|
+
}
|
|
1101
|
+
return validateLogicalMessage(lc, msg, json, schema, () => str);
|
|
1102
|
+
}
|
|
1103
|
+
function validateLogicalMessage(lc, msg, json, schema, contentForLog) {
|
|
1035
1104
|
try {
|
|
1036
|
-
const json = JSON.parse(str);
|
|
1037
1105
|
return parse(json, schema, "passthrough");
|
|
1038
1106
|
} catch (e) {
|
|
1039
|
-
lc
|
|
1040
|
-
...msg,
|
|
1041
|
-
content: str
|
|
1042
|
-
} });
|
|
1043
|
-
throw e;
|
|
1107
|
+
return failParse(lc, msg, e, contentForLog());
|
|
1044
1108
|
}
|
|
1045
1109
|
}
|
|
1110
|
+
/**
|
|
1111
|
+
* Logs and rethrows a parse failure. Any session that can call
|
|
1112
|
+
* `pg_logical_emit_message()` can emit a message with a prefix that the
|
|
1113
|
+
* zero-cache parses, so the content is untrusted: it is logged at `warn`
|
|
1114
|
+
* (callers skip the message, so there is nothing for an operator to fix in
|
|
1115
|
+
* zero-cache) without the content, which goes to `debug`, bounded.
|
|
1116
|
+
*/
|
|
1117
|
+
function failParse(lc, msg, e, content) {
|
|
1118
|
+
const { content: _, ...header } = msg;
|
|
1119
|
+
lc.warn?.(`unable to parse logical message content: ${String(e)}`, {
|
|
1120
|
+
message: header,
|
|
1121
|
+
contentLength: content.length
|
|
1122
|
+
});
|
|
1123
|
+
lc.debug?.(`unparseable logical message content`, { content: content.substring(0, 4096) });
|
|
1124
|
+
throw e;
|
|
1125
|
+
}
|
|
1126
|
+
/** A property of untrusted JSON, or `undefined` if there is no such property. */
|
|
1127
|
+
function field(json, name) {
|
|
1128
|
+
return typeof json === "object" && json !== null && name in json ? json[name] : void 0;
|
|
1129
|
+
}
|
|
1130
|
+
function describeUnverifiedMessage(json) {
|
|
1131
|
+
const str = (value) => typeof value === "string" ? value.substring(0, 200) : null;
|
|
1132
|
+
return {
|
|
1133
|
+
type: str(field(json, "type")),
|
|
1134
|
+
tag: str(field(field(json, "event"), "tag")),
|
|
1135
|
+
query: str(field(field(json, "context"), "query"))
|
|
1136
|
+
};
|
|
1137
|
+
}
|
|
1138
|
+
function equalSecrets(a, b) {
|
|
1139
|
+
const bufA = Buffer.from(a);
|
|
1140
|
+
const bufB = Buffer.from(b);
|
|
1141
|
+
return bufA.length === bufB.length && timingSafeEqual(bufA, bufB);
|
|
1142
|
+
}
|
|
1046
1143
|
//#endregion
|
|
1047
1144
|
export { Acker, LagReporter, PostgresChangeSource, isIndexStructurallyChanged, relationDifferent };
|
|
1048
1145
|
|