Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion deno.json
Original file line number Diff line number Diff line change
Expand Up @@ -403,7 +403,7 @@
"tasks": {
"setup": "deno run --allow-all scripts/setup.ts",
"generate": "deno run -A scripts/build/generate-templates-manifest.ts && deno run -A scripts/build/generate-dev-ui-manifest.ts && deno run -A scripts/build/prebundle-client-scripts.ts && deno run -A scripts/build/prebundle-bridge.ts && deno run -A scripts/build/prebundle-rsc-scripts.ts && deno run -A scripts/build/prebundle-hydration-runtime.ts",
"generate:manifests:check": "deno run -A scripts/build/generate-templates-manifest.ts --check && deno run -A scripts/build/generate-dev-ui-manifest.ts --check && deno run -A scripts/build/prebundle-hydration-runtime.ts --check",
"generate:manifests:check": "deno run -A scripts/build/generate-templates-manifest.ts --check && deno run -A scripts/build/generate-dev-ui-manifest.ts --check && deno run -A scripts/build/prebundle-hydration-runtime.ts --check && deno run -A scripts/build/prebundle-client-scripts.ts --check",
"start": "deno task generate && deno run --allow-read --allow-write --allow-net --allow-env --allow-run --allow-sys --unstable-worker-options --unstable-net cli/main.ts",
"start:headless": "deno task generate && deno run --allow-read --allow-write --allow-net --allow-env --allow-run --allow-sys --unstable-worker-options --unstable-net cli/main.ts --headless",
"proxy": "deno task generate && deno run --allow-read --allow-write --allow-net --allow-env --allow-run --allow-sys --unstable-worker-options --unstable-net cli/main.ts serve --mode=proxy",
Expand Down
71 changes: 60 additions & 11 deletions scripts/build/prebundle-client-scripts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,19 +41,64 @@ const candidatesPath = join(
"framework-candidates.generated.ts",
);

async function writeFormattedTypeScriptFile(path: string, contents: string): Promise<void> {
await Deno.writeTextFile(path, contents);
const result = await new Deno.Command("deno", {
args: ["fmt", path],
stdout: "null",
const checkMode = Deno.args.includes("--check");
const staleFiles: string[] = [];

/**
* Format through stdin rather than writing and formatting in place, so --check
* can compare against the same shape the write path lands on disk.
*/
async function formatTypeScript(source: string, path: string): Promise<string> {
const fmt = new Deno.Command("deno", {
args: ["fmt", "-", "--ext", "ts"],
stdin: "piped",
stdout: "piped",
stderr: "piped",
}).output();
}).spawn();

const writer = fmt.stdin.getWriter();
await writer.write(new TextEncoder().encode(source));
await writer.close();

const result = await fmt.output();
if (!result.success) {
const errorOutput = new TextDecoder().decode(result.stderr).trim();
// This script generates two files; without the path the failure says
// nothing about which one to go and look at.
throw new Error(
`Failed to format generated file ${path}${errorOutput ? `: ${errorOutput}` : ""}`,
);
}
return new TextDecoder().decode(result.stdout);
}

/**
* Writes the generated file, or under --check reports whether the committed
* copy still matches. Stale files are collected rather than exited on, so one
* run tells you everything that needs regenerating.
*/
async function emitGeneratedFile(
path: string,
contents: string,
detail: string,
): Promise<void> {
const formatted = await formatTypeScript(contents, path);

if (checkMode) {
const existing = await Deno.readTextFile(path).catch(() => null);
if (existing !== formatted) {
console.error(`${path} is stale. Run deno task generate.`);
staleFiles.push(path);
return;
}
console.log(`${path} is current.`);
console.log(` ${detail}`);
return;
}

await Deno.writeTextFile(path, formatted);
console.log(`✅ Generated ${path}`);
console.log(` ${detail}`);
}

console.log("[prebundle-client-scripts] Bundling client router...");
Expand All @@ -79,8 +124,7 @@ export const CLIENT_ROUTER_BUNDLE: string | undefined = ${JSON.stringify(routerB
export const CLIENT_PREFETCH_BUNDLE: string | undefined = ${JSON.stringify(prefetchBundle)};
`;

await writeFormattedTypeScriptFile(templatesPath, output);
console.log(`[prebundle-client-scripts] Written to ${templatesPath}`);
await emitGeneratedFile(templatesPath, output, "client router + prefetch bundles");

// --- Extract framework component Tailwind candidates ---
console.log("[prebundle-client-scripts] Extracting framework component candidates...");
Expand Down Expand Up @@ -133,7 +177,12 @@ const candidatesOutput = `/**
export const FRAMEWORK_CANDIDATES: readonly string[] = ${JSON.stringify(sorted, null, 2).replace(/\n\]$/, ",\n]")};
`;

await writeFormattedTypeScriptFile(candidatesPath, candidatesOutput);
console.log(
`[prebundle-client-scripts] Extracted ${sorted.length} framework candidates to ${candidatesPath}`,
await emitGeneratedFile(
candidatesPath,
candidatesOutput,
`${sorted.length} framework candidates`,
);

if (staleFiles.length > 0) {
Deno.exit(1);
}
28 changes: 27 additions & 1 deletion src/server/handlers/dev/framework-candidates.generated.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ export const FRAMEWORK_CANDIDATES: readonly string[] = [
"!value",
"!visible)",
"!w-auto",
"!warnedMissingAnchor)",
"-1",
"-1)",
"-1,",
Expand Down Expand Up @@ -489,6 +490,7 @@ export const FRAMEWORK_CANDIDATES: readonly string[] = [
"18a4",
"18px",
"19",
"19).",
"19.32Q12",
"19.78",
"19.9502a4.4992",
Expand Down Expand Up @@ -987,7 +989,6 @@ export const FRAMEWORK_CANDIDATES: readonly string[] = [
"Alternate",
"Always-visible",
"An",
"Anchor",
"AnchorRendererProps",
"AnchorRendererProps)",
"Anchored",
Expand Down Expand Up @@ -2285,6 +2286,7 @@ export const FRAMEWORK_CANDIDATES: readonly string[] = [
"DialogTrigger,",
"Dims",
"Disabled",
"Disclosure",
"DisclosureOptions",
"DisclosureOptions)",
"DisclosureOptions,",
Expand Down Expand Up @@ -3649,6 +3651,7 @@ export const FRAMEWORK_CANDIDATES: readonly string[] = [
"React.ReactNode>();",
"React.ReactNode>,",
"React.ReactNode>;",
"React.Ref<HTMLButtonElement>",
"React.Ref<HTMLButtonElement>;",
"React.Ref<HTMLDivElement>;",
"React.Ref<HTMLElement>",
Expand Down Expand Up @@ -4645,6 +4648,7 @@ export const FRAMEWORK_CANDIDATES: readonly string[] = [
"Waiting",
"Walk",
"Walking",
"Warn",
"Was",
"We",
"Web",
Expand Down Expand Up @@ -4963,6 +4967,7 @@ export const FRAMEWORK_CANDIDATES: readonly string[] = [
"[timeout]);",
"[topFaded,",
"[tracked,",
"[ui]",
"[uncontrolledOpen,",
"[update]);",
"[uploadError,",
Expand Down Expand Up @@ -5239,6 +5244,7 @@ export const FRAMEWORK_CANDIDATES: readonly string[] = [
"anchor:",
"anchorRef",
"anchorRef,",
"anchorRef.current",
"anchorRef.current?.closest<HTMLElement>(UI_SCOPE_SELECTOR)",
"anchorRef.current?.getBoundingClientRect();",
"anchorRef:",
Expand Down Expand Up @@ -5440,6 +5446,7 @@ export const FRAMEWORK_CANDIDATES: readonly string[] = [
"attachFilesLabel:",
"attachFilesLabel?:",
"attachFilesLabel}",
"attached",
"attaching",
"attachment",
"attachment,",
Expand Down Expand Up @@ -6019,6 +6026,7 @@ export const FRAMEWORK_CANDIDATES: readonly string[] = [
"cards)",
"cards,",
"cares",
"carried",
"carries",
"carry",
"cascade",
Expand Down Expand Up @@ -6443,6 +6451,7 @@ export const FRAMEWORK_CANDIDATES: readonly string[] = [
"composable",
"compose",
"composeRefs(forwardedRef,",
"composeRefs,",
"composeRefs<T>(",
"composed",
"composed).",
Expand Down Expand Up @@ -6512,6 +6521,7 @@ export const FRAMEWORK_CANDIDATES: readonly string[] = [
"considered",
"consistent",
"console.error(",
"console.warn(",
"const",
"const,",
"const;",
Expand Down Expand Up @@ -6582,6 +6592,7 @@ export const FRAMEWORK_CANDIDATES: readonly string[] = [
"continue;",
"contract",
"contract):",
"contract:",
"control",
"control,",
"control.",
Expand Down Expand Up @@ -6767,6 +6778,7 @@ export const FRAMEWORK_CANDIDATES: readonly string[] = [
"ctx:",
"ctx;",
"ctx?.activeConversationId",
"ctx?.anchorRef",
"ctx?.anchorRef;",
"ctx?.conversations",
"ctx?.open",
Expand Down Expand Up @@ -7191,6 +7203,7 @@ export const FRAMEWORK_CANDIDATES: readonly string[] = [
"documents",
"docx:",
"does",
"does;",
"doesn't",
"domain",
"don't",
Expand Down Expand Up @@ -7353,6 +7366,7 @@ export const FRAMEWORK_CANDIDATES: readonly string[] = [
"el.value.length;",
"element",
"element)",
"element).",
"element,",
"element.",
"element.getAttribute(",
Expand Down Expand Up @@ -8477,6 +8491,7 @@ export const FRAMEWORK_CANDIDATES: readonly string[] = [
"include",
"included",
"includes",
"including",
"increment",
"indentation",
"independent",
Expand Down Expand Up @@ -9325,6 +9340,7 @@ export const FRAMEWORK_CANDIDATES: readonly string[] = [
"menu).",
"menu,",
"menu.",
"menu;",
"menuOpen,",
"menuOpen:",
"menuOpen],",
Expand Down Expand Up @@ -10212,6 +10228,7 @@ export const FRAMEWORK_CANDIDATES: readonly string[] = [
"openai",
"openai/gpt-4o",
"openai:",
"opened",
"opening",
"opens",
"opens,",
Expand Down Expand Up @@ -10629,6 +10646,7 @@ export const FRAMEWORK_CANDIDATES: readonly string[] = [
"popover).",
"popover.",
"popover.tsx",
"popover;",
"populated",
"portal",
"portal,",
Expand All @@ -10651,6 +10669,7 @@ export const FRAMEWORK_CANDIDATES: readonly string[] = [
"positioned",
"positioning",
"positioning,",
"positioning-anchor",
"positions",
"positive",
"post-hydration",
Expand Down Expand Up @@ -11117,6 +11136,7 @@ export const FRAMEWORK_CANDIDATES: readonly string[] = [
"ref.current?.querySelector<HTMLElement>(FOCUSABLE);",
"ref:",
"ref={anchorRef}",
"ref={composeRefs<HTMLButtonElement>(",
"ref={fieldContainerRef}",
"ref={fileInputRef}",
"ref={inputRef}",
Expand Down Expand Up @@ -11225,6 +11245,7 @@ export const FRAMEWORK_CANDIDATES: readonly string[] = [
"render():",
"render();",
"render(id:",
"render,",
"render-or-compose",
"render.",
"renderAnswerPart(",
Expand Down Expand Up @@ -11730,6 +11751,7 @@ export const FRAMEWORK_CANDIDATES: readonly string[] = [
"serverItems]);",
"session",
"session's",
"session,",
"session.",
"sessionChat,",
"sessionChat:",
Expand Down Expand Up @@ -13171,6 +13193,8 @@ export const FRAMEWORK_CANDIDATES: readonly string[] = [
"ui/switch.tsx",
"ui/tokens",
"ui/tokens.tsx",
"unanchored",
"unanchored.",
"unavailable",
"unavailable).",
"unavailable,",
Expand Down Expand Up @@ -13765,7 +13789,9 @@ export const FRAMEWORK_CANDIDATES: readonly string[] = [
"waiting",
"waits",
"want",
"warnedMissingAnchor",
"warning:",
"warns",
"was",
"way.",
"way;",
Expand Down