@statelyai/sdk 0.15.0 → 0.16.1
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/README.md +45 -8
- package/dist/bin.d.mts +1 -0
- package/dist/bin.mjs +35 -0
- package/dist/embed.mjs +1 -1
- package/dist/index.d.mts +4 -4
- package/dist/index.mjs +4 -4
- package/dist/{inspect-DenVP7IE.d.mts → inspect-BScvqVcM.d.mts} +56 -64
- package/dist/{inspect-DWDTNMEc.mjs → inspect-C3Y_o_Np.mjs} +123 -73
- package/dist/inspect.d.mts +1 -1
- package/dist/inspect.mjs +1 -1
- package/dist/node-relay.d.mts +22 -0
- package/dist/node-relay.mjs +84 -0
- package/dist/protocol.d.mts +108 -118
- package/dist/protocol.mjs +33 -2
- package/dist/relay.d.mts +10 -11
- package/dist/relay.mjs +83 -62
- package/dist/studio.d.mts +1 -1
- package/dist/sync.d.mts +1 -1
- package/dist/{transport-D2Ud05yg.mjs → transport-B_ig9Znn.mjs} +56 -198
- package/package.json +15 -4
- /package/dist/{studio-Da5pyxv6.d.mts → studio-Bk_u41gu.d.mts} +0 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
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) {
|
|
@@ -26,6 +26,15 @@ async function openBrowser(url) {
|
|
|
26
26
|
});
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
+
//#endregion
|
|
30
|
+
//#region src/version.ts
|
|
31
|
+
const SDK_VERSION = "0.16.1";
|
|
32
|
+
function inspectionRuntime() {
|
|
33
|
+
if (typeof window !== "undefined") return "browser";
|
|
34
|
+
if (typeof process !== "undefined" && process.versions?.node) return "node";
|
|
35
|
+
return "unknown";
|
|
36
|
+
}
|
|
37
|
+
|
|
29
38
|
//#endregion
|
|
30
39
|
//#region src/inspect.ts
|
|
31
40
|
const defaultSerializeSnapshot = (snapshot) => ({
|
|
@@ -37,25 +46,23 @@ function isStoppedSnapshot(snapshot) {
|
|
|
37
46
|
const status = snapshot?.status;
|
|
38
47
|
return status === "done" || status === "stopped" || status === "error";
|
|
39
48
|
}
|
|
40
|
-
function
|
|
41
|
-
if (!globalThis.crypto?.randomUUID) throw new Error("createInspector() requires crypto.randomUUID() to generate a secure
|
|
49
|
+
function generateRoomId() {
|
|
50
|
+
if (!globalThis.crypto?.randomUUID) throw new Error("createInspector() requires crypto.randomUUID() to generate a secure room capability. Pass roomId explicitly in older runtimes.");
|
|
42
51
|
return globalThis.crypto.randomUUID();
|
|
43
52
|
}
|
|
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
53
|
function createInspector(options = {}) {
|
|
57
|
-
const
|
|
58
|
-
const
|
|
54
|
+
const environmentUrl = typeof process !== "undefined" ? process.env?.STATELY_INSPECT_URL : void 0;
|
|
55
|
+
const url = options.url ?? environmentUrl ?? "wss://sky.stately.ai";
|
|
56
|
+
const { inspectorBaseUrl, autoOpen = true, name, serializeSnapshot = defaultSerializeSnapshot, extractMachineConfig = defaultExtractMachineConfig, selectedSessionId: configuredSelectedSessionId, selectedActorId, panels, theme, readOnly, depth, capabilities, transport: injectedTransport } = options;
|
|
57
|
+
const roomId = options.roomId ?? options.sessionId ?? getInspectionRoomId(url) ?? generateRoomId();
|
|
58
|
+
const producerId = options.producerId ?? generateRoomId();
|
|
59
|
+
const roomUrls = injectedTransport ? null : createInspectionRoomUrls({
|
|
60
|
+
url,
|
|
61
|
+
roomId,
|
|
62
|
+
inspectorBaseUrl
|
|
63
|
+
});
|
|
64
|
+
const relayUrl = roomUrls?.relayUrl ?? null;
|
|
65
|
+
const inspectorUrl = roomUrls?.inspectorUrl ?? null;
|
|
59
66
|
const displayName = name ?? "system:manual";
|
|
60
67
|
let destroyed = false;
|
|
61
68
|
let initSent = false;
|
|
@@ -63,14 +70,26 @@ function createInspector(options = {}) {
|
|
|
63
70
|
let pendingTransportReady = false;
|
|
64
71
|
let transportWasReady = false;
|
|
65
72
|
let didAutoOpen = false;
|
|
73
|
+
let resolveReady;
|
|
74
|
+
let rejectReady;
|
|
75
|
+
let readySettled = false;
|
|
76
|
+
const ready = new Promise((resolve, reject) => {
|
|
77
|
+
resolveReady = resolve;
|
|
78
|
+
rejectReady = reject;
|
|
79
|
+
});
|
|
80
|
+
ready.catch(() => {});
|
|
66
81
|
const pendingMessages = [];
|
|
67
82
|
const events = createEventRegistry();
|
|
68
83
|
const localListeners = {};
|
|
69
84
|
const transport = injectedTransport ?? createWebSocketTransport({
|
|
70
|
-
url,
|
|
71
|
-
role: "
|
|
72
|
-
|
|
73
|
-
metadata: {
|
|
85
|
+
url: relayUrl,
|
|
86
|
+
role: "producer",
|
|
87
|
+
producerId,
|
|
88
|
+
metadata: {
|
|
89
|
+
name: displayName,
|
|
90
|
+
sdkVersion: SDK_VERSION,
|
|
91
|
+
runtime: inspectionRuntime()
|
|
92
|
+
}
|
|
74
93
|
});
|
|
75
94
|
const ownsTransport = !injectedTransport;
|
|
76
95
|
const exportManager = createPendingExportManager((message) => send(message));
|
|
@@ -87,6 +106,8 @@ function createInspector(options = {}) {
|
|
|
87
106
|
if (!initSent) sendInit();
|
|
88
107
|
const queued = pendingMessages.splice(0);
|
|
89
108
|
for (const message of queued) transport.send(message);
|
|
109
|
+
readySettled = true;
|
|
110
|
+
resolveReady();
|
|
90
111
|
} else {
|
|
91
112
|
pendingMessages.length = 0;
|
|
92
113
|
initSent = false;
|
|
@@ -94,8 +115,7 @@ function createInspector(options = {}) {
|
|
|
94
115
|
}
|
|
95
116
|
if (autoOpen && !didAutoOpen && ownsTransport) {
|
|
96
117
|
didAutoOpen = true;
|
|
97
|
-
|
|
98
|
-
if (launchUrl) openBrowser(launchUrl).catch((error) => {
|
|
118
|
+
if (inspectorUrl) openBrowser(inspectorUrl).catch((error) => {
|
|
99
119
|
const failure = {
|
|
100
120
|
code: "open_failed",
|
|
101
121
|
message: error instanceof Error ? error.message : "Unable to open the inspector browser"
|
|
@@ -112,6 +132,15 @@ function createInspector(options = {}) {
|
|
|
112
132
|
}
|
|
113
133
|
handleTransportReady();
|
|
114
134
|
});
|
|
135
|
+
transport.onError?.((failure) => {
|
|
136
|
+
const error = new Error(failure.message);
|
|
137
|
+
if (!readySettled) {
|
|
138
|
+
readySettled = true;
|
|
139
|
+
rejectReady(error);
|
|
140
|
+
}
|
|
141
|
+
emitLocal("error", failure);
|
|
142
|
+
events.emit("error", failure);
|
|
143
|
+
});
|
|
115
144
|
transport.onMessage((msg) => {
|
|
116
145
|
if (destroyed) return;
|
|
117
146
|
switch (msg.type) {
|
|
@@ -120,6 +149,10 @@ function createInspector(options = {}) {
|
|
|
120
149
|
break;
|
|
121
150
|
case "@statelyai.error":
|
|
122
151
|
exportManager.reject(new Error(msg.message), msg.requestId);
|
|
152
|
+
if (!readySettled) {
|
|
153
|
+
readySettled = true;
|
|
154
|
+
rejectReady(new Error(msg.message));
|
|
155
|
+
}
|
|
123
156
|
emitLocal("error", {
|
|
124
157
|
code: msg.code,
|
|
125
158
|
message: msg.message
|
|
@@ -138,13 +171,14 @@ function createInspector(options = {}) {
|
|
|
138
171
|
for (const handler of set) handler(data);
|
|
139
172
|
}
|
|
140
173
|
const actors = /* @__PURE__ */ new Map();
|
|
174
|
+
const manualSessionIds = /* @__PURE__ */ new Map();
|
|
141
175
|
/** Tracks which actors we've already emitted local actor events for. */
|
|
142
176
|
const locallyRegistered = /* @__PURE__ */ new Set();
|
|
143
177
|
/** v5 emits transition facets separately; accumulate them until snapshot. */
|
|
144
178
|
const pendingTransitions = /* @__PURE__ */ new Map();
|
|
145
179
|
function emitRegisterOnce(entry) {
|
|
146
|
-
if (locallyRegistered.has(entry.
|
|
147
|
-
locallyRegistered.add(entry.
|
|
180
|
+
if (locallyRegistered.has(entry.sessionId)) return;
|
|
181
|
+
locallyRegistered.add(entry.sessionId);
|
|
148
182
|
emitLocal("actor", entry);
|
|
149
183
|
emitLocal("register", entry);
|
|
150
184
|
}
|
|
@@ -164,10 +198,10 @@ function createInspector(options = {}) {
|
|
|
164
198
|
}
|
|
165
199
|
function toEntry(actorRef, rootActorId, details) {
|
|
166
200
|
return {
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
201
|
+
sessionId: actorRef.sessionId,
|
|
202
|
+
actorId: details?.id ?? actorRef.id ?? actorRef.sessionId,
|
|
203
|
+
parentSessionId: details?.parentRef?.sessionId ?? actorRef._parent?.sessionId ?? null,
|
|
204
|
+
rootSessionId: rootActorId,
|
|
171
205
|
systemId: actorRef.systemId,
|
|
172
206
|
snapshot: details?.snapshot ? serializeSnapshot(details.snapshot) : snapshotValue(actorRef),
|
|
173
207
|
stopped: stoppedValue(actorRef, details?.snapshot),
|
|
@@ -176,9 +210,9 @@ function createInspector(options = {}) {
|
|
|
176
210
|
}
|
|
177
211
|
function toSystemEntry(entry) {
|
|
178
212
|
return {
|
|
213
|
+
sessionId: entry.sessionId,
|
|
179
214
|
actorId: entry.actorId,
|
|
180
|
-
|
|
181
|
-
id: entry.id,
|
|
215
|
+
parentSessionId: entry.parentSessionId,
|
|
182
216
|
machine: entry.machineConfig,
|
|
183
217
|
snapshot: entry.snapshot ?? void 0,
|
|
184
218
|
...entry.stopped && { stopped: true }
|
|
@@ -195,7 +229,7 @@ function createInspector(options = {}) {
|
|
|
195
229
|
const snapshot = actorRef.getSnapshot();
|
|
196
230
|
existing.snapshot = serializeSnapshot(snapshot);
|
|
197
231
|
existing.stopped ||= isStoppedSnapshot(snapshot);
|
|
198
|
-
} else actors.set(entry.
|
|
232
|
+
} else actors.set(entry.sessionId, entry);
|
|
199
233
|
emitRegisterOnce(entry);
|
|
200
234
|
const children = actorRef.getSnapshot()?.children ?? {};
|
|
201
235
|
for (const child of Object.values(children)) if (child) backfillActorTree(child, rootActorId);
|
|
@@ -204,12 +238,14 @@ function createInspector(options = {}) {
|
|
|
204
238
|
const observedRootIds = /* @__PURE__ */ new Set();
|
|
205
239
|
function sendInit() {
|
|
206
240
|
for (const [rootActorId, { actor }] of inspectedRoots) backfillActorTree(actor, rootActorId);
|
|
241
|
+
const allEntries = Array.from(actors.values());
|
|
242
|
+
const selectedSessionId = configuredSelectedSessionId ?? selectedActorId ?? observedRootIds.values().next().value ?? allEntries[0]?.sessionId;
|
|
207
243
|
send({
|
|
208
244
|
type: "@statelyai.system.init",
|
|
209
245
|
protocolVersion: INSPECTION_PROTOCOL_VERSION,
|
|
210
246
|
mode: "inspecting",
|
|
211
|
-
actors:
|
|
212
|
-
|
|
247
|
+
actors: allEntries.map(toSystemEntry),
|
|
248
|
+
...selectedSessionId && { selectedSessionId },
|
|
213
249
|
...theme && { theme },
|
|
214
250
|
...readOnly !== void 0 && { readOnly },
|
|
215
251
|
...depth !== void 0 && { depth },
|
|
@@ -223,13 +259,13 @@ function createInspector(options = {}) {
|
|
|
223
259
|
function handleActor(actorRef, rootActorId, details) {
|
|
224
260
|
if (actors.has(actorRef.sessionId)) return;
|
|
225
261
|
const entry = toEntry(actorRef, rootActorId, details);
|
|
226
|
-
actors.set(entry.
|
|
262
|
+
actors.set(entry.sessionId, entry);
|
|
227
263
|
emitRegisterOnce(entry);
|
|
228
264
|
if (initSent) send({
|
|
229
265
|
type: "@statelyai.system.actorRegistered",
|
|
266
|
+
sessionId: entry.sessionId,
|
|
230
267
|
actorId: entry.actorId,
|
|
231
|
-
|
|
232
|
-
id: entry.id,
|
|
268
|
+
parentSessionId: entry.parentSessionId,
|
|
233
269
|
machine: entry.machineConfig,
|
|
234
270
|
snapshot: entry.snapshot ?? void 0
|
|
235
271
|
});
|
|
@@ -254,7 +290,7 @@ function createInspector(options = {}) {
|
|
|
254
290
|
}
|
|
255
291
|
function normalizeSentEvent(sentEvent) {
|
|
256
292
|
return {
|
|
257
|
-
...sentEvent.targetRef?.sessionId && {
|
|
293
|
+
...sentEvent.targetRef?.sessionId && { targetSessionId: sentEvent.targetRef.sessionId },
|
|
258
294
|
targetId: sentEvent.targetId,
|
|
259
295
|
event: sentEvent.event,
|
|
260
296
|
...sentEvent.delay !== void 0 && { delay: sentEvent.delay },
|
|
@@ -265,23 +301,23 @@ function createInspector(options = {}) {
|
|
|
265
301
|
return {
|
|
266
302
|
previousSnapshot: actors.get(actorRef.sessionId)?.snapshot ?? null,
|
|
267
303
|
event,
|
|
268
|
-
|
|
304
|
+
sourceSessionId: sourceRef?.sessionId ?? null,
|
|
269
305
|
actions: [],
|
|
270
306
|
transitions: [],
|
|
271
307
|
sent: []
|
|
272
308
|
};
|
|
273
309
|
}
|
|
274
|
-
function handleEvent(
|
|
310
|
+
function handleEvent(sessionId, event, sourceSessionId) {
|
|
275
311
|
const inspectedEvent = {
|
|
276
|
-
|
|
277
|
-
|
|
312
|
+
sessionId,
|
|
313
|
+
sourceSessionId,
|
|
278
314
|
event
|
|
279
315
|
};
|
|
280
316
|
if (initSent) send({
|
|
281
317
|
type: "@statelyai.system.actorEvent",
|
|
282
|
-
|
|
318
|
+
sessionId,
|
|
283
319
|
event,
|
|
284
|
-
|
|
320
|
+
sourceSessionId
|
|
285
321
|
});
|
|
286
322
|
emitLocal("event", inspectedEvent);
|
|
287
323
|
}
|
|
@@ -298,8 +334,8 @@ function createInspector(options = {}) {
|
|
|
298
334
|
if (!entry) return;
|
|
299
335
|
const serialized = serializeSnapshot(snapshot);
|
|
300
336
|
const inspectedSnapshot = {
|
|
301
|
-
|
|
302
|
-
|
|
337
|
+
sessionId: entry.sessionId,
|
|
338
|
+
sourceSessionId: transition.sourceSessionId,
|
|
303
339
|
previousSnapshot: transition.previousSnapshot,
|
|
304
340
|
snapshot: serialized,
|
|
305
341
|
event: triggeringEvent ?? transition.event ?? null,
|
|
@@ -311,14 +347,14 @@ function createInspector(options = {}) {
|
|
|
311
347
|
entry.snapshot = serialized;
|
|
312
348
|
const stopped = isStoppedSnapshot(snapshot);
|
|
313
349
|
entry.stopped ||= stopped;
|
|
314
|
-
pendingTransitions.delete(entry.
|
|
350
|
+
pendingTransitions.delete(entry.sessionId);
|
|
315
351
|
if (initSent) send({
|
|
316
352
|
type: "@statelyai.system.actorSnapshot",
|
|
317
|
-
|
|
353
|
+
sessionId: entry.sessionId,
|
|
318
354
|
previousSnapshot: inspectedSnapshot.previousSnapshot,
|
|
319
355
|
snapshot: inspectedSnapshot.snapshot,
|
|
320
356
|
event: inspectedSnapshot.event,
|
|
321
|
-
|
|
357
|
+
sourceSessionId: inspectedSnapshot.sourceSessionId,
|
|
322
358
|
actions: inspectedSnapshot.actions,
|
|
323
359
|
transitions: inspectedSnapshot.transitions,
|
|
324
360
|
sent: inspectedSnapshot.sent
|
|
@@ -326,12 +362,12 @@ function createInspector(options = {}) {
|
|
|
326
362
|
emitLocal("snapshot", inspectedSnapshot);
|
|
327
363
|
emitLocal("transition", inspectedSnapshot);
|
|
328
364
|
if (stopped && !wasStopped) {
|
|
329
|
-
pendingTransitions.delete(entry.
|
|
365
|
+
pendingTransitions.delete(entry.sessionId);
|
|
330
366
|
if (initSent) send({
|
|
331
367
|
type: "@statelyai.system.actorStopped",
|
|
332
|
-
|
|
368
|
+
sessionId: entry.sessionId
|
|
333
369
|
});
|
|
334
|
-
const stopped = {
|
|
370
|
+
const stopped = { sessionId: entry.sessionId };
|
|
335
371
|
emitLocal("stop", stopped);
|
|
336
372
|
emitLocal("stopped", stopped);
|
|
337
373
|
}
|
|
@@ -372,7 +408,7 @@ function createInspector(options = {}) {
|
|
|
372
408
|
handleTransition(event.actorRef, event.snapshot, event.event, rootActorId, {
|
|
373
409
|
previousSnapshot: actors.get(event.actorRef.sessionId)?.snapshot ?? null,
|
|
374
410
|
event: event.event,
|
|
375
|
-
|
|
411
|
+
sourceSessionId: event.sourceRef?.sessionId ?? null,
|
|
376
412
|
actions: event.actions.map(normalizeAction),
|
|
377
413
|
transitions: event.microsteps.map(normalizeTakenTransition),
|
|
378
414
|
sent: event.sent.map(normalizeSentEvent)
|
|
@@ -400,37 +436,44 @@ function createInspector(options = {}) {
|
|
|
400
436
|
inspectedRoots.delete(rootActorId);
|
|
401
437
|
} };
|
|
402
438
|
}
|
|
439
|
+
function getManualSessionId(actorId) {
|
|
440
|
+
return manualSessionIds.get(actorId) ?? `${producerId}:${actorId}`;
|
|
441
|
+
}
|
|
403
442
|
function manualRegister(id, opts) {
|
|
404
|
-
|
|
443
|
+
const sessionId = getManualSessionId(id);
|
|
444
|
+
if (actors.has(sessionId)) return;
|
|
445
|
+
manualSessionIds.set(id, sessionId);
|
|
446
|
+
const parentSessionId = opts?.parent ? getManualSessionId(opts.parent) : null;
|
|
405
447
|
const entry = {
|
|
448
|
+
sessionId,
|
|
406
449
|
actorId: id,
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
id,
|
|
450
|
+
parentSessionId,
|
|
451
|
+
rootSessionId: (parentSessionId && actors.get(parentSessionId)?.rootSessionId) ?? sessionId,
|
|
410
452
|
systemId: opts?.systemId,
|
|
411
453
|
snapshot: opts?.snapshot ?? null,
|
|
412
454
|
stopped: false,
|
|
413
455
|
machineConfig: opts?.machine ?? null
|
|
414
456
|
};
|
|
415
|
-
actors.set(
|
|
457
|
+
actors.set(sessionId, entry);
|
|
416
458
|
if (!initSent) sendInit();
|
|
417
459
|
else send({
|
|
418
460
|
type: "@statelyai.system.actorRegistered",
|
|
461
|
+
sessionId,
|
|
419
462
|
actorId: id,
|
|
420
|
-
|
|
421
|
-
id,
|
|
463
|
+
parentSessionId: entry.parentSessionId,
|
|
422
464
|
machine: entry.machineConfig,
|
|
423
465
|
snapshot: entry.snapshot ?? void 0
|
|
424
466
|
});
|
|
425
467
|
emitRegisterOnce(entry);
|
|
426
468
|
}
|
|
427
469
|
function manualSnapshot(actorId, snapshot, event) {
|
|
428
|
-
|
|
429
|
-
|
|
470
|
+
const sessionId = getManualSessionId(actorId);
|
|
471
|
+
if (!actors.has(sessionId)) manualRegister(actorId);
|
|
472
|
+
const entry = actors.get(sessionId);
|
|
430
473
|
const previousSnapshot = entry.snapshot;
|
|
431
474
|
const inspectedSnapshot = {
|
|
432
|
-
|
|
433
|
-
|
|
475
|
+
sessionId,
|
|
476
|
+
sourceSessionId: null,
|
|
434
477
|
previousSnapshot,
|
|
435
478
|
snapshot,
|
|
436
479
|
event: event ?? null,
|
|
@@ -441,11 +484,11 @@ function createInspector(options = {}) {
|
|
|
441
484
|
entry.snapshot = snapshot;
|
|
442
485
|
if (initSent) send({
|
|
443
486
|
type: "@statelyai.system.actorSnapshot",
|
|
444
|
-
|
|
487
|
+
sessionId,
|
|
445
488
|
previousSnapshot,
|
|
446
489
|
snapshot,
|
|
447
490
|
event: event ?? null,
|
|
448
|
-
|
|
491
|
+
sourceSessionId: null,
|
|
449
492
|
actions: [],
|
|
450
493
|
transitions: [],
|
|
451
494
|
sent: []
|
|
@@ -455,18 +498,20 @@ function createInspector(options = {}) {
|
|
|
455
498
|
}
|
|
456
499
|
function manualEvent(actorId, event, eventOpts) {
|
|
457
500
|
const eventObj = typeof event === "string" ? { type: event } : { ...event };
|
|
458
|
-
|
|
459
|
-
|
|
501
|
+
const sessionId = getManualSessionId(actorId);
|
|
502
|
+
if (!actors.has(sessionId)) manualRegister(actorId);
|
|
503
|
+
handleEvent(sessionId, eventObj, eventOpts?.source ? getManualSessionId(eventOpts.source) : null);
|
|
460
504
|
}
|
|
461
505
|
function manualStop(actorId) {
|
|
462
|
-
const
|
|
506
|
+
const sessionId = getManualSessionId(actorId);
|
|
507
|
+
const entry = actors.get(sessionId);
|
|
463
508
|
if (!entry || entry.stopped) return;
|
|
464
509
|
entry.stopped = true;
|
|
465
510
|
if (initSent) send({
|
|
466
511
|
type: "@statelyai.system.actorStopped",
|
|
467
|
-
|
|
512
|
+
sessionId
|
|
468
513
|
});
|
|
469
|
-
const stopped = {
|
|
514
|
+
const stopped = { sessionId };
|
|
470
515
|
emitLocal("stop", stopped);
|
|
471
516
|
emitLocal("stopped", stopped);
|
|
472
517
|
}
|
|
@@ -477,9 +522,14 @@ function createInspector(options = {}) {
|
|
|
477
522
|
}
|
|
478
523
|
return {
|
|
479
524
|
actors,
|
|
525
|
+
roomId,
|
|
526
|
+
relayUrl,
|
|
527
|
+
producerId,
|
|
480
528
|
get sessionId() {
|
|
481
|
-
return
|
|
529
|
+
return roomId;
|
|
482
530
|
},
|
|
531
|
+
inspectorUrl,
|
|
532
|
+
ready,
|
|
483
533
|
inspect: handleInspectionEvent,
|
|
484
534
|
attach: attachActor,
|
|
485
535
|
on(event, handler) {
|
package/dist/inspect.d.mts
CHANGED
|
@@ -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,
|
|
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-BScvqVcM.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
|
@@ -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 };
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { getInspectionRoomId } from "./protocol.mjs";
|
|
2
|
+
import { createInspectionRelay } from "./relay.mjs";
|
|
3
|
+
import { createServer } from "node:http";
|
|
4
|
+
import { randomUUID } from "node:crypto";
|
|
5
|
+
import { WebSocket, WebSocketServer } from "ws";
|
|
6
|
+
|
|
7
|
+
//#region src/node-relay.ts
|
|
8
|
+
/** Local/self-hosted Node adapter for the room inspection relay. */
|
|
9
|
+
var NodeInspectionRelayServer = class {
|
|
10
|
+
server = null;
|
|
11
|
+
webSocketServer = null;
|
|
12
|
+
rooms = /* @__PURE__ */ new Map();
|
|
13
|
+
connections = /* @__PURE__ */ new Map();
|
|
14
|
+
sockets = /* @__PURE__ */ new Map();
|
|
15
|
+
constructor(options = {}) {
|
|
16
|
+
this.options = options;
|
|
17
|
+
}
|
|
18
|
+
get url() {
|
|
19
|
+
if (!this.server) throw new Error("Inspection relay is not running.");
|
|
20
|
+
const address = this.server.address();
|
|
21
|
+
if (!address || typeof address === "string") throw new Error("Inspection relay address is unavailable.");
|
|
22
|
+
return `ws://${this.options.host ?? "127.0.0.1"}:${address.port}`;
|
|
23
|
+
}
|
|
24
|
+
async start() {
|
|
25
|
+
if (this.server) return;
|
|
26
|
+
this.server = createServer();
|
|
27
|
+
this.webSocketServer = new WebSocketServer({ server: this.server });
|
|
28
|
+
this.webSocketServer.on("connection", (socket, request) => {
|
|
29
|
+
const roomId = getInspectionRoomId(new URL(request.url ?? "/", this.url));
|
|
30
|
+
if (!roomId) {
|
|
31
|
+
socket.close(1008, "Missing ?r=<roomId>");
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
const relay = this.rooms.get(roomId) ?? createInspectionRelay();
|
|
35
|
+
this.rooms.set(roomId, relay);
|
|
36
|
+
const peerId = randomUUID();
|
|
37
|
+
this.connections.set(socket, {
|
|
38
|
+
peerId,
|
|
39
|
+
relay
|
|
40
|
+
});
|
|
41
|
+
this.sockets.set(peerId, socket);
|
|
42
|
+
socket.on("message", (raw) => {
|
|
43
|
+
for (const effect of relay.receive(peerId, raw.toString())) {
|
|
44
|
+
const target = this.sockets.get(effect.peerId);
|
|
45
|
+
if (target?.readyState === WebSocket.OPEN) target.send(JSON.stringify(effect.message));
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
socket.on("close", () => {
|
|
49
|
+
relay.disconnect(peerId);
|
|
50
|
+
this.connections.delete(socket);
|
|
51
|
+
this.sockets.delete(peerId);
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
await new Promise((resolve, reject) => {
|
|
55
|
+
this.server.once("error", reject);
|
|
56
|
+
this.server.listen(this.options.port ?? 4242, this.options.host ?? "127.0.0.1", () => {
|
|
57
|
+
this.server.off("error", reject);
|
|
58
|
+
resolve();
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
this.options.logger?.info(`Inspection relay listening on ${this.url}`);
|
|
62
|
+
}
|
|
63
|
+
async stop() {
|
|
64
|
+
for (const socket of this.connections.keys()) socket.close();
|
|
65
|
+
this.connections.clear();
|
|
66
|
+
this.sockets.clear();
|
|
67
|
+
for (const relay of this.rooms.values()) relay.clear();
|
|
68
|
+
this.rooms.clear();
|
|
69
|
+
if (this.webSocketServer) {
|
|
70
|
+
await new Promise((resolve) => this.webSocketServer.close(() => resolve()));
|
|
71
|
+
this.webSocketServer = null;
|
|
72
|
+
}
|
|
73
|
+
if (this.server) {
|
|
74
|
+
await new Promise((resolve, reject) => this.server.close((error) => error ? reject(error) : resolve()));
|
|
75
|
+
this.server = null;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
function createNodeInspectionRelay(options) {
|
|
80
|
+
return new NodeInspectionRelayServer(options);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
//#endregion
|
|
84
|
+
export { NodeInspectionRelayServer, createNodeInspectionRelay };
|