pi-chrome 0.4.3 → 0.4.4

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.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "manifest_version": 3,
3
3
  "name": "Pi Existing Chrome Profile Bridge",
4
- "version": "0.4.3",
4
+ "version": "0.4.4",
5
5
  "description": "Lets Pi control tabs in this existing Chrome profile via a local bridge at 127.0.0.1.",
6
6
  "permissions": ["tabs", "scripting", "storage", "activeTab", "alarms"],
7
7
  "host_permissions": ["<all_urls>", "http://127.0.0.1:17318/*"],
@@ -46,7 +46,7 @@ type BridgeResult = {
46
46
  error?: string;
47
47
  };
48
48
 
49
- const PI_CHROME_VERSION = "0.4.3";
49
+ const PI_CHROME_VERSION = "0.4.4";
50
50
  const DEFAULT_HOST = process.env.PI_CHROME_BRIDGE_HOST ?? "127.0.0.1";
51
51
  const DEFAULT_PORT = Number(process.env.PI_CHROME_BRIDGE_PORT ?? "17318");
52
52
  const DEFAULT_TIMEOUT_MS = 30_000;
@@ -274,7 +274,24 @@ class ChromeProfileBridge {
274
274
  if (request.method === "GET" && url.pathname === "/next") {
275
275
  this.lastSeenAt = Date.now();
276
276
  this.clientName = url.searchParams.get("name") ?? undefined;
277
- const command = this.queue.shift() ?? (await this.waitForCommand(25_000));
277
+ let aborted = false;
278
+ let activeWaiter: ((command: BridgeCommand | undefined) => void) | undefined;
279
+ request.once("close", () => {
280
+ aborted = true;
281
+ if (activeWaiter) this.waiters = this.waiters.filter((entry) => entry !== activeWaiter);
282
+ });
283
+ let command = this.queue.shift();
284
+ if (!command) {
285
+ command = await this.waitForCommand(25_000, (waiter) => {
286
+ activeWaiter = waiter;
287
+ });
288
+ }
289
+ if (aborted) {
290
+ // Long-poll connection died before we could deliver. Requeue any command we pulled
291
+ // so the next live /next picks it up instead of dropping it on the floor.
292
+ if (command) this.queue.unshift(command);
293
+ return;
294
+ }
278
295
  sendJson(response, 200, command ? { type: "command", command } : { type: "none" });
279
296
  return;
280
297
  }
@@ -296,16 +313,22 @@ class ChromeProfileBridge {
296
313
  sendJson(response, 404, { error: "not found" });
297
314
  }
298
315
 
299
- private waitForCommand(timeoutMs: number): Promise<BridgeCommand | undefined> {
316
+ private waitForCommand(
317
+ timeoutMs: number,
318
+ registerWaiter?: (waiter: (command: BridgeCommand | undefined) => void) => void,
319
+ ): Promise<BridgeCommand | undefined> {
300
320
  return new Promise((resolveWait) => {
301
- const timer = setTimeout(() => {
302
- this.waiters = this.waiters.filter((waiter) => waiter !== resolveWait);
303
- resolveWait(undefined);
304
- }, timeoutMs);
305
- this.waiters.push((command) => {
321
+ let settled = false;
322
+ const waiter = (command: BridgeCommand | undefined) => {
323
+ if (settled) return;
324
+ settled = true;
306
325
  clearTimeout(timer);
326
+ this.waiters = this.waiters.filter((entry) => entry !== waiter);
307
327
  resolveWait(command);
308
- });
328
+ };
329
+ const timer = setTimeout(() => waiter(undefined), timeoutMs);
330
+ this.waiters.push(waiter);
331
+ registerWaiter?.(waiter);
309
332
  });
310
333
  }
311
334
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-chrome",
3
- "version": "0.4.3",
3
+ "version": "0.4.4",
4
4
  "description": "Drive your existing logged-in Chrome from Pi \u2014 no re-login, no throwaway profile, background by default.",
5
5
  "keywords": [
6
6
  "pi-package",