@statelyai/sdk 0.15.0 → 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.
- package/README.md +33 -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 +5 -5
- package/dist/{inspect-DWDTNMEc.mjs → inspect-BwVdM4R8.mjs} +109 -72
- package/dist/{inspect-DenVP7IE.d.mts → inspect-CduY_2Fa.d.mts} +54 -59
- 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 +101 -114
- package/dist/protocol.mjs +33 -2
- package/dist/relay.d.mts +10 -11
- package/dist/relay.mjs +83 -62
- package/dist/{statelyPragma-Bm9O4XV6.mjs → statelyPragma-Th0gdXfx.mjs} +0 -1
- package/dist/studio.d.mts +1 -1
- package/dist/sync.d.mts +1 -1
- package/dist/sync.mjs +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,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: '
|
|
21
|
-
|
|
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.
|
|
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
|
-
|
|
100
|
-
/** Root actor's sessionId
|
|
101
|
-
|
|
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
|
-
|
|
116
|
-
|
|
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
|
-
|
|
131
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
/**
|
|
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
|
-
*
|
|
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.
|
|
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
|
|
201
|
-
*
|
|
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 `
|
|
192
|
+
/** Snapshot of currently-adopted actors keyed by global `sessionId`. */
|
|
208
193
|
readonly actors: ReadonlyMap<string, AdoptedActor>;
|
|
209
|
-
/**
|
|
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 {
|
|
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 };
|
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-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
|
@@ -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 };
|