release: WRNexusJS 0.8.3
Quality / quality (ubuntu-latest) (push) Failing after 12m9s
Quality / quality (windows-latest) (push) Canceled after 0s

This commit is contained in:
2026-08-03 19:47:30 +05:30
parent e8f630f12d
commit 4cebacadfe
156 changed files with 2608 additions and 473 deletions
+121
View File
@@ -452,3 +452,124 @@ test("$emit inside component functions does not depend on a global browser event
expect(win.document.querySelector("span")!.textContent).toBe("true");
expect(detail).toEqual({ source: "click" });
});
test("template literals work inside browser API call arguments", () => {
const behavior = Buffer.from(
JSON.stringify({
functions: `function save() {
window.localStorage.setItem(\`prefs:\${count}\`, JSON.stringify(count))
message = \`Saved \${count}\`
}`,
watches: [],
lifecycle: {},
}),
).toString("base64");
const win = mount(
`<div data-scope="count: 3, message: 'ready'" data-wrn-behavior="${behavior}">` +
`<button data-on-click="save()">{message}</button></div>`,
);
win.document.querySelector("button")!.click();
expect(win.localStorage.getItem("prefs:3")).toBe("3");
expect(win.document.querySelector("button")!.textContent).toBe("Saved 3");
});
test("compiled client functions are not overwritten by fallback behavior parsing", () => {
const behavior = Buffer.from(
JSON.stringify({
functions: `function save() { message = \`fallback\` }`,
watches: [],
lifecycle: {},
}),
).toString("base64");
const win = new Window() as unknown as Window & Record<string, unknown>;
win.document.body.innerHTML =
`<div id="scope" data-scope="message: 'ready'" data-wrn-behavior="${behavior}">` +
`<button data-on-click="save()">{message}</button></div>`;
const scope = win.document.getElementById("scope") as unknown as HTMLElement & {
__wrnexusClientModule?: unknown;
};
scope.__wrnexusClientModule = {
bindClientScope(context: { state: Record<string, unknown> }) {
return {
save() {
context.state.message = "native";
},
};
},
};
(globalThis as Record<string, unknown>).window = win;
(globalThis as Record<string, unknown>).document = win.document;
(globalThis as Record<string, unknown>).location = win.location;
(globalThis as Record<string, unknown>).NodeFilter = (
win as unknown as { NodeFilter: unknown }
).NodeFilter;
(globalThis as Record<string, unknown>).MutationObserver = (
win as unknown as { MutationObserver: unknown }
).MutationObserver;
(0, eval)(REACTIVE_RUNTIME);
(win as unknown as { __wrnexusHydrateScopes?: (root: unknown) => void }).__wrnexusHydrateScopes?.(
win.document,
);
win.document.querySelector("button")!.click();
expect(win.document.querySelector("button")!.textContent).toBe("native");
});
test("$route updates after client navigation", () => {
const win = new Window({ url: "http://localhost/" }) as unknown as Window &
Record<string, unknown>;
win.document.body.innerHTML =
`<span hidden data-wrn-route-params='{"id":"42"}'></span>` +
`<div data-scope=""><strong>{$route.pathname}</strong><em>{$route.params.id}</em></div>`;
(globalThis as Record<string, unknown>).window = win;
(globalThis as Record<string, unknown>).document = win.document;
(globalThis as Record<string, unknown>).location = win.location;
(globalThis as Record<string, unknown>).NodeFilter = (
win as unknown as { NodeFilter: unknown }
).NodeFilter;
(globalThis as Record<string, unknown>).MutationObserver = (
win as unknown as { MutationObserver: unknown }
).MutationObserver;
(0, eval)(REACTIVE_RUNTIME);
(win as unknown as { __wrnexusHydrateScopes?: (root: unknown) => void }).__wrnexusHydrateScopes?.(
win.document,
);
expect(win.document.querySelector("strong")!.textContent).toBe("/");
expect(win.document.querySelector("em")!.textContent).toBe("42");
expect(win.document.querySelector("[data-wrn-route-params]")).toBeNull();
win.history.pushState({}, "", "/settings?tab=chat");
win.dispatchEvent(
new (win as unknown as { CustomEvent: typeof CustomEvent }).CustomEvent(
"wrnexus:navigated",
) as unknown as Parameters<Window["dispatchEvent"]>[0],
);
expect(win.document.querySelector("strong")!.textContent).toBe("/settings");
});
test("cache invalidation refetches matching client Async boundaries", async () => {
let requests = 0;
(globalThis as Record<string, unknown>).fetch = () => {
requests++;
return Promise.resolve(Response.json({ data: { value: requests } }));
};
const win = mount(
`<section data-wrn-async="uploads" data-wrn-async-tags="uploads" data-wrn-async-retries="0">` +
`<div data-wrn-async-content></div>` +
`<template data-wrn-async-loading>Loading</template>` +
`<template data-wrn-async-success data-wrn-async-alias="uploads"><b>{uploads.value}</b></template>` +
`<template data-wrn-async-error data-wrn-async-alias="error">{error.message}</template>` +
`</section>`,
);
const runtime = win as unknown as { __wrnexusHydrateAsyncBoundaries?: (root: unknown) => void };
runtime.__wrnexusHydrateAsyncBoundaries?.(win.document);
await new Promise((resolve) => setTimeout(resolve, 0));
expect(win.document.querySelector("b")?.textContent).toBe("1");
win.dispatchEvent(
new (win as unknown as { CustomEvent: typeof CustomEvent }).CustomEvent(
"wrnexus:cache:invalidate",
{ detail: { tags: ["uploads"] } },
) as unknown as Parameters<Window["dispatchEvent"]>[0],
);
await new Promise((resolve) => setTimeout(resolve, 0));
expect(requests).toBe(2);
expect(win.document.querySelector("b")?.textContent).toBe("2");
});