@statelyai/sdk 0.14.2 → 0.16.0

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,5 +1,5 @@
1
- import { a as createPendingExportManager, i as createEventRegistry, r as createWebSocketTransport } from "./transport-D2Ud05yg.mjs";
2
- import { INSPECTION_PROTOCOL_VERSION } from "./protocol.mjs";
1
+ import { i as createPendingExportManager, n as createWebSocketTransport, r as createEventRegistry } from "./transport-B_ig9Znn.mjs";
2
+ import { INSPECTION_PROTOCOL_VERSION, createInspectionRoomUrls, getInspectionRoomId } from "./protocol.mjs";
3
3
 
4
4
  //#region src/openBrowser.ts
5
5
  async function openBrowser(url) {
@@ -37,25 +37,23 @@ function isStoppedSnapshot(snapshot) {
37
37
  const status = snapshot?.status;
38
38
  return status === "done" || status === "stopped" || status === "error";
39
39
  }
40
- function generateSessionId() {
41
- if (!globalThis.crypto?.randomUUID) throw new Error("createInspector() requires crypto.randomUUID() to generate a secure session capability. Pass sessionId explicitly in older runtimes.");
40
+ function generateRoomId() {
41
+ if (!globalThis.crypto?.randomUUID) throw new Error("createInspector() requires crypto.randomUUID() to generate a secure room capability. Pass roomId explicitly in older runtimes.");
42
42
  return globalThis.crypto.randomUUID();
43
43
  }
44
- function createInspectorLaunchUrl(websocketUrl, sessionId) {
45
- try {
46
- const launchUrl = new URL(websocketUrl);
47
- if (launchUrl.protocol === "ws:") launchUrl.protocol = "http:";
48
- else if (launchUrl.protocol === "wss:") launchUrl.protocol = "https:";
49
- else return null;
50
- launchUrl.searchParams.set("session", sessionId);
51
- return launchUrl.toString();
52
- } catch {
53
- return null;
54
- }
55
- }
56
44
  function createInspector(options = {}) {
57
- const { url = "ws://localhost:4242", autoOpen = true, name, serializeSnapshot = defaultSerializeSnapshot, extractMachineConfig = defaultExtractMachineConfig, selectedActorId, panels, theme, readOnly, depth, capabilities, transport: injectedTransport } = options;
58
- const sessionId = options.sessionId ?? generateSessionId();
45
+ const environmentUrl = typeof process !== "undefined" ? process.env?.STATELY_INSPECT_URL : void 0;
46
+ const url = options.url ?? environmentUrl ?? "wss://sky.stately.ai";
47
+ const { inspectorBaseUrl, autoOpen = true, name, serializeSnapshot = defaultSerializeSnapshot, extractMachineConfig = defaultExtractMachineConfig, selectedSessionId: configuredSelectedSessionId, selectedActorId, panels, theme, readOnly, depth, capabilities, transport: injectedTransport } = options;
48
+ const roomId = options.roomId ?? options.sessionId ?? getInspectionRoomId(url) ?? generateRoomId();
49
+ const producerId = options.producerId ?? generateRoomId();
50
+ const roomUrls = injectedTransport ? null : createInspectionRoomUrls({
51
+ url,
52
+ roomId,
53
+ inspectorBaseUrl
54
+ });
55
+ const relayUrl = roomUrls?.relayUrl ?? null;
56
+ const inspectorUrl = roomUrls?.inspectorUrl ?? null;
59
57
  const displayName = name ?? "system:manual";
60
58
  let destroyed = false;
61
59
  let initSent = false;
@@ -63,13 +61,21 @@ function createInspector(options = {}) {
63
61
  let pendingTransportReady = false;
64
62
  let transportWasReady = false;
65
63
  let didAutoOpen = false;
64
+ let resolveReady;
65
+ let rejectReady;
66
+ let readySettled = false;
67
+ const ready = new Promise((resolve, reject) => {
68
+ resolveReady = resolve;
69
+ rejectReady = reject;
70
+ });
71
+ ready.catch(() => {});
66
72
  const pendingMessages = [];
67
73
  const events = createEventRegistry();
68
74
  const localListeners = {};
69
75
  const transport = injectedTransport ?? createWebSocketTransport({
70
- url,
71
- role: "client",
72
- sessionId,
76
+ url: relayUrl,
77
+ role: "producer",
78
+ producerId,
73
79
  metadata: { name: displayName }
74
80
  });
75
81
  const ownsTransport = !injectedTransport;
@@ -87,6 +93,8 @@ function createInspector(options = {}) {
87
93
  if (!initSent) sendInit();
88
94
  const queued = pendingMessages.splice(0);
89
95
  for (const message of queued) transport.send(message);
96
+ readySettled = true;
97
+ resolveReady();
90
98
  } else {
91
99
  pendingMessages.length = 0;
92
100
  initSent = false;
@@ -94,8 +102,7 @@ function createInspector(options = {}) {
94
102
  }
95
103
  if (autoOpen && !didAutoOpen && ownsTransport) {
96
104
  didAutoOpen = true;
97
- const launchUrl = createInspectorLaunchUrl(url, sessionId);
98
- if (launchUrl) openBrowser(launchUrl).catch((error) => {
105
+ if (inspectorUrl) openBrowser(inspectorUrl).catch((error) => {
99
106
  const failure = {
100
107
  code: "open_failed",
101
108
  message: error instanceof Error ? error.message : "Unable to open the inspector browser"
@@ -112,6 +119,15 @@ function createInspector(options = {}) {
112
119
  }
113
120
  handleTransportReady();
114
121
  });
122
+ transport.onError?.((failure) => {
123
+ const error = new Error(failure.message);
124
+ if (!readySettled) {
125
+ readySettled = true;
126
+ rejectReady(error);
127
+ }
128
+ emitLocal("error", failure);
129
+ events.emit("error", failure);
130
+ });
115
131
  transport.onMessage((msg) => {
116
132
  if (destroyed) return;
117
133
  switch (msg.type) {
@@ -120,6 +136,10 @@ function createInspector(options = {}) {
120
136
  break;
121
137
  case "@statelyai.error":
122
138
  exportManager.reject(new Error(msg.message), msg.requestId);
139
+ if (!readySettled) {
140
+ readySettled = true;
141
+ rejectReady(new Error(msg.message));
142
+ }
123
143
  emitLocal("error", {
124
144
  code: msg.code,
125
145
  message: msg.message
@@ -138,13 +158,14 @@ function createInspector(options = {}) {
138
158
  for (const handler of set) handler(data);
139
159
  }
140
160
  const actors = /* @__PURE__ */ new Map();
161
+ const manualSessionIds = /* @__PURE__ */ new Map();
141
162
  /** Tracks which actors we've already emitted local actor events for. */
142
163
  const locallyRegistered = /* @__PURE__ */ new Set();
143
164
  /** v5 emits transition facets separately; accumulate them until snapshot. */
144
165
  const pendingTransitions = /* @__PURE__ */ new Map();
145
166
  function emitRegisterOnce(entry) {
146
- if (locallyRegistered.has(entry.actorId)) return;
147
- locallyRegistered.add(entry.actorId);
167
+ if (locallyRegistered.has(entry.sessionId)) return;
168
+ locallyRegistered.add(entry.sessionId);
148
169
  emitLocal("actor", entry);
149
170
  emitLocal("register", entry);
150
171
  }
@@ -164,10 +185,10 @@ function createInspector(options = {}) {
164
185
  }
165
186
  function toEntry(actorRef, rootActorId, details) {
166
187
  return {
167
- actorId: actorRef.sessionId,
168
- parentActorId: details?.parentRef?.sessionId ?? actorRef._parent?.sessionId ?? null,
169
- rootId: rootActorId,
170
- id: details?.id ?? actorRef.id ?? actorRef.sessionId,
188
+ sessionId: actorRef.sessionId,
189
+ actorId: details?.id ?? actorRef.id ?? actorRef.sessionId,
190
+ parentSessionId: details?.parentRef?.sessionId ?? actorRef._parent?.sessionId ?? null,
191
+ rootSessionId: rootActorId,
171
192
  systemId: actorRef.systemId,
172
193
  snapshot: details?.snapshot ? serializeSnapshot(details.snapshot) : snapshotValue(actorRef),
173
194
  stopped: stoppedValue(actorRef, details?.snapshot),
@@ -176,9 +197,9 @@ function createInspector(options = {}) {
176
197
  }
177
198
  function toSystemEntry(entry) {
178
199
  return {
200
+ sessionId: entry.sessionId,
179
201
  actorId: entry.actorId,
180
- parentActorId: entry.parentActorId,
181
- id: entry.id,
202
+ parentSessionId: entry.parentSessionId,
182
203
  machine: entry.machineConfig,
183
204
  snapshot: entry.snapshot ?? void 0,
184
205
  ...entry.stopped && { stopped: true }
@@ -195,7 +216,7 @@ function createInspector(options = {}) {
195
216
  const snapshot = actorRef.getSnapshot();
196
217
  existing.snapshot = serializeSnapshot(snapshot);
197
218
  existing.stopped ||= isStoppedSnapshot(snapshot);
198
- } else actors.set(entry.actorId, entry);
219
+ } else actors.set(entry.sessionId, entry);
199
220
  emitRegisterOnce(entry);
200
221
  const children = actorRef.getSnapshot()?.children ?? {};
201
222
  for (const child of Object.values(children)) if (child) backfillActorTree(child, rootActorId);
@@ -204,12 +225,14 @@ function createInspector(options = {}) {
204
225
  const observedRootIds = /* @__PURE__ */ new Set();
205
226
  function sendInit() {
206
227
  for (const [rootActorId, { actor }] of inspectedRoots) backfillActorTree(actor, rootActorId);
228
+ const allEntries = Array.from(actors.values());
229
+ const selectedSessionId = configuredSelectedSessionId ?? selectedActorId ?? observedRootIds.values().next().value ?? allEntries[0]?.sessionId;
207
230
  send({
208
231
  type: "@statelyai.system.init",
209
232
  protocolVersion: INSPECTION_PROTOCOL_VERSION,
210
233
  mode: "inspecting",
211
- actors: Array.from(actors.values()).map(toSystemEntry),
212
- selectedActorId: selectedActorId ?? observedRootIds.values().next().value ?? sessionId,
234
+ actors: allEntries.map(toSystemEntry),
235
+ ...selectedSessionId && { selectedSessionId },
213
236
  ...theme && { theme },
214
237
  ...readOnly !== void 0 && { readOnly },
215
238
  ...depth !== void 0 && { depth },
@@ -223,13 +246,13 @@ function createInspector(options = {}) {
223
246
  function handleActor(actorRef, rootActorId, details) {
224
247
  if (actors.has(actorRef.sessionId)) return;
225
248
  const entry = toEntry(actorRef, rootActorId, details);
226
- actors.set(entry.actorId, entry);
249
+ actors.set(entry.sessionId, entry);
227
250
  emitRegisterOnce(entry);
228
251
  if (initSent) send({
229
252
  type: "@statelyai.system.actorRegistered",
253
+ sessionId: entry.sessionId,
230
254
  actorId: entry.actorId,
231
- parentActorId: entry.parentActorId,
232
- id: entry.id,
255
+ parentSessionId: entry.parentSessionId,
233
256
  machine: entry.machineConfig,
234
257
  snapshot: entry.snapshot ?? void 0
235
258
  });
@@ -254,7 +277,7 @@ function createInspector(options = {}) {
254
277
  }
255
278
  function normalizeSentEvent(sentEvent) {
256
279
  return {
257
- ...sentEvent.targetRef?.sessionId && { targetActorId: sentEvent.targetRef.sessionId },
280
+ ...sentEvent.targetRef?.sessionId && { targetSessionId: sentEvent.targetRef.sessionId },
258
281
  targetId: sentEvent.targetId,
259
282
  event: sentEvent.event,
260
283
  ...sentEvent.delay !== void 0 && { delay: sentEvent.delay },
@@ -265,23 +288,23 @@ function createInspector(options = {}) {
265
288
  return {
266
289
  previousSnapshot: actors.get(actorRef.sessionId)?.snapshot ?? null,
267
290
  event,
268
- sourceActorId: sourceRef?.sessionId ?? null,
291
+ sourceSessionId: sourceRef?.sessionId ?? null,
269
292
  actions: [],
270
293
  transitions: [],
271
294
  sent: []
272
295
  };
273
296
  }
274
- function handleEvent(actorId, event, sourceActorId) {
297
+ function handleEvent(sessionId, event, sourceSessionId) {
275
298
  const inspectedEvent = {
276
- actorId,
277
- sourceActorId,
299
+ sessionId,
300
+ sourceSessionId,
278
301
  event
279
302
  };
280
303
  if (initSent) send({
281
304
  type: "@statelyai.system.actorEvent",
282
- actorId,
305
+ sessionId,
283
306
  event,
284
- sourceActorId
307
+ sourceSessionId
285
308
  });
286
309
  emitLocal("event", inspectedEvent);
287
310
  }
@@ -298,8 +321,8 @@ function createInspector(options = {}) {
298
321
  if (!entry) return;
299
322
  const serialized = serializeSnapshot(snapshot);
300
323
  const inspectedSnapshot = {
301
- actorId: entry.actorId,
302
- sourceActorId: transition.sourceActorId,
324
+ sessionId: entry.sessionId,
325
+ sourceSessionId: transition.sourceSessionId,
303
326
  previousSnapshot: transition.previousSnapshot,
304
327
  snapshot: serialized,
305
328
  event: triggeringEvent ?? transition.event ?? null,
@@ -311,14 +334,14 @@ function createInspector(options = {}) {
311
334
  entry.snapshot = serialized;
312
335
  const stopped = isStoppedSnapshot(snapshot);
313
336
  entry.stopped ||= stopped;
314
- pendingTransitions.delete(entry.actorId);
337
+ pendingTransitions.delete(entry.sessionId);
315
338
  if (initSent) send({
316
339
  type: "@statelyai.system.actorSnapshot",
317
- actorId: entry.actorId,
340
+ sessionId: entry.sessionId,
318
341
  previousSnapshot: inspectedSnapshot.previousSnapshot,
319
342
  snapshot: inspectedSnapshot.snapshot,
320
343
  event: inspectedSnapshot.event,
321
- sourceActorId: inspectedSnapshot.sourceActorId,
344
+ sourceSessionId: inspectedSnapshot.sourceSessionId,
322
345
  actions: inspectedSnapshot.actions,
323
346
  transitions: inspectedSnapshot.transitions,
324
347
  sent: inspectedSnapshot.sent
@@ -326,12 +349,12 @@ function createInspector(options = {}) {
326
349
  emitLocal("snapshot", inspectedSnapshot);
327
350
  emitLocal("transition", inspectedSnapshot);
328
351
  if (stopped && !wasStopped) {
329
- pendingTransitions.delete(entry.actorId);
352
+ pendingTransitions.delete(entry.sessionId);
330
353
  if (initSent) send({
331
354
  type: "@statelyai.system.actorStopped",
332
- actorId: entry.actorId
355
+ sessionId: entry.sessionId
333
356
  });
334
- const stopped = { actorId: entry.actorId };
357
+ const stopped = { sessionId: entry.sessionId };
335
358
  emitLocal("stop", stopped);
336
359
  emitLocal("stopped", stopped);
337
360
  }
@@ -372,7 +395,7 @@ function createInspector(options = {}) {
372
395
  handleTransition(event.actorRef, event.snapshot, event.event, rootActorId, {
373
396
  previousSnapshot: actors.get(event.actorRef.sessionId)?.snapshot ?? null,
374
397
  event: event.event,
375
- sourceActorId: event.sourceRef?.sessionId ?? null,
398
+ sourceSessionId: event.sourceRef?.sessionId ?? null,
376
399
  actions: event.actions.map(normalizeAction),
377
400
  transitions: event.microsteps.map(normalizeTakenTransition),
378
401
  sent: event.sent.map(normalizeSentEvent)
@@ -400,37 +423,44 @@ function createInspector(options = {}) {
400
423
  inspectedRoots.delete(rootActorId);
401
424
  } };
402
425
  }
426
+ function getManualSessionId(actorId) {
427
+ return manualSessionIds.get(actorId) ?? `${producerId}:${actorId}`;
428
+ }
403
429
  function manualRegister(id, opts) {
404
- if (actors.has(id)) return;
430
+ const sessionId = getManualSessionId(id);
431
+ if (actors.has(sessionId)) return;
432
+ manualSessionIds.set(id, sessionId);
433
+ const parentSessionId = opts?.parent ? getManualSessionId(opts.parent) : null;
405
434
  const entry = {
435
+ sessionId,
406
436
  actorId: id,
407
- parentActorId: opts?.parent ?? null,
408
- rootId: sessionId,
409
- id,
437
+ parentSessionId,
438
+ rootSessionId: (parentSessionId && actors.get(parentSessionId)?.rootSessionId) ?? sessionId,
410
439
  systemId: opts?.systemId,
411
440
  snapshot: opts?.snapshot ?? null,
412
441
  stopped: false,
413
442
  machineConfig: opts?.machine ?? null
414
443
  };
415
- actors.set(id, entry);
444
+ actors.set(sessionId, entry);
416
445
  if (!initSent) sendInit();
417
446
  else send({
418
447
  type: "@statelyai.system.actorRegistered",
448
+ sessionId,
419
449
  actorId: id,
420
- parentActorId: entry.parentActorId,
421
- id,
450
+ parentSessionId: entry.parentSessionId,
422
451
  machine: entry.machineConfig,
423
452
  snapshot: entry.snapshot ?? void 0
424
453
  });
425
454
  emitRegisterOnce(entry);
426
455
  }
427
456
  function manualSnapshot(actorId, snapshot, event) {
428
- if (!actors.has(actorId)) manualRegister(actorId);
429
- const entry = actors.get(actorId);
457
+ const sessionId = getManualSessionId(actorId);
458
+ if (!actors.has(sessionId)) manualRegister(actorId);
459
+ const entry = actors.get(sessionId);
430
460
  const previousSnapshot = entry.snapshot;
431
461
  const inspectedSnapshot = {
432
- actorId,
433
- sourceActorId: null,
462
+ sessionId,
463
+ sourceSessionId: null,
434
464
  previousSnapshot,
435
465
  snapshot,
436
466
  event: event ?? null,
@@ -441,11 +471,11 @@ function createInspector(options = {}) {
441
471
  entry.snapshot = snapshot;
442
472
  if (initSent) send({
443
473
  type: "@statelyai.system.actorSnapshot",
444
- actorId,
474
+ sessionId,
445
475
  previousSnapshot,
446
476
  snapshot,
447
477
  event: event ?? null,
448
- sourceActorId: null,
478
+ sourceSessionId: null,
449
479
  actions: [],
450
480
  transitions: [],
451
481
  sent: []
@@ -455,18 +485,20 @@ function createInspector(options = {}) {
455
485
  }
456
486
  function manualEvent(actorId, event, eventOpts) {
457
487
  const eventObj = typeof event === "string" ? { type: event } : { ...event };
458
- if (!actors.has(actorId)) manualRegister(actorId);
459
- handleEvent(actorId, eventObj, eventOpts?.source ?? null);
488
+ const sessionId = getManualSessionId(actorId);
489
+ if (!actors.has(sessionId)) manualRegister(actorId);
490
+ handleEvent(sessionId, eventObj, eventOpts?.source ? getManualSessionId(eventOpts.source) : null);
460
491
  }
461
492
  function manualStop(actorId) {
462
- const entry = actors.get(actorId);
493
+ const sessionId = getManualSessionId(actorId);
494
+ const entry = actors.get(sessionId);
463
495
  if (!entry || entry.stopped) return;
464
496
  entry.stopped = true;
465
497
  if (initSent) send({
466
498
  type: "@statelyai.system.actorStopped",
467
- actorId
499
+ sessionId
468
500
  });
469
- const stopped = { actorId };
501
+ const stopped = { sessionId };
470
502
  emitLocal("stop", stopped);
471
503
  emitLocal("stopped", stopped);
472
504
  }
@@ -477,9 +509,14 @@ function createInspector(options = {}) {
477
509
  }
478
510
  return {
479
511
  actors,
512
+ roomId,
513
+ relayUrl,
514
+ producerId,
480
515
  get sessionId() {
481
- return sessionId;
516
+ return roomId;
482
517
  },
518
+ inspectorUrl,
519
+ ready,
483
520
  inspect: handleInspectionEvent,
484
521
  attach: attachActor,
485
522
  on(event, handler) {
@@ -1,12 +1,17 @@
1
1
  import { EditorCapabilities, EmbedEventMap, ExportCallOptions, ExportFormat, ExportFormatMap, InspectionAction, InspectionSentEvent, InspectionTakenTransition, ProtocolMessage } from "./protocol.mjs";
2
2
 
3
3
  //#region src/transport.d.ts
4
+ interface TransportFailure {
5
+ code: string;
6
+ message: string;
7
+ }
4
8
  interface Transport {
5
9
  send(msg: ProtocolMessage): void;
6
10
  onMessage(handler: (msg: ProtocolMessage) => void): () => void;
7
11
  destroy(): void;
8
12
  readonly ready: boolean;
9
13
  onReady(handler: () => void): () => void;
14
+ onError?(handler: (failure: TransportFailure) => void): () => void;
10
15
  }
11
16
  interface PostMessageTransportOptions {
12
17
  iframe: HTMLIFrameElement;
@@ -17,51 +22,18 @@ interface PostMessageTransportOptions {
17
22
  declare function createPostMessageTransport(options: PostMessageTransportOptions): Transport;
18
23
  interface WebSocketTransportOptions {
19
24
  url: string;
20
- role: 'client' | 'viz';
21
- sessionId: string;
25
+ role: 'producer' | 'viewer';
26
+ producerId?: string;
22
27
  metadata?: {
23
28
  name?: string;
24
29
  machineId?: string;
25
30
  };
26
31
  /** Reconnect on disconnect. Default true. */
27
32
  reconnect?: boolean;
28
- /** Max reconnect attempts. Default 10. */
33
+ /** Max reconnect attempts after the first connection. Default 10. */
29
34
  maxReconnectAttempts?: number;
30
35
  }
31
36
  declare function createWebSocketTransport(options: WebSocketTransportOptions): Transport;
32
- interface MultiplexedWebSocketConnectionOptions {
33
- url: string;
34
- role: 'client' | 'viz';
35
- /** First (primary) session to register on connect. */
36
- sessionId: string;
37
- /** Metadata for the primary session. */
38
- metadata?: {
39
- name?: string;
40
- machineId?: string;
41
- };
42
- reconnect?: boolean;
43
- maxReconnectAttempts?: number;
44
- }
45
- interface MultiplexedChannelOptions {
46
- /** Session id this channel targets. */
47
- sessionId: string;
48
- /** Optional metadata for this session. */
49
- metadata?: {
50
- name?: string;
51
- machineId?: string;
52
- };
53
- }
54
- interface MultiplexedWebSocketConnection {
55
- /** Open a channel for a sessionId. Re-opening an existing session returns the same channel. */
56
- openChannel(options: MultiplexedChannelOptions): Transport;
57
- /** Close the connection and all its channels. */
58
- destroy(): void;
59
- /** Whether the underlying WebSocket is connected + the primary session is registered. */
60
- readonly ready: boolean;
61
- /** Primary session id (first registered). */
62
- readonly primarySessionId: string;
63
- }
64
- declare function createMultiplexedWebSocketConnection(options: MultiplexedWebSocketConnectionOptions): MultiplexedWebSocketConnection;
65
37
  //#endregion
66
38
  //#region src/inspect.d.ts
67
39
  interface MinimalActorRef {
@@ -93,14 +65,14 @@ interface InspectorInspectionEvent {
93
65
  readonly actorRef: unknown;
94
66
  }
95
67
  interface AdoptedActor {
96
- /** `actor.sessionId` from xstate. Unique across the system. */
68
+ /** Globally unique `actor.sessionId` from xstate. */
69
+ sessionId: string;
70
+ /** System-local `actor.id`. */
97
71
  actorId: string;
98
72
  /** Parent actor's sessionId, or `null` for the root. */
99
- parentActorId: string | null;
100
- /** Root actor's sessionId (equal to `actorId` for the root). */
101
- rootId: string;
102
- /** `actor.id` — a human-facing local name. */
103
- id: string;
73
+ parentSessionId: string | null;
74
+ /** Root actor's sessionId. */
75
+ rootSessionId: string;
104
76
  /** `actor.systemId`, if registered under one. */
105
77
  systemId: string | undefined;
106
78
  /** Latest serialized snapshot streamed for this actor. */
@@ -112,8 +84,8 @@ interface AdoptedActor {
112
84
  }
113
85
  /** One observed snapshot, independent of the XState inspection version. */
114
86
  interface InspectedSnapshot {
115
- actorId: string;
116
- sourceActorId: string | null;
87
+ sessionId: string;
88
+ sourceSessionId: string | null;
117
89
  /** Previously observed snapshot, which may not be the immediate predecessor. */
118
90
  previousSnapshot: unknown | null;
119
91
  snapshot: unknown;
@@ -127,8 +99,8 @@ interface InspectedSnapshot {
127
99
  type InspectedTransition = InspectedSnapshot;
128
100
  /** One observed event, independent of whether processing produced a snapshot. */
129
101
  interface InspectedEvent {
130
- actorId: string;
131
- sourceActorId: string | null;
102
+ sessionId: string;
103
+ sourceSessionId: string | null;
132
104
  event: unknown;
133
105
  }
134
106
  interface InspectorEvents {
@@ -136,7 +108,7 @@ interface InspectorEvents {
136
108
  event: InspectedEvent;
137
109
  snapshot: InspectedSnapshot;
138
110
  stop: {
139
- actorId: string;
111
+ sessionId: string;
140
112
  };
141
113
  /** @deprecated Use `actor`. */
142
114
  register: AdoptedActor;
@@ -144,7 +116,7 @@ interface InspectorEvents {
144
116
  transition: InspectedSnapshot;
145
117
  /** @deprecated Use `stop`. */
146
118
  stopped: {
147
- actorId: string;
119
+ sessionId: string;
148
120
  };
149
121
  error: EmbedEventMap['error'];
150
122
  }
@@ -161,15 +133,27 @@ interface ManualActorOptions {
161
133
  systemId?: string;
162
134
  }
163
135
  interface CreateInspectorOptions {
164
- /** WebSocket URL of the devtools server. Default: `'ws://localhost:4242'`. */
136
+ /**
137
+ * WebSocket relay base URL. Defaults to `STATELY_INSPECT_URL`, then
138
+ * `wss://sky.stately.ai`. Passing this option always wins.
139
+ */
165
140
  url?: string;
141
+ /** Unguessable inspection room capability. Defaults to a random UUID. */
142
+ roomId?: string;
143
+ /** Stable identity for this producer connection. Defaults to a random UUID. */
144
+ producerId?: string;
145
+ /**
146
+ * Inspector UI base URL when hosted separately from the WebSocket relay. The
147
+ * inspector adds `ws` and `r` query parameters. When omitted, the URL
148
+ * is derived from the relay URL by replacing `ws` with `http`.
149
+ */
150
+ inspectorBaseUrl?: string;
166
151
  /** Auto-open browser to visualizer. Default: `true`. */
167
152
  autoOpen?: boolean;
168
153
  /**
169
- * Relay session capability. Defaults to a cryptographically random UUID.
170
- * This is the `?session=<id>` value the visualizer connects with. Custom
171
- * values used with a hosted relay must be unguessable.
154
+ * Legacy name for the unguessable room capability.
172
155
  */
156
+ /** @deprecated Use {@link roomId}. */
173
157
  sessionId?: string;
174
158
  /** Display name for this system in the visualizer. */
175
159
  name?: string;
@@ -184,7 +168,9 @@ interface CreateInspectorOptions {
184
168
  * `actor.logic.config`. Return `null` for non-machine actors.
185
169
  */
186
170
  extractMachineConfig?: (actor: any, source?: unknown) => unknown;
187
- /** Selected actor id to focus on first. Defaults to the first inspected root. */
171
+ /** Selected actor session id to focus on first. */
172
+ selectedSessionId?: string;
173
+ /** @deprecated Use {@link selectedSessionId}. */
188
174
  selectedActorId?: string;
189
175
  /** Panel layout forwarded into the system init message. */
190
176
  panels?: {
@@ -197,17 +183,26 @@ interface CreateInspectorOptions {
197
183
  depth?: number;
198
184
  capabilities?: EditorCapabilities;
199
185
  /**
200
- * Advanced: inject a pre-built transport (e.g. a channel from a
201
- * multiplexed connection). When provided, `url`/`name` are ignored and the
202
- * inspector shares that transport instead of opening its own WebSocket.
186
+ * Advanced: inject a pre-built transport. When provided, `url`/`name` are
187
+ * ignored and no WebSocket or browser URL is created.
203
188
  */
204
189
  transport?: Transport;
205
190
  }
206
191
  interface Inspector {
207
- /** Snapshot of currently-adopted actors keyed by `actorId`. */
192
+ /** Snapshot of currently-adopted actors keyed by global `sessionId`. */
208
193
  readonly actors: ReadonlyMap<string, AdoptedActor>;
209
- /** The relay sessionId this inspector registered under. */
194
+ /** Unguessable inspection room capability. */
195
+ readonly roomId: string;
196
+ /** Complete WebSocket URL for this room. */
197
+ readonly relayUrl: string | null;
198
+ /** Identity stamped onto this producer's protocol messages. */
199
+ readonly producerId: string;
200
+ /** @deprecated Use {@link roomId}. */
210
201
  readonly sessionId: string;
202
+ /** URL that opens the inspector UI for this live session. */
203
+ readonly inspectorUrl: string | null;
204
+ /** Resolves after the first relay registration and initial-state flush. */
205
+ readonly ready: Promise<void>;
211
206
  /**
212
207
  * XState `inspect` option callback. Pass directly to `createActor` or another
213
208
  * host that creates actors internally.
@@ -251,4 +246,4 @@ declare function createInspector(options?: CreateInspectorOptions): Inspector;
251
246
  /** @deprecated Use {@link createInspector}. */
252
247
  declare const createStatelyInspector: typeof createInspector;
253
248
  //#endregion
254
- export { createPostMessageTransport as _, InspectedTransition as a, InspectorInspectionEvent as c, createStatelyInspector as d, MultiplexedChannelOptions as f, createMultiplexedWebSocketConnection as g, Transport as h, InspectedSnapshot as i, ManualActorOptions as l, MultiplexedWebSocketConnectionOptions as m, CreateInspectorOptions as n, Inspector as o, MultiplexedWebSocketConnection as p, InspectedEvent as r, InspectorEvents as s, AdoptedActor as t, createInspector as u, createWebSocketTransport as v };
249
+ export { InspectedTransition as a, InspectorInspectionEvent as c, createStatelyInspector as d, Transport as f, createWebSocketTransport as h, InspectedSnapshot as i, ManualActorOptions as l, createPostMessageTransport as m, CreateInspectorOptions as n, Inspector as o, TransportFailure as p, InspectedEvent as r, InspectorEvents as s, AdoptedActor as t, createInspector as u };
@@ -1,3 +1,3 @@
1
1
  import { EditorCapabilities, EmbedEventHandler, EmbedEventMap, EmbedEventName, EmbedMode, ExportCallOptions, ExportFormat, ExportFormatMap, InspectionAction, InspectionSentEvent, InspectionTakenTransition } from "./protocol.mjs";
2
- import { a as InspectedTransition, c as InspectorInspectionEvent, d as createStatelyInspector, h as Transport, i as InspectedSnapshot, l as ManualActorOptions, n as CreateInspectorOptions, o as Inspector, r as InspectedEvent, s as InspectorEvents, t as AdoptedActor, u as createInspector } from "./inspect-DQ_7I7eH.mjs";
2
+ import { a as InspectedTransition, c as InspectorInspectionEvent, d as createStatelyInspector, f as Transport, i as InspectedSnapshot, l as ManualActorOptions, n as CreateInspectorOptions, o as Inspector, r as InspectedEvent, s as InspectorEvents, t as AdoptedActor, u as createInspector } from "./inspect-CduY_2Fa.mjs";
3
3
  export { AdoptedActor, CreateInspectorOptions, EditorCapabilities, EmbedEventHandler, EmbedEventMap, EmbedEventName, EmbedMode, ExportCallOptions, ExportFormat, ExportFormatMap, InspectedEvent, InspectedSnapshot, InspectedTransition, InspectionAction, InspectionSentEvent, InspectionTakenTransition, Inspector, InspectorEvents, InspectorInspectionEvent, ManualActorOptions, Transport, createInspector, createStatelyInspector };
package/dist/inspect.mjs CHANGED
@@ -1,3 +1,3 @@
1
- import { n as createStatelyInspector, t as createInspector } from "./inspect-DWDTNMEc.mjs";
1
+ import { n as createStatelyInspector, t as createInspector } from "./inspect-BwVdM4R8.mjs";
2
2
 
3
3
  export { createInspector, createStatelyInspector };
@@ -0,0 +1,22 @@
1
+ //#region src/node-relay.d.ts
2
+ interface NodeInspectionRelayOptions {
3
+ host?: string;
4
+ port?: number;
5
+ logger?: Pick<Console, 'info'>;
6
+ }
7
+ /** Local/self-hosted Node adapter for the room inspection relay. */
8
+ declare class NodeInspectionRelayServer {
9
+ private readonly options;
10
+ private server;
11
+ private webSocketServer;
12
+ private readonly rooms;
13
+ private readonly connections;
14
+ private readonly sockets;
15
+ constructor(options?: NodeInspectionRelayOptions);
16
+ get url(): string;
17
+ start(): Promise<void>;
18
+ stop(): Promise<void>;
19
+ }
20
+ declare function createNodeInspectionRelay(options?: NodeInspectionRelayOptions): NodeInspectionRelayServer;
21
+ //#endregion
22
+ export { NodeInspectionRelayOptions, NodeInspectionRelayServer, createNodeInspectionRelay };