Refresh UI components and showcase; release updated framework packages
This commit is contained in:
1 parent
d800228585
commit
c77f5e1cec
293 files changed
+22544
-35778
No files matched your search
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@wrnexus/ssr",
|
||||
"version": "0.8.11",
|
||||
"version": "0.8.12",
|
||||
"type": "module",
|
||||
"main": "src/index.ts",
|
||||
"exports": {
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* the browser, which keeps "server-only code" genuinely server-only.
|
||||
*/
|
||||
|
||||
import { escapeHtml, type PageMeta, type SeoConfig } from "@wrnexus/core";
|
||||
import { escapeHtml, renderControlTemplates, type PageMeta, type SeoConfig } from "@wrnexus/core";
|
||||
|
||||
export interface ScriptAsset {
|
||||
src: string;
|
||||
@@ -120,7 +120,7 @@ export function renderDocument(opts: RenderOptions): string {
|
||||
|
||||
const globalHead = opts.extraHead ? `\n ${opts.extraHead}` : "";
|
||||
const localStyles = extracted.styles ? `\n ${extracted.styles}` : "";
|
||||
const extraBody = opts.extraBody ? `\n ${opts.extraBody}` : "";
|
||||
const extraBody = renderControlTemplates() + (opts.extraBody ? `\n ${opts.extraBody}` : "");
|
||||
|
||||
const htmlAttrs = /(?:^|\s)lang\s*=/.test(opts.htmlAttrs ?? "")
|
||||
? (opts.htmlAttrs ?? "")
|
||||
@@ -445,7 +445,9 @@ export function renderDocumentStream(opts: StreamRenderOptions): ReadableStream<
|
||||
try {
|
||||
controller.enqueue(encoder.encode(prefix ?? ""));
|
||||
for await (const chunk of bodyChunks(opts.body)) controller.enqueue(encoder.encode(chunk));
|
||||
controller.enqueue(encoder.encode(suffix ?? ""));
|
||||
// Async body rendering can register templates after the shell is built.
|
||||
const tail = (suffix ?? "").replace(/<script type="application\/json" data-wrn-controls[^>]*>[\s\S]*?<\/script>/g, "");
|
||||
controller.enqueue(encoder.encode(renderControlTemplates() + tail));
|
||||
controller.close();
|
||||
} catch (error) {
|
||||
controller.error(error);
|
||||
|
||||
@@ -1,6 +1,21 @@
|
||||
import { expect, test } from "bun:test";
|
||||
import { renderDocument, renderDocumentStream, renderStoreHydration } from "../src/index.ts";
|
||||
import type { StoreContainer } from "@wrnexus/store";
|
||||
import { runWithRequestContext, encodeControlTemplate } from "@wrnexus/core";
|
||||
|
||||
test("streamed documents include templates registered by late body chunks", async () => {
|
||||
await runWithRequestContext({} as never, async () => {
|
||||
async function* body() {
|
||||
yield "<p>Shell</p>";
|
||||
await Promise.resolve();
|
||||
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('"body":"Late"');
|
||||
expect(html.match(/data-wrn-controls/g)).toHaveLength(1);
|
||||
});
|
||||
});
|
||||
|
||||
test("store hydration is HTML-safe, bounded, redacted, and JSON-compatible", () => {
|
||||
const container = {
|
||||
|
||||
Reference in new issue
Block a user