summaryrefslogtreecommitdiff
path: root/cli/js
diff options
context:
space:
mode:
Diffstat (limited to 'cli/js')
-rw-r--r--cli/js/compiler.ts2
-rw-r--r--cli/js/globals.ts11
-rw-r--r--cli/js/lib.deno_runtime.d.ts35
-rw-r--r--cli/js/worker_main.ts98
-rw-r--r--cli/js/workers.ts128
5 files changed, 144 insertions, 130 deletions
diff --git a/cli/js/compiler.ts b/cli/js/compiler.ts
index 79b9fdaf6..7addfc5ca 100644
--- a/cli/js/compiler.ts
+++ b/cli/js/compiler.ts
@@ -32,7 +32,7 @@ import { fromTypeScriptDiagnostic } from "./diagnostics_util.ts";
import * as os from "./os.ts";
import { assert } from "./util.ts";
import * as util from "./util.ts";
-import { postMessage, workerClose, workerMain } from "./workers.ts";
+import { postMessage, workerClose, workerMain } from "./worker_main.ts";
const self = globalThis;
diff --git a/cli/js/globals.ts b/cli/js/globals.ts
index 5754002c0..0f364b8e0 100644
--- a/cli/js/globals.ts
+++ b/cli/js/globals.ts
@@ -21,6 +21,7 @@ import * as textEncoding from "./text_encoding.ts";
import * as timers from "./timers.ts";
import * as url from "./url.ts";
import * as urlSearchParams from "./url_search_params.ts";
+import * as workerRuntime from "./worker_main.ts";
import * as workers from "./workers.ts";
import * as performanceUtil from "./performance.ts";
import * as request from "./request.ts";
@@ -194,12 +195,12 @@ const globalProperties = {
Response: nonEnumerable(fetchTypes.Response),
performance: writable(new performanceUtil.Performance()),
- onmessage: writable(workers.onmessage),
- onerror: writable(workers.onerror),
+ onmessage: writable(workerRuntime.onmessage),
+ onerror: writable(workerRuntime.onerror),
- workerMain: nonEnumerable(workers.workerMain),
- workerClose: nonEnumerable(workers.workerClose),
- postMessage: writable(workers.postMessage),
+ workerMain: nonEnumerable(workerRuntime.workerMain),
+ workerClose: nonEnumerable(workerRuntime.workerClose),
+ postMessage: writable(workerRuntime.postMessage),
Worker: nonEnumerable(workers.WorkerImpl),
[domTypes.eventTargetHost]: nonEnumerable(null),
diff --git a/cli/js/lib.deno_runtime.d.ts b/cli/js/lib.deno_runtime.d.ts
index 0fa183348..05553ffb7 100644
--- a/cli/js/lib.deno_runtime.d.ts
+++ b/cli/js/lib.deno_runtime.d.ts
@@ -2128,9 +2128,9 @@ declare interface Window {
performance: __performanceUtil.Performance;
onmessage: (e: { data: any }) => void;
onerror: undefined | typeof onerror;
- workerMain: typeof __workers.workerMain;
- workerClose: typeof __workers.workerClose;
- postMessage: typeof __workers.postMessage;
+ workerMain: typeof __workerMain.workerMain;
+ workerClose: typeof __workerMain.workerClose;
+ postMessage: typeof __workerMain.postMessage;
Worker: typeof __workers.WorkerImpl;
addEventListener: (
type: string,
@@ -2187,9 +2187,9 @@ declare let onerror:
e: Event
) => boolean | void)
| undefined;
-declare const workerMain: typeof __workers.workerMain;
-declare const workerClose: typeof __workers.workerClose;
-declare const postMessage: typeof __workers.postMessage;
+declare const workerMain: typeof __workerMain.workerMain;
+declare const workerClose: typeof __workerMain.workerClose;
+declare const postMessage: typeof __workerMain.postMessage;
declare const Worker: typeof __workers.WorkerImpl;
declare const addEventListener: (
type: string,
@@ -3437,31 +3437,25 @@ declare namespace __url {
};
}
-declare namespace __workers {
- // @url js/workers.d.ts
-
- export function encodeMessage(data: any): Uint8Array;
- export function decodeMessage(dataIntArray: Uint8Array): any;
+declare namespace __workerMain {
export let onmessage: (e: { data: any }) => void;
export function postMessage(data: any): void;
export function getMessage(): Promise<any>;
export let isClosing: boolean;
export function workerClose(): void;
export function workerMain(): Promise<void>;
+}
+
+declare namespace __workers {
+ // @url js/workers.d.ts
export interface Worker {
onerror?: (e: Event) => void;
onmessage?: (e: { data: any }) => void;
onmessageerror?: () => void;
postMessage(data: any): void;
- closed: Promise<void>;
}
- export interface WorkerOptions {}
- /** Extended Deno Worker initialization options.
- * `noDenoNamespace` hides global `window.Deno` namespace for
- * spawned worker and nested workers spawned by it (default: false).
- */
- export interface DenoWorkerOptions extends WorkerOptions {
- noDenoNamespace?: boolean;
+ export interface WorkerOptions {
+ type?: "classic" | "module";
}
export class WorkerImpl implements Worker {
private readonly id;
@@ -3470,8 +3464,7 @@ declare namespace __workers {
onerror?: (e: Event) => void;
onmessage?: (data: any) => void;
onmessageerror?: () => void;
- constructor(specifier: string, options?: DenoWorkerOptions);
- readonly closed: Promise<void>;
+ constructor(specifier: string, options?: WorkerOptions);
postMessage(data: any): void;
private run;
}
diff --git a/cli/js/worker_main.ts b/cli/js/worker_main.ts
new file mode 100644
index 000000000..cb70057ea
--- /dev/null
+++ b/cli/js/worker_main.ts
@@ -0,0 +1,98 @@
+// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
+/* eslint-disable @typescript-eslint/no-explicit-any */
+import { core } from "./core.ts";
+import * as dispatch from "./dispatch.ts";
+import { sendAsync, sendSync } from "./dispatch_json.ts";
+import { log } from "./util.ts";
+import { TextDecoder, TextEncoder } from "./text_encoding.ts";
+
+const encoder = new TextEncoder();
+const decoder = new TextDecoder();
+
+function encodeMessage(data: any): Uint8Array {
+ const dataJson = JSON.stringify(data);
+ return encoder.encode(dataJson);
+}
+
+function decodeMessage(dataIntArray: Uint8Array): any {
+ const dataJson = decoder.decode(dataIntArray);
+ return JSON.parse(dataJson);
+}
+
+// Stuff for workers
+export const onmessage: (e: { data: any }) => void = (): void => {};
+export const onerror: (e: { data: any }) => void = (): void => {};
+
+export function postMessage(data: any): void {
+ const dataIntArray = encodeMessage(data);
+ sendSync(dispatch.OP_WORKER_POST_MESSAGE, {}, dataIntArray);
+}
+
+export async function getMessage(): Promise<any> {
+ log("getMessage");
+ const res = await sendAsync(dispatch.OP_WORKER_GET_MESSAGE);
+ if (res.data != null) {
+ return decodeMessage(new Uint8Array(res.data));
+ } else {
+ return null;
+ }
+}
+
+export let isClosing = false;
+
+export function workerClose(): void {
+ isClosing = true;
+}
+
+export async function workerMain(): Promise<void> {
+ const ops = core.ops();
+ // TODO(bartlomieju): this is a prototype, we should come up with
+ // something a bit more sophisticated
+ for (const [name, opId] of Object.entries(ops)) {
+ const opName = `OP_${name.toUpperCase()}`;
+ // Assign op ids to actual variables
+ // TODO(ry) This type casting is gross and should be fixed.
+ ((dispatch as unknown) as { [key: string]: number })[opName] = opId;
+ core.setAsyncHandler(opId, dispatch.getAsyncHandler(opName));
+ }
+
+ log("workerMain");
+
+ while (!isClosing) {
+ const data = await getMessage();
+ if (data == null) {
+ log("workerMain got null message. quitting.");
+ break;
+ }
+
+ let result: void | Promise<void>;
+ const event = { data };
+
+ try {
+ if (!globalThis["onmessage"]) {
+ break;
+ }
+ result = globalThis.onmessage!(event);
+ if (result && "then" in result) {
+ await result;
+ }
+ if (!globalThis["onmessage"]) {
+ break;
+ }
+ } catch (e) {
+ if (globalThis["onerror"]) {
+ const result = globalThis.onerror(
+ e.message,
+ e.fileName,
+ e.lineNumber,
+ e.columnNumber,
+ e
+ );
+ if (result === true) {
+ continue;
+ }
+ }
+ throw e;
+ }
+ }
+}
diff --git a/cli/js/workers.ts b/cli/js/workers.ts
index 7e8219e19..60ef73da0 100644
--- a/cli/js/workers.ts
+++ b/cli/js/workers.ts
@@ -2,35 +2,35 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import * as dispatch from "./dispatch.ts";
import { sendAsync, sendSync } from "./dispatch_json.ts";
-import { log, createResolvable, Resolvable } from "./util.ts";
+import { log } from "./util.ts";
import { TextDecoder, TextEncoder } from "./text_encoding.ts";
+/*
import { blobURLMap } from "./url.ts";
import { blobBytesWeakMap } from "./blob.ts";
+*/
import { Event } from "./event.ts";
import { EventTarget } from "./event_target.ts";
const encoder = new TextEncoder();
const decoder = new TextDecoder();
-export function encodeMessage(data: any): Uint8Array {
+function encodeMessage(data: any): Uint8Array {
const dataJson = JSON.stringify(data);
return encoder.encode(dataJson);
}
-export function decodeMessage(dataIntArray: Uint8Array): any {
+function decodeMessage(dataIntArray: Uint8Array): any {
const dataJson = decoder.decode(dataIntArray);
return JSON.parse(dataJson);
}
function createWorker(
specifier: string,
- includeDenoNamespace: boolean,
hasSourceCode: boolean,
sourceCode: Uint8Array
): { id: number; loaded: boolean } {
return sendSync(dispatch.OP_CREATE_WORKER, {
specifier,
- includeDenoNamespace,
hasSourceCode,
sourceCode: new TextDecoder().decode(sourceCode)
});
@@ -67,92 +67,15 @@ async function hostGetMessage(id: number): Promise<any> {
}
}
-// Stuff for workers
-export const onmessage: (e: { data: any }) => void = (): void => {};
-export const onerror: (e: { data: any }) => void = (): void => {};
-
-export function postMessage(data: any): void {
- const dataIntArray = encodeMessage(data);
- sendSync(dispatch.OP_WORKER_POST_MESSAGE, {}, dataIntArray);
-}
-
-export async function getMessage(): Promise<any> {
- log("getMessage");
- const res = await sendAsync(dispatch.OP_WORKER_GET_MESSAGE);
- if (res.data != null) {
- return decodeMessage(new Uint8Array(res.data));
- } else {
- return null;
- }
-}
-
-export let isClosing = false;
-
-export function workerClose(): void {
- isClosing = true;
-}
-
-export async function workerMain(): Promise<void> {
- log("workerMain");
-
- while (!isClosing) {
- const data = await getMessage();
- if (data == null) {
- log("workerMain got null message. quitting.");
- break;
- }
-
- let result: void | Promise<void>;
- const event = { data };
-
- try {
- if (!globalThis["onmessage"]) {
- break;
- }
- result = globalThis.onmessage!(event);
- if (result && "then" in result) {
- await result;
- }
- if (!globalThis["onmessage"]) {
- break;
- }
- } catch (e) {
- if (globalThis["onerror"]) {
- const result = globalThis.onerror(
- e.message,
- e.fileName,
- e.lineNumber,
- e.columnNumber,
- e
- );
- if (result === true) {
- continue;
- }
- }
- throw e;
- }
- }
-}
-
export interface Worker {
onerror?: (e: any) => void;
onmessage?: (e: { data: any }) => void;
onmessageerror?: () => void;
postMessage(data: any): void;
- // TODO(bartlomieju): remove this
- closed: Promise<void>;
}
-// TODO(kevinkassimo): Maybe implement reasonable web worker options?
-// eslint-disable-next-line @typescript-eslint/no-empty-interface
-export interface WorkerOptions {}
-
-/** Extended Deno Worker initialization options.
- * `noDenoNamespace` hides global `globalThis.Deno` namespace for
- * spawned worker and nested workers spawned by it (default: false).
- */
-export interface DenoWorkerOptions extends WorkerOptions {
- noDenoNamespace?: boolean;
+export interface WorkerOptions {
+ type?: "classic" | "module";
}
export class WorkerImpl extends EventTarget implements Worker {
@@ -160,20 +83,29 @@ export class WorkerImpl extends EventTarget implements Worker {
private isClosing = false;
private messageBuffer: any[] = [];
private ready = false;
- private readonly isClosedPromise: Resolvable<void>;
public onerror?: (e: any) => void;
public onmessage?: (data: any) => void;
public onmessageerror?: () => void;
- constructor(specifier: string, options?: DenoWorkerOptions) {
+ constructor(specifier: string, options?: WorkerOptions) {
super();
- let hasSourceCode = false;
- let sourceCode = new Uint8Array();
- let includeDenoNamespace = true;
- if (options && options.noDenoNamespace) {
- includeDenoNamespace = false;
+ let type = "classic";
+
+ if (options?.type) {
+ type = options.type;
+ }
+
+ if (type !== "module") {
+ throw new Error(
+ 'Not yet implemented: only "module" type workers are supported'
+ );
}
+
+ const hasSourceCode = false;
+ const sourceCode = new Uint8Array();
+
+ /* TODO(bartlomieju):
// Handle blob URL.
if (specifier.startsWith("blob:")) {
hasSourceCode = true;
@@ -187,23 +119,14 @@ export class WorkerImpl extends EventTarget implements Worker {
}
sourceCode = blobBytes!;
}
+ */
- const { id, loaded } = createWorker(
- specifier,
- includeDenoNamespace,
- hasSourceCode,
- sourceCode
- );
+ const { id, loaded } = createWorker(specifier, hasSourceCode, sourceCode);
this.id = id;
this.ready = loaded;
- this.isClosedPromise = createResolvable();
this.poll();
}
- get closed(): Promise<void> {
- return this.isClosedPromise;
- }
-
private handleError(e: any): boolean {
// TODO: this is being handled in a type unsafe way, it should be type safe
// eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -259,7 +182,6 @@ export class WorkerImpl extends EventTarget implements Worker {
} else {
this.isClosing = true;
hostCloseWorker(this.id);
- this.isClosedPromise.resolve();
break;
}
}