56 lines
2.1 KiB
JavaScript
56 lines
2.1 KiB
JavaScript
import { OperationLedger, LEDGER_SCHEMA, LEDGER_PHASES } from "./operation-ledger.mjs";
|
|
import { fnv1a64 } from "./replay.mjs";
|
|
|
|
export const XYZAC_COMMAND_LEDGER_SCHEMA = "xyzac-command-ledger.v1";
|
|
const TERMINAL_PHASES = new Set(["committed", "aborted", "failed"]);
|
|
|
|
export class XyzacCommandLedger extends OperationLedger {
|
|
constructor(entries = []) {
|
|
super(entries);
|
|
this.scope = "selected_xyzac_simulation";
|
|
}
|
|
|
|
prepare(input) {
|
|
if (["HELLO", "CAPABILITIES", "SNAPSHOT_REQUEST", "CANCEL"].includes(input?.kind)) return { status: "untracked", replay: false, entry: null };
|
|
const result = super.prepare(input);
|
|
if (result.entry) {
|
|
result.entry.scope = this.scope;
|
|
result.entry.intent_hash = result.entry.intent_hash ?? fnv1a64({ kind: input.kind, payload: input.payload ?? {}, operation_id: input.operation_id });
|
|
}
|
|
return result;
|
|
}
|
|
|
|
acknowledge(operationId, response) {
|
|
return this.verify(operationId, response);
|
|
}
|
|
|
|
result(operationId, response, seq) {
|
|
this.acknowledge(operationId, response);
|
|
return this.commit(operationId, seq);
|
|
}
|
|
|
|
pending() {
|
|
return [...this.entries.values()]
|
|
.filter((entry) => !TERMINAL_PHASES.has(entry.phase))
|
|
.sort((left, right) => left.seq - right.seq)
|
|
.map((entry) => structuredClone(entry));
|
|
}
|
|
|
|
reconcileAll() {
|
|
return this.pending().map((entry) => ({ operation_id: entry.operation_id, status: entry.phase, entry }));
|
|
}
|
|
|
|
timeoutReconcile(operationId) {
|
|
const reconciliation = this.reconcile(operationId);
|
|
return { status: "reconcile_required", operation_id: operationId, retry_allowed: false, reconciliation };
|
|
}
|
|
|
|
audit({ includeResponses = true } = {}) {
|
|
const exported = super.export();
|
|
const pending = this.pending();
|
|
const entries = includeResponses ? exported.entries : exported.entries.map((entry) => { const { response, ...summary } = entry; return summary; });
|
|
const unsigned = { schema: XYZAC_COMMAND_LEDGER_SCHEMA, operation_schema: LEDGER_SCHEMA, phases: [...LEDGER_PHASES], scope: this.scope, entries, pending_count: pending.length };
|
|
return { ...unsigned, state_hash: fnv1a64(unsigned) };
|
|
}
|
|
}
|