@statelyai/sdk 0.6.0 → 0.6.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 +52 -1
- package/dist/assetStorage.d.mts +73 -0
- package/dist/assetStorage.mjs +99 -0
- package/dist/cli.d.mts +1 -1
- package/dist/cli.mjs +1 -1
- package/dist/embed.d.mts +9 -2
- package/dist/embed.mjs +13 -7
- package/dist/graph.d.mts +1 -1
- package/dist/graph.mjs +9 -5
- package/dist/graphToXStateTS-Gzh0ZqbN.mjs +709 -0
- package/dist/index.d.mts +140 -5
- package/dist/index.mjs +3 -2
- package/dist/{inspect-DIxB2Tr3.d.mts → inspect-BMIJcsFh.d.mts} +1 -1
- package/dist/inspect.d.mts +2 -2
- package/dist/sync.d.mts +1 -1
- package/dist/sync.mjs +1 -1
- package/package.json +6 -3
- package/dist/graphToXStateTS-CvXM8wHL.mjs +0 -344
- /package/dist/{graph-CB-ALrdk.d.mts → graph-DpBGHZwl.d.mts} +0 -0
- /package/dist/{protocol-CEbWQPYe.d.mts → protocol-CDoCcaIP.d.mts} +0 -0
package/README.md
CHANGED
|
@@ -137,6 +137,8 @@ import {
|
|
|
137
137
|
createStatelyClient,
|
|
138
138
|
createStatelyEmbed,
|
|
139
139
|
createStatelyInspector,
|
|
140
|
+
createS3AssetUploadAdapter,
|
|
141
|
+
createSupabaseAssetUploadAdapter,
|
|
140
142
|
fromStudioMachine,
|
|
141
143
|
graphToMachineConfig,
|
|
142
144
|
graphToXStateTS,
|
|
@@ -156,6 +158,10 @@ import {
|
|
|
156
158
|
} from '@statelyai/sdk/api';
|
|
157
159
|
import { fromStudioMachine, toStudioMachine } from '@statelyai/sdk/graph';
|
|
158
160
|
import { planSync, pullSync, pushSync } from '@statelyai/sdk/sync';
|
|
161
|
+
import {
|
|
162
|
+
createS3AssetUploadAdapter,
|
|
163
|
+
createSupabaseAssetUploadAdapter,
|
|
164
|
+
} from '@statelyai/sdk/assetStorage';
|
|
159
165
|
import type { GraphPatch } from '@statelyai/sdk/patchTypes';
|
|
160
166
|
```
|
|
161
167
|
|
|
@@ -462,9 +468,54 @@ const embed = createStatelyEmbed({
|
|
|
462
468
|
});
|
|
463
469
|
```
|
|
464
470
|
|
|
471
|
+
For reusable integrations, pass an upload adapter instead of wiring the callback inline:
|
|
472
|
+
|
|
473
|
+
```ts
|
|
474
|
+
import { createStatelyEmbed, createS3AssetUploadAdapter } from '@statelyai/sdk';
|
|
475
|
+
|
|
476
|
+
const adapter = createS3AssetUploadAdapter({
|
|
477
|
+
bucket: 'assets',
|
|
478
|
+
publicBaseUrl: 'https://cdn.example.com/assets',
|
|
479
|
+
async getUploadTarget({ key, contentType }) {
|
|
480
|
+
const response = await fetch('/api/assets/presign', {
|
|
481
|
+
method: 'POST',
|
|
482
|
+
headers: { 'Content-Type': 'application/json' },
|
|
483
|
+
body: JSON.stringify({ key, contentType }),
|
|
484
|
+
});
|
|
485
|
+
return response.json();
|
|
486
|
+
},
|
|
487
|
+
});
|
|
488
|
+
|
|
489
|
+
const embed = createStatelyEmbed({
|
|
490
|
+
baseUrl: 'https://stately.ai',
|
|
491
|
+
assets: { adapter },
|
|
492
|
+
});
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
Supabase storage can use the same adapter contract:
|
|
496
|
+
|
|
497
|
+
```ts
|
|
498
|
+
import {
|
|
499
|
+
createStatelyEmbed,
|
|
500
|
+
createSupabaseAssetUploadAdapter,
|
|
501
|
+
} from '@statelyai/sdk';
|
|
502
|
+
|
|
503
|
+
const adapter = createSupabaseAssetUploadAdapter({
|
|
504
|
+
client: supabaseClient,
|
|
505
|
+
bucket: 'assets',
|
|
506
|
+
projectVersionId,
|
|
507
|
+
});
|
|
508
|
+
|
|
509
|
+
const embed = createStatelyEmbed({
|
|
510
|
+
baseUrl: 'https://stately.ai',
|
|
511
|
+
assets: { adapter },
|
|
512
|
+
});
|
|
513
|
+
```
|
|
514
|
+
|
|
465
515
|
| Option | Type | Description |
|
|
466
516
|
| ----------------- | ------------------------------------------------------------------------- | ----------------------------------------------------------- |
|
|
467
|
-
| `onUploadRequest` | `(file: File, context: { stateNodeId: string }) => Promise<UploadResult>` |
|
|
517
|
+
| `onUploadRequest` | `(file: File, context: { stateNodeId: string }) => Promise<UploadResult>` | Called when the editor needs to upload a file |
|
|
518
|
+
| `adapter` | `AssetUploadAdapter` | Provider-specific uploader, such as the S3 or Supabase adapter |
|
|
468
519
|
| `accept` | `string[]` | Accepted MIME types. Supports wildcards like `image/*` |
|
|
469
520
|
| `maxFileSize` | `number` | Max file size in bytes. Defaults to `10_485_760` |
|
|
470
521
|
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { m as UploadResult } from "./protocol-CDoCcaIP.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/assetStorage.d.ts
|
|
4
|
+
interface AssetUploadContext {
|
|
5
|
+
stateNodeId: string;
|
|
6
|
+
}
|
|
7
|
+
interface AssetUploadRequest extends AssetUploadContext {
|
|
8
|
+
file: File;
|
|
9
|
+
}
|
|
10
|
+
interface AssetUploadAdapter {
|
|
11
|
+
upload(request: AssetUploadRequest): Promise<UploadResult>;
|
|
12
|
+
accept?: string[];
|
|
13
|
+
maxFileSize?: number;
|
|
14
|
+
}
|
|
15
|
+
type AssetObjectKeyFactory = (request: AssetUploadRequest) => string | Promise<string>;
|
|
16
|
+
interface S3UploadTarget {
|
|
17
|
+
uploadUrl: string;
|
|
18
|
+
publicUrl?: string;
|
|
19
|
+
method?: 'PUT' | 'POST';
|
|
20
|
+
headers?: Record<string, string>;
|
|
21
|
+
fields?: Record<string, string>;
|
|
22
|
+
}
|
|
23
|
+
interface CreateS3AssetUploadAdapterOptions {
|
|
24
|
+
bucket?: string;
|
|
25
|
+
publicBaseUrl?: string;
|
|
26
|
+
accept?: string[];
|
|
27
|
+
maxFileSize?: number;
|
|
28
|
+
key?: AssetObjectKeyFactory;
|
|
29
|
+
getUploadTarget: (request: AssetUploadRequest & {
|
|
30
|
+
key: string;
|
|
31
|
+
contentType: string;
|
|
32
|
+
bucket?: string;
|
|
33
|
+
}) => Promise<S3UploadTarget>;
|
|
34
|
+
}
|
|
35
|
+
interface SupabaseStorageBucket {
|
|
36
|
+
upload(path: string, file: File, options?: {
|
|
37
|
+
cacheControl?: string;
|
|
38
|
+
contentType?: string;
|
|
39
|
+
upsert?: boolean;
|
|
40
|
+
}): Promise<{
|
|
41
|
+
data: {
|
|
42
|
+
path: string;
|
|
43
|
+
} | null;
|
|
44
|
+
error: Error | {
|
|
45
|
+
message: string;
|
|
46
|
+
} | null;
|
|
47
|
+
}>;
|
|
48
|
+
getPublicUrl?(path: string): {
|
|
49
|
+
data: {
|
|
50
|
+
publicUrl: string;
|
|
51
|
+
};
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
interface SupabaseStorageClient {
|
|
55
|
+
storage: {
|
|
56
|
+
from(bucket: string): SupabaseStorageBucket;
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
interface CreateSupabaseAssetUploadAdapterOptions {
|
|
60
|
+
client: SupabaseStorageClient;
|
|
61
|
+
bucket?: string;
|
|
62
|
+
publicBaseUrl?: string;
|
|
63
|
+
projectVersionId?: string;
|
|
64
|
+
accept?: string[];
|
|
65
|
+
maxFileSize?: number;
|
|
66
|
+
cacheControl?: string;
|
|
67
|
+
upsert?: boolean;
|
|
68
|
+
key?: AssetObjectKeyFactory;
|
|
69
|
+
}
|
|
70
|
+
declare function createS3AssetUploadAdapter(options: CreateS3AssetUploadAdapterOptions): AssetUploadAdapter;
|
|
71
|
+
declare function createSupabaseAssetUploadAdapter(options: CreateSupabaseAssetUploadAdapterOptions): AssetUploadAdapter;
|
|
72
|
+
//#endregion
|
|
73
|
+
export { AssetObjectKeyFactory, AssetUploadAdapter, AssetUploadContext, AssetUploadRequest, CreateS3AssetUploadAdapterOptions, CreateSupabaseAssetUploadAdapterOptions, S3UploadTarget, SupabaseStorageClient, createS3AssetUploadAdapter, createSupabaseAssetUploadAdapter };
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
//#region src/assetStorage.ts
|
|
2
|
+
function sanitizeFileName(name) {
|
|
3
|
+
return name.replace(/[^A-Za-z0-9._-]+/g, "-").replace(/^-+|-+$/g, "");
|
|
4
|
+
}
|
|
5
|
+
function defaultObjectKey({ file, stateNodeId }) {
|
|
6
|
+
const fileName = sanitizeFileName(file.name) || "asset";
|
|
7
|
+
return `${stateNodeId}/${crypto.randomUUID()}-${fileName}`;
|
|
8
|
+
}
|
|
9
|
+
function createProjectObjectKey(projectVersionId) {
|
|
10
|
+
return ({ file }) => {
|
|
11
|
+
const fileName = sanitizeFileName(file.name) || "asset";
|
|
12
|
+
return `${projectVersionId}/${crypto.randomUUID()}-${fileName}`;
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
function joinUrl(baseUrl, key) {
|
|
16
|
+
return `${baseUrl.replace(/\/+$/, "")}/${key.split("/").map(encodeURIComponent).join("/")}`;
|
|
17
|
+
}
|
|
18
|
+
async function uploadToTarget(target, file) {
|
|
19
|
+
if (target.method === "POST" || target.fields) {
|
|
20
|
+
const formData = new FormData();
|
|
21
|
+
Object.entries(target.fields ?? {}).forEach(([name, value]) => {
|
|
22
|
+
formData.append(name, value);
|
|
23
|
+
});
|
|
24
|
+
formData.append("file", file);
|
|
25
|
+
const response = await fetch(target.uploadUrl, {
|
|
26
|
+
method: "POST",
|
|
27
|
+
body: formData
|
|
28
|
+
});
|
|
29
|
+
if (!response.ok) throw new Error(`Asset upload failed with ${response.status}`);
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
const response = await fetch(target.uploadUrl, {
|
|
33
|
+
method: target.method ?? "PUT",
|
|
34
|
+
headers: {
|
|
35
|
+
"Content-Type": file.type || "application/octet-stream",
|
|
36
|
+
...target.headers
|
|
37
|
+
},
|
|
38
|
+
body: file
|
|
39
|
+
});
|
|
40
|
+
if (!response.ok) throw new Error(`Asset upload failed with ${response.status}`);
|
|
41
|
+
}
|
|
42
|
+
function createS3AssetUploadAdapter(options) {
|
|
43
|
+
return {
|
|
44
|
+
accept: options.accept,
|
|
45
|
+
maxFileSize: options.maxFileSize,
|
|
46
|
+
async upload(request) {
|
|
47
|
+
const key = await (options.key ?? defaultObjectKey)(request);
|
|
48
|
+
const target = await options.getUploadTarget({
|
|
49
|
+
...request,
|
|
50
|
+
key,
|
|
51
|
+
contentType: request.file.type || "application/octet-stream",
|
|
52
|
+
bucket: options.bucket
|
|
53
|
+
});
|
|
54
|
+
await uploadToTarget(target, request.file);
|
|
55
|
+
const url = target.publicUrl ?? (options.publicBaseUrl ? joinUrl(options.publicBaseUrl, key) : void 0);
|
|
56
|
+
if (!url) throw new Error("S3 asset upload adapter requires a publicUrl or publicBaseUrl");
|
|
57
|
+
return {
|
|
58
|
+
url,
|
|
59
|
+
name: request.file.name,
|
|
60
|
+
metadata: {
|
|
61
|
+
bucket: options.bucket,
|
|
62
|
+
key
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
function createSupabaseAssetUploadAdapter(options) {
|
|
69
|
+
const bucket = options.bucket ?? "assets";
|
|
70
|
+
return {
|
|
71
|
+
accept: options.accept,
|
|
72
|
+
maxFileSize: options.maxFileSize,
|
|
73
|
+
async upload(request) {
|
|
74
|
+
const storage = options.client.storage.from(bucket);
|
|
75
|
+
const key = await (options.key ?? (options.projectVersionId ? createProjectObjectKey(options.projectVersionId) : defaultObjectKey))(request);
|
|
76
|
+
const { data, error } = await storage.upload(key, request.file, {
|
|
77
|
+
cacheControl: options.cacheControl,
|
|
78
|
+
contentType: request.file.type || "application/octet-stream",
|
|
79
|
+
upsert: options.upsert
|
|
80
|
+
});
|
|
81
|
+
if (error) throw new Error(error.message);
|
|
82
|
+
if (!data?.path) throw new Error("Supabase asset upload did not return a path");
|
|
83
|
+
const publicUrl = storage.getPublicUrl?.(data.path)?.data.publicUrl ?? (options.publicBaseUrl ? joinUrl(options.publicBaseUrl, data.path) : void 0);
|
|
84
|
+
if (!publicUrl) throw new Error("Supabase asset upload adapter requires getPublicUrl or publicBaseUrl");
|
|
85
|
+
return {
|
|
86
|
+
url: publicUrl,
|
|
87
|
+
name: request.file.name,
|
|
88
|
+
metadata: {
|
|
89
|
+
bucket,
|
|
90
|
+
path: data.path,
|
|
91
|
+
key: data.path
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
//#endregion
|
|
99
|
+
export { createS3AssetUploadAdapter, createSupabaseAssetUploadAdapter };
|
package/dist/cli.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ConnectedRepo, CreateProjectInput, ProjectData, StudioClient } from "./studio.mjs";
|
|
2
|
-
import "./graph-
|
|
2
|
+
import "./graph-DpBGHZwl.mjs";
|
|
3
3
|
import { SyncPlan } from "./sync.mjs";
|
|
4
4
|
import { Command } from "@oclif/core";
|
|
5
5
|
import * as _oclif_core_interfaces0 from "@oclif/core/interfaces";
|
package/dist/cli.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createStatelyClient } from "./studio.mjs";
|
|
3
|
-
import "./graphToXStateTS-
|
|
3
|
+
import "./graphToXStateTS-Gzh0ZqbN.mjs";
|
|
4
4
|
import { planSync, pullSync } from "./sync.mjs";
|
|
5
5
|
import fs from "node:fs/promises";
|
|
6
6
|
import * as path$1 from "node:path";
|
package/dist/embed.d.mts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { a as EmbedMode, c as ExportFormatMap, d as MachineSourceLocations, f as ProjectEmbedMachine, i as EmbedEventName, l as InitOptions, m as UploadResult, n as EmbedEventHandler, o as ExportCallOptions, r as EmbedEventMap, s as ExportFormat, t as CommentsConfig, u as MachineInitOptions } from "./protocol-
|
|
1
|
+
import { a as EmbedMode, c as ExportFormatMap, d as MachineSourceLocations, f as ProjectEmbedMachine, i as EmbedEventName, l as InitOptions, m as UploadResult, n as EmbedEventHandler, o as ExportCallOptions, r as EmbedEventMap, s as ExportFormat, t as CommentsConfig, u as MachineInitOptions } from "./protocol-CDoCcaIP.mjs";
|
|
2
|
+
import { AssetUploadAdapter } from "./assetStorage.mjs";
|
|
2
3
|
|
|
3
4
|
//#region src/embed.d.ts
|
|
4
5
|
interface AssetConfig {
|
|
@@ -7,9 +8,15 @@ interface AssetConfig {
|
|
|
7
8
|
* Receives a real File object (reconstructed from serialized data).
|
|
8
9
|
* Throwing or rejecting will show an error toast in the embed.
|
|
9
10
|
*/
|
|
10
|
-
onUploadRequest
|
|
11
|
+
onUploadRequest?: (file: File, context: {
|
|
11
12
|
stateNodeId: string;
|
|
12
13
|
}) => Promise<UploadResult>;
|
|
14
|
+
/**
|
|
15
|
+
* Storage adapter used by the embed upload bridge. This keeps the editor
|
|
16
|
+
* protocol storage-neutral while allowing integrations to plug in S3, R2,
|
|
17
|
+
* Supabase, or any other backing store.
|
|
18
|
+
*/
|
|
19
|
+
adapter?: AssetUploadAdapter;
|
|
13
20
|
/**
|
|
14
21
|
* Accepted MIME types. Supports wildcards (e.g. 'image/*').
|
|
15
22
|
* @default ['image/*']
|
package/dist/embed.mjs
CHANGED
|
@@ -43,6 +43,13 @@ function createStatelyEmbed(options) {
|
|
|
43
43
|
const pendingMessages = [];
|
|
44
44
|
const events = createEventRegistry();
|
|
45
45
|
const exportManager = createPendingExportManager((message) => send(message));
|
|
46
|
+
const assetUploadAdapter = options.assets?.adapter;
|
|
47
|
+
const uploadAsset = options.assets?.onUploadRequest ? (file, context) => options.assets.onUploadRequest(file, context) : assetUploadAdapter ? (file, context) => assetUploadAdapter.upload({
|
|
48
|
+
file,
|
|
49
|
+
...context
|
|
50
|
+
}) : void 0;
|
|
51
|
+
const assetAccept = options.assets?.accept ?? assetUploadAdapter?.accept;
|
|
52
|
+
const assetMaxFileSize = options.assets?.maxFileSize ?? assetUploadAdapter?.maxFileSize;
|
|
46
53
|
function send(msg) {
|
|
47
54
|
if (!transport?.ready) {
|
|
48
55
|
pendingMessages.push(msg);
|
|
@@ -63,11 +70,11 @@ function createStatelyEmbed(options) {
|
|
|
63
70
|
case "@statelyai.ready": {
|
|
64
71
|
const ready = data;
|
|
65
72
|
flush();
|
|
66
|
-
if (
|
|
73
|
+
if (uploadAsset) send({
|
|
67
74
|
type: "@statelyai.uploadCapabilities",
|
|
68
75
|
enabled: true,
|
|
69
|
-
accept:
|
|
70
|
-
maxFileSize:
|
|
76
|
+
accept: assetAccept,
|
|
77
|
+
maxFileSize: assetMaxFileSize
|
|
71
78
|
});
|
|
72
79
|
options.onReady?.();
|
|
73
80
|
events.emit("ready", { version: ready.version });
|
|
@@ -129,7 +136,7 @@ function createStatelyEmbed(options) {
|
|
|
129
136
|
}
|
|
130
137
|
case "@statelyai.uploadRequest": {
|
|
131
138
|
const req = data;
|
|
132
|
-
if (!
|
|
139
|
+
if (!uploadAsset) {
|
|
133
140
|
send({
|
|
134
141
|
type: "@statelyai.error",
|
|
135
142
|
requestId: req.requestId,
|
|
@@ -138,7 +145,7 @@ function createStatelyEmbed(options) {
|
|
|
138
145
|
});
|
|
139
146
|
break;
|
|
140
147
|
}
|
|
141
|
-
const maxSize =
|
|
148
|
+
const maxSize = assetMaxFileSize ?? 10485760;
|
|
142
149
|
if (req.file.size > maxSize) {
|
|
143
150
|
send({
|
|
144
151
|
type: "@statelyai.error",
|
|
@@ -151,8 +158,7 @@ function createStatelyEmbed(options) {
|
|
|
151
158
|
const binary = atob(req.file.data);
|
|
152
159
|
const bytes = new Uint8Array(binary.length);
|
|
153
160
|
for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);
|
|
154
|
-
|
|
155
|
-
options.assets.onUploadRequest(file, { stateNodeId: req.stateNodeId }).then((result) => {
|
|
161
|
+
uploadAsset(new File([bytes], req.file.name, { type: req.file.mimeType }), { stateNodeId: req.stateNodeId }).then((result) => {
|
|
156
162
|
send({
|
|
157
163
|
type: "@statelyai.uploadResponse",
|
|
158
164
|
requestId: req.requestId,
|
package/dist/graph.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { _ as studioMachineConverter, a as StatelyGraphData, c as StatelyInvoke, d as StudioAction, f as StudioEdge, g as fromStudioMachine, h as StudioNode, i as StatelyGraph, l as StatelyNodeData, m as StudioMachine, n as StatelyActorImplementation, o as StatelyGuard, p as StudioEventTypeData, r as StatelyEdgeData, s as StatelyImplementation, t as StatelyAction, u as StatelyTagImplementation, v as toStudioMachine } from "./graph-
|
|
1
|
+
import { _ as studioMachineConverter, a as StatelyGraphData, c as StatelyInvoke, d as StudioAction, f as StudioEdge, g as fromStudioMachine, h as StudioNode, i as StatelyGraph, l as StatelyNodeData, m as StudioMachine, n as StatelyActorImplementation, o as StatelyGuard, p as StudioEventTypeData, r as StatelyEdgeData, s as StatelyImplementation, t as StatelyAction, u as StatelyTagImplementation, v as toStudioMachine } from "./graph-DpBGHZwl.mjs";
|
|
2
2
|
export { StatelyAction, StatelyActorImplementation, StatelyEdgeData, StatelyGraph, StatelyGraphData, StatelyGuard, StatelyImplementation, StatelyInvoke, StatelyNodeData, StatelyTagImplementation, StudioAction, StudioEdge, StudioEventTypeData, StudioMachine, StudioNode, fromStudioMachine, studioMachineConverter, toStudioMachine };
|
package/dist/graph.mjs
CHANGED
|
@@ -2,8 +2,12 @@ import { createFormatConverter, createGraph } from "@statelyai/graph";
|
|
|
2
2
|
|
|
3
3
|
//#region src/graph.ts
|
|
4
4
|
const EXPR_ACTION_TYPE = "xstate.expr";
|
|
5
|
+
function stripMarkdownLinks(code) {
|
|
6
|
+
return code.replace(/\[([^\]\n]+)\]\(([^)\n]+)\)/g, "$1");
|
|
7
|
+
}
|
|
5
8
|
function stripExportDefault(code) {
|
|
6
|
-
|
|
9
|
+
const normalized = stripMarkdownLinks(code).trim();
|
|
10
|
+
return normalized.match(/^export\s+default\s+(.+)/s)?.[1]?.trim() ?? normalized;
|
|
7
11
|
}
|
|
8
12
|
function toJsonObject(value) {
|
|
9
13
|
return value;
|
|
@@ -332,7 +336,7 @@ function fromStudioMachine(studioMachine) {
|
|
|
332
336
|
...edge.data.guard ? { guard: {
|
|
333
337
|
type: edge.data.guard.type,
|
|
334
338
|
params: toUnknownRecord(edge.data.guard.params),
|
|
335
|
-
...edge.data.guard.kind === "inline" ? { code: edge.data.guard.type } : {}
|
|
339
|
+
...edge.data.guard.kind === "inline" ? { code: stripExportDefault(studioMachine.implementations?.guards?.[edge.data.guard.type]?.code ?? edge.data.guard.type) } : {}
|
|
336
340
|
} } : {},
|
|
337
341
|
actions: edge.data.actions.map((action) => fromStudioAction(action, studioMachine.implementations?.actions)),
|
|
338
342
|
...edge.data.description ? { description: edge.data.description } : {},
|
|
@@ -350,9 +354,9 @@ function fromStudioMachine(studioMachine) {
|
|
|
350
354
|
data: {
|
|
351
355
|
...studioMachine.schemas ? { schemas: studioMachine.schemas } : {},
|
|
352
356
|
...studioMachine.implementations ? { implementations: {
|
|
353
|
-
actions: Object.
|
|
354
|
-
guards: Object.
|
|
355
|
-
actors: Object.
|
|
357
|
+
actions: Object.entries(studioMachine.implementations.actions).filter(([key]) => !key.startsWith("inline:")).map(([, source]) => fromActionSource(source)),
|
|
358
|
+
guards: Object.entries(studioMachine.implementations.guards).filter(([key]) => !key.startsWith("inline:")).map(([, guard]) => fromGuardSource(guard)),
|
|
359
|
+
actors: Object.entries(studioMachine.implementations.actors).filter(([key]) => !key.startsWith("inline:") && !/:invocation\[\d+\]$/.test(key)).map(([, actor]) => fromActorSource(actor)),
|
|
356
360
|
delays: [],
|
|
357
361
|
tags: []
|
|
358
362
|
} } : {}
|