@vesk/compiler 0.2.57 → 0.2.58
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client-codegen.d.ts","sourceRoot":"","sources":["../src/client-codegen.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,MAAM,EAAuB,MAAM,uBAAuB,CAAC;AACzE,OAAO,EAGL,cAAc,EAQd,gBAAgB,EASjB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAkGxD,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,SAAS,GAAG,MAAM,CAAC;CAC1B;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAI1D;AAiDD,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,UAAU,GAAG,gBAAgB,GAAG,cAAc,EAAE,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,GAAG,MAAM,CAgJlI;AAID,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAU5E;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,GAAG,MAAM,EAAE,CAuB9F;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,GAAG,MAAM,CAY5F;AAoBD,qDAAqD;AACrD,MAAM,MAAM,SAAS,GAAG;IAAE,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAEtC;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,UAAU,CAAC,EAAE,MAAM,EAAE,KAAK,SAAI,GAAG,SAAS,CAQtE;
|
|
1
|
+
{"version":3,"file":"client-codegen.d.ts","sourceRoot":"","sources":["../src/client-codegen.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,MAAM,EAAuB,MAAM,uBAAuB,CAAC;AACzE,OAAO,EAGL,cAAc,EAQd,gBAAgB,EASjB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAkGxD,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,SAAS,GAAG,MAAM,CAAC;CAC1B;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAI1D;AAiDD,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,UAAU,GAAG,gBAAgB,GAAG,cAAc,EAAE,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,GAAG,MAAM,CAgJlI;AAID,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAU5E;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,GAAG,MAAM,EAAE,CAuB9F;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,GAAG,MAAM,CAY5F;AAoBD,qDAAqD;AACrD,MAAM,MAAM,SAAS,GAAG;IAAE,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAEtC;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,UAAU,CAAC,EAAE,MAAM,EAAE,KAAK,SAAI,GAAG,SAAS,CAQtE;AAmgED,iBAAS,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAe3C;AAmJD,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAO9C;AAuED,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,IAAI,EAAE,OAAO,GAAE;IAAE,WAAW,CAAC,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,eAAe,CAAC,EAAE,OAAO,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IAAC,aAAa,CAAC,EAAE,SAAS,CAAC;IAAC,UAAU,CAAC,EAAE,OAAO,CAAA;CAAO,GAAG,MAAM,CAOpQ;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,MAAM,EACd,cAAc,EAAE,MAAM,GAAG,IAAI,EAC7B,UAAU,CAAC,EAAE,MAAM,EACnB,IAAI,CAAC,EAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,UAAU,CAAC,EAAE,OAAO,CAAA;CAAE,GACjD;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,OAAO,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAAC,aAAa,EAAE,MAAM,EAAE,CAAC;IAAC,cAAc,EAAE,MAAM,EAAE,CAAA;CAAE,CAyC5J;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAG/E;AAED,OAAO,EAAE,aAAa,IAAI,OAAO,EAAE,UAAU,EAAE,CAAC"}
|
package/dist/client-codegen.js
CHANGED
|
@@ -2334,6 +2334,42 @@ function generateComponent(comp, importedNames = new Set(), hydrate = false, asy
|
|
|
2334
2334
|
// budget intact for the next claim.
|
|
2335
2335
|
topBudget = regionBudgetVar(ctx, 0, undefined, `(typeof __hydrate.takeSkipK === 'function' ? __hydrate.takeSkipK() : 0)`);
|
|
2336
2336
|
}
|
|
2337
|
+
if (ctx.hydrate) {
|
|
2338
|
+
// A component whose body emits NO claim still rendered SSR content: hydrate
|
|
2339
|
+
// mode never re-creates a static subtree, so that content stays in the DOM
|
|
2340
|
+
// with nobody to own it. The NEXT sibling's claim then landed on it, read
|
|
2341
|
+
// the tag mismatch as a divergence, consumed the slot and DETACHED it —
|
|
2342
|
+
// handing back a fresh element that never reached the document, so this
|
|
2343
|
+
// component rendered but was inert. A bare `effect()` plus static markup is
|
|
2344
|
+
// exactly this case: not "fully static" (so it gets no claimOnly stub from
|
|
2345
|
+
// the component map below) and yet it claims nothing.
|
|
2346
|
+
//
|
|
2347
|
+
// The component claims its OWN slots instead, which is what the fully-static
|
|
2348
|
+
// stub already does. Counting is exact here because the guard below admits
|
|
2349
|
+
// only top-level static/text/runtime nodes: each StaticNode is one server
|
|
2350
|
+
// element, and fragments are flattened into the node list by the IR
|
|
2351
|
+
// generator rather than wrapped. If anything in the body could claim, or
|
|
2352
|
+
// anything is a region/loop/call whose slot count depends on which branch
|
|
2353
|
+
// ran, no prelude is emitted — the callee stays exactly as it was.
|
|
2354
|
+
//
|
|
2355
|
+
// This is compile-time only: no runtime walker change and no per-call-site
|
|
2356
|
+
// marker, so it costs nothing in the client bundle.
|
|
2357
|
+
const bodyNodes = comp.body.filter((node) => !(node instanceof TrackDecl));
|
|
2358
|
+
// Text is never a walker slot: a top-level text binding and a bare text
|
|
2359
|
+
// statement both render into an element's interior, so they neither claim
|
|
2360
|
+
// nor occupy a top-level slot.
|
|
2361
|
+
const slotless = (node) => node instanceof StaticNode || node instanceof TextNode || node instanceof RuntimeStatement
|
|
2362
|
+
|| (node instanceof DynamicBinding && node.kind === 'text');
|
|
2363
|
+
const claimless = bodyNodes.every((node) => slotless(node) && !claimsWalkerNode(ctx, node));
|
|
2364
|
+
if (claimless) {
|
|
2365
|
+
const slots = bodyNodes.filter((node) => node instanceof StaticNode).length;
|
|
2366
|
+
for (let i = 0; i < slots; i++) {
|
|
2367
|
+
ctx.push(indent(`__hydrate.claimOnly(undefined, ${i === 0 && topBudget ? topBudget : '0'});`));
|
|
2368
|
+
if (i === 0 && topBudget)
|
|
2369
|
+
ctx.push(indent(`${topBudget} = 0;`));
|
|
2370
|
+
}
|
|
2371
|
+
}
|
|
2372
|
+
}
|
|
2337
2373
|
for (const node of comp.body) {
|
|
2338
2374
|
if (node instanceof TrackDecl)
|
|
2339
2375
|
continue;
|
|
@@ -2374,7 +2410,31 @@ function generateComponent(comp, importedNames = new Set(), hydrate = false, asy
|
|
|
2374
2410
|
ctx.push(indent(`return __pendingChild || $mount;`));
|
|
2375
2411
|
}
|
|
2376
2412
|
else {
|
|
2377
|
-
|
|
2413
|
+
// A bare `{props.children}` slot is this layout's output, but the layout may
|
|
2414
|
+
// ALSO have siblings of its own (a static island, a `<nav>`). Those land in
|
|
2415
|
+
// `$root`, and returning only the slot threw them away on every FRESH
|
|
2416
|
+
// render — after any SPA navigation the layout was just the page with no
|
|
2417
|
+
// nav, while a hard load of the same URL was fine (SSR emits the whole
|
|
2418
|
+
// chain). Hydrate mode is deliberately untouched: there the return value is
|
|
2419
|
+
// ignored by the router and the claims are already in place in the DOM.
|
|
2420
|
+
//
|
|
2421
|
+
// GATED on the body actually holding a bare slot. In a fresh render
|
|
2422
|
+
// `__pendingChild` is assigned ONLY by the bare-slot branch (every other
|
|
2423
|
+
// slot appends into its parent element), so without a top-level SlotNode
|
|
2424
|
+
// this code is unreachable — and emitting five lines per component cost
|
|
2425
|
+
// ~18 KB across test-app, which is the whole app's route payload. The
|
|
2426
|
+
// promise branch is not dead weight either: the router hands a suspending
|
|
2427
|
+
// page to the layout as a promise, so the slot content really can be one.
|
|
2428
|
+
const hasBareSlot = comp.body.some((node) => node instanceof SlotNode);
|
|
2429
|
+
if (hasBareSlot) {
|
|
2430
|
+
ctx.push(indent(`if (__pendingChild !== null && __pendingChild !== undefined) {`));
|
|
2431
|
+
ctx.push(indent(` if (typeof __pendingChild.then === 'function') return __pendingChild.then((__c) => { $root.appendChild(toDomNode(__c)); return $root; });`));
|
|
2432
|
+
ctx.push(indent(` const __c = toDomNode(__pendingChild);`));
|
|
2433
|
+
ctx.push(indent(` if ($root.childNodes.length === 0) return __c;`));
|
|
2434
|
+
ctx.push(indent(` $root.appendChild(__c);`));
|
|
2435
|
+
ctx.push(indent(`}`));
|
|
2436
|
+
}
|
|
2437
|
+
ctx.push(indent(hasBareSlot ? `return $root;` : `return __pendingChild || $root;`));
|
|
2378
2438
|
}
|
|
2379
2439
|
ctx.push(indent(`} finally {`));
|
|
2380
2440
|
ctx.push(indent(`\tsetActiveComponent(__prev);`));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vesk/compiler",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.58",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Vesk compiler — lexer, parser, semantic analysis, IR, codegen",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
22
22
|
"@sveltejs/acorn-typescript": "^1.0.0",
|
|
23
|
-
"@vesk/types": "^0.2.
|
|
23
|
+
"@vesk/types": "^0.2.58",
|
|
24
24
|
"acorn": "^8.15.0",
|
|
25
25
|
"esrap": "^2.3.0",
|
|
26
26
|
"is-reference": "^3.0.0",
|