diff options
Diffstat (limited to 'runtime/js/11_workers.js')
-rw-r--r-- | runtime/js/11_workers.js | 128 |
1 files changed, 120 insertions, 8 deletions
diff --git a/runtime/js/11_workers.js b/runtime/js/11_workers.js index 62210dfae..db0bbc3c7 100644 --- a/runtime/js/11_workers.js +++ b/runtime/js/11_workers.js @@ -3,21 +3,24 @@ ((window) => { const core = window.Deno.core; const { Window } = window.__bootstrap.globalInterfaces; - const { log } = window.__bootstrap.util; + const { log, pathFromURL } = window.__bootstrap.util; const { defineEventHandler } = window.__bootstrap.webUtil; + const build = window.__bootstrap.build.build; function createWorker( specifier, hasSourceCode, sourceCode, useDenoNamespace, + permissions, name, ) { return core.jsonOpSync("op_create_worker", { - specifier, hasSourceCode, - sourceCode, name, + permissions, + sourceCode, + specifier, useDenoNamespace, }); } @@ -47,14 +50,122 @@ return JSON.parse(dataJson); } + /** + * @param {string} permission + * @return {boolean} + */ + function parseBooleanPermission( + value, + permission, + ) { + if (value !== "inherit" && typeof value !== "boolean") { + throw new Error( + `Expected 'boolean' for ${permission} permission, ${typeof value} received`, + ); + } + return value === "inherit" ? undefined : value; + } + + /** + * @param {string} permission + * @return {(boolean | string[])} + * */ + function parseArrayPermission( + value, + permission, + ) { + if (typeof value === "string") { + if (value !== "inherit") { + throw new Error( + `Expected 'array' or 'boolean' for ${permission} permission, "${value}" received`, + ); + } + } else if (!Array.isArray(value) && typeof value !== "boolean") { + throw new Error( + `Expected 'array' or 'boolean' for ${permission} permission, ${typeof value} received`, + ); + //Casts URLs to absolute routes + } else if (Array.isArray(value)) { + value = value.map((route) => { + if (route instanceof URL) { + route = pathFromURL(route); + } + return route; + }); + } + + return value === "inherit" ? undefined : value; + } + + /** + * Normalizes data, runs checks on parameters and deletes inherited permissions + */ + function parsePermissions({ + env = "inherit", + hrtime = "inherit", + net = "inherit", + plugin = "inherit", + read = "inherit", + run = "inherit", + write = "inherit", + }) { + return { + env: parseBooleanPermission(env, "env"), + hrtime: parseBooleanPermission(hrtime, "hrtime"), + net: parseArrayPermission(net, "net"), + plugin: parseBooleanPermission(plugin, "plugin"), + read: parseArrayPermission(read, "read"), + run: parseBooleanPermission(run, "run"), + write: parseArrayPermission(write, "write"), + }; + } + class Worker extends EventTarget { #id = 0; #name = ""; #terminated = false; - constructor(specifier, options) { + constructor(specifier, options = {}) { super(); - const { type = "classic", name = "unknown" } = options ?? {}; + const { + deno = {}, + name = "unknown", + type = "classic", + } = options; + + // TODO(Soremwar) + // `deno: true` is kept for backwards compatibility with the previous worker + // options implementation. Remove for 2.0 + let workerDenoAttributes; + if (deno === true) { + workerDenoAttributes = { + // Change this to enable the Deno namespace by default + namespace: deno, + permissions: null, + }; + } else { + workerDenoAttributes = { + // Change this to enable the Deno namespace by default + namespace: !!(deno?.namespace ?? false), + permissions: (deno?.permissions ?? "inherit") === "inherit" + ? null + : deno?.permissions, + }; + + // If the permission option is set to false, all permissions + // must be removed from the worker + if (workerDenoAttributes.permissions === false) { + workerDenoAttributes.permissions = { + env: false, + hrtime: false, + net: false, + plugin: false, + read: false, + run: false, + write: false, + }; + } + } if (type !== "module") { throw new Error( @@ -66,13 +177,14 @@ const hasSourceCode = false; const sourceCode = decoder.decode(new Uint8Array()); - const useDenoNamespace = options ? !!options.deno : false; - const { id } = createWorker( specifier, hasSourceCode, sourceCode, - useDenoNamespace, + workerDenoAttributes.namespace, + workerDenoAttributes.permissions === null + ? null + : parsePermissions(workerDenoAttributes.permissions), options?.name, ); this.#id = id; |