feat(sync): add typed flat patch boundary

req: sync/002

req: sync/003
This commit is contained in:
slhx agent
2026-07-13 21:02:43 +02:00
parent 25fcdae9b9
commit 34728b9a35
12 changed files with 625 additions and 11 deletions
+20 -3
View File
@@ -18,6 +18,7 @@
const sseSources = new WeakMap();
const atomStores = new WeakMap();
const dragKeys = new WeakMap();
let currentOperationId = null;
const clientHandlers = new Map();
const clientRuns = new WeakMap();
@@ -253,6 +254,7 @@
try {
if (!handler) throw new Error(`unknown client-local hemx handler: ${name}`);
const stateVersion = Number(root.getAttribute("data-hemx-client-state-version") || "1");
const operationId = crypto.randomUUID();
const wire = await handler(
1,
event.type,
@@ -264,7 +266,12 @@
);
if (!(wire instanceof Uint8Array)) throw new Error(`client-local hemx handler ${name} returned an invalid effect batch`);
if (!active()) return;
applyBatch(wire, root);
currentOperationId = operationId;
try {
applyBatch(wire, root);
} finally {
currentOperationId = null;
}
if (name === "reorder_card") {
const key = dragKeys.get(root) || el.getAttribute("data-card-id");
const moved = key ? firstElement(root, (node) => node.getAttribute("data-key") === key) : null;
@@ -469,8 +476,18 @@
if (op.title) document.title = op.title;
}
} else if (op.kind === "emit") {
handleRuntimeEvent(scope, op.name, op.payload);
emit(scope, op.name, op.payload);
let payload = op.payload;
if (currentOperationId && op.name === "hemx:sync-patch") {
const patch = JSON.parse(payload);
if (patch.idempotencyKey !== "$hemx-interaction" || patch.operationId !== "$hemx-interaction") {
throw new Error("hemx sync patch is missing its interaction identity");
}
patch.idempotencyKey = currentOperationId;
patch.operationId = currentOperationId;
payload = JSON.stringify(patch);
}
handleRuntimeEvent(scope, op.name, payload);
emit(scope, op.name, payload);
}
return true;
}