• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1'use strict';
2
3const {
4  PromiseResolve,
5} = primordials;
6const {
7  ERR_INVALID_ARG_TYPE,
8  ERR_WEBASSEMBLY_RESPONSE,
9} = require('internal/errors').codes;
10
11let undici;
12function lazyUndici() {
13  return undici ??= require('internal/deps/undici/undici');
14}
15
16// This is essentially an implementation of a v8::WasmStreamingCallback, except
17// that it is implemented in JavaScript because the fetch() implementation is
18// difficult to use from C++. See lib/internal/process/pre_execution.js and
19// src/node_wasm_web_api.cc that interact with this function.
20function wasmStreamingCallback(streamState, source) {
21  (async () => {
22    const response = await PromiseResolve(source);
23    if (!(response instanceof lazyUndici().Response)) {
24      throw new ERR_INVALID_ARG_TYPE(
25        'source', ['Response', 'Promise resolving to Response'], response);
26    }
27
28    const contentType = response.headers.get('Content-Type');
29    if (contentType !== 'application/wasm') {
30      throw new ERR_WEBASSEMBLY_RESPONSE(
31        `has unsupported MIME type '${contentType}'`);
32    }
33
34    if (!response.ok) {
35      throw new ERR_WEBASSEMBLY_RESPONSE(
36        `has status code ${response.status}`);
37    }
38
39    if (response.bodyUsed !== false) {
40      throw new ERR_WEBASSEMBLY_RESPONSE('body has already been used');
41    }
42
43    if (response.url) {
44      streamState.setURL(response.url);
45    }
46
47    // Pass all data from the response body to the WebAssembly compiler.
48    const { body } = response;
49    if (body != null) {
50      for await (const chunk of body) {
51        streamState.push(chunk);
52      }
53    }
54  })().then(() => {
55    // No error occurred. Tell the implementation that the stream has ended.
56    streamState.finish();
57  }, (err) => {
58    // An error occurred, either because the given object was not a valid
59    // and usable Response or because a network error occurred.
60    streamState.abort(err);
61  });
62}
63
64module.exports = {
65  wasmStreamingCallback,
66};
67