@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.
@@ -0,0 +1,45 @@
1
+ import { a as ExportCallOptions, c as InitOptions, i as EmbedMode, n as EmbedEventMap, o as ExportFormat, r as EmbedEventName, s as ExportFormatMap, t as EmbedEventHandler } from "./protocol-BC-_s3if.mjs";
2
+
3
+ //#region src/inspect.d.ts
4
+ interface CreateInspectorOptions {
5
+ /** WebSocket URL of the devtools server. Default: 'ws://localhost:4242' */
6
+ url?: string;
7
+ /** Auto-open browser to visualizer. Default: true */
8
+ autoOpen?: boolean;
9
+ /** Unique session ID. Auto-generated if not provided. */
10
+ sessionId?: string;
11
+ /** Display name for this connection in the visualizer. */
12
+ name?: string;
13
+ }
14
+ interface Inspector {
15
+ /** Send a machine for inspection (starts visualization). */
16
+ inspect(options: InspectOptions): void;
17
+ /** Update the machine currently being inspected. */
18
+ update(machine: unknown, format?: string): void;
19
+ /** Change the visualization mode. */
20
+ setMode(mode: EmbedMode): void;
21
+ /** Export the current machine in a given format. Returns a promise. */
22
+ export<F extends ExportFormat>(format: F, options?: ExportCallOptions<F>): Promise<ExportFormatMap[F]['result']>;
23
+ /** Subscribe to events from the visualizer. */
24
+ on<K extends EmbedEventName>(event: K, handler: EmbedEventHandler<K>): void;
25
+ /** Unsubscribe from an event. */
26
+ off<K extends EmbedEventName>(event: K, handler: EmbedEventHandler<K>): void;
27
+ /** Send a state snapshot for real-time inspection. */
28
+ sendSnapshot(snapshot: unknown, event?: unknown): void;
29
+ /** Clean up the connection. */
30
+ destroy(): void;
31
+ /** Session ID for this connection. */
32
+ readonly sessionId: string;
33
+ }
34
+ interface InspectOptions {
35
+ machine: unknown;
36
+ format?: string;
37
+ mode?: EmbedMode;
38
+ theme?: 'light' | 'dark';
39
+ readOnly?: boolean;
40
+ depth?: number;
41
+ panels?: InitOptions['panels'];
42
+ }
43
+ declare function createStatelyInspector(options?: CreateInspectorOptions): Inspector;
44
+ //#endregion
45
+ export { CreateInspectorOptions, type EmbedEventHandler, type EmbedEventMap, type EmbedEventName, type EmbedMode, type ExportCallOptions, type ExportFormat, type ExportFormatMap, type InitOptions, InspectOptions, Inspector, createStatelyInspector };
@@ -0,0 +1,122 @@
1
+ import { a as createRequestId, i as createPendingExportManager, n as createWebSocketTransport, o as toInitMessage, r as createEventRegistry } from "./transport-D352iKKa.mjs";
2
+
3
+ //#region src/inspect.ts
4
+ function generateId() {
5
+ return createRequestId();
6
+ }
7
+ function createStatelyInspector(options) {
8
+ const { url = "ws://localhost:4242", autoOpen = true, sessionId = generateId(), name } = options ?? {};
9
+ let destroyed = false;
10
+ const pendingMessages = [];
11
+ const events = createEventRegistry();
12
+ const transport = createWebSocketTransport({
13
+ url,
14
+ role: "client",
15
+ sessionId,
16
+ ...name && { metadata: { name } }
17
+ });
18
+ const exportManager = createPendingExportManager((message) => send(message));
19
+ function send(msg) {
20
+ if (!transport.ready) {
21
+ pendingMessages.push(msg);
22
+ return;
23
+ }
24
+ transport.send(msg);
25
+ }
26
+ function flush() {
27
+ while (pendingMessages.length > 0) {
28
+ const msg = pendingMessages.shift();
29
+ transport.send(msg);
30
+ }
31
+ }
32
+ transport.onReady(() => {
33
+ flush();
34
+ });
35
+ if (autoOpen) transport.onReady(() => {
36
+ transport.send({
37
+ type: "@statelyai.requestOpen",
38
+ sessionId
39
+ });
40
+ });
41
+ transport.onMessage((msg) => {
42
+ if (destroyed) return;
43
+ switch (msg.type) {
44
+ case "@statelyai.ready":
45
+ events.emit("ready", { version: msg.version });
46
+ break;
47
+ case "@statelyai.loaded":
48
+ events.emit("loaded", { graph: msg.graph });
49
+ break;
50
+ case "@statelyai.change":
51
+ events.emit("change", {
52
+ graph: msg.graph,
53
+ machineConfig: msg.machineConfig
54
+ });
55
+ break;
56
+ case "@statelyai.save":
57
+ events.emit("save", {
58
+ graph: msg.graph,
59
+ machineConfig: msg.machineConfig
60
+ });
61
+ break;
62
+ case "@statelyai.retrieved":
63
+ exportManager.resolve(msg.requestId, msg.data);
64
+ break;
65
+ case "@statelyai.error":
66
+ exportManager.reject(new Error(msg.message), msg.requestId);
67
+ events.emit("error", {
68
+ code: msg.code,
69
+ message: msg.message
70
+ });
71
+ break;
72
+ }
73
+ });
74
+ return {
75
+ get sessionId() {
76
+ return sessionId;
77
+ },
78
+ inspect(opts) {
79
+ send(toInitMessage(opts));
80
+ },
81
+ update(machine, format) {
82
+ send({
83
+ type: "@statelyai.update",
84
+ machine,
85
+ format
86
+ });
87
+ },
88
+ setMode(mode) {
89
+ send({
90
+ type: "@statelyai.setMode",
91
+ mode
92
+ });
93
+ },
94
+ export(format, callOptions) {
95
+ return exportManager.start(format, callOptions, "Inspector is destroyed", () => destroyed);
96
+ },
97
+ on(event, handler) {
98
+ events.on(event, handler);
99
+ },
100
+ off(event, handler) {
101
+ events.off(event, handler);
102
+ },
103
+ sendSnapshot(snapshot, event) {
104
+ send({
105
+ type: "@statelyai.inspectSnapshot",
106
+ snapshot,
107
+ event: event ?? null
108
+ });
109
+ },
110
+ destroy() {
111
+ if (destroyed) return;
112
+ destroyed = true;
113
+ transport.destroy();
114
+ exportManager.clear("Inspector destroyed");
115
+ events.clear();
116
+ pendingMessages.length = 0;
117
+ }
118
+ };
119
+ }
120
+
121
+ //#endregion
122
+ export { createStatelyInspector };
@@ -0,0 +1,172 @@
1
+ //#region src/protocol.d.ts
2
+ type EmbedMode = 'editing' | 'viewing' | 'simulating' | 'inspecting';
3
+ interface ExportFormatMap {
4
+ xstate: {
5
+ options: {
6
+ version?: 4 | 5;
7
+ addTSTypes?: boolean;
8
+ showIds?: boolean;
9
+ showDescriptions?: boolean;
10
+ };
11
+ result: string;
12
+ };
13
+ json: {
14
+ options: {
15
+ simplifyArrays?: boolean;
16
+ version?: 4 | 5;
17
+ };
18
+ result: Record<string, unknown>;
19
+ };
20
+ digraph: {
21
+ options: object;
22
+ result: Record<string, unknown>;
23
+ };
24
+ mermaid: {
25
+ options: object;
26
+ result: string;
27
+ };
28
+ scxml: {
29
+ options: object;
30
+ result: string;
31
+ };
32
+ }
33
+ type ExportFormat = keyof ExportFormatMap;
34
+ type ExportCallOptions<F extends ExportFormat> = ExportFormatMap[F]['options'] & {
35
+ timeout?: number;
36
+ };
37
+ interface EmbedEventMap {
38
+ ready: {
39
+ version: string;
40
+ };
41
+ loaded: {
42
+ graph: unknown;
43
+ };
44
+ change: {
45
+ graph: unknown;
46
+ machineConfig: unknown;
47
+ };
48
+ save: {
49
+ graph: unknown;
50
+ machineConfig: unknown;
51
+ };
52
+ error: {
53
+ code: string;
54
+ message: string;
55
+ };
56
+ snapshot: {
57
+ snapshot: unknown;
58
+ event: unknown | null;
59
+ };
60
+ }
61
+ type EmbedEventName = keyof EmbedEventMap;
62
+ type EmbedEventHandler<K extends EmbedEventName> = (data: EmbedEventMap[K]) => void;
63
+ interface InitOptions {
64
+ machine: unknown;
65
+ format?: string;
66
+ mode?: EmbedMode;
67
+ theme?: 'light' | 'dark';
68
+ readOnly?: boolean;
69
+ depth?: number;
70
+ panels?: {
71
+ leftPanels?: string[];
72
+ rightPanels?: string[];
73
+ activePanels?: string[];
74
+ };
75
+ }
76
+ interface InitMessage {
77
+ type: '@statelyai.init';
78
+ machine: unknown;
79
+ format?: string;
80
+ mode?: EmbedMode;
81
+ theme?: 'light' | 'dark';
82
+ readOnly?: boolean;
83
+ depth?: number;
84
+ leftPanels?: string[];
85
+ rightPanels?: string[];
86
+ activePanels?: string[];
87
+ }
88
+ interface UpdateMessage {
89
+ type: '@statelyai.update';
90
+ machine: unknown;
91
+ format?: string;
92
+ }
93
+ interface SetModeMessage {
94
+ type: '@statelyai.setMode';
95
+ mode: EmbedMode;
96
+ }
97
+ interface SetThemeMessage {
98
+ type: '@statelyai.setTheme';
99
+ theme: 'light' | 'dark';
100
+ }
101
+ interface RetrieveMessage {
102
+ type: '@statelyai.retrieve';
103
+ requestId: string;
104
+ format: ExportFormat;
105
+ options?: Record<string, unknown>;
106
+ }
107
+ interface ToastMessage {
108
+ type: '@statelyai.toast';
109
+ message: string;
110
+ toastType?: 'success' | 'error' | 'info' | 'warning';
111
+ }
112
+ interface InspectSnapshotMessage {
113
+ type: '@statelyai.inspectSnapshot';
114
+ snapshot: unknown;
115
+ event: unknown | null;
116
+ }
117
+ /** All messages a client (embed/inspector) can send to the viz. */
118
+ type ClientMessage = InitMessage | UpdateMessage | SetModeMessage | SetThemeMessage | RetrieveMessage | ToastMessage | InspectSnapshotMessage;
119
+ interface ReadyMessage {
120
+ type: '@statelyai.ready';
121
+ version: string;
122
+ }
123
+ interface LoadedMessage {
124
+ type: '@statelyai.loaded';
125
+ graph: unknown;
126
+ }
127
+ interface ChangeMessage {
128
+ type: '@statelyai.change';
129
+ graph: unknown;
130
+ machineConfig: unknown;
131
+ }
132
+ interface SaveMessage {
133
+ type: '@statelyai.save';
134
+ graph: unknown;
135
+ machineConfig: unknown;
136
+ }
137
+ interface RetrievedMessage {
138
+ type: '@statelyai.retrieved';
139
+ requestId: string;
140
+ data: unknown;
141
+ }
142
+ interface ErrorMessage {
143
+ type: '@statelyai.error';
144
+ code: string;
145
+ message: string;
146
+ requestId?: string;
147
+ }
148
+ /** All messages the viz can send back to a client. */
149
+ type VizMessage = ReadyMessage | LoadedMessage | ChangeMessage | SaveMessage | RetrievedMessage | ErrorMessage;
150
+ interface RegisterMessage {
151
+ type: '@statelyai.register';
152
+ role: 'client' | 'viz';
153
+ sessionId: string;
154
+ metadata?: {
155
+ name?: string;
156
+ machineId?: string;
157
+ };
158
+ }
159
+ interface RegisteredMessage {
160
+ type: '@statelyai.registered';
161
+ sessionId: string;
162
+ }
163
+ interface RequestOpenMessage {
164
+ type: '@statelyai.requestOpen';
165
+ sessionId: string;
166
+ }
167
+ /** All session-management messages for the WS relay. */
168
+ type SessionMessage = RegisterMessage | RegisteredMessage | RequestOpenMessage;
169
+ /** Any valid protocol message. */
170
+ type ProtocolMessage = ClientMessage | VizMessage | SessionMessage;
171
+ //#endregion
172
+ export { ExportCallOptions as a, InitOptions as c, EmbedMode as i, ProtocolMessage as l, EmbedEventMap as n, ExportFormat as o, EmbedEventName as r, ExportFormatMap as s, EmbedEventHandler as t };
@@ -0,0 +1,54 @@
1
+ //#region src/studio.d.ts
2
+ interface StudioClientOptions {
3
+ baseUrl?: string;
4
+ apiKey?: string;
5
+ fetch?: typeof fetch;
6
+ }
7
+ interface VerifyApiKeyResponse {
8
+ valid: boolean;
9
+ }
10
+ interface ProjectMachine {
11
+ machineId: string;
12
+ name: string;
13
+ }
14
+ interface ProjectData {
15
+ projectId: string;
16
+ machines: ProjectMachine[];
17
+ }
18
+ interface ExtractedMachine {
19
+ id?: string;
20
+ config: Record<string, unknown>;
21
+ setupConfig?: Record<string, unknown>;
22
+ implementations?: Record<string, unknown>;
23
+ _type: 'setup.createMachine' | 'createMachine';
24
+ }
25
+ interface ExtractMachinesResponse {
26
+ machines: ExtractedMachine[];
27
+ error?: string;
28
+ }
29
+ interface GetMachineOptions {
30
+ version?: string;
31
+ }
32
+ declare class StudioApiError extends Error {
33
+ readonly status: number;
34
+ constructor(message: string, status: number);
35
+ }
36
+ interface StudioClient {
37
+ auth: {
38
+ verify(apiKey?: string): Promise<VerifyApiKeyResponse>;
39
+ };
40
+ projects: {
41
+ get(projectId: string): Promise<ProjectData>;
42
+ };
43
+ machines: {
44
+ get<TMachine = Record<string, unknown>>(machineId: string, options?: GetMachineOptions): Promise<TMachine>;
45
+ };
46
+ code: {
47
+ extractMachines(code: string, options?: {
48
+ apiKey?: string | null;
49
+ }): Promise<ExtractMachinesResponse>;
50
+ };
51
+ }
52
+ declare function createStatelyClient(options?: StudioClientOptions): StudioClient;
53
+ //#endregion
54
+ export { ExtractMachinesResponse, ExtractedMachine, GetMachineOptions, ProjectData, ProjectMachine, StudioApiError, StudioClient, StudioClientOptions, VerifyApiKeyResponse, createStatelyClient };
@@ -0,0 +1,62 @@
1
+ //#region src/studio.ts
2
+ var StudioApiError = class extends Error {
3
+ status;
4
+ constructor(message, status) {
5
+ super(message);
6
+ this.name = "StudioApiError";
7
+ this.status = status;
8
+ }
9
+ };
10
+ function getFetch(fetchImpl) {
11
+ const resolvedFetch = fetchImpl ?? globalThis.fetch;
12
+ if (!resolvedFetch) throw new Error("No fetch implementation available. Pass one via createStatelyClient({ fetch }).");
13
+ return resolvedFetch;
14
+ }
15
+ function joinApiUrl(baseUrl, path) {
16
+ return `${baseUrl.replace(/\/+$/, "")}/registry/api/v1${path}`;
17
+ }
18
+ async function parseJson(response) {
19
+ if (!response.headers.get("content-type")?.includes("application/json")) return null;
20
+ return response.json().catch(() => null);
21
+ }
22
+ function createStatelyClient(options = {}) {
23
+ const baseUrl = options.baseUrl ?? "https://stately.ai";
24
+ const fetchImpl = getFetch(options.fetch);
25
+ async function request(path, init = {}, apiKeyOverride) {
26
+ const headers = new Headers(init.headers);
27
+ const apiKey = apiKeyOverride ?? options.apiKey;
28
+ if (apiKey) headers.set("Authorization", `Bearer ${apiKey}`);
29
+ const response = await fetchImpl(joinApiUrl(baseUrl, path), {
30
+ ...init,
31
+ headers
32
+ });
33
+ const data = await parseJson(response);
34
+ if (!response.ok) throw new StudioApiError(typeof data === "object" && data !== null && "error" in data && typeof data.error === "string" ? data.error : `HTTP ${response.status}`, response.status);
35
+ return data;
36
+ }
37
+ return {
38
+ auth: { verify(apiKey) {
39
+ return request("/verify", { method: "GET" }, apiKey);
40
+ } },
41
+ projects: { get(projectId) {
42
+ return request(`/projects/${encodeURIComponent(projectId)}`, { method: "GET" });
43
+ } },
44
+ machines: { get(machineId, getOptions = {}) {
45
+ const search = new URLSearchParams();
46
+ if (getOptions.version) search.set("version", getOptions.version);
47
+ const suffix = search.size > 0 ? `?${search.toString()}` : "";
48
+ return request(`/machines/${encodeURIComponent(machineId)}${suffix}`, { method: "GET" });
49
+ } },
50
+ code: { extractMachines(code, extractOptions = {}) {
51
+ const apiKey = extractOptions.apiKey ?? options.apiKey ?? "anonymous";
52
+ return request("/code", {
53
+ method: "POST",
54
+ headers: { "Content-Type": "application/json" },
55
+ body: JSON.stringify({ code })
56
+ }, apiKey);
57
+ } }
58
+ };
59
+ }
60
+
61
+ //#endregion
62
+ export { StudioApiError, createStatelyClient };