-
-
Notifications
You must be signed in to change notification settings - Fork 11
/
plug.ts
111 lines (92 loc) 路 2.35 KB
/
plug.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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
import {
Cache,
extname,
} from "./deps.ts";
export interface CrossOptions {
name: string;
urls: { [os in typeof Deno.build.os]?: string };
policy?: CachePolicy;
cache?: string;
}
export interface SingleOptions {
name: string;
url: string;
policy?: CachePolicy;
cache?: string;
}
export type Options = CrossOptions | SingleOptions;
export enum CachePolicy {
NONE,
STORE,
}
interface UnstableCore {
ops: () => { [key: string]: number };
setAsyncHandler(rid: number, handler: (response: Uint8Array) => void): void;
dispatch(
rid: number,
// deno-lint-ignore no-explicit-any
msg: any,
buf?: ArrayBufferView,
): Uint8Array | undefined;
}
export class PlugError extends Error {
constructor(message: string) {
super(message);
this.name = "PlugError";
this.stack = undefined;
}
}
export class PlugImportError extends Error {
constructor(message: string) {
super(message);
this.name = "PlugImportError";
this.stack = undefined;
}
}
export async function prepare(options: Options): Promise<number> {
const directory = options.cache ?? Cache.options.directory;
const policy = options.policy === CachePolicy.NONE
? Cache.RELOAD_POLICY
: undefined;
Cache.configure({ directory });
let url;
if ("urls" in options) {
url = options.urls[os];
if (!url) {
throw new PlugImportError(`URL for "${os}" platform was not provided.`);
}
} else {
url = options.url;
}
const pref = prefixes[os];
const ext = extensions[os];
url = Object.values(extensions).includes(extname(url))
? url
: `${url}${(url.endsWith("/") ? "" : "/")}${pref}${options.name}${ext}`;
const plug = Cache.namespace("plug");
const file = await plug.fetch(url, policy);
// deno-lint-ignore ban-ts-comment
// @ts-ignore
return Deno.openPlugin(file.path);
}
export function getOpId(op: string): number {
const id = core.ops()[op];
if (!(id > 0)) {
throw new PlugError(`Bad op id for "${op}"`);
}
return id;
}
// deno-lint-ignore ban-ts-comment
// @ts-ignore
export const core = Deno.core as UnstableCore;
export const os = Deno.build.os;
export const extensions: { [os in typeof Deno.build.os]: string } = {
darwin: ".dylib",
linux: ".so",
windows: ".dll",
};
export const prefixes: { [os in typeof Deno.build.os]: string } = {
darwin: "lib",
linux: "lib",
windows: "",
};