pi-amq 0.1.1
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/CHANGELOG.md +66 -0
- package/LICENSE +21 -0
- package/README.md +92 -0
- package/THIRD_PARTY_NOTICES.md +33 -0
- package/dist/extension/guidance.d.ts +25 -0
- package/dist/extension/guidance.d.ts.map +1 -0
- package/dist/extension/guidance.js +121 -0
- package/dist/extension/guidance.js.map +1 -0
- package/dist/extension/guide.d.ts +30 -0
- package/dist/extension/guide.d.ts.map +1 -0
- package/dist/extension/guide.js +128 -0
- package/dist/extension/guide.js.map +1 -0
- package/dist/extension/index.d.ts +4 -0
- package/dist/extension/index.d.ts.map +1 -0
- package/dist/extension/index.js +6 -0
- package/dist/extension/index.js.map +1 -0
- package/dist/extension/runtime.d.ts +48 -0
- package/dist/extension/runtime.d.ts.map +1 -0
- package/dist/extension/runtime.js +1095 -0
- package/dist/extension/runtime.js.map +1 -0
- package/dist/extension/tools.d.ts +12 -0
- package/dist/extension/tools.d.ts.map +1 -0
- package/dist/extension/tools.js +198 -0
- package/dist/extension/tools.js.map +1 -0
- package/dist/extension/worker-runtime.d.ts +34 -0
- package/dist/extension/worker-runtime.d.ts.map +1 -0
- package/dist/extension/worker-runtime.js +974 -0
- package/dist/extension/worker-runtime.js.map +1 -0
- package/dist/extension/worker-tools.d.ts +140 -0
- package/dist/extension/worker-tools.d.ts.map +1 -0
- package/dist/extension/worker-tools.js +217 -0
- package/dist/extension/worker-tools.js.map +1 -0
- package/dist/integration/confirmed-bind-onboarding.d.ts +44 -0
- package/dist/integration/confirmed-bind-onboarding.d.ts.map +1 -0
- package/dist/integration/confirmed-bind-onboarding.js +199 -0
- package/dist/integration/confirmed-bind-onboarding.js.map +1 -0
- package/dist/integration/fleet-view.d.ts +66 -0
- package/dist/integration/fleet-view.d.ts.map +1 -0
- package/dist/integration/fleet-view.js +238 -0
- package/dist/integration/fleet-view.js.map +1 -0
- package/dist/integration/fresh-session-dispatcher.d.ts +66 -0
- package/dist/integration/fresh-session-dispatcher.d.ts.map +1 -0
- package/dist/integration/fresh-session-dispatcher.js +103 -0
- package/dist/integration/fresh-session-dispatcher.js.map +1 -0
- package/dist/integration/launch-preview.d.ts +31 -0
- package/dist/integration/launch-preview.d.ts.map +1 -0
- package/dist/integration/launch-preview.js +325 -0
- package/dist/integration/launch-preview.js.map +1 -0
- package/dist/integration/transport-port.d.ts +39 -0
- package/dist/integration/transport-port.d.ts.map +1 -0
- package/dist/integration/transport-port.js +2 -0
- package/dist/integration/transport-port.js.map +1 -0
- package/dist/integration/worker-completion-notifier.d.ts +22 -0
- package/dist/integration/worker-completion-notifier.d.ts.map +1 -0
- package/dist/integration/worker-completion-notifier.js +81 -0
- package/dist/integration/worker-completion-notifier.js.map +1 -0
- package/dist/transport/amq-cli-adapter.d.ts +41 -0
- package/dist/transport/amq-cli-adapter.d.ts.map +1 -0
- package/dist/transport/amq-cli-adapter.js +291 -0
- package/dist/transport/amq-cli-adapter.js.map +1 -0
- package/dist/transport/amq-message.d.ts +47 -0
- package/dist/transport/amq-message.d.ts.map +1 -0
- package/dist/transport/amq-message.js +173 -0
- package/dist/transport/amq-message.js.map +1 -0
- package/dist/transport/amq-operations.d.ts +105 -0
- package/dist/transport/amq-operations.d.ts.map +1 -0
- package/dist/transport/amq-operations.js +320 -0
- package/dist/transport/amq-operations.js.map +1 -0
- package/dist/transport/atomic-json.d.ts +18 -0
- package/dist/transport/atomic-json.d.ts.map +1 -0
- package/dist/transport/atomic-json.js +90 -0
- package/dist/transport/atomic-json.js.map +1 -0
- package/dist/transport/binding-resolver.d.ts +46 -0
- package/dist/transport/binding-resolver.d.ts.map +1 -0
- package/dist/transport/binding-resolver.js +389 -0
- package/dist/transport/binding-resolver.js.map +1 -0
- package/dist/transport/bridge-journal.d.ts +100 -0
- package/dist/transport/bridge-journal.d.ts.map +1 -0
- package/dist/transport/bridge-journal.js +459 -0
- package/dist/transport/bridge-journal.js.map +1 -0
- package/dist/transport/dlq-retry-audit.d.ts +28 -0
- package/dist/transport/dlq-retry-audit.d.ts.map +1 -0
- package/dist/transport/dlq-retry-audit.js +66 -0
- package/dist/transport/dlq-retry-audit.js.map +1 -0
- package/dist/transport/inbox-pump.d.ts +81 -0
- package/dist/transport/inbox-pump.d.ts.map +1 -0
- package/dist/transport/inbox-pump.js +558 -0
- package/dist/transport/inbox-pump.js.map +1 -0
- package/dist/transport/index.d.ts +12 -0
- package/dist/transport/index.d.ts.map +1 -0
- package/dist/transport/index.js +12 -0
- package/dist/transport/index.js.map +1 -0
- package/dist/transport/presence-projector.d.ts +29 -0
- package/dist/transport/presence-projector.d.ts.map +1 -0
- package/dist/transport/presence-projector.js +73 -0
- package/dist/transport/presence-projector.js.map +1 -0
- package/dist/transport/priority-delivery-scheduler.d.ts +85 -0
- package/dist/transport/priority-delivery-scheduler.d.ts.map +1 -0
- package/dist/transport/priority-delivery-scheduler.js +210 -0
- package/dist/transport/priority-delivery-scheduler.js.map +1 -0
- package/dist/transport/receiver-lease.d.ts +102 -0
- package/dist/transport/receiver-lease.d.ts.map +1 -0
- package/dist/transport/receiver-lease.js +778 -0
- package/dist/transport/receiver-lease.js.map +1 -0
- package/dist/transport/runtime-status.d.ts +48 -0
- package/dist/transport/runtime-status.d.ts.map +1 -0
- package/dist/transport/runtime-status.js +71 -0
- package/dist/transport/runtime-status.js.map +1 -0
- package/dist/workflow/atomic-storage.d.ts +12 -0
- package/dist/workflow/atomic-storage.d.ts.map +1 -0
- package/dist/workflow/atomic-storage.js +104 -0
- package/dist/workflow/atomic-storage.js.map +1 -0
- package/dist/workflow/budget.d.ts +18 -0
- package/dist/workflow/budget.d.ts.map +1 -0
- package/dist/workflow/budget.js +74 -0
- package/dist/workflow/budget.js.map +1 -0
- package/dist/workflow/index.d.ts +17 -0
- package/dist/workflow/index.d.ts.map +1 -0
- package/dist/workflow/index.js +17 -0
- package/dist/workflow/index.js.map +1 -0
- package/dist/workflow/lifecycle-projection.d.ts +18 -0
- package/dist/workflow/lifecycle-projection.d.ts.map +1 -0
- package/dist/workflow/lifecycle-projection.js +22 -0
- package/dist/workflow/lifecycle-projection.js.map +1 -0
- package/dist/workflow/model-fallback.d.ts +2 -0
- package/dist/workflow/model-fallback.d.ts.map +1 -0
- package/dist/workflow/model-fallback.js +17 -0
- package/dist/workflow/model-fallback.js.map +1 -0
- package/dist/workflow/pi-session-fork.d.ts +18 -0
- package/dist/workflow/pi-session-fork.d.ts.map +1 -0
- package/dist/workflow/pi-session-fork.js +80 -0
- package/dist/workflow/pi-session-fork.js.map +1 -0
- package/dist/workflow/run-artifacts.d.ts +5 -0
- package/dist/workflow/run-artifacts.d.ts.map +1 -0
- package/dist/workflow/run-artifacts.js +25 -0
- package/dist/workflow/run-artifacts.js.map +1 -0
- package/dist/workflow/run-cleanup.d.ts +70 -0
- package/dist/workflow/run-cleanup.d.ts.map +1 -0
- package/dist/workflow/run-cleanup.js +222 -0
- package/dist/workflow/run-cleanup.js.map +1 -0
- package/dist/workflow/run-gate.d.ts +43 -0
- package/dist/workflow/run-gate.d.ts.map +1 -0
- package/dist/workflow/run-gate.js +70 -0
- package/dist/workflow/run-gate.js.map +1 -0
- package/dist/workflow/run-store.d.ts +208 -0
- package/dist/workflow/run-store.d.ts.map +1 -0
- package/dist/workflow/run-store.js +2965 -0
- package/dist/workflow/run-store.js.map +1 -0
- package/dist/workflow/spawn-confirmation.d.ts +44 -0
- package/dist/workflow/spawn-confirmation.d.ts.map +1 -0
- package/dist/workflow/spawn-confirmation.js +228 -0
- package/dist/workflow/spawn-confirmation.js.map +1 -0
- package/dist/workflow/system-process-inspector.d.ts +9 -0
- package/dist/workflow/system-process-inspector.d.ts.map +1 -0
- package/dist/workflow/system-process-inspector.js +129 -0
- package/dist/workflow/system-process-inspector.js.map +1 -0
- package/dist/workflow/worker-child-extension.d.ts +3 -0
- package/dist/workflow/worker-child-extension.d.ts.map +1 -0
- package/dist/workflow/worker-child-extension.js +182 -0
- package/dist/workflow/worker-child-extension.js.map +1 -0
- package/dist/workflow/worker-gate.d.ts +74 -0
- package/dist/workflow/worker-gate.d.ts.map +1 -0
- package/dist/workflow/worker-gate.js +165 -0
- package/dist/workflow/worker-gate.js.map +1 -0
- package/dist/workflow/worker-launch.d.ts +65 -0
- package/dist/workflow/worker-launch.d.ts.map +1 -0
- package/dist/workflow/worker-launch.js +338 -0
- package/dist/workflow/worker-launch.js.map +1 -0
- package/dist/workflow/worker-model-catalog.d.ts +36 -0
- package/dist/workflow/worker-model-catalog.d.ts.map +1 -0
- package/dist/workflow/worker-model-catalog.js +105 -0
- package/dist/workflow/worker-model-catalog.js.map +1 -0
- package/dist/workflow/worker-process-supervisor.d.ts +110 -0
- package/dist/workflow/worker-process-supervisor.d.ts.map +1 -0
- package/dist/workflow/worker-process-supervisor.js +1188 -0
- package/dist/workflow/worker-process-supervisor.js.map +1 -0
- package/dist/workflow/worker-prompt-capsule.d.ts +32 -0
- package/dist/workflow/worker-prompt-capsule.d.ts.map +1 -0
- package/dist/workflow/worker-prompt-capsule.js +52 -0
- package/dist/workflow/worker-prompt-capsule.js.map +1 -0
- package/dist/workflow/worker-role-presets.d.ts +38 -0
- package/dist/workflow/worker-role-presets.d.ts.map +1 -0
- package/dist/workflow/worker-role-presets.js +201 -0
- package/dist/workflow/worker-role-presets.js.map +1 -0
- package/dist/workflow/workflow-doctor.d.ts +57 -0
- package/dist/workflow/workflow-doctor.d.ts.map +1 -0
- package/dist/workflow/workflow-doctor.js +289 -0
- package/dist/workflow/workflow-doctor.js.map +1 -0
- package/dist/workflow/workflow-lease.d.ts +125 -0
- package/dist/workflow/workflow-lease.d.ts.map +1 -0
- package/dist/workflow/workflow-lease.js +689 -0
- package/dist/workflow/workflow-lease.js.map +1 -0
- package/dist/workflow/workflow-types.d.ts +335 -0
- package/dist/workflow/workflow-types.d.ts.map +1 -0
- package/dist/workflow/workflow-types.js +11 -0
- package/dist/workflow/workflow-types.js.map +1 -0
- package/dist/workflow/workspace-paths.d.ts +4 -0
- package/dist/workflow/workspace-paths.d.ts.map +1 -0
- package/dist/workflow/workspace-paths.js +22 -0
- package/dist/workflow/workspace-paths.js.map +1 -0
- package/docs/conformance.md +116 -0
- package/docs/demo-transcript.md +34 -0
- package/docs/design.md +1481 -0
- package/docs/operator-guide.md +100 -0
- package/extension/guidance.ts +162 -0
- package/extension/guide.ts +155 -0
- package/extension/index.ts +8 -0
- package/extension/runtime.ts +1224 -0
- package/extension/tools.ts +221 -0
- package/extension/worker-runtime.ts +1150 -0
- package/extension/worker-tools.ts +276 -0
- package/integration/confirmed-bind-onboarding.ts +296 -0
- package/integration/fleet-view.ts +286 -0
- package/integration/fresh-session-dispatcher.ts +166 -0
- package/integration/launch-preview.ts +396 -0
- package/integration/transport-port.ts +29 -0
- package/integration/worker-completion-notifier.ts +98 -0
- package/package.json +55 -0
- package/roles/oracle.md +9 -0
- package/roles/researcher.md +8 -0
- package/roles/reviewer.md +9 -0
- package/roles/scout.md +8 -0
- package/roles/worker.md +10 -0
- package/scripts/demo-two-terminal.sh +59 -0
- package/skills/coordination-patterns/SKILL.md +41 -0
- package/skills/coordination-patterns/references/supervised-worker-fan-out.md +12 -0
- package/skills/coordination-patterns/references/today-mail-team.md +36 -0
- package/transport/amq-cli-adapter.ts +381 -0
- package/transport/amq-message.ts +218 -0
- package/transport/amq-operations.ts +482 -0
- package/transport/atomic-json.ts +115 -0
- package/transport/binding-resolver.ts +565 -0
- package/transport/bridge-journal.ts +588 -0
- package/transport/dlq-retry-audit.ts +97 -0
- package/transport/inbox-pump.ts +729 -0
- package/transport/index.ts +11 -0
- package/transport/presence-projector.ts +104 -0
- package/transport/priority-delivery-scheduler.ts +328 -0
- package/transport/receiver-lease.ts +945 -0
- package/transport/runtime-status.ts +112 -0
- package/workflow/.gitkeep +1 -0
- package/workflow/atomic-storage.ts +120 -0
- package/workflow/budget.ts +90 -0
- package/workflow/index.ts +16 -0
- package/workflow/lifecycle-projection.ts +37 -0
- package/workflow/model-fallback.ts +17 -0
- package/workflow/pi-session-fork.ts +96 -0
- package/workflow/run-artifacts.ts +36 -0
- package/workflow/run-cleanup.ts +315 -0
- package/workflow/run-gate.ts +122 -0
- package/workflow/run-store.ts +3890 -0
- package/workflow/spawn-confirmation.ts +305 -0
- package/workflow/system-process-inspector.ts +142 -0
- package/workflow/worker-child-extension.ts +193 -0
- package/workflow/worker-gate.ts +238 -0
- package/workflow/worker-launch.ts +485 -0
- package/workflow/worker-model-catalog.ts +165 -0
- package/workflow/worker-process-supervisor.ts +1504 -0
- package/workflow/worker-prompt-capsule.ts +81 -0
- package/workflow/worker-role-presets.ts +241 -0
- package/workflow/workflow-doctor.ts +400 -0
- package/workflow/workflow-lease.ts +905 -0
- package/workflow/workflow-types.ts +367 -0
- package/workflow/workspace-paths.ts +32 -0
|
@@ -0,0 +1,459 @@
|
|
|
1
|
+
import { mkdir, readdir } from "node:fs/promises";
|
|
2
|
+
import { isAbsolute, join, normalize } from "node:path";
|
|
3
|
+
import { readJson, writeAtomicJson, } from "./atomic-json.js";
|
|
4
|
+
import { ReceiverLeaseManager } from "./receiver-lease.js";
|
|
5
|
+
const RECORD_KEYS = [
|
|
6
|
+
"schema",
|
|
7
|
+
"id",
|
|
8
|
+
"attempt",
|
|
9
|
+
"phase",
|
|
10
|
+
"binding",
|
|
11
|
+
"leaseGeneration",
|
|
12
|
+
"targetSessionId",
|
|
13
|
+
"delivery",
|
|
14
|
+
"claimedAt",
|
|
15
|
+
"receiptWarning",
|
|
16
|
+
"updatedAt",
|
|
17
|
+
];
|
|
18
|
+
const BINDING_KEYS = ["rootId", "handle"];
|
|
19
|
+
/** Generation-fenced durable intent across the AMQ-to-pi delivery boundary. */
|
|
20
|
+
export class BridgeJournal {
|
|
21
|
+
#namespaceDirectory;
|
|
22
|
+
#leaseManager;
|
|
23
|
+
#now;
|
|
24
|
+
#atomicFault;
|
|
25
|
+
constructor(options) {
|
|
26
|
+
if (!isAbsolute(options.namespaceDirectory)) {
|
|
27
|
+
throw new TypeError("Bridge journal namespace must be absolute");
|
|
28
|
+
}
|
|
29
|
+
this.#namespaceDirectory = normalize(options.namespaceDirectory);
|
|
30
|
+
this.#leaseManager = options.leaseManager;
|
|
31
|
+
this.#now = options.now ?? (() => new Date());
|
|
32
|
+
this.#atomicFault = options.atomicFault;
|
|
33
|
+
}
|
|
34
|
+
async createPending(input) {
|
|
35
|
+
validateMessageId(input.id);
|
|
36
|
+
requirePositiveInteger(input.attempt, "bridge attempt");
|
|
37
|
+
const binding = parseBinding(input.binding);
|
|
38
|
+
requireNonEmpty(input.leaseGeneration, "lease generation");
|
|
39
|
+
return this.#leaseManager.withCurrentLease(input.leaseGeneration, async () => {
|
|
40
|
+
await this.#initialize();
|
|
41
|
+
const record = {
|
|
42
|
+
schema: 1,
|
|
43
|
+
id: input.id,
|
|
44
|
+
attempt: input.attempt,
|
|
45
|
+
phase: "pending",
|
|
46
|
+
binding,
|
|
47
|
+
leaseGeneration: input.leaseGeneration,
|
|
48
|
+
targetSessionId: null,
|
|
49
|
+
delivery: null,
|
|
50
|
+
claimedAt: null,
|
|
51
|
+
receiptWarning: null,
|
|
52
|
+
updatedAt: this.#now().toISOString(),
|
|
53
|
+
};
|
|
54
|
+
await writeAtomicJson(this.#path(input.id), record, {
|
|
55
|
+
createOnly: true,
|
|
56
|
+
...(this.#atomicFault ? { fault: this.#atomicFault } : {}),
|
|
57
|
+
});
|
|
58
|
+
return record;
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
async read(id) {
|
|
62
|
+
validateMessageId(id);
|
|
63
|
+
const raw = await readJson(this.#path(id));
|
|
64
|
+
return raw === undefined ? undefined : parseBridgeJournalRecordV1(raw);
|
|
65
|
+
}
|
|
66
|
+
async list() {
|
|
67
|
+
let entries;
|
|
68
|
+
try {
|
|
69
|
+
entries = await readdir(join(this.#namespaceDirectory, "journal"));
|
|
70
|
+
}
|
|
71
|
+
catch (error) {
|
|
72
|
+
if (isNodeError(error) && error.code === "ENOENT")
|
|
73
|
+
return [];
|
|
74
|
+
throw error;
|
|
75
|
+
}
|
|
76
|
+
const records = [];
|
|
77
|
+
for (const entry of entries.sort()) {
|
|
78
|
+
if (!entry.endsWith(".json") || entry.startsWith("."))
|
|
79
|
+
continue;
|
|
80
|
+
const raw = await readJson(join(this.#namespaceDirectory, "journal", entry));
|
|
81
|
+
if (raw === undefined)
|
|
82
|
+
continue;
|
|
83
|
+
records.push(parseBridgeJournalRecordV1(raw));
|
|
84
|
+
}
|
|
85
|
+
return records.sort((left, right) => left.id.localeCompare(right.id));
|
|
86
|
+
}
|
|
87
|
+
async readHistory(id, attempt) {
|
|
88
|
+
validateMessageId(id);
|
|
89
|
+
requirePositiveInteger(attempt, "bridge history attempt");
|
|
90
|
+
const raw = await readJson(this.#historyPath(id, attempt));
|
|
91
|
+
return raw === undefined ? undefined : parseBridgeAttemptHistoryV1(raw);
|
|
92
|
+
}
|
|
93
|
+
async adoptPending(id, generation, binding) {
|
|
94
|
+
validateMessageId(id);
|
|
95
|
+
requireNonEmpty(generation, "lease generation");
|
|
96
|
+
const expectedBinding = parseBinding(binding);
|
|
97
|
+
return this.#leaseManager.withCurrentLease(generation, async () => {
|
|
98
|
+
const record = await this.read(id);
|
|
99
|
+
if (!record)
|
|
100
|
+
throw new Error(`Bridge journal record ${id} does not exist`);
|
|
101
|
+
if (record.phase !== "pending") {
|
|
102
|
+
throw new Error(`Only a pending bridge journal record can be adopted, got ${record.phase}`);
|
|
103
|
+
}
|
|
104
|
+
if (record.binding.rootId !== expectedBinding.rootId
|
|
105
|
+
|| record.binding.handle !== expectedBinding.handle) {
|
|
106
|
+
throw new Error("Pending bridge journal binding does not match the current receiver");
|
|
107
|
+
}
|
|
108
|
+
if (record.leaseGeneration === generation)
|
|
109
|
+
return record;
|
|
110
|
+
const adopted = parseBridgeJournalRecordV1({
|
|
111
|
+
...record,
|
|
112
|
+
leaseGeneration: generation,
|
|
113
|
+
updatedAt: this.#now().toISOString(),
|
|
114
|
+
});
|
|
115
|
+
await writeAtomicJson(this.#path(id), adopted, {
|
|
116
|
+
...(this.#atomicFault ? { fault: this.#atomicFault } : {}),
|
|
117
|
+
});
|
|
118
|
+
return adopted;
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
async recordClaim(id, generation, claim) {
|
|
122
|
+
const claimedAt = requireIso(claim.claimedAt, "claimedAt");
|
|
123
|
+
const receiptWarning = claim.receiptWarning === undefined
|
|
124
|
+
? undefined
|
|
125
|
+
: optionalString(claim.receiptWarning, "receiptWarning");
|
|
126
|
+
return this.#mutatePending(id, generation, (record) => ({
|
|
127
|
+
...record,
|
|
128
|
+
claimedAt,
|
|
129
|
+
...(receiptWarning === undefined ? {} : { receiptWarning }),
|
|
130
|
+
updatedAt: this.#now().toISOString(),
|
|
131
|
+
}));
|
|
132
|
+
}
|
|
133
|
+
async setTarget(id, generation, target) {
|
|
134
|
+
const targetSessionId = requireNonEmpty(target.targetSessionId, "target session ID");
|
|
135
|
+
const delivery = parseDelivery(target.delivery);
|
|
136
|
+
return this.#mutatePending(id, generation, (record) => ({
|
|
137
|
+
...record,
|
|
138
|
+
targetSessionId,
|
|
139
|
+
delivery,
|
|
140
|
+
updatedAt: this.#now().toISOString(),
|
|
141
|
+
}));
|
|
142
|
+
}
|
|
143
|
+
async markInjected(id, generation, evidence) {
|
|
144
|
+
return this.#mutatePending(id, generation, (record) => {
|
|
145
|
+
if (!matchingDiskProjection(record, evidence)) {
|
|
146
|
+
throw new Error("Injected transition requires matching disk-visible pi projection evidence");
|
|
147
|
+
}
|
|
148
|
+
return {
|
|
149
|
+
...record,
|
|
150
|
+
phase: "injected",
|
|
151
|
+
updatedAt: this.#now().toISOString(),
|
|
152
|
+
};
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
async markDlq(id, generation, evidence) {
|
|
156
|
+
requireNonEmpty(evidence.diagnostic, "DLQ diagnostic");
|
|
157
|
+
return this.#mutatePending(id, generation, (record) => {
|
|
158
|
+
if (evidence.messageId !== record.id) {
|
|
159
|
+
throw new Error("DLQ evidence message ID does not match the journal record");
|
|
160
|
+
}
|
|
161
|
+
return {
|
|
162
|
+
...record,
|
|
163
|
+
phase: "dlq",
|
|
164
|
+
updatedAt: this.#now().toISOString(),
|
|
165
|
+
};
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
async promoteVerifiedRetry(id, generation, evidence) {
|
|
169
|
+
validateMessageId(id);
|
|
170
|
+
requireNonEmpty(generation, "lease generation");
|
|
171
|
+
const audit = parseBridgeRetryAuditEvidence(evidence);
|
|
172
|
+
if (audit.originalMessageId !== id || audit.visibleMessageId !== id) {
|
|
173
|
+
throw new Error("DLQ retry requires matching original and visibly redelivered message IDs");
|
|
174
|
+
}
|
|
175
|
+
return this.#leaseManager.withCurrentLease(generation, async () => {
|
|
176
|
+
const record = await this.read(id);
|
|
177
|
+
if (!record)
|
|
178
|
+
throw new Error(`Bridge journal record ${id} does not exist`);
|
|
179
|
+
if (record.leaseGeneration !== generation) {
|
|
180
|
+
throw new Error("Bridge journal lease generation does not match the current retry");
|
|
181
|
+
}
|
|
182
|
+
if (record.phase === "pending") {
|
|
183
|
+
const history = record.attempt > 1
|
|
184
|
+
? await this.readHistory(id, record.attempt - 1)
|
|
185
|
+
: undefined;
|
|
186
|
+
if (history && sameRetryAudit(history.retryAudit, audit))
|
|
187
|
+
return record;
|
|
188
|
+
throw new Error(`Bridge journal pending attempt ${record.attempt} cannot be promoted again`);
|
|
189
|
+
}
|
|
190
|
+
if (record.phase !== "dlq") {
|
|
191
|
+
throw new Error(`Bridge journal ${record.phase} phase cannot accept a DLQ retry`);
|
|
192
|
+
}
|
|
193
|
+
if (audit.retryCount !== record.attempt) {
|
|
194
|
+
if (await this.#retryAuditWasConsumed(id, audit.auditId)) {
|
|
195
|
+
throw new Error(`AMQ retry audit ${audit.auditId} was already consumed by an earlier bridge attempt`);
|
|
196
|
+
}
|
|
197
|
+
throw new Error(`AMQ retry count ${audit.retryCount} does not match terminal bridge attempt ${record.attempt}`);
|
|
198
|
+
}
|
|
199
|
+
await this.#initialize();
|
|
200
|
+
await mkdir(join(this.#namespaceDirectory, "history"), { recursive: true, mode: 0o700 });
|
|
201
|
+
const history = {
|
|
202
|
+
schema: "pi-amq-attempt-history/v1",
|
|
203
|
+
record,
|
|
204
|
+
retryAudit: audit,
|
|
205
|
+
};
|
|
206
|
+
const historyPath = this.#historyPath(id, record.attempt);
|
|
207
|
+
const existing = await readJson(historyPath);
|
|
208
|
+
if (existing === undefined) {
|
|
209
|
+
if (await this.#retryAuditWasConsumed(id, audit.auditId)) {
|
|
210
|
+
throw new Error(`AMQ retry audit ${audit.auditId} was already consumed by an earlier bridge attempt`);
|
|
211
|
+
}
|
|
212
|
+
await writeAtomicJson(historyPath, history, {
|
|
213
|
+
createOnly: true,
|
|
214
|
+
...(this.#atomicFault ? { fault: this.#atomicFault } : {}),
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
else {
|
|
218
|
+
const parsed = parseBridgeAttemptHistoryV1(existing);
|
|
219
|
+
if (!sameArchivedAttempt(parsed.record, record)
|
|
220
|
+
|| !sameRetryAudit(parsed.retryAudit, audit)) {
|
|
221
|
+
throw new Error(`Bridge attempt history ${record.attempt} conflicts with the verified retry audit`);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
const pending = {
|
|
225
|
+
schema: 1,
|
|
226
|
+
id,
|
|
227
|
+
attempt: record.attempt + 1,
|
|
228
|
+
phase: "pending",
|
|
229
|
+
binding: record.binding,
|
|
230
|
+
leaseGeneration: generation,
|
|
231
|
+
targetSessionId: null,
|
|
232
|
+
delivery: null,
|
|
233
|
+
claimedAt: null,
|
|
234
|
+
receiptWarning: null,
|
|
235
|
+
updatedAt: this.#now().toISOString(),
|
|
236
|
+
};
|
|
237
|
+
await writeAtomicJson(this.#path(id), pending, {
|
|
238
|
+
...(this.#atomicFault ? { fault: this.#atomicFault } : {}),
|
|
239
|
+
});
|
|
240
|
+
return pending;
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
async #mutatePending(id, generation, mutation) {
|
|
244
|
+
validateMessageId(id);
|
|
245
|
+
requireNonEmpty(generation, "lease generation");
|
|
246
|
+
return this.#leaseManager.withCurrentLease(generation, async () => {
|
|
247
|
+
const record = await this.read(id);
|
|
248
|
+
if (!record)
|
|
249
|
+
throw new Error(`Bridge journal record ${id} does not exist`);
|
|
250
|
+
if (record.leaseGeneration !== generation) {
|
|
251
|
+
throw new Error("Bridge journal lease generation does not match the current mutation");
|
|
252
|
+
}
|
|
253
|
+
if (record.phase !== "pending") {
|
|
254
|
+
throw new Error(`Bridge journal ${record.phase} phase is terminal for attempt ${record.attempt}`);
|
|
255
|
+
}
|
|
256
|
+
const updated = parseBridgeJournalRecordV1(mutation(record));
|
|
257
|
+
await writeAtomicJson(this.#path(id), updated, {
|
|
258
|
+
...(this.#atomicFault ? { fault: this.#atomicFault } : {}),
|
|
259
|
+
});
|
|
260
|
+
return updated;
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
async #initialize() {
|
|
264
|
+
await mkdir(join(this.#namespaceDirectory, "journal"), { recursive: true, mode: 0o700 });
|
|
265
|
+
}
|
|
266
|
+
#path(id) {
|
|
267
|
+
return join(this.#namespaceDirectory, "journal", `${id}.json`);
|
|
268
|
+
}
|
|
269
|
+
#historyPath(id, attempt) {
|
|
270
|
+
return join(this.#namespaceDirectory, "history", `${id}.attempt-${attempt}.json`);
|
|
271
|
+
}
|
|
272
|
+
async #retryAuditWasConsumed(id, auditId) {
|
|
273
|
+
let entries;
|
|
274
|
+
try {
|
|
275
|
+
entries = await readdir(join(this.#namespaceDirectory, "history"));
|
|
276
|
+
}
|
|
277
|
+
catch (error) {
|
|
278
|
+
if (isNodeError(error) && error.code === "ENOENT")
|
|
279
|
+
return false;
|
|
280
|
+
throw error;
|
|
281
|
+
}
|
|
282
|
+
for (const entry of entries) {
|
|
283
|
+
if (!entry.startsWith(`${id}.attempt-`) || !entry.endsWith(".json"))
|
|
284
|
+
continue;
|
|
285
|
+
const raw = await readJson(join(this.#namespaceDirectory, "history", entry));
|
|
286
|
+
if (raw && parseBridgeAttemptHistoryV1(raw).retryAudit.auditId === auditId)
|
|
287
|
+
return true;
|
|
288
|
+
}
|
|
289
|
+
return false;
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
export function planBridgeRecovery(record, facts) {
|
|
293
|
+
const parsed = parseBridgeJournalRecordV1(record);
|
|
294
|
+
if (parsed.phase === "dlq")
|
|
295
|
+
return { kind: "terminal-dlq" };
|
|
296
|
+
if (parsed.phase === "injected") {
|
|
297
|
+
return facts.projection && matchingDiskProjection(parsed, facts.projection)
|
|
298
|
+
? { kind: "already-injected" }
|
|
299
|
+
: { kind: "diagnostic", reason: "injected-projection-missing" };
|
|
300
|
+
}
|
|
301
|
+
if (facts.amqLocation === "dlq")
|
|
302
|
+
return { kind: "mark-dlq" };
|
|
303
|
+
if (facts.projection && matchingDiskProjection(parsed, facts.projection)) {
|
|
304
|
+
return { kind: "mark-injected" };
|
|
305
|
+
}
|
|
306
|
+
if (facts.amqLocation === "new")
|
|
307
|
+
return { kind: "exact-read", emitDrainedReceipt: true };
|
|
308
|
+
if (facts.amqLocation === "cur")
|
|
309
|
+
return { kind: "exact-read", emitDrainedReceipt: false };
|
|
310
|
+
return { kind: "needs-attention", reason: "message-not-found" };
|
|
311
|
+
}
|
|
312
|
+
export function parseBridgeJournalRecordV1(value) {
|
|
313
|
+
const object = strictRecord(value, RECORD_KEYS, "bridge journal record");
|
|
314
|
+
if (numeric(object, "schema") !== 1)
|
|
315
|
+
throw new Error("bridge journal schema must be 1");
|
|
316
|
+
const phase = object.phase;
|
|
317
|
+
if (phase !== "pending" && phase !== "injected" && phase !== "dlq") {
|
|
318
|
+
throw new Error("bridge journal phase is invalid");
|
|
319
|
+
}
|
|
320
|
+
const targetSessionId = optionalString(object.targetSessionId, "targetSessionId");
|
|
321
|
+
const delivery = object.delivery === null ? null : parseDelivery(object.delivery);
|
|
322
|
+
if ((targetSessionId === null) !== (delivery === null)) {
|
|
323
|
+
throw new Error("targetSessionId and delivery must be present together");
|
|
324
|
+
}
|
|
325
|
+
if (phase === "injected" && targetSessionId === null) {
|
|
326
|
+
throw new Error("injected bridge journal record requires a target session");
|
|
327
|
+
}
|
|
328
|
+
return {
|
|
329
|
+
schema: 1,
|
|
330
|
+
id: parseMessageId(object.id),
|
|
331
|
+
attempt: requirePositiveInteger(numeric(object, "attempt"), "bridge attempt"),
|
|
332
|
+
phase,
|
|
333
|
+
binding: parseBinding(object.binding),
|
|
334
|
+
leaseGeneration: string(object, "leaseGeneration"),
|
|
335
|
+
targetSessionId,
|
|
336
|
+
delivery,
|
|
337
|
+
claimedAt: optionalIso(object.claimedAt, "claimedAt"),
|
|
338
|
+
receiptWarning: optionalString(object.receiptWarning, "receiptWarning"),
|
|
339
|
+
updatedAt: requireIso(string(object, "updatedAt"), "updatedAt"),
|
|
340
|
+
};
|
|
341
|
+
}
|
|
342
|
+
export function parseBridgeAttemptHistoryV1(value) {
|
|
343
|
+
const object = strictRecord(value, ["schema", "record", "retryAudit"], "bridge attempt history");
|
|
344
|
+
if (object.schema !== "pi-amq-attempt-history/v1") {
|
|
345
|
+
throw new Error("bridge attempt history schema is invalid");
|
|
346
|
+
}
|
|
347
|
+
const record = parseBridgeJournalRecordV1(object.record);
|
|
348
|
+
if (record.phase !== "dlq")
|
|
349
|
+
throw new Error("bridge attempt history must archive a terminal DLQ record");
|
|
350
|
+
return {
|
|
351
|
+
schema: "pi-amq-attempt-history/v1",
|
|
352
|
+
record,
|
|
353
|
+
retryAudit: parseBridgeRetryAuditEvidence(object.retryAudit),
|
|
354
|
+
};
|
|
355
|
+
}
|
|
356
|
+
function parseBridgeRetryAuditEvidence(value) {
|
|
357
|
+
const object = strictRecord(value, ["auditId", "originalMessageId", "retryCount", "retryState", "visibleMessageId"], "bridge retry audit");
|
|
358
|
+
if (object.retryState !== "delivered")
|
|
359
|
+
throw new Error("AMQ retry audit must be delivered");
|
|
360
|
+
return {
|
|
361
|
+
auditId: string(object, "auditId"),
|
|
362
|
+
originalMessageId: parseMessageId(object.originalMessageId),
|
|
363
|
+
retryCount: requirePositiveInteger(numeric(object, "retryCount"), "AMQ retry count"),
|
|
364
|
+
retryState: "delivered",
|
|
365
|
+
visibleMessageId: parseMessageId(object.visibleMessageId),
|
|
366
|
+
};
|
|
367
|
+
}
|
|
368
|
+
function sameRetryAudit(left, right) {
|
|
369
|
+
return left.auditId === right.auditId
|
|
370
|
+
&& left.originalMessageId === right.originalMessageId
|
|
371
|
+
&& left.retryCount === right.retryCount
|
|
372
|
+
&& left.retryState === right.retryState
|
|
373
|
+
&& left.visibleMessageId === right.visibleMessageId;
|
|
374
|
+
}
|
|
375
|
+
function sameArchivedAttempt(left, right) {
|
|
376
|
+
return JSON.stringify(left) === JSON.stringify(right);
|
|
377
|
+
}
|
|
378
|
+
function matchingDiskProjection(record, evidence) {
|
|
379
|
+
return evidence.diskVisible
|
|
380
|
+
&& evidence.messageId === record.id
|
|
381
|
+
&& record.targetSessionId !== null
|
|
382
|
+
&& evidence.sessionId === record.targetSessionId;
|
|
383
|
+
}
|
|
384
|
+
function parseBinding(value) {
|
|
385
|
+
const object = strictRecord(value, BINDING_KEYS, "bridge binding");
|
|
386
|
+
return {
|
|
387
|
+
rootId: string(object, "rootId"),
|
|
388
|
+
handle: string(object, "handle"),
|
|
389
|
+
};
|
|
390
|
+
}
|
|
391
|
+
function parseDelivery(value) {
|
|
392
|
+
if (value === "steer" || value === "followUp" || value === "nextTurn" || value === "fresh-session") {
|
|
393
|
+
return value;
|
|
394
|
+
}
|
|
395
|
+
throw new Error("bridge delivery is invalid");
|
|
396
|
+
}
|
|
397
|
+
function parseMessageId(value) {
|
|
398
|
+
if (typeof value !== "string")
|
|
399
|
+
throw new Error("bridge message ID must be a string");
|
|
400
|
+
validateMessageId(value);
|
|
401
|
+
return value;
|
|
402
|
+
}
|
|
403
|
+
function validateMessageId(id) {
|
|
404
|
+
if (!/^[A-Za-z0-9][A-Za-z0-9._-]{0,254}$/.test(id)) {
|
|
405
|
+
throw new TypeError("Bridge message ID is not safe for the extension namespace");
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
function strictRecord(value, allowed, name) {
|
|
409
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
410
|
+
throw new Error(`${name} must be an object`);
|
|
411
|
+
}
|
|
412
|
+
const object = value;
|
|
413
|
+
const unknown = Object.keys(object).filter((key) => !allowed.includes(key));
|
|
414
|
+
if (unknown.length > 0)
|
|
415
|
+
throw new Error(`${name} contains unknown fields: ${unknown.join(", ")}`);
|
|
416
|
+
return object;
|
|
417
|
+
}
|
|
418
|
+
function string(object, key) {
|
|
419
|
+
const value = object[key];
|
|
420
|
+
if (typeof value !== "string" || value.length === 0)
|
|
421
|
+
throw new Error(`${key} must be a non-empty string`);
|
|
422
|
+
return value;
|
|
423
|
+
}
|
|
424
|
+
function numeric(object, key) {
|
|
425
|
+
const value = object[key];
|
|
426
|
+
if (typeof value !== "number" || !Number.isFinite(value))
|
|
427
|
+
throw new Error(`${key} must be a number`);
|
|
428
|
+
return value;
|
|
429
|
+
}
|
|
430
|
+
function optionalString(value, name) {
|
|
431
|
+
if (value === null)
|
|
432
|
+
return null;
|
|
433
|
+
if (typeof value !== "string" || value.length === 0)
|
|
434
|
+
throw new Error(`${name} must be null or a non-empty string`);
|
|
435
|
+
return value;
|
|
436
|
+
}
|
|
437
|
+
function optionalIso(value, name) {
|
|
438
|
+
const stringValue = optionalString(value, name);
|
|
439
|
+
return stringValue === null ? null : requireIso(stringValue, name);
|
|
440
|
+
}
|
|
441
|
+
function requireIso(value, name) {
|
|
442
|
+
if (!Number.isFinite(Date.parse(value)))
|
|
443
|
+
throw new Error(`${name} must be an ISO timestamp`);
|
|
444
|
+
return value;
|
|
445
|
+
}
|
|
446
|
+
function requirePositiveInteger(value, name) {
|
|
447
|
+
if (!Number.isSafeInteger(value) || value <= 0)
|
|
448
|
+
throw new TypeError(`${name} must be a positive safe integer`);
|
|
449
|
+
return value;
|
|
450
|
+
}
|
|
451
|
+
function requireNonEmpty(value, name) {
|
|
452
|
+
if (value.length === 0)
|
|
453
|
+
throw new TypeError(`${name} is required`);
|
|
454
|
+
return value;
|
|
455
|
+
}
|
|
456
|
+
function isNodeError(error) {
|
|
457
|
+
return error instanceof Error && "code" in error;
|
|
458
|
+
}
|
|
459
|
+
//# sourceMappingURL=bridge-journal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bridge-journal.js","sourceRoot":"","sources":["../../transport/bridge-journal.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { AmqCommandResult, AmqRunOptions } from "./amq-cli-adapter.js";
|
|
2
|
+
import type { BridgeRetryAuditEvidence } from "./bridge-journal.js";
|
|
3
|
+
interface JsonRunner {
|
|
4
|
+
runJson<T = unknown>(argv: readonly string[], options?: AmqRunOptions<T>): Promise<AmqCommandResult<T>>;
|
|
5
|
+
}
|
|
6
|
+
export interface DlqRetryAuditVerifier {
|
|
7
|
+
verify(visibleMessageId: string, signal?: AbortSignal): Promise<readonly BridgeRetryAuditEvidence[]>;
|
|
8
|
+
}
|
|
9
|
+
interface DlqListAudit {
|
|
10
|
+
readonly id: string;
|
|
11
|
+
readonly originalId: string;
|
|
12
|
+
readonly retryCount: number;
|
|
13
|
+
readonly retryState: string;
|
|
14
|
+
readonly retryDelivered: boolean;
|
|
15
|
+
}
|
|
16
|
+
/** Reads only AMQ's durable DLQ audit; visible redelivery is supplied by the inbox candidate. */
|
|
17
|
+
export declare class AmqDlqRetryAuditVerifier implements DlqRetryAuditVerifier {
|
|
18
|
+
#private;
|
|
19
|
+
constructor(options: {
|
|
20
|
+
readonly runner: JsonRunner;
|
|
21
|
+
readonly root: string;
|
|
22
|
+
readonly handle: string;
|
|
23
|
+
});
|
|
24
|
+
verify(visibleMessageId: string, signal?: AbortSignal): Promise<readonly BridgeRetryAuditEvidence[]>;
|
|
25
|
+
}
|
|
26
|
+
export declare function parseDlqListAudits(value: unknown): readonly DlqListAudit[];
|
|
27
|
+
export {};
|
|
28
|
+
//# sourceMappingURL=dlq-retry-audit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dlq-retry-audit.d.ts","sourceRoot":"","sources":["../../transport/dlq-retry-audit.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAC5E,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AAEpE,UAAU,UAAU;IAClB,OAAO,CAAC,CAAC,GAAG,OAAO,EACjB,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,OAAO,CAAC,EAAE,aAAa,CAAC,CAAC,CAAC,GACzB,OAAO,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC;CACjC;AAED,MAAM,WAAW,qBAAqB;IACpC,MAAM,CACJ,gBAAgB,EAAE,MAAM,EACxB,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,SAAS,wBAAwB,EAAE,CAAC,CAAC;CACjD;AAED,UAAU,YAAY;IACpB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC;CAClC;AAED,iGAAiG;AACjG,qBAAa,wBAAyB,YAAW,qBAAqB;;gBAKxD,OAAO,EAAE;QAAE,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;QAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;KAAE;IAM9F,MAAM,CACV,gBAAgB,EAAE,MAAM,EACxB,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,SAAS,wBAAwB,EAAE,CAAC;CAmBhD;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,SAAS,YAAY,EAAE,CAY1E"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/** Reads only AMQ's durable DLQ audit; visible redelivery is supplied by the inbox candidate. */
|
|
2
|
+
export class AmqDlqRetryAuditVerifier {
|
|
3
|
+
#runner;
|
|
4
|
+
#root;
|
|
5
|
+
#handle;
|
|
6
|
+
constructor(options) {
|
|
7
|
+
this.#runner = options.runner;
|
|
8
|
+
this.#root = options.root;
|
|
9
|
+
this.#handle = options.handle;
|
|
10
|
+
}
|
|
11
|
+
async verify(visibleMessageId, signal) {
|
|
12
|
+
const result = await this.#runner.runJson(["dlq", "list", "--root", this.#root, "--me", this.#handle, "--cur"], { ...(signal ? { signal } : {}), parse: parseDlqListAudits });
|
|
13
|
+
if (!result.ok || !result.json)
|
|
14
|
+
return [];
|
|
15
|
+
return result.json
|
|
16
|
+
.filter((item) => item.originalId === visibleMessageId
|
|
17
|
+
&& item.retryState === "delivered"
|
|
18
|
+
&& item.retryDelivered
|
|
19
|
+
&& item.retryCount > 0)
|
|
20
|
+
.map((item) => ({
|
|
21
|
+
auditId: item.id,
|
|
22
|
+
originalMessageId: item.originalId,
|
|
23
|
+
retryCount: item.retryCount,
|
|
24
|
+
retryState: "delivered",
|
|
25
|
+
visibleMessageId,
|
|
26
|
+
}));
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
export function parseDlqListAudits(value) {
|
|
30
|
+
if (!Array.isArray(value))
|
|
31
|
+
throw new Error("amq dlq list --json must return an array");
|
|
32
|
+
return value.map((item, index) => {
|
|
33
|
+
const object = record(item, `AMQ DLQ list item ${index}`);
|
|
34
|
+
return {
|
|
35
|
+
id: string(object, "id"),
|
|
36
|
+
originalId: string(object, "original_id"),
|
|
37
|
+
retryCount: nonNegativeInteger(object, "retry_count"),
|
|
38
|
+
retryState: string(object, "retry_state"),
|
|
39
|
+
retryDelivered: boolean(object, "retry_delivered"),
|
|
40
|
+
};
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
function record(value, name) {
|
|
44
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
45
|
+
throw new Error(`${name} must be an object`);
|
|
46
|
+
return value;
|
|
47
|
+
}
|
|
48
|
+
function string(object, key) {
|
|
49
|
+
const value = object[key];
|
|
50
|
+
if (typeof value !== "string" || value.length === 0)
|
|
51
|
+
throw new Error(`${key} must be a non-empty string`);
|
|
52
|
+
return value;
|
|
53
|
+
}
|
|
54
|
+
function nonNegativeInteger(object, key) {
|
|
55
|
+
const value = object[key];
|
|
56
|
+
if (!Number.isSafeInteger(value) || value < 0)
|
|
57
|
+
throw new Error(`${key} must be a non-negative integer`);
|
|
58
|
+
return value;
|
|
59
|
+
}
|
|
60
|
+
function boolean(object, key) {
|
|
61
|
+
const value = object[key];
|
|
62
|
+
if (typeof value !== "boolean")
|
|
63
|
+
throw new Error(`${key} must be a boolean`);
|
|
64
|
+
return value;
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=dlq-retry-audit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dlq-retry-audit.js","sourceRoot":"","sources":["../../transport/dlq-retry-audit.ts"],"names":[],"mappings":"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"}
|