summaryrefslogtreecommitdiff
path: root/cli
diff options
context:
space:
mode:
Diffstat (limited to 'cli')
-rw-r--r--cli/build.rs17
-rw-r--r--cli/compilers/mod.rs1
-rw-r--r--cli/compilers/ts.rs14
-rw-r--r--cli/global_state.rs10
-rw-r--r--cli/js.rs6
-rw-r--r--cli/js/compiler.ts4
-rw-r--r--cli/js/compiler_bootstrap.ts24
-rw-r--r--cli/js/compiler_host.ts4
-rw-r--r--cli/js/globals.ts2
-rw-r--r--cli/js/lib.deno.ns.d.ts (renamed from cli/js/lib.deno.d.ts)0
-rw-r--r--cli/js/lib.deno.shared_globals.d.ts (renamed from cli/js/lib.deno_main.d.ts)260
-rw-r--r--cli/js/lib.deno.window.d.ts214
-rw-r--r--cli/js/lib.deno.worker.d.ts45
-rw-r--r--cli/js/lib.deno_worker.d.ts5
-rw-r--r--cli/js/runtime_worker.ts5
-rw-r--r--cli/js/workers.ts19
-rw-r--r--cli/lib.rs10
-rw-r--r--cli/ops/worker_host.rs19
-rw-r--r--cli/state.rs46
-rw-r--r--cli/tests/026_workers.ts10
-rw-r--r--cli/tests/subdir/bench_worker.ts2
-rw-r--r--cli/tests/subdir/test_worker.js7
-rw-r--r--cli/tests/subdir/test_worker.ts6
-rw-r--r--cli/tests/types.out6
24 files changed, 449 insertions, 287 deletions
diff --git a/cli/build.rs b/cli/build.rs
index b57b86b91..426403f1a 100644
--- a/cli/build.rs
+++ b/cli/build.rs
@@ -71,14 +71,21 @@ fn main() {
let snapshot_path = o.join("COMPILER_SNAPSHOT.bin");
let mut custom_libs: HashMap<String, PathBuf> = HashMap::new();
custom_libs.insert(
- "lib.deno_main.d.ts".to_string(),
- c.join("js/lib.deno_main.d.ts"),
+ "lib.deno.window.d.ts".to_string(),
+ c.join("js/lib.deno.window.d.ts"),
);
custom_libs.insert(
- "lib.deno_worker.d.ts".to_string(),
- c.join("js/lib.deno_worker.d.ts"),
+ "lib.deno.worker.d.ts".to_string(),
+ c.join("js/lib.deno.worker.d.ts"),
+ );
+ custom_libs.insert(
+ "lib.deno.shared_globals.d.ts".to_string(),
+ c.join("js/lib.deno.shared_globals.d.ts"),
+ );
+ custom_libs.insert(
+ "lib.deno.ns.d.ts".to_string(),
+ c.join("js/lib.deno.ns.d.ts"),
);
- custom_libs.insert("lib.deno.d.ts".to_string(), c.join("js/lib.deno.d.ts"));
let main_module_name =
deno_typescript::compile_bundle(&bundle_path, root_names)
diff --git a/cli/compilers/mod.rs b/cli/compilers/mod.rs
index f4aac3681..a2abbe2aa 100644
--- a/cli/compilers/mod.rs
+++ b/cli/compilers/mod.rs
@@ -13,6 +13,7 @@ pub use js::JsCompiler;
pub use json::JsonCompiler;
pub use ts::runtime_compile_async;
pub use ts::runtime_transpile_async;
+pub use ts::TargetLib;
pub use ts::TsCompiler;
pub use wasm::WasmCompiler;
diff --git a/cli/compilers/ts.rs b/cli/compilers/ts.rs
index 946617fa5..5aa299518 100644
--- a/cli/compilers/ts.rs
+++ b/cli/compilers/ts.rs
@@ -37,6 +37,12 @@ lazy_static! {
Regex::new(r#""checkJs"\s*?:\s*?true"#).unwrap();
}
+#[derive(Clone, Copy)]
+pub enum TargetLib {
+ Main,
+ Worker,
+}
+
/// Struct which represents the state of the compiler
/// configuration where the first is canonical name for the configuration file,
/// second is a vector of the bytes of the contents of the configuration file,
@@ -318,6 +324,7 @@ impl TsCompiler {
&self,
global_state: ThreadSafeGlobalState,
source_file: &SourceFile,
+ target: TargetLib,
) -> Pin<Box<CompiledModuleFuture>> {
if self.has_compiled(&source_file.url) {
return match self.get_compiled_module(&source_file.url) {
@@ -360,7 +367,10 @@ impl TsCompiler {
&source_file.url
);
- let target = "main";
+ let target = match target {
+ TargetLib::Main => "main",
+ TargetLib::Worker => "worker",
+ };
let root_names = vec![module_url.to_string()];
let req_msg = req(
@@ -710,7 +720,7 @@ mod tests {
let fut = async move {
let result = mock_state
.ts_compiler
- .compile_async(mock_state.clone(), &out)
+ .compile_async(mock_state.clone(), &out, TargetLib::Main)
.await;
assert!(result.is_ok());
diff --git a/cli/global_state.rs b/cli/global_state.rs
index 1709a3429..3298799d1 100644
--- a/cli/global_state.rs
+++ b/cli/global_state.rs
@@ -2,6 +2,7 @@
use crate::compilers::CompiledModule;
use crate::compilers::JsCompiler;
use crate::compilers::JsonCompiler;
+use crate::compilers::TargetLib;
use crate::compilers::TsCompiler;
use crate::compilers::WasmCompiler;
use crate::deno_dir;
@@ -122,6 +123,7 @@ impl ThreadSafeGlobalState {
&self,
module_specifier: &ModuleSpecifier,
maybe_referrer: Option<ModuleSpecifier>,
+ target_lib: TargetLib,
) -> impl Future<Output = Result<CompiledModule, ErrBox>> {
let state1 = self.clone();
let state2 = self.clone();
@@ -141,11 +143,15 @@ impl ThreadSafeGlobalState {
msg::MediaType::TypeScript
| msg::MediaType::TSX
| msg::MediaType::JSX => {
- state1.ts_compiler.compile_async(state1.clone(), &out)
+ state1
+ .ts_compiler
+ .compile_async(state1.clone(), &out, target_lib)
}
msg::MediaType::JavaScript => {
if state1.ts_compiler.compile_js {
- state1.ts_compiler.compile_async(state1.clone(), &out)
+ state1
+ .ts_compiler
+ .compile_async(state1.clone(), &out, target_lib)
} else {
state1.js_compiler.compile_async(&out)
}
diff --git a/cli/js.rs b/cli/js.rs
index 2e9adf1b4..746e49fe4 100644
--- a/cli/js.rs
+++ b/cli/js.rs
@@ -16,8 +16,10 @@ pub static COMPILER_SNAPSHOT_MAP: &[u8] =
pub static COMPILER_SNAPSHOT_DTS: &[u8] =
include_bytes!(concat!(env!("OUT_DIR"), "/COMPILER_SNAPSHOT.d.ts"));
-pub static DENO_NS_LIB: &str = include_str!("js/lib.deno.d.ts");
-pub static DENO_MAIN_LIB: &str = include_str!("js/lib.deno_main.d.ts");
+pub static DENO_NS_LIB: &str = include_str!("js/lib.deno.ns.d.ts");
+pub static SHARED_GLOBALS_LIB: &str =
+ include_str!("js/lib.deno.shared_globals.d.ts");
+pub static WINDOW_LIB: &str = include_str!("js/lib.deno.window.d.ts");
#[test]
fn cli_snapshot() {
diff --git a/cli/js/compiler.ts b/cli/js/compiler.ts
index 394c6cf52..f003d7d0b 100644
--- a/cli/js/compiler.ts
+++ b/cli/js/compiler.ts
@@ -304,7 +304,7 @@ async function tsCompilerOnMessage({
}
// The compiler isolate exits after a single message.
- globalThis.workerClose();
+ globalThis.close();
}
async function wasmCompilerOnMessage({
@@ -332,7 +332,7 @@ async function wasmCompilerOnMessage({
util.log("<<< WASM compile end");
// The compiler isolate exits after a single message.
- globalThis.workerClose();
+ globalThis.close();
}
function bootstrapTsCompilerRuntime(): void {
diff --git a/cli/js/compiler_bootstrap.ts b/cli/js/compiler_bootstrap.ts
index afb3d2be5..585aec016 100644
--- a/cli/js/compiler_bootstrap.ts
+++ b/cli/js/compiler_bootstrap.ts
@@ -15,17 +15,27 @@ const options = host.getCompilationSettings();
// This is a hacky way of adding our libs to the libs available in TypeScript()
// as these are internal APIs of TypeScript which maintain valid libs
/* eslint-disable @typescript-eslint/no-explicit-any */
-(ts as any).libs.push("deno_main", "deno_worker", "deno");
-(ts as any).libMap.set("deno_main", "lib.deno_main.d.ts");
-(ts as any).libMap.set("deno_worker", "lib.deno_worker.d.ts");
-(ts as any).libMap.set("deno", "lib.deno.d.ts");
+(ts as any).libs.push(
+ "deno_ns",
+ "deno_window",
+ "deno_worker",
+ "deno_shared_globals"
+);
+(ts as any).libMap.set("deno_ns", "lib.deno.ns.d.ts");
+(ts as any).libMap.set("deno_window", "lib.deno.window.d.ts");
+(ts as any).libMap.set("deno_worker", "lib.deno.worker.d.ts");
+(ts as any).libMap.set("deno_shared_globals", "lib.deno.shared_globals.d.ts");
/* eslint-enable @typescript-eslint/no-explicit-any */
// this pre-populates the cache at snapshot time of our library files, so they
// are available in the future when needed.
-host.getSourceFile(`${ASSETS}/lib.deno_main.d.ts`, ts.ScriptTarget.ESNext);
-host.getSourceFile(`${ASSETS}/lib.deno_worker.d.ts`, ts.ScriptTarget.ESNext);
-host.getSourceFile(`${ASSETS}/lib.deno.d.ts`, ts.ScriptTarget.ESNext);
+host.getSourceFile(`${ASSETS}/lib.deno.ns.d.ts`, ts.ScriptTarget.ESNext);
+host.getSourceFile(`${ASSETS}/lib.deno.window.d.ts`, ts.ScriptTarget.ESNext);
+host.getSourceFile(`${ASSETS}/lib.deno.worker.d.ts`, ts.ScriptTarget.ESNext);
+host.getSourceFile(
+ `${ASSETS}/lib.deno.shared_globals.d.ts`,
+ ts.ScriptTarget.ESNext
+);
/**
* This function spins up TS compiler and loads all available libraries
diff --git a/cli/js/compiler_host.ts b/cli/js/compiler_host.ts
index 619ce702a..291f6fbc5 100644
--- a/cli/js/compiler_host.ts
+++ b/cli/js/compiler_host.ts
@@ -233,9 +233,9 @@ export class Host implements ts.CompilerHost {
switch (this._target) {
case CompilerHostTarget.Main:
case CompilerHostTarget.Runtime:
- return `${ASSETS}/lib.deno_main.d.ts`;
+ return `${ASSETS}/lib.deno.window.d.ts`;
case CompilerHostTarget.Worker:
- return `${ASSETS}/lib.deno_worker.d.ts`;
+ return `${ASSETS}/lib.deno.worker.d.ts`;
}
}
diff --git a/cli/js/globals.ts b/cli/js/globals.ts
index e6c1e855c..7cce739d5 100644
--- a/cli/js/globals.ts
+++ b/cli/js/globals.ts
@@ -132,7 +132,7 @@ declare global {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
var onmessage: ((e: { data: any }) => Promise<void> | void) | undefined;
// Called in compiler
- var workerClose: () => void;
+ var close: () => void;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
var postMessage: (msg: any) => void;
// Assigned to `self` global - compiler
diff --git a/cli/js/lib.deno.d.ts b/cli/js/lib.deno.ns.d.ts
index 0fa6f008c..0fa6f008c 100644
--- a/cli/js/lib.deno.d.ts
+++ b/cli/js/lib.deno.ns.d.ts
diff --git a/cli/js/lib.deno_main.d.ts b/cli/js/lib.deno.shared_globals.d.ts
index 52b6fb7f5..c8dfc833d 100644
--- a/cli/js/lib.deno_main.d.ts
+++ b/cli/js/lib.deno.shared_globals.d.ts
@@ -3,23 +3,23 @@
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-interface, @typescript-eslint/no-explicit-any */
/// <reference no-default-lib="true" />
-/// <reference lib="deno" />
+/// <reference lib="deno_ns" />
/// <reference lib="esnext" />
-declare interface Window {
- window: Window & typeof globalThis;
+// https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope
+
+declare interface WindowOrWorkerGlobalScope {
+ // methods
atob: typeof __textEncoding.atob;
btoa: typeof __textEncoding.btoa;
- fetch: typeof __fetch.fetch;
- clearTimeout: typeof __timers.clearTimeout;
clearInterval: typeof __timers.clearInterval;
- console: __console.Console;
- setTimeout: typeof __timers.setTimeout;
+ clearTimeout: typeof __timers.clearTimeout;
+ fetch: typeof __fetch.fetch;
+ queueMicrotask: (task: () => void) => void;
setInterval: typeof __timers.setInterval;
- location: __domTypes.Location;
- onload: Function | undefined;
- onunload: Function | undefined;
- crypto: Crypto;
+ setTimeout: typeof __timers.setTimeout;
+ // properties
+ console: __console.Console;
Blob: typeof __blob.DenoBlob;
File: __domTypes.DomFileConstructor;
CustomEvent: typeof __customEvent.CustomEvent;
@@ -34,11 +34,9 @@ declare interface Window {
Request: __domTypes.RequestConstructor;
Response: typeof __fetch.Response;
performance: __performanceUtil.Performance;
- onmessage: (e: { data: any }) => void;
- onerror: undefined | typeof onerror;
- workerClose: typeof __workerMain.workerClose;
- postMessage: typeof __workerMain.postMessage;
Worker: typeof __workers.WorkerImpl;
+ location: __domTypes.Location;
+
addEventListener: (
type: string,
callback: (event: __domTypes.Event) => void | null,
@@ -50,23 +48,17 @@ declare interface Window {
callback: (event: __domTypes.Event) => void | null,
options?: boolean | __domTypes.EventListenerOptions | undefined
) => void;
- queueMicrotask: (task: () => void) => void;
- Deno: typeof Deno;
}
-declare const window: Window & typeof globalThis;
declare const atob: typeof __textEncoding.atob;
declare const btoa: typeof __textEncoding.btoa;
-declare const fetch: typeof __fetch.fetch;
-declare const clearTimeout: typeof __timers.clearTimeout;
declare const clearInterval: typeof __timers.clearInterval;
-declare const console: __console.Console;
-declare const setTimeout: typeof __timers.setTimeout;
+declare const clearTimeout: typeof __timers.clearTimeout;
+declare const fetch: typeof __fetch.fetch;
declare const setInterval: typeof __timers.setInterval;
-declare const location: __domTypes.Location;
-declare const onload: Function | undefined;
-declare const onunload: Function | undefined;
-declare const crypto: Crypto;
+declare const setTimeout: typeof __timers.setTimeout;
+
+declare const console: __console.Console;
declare const Blob: typeof __blob.DenoBlob;
declare const File: __domTypes.DomFileConstructor;
declare const CustomEventInit: typeof __customEvent.CustomEventInit;
@@ -78,25 +70,15 @@ declare const EventTarget: typeof __eventTarget.EventTarget;
declare const URL: typeof __url.URL;
declare const URLSearchParams: typeof __urlSearchParams.URLSearchParams;
declare const Headers: __domTypes.HeadersConstructor;
+declare const location: __domTypes.Location;
declare const FormData: __domTypes.FormDataConstructor;
declare const TextEncoder: typeof __textEncoding.TextEncoder;
declare const TextDecoder: typeof __textEncoding.TextDecoder;
declare const Request: __domTypes.RequestConstructor;
declare const Response: typeof __fetch.Response;
declare const performance: __performanceUtil.Performance;
-declare let onmessage: ((e: { data: any }) => Promise<void> | void) | undefined;
-declare let onerror:
- | ((
- msg: string,
- source: string,
- lineno: number,
- colno: number,
- e: Event
- ) => boolean | void)
- | undefined;
-declare const workerClose: typeof __workerMain.workerClose;
-declare const postMessage: typeof __workerMain.postMessage;
declare const Worker: typeof __workers.WorkerImpl;
+
declare const addEventListener: (
type: string,
callback: (event: __domTypes.Event) => void | null,
@@ -133,198 +115,6 @@ declare interface ImportMeta {
main: boolean;
}
-declare interface Crypto {
- readonly subtle: null;
- getRandomValues<
- T extends
- | Int8Array
- | Int16Array
- | Int32Array
- | Uint8Array
- | Uint16Array
- | Uint32Array
- | Uint8ClampedArray
- | Float32Array
- | Float64Array
- | DataView
- | null
- >(
- array: T
- ): T;
-}
-
-// This follows the WebIDL at: https://webassembly.github.io/spec/js-api/
-// and: https://webassembly.github.io/spec/web-api/
-
-declare namespace WebAssembly {
- interface WebAssemblyInstantiatedSource {
- module: Module;
- instance: Instance;
- }
-
- /** Compiles a `WebAssembly.Module` from WebAssembly binary code. This
- * function is useful if it is necessary to a compile a module before it can
- * be instantiated (otherwise, the `WebAssembly.instantiate()` function
- * should be used). */
- function compile(bufferSource: __domTypes.BufferSource): Promise<Module>;
-
- /** Compiles a `WebAssembly.Module` directly from a streamed underlying
- * source. This function is useful if it is necessary to a compile a module
- * before it can be instantiated (otherwise, the
- * `WebAssembly.instantiateStreaming()` function should be used). */
- function compileStreaming(
- source: Promise<__domTypes.Response>
- ): Promise<Module>;
-
- /** Takes the WebAssembly binary code, in the form of a typed array or
- * `ArrayBuffer`, and performs both compilation and instantiation in one step.
- * The returned `Promise` resolves to both a compiled `WebAssembly.Module` and
- * its first `WebAssembly.Instance`. */
- function instantiate(
- bufferSource: __domTypes.BufferSource,
- importObject?: object
- ): Promise<WebAssemblyInstantiatedSource>;
-
- /** Takes an already-compiled `WebAssembly.Module` and returns a `Promise`
- * that resolves to an `Instance` of that `Module`. This overload is useful if
- * the `Module` has already been compiled. */
- function instantiate(
- module: Module,
- importObject?: object
- ): Promise<Instance>;
-
- /** Compiles and instantiates a WebAssembly module directly from a streamed
- * underlying source. This is the most efficient, optimized way to load wasm
- * code. */
- function instantiateStreaming(
- source: Promise<__domTypes.Response>,
- importObject?: object
- ): Promise<WebAssemblyInstantiatedSource>;
-
- /** Validates a given typed array of WebAssembly binary code, returning
- * whether the bytes form a valid wasm module (`true`) or not (`false`). */
- function validate(bufferSource: __domTypes.BufferSource): boolean;
-
- type ImportExportKind = "function" | "table" | "memory" | "global";
-
- interface ModuleExportDescriptor {
- name: string;
- kind: ImportExportKind;
- }
- interface ModuleImportDescriptor {
- module: string;
- name: string;
- kind: ImportExportKind;
- }
-
- class Module {
- constructor(bufferSource: __domTypes.BufferSource);
-
- /** Given a `Module` and string, returns a copy of the contents of all
- * custom sections in the module with the given string name. */
- static customSections(
- moduleObject: Module,
- sectionName: string
- ): ArrayBuffer;
-
- /** Given a `Module`, returns an array containing descriptions of all the
- * declared exports. */
- static exports(moduleObject: Module): ModuleExportDescriptor[];
-
- /** Given a `Module`, returns an array containing descriptions of all the
- * declared imports. */
- static imports(moduleObject: Module): ModuleImportDescriptor[];
- }
-
- class Instance<T extends object = { [key: string]: any }> {
- constructor(module: Module, importObject?: object);
-
- /** An object containing as its members all the functions exported from the
- * WebAssembly module instance, to allow them to be accessed and used by
- * JavaScript. */
- readonly exports: T;
- }
-
- interface MemoryDescriptor {
- initial: number;
- maximum?: number;
- }
-
- class Memory {
- constructor(descriptor: MemoryDescriptor);
-
- /** An accessor property that returns the buffer contained in the memory. */
- readonly buffer: ArrayBuffer;
-
- /** Increases the size of the memory instance by a specified number of
- * WebAssembly pages (each one is 64KB in size). */
- grow(delta: number): number;
- }
-
- type TableKind = "anyfunc";
-
- interface TableDescriptor {
- element: TableKind;
- initial: number;
- maximum?: number;
- }
-
- class Table {
- constructor(descriptor: TableDescriptor);
-
- /** Returns the length of the table, i.e. the number of elements. */
- readonly length: number;
-
- /** Accessor function — gets the element stored at a given index. */
- get(index: number): (...args: any[]) => any;
-
- /** Increases the size of the Table instance by a specified number of
- * elements. */
- grow(delta: number): number;
-
- /** Sets an element stored at a given index to a given value. */
- set(index: number, value: (...args: any[]) => any): void;
- }
-
- type ValueType = "i32" | "i64" | "f32" | "f64";
-
- interface GlobalDescriptor {
- value: ValueType;
- mutable?: boolean;
- }
-
- /** Represents a global variable instance, accessible from both JavaScript and
- * importable/exportable across one or more `WebAssembly.Module` instances.
- * This allows dynamic linking of multiple modules. */
- class Global {
- constructor(descriptor: GlobalDescriptor, value?: any);
-
- /** Old-style method that returns the value contained inside the global
- * variable. */
- valueOf(): any;
-
- /** The value contained inside the global variable — this can be used to
- * directly set and get the global's value. */
- value: any;
- }
-
- /** Indicates an error during WebAssembly decoding or validation */
- class CompileError extends Error {
- constructor(message: string, fileName?: string, lineNumber?: string);
- }
-
- /** Indicates an error during module instantiation (besides traps from the
- * start function). */
- class LinkError extends Error {
- constructor(message: string, fileName?: string, lineNumber?: string);
- }
-
- /** Is thrown whenever WebAssembly specifies a trap. */
- class RuntimeError extends Error {
- constructor(message: string, fileName?: string, lineNumber?: string);
- }
-}
-
declare namespace __domTypes {
// @url js/dom_types.d.ts
@@ -1519,13 +1309,6 @@ declare namespace __url {
};
}
-declare namespace __workerMain {
- export let onmessage: (e: { data: any }) => void;
- export function postMessage(data: any): void;
- export function getMessage(): Promise<any>;
- export function workerClose(): void;
-}
-
declare namespace __workers {
// @url js/workers.d.ts
export interface Worker {
@@ -1533,9 +1316,11 @@ declare namespace __workers {
onmessage?: (e: { data: any }) => void;
onmessageerror?: () => void;
postMessage(data: any): void;
+ terminate(): void;
}
export interface WorkerOptions {
type?: "classic" | "module";
+ name?: string;
}
export class WorkerImpl implements Worker {
private readonly id;
@@ -1546,6 +1331,7 @@ declare namespace __workers {
onmessageerror?: () => void;
constructor(specifier: string, options?: WorkerOptions);
postMessage(data: any): void;
+ terminate(): void;
private run;
}
}
diff --git a/cli/js/lib.deno.window.d.ts b/cli/js/lib.deno.window.d.ts
new file mode 100644
index 000000000..d4dc08acb
--- /dev/null
+++ b/cli/js/lib.deno.window.d.ts
@@ -0,0 +1,214 @@
+// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
+
+/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-interface, @typescript-eslint/no-explicit-any */
+
+/// <reference no-default-lib="true" />
+/// <reference lib="deno_ns" />
+/// <reference lib="deno_shared_globals" />
+/// <reference lib="esnext" />
+
+declare interface Window extends WindowOrWorkerGlobalScope {
+ window: Window & WindowOrWorkerGlobalScope & typeof globalThis;
+ onload: Function | undefined;
+ onunload: Function | undefined;
+ crypto: Crypto;
+ Deno: typeof Deno;
+}
+
+declare const window: Window & WindowOrWorkerGlobalScope & typeof globalThis;
+declare const onload: Function | undefined;
+declare const onunload: Function | undefined;
+declare const crypto: Crypto;
+
+declare interface Crypto {
+ readonly subtle: null;
+ getRandomValues<
+ T extends
+ | Int8Array
+ | Int16Array
+ | Int32Array
+ | Uint8Array
+ | Uint16Array
+ | Uint32Array
+ | Uint8ClampedArray
+ | Float32Array
+ | Float64Array
+ | DataView
+ | null
+ >(
+ array: T
+ ): T;
+}
+
+// This follows the WebIDL at: https://webassembly.github.io/spec/js-api/
+// and: https://webassembly.github.io/spec/web-api/
+
+declare namespace WebAssembly {
+ interface WebAssemblyInstantiatedSource {
+ module: Module;
+ instance: Instance;
+ }
+
+ /** Compiles a `WebAssembly.Module` from WebAssembly binary code. This
+ * function is useful if it is necessary to a compile a module before it can
+ * be instantiated (otherwise, the `WebAssembly.instantiate()` function
+ * should be used). */
+ function compile(bufferSource: __domTypes.BufferSource): Promise<Module>;
+
+ /** Compiles a `WebAssembly.Module` directly from a streamed underlying
+ * source. This function is useful if it is necessary to a compile a module
+ * before it can be instantiated (otherwise, the
+ * `WebAssembly.instantiateStreaming()` function should be used). */
+ function compileStreaming(
+ source: Promise<__domTypes.Response>
+ ): Promise<Module>;
+
+ /** Takes the WebAssembly binary code, in the form of a typed array or
+ * `ArrayBuffer`, and performs both compilation and instantiation in one step.
+ * The returned `Promise` resolves to both a compiled `WebAssembly.Module` and
+ * its first `WebAssembly.Instance`. */
+ function instantiate(
+ bufferSource: __domTypes.BufferSource,
+ importObject?: object
+ ): Promise<WebAssemblyInstantiatedSource>;
+
+ /** Takes an already-compiled `WebAssembly.Module` and returns a `Promise`
+ * that resolves to an `Instance` of that `Module`. This overload is useful if
+ * the `Module` has already been compiled. */
+ function instantiate(
+ module: Module,
+ importObject?: object
+ ): Promise<Instance>;
+
+ /** Compiles and instantiates a WebAssembly module directly from a streamed
+ * underlying source. This is the most efficient, optimized way to load wasm
+ * code. */
+ function instantiateStreaming(
+ source: Promise<__domTypes.Response>,
+ importObject?: object
+ ): Promise<WebAssemblyInstantiatedSource>;
+
+ /** Validates a given typed array of WebAssembly binary code, returning
+ * whether the bytes form a valid wasm module (`true`) or not (`false`). */
+ function validate(bufferSource: __domTypes.BufferSource): boolean;
+
+ type ImportExportKind = "function" | "table" | "memory" | "global";
+
+ interface ModuleExportDescriptor {
+ name: string;
+ kind: ImportExportKind;
+ }
+ interface ModuleImportDescriptor {
+ module: string;
+ name: string;
+ kind: ImportExportKind;
+ }
+
+ class Module {
+ constructor(bufferSource: __domTypes.BufferSource);
+
+ /** Given a `Module` and string, returns a copy of the contents of all
+ * custom sections in the module with the given string name. */
+ static customSections(
+ moduleObject: Module,
+ sectionName: string
+ ): ArrayBuffer;
+
+ /** Given a `Module`, returns an array containing descriptions of all the
+ * declared exports. */
+ static exports(moduleObject: Module): ModuleExportDescriptor[];
+
+ /** Given a `Module`, returns an array containing descriptions of all the
+ * declared imports. */
+ static imports(moduleObject: Module): ModuleImportDescriptor[];
+ }
+
+ class Instance<T extends object = { [key: string]: any }> {
+ constructor(module: Module, importObject?: object);
+
+ /** An object containing as its members all the functions exported from the
+ * WebAssembly module instance, to allow them to be accessed and used by
+ * JavaScript. */
+ readonly exports: T;
+ }
+
+ interface MemoryDescriptor {
+ initial: number;
+ maximum?: number;
+ }
+
+ class Memory {
+ constructor(descriptor: MemoryDescriptor);
+
+ /** An accessor property that returns the buffer contained in the memory. */
+ readonly buffer: ArrayBuffer;
+
+ /** Increases the size of the memory instance by a specified number of
+ * WebAssembly pages (each one is 64KB in size). */
+ grow(delta: number): number;
+ }
+
+ type TableKind = "anyfunc";
+
+ interface TableDescriptor {
+ element: TableKind;
+ initial: number;
+ maximum?: number;
+ }
+
+ class Table {
+ constructor(descriptor: TableDescriptor);
+
+ /** Returns the length of the table, i.e. the number of elements. */
+ readonly length: number;
+
+ /** Accessor function — gets the element stored at a given index. */
+ get(index: number): (...args: any[]) => any;
+
+ /** Increases the size of the Table instance by a specified number of
+ * elements. */
+ grow(delta: number): number;
+
+ /** Sets an element stored at a given index to a given value. */
+ set(index: number, value: (...args: any[]) => any): void;
+ }
+
+ type ValueType = "i32" | "i64" | "f32" | "f64";
+
+ interface GlobalDescriptor {
+ value: ValueType;
+ mutable?: boolean;
+ }
+
+ /** Represents a global variable instance, accessible from both JavaScript and
+ * importable/exportable across one or more `WebAssembly.Module` instances.
+ * This allows dynamic linking of multiple modules. */
+ class Global {
+ constructor(descriptor: GlobalDescriptor, value?: any);
+
+ /** Old-style method that returns the value contained inside the global
+ * variable. */
+ valueOf(): any;
+
+ /** The value contained inside the global variable — this can be used to
+ * directly set and get the global's value. */
+ value: any;
+ }
+
+ /** Indicates an error during WebAssembly decoding or validation */
+ class CompileError extends Error {
+ constructor(message: string, fileName?: string, lineNumber?: string);
+ }
+
+ /** Indicates an error during module instantiation (besides traps from the
+ * start function). */
+ class LinkError extends Error {
+ constructor(message: string, fileName?: string, lineNumber?: string);
+ }
+
+ /** Is thrown whenever WebAssembly specifies a trap. */
+ class RuntimeError extends Error {
+ constructor(message: string, fileName?: string, lineNumber?: string);
+ }
+}
+/* eslint-enable @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-interface, @typescript-eslint/no-explicit-any */
diff --git a/cli/js/lib.deno.worker.d.ts b/cli/js/lib.deno.worker.d.ts
new file mode 100644
index 000000000..07955345c
--- /dev/null
+++ b/cli/js/lib.deno.worker.d.ts
@@ -0,0 +1,45 @@
+// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
+
+/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-interface, @typescript-eslint/no-explicit-any */
+
+/// <reference no-default-lib="true" />
+/// <reference lib="deno_shared_globals" />
+/// <reference lib="esnext" />
+
+declare interface DedicatedWorkerGlobalScope extends WindowOrWorkerGlobalScope {
+ self: DedicatedWorkerGlobalScope &
+ WindowOrWorkerGlobalScope &
+ typeof globalThis;
+ onmessage: (e: { data: any }) => void;
+ onerror: undefined | typeof onerror;
+ name: typeof __workerMain.name;
+ close: typeof __workerMain.close;
+ postMessage: typeof __workerMain.postMessage;
+}
+
+declare const self: DedicatedWorkerGlobalScope &
+ WindowOrWorkerGlobalScope &
+ typeof globalThis;
+declare let onmessage: ((e: { data: any }) => Promise<void> | void) | undefined;
+declare let onerror:
+ | ((
+ msg: string,
+ source: string,
+ lineno: number,
+ colno: number,
+ e: Event
+ ) => boolean | void)
+ | undefined;
+declare const close: typeof __workerMain.close;
+declare const name: typeof __workerMain.name;
+declare const postMessage: typeof __workerMain.postMessage;
+
+declare namespace __workerMain {
+ export let onmessage: (e: { data: any }) => void;
+ export function postMessage(data: any): void;
+ export function getMessage(): Promise<any>;
+ export function close(): void;
+ export const name: string;
+}
+
+/* eslint-enable @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-interface, @typescript-eslint/no-explicit-any */
diff --git a/cli/js/lib.deno_worker.d.ts b/cli/js/lib.deno_worker.d.ts
deleted file mode 100644
index d7652807d..000000000
--- a/cli/js/lib.deno_worker.d.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
-
-/// <reference no-default-lib="true" />
-/// <reference lib="deno" />
-/// <reference lib="webworker" />
diff --git a/cli/js/runtime_worker.ts b/cli/js/runtime_worker.ts
index 7f1d1b69c..0dc65fdb6 100644
--- a/cli/js/runtime_worker.ts
+++ b/cli/js/runtime_worker.ts
@@ -54,7 +54,7 @@ export async function getMessage(): Promise<any> {
let isClosing = false;
let hasBootstrapped = false;
-export function workerClose(): void {
+export function close(): void {
isClosing = true;
}
@@ -102,7 +102,7 @@ export const workerRuntimeGlobalProperties = {
self: readOnly(globalThis),
onmessage: writable(onmessage),
onerror: writable(onerror),
- workerClose: nonEnumerable(workerClose),
+ close: nonEnumerable(close),
postMessage: writable(postMessage)
};
@@ -122,5 +122,6 @@ export function bootstrapWorkerRuntime(name: string): void {
Object.defineProperties(globalThis, windowOrWorkerGlobalScopeProperties);
Object.defineProperties(globalThis, workerRuntimeGlobalProperties);
Object.defineProperties(globalThis, eventTargetProperties);
+ Object.defineProperties(globalThis, { name: readOnly(name) });
runtime.start(false, name);
}
diff --git a/cli/js/workers.ts b/cli/js/workers.ts
index 60ef73da0..2a5d4d190 100644
--- a/cli/js/workers.ts
+++ b/cli/js/workers.ts
@@ -27,12 +27,14 @@ function decodeMessage(dataIntArray: Uint8Array): any {
function createWorker(
specifier: string,
hasSourceCode: boolean,
- sourceCode: Uint8Array
+ sourceCode: Uint8Array,
+ name?: string
): { id: number; loaded: boolean } {
return sendSync(dispatch.OP_CREATE_WORKER, {
specifier,
hasSourceCode,
- sourceCode: new TextDecoder().decode(sourceCode)
+ sourceCode: new TextDecoder().decode(sourceCode),
+ name
});
}
@@ -72,10 +74,12 @@ export interface Worker {
onmessage?: (e: { data: any }) => void;
onmessageerror?: () => void;
postMessage(data: any): void;
+ terminate(): void;
}
export interface WorkerOptions {
type?: "classic" | "module";
+ name?: string;
}
export class WorkerImpl extends EventTarget implements Worker {
@@ -121,7 +125,12 @@ export class WorkerImpl extends EventTarget implements Worker {
}
*/
- const { id, loaded } = createWorker(specifier, hasSourceCode, sourceCode);
+ const { id, loaded } = createWorker(
+ specifier,
+ hasSourceCode,
+ sourceCode,
+ options?.name
+ );
this.id = id;
this.ready = loaded;
this.poll();
@@ -196,6 +205,10 @@ export class WorkerImpl extends EventTarget implements Worker {
hostPostMessage(this.id, data);
}
+ terminate(): void {
+ throw new Error("Not yet implemented");
+ }
+
private async run(): Promise<void> {
while (!this.isClosing) {
const data = await hostGetMessage(this.id);
diff --git a/cli/lib.rs b/cli/lib.rs
index 311d8ce30..56705289f 100644
--- a/cli/lib.rs
+++ b/cli/lib.rs
@@ -54,6 +54,7 @@ pub mod version;
mod web_worker;
pub mod worker;
+use crate::compilers::TargetLib;
use crate::deno_error::js_check;
use crate::deno_error::{print_err_and_exit, print_msg_and_exit};
use crate::global_state::ThreadSafeGlobalState;
@@ -146,7 +147,12 @@ fn create_worker_and_state(
}
fn types_command() {
- println!("{}\n{}", crate::js::DENO_NS_LIB, crate::js::DENO_MAIN_LIB);
+ println!(
+ "{}\n{}\n{}",
+ crate::js::DENO_NS_LIB,
+ crate::js::SHARED_GLOBALS_LIB,
+ crate::js::WINDOW_LIB
+ );
}
fn print_cache_info(worker: MainWorker) {
@@ -198,7 +204,7 @@ async fn print_file_info(
let maybe_compiled = global_state_
.clone()
- .fetch_compiled_module(&module_specifier, None)
+ .fetch_compiled_module(&module_specifier, None, TargetLib::Main)
.await;
if let Err(e) = maybe_compiled {
debug!("compiler error exiting!");
diff --git a/cli/ops/worker_host.rs b/cli/ops/worker_host.rs
index 976c32219..a1509d2f7 100644
--- a/cli/ops/worker_host.rs
+++ b/cli/ops/worker_host.rs
@@ -4,7 +4,6 @@ use crate::deno_error::bad_resource;
use crate::deno_error::js_check;
use crate::deno_error::DenoError;
use crate::deno_error::ErrorKind;
-use crate::deno_error::GetErrorKind;
use crate::fmt_errors::JSError;
use crate::ops::json_op;
use crate::startup_data;
@@ -60,6 +59,7 @@ pub fn init(i: &mut Isolate, s: &ThreadSafeState) {
#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
struct CreateWorkerArgs {
+ name: Option<String>,
specifier: String,
has_source_code: bool,
source_code: String,
@@ -89,23 +89,28 @@ fn op_create_worker(
}
let (int, ext) = ThreadSafeState::create_channels();
- let child_state = ThreadSafeState::new(
+ let child_state = ThreadSafeState::new_for_worker(
state.global_state.clone(),
Some(parent_state.permissions.clone()), // by default share with parent
Some(module_specifier.clone()),
int,
)?;
+ let worker_name = if let Some(name) = args.name {
+ name
+ } else {
+ // TODO(bartlomieju): change it to something more descriptive
+ format!("USER-WORKER-{}", specifier)
+ };
+
// TODO: add a new option to make child worker not sharing permissions
// with parent (aka .clone(), requests from child won't reflect in parent)
- // TODO(bartlomieju): get it from "name" argument when creating worker
- let name = format!("USER-WORKER-{}", specifier);
let mut worker = WebWorker::new(
- name.to_string(),
+ worker_name.to_string(),
startup_data::deno_isolate_init(),
child_state,
ext,
);
- let script = format!("bootstrapWorkerRuntime(\"{}\")", name);
+ let script = format!("bootstrapWorkerRuntime(\"{}\")", worker_name);
js_check(worker.execute(&script));
js_check(worker.execute("runWorkerMessageLoop()"));
@@ -158,6 +163,8 @@ impl Future for WorkerPollFuture {
}
fn serialize_worker_result(result: Result<(), ErrBox>) -> Value {
+ use crate::deno_error::GetErrorKind;
+
if let Err(error) = result {
match error.kind() {
ErrorKind::JSError => {
diff --git a/cli/state.rs b/cli/state.rs
index b224451c5..c4835d6f5 100644
--- a/cli/state.rs
+++ b/cli/state.rs
@@ -1,4 +1,5 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
+use crate::compilers::TargetLib;
use crate::deno_error::permission_denied;
use crate::global_state::ThreadSafeGlobalState;
use crate::global_timer::GlobalTimer;
@@ -59,6 +60,7 @@ pub struct State {
pub start_time: Instant,
pub seeded_rng: Option<Mutex<StdRng>>,
pub resource_table: Mutex<ResourceTable>,
+ pub target_lib: TargetLib,
}
impl Clone for ThreadSafeState {
@@ -200,7 +202,7 @@ impl Loader for ThreadSafeState {
let module_url_specified = module_specifier.to_string();
let fut = self
.global_state
- .fetch_compiled_module(module_specifier, maybe_referrer)
+ .fetch_compiled_module(module_specifier, maybe_referrer, self.target_lib)
.map_ok(|compiled_module| deno_core::SourceCodeInfo {
// Real module name, might be different from initial specifier
// due to redirections.
@@ -228,9 +230,9 @@ impl ThreadSafeState {
(internal_channels, external_channels)
}
+ /// If `shared_permission` is None then permissions from globa state are used.
pub fn new(
global_state: ThreadSafeGlobalState,
- // If Some(perm), use perm. Else copy from global_state.
shared_permissions: Option<Arc<Mutex<DenoPermissions>>>,
main_module: Option<ModuleSpecifier>,
internal_channels: WorkerChannels,
@@ -267,6 +269,46 @@ impl ThreadSafeState {
seeded_rng,
resource_table: Mutex::new(ResourceTable::default()),
+ target_lib: TargetLib::Main,
+ };
+
+ Ok(ThreadSafeState(Arc::new(state)))
+ }
+
+ /// If `shared_permission` is None then permissions from globa state are used.
+ pub fn new_for_worker(
+ global_state: ThreadSafeGlobalState,
+ shared_permissions: Option<Arc<Mutex<DenoPermissions>>>,
+ main_module: Option<ModuleSpecifier>,
+ internal_channels: WorkerChannels,
+ ) -> Result<Self, ErrBox> {
+ let seeded_rng = match global_state.flags.seed {
+ Some(seed) => Some(Mutex::new(StdRng::seed_from_u64(seed))),
+ None => None,
+ };
+
+ let permissions = if let Some(perm) = shared_permissions {
+ perm
+ } else {
+ Arc::new(Mutex::new(global_state.permissions.clone()))
+ };
+
+ let state = State {
+ global_state,
+ main_module,
+ permissions,
+ import_map: None,
+ worker_channels: internal_channels,
+ metrics: Metrics::default(),
+ global_timer: Mutex::new(GlobalTimer::new()),
+ workers: Mutex::new(HashMap::new()),
+ loading_workers: Mutex::new(HashMap::new()),
+ next_worker_id: AtomicUsize::new(0),
+ start_time: Instant::now(),
+ seeded_rng,
+
+ resource_table: Mutex::new(ResourceTable::default()),
+ target_lib: TargetLib::Worker,
};
Ok(ThreadSafeState(Arc::new(state)))
diff --git a/cli/tests/026_workers.ts b/cli/tests/026_workers.ts
index 3043cc7b9..7ec6996e1 100644
--- a/cli/tests/026_workers.ts
+++ b/cli/tests/026_workers.ts
@@ -1,5 +1,11 @@
-const jsWorker = new Worker("./subdir/test_worker.js", { type: "module" });
-const tsWorker = new Worker("./subdir/test_worker.ts", { type: "module" });
+const jsWorker = new Worker("./subdir/test_worker.js", {
+ type: "module",
+ name: "jsWorker"
+});
+const tsWorker = new Worker("./subdir/test_worker.ts", {
+ type: "module",
+ name: "tsWorker"
+});
tsWorker.onmessage = (e): void => {
console.log("Received ts: " + e.data);
diff --git a/cli/tests/subdir/bench_worker.ts b/cli/tests/subdir/bench_worker.ts
index 696a84b9f..619a35fa2 100644
--- a/cli/tests/subdir/bench_worker.ts
+++ b/cli/tests/subdir/bench_worker.ts
@@ -15,7 +15,7 @@ onmessage = function(e): void {
break;
case 3: // Close
postMessage({ cmdId: 3 });
- workerClose();
+ close();
break;
}
};
diff --git a/cli/tests/subdir/test_worker.js b/cli/tests/subdir/test_worker.js
index cec5bdf9b..f0d9fbed6 100644
--- a/cli/tests/subdir/test_worker.js
+++ b/cli/tests/subdir/test_worker.js
@@ -1,5 +1,10 @@
let thrown = false;
+// TODO(bartlomieju): add test for throwing in web worker
+if (self.name !== "jsWorker") {
+ throw Error(`Bad worker name: ${self.name}, expected jsWorker`);
+}
+
onmessage = function(e) {
console.log(e.data);
@@ -10,7 +15,7 @@ onmessage = function(e) {
postMessage(e.data);
- workerClose();
+ close();
};
onerror = function() {
diff --git a/cli/tests/subdir/test_worker.ts b/cli/tests/subdir/test_worker.ts
index c8109d131..bc3f358f8 100644
--- a/cli/tests/subdir/test_worker.ts
+++ b/cli/tests/subdir/test_worker.ts
@@ -1,7 +1,11 @@
+if (self.name !== "tsWorker") {
+ throw Error(`Invalid worker name: ${self.name}, expected tsWorker`);
+}
+
onmessage = function(e): void {
console.log(e.data);
postMessage(e.data);
- workerClose();
+ close();
};
diff --git a/cli/tests/types.out b/cli/tests/types.out
index df79ff821..a212c01e8 100644
--- a/cli/tests/types.out
+++ b/cli/tests/types.out
@@ -5,10 +5,12 @@ declare namespace Deno {
[WILDCARD]
}
[WILDCARD]
-declare interface Window {
+declare interface WindowOrWorkerGlobalScope {
+[WILDCARD]
+declare interface Window extends WindowOrWorkerGlobalScope {
[WILDCARD]
Deno: typeof Deno;
}
-declare const window: Window & typeof globalThis;
+declare const window: Window & WindowOrWorkerGlobalScope & typeof globalThis;
[WILDCARD]