diff --git a/bun.lock b/bun.lock
index 56b0b71c..044671dd 100644
--- a/bun.lock
+++ b/bun.lock
@@ -688,7 +688,7 @@
},
"packages/ui": {
"name": "@wrnexus/ui",
- "version": "0.8.59",
+ "version": "0.8.60",
"dependencies": {
"@wrnexus/core": "workspace:*",
},
diff --git a/packages/dev-server/test/large-select-runtime.test.ts b/packages/dev-server/test/large-select-runtime.test.ts
new file mode 100644
index 00000000..5b357b85
--- /dev/null
+++ b/packages/dev-server/test/large-select-runtime.test.ts
@@ -0,0 +1,60 @@
+import { expect, test } from "bun:test";
+import { mkdirSync, mkdtempSync, writeFileSync, readFileSync, rmSync } from "node:fs";
+import { tmpdir } from "node:os";
+import { join, basename } from "node:path";
+import { buildRouter } from "@wrnexus/router";
+import { renderComponent } from "../../test/src/index.ts";
+import { createHandlers } from "../src/runtime.ts";
+
+test("large timezone select responds through the complete page renderer", async () => {
+ const root = mkdtempSync(join(tmpdir(), "wrn-large-select-"));
+ try {
+ mkdirSync(join(root, "pages"));
+ mkdirSync(join(root, "components"));
+ writeFileSync(join(root, "pages/index.ts"), "");
+ for (const name of ["AdvancedSelect", "SelectStyles", "Shell"])
+ writeFileSync(
+ join(root, `components/${name}.wrn`),
+ `component ${name} { view {
} }`,
+ );
+ const select = await renderComponent(
+ readFileSync(new URL("../../ui/components/AdvancedSelect.wrn", import.meta.url), "utf8"),
+ {
+ name: "timezone",
+ value: "UTC",
+ searchResultLimit: 40,
+ options: Intl.supportedValuesOf("timeZone").map((value) => ({ value, label: value })),
+ },
+ );
+ const handlers = createHandlers({
+ mode: "development",
+ hmr: false,
+ router: buildRouter(root),
+ loadModule: async (file) =>
+ basename(file) === "AdvancedSelect.wrn"
+ ? { render: () => select }
+ : basename(file) === "SelectStyles.wrn"
+ ? { render: () => "" }
+ : basename(file) === "Shell.wrn"
+ ? { render: () => "" }
+ : {
+ default: () =>
+ '",
+ },
+ getMiddleware: async () => [],
+ assets: { serve: async () => null },
+ });
+ const response = await handlers.fetch(new Request("http://example.test/"), {
+ upgrade: () => false,
+ });
+ expect(response?.status).toBe(200);
+ const html = await response!.text();
+ expect(html).toContain("Asia/Kolkata");
+ // Four full lists previously exceeded 11 MB, including hydration metadata.
+ expect(html.length).toBeLessThan(6_000_000);
+ } finally {
+ rmSync(root, { recursive: true, force: true });
+ }
+}, 15000);
diff --git a/packages/ui/components/AdvancedSelect.wrn b/packages/ui/components/AdvancedSelect.wrn
index 9f5b90ee..1042c55a 100644
--- a/packages/ui/components/AdvancedSelect.wrn
+++ b/packages/ui/components/AdvancedSelect.wrn
@@ -375,7 +375,7 @@ component AdvancedSelect {
{#if visibleOptions(group.options || []).length}
{group.label}
- {#each group.options || [] as option}
+ {#each visibleOptions(group.options || []) as option}