@statelyai/sdk 0.40.0 → 0.41.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.
Files changed (35) hide show
  1. package/README.md +10 -0
  2. package/dist/assetStorage.d.mts +1 -1
  3. package/dist/chunk-D1OLi6Wq.mjs +46 -0
  4. package/dist/editorHostProtocol.d.mts +3 -3
  5. package/dist/embed.d.mts +4 -3
  6. package/dist/embed.mjs +1 -1
  7. package/dist/{graph-9CApplKH.d.mts → graph-DbZdSisK.d.mts} +1 -1
  8. package/dist/graph.d.mts +1 -1
  9. package/dist/{index-gyYPC8rD.d.mts → index-DqF1xP8P.d.mts} +50 -399
  10. package/dist/index.d.mts +5 -5
  11. package/dist/index.mjs +3 -3
  12. package/dist/{inspect-COd1d8sJ.mjs → inspect-CDjr4saL.mjs} +1 -1
  13. package/dist/{inspect-C8SpNJKF.d.mts → inspect-ruD95iBM.d.mts} +1 -1
  14. package/dist/inspect.d.mts +2 -2
  15. package/dist/inspect.mjs +2 -2
  16. package/dist/machineGraph-DYtFKHlq-BpWpGU22.mjs +3 -0
  17. package/dist/machineGraph-DYtFKHlq-ChbeTHlv.mjs +1023 -0
  18. package/dist/patchTypes.d.mts +1 -1
  19. package/dist/{protocol-DUehXGus.d.mts → protocol-BvElOcXs.d.mts} +4 -3
  20. package/dist/protocol.d.mts +1 -1
  21. package/dist/relay.d.mts +1 -1
  22. package/dist/rolldown-runtime-95iHPtFO-Bo6l7CbO.mjs +114 -0
  23. package/dist/{studio-D0XNCqKr.mjs → schemas-DsQ8UYlM.mjs} +36 -1649
  24. package/dist/sourceCoverage.d.mts +101 -0
  25. package/dist/sourceCoverage.mjs +3572 -0
  26. package/dist/studio-DH7OeLao.mjs +1604 -0
  27. package/dist/{studio-DeFtdrGS.d.mts → studio-DRw9sxCm.d.mts} +10 -2
  28. package/dist/studio.d.mts +1 -1
  29. package/dist/studio.mjs +1 -1
  30. package/dist/{version-CRlxeCo2.mjs → version-eag6cuvm.mjs} +1 -1
  31. package/dist/xstateSource-BUCx2xA4-CWteIFJn.d.mts +451 -0
  32. package/dist/xstateSource-JvwXWv6G-KnMMoZlG.mjs +151753 -0
  33. package/package.json +7 -3
  34. /package/dist/{editor-sync-types-Ch5P5XRj.d.mts → editor-sync-types-BjgSBGxf.d.mts} +0 -0
  35. /package/dist/{patchTypes-BZ7gzwAP.d.mts → patchTypes-BFlvJTDJ.d.mts} +0 -0
@@ -0,0 +1,1023 @@
1
+ import { Et as array, Nn as record, Rn as string, Tn as object, Xn as union, Zn as unknown, dn as literal, wn as number } from "./schemas-DsQ8UYlM.mjs";
2
+ import { a as XSTATE_V5_PROFILE, d as isCodeExpression, f as isXStateV6Profile, h as serializeJS, i as SERIALIZED_SOURCE_ID, m as raw, n as FN_PROJECTION_META, o as XSTATE_V6_BRANCH_DESCRIPTION_META, p as normalizeMachineProfile, t as __exportAll } from "./rolldown-runtime-95iHPtFO-Bo6l7CbO.mjs";
3
+
4
+ //#region ../graph-tools/dist/machineGraph-DYtFKHlq.mjs
5
+ function normalizeProfileRef(profile) {
6
+ return profile === "xstate-v5" || profile === "xstate-v6-alpha" ? normalizeMachineProfile(profile) : profile;
7
+ }
8
+ const AFTER_EVENT_PREFIX = "xstate.after.";
9
+ /** Recovers an authored delay key from an internal after-event type. */
10
+ function getDelayKeyFromEventType(eventType, sourceId) {
11
+ if (!eventType.startsWith(AFTER_EVENT_PREFIX)) return null;
12
+ const encoded = eventType.slice(13);
13
+ const sourceSuffix = sourceId ? `.${sourceId}` : null;
14
+ if (sourceSuffix && encoded.endsWith(sourceSuffix)) return encoded.slice(0, -sourceSuffix.length);
15
+ return encoded.split(".")[0] ?? encoded;
16
+ }
17
+ function isAutoGeneratedId(id) {
18
+ return !!id && id.startsWith("$auto-");
19
+ }
20
+ function getAuthoredNodeId(node) {
21
+ const authored = node.data.nodeId ?? void 0;
22
+ return authored && !isAutoGeneratedId(authored) ? authored : void 0;
23
+ }
24
+ function getRootEmittedId(graph, node) {
25
+ if (graph.id === "root" && node.data.key && node.data.key !== "root") return getAuthoredNodeId(node) ?? node.data.key;
26
+ return getAuthoredNodeId(node) ?? (isAutoGeneratedId(graph.id) ? void 0 : graph.id);
27
+ }
28
+ function getDefaultPathId(graph, node) {
29
+ if (!node.parentId) return getRootEmittedId(graph, node) ?? "(machine)";
30
+ const parentNode = graph.nodes.find((candidate) => candidate.id === node.parentId);
31
+ if (!parentNode) return node.data.key;
32
+ return `${getDefaultPathId(graph, parentNode)}.${node.data.key}`;
33
+ }
34
+ function getEmittedNodeId(graph, node) {
35
+ const authored = getAuthoredNodeId(node);
36
+ if (!node.parentId) return getRootEmittedId(graph, node);
37
+ if (!authored) return void 0;
38
+ return authored;
39
+ }
40
+ function getResolvedNodeId(graph, node) {
41
+ return getEmittedNodeId(graph, node) ?? getDefaultPathId(graph, node);
42
+ }
43
+ /**
44
+ * Strips `export default` wrapper from an expression string.
45
+ * E.g. `"export default assign({ ... })"` → `"assign({ ... })"`
46
+ */
47
+ function stripExportDefault(code) {
48
+ const trimmed = code.trim();
49
+ if (trimmed.startsWith("export default ")) return trimmed.slice(15).replace(/;$/, "");
50
+ return trimmed;
51
+ }
52
+ /**
53
+ * Graph-native transition references. Transitions point at invoke/action/state
54
+ * blocks by graph id (`@statelyai.*`); the literal `xstate.*` event is produced
55
+ * here at codegen time. Literal `xstate.*` strings (pre-resolved, e.g. baked by
56
+ * an import) are passed through unchanged.
57
+ */
58
+ const STATELY_PREFIX = "@statelyai";
59
+ /** Legacy prefix accepted on read for graphs persisted before the rename. */
60
+ const LEGACY_STATELY_PREFIX = "@stately";
61
+ const STATELY_REF_PREFIX = {
62
+ invokeDone: "@statelyai.invoke.done",
63
+ invokeError: "@statelyai.invoke.error",
64
+ invokeSnapshot: "@statelyai.invoke.snapshot",
65
+ invokeTimeout: "@statelyai.invoke.timeout",
66
+ actionDone: "@statelyai.action.done",
67
+ actionError: "@statelyai.action.error",
68
+ stateDone: "@statelyai.state.done",
69
+ stateError: "@statelyai.state.error",
70
+ stateTimeout: "@statelyai.state.timeout"
71
+ };
72
+ function parseStatelyRef(eventType) {
73
+ if (eventType.startsWith(`${LEGACY_STATELY_PREFIX}.`)) eventType = `${STATELY_PREFIX}${eventType.slice(8)}`;
74
+ if (!eventType.startsWith(`${STATELY_PREFIX}.`)) return null;
75
+ for (const kind of Object.keys(STATELY_REF_PREFIX)) {
76
+ const prefix = STATELY_REF_PREFIX[kind];
77
+ if (eventType === prefix) return {
78
+ kind,
79
+ blockId: ""
80
+ };
81
+ if (eventType.startsWith(`${prefix}.`)) return {
82
+ kind,
83
+ blockId: eventType.slice(prefix.length + 1)
84
+ };
85
+ }
86
+ return null;
87
+ }
88
+ /** Find an invoke block by its graph id, or by its emitted id (legacy literals). */
89
+ function findInvokeByActorId(node, actorId) {
90
+ const invokes = node.data.invokes ?? [];
91
+ return invokes.find((inv) => inv.id === actorId) ?? invokes.find((inv) => (inv.invocationId ?? inv.id) === actorId);
92
+ }
93
+ /** Resolve a spawn action block id to its spawned actor id (`params.id`). */
94
+ function resolveSpawnActorId(node, actionId) {
95
+ const spawnId = [...node.data.entry ?? [], ...node.data.exit ?? []].find((action) => action.id === actionId)?.params?.["id"];
96
+ return typeof spawnId === "string" && spawnId ? spawnId : actionId;
97
+ }
98
+ /**
99
+ * Resolve an edge's target into the string XState expects on the source state.
100
+ * Prefer a relative key path (resolved against the source's parent, or the root
101
+ * itself for root transitions) so output reads like a hand-written machine —
102
+ * e.g. a sibling's child becomes `Unlocked.Manual`. Fall back to an absolute
103
+ * `#id` reference only when the target lives outside the source's subtree.
104
+ */
105
+ function resolveTransitionTarget(graph, sourceNode, targetNode) {
106
+ const isRootSource = sourceNode.parentId == null;
107
+ const baseId = sourceNode.parentId ?? sourceNode.id;
108
+ const keys = [];
109
+ let current = targetNode;
110
+ while (current) {
111
+ keys.unshift(current.data.key.replace(/\\/g, "\\\\").replace(/\./g, "\\."));
112
+ if (current.parentId === baseId) {
113
+ if (isRootSource) return `.${keys.join(".")}`;
114
+ return keys.join(".");
115
+ }
116
+ const parentId = current.parentId;
117
+ current = graph.nodes.find((n) => n.id === parentId);
118
+ }
119
+ return `#${getAbsoluteTargetId(graph, targetNode)}`;
120
+ }
121
+ function getAbsoluteTargetId(graph, targetNode) {
122
+ const resolved = getResolvedNodeId(graph, targetNode);
123
+ if (!resolved.startsWith("root.")) return resolved;
124
+ const rootNode = graph.nodes.find((node) => node.parentId === null);
125
+ const rootKey = rootNode?.data.nodeId && !isAutoGeneratedId(rootNode.data.nodeId) ? rootNode.data.nodeId : rootNode?.data.key;
126
+ return rootKey && rootKey !== "root" ? `${rootKey}.${resolved.slice(5)}` : resolved;
127
+ }
128
+ /** Unwrap single-element arrays to a single value (XState single-or-array convention) */
129
+ function singleOrArray(arr) {
130
+ return arr.length === 1 ? arr[0] : arr;
131
+ }
132
+ /** Unwrap each value in a record of arrays */
133
+ function singleOrArrayRecord(record) {
134
+ const result = {};
135
+ for (const [key, arr] of Object.entries(record)) result[key] = singleOrArray(arr);
136
+ return result;
137
+ }
138
+ /**
139
+ * Remove empty arrays/objects/strings, unwrap single-element arrays.
140
+ * Matches studio's simplifyAttributes behavior.
141
+ */
142
+ /**
143
+ * Keys whose empty object value is authored, not incidental: `context: {}`
144
+ * declares that the machine has context, so dropping it loses information.
145
+ */
146
+ const KEEP_WHEN_EMPTY = new Set(["context"]);
147
+ const KEEP_SINGLETON_ARRAY = new Set(["internalEvents", "tags"]);
148
+ function simplifyAttributes(obj) {
149
+ for (const key of Object.keys(obj)) {
150
+ const value = obj[key];
151
+ if (value === void 0 || value === null) delete obj[key];
152
+ else if (KEEP_WHEN_EMPTY.has(key)) continue;
153
+ else if (Array.isArray(value)) {
154
+ if (value.length === 0) delete obj[key];
155
+ else if (value.length === 1 && !KEEP_SINGLETON_ARRAY.has(key)) obj[key] = value[0];
156
+ } else if (typeof value === "object" && Object.keys(value).length === 0) delete obj[key];
157
+ else if (typeof value === "string" && value === "") delete obj[key];
158
+ }
159
+ return obj;
160
+ }
161
+ /**
162
+ * Recursively apply simplifyAttributes to a config tree.
163
+ * Cleans up the config and all nested state nodes, transitions, and invokes.
164
+ */
165
+ function deepSimplify(config) {
166
+ for (const mapKey of ["on", "after"]) {
167
+ const map = config[mapKey];
168
+ if (map && typeof map === "object" && !Array.isArray(map)) {
169
+ for (const [, val] of Object.entries(map)) if (val && typeof val === "object" && !Array.isArray(val)) simplifyAttributes(val);
170
+ else if (Array.isArray(val)) {
171
+ for (const item of val) if (item && typeof item === "object") simplifyAttributes(item);
172
+ }
173
+ }
174
+ }
175
+ for (const key of [
176
+ "always",
177
+ "onDone",
178
+ "onError",
179
+ "onTimeout"
180
+ ]) {
181
+ const val = config[key];
182
+ if (val && typeof val === "object" && !Array.isArray(val)) simplifyAttributes(val);
183
+ else if (Array.isArray(val)) {
184
+ for (const item of val) if (item && typeof item === "object") simplifyAttributes(item);
185
+ }
186
+ }
187
+ const invoke = config.invoke;
188
+ if (invoke && typeof invoke === "object" && !Array.isArray(invoke)) simplifyAttributes(invoke);
189
+ else if (Array.isArray(invoke)) {
190
+ for (const item of invoke) if (item && typeof item === "object") simplifyAttributes(item);
191
+ }
192
+ simplifyAttributes(config);
193
+ if (config.states && typeof config.states === "object") for (const stateConfig of Object.values(config.states)) deepSimplify(stateConfig);
194
+ return config;
195
+ }
196
+ function buildMeta(meta, color, showStatelyMeta = true) {
197
+ if (isCodeExpression(meta)) return meta;
198
+ const result = {};
199
+ if (meta) {
200
+ for (const [k, v] of Object.entries(meta)) if (v !== void 0 && v !== null && (showStatelyMeta || k === FN_PROJECTION_META || !k.startsWith("@statelyai"))) result[k] = v;
201
+ }
202
+ if (color !== void 0 && showStatelyMeta) result["@statelyai.color"] = color;
203
+ return Object.keys(result).length > 0 ? result : void 0;
204
+ }
205
+ /** Format event param — supports { type: string } (new) and plain string (legacy) */
206
+ function formatEventParam(event) {
207
+ if (isCodeExpression(event)) return serializeJS(event);
208
+ if (event && typeof event === "object" && "type" in event) return formatInlineObject(event);
209
+ if (typeof event === "string") return `{ type: '${event}' }`;
210
+ return "undefined";
211
+ }
212
+ function formatStringParam(value) {
213
+ if (typeof value === "string") return `'${value}'`;
214
+ return isCodeExpression(value) ? serializeJS(value) : "undefined";
215
+ }
216
+ function formatInlineObject(value) {
217
+ return serializeJS(raw(`{ ${Object.entries(value).filter(([, item]) => item !== void 0).map(([key, item]) => `${formatObjectKey(key)}: ${serializeJS(item)}`).join(", ")} }`, value));
218
+ }
219
+ function formatObjectKey(key) {
220
+ return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(key) ? key : JSON.stringify(key);
221
+ }
222
+ const codeExpressionParamSchema = object({
223
+ "@type": literal("code"),
224
+ expr: string()
225
+ }).passthrough();
226
+ const eventParamSchema = union([
227
+ string(),
228
+ object({ type: string() }).catchall(unknown()),
229
+ codeExpressionParamSchema
230
+ ]);
231
+ const stringOrCodeParamSchema = union([string(), codeExpressionParamSchema]);
232
+ const delayParamSchema = union([
233
+ number(),
234
+ string(),
235
+ codeExpressionParamSchema
236
+ ]);
237
+ const builtInActionParamSchemas = {
238
+ "xstate.enqueue": object({
239
+ code: string().optional(),
240
+ lang: string().optional()
241
+ }),
242
+ "xstate.raise": object({
243
+ event: eventParamSchema.optional(),
244
+ id: stringOrCodeParamSchema.optional(),
245
+ delay: delayParamSchema.optional()
246
+ }),
247
+ "xstate.sendTo": object({
248
+ to: stringOrCodeParamSchema.optional(),
249
+ event: eventParamSchema.optional(),
250
+ id: stringOrCodeParamSchema.optional(),
251
+ delay: delayParamSchema.optional()
252
+ }),
253
+ "xstate.cancel": object({ sendId: stringOrCodeParamSchema.optional() }),
254
+ "xstate.emit": object({ event: eventParamSchema.optional() }),
255
+ "xstate.spawnChild": object({
256
+ src: stringOrCodeParamSchema.optional(),
257
+ id: stringOrCodeParamSchema.optional(),
258
+ systemId: stringOrCodeParamSchema.optional(),
259
+ input: unknown().optional()
260
+ }),
261
+ "xstate.stopChild": object({ actorRef: stringOrCodeParamSchema.optional() }),
262
+ "xstate.log": object({ label: unknown().optional() }),
263
+ "xstate.assign": object({ assignment: record(string(), unknown()).optional() }).catchall(unknown()),
264
+ "xstate.choose": object({ branches: array(object({
265
+ guard: unknown().optional(),
266
+ actions: array(unknown()).optional()
267
+ })).optional() })
268
+ };
269
+ const XSTATE_BUILT_IN_ACTIONS = {
270
+ "xstate.enqueue": {
271
+ package: "xstate",
272
+ version: "^6",
273
+ import: "enqueue",
274
+ importKind: "named",
275
+ paramsSchema: builtInActionParamSchemas["xstate.enqueue"],
276
+ emit(params) {
277
+ return typeof params?.code === "string" ? stripExportDefault(params.code) : "";
278
+ }
279
+ },
280
+ "xstate.raise": {
281
+ package: "xstate",
282
+ version: "^5",
283
+ import: "raise",
284
+ importKind: "named",
285
+ paramsSchema: builtInActionParamSchemas["xstate.raise"],
286
+ emit(params) {
287
+ const eventStr = formatEventParam(params?.event);
288
+ const opts = [];
289
+ if (params?.id) opts.push(`id: ${formatStringParam(params.id)}`);
290
+ if (params?.delay != null) opts.push(`delay: ${serializeJS(params.delay)}`);
291
+ return `raise(${eventStr}${opts.length > 0 ? `, { ${opts.join(", ")} }` : ""})`;
292
+ }
293
+ },
294
+ "xstate.sendTo": {
295
+ package: "xstate",
296
+ version: "^5",
297
+ import: "sendTo",
298
+ importKind: "named",
299
+ paramsSchema: builtInActionParamSchemas["xstate.sendTo"],
300
+ emit(params) {
301
+ const to = formatStringParam(params?.to);
302
+ const eventStr = formatEventParam(params?.event);
303
+ const opts = [];
304
+ if (params?.id) opts.push(`id: ${formatStringParam(params.id)}`);
305
+ if (params?.delay != null) opts.push(`delay: ${serializeJS(params.delay)}`);
306
+ return `sendTo(${to}, ${eventStr}${opts.length > 0 ? `, { ${opts.join(", ")} }` : ""})`;
307
+ }
308
+ },
309
+ "xstate.cancel": {
310
+ package: "xstate",
311
+ version: "^5",
312
+ import: "cancel",
313
+ importKind: "named",
314
+ paramsSchema: builtInActionParamSchemas["xstate.cancel"],
315
+ emit(params) {
316
+ return `cancel(${formatStringParam(params?.sendId)})`;
317
+ }
318
+ },
319
+ "xstate.emit": {
320
+ package: "xstate",
321
+ version: "^5",
322
+ import: "emit",
323
+ importKind: "named",
324
+ paramsSchema: builtInActionParamSchemas["xstate.emit"],
325
+ emit(params) {
326
+ return `emit(${formatEventParam(params?.event)})`;
327
+ }
328
+ },
329
+ "xstate.spawnChild": {
330
+ package: "xstate",
331
+ version: "^5",
332
+ import: "spawnChild",
333
+ importKind: "named",
334
+ paramsSchema: builtInActionParamSchemas["xstate.spawnChild"],
335
+ emit(params) {
336
+ const src = formatStringParam(params?.src);
337
+ const opts = [];
338
+ if (params?.id) opts.push(`id: ${formatStringParam(params.id)}`);
339
+ if (params?.systemId) opts.push(`systemId: ${formatStringParam(params.systemId)}`);
340
+ if (params?.input !== void 0) opts.push(`input: ${serializeJS(params.input)}`);
341
+ return `spawnChild(${src}${opts.length > 0 ? `, { ${opts.join(", ")} }` : ""})`;
342
+ }
343
+ },
344
+ "xstate.stopChild": {
345
+ package: "xstate",
346
+ version: "^5",
347
+ import: "stopChild",
348
+ importKind: "named",
349
+ paramsSchema: builtInActionParamSchemas["xstate.stopChild"],
350
+ emit(params) {
351
+ return `stopChild(${formatStringParam(params?.actorRef)})`;
352
+ }
353
+ },
354
+ "xstate.log": {
355
+ package: "xstate",
356
+ version: "^5",
357
+ import: "log",
358
+ importKind: "named",
359
+ paramsSchema: builtInActionParamSchemas["xstate.log"],
360
+ emit(params) {
361
+ return `log(${(params?.label !== void 0 ? serializeJS(params.label) : void 0) ?? ""})`;
362
+ }
363
+ },
364
+ "xstate.choose": {
365
+ package: "xstate",
366
+ version: "^5",
367
+ import: "enqueueActions",
368
+ importKind: "named",
369
+ paramsSchema: builtInActionParamSchemas["xstate.choose"],
370
+ emit(params) {
371
+ return emitChooseBranches(params?.branches ?? []);
372
+ }
373
+ },
374
+ "xstate.assign": {
375
+ package: "xstate",
376
+ version: "^5",
377
+ import: "assign",
378
+ importKind: "named",
379
+ paramsSchema: builtInActionParamSchemas["xstate.assign"],
380
+ emit(params) {
381
+ if (isCodeExpression(params?.assignment)) return `assign(${serializeJS(params.assignment)})`;
382
+ const assignments = params?.assignment && typeof params.assignment === "object" && !Array.isArray(params.assignment) ? params.assignment : params;
383
+ const entries = Object.entries(assignments ?? {}).filter(([k, v]) => k && v !== void 0);
384
+ if (entries.length === 0) return "assign({})";
385
+ return `assign({ ${entries.map(([k, v]) => `${JSON.stringify(k)}: ${formatAssignValue(v)}`).join(", ")} })`;
386
+ }
387
+ }
388
+ };
389
+ function isBuiltInActionType(type) {
390
+ return type in XSTATE_BUILT_IN_ACTIONS;
391
+ }
392
+ /** Lower `xstate.choose` branches to an `enqueueActions` if/else-if chain. */
393
+ function emitChooseBranches(branches) {
394
+ const lines = [];
395
+ const indent = (depth) => " ".repeat(depth);
396
+ const serializeEnqueued = (action, depth) => {
397
+ if (action && typeof action === "object" && !Array.isArray(action) && Object.keys(action).length === 1 && typeof action.type === "string") return serializeJS(action.type);
398
+ return serializeJS(action, depth * 2);
399
+ };
400
+ const body = (actions, depth) => (actions ?? []).map((action) => `${indent(depth)}enqueue(${serializeEnqueued(action, depth)});`);
401
+ let closed = false;
402
+ let opened = false;
403
+ for (const branch of branches) {
404
+ if (closed) break;
405
+ if (branch.guard === void 0) {
406
+ if (opened) {
407
+ lines.push(` } else {`);
408
+ lines.push(...body(branch.actions, 2));
409
+ lines.push(" }");
410
+ } else lines.push(...body(branch.actions, 1));
411
+ closed = true;
412
+ continue;
413
+ }
414
+ lines.push(` ${opened ? "} else if" : "if"} (check(${serializeJS(branch.guard)})) {`);
415
+ lines.push(...body(branch.actions, 2));
416
+ opened = true;
417
+ }
418
+ if (opened && !closed) lines.push(" }");
419
+ return `enqueueActions(({ check, enqueue }) => {\n${lines.join("\n")}\n})`;
420
+ }
421
+ function emitBuiltInAction(type, params) {
422
+ return XSTATE_BUILT_IN_ACTIONS[type].emit(params);
423
+ }
424
+ function actionCodeExpression(expr, source) {
425
+ return {
426
+ "@type": "code",
427
+ lang: "ts",
428
+ expr,
429
+ imports: [{
430
+ package: source.package,
431
+ version: source.version,
432
+ import: source.import,
433
+ importKind: source.importKind
434
+ }]
435
+ };
436
+ }
437
+ function inlineCodeExpression(expr, sourceValue) {
438
+ const result = {
439
+ "@type": "code",
440
+ lang: "ts",
441
+ expr: stripExportDefault(expr)
442
+ };
443
+ const sourceId = sourceValue?.[SERIALIZED_SOURCE_ID];
444
+ if (sourceId !== void 0) Object.defineProperty(result, SERIALIZED_SOURCE_ID, {
445
+ value: sourceId,
446
+ enumerable: true
447
+ });
448
+ return result;
449
+ }
450
+ /**
451
+ * Serialize an edge guard for a machine config. Codegen emits inline guards as
452
+ * a code-expression directive so the source round-trips. The simulation passes
453
+ * `asTypeRef` to get a plain `{ type }` reference instead (it stubs guards by
454
+ * type and can't evaluate the source) — see MachineConfigOptions.
455
+ */
456
+ function serializeGuard(guard, asTypeRef) {
457
+ if (asTypeRef) return guard.params ? {
458
+ type: guard.type,
459
+ params: guard.params
460
+ } : { type: guard.type };
461
+ return guard.code ? inlineCodeExpression(guard.code, guard) : guard;
462
+ }
463
+ /**
464
+ * Converts a built-in xstate ActionItem to a code expression directive,
465
+ * or returns a plain { type, params } object for user-defined actions.
466
+ */
467
+ function serializeActionItem(action, keepChooseStructured = false) {
468
+ const { type, params } = action;
469
+ if (keepChooseStructured && type === "xstate.choose") return {
470
+ type,
471
+ params
472
+ };
473
+ if (type === "xstate.enqueue" && typeof params?.code === "string") return inlineCodeExpression(params.code, action);
474
+ const exprCode = type === "xstate.expr" && typeof params?.code === "string" ? params.code : void 0;
475
+ if (isBuiltInActionType(type)) {
476
+ const builtInAction = XSTATE_BUILT_IN_ACTIONS[type];
477
+ return actionCodeExpression(emitBuiltInAction(type, params), builtInAction);
478
+ }
479
+ if (exprCode) return inlineCodeExpression(exprCode, action);
480
+ if (!params || Object.keys(params).length === 0) return { type };
481
+ return {
482
+ type,
483
+ params
484
+ };
485
+ }
486
+ function formatAssignValue(value) {
487
+ if (typeof value !== "string") return serializeJS(value);
488
+ const templateExpression = value.match(/^\{\{([\s\S]*)\}\}$/);
489
+ if (templateExpression) return templateExpression[1].trim();
490
+ return JSON.stringify(value);
491
+ }
492
+ /** Normalize tag to string — handles both `string` and `{ name: string }` */
493
+ function tagToString(tag) {
494
+ return typeof tag === "string" ? tag : tag.name;
495
+ }
496
+ function graphToMachineConfig(graph, options = {}) {
497
+ const v6 = isXStateV6Profile(graph.data.profile);
498
+ const { showDescriptions = true, showMeta = true, showStatelyMeta = true, inlineGuardsAsTypeRef = false, keepChooseStructured = false, timerActionsAsTypeRef = false } = options;
499
+ const serializeAction = (action) => timerActionsAsTypeRef && ["xstate.raise", "xstate.cancel"].includes(action.type) ? {
500
+ type: action.type,
501
+ params: action.params
502
+ } : serializeActionItem(action, keepChooseStructured);
503
+ const config = {};
504
+ function getNodeConfig(node) {
505
+ const nodeConfig = node.parentId ? {} : config;
506
+ const resolvedNodeId = getEmittedNodeId(graph, node);
507
+ const initialNode = node.data.initialId ? graph.nodes.find((n) => n.id === node.data.initialId) : null;
508
+ const nodeType = [
509
+ "final",
510
+ "history",
511
+ "parallel",
512
+ "choice"
513
+ ].includes(node.data.type) ? node.data.type : void 0;
514
+ const tags = node.data.tags;
515
+ const stateMeta = showMeta ? buildMeta({
516
+ ...node.data.meta,
517
+ ...node.data.assets?.length ? { "@statelyai.assets": node.data.assets.map(({ type, url, size, width, height, name, metadata }) => ({
518
+ type,
519
+ url,
520
+ ...size ? { size } : {},
521
+ ...name !== void 0 ? { name } : {},
522
+ ...metadata !== void 0 ? { metadata } : {},
523
+ ...type === "iframe" ? {
524
+ ...width !== void 0 ? { width } : {},
525
+ ...height !== void 0 ? { height } : {}
526
+ } : {}
527
+ })) } : {},
528
+ ...node.data.appearance ? { "@statelyai.appearance": node.data.appearance } : {}
529
+ }, node.data.color, showStatelyMeta) : void 0;
530
+ Object.assign(nodeConfig, {
531
+ id: resolvedNodeId,
532
+ type: nodeType === "normal" ? void 0 : nodeType ?? void 0,
533
+ initial: initialNode ? nodeType === "history" ? void 0 : node.data.initialInput !== void 0 ? {
534
+ target: initialNode.data.key,
535
+ input: node.data.initialInput
536
+ } : initialNode.data.key : void 0,
537
+ target: nodeType === "history" && initialNode ? resolveTransitionTarget(graph, node, initialNode) : void 0,
538
+ ...node.data.timeout !== void 0 ? { timeout: node.data.timeout } : void 0,
539
+ ...node.data.route !== void 0 ? { route: node.data.route } : void 0,
540
+ ...node.data.entry?.length ? { entry: node.data.entry.map(serializeAction) } : void 0,
541
+ ...node.data.exit?.length ? { exit: node.data.exit.map(serializeAction) } : void 0,
542
+ ...node.data.invokes?.length ? { invoke: node.data.invokes.map((inv) => ({
543
+ src: inv.srcExpression ?? inv.src,
544
+ id: inv.invocationId ?? inv.id,
545
+ ...inv.registryKey ? { registryKey: inv.registryKey } : void 0,
546
+ ...inv.timeout !== void 0 ? { timeout: inv.timeout } : void 0,
547
+ ...inv.input !== void 0 ? { input: inv.input } : void 0,
548
+ ...inv.output !== void 0 ? { output: inv.output } : void 0
549
+ })) } : void 0,
550
+ ...node.data.output !== void 0 ? { output: node.data.output } : void 0,
551
+ ...node.data.schemas ? { schemas: node.data.schemas } : void 0,
552
+ ...tags?.length ? { tags: tags.map(tagToString) } : void 0,
553
+ ...showDescriptions && node.data.description ? { description: node.data.description } : void 0,
554
+ ...stateMeta ? { meta: stateMeta } : void 0,
555
+ ...node.data.history ? { history: node.data.history } : void 0
556
+ });
557
+ const childNodes = graph.nodes.filter((n) => n.parentId === node.id && !n.data.temp);
558
+ const edges = graph.edges.filter((edge) => edge.sourceId === node.id && !edge.data.temp);
559
+ if (edges.length > 0) {
560
+ const on = {};
561
+ const transitionOrder = /* @__PURE__ */ new Map();
562
+ const scxmlTransitions = [];
563
+ const after = {};
564
+ const alwaysArr = [];
565
+ const choiceArr = [];
566
+ const onDone = {};
567
+ const onError = [];
568
+ const onTimeout = [];
569
+ const invokeMap = {};
570
+ for (const edge of edges) {
571
+ const targetNode = graph.nodes.find((n) => n.id === edge.targetId);
572
+ const resolvedTarget = targetNode ? resolveTransitionTarget(graph, node, targetNode) : "";
573
+ const resolvedTargets = [resolvedTarget, ...(edge.data.additionalTargetIds ?? []).flatMap((targetId) => {
574
+ const additionalTarget = graph.nodes.find((n) => n.id === targetId);
575
+ return additionalTarget ? [resolveTransitionTarget(graph, node, additionalTarget)] : [];
576
+ })].filter(Boolean);
577
+ const type = edge.data.eventType ?? "";
578
+ const transitionMeta = showMeta ? buildMeta({
579
+ ...edge.data.meta,
580
+ ...edge.data.assets?.length ? { "@statelyai.assets": edge.data.assets.map(({ type, url, size, width, height, name, metadata }) => ({
581
+ type,
582
+ url,
583
+ ...size ? { size } : {},
584
+ ...name !== void 0 ? { name } : {},
585
+ ...metadata !== void 0 ? { metadata } : {},
586
+ ...type === "iframe" ? {
587
+ ...width !== void 0 ? { width } : {},
588
+ ...height !== void 0 ? { height } : {}
589
+ } : {}
590
+ })) } : {},
591
+ ...edge.data.appearance ? { "@statelyai.appearance": edge.data.appearance } : {}
592
+ }, edge.data.color, showStatelyMeta) : edge.data.meta?.[FN_PROJECTION_META] ? { [FN_PROJECTION_META]: edge.data.meta[FN_PROJECTION_META] } : void 0;
593
+ const transitionObject = {
594
+ ...edge.data.matches ? { matches: edge.data.matches } : void 0,
595
+ target: edge.data.transitionType === "targetless" ? void 0 : resolvedTargets.length > 1 ? resolvedTargets : `${resolvedTarget}`,
596
+ ...edge.data.transitionType === "reenter" ? { reenter: true } : void 0,
597
+ guard: edge.data.guard ? serializeGuard(edge.data.guard, inlineGuardsAsTypeRef) : void 0,
598
+ ...edge.data.context !== void 0 ? { context: edge.data.context } : void 0,
599
+ ...edge.data.input !== void 0 ? { input: edge.data.input } : void 0,
600
+ actions: edge.data.actions?.length ? edge.data.actions.map(serializeAction) : void 0,
601
+ description: showDescriptions ? edge.data.description ?? void 0 : void 0,
602
+ ...transitionMeta ? { meta: transitionMeta } : void 0
603
+ };
604
+ transitionOrder.set(transitionObject, transitionOrder.size);
605
+ const pushOn = (key) => {
606
+ if (!on[key]) on[key] = [];
607
+ on[key].push(transitionObject);
608
+ };
609
+ const nestInvoke = (blockId, slot) => {
610
+ invokeMap[blockId] = {
611
+ ...invokeMap[blockId],
612
+ [slot]: (invokeMap[blockId]?.[slot] ?? []).concat(transitionObject)
613
+ };
614
+ };
615
+ const ref = parseStatelyRef(type);
616
+ if (ref) if (ref.kind === "invokeDone") nestInvoke(ref.blockId, "onDone");
617
+ else if (ref.kind === "invokeError") nestInvoke(ref.blockId, "onError");
618
+ else if (ref.kind === "invokeSnapshot") nestInvoke(ref.blockId, "onSnapshot");
619
+ else if (ref.kind === "invokeTimeout") nestInvoke(ref.blockId, "onTimeout");
620
+ else if (ref.kind === "stateDone") {
621
+ if (!onDone[type]) onDone[type] = [];
622
+ onDone[type].push(transitionObject);
623
+ } else if (ref.kind === "stateError") onError.push(transitionObject);
624
+ else if (ref.kind === "stateTimeout") onTimeout.push(transitionObject);
625
+ else {
626
+ const verb = ref.kind === "actionDone" ? "done" : "error";
627
+ const actorId = resolveSpawnActorId(node, ref.blockId);
628
+ if (v6) {
629
+ const eventType = `xstate.${verb}.actor`;
630
+ if (!on[eventType]) on[eventType] = [];
631
+ on[eventType].push({
632
+ ...transitionObject,
633
+ matches: {
634
+ ...transitionObject.matches,
635
+ actorId
636
+ }
637
+ });
638
+ } else pushOn(`xstate.${verb}.actor.${actorId}`);
639
+ }
640
+ else if (edge.data.route) continue;
641
+ else if (type === "" && node.data.type === "choice") choiceArr.push(transitionObject);
642
+ else if (type === "") alwaysArr.push(transitionObject);
643
+ else if (type.startsWith("xstate.after.")) {
644
+ const delayKey = getDelayKeyFromEventType(type, edge.sourceId);
645
+ if (!after[delayKey]) after[delayKey] = [];
646
+ after[delayKey].push(transitionObject);
647
+ } else if (edge.data.meta?.["@statelyai.scxml.eventDescriptor"]) scxmlTransitions.push({
648
+ descriptor: type,
649
+ transition: transitionObject
650
+ });
651
+ else if (type === "*") pushOn("*");
652
+ else if (type.startsWith("xstate.done.state")) {
653
+ if (!onDone[type]) onDone[type] = [];
654
+ onDone[type].push(transitionObject);
655
+ } else if (type.startsWith("xstate.done.actor.") || type.startsWith("xstate.error.actor.") || type.startsWith("xstate.snapshot.actor.") || type.startsWith("xstate.snapshot.")) {
656
+ const verb = type.startsWith("xstate.done.actor.") ? "onDone" : type.startsWith("xstate.error.actor.") ? "onError" : "onSnapshot";
657
+ const invoke = findInvokeByActorId(node, type.startsWith("xstate.snapshot.") ? type.slice(16).replace(/^actor\./, "") : type.slice(type.lastIndexOf(".actor.") + 7));
658
+ if (invoke) nestInvoke(invoke.id, verb);
659
+ else pushOn(type);
660
+ } else pushOn(type);
661
+ }
662
+ const descriptorBase = (descriptor) => descriptor.replace(/\.\*$/, "");
663
+ const scxmlKeys = new Set([...Object.keys(on), ...scxmlTransitions.flatMap(({ descriptor }) => descriptor === "*" ? ["*"] : descriptorBase(descriptor) ? [descriptorBase(descriptor), `${descriptorBase(descriptor)}.*`] : [])]);
664
+ for (const key of scxmlKeys) {
665
+ const base = descriptorBase(key);
666
+ const matching = scxmlTransitions.filter(({ descriptor }) => {
667
+ const prefix = descriptorBase(descriptor);
668
+ return descriptor === "*" || base === prefix || base.startsWith(`${prefix}.`);
669
+ }).map(({ transition }) => transition);
670
+ on[key] = [...new Set([...on[key] ?? [], ...matching])].sort((a, b) => (transitionOrder.get(a) ?? 0) - (transitionOrder.get(b) ?? 0));
671
+ }
672
+ if (Object.keys(on).length > 0) nodeConfig.on = singleOrArrayRecord(on);
673
+ if (Object.keys(after).length > 0) nodeConfig.after = singleOrArrayRecord(after);
674
+ if (alwaysArr.length > 0) nodeConfig.always = singleOrArray(alwaysArr);
675
+ if (choiceArr.length > 0) nodeConfig.choice = singleOrArray(choiceArr);
676
+ if (Object.keys(onDone).length > 0) nodeConfig.onDone = singleOrArray(Object.values(onDone).flat());
677
+ if (onError.length > 0) nodeConfig.onError = singleOrArray(onError);
678
+ if (onTimeout.length > 0) nodeConfig.onTimeout = singleOrArray(onTimeout);
679
+ if (Object.keys(invokeMap).length > 0 && Array.isArray(nodeConfig.invoke)) nodeConfig.invoke = nodeConfig.invoke.map((inv, index) => {
680
+ const mapped = invokeMap[node.data.invokes?.[index]?.id ?? inv.id];
681
+ if (!mapped) return inv;
682
+ return {
683
+ ...inv,
684
+ ...mapped.onDone ? { onDone: singleOrArray(mapped.onDone) } : void 0,
685
+ ...mapped.onError ? { onError: singleOrArray(mapped.onError) } : void 0,
686
+ ...mapped.onSnapshot ? { onSnapshot: singleOrArray(mapped.onSnapshot) } : void 0,
687
+ ...mapped.onTimeout ? { onTimeout: singleOrArray(mapped.onTimeout) } : void 0
688
+ };
689
+ });
690
+ }
691
+ if (Array.isArray(nodeConfig.invoke)) nodeConfig.invoke = nodeConfig.invoke.map((inv) => {
692
+ if (inv.id && !isAutoGeneratedId(inv.id)) return inv;
693
+ const { id: _id, ...rest } = inv;
694
+ return rest;
695
+ });
696
+ if (childNodes.length > 0) {
697
+ nodeConfig.states = {};
698
+ for (const childState of childNodes) nodeConfig.states[childState.data.key] = getNodeConfig(childState);
699
+ }
700
+ return nodeConfig;
701
+ }
702
+ const rootNode = graph.nodes.find((node) => node.parentId === null || node.parentId == null);
703
+ if (!rootNode) throw new Error("No root node found");
704
+ getNodeConfig(rootNode);
705
+ if (graph.data.context !== void 0 && graph.data.context !== null) config.context = graph.data.context;
706
+ if (graph.data.version) config.version = graph.data.version;
707
+ if (graph.data.options?.maxIterations !== void 0) config.options = { maxIterations: graph.data.options.maxIterations };
708
+ if (graph.data.internalEvents?.length) config.internalEvents = graph.data.internalEvents;
709
+ return deepSimplify(config);
710
+ }
711
+ var machineGraph_exports = /* @__PURE__ */ __exportAll({
712
+ applyDefaultInitialIds: () => applyDefaultInitialIds,
713
+ graphToNormalizedMachine: () => graphToNormalizedMachine,
714
+ machineConfigToGraph: () => machineConfigToGraph
715
+ });
716
+ /**
717
+ * A compound state node with no usable `initial` cannot be simulated (XState
718
+ * throws "No initial state specified for compound state node"). This walks a
719
+ * finished graph and defaults every such node's `initialId` to its first child,
720
+ * which also repairs `initial` references that resolved to no node at all.
721
+ */
722
+ function applyDefaultInitialIds(nodes) {
723
+ const childrenByParentId = /* @__PURE__ */ new Map();
724
+ const nodeIds = new Set(nodes.map((node) => node.id));
725
+ for (const node of nodes) {
726
+ if (node.parentId === null || node.parentId === void 0) continue;
727
+ if (node.data.type === "annotation") continue;
728
+ const siblings = childrenByParentId.get(node.parentId);
729
+ if (siblings) siblings.push(node);
730
+ else childrenByParentId.set(node.parentId, [node]);
731
+ }
732
+ for (const node of nodes) {
733
+ const type = node.data.type;
734
+ if (type !== null && type !== void 0 && type !== "normal") continue;
735
+ if (node.data.initialId && nodeIds.has(node.data.initialId)) continue;
736
+ const firstChild = childrenByParentId.get(node.id)?.[0];
737
+ if (!firstChild) continue;
738
+ node.data.initialId = firstChild.id;
739
+ if ("initialNodeId" in node) node.initialNodeId = firstChild.id;
740
+ }
741
+ }
742
+ function toArray(value) {
743
+ return Array.isArray(value) ? value : value === void 0 ? [] : [value];
744
+ }
745
+ function actionItems(value, idPrefix) {
746
+ return toArray(value).flat().map((item, index) => {
747
+ if (typeof item === "string") return {
748
+ id: `${idPrefix}-${index}`,
749
+ type: item
750
+ };
751
+ if (item && typeof item === "object" && "type" in item) {
752
+ const action = item;
753
+ if (typeof action.type === "string") return {
754
+ id: `${idPrefix}-${index}`,
755
+ type: action.type,
756
+ params: action.params
757
+ };
758
+ }
759
+ return null;
760
+ }).filter((item) => item !== null);
761
+ }
762
+ function invokeItems(value) {
763
+ return toArray(value).map((item, index) => {
764
+ if (typeof item === "string") return {
765
+ id: item || `invoke-${index}`,
766
+ src: item
767
+ };
768
+ if (!item || typeof item !== "object") return null;
769
+ const invoke = item;
770
+ const srcExpression = isCodeExpression(invoke.src) ? invoke.src : void 0;
771
+ if (typeof invoke.src !== "string" && !srcExpression) return null;
772
+ const src = typeof invoke.src === "string" ? invoke.src : "inline:";
773
+ return {
774
+ id: typeof invoke.id === "string" ? invoke.id : srcExpression ? `$auto-inline-${index}` : `$auto-invoke-${src || index}`,
775
+ ...typeof invoke.id === "string" ? { invocationId: invoke.id } : {},
776
+ src,
777
+ ...srcExpression ? { srcExpression } : {},
778
+ ...typeof invoke.registryKey === "string" ? { registryKey: invoke.registryKey } : {},
779
+ ...invoke.timeout !== void 0 ? { timeout: invoke.timeout } : {},
780
+ ...invoke.input !== void 0 ? { input: invoke.input } : {},
781
+ ...invoke.output !== void 0 ? { output: invoke.output } : {}
782
+ };
783
+ }).filter((item) => item !== null);
784
+ }
785
+ function transitionTargets(target) {
786
+ if (typeof target === "string") return [target];
787
+ if (Array.isArray(target)) return target.filter((item) => typeof item === "string");
788
+ return [];
789
+ }
790
+ function transitionObjects(value) {
791
+ return toArray(value).map((item) => {
792
+ if (typeof item === "string") return { target: item };
793
+ if (item && typeof item === "object") return item;
794
+ return {};
795
+ });
796
+ }
797
+ function guardObject(value) {
798
+ if (!value) return null;
799
+ if (typeof value === "string") return { type: value };
800
+ if (typeof value === "object" && "type" in value && typeof value.type === "string") {
801
+ const guard = value;
802
+ return {
803
+ type: guard.type,
804
+ code: guard.code,
805
+ params: guard.params
806
+ };
807
+ }
808
+ return null;
809
+ }
810
+ function implementationItems(value) {
811
+ if (!value || typeof value !== "object" || Array.isArray(value)) return [];
812
+ return Object.entries(value).map(([name, body]) => ({
813
+ id: name,
814
+ name,
815
+ description: null,
816
+ paramsSchema: null,
817
+ code: typeof body === "string" || typeof body === "number" ? {
818
+ body: String(body),
819
+ lang: "ts"
820
+ } : isCodeExpression(body) ? {
821
+ body: body.expr,
822
+ lang: body.lang,
823
+ imports: body.imports
824
+ } : null
825
+ }));
826
+ }
827
+ function actorImplementationItems(value) {
828
+ return implementationItems(value).map((item) => ({
829
+ ...item,
830
+ inputSchema: null,
831
+ outputSchema: null
832
+ }));
833
+ }
834
+ function machineConfigToGraph(config, options = {}) {
835
+ const rootState = config;
836
+ const rootConfig = config;
837
+ const rootKey = String(rootState.id ?? "machine");
838
+ const graph = {
839
+ id: "root",
840
+ nodes: [],
841
+ edges: [],
842
+ data: {
843
+ profile: normalizeProfileRef(options.profile ?? XSTATE_V5_PROFILE),
844
+ version: typeof rootConfig.version === "string" ? rootConfig.version : null,
845
+ options: rootConfig.options && typeof rootConfig.options === "object" && !Array.isArray(rootConfig.options) ? rootConfig.options : null,
846
+ internalEvents: Array.isArray(rootConfig.internalEvents) ? rootConfig.internalEvents.filter((event) => typeof event === "string") : null,
847
+ context: rootConfig.context && typeof rootConfig.context === "object" ? rootConfig.context : null,
848
+ implementations: {
849
+ actions: implementationItems(rootConfig.actions),
850
+ guards: implementationItems(rootConfig.guards),
851
+ actors: actorImplementationItems(rootConfig.actors ?? rootConfig.actorSources),
852
+ delays: implementationItems(rootConfig.delays)
853
+ },
854
+ schemas: config.schemas ?? null
855
+ }
856
+ };
857
+ const stateByGraphId = /* @__PURE__ */ new Map();
858
+ const explicitIdToGraphId = /* @__PURE__ */ new Map();
859
+ function initialParts(initial) {
860
+ return typeof initial === "string" ? {
861
+ target: initial,
862
+ input: void 0
863
+ } : initial && typeof initial === "object" ? {
864
+ target: initial.target,
865
+ input: initial.input
866
+ } : {
867
+ target: void 0,
868
+ input: void 0
869
+ };
870
+ }
871
+ function collect(state, key, parentId) {
872
+ const id = parentId ? `${parentId}.${key}` : "root";
873
+ stateByGraphId.set(id, state);
874
+ if (state.id) explicitIdToGraphId.set(state.id.replace(/^#/, ""), id);
875
+ if (!parentId && state.id) explicitIdToGraphId.set(rootKey, id);
876
+ const initial = initialParts(state.initial);
877
+ graph.nodes.push({
878
+ id,
879
+ parentId,
880
+ data: {
881
+ nodeId: state.id ?? null,
882
+ key,
883
+ type: state.type === "parallel" || state.type === "final" || state.type === "history" || state.type === "choice" ? state.type : null,
884
+ initialId: null,
885
+ ...initial.input !== void 0 ? { initialInput: initial.input } : {},
886
+ ...state.timeout !== void 0 ? { timeout: state.timeout } : {},
887
+ ...state.route !== void 0 ? { route: state.route } : {},
888
+ history: state.history ?? false,
889
+ ...state.output !== void 0 ? { output: state.output } : {},
890
+ ...parentId && state.schemas ? { schemas: state.schemas } : {},
891
+ entry: actionItems(state.entry, `${id}-entry`),
892
+ exit: actionItems(state.exit, `${id}-exit`),
893
+ invokes: invokeItems(state.invoke),
894
+ tags: Array.isArray(state.tags) ? state.tags : typeof state.tags === "string" ? [state.tags] : [],
895
+ description: state.description ?? null,
896
+ meta: state.meta ?? null
897
+ }
898
+ });
899
+ for (const [childKey, child] of Object.entries(state.states ?? {})) collect(child, childKey, id);
900
+ }
901
+ collect(rootState, rootKey, null);
902
+ function targetToNodeId(sourceId, target) {
903
+ if (!target) return sourceId;
904
+ if (target === ".") return sourceId;
905
+ if (target.startsWith(".")) return `${sourceId}${target}`;
906
+ if (target.startsWith("#")) {
907
+ const authored = target.slice(1);
908
+ const matchedId = [...explicitIdToGraphId.keys()].sort((a, b) => b.length - a.length).find((candidate) => authored === candidate || authored.startsWith(`${candidate}.`));
909
+ if (matchedId) {
910
+ const suffix = authored.slice(matchedId.length);
911
+ return `${explicitIdToGraphId.get(matchedId)}${suffix}`;
912
+ }
913
+ const rootPrefix = `${rootKey}.`;
914
+ const path = authored.startsWith(rootPrefix) ? authored.slice(rootPrefix.length) : authored;
915
+ return path ? `root.${path}` : "root";
916
+ }
917
+ return `${sourceId.split(".").slice(0, -1).join(".") || "root"}.${target}`;
918
+ }
919
+ function initialTargetToNodeId(sourceId, target) {
920
+ if (!target) return null;
921
+ if (target.startsWith("#")) return targetToNodeId(sourceId, target);
922
+ return `${sourceId}.${target.replace(/^\./, "")}`;
923
+ }
924
+ for (const node of graph.nodes) {
925
+ const state = stateByGraphId.get(node.id);
926
+ const historyTarget = transitionTargets(state.target)[0];
927
+ node.data.initialId = state.type === "history" ? historyTarget ? targetToNodeId(node.id, historyTarget) : null : initialTargetToNodeId(node.id, initialParts(state.initial).target);
928
+ }
929
+ applyDefaultInitialIds(graph.nodes);
930
+ function doneStateEventType(eventType) {
931
+ if (!eventType.startsWith("xstate.done.state.")) return null;
932
+ const stateId = eventType.slice(18);
933
+ const graphId = explicitIdToGraphId.get(stateId);
934
+ if (graphId) return `@statelyai.state.done.${graphId}`;
935
+ if (stateByGraphId.has(stateId)) return `@statelyai.state.done.${stateId}`;
936
+ const rootPrefix = `${rootKey}.`;
937
+ if (stateId.startsWith(rootPrefix)) {
938
+ const mapped = `root.${stateId.slice(rootPrefix.length)}`;
939
+ if (stateByGraphId.has(mapped)) return `@statelyai.state.done.${mapped}`;
940
+ }
941
+ return null;
942
+ }
943
+ /**
944
+ * `on: { 'xstate.done.actor.<invokeId>': ... }` is the same edge the exporter
945
+ * writes back as the invoke's `onDone`/`onError`, so it is stored as the
946
+ * canonical internal reference. Otherwise the two encodings do not
947
+ * round-trip.
948
+ */
949
+ function invokeActorEventType(state, eventType) {
950
+ const match = /^xstate\.(done|error)\.actor\.(.+)$/.exec(eventType);
951
+ const snapshotMatch = /^xstate\.snapshot(?:\.actor)?\.(.+)$/.exec(eventType);
952
+ if (!match && !snapshotMatch) return null;
953
+ const verb = match?.[1] ?? "snapshot";
954
+ const actorId = match?.[2] ?? snapshotMatch?.[1];
955
+ const invoke = invokeItems(state.invoke).find((item) => item.invocationId === actorId);
956
+ if (!invoke) return null;
957
+ return `@statelyai.invoke.${verb}.${invoke.id}`;
958
+ }
959
+ function addTransitions(sourceId, value, eventType, idPrefix, extraData = {}) {
960
+ for (const [index, transition] of transitionObjects(value).entries()) {
961
+ const targets = transitionTargets(transition.target);
962
+ const target = targets[0];
963
+ const edgeId = `${sourceId}-${idPrefix}-${index}`;
964
+ graph.edges.push({
965
+ id: edgeId,
966
+ sourceId,
967
+ targetId: targetToNodeId(sourceId, target),
968
+ data: {
969
+ eventType,
970
+ ...targets.length > 1 ? { additionalTargetIds: targets.slice(1).map((item) => targetToNodeId(sourceId, item)) } : {},
971
+ ...transition.matches && typeof transition.matches === "object" ? { matches: transition.matches } : {},
972
+ transitionType: target ? transition.reenter ? "reenter" : "normal" : "targetless",
973
+ guard: guardObject(transition.guard),
974
+ ...transition.context !== void 0 ? { context: transition.context } : {},
975
+ ...transition.input !== void 0 ? { input: transition.input } : {},
976
+ actions: actionItems(transition.actions, `${edgeId}-actions`),
977
+ description: transition.meta && typeof transition.meta === "object" && Object.prototype.hasOwnProperty.call(transition.meta, XSTATE_V6_BRANCH_DESCRIPTION_META) ? typeof transition.meta[XSTATE_V6_BRANCH_DESCRIPTION_META] === "string" ? transition.meta[XSTATE_V6_BRANCH_DESCRIPTION_META] : null : typeof transition.description === "string" ? transition.description : null,
978
+ meta: transition.meta && typeof transition.meta === "object" ? transition.meta : null,
979
+ ...extraData
980
+ }
981
+ });
982
+ }
983
+ }
984
+ for (const node of graph.nodes) {
985
+ const id = node.id;
986
+ const state = stateByGraphId.get(id);
987
+ for (const [eventType, value] of Object.entries(state.on ?? {})) addTransitions(id, value, doneStateEventType(eventType) ?? invokeActorEventType(state, eventType) ?? eventType, eventType);
988
+ for (const [delay, value] of Object.entries(state.after ?? {})) addTransitions(id, value, `xstate.after.${delay}.${id}`, `after-${delay}`);
989
+ addTransitions(id, state.always, "", "always");
990
+ addTransitions(id, state.choice, "", "choice");
991
+ addTransitions(id, state.onDone, `@statelyai.state.done.${id}`, "state-done");
992
+ addTransitions(id, state.onError, `@statelyai.state.error.${id}`, "state-error");
993
+ addTransitions(id, state.onTimeout, `@statelyai.state.timeout.${id}`, "state-timeout");
994
+ const invokes = invokeItems(state.invoke);
995
+ for (const [invokeIndex, rawInvoke] of toArray(state.invoke).entries()) {
996
+ if (!rawInvoke || typeof rawInvoke !== "object") continue;
997
+ const invoke = invokes[invokeIndex];
998
+ if (!invoke) continue;
999
+ const invokeConfig = rawInvoke;
1000
+ for (const [slot, refSlot] of [
1001
+ ["onDone", "done"],
1002
+ ["onError", "error"],
1003
+ ["onSnapshot", "snapshot"],
1004
+ ["onTimeout", "timeout"]
1005
+ ]) addTransitions(id, invokeConfig[slot], `@statelyai.invoke.${refSlot}.${invoke.id}`, `invoke-${invoke.id}-${refSlot}`);
1006
+ }
1007
+ }
1008
+ for (const node of graph.nodes) {
1009
+ if (node.id === "root" || node.data.route === void 0) continue;
1010
+ const route = node.data.route;
1011
+ addTransitions("root", {
1012
+ ...isCodeExpression(route) ? {} : route && typeof route === "object" ? route : {},
1013
+ target: `#${node.data.nodeId ?? node.id}`
1014
+ }, "xstate.route", `route-${node.id}`, { route: true });
1015
+ }
1016
+ return graph;
1017
+ }
1018
+ function graphToNormalizedMachine(graph) {
1019
+ return graphToMachineConfig(graph);
1020
+ }
1021
+
1022
+ //#endregion
1023
+ export { graphToNormalizedMachine as a, normalizeProfileRef as c, graphToMachineConfig as i, stripExportDefault as l, getDelayKeyFromEventType as n, machineConfigToGraph as o, getResolvedNodeId as r, machineGraph_exports as s, applyDefaultInitialIds as t };