@vesk/adapter 0.2.50-canary.3 → 0.2.50-canary.5
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/dev-server.d.ts.map +1 -1
- package/dist/dev-server.js +5 -0
- package/dist/error-report.d.ts +43 -0
- package/dist/error-report.d.ts.map +1 -0
- package/dist/error-report.js +52 -0
- package/dist/events.d.ts +17 -0
- package/dist/events.d.ts.map +1 -1
- package/dist/events.js +23 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -1
- package/dist/prod-server.d.ts.map +1 -1
- package/dist/prod-server.js +15 -0
- package/package.json +4 -4
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;
|
|
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;AASjG,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,OAAO,CAAC;AAK7C,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,CAwqBvG"}
|
package/dist/dev-server.js
CHANGED
|
@@ -6,6 +6,7 @@ import { stripCodeTypes } from '@vesk/compiler/src/strip-ts';
|
|
|
6
6
|
import { DEFAULT_MAX_BODY_BYTES, safeJsonForScript } from '@vesk/compiler/src/server-codegen';
|
|
7
7
|
import { build } from '@vesk/adapter/src/index';
|
|
8
8
|
import { cacheControlFor } from '@vesk/adapter/src/asset-hash';
|
|
9
|
+
import { reportServerError, registerErrorHooks } from '@vesk/adapter/src/error-report';
|
|
9
10
|
import { buildErrorPayload, createHmrServer } from './hmr';
|
|
10
11
|
import * as hmrApi from './hmr';
|
|
11
12
|
import { createDevApiRouter } from './dev-api';
|
|
@@ -206,6 +207,9 @@ export async function startDevServer(appDir, options) {
|
|
|
206
207
|
const devDir = resolve(appDir, '..', '.vesk', 'dev');
|
|
207
208
|
const publicDir = options?.publicDir || resolve(appDir, '..', 'public');
|
|
208
209
|
installMdReadHook([publicDir, resolve(devDir, 'static', 'public')]);
|
|
210
|
+
// Plugin `onError` hooks only exist here (dev): in production there are no
|
|
211
|
+
// plugin objects, and `_events.ts` is the seam that ships.
|
|
212
|
+
registerErrorHooks(options?.plugins);
|
|
209
213
|
// Dev-panel plugin list: plugin / module names declared in the dev server's own config.
|
|
210
214
|
const configPluginNames = (options?.plugins || []).map((p) => {
|
|
211
215
|
if (typeof p === 'string')
|
|
@@ -700,6 +704,7 @@ export async function startDevServer(appDir, options) {
|
|
|
700
704
|
}
|
|
701
705
|
catch (e) {
|
|
702
706
|
console.error('[vesk dev] SSR render failed:', e instanceof Error ? (e.stack || e.message) : String(e));
|
|
707
|
+
await reportServerError(e, { url: url.href, target: 'dev', status: 500 });
|
|
703
708
|
res.writeHead(500, { 'Content-Type': 'text/html' });
|
|
704
709
|
res.end(renderSsrErrorPage(e, url.pathname));
|
|
705
710
|
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The production error-reporting seam.
|
|
3
|
+
*
|
|
4
|
+
* Production never leaks a stack trace to the client (that is the right
|
|
5
|
+
* default), which used to mean an adopter had two bad options: show the stack,
|
|
6
|
+
* or replace the adapter's error handling. This is the supported middle: a
|
|
7
|
+
* plugin's `onError` hook receives the error, the route and the build id.
|
|
8
|
+
*
|
|
9
|
+
* Design rules:
|
|
10
|
+
* - a hook that throws is caught and logged, never turned into a second
|
|
11
|
+
* failure (a reporting outage must not take down the page that was already
|
|
12
|
+
* failing);
|
|
13
|
+
* - one failing hook does not stop the others;
|
|
14
|
+
* - nothing is reported twice for one request.
|
|
15
|
+
*/
|
|
16
|
+
import type { ServerErrorContext, VeskPlugin } from '@vesk/types';
|
|
17
|
+
export interface BuildConfigLike {
|
|
18
|
+
version?: number;
|
|
19
|
+
buildId?: string;
|
|
20
|
+
veskVersion?: string;
|
|
21
|
+
[key: string]: unknown;
|
|
22
|
+
}
|
|
23
|
+
export declare function registerErrorReporter(fn: (err: unknown, ctx: ServerErrorContext) => void | Promise<void>): void;
|
|
24
|
+
export declare function clearErrorReporters(): void;
|
|
25
|
+
export declare function errorReporterCount(): number;
|
|
26
|
+
/** Register every plugin that declares `onError`. */
|
|
27
|
+
export declare function registerErrorHooks(plugins: VeskPlugin[] | null | undefined): void;
|
|
28
|
+
export interface ReportOptions {
|
|
29
|
+
url?: string;
|
|
30
|
+
routePath?: string;
|
|
31
|
+
target: ServerErrorContext['target'];
|
|
32
|
+
status?: number;
|
|
33
|
+
durationMs?: number;
|
|
34
|
+
buildConfig?: BuildConfigLike | null;
|
|
35
|
+
/** Suppress a duplicate report for the same error object. */
|
|
36
|
+
dedupe?: boolean;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Report a production failure. Never throws: a failure to report is logged and
|
|
40
|
+
* swallowed, because the caller is already handling a worse problem.
|
|
41
|
+
*/
|
|
42
|
+
export declare function reportServerError(err: unknown, options: ReportOptions): Promise<void>;
|
|
43
|
+
//# sourceMappingURL=error-report.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error-report.d.ts","sourceRoot":"","sources":["../src/error-report.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,KAAK,EAAE,kBAAkB,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAElE,MAAM,WAAW,eAAe;IAC9B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAMD,wBAAgB,qBAAqB,CAAC,EAAE,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,kBAAkB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAE/G;AAED,wBAAgB,mBAAmB,IAAI,IAAI,CAE1C;AAED,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C;AAED,qDAAqD;AACrD,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,IAAI,GAAG,SAAS,GAAG,IAAI,CAIjF;AAED,MAAM,WAAW,aAAa;IAC5B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,kBAAkB,CAAC,QAAQ,CAAC,CAAC;IACrC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,eAAe,GAAG,IAAI,CAAC;IACrC,6DAA6D;IAC7D,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;;GAGG;AACH,wBAAsB,iBAAiB,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAyB3F"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/** Process-wide hook list; the config's plugins are registered at boot. */
|
|
2
|
+
const hooks = [];
|
|
3
|
+
const reported = new WeakSet();
|
|
4
|
+
export function registerErrorReporter(fn) {
|
|
5
|
+
if (typeof fn === 'function')
|
|
6
|
+
hooks.push(fn);
|
|
7
|
+
}
|
|
8
|
+
export function clearErrorReporters() {
|
|
9
|
+
hooks.length = 0;
|
|
10
|
+
}
|
|
11
|
+
export function errorReporterCount() {
|
|
12
|
+
return hooks.length;
|
|
13
|
+
}
|
|
14
|
+
/** Register every plugin that declares `onError`. */
|
|
15
|
+
export function registerErrorHooks(plugins) {
|
|
16
|
+
for (const plugin of plugins || []) {
|
|
17
|
+
if (plugin && typeof plugin.onError === 'function')
|
|
18
|
+
registerErrorReporter(plugin.onError);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Report a production failure. Never throws: a failure to report is logged and
|
|
23
|
+
* swallowed, because the caller is already handling a worse problem.
|
|
24
|
+
*/
|
|
25
|
+
export async function reportServerError(err, options) {
|
|
26
|
+
if (options.dedupe !== false && err && typeof err === 'object') {
|
|
27
|
+
if (reported.has(err))
|
|
28
|
+
return;
|
|
29
|
+
reported.add(err);
|
|
30
|
+
}
|
|
31
|
+
const cfg = options.buildConfig || null;
|
|
32
|
+
const ctx = {
|
|
33
|
+
url: options.url,
|
|
34
|
+
routePath: options.routePath,
|
|
35
|
+
target: options.target,
|
|
36
|
+
status: options.status ?? 500,
|
|
37
|
+
durationMs: options.durationMs,
|
|
38
|
+
version: typeof cfg?.veskVersion === 'string' ? cfg.veskVersion : undefined,
|
|
39
|
+
buildId: typeof cfg?.buildId === 'string' ? cfg.buildId : undefined,
|
|
40
|
+
errorName: err instanceof Error ? err.name : typeof err,
|
|
41
|
+
message: err instanceof Error ? err.message : String(err),
|
|
42
|
+
stack: err instanceof Error ? err.stack : undefined,
|
|
43
|
+
};
|
|
44
|
+
for (const hook of hooks) {
|
|
45
|
+
try {
|
|
46
|
+
await hook(err, ctx);
|
|
47
|
+
}
|
|
48
|
+
catch (e) {
|
|
49
|
+
console.error('vesk: an onError hook threw and was ignored:', e?.message ?? e);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
package/dist/events.d.ts
CHANGED
|
@@ -1,3 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wrapper module bundled into `server/events.js`. It lifts the user's
|
|
3
|
+
* `_events.ts` exports into `executeStart` / `executeRequest` / `executeStop`
|
|
4
|
+
* entry points with a context that routes `set`/`get` into the process-wide
|
|
5
|
+
* server context (`globalThis.__vesk_server_ctx`).
|
|
6
|
+
*
|
|
7
|
+
* The `__vesk_events_started` guard is global (not module-local) so lazy edge
|
|
8
|
+
* isolates and the Node prod server share one lifetime; `onStop` clears it so
|
|
9
|
+
* dev HMR reloads can boot a fresh module.
|
|
10
|
+
*/
|
|
11
|
+
export declare function buildEventsEntry(sourcePath: string): string;
|
|
12
|
+
/**
|
|
13
|
+
* Report a production failure to `_events.ts`'s `onError`, if it exports one.
|
|
14
|
+
* Never throws: a reporting outage must not add a second failure to a request
|
|
15
|
+
* that already failed.
|
|
16
|
+
*/
|
|
17
|
+
export declare function executeError(err: unknown, base: Record<string, unknown>, mod: unknown): Promise<void>;
|
|
1
18
|
/**
|
|
2
19
|
* Compile the app's `_events.ts` (if present) into a self-contained
|
|
3
20
|
* `server/events.js` next to the server runtime. Returns true when an events
|
package/dist/events.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../src/events.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../src/events.ts"],"names":[],"mappings":"AAOA;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAuD3D;AAED;;;;GAIG;AACH,wBAAsB,YAAY,CAChC,GAAG,EAAE,OAAO,EACZ,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,GAAG,EAAE,OAAO,GACX,OAAO,CAAC,IAAI,CAAC,CAQf;AAED;;;;;;GAMG;AACH,wBAAsB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAiCpF"}
|
package/dist/events.js
CHANGED
|
@@ -13,14 +13,17 @@ let buildId = 0;
|
|
|
13
13
|
* isolates and the Node prod server share one lifetime; `onStop` clears it so
|
|
14
14
|
* dev HMR reloads can boot a fresh module.
|
|
15
15
|
*/
|
|
16
|
-
function
|
|
16
|
+
export function buildEventsEntry(sourcePath) {
|
|
17
17
|
return [
|
|
18
18
|
`import * as __events from ${JSON.stringify(sourcePath)};`,
|
|
19
19
|
'',
|
|
20
20
|
'const __store = () => (globalThis.__vesk_server_ctx ||= {});',
|
|
21
21
|
'',
|
|
22
22
|
'const __handlers = {};',
|
|
23
|
-
|
|
23
|
+
// `onError` joins the server events: production has no plugin objects, so
|
|
24
|
+
// this is the seam an error reporter actually uses there (plugins carry
|
|
25
|
+
// their own `onError` in dev, where plugin objects do exist).
|
|
26
|
+
"for (const __name of ['onStart', 'onRequest', 'onStop', 'onError']) {",
|
|
24
27
|
' const __fn = __events[__name];',
|
|
25
28
|
" if (typeof __fn === 'function') __handlers[__name] = __fn;",
|
|
26
29
|
'}',
|
|
@@ -61,9 +64,26 @@ function buildEntry(sourcePath) {
|
|
|
61
64
|
'export const onStart = __handlers.onStart;',
|
|
62
65
|
'export const onRequest = __handlers.onRequest;',
|
|
63
66
|
'export const onStop = __handlers.onStop;',
|
|
67
|
+
'export const onError = __handlers.onError;',
|
|
64
68
|
'',
|
|
65
69
|
].join('\n');
|
|
66
70
|
}
|
|
71
|
+
/**
|
|
72
|
+
* Report a production failure to `_events.ts`'s `onError`, if it exports one.
|
|
73
|
+
* Never throws: a reporting outage must not add a second failure to a request
|
|
74
|
+
* that already failed.
|
|
75
|
+
*/
|
|
76
|
+
export async function executeError(err, base, mod) {
|
|
77
|
+
const fn = mod?.onError;
|
|
78
|
+
if (typeof fn !== 'function')
|
|
79
|
+
return;
|
|
80
|
+
try {
|
|
81
|
+
await fn(err, base);
|
|
82
|
+
}
|
|
83
|
+
catch (e) {
|
|
84
|
+
console.error('vesk: _events onError threw and was ignored:', e instanceof Error ? e.message : e);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
67
87
|
/**
|
|
68
88
|
* Compile the app's `_events.ts` (if present) into a self-contained
|
|
69
89
|
* `server/events.js` next to the server runtime. Returns true when an events
|
|
@@ -78,7 +98,7 @@ export async function compileEvents(appDir, outDir) {
|
|
|
78
98
|
const serverDir = resolve(outDir, 'server');
|
|
79
99
|
mkdirSync(serverDir, { recursive: true });
|
|
80
100
|
const entryFile = resolve(serverDir, `.events-entry-${buildId++}.mjs`);
|
|
81
|
-
writeFileSync(entryFile,
|
|
101
|
+
writeFileSync(entryFile, buildEventsEntry(sourcePath), 'utf-8');
|
|
82
102
|
try {
|
|
83
103
|
const result = await esbuild.build({
|
|
84
104
|
entryPoints: [entryFile],
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAmBA,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;AAkDD,wBAAsB,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC,CAqWpG;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
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { mkdirSync, writeFileSync, existsSync, readFileSync } from 'node:fs';
|
|
2
|
-
import { resolve, dirname, relative, basename } from 'node:path';
|
|
2
|
+
import { resolve, dirname, relative, basename, join } from 'node:path';
|
|
3
3
|
import { fileURLToPath } from 'node:url';
|
|
4
4
|
import { bundleRuntime } from '@vesk/adapter/src/runtime-bundle';
|
|
5
5
|
import { generateSsrFunction } from '@vesk/adapter/src/ssr-function';
|
|
@@ -7,6 +7,10 @@ import { resolveUserCssPath, isTailwindPlugin, resolveCssUrls, hasBuiltGlobalCss
|
|
|
7
7
|
import { collectActionIds } from '@vesk/compiler/src/actions';
|
|
8
8
|
import { generateApiFunction } from '@vesk/adapter/src/api-function';
|
|
9
9
|
import { describeAsset } from '@vesk/adapter/src/asset-hash';
|
|
10
|
+
// The adapter's own package.json, for the version stamped into the manifest.
|
|
11
|
+
function PACKAGES_DIR_SELF() {
|
|
12
|
+
return resolve(dirname(fileURLToPath(import.meta.url)), '..');
|
|
13
|
+
}
|
|
10
14
|
import { compileMiddleware, compileMiddlewareCode } from '@vesk/adapter/src/middleware';
|
|
11
15
|
import { compileEvents } from '@vesk/adapter/src/events';
|
|
12
16
|
import { generateClientBundle } from '@vesk/adapter/src/client-bundle';
|
|
@@ -380,6 +384,10 @@ export async function build(appDir, options) {
|
|
|
380
384
|
const manifest = generateManifest(routeTree, ssrRoutes, apiRoutes, prerenderedRoutes, middlewareEnabled, actionMap, pluginHeadExtra, hasEvents);
|
|
381
385
|
// The asset map is what makes a deploy auditable: sizes, content hashes and
|
|
382
386
|
// the SRI digests a page can carry.
|
|
387
|
+
// The build id is the asset map's own fingerprint: same assets, same id.
|
|
388
|
+
const buildId = emittedAssets.map((a) => a.hash).join('-');
|
|
389
|
+
manifest.buildId = buildId.slice(0, 32);
|
|
390
|
+
manifest.veskVersion = JSON.parse(readFileSync(join(PACKAGES_DIR_SELF(), 'package.json'), 'utf-8')).version;
|
|
383
391
|
manifest.assets = {
|
|
384
392
|
hashed,
|
|
385
393
|
client: { file: clientFileName, url: clientUrl, hash: clientAsset.hash, bytes: clientAsset.bytes, integrity: clientAsset.integrity },
|
|
@@ -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;AAiDjG,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,KAAK,GAAG;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,CAIzE;AAkGD,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,CAwdxI"}
|
package/dist/prod-server.js
CHANGED
|
@@ -5,6 +5,8 @@ import { fileURLToPath } from 'node:url';
|
|
|
5
5
|
import { createRateLimiter, resolveComponentName, safeJsonForScript, getClientProtocol, DEFAULT_MAX_BODY_BYTES } from '@vesk/compiler/src/server-codegen';
|
|
6
6
|
import { securityHeaders } from '@vesk/compiler/src/server-utils';
|
|
7
7
|
import { cacheControlFor } from '@vesk/adapter/src/asset-hash';
|
|
8
|
+
import { reportServerError } from '@vesk/adapter/src/error-report';
|
|
9
|
+
import { executeError } from '@vesk/adapter/src/events';
|
|
8
10
|
import { resolveWithin, installMdReadHook } from '@vesk/adapter/src/paths';
|
|
9
11
|
import { resolveCssUrls, hasBuiltGlobalCss } from '@vesk/adapter/src/css';
|
|
10
12
|
import { loadVeskConfig } from '@vesk/adapter/src/load-config';
|
|
@@ -511,6 +513,19 @@ export async function startProdServer(outDir, options) {
|
|
|
511
513
|
return;
|
|
512
514
|
}
|
|
513
515
|
console.error('vesk ssr error:', err.message);
|
|
516
|
+
// Two seams, both best-effort: a plugin's `onError` (dev-style
|
|
517
|
+
// plugin objects don't exist here) and `_events.ts`'s, which IS
|
|
518
|
+
// baked into the production build.
|
|
519
|
+
await reportServerError(err, {
|
|
520
|
+
url: url.pathname + url.search,
|
|
521
|
+
routePath: route.path,
|
|
522
|
+
target: 'node',
|
|
523
|
+
status: 500,
|
|
524
|
+
buildConfig,
|
|
525
|
+
});
|
|
526
|
+
if (eventsMod) {
|
|
527
|
+
await executeError(err, { url: url.href, routePath: route.path, target: 'node', status: 500 }, eventsMod);
|
|
528
|
+
}
|
|
514
529
|
const errPath = resolve(appDir, 'error.vsk');
|
|
515
530
|
let errorHtml = null;
|
|
516
531
|
if (existsSync(errPath)) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vesk/adapter",
|
|
3
|
-
"version": "0.2.50-canary.
|
|
3
|
+
"version": "0.2.50-canary.5",
|
|
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.50-canary.
|
|
27
|
-
"@vesk/runtime": "^0.2.50-canary.
|
|
28
|
-
"@vesk/types": "^0.2.50-canary.
|
|
26
|
+
"@vesk/compiler": "^0.2.50-canary.5",
|
|
27
|
+
"@vesk/runtime": "^0.2.50-canary.5",
|
|
28
|
+
"@vesk/types": "^0.2.50-canary.5"
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|
|
31
31
|
"@types/ws": "^8.18.1",
|