From 1b6f8318750d319d689f7eeef9e7e1f2e56b94a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Iwa=C5=84czuk?= Date: Sun, 8 Mar 2020 13:09:22 +0100 Subject: reorg: move JS ops implementations to cli/js/ops/, part 1 (#4264) Following JS ops were moved to separate files in cli/js/ops directory: - compiler - dispatch_json - dispatch_minimal - errors - fetch - fs_events - os - random - repl - resources - runtime_compiler - runtime - tty --- cli/js/chmod.ts | 2 +- cli/js/chown.ts | 2 +- cli/js/compiler_api.ts | 17 +-- cli/js/compiler_imports.ts | 9 +- cli/js/compiler_util.ts | 26 +---- cli/js/copy_file.ts | 2 +- cli/js/deno.ts | 14 ++- cli/js/dir.ts | 2 +- cli/js/dispatch.ts | 4 +- cli/js/dispatch_json.ts | 97 ----------------- cli/js/dispatch_minimal.ts | 115 -------------------- cli/js/error_stack.ts | 52 +-------- cli/js/files.ts | 10 +- cli/js/format_error.ts | 11 -- cli/js/fs_events.ts | 39 ------- cli/js/get_random_values.ts | 30 ------ cli/js/link.ts | 2 +- cli/js/make_temp.ts | 2 +- cli/js/metrics.ts | 39 ------- cli/js/mkdir.ts | 2 +- cli/js/net.ts | 5 +- cli/js/ops/compiler.ts | 55 ++++++++++ cli/js/ops/dispatch_json.ts | 97 +++++++++++++++++ cli/js/ops/dispatch_minimal.ts | 115 ++++++++++++++++++++ cli/js/ops/errors.ts | 61 +++++++++++ cli/js/ops/fetch.ts | 28 +++++ cli/js/ops/fs_events.ts | 39 +++++++ cli/js/ops/get_random_values.ts | 30 ++++++ cli/js/ops/os.ts | 227 ++++++++++++++++++++++++++++++++++++++++ cli/js/ops/repl.ts | 11 ++ cli/js/ops/resources.ts | 23 ++++ cli/js/ops/runtime.ts | 67 ++++++++++++ cli/js/ops/runtime_compiler.ts | 23 ++++ cli/js/ops/tty.ts | 14 +++ cli/js/os.ts | 227 ---------------------------------------- cli/js/performance.ts | 2 +- cli/js/permissions.ts | 2 +- cli/js/plugins.ts | 2 +- cli/js/process.ts | 5 +- cli/js/read_dir.ts | 2 +- cli/js/read_link.ts | 2 +- cli/js/realpath.ts | 2 +- cli/js/remove.ts | 2 +- cli/js/rename.ts | 2 +- cli/js/repl.ts | 15 +-- cli/js/resources.ts | 18 ---- cli/js/runtime.ts | 23 +--- cli/js/runtime_main.ts | 2 +- cli/js/runtime_worker.ts | 2 +- cli/js/signals.ts | 2 +- cli/js/stat.ts | 2 +- cli/js/symlink.ts | 2 +- cli/js/testing.ts | 2 +- cli/js/timers.ts | 2 +- cli/js/tls.ts | 2 +- cli/js/truncate.ts | 2 +- cli/js/tty.ts | 14 --- cli/js/utime.ts | 2 +- cli/js/web/fetch.ts | 19 +--- cli/js/web/url.ts | 2 +- cli/js/workers.ts | 2 +- 61 files changed, 862 insertions(+), 771 deletions(-) delete mode 100644 cli/js/dispatch_json.ts delete mode 100644 cli/js/dispatch_minimal.ts delete mode 100644 cli/js/format_error.ts delete mode 100644 cli/js/fs_events.ts delete mode 100644 cli/js/get_random_values.ts delete mode 100644 cli/js/metrics.ts create mode 100644 cli/js/ops/compiler.ts create mode 100644 cli/js/ops/dispatch_json.ts create mode 100644 cli/js/ops/dispatch_minimal.ts create mode 100644 cli/js/ops/errors.ts create mode 100644 cli/js/ops/fetch.ts create mode 100644 cli/js/ops/fs_events.ts create mode 100644 cli/js/ops/get_random_values.ts create mode 100644 cli/js/ops/os.ts create mode 100644 cli/js/ops/repl.ts create mode 100644 cli/js/ops/resources.ts create mode 100644 cli/js/ops/runtime.ts create mode 100644 cli/js/ops/runtime_compiler.ts create mode 100644 cli/js/ops/tty.ts delete mode 100644 cli/js/os.ts delete mode 100644 cli/js/resources.ts delete mode 100644 cli/js/tty.ts (limited to 'cli/js') diff --git a/cli/js/chmod.ts b/cli/js/chmod.ts index 5aa4ce7ea..b6238f02d 100644 --- a/cli/js/chmod.ts +++ b/cli/js/chmod.ts @@ -1,5 +1,5 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. -import { sendSync, sendAsync } from "./dispatch_json.ts"; +import { sendSync, sendAsync } from "./ops/dispatch_json.ts"; /** Synchronously changes the permission of a specific file/directory of * specified path. Ignores the process's umask. diff --git a/cli/js/chown.ts b/cli/js/chown.ts index e39741546..a89c58f5b 100644 --- a/cli/js/chown.ts +++ b/cli/js/chown.ts @@ -1,5 +1,5 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. -import { sendSync, sendAsync } from "./dispatch_json.ts"; +import { sendSync, sendAsync } from "./ops/dispatch_json.ts"; /** Synchronously change owner of a regular file or directory. Linux/Mac OS * only at the moment. diff --git a/cli/js/compiler_api.ts b/cli/js/compiler_api.ts index 3638046b6..b7c4e83e8 100644 --- a/cli/js/compiler_api.ts +++ b/cli/js/compiler_api.ts @@ -4,8 +4,8 @@ // compiler within Deno. import { DiagnosticItem } from "./diagnostics.ts"; -import { sendAsync } from "./dispatch_json.ts"; import * as util from "./util.ts"; +import * as runtimeCompilerOps from "./ops/runtime_compiler.ts"; /** A specific subset TypeScript compiler options that can be supported by * the Deno TypeScript compiler. */ @@ -300,7 +300,7 @@ export interface TranspileOnlyResult { * Many of the options related to type checking and emitting * type declaration files will have no impact on the output. */ -export function transpileOnly( +export async function transpileOnly( sources: Record, options?: CompilerOptions ): Promise> { @@ -309,7 +309,8 @@ export function transpileOnly( sources, options: options ? JSON.stringify(options) : undefined }; - return sendAsync("op_transpile", payload).then(result => JSON.parse(result)); + const result = await runtimeCompilerOps.transpile(payload); + return JSON.parse(result); } /** Takes a root module name, any optionally a record set of sources. Resolves @@ -339,7 +340,7 @@ export function transpileOnly( * @param options An optional object of options to send to the compiler. This is * a subset of ts.CompilerOptions which can be supported by Deno. */ -export function compile( +export async function compile( rootName: string, sources?: Record, options?: CompilerOptions @@ -355,7 +356,8 @@ export function compile( sources: !!sources, options }); - return sendAsync("op_compile", payload).then(result => JSON.parse(result)); + const result = await runtimeCompilerOps.compile(payload); + return JSON.parse(result); } /** Takes a root module name, and optionally a record set of sources. Resolves @@ -386,7 +388,7 @@ export function compile( * @param options An optional object of options to send to the compiler. This is * a subset of ts.CompilerOptions which can be supported by Deno. */ -export function bundle( +export async function bundle( rootName: string, sources?: Record, options?: CompilerOptions @@ -402,5 +404,6 @@ export function bundle( sources: !!sources, options }); - return sendAsync("op_compile", payload).then(result => JSON.parse(result)); + const result = await runtimeCompilerOps.compile(payload); + return JSON.parse(result); } diff --git a/cli/js/compiler_imports.ts b/cli/js/compiler_imports.ts index 387c47fc4..377df4098 100644 --- a/cli/js/compiler_imports.ts +++ b/cli/js/compiler_imports.ts @@ -7,9 +7,9 @@ import { } from "./compiler_sourcefile.ts"; import { normalizeString, CHAR_FORWARD_SLASH } from "./compiler_util.ts"; import { cwd } from "./dir.ts"; -import { sendAsync, sendSync } from "./dispatch_json.ts"; import { assert } from "./util.ts"; import * as util from "./util.ts"; +import * as compilerOps from "./ops/compiler.ts"; /** Resolve a path to the final path segment passed. */ function resolvePath(...pathSegments: string[]): string { @@ -68,7 +68,7 @@ export function resolveModules( referrer?: string ): string[] { util.log("compiler_imports::resolveModules", { specifiers, referrer }); - return sendSync("op_resolve_modules", { specifiers, referrer }); + return compilerOps.resolveModules(specifiers, referrer); } /** Ops to Rust to fetch modules meta data. */ @@ -77,10 +77,7 @@ function fetchSourceFiles( referrer?: string ): Promise { util.log("compiler_imports::fetchSourceFiles", { specifiers, referrer }); - return sendAsync("op_fetch_source_files", { - specifiers, - referrer - }); + return compilerOps.fetchSourceFiles(specifiers, referrer); } /** Given a filename, determine the media type based on extension. Used when diff --git a/cli/js/compiler_util.ts b/cli/js/compiler_util.ts index 57ba9589b..3cc661d6c 100644 --- a/cli/js/compiler_util.ts +++ b/cli/js/compiler_util.ts @@ -5,9 +5,8 @@ import { CompilerOptions } from "./compiler_api.ts"; import { buildBundle } from "./compiler_bundler.ts"; import { ConfigureResponse, Host } from "./compiler_host.ts"; import { SourceFile } from "./compiler_sourcefile.ts"; -import { sendSync } from "./dispatch_json.ts"; -import { atob, TextDecoder, TextEncoder } from "./web/text_encoding.ts"; -import { core } from "./core.ts"; +import { atob, TextEncoder } from "./web/text_encoding.ts"; +import * as compilerOps from "./ops/compiler.ts"; import * as util from "./util.ts"; import { assert } from "./util.ts"; import { writeFileSync } from "./write_file.ts"; @@ -70,36 +69,21 @@ function cache( if (emittedFileName.endsWith(".map")) { // Source Map - sendSync("op_cache", { - extension: ".map", - moduleId, - contents - }); + compilerOps.cache(".map", moduleId, contents); } else if ( emittedFileName.endsWith(".js") || emittedFileName.endsWith(".json") ) { // Compiled JavaScript - sendSync("op_cache", { - extension: ".js", - moduleId, - contents - }); + compilerOps.cache(".js", moduleId, contents); } else { assert(false, `Trying to cache unhandled file type "${emittedFileName}"`); } } -const encoder = new TextEncoder(); -const decoder = new TextDecoder(); - /** Retrieve an asset from Rust. */ export function getAsset(name: string): string { - const opId = core.ops()["op_fetch_asset"]; - // We really don't want to depend on JSON dispatch during snapshotting, so - // this op exchanges strings with Rust as raw byte arrays. - const sourceCodeBytes = core.dispatch(opId, encoder.encode(name)); - return decoder.decode(sourceCodeBytes!); + return compilerOps.getAsset(name); } /** Generates a `writeFile` function which can be passed to the compiler `Host` diff --git a/cli/js/copy_file.ts b/cli/js/copy_file.ts index 6da50d1f6..6c9bf6b03 100644 --- a/cli/js/copy_file.ts +++ b/cli/js/copy_file.ts @@ -1,5 +1,5 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. -import { sendSync, sendAsync } from "./dispatch_json.ts"; +import { sendSync, sendAsync } from "./ops/dispatch_json.ts"; /** Synchronously copies the contents and permissions of one file to another * specified path, by default creating a new file if needed, else overwriting. diff --git a/cli/js/deno.ts b/cli/js/deno.ts index 92c6984ac..2d16b75cf 100644 --- a/cli/js/deno.ts +++ b/cli/js/deno.ts @@ -21,7 +21,7 @@ export { DiagnosticMessageChain } from "./diagnostics.ts"; export { chdir, cwd } from "./dir.ts"; -export { applySourceMap } from "./error_stack.ts"; +export { applySourceMap, formatDiagnostics } from "./ops/errors.ts"; export { errors } from "./errors.ts"; export { FileInfo } from "./file_info.ts"; export { @@ -39,12 +39,10 @@ export { writeSync, seek, seekSync, - close, OpenOptions, OpenMode } from "./files.ts"; -export { formatDiagnostics } from "./format_error.ts"; -export { FsEvent, fsEvents } from "./fs_events.ts"; +export { FsEvent, fsEvents } from "./ops/fs_events.ts"; export { EOF, copy, @@ -72,7 +70,7 @@ export { makeTempFile, MakeTempOptions } from "./make_temp.ts"; -export { metrics, Metrics } from "./metrics.ts"; +export { metrics, Metrics } from "./ops/runtime.ts"; export { mkdirSync, mkdir, MkdirOptions } from "./mkdir.ts"; export { Addr, @@ -94,7 +92,7 @@ export { hostname, loadavg, osRelease -} from "./os.ts"; +} from "./ops/os.ts"; export { permissions, PermissionName, @@ -117,13 +115,13 @@ export { readlinkSync, readlink } from "./read_link.ts"; export { realpathSync, realpath } from "./realpath.ts"; export { removeSync, remove, RemoveOptions } from "./remove.ts"; export { renameSync, rename } from "./rename.ts"; -export { resources } from "./resources.ts"; +export { resources, close } from "./ops/resources.ts"; export { signal, signals, SignalStream } from "./signals.ts"; export { statSync, lstatSync, stat, lstat } from "./stat.ts"; export { symlinkSync, symlink } from "./symlink.ts"; export { connectTLS, listenTLS } from "./tls.ts"; export { truncateSync, truncate } from "./truncate.ts"; -export { isatty, setRaw } from "./tty.ts"; +export { isatty, setRaw } from "./ops/tty.ts"; export { utimeSync, utime } from "./utime.ts"; export { version } from "./version.ts"; export { writeFileSync, writeFile, WriteFileOptions } from "./write_file.ts"; diff --git a/cli/js/dir.ts b/cli/js/dir.ts index bc62be83f..7a809a664 100644 --- a/cli/js/dir.ts +++ b/cli/js/dir.ts @@ -1,5 +1,5 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. -import { sendSync } from "./dispatch_json.ts"; +import { sendSync } from "./ops/dispatch_json.ts"; /** * **UNSTABLE**: maybe needs permissions. diff --git a/cli/js/dispatch.ts b/cli/js/dispatch.ts index db10db8ca..f3c92dbc6 100644 --- a/cli/js/dispatch.ts +++ b/cli/js/dispatch.ts @@ -1,6 +1,6 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. -import * as minimal from "./dispatch_minimal.ts"; -import * as json from "./dispatch_json.ts"; +import * as minimal from "./ops/dispatch_minimal.ts"; +import * as json from "./ops/dispatch_json.ts"; import { AsyncHandler } from "./plugins.ts"; const PLUGIN_ASYNC_HANDLER_MAP: Map = new Map(); diff --git a/cli/js/dispatch_json.ts b/cli/js/dispatch_json.ts deleted file mode 100644 index f7f389b79..000000000 --- a/cli/js/dispatch_json.ts +++ /dev/null @@ -1,97 +0,0 @@ -// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. -import * as util from "./util.ts"; -import { TextEncoder, TextDecoder } from "./web/text_encoding.ts"; -import { core } from "./core.ts"; -import { OPS_CACHE } from "./runtime.ts"; -import { ErrorKind, getErrorClass } from "./errors.ts"; - -// eslint-disable-next-line @typescript-eslint/no-explicit-any -type Ok = any; - -interface JsonError { - kind: ErrorKind; - message: string; -} - -interface JsonResponse { - ok?: Ok; - err?: JsonError; - promiseId?: number; // Only present in async messages. -} - -const promiseTable = new Map>(); -let _nextPromiseId = 1; - -function nextPromiseId(): number { - return _nextPromiseId++; -} - -function decode(ui8: Uint8Array): JsonResponse { - const s = new TextDecoder().decode(ui8); - return JSON.parse(s) as JsonResponse; -} - -function encode(args: object): Uint8Array { - const s = JSON.stringify(args); - return new TextEncoder().encode(s); -} - -function unwrapResponse(res: JsonResponse): Ok { - if (res.err != null) { - throw new (getErrorClass(res.err.kind))(res.err.message); - } - util.assert(res.ok != null); - return res.ok; -} - -export function asyncMsgFromRust(resUi8: Uint8Array): void { - const res = decode(resUi8); - util.assert(res.promiseId != null); - - const promise = promiseTable.get(res.promiseId!); - util.assert(promise != null); - promiseTable.delete(res.promiseId!); - promise.resolve(res); -} - -export function sendSync( - opName: string, - args: object = {}, - zeroCopy?: Uint8Array -): Ok { - const opId = OPS_CACHE[opName]; - util.log("sendSync", opName, opId); - const argsUi8 = encode(args); - const resUi8 = core.dispatch(opId, argsUi8, zeroCopy); - util.assert(resUi8 != null); - - const res = decode(resUi8); - util.assert(res.promiseId == null); - return unwrapResponse(res); -} - -export async function sendAsync( - opName: string, - args: object = {}, - zeroCopy?: Uint8Array -): Promise { - const opId = OPS_CACHE[opName]; - util.log("sendAsync", opName, opId); - const promiseId = nextPromiseId(); - args = Object.assign(args, { promiseId }); - const promise = util.createResolvable(); - - const argsUi8 = encode(args); - const buf = core.dispatch(opId, argsUi8, zeroCopy); - if (buf) { - // Sync result. - const res = decode(buf); - promise.resolve(res); - } else { - // Async result. - promiseTable.set(promiseId, promise); - } - - const res = await promise; - return unwrapResponse(res); -} diff --git a/cli/js/dispatch_minimal.ts b/cli/js/dispatch_minimal.ts deleted file mode 100644 index a62cc7c85..000000000 --- a/cli/js/dispatch_minimal.ts +++ /dev/null @@ -1,115 +0,0 @@ -// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. -import * as util from "./util.ts"; -import { core } from "./core.ts"; -import { TextDecoder } from "./web/text_encoding.ts"; -import { ErrorKind, errors, getErrorClass } from "./errors.ts"; - -const promiseTableMin = new Map>(); -// Note it's important that promiseId starts at 1 instead of 0, because sync -// messages are indicated with promiseId 0. If we ever add wrap around logic for -// overflows, this should be taken into account. -let _nextPromiseId = 1; - -const decoder = new TextDecoder(); - -function nextPromiseId(): number { - return _nextPromiseId++; -} - -export interface RecordMinimal { - promiseId: number; - arg: number; - result: number; - err?: { - kind: ErrorKind; - message: string; - }; -} - -export function recordFromBufMinimal(ui8: Uint8Array): RecordMinimal { - const header = ui8.subarray(0, 12); - const buf32 = new Int32Array( - header.buffer, - header.byteOffset, - header.byteLength / 4 - ); - const promiseId = buf32[0]; - const arg = buf32[1]; - const result = buf32[2]; - let err; - - if (arg < 0) { - const kind = result as ErrorKind; - const message = decoder.decode(ui8.subarray(12)); - err = { kind, message }; - } else if (ui8.length != 12) { - throw new errors.InvalidData("BadMessage"); - } - - return { - promiseId, - arg, - result, - err - }; -} - -function unwrapResponse(res: RecordMinimal): number { - if (res.err != null) { - throw new (getErrorClass(res.err.kind))(res.err.message); - } - return res.result; -} - -const scratch32 = new Int32Array(3); -const scratchBytes = new Uint8Array( - scratch32.buffer, - scratch32.byteOffset, - scratch32.byteLength -); -util.assert(scratchBytes.byteLength === scratch32.length * 4); - -export function asyncMsgFromRust(ui8: Uint8Array): void { - const record = recordFromBufMinimal(ui8); - const { promiseId } = record; - const promise = promiseTableMin.get(promiseId); - promiseTableMin.delete(promiseId); - util.assert(promise); - promise.resolve(record); -} - -export async function sendAsyncMinimal( - opId: number, - arg: number, - zeroCopy: Uint8Array -): Promise { - const promiseId = nextPromiseId(); // AKA cmdId - scratch32[0] = promiseId; - scratch32[1] = arg; - scratch32[2] = 0; // result - const promise = util.createResolvable(); - const buf = core.dispatch(opId, scratchBytes, zeroCopy); - if (buf) { - const record = recordFromBufMinimal(buf); - // Sync result. - promise.resolve(record); - } else { - // Async result. - promiseTableMin.set(promiseId, promise); - } - - const res = await promise; - return unwrapResponse(res); -} - -export function sendSyncMinimal( - opId: number, - arg: number, - zeroCopy: Uint8Array -): number { - scratch32[0] = 0; // promiseId 0 indicates sync - scratch32[1] = arg; - const res = core.dispatch(opId, scratchBytes, zeroCopy)!; - const resRecord = recordFromBufMinimal(res); - return unwrapResponse(resRecord); -} diff --git a/cli/js/error_stack.ts b/cli/js/error_stack.ts index ff15cee60..8d2badc20 100644 --- a/cli/js/error_stack.ts +++ b/cli/js/error_stack.ts @@ -1,60 +1,10 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. // Some of the code here is adapted directly from V8 and licensed under a BSD // style license available here: https://github.com/v8/v8/blob/24886f2d1c565287d33d71e4109a53bf0b54b75c/LICENSE.v8 -import { sendSync } from "./dispatch_json.ts"; +import { applySourceMap, Location } from "./ops/errors.ts"; import { assert } from "./util.ts"; import { exposeForTest } from "./internals.ts"; -export interface Location { - /** The full url for the module, e.g. `file://some/file.ts` or - * `https://some/file.ts`. */ - filename: string; - - /** The line number in the file. It is assumed to be 1-indexed. */ - line: number; - - /** The column number in the file. It is assumed to be 1-indexed. */ - column: number; -} - -/** Given a current location in a module, lookup the source location and - * return it. - * - * When Deno transpiles code, it keep source maps of the transpiled code. This - * function can be used to lookup the original location. This is automatically - * done when accessing the `.stack` of an error, or when an uncaught error is - * logged. This function can be used to perform the lookup for creating better - * error handling. - * - * **Note:** `line` and `column` are 1 indexed, which matches display - * expectations, but is not typical of most index numbers in Deno. - * - * An example: - * - * const orig = Deno.applySourceMap({ - * location: "file://my/module.ts", - * line: 5, - * column: 15 - * }); - * console.log(`${orig.filename}:${orig.line}:${orig.column}`); - * - */ -export function applySourceMap(location: Location): Location { - const { filename, line, column } = location; - // On this side, line/column are 1 based, but in the source maps, they are - // 0 based, so we have to convert back and forth - const res = sendSync("op_apply_source_map", { - filename, - line: line - 1, - column: column - 1 - }); - return { - filename: res.filename, - line: res.line + 1, - column: res.column + 1 - }; -} - /** Mutate the call site so that it returns the location, instead of its * original location. */ diff --git a/cli/js/files.ts b/cli/js/files.ts index 440d77be1..21b0105af 100644 --- a/cli/js/files.ts +++ b/cli/js/files.ts @@ -10,11 +10,12 @@ import { SyncWriter, SyncSeeker } from "./io.ts"; -import { sendAsyncMinimal, sendSyncMinimal } from "./dispatch_minimal.ts"; +import { sendAsyncMinimal, sendSyncMinimal } from "./ops/dispatch_minimal.ts"; import { sendSync as sendSyncJson, sendAsync as sendAsyncJson -} from "./dispatch_json.ts"; +} from "./ops/dispatch_json.ts"; +import { close } from "./ops/resources.ts"; import { OPS_CACHE } from "./runtime.ts"; // This is done because read/write are extremely performance sensitive. @@ -241,11 +242,6 @@ export async function seek( return await sendAsyncJson("op_seek", { rid, offset, whence }); } -/** Close the given resource ID. */ -export function close(rid: number): void { - sendSyncJson("op_close", { rid }); -} - /** The Deno abstraction for reading and writing files. */ export class File implements diff --git a/cli/js/format_error.ts b/cli/js/format_error.ts deleted file mode 100644 index 0a322338a..000000000 --- a/cli/js/format_error.ts +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. -import { DiagnosticItem } from "./diagnostics.ts"; -import { sendSync } from "./dispatch_json.ts"; - -/** - * Format an array of diagnostic items and return them as a single string. - * @param items An array of diagnostic items to format - */ -export function formatDiagnostics(items: DiagnosticItem[]): string { - return sendSync("op_format_diagnostic", { items }); -} diff --git a/cli/js/fs_events.ts b/cli/js/fs_events.ts deleted file mode 100644 index b549b3d4d..000000000 --- a/cli/js/fs_events.ts +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright 2019 the Deno authors. All rights reserved. MIT license. -import { sendSync, sendAsync } from "./dispatch_json.ts"; -import { close } from "./files.ts"; - -export interface FsEvent { - kind: "any" | "access" | "create" | "modify" | "remove"; - paths: string[]; -} - -class FsEvents implements AsyncIterableIterator { - readonly rid: number; - - constructor(paths: string[], options: { recursive: boolean }) { - const { recursive } = options; - this.rid = sendSync("op_fs_events_open", { recursive, paths }); - } - - async next(): Promise> { - return await sendAsync("op_fs_events_poll", { - rid: this.rid - }); - } - - async return(value?: FsEvent): Promise> { - close(this.rid); - return { value, done: true }; - } - - [Symbol.asyncIterator](): AsyncIterableIterator { - return this; - } -} - -export function fsEvents( - paths: string | string[], - options = { recursive: true } -): AsyncIterableIterator { - return new FsEvents(Array.isArray(paths) ? paths : [paths], options); -} diff --git a/cli/js/get_random_values.ts b/cli/js/get_random_values.ts deleted file mode 100644 index 799173702..000000000 --- a/cli/js/get_random_values.ts +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. -import { sendSync } from "./dispatch_json.ts"; -import { assert } from "./util.ts"; - -/** Synchronously collects cryptographically secure random values. The - * underlying CSPRNG in use is Rust's `rand::rngs::ThreadRng`. - * - * const arr = new Uint8Array(32); - * crypto.getRandomValues(arr); - */ -export function getRandomValues< - T extends - | Int8Array - | Uint8Array - | Uint8ClampedArray - | Int16Array - | Uint16Array - | Int32Array - | Uint32Array ->(typedArray: T): T { - assert(typedArray !== null, "Input must not be null"); - assert(typedArray.length <= 65536, "Input must not be longer than 65536"); - const ui8 = new Uint8Array( - typedArray.buffer, - typedArray.byteOffset, - typedArray.byteLength - ); - sendSync("op_get_random_values", {}, ui8); - return typedArray; -} diff --git a/cli/js/link.ts b/cli/js/link.ts index cd738b1bc..a2ce33d9f 100644 --- a/cli/js/link.ts +++ b/cli/js/link.ts @@ -1,5 +1,5 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. -import { sendSync, sendAsync } from "./dispatch_json.ts"; +import { sendSync, sendAsync } from "./ops/dispatch_json.ts"; /** Creates `newname` as a hard link to `oldname`. * diff --git a/cli/js/make_temp.ts b/cli/js/make_temp.ts index 1d8e283d3..87c694204 100644 --- a/cli/js/make_temp.ts +++ b/cli/js/make_temp.ts @@ -1,5 +1,5 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. -import { sendSync, sendAsync } from "./dispatch_json.ts"; +import { sendSync, sendAsync } from "./ops/dispatch_json.ts"; export interface MakeTempOptions { /** Directory where the temporary directory should be created (defaults to diff --git a/cli/js/metrics.ts b/cli/js/metrics.ts deleted file mode 100644 index 90f22854c..000000000 --- a/cli/js/metrics.ts +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. -import { sendSync } from "./dispatch_json.ts"; - -export interface Metrics { - opsDispatched: number; - opsDispatchedSync: number; - opsDispatchedAsync: number; - opsDispatchedAsyncUnref: number; - opsCompleted: number; - opsCompletedSync: number; - opsCompletedAsync: number; - opsCompletedAsyncUnref: number; - bytesSentControl: number; - bytesSentData: number; - bytesReceived: number; -} - -/** Receive metrics from the privileged side of Deno. - * - * > console.table(Deno.metrics()) - * ┌─────────────────────────┬────────┐ - * │ (index) │ Values │ - * ├─────────────────────────┼────────┤ - * │ opsDispatched │ 3 │ - * │ opsDispatchedSync │ 2 │ - * │ opsDispatchedAsync │ 1 │ - * │ opsDispatchedAsyncUnref │ 0 │ - * │ opsCompleted │ 3 │ - * │ opsCompletedSync │ 2 │ - * │ opsCompletedAsync │ 1 │ - * │ opsCompletedAsyncUnref │ 0 │ - * │ bytesSentControl │ 73 │ - * │ bytesSentData │ 0 │ - * │ bytesReceived │ 375 │ - * └─────────────────────────┴────────┘ - */ -export function metrics(): Metrics { - return sendSync("op_metrics"); -} diff --git a/cli/js/mkdir.ts b/cli/js/mkdir.ts index 4d15d9a44..3f4a18b19 100644 --- a/cli/js/mkdir.ts +++ b/cli/js/mkdir.ts @@ -1,5 +1,5 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. -import { sendSync, sendAsync } from "./dispatch_json.ts"; +import { sendSync, sendAsync } from "./ops/dispatch_json.ts"; // TODO(ry) The complexity in argument parsing is to support deprecated forms of // mkdir and mkdirSync. diff --git a/cli/js/net.ts b/cli/js/net.ts index e03175b57..654762885 100644 --- a/cli/js/net.ts +++ b/cli/js/net.ts @@ -1,7 +1,8 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. import { EOF, Reader, Writer, Closer } from "./io.ts"; -import { read, write, close } from "./files.ts"; -import { sendSync, sendAsync } from "./dispatch_json.ts"; +import { read, write } from "./files.ts"; +import { close } from "./ops/resources.ts"; +import { sendSync, sendAsync } from "./ops/dispatch_json.ts"; export type Transport = "tcp" | "udp"; // TODO support other types: diff --git a/cli/js/ops/compiler.ts b/cli/js/ops/compiler.ts new file mode 100644 index 000000000..b45ad42b2 --- /dev/null +++ b/cli/js/ops/compiler.ts @@ -0,0 +1,55 @@ +// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. + +import { sendAsync, sendSync } from "./dispatch_json.ts"; +import { TextDecoder, TextEncoder } from "../web/text_encoding.ts"; +import { core } from "../core.ts"; + +/** Ops to Rust to resolve modules' URLs. */ +export function resolveModules( + specifiers: string[], + referrer?: string +): string[] { + return sendSync("op_resolve_modules", { specifiers, referrer }); +} + +/** Ops to Rust to fetch modules meta data. */ +export function fetchSourceFiles( + specifiers: string[], + referrer?: string +): Promise< + Array<{ + url: string; + filename: string; + mediaType: number; + sourceCode: string; + }> +> { + return sendAsync("op_fetch_source_files", { + specifiers, + referrer + }); +} + +const encoder = new TextEncoder(); +const decoder = new TextDecoder(); + +/** This op is also used during snapshotting */ +export function getAsset(name: string): string { + const opId = core.ops()["op_fetch_asset"]; + // We really don't want to depend on JSON dispatch during snapshotting, so + // this op exchanges strings with Rust as raw byte arrays. + const sourceCodeBytes = core.dispatch(opId, encoder.encode(name)); + return decoder.decode(sourceCodeBytes!); +} + +export function cache( + extension: string, + moduleId: string, + contents: string +): void { + sendSync("op_cache", { + extension, + moduleId, + contents + }); +} diff --git a/cli/js/ops/dispatch_json.ts b/cli/js/ops/dispatch_json.ts new file mode 100644 index 000000000..6fb9007df --- /dev/null +++ b/cli/js/ops/dispatch_json.ts @@ -0,0 +1,97 @@ +// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. +import * as util from "../util.ts"; +import { TextEncoder, TextDecoder } from "../web/text_encoding.ts"; +import { core } from "../core.ts"; +import { OPS_CACHE } from "../runtime.ts"; +import { ErrorKind, getErrorClass } from "../errors.ts"; + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +type Ok = any; + +interface JsonError { + kind: ErrorKind; + message: string; +} + +interface JsonResponse { + ok?: Ok; + err?: JsonError; + promiseId?: number; // Only present in async messages. +} + +const promiseTable = new Map>(); +let _nextPromiseId = 1; + +function nextPromiseId(): number { + return _nextPromiseId++; +} + +function decode(ui8: Uint8Array): JsonResponse { + const s = new TextDecoder().decode(ui8); + return JSON.parse(s) as JsonResponse; +} + +function encode(args: object): Uint8Array { + const s = JSON.stringify(args); + return new TextEncoder().encode(s); +} + +function unwrapResponse(res: JsonResponse): Ok { + if (res.err != null) { + throw new (getErrorClass(res.err.kind))(res.err.message); + } + util.assert(res.ok != null); + return res.ok; +} + +export function asyncMsgFromRust(resUi8: Uint8Array): void { + const res = decode(resUi8); + util.assert(res.promiseId != null); + + const promise = promiseTable.get(res.promiseId!); + util.assert(promise != null); + promiseTable.delete(res.promiseId!); + promise.resolve(res); +} + +export function sendSync( + opName: string, + args: object = {}, + zeroCopy?: Uint8Array +): Ok { + const opId = OPS_CACHE[opName]; + util.log("sendSync", opName, opId); + const argsUi8 = encode(args); + const resUi8 = core.dispatch(opId, argsUi8, zeroCopy); + util.assert(resUi8 != null); + + const res = decode(resUi8); + util.assert(res.promiseId == null); + return unwrapResponse(res); +} + +export async function sendAsync( + opName: string, + args: object = {}, + zeroCopy?: Uint8Array +): Promise { + const opId = OPS_CACHE[opName]; + util.log("sendAsync", opName, opId); + const promiseId = nextPromiseId(); + args = Object.assign(args, { promiseId }); + const promise = util.createResolvable(); + + const argsUi8 = encode(args); + const buf = core.dispatch(opId, argsUi8, zeroCopy); + if (buf) { + // Sync result. + const res = decode(buf); + promise.resolve(res); + } else { + // Async result. + promiseTable.set(promiseId, promise); + } + + const res = await promise; + return unwrapResponse(res); +} diff --git a/cli/js/ops/dispatch_minimal.ts b/cli/js/ops/dispatch_minimal.ts new file mode 100644 index 000000000..7aec4683c --- /dev/null +++ b/cli/js/ops/dispatch_minimal.ts @@ -0,0 +1,115 @@ +// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. +import * as util from "../util.ts"; +import { core } from "../core.ts"; +import { TextDecoder } from "../web/text_encoding.ts"; +import { ErrorKind, errors, getErrorClass } from "../errors.ts"; + +const promiseTableMin = new Map>(); +// Note it's important that promiseId starts at 1 instead of 0, because sync +// messages are indicated with promiseId 0. If we ever add wrap around logic for +// overflows, this should be taken into account. +let _nextPromiseId = 1; + +const decoder = new TextDecoder(); + +function nextPromiseId(): number { + return _nextPromiseId++; +} + +export interface RecordMinimal { + promiseId: number; + arg: number; + result: number; + err?: { + kind: ErrorKind; + message: string; + }; +} + +export function recordFromBufMinimal(ui8: Uint8Array): RecordMinimal { + const header = ui8.subarray(0, 12); + const buf32 = new Int32Array( + header.buffer, + header.byteOffset, + header.byteLength / 4 + ); + const promiseId = buf32[0]; + const arg = buf32[1]; + const result = buf32[2]; + let err; + + if (arg < 0) { + const kind = result as ErrorKind; + const message = decoder.decode(ui8.subarray(12)); + err = { kind, message }; + } else if (ui8.length != 12) { + throw new errors.InvalidData("BadMessage"); + } + + return { + promiseId, + arg, + result, + err + }; +} + +function unwrapResponse(res: RecordMinimal): number { + if (res.err != null) { + throw new (getErrorClass(res.err.kind))(res.err.message); + } + return res.result; +} + +const scratch32 = new Int32Array(3); +const scratchBytes = new Uint8Array( + scratch32.buffer, + scratch32.byteOffset, + scratch32.byteLength +); +util.assert(scratchBytes.byteLength === scratch32.length * 4); + +export function asyncMsgFromRust(ui8: Uint8Array): void { + const record = recordFromBufMinimal(ui8); + const { promiseId } = record; + const promise = promiseTableMin.get(promiseId); + promiseTableMin.delete(promiseId); + util.assert(promise); + promise.resolve(record); +} + +export async function sendAsyncMinimal( + opId: number, + arg: number, + zeroCopy: Uint8Array +): Promise { + const promiseId = nextPromiseId(); // AKA cmdId + scratch32[0] = promiseId; + scratch32[1] = arg; + scratch32[2] = 0; // result + const promise = util.createResolvable(); + const buf = core.dispatch(opId, scratchBytes, zeroCopy); + if (buf) { + const record = recordFromBufMinimal(buf); + // Sync result. + promise.resolve(record); + } else { + // Async result. + promiseTableMin.set(promiseId, promise); + } + + const res = await promise; + return unwrapResponse(res); +} + +export function sendSyncMinimal( + opId: number, + arg: number, + zeroCopy: Uint8Array +): number { + scratch32[0] = 0; // promiseId 0 indicates sync + scratch32[1] = arg; + const res = core.dispatch(opId, scratchBytes, zeroCopy)!; + const resRecord = recordFromBufMinimal(res); + return unwrapResponse(resRecord); +} diff --git a/cli/js/ops/errors.ts b/cli/js/ops/errors.ts new file mode 100644 index 000000000..f96e376d6 --- /dev/null +++ b/cli/js/ops/errors.ts @@ -0,0 +1,61 @@ +// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. +import { DiagnosticItem } from "../diagnostics.ts"; +import { sendSync } from "./dispatch_json.ts"; + +/** + * Format an array of diagnostic items and return them as a single string. + * @param items An array of diagnostic items to format + */ +export function formatDiagnostics(items: DiagnosticItem[]): string { + return sendSync("op_format_diagnostic", { items }); +} + +export interface Location { + /** The full url for the module, e.g. `file://some/file.ts` or + * `https://some/file.ts`. */ + filename: string; + + /** The line number in the file. It is assumed to be 1-indexed. */ + line: number; + + /** The column number in the file. It is assumed to be 1-indexed. */ + column: number; +} + +/** Given a current location in a module, lookup the source location and + * return it. + * + * When Deno transpiles code, it keep source maps of the transpiled code. This + * function can be used to lookup the original location. This is automatically + * done when accessing the `.stack` of an error, or when an uncaught error is + * logged. This function can be used to perform the lookup for creating better + * error handling. + * + * **Note:** `line` and `column` are 1 indexed, which matches display + * expectations, but is not typical of most index numbers in Deno. + * + * An example: + * + * const orig = Deno.applySourceMap({ + * location: "file://my/module.ts", + * line: 5, + * column: 15 + * }); + * console.log(`${orig.filename}:${orig.line}:${orig.column}`); + * + */ +export function applySourceMap(location: Location): Location { + const { filename, line, column } = location; + // On this side, line/column are 1 based, but in the source maps, they are + // 0 based, so we have to convert back and forth + const res = sendSync("op_apply_source_map", { + filename, + line: line - 1, + column: column - 1 + }); + return { + filename: res.filename, + line: res.line + 1, + column: res.column + 1 + }; +} diff --git a/cli/js/ops/fetch.ts b/cli/js/ops/fetch.ts new file mode 100644 index 000000000..c5c0cb883 --- /dev/null +++ b/cli/js/ops/fetch.ts @@ -0,0 +1,28 @@ +// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. + +import { sendAsync } from "./dispatch_json.ts"; + +interface FetchRequest { + url: string; + method: string | null; + headers: Array<[string, string]>; +} + +export interface FetchResponse { + bodyRid: number; + status: number; + statusText: string; + headers: Array<[string, string]>; +} + +export async function fetch( + args: FetchRequest, + body: ArrayBufferView | undefined +): Promise { + let zeroCopy = undefined; + if (body) { + zeroCopy = new Uint8Array(body.buffer, body.byteOffset, body.byteLength); + } + + return await sendAsync("op_fetch", args, zeroCopy); +} diff --git a/cli/js/ops/fs_events.ts b/cli/js/ops/fs_events.ts new file mode 100644 index 000000000..09e82c515 --- /dev/null +++ b/cli/js/ops/fs_events.ts @@ -0,0 +1,39 @@ +// Copyright 2019 the Deno authors. All rights reserved. MIT license. +import { sendSync, sendAsync } from "./dispatch_json.ts"; +import { close } from "./resources.ts"; + +export interface FsEvent { + kind: "any" | "access" | "create" | "modify" | "remove"; + paths: string[]; +} + +class FsEvents implements AsyncIterableIterator { + readonly rid: number; + + constructor(paths: string[], options: { recursive: boolean }) { + const { recursive } = options; + this.rid = sendSync("op_fs_events_open", { recursive, paths }); + } + + async next(): Promise> { + return await sendAsync("op_fs_events_poll", { + rid: this.rid + }); + } + + async return(value?: FsEvent): Promise> { + close(this.rid); + return { value, done: true }; + } + + [Symbol.asyncIterator](): AsyncIterableIterator { + return this; + } +} + +export function fsEvents( + paths: string | string[], + options = { recursive: true } +): AsyncIterableIterator { + return new FsEvents(Array.isArray(paths) ? paths : [paths], options); +} diff --git a/cli/js/ops/get_random_values.ts b/cli/js/ops/get_random_values.ts new file mode 100644 index 000000000..0e384c259 --- /dev/null +++ b/cli/js/ops/get_random_values.ts @@ -0,0 +1,30 @@ +// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. +import { sendSync } from "./dispatch_json.ts"; +import { assert } from "../util.ts"; + +/** Synchronously collects cryptographically secure random values. The + * underlying CSPRNG in use is Rust's `rand::rngs::ThreadRng`. + * + * const arr = new Uint8Array(32); + * crypto.getRandomValues(arr); + */ +export function getRandomValues< + T extends + | Int8Array + | Uint8Array + | Uint8ClampedArray + | Int16Array + | Uint16Array + | Int32Array + | Uint32Array +>(typedArray: T): T { + assert(typedArray !== null, "Input must not be null"); + assert(typedArray.length <= 65536, "Input must not be longer than 65536"); + const ui8 = new Uint8Array( + typedArray.buffer, + typedArray.byteOffset, + typedArray.byteLength + ); + sendSync("op_get_random_values", {}, ui8); + return typedArray; +} diff --git a/cli/js/ops/os.ts b/cli/js/ops/os.ts new file mode 100644 index 000000000..2d27f7ef5 --- /dev/null +++ b/cli/js/ops/os.ts @@ -0,0 +1,227 @@ +// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. +import { sendSync } from "./dispatch_json.ts"; +import { errors } from "../errors.ts"; +import * as util from "../util.ts"; + +/** Get the loadavg. + * Requires the `--allow-env` flag. + * + * console.log(Deno.loadavg()); + */ +export function loadavg(): number[] { + return sendSync("op_loadavg"); +} + +/** Get the hostname. + * Requires the `--allow-env` flag. + * + * console.log(Deno.hostname()); + */ +export function hostname(): string { + return sendSync("op_hostname"); +} + +/** Get OS release. + * Requires the `--allow-env` flag. + * + * console.log(Deno.osRelease()); + */ +export function osRelease(): string { + return sendSync("op_os_release"); +} + +/** Exit the Deno process with optional exit code. */ +export function exit(code = 0): never { + sendSync("op_exit", { code }); + return util.unreachable(); +} + +function setEnv(key: string, value: string): void { + sendSync("op_set_env", { key, value }); +} + +function getEnv(key: string): string | undefined { + return sendSync("op_get_env", { key })[0]; +} + +/** Returns a snapshot of the environment variables at invocation. Mutating a + * property in the object will set that variable in the environment for + * the process. The environment object will only accept `string`s + * as values. + * + * console.log(Deno.env("SHELL")); + * const myEnv = Deno.env(); + * console.log(myEnv.SHELL); + * myEnv.TEST_VAR = "HELLO"; + * const newEnv = Deno.env(); + * console.log(myEnv.TEST_VAR == newEnv.TEST_VAR); + */ +export function env(): { [index: string]: string }; +export function env(key: string): string | undefined; +export function env( + key?: string +): { [index: string]: string } | string | undefined { + if (key) { + return getEnv(key); + } + const env = sendSync("op_env"); + return new Proxy(env, { + set(obj, prop: string, value: string): boolean { + setEnv(prop, value); + return Reflect.set(obj, prop, value); + } + }); +} + +type DirKind = + | "home" + | "cache" + | "config" + | "executable" + | "data" + | "data_local" + | "audio" + | "desktop" + | "document" + | "download" + | "font" + | "picture" + | "public" + | "template" + | "tmp" + | "video"; + +/** + * Returns the user and platform specific directories. + * Requires the `--allow-env` flag. + * Returns null if there is no applicable directory or if any other error + * occurs. + * + * Argument values: "home", "cache", "config", "executable", "data", + * "data_local", "audio", "desktop", "document", "download", "font", "picture", + * "public", "template", "video" + * + * "cache" + * |Platform | Value | Example | + * | ------- | ----------------------------------- | ---------------------------- | + * | Linux | `$XDG_CACHE_HOME` or `$HOME`/.cache | /home/alice/.cache | + * | macOS | `$HOME`/Library/Caches | /Users/Alice/Library/Caches | + * | Windows | `{FOLDERID_LocalAppData}` | C:\Users\Alice\AppData\Local | + * + * "config" + * |Platform | Value | Example | + * | ------- | ------------------------------------- | -------------------------------- | + * | Linux | `$XDG_CONFIG_HOME` or `$HOME`/.config | /home/alice/.config | + * | macOS | `$HOME`/Library/Preferences | /Users/Alice/Library/Preferences | + * | Windows | `{FOLDERID_RoamingAppData}` | C:\Users\Alice\AppData\Roaming | + * + * "executable" + * |Platform | Value | Example | + * | ------- | --------------------------------------------------------------- | -----------------------| + * | Linux | `XDG_BIN_HOME` or `$XDG_DATA_HOME`/../bin or `$HOME`/.local/bin | /home/alice/.local/bin | + * | macOS | - | - | + * | Windows | - | - | + * + * "data" + * |Platform | Value | Example | + * | ------- | ---------------------------------------- | ---------------------------------------- | + * | Linux | `$XDG_DATA_HOME` or `$HOME`/.local/share | /home/alice/.local/share | + * | macOS | `$HOME`/Library/Application Support | /Users/Alice/Library/Application Support | + * | Windows | `{FOLDERID_RoamingAppData}` | C:\Users\Alice\AppData\Roaming | + * + * "data_local" + * |Platform | Value | Example | + * | ------- | ---------------------------------------- | ---------------------------------------- | + * | Linux | `$XDG_DATA_HOME` or `$HOME`/.local/share | /home/alice/.local/share | + * | macOS | `$HOME`/Library/Application Support | /Users/Alice/Library/Application Support | + * | Windows | `{FOLDERID_LocalAppData}` | C:\Users\Alice\AppData\Local | + * + * "audio" + * |Platform | Value | Example | + * | ------- | ------------------ | -------------------- | + * | Linux | `XDG_MUSIC_DIR` | /home/alice/Music | + * | macOS | `$HOME`/Music | /Users/Alice/Music | + * | Windows | `{FOLDERID_Music}` | C:\Users\Alice\Music | + * + * "desktop" + * |Platform | Value | Example | + * | ------- | -------------------- | ---------------------- | + * | Linux | `XDG_DESKTOP_DIR` | /home/alice/Desktop | + * | macOS | `$HOME`/Desktop | /Users/Alice/Desktop | + * | Windows | `{FOLDERID_Desktop}` | C:\Users\Alice\Desktop | + * + * "document" + * |Platform | Value | Example | + * | ------- | ---------------------- | ------------------------ | + * | Linux | `XDG_DOCUMENTS_DIR` | /home/alice/Documents | + * | macOS | `$HOME`/Documents | /Users/Alice/Documents | + * | Windows | `{FOLDERID_Documents}` | C:\Users\Alice\Documents | + * + * "download" + * |Platform | Value | Example | + * | ------- | ---------------------- | ------------------------ | + * | Linux | `XDG_DOWNLOAD_DIR` | /home/alice/Downloads | + * | macOS | `$HOME`/Downloads | /Users/Alice/Downloads | + * | Windows | `{FOLDERID_Downloads}` | C:\Users\Alice\Downloads | + * + * "font" + * |Platform | Value | Example | + * | ------- | ---------------------------------------------------- | ------------------------------ | + * | Linux | `$XDG_DATA_HOME`/fonts or `$HOME`/.local/share/fonts | /home/alice/.local/share/fonts | + * | macOS | `$HOME/Library/Fonts` | /Users/Alice/Library/Fonts | + * | Windows | – | – | + * + * "picture" + * |Platform | Value | Example | + * | ------- | --------------------- | ----------------------- | + * | Linux | `XDG_PICTURES_DIR` | /home/alice/Pictures | + * | macOS | `$HOME`/Pictures | /Users/Alice/Pictures | + * | Windows | `{FOLDERID_Pictures}` | C:\Users\Alice\Pictures | + * + * "public" + * |Platform | Value | Example | + * | ------- | --------------------- | ------------------- | + * | Linux | `XDG_PUBLICSHARE_DIR` | /home/alice/Public | + * | macOS | `$HOME`/Public | /Users/Alice/Public | + * | Windows | `{FOLDERID_Public}` | C:\Users\Public | + * + * "template" + * |Platform | Value | Example | + * | ------- | ---------------------- | ---------------------------------------------------------- | + * | Linux | `XDG_TEMPLATES_DIR` | /home/alice/Templates | + * | macOS | – | – | + * | Windows | `{FOLDERID_Templates}` | C:\Users\Alice\AppData\Roaming\Microsoft\Windows\Templates | + * + * "tmp" + * + * |Platform | Value | Example | + * | ------- | ---------------------- | ---------------------------------------------------------- | + * | Linux | `TMPDIR` | /tmp | + * | macOS | `TMPDIR` | /tmp | + * | Windows | `{TMP}` | C:\Users\Alice\AppData\Local\Temp | + * + * "video" + * |Platform | Value | Example | + * | ------- | ------------------- | --------------------- | + * | Linux | `XDG_VIDEOS_DIR` | /home/alice/Videos | + * | macOS | `$HOME`/Movies | /Users/Alice/Movies | + * | Windows | `{FOLDERID_Videos}` | C:\Users\Alice\Videos | + */ +export function dir(kind: DirKind): string | null { + try { + return sendSync("op_get_dir", { kind }); + } catch (error) { + if (error instanceof errors.PermissionDenied) { + throw error; + } + return null; + } +} + +/** + * Returns the path to the current deno executable. + * Requires the `--allow-env` flag. + */ +export function execPath(): string { + return sendSync("op_exec_path"); +} diff --git a/cli/js/ops/repl.ts b/cli/js/ops/repl.ts new file mode 100644 index 000000000..3f40f4456 --- /dev/null +++ b/cli/js/ops/repl.ts @@ -0,0 +1,11 @@ +// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. + +import { sendSync, sendAsync } from "./dispatch_json.ts"; + +export function startRepl(historyFile: string): number { + return sendSync("op_repl_start", { historyFile }); +} + +export async function readline(rid: number, prompt: string): Promise { + return sendAsync("op_repl_readline", { rid, prompt }); +} diff --git a/cli/js/ops/resources.ts b/cli/js/ops/resources.ts new file mode 100644 index 000000000..b04810989 --- /dev/null +++ b/cli/js/ops/resources.ts @@ -0,0 +1,23 @@ +// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. +import { sendSync } from "./dispatch_json.ts"; + +export interface ResourceMap { + [rid: number]: string; +} + +/** Returns a map of open _file like_ resource ids along with their string + * representation. + */ +export function resources(): ResourceMap { + const res = sendSync("op_resources") as Array<[number, string]>; + const resources: ResourceMap = {}; + for (const resourceTuple of res) { + resources[resourceTuple[0]] = resourceTuple[1]; + } + return resources; +} + +/** Close the given resource ID. */ +export function close(rid: number): void { + sendSync("op_close", { rid }); +} diff --git a/cli/js/ops/runtime.ts b/cli/js/ops/runtime.ts new file mode 100644 index 000000000..7538ce12f --- /dev/null +++ b/cli/js/ops/runtime.ts @@ -0,0 +1,67 @@ +// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. + +import { sendSync } from "./dispatch_json.ts"; + +// TODO(bartlomieju): these two types are duplicated +// in `cli/js/build.ts` - deduplicate +export type OperatingSystem = "mac" | "win" | "linux"; +export type Arch = "x64" | "arm64"; + +export interface Start { + cwd: string; + pid: number; + args: string[]; + location: string; // Absolute URL. + repl: boolean; + debugFlag: boolean; + depsFlag: boolean; + typesFlag: boolean; + versionFlag: boolean; + denoVersion: string; + v8Version: string; + tsVersion: string; + noColor: boolean; + os: OperatingSystem; + arch: Arch; +} + +export function start(): Start { + return sendSync("op_start"); +} + +export interface Metrics { + opsDispatched: number; + opsDispatchedSync: number; + opsDispatchedAsync: number; + opsDispatchedAsyncUnref: number; + opsCompleted: number; + opsCompletedSync: number; + opsCompletedAsync: number; + opsCompletedAsyncUnref: number; + bytesSentControl: number; + bytesSentData: number; + bytesReceived: number; +} + +/** Receive metrics from the privileged side of Deno. + * + * > console.table(Deno.metrics()) + * ┌─────────────────────────┬────────┐ + * │ (index) │ Values │ + * ├─────────────────────────┼────────┤ + * │ opsDispatched │ 3 │ + * │ opsDispatchedSync │ 2 │ + * │ opsDispatchedAsync │ 1 │ + * │ opsDispatchedAsyncUnref │ 0 │ + * │ opsCompleted │ 3 │ + * │ opsCompletedSync │ 2 │ + * │ opsCompletedAsync │ 1 │ + * │ opsCompletedAsyncUnref │ 0 │ + * │ bytesSentControl │ 73 │ + * │ bytesSentData │ 0 │ + * │ bytesReceived │ 375 │ + * └─────────────────────────┴────────┘ + */ +export function metrics(): Metrics { + return sendSync("op_metrics"); +} diff --git a/cli/js/ops/runtime_compiler.ts b/cli/js/ops/runtime_compiler.ts new file mode 100644 index 000000000..035a4ef59 --- /dev/null +++ b/cli/js/ops/runtime_compiler.ts @@ -0,0 +1,23 @@ +// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. + +import { sendAsync } from "./dispatch_json.ts"; + +interface CompileRequest { + rootName: string; + sources?: Record; + options?: string; + bundle: boolean; +} + +export async function compile(request: CompileRequest): Promise { + return sendAsync("op_compile", request); +} + +interface TranspileRequest { + sources: Record; + options?: string; +} + +export async function transpile(request: TranspileRequest): Promise { + return sendAsync("op_transpile", request); +} diff --git a/cli/js/ops/tty.ts b/cli/js/ops/tty.ts new file mode 100644 index 000000000..2ad44d025 --- /dev/null +++ b/cli/js/ops/tty.ts @@ -0,0 +1,14 @@ +import { sendSync } from "./dispatch_json.ts"; + +/** Check if a given resource is TTY. */ +export function isatty(rid: number): boolean { + return sendSync("op_isatty", { rid }); +} + +/** Set TTY to be under raw mode or not. */ +export function setRaw(rid: number, mode: boolean): void { + sendSync("op_set_raw", { + rid, + mode + }); +} diff --git a/cli/js/os.ts b/cli/js/os.ts deleted file mode 100644 index 89632e34f..000000000 --- a/cli/js/os.ts +++ /dev/null @@ -1,227 +0,0 @@ -// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. -import { sendSync } from "./dispatch_json.ts"; -import { errors } from "./errors.ts"; -import * as util from "./util.ts"; - -/** Get the loadavg. - * Requires the `--allow-env` flag. - * - * console.log(Deno.loadavg()); - */ -export function loadavg(): number[] { - return sendSync("op_loadavg"); -} - -/** Get the hostname. - * Requires the `--allow-env` flag. - * - * console.log(Deno.hostname()); - */ -export function hostname(): string { - return sendSync("op_hostname"); -} - -/** Get OS release. - * Requires the `--allow-env` flag. - * - * console.log(Deno.osRelease()); - */ -export function osRelease(): string { - return sendSync("op_os_release"); -} - -/** Exit the Deno process with optional exit code. */ -export function exit(code = 0): never { - sendSync("op_exit", { code }); - return util.unreachable(); -} - -function setEnv(key: string, value: string): void { - sendSync("op_set_env", { key, value }); -} - -function getEnv(key: string): string | undefined { - return sendSync("op_get_env", { key })[0]; -} - -/** Returns a snapshot of the environment variables at invocation. Mutating a - * property in the object will set that variable in the environment for - * the process. The environment object will only accept `string`s - * as values. - * - * console.log(Deno.env("SHELL")); - * const myEnv = Deno.env(); - * console.log(myEnv.SHELL); - * myEnv.TEST_VAR = "HELLO"; - * const newEnv = Deno.env(); - * console.log(myEnv.TEST_VAR == newEnv.TEST_VAR); - */ -export function env(): { [index: string]: string }; -export function env(key: string): string | undefined; -export function env( - key?: string -): { [index: string]: string } | string | undefined { - if (key) { - return getEnv(key); - } - const env = sendSync("op_env"); - return new Proxy(env, { - set(obj, prop: string, value: string): boolean { - setEnv(prop, value); - return Reflect.set(obj, prop, value); - } - }); -} - -type DirKind = - | "home" - | "cache" - | "config" - | "executable" - | "data" - | "data_local" - | "audio" - | "desktop" - | "document" - | "download" - | "font" - | "picture" - | "public" - | "template" - | "tmp" - | "video"; - -/** - * Returns the user and platform specific directories. - * Requires the `--allow-env` flag. - * Returns null if there is no applicable directory or if any other error - * occurs. - * - * Argument values: "home", "cache", "config", "executable", "data", - * "data_local", "audio", "desktop", "document", "download", "font", "picture", - * "public", "template", "video" - * - * "cache" - * |Platform | Value | Example | - * | ------- | ----------------------------------- | ---------------------------- | - * | Linux | `$XDG_CACHE_HOME` or `$HOME`/.cache | /home/alice/.cache | - * | macOS | `$HOME`/Library/Caches | /Users/Alice/Library/Caches | - * | Windows | `{FOLDERID_LocalAppData}` | C:\Users\Alice\AppData\Local | - * - * "config" - * |Platform | Value | Example | - * | ------- | ------------------------------------- | -------------------------------- | - * | Linux | `$XDG_CONFIG_HOME` or `$HOME`/.config | /home/alice/.config | - * | macOS | `$HOME`/Library/Preferences | /Users/Alice/Library/Preferences | - * | Windows | `{FOLDERID_RoamingAppData}` | C:\Users\Alice\AppData\Roaming | - * - * "executable" - * |Platform | Value | Example | - * | ------- | --------------------------------------------------------------- | -----------------------| - * | Linux | `XDG_BIN_HOME` or `$XDG_DATA_HOME`/../bin or `$HOME`/.local/bin | /home/alice/.local/bin | - * | macOS | - | - | - * | Windows | - | - | - * - * "data" - * |Platform | Value | Example | - * | ------- | ---------------------------------------- | ---------------------------------------- | - * | Linux | `$XDG_DATA_HOME` or `$HOME`/.local/share | /home/alice/.local/share | - * | macOS | `$HOME`/Library/Application Support | /Users/Alice/Library/Application Support | - * | Windows | `{FOLDERID_RoamingAppData}` | C:\Users\Alice\AppData\Roaming | - * - * "data_local" - * |Platform | Value | Example | - * | ------- | ---------------------------------------- | ---------------------------------------- | - * | Linux | `$XDG_DATA_HOME` or `$HOME`/.local/share | /home/alice/.local/share | - * | macOS | `$HOME`/Library/Application Support | /Users/Alice/Library/Application Support | - * | Windows | `{FOLDERID_LocalAppData}` | C:\Users\Alice\AppData\Local | - * - * "audio" - * |Platform | Value | Example | - * | ------- | ------------------ | -------------------- | - * | Linux | `XDG_MUSIC_DIR` | /home/alice/Music | - * | macOS | `$HOME`/Music | /Users/Alice/Music | - * | Windows | `{FOLDERID_Music}` | C:\Users\Alice\Music | - * - * "desktop" - * |Platform | Value | Example | - * | ------- | -------------------- | ---------------------- | - * | Linux | `XDG_DESKTOP_DIR` | /home/alice/Desktop | - * | macOS | `$HOME`/Desktop | /Users/Alice/Desktop | - * | Windows | `{FOLDERID_Desktop}` | C:\Users\Alice\Desktop | - * - * "document" - * |Platform | Value | Example | - * | ------- | ---------------------- | ------------------------ | - * | Linux | `XDG_DOCUMENTS_DIR` | /home/alice/Documents | - * | macOS | `$HOME`/Documents | /Users/Alice/Documents | - * | Windows | `{FOLDERID_Documents}` | C:\Users\Alice\Documents | - * - * "download" - * |Platform | Value | Example | - * | ------- | ---------------------- | ------------------------ | - * | Linux | `XDG_DOWNLOAD_DIR` | /home/alice/Downloads | - * | macOS | `$HOME`/Downloads | /Users/Alice/Downloads | - * | Windows | `{FOLDERID_Downloads}` | C:\Users\Alice\Downloads | - * - * "font" - * |Platform | Value | Example | - * | ------- | ---------------------------------------------------- | ------------------------------ | - * | Linux | `$XDG_DATA_HOME`/fonts or `$HOME`/.local/share/fonts | /home/alice/.local/share/fonts | - * | macOS | `$HOME/Library/Fonts` | /Users/Alice/Library/Fonts | - * | Windows | – | – | - * - * "picture" - * |Platform | Value | Example | - * | ------- | --------------------- | ----------------------- | - * | Linux | `XDG_PICTURES_DIR` | /home/alice/Pictures | - * | macOS | `$HOME`/Pictures | /Users/Alice/Pictures | - * | Windows | `{FOLDERID_Pictures}` | C:\Users\Alice\Pictures | - * - * "public" - * |Platform | Value | Example | - * | ------- | --------------------- | ------------------- | - * | Linux | `XDG_PUBLICSHARE_DIR` | /home/alice/Public | - * | macOS | `$HOME`/Public | /Users/Alice/Public | - * | Windows | `{FOLDERID_Public}` | C:\Users\Public | - * - * "template" - * |Platform | Value | Example | - * | ------- | ---------------------- | ---------------------------------------------------------- | - * | Linux | `XDG_TEMPLATES_DIR` | /home/alice/Templates | - * | macOS | – | – | - * | Windows | `{FOLDERID_Templates}` | C:\Users\Alice\AppData\Roaming\Microsoft\Windows\Templates | - * - * "tmp" - * - * |Platform | Value | Example | - * | ------- | ---------------------- | ---------------------------------------------------------- | - * | Linux | `TMPDIR` | /tmp | - * | macOS | `TMPDIR` | /tmp | - * | Windows | `{TMP}` | C:\Users\Alice\AppData\Local\Temp | - * - * "video" - * |Platform | Value | Example | - * | ------- | ------------------- | --------------------- | - * | Linux | `XDG_VIDEOS_DIR` | /home/alice/Videos | - * | macOS | `$HOME`/Movies | /Users/Alice/Movies | - * | Windows | `{FOLDERID_Videos}` | C:\Users\Alice\Videos | - */ -export function dir(kind: DirKind): string | null { - try { - return sendSync("op_get_dir", { kind }); - } catch (error) { - if (error instanceof errors.PermissionDenied) { - throw error; - } - return null; - } -} - -/** - * Returns the path to the current deno executable. - * Requires the `--allow-env` flag. - */ -export function execPath(): string { - return sendSync("op_exec_path"); -} diff --git a/cli/js/performance.ts b/cli/js/performance.ts index 981be64d4..9d49e6a4c 100644 --- a/cli/js/performance.ts +++ b/cli/js/performance.ts @@ -1,5 +1,5 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. -import { sendSync } from "./dispatch_json.ts"; +import { sendSync } from "./ops/dispatch_json.ts"; interface NowResponse { seconds: number; diff --git a/cli/js/permissions.ts b/cli/js/permissions.ts index d414dd1ef..d3f3d163a 100644 --- a/cli/js/permissions.ts +++ b/cli/js/permissions.ts @@ -1,5 +1,5 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. -import { sendSync } from "./dispatch_json.ts"; +import { sendSync } from "./ops/dispatch_json.ts"; /** Permissions as granted by the caller * See: https://w3c.github.io/permissions/#permission-registry diff --git a/cli/js/plugins.ts b/cli/js/plugins.ts index 44a3083bb..2dbee4c74 100644 --- a/cli/js/plugins.ts +++ b/cli/js/plugins.ts @@ -1,4 +1,4 @@ -import { sendSync } from "./dispatch_json.ts"; +import { sendSync } from "./ops/dispatch_json.ts"; import { core } from "./core.ts"; export interface AsyncHandler { diff --git a/cli/js/process.ts b/cli/js/process.ts index 4c8685cae..dc1af51ce 100644 --- a/cli/js/process.ts +++ b/cli/js/process.ts @@ -1,6 +1,7 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. -import { sendSync, sendAsync } from "./dispatch_json.ts"; -import { File, close } from "./files.ts"; +import { sendSync, sendAsync } from "./ops/dispatch_json.ts"; +import { File } from "./files.ts"; +import { close } from "./ops/resources.ts"; import { ReadCloser, WriteCloser } from "./io.ts"; import { readAll } from "./buffer.ts"; import { assert, unreachable } from "./util.ts"; diff --git a/cli/js/read_dir.ts b/cli/js/read_dir.ts index d8c1a7db8..975f5d8b4 100644 --- a/cli/js/read_dir.ts +++ b/cli/js/read_dir.ts @@ -1,5 +1,5 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. -import { sendSync, sendAsync } from "./dispatch_json.ts"; +import { sendSync, sendAsync } from "./ops/dispatch_json.ts"; import { FileInfo, FileInfoImpl } from "./file_info.ts"; import { StatResponse } from "./stat.ts"; diff --git a/cli/js/read_link.ts b/cli/js/read_link.ts index 64c60eedb..3ff56b990 100644 --- a/cli/js/read_link.ts +++ b/cli/js/read_link.ts @@ -1,5 +1,5 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. -import { sendSync, sendAsync } from "./dispatch_json.ts"; +import { sendSync, sendAsync } from "./ops/dispatch_json.ts"; /** Returns the destination of the named symbolic link. * diff --git a/cli/js/realpath.ts b/cli/js/realpath.ts index c425049f4..5a0c1cbf3 100644 --- a/cli/js/realpath.ts +++ b/cli/js/realpath.ts @@ -1,5 +1,5 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. -import { sendSync, sendAsync } from "./dispatch_json.ts"; +import { sendSync, sendAsync } from "./ops/dispatch_json.ts"; /** Returns absolute normalized path with symbolic links resolved synchronously. * diff --git a/cli/js/remove.ts b/cli/js/remove.ts index 89e5850ab..37603bd0c 100644 --- a/cli/js/remove.ts +++ b/cli/js/remove.ts @@ -1,5 +1,5 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. -import { sendSync, sendAsync } from "./dispatch_json.ts"; +import { sendSync, sendAsync } from "./ops/dispatch_json.ts"; export interface RemoveOptions { /** Defaults to `false`. If set to `true`, path will be removed even if diff --git a/cli/js/rename.ts b/cli/js/rename.ts index ec5c18b87..eaa236336 100644 --- a/cli/js/rename.ts +++ b/cli/js/rename.ts @@ -1,5 +1,5 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. -import { sendSync, sendAsync } from "./dispatch_json.ts"; +import { sendSync, sendAsync } from "./ops/dispatch_json.ts"; /** Synchronously renames (moves) `oldpath` to `newpath`. If `newpath` already * exists and is not a directory, `renameSync()` replaces it. OS-specific diff --git a/cli/js/repl.ts b/cli/js/repl.ts index 0ef86ecd9..8325159dd 100644 --- a/cli/js/repl.ts +++ b/cli/js/repl.ts @@ -1,9 +1,9 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. -import { close } from "./files.ts"; -import { exit } from "./os.ts"; +import { exit } from "./ops/os.ts"; import { core } from "./core.ts"; import { stringifyArgs } from "./console.ts"; -import { sendSync, sendAsync } from "./dispatch_json.ts"; +import { startRepl, readline } from "./ops/repl.ts"; +import { close } from "./ops/resources.ts"; /** * REPL logging. @@ -41,15 +41,6 @@ const replCommands = { } }; -function startRepl(historyFile: string): number { - return sendSync("op_repl_start", { historyFile }); -} - -// @internal -export async function readline(rid: number, prompt: string): Promise { - return sendAsync("op_repl_readline", { rid, prompt }); -} - // Error messages that allow users to continue input // instead of throwing an error to REPL // ref: https://github.com/v8/v8/blob/master/src/message-template.h diff --git a/cli/js/resources.ts b/cli/js/resources.ts deleted file mode 100644 index 4c2de1fc3..000000000 --- a/cli/js/resources.ts +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. -import { sendSync } from "./dispatch_json.ts"; - -export interface ResourceMap { - [rid: number]: string; -} - -/** Returns a map of open _file like_ resource ids along with their string - * representation. - */ -export function resources(): ResourceMap { - const res = sendSync("op_resources") as Array<[number, string]>; - const resources: ResourceMap = {}; - for (const resourceTuple of res) { - resources[resourceTuple[0]] = resourceTuple[1]; - } - return resources; -} diff --git a/cli/js/runtime.ts b/cli/js/runtime.ts index ffa943501..9a304379f 100644 --- a/cli/js/runtime.ts +++ b/cli/js/runtime.ts @@ -1,32 +1,13 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. import { core } from "./core.ts"; import * as dispatch from "./dispatch.ts"; -import { sendSync } from "./dispatch_json.ts"; import { assert } from "./util.ts"; import * as util from "./util.ts"; -import { OperatingSystem, Arch } from "./build.ts"; import { setBuildInfo } from "./build.ts"; import { setVersions } from "./version.ts"; import { setLocation } from "./web/location.ts"; import { setPrepareStackTrace } from "./error_stack.ts"; - -interface Start { - cwd: string; - pid: number; - args: string[]; - location: string; // Absolute URL. - repl: boolean; - debugFlag: boolean; - depsFlag: boolean; - typesFlag: boolean; - versionFlag: boolean; - denoVersion: string; - v8Version: string; - tsVersion: string; - noColor: boolean; - os: OperatingSystem; - arch: Arch; -} +import { Start, start as startOp } from "./ops/runtime.ts"; export let OPS_CACHE: { [name: string]: number }; @@ -49,7 +30,7 @@ export function start(preserveDenoNamespace = true, source?: string): Start { // First we send an empty `Start` message to let the privileged side know we // are ready. The response should be a `StartRes` message containing the CLI // args and other info. - const s = sendSync("op_start"); + const s = startOp(); setVersions(s.denoVersion, s.v8Version, s.tsVersion); setBuildInfo(s.os, s.arch); diff --git a/cli/js/runtime_main.ts b/cli/js/runtime_main.ts index e05790e90..84ee43d37 100644 --- a/cli/js/runtime_main.ts +++ b/cli/js/runtime_main.ts @@ -9,7 +9,7 @@ import * as Deno from "./deno.ts"; import * as domTypes from "./web/dom_types.ts"; -import * as csprng from "./get_random_values.ts"; +import * as csprng from "./ops/get_random_values.ts"; import { readOnly, writable, diff --git a/cli/js/runtime_worker.ts b/cli/js/runtime_worker.ts index b3a5250fa..9cfd9229c 100644 --- a/cli/js/runtime_worker.ts +++ b/cli/js/runtime_worker.ts @@ -16,7 +16,7 @@ import { windowOrWorkerGlobalScopeProperties, eventTargetProperties } from "./globals.ts"; -import { sendSync } from "./dispatch_json.ts"; +import { sendSync } from "./ops/dispatch_json.ts"; import { log } from "./util.ts"; import { TextEncoder } from "./web/text_encoding.ts"; import * as runtime from "./runtime.ts"; diff --git a/cli/js/signals.ts b/cli/js/signals.ts index b79868888..71ac32ae9 100644 --- a/cli/js/signals.ts +++ b/cli/js/signals.ts @@ -1,6 +1,6 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. import { Signal } from "./process.ts"; -import { sendSync, sendAsync } from "./dispatch_json.ts"; +import { sendSync, sendAsync } from "./ops/dispatch_json.ts"; import { build } from "./build.ts"; /** diff --git a/cli/js/stat.ts b/cli/js/stat.ts index fa49953fb..a00a62d0c 100644 --- a/cli/js/stat.ts +++ b/cli/js/stat.ts @@ -1,5 +1,5 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. -import { sendSync, sendAsync } from "./dispatch_json.ts"; +import { sendSync, sendAsync } from "./ops/dispatch_json.ts"; import { FileInfo, FileInfoImpl } from "./file_info.ts"; /** @internal */ diff --git a/cli/js/symlink.ts b/cli/js/symlink.ts index e484ce4a3..9a63fca9f 100644 --- a/cli/js/symlink.ts +++ b/cli/js/symlink.ts @@ -1,5 +1,5 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. -import { sendSync, sendAsync } from "./dispatch_json.ts"; +import { sendSync, sendAsync } from "./ops/dispatch_json.ts"; import * as util from "./util.ts"; import { build } from "./build.ts"; diff --git a/cli/js/testing.ts b/cli/js/testing.ts index 4283f73d7..f851b8fcc 100644 --- a/cli/js/testing.ts +++ b/cli/js/testing.ts @@ -1,6 +1,6 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. import { red, green, bgRed, gray, italic } from "./colors.ts"; -import { exit } from "./os.ts"; +import { exit } from "./ops/os.ts"; import { Console } from "./console.ts"; function formatDuration(time = 0): string { diff --git a/cli/js/timers.ts b/cli/js/timers.ts index 2b29f2a55..31f81332a 100644 --- a/cli/js/timers.ts +++ b/cli/js/timers.ts @@ -1,6 +1,6 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. import { assert } from "./util.ts"; -import { sendSync, sendAsync } from "./dispatch_json.ts"; +import { sendSync, sendAsync } from "./ops/dispatch_json.ts"; import { RBTree } from "./rbtree.ts"; const { console } = globalThis; diff --git a/cli/js/tls.ts b/cli/js/tls.ts index 2780956a1..98a6586bb 100644 --- a/cli/js/tls.ts +++ b/cli/js/tls.ts @@ -1,5 +1,5 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. -import { sendAsync, sendSync } from "./dispatch_json.ts"; +import { sendAsync, sendSync } from "./ops/dispatch_json.ts"; import { Listener, Transport, Conn, ConnImpl, ListenerImpl } from "./net.ts"; // TODO(ry) There are many configuration options to add... diff --git a/cli/js/truncate.ts b/cli/js/truncate.ts index 15143479f..b43c88f60 100644 --- a/cli/js/truncate.ts +++ b/cli/js/truncate.ts @@ -1,5 +1,5 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. -import { sendSync, sendAsync } from "./dispatch_json.ts"; +import { sendSync, sendAsync } from "./ops/dispatch_json.ts"; function coerceLen(len?: number): number { if (!len) { diff --git a/cli/js/tty.ts b/cli/js/tty.ts deleted file mode 100644 index 2ad44d025..000000000 --- a/cli/js/tty.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { sendSync } from "./dispatch_json.ts"; - -/** Check if a given resource is TTY. */ -export function isatty(rid: number): boolean { - return sendSync("op_isatty", { rid }); -} - -/** Set TTY to be under raw mode or not. */ -export function setRaw(rid: number, mode: boolean): void { - sendSync("op_set_raw", { - rid, - mode - }); -} diff --git a/cli/js/utime.ts b/cli/js/utime.ts index 2026e60bf..9224a3ffa 100644 --- a/cli/js/utime.ts +++ b/cli/js/utime.ts @@ -1,5 +1,5 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. -import { sendSync, sendAsync } from "./dispatch_json.ts"; +import { sendSync, sendAsync } from "./ops/dispatch_json.ts"; function toSecondsFromEpoch(v: number | Date): number { return v instanceof Date ? v.valueOf() / 1000 : v; diff --git a/cli/js/web/fetch.ts b/cli/js/web/fetch.ts index 17cd43129..fbe795b4a 100644 --- a/cli/js/web/fetch.ts +++ b/cli/js/web/fetch.ts @@ -10,12 +10,13 @@ import { TextDecoder, TextEncoder } from "./text_encoding.ts"; import { DenoBlob, bytesSymbol as blobBytesSymbol } from "./blob.ts"; import { Headers } from "./headers.ts"; import * as io from "../io.ts"; -import { read, close } from "../files.ts"; +import { read } from "../files.ts"; +import { close } from "../ops/resources.ts"; import { Buffer } from "../buffer.ts"; import { FormData } from "./form_data.ts"; import { URL } from "./url.ts"; import { URLSearchParams } from "./url_search_params.ts"; -import { sendAsync } from "../dispatch_json.ts"; +import { fetch as opFetch, FetchResponse } from "../ops/fetch.ts"; function getHeaderValueParams(value: string): Map { const params = new Map(); @@ -439,13 +440,6 @@ export class Response implements domTypes.Response { } } -interface FetchResponse { - bodyRid: number; - status: number; - statusText: string; - headers: Array<[string, string]>; -} - async function sendFetchReq( url: string, method: string | null, @@ -457,18 +451,13 @@ async function sendFetchReq( headerArray = Array.from(headers.entries()); } - let zeroCopy = undefined; - if (body) { - zeroCopy = new Uint8Array(body.buffer, body.byteOffset, body.byteLength); - } - const args = { method, url, headers: headerArray }; - return (await sendAsync("op_fetch", args, zeroCopy)) as FetchResponse; + return await opFetch(args, body); } /** Fetch a resource from the network. */ diff --git a/cli/js/web/url.ts b/cli/js/web/url.ts index 4cf9ae257..076ec81f1 100644 --- a/cli/js/web/url.ts +++ b/cli/js/web/url.ts @@ -1,7 +1,7 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. import * as urlSearchParams from "./url_search_params.ts"; import * as domTypes from "./dom_types.ts"; -import { getRandomValues } from "../get_random_values.ts"; +import { getRandomValues } from "../ops/get_random_values.ts"; import { customInspect } from "../console.ts"; interface URLParts { diff --git a/cli/js/workers.ts b/cli/js/workers.ts index 95012e1b8..421975e20 100644 --- a/cli/js/workers.ts +++ b/cli/js/workers.ts @@ -1,6 +1,6 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. /* eslint-disable @typescript-eslint/no-explicit-any */ -import { sendAsync, sendSync } from "./dispatch_json.ts"; +import { sendAsync, sendSync } from "./ops/dispatch_json.ts"; import { log } from "./util.ts"; import { TextDecoder, TextEncoder } from "./web/text_encoding.ts"; /* -- cgit v1.2.3