diff options
Diffstat (limited to 'cli/js/dispatch_json.ts')
-rw-r--r-- | cli/js/dispatch_json.ts | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/cli/js/dispatch_json.ts b/cli/js/dispatch_json.ts new file mode 100644 index 000000000..572ec855a --- /dev/null +++ b/cli/js/dispatch_json.ts @@ -0,0 +1,86 @@ +// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. +import * as util from "./util.ts"; +import { TextEncoder, TextDecoder } from "./text_encoding.ts"; +import { core } from "./core.ts"; +import { ErrorKind, DenoError } 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<number, util.Resolvable<JsonResponse>>(); +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 DenoError(res.err!.kind, res.err!.message); + } + util.assert(res.ok != null); + return res.ok!; +} + +export function asyncMsgFromRust(opId: number, 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( + opId: number, + args: object = {}, + zeroCopy?: Uint8Array +): Ok { + 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( + opId: number, + args: object = {}, + zeroCopy?: Uint8Array +): Promise<Ok> { + const promiseId = nextPromiseId(); + args = Object.assign(args, { promiseId }); + const promise = util.createResolvable<Ok>(); + promiseTable.set(promiseId, promise); + + const argsUi8 = encode(args); + const resUi8 = core.dispatch(opId, argsUi8, zeroCopy); + util.assert(resUi8 == null); + + const res = await promise; + return unwrapResponse(res); +} |