@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.
- package/dist/ssr-function.d.ts.map +1 -1
- package/dist/ssr-function.js +22 -63
- package/package.json +4 -4
|
@@ -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,
|
|
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"}
|
package/dist/ssr-function.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { readFileSync, existsSync
|
|
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 (
|
|
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
|
-
|
|
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)};\
|
|
234
|
-
: 'const _errorComp = null;\
|
|
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)};\
|
|
246
|
-
: 'const _notFoundComp = null;\
|
|
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 +=
|
|
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((
|
|
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 +=
|
|
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
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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.
|
|
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.
|
|
27
|
-
"@vesk/runtime": "^0.2.
|
|
28
|
-
"@vesk/types": "^0.2.
|
|
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",
|