@statelyai/sdk 0.31.0 → 0.31.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 +9 -0
- package/dist/assetStorage.d.mts +1 -1
- package/dist/{dist-BQEaIgBI.mjs → dist-wbhkeGh6.mjs} +356 -71
- package/dist/{editorHostSession-Dm5i4mg_.mjs → editorHostSession-DfmHzpls.mjs} +17 -8
- package/dist/{editorHostSession-BHr3WBHT.d.mts → editorHostSession-UdKBWr0I.d.mts} +12 -1
- package/dist/editorHostSession.d.mts +1 -1
- package/dist/editorHostSession.mjs +2 -2
- package/dist/embed.d.mts +6 -4
- package/dist/embed.mjs +2 -1
- package/dist/{graph-CehpcL7P.d.mts → graph-CR_g-mOq.d.mts} +1 -1
- package/dist/graph.d.mts +1 -1
- package/dist/{index-ZlKF1x_z.d.mts → index-DlOZxzrW.d.mts} +12 -1
- package/dist/index.d.mts +6 -6
- package/dist/index.mjs +4 -4
- package/dist/{inspect-BgYRNJF9.d.mts → inspect-DVRwYKva.d.mts} +3 -1
- package/dist/{inspect-BD6fDWzd.mjs → inspect-Dcjy_T2E.mjs} +25 -1
- package/dist/inspect.d.mts +2 -2
- package/dist/inspect.mjs +2 -2
- package/dist/patchTypes.d.mts +1 -1
- package/dist/{protocol-DOt1Vz-5.d.mts → protocol-DC7XJtw_.d.mts} +21 -4
- package/dist/protocol.d.mts +2 -2
- package/dist/relay.d.mts +1 -1
- package/dist/{studio-GZ6E_xns.d.mts → studio-DV5IIGhV.d.mts} +1 -1
- package/dist/studio.d.mts +1 -1
- package/dist/sync.d.mts +2 -2
- package/dist/sync.mjs +347 -13
- package/dist/{version-DbnY8nLV.mjs → version-CsJTVKWN.mjs} +2 -1
- package/package.json +3 -3
|
@@ -3279,6 +3279,7 @@ function alignCompareGraphIds(base, compare, semanticBase, semanticCompare) {
|
|
|
3279
3279
|
}
|
|
3280
3280
|
const XSTATE_V5_PROFILE = "@statelyai/xstate@5.30.0";
|
|
3281
3281
|
const XSTATE_V6_PROFILE = "@statelyai/xstate@6.0.0-alpha.51";
|
|
3282
|
+
const XSTATE_V6_BRANCH_DESCRIPTION_META = "@statelyai.branchDescription";
|
|
3282
3283
|
const LEGACY_MACHINE_PROFILES = ["xstate-v5", "xstate-v6-alpha"];
|
|
3283
3284
|
function normalizeMachineProfile(profile) {
|
|
3284
3285
|
return profile === "xstate-v5" ? XSTATE_V5_PROFILE : profile === "xstate-v6-alpha" ? XSTATE_V6_PROFILE : profile;
|
|
@@ -3301,6 +3302,15 @@ function parseProfileSpecifier(specifier) {
|
|
|
3301
3302
|
function normalizeProfileRef(profile) {
|
|
3302
3303
|
return profile === "xstate-v5" || profile === "xstate-v6-alpha" ? normalizeMachineProfile(profile) : profile;
|
|
3303
3304
|
}
|
|
3305
|
+
const AFTER_EVENT_PREFIX = "xstate.after.";
|
|
3306
|
+
/** Recovers an authored delay key from an internal after-event type. */
|
|
3307
|
+
function getDelayKeyFromEventType(eventType, sourceId) {
|
|
3308
|
+
if (!eventType.startsWith(AFTER_EVENT_PREFIX)) return null;
|
|
3309
|
+
const encoded = eventType.slice(13);
|
|
3310
|
+
const sourceSuffix = sourceId ? `.${sourceId}` : null;
|
|
3311
|
+
if (sourceSuffix && encoded.endsWith(sourceSuffix)) return encoded.slice(0, -sourceSuffix.length);
|
|
3312
|
+
return encoded.split(".")[0] ?? encoded;
|
|
3313
|
+
}
|
|
3304
3314
|
function isAutoGeneratedId(id) {
|
|
3305
3315
|
return !!id && id.startsWith("$auto-");
|
|
3306
3316
|
}
|
|
@@ -3511,6 +3521,7 @@ function singleOrArrayRecord(record) {
|
|
|
3511
3521
|
* declares that the machine has context, so dropping it loses information.
|
|
3512
3522
|
*/
|
|
3513
3523
|
const KEEP_WHEN_EMPTY = new Set(["context"]);
|
|
3524
|
+
const KEEP_SINGLETON_ARRAY = new Set(["internalEvents", "tags"]);
|
|
3514
3525
|
function simplifyAttributes(obj) {
|
|
3515
3526
|
for (const key of Object.keys(obj)) {
|
|
3516
3527
|
const value = obj[key];
|
|
@@ -3518,7 +3529,7 @@ function simplifyAttributes(obj) {
|
|
|
3518
3529
|
else if (KEEP_WHEN_EMPTY.has(key)) continue;
|
|
3519
3530
|
else if (Array.isArray(value)) {
|
|
3520
3531
|
if (value.length === 0) delete obj[key];
|
|
3521
|
-
else if (value.length === 1) obj[key] = value[0];
|
|
3532
|
+
else if (value.length === 1 && !KEEP_SINGLETON_ARRAY.has(key)) obj[key] = value[0];
|
|
3522
3533
|
} else if (typeof value === "object" && Object.keys(value).length === 0) delete obj[key];
|
|
3523
3534
|
else if (typeof value === "string" && value === "") delete obj[key];
|
|
3524
3535
|
}
|
|
@@ -3897,11 +3908,15 @@ function graphToMachineConfig(graph, options = {}) {
|
|
|
3897
3908
|
for (const edge of edges) {
|
|
3898
3909
|
const targetNode = graph.nodes.find((n) => n.id === edge.targetId);
|
|
3899
3910
|
const resolvedTarget = targetNode ? resolveTransitionTarget(graph, node, targetNode) : "";
|
|
3911
|
+
const resolvedTargets = [resolvedTarget, ...(edge.data.additionalTargetIds ?? []).flatMap((targetId) => {
|
|
3912
|
+
const additionalTarget = graph.nodes.find((n) => n.id === targetId);
|
|
3913
|
+
return additionalTarget ? [resolveTransitionTarget(graph, node, additionalTarget)] : [];
|
|
3914
|
+
})].filter(Boolean);
|
|
3900
3915
|
const type = edge.data.eventType ?? "";
|
|
3901
3916
|
const transitionMeta = showMeta ? buildMeta(edge.data.meta, edge.data.color) : void 0;
|
|
3902
3917
|
const transitionObject = {
|
|
3903
3918
|
...edge.data.matches ? { matches: edge.data.matches } : void 0,
|
|
3904
|
-
target: edge.data.transitionType === "targetless" ? void 0 : `${resolvedTarget}`,
|
|
3919
|
+
target: edge.data.transitionType === "targetless" ? void 0 : resolvedTargets.length > 1 ? resolvedTargets : `${resolvedTarget}`,
|
|
3905
3920
|
...edge.data.transitionType === "reenter" ? { reenter: true } : void 0,
|
|
3906
3921
|
guard: edge.data.guard ? serializeGuard(edge.data.guard, inlineGuardsAsTypeRef) : void 0,
|
|
3907
3922
|
...edge.data.context !== void 0 ? { context: edge.data.context } : void 0,
|
|
@@ -3949,16 +3964,16 @@ function graphToMachineConfig(graph, options = {}) {
|
|
|
3949
3964
|
else if (type === "" && node.data.type === "choice") choiceArr.push(transitionObject);
|
|
3950
3965
|
else if (type === "") alwaysArr.push(transitionObject);
|
|
3951
3966
|
else if (type.startsWith("xstate.after.")) {
|
|
3952
|
-
const delayKey = type.
|
|
3967
|
+
const delayKey = getDelayKeyFromEventType(type, edge.sourceId);
|
|
3953
3968
|
if (!after[delayKey]) after[delayKey] = [];
|
|
3954
3969
|
after[delayKey].push(transitionObject);
|
|
3955
3970
|
} else if (type === "*") pushOn("*");
|
|
3956
3971
|
else if (type.startsWith("xstate.done.state")) {
|
|
3957
3972
|
if (!onDone[type]) onDone[type] = [];
|
|
3958
3973
|
onDone[type].push(transitionObject);
|
|
3959
|
-
} else if (type.startsWith("xstate.done.actor.") || type.startsWith("xstate.error.actor.") || type.startsWith("xstate.snapshot.actor.")) {
|
|
3974
|
+
} else if (type.startsWith("xstate.done.actor.") || type.startsWith("xstate.error.actor.") || type.startsWith("xstate.snapshot.actor.") || type.startsWith("xstate.snapshot.")) {
|
|
3960
3975
|
const verb = type.startsWith("xstate.done.actor.") ? "onDone" : type.startsWith("xstate.error.actor.") ? "onError" : "onSnapshot";
|
|
3961
|
-
const invoke = findInvokeByActorId(node, type.slice(type.lastIndexOf(".actor.") + 7));
|
|
3976
|
+
const invoke = findInvokeByActorId(node, type.startsWith("xstate.snapshot.") ? type.slice(16).replace(/^actor\./, "") : type.slice(type.lastIndexOf(".actor.") + 7));
|
|
3962
3977
|
if (invoke) nestInvoke(invoke.id, verb);
|
|
3963
3978
|
else pushOn(type);
|
|
3964
3979
|
} else pushOn(type);
|
|
@@ -3999,6 +4014,7 @@ function graphToMachineConfig(graph, options = {}) {
|
|
|
3999
4014
|
if (graph.data.context !== void 0 && graph.data.context !== null) config.context = graph.data.context;
|
|
4000
4015
|
if (graph.data.version) config.version = graph.data.version;
|
|
4001
4016
|
if (graph.data.options?.maxIterations !== void 0) config.options = { maxIterations: graph.data.options.maxIterations };
|
|
4017
|
+
if (graph.data.internalEvents?.length) config.internalEvents = graph.data.internalEvents;
|
|
4002
4018
|
return deepSimplify(config);
|
|
4003
4019
|
}
|
|
4004
4020
|
const INLINE_EXPRESSION_DIRECTIVE_FIELDS = [
|
|
@@ -4400,31 +4416,32 @@ function resolvedExpressionText(expression, bindings, resolving = /* @__PURE__ *
|
|
|
4400
4416
|
for (const replacement of replacements.sort((a, b) => b.start - a.start)) result = result.slice(0, replacement.start) + replacement.text + result.slice(replacement.end);
|
|
4401
4417
|
return result;
|
|
4402
4418
|
}
|
|
4403
|
-
function typeNodeToJsonSchema(node) {
|
|
4404
|
-
if (ts.isParenthesizedTypeNode(node)) return typeNodeToJsonSchema(node.type);
|
|
4419
|
+
function typeNodeToJsonSchema(node, bindings = /* @__PURE__ */ new Map(), resolving = /* @__PURE__ */ new Set()) {
|
|
4420
|
+
if (ts.isParenthesizedTypeNode(node)) return typeNodeToJsonSchema(node.type, bindings, resolving);
|
|
4405
4421
|
if (ts.isLiteralTypeNode(node)) {
|
|
4406
4422
|
const literal = node.literal;
|
|
4407
4423
|
if (ts.isStringLiteral(literal) || ts.isNumericLiteral(literal)) return { const: ts.isNumericLiteral(literal) ? Number(literal.text) : literal.text };
|
|
4408
4424
|
if (literal.kind === ts.SyntaxKind.TrueKeyword) return { const: true };
|
|
4409
4425
|
if (literal.kind === ts.SyntaxKind.FalseKeyword) return { const: false };
|
|
4426
|
+
if (literal.kind === ts.SyntaxKind.NullKeyword) return { type: "null" };
|
|
4410
4427
|
return null;
|
|
4411
4428
|
}
|
|
4412
4429
|
if (ts.isUnionTypeNode(node)) {
|
|
4413
|
-
const members = node.types.map(typeNodeToJsonSchema);
|
|
4430
|
+
const members = node.types.map((member) => typeNodeToJsonSchema(member, bindings, resolving));
|
|
4414
4431
|
if (members.some((member) => !member)) return null;
|
|
4415
4432
|
const constants = members.map((member) => member?.const);
|
|
4416
4433
|
if (constants.every((value) => value !== void 0)) return { enum: constants };
|
|
4417
4434
|
return { anyOf: members };
|
|
4418
4435
|
}
|
|
4419
4436
|
if (ts.isArrayTypeNode(node)) {
|
|
4420
|
-
const items = typeNodeToJsonSchema(node.elementType);
|
|
4437
|
+
const items = typeNodeToJsonSchema(node.elementType, bindings, resolving);
|
|
4421
4438
|
return items ? {
|
|
4422
4439
|
type: "array",
|
|
4423
4440
|
items
|
|
4424
4441
|
} : null;
|
|
4425
4442
|
}
|
|
4426
4443
|
if (ts.isTupleTypeNode(node)) {
|
|
4427
|
-
const items = node.elements.map((element) => typeNodeToJsonSchema(element));
|
|
4444
|
+
const items = node.elements.map((element) => typeNodeToJsonSchema(element, bindings, resolving));
|
|
4428
4445
|
if (items.some((item) => !item)) return null;
|
|
4429
4446
|
return {
|
|
4430
4447
|
type: "array",
|
|
@@ -4439,7 +4456,7 @@ function typeNodeToJsonSchema(node) {
|
|
|
4439
4456
|
for (const member of node.members) {
|
|
4440
4457
|
if (!ts.isPropertySignature(member) || !member.type || !member.name) return null;
|
|
4441
4458
|
const name = propName(member.name);
|
|
4442
|
-
const schema = typeNodeToJsonSchema(member.type);
|
|
4459
|
+
const schema = typeNodeToJsonSchema(member.type, bindings, resolving);
|
|
4443
4460
|
if (!name || !schema) return null;
|
|
4444
4461
|
properties[name] = schema;
|
|
4445
4462
|
if (!member.questionToken) required.push(name);
|
|
@@ -4452,21 +4469,77 @@ function typeNodeToJsonSchema(node) {
|
|
|
4452
4469
|
};
|
|
4453
4470
|
}
|
|
4454
4471
|
switch (node.kind) {
|
|
4472
|
+
case ts.SyntaxKind.VoidKeyword: return {
|
|
4473
|
+
type: "object",
|
|
4474
|
+
properties: {},
|
|
4475
|
+
required: []
|
|
4476
|
+
};
|
|
4455
4477
|
case ts.SyntaxKind.StringKeyword: return { type: "string" };
|
|
4456
4478
|
case ts.SyntaxKind.NumberKeyword: return { type: "number" };
|
|
4457
4479
|
case ts.SyntaxKind.BooleanKeyword: return { type: "boolean" };
|
|
4458
4480
|
case ts.SyntaxKind.NullKeyword: return { type: "null" };
|
|
4481
|
+
case ts.SyntaxKind.VoidKeyword: return {
|
|
4482
|
+
type: "object",
|
|
4483
|
+
properties: {},
|
|
4484
|
+
required: [],
|
|
4485
|
+
additionalProperties: false
|
|
4486
|
+
};
|
|
4459
4487
|
case ts.SyntaxKind.UnknownKeyword:
|
|
4460
4488
|
case ts.SyntaxKind.AnyKeyword: return {};
|
|
4461
|
-
default:
|
|
4489
|
+
default: break;
|
|
4490
|
+
}
|
|
4491
|
+
if (ts.isTypeReferenceNode(node) && ts.isIdentifier(node.typeName)) {
|
|
4492
|
+
const name = node.typeName.text;
|
|
4493
|
+
if (name === "Array" && node.typeArguments?.length === 1) {
|
|
4494
|
+
const items = typeNodeToJsonSchema(node.typeArguments[0], bindings, resolving);
|
|
4495
|
+
return items ? {
|
|
4496
|
+
type: "array",
|
|
4497
|
+
items
|
|
4498
|
+
} : null;
|
|
4499
|
+
}
|
|
4500
|
+
const binding = bindings.get(name);
|
|
4501
|
+
if (!binding || resolving.has(name)) return null;
|
|
4502
|
+
const nextResolving = new Set(resolving).add(name);
|
|
4503
|
+
if (ts.isTypeAliasDeclaration(binding)) return typeNodeToJsonSchema(binding.type, bindings, nextResolving);
|
|
4504
|
+
const properties = {};
|
|
4505
|
+
const required = /* @__PURE__ */ new Set();
|
|
4506
|
+
for (const heritageClause of binding.heritageClauses ?? []) {
|
|
4507
|
+
if (heritageClause.token !== ts.SyntaxKind.ExtendsKeyword) return null;
|
|
4508
|
+
for (const heritage of heritageClause.types) {
|
|
4509
|
+
if (!ts.isIdentifier(heritage.expression) || (heritage.typeArguments?.length ?? 0) > 0) return null;
|
|
4510
|
+
const baseName = heritage.expression.text;
|
|
4511
|
+
const baseBinding = bindings.get(baseName);
|
|
4512
|
+
if (!baseBinding || !ts.isInterfaceDeclaration(baseBinding)) return null;
|
|
4513
|
+
const baseSchema = typeNodeToJsonSchema(ts.factory.createTypeReferenceNode(heritage.expression, heritage.typeArguments), bindings, nextResolving);
|
|
4514
|
+
if (!baseSchema || baseSchema.type !== "object" || !baseSchema.properties) return null;
|
|
4515
|
+
Object.assign(properties, baseSchema.properties);
|
|
4516
|
+
for (const name of baseSchema.required ?? []) required.add(name);
|
|
4517
|
+
}
|
|
4518
|
+
}
|
|
4519
|
+
for (const member of binding.members) {
|
|
4520
|
+
if (!ts.isPropertySignature(member) || !member.type || !member.name) return null;
|
|
4521
|
+
const propertyName = propName(member.name);
|
|
4522
|
+
const schema = typeNodeToJsonSchema(member.type, bindings, nextResolving);
|
|
4523
|
+
if (!propertyName || !schema) return null;
|
|
4524
|
+
properties[propertyName] = schema;
|
|
4525
|
+
if (member.questionToken) required.delete(propertyName);
|
|
4526
|
+
else required.add(propertyName);
|
|
4527
|
+
}
|
|
4528
|
+
return {
|
|
4529
|
+
type: "object",
|
|
4530
|
+
properties,
|
|
4531
|
+
...required.size ? { required: [...required] } : void 0,
|
|
4532
|
+
additionalProperties: false
|
|
4533
|
+
};
|
|
4462
4534
|
}
|
|
4535
|
+
return null;
|
|
4463
4536
|
}
|
|
4464
|
-
function typesCallSchema(node) {
|
|
4537
|
+
function typesCallSchema(node, bindings) {
|
|
4465
4538
|
const value = unwrapExpression(node);
|
|
4466
4539
|
if (!ts.isCallExpression(value) || value.expression.getText() !== "types" || value.typeArguments?.length !== 1) return null;
|
|
4467
|
-
return typeNodeToJsonSchema(value.typeArguments[0]);
|
|
4540
|
+
return typeNodeToJsonSchema(value.typeArguments[0], bindings);
|
|
4468
4541
|
}
|
|
4469
|
-
function schemasObjectToValue(node) {
|
|
4542
|
+
function schemasObjectToValue(node, bindings) {
|
|
4470
4543
|
const value = unwrapExpression(node);
|
|
4471
4544
|
if (!ts.isObjectLiteralExpression(value)) return null;
|
|
4472
4545
|
const result = {};
|
|
@@ -4474,25 +4547,46 @@ function schemasObjectToValue(node) {
|
|
|
4474
4547
|
if (!ts.isPropertyAssignment(property)) continue;
|
|
4475
4548
|
const key = propName(property.name);
|
|
4476
4549
|
if (!key) continue;
|
|
4477
|
-
if (
|
|
4550
|
+
if ([
|
|
4551
|
+
"events",
|
|
4552
|
+
"internalEvents",
|
|
4553
|
+
"emitted",
|
|
4554
|
+
"children"
|
|
4555
|
+
].includes(key) && ts.isObjectLiteralExpression(property.initializer)) {
|
|
4478
4556
|
const events = {};
|
|
4479
4557
|
for (const eventProperty of property.initializer.properties) {
|
|
4480
4558
|
if (!ts.isPropertyAssignment(eventProperty)) continue;
|
|
4481
4559
|
const eventType = propName(eventProperty.name);
|
|
4482
|
-
const schema = typesCallSchema(eventProperty.initializer);
|
|
4560
|
+
const schema = typesCallSchema(eventProperty.initializer, bindings);
|
|
4483
4561
|
if (eventType && schema) events[eventType] = schema;
|
|
4484
4562
|
}
|
|
4485
|
-
result
|
|
4563
|
+
result[key] = events;
|
|
4486
4564
|
continue;
|
|
4487
4565
|
}
|
|
4488
|
-
|
|
4566
|
+
if (["actions", "guards"].includes(key) && ts.isObjectLiteralExpression(property.initializer)) {
|
|
4567
|
+
const implementations = {};
|
|
4568
|
+
for (const implementation of property.initializer.properties) {
|
|
4569
|
+
if (!ts.isPropertyAssignment(implementation)) continue;
|
|
4570
|
+
const name = propName(implementation.name);
|
|
4571
|
+
if (!name || !ts.isObjectLiteralExpression(implementation.initializer)) continue;
|
|
4572
|
+
const params = implementation.initializer.properties.find((candidate) => ts.isPropertyAssignment(candidate) && propName(candidate.name) === "params");
|
|
4573
|
+
const schema = params ? typesCallSchema(params.initializer, bindings) : null;
|
|
4574
|
+
implementations[name] = schema ? { params: schema } : {};
|
|
4575
|
+
}
|
|
4576
|
+
result[key] = implementations;
|
|
4577
|
+
continue;
|
|
4578
|
+
}
|
|
4579
|
+
const schema = typesCallSchema(property.initializer, bindings);
|
|
4489
4580
|
if (!schema) continue;
|
|
4490
4581
|
result[key] = key === "context" ? schema.properties ?? {} : schema;
|
|
4491
4582
|
}
|
|
4492
4583
|
return result;
|
|
4493
4584
|
}
|
|
4494
4585
|
function propertyContext(parent, key) {
|
|
4495
|
-
const inherited =
|
|
4586
|
+
const inherited = {
|
|
4587
|
+
...parent.imports ? { imports: parent.imports } : {},
|
|
4588
|
+
...parent.typeBindings ? { typeBindings: parent.typeBindings } : {}
|
|
4589
|
+
};
|
|
4496
4590
|
if (parent.statesMap) return {
|
|
4497
4591
|
...inherited,
|
|
4498
4592
|
v6: parent.v6
|
|
@@ -4502,12 +4596,17 @@ function propertyContext(parent, key) {
|
|
|
4502
4596
|
v6: parent.v6,
|
|
4503
4597
|
statesMap: true
|
|
4504
4598
|
};
|
|
4599
|
+
if (key === "schemas") return {
|
|
4600
|
+
...inherited,
|
|
4601
|
+
v6: parent.v6,
|
|
4602
|
+
schemasValue: true
|
|
4603
|
+
};
|
|
4505
4604
|
if (parent.machineValue && (key === "actors" || key === "actorSources")) return {
|
|
4506
4605
|
...inherited,
|
|
4507
4606
|
v6: parent.v6,
|
|
4508
4607
|
implementationMap: true
|
|
4509
4608
|
};
|
|
4510
|
-
if (parent.setupValue && (key === "actions" || key === "guards" || key === "actors" || key === "delays")) return {
|
|
4609
|
+
if (parent.setupValue && (key === "actions" || key === "guards" || key === "actors" || key === "actorSources" || key === "delays")) return {
|
|
4511
4610
|
...inherited,
|
|
4512
4611
|
v6: parent.v6,
|
|
4513
4612
|
implementationMap: true
|
|
@@ -4765,6 +4864,10 @@ function mergeBranchPrefix(prefix, branch) {
|
|
|
4765
4864
|
return {
|
|
4766
4865
|
conds: [...prefix.conds, ...branch.conds],
|
|
4767
4866
|
actions: [...prefix.actions, ...branch.actions],
|
|
4867
|
+
...prefix.contextUpdates || branch.contextUpdates ? { contextUpdates: {
|
|
4868
|
+
...prefix.contextUpdates,
|
|
4869
|
+
...branch.contextUpdates
|
|
4870
|
+
} } : {},
|
|
4768
4871
|
result: branch.result,
|
|
4769
4872
|
unknown: prefix.unknown || branch.unknown
|
|
4770
4873
|
};
|
|
@@ -4845,6 +4948,31 @@ function expressionStatementAction(statement, enqName, bindings) {
|
|
|
4845
4948
|
}
|
|
4846
4949
|
};
|
|
4847
4950
|
}
|
|
4951
|
+
/**
|
|
4952
|
+
* The v6 exporter uses a local accumulator when a transition has multiple
|
|
4953
|
+
* context updates or queued effects. Recover the partial context update from
|
|
4954
|
+
* that canonical form so import -> graph -> export remains targetable.
|
|
4955
|
+
*/
|
|
4956
|
+
function generatedContextUpdate(statement, bindings) {
|
|
4957
|
+
const expression = unwrapExpression(statement.expression);
|
|
4958
|
+
if (!ts.isBinaryExpression(expression) || expression.operatorToken.kind !== ts.SyntaxKind.EqualsToken || !ts.isIdentifier(expression.left) || expression.left.text !== "nextContext") return;
|
|
4959
|
+
const right = unwrapExpression(expression.right);
|
|
4960
|
+
if (!ts.isObjectLiteralExpression(right)) return null;
|
|
4961
|
+
const updates = {};
|
|
4962
|
+
for (const property of right.properties) {
|
|
4963
|
+
if (!ts.isSpreadAssignment(property)) return null;
|
|
4964
|
+
const spread = unwrapExpression(property.expression);
|
|
4965
|
+
if (ts.isIdentifier(spread) && spread.text === "nextContext") continue;
|
|
4966
|
+
if (!ts.isObjectLiteralExpression(spread)) return null;
|
|
4967
|
+
const value = objectLiteralToValue(spread, bindings, {
|
|
4968
|
+
v6: true,
|
|
4969
|
+
assignmentMap: true
|
|
4970
|
+
}, 0);
|
|
4971
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return null;
|
|
4972
|
+
Object.assign(updates, value);
|
|
4973
|
+
}
|
|
4974
|
+
return updates;
|
|
4975
|
+
}
|
|
4848
4976
|
function statementBranches(statements, bindings, enqName, prefixes = [{
|
|
4849
4977
|
conds: [],
|
|
4850
4978
|
actions: []
|
|
@@ -4860,6 +4988,12 @@ function statementBranches(statements, bindings, enqName, prefixes = [{
|
|
|
4860
4988
|
nextOpen.push(prefix);
|
|
4861
4989
|
continue;
|
|
4862
4990
|
}
|
|
4991
|
+
if (ts.isBlock(statement)) {
|
|
4992
|
+
const nestedBranches = statementBranches(statement.statements, scopedBindings, enqName, [prefix]);
|
|
4993
|
+
for (const branch of nestedBranches) if ("result" in branch) done.push(branch);
|
|
4994
|
+
else nextOpen.push(branch);
|
|
4995
|
+
continue;
|
|
4996
|
+
}
|
|
4863
4997
|
if (ts.isReturnStatement(statement)) {
|
|
4864
4998
|
if (!statement.expression) {
|
|
4865
4999
|
done.push({
|
|
@@ -4872,6 +5006,21 @@ function statementBranches(statements, bindings, enqName, prefixes = [{
|
|
|
4872
5006
|
continue;
|
|
4873
5007
|
}
|
|
4874
5008
|
if (ts.isExpressionStatement(statement)) {
|
|
5009
|
+
const contextUpdate = generatedContextUpdate(statement, scopedBindings);
|
|
5010
|
+
if (contextUpdate !== void 0) {
|
|
5011
|
+
if (contextUpdate === null) nextOpen.push({
|
|
5012
|
+
...prefix,
|
|
5013
|
+
unknown: true
|
|
5014
|
+
});
|
|
5015
|
+
else nextOpen.push({
|
|
5016
|
+
...prefix,
|
|
5017
|
+
contextUpdates: {
|
|
5018
|
+
...prefix.contextUpdates,
|
|
5019
|
+
...contextUpdate
|
|
5020
|
+
}
|
|
5021
|
+
});
|
|
5022
|
+
continue;
|
|
5023
|
+
}
|
|
4875
5024
|
const action = expressionStatementAction(statement, enqName, scopedBindings);
|
|
4876
5025
|
if (action) {
|
|
4877
5026
|
nextOpen.push({
|
|
@@ -4975,15 +5124,34 @@ function normalizeFunctionTransition(fn, bindings, depth) {
|
|
|
4975
5124
|
if (branches.some((branch) => branch.unknown)) return fallbackFunctionTransition(fn);
|
|
4976
5125
|
const contextIdentity = transitionContextIdentity(fn);
|
|
4977
5126
|
const transitions = branches.map((branch) => {
|
|
4978
|
-
|
|
5127
|
+
let result = branch.result;
|
|
5128
|
+
if (branch.contextUpdates && result && typeof result === "object" && !Array.isArray(result)) {
|
|
5129
|
+
const record = result;
|
|
5130
|
+
const context = record.context;
|
|
5131
|
+
const contextRecord = context && typeof context === "object" && !Array.isArray(context) ? context : null;
|
|
5132
|
+
if (contextRecord?.["@type"] === "code" && contextRecord.expr === "nextContext") result = {
|
|
5133
|
+
...record,
|
|
5134
|
+
context: branch.contextUpdates
|
|
5135
|
+
};
|
|
5136
|
+
}
|
|
5137
|
+
const transition = transitionFromValue(result, branch.actions);
|
|
4979
5138
|
if (!transition) return null;
|
|
5139
|
+
const matches = matchesFromConditions(branch.conds);
|
|
4980
5140
|
if (typeof transition === "string") {
|
|
5141
|
+
if (matches) return {
|
|
5142
|
+
target: transition,
|
|
5143
|
+
matches
|
|
5144
|
+
};
|
|
4981
5145
|
const guard = guardFromConditions(branch.conds, guardParams(fn));
|
|
4982
5146
|
return guard ? {
|
|
4983
5147
|
target: transition,
|
|
4984
5148
|
guard
|
|
4985
5149
|
} : transition;
|
|
4986
5150
|
}
|
|
5151
|
+
if (matches) return omitIdentityTransitionContext({
|
|
5152
|
+
...transition,
|
|
5153
|
+
matches
|
|
5154
|
+
}, contextIdentity);
|
|
4987
5155
|
const guard = guardFromConditions(branch.conds, guardParams(fn));
|
|
4988
5156
|
return omitIdentityTransitionContext(guard ? {
|
|
4989
5157
|
...transition,
|
|
@@ -4994,6 +5162,26 @@ function normalizeFunctionTransition(fn, bindings, depth) {
|
|
|
4994
5162
|
if (transitions.length > 1) return transitions;
|
|
4995
5163
|
return fallbackFunctionTransition(fn);
|
|
4996
5164
|
}
|
|
5165
|
+
function matchesFromConditions(conditions) {
|
|
5166
|
+
const positives = conditions.filter((condition) => !condition.negated);
|
|
5167
|
+
if (positives.length !== 1) return null;
|
|
5168
|
+
const match = positives[0].text.match(/^Object\.is\(event\[['"]([^'"]+)['"]\],\s*(.+)\)$/);
|
|
5169
|
+
if (!match) return null;
|
|
5170
|
+
const [, key, rawValue] = match;
|
|
5171
|
+
if (!key || !rawValue) return null;
|
|
5172
|
+
for (const condition of conditions) {
|
|
5173
|
+
if (!condition.negated) continue;
|
|
5174
|
+
const negative = condition.text.match(/^Object\.is\(event\[['"]([^'"]+)['"]\],\s*(.+)\)$/);
|
|
5175
|
+
if (!negative || negative[1] !== key) return null;
|
|
5176
|
+
}
|
|
5177
|
+
const value = rawValue.trim();
|
|
5178
|
+
if (value.startsWith("'") && value.endsWith("'") || value.startsWith("\"") && value.endsWith("\"")) return { [key]: value.slice(1, -1) };
|
|
5179
|
+
if (value === "true") return { [key]: true };
|
|
5180
|
+
if (value === "false") return { [key]: false };
|
|
5181
|
+
if (value === "null") return { [key]: null };
|
|
5182
|
+
const number = Number(value);
|
|
5183
|
+
return Number.isNaN(number) ? null : { [key]: number };
|
|
5184
|
+
}
|
|
4997
5185
|
/**
|
|
4998
5186
|
* XState v5 has no `choose()`, so `xstate.choose` is exported as the canonical
|
|
4999
5187
|
* `enqueueActions(({ check, enqueue }) => { if (check(g)) { enqueue(a); } ... })`
|
|
@@ -5076,15 +5264,6 @@ function inlineAction(fn) {
|
|
|
5076
5264
|
}
|
|
5077
5265
|
};
|
|
5078
5266
|
}
|
|
5079
|
-
function enqueueAction(fn) {
|
|
5080
|
-
return {
|
|
5081
|
-
type: "xstate.enqueue",
|
|
5082
|
-
params: {
|
|
5083
|
-
code: fn.getText(),
|
|
5084
|
-
lang: "ts"
|
|
5085
|
-
}
|
|
5086
|
-
};
|
|
5087
|
-
}
|
|
5088
5267
|
function inlineCodeExpression(expr, imports) {
|
|
5089
5268
|
return {
|
|
5090
5269
|
"@type": "code",
|
|
@@ -5117,8 +5296,8 @@ function codeImportsForExpression(expression, imports) {
|
|
|
5117
5296
|
* `entry: ({ actions }, enq) => { enq(actions['NAME'], params); ... }` is the
|
|
5118
5297
|
* shape the exporter writes for a plain list of *named* actions, so it is
|
|
5119
5298
|
* decomposed back into those actions instead of surviving as one opaque
|
|
5120
|
-
*
|
|
5121
|
-
*
|
|
5299
|
+
* inline code action. Direct `enq.raise(...)` / `enq(() => ...)` bodies are
|
|
5300
|
+
* authored code and remain one inline action.
|
|
5122
5301
|
*/
|
|
5123
5302
|
function enqueuedNamedActions(fn, bindings) {
|
|
5124
5303
|
const body = fn.body;
|
|
@@ -5141,7 +5320,7 @@ function enqueuedNamedActions(fn, bindings) {
|
|
|
5141
5320
|
function normalizeFunctionAction(fn, bindings) {
|
|
5142
5321
|
const actions = enqueuedNamedActions(fn, bindings);
|
|
5143
5322
|
if (actions) return actions.length === 1 ? actions[0] : actions;
|
|
5144
|
-
return
|
|
5323
|
+
return inlineAction(fn);
|
|
5145
5324
|
}
|
|
5146
5325
|
function objectLiteralToValue(node, bindings, context, depth, overrides = /* @__PURE__ */ new Map()) {
|
|
5147
5326
|
const result = {};
|
|
@@ -5159,7 +5338,7 @@ function objectLiteralToValue(node, bindings, context, depth, overrides = /* @__
|
|
|
5159
5338
|
continue;
|
|
5160
5339
|
}
|
|
5161
5340
|
if (context.v6 && key === "schemas" && ts.isPropertyAssignment(property)) {
|
|
5162
|
-
const schemas = schemasObjectToValue(property.initializer);
|
|
5341
|
+
const schemas = schemasObjectToValue(property.initializer, context.typeBindings ?? /* @__PURE__ */ new Map());
|
|
5163
5342
|
if (schemas) {
|
|
5164
5343
|
result[key] = schemas;
|
|
5165
5344
|
continue;
|
|
@@ -5212,6 +5391,14 @@ function expressionToValue(expression, bindings, context = {}, depth = 0) {
|
|
|
5212
5391
|
}
|
|
5213
5392
|
return inlineCodeExpression(node.getText(), codeImportsForExpression(node.getText(), context.imports));
|
|
5214
5393
|
}
|
|
5394
|
+
if (context.schemasValue) {
|
|
5395
|
+
if (ts.isIdentifier(node)) {
|
|
5396
|
+
const binding = bindings.get(node.text);
|
|
5397
|
+
if (binding && !ts.isFunctionDeclaration(binding)) return expressionToValue(binding, bindings, context, depth + 1);
|
|
5398
|
+
}
|
|
5399
|
+
const schemas = schemasObjectToValue(node, context.typeBindings ?? /* @__PURE__ */ new Map());
|
|
5400
|
+
if (schemas) return schemas;
|
|
5401
|
+
}
|
|
5215
5402
|
if (context.machineContextValue && (ts.isArrowFunction(node) || ts.isFunctionExpression(node))) return inlineCodeExpression(node.getText());
|
|
5216
5403
|
if (context.targetValue) {
|
|
5217
5404
|
if (ts.isStringLiteral(node) || ts.isNoSubstitutionTemplateLiteral(node)) return node.text;
|
|
@@ -5340,6 +5527,12 @@ function collectBindings(file) {
|
|
|
5340
5527
|
}
|
|
5341
5528
|
return bindings;
|
|
5342
5529
|
}
|
|
5530
|
+
function collectSchemaTypeBindings(file) {
|
|
5531
|
+
const bindings = /* @__PURE__ */ new Map();
|
|
5532
|
+
for (const statement of file.statements) if (ts.isTypeAliasDeclaration(statement) && statement.name) bindings.set(statement.name.text, statement);
|
|
5533
|
+
else if (ts.isInterfaceDeclaration(statement) && statement.name) bindings.set(statement.name.text, statement);
|
|
5534
|
+
return bindings;
|
|
5535
|
+
}
|
|
5343
5536
|
function collectSourceImports(file) {
|
|
5344
5537
|
const imports = /* @__PURE__ */ new Map();
|
|
5345
5538
|
for (const statement of file.statements) {
|
|
@@ -5524,6 +5717,7 @@ function extractXStateMachineConfigEntries(source, options = {}) {
|
|
|
5524
5717
|
const file = sourceFile(source);
|
|
5525
5718
|
const bindings = collectBindings(file);
|
|
5526
5719
|
const imports = collectSourceImports(file);
|
|
5720
|
+
const typeBindings = collectSchemaTypeBindings(file);
|
|
5527
5721
|
const found = [];
|
|
5528
5722
|
let machineIndex = 0;
|
|
5529
5723
|
const profile = options.profile === "auto" || !options.profile ? detectXStateSourceProfile(source) : options.profile;
|
|
@@ -5605,14 +5799,16 @@ function extractXStateMachineConfigEntries(source, options = {}) {
|
|
|
5605
5799
|
const value = expressionToValue(arg, bindings, {
|
|
5606
5800
|
v6: profile === "xstate-v6-alpha",
|
|
5607
5801
|
machineValue: true,
|
|
5608
|
-
imports
|
|
5802
|
+
imports,
|
|
5803
|
+
typeBindings
|
|
5609
5804
|
});
|
|
5610
5805
|
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
5611
5806
|
const { states: setupStates, ...setupWithoutStates } = setupConfigExpressionsForCreateMachine(node, bindings).reduce((merged, setupArg) => {
|
|
5612
5807
|
const setupValue = expressionToValue(setupArg, bindings, {
|
|
5613
5808
|
v6: profile === "xstate-v6-alpha",
|
|
5614
5809
|
setupValue: true,
|
|
5615
|
-
imports
|
|
5810
|
+
imports,
|
|
5811
|
+
typeBindings
|
|
5616
5812
|
});
|
|
5617
5813
|
if (!isRecordValue(setupValue)) return merged;
|
|
5618
5814
|
return mergeSetupRecords(merged, setupValue);
|
|
@@ -5751,11 +5947,12 @@ function eventSchemaToZod(schema) {
|
|
|
5751
5947
|
function objectToZod(schema) {
|
|
5752
5948
|
const properties = schema.properties ?? {};
|
|
5753
5949
|
const required = new Set(Array.isArray(schema.required) ? schema.required : []);
|
|
5754
|
-
|
|
5950
|
+
const shape = Object.fromEntries(Object.entries(properties).map(([key, definition]) => {
|
|
5755
5951
|
return [key, raw(`${definitionToZod(definition)}${isRequiredProperty(key, definition, required) ? "" : ".optional()"}`)];
|
|
5756
|
-
}))
|
|
5952
|
+
}));
|
|
5953
|
+
let result = `z.object(${serializeJS(shape)})`;
|
|
5757
5954
|
if (schema.additionalProperties === false) result += ".strict()";
|
|
5758
|
-
else if (schema.additionalProperties === true || schema.additionalProperties === void 0) result
|
|
5955
|
+
else if (schema.additionalProperties === true || schema.additionalProperties === void 0) result = `z.looseObject(${serializeJS(shape)})`;
|
|
5759
5956
|
else if (schema.additionalProperties) result += `.catchall(${jsonSchemaToZod(schema.additionalProperties)})`;
|
|
5760
5957
|
return result;
|
|
5761
5958
|
}
|
|
@@ -5838,7 +6035,7 @@ function graphToXStateTS(graph, options = {}) {
|
|
|
5838
6035
|
const schemas = graph.data.schemas;
|
|
5839
6036
|
const impls = filterInlineImplementations$1(graph.data.implementations);
|
|
5840
6037
|
const supportsTypeSyntax = targetLanguage === "typescript";
|
|
5841
|
-
const hasSchemas = !!(schemas && (schemas.context || schemas.events || schemas.input || schemas.output));
|
|
6038
|
+
const hasSchemas = !!(schemas && (schemas.context || schemas.events || schemas.internalEvents || schemas.emitted || schemas.actions || schemas.guards || schemas.children || schemas.input || schemas.output || schemas.tags || schemas.meta));
|
|
5842
6039
|
const hasStateSchemas = graph.nodes.some((node) => node.data.schemas);
|
|
5843
6040
|
const hasActions = !!impls?.actions.length;
|
|
5844
6041
|
const hasGuards = !!impls?.guards.length;
|
|
@@ -5861,7 +6058,7 @@ function graphToXStateTS(graph, options = {}) {
|
|
|
5861
6058
|
usesTypes: xstateVersion === 6 && supportsTypeSyntax && (hasSchemas || hasStateSchemas) && xstateV6SchemaFormat === "types",
|
|
5862
6059
|
usesZod: xstateVersion === 6 && (hasSchemas || hasStateSchemas) && xstateV6SchemaFormat === "zod"
|
|
5863
6060
|
});
|
|
5864
|
-
const machineConfig = xstateVersion === 6 ?
|
|
6061
|
+
const machineConfig = xstateVersion === 6 ? toXStateV6MachineConfig(graphToMachineConfig(graph, {
|
|
5865
6062
|
...configOptions,
|
|
5866
6063
|
keepChooseStructured: true
|
|
5867
6064
|
})) : toV5MachineConfig(graphToMachineConfig(graph, configOptions));
|
|
@@ -5993,7 +6190,7 @@ function toV5MachineConfig(machineConfig) {
|
|
|
5993
6190
|
return wasArray ? mapped : mapped[0];
|
|
5994
6191
|
});
|
|
5995
6192
|
}
|
|
5996
|
-
function
|
|
6193
|
+
function toXStateV6MachineConfig(machineConfig) {
|
|
5997
6194
|
return mapV6MachineConfig(machineConfig);
|
|
5998
6195
|
}
|
|
5999
6196
|
function mapV6MachineConfig(value, context = {}) {
|
|
@@ -6006,6 +6203,10 @@ function mapV6MachineConfig(value, context = {}) {
|
|
|
6006
6203
|
result[key] = mapV6StatesMap(item);
|
|
6007
6204
|
continue;
|
|
6008
6205
|
}
|
|
6206
|
+
if (key === "choice") {
|
|
6207
|
+
result[key] = buildV6TransitionFunction(Array.isArray(item) ? item : [item]) ?? mapV6MachineConfig(item, { transitionValue: true });
|
|
6208
|
+
continue;
|
|
6209
|
+
}
|
|
6009
6210
|
if (key === "entry" || key === "exit" || key === "actions") {
|
|
6010
6211
|
result[key] = toV6ActionField(Array.isArray(item) ? item : item === void 0 ? [] : [item]);
|
|
6011
6212
|
continue;
|
|
@@ -6041,18 +6242,20 @@ function toV6TransitionValue(value) {
|
|
|
6041
6242
|
const transition = value;
|
|
6042
6243
|
if (transition.matches !== void 0) return buildV6TransitionFunction([transition]) ?? mapV6MachineConfig(transition);
|
|
6043
6244
|
if (transition.guard) return buildV6TransitionFunction([transition]) ?? mapV6MachineConfig(transition);
|
|
6044
|
-
if (transition.description || transition.input !== void 0) return mapV6MachineConfig(transition);
|
|
6245
|
+
if (transition.description || transition.input !== void 0 && !containsInlineExpression(transition.input)) return mapV6MachineConfig(transition);
|
|
6045
6246
|
const target = transition.target;
|
|
6046
6247
|
const context = transition.context;
|
|
6047
6248
|
const actionsValue = transition.actions;
|
|
6048
6249
|
const actions = Array.isArray(actionsValue) ? actionsValue : actionsValue === void 0 ? [] : [actionsValue];
|
|
6049
|
-
if (actions.length === 0 &&
|
|
6050
|
-
if (actions.length === 0 && target === void 0 &&
|
|
6250
|
+
if (actions.length === 0 && !containsInlineExpression(transition) && !containsTemplateExpression(transition)) return mapV6MachineConfig(transition);
|
|
6251
|
+
if (actions.length === 0 && typeof target === "string" && context === void 0 && transition.input === void 0 && !transition.reenter && !transition.meta) return { target };
|
|
6252
|
+
if (actions.length === 0 && target === void 0 && context === void 0 && transition.input === void 0) return mapV6MachineConfig(transition);
|
|
6051
6253
|
return buildV6ActionFunction(actions, {
|
|
6052
|
-
target: typeof target === "string" ? target : void 0,
|
|
6254
|
+
target: typeof target === "string" || Array.isArray(target) && target.every((item) => typeof item === "string") ? target : void 0,
|
|
6053
6255
|
reenter: transition.reenter === true,
|
|
6054
6256
|
meta: transition.meta,
|
|
6055
|
-
context
|
|
6257
|
+
context,
|
|
6258
|
+
input: transition.input
|
|
6056
6259
|
}) ?? mapV6MachineConfig(transition);
|
|
6057
6260
|
}
|
|
6058
6261
|
function guardCondition(value) {
|
|
@@ -6075,10 +6278,14 @@ function guardCondition(value) {
|
|
|
6075
6278
|
if (arrow < 0) return null;
|
|
6076
6279
|
const params = expression.slice(0, arrow).trim();
|
|
6077
6280
|
const body = expression.slice(arrow + 2).trim();
|
|
6078
|
-
|
|
6281
|
+
const callCondition = `(${expression})({ context, event, input, output, actions, guards, children, self, system })`;
|
|
6282
|
+
if (body.startsWith("{")) return {
|
|
6283
|
+
condition: callCondition,
|
|
6284
|
+
callCondition
|
|
6285
|
+
};
|
|
6079
6286
|
return {
|
|
6080
6287
|
condition: body,
|
|
6081
|
-
callCondition
|
|
6288
|
+
callCondition,
|
|
6082
6289
|
firstParam: params.startsWith("(") && params.endsWith(")") ? params.slice(1, -1).trim() : params
|
|
6083
6290
|
};
|
|
6084
6291
|
}
|
|
@@ -6106,7 +6313,8 @@ const V6_ARG_BINDINGS = [
|
|
|
6106
6313
|
];
|
|
6107
6314
|
const V6_IDENTIFIER = /^[A-Za-z_$][A-Za-z0-9_$]*$/;
|
|
6108
6315
|
function inferV6ArgBindings(code) {
|
|
6109
|
-
|
|
6316
|
+
const withoutPropertyKeys = code.replace(/\b(context|event|input|output|actions|guards|children|self|system)\s*:/g, "");
|
|
6317
|
+
return V6_ARG_BINDINGS.filter((name) => new RegExp(`\\b${name}\\b`).test(withoutPropertyKeys));
|
|
6110
6318
|
}
|
|
6111
6319
|
/** Splits a destructuring pattern body on its top-level commas. */
|
|
6112
6320
|
function splitV6PatternEntries(body) {
|
|
@@ -6183,11 +6391,15 @@ function mergeV6FirstParam(authoredFirstParam, inferred) {
|
|
|
6183
6391
|
};
|
|
6184
6392
|
}
|
|
6185
6393
|
function buildV6TransitionFunction(transitions) {
|
|
6394
|
+
const transitionObjects = transitions.every((item) => Boolean(item) && typeof item === "object" && !Array.isArray(item)) ? transitions : void 0;
|
|
6395
|
+
if (!transitionObjects?.length) return;
|
|
6396
|
+
const descriptions = transitionObjects.map((transition) => typeof transition.description === "string" ? transition.description : void 0);
|
|
6397
|
+
const hasBranchDescriptions = transitionObjects.some((transition) => Object.prototype.hasOwnProperty.call(transition.meta ?? {}, XSTATE_V6_BRANCH_DESCRIPTION_META)) || descriptions.some((description) => description !== descriptions[0]);
|
|
6186
6398
|
const branches = [];
|
|
6187
6399
|
let authoredFirstParam;
|
|
6188
|
-
|
|
6189
|
-
|
|
6190
|
-
const
|
|
6400
|
+
const commonDescription = descriptions[0];
|
|
6401
|
+
for (const transition of transitionObjects) {
|
|
6402
|
+
const description = typeof transition.description === "string" ? transition.description : void 0;
|
|
6191
6403
|
const match = transition.matches === void 0 ? void 0 : matchesCondition(transition.matches);
|
|
6192
6404
|
if (match === null) return;
|
|
6193
6405
|
const guard = guardCondition(transition.guard);
|
|
@@ -6201,9 +6413,12 @@ function buildV6TransitionFunction(transitions) {
|
|
|
6201
6413
|
if (effects.some((effect) => !effect)) return;
|
|
6202
6414
|
const rendered = renderV6Effects(effects.filter((effect) => Boolean(effect)), transition.context === void 0 ? void 0 : serializeJS(unwrapTemplateExpressions(transition.context)));
|
|
6203
6415
|
const effectiveReturnValue = buildV6TransitionReturnValue({
|
|
6204
|
-
target: typeof transition.target === "string" ? transition.target : void 0,
|
|
6416
|
+
target: typeof transition.target === "string" || Array.isArray(transition.target) && transition.target.every((target) => typeof target === "string") ? transition.target : void 0,
|
|
6205
6417
|
reenter: transition.reenter === true,
|
|
6206
|
-
meta:
|
|
6418
|
+
meta: hasBranchDescriptions ? {
|
|
6419
|
+
...transition.meta ?? {},
|
|
6420
|
+
[XSTATE_V6_BRANCH_DESCRIPTION_META]: description ?? null
|
|
6421
|
+
} : transition.meta,
|
|
6207
6422
|
input: transition.input
|
|
6208
6423
|
}, rendered.contextValue) ?? "{}";
|
|
6209
6424
|
const body = [...rendered.statements.map(formatV6Statement), `return ${effectiveReturnValue};`];
|
|
@@ -6220,22 +6435,25 @@ function buildV6TransitionFunction(transitions) {
|
|
|
6220
6435
|
let renderedBranches = branches;
|
|
6221
6436
|
let merged = mergeV6FirstParam(authoredFirstParam, inferV6ArgBindings(generated));
|
|
6222
6437
|
if (!merged) {
|
|
6223
|
-
if (branches.some((branch) => !branch.callCondition)) return;
|
|
6224
6438
|
renderedBranches = branches.map((branch) => ({
|
|
6225
6439
|
...branch,
|
|
6226
|
-
condition: branch.callCondition
|
|
6440
|
+
condition: branch.callCondition ?? branch.condition
|
|
6227
6441
|
}));
|
|
6228
6442
|
merged = mergeV6FirstParam(void 0, inferV6ArgBindings(`${renderedBranches.map((branch) => branch.condition).join("\n")}\n${generated}`));
|
|
6229
6443
|
}
|
|
6230
6444
|
if (!merged) return;
|
|
6231
|
-
const lines = merged.prelude.map((statement) =>
|
|
6232
|
-
for (const branch of renderedBranches) if (branch.condition === "true") lines.push(...branch.body.map((line) =>
|
|
6445
|
+
const lines = merged.prelude.map((statement) => indentV6Code(statement, 2));
|
|
6446
|
+
for (const branch of renderedBranches) if (branch.condition === "true") lines.push(...branch.body.map((line) => indentV6Code(line, 2)));
|
|
6233
6447
|
else {
|
|
6234
|
-
lines.push(`
|
|
6235
|
-
lines.push(...branch.body.map((line) =>
|
|
6448
|
+
lines.push(indentV6Code(`if (${branch.condition}) {`, 2));
|
|
6449
|
+
lines.push(...branch.body.map((line) => indentV6Code(line, 4)));
|
|
6236
6450
|
lines.push(" }");
|
|
6237
6451
|
}
|
|
6238
|
-
|
|
6452
|
+
const transitionFunction = raw(`(${merged.firstParam}, enq) => {\n${lines.join("\n")}\n}`);
|
|
6453
|
+
return commonDescription === void 0 || hasBranchDescriptions ? transitionFunction : {
|
|
6454
|
+
description: commonDescription,
|
|
6455
|
+
to: transitionFunction
|
|
6456
|
+
};
|
|
6239
6457
|
}
|
|
6240
6458
|
function toV6ActionField(actions) {
|
|
6241
6459
|
if (actions.length === 1) {
|
|
@@ -6254,7 +6472,11 @@ function buildV6ActionFunction(actions, transition) {
|
|
|
6254
6472
|
if (transition) returnValue = buildV6TransitionReturnValue(transition, rendered.contextValue);
|
|
6255
6473
|
if (statements.length === 0 && !returnValue) return void 0;
|
|
6256
6474
|
const bindings = inferV6ArgBindings([...statements, returnValue ?? ""].join("\n"));
|
|
6257
|
-
return raw(`(${bindings.length ? `{ ${bindings.join(", ")} }` : "_"}, enq) => {\n${[...statements.map((statement) =>
|
|
6475
|
+
return raw(`(${bindings.length ? `{ ${bindings.join(", ")} }` : "_"}, enq) => {\n${[...statements.map((statement) => indentV6Code(formatV6Statement(statement), 2)), ...returnValue ? [indentV6Code(`return ${returnValue};`, 2)] : []].join("\n")}\n}`);
|
|
6476
|
+
}
|
|
6477
|
+
function indentV6Code(code, spaces) {
|
|
6478
|
+
const indent = " ".repeat(spaces);
|
|
6479
|
+
return code.split("\n").map((line) => line ? `${indent}${line}` : line).join("\n");
|
|
6258
6480
|
}
|
|
6259
6481
|
function formatV6Statement(statement) {
|
|
6260
6482
|
const trimmed = statement.trim();
|
|
@@ -6265,7 +6487,7 @@ function renderV6Effects(effects, finalContext) {
|
|
|
6265
6487
|
const statements = ["let nextContext = context"];
|
|
6266
6488
|
const inCurrentContext = (body) => {
|
|
6267
6489
|
if (body.length === 0) return;
|
|
6268
|
-
statements.push("{", " const context = nextContext", ...body.map((line) =>
|
|
6490
|
+
statements.push("{", " const context = nextContext", ...body.map((line) => indentV6Code(line, 2)), "}");
|
|
6269
6491
|
};
|
|
6270
6492
|
for (const effect of effects) {
|
|
6271
6493
|
inCurrentContext(effect.statements ?? []);
|
|
@@ -6286,8 +6508,16 @@ function unwrapTemplateExpressions(value) {
|
|
|
6286
6508
|
if (!value || typeof value !== "object") return value;
|
|
6287
6509
|
return Object.fromEntries(Object.entries(value).map(([key, item]) => [key, unwrapTemplateExpressions(item)]));
|
|
6288
6510
|
}
|
|
6511
|
+
function containsTemplateExpression(value) {
|
|
6512
|
+
if (typeof value === "string") return /^\{\{[\s\S]*\}\}$/.test(value.trim());
|
|
6513
|
+
if (Array.isArray(value)) return value.some(containsTemplateExpression);
|
|
6514
|
+
return Boolean(value) && typeof value === "object" && Object.values(value).some(containsTemplateExpression);
|
|
6515
|
+
}
|
|
6289
6516
|
function buildV6TransitionReturnValue(transition, contextValue) {
|
|
6290
|
-
if (!transition.reenter && !transition.meta && !contextValue && transition.input === void 0)
|
|
6517
|
+
if (!transition.reenter && !transition.meta && !contextValue && transition.input === void 0) {
|
|
6518
|
+
const target = Array.isArray(transition.target) ? `[${transition.target.map((item) => serializeJS(item)).join(", ")}]` : serializeJS(transition.target);
|
|
6519
|
+
return transition.target ? `{ target: ${target} }` : void 0;
|
|
6520
|
+
}
|
|
6291
6521
|
return serializeJS({
|
|
6292
6522
|
target: transition.target,
|
|
6293
6523
|
reenter: transition.reenter ? true : void 0,
|
|
@@ -6325,6 +6555,13 @@ function inlineExpr(value) {
|
|
|
6325
6555
|
const directive = value;
|
|
6326
6556
|
return directive["@type"] === "code" && typeof directive.expr === "string" ? directive.expr : void 0;
|
|
6327
6557
|
}
|
|
6558
|
+
function containsInlineExpression(value) {
|
|
6559
|
+
if (!value || typeof value !== "object") return false;
|
|
6560
|
+
if (Array.isArray(value)) return value.some(containsInlineExpression);
|
|
6561
|
+
const record = value;
|
|
6562
|
+
if (record["@type"] === "code" && typeof record.expr === "string") return true;
|
|
6563
|
+
return Object.values(record).some(containsInlineExpression);
|
|
6564
|
+
}
|
|
6328
6565
|
function actionToV6Effect(action) {
|
|
6329
6566
|
const expr = inlineExpr(action);
|
|
6330
6567
|
if (expr) {
|
|
@@ -6520,6 +6757,12 @@ function getCodeExpressionImports$1(graph) {
|
|
|
6520
6757
|
const XSTATE_ACTOR_LOGIC_HELPERS = new Set([
|
|
6521
6758
|
"createMachine",
|
|
6522
6759
|
"createAsyncLogic",
|
|
6760
|
+
"createCallbackLogic",
|
|
6761
|
+
"createEventObservableLogic",
|
|
6762
|
+
"createListenerLogic",
|
|
6763
|
+
"createLogic",
|
|
6764
|
+
"createObservableLogic",
|
|
6765
|
+
"createSubscriptionLogic",
|
|
6523
6766
|
"fromPromise",
|
|
6524
6767
|
"fromCallback",
|
|
6525
6768
|
"fromObservable",
|
|
@@ -6604,8 +6847,17 @@ function buildV6SchemasBlock(schemas, options) {
|
|
|
6604
6847
|
const contextType = contextSchemaToTSType(schemas.context);
|
|
6605
6848
|
if (contextType) result.context = raw(`types<${contextType}>()`);
|
|
6606
6849
|
if (schemas.events && Object.keys(schemas.events).length > 0) result.events = Object.fromEntries(Object.entries(schemas.events).map(([eventType, schema]) => [eventType, raw(`types<${eventPayloadSchemaToTSType(schema)}>()`)]));
|
|
6850
|
+
if (schemas.emitted && Object.keys(schemas.emitted).length > 0) result.emitted = Object.fromEntries(Object.entries(schemas.emitted).map(([eventType, schema]) => [eventType, raw(`types<${eventPayloadSchemaToTSType(schema)}>()`)]));
|
|
6851
|
+
if (schemas.internalEvents && Object.keys(schemas.internalEvents).length > 0) result.internalEvents = Object.fromEntries(Object.entries(schemas.internalEvents).map(([eventType, schema]) => [eventType, raw(`types<${eventPayloadSchemaToTSType(schema)}>()`)]));
|
|
6852
|
+
if (schemas.children && Object.keys(schemas.children).length > 0) result.children = Object.fromEntries(Object.entries(schemas.children).map(([name, schema]) => [name, raw(`types<${jsonSchemaToTSType(schema)}>()`)]));
|
|
6853
|
+
for (const key of ["actions", "guards"]) {
|
|
6854
|
+
const map = schemas[key];
|
|
6855
|
+
if (map && Object.keys(map).length > 0) result[key] = Object.fromEntries(Object.entries(map).map(([name, value]) => [name, { ...value.params ? { params: raw(`types<${jsonSchemaToTSType(value.params)}>()`) } : {} }]));
|
|
6856
|
+
}
|
|
6607
6857
|
if (schemas.input) result.input = raw(`types<${jsonSchemaToTSType(schemas.input)}>()`);
|
|
6608
6858
|
if (schemas.output) result.output = raw(`types<${jsonSchemaToTSType(schemas.output)}>()`);
|
|
6859
|
+
if (schemas.tags && Object.keys(schemas.tags).length > 0) result.tags = raw(`types<${jsonSchemaToTSType(schemas.tags)}>()`);
|
|
6860
|
+
if (schemas.meta && Object.keys(schemas.meta).length > 0) result.meta = raw(`types<${jsonSchemaToTSType(schemas.meta)}>()`);
|
|
6609
6861
|
return Object.keys(result).length > 0 ? result : void 0;
|
|
6610
6862
|
}
|
|
6611
6863
|
function buildV6ZodSchemasBlock(schemas) {
|
|
@@ -6614,14 +6866,25 @@ function buildV6ZodSchemasBlock(schemas) {
|
|
|
6614
6866
|
const contextSchema = contextSchemaToZod(schemas.context);
|
|
6615
6867
|
if (contextSchema) result.context = raw(contextSchema);
|
|
6616
6868
|
if (schemas.events && Object.keys(schemas.events).length > 0) result.events = Object.fromEntries(Object.entries(schemas.events).map(([eventType, schema]) => [eventType, raw(eventSchemaToZod(schema))]));
|
|
6869
|
+
if (schemas.emitted && Object.keys(schemas.emitted).length > 0) result.emitted = Object.fromEntries(Object.entries(schemas.emitted).map(([eventType, schema]) => [eventType, raw(eventSchemaToZod(schema))]));
|
|
6870
|
+
for (const key of ["internalEvents", "children"]) {
|
|
6871
|
+
const map = schemas[key];
|
|
6872
|
+
if (map && Object.keys(map).length > 0) result[key] = Object.fromEntries(Object.entries(map).map(([name, schema]) => [name, raw(jsonSchemaToZod(schema))]));
|
|
6873
|
+
}
|
|
6874
|
+
for (const key of ["actions", "guards"]) {
|
|
6875
|
+
const map = schemas[key];
|
|
6876
|
+
if (map && Object.keys(map).length > 0) result[key] = Object.fromEntries(Object.entries(map).map(([name, value]) => [name, { ...value.params ? { params: raw(jsonSchemaToZod(value.params)) } : {} }]));
|
|
6877
|
+
}
|
|
6617
6878
|
if (schemas.input) result.input = raw(jsonSchemaToZod(schemas.input));
|
|
6618
6879
|
if (schemas.output) result.output = raw(jsonSchemaToZod(schemas.output));
|
|
6880
|
+
if (schemas.tags && Object.keys(schemas.tags).length > 0) result.tags = raw(jsonSchemaToZod(schemas.tags));
|
|
6881
|
+
if (schemas.meta && Object.keys(schemas.meta).length > 0) result.meta = raw(jsonSchemaToZod(schemas.meta));
|
|
6619
6882
|
return Object.keys(result).length > 0 ? result : void 0;
|
|
6620
6883
|
}
|
|
6621
6884
|
function eventPayloadSchemaToTSType(schema) {
|
|
6622
6885
|
const props = schema.properties ?? {};
|
|
6623
6886
|
const payloadProps = Object.fromEntries(Object.entries(props).filter(([key]) => key !== "type"));
|
|
6624
|
-
if (Object.keys(payloadProps).length === 0) return "
|
|
6887
|
+
if (Object.keys(payloadProps).length === 0) return "void";
|
|
6625
6888
|
return jsonSchemaToTSType({
|
|
6626
6889
|
...schema,
|
|
6627
6890
|
properties: payloadProps,
|
|
@@ -6639,14 +6902,16 @@ function hasSchemaProperties(schema) {
|
|
|
6639
6902
|
function buildActionsBlock(actions, options) {
|
|
6640
6903
|
const block = {};
|
|
6641
6904
|
for (const implementation of actions) if (implementation.code?.body) {
|
|
6905
|
+
if (options.xstateVersion === 6) assertV6NamedActionBody(implementation.name, implementation.code.body);
|
|
6642
6906
|
const inlineExpression = getInlineExpression$1(implementation.code.body);
|
|
6643
6907
|
if (inlineExpression) {
|
|
6644
6908
|
block[implementation.name] = raw(inlineExpression);
|
|
6645
6909
|
continue;
|
|
6646
6910
|
}
|
|
6647
|
-
const params = hasSchemaProperties(implementation.paramsSchema) ? options.includeTypeSyntax ? `, params: ${jsonSchemaToTSType(implementation.paramsSchema)}` : ", params" : "";
|
|
6648
|
-
|
|
6649
|
-
|
|
6911
|
+
const params = hasSchemaProperties(implementation.paramsSchema) ? options.xstateVersion === 6 ? options.includeTypeSyntax ? `params: ${jsonSchemaToTSType(implementation.paramsSchema)}` : "params" : options.includeTypeSyntax ? `, params: ${jsonSchemaToTSType(implementation.paramsSchema)}` : ", params" : "";
|
|
6912
|
+
const firstParam = options.xstateVersion === 6 ? params : `{ context, event }${params}`;
|
|
6913
|
+
block[implementation.name] = raw(`function (${firstParam}) {\n ${dedent(implementation.code.body)}\n}`);
|
|
6914
|
+
} else block[implementation.name] = raw(options.xstateVersion === 6 ? `function () {\n // TODO: implement ${implementation.name}\n}` : `function ({ context, event }) {\n // TODO: implement ${implementation.name}\n}`);
|
|
6650
6915
|
return block;
|
|
6651
6916
|
}
|
|
6652
6917
|
function buildGuardsBlock(guards, options) {
|
|
@@ -6718,6 +6983,23 @@ function getInlineExpression$1(code) {
|
|
|
6718
6983
|
if (stripped !== code.trim()) return stripped;
|
|
6719
6984
|
return isCompleteFunctionExpression(stripped) || isCompleteXStateHelperExpression(stripped) ? stripped : void 0;
|
|
6720
6985
|
}
|
|
6986
|
+
/**
|
|
6987
|
+
* A complete function expression is preserved verbatim when it came from an
|
|
6988
|
+
* imported implementation. Reject the XState v5 named-action signature here
|
|
6989
|
+
* instead of emitting a v6 action whose `context`/`event` references are free
|
|
6990
|
+
* at runtime. XState v6 named actions receive only their params argument.
|
|
6991
|
+
*/
|
|
6992
|
+
function assertV6NamedActionBody(name, code) {
|
|
6993
|
+
const expression = parseSingleExpression(stripExportDefault(code))?.expression;
|
|
6994
|
+
if (!expression || !ts.isArrowFunction(expression) && !ts.isFunctionExpression(expression)) return;
|
|
6995
|
+
const firstParameter = expression.parameters[0]?.name;
|
|
6996
|
+
if (!firstParameter || !ts.isObjectBindingPattern(firstParameter)) return;
|
|
6997
|
+
if (firstParameter.elements.some((element) => {
|
|
6998
|
+
if (element.dotDotDotToken) return false;
|
|
6999
|
+
const property = element.propertyName ?? element.name;
|
|
7000
|
+
return ts.isIdentifier(property) && (property.text === "context" || property.text === "event");
|
|
7001
|
+
})) throw new Error(`Cannot export named action "${name}" as XState v6: its implementation uses the XState v5 context/event signature. Rewrite it to receive params only.`);
|
|
7002
|
+
}
|
|
6721
7003
|
function parseSingleExpression(code) {
|
|
6722
7004
|
const candidate = code.trim().replace(/;$/, "");
|
|
6723
7005
|
const source = ts.createSourceFile("implementation.ts", `(${candidate})`, ts.ScriptTarget.Latest, false, ts.ScriptKind.TS);
|
|
@@ -6833,6 +7115,9 @@ function transformState(state, ctx, sourceKey) {
|
|
|
6833
7115
|
case "output":
|
|
6834
7116
|
result.data = transformCodeValues(value);
|
|
6835
7117
|
break;
|
|
7118
|
+
case "tags":
|
|
7119
|
+
result.tags = Array.isArray(value) && value.length === 1 ? value[0] : value;
|
|
7120
|
+
break;
|
|
6836
7121
|
case "entry":
|
|
6837
7122
|
case "exit":
|
|
6838
7123
|
result[key] = transformActions(value);
|
|
@@ -7753,4 +8038,4 @@ const simulateMachineStepInputSchema = machineInputSchema.extend({
|
|
|
7753
8038
|
});
|
|
7754
8039
|
|
|
7755
8040
|
//#endregion
|
|
7756
|
-
export {
|
|
8041
|
+
export { toXStateV6MachineConfig as S, graphToXStateV4TS as _, alignCompareGraphIds as a, raw as b, diffGraphsSemantically as c, getDelayKeyFromEventType as d, getXStateFSMCompatibilityIssues as f, graphToXStateTS as g, graphToXStateFSM as h, XSTATE_V6_FN_TRANSITION_META as i, eventsSchemaToTSType as l, graphToMachineConfig as m, RawCode as n, contextSchemaToTSType as o, graphChangeToPatchesResult as p, XSTATE_V6_BRANCH_DESCRIPTION_META as r, detectXStateSourceProfile as s, INLINE_EXPRESSION_DIRECTIVE_FIELDS as t, extractXStateMachineConfigEntries as u, jsonSchemaToTSType as v, serializeJS as x, normalizeMachineProfile as y };
|