@vesk/adapter 0.2.22 → 0.2.24
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-bundle.d.ts.map +1 -1
- package/dist/client-bundle.js +123 -37
- package/dist/dev-server.d.ts.map +1 -1
- package/dist/dev-server.js +64 -6
- package/dist/hmr.d.ts.map +1 -1
- package/dist/hmr.js +64 -12
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +12 -5
- package/dist/load-config.d.ts +3 -0
- package/dist/load-config.d.ts.map +1 -0
- package/dist/load-config.js +85 -0
- package/dist/prod-server.d.ts.map +1 -1
- package/dist/prod-server.js +5 -18
- package/dist/runtime-bundle.js +2 -2
- package/dist/ssr-function.d.ts.map +1 -1
- package/dist/ssr-function.js +91 -85
- package/dist/types.d.ts +1 -1
- package/dist/types.d.ts.map +1 -1
- package/package.json +4 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client-bundle.d.ts","sourceRoot":"","sources":["../src/client-bundle.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,SAAS,EAAE,mBAAmB,EAAE,kBAAkB,
|
|
1
|
+
{"version":3,"file":"client-bundle.d.ts","sourceRoot":"","sources":["../src/client-bundle.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,SAAS,EAAE,mBAAmB,EAAE,kBAAkB,EAAmF,MAAM,yBAAyB,CAAC;AAoCnL;;;;;;;;;;;;;GAaG;AACH,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CA8BhE;AAoWD;;;;;;;;;;;;GAYG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAkBxD;AAmCD,wBAAsB,oBAAoB,CACxC,SAAS,EAAE,SAAS,EAAE,EACtB,MAAM,EAAE,MAAM,EACd,YAAY,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EAClC,OAAO,CAAC,EAAE,mBAAmB,GAC5B,OAAO,CAAC,kBAAkB,CAAC,CA4Z7B;AAMD,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CA+B3D;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAUlE;AAYD;;;;;;;;GAQG;AACH,wBAAsB,sBAAsB,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAuCrG"}
|
package/dist/client-bundle.js
CHANGED
|
@@ -197,14 +197,15 @@ function demoteExports(code) {
|
|
|
197
197
|
code = code.slice(0, e.start) + e.text + code.slice(e.end);
|
|
198
198
|
return code;
|
|
199
199
|
}
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
200
|
+
/**
|
|
201
|
+
* Parse-free stand-in for the per-chunk `import` scan: a chunk carries live
|
|
202
|
+
* `import` statements iff its deduped head rendered non-empty, or its import
|
|
203
|
+
* merge aborted (in which case some file bodies retain their raw imports for
|
|
204
|
+
* esbuild to bundle). Equivalent to parsing the assembled chunk code, without
|
|
205
|
+
* the ~50-100KB acorn parse per chunk on every dev rebuild.
|
|
206
|
+
*/
|
|
207
|
+
function chunkHasImports(headLen, mergeAborted) {
|
|
208
|
+
return headLen > 0 || mergeAborted;
|
|
208
209
|
}
|
|
209
210
|
/**
|
|
210
211
|
* Rewrites a compiled file's source specifier so esbuild can resolve it from
|
|
@@ -228,8 +229,8 @@ function resolveImportSource(src, filePath) {
|
|
|
228
229
|
* each file's component AND hydrator both keep their imports verbatim. So the
|
|
229
230
|
* same named binding frequently appears multiple times in one chunk — once per
|
|
230
231
|
* (file, comp|hyd) pair, plus once per extra file. acorn's `parse()` rejects
|
|
231
|
-
* that with `Identifier has already been declared`, so `
|
|
232
|
-
* to silently
|
|
232
|
+
* that with `Identifier has already been declared`, so a naive `import` scan
|
|
233
|
+
* used to silently pass and esbuild — which rejects the same duplicates —
|
|
233
234
|
* never ran; the chunk shipped with raw `import` statements inside its
|
|
234
235
|
* classic-script IIFE and hydration died with `SyntaxError: Cannot use import
|
|
235
236
|
* statement outside a module`.
|
|
@@ -251,7 +252,7 @@ class ChunkImports {
|
|
|
251
252
|
return code;
|
|
252
253
|
}
|
|
253
254
|
/** Folds one file's imports into the merged set and returns the code with its imports stripped. */
|
|
254
|
-
add(code, filePath) {
|
|
255
|
+
add(code, filePath, specSink) {
|
|
255
256
|
if (!code || this.aborted)
|
|
256
257
|
return code;
|
|
257
258
|
let ast;
|
|
@@ -273,34 +274,28 @@ class ChunkImports {
|
|
|
273
274
|
if (typeof src !== 'string')
|
|
274
275
|
continue;
|
|
275
276
|
const resolved = resolveImportSource(src, filePath);
|
|
276
|
-
let group = this.bySource.get(resolved);
|
|
277
|
-
if (!group) {
|
|
278
|
-
group = { named: new Map() };
|
|
279
|
-
this.bySource.set(resolved, group);
|
|
280
|
-
}
|
|
281
277
|
for (const spec of node.specifiers ?? []) {
|
|
282
278
|
const s = spec;
|
|
283
279
|
const local = s.local?.name;
|
|
284
280
|
if (typeof local !== 'string')
|
|
285
281
|
return this.fail(`nameless specifier from '${resolved}' in ${filePath}`, code);
|
|
286
282
|
if (s.type === 'ImportDefaultSpecifier') {
|
|
287
|
-
if (
|
|
288
|
-
return
|
|
289
|
-
|
|
283
|
+
if (!this.foldSpec(resolved, 'default', local, undefined, filePath, code))
|
|
284
|
+
return code;
|
|
285
|
+
specSink?.push({ source: resolved, kind: 'default', local });
|
|
290
286
|
}
|
|
291
287
|
else if (s.type === 'ImportNamespaceSpecifier') {
|
|
292
|
-
if (
|
|
293
|
-
return
|
|
294
|
-
|
|
288
|
+
if (!this.foldSpec(resolved, 'namespace', local, undefined, filePath, code))
|
|
289
|
+
return code;
|
|
290
|
+
specSink?.push({ source: resolved, kind: 'namespace', local });
|
|
295
291
|
}
|
|
296
292
|
else if (s.type === 'ImportSpecifier') {
|
|
297
293
|
const imported = s.imported?.name;
|
|
298
294
|
if (typeof imported !== 'string')
|
|
299
295
|
return this.fail(`nameless named-import from '${resolved}' in ${filePath}`, code);
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
group.named.set(imported, { kind: 'named', local, imported });
|
|
296
|
+
if (!this.foldSpec(resolved, 'named', local, imported, filePath, code))
|
|
297
|
+
return code;
|
|
298
|
+
specSink?.push({ source: resolved, kind: 'named', local, imported });
|
|
304
299
|
}
|
|
305
300
|
}
|
|
306
301
|
let cut = node.end;
|
|
@@ -312,6 +307,45 @@ class ChunkImports {
|
|
|
312
307
|
return code;
|
|
313
308
|
return removeRanges(code, ranges);
|
|
314
309
|
}
|
|
310
|
+
/**
|
|
311
|
+
* Shared single-spec fold used by both the fresh compile path and the
|
|
312
|
+
* parse-free warm replay. Returns false (and aborts the merge) on a
|
|
313
|
+
* conflicting binding — same shape as the pre-refactor inline logic.
|
|
314
|
+
*/
|
|
315
|
+
foldSpec(source, kind, local, imported, filePath, code) {
|
|
316
|
+
let group = this.bySource.get(source);
|
|
317
|
+
if (!group) {
|
|
318
|
+
group = { named: new Map() };
|
|
319
|
+
this.bySource.set(source, group);
|
|
320
|
+
}
|
|
321
|
+
if (kind === 'default') {
|
|
322
|
+
if (group.default && group.default.local !== local) {
|
|
323
|
+
this.fail(`conflicting default imports from '${source}' in ${filePath}`, code);
|
|
324
|
+
return false;
|
|
325
|
+
}
|
|
326
|
+
group.default = { kind: 'default', local };
|
|
327
|
+
}
|
|
328
|
+
else if (kind === 'namespace') {
|
|
329
|
+
if (group.namespace && group.namespace.local !== local) {
|
|
330
|
+
this.fail(`conflicting namespace imports from '${source}' in ${filePath}`, code);
|
|
331
|
+
return false;
|
|
332
|
+
}
|
|
333
|
+
group.namespace = { kind: 'namespace', local };
|
|
334
|
+
}
|
|
335
|
+
else {
|
|
336
|
+
if (typeof imported !== 'string') {
|
|
337
|
+
this.fail(`nameless named-import from '${source}' in ${filePath}`, code);
|
|
338
|
+
return false;
|
|
339
|
+
}
|
|
340
|
+
const existing = group.named.get(imported);
|
|
341
|
+
if (existing && existing.local !== local) {
|
|
342
|
+
this.fail(`'${imported}' from '${source}' bound to both '${existing.local}' and '${local}' in ${filePath}`, code);
|
|
343
|
+
return false;
|
|
344
|
+
}
|
|
345
|
+
group.named.set(imported, { kind: 'named', local, imported });
|
|
346
|
+
}
|
|
347
|
+
return true;
|
|
348
|
+
}
|
|
315
349
|
/** True when every file parsed and merged cleanly (no conflict, no parse abort). */
|
|
316
350
|
get ok() {
|
|
317
351
|
return !this.aborted;
|
|
@@ -352,6 +386,16 @@ function removeRanges(code, ranges) {
|
|
|
352
386
|
}
|
|
353
387
|
return out.trim();
|
|
354
388
|
}
|
|
389
|
+
/**
|
|
390
|
+
* Historical cache replay: re-parse a cached entry's import-carrying codes
|
|
391
|
+
* and re-fold them into the chunk accumulator. Used only on rare fold aborts
|
|
392
|
+
* and old-style cache entries — the parse-free fast path is the norm.
|
|
393
|
+
*/
|
|
394
|
+
function fallbackReplay(cached, filePath, imports) {
|
|
395
|
+
const comp = cached.compCode ? imports.add(cached.compCode, filePath).replace(/^\n+/, '').replace(/\n+$/, '') : '';
|
|
396
|
+
const hyd = cached.hydCode ? imports.add(cached.hydCode, filePath).replace(/__components/g, '__hydrators').replace(/^\n+/, '').replace(/\n+$/, '') : '';
|
|
397
|
+
return [comp, hyd].filter(Boolean).join('\n');
|
|
398
|
+
}
|
|
355
399
|
/**
|
|
356
400
|
* Scopes one file's contribution to the shared chunk: module-level
|
|
357
401
|
* import/export statements pass through untouched, all other top-level
|
|
@@ -454,7 +498,7 @@ function removeCompiledNodes(code, isTarget) {
|
|
|
454
498
|
}
|
|
455
499
|
export async function generateClientBundle(routeTree, appDir, componentMap, options) {
|
|
456
500
|
const runtimeDir = findRuntimeSrc(appDir);
|
|
457
|
-
|
|
501
|
+
let seen = new Set();
|
|
458
502
|
const chunks = [];
|
|
459
503
|
const runtimeImportNames = new Set();
|
|
460
504
|
const cache = options?.cache;
|
|
@@ -540,9 +584,33 @@ export async function generateClientBundle(routeTree, appDir, componentMap, opti
|
|
|
540
584
|
// file carry the same import twice (joint parse would abort the merge).
|
|
541
585
|
// Mirror the fresh path exactly: strip, rename the hydrator registry,
|
|
542
586
|
// trim — otherwise warm output drifts from cold output.
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
587
|
+
let cachedFileCode = '';
|
|
588
|
+
if (cached.compBody !== undefined) {
|
|
589
|
+
// Parse-free warm replay: the body/scoped strings and the folded
|
|
590
|
+
// import specifiers were computed once at fresh-compile time, so this
|
|
591
|
+
// hit costs zero parses (the hot path paid ~5 acorn parses per cached
|
|
592
|
+
// file per chunk before — ~4k parses per edit on the test app).
|
|
593
|
+
let aborted = false;
|
|
594
|
+
for (const s of cached.importSpecs ?? []) {
|
|
595
|
+
if (!imports.foldSpec(s.source, s.kind, s.local, s.imported, filePath, cached.compCode)) {
|
|
596
|
+
aborted = true;
|
|
597
|
+
break;
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
if (aborted) {
|
|
601
|
+
// Rare fold conflict — fall back to the historical parse path so
|
|
602
|
+
// the merge-abort semantics (and `ok` reporting) stay identical.
|
|
603
|
+
cachedFileCode = fallbackReplay(cached, filePath, imports);
|
|
604
|
+
}
|
|
605
|
+
else if (cached.scoped) {
|
|
606
|
+
output.push(cached.scoped);
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
else {
|
|
610
|
+
// Old-style entry (e.g. populated before the parse-free fields were
|
|
611
|
+
// introduced): historical replay.
|
|
612
|
+
cachedFileCode = fallbackReplay(cached, filePath, imports);
|
|
613
|
+
}
|
|
546
614
|
if (cachedFileCode.trim())
|
|
547
615
|
output.push(scopeFileContribution(cachedFileCode));
|
|
548
616
|
for (const n of cached.runtimeNames)
|
|
@@ -566,10 +634,14 @@ export async function generateClientBundle(routeTree, appDir, componentMap, opti
|
|
|
566
634
|
const { comp: rawComp, hyd: rawHyd, name: actualName } = compileClientBoth(src, null, filePath);
|
|
567
635
|
// Cache keeps the import-carrying codes so a warm build can re-fold them
|
|
568
636
|
// into its own fresh accumulator; the emitted codes are import-stripped.
|
|
637
|
+
// The bodies/specs/scoped artifacts are cached too so warm replay never
|
|
638
|
+
// re-parses (see the `compBody !== undefined` fast path above).
|
|
569
639
|
const compWithImports = rawComp ? stripExports(stripVskImports(stripRuntimeImport(rawComp))) : '';
|
|
570
640
|
const hydWithImports = rawHyd ? stripExports(stripVskImports(stripRuntimeImport(rawHyd))) : '';
|
|
571
|
-
const
|
|
572
|
-
const
|
|
641
|
+
const compSpecs = [];
|
|
642
|
+
const hydSpecs = [];
|
|
643
|
+
const compCode = compWithImports ? imports.add(compWithImports, filePath, compSpecs).replace(/^\n+/, '').replace(/\n+$/, '') : '';
|
|
644
|
+
const hydCode = hydWithImports ? imports.add(hydWithImports, filePath, hydSpecs).replace(/__components/g, '__hydrators').replace(/^\n+/, '').replace(/\n+$/, '') : '';
|
|
573
645
|
if (rawComp)
|
|
574
646
|
collectRuntimeImports(rawComp);
|
|
575
647
|
if (rawHyd)
|
|
@@ -585,8 +657,9 @@ export async function generateClientBundle(routeTree, appDir, componentMap, opti
|
|
|
585
657
|
// Comp and hyd contributions of one file share its top-level bindings,
|
|
586
658
|
// so they are scoped together in a single block (see replay path above).
|
|
587
659
|
const fileCode = [compCode, hydCode].filter(Boolean).join('\n');
|
|
588
|
-
|
|
589
|
-
|
|
660
|
+
const scopedContribution = fileCode.trim() ? scopeFileContribution(fileCode) : '';
|
|
661
|
+
if (scopedContribution)
|
|
662
|
+
output.push(scopedContribution);
|
|
590
663
|
if (actualName && resolvedName !== null && actualName !== resolvedName) {
|
|
591
664
|
output.push(`Object.defineProperty(__components, ${JSON.stringify(resolvedName)}, { get: () => __components[${JSON.stringify(actualName)}], configurable: true });`);
|
|
592
665
|
output.push(`Object.defineProperty(__hydrators, ${JSON.stringify(resolvedName)}, { get: () => __hydrators[${JSON.stringify(actualName)}], configurable: true });`);
|
|
@@ -601,6 +674,10 @@ export async function generateClientBundle(routeTree, appDir, componentMap, opti
|
|
|
601
674
|
actualName,
|
|
602
675
|
runtimeNames: [...runtimeImportNames].filter((n) => !namesBefore.has(n)),
|
|
603
676
|
imports: importedPaths,
|
|
677
|
+
compBody: compCode,
|
|
678
|
+
hydBody: hydCode,
|
|
679
|
+
scoped: scopedContribution,
|
|
680
|
+
importSpecs: [...compSpecs, ...hydSpecs],
|
|
604
681
|
});
|
|
605
682
|
}
|
|
606
683
|
}
|
|
@@ -630,6 +707,14 @@ export async function generateClientBundle(routeTree, appDir, componentMap, opti
|
|
|
630
707
|
const chunkEntries = [];
|
|
631
708
|
function walkSplit(nodes, _chain) {
|
|
632
709
|
for (const node of nodes) {
|
|
710
|
+
// Each chunk must be self-contained: reset the compile dedupe so a
|
|
711
|
+
// shared .vsk component (e.g. a site-wide Footer imported by the root
|
|
712
|
+
// layout) is emitted into every chunk that references it. With a
|
|
713
|
+
// single global `seen`, the first chunk to import a component owns it
|
|
714
|
+
// and later chunks reference `__components["X"]` without registering
|
|
715
|
+
// it — which breaks standalone layouts, whose match chain drops the
|
|
716
|
+
// index chunk at runtime.
|
|
717
|
+
seen = new Set();
|
|
633
718
|
const chunkCode = [];
|
|
634
719
|
const chunkImports = new ChunkImports();
|
|
635
720
|
const pagePath = resolve(appDir, node.sourceDir, 'page.vsk');
|
|
@@ -670,7 +755,7 @@ export async function generateClientBundle(routeTree, appDir, componentMap, opti
|
|
|
670
755
|
console.error('[vesk] chunk import merge aborted for', chunkName + ':', chunkImports.reason);
|
|
671
756
|
const head = chunkImports.render();
|
|
672
757
|
const code = (head ? head + '\n\n' : '') + chunkCode.join('\n\n');
|
|
673
|
-
chunkEntries.push({ name: chunkName, code, node });
|
|
758
|
+
chunkEntries.push({ name: chunkName, code, node, imports: chunkHasImports(head.length, !chunkImports.ok) });
|
|
674
759
|
}
|
|
675
760
|
walkSplit(node.children || [], [..._chain, node]);
|
|
676
761
|
}
|
|
@@ -679,6 +764,7 @@ export async function generateClientBundle(routeTree, appDir, componentMap, opti
|
|
|
679
764
|
const sharedCode = [];
|
|
680
765
|
const sharedImports = new ChunkImports();
|
|
681
766
|
const compMap = componentMap || new Map();
|
|
767
|
+
seen = new Set();
|
|
682
768
|
for (const [compName, compPath] of compMap) {
|
|
683
769
|
compileFile(compPath, compName, sharedCode, sharedImports);
|
|
684
770
|
}
|
|
@@ -687,14 +773,14 @@ export async function generateClientBundle(routeTree, appDir, componentMap, opti
|
|
|
687
773
|
console.error('[vesk] chunk import merge aborted for shared.js:', sharedImports.reason);
|
|
688
774
|
const head = sharedImports.render();
|
|
689
775
|
const code = (head ? head + '\n\n' : '') + sharedCode.join('\n\n');
|
|
690
|
-
chunkEntries.push({ name: 'shared.js', code, node: null });
|
|
776
|
+
chunkEntries.push({ name: 'shared.js', code, node: null, imports: chunkHasImports(head.length, !sharedImports.ok) });
|
|
691
777
|
}
|
|
692
778
|
const chunkIIFE = (body) => `(()=>{\nconst __components = globalThis.__components || (globalThis.__components = {});\nconst __hydrators = globalThis.__hydrators || (globalThis.__hydrators = {});\n${body}\n})();\n`;
|
|
693
779
|
for (const entry of chunkEntries) {
|
|
694
780
|
if (!entry.code.trim())
|
|
695
781
|
continue;
|
|
696
782
|
let finalCode;
|
|
697
|
-
if (
|
|
783
|
+
if (entry.imports) {
|
|
698
784
|
// Bundle the chunk through esbuild so every remaining import (npm
|
|
699
785
|
// packages like lucide-vesk and rewritten relative `.ts` value
|
|
700
786
|
// modules) is inlined into the IIFE — a classic script cannot carry
|
package/dist/dev-server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dev-server.d.ts","sourceRoot":"","sources":["../src/dev-server.ts"],"names":[],"mappings":"AAEA,OAAO,EAAgB,KAAK,MAAM,EAA6C,MAAM,WAAW,CAAC;AAOjG,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,OAAO,CAAC;AAI7C,OAAO,KAAK,EAAa,gBAAgB,EAAwB,MAAM,yBAAyB,CAAC;AAgBjG;;;;;GAKG;AACH,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,IAAI,GAAG,WAAW,GAAG,OAAO,GAAG,MAAM,CAAC;IAC9C,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,KAAK,EAAE,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IACxD,QAAQ,EAAE,OAAO,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB;+EAC2E;IAC3E,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED,mEAAmE;AACnE,wBAAgB,kBAAkB,IAAI,WAAW,CAEhD;AAuCD,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,KAAK,GAAG;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,CAIzE;AAkBD,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,mHAAmH;IACnH,QAAQ,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC;IAC7B;;8BAE0B;IAC1B,MAAM,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,UAAU,GAAG,YAAY,GAAG,SAAS,GAAG,WAAW,GAAG,QAAQ,CAAC;IACrE,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,wBAAwB;IACvC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,WAAW,CAAC,EAAE,MAAM,WAAW,CAAC;IAChC,8EAA8E;IAC9E,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,uBAAuB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3E;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,wBAAwB,GAAG;IACvE,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAC;CAChH,CAUA;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,CAa3C;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAIrD;AA8CD,wBAAsB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"dev-server.d.ts","sourceRoot":"","sources":["../src/dev-server.ts"],"names":[],"mappings":"AAEA,OAAO,EAAgB,KAAK,MAAM,EAA6C,MAAM,WAAW,CAAC;AAOjG,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,OAAO,CAAC;AAI7C,OAAO,KAAK,EAAa,gBAAgB,EAAwB,MAAM,yBAAyB,CAAC;AAgBjG;;;;;GAKG;AACH,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,IAAI,GAAG,WAAW,GAAG,OAAO,GAAG,MAAM,CAAC;IAC9C,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,KAAK,EAAE,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IACxD,QAAQ,EAAE,OAAO,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB;+EAC2E;IAC3E,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED,mEAAmE;AACnE,wBAAgB,kBAAkB,IAAI,WAAW,CAEhD;AAuCD,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,KAAK,GAAG;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,CAIzE;AAkBD,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,mHAAmH;IACnH,QAAQ,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC;IAC7B;;8BAE0B;IAC1B,MAAM,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,UAAU,GAAG,YAAY,GAAG,SAAS,GAAG,WAAW,GAAG,QAAQ,CAAC;IACrE,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,wBAAwB;IACvC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,WAAW,CAAC,EAAE,MAAM,WAAW,CAAC;IAChC,8EAA8E;IAC9E,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,uBAAuB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3E;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,wBAAwB,GAAG;IACvE,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAC;CAChH,CAUA;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,CAa3C;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAIrD;AA8CD,wBAAsB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAwnBvG"}
|
package/dist/dev-server.js
CHANGED
|
@@ -3,12 +3,12 @@ import { resolve, extname, dirname } from 'node:path';
|
|
|
3
3
|
import { createServer } from 'node:http';
|
|
4
4
|
import { fileURLToPath } from 'node:url';
|
|
5
5
|
import { stripCodeTypes } from '@vesk/compiler/src/strip-ts';
|
|
6
|
-
import { DEFAULT_MAX_BODY_BYTES } from '@vesk/compiler/src/server-codegen';
|
|
6
|
+
import { DEFAULT_MAX_BODY_BYTES, safeJsonForScript } from '@vesk/compiler/src/server-codegen';
|
|
7
7
|
import { build } from '@vesk/adapter/src/index';
|
|
8
|
-
import { createHmrServer } from './hmr';
|
|
8
|
+
import { buildErrorPayload, createHmrServer } from './hmr';
|
|
9
9
|
import * as hmrApi from './hmr';
|
|
10
10
|
import { createDevApiRouter } from './dev-api';
|
|
11
|
-
import {
|
|
11
|
+
import { buildTreeShakenRuntime, runtimeExportNames } from '@vesk/adapter/src/client-bundle';
|
|
12
12
|
import { resolveWithin, installMdReadHook } from '@vesk/adapter/src/paths';
|
|
13
13
|
import { getPluginRecords } from './plugins';
|
|
14
14
|
// @vesk/agentic — optional AI plugin; gated by active state if installed
|
|
@@ -358,6 +358,7 @@ export async function startDevServer(appDir, options) {
|
|
|
358
358
|
let ssrVersion = Date.now();
|
|
359
359
|
let routeTree = [];
|
|
360
360
|
let runtimeBundle = '';
|
|
361
|
+
let pendingInitialError = null;
|
|
361
362
|
let eventsMod = null;
|
|
362
363
|
async function reloadEventsMod() {
|
|
363
364
|
const eventsPath = resolve(devDir, 'server', 'events.js');
|
|
@@ -375,7 +376,7 @@ export async function startDevServer(appDir, options) {
|
|
|
375
376
|
async function doBuild() {
|
|
376
377
|
const start = Date.now();
|
|
377
378
|
try {
|
|
378
|
-
const result = await build(appDir, { outDir: devDir, publicDir, hmr: true });
|
|
379
|
+
const result = await build(appDir, { outDir: devDir, publicDir, hmr: true, plugins: options?.plugins });
|
|
379
380
|
const configPath = resolve(devDir, 'config.json');
|
|
380
381
|
if (existsSync(configPath)) {
|
|
381
382
|
config = JSON.parse(readFileSync(configPath, 'utf-8'));
|
|
@@ -384,17 +385,39 @@ export async function startDevServer(appDir, options) {
|
|
|
384
385
|
routeTree = result.routeTree;
|
|
385
386
|
const monorepoRoot = resolve(__dirname, '..', '..', '..');
|
|
386
387
|
const runtimeDir = resolve(monorepoRoot, 'packages', 'runtime', 'dist');
|
|
387
|
-
|
|
388
|
+
// The full runtime surface for /_vesk/runtime.js. The legacy concat
|
|
389
|
+
// (buildRuntimeCode) collides on module-scope names shared by separate
|
|
390
|
+
// runtime modules (e.g. hydrateInitial in hydrate.ts and router.ts) and
|
|
391
|
+
// is a SyntaxError as a module — every import() of it fails. The
|
|
392
|
+
// tree-shaken full set is one closed IIFE + explicit re-exports, so all
|
|
393
|
+
// runtime names resolve. Matches prod, which serves client.js there.
|
|
394
|
+
runtimeBundle = await buildTreeShakenRuntime(runtimeDir, [...runtimeExportNames(runtimeDir)]);
|
|
388
395
|
await reloadEventsMod();
|
|
389
396
|
lastBuild = Date.now();
|
|
397
|
+
// successful build clears any pending error
|
|
398
|
+
pendingInitialError = null;
|
|
390
399
|
console.error(`vesk dev: rebuilt in ${Date.now() - start}ms`);
|
|
391
400
|
}
|
|
392
401
|
catch (e) {
|
|
393
402
|
const message = e instanceof Error ? e.message : String(e);
|
|
394
403
|
console.error(`vesk dev: build error: ${message}`);
|
|
404
|
+
// surface the error to the HMR overlay + devtool Errors panel
|
|
405
|
+
try {
|
|
406
|
+
const filename = e?.filename
|
|
407
|
+
|| e?.file
|
|
408
|
+
|| 'app';
|
|
409
|
+
const payload = buildErrorPayload(e, String(filename), { appDir });
|
|
410
|
+
pendingInitialError = payload;
|
|
411
|
+
if (hmrSession) {
|
|
412
|
+
hmrSession.broadcast('error', payload);
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
catch {
|
|
416
|
+
/* best-effort */
|
|
417
|
+
}
|
|
395
418
|
}
|
|
396
419
|
}
|
|
397
|
-
await doBuild();
|
|
420
|
+
await doBuild().catch(() => { });
|
|
398
421
|
const server = createServer(async (req, res) => {
|
|
399
422
|
const url = new URL(req.url || '/', `http://localhost:${port}`);
|
|
400
423
|
// Dev panel endpoints (/__vesk/...): HMR state, plugin list, activate/
|
|
@@ -491,6 +514,28 @@ export async function startDevServer(appDir, options) {
|
|
|
491
514
|
res.end(runtimeBundle);
|
|
492
515
|
return;
|
|
493
516
|
}
|
|
517
|
+
// External data scripts (/ssr-data.js?t=...) are emitted by
|
|
518
|
+
// storeDataScriptGlobal once a render serializes SSR data. Without this
|
|
519
|
+
// route the dev SPA fallback served the HTML document as the script's
|
|
520
|
+
// payload, which the client then failed to parse as JavaScript
|
|
521
|
+
// ("Unexpected token '<'") — dev pages never serialized data before so
|
|
522
|
+
// the tag was never emitted and this was unreachable. Mirrors prod-server.
|
|
523
|
+
if (url.pathname === '/ssr-data.js') {
|
|
524
|
+
const token = url.searchParams.get('t') || '';
|
|
525
|
+
const store = globalThis.__vsk_ssr_data_store;
|
|
526
|
+
const payload = store?.[token];
|
|
527
|
+
if (payload)
|
|
528
|
+
delete store[token];
|
|
529
|
+
console.error(`[ssr-data-trace] ${url.pathname} token=${token.slice(0, 6)} referer=${req.headers['referer'] || req.headers['referrer'] || '-'} payload=${payload ? JSON.stringify({ props: Object.keys(payload.props || {}), data: Object.keys(payload.ssrData || {}) }) : 'NONE'}`);
|
|
530
|
+
const lines = [];
|
|
531
|
+
if (payload?.props)
|
|
532
|
+
lines.push(`globalThis.__vesk_props = ${safeJsonForScript(JSON.stringify(payload.props))};`);
|
|
533
|
+
if (payload?.ssrData)
|
|
534
|
+
lines.push(`globalThis.__vsk_ssr_data = ${safeJsonForScript(JSON.stringify(payload.ssrData))};`);
|
|
535
|
+
res.writeHead(200, { 'Content-Type': 'application/javascript', 'Cache-Control': 'no-store' });
|
|
536
|
+
res.end(lines.join('\n') || '// no ssr data');
|
|
537
|
+
return;
|
|
538
|
+
}
|
|
494
539
|
if (url.pathname.startsWith('/_vesk/static/')) {
|
|
495
540
|
const relPath = url.pathname.slice('/_vesk/static/'.length);
|
|
496
541
|
const staticPath = resolveWithin(resolve(devDir, 'static'), relPath);
|
|
@@ -558,6 +603,9 @@ export async function startDevServer(appDir, options) {
|
|
|
558
603
|
let finalBody = body;
|
|
559
604
|
if (contentType.includes('text/html')) {
|
|
560
605
|
finalBody = injectDevScripts(body);
|
|
606
|
+
if (finalBody.includes('/ssr-data.js')) {
|
|
607
|
+
console.error(`[body-trace] ${url.pathname} HTML body carries ssr-data ref (was-in-body=${body.includes('/ssr-data.js')})`);
|
|
608
|
+
}
|
|
561
609
|
}
|
|
562
610
|
res.writeHead(response.status, headers);
|
|
563
611
|
res.end(finalBody);
|
|
@@ -602,10 +650,15 @@ export async function startDevServer(appDir, options) {
|
|
|
602
650
|
const handlerPath = resolve(devDir, ssrRoute.function);
|
|
603
651
|
if (existsSync(handlerPath)) {
|
|
604
652
|
try {
|
|
653
|
+
const t0 = process.hrtime.bigint();
|
|
654
|
+
const tImport0 = process.hrtime.bigint();
|
|
605
655
|
const mod = await import(`${handlerPath}?t=${ssrVersion}`);
|
|
656
|
+
const tImport1 = process.hrtime.bigint();
|
|
606
657
|
const webRequest = makeWebRequest(req, url.href, maxBodyBytes);
|
|
607
658
|
const response = await mod.handle(webRequest);
|
|
659
|
+
const tHandle1 = process.hrtime.bigint();
|
|
608
660
|
const body = await response.text();
|
|
661
|
+
const tText1 = process.hrtime.bigint();
|
|
609
662
|
const headers = Object.fromEntries(response.headers);
|
|
610
663
|
const contentType = headers['content-type'] || '';
|
|
611
664
|
let finalBody = body;
|
|
@@ -614,6 +667,7 @@ export async function startDevServer(appDir, options) {
|
|
|
614
667
|
}
|
|
615
668
|
res.writeHead(response.status, headers);
|
|
616
669
|
res.end(finalBody);
|
|
670
|
+
console.error(`[vdtime] ${url.pathname} ssrVersion=${ssrVersion} total=${Number(tHandle1 - t0) / 1e6 | 0}ms import=${Number(tImport1 - tImport0) / 1e6 | 0}ms handle=${Number(tHandle1 - tImport1) / 1e6 | 0}ms text=${Number(tText1 - tHandle1) / 1e6 | 0}ms`);
|
|
617
671
|
}
|
|
618
672
|
catch (e) {
|
|
619
673
|
res.writeHead(500, { 'Content-Type': 'text/html' });
|
|
@@ -655,6 +709,10 @@ export async function startDevServer(appDir, options) {
|
|
|
655
709
|
});
|
|
656
710
|
const hmr = createHmrServer(server, appDir, devDir, componentMap);
|
|
657
711
|
hmrSession = hmr;
|
|
712
|
+
// replay any build error that happened before the HMR server existed
|
|
713
|
+
if (pendingInitialError) {
|
|
714
|
+
hmr.broadcast('error', pendingInitialError);
|
|
715
|
+
}
|
|
658
716
|
// ── Console streaming to devtool ────────────────────────────────────────
|
|
659
717
|
// Read `logs` from vesk.config and wire up server-side console interception
|
|
660
718
|
// so console.log/warn/error/info/debug are forwarded to the devtool Log tab.
|
package/dist/hmr.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hmr.d.ts","sourceRoot":"","sources":["../src/hmr.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAUxC,OAAO,EAAsC,KAAK,SAAS,EAAE,MAAM,mCAAmC,CAAC;AAEvG,OAAO,KAAK,EAAE,SAAS,EAAkB,MAAM,yBAAyB,CAAC;AAIzE;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAaD,wBAAgB,WAAW,IAAI;IAC7B,MAAM,EAAE,IAAI,GAAG,QAAQ,CAAC;IACxB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,KAAK,EAAE,eAAe,GAAG,IAAI,CAAC;IAC9B,QAAQ,EAAE,OAAO,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,CAQA;AAED,MAAM,WAAW,wBAAwB;IACvC,8EAA8E;IAC9E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,wEAAwE;IACxE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACjC;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,OAAO,EACd,QAAQ,EAAE,MAAM,EAChB,IAAI,GAAE,wBAA6B,GAClC,eAAe,
|
|
1
|
+
{"version":3,"file":"hmr.d.ts","sourceRoot":"","sources":["../src/hmr.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAUxC,OAAO,EAAsC,KAAK,SAAS,EAAE,MAAM,mCAAmC,CAAC;AAEvG,OAAO,KAAK,EAAE,SAAS,EAAkB,MAAM,yBAAyB,CAAC;AAIzE;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAaD,wBAAgB,WAAW,IAAI;IAC7B,MAAM,EAAE,IAAI,GAAG,QAAQ,CAAC;IACxB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,KAAK,EAAE,eAAe,GAAG,IAAI,CAAC;IAC9B,QAAQ,EAAE,OAAO,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,CAQA;AAED,MAAM,WAAW,wBAAwB;IACvC,8EAA8E;IAC9E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,wEAAwE;IACxE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACjC;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,OAAO,EACd,QAAQ,EAAE,MAAM,EAChB,IAAI,GAAE,wBAA6B,GAClC,eAAe,CA6FjB;AAwRD,wBAAgB,eAAe,CAC7B,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,YAAY,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GACjC;IACD,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;IAClE,gBAAgB,EAAE,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,SAAS,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACvH,WAAW,EAAE,MAAM,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;CACnD,CA6KA"}
|
package/dist/hmr.js
CHANGED
|
@@ -57,15 +57,39 @@ export function buildErrorPayload(error, filename, opts = {}) {
|
|
|
57
57
|
? error.stack
|
|
58
58
|
: undefined;
|
|
59
59
|
let codeframe;
|
|
60
|
+
let resolvedAbsPath;
|
|
60
61
|
if (line !== null && line >= 1 && typeof opts.appDir === 'string') {
|
|
61
62
|
let src;
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
63
|
+
const candidates = [];
|
|
64
|
+
// file may be relative to appDir (e.g. "comparison/page.vsk"),
|
|
65
|
+
// prefixed with "app/" (e.g. "app/comparison/page.vsk"),
|
|
66
|
+
// absolute, or relative to project root.
|
|
67
|
+
if (file.startsWith('/')) {
|
|
68
|
+
candidates.push(file);
|
|
66
69
|
}
|
|
67
|
-
|
|
68
|
-
|
|
70
|
+
else {
|
|
71
|
+
candidates.push(resolve(opts.appDir, file));
|
|
72
|
+
if (file.startsWith('app/')) {
|
|
73
|
+
candidates.push(resolve(opts.appDir, file.slice(4)));
|
|
74
|
+
candidates.push(resolve(opts.appDir, '..', file));
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
candidates.push(resolve(opts.appDir, '..', file));
|
|
78
|
+
}
|
|
79
|
+
// also try file as-is relative to cwd
|
|
80
|
+
candidates.push(resolve(file));
|
|
81
|
+
}
|
|
82
|
+
for (const absPath of candidates) {
|
|
83
|
+
try {
|
|
84
|
+
if (existsSync(absPath)) {
|
|
85
|
+
src = readFileSync(absPath, 'utf-8');
|
|
86
|
+
resolvedAbsPath = absPath;
|
|
87
|
+
break;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
catch {
|
|
91
|
+
/* try next candidate */
|
|
92
|
+
}
|
|
69
93
|
}
|
|
70
94
|
if (typeof src === 'string' && src.length > 0) {
|
|
71
95
|
const cf = buildCodeframe(src, line, column ?? 1);
|
|
@@ -76,9 +100,9 @@ export function buildErrorPayload(error, filename, opts = {}) {
|
|
|
76
100
|
}
|
|
77
101
|
}
|
|
78
102
|
const tipsData = suggestFor(message);
|
|
79
|
-
const filePath = typeof opts.appDir === 'string'
|
|
103
|
+
const filePath = resolvedAbsPath ?? (typeof opts.appDir === 'string'
|
|
80
104
|
? resolve(opts.appDir, file)
|
|
81
|
-
: undefined;
|
|
105
|
+
: undefined);
|
|
82
106
|
// The file header already shows the location; strip the redundant
|
|
83
107
|
// " in <file>" suffix compilers append to messages (e.g. acorn's
|
|
84
108
|
// "Unexpected token in /abs/app/page.vsk").
|
|
@@ -129,9 +153,13 @@ function collectAncestorLayouts(routeTree, sourceDir, chain = []) {
|
|
|
129
153
|
if (node.sourceDir === sourceDir)
|
|
130
154
|
return chain;
|
|
131
155
|
if (node.children) {
|
|
156
|
+
// Standalone layouts drop the ancestor chain — they replace the
|
|
157
|
+
// root layout nesting for all descendants.
|
|
158
|
+
const isStandalone = node.standalone === true;
|
|
159
|
+
const base = isStandalone ? [] : chain;
|
|
132
160
|
const nextChain = node.layout
|
|
133
|
-
? [...
|
|
134
|
-
:
|
|
161
|
+
? [...base, { sourceDir: node.sourceDir, layoutCompName: node.layout }]
|
|
162
|
+
: base;
|
|
135
163
|
const found = collectAncestorLayouts(node.children, sourceDir, nextChain);
|
|
136
164
|
if (found)
|
|
137
165
|
return found;
|
|
@@ -478,11 +506,35 @@ export function createHmrServer(httpServer, appDir, devDir, componentMap) {
|
|
|
478
506
|
}
|
|
479
507
|
}
|
|
480
508
|
if (sourceDir !== null) {
|
|
481
|
-
|
|
509
|
+
// sourceDir from extractSourceDir is relative to appDir (e.g. "community/discussions"),
|
|
510
|
+
// while routeTree nodes store absolute sourceDir — normalize to absolute for lookup
|
|
511
|
+
let absSourceDir;
|
|
512
|
+
if (sourceDir === '') {
|
|
513
|
+
absSourceDir = appDir;
|
|
514
|
+
}
|
|
515
|
+
else if (sourceDir.startsWith('app/')) {
|
|
516
|
+
absSourceDir = resolve(appDir, '..', sourceDir);
|
|
517
|
+
}
|
|
518
|
+
else {
|
|
519
|
+
absSourceDir = resolve(appDir, sourceDir);
|
|
520
|
+
}
|
|
521
|
+
const routeNode = findRouteForSource(routeTree, absSourceDir);
|
|
482
522
|
if (routeNode) {
|
|
483
|
-
const ancestorLayouts = collectAncestorLayouts(routeTree,
|
|
523
|
+
const ancestorLayouts = collectAncestorLayouts(routeTree, absSourceDir);
|
|
484
524
|
regenerateSsrFunction(routeNode, appDir, devDir, componentMap, { ancestorLayouts: ancestorLayouts || [] });
|
|
485
525
|
}
|
|
526
|
+
else if (filename.endsWith('page.vsk') || filename.endsWith('layout.vsk')) {
|
|
527
|
+
// new route (e.g. freshly created app/community/discussions/page.vsk)
|
|
528
|
+
// — routeTree is stale, need a full rebuild to pick up the new node
|
|
529
|
+
// and generate its SSR function with the correct layout chain
|
|
530
|
+
try {
|
|
531
|
+
await doFullBuild();
|
|
532
|
+
broadcast('reload', { reason: `new route: ${filename}`, time: Date.now() - start });
|
|
533
|
+
}
|
|
534
|
+
catch (e) {
|
|
535
|
+
broadcast('error', buildErrorPayload(e, filename, { appDir }));
|
|
536
|
+
}
|
|
537
|
+
}
|
|
486
538
|
}
|
|
487
539
|
console.error(`vesk hmr: ${assignments.map(a => a.name).join(', ')} (${Date.now() - start}ms)`);
|
|
488
540
|
}
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EACe,YAAY,EAAE,WAAW,EAC7B,UAAU,EAChC,MAAM,yBAAyB,CAAC;AAiBjC;;;;;;GAMG;AACH,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,OAAO,CAAC;CACjB;AACD,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,iBAAiB,EAAE,CAAC;CAC9B;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,UAAU,EAAE,EACrB,OAAO,EAAE,iBAAiB,EAAE,GAAG,IAAI,GAAG,SAAS,GAC9C,UAAU,EAAE,CAQd;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,UAAU,EAAE,EACrB,KAAK,EAAE,eAAe,GAAG,IAAI,GAAG,SAAS,GACxC,UAAU,EAAE,CAGd;AA+BD,wBAAsB,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EACe,YAAY,EAAE,WAAW,EAC7B,UAAU,EAChC,MAAM,yBAAyB,CAAC;AAiBjC;;;;;;GAMG;AACH,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,OAAO,CAAC;CACjB;AACD,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,iBAAiB,EAAE,CAAC;CAC9B;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,UAAU,EAAE,EACrB,OAAO,EAAE,iBAAiB,EAAE,GAAG,IAAI,GAAG,SAAS,GAC9C,UAAU,EAAE,CAQd;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,UAAU,EAAE,EACrB,KAAK,EAAE,eAAe,GAAG,IAAI,GAAG,SAAS,GACxC,UAAU,EAAE,CAGd;AA+BD,wBAAsB,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC,CA8TpG;AAED,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAIhE,OAAO,EACL,kBAAkB,EAClB,oBAAoB,EACpB,yBAAyB,EACzB,eAAe,GAChB,MAAM,2BAA2B,CAAC;AACnC,YAAY,EACV,mBAAmB,EACnB,YAAY,EACZ,kBAAkB,EAClB,cAAc,EACd,iBAAiB,EACjB,gBAAgB,EAChB,aAAa,EACb,aAAa,GACd,MAAM,2BAA2B,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -197,9 +197,13 @@ export async function build(appDir, options) {
|
|
|
197
197
|
const actionMap = {};
|
|
198
198
|
function walk(nodes, ancestorLayouts = []) {
|
|
199
199
|
for (const node of nodes) {
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
200
|
+
// Standalone layouts drop the entire ancestor chain — they replace
|
|
201
|
+
// the root layout nesting, so only their own layout (if any) remains.
|
|
202
|
+
const isStandalone = node.standalone === true;
|
|
203
|
+
let childAncestorLayouts = isStandalone ? [] : ancestorLayouts;
|
|
204
|
+
if (node.layout) {
|
|
205
|
+
childAncestorLayouts = [...childAncestorLayouts, { sourceDir: node.sourceDir, layoutCompName: node.layout }];
|
|
206
|
+
}
|
|
203
207
|
if (node.page) {
|
|
204
208
|
const mwChain = collectMiddlewareChain(routeTree, node.fullPath, appDir);
|
|
205
209
|
let mwCode = null;
|
|
@@ -207,7 +211,10 @@ export async function build(appDir, options) {
|
|
|
207
211
|
const mwSources = mwChain.map((m) => readFileSync(m.sourcePath, 'utf-8'));
|
|
208
212
|
mwCode = compileMiddlewareCode(mwSources);
|
|
209
213
|
}
|
|
210
|
-
|
|
214
|
+
// For standalone routes the layout chain is cleared — only the
|
|
215
|
+
// standalone node's own layout (if any) applies, no root ancestors.
|
|
216
|
+
const ssrAncestorLayouts = isStandalone ? [] : ancestorLayouts;
|
|
217
|
+
const { funcPath, funcCode, name } = generateSsrFunction(node, appDir, outDir, componentMap, { ancestorLayouts: ssrAncestorLayouts, middlewareCode: mwCode, headExtra: pluginHeadExtra });
|
|
211
218
|
writeFileSync(funcPath, funcCode, 'utf-8');
|
|
212
219
|
const pagePath = resolve(appDir, node.sourceDir, 'page.vsk');
|
|
213
220
|
if (existsSync(pagePath)) {
|
|
@@ -217,7 +224,7 @@ export async function build(appDir, options) {
|
|
|
217
224
|
const layoutSrc = readFileSync(resolve(appDir, node.sourceDir, 'layout.vsk'), 'utf-8');
|
|
218
225
|
actionIds.push(...collectActionIds(layoutSrc));
|
|
219
226
|
}
|
|
220
|
-
for (const a of
|
|
227
|
+
for (const a of ssrAncestorLayouts) {
|
|
221
228
|
const ancestorSrc = readFileSync(resolve(appDir, a.sourceDir, 'layout.vsk'), 'utf-8');
|
|
222
229
|
actionIds.push(...collectActionIds(ancestorSrc));
|
|
223
230
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"load-config.d.ts","sourceRoot":"","sources":["../src/load-config.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAE3D,wBAAsB,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CA+DxF"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared `vesk.config.{ts,js}` loader for the CLI and the production server.
|
|
3
|
+
*
|
|
4
|
+
* TS configs are transpiled to ESM and evaluated from a temp module rooted
|
|
5
|
+
* inside the project (`.vesk/`) so bare package imports (`@vesk/plugin-*`)
|
|
6
|
+
* resolve against the project's own `node_modules`. `@vesk/compiler` imports
|
|
7
|
+
* are stripped and the helpers injected via `globalThis.__vesk_inject` so the
|
|
8
|
+
* running CLI/adapter's own compiler build is used regardless of which version
|
|
9
|
+
* the project has installed.
|
|
10
|
+
*/
|
|
11
|
+
import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'node:fs';
|
|
12
|
+
import { join, dirname } from 'node:path';
|
|
13
|
+
import { pathToFileURL } from 'node:url';
|
|
14
|
+
import { createRequire } from 'node:module';
|
|
15
|
+
import { defineConfig, definePlugin, preset, validateConfig } from '@vesk/compiler/src/config';
|
|
16
|
+
export async function loadVeskConfig(projectDir) {
|
|
17
|
+
const jsPath = join(projectDir, 'vesk.config.js');
|
|
18
|
+
const tsPath = join(projectDir, 'vesk.config.ts');
|
|
19
|
+
let configPath = null;
|
|
20
|
+
if (existsSync(jsPath))
|
|
21
|
+
configPath = jsPath;
|
|
22
|
+
else if (existsSync(tsPath))
|
|
23
|
+
configPath = tsPath;
|
|
24
|
+
if (!configPath)
|
|
25
|
+
return undefined;
|
|
26
|
+
let raw;
|
|
27
|
+
if (configPath.endsWith('.ts')) {
|
|
28
|
+
const { transpile } = await import('typescript');
|
|
29
|
+
const src = readFileSync(configPath, 'utf-8');
|
|
30
|
+
let js = transpile(src, { module: 99, target: 99 });
|
|
31
|
+
const inject = { defineConfig, definePlugin, preset };
|
|
32
|
+
const projectRequire = createRequire(join(projectDir, 'package.json'));
|
|
33
|
+
const importRe = /import\s+(?:(?:\*\s*as\s+([\w$]+))|([\w$]+(?:\s*,\s*\{[^}]*\})?)|(\{[^}]*\}))\s+from\s+['"]([^'"]+)['"]\s*;?/g;
|
|
34
|
+
let m;
|
|
35
|
+
while ((m = importRe.exec(js)) !== null) {
|
|
36
|
+
const nsName = m[1];
|
|
37
|
+
const defPart = m[2];
|
|
38
|
+
const namedPart = m[3];
|
|
39
|
+
const specifier = m[4];
|
|
40
|
+
if (specifier === '@vesk/compiler')
|
|
41
|
+
continue;
|
|
42
|
+
const mod = await import(pathToFileURL(projectRequire.resolve(specifier)).href);
|
|
43
|
+
if (nsName) {
|
|
44
|
+
inject[nsName] = mod;
|
|
45
|
+
}
|
|
46
|
+
else if (defPart) {
|
|
47
|
+
const defaultName = defPart.split(',')[0].trim();
|
|
48
|
+
inject[defaultName] = mod.default ?? mod;
|
|
49
|
+
const open = defPart.indexOf('{');
|
|
50
|
+
if (open !== -1) {
|
|
51
|
+
for (const n of defPart.slice(open).matchAll(/(\w+)/g))
|
|
52
|
+
inject[n[1]] = mod[n[1]];
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
else if (namedPart) {
|
|
56
|
+
for (const n of namedPart.matchAll(/(\w+)/g))
|
|
57
|
+
inject[n[1]] = mod[n[1]];
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
js = js.replace(importRe, '');
|
|
61
|
+
const injectKeys = Object.keys(inject);
|
|
62
|
+
js = `const {${injectKeys.join(',')}} = globalThis.__vesk_inject;\n` + js;
|
|
63
|
+
const tmpFile = join(projectDir, '.vesk', 'config.loader.tmp.mjs');
|
|
64
|
+
mkdirSync(dirname(tmpFile), { recursive: true });
|
|
65
|
+
writeFileSync(tmpFile, js, 'utf-8');
|
|
66
|
+
globalThis.__vesk_inject = inject;
|
|
67
|
+
try {
|
|
68
|
+
const mod = await import(`${pathToFileURL(tmpFile).href}?t=${Date.now()}`);
|
|
69
|
+
raw = mod.default;
|
|
70
|
+
}
|
|
71
|
+
finally {
|
|
72
|
+
delete globalThis.__vesk_inject;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
const mod = await import(`${pathToFileURL(configPath).href}?t=${Date.now()}`);
|
|
77
|
+
raw = mod.default;
|
|
78
|
+
}
|
|
79
|
+
if (typeof raw === 'function')
|
|
80
|
+
raw = raw();
|
|
81
|
+
const config = (typeof defineConfig === 'function' ? defineConfig(raw) : raw);
|
|
82
|
+
if (typeof validateConfig === 'function')
|
|
83
|
+
validateConfig(config);
|
|
84
|
+
return config;
|
|
85
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prod-server.d.ts","sourceRoot":"","sources":["../src/prod-server.ts"],"names":[],"mappings":"AAEA,OAAO,EAA2D,KAAK,MAAM,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"prod-server.d.ts","sourceRoot":"","sources":["../src/prod-server.ts"],"names":[],"mappings":"AAEA,OAAO,EAA2D,KAAK,MAAM,EAAE,MAAM,WAAW,CAAC;AA8CjG,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,KAAK,GAAG;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,CAIzE;AA+FD,wBAAsB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAwbxI"}
|
package/dist/prod-server.js
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
import { readFileSync, existsSync, statSync } from 'node:fs';
|
|
2
2
|
import { resolve, extname, dirname } from 'node:path';
|
|
3
3
|
import { createServer } from 'node:http';
|
|
4
|
-
import { createRequire } from 'node:module';
|
|
5
4
|
import { fileURLToPath } from 'node:url';
|
|
6
5
|
import { createRateLimiter, resolveComponentName, safeJsonForScript, getClientProtocol, DEFAULT_MAX_BODY_BYTES } from '@vesk/compiler/src/server-codegen';
|
|
7
6
|
import { securityHeaders } from '@vesk/compiler/src/server-utils';
|
|
8
7
|
import { resolveWithin, installMdReadHook } from '@vesk/adapter/src/paths';
|
|
9
8
|
import { resolveCssUrls, hasBuiltGlobalCss } from '@vesk/adapter/src/css';
|
|
10
|
-
|
|
9
|
+
import { loadVeskConfig } from '@vesk/adapter/src/load-config';
|
|
11
10
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
12
11
|
async function readBody(req, maxBytes = DEFAULT_MAX_BODY_BYTES) {
|
|
13
12
|
const chunks = [];
|
|
@@ -140,23 +139,11 @@ export async function startProdServer(outDir, options) {
|
|
|
140
139
|
let securityConfig = {};
|
|
141
140
|
let mdConfig;
|
|
142
141
|
try {
|
|
143
|
-
const
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
rawConfig = _require(veskConfigPath);
|
|
142
|
+
const config = await loadVeskConfig(projectDir);
|
|
143
|
+
if (config) {
|
|
144
|
+
securityConfig = { security: config.security };
|
|
145
|
+
mdConfig = config.md;
|
|
148
146
|
}
|
|
149
|
-
else if (existsSync(veskConfigTsPath)) {
|
|
150
|
-
const { transpile } = _require('typescript');
|
|
151
|
-
const src = readFileSync(veskConfigTsPath, 'utf-8');
|
|
152
|
-
const result = transpile(src, { module: 99, target: 99 });
|
|
153
|
-
rawConfig = eval(`(${result})`);
|
|
154
|
-
}
|
|
155
|
-
if (typeof rawConfig === 'function')
|
|
156
|
-
rawConfig = rawConfig();
|
|
157
|
-
const configObj = rawConfig;
|
|
158
|
-
securityConfig = { security: configObj.security };
|
|
159
|
-
mdConfig = configObj.md;
|
|
160
147
|
}
|
|
161
148
|
catch (e) {
|
|
162
149
|
// Fail closed: keep the secure defaults above and warn loudly — a broken
|
package/dist/runtime-bundle.js
CHANGED
|
@@ -39,7 +39,7 @@ export async function bundleRuntime(appDir, outDir) {
|
|
|
39
39
|
const runtimeRoot = findRuntimeSrc(appDir);
|
|
40
40
|
const entryFile = resolve(outDir, 'server', `.runtime-entry-${buildId++}.mjs`);
|
|
41
41
|
const entryContent = [
|
|
42
|
-
`import { renderPage, renderFullPage, renderPageStream, compileFile, setRuntimeModule, setVskHydrate, assertSameOrigin } from ${JSON.stringify(resolve(compilerRoot, 'server-codegen.js'))};`,
|
|
42
|
+
`import { renderPage, renderFullPage, renderPageStream, compileFile, setRuntimeModule, setVskHydrate, hydratePrecompile, assertSameOrigin } from ${JSON.stringify(resolve(compilerRoot, 'server-codegen.js'))};`,
|
|
43
43
|
`import { parseCookies } from ${JSON.stringify(resolve(compilerRoot, 'server-cookies.js'))};`,
|
|
44
44
|
`import * as __veskRuntime from ${JSON.stringify(resolve(runtimeRoot, 'index-server.js'))};`,
|
|
45
45
|
'',
|
|
@@ -77,7 +77,7 @@ export async function bundleRuntime(appDir, outDir) {
|
|
|
77
77
|
' return req.locals || {};',
|
|
78
78
|
'}',
|
|
79
79
|
'',
|
|
80
|
-
'export { renderPage, renderFullPage, renderPageStream, compileFile, setVskHydrate, parseCookies, assertSameOrigin };',
|
|
80
|
+
'export { renderPage, renderFullPage, renderPageStream, compileFile, setVskHydrate, hydratePrecompile, parseCookies, assertSameOrigin };',
|
|
81
81
|
'export { withSsrStore } from "@vesk/compiler/src/ssr-store";',
|
|
82
82
|
'',
|
|
83
83
|
'// Deliver hydration data as an origin-served script so strict CSP (no unsafe-inline)',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ssr-function.d.ts","sourceRoot":"","sources":["../src/ssr-function.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,SAAS,EAAkB,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"ssr-function.d.ts","sourceRoot":"","sources":["../src/ssr-function.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,SAAS,EAAkB,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAI7F,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAQjF;AAgED,wBAAgB,mBAAmB,CACjC,SAAS,EAAE,SAAS,EACpB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,YAAY,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EAClC,OAAO,CAAC,EAAE,kBAAkB,GAC3B;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAoYtD"}
|
package/dist/ssr-function.js
CHANGED
|
@@ -1,13 +1,7 @@
|
|
|
1
1
|
import { readFileSync, existsSync } from 'node:fs';
|
|
2
2
|
import { resolve, relative, join } from 'node:path';
|
|
3
|
-
import { resolveComponentName } from '@vesk/compiler/src/server-codegen';
|
|
3
|
+
import { resolveComponentName, precompileFile } from '@vesk/compiler/src/server-codegen';
|
|
4
4
|
import { resolveCssUrls, hasBuiltGlobalCss } from '@vesk/adapter/src/css';
|
|
5
|
-
function escapeSource(src) {
|
|
6
|
-
return src
|
|
7
|
-
.replace(/\\/g, '\\\\')
|
|
8
|
-
.replace(/`/g, '\\`')
|
|
9
|
-
.replace(/\$/g, '\\$');
|
|
10
|
-
}
|
|
11
5
|
// Finds the nearest error.vsk walking up from the route's own directory to the
|
|
12
6
|
// app root, mirroring the router's findErrorComponent chain semantics.
|
|
13
7
|
export function resolveErrorFile(sourceDir, appDir) {
|
|
@@ -31,6 +25,19 @@ function routeName(segments) {
|
|
|
31
25
|
function extractCompName(src) {
|
|
32
26
|
return resolveComponentName(src);
|
|
33
27
|
}
|
|
28
|
+
/**
|
|
29
|
+
* Precompiles a `.vsk` file at BUILD time into a `PrecompileFilePlan` and
|
|
30
|
+
* returns it as a JSON object literal. True AOT: no source is embedded, no
|
|
31
|
+
* compile happens in the deployed function — `hydratePrecompile` rebuilds the
|
|
32
|
+
* render result at module load from this JSON alone.
|
|
33
|
+
*/
|
|
34
|
+
function precompilePlan(entryPath) {
|
|
35
|
+
const src = readFileSync(entryPath, 'utf-8');
|
|
36
|
+
return JSON.stringify(precompileFile(src, entryPath));
|
|
37
|
+
}
|
|
38
|
+
function hydrateInvoke(planExpr) {
|
|
39
|
+
return `(() => { try { return hydratePrecompile(${planExpr}); } catch { return null; } })()`;
|
|
40
|
+
}
|
|
34
41
|
function buildParamExtraction(node, urlParts) {
|
|
35
42
|
const parts = [];
|
|
36
43
|
let partIdx = Math.max(0, urlParts.length - 1);
|
|
@@ -96,38 +103,32 @@ export function generateSsrFunction(routeNode, appDir, outDir, componentMap, opt
|
|
|
96
103
|
const entryPath = resolve(appDir, entry.sourceDir, 'layout.vsk');
|
|
97
104
|
const entrySrc = readFileSync(entryPath, 'utf-8');
|
|
98
105
|
const entryComp = extractCompName(entrySrc) || 'Layout';
|
|
99
|
-
const
|
|
106
|
+
const plan = precompilePlan(entryPath);
|
|
100
107
|
layoutDecls.push({
|
|
101
|
-
src: `\`${escaped}\``,
|
|
102
108
|
comp: JSON.stringify(entryComp),
|
|
103
|
-
|
|
104
|
-
compiled:
|
|
109
|
+
plan,
|
|
110
|
+
compiled: hydrateInvoke(plan),
|
|
105
111
|
});
|
|
106
112
|
}
|
|
107
|
-
const
|
|
108
|
-
const pageComp = extractCompName(
|
|
113
|
+
const pagePlan = precompilePlan(pagePath);
|
|
114
|
+
const pageComp = extractCompName(readFileSync(pagePath, 'utf-8')) || 'Page';
|
|
109
115
|
const errorPath = resolveErrorFile(routeNode.sourceDir, appDir);
|
|
110
116
|
const errorSrc = errorPath ? readFileSync(errorPath, 'utf-8') : null;
|
|
111
117
|
const errorComp = errorPath ? (extractCompName(errorSrc) || 'Error') : null;
|
|
112
118
|
const errorVars = errorPath
|
|
113
|
-
? `const
|
|
114
|
-
: 'const
|
|
119
|
+
? `const _errorComp = ${JSON.stringify(errorComp)};\nconst _errorCompiled = ${hydrateInvoke(precompilePlan(errorPath))};\n`
|
|
120
|
+
: 'const _errorComp = null;\nconst _errorCompiled = null;\n';
|
|
115
121
|
let src = '';
|
|
116
122
|
if (layoutDecls.length > 0) {
|
|
117
|
-
src = `const
|
|
118
|
-
src += `const
|
|
119
|
-
src += `const _pagePath = ${JSON.stringify(pagePath)};\n`;
|
|
120
|
-
src += `const _pageCompiled = (() => { try { setVskHydrate(true); return compileFile(_pageSrc, { sourcePath: _pagePath }); } catch { return null; } finally { setVskHydrate(false); } })();\n`;
|
|
121
|
-
src += `const _layoutSrcList = [\n${layoutDecls.map((d) => ' ' + d.src + ',').join('\n')}\n];\n`;
|
|
123
|
+
src = `const _pageComp = ${JSON.stringify(pageComp)};\n`;
|
|
124
|
+
src += `const _pageCompiled = (() => { try { return hydratePrecompile(${pagePlan}); } catch { return null; } })();\n`;
|
|
122
125
|
src += `const _layoutCompList = [${layoutDecls.map((d) => d.comp).join(', ')}];\n`;
|
|
123
|
-
src += `const _layoutPathList = [${layoutDecls.map((d) => d.path).join(', ')}];\n`;
|
|
124
126
|
src += `const _layoutCompiledList = [\n${layoutDecls.map((d) => ' ' + d.compiled + ',').join('\n')}\n];\n`;
|
|
125
127
|
src += errorVars;
|
|
126
128
|
}
|
|
127
129
|
else {
|
|
128
|
-
src = `const
|
|
129
|
-
src += `const
|
|
130
|
-
src += `const _srcCompiled = (() => { try { setVskHydrate(true); return compileFile(_src, { sourcePath: _srcPath }); } catch { return null; } finally { setVskHydrate(false); } })();\n`;
|
|
130
|
+
src = `const _comp = ${JSON.stringify(pageComp)};\n`;
|
|
131
|
+
src += `const _compiled = (() => { try { return hydratePrecompile(${pagePlan}); } catch { return null; } })();\n`;
|
|
131
132
|
src += errorVars;
|
|
132
133
|
}
|
|
133
134
|
const urlParts = routeNode.fullPath.split('/').filter(Boolean);
|
|
@@ -139,12 +140,11 @@ export function generateSsrFunction(routeNode, appDir, outDir, componentMap, opt
|
|
|
139
140
|
const compRegEntries = [];
|
|
140
141
|
const compMap = componentMap || new Map();
|
|
141
142
|
for (const [compName, compPath] of compMap) {
|
|
142
|
-
const
|
|
143
|
-
const
|
|
144
|
-
compRegEntries.push(` registry.set(${JSON.stringify(compName)}, async (props, __registry, __vesk) => {\n const _src = \`${escapedSrc}\`;\n const _comp = ${JSON.stringify(compName)};\n const _compiled = (() => { try { setVskHydrate(true); return compileFile(_src, { sourcePath: ${JSON.stringify(compPath)} }); } catch { return null; } finally { setVskHydrate(false); } })();\n const result = await renderPage(_src, _comp, props, __registry, { hydrate: true, cached: _compiled, sourcePath: ${JSON.stringify(compPath)} });\n return result.body;\n })`);
|
|
143
|
+
const plan = precompilePlan(compPath);
|
|
144
|
+
compRegEntries.push(` (() => {\n const _compiled = (() => { try { return hydratePrecompile(${plan}); } catch { return null; } })();\n registry.set(${JSON.stringify(compName)}, async (props, __registry, __vesk) => {\n const result = await renderPage('', ${JSON.stringify(compName)}, props, __registry, { hydrate: true, cached: _compiled });\n return result.body;\n });\n })();`);
|
|
145
145
|
}
|
|
146
146
|
if (compRegEntries.length > 0) {
|
|
147
|
-
registryCode =
|
|
147
|
+
registryCode = 'const __componentRegistry = new Map();\n{\n' + compRegEntries.join('\n') + '\n}\n';
|
|
148
148
|
}
|
|
149
149
|
else {
|
|
150
150
|
registryCode = 'const __componentRegistry = new Map();\n';
|
|
@@ -153,9 +153,9 @@ export function generateSsrFunction(routeNode, appDir, outDir, componentMap, opt
|
|
|
153
153
|
if (layoutDecls.length > 0) {
|
|
154
154
|
htmlFnCode = [
|
|
155
155
|
'async function __renderErrorBody(props) {',
|
|
156
|
-
' if (!
|
|
156
|
+
' if (!_errorComp) throw props.error || new Error("Internal Server Error");',
|
|
157
157
|
' try {',
|
|
158
|
-
' const result = await renderPage(
|
|
158
|
+
' const result = await renderPage(\'\', _errorComp, props, __componentRegistry, { hydrate: true, cached: _errorCompiled });',
|
|
159
159
|
' return result.body;',
|
|
160
160
|
' } catch {',
|
|
161
161
|
' return \'<h1>500 \\u2014 Internal Server Error</h1>\';',
|
|
@@ -168,7 +168,7 @@ export function generateSsrFunction(routeNode, appDir, outDir, componentMap, opt
|
|
|
168
168
|
' let caughtError = null;',
|
|
169
169
|
" const __expose = process.env.NODE_ENV !== 'production';",
|
|
170
170
|
' try {',
|
|
171
|
-
' page = await renderPage(
|
|
171
|
+
' page = await renderPage(\'\', _pageComp, { params }, __componentRegistry, { hydrate: true, cached: _pageCompiled });',
|
|
172
172
|
' } catch (err) {',
|
|
173
173
|
' if (err && (err.name === \'NotFoundError\' || err.name === \'Redirect\')) throw err;',
|
|
174
174
|
' caughtError = err;',
|
|
@@ -178,12 +178,12 @@ export function generateSsrFunction(routeNode, appDir, outDir, componentMap, opt
|
|
|
178
178
|
' }',
|
|
179
179
|
' let _body = (caughtError ? \'<!--vesk-ssr-error:\' + (caughtError && typeof caughtError === \'object\' && \'message\' in caughtError ? encodeURIComponent(__expose ? String(caughtError.message) : \'Internal Server Error\') : \'\') + \'-->\' : \'\') + page.body;',
|
|
180
180
|
' let _head = page.head || \'\';',
|
|
181
|
-
' for (let _i =
|
|
182
|
-
|
|
181
|
+
' for (let _i = _layoutCompList.length - 1; _i > 0; _i--) {',
|
|
182
|
+
" const _inner = await renderPage('', _layoutCompList[_i], { params, children: _body }, __componentRegistry, { hydrate: true, cached: _layoutCompiledList[_i] });",
|
|
183
183
|
' _body = _inner.body;',
|
|
184
184
|
' if (_inner.head) _head = _inner.head + _head;',
|
|
185
185
|
' }',
|
|
186
|
-
|
|
186
|
+
" const html = await renderFullPage('', _layoutCompList[0], { params, children: _body }, __componentRegistry, { hydrate: true, cached: _layoutCompiledList[0]" + bakedOptions + clientScriptOption + dataScriptOption + ", pageHead: _head });",
|
|
187
187
|
" return new Response(html, { headers: { 'Content-Type': 'text/html' }, status: caughtError ? 500 : 200 });",
|
|
188
188
|
' });',
|
|
189
189
|
'}',
|
|
@@ -193,19 +193,19 @@ export function generateSsrFunction(routeNode, appDir, outDir, componentMap, opt
|
|
|
193
193
|
else {
|
|
194
194
|
htmlFnCode = [
|
|
195
195
|
'async function __renderErrorFullPage(params, requestUrl, err) {',
|
|
196
|
-
' if (!
|
|
196
|
+
' if (!_errorComp) throw err;',
|
|
197
197
|
" const __expose = process.env.NODE_ENV !== 'production';",
|
|
198
198
|
" const message = err && typeof err === 'object' && 'message' in err ? String(err.message) : String(err);",
|
|
199
199
|
" const stack = err && typeof err === 'object' && 'stack' in err ? String(err.stack) : '';",
|
|
200
200
|
" const props = { params, statusCode: 500, error: __expose ? message : 'Internal Server Error', stack: __expose ? stack : '', url: requestUrl || '' };",
|
|
201
|
-
|
|
201
|
+
" return renderFullPage('', _errorComp, props, __componentRegistry, { hydrate: true, cached: _errorCompiled" + bakedOptions + clientScriptOption + dataScriptOption + " });",
|
|
202
202
|
'}',
|
|
203
203
|
'',
|
|
204
204
|
'async function __renderHtml(params, requestUrl) {',
|
|
205
205
|
' return withSsrStore(async () => {',
|
|
206
206
|
' let stream;',
|
|
207
207
|
' try {',
|
|
208
|
-
|
|
208
|
+
" stream = renderPageStream('', _comp, { params }, __componentRegistry, { hydrate: true, cached: _compiled" + bakedOptions + clientScriptOption + dataScriptOption + ' });',
|
|
209
209
|
' } catch (err) {',
|
|
210
210
|
' if (err && (err.name === \'NotFoundError\' || err.name === \'Redirect\')) throw err;',
|
|
211
211
|
' const html = await __renderErrorFullPage(params, requestUrl, err);',
|
|
@@ -235,25 +235,41 @@ export function generateSsrFunction(routeNode, appDir, outDir, componentMap, opt
|
|
|
235
235
|
}
|
|
236
236
|
let dataCode;
|
|
237
237
|
const exposeErr = "process.env.NODE_ENV !== 'production'";
|
|
238
|
+
// SPA data-nav renders page + layouts through renderPage and never runs
|
|
239
|
+
// renderFullPage/renderPageStream, whose finally blocks own the per-request
|
|
240
|
+
// token/slot cleanup in the full-page path. Clear the handoff globals here so
|
|
241
|
+
// the next full-page render can't reuse the stale token and serialize the
|
|
242
|
+
// previous nav's SSR data into its page (ssr-data leak).
|
|
243
|
+
const dataNavCleanup = [
|
|
244
|
+
' } finally {',
|
|
245
|
+
' const __dnToken = globalThis.__vsk_ssr_token;',
|
|
246
|
+
' delete globalThis.__vsk_ssr;',
|
|
247
|
+
' if (__dnToken) delete globalThis[`__vsk_ssr_data_${__dnToken}`];',
|
|
248
|
+
' delete globalThis.__vsk_ssr_token;',
|
|
249
|
+
' delete globalThis.__vsk_ssr_data;',
|
|
250
|
+
' }',
|
|
251
|
+
];
|
|
238
252
|
if (layoutDecls.length > 0) {
|
|
239
253
|
dataCode = [
|
|
240
254
|
" if (request.headers.get('x-vesk-data') === '1') {",
|
|
241
|
-
' let dataPage;',
|
|
242
255
|
' try {',
|
|
243
|
-
' dataPage
|
|
244
|
-
'
|
|
245
|
-
|
|
246
|
-
'
|
|
247
|
-
|
|
248
|
-
'
|
|
249
|
-
'
|
|
250
|
-
'
|
|
251
|
-
'
|
|
252
|
-
'
|
|
253
|
-
'
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
256
|
+
' let dataPage;',
|
|
257
|
+
' try {',
|
|
258
|
+
" dataPage = await renderPage('', _pageComp, { params }, __componentRegistry, { hydrate: true, cached: _pageCompiled });",
|
|
259
|
+
' } catch (err) {',
|
|
260
|
+
" if (err && (err.name === 'NotFoundError' || err.name === 'Redirect')) throw err;",
|
|
261
|
+
' const message = err && typeof err === \'object\' && \'message\' in err ? String(err.message) : String(err);',
|
|
262
|
+
` return new Response(JSON.stringify({ error: ${exposeErr} ? message : 'Internal Server Error' }), { status: 500, headers: { 'Content-Type': 'application/json', 'Cache-Control': 'no-store', Vary: 'x-vesk-data' } });`,
|
|
263
|
+
' }',
|
|
264
|
+
' let _dataHead = dataPage.head || \'\';',
|
|
265
|
+
' for (let _i = _layoutCompList.length - 1; _i >= 0; _i--) {',
|
|
266
|
+
" const _dl = await renderPage('', _layoutCompList[_i], { params, children: '' }, __componentRegistry, { hydrate: true, cached: _layoutCompiledList[_i] });",
|
|
267
|
+
' _dataHead = (_dl.head || \'\') + _dataHead;',
|
|
268
|
+
' }',
|
|
269
|
+
" return new Response(JSON.stringify({ path: url.pathname, params, props: dataPage.props || { params }, head: _dataHead }), {",
|
|
270
|
+
" headers: { 'Content-Type': 'application/json', 'Cache-Control': 'no-store', Vary: 'x-vesk-data' },",
|
|
271
|
+
' });',
|
|
272
|
+
...dataNavCleanup,
|
|
257
273
|
' }',
|
|
258
274
|
' return __renderHtml(params, url.href);',
|
|
259
275
|
].join('\n');
|
|
@@ -261,17 +277,19 @@ export function generateSsrFunction(routeNode, appDir, outDir, componentMap, opt
|
|
|
261
277
|
else {
|
|
262
278
|
dataCode = [
|
|
263
279
|
" if (request.headers.get('x-vesk-data') === '1') {",
|
|
264
|
-
' let dataPage;',
|
|
265
280
|
' try {',
|
|
266
|
-
' dataPage
|
|
267
|
-
'
|
|
268
|
-
|
|
269
|
-
'
|
|
270
|
-
|
|
271
|
-
'
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
'
|
|
281
|
+
' let dataPage;',
|
|
282
|
+
' try {',
|
|
283
|
+
" dataPage = await renderPage('', _comp, { params }, __componentRegistry, { hydrate: true, cached: _compiled });",
|
|
284
|
+
' } catch (err) {',
|
|
285
|
+
" if (err && (err.name === 'NotFoundError' || err.name === 'Redirect')) throw err;",
|
|
286
|
+
' const message = err && typeof err === \'object\' && \'message\' in err ? String(err.message) : String(err);',
|
|
287
|
+
` return new Response(JSON.stringify({ error: ${exposeErr} ? message : 'Internal Server Error' }), { status: 500, headers: { 'Content-Type': 'application/json', 'Cache-Control': 'no-store', Vary: 'x-vesk-data' } });`,
|
|
288
|
+
' }',
|
|
289
|
+
" return new Response(JSON.stringify({ path: url.pathname, params, props: dataPage.props || { params }, head: dataPage.head || '' }), {",
|
|
290
|
+
" headers: { 'Content-Type': 'application/json', 'Cache-Control': 'no-store', Vary: 'x-vesk-data' },",
|
|
291
|
+
' });',
|
|
292
|
+
...dataNavCleanup,
|
|
275
293
|
' }',
|
|
276
294
|
' return __renderHtml(params, url.href);',
|
|
277
295
|
].join('\n');
|
|
@@ -318,28 +336,16 @@ export function generateSsrFunction(routeNode, appDir, outDir, componentMap, opt
|
|
|
318
336
|
' }',
|
|
319
337
|
].join('\n');
|
|
320
338
|
}
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
].join('\n');
|
|
332
|
-
}
|
|
333
|
-
else {
|
|
334
|
-
registerActionsCode = [
|
|
335
|
-
'async function __registerActions() {',
|
|
336
|
-
' if (__actionsRegistered) return;',
|
|
337
|
-
' __actionsRegistered = true;',
|
|
338
|
-
' compileFile(_src, { sourcePath: _srcPath });',
|
|
339
|
-
'}',
|
|
340
|
-
'',
|
|
341
|
-
].join('\n');
|
|
342
|
-
}
|
|
339
|
+
// Actions are registered while each plan hydrates (its actions-transformed
|
|
340
|
+
// top-level code runs `defineAction` during `hydratePrecompile`), so the
|
|
341
|
+
// request-time registration pass is a no-op.
|
|
342
|
+
const registerActionsCode = [
|
|
343
|
+
'async function __registerActions() {',
|
|
344
|
+
' if (__actionsRegistered) return;',
|
|
345
|
+
' __actionsRegistered = true;',
|
|
346
|
+
'}',
|
|
347
|
+
'',
|
|
348
|
+
].join('\n');
|
|
343
349
|
const actionCode = [
|
|
344
350
|
'export async function handleAction(request, id) {',
|
|
345
351
|
' // CSRF defense: cross-site browser POSTs always carry an Origin header.',
|
|
@@ -421,7 +427,7 @@ export function generateSsrFunction(routeNode, appDir, outDir, componentMap, opt
|
|
|
421
427
|
'',
|
|
422
428
|
].join('\n');
|
|
423
429
|
const funcCode = [
|
|
424
|
-
"import { renderFullPage, renderPageStream, renderPage,
|
|
430
|
+
"import { renderFullPage, renderPageStream, renderPage, hydratePrecompile, parseCookies, getAction, validateActionInput, issuesToFieldMap, storeDataScriptGlobal, withSsrStore, assertSameOrigin, VeskRequest } from '../runtime.js';",
|
|
425
431
|
'',
|
|
426
432
|
middlewareCode || '',
|
|
427
433
|
registryCode,
|
package/dist/types.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export type { RouteNode, ApiRouteNode, VeskPlugin, ServerEventContext, VeskEventHandlers, VeskSecurity, VeskCors, VeskRateLimit, VeskSecurityPreset, SecurityConfig, MiddlewareChainItem, MiddlewareExtractResult, AncestorLayout, BuildOptions, DevServerOptions, ProdServerOptions, SsrFunctionOptions, ApiFunctionOptions, ClientBundleOptions, ClientBundleFileEntry, ClientBundleCache, ChunkEntry, ClientBundleResult, MonolithicBundleParts, Manifest, ManifestRouteEntry, ManifestActionEntry, ManifestPrerenderedEntry, SsgRouteResult, BuildResult, ImageRef, ImageResult, SeoCheckIssue, SeoAuditResult, CombinedPageInfo, Tracked, Resource, UseFetchOptions, UseFetchStreamOptions, VeskRequest, VeskResponse, SetCookieOptions, CookieStore, ServerRequest, SsrDataSink, MdProps, MdConfig, MdHtmlMode, MarkdownOptions, MdHtmlWarning, } from '@vesk/types';
|
|
1
|
+
export type { RouteNode, ApiRouteNode, VeskPlugin, ServerEventContext, VeskEventHandlers, VeskSecurity, VeskCors, VeskRateLimit, VeskSecurityPreset, SecurityConfig, MiddlewareChainItem, MiddlewareExtractResult, AncestorLayout, BuildOptions, DevServerOptions, ProdServerOptions, SsrFunctionOptions, ApiFunctionOptions, ClientBundleOptions, ClientBundleFileEntry, ClientBundleChunkSpec, ClientBundleCache, ChunkEntry, ClientBundleResult, MonolithicBundleParts, Manifest, ManifestRouteEntry, ManifestActionEntry, ManifestPrerenderedEntry, SsgRouteResult, BuildResult, ImageRef, ImageResult, SeoCheckIssue, SeoAuditResult, CombinedPageInfo, Tracked, Resource, UseFetchOptions, UseFetchStreamOptions, VeskRequest, VeskResponse, SetCookieOptions, CookieStore, ServerRequest, SsrDataSink, MdProps, MdConfig, MdHtmlMode, MarkdownOptions, MdHtmlWarning, } from '@vesk/types';
|
|
2
2
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAGA,YAAY,EACV,SAAS,EACT,YAAY,EACZ,UAAU,EACV,kBAAkB,EAClB,iBAAiB,EACjB,YAAY,EACZ,QAAQ,EACR,aAAa,EACb,kBAAkB,EAClB,cAAc,EACd,mBAAmB,EACnB,uBAAuB,EACvB,cAAc,EACd,YAAY,EACZ,gBAAgB,EAChB,iBAAiB,EACjB,kBAAkB,EAClB,kBAAkB,EAClB,mBAAmB,EACnB,qBAAqB,EACrB,iBAAiB,EACjB,UAAU,EACV,kBAAkB,EAClB,qBAAqB,EACrB,QAAQ,EACR,kBAAkB,EAClB,mBAAmB,EACnB,wBAAwB,EACxB,cAAc,EACd,WAAW,EACX,QAAQ,EACR,WAAW,EACX,aAAa,EACb,cAAc,EACd,gBAAgB,EAChB,OAAO,EACP,QAAQ,EACR,eAAe,EACf,qBAAqB,EACrB,WAAW,EACX,YAAY,EACZ,gBAAgB,EAChB,WAAW,EACX,aAAa,EACb,WAAW,EACX,OAAO,EACP,QAAQ,EACR,UAAU,EACV,eAAe,EACf,aAAa,GACd,MAAM,aAAa,CAAC"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAGA,YAAY,EACV,SAAS,EACT,YAAY,EACZ,UAAU,EACV,kBAAkB,EAClB,iBAAiB,EACjB,YAAY,EACZ,QAAQ,EACR,aAAa,EACb,kBAAkB,EAClB,cAAc,EACd,mBAAmB,EACnB,uBAAuB,EACvB,cAAc,EACd,YAAY,EACZ,gBAAgB,EAChB,iBAAiB,EACjB,kBAAkB,EAClB,kBAAkB,EAClB,mBAAmB,EACnB,qBAAqB,EACrB,qBAAqB,EACrB,iBAAiB,EACjB,UAAU,EACV,kBAAkB,EAClB,qBAAqB,EACrB,QAAQ,EACR,kBAAkB,EAClB,mBAAmB,EACnB,wBAAwB,EACxB,cAAc,EACd,WAAW,EACX,QAAQ,EACR,WAAW,EACX,aAAa,EACb,cAAc,EACd,gBAAgB,EAChB,OAAO,EACP,QAAQ,EACR,eAAe,EACf,qBAAqB,EACrB,WAAW,EACX,YAAY,EACZ,gBAAgB,EAChB,WAAW,EACX,aAAa,EACb,WAAW,EACX,OAAO,EACP,QAAQ,EACR,UAAU,EACV,eAAe,EACf,aAAa,GACd,MAAM,aAAa,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vesk/adapter",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.24",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Vesk adapter — builds deployable .vesk/ output for Deno and Node serverless",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -23,9 +23,9 @@
|
|
|
23
23
|
"sharp": "^0.35.3"
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"@vesk/compiler": "^0.2.
|
|
27
|
-
"@vesk/runtime": "^0.2.
|
|
28
|
-
"@vesk/types": "^0.2.
|
|
26
|
+
"@vesk/compiler": "^0.2.24",
|
|
27
|
+
"@vesk/runtime": "^0.2.24",
|
|
28
|
+
"@vesk/types": "^0.2.24"
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|
|
31
31
|
"@types/ws": "^8.18.1",
|