@depup/vitest 4.0.18-depup.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +691 -0
- package/README.md +7 -0
- package/browser/context.d.ts +7 -0
- package/browser/context.js +20 -0
- package/config.d.ts +3 -0
- package/coverage.d.ts +1 -0
- package/dist/browser.d.ts +46 -0
- package/dist/browser.js +20 -0
- package/dist/chunks/_commonjsHelpers.D26ty3Ew.js +6 -0
- package/dist/chunks/base.CJ0Y4ePK.js +165 -0
- package/dist/chunks/benchmark.B3N2zMcH.js +40 -0
- package/dist/chunks/benchmark.d.DAaHLpsq.d.ts +24 -0
- package/dist/chunks/browser.d.ChKACdzH.d.ts +59 -0
- package/dist/chunks/cac.DVeoLl0M.js +1409 -0
- package/dist/chunks/cli-api.B7PN_QUv.js +13657 -0
- package/dist/chunks/config.d.Cy95HiCx.d.ts +210 -0
- package/dist/chunks/console.Cf-YriPC.js +146 -0
- package/dist/chunks/constants.D_Q9UYh-.js +36 -0
- package/dist/chunks/coverage.AVPTjMgw.js +3292 -0
- package/dist/chunks/coverage.D_JHT54q.js +25 -0
- package/dist/chunks/coverage.d.BZtK59WP.d.ts +37 -0
- package/dist/chunks/creator.DAmOKTvJ.js +673 -0
- package/dist/chunks/date.Bq6ZW5rf.js +73 -0
- package/dist/chunks/defaults.BOqNVLsY.js +74 -0
- package/dist/chunks/env.D4Lgay0q.js +8 -0
- package/dist/chunks/environment.d.CrsxCzP1.d.ts +29 -0
- package/dist/chunks/evaluatedModules.Dg1zASAC.js +17 -0
- package/dist/chunks/evaluatedModules.d.BxJ5omdx.d.ts +7 -0
- package/dist/chunks/git.Bm2pzPAa.js +71 -0
- package/dist/chunks/global.d.B15mdLcR.d.ts +99 -0
- package/dist/chunks/globals.DOayXfHP.js +30 -0
- package/dist/chunks/index.6Qv1eEA6.js +109 -0
- package/dist/chunks/index.C5r1PdPD.js +231 -0
- package/dist/chunks/index.Chj8NDwU.js +206 -0
- package/dist/chunks/index.CyBMJtT7.js +727 -0
- package/dist/chunks/index.D3XRDfWc.js +213 -0
- package/dist/chunks/index.D4KonVSU.js +6343 -0
- package/dist/chunks/index.M8mOzt4Y.js +3839 -0
- package/dist/chunks/index.Z5E_ObnR.js +37 -0
- package/dist/chunks/init-forks._y3TW739.js +41 -0
- package/dist/chunks/init-threads.DBO2kn-p.js +18 -0
- package/dist/chunks/init.B6MLFIaN.js +334 -0
- package/dist/chunks/inspector.CvyFGlXm.js +53 -0
- package/dist/chunks/modules.BJuCwlRJ.js +36 -0
- package/dist/chunks/node.Ce0vMQM7.js +14 -0
- package/dist/chunks/plugin.d.CtqpEehP.d.ts +38 -0
- package/dist/chunks/reporters.d.CWXNI2jG.d.ts +3271 -0
- package/dist/chunks/rpc.BoxB0q7B.js +76 -0
- package/dist/chunks/rpc.d.RH3apGEf.d.ts +64 -0
- package/dist/chunks/setup-common.Cm-kSBVi.js +60 -0
- package/dist/chunks/startModuleRunner.DEj0jb3e.js +861 -0
- package/dist/chunks/suite.d.BJWk38HB.d.ts +10 -0
- package/dist/chunks/test.B8ej_ZHS.js +254 -0
- package/dist/chunks/traces.CCmnQaNT.js +217 -0
- package/dist/chunks/traces.d.402V_yFI.d.ts +18 -0
- package/dist/chunks/utils.DvEY5TfP.js +52 -0
- package/dist/chunks/vi.2VT5v0um.js +3919 -0
- package/dist/chunks/vm.D3epNOPZ.js +744 -0
- package/dist/chunks/worker.d.Dyxm8DEL.d.ts +255 -0
- package/dist/cli.js +28 -0
- package/dist/config.cjs +94 -0
- package/dist/config.d.ts +104 -0
- package/dist/config.js +15 -0
- package/dist/coverage.d.ts +118 -0
- package/dist/coverage.js +23 -0
- package/dist/environments.d.ts +22 -0
- package/dist/environments.js +3 -0
- package/dist/index.d.ts +510 -0
- package/dist/index.js +20 -0
- package/dist/mocker.d.ts +1 -0
- package/dist/mocker.js +1 -0
- package/dist/module-evaluator.d.ts +124 -0
- package/dist/module-evaluator.js +343 -0
- package/dist/module-runner.js +17 -0
- package/dist/node.d.ts +251 -0
- package/dist/node.js +98 -0
- package/dist/path.js +7 -0
- package/dist/reporters.d.ts +27 -0
- package/dist/reporters.js +24 -0
- package/dist/runners.d.ts +50 -0
- package/dist/runners.js +19 -0
- package/dist/snapshot.d.ts +9 -0
- package/dist/snapshot.js +4 -0
- package/dist/spy.js +1 -0
- package/dist/suite.d.ts +5 -0
- package/dist/suite.js +6 -0
- package/dist/worker.d.ts +32 -0
- package/dist/worker.js +48 -0
- package/dist/workers/forks.js +54 -0
- package/dist/workers/runVmTests.js +95 -0
- package/dist/workers/threads.js +55 -0
- package/dist/workers/vmForks.js +36 -0
- package/dist/workers/vmThreads.js +37 -0
- package/environments.d.ts +1 -0
- package/globals.d.ts +20 -0
- package/import-meta.d.ts +5 -0
- package/importMeta.d.ts +4 -0
- package/index.cjs +5 -0
- package/index.d.cts +1 -0
- package/jsdom.d.ts +6 -0
- package/mocker.d.ts +1 -0
- package/node.d.ts +1 -0
- package/optional-types.d.ts +7 -0
- package/package.json +224 -0
- package/reporters.d.ts +1 -0
- package/runners.d.ts +1 -0
- package/snapshot.d.ts +1 -0
- package/suite.d.ts +1 -0
- package/suppress-warnings.cjs +21 -0
- package/vitest.mjs +2 -0
- package/worker.d.ts +1 -0
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import { getTasks, getFullName, getTests } from '@vitest/runner/utils';
|
|
3
|
+
import * as pathe from 'pathe';
|
|
4
|
+
import c from 'tinyrainbow';
|
|
5
|
+
import { g as getStateSymbol, t as truncateString, F as F_RIGHT, D as DefaultReporter, f as formatProjectName, s as separator } from './index.M8mOzt4Y.js';
|
|
6
|
+
import { stripVTControlCharacters } from 'node:util';
|
|
7
|
+
import { notNullish } from '@vitest/utils/helpers';
|
|
8
|
+
|
|
9
|
+
function createBenchmarkJsonReport(files) {
|
|
10
|
+
const report = { files: [] };
|
|
11
|
+
for (const file of files) {
|
|
12
|
+
const groups = [];
|
|
13
|
+
for (const task of getTasks(file)) if (task?.type === "suite") {
|
|
14
|
+
const benchmarks = [];
|
|
15
|
+
for (const t of task.tasks) {
|
|
16
|
+
const benchmark = t.meta.benchmark && t.result?.benchmark;
|
|
17
|
+
if (benchmark) benchmarks.push({
|
|
18
|
+
id: t.id,
|
|
19
|
+
...benchmark,
|
|
20
|
+
samples: []
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
if (benchmarks.length) groups.push({
|
|
24
|
+
fullName: getFullName(task, " > "),
|
|
25
|
+
benchmarks
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
report.files.push({
|
|
29
|
+
filepath: file.filepath,
|
|
30
|
+
groups
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
return report;
|
|
34
|
+
}
|
|
35
|
+
function flattenFormattedBenchmarkReport(report) {
|
|
36
|
+
const flat = {};
|
|
37
|
+
for (const file of report.files) for (const group of file.groups) for (const t of group.benchmarks) flat[t.id] = t;
|
|
38
|
+
return flat;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const outputMap = /* @__PURE__ */ new WeakMap();
|
|
42
|
+
function formatNumber(number) {
|
|
43
|
+
const res = String(number.toFixed(number < 100 ? 4 : 2)).split(".");
|
|
44
|
+
return res[0].replace(/(?=(?:\d{3})+$)\B/g, ",") + (res[1] ? `.${res[1]}` : "");
|
|
45
|
+
}
|
|
46
|
+
const tableHead = [
|
|
47
|
+
"name",
|
|
48
|
+
"hz",
|
|
49
|
+
"min",
|
|
50
|
+
"max",
|
|
51
|
+
"mean",
|
|
52
|
+
"p75",
|
|
53
|
+
"p99",
|
|
54
|
+
"p995",
|
|
55
|
+
"p999",
|
|
56
|
+
"rme",
|
|
57
|
+
"samples"
|
|
58
|
+
];
|
|
59
|
+
function renderBenchmarkItems(result) {
|
|
60
|
+
return [
|
|
61
|
+
result.name,
|
|
62
|
+
formatNumber(result.hz || 0),
|
|
63
|
+
formatNumber(result.min || 0),
|
|
64
|
+
formatNumber(result.max || 0),
|
|
65
|
+
formatNumber(result.mean || 0),
|
|
66
|
+
formatNumber(result.p75 || 0),
|
|
67
|
+
formatNumber(result.p99 || 0),
|
|
68
|
+
formatNumber(result.p995 || 0),
|
|
69
|
+
formatNumber(result.p999 || 0),
|
|
70
|
+
`±${(result.rme || 0).toFixed(2)}%`,
|
|
71
|
+
(result.sampleCount || 0).toString()
|
|
72
|
+
];
|
|
73
|
+
}
|
|
74
|
+
function computeColumnWidths(results) {
|
|
75
|
+
const rows = [tableHead, ...results.map((v) => renderBenchmarkItems(v))];
|
|
76
|
+
return Array.from(tableHead, (_, i) => Math.max(...rows.map((row) => stripVTControlCharacters(row[i]).length)));
|
|
77
|
+
}
|
|
78
|
+
function padRow(row, widths) {
|
|
79
|
+
return row.map((v, i) => i ? v.padStart(widths[i], " ") : v.padEnd(widths[i], " "));
|
|
80
|
+
}
|
|
81
|
+
function renderTableHead(widths) {
|
|
82
|
+
return " ".repeat(3) + padRow(tableHead, widths).map(c.bold).join(" ");
|
|
83
|
+
}
|
|
84
|
+
function renderBenchmark(result, widths) {
|
|
85
|
+
const padded = padRow(renderBenchmarkItems(result), widths);
|
|
86
|
+
return [
|
|
87
|
+
padded[0],
|
|
88
|
+
c.blue(padded[1]),
|
|
89
|
+
c.cyan(padded[2]),
|
|
90
|
+
c.cyan(padded[3]),
|
|
91
|
+
c.cyan(padded[4]),
|
|
92
|
+
c.cyan(padded[5]),
|
|
93
|
+
c.cyan(padded[6]),
|
|
94
|
+
c.cyan(padded[7]),
|
|
95
|
+
c.cyan(padded[8]),
|
|
96
|
+
c.dim(padded[9]),
|
|
97
|
+
c.dim(padded[10])
|
|
98
|
+
].join(" ");
|
|
99
|
+
}
|
|
100
|
+
function renderTable(options) {
|
|
101
|
+
const output = [];
|
|
102
|
+
const benchMap = {};
|
|
103
|
+
for (const task of options.tasks) if (task.meta.benchmark && task.result?.benchmark) benchMap[task.id] = {
|
|
104
|
+
current: task.result.benchmark,
|
|
105
|
+
baseline: options.compare?.[task.id]
|
|
106
|
+
};
|
|
107
|
+
const benchCount = Object.entries(benchMap).length;
|
|
108
|
+
const columnWidths = computeColumnWidths(Object.values(benchMap).flatMap((v) => [v.current, v.baseline]).filter(notNullish));
|
|
109
|
+
let idx = 0;
|
|
110
|
+
const padding = " ".repeat(1 );
|
|
111
|
+
for (const task of options.tasks) {
|
|
112
|
+
const duration = task.result?.duration;
|
|
113
|
+
const bench = benchMap[task.id];
|
|
114
|
+
let prefix = "";
|
|
115
|
+
if (idx === 0 && task.meta?.benchmark) prefix += `${renderTableHead(columnWidths)}\n${padding}`;
|
|
116
|
+
prefix += ` ${getStateSymbol(task)} `;
|
|
117
|
+
let suffix = "";
|
|
118
|
+
if (task.type === "suite") suffix += c.dim(` (${getTests(task).length})`);
|
|
119
|
+
if (task.mode === "skip" || task.mode === "todo") suffix += c.dim(c.gray(" [skipped]"));
|
|
120
|
+
if (duration != null) {
|
|
121
|
+
const color = duration > options.slowTestThreshold ? c.yellow : c.green;
|
|
122
|
+
suffix += color(` ${Math.round(duration)}${c.dim("ms")}`);
|
|
123
|
+
}
|
|
124
|
+
if (options.showHeap && task.result?.heap != null) suffix += c.magenta(` ${Math.floor(task.result.heap / 1024 / 1024)} MB heap used`);
|
|
125
|
+
if (bench) {
|
|
126
|
+
let body = renderBenchmark(bench.current, columnWidths);
|
|
127
|
+
if (options.compare && bench.baseline) {
|
|
128
|
+
if (bench.current.hz) {
|
|
129
|
+
const diff = bench.current.hz / bench.baseline.hz;
|
|
130
|
+
const diffFixed = diff.toFixed(2);
|
|
131
|
+
if (diffFixed === "1.0.0") body += c.gray(` [${diffFixed}x]`);
|
|
132
|
+
if (diff > 1) body += c.blue(` [${diffFixed}x] ⇑`);
|
|
133
|
+
else body += c.red(` [${diffFixed}x] ⇓`);
|
|
134
|
+
}
|
|
135
|
+
output.push(padding + prefix + body + suffix);
|
|
136
|
+
const bodyBaseline = renderBenchmark(bench.baseline, columnWidths);
|
|
137
|
+
output.push(`${padding} ${bodyBaseline} ${c.dim("(baseline)")}`);
|
|
138
|
+
} else {
|
|
139
|
+
if (bench.current.rank === 1 && benchCount > 1) body += c.bold(c.green(" fastest"));
|
|
140
|
+
if (bench.current.rank === benchCount && benchCount > 2) body += c.bold(c.gray(" slowest"));
|
|
141
|
+
output.push(padding + prefix + body + suffix);
|
|
142
|
+
}
|
|
143
|
+
} else output.push(padding + prefix + task.name + suffix);
|
|
144
|
+
if (task.result?.state !== "pass" && outputMap.get(task) != null) {
|
|
145
|
+
let data = outputMap.get(task);
|
|
146
|
+
if (typeof data === "string") {
|
|
147
|
+
data = stripVTControlCharacters(data.trim().split("\n").filter(Boolean).pop());
|
|
148
|
+
if (data === "") data = void 0;
|
|
149
|
+
}
|
|
150
|
+
if (data != null) {
|
|
151
|
+
const out = ` ${" ".repeat(options.level)}${F_RIGHT} ${data}`;
|
|
152
|
+
output.push(c.gray(truncateString(out, options.columns)));
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
idx++;
|
|
156
|
+
}
|
|
157
|
+
return output.filter(Boolean).join("\n");
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
class BenchmarkReporter extends DefaultReporter {
|
|
161
|
+
compare;
|
|
162
|
+
async onInit(ctx) {
|
|
163
|
+
super.onInit(ctx);
|
|
164
|
+
if (this.ctx.config.benchmark?.compare) {
|
|
165
|
+
const compareFile = pathe.resolve(this.ctx.config.root, this.ctx.config.benchmark?.compare);
|
|
166
|
+
try {
|
|
167
|
+
this.compare = flattenFormattedBenchmarkReport(JSON.parse(await fs.promises.readFile(compareFile, "utf-8")));
|
|
168
|
+
} catch (e) {
|
|
169
|
+
this.error(`Failed to read '${compareFile}'`, e);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
onTaskUpdate(packs) {
|
|
174
|
+
for (const pack of packs) {
|
|
175
|
+
const task = this.ctx.state.idMap.get(pack[0]);
|
|
176
|
+
if (task?.type === "suite" && task.result?.state !== "run") task.tasks.filter((task) => task.result?.benchmark).sort((benchA, benchB) => benchA.result.benchmark.mean - benchB.result.benchmark.mean).forEach((bench, idx) => {
|
|
177
|
+
bench.result.benchmark.rank = Number(idx) + 1;
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
onTestSuiteResult(testSuite) {
|
|
182
|
+
super.onTestSuiteResult(testSuite);
|
|
183
|
+
this.printSuiteTable(testSuite);
|
|
184
|
+
}
|
|
185
|
+
printTestModule(testModule) {
|
|
186
|
+
this.printSuiteTable(testModule);
|
|
187
|
+
}
|
|
188
|
+
printSuiteTable(testTask) {
|
|
189
|
+
const state = testTask.state();
|
|
190
|
+
if (state === "pending" || state === "queued") return;
|
|
191
|
+
const benches = testTask.task.tasks.filter((t) => t.meta.benchmark);
|
|
192
|
+
const duration = testTask.task.result?.duration || 0;
|
|
193
|
+
if (benches.length > 0 && benches.every((t) => t.result?.state !== "run" && t.result?.state !== "queued")) {
|
|
194
|
+
let title = `\n ${getStateSymbol(testTask.task)} ${formatProjectName(testTask.project)}${getFullName(testTask.task, separator)}`;
|
|
195
|
+
if (duration != null && duration > this.ctx.config.slowTestThreshold) title += c.yellow(` ${Math.round(duration)}${c.dim("ms")}`);
|
|
196
|
+
this.log(title);
|
|
197
|
+
this.log(renderTable({
|
|
198
|
+
tasks: benches,
|
|
199
|
+
level: 1,
|
|
200
|
+
columns: this.ctx.logger.getColumns(),
|
|
201
|
+
compare: this.compare,
|
|
202
|
+
showHeap: this.ctx.config.logHeapUsage,
|
|
203
|
+
slowTestThreshold: this.ctx.config.slowTestThreshold
|
|
204
|
+
}));
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
async onTestRunEnd(testModules, unhandledErrors, reason) {
|
|
208
|
+
super.onTestRunEnd(testModules, unhandledErrors, reason);
|
|
209
|
+
// write output for future comparison
|
|
210
|
+
let outputFile = this.ctx.config.benchmark?.outputJson;
|
|
211
|
+
if (outputFile) {
|
|
212
|
+
outputFile = pathe.resolve(this.ctx.config.root, outputFile);
|
|
213
|
+
const outputDirectory = pathe.dirname(outputFile);
|
|
214
|
+
if (!fs.existsSync(outputDirectory)) await fs.promises.mkdir(outputDirectory, { recursive: true });
|
|
215
|
+
const output = createBenchmarkJsonReport(testModules.map((t) => t.task.file));
|
|
216
|
+
await fs.promises.writeFile(outputFile, JSON.stringify(output, null, 2));
|
|
217
|
+
this.log(`Benchmark report written to ${outputFile}`);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
class VerboseBenchmarkReporter extends BenchmarkReporter {
|
|
223
|
+
verbose = true;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
const BenchmarkReportsMap = {
|
|
227
|
+
default: BenchmarkReporter,
|
|
228
|
+
verbose: VerboseBenchmarkReporter
|
|
229
|
+
};
|
|
230
|
+
|
|
231
|
+
export { BenchmarkReporter as B, VerboseBenchmarkReporter as V, BenchmarkReportsMap as a };
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
//#region src/messages.ts
|
|
2
|
+
const TYPE_REQUEST = "q";
|
|
3
|
+
const TYPE_RESPONSE = "s";
|
|
4
|
+
|
|
5
|
+
//#endregion
|
|
6
|
+
//#region src/utils.ts
|
|
7
|
+
function createPromiseWithResolvers() {
|
|
8
|
+
let resolve;
|
|
9
|
+
let reject;
|
|
10
|
+
return {
|
|
11
|
+
promise: new Promise((res, rej) => {
|
|
12
|
+
resolve = res;
|
|
13
|
+
reject = rej;
|
|
14
|
+
}),
|
|
15
|
+
resolve,
|
|
16
|
+
reject
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
const random = Math.random.bind(Math);
|
|
20
|
+
const urlAlphabet = "useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict";
|
|
21
|
+
function nanoid(size = 21) {
|
|
22
|
+
let id = "";
|
|
23
|
+
let i = size;
|
|
24
|
+
while (i--) id += urlAlphabet[random() * 64 | 0];
|
|
25
|
+
return id;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
//#endregion
|
|
29
|
+
//#region src/main.ts
|
|
30
|
+
const DEFAULT_TIMEOUT = 6e4;
|
|
31
|
+
const defaultSerialize = (i) => i;
|
|
32
|
+
const defaultDeserialize = defaultSerialize;
|
|
33
|
+
const { clearTimeout, setTimeout } = globalThis;
|
|
34
|
+
function createBirpc($functions, options) {
|
|
35
|
+
const { post, on, off = () => {}, eventNames = [], serialize = defaultSerialize, deserialize = defaultDeserialize, resolver, bind = "rpc", timeout = DEFAULT_TIMEOUT, proxify = true } = options;
|
|
36
|
+
let $closed = false;
|
|
37
|
+
const _rpcPromiseMap = /* @__PURE__ */ new Map();
|
|
38
|
+
let _promiseInit;
|
|
39
|
+
let rpc;
|
|
40
|
+
async function _call(method, args, event, optional) {
|
|
41
|
+
if ($closed) throw new Error(`[birpc] rpc is closed, cannot call "${method}"`);
|
|
42
|
+
const req = {
|
|
43
|
+
m: method,
|
|
44
|
+
a: args,
|
|
45
|
+
t: TYPE_REQUEST
|
|
46
|
+
};
|
|
47
|
+
if (optional) req.o = true;
|
|
48
|
+
const send = async (_req) => post(serialize(_req));
|
|
49
|
+
if (event) {
|
|
50
|
+
await send(req);
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
if (_promiseInit) try {
|
|
54
|
+
await _promiseInit;
|
|
55
|
+
} finally {
|
|
56
|
+
_promiseInit = void 0;
|
|
57
|
+
}
|
|
58
|
+
let { promise, resolve, reject } = createPromiseWithResolvers();
|
|
59
|
+
const id = nanoid();
|
|
60
|
+
req.i = id;
|
|
61
|
+
let timeoutId;
|
|
62
|
+
async function handler(newReq = req) {
|
|
63
|
+
if (timeout >= 0) {
|
|
64
|
+
timeoutId = setTimeout(() => {
|
|
65
|
+
try {
|
|
66
|
+
if (options.onTimeoutError?.call(rpc, method, args) !== true) throw new Error(`[birpc] timeout on calling "${method}"`);
|
|
67
|
+
} catch (e) {
|
|
68
|
+
reject(e);
|
|
69
|
+
}
|
|
70
|
+
_rpcPromiseMap.delete(id);
|
|
71
|
+
}, timeout);
|
|
72
|
+
if (typeof timeoutId === "object") timeoutId = timeoutId.unref?.();
|
|
73
|
+
}
|
|
74
|
+
_rpcPromiseMap.set(id, {
|
|
75
|
+
resolve,
|
|
76
|
+
reject,
|
|
77
|
+
timeoutId,
|
|
78
|
+
method
|
|
79
|
+
});
|
|
80
|
+
await send(newReq);
|
|
81
|
+
return promise;
|
|
82
|
+
}
|
|
83
|
+
try {
|
|
84
|
+
if (options.onRequest) await options.onRequest.call(rpc, req, handler, resolve);
|
|
85
|
+
else await handler();
|
|
86
|
+
} catch (e) {
|
|
87
|
+
if (options.onGeneralError?.call(rpc, e) !== true) throw e;
|
|
88
|
+
return;
|
|
89
|
+
} finally {
|
|
90
|
+
clearTimeout(timeoutId);
|
|
91
|
+
_rpcPromiseMap.delete(id);
|
|
92
|
+
}
|
|
93
|
+
return promise;
|
|
94
|
+
}
|
|
95
|
+
const builtinMethods = {
|
|
96
|
+
$call: (method, ...args) => _call(method, args, false),
|
|
97
|
+
$callOptional: (method, ...args) => _call(method, args, false, true),
|
|
98
|
+
$callEvent: (method, ...args) => _call(method, args, true),
|
|
99
|
+
$callRaw: (options$1) => _call(options$1.method, options$1.args, options$1.event, options$1.optional),
|
|
100
|
+
$rejectPendingCalls,
|
|
101
|
+
get $closed() {
|
|
102
|
+
return $closed;
|
|
103
|
+
},
|
|
104
|
+
get $meta() {
|
|
105
|
+
return options.meta;
|
|
106
|
+
},
|
|
107
|
+
$close,
|
|
108
|
+
$functions
|
|
109
|
+
};
|
|
110
|
+
if (proxify) rpc = new Proxy({}, { get(_, method) {
|
|
111
|
+
if (Object.prototype.hasOwnProperty.call(builtinMethods, method)) return builtinMethods[method];
|
|
112
|
+
if (method === "then" && !eventNames.includes("then") && !("then" in $functions)) return void 0;
|
|
113
|
+
const sendEvent = (...args) => _call(method, args, true);
|
|
114
|
+
if (eventNames.includes(method)) {
|
|
115
|
+
sendEvent.asEvent = sendEvent;
|
|
116
|
+
return sendEvent;
|
|
117
|
+
}
|
|
118
|
+
const sendCall = (...args) => _call(method, args, false);
|
|
119
|
+
sendCall.asEvent = sendEvent;
|
|
120
|
+
return sendCall;
|
|
121
|
+
} });
|
|
122
|
+
else rpc = builtinMethods;
|
|
123
|
+
function $close(customError) {
|
|
124
|
+
$closed = true;
|
|
125
|
+
_rpcPromiseMap.forEach(({ reject, method }) => {
|
|
126
|
+
const error = /* @__PURE__ */ new Error(`[birpc] rpc is closed, cannot call "${method}"`);
|
|
127
|
+
if (customError) {
|
|
128
|
+
customError.cause ??= error;
|
|
129
|
+
return reject(customError);
|
|
130
|
+
}
|
|
131
|
+
reject(error);
|
|
132
|
+
});
|
|
133
|
+
_rpcPromiseMap.clear();
|
|
134
|
+
off(onMessage);
|
|
135
|
+
}
|
|
136
|
+
function $rejectPendingCalls(handler) {
|
|
137
|
+
const handlerResults = Array.from(_rpcPromiseMap.values()).map(({ method, reject }) => {
|
|
138
|
+
if (!handler) return reject(/* @__PURE__ */ new Error(`[birpc]: rejected pending call "${method}".`));
|
|
139
|
+
return handler({
|
|
140
|
+
method,
|
|
141
|
+
reject
|
|
142
|
+
});
|
|
143
|
+
});
|
|
144
|
+
_rpcPromiseMap.clear();
|
|
145
|
+
return handlerResults;
|
|
146
|
+
}
|
|
147
|
+
async function onMessage(data, ...extra) {
|
|
148
|
+
let msg;
|
|
149
|
+
try {
|
|
150
|
+
msg = deserialize(data);
|
|
151
|
+
} catch (e) {
|
|
152
|
+
if (options.onGeneralError?.call(rpc, e) !== true) throw e;
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
if (msg.t === TYPE_REQUEST) {
|
|
156
|
+
const { m: method, a: args, o: optional } = msg;
|
|
157
|
+
let result, error;
|
|
158
|
+
let fn = await (resolver ? resolver.call(rpc, method, $functions[method]) : $functions[method]);
|
|
159
|
+
if (optional) fn ||= () => void 0;
|
|
160
|
+
if (!fn) error = /* @__PURE__ */ new Error(`[birpc] function "${method}" not found`);
|
|
161
|
+
else try {
|
|
162
|
+
result = await fn.apply(bind === "rpc" ? rpc : $functions, args);
|
|
163
|
+
} catch (e) {
|
|
164
|
+
error = e;
|
|
165
|
+
}
|
|
166
|
+
if (msg.i) {
|
|
167
|
+
if (error && options.onFunctionError) {
|
|
168
|
+
if (options.onFunctionError.call(rpc, error, method, args) === true) return;
|
|
169
|
+
}
|
|
170
|
+
if (!error) try {
|
|
171
|
+
await post(serialize({
|
|
172
|
+
t: TYPE_RESPONSE,
|
|
173
|
+
i: msg.i,
|
|
174
|
+
r: result
|
|
175
|
+
}), ...extra);
|
|
176
|
+
return;
|
|
177
|
+
} catch (e) {
|
|
178
|
+
error = e;
|
|
179
|
+
if (options.onGeneralError?.call(rpc, e, method, args) !== true) throw e;
|
|
180
|
+
}
|
|
181
|
+
try {
|
|
182
|
+
await post(serialize({
|
|
183
|
+
t: TYPE_RESPONSE,
|
|
184
|
+
i: msg.i,
|
|
185
|
+
e: error
|
|
186
|
+
}), ...extra);
|
|
187
|
+
} catch (e) {
|
|
188
|
+
if (options.onGeneralError?.call(rpc, e, method, args) !== true) throw e;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
} else {
|
|
192
|
+
const { i: ack, r: result, e: error } = msg;
|
|
193
|
+
const promise = _rpcPromiseMap.get(ack);
|
|
194
|
+
if (promise) {
|
|
195
|
+
clearTimeout(promise.timeoutId);
|
|
196
|
+
if (error) promise.reject(error);
|
|
197
|
+
else promise.resolve(result);
|
|
198
|
+
}
|
|
199
|
+
_rpcPromiseMap.delete(ack);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
_promiseInit = on(onMessage);
|
|
203
|
+
return rpc;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
export { createBirpc as c };
|