@statelyai/sdk 0.31.0 → 0.31.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/dist/sync.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  import "./openapi-BTDjYWXd.mjs";
2
2
  import { r as createStatelyClient } from "./studio-rSI54Ese.mjs";
3
- import { a as detectXStateSourceProfile, c as extractXStateMachineConfigEntries, d as graphToMachineConfig, g as normalizeMachineProfile, o as diffGraphsSemantically, p as graphToXStateTS, r as alignCompareGraphIds, t as INLINE_EXPRESSION_DIRECTIVE_FIELDS, u as graphChangeToPatchesResult, v as serializeJS } from "./dist-BQEaIgBI.mjs";
3
+ import { S as toXStateV6MachineConfig, a as alignCompareGraphIds, c as diffGraphsSemantically, d as getDelayKeyFromEventType, g as graphToXStateTS, i as XSTATE_V6_FN_TRANSITION_META, m as graphToMachineConfig, p as graphChangeToPatchesResult, r as XSTATE_V6_BRANCH_DESCRIPTION_META, s as detectXStateSourceProfile, t as INLINE_EXPRESSION_DIRECTIVE_FIELDS, u as extractXStateMachineConfigEntries, x as serializeJS, y as normalizeMachineProfile } from "./dist-wbhkeGh6.mjs";
4
4
  import { n as getStatelyPragma, r as upsertStatelyPragma, t as findStatelyPragmaAttachments } from "./statelyPragma-D46lczJR.mjs";
5
5
  import { fromStudioMachine, toStudioMachine } from "./graph.mjs";
6
6
  import * as ts$1 from "typescript";
@@ -1248,6 +1248,10 @@ function fallbackRootReplacement(document, sourceFile, machineConfigNode, machin
1248
1248
  return addCodeImportReplacements(document, sourceFile, machineConfig, [createReplacement(document, sourceFile, machineConfigNode, machineConfig)]).sort(compareReplacementRangesDescending);
1249
1249
  }
1250
1250
  async function tryCreateTransitionPatchSplitForDocuments(document, sourceFile, machineConfigNode, machineConfig, patches, prevGraph, nextGraph, sourceLocations, openTextDocument) {
1251
+ if (isXStateV6Source(sourceLocations)) {
1252
+ const v6Split = await tryCreateV6TransitionPatchSplitForDocuments(document, sourceFile, machineConfigNode, machineConfig, patches, prevGraph, nextGraph, sourceLocations, openTextDocument);
1253
+ if (v6Split) return v6Split;
1254
+ }
1251
1255
  const replacements = [];
1252
1256
  const remainingPatches = [];
1253
1257
  const handledTransitionKeys = /* @__PURE__ */ new Set();
@@ -1302,6 +1306,114 @@ async function tryCreateTransitionPatchSplitForDocuments(document, sourceFile, m
1302
1306
  remainingPatches
1303
1307
  } : null;
1304
1308
  }
1309
+ async function tryCreateV6TransitionPatchSplitForDocuments(document, sourceFile, machineConfigNode, machineConfig, patches, prevGraph, nextGraph, sourceLocations, openTextDocument) {
1310
+ applyV6FunctionDescriptionEdits(machineConfig, machineConfigNode, patches, prevGraph, nextGraph);
1311
+ const propertiesByPath = /* @__PURE__ */ new Map();
1312
+ const remainingPatches = [];
1313
+ const deletedStatePaths = patches.flatMap((patch) => {
1314
+ if (patch.op !== "deleteState") return [];
1315
+ const path = resolveStatePath(prevGraph, patch.stateId);
1316
+ return path ? [path] : [];
1317
+ });
1318
+ for (const patch of patches) {
1319
+ const edgeId = getTransitionPatchEdgeId(patch, prevGraph, nextGraph);
1320
+ if ((edgeId ? prevGraph.edges.find((edge) => edge.id === edgeId) ?? nextGraph.edges.find((edge) => edge.id === edgeId) : void 0)?.data?.meta?.[XSTATE_V6_FN_TRANSITION_META] === true && patch.op !== "deleteTransition") return {
1321
+ replacements: [],
1322
+ remainingPatches: []
1323
+ };
1324
+ const targets = getV6TransitionPropertyTargets(patch, prevGraph, nextGraph);
1325
+ if (targets.length === 0) {
1326
+ remainingPatches.push(patch);
1327
+ continue;
1328
+ }
1329
+ for (const target of targets) {
1330
+ if (deletedStatePaths.some((deletedPath) => isPathEqualOrDescendant(target.path, deletedPath))) continue;
1331
+ const key = target.path.join(".");
1332
+ const group = propertiesByPath.get(key) ?? {
1333
+ path: target.path,
1334
+ properties: /* @__PURE__ */ new Map()
1335
+ };
1336
+ const slots = group.properties.get(target.propertyName) ?? /* @__PURE__ */ new Set();
1337
+ if (target.slotKey !== null) slots.add(target.slotKey);
1338
+ group.properties.set(target.propertyName, slots);
1339
+ propertiesByPath.set(key, group);
1340
+ }
1341
+ }
1342
+ if (propertiesByPath.size === 0) return null;
1343
+ const replacements = [];
1344
+ for (const { path, properties } of propertiesByPath.values()) {
1345
+ if (!canSerializeXStateV6TransitionProperties(machineConfig, path, properties)) return {
1346
+ replacements: [],
1347
+ remainingPatches: []
1348
+ };
1349
+ const propertyReplacements = await createStatePropertiesReplacementForDocuments(document, sourceFile, machineConfigNode, machineConfig, path, [...properties.keys()], sourceLocations, openTextDocument, properties);
1350
+ if (!propertyReplacements) return null;
1351
+ replacements.push(...propertyReplacements);
1352
+ }
1353
+ return {
1354
+ replacements: replacements.sort(compareReplacementRangesDescending),
1355
+ remainingPatches
1356
+ };
1357
+ }
1358
+ function applyV6FunctionDescriptionEdits(machineConfig, machineConfigNode, patches, prevGraph, nextGraph) {
1359
+ for (const patch of patches) {
1360
+ if (patch.op !== "updateTransition" || patch.transitionDescription === void 0 || Object.prototype.hasOwnProperty.call(patch.meta ?? {}, XSTATE_V6_BRANCH_DESCRIPTION_META)) continue;
1361
+ const target = getTransitionPatchTarget(patch, prevGraph, nextGraph);
1362
+ if (!target) continue;
1363
+ const stateObject = getStateObjectLiteralByPath(machineConfigNode, target.sourcePath);
1364
+ if (!stateObject || !isV6FunctionTransitionSource(stateObject, target.previousEventType)) continue;
1365
+ const stateConfig = getStateConfigByPath(machineConfig, target.sourcePath);
1366
+ const transitions = (isMachineConfig(stateConfig?.on) ? stateConfig.on : null)?.[target.eventType];
1367
+ if (!Array.isArray(transitions)) continue;
1368
+ for (const transition of transitions) {
1369
+ if (!isMachineConfig(transition)) continue;
1370
+ if (patch.transitionDescription === null) delete transition.description;
1371
+ else transition.description = patch.transitionDescription;
1372
+ }
1373
+ }
1374
+ }
1375
+ function isV6FunctionTransitionSource(stateObject, eventType) {
1376
+ const onObject = getObjectLiteralProperty(stateObject, "on");
1377
+ if (!onObject) return false;
1378
+ const eventProperty = findObjectLiteralProperty(onObject, eventType);
1379
+ if (!eventProperty || !ts$1.isPropertyAssignment(eventProperty)) return false;
1380
+ const initializer = unwrapExpression$1(eventProperty.initializer);
1381
+ if (ts$1.isArrowFunction(initializer) || ts$1.isFunctionExpression(initializer)) return true;
1382
+ if (!ts$1.isObjectLiteralExpression(initializer)) return false;
1383
+ return initializer.properties.some((property) => ts$1.isPropertyAssignment(property) && property.name.getText().replace(/^['"]|['"]$/g, "") === "to");
1384
+ }
1385
+ function canSerializeXStateV6TransitionProperties(machineConfig, path, properties) {
1386
+ const stateConfig = getStateConfigByPath(machineConfig, path);
1387
+ if (!stateConfig) return false;
1388
+ for (const [propertyName, slots] of properties) {
1389
+ const value = stateConfig[propertyName];
1390
+ if (value === void 0) continue;
1391
+ const converted = getXStateV6PropertyValue(propertyName, value);
1392
+ if (propertyName === "on" || propertyName === "after") {
1393
+ if (!isMachineConfig(converted)) return false;
1394
+ if ([...slots].some((slot) => Array.isArray(converted[slot]))) return false;
1395
+ continue;
1396
+ }
1397
+ if (propertyName === "invoke") {
1398
+ const invokes = Array.isArray(converted) ? converted : [converted];
1399
+ for (const slotRef of slots) {
1400
+ const match = /^@statelyai\.invoke\.(done|error|snapshot|timeout)\.(.+)$/.exec(slotRef);
1401
+ if (!match) return false;
1402
+ const invoke = invokes[findXStateV6InvokeIndex(invokes, match[2])];
1403
+ const slot = {
1404
+ done: "onDone",
1405
+ error: "onError",
1406
+ snapshot: "onSnapshot",
1407
+ timeout: "onTimeout"
1408
+ }[match[1]];
1409
+ if (!isMachineConfig(invoke) || Array.isArray(invoke[slot])) return false;
1410
+ }
1411
+ continue;
1412
+ }
1413
+ if (Array.isArray(converted)) return false;
1414
+ }
1415
+ return true;
1416
+ }
1305
1417
  async function createDeleteTransitionReplacementsForDocuments(document, sourceFile, machineConfigNode, transitionTarget, sourceLocations, openTextDocument) {
1306
1418
  const mappedTarget = await getMappedStateReplacementTarget(document, sourceFile, sourceLocations, transitionTarget.sourcePath, openTextDocument);
1307
1419
  const targetDocument = mappedTarget?.document ?? document;
@@ -1329,7 +1441,7 @@ async function createTransitionReplacementForDocuments(document, sourceFile, mac
1329
1441
  if (onObject) return createObjectLiteralPropertyInsertion(targetDocument, targetSourceFile, onObject, transitionTarget.eventType, nextTransitionValue);
1330
1442
  return createObjectLiteralPropertyInsertion(targetDocument, targetSourceFile, stateObject, "on", { [transitionTarget.eventType]: nextTransitionValue });
1331
1443
  }
1332
- async function createStatePropertiesReplacementForDocuments(document, sourceFile, machineConfigNode, machineConfig, path, propertyNames, sourceLocations, openTextDocument) {
1444
+ async function createStatePropertiesReplacementForDocuments(document, sourceFile, machineConfigNode, machineConfig, path, propertyNames, sourceLocations, openTextDocument, affectedV6Slots) {
1333
1445
  const nextStateConfig = getStateConfigByPath(machineConfig, path);
1334
1446
  if (!isMachineConfig(nextStateConfig)) return null;
1335
1447
  const mappedTarget = await getMappedStateReplacementTarget(document, sourceFile, sourceLocations, path, openTextDocument);
@@ -1340,8 +1452,36 @@ async function createStatePropertiesReplacementForDocuments(document, sourceFile
1340
1452
  const replacements = [];
1341
1453
  const insertionEntries = [];
1342
1454
  for (const propertyName of propertyNames) {
1343
- const nextValue = nextStateConfig[propertyName];
1455
+ const rawNextValue = nextStateConfig[propertyName];
1344
1456
  const property = findObjectLiteralProperty(stateObject, propertyName);
1457
+ const affectedSlots = affectedV6Slots?.get(propertyName);
1458
+ const nextValue = rawNextValue === void 0 || !isXStateV6Source(sourceLocations) ? rawNextValue : getXStateV6PropertyValue(propertyName, rawNextValue);
1459
+ if (affectedSlots && (propertyName === "on" || propertyName === "after") && property && ts$1.isPropertyAssignment(property) && isMachineConfig(nextValue)) {
1460
+ const existingMap = unwrapObjectLiteralExpression(property.initializer);
1461
+ if (existingMap) {
1462
+ const insertedSlots = [];
1463
+ for (const slot of affectedSlots) {
1464
+ const existingSlot = findObjectLiteralProperty(existingMap, slot);
1465
+ const nextSlotValue = nextValue[slot];
1466
+ if (nextSlotValue === void 0) {
1467
+ if (existingSlot) replacements.push(createObjectLiteralPropertyDeletion(targetDocument, targetSourceFile, existingMap, existingSlot));
1468
+ } else if (existingSlot) replacements.push(createPropertyValueReplacement(targetDocument, targetSourceFile, existingSlot, nextSlotValue));
1469
+ else insertedSlots.push({
1470
+ key: slot,
1471
+ config: nextSlotValue
1472
+ });
1473
+ }
1474
+ if (insertedSlots.length > 0) replacements.push(createObjectLiteralPropertiesInsertion(targetDocument, targetSourceFile, existingMap, insertedSlots));
1475
+ continue;
1476
+ }
1477
+ }
1478
+ if (affectedSlots && propertyName === "invoke" && property && ts$1.isPropertyAssignment(property)) {
1479
+ const invokeReplacements = createXStateV6InvokeSlotReplacements(targetDocument, targetSourceFile, property.initializer, nextValue, affectedSlots);
1480
+ if (invokeReplacements) {
1481
+ replacements.push(...invokeReplacements);
1482
+ continue;
1483
+ }
1484
+ }
1345
1485
  if (nextValue === void 0) {
1346
1486
  if (!property) continue;
1347
1487
  replacements.push(createObjectLiteralPropertyDeletion(targetDocument, targetSourceFile, stateObject, property));
@@ -1359,10 +1499,63 @@ async function createStatePropertiesReplacementForDocuments(document, sourceFile
1359
1499
  if (insertionEntries.length > 0) replacements.push(createObjectLiteralPropertiesInsertion(targetDocument, targetSourceFile, stateObject, insertionEntries));
1360
1500
  return replacements.length > 0 ? replacements.sort(compareReplacementRangesDescending) : [];
1361
1501
  }
1502
+ function createXStateV6InvokeSlotReplacements(document, sourceFile, initializer, nextValue, affectedSlots) {
1503
+ const expression = unwrapExpression$1(initializer);
1504
+ const existingInvokes = ts$1.isArrayLiteralExpression(expression) ? expression.elements.filter(ts$1.isExpression) : [expression];
1505
+ const nextInvokes = Array.isArray(nextValue) ? nextValue : [nextValue];
1506
+ const replacements = [];
1507
+ const insertions = /* @__PURE__ */ new Map();
1508
+ for (const slotRef of affectedSlots) {
1509
+ const match = /^@statelyai\.invoke\.(done|error|snapshot|timeout)\.(.+)$/.exec(slotRef);
1510
+ if (!match) return null;
1511
+ const propertyName = {
1512
+ done: "onDone",
1513
+ error: "onError",
1514
+ snapshot: "onSnapshot",
1515
+ timeout: "onTimeout"
1516
+ }[match[1]];
1517
+ const invokeId = match[2];
1518
+ const invokeIndex = findXStateV6InvokeIndex(nextInvokes, invokeId);
1519
+ const existingInvoke = existingInvokes[invokeIndex];
1520
+ const nextInvoke = nextInvokes[invokeIndex];
1521
+ if (invokeIndex < 0 || !existingInvoke || !nextInvoke || !isMachineConfig(nextInvoke)) return null;
1522
+ const existingObject = unwrapObjectLiteralExpression(existingInvoke);
1523
+ if (!existingObject) return null;
1524
+ const existingProperty = findObjectLiteralProperty(existingObject, propertyName);
1525
+ const nextSlotValue = nextInvoke[propertyName];
1526
+ if (nextSlotValue === void 0) {
1527
+ if (existingProperty) replacements.push(createObjectLiteralPropertyDeletion(document, sourceFile, existingObject, existingProperty));
1528
+ } else if (existingProperty) replacements.push(createPropertyValueReplacement(document, sourceFile, existingProperty, nextSlotValue));
1529
+ else {
1530
+ const entries = insertions.get(existingObject) ?? [];
1531
+ entries.push({
1532
+ key: propertyName,
1533
+ config: nextSlotValue
1534
+ });
1535
+ insertions.set(existingObject, entries);
1536
+ }
1537
+ }
1538
+ for (const [existingObject, entries] of insertions) replacements.push(createObjectLiteralPropertiesInsertion(document, sourceFile, existingObject, entries));
1539
+ return replacements;
1540
+ }
1541
+ function findXStateV6InvokeIndex(invokes, invokeId) {
1542
+ return invokes.findIndex((candidate, index) => {
1543
+ if (!isMachineConfig(candidate)) return false;
1544
+ if (candidate.id === invokeId) return true;
1545
+ if (candidate.id !== void 0) return false;
1546
+ if (invokeId === `$auto-inline-${index}`) return true;
1547
+ return typeof candidate.src === "string" && invokeId === `$auto-invoke-${candidate.src}`;
1548
+ });
1549
+ }
1550
+ function getXStateV6PropertyValue(propertyName, value) {
1551
+ const converted = toXStateV6MachineConfig({ [propertyName]: value });
1552
+ return isMachineConfig(converted) ? converted[propertyName] : value;
1553
+ }
1362
1554
  function getTransitionPatchTarget(patch, prevGraph, nextGraph) {
1363
1555
  const patchRecord = patch;
1364
1556
  if (patch.op === "createTransition") {
1365
- const edge = patch.id ? nextGraph.edges.find((item) => item.id === patch.id) : nextGraph.edges.find((item) => item.sourceId === patch.sourceId);
1557
+ const edge = getCreatedTransitionEdge(patch, prevGraph, nextGraph);
1558
+ if (!edge) return null;
1366
1559
  const sourcePath = resolveStatePath(nextGraph, patch.sourceId);
1367
1560
  const eventType = edge?.data?.eventType ?? edge?.label ?? patchRecord.eventType;
1368
1561
  if (!sourcePath || !eventType) return null;
@@ -1370,8 +1563,8 @@ function getTransitionPatchTarget(patch, prevGraph, nextGraph) {
1370
1563
  sourcePath,
1371
1564
  eventType,
1372
1565
  previousEventType: eventType,
1373
- transitionId: edge?.id ?? patch.id,
1374
- index: getTransitionIndexFromId(edge?.id ?? patch.id ?? "")
1566
+ transitionId: edge.id,
1567
+ index: getTransitionIndexFromId(edge.id)
1375
1568
  };
1376
1569
  }
1377
1570
  const edgeId = patch.op === "updateTransition" || patch.op === "deleteTransition" ? patch.transitionId : patch.op === "setGuard" || patch.op === "deleteGuard" ? patch.edgeId : patch.op === "createAction" || patch.op === "updateAction" || patch.op === "deleteAction" ? "edgeId" in patch.location ? patch.location.edgeId : null : null;
@@ -1390,6 +1583,68 @@ function getTransitionPatchTarget(patch, prevGraph, nextGraph) {
1390
1583
  index: getTransitionIndexFromId(edgeId)
1391
1584
  };
1392
1585
  }
1586
+ function isXStateV6Source(sourceLocations) {
1587
+ return sourceLocations?.profile === "xstate-v6-alpha" || sourceLocations?.profileRef?.startsWith("@statelyai/xstate@6") === true;
1588
+ }
1589
+ function getV6TransitionPropertyTargets(patch, prevGraph, nextGraph) {
1590
+ const edgeId = getTransitionPatchEdgeId(patch, prevGraph, nextGraph);
1591
+ if (!edgeId) return [];
1592
+ const candidates = [{
1593
+ edge: prevGraph.edges.find((edge) => edge.id === edgeId),
1594
+ graph: prevGraph
1595
+ }, {
1596
+ edge: nextGraph.edges.find((edge) => edge.id === edgeId),
1597
+ graph: nextGraph
1598
+ }];
1599
+ const targets = /* @__PURE__ */ new Map();
1600
+ for (const { edge, graph } of candidates) {
1601
+ if (!edge || edge.data?.route) continue;
1602
+ const path = resolveStatePath(graph, edge.sourceId);
1603
+ if (!path) continue;
1604
+ const eventType = edge.data?.eventType ?? edge.label ?? "";
1605
+ const sourceNode = graph.nodes.find((node) => node.id === edge.sourceId);
1606
+ let propertyName;
1607
+ let slotKey = null;
1608
+ if (eventType === "") propertyName = sourceNode?.data.type === "choice" ? "choice" : "always";
1609
+ else if (eventType.startsWith("xstate.after.")) {
1610
+ propertyName = "after";
1611
+ slotKey = getDelayKeyFromEventType(eventType, edge.sourceId);
1612
+ } else if (eventType.startsWith("@statelyai.invoke.")) {
1613
+ propertyName = "invoke";
1614
+ slotKey = eventType;
1615
+ } else if (eventType.startsWith("@statelyai.state.done.")) propertyName = "onDone";
1616
+ else if (eventType.startsWith("@statelyai.state.error.")) propertyName = "onError";
1617
+ else if (eventType.startsWith("@statelyai.state.timeout.")) propertyName = "onTimeout";
1618
+ else {
1619
+ propertyName = "on";
1620
+ slotKey = eventType;
1621
+ }
1622
+ targets.set(`${path.join(".")}:${propertyName}:${slotKey ?? ""}`, {
1623
+ path,
1624
+ propertyName,
1625
+ slotKey
1626
+ });
1627
+ }
1628
+ return [...targets.values()];
1629
+ }
1630
+ function getCreatedTransitionEdge(patch, prevGraph, nextGraph) {
1631
+ const previousIds = new Set(prevGraph.edges.map((edge) => edge.id));
1632
+ let candidates = nextGraph.edges.filter((edge) => !previousIds.has(edge.id) && edge.sourceId === patch.sourceId);
1633
+ const createdWithRequestedId = patch.id ? candidates.find((edge) => edge.id === patch.id) : void 0;
1634
+ if (createdWithRequestedId) return createdWithRequestedId;
1635
+ if (patch.eventType !== void 0) candidates = candidates.filter((edge) => (edge.data?.eventType ?? edge.label) === patch.eventType);
1636
+ if (patch.targetId !== void 0) candidates = candidates.filter((edge) => edge.targetId === patch.targetId);
1637
+ if (patch.transitionType !== void 0) candidates = candidates.filter((edge) => edge.data?.transitionType === patch.transitionType);
1638
+ if (patch.matches !== void 0) candidates = candidates.filter((edge) => JSON.stringify(edge.data?.matches) === JSON.stringify(patch.matches));
1639
+ return candidates.length === 1 ? candidates[0] : null;
1640
+ }
1641
+ function getTransitionPatchEdgeId(patch, prevGraph, nextGraph) {
1642
+ if (patch.op === "createTransition") return getCreatedTransitionEdge(patch, prevGraph, nextGraph)?.id ?? null;
1643
+ if (patch.op === "updateTransition" || patch.op === "deleteTransition") return patch.transitionId;
1644
+ if (patch.op === "setGuard" || patch.op === "deleteGuard") return patch.edgeId;
1645
+ if ((patch.op === "createAction" || patch.op === "updateAction" || patch.op === "deleteAction") && "edgeId" in patch.location) return patch.location.edgeId;
1646
+ return null;
1647
+ }
1393
1648
  function getStatePropertyPatchTargets(patch, prevGraph, nextGraph) {
1394
1649
  if (patch.op === "updateSchemas") return [{
1395
1650
  path: [],
@@ -1481,7 +1736,24 @@ function createArrayElementDeletion(document, sourceFile, arrayLiteral, element)
1481
1736
  }
1482
1737
  function createExpressionReplacement(document, sourceFile, expression, nextValue) {
1483
1738
  const formatting = getFormattingContextForExpression(document, sourceFile, expression);
1484
- return createOffsetReplacement(document, expression.getStart(sourceFile), expression.getEnd(), printExpression(valueToExpression(nextValue, unwrapExpression$1(expression)), sourceFile, formatting));
1739
+ const printed = containsRawCodeLike(nextValue) ? reindentPrintedExpression(serializeJS(nextValue), formatting) : printExpression(valueToExpression(nextValue, unwrapExpression$1(expression)), sourceFile, formatting);
1740
+ return createOffsetReplacement(document, expression.getStart(sourceFile), expression.getEnd(), preserveExpressionComments(expression, sourceFile, printed, formatting));
1741
+ }
1742
+ function preserveExpressionComments(expression, sourceFile, printed, formatting) {
1743
+ const original = sourceFile.text.slice(expression.getStart(sourceFile), expression.getEnd());
1744
+ const scanner = ts$1.createScanner(ts$1.ScriptTarget.Latest, false, ts$1.LanguageVariant.JSX, original);
1745
+ const comments = [];
1746
+ for (let token = scanner.scan(); token !== ts$1.SyntaxKind.EndOfFileToken; token = scanner.scan()) if (token === ts$1.SyntaxKind.SingleLineCommentTrivia || token === ts$1.SyntaxKind.MultiLineCommentTrivia) comments.push(scanner.getTokenText());
1747
+ const missing = comments.filter((comment) => !printed.includes(comment));
1748
+ if (missing.length === 0) return printed;
1749
+ const lineSeparator = formatting.newLineKind === ts$1.NewLineKind.CarriageReturnLineFeed ? "\r\n" : "\n";
1750
+ const bodyStart = printed.indexOf("=> {");
1751
+ if (bodyStart >= 0) {
1752
+ const insertion = bodyStart + 4;
1753
+ const indent = `${formatting.baseIndent}${formatting.indentUnit}`;
1754
+ return `${printed.slice(0, insertion)}${lineSeparator}${missing.map((comment) => `${indent}${comment}`).join(lineSeparator)}${printed.slice(insertion)}`;
1755
+ }
1756
+ return `${missing.join(lineSeparator)}${lineSeparator}${formatting.baseIndent}${printed}`;
1485
1757
  }
1486
1758
  function createPropertyValueReplacement(document, sourceFile, property, nextValue) {
1487
1759
  if (!ts$1.isPropertyAssignment(property)) return createPropertyAssignmentReplacement(document, sourceFile, property, getStatePropertyKeyText(property) ?? "value", nextValue);
@@ -1963,7 +2235,8 @@ function getStatePropertyKeyText(property) {
1963
2235
  return null;
1964
2236
  }
1965
2237
  function printObjectLiteralProperty(key, value, sourceFile, formatting) {
1966
- const objectText = printExpression(valueToExpression({ [key]: value }), sourceFile, formatting);
2238
+ const objectValue = { [key]: value };
2239
+ const objectText = containsRawCodeLike(value) ? reindentPrintedExpression(serializeJS(objectValue), formatting) : printExpression(valueToExpression(objectValue), sourceFile, formatting);
1967
2240
  const lineSeparator = formatting.newLineKind === ts$1.NewLineKind.CarriageReturnLineFeed ? "\r\n" : "\n";
1968
2241
  const lines = objectText.split(/\r?\n/);
1969
2242
  if (lines.length <= 2) return objectText.replace(/^\{\s*/, "").replace(/\s*\}$/, "");
@@ -2391,9 +2664,10 @@ function tryCreateSemanticReplacements(document, sourceFile, machineConfigNode,
2391
2664
  return replacements.sort(compareReplacementRangesDescending);
2392
2665
  }
2393
2666
  async function tryCreateSemanticPatchSplitForDocuments(document, sourceFile, machineConfigNode, patches, prevGraph, nextGraph, sourceLocations, openTextDocument) {
2394
- const split = getSemanticStateRenamePatchSplit(patches, prevGraph, nextGraph);
2395
- if (!split) return null;
2396
- const replacements = [];
2667
+ const descriptionSplit = isXStateV6Source(sourceLocations) ? await tryCreateV6WrapperDescriptionPatchSplitForDocuments(document, sourceFile, machineConfigNode, patches, prevGraph, nextGraph, sourceLocations, openTextDocument) : null;
2668
+ const split = getSemanticStateRenamePatchSplit(descriptionSplit?.remainingPatches ?? patches, prevGraph, nextGraph);
2669
+ if (!split) return descriptionSplit;
2670
+ const replacements = [...descriptionSplit?.replacements ?? []];
2397
2671
  const targetLiterals = await collectMappedTargetStringLiterals(document, sourceFile, machineConfigNode, sourceLocations, openTextDocument);
2398
2672
  let activeSourceLocations = sourceLocations;
2399
2673
  for (const rename of split.renames) {
@@ -2410,6 +2684,55 @@ async function tryCreateSemanticPatchSplitForDocuments(document, sourceFile, mac
2410
2684
  sourceLocations: activeSourceLocations
2411
2685
  };
2412
2686
  }
2687
+ async function tryCreateV6WrapperDescriptionPatchSplitForDocuments(document, sourceFile, machineConfigNode, patches, prevGraph, nextGraph, sourceLocations, openTextDocument) {
2688
+ const replacements = [];
2689
+ const remainingPatches = [];
2690
+ const descriptionsByTarget = /* @__PURE__ */ new Map();
2691
+ for (const patch of patches) {
2692
+ if (patch.op !== "updateTransition" || patch.transitionDescription === void 0 || Object.entries(patch).some(([key, value]) => value !== void 0 && ![
2693
+ "op",
2694
+ "transitionId",
2695
+ "transitionDescription"
2696
+ ].includes(key))) {
2697
+ remainingPatches.push(patch);
2698
+ continue;
2699
+ }
2700
+ const target = getTransitionPatchTarget(patch, prevGraph, nextGraph);
2701
+ if (!target || target.previousEventType !== target.eventType) {
2702
+ remainingPatches.push(patch);
2703
+ continue;
2704
+ }
2705
+ const targetKey = `${target.sourcePath.join(".")}:${target.eventType}`;
2706
+ if (descriptionsByTarget.has(targetKey)) {
2707
+ if (descriptionsByTarget.get(targetKey) !== patch.transitionDescription) return null;
2708
+ continue;
2709
+ }
2710
+ descriptionsByTarget.set(targetKey, patch.transitionDescription);
2711
+ const mappedTarget = await getMappedStateReplacementTarget(document, sourceFile, sourceLocations, target.sourcePath, openTextDocument);
2712
+ const targetDocument = mappedTarget?.document ?? document;
2713
+ const targetSourceFile = mappedTarget?.sourceFile ?? sourceFile;
2714
+ const stateObject = mappedTarget?.node ?? getStateObjectLiteralByPath(machineConfigNode, target.sourcePath);
2715
+ const onObject = stateObject ? getObjectLiteralProperty(stateObject, "on") : null;
2716
+ const eventProperty = onObject ? findObjectLiteralProperty(onObject, target.eventType) : null;
2717
+ const initializer = eventProperty && ts$1.isPropertyAssignment(eventProperty) ? unwrapExpression$1(eventProperty.initializer) : null;
2718
+ const wrapper = initializer && ts$1.isObjectLiteralExpression(initializer) ? initializer : null;
2719
+ const toProperty = wrapper ? getPropertyAssignment(wrapper, "to") : null;
2720
+ if (!wrapper || !toProperty) {
2721
+ remainingPatches.push(patch);
2722
+ continue;
2723
+ }
2724
+ const descriptionProperty = getPropertyAssignment(wrapper, "description");
2725
+ if (patch.transitionDescription === null) {
2726
+ if (descriptionProperty) replacements.push(createObjectLiteralPropertyDeletion(targetDocument, targetSourceFile, wrapper, descriptionProperty));
2727
+ } else if (descriptionProperty) replacements.push(createPropertyValueReplacement(targetDocument, targetSourceFile, descriptionProperty, patch.transitionDescription));
2728
+ else replacements.push(...createObjectLiteralPropertyInsertion(targetDocument, targetSourceFile, wrapper, "description", patch.transitionDescription));
2729
+ }
2730
+ return replacements.length > 0 ? {
2731
+ replacements,
2732
+ remainingPatches,
2733
+ sourceLocations
2734
+ } : null;
2735
+ }
2413
2736
  function getSemanticStateRenameFromPatch(patch, prevGraph, nextGraph) {
2414
2737
  if (patch.op !== "updateState" || patch.key === void 0) return null;
2415
2738
  const prevPath = resolveStatePath(prevGraph, patch.stateId);
@@ -3048,11 +3371,12 @@ function reindentPrintedExpression(printed, formatting) {
3048
3371
  const lineSeparator = formatting.newLineKind === ts$1.NewLineKind.CarriageReturnLineFeed ? "\r\n" : "\n";
3049
3372
  const lines = printed.split(/\r?\n/);
3050
3373
  if (lines.length <= 1) return printed;
3374
+ const printedIndentUnit = Math.min(...lines.slice(1).map((line) => line.match(/^ */)?.[0].length ?? 0).filter((indent) => indent > 0), 4);
3051
3375
  return lines.map((line, index) => {
3052
3376
  if (index === 0) return line;
3053
3377
  if (line.trim() === "") return "";
3054
3378
  const leadingSpaces = line.match(/^ */)?.[0].length ?? 0;
3055
- const indentLevel = Math.floor(leadingSpaces / 4);
3379
+ const indentLevel = Math.floor(leadingSpaces / printedIndentUnit);
3056
3380
  return `${formatting.baseIndent}${formatting.indentUnit.repeat(indentLevel)}${line.slice(leadingSpaces)}`;
3057
3381
  }).join(lineSeparator);
3058
3382
  }
@@ -3121,7 +3445,12 @@ function valueToExpression(value, existingExpression) {
3121
3445
  }
3122
3446
  if (isMachineConfig(value)) {
3123
3447
  const existingObject = existingExpression && ts$1.isObjectLiteralExpression(existingExpression) ? existingExpression : void 0;
3124
- const properties = Object.entries(value).filter(([, propertyValue]) => propertyValue !== void 0).map(([key, propertyValue]) => {
3448
+ const entries = Object.entries(value).filter(([, propertyValue]) => propertyValue !== void 0);
3449
+ if (existingObject) {
3450
+ const existingOrder = new Map(existingObject.properties.map((property, index) => [getStatePropertyKeyText(property), index]));
3451
+ entries.sort(([left], [right]) => (existingOrder.get(left) ?? Number.MAX_SAFE_INTEGER) - (existingOrder.get(right) ?? Number.MAX_SAFE_INTEGER));
3452
+ }
3453
+ const properties = entries.map(([key, propertyValue]) => {
3125
3454
  const existingProperty = existingObject ? getPropertyAssignment(existingObject, key) : null;
3126
3455
  const nextInitializer = getPreservedPropertyInitializer(key, propertyValue, existingProperty?.initializer) ?? valueToExpression(propertyValue, existingProperty?.initializer);
3127
3456
  if (existingProperty) return ts$1.factory.updatePropertyAssignment(existingProperty, existingProperty.name, nextInitializer);
@@ -3146,6 +3475,11 @@ function isRawCodeLike(value) {
3146
3475
  const raw = value;
3147
3476
  return raw.constructor?.name === "RawCode" && typeof raw.code === "string";
3148
3477
  }
3478
+ function containsRawCodeLike(value) {
3479
+ if (isRawCodeLike(value)) return true;
3480
+ if (Array.isArray(value)) return value.some(containsRawCodeLike);
3481
+ return Boolean(value) && typeof value === "object" && Object.values(value).some(containsRawCodeLike);
3482
+ }
3149
3483
  function inlineExpressionDirectiveToExpression(value) {
3150
3484
  if (!isInlineExpressionDirective(value)) return null;
3151
3485
  return ts$1.factory.createIdentifier(value.expr);
@@ -365,7 +365,7 @@ function createWebSocketTransport(options) {
365
365
 
366
366
  //#endregion
367
367
  //#region src/version.ts
368
- const SDK_VERSION = "0.31.0";
368
+ const SDK_VERSION = "0.31.1";
369
369
  function inspectionRuntime() {
370
370
  if (typeof window !== "undefined") return "browser";
371
371
  if (typeof process !== "undefined" && process.versions?.node) return "node";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@statelyai/sdk",
3
- "version": "0.31.0",
3
+ "version": "0.31.1",
4
4
  "license": "MIT",
5
5
  "bin": {
6
6
  "stately-sdk": "./dist/bin.mjs"
@@ -93,8 +93,8 @@
93
93
  "jsdom": "^27.4.0",
94
94
  "tsdown": "0.21.0-beta.2",
95
95
  "vitest": "^3.2.4",
96
- "@statelyai/api-contract": "0.4.5",
97
- "@statelyai/graph-tools": "0.8.1"
96
+ "@statelyai/api-contract": "0.4.7",
97
+ "@statelyai/graph-tools": "0.8.3"
98
98
  },
99
99
  "engines": {
100
100
  "node": ">=22.4"