@statelyai/sdk 0.12.3 → 0.13.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 +42 -12
- package/dist/auth.d.mts +1 -1
- package/dist/embed.mjs +1 -1
- package/dist/{graph-Dq5ycdSq.d.mts → graph-R0sbxnZ7.d.mts} +1 -1
- package/dist/graph.d.mts +1 -1
- package/dist/index.d.mts +7 -6
- package/dist/index.mjs +6 -4
- package/dist/{inspect-BmZUcnZB.d.mts → inspect-COqtklcn.d.mts} +88 -6
- package/dist/inspect-pcNCbL7j.mjs +469 -0
- package/dist/inspect.d.mts +3 -3
- package/dist/inspect.mjs +2 -305
- package/dist/patchTypes.d.mts +1 -1
- package/dist/protocol.d.mts +35 -6
- package/dist/protocol.mjs +3 -1
- package/dist/relay.d.mts +43 -0
- package/dist/relay.mjs +153 -0
- package/dist/studio.d.mts +1 -1
- package/dist/sync.d.mts +1 -1
- package/dist/sync.mjs +1 -1
- package/dist/{transport-DysvAtl5.mjs → transport-D2Ud05yg.mjs} +178 -2
- package/package.json +6 -1
- /package/dist/{auth-DO1-eQcU.d.mts → auth-DmPZiERd.d.mts} +0 -0
- /package/dist/{dist-C-AdA8Iw.mjs → dist-CHGcvOdQ.mjs} +0 -0
- /package/dist/{index-BRW2DecD.d.mts → index-DVjNSTuQ.d.mts} +0 -0
package/dist/inspect.mjs
CHANGED
|
@@ -1,306 +1,3 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { n as createStatelyInspector, t as createInspector } from "./inspect-pcNCbL7j.mjs";
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
const defaultSerializeSnapshot = (snapshot) => ({
|
|
5
|
-
value: snapshot?.value,
|
|
6
|
-
status: snapshot?.status
|
|
7
|
-
});
|
|
8
|
-
const defaultExtractMachineConfig = (actor) => actor?.logic?.config ?? null;
|
|
9
|
-
let nextManualId = 0;
|
|
10
|
-
function generateSessionId() {
|
|
11
|
-
return `manual-${Date.now()}-${nextManualId++}`;
|
|
12
|
-
}
|
|
13
|
-
function createStatelyInspector(options = {}) {
|
|
14
|
-
const { url = "ws://localhost:4242", autoOpen = true, name, serializeSnapshot = defaultSerializeSnapshot, extractMachineConfig = defaultExtractMachineConfig, selectedActorId, panels, theme, readOnly, depth, capabilities, transport: injectedTransport } = options;
|
|
15
|
-
const sessionId = options.sessionId ?? generateSessionId();
|
|
16
|
-
const displayName = name ?? "system:manual";
|
|
17
|
-
let destroyed = false;
|
|
18
|
-
let initSent = false;
|
|
19
|
-
const pendingMessages = [];
|
|
20
|
-
const events = createEventRegistry();
|
|
21
|
-
const localListeners = {};
|
|
22
|
-
const transport = injectedTransport ?? createWebSocketTransport({
|
|
23
|
-
url,
|
|
24
|
-
role: "client",
|
|
25
|
-
sessionId,
|
|
26
|
-
metadata: { name: displayName }
|
|
27
|
-
});
|
|
28
|
-
const ownsTransport = !injectedTransport;
|
|
29
|
-
const exportManager = createPendingExportManager((message) => send(message));
|
|
30
|
-
function send(msg) {
|
|
31
|
-
if (!transport.ready) {
|
|
32
|
-
pendingMessages.push(msg);
|
|
33
|
-
return;
|
|
34
|
-
}
|
|
35
|
-
transport.send(msg);
|
|
36
|
-
}
|
|
37
|
-
transport.onReady(() => {
|
|
38
|
-
pendingMessages.length = 0;
|
|
39
|
-
initSent = false;
|
|
40
|
-
sendInit();
|
|
41
|
-
if (autoOpen) transport.send({
|
|
42
|
-
type: "@statelyai.requestOpen",
|
|
43
|
-
sessionId
|
|
44
|
-
});
|
|
45
|
-
});
|
|
46
|
-
transport.onMessage((msg) => {
|
|
47
|
-
if (destroyed) return;
|
|
48
|
-
switch (msg.type) {
|
|
49
|
-
case "@statelyai.retrieved":
|
|
50
|
-
exportManager.resolve(msg.requestId, msg.data);
|
|
51
|
-
break;
|
|
52
|
-
case "@statelyai.error":
|
|
53
|
-
exportManager.reject(new Error(msg.message), msg.requestId);
|
|
54
|
-
emitLocal("error", {
|
|
55
|
-
code: msg.code,
|
|
56
|
-
message: msg.message
|
|
57
|
-
});
|
|
58
|
-
events.emit("error", {
|
|
59
|
-
code: msg.code,
|
|
60
|
-
message: msg.message
|
|
61
|
-
});
|
|
62
|
-
break;
|
|
63
|
-
default: break;
|
|
64
|
-
}
|
|
65
|
-
});
|
|
66
|
-
function emitLocal(event, data) {
|
|
67
|
-
const set = localListeners[event];
|
|
68
|
-
if (!set) return;
|
|
69
|
-
for (const handler of set) handler(data);
|
|
70
|
-
}
|
|
71
|
-
const actors = /* @__PURE__ */ new Map();
|
|
72
|
-
/** Tracks which actors we've already emitted local 'register' events for. */
|
|
73
|
-
const locallyRegistered = /* @__PURE__ */ new Set();
|
|
74
|
-
/**
|
|
75
|
-
* Maps target actorId → source actorId for the most recent `@xstate.event`.
|
|
76
|
-
* Read + cleared by `handleSnapshot` so the source info propagates into the
|
|
77
|
-
* `actorSnapshot` message. xstate emits `@xstate.event` immediately before
|
|
78
|
-
* `@xstate.snapshot` for the same actor.
|
|
79
|
-
*/
|
|
80
|
-
const pendingEventSource = /* @__PURE__ */ new Map();
|
|
81
|
-
function emitRegisterOnce(entry) {
|
|
82
|
-
if (locallyRegistered.has(entry.actorId)) return;
|
|
83
|
-
locallyRegistered.add(entry.actorId);
|
|
84
|
-
emitLocal("register", entry);
|
|
85
|
-
}
|
|
86
|
-
function snapshotValue(actorRef) {
|
|
87
|
-
try {
|
|
88
|
-
return serializeSnapshot(actorRef.getSnapshot());
|
|
89
|
-
} catch {
|
|
90
|
-
return null;
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
function toEntry(actorRef, rootActorId) {
|
|
94
|
-
return {
|
|
95
|
-
actorId: actorRef.sessionId,
|
|
96
|
-
parentActorId: actorRef._parent?.sessionId ?? null,
|
|
97
|
-
rootId: rootActorId,
|
|
98
|
-
id: actorRef.id,
|
|
99
|
-
systemId: actorRef.systemId,
|
|
100
|
-
snapshot: snapshotValue(actorRef),
|
|
101
|
-
machineConfig: extractMachineConfig(actorRef)
|
|
102
|
-
};
|
|
103
|
-
}
|
|
104
|
-
function toSystemEntry(entry) {
|
|
105
|
-
return {
|
|
106
|
-
actorId: entry.actorId,
|
|
107
|
-
parentActorId: entry.parentActorId,
|
|
108
|
-
id: entry.id,
|
|
109
|
-
machine: entry.machineConfig,
|
|
110
|
-
snapshot: entry.snapshot ?? void 0
|
|
111
|
-
};
|
|
112
|
-
}
|
|
113
|
-
/**
|
|
114
|
-
* Walk the actor tree and populate the local `actors` map. Idempotent —
|
|
115
|
-
* existing entries stay in place but have their snapshot refreshed.
|
|
116
|
-
*/
|
|
117
|
-
function backfillActorTree(actorRef, rootActorId) {
|
|
118
|
-
const existing = actors.get(actorRef.sessionId);
|
|
119
|
-
const entry = existing ?? toEntry(actorRef, rootActorId);
|
|
120
|
-
if (existing) existing.snapshot = snapshotValue(actorRef);
|
|
121
|
-
else actors.set(entry.actorId, entry);
|
|
122
|
-
emitRegisterOnce(entry);
|
|
123
|
-
const children = actorRef.getSnapshot()?.children ?? {};
|
|
124
|
-
for (const child of Object.values(children)) if (child) backfillActorTree(child, rootActorId);
|
|
125
|
-
}
|
|
126
|
-
const inspectedRoots = /* @__PURE__ */ new Map();
|
|
127
|
-
function sendInit() {
|
|
128
|
-
for (const [rootActorId, { actor }] of inspectedRoots) backfillActorTree(actor, rootActorId);
|
|
129
|
-
send({
|
|
130
|
-
type: "@statelyai.system.init",
|
|
131
|
-
mode: "inspecting",
|
|
132
|
-
actors: Array.from(actors.values()).map(toSystemEntry),
|
|
133
|
-
selectedActorId: selectedActorId ?? inspectedRoots.keys().next().value ?? sessionId,
|
|
134
|
-
...theme && { theme },
|
|
135
|
-
...readOnly !== void 0 && { readOnly },
|
|
136
|
-
...depth !== void 0 && { depth },
|
|
137
|
-
...capabilities !== void 0 && { capabilities },
|
|
138
|
-
...panels?.leftPanels && { leftPanels: panels.leftPanels },
|
|
139
|
-
...panels?.rightPanels && { rightPanels: panels.rightPanels },
|
|
140
|
-
...panels?.activePanels && { activePanels: panels.activePanels }
|
|
141
|
-
});
|
|
142
|
-
initSent = true;
|
|
143
|
-
}
|
|
144
|
-
function handleActor(actorRef, rootActorId) {
|
|
145
|
-
if (actors.has(actorRef.sessionId)) return;
|
|
146
|
-
const entry = toEntry(actorRef, rootActorId);
|
|
147
|
-
actors.set(entry.actorId, entry);
|
|
148
|
-
if (!initSent) return;
|
|
149
|
-
send({
|
|
150
|
-
type: "@statelyai.system.actorRegistered",
|
|
151
|
-
actorId: entry.actorId,
|
|
152
|
-
parentActorId: entry.parentActorId,
|
|
153
|
-
id: entry.id,
|
|
154
|
-
machine: entry.machineConfig,
|
|
155
|
-
snapshot: entry.snapshot ?? void 0
|
|
156
|
-
});
|
|
157
|
-
emitRegisterOnce(entry);
|
|
158
|
-
}
|
|
159
|
-
function handleSnapshot(actorRef, snapshot, triggeringEvent, rootActorId) {
|
|
160
|
-
if (!actors.has(actorRef.sessionId)) handleActor(actorRef, rootActorId);
|
|
161
|
-
const entry = actors.get(actorRef.sessionId);
|
|
162
|
-
if (!entry) return;
|
|
163
|
-
const serialized = serializeSnapshot(snapshot);
|
|
164
|
-
entry.snapshot = serialized;
|
|
165
|
-
const sourceActorId = pendingEventSource.get(entry.actorId) ?? null;
|
|
166
|
-
pendingEventSource.delete(entry.actorId);
|
|
167
|
-
if (initSent) send({
|
|
168
|
-
type: "@statelyai.system.actorSnapshot",
|
|
169
|
-
actorId: entry.actorId,
|
|
170
|
-
snapshot: serialized,
|
|
171
|
-
event: triggeringEvent ?? null,
|
|
172
|
-
...sourceActorId ? { sourceActorId } : {}
|
|
173
|
-
});
|
|
174
|
-
emitLocal("snapshot", entry);
|
|
175
|
-
const status = snapshot?.status;
|
|
176
|
-
if (status === "done" || status === "stopped" || status === "error") {
|
|
177
|
-
actors.delete(entry.actorId);
|
|
178
|
-
pendingEventSource.delete(entry.actorId);
|
|
179
|
-
if (initSent) send({
|
|
180
|
-
type: "@statelyai.system.actorStopped",
|
|
181
|
-
actorId: entry.actorId
|
|
182
|
-
});
|
|
183
|
-
emitLocal("stopped", { actorId: entry.actorId });
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
function inspectActor(actor) {
|
|
187
|
-
const root = actor;
|
|
188
|
-
const rootActorId = root.sessionId;
|
|
189
|
-
const existing = inspectedRoots.get(rootActorId);
|
|
190
|
-
if (existing) return existing.subscription;
|
|
191
|
-
const subscription = root.system.inspect((inspectionEvent) => {
|
|
192
|
-
if (destroyed) return;
|
|
193
|
-
switch (inspectionEvent.type) {
|
|
194
|
-
case "@xstate.actor":
|
|
195
|
-
handleActor(inspectionEvent.actorRef, rootActorId);
|
|
196
|
-
break;
|
|
197
|
-
case "@xstate.event":
|
|
198
|
-
if (inspectionEvent.sourceRef) pendingEventSource.set(inspectionEvent.actorRef.sessionId, inspectionEvent.sourceRef.sessionId);
|
|
199
|
-
break;
|
|
200
|
-
case "@xstate.snapshot":
|
|
201
|
-
handleSnapshot(inspectionEvent.actorRef, inspectionEvent.snapshot, inspectionEvent.event, rootActorId);
|
|
202
|
-
break;
|
|
203
|
-
default: break;
|
|
204
|
-
}
|
|
205
|
-
});
|
|
206
|
-
inspectedRoots.set(rootActorId, {
|
|
207
|
-
actor: root,
|
|
208
|
-
subscription
|
|
209
|
-
});
|
|
210
|
-
backfillActorTree(root, rootActorId);
|
|
211
|
-
if (initSent) sendInit();
|
|
212
|
-
return { unsubscribe() {
|
|
213
|
-
subscription.unsubscribe();
|
|
214
|
-
inspectedRoots.delete(rootActorId);
|
|
215
|
-
} };
|
|
216
|
-
}
|
|
217
|
-
function manualRegister(id, opts) {
|
|
218
|
-
if (actors.has(id)) return;
|
|
219
|
-
const entry = {
|
|
220
|
-
actorId: id,
|
|
221
|
-
parentActorId: opts?.parent ?? null,
|
|
222
|
-
rootId: sessionId,
|
|
223
|
-
id,
|
|
224
|
-
systemId: opts?.systemId,
|
|
225
|
-
snapshot: opts?.snapshot ?? null,
|
|
226
|
-
machineConfig: opts?.machine ?? null
|
|
227
|
-
};
|
|
228
|
-
actors.set(id, entry);
|
|
229
|
-
if (initSent) send({
|
|
230
|
-
type: "@statelyai.system.actorRegistered",
|
|
231
|
-
actorId: id,
|
|
232
|
-
parentActorId: entry.parentActorId,
|
|
233
|
-
id,
|
|
234
|
-
machine: entry.machineConfig,
|
|
235
|
-
snapshot: entry.snapshot ?? void 0
|
|
236
|
-
});
|
|
237
|
-
emitRegisterOnce(entry);
|
|
238
|
-
}
|
|
239
|
-
function manualSnapshot(actorId, snapshot, event, sourceActorId) {
|
|
240
|
-
if (!actors.has(actorId)) manualRegister(actorId);
|
|
241
|
-
const entry = actors.get(actorId);
|
|
242
|
-
entry.snapshot = snapshot;
|
|
243
|
-
if (initSent) send({
|
|
244
|
-
type: "@statelyai.system.actorSnapshot",
|
|
245
|
-
actorId,
|
|
246
|
-
snapshot,
|
|
247
|
-
event: event ?? null,
|
|
248
|
-
...sourceActorId ? { sourceActorId } : {}
|
|
249
|
-
});
|
|
250
|
-
emitLocal("snapshot", entry);
|
|
251
|
-
}
|
|
252
|
-
function manualEvent(actorId, event, eventOpts) {
|
|
253
|
-
const eventObj = typeof event === "string" ? { type: event } : { ...event };
|
|
254
|
-
manualSnapshot(actorId, actors.get(actorId)?.snapshot ?? null, eventObj, eventOpts?.source ?? null);
|
|
255
|
-
}
|
|
256
|
-
function manualStop(actorId) {
|
|
257
|
-
if (!actors.has(actorId)) return;
|
|
258
|
-
actors.delete(actorId);
|
|
259
|
-
if (initSent) send({
|
|
260
|
-
type: "@statelyai.system.actorStopped",
|
|
261
|
-
actorId
|
|
262
|
-
});
|
|
263
|
-
emitLocal("stopped", { actorId });
|
|
264
|
-
}
|
|
265
|
-
return {
|
|
266
|
-
actors,
|
|
267
|
-
get sessionId() {
|
|
268
|
-
return sessionId;
|
|
269
|
-
},
|
|
270
|
-
inspect: inspectActor,
|
|
271
|
-
on(event, handler) {
|
|
272
|
-
if (!localListeners[event]) localListeners[event] = /* @__PURE__ */ new Set();
|
|
273
|
-
localListeners[event].add(handler);
|
|
274
|
-
return () => {
|
|
275
|
-
localListeners[event].delete(handler);
|
|
276
|
-
};
|
|
277
|
-
},
|
|
278
|
-
off(event, handler) {
|
|
279
|
-
localListeners[event]?.delete(handler);
|
|
280
|
-
},
|
|
281
|
-
export(format, callOptions) {
|
|
282
|
-
return exportManager.start(format, callOptions, "Inspector is destroyed", () => destroyed);
|
|
283
|
-
},
|
|
284
|
-
actor: manualRegister,
|
|
285
|
-
snapshot: manualSnapshot,
|
|
286
|
-
event: manualEvent,
|
|
287
|
-
stop: manualStop,
|
|
288
|
-
destroy() {
|
|
289
|
-
if (destroyed) return;
|
|
290
|
-
destroyed = true;
|
|
291
|
-
try {
|
|
292
|
-
for (const { subscription } of inspectedRoots.values()) subscription.unsubscribe();
|
|
293
|
-
} catch {}
|
|
294
|
-
if (ownsTransport) transport.destroy();
|
|
295
|
-
exportManager.clear("Inspector destroyed");
|
|
296
|
-
events.clear();
|
|
297
|
-
actors.clear();
|
|
298
|
-
inspectedRoots.clear();
|
|
299
|
-
pendingMessages.length = 0;
|
|
300
|
-
for (const set of Object.values(localListeners)) set?.clear();
|
|
301
|
-
}
|
|
302
|
-
};
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
//#endregion
|
|
306
|
-
export { createStatelyInspector };
|
|
3
|
+
export { createInspector, createStatelyInspector };
|
package/dist/patchTypes.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as EditorStateType, n as CanvasColor, o as GraphPatch, s as ImplementationSourceType, t as ActionLocation } from "./index-
|
|
1
|
+
import { a as EditorStateType, n as CanvasColor, o as GraphPatch, s as ImplementationSourceType, t as ActionLocation } from "./index-DVjNSTuQ.mjs";
|
|
2
2
|
export { type ActionLocation, type CanvasColor, type EditorStateType, type GraphPatch, type ImplementationSourceType };
|
package/dist/protocol.d.mts
CHANGED
|
@@ -338,8 +338,29 @@ interface ActorSystemEntry {
|
|
|
338
338
|
/** Optional current snapshot (`{value, status, ...}`). */
|
|
339
339
|
snapshot?: unknown;
|
|
340
340
|
}
|
|
341
|
+
/** JSON-safe record of an action executed during an inspected transition. */
|
|
342
|
+
interface InspectionAction {
|
|
343
|
+
type: string;
|
|
344
|
+
params?: unknown;
|
|
345
|
+
}
|
|
346
|
+
/** JSON-safe identity of a state transition taken during a macrostep. */
|
|
347
|
+
interface InspectionTakenTransition {
|
|
348
|
+
sourceStateId: string | null;
|
|
349
|
+
targetStateIds: string[];
|
|
350
|
+
eventType?: string;
|
|
351
|
+
reenter?: boolean;
|
|
352
|
+
}
|
|
353
|
+
/** JSON-safe record of an event sent or scheduled during a transition. */
|
|
354
|
+
interface InspectionSentEvent {
|
|
355
|
+
targetActorId?: string;
|
|
356
|
+
targetId: string;
|
|
357
|
+
event: unknown;
|
|
358
|
+
delay?: number;
|
|
359
|
+
id?: string;
|
|
360
|
+
}
|
|
341
361
|
interface SystemInitMessage {
|
|
342
362
|
type: "@statelyai.system.init";
|
|
363
|
+
protocolVersion?: number;
|
|
343
364
|
/** All known actors at the moment the system is first streamed. */
|
|
344
365
|
actors: ActorSystemEntry[];
|
|
345
366
|
/** Actor id the viz should focus first. Defaults to the root. */
|
|
@@ -367,10 +388,18 @@ interface SystemActorRegisteredMessage {
|
|
|
367
388
|
interface SystemActorSnapshotMessage {
|
|
368
389
|
type: "@statelyai.system.actorSnapshot";
|
|
369
390
|
actorId: string;
|
|
391
|
+
/** Snapshot before the event was processed. */
|
|
392
|
+
previousSnapshot?: unknown | null;
|
|
370
393
|
snapshot: unknown;
|
|
371
394
|
event?: unknown | null;
|
|
372
395
|
/** The actorId of the actor that sent the triggering event, if known. */
|
|
373
396
|
sourceActorId?: string | null;
|
|
397
|
+
/** Actions executed while processing the event. */
|
|
398
|
+
actions?: InspectionAction[];
|
|
399
|
+
/** State transitions taken across every microstep. */
|
|
400
|
+
transitions?: InspectionTakenTransition[];
|
|
401
|
+
/** Events sent or scheduled while processing the event. */
|
|
402
|
+
sent?: InspectionSentEvent[];
|
|
374
403
|
}
|
|
375
404
|
/** An actor reached a final state / was stopped. */
|
|
376
405
|
interface SystemActorStoppedMessage {
|
|
@@ -468,6 +497,7 @@ type ClientMessage = InitMessage | SetApiKeyMessage | ProjectInitMessage | Proje
|
|
|
468
497
|
type VizMessage = ReadyMessage | LoadedMessage | ChangeMessage | SaveMessage | ProjectMachineSelectedMessage | RetrievedMessage | ErrorMessage | CapabilityDeniedMessage | UploadRequestMessage;
|
|
469
498
|
interface RegisterMessage {
|
|
470
499
|
type: "@statelyai.register";
|
|
500
|
+
protocolVersion?: number;
|
|
471
501
|
role: "client" | "viz";
|
|
472
502
|
sessionId: string;
|
|
473
503
|
metadata?: {
|
|
@@ -477,10 +507,7 @@ interface RegisterMessage {
|
|
|
477
507
|
}
|
|
478
508
|
interface RegisteredMessage {
|
|
479
509
|
type: "@statelyai.registered";
|
|
480
|
-
|
|
481
|
-
}
|
|
482
|
-
interface RequestOpenMessage {
|
|
483
|
-
type: "@statelyai.requestOpen";
|
|
510
|
+
protocolVersion?: number;
|
|
484
511
|
sessionId: string;
|
|
485
512
|
}
|
|
486
513
|
/**
|
|
@@ -508,9 +535,11 @@ interface SessionAddedMessage {
|
|
|
508
535
|
sessionId: string;
|
|
509
536
|
}
|
|
510
537
|
/** All session-management messages for the WS relay. */
|
|
511
|
-
type SessionMessage = RegisterMessage | RegisteredMessage |
|
|
538
|
+
type SessionMessage = RegisterMessage | RegisteredMessage | AddSessionMessage | SessionAddedMessage;
|
|
512
539
|
/** Any valid protocol message. */
|
|
513
540
|
type ProtocolMessage = ClientMessage | VizMessage | SessionMessage;
|
|
514
541
|
declare const PREFIX = "@statelyai.";
|
|
542
|
+
/** Current WebSocket inspection protocol version. */
|
|
543
|
+
declare const INSPECTION_PROTOCOL_VERSION = 1;
|
|
515
544
|
//#endregion
|
|
516
|
-
export { ActorSystemEntry, AddSessionMessage, CapabilityDeniedCapability, CapabilityDeniedEvent, CapabilityDeniedMessage, ChangeMessage, ClientMessage, CommentsConfig, EditorCapabilities, EmbedEventHandler, EmbedEventMap, EmbedEventName, EmbedMode, ErrorMessage, ExportCallOptions, ExportFormat, ExportFormatMap, InitMessage, InitOptions, InspectSnapshotMessage, LoadedMessage, MachineInitOptions, MachineSourceLocations, PREFIX, ProjectEmbedMachine, ProjectInitMessage, ProjectInitOptions, ProjectMachineSelectedMessage, ProjectSelectMachineMessage, ProjectUpdateMessage, ProtocolMessage, ReadOnlyReason, ReadyMessage, RegisterMessage, RegisteredMessage,
|
|
545
|
+
export { ActorSystemEntry, AddSessionMessage, CapabilityDeniedCapability, CapabilityDeniedEvent, CapabilityDeniedMessage, ChangeMessage, ClientMessage, CommentsConfig, EditorCapabilities, EmbedEventHandler, EmbedEventMap, EmbedEventName, EmbedMode, ErrorMessage, ExportCallOptions, ExportFormat, ExportFormatMap, INSPECTION_PROTOCOL_VERSION, InitMessage, InitOptions, InspectSnapshotMessage, InspectionAction, InspectionSentEvent, InspectionTakenTransition, LoadedMessage, MachineInitOptions, MachineSourceLocations, PREFIX, ProjectEmbedMachine, ProjectInitMessage, ProjectInitOptions, ProjectMachineSelectedMessage, ProjectSelectMachineMessage, ProjectUpdateMessage, ProtocolMessage, ReadOnlyReason, ReadyMessage, RegisterMessage, RegisteredMessage, RetrieveMessage, RetrievedMessage, SaveMessage, SessionAddedMessage, SessionMessage, SetApiKeyMessage, SetModeMessage, SetSettingsMessage, SetThemeMessage, SourceLocation, SourceRange, StateSourceLocation, SystemActorRegisteredMessage, SystemActorSnapshotMessage, SystemActorStoppedMessage, SystemInitMessage, ToastMessage, UpdateMessage, UploadCapabilitiesMessage, UploadFileInfo, UploadRequestMessage, UploadResponseMessage, UploadResult, ValidationIssue, VizMessage };
|
package/dist/protocol.mjs
CHANGED
package/dist/relay.d.mts
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { ProtocolMessage } from "./protocol.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/relay.d.ts
|
|
4
|
+
type InspectionRelayRole = 'client' | 'viz';
|
|
5
|
+
interface InspectionRelayPeer {
|
|
6
|
+
id: string;
|
|
7
|
+
role: InspectionRelayRole;
|
|
8
|
+
primarySessionId: string;
|
|
9
|
+
sessionIds: string[];
|
|
10
|
+
}
|
|
11
|
+
interface InspectionRelaySnapshot {
|
|
12
|
+
sessions: Record<string, ProtocolMessage[]>;
|
|
13
|
+
}
|
|
14
|
+
type InspectionRelayEffect = {
|
|
15
|
+
type: 'send';
|
|
16
|
+
peerId: string;
|
|
17
|
+
message: ProtocolMessage;
|
|
18
|
+
};
|
|
19
|
+
interface InspectionRelay {
|
|
20
|
+
/** Restore a live peer after process/DO hibernation. */
|
|
21
|
+
connect(peer: InspectionRelayPeer): void;
|
|
22
|
+
disconnect(peerId: string): void;
|
|
23
|
+
clear(): void;
|
|
24
|
+
peer(peerId: string): InspectionRelayPeer | undefined;
|
|
25
|
+
receive(peerId: string, raw: unknown): InspectionRelayEffect[];
|
|
26
|
+
snapshot(): InspectionRelaySnapshot;
|
|
27
|
+
}
|
|
28
|
+
interface CreateInspectionRelayOptions {
|
|
29
|
+
snapshot?: InspectionRelaySnapshot;
|
|
30
|
+
maxReplayMessages?: number;
|
|
31
|
+
/** Maximum sessions retained for late-join replay. Default 100. */
|
|
32
|
+
maxReplaySessions?: number;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Runtime-neutral WebSocket inspection room.
|
|
36
|
+
*
|
|
37
|
+
* It owns protocol registration, routing, multiplexed session membership, and
|
|
38
|
+
* bounded late-join replay. Node and Durable Object adapters only translate
|
|
39
|
+
* `send` effects to their native WebSocket APIs and persist `snapshot()`.
|
|
40
|
+
*/
|
|
41
|
+
declare function createInspectionRelay(options?: CreateInspectionRelayOptions): InspectionRelay;
|
|
42
|
+
//#endregion
|
|
43
|
+
export { CreateInspectionRelayOptions, InspectionRelay, InspectionRelayEffect, InspectionRelayPeer, InspectionRelayRole, InspectionRelaySnapshot, createInspectionRelay };
|
package/dist/relay.mjs
ADDED
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import { INSPECTION_PROTOCOL_VERSION, PREFIX } from "./protocol.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/relay.ts
|
|
4
|
+
function parseMessage(raw) {
|
|
5
|
+
if (raw instanceof ArrayBuffer) raw = new TextDecoder().decode(raw);
|
|
6
|
+
if (typeof raw === "string") try {
|
|
7
|
+
raw = JSON.parse(raw);
|
|
8
|
+
} catch {
|
|
9
|
+
return null;
|
|
10
|
+
}
|
|
11
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw)) return null;
|
|
12
|
+
const message = raw;
|
|
13
|
+
return typeof message.type === "string" && message.type.startsWith(PREFIX) ? message : null;
|
|
14
|
+
}
|
|
15
|
+
function errorMessage(code, message) {
|
|
16
|
+
return {
|
|
17
|
+
type: "@statelyai.error",
|
|
18
|
+
code,
|
|
19
|
+
message
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
function compactReplay(replay, message, max) {
|
|
23
|
+
const record = message;
|
|
24
|
+
const type = record.type;
|
|
25
|
+
if (type === "@statelyai.system.init") for (let index = replay.length - 1; index >= 0; index--) {
|
|
26
|
+
const replayType = replay[index].type;
|
|
27
|
+
if (replayType === "@statelyai.system.init" || replayType.startsWith("@statelyai.system.actor")) replay.splice(index, 1);
|
|
28
|
+
}
|
|
29
|
+
else if (type === "@statelyai.init") {
|
|
30
|
+
const index = replay.findIndex((entry) => entry.type === "@statelyai.init");
|
|
31
|
+
if (index >= 0) replay.splice(index, 1);
|
|
32
|
+
} else if (type === "@statelyai.system.actorSnapshot" || type === "@statelyai.inspectSnapshot") {
|
|
33
|
+
const actorId = record.actorId;
|
|
34
|
+
const index = replay.findIndex((entry) => {
|
|
35
|
+
const candidate = entry;
|
|
36
|
+
return candidate.type === type && candidate.actorId === actorId;
|
|
37
|
+
});
|
|
38
|
+
if (index >= 0) replay.splice(index, 1);
|
|
39
|
+
}
|
|
40
|
+
replay.push(message);
|
|
41
|
+
if (replay.length > max) replay.splice(0, replay.length - max);
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Runtime-neutral WebSocket inspection room.
|
|
45
|
+
*
|
|
46
|
+
* It owns protocol registration, routing, multiplexed session membership, and
|
|
47
|
+
* bounded late-join replay. Node and Durable Object adapters only translate
|
|
48
|
+
* `send` effects to their native WebSocket APIs and persist `snapshot()`.
|
|
49
|
+
*/
|
|
50
|
+
function createInspectionRelay(options = {}) {
|
|
51
|
+
const maxReplayMessages = options.maxReplayMessages ?? 200;
|
|
52
|
+
const maxReplaySessions = Math.max(1, options.maxReplaySessions ?? 100);
|
|
53
|
+
const peers = /* @__PURE__ */ new Map();
|
|
54
|
+
const sessions = new Map(Object.entries(options.snapshot?.sessions ?? {}).slice(-maxReplaySessions).map(([id, replay]) => [id, [...replay]]));
|
|
55
|
+
const send = (peerId, message) => ({
|
|
56
|
+
type: "send",
|
|
57
|
+
peerId,
|
|
58
|
+
message
|
|
59
|
+
});
|
|
60
|
+
function replayTo(peerId, sessionId) {
|
|
61
|
+
return (sessions.get(sessionId) ?? []).map((message) => send(peerId, message));
|
|
62
|
+
}
|
|
63
|
+
function oppositePeers(sender, sessionId) {
|
|
64
|
+
return Array.from(peers.values()).filter((peer) => peer.id !== sender.id && peer.role !== sender.role && peer.sessionIds.includes(sessionId));
|
|
65
|
+
}
|
|
66
|
+
function retainReplay(sessionId, replay) {
|
|
67
|
+
sessions.delete(sessionId);
|
|
68
|
+
sessions.set(sessionId, replay);
|
|
69
|
+
while (sessions.size > maxReplaySessions) {
|
|
70
|
+
const oldestSessionId = sessions.keys().next().value;
|
|
71
|
+
if (oldestSessionId === void 0) break;
|
|
72
|
+
sessions.delete(oldestSessionId);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return {
|
|
76
|
+
connect(peer) {
|
|
77
|
+
peers.set(peer.id, {
|
|
78
|
+
...peer,
|
|
79
|
+
sessionIds: Array.from(new Set([peer.primarySessionId, ...peer.sessionIds]))
|
|
80
|
+
});
|
|
81
|
+
},
|
|
82
|
+
disconnect(peerId) {
|
|
83
|
+
peers.delete(peerId);
|
|
84
|
+
},
|
|
85
|
+
clear() {
|
|
86
|
+
peers.clear();
|
|
87
|
+
sessions.clear();
|
|
88
|
+
},
|
|
89
|
+
peer(peerId) {
|
|
90
|
+
const peer = peers.get(peerId);
|
|
91
|
+
return peer ? {
|
|
92
|
+
...peer,
|
|
93
|
+
sessionIds: [...peer.sessionIds]
|
|
94
|
+
} : void 0;
|
|
95
|
+
},
|
|
96
|
+
receive(peerId, raw) {
|
|
97
|
+
const message = parseMessage(raw);
|
|
98
|
+
if (!message) return [];
|
|
99
|
+
if (message.type === "@statelyai.register") {
|
|
100
|
+
const role = message.role;
|
|
101
|
+
const sessionId = message.sessionId;
|
|
102
|
+
const protocolVersion = message.protocolVersion;
|
|
103
|
+
if (role !== "client" && role !== "viz" || typeof sessionId !== "string" || sessionId.length === 0) return [send(peerId, errorMessage("invalid_registration", "Invalid relay registration"))];
|
|
104
|
+
if (typeof protocolVersion === "number" && protocolVersion > INSPECTION_PROTOCOL_VERSION) return [send(peerId, errorMessage("unsupported_protocol", `Protocol ${protocolVersion} is not supported`))];
|
|
105
|
+
const peer = {
|
|
106
|
+
id: peerId,
|
|
107
|
+
role,
|
|
108
|
+
primarySessionId: sessionId,
|
|
109
|
+
sessionIds: [sessionId]
|
|
110
|
+
};
|
|
111
|
+
peers.set(peerId, peer);
|
|
112
|
+
const effects = [send(peerId, {
|
|
113
|
+
type: "@statelyai.registered",
|
|
114
|
+
protocolVersion: INSPECTION_PROTOCOL_VERSION,
|
|
115
|
+
sessionId
|
|
116
|
+
})];
|
|
117
|
+
if (role === "viz") effects.push(...replayTo(peerId, sessionId));
|
|
118
|
+
return effects;
|
|
119
|
+
}
|
|
120
|
+
const sender = peers.get(peerId);
|
|
121
|
+
if (!sender) return [send(peerId, errorMessage("not_registered", "Register before sending messages"))];
|
|
122
|
+
if (message.type === "@statelyai.addSession") {
|
|
123
|
+
const sessionId = message.sessionId;
|
|
124
|
+
if (typeof sessionId !== "string" || sessionId.length === 0) return [send(peerId, errorMessage("invalid_session", "Invalid session id"))];
|
|
125
|
+
if (!sender.sessionIds.includes(sessionId)) sender.sessionIds.push(sessionId);
|
|
126
|
+
const effects = [send(peerId, {
|
|
127
|
+
type: "@statelyai.sessionAdded",
|
|
128
|
+
sessionId
|
|
129
|
+
})];
|
|
130
|
+
if (sender.role === "viz") effects.push(...replayTo(peerId, sessionId));
|
|
131
|
+
return effects;
|
|
132
|
+
}
|
|
133
|
+
const sessionId = (typeof message.sessionId === "string" ? message.sessionId : void 0) ?? sender.primarySessionId;
|
|
134
|
+
if (!sender.sessionIds.includes(sessionId)) return [send(peerId, errorMessage("unknown_session", "Peer is not registered for session"))];
|
|
135
|
+
const stamped = {
|
|
136
|
+
...message,
|
|
137
|
+
sessionId
|
|
138
|
+
};
|
|
139
|
+
if (sender.role === "client") {
|
|
140
|
+
const replay = sessions.get(sessionId) ?? [];
|
|
141
|
+
compactReplay(replay, stamped, maxReplayMessages);
|
|
142
|
+
retainReplay(sessionId, replay);
|
|
143
|
+
}
|
|
144
|
+
return oppositePeers(sender, sessionId).map((peer) => send(peer.id, stamped));
|
|
145
|
+
},
|
|
146
|
+
snapshot() {
|
|
147
|
+
return { sessions: Object.fromEntries(Array.from(sessions, ([sessionId, replay]) => [sessionId, [...replay]])) };
|
|
148
|
+
}
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
//#endregion
|
|
153
|
+
export { createInspectionRelay };
|
package/dist/studio.d.mts
CHANGED
package/dist/sync.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { b as DigraphConfig, i as StatelyGraph } from "./graph-
|
|
1
|
+
import { b as DigraphConfig, i as StatelyGraph } from "./graph-R0sbxnZ7.mjs";
|
|
2
2
|
import { CreateProjectInput, ProjectData, StudioClient, StudioMachineRecord, XStateVersion } from "./studio.mjs";
|
|
3
3
|
import { GraphDiff } from "@statelyai/graph";
|
|
4
4
|
|
package/dist/sync.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createStatelyClient } from "./studio.mjs";
|
|
2
|
-
import { d as xstateSourceToConfig, f as findStatelyPragmaAttachments, i as detectXStateSourceProfile, m as upsertStatelyPragma, p as getStatelyPragma, s as graphToXStateTS, t as INLINE_EXPRESSION_DIRECTIVE_FIELDS, u as serializeJS } from "./dist-
|
|
2
|
+
import { d as xstateSourceToConfig, f as findStatelyPragmaAttachments, i as detectXStateSourceProfile, m as upsertStatelyPragma, p as getStatelyPragma, s as graphToXStateTS, t as INLINE_EXPRESSION_DIRECTIVE_FIELDS, u as serializeJS } from "./dist-CHGcvOdQ.mjs";
|
|
3
3
|
import { fromStudioMachine, toStudioMachine } from "./graph.mjs";
|
|
4
4
|
import * as ts$1 from "typescript";
|
|
5
5
|
import ts from "typescript";
|