feat: release design system engine, studio and component contracts
This commit is contained in:
1 parent
ff1065fb27
commit
3943b946d6
693 files changed
+175546
-3894
No files matched your search
@@ -3,6 +3,35 @@ import { renderDocument, renderDocumentStream, renderStoreHydration } from "../s
|
||||
import type { StoreContainer } from "@wrnexus/store";
|
||||
import { runWithRequestContext, encodeControlTemplate } from "@wrnexus/core";
|
||||
|
||||
test("inactive hydration branches share nonce-tagged styles without changing registry source", () => {
|
||||
runWithRequestContext({} as never, () => {
|
||||
const css = ".review{color:blue}".repeat(500);
|
||||
const style = `<style data-wrnexus-style-id="review" data-wrnexus-style-owner="Review" data-wrnexus-style-kind="component">${css}</style>`;
|
||||
const reference = encodeControlTemplate([
|
||||
{ cond: "open", body: `${style.repeat(30)}<button>Review</button>` },
|
||||
]);
|
||||
const options = {
|
||||
meta: {},
|
||||
body: `<template data-wrn-if="${reference}"></template>${style}`,
|
||||
styleNonce: "review-nonce",
|
||||
};
|
||||
for (let attempt = 0; attempt < 2; attempt++) {
|
||||
const html = renderDocument(options);
|
||||
expect(html.match(/data-wrnexus-style-id="review"/g)).toHaveLength(1);
|
||||
expect(html).toContain('nonce="review-nonce"');
|
||||
expect(html.indexOf(css)).toBeLessThan(html.indexOf("</head>"));
|
||||
const definitions = JSON.parse(/data-wrn-controls[^>]*>(.*?)<\/script>/s.exec(html)![1]!);
|
||||
expect(definitions[0][0].body).toBe("<button>Review</button>");
|
||||
expect(html.length).toBeLessThan(css.length + 2000);
|
||||
}
|
||||
const inactiveOnly = renderDocument({
|
||||
meta: {},
|
||||
body: `<template data-wrn-if="${reference}"></template>`,
|
||||
});
|
||||
expect(inactiveOnly).toContain(css);
|
||||
});
|
||||
});
|
||||
|
||||
test("streamed documents include templates registered by late body chunks", async () => {
|
||||
await runWithRequestContext({} as never, async () => {
|
||||
async function* body() {
|
||||
@@ -11,7 +40,7 @@ test("streamed documents include templates registered by late body chunks", asyn
|
||||
yield `<template data-wrn-if="${encodeControlTemplate([{ cond: null, body: "Late" }])}"></template>`;
|
||||
}
|
||||
const html = await new Response(renderDocumentStream({ meta: {}, body: body() })).text();
|
||||
expect(html).toContain('data-wrn-controls');
|
||||
expect(html).toContain("data-wrn-controls");
|
||||
expect(html).toContain('"body":"Late"');
|
||||
expect(html.match(/data-wrn-controls/g)).toHaveLength(1);
|
||||
});
|
||||
@@ -185,3 +214,98 @@ test("places document-layout WRN styles at the end of head", () => {
|
||||
expect(styleIndex).toBeLessThan(headEnd);
|
||||
expect(html).not.toContain("<body><style");
|
||||
});
|
||||
|
||||
test("repeated behavior descriptors are shared across body and inactive templates", () => {
|
||||
runWithRequestContext({} as never, () => {
|
||||
const behavior = {
|
||||
functions: "function increment(){count++}",
|
||||
outputs: [],
|
||||
computed: [],
|
||||
effects: [],
|
||||
lifecycle: {},
|
||||
watches: [],
|
||||
};
|
||||
const encoded = Buffer.from(JSON.stringify(behavior)).toString("base64");
|
||||
const instance = `<div data-scope="count: 0" data-wrn-behavior="${encoded}"><button>Increment</button></div>`;
|
||||
const reference = encodeControlTemplate([{ cond: "open", body: instance.repeat(100) }]);
|
||||
const document = renderDocument({
|
||||
meta: {},
|
||||
body: instance.repeat(100) + `<template data-wrn-if="${reference}"></template>`,
|
||||
});
|
||||
const definitions = JSON.parse(/data-wrn-controls[^>]*>(.*?)<\/script>/s.exec(document)![1]!);
|
||||
expect(definitions.filter((entry: any) => entry.functions)).toHaveLength(1);
|
||||
expect(document).not.toContain(`data-wrn-behavior="${encoded}"`);
|
||||
expect(document.match(/data-wrn-behavior="@/g)?.length).toBe(100);
|
||||
expect(definitions[0][0].body.match(/data-wrn-behavior="@/g)).toHaveLength(100);
|
||||
expect(document.length).toBeLessThan(instance.length * 200);
|
||||
});
|
||||
});
|
||||
|
||||
test("old client navigation keeps inline behavior while capable clients use references", () => {
|
||||
const encoded = Buffer.from(
|
||||
JSON.stringify({ functions: "function increment(){count++}" }),
|
||||
).toString("base64");
|
||||
for (const capable of [false, true])
|
||||
runWithRequestContext(
|
||||
{
|
||||
req: new Request("https://example.test/next", {
|
||||
headers: {
|
||||
"x-wrnexus-nav": "1",
|
||||
...(capable ? { "x-wrnexus-behaviors": "registry-v1" } : {}),
|
||||
},
|
||||
}),
|
||||
} as never,
|
||||
() => {
|
||||
const html = renderDocument({
|
||||
meta: {},
|
||||
body: `<div data-scope="count: 0" data-wrn-behavior="${encoded}"></div>`,
|
||||
});
|
||||
expect(html.includes(`data-wrn-behavior="${encoded}"`)).toBe(!capable);
|
||||
expect(html.includes('data-wrn-behavior="@')).toBe(capable);
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
test("scope and loop metadata share a request value without duplicating fallback declarations", () => {
|
||||
const encoded = Buffer.from(
|
||||
JSON.stringify({ items: Array.from({ length: 30 }, (_, i) => ({ label: "Menu " + i })) }),
|
||||
).toString("base64");
|
||||
for (const mode of ["registry-v1", "registry-v2"])
|
||||
runWithRequestContext(
|
||||
{
|
||||
req: new Request("https://example.test/", {
|
||||
headers: { "x-wrnexus-nav": "1", "x-wrnexus-behaviors": mode },
|
||||
}),
|
||||
} as never,
|
||||
() => {
|
||||
const node = `<div data-scope="items: []" data-wrn-scope="${encoded}"><button data-wrn-loop-locals="${encoded}">Menu</button></div>`;
|
||||
const html = renderDocument({ meta: {}, body: node.repeat(50) });
|
||||
if (mode === "registry-v1") {
|
||||
expect(html).toContain(`data-wrn-scope="${encoded}"`);
|
||||
expect(html).toContain('data-scope="items: []"');
|
||||
} else {
|
||||
expect(html).not.toContain(encoded);
|
||||
expect(html).toContain('data-scope=""');
|
||||
expect(html).toContain('data-wrn-loop-locals="@');
|
||||
expect(html.length).toBeLessThan(node.length * 10);
|
||||
}
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
test("scope state named body remains data rather than a control template", () => {
|
||||
runWithRequestContext({} as never, () => {
|
||||
const value = {
|
||||
body: '<style data-wrnexus-style-id="user">literal user text</style>',
|
||||
label: "keep",
|
||||
};
|
||||
const encoded = Buffer.from(JSON.stringify(value)).toString("base64");
|
||||
const html = renderDocument({
|
||||
meta: {},
|
||||
body: `<div data-scope="" data-wrn-scope="${encoded}"></div>`,
|
||||
});
|
||||
const entries = JSON.parse(/data-wrn-controls[^>]*>(.*?)<\/script>/s.exec(html)![1]!);
|
||||
expect(entries.find((entry: any) => entry.__wrnMetadata)?.value).toEqual(value);
|
||||
expect(html.split("</head>")[0]).not.toContain("literal user text");
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user