Skip to content

Commit c02cf13

Browse files
authored
Support webassembly instantiate streaming (#431)
* Allow loadPolicy to accept a PromiseLike<Response> or Response to be able to use WebAssembly.instantiateStreaming over WebAssembly.instantiate internally Signed-off-by: Eric Tucker <[email protected]> * Only accept promise instead of Promise for streaming Signed-off-by: Eric Tucker <[email protected]>
1 parent f94e758 commit c02cf13

File tree

2 files changed

+27
-6
lines changed

2 files changed

+27
-6
lines changed

src/opa.js

+11-6
Original file line numberDiff line numberDiff line change
@@ -262,18 +262,23 @@ function _preparePolicy(env, wasm, memory) {
262262
* It will return a Promise, depending on the input type the promise
263263
* resolves to both a compiled WebAssembly.Module and its first WebAssembly.Instance
264264
* or to the WebAssemblyInstance.
265-
* @param {BufferSource | WebAssembly.Module} policyWasm
265+
* @param {BufferSource | WebAssembly.Module | Response | Promise<Response>} policyWasm
266266
* @param {WebAssembly.Memory} memory
267267
* @param {{ [builtinName: string]: Function }} customBuiltins
268268
* @returns {Promise<{ policy: WebAssembly.WebAssemblyInstantiatedSource | WebAssembly.Instance, minorVersion: number }>}
269269
*/
270270
async function _loadPolicy(policyWasm, memory, customBuiltins) {
271271
const env = {};
272272

273-
const wasm = await WebAssembly.instantiate(
274-
policyWasm,
275-
_importObject(env, memory, customBuiltins),
276-
);
273+
const isStreaming = policyWasm instanceof Response ||
274+
policyWasm instanceof Promise;
275+
276+
const importObject = _importObject(env, memory, customBuiltins);
277+
278+
const wasm =
279+
await (isStreaming
280+
? WebAssembly.instantiateStreaming(policyWasm, importObject)
281+
: WebAssembly.instantiate(policyWasm, importObject));
277282

278283
return _preparePolicy(env, wasm, memory);
279284
}
@@ -460,7 +465,7 @@ module.exports = {
460465
* To set custom memory size specify number of memory pages
461466
* as second param.
462467
* Defaults to 5 pages (320KB).
463-
* @param {BufferSource | WebAssembly.Module} regoWasm
468+
* @param {BufferSource | WebAssembly.Module | Response | Promise<Response>} regoWasm
464469
* @param {number | WebAssembly.MemoryDescriptor} memoryDescriptor For backwards-compatibility, a 'number' argument is taken to be the initial memory size.
465470
* @param {{ [builtinName: string]: Function }} customBuiltins A map from string names to builtin functions
466471
* @returns {Promise<LoadedPolicy>}

test/browser-integration.test.js

+16
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,22 @@ test("esm script should expose working opa module", async () => {
4141
]);
4242
});
4343

44+
test("loadPolicy should allow for a response object that resolves to a fetched wasm module", async () => {
45+
const result = await page.evaluate(async function () {
46+
// NOTE: Paths are evaluated relative to the project root.
47+
const { default: opa } = await import("/dist/opa-wasm-browser.esm.js");
48+
const policy = await opa.loadPolicy(
49+
fetch("/test/fixtures/multiple-entrypoints/policy.wasm"),
50+
);
51+
return policy.evaluate({}, "example/one");
52+
});
53+
expect(result).toEqual([
54+
{
55+
result: { myOtherRule: false, myRule: false },
56+
},
57+
]);
58+
});
59+
4460
test("default script should expose working opa global", async () => {
4561
// Load module into global scope.
4662
const script = fs.readFileSync(

0 commit comments

Comments
 (0)