feat: replace the ssr/client data blocks with apis blocks

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-20 07:59:37 +05:30
co-authored by Claude Opus 5
parent de99a2c2e0
commit 890d6106b3
14 changed files with 135 additions and 1421 deletions
+9 -13
View File
@@ -378,14 +378,13 @@ function clientCalledApiNames(ast: PageAst): Set<string> {
* never does either.
*/
function assertNoDynamicApiAccess(ast: PageAst): void {
// Only pages with a mode "any" block have anything at stake here: those
// Only pages with a sectioned api block have anything at stake here: those
// blocks are emitted solely because usage detection saw `api.<name>`, so a
// dynamic reference this scan can't see is the one that silently drops a
// block from the bundle. Mode "client" blocks always ship regardless of
// usage, and a page with no api blocks at all may still declare an
// ordinary `state api` (see the B5 regression test) where a bare "api"
// block from the bundle. A page with no api blocks at all may still declare
// an ordinary `state api` (see the B5 regression test) where a bare "api"
// identifier is just that state, not a missed block reference.
if (!ast.dataApis.some((block) => block.mode === "any" && block.sections)) return;
if (!ast.dataApis.some((block) => block.sections)) return;
for (const fn of ast.runtimeFunctions.filter((fn) => ["client", "shared"].includes(fn.runtime))) {
const masked = maskStringsAndComments(fn.body);
@@ -403,16 +402,13 @@ function assertNoDynamicApiAccess(ast: PageAst): void {
}
/**
* A block is emitted into the browser module when it is authored as
* client-only, or when it is mode "any" and a client function actually calls
* it. `hasClientApi` below must use this exact predicate so the `api`
* reserved-binding exclusion and the emitted object can never disagree.
* A block is emitted into the browser module when it declares typed sections
* and a client function actually calls it. `hasClientApi` below must use this
* exact predicate so the `api` reserved-binding exclusion and the emitted
* object can never disagree.
*/
function isClientEmittedApiBlock(block: PageAst["dataApis"][number], called: Set<string>): boolean {
return (
Boolean(block.sections) &&
(block.mode === "client" || (block.mode === "any" && called.has(block.name)))
);
return Boolean(block.sections) && called.has(block.name);
}
/**