@vesk/adapter 0.0.1

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.
Files changed (60) hide show
  1. package/README.md +21 -0
  2. package/dist/api-function.d.ts +7 -0
  3. package/dist/api-function.d.ts.map +1 -0
  4. package/dist/api-function.js +187 -0
  5. package/dist/client-bundle.d.ts +19 -0
  6. package/dist/client-bundle.d.ts.map +1 -0
  7. package/dist/client-bundle.js +491 -0
  8. package/dist/dev-server.d.ts +4 -0
  9. package/dist/dev-server.d.ts.map +1 -0
  10. package/dist/dev-server.js +358 -0
  11. package/dist/esbuild-fallback.d.ts +3 -0
  12. package/dist/esbuild-fallback.d.ts.map +1 -0
  13. package/dist/esbuild-fallback.js +64 -0
  14. package/dist/hmr.d.ts +7 -0
  15. package/dist/hmr.d.ts.map +1 -0
  16. package/dist/hmr.js +411 -0
  17. package/dist/image-pipeline.d.ts +3 -0
  18. package/dist/image-pipeline.d.ts.map +1 -0
  19. package/dist/image-pipeline.js +120 -0
  20. package/dist/index.d.ts +4 -0
  21. package/dist/index.d.ts.map +1 -0
  22. package/dist/index.js +291 -0
  23. package/dist/manifest.d.ts +3 -0
  24. package/dist/manifest.d.ts.map +1 -0
  25. package/dist/manifest.js +47 -0
  26. package/dist/middleware.d.ts +4 -0
  27. package/dist/middleware.d.ts.map +1 -0
  28. package/dist/middleware.js +96 -0
  29. package/dist/package.json +15 -0
  30. package/dist/platform-deploy.d.ts +18 -0
  31. package/dist/platform-deploy.d.ts.map +1 -0
  32. package/dist/platform-deploy.js +354 -0
  33. package/dist/platform-handler.d.ts +32 -0
  34. package/dist/platform-handler.d.ts.map +1 -0
  35. package/dist/platform-handler.js +211 -0
  36. package/dist/platform-output.d.ts +30 -0
  37. package/dist/platform-output.d.ts.map +1 -0
  38. package/dist/platform-output.js +119 -0
  39. package/dist/platform.d.ts +17 -0
  40. package/dist/platform.d.ts.map +1 -0
  41. package/dist/platform.js +35 -0
  42. package/dist/prod-server.d.ts +5 -0
  43. package/dist/prod-server.d.ts.map +1 -0
  44. package/dist/prod-server.js +429 -0
  45. package/dist/runtime-bundle.d.ts +2 -0
  46. package/dist/runtime-bundle.d.ts.map +1 -0
  47. package/dist/runtime-bundle.js +140 -0
  48. package/dist/seo-audit.d.ts +3 -0
  49. package/dist/seo-audit.d.ts.map +1 -0
  50. package/dist/seo-audit.js +169 -0
  51. package/dist/ssr-function.d.ts +8 -0
  52. package/dist/ssr-function.d.ts.map +1 -0
  53. package/dist/ssr-function.js +415 -0
  54. package/dist/static.d.ts +8 -0
  55. package/dist/static.d.ts.map +1 -0
  56. package/dist/static.js +130 -0
  57. package/dist/types.d.ts +182 -0
  58. package/dist/types.d.ts.map +1 -0
  59. package/dist/types.js +1 -0
  60. package/package.json +54 -0
@@ -0,0 +1,491 @@
1
+ import { readFileSync, existsSync, writeFileSync, unlinkSync } from 'node:fs';
2
+ import { resolve, join, dirname, relative, sep } from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
4
+ import { build, transformSync } from './esbuild-fallback.js';
5
+ import { compileClient } from '@vesk/compiler/src/client-codegen';
6
+ import { resolveComponentName } from '@vesk/compiler/src/server-codegen';
7
+ import { collectVskImportPaths, vskImportLines } from '@vesk/compiler/src/vsk-imports';
8
+ const __dirname = dirname(fileURLToPath(import.meta.url));
9
+ function buildRouterOpts(options) {
10
+ const ttl = options?.routeDataCache;
11
+ if (typeof ttl === 'number' && ttl > 0) {
12
+ return `, { routeDataCache: ${ttl} }`;
13
+ }
14
+ return '';
15
+ }
16
+ function findRuntimeSrc(appDir) {
17
+ const monorepoRoot = resolve(__dirname, '..', '..', '..');
18
+ const candidates = [
19
+ resolve(monorepoRoot, 'packages', 'runtime', 'dist'),
20
+ resolve(appDir, '..', 'node_modules', '@vesk/runtime'),
21
+ resolve(appDir, 'node_modules', '@vesk/runtime'),
22
+ ];
23
+ for (const base of candidates) {
24
+ for (const dir of [base, join(base, 'dist')]) {
25
+ if (existsSync(join(dir, 'index-client.js')))
26
+ return dir;
27
+ }
28
+ }
29
+ throw new Error('@vesk/runtime/dist not found — run "npm run build" first');
30
+ }
31
+ export async function generateClientBundle(routeTree, appDir, componentMap, options) {
32
+ const runtimeDir = findRuntimeSrc(appDir);
33
+ const seen = new Set();
34
+ const chunks = [];
35
+ const runtimeImportNames = new Set();
36
+ function collectRuntimeImports(code) {
37
+ const re = /^import\s*\{([^}]*)\}\s*from\s*['"]@vesk\/runtime['"];?\s*\n?/gm;
38
+ for (const m of code.matchAll(re)) {
39
+ for (const name of m[1].split(',')) {
40
+ const trimmed = name.trim().replace(/^(\w+)\s+as\s+.*$/, '$1');
41
+ if (!trimmed || /^(type|typeof)\s/.test(trimmed))
42
+ continue;
43
+ runtimeImportNames.add(trimmed);
44
+ }
45
+ }
46
+ }
47
+ function stripRuntimeImport(code) {
48
+ return code.replace(/^import\s*\{[^}]*\}\s*from\s*['"]@vesk\/runtime['"];?\s*\n?/gm, '')
49
+ .replace(/const\s+__components\s*=\s*\{\};\s*\n?/g, '')
50
+ .replace(/^function __cleanup\(start, end\) \{[\s\S]*?\n\}\s*\n?/gm, '')
51
+ .replace(/^function __place\(start, end, nodes, fallback\) \{[\s\S]*?\n\}\s*\n?/gm, '');
52
+ }
53
+ function stripVskImports(code) {
54
+ return code.replace(/^import\s*\{[^}]*\}\s*from\s*['"][^'"]*\.vsk['"];?\s*\n?/gm, '');
55
+ }
56
+ function resolveVskImports(filePath, compile) {
57
+ const src = readFileSync(filePath, 'utf-8');
58
+ for (const importPath of collectVskImportPaths(vskImportLines(src), filePath)) {
59
+ let importedName = null;
60
+ try {
61
+ importedName = resolveComponentName(readFileSync(importPath, 'utf-8'));
62
+ }
63
+ catch {
64
+ continue;
65
+ }
66
+ compile(importPath, importedName);
67
+ }
68
+ }
69
+ function stripExports(code) {
70
+ return code
71
+ .replace(/^export\s+default\s+__components\[.*?\];?\s*\n?/gm, '')
72
+ .replace(/^export\s+(const|let|var)\s+\w+\s*=\s*__components\[.*?\];?\s*\n?/gm, '');
73
+ }
74
+ function compileFile(filePath, resolvedName, output) {
75
+ if (seen.has(filePath))
76
+ return;
77
+ seen.add(filePath);
78
+ const src = readFileSync(filePath, 'utf-8');
79
+ resolveVskImports(filePath, (p, n) => compileFile(p, n || '', output));
80
+ const compCode = compileClient(src, null, { forceClient: true });
81
+ if (compCode) {
82
+ collectRuntimeImports(compCode);
83
+ const stripped = stripExports(stripVskImports(stripRuntimeImport(compCode)));
84
+ output.push(stripped.replace(/^\n+/, '').replace(/\n+$/, ''));
85
+ }
86
+ const hydCode = compileClient(src, null, { hydrate: true, forceClient: true, includeTopLevel: false });
87
+ if (hydCode) {
88
+ collectRuntimeImports(hydCode);
89
+ const stripped = stripExports(stripVskImports(stripRuntimeImport(hydCode)))
90
+ .replace(/__components/g, '__hydrators');
91
+ output.push(stripped.replace(/^\n+/, '').replace(/\n+$/, ''));
92
+ }
93
+ const actualName = resolveComponentName(src);
94
+ if (actualName && actualName !== resolvedName) {
95
+ output.push(`Object.defineProperty(__components, ${JSON.stringify(resolvedName)}, { get: () => __components[${JSON.stringify(actualName)}], configurable: true });`);
96
+ output.push(`Object.defineProperty(__hydrators, ${JSON.stringify(resolvedName)}, { get: () => __hydrators[${JSON.stringify(actualName)}], configurable: true });`);
97
+ }
98
+ }
99
+ function buildChunkName(node) {
100
+ const dir = relative(appDir, node.sourceDir || '');
101
+ const parts = dir.split(sep).filter(Boolean);
102
+ const slug = parts.length > 0 ? parts.join('-') : 'index';
103
+ return slug.replace(/[\[\]]/g, '_');
104
+ }
105
+ const codeSplit = !!(options?.codeSplit);
106
+ if (codeSplit) {
107
+ const chunkEntries = [];
108
+ function walkSplit(nodes, _chain) {
109
+ for (const node of nodes) {
110
+ const chunkCode = [];
111
+ const pagePath = resolve(appDir, node.sourceDir, 'page.vsk');
112
+ if (node.page && existsSync(pagePath)) {
113
+ compileFile(pagePath, node.page, chunkCode);
114
+ }
115
+ const layoutPath = resolve(appDir, node.sourceDir, 'layout.vsk');
116
+ if (node.layout && existsSync(layoutPath)) {
117
+ compileFile(layoutPath, node.layout, chunkCode);
118
+ }
119
+ const errorPath = resolve(appDir, node.sourceDir, 'error.vsk');
120
+ if (node.error && existsSync(errorPath)) {
121
+ compileFile(errorPath, node.error, chunkCode);
122
+ }
123
+ const notFoundPath = resolve(appDir, node.sourceDir, 'not-found.vsk');
124
+ if (node.notFound && existsSync(notFoundPath)) {
125
+ compileFile(notFoundPath, node.notFound, chunkCode);
126
+ }
127
+ const loadingPath = resolve(appDir, node.sourceDir, 'loading.vsk');
128
+ if (node.loading && existsSync(loadingPath)) {
129
+ compileFile(loadingPath, node.loading, chunkCode);
130
+ }
131
+ if (chunkCode.length > 0) {
132
+ const chunkName = `page-${buildChunkName(node)}.js`;
133
+ chunkEntries.push({ name: chunkName, code: chunkCode.join('\n\n'), node });
134
+ }
135
+ walkSplit(node.children || [], [..._chain, node]);
136
+ }
137
+ }
138
+ walkSplit(routeTree, []);
139
+ const sharedCode = [];
140
+ const compMap = componentMap || new Map();
141
+ for (const [compName, compPath] of compMap) {
142
+ compileFile(compPath, compName, sharedCode);
143
+ }
144
+ if (sharedCode.length > 0) {
145
+ chunkEntries.push({ name: 'shared.js', code: sharedCode.join('\n\n'), node: null });
146
+ }
147
+ for (const entry of chunkEntries) {
148
+ if (entry.code.trim()) {
149
+ chunks.push({
150
+ name: entry.name,
151
+ code: `(()=>{\nconst __components = globalThis.__components || (globalThis.__components = {});\nconst __hydrators = globalThis.__hydrators || (globalThis.__hydrators = {});\n${entry.code}\n})();\n`,
152
+ });
153
+ }
154
+ }
155
+ function annotate(nodes) {
156
+ for (const node of nodes) {
157
+ const chunkName = `page-${buildChunkName(node)}.js`;
158
+ const hasEntry = chunkEntries.some(e => e.name === chunkName && e.code.trim());
159
+ if (hasEntry)
160
+ node.chunk = `/_vesk/static/${chunkName}`;
161
+ annotate(node.children || []);
162
+ }
163
+ }
164
+ annotate(routeTree);
165
+ const main = await buildMainBundle(routeTree, runtimeDir, true, {}, !!options?.hmr, !!options?.importRuntime, runtimeImportNames, options?.routeDataCache);
166
+ return { main, chunks };
167
+ }
168
+ else {
169
+ let componentLines = [];
170
+ let hydratorLines = [];
171
+ let aliasLines = [];
172
+ let hydratorAliasLines = [];
173
+ function compileFileMono(filePath, resolvedName) {
174
+ if (seen.has(filePath))
175
+ return;
176
+ seen.add(filePath);
177
+ const src = readFileSync(filePath, 'utf-8');
178
+ resolveVskImports(filePath, (p, n) => compileFileMono(p, n || ''));
179
+ const compCode = compileClient(src, null, { forceClient: true });
180
+ if (compCode) {
181
+ collectRuntimeImports(compCode);
182
+ const stripped = stripExports(stripVskImports(stripRuntimeImport(compCode)));
183
+ componentLines.push(stripped.replace(/^\n+/, '').replace(/\n+$/, ''));
184
+ }
185
+ const hydCode = compileClient(src, null, { hydrate: true, forceClient: true, includeTopLevel: false });
186
+ if (hydCode) {
187
+ collectRuntimeImports(hydCode);
188
+ const stripped = stripExports(stripVskImports(stripRuntimeImport(hydCode)))
189
+ .replace(/__components/g, '__hydrators');
190
+ hydratorLines.push(stripped.replace(/^\n+/, '').replace(/\n+$/, ''));
191
+ }
192
+ const actualName = resolveComponentName(src);
193
+ if (actualName && actualName !== resolvedName) {
194
+ aliasLines.push(`Object.defineProperty(__components, ${JSON.stringify(resolvedName)}, { get: () => __components[${JSON.stringify(actualName)}], configurable: true });`);
195
+ hydratorAliasLines.push(`Object.defineProperty(__hydrators, ${JSON.stringify(resolvedName)}, { get: () => __hydrators[${JSON.stringify(actualName)}], configurable: true });`);
196
+ }
197
+ }
198
+ function walkMono(nodes) {
199
+ for (const node of nodes) {
200
+ const pagePath = resolve(appDir, node.sourceDir, 'page.vsk');
201
+ if (node.page && existsSync(pagePath))
202
+ compileFileMono(pagePath, node.page);
203
+ const layoutPath = resolve(appDir, node.sourceDir, 'layout.vsk');
204
+ if (node.layout && existsSync(layoutPath))
205
+ compileFileMono(layoutPath, node.layout);
206
+ const errorPath = resolve(appDir, node.sourceDir, 'error.vsk');
207
+ if (node.error && existsSync(errorPath))
208
+ compileFileMono(errorPath, node.error);
209
+ const notFoundPath = resolve(appDir, node.sourceDir, 'not-found.vsk');
210
+ if (node.notFound && existsSync(notFoundPath))
211
+ compileFileMono(notFoundPath, node.notFound);
212
+ const loadingPath = resolve(appDir, node.sourceDir, 'loading.vsk');
213
+ if (node.loading && existsSync(loadingPath))
214
+ compileFileMono(loadingPath, node.loading);
215
+ walkMono(node.children || []);
216
+ }
217
+ }
218
+ walkMono(routeTree);
219
+ const compMap = componentMap || new Map();
220
+ for (const [compName, compPath] of compMap) {
221
+ compileFileMono(compPath, compName);
222
+ }
223
+ const main = await buildMainBundle(routeTree, runtimeDir, false, {
224
+ componentLines, hydratorLines, aliasLines, hydratorAliasLines,
225
+ }, !!options?.hmr, !!options?.importRuntime, runtimeImportNames, options?.routeDataCache);
226
+ return { main, chunks: [] };
227
+ }
228
+ }
229
+ function stripTypes(code) {
230
+ return transformSync(code, { loader: 'ts' }).code;
231
+ }
232
+ export function buildRuntimeCode(runtimeDir) {
233
+ const runtimeFiles = [
234
+ 'ripple-constants.js', 'ripple-utils.js', 'ripple-runtime.js', 'ripple-blocks.js',
235
+ 'context.js', 'hydrate.js', 'resource.js',
236
+ 'reconcile.js', 'bindings.js', 'router-match.js', 'router-components.js', 'router.js',
237
+ 'portal.js',
238
+ 'seo.js', 'image.js', 'experiment.js', 'form.js', 'action.js',
239
+ ];
240
+ let code = '';
241
+ for (const f of runtimeFiles) {
242
+ const p = join(runtimeDir, f);
243
+ if (existsSync(p)) {
244
+ let src = readFileSync(p, 'utf-8');
245
+ src = stripTypes(src);
246
+ src = src.replace(/^import\s+[\s\S]*?from\s+['"](?:\.\/.*?|@vesk\/runtime\/src\/.*?)['"];?\n?/gm, '');
247
+ src = src.replace(/^import\s+['"](?:\.\/.*?|@vesk\/runtime\/src\/.*?)['"];?\n?/gm, '');
248
+ src = src.replace(/^export\s*\{\s*[\s\S]*?\}\s*from\s+['"][^'"]+['"];?\n?/gm, '');
249
+ src = src.replace(/^export\s*\{\s*[\s\S]*?\};?\n?/gm, '');
250
+ src = src.replace(/^export\s+/gm, '');
251
+ code += `// --- ${f} ---\n${src}\n`;
252
+ }
253
+ }
254
+ const indexSrc = readFileSync(join(runtimeDir, 'index-client.js'), 'utf-8');
255
+ const exportNames = stripTypes(indexSrc).match(/export\s*\{\s*([^}]+)\s*\}\s*from/g)
256
+ ?.flatMap(m => m.replace(/export\s*\{\s*|\s*\}\s*from/g, '').split(',').map(s => s.trim())) || [];
257
+ code += '// --- exports ---\n';
258
+ for (const name of [...new Set(exportNames)]) {
259
+ if (name)
260
+ code += `export { ${name} };\n`;
261
+ }
262
+ return code;
263
+ }
264
+ /**
265
+ * Names the client runtime actually exports, so the tree-shaken bundle only
266
+ * emits the modules reachable from the used set.
267
+ */
268
+ export function runtimeExportNames(runtimeDir) {
269
+ const indexSrc = readFileSync(join(runtimeDir, 'index-client.js'), 'utf-8');
270
+ const names = new Set();
271
+ for (const m of indexSrc.matchAll(/export\s*\{([^}]+)\}\s*from/g)) {
272
+ for (const raw of m[1].split(',')) {
273
+ const n = raw.trim().split(/\s+as\s+/).pop().trim();
274
+ if (n)
275
+ names.add(n);
276
+ }
277
+ }
278
+ return names;
279
+ }
280
+ let runtimeEntryId = 0;
281
+ /**
282
+ * Builds a single self-contained runtime module for the given used names.
283
+ *
284
+ * The runtime's real module graph is bundled by esbuild into one IIFE whose
285
+ * scope is fully closed, so its internal identifiers can never collide with
286
+ * page code. Only the exact names the app uses are re-exported as module-scope
287
+ * const bindings. This replaces the old regex-based file concatenation, which
288
+ * leaked runtime module-scope names into the page scope.
289
+ */
290
+ export async function buildTreeShakenRuntime(runtimeDir, usedNames) {
291
+ const unique = [...new Set(usedNames)];
292
+ const available = runtimeExportNames(runtimeDir);
293
+ const missing = unique.filter((n) => !available.has(n));
294
+ if (missing.length > 0) {
295
+ console.error(`vesk: runtime names not exported — ${missing.join(', ')}; falling back to full runtime`);
296
+ return buildRuntimeCode(runtimeDir);
297
+ }
298
+ const entry = join(runtimeDir, `.runtime-tree-entry-${runtimeEntryId++}.mjs`);
299
+ try {
300
+ writeFileSync(entry, `export { ${unique.join(', ')} } from './index-client.js';\n`);
301
+ const result = await build({
302
+ entryPoints: [entry],
303
+ bundle: true,
304
+ format: 'iife',
305
+ globalName: '__veskRuntime',
306
+ platform: 'browser',
307
+ target: ['es2022'],
308
+ treeShaking: true,
309
+ minify: true,
310
+ write: false,
311
+ logLevel: 'silent',
312
+ });
313
+ const bundle = result.outputFiles[0].text;
314
+ return `${bundle}\nconst { ${unique.join(', ')} } = __veskRuntime;\nexport { ${unique.join(', ')} };\n`;
315
+ }
316
+ catch (e) {
317
+ console.error('vesk: runtime tree-shake failed, falling back to full runtime:', e.message);
318
+ return buildRuntimeCode(runtimeDir);
319
+ }
320
+ finally {
321
+ try {
322
+ unlinkSync(entry);
323
+ }
324
+ catch { /* ignore */ }
325
+ }
326
+ }
327
+ function appendHmrGlobals(code) {
328
+ return code +
329
+ "globalThis.__vesk_hmr_eval = (code) => eval(code);\n";
330
+ }
331
+ async function buildMainBundle(routeTree, runtimeDir, codeSplit, mono, hmr, importRuntime, runtimeImportNames, routeDataCache) {
332
+ const baseRuntimeImports = ['createFileRouter', 'get', 'set', 'effect', 'track', 'destroy_block', 'getActiveComponent', 'setActiveComponent', 'NavLink', 'Link', 'reactiveProps', 'matchRoute', 'ensureChunk'];
333
+ const allRuntimeImports = runtimeImportNames && runtimeImportNames.size > 0
334
+ ? [...new Set([...baseRuntimeImports, ...runtimeImportNames])]
335
+ : baseRuntimeImports;
336
+ const runtimeGlobals = [
337
+ 'reconcile', 'createHydrateWalker', 'needsHydration', 'hydrate',
338
+ 'hydrateViewport', 'hydrateIdle', 'hydrateOnInteraction', 'collectVskMarkers',
339
+ 'matchRoute', 'ensureChunk',
340
+ ];
341
+ const usedRuntimeNames = [...new Set([...baseRuntimeImports, ...allRuntimeImports, ...runtimeGlobals])];
342
+ const runtimeCode = importRuntime ? '' : await buildTreeShakenRuntime(runtimeDir, usedRuntimeNames);
343
+ const preamble = importRuntime
344
+ ? `import { ${allRuntimeImports.join(', ')} } from '/_vesk/runtime.js';\n\n`
345
+ : runtimeCode + '\n';
346
+ const cleanupFn = 'function __cleanup(start, end) {\n\tlet n = start.nextSibling;\n\twhile (n && n !== end) {\n\t\tconst next = n.nextSibling;\n\t\tn.remove();\n\t\tn = next;\n\t}\n}\n';
347
+ const placeFn = 'function __place(start, end, nodes, fallback) {\n' +
348
+ '\tif (start.parentNode !== null) {\n' +
349
+ '\t\tconst p = start.parentNode;\n' +
350
+ '\t\tfor (let i = 0; i < nodes.length; i++) p.insertBefore(nodes[i], end);\n' +
351
+ '\t\treturn;\n' +
352
+ '\t}\n' +
353
+ '\tif (nodes.length > 0 && nodes[0].parentNode) {\n' +
354
+ '\t\tconst p = nodes[0].parentNode;\n' +
355
+ '\t\tp.insertBefore(start, nodes[0]);\n' +
356
+ '\t\tp.insertBefore(end, nodes[nodes.length - 1].nextSibling);\n' +
357
+ '\t\treturn;\n' +
358
+ '\t}\n' +
359
+ '\tfallback.appendChild(start);\n' +
360
+ '\tfallback.appendChild(end);\n' +
361
+ '\tfor (let i = 0; i < nodes.length; i++) fallback.insertBefore(nodes[i], end);\n' +
362
+ '}\n';
363
+ const updateComponentsFn = 'function __updateComponents(nodes) {\n' +
364
+ ' for (const n of nodes) {\n' +
365
+ " if (n._pageName && __components[n._pageName]) n.page = __components[n._pageName];\n" +
366
+ " if (n._layoutName && __components[n._layoutName]) n.layout = __components[n._layoutName];\n" +
367
+ " if (n._errorName && __components[n._errorName]) n.error = __components[n._errorName];\n" +
368
+ " if (n._notFoundName && __components[n._notFoundName]) n.notFound = __components[n._notFoundName];\n" +
369
+ ' if (n.children) __updateComponents(n.children);\n' +
370
+ ' }\n' +
371
+ '}\n';
372
+ const routeTreeJson = JSON.stringify(routeTree);
373
+ if (codeSplit) {
374
+ const resolveNamesFn = 'function __resolveNames(nodes) {\n' +
375
+ ' for (const n of nodes) {\n' +
376
+ " if (n.chunk) n._chunk = n.chunk;\n" +
377
+ " if (n.chunkError) n._chunkError = n.chunkError;\n" +
378
+ " if (typeof n.page === 'string') n._pageName = n.page;\n" +
379
+ " if (typeof n.layout === 'string') n._layoutName = n.layout;\n" +
380
+ " if (typeof n.error === 'string') n._errorName = n.error;\n" +
381
+ " if (typeof n.notFound === 'string') n._notFoundName = n.notFound;\n" +
382
+ ' if (n.children) __resolveNames(n.children);\n' +
383
+ ' }\n' +
384
+ '}\n';
385
+ const pendCode = 'const __pendChunks = [];\n' +
386
+ "const __currentPath = typeof window !== 'undefined' ? window.location.pathname : '/';\n" +
387
+ "if (typeof matchRoute === 'function') {\n" +
388
+ ' const __currentMatch = matchRoute(__routeTree, __currentPath);\n' +
389
+ ' if (__currentMatch) {\n' +
390
+ ' for (const n of __currentMatch.matchChain) {\n' +
391
+ " if (n._chunk && !__pendChunks.includes(n._chunk)) __pendChunks.push(n._chunk);\n" +
392
+ ' }\n' +
393
+ ' }\n' +
394
+ '}\n';
395
+ const routerOpts = buildRouterOpts({ routeDataCache });
396
+ const startRouterCode = 'const __startRouter = function() {\n' +
397
+ ' __updateComponents(__routeTree);\n' +
398
+ ` const __router = createFileRouter(__routeTree${routerOpts});\n` +
399
+ ' __router.__hydrators = __hydrators;\n' +
400
+ ' __router.__updateComponents = __updateComponents;\n' +
401
+ ' globalThis.__vesk_router = __router;\n' +
402
+ " if (typeof document !== 'undefined') __router.start();\n" +
403
+ '};\n' +
404
+ "if (__pendChunks.length > 0 && typeof ensureChunk === 'function') {\n" +
405
+ " Promise.all(__pendChunks.map(u => ensureChunk(u).catch(() => undefined))).then(__startRouter);\n" +
406
+ '} else {\n' +
407
+ ' __startRouter();\n' +
408
+ '}\n';
409
+ // Chunks execute as classic scripts, so the bootstrap's chunk loader
410
+ // and route matcher must exist on globalThis before any chunk loads.
411
+ // Runtime names are only emitted when a chunk's compiled code imports
412
+ // them — otherwise an app without (say) keyed maps would reference an
413
+ // unimported `reconcile` and kill the whole module.
414
+ const globalNames = [
415
+ 'reactiveProps', 'getActiveComponent', 'setActiveComponent', 'track',
416
+ 'set', 'get', 'effect', 'destroy_block', 'reconcile', 'NavLink', 'Link',
417
+ 'createHydrateWalker', 'needsHydration', 'hydrate', 'hydrateViewport',
418
+ 'hydrateIdle', 'hydrateOnInteraction', 'collectVskMarkers',
419
+ 'matchRoute', 'ensureChunk',
420
+ ];
421
+ const importedSet = new Set(allRuntimeImports);
422
+ const runtimeGlobals = globalNames
423
+ .filter(n => importedSet.has(n))
424
+ .map(n => `globalThis.${n} = ${n};\n`)
425
+ .join('') +
426
+ 'globalThis.__runtime_comps = __runtime_comps;\n' +
427
+ 'globalThis.__cleanup = __cleanup;\n' +
428
+ 'globalThis.__place = __place;\n\n';
429
+ const extraGlobals = [...(runtimeImportNames || [])]
430
+ .filter(n => n && n !== 'default')
431
+ .map(n => `globalThis.${n} = ${n};\n`)
432
+ .join('');
433
+ const code = preamble +
434
+ 'const __components = globalThis.__components || (globalThis.__components = {});\n' +
435
+ 'const __hydrators = globalThis.__hydrators || (globalThis.__hydrators = {});\n' +
436
+ 'const __runtime_comps = __components;\n\n' +
437
+ runtimeGlobals + extraGlobals +
438
+ cleanupFn +
439
+ placeFn +
440
+ 'globalThis.__components = __components;\n' +
441
+ resolveNamesFn +
442
+ updateComponentsFn +
443
+ 'const __routeTree = ' + routeTreeJson + ';\n' +
444
+ '__resolveNames(__routeTree);\n' +
445
+ pendCode +
446
+ startRouterCode;
447
+ return hmr ? appendHmrGlobals(code) : code;
448
+ }
449
+ const componentLines = mono?.componentLines || [];
450
+ const hydratorLines = mono?.hydratorLines || [];
451
+ const aliasLines = mono?.aliasLines || [];
452
+ const hydratorAliasLines = mono?.hydratorAliasLines || [];
453
+ const aliasCode = aliasLines.length > 0 ? aliasLines.join('\n') + '\n' : '';
454
+ const hydratorAliasCode = hydratorAliasLines.length > 0 ? hydratorAliasLines.join('\n') + '\n' : '';
455
+ const routerOpts = buildRouterOpts({ routeDataCache });
456
+ const code = preamble +
457
+ 'const __components = {};\n' +
458
+ 'const __hydrators = {};\n' +
459
+ 'const __runtime_comps = __components;\n\n' +
460
+ componentLines.join('\n\n') + '\n' +
461
+ aliasCode +
462
+ hydratorLines.join('\n\n') + '\n' +
463
+ hydratorAliasCode +
464
+ cleanupFn +
465
+ placeFn +
466
+ 'globalThis.__components = __components;\n' +
467
+ 'function __resolveNames(nodes) {\n' +
468
+ ' for (const n of nodes) {\n' +
469
+ " if (typeof n.page === 'string') {\n" +
470
+ ' n._pageName = n.page;\n' +
471
+ ' n.page = __components[n.page];\n' +
472
+ ' }\n' +
473
+ " if (typeof n.layout === 'string') {\n" +
474
+ ' n._layoutName = n.layout;\n' +
475
+ ' n.layout = __components[n.layout];\n' +
476
+ ' }\n' +
477
+ " if (typeof n.error === 'string') n.error = __components[n.error];\n" +
478
+ " if (typeof n.notFound === 'string') n.notFound = __components[n.notFound];\n" +
479
+ ' if (n.children) __resolveNames(n.children);\n' +
480
+ ' }\n' +
481
+ '}\n' +
482
+ updateComponentsFn +
483
+ 'const __routeTree = ' + routeTreeJson + ';\n' +
484
+ '__resolveNames(__routeTree);\n' +
485
+ `const __router = createFileRouter(__routeTree${routerOpts});\n` +
486
+ 'globalThis.__vesk_router = __router;\n' +
487
+ '__router.__hydrators = __hydrators;\n' +
488
+ '__router.__updateComponents = __updateComponents;\n' +
489
+ "if (typeof document !== 'undefined') __router.start();\n";
490
+ return hmr ? appendHmrGlobals(code) : code;
491
+ }
@@ -0,0 +1,4 @@
1
+ import { type Server } from 'node:http';
2
+ import type { DevServerOptions } from '@vesk/adapter/src/types';
3
+ export declare function startDevServer(appDir: string, options?: DevServerOptions): Promise<Server | void>;
4
+ //# sourceMappingURL=dev-server.d.ts.map
@@ -0,0 +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;AAMjG,OAAO,KAAK,EAAa,gBAAgB,EAAY,MAAM,yBAAyB,CAAC;AAuDrF,wBAAsB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAiTvG"}