@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.
@@ -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;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;AAumED,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"}
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"}
@@ -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 declaration
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
- if (node instanceof TrackDecl)
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.61",
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.61",
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",