@vesk/compiler 0.2.61 → 0.2.62
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.
- package/dist/client-codegen.d.ts.map +1 -1
- package/dist/client-codegen.js +101 -3
- package/package.json +2 -2
|
@@ -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,EAUjB,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,CAI5E;AAyCD;;;;;;;;;;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;
|
|
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,EAUjB,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,CAI5E;AAyCD;;;;;;;;;;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;AAoFD,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;AA+nED,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
|
@@ -406,6 +406,78 @@ export function transformTrackedInit(init, tracked) {
|
|
|
406
406
|
return init;
|
|
407
407
|
return transformTracked({ raw: init, ast: expr }, tracked);
|
|
408
408
|
}
|
|
409
|
+
/**
|
|
410
|
+
* Names a body-level `RuntimeStatement` binds (`const list = …`, `let x = …`).
|
|
411
|
+
* Only top-level `Identifier` declarators count — destructuring patterns are
|
|
412
|
+
* rare here and a false negative only means we hoist, which is the previous
|
|
413
|
+
* behaviour.
|
|
414
|
+
*/
|
|
415
|
+
function runtimeDeclaredNames(node) {
|
|
416
|
+
if (!(node instanceof RuntimeStatement))
|
|
417
|
+
return [];
|
|
418
|
+
const stmt = node.ast;
|
|
419
|
+
if (!stmt || stmt.type !== 'VariableDeclaration' || !stmt.declarations)
|
|
420
|
+
return [];
|
|
421
|
+
const out = [];
|
|
422
|
+
for (const d of stmt.declarations) {
|
|
423
|
+
if (d.id && d.id.type === 'Identifier' && typeof d.id.name === 'string')
|
|
424
|
+
out.push(d.id.name);
|
|
425
|
+
}
|
|
426
|
+
return out;
|
|
427
|
+
}
|
|
428
|
+
/**
|
|
429
|
+
* Whether a `TrackDecl` initializer reads any of `names`. Parsed with the vsk
|
|
430
|
+
* parser (TS generics and `.vsk` syntax included) and walked AST-only — no
|
|
431
|
+
* regex over source. An unparsable init reports `false`, which keeps the
|
|
432
|
+
* previous hoist behaviour rather than silently changing emission order.
|
|
433
|
+
*/
|
|
434
|
+
function initReadsAnyOf(init, names) {
|
|
435
|
+
if (!init || names.size === 0)
|
|
436
|
+
return false;
|
|
437
|
+
let expr = null;
|
|
438
|
+
try {
|
|
439
|
+
const prog = parse(`(${init})`);
|
|
440
|
+
expr = prog.body?.[0]?.type === 'ExpressionStatement' ? (prog.body[0].expression ?? null) : null;
|
|
441
|
+
}
|
|
442
|
+
catch {
|
|
443
|
+
return false;
|
|
444
|
+
}
|
|
445
|
+
if (!expr)
|
|
446
|
+
return false;
|
|
447
|
+
let found = false;
|
|
448
|
+
const walk = (n) => {
|
|
449
|
+
if (found || !n || typeof n !== 'object')
|
|
450
|
+
return;
|
|
451
|
+
if (Array.isArray(n)) {
|
|
452
|
+
for (const c of n)
|
|
453
|
+
walk(c);
|
|
454
|
+
return;
|
|
455
|
+
}
|
|
456
|
+
const t = n.type;
|
|
457
|
+
if (typeof t !== 'string')
|
|
458
|
+
return;
|
|
459
|
+
if (t === 'Identifier') {
|
|
460
|
+
if (names.has(n.name))
|
|
461
|
+
found = true;
|
|
462
|
+
return;
|
|
463
|
+
}
|
|
464
|
+
if (t === 'MemberExpression') {
|
|
465
|
+
const m = n;
|
|
466
|
+
walk(m.object);
|
|
467
|
+
// A non-computed property is a field name, not a reference.
|
|
468
|
+
if (m.computed)
|
|
469
|
+
walk(m.property);
|
|
470
|
+
return;
|
|
471
|
+
}
|
|
472
|
+
for (const key of Object.keys(n)) {
|
|
473
|
+
if (key === 'loc' || key === 'range' || key === 'start' || key === 'end')
|
|
474
|
+
continue;
|
|
475
|
+
walk(n[key]);
|
|
476
|
+
}
|
|
477
|
+
};
|
|
478
|
+
walk(expr);
|
|
479
|
+
return found;
|
|
480
|
+
}
|
|
409
481
|
const NON_BUBBLING_EVENTS = new Set([
|
|
410
482
|
'focus', 'blur',
|
|
411
483
|
'mouseenter', 'mouseleave',
|
|
@@ -2484,9 +2556,29 @@ function generateComponent(comp, importedNames = new Set(), hydrate = false, asy
|
|
|
2484
2556
|
const paramInit = buildParamInit(comp.paramNames, comp.propsAlias);
|
|
2485
2557
|
if (paramInit)
|
|
2486
2558
|
ctx.push(indent(paramInit));
|
|
2487
|
-
// Hoist TrackDecls to top to avoid TDZ when Head/effects reference them before
|
|
2559
|
+
// Hoist TrackDecls to top to avoid TDZ when Head/effects reference them before
|
|
2560
|
+
// declaration — BUT a TrackDecl whose initializer reads a binding declared by
|
|
2561
|
+
// an EARLIER body statement must stay in place. Hoisting it turned
|
|
2562
|
+
// `const list = …; const &[sel] = track(list[0])` into
|
|
2563
|
+
// `const sel = track(list[0]); const list = …`, so the client threw
|
|
2564
|
+
// `ReferenceError: Cannot access 'list' before initialization` and the route
|
|
2565
|
+
// rendered the error page after hydration. Source order already satisfies the
|
|
2566
|
+
// Head/effect case, because both are emitted after the statements they read.
|
|
2567
|
+
const deferredTrackDecls = new Set();
|
|
2568
|
+
{
|
|
2569
|
+
const declaredSoFar = new Set();
|
|
2570
|
+
for (const node of comp.body) {
|
|
2571
|
+
if (node instanceof TrackDecl) {
|
|
2572
|
+
if (initReadsAnyOf(node.init, declaredSoFar))
|
|
2573
|
+
deferredTrackDecls.add(node);
|
|
2574
|
+
continue;
|
|
2575
|
+
}
|
|
2576
|
+
for (const name of runtimeDeclaredNames(node))
|
|
2577
|
+
declaredSoFar.add(name);
|
|
2578
|
+
}
|
|
2579
|
+
}
|
|
2488
2580
|
for (const node of comp.body) {
|
|
2489
|
-
if (node instanceof TrackDecl) {
|
|
2581
|
+
if (node instanceof TrackDecl && !deferredTrackDecls.has(node)) {
|
|
2490
2582
|
emitNode(ctx, node, tracked, null);
|
|
2491
2583
|
}
|
|
2492
2584
|
}
|
|
@@ -2539,8 +2631,14 @@ function generateComponent(comp, importedNames = new Set(), hydrate = false, asy
|
|
|
2539
2631
|
}
|
|
2540
2632
|
}
|
|
2541
2633
|
for (const node of comp.body) {
|
|
2542
|
-
|
|
2634
|
+
// A TrackDecl that could not be hoisted (its init reads an earlier body
|
|
2635
|
+
// binding) is emitted here, in source order, so the binding it reads is
|
|
2636
|
+
// already initialised.
|
|
2637
|
+
if (node instanceof TrackDecl) {
|
|
2638
|
+
if (deferredTrackDecls.has(node))
|
|
2639
|
+
emitNode(ctx, node, tracked, null);
|
|
2543
2640
|
continue;
|
|
2641
|
+
}
|
|
2544
2642
|
const v = emitNode(ctx, node, tracked, null, undefined, '__components', topPendingSkip, topBudget || undefined);
|
|
2545
2643
|
if (v) {
|
|
2546
2644
|
if (ctx.hydrate) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vesk/compiler",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.62",
|
|
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.62",
|
|
24
24
|
"acorn": "^8.15.0",
|
|
25
25
|
"esrap": "^2.3.0",
|
|
26
26
|
"is-reference": "^3.0.0",
|