@statelyai/sdk 0.14.1 → 0.14.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/dist/auth.d.mts +1 -1
- package/dist/{dist-C8jVuuHf.mjs → dist-CO36Ks-i.mjs} +239 -35
- package/dist/dist-Ci5I7Rjq.mjs +9401 -0
- package/dist/embed.d.mts +4 -3
- package/dist/{graph-R0sbxnZ7.d.mts → graph-3oSqiY4N.d.mts} +5 -1
- package/dist/graph.d.mts +1 -1
- package/dist/graph.mjs +4 -0
- package/dist/{index-DVjNSTuQ.d.mts → index-CcgKzQ-C.d.mts} +52 -4
- package/dist/index.d.mts +3 -3
- package/dist/index.mjs +2 -2
- package/dist/{inspect-BcKTFJI1.mjs → inspect-DWDTNMEc.mjs} +15 -6
- package/dist/inspect.mjs +1 -1
- package/dist/patchTypes.d.mts +1 -1
- package/dist/protocol.d.mts +8 -6
- package/dist/studio.d.mts +1 -1
- package/dist/sync.d.mts +1 -1
- package/dist/sync.mjs +209 -7
- package/package.json +2 -2
- /package/dist/{auth-DmPZiERd.d.mts → auth-D9-iLi-S.d.mts} +0 -0
package/dist/sync.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createStatelyClient } from "./studio.mjs";
|
|
2
|
-
import { d as xstateSourceToConfig, f as findStatelyPragmaAttachments, i as detectXStateSourceProfile, m as upsertStatelyPragma, p as getStatelyPragma, s as graphToXStateTS, t as INLINE_EXPRESSION_DIRECTIVE_FIELDS, u as serializeJS } from "./dist-
|
|
2
|
+
import { d as xstateSourceToConfig, f as findStatelyPragmaAttachments, i as detectXStateSourceProfile, m as upsertStatelyPragma, p as getStatelyPragma, s as graphToXStateTS, t as INLINE_EXPRESSION_DIRECTIVE_FIELDS, u as serializeJS } from "./dist-CO36Ks-i.mjs";
|
|
3
3
|
import { fromStudioMachine, toStudioMachine } from "./graph.mjs";
|
|
4
4
|
import * as ts$1 from "typescript";
|
|
5
5
|
import ts from "typescript";
|
|
@@ -65,9 +65,35 @@ function createFileSourceDocumentResolver() {
|
|
|
65
65
|
resolveImport(fromDocument, specifier) {
|
|
66
66
|
const importedFileName = resolveImportPath(fromDocument.fileName, specifier);
|
|
67
67
|
return importedFileName ? readFileSnapshot(importedFileName) : null;
|
|
68
|
+
},
|
|
69
|
+
resolvePackageJson(fromDocument, packageName) {
|
|
70
|
+
let directory = path$1.dirname(path$1.resolve(fromDocument.fileName));
|
|
71
|
+
while (true) {
|
|
72
|
+
const packageJson = readFileSnapshot(path$1.join(directory, "package.json"));
|
|
73
|
+
if (packageJson && packageJsonDeclares(packageJson.text, packageName)) return packageJson;
|
|
74
|
+
const parent = path$1.dirname(directory);
|
|
75
|
+
if (parent === directory) return null;
|
|
76
|
+
directory = parent;
|
|
77
|
+
}
|
|
68
78
|
}
|
|
69
79
|
};
|
|
70
80
|
}
|
|
81
|
+
function packageJsonDeclares(text, packageName) {
|
|
82
|
+
try {
|
|
83
|
+
const manifest = JSON.parse(text);
|
|
84
|
+
return [
|
|
85
|
+
"dependencies",
|
|
86
|
+
"devDependencies",
|
|
87
|
+
"peerDependencies",
|
|
88
|
+
"optionalDependencies"
|
|
89
|
+
].some((field) => {
|
|
90
|
+
const dependencies = manifest[field];
|
|
91
|
+
return Boolean(dependencies && typeof dependencies === "object" && Object.prototype.hasOwnProperty.call(dependencies, packageName));
|
|
92
|
+
});
|
|
93
|
+
} catch {
|
|
94
|
+
return false;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
71
97
|
function resolveImportPath(fromFileName, specifier) {
|
|
72
98
|
if (!specifier.startsWith(".")) return null;
|
|
73
99
|
const basePath = path$1.resolve(path$1.dirname(fromFileName), specifier);
|
|
@@ -121,20 +147,116 @@ function collectXStateSourceLocations(sourceText, document, options = {}) {
|
|
|
121
147
|
const states = [];
|
|
122
148
|
const statesObjectLocations = [];
|
|
123
149
|
collectStateLocations(root, [], states, statesObjectLocations, bindings, staticValues, root);
|
|
150
|
+
const packageProfile = detectXStatePackageProfile(options.resolver?.resolvePackageJson?.({
|
|
151
|
+
fileName: document.fileName,
|
|
152
|
+
uri
|
|
153
|
+
}, "xstate"));
|
|
124
154
|
const rootProfile = detectXStateSourceProfile(sourceText);
|
|
125
155
|
const referencedStateSymbols = new Set([...states, ...statesObjectLocations].map((state) => state.symbol).filter((symbol) => typeof symbol === "string"));
|
|
156
|
+
const resolvedTransitionFunctions = collectResolvedTransitionFunctions(root, bindings);
|
|
157
|
+
const inferredProfile = rootProfile === "xstate-v6-alpha" || resolvedTransitionFunctions.size > 0 || [...referencedStateSymbols].some((symbol) => detectXStateSourceProfile(bindings.get(symbol)?.sourceFile.text ?? "") === "xstate-v6-alpha") ? "xstate-v6-alpha" : rootProfile;
|
|
126
158
|
return {
|
|
127
159
|
version: 1,
|
|
128
|
-
profile:
|
|
160
|
+
profile: packageProfile ?? inferredProfile,
|
|
129
161
|
root: {
|
|
130
162
|
uri,
|
|
131
163
|
range: toSourceRange$1(sourceFile, root)
|
|
132
164
|
},
|
|
133
165
|
statesObject: statesObjectLocations[0],
|
|
134
166
|
states,
|
|
135
|
-
staticValues: collectStaticValueReferences(sourceFile, uri, root, staticValues)
|
|
167
|
+
staticValues: collectStaticValueReferences(sourceFile, uri, root, staticValues),
|
|
168
|
+
transitionFunctions: [...resolvedTransitionFunctions].flatMap(([symbol, resolved]) => resolved.binding.uri === uri ? [] : [{
|
|
169
|
+
symbol,
|
|
170
|
+
uri: resolved.binding.uri,
|
|
171
|
+
range: toSourceRange$1(resolved.binding.sourceFile, resolved.binding.node),
|
|
172
|
+
sourcePaths: resolved.sourcePaths
|
|
173
|
+
}])
|
|
136
174
|
};
|
|
137
175
|
}
|
|
176
|
+
function detectXStatePackageProfile(packageJson) {
|
|
177
|
+
if (!packageJson) return void 0;
|
|
178
|
+
let manifest;
|
|
179
|
+
try {
|
|
180
|
+
manifest = JSON.parse(packageJson.text);
|
|
181
|
+
} catch {
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
const dependencyFields = [
|
|
185
|
+
"dependencies",
|
|
186
|
+
"devDependencies",
|
|
187
|
+
"peerDependencies",
|
|
188
|
+
"optionalDependencies"
|
|
189
|
+
];
|
|
190
|
+
let range;
|
|
191
|
+
for (const field of dependencyFields) {
|
|
192
|
+
const dependencies = manifest[field];
|
|
193
|
+
if (!dependencies || typeof dependencies !== "object") continue;
|
|
194
|
+
const value = dependencies.xstate;
|
|
195
|
+
if (typeof value === "string") {
|
|
196
|
+
range = value;
|
|
197
|
+
break;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
if (!range) return void 0;
|
|
201
|
+
const clauseProfiles = range.replace(/^(?:workspace:|npm:xstate@)/, "").split("||").map((clause) => detectXStateRangeClauseProfile(clause.trim()));
|
|
202
|
+
const profiles = new Set(clauseProfiles);
|
|
203
|
+
if (profiles.size !== 1 || profiles.has(void 0)) return void 0;
|
|
204
|
+
return clauseProfiles[0];
|
|
205
|
+
}
|
|
206
|
+
function detectXStateRangeClauseProfile(clause) {
|
|
207
|
+
const normalizedClause = clause.replace(/([<>]=?)\s+/g, "$1");
|
|
208
|
+
let lowerRequiresV6 = false;
|
|
209
|
+
let upperRequiresV5 = false;
|
|
210
|
+
let directProfile;
|
|
211
|
+
for (const match of normalizedClause.matchAll(/(?:^|\s)([<>]=?|[~^])?v?(\d+)(?:\.(\d+|x|\*))?(?:\.(\d+|x|\*))?(?:-[0-9A-Za-z.-]+)?(?=\s|$)/g)) {
|
|
212
|
+
const operator = match[1] ?? "";
|
|
213
|
+
const major = Number(match[2]);
|
|
214
|
+
const minor = parseRangePart(match[3]);
|
|
215
|
+
const patch = parseRangePart(match[4]);
|
|
216
|
+
if (operator === ">" || operator === ">=") {
|
|
217
|
+
if (major >= 6) lowerRequiresV6 = true;
|
|
218
|
+
continue;
|
|
219
|
+
}
|
|
220
|
+
if (operator === "<") {
|
|
221
|
+
if (major < 6 || major === 6 && (minor ?? 0) === 0 && (patch ?? 0) === 0) upperRequiresV5 = true;
|
|
222
|
+
continue;
|
|
223
|
+
}
|
|
224
|
+
if (operator === "<=") {
|
|
225
|
+
if (major < 6) upperRequiresV5 = true;
|
|
226
|
+
continue;
|
|
227
|
+
}
|
|
228
|
+
const profile = major >= 6 ? "xstate-v6-alpha" : "xstate-v5";
|
|
229
|
+
if (directProfile && directProfile !== profile) return void 0;
|
|
230
|
+
directProfile = profile;
|
|
231
|
+
}
|
|
232
|
+
if (lowerRequiresV6 && upperRequiresV5) return void 0;
|
|
233
|
+
if (lowerRequiresV6) return "xstate-v6-alpha";
|
|
234
|
+
if (upperRequiresV5) return "xstate-v5";
|
|
235
|
+
return directProfile;
|
|
236
|
+
}
|
|
237
|
+
function parseRangePart(value) {
|
|
238
|
+
return value && /^\d+$/.test(value) ? Number(value) : void 0;
|
|
239
|
+
}
|
|
240
|
+
function collectImportedXStateTransitionSources(sourceText, document, options = {}) {
|
|
241
|
+
if (!options.resolver) return [];
|
|
242
|
+
const sourceFile = ts$1.createSourceFile(document.fileName, sourceText, ts$1.ScriptTarget.Latest, true, getScriptKind$2(document.fileName));
|
|
243
|
+
const uri = document.uri?.toString() ?? document.fileName;
|
|
244
|
+
sourceFileUris.set(sourceFile, uri);
|
|
245
|
+
const bindings = collectBindings(sourceFile, uri, document.fileName, options);
|
|
246
|
+
const root = findMachineConfigObjectLiteral(sourceFile, bindings);
|
|
247
|
+
if (!root) return [];
|
|
248
|
+
return [...collectResolvedTransitionFunctions(root, bindings)].flatMap(([localName, resolved]) => {
|
|
249
|
+
const { binding } = resolved;
|
|
250
|
+
if (binding.uri === uri) return [];
|
|
251
|
+
if (ts$1.isFunctionDeclaration(binding.node)) {
|
|
252
|
+
const name = binding.node.name;
|
|
253
|
+
if (!name) return [];
|
|
254
|
+
const suffix = binding.node.getText(binding.sourceFile).slice(name.getEnd() - binding.node.getStart(binding.sourceFile));
|
|
255
|
+
return [`${binding.node.modifiers?.some((modifier) => modifier.kind === ts$1.SyntaxKind.AsyncKeyword) ? "async " : ""}function ${localName}${suffix}`];
|
|
256
|
+
}
|
|
257
|
+
return [`const ${localName} = ${binding.node.getText(binding.sourceFile)};`];
|
|
258
|
+
});
|
|
259
|
+
}
|
|
138
260
|
function collectStaticValueBindings(sourceFile) {
|
|
139
261
|
const bindings = /* @__PURE__ */ new Map();
|
|
140
262
|
for (const statement of sourceFile.statements) {
|
|
@@ -180,9 +302,30 @@ function collectBindings(sourceFile, uri, fileName, options, cache = /* @__PURE_
|
|
|
180
302
|
function collectTopLevelBindings(sourceFile, uri) {
|
|
181
303
|
const bindings = /* @__PURE__ */ new Map();
|
|
182
304
|
for (const statement of sourceFile.statements) {
|
|
305
|
+
if (ts$1.isFunctionDeclaration(statement) && statement.name) {
|
|
306
|
+
bindings.set(statement.name.text, {
|
|
307
|
+
kind: "transitionFunction",
|
|
308
|
+
node: statement,
|
|
309
|
+
sourceFile,
|
|
310
|
+
uri,
|
|
311
|
+
bindings
|
|
312
|
+
});
|
|
313
|
+
continue;
|
|
314
|
+
}
|
|
183
315
|
if (!ts$1.isVariableStatement(statement)) continue;
|
|
184
316
|
for (const declaration of statement.declarationList.declarations) {
|
|
185
317
|
if (!ts$1.isIdentifier(declaration.name) || !declaration.initializer) continue;
|
|
318
|
+
const initializer = unwrapExpression$1(declaration.initializer);
|
|
319
|
+
if (ts$1.isArrowFunction(initializer) || ts$1.isFunctionExpression(initializer)) {
|
|
320
|
+
bindings.set(declaration.name.text, {
|
|
321
|
+
kind: "transitionFunction",
|
|
322
|
+
node: initializer,
|
|
323
|
+
sourceFile,
|
|
324
|
+
uri,
|
|
325
|
+
bindings
|
|
326
|
+
});
|
|
327
|
+
continue;
|
|
328
|
+
}
|
|
186
329
|
const objectLiteral = unwrapObjectLiteralExpression(declaration.initializer);
|
|
187
330
|
if (objectLiteral) {
|
|
188
331
|
bindings.set(declaration.name.text, {
|
|
@@ -228,6 +371,62 @@ function addImportedBindings(bindings, sourceFile, uri, fileName, options, cache
|
|
|
228
371
|
}
|
|
229
372
|
}
|
|
230
373
|
}
|
|
374
|
+
function collectResolvedTransitionFunctions(root, bindings) {
|
|
375
|
+
const found = /* @__PURE__ */ new Map();
|
|
376
|
+
const visitExpression = (expression, sourcePath) => {
|
|
377
|
+
const current = unwrapExpression$1(expression);
|
|
378
|
+
if (ts$1.isIdentifier(current)) {
|
|
379
|
+
const binding = bindings.get(current.text);
|
|
380
|
+
if (binding?.kind === "transitionFunction") {
|
|
381
|
+
const resolved = found.get(current.text) ?? {
|
|
382
|
+
binding,
|
|
383
|
+
sourcePaths: []
|
|
384
|
+
};
|
|
385
|
+
if (!resolved.sourcePaths.some((existing) => existing.length === sourcePath.length && existing.every((segment, index) => segment === sourcePath[index]))) resolved.sourcePaths.push(sourcePath);
|
|
386
|
+
found.set(current.text, resolved);
|
|
387
|
+
}
|
|
388
|
+
return;
|
|
389
|
+
}
|
|
390
|
+
if (ts$1.isObjectLiteralExpression(current)) {
|
|
391
|
+
for (const property of current.properties) if (ts$1.isPropertyAssignment(property)) visitExpression(property.initializer, sourcePath);
|
|
392
|
+
else if (ts$1.isShorthandPropertyAssignment(property)) visitExpression(property.name, sourcePath);
|
|
393
|
+
else if (ts$1.isSpreadAssignment(property)) visitExpression(property.expression, sourcePath);
|
|
394
|
+
return;
|
|
395
|
+
}
|
|
396
|
+
if (ts$1.isArrayLiteralExpression(current)) {
|
|
397
|
+
for (const element of current.elements) if (ts$1.isExpression(element)) visitExpression(element, sourcePath);
|
|
398
|
+
return;
|
|
399
|
+
}
|
|
400
|
+
ts$1.forEachChild(current, (child) => {
|
|
401
|
+
if (ts$1.isExpression(child)) visitExpression(child, sourcePath);
|
|
402
|
+
});
|
|
403
|
+
};
|
|
404
|
+
const visitState = (state, sourcePath) => {
|
|
405
|
+
for (const propertyName of [
|
|
406
|
+
"on",
|
|
407
|
+
"after",
|
|
408
|
+
"always",
|
|
409
|
+
"onDone",
|
|
410
|
+
"onError",
|
|
411
|
+
"onSnapshot",
|
|
412
|
+
"onTimeout"
|
|
413
|
+
]) {
|
|
414
|
+
const property = state.properties.find((candidate) => ts$1.isPropertyAssignment(candidate) && getPropertyNameText$1(candidate.name) === propertyName);
|
|
415
|
+
if (property) visitExpression(property.initializer, sourcePath);
|
|
416
|
+
}
|
|
417
|
+
const states = state.properties.find((candidate) => ts$1.isPropertyAssignment(candidate) && getPropertyNameText$1(candidate.name) === "states");
|
|
418
|
+
const statesObject = states && unwrapObjectLiteralExpression(states.initializer);
|
|
419
|
+
if (!statesObject) return;
|
|
420
|
+
for (const property of statesObject.properties) {
|
|
421
|
+
if (!ts$1.isPropertyAssignment(property)) continue;
|
|
422
|
+
const child = unwrapObjectLiteralExpression(property.initializer);
|
|
423
|
+
const key = getPropertyNameText$1(property.name);
|
|
424
|
+
if (child && key) visitState(child, [...sourcePath, key]);
|
|
425
|
+
}
|
|
426
|
+
};
|
|
427
|
+
visitState(root, []);
|
|
428
|
+
return found;
|
|
429
|
+
}
|
|
231
430
|
function findMachineConfigObjectLiteral(sourceFile, bindings) {
|
|
232
431
|
let found = null;
|
|
233
432
|
const visit = (node) => {
|
|
@@ -276,7 +475,7 @@ function collectStateLocations(stateObject, parentPath, locations, statesObjectL
|
|
|
276
475
|
function resolveStateProperty(property, bindings, staticValues, root) {
|
|
277
476
|
if (ts$1.isShorthandPropertyAssignment(property)) {
|
|
278
477
|
const binding = bindings.get(property.name.text);
|
|
279
|
-
if (!binding) return null;
|
|
478
|
+
if (!binding || binding.kind === "transitionFunction") return null;
|
|
280
479
|
return {
|
|
281
480
|
key: property.name.text,
|
|
282
481
|
kind: binding.kind,
|
|
@@ -306,7 +505,7 @@ function resolveStateProperty(property, bindings, staticValues, root) {
|
|
|
306
505
|
};
|
|
307
506
|
if (ts$1.isIdentifier(property.initializer)) {
|
|
308
507
|
const binding = bindings.get(property.initializer.text);
|
|
309
|
-
if (!binding) return null;
|
|
508
|
+
if (!binding || binding.kind === "transitionFunction") return null;
|
|
310
509
|
return {
|
|
311
510
|
key: resolvedKey.key,
|
|
312
511
|
kind: binding.kind,
|
|
@@ -584,10 +783,13 @@ function parseSourceToMachine(text, document, options = {}) {
|
|
|
584
783
|
...statesObjectReplacements,
|
|
585
784
|
...importReplacements
|
|
586
785
|
].filter(removeOverlappingRanges).sort(compareSourceRangesDescending));
|
|
587
|
-
if (sourceLocations.profile === "xstate-v6-alpha")
|
|
786
|
+
if (sourceLocations.profile === "xstate-v6-alpha") {
|
|
787
|
+
const importedTransitionSources = collectImportedXStateTransitionSources(text, document, options);
|
|
788
|
+
return `import { createMachine } from "xstate";
|
|
588
789
|
|
|
589
|
-
export const machine = createMachine(${serializeJS(xstateSourceToConfig(hydratedText, { profile: "xstate-v6-alpha" }), 0)});
|
|
790
|
+
export const machine = createMachine(${serializeJS(xstateSourceToConfig(importedTransitionSources.length ? `${hydratedText}\n${importedTransitionSources.join("\n")}` : hydratedText, { profile: "xstate-v6-alpha" }), 0)});
|
|
590
791
|
`;
|
|
792
|
+
}
|
|
591
793
|
return hydratedText;
|
|
592
794
|
}
|
|
593
795
|
function readHydratedStatesObject(uri, range, states, resolver) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@statelyai/sdk",
|
|
3
|
-
"version": "0.14.
|
|
3
|
+
"version": "0.14.2",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist",
|
|
@@ -81,7 +81,7 @@
|
|
|
81
81
|
"tsdown": "0.21.0-beta.2",
|
|
82
82
|
"vitest": "^3.2.4",
|
|
83
83
|
"ws": "^8.19.0",
|
|
84
|
-
"@statelyai/graph-tools": "0.0.
|
|
84
|
+
"@statelyai/graph-tools": "0.0.7"
|
|
85
85
|
},
|
|
86
86
|
"scripts": {
|
|
87
87
|
"build": "tsdown",
|
|
File without changes
|