summaryrefslogtreecommitdiff
path: root/runtime/js
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/js')
-rw-r--r--runtime/js/11_workers.js31
-rw-r--r--runtime/js/99_main.js46
2 files changed, 66 insertions, 11 deletions
diff --git a/runtime/js/11_workers.js b/runtime/js/11_workers.js
index b5a8a9d0c..2f9413119 100644
--- a/runtime/js/11_workers.js
+++ b/runtime/js/11_workers.js
@@ -7,7 +7,6 @@
ArrayIsArray,
ArrayPrototypeMap,
Error,
- Uint8Array,
StringPrototypeStartsWith,
String,
SymbolIterator,
@@ -28,6 +27,7 @@
useDenoNamespace,
permissions,
name,
+ workerType,
) {
return core.opSync("op_create_worker", {
hasSourceCode,
@@ -36,6 +36,7 @@
sourceCode,
specifier,
useDenoNamespace,
+ workerType,
});
}
@@ -183,20 +184,12 @@
}
}
- if (type !== "module") {
- throw new Error(
- 'Not yet implemented: only "module" type workers are supported',
- );
- }
-
- this.#name = name;
- const hasSourceCode = false;
- const sourceCode = core.decode(new Uint8Array());
+ const workerType = webidl.converters["WorkerType"](type);
if (
StringPrototypeStartsWith(specifier, "./") ||
StringPrototypeStartsWith(specifier, "../") ||
- StringPrototypeStartsWith(specifier, "/") || type == "classic"
+ StringPrototypeStartsWith(specifier, "/") || workerType === "classic"
) {
const baseUrl = getLocationHref();
if (baseUrl != null) {
@@ -204,6 +197,16 @@
}
}
+ this.#name = name;
+ let hasSourceCode, sourceCode;
+ if (workerType === "classic") {
+ hasSourceCode = true;
+ sourceCode = `importScripts("#");`;
+ } else {
+ hasSourceCode = false;
+ sourceCode = "";
+ }
+
const id = createWorker(
specifier,
hasSourceCode,
@@ -213,6 +216,7 @@
? null
: parsePermissions(workerDenoAttributes.permissions),
options?.name,
+ workerType,
);
this.#id = id;
this.#pollControl();
@@ -344,6 +348,11 @@
defineEventHandler(Worker.prototype, "message");
defineEventHandler(Worker.prototype, "messageerror");
+ webidl.converters["WorkerType"] = webidl.createEnumConverter("WorkerType", [
+ "classic",
+ "module",
+ ]);
+
window.__bootstrap.worker = {
parsePermissions,
Worker,
diff --git a/runtime/js/99_main.js b/runtime/js/99_main.js
index 6d5599e71..b1f7d1473 100644
--- a/runtime/js/99_main.js
+++ b/runtime/js/99_main.js
@@ -8,6 +8,7 @@ delete Object.prototype.__proto__;
((window) => {
const core = Deno.core;
const {
+ ArrayPrototypeMap,
Error,
FunctionPrototypeCall,
FunctionPrototypeBind,
@@ -164,6 +165,44 @@ delete Object.prototype.__proto__;
}
}
+ let loadedMainWorkerScript = false;
+
+ function importScripts(...urls) {
+ if (core.opSync("op_worker_get_type") === "module") {
+ throw new TypeError("Can't import scripts in a module worker.");
+ }
+
+ const baseUrl = location.getLocationHref();
+ const parsedUrls = ArrayPrototypeMap(urls, (scriptUrl) => {
+ try {
+ return new url.URL(scriptUrl, baseUrl ?? undefined).href;
+ } catch {
+ throw new domException.DOMException(
+ "Failed to parse URL.",
+ "SyntaxError",
+ );
+ }
+ });
+
+ // A classic worker's main script has looser MIME type checks than any
+ // imported scripts, so we use `loadedMainWorkerScript` to distinguish them.
+ // TODO(andreubotella) Refactor worker creation so the main script isn't
+ // loaded with `importScripts()`.
+ const scripts = core.opSync(
+ "op_worker_sync_fetch",
+ parsedUrls,
+ !loadedMainWorkerScript,
+ );
+ loadedMainWorkerScript = true;
+
+ for (const { url, script } of scripts) {
+ const err = core.evalContext(script, url)[1];
+ if (err !== null) {
+ throw err.thrown;
+ }
+ }
+ }
+
function opMainModule() {
return core.opSync("op_main_module");
}
@@ -597,6 +636,13 @@ delete Object.prototype.__proto__;
}
ObjectDefineProperties(globalThis, workerRuntimeGlobalProperties);
ObjectDefineProperties(globalThis, { name: util.readOnly(name) });
+ if (runtimeOptions.enableTestingFeaturesFlag) {
+ ObjectDefineProperty(
+ globalThis,
+ "importScripts",
+ util.writable(importScripts),
+ );
+ }
ObjectSetPrototypeOf(globalThis, DedicatedWorkerGlobalScope.prototype);
const consoleFromDeno = globalThis.console;