@vercel/node 2.4.3 → 2.5.0
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.js +27 -17
- package/dist/edge-wasm-plugin.d.ts +21 -0
- package/dist/edge-wasm-plugin.js +82 -0
- package/dist/index.js +3145 -2944
- package/package.json +7 -7
package/dist/dev-server.js
CHANGED
@@ -70,7 +70,7 @@ const static_config_1 = require("@vercel/static-config");
|
|
70
70
|
const ts_morph_1 = require("ts-morph");
|
71
71
|
const esbuild_1 = __importDefault(require("esbuild"));
|
72
72
|
const node_fetch_1 = __importDefault(require("node-fetch"));
|
73
|
-
const
|
73
|
+
const edge_wasm_plugin_1 = require("./edge-wasm-plugin");
|
74
74
|
function logError(error) {
|
75
75
|
console.error(error.message);
|
76
76
|
if (error.stack) {
|
@@ -126,24 +126,25 @@ async function serializeRequest(message) {
|
|
126
126
|
body,
|
127
127
|
});
|
128
128
|
}
|
129
|
-
async function compileUserCode(
|
129
|
+
async function compileUserCode(entrypointPath, entrypointLabel) {
|
130
|
+
const { wasmAssets, plugin: edgeWasmPlugin } = edge_wasm_plugin_1.createEdgeWasmPlugin();
|
130
131
|
try {
|
131
132
|
const result = await esbuild_1.default.build({
|
132
133
|
platform: 'node',
|
133
134
|
target: 'node14',
|
134
135
|
sourcemap: 'inline',
|
135
136
|
bundle: true,
|
136
|
-
|
137
|
+
plugins: [edgeWasmPlugin],
|
138
|
+
entryPoints: [entrypointPath],
|
137
139
|
write: false,
|
138
140
|
format: 'cjs',
|
139
141
|
});
|
140
142
|
const compiledFile = result.outputFiles?.[0];
|
141
143
|
if (!compiledFile) {
|
142
|
-
throw new Error(`Compilation of ${
|
144
|
+
throw new Error(`Compilation of ${entrypointLabel} produced no output files.`);
|
143
145
|
}
|
144
|
-
const userCode =
|
145
|
-
|
146
|
-
${userCode};
|
146
|
+
const userCode = `
|
147
|
+
${compiledFile.text};
|
147
148
|
|
148
149
|
addEventListener('fetch', async (event) => {
|
149
150
|
try {
|
@@ -173,6 +174,10 @@ async function compileUserCode(entrypoint) {
|
|
173
174
|
|
174
175
|
let response = await edgeHandler(event.request, event);
|
175
176
|
|
177
|
+
if (!response) {
|
178
|
+
throw new Error('Edge Function "${entrypointLabel}" did not return a response.');
|
179
|
+
}
|
180
|
+
|
176
181
|
return event.respondWith(response);
|
177
182
|
} catch (error) {
|
178
183
|
// we can't easily show a meaningful stack trace
|
@@ -185,6 +190,7 @@ async function compileUserCode(entrypoint) {
|
|
185
190
|
}));
|
186
191
|
}
|
187
192
|
})`;
|
193
|
+
return { userCode, wasmAssets };
|
188
194
|
}
|
189
195
|
catch (error) {
|
190
196
|
// We can't easily show a meaningful stack trace from ncc -> edge-runtime.
|
@@ -194,20 +200,24 @@ async function compileUserCode(entrypoint) {
|
|
194
200
|
return undefined;
|
195
201
|
}
|
196
202
|
}
|
197
|
-
async function createEdgeRuntime(
|
203
|
+
async function createEdgeRuntime(params) {
|
198
204
|
try {
|
199
|
-
if (!
|
205
|
+
if (!params) {
|
200
206
|
return undefined;
|
201
207
|
}
|
208
|
+
const wasmBindings = await params.wasmAssets.getContext();
|
202
209
|
const edgeRuntime = new edge_runtime_1.EdgeRuntime({
|
203
|
-
initialCode: userCode,
|
210
|
+
initialCode: params.userCode,
|
204
211
|
extend: (context) => {
|
205
212
|
Object.assign(context, {
|
206
213
|
__dirname: '',
|
207
214
|
module: {
|
208
215
|
exports: {},
|
209
216
|
},
|
210
|
-
|
217
|
+
process: {
|
218
|
+
env: process.env,
|
219
|
+
},
|
220
|
+
}, wasmBindings);
|
211
221
|
return context;
|
212
222
|
},
|
213
223
|
});
|
@@ -223,8 +233,8 @@ async function createEdgeRuntime(userCode) {
|
|
223
233
|
return undefined;
|
224
234
|
}
|
225
235
|
}
|
226
|
-
async function createEdgeEventHandler(
|
227
|
-
const userCode = await compileUserCode(
|
236
|
+
async function createEdgeEventHandler(entrypointPath, entrypointLabel) {
|
237
|
+
const userCode = await compileUserCode(entrypointPath, entrypointLabel);
|
228
238
|
const server = await createEdgeRuntime(userCode);
|
229
239
|
return async function (request) {
|
230
240
|
if (!server) {
|
@@ -266,15 +276,15 @@ function parseRuntime(entrypoint, entryPointPath) {
|
|
266
276
|
return runtime;
|
267
277
|
}
|
268
278
|
async function createEventHandler(entrypoint, config, options) {
|
269
|
-
const
|
270
|
-
const runtime = parseRuntime(entrypoint,
|
279
|
+
const entrypointPath = path_1.join(process.cwd(), entrypoint);
|
280
|
+
const runtime = parseRuntime(entrypoint, entrypointPath);
|
271
281
|
// `middleware.js`/`middleware.ts` file is always run as
|
272
282
|
// an Edge Function, otherwise needs to be opted-in via
|
273
283
|
// `export const config = { runtime: 'experimental-edge' }`
|
274
284
|
if (config.middleware === true || runtime === 'experimental-edge') {
|
275
|
-
return createEdgeEventHandler(
|
285
|
+
return createEdgeEventHandler(entrypointPath, entrypoint);
|
276
286
|
}
|
277
|
-
return createServerlessEventHandler(
|
287
|
+
return createServerlessEventHandler(entrypointPath, options);
|
278
288
|
}
|
279
289
|
let handleEvent;
|
280
290
|
let handlerEventError;
|
@@ -0,0 +1,21 @@
|
|
1
|
+
import type { Plugin } from 'esbuild';
|
2
|
+
export declare class WasmAssets {
|
3
|
+
private readonly assets;
|
4
|
+
/**
|
5
|
+
* Declare a WebAssembly binding
|
6
|
+
*/
|
7
|
+
declare(filePath: string): Promise<string>;
|
8
|
+
/**
|
9
|
+
* Get an object with the context needed to execute the code
|
10
|
+
* built with the plugin
|
11
|
+
*/
|
12
|
+
getContext(): Promise<Record<string, WebAssembly.Module>>;
|
13
|
+
/**
|
14
|
+
* Allow to iterate easily
|
15
|
+
*/
|
16
|
+
[Symbol.iterator](): IterableIterator<[string, string]>;
|
17
|
+
}
|
18
|
+
export declare function createEdgeWasmPlugin(): {
|
19
|
+
plugin: Plugin;
|
20
|
+
wasmAssets: WasmAssets;
|
21
|
+
};
|
@@ -0,0 +1,82 @@
|
|
1
|
+
"use strict";
|
2
|
+
// copied from `edge-functions-bridge`:
|
3
|
+
// https://github.com/vercel/runtimes/blob/c076db9e3ce5635f7c2690396e3d9f791a0fd808/packages/edge-functions-bridge/src/get-edge-function-source.ts#L282-L317
|
4
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
5
|
+
exports.createEdgeWasmPlugin = exports.WasmAssets = void 0;
|
6
|
+
const crypto_1 = require("crypto");
|
7
|
+
const fs_1 = require("fs");
|
8
|
+
class WasmAssets {
|
9
|
+
constructor() {
|
10
|
+
this.assets = new Map();
|
11
|
+
}
|
12
|
+
/**
|
13
|
+
* Declare a WebAssembly binding
|
14
|
+
*/
|
15
|
+
async declare(filePath) {
|
16
|
+
const hash = sha1(await fs_1.promises.readFile(filePath));
|
17
|
+
const name = `wasm_${hash}`;
|
18
|
+
this.assets.set(name, filePath);
|
19
|
+
return name;
|
20
|
+
}
|
21
|
+
/**
|
22
|
+
* Get an object with the context needed to execute the code
|
23
|
+
* built with the plugin
|
24
|
+
*/
|
25
|
+
async getContext() {
|
26
|
+
const promises = [];
|
27
|
+
const context = {};
|
28
|
+
for (const [name, filePath] of this.assets) {
|
29
|
+
promises.push((async () => {
|
30
|
+
const bytes = await fs_1.promises.readFile(filePath);
|
31
|
+
context[name] = await WebAssembly.compile(bytes);
|
32
|
+
})());
|
33
|
+
}
|
34
|
+
await Promise.all(promises);
|
35
|
+
return context;
|
36
|
+
}
|
37
|
+
/**
|
38
|
+
* Allow to iterate easily
|
39
|
+
*/
|
40
|
+
[Symbol.iterator]() {
|
41
|
+
return this.assets[Symbol.iterator]();
|
42
|
+
}
|
43
|
+
}
|
44
|
+
exports.WasmAssets = WasmAssets;
|
45
|
+
function createEdgeWasmPlugin() {
|
46
|
+
const wasmAssets = new WasmAssets();
|
47
|
+
const plugin = {
|
48
|
+
name: 'vercel-wasm',
|
49
|
+
setup(b) {
|
50
|
+
b.onResolve({ filter: /\.wasm\?module/i }, async (data) => {
|
51
|
+
const wasmFile = data.path.replace(/\?module$/, '');
|
52
|
+
const resolvedPath = await b.resolve(wasmFile, {
|
53
|
+
importer: data.importer,
|
54
|
+
resolveDir: data.resolveDir,
|
55
|
+
});
|
56
|
+
if (!resolvedPath.path) {
|
57
|
+
return {
|
58
|
+
errors: [
|
59
|
+
{ text: `WebAssembly file could not be located: ${wasmFile}` },
|
60
|
+
],
|
61
|
+
};
|
62
|
+
}
|
63
|
+
const name = await wasmAssets.declare(resolvedPath.path);
|
64
|
+
return {
|
65
|
+
path: name,
|
66
|
+
namespace: 'vercel-wasm',
|
67
|
+
};
|
68
|
+
});
|
69
|
+
b.onLoad({ namespace: 'vercel-wasm', filter: /.+/ }, args => {
|
70
|
+
return {
|
71
|
+
loader: 'js',
|
72
|
+
contents: `export default globalThis[${JSON.stringify(args.path)}]`,
|
73
|
+
};
|
74
|
+
});
|
75
|
+
},
|
76
|
+
};
|
77
|
+
return { plugin, wasmAssets };
|
78
|
+
}
|
79
|
+
exports.createEdgeWasmPlugin = createEdgeWasmPlugin;
|
80
|
+
function sha1(data) {
|
81
|
+
return crypto_1.createHash('sha1').update(data).digest('hex');
|
82
|
+
}
|