summaryrefslogtreecommitdiff
path: root/cli/js/plugins.ts
blob: 498da8e16f23e4d49a23ab50d94886390ba5362c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
import { openPlugin as openPluginOp } from "./ops/plugins.ts";
import { core } from "./core.ts";
import { close } from "./ops/resources.ts";

export interface AsyncHandler {
  (msg: Uint8Array): void;
}

interface PluginOp {
  dispatch(
    control: Uint8Array,
    zeroCopy?: ArrayBufferView | null
  ): Uint8Array | null;
  setAsyncHandler(handler: AsyncHandler): void;
}

class PluginOpImpl implements PluginOp {
  readonly #opId: number;

  constructor(opId: number) {
    this.#opId = opId;
  }

  dispatch(
    control: Uint8Array,
    zeroCopy?: ArrayBufferView | null
  ): Uint8Array | null {
    return core.dispatch(this.#opId, control, zeroCopy);
  }

  setAsyncHandler(handler: AsyncHandler): void {
    core.setAsyncHandler(this.#opId, handler);
  }
}

interface Plugin {
  ops: {
    [name: string]: PluginOp;
  };
  close(): void;
}

class PluginImpl implements Plugin {
  #ops: { [name: string]: PluginOp } = {};

  constructor(readonly rid: number, ops: { [name: string]: number }) {
    for (const op in ops) {
      this.#ops[op] = new PluginOpImpl(ops[op]);
    }
  }

  get ops(): { [name: string]: PluginOp } {
    return Object.assign({}, this.#ops);
  }

  close(): void {
    close(this.rid);
  }
}

export function openPlugin(filename: string): Plugin {
  const response = openPluginOp(filename);
  return new PluginImpl(response.rid, response.ops);
}