@statelyai/sdk 0.4.0 → 0.5.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/LICENSE +7 -675
- package/README.md +290 -159
- package/dist/cli.d.mts +24 -5
- package/dist/cli.mjs +79 -18
- package/dist/embed.d.mts +5 -3
- package/dist/embed.mjs +30 -10
- package/dist/graph.mjs +27 -19
- package/dist/{graphToXStateTS-C6HQUrBB.mjs → graphToXStateTS-BSUj97r0.mjs} +46 -19
- package/dist/index.d.mts +5 -34
- package/dist/index.mjs +2 -2
- package/dist/inspect-WUC2inmJ.d.mts +206 -0
- package/dist/inspect.d.mts +3 -49
- package/dist/inspect.mjs +229 -62
- package/dist/patchTypes.d.mts +225 -0
- package/dist/patchTypes.mjs +1 -0
- package/dist/protocol-B1cNV7QB.d.mts +397 -0
- package/dist/sync.mjs +1 -1
- package/dist/{transport-C1fRAuv-.mjs → transport-lomH7b0v.mjs} +14 -13
- package/package.json +14 -5
- package/dist/protocol-BgXSkIuc.d.mts +0 -221
package/dist/cli.mjs
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { planSync, pullSync } from "./sync.mjs";
|
|
3
3
|
import path from "node:path";
|
|
4
|
+
import fs from "node:fs";
|
|
5
|
+
import { fileURLToPath } from "node:url";
|
|
4
6
|
import { Args, Command, Flags, flush, handle, run as run$1 } from "@oclif/core";
|
|
7
|
+
import { openEditor } from "@statelyai/editor-sync/cli-host";
|
|
5
8
|
|
|
6
9
|
//#region src/cli.ts
|
|
7
10
|
function loadLocalEnv() {
|
|
@@ -12,20 +15,23 @@ function loadLocalEnv() {
|
|
|
12
15
|
} catch {}
|
|
13
16
|
}
|
|
14
17
|
loadLocalEnv();
|
|
18
|
+
function getDefaultApiKey() {
|
|
19
|
+
return process.env.STATELY_API_KEY ?? process.env.NEXT_PUBLIC_STATELY_API_KEY;
|
|
20
|
+
}
|
|
21
|
+
function getDefaultBaseUrl() {
|
|
22
|
+
return process.env.STATELY_API_URL ?? process.env.NEXT_PUBLIC_BASE_URL ?? process.env.NEXT_PUBLIC_STATELY_API_URL;
|
|
23
|
+
}
|
|
24
|
+
function getDefaultEditorUrl() {
|
|
25
|
+
return process.env.STATELY_EDITOR_URL ?? process.env.NEXT_PUBLIC_BETA_EDITOR_URL ?? process.env.NEXT_PUBLIC_BASE_URL ?? "http://localhost:3001";
|
|
26
|
+
}
|
|
15
27
|
const sharedFlags = {
|
|
16
28
|
help: Flags.help({ char: "h" }),
|
|
17
29
|
"fail-on-changes": Flags.boolean({
|
|
18
30
|
default: false,
|
|
19
31
|
description: "Exit with a nonzero code when differences are found"
|
|
20
32
|
}),
|
|
21
|
-
"api-key": Flags.string({
|
|
22
|
-
|
|
23
|
-
default: process.env.STATELY_API_KEY ?? process.env.NEXT_PUBLIC_STATELY_API_KEY
|
|
24
|
-
}),
|
|
25
|
-
"base-url": Flags.string({
|
|
26
|
-
description: "Base URL for Stately Studio or a self-hosted deployment",
|
|
27
|
-
default: process.env.STATELY_API_URL ?? process.env.NEXT_PUBLIC_BASE_URL ?? process.env.NEXT_PUBLIC_STATELY_API_URL
|
|
28
|
-
})
|
|
33
|
+
"api-key": Flags.string({ description: "Stately API key used for remote source or target resolution" }),
|
|
34
|
+
"base-url": Flags.string({ description: "Base URL for Stately Studio or a self-hosted deployment" })
|
|
29
35
|
};
|
|
30
36
|
function formatChangeList(label, items) {
|
|
31
37
|
if (items.length === 0) return null;
|
|
@@ -82,8 +88,8 @@ var PlanCommand = class PlanCommand extends ParsedSyncCommand {
|
|
|
82
88
|
const plan = await planSync({
|
|
83
89
|
source: args.source,
|
|
84
90
|
target: args.target,
|
|
85
|
-
apiKey: flags["api-key"],
|
|
86
|
-
baseUrl: flags["base-url"]
|
|
91
|
+
apiKey: flags["api-key"] ?? getDefaultApiKey(),
|
|
92
|
+
baseUrl: flags["base-url"] ?? getDefaultBaseUrl()
|
|
87
93
|
});
|
|
88
94
|
this.log(formatPlanSummary(plan));
|
|
89
95
|
this.exit(flags["fail-on-changes"] && plan.summary.hasChanges ? 1 : 0);
|
|
@@ -98,8 +104,8 @@ var DiffCommand = class DiffCommand extends ParsedSyncCommand {
|
|
|
98
104
|
const plan = await planSync({
|
|
99
105
|
source: args.source,
|
|
100
106
|
target: args.target,
|
|
101
|
-
apiKey: flags["api-key"],
|
|
102
|
-
baseUrl: flags["base-url"]
|
|
107
|
+
apiKey: flags["api-key"] ?? getDefaultApiKey(),
|
|
108
|
+
baseUrl: flags["base-url"] ?? getDefaultBaseUrl()
|
|
103
109
|
});
|
|
104
110
|
this.log(formatPlanSummary(plan));
|
|
105
111
|
this.exit(flags["fail-on-changes"] && plan.summary.hasChanges ? 1 : 0);
|
|
@@ -114,27 +120,82 @@ var PullCommand = class PullCommand extends ParsedSyncCommand {
|
|
|
114
120
|
const result = await pullSync({
|
|
115
121
|
source: args.source,
|
|
116
122
|
target: args.target,
|
|
117
|
-
apiKey: flags["api-key"],
|
|
118
|
-
baseUrl: flags["base-url"]
|
|
123
|
+
apiKey: flags["api-key"] ?? getDefaultApiKey(),
|
|
124
|
+
baseUrl: flags["base-url"] ?? getDefaultBaseUrl()
|
|
119
125
|
});
|
|
120
126
|
this.log(`Pulled: ${result.source.locator} -> ${result.outputPath}\nTarget: ${result.target.kind} (${result.target.format})`);
|
|
121
127
|
}
|
|
122
128
|
};
|
|
129
|
+
var OpenCommand = class OpenCommand extends Command {
|
|
130
|
+
static enableJsonFlag = false;
|
|
131
|
+
static summary = "Open a local file in the Stately visual editor.";
|
|
132
|
+
static description = "Starts a local browser-backed editor session. Saved file changes update the visual editor, and saved visual edits are written back to the source file.";
|
|
133
|
+
static args = { file: Args.string({
|
|
134
|
+
required: true,
|
|
135
|
+
description: "Local source file to edit visually."
|
|
136
|
+
}) };
|
|
137
|
+
static flags = {
|
|
138
|
+
help: Flags.help({ char: "h" }),
|
|
139
|
+
"api-key": Flags.string({ description: "Stately API key used by the embedded editor" }),
|
|
140
|
+
"editor-url": Flags.string({ description: "Base URL for the Stately editor embed" }),
|
|
141
|
+
host: Flags.string({
|
|
142
|
+
description: "Local server host",
|
|
143
|
+
default: "127.0.0.1"
|
|
144
|
+
}),
|
|
145
|
+
port: Flags.integer({
|
|
146
|
+
description: "Local server port. Defaults to a random available port.",
|
|
147
|
+
default: 0,
|
|
148
|
+
min: 0
|
|
149
|
+
}),
|
|
150
|
+
open: Flags.boolean({
|
|
151
|
+
description: "Open the local editor URL in the default browser",
|
|
152
|
+
default: true,
|
|
153
|
+
allowNo: true
|
|
154
|
+
}),
|
|
155
|
+
debug: Flags.boolean({
|
|
156
|
+
description: "Log editor protocol messages",
|
|
157
|
+
default: false
|
|
158
|
+
})
|
|
159
|
+
};
|
|
160
|
+
async run() {
|
|
161
|
+
const { args, flags } = await this.parse(OpenCommand);
|
|
162
|
+
await openEditor({
|
|
163
|
+
fileName: path.resolve(args.file),
|
|
164
|
+
editorUrl: flags["editor-url"] ?? getDefaultEditorUrl(),
|
|
165
|
+
host: flags.host,
|
|
166
|
+
port: flags.port,
|
|
167
|
+
shouldOpen: flags.open,
|
|
168
|
+
apiKey: flags["api-key"] ?? getDefaultApiKey(),
|
|
169
|
+
debug: flags.debug
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
};
|
|
123
173
|
const COMMANDS = {
|
|
124
174
|
plan: PlanCommand,
|
|
125
175
|
diff: DiffCommand,
|
|
126
|
-
pull: PullCommand
|
|
176
|
+
pull: PullCommand,
|
|
177
|
+
open: OpenCommand
|
|
127
178
|
};
|
|
128
|
-
async function run(argv = process.argv.slice(2)) {
|
|
179
|
+
async function run(argv = process.argv.slice(2), entryUrl = import.meta.url) {
|
|
129
180
|
const normalizedArgv = argv.length === 1 && argv[0] === "-h" ? ["--help"] : argv;
|
|
130
181
|
try {
|
|
131
|
-
await run$1(normalizedArgv,
|
|
182
|
+
await run$1(normalizedArgv, entryUrl);
|
|
132
183
|
await flush();
|
|
133
184
|
} catch (error) {
|
|
134
185
|
await handle(error);
|
|
135
186
|
}
|
|
136
187
|
}
|
|
137
|
-
|
|
188
|
+
function isDirectExecution() {
|
|
189
|
+
const entryPath = process.argv[1];
|
|
190
|
+
if (!entryPath) return false;
|
|
191
|
+
const modulePath = fileURLToPath(import.meta.url);
|
|
192
|
+
try {
|
|
193
|
+
return fs.realpathSync(entryPath) === fs.realpathSync(modulePath);
|
|
194
|
+
} catch {
|
|
195
|
+
return path.resolve(entryPath) === modulePath;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
if (isDirectExecution()) run();
|
|
138
199
|
|
|
139
200
|
//#endregion
|
|
140
201
|
export { COMMANDS, formatPlanSummary, run };
|
package/dist/embed.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as EmbedMode, c as ExportFormatMap,
|
|
1
|
+
import { a as EmbedMode, c as ExportFormatMap, f as UploadResult, i as EmbedEventName, l as InitOptions, n as EmbedEventHandler, o as ExportCallOptions, r as EmbedEventMap, s as ExportFormat, t as CommentsConfig, u as MachineSourceLocations } from "./protocol-B1cNV7QB.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/embed.d.ts
|
|
4
4
|
interface AssetConfig {
|
|
@@ -44,11 +44,13 @@ interface StatelyEmbed {
|
|
|
44
44
|
/** Send init message (queued if iframe not ready yet). */
|
|
45
45
|
init(options: InitOptions): void;
|
|
46
46
|
/** Update the machine (shorthand for update message). */
|
|
47
|
-
updateMachine(machine: unknown, format?: string): void;
|
|
47
|
+
updateMachine(machine: unknown, format?: string, sourceLocations?: MachineSourceLocations): void;
|
|
48
48
|
/** Change the embed mode. */
|
|
49
49
|
setMode(mode: EmbedMode): void;
|
|
50
50
|
/** Change the embed theme. */
|
|
51
51
|
setTheme(theme: 'light' | 'dark'): void;
|
|
52
|
+
/** Update editor settings. Merges with existing settings. */
|
|
53
|
+
setSettings(settings: Record<string, unknown>): void;
|
|
52
54
|
/** Export the current machine in a given format. Returns a promise. */
|
|
53
55
|
export<F extends ExportFormat>(format: F, options?: ExportCallOptions<F>): Promise<ExportFormatMap[F]['result']>;
|
|
54
56
|
/** Subscribe to an embed event. */
|
|
@@ -62,4 +64,4 @@ interface StatelyEmbed {
|
|
|
62
64
|
}
|
|
63
65
|
declare function createStatelyEmbed(options: StatelyEmbedOptions): StatelyEmbed;
|
|
64
66
|
//#endregion
|
|
65
|
-
export { AssetConfig, type CommentsConfig, type EmbedEventHandler, type EmbedEventMap, type EmbedEventName, type EmbedMode, type ExportCallOptions, type ExportFormat, type ExportFormatMap, type InitOptions, StatelyEmbed, StatelyEmbedOptions, type UploadResult, createStatelyEmbed };
|
|
67
|
+
export { AssetConfig, type CommentsConfig, type EmbedEventHandler, type EmbedEventMap, type EmbedEventName, type EmbedMode, type ExportCallOptions, type ExportFormat, type ExportFormatMap, type InitOptions, type MachineSourceLocations, StatelyEmbed, StatelyEmbedOptions, type UploadResult, createStatelyEmbed };
|
package/dist/embed.mjs
CHANGED
|
@@ -1,10 +1,15 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { a as toInitMessage, i as createPendingExportManager, r as createEventRegistry, t as createPostMessageTransport } from "./transport-lomH7b0v.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/embed.ts
|
|
4
|
-
function
|
|
4
|
+
function buildEmbedUrl(options) {
|
|
5
5
|
const base = options.baseUrl.replace(/\/+$/, "") + "/embed";
|
|
6
|
-
const
|
|
7
|
-
|
|
6
|
+
const url = new URL(base);
|
|
7
|
+
if (options.apiKey) url.searchParams.set("api_key", options.apiKey);
|
|
8
|
+
return url.toString();
|
|
9
|
+
}
|
|
10
|
+
function createStatelyEmbed(options) {
|
|
11
|
+
const embedUrl = buildEmbedUrl(options);
|
|
12
|
+
const targetOrigin = options.origin ?? "*";
|
|
8
13
|
let iframe = null;
|
|
9
14
|
let transport = null;
|
|
10
15
|
let ownedIframe = false;
|
|
@@ -45,7 +50,10 @@ function createStatelyEmbed(options) {
|
|
|
45
50
|
case "@statelyai.loaded": {
|
|
46
51
|
const loaded = data;
|
|
47
52
|
options.onLoaded?.(loaded.graph);
|
|
48
|
-
events.emit("loaded", {
|
|
53
|
+
events.emit("loaded", {
|
|
54
|
+
graph: loaded.graph,
|
|
55
|
+
sourceLocations: loaded.sourceLocations
|
|
56
|
+
});
|
|
49
57
|
break;
|
|
50
58
|
}
|
|
51
59
|
case "@statelyai.change": {
|
|
@@ -53,7 +61,9 @@ function createStatelyEmbed(options) {
|
|
|
53
61
|
options.onChange?.(change.graph, change.machineConfig);
|
|
54
62
|
events.emit("change", {
|
|
55
63
|
graph: change.graph,
|
|
56
|
-
machineConfig: change.machineConfig
|
|
64
|
+
machineConfig: change.machineConfig,
|
|
65
|
+
patches: change.patches,
|
|
66
|
+
sourceLocations: change.sourceLocations
|
|
57
67
|
});
|
|
58
68
|
break;
|
|
59
69
|
}
|
|
@@ -62,7 +72,10 @@ function createStatelyEmbed(options) {
|
|
|
62
72
|
options.onSave?.(save.graph, save.machineConfig);
|
|
63
73
|
events.emit("save", {
|
|
64
74
|
graph: save.graph,
|
|
65
|
-
machineConfig: save.machineConfig
|
|
75
|
+
machineConfig: save.machineConfig,
|
|
76
|
+
patches: save.patches,
|
|
77
|
+
validations: save.validations,
|
|
78
|
+
sourceLocations: save.sourceLocations
|
|
66
79
|
});
|
|
67
80
|
break;
|
|
68
81
|
}
|
|
@@ -158,7 +171,7 @@ function createStatelyEmbed(options) {
|
|
|
158
171
|
el.style.border = "none";
|
|
159
172
|
el.style.width = "100%";
|
|
160
173
|
el.style.height = "100%";
|
|
161
|
-
el.setAttribute("sandbox", "allow-scripts allow-same-origin");
|
|
174
|
+
el.setAttribute("sandbox", "allow-scripts allow-same-origin allow-forms allow-popups allow-popups-to-escape-sandbox");
|
|
162
175
|
el.setAttribute("allow", "clipboard-read; clipboard-write");
|
|
163
176
|
container.appendChild(el);
|
|
164
177
|
iframe = el;
|
|
@@ -169,11 +182,12 @@ function createStatelyEmbed(options) {
|
|
|
169
182
|
init(opts) {
|
|
170
183
|
send(toInitMessage(opts));
|
|
171
184
|
},
|
|
172
|
-
updateMachine(machine, format) {
|
|
185
|
+
updateMachine(machine, format, sourceLocations) {
|
|
173
186
|
send({
|
|
174
187
|
type: "@statelyai.update",
|
|
175
188
|
machine,
|
|
176
|
-
format
|
|
189
|
+
format,
|
|
190
|
+
sourceLocations
|
|
177
191
|
});
|
|
178
192
|
},
|
|
179
193
|
setMode(mode) {
|
|
@@ -188,6 +202,12 @@ function createStatelyEmbed(options) {
|
|
|
188
202
|
theme
|
|
189
203
|
});
|
|
190
204
|
},
|
|
205
|
+
setSettings(settings) {
|
|
206
|
+
send({
|
|
207
|
+
type: "@statelyai.setSettings",
|
|
208
|
+
settings
|
|
209
|
+
});
|
|
210
|
+
},
|
|
191
211
|
toast(message, toastType) {
|
|
192
212
|
send({
|
|
193
213
|
type: "@statelyai.toast",
|
package/dist/graph.mjs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { createFormatConverter, createGraph } from "@statelyai/graph";
|
|
2
2
|
|
|
3
3
|
//#region src/graph.ts
|
|
4
|
+
const EXPR_ACTION_TYPE = "xstate.expr";
|
|
4
5
|
function toJsonObject(value) {
|
|
5
6
|
return value;
|
|
6
7
|
}
|
|
@@ -31,17 +32,17 @@ function normalizeStudioHistory(history) {
|
|
|
31
32
|
if (history === true) return "shallow";
|
|
32
33
|
return history || void 0;
|
|
33
34
|
}
|
|
34
|
-
function toActionSource(
|
|
35
|
+
function toActionSource(implementation) {
|
|
35
36
|
return {
|
|
36
37
|
type: "action",
|
|
37
|
-
id:
|
|
38
|
-
name:
|
|
39
|
-
...
|
|
40
|
-
...
|
|
41
|
-
lang:
|
|
38
|
+
id: implementation.id,
|
|
39
|
+
name: implementation.name,
|
|
40
|
+
...implementation.description ? { description: implementation.description } : {},
|
|
41
|
+
...implementation.icon ? { icon: implementation.icon } : {},
|
|
42
|
+
lang: implementation.code?.lang ?? "js",
|
|
42
43
|
imports: [],
|
|
43
|
-
code:
|
|
44
|
-
...
|
|
44
|
+
code: implementation.code?.body,
|
|
45
|
+
...implementation.paramsSchema ? { paramsSchema: implementation.paramsSchema } : {}
|
|
45
46
|
};
|
|
46
47
|
}
|
|
47
48
|
function toGuardSource(guard) {
|
|
@@ -72,16 +73,16 @@ function toActorSource(actor) {
|
|
|
72
73
|
...actor.outputSchema ? { outputSchema: actor.outputSchema } : {}
|
|
73
74
|
};
|
|
74
75
|
}
|
|
75
|
-
function fromActionSource(
|
|
76
|
+
function fromActionSource(source) {
|
|
76
77
|
return {
|
|
77
|
-
id:
|
|
78
|
-
name:
|
|
79
|
-
description:
|
|
80
|
-
...
|
|
81
|
-
paramsSchema:
|
|
82
|
-
...
|
|
83
|
-
body:
|
|
84
|
-
...
|
|
78
|
+
id: source.id,
|
|
79
|
+
name: source.name,
|
|
80
|
+
description: source.description ?? null,
|
|
81
|
+
...source.icon ? { icon: source.icon } : {},
|
|
82
|
+
paramsSchema: source.paramsSchema ?? null,
|
|
83
|
+
...source.code ? { code: {
|
|
84
|
+
body: source.code,
|
|
85
|
+
...source.lang ? { lang: source.lang } : {}
|
|
85
86
|
} } : {}
|
|
86
87
|
};
|
|
87
88
|
}
|
|
@@ -113,6 +114,10 @@ function fromActorSource(actor) {
|
|
|
113
114
|
};
|
|
114
115
|
}
|
|
115
116
|
function toStudioAction(action) {
|
|
117
|
+
if (action.type === EXPR_ACTION_TYPE && typeof action.params?.code === "string") return {
|
|
118
|
+
kind: "inline",
|
|
119
|
+
action: { expr: action.params.code }
|
|
120
|
+
};
|
|
116
121
|
return {
|
|
117
122
|
kind: "named",
|
|
118
123
|
action: {
|
|
@@ -123,8 +128,11 @@ function toStudioAction(action) {
|
|
|
123
128
|
}
|
|
124
129
|
function fromStudioAction(action) {
|
|
125
130
|
if (action.kind === "inline") return {
|
|
126
|
-
type:
|
|
127
|
-
params: {
|
|
131
|
+
type: EXPR_ACTION_TYPE,
|
|
132
|
+
params: {
|
|
133
|
+
code: action.action.expr,
|
|
134
|
+
lang: "ts"
|
|
135
|
+
}
|
|
128
136
|
};
|
|
129
137
|
if ("params" in action.action && action.action.params) return {
|
|
130
138
|
type: action.action.type,
|
|
@@ -84,14 +84,17 @@ function stripExportDefault(code) {
|
|
|
84
84
|
|
|
85
85
|
//#endregion
|
|
86
86
|
//#region src/graphToMachineConfig.ts
|
|
87
|
-
function
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
return
|
|
87
|
+
function isAutoGeneratedId(id) {
|
|
88
|
+
return !!id && id.startsWith("$auto-");
|
|
89
|
+
}
|
|
90
|
+
function getSerializedNodeId(node) {
|
|
91
|
+
return node.data.nodeId ?? void 0;
|
|
92
|
+
}
|
|
93
|
+
function getDefaultNodeId(graph, node) {
|
|
94
|
+
if (!node.parentId) return "(machine)";
|
|
95
|
+
const parentNode = graph.nodes.find((candidate) => candidate.id === node.parentId);
|
|
96
|
+
if (!parentNode) return `${node.parentId}.${node.data.key}`;
|
|
97
|
+
return `${getSerializedNodeId(parentNode) ?? getDefaultNodeId(graph, parentNode)}.${node.data.key}`;
|
|
95
98
|
}
|
|
96
99
|
/** Unwrap single-element arrays to a single value (XState single-or-array convention) */
|
|
97
100
|
function singleOrArray(arr) {
|
|
@@ -169,6 +172,7 @@ function formatEventParam(event) {
|
|
|
169
172
|
*/
|
|
170
173
|
function serializeActionItem(action) {
|
|
171
174
|
const { type, params } = action;
|
|
175
|
+
const exprCode = type === "xstate.expr" && typeof params?.code === "string" ? params.code : void 0;
|
|
172
176
|
switch (type) {
|
|
173
177
|
case "xstate.raise": {
|
|
174
178
|
const eventStr = formatEventParam(params?.event);
|
|
@@ -196,9 +200,14 @@ function serializeActionItem(action) {
|
|
|
196
200
|
}
|
|
197
201
|
case "xstate.stopChild": return raw(`stopChild(${params?.actorRef ? `'${params.actorRef}'` : `'unknown'`})`);
|
|
198
202
|
case "xstate.log": return raw(`log(${(params?.label ? `'${params.label}'` : void 0) ?? ""})`);
|
|
199
|
-
case "xstate.assign":
|
|
203
|
+
case "xstate.assign": {
|
|
204
|
+
const assignments = params?.assignment && typeof params.assignment === "object" && !Array.isArray(params.assignment) ? params.assignment : params;
|
|
205
|
+
const entries = Object.entries(assignments ?? {}).filter(([k, v]) => k && v !== void 0);
|
|
206
|
+
if (entries.length === 0) return raw(`assign({ /* ... */ })`);
|
|
207
|
+
return raw(`assign({ ${entries.map(([k, v]) => `${JSON.stringify(k)}: ${formatAssignValue(v)}`).join(", ")} })`);
|
|
208
|
+
}
|
|
200
209
|
default:
|
|
201
|
-
if (
|
|
210
|
+
if (exprCode) return raw(stripExportDefault(exprCode));
|
|
202
211
|
if (!params || Object.keys(params).length === 0) return { type };
|
|
203
212
|
return {
|
|
204
213
|
type,
|
|
@@ -206,6 +215,12 @@ function serializeActionItem(action) {
|
|
|
206
215
|
};
|
|
207
216
|
}
|
|
208
217
|
}
|
|
218
|
+
function formatAssignValue(value) {
|
|
219
|
+
if (typeof value !== "string") return JSON.stringify(value);
|
|
220
|
+
const templateExpression = value.match(/^\{\{([\s\S]*)\}\}$/);
|
|
221
|
+
if (templateExpression) return templateExpression[1];
|
|
222
|
+
return JSON.stringify(value);
|
|
223
|
+
}
|
|
209
224
|
/** Normalize tag to string — handles both `string` and `{ name: string }` */
|
|
210
225
|
function tagToString(tag) {
|
|
211
226
|
return typeof tag === "string" ? tag : tag.name;
|
|
@@ -215,8 +230,10 @@ function graphToMachineConfig(graph, options = {}) {
|
|
|
215
230
|
const config = {};
|
|
216
231
|
function getNodeConfig(node) {
|
|
217
232
|
const nodeConfig = node.parentId ? {} : config;
|
|
218
|
-
const
|
|
219
|
-
const
|
|
233
|
+
const isRoot = !node.parentId;
|
|
234
|
+
const authoredNodeId = getSerializedNodeId(node) ?? (isRoot ? graph.id : void 0);
|
|
235
|
+
const defaultNodeId = getDefaultNodeId(graph, node);
|
|
236
|
+
const resolvedNodeId = isAutoGeneratedId(authoredNodeId) ? void 0 : isRoot ? authoredNodeId : defaultNodeId === authoredNodeId ? void 0 : authoredNodeId;
|
|
220
237
|
const initialNode = node.data.initialId ? graph.nodes.find((n) => n.id === node.data.initialId) : null;
|
|
221
238
|
const nodeType = [
|
|
222
239
|
"final",
|
|
@@ -252,7 +269,7 @@ function graphToMachineConfig(graph, options = {}) {
|
|
|
252
269
|
const targetNode = graph.nodes.find((n) => n.id === edge.targetId);
|
|
253
270
|
const resolvedTarget = targetNode ? targetNode.parentId === node.parentId ? targetNode.data.key : `#${targetNode.id}` : "";
|
|
254
271
|
const type = edge.data.eventType ?? "";
|
|
255
|
-
const transitionMeta = buildMeta(edge.data.meta, edge.data.color);
|
|
272
|
+
const transitionMeta = showMeta ? buildMeta(edge.data.meta, edge.data.color) : void 0;
|
|
256
273
|
const transitionObject = {
|
|
257
274
|
target: `${resolvedTarget}`,
|
|
258
275
|
...edge.data.transitionType === "reenter" ? { reenter: true } : void 0,
|
|
@@ -303,6 +320,11 @@ function graphToMachineConfig(graph, options = {}) {
|
|
|
303
320
|
};
|
|
304
321
|
});
|
|
305
322
|
}
|
|
323
|
+
if (Array.isArray(nodeConfig.invoke)) nodeConfig.invoke = nodeConfig.invoke.map((inv) => {
|
|
324
|
+
if (!isAutoGeneratedId(inv.id)) return inv;
|
|
325
|
+
const { id: _id, ...rest } = inv;
|
|
326
|
+
return rest;
|
|
327
|
+
});
|
|
306
328
|
if (childNodes.length > 0) {
|
|
307
329
|
nodeConfig.states = {};
|
|
308
330
|
for (const childState of childNodes) nodeConfig.states[childState.data.key] = getNodeConfig(childState);
|
|
@@ -442,17 +464,22 @@ function scanInlineCodeForBuiltins(code, used) {
|
|
|
442
464
|
const expr = stripExportDefault(code);
|
|
443
465
|
for (const importName of Object.values(BUILTIN_ACTION_IMPORTS)) if (new RegExp(`\\b${importName}\\b`).test(expr)) used.add(importName);
|
|
444
466
|
}
|
|
467
|
+
function getExprActionCode(action) {
|
|
468
|
+
return action.type === "xstate.expr" && typeof action.params?.code === "string" ? action.params.code : void 0;
|
|
469
|
+
}
|
|
445
470
|
function getUsedBuiltInActions(graph) {
|
|
446
471
|
const used = /* @__PURE__ */ new Set();
|
|
447
472
|
for (const node of graph.nodes) for (const action of [...node.data.entry ?? [], ...node.data.exit ?? []]) {
|
|
448
473
|
const imp = BUILTIN_ACTION_IMPORTS[action.type];
|
|
449
474
|
if (imp) used.add(imp);
|
|
450
|
-
|
|
475
|
+
const exprCode = getExprActionCode(action);
|
|
476
|
+
if (exprCode) scanInlineCodeForBuiltins(exprCode, used);
|
|
451
477
|
}
|
|
452
478
|
for (const edge of graph.edges) for (const action of edge.data.actions ?? []) {
|
|
453
479
|
const imp = BUILTIN_ACTION_IMPORTS[action.type];
|
|
454
480
|
if (imp) used.add(imp);
|
|
455
|
-
|
|
481
|
+
const exprCode = getExprActionCode(action);
|
|
482
|
+
if (exprCode) scanInlineCodeForBuiltins(exprCode, used);
|
|
456
483
|
}
|
|
457
484
|
return used;
|
|
458
485
|
}
|
|
@@ -497,10 +524,10 @@ function hasSchemaProperties(schema) {
|
|
|
497
524
|
}
|
|
498
525
|
function buildActionsBlock(actions) {
|
|
499
526
|
const block = {};
|
|
500
|
-
for (const
|
|
501
|
-
const params = hasSchemaProperties(
|
|
502
|
-
block[
|
|
503
|
-
} else block[
|
|
527
|
+
for (const implementation of actions) if (implementation.code?.body) {
|
|
528
|
+
const params = hasSchemaProperties(implementation.paramsSchema) ? `, params: ${jsonSchemaToTSType(implementation.paramsSchema)}` : "";
|
|
529
|
+
block[implementation.name] = raw(`function ({ context, event }${params ? params : ""}) {\n ${dedent(implementation.code.body)}\n}`);
|
|
530
|
+
} else block[implementation.name] = raw(`function ({ context, event }) {\n // TODO: implement ${implementation.name}\n}`);
|
|
504
531
|
return block;
|
|
505
532
|
}
|
|
506
533
|
function buildGuardsBlock(guards) {
|
package/dist/index.d.mts
CHANGED
|
@@ -1,47 +1,17 @@
|
|
|
1
1
|
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-BfezxFKJ.mjs";
|
|
2
2
|
import { a as ProjectMachine, c as StudioClientOptions, i as ProjectData, l as VerifyApiKeyResponse, n as ExtractedMachine, o as StudioApiError, r as GetMachineOptions, s as StudioClient, t as ExtractMachinesResponse, u as createStatelyClient } from "./studio-D2uQhrvX.mjs";
|
|
3
3
|
import { PlanSyncOptions, PullSyncResult, ResolvedSyncInput, SyncInputFormat, SyncPlan, SyncPlanSummary } from "./sync.mjs";
|
|
4
|
-
import { a as EmbedMode, c as ExportFormatMap,
|
|
4
|
+
import { a as EmbedMode, c as ExportFormatMap, f as UploadResult, i as EmbedEventName, l as InitOptions, n as EmbedEventHandler, o as ExportCallOptions, r as EmbedEventMap, s as ExportFormat, t as CommentsConfig } from "./protocol-B1cNV7QB.mjs";
|
|
5
5
|
import { AssetConfig, StatelyEmbed, StatelyEmbedOptions, createStatelyEmbed } from "./embed.mjs";
|
|
6
|
-
import { CreateInspectorOptions,
|
|
6
|
+
import { a as ManualActorOptions, c as createPostMessageTransport, i as InspectorEvents, l as createWebSocketTransport, n as CreateInspectorOptions, o as createStatelyInspector, r as Inspector, s as Transport, t as AdoptedActor } from "./inspect-WUC2inmJ.mjs";
|
|
7
|
+
import { ActionLocation, GraphPatch } from "./patchTypes.mjs";
|
|
7
8
|
import { JSONSchema7 } from "json-schema";
|
|
8
9
|
import { UnknownMachineConfig } from "xstate";
|
|
9
10
|
|
|
10
|
-
//#region src/transport.d.ts
|
|
11
|
-
interface Transport {
|
|
12
|
-
send(msg: ProtocolMessage): void;
|
|
13
|
-
onMessage(handler: (msg: ProtocolMessage) => void): () => void;
|
|
14
|
-
destroy(): void;
|
|
15
|
-
readonly ready: boolean;
|
|
16
|
-
onReady(handler: () => void): () => void;
|
|
17
|
-
}
|
|
18
|
-
interface PostMessageTransportOptions {
|
|
19
|
-
iframe: HTMLIFrameElement;
|
|
20
|
-
targetOrigin: string;
|
|
21
|
-
/** Filter by source. Defaults to iframe.contentWindow. */
|
|
22
|
-
source?: Window;
|
|
23
|
-
}
|
|
24
|
-
declare function createPostMessageTransport(options: PostMessageTransportOptions): Transport;
|
|
25
|
-
interface WebSocketTransportOptions {
|
|
26
|
-
url: string;
|
|
27
|
-
role: 'client' | 'viz';
|
|
28
|
-
sessionId: string;
|
|
29
|
-
metadata?: {
|
|
30
|
-
name?: string;
|
|
31
|
-
machineId?: string;
|
|
32
|
-
};
|
|
33
|
-
/** Reconnect on disconnect. Default true. */
|
|
34
|
-
reconnect?: boolean;
|
|
35
|
-
/** Max reconnect attempts. Default 10. */
|
|
36
|
-
maxReconnectAttempts?: number;
|
|
37
|
-
}
|
|
38
|
-
declare function createWebSocketTransport(options: WebSocketTransportOptions): Transport;
|
|
39
|
-
//#endregion
|
|
40
11
|
//#region src/codegenTypes.d.ts
|
|
41
12
|
interface CodeGenAction {
|
|
42
13
|
type: string;
|
|
43
14
|
params?: Record<string, unknown>;
|
|
44
|
-
code?: string;
|
|
45
15
|
}
|
|
46
16
|
interface CodeGenGuard {
|
|
47
17
|
type: string;
|
|
@@ -54,6 +24,7 @@ interface CodeGenInvoke {
|
|
|
54
24
|
input?: unknown;
|
|
55
25
|
}
|
|
56
26
|
interface CodeGenNodeData {
|
|
27
|
+
nodeId?: string | null;
|
|
57
28
|
key: string;
|
|
58
29
|
type?: 'normal' | 'parallel' | 'final' | 'history' | null;
|
|
59
30
|
initialId?: string | null;
|
|
@@ -176,4 +147,4 @@ declare function contextSchemaToTSType(context: Record<string, JSONSchema7> | nu
|
|
|
176
147
|
*/
|
|
177
148
|
declare function eventsSchemaToTSType(events: Record<string, JSONSchema7> | null | undefined): string | null;
|
|
178
149
|
//#endregion
|
|
179
|
-
export { type AssetConfig, type CodeGenGraph, type CommentsConfig, 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
|
|
150
|
+
export { type ActionLocation, type AdoptedActor, type AssetConfig, type CodeGenGraph, type CommentsConfig, 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 GraphPatch, type InitOptions, type Inspector, type InspectorEvents, type MachineConfigOptions, type ManualActorOptions, type PlanSyncOptions, type ProjectData, type ProjectMachine, type PullSyncResult, RawCode, 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 UploadResult, type VerifyApiKeyResponse, type XStateTSOptions, contextSchemaToTSType, createPostMessageTransport, createStatelyClient, createStatelyEmbed, createStatelyInspector, createWebSocketTransport, eventsSchemaToTSType, fromStudioMachine, graphToMachineConfig, graphToXStateTS, jsonSchemaToTSType, raw, serializeJS, studioMachineConverter, toStudioMachine };
|
package/dist/index.mjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { n as createWebSocketTransport, t as createPostMessageTransport } from "./transport-
|
|
1
|
+
import { n as createWebSocketTransport, t as createPostMessageTransport } from "./transport-lomH7b0v.mjs";
|
|
2
2
|
import { createStatelyEmbed } from "./embed.mjs";
|
|
3
3
|
import { createStatelyInspector } from "./inspect.mjs";
|
|
4
4
|
import { StudioApiError, createStatelyClient } from "./studio.mjs";
|
|
5
5
|
import { fromStudioMachine, studioMachineConverter, toStudioMachine } from "./graph.mjs";
|
|
6
|
-
import { a as graphToMachineConfig, c as serializeJS, i as jsonSchemaToTSType, n as contextSchemaToTSType, o as RawCode, r as eventsSchemaToTSType, s as raw, t as graphToXStateTS } from "./graphToXStateTS-
|
|
6
|
+
import { a as graphToMachineConfig, c as serializeJS, i as jsonSchemaToTSType, n as contextSchemaToTSType, o as RawCode, r as eventsSchemaToTSType, s as raw, t as graphToXStateTS } from "./graphToXStateTS-BSUj97r0.mjs";
|
|
7
7
|
|
|
8
8
|
export { RawCode, StudioApiError, contextSchemaToTSType, createPostMessageTransport, createStatelyClient, createStatelyEmbed, createStatelyInspector, createWebSocketTransport, eventsSchemaToTSType, fromStudioMachine, graphToMachineConfig, graphToXStateTS, jsonSchemaToTSType, raw, serializeJS, studioMachineConverter, toStudioMachine };
|