@vesk/compiler 0.2.50 → 0.2.52

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.
@@ -7,6 +7,7 @@ import { walk } from 'zimmerframe';
7
7
  import { parse } from '@vesk/compiler/src/parser';
8
8
  import { stripTsTypes, hasTsSyntax, isTypeOnlyStatement } from '@vesk/compiler/src/strip-ts';
9
9
  import { importModuleTarget } from '@vesk/compiler/src/tokens';
10
+ import { VeskError } from '@vesk/compiler/src/errors';
10
11
  // =============================================================
11
12
  // SSR module-value imports.
12
13
  //
@@ -246,6 +247,12 @@ export function loadSsrModule(absPath) {
246
247
  // transitive closure on every cold load (tens of seconds dev, too slow to
247
248
  // ship in prod).
248
249
  const src = readSsrSource(absPath);
250
+ // Report here, before any fallback can run. `nativeRequireFallback` and
251
+ // the raw-source substitution both "succeed" in the sense that they
252
+ // return something, which is how an unparseable module used to keep
253
+ // going and fail somewhere else entirely.
254
+ if (src?.parseError)
255
+ throw src.parseError;
249
256
  const body = (src?.ast?.body || []);
250
257
  if (src && isPureReexportBarrel(body)) {
251
258
  exportsObj = createLazyBarrelExports(buildBarrelSpec(body), dirname(absPath));
@@ -365,14 +372,31 @@ export function readSsrSource(absPath) {
365
372
  return null;
366
373
  }
367
374
  const raw = cachedRaw;
368
- let ast = null;
369
375
  try {
370
- ast = parse(raw, { filename: absPath });
371
- }
372
- catch {
373
- ast = null;
376
+ return { raw, ast: parse(raw, { filename: absPath }) };
377
+ }
378
+ catch (e) {
379
+ // A parse failure is a BUILD FAILURE, not a fallback. It used to return
380
+ // `ast: null` silently, and the caller then substituted the raw source — so
381
+ // the file's TypeScript syntax reached `new Function` and surfaced as a
382
+ // bare `Unexpected token ':'` in whichever module imported it, with no
383
+ // file, no line, and (because the module's exports came back undefined) a
384
+ // trail of unrelated `X is not iterable` failures behind it.
385
+ const err = e;
386
+ let parseError;
387
+ if (err instanceof VeskError) {
388
+ // `parse()` already produced a located diagnostic for this file. Keep its
389
+ // message, frame and position — they are strictly better than a wrapper's
390
+ // — and add the code so the failure is identifiable in build logs.
391
+ parseError = err;
392
+ if (err.code === undefined)
393
+ err.code = 'V0901';
394
+ }
395
+ else {
396
+ parseError = VeskError.moduleParseFailed({ file: absPath, reason: e?.message });
397
+ }
398
+ return { raw, ast: null, parseError };
374
399
  }
375
- return { raw, ast };
376
400
  }
377
401
  /** True when every statement in a module body is a re-export (or a type-only /
378
402
  * directive statement). Such "pure barrels" carry no computation of their own,
@@ -481,7 +505,11 @@ function createLazyBarrelExports(spec, dir) {
481
505
  const loadSource = (source) => {
482
506
  let target = targets.get(source);
483
507
  if (!target) {
484
- target = resolveSsrModule(source, dir) ?? '';
508
+ // Compiler-owned sources resolve through their package `exports` map, not
509
+ // the project's tsconfig `paths` (see `createModuleRequire`).
510
+ target = (isCompilerOwnedTarget(source)
511
+ ? resolveCompilerOwnedModule(source)
512
+ : resolveSsrModule(source, dir)) ?? '';
485
513
  if (!target)
486
514
  return null;
487
515
  targets.set(source, target);
@@ -590,6 +618,11 @@ function evaluateModuleFile(absPath, exportsObj, src) {
590
618
  let ast;
591
619
  if (src) {
592
620
  ast = src.ast;
621
+ // Report the parse failure at the file that caused it rather than letting
622
+ // the raw source reach `new Function` and fail as a SyntaxError nobody can
623
+ // trace back.
624
+ if (!ast && src.parseError)
625
+ throw src.parseError;
593
626
  }
594
627
  else {
595
628
  try {
@@ -684,8 +717,59 @@ function scanUnsupportedNode(node, inFunction = false) {
684
717
  return null;
685
718
  }
686
719
  /** Recursive `require` used inside evaluated modules, rooted at their dir. */
720
+ /**
721
+ * Resolve a compiler-owned (`@vesk/*`) specifier WITHOUT consulting tsconfig
722
+ * `paths`. The package's own `exports` map is the authority for its own
723
+ * subpaths — and it points at built JavaScript.
724
+ */
725
+ function resolveCompilerOwnedModule(specifier) {
726
+ const viaExports = resolveViaPackageExports(specifier, process.cwd());
727
+ if (viaExports)
728
+ return viaExports;
729
+ const viaModuleField = resolveViaPackageModuleField(specifier, process.cwd());
730
+ if (viaModuleField)
731
+ return viaModuleField;
732
+ const native = nativeResolve(specifier, process.cwd());
733
+ if (native && !isBuiltinPath(native))
734
+ return native;
735
+ return null;
736
+ }
687
737
  function createModuleRequire(fromDir) {
688
738
  return (specifier) => {
739
+ // `@vesk/*` is compiler-owned, and it is BUILT JavaScript by the time it
740
+ // ships (`@vesk/runtime` → `dist/index-client.js`). It must not go through
741
+ // this loader at all, which parses with the `.vsk` grammar.
742
+ //
743
+ // Both halves of that were wrong, and together they took down any module
744
+ // that imported BOTH a `@vesk/*` package and a relative module:
745
+ //
746
+ // 1. Resolution used the project's tsconfig `paths`, which map
747
+ // `@vesk/runtime/*` to `packages/runtime/src/*`, while the package's own
748
+ // `exports` map sends the same specifier to `dist/*.js`. The alias won,
749
+ // so the loader was handed raw TypeScript.
750
+ // 2. The built runtime entry is itself a re-export barrel, so it became a
751
+ // lazy Proxy. Reading any name resolved a source file and parsed it
752
+ // with the `.vsk` grammar — which rejects `component` as a reserved
753
+ // word, so even `dist/ripple-runtime.js` failed.
754
+ //
755
+ // The resulting throw escaped the proxy read and propagated out of the
756
+ // IMPORTING module's evaluation, so every one of its exports came back
757
+ // `undefined` and any `track(...)` cell in it threw
758
+ // `Cannot read properties of undefined (reading 'get')`.
759
+ //
760
+ // Native `require` is the right loader here: these packages ship plain JS
761
+ // with a real `exports` map, exactly what Node is for. The bare-only and
762
+ // relative-only cases each happened to recover via `nativeRequireFallback`,
763
+ // which is why each looked fine in isolation and only the combination broke.
764
+ if (isCompilerOwnedTarget(specifier)) {
765
+ const resolved = resolveCompilerOwnedModule(specifier);
766
+ if (resolved) {
767
+ const native = nativeRequireFallback(resolved);
768
+ if (native)
769
+ return native;
770
+ }
771
+ throw new Error(`Cannot load module '${specifier}'`);
772
+ }
689
773
  const resolved = resolveSsrModule(specifier, fromDir);
690
774
  if (!resolved)
691
775
  throw new Error(`Cannot find module '${specifier}'`);
@@ -1454,6 +1538,11 @@ export function collectModuleBundled(absPath, collector) {
1454
1538
  else {
1455
1539
  const src = readSsrSource(absPath);
1456
1540
  if (!src || !src.ast) {
1541
+ // A module we could not parse is a hard failure. Substituting the raw
1542
+ // source (the historical behavior) pushes every type annotation in this
1543
+ // file into `new Function` and blames some unrelated module later.
1544
+ if (src?.parseError)
1545
+ throw src.parseError;
1457
1546
  const raw = src ? src.raw : '// unreadable during build\nmodule.exports = {};';
1458
1547
  collector.modules.push({ key, code: raw, dir, deps: {} });
1459
1548
  return key;
package/dist/parser.d.ts CHANGED
@@ -33,6 +33,35 @@ export declare function preprocessForClauses(source: string): {
33
33
  code: string;
34
34
  annotations: VeskAnnotation[];
35
35
  };
36
+ /**
37
+ * Blanks the type parameter list of a GENERIC ARROW function:
38
+ *
39
+ * const read = <T,>(key: string, fallback: T): T => fallback;
40
+ *
41
+ * The list is type-only information the TS stripper deletes anyway, and it is
42
+ * unrepresentable in the tokenizer this parser uses: a `<` in expression
43
+ * position is read as `jsxTagStart`, and inside it the tokenizer emits
44
+ * `jsxName` / `jsxTagEnd` — never type tokens. So the construct could not be
45
+ * parsed at all, while `function f<T>(…)` and `async <T,>(…)` both could.
46
+ *
47
+ * That failure was silent rather than loud. `readSsrSource` treats a parse
48
+ * error as "not a module we understand" and substitutes the RAW, untranspiled
49
+ * source, so the parse error surfaced much later as
50
+ * `Unexpected token ':'` while the emitted module was being evaluated.
51
+ *
52
+ * Blanked IN PLACE — same character length, so every source offset, and
53
+ * therefore every AST node position, is preserved. This runs alongside the
54
+ * `{#clause}` and specifier-export passes for the same reason.
55
+ *
56
+ * The disambiguation is structural, not textual: the `>` must be followed by the
57
+ * arrow's PARAMETER list and then (after an optional return type) by `=>`. That
58
+ * is what separates `const f = <T,>(k: T): T => k` from the JSX
59
+ * `const a = <div>(hi)</div>`, where the `>` is also followed by `(` but never
60
+ * by `=>`. Type arguments (`f<T>(x)`) and comparisons fail the same test, so
61
+ * they are left untouched. A `<` inside a string, template or comment is
62
+ * skipped by the lexical scan before any of this runs.
63
+ */
64
+ export declare function blankGenericArrowTypeParams(source: string): string;
36
65
  export declare function createBaseParser(): typeof acorn.Parser;
37
66
  /**
38
67
  * Parse GENERATED JavaScript with plain acorn — no TypeScript plugin, no
@@ -1 +1 @@
1
- {"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../src/parser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAOtC,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,YAAY,CAAC;IACnB,8CAA8C;IAC9C,QAAQ,EAAE,MAAM,CAAC;IACjB,gEAAgE;IAChE,WAAW,EAAE,MAAM,CAAC;IACpB,8CAA8C;IAC9C,SAAS,EAAE,MAAM,CAAC;IAClB,0EAA0E;IAC1E,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5B,sDAAsD;IACtD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AA0BD;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,cAAc,EAAE,CAAA;CAAE,CA4LpG;AAED,wBAAgB,gBAAgB,IAAI,OAAO,KAAK,CAAC,MAAM,CAEtD;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI,CAM/D;AAED,wBAAgB,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,YAAiB,GAAG,OAAO,CAuEzE"}
1
+ {"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../src/parser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAOtC,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,YAAY,CAAC;IACnB,8CAA8C;IAC9C,QAAQ,EAAE,MAAM,CAAC;IACjB,gEAAgE;IAChE,WAAW,EAAE,MAAM,CAAC;IACpB,8CAA8C;IAC9C,SAAS,EAAE,MAAM,CAAC;IAClB,0EAA0E;IAC1E,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5B,sDAAsD;IACtD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AA0BD;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,cAAc,EAAE,CAAA;CAAE,CA4LpG;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAwFlE;AA2DD,wBAAgB,gBAAgB,IAAI,OAAO,KAAK,CAAC,MAAM,CAEtD;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI,CAM/D;AAED,wBAAgB,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,YAAiB,GAAG,OAAO,CAuEzE"}
package/dist/parser.js CHANGED
@@ -253,6 +253,226 @@ export function preprocessForClauses(source) {
253
253
  }
254
254
  return { code: chars.join(''), annotations };
255
255
  }
256
+ /**
257
+ * Blanks the type parameter list of a GENERIC ARROW function:
258
+ *
259
+ * const read = <T,>(key: string, fallback: T): T => fallback;
260
+ *
261
+ * The list is type-only information the TS stripper deletes anyway, and it is
262
+ * unrepresentable in the tokenizer this parser uses: a `<` in expression
263
+ * position is read as `jsxTagStart`, and inside it the tokenizer emits
264
+ * `jsxName` / `jsxTagEnd` — never type tokens. So the construct could not be
265
+ * parsed at all, while `function f<T>(…)` and `async <T,>(…)` both could.
266
+ *
267
+ * That failure was silent rather than loud. `readSsrSource` treats a parse
268
+ * error as "not a module we understand" and substitutes the RAW, untranspiled
269
+ * source, so the parse error surfaced much later as
270
+ * `Unexpected token ':'` while the emitted module was being evaluated.
271
+ *
272
+ * Blanked IN PLACE — same character length, so every source offset, and
273
+ * therefore every AST node position, is preserved. This runs alongside the
274
+ * `{#clause}` and specifier-export passes for the same reason.
275
+ *
276
+ * The disambiguation is structural, not textual: the `>` must be followed by the
277
+ * arrow's PARAMETER list and then (after an optional return type) by `=>`. That
278
+ * is what separates `const f = <T,>(k: T): T => k` from the JSX
279
+ * `const a = <div>(hi)</div>`, where the `>` is also followed by `(` but never
280
+ * by `=>`. Type arguments (`f<T>(x)`) and comparisons fail the same test, so
281
+ * they are left untouched. A `<` inside a string, template or comment is
282
+ * skipped by the lexical scan before any of this runs.
283
+ */
284
+ export function blankGenericArrowTypeParams(source) {
285
+ let changed = false;
286
+ const chars = source.split('');
287
+ let i = 0;
288
+ const isSpace = (ch) => isSpaceChar(ch);
289
+ while (i < source.length) {
290
+ const ch = source[i];
291
+ // Skip strings, templates and comments — the same lexical discipline the
292
+ // clause pass uses, so a `<T,>` inside a string or comment is never touched.
293
+ if (ch === '"' || ch === "'" || ch === '`') {
294
+ const quote = ch;
295
+ let j = i + 1;
296
+ while (j < source.length) {
297
+ if (source[j] === '\\') {
298
+ j += 2;
299
+ continue;
300
+ }
301
+ if (source[j] === quote) {
302
+ j++;
303
+ break;
304
+ }
305
+ if (quote === '`' && source[j] === '$' && source[j + 1] === '{') {
306
+ let depth = 1;
307
+ j += 2;
308
+ while (j < source.length && depth > 0) {
309
+ if (source[j] === '{')
310
+ depth++;
311
+ else if (source[j] === '}')
312
+ depth--;
313
+ j++;
314
+ }
315
+ continue;
316
+ }
317
+ j++;
318
+ }
319
+ i = j;
320
+ continue;
321
+ }
322
+ if (ch === '/' && source[i + 1] === '/') {
323
+ while (i < source.length && source[i] !== '\n')
324
+ i++;
325
+ continue;
326
+ }
327
+ if (ch === '/' && source[i + 1] === '*') {
328
+ i += 2;
329
+ while (i < source.length && !(source[i] === '*' && source[i + 1] === '/'))
330
+ i++;
331
+ i += 2;
332
+ continue;
333
+ }
334
+ if (ch !== '<') {
335
+ i++;
336
+ continue;
337
+ }
338
+ // A candidate `<` in expression position: find the matching `>`, tracking
339
+ // angle depth and skipping bracketed groups (a `>` inside `(…)`/`[…]`/`{…}`
340
+ // is a comparison or a nested type argument, never the terminator).
341
+ let j = i + 1;
342
+ let angle = 1;
343
+ let end = -1;
344
+ let bail = false;
345
+ while (j < source.length) {
346
+ const c = source[j];
347
+ if (c === '<') {
348
+ angle++;
349
+ j++;
350
+ continue;
351
+ }
352
+ if (c === '>') {
353
+ angle--;
354
+ j++;
355
+ if (angle === 0) {
356
+ end = j;
357
+ break;
358
+ }
359
+ continue;
360
+ }
361
+ if (c === '(' || c === '[' || c === '{') {
362
+ const close = c === '(' ? ')' : c === '[' ? ']' : '}';
363
+ let depth = 0;
364
+ while (j < source.length) {
365
+ const d = source[j];
366
+ if (d === c)
367
+ depth++;
368
+ else if (d === close) {
369
+ depth--;
370
+ if (depth === 0) {
371
+ j++;
372
+ break;
373
+ }
374
+ }
375
+ j++;
376
+ }
377
+ continue;
378
+ }
379
+ if (c === ';' || c === '\n') {
380
+ bail = true;
381
+ break;
382
+ }
383
+ j++;
384
+ }
385
+ if (bail || end < 0) {
386
+ i++;
387
+ continue;
388
+ }
389
+ // Must be an arrow: `>` then a parameter list, then an optional return
390
+ // type, then `=>`. Scanning to the `=>` is what distinguishes this from a
391
+ // JSX element that happens to be followed by a parenthesized text run.
392
+ if (!isArrowParameterList(source, end)) {
393
+ i = end;
394
+ continue;
395
+ }
396
+ for (let p = i; p < end; p++) {
397
+ if (chars[p] !== '\n')
398
+ chars[p] = ' ';
399
+ }
400
+ changed = true;
401
+ i = end;
402
+ }
403
+ return changed ? chars.join('') : source;
404
+ }
405
+ /**
406
+ * True when `source` continues from `from` with `( … )` — optionally followed
407
+ * by a `: ReturnType` — and then `=>`. Balances brackets so the arrow inside a
408
+ * default value (`(cb = () => 1) => …`) is not mistaken for the terminator.
409
+ */
410
+ function isArrowParameterList(source, from) {
411
+ let i = from;
412
+ while (i < source.length && isSpaceChar(source[i]))
413
+ i++;
414
+ if (source[i] !== '(')
415
+ return false;
416
+ let depth = 0;
417
+ while (i < source.length) {
418
+ const ch = source[i];
419
+ if (ch === '(' || ch === '[' || ch === '{') {
420
+ depth++;
421
+ i++;
422
+ continue;
423
+ }
424
+ if (ch === ')' || ch === ']' || ch === '}') {
425
+ depth--;
426
+ i++;
427
+ if (depth === 0)
428
+ break;
429
+ continue;
430
+ }
431
+ i++;
432
+ }
433
+ if (depth !== 0)
434
+ return false;
435
+ while (i < source.length && isSpaceChar(source[i]))
436
+ i++;
437
+ // Optional return type: `: T` up to the `=>` at depth zero.
438
+ if (source[i] === ':') {
439
+ i++;
440
+ let tdepth = 0;
441
+ while (i < source.length) {
442
+ const ch = source[i];
443
+ if (ch === '(' || ch === '[' || ch === '{') {
444
+ tdepth++;
445
+ i++;
446
+ continue;
447
+ }
448
+ if (ch === ')' || ch === ']' || ch === '}') {
449
+ if (tdepth === 0)
450
+ return false;
451
+ tdepth--;
452
+ i++;
453
+ continue;
454
+ }
455
+ if (tdepth === 0 && ch === '=' && source[i + 1] === '>')
456
+ return true;
457
+ // A statement boundary ends the scan ONLY at depth zero. An object
458
+ // LITERAL type is full of them and is perfectly legal inside a return
459
+ // annotation: `{ roles: R[]; changed: boolean }` has a `;` (and, when it
460
+ // wraps, a newline) inside the braces. Bailing on those is what made
461
+ // `<R extends { id: string }>(a: R[], b: R[]): { roles: R[]; changed:
462
+ // boolean } => a` the one generic-arrow shape that still failed — it needs
463
+ // a generic arrow AND a braced constraint AND a return annotation, which
464
+ // is why dropping any ONE of the three parsed cleanly.
465
+ if (tdepth === 0 && (ch === ';' || ch === '\n'))
466
+ return false;
467
+ i++;
468
+ }
469
+ return false;
470
+ }
471
+ return source[i] === '=' && source[i + 1] === '>';
472
+ }
473
+ function isSpaceChar(ch) {
474
+ return ch === ' ' || ch === '\t' || ch === '\n' || ch === '\r' || ch === '\f' || ch === '\v';
475
+ }
256
476
  export function createBaseParser() {
257
477
  return acorn.Parser.extend(tsPlugin({}), VeskParserPlugin());
258
478
  }
@@ -283,7 +503,7 @@ export function parseGeneratedJs(source) {
283
503
  }
284
504
  export function parse(source, options = {}) {
285
505
  const ParserClass = createBaseParser();
286
- const { code, annotations } = preprocessForClauses(blankComments(source));
506
+ const { code, annotations } = preprocessForClauses(blankGenericArrowTypeParams(blankComments(source)));
287
507
  // Acorn validates that every `export { X }` names a real top-level binding.
288
508
  // A `.vsk` component is a registry entry, not a binding, so acorn rejects
289
509
  // `export { MyComponent }`. Remove only those specifier lists — one whose
@@ -1 +1 @@
1
- {"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAM1D,MAAM,WAAW,WAAW;IAC1B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChC;AAED;;;;;;GAMG;AACH,4DAA4D;AAC5D,wBAAgB,eAAe,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAajD;AAED,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAqB3F;AAkDD,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAUnE;AAwED,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,SAAS,EAAE,CAKjF;AAMD,wBAAgB,cAAc,CAAC,aAAa,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CA2BzE;AA6HD,wBAAgB,cAAc,CAAC,IAAI,EAAE,SAAS,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAgBrE;AAED,MAAM,WAAW,oBAAoB;IACnC,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,SAAS,EAAE,EAAE,OAAO,GAAE,oBAAyB,GAAG,MAAM,CAoCnG;AAoBD,wBAAgB,QAAQ,CAAC,IAAI,EAAE,SAAS,EAAE,EAAE,QAAQ,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CAmGhF"}
1
+ {"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAM1D,MAAM,WAAW,WAAW;IAC1B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChC;AAED;;;;;;GAMG;AACH,4DAA4D;AAC5D,wBAAgB,eAAe,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAajD;AAED,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAqB3F;AAkDD,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAUnE;AAwED,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,SAAS,EAAE,CAKjF;AAMD,wBAAgB,cAAc,CAAC,aAAa,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CA2BzE;AA6HD,wBAAgB,cAAc,CAAC,IAAI,EAAE,SAAS,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAgBrE;AAED,MAAM,WAAW,oBAAoB;IACnC,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,SAAS,EAAE,EAAE,OAAO,GAAE,oBAAyB,GAAG,MAAM,CAoCnG;AAoBD,wBAAgB,QAAQ,CAAC,IAAI,EAAE,SAAS,EAAE,EAAE,QAAQ,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CAkHhF"}
package/dist/router.js CHANGED
@@ -520,6 +520,21 @@ export function matchUrl(tree, pathname) {
520
520
  pushWithStandalone(node);
521
521
  return true;
522
522
  }
523
+ // A group can also BE the page at this position: `app/(public)/page.vsk`
524
+ // serves `/`. The recursion above only ever considers the group's
525
+ // CHILDREN, and at `/` none of them match (they all carry a path
526
+ // segment), so the group was skipped entirely and the match fell
527
+ // through to the page-less root node — which produced a 404 for the
528
+ // zero-segment path while every nested route (`/about`, `/login`)
529
+ // matched fine.
530
+ //
531
+ // A group is transparent for PREFIX matching, and it has to be
532
+ // transparent here too: a group with no page at this position is not a
533
+ // match, a group WITH one is.
534
+ if (partIndex >= parts.length && node.page && node.fullPath === '/' + parts.join('/')) {
535
+ pushWithStandalone(node);
536
+ return true;
537
+ }
523
538
  continue;
524
539
  }
525
540
  if (node.fullPath === '/') {
@@ -1 +1 @@
1
- {"version":3,"file":"server-jsgen.d.ts","sourceRoot":"","sources":["../src/server-jsgen.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAOzE,OAAO,EAAkG,KAAK,WAAW,EAAE,MAAM,mCAAmC,CAAC;AA4DrK,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,IAAI,EAAE,OAAO,GAAE,OAAe,EAAE,OAAO,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,GAAG,MAAM,CA4EjJ;AAyZD,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,WAAW,EAAE,aAAa,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,MAAM,CAwD1F;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;CAClB;AAuFD;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,iBAAiB,EAAE,CAkCzE;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,cAAc,EAAE,OAAO,GAAG,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,CAYhG"}
1
+ {"version":3,"file":"server-jsgen.d.ts","sourceRoot":"","sources":["../src/server-jsgen.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAOzE,OAAO,EAAkG,KAAK,WAAW,EAAE,MAAM,mCAAmC,CAAC;AA6DrK,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,IAAI,EAAE,OAAO,GAAE,OAAe,EAAE,OAAO,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,GAAG,MAAM,CA4EjJ;AAobD,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,WAAW,EAAE,aAAa,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,MAAM,CAwD1F;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;CAClB;AAuFD;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,iBAAiB,EAAE,CAkCzE;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,cAAc,EAAE,OAAO,GAAG,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,CAYhG"}
@@ -1,7 +1,7 @@
1
1
  import { Expression, StaticNode, TextNode, DynamicBinding, OpaqueDynamicRegion, MapRegion, WhileLoop, SwitchBlock, TryCatch, ForLoop, TrackDecl, RuntimeStatement, ComponentRef, ComponentCall, ServerBlock, ClientBlock, HeadBlock, SlotNode, PropSlot, PropSlotRender, } from '@vesk/compiler/src/ir';
2
2
  import { isStaticIR, collectTrackedNames, transformTracked, transformTrackedInit, semicolonizeStatement } from '@vesk/compiler/src/client-codegen';
3
3
  import { unwrapTrackCall, stripTrackGeneric, hasTopLevelComma, skipWhitespace, findBalancedEnd, startsWithIdentifier, callsIdentifier } from '@vesk/compiler/src/scan';
4
- import { escapeHtml, indent, exprJS, extractTopLevelNames, extractRuntimeNames, buildParamInit, __vskHydrate, __vskMarkerless, __vskImportedNames, setVskImportedNames, setVskForceClaim, takeVskForceClaim, nextVskId, } from '@vesk/compiler/src/server-utils';
4
+ import { escapeHtml, indent, exprJS, extractTopLevelNames, extractRuntimeNames, buildParamInit, VOID_ELEMENTS, __vskHydrate, __vskMarkerless, __vskImportedNames, setVskImportedNames, setVskForceClaim, takeVskForceClaim, nextVskId, } from '@vesk/compiler/src/server-utils';
5
5
  import { localValueImportNames } from '@vesk/compiler/src/module-imports';
6
6
  import { lowerJsxInExpression } from '@vesk/compiler/src/server-jsx-lowering';
7
7
  import { print } from 'esrap';
@@ -52,7 +52,7 @@ function componentMarker(compName) {
52
52
  export function irNodeToJS(node, importedNames, isAsync = false, tracked) {
53
53
  importedNames = importedNames || __vskImportedNames;
54
54
  if (node instanceof StaticNode)
55
- return staticNodeToJS(node, isAsync, tracked);
55
+ return staticNodeToJS(node, isAsync, tracked, __inForeignContent);
56
56
  if (node instanceof TextNode) {
57
57
  if (!node.value)
58
58
  return '';
@@ -165,7 +165,16 @@ function exprJSX(node, tracked) {
165
165
  }
166
166
  return exprJS(transformTracked({ ...node, ast: lowered }, tracked || new Map()));
167
167
  }
168
- function staticNodeToJS(node, isAsync = false, tracked) {
168
+ /**
169
+ * True while emitting inside `<svg>`/`<math>`, where self-closing syntax is
170
+ * part of the content model rather than ignored. Module-level because the
171
+ * emitter already recurses through `irNodeToJS`, and threading a context
172
+ * parameter through every call site would touch a dozen emitters that have no
173
+ * interest in it.
174
+ */
175
+ let __inForeignContent = false;
176
+ const FOREIGN_ROOTS = new Set(['svg', 'math']);
177
+ function staticNodeToJS(node, isAsync = false, tracked, inForeign = false) {
169
178
  const lines = [];
170
179
  const dynAttrTargets = new Set();
171
180
  for (const child of node.children) {
@@ -199,18 +208,31 @@ function staticNodeToJS(node, isAsync = false, tracked) {
199
208
  }
200
209
  }
201
210
  if (node.selfClosing) {
202
- let tag = openTag + ' />';
211
+ const voidOrForeign = VOID_ELEMENTS.has(node.tag) || inForeign;
212
+ // A self-closing JSX element is NOT a self-closing HTML element. The HTML
213
+ // parser ignores the trailing slash on anything that is not a void element,
214
+ // so `<div class="dot" />` opens a `<div>` and every following sibling
215
+ // becomes its child — the served document's structure silently diverges
216
+ // from the client's, which builds a real element with `createElement`.
217
+ // Void elements keep `/>`, and so does anything inside `<svg>`/`<math>`,
218
+ // where self-closing syntax IS part of the content model.
219
+ const tail = voidOrForeign ? ' />' : `></${node.tag}>`;
203
220
  if (hasDynamicAttrs) {
204
- let expr = JSON.stringify(tag);
221
+ // Dynamic attributes must land INSIDE the open tag. They used to be
222
+ // appended after it — `<img /> src="..."` — which made the parser drop
223
+ // them, so `<div style={{ backgroundColor: accent }} />` served with no
224
+ // `style` at all and the colour silently vanished.
225
+ let expr = JSON.stringify(openTag);
205
226
  for (const child of node.children) {
206
227
  if (child instanceof DynamicBinding && child.kind === 'attribute' && child.target !== 'ref' && !isEvent(child.target)) {
207
228
  expr += ` + __attr(${JSON.stringify(child.target)}, ${exprJSX(child.expression, tracked)})`;
208
229
  }
209
230
  }
231
+ expr += ` + ${JSON.stringify(tail)}`;
210
232
  lines.push(`__out.push(${expr});`);
211
233
  }
212
234
  else {
213
- lines.push(`__out.push(${JSON.stringify(tag)});`);
235
+ lines.push(`__out.push(${JSON.stringify(openTag + tail)});`);
214
236
  }
215
237
  return lines.join('\n');
216
238
  }
@@ -228,11 +250,15 @@ function staticNodeToJS(node, isAsync = false, tracked) {
228
250
  else {
229
251
  lines.push(`__out.push(${JSON.stringify(openTag + '>')});`);
230
252
  }
253
+ const prevForeign = __inForeignContent;
254
+ if (FOREIGN_ROOTS.has(node.tag))
255
+ __inForeignContent = true;
231
256
  for (const child of childNodes) {
232
257
  const code = irNodeToJS(child, null, isAsync, tracked);
233
258
  if (code)
234
259
  lines.push(code);
235
260
  }
261
+ __inForeignContent = prevForeign;
236
262
  lines.push(`__out.push(${JSON.stringify('</' + node.tag + '>')});`);
237
263
  return lines.join('\n');
238
264
  }
@@ -1,4 +1,5 @@
1
1
  import type { IRNode } from '@vesk/compiler/src/ir';
2
+ export declare const VOID_ELEMENTS: Set<string>;
2
3
  export declare let __vskHydrate: boolean;
3
4
  export declare let __vskMarkerless: boolean;
4
5
  export declare let __vskId: number;
@@ -1 +1 @@
1
- {"version":3,"file":"server-utils.d.ts","sourceRoot":"","sources":["../src/server-utils.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"server-utils.d.ts","sourceRoot":"","sources":["../src/server-utils.ts"],"names":[],"mappings":"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"}
@@ -4,7 +4,7 @@ import { parse } from '@vesk/compiler/src/parser';
4
4
  import { generateIR } from '@vesk/compiler/src/ir-generator';
5
5
  import { htmlTagName, htmlTagEnd } from '@vesk/compiler/src/scan';
6
6
  import { importModuleTarget, extractImportNames, stripTrackDeclMarkers } from '@vesk/compiler/src/tokens';
7
- const VOID_ELEMENTS = new Set([
7
+ export const VOID_ELEMENTS = new Set([
8
8
  'area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input', 'link', 'meta', 'param', 'source', 'track', 'wbr',
9
9
  ]);
10
10
  const RAW_TEXT_ELEMENTS = new Set(['style', 'script', 'title']);
@@ -1 +1 @@
1
- {"version":3,"file":"strip-ts.d.ts","sourceRoot":"","sources":["../src/strip-ts.ts"],"names":[],"mappings":"AAwBA,oFAAoF;AACpF,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,GAAG,GAAG,OAAO,CAOzD;AAUD,2DAA2D;AAC3D,wBAAgB,WAAW,CAAC,GAAG,EAAE,GAAG,GAAG,OAAO,CAgB7C;AAYD,sFAAsF;AACtF,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,GAAG,GAAG,OAAO,CAUtD;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,GAAG,GAAG,GAAG,CAmF1C;AAWD;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAiBnD"}
1
+ {"version":3,"file":"strip-ts.d.ts","sourceRoot":"","sources":["../src/strip-ts.ts"],"names":[],"mappings":"AAwBA,oFAAoF;AACpF,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,GAAG,GAAG,OAAO,CAOzD;AAUD,2DAA2D;AAC3D,wBAAgB,WAAW,CAAC,GAAG,EAAE,GAAG,GAAG,OAAO,CAgB7C;AAYD,sFAAsF;AACtF,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,GAAG,GAAG,OAAO,CAUtD;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,GAAG,GAAG,GAAG,CAmF1C;AAkDD;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAiBnD"}