@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.
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { t as __name } from "./rolldown-runtime-CRm0XQPb.js";
2
- import { a as AgentPermissions, c as ClientInfo } from "./index-V3fjg2mj.js";
2
+ import { a as AgentPermissions, c as ClientInfo } from "./index-Dq2uq38g.js";
3
3
  import { Storage } from "unstorage";
4
4
  import { Config, Hookable, KubbHooks } from "@kubb/core";
5
5
  //#region src/api.d.ts
@@ -147,6 +147,11 @@ type StudioConnectedContext = {
147
147
  agent: string;
148
148
  };
149
149
  };
150
+ /**
151
+ * Fired once Studio confirms the `agent:connect` handshake was received and the session is fully
152
+ * registered. Distinct from `studio:connected`, which only means the socket is open.
153
+ */
154
+ type StudioReadyContext = Record<string, never>;
150
155
  type StudioDisconnectedContext = {
151
156
  /**
152
157
  * Why Studio ended the session.
@@ -187,6 +192,7 @@ declare global {
187
192
  interface KubbHooksRegistry {
188
193
  'studio:connecting': [ctx: StudioConnectingContext];
189
194
  'studio:connected': [ctx: StudioConnectedContext];
195
+ 'studio:ready': [ctx: StudioReadyContext];
190
196
  'studio:disconnected': [ctx: StudioDisconnectedContext];
191
197
  'studio:command:start': [ctx: StudioCommandStartContext];
192
198
  'studio:command:end': [ctx: StudioCommandEndContext];
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { t as __name } from "./rolldown-runtime-CRm0XQPb.js";
2
- import { isCommandMessage, isDisconnectMessage, isStudioPingMessage } from "./protocol.js";
2
+ import { isCommandMessage, isDisconnectMessage, isStudioPingMessage, isStudioReadyMessage } from "./protocol.js";
3
3
  import { createRequire } from "node:module";
4
4
  import { styleText } from "node:util";
5
5
  import { readFile, writeFile } from "node:fs/promises";
@@ -564,7 +564,7 @@ async function disconnect({ sessionId, token, studioUrl, slug }) {
564
564
  }
565
565
  //#endregion
566
566
  //#region package.json
567
- var version = "5.2.4";
567
+ var version = "5.2.5";
568
568
  //#endregion
569
569
  //#region src/hooks.ts
570
570
  /**
@@ -1786,6 +1786,12 @@ function setupEventsStream(ws, hooks) {
1786
1786
  //#endregion
1787
1787
  //#region src/StudioSession.ts
1788
1788
  /**
1789
+ * How long the `agent:connect` handshake may go unacknowledged before `studio:ready` is given up
1790
+ * on for this open. A Studio that predates the ack never sends one, so this only ever produces a
1791
+ * warning, not a reconnect.
1792
+ */
1793
+ const READY_TIMEOUT_MS = 1e4;
1794
+ /**
1789
1795
  * Fills in a host's options: the hosted Studio URL, the current working directory, and every
1790
1796
  * permission off unless granted. Idempotent, so a reconnect can pass an already-resolved bag
1791
1797
  * back in.
@@ -1856,6 +1862,7 @@ var StudioSession = class {
1856
1862
  #disposed = false;
1857
1863
  #isGenerating = false;
1858
1864
  #heartbeatTimer;
1865
+ #readyTimer;
1859
1866
  #lastPongAt = Date.now();
1860
1867
  constructor(options) {
1861
1868
  this.#options = applyStudioDefaults(options);
@@ -1989,10 +1996,24 @@ var StudioSession = class {
1989
1996
  });
1990
1997
  try {
1991
1998
  await this.#sendConnectedPayload();
1999
+ this.#waitForReady();
1992
2000
  } catch (error) {
1993
2001
  await this.#warn(`Failed to send the connect payload: ${getErrorMessage(error)}`);
1994
2002
  }
1995
2003
  }
2004
+ /**
2005
+ * Arms the timeout for Studio's `studio:ready` acknowledgement. Re-armed on every open, since a
2006
+ * command sent while the agent is not attached is lost either way (see `#sendConnectedPayload`),
2007
+ * so each reconnect needs its own fresh wait.
2008
+ */
2009
+ #waitForReady() {
2010
+ if (this.#disposed) return;
2011
+ clearTimeout(this.#readyTimer);
2012
+ this.#readyTimer = setTimeout(() => {
2013
+ this.#readyTimer = void 0;
2014
+ Promise.resolve(this.#warn(`Kubb Studio did not confirm the connection was ready within ${READY_TIMEOUT_MS}ms`)).catch(() => {});
2015
+ }, READY_TIMEOUT_MS);
2016
+ }
1996
2017
  #onOpen = () => void this.#handleOpen().catch(() => {});
1997
2018
  #onAbort = () => void this.#end({
1998
2019
  reason: "shutdown",
@@ -2012,6 +2033,8 @@ var StudioSession = class {
2012
2033
  dispose(reason = "cleanup") {
2013
2034
  clearInterval(this.#heartbeatTimer);
2014
2035
  this.#heartbeatTimer = void 0;
2036
+ clearTimeout(this.#readyTimer);
2037
+ this.#readyTimer = void 0;
2015
2038
  try {
2016
2039
  this.#ws?.close(1e3, reason);
2017
2040
  } catch {}
@@ -2046,6 +2069,12 @@ var StudioSession = class {
2046
2069
  this.#lastPongAt = Date.now();
2047
2070
  return;
2048
2071
  }
2072
+ if (isStudioReadyMessage(data)) {
2073
+ clearTimeout(this.#readyTimer);
2074
+ this.#readyTimer = void 0;
2075
+ await this.#hooks.callHook("studio:ready", {});
2076
+ return;
2077
+ }
2049
2078
  if (isDisconnectMessage(data)) {
2050
2079
  await this.#handleDisconnect(data.reason);
2051
2080
  return;