@vercel/node 2.4.5 → 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.
@@ -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 util_1 = require("util");
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) {
@@ -127,12 +127,14 @@ async function serializeRequest(message) {
127
127
  });
128
128
  }
129
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,
137
+ plugins: [edgeWasmPlugin],
136
138
  entryPoints: [entrypointPath],
137
139
  write: false,
138
140
  format: 'cjs',
@@ -141,9 +143,8 @@ async function compileUserCode(entrypointPath, entrypointLabel) {
141
143
  if (!compiledFile) {
142
144
  throw new Error(`Compilation of ${entrypointLabel} produced no output files.`);
143
145
  }
144
- const userCode = new util_1.TextDecoder().decode(compiledFile.contents);
145
- return `
146
- ${userCode};
146
+ const userCode = `
147
+ ${compiledFile.text};
147
148
 
148
149
  addEventListener('fetch', async (event) => {
149
150
  try {
@@ -189,6 +190,7 @@ async function compileUserCode(entrypointPath, entrypointLabel) {
189
190
  }));
190
191
  }
191
192
  })`;
193
+ return { userCode, wasmAssets };
192
194
  }
193
195
  catch (error) {
194
196
  // We can't easily show a meaningful stack trace from ncc -> edge-runtime.
@@ -198,13 +200,14 @@ async function compileUserCode(entrypointPath, entrypointLabel) {
198
200
  return undefined;
199
201
  }
200
202
  }
201
- async function createEdgeRuntime(userCode) {
203
+ async function createEdgeRuntime(params) {
202
204
  try {
203
- if (!userCode) {
205
+ if (!params) {
204
206
  return undefined;
205
207
  }
208
+ const wasmBindings = await params.wasmAssets.getContext();
206
209
  const edgeRuntime = new edge_runtime_1.EdgeRuntime({
207
- initialCode: userCode,
210
+ initialCode: params.userCode,
208
211
  extend: (context) => {
209
212
  Object.assign(context, {
210
213
  __dirname: '',
@@ -214,7 +217,7 @@ async function createEdgeRuntime(userCode) {
214
217
  process: {
215
218
  env: process.env,
216
219
  },
217
- });
220
+ }, wasmBindings);
218
221
  return context;
219
222
  },
220
223
  });
@@ -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
+ }