Skip to content

Commit

Permalink
fix: don't keep the infinite debugger spinner (#493)
Browse files Browse the repository at this point in the history
* fix: don't keep the infinite debugger spinner

* chore: cleanup

* chore: cleanup delayed calls
  • Loading branch information
sheremet-va authored Oct 8, 2024
1 parent b6a8696 commit da757bb
Show file tree
Hide file tree
Showing 9 changed files with 323 additions and 36 deletions.
268 changes: 265 additions & 3 deletions patches/[email protected]
Original file line number Diff line number Diff line change
@@ -1,13 +1,275 @@
diff --git a/dist/index.cjs b/dist/index.cjs
index d8119336758abcb11f5e247dfe579b1b5c5fefd5..00e4b1a01cfa480a874f5da6f8dcdd4db2b89e99 100644
--- a/dist/index.cjs
+++ b/dist/index.cjs
@@ -11,18 +11,24 @@ function createBirpc(functions, options) {
const {
post,
on,
+ off = () => {
+ },
eventNames = [],
serialize = defaultSerialize,
deserialize = defaultDeserialize,
resolver,
+ bind = "rpc",
timeout = DEFAULT_TIMEOUT
} = options;
const rpcPromiseMap = /* @__PURE__ */ new Map();
let _promise;
+ let closed = false;
const rpc = new Proxy({}, {
get(_, method) {
if (method === "$functions")
return functions;
+ if (method === "$close")
+ return close;
if (method === "then" && !eventNames.includes("then") && !("then" in functions))
return void 0;
const sendEvent = (...args) => {
@@ -33,7 +39,15 @@ function createBirpc(functions, options) {
return sendEvent;
}
const sendCall = async (...args) => {
- await _promise;
+ if (closed)
+ throw new Error(`[birpc] rpc is closed, cannot call "${method}"`);
+ if (_promise) {
+ try {
+ await _promise;
+ } finally {
+ _promise = void 0;
+ }
+ }
return new Promise((resolve, reject) => {
const id = nanoid();
let timeoutId;
@@ -58,7 +72,15 @@ function createBirpc(functions, options) {
return sendCall;
}
});
- _promise = on(async (data, ...extra) => {
+ function close() {
+ closed = true;
+ rpcPromiseMap.forEach(({ reject }) => {
+ reject(new Error("[birpc] rpc is closed"));
+ });
+ rpcPromiseMap.clear();
+ off(onMessage);
+ }
+ async function onMessage(data, ...extra) {
const msg = deserialize(data);
if (msg.t === "q") {
const { m: method, a: args } = msg;
@@ -68,7 +90,7 @@ function createBirpc(functions, options) {
error = new Error(`[birpc] function "${method}" not found`);
} else {
try {
- result = await fn.apply(rpc, args);
+ result = await fn.apply(bind === "rpc" ? rpc : functions, args);
} catch (e) {
error = e;
}
@@ -90,7 +112,8 @@ function createBirpc(functions, options) {
}
rpcPromiseMap.delete(ack);
}
- });
+ }
+ _promise = on(onMessage);
return rpc;
}
const cacheMap = /* @__PURE__ */ new WeakMap();
diff --git a/dist/index.d.cts b/dist/index.d.cts
index 010f33e6343281a894b6835d89b7fcf1157250a7..f7618f7f8118d24723693415dc321adfa5881458 100644
--- a/dist/index.d.cts
+++ b/dist/index.d.cts
@@ -11,6 +11,10 @@ interface ChannelOptions {
* Listener to receive raw message
*/
on: (fn: (data: any, ...extras: any[]) => void) => any | Promise<any>;
+ /**
+ * Clear the listener when `$close` is called
+ */
+ off?: (fn: (data: any, ...extras: any[]) => void) => any | Promise<any>;
/**
* Custom function to serialize data
*
@@ -23,6 +27,10 @@ interface ChannelOptions {
* by default it passes the data as-is
*/
deserialize?: (data: any) => any;
+ /**
+ * Call the methods with the RPC context or the original functions object
+ */
+ bind?: 'rpc' | 'functions';
}
interface EventOptions<Remote> {
/**
@@ -71,6 +79,7 @@ type BirpcReturn<RemoteFunctions, LocalFunctions = Record<string, never>> = {
[K in keyof RemoteFunctions]: BirpcFn<RemoteFunctions[K]>;
} & {
$functions: LocalFunctions;
+ $close: () => void;
};
type BirpcGroupReturn<RemoteFunctions> = {
[K in keyof RemoteFunctions]: BirpcGroupFn<RemoteFunctions[K]>;
diff --git a/dist/index.d.mts b/dist/index.d.mts
index 010f33e6343281a894b6835d89b7fcf1157250a7..f7618f7f8118d24723693415dc321adfa5881458 100644
--- a/dist/index.d.mts
+++ b/dist/index.d.mts
@@ -11,6 +11,10 @@ interface ChannelOptions {
* Listener to receive raw message
*/
on: (fn: (data: any, ...extras: any[]) => void) => any | Promise<any>;
+ /**
+ * Clear the listener when `$close` is called
+ */
+ off?: (fn: (data: any, ...extras: any[]) => void) => any | Promise<any>;
/**
* Custom function to serialize data
*
@@ -23,6 +27,10 @@ interface ChannelOptions {
* by default it passes the data as-is
*/
deserialize?: (data: any) => any;
+ /**
+ * Call the methods with the RPC context or the original functions object
+ */
+ bind?: 'rpc' | 'functions';
}
interface EventOptions<Remote> {
/**
@@ -71,6 +79,7 @@ type BirpcReturn<RemoteFunctions, LocalFunctions = Record<string, never>> = {
[K in keyof RemoteFunctions]: BirpcFn<RemoteFunctions[K]>;
} & {
$functions: LocalFunctions;
+ $close: () => void;
};
type BirpcGroupReturn<RemoteFunctions> = {
[K in keyof RemoteFunctions]: BirpcGroupFn<RemoteFunctions[K]>;
diff --git a/dist/index.d.ts b/dist/index.d.ts
index 010f33e6343281a894b6835d89b7fcf1157250a7..f7618f7f8118d24723693415dc321adfa5881458 100644
--- a/dist/index.d.ts
+++ b/dist/index.d.ts
@@ -11,6 +11,10 @@ interface ChannelOptions {
* Listener to receive raw message
*/
on: (fn: (data: any, ...extras: any[]) => void) => any | Promise<any>;
+ /**
+ * Clear the listener when `$close` is called
+ */
+ off?: (fn: (data: any, ...extras: any[]) => void) => any | Promise<any>;
/**
* Custom function to serialize data
*
@@ -23,6 +27,10 @@ interface ChannelOptions {
* by default it passes the data as-is
*/
deserialize?: (data: any) => any;
+ /**
+ * Call the methods with the RPC context or the original functions object
+ */
+ bind?: 'rpc' | 'functions';
}
interface EventOptions<Remote> {
/**
@@ -71,6 +79,7 @@ type BirpcReturn<RemoteFunctions, LocalFunctions = Record<string, never>> = {
[K in keyof RemoteFunctions]: BirpcFn<RemoteFunctions[K]>;
} & {
$functions: LocalFunctions;
+ $close: () => void;
};
type BirpcGroupReturn<RemoteFunctions> = {
[K in keyof RemoteFunctions]: BirpcGroupFn<RemoteFunctions[K]>;
diff --git a/dist/index.mjs b/dist/index.mjs
index 8396fdbfbd7e1df8935c0806af9e7b31f8ccc261..7fcc87a89d7ca21cbf3a3e97ddedec0c51a7ef2a 100644
index 8396fdbfbd7e1df8935c0806af9e7b31f8ccc261..4544cebb4378902b8e08686ed882689d7102f0f5 100644
--- a/dist/index.mjs
+++ b/dist/index.mjs
@@ -66,7 +66,7 @@ function createBirpc(functions, options) {
@@ -9,18 +9,24 @@ function createBirpc(functions, options) {
const {
post,
on,
+ off = () => {
+ },
eventNames = [],
serialize = defaultSerialize,
deserialize = defaultDeserialize,
resolver,
+ bind = "rpc",
timeout = DEFAULT_TIMEOUT
} = options;
const rpcPromiseMap = /* @__PURE__ */ new Map();
let _promise;
+ let closed = false;
const rpc = new Proxy({}, {
get(_, method) {
if (method === "$functions")
return functions;
+ if (method === "$close")
+ return close;
if (method === "then" && !eventNames.includes("then") && !("then" in functions))
return void 0;
const sendEvent = (...args) => {
@@ -31,7 +37,15 @@ function createBirpc(functions, options) {
return sendEvent;
}
const sendCall = async (...args) => {
- await _promise;
+ if (closed)
+ throw new Error(`[birpc] rpc is closed, cannot call "${method}"`);
+ if (_promise) {
+ try {
+ await _promise;
+ } finally {
+ _promise = void 0;
+ }
+ }
return new Promise((resolve, reject) => {
const id = nanoid();
let timeoutId;
@@ -48,7 +62,7 @@ function createBirpc(functions, options) {
if (typeof timeoutId === "object")
timeoutId = timeoutId.unref?.();
}
- rpcPromiseMap.set(id, { resolve, reject, timeoutId });
+ rpcPromiseMap.set(id, { resolve, reject, timeoutId, method });
post(serialize({ m: method, a: args, i: id, t: "q" }));
});
};
@@ -56,7 +70,15 @@ function createBirpc(functions, options) {
return sendCall;
}
});
- _promise = on(async (data, ...extra) => {
+ function close() {
+ closed = true;
+ rpcPromiseMap.forEach(({ reject, method }) => {
+ reject(new Error(`[birpc] rpc is closed, cannot call "${method}"`));
+ });
+ rpcPromiseMap.clear();
+ off(onMessage);
+ }
+ async function onMessage(data, ...extra) {
const msg = deserialize(data);
if (msg.t === "q") {
const { m: method, a: args } = msg;
@@ -66,7 +88,7 @@ function createBirpc(functions, options) {
error = new Error(`[birpc] function "${method}" not found`);
} else {
try {
- result = await fn.apply(rpc, args);
+ result = await fn.apply(functions, args);
+ result = await fn.apply(bind === "rpc" ? rpc : functions, args);
} catch (e) {
error = e;
}
@@ -88,7 +110,8 @@ function createBirpc(functions, options) {
}
rpcPromiseMap.delete(ack);
}
- });
+ }
+ _promise = on(onMessage);
return rpc;
}
const cacheMap = /* @__PURE__ */ new WeakMap();
6 changes: 3 additions & 3 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 15 additions & 3 deletions src/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ export class VitestFolderAPI {

private handlers: ResolvedMeta['handlers']

public createDate = Date.now()

constructor(
private pkg: VitestPackage,
private meta: ResolvedMeta,
Expand Down Expand Up @@ -115,19 +117,28 @@ export class VitestFolderAPI {
return this.meta.rpc.getFiles()
}

onFileCreated = createQueuedHandler((files: string[]) => {
onFileCreated = createQueuedHandler(async (files: string[]) => {
if (this.process.closed) {
return
}
return this.meta.rpc.onFilesCreated(files)
})

onFileChanged = createQueuedHandler((files: string[]) => {
onFileChanged = createQueuedHandler(async (files: string[]) => {
if (this.process.closed) {
return
}
return this.meta.rpc.onFilesChanged(files)
})

async collectTests(projectName: string, testFile: string) {
return this._collectTests(`${projectName}\0${normalize(testFile)}`)
}

private _collectTests = createQueuedHandler((testsQueue: string[]) => {
private _collectTests = createQueuedHandler(async (testsQueue: string[]) => {
if (this.process.closed) {
return
}
const tests = Array.from(testsQueue).map((spec) => {
const [projectName, filepath] = spec.split('\0', 2)
return [projectName, filepath] as [string, string]
Expand Down Expand Up @@ -163,6 +174,7 @@ export class VitestFolderAPI {
log.error('[API]', 'Failed to close Vitest process', err)
})
}
this.meta.rpc.$close()
}

async cancelRun() {
Expand Down
1 change: 1 addition & 0 deletions src/api/rpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ export function createVitestRpc(options: {
events,
{
timeout: -1,
bind: 'functions',
on(listener) {
options.on(listener)
},
Expand Down
Loading

0 comments on commit da757bb

Please sign in to comment.