@vesk/adapter 0.2.92 → 0.2.94
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 +4 -0
- package/dist/client-bundle.d.ts.map +1 -1
- package/dist/client-bundle.js +228 -97
- package/dist/dev-server.d.ts.map +1 -1
- package/dist/dev-server.js +29 -2
- package/dist/esbuild-fallback.d.ts.map +1 -1
- package/dist/esbuild-fallback.js +9 -6
- package/dist/platform-deploy.d.ts +28 -0
- package/dist/platform-deploy.d.ts.map +1 -1
- package/dist/platform-deploy.js +108 -23
- package/dist/platform-handler.d.ts.map +1 -1
- package/dist/platform-handler.js +53 -7
- package/dist/server-only.d.ts +9 -0
- package/dist/server-only.d.ts.map +1 -1
- package/dist/server-only.js +11 -0
- package/package.json +4 -4
package/dist/client-bundle.d.ts
CHANGED
|
@@ -132,6 +132,10 @@ export declare function buildRuntimeCode(runtimeDir: string): string;
|
|
|
132
132
|
/**
|
|
133
133
|
* Names the client runtime actually exports, so the tree-shaken bundle only
|
|
134
134
|
* emits the modules reachable from the used set.
|
|
135
|
+
*
|
|
136
|
+
* Parses index-client.js with the AST parser instead of regex so that direct
|
|
137
|
+
* declarations (export function locals() {}, export const x = 1, export class
|
|
138
|
+
* Foo {}) are captured alongside re-exports (export { X } from '...').
|
|
135
139
|
*/
|
|
136
140
|
export declare function runtimeExportNames(runtimeDir: string): Set<string>;
|
|
137
141
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client-bundle.d.ts","sourceRoot":"","sources":["../src/client-bundle.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,SAAS,EAAE,mBAAmB,EAAE,kBAAkB,EAAmF,MAAM,yBAAyB,CAAC;AAuEnL;;;;;;;;;;;;;GAaG;AACH,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CA4BhE;AAED;;;;;GAKG;AACH,UAAU,YAAY;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;IAC7B,EAAE,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACvB,YAAY,CAAC,EAAE,KAAK,CAAC;QAAE,EAAE,CAAC,EAAE;YAAE,IAAI,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC;QAAC,IAAI,CAAC,EAAE;YAAE,IAAI,CAAC,EAAE,MAAM,CAAC;YAAC,MAAM,CAAC,EAAE;gBAAE,IAAI,CAAC,EAAE,MAAM,CAAC;gBAAC,IAAI,CAAC,EAAE,MAAM,CAAA;aAAE,CAAA;SAAE,CAAA;KAAE,CAAC,CAAC;IACtH,WAAW,CAAC,EAAE;QACZ,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,MAAM,CAAC,EAAE;YAAE,IAAI,CAAC,EAAE,MAAM,CAAC;YAAC,IAAI,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC;QAC1C,YAAY,CAAC,EAAE,KAAK,CAAC;YAAE,IAAI,CAAC,EAAE;gBAAE,IAAI,CAAC,EAAE,MAAM,CAAC;gBAAC,MAAM,CAAC,EAAE;oBAAE,IAAI,CAAC,EAAE,MAAM,CAAC;oBAAC,IAAI,CAAC,EAAE,MAAM,CAAA;iBAAE,CAAA;aAAE,CAAA;SAAE,CAAC,CAAC;KAC/F,CAAC;IACF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;
|
|
1
|
+
{"version":3,"file":"client-bundle.d.ts","sourceRoot":"","sources":["../src/client-bundle.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,SAAS,EAAE,mBAAmB,EAAE,kBAAkB,EAAmF,MAAM,yBAAyB,CAAC;AAuEnL;;;;;;;;;;;;;GAaG;AACH,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CA4BhE;AAED;;;;;GAKG;AACH,UAAU,YAAY;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;IAC7B,EAAE,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACvB,YAAY,CAAC,EAAE,KAAK,CAAC;QAAE,EAAE,CAAC,EAAE;YAAE,IAAI,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC;QAAC,IAAI,CAAC,EAAE;YAAE,IAAI,CAAC,EAAE,MAAM,CAAC;YAAC,MAAM,CAAC,EAAE;gBAAE,IAAI,CAAC,EAAE,MAAM,CAAC;gBAAC,IAAI,CAAC,EAAE,MAAM,CAAA;aAAE,CAAA;SAAE,CAAA;KAAE,CAAC,CAAC;IACtH,WAAW,CAAC,EAAE;QACZ,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,MAAM,CAAC,EAAE;YAAE,IAAI,CAAC,EAAE,MAAM,CAAC;YAAC,IAAI,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC;QAC1C,YAAY,CAAC,EAAE,KAAK,CAAC;YAAE,IAAI,CAAC,EAAE;gBAAE,IAAI,CAAC,EAAE,MAAM,CAAC;gBAAC,MAAM,CAAC,EAAE;oBAAE,IAAI,CAAC,EAAE,MAAM,CAAC;oBAAC,IAAI,CAAC,EAAE,MAAM,CAAA;iBAAE,CAAA;aAAE,CAAA;SAAE,CAAC,CAAC;KAC/F,CAAC;IACF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AA4DD;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAKzD;AAkCD;;;;;;;;;;;GAWG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CA+B7D;AAiCD;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAyBlD;AA8RD;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CA+B5D;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CASxD;AA4CD,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,OAAO,GAAG,MAAM,CAoBnG;AAED,yEAAyE;AACzE,eAAO,MAAM,iBAAiB,cAAc,CAAC;AAE7C;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,GAAG,MAAM,CAKtE;AAED,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,CA41B7B;AAMD,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CA+B3D;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAkClE;AAoCD;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAI/F"}
|
package/dist/client-bundle.js
CHANGED
|
@@ -137,32 +137,41 @@ function isAnyImport(node) {
|
|
|
137
137
|
}
|
|
138
138
|
/**
|
|
139
139
|
* Generated client-preamble nodes the bundle must not re-emit: the local
|
|
140
|
-
* `const __components = {}`
|
|
141
|
-
* the chunk IIFEs already define their own
|
|
142
|
-
* declaration in the same scope would
|
|
140
|
+
* `const __components = {}` / `const __hydrators = {}` registries plus the
|
|
141
|
+
* `__cleanup` / `__place` helpers — the chunk IIFEs already define their own
|
|
142
|
+
* registries, so a second declaration in the same scope would shadow the live
|
|
143
|
+
* map (registrations would land on a detached object).
|
|
143
144
|
*/
|
|
144
145
|
function isRuntimePreamble(node) {
|
|
145
146
|
if (node.type === 'FunctionDeclaration' && (node.id?.name === '__cleanup' || node.id?.name === '__place')) {
|
|
146
147
|
return true;
|
|
147
148
|
}
|
|
148
149
|
if (node.type === 'VariableDeclaration') {
|
|
149
|
-
|
|
150
|
+
const name = node.declarations?.[0]?.id?.name;
|
|
151
|
+
return name === '__components' || name === '__hydrators';
|
|
150
152
|
}
|
|
151
153
|
return false;
|
|
152
154
|
}
|
|
153
155
|
/**
|
|
154
156
|
* `export default __components[<name>];` / `export const <name> = __components[<name>];`
|
|
155
|
-
* aliases emitted by codegen.
|
|
156
|
-
*
|
|
157
|
+
* aliases emitted by codegen. Hydrate-mode codegen emits the same alias against
|
|
158
|
+
* `__hydrators`. The bundle registers components on those maps directly, so
|
|
159
|
+
* these module-level re-exports must go — two surviving `export default`s in
|
|
160
|
+
* one chunk are a `SyntaxError: Identifier '.default' has already been
|
|
161
|
+
* declared` that kills every page script.
|
|
157
162
|
*/
|
|
158
163
|
function isComponentExport(node) {
|
|
164
|
+
const isRegistry = (ref) => {
|
|
165
|
+
const n = ref;
|
|
166
|
+
return !!n && n.type === 'MemberExpression' && n.object?.type === 'Identifier'
|
|
167
|
+
&& (n.object.name === '__components' || n.object.name === '__hydrators');
|
|
168
|
+
};
|
|
159
169
|
if (node.type === 'ExportDefaultDeclaration') {
|
|
160
|
-
|
|
161
|
-
return !!d && d.type === 'MemberExpression' && d.object?.type === 'Identifier' && d.object.name === '__components';
|
|
170
|
+
return isRegistry(node.declaration);
|
|
162
171
|
}
|
|
163
172
|
if (node.type === 'ExportNamedDeclaration') {
|
|
164
173
|
const init = node.declaration?.type === 'VariableDeclaration' ? node.declaration.declarations?.[0]?.init : undefined;
|
|
165
|
-
return
|
|
174
|
+
return isRegistry(init);
|
|
166
175
|
}
|
|
167
176
|
return false;
|
|
168
177
|
}
|
|
@@ -582,7 +591,7 @@ function removeRanges(code, ranges) {
|
|
|
582
591
|
*/
|
|
583
592
|
function fallbackReplay(cached, filePath, imports) {
|
|
584
593
|
const comp = cached.compCode ? imports.add(cached.compCode, filePath).replace(/^\n+/, '').replace(/\n+$/, '') : '';
|
|
585
|
-
const hyd = cached.hydCode ? imports.add(cached.hydCode, filePath).replace(
|
|
594
|
+
const hyd = cached.hydCode ? imports.add(cached.hydCode, filePath).replace(/^\n+/, '').replace(/\n+$/, '') : '';
|
|
586
595
|
return [comp, hyd].filter(Boolean).join('\n');
|
|
587
596
|
}
|
|
588
597
|
/**
|
|
@@ -929,7 +938,7 @@ export async function generateClientBundle(routeTree, appDir, componentMap, opti
|
|
|
929
938
|
const compSpecs = [];
|
|
930
939
|
const hydSpecs = [];
|
|
931
940
|
const compCode = compWithImports ? imports.add(compWithImports, filePath, compSpecs).replace(/^\n+/, '').replace(/\n+$/, '') : '';
|
|
932
|
-
const hydCode = hydWithImports ? imports.add(hydWithImports, filePath, hydSpecs).replace(
|
|
941
|
+
const hydCode = hydWithImports ? imports.add(hydWithImports, filePath, hydSpecs).replace(/^\n+/, '').replace(/\n+$/, '') : '';
|
|
933
942
|
if (rawComp)
|
|
934
943
|
collectRuntimeImports(rawComp);
|
|
935
944
|
if (rawHyd)
|
|
@@ -1236,7 +1245,7 @@ export async function generateClientBundle(routeTree, appDir, componentMap, opti
|
|
|
1236
1245
|
const shim = join(tmpBase, `shim-${i}.js`);
|
|
1237
1246
|
const shimLines = [`const m = globalThis.__veskShared[${JSON.stringify(file)}];`];
|
|
1238
1247
|
if (hasDefault)
|
|
1239
|
-
shimLines.push(`export default m;`);
|
|
1248
|
+
shimLines.push(`export default m["default"];`);
|
|
1240
1249
|
for (const name of [...named].sort()) {
|
|
1241
1250
|
shimLines.push(`export const ${name} = m[${JSON.stringify(name)}];`);
|
|
1242
1251
|
}
|
|
@@ -1304,30 +1313,53 @@ export async function generateClientBundle(routeTree, appDir, componentMap, opti
|
|
|
1304
1313
|
// Pass the app tsconfig so esbuild resolves tsconfig `paths` aliases
|
|
1305
1314
|
// (`@/x`, `@app/x`) inside transitively bundled modules too.
|
|
1306
1315
|
const appTsconfig = findTsconfigPath(appDir);
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1316
|
+
// Build an alias map so esbuild can resolve bare specifiers
|
|
1317
|
+
// (e.g. "vesk-qr") from the app's node_modules. The entry code lives
|
|
1318
|
+
// in a temp directory, so esbuild's default resolver (walking up from
|
|
1319
|
+
// the entry file) can't find app-level node_modules. resolveDir
|
|
1320
|
+
// doesn't exist in this esbuild version, so we alias each bare
|
|
1321
|
+
// specifier to its resolved absolute path.
|
|
1322
|
+
const alias = {};
|
|
1323
|
+
for (const source of entry.importsTable.sources()) {
|
|
1324
|
+
if (source.startsWith('/') || source.startsWith('./') || source.startsWith('../'))
|
|
1325
|
+
continue;
|
|
1326
|
+
let resolved = resolveSsrModule(source, appDir);
|
|
1327
|
+
if (!resolved)
|
|
1328
|
+
resolved = resolveImportPath(source, appDir);
|
|
1329
|
+
if (resolved && !resolved.startsWith('\0builtin:')) {
|
|
1330
|
+
alias[source] = resolved;
|
|
1331
|
+
}
|
|
1332
|
+
}
|
|
1333
|
+
const result = await Promise.race([
|
|
1334
|
+
build({
|
|
1335
|
+
entryPoints: [tmpFile],
|
|
1336
|
+
bundle: true,
|
|
1337
|
+
format: 'iife',
|
|
1338
|
+
platform: 'browser',
|
|
1339
|
+
write: false,
|
|
1340
|
+
logLevel: 'silent',
|
|
1341
|
+
loader: { '.js': 'tsx' },
|
|
1342
|
+
// Bundled dependencies (lucide-vesk above all) carry a license
|
|
1343
|
+
// banner per module, and a barrel import pulls in hundreds of
|
|
1344
|
+
// them. Those banners were ~339 KB of a 350 KB chunk, which is
|
|
1345
|
+
// what kept a barrel import from being usable at all. Attribution
|
|
1346
|
+
// for a dependency stays in its own package; shipping every
|
|
1347
|
+
// module's header inside our own chunk adds nothing.
|
|
1348
|
+
legalComments: 'none',
|
|
1349
|
+
// Shared app modules are NOT inlined here: the resolver below
|
|
1350
|
+
// redirects them to a generated shim reading
|
|
1351
|
+
// `globalThis.__veskShared`, so the single copy in
|
|
1352
|
+
// shared-modules.js serves every route chunk. (esbuild's `alias`
|
|
1353
|
+
// option only accepts bare package names, so this is a resolver
|
|
1354
|
+
// rather than a map.)
|
|
1355
|
+
...(sharedRedirectPlugin ? { plugins: [sharedRedirectPlugin, serverOnlyGuard] } : { plugins: [serverOnlyGuard] }),
|
|
1356
|
+
...(appTsconfig ? { tsconfig: appTsconfig } : {}),
|
|
1357
|
+
// Alias bare specifiers to their resolved absolute paths so
|
|
1358
|
+
// esbuild can find them from the temp chunk dir.
|
|
1359
|
+
...(Object.keys(alias).length ? { alias } : {}),
|
|
1360
|
+
}),
|
|
1361
|
+
new Promise((_, reject) => setTimeout(() => reject(new Error('chunk esbuild timeout')), 60000)),
|
|
1362
|
+
]);
|
|
1331
1363
|
finalCode = result.outputFiles[0].text;
|
|
1332
1364
|
}
|
|
1333
1365
|
catch (e) {
|
|
@@ -1337,22 +1369,22 @@ export async function generateClientBundle(routeTree, appDir, componentMap, opti
|
|
|
1337
1369
|
return x.text + at;
|
|
1338
1370
|
}).join(' | ') || err?.message || String(e);
|
|
1339
1371
|
console.error('[vesk] chunk bundle failed', entry.name, detail);
|
|
1340
|
-
//
|
|
1341
|
-
//
|
|
1342
|
-
//
|
|
1343
|
-
//
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1372
|
+
// A module-scope server-only use is diagnosed here rather than after
|
|
1373
|
+
// the try: the bundler itself throws when the transitive TCP driver
|
|
1374
|
+
// (pg → node:net) can't be browser-bundled, which would otherwise
|
|
1375
|
+
// shadow the real, actionable problem.
|
|
1376
|
+
if (eagerHits.length > 0) {
|
|
1377
|
+
const eagerDetail = eagerHits
|
|
1378
|
+
.map(h => `${h.importer} uses ${h.bindings.map(b => `"${b}"`).join(', ')} from "${h.specifier}" at module scope`)
|
|
1379
|
+
.join('; ');
|
|
1380
|
+
console.error('[vesk] server-only package used at module scope in client code', entry.name + ':', eagerDetail);
|
|
1381
|
+
throw new Error(`[vesk] ${entry.name}: ${eagerDetail}.\n` +
|
|
1382
|
+
'A module-scope statement runs the moment the browser evaluates the chunk, so a ' +
|
|
1383
|
+
'server-only package cannot be substituted there. Move that work into an API route ' +
|
|
1384
|
+
'(app/api/**/route.ts) or a server action — if the binding is only used from inside ' +
|
|
1385
|
+
'a function, this build already handles it.');
|
|
1348
1386
|
}
|
|
1349
|
-
|
|
1350
|
-
// classic script at least parses. Bindings imported from native-only
|
|
1351
|
-
// `@vesk/*` libraries get throwing stubs (a readable degradation
|
|
1352
|
-
// instead of a baffling `X is not defined`); every other stripped
|
|
1353
|
-
// name stays dangling, which is the pre-existing failure mode.
|
|
1354
|
-
const stripped = demoteExports(removeCompiledNodes(entry.code, isAnyImport));
|
|
1355
|
-
finalCode = chunkIIFE(nativeLibraryImportStubs(entry.code) + stripped);
|
|
1387
|
+
throw new Error(`[vesk] chunk bundle failed: ${entry.name} — ${detail}`);
|
|
1356
1388
|
}
|
|
1357
1389
|
finally {
|
|
1358
1390
|
try {
|
|
@@ -1360,25 +1392,6 @@ export async function generateClientBundle(routeTree, appDir, componentMap, opti
|
|
|
1360
1392
|
}
|
|
1361
1393
|
catch { }
|
|
1362
1394
|
}
|
|
1363
|
-
// Checked OUTSIDE the try above, deliberately. A TCP driver cannot be
|
|
1364
|
-
// stubbed into a browser bundle — a page that looked fine and failed on
|
|
1365
|
-
// its first query would be worse than a build error — and the catch
|
|
1366
|
-
// block degrades every failure into "strip the imports and carry on",
|
|
1367
|
-
// which is exactly the wrong outcome for this one.
|
|
1368
|
-
if (eagerHits.length > 0) {
|
|
1369
|
-
// A stub would throw while the chunk is still evaluating, so the page
|
|
1370
|
-
// would die before a component existed. That is the worst place to
|
|
1371
|
-
// learn about it: refuse the build instead.
|
|
1372
|
-
const detail = eagerHits
|
|
1373
|
-
.map(h => `${h.importer} uses ${h.bindings.map(b => `"${b}"`).join(', ')} from "${h.specifier}" at module scope`)
|
|
1374
|
-
.join('; ');
|
|
1375
|
-
console.error('[vesk] server-only package used at module scope in client code', entry.name + ':', detail);
|
|
1376
|
-
throw new Error(`[vesk] ${entry.name}: ${detail}.\n` +
|
|
1377
|
-
'A module-scope statement runs the moment the browser evaluates the chunk, so a ' +
|
|
1378
|
-
'server-only package cannot be substituted there. Move that work into an API route ' +
|
|
1379
|
-
'(app/api/**/route.ts) or a server action — if the binding is only used from inside ' +
|
|
1380
|
-
'a function, this build already handles it.');
|
|
1381
|
-
}
|
|
1382
1395
|
if (driverHits.length > 0) {
|
|
1383
1396
|
const detail = [...new Set(driverHits.map(h => `${h.specifier} (from ${h.importer})`))].join(', ');
|
|
1384
1397
|
console.error('[vesk] chunk bundle contains a TCP-only driver', entry.name + ':', detail);
|
|
@@ -1494,6 +1507,13 @@ export async function generateClientBundle(routeTree, appDir, componentMap, opti
|
|
|
1494
1507
|
let hydratorLines = [];
|
|
1495
1508
|
let aliasLines = [];
|
|
1496
1509
|
let hydratorAliasLines = [];
|
|
1510
|
+
// Mono builds bundle every file into one module scope. External-package
|
|
1511
|
+
// imports (e.g. vesk-qr) are not stripped by stripVskImports/stripRuntimeImport,
|
|
1512
|
+
// so multiple files importing the same package would emit duplicate
|
|
1513
|
+
// `import { X } from "pkg"` declarations — a SyntaxError. Fold them into
|
|
1514
|
+
// one deduped import block instead (mirrors what ChunkImports does for
|
|
1515
|
+
// code-split chunks).
|
|
1516
|
+
const monoImports = new ChunkImports();
|
|
1497
1517
|
function compileFileMono(filePath, resolvedName) {
|
|
1498
1518
|
if (seen.has(filePath))
|
|
1499
1519
|
return;
|
|
@@ -1512,8 +1532,15 @@ export async function generateClientBundle(routeTree, appDir, componentMap, opti
|
|
|
1512
1532
|
if (hydCode)
|
|
1513
1533
|
collectRuntimeImports(hydCode);
|
|
1514
1534
|
// Comp and hyd share the file's top-level bindings — scope together.
|
|
1515
|
-
|
|
1516
|
-
|
|
1535
|
+
let strippedComp = compCode ? stripExports(stripVskImports(stripRuntimeImport(compCode))).replace(/^\n+/, '').replace(/\n+$/, '') : '';
|
|
1536
|
+
let strippedHyd = hydCode ? stripExports(stripVskImports(stripRuntimeImport(hydCode))).replace(/^\n+/, '').replace(/\n+$/, '') : '';
|
|
1537
|
+
// Fold remaining external-package imports into the shared dedup set and
|
|
1538
|
+
// strip them from each file's contribution, so the same package imported
|
|
1539
|
+
// by multiple files only emits one `import` statement.
|
|
1540
|
+
if (monoImports.ok) {
|
|
1541
|
+
strippedComp = strippedComp ? monoImports.add(strippedComp, filePath).replace(/^\n+/, '').replace(/\n+$/, '') : '';
|
|
1542
|
+
strippedHyd = strippedHyd ? monoImports.add(strippedHyd, filePath).replace(/^\n+/, '').replace(/\n+$/, '') : '';
|
|
1543
|
+
}
|
|
1517
1544
|
const fileCode = [strippedComp, strippedHyd].filter(Boolean).join('\n');
|
|
1518
1545
|
if (fileCode.trim())
|
|
1519
1546
|
componentLines.push(scopeFileContribution(fileCode));
|
|
@@ -1554,9 +1581,79 @@ export async function generateClientBundle(routeTree, appDir, componentMap, opti
|
|
|
1554
1581
|
for (const [compName, compPath] of compMap) {
|
|
1555
1582
|
compileFileMono(compPath, compName);
|
|
1556
1583
|
}
|
|
1557
|
-
|
|
1584
|
+
// Emit the deduplicated external-package import block at the top of the
|
|
1585
|
+
// bundle so every file can reference those bindings without duplicate
|
|
1586
|
+
// declarations. If the import merge aborted (conflicting bindings), log a
|
|
1587
|
+
// warning and leave imports in place (best-effort, matches historical behaviour).
|
|
1588
|
+
if (monoImports.ok) {
|
|
1589
|
+
const head = monoImports.render();
|
|
1590
|
+
if (head)
|
|
1591
|
+
componentLines.unshift(head);
|
|
1592
|
+
}
|
|
1593
|
+
else {
|
|
1594
|
+
console.error('[vesk] mono import merge aborted:', monoImports.reason);
|
|
1595
|
+
}
|
|
1596
|
+
let main = await buildMainBundle(routeTree, runtimeDir, false, {
|
|
1558
1597
|
componentLines, hydratorLines, aliasLines, hydratorAliasLines,
|
|
1559
1598
|
}, !!options?.hmr, !!options?.importRuntime, runtimeImportNames, options?.routeDataCache);
|
|
1599
|
+
// Bundle the monolithic output through esbuild so bare external-package
|
|
1600
|
+
// imports (e.g. vesk-qr) are inlined instead of shipped as filesystem
|
|
1601
|
+
// paths the browser cannot load. Without this, client.js contains
|
|
1602
|
+
// `import ... from "/absolute/path/to/node_modules/…"` — the dev server
|
|
1603
|
+
// answers that with its SPA fallback (text/html), the module script dies,
|
|
1604
|
+
// the router never starts and hydration never completes.
|
|
1605
|
+
const appTsconfig = findTsconfigPath(appDir);
|
|
1606
|
+
const tmpBase = mkdtempSync(join(resolve(appDir, '..'), 'tmp-vesk-mono-'));
|
|
1607
|
+
try {
|
|
1608
|
+
const tmpFile = join(tmpBase, 'entry.js');
|
|
1609
|
+
writeFileSync(tmpFile, main, 'utf-8');
|
|
1610
|
+
const result = await build({
|
|
1611
|
+
entryPoints: [tmpFile],
|
|
1612
|
+
bundle: true,
|
|
1613
|
+
format: 'iife',
|
|
1614
|
+
platform: 'browser',
|
|
1615
|
+
write: false,
|
|
1616
|
+
logLevel: 'silent',
|
|
1617
|
+
loader: { '.js': 'tsx' },
|
|
1618
|
+
legalComments: 'none',
|
|
1619
|
+
...(appTsconfig ? { tsconfig: appTsconfig } : {}),
|
|
1620
|
+
// Stub only the OPTIONAL CJS deps (canvas for raster export, @zxing/*
|
|
1621
|
+
// for scan validation). They degrade gracefully and their absence must
|
|
1622
|
+
// not break the bundle.
|
|
1623
|
+
//
|
|
1624
|
+
// `qrcode-generator` must NOT be stubbed: it is the pure-JS encoder
|
|
1625
|
+
// every client-side QR (vesk-qr's dynamic `import("qrcode-generator")`)
|
|
1626
|
+
// runs on. Stubbing it to `export {}` makes `getQrcode()` resolve to an
|
|
1627
|
+
// empty object, so `CofoundrMatrix.generate()` throws
|
|
1628
|
+
// "QREncodingError: generator is not a function" during hydration and
|
|
1629
|
+
// the page falls back to the client error boundary. esbuild bundles it
|
|
1630
|
+
// as CJS fine; only genuinely Node-only/optional deps belong here.
|
|
1631
|
+
plugins: [
|
|
1632
|
+
{
|
|
1633
|
+
name: 'stub-browser-packages',
|
|
1634
|
+
setup(b) {
|
|
1635
|
+
b.onResolve({ filter: /^(canvas|@zxing\/(browser|node))(\/|$)/ }, (args) => ({ path: args.path, namespace: 'browser-stub' }));
|
|
1636
|
+
b.onLoad({ filter: /.*/, namespace: 'browser-stub' }, () => ({
|
|
1637
|
+
contents: 'export {}\n',
|
|
1638
|
+
loader: 'js',
|
|
1639
|
+
}));
|
|
1640
|
+
},
|
|
1641
|
+
},
|
|
1642
|
+
],
|
|
1643
|
+
});
|
|
1644
|
+
main = result.outputFiles[0].text;
|
|
1645
|
+
}
|
|
1646
|
+
catch (e) {
|
|
1647
|
+
const detail = e?.errors?.map((x) => x.text).join(' | ') || e.message || String(e);
|
|
1648
|
+
console.error('[vesk] client bundle failed', detail);
|
|
1649
|
+
throw new Error(`[vesk] client bundle failed — ${detail}`);
|
|
1650
|
+
}
|
|
1651
|
+
finally {
|
|
1652
|
+
try {
|
|
1653
|
+
rmSync(tmpBase, { recursive: true, force: true });
|
|
1654
|
+
}
|
|
1655
|
+
catch { }
|
|
1656
|
+
}
|
|
1560
1657
|
// Mono (non-codeSplit) builds are the production path — no incremental cache.
|
|
1561
1658
|
componentOwners.report('client bundle');
|
|
1562
1659
|
return { main: await applyTransformPlugins(main, 'client.js'), chunks: [] };
|
|
@@ -1600,15 +1697,46 @@ export function buildRuntimeCode(runtimeDir) {
|
|
|
1600
1697
|
/**
|
|
1601
1698
|
* Names the client runtime actually exports, so the tree-shaken bundle only
|
|
1602
1699
|
* emits the modules reachable from the used set.
|
|
1700
|
+
*
|
|
1701
|
+
* Parses index-client.js with the AST parser instead of regex so that direct
|
|
1702
|
+
* declarations (export function locals() {}, export const x = 1, export class
|
|
1703
|
+
* Foo {}) are captured alongside re-exports (export { X } from '...').
|
|
1603
1704
|
*/
|
|
1604
1705
|
export function runtimeExportNames(runtimeDir) {
|
|
1605
1706
|
const indexSrc = readFileSync(join(runtimeDir, 'index-client.js'), 'utf-8');
|
|
1606
1707
|
const names = new Set();
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1708
|
+
const ast = parse(indexSrc, { filename: join(runtimeDir, 'index-client.js') });
|
|
1709
|
+
for (const node of ast.body) {
|
|
1710
|
+
const n = node;
|
|
1711
|
+
if (n.type === 'ExportNamedDeclaration') {
|
|
1712
|
+
if (n.declaration) {
|
|
1713
|
+
// Direct declaration: export function foo() {}, export const x = 1,
|
|
1714
|
+
// export class Bar {}
|
|
1715
|
+
const decl = n.declaration;
|
|
1716
|
+
if (decl.type === 'FunctionDeclaration' && decl.id) {
|
|
1717
|
+
names.add(String(decl.id.name));
|
|
1718
|
+
}
|
|
1719
|
+
else if (decl.type === 'ClassDeclaration' && decl.id) {
|
|
1720
|
+
names.add(String(decl.id.name));
|
|
1721
|
+
}
|
|
1722
|
+
else if (decl.type === 'VariableDeclaration') {
|
|
1723
|
+
for (const d of decl.declarations) {
|
|
1724
|
+
if (d.id.type === 'Identifier') {
|
|
1725
|
+
names.add(String(d.id.name));
|
|
1726
|
+
}
|
|
1727
|
+
}
|
|
1728
|
+
}
|
|
1729
|
+
}
|
|
1730
|
+
else if (n.source) {
|
|
1731
|
+
// Re-export: export { X } from '...' or export { X as Y } from '...'
|
|
1732
|
+
for (const spec of n.specifiers) {
|
|
1733
|
+
if (spec.type === 'ExportSpecifier') {
|
|
1734
|
+
const exported = spec.exported.name;
|
|
1735
|
+
if (exported)
|
|
1736
|
+
names.add(String(exported));
|
|
1737
|
+
}
|
|
1738
|
+
}
|
|
1739
|
+
}
|
|
1612
1740
|
}
|
|
1613
1741
|
}
|
|
1614
1742
|
return names;
|
|
@@ -1700,25 +1828,28 @@ async function bundleRuntimeNames(runtimeDir, names, strict = false) {
|
|
|
1700
1828
|
}
|
|
1701
1829
|
catch { /* not present yet */ }
|
|
1702
1830
|
writeFileSync(entry, `export { ${unique.join(', ')} } from ${JSON.stringify(indexClient)};\n`);
|
|
1703
|
-
const result = await
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1831
|
+
const result = await Promise.race([
|
|
1832
|
+
build({
|
|
1833
|
+
entryPoints: [esbuildPath(entry)],
|
|
1834
|
+
bundle: true,
|
|
1835
|
+
format: 'iife',
|
|
1836
|
+
globalName: '__veskRuntime',
|
|
1837
|
+
platform: 'browser',
|
|
1838
|
+
target: ['es2022'],
|
|
1839
|
+
treeShaking: true,
|
|
1840
|
+
// Do not let esbuild rename identifiers here. This bundle is one large
|
|
1841
|
+
// IIFE built from many runtime modules, and the renaming pass of some
|
|
1842
|
+
// esbuild versions (observed on 0.25.12) emits a free reference to an
|
|
1843
|
+
// undefined minified name (ReferenceError: m is not defined) that kills
|
|
1844
|
+
// client hydration for the whole app. Whitespace-only output keeps the
|
|
1845
|
+
// runtime deterministic at a modest size cost; tree-shaking still prunes
|
|
1846
|
+
// unreachable modules, so names coming out of the IIFE are untouched.
|
|
1847
|
+
minify: false,
|
|
1848
|
+
write: false,
|
|
1849
|
+
logLevel: 'silent',
|
|
1850
|
+
}),
|
|
1851
|
+
new Promise((_, reject) => setTimeout(() => reject(new Error('runtime esbuild timeout')), 60000)),
|
|
1852
|
+
]);
|
|
1722
1853
|
const bundle = result.outputFiles[0].text;
|
|
1723
1854
|
return `${bundle}\nconst { ${unique.join(', ')} } = __veskRuntime;\nexport { ${unique.join(', ')} };\n`;
|
|
1724
1855
|
}
|
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;AASjG,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,OAAO,CAAC;AAO7C,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;AAwDD,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,
|
|
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;AAO7C,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;AAwDD,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,CAQrD;AAUD,wBAAsB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CA4sBvG"}
|
package/dist/dev-server.js
CHANGED
|
@@ -150,7 +150,10 @@ export function devBootstrapScript() {
|
|
|
150
150
|
export function injectDevScripts(html) {
|
|
151
151
|
if (!html.includes('</body>'))
|
|
152
152
|
return html;
|
|
153
|
-
const scripts = '\t<script type="module" src="/_vesk/
|
|
153
|
+
const scripts = '\t<script type="module" src="/_vesk/client.js"></script>\n' +
|
|
154
|
+
'\t<script type="module" src="/_vesk/hmr.js"></script>\n' +
|
|
155
|
+
devBootstrapScript() +
|
|
156
|
+
'\n';
|
|
154
157
|
return html.replace('</body>', scripts + '</body>');
|
|
155
158
|
}
|
|
156
159
|
const MIME = {
|
|
@@ -404,7 +407,12 @@ export async function startDevServer(appDir, options) {
|
|
|
404
407
|
}
|
|
405
408
|
}
|
|
406
409
|
}
|
|
407
|
-
await doBuild()
|
|
410
|
+
await doBuild();
|
|
411
|
+
if (pendingInitialError) {
|
|
412
|
+
console.error(`vesk dev: initial build failed — ${pendingInitialError.message}`);
|
|
413
|
+
console.error(`vesk dev: cannot start server with a broken build. Fix the errors above and restart.`);
|
|
414
|
+
process.exit(1);
|
|
415
|
+
}
|
|
408
416
|
const server = createServer(async (req, res) => {
|
|
409
417
|
const url = new URL(req.url || '/', `http://localhost:${port}`);
|
|
410
418
|
// SSR fetches may run while concurrent sub-requests (e.g. the page's own
|
|
@@ -507,6 +515,25 @@ export async function startDevServer(appDir, options) {
|
|
|
507
515
|
res.end(runtimeBundle);
|
|
508
516
|
return;
|
|
509
517
|
}
|
|
518
|
+
// Serve the dev client bundle at /_vesk/client.js. The file is written to
|
|
519
|
+
// devDir/static/client.js by the build step. The SSR-injected script tag
|
|
520
|
+
// references this exact URL.
|
|
521
|
+
if (url.pathname === '/_vesk/client.js') {
|
|
522
|
+
const clientPath = resolve(devDir, 'static', 'client.js');
|
|
523
|
+
try {
|
|
524
|
+
if (existsSync(clientPath)) {
|
|
525
|
+
res.writeHead(200, { 'Content-Type': 'application/javascript' });
|
|
526
|
+
res.end(readFileSync(clientPath, 'utf-8'));
|
|
527
|
+
return;
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
catch {
|
|
531
|
+
/* fall through to 404 below */
|
|
532
|
+
}
|
|
533
|
+
res.writeHead(404, { 'Content-Type': 'text/plain' });
|
|
534
|
+
res.end('client.js not built yet');
|
|
535
|
+
return;
|
|
536
|
+
}
|
|
510
537
|
// External data scripts (/ssr-data.js?t=...) are emitted by
|
|
511
538
|
// storeDataScriptGlobal once a render serializes SSR data. Without this
|
|
512
539
|
// route the dev SPA fallback served the HTML document as the script's
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"esbuild-fallback.d.ts","sourceRoot":"","sources":["../src/esbuild-fallback.ts"],"names":[],"mappings":"AAkCA,wBAAsB,KAAK,CAAC,OAAO,EAAE,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,
|
|
1
|
+
{"version":3,"file":"esbuild-fallback.d.ts","sourceRoot":"","sources":["../src/esbuild-fallback.ts"],"names":[],"mappings":"AAkCA,wBAAsB,KAAK,CAAC,OAAO,EAAE,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,CAoBtD"}
|
package/dist/esbuild-fallback.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
// the compiler's dependency-free `stripCodeTypes` (acorn-based), so no
|
|
5
5
|
// transformSync path exists anymore.
|
|
6
6
|
let _nativeBuild = null;
|
|
7
|
-
let _nativeDead =
|
|
7
|
+
let _nativeDead = process.env.VESK_NO_NATIVE_ESBUILD === 'true';
|
|
8
8
|
let _wasm = null;
|
|
9
9
|
let _wasmReady = null;
|
|
10
10
|
async function loadNative() {
|
|
@@ -25,22 +25,25 @@ async function getWasm() {
|
|
|
25
25
|
_wasmReady = import('esbuild-wasm').then(m => {
|
|
26
26
|
_wasm = m;
|
|
27
27
|
return m;
|
|
28
|
-
}).catch(() => {
|
|
28
|
+
}).catch((e) => {
|
|
29
29
|
_wasmReady = null;
|
|
30
|
-
throw new Error(
|
|
30
|
+
throw new Error(`esbuild-wasm not available — install it with: npm install esbuild-wasm (underlying: ${e instanceof Error ? e.message : String(e)})`);
|
|
31
31
|
});
|
|
32
32
|
}
|
|
33
33
|
return _wasmReady;
|
|
34
34
|
}
|
|
35
35
|
export async function build(options) {
|
|
36
36
|
await loadNative();
|
|
37
|
-
if (_nativeBuild) {
|
|
37
|
+
if (_nativeBuild && !_nativeDead) {
|
|
38
38
|
try {
|
|
39
|
-
return await
|
|
39
|
+
return await Promise.race([
|
|
40
|
+
_nativeBuild(options),
|
|
41
|
+
new Promise((_, reject) => setTimeout(() => reject(new Error('esbuild native timeout')), 120000)),
|
|
42
|
+
]);
|
|
40
43
|
}
|
|
41
44
|
catch (e) {
|
|
42
45
|
const msg = e instanceof Error ? e.message : String(e);
|
|
43
|
-
if (msg.includes('SIGILL') || msg.includes('illegal hardware instruction') || msg.includes('cannot execute binary file')) {
|
|
46
|
+
if (msg.includes('SIGILL') || msg.includes('illegal hardware instruction') || msg.includes('cannot execute binary file') || msg.includes('esbuild native timeout')) {
|
|
44
47
|
console.warn('vesk: native esbuild failed, falling back to esbuild-wasm:', msg);
|
|
45
48
|
_nativeDead = true;
|
|
46
49
|
}
|
|
@@ -4,6 +4,22 @@ import type { Platform } from '@vesk/adapter/src/platform';
|
|
|
4
4
|
export interface DeployContext extends PlatformBuildContext {
|
|
5
5
|
prerenderedRoutes: SsgRouteResult[];
|
|
6
6
|
}
|
|
7
|
+
/**
|
|
8
|
+
* Ship the installed TCP driver packages (and their transitive dependency
|
|
9
|
+
* closures) into a Node function's `node_modules`.
|
|
10
|
+
*
|
|
11
|
+
* A serverless function built by Vesk is otherwise self-contained — esbuild
|
|
12
|
+
* inlines everything. But a driver loaded through a variable `import(spec)`
|
|
13
|
+
* (e.g. `slintorm`'s `importDriver("pg")`) is invisible to esbuild *and* to the
|
|
14
|
+
* host's dependency tracer, and Build Output API functions do not install
|
|
15
|
+
* package.json dependencies. Without this the Postgres driver fails at runtime
|
|
16
|
+
* with `Cannot find module 'pg'` even though it is installed at build time.
|
|
17
|
+
*
|
|
18
|
+
* Only `dependencies`/`optionalDependencies` are followed (never dev deps), and
|
|
19
|
+
* nested `node_modules` are skipped because every dependency is flattened into
|
|
20
|
+
* the function's `node_modules` by name.
|
|
21
|
+
*/
|
|
22
|
+
export declare function shipNodeDriverClosures(projectRoot: string, funcDir: string): void;
|
|
7
23
|
/**
|
|
8
24
|
* Universal deployment emit. The handler, the bundle and the static layout are
|
|
9
25
|
* shared across every platform — only the ~10-line shell each runtime mandates
|
|
@@ -16,4 +32,16 @@ export interface DeployContext extends PlatformBuildContext {
|
|
|
16
32
|
* not a symlink).
|
|
17
33
|
*/
|
|
18
34
|
export declare function emitPlatformOutput(platform: Platform, ctx: DeployContext): Promise<string | null>;
|
|
35
|
+
/**
|
|
36
|
+
* Vercel Node entry source.
|
|
37
|
+
*
|
|
38
|
+
* The request URL is the base that SSR helpers resolve relative
|
|
39
|
+
* `useFetch('/api/…')` calls against. On Vercel, `req.headers.host` can be the
|
|
40
|
+
* deployment-specific host, which sits behind deployment protection, while
|
|
41
|
+
* `x-forwarded-host` carries the public alias the browser used. Preferring the
|
|
42
|
+
* forwarded host/proto keeps internal SSR fetches on the public origin; hitting
|
|
43
|
+
* the protected host follows a redirect to Vercel's auth HTML, which then fails
|
|
44
|
+
* `res.json()` with `Unexpected token '<'`.
|
|
45
|
+
*/
|
|
46
|
+
export declare function vercelBootstrapSource(): string;
|
|
19
47
|
//# sourceMappingURL=platform-deploy.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"platform-deploy.d.ts","sourceRoot":"","sources":["../src/platform-deploy.ts"],"names":[],"mappings":"AAEA,OAAO,EAAwD,KAAK,oBAAoB,EAAE,MAAM,oCAAoC,CAAC;
|
|
1
|
+
{"version":3,"file":"platform-deploy.d.ts","sourceRoot":"","sources":["../src/platform-deploy.ts"],"names":[],"mappings":"AAEA,OAAO,EAAwD,KAAK,oBAAoB,EAAE,MAAM,oCAAoC,CAAC;AAGrI,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AAE3D,MAAM,WAAW,aAAc,SAAQ,oBAAoB;IACzD,iBAAiB,EAAE,cAAc,EAAE,CAAC;CACrC;AAkBD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,sBAAsB,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CA0BjF;AA0BD;;;;;;;;;;GAUG;AACH,wBAAsB,kBAAkB,CAAC,QAAQ,EAAE,QAAQ,EAAE,GAAG,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAoFvG;AAqGD;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,IAAI,MAAM,CA2B9C"}
|
package/dist/platform-deploy.js
CHANGED
|
@@ -1,7 +1,71 @@
|
|
|
1
|
-
import { writeFileSync, mkdirSync, rmSync, cpSync } from 'node:fs';
|
|
2
|
-
import { resolve } from 'node:path';
|
|
1
|
+
import { writeFileSync, mkdirSync, rmSync, cpSync, readFileSync, existsSync } from 'node:fs';
|
|
2
|
+
import { resolve, dirname, relative } from 'node:path';
|
|
3
3
|
import { generatePlatformHandlerSource, bundlePlatformHandler } from '@vesk/adapter/src/platform-handler';
|
|
4
4
|
import { ensureCleanDir, writePlatformStatic, writePrerenderedStatic, listStaticDir, mimeFor } from '@vesk/adapter/src/platform-output';
|
|
5
|
+
import { tcpDriverPackages } from '@vesk/adapter/src/server-only';
|
|
6
|
+
/**
|
|
7
|
+
* Resolve an installed package directory the way Node does: walk up from the
|
|
8
|
+
* project root looking for `node_modules/<name>` (handles npm hoisting and
|
|
9
|
+
* monorepo workspaces). Returns null when the package is not installed.
|
|
10
|
+
*/
|
|
11
|
+
function resolveInstalledPackage(projectRoot, name) {
|
|
12
|
+
let dir = projectRoot;
|
|
13
|
+
while (true) {
|
|
14
|
+
const candidate = resolve(dir, 'node_modules', name);
|
|
15
|
+
if (existsSync(resolve(candidate, 'package.json')))
|
|
16
|
+
return candidate;
|
|
17
|
+
const parent = dirname(dir);
|
|
18
|
+
if (parent === dir)
|
|
19
|
+
return null;
|
|
20
|
+
dir = parent;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Ship the installed TCP driver packages (and their transitive dependency
|
|
25
|
+
* closures) into a Node function's `node_modules`.
|
|
26
|
+
*
|
|
27
|
+
* A serverless function built by Vesk is otherwise self-contained — esbuild
|
|
28
|
+
* inlines everything. But a driver loaded through a variable `import(spec)`
|
|
29
|
+
* (e.g. `slintorm`'s `importDriver("pg")`) is invisible to esbuild *and* to the
|
|
30
|
+
* host's dependency tracer, and Build Output API functions do not install
|
|
31
|
+
* package.json dependencies. Without this the Postgres driver fails at runtime
|
|
32
|
+
* with `Cannot find module 'pg'` even though it is installed at build time.
|
|
33
|
+
*
|
|
34
|
+
* Only `dependencies`/`optionalDependencies` are followed (never dev deps), and
|
|
35
|
+
* nested `node_modules` are skipped because every dependency is flattened into
|
|
36
|
+
* the function's `node_modules` by name.
|
|
37
|
+
*/
|
|
38
|
+
export function shipNodeDriverClosures(projectRoot, funcDir) {
|
|
39
|
+
const destModules = resolve(funcDir, 'node_modules');
|
|
40
|
+
const seen = new Set();
|
|
41
|
+
const queue = tcpDriverPackages();
|
|
42
|
+
while (queue.length > 0) {
|
|
43
|
+
const name = queue.shift();
|
|
44
|
+
if (seen.has(name))
|
|
45
|
+
continue;
|
|
46
|
+
seen.add(name);
|
|
47
|
+
const pkgDir = resolveInstalledPackage(projectRoot, name);
|
|
48
|
+
if (!pkgDir)
|
|
49
|
+
continue;
|
|
50
|
+
const dest = resolve(destModules, name);
|
|
51
|
+
mkdirSync(dirname(dest), { recursive: true });
|
|
52
|
+
cpSync(pkgDir, dest, {
|
|
53
|
+
recursive: true,
|
|
54
|
+
filter: (src) => !relative(pkgDir, src).split(/[\\/]/).includes('node_modules'),
|
|
55
|
+
});
|
|
56
|
+
let pkg = {};
|
|
57
|
+
try {
|
|
58
|
+
pkg = JSON.parse(readFileSync(resolve(pkgDir, 'package.json'), 'utf-8'));
|
|
59
|
+
}
|
|
60
|
+
catch { /* unreadable package.json: copy the package as-is */ }
|
|
61
|
+
const deps = {
|
|
62
|
+
...(pkg.dependencies || {}),
|
|
63
|
+
...(pkg.optionalDependencies || {}),
|
|
64
|
+
};
|
|
65
|
+
for (const dep of Object.keys(deps))
|
|
66
|
+
queue.push(dep);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
5
69
|
/**
|
|
6
70
|
* Universal deployment emit. The handler, the bundle and the static layout are
|
|
7
71
|
* shared across every platform — only the ~10-line shell each runtime mandates
|
|
@@ -60,6 +124,8 @@ export async function emitPlatformOutput(platform, ctx) {
|
|
|
60
124
|
}
|
|
61
125
|
handlerRel = `${shell.functionFile.dir}/${shell.functionFile.file}`;
|
|
62
126
|
await bundlePlatformHandler({ entry, outfile: resolve(funcDir, shell.functionFile.file), nodeBuiltins: shell.nodeBuiltins });
|
|
127
|
+
if (shell.nodeBuiltins)
|
|
128
|
+
shipNodeDriverClosures(projectRoot, funcDir);
|
|
63
129
|
}
|
|
64
130
|
else {
|
|
65
131
|
handlerRel = shell.outfile || 'index.js';
|
|
@@ -186,6 +252,45 @@ function serveEmbeddedStatic(request) {
|
|
|
186
252
|
return null;
|
|
187
253
|
}`;
|
|
188
254
|
}
|
|
255
|
+
/**
|
|
256
|
+
* Vercel Node entry source.
|
|
257
|
+
*
|
|
258
|
+
* The request URL is the base that SSR helpers resolve relative
|
|
259
|
+
* `useFetch('/api/…')` calls against. On Vercel, `req.headers.host` can be the
|
|
260
|
+
* deployment-specific host, which sits behind deployment protection, while
|
|
261
|
+
* `x-forwarded-host` carries the public alias the browser used. Preferring the
|
|
262
|
+
* forwarded host/proto keeps internal SSR fetches on the public origin; hitting
|
|
263
|
+
* the protected host follows a redirect to Vercel's auth HTML, which then fails
|
|
264
|
+
* `res.json()` with `Unexpected token '<'`.
|
|
265
|
+
*/
|
|
266
|
+
export function vercelBootstrapSource() {
|
|
267
|
+
return [
|
|
268
|
+
'export default async function veskNodeEntry(req, res) {',
|
|
269
|
+
" const __fwdHost = String(req.headers['x-forwarded-host'] || '').split(',')[0].trim();",
|
|
270
|
+
" const __host = __fwdHost || req.headers.host || 'localhost';",
|
|
271
|
+
" const __fwdProto = String(req.headers['x-forwarded-proto'] || '').split(',')[0].trim();",
|
|
272
|
+
" const __local = __host === 'localhost' || __host.startsWith('127.') || __host === '[::1]';",
|
|
273
|
+
" const __proto = __fwdProto || (__local ? 'http' : 'https');",
|
|
274
|
+
' const url = new URL(req.url, `${__proto}://${__host}`);',
|
|
275
|
+
" const method = req.method || 'GET';",
|
|
276
|
+
' let body;',
|
|
277
|
+
" if (method !== 'GET' && method !== 'HEAD') {",
|
|
278
|
+
' body = await new Promise((resolveBody, reject) => {',
|
|
279
|
+
' const chunks = [];',
|
|
280
|
+
" req.on('data', (c) => chunks.push(c));",
|
|
281
|
+
' req.on("error", reject);',
|
|
282
|
+
' req.on("end", () => resolveBody(Buffer.concat(chunks)));',
|
|
283
|
+
' });',
|
|
284
|
+
' }',
|
|
285
|
+
' const headers = {};',
|
|
286
|
+
' for (const key in req.headers) headers[key] = req.headers[key];',
|
|
287
|
+
' const request = new Request(url, { method, headers, body });',
|
|
288
|
+
' const response = await handleRequest(request);',
|
|
289
|
+
' res.writeHead(response.status, Object.fromEntries(response.headers));',
|
|
290
|
+
' res.end(await response.text());',
|
|
291
|
+
'}',
|
|
292
|
+
].join('\n');
|
|
293
|
+
}
|
|
189
294
|
function shellFor(platform) {
|
|
190
295
|
switch (platform) {
|
|
191
296
|
case 'vercel':
|
|
@@ -206,27 +311,7 @@ function shellFor(platform) {
|
|
|
206
311
|
shouldAddSourcemapSupport: false,
|
|
207
312
|
supportsResponseStreaming: true,
|
|
208
313
|
},
|
|
209
|
-
bootstrap:
|
|
210
|
-
'export default async function veskNodeEntry(req, res) {',
|
|
211
|
-
" const url = new URL(req.url, 'http://' + (req.headers.host || 'localhost'));",
|
|
212
|
-
" const method = req.method || 'GET';",
|
|
213
|
-
' let body;',
|
|
214
|
-
" if (method !== 'GET' && method !== 'HEAD') {",
|
|
215
|
-
' body = await new Promise((resolveBody, reject) => {',
|
|
216
|
-
' const chunks = [];',
|
|
217
|
-
" req.on('data', (c) => chunks.push(c));",
|
|
218
|
-
' req.on("error", reject);',
|
|
219
|
-
' req.on("end", () => resolveBody(Buffer.concat(chunks)));',
|
|
220
|
-
' });',
|
|
221
|
-
' }',
|
|
222
|
-
' const headers = {};',
|
|
223
|
-
' for (const key in req.headers) headers[key] = req.headers[key];',
|
|
224
|
-
' const request = new Request(url, { method, headers, body });',
|
|
225
|
-
' const response = await handleRequest(request);',
|
|
226
|
-
' res.writeHead(response.status, Object.fromEntries(response.headers));',
|
|
227
|
-
' res.end(await response.text());',
|
|
228
|
-
'}',
|
|
229
|
-
].join('\n'),
|
|
314
|
+
bootstrap: vercelBootstrapSource(),
|
|
230
315
|
};
|
|
231
316
|
case 'netlify':
|
|
232
317
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"platform-handler.d.ts","sourceRoot":"","sources":["../src/platform-handler.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AASvE,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,SAAS,EAAE,CAAC;IACvB,SAAS,EAAE,YAAY,EAAE,CAAC;IAC1B,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,aAAa,EAAE,OAAO,CAAC;IACvB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,iFAAiF;IACjF,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,MAAM,CAMpD;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAGrD;AAED,wBAAgB,IAAI,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAEtC;AAgBD;;;;;GAKG;AACH,wBAAgB,6BAA6B,CAAC,KAAK,EAAE,oBAAoB,GAAG,MAAM,CA4PjF;AAED,MAAM,WAAW,qBAAqB;IACpC,kEAAkE;IAClE,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,wBAAsB,qBAAqB,CAAC,OAAO,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"platform-handler.d.ts","sourceRoot":"","sources":["../src/platform-handler.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AASvE,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,SAAS,EAAE,CAAC;IACvB,SAAS,EAAE,YAAY,EAAE,CAAC;IAC1B,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,aAAa,EAAE,OAAO,CAAC;IACvB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,iFAAiF;IACjF,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,MAAM,CAMpD;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAGrD;AAED,wBAAgB,IAAI,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAEtC;AAgBD;;;;;GAKG;AACH,wBAAgB,6BAA6B,CAAC,KAAK,EAAE,oBAAoB,GAAG,MAAM,CA4PjF;AAED,MAAM,WAAW,qBAAqB;IACpC,kEAAkE;IAClE,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,wBAAsB,qBAAqB,CAAC,OAAO,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC,CA6JzF;AAED,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,SAAS,EAAE,CAAC;IACvB,SAAS,EAAE,YAAY,EAAE,CAAC;IAC1B,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,aAAa,EAAE,OAAO,CAAC;IACvB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB"}
|
package/dist/platform-handler.js
CHANGED
|
@@ -337,17 +337,52 @@ export const sep = '/';
|
|
|
337
337
|
export const delimiter = ':';
|
|
338
338
|
export const spawnSync = () => ({ status: 0 });
|
|
339
339
|
export const execSync = () => '';
|
|
340
|
-
export const randomBytes = () => ({});
|
|
341
|
-
export const createHash = () => ({ update: () => {}, digest: () => '' });
|
|
342
340
|
`;
|
|
343
|
-
return {
|
|
344
|
-
contents,
|
|
345
|
-
loader: 'js',
|
|
346
|
-
};
|
|
341
|
+
return { contents, loader: 'js' };
|
|
347
342
|
});
|
|
348
343
|
},
|
|
349
344
|
});
|
|
350
345
|
}
|
|
346
|
+
// Edge/neutral targets bundle everything into ESM. CJS dependencies (e.g.
|
|
347
|
+
// qrcode-generator via vesk-qr) can't be bundled as ESM — esbuild rewrites
|
|
348
|
+
// their require() calls into `__require` shims that throw in ESM output.
|
|
349
|
+
// esbuild 0.28's string `external` option does not externalize resolvable
|
|
350
|
+
// bare specifiers (it emits `__require` shims instead), so resolve these
|
|
351
|
+
// packages to empty stub modules. vesk-qr and its optional CJS deps
|
|
352
|
+
// (qrcode-generator, canvas, @zxing/*) are optional at runtime on edge (they
|
|
353
|
+
// fail gracefully), so stubbing them at build time is safe and keeps the
|
|
354
|
+
// bundle valid ESM.
|
|
355
|
+
//
|
|
356
|
+
// Node targets are different: the `createRequire` banner makes the
|
|
357
|
+
// `__require` shim resolve for real, so vesk-qr and its encoder (the CJS
|
|
358
|
+
// `qrcode-generator`) MUST be bundled. A Build Output function ships no
|
|
359
|
+
// package.json deps, and stubbing the encoder makes `buildQrSvg()` throw
|
|
360
|
+
// during SSR (500 on any page that awaits a QR). canvas/@zxing stay
|
|
361
|
+
// stubbed because they are optional and only back raster/scan validation,
|
|
362
|
+
// which degrades gracefully when the decoder is unavailable.
|
|
363
|
+
const qrStubPattern = nodeBuiltins
|
|
364
|
+
? /^(canvas|@zxing\/(browser|node))(\/|$)/
|
|
365
|
+
: /^(vesk-qr|qrcode-generator|canvas|@zxing\/(browser|node))(\/|$)/;
|
|
366
|
+
plugins.push({
|
|
367
|
+
name: 'stub-optional-qr-packages',
|
|
368
|
+
setup(build) {
|
|
369
|
+
build.onResolve({ filter: qrStubPattern }, (args) => ({ path: args.path, namespace: 'vesk-edge-stub' }));
|
|
370
|
+
build.onLoad({ filter: /.*/, namespace: 'vesk-edge-stub' }, () => ({
|
|
371
|
+
contents: [
|
|
372
|
+
'export const CofoundrMatrix = undefined;\n',
|
|
373
|
+
'export const generate = undefined;\n',
|
|
374
|
+
'export const Qr = undefined;\n',
|
|
375
|
+
'export const RawHtml = undefined;\n',
|
|
376
|
+
'export const CanvasUnavailableError = undefined;\n',
|
|
377
|
+
'export const InvalidConfigError = undefined;\n',
|
|
378
|
+
'export const QREncodingError = undefined;\n',
|
|
379
|
+
'export const ScanReliabilityError = undefined;\n',
|
|
380
|
+
'export const QRError = undefined;\n',
|
|
381
|
+
].join(''),
|
|
382
|
+
loader: 'js',
|
|
383
|
+
}));
|
|
384
|
+
},
|
|
385
|
+
});
|
|
351
386
|
const result = await build({
|
|
352
387
|
entryPoints: [entry],
|
|
353
388
|
bundle: true,
|
|
@@ -377,7 +412,18 @@ export const createHash = () => ({ update: () => {}, digest: () => '' });
|
|
|
377
412
|
'const require = createRequire(import.meta.url);\n',
|
|
378
413
|
},
|
|
379
414
|
}
|
|
380
|
-
: {
|
|
415
|
+
: {
|
|
416
|
+
// Edge/neutral targets bundle everything into ESM. CJS dependencies
|
|
417
|
+
// (e.g. qrcode-generator via vesk-qr) can't be bundled as ESM —
|
|
418
|
+
// esbuild adds `__require` shims that throw in ESM output. Mark them
|
|
419
|
+
// external so they're left as bare imports instead of `__require`
|
|
420
|
+
// shims. vesk-qr is ESM but internally requires() its CJS deps,
|
|
421
|
+
// which would generate __require shims — externalize it too so its
|
|
422
|
+
// code never enters the bundle. On edge hosts without node_modules
|
|
423
|
+
// these external imports fail at runtime (expected — CJS packages
|
|
424
|
+
// don't run on edge), but the bundle itself is valid ESM.
|
|
425
|
+
external: ['vesk-qr', 'qrcode-generator', 'canvas', '@zxing/browser', '@zxing/node'],
|
|
426
|
+
}),
|
|
381
427
|
logOverride: { 'direct-eval': 'silent' },
|
|
382
428
|
plugins,
|
|
383
429
|
});
|
package/dist/server-only.d.ts
CHANGED
|
@@ -52,6 +52,15 @@
|
|
|
52
52
|
* `packages/adapter/AGENTS.md` for the three outcomes the plugin must
|
|
53
53
|
* distinguish.
|
|
54
54
|
*/
|
|
55
|
+
/**
|
|
56
|
+
* The TCP drivers that are real npm packages (not `node:` builtins). A Node
|
|
57
|
+
* serverless function bundles statically-imported code, but a driver loaded
|
|
58
|
+
* through a variable `import(spec)` (e.g. `slintorm`'s `importDriver("pg")`)
|
|
59
|
+
* cannot be traced by the bundler or the platform's dependency tracer. Node
|
|
60
|
+
* targets ship these package closures into the function's `node_modules` so
|
|
61
|
+
* that dynamic import resolves at runtime.
|
|
62
|
+
*/
|
|
63
|
+
export declare function tcpDriverPackages(): string[];
|
|
55
64
|
export type ServerOnlyKind = 'server-only-package' | 'tcp-driver';
|
|
56
65
|
/**
|
|
57
66
|
* Classify a bare import specifier. Returns null for anything that is fine on
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server-only.d.ts","sourceRoot":"","sources":["../src/server-only.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqDG;AAsCH,MAAM,MAAM,cAAc,GAAG,qBAAqB,GAAG,YAAY,CAAC;AAElE;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI,CAMrE;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE3D;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE1D;AAED;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,KAAK,CAAC;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,GAAG,MAAM,CAkB5F;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,GAAE,CAAC,IAAI,EAAE,MAAM,KAAK,cAAc,GAAG,IAAwB,GAAG,MAAM,CAoBjI;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,cAAc,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,2DAA2D;IAC3D,IAAI,EAAE,MAAM,CAAC;IACb,uDAAuD;IACvD,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,2BAA2B;IAC3B,MAAM,EAAE,MAAM,CAAC;CAChB;AAWD;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,GAC3C,mBAAmB,EAAE,CA8BvB;AAYD;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,mBAAmB,EAAE,GAAG,KAAK,CAU7E;AAYD,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAGlH;AAMD,sDAAsD;AACtD,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,GAAE,MAAM,EAAO,GAAG,MAAM,EAAE,CAwB3E;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,mBAAmB,EAAE,CAUzE"}
|
|
1
|
+
{"version":3,"file":"server-only.d.ts","sourceRoot":"","sources":["../src/server-only.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqDG;AAsCH;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,EAAE,CAE5C;AAED,MAAM,MAAM,cAAc,GAAG,qBAAqB,GAAG,YAAY,CAAC;AAElE;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI,CAMrE;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE3D;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE1D;AAED;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,KAAK,CAAC;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,GAAG,MAAM,CAkB5F;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,GAAE,CAAC,IAAI,EAAE,MAAM,KAAK,cAAc,GAAG,IAAwB,GAAG,MAAM,CAoBjI;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,cAAc,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,2DAA2D;IAC3D,IAAI,EAAE,MAAM,CAAC;IACb,uDAAuD;IACvD,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,2BAA2B;IAC3B,MAAM,EAAE,MAAM,CAAC;CAChB;AAWD;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,GAC3C,mBAAmB,EAAE,CA8BvB;AAYD;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,mBAAmB,EAAE,GAAG,KAAK,CAU7E;AAYD,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAGlH;AAMD,sDAAsD;AACtD,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,GAAE,MAAM,EAAO,GAAG,MAAM,EAAE,CAwB3E;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,mBAAmB,EAAE,CAUzE"}
|
package/dist/server-only.js
CHANGED
|
@@ -85,6 +85,17 @@ const TCP_DRIVERS = new Set([
|
|
|
85
85
|
'node:net',
|
|
86
86
|
'node:tls',
|
|
87
87
|
]);
|
|
88
|
+
/**
|
|
89
|
+
* The TCP drivers that are real npm packages (not `node:` builtins). A Node
|
|
90
|
+
* serverless function bundles statically-imported code, but a driver loaded
|
|
91
|
+
* through a variable `import(spec)` (e.g. `slintorm`'s `importDriver("pg")`)
|
|
92
|
+
* cannot be traced by the bundler or the platform's dependency tracer. Node
|
|
93
|
+
* targets ship these package closures into the function's `node_modules` so
|
|
94
|
+
* that dynamic import resolves at runtime.
|
|
95
|
+
*/
|
|
96
|
+
export function tcpDriverPackages() {
|
|
97
|
+
return [...TCP_DRIVERS].filter((spec) => !spec.startsWith('node:'));
|
|
98
|
+
}
|
|
88
99
|
/**
|
|
89
100
|
* Classify a bare import specifier. Returns null for anything that is fine on
|
|
90
101
|
* the client — including a subpath of a listed package that is itself a
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vesk/adapter",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.94",
|
|
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.94",
|
|
27
|
+
"@vesk/runtime": "^0.2.94",
|
|
28
|
+
"@vesk/types": "^0.2.94"
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|
|
31
31
|
"@types/ws": "^8.18.1",
|