feat(wasm): validate client event and state ABI
req: client_local/005\nreq: client_local/006\nreq: client_local/007\nreq: client_local/008\nreq: client_local/009\nreq: client_local/010\nreq: client_local/014
This commit is contained in:
+31
-6
@@ -238,13 +238,34 @@
|
||||
});
|
||||
}
|
||||
|
||||
async function runClient(el) {
|
||||
async function runClient(el, event) {
|
||||
const name = el.getAttribute("data-hemx-client");
|
||||
const root = rootOf(el);
|
||||
const handler = clientHandlers.get(name);
|
||||
if (!handler) throw new Error(`unknown client-local hemx handler: ${name}`);
|
||||
const wire = await handler();
|
||||
if (!(wire instanceof Uint8Array)) throw new Error(`client-local hemx handler ${name} returned an invalid effect batch`);
|
||||
applyBatch(wire, rootOf(el));
|
||||
showError(el, null);
|
||||
showPending(el, true);
|
||||
try {
|
||||
if (!handler) throw new Error(`unknown client-local hemx handler: ${name}`);
|
||||
const stateVersion = Number(root.getAttribute("data-hemx-client-state-version") || "1");
|
||||
const wire = await handler(
|
||||
1,
|
||||
event.type,
|
||||
"value" in el ? String(el.value) : undefined,
|
||||
"checked" in el ? Boolean(el.checked) : undefined,
|
||||
event.key || undefined,
|
||||
stateVersion,
|
||||
root.getAttribute(STATE) || "",
|
||||
);
|
||||
if (!(wire instanceof Uint8Array)) throw new Error(`client-local hemx handler ${name} returned an invalid effect batch`);
|
||||
applyBatch(wire, root);
|
||||
} catch (error) {
|
||||
const fallback = el.hasAttribute("data-hemx-client-fallback");
|
||||
showError(el, error);
|
||||
emit(root, "hemx:client-error", { handler: name, message: String(error), fallback });
|
||||
if (fallback) await send(el, event.type, el);
|
||||
} finally {
|
||||
showPending(el, false);
|
||||
}
|
||||
}
|
||||
|
||||
async function send(el, eventName, source = el) {
|
||||
@@ -682,7 +703,11 @@
|
||||
if (direct && defaultEvent(direct) === "click") {
|
||||
event.preventDefault();
|
||||
if (direct.hasAttribute("data-hemx-client")) {
|
||||
runClient(direct).catch((error) => emit(root, "hemx:client-error", String(error)));
|
||||
runClient(direct, event).catch((error) => emit(root, "hemx:client-error", {
|
||||
handler: direct.getAttribute("data-hemx-client"),
|
||||
message: String(error),
|
||||
fallback: false,
|
||||
}));
|
||||
} else {
|
||||
schedule(direct, name);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user