11cb0ef41Sopenharmony_ci'use strict'; 21cb0ef41Sopenharmony_ci 31cb0ef41Sopenharmony_ciconst { 41cb0ef41Sopenharmony_ci PromiseResolve, 51cb0ef41Sopenharmony_ci} = primordials; 61cb0ef41Sopenharmony_ciconst { 71cb0ef41Sopenharmony_ci ERR_INVALID_ARG_TYPE, 81cb0ef41Sopenharmony_ci ERR_WEBASSEMBLY_RESPONSE, 91cb0ef41Sopenharmony_ci} = require('internal/errors').codes; 101cb0ef41Sopenharmony_ci 111cb0ef41Sopenharmony_cilet undici; 121cb0ef41Sopenharmony_cifunction lazyUndici() { 131cb0ef41Sopenharmony_ci return undici ??= require('internal/deps/undici/undici'); 141cb0ef41Sopenharmony_ci} 151cb0ef41Sopenharmony_ci 161cb0ef41Sopenharmony_ci// This is essentially an implementation of a v8::WasmStreamingCallback, except 171cb0ef41Sopenharmony_ci// that it is implemented in JavaScript because the fetch() implementation is 181cb0ef41Sopenharmony_ci// difficult to use from C++. See lib/internal/process/pre_execution.js and 191cb0ef41Sopenharmony_ci// src/node_wasm_web_api.cc that interact with this function. 201cb0ef41Sopenharmony_cifunction wasmStreamingCallback(streamState, source) { 211cb0ef41Sopenharmony_ci (async () => { 221cb0ef41Sopenharmony_ci const response = await PromiseResolve(source); 231cb0ef41Sopenharmony_ci if (!(response instanceof lazyUndici().Response)) { 241cb0ef41Sopenharmony_ci throw new ERR_INVALID_ARG_TYPE( 251cb0ef41Sopenharmony_ci 'source', ['Response', 'Promise resolving to Response'], response); 261cb0ef41Sopenharmony_ci } 271cb0ef41Sopenharmony_ci 281cb0ef41Sopenharmony_ci const contentType = response.headers.get('Content-Type'); 291cb0ef41Sopenharmony_ci if (contentType !== 'application/wasm') { 301cb0ef41Sopenharmony_ci throw new ERR_WEBASSEMBLY_RESPONSE( 311cb0ef41Sopenharmony_ci `has unsupported MIME type '${contentType}'`); 321cb0ef41Sopenharmony_ci } 331cb0ef41Sopenharmony_ci 341cb0ef41Sopenharmony_ci if (!response.ok) { 351cb0ef41Sopenharmony_ci throw new ERR_WEBASSEMBLY_RESPONSE( 361cb0ef41Sopenharmony_ci `has status code ${response.status}`); 371cb0ef41Sopenharmony_ci } 381cb0ef41Sopenharmony_ci 391cb0ef41Sopenharmony_ci if (response.bodyUsed !== false) { 401cb0ef41Sopenharmony_ci throw new ERR_WEBASSEMBLY_RESPONSE('body has already been used'); 411cb0ef41Sopenharmony_ci } 421cb0ef41Sopenharmony_ci 431cb0ef41Sopenharmony_ci if (response.url) { 441cb0ef41Sopenharmony_ci streamState.setURL(response.url); 451cb0ef41Sopenharmony_ci } 461cb0ef41Sopenharmony_ci 471cb0ef41Sopenharmony_ci // Pass all data from the response body to the WebAssembly compiler. 481cb0ef41Sopenharmony_ci const { body } = response; 491cb0ef41Sopenharmony_ci if (body != null) { 501cb0ef41Sopenharmony_ci for await (const chunk of body) { 511cb0ef41Sopenharmony_ci streamState.push(chunk); 521cb0ef41Sopenharmony_ci } 531cb0ef41Sopenharmony_ci } 541cb0ef41Sopenharmony_ci })().then(() => { 551cb0ef41Sopenharmony_ci // No error occurred. Tell the implementation that the stream has ended. 561cb0ef41Sopenharmony_ci streamState.finish(); 571cb0ef41Sopenharmony_ci }, (err) => { 581cb0ef41Sopenharmony_ci // An error occurred, either because the given object was not a valid 591cb0ef41Sopenharmony_ci // and usable Response or because a network error occurred. 601cb0ef41Sopenharmony_ci streamState.abort(err); 611cb0ef41Sopenharmony_ci }); 621cb0ef41Sopenharmony_ci} 631cb0ef41Sopenharmony_ci 641cb0ef41Sopenharmony_cimodule.exports = { 651cb0ef41Sopenharmony_ci wasmStreamingCallback, 661cb0ef41Sopenharmony_ci}; 67