@inkbox/sdk 0.4.16 → 0.4.18

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.
@@ -68,7 +68,9 @@ export class MessagesResource {
68
68
  * replied to. Threads the reply automatically.
69
69
  * @param options.attachments - Optional file attachments. Each entry must have
70
70
  * `filename`, `contentType` (MIME type), and `contentBase64` (base64-encoded
71
- * file content). Max total size: 25 MB. Blocked: `.exe`, `.bat`, `.scr`.
71
+ * file content). Max total size: 25 MB. Blocked: `.exe`, `.bat`, `.scr`. Set
72
+ * `contentId` on an entry to render it inline in the HTML body instead of as
73
+ * a download (see the field doc).
72
74
  * @param options.trackOpens - Embed an open-tracking pixel in the HTML body.
73
75
  * Requires `bodyHtml`; a plain-text-only send with `trackOpens` is rejected
74
76
  * with 422. Opens surface as `firstOpenedAt`/`openCount`; `openCount` is
@@ -93,11 +95,16 @@ export class MessagesResource {
93
95
  body["in_reply_to_message_id"] = options.inReplyToMessageId;
94
96
  }
95
97
  if (options.attachments !== undefined) {
96
- body["attachments"] = options.attachments.map((a) => ({
97
- filename: a.filename,
98
- content_type: a.contentType,
99
- content_base64: a.contentBase64,
100
- }));
98
+ body["attachments"] = options.attachments.map((a) => {
99
+ const att = {
100
+ filename: a.filename,
101
+ content_type: a.contentType,
102
+ content_base64: a.contentBase64,
103
+ };
104
+ if (a.contentId !== undefined)
105
+ att["content_id"] = a.contentId;
106
+ return att;
107
+ });
101
108
  }
102
109
  if (options.trackOpens)
103
110
  body["track_opens"] = true;
@@ -115,7 +122,7 @@ export class MessagesResource {
115
122
  * @param options.bodyText - Plain-text reply body.
116
123
  * @param options.bodyHtml - HTML reply body.
117
124
  * @param options.attachments - Optional file attachments. Same shape as
118
- * `send({ attachments })`.
125
+ * `send({ attachments })`, including `contentId` for inline images.
119
126
  * @param options.replyTo - Optional Reply-To address.
120
127
  */
121
128
  async replyAll(emailAddress, messageId, options = {}) {
@@ -127,11 +134,16 @@ export class MessagesResource {
127
134
  if (options.bodyHtml !== undefined)
128
135
  body["body_html"] = options.bodyHtml;
129
136
  if (options.attachments !== undefined) {
130
- body["attachments"] = options.attachments.map((a) => ({
131
- filename: a.filename,
132
- content_type: a.contentType,
133
- content_base64: a.contentBase64,
134
- }));
137
+ body["attachments"] = options.attachments.map((a) => {
138
+ const att = {
139
+ filename: a.filename,
140
+ content_type: a.contentType,
141
+ content_base64: a.contentBase64,
142
+ };
143
+ if (a.contentId !== undefined)
144
+ att["content_id"] = a.contentId;
145
+ return att;
146
+ });
135
147
  }
136
148
  if (options.replyTo !== undefined)
137
149
  body["reply_to"] = options.replyTo;
@@ -1 +1 @@
1
- {"version":3,"file":"messages.js","sourceRoot":"","sources":["../../../src/mail/resources/messages.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"messages.js","sourceRoot":"","sources":["../../../src/mail/resources/messages.ts"],"names":[],"mappings":"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"}
@@ -7,7 +7,7 @@
7
7
  */
8
8
  import type { Tunnel } from "../types.js";
9
9
  import type { TunnelRuntime } from "./_runtime.js";
10
- export type TunnelStatusCallback = (status: "connecting" | "connected" | "reconnecting" | "closed") => void;
10
+ export type TunnelStatusCallback = (status: "connecting" | "connected" | "reconnecting" | "closed" | "superseded") => void;
11
11
  /**
12
12
  * Options that affect how the listener behaves around process signals.
13
13
  *
@@ -1 +1 @@
1
- {"version":3,"file":"_listener.d.ts","sourceRoot":"","sources":["../../../src/tunnels/client/_listener.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAEnD,MAAM,MAAM,oBAAoB,GAAG,CACjC,MAAM,EAAE,YAAY,GAAG,WAAW,GAAG,cAAc,GAAG,QAAQ,KAC3D,IAAI,CAAC;AAEV;;;;;;;GAOG;AACH,MAAM,WAAW,kBAAkB;IACjC,qBAAqB,CAAC,EAAE,OAAO,CAAC;CACjC;AAED;;;;;;GAMG;AACH,MAAM,WAAW,cAAc;IAC7B,+BAA+B;IAC/B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,yEAAyE;IACzE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,sEAAsE;IACtE,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACtB,6CAA6C;IAC7C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,0CAA0C;IAC1C,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACxB,qCAAqC;IACrC,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/B;AAED,qBAAa,kBAAmB,YAAW,cAAc;IACvD,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAgB;IACxC,OAAO,CAAC,YAAY,CAA8B;IAClD,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,aAAa,CAAiB;IACtC,OAAO,CAAC,sBAAsB,CAA6B;IAC3D,OAAO,CAAC,uBAAuB,CAA6B;IAC5D,OAAO,CAAC,gBAAgB,CAAS;gBAErB,IAAI,EAAE;QAChB,UAAU,EAAE,MAAM,CAAC;QACnB,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,EAAE,aAAa,CAAC;QACvB,YAAY,CAAC,EAAE,kBAAkB,CAAC;KACnC;IAkDK,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;IAY7B,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IASrB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAItB,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;CAoB9B"}
1
+ {"version":3,"file":"_listener.d.ts","sourceRoot":"","sources":["../../../src/tunnels/client/_listener.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAEnD,MAAM,MAAM,oBAAoB,GAAG,CACjC,MAAM,EAAE,YAAY,GAAG,WAAW,GAAG,cAAc,GAAG,QAAQ,GAAG,YAAY,KAC1E,IAAI,CAAC;AAEV;;;;;;;GAOG;AACH,MAAM,WAAW,kBAAkB;IACjC,qBAAqB,CAAC,EAAE,OAAO,CAAC;CACjC;AAED;;;;;;GAMG;AACH,MAAM,WAAW,cAAc;IAC7B,+BAA+B;IAC/B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,yEAAyE;IACzE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,sEAAsE;IACtE,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACtB,6CAA6C;IAC7C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,0CAA0C;IAC1C,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACxB,qCAAqC;IACrC,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/B;AAED,qBAAa,kBAAmB,YAAW,cAAc;IACvD,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAgB;IACxC,OAAO,CAAC,YAAY,CAA8B;IAClD,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,aAAa,CAAiB;IACtC,OAAO,CAAC,sBAAsB,CAA6B;IAC3D,OAAO,CAAC,uBAAuB,CAA6B;IAC5D,OAAO,CAAC,gBAAgB,CAAS;gBAErB,IAAI,EAAE;QAChB,UAAU,EAAE,MAAM,CAAC;QACnB,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,EAAE,aAAa,CAAC;QACvB,YAAY,CAAC,EAAE,kBAAkB,CAAC;KACnC;IAkDK,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;IAY7B,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IASrB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAItB,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;CAoB9B"}
@@ -36,10 +36,17 @@ export declare const HANDOFF_SETTLE_MS = 2000;
36
36
  export declare const POST_ACTIVE_WAIT_MS = 5000;
37
37
  export declare const DEFAULT_INBOUND_BODY_BYTES: number;
38
38
  export declare const DEFAULT_OUTBOUND_BODY_BYTES: number;
39
+ export declare const SUPERSEDED_GOAWAY_ERROR_CODE = 4609;
40
+ export declare const GOAWAY_REASON_SUPERSEDED = "superseded";
41
+ export declare const INTAKE_REASON_SUPERSEDED = "intake-superseded";
42
+ export declare const HELLO_REASON_SUPERSEDED = "hello-superseded";
39
43
  export declare class TunnelAuthError extends Error {
40
44
  constructor(message: string);
41
45
  }
42
- export type StatusCallback = (status: "connecting" | "connected" | "reconnecting" | "closed") => void;
46
+ export declare class TunnelSupersededError extends Error {
47
+ constructor(message: string);
48
+ }
49
+ export type StatusCallback = (status: "connecting" | "connected" | "reconnecting" | "closed" | "superseded") => void;
43
50
  /**
44
51
  * What this runtime forwards to. URL is required; `httpHandler` and
45
52
  * `wsHandler` activate the in-process callable paths.
@@ -107,6 +114,7 @@ export declare class TunnelRuntime {
107
114
  private handoffPromise;
108
115
  private wakeSupervisor;
109
116
  private stop;
117
+ private superseded;
110
118
  private readonly tasks;
111
119
  private passthroughDispatch;
112
120
  private readonly undiciAgentCache;
@@ -132,6 +140,26 @@ export declare class TunnelRuntime {
132
140
  /** Resolve once the supervised conn closes OR a handoff swaps active. */
133
141
  private waitCloseOrHandoff;
134
142
  private signalSupervisor;
143
+ /**
144
+ * True iff a takeover signal on `conn` should stop the runtime. Ignored only
145
+ * for a conn we ourselves put into make-before-break drain (our own
146
+ * predecessor, tracked in `this.draining`); a not-yet-active replacement
147
+ * mid-handoff is a real external takeover, so it stays terminal.
148
+ */
149
+ private supersededIsTerminal;
150
+ /** Record the takeover; the supervisor will stop and not reconnect. */
151
+ private markSuperseded;
152
+ /**
153
+ * Log, notify, and throw the terminal takeover error (no reconnect).
154
+ * Rethrows the original error when given, so its message (which
155
+ * channel/slot observed the takeover) survives to the caller.
156
+ */
157
+ private stopSuperseded;
158
+ /**
159
+ * Classify a non-zero GOAWAY: takeover (terminal) vs infra fault (reconnect).
160
+ * The dedicated code is authoritative; the reason is a belt cross-check.
161
+ */
162
+ private maybeMarkSupersededGoaway;
135
163
  /**
136
164
  * On a NO_ERROR GOAWAY, mark the old conn draining and stand up a fresh
137
165
  * connection before closing it. In-band: never trips the backoff loop.
@@ -1 +1 @@
1
- {"version":3,"file":"_runtime.d.ts","sourceRoot":"","sources":["../../../src/tunnels/client/_runtime.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"_runtime.d.ts","sourceRoot":"","sources":["../../../src/tunnels/client/_runtime.ts"],"names":[],"mappings":"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"}
@@ -57,12 +57,26 @@ export const HANDOFF_SETTLE_MS = 2_000;
57
57
  export const POST_ACTIVE_WAIT_MS = 5_000;
58
58
  export const DEFAULT_INBOUND_BODY_BYTES = 32 * 1024 * 1024;
59
59
  export const DEFAULT_OUTBOUND_BODY_BYTES = 32 * 1024 * 1024;
60
+ // Signals that another client connected to this tunnel and took over: this
61
+ // client must stop and not reconnect. Delivered as a dedicated GOAWAY error
62
+ // code (the reliable channel) plus matching reason strings on the GOAWAY debug
63
+ // data and the intake / hello responses. Must stay in lockstep with the server.
64
+ export const SUPERSEDED_GOAWAY_ERROR_CODE = 0x1201;
65
+ export const GOAWAY_REASON_SUPERSEDED = "superseded";
66
+ export const INTAKE_REASON_SUPERSEDED = "intake-superseded";
67
+ export const HELLO_REASON_SUPERSEDED = "hello-superseded";
60
68
  export class TunnelAuthError extends Error {
61
69
  constructor(message) {
62
70
  super(message);
63
71
  this.name = "TunnelAuthError";
64
72
  }
65
73
  }
74
+ export class TunnelSupersededError extends Error {
75
+ constructor(message) {
76
+ super(message);
77
+ this.name = "TunnelSupersededError";
78
+ }
79
+ }
66
80
  class OwnerTokenInvalidError extends Error {
67
81
  constructor(message) {
68
82
  super(message);
@@ -95,6 +109,23 @@ function isSessionTerminalError(err) {
95
109
  code === "ERR_HTTP2_STREAM_CANCEL" ||
96
110
  code === "ERR_HTTP2_SESSION_ERROR");
97
111
  }
112
+ /** Extract a ``reason`` string from a JSON ``{"reason": ...}`` payload. */
113
+ function parseReasonJson(buf) {
114
+ if (buf === undefined || buf === null || buf.length === 0)
115
+ return null;
116
+ try {
117
+ const parsed = JSON.parse(buf.toString("utf-8"));
118
+ if (typeof parsed === "object" && parsed !== null) {
119
+ const reason = parsed.reason;
120
+ if (typeof reason === "string")
121
+ return reason;
122
+ }
123
+ }
124
+ catch {
125
+ return null;
126
+ }
127
+ return null;
128
+ }
98
129
  /**
99
130
  * One persistent h2 connection's state. The runtime holds a single
100
131
  * `active` Connection (the pool that parks new intakes) plus zero-or-more
@@ -158,6 +189,9 @@ export class TunnelRuntime {
158
189
  // Resolves the supervisor's wait when the active conn is swapped.
159
190
  wakeSupervisor = null;
160
191
  stop = false;
192
+ // Set when another client took over this tunnel: serveForever stops and does
193
+ // not reconnect. Distinct from a transient drop or a drain.
194
+ superseded = false;
161
195
  // Dispatch tasks are runtime-scoped (not per-connection): a handoff must
162
196
  // let an in-flight handler finish and post its reply on the NEW conn.
163
197
  tasks = new Set();
@@ -206,6 +240,15 @@ export class TunnelRuntime {
206
240
  this.notifyStatus("closed");
207
241
  throw err;
208
242
  }
243
+ if (err instanceof TunnelSupersededError) {
244
+ this.stopSuperseded(err);
245
+ }
246
+ // A takeover GOAWAY that lands mid-hello sets `superseded` but surfaces
247
+ // as a plain connection error; go terminal here so we don't reconnect
248
+ // and boot the client that replaced us.
249
+ if (this.superseded) {
250
+ this.stopSuperseded();
251
+ }
209
252
  consecutiveFailures += 1;
210
253
  // eslint-disable-next-line no-console
211
254
  console.warn(`tunnel runtime: connection error (#${consecutiveFailures}); reconnecting`, err);
@@ -340,6 +383,10 @@ export class TunnelRuntime {
340
383
  if (session === null || session.closed || session.destroyed)
341
384
  break;
342
385
  }
386
+ // Another client took over this tunnel: stop, do not reconnect.
387
+ if (this.superseded) {
388
+ throw new TunnelSupersededError("another client connected to this tunnel; not reconnecting");
389
+ }
343
390
  }
344
391
  finally {
345
392
  this.stopPingLoop(conn);
@@ -383,6 +430,57 @@ export class TunnelRuntime {
383
430
  if (w !== null)
384
431
  w();
385
432
  }
433
+ // --- takeover (superseded) --------------------------------------------
434
+ /**
435
+ * True iff a takeover signal on `conn` should stop the runtime. Ignored only
436
+ * for a conn we ourselves put into make-before-break drain (our own
437
+ * predecessor, tracked in `this.draining`); a not-yet-active replacement
438
+ * mid-handoff is a real external takeover, so it stays terminal.
439
+ */
440
+ supersededIsTerminal(conn) {
441
+ return !this.draining.has(conn);
442
+ }
443
+ /** Record the takeover; the supervisor will stop and not reconnect. */
444
+ markSuperseded() {
445
+ this.superseded = true;
446
+ }
447
+ /**
448
+ * Log, notify, and throw the terminal takeover error (no reconnect).
449
+ * Rethrows the original error when given, so its message (which
450
+ * channel/slot observed the takeover) survives to the caller.
451
+ */
452
+ stopSuperseded(err) {
453
+ // eslint-disable-next-line no-console
454
+ console.warn("tunnel taken over: another client connected to this tunnel, so " +
455
+ "this client is stopping and will not reconnect. If this is " +
456
+ "unexpected, check for a second instance running the same " +
457
+ "identity (only one live connection per tunnel is kept).");
458
+ this.notifyStatus("superseded");
459
+ throw err ??
460
+ new TunnelSupersededError("another client connected to this tunnel; not reconnecting");
461
+ }
462
+ /**
463
+ * Classify a non-zero GOAWAY: takeover (terminal) vs infra fault (reconnect).
464
+ * The dedicated code is authoritative; the reason is a belt cross-check.
465
+ */
466
+ maybeMarkSupersededGoaway(conn, errorCode, opaqueData) {
467
+ const reason = parseReasonJson(opaqueData);
468
+ const isTakeover = errorCode === SUPERSEDED_GOAWAY_ERROR_CODE ||
469
+ reason === GOAWAY_REASON_SUPERSEDED;
470
+ if (!isTakeover) {
471
+ if (reason === null) {
472
+ // eslint-disable-next-line no-console
473
+ console.warn(`tunnel runtime: non-zero GOAWAY (code=${errorCode}) without a reason; reconnecting`);
474
+ }
475
+ return;
476
+ }
477
+ if (!this.supersededIsTerminal(conn)) {
478
+ // eslint-disable-next-line no-console
479
+ console.info("tunnel runtime: takeover signal on our own draining predecessor; ignoring");
480
+ return;
481
+ }
482
+ this.markSuperseded();
483
+ }
386
484
  // --- make-before-break handoff ----------------------------------------
387
485
  /**
388
486
  * On a NO_ERROR GOAWAY, mark the old conn draining and stand up a fresh
@@ -413,16 +511,28 @@ export class TunnelRuntime {
413
511
  this.signalSupervisor();
414
512
  }
415
513
  catch (err) {
416
- // Redial budget exhausted (or auth failure): give up on
417
- // make-before-break and fall to the cold reconnect path by forcing
418
- // the old session closed so the supervisor returns.
419
- // eslint-disable-next-line no-console
420
- console.warn("tunnel runtime: handoff failed; reconnecting cold", err);
421
- try {
422
- oldConn.session?.destroy();
514
+ if (err instanceof TunnelSupersededError) {
515
+ // External takeover during the handoff hello: `superseded` is set, so
516
+ // end the old conn and wake the supervisor to stop terminally (no cold
517
+ // redial, which would boot the client that replaced us).
518
+ try {
519
+ oldConn.session?.destroy();
520
+ }
521
+ catch { /* swallow */ }
522
+ this.signalSupervisor();
523
+ }
524
+ else {
525
+ // Redial budget exhausted (or auth failure): give up on
526
+ // make-before-break and fall to the cold reconnect path by forcing
527
+ // the old session closed so the supervisor returns.
528
+ // eslint-disable-next-line no-console
529
+ console.warn("tunnel runtime: handoff failed; reconnecting cold", err);
530
+ try {
531
+ oldConn.session?.destroy();
532
+ }
533
+ catch { /* swallow */ }
534
+ this.signalSupervisor();
423
535
  }
424
- catch { /* swallow */ }
425
- this.signalSupervisor();
426
536
  }
427
537
  finally {
428
538
  this.handoffInFlight = false;
@@ -448,8 +558,17 @@ export class TunnelRuntime {
448
558
  await this.closeConnection(conn);
449
559
  }
450
560
  catch { /* swallow */ }
451
- if (err instanceof TunnelAuthError)
561
+ // A rejected key or a takeover is terminal; never retry either
562
+ // (retrying a takeover would boot the client that replaced us).
563
+ if (err instanceof TunnelAuthError || err instanceof TunnelSupersededError) {
452
564
  throw err;
565
+ }
566
+ // A takeover GOAWAY that landed mid-hello set `superseded` but surfaced
567
+ // here as a plain reset/status-0 error; stop now so we don't re-hello
568
+ // and boot the client that replaced us.
569
+ if (this.superseded) {
570
+ throw new TunnelSupersededError("another client connected to this tunnel during handoff");
571
+ }
453
572
  if (Date.now() - start > HANDOFF_REDIAL_BUDGET_MS) {
454
573
  throw new Error("handoff redial budget exhausted");
455
574
  }
@@ -508,15 +627,19 @@ export class TunnelRuntime {
508
627
  // eslint-disable-next-line no-console
509
628
  console.warn("tunnel runtime: h2 session error", err);
510
629
  });
511
- session.on("goaway", (errorCode, lastStreamId) => {
630
+ session.on("goaway", (errorCode, lastStreamId, opaqueData) => {
512
631
  // eslint-disable-next-line no-console
513
632
  console.info(`tunnel runtime: GOAWAY received error_code=${errorCode} last_stream_id=${lastStreamId}`);
514
- // NO_ERROR GOAWAY is the server's drain signal: stand up a fresh
515
- // connection make-before-break. A non-zero code is a real fault
516
- // let the session close and reconnect cold.
633
+ // NO_ERROR GOAWAY = drain (make-before-break handoff). A non-zero code
634
+ // is a takeover (stop) or a real fault (reconnect cold), classified
635
+ // below; setting the takeover flag here wins over the 'error'/'close'
636
+ // reconnect path that the same GOAWAY also drives.
517
637
  if (errorCode === 0) {
518
638
  this.beginHandoff(conn);
519
639
  }
640
+ else {
641
+ this.maybeMarkSupersededGoaway(conn, errorCode, opaqueData);
642
+ }
520
643
  });
521
644
  // Watch the underlying TCP/TLS socket directly. Node's h2 client
522
645
  // sometimes loses the connection without emitting ``error`` or
@@ -612,6 +735,15 @@ export class TunnelRuntime {
612
735
  if (status === 401 || status === 403) {
613
736
  throw new TunnelAuthError(`${ControlPaths.HELLO} returned ${status}; the API key was rejected (check the key matches the tunnel's identity scope, or use an admin-scoped key in the tunnel's org)`);
614
737
  }
738
+ // Displaced during hello: a strictly-later hello (another client) won the
739
+ // tunnel. Always terminal, even mid-handoff: the server sends this only
740
+ // when a newer client has connected, so retrying would re-hello and boot
741
+ // the client that replaced us.
742
+ if (status === 409 &&
743
+ parseReasonJson(body) === HELLO_REASON_SUPERSEDED) {
744
+ this.superseded = true;
745
+ throw new TunnelSupersededError("another client connected to this tunnel during hello");
746
+ }
615
747
  if (status !== 200) {
616
748
  throw new Error(`${ControlPaths.HELLO} returned ${status}; transient — will retry`);
617
749
  }
@@ -755,6 +887,16 @@ export class TunnelRuntime {
755
887
  envelope = await this.parkOneIntake(conn, slot);
756
888
  }
757
889
  catch (err) {
890
+ if (err instanceof TunnelSupersededError) {
891
+ // Another client took over: force this conn down so the supervisor
892
+ // observes the terminal flag and stops (no reconnect).
893
+ this.markSuperseded();
894
+ try {
895
+ conn.session?.destroy();
896
+ }
897
+ catch { /* swallow */ }
898
+ return;
899
+ }
758
900
  if (err instanceof OwnerTokenInvalidError) {
759
901
  // eslint-disable-next-line no-console
760
902
  console.warn(`intake slot ${slot}: owner_token rejected; ` +
@@ -843,6 +985,15 @@ export class TunnelRuntime {
843
985
  const reason = recvHeaders.find(([k]) => k === TunnelMetaHeader.REASON)?.[1] ?? "";
844
986
  // eslint-disable-next-line no-console
845
987
  console.warn(`${ControlPaths.INTAKE} slot=${slot} -> status=${status} reason=${reason}`);
988
+ // Another client took over this tunnel. Terminal, unless this is our own
989
+ // draining predecessor (a normal reconnect). A drain uses a different
990
+ // reason and falls through to re-park below.
991
+ if (reason === INTAKE_REASON_SUPERSEDED) {
992
+ if (this.supersededIsTerminal(conn)) {
993
+ throw new TunnelSupersededError(`slot=${slot}: another client connected to this tunnel`);
994
+ }
995
+ return null;
996
+ }
846
997
  if (status === "401") {
847
998
  throw new OwnerTokenInvalidError(`slot=${slot} status=401 reason=${reason}`);
848
999
  }