@vesk/adapter 0.2.77 → 0.2.78

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"ssr-function.d.ts","sourceRoot":"","sources":["../src/ssr-function.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,SAAS,EAAkB,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAE7F;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAQlG;AAED,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAEjF;AAED,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAEpF;AAED;;;;;;;GAOG;AACH,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAQvG;AAgED;;;2EAG2E;AAC3E,wBAAgB,qBAAqB,IAAI,MAAM,CA4C9C;AAED,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,CA+hBtD"}
1
+ {"version":3,"file":"ssr-function.d.ts","sourceRoot":"","sources":["../src/ssr-function.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,SAAS,EAAkB,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAE7F;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAQlG;AAED,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAEjF;AAED,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAEpF;AAED;;;;;;;GAOG;AACH,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAQvG;AAgED;;;2EAG2E;AAC3E,wBAAgB,qBAAqB,IAAI,MAAM,CA4C9C;AAED,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,CAiftD"}
@@ -1,4 +1,4 @@
1
- import { readFileSync, existsSync, mkdirSync, writeFileSync } from 'node:fs';
1
+ import { readFileSync, existsSync } from 'node:fs';
2
2
  import { resolve, relative, join } from 'node:path';
3
3
  import { resolveComponentName, precompileFile } from '@vesk/compiler/src/server-codegen';
4
4
  import { resolveCssUrls, hasBuiltGlobalCss } from '@vesk/adapter/src/css';
@@ -163,39 +163,6 @@ export function generateSsrFunction(routeNode, appDir, outDir, componentMap, opt
163
163
  const middlewareCode = options?.middlewareCode || null;
164
164
  const headExtra = options?.headExtra || null;
165
165
  const pagePath = resolve(appDir, routeNode.sourceDir, 'page.vsk');
166
- // Precompiled plans are written to static files and fetched at render time
167
- // instead of being embedded inline. Embedding every page/layout/error plan as
168
- // inline JSON makes each SSR function module large enough to OOM on memory-
169
- // constrained build containers (e.g. Vercel's 2048 MB serverless limit).
170
- const plansDir = resolve(outDir, 'static', 'ssr-plans');
171
- mkdirSync(plansDir, { recursive: true });
172
- function writePlan(planKey, planJSON) {
173
- const fileName = `plan-${planKey}.mjs`;
174
- const planFile = resolve(plansDir, fileName);
175
- writeFileSync(planFile, `export const plan = ${planJSON};\n`, 'utf-8');
176
- // Return a relative path from the SSR function directory so dynamic
177
- // import() inside the generated function resolves to the plan module.
178
- return relative(resolve(outDir, 'server', 'functions'), planFile);
179
- }
180
- /** Generates a lazy getter that imports a precompiled plan module and compiles
181
- * it with hydratePrecompile on first use, caching the result. Import failures
182
- * degrade to null (renderPage falls back to compiling from source).
183
- * The IIFE form is a single expression so it can be placed anywhere — inside
184
- * array literals, object literals, or at module scope — without syntax errors.
185
- */
186
- function planGetterCode(varName, planUrl) {
187
- return `const ${varName} = (() => {
188
- let cache = null;
189
- return async () => {
190
- if (cache) return cache;
191
- try {
192
- const mod = await import(${JSON.stringify(planUrl)});
193
- cache = hydratePrecompile(mod.plan);
194
- } catch { cache = null; }
195
- return cache;
196
- };
197
- })();`;
198
- }
199
166
  const parts = routeNode.fullPath.split('/').filter(Boolean);
200
167
  const name = routeName(parts);
201
168
  const funcDir = resolve(outDir, 'server', 'functions');
@@ -213,15 +180,15 @@ export function generateSsrFunction(routeNode, appDir, outDir, componentMap, opt
213
180
  ...(routeNode.layout ? [{ sourceDir: routeNode.sourceDir, layoutCompName: routeNode.layout }] : []),
214
181
  ];
215
182
  const layoutDecls = [];
216
- for (let li = 0; li < layoutStack.length; li++) {
217
- const entry = layoutStack[li];
183
+ for (const entry of layoutStack) {
218
184
  const entryPath = resolve(appDir, entry.sourceDir, 'layout.vsk');
219
185
  const entrySrc = readFileSync(entryPath, 'utf-8');
220
186
  const entryComp = extractCompName(entrySrc) || 'Layout';
221
187
  const plan = precompilePlan(entryPath);
222
188
  layoutDecls.push({
223
189
  comp: JSON.stringify(entryComp),
224
- planUrl: writePlan('layout-' + name + '-' + li, plan),
190
+ plan,
191
+ compiled: hydrateInvoke(plan),
225
192
  });
226
193
  }
227
194
  const pagePlan = precompilePlan(pagePath);
@@ -230,8 +197,8 @@ export function generateSsrFunction(routeNode, appDir, outDir, componentMap, opt
230
197
  const errorSrc = errorPath ? readFileSync(errorPath, 'utf-8') : null;
231
198
  const errorComp = errorPath ? (extractCompName(errorSrc) || 'Error') : null;
232
199
  const errorVars = errorPath
233
- ? `const _errorComp = ${JSON.stringify(errorComp)};\n${planGetterCode('_errorCompiled', writePlan('error-' + name, precompilePlan(errorPath)))}\n`
234
- : 'const _errorComp = null;\nasync function _errorCompiled() { return null; }\n';
200
+ ? `const _errorComp = ${JSON.stringify(errorComp)};\nconst _errorCompiled = ${hydrateInvoke(precompilePlan(errorPath))};\n`
201
+ : 'const _errorComp = null;\nconst _errorCompiled = null;\n';
235
202
  // Not-found used to have no server-side resolution at all: a NotFoundError was
236
203
  // re-thrown out of the function and the prod server answered with the ROOT
237
204
  // not-found.vsk. A nested `app/admin/not-found.vsk` therefore did nothing on a
@@ -242,23 +209,19 @@ export function generateSsrFunction(routeNode, appDir, outDir, componentMap, opt
242
209
  const notFoundSrc = notFoundPath ? readFileSync(notFoundPath, 'utf-8') : null;
243
210
  const notFoundComp = notFoundPath ? (extractCompName(notFoundSrc) || 'NotFound') : null;
244
211
  const notFoundVars = notFoundPath
245
- ? `const _notFoundComp = ${JSON.stringify(notFoundComp)};\n${planGetterCode('_notFoundCompiled', writePlan('notfound-' + name, precompilePlan(notFoundPath)))}\n`
246
- : 'const _notFoundComp = null;\nasync function _notFoundCompiled() { return null; }\n';
247
- const pagePlanUrl = writePlan('page-' + name, pagePlan);
212
+ ? `const _notFoundComp = ${JSON.stringify(notFoundComp)};\nconst _notFoundCompiled = ${hydrateInvoke(precompilePlan(notFoundPath))};\n`
213
+ : 'const _notFoundComp = null;\nconst _notFoundCompiled = null;\n';
248
214
  let src = '';
249
215
  if (layoutDecls.length > 0) {
250
- const pageGetter = planGetterCode('_pageCompiled', pagePlanUrl);
251
- const layoutGetters = layoutDecls.map((d, i) => planGetterCode('_layoutCompiled_' + i, d.planUrl));
252
216
  src = `const _pageComp = ${JSON.stringify(pageComp)};\n`;
253
- src += pageGetter + '\n';
254
- src += layoutGetters.join('\n') + '\n';
217
+ src += `const _pageCompiled = (() => { try { return hydratePrecompile(${pagePlan}); } catch { return null; } })();\n`;
255
218
  src += `const _layoutCompList = [${layoutDecls.map((d) => d.comp).join(', ')}];\n`;
256
- src += `const _layoutCompiledList = [${layoutDecls.map((_, i) => '_layoutCompiled_' + i).join(', ')}];\n`;
219
+ src += `const _layoutCompiledList = [\n${layoutDecls.map((d) => ' ' + d.compiled + ',').join('\n')}\n];\n`;
257
220
  src += errorVars + notFoundVars;
258
221
  }
259
222
  else {
260
223
  src = `const _comp = ${JSON.stringify(pageComp)};\n`;
261
- src += planGetterCode('_compiled', pagePlanUrl) + '\n';
224
+ src += `const _compiled = (() => { try { return hydratePrecompile(${pagePlan}); } catch { return null; } })();\n`;
262
225
  src += errorVars + notFoundVars;
263
226
  }
264
227
  const urlParts = routeNode.fullPath.split('/').filter(Boolean);
@@ -272,13 +235,9 @@ export function generateSsrFunction(routeNode, appDir, outDir, componentMap, opt
272
235
  let registryCode = '';
273
236
  const compRegEntries = [];
274
237
  const compMap = componentMap || new Map();
275
- let compCounter = 0;
276
238
  for (const [compName, compPath] of compMap) {
277
239
  const plan = precompilePlan(compPath);
278
- const compPlanUrl = writePlan('comp-' + name + '-' + compCounter, plan);
279
- const compGetter = '_compiled_' + compCounter;
280
- compCounter++;
281
- compRegEntries.push(` (() => {\n${planGetterCode(compGetter, compPlanUrl)}\n __componentRegistry.set(${JSON.stringify(compName)}, async (props, __registry, __vesk) => {\n const result = await renderPage('', ${JSON.stringify(compName)}, props, __registry, { hydrate: true, cached: await ${compGetter}() });\n return result.body;\n });\n })();`);
240
+ compRegEntries.push(` (() => {\n const _compiled = (() => { try { return hydratePrecompile(${plan}); } catch { return null; } })();\n __componentRegistry.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 })();`);
282
241
  }
283
242
  if (compRegEntries.length > 0) {
284
243
  registryCode = 'const __componentRegistry = new Map();\n{\n' + compRegEntries.join('\n') + '\n}\n';
@@ -292,7 +251,7 @@ export function generateSsrFunction(routeNode, appDir, outDir, componentMap, opt
292
251
  'async function __renderErrorBody(props) {',
293
252
  ' if (!_errorComp) throw props.error || new Error("Internal Server Error");',
294
253
  ' try {',
295
- ' const result = await renderPage(\'\', _errorComp, props, __componentRegistry, { hydrate: true, cached: await _errorCompiled() });',
254
+ ' const result = await renderPage(\'\', _errorComp, props, __componentRegistry, { hydrate: true, cached: _errorCompiled });',
296
255
  ' return result.body;',
297
256
  ' } catch {',
298
257
  ` return ${JSON.stringify(renderDefaultErrorFragment())};`,
@@ -305,7 +264,7 @@ export function generateSsrFunction(routeNode, appDir, outDir, componentMap, opt
305
264
  'async function __renderNotFoundBody(props) {',
306
265
  ' if (!_notFoundComp) return null;',
307
266
  ' try {',
308
- ' const result = await renderPage(\'\', _notFoundComp, props, __componentRegistry, { hydrate: true, cached: await _notFoundCompiled() });',
267
+ ' const result = await renderPage(\'\', _notFoundComp, props, __componentRegistry, { hydrate: true, cached: _notFoundCompiled });',
309
268
  ' return result.body;',
310
269
  ' } catch {',
311
270
  ' return null;',
@@ -319,11 +278,11 @@ export function generateSsrFunction(routeNode, appDir, outDir, componentMap, opt
319
278
  ' let _b = body;',
320
279
  ' let _h = head || "";',
321
280
  ' for (let _i = _layoutCompList.length - 1; _i > 0; _i--) {',
322
- " const _inner = await renderPage('', _layoutCompList[_i], { params, children: _b }, __componentRegistry, { hydrate: true, cached: await _layoutCompiledList[_i]() });",
281
+ " const _inner = await renderPage('', _layoutCompList[_i], { params, children: _b }, __componentRegistry, { hydrate: true, cached: _layoutCompiledList[_i] });",
323
282
  ' _b = _inner.body;',
324
283
  ' if (_inner.head) _h = _inner.head + _h;',
325
284
  ' }',
326
- " return renderFullPage('', _layoutCompList[0], { params, children: _b }, __componentRegistry, { hydrate: true, cached: await _layoutCompiledList[0]()" + bakedOptions + clientScriptOption + dataScriptOption + ", pageHead: _h });",
285
+ " return renderFullPage('', _layoutCompList[0], { params, children: _b }, __componentRegistry, { hydrate: true, cached: _layoutCompiledList[0]" + bakedOptions + clientScriptOption + dataScriptOption + ", pageHead: _h });",
327
286
  '}',
328
287
  '',
329
288
  'async function __renderHtml(params, requestUrl) {',
@@ -334,7 +293,7 @@ export function generateSsrFunction(routeNode, appDir, outDir, componentMap, opt
334
293
  ' let notFound = false;',
335
294
  " const __expose = process.env.NODE_ENV !== 'production';",
336
295
  ' try {',
337
- ' page = await renderPage(\'\', _pageComp, { params }, __componentRegistry, { hydrate: true, cached: await _pageCompiled() });',
296
+ ' page = await renderPage(\'\', _pageComp, { params }, __componentRegistry, { hydrate: true, cached: _pageCompiled });',
338
297
  ' } catch (err) {',
339
298
  " if (err && err.name === 'Redirect') throw err;",
340
299
  " if (err && err.name === 'NotFoundError') {",
@@ -372,7 +331,7 @@ export function generateSsrFunction(routeNode, appDir, outDir, componentMap, opt
372
331
  " const message = err && typeof err === 'object' && 'message' in err ? String(err.message) : String(err);",
373
332
  " const stack = err && typeof err === 'object' && 'stack' in err ? String(err.stack) : '';",
374
333
  " const props = { params, statusCode: 500, error: __expose ? message : 'Internal Server Error', stack: __expose ? stack : '', url: requestUrl || '' };",
375
- " return renderFullPage('', _errorComp, props, __componentRegistry, { hydrate: true, cached: await _errorCompiled()" + bakedOptions + clientScriptOption + dataScriptOption + " });",
334
+ " return renderFullPage('', _errorComp, props, __componentRegistry, { hydrate: true, cached: _errorCompiled" + bakedOptions + clientScriptOption + dataScriptOption + " });",
376
335
  '}',
377
336
  '',
378
337
  'async function __renderHtml(params, requestUrl) {',
@@ -387,7 +346,7 @@ export function generateSsrFunction(routeNode, appDir, outDir, componentMap, opt
387
346
  // though it runs outside the ALS scope.
388
347
  " const __streamToken = globalThis.__vsk_ssr_token || '';",
389
348
  ' try {',
390
- " stream = renderPageStream('', _comp, { params }, __componentRegistry, { hydrate: true, cached: await _compiled()" + bakedOptions + clientScriptOption + dataScriptOption + ' });',
349
+ " stream = renderPageStream('', _comp, { params }, __componentRegistry, { hydrate: true, cached: _compiled" + bakedOptions + clientScriptOption + dataScriptOption + ' });',
391
350
  ' } catch (err) {',
392
351
  ' if (err && (err.name === \'NotFoundError\' || err.name === \'Redirect\')) throw err;',
393
352
  ' const html = await __renderErrorFullPage(params, requestUrl, err);',
@@ -474,7 +433,7 @@ export function generateSsrFunction(routeNode, appDir, outDir, componentMap, opt
474
433
  ' try {',
475
434
  ' let dataPage;',
476
435
  ' try {',
477
- " dataPage = await renderPage('', _pageComp, { params }, __componentRegistry, { hydrate: true, cached: await _pageCompiled() });",
436
+ " dataPage = await renderPage('', _pageComp, { params }, __componentRegistry, { hydrate: true, cached: _pageCompiled });",
478
437
  ' } catch (err) {',
479
438
  " if (err && (err.name === 'NotFoundError' || err.name === 'Redirect')) throw err;",
480
439
  ' const message = err && typeof err === \'object\' && \'message\' in err ? String(err.message) : String(err);',
@@ -482,7 +441,7 @@ export function generateSsrFunction(routeNode, appDir, outDir, componentMap, opt
482
441
  ' }',
483
442
  ' let _dataHead = dataPage.head || \'\';',
484
443
  ' for (let _i = _layoutCompList.length - 1; _i >= 0; _i--) {',
485
- " const _dl = await renderPage('', _layoutCompList[_i], { params, children: '' }, __componentRegistry, { hydrate: true, cached: await _layoutCompiledList[_i]() });",
444
+ " const _dl = await renderPage('', _layoutCompList[_i], { params, children: '' }, __componentRegistry, { hydrate: true, cached: _layoutCompiledList[_i] });",
486
445
  ' _dataHead = (_dl.head || \'\') + _dataHead;',
487
446
  ' }',
488
447
  " return new Response(JSON.stringify({ path: url.pathname, params, props: dataPage.props || { params }, head: _dataHead }), {",
@@ -501,7 +460,7 @@ export function generateSsrFunction(routeNode, appDir, outDir, componentMap, opt
501
460
  ' try {',
502
461
  ' let dataPage;',
503
462
  ' try {',
504
- " dataPage = await renderPage('', _comp, { params }, __componentRegistry, { hydrate: true, cached: await _compiled() });",
463
+ " dataPage = await renderPage('', _comp, { params }, __componentRegistry, { hydrate: true, cached: _compiled });",
505
464
  ' } catch (err) {',
506
465
  " if (err && (err.name === 'NotFoundError' || err.name === 'Redirect')) throw err;",
507
466
  ' const message = err && typeof err === \'object\' && \'message\' in err ? String(err.message) : String(err);',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vesk/adapter",
3
- "version": "0.2.77",
3
+ "version": "0.2.78",
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.77",
27
- "@vesk/runtime": "^0.2.77",
28
- "@vesk/types": "^0.2.77"
26
+ "@vesk/compiler": "^0.2.78",
27
+ "@vesk/runtime": "^0.2.78",
28
+ "@vesk/types": "^0.2.78"
29
29
  },
30
30
  "devDependencies": {
31
31
  "@types/ws": "^8.18.1",