@kubb/studio 5.2.4 → 5.2.5

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.
@@ -327,9 +327,10 @@ declare const commandTypes: readonly ["studio:generate", "studio:connect", "stud
327
327
  */
328
328
  type ClientInfo = {
329
329
  /**
330
- * `cli` for a `kubb studio` connection from a developer's machine, `docker` for the agent image.
330
+ * `cli` for a `kubb studio` connection from a developer's machine, `docker` for the agent image,
331
+ * `ci` for a client embedded directly in an automated pipeline (no `kubb studio` process).
331
332
  */
332
- kind: 'cli' | 'docker';
333
+ kind: 'cli' | 'docker' | 'ci';
333
334
  };
334
335
  /**
335
336
  * Payload of the `agent:connect` handshake, sent when the agent attaches to a session. Carries only
@@ -458,6 +459,14 @@ type AgentPingMessage = {
458
459
  type StudioPingMessage = {
459
460
  type: 'studio:ping';
460
461
  };
462
+ /**
463
+ * Studio's acknowledgement that an `agent:connect` handshake was received and the session is
464
+ * fully registered: the connection now counts as available for job dispatch. Distinct from the
465
+ * socket merely being open, which is not yet the same thing.
466
+ */
467
+ type StudioReadyMessage = {
468
+ type: 'studio:ready';
469
+ };
461
470
  /**
462
471
  * Disconnect message sent from Studio to Agent when the session is expired or revoked.
463
472
  * The agent should close the connection without reconnecting.
@@ -548,7 +557,7 @@ type AgentConnectResponse = {
548
557
  * Every message that can cross the agent WebSocket, in either direction. Narrow it with the
549
558
  * `is*Message` guards below before reading a variant's fields.
550
559
  */
551
- type AgentMessage = CommandMessage | DataMessage | AgentConnectMessage | AgentSaveMessage | AgentPingMessage | AgentDisconnectMessage | StudioErrorMessage | StudioPingMessage | StudioDisconnectMessage;
560
+ type AgentMessage = CommandMessage | DataMessage | AgentConnectMessage | AgentSaveMessage | AgentPingMessage | AgentDisconnectMessage | StudioErrorMessage | StudioPingMessage | StudioReadyMessage | StudioDisconnectMessage;
552
561
  declare function isCommandMessage(msg: AgentMessage): msg is CommandMessage;
553
562
  /**
554
563
  * Type guard to narrow a data message to a specific event type.
@@ -563,7 +572,8 @@ declare function isCommandMessage(msg: AgentMessage): msg is CommandMessage;
563
572
  */
564
573
  declare function isDataMessage<T extends KubbHook>(msg: AgentMessage, type?: T): msg is DataMessage<T>;
565
574
  declare function isStudioPingMessage(msg: AgentMessage): msg is StudioPingMessage;
575
+ declare function isStudioReadyMessage(msg: AgentMessage): msg is StudioReadyMessage;
566
576
  declare function isDisconnectMessage(msg: AgentMessage): msg is StudioDisconnectMessage;
567
577
  //#endregion
568
- export { isCommandMessage as A, StudioConnectMessage as C, StudioPingMessage as D, StudioGenerateMessage as E, isDisconnectMessage as M, isStudioPingMessage as N, StudioSaveMessage as O, PluginView as S, StudioErrorMessage as T, DataMessagePayload as _, AgentPermissions as a, KubbHooks$1 as b, ClientInfo as c, ConfigEditOutcome as d, ConfigFileView as f, DataMessage as g, ConnectMessagePayload as h, AgentMessage as i, isDataMessage as j, commandTypes as k, CommandMessage as l, ConfigView as m, AgentConnectResponse as n, AgentPingMessage as o, ConfigRef as p, AgentDisconnectMessage as r, AgentSaveMessage as s, AgentConnectMessage as t, ConfigEdit as u, JSONKubbConfig as v, StudioDisconnectMessage as w, OptionValue as x, KubbHook as y };
569
- //# sourceMappingURL=index-V3fjg2mj.d.ts.map
578
+ export { commandTypes as A, StudioConnectMessage as C, StudioPingMessage as D, StudioGenerateMessage as E, isStudioReadyMessage as F, isDataMessage as M, isDisconnectMessage as N, StudioReadyMessage as O, isStudioPingMessage as P, PluginView as S, StudioErrorMessage as T, DataMessagePayload as _, AgentPermissions as a, KubbHooks$1 as b, ClientInfo as c, ConfigEditOutcome as d, ConfigFileView as f, DataMessage as g, ConnectMessagePayload as h, AgentMessage as i, isCommandMessage as j, StudioSaveMessage as k, CommandMessage as l, ConfigView as m, AgentConnectResponse as n, AgentPingMessage as o, ConfigRef as p, AgentDisconnectMessage as r, AgentSaveMessage as s, AgentConnectMessage as t, ConfigEdit as u, JSONKubbConfig as v, StudioDisconnectMessage as w, OptionValue as x, KubbHook as y };
579
+ //# sourceMappingURL=index-Dq2uq38g.d.ts.map
package/dist/index.cjs CHANGED
@@ -569,7 +569,7 @@ async function disconnect({ sessionId, token, studioUrl, slug }) {
569
569
  }
570
570
  //#endregion
571
571
  //#region package.json
572
- var version = "5.2.4";
572
+ var version = "5.2.5";
573
573
  //#endregion
574
574
  //#region src/hooks.ts
575
575
  /**
@@ -1791,6 +1791,12 @@ function setupEventsStream(ws$5, hooks) {
1791
1791
  //#endregion
1792
1792
  //#region src/StudioSession.ts
1793
1793
  /**
1794
+ * How long the `agent:connect` handshake may go unacknowledged before `studio:ready` is given up
1795
+ * on for this open. A Studio that predates the ack never sends one, so this only ever produces a
1796
+ * warning, not a reconnect.
1797
+ */
1798
+ const READY_TIMEOUT_MS = 1e4;
1799
+ /**
1794
1800
  * Fills in a host's options: the hosted Studio URL, the current working directory, and every
1795
1801
  * permission off unless granted. Idempotent, so a reconnect can pass an already-resolved bag
1796
1802
  * back in.
@@ -1861,6 +1867,7 @@ var StudioSession = class {
1861
1867
  #disposed = false;
1862
1868
  #isGenerating = false;
1863
1869
  #heartbeatTimer;
1870
+ #readyTimer;
1864
1871
  #lastPongAt = Date.now();
1865
1872
  constructor(options) {
1866
1873
  this.#options = applyStudioDefaults(options);
@@ -1994,10 +2001,24 @@ var StudioSession = class {
1994
2001
  });
1995
2002
  try {
1996
2003
  await this.#sendConnectedPayload();
2004
+ this.#waitForReady();
1997
2005
  } catch (error) {
1998
2006
  await this.#warn(`Failed to send the connect payload: ${getErrorMessage(error)}`);
1999
2007
  }
2000
2008
  }
2009
+ /**
2010
+ * Arms the timeout for Studio's `studio:ready` acknowledgement. Re-armed on every open, since a
2011
+ * command sent while the agent is not attached is lost either way (see `#sendConnectedPayload`),
2012
+ * so each reconnect needs its own fresh wait.
2013
+ */
2014
+ #waitForReady() {
2015
+ if (this.#disposed) return;
2016
+ clearTimeout(this.#readyTimer);
2017
+ this.#readyTimer = setTimeout(() => {
2018
+ this.#readyTimer = void 0;
2019
+ Promise.resolve(this.#warn(`Kubb Studio did not confirm the connection was ready within ${READY_TIMEOUT_MS}ms`)).catch(() => {});
2020
+ }, READY_TIMEOUT_MS);
2021
+ }
2001
2022
  #onOpen = () => void this.#handleOpen().catch(() => {});
2002
2023
  #onAbort = () => void this.#end({
2003
2024
  reason: "shutdown",
@@ -2017,6 +2038,8 @@ var StudioSession = class {
2017
2038
  dispose(reason = "cleanup") {
2018
2039
  clearInterval(this.#heartbeatTimer);
2019
2040
  this.#heartbeatTimer = void 0;
2041
+ clearTimeout(this.#readyTimer);
2042
+ this.#readyTimer = void 0;
2020
2043
  try {
2021
2044
  this.#ws?.close(1e3, reason);
2022
2045
  } catch {}
@@ -2051,6 +2074,12 @@ var StudioSession = class {
2051
2074
  this.#lastPongAt = Date.now();
2052
2075
  return;
2053
2076
  }
2077
+ if (require_protocol.isStudioReadyMessage(data)) {
2078
+ clearTimeout(this.#readyTimer);
2079
+ this.#readyTimer = void 0;
2080
+ await this.#hooks.callHook("studio:ready", {});
2081
+ return;
2082
+ }
2054
2083
  if (require_protocol.isDisconnectMessage(data)) {
2055
2084
  await this.#handleDisconnect(data.reason);
2056
2085
  return;