webassembly-loader-sw
Version:
Webpack loader for WebAssembly (like wasm-loader but have different export options)
156 lines (146 loc) • 4.85 kB
JavaScript
;
Object.defineProperty(exports, '__esModule', { value: true });
function _interopDefault(ex) {
return ex && typeof ex === 'object' && 'default' in ex ? ex['default'] : ex;
}
var path = require('path');
var typescriptJsonSchema = require('typescript-json-schema');
var loaderUtils = require('loader-utils');
var validate = _interopDefault(require('schema-utils'));
var compilerOptions = {
moduleResolution: 'node',
target: 'esnext',
module: 'commonjs',
lib: ['esnext'],
strict: true,
skipLibCheck: true,
allowSyntheticDefaultImports: true,
experimentalDecorators: true,
emitDecoratorMetadata: true,
outDir: 'dist',
typeRoots: ['node_modules/@types'],
resolveJsonModule: true,
allowJs: true
};
var include = ['src', 'test'];
var exclude = ['node_modules', 'examples'];
var tsconfig = {
compilerOptions: compilerOptions,
include: include,
exclude: exclude
};
// bear in mind this is ran from dist
const program = typescriptJsonSchema.getProgramFromFiles(
[path.resolve(__dirname, '../types/options.d.ts')],
tsconfig.compilerOptions,
path.resolve(__dirname, '..')
);
const schema = typescriptJsonSchema.generateSchema(
program,
'WebAssemblyLoaderOptions',
{
noExtraProps: true
}
);
const createImportObject = options => {
return `{
env: {
memory: new WebAssembly.Memory(${JSON.stringify(
options.memoryDescriptor
)}),
table: new WebAssembly.Table(${JSON.stringify(options.tableDescriptor)})
},
${options.importObjectProps}
}`;
};
// {
// './cardano_multiplatform_lib_bg.js': __webpack_require__("../../node_modules/@dcspark/cardano-multiplatform-lib-browser/cardano_multiplatform_lib_bg.js"),
// }
/** Wrap binary data as commonjs module so it can be imported by doing require(module)
* @param buffer raw binary data to be wrapped as es6 module
* @return chainable object which represent `wrap this data as...`
* @example return wrap(arrayBuffer).asWebAssembly.Module
*/
function wrap(buffer, options) {
const data = buffer.toJSON().data.toString();
let exportString = 'module.exports ='; // if (module === 'cjs')
if (options.module === 'esm') exportString = 'export default';
return {
asBuffer: `${exportString} Buffer.from([${data}])`,
asWebAssembly: {
Module: `${exportString} new WebAssembly.Module(
Buffer.from([${data}])
)`,
Instance: `${exportString} new WebAssembly.Instance(
new WebAssembly.Module(
Buffer.from([${data}])
),
${createImportObject(options)}
).exports`
},
promiseWebAssembly: {
Module: `${exportString} () => WebAssembly.compile(
Buffer.from([${data}])
)`,
Instance: `${exportString} importObject => WebAssembly.instantiate(
new WebAssembly.Module(Buffer.from([${data}])),
importObject
)`,
Both: `${exportString} importObject => WebAssembly.instantiate(
Buffer.from([${data}]), importObject
)`
}
};
}
function panic(message, cb) {
if (cb) cb(message);
else throw new Error(message);
}
//#endregion
/** Transform WebAssembly binary into JS module
* @param source - WebAssembly Buffer
* @param options - what type of export you want to generate
* @return string of the code
* @example const code = wasm2js(Buffer.from([0x00, 0x61, 0x73, 0x6d, 0x01, 0, 0, 0]), 'instance')
*/
function wasm2js(source, options) {
if (WebAssembly.validate(source) === false)
panic('Invalid WebAssembly file', options.errorHandler);
switch (options.export) {
case 'buffer':
return wrap(source, options).asBuffer;
case 'instance':
return wrap(source, options).asWebAssembly.Instance;
case 'module':
return wrap(source, options).asWebAssembly.Module;
case 'async':
return wrap(source, options).promiseWebAssembly.Both;
case 'async-instance':
return wrap(source, options).promiseWebAssembly.Instance;
case 'async-module':
return wrap(source, options).promiseWebAssembly.Module;
default:
throw new Error(`exporting as "${options.export}" not available`);
}
}
const defaultOptions = {
export: 'async'
};
module.exports = function(source) {
const options = loaderUtils.getOptions(this) || defaultOptions;
validate(schema, options, 'webassembly-loader');
// if (options.export === 'buffer') return source; /*🤔*/
return wasm2js(source, {
export: options.export,
module: 'cjs',
errorHandler: errMsg => this.emitError(errMsg),
memoryDescriptor: options.memoryDescriptor || { initial: 64 },
tableDescriptor: options.tableDescriptor || {
initial: 0,
element: 'anyfunc'
},
importObjectProps: options.importObjectProps || ''
});
};
module.exports.raw = true;
exports.default = wasm2js;