@statelyai/sdk 0.1.1 → 0.3.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/dist/graph.mjs ADDED
@@ -0,0 +1,344 @@
1
+ import { createFormatConverter, createGraph } from "@statelyai/graph";
2
+
3
+ //#region src/graph.ts
4
+ function toJsonObject(value) {
5
+ return value;
6
+ }
7
+ function toUnknownRecord(value) {
8
+ return value;
9
+ }
10
+ function normalizeStudioNodeType(type) {
11
+ return type === "annotation" ? void 0 : type;
12
+ }
13
+ function normalizeSchemas(schemas) {
14
+ if (!schemas) return;
15
+ return {
16
+ input: schemas.input ?? null,
17
+ output: schemas.output ?? null,
18
+ context: schemas.context ?? {},
19
+ events: schemas.events ?? {},
20
+ actions: schemas.actions ?? {},
21
+ guards: schemas.guards ?? {},
22
+ actors: schemas.actors ?? {},
23
+ tags: schemas.tags ?? {},
24
+ delays: schemas.delays ?? {}
25
+ };
26
+ }
27
+ function toCanvasColor(color) {
28
+ return color;
29
+ }
30
+ function normalizeStudioHistory(history) {
31
+ if (history === true) return "shallow";
32
+ return history || void 0;
33
+ }
34
+ function toActionSource(action) {
35
+ return {
36
+ type: "action",
37
+ id: action.id,
38
+ name: action.name,
39
+ ...action.description ? { description: action.description } : {},
40
+ ...action.icon ? { icon: action.icon } : {},
41
+ lang: action.code?.lang ?? "js",
42
+ imports: [],
43
+ code: action.code?.body,
44
+ ...action.paramsSchema ? { paramsSchema: action.paramsSchema } : {}
45
+ };
46
+ }
47
+ function toGuardSource(guard) {
48
+ return {
49
+ type: "guard",
50
+ id: guard.id,
51
+ name: guard.name,
52
+ ...guard.description ? { description: guard.description } : {},
53
+ ...guard.icon ? { icon: guard.icon } : {},
54
+ lang: guard.code?.lang ?? "js",
55
+ imports: [],
56
+ code: guard.code?.body,
57
+ ...guard.paramsSchema ? { paramsSchema: guard.paramsSchema } : {}
58
+ };
59
+ }
60
+ function toActorSource(actor) {
61
+ return {
62
+ type: "actor",
63
+ id: actor.id,
64
+ name: actor.name,
65
+ ...actor.description ? { description: actor.description } : {},
66
+ ...actor.icon ? { icon: actor.icon } : {},
67
+ lang: actor.code?.lang ?? "js",
68
+ imports: [],
69
+ code: actor.code?.body,
70
+ kind: "named",
71
+ ...actor.inputSchema ? { inputSchema: actor.inputSchema } : {},
72
+ ...actor.outputSchema ? { outputSchema: actor.outputSchema } : {}
73
+ };
74
+ }
75
+ function fromActionSource(action) {
76
+ return {
77
+ id: action.id,
78
+ name: action.name,
79
+ description: action.description ?? null,
80
+ ...action.icon ? { icon: action.icon } : {},
81
+ paramsSchema: action.paramsSchema ?? null,
82
+ ...action.code ? { code: {
83
+ body: action.code,
84
+ ...action.lang ? { lang: action.lang } : {}
85
+ } } : {}
86
+ };
87
+ }
88
+ function fromGuardSource(guard) {
89
+ return {
90
+ id: guard.id,
91
+ name: guard.name,
92
+ description: guard.description ?? null,
93
+ ...guard.icon ? { icon: guard.icon } : {},
94
+ paramsSchema: guard.paramsSchema ?? null,
95
+ ...guard.code ? { code: {
96
+ body: guard.code,
97
+ ...guard.lang ? { lang: guard.lang } : {}
98
+ } } : {}
99
+ };
100
+ }
101
+ function fromActorSource(actor) {
102
+ return {
103
+ id: actor.id,
104
+ name: actor.name,
105
+ description: actor.description ?? null,
106
+ ...actor.icon ? { icon: actor.icon } : {},
107
+ inputSchema: actor.inputSchema ?? null,
108
+ outputSchema: actor.outputSchema ?? null,
109
+ ...actor.code ? { code: {
110
+ body: actor.code,
111
+ ...actor.lang ? { lang: actor.lang } : {}
112
+ } } : {}
113
+ };
114
+ }
115
+ function toStudioAction(action) {
116
+ return {
117
+ kind: "named",
118
+ action: {
119
+ type: action.type,
120
+ ...action.params && Object.keys(action.params).length > 0 ? { params: toJsonObject(action.params) } : {}
121
+ }
122
+ };
123
+ }
124
+ function fromStudioAction(action) {
125
+ if (action.kind === "inline") return {
126
+ type: "inline",
127
+ params: { expr: action.action.expr }
128
+ };
129
+ if ("params" in action.action && action.action.params) return {
130
+ type: action.action.type,
131
+ params: toUnknownRecord(action.action.params)
132
+ };
133
+ return { type: action.action.type };
134
+ }
135
+ function toStudioEventTypeData(eventType) {
136
+ if (eventType === "") return { type: "always" };
137
+ if (eventType === "*") return { type: "wildcard" };
138
+ if (eventType.startsWith("xstate.after.")) return {
139
+ type: "after",
140
+ delay: eventType.slice(13).split(".")[0] ?? ""
141
+ };
142
+ return {
143
+ type: "named",
144
+ eventType
145
+ };
146
+ }
147
+ function fromStudioEventTypeData(eventTypeData) {
148
+ switch (eventTypeData.type) {
149
+ case "always": return "";
150
+ case "wildcard": return "*";
151
+ case "after": return `xstate.after.${eventTypeData.delay ?? ""}`;
152
+ case "named": return eventTypeData.eventType ?? "";
153
+ case "invocation.done": return `xstate.done.actor.${eventTypeData.invocationId}`;
154
+ case "invocation.error": return `xstate.error.actor.${eventTypeData.invocationId}`;
155
+ case "state.done": return "xstate.done.state";
156
+ case "init": return "xstate.init";
157
+ default: return "";
158
+ }
159
+ }
160
+ function toStudioNode(graph, nodeId, pathIds, parentPath) {
161
+ const node = graph.nodes.find((candidate) => candidate.id === nodeId);
162
+ if (!node) throw new Error(`Node not found: ${nodeId}`);
163
+ const pathId = parentPath ? `${parentPath}.${node.data.key}` : node.data.key;
164
+ pathIds.set(node.id, pathId);
165
+ const childNodes = graph.nodes.filter((candidate) => candidate.parentId === node.id).map((child) => toStudioNode(graph, child.id, pathIds, pathId));
166
+ const initialKey = node.data.initialId ? graph.nodes.find((candidate) => candidate.id === node.data.initialId)?.data.key : void 0;
167
+ return {
168
+ id: pathId,
169
+ ...node.x !== void 0 && node.y !== void 0 ? { position: {
170
+ x: node.x,
171
+ y: node.y
172
+ } } : {},
173
+ ...node.width !== void 0 && node.height !== void 0 ? { size: {
174
+ width: node.width,
175
+ height: node.height
176
+ } } : {},
177
+ data: {
178
+ key: node.data.key,
179
+ ...normalizeStudioNodeType(node.data.type) ? { type: normalizeStudioNodeType(node.data.type) } : {},
180
+ ...normalizeStudioHistory(node.data.history) ? { history: normalizeStudioHistory(node.data.history) } : {},
181
+ ...initialKey ? { initial: initialKey } : {},
182
+ entry: (node.data.entry ?? []).map(toStudioAction),
183
+ exit: (node.data.exit ?? []).map(toStudioAction),
184
+ invoke: (node.data.invokes ?? []).map((invoke) => ({
185
+ src: invoke.src,
186
+ id: invoke.id,
187
+ input: toJsonObject(invoke.input),
188
+ settings: {},
189
+ kind: invoke.src.startsWith("inline:") ? "inline" : "named"
190
+ })),
191
+ tags: node.data.tags ?? [],
192
+ ...node.data.description ? { description: node.data.description } : {},
193
+ ...node.data.color ? { color: toCanvasColor(node.data.color) } : {},
194
+ ...node.data.meta ? { metaEntries: Object.entries(node.data.meta) } : {}
195
+ },
196
+ nodes: childNodes
197
+ };
198
+ }
199
+ function flattenStudioNodes(studioNode, parentId, nodes, pathIdToNodeId) {
200
+ const nodeId = studioNode.id;
201
+ pathIdToNodeId.set(studioNode.id, nodeId);
202
+ const initialId = studioNode.data.initial ? `${studioNode.id}.${studioNode.data.initial}` : void 0;
203
+ nodes.push({
204
+ type: "node",
205
+ id: nodeId,
206
+ parentId,
207
+ label: studioNode.data.key,
208
+ ...initialId ? { initialNodeId: initialId } : {},
209
+ ...studioNode.position ? {
210
+ x: studioNode.position.x,
211
+ y: studioNode.position.y
212
+ } : {},
213
+ ...studioNode.size ? {
214
+ width: studioNode.size.width,
215
+ height: studioNode.size.height
216
+ } : {},
217
+ data: {
218
+ key: studioNode.data.key,
219
+ ...normalizeStudioNodeType(studioNode.data.type) ? { type: normalizeStudioNodeType(studioNode.data.type) } : {},
220
+ ...studioNode.data.history ? { history: studioNode.data.history } : {},
221
+ ...initialId ? { initialId } : {},
222
+ entry: studioNode.data.entry.map(fromStudioAction),
223
+ exit: studioNode.data.exit.map(fromStudioAction),
224
+ invokes: studioNode.data.invoke.map((invoke) => ({
225
+ src: invoke.src,
226
+ id: invoke.id,
227
+ input: toUnknownRecord(invoke.input)
228
+ })),
229
+ tags: studioNode.data.tags,
230
+ ...studioNode.data.description ? { description: studioNode.data.description } : {},
231
+ ...studioNode.data.color ? { color: studioNode.data.color } : {},
232
+ ...studioNode.data.metaEntries ? { meta: Object.fromEntries(studioNode.data.metaEntries) } : {}
233
+ }
234
+ });
235
+ studioNode.nodes.forEach((child) => flattenStudioNodes(child, nodeId, nodes, pathIdToNodeId));
236
+ }
237
+ function toStudioMachine(graph) {
238
+ const rootNode = graph.nodes.find((node) => node.parentId == null);
239
+ if (!rootNode) throw new Error("No root node found in graph");
240
+ const pathIds = /* @__PURE__ */ new Map();
241
+ const studioRootNode = toStudioNode(graph, rootNode.id, pathIds);
242
+ const edgeGroupCounts = /* @__PURE__ */ new Map();
243
+ const studioEdges = graph.edges.map((edge) => {
244
+ const source = pathIds.get(edge.sourceId) ?? edge.sourceId;
245
+ const target = edge.targetId ? pathIds.get(edge.targetId) ?? edge.targetId : void 0;
246
+ const eventType = edge.data.eventType;
247
+ const groupKey = `${source}:${eventType}`;
248
+ const index = edgeGroupCounts.get(groupKey) ?? 0;
249
+ edgeGroupCounts.set(groupKey, index + 1);
250
+ return {
251
+ id: `${source}#${eventType}[${index}]`,
252
+ source,
253
+ target: target && edge.data.transitionType !== "targetless" ? target : void 0,
254
+ ...edge.x !== void 0 && edge.y !== void 0 ? { position: {
255
+ x: edge.x,
256
+ y: edge.y
257
+ } } : {},
258
+ ...edge.width !== void 0 && edge.height !== void 0 ? { size: {
259
+ width: edge.width,
260
+ height: edge.height
261
+ } } : {},
262
+ data: {
263
+ eventTypeData: toStudioEventTypeData(eventType),
264
+ actions: (edge.data.actions ?? []).map(toStudioAction),
265
+ ...edge.data.guard ? { guard: {
266
+ kind: edge.data.guard.code ? "inline" : "named",
267
+ type: edge.data.guard.type,
268
+ params: toJsonObject(edge.data.guard.params ?? {})
269
+ } } : {},
270
+ ...edge.data.description ? { description: edge.data.description } : {},
271
+ ...edge.data.transitionType === "reenter" ? { internal: false } : {},
272
+ ...edge.data.color ? { color: toCanvasColor(edge.data.color) } : {},
273
+ ...edge.data.meta ? { metaEntries: Object.entries(edge.data.meta) } : {}
274
+ }
275
+ };
276
+ });
277
+ return {
278
+ id: graph.id,
279
+ rootNode: studioRootNode,
280
+ edges: studioEdges,
281
+ context: {},
282
+ ...graph.data?.schemas ? { schemas: normalizeSchemas(graph.data.schemas) } : {},
283
+ ...graph.data?.implementations ? { implementations: {
284
+ actions: Object.fromEntries(graph.data.implementations.actions.map((action) => [action.name, toActionSource(action)])),
285
+ guards: Object.fromEntries(graph.data.implementations.guards.map((guard) => [guard.name, toGuardSource(guard)])),
286
+ actors: Object.fromEntries(graph.data.implementations.actors.map((actor) => [actor.name, toActorSource(actor)]))
287
+ } } : {}
288
+ };
289
+ }
290
+ function fromStudioMachine(studioMachine) {
291
+ const nodes = [];
292
+ const pathIdToNodeId = /* @__PURE__ */ new Map();
293
+ flattenStudioNodes(studioMachine.rootNode, null, nodes, pathIdToNodeId);
294
+ const edges = studioMachine.edges.map((edge) => ({
295
+ type: "edge",
296
+ id: edge.id,
297
+ sourceId: pathIdToNodeId.get(edge.source) ?? edge.source,
298
+ targetId: edge.target ? pathIdToNodeId.get(edge.target) ?? edge.target : pathIdToNodeId.get(edge.source) ?? edge.source,
299
+ label: fromStudioEventTypeData(edge.data.eventTypeData),
300
+ ...edge.position ? {
301
+ x: edge.position.x,
302
+ y: edge.position.y
303
+ } : {},
304
+ ...edge.size ? {
305
+ width: edge.size.width,
306
+ height: edge.size.height
307
+ } : {},
308
+ data: {
309
+ eventType: fromStudioEventTypeData(edge.data.eventTypeData),
310
+ transitionType: edge.target ? "normal" : "targetless",
311
+ ...edge.data.guard ? { guard: {
312
+ type: edge.data.guard.type,
313
+ params: toUnknownRecord(edge.data.guard.params),
314
+ ...edge.data.guard.kind === "inline" ? { code: edge.data.guard.type } : {}
315
+ } } : {},
316
+ actions: edge.data.actions.map(fromStudioAction),
317
+ ...edge.data.description ? { description: edge.data.description } : {},
318
+ ...edge.data.color ? { color: edge.data.color } : {},
319
+ ...edge.data.metaEntries ? { meta: Object.fromEntries(edge.data.metaEntries) } : {}
320
+ }
321
+ }));
322
+ return createGraph({
323
+ id: studioMachine.id,
324
+ nodes: nodes.map(({ type: _type, initialNodeId, ...node }) => ({
325
+ ...node,
326
+ ...initialNodeId ? { initialNodeId } : {}
327
+ })),
328
+ edges: edges.map(({ type: _type, ...edge }) => edge),
329
+ data: {
330
+ ...studioMachine.schemas ? { schemas: studioMachine.schemas } : {},
331
+ ...studioMachine.implementations ? { implementations: {
332
+ actions: Object.values(studioMachine.implementations.actions).map(fromActionSource),
333
+ guards: Object.values(studioMachine.implementations.guards).map(fromGuardSource),
334
+ actors: Object.values(studioMachine.implementations.actors).map(fromActorSource),
335
+ delays: [],
336
+ tags: []
337
+ } } : {}
338
+ }
339
+ });
340
+ }
341
+ const studioMachineConverter = createFormatConverter(toStudioMachine, fromStudioMachine);
342
+
343
+ //#endregion
344
+ export { fromStudioMachine, studioMachineConverter, toStudioMachine };
package/dist/index.d.mts CHANGED
@@ -1,111 +1,38 @@
1
- //#region src/embed.d.ts
2
- interface ExportFormatMap {
3
- xstate: {
4
- options: {
5
- version?: 4 | 5;
6
- addTSTypes?: boolean;
7
- showIds?: boolean;
8
- showDescriptions?: boolean;
9
- };
10
- result: string;
11
- };
12
- json: {
13
- options: {
14
- simplifyArrays?: boolean;
15
- version?: 4 | 5;
16
- };
17
- result: Record<string, unknown>;
18
- };
19
- digraph: {
20
- options: Record<string, never>;
21
- result: Record<string, unknown>;
22
- };
23
- mermaid: {
24
- options: Record<string, never>;
25
- result: string;
26
- };
27
- scxml: {
28
- options: Record<string, never>;
29
- result: string;
30
- };
31
- }
32
- type ExportFormat = keyof ExportFormatMap;
33
- type ExportCallOptions<F extends ExportFormat> = ExportFormatMap[F]['options'] & {
34
- timeout?: number;
35
- };
36
- type EmbedMode = 'editing' | 'viewing' | 'simulating';
37
- interface InitOptions {
38
- machine: unknown;
39
- format?: string;
40
- mode?: EmbedMode;
41
- theme?: 'light' | 'dark';
42
- readOnly?: boolean;
43
- depth?: number;
44
- panels?: {
45
- leftPanels?: string[];
46
- rightPanels?: string[];
47
- activePanels?: string[];
48
- };
49
- }
50
- interface EmbedEventMap {
51
- ready: {
52
- version: string;
53
- };
54
- loaded: {
55
- graph: unknown;
56
- };
57
- change: {
58
- graph: unknown;
59
- machineConfig: unknown;
60
- };
61
- save: {
62
- graph: unknown;
63
- machineConfig: unknown;
64
- };
65
- error: {
66
- code: string;
67
- message: string;
68
- };
1
+ import { a as ExportCallOptions, c as InitOptions, i as EmbedMode, l as ProtocolMessage, n as EmbedEventMap, o as ExportFormat, r as EmbedEventName, s as ExportFormatMap, t as EmbedEventHandler } from "./protocol-BC-_s3if.mjs";
2
+ import { StatelyEmbed, StatelyEmbedOptions, createStatelyEmbed } from "./embed.mjs";
3
+ import { C as EventTypeData, S as DigraphNodeConfig, _ as studioMachineConverter, a as StatelyGraphData, b as DigraphConfig, c as StatelyInvoke, d as StudioAction, f as StudioEdge, g as fromStudioMachine, h as StudioNode, i as StatelyGraph, l as StatelyNodeData, m as StudioMachine, o as StatelyGuard, r as StatelyEdgeData, t as StatelyAction, v as toStudioMachine, w as StateNodeJSONData, x as DigraphEdgeConfig, y as DigraphAction } from "./graph-C-7ZK_nK.mjs";
4
+ import { CreateInspectorOptions, InspectOptions, Inspector, createStatelyInspector } from "./inspect.mjs";
5
+ import { ExtractMachinesResponse, ExtractedMachine, GetMachineOptions, ProjectData, ProjectMachine, StudioApiError, StudioClient, StudioClientOptions, VerifyApiKeyResponse, createStatelyClient } from "./studio.mjs";
6
+ import { PlanSyncOptions, PullSyncResult, ResolvedSyncInput, SyncInputFormat, SyncPlan, SyncPlanSummary, planSync, pullSync } from "./sync.mjs";
7
+
8
+ //#region src/transport.d.ts
9
+ interface Transport {
10
+ send(msg: ProtocolMessage): void;
11
+ onMessage(handler: (msg: ProtocolMessage) => void): () => void;
12
+ destroy(): void;
13
+ readonly ready: boolean;
14
+ onReady(handler: () => void): () => void;
69
15
  }
70
- type EmbedEventName = keyof EmbedEventMap;
71
- type EmbedEventHandler<K extends EmbedEventName> = (data: EmbedEventMap[K]) => void;
72
- interface StatelyEmbedOptions {
73
- baseUrl: string;
74
- apiKey?: string;
75
- origin?: string;
76
- onReady?: () => void;
77
- onLoaded?: (graph: unknown) => void;
78
- onChange?: (graph: unknown, machineConfig: unknown) => void;
79
- onSave?: (graph: unknown, machineConfig: unknown) => void;
80
- onError?: (error: {
81
- code: string;
82
- message: string;
83
- }) => void;
16
+ interface PostMessageTransportOptions {
17
+ iframe: HTMLIFrameElement;
18
+ targetOrigin: string;
19
+ /** Filter by source. Defaults to iframe.contentWindow. */
20
+ source?: Window;
84
21
  }
85
- interface StatelyEmbed {
86
- /** Attach to an existing iframe element. Sets src and begins handshake. */
87
- attach(iframe: HTMLIFrameElement): void;
88
- /** Create an iframe and mount it into a container element. */
89
- mount(container: HTMLElement): HTMLIFrameElement;
90
- /** Send init message (queued if iframe not ready yet). */
91
- init(options: InitOptions): void;
92
- /** Update the machine (shorthand for update message). */
93
- updateMachine(machine: unknown, format?: string): void;
94
- /** Change the embed mode. */
95
- setMode(mode: EmbedMode): void;
96
- /** Change the embed theme. */
97
- setTheme(theme: 'light' | 'dark'): void;
98
- /** Export the current machine in a given format. Returns a promise. */
99
- export<F extends ExportFormat>(format: F, options?: ExportCallOptions<F>): Promise<ExportFormatMap[F]['result']>;
100
- /** Subscribe to an embed event. */
101
- on<K extends EmbedEventName>(event: K, handler: EmbedEventHandler<K>): void;
102
- /** Unsubscribe from an embed event. */
103
- off<K extends EmbedEventName>(event: K, handler: EmbedEventHandler<K>): void;
104
- /** Show a toast message in the embed. */
105
- toast(message: string, toastType?: 'success' | 'error' | 'info' | 'warning'): void;
106
- /** Tear down: remove listener, reject pending promises, optionally remove iframe. */
107
- destroy(): void;
22
+ declare function createPostMessageTransport(options: PostMessageTransportOptions): Transport;
23
+ interface WebSocketTransportOptions {
24
+ url: string;
25
+ role: 'client' | 'viz';
26
+ sessionId: string;
27
+ metadata?: {
28
+ name?: string;
29
+ machineId?: string;
30
+ };
31
+ /** Reconnect on disconnect. Default true. */
32
+ reconnect?: boolean;
33
+ /** Max reconnect attempts. Default 10. */
34
+ maxReconnectAttempts?: number;
108
35
  }
109
- declare function createStatelyEmbed(options: StatelyEmbedOptions): StatelyEmbed;
36
+ declare function createWebSocketTransport(options: WebSocketTransportOptions): Transport;
110
37
  //#endregion
111
- export { type EmbedEventMap, type EmbedMode, type ExportCallOptions, type ExportFormat, type ExportFormatMap, type InitOptions, type StatelyEmbed, type StatelyEmbedOptions, createStatelyEmbed };
38
+ export { type CreateInspectorOptions, type DigraphAction, type DigraphConfig, type DigraphEdgeConfig, type DigraphNodeConfig, type EmbedEventHandler, type EmbedEventMap, type EmbedEventName, type EmbedMode, type EventTypeData, type ExportCallOptions, type ExportFormat, type ExportFormatMap, type ExtractMachinesResponse, type ExtractedMachine, type GetMachineOptions, type InitOptions, type InspectOptions, type Inspector, type PlanSyncOptions, type ProjectData, type ProjectMachine, type PullSyncResult, type ResolvedSyncInput, type StateNodeJSONData, type StatelyAction, type StatelyEdgeData, type StatelyEmbed, type StatelyEmbedOptions, type StatelyGraph, type StatelyGraphData, type StatelyGuard, type StatelyInvoke, type StatelyNodeData, type StudioAction, StudioApiError, type StudioClient, type StudioClientOptions, type StudioEdge, type StudioMachine, type StudioNode, type SyncInputFormat, type SyncPlan, type SyncPlanSummary, type Transport, type VerifyApiKeyResponse, createPostMessageTransport, createStatelyClient, createStatelyEmbed, createStatelyInspector, createWebSocketTransport, fromStudioMachine, planSync, pullSync, studioMachineConverter, toStudioMachine };
package/dist/index.mjs CHANGED
@@ -1,201 +1,8 @@
1
- //#region src/embed.ts
2
- const PREFIX = "@statelyai.";
3
- function createStatelyEmbed(options) {
4
- const base = options.baseUrl.replace(/\/+$/, "") + "/embed";
5
- const embedUrl = options.apiKey ? `${base}?api_key=${encodeURIComponent(options.apiKey)}` : base;
6
- const targetOrigin = options.origin ?? new URL(embedUrl).origin;
7
- let iframe = null;
8
- let ownedIframe = false;
9
- let ready = false;
10
- let destroyed = false;
11
- const pendingMessages = [];
12
- let pendingExport = null;
13
- const jsonResultFormats = new Set(["digraph", "json"]);
14
- const listeners = {};
15
- function emit(event, data) {
16
- const set = listeners[event];
17
- if (set) set.forEach((fn) => fn(data));
18
- }
19
- function send(msg) {
20
- if (!ready) {
21
- pendingMessages.push(msg);
22
- return;
23
- }
24
- iframe?.contentWindow?.postMessage(msg, targetOrigin);
25
- }
26
- function flush() {
27
- while (pendingMessages.length > 0) {
28
- const msg = pendingMessages.shift();
29
- iframe?.contentWindow?.postMessage(msg, targetOrigin);
30
- }
31
- }
32
- function handleMessage(e) {
33
- if (destroyed) return;
34
- if (e.source !== iframe?.contentWindow) return;
35
- const data = e.data;
36
- if (!data?.type?.startsWith?.(PREFIX)) return;
37
- switch (data.type) {
38
- case "@statelyai.ready":
39
- ready = true;
40
- flush();
41
- options.onReady?.();
42
- emit("ready", { version: data.version });
43
- break;
44
- case "@statelyai.loaded":
45
- options.onLoaded?.(data.graph);
46
- emit("loaded", { graph: data.graph });
47
- break;
48
- case "@statelyai.change":
49
- options.onChange?.(data.graph, data.machineConfig);
50
- emit("change", {
51
- graph: data.graph,
52
- machineConfig: data.machineConfig
53
- });
54
- break;
55
- case "@statelyai.save":
56
- options.onSave?.(data.graph, data.machineConfig);
57
- emit("save", {
58
- graph: data.graph,
59
- machineConfig: data.machineConfig
60
- });
61
- break;
62
- case "@statelyai.retrieved":
63
- if (pendingExport) {
64
- clearTimeout(pendingExport.timer);
65
- let result = data.data;
66
- if (jsonResultFormats.has(pendingExport.format) && typeof result === "string") result = JSON.parse(result);
67
- pendingExport.resolve(result);
68
- pendingExport = null;
69
- }
70
- break;
71
- case "@statelyai.error": {
72
- const err = {
73
- code: data.code,
74
- message: data.message
75
- };
76
- options.onError?.(err);
77
- emit("error", err);
78
- break;
79
- }
80
- }
81
- }
82
- function startListening() {
83
- window.addEventListener("message", handleMessage);
84
- }
85
- return {
86
- attach(el) {
87
- if (destroyed) return;
88
- iframe = el;
89
- ownedIframe = false;
90
- ready = false;
91
- el.src = embedUrl;
92
- startListening();
93
- },
94
- mount(container) {
95
- if (destroyed) throw new Error("Embed is destroyed");
96
- const el = document.createElement("iframe");
97
- el.src = embedUrl;
98
- el.style.border = "none";
99
- el.style.width = "100%";
100
- el.style.height = "100%";
101
- el.setAttribute("sandbox", "allow-scripts allow-same-origin");
102
- el.setAttribute("allow", "clipboard-read; clipboard-write");
103
- container.appendChild(el);
104
- iframe = el;
105
- ownedIframe = true;
106
- ready = false;
107
- startListening();
108
- return el;
109
- },
110
- init(opts) {
111
- send({
112
- type: "@statelyai.init",
113
- machine: opts.machine,
114
- format: opts.format,
115
- mode: opts.mode,
116
- theme: opts.theme,
117
- readOnly: opts.readOnly,
118
- depth: opts.depth,
119
- leftPanels: opts.panels?.leftPanels,
120
- rightPanels: opts.panels?.rightPanels,
121
- activePanels: opts.panels?.activePanels
122
- });
123
- },
124
- updateMachine(machine, format) {
125
- send({
126
- type: "@statelyai.update",
127
- machine,
128
- format
129
- });
130
- },
131
- setMode(mode) {
132
- send({
133
- type: "@statelyai.setMode",
134
- mode
135
- });
136
- },
137
- setTheme(theme) {
138
- send({
139
- type: "@statelyai.setTheme",
140
- theme
141
- });
142
- },
143
- toast(message, toastType) {
144
- send({
145
- type: "@statelyai.toast",
146
- message,
147
- toastType
148
- });
149
- },
150
- export(format, options) {
151
- const { timeout = 1e4, ...formatOptions } = options ?? {};
152
- return new Promise((resolve, reject) => {
153
- if (destroyed) {
154
- reject(/* @__PURE__ */ new Error("Embed is destroyed"));
155
- return;
156
- }
157
- if (pendingExport) {
158
- clearTimeout(pendingExport.timer);
159
- pendingExport.reject(/* @__PURE__ */ new Error("Superseded by new export"));
160
- }
161
- pendingExport = {
162
- resolve,
163
- reject,
164
- timer: setTimeout(() => {
165
- pendingExport = null;
166
- reject(/* @__PURE__ */ new Error("Export timed out"));
167
- }, timeout),
168
- format
169
- };
170
- send({
171
- type: "@statelyai.retrieve",
172
- format,
173
- ...Object.keys(formatOptions).length > 0 && { options: formatOptions }
174
- });
175
- });
176
- },
177
- on(event, handler) {
178
- if (!listeners[event]) listeners[event] = /* @__PURE__ */ new Set();
179
- listeners[event].add(handler);
180
- },
181
- off(event, handler) {
182
- listeners[event]?.delete(handler);
183
- },
184
- destroy() {
185
- if (destroyed) return;
186
- destroyed = true;
187
- window.removeEventListener("message", handleMessage);
188
- if (pendingExport) {
189
- clearTimeout(pendingExport.timer);
190
- pendingExport.reject(/* @__PURE__ */ new Error("Embed destroyed"));
191
- pendingExport = null;
192
- }
193
- pendingMessages.length = 0;
194
- if (ownedIframe && iframe) iframe.remove();
195
- iframe = null;
196
- }
197
- };
198
- }
1
+ import { n as createWebSocketTransport, t as createPostMessageTransport } from "./transport-D352iKKa.mjs";
2
+ import { createStatelyEmbed } from "./embed.mjs";
3
+ import { createStatelyInspector } from "./inspect.mjs";
4
+ import { StudioApiError, createStatelyClient } from "./studio.mjs";
5
+ import { fromStudioMachine, studioMachineConverter, toStudioMachine } from "./graph.mjs";
6
+ import { n as pullSync, t as planSync } from "./sync-CzEOizjx.mjs";
199
7
 
200
- //#endregion
201
- export { createStatelyEmbed };
8
+ export { StudioApiError, createPostMessageTransport, createStatelyClient, createStatelyEmbed, createStatelyInspector, createWebSocketTransport, fromStudioMachine, planSync, pullSync, studioMachineConverter, toStudioMachine };