'use strict'; const { PromiseResolve, } = primordials; const { ERR_INVALID_ARG_TYPE, ERR_WEBASSEMBLY_RESPONSE, } = require('internal/errors').codes; let undici; function lazyUndici() { return undici ??= require('internal/deps/undici/undici'); } // This is essentially an implementation of a v8::WasmStreamingCallback, except // that it is implemented in JavaScript because the fetch() implementation is // difficult to use from C++. See lib/internal/process/pre_execution.js and // src/node_wasm_web_api.cc that interact with this function. function wasmStreamingCallback(streamState, source) { (async () => { const response = await PromiseResolve(source); if (!(response instanceof lazyUndici().Response)) { throw new ERR_INVALID_ARG_TYPE( 'source', ['Response', 'Promise resolving to Response'], response); } const contentType = response.headers.get('Content-Type'); if (contentType !== 'application/wasm') { throw new ERR_WEBASSEMBLY_RESPONSE( `has unsupported MIME type '${contentType}'`); } if (!response.ok) { throw new ERR_WEBASSEMBLY_RESPONSE( `has status code ${response.status}`); } if (response.bodyUsed !== false) { throw new ERR_WEBASSEMBLY_RESPONSE('body has already been used'); } if (response.url) { streamState.setURL(response.url); } // Pass all data from the response body to the WebAssembly compiler. const { body } = response; if (body != null) { for await (const chunk of body) { streamState.push(chunk); } } })().then(() => { // No error occurred. Tell the implementation that the stream has ended. streamState.finish(); }, (err) => { // An error occurred, either because the given object was not a valid // and usable Response or because a network error occurred. streamState.abort(err); }); } module.exports = { wasmStreamingCallback, };