@statelyai/sdk 0.31.0 → 0.31.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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.slice(13).split(".")[0];
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: return null;
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 (key === "events" && ts.isObjectLiteralExpression(property.initializer)) {
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.events = events;
4563
+ result[key] = events;
4486
4564
  continue;
4487
4565
  }
4488
- const schema = typesCallSchema(property.initializer);
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 = parent.imports ? { imports: parent.imports } : {};
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
- const transition = transitionFromValue(branch.result, branch.actions);
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
- * `xstate.enqueue` code action. Direct `enq.raise(...)` / `enq(() => ...)`
5121
- * bodies are deliberately left alone: they are authored code, not a list.
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 enqueueAction(fn);
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
- let result = `z.object(${serializeJS(Object.fromEntries(Object.entries(properties).map(([key, definition]) => {
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 += ".passthrough()";
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 ? toV6MachineConfig(graphToMachineConfig(graph, {
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 toV6MachineConfig(machineConfig) {
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 && typeof target === "string" && context === void 0 && !transition.reenter && !transition.meta) return target;
6050
- if (actions.length === 0 && target === void 0 && context === void 0) return mapV6MachineConfig(transition);
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
- if (body.startsWith("{")) return null;
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: `(${expression})({ context, event, input, output, actions, guards, children, self, system })`,
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
- return V6_ARG_BINDINGS.filter((name) => new RegExp(`\\b${name}\\b`).test(code));
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
- for (const item of transitions) {
6189
- if (!item || typeof item !== "object" || Array.isArray(item)) return;
6190
- const transition = item;
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: transition.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) => ` ${statement}`);
6232
- for (const branch of renderedBranches) if (branch.condition === "true") lines.push(...branch.body.map((line) => ` ${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(` if (${branch.condition}) {`);
6235
- lines.push(...branch.body.map((line) => ` ${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
- return raw(`(${merged.firstParam}, enq) => {\n${lines.join("\n")}\n}`);
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) => ` ${formatV6Statement(statement)}`), ...returnValue ? [` return ${returnValue};`] : []].join("\n")}\n}`);
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) => ` ${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) return transition.target ? `{ target: ${serializeJS(transition.target)} }` : 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
- block[implementation.name] = raw(`function ({ context, event }${params ? params : ""}) {\n ${dedent(implementation.code.body)}\n}`);
6649
- } else block[implementation.name] = raw(`function ({ context, event }) {\n // TODO: implement ${implementation.name}\n}`);
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 { raw as _, detectXStateSourceProfile as a, extractXStateMachineConfigEntries as c, graphToMachineConfig as d, graphToXStateFSM as f, normalizeMachineProfile as g, jsonSchemaToTSType as h, contextSchemaToTSType as i, getXStateFSMCompatibilityIssues as l, graphToXStateV4TS as m, RawCode as n, diffGraphsSemantically as o, graphToXStateTS as p, alignCompareGraphIds as r, eventsSchemaToTSType as s, INLINE_EXPRESSION_DIRECTIVE_FIELDS as t, graphChangeToPatchesResult as u, serializeJS as v };
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 };