forked from lemarier/wry_deno
-
Notifications
You must be signed in to change notification settings - Fork 0
/
plugin.ts
88 lines (71 loc) · 1.95 KB
/
plugin.ts
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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
import { Plug } from "./deps.ts";
const VERSION = "0.1.2";
const PLUGIN_URL = Deno.env.get("PLUGIN_URL") ??
`https://github.com/lemarier/wry_deno/releases/download/${VERSION}/`;
const DEBUG = Boolean(Deno.env.get("DEBUG"));
const encoder = new TextEncoder();
const decoder = new TextDecoder();
let rid: number | undefined;
function deserialize(text: string): unknown {
return JSON.parse(
text.replace(/([^\"]+\"\:\s*)(\d{16,})/g, '$1"$2n"'),
(_, v) => {
if (typeof v === "string" && /^\d{16,}n$/.test(v)) {
v = BigInt(v.slice(0, -1));
}
return v;
},
);
}
function serialize(value: unknown, space?: number): string {
return JSON.stringify(value, (_, v) => {
if (typeof v === "bigint") {
v = v.toString() + "n";
}
return v;
}, space).replace(/(?:\")(\d{16,})(?:n\")/g, "$1");
}
function decode(data: Uint8Array): unknown {
const text = decoder.decode(data);
return deserialize(text);
}
function encode(data: unknown): Uint8Array {
const text = serialize(data);
return encoder.encode(text);
}
export type Result<T> = { err: string } | { ok: T };
export function sync<T>(op: string, data: unknown = {}): T {
if (rid === undefined) {
throw "The plugin must be initialized before use";
}
const opId = Plug.getOpId(op);
const response = Plug.core.dispatch(opId, encode(data))!;
return decode(response) as T;
}
export function unwrap<T>(result: Result<T>): T {
if ("err" in result) {
throw (result as { err: string }).err;
}
if ("ok" in result) {
return (result as { ok: T }).ok;
}
throw `Invalid result (${JSON.stringify(result)})`;
}
/**
* Loads the plugin
*/
export async function load(cache = !DEBUG) {
unload();
rid = await Plug.prepare({
name: "wry_deno",
url: PLUGIN_URL,
policy: cache ? Plug.CachePolicy.STORE : Plug.CachePolicy.NONE,
});
}
/**
* Frees the plugin
*/
export function unload() {
if (rid !== undefined) Deno.close(rid);
rid = undefined;
}