@statelyai/sdk 0.29.1 → 0.31.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 (34) hide show
  1. package/README.md +6 -0
  2. package/dist/assetStorage.d.mts +1 -1
  3. package/dist/auth.d.mts +1 -1
  4. package/dist/{statelyPragma-p1vu8PmH.mjs → dist-BQEaIgBI.mjs} +113 -134
  5. package/dist/{editor-sync-types-DB1N6QUK.d.mts → editor-sync-types-CPpzTSnT.d.mts} +4 -0
  6. package/dist/{editorHostSession-vSt07IJV.d.mts → editorHostSession-BHr3WBHT.d.mts} +105 -6
  7. package/dist/{editorHostSession-DNpXPNAc.mjs → editorHostSession-Dm5i4mg_.mjs} +380 -20
  8. package/dist/editorHostSession.d.mts +2 -2
  9. package/dist/editorHostSession.mjs +3 -2
  10. package/dist/embed.d.mts +3 -4
  11. package/dist/embed.mjs +5 -2
  12. package/dist/{graph-C8E1Exad.d.mts → graph-CehpcL7P.d.mts} +1 -1
  13. package/dist/graph.d.mts +1 -1
  14. package/dist/{index-D4pdeDpT.d.mts → index-ZlKF1x_z.d.mts} +80 -1
  15. package/dist/index.d.mts +8 -9
  16. package/dist/index.mjs +6 -5
  17. package/dist/{inspect-dmCvrIl1.mjs → inspect-BD6fDWzd.mjs} +1 -1
  18. package/dist/{inspect-D61HS-t7.d.mts → inspect-BgYRNJF9.d.mts} +1 -2
  19. package/dist/inspect.d.mts +2 -2
  20. package/dist/inspect.mjs +2 -2
  21. package/dist/patchTypes.d.mts +1 -1
  22. package/dist/protocol-DOt1Vz-5.d.mts +842 -0
  23. package/dist/protocol.d.mts +2 -821
  24. package/dist/relay.d.mts +1 -1
  25. package/dist/statelyPragma-D46lczJR.mjs +102 -0
  26. package/dist/{studio-D-yqFd0u.d.mts → studio-GZ6E_xns.d.mts} +2 -2
  27. package/dist/studio.d.mts +1 -1
  28. package/dist/sync.d.mts +2 -2
  29. package/dist/sync.mjs +65 -18
  30. package/dist/{version-DC3yW9Dk.mjs → version-DbnY8nLV.mjs} +1 -1
  31. package/package.json +3 -3
  32. package/schemas/statelyai.schema.json +6 -0
  33. package/dist/embedPanel-Bpbq4sfJ.d.mts +0 -13
  34. /package/dist/{auth-BPyCCHYo.d.mts → auth-Dg7prjeL.d.mts} +0 -0
package/dist/relay.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { ProtocolMessage } from "./protocol.mjs";
1
+ import { dt as ProtocolMessage } from "./protocol-DOt1Vz-5.mjs";
2
2
 
3
3
  //#region src/relay.d.ts
4
4
  type InspectionRelayRole = 'producer' | 'viewer';
@@ -0,0 +1,102 @@
1
+ import ts from "typescript";
2
+
3
+ //#region src/statelyPragma.ts
4
+ function findStatelyPragmaAttachments(sourceText, fileName = "machine.ts") {
5
+ const sourceFile = ts.createSourceFile(fileName, sourceText, ts.ScriptTarget.Latest, true, getScriptKind(fileName));
6
+ const attachments = [];
7
+ const visit = (node) => {
8
+ if (ts.isCallExpression(node) && isCreateMachineExpression(node.expression)) {
9
+ const attachNode = findAttachNode(node);
10
+ if (attachNode) attachments.push({
11
+ machineStart: getMachineExpressionStart(node.expression, sourceFile),
12
+ attachStart: attachNode.getStart(sourceFile),
13
+ pragma: findAttachedStatelyPragma(sourceText, attachNode)
14
+ });
15
+ }
16
+ ts.forEachChild(node, visit);
17
+ };
18
+ visit(sourceFile);
19
+ return attachments;
20
+ }
21
+ function getStatelyPragma(sourceText, fileName = "machine.ts", machineIndex = 0) {
22
+ return findStatelyPragmaAttachments(sourceText, fileName)[machineIndex]?.pragma;
23
+ }
24
+ function upsertStatelyPragma(sourceText, id, options = {}) {
25
+ const attachment = findStatelyPragmaAttachments(sourceText, options.fileName ?? "machine.ts")[options.machineIndex ?? 0];
26
+ if (!attachment) return sourceText;
27
+ const lineEnding = options.lineEnding ?? detectLineEnding(sourceText);
28
+ const canonicalComment = `// @statelyai id=${id}`;
29
+ if (attachment.pragma) return sourceText.slice(0, attachment.pragma.start) + canonicalComment + sourceText.slice(attachment.pragma.end);
30
+ const insertText = `${getIndentationAtOffset(sourceText, attachment.attachStart)}${canonicalComment}${lineEnding}`;
31
+ return sourceText.slice(0, attachment.attachStart) + insertText + sourceText.slice(attachment.attachStart);
32
+ }
33
+ function findAttachedStatelyPragma(sourceText, node) {
34
+ const comments = ts.getLeadingCommentRanges(sourceText, node.getFullStart()) ?? [];
35
+ for (let index = comments.length - 1; index >= 0; index -= 1) {
36
+ const comment = comments[index];
37
+ const parsed = parseStatelyPragma(sourceText, comment.pos, comment.end);
38
+ if (parsed) return parsed;
39
+ }
40
+ }
41
+ function parseStatelyPragma(sourceText, start, end) {
42
+ const match = normalizeCommentContent(sourceText.slice(start, end)).match(/^@statelyai(?:\s+(.*))?$/s);
43
+ if (!match) return;
44
+ const fields = parseFields(match[1] ?? "");
45
+ return {
46
+ tag: "@statelyai",
47
+ id: fields.id,
48
+ fields,
49
+ start,
50
+ end
51
+ };
52
+ }
53
+ function normalizeCommentContent(rawComment) {
54
+ if (rawComment.startsWith("//")) return rawComment.slice(2).trim();
55
+ if (rawComment.startsWith("/*")) return rawComment.slice(2, rawComment.endsWith("*/") ? -2 : void 0).split(/\r?\n/).map((line) => line.replace(/^\s*\*\s?/, "")).join(" ").trim();
56
+ return rawComment.trim();
57
+ }
58
+ function parseFields(input) {
59
+ const fields = {};
60
+ for (const token of input.split(/\s+/)) {
61
+ if (!token) continue;
62
+ const equalsIndex = token.indexOf("=");
63
+ if (equalsIndex <= 0) continue;
64
+ const key = token.slice(0, equalsIndex);
65
+ const value = token.slice(equalsIndex + 1);
66
+ if (!key || !value) continue;
67
+ fields[key] = value;
68
+ }
69
+ return fields;
70
+ }
71
+ function findAttachNode(node) {
72
+ let current = node;
73
+ while (current?.parent) {
74
+ if (ts.isVariableStatement(current.parent) || ts.isExpressionStatement(current.parent) || ts.isExportAssignment(current.parent)) return current.parent;
75
+ current = current.parent;
76
+ }
77
+ return current;
78
+ }
79
+ function isCreateMachineExpression(expression) {
80
+ const isMachineFactoryName = (name) => name === "createMachine" || name === "createMachineFromConfig";
81
+ return ts.isIdentifier(expression) && isMachineFactoryName(expression.text) || ts.isPropertyAccessExpression(expression) && isMachineFactoryName(expression.name.text);
82
+ }
83
+ function getMachineExpressionStart(expression, sourceFile) {
84
+ if (ts.isPropertyAccessExpression(expression)) return expression.name.getStart(sourceFile);
85
+ return expression.getStart(sourceFile);
86
+ }
87
+ function getIndentationAtOffset(sourceText, offset) {
88
+ const lineStart = sourceText.lastIndexOf("\n", Math.max(0, offset - 1)) + 1;
89
+ return sourceText.slice(lineStart, offset).match(/^[ \t]*/)?.[0] ?? "";
90
+ }
91
+ function detectLineEnding(sourceText) {
92
+ return sourceText.includes("\r\n") ? "\r\n" : "\n";
93
+ }
94
+ function getScriptKind(fileName) {
95
+ if (fileName.endsWith(".tsx")) return ts.ScriptKind.TSX;
96
+ if (fileName.endsWith(".jsx")) return ts.ScriptKind.JSX;
97
+ if (fileName.endsWith(".js")) return ts.ScriptKind.JS;
98
+ return ts.ScriptKind.TS;
99
+ }
100
+
101
+ //#endregion
102
+ export { getStatelyPragma as n, upsertStatelyPragma as r, findStatelyPragmaAttachments as t };
@@ -1,5 +1,5 @@
1
- import { A as ZodObject, D as ZodLiteral, E as ZodEnum, F as ZodUnknown, I as output, L as $loose, M as ZodRecord, N as ZodString, O as ZodNullable, P as ZodUnion, R as $strip, T as ZodBoolean, j as ZodOptional, k as ZodNumber, w as ZodArray } from "./index-D4pdeDpT.mjs";
2
- import { n as StatelyCredential, t as StatelyAuthMode } from "./auth-BPyCCHYo.mjs";
1
+ import { A as ZodObject, D as ZodLiteral, E as ZodEnum, F as ZodUnknown, I as output, L as $loose, M as ZodRecord, N as ZodString, O as ZodNullable, P as ZodUnion, R as $strip, T as ZodBoolean, j as ZodOptional, k as ZodNumber, w as ZodArray } from "./index-ZlKF1x_z.mjs";
2
+ import { n as StatelyCredential, t as StatelyAuthMode } from "./auth-Dg7prjeL.mjs";
3
3
 
4
4
  //#region ../api-contract/dist/errors.d.mts
5
5
  /**
package/dist/studio.d.mts CHANGED
@@ -1,2 +1,2 @@
1
- import { A as Machine, C as StudioMachineRecord, D as VerifyApiKeyResponse, E as UpdateProjectInput, F as ProjectVisibility, I as VerifyResult, L as XStateVersion, M as Project, N as ProjectMachineSummary, O as createStatelyClient, P as ProjectSummary, R as ResourceErrorCode, S as StudioClientOptions, T as UpdateMachineInput, _ as ProjectMachine, a as CreateMachineTemplate, b as StudioApiErrorOptions, c as EnsureProjectInput, d as ExtractedMachine, f as GetMachineOptions, g as ProjectData, h as LegacyUpdateMachineInput, i as CreateMachineInput, j as MachineVersion, k as ExtractedMachines, l as ExtractMachinesInput, m as LegacyProjectVisibility, n as CreateMachineFromDefinitionInput, o as CreateProjectInput, p as LegacyExtractMachinesOptions, r as CreateMachineFromTemplateInput, s as DEFAULT_STATELY_BASE_URL, t as ConnectedRepo, u as ExtractMachinesResponse, v as RepoType, w as StudioRequestOptions, x as StudioClient, y as StudioApiError } from "./studio-D-yqFd0u.mjs";
1
+ import { A as Machine, C as StudioMachineRecord, D as VerifyApiKeyResponse, E as UpdateProjectInput, F as ProjectVisibility, I as VerifyResult, L as XStateVersion, M as Project, N as ProjectMachineSummary, O as createStatelyClient, P as ProjectSummary, R as ResourceErrorCode, S as StudioClientOptions, T as UpdateMachineInput, _ as ProjectMachine, a as CreateMachineTemplate, b as StudioApiErrorOptions, c as EnsureProjectInput, d as ExtractedMachine, f as GetMachineOptions, g as ProjectData, h as LegacyUpdateMachineInput, i as CreateMachineInput, j as MachineVersion, k as ExtractedMachines, l as ExtractMachinesInput, m as LegacyProjectVisibility, n as CreateMachineFromDefinitionInput, o as CreateProjectInput, p as LegacyExtractMachinesOptions, r as CreateMachineFromTemplateInput, s as DEFAULT_STATELY_BASE_URL, t as ConnectedRepo, u as ExtractMachinesResponse, v as RepoType, w as StudioRequestOptions, x as StudioClient, y as StudioApiError } from "./studio-GZ6E_xns.mjs";
2
2
  export { ConnectedRepo, CreateMachineFromDefinitionInput, CreateMachineFromTemplateInput, CreateMachineInput, CreateMachineTemplate, CreateProjectInput, DEFAULT_STATELY_BASE_URL, EnsureProjectInput, ExtractMachinesInput, ExtractMachinesResponse, ExtractedMachine, ExtractedMachines, GetMachineOptions, LegacyExtractMachinesOptions, LegacyProjectVisibility, LegacyUpdateMachineInput, Machine, MachineVersion, Project, ProjectData, ProjectMachine, ProjectMachineSummary, ProjectSummary, ProjectVisibility, RepoType, ResourceErrorCode, StudioApiError, StudioApiErrorOptions, StudioClient, StudioClientOptions, StudioMachineRecord, StudioRequestOptions, UpdateMachineInput, UpdateProjectInput, VerifyApiKeyResponse, VerifyResult, XStateVersion, createStatelyClient };
package/dist/sync.d.mts CHANGED
@@ -1,5 +1,5 @@
1
- import { b as DigraphConfig, i as StatelyGraph } from "./graph-C8E1Exad.mjs";
2
- import { C as StudioMachineRecord, L as XStateVersion, g as ProjectData, o as CreateProjectInput, x as StudioClient } from "./studio-D-yqFd0u.mjs";
1
+ import { b as DigraphConfig, i as StatelyGraph } from "./graph-CehpcL7P.mjs";
2
+ import { C as StudioMachineRecord, L as XStateVersion, g as ProjectData, o as CreateProjectInput, x as StudioClient } from "./studio-GZ6E_xns.mjs";
3
3
  import { GraphDiff } from "@statelyai/graph";
4
4
 
5
5
  //#region src/sync.d.ts
package/dist/sync.mjs CHANGED
@@ -1,6 +1,7 @@
1
1
  import "./openapi-BTDjYWXd.mjs";
2
2
  import { r as createStatelyClient } from "./studio-rSI54Ese.mjs";
3
- import { b as serializeJS, c as detectXStateSourceProfile, f as graphChangeToPatchesResult, h as graphToXStateTS, i as INLINE_EXPRESSION_DIRECTIVE_FIELDS, l as diffGraphsSemantically, n as getStatelyPragma, o as alignCompareGraphIds, p as graphToMachineConfig, r as upsertStatelyPragma, t as findStatelyPragmaAttachments, v as normalizeMachineProfile, x as xstateSourceToConfig } from "./statelyPragma-p1vu8PmH.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";
4
+ import { n as getStatelyPragma, r as upsertStatelyPragma, t as findStatelyPragmaAttachments } from "./statelyPragma-D46lczJR.mjs";
4
5
  import { fromStudioMachine, toStudioMachine } from "./graph.mjs";
5
6
  import * as ts$1 from "typescript";
6
7
  import ts from "typescript";
@@ -820,11 +821,15 @@ function parseSourceToMachine(text, document, options = {}) {
820
821
  ...statesObjectReplacements,
821
822
  ...importReplacements
822
823
  ].filter(removeOverlappingRanges).sort(compareSourceRangesDescending));
823
- if (sourceLocations.profile === "xstate-v6-alpha") {
824
+ if (sourceLocations.profile === "xstate-v6-alpha" || options.machineIndex !== void 0) {
824
825
  const importedTransitionSources = collectImportedXStateTransitionSources(text, document, options);
826
+ const parseText = importedTransitionSources.length ? `${hydratedText}\n${importedTransitionSources.join("\n")}` : hydratedText;
827
+ const selectedMachineIndex = options.machineIndex ?? 0;
828
+ const config = extractXStateMachineConfigEntries(parseText, { profile: sourceLocations.profile }).find((entry) => entry.machineIndex === selectedMachineIndex)?.config;
829
+ if (!config) throw new Error(`No machine at index ${selectedMachineIndex} was found in ${document.fileName}.`);
825
830
  return `import { createMachine } from "xstate";
826
831
 
827
- export const machine = createMachine(${serializeJS(xstateSourceToConfig(importedTransitionSources.length ? `${hydratedText}\n${importedTransitionSources.join("\n")}` : hydratedText, { profile: "xstate-v6-alpha" }), 0)});
832
+ export const machine = createMachine(${serializeJS(config, 0)});
828
833
  `;
829
834
  }
830
835
  return hydratedText;
@@ -1092,12 +1097,13 @@ function offsetAtRangePosition$1(sourceText, line, character) {
1092
1097
  function applyMachineToSource(machineConfig, document, options = {}) {
1093
1098
  if (!isMachineConfig(machineConfig)) return [];
1094
1099
  const sourceFile = createSourceFile(document, document.getText());
1095
- const machineConfigNode = findMachineConfigObjectLiteral(sourceFile, options.machineIndex);
1100
+ const machineConfigNode = getMappedRootObjectLiteral(document, sourceFile, options.sourceLocations) ?? findMachineConfigObjectLiteral(sourceFile, options.machineIndex);
1096
1101
  if (!machineConfigNode) return [];
1102
+ if (options.sourceUpdateStrategy === "rewrite") return addCodeImportReplacements(document, sourceFile, machineConfig, [createRewriteReplacement(document, sourceFile, machineConfigNode, machineConfig)]).sort(compareReplacementRangesDescending);
1097
1103
  const parsedPatches = parseGraphPatches(options.patches);
1098
1104
  const prevGraph = parseGraph(options.prevGraph);
1099
1105
  const nextGraph = parseGraph(options.nextGraph);
1100
- const rootNode = getMappedRootObjectLiteral(document, sourceFile, options.sourceLocations) ?? machineConfigNode;
1106
+ const rootNode = machineConfigNode;
1101
1107
  if (!parsedPatches || !prevGraph || !nextGraph || parsedPatches.length === 0) {
1102
1108
  if (wouldDeModularizeRootReplacement(options.sourceLocations)) return [];
1103
1109
  return [createReplacement(document, sourceFile, rootNode, machineConfig)];
@@ -1171,6 +1177,7 @@ async function applyMachineToSourceDocuments(machineConfig, document, options =
1171
1177
  const sourceFile = createSourceFile(document, document.getText());
1172
1178
  const machineConfigNode = getMappedRootObjectLiteral(document, sourceFile, options.sourceLocations) ?? findMachineConfigObjectLiteral(sourceFile, options.machineIndex);
1173
1179
  if (!machineConfigNode) return [];
1180
+ if (options.sourceUpdateStrategy === "rewrite") return addCodeImportReplacements(document, sourceFile, machineConfig, [createRewriteReplacement(document, sourceFile, machineConfigNode, machineConfig)]).sort(compareReplacementRangesDescending);
1174
1181
  const parsedPatches = parseGraphPatches(options.patches);
1175
1182
  const prevGraph = parseGraph(options.prevGraph);
1176
1183
  const nextGraph = parseGraph(options.nextGraph);
@@ -1319,8 +1326,8 @@ async function createTransitionReplacementForDocuments(document, sourceFile, mac
1319
1326
  if (transitionSource && transitionTarget.previousEventType === transitionTarget.eventType) return [createPropertyValueReplacement(targetDocument, targetSourceFile, transitionSource.eventProperty, nextTransitionValue)];
1320
1327
  if (transitionSource) return [createPropertyAssignmentReplacement(targetDocument, targetSourceFile, transitionSource.eventProperty, transitionTarget.eventType, nextTransitionValue)];
1321
1328
  const onObject = getObjectLiteralProperty(stateObject, "on");
1322
- if (onObject) return [createObjectLiteralPropertyInsertion(targetDocument, targetSourceFile, onObject, transitionTarget.eventType, nextTransitionValue)];
1323
- return [createObjectLiteralPropertyInsertion(targetDocument, targetSourceFile, stateObject, "on", { [transitionTarget.eventType]: nextTransitionValue })];
1329
+ if (onObject) return createObjectLiteralPropertyInsertion(targetDocument, targetSourceFile, onObject, transitionTarget.eventType, nextTransitionValue);
1330
+ return createObjectLiteralPropertyInsertion(targetDocument, targetSourceFile, stateObject, "on", { [transitionTarget.eventType]: nextTransitionValue });
1324
1331
  }
1325
1332
  async function createStatePropertiesReplacementForDocuments(document, sourceFile, machineConfigNode, machineConfig, path, propertyNames, sourceLocations, openTextDocument) {
1326
1333
  const nextStateConfig = getStateConfigByPath(machineConfig, path);
@@ -1485,8 +1492,30 @@ function createPropertyAssignmentReplacement(document, sourceFile, property, key
1485
1492
  return createOffsetReplacement(document, property.getStart(sourceFile), property.getEnd(), text);
1486
1493
  }
1487
1494
  function createObjectLiteralPropertyInsertion(document, sourceFile, objectLiteral, key, nextValue) {
1488
- const text = objectPropertyTextForInsertion(objectLiteral, printObjectLiteralProperty(key, nextValue, sourceFile, getFormattingContext(document, sourceFile, objectLiteral)));
1489
- return createOffsetReplacement(document, objectLiteral.properties.end, objectLiteral.properties.end, text);
1495
+ const propertyText = objectPropertyTextForInsertion(objectLiteral, printObjectLiteralProperty(key, nextValue, sourceFile, getFormattingContext(document, sourceFile, objectLiteral)));
1496
+ return createObjectPropertyInsertionReplacements(document, objectLiteral, getObjectLiteralPropertyInsertionOffset(sourceFile, objectLiteral), propertyText);
1497
+ }
1498
+ function getObjectLiteralPropertyInsertionOffset(sourceFile, objectLiteral) {
1499
+ const propertiesEnd = objectLiteral.properties.end;
1500
+ const objectEnd = objectLiteral.getEnd() - 1;
1501
+ const trailingTrivia = sourceFile.text.slice(propertiesEnd, objectEnd);
1502
+ const commentMatch = /^[ \t]*(\/\/|\/\*)/.exec(trailingTrivia);
1503
+ if (!commentMatch) return propertiesEnd;
1504
+ const commentStart = propertiesEnd + commentMatch.index + commentMatch[0].length - 2;
1505
+ if (commentMatch[1] === "//") {
1506
+ const lineFeed = sourceFile.text.indexOf("\n", commentStart);
1507
+ const lineEnd = lineFeed === -1 ? objectEnd : Math.min(lineFeed, objectEnd);
1508
+ return lineEnd > commentStart && sourceFile.text.charCodeAt(lineEnd - 1) === 13 ? lineEnd - 1 : lineEnd;
1509
+ }
1510
+ const commentEnd = sourceFile.text.indexOf("*/", commentStart + 2);
1511
+ return commentEnd === -1 ? propertiesEnd : Math.min(commentEnd + 2, objectEnd);
1512
+ }
1513
+ function createObjectPropertyInsertionReplacements(document, objectLiteral, insertionOffset, propertyText) {
1514
+ const propertiesEnd = objectLiteral.properties.end;
1515
+ const needsComma = objectLiteral.properties.length > 0 && !objectLiteral.properties.hasTrailingComma;
1516
+ const replacements = [createOffsetReplacement(document, insertionOffset, insertionOffset, `${needsComma && insertionOffset === propertiesEnd ? "," : ""}${propertyText}`)];
1517
+ if (needsComma && insertionOffset !== propertiesEnd) replacements.push(createOffsetReplacement(document, propertiesEnd, propertiesEnd, ","));
1518
+ return replacements;
1490
1519
  }
1491
1520
  function getArrayElementDeletionRange(sourceFile, arrayLiteral, element) {
1492
1521
  const elements = [...arrayLiteral.elements];
@@ -1583,14 +1612,16 @@ function createImplementationCreateReplacements(document, sourceFile, implementa
1583
1612
  if (!implementation.id || !implementationCode) return null;
1584
1613
  const categoryObject = getObjectLiteralProperty(implementationRoot, categoryName);
1585
1614
  if (!categoryObject) {
1586
- const text = objectPropertyTextForInsertion(implementationRoot, `${propertyNameTextForSource(categoryName)}: {\n${getIndentForNewObjectProperty(sourceFile, implementationRoot)}${propertyNameTextForSource(implementation.id)}: ${implementationCode},\n${getIndentForObjectClose(sourceFile, implementationRoot)}}`);
1587
- return [createOffsetReplacement(document, implementationRoot.properties.end, implementationRoot.properties.end, text)];
1615
+ const propertyText = objectPropertyTextForInsertion(implementationRoot, `${propertyNameTextForSource(categoryName)}: {\n${getIndentForNewObjectProperty(sourceFile, implementationRoot)}${propertyNameTextForSource(implementation.id)}: ${implementationCode},\n${getIndentForObjectClose(sourceFile, implementationRoot)}}`);
1616
+ return createObjectPropertyInsertionReplacements(document, implementationRoot, getObjectLiteralPropertyInsertionOffset(sourceFile, implementationRoot), propertyText);
1588
1617
  }
1589
- const text = objectPropertyTextForInsertion(categoryObject, `${propertyNameTextForSource(implementation.id)}: ${implementationCode}`);
1590
- return [createOffsetReplacement(document, categoryObject.properties.end, categoryObject.properties.end, text)];
1618
+ const propertyText = objectPropertyTextForInsertion(categoryObject, `${propertyNameTextForSource(implementation.id)}: ${implementationCode}`);
1619
+ return createObjectPropertyInsertionReplacements(document, categoryObject, getObjectLiteralPropertyInsertionOffset(sourceFile, categoryObject), propertyText);
1591
1620
  }
1592
1621
  function objectPropertyTextForInsertion(objectLiteral, propertyText) {
1593
- return `${objectLiteral.properties.length > 0 ? "," : ""}${getLineBreak(objectLiteral.getSourceFile())}${getIndentForNewObjectProperty(objectLiteral.getSourceFile(), objectLiteral)}${propertyText}`;
1622
+ const lineBreak = getLineBreak(objectLiteral.getSourceFile());
1623
+ const indent = getIndentForNewObjectProperty(objectLiteral.getSourceFile(), objectLiteral);
1624
+ return `${lineBreak}${indent}${propertyText.startsWith(indent) ? propertyText.slice(indent.length) : propertyText}`;
1594
1625
  }
1595
1626
  function getLineBreak(sourceFile) {
1596
1627
  return sourceFile.text.includes("\r\n") ? "\r\n" : "\n";
@@ -1886,7 +1917,7 @@ function getObjectLiteralPropertyDeletionRange(sourceFile, objectLiteral, proper
1886
1917
  const propertyEnd = property.getEnd();
1887
1918
  if (properties.length === 1) return {
1888
1919
  start: propertyStart,
1889
- end: propertyEnd
1920
+ end: objectLiteral.properties.hasTrailingComma ? objectLiteral.properties.end : propertyEnd
1890
1921
  };
1891
1922
  if (propertyIndex === properties.length - 1) {
1892
1923
  const previousProperty = properties[propertyIndex - 1];
@@ -2254,6 +2285,21 @@ function createReplacement(document, sourceFile, node, value) {
2254
2285
  newText: printExpression(valueToExpression(value, node), sourceFile, formatting)
2255
2286
  };
2256
2287
  }
2288
+ function createRewriteReplacement(document, sourceFile, node, value) {
2289
+ const start = document.positionAt(node.getStart(sourceFile));
2290
+ const end = document.positionAt(node.getEnd());
2291
+ const formatting = getFormattingContext(document, sourceFile, node);
2292
+ return {
2293
+ uri: getDocumentUri(document),
2294
+ range: {
2295
+ startLine: start.line,
2296
+ startChar: start.character,
2297
+ endLine: end.line,
2298
+ endChar: end.character
2299
+ },
2300
+ newText: printExpression(valueToExpression(value), sourceFile, formatting)
2301
+ };
2302
+ }
2257
2303
  function addCodeImportReplacements(document, sourceFile, machineConfig, replacements) {
2258
2304
  const importReplacements = createCodeImportReplacements(document, sourceFile, collectCodeImports(machineConfig));
2259
2305
  return [...replacements, ...importReplacements];
@@ -3165,11 +3211,12 @@ const xstateAdapter = {
3165
3211
  return collectXStateSourceLocations(text, document, options);
3166
3212
  },
3167
3213
  async applyMachineToDocument(machineConfig, document, options) {
3168
- const rootSourceLocation = collectXStateSourceLocations(document.getText(), document, { machineIndex: options?.machineIndex })?.root ?? options?.sourceLocations?.root;
3214
+ const detectedSourceLocations = collectXStateSourceLocations(document.getText(), document, { machineIndex: options?.machineIndex });
3215
+ const rootSourceLocation = options?.sourceLocations?.root ?? detectedSourceLocations?.root;
3169
3216
  const sanitizedMachineConfig = options?.preserveStatelyMetadata === false ? stripStatelyMetadata(machineConfig) : machineConfig;
3170
3217
  if (!options?.patches?.length) return [];
3171
3218
  const replacements = await applyMachineToSourceDocuments(sanitizedMachineConfig, document, options);
3172
- if (replacements.some(containsXStateExpressionPlaceholder) || replacements.some((replacement) => isImplicitRootReplacement(replacement, rootSourceLocation))) return [];
3219
+ if (replacements.some(containsXStateExpressionPlaceholder) || options?.sourceUpdateStrategy !== "rewrite" && replacements.some((replacement) => isImplicitRootReplacement(replacement, rootSourceLocation))) return [];
3173
3220
  return replacements;
3174
3221
  }
3175
3222
  };
@@ -3503,7 +3550,7 @@ async function extractMachinesFromLocalSource(sourcePath, contents, machineIndex
3503
3550
  return { machines: extractMachineConfigsFromAst(sourcePath, parseSourceToMachine(contents, createTextDocument(sourcePath, contents), {
3504
3551
  machineIndex,
3505
3552
  resolver: createFileSourceDocumentResolver()
3506
- }), machineIndex) };
3553
+ }), machineIndex === void 0 ? void 0 : 0) };
3507
3554
  } catch (error) {
3508
3555
  return {
3509
3556
  machines: [],
@@ -365,7 +365,7 @@ function createWebSocketTransport(options) {
365
365
 
366
366
  //#endregion
367
367
  //#region src/version.ts
368
- const SDK_VERSION = "0.29.1";
368
+ const SDK_VERSION = "0.31.0";
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.29.1",
3
+ "version": "0.31.0",
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/graph-tools": "0.7.2",
97
- "@statelyai/api-contract": "0.4.3"
96
+ "@statelyai/api-contract": "0.4.5",
97
+ "@statelyai/graph-tools": "0.8.1"
98
98
  },
99
99
  "engines": {
100
100
  "node": ">=22.4"
@@ -34,6 +34,12 @@
34
34
  "default": 5,
35
35
  "description": "Default XState major version for sources that do not override it. Only XState 5+ is supported."
36
36
  },
37
+ "sourceUpdateStrategy": {
38
+ "type": "string",
39
+ "enum": ["preserve", "rewrite"],
40
+ "default": "preserve",
41
+ "description": "Controls whether visual edits preserve existing source formatting or rewrite the selected machine."
42
+ },
37
43
  "include": {
38
44
  "type": "array",
39
45
  "items": {
@@ -1,13 +0,0 @@
1
- //#region src/embedPanel.d.ts
2
- type EmbedPanelPosition = 'left' | 'right' | 'bottom';
3
- interface EmbedPanelConfig {
4
- id: string;
5
- /** Restrict the panel to one side. Omit to allow any side. */
6
- position?: EmbedPanelPosition;
7
- /** Keep a one-click tab visible on its positioned or preferred side. */
8
- tab?: boolean;
9
- /** Open the panel when the embed is initialized. */
10
- initiallyOpen?: boolean;
11
- }
12
- //#endregion
13
- export { EmbedPanelPosition as n, EmbedPanelConfig as t };