@mmapp/react-compiler 0.1.0-alpha.3 → 0.1.0-alpha.5

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.
@@ -445,25 +445,25 @@ function inferTransitionStates(transitions, states) {
445
445
  const stateArray = Array.from(states.values());
446
446
  const startStates = stateArray.filter((s) => s.type === "START");
447
447
  const regularStates = stateArray.filter((s) => s.type === "REGULAR");
448
- const needsInference = transitions.filter((t19) => t19.from.length === 0 || !t19.to);
448
+ const needsInference = transitions.filter((t23) => t23.from.length === 0 || !t23.to);
449
449
  if (needsInference.length === 0) return;
450
450
  if (startStates.length === 1 && regularStates.length > 0) {
451
- needsInference.forEach((t19, idx) => {
452
- if (t19.from.length === 0) {
453
- t19.from = [startStates[0].name];
451
+ needsInference.forEach((t23, idx) => {
452
+ if (t23.from.length === 0) {
453
+ t23.from = [startStates[0].name];
454
454
  }
455
- if (!t19.to) {
456
- t19.to = regularStates[idx % regularStates.length]?.name || startStates[0].name;
455
+ if (!t23.to) {
456
+ t23.to = regularStates[idx % regularStates.length]?.name || startStates[0].name;
457
457
  }
458
458
  });
459
459
  } else {
460
460
  const allStateNames = stateArray.map((s) => s.name);
461
- needsInference.forEach((t19, idx) => {
462
- if (t19.from.length === 0 && allStateNames.length > 0) {
463
- t19.from = [allStateNames[0]];
461
+ needsInference.forEach((t23, idx) => {
462
+ if (t23.from.length === 0 && allStateNames.length > 0) {
463
+ t23.from = [allStateNames[0]];
464
464
  }
465
- if (!t19.to && allStateNames.length > 1) {
466
- t19.to = allStateNames[Math.min(idx + 1, allStateNames.length - 1)];
465
+ if (!t23.to && allStateNames.length > 1) {
466
+ t23.to = allStateNames[Math.min(idx + 1, allStateNames.length - 1)];
467
467
  }
468
468
  });
469
469
  }
@@ -2551,7 +2551,7 @@ function resolveType(annotation) {
2551
2551
  }
2552
2552
  if (t11.isTSUnionType(annotation)) {
2553
2553
  const allLiterals = annotation.types.every(
2554
- (t22) => t11.isTSLiteralType(t22) && (t11.isStringLiteral(t22.literal) || t11.isNumericLiteral(t22.literal))
2554
+ (t23) => t11.isTSLiteralType(t23) && (t11.isStringLiteral(t23.literal) || t11.isNumericLiteral(t23.literal))
2555
2555
  );
2556
2556
  if (allLiterals) return "select";
2557
2557
  return "text";
@@ -3033,6 +3033,7 @@ function extractDefineModelCall(programPath, compilerState, actionCounter) {
3033
3033
  const on_exit = parseActionArray(stateConfig.on_exit, actionCounter);
3034
3034
  const during = parseDuringArray(stateConfig.during, actionCounter);
3035
3035
  const on_event = parseOnEventArray(stateConfig.on_event, actionCounter);
3036
+ const stateRuntime = stateConfig.runtime;
3036
3037
  if (!compilerState.states.has(name)) {
3037
3038
  compilerState.states.set(name, {
3038
3039
  name,
@@ -3041,7 +3042,8 @@ function extractDefineModelCall(programPath, compilerState, actionCounter) {
3041
3042
  on_enter,
3042
3043
  during,
3043
3044
  on_exit,
3044
- ...on_event.length > 0 ? { on_event } : {}
3045
+ ...on_event.length > 0 ? { on_event } : {},
3046
+ ...stateRuntime ? { runtime: stateRuntime } : {}
3045
3047
  });
3046
3048
  } else {
3047
3049
  const existing = compilerState.states.get(name);
@@ -3095,6 +3097,7 @@ function extractDefineModelCall(programPath, compilerState, actionCounter) {
3095
3097
  }
3096
3098
  }
3097
3099
  const actions = parseActionArray(transConfig.actions, actionCounter);
3100
+ const transRuntime = transConfig.runtime;
3098
3101
  compilerState.transitions.push({
3099
3102
  name,
3100
3103
  from,
@@ -3104,7 +3107,8 @@ function extractDefineModelCall(programPath, compilerState, actionCounter) {
3104
3107
  actions,
3105
3108
  roles: transConfig.roles,
3106
3109
  auto: transConfig.auto,
3107
- required_fields: transConfig.required_fields
3110
+ required_fields: transConfig.required_fields,
3111
+ ...transRuntime ? { runtime: transRuntime } : {}
3108
3112
  });
3109
3113
  }
3110
3114
  }
@@ -3121,6 +3125,9 @@ function extractDefineModelCall(programPath, compilerState, actionCounter) {
3121
3125
  if (config.metadata && typeof config.metadata === "object") {
3122
3126
  compilerState.metadata.modelMetadata = config.metadata;
3123
3127
  }
3128
+ if (config.orchestration && typeof config.orchestration === "object" && !Array.isArray(config.orchestration)) {
3129
+ compilerState.metadata.orchestration = config.orchestration;
3130
+ }
3124
3131
  return true;
3125
3132
  }
3126
3133
  return false;
@@ -3309,6 +3316,1873 @@ var init_model_extractor = __esm({
3309
3316
  }
3310
3317
  });
3311
3318
 
3319
+ // src/babel/extractors/workflow-shorthand.ts
3320
+ function makeState(name, type) {
3321
+ return {
3322
+ name,
3323
+ type,
3324
+ on_enter: [],
3325
+ during: [],
3326
+ on_exit: []
3327
+ };
3328
+ }
3329
+ function makeTransition(name, from, to) {
3330
+ return {
3331
+ name,
3332
+ from: [from],
3333
+ to,
3334
+ actions: []
3335
+ };
3336
+ }
3337
+ function dedupeTransitions(ts) {
3338
+ const seen = /* @__PURE__ */ new Set();
3339
+ const out = [];
3340
+ for (const t23 of ts) {
3341
+ const key = `${t23.name}::${t23.from.join(",")}::${t23.to}`;
3342
+ if (!seen.has(key)) {
3343
+ seen.add(key);
3344
+ out.push(t23);
3345
+ }
3346
+ }
3347
+ return out;
3348
+ }
3349
+ function tokenize(line) {
3350
+ const tokens = [];
3351
+ let m;
3352
+ TOKEN_RE.lastIndex = 0;
3353
+ while ((m = TOKEN_RE.exec(line)) !== null) {
3354
+ if (m[1]) {
3355
+ tokens.push({ kind: "arrow", direction: "bidirectional" });
3356
+ } else if (m[2]) {
3357
+ tokens.push({ kind: "arrow", direction: "backward", name: m[2] });
3358
+ } else if (m[3]) {
3359
+ tokens.push({ kind: "arrow", direction: "backward" });
3360
+ } else if (m[4]) {
3361
+ tokens.push({ kind: "arrow", direction: "forward", name: m[4] });
3362
+ } else if (m[5]) {
3363
+ tokens.push({ kind: "arrow", direction: "forward" });
3364
+ } else if (m[6]) {
3365
+ tokens.push({ kind: "branch" });
3366
+ } else if (m[7]) {
3367
+ tokens.push({ kind: "state", name: m[7] });
3368
+ }
3369
+ }
3370
+ return tokens;
3371
+ }
3372
+ function parseTokens(tokens, stateMap, transitions, outgoingCounts) {
3373
+ let lastState = null;
3374
+ for (let i = 0; i < tokens.length; i++) {
3375
+ const tok = tokens[i];
3376
+ if (tok.kind === "state") {
3377
+ stateMap.set(tok.name, stateMap.has(tok.name) ? stateMap.get(tok.name) : true);
3378
+ lastState = tok.name;
3379
+ continue;
3380
+ }
3381
+ if (tok.kind === "branch") {
3382
+ continue;
3383
+ }
3384
+ if (tok.kind === "arrow") {
3385
+ let nextIdx = i + 1;
3386
+ const targets = [];
3387
+ while (nextIdx < tokens.length) {
3388
+ const next = tokens[nextIdx];
3389
+ if (next.kind === "state") {
3390
+ targets.push(next.name);
3391
+ stateMap.set(next.name, stateMap.has(next.name) ? stateMap.get(next.name) : true);
3392
+ nextIdx++;
3393
+ if (nextIdx < tokens.length && tokens[nextIdx].kind === "branch") {
3394
+ nextIdx++;
3395
+ continue;
3396
+ }
3397
+ break;
3398
+ } else {
3399
+ nextIdx++;
3400
+ }
3401
+ }
3402
+ if (lastState && targets.length > 0) {
3403
+ for (const target of targets) {
3404
+ if (tok.direction === "forward" || tok.direction === "bidirectional") {
3405
+ const name = tok.name || `to_${target}`;
3406
+ transitions.push(makeTransition(name, lastState, target));
3407
+ outgoingCounts.set(lastState, (outgoingCounts.get(lastState) || 0) + 1);
3408
+ }
3409
+ if (tok.direction === "backward" || tok.direction === "bidirectional") {
3410
+ const name = tok.name || `to_${lastState}`;
3411
+ transitions.push(makeTransition(name, target, lastState));
3412
+ outgoingCounts.set(target, (outgoingCounts.get(target) || 0) + 1);
3413
+ }
3414
+ }
3415
+ lastState = targets[targets.length > 1 ? 0 : 0];
3416
+ if (targets.length === 1) {
3417
+ lastState = targets[0];
3418
+ }
3419
+ i = nextIdx - 1;
3420
+ }
3421
+ }
3422
+ }
3423
+ }
3424
+ function parseMultiLine(lines) {
3425
+ const allStateNames = [];
3426
+ const allTransitions = [];
3427
+ const stateMap = /* @__PURE__ */ new Map();
3428
+ const outgoingCounts = /* @__PURE__ */ new Map();
3429
+ for (const line of lines) {
3430
+ const trimmed = line.trim();
3431
+ if (!trimmed) continue;
3432
+ const tokens = tokenize(trimmed);
3433
+ const hasStates = tokens.some((t23) => t23.kind === "state");
3434
+ const hasForwardArrows = tokens.some(
3435
+ (t23) => t23.kind === "arrow" && (t23.direction === "forward" || t23.direction === "bidirectional")
3436
+ );
3437
+ if (hasStates && hasForwardArrows) {
3438
+ for (const tok of tokens) {
3439
+ if (tok.kind === "state" && !allStateNames.includes(tok.name)) {
3440
+ allStateNames.push(tok.name);
3441
+ }
3442
+ }
3443
+ parseTokens(tokens, stateMap, allTransitions, outgoingCounts);
3444
+ } else if (!hasStates && tokens.some((t23) => t23.kind === "arrow")) {
3445
+ let arrowIndex = 0;
3446
+ for (const tok of tokens) {
3447
+ if (tok.kind === "arrow") {
3448
+ if (arrowIndex < allStateNames.length - 1) {
3449
+ const left = allStateNames[arrowIndex];
3450
+ const right = allStateNames[arrowIndex + 1];
3451
+ if (tok.direction === "backward" || tok.direction === "bidirectional") {
3452
+ const name = tok.name || `to_${left}`;
3453
+ allTransitions.push(makeTransition(name, right, left));
3454
+ outgoingCounts.set(right, (outgoingCounts.get(right) || 0) + 1);
3455
+ }
3456
+ if (tok.direction === "forward" || tok.direction === "bidirectional") {
3457
+ const name = tok.name || `to_${right}`;
3458
+ allTransitions.push(makeTransition(name, left, right));
3459
+ outgoingCounts.set(left, (outgoingCounts.get(left) || 0) + 1);
3460
+ }
3461
+ }
3462
+ arrowIndex++;
3463
+ }
3464
+ }
3465
+ } else if (hasStates) {
3466
+ parseTokens(tokens, stateMap, allTransitions, outgoingCounts);
3467
+ for (const tok of tokens) {
3468
+ if (tok.kind === "state" && !allStateNames.includes(tok.name)) {
3469
+ allStateNames.push(tok.name);
3470
+ }
3471
+ }
3472
+ }
3473
+ }
3474
+ return { stateNames: allStateNames, transitions: dedupeTransitions(allTransitions) };
3475
+ }
3476
+ function parseArrowSyntax(arrow) {
3477
+ const lines = arrow.split("\n");
3478
+ const { stateNames, transitions } = parseMultiLine(lines);
3479
+ if (stateNames.length === 0) {
3480
+ return { states: [], transitions: [] };
3481
+ }
3482
+ const hasOutgoing = /* @__PURE__ */ new Set();
3483
+ for (const t23 of transitions) {
3484
+ for (const from of t23.from) {
3485
+ hasOutgoing.add(from);
3486
+ }
3487
+ }
3488
+ const states = stateNames.map((name, idx) => {
3489
+ let type = "REGULAR";
3490
+ if (idx === 0) {
3491
+ type = "START";
3492
+ } else if (!hasOutgoing.has(name)) {
3493
+ type = "END";
3494
+ }
3495
+ return makeState(name, type);
3496
+ });
3497
+ return { states, transitions };
3498
+ }
3499
+ function parseFieldRecord(fields) {
3500
+ return Object.entries(fields).map(([name, typeStr]) => {
3501
+ let required = false;
3502
+ let raw = typeStr.trim();
3503
+ if (raw.endsWith("!")) {
3504
+ required = true;
3505
+ raw = raw.slice(0, -1).trim();
3506
+ }
3507
+ let defaultValue;
3508
+ const eqIdx = raw.indexOf("=");
3509
+ let typePart = raw;
3510
+ if (eqIdx !== -1) {
3511
+ typePart = raw.slice(0, eqIdx).trim();
3512
+ const valStr = raw.slice(eqIdx + 1).trim();
3513
+ try {
3514
+ defaultValue = JSON.parse(valStr);
3515
+ } catch {
3516
+ defaultValue = valStr;
3517
+ }
3518
+ }
3519
+ const TYPE_MAP = {
3520
+ string: "text",
3521
+ str: "text",
3522
+ text: "text",
3523
+ number: "number",
3524
+ num: "number",
3525
+ int: "number",
3526
+ integer: "number",
3527
+ float: "number",
3528
+ bool: "boolean",
3529
+ boolean: "boolean",
3530
+ date: "date",
3531
+ datetime: "datetime",
3532
+ email: "email",
3533
+ url: "url",
3534
+ json: "json",
3535
+ object: "json",
3536
+ array: "json",
3537
+ select: "select",
3538
+ enum: "select",
3539
+ file: "file",
3540
+ image: "image",
3541
+ currency: "currency",
3542
+ phone: "phone",
3543
+ address: "address",
3544
+ rich_text: "rich_text",
3545
+ richtext: "rich_text",
3546
+ color: "color",
3547
+ rating: "rating"
3548
+ };
3549
+ const fieldType = TYPE_MAP[typePart.toLowerCase()] || typePart;
3550
+ const field = {
3551
+ name,
3552
+ type: fieldType
3553
+ };
3554
+ if (required) field.required = true;
3555
+ if (defaultValue !== void 0) field.default_value = defaultValue;
3556
+ return field;
3557
+ });
3558
+ }
3559
+ function parseWorkflowShorthand(slug, fieldsOrArrow, arrowString) {
3560
+ let fields = [];
3561
+ let arrow;
3562
+ if (typeof fieldsOrArrow === "string") {
3563
+ arrow = fieldsOrArrow;
3564
+ } else {
3565
+ fields = parseFieldRecord(fieldsOrArrow);
3566
+ arrow = arrowString || "";
3567
+ }
3568
+ const { states, transitions } = parseArrowSyntax(arrow);
3569
+ return { slug, fields, states, transitions };
3570
+ }
3571
+ var TOKEN_RE;
3572
+ var init_workflow_shorthand = __esm({
3573
+ "src/babel/extractors/workflow-shorthand.ts"() {
3574
+ "use strict";
3575
+ TOKEN_RE = /(<->)|<-(\w+)-|(<-)|(?:-(\w+)->)|(->)|(\|)|([a-zA-Z_]\w*)/g;
3576
+ }
3577
+ });
3578
+
3579
+ // src/babel/extractors/flow-extractor.ts
3580
+ function isImperativeWorkflowFile(path, _filename) {
3581
+ for (const node of path.node.body) {
3582
+ if (t12.isExportDefaultDeclaration(node)) {
3583
+ const decl = node.declaration;
3584
+ if (t12.isFunctionDeclaration(decl) && decl.async && decl.params.length > 0) {
3585
+ const param = decl.params[0];
3586
+ if (t12.isIdentifier(param) && param.typeAnnotation) {
3587
+ return true;
3588
+ }
3589
+ }
3590
+ if (t12.isCallExpression(decl) && t12.isIdentifier(decl.callee) && decl.callee.name === "workflow") {
3591
+ return true;
3592
+ }
3593
+ }
3594
+ }
3595
+ return false;
3596
+ }
3597
+ function roleCondition(role) {
3598
+ return { type: "role", field: role, operator: "eq", value: true };
3599
+ }
3600
+ function resolveType2(annotation) {
3601
+ if (t12.isTSStringKeyword(annotation)) return "text";
3602
+ if (t12.isTSNumberKeyword(annotation)) return "number";
3603
+ if (t12.isTSBooleanKeyword(annotation)) return "boolean";
3604
+ if (t12.isTSTypeReference(annotation) && t12.isIdentifier(annotation.typeName)) {
3605
+ const name = annotation.typeName.name;
3606
+ if (TS_TYPE_MAP[name]) return TS_TYPE_MAP[name];
3607
+ if (name === "Array") return "multi_select";
3608
+ return name.replace(/([A-Z])/g, "-$1").toLowerCase().replace(/^-/, "");
3609
+ }
3610
+ if (t12.isTSArrayType(annotation)) return "multi_select";
3611
+ if (t12.isTSUnionType(annotation)) {
3612
+ const allLiterals = annotation.types.every(
3613
+ (t23) => t12.isTSLiteralType(t23) && (t12.isStringLiteral(t23.literal) || t12.isNumericLiteral(t23.literal))
3614
+ );
3615
+ if (allLiterals) return "select";
3616
+ return "text";
3617
+ }
3618
+ if (t12.isTSLiteralType(annotation) && t12.isStringLiteral(annotation.literal)) return "text";
3619
+ if (t12.isTSLiteralType(annotation) && t12.isNumericLiteral(annotation.literal)) return "number";
3620
+ return "text";
3621
+ }
3622
+ function extractUnionOptions2(annotation) {
3623
+ if (!t12.isTSUnionType(annotation)) return void 0;
3624
+ const options = [];
3625
+ for (const member of annotation.types) {
3626
+ if (t12.isTSLiteralType(member) && t12.isStringLiteral(member.literal)) {
3627
+ options.push(member.literal.value);
3628
+ }
3629
+ }
3630
+ return options.length > 0 ? options : void 0;
3631
+ }
3632
+ function extractFieldsFromInterface2(declaration) {
3633
+ const fields = [];
3634
+ for (const member of declaration.body.body) {
3635
+ if (!t12.isTSPropertySignature(member)) continue;
3636
+ if (!t12.isIdentifier(member.key)) continue;
3637
+ const name = member.key.name;
3638
+ const required = !member.optional;
3639
+ const typeAnno = member.typeAnnotation;
3640
+ let fieldType = typeAnno ? resolveType2(typeAnno.typeAnnotation) : "text";
3641
+ if (NAME_TYPE_MAP[name]) fieldType = NAME_TYPE_MAP[name];
3642
+ const field = {
3643
+ name,
3644
+ type: fieldType,
3645
+ label: name.replace(/([A-Z])/g, " $1").replace(/^./, (c) => c.toUpperCase()),
3646
+ required,
3647
+ default_value: getDefaultForType(fieldType)
3648
+ };
3649
+ if (typeAnno) {
3650
+ const options = extractUnionOptions2(typeAnno.typeAnnotation);
3651
+ if (options) {
3652
+ field.validation = { options };
3653
+ }
3654
+ }
3655
+ fields.push(field);
3656
+ }
3657
+ return fields;
3658
+ }
3659
+ function getDefaultForType(type) {
3660
+ switch (type) {
3661
+ case "text":
3662
+ case "email":
3663
+ case "url":
3664
+ case "phone":
3665
+ case "select":
3666
+ return "";
3667
+ case "number":
3668
+ case "currency":
3669
+ return 0;
3670
+ case "boolean":
3671
+ return false;
3672
+ case "multi_select":
3673
+ return [];
3674
+ case "json":
3675
+ return {};
3676
+ default:
3677
+ return null;
3678
+ }
3679
+ }
3680
+ function extractNodeValue2(node) {
3681
+ if (t12.isStringLiteral(node)) return node.value;
3682
+ if (t12.isNumericLiteral(node)) return node.value;
3683
+ if (t12.isBooleanLiteral(node)) return node.value;
3684
+ if (t12.isNullLiteral(node)) return null;
3685
+ if (t12.isArrayExpression(node)) {
3686
+ return node.elements.map((el) => {
3687
+ if (!el || t12.isSpreadElement(el)) return null;
3688
+ return extractNodeValue2(el);
3689
+ });
3690
+ }
3691
+ if (t12.isObjectExpression(node)) {
3692
+ const obj = {};
3693
+ for (const prop of node.properties) {
3694
+ if (!t12.isObjectProperty(prop)) continue;
3695
+ const key = t12.isIdentifier(prop.key) ? prop.key.name : t12.isStringLiteral(prop.key) ? prop.key.value : null;
3696
+ if (key) obj[key] = extractNodeValue2(prop.value);
3697
+ }
3698
+ return obj;
3699
+ }
3700
+ if (t12.isTemplateLiteral(node)) {
3701
+ return node.quasis.map((q) => q.value.raw).join("${}");
3702
+ }
3703
+ if (t12.isIdentifier(node)) {
3704
+ if (node.name === "undefined") return void 0;
3705
+ return node.name;
3706
+ }
3707
+ if (t12.isMemberExpression(node)) {
3708
+ return memberExprToString(node);
3709
+ }
3710
+ if (t12.isTSAsExpression(node)) return extractNodeValue2(node.expression);
3711
+ if (t12.isArrowFunctionExpression(node) || t12.isFunctionExpression(node)) {
3712
+ return "[Function]";
3713
+ }
3714
+ return "[Expression]";
3715
+ }
3716
+ function memberExprToString(node) {
3717
+ const obj = t12.isIdentifier(node.object) ? node.object.name : t12.isMemberExpression(node.object) ? memberExprToString(node.object) : "[object]";
3718
+ const prop = t12.isIdentifier(node.property) ? node.property.name : t12.isStringLiteral(node.property) ? node.property.value : "[property]";
3719
+ return `${obj}.${prop}`;
3720
+ }
3721
+ function analyzeStateFn(fn, paramName, actionCounter) {
3722
+ const onEnter = [];
3723
+ const validations = [];
3724
+ const conditions = [];
3725
+ const roles = [];
3726
+ const requiredFields = [];
3727
+ const during = [];
3728
+ const onEvent = [];
3729
+ let timeout;
3730
+ let runtime;
3731
+ if (!fn.body || !t12.isBlockStatement(fn.body)) {
3732
+ return { onEnter, validations, conditions, roles, requiredFields, during, onEvent, timeout, runtime };
3733
+ }
3734
+ for (const stmt of fn.body.body) {
3735
+ processStatement(stmt, paramName, actionCounter, {
3736
+ onEnter,
3737
+ validations,
3738
+ conditions,
3739
+ roles,
3740
+ requiredFields,
3741
+ during,
3742
+ onEvent,
3743
+ setTimeout: (t23) => {
3744
+ timeout = t23;
3745
+ },
3746
+ setRuntime: (r) => {
3747
+ runtime = r;
3748
+ }
3749
+ });
3750
+ }
3751
+ return { onEnter, validations, conditions, roles, requiredFields, during, onEvent, timeout, runtime };
3752
+ }
3753
+ function processStatement(stmt, paramName, actionCounter, ctx) {
3754
+ if (t12.isExpressionStatement(stmt)) {
3755
+ processExpression(stmt.expression, paramName, actionCounter, ctx);
3756
+ return;
3757
+ }
3758
+ if (t12.isIfStatement(stmt)) {
3759
+ const testStr = expressionToIR(stmt.test, paramName);
3760
+ if (t12.isBlockStatement(stmt.consequent)) {
3761
+ for (const inner of stmt.consequent.body) {
3762
+ processStatement(inner, paramName, actionCounter, {
3763
+ ...ctx,
3764
+ ifCondition: testStr
3765
+ });
3766
+ }
3767
+ }
3768
+ return;
3769
+ }
3770
+ if (t12.isVariableDeclaration(stmt)) {
3771
+ for (const decl of stmt.declarations) {
3772
+ if (decl.init && t12.isAwaitExpression(decl.init)) {
3773
+ processExpression(decl.init, paramName, actionCounter, ctx);
3774
+ }
3775
+ }
3776
+ }
3777
+ }
3778
+ function processExpression(expr, paramName, actionCounter, ctx) {
3779
+ if (t12.isAssignmentExpression(expr) && t12.isMemberExpression(expr.left)) {
3780
+ const left = memberExprToString(expr.left);
3781
+ if (left.startsWith(`${paramName}.`)) {
3782
+ const field = left.slice(paramName.length + 1);
3783
+ const valueExpr = expressionToIR(expr.right, paramName);
3784
+ const action = {
3785
+ id: `auto_${++actionCounter.value}`,
3786
+ type: "set_field",
3787
+ mode: "auto",
3788
+ config: { field, expression: valueExpr },
3789
+ ...ctx.ifCondition ? { condition: ctx.ifCondition } : {}
3790
+ };
3791
+ ctx.onEnter.push(action);
3792
+ return;
3793
+ }
3794
+ }
3795
+ if (t12.isAssignmentExpression(expr) && expr.operator !== "=" && t12.isMemberExpression(expr.left)) {
3796
+ const left = memberExprToString(expr.left);
3797
+ if (left.startsWith(`${paramName}.`)) {
3798
+ const field = left.slice(paramName.length + 1);
3799
+ const op = expr.operator.replace("=", "");
3800
+ const valueExpr = expressionToIR(expr.right, paramName);
3801
+ const action = {
3802
+ id: `auto_${++actionCounter.value}`,
3803
+ type: "set_field",
3804
+ mode: "auto",
3805
+ config: { field, expression: `state_data.${field} ${op} ${valueExpr}` },
3806
+ ...ctx.ifCondition ? { condition: ctx.ifCondition } : {}
3807
+ };
3808
+ ctx.onEnter.push(action);
3809
+ return;
3810
+ }
3811
+ }
3812
+ if (t12.isCallExpression(expr) || t12.isAwaitExpression(expr) && t12.isCallExpression(expr.argument)) {
3813
+ const call = t12.isAwaitExpression(expr) ? expr.argument : expr;
3814
+ const fnName = t12.isIdentifier(call.callee) ? call.callee.name : t12.isMemberExpression(call.callee) && t12.isIdentifier(call.callee.property) ? call.callee.property.name : null;
3815
+ if (!fnName) return;
3816
+ if (VALIDATION_FNS.has(fnName)) {
3817
+ extractValidation(call, paramName, ctx);
3818
+ return;
3819
+ }
3820
+ if (fnName === "log") {
3821
+ const event = call.arguments[0] ? extractNodeValue2(call.arguments[0]) : "";
3822
+ const data = call.arguments[1] ? extractNodeValue2(call.arguments[1]) : void 0;
3823
+ ctx.onEnter.push({
3824
+ id: `auto_${++actionCounter.value}`,
3825
+ type: "log_event",
3826
+ mode: "auto",
3827
+ config: { event: String(event), ...data ? { data } : {} },
3828
+ ...ctx.ifCondition ? { condition: ctx.ifCondition } : {}
3829
+ });
3830
+ return;
3831
+ }
3832
+ if (fnName === "notify") {
3833
+ const to = call.arguments[0] ? expressionToIR(call.arguments[0], paramName) : "";
3834
+ const message = call.arguments[1] ? extractNodeValue2(call.arguments[1]) : "";
3835
+ const opts = call.arguments[2] ? extractNodeValue2(call.arguments[2]) : {};
3836
+ ctx.onEnter.push({
3837
+ id: `auto_${++actionCounter.value}`,
3838
+ type: "send_notification",
3839
+ mode: "auto",
3840
+ config: {
3841
+ to: String(to),
3842
+ message: String(message),
3843
+ ...opts
3844
+ },
3845
+ ...ctx.ifCondition ? { condition: ctx.ifCondition } : {}
3846
+ });
3847
+ return;
3848
+ }
3849
+ if (fnName === "emit") {
3850
+ const event = call.arguments[0] ? extractNodeValue2(call.arguments[0]) : "";
3851
+ const payload = call.arguments[1] ? extractNodeValue2(call.arguments[1]) : void 0;
3852
+ ctx.onEnter.push({
3853
+ id: `auto_${++actionCounter.value}`,
3854
+ type: "emit_event",
3855
+ mode: "auto",
3856
+ config: { event: String(event), ...payload ? { payload } : {} },
3857
+ ...ctx.ifCondition ? { condition: ctx.ifCondition } : {}
3858
+ });
3859
+ return;
3860
+ }
3861
+ if (fnName === "requireRole") {
3862
+ for (const arg of call.arguments) {
3863
+ if (t12.isStringLiteral(arg)) ctx.roles.push(arg.value);
3864
+ }
3865
+ return;
3866
+ }
3867
+ if (fnName === "requireField") {
3868
+ for (const arg of call.arguments) {
3869
+ if (t12.isStringLiteral(arg)) ctx.requiredFields.push(arg.value);
3870
+ }
3871
+ return;
3872
+ }
3873
+ if (fnName === "runtime") {
3874
+ if (call.arguments[0] && t12.isStringLiteral(call.arguments[0])) {
3875
+ ctx.setRuntime(call.arguments[0].value);
3876
+ }
3877
+ return;
3878
+ }
3879
+ if (fnName === "guard") {
3880
+ if (call.arguments[0] && t12.isStringLiteral(call.arguments[0])) {
3881
+ ctx.conditions.push({ expression: call.arguments[0].value });
3882
+ }
3883
+ return;
3884
+ }
3885
+ if (fnName === "every") {
3886
+ const interval = call.arguments[0] && t12.isStringLiteral(call.arguments[0]) ? call.arguments[0].value : "1h";
3887
+ const intervalMs = parseDuration(interval);
3888
+ const opts = call.arguments[1] ? extractNodeValue2(call.arguments[1]) : {};
3889
+ const duringAction = {
3890
+ id: `during_${++actionCounter.value}`,
3891
+ type: "interval",
3892
+ interval_ms: intervalMs,
3893
+ ...typeof opts === "object" && opts !== null && opts.when ? { condition: opts.when } : {},
3894
+ actions: []
3895
+ // Placeholder — body analysis would extract inner actions
3896
+ };
3897
+ ctx.during.push(duringAction);
3898
+ return;
3899
+ }
3900
+ if (fnName === "cron") {
3901
+ const cronExpr = call.arguments[0] && t12.isStringLiteral(call.arguments[0]) ? call.arguments[0].value : "* * * * *";
3902
+ ctx.during.push({
3903
+ id: `during_${++actionCounter.value}`,
3904
+ type: "cron",
3905
+ cron: cronExpr,
3906
+ actions: []
3907
+ });
3908
+ return;
3909
+ }
3910
+ if (fnName === "after") {
3911
+ const delay = call.arguments[0] && t12.isStringLiteral(call.arguments[0]) ? call.arguments[0].value : "1h";
3912
+ ctx.during.push({
3913
+ id: `during_${++actionCounter.value}`,
3914
+ type: "timeout",
3915
+ delay_ms: parseDuration(delay),
3916
+ actions: []
3917
+ });
3918
+ return;
3919
+ }
3920
+ if (fnName === "on" && !t12.isAwaitExpression(expr)) {
3921
+ const pattern = call.arguments[0] && t12.isStringLiteral(call.arguments[0]) ? call.arguments[0].value : "*";
3922
+ const opts = call.arguments[1] ? extractNodeValue2(call.arguments[1]) : {};
3923
+ const optsObj = typeof opts === "object" && opts !== null ? opts : {};
3924
+ ctx.onEvent.push({
3925
+ match: pattern,
3926
+ ...optsObj.when ? { conditions: [String(optsObj.when)] } : {},
3927
+ actions: []
3928
+ });
3929
+ return;
3930
+ }
3931
+ if (fnName === "timeout") {
3932
+ const duration = call.arguments[0] && t12.isStringLiteral(call.arguments[0]) ? call.arguments[0].value : "1h";
3933
+ const opts = call.arguments[1] ? extractNodeValue2(call.arguments[1]) : {};
3934
+ const optsObj = typeof opts === "object" && opts !== null ? opts : {};
3935
+ ctx.setTimeout({
3936
+ duration,
3937
+ fallback: {
3938
+ ...optsObj.transition ? { transition: String(optsObj.transition) } : {},
3939
+ ...optsObj.action ? { action: String(optsObj.action) } : {}
3940
+ }
3941
+ });
3942
+ return;
3943
+ }
3944
+ if (fnName === "restrict") {
3945
+ return;
3946
+ }
3947
+ }
3948
+ }
3949
+ function extractValidation(call, paramName, ctx) {
3950
+ const condArg = call.arguments[0];
3951
+ const msgArg = call.arguments[1];
3952
+ const sevArg = call.arguments[2];
3953
+ const message = msgArg && t12.isStringLiteral(msgArg) ? msgArg.value : "Validation failed";
3954
+ const severity = sevArg && t12.isStringLiteral(sevArg) && sevArg.value === "warning" ? "warning" : "error";
3955
+ if (!condArg) return;
3956
+ const field = extractFieldFromCondition(condArg, paramName);
3957
+ const exprStr = expressionToIR(condArg, paramName);
3958
+ if (field) {
3959
+ const validation = {};
3960
+ if (t12.isBinaryExpression(condArg) && (condArg.operator === ">" || condArg.operator === ">=")) {
3961
+ if (isLengthAccess(condArg.left, paramName, field) && t12.isNumericLiteral(condArg.right)) {
3962
+ validation.minLength = condArg.right.value + (condArg.operator === ">" ? 1 : 0);
3963
+ } else if (isFieldAccess(condArg.left, paramName, field) && t12.isNumericLiteral(condArg.right)) {
3964
+ validation.min = condArg.right.value + (condArg.operator === ">" ? 1e-3 : 0);
3965
+ }
3966
+ }
3967
+ if (t12.isBinaryExpression(condArg) && (condArg.operator === "<" || condArg.operator === "<=")) {
3968
+ if (isFieldAccess(condArg.left, paramName, field) && t12.isNumericLiteral(condArg.right)) {
3969
+ validation.max = condArg.right.value;
3970
+ }
3971
+ }
3972
+ if (t12.isCallExpression(condArg) && t12.isMemberExpression(condArg.callee) && t12.isRegExpLiteral(condArg.callee.object) && t12.isIdentifier(condArg.callee.property) && condArg.callee.property.name === "test") {
3973
+ if (!validation.rules) validation.rules = [];
3974
+ validation.rules.push({
3975
+ expression: `MATCHES(value, "${condArg.callee.object.pattern}")`,
3976
+ message: "",
3977
+ // Will be set from the validate() message arg
3978
+ severity: "error"
3979
+ });
3980
+ }
3981
+ ctx.validations.push({ field, validation, message, severity });
3982
+ } else {
3983
+ ctx.validations.push({
3984
+ field: "__cross__",
3985
+ validation: { rules: [{ expression: exprStr, message, severity }] },
3986
+ message,
3987
+ severity
3988
+ });
3989
+ }
3990
+ }
3991
+ function extractFieldFromCondition(node, paramName) {
3992
+ if (t12.isMemberExpression(node)) {
3993
+ const str = memberExprToString(node);
3994
+ if (str.startsWith(`${paramName}.`)) {
3995
+ const parts = str.slice(paramName.length + 1).split(".");
3996
+ return parts[0];
3997
+ }
3998
+ }
3999
+ if (t12.isBinaryExpression(node)) {
4000
+ return extractFieldFromCondition(node.left, paramName) || extractFieldFromCondition(node.right, paramName);
4001
+ }
4002
+ if (t12.isCallExpression(node) && t12.isMemberExpression(node.callee)) {
4003
+ return extractFieldFromCondition(node.callee.object, paramName);
4004
+ }
4005
+ if (t12.isCallExpression(node) && t12.isMemberExpression(node.callee) && t12.isRegExpLiteral(node.callee.object) && node.arguments[0]) {
4006
+ return extractFieldFromCondition(node.arguments[0], paramName);
4007
+ }
4008
+ if (t12.isLogicalExpression(node)) {
4009
+ return extractFieldFromCondition(node.left, paramName) || extractFieldFromCondition(node.right, paramName);
4010
+ }
4011
+ if (t12.isUnaryExpression(node)) {
4012
+ return extractFieldFromCondition(node.argument, paramName);
4013
+ }
4014
+ return null;
4015
+ }
4016
+ function isLengthAccess(node, paramName, field) {
4017
+ if (!t12.isMemberExpression(node)) return false;
4018
+ const str = memberExprToString(node);
4019
+ return str === `${paramName}.${field}.length`;
4020
+ }
4021
+ function isFieldAccess(node, paramName, field) {
4022
+ if (!t12.isMemberExpression(node)) return false;
4023
+ const str = memberExprToString(node);
4024
+ return str === `${paramName}.${field}`;
4025
+ }
4026
+ function expressionToIR(node, paramName) {
4027
+ if (t12.isStringLiteral(node)) return `"${node.value}"`;
4028
+ if (t12.isNumericLiteral(node)) return String(node.value);
4029
+ if (t12.isBooleanLiteral(node)) return String(node.value);
4030
+ if (t12.isNullLiteral(node)) return "null";
4031
+ if (t12.isIdentifier(node)) {
4032
+ if (node.name === paramName) return "state_data";
4033
+ if (node.name === "actor") return "context";
4034
+ if (node.name === "instance") return "instance";
4035
+ return node.name;
4036
+ }
4037
+ if (t12.isMemberExpression(node)) {
4038
+ const str = memberExprToString(node);
4039
+ if (str.startsWith(`${paramName}.`)) return "state_data." + str.slice(paramName.length + 1);
4040
+ if (str.startsWith("actor.")) return "context." + str.slice(6);
4041
+ if (str.startsWith("Date.")) {
4042
+ if (str === "Date.now") return "NOW()";
4043
+ }
4044
+ return str;
4045
+ }
4046
+ if (t12.isCallExpression(node)) {
4047
+ if (t12.isMemberExpression(node.callee) && t12.isIdentifier(node.callee.property)) {
4048
+ const obj = expressionToIR(node.callee.object, paramName);
4049
+ const method = node.callee.property.name;
4050
+ if (method === "now" && obj === "Date") return "NOW()";
4051
+ if (method === "includes") {
4052
+ const arg = node.arguments[0] ? expressionToIR(node.arguments[0], paramName) : "";
4053
+ return `CONTAINS(${obj}, ${arg})`;
4054
+ }
4055
+ if (method === "length") return `LEN(${obj})`;
4056
+ }
4057
+ if (t12.isIdentifier(node.callee) && node.callee.name === "Date") {
4058
+ if (t12.isMemberExpression(node) && t12.isIdentifier(node.property) && node.property.name === "now") {
4059
+ return "NOW()";
4060
+ }
4061
+ }
4062
+ return "[call]";
4063
+ }
4064
+ if (t12.isBinaryExpression(node)) {
4065
+ const left = expressionToIR(node.left, paramName);
4066
+ const right = expressionToIR(node.right, paramName);
4067
+ return `${left} ${node.operator} ${right}`;
4068
+ }
4069
+ if (t12.isLogicalExpression(node)) {
4070
+ const left = expressionToIR(node.left, paramName);
4071
+ const right = expressionToIR(node.right, paramName);
4072
+ const op = node.operator === "&&" ? "AND" : node.operator === "||" ? "OR" : node.operator;
4073
+ return `${left} ${op} ${right}`;
4074
+ }
4075
+ if (t12.isUnaryExpression(node)) {
4076
+ if (node.operator === "!") return `NOT(${expressionToIR(node.argument, paramName)})`;
4077
+ return `${node.operator}${expressionToIR(node.argument, paramName)}`;
4078
+ }
4079
+ if (t12.isConditionalExpression(node)) {
4080
+ return `IF(${expressionToIR(node.test, paramName)}, ${expressionToIR(node.consequent, paramName)}, ${expressionToIR(node.alternate, paramName)})`;
4081
+ }
4082
+ if (t12.isTemplateLiteral(node)) {
4083
+ const parts = [];
4084
+ for (let i = 0; i < node.quasis.length; i++) {
4085
+ parts.push(node.quasis[i].value.raw);
4086
+ if (i < node.expressions.length) {
4087
+ parts.push(`{{ ${expressionToIR(node.expressions[i], paramName)} }}`);
4088
+ }
4089
+ }
4090
+ return `"${parts.join("")}"`;
4091
+ }
4092
+ if (t12.isRegExpLiteral(node)) return node.pattern;
4093
+ return "[expr]";
4094
+ }
4095
+ function extractCallSequence(body, paramName, localFnNames, importedFns) {
4096
+ const calls = [];
4097
+ for (const stmt of body.body) {
4098
+ extractCallsFromStatement(stmt, paramName, localFnNames, importedFns, calls);
4099
+ }
4100
+ return calls;
4101
+ }
4102
+ function extractCallsFromStatement(stmt, paramName, localFnNames, importedFns, calls, condition) {
4103
+ if (t12.isExpressionStatement(stmt)) {
4104
+ const expr = stmt.expression;
4105
+ if (t12.isAwaitExpression(expr)) {
4106
+ const call = extractWorkflowCall(expr.argument, paramName, localFnNames, importedFns);
4107
+ if (call) {
4108
+ if (condition) call.condition = condition;
4109
+ calls.push(call);
4110
+ }
4111
+ }
4112
+ if (t12.isCallExpression(expr) && t12.isIdentifier(expr.callee) && expr.callee.name === "allowTransition") {
4113
+ }
4114
+ }
4115
+ if (t12.isVariableDeclaration(stmt)) {
4116
+ for (const decl of stmt.declarations) {
4117
+ if (decl.init && t12.isAwaitExpression(decl.init)) {
4118
+ const call = extractWorkflowCall(decl.init.argument, paramName, localFnNames, importedFns);
4119
+ if (call) {
4120
+ if (condition) call.condition = condition;
4121
+ calls.push(call);
4122
+ }
4123
+ }
4124
+ }
4125
+ }
4126
+ if (t12.isIfStatement(stmt)) {
4127
+ const condStr = expressionToIR(stmt.test, paramName);
4128
+ if (t12.isBlockStatement(stmt.consequent)) {
4129
+ for (const inner of stmt.consequent.body) {
4130
+ extractCallsFromStatement(inner, paramName, localFnNames, importedFns, calls, condStr);
4131
+ }
4132
+ }
4133
+ if (stmt.alternate) {
4134
+ const negCond = `NOT(${condStr})`;
4135
+ if (t12.isBlockStatement(stmt.alternate)) {
4136
+ for (const inner of stmt.alternate.body) {
4137
+ extractCallsFromStatement(inner, paramName, localFnNames, importedFns, calls, negCond);
4138
+ }
4139
+ } else if (t12.isIfStatement(stmt.alternate)) {
4140
+ extractCallsFromStatement(stmt.alternate, paramName, localFnNames, importedFns, calls);
4141
+ }
4142
+ }
4143
+ }
4144
+ if (t12.isTryStatement(stmt)) {
4145
+ const tryBlockCalls = [];
4146
+ if (stmt.block) {
4147
+ for (const inner of stmt.block.body) {
4148
+ extractCallsFromStatement(inner, paramName, localFnNames, importedFns, tryBlockCalls, condition);
4149
+ }
4150
+ }
4151
+ calls.push(...tryBlockCalls);
4152
+ if (stmt.handler && stmt.handler.body) {
4153
+ const catchBody = stmt.handler.body;
4154
+ const compensationActions = [];
4155
+ const catchParamName = stmt.handler.param && t12.isIdentifier(stmt.handler.param) ? stmt.handler.param.name : "error";
4156
+ const hasReturn = catchBody.body.some((s) => t12.isReturnStatement(s));
4157
+ for (const inner of catchBody.body) {
4158
+ if (t12.isReturnStatement(inner)) continue;
4159
+ extractCallsFromStatement(inner, paramName, localFnNames, importedFns, compensationActions, condition);
4160
+ }
4161
+ calls.push({
4162
+ type: "stateCall",
4163
+ name: `__compensation_${calls.length}`,
4164
+ options: {
4165
+ __isCompensation: true,
4166
+ __tryBlockCallNames: tryBlockCalls.map((c) => c.name),
4167
+ __compensationCalls: compensationActions,
4168
+ __hasReturn: hasReturn,
4169
+ __catchParam: catchParamName,
4170
+ __catchBody: catchBody
4171
+ }
4172
+ });
4173
+ }
4174
+ }
4175
+ if (t12.isSwitchStatement(stmt)) {
4176
+ }
4177
+ }
4178
+ function extractWorkflowCall(node, paramName, localFnNames, importedFns) {
4179
+ if (t12.isCallExpression(node)) {
4180
+ const callee = node.callee;
4181
+ if (t12.isIdentifier(callee) && callee.name === "named" && node.arguments.length >= 2) {
4182
+ const name = t12.isStringLiteral(node.arguments[0]) ? node.arguments[0].value : "";
4183
+ const inner = node.arguments[1];
4184
+ if (t12.isCallExpression(inner) || t12.isAwaitExpression(inner)) {
4185
+ const innerNode = t12.isAwaitExpression(inner) ? inner.argument : inner;
4186
+ const innerCall = extractWorkflowCall(innerNode, paramName, localFnNames, importedFns);
4187
+ if (innerCall) {
4188
+ innerCall.transitionName = name;
4189
+ return innerCall;
4190
+ }
4191
+ }
4192
+ return null;
4193
+ }
4194
+ if (t12.isIdentifier(callee) && callee.name === "userAction") {
4195
+ const name = node.arguments[0] && t12.isStringLiteral(node.arguments[0]) ? node.arguments[0].value : "action";
4196
+ const opts = node.arguments[1] ? extractNodeValue2(node.arguments[1]) : {};
4197
+ return { type: "userAction", name, options: opts };
4198
+ }
4199
+ if (t12.isIdentifier(callee) && callee.name === "userChoice") {
4200
+ const choices = node.arguments[0] ? extractNodeValue2(node.arguments[0]) : {};
4201
+ return { type: "userChoice", name: "choice", choices };
4202
+ }
4203
+ if (t12.isIdentifier(callee) && callee.name === "delay") {
4204
+ const duration = node.arguments[0] && t12.isStringLiteral(node.arguments[0]) ? node.arguments[0].value : "0";
4205
+ return { type: "delay", name: `delay_${duration}` };
4206
+ }
4207
+ if (t12.isIdentifier(callee) && callee.name === "on") {
4208
+ const pattern = node.arguments[0] && t12.isStringLiteral(node.arguments[0]) ? node.arguments[0].value : "*";
4209
+ const opts = node.arguments[1] ? extractNodeValue2(node.arguments[1]) : {};
4210
+ opts.__eventPattern = pattern;
4211
+ return { type: "awaitOn", name: pattern.replace(/[^a-zA-Z0-9]/g, "_"), options: opts };
4212
+ }
4213
+ if (t12.isMemberExpression(callee) && t12.isIdentifier(callee.object) && callee.object.name === "Promise" && t12.isIdentifier(callee.property)) {
4214
+ if (callee.property.name === "all" && node.arguments[0] && t12.isArrayExpression(node.arguments[0])) {
4215
+ const parallelCalls = [];
4216
+ for (const el of node.arguments[0].elements) {
4217
+ if (!el || t12.isSpreadElement(el)) continue;
4218
+ const innerNode = t12.isAwaitExpression(el) ? el.argument : el;
4219
+ const c = extractWorkflowCall(innerNode, paramName, localFnNames, importedFns);
4220
+ if (c) parallelCalls.push(c);
4221
+ }
4222
+ return { type: "promiseAll", name: "parallel", parallelCalls };
4223
+ }
4224
+ if (callee.property.name === "race" && node.arguments[0] && t12.isArrayExpression(node.arguments[0])) {
4225
+ const parallelCalls = [];
4226
+ for (const el of node.arguments[0].elements) {
4227
+ if (!el || t12.isSpreadElement(el)) continue;
4228
+ const innerNode = t12.isAwaitExpression(el) ? el.argument : el;
4229
+ const c = extractWorkflowCall(innerNode, paramName, localFnNames, importedFns);
4230
+ if (c) parallelCalls.push(c);
4231
+ }
4232
+ return { type: "promiseRace", name: "race", parallelCalls };
4233
+ }
4234
+ }
4235
+ if (t12.isIdentifier(callee) && localFnNames.has(callee.name)) {
4236
+ return { type: "stateCall", name: callee.name };
4237
+ }
4238
+ if (t12.isIdentifier(callee) && importedFns.has(callee.name)) {
4239
+ return {
4240
+ type: "serviceCall",
4241
+ name: callee.name,
4242
+ importSource: importedFns.get(callee.name)
4243
+ };
4244
+ }
4245
+ }
4246
+ return null;
4247
+ }
4248
+ function extractAllowTransitions(body) {
4249
+ const result = [];
4250
+ for (const stmt of body.body) {
4251
+ if (!t12.isExpressionStatement(stmt)) continue;
4252
+ const expr = stmt.expression;
4253
+ if (!t12.isCallExpression(expr)) continue;
4254
+ if (!t12.isIdentifier(expr.callee) || expr.callee.name !== "allowTransition") continue;
4255
+ const nameArg = expr.arguments[0];
4256
+ const optsArg = expr.arguments[1];
4257
+ if (!t12.isStringLiteral(nameArg)) continue;
4258
+ const name = nameArg.value;
4259
+ const opts = optsArg && t12.isObjectExpression(optsArg) ? extractNodeValue2(optsArg) : {};
4260
+ let from = [];
4261
+ if (typeof opts.from === "string") from = [opts.from];
4262
+ else if (Array.isArray(opts.from)) from = opts.from.map(String);
4263
+ result.push({
4264
+ name,
4265
+ from,
4266
+ to: String(opts.to || ""),
4267
+ ...opts.roles ? { roles: opts.roles } : {},
4268
+ ...opts.require ? { require: opts.require } : {},
4269
+ ...opts.when ? { when: String(opts.when) } : {}
4270
+ });
4271
+ }
4272
+ return result;
4273
+ }
4274
+ function parseDuration(str) {
4275
+ const match = str.match(/^(\d+(?:\.\d+)?)\s*(ms|s|m|h|d|w)$/);
4276
+ if (!match) return 0;
4277
+ const value = parseFloat(match[1]);
4278
+ switch (match[2]) {
4279
+ case "ms":
4280
+ return value;
4281
+ case "s":
4282
+ return value * 1e3;
4283
+ case "m":
4284
+ return value * 6e4;
4285
+ case "h":
4286
+ return value * 36e5;
4287
+ case "d":
4288
+ return value * 864e5;
4289
+ case "w":
4290
+ return value * 6048e5;
4291
+ default:
4292
+ return 0;
4293
+ }
4294
+ }
4295
+ function toSnakeCase2(name) {
4296
+ return name.replace(/([A-Z])/g, "_$1").toLowerCase().replace(/^_/, "");
4297
+ }
4298
+ function fnNameToSlug(name) {
4299
+ return name.replace(/([A-Z])/g, "-$1").toLowerCase().replace(/^-/, "");
4300
+ }
4301
+ function extractStateDataRefs(expression) {
4302
+ const refs = [];
4303
+ const regex = /state_data\.(\w+)/g;
4304
+ let match;
4305
+ while ((match = regex.exec(expression)) !== null) {
4306
+ refs.push(match[1]);
4307
+ }
4308
+ return [...new Set(refs)];
4309
+ }
4310
+ function detectComputedFieldsFromActions(compilerState, stateFnInfos) {
4311
+ for (const [, info] of stateFnInfos) {
4312
+ for (const action of info.onEnter) {
4313
+ if (action.type !== "set_field") continue;
4314
+ const config = action.config;
4315
+ if (!config?.field || !config?.expression) continue;
4316
+ const targetField = config.field;
4317
+ const expression = config.expression;
4318
+ const refs = extractStateDataRefs(expression);
4319
+ const deps = refs.filter((r) => r !== targetField);
4320
+ if (deps.length === 0) continue;
4321
+ const field = compilerState.fields.find((f) => f.name === targetField);
4322
+ if (field) {
4323
+ field.computed = expression;
4324
+ field.computed_deps = deps;
4325
+ }
4326
+ }
4327
+ }
4328
+ }
4329
+ function detectComputedFieldGetters(path, paramName, paramTypeName, compilerState) {
4330
+ for (const node of path.node.body) {
4331
+ if (!t12.isFunctionDeclaration(node)) continue;
4332
+ if (node.async) continue;
4333
+ if (!node.id) continue;
4334
+ if (node.params.length !== 1) continue;
4335
+ const fnParam = node.params[0];
4336
+ if (!t12.isIdentifier(fnParam)) continue;
4337
+ if (fnParam.typeAnnotation && t12.isTSTypeAnnotation(fnParam.typeAnnotation)) {
4338
+ const typeAnno = fnParam.typeAnnotation.typeAnnotation;
4339
+ if (t12.isTSTypeReference(typeAnno) && t12.isIdentifier(typeAnno.typeName)) {
4340
+ if (typeAnno.typeName.name !== paramTypeName) continue;
4341
+ } else {
4342
+ continue;
4343
+ }
4344
+ } else {
4345
+ continue;
4346
+ }
4347
+ const hasReturnType = node.returnType && t12.isTSTypeAnnotation(node.returnType);
4348
+ if (!node.body || !t12.isBlockStatement(node.body)) continue;
4349
+ const returnStmt = node.body.body.find(
4350
+ (s) => t12.isReturnStatement(s)
4351
+ );
4352
+ if (!returnStmt?.argument) continue;
4353
+ const getterParamName = fnParam.name;
4354
+ const expression = expressionToIR(returnStmt.argument, getterParamName);
4355
+ const deps = extractStateDataRefs(expression);
4356
+ if (deps.length === 0) continue;
4357
+ const fieldName = node.id.name;
4358
+ let field = compilerState.fields.find((f) => f.name === fieldName);
4359
+ if (field) {
4360
+ field.computed = expression;
4361
+ field.computed_deps = deps;
4362
+ } else {
4363
+ let fieldType = "text";
4364
+ if (hasReturnType) {
4365
+ const retType = node.returnType.typeAnnotation;
4366
+ fieldType = resolveType2(retType);
4367
+ }
4368
+ compilerState.fields.push({
4369
+ name: fieldName,
4370
+ type: fieldType,
4371
+ label: fieldName.replace(/([A-Z])/g, " $1").replace(/^./, (c) => c.toUpperCase()),
4372
+ required: false,
4373
+ computed: expression,
4374
+ computed_deps: deps
4375
+ });
4376
+ }
4377
+ }
4378
+ }
4379
+ function extractImperativeWorkflow(path, state) {
4380
+ const compilerState = state;
4381
+ if (!compilerState.actionCounter) compilerState.actionCounter = 0;
4382
+ const actionCounter = { value: compilerState.actionCounter };
4383
+ const importedFns = /* @__PURE__ */ new Map();
4384
+ const stdLibImports = /* @__PURE__ */ new Set();
4385
+ for (const node of path.node.body) {
4386
+ if (t12.isImportDeclaration(node)) {
4387
+ const source = node.source.value;
4388
+ for (const spec of node.specifiers) {
4389
+ const localName = spec.local.name;
4390
+ if (source.includes("@mmapp/react") || source.includes("@mindmatrix/react")) {
4391
+ stdLibImports.add(localName);
4392
+ } else {
4393
+ importedFns.set(localName, source);
4394
+ }
4395
+ }
4396
+ }
4397
+ }
4398
+ for (const node of path.node.body) {
4399
+ if (t12.isExportDefaultDeclaration(node) && t12.isCallExpression(node.declaration)) {
4400
+ const call = node.declaration;
4401
+ if (t12.isIdentifier(call.callee) && call.callee.name === "workflow") {
4402
+ const slugArg = call.arguments[0] && t12.isStringLiteral(call.arguments[0]) ? call.arguments[0].value : "workflow";
4403
+ let fieldsOrArrow = "";
4404
+ let arrowString;
4405
+ if (call.arguments.length === 2) {
4406
+ const arg1 = call.arguments[1];
4407
+ if (t12.isStringLiteral(arg1)) {
4408
+ fieldsOrArrow = arg1.value;
4409
+ } else if (t12.isTemplateLiteral(arg1)) {
4410
+ fieldsOrArrow = arg1.quasis.map((q) => q.value.raw).join("");
4411
+ } else if (t12.isObjectExpression(arg1)) {
4412
+ fieldsOrArrow = extractNodeValue2(arg1);
4413
+ }
4414
+ } else if (call.arguments.length >= 3) {
4415
+ const arg1 = call.arguments[1];
4416
+ const arg2 = call.arguments[2];
4417
+ if (t12.isObjectExpression(arg1)) {
4418
+ fieldsOrArrow = extractNodeValue2(arg1);
4419
+ }
4420
+ if (t12.isStringLiteral(arg2)) {
4421
+ arrowString = arg2.value;
4422
+ } else if (t12.isTemplateLiteral(arg2)) {
4423
+ arrowString = arg2.quasis.map((q) => q.value.raw).join("");
4424
+ }
4425
+ }
4426
+ const result = parseWorkflowShorthand(slugArg, fieldsOrArrow, arrowString);
4427
+ compilerState.metadata.slug = result.slug;
4428
+ compilerState.metadata.category = "workflow";
4429
+ compilerState.fields.push(...result.fields);
4430
+ for (const s of result.states) {
4431
+ compilerState.states.set(s.name, s);
4432
+ }
4433
+ compilerState.transitions.push(...result.transitions);
4434
+ compilerState.actionCounter = actionCounter.value;
4435
+ return;
4436
+ }
4437
+ }
4438
+ }
4439
+ let parentFn = null;
4440
+ let parentName = "";
4441
+ let paramName = "";
4442
+ let paramTypeName = "";
4443
+ for (const node of path.node.body) {
4444
+ if (t12.isExportDefaultDeclaration(node) && t12.isFunctionDeclaration(node.declaration)) {
4445
+ const fn = node.declaration;
4446
+ if (fn.async && fn.params.length > 0) {
4447
+ parentFn = fn;
4448
+ parentName = fn.id?.name || "workflow";
4449
+ const param = fn.params[0];
4450
+ if (t12.isIdentifier(param)) {
4451
+ paramName = param.name;
4452
+ if (param.typeAnnotation && t12.isTSTypeAnnotation(param.typeAnnotation)) {
4453
+ const typeAnno = param.typeAnnotation.typeAnnotation;
4454
+ if (t12.isTSTypeReference(typeAnno) && t12.isIdentifier(typeAnno.typeName)) {
4455
+ paramTypeName = typeAnno.typeName.name;
4456
+ }
4457
+ }
4458
+ }
4459
+ }
4460
+ }
4461
+ }
4462
+ if (!parentFn || !paramName) return;
4463
+ const slug = fnNameToSlug(parentName.replace(/Workflow$/, ""));
4464
+ compilerState.metadata.slug = slug;
4465
+ compilerState.metadata.category = "workflow";
4466
+ for (const node of path.node.body) {
4467
+ if (t12.isTSInterfaceDeclaration(node) && node.id.name === paramTypeName) {
4468
+ const fields = extractFieldsFromInterface2(node);
4469
+ compilerState.fields.push(...fields);
4470
+ compilerState.metadata.name = paramTypeName;
4471
+ }
4472
+ if (t12.isExportNamedDeclaration(node) && t12.isTSInterfaceDeclaration(node.declaration) && node.declaration.id.name === paramTypeName) {
4473
+ const fields = extractFieldsFromInterface2(node.declaration);
4474
+ compilerState.fields.push(...fields);
4475
+ compilerState.metadata.name = paramTypeName;
4476
+ }
4477
+ }
4478
+ const localFns = /* @__PURE__ */ new Map();
4479
+ const localFnNames = /* @__PURE__ */ new Set();
4480
+ for (const node of path.node.body) {
4481
+ if (t12.isFunctionDeclaration(node) && node.async && node.id) {
4482
+ if (node.id.name !== parentName) {
4483
+ localFns.set(node.id.name, node);
4484
+ localFnNames.add(node.id.name);
4485
+ }
4486
+ }
4487
+ if (t12.isExportNamedDeclaration(node) && t12.isFunctionDeclaration(node.declaration) && node.declaration.async && node.declaration.id) {
4488
+ if (node.declaration.id.name !== parentName) {
4489
+ localFns.set(node.declaration.id.name, node.declaration);
4490
+ localFnNames.add(node.declaration.id.name);
4491
+ }
4492
+ }
4493
+ }
4494
+ for (const node of path.node.body) {
4495
+ if (t12.isExportNamedDeclaration(node) && t12.isVariableDeclaration(node.declaration)) {
4496
+ for (const decl of node.declaration.declarations) {
4497
+ if (t12.isIdentifier(decl.id) && decl.id.name === "defaults" && t12.isObjectExpression(decl.init)) {
4498
+ const defaults = extractNodeValue2(decl.init);
4499
+ for (const [name, value] of Object.entries(defaults)) {
4500
+ const field = compilerState.fields.find((f) => f.name === name);
4501
+ if (field && value !== void 0) {
4502
+ field.default_value = value;
4503
+ }
4504
+ }
4505
+ }
4506
+ }
4507
+ }
4508
+ }
4509
+ const stateFnInfos = /* @__PURE__ */ new Map();
4510
+ for (const [name, fn] of localFns) {
4511
+ const fnParamName = fn.params[0] && t12.isIdentifier(fn.params[0]) ? fn.params[0].name : paramName;
4512
+ const analysis = analyzeStateFn(fn, fnParamName, actionCounter);
4513
+ stateFnInfos.set(name, {
4514
+ name,
4515
+ node: fn,
4516
+ params: fn.params.map((p) => t12.isIdentifier(p) ? p.name : ""),
4517
+ ...analysis
4518
+ });
4519
+ }
4520
+ detectComputedFieldsFromActions(compilerState, stateFnInfos);
4521
+ detectComputedFieldGetters(path, paramName, paramTypeName, compilerState);
4522
+ const callSequence = extractCallSequence(
4523
+ parentFn.body,
4524
+ paramName,
4525
+ localFnNames,
4526
+ importedFns
4527
+ );
4528
+ const allowTransitions = extractAllowTransitions(parentFn.body);
4529
+ const referencedStates = /* @__PURE__ */ new Set();
4530
+ let firstStateName = "";
4531
+ let prevStateName = "";
4532
+ let transitionIndex = 0;
4533
+ for (const call of callSequence) {
4534
+ const stateName = toSnakeCase2(call.name);
4535
+ switch (call.type) {
4536
+ case "stateCall": {
4537
+ if (call.name.startsWith("__compensation_") && call.options?.__isCompensation) {
4538
+ const compOpts = call.options;
4539
+ const tryCallNames = compOpts.__tryBlockCallNames || [];
4540
+ const compensationCalls = compOpts.__compensationCalls || [];
4541
+ const hasReturn = compOpts.__hasReturn;
4542
+ const catchBody = compOpts.__catchBody;
4543
+ const compIndex = ++transitionIndex;
4544
+ const compStateName = `compensation_${compIndex}`;
4545
+ const compActions = [];
4546
+ if (catchBody) {
4547
+ for (const innerStmt of catchBody.body) {
4548
+ if (t12.isReturnStatement(innerStmt)) continue;
4549
+ if (t12.isExpressionStatement(innerStmt)) {
4550
+ const innerExpr = innerStmt.expression;
4551
+ if (t12.isAssignmentExpression(innerExpr) && t12.isMemberExpression(innerExpr.left)) {
4552
+ const left = memberExprToString(innerExpr.left);
4553
+ if (left.startsWith(`${paramName}.`)) {
4554
+ const field = left.slice(paramName.length + 1);
4555
+ const valueExpr = expressionToIR(innerExpr.right, paramName);
4556
+ compActions.push({
4557
+ id: `auto_${++actionCounter.value}`,
4558
+ type: "set_field",
4559
+ mode: "auto",
4560
+ config: { field, expression: valueExpr }
4561
+ });
4562
+ }
4563
+ }
4564
+ if (t12.isAwaitExpression(innerExpr) && t12.isCallExpression(innerExpr.argument)) {
4565
+ const innerCall = innerExpr.argument;
4566
+ const fnName = t12.isIdentifier(innerCall.callee) ? innerCall.callee.name : null;
4567
+ if (fnName && importedFns.has(fnName)) {
4568
+ compActions.push({
4569
+ id: `auto_${++actionCounter.value}`,
4570
+ type: "call_workflow",
4571
+ mode: "auto",
4572
+ config: { definition_slug: fnNameToSlug(fnName), blocking: true }
4573
+ });
4574
+ }
4575
+ if (fnName === "log") {
4576
+ const event = innerCall.arguments[0] ? extractNodeValue2(innerCall.arguments[0]) : "";
4577
+ compActions.push({
4578
+ id: `auto_${++actionCounter.value}`,
4579
+ type: "log_event",
4580
+ mode: "auto",
4581
+ config: { event: String(event) }
4582
+ });
4583
+ }
4584
+ if (fnName === "notify") {
4585
+ const to = innerCall.arguments[0] ? expressionToIR(innerCall.arguments[0], paramName) : "";
4586
+ const message = innerCall.arguments[1] ? extractNodeValue2(innerCall.arguments[1]) : "";
4587
+ compActions.push({
4588
+ id: `auto_${++actionCounter.value}`,
4589
+ type: "send_notification",
4590
+ mode: "auto",
4591
+ config: { to: String(to), message: String(message) }
4592
+ });
4593
+ }
4594
+ if (fnName === "emit") {
4595
+ const event = innerCall.arguments[0] ? extractNodeValue2(innerCall.arguments[0]) : "";
4596
+ compActions.push({
4597
+ id: `auto_${++actionCounter.value}`,
4598
+ type: "emit_event",
4599
+ mode: "auto",
4600
+ config: { event: String(event) }
4601
+ });
4602
+ }
4603
+ }
4604
+ if (t12.isCallExpression(innerExpr)) {
4605
+ const fnName = t12.isIdentifier(innerExpr.callee) ? innerExpr.callee.name : null;
4606
+ if (fnName === "log") {
4607
+ const event = innerExpr.arguments[0] ? extractNodeValue2(innerExpr.arguments[0]) : "";
4608
+ compActions.push({
4609
+ id: `auto_${++actionCounter.value}`,
4610
+ type: "log_event",
4611
+ mode: "auto",
4612
+ config: { event: String(event) }
4613
+ });
4614
+ }
4615
+ if (fnName === "notify") {
4616
+ const to = innerExpr.arguments[0] ? expressionToIR(innerExpr.arguments[0], paramName) : "";
4617
+ const message = innerExpr.arguments[1] ? extractNodeValue2(innerExpr.arguments[1]) : "";
4618
+ compActions.push({
4619
+ id: `auto_${++actionCounter.value}`,
4620
+ type: "send_notification",
4621
+ mode: "auto",
4622
+ config: { to: String(to), message: String(message) }
4623
+ });
4624
+ }
4625
+ if (fnName === "emit") {
4626
+ const event = innerExpr.arguments[0] ? extractNodeValue2(innerExpr.arguments[0]) : "";
4627
+ compActions.push({
4628
+ id: `auto_${++actionCounter.value}`,
4629
+ type: "emit_event",
4630
+ mode: "auto",
4631
+ config: { event: String(event) }
4632
+ });
4633
+ }
4634
+ }
4635
+ }
4636
+ if (t12.isIfStatement(innerStmt) && t12.isBlockStatement(innerStmt.consequent)) {
4637
+ const condStr = expressionToIR(innerStmt.test, paramName);
4638
+ for (const ifInner of innerStmt.consequent.body) {
4639
+ if (t12.isExpressionStatement(ifInner)) {
4640
+ const ifExpr = ifInner.expression;
4641
+ if (t12.isAssignmentExpression(ifExpr) && t12.isMemberExpression(ifExpr.left)) {
4642
+ const left = memberExprToString(ifExpr.left);
4643
+ if (left.startsWith(`${paramName}.`)) {
4644
+ const field = left.slice(paramName.length + 1);
4645
+ const valueExpr = expressionToIR(ifExpr.right, paramName);
4646
+ compActions.push({
4647
+ id: `auto_${++actionCounter.value}`,
4648
+ type: "set_field",
4649
+ mode: "auto",
4650
+ config: { field, expression: valueExpr },
4651
+ condition: condStr
4652
+ });
4653
+ }
4654
+ }
4655
+ if (t12.isAwaitExpression(ifExpr) && t12.isCallExpression(ifExpr.argument)) {
4656
+ const ifCall = ifExpr.argument;
4657
+ const fnName = t12.isIdentifier(ifCall.callee) ? ifCall.callee.name : null;
4658
+ if (fnName && importedFns.has(fnName)) {
4659
+ compActions.push({
4660
+ id: `auto_${++actionCounter.value}`,
4661
+ type: "call_workflow",
4662
+ mode: "auto",
4663
+ config: { definition_slug: fnNameToSlug(fnName), blocking: true },
4664
+ condition: condStr
4665
+ });
4666
+ }
4667
+ }
4668
+ }
4669
+ }
4670
+ }
4671
+ }
4672
+ }
4673
+ for (const cc of compensationCalls) {
4674
+ if (cc.type === "serviceCall") {
4675
+ compActions.push({
4676
+ id: `auto_${++actionCounter.value}`,
4677
+ type: "call_workflow",
4678
+ mode: "auto",
4679
+ config: { definition_slug: fnNameToSlug(cc.name), blocking: true }
4680
+ });
4681
+ }
4682
+ }
4683
+ compilerState.states.set(compStateName, {
4684
+ name: compStateName,
4685
+ type: hasReturn ? "END" : "REGULAR",
4686
+ on_enter: compActions,
4687
+ during: [],
4688
+ on_exit: []
4689
+ });
4690
+ for (const tryCallName of tryCallNames) {
4691
+ let tryStateName;
4692
+ if (localFnNames.has(tryCallName)) {
4693
+ tryStateName = toSnakeCase2(tryCallName);
4694
+ } else if (importedFns.has(tryCallName)) {
4695
+ tryStateName = `awaiting_${toSnakeCase2(tryCallName)}`;
4696
+ } else {
4697
+ tryStateName = toSnakeCase2(tryCallName);
4698
+ }
4699
+ if (compilerState.states.has(tryStateName)) {
4700
+ compilerState.transitions.push({
4701
+ name: `error_to_${compStateName}`,
4702
+ from: [tryStateName],
4703
+ to: compStateName,
4704
+ conditions: [{ expression: "error != null" }],
4705
+ actions: [],
4706
+ auto: true
4707
+ });
4708
+ }
4709
+ }
4710
+ if (!hasReturn) {
4711
+ prevStateName = compStateName;
4712
+ }
4713
+ break;
4714
+ }
4715
+ referencedStates.add(call.name);
4716
+ if (!firstStateName) firstStateName = stateName;
4717
+ const info = stateFnInfos.get(call.name);
4718
+ if (info && !compilerState.states.has(stateName)) {
4719
+ compilerState.states.set(stateName, {
4720
+ name: stateName,
4721
+ type: !firstStateName || stateName === toSnakeCase2(callSequence[0]?.name || "") ? "START" : "REGULAR",
4722
+ on_enter: info.onEnter,
4723
+ during: info.during,
4724
+ on_exit: [],
4725
+ ...info.onEvent.length > 0 ? { on_event: info.onEvent } : {},
4726
+ ...info.timeout ? { timeout: info.timeout } : {},
4727
+ ...info.runtime ? { runtime: info.runtime } : {}
4728
+ });
4729
+ } else if (!compilerState.states.has(stateName)) {
4730
+ compilerState.states.set(stateName, {
4731
+ name: stateName,
4732
+ type: "REGULAR",
4733
+ on_enter: [],
4734
+ during: [],
4735
+ on_exit: []
4736
+ });
4737
+ }
4738
+ if (prevStateName && prevStateName !== stateName) {
4739
+ const transName = call.transitionName || `to_${stateName}`;
4740
+ const conditions = [];
4741
+ if (call.condition) {
4742
+ conditions.push({ expression: call.condition });
4743
+ }
4744
+ if (info?.roles.length) {
4745
+ for (const role of info.roles) {
4746
+ conditions.push(roleCondition(role));
4747
+ }
4748
+ }
4749
+ compilerState.transitions.push({
4750
+ name: transName,
4751
+ from: [prevStateName],
4752
+ to: stateName,
4753
+ conditions: conditions.length > 0 ? conditions : void 0,
4754
+ actions: [],
4755
+ ...info?.requiredFields.length ? { required_fields: info.requiredFields } : {},
4756
+ auto: true
4757
+ });
4758
+ }
4759
+ prevStateName = stateName;
4760
+ break;
4761
+ }
4762
+ case "userAction": {
4763
+ const awaitState = `awaiting_${call.name}`;
4764
+ if (!compilerState.states.has(awaitState)) {
4765
+ compilerState.states.set(awaitState, {
4766
+ name: awaitState,
4767
+ type: "REGULAR",
4768
+ on_enter: [],
4769
+ during: [],
4770
+ on_exit: []
4771
+ });
4772
+ }
4773
+ if (prevStateName) {
4774
+ compilerState.transitions.push({
4775
+ name: `to_${awaitState}`,
4776
+ from: [prevStateName],
4777
+ to: awaitState,
4778
+ actions: [],
4779
+ auto: true,
4780
+ ...call.condition ? { conditions: [{ expression: call.condition }] } : {}
4781
+ });
4782
+ }
4783
+ const opts = call.options || {};
4784
+ const conditions = [];
4785
+ if (opts.roles && Array.isArray(opts.roles)) {
4786
+ for (const role of opts.roles) {
4787
+ conditions.push(roleCondition(role));
4788
+ }
4789
+ }
4790
+ if (opts.when && typeof opts.when === "string") {
4791
+ conditions.push({ expression: opts.when });
4792
+ }
4793
+ compilerState.transitions.push({
4794
+ name: call.name,
4795
+ from: [awaitState],
4796
+ to: "",
4797
+ // Will be resolved later (next state in sequence)
4798
+ conditions: conditions.length > 0 ? conditions : void 0,
4799
+ actions: [],
4800
+ ...opts.require ? { required_fields: opts.require } : {}
4801
+ });
4802
+ prevStateName = awaitState;
4803
+ break;
4804
+ }
4805
+ case "userChoice": {
4806
+ const choiceState = prevStateName || "choice";
4807
+ if (call.choices) {
4808
+ for (const [optionName, optionConfig] of Object.entries(call.choices)) {
4809
+ const config = optionConfig;
4810
+ const conditions = [];
4811
+ if (config.roles && Array.isArray(config.roles)) {
4812
+ for (const role of config.roles) {
4813
+ conditions.push(roleCondition(role));
4814
+ }
4815
+ }
4816
+ if (config.when && typeof config.when === "string") {
4817
+ conditions.push({ expression: config.when });
4818
+ }
4819
+ compilerState.transitions.push({
4820
+ name: optionName,
4821
+ from: [choiceState],
4822
+ to: "",
4823
+ // Resolved by switch/case handling
4824
+ conditions: conditions.length > 0 ? conditions : void 0,
4825
+ actions: [],
4826
+ ...config.require ? { required_fields: config.require } : {}
4827
+ });
4828
+ }
4829
+ }
4830
+ break;
4831
+ }
4832
+ case "serviceCall": {
4833
+ const serviceSlug = fnNameToSlug(call.name);
4834
+ const serviceState = `awaiting_${toSnakeCase2(call.name)}`;
4835
+ compilerState.states.set(serviceState, {
4836
+ name: serviceState,
4837
+ type: "REGULAR",
4838
+ on_enter: [{
4839
+ id: `auto_${++actionCounter.value}`,
4840
+ type: "call_workflow",
4841
+ mode: "auto",
4842
+ config: {
4843
+ definition_slug: serviceSlug,
4844
+ blocking: true
4845
+ }
4846
+ }],
4847
+ during: [],
4848
+ on_exit: []
4849
+ });
4850
+ if (prevStateName) {
4851
+ compilerState.transitions.push({
4852
+ name: `call_${toSnakeCase2(call.name)}`,
4853
+ from: [prevStateName],
4854
+ to: serviceState,
4855
+ actions: [],
4856
+ auto: true,
4857
+ ...call.condition ? { conditions: [{ expression: call.condition }] } : {}
4858
+ });
4859
+ }
4860
+ prevStateName = serviceState;
4861
+ break;
4862
+ }
4863
+ case "awaitOn": {
4864
+ const eventState = `awaiting_${call.name}`;
4865
+ const opts = call.options || {};
4866
+ const eventPattern = opts.__eventPattern ? String(opts.__eventPattern) : call.name.replace(/_/g, ":");
4867
+ const awaitOnMetadata = {
4868
+ event_pattern: eventPattern
4869
+ };
4870
+ if (opts.when && typeof opts.when === "string") {
4871
+ awaitOnMetadata.event_condition = String(opts.when);
4872
+ }
4873
+ if (opts.timeout) {
4874
+ awaitOnMetadata.event_timeout = String(opts.timeout);
4875
+ }
4876
+ const awaitState = {
4877
+ name: eventState,
4878
+ type: "REGULAR",
4879
+ on_enter: [],
4880
+ during: [],
4881
+ on_exit: [],
4882
+ ...opts.timeout ? { timeout: { duration: String(opts.timeout) } } : {}
4883
+ };
4884
+ if (awaitOnMetadata) awaitState.metadata = awaitOnMetadata;
4885
+ compilerState.states.set(eventState, awaitState);
4886
+ if (prevStateName) {
4887
+ compilerState.transitions.push({
4888
+ name: `await_${call.name}`,
4889
+ from: [prevStateName],
4890
+ to: eventState,
4891
+ actions: [],
4892
+ auto: true,
4893
+ ...call.condition ? { conditions: [{ expression: call.condition }] } : {}
4894
+ });
4895
+ }
4896
+ const eventConditions = [];
4897
+ if (opts.when && typeof opts.when === "string") {
4898
+ eventConditions.push({ expression: String(opts.when) });
4899
+ }
4900
+ compilerState.transitions.push({
4901
+ name: `${call.name}_matched`,
4902
+ from: [eventState],
4903
+ to: "",
4904
+ // Resolved to next state
4905
+ conditions: eventConditions.length > 0 ? eventConditions : void 0,
4906
+ actions: [],
4907
+ auto: true
4908
+ });
4909
+ prevStateName = eventState;
4910
+ break;
4911
+ }
4912
+ case "promiseAll": {
4913
+ const parallelState = `parallel_${++transitionIndex}`;
4914
+ const parallelActions = [];
4915
+ for (const pc of call.parallelCalls || []) {
4916
+ if (pc.type === "serviceCall") {
4917
+ parallelActions.push({
4918
+ id: `auto_${++actionCounter.value}`,
4919
+ type: "call_workflow",
4920
+ mode: "auto",
4921
+ config: {
4922
+ definition_slug: fnNameToSlug(pc.name),
4923
+ blocking: true
4924
+ }
4925
+ });
4926
+ }
4927
+ }
4928
+ compilerState.states.set(parallelState, {
4929
+ name: parallelState,
4930
+ type: "REGULAR",
4931
+ on_enter: parallelActions,
4932
+ during: [],
4933
+ on_exit: []
4934
+ });
4935
+ if (prevStateName) {
4936
+ compilerState.transitions.push({
4937
+ name: `to_${parallelState}`,
4938
+ from: [prevStateName],
4939
+ to: parallelState,
4940
+ actions: [],
4941
+ auto: true
4942
+ });
4943
+ }
4944
+ prevStateName = parallelState;
4945
+ break;
4946
+ }
4947
+ case "delay": {
4948
+ const delayState = `delay_${++transitionIndex}`;
4949
+ const durationMatch = call.name.match(/delay_(.+)/);
4950
+ const duration = durationMatch ? durationMatch[1] : "0";
4951
+ compilerState.states.set(delayState, {
4952
+ name: delayState,
4953
+ type: "REGULAR",
4954
+ on_enter: [],
4955
+ during: [],
4956
+ on_exit: [],
4957
+ timeout: { duration, fallback: {} }
4958
+ });
4959
+ if (prevStateName) {
4960
+ compilerState.transitions.push({
4961
+ name: `to_${delayState}`,
4962
+ from: [prevStateName],
4963
+ to: delayState,
4964
+ actions: [],
4965
+ auto: true
4966
+ });
4967
+ }
4968
+ prevStateName = delayState;
4969
+ break;
4970
+ }
4971
+ }
4972
+ }
4973
+ if (prevStateName && compilerState.states.has(prevStateName)) {
4974
+ const lastState = compilerState.states.get(prevStateName);
4975
+ const hasOutgoing = compilerState.transitions.some((t23) => t23.from.includes(prevStateName));
4976
+ if (!hasOutgoing) {
4977
+ lastState.type = "END";
4978
+ }
4979
+ }
4980
+ if (firstStateName && compilerState.states.has(firstStateName)) {
4981
+ compilerState.states.get(firstStateName).type = "START";
4982
+ }
4983
+ for (let i = 0; i < compilerState.transitions.length; i++) {
4984
+ const trans = compilerState.transitions[i];
4985
+ if (trans.to === "" && i + 1 < compilerState.transitions.length) {
4986
+ const nextTrans = compilerState.transitions[i + 1];
4987
+ if (nextTrans.to) {
4988
+ trans.to = nextTrans.to;
4989
+ } else if (nextTrans.from.length > 0) {
4990
+ }
4991
+ }
4992
+ }
4993
+ const stateSequence = callSequence.filter((c) => c.type === "stateCall" || c.type === "serviceCall" || c.type === "userAction" || c.type === "awaitOn").map((c) => {
4994
+ if (c.type === "stateCall") return toSnakeCase2(c.name);
4995
+ if (c.type === "userAction") return `awaiting_${c.name}`;
4996
+ if (c.type === "serviceCall") return `awaiting_${toSnakeCase2(c.name)}`;
4997
+ if (c.type === "awaitOn") return `awaiting_${c.name}`;
4998
+ return c.name;
4999
+ });
5000
+ for (const trans of compilerState.transitions) {
5001
+ if (trans.to === "") {
5002
+ const fromState = trans.from[0];
5003
+ const idx = stateSequence.indexOf(fromState);
5004
+ if (idx >= 0 && idx + 1 < stateSequence.length) {
5005
+ trans.to = stateSequence[idx + 1];
5006
+ }
5007
+ }
5008
+ }
5009
+ for (const at of allowTransitions) {
5010
+ const resolvedTo = at.to === "$self" ? "__self__" : toSnakeCase2(at.to);
5011
+ const resolvedFrom = at.from.map((f) => toSnakeCase2(f));
5012
+ const conditions = [];
5013
+ if (at.roles) {
5014
+ for (const role of at.roles) {
5015
+ conditions.push(roleCondition(role));
5016
+ }
5017
+ }
5018
+ if (at.when) {
5019
+ conditions.push({ expression: at.when });
5020
+ }
5021
+ if (resolvedTo !== "__self__" && !compilerState.states.has(resolvedTo)) {
5022
+ compilerState.states.set(resolvedTo, {
5023
+ name: resolvedTo,
5024
+ type: "REGULAR",
5025
+ on_enter: [],
5026
+ during: [],
5027
+ on_exit: []
5028
+ });
5029
+ }
5030
+ if (resolvedTo === "__self__") {
5031
+ for (const from of resolvedFrom) {
5032
+ compilerState.transitions.push({
5033
+ name: at.name,
5034
+ from: [from],
5035
+ to: from,
5036
+ conditions: conditions.length > 0 ? conditions : void 0,
5037
+ actions: [],
5038
+ ...at.require ? { required_fields: at.require } : {}
5039
+ });
5040
+ }
5041
+ } else {
5042
+ compilerState.transitions.push({
5043
+ name: at.name,
5044
+ from: resolvedFrom,
5045
+ to: resolvedTo,
5046
+ conditions: conditions.length > 0 ? conditions : void 0,
5047
+ actions: [],
5048
+ ...at.require ? { required_fields: at.require } : {}
5049
+ });
5050
+ }
5051
+ }
5052
+ for (const [, info] of stateFnInfos) {
5053
+ for (const v of info.validations) {
5054
+ if (v.field === "__cross__") continue;
5055
+ const field = compilerState.fields.find((f) => f.name === v.field);
5056
+ if (field) {
5057
+ if (!field.validation) field.validation = {};
5058
+ Object.assign(field.validation, v.validation);
5059
+ if (v.validation.rules) {
5060
+ if (!field.validation.rules) field.validation.rules = [];
5061
+ field.validation.rules.push(...v.validation.rules);
5062
+ }
5063
+ }
5064
+ }
5065
+ }
5066
+ for (const node of path.node.body) {
5067
+ if (t12.isExportNamedDeclaration(node) && t12.isVariableDeclaration(node.declaration)) {
5068
+ for (const decl of node.declaration.declarations) {
5069
+ if (t12.isIdentifier(decl.id) && decl.id.name === "roles" && decl.init) {
5070
+ let rolesObj = null;
5071
+ if (t12.isCallExpression(decl.init) && t12.isIdentifier(decl.init.callee) && decl.init.callee.name === "defineRoles" && t12.isObjectExpression(decl.init.arguments[0])) {
5072
+ rolesObj = decl.init.arguments[0];
5073
+ } else if (t12.isObjectExpression(decl.init)) {
5074
+ rolesObj = decl.init;
5075
+ }
5076
+ if (rolesObj) {
5077
+ const roles = extractNodeValue2(rolesObj);
5078
+ if (!compilerState.metadata.roles) compilerState.metadata.roles = {};
5079
+ for (const [roleName, roleConfig] of Object.entries(roles)) {
5080
+ compilerState.metadata.roles[roleName] = roleConfig;
5081
+ }
5082
+ }
5083
+ }
5084
+ if (t12.isIdentifier(decl.id) && decl.id.name === "fieldAccess" && t12.isObjectExpression(decl.init)) {
5085
+ const access = extractNodeValue2(decl.init);
5086
+ for (const [fieldName, config] of Object.entries(access)) {
5087
+ const field = compilerState.fields.find((f) => f.name === fieldName);
5088
+ if (field) {
5089
+ if (config.visibleTo) field.visible_to_roles = config.visibleTo;
5090
+ if (config.editableBy) field.editable_by_roles = config.editableBy;
5091
+ if (config.editableIn) field.editable_in_states = config.editableIn;
5092
+ }
5093
+ }
5094
+ }
5095
+ if (t12.isIdentifier(decl.id) && decl.id.name === "config" && decl.init) {
5096
+ if (t12.isCallExpression(decl.init) && t12.isIdentifier(decl.init.callee) && decl.init.callee.name === "orchestration" && t12.isObjectExpression(decl.init.arguments[0])) {
5097
+ compilerState.metadata.orchestration = extractNodeValue2(decl.init.arguments[0]);
5098
+ }
5099
+ }
5100
+ }
5101
+ }
5102
+ }
5103
+ for (const node of path.node.body) {
5104
+ if (t12.isExportNamedDeclaration(node) && t12.isVariableDeclaration(node.declaration)) {
5105
+ for (const decl of node.declaration.declarations) {
5106
+ if (t12.isIdentifier(decl.id) && decl.id.name === "fields" && t12.isObjectExpression(decl.init)) {
5107
+ const fieldsConfig = extractNodeValue2(decl.init);
5108
+ for (const [name, config] of Object.entries(fieldsConfig)) {
5109
+ const field = compilerState.fields.find((f) => f.name === name);
5110
+ if (!field) continue;
5111
+ if (typeof config === "string") {
5112
+ if (config.includes("!")) field.required = true;
5113
+ } else if (typeof config === "object" && config !== null) {
5114
+ const cfg = config;
5115
+ if (cfg.required) field.required = true;
5116
+ if (cfg.min !== void 0 || cfg.max !== void 0 || cfg.minLength !== void 0 || cfg.maxLength !== void 0 || cfg.pattern !== void 0) {
5117
+ if (!field.validation) field.validation = {};
5118
+ if (cfg.min !== void 0) field.validation.min = Number(cfg.min);
5119
+ if (cfg.max !== void 0) field.validation.max = Number(cfg.max);
5120
+ if (cfg.minLength !== void 0) field.validation.minLength = Number(cfg.minLength);
5121
+ if (cfg.maxLength !== void 0) field.validation.maxLength = Number(cfg.maxLength);
5122
+ if (cfg.pattern !== void 0) {
5123
+ if (!field.validation.rules) field.validation.rules = [];
5124
+ field.validation.rules.push({
5125
+ expression: `MATCHES(value, "${String(cfg.pattern)}")`,
5126
+ message: "Invalid format",
5127
+ severity: "error"
5128
+ });
5129
+ }
5130
+ }
5131
+ if (cfg.default !== void 0) field.default_value = cfg.default;
5132
+ }
5133
+ }
5134
+ }
5135
+ }
5136
+ }
5137
+ }
5138
+ compilerState.transitions = compilerState.transitions.filter((t23) => t23.to !== "");
5139
+ for (const trans of compilerState.transitions) {
5140
+ for (const from of trans.from) {
5141
+ if (!compilerState.states.has(from)) {
5142
+ compilerState.states.set(from, {
5143
+ name: from,
5144
+ type: "REGULAR",
5145
+ on_enter: [],
5146
+ during: [],
5147
+ on_exit: []
5148
+ });
5149
+ }
5150
+ }
5151
+ if (!compilerState.states.has(trans.to)) {
5152
+ compilerState.states.set(trans.to, {
5153
+ name: trans.to,
5154
+ type: "REGULAR",
5155
+ on_enter: [],
5156
+ during: [],
5157
+ on_exit: []
5158
+ });
5159
+ }
5160
+ }
5161
+ compilerState.actionCounter = actionCounter.value;
5162
+ }
5163
+ var t12, VALIDATION_FNS, TS_TYPE_MAP, NAME_TYPE_MAP;
5164
+ var init_flow_extractor = __esm({
5165
+ "src/babel/extractors/flow-extractor.ts"() {
5166
+ "use strict";
5167
+ t12 = __toESM(require("@babel/types"));
5168
+ init_workflow_shorthand();
5169
+ VALIDATION_FNS = /* @__PURE__ */ new Set(["validate", "assert"]);
5170
+ TS_TYPE_MAP = {
5171
+ Date: "datetime",
5172
+ Record: "json",
5173
+ Map: "json",
5174
+ Set: "json",
5175
+ URL: "url"
5176
+ };
5177
+ NAME_TYPE_MAP = {
5178
+ email: "email",
5179
+ url: "url",
5180
+ website: "url",
5181
+ phone: "phone"
5182
+ };
5183
+ }
5184
+ });
5185
+
3312
5186
  // src/babel/extractors/server-action-extractor.ts
3313
5187
  function isServerActionFile(filename) {
3314
5188
  if (!filename) return false;
@@ -3318,9 +5192,9 @@ function extractServerActions(path, state) {
3318
5192
  const compilerState = state;
3319
5193
  const serverActions = [];
3320
5194
  for (const node of path.node.body) {
3321
- if (t12.isExportNamedDeclaration(node)) {
5195
+ if (t13.isExportNamedDeclaration(node)) {
3322
5196
  const decl = node.declaration;
3323
- if (t12.isFunctionDeclaration(decl) && decl.id) {
5197
+ if (t13.isFunctionDeclaration(decl) && decl.id) {
3324
5198
  const action = extractFunctionAction(decl);
3325
5199
  if (action) {
3326
5200
  const comments = node.leadingComments || decl.leadingComments || [];
@@ -3328,19 +5202,19 @@ function extractServerActions(path, state) {
3328
5202
  serverActions.push(action);
3329
5203
  }
3330
5204
  }
3331
- if (t12.isVariableDeclaration(decl)) {
5205
+ if (t13.isVariableDeclaration(decl)) {
3332
5206
  for (const varDecl of decl.declarations) {
3333
- if (!t12.isIdentifier(varDecl.id)) continue;
5207
+ if (!t13.isIdentifier(varDecl.id)) continue;
3334
5208
  const init = varDecl.init;
3335
- if (t12.isArrowFunctionExpression(init) || t12.isFunctionExpression(init)) {
5209
+ if (t13.isArrowFunctionExpression(init) || t13.isFunctionExpression(init)) {
3336
5210
  const action = {
3337
5211
  name: varDecl.id.name,
3338
5212
  async: init.async || false,
3339
- params: init.params.filter((p) => t12.isIdentifier(p)).map((p) => p.name)
5213
+ params: init.params.filter((p) => t13.isIdentifier(p)).map((p) => p.name)
3340
5214
  };
3341
5215
  if (init.params.length > 0) {
3342
5216
  const firstParam = init.params[0];
3343
- if (t12.isIdentifier(firstParam) && firstParam.typeAnnotation) {
5217
+ if (t13.isIdentifier(firstParam) && firstParam.typeAnnotation) {
3344
5218
  action.contextType = extractTypeName(firstParam.typeAnnotation);
3345
5219
  }
3346
5220
  }
@@ -3360,20 +5234,20 @@ function extractFunctionAction(decl) {
3360
5234
  const action = {
3361
5235
  name: decl.id.name,
3362
5236
  async: decl.async || false,
3363
- params: decl.params.filter((p) => t12.isIdentifier(p)).map((p) => p.name)
5237
+ params: decl.params.filter((p) => t13.isIdentifier(p)).map((p) => p.name)
3364
5238
  };
3365
5239
  if (decl.params.length > 0) {
3366
5240
  const firstParam = decl.params[0];
3367
- if (t12.isIdentifier(firstParam) && firstParam.typeAnnotation) {
5241
+ if (t13.isIdentifier(firstParam) && firstParam.typeAnnotation) {
3368
5242
  action.contextType = extractTypeName(firstParam.typeAnnotation);
3369
5243
  }
3370
5244
  }
3371
5245
  return action;
3372
5246
  }
3373
5247
  function extractTypeName(annotation) {
3374
- if (t12.isTSTypeAnnotation(annotation)) {
5248
+ if (t13.isTSTypeAnnotation(annotation)) {
3375
5249
  const typeNode = annotation.typeAnnotation;
3376
- if (t12.isTSTypeReference(typeNode) && t12.isIdentifier(typeNode.typeName)) {
5250
+ if (t13.isTSTypeReference(typeNode) && t13.isIdentifier(typeNode.typeName)) {
3377
5251
  return typeNode.typeName.name;
3378
5252
  }
3379
5253
  }
@@ -3392,11 +5266,11 @@ function extractDescription(comments) {
3392
5266
  }
3393
5267
  return void 0;
3394
5268
  }
3395
- var t12;
5269
+ var t13;
3396
5270
  var init_server_action_extractor = __esm({
3397
5271
  "src/babel/extractors/server-action-extractor.ts"() {
3398
5272
  "use strict";
3399
- t12 = __toESM(require("@babel/types"));
5273
+ t13 = __toESM(require("@babel/types"));
3400
5274
  }
3401
5275
  });
3402
5276
 
@@ -3405,21 +5279,21 @@ function extractServerActionHook(path, state) {
3405
5279
  const args = path.node.arguments;
3406
5280
  if (args.length < 1) return;
3407
5281
  const nameArg = args[0];
3408
- if (!t13.isStringLiteral(nameArg)) return;
5282
+ if (!t14.isStringLiteral(nameArg)) return;
3409
5283
  const compilerState = state;
3410
5284
  const entry = {
3411
5285
  name: nameArg.value
3412
5286
  };
3413
- if (args.length > 1 && t13.isObjectExpression(args[1])) {
5287
+ if (args.length > 1 && t14.isObjectExpression(args[1])) {
3414
5288
  for (const prop of args[1].properties) {
3415
- if (!t13.isObjectProperty(prop) || !t13.isIdentifier(prop.key)) continue;
3416
- if (prop.key.name === "instanceId" && t13.isStringLiteral(prop.value)) {
5289
+ if (!t14.isObjectProperty(prop) || !t14.isIdentifier(prop.key)) continue;
5290
+ if (prop.key.name === "instanceId" && t14.isStringLiteral(prop.value)) {
3417
5291
  entry.staticInstanceId = prop.value.value;
3418
5292
  }
3419
5293
  }
3420
5294
  }
3421
5295
  const parent = path.parentPath;
3422
- if (parent?.isVariableDeclarator() && t13.isIdentifier(parent.node.id)) {
5296
+ if (parent?.isVariableDeclarator() && t14.isIdentifier(parent.node.id)) {
3423
5297
  entry.variableName = parent.node.id.name;
3424
5298
  }
3425
5299
  if (!compilerState.metadata) compilerState.metadata = {};
@@ -3427,11 +5301,11 @@ function extractServerActionHook(path, state) {
3427
5301
  if (!meta.serverActionHooks) meta.serverActionHooks = [];
3428
5302
  meta.serverActionHooks.push(entry);
3429
5303
  }
3430
- var t13;
5304
+ var t14;
3431
5305
  var init_server_action_hook_extractor = __esm({
3432
5306
  "src/babel/extractors/server-action-hook-extractor.ts"() {
3433
5307
  "use strict";
3434
- t13 = __toESM(require("@babel/types"));
5308
+ t14 = __toESM(require("@babel/types"));
3435
5309
  }
3436
5310
  });
3437
5311
 
@@ -3442,23 +5316,23 @@ function extractServerState(path, state) {
3442
5316
  const compilerState = state;
3443
5317
  const entry = {};
3444
5318
  const instanceArg = args[0];
3445
- if (t14.isStringLiteral(instanceArg)) {
5319
+ if (t15.isStringLiteral(instanceArg)) {
3446
5320
  entry.staticInstanceId = instanceArg.value;
3447
5321
  }
3448
- if (args.length > 1 && t14.isObjectExpression(args[1])) {
5322
+ if (args.length > 1 && t15.isObjectExpression(args[1])) {
3449
5323
  for (const prop of args[1].properties) {
3450
- if (!t14.isObjectProperty(prop) || !t14.isIdentifier(prop.key)) continue;
3451
- if (prop.key.name === "enabled" && t14.isBooleanLiteral(prop.value)) {
5324
+ if (!t15.isObjectProperty(prop) || !t15.isIdentifier(prop.key)) continue;
5325
+ if (prop.key.name === "enabled" && t15.isBooleanLiteral(prop.value)) {
3452
5326
  if (!prop.value.value) entry.disabled = true;
3453
5327
  }
3454
5328
  }
3455
5329
  }
3456
5330
  const parent = path.parentPath;
3457
5331
  if (parent?.isVariableDeclarator()) {
3458
- if (t14.isIdentifier(parent.node.id)) {
5332
+ if (t15.isIdentifier(parent.node.id)) {
3459
5333
  entry.variableName = parent.node.id.name;
3460
- } else if (t14.isObjectPattern(parent.node.id)) {
3461
- const props = parent.node.id.properties.filter((p) => t14.isObjectProperty(p) && t14.isIdentifier(p.key)).map((p) => p.key.name);
5334
+ } else if (t15.isObjectPattern(parent.node.id)) {
5335
+ const props = parent.node.id.properties.filter((p) => t15.isObjectProperty(p) && t15.isIdentifier(p.key)).map((p) => p.key.name);
3462
5336
  if (props.length > 0) {
3463
5337
  entry.variableName = props.join(", ");
3464
5338
  }
@@ -3470,11 +5344,11 @@ function extractServerState(path, state) {
3470
5344
  meta.serverStateSubscriptions.push(entry);
3471
5345
  meta.requiresSSE = true;
3472
5346
  }
3473
- var t14;
5347
+ var t15;
3474
5348
  var init_server_state_extractor = __esm({
3475
5349
  "src/babel/extractors/server-state-extractor.ts"() {
3476
5350
  "use strict";
3477
- t14 = __toESM(require("@babel/types"));
5351
+ t15 = __toESM(require("@babel/types"));
3478
5352
  }
3479
5353
  });
3480
5354
 
@@ -3558,7 +5432,7 @@ function parseDmn(source) {
3558
5432
  }
3559
5433
  function extractGrammarIsland(path, state, slug) {
3560
5434
  const tag = path.node.tag;
3561
- if (!t15.isIdentifier(tag)) return;
5435
+ if (!t16.isIdentifier(tag)) return;
3562
5436
  const tagName = tag.name;
3563
5437
  if (!GRAMMAR_TAGS.has(tagName)) return;
3564
5438
  const compilerState = state;
@@ -3568,7 +5442,7 @@ function extractGrammarIsland(path, state, slug) {
3568
5442
  rawSource += quasi.quasis[i].value.raw;
3569
5443
  if (i < quasi.expressions.length) {
3570
5444
  const expr = quasi.expressions[i];
3571
- if (t15.isIdentifier(expr)) {
5445
+ if (t16.isIdentifier(expr)) {
3572
5446
  rawSource += `\${${expr.name}}`;
3573
5447
  } else {
3574
5448
  rawSource += `\${expr_${i}}`;
@@ -3608,186 +5482,748 @@ function extractGrammarIsland(path, state, slug) {
3608
5482
  if (!meta.grammarIslands) meta.grammarIslands = [];
3609
5483
  meta.grammarIslands.push(island);
3610
5484
  }
3611
- function extractGrammarIslands(path, state) {
3612
- path.traverse({
3613
- TaggedTemplateExpression(templatePath) {
3614
- const tag = templatePath.node.tag;
3615
- if (!t15.isIdentifier(tag) || !GRAMMAR_TAGS.has(tag.name)) return;
3616
- let slug = "unnamed";
3617
- const parent = templatePath.parentPath;
3618
- if (parent && parent.isVariableDeclarator() && t15.isIdentifier(parent.node.id)) {
3619
- slug = parent.node.id.name;
3620
- }
3621
- if (parent && parent.isObjectProperty() && t15.isIdentifier(parent.node.key)) {
3622
- slug = parent.node.key.name;
5485
+ function extractGrammarIslands(path, state) {
5486
+ path.traverse({
5487
+ TaggedTemplateExpression(templatePath) {
5488
+ const tag = templatePath.node.tag;
5489
+ if (!t16.isIdentifier(tag) || !GRAMMAR_TAGS.has(tag.name)) return;
5490
+ let slug = "unnamed";
5491
+ const parent = templatePath.parentPath;
5492
+ if (parent && parent.isVariableDeclarator() && t16.isIdentifier(parent.node.id)) {
5493
+ slug = parent.node.id.name;
5494
+ }
5495
+ if (parent && parent.isObjectProperty() && t16.isIdentifier(parent.node.key)) {
5496
+ slug = parent.node.key.name;
5497
+ }
5498
+ if (parent && parent.isObjectProperty() && t16.isStringLiteral(parent.node.key)) {
5499
+ slug = parent.node.key.value;
5500
+ }
5501
+ extractGrammarIsland(templatePath, state, slug);
5502
+ }
5503
+ });
5504
+ }
5505
+ var t16, GRAMMAR_TAGS;
5506
+ var init_grammar_island_extractor = __esm({
5507
+ "src/babel/extractors/grammar-island-extractor.ts"() {
5508
+ "use strict";
5509
+ t16 = __toESM(require("@babel/types"));
5510
+ GRAMMAR_TAGS = /* @__PURE__ */ new Set(["cedar", "sql", "cron", "dmn", "graphql", "jsonpath"]);
5511
+ }
5512
+ });
5513
+
5514
+ // src/babel/extractors/context-extractor.ts
5515
+ function hasContextCreation(path) {
5516
+ let found = false;
5517
+ path.traverse({
5518
+ CallExpression(callPath) {
5519
+ if (t17.isIdentifier(callPath.node.callee, { name: "createContext" })) {
5520
+ found = true;
5521
+ callPath.stop();
5522
+ }
5523
+ }
5524
+ });
5525
+ return found;
5526
+ }
5527
+ function extractContextWorkflows(path, state) {
5528
+ const compilerState = state;
5529
+ const contextWorkflows = [];
5530
+ const contextNames = /* @__PURE__ */ new Map();
5531
+ path.traverse({
5532
+ // Detect: const XContext = createContext(...)
5533
+ VariableDeclarator(declPath) {
5534
+ const init = declPath.node.init;
5535
+ if (!init || !t17.isCallExpression(init)) return;
5536
+ if (!t17.isIdentifier(init.callee, { name: "createContext" })) return;
5537
+ if (!t17.isIdentifier(declPath.node.id)) return;
5538
+ const contextName = declPath.node.id.name;
5539
+ contextNames.set(contextName, contextName);
5540
+ const workflow = {
5541
+ name: contextName,
5542
+ fields: [],
5543
+ reducerActions: []
5544
+ };
5545
+ const typeParams = init.typeParameters;
5546
+ if (typeParams && t17.isTSTypeParameterInstantiation(typeParams)) {
5547
+ const typeArg = typeParams.params[0];
5548
+ if (t17.isTSTypeReference(typeArg) && t17.isIdentifier(typeArg.typeName)) {
5549
+ const interfaceName = typeArg.typeName.name;
5550
+ extractFieldsFromInterface3(path, interfaceName, workflow);
5551
+ }
5552
+ }
5553
+ if (init.arguments.length > 0 && t17.isObjectExpression(init.arguments[0])) {
5554
+ workflow.initialState = extractObjectLiteral2(init.arguments[0]);
5555
+ }
5556
+ contextWorkflows.push(workflow);
5557
+ },
5558
+ // Detect useReducer(reducer, initialState) and extract reducer cases
5559
+ CallExpression(callPath) {
5560
+ if (!t17.isIdentifier(callPath.node.callee, { name: "useReducer" })) return;
5561
+ const args = callPath.node.arguments;
5562
+ if (args.length < 1) return;
5563
+ const reducerArg = args[0];
5564
+ if (!t17.isIdentifier(reducerArg)) return;
5565
+ const reducerName = reducerArg.name;
5566
+ const actions = extractReducerActions(path, reducerName);
5567
+ if (contextWorkflows.length > 0) {
5568
+ const lastWorkflow = contextWorkflows[contextWorkflows.length - 1];
5569
+ lastWorkflow.reducerActions = actions;
5570
+ lastWorkflow.reducerName = reducerName;
5571
+ }
5572
+ }
5573
+ });
5574
+ if (contextWorkflows.length > 0) {
5575
+ if (!compilerState.metadata) compilerState.metadata = {};
5576
+ const meta = compilerState.metadata;
5577
+ meta.contextWorkflows = contextWorkflows;
5578
+ }
5579
+ }
5580
+ function extractFieldsFromInterface3(path, interfaceName, workflow) {
5581
+ path.traverse({
5582
+ TSInterfaceDeclaration(ifacePath) {
5583
+ if (!t17.isIdentifier(ifacePath.node.id, { name: interfaceName })) return;
5584
+ for (const prop of ifacePath.node.body.body) {
5585
+ if (!t17.isTSPropertySignature(prop)) continue;
5586
+ if (!t17.isIdentifier(prop.key)) continue;
5587
+ const field = {
5588
+ name: prop.key.name,
5589
+ type: extractTSType(prop.typeAnnotation),
5590
+ optional: prop.optional || false
5591
+ };
5592
+ workflow.fields.push(field);
5593
+ }
5594
+ }
5595
+ });
5596
+ }
5597
+ function extractTSType(annotation) {
5598
+ if (!annotation || !t17.isTSTypeAnnotation(annotation)) return "unknown";
5599
+ const typeNode = annotation.typeAnnotation;
5600
+ if (t17.isTSStringKeyword(typeNode)) return "string";
5601
+ if (t17.isTSNumberKeyword(typeNode)) return "number";
5602
+ if (t17.isTSBooleanKeyword(typeNode)) return "boolean";
5603
+ if (t17.isTSArrayType(typeNode)) return `${extractTSTypeNode(typeNode.elementType)}[]`;
5604
+ if (t17.isTSTypeReference(typeNode) && t17.isIdentifier(typeNode.typeName)) return typeNode.typeName.name;
5605
+ return "unknown";
5606
+ }
5607
+ function extractTSTypeNode(node) {
5608
+ if (t17.isTSStringKeyword(node)) return "string";
5609
+ if (t17.isTSNumberKeyword(node)) return "number";
5610
+ if (t17.isTSBooleanKeyword(node)) return "boolean";
5611
+ if (t17.isTSTypeReference(node) && t17.isIdentifier(node.typeName)) return node.typeName.name;
5612
+ return "unknown";
5613
+ }
5614
+ function extractReducerActions(path, reducerName) {
5615
+ const actions = [];
5616
+ path.traverse({
5617
+ FunctionDeclaration(funcPath) {
5618
+ if (!funcPath.node.id || funcPath.node.id.name !== reducerName) return;
5619
+ funcPath.traverse({
5620
+ SwitchStatement(switchPath) {
5621
+ for (const switchCase of switchPath.node.cases) {
5622
+ if (!switchCase.test) continue;
5623
+ if (t17.isStringLiteral(switchCase.test)) {
5624
+ actions.push({
5625
+ type: switchCase.test.value
5626
+ });
5627
+ }
5628
+ }
5629
+ }
5630
+ });
5631
+ }
5632
+ });
5633
+ return actions;
5634
+ }
5635
+ function extractObjectLiteral2(obj) {
5636
+ const result = {};
5637
+ for (const prop of obj.properties) {
5638
+ if (!t17.isObjectProperty(prop) || !t17.isIdentifier(prop.key)) continue;
5639
+ if (t17.isStringLiteral(prop.value)) result[prop.key.name] = prop.value.value;
5640
+ else if (t17.isNumericLiteral(prop.value)) result[prop.key.name] = prop.value.value;
5641
+ else if (t17.isBooleanLiteral(prop.value)) result[prop.key.name] = prop.value.value;
5642
+ else if (t17.isNullLiteral(prop.value)) result[prop.key.name] = null;
5643
+ else if (t17.isArrayExpression(prop.value)) result[prop.key.name] = [];
5644
+ else if (t17.isObjectExpression(prop.value)) result[prop.key.name] = extractObjectLiteral2(prop.value);
5645
+ }
5646
+ return result;
5647
+ }
5648
+ var t17;
5649
+ var init_context_extractor = __esm({
5650
+ "src/babel/extractors/context-extractor.ts"() {
5651
+ "use strict";
5652
+ t17 = __toESM(require("@babel/types"));
5653
+ }
5654
+ });
5655
+
5656
+ // src/babel/extractors/middleware-extractor.ts
5657
+ function hasMiddleware(path) {
5658
+ for (const node of path.node.body) {
5659
+ if (t18.isExportDefaultDeclaration(node)) {
5660
+ const decl = node.declaration;
5661
+ if (isDefineMiddlewareCall(decl) || isBuiltinFactoryCall(decl)) {
5662
+ return true;
5663
+ }
5664
+ }
5665
+ if (t18.isExportNamedDeclaration(node) && node.declaration) {
5666
+ if (t18.isVariableDeclaration(node.declaration)) {
5667
+ for (const declarator of node.declaration.declarations) {
5668
+ if (declarator.init && (isDefineMiddlewareCall(declarator.init) || isBuiltinFactoryCall(declarator.init))) {
5669
+ return true;
5670
+ }
5671
+ }
5672
+ }
5673
+ }
5674
+ if (t18.isVariableDeclaration(node)) {
5675
+ for (const declarator of node.declarations) {
5676
+ if (declarator.init && (isDefineMiddlewareCall(declarator.init) || isBuiltinFactoryCall(declarator.init))) {
5677
+ return true;
5678
+ }
5679
+ }
5680
+ }
5681
+ }
5682
+ return false;
5683
+ }
5684
+ function isDefineMiddlewareCall(node) {
5685
+ return t18.isCallExpression(node) && t18.isIdentifier(node.callee) && node.callee.name === "defineMiddleware";
5686
+ }
5687
+ function isBuiltinFactoryCall(node) {
5688
+ return t18.isCallExpression(node) && t18.isIdentifier(node.callee) && BUILTIN_FACTORIES.has(node.callee.name);
5689
+ }
5690
+ function extractMiddleware(path, state) {
5691
+ const compilerState = state;
5692
+ if (!compilerState.metadata) compilerState.metadata = {};
5693
+ const meta = compilerState.metadata;
5694
+ if (!meta.middleware) meta.middleware = [];
5695
+ const middlewareList = meta.middleware;
5696
+ path.traverse({
5697
+ CallExpression(callPath) {
5698
+ const callee = callPath.node.callee;
5699
+ if (!t18.isIdentifier(callee)) return;
5700
+ if (callee.name === "defineMiddleware") {
5701
+ const extracted = extractDefineMiddleware(callPath);
5702
+ if (extracted) middlewareList.push(extracted);
5703
+ } else if (BUILTIN_FACTORIES.has(callee.name)) {
5704
+ const extracted = extractBuiltinFactory(callee.name, callPath);
5705
+ if (extracted) middlewareList.push(extracted);
5706
+ }
5707
+ }
5708
+ });
5709
+ }
5710
+ function extractDefineMiddleware(callPath) {
5711
+ const args = callPath.node.arguments;
5712
+ if (args.length < 1 || !t18.isObjectExpression(args[0])) return null;
5713
+ const obj = args[0];
5714
+ let name = "unnamed";
5715
+ let match = [];
5716
+ let priority = 0;
5717
+ const before = [];
5718
+ const after = [];
5719
+ let hasAround = false;
5720
+ let config;
5721
+ for (const prop of obj.properties) {
5722
+ if (!t18.isObjectProperty(prop) && !t18.isObjectMethod(prop)) continue;
5723
+ const key = t18.isObjectProperty(prop) ? prop.key : prop.key;
5724
+ const keyName = t18.isIdentifier(key) ? key.name : t18.isStringLiteral(key) ? key.value : null;
5725
+ if (!keyName) continue;
5726
+ switch (keyName) {
5727
+ case "name":
5728
+ if (t18.isObjectProperty(prop) && t18.isStringLiteral(prop.value)) {
5729
+ name = prop.value.value;
5730
+ }
5731
+ break;
5732
+ case "match":
5733
+ if (t18.isObjectProperty(prop)) {
5734
+ if (t18.isStringLiteral(prop.value)) {
5735
+ match = [prop.value.value];
5736
+ } else if (t18.isArrayExpression(prop.value)) {
5737
+ match = prop.value.elements.filter((el) => t18.isStringLiteral(el)).map((el) => el.value);
5738
+ }
5739
+ }
5740
+ break;
5741
+ case "priority":
5742
+ if (t18.isObjectProperty(prop) && t18.isNumericLiteral(prop.value)) {
5743
+ priority = prop.value.value;
5744
+ }
5745
+ break;
5746
+ case "config":
5747
+ if (t18.isObjectProperty(prop) && t18.isObjectExpression(prop.value)) {
5748
+ config = extractConfigSchema(prop.value);
5749
+ }
5750
+ break;
5751
+ case "before":
5752
+ if (t18.isObjectMethod(prop)) {
5753
+ extractActionsFromBody(prop.body, before);
5754
+ } else if (t18.isObjectProperty(prop)) {
5755
+ const val = prop.value;
5756
+ if (t18.isFunctionExpression(val) || t18.isArrowFunctionExpression(val)) {
5757
+ const body = t18.isBlockStatement(val.body) ? val.body : null;
5758
+ if (body) extractActionsFromBody(body, before);
5759
+ }
5760
+ }
5761
+ break;
5762
+ case "after":
5763
+ if (t18.isObjectMethod(prop)) {
5764
+ extractActionsFromBody(prop.body, after);
5765
+ } else if (t18.isObjectProperty(prop)) {
5766
+ const val = prop.value;
5767
+ if (t18.isFunctionExpression(val) || t18.isArrowFunctionExpression(val)) {
5768
+ const body = t18.isBlockStatement(val.body) ? val.body : null;
5769
+ if (body) extractActionsFromBody(body, after);
5770
+ }
5771
+ }
5772
+ break;
5773
+ case "around":
5774
+ hasAround = true;
5775
+ break;
5776
+ }
5777
+ }
5778
+ return { name, match, priority, before, after, hasAround, config };
5779
+ }
5780
+ function extractBuiltinFactory(factoryName, callPath) {
5781
+ const args = callPath.node.arguments;
5782
+ const opts = args.length > 0 && t18.isObjectExpression(args[0]) ? args[0] : null;
5783
+ switch (factoryName) {
5784
+ case "withAuth": {
5785
+ let redirectTo;
5786
+ if (opts) {
5787
+ for (const prop of opts.properties) {
5788
+ if (t18.isObjectProperty(prop) && t18.isIdentifier(prop.key) && prop.key.name === "redirectTo" && t18.isStringLiteral(prop.value)) {
5789
+ redirectTo = prop.value.value;
5790
+ }
5791
+ }
5792
+ }
5793
+ return {
5794
+ name: "mm:auth",
5795
+ match: ["*:*:transition.execute"],
5796
+ priority: 90,
5797
+ before: [{ type: "block", args: { condition: "!ctx.actor.id", reason: redirectTo ? `redirect:${redirectTo}` : "Authentication required" } }],
5798
+ after: [],
5799
+ hasAround: false,
5800
+ factory: "withAuth"
5801
+ };
5802
+ }
5803
+ case "withAuditLog": {
5804
+ let level = "info";
5805
+ if (opts) {
5806
+ for (const prop of opts.properties) {
5807
+ if (t18.isObjectProperty(prop) && t18.isIdentifier(prop.key) && prop.key.name === "level" && t18.isStringLiteral(prop.value)) {
5808
+ level = prop.value.value;
5809
+ }
5810
+ }
5811
+ }
5812
+ return {
5813
+ name: "mm:audit-log",
5814
+ match: ["*:*:transition.execute"],
5815
+ priority: 0,
5816
+ before: [],
5817
+ after: [{ type: "modify", args: { __audit: { level } } }],
5818
+ hasAround: false,
5819
+ factory: "withAuditLog"
5820
+ };
5821
+ }
5822
+ case "withRateLimit": {
5823
+ let maxPerMinute = 60;
5824
+ if (opts) {
5825
+ for (const prop of opts.properties) {
5826
+ if (t18.isObjectProperty(prop) && t18.isIdentifier(prop.key) && prop.key.name === "maxPerMinute" && t18.isNumericLiteral(prop.value)) {
5827
+ maxPerMinute = prop.value.value;
5828
+ }
5829
+ }
5830
+ }
5831
+ return {
5832
+ name: "mm:rate-limit",
5833
+ match: ["*:*:transition.execute"],
5834
+ priority: 80,
5835
+ before: [{ type: "block", args: { condition: `counter >= ${maxPerMinute}`, reason: `Rate limit exceeded: ${maxPerMinute} per minute` } }],
5836
+ after: [],
5837
+ hasAround: false,
5838
+ config: { maxPerMinute: { type: "number", default: maxPerMinute } },
5839
+ factory: "withRateLimit"
5840
+ };
5841
+ }
5842
+ case "withValidation": {
5843
+ const rules = [];
5844
+ if (opts) {
5845
+ for (const prop of opts.properties) {
5846
+ if (t18.isObjectProperty(prop) && t18.isIdentifier(prop.key) && prop.key.name === "rules" && t18.isArrayExpression(prop.value)) {
5847
+ for (const el of prop.value.elements) {
5848
+ if (!t18.isObjectExpression(el)) continue;
5849
+ let fields = [];
5850
+ let check = "";
5851
+ let message = "";
5852
+ for (const rp of el.properties) {
5853
+ if (!t18.isObjectProperty(rp) || !t18.isIdentifier(rp.key)) continue;
5854
+ if (rp.key.name === "fields" && t18.isArrayExpression(rp.value)) {
5855
+ fields = rp.value.elements.filter((e) => t18.isStringLiteral(e)).map((e) => e.value);
5856
+ }
5857
+ if (rp.key.name === "check" && t18.isStringLiteral(rp.value)) {
5858
+ check = rp.value.value;
5859
+ }
5860
+ if (rp.key.name === "message" && t18.isStringLiteral(rp.value)) {
5861
+ message = rp.value.value;
5862
+ }
5863
+ }
5864
+ if (fields.length > 0) rules.push({ fields, check, message });
5865
+ }
5866
+ }
5867
+ }
5868
+ }
5869
+ return {
5870
+ name: "mm:validation",
5871
+ match: ["*:*:field.change"],
5872
+ priority: 70,
5873
+ before: rules.map((r) => ({ type: "validate", args: { fields: r.fields, check: r.check, message: r.message } })),
5874
+ after: [],
5875
+ hasAround: false,
5876
+ config: { rules: { type: "json", default: rules } },
5877
+ factory: "withValidation"
5878
+ };
5879
+ }
5880
+ case "withMetrics": {
5881
+ let endpoint;
5882
+ if (opts) {
5883
+ for (const prop of opts.properties) {
5884
+ if (t18.isObjectProperty(prop) && t18.isIdentifier(prop.key) && prop.key.name === "endpoint" && t18.isStringLiteral(prop.value)) {
5885
+ endpoint = prop.value.value;
5886
+ }
5887
+ }
5888
+ }
5889
+ return {
5890
+ name: "mm:metrics",
5891
+ match: ["*:*:*"],
5892
+ priority: 100,
5893
+ before: [],
5894
+ after: [],
5895
+ hasAround: true,
5896
+ config: { endpoint: { type: "string", default: endpoint } },
5897
+ factory: "withMetrics"
5898
+ };
5899
+ }
5900
+ default:
5901
+ return null;
5902
+ }
5903
+ }
5904
+ function extractActionsFromBody(body, actions) {
5905
+ for (const stmt of body.body) {
5906
+ if (t18.isExpressionStatement(stmt) && t18.isCallExpression(stmt.expression)) {
5907
+ const call = stmt.expression;
5908
+ if (t18.isMemberExpression(call.callee) && t18.isIdentifier(call.callee.property)) {
5909
+ const method = call.callee.property.name;
5910
+ if (method === "block" && call.arguments.length > 0) {
5911
+ const arg = call.arguments[0];
5912
+ actions.push({
5913
+ type: "block",
5914
+ args: { reason: t18.isStringLiteral(arg) ? arg.value : "<expression>" }
5915
+ });
5916
+ } else if (method === "modify" && call.arguments.length > 0) {
5917
+ const arg = call.arguments[0];
5918
+ actions.push({
5919
+ type: "modify",
5920
+ args: t18.isObjectExpression(arg) ? extractStaticObject(arg) : {}
5921
+ });
5922
+ } else if (method === "skip") {
5923
+ actions.push({ type: "skip" });
5924
+ }
5925
+ }
5926
+ }
5927
+ if (t18.isIfStatement(stmt)) {
5928
+ if (t18.isBlockStatement(stmt.consequent)) {
5929
+ extractActionsFromBody(stmt.consequent, actions);
5930
+ } else if (t18.isExpressionStatement(stmt.consequent)) {
5931
+ extractActionsFromBody(
5932
+ t18.blockStatement([stmt.consequent]),
5933
+ actions
5934
+ );
5935
+ }
5936
+ }
5937
+ }
5938
+ }
5939
+ function extractStaticObject(obj) {
5940
+ const result = {};
5941
+ for (const prop of obj.properties) {
5942
+ if (!t18.isObjectProperty(prop)) continue;
5943
+ const key = t18.isIdentifier(prop.key) ? prop.key.name : t18.isStringLiteral(prop.key) ? prop.key.value : null;
5944
+ if (!key) continue;
5945
+ const val = prop.value;
5946
+ if (t18.isStringLiteral(val)) result[key] = val.value;
5947
+ else if (t18.isNumericLiteral(val)) result[key] = val.value;
5948
+ else if (t18.isBooleanLiteral(val)) result[key] = val.value;
5949
+ else if (t18.isNullLiteral(val)) result[key] = null;
5950
+ else if (t18.isObjectExpression(val)) result[key] = extractStaticObject(val);
5951
+ else if (t18.isMemberExpression(val)) {
5952
+ result[key] = memberExprToString2(val);
5953
+ } else {
5954
+ result[key] = "<expression>";
5955
+ }
5956
+ }
5957
+ return result;
5958
+ }
5959
+ function memberExprToString2(expr) {
5960
+ const parts = [];
5961
+ let current = expr;
5962
+ while (t18.isMemberExpression(current)) {
5963
+ if (t18.isIdentifier(current.property)) {
5964
+ parts.unshift(current.property.name);
5965
+ }
5966
+ current = current.object;
5967
+ }
5968
+ if (t18.isIdentifier(current)) {
5969
+ parts.unshift(current.name);
5970
+ }
5971
+ return "$" + parts.join(".");
5972
+ }
5973
+ function extractConfigSchema(obj) {
5974
+ const schema = {};
5975
+ for (const prop of obj.properties) {
5976
+ if (!t18.isObjectProperty(prop) || !t18.isIdentifier(prop.key)) continue;
5977
+ if (!t18.isObjectExpression(prop.value)) continue;
5978
+ const entry = { type: "string" };
5979
+ for (const inner of prop.value.properties) {
5980
+ if (!t18.isObjectProperty(inner) || !t18.isIdentifier(inner.key)) continue;
5981
+ if (inner.key.name === "type" && t18.isStringLiteral(inner.value)) {
5982
+ entry.type = inner.value.value;
3623
5983
  }
3624
- if (parent && parent.isObjectProperty() && t15.isStringLiteral(parent.node.key)) {
3625
- slug = parent.node.key.value;
5984
+ if (inner.key.name === "default") {
5985
+ if (t18.isStringLiteral(inner.value)) entry.default = inner.value.value;
5986
+ else if (t18.isNumericLiteral(inner.value)) entry.default = inner.value.value;
5987
+ else if (t18.isBooleanLiteral(inner.value)) entry.default = inner.value.value;
3626
5988
  }
3627
- extractGrammarIsland(templatePath, state, slug);
3628
5989
  }
3629
- });
5990
+ schema[prop.key.name] = entry;
5991
+ }
5992
+ return schema;
3630
5993
  }
3631
- var t15, GRAMMAR_TAGS;
3632
- var init_grammar_island_extractor = __esm({
3633
- "src/babel/extractors/grammar-island-extractor.ts"() {
5994
+ var t18, BUILTIN_FACTORIES;
5995
+ var init_middleware_extractor = __esm({
5996
+ "src/babel/extractors/middleware-extractor.ts"() {
3634
5997
  "use strict";
3635
- t15 = __toESM(require("@babel/types"));
3636
- GRAMMAR_TAGS = /* @__PURE__ */ new Set(["cedar", "sql", "cron", "dmn", "graphql", "jsonpath"]);
5998
+ t18 = __toESM(require("@babel/types"));
5999
+ BUILTIN_FACTORIES = /* @__PURE__ */ new Set([
6000
+ "withAuth",
6001
+ "withAuditLog",
6002
+ "withRateLimit",
6003
+ "withValidation",
6004
+ "withMetrics"
6005
+ ]);
3637
6006
  }
3638
6007
  });
3639
6008
 
3640
- // src/babel/extractors/context-extractor.ts
3641
- function hasContextCreation(path) {
3642
- let found = false;
3643
- path.traverse({
3644
- CallExpression(callPath) {
3645
- if (t16.isIdentifier(callPath.node.callee, { name: "createContext" })) {
3646
- found = true;
3647
- callPath.stop();
6009
+ // src/babel/extractors/constraint-extractor.ts
6010
+ function hasConstraints(path) {
6011
+ for (const node of path.node.body) {
6012
+ if (t19.isExportNamedDeclaration(node) && node.declaration) {
6013
+ if (t19.isVariableDeclaration(node.declaration)) {
6014
+ for (const declarator of node.declaration.declarations) {
6015
+ if (declarator.init && isConstraintsCall(declarator.init)) {
6016
+ return true;
6017
+ }
6018
+ }
3648
6019
  }
3649
6020
  }
3650
- });
3651
- return found;
6021
+ if (t19.isVariableDeclaration(node)) {
6022
+ for (const declarator of node.declarations) {
6023
+ if (declarator.init && isConstraintsCall(declarator.init)) {
6024
+ return true;
6025
+ }
6026
+ }
6027
+ }
6028
+ if (t19.isExpressionStatement(node) && isConstraintsCall(node.expression)) {
6029
+ return true;
6030
+ }
6031
+ }
6032
+ return false;
3652
6033
  }
3653
- function extractContextWorkflows(path, state) {
6034
+ function isConstraintsCall(node) {
6035
+ return t19.isCallExpression(node) && t19.isIdentifier(node.callee) && node.callee.name === "constraints";
6036
+ }
6037
+ function extractConstraints(path, state) {
3654
6038
  const compilerState = state;
3655
- const contextWorkflows = [];
3656
- const contextNames = /* @__PURE__ */ new Map();
6039
+ if (!compilerState.metadata) compilerState.metadata = {};
6040
+ const meta = compilerState.metadata;
6041
+ if (!meta.constraints) meta.constraints = [];
6042
+ const constraintList = meta.constraints;
3657
6043
  path.traverse({
3658
- // Detect: const XContext = createContext(...)
3659
- VariableDeclarator(declPath) {
3660
- const init = declPath.node.init;
3661
- if (!init || !t16.isCallExpression(init)) return;
3662
- if (!t16.isIdentifier(init.callee, { name: "createContext" })) return;
3663
- if (!t16.isIdentifier(declPath.node.id)) return;
3664
- const contextName = declPath.node.id.name;
3665
- contextNames.set(contextName, contextName);
3666
- const workflow = {
3667
- name: contextName,
3668
- fields: [],
3669
- reducerActions: []
3670
- };
3671
- const typeParams = init.typeParameters;
3672
- if (typeParams && t16.isTSTypeParameterInstantiation(typeParams)) {
3673
- const typeArg = typeParams.params[0];
3674
- if (t16.isTSTypeReference(typeArg) && t16.isIdentifier(typeArg.typeName)) {
3675
- const interfaceName = typeArg.typeName.name;
3676
- extractFieldsFromInterface2(path, interfaceName, workflow);
3677
- }
3678
- }
3679
- if (init.arguments.length > 0 && t16.isObjectExpression(init.arguments[0])) {
3680
- workflow.initialState = extractObjectLiteral2(init.arguments[0]);
3681
- }
3682
- contextWorkflows.push(workflow);
3683
- },
3684
- // Detect useReducer(reducer, initialState) and extract reducer cases
3685
6044
  CallExpression(callPath) {
3686
- if (!t16.isIdentifier(callPath.node.callee, { name: "useReducer" })) return;
6045
+ const callee = callPath.node.callee;
6046
+ if (!t19.isIdentifier(callee) || callee.name !== "constraints") return;
3687
6047
  const args = callPath.node.arguments;
3688
- if (args.length < 1) return;
3689
- const reducerArg = args[0];
3690
- if (!t16.isIdentifier(reducerArg)) return;
3691
- const reducerName = reducerArg.name;
3692
- const actions = extractReducerActions(path, reducerName);
3693
- if (contextWorkflows.length > 0) {
3694
- const lastWorkflow = contextWorkflows[contextWorkflows.length - 1];
3695
- lastWorkflow.reducerActions = actions;
3696
- lastWorkflow.reducerName = reducerName;
6048
+ for (const arg of args) {
6049
+ if (t19.isStringLiteral(arg)) {
6050
+ constraintList.push({
6051
+ rule: arg.value,
6052
+ type: BUILTIN_CONSTRAINTS.has(arg.value) ? "builtin" : "custom"
6053
+ });
6054
+ }
3697
6055
  }
3698
6056
  }
3699
6057
  });
3700
- if (contextWorkflows.length > 0) {
3701
- if (!compilerState.metadata) compilerState.metadata = {};
3702
- const meta = compilerState.metadata;
3703
- meta.contextWorkflows = contextWorkflows;
6058
+ }
6059
+ var t19, BUILTIN_CONSTRAINTS;
6060
+ var init_constraint_extractor = __esm({
6061
+ "src/babel/extractors/constraint-extractor.ts"() {
6062
+ "use strict";
6063
+ t19 = __toESM(require("@babel/types"));
6064
+ BUILTIN_CONSTRAINTS = /* @__PURE__ */ new Set([
6065
+ "every state is reachable",
6066
+ "no deadlocks",
6067
+ "no unreachable states",
6068
+ "deterministic guards",
6069
+ "terminates",
6070
+ "no guard overlaps",
6071
+ "all roles defined",
6072
+ "all fields validated"
6073
+ ]);
6074
+ }
6075
+ });
6076
+
6077
+ // src/babel/extractors/actor-extractor.ts
6078
+ function hasActorConfig(path) {
6079
+ for (const node of path.node.body) {
6080
+ if (t20.isExportNamedDeclaration(node) && node.declaration) {
6081
+ if (t20.isVariableDeclaration(node.declaration)) {
6082
+ for (const declarator of node.declaration.declarations) {
6083
+ if (declarator.init && isActorCall(declarator.init)) {
6084
+ return true;
6085
+ }
6086
+ }
6087
+ }
6088
+ }
6089
+ if (t20.isVariableDeclaration(node)) {
6090
+ for (const declarator of node.declarations) {
6091
+ if (declarator.init && isActorCall(declarator.init)) {
6092
+ return true;
6093
+ }
6094
+ }
6095
+ }
6096
+ if (t20.isExpressionStatement(node) && isActorCall(node.expression)) {
6097
+ return true;
6098
+ }
3704
6099
  }
6100
+ return false;
6101
+ }
6102
+ function isActorCall(node) {
6103
+ return t20.isCallExpression(node) && t20.isIdentifier(node.callee) && (node.callee.name === "configureActor" || node.callee.name === "spawnActor");
3705
6104
  }
3706
- function extractFieldsFromInterface2(path, interfaceName, workflow) {
6105
+ function extractActorConfig(path, state) {
6106
+ const compilerState = state;
6107
+ if (!compilerState.metadata) compilerState.metadata = {};
6108
+ const meta = compilerState.metadata;
6109
+ if (!meta.actor) {
6110
+ meta.actor = {
6111
+ supervision: { strategy: "escalate" },
6112
+ mailbox: {},
6113
+ hierarchy: {},
6114
+ spawns: []
6115
+ };
6116
+ }
6117
+ const actorConfig = meta.actor;
3707
6118
  path.traverse({
3708
- TSInterfaceDeclaration(ifacePath) {
3709
- if (!t16.isIdentifier(ifacePath.node.id, { name: interfaceName })) return;
3710
- for (const prop of ifacePath.node.body.body) {
3711
- if (!t16.isTSPropertySignature(prop)) continue;
3712
- if (!t16.isIdentifier(prop.key)) continue;
3713
- const field = {
3714
- name: prop.key.name,
3715
- type: extractTSType(prop.typeAnnotation),
3716
- optional: prop.optional || false
3717
- };
3718
- workflow.fields.push(field);
6119
+ CallExpression(callPath) {
6120
+ const callee = callPath.node.callee;
6121
+ if (!t20.isIdentifier(callee)) return;
6122
+ if (callee.name === "configureActor") {
6123
+ extractConfigureActor(callPath, actorConfig);
6124
+ } else if (callee.name === "spawnActor") {
6125
+ extractSpawnActor(callPath, actorConfig);
3719
6126
  }
3720
6127
  }
3721
6128
  });
3722
6129
  }
3723
- function extractTSType(annotation) {
3724
- if (!annotation || !t16.isTSTypeAnnotation(annotation)) return "unknown";
3725
- const typeNode = annotation.typeAnnotation;
3726
- if (t16.isTSStringKeyword(typeNode)) return "string";
3727
- if (t16.isTSNumberKeyword(typeNode)) return "number";
3728
- if (t16.isTSBooleanKeyword(typeNode)) return "boolean";
3729
- if (t16.isTSArrayType(typeNode)) return `${extractTSTypeNode(typeNode.elementType)}[]`;
3730
- if (t16.isTSTypeReference(typeNode) && t16.isIdentifier(typeNode.typeName)) return typeNode.typeName.name;
3731
- return "unknown";
6130
+ function extractConfigureActor(callPath, actorConfig) {
6131
+ const args = callPath.node.arguments;
6132
+ if (args.length < 1 || !t20.isObjectExpression(args[0])) return;
6133
+ const obj = args[0];
6134
+ for (const prop of obj.properties) {
6135
+ if (!t20.isObjectProperty(prop) || !t20.isIdentifier(prop.key)) continue;
6136
+ switch (prop.key.name) {
6137
+ case "supervision":
6138
+ if (t20.isObjectExpression(prop.value)) {
6139
+ actorConfig.supervision = extractSupervision(prop.value);
6140
+ }
6141
+ break;
6142
+ case "mailbox":
6143
+ if (t20.isObjectExpression(prop.value)) {
6144
+ actorConfig.mailbox = extractMailbox(prop.value);
6145
+ }
6146
+ break;
6147
+ case "hierarchy":
6148
+ if (t20.isObjectExpression(prop.value)) {
6149
+ actorConfig.hierarchy = extractStaticObj(prop.value);
6150
+ }
6151
+ break;
6152
+ }
6153
+ }
3732
6154
  }
3733
- function extractTSTypeNode(node) {
3734
- if (t16.isTSStringKeyword(node)) return "string";
3735
- if (t16.isTSNumberKeyword(node)) return "number";
3736
- if (t16.isTSBooleanKeyword(node)) return "boolean";
3737
- if (t16.isTSTypeReference(node) && t16.isIdentifier(node.typeName)) return node.typeName.name;
3738
- return "unknown";
6155
+ function extractSpawnActor(callPath, actorConfig) {
6156
+ const args = callPath.node.arguments;
6157
+ if (args.length < 1 || !t20.isStringLiteral(args[0])) return;
6158
+ const spawn = { slug: args[0].value };
6159
+ if (args.length > 1 && t20.isObjectExpression(args[1])) {
6160
+ for (const prop of args[1].properties) {
6161
+ if (!t20.isObjectProperty(prop) || !t20.isIdentifier(prop.key)) continue;
6162
+ if (prop.key.name === "supervision" && t20.isObjectExpression(prop.value)) {
6163
+ spawn.supervision = extractSupervision(prop.value);
6164
+ } else if (prop.key.name === "blocking" && t20.isBooleanLiteral(prop.value)) {
6165
+ spawn.blocking = prop.value.value;
6166
+ }
6167
+ }
6168
+ }
6169
+ actorConfig.spawns.push(spawn);
3739
6170
  }
3740
- function extractReducerActions(path, reducerName) {
3741
- const actions = [];
3742
- path.traverse({
3743
- FunctionDeclaration(funcPath) {
3744
- if (!funcPath.node.id || funcPath.node.id.name !== reducerName) return;
3745
- funcPath.traverse({
3746
- SwitchStatement(switchPath) {
3747
- for (const switchCase of switchPath.node.cases) {
3748
- if (!switchCase.test) continue;
3749
- if (t16.isStringLiteral(switchCase.test)) {
3750
- actions.push({
3751
- type: switchCase.test.value
3752
- });
3753
- }
3754
- }
3755
- }
3756
- });
6171
+ function extractSupervision(obj) {
6172
+ const result = { strategy: "escalate" };
6173
+ for (const prop of obj.properties) {
6174
+ if (!t20.isObjectProperty(prop) || !t20.isIdentifier(prop.key)) continue;
6175
+ switch (prop.key.name) {
6176
+ case "strategy":
6177
+ if (t20.isStringLiteral(prop.value)) result.strategy = prop.value.value;
6178
+ break;
6179
+ case "maxRetries":
6180
+ if (t20.isNumericLiteral(prop.value)) result.maxRetries = prop.value.value;
6181
+ break;
6182
+ case "retryWindow":
6183
+ if (t20.isStringLiteral(prop.value)) result.retryWindow = prop.value.value;
6184
+ break;
6185
+ case "backoff":
6186
+ if (t20.isStringLiteral(prop.value)) result.backoff = prop.value.value;
6187
+ break;
3757
6188
  }
3758
- });
3759
- return actions;
6189
+ }
6190
+ return result;
3760
6191
  }
3761
- function extractObjectLiteral2(obj) {
6192
+ function extractMailbox(obj) {
3762
6193
  const result = {};
3763
6194
  for (const prop of obj.properties) {
3764
- if (!t16.isObjectProperty(prop) || !t16.isIdentifier(prop.key)) continue;
3765
- if (t16.isStringLiteral(prop.value)) result[prop.key.name] = prop.value.value;
3766
- else if (t16.isNumericLiteral(prop.value)) result[prop.key.name] = prop.value.value;
3767
- else if (t16.isBooleanLiteral(prop.value)) result[prop.key.name] = prop.value.value;
3768
- else if (t16.isNullLiteral(prop.value)) result[prop.key.name] = null;
3769
- else if (t16.isArrayExpression(prop.value)) result[prop.key.name] = [];
3770
- else if (t16.isObjectExpression(prop.value)) result[prop.key.name] = extractObjectLiteral2(prop.value);
6195
+ if (!t20.isObjectProperty(prop) || !t20.isIdentifier(prop.key)) continue;
6196
+ switch (prop.key.name) {
6197
+ case "capacity":
6198
+ if (t20.isNumericLiteral(prop.value)) result.capacity = prop.value.value;
6199
+ break;
6200
+ case "overflow":
6201
+ if (t20.isStringLiteral(prop.value)) result.overflow = prop.value.value;
6202
+ break;
6203
+ case "priority":
6204
+ if (t20.isStringLiteral(prop.value)) result.priority = prop.value.value;
6205
+ break;
6206
+ }
3771
6207
  }
3772
6208
  return result;
3773
6209
  }
3774
- var t16;
3775
- var init_context_extractor = __esm({
3776
- "src/babel/extractors/context-extractor.ts"() {
3777
- "use strict";
3778
- t16 = __toESM(require("@babel/types"));
6210
+ function extractStaticObj(obj) {
6211
+ const result = {};
6212
+ for (const prop of obj.properties) {
6213
+ if (!t20.isObjectProperty(prop) || !t20.isIdentifier(prop.key)) continue;
6214
+ const val = prop.value;
6215
+ if (t20.isStringLiteral(val)) result[prop.key.name] = val.value;
6216
+ else if (t20.isNumericLiteral(val)) result[prop.key.name] = val.value;
6217
+ else if (t20.isBooleanLiteral(val)) result[prop.key.name] = val.value;
6218
+ else if (t20.isNullLiteral(val)) result[prop.key.name] = null;
3779
6219
  }
3780
- });
3781
-
3782
- // ../player-core/dist/index.mjs
3783
- function normalizeCategory(primary, ...tags) {
3784
- const uniqueTags = [...new Set(tags.filter((t19) => t19 !== primary))];
3785
- uniqueTags.sort();
3786
- return [primary, ...uniqueTags];
3787
- }
3788
- var init_dist = __esm({
3789
- "../player-core/dist/index.mjs"() {
6220
+ return result;
6221
+ }
6222
+ var t20;
6223
+ var init_actor_extractor = __esm({
6224
+ "src/babel/extractors/actor-extractor.ts"() {
3790
6225
  "use strict";
6226
+ t20 = __toESM(require("@babel/types"));
3791
6227
  }
3792
6228
  });
3793
6229
 
@@ -3993,7 +6429,7 @@ function normalizeViewNode(node, fieldNames) {
3993
6429
  }
3994
6430
  return node;
3995
6431
  }
3996
- function toSnakeCase2(str) {
6432
+ function toSnakeCase3(str) {
3997
6433
  return str.replace(/([A-Z])/g, "_$1").toLowerCase().replace(/^_/, "");
3998
6434
  }
3999
6435
  function convertAction(action) {
@@ -4088,7 +6524,7 @@ function emitIR(extracted) {
4088
6524
  if (fields.length > 0) {
4089
6525
  const localDefaults = {};
4090
6526
  for (const f of fields) {
4091
- localDefaults[toSnakeCase2(f.name)] = f.default_value ?? null;
6527
+ localDefaults[toSnakeCase3(f.name)] = f.default_value ?? null;
4092
6528
  }
4093
6529
  if (!normalizedView.config) normalizedView.config = {};
4094
6530
  normalizedView.config.localDefaults = localDefaults;
@@ -4167,7 +6603,7 @@ function liftAction(action) {
4167
6603
  }
4168
6604
  return {
4169
6605
  slug: action.id,
4170
- category: normalizeCategory("expression", "mutation", action.type),
6606
+ category: (0, import_player_core.normalizeCategory)("expression", "mutation", action.type),
4171
6607
  parts: parts.length > 0 ? parts : void 0
4172
6608
  };
4173
6609
  }
@@ -4197,7 +6633,7 @@ function liftSchedule(during) {
4197
6633
  for (const action of during.actions) {
4198
6634
  parts.push({
4199
6635
  slug: "do",
4200
- category: normalizeCategory("expression", "mutation", action.type),
6636
+ category: (0, import_player_core.normalizeCategory)("expression", "mutation", action.type),
4201
6637
  parts: Object.entries(action.config || {}).map(([key, value]) => ({
4202
6638
  slug: key,
4203
6639
  category: ["atom"],
@@ -4207,7 +6643,7 @@ function liftSchedule(during) {
4207
6643
  }
4208
6644
  return {
4209
6645
  slug: during.id,
4210
- category: normalizeCategory("schedule", during.type),
6646
+ category: (0, import_player_core.normalizeCategory)("schedule", during.type),
4211
6647
  parts
4212
6648
  };
4213
6649
  }
@@ -4220,14 +6656,14 @@ function liftState(state) {
4220
6656
  if (state.on_enter && state.on_enter.length > 0) {
4221
6657
  parts.push({
4222
6658
  slug: "on_enter",
4223
- category: normalizeCategory("expression", "sequence"),
6659
+ category: (0, import_player_core.normalizeCategory)("expression", "sequence"),
4224
6660
  parts: state.on_enter.map(liftAction)
4225
6661
  });
4226
6662
  }
4227
6663
  if (state.on_exit && state.on_exit.length > 0) {
4228
6664
  parts.push({
4229
6665
  slug: "on_exit",
4230
- category: normalizeCategory("expression", "sequence"),
6666
+ category: (0, import_player_core.normalizeCategory)("expression", "sequence"),
4231
6667
  parts: state.on_exit.map(liftAction)
4232
6668
  });
4233
6669
  }
@@ -4238,7 +6674,7 @@ function liftState(state) {
4238
6674
  }
4239
6675
  return {
4240
6676
  slug: state.name,
4241
- category: normalizeCategory("state", ...tags),
6677
+ category: (0, import_player_core.normalizeCategory)("state", ...tags),
4242
6678
  parts: parts.length > 0 ? parts : void 0
4243
6679
  };
4244
6680
  }
@@ -4261,17 +6697,17 @@ function liftTransition(transition) {
4261
6697
  if (transition.actions && transition.actions.length > 0) {
4262
6698
  parts.push({
4263
6699
  slug: "actions",
4264
- category: normalizeCategory("expression", "sequence"),
6700
+ category: (0, import_player_core.normalizeCategory)("expression", "sequence"),
4265
6701
  parts: transition.actions.map(liftAction)
4266
6702
  });
4267
6703
  }
4268
6704
  if (transition.conditions && transition.conditions.length > 0) {
4269
6705
  parts.push({
4270
6706
  slug: "conditions",
4271
- category: normalizeCategory("expression", "guard"),
6707
+ category: (0, import_player_core.normalizeCategory)("expression", "guard"),
4272
6708
  parts: transition.conditions.map((c, i) => ({
4273
6709
  slug: `condition_${i}`,
4274
- category: normalizeCategory("expression", c.type || "condition"),
6710
+ category: (0, import_player_core.normalizeCategory)("expression", c.type || "condition"),
4275
6711
  parts: c.expression ? [{ slug: c.expression, category: ["binding"] }] : void 0
4276
6712
  }))
4277
6713
  });
@@ -4310,7 +6746,7 @@ function liftField(field) {
4310
6746
  }
4311
6747
  return {
4312
6748
  slug: field.name,
4313
- category: normalizeCategory("field", field.type),
6749
+ category: (0, import_player_core.normalizeCategory)("field", field.type),
4314
6750
  parts: parts.length > 0 ? parts : void 0
4315
6751
  };
4316
6752
  }
@@ -4333,20 +6769,20 @@ function liftView(node) {
4333
6769
  if (match) {
4334
6770
  parts.push({
4335
6771
  slug: key,
4336
- category: normalizeCategory("expression", "effect", "transition"),
6772
+ category: (0, import_player_core.normalizeCategory)("expression", "effect", "transition"),
4337
6773
  parts: [{ slug: match[1], category: ["ref"] }]
4338
6774
  });
4339
6775
  } else {
4340
6776
  parts.push({
4341
6777
  slug: key,
4342
- category: normalizeCategory("expression", "binding"),
6778
+ category: (0, import_player_core.normalizeCategory)("expression", "binding"),
4343
6779
  parts: [{ slug: String(expr), category: ["binding"] }]
4344
6780
  });
4345
6781
  }
4346
6782
  } else {
4347
6783
  parts.push({
4348
6784
  slug: key,
4349
- category: normalizeCategory("expression", "binding"),
6785
+ category: (0, import_player_core.normalizeCategory)("expression", "binding"),
4350
6786
  parts: [{ slug: String(expr), category: ["binding"] }]
4351
6787
  });
4352
6788
  }
@@ -4357,20 +6793,20 @@ function liftView(node) {
4357
6793
  if (eqMatch) {
4358
6794
  parts.push({
4359
6795
  slug: "visible_when",
4360
- category: normalizeCategory("expression", "guard"),
6796
+ category: (0, import_player_core.normalizeCategory)("expression", "guard"),
4361
6797
  parts: [{
4362
6798
  slug: "body",
4363
- category: normalizeCategory("expression", "eq"),
6799
+ category: (0, import_player_core.normalizeCategory)("expression", "eq"),
4364
6800
  parts: [
4365
- { slug: "lhs", category: normalizeCategory("expression", "path"), parts: [{ slug: eqMatch[1], category: ["binding"] }] },
4366
- { slug: "rhs", category: normalizeCategory("expression", "literal"), parts: [{ slug: eqMatch[2], category: ["literal"] }] }
6801
+ { slug: "lhs", category: (0, import_player_core.normalizeCategory)("expression", "path"), parts: [{ slug: eqMatch[1], category: ["binding"] }] },
6802
+ { slug: "rhs", category: (0, import_player_core.normalizeCategory)("expression", "literal"), parts: [{ slug: eqMatch[2], category: ["literal"] }] }
4367
6803
  ]
4368
6804
  }]
4369
6805
  });
4370
6806
  } else {
4371
6807
  parts.push({
4372
6808
  slug: "visible_when",
4373
- category: normalizeCategory("expression", "guard"),
6809
+ category: (0, import_player_core.normalizeCategory)("expression", "guard"),
4374
6810
  parts: [{ slug: node.visible_when, category: ["binding"] }]
4375
6811
  });
4376
6812
  }
@@ -4382,7 +6818,7 @@ function liftView(node) {
4382
6818
  }
4383
6819
  return {
4384
6820
  slug: node.id,
4385
- category: normalizeCategory("view", componentTag),
6821
+ category: (0, import_player_core.normalizeCategory)("view", componentTag),
4386
6822
  parts: parts.length > 0 ? parts : void 0
4387
6823
  };
4388
6824
  }
@@ -4403,7 +6839,7 @@ function emitCanonical(extracted, sourceFilename) {
4403
6839
  }
4404
6840
  parts.push({
4405
6841
  slug: "manifest",
4406
- category: normalizeCategory("meta", "manifest"),
6842
+ category: (0, import_player_core.normalizeCategory)("meta", "manifest"),
4407
6843
  parts: [
4408
6844
  {
4409
6845
  slug: "workflows",
@@ -4424,7 +6860,7 @@ function emitCanonical(extracted, sourceFilename) {
4424
6860
  let categoryArray;
4425
6861
  if (category.includes("/")) {
4426
6862
  const [primary, ...tags] = category.split("/");
4427
- categoryArray = normalizeCategory(primary, ...tags);
6863
+ categoryArray = (0, import_player_core.normalizeCategory)(primary, ...tags);
4428
6864
  } else {
4429
6865
  categoryArray = [category];
4430
6866
  }
@@ -4486,7 +6922,7 @@ function emitWorkflowDefinition(extracted) {
4486
6922
  on_event: (s.on_event || []).map(convertOnEvent)
4487
6923
  }));
4488
6924
  const fields = ir.fields.map((f) => ({
4489
- name: toSnakeCase2(f.name),
6925
+ name: toSnakeCase3(f.name),
4490
6926
  field_type: f.type,
4491
6927
  label: f.label || f.name.replace(/([A-Z])/g, " $1").replace(/^./, (c) => c.toUpperCase()),
4492
6928
  required: f.required || false,
@@ -4502,16 +6938,16 @@ function emitWorkflowDefinition(extracted) {
4502
6938
  ...f.editable_when && { editable_when: f.editable_when },
4503
6939
  ...f.state_home && { state_home: f.state_home }
4504
6940
  }));
4505
- const transitions = ir.transitions.map((t19) => ({
4506
- name: t19.name,
4507
- from: t19.from,
4508
- to: t19.to,
4509
- description: t19.description || "",
4510
- roles: t19.roles || [],
4511
- auto: t19.auto || false,
4512
- conditions: t19.conditions || [],
4513
- actions: (t19.actions || []).map(convertAction),
4514
- required_fields: t19.required_fields || [],
6941
+ const transitions = ir.transitions.map((t23) => ({
6942
+ name: t23.name,
6943
+ from: t23.from,
6944
+ to: t23.to,
6945
+ description: t23.description || "",
6946
+ roles: t23.roles || [],
6947
+ auto: t23.auto || false,
6948
+ conditions: t23.conditions || [],
6949
+ actions: (t23.actions || []).map(convertAction),
6950
+ required_fields: t23.required_fields || [],
4515
6951
  priority: 0
4516
6952
  }));
4517
6953
  const state_data = {};
@@ -4529,7 +6965,7 @@ function emitWorkflowDefinition(extracted) {
4529
6965
  if (extracted.fields.length > 0) {
4530
6966
  const localDefaults = {};
4531
6967
  for (const f of extracted.fields) {
4532
- localDefaults[toSnakeCase2(f.name)] = f.default_value ?? null;
6968
+ localDefaults[toSnakeCase3(f.name)] = f.default_value ?? null;
4533
6969
  }
4534
6970
  if (!viewRoot.config) viewRoot.config = {};
4535
6971
  viewRoot.config.localDefaults = localDefaults;
@@ -4587,11 +7023,11 @@ function compilerStateToWorkflow(state, metadata) {
4587
7023
  extraMetadata: Object.keys(extraMetadata).length > 0 ? extraMetadata : void 0
4588
7024
  };
4589
7025
  }
4590
- var PROP_RULES, COMPONENT_RENAMES, RENAME_EXTRA_CONFIG;
7026
+ var import_player_core, PROP_RULES, COMPONENT_RENAMES, RENAME_EXTRA_CONFIG;
4591
7027
  var init_pure_form_emitter = __esm({
4592
7028
  "src/babel/emitters/pure-form-emitter.ts"() {
4593
7029
  "use strict";
4594
- init_dist();
7030
+ import_player_core = require("@mindmatrix/player-core");
4595
7031
  init_transition_extractor();
4596
7032
  init_experience_transform();
4597
7033
  PROP_RULES = {
@@ -4621,8 +7057,8 @@ var init_pure_form_emitter = __esm({
4621
7057
  function resolveSlugArg(args, state) {
4622
7058
  if (args.length < 1) return null;
4623
7059
  const slugArg = args[0];
4624
- if (t17.isStringLiteral(slugArg)) return slugArg.value;
4625
- if (t17.isIdentifier(slugArg)) {
7060
+ if (t21.isStringLiteral(slugArg)) return slugArg.value;
7061
+ if (t21.isIdentifier(slugArg)) {
4626
7062
  const compilerState = state;
4627
7063
  const meta = compilerState.metadata;
4628
7064
  const resolvedSlugs = meta.__modelImportSlugs;
@@ -4648,43 +7084,43 @@ function extractQueryDataSource(path, state) {
4648
7084
  slug,
4649
7085
  query: "list"
4650
7086
  };
4651
- if (args.length > 1 && t17.isObjectExpression(args[1])) {
7087
+ if (args.length > 1 && t21.isObjectExpression(args[1])) {
4652
7088
  for (const prop of args[1].properties) {
4653
- if (!t17.isObjectProperty(prop) || !t17.isIdentifier(prop.key)) continue;
7089
+ if (!t21.isObjectProperty(prop) || !t21.isIdentifier(prop.key)) continue;
4654
7090
  const key = prop.key.name;
4655
7091
  const val = prop.value;
4656
7092
  switch (key) {
4657
7093
  case "limit":
4658
- if (t17.isNumericLiteral(val)) {
7094
+ if (t21.isNumericLiteral(val)) {
4659
7095
  dataSource.pageSize = val.value;
4660
7096
  dataSource.paginated = true;
4661
7097
  }
4662
7098
  break;
4663
7099
  case "orderBy":
4664
- if (t17.isStringLiteral(val)) {
7100
+ if (t21.isStringLiteral(val)) {
4665
7101
  dataSource.sort = val.value;
4666
7102
  }
4667
7103
  break;
4668
7104
  case "order":
4669
- if (t17.isStringLiteral(val) && dataSource.sort) {
7105
+ if (t21.isStringLiteral(val) && dataSource.sort) {
4670
7106
  dataSource.sort = `${dataSource.sort}:${val.value}`;
4671
7107
  }
4672
7108
  break;
4673
7109
  case "search":
4674
- if (t17.isStringLiteral(val)) {
7110
+ if (t21.isStringLiteral(val)) {
4675
7111
  dataSource.search = val.value;
4676
7112
  }
4677
7113
  break;
4678
7114
  case "searchFields":
4679
- if (t17.isArrayExpression(val)) {
4680
- dataSource.searchFields = val.elements.filter((el) => t17.isStringLiteral(el)).map((el) => el.value);
7115
+ if (t21.isArrayExpression(val)) {
7116
+ dataSource.searchFields = val.elements.filter((el) => t21.isStringLiteral(el)).map((el) => el.value);
4681
7117
  }
4682
7118
  break;
4683
7119
  case "filter":
4684
- if (t17.isObjectExpression(val)) {
7120
+ if (t21.isObjectExpression(val)) {
4685
7121
  const filter = {};
4686
7122
  for (const fp of val.properties) {
4687
- if (t17.isObjectProperty(fp) && t17.isIdentifier(fp.key) && t17.isStringLiteral(fp.value)) {
7123
+ if (t21.isObjectProperty(fp) && t21.isIdentifier(fp.key) && t21.isStringLiteral(fp.value)) {
4688
7124
  filter[fp.key.name] = fp.value.value;
4689
7125
  }
4690
7126
  }
@@ -4694,19 +7130,19 @@ function extractQueryDataSource(path, state) {
4694
7130
  }
4695
7131
  break;
4696
7132
  case "state":
4697
- if (t17.isStringLiteral(val)) {
7133
+ if (t21.isStringLiteral(val)) {
4698
7134
  if (!dataSource.filter) dataSource.filter = {};
4699
7135
  dataSource.filter.current_state = val.value;
4700
7136
  }
4701
7137
  break;
4702
7138
  case "groupBy":
4703
- if (t17.isStringLiteral(val)) {
7139
+ if (t21.isStringLiteral(val)) {
4704
7140
  dataSource.groupBy = val.value;
4705
7141
  }
4706
7142
  break;
4707
7143
  case "facets":
4708
- if (t17.isArrayExpression(val)) {
4709
- dataSource.facets = val.elements.filter((el) => t17.isStringLiteral(el)).map((el) => el.value);
7144
+ if (t21.isArrayExpression(val)) {
7145
+ dataSource.facets = val.elements.filter((el) => t21.isStringLiteral(el)).map((el) => el.value);
4710
7146
  }
4711
7147
  break;
4712
7148
  }
@@ -4730,17 +7166,17 @@ function extractMutationDataSource(path, state) {
4730
7166
  }
4731
7167
  function extractDuringAction(path, state) {
4732
7168
  const args = path.node.arguments;
4733
- if (args.length < 1 || !t17.isObjectExpression(args[0])) return;
7169
+ if (args.length < 1 || !t21.isObjectExpression(args[0])) return;
4734
7170
  const compilerState = state;
4735
7171
  const config = args[0];
4736
7172
  let stateName;
4737
7173
  let intervalMs = 1e3;
4738
7174
  for (const prop of config.properties) {
4739
- if (!t17.isObjectProperty(prop) || !t17.isIdentifier(prop.key)) continue;
4740
- if (prop.key.name === "state" && t17.isStringLiteral(prop.value)) {
7175
+ if (!t21.isObjectProperty(prop) || !t21.isIdentifier(prop.key)) continue;
7176
+ if (prop.key.name === "state" && t21.isStringLiteral(prop.value)) {
4741
7177
  stateName = prop.value.value;
4742
7178
  }
4743
- if (prop.key.name === "intervalMs" && t17.isNumericLiteral(prop.value)) {
7179
+ if (prop.key.name === "intervalMs" && t21.isNumericLiteral(prop.value)) {
4744
7180
  intervalMs = prop.value.value;
4745
7181
  }
4746
7182
  }
@@ -4766,7 +7202,7 @@ function extractDuringAction(path, state) {
4766
7202
  }
4767
7203
  function extractRoleDependency(path, state) {
4768
7204
  const args = path.node.arguments;
4769
- if (args.length < 1 || !t17.isStringLiteral(args[0])) return;
7205
+ if (args.length < 1 || !t21.isStringLiteral(args[0])) return;
4770
7206
  const compilerState = state;
4771
7207
  if (!compilerState.metadata) compilerState.metadata = {};
4772
7208
  const meta = compilerState.metadata;
@@ -4777,7 +7213,7 @@ function extractRoleDependency(path, state) {
4777
7213
  }
4778
7214
  function extractViewDependency(path, state) {
4779
7215
  const args = path.node.arguments;
4780
- if (args.length < 1 || !t17.isStringLiteral(args[0])) return;
7216
+ if (args.length < 1 || !t21.isStringLiteral(args[0])) return;
4781
7217
  const compilerState = state;
4782
7218
  if (!compilerState.metadata) compilerState.metadata = {};
4783
7219
  const meta = compilerState.metadata;
@@ -4794,7 +7230,7 @@ function extractParamsUsage(_path, state) {
4794
7230
  }
4795
7231
  function extractLibraryDependency(path, state) {
4796
7232
  const args = path.node.arguments;
4797
- if (args.length < 1 || !t17.isStringLiteral(args[0])) return;
7233
+ if (args.length < 1 || !t21.isStringLiteral(args[0])) return;
4798
7234
  const compilerState = state;
4799
7235
  if (!compilerState.metadata) compilerState.metadata = {};
4800
7236
  const meta = compilerState.metadata;
@@ -4867,15 +7303,15 @@ function createVisitor(options = {}) {
4867
7303
  }
4868
7304
  }
4869
7305
  const exportDeclaration = program.body.find(
4870
- (node) => t17.isExportNamedDeclaration(node) || t17.isExportDefaultDeclaration(node)
7306
+ (node) => t21.isExportNamedDeclaration(node) || t21.isExportDefaultDeclaration(node)
4871
7307
  );
4872
7308
  if (exportDeclaration) {
4873
7309
  if (exportDeclaration.leadingComments) {
4874
7310
  extractMetadataFromComments(exportDeclaration.leadingComments, compilerState.metadata);
4875
7311
  }
4876
- if (t17.isExportNamedDeclaration(exportDeclaration)) {
7312
+ if (t21.isExportNamedDeclaration(exportDeclaration)) {
4877
7313
  const declaration = exportDeclaration.declaration;
4878
- if (t17.isFunctionDeclaration(declaration)) {
7314
+ if (t21.isFunctionDeclaration(declaration)) {
4879
7315
  if (declaration.id) {
4880
7316
  compilerState.metadata.name = declaration.id.name;
4881
7317
  }
@@ -4883,16 +7319,16 @@ function createVisitor(options = {}) {
4883
7319
  extractMetadataFromComments(declaration.leadingComments, compilerState.metadata);
4884
7320
  }
4885
7321
  }
4886
- } else if (t17.isExportDefaultDeclaration(exportDeclaration)) {
7322
+ } else if (t21.isExportDefaultDeclaration(exportDeclaration)) {
4887
7323
  const declaration = exportDeclaration.declaration;
4888
- if (t17.isFunctionDeclaration(declaration)) {
7324
+ if (t21.isFunctionDeclaration(declaration)) {
4889
7325
  if (declaration.id) {
4890
7326
  compilerState.metadata.name = declaration.id.name;
4891
7327
  }
4892
7328
  if (declaration.leadingComments) {
4893
7329
  extractMetadataFromComments(declaration.leadingComments, compilerState.metadata);
4894
7330
  }
4895
- } else if (t17.isIdentifier(declaration)) {
7331
+ } else if (t21.isIdentifier(declaration)) {
4896
7332
  compilerState.metadata.name = declaration.name;
4897
7333
  }
4898
7334
  }
@@ -4903,7 +7339,13 @@ function createVisitor(options = {}) {
4903
7339
  compilerState.metadata.__slugAutoFallback = true;
4904
7340
  }
4905
7341
  Object.assign(state, compilerState);
4906
- if (isModelFile(_path, state.filename)) {
7342
+ if (isImperativeWorkflowFile(_path, state.filename)) {
7343
+ extractImperativeWorkflow(_path, state);
7344
+ state.__isModelFile = true;
7345
+ if (!compilerState.metadata.category) {
7346
+ compilerState.metadata.category = "workflow";
7347
+ }
7348
+ } else if (isModelFile(_path, state.filename)) {
4907
7349
  extractModelFile(_path, state);
4908
7350
  state.__isModelFile = true;
4909
7351
  if (!compilerState.metadata.category) {
@@ -4914,6 +7356,15 @@ function createVisitor(options = {}) {
4914
7356
  if (hasContextCreation(_path)) {
4915
7357
  extractContextWorkflows(_path, state);
4916
7358
  }
7359
+ if (hasMiddleware(_path)) {
7360
+ extractMiddleware(_path, state);
7361
+ }
7362
+ if (hasConstraints(_path)) {
7363
+ extractConstraints(_path, state);
7364
+ }
7365
+ if (hasActorConfig(_path)) {
7366
+ extractActorConfig(_path, state);
7367
+ }
4917
7368
  if (isServerActionFile(state.filename)) {
4918
7369
  extractServerActions(_path, state);
4919
7370
  state.__isServerActionFile = true;
@@ -4949,7 +7400,7 @@ function createVisitor(options = {}) {
4949
7400
  // Main hook extraction dispatcher
4950
7401
  CallExpression(path, state) {
4951
7402
  const callee = path.node.callee;
4952
- if (!t17.isIdentifier(callee)) return;
7403
+ if (!t21.isIdentifier(callee)) return;
4953
7404
  const compilerState = state;
4954
7405
  const hookName = callee.name;
4955
7406
  if (mode === "strict" && STRICT_BANNED_HOOKS[hookName]) {
@@ -5041,7 +7492,7 @@ function createVisitor(options = {}) {
5041
7492
  if (!meta.__modelImports) meta.__modelImports = {};
5042
7493
  const imports = meta.__modelImports;
5043
7494
  for (const specifier of path.node.specifiers) {
5044
- if (t17.isImportDefaultSpecifier(specifier) || t17.isImportSpecifier(specifier)) {
7495
+ if (t21.isImportDefaultSpecifier(specifier) || t21.isImportSpecifier(specifier)) {
5045
7496
  imports[specifier.local.name] = source;
5046
7497
  }
5047
7498
  }
@@ -5074,8 +7525,8 @@ function createVisitor(options = {}) {
5074
7525
  if (!compilerState.metadata) return;
5075
7526
  const id = path.node.id;
5076
7527
  const init = path.node.init;
5077
- if (t17.isArrayPattern(id)) return;
5078
- if (!t17.isIdentifier(id) || !init || !t17.isExpression(init)) return;
7528
+ if (t21.isArrayPattern(id)) return;
7529
+ if (!t21.isIdentifier(id) || !init || !t21.isExpression(init)) return;
5079
7530
  const parentFn = path.getFunctionParent();
5080
7531
  if (!parentFn) return;
5081
7532
  const parentNode = parentFn.parentPath;
@@ -5083,17 +7534,17 @@ function createVisitor(options = {}) {
5083
7534
  let isExportedByName = false;
5084
7535
  if (!isExportedDirectly && parentNode?.isVariableDeclarator()) {
5085
7536
  const varId = parentNode.node.id;
5086
- if (t17.isIdentifier(varId)) {
7537
+ if (t21.isIdentifier(varId)) {
5087
7538
  isExportedByName = varId.name === compilerState.metadata?.name;
5088
7539
  }
5089
7540
  }
5090
7541
  if (!isExportedDirectly && !isExportedByName) return;
5091
- if (t17.isCallExpression(init) && t17.isIdentifier(init.callee)) {
7542
+ if (t21.isCallExpression(init) && t21.isIdentifier(init.callee)) {
5092
7543
  const callee = init.callee.name;
5093
7544
  if (callee === "useQuery") {
5094
- registerDerivedVar(id.name, t17.optionalMemberExpression(
5095
- t17.identifier("$instance"),
5096
- t17.identifier(id.name),
7545
+ registerDerivedVar(id.name, t21.optionalMemberExpression(
7546
+ t21.identifier("$instance"),
7547
+ t21.identifier(id.name),
5097
7548
  false,
5098
7549
  // computed
5099
7550
  true
@@ -5102,23 +7553,23 @@ function createVisitor(options = {}) {
5102
7553
  return;
5103
7554
  }
5104
7555
  if (callee === "useMutation") {
5105
- registerDerivedVar(id.name, t17.memberExpression(
5106
- t17.identifier("$action"),
5107
- t17.identifier("transition")
7556
+ registerDerivedVar(id.name, t21.memberExpression(
7557
+ t21.identifier("$action"),
7558
+ t21.identifier("transition")
5108
7559
  ));
5109
7560
  return;
5110
7561
  }
5111
7562
  if (callee === "useServerAction") {
5112
- registerDerivedVar(id.name, t17.memberExpression(
5113
- t17.identifier("$action"),
5114
- t17.identifier("serverAction")
7563
+ registerDerivedVar(id.name, t21.memberExpression(
7564
+ t21.identifier("$action"),
7565
+ t21.identifier("serverAction")
5115
7566
  ));
5116
7567
  return;
5117
7568
  }
5118
7569
  if (callee === "useServerState") {
5119
- registerDerivedVar(id.name, t17.optionalMemberExpression(
5120
- t17.identifier("$instance"),
5121
- t17.identifier("serverState"),
7570
+ registerDerivedVar(id.name, t21.optionalMemberExpression(
7571
+ t21.identifier("$instance"),
7572
+ t21.identifier("serverState"),
5122
7573
  false,
5123
7574
  true
5124
7575
  ));
@@ -5126,12 +7577,12 @@ function createVisitor(options = {}) {
5126
7577
  }
5127
7578
  if (callee === "useMemo" && init.arguments.length >= 1) {
5128
7579
  const callback = init.arguments[0];
5129
- if (t17.isArrowFunctionExpression(callback)) {
5130
- if (t17.isExpression(callback.body)) {
7580
+ if (t21.isArrowFunctionExpression(callback)) {
7581
+ if (t21.isExpression(callback.body)) {
5131
7582
  registerDerivedVar(id.name, callback.body);
5132
- } else if (t17.isBlockStatement(callback.body)) {
5133
- const retStmt = callback.body.body.find((s) => t17.isReturnStatement(s));
5134
- if (retStmt?.argument && t17.isExpression(retStmt.argument)) {
7583
+ } else if (t21.isBlockStatement(callback.body)) {
7584
+ const retStmt = callback.body.body.find((s) => t21.isReturnStatement(s));
7585
+ if (retStmt?.argument && t21.isExpression(retStmt.argument)) {
5135
7586
  registerDerivedVar(id.name, retStmt.argument);
5136
7587
  }
5137
7588
  }
@@ -5146,7 +7597,7 @@ function createVisitor(options = {}) {
5146
7597
  // Only extract from the exported component function's direct return,
5147
7598
  // not from nested callbacks (Each render functions, helper components, etc.).
5148
7599
  ReturnStatement(path, state) {
5149
- if (!t17.isJSXElement(path.node.argument) && !t17.isJSXFragment(path.node.argument)) return;
7600
+ if (!t21.isJSXElement(path.node.argument) && !t21.isJSXFragment(path.node.argument)) return;
5150
7601
  const parentFn = path.getFunctionParent();
5151
7602
  if (!parentFn) return;
5152
7603
  const parentNode = parentFn.parentPath;
@@ -5154,7 +7605,7 @@ function createVisitor(options = {}) {
5154
7605
  let isExportedByName = false;
5155
7606
  if (!isExportedDirectly && parentNode?.isVariableDeclarator()) {
5156
7607
  const varId = parentNode.node.id;
5157
- if (t17.isIdentifier(varId)) {
7608
+ if (t21.isIdentifier(varId)) {
5158
7609
  isExportedByName = varId.name === state.metadata?.name;
5159
7610
  }
5160
7611
  }
@@ -5164,11 +7615,11 @@ function createVisitor(options = {}) {
5164
7615
  }
5165
7616
  };
5166
7617
  }
5167
- var t17, STRICT_BANNED_HOOKS;
7618
+ var t21, STRICT_BANNED_HOOKS;
5168
7619
  var init_visitor = __esm({
5169
7620
  "src/babel/visitor.ts"() {
5170
7621
  "use strict";
5171
- t17 = __toESM(require("@babel/types"));
7622
+ t21 = __toESM(require("@babel/types"));
5172
7623
  init_state_extractor();
5173
7624
  init_effect_extractor();
5174
7625
  init_transition_extractor();
@@ -5179,11 +7630,15 @@ var init_visitor = __esm({
5179
7630
  init_computed_extractor();
5180
7631
  init_transition_effect_extractor();
5181
7632
  init_model_extractor();
7633
+ init_flow_extractor();
5182
7634
  init_server_action_extractor();
5183
7635
  init_server_action_hook_extractor();
5184
7636
  init_server_state_extractor();
5185
7637
  init_grammar_island_extractor();
5186
7638
  init_context_extractor();
7639
+ init_middleware_extractor();
7640
+ init_constraint_extractor();
7641
+ init_actor_extractor();
5187
7642
  init_pure_form_emitter();
5188
7643
  STRICT_BANNED_HOOKS = {
5189
7644
  useEffect: "STRICT_USE_EFFECT",
@@ -5461,7 +7916,7 @@ function compileModel(filename, source, options = {}) {
5461
7916
  ir,
5462
7917
  interfaceName,
5463
7918
  fieldNames: ir.fields.map((f) => f.name),
5464
- transitionNames: ir.transitions.map((t19) => t19.name),
7919
+ transitionNames: ir.transitions.map((t23) => t23.name),
5465
7920
  stateNames: ir.states.map((s) => s.name),
5466
7921
  hasFieldOptions: Object.keys(rawFieldOptions).length > 0,
5467
7922
  fieldOptions: rawFieldOptions
@@ -5881,7 +8336,7 @@ function extractAction(source, filename) {
5881
8336
  const fields = params.map((p) => paramToField(p));
5882
8337
  const parameterMap = /* @__PURE__ */ new Map();
5883
8338
  for (const p of params) {
5884
- const snakeName = toSnakeCase3(p.name);
8339
+ const snakeName = toSnakeCase4(p.name);
5885
8340
  if (snakeName !== p.name) {
5886
8341
  parameterMap.set(p.name, snakeName);
5887
8342
  }
@@ -5901,7 +8356,7 @@ function extractAction(source, filename) {
5901
8356
  }
5902
8357
  if (isAsync) {
5903
8358
  const segments = splitAtAwaits(body.body);
5904
- const hasAwaits = segments.some((s) => s.kind === "await");
8359
+ const hasAwaits = segments.some((s) => s.kind !== "sync");
5905
8360
  if (hasAwaits) {
5906
8361
  const rewritten = rewriteAwaitReferences(segments);
5907
8362
  const { states: states2, transitions: transitions2, bodyIsPure } = generateMultiStateIR(rewritten, warnings, parameterMap);
@@ -5976,10 +8431,10 @@ function extractAction(source, filename) {
5976
8431
  function findDefaultExportedFunction(ast) {
5977
8432
  const topLevelVars = /* @__PURE__ */ new Map();
5978
8433
  for (const node of ast.program.body) {
5979
- if (t18.isVariableDeclaration(node)) {
8434
+ if (t22.isVariableDeclaration(node)) {
5980
8435
  for (const decl of node.declarations) {
5981
- if (t18.isIdentifier(decl.id) && decl.init) {
5982
- if (t18.isArrowFunctionExpression(decl.init) || t18.isFunctionExpression(decl.init)) {
8436
+ if (t22.isIdentifier(decl.id) && decl.init) {
8437
+ if (t22.isArrowFunctionExpression(decl.init) || t22.isFunctionExpression(decl.init)) {
5983
8438
  topLevelVars.set(decl.id.name, decl.init);
5984
8439
  }
5985
8440
  }
@@ -5987,19 +8442,19 @@ function findDefaultExportedFunction(ast) {
5987
8442
  }
5988
8443
  }
5989
8444
  for (const node of ast.program.body) {
5990
- if (t18.isExportDefaultDeclaration(node)) {
8445
+ if (t22.isExportDefaultDeclaration(node)) {
5991
8446
  const decl = node.declaration;
5992
- if (t18.isFunctionDeclaration(decl) && decl.body) {
8447
+ if (t22.isFunctionDeclaration(decl) && decl.body) {
5993
8448
  const name = decl.id?.name ?? inferNameFromFile(decl) ?? "action";
5994
8449
  return extractFromFunction(name, decl.params, decl.body, decl.returnType, decl.async);
5995
8450
  }
5996
- if (t18.isArrowFunctionExpression(decl) || t18.isFunctionExpression(decl)) {
5997
- const name = t18.isFunctionExpression(decl) && decl.id ? decl.id.name : "action";
8451
+ if (t22.isArrowFunctionExpression(decl) || t22.isFunctionExpression(decl)) {
8452
+ const name = t22.isFunctionExpression(decl) && decl.id ? decl.id.name : "action";
5998
8453
  const body = ensureBlock(decl.body);
5999
8454
  if (!body) return null;
6000
8455
  return extractFromFunction(name, decl.params, body, decl.returnType, decl.async);
6001
8456
  }
6002
- if (t18.isIdentifier(decl)) {
8457
+ if (t22.isIdentifier(decl)) {
6003
8458
  const fn = topLevelVars.get(decl.name);
6004
8459
  if (fn) {
6005
8460
  const body = ensureBlock(fn.body);
@@ -6013,28 +8468,28 @@ function findDefaultExportedFunction(ast) {
6013
8468
  }
6014
8469
  function extractFromFunction(name, params, body, returnType, isAsync = false) {
6015
8470
  const extracted = params.map((p) => extractParam(p));
6016
- const returnTypeAnnotation = returnType && t18.isTSTypeAnnotation(returnType) ? serializeTSType(returnType.typeAnnotation) : void 0;
8471
+ const returnTypeAnnotation = returnType && t22.isTSTypeAnnotation(returnType) ? serializeTSType(returnType.typeAnnotation) : void 0;
6017
8472
  return { name, params: extracted, body, returnTypeAnnotation, isAsync };
6018
8473
  }
6019
8474
  function ensureBlock(body) {
6020
- if (t18.isBlockStatement(body)) return body;
6021
- const ret = t18.returnStatement(body);
6022
- return t18.blockStatement([ret]);
8475
+ if (t22.isBlockStatement(body)) return body;
8476
+ const ret = t22.returnStatement(body);
8477
+ return t22.blockStatement([ret]);
6023
8478
  }
6024
8479
  function inferNameFromFile(_node) {
6025
8480
  return null;
6026
8481
  }
6027
8482
  function extractParam(param) {
6028
- if (t18.isIdentifier(param)) {
8483
+ if (t22.isIdentifier(param)) {
6029
8484
  return {
6030
8485
  name: param.name,
6031
8486
  typeAnnotation: param.typeAnnotation ? param.typeAnnotation.typeAnnotation : null,
6032
8487
  optional: param.optional ?? false
6033
8488
  };
6034
8489
  }
6035
- if (t18.isAssignmentPattern(param)) {
8490
+ if (t22.isAssignmentPattern(param)) {
6036
8491
  const inner = param.left;
6037
- if (t18.isIdentifier(inner)) {
8492
+ if (t22.isIdentifier(inner)) {
6038
8493
  return {
6039
8494
  name: inner.name,
6040
8495
  typeAnnotation: inner.typeAnnotation ? inner.typeAnnotation.typeAnnotation : null,
@@ -6043,10 +8498,10 @@ function extractParam(param) {
6043
8498
  };
6044
8499
  }
6045
8500
  }
6046
- if (t18.isRestElement(param)) {
8501
+ if (t22.isRestElement(param)) {
6047
8502
  const arg = param.argument;
6048
8503
  return {
6049
- name: t18.isIdentifier(arg) ? arg.name : "rest",
8504
+ name: t22.isIdentifier(arg) ? arg.name : "rest",
6050
8505
  typeAnnotation: null,
6051
8506
  optional: true
6052
8507
  };
@@ -6056,7 +8511,7 @@ function extractParam(param) {
6056
8511
  function paramToField(param) {
6057
8512
  const fieldType = param.typeAnnotation ? tsTypeToFieldType2(param.typeAnnotation) : "text";
6058
8513
  const field = {
6059
- name: toSnakeCase3(param.name),
8514
+ name: toSnakeCase4(param.name),
6060
8515
  type: fieldType,
6061
8516
  required: !param.optional
6062
8517
  };
@@ -6067,34 +8522,34 @@ function paramToField(param) {
6067
8522
  }
6068
8523
  function extractLiteralDefault(expr) {
6069
8524
  if (!expr) return void 0;
6070
- if (t18.isStringLiteral(expr)) return expr.value;
6071
- if (t18.isNumericLiteral(expr)) return expr.value;
6072
- if (t18.isBooleanLiteral(expr)) return expr.value;
6073
- if (t18.isNullLiteral(expr)) return null;
6074
- if (t18.isArrayExpression(expr) && expr.elements.length === 0) return [];
6075
- if (t18.isObjectExpression(expr) && expr.properties.length === 0) return {};
8525
+ if (t22.isStringLiteral(expr)) return expr.value;
8526
+ if (t22.isNumericLiteral(expr)) return expr.value;
8527
+ if (t22.isBooleanLiteral(expr)) return expr.value;
8528
+ if (t22.isNullLiteral(expr)) return null;
8529
+ if (t22.isArrayExpression(expr) && expr.elements.length === 0) return [];
8530
+ if (t22.isObjectExpression(expr) && expr.properties.length === 0) return {};
6076
8531
  return void 0;
6077
8532
  }
6078
8533
  function tsTypeToFieldType2(tsType) {
6079
- if (t18.isTSStringKeyword(tsType)) return "text";
6080
- if (t18.isTSNumberKeyword(tsType)) return "number";
6081
- if (t18.isTSBooleanKeyword(tsType)) return "boolean";
6082
- if (t18.isTSObjectKeyword(tsType)) return "json";
6083
- if (t18.isTSAnyKeyword(tsType) || t18.isTSUnknownKeyword(tsType)) return "json";
6084
- if (t18.isTSArrayType(tsType)) return "json";
6085
- if (t18.isTSUnionType(tsType)) {
8534
+ if (t22.isTSStringKeyword(tsType)) return "text";
8535
+ if (t22.isTSNumberKeyword(tsType)) return "number";
8536
+ if (t22.isTSBooleanKeyword(tsType)) return "boolean";
8537
+ if (t22.isTSObjectKeyword(tsType)) return "json";
8538
+ if (t22.isTSAnyKeyword(tsType) || t22.isTSUnknownKeyword(tsType)) return "json";
8539
+ if (t22.isTSArrayType(tsType)) return "json";
8540
+ if (t22.isTSUnionType(tsType)) {
6086
8541
  const nonNullable = tsType.types.filter(
6087
- (t22) => !t18.isTSNullKeyword(t22) && !t18.isTSUndefinedKeyword(t22)
8542
+ (t23) => !t22.isTSNullKeyword(t23) && !t22.isTSUndefinedKeyword(t23)
6088
8543
  );
6089
8544
  if (nonNullable.length === 1) {
6090
8545
  return tsTypeToFieldType2(nonNullable[0]);
6091
8546
  }
6092
- if (nonNullable.every((t22) => t18.isTSLiteralType(t22) && t18.isStringLiteral(t22.literal))) {
8547
+ if (nonNullable.every((t23) => t22.isTSLiteralType(t23) && t22.isStringLiteral(t23.literal))) {
6093
8548
  return "select";
6094
8549
  }
6095
8550
  return "text";
6096
8551
  }
6097
- if (t18.isTSTypeReference(tsType) && t18.isIdentifier(tsType.typeName)) {
8552
+ if (t22.isTSTypeReference(tsType) && t22.isIdentifier(tsType.typeName)) {
6098
8553
  const name = tsType.typeName.name;
6099
8554
  if (name === "Date") return "datetime";
6100
8555
  if (name === "string") return "text";
@@ -6104,16 +8559,16 @@ function tsTypeToFieldType2(tsType) {
6104
8559
  return "text";
6105
8560
  }
6106
8561
  function serializeTSType(tsType) {
6107
- if (t18.isTSStringKeyword(tsType)) return "string";
6108
- if (t18.isTSNumberKeyword(tsType)) return "number";
6109
- if (t18.isTSBooleanKeyword(tsType)) return "boolean";
6110
- if (t18.isTSVoidKeyword(tsType)) return "void";
6111
- if (t18.isTSAnyKeyword(tsType)) return "any";
6112
- if (t18.isTSTypeReference(tsType) && t18.isIdentifier(tsType.typeName)) {
8562
+ if (t22.isTSStringKeyword(tsType)) return "string";
8563
+ if (t22.isTSNumberKeyword(tsType)) return "number";
8564
+ if (t22.isTSBooleanKeyword(tsType)) return "boolean";
8565
+ if (t22.isTSVoidKeyword(tsType)) return "void";
8566
+ if (t22.isTSAnyKeyword(tsType)) return "any";
8567
+ if (t22.isTSTypeReference(tsType) && t22.isIdentifier(tsType.typeName)) {
6113
8568
  return tsType.typeName.name;
6114
8569
  }
6115
- if (t18.isTSArrayType(tsType)) return `${serializeTSType(tsType.elementType)}[]`;
6116
- if (t18.isTSPromiseType(tsType)) {
8570
+ if (t22.isTSArrayType(tsType)) return `${serializeTSType(tsType.elementType)}[]`;
8571
+ if (t22.isTSPromiseType(tsType)) {
6117
8572
  return `Promise<${tsType.typeParameter ? serializeTSType(tsType.typeParameter.params[0]) : "unknown"}>`;
6118
8573
  }
6119
8574
  return "unknown";
@@ -6123,6 +8578,56 @@ function splitAtAwaits(body) {
6123
8578
  let current = [];
6124
8579
  let index = 0;
6125
8580
  for (const stmt of body) {
8581
+ if (t22.isTryStatement(stmt) && containsAwait(stmt.block)) {
8582
+ if (current.length > 0) {
8583
+ segments.push({ index: index++, kind: "sync", statements: current });
8584
+ current = [];
8585
+ }
8586
+ const trySegs = splitAtAwaits(stmt.block.body);
8587
+ const catchStmts = stmt.handler?.body.body ?? [];
8588
+ const catchParam = stmt.handler?.param && t22.isIdentifier(stmt.handler.param) ? stmt.handler.param.name : "error";
8589
+ segments.push({
8590
+ index: index++,
8591
+ kind: "try_catch",
8592
+ statements: [stmt],
8593
+ trySegments: trySegs,
8594
+ catchStatements: catchStmts,
8595
+ catchParam
8596
+ });
8597
+ continue;
8598
+ }
8599
+ if (t22.isForOfStatement(stmt) && containsAwait(stmt.body)) {
8600
+ if (current.length > 0) {
8601
+ segments.push({ index: index++, kind: "sync", statements: current });
8602
+ current = [];
8603
+ }
8604
+ const loopBody = t22.isBlockStatement(stmt.body) ? stmt.body.body : [stmt.body];
8605
+ const loopBinding = t22.isVariableDeclaration(stmt.left) && t22.isIdentifier(stmt.left.declarations[0]?.id) ? stmt.left.declarations[0].id.name : "item";
8606
+ segments.push({
8607
+ index: index++,
8608
+ kind: "loop",
8609
+ statements: [stmt],
8610
+ loopBinding,
8611
+ loopIterable: stmt.right,
8612
+ loopBodySegments: splitAtAwaits(loopBody)
8613
+ });
8614
+ continue;
8615
+ }
8616
+ const promiseInfo = extractPromiseAllOrRace(stmt);
8617
+ if (promiseInfo) {
8618
+ if (current.length > 0) {
8619
+ segments.push({ index: index++, kind: "sync", statements: current });
8620
+ current = [];
8621
+ }
8622
+ segments.push({
8623
+ index: index++,
8624
+ kind: promiseInfo.type === "all" ? "parallel" : "race",
8625
+ statements: [stmt],
8626
+ parallelCallees: promiseInfo.callees,
8627
+ resultBinding: promiseInfo.binding
8628
+ });
8629
+ continue;
8630
+ }
6126
8631
  const awaitInfo = extractAwait(stmt);
6127
8632
  if (!awaitInfo) {
6128
8633
  current.push(stmt);
@@ -6147,22 +8652,22 @@ function splitAtAwaits(body) {
6147
8652
  return segments;
6148
8653
  }
6149
8654
  function extractAwait(stmt) {
6150
- if (t18.isVariableDeclaration(stmt)) {
8655
+ if (t22.isVariableDeclaration(stmt)) {
6151
8656
  const decl = stmt.declarations[0];
6152
- if (decl?.init && t18.isAwaitExpression(decl.init)) {
8657
+ if (decl?.init && t22.isAwaitExpression(decl.init)) {
6153
8658
  const arg = decl.init.argument;
6154
- if (t18.isCallExpression(arg)) {
8659
+ if (t22.isCallExpression(arg)) {
6155
8660
  return {
6156
8661
  callee: getCalleeName(arg.callee),
6157
8662
  args: arg.arguments,
6158
- binding: t18.isIdentifier(decl.id) ? decl.id.name : void 0
8663
+ binding: t22.isIdentifier(decl.id) ? decl.id.name : void 0
6159
8664
  };
6160
8665
  }
6161
8666
  }
6162
8667
  }
6163
- if (t18.isExpressionStatement(stmt) && t18.isAwaitExpression(stmt.expression)) {
8668
+ if (t22.isExpressionStatement(stmt) && t22.isAwaitExpression(stmt.expression)) {
6164
8669
  const arg = stmt.expression.argument;
6165
- if (t18.isCallExpression(arg)) {
8670
+ if (t22.isCallExpression(arg)) {
6166
8671
  return {
6167
8672
  callee: getCalleeName(arg.callee),
6168
8673
  args: arg.arguments,
@@ -6170,9 +8675,9 @@ function extractAwait(stmt) {
6170
8675
  };
6171
8676
  }
6172
8677
  }
6173
- if (t18.isReturnStatement(stmt) && stmt.argument && t18.isAwaitExpression(stmt.argument)) {
8678
+ if (t22.isReturnStatement(stmt) && stmt.argument && t22.isAwaitExpression(stmt.argument)) {
6174
8679
  const arg = stmt.argument.argument;
6175
- if (t18.isCallExpression(arg)) {
8680
+ if (t22.isCallExpression(arg)) {
6176
8681
  return {
6177
8682
  callee: getCalleeName(arg.callee),
6178
8683
  args: arg.arguments,
@@ -6182,9 +8687,89 @@ function extractAwait(stmt) {
6182
8687
  }
6183
8688
  return null;
6184
8689
  }
8690
+ function containsAwait(node) {
8691
+ if (t22.isAwaitExpression(node)) return true;
8692
+ if (t22.isBlockStatement(node)) {
8693
+ return node.body.some((s) => containsAwait(s));
8694
+ }
8695
+ if (t22.isExpressionStatement(node)) {
8696
+ return containsAwait(node.expression);
8697
+ }
8698
+ if (t22.isVariableDeclaration(node)) {
8699
+ return node.declarations.some((d) => d.init ? containsAwait(d.init) : false);
8700
+ }
8701
+ if (t22.isReturnStatement(node) && node.argument) {
8702
+ return containsAwait(node.argument);
8703
+ }
8704
+ if (t22.isCallExpression(node)) {
8705
+ return node.arguments.some((a) => t22.isNode(a) && containsAwait(a));
8706
+ }
8707
+ if (t22.isForOfStatement(node)) {
8708
+ return containsAwait(node.body);
8709
+ }
8710
+ if (t22.isForStatement(node)) {
8711
+ return containsAwait(node.body);
8712
+ }
8713
+ if (t22.isIfStatement(node)) {
8714
+ return containsAwait(node.consequent) || (node.alternate ? containsAwait(node.alternate) : false);
8715
+ }
8716
+ if (t22.isTryStatement(node)) {
8717
+ return containsAwait(node.block) || (node.handler ? containsAwait(node.handler.body) : false);
8718
+ }
8719
+ if (t22.isArrayExpression(node)) {
8720
+ return node.elements.some((e) => e && !t22.isSpreadElement(e) && containsAwait(e));
8721
+ }
8722
+ return false;
8723
+ }
8724
+ function extractPromiseAllOrRace(stmt) {
8725
+ let awaitExpr = null;
8726
+ let binding;
8727
+ if (t22.isVariableDeclaration(stmt)) {
8728
+ const decl = stmt.declarations[0];
8729
+ if (decl?.init && t22.isAwaitExpression(decl.init)) {
8730
+ awaitExpr = decl.init;
8731
+ binding = t22.isIdentifier(decl.id) ? decl.id.name : t22.isArrayPattern(decl.id) ? "__destructured__" : void 0;
8732
+ }
8733
+ } else if (t22.isExpressionStatement(stmt) && t22.isAwaitExpression(stmt.expression)) {
8734
+ awaitExpr = stmt.expression;
8735
+ }
8736
+ if (!awaitExpr) return null;
8737
+ const arg = awaitExpr.argument;
8738
+ if (!t22.isCallExpression(arg)) return null;
8739
+ if (!t22.isMemberExpression(arg.callee)) return null;
8740
+ if (!t22.isIdentifier(arg.callee.object) || arg.callee.object.name !== "Promise") return null;
8741
+ if (!t22.isIdentifier(arg.callee.property)) return null;
8742
+ const method = arg.callee.property.name;
8743
+ if (method !== "all" && method !== "race") return null;
8744
+ const firstArg = arg.arguments[0];
8745
+ if (!t22.isArrayExpression(firstArg)) return null;
8746
+ const callees = [];
8747
+ for (const elem of firstArg.elements) {
8748
+ if (!elem || t22.isSpreadElement(elem)) continue;
8749
+ if (t22.isCallExpression(elem)) {
8750
+ callees.push({
8751
+ callee: getCalleeName(elem.callee),
8752
+ args: elem.arguments
8753
+ });
8754
+ }
8755
+ }
8756
+ if (callees.length === 0) return null;
8757
+ if (binding === "__destructured__" && t22.isVariableDeclaration(stmt)) {
8758
+ const decl = stmt.declarations[0];
8759
+ if (t22.isArrayPattern(decl.id)) {
8760
+ for (let i = 0; i < decl.id.elements.length && i < callees.length; i++) {
8761
+ const elem = decl.id.elements[i];
8762
+ if (t22.isIdentifier(elem)) {
8763
+ callees[i].binding = elem.name;
8764
+ }
8765
+ }
8766
+ }
8767
+ }
8768
+ return { type: method, callees, binding };
8769
+ }
6185
8770
  function getCalleeName(callee) {
6186
- if (t18.isIdentifier(callee)) return callee.name;
6187
- if (t18.isMemberExpression(callee) && t18.isIdentifier(callee.object) && t18.isIdentifier(callee.property)) {
8771
+ if (t22.isIdentifier(callee)) return callee.name;
8772
+ if (t22.isMemberExpression(callee) && t22.isIdentifier(callee.object) && t22.isIdentifier(callee.property)) {
6188
8773
  return `${callee.object.name}_${callee.property.name}`;
6189
8774
  }
6190
8775
  return "unknown_action";
@@ -6194,7 +8779,7 @@ function rewriteAwaitReferences(segments) {
6194
8779
  const slugCounts = /* @__PURE__ */ new Map();
6195
8780
  return segments.map((seg) => {
6196
8781
  if (seg.kind === "await" && seg.resultBinding) {
6197
- const slug = toSnakeCase3(seg.awaitTarget ?? "unknown");
8782
+ const slug = toSnakeCase4(seg.awaitTarget ?? "unknown");
6198
8783
  const count = (slugCounts.get(slug) ?? 0) + 1;
6199
8784
  slugCounts.set(slug, count);
6200
8785
  const key = count > 1 ? `${slug}_${count}` : slug;
@@ -6222,7 +8807,7 @@ function generateMultiStateIR(segments, _warnings, parameterMap) {
6222
8807
  const slugCounts = /* @__PURE__ */ new Map();
6223
8808
  for (const seg of segments) {
6224
8809
  if (seg.kind === "await" && seg.resultBinding) {
6225
- const slug = toSnakeCase3(seg.awaitTarget ?? "unknown");
8810
+ const slug = toSnakeCase4(seg.awaitTarget ?? "unknown");
6226
8811
  const count = (slugCounts.get(slug) ?? 0) + 1;
6227
8812
  slugCounts.set(slug, count);
6228
8813
  const key = count > 1 ? `${slug}_${count}` : slug;
@@ -6239,7 +8824,177 @@ function generateMultiStateIR(segments, _warnings, parameterMap) {
6239
8824
  pendingSyncStmts.push(...seg.statements);
6240
8825
  continue;
6241
8826
  }
6242
- const targetSlug = toSnakeCase3(seg.awaitTarget ?? "unknown");
8827
+ if (seg.kind === "try_catch" && seg.trySegments) {
8828
+ if (pendingSyncStmts.length > 0) {
8829
+ const block = t22.blockStatement(pendingSyncStmts);
8830
+ const transpiled = transpileBlock(block, { allMutable: true, derivedVarMap: buildDerivedVarMap(awaitBindings), parameterMap });
8831
+ if (!transpiled.pure) bodyIsPure = false;
8832
+ const preState = uniqueState("pre_try", usedStateNames);
8833
+ states.push({ name: preState, type: "REGULAR", on_enter: [], during: [], on_exit: [] });
8834
+ transitions.push({
8835
+ name: transitionCount === 0 ? "execute" : `on_${getStateSuffix(prevState)}_complete`,
8836
+ from: [prevState],
8837
+ to: preState,
8838
+ actions: [{ id: `pre_try_${transitionCount}`, type: "eval", mode: "auto", config: { expression: transpiled.expression } }]
8839
+ });
8840
+ prevState = preState;
8841
+ transitionCount++;
8842
+ pendingSyncStmts = [];
8843
+ }
8844
+ const tryResult = generateMultiStateIR(seg.trySegments, _warnings, parameterMap);
8845
+ if (!tryResult.bodyIsPure) bodyIsPure = false;
8846
+ const successState = uniqueState("try_success", usedStateNames);
8847
+ const errorState = uniqueState("try_error", usedStateNames);
8848
+ states.push({ name: errorState, type: "REGULAR", on_enter: [], during: [], on_exit: [] });
8849
+ states.push({ name: successState, type: "REGULAR", on_enter: [], during: [], on_exit: [] });
8850
+ for (const s of tryResult.states) {
8851
+ if (s.name === "ready" || s.name === "done") continue;
8852
+ states.push(s);
8853
+ }
8854
+ for (const tr of tryResult.transitions) {
8855
+ const remappedFrom = tr.from.map((f) => f === "ready" ? prevState : f);
8856
+ const remappedTo = tr.to === "done" ? successState : tr.to;
8857
+ transitions.push({ ...tr, from: remappedFrom, to: remappedTo });
8858
+ if (tr.actions.some((a) => a.type === "call_workflow")) {
8859
+ const awaitState = tr.to === successState ? successState : tr.to;
8860
+ if (awaitState !== successState) {
8861
+ transitions.push({
8862
+ name: `on_${getStateSuffix(awaitState)}_error`,
8863
+ from: [awaitState],
8864
+ to: errorState,
8865
+ actions: [],
8866
+ conditions: [{ expression: "action_error != null", type: "expression" }]
8867
+ });
8868
+ }
8869
+ }
8870
+ }
8871
+ if (tryResult.transitions.length > 0 && transitionCount === 0) {
8872
+ transitions[transitions.length - tryResult.transitions.length].name = "execute";
8873
+ }
8874
+ if (seg.catchStatements && seg.catchStatements.length > 0) {
8875
+ const catchBlock = t22.blockStatement(seg.catchStatements);
8876
+ const catchBindings = new Map(awaitBindings);
8877
+ if (seg.catchParam) {
8878
+ catchBindings.set(seg.catchParam, "action_error");
8879
+ }
8880
+ const catchTranspiled = transpileBlock(catchBlock, {
8881
+ allMutable: true,
8882
+ derivedVarMap: buildDerivedVarMap(catchBindings),
8883
+ parameterMap
8884
+ });
8885
+ if (!catchTranspiled.pure) bodyIsPure = false;
8886
+ const postCatch = uniqueState("post_catch", usedStateNames);
8887
+ states.push({ name: postCatch, type: "REGULAR", on_enter: [], during: [], on_exit: [] });
8888
+ transitions.push({
8889
+ name: `catch_${transitionCount}`,
8890
+ from: [errorState],
8891
+ to: postCatch,
8892
+ actions: [{ id: `catch_eval_${transitionCount}`, type: "eval", mode: "auto", config: { expression: catchTranspiled.expression } }]
8893
+ });
8894
+ prevState = postCatch;
8895
+ transitions.push({
8896
+ name: `try_success_${transitionCount}`,
8897
+ from: [successState],
8898
+ to: postCatch,
8899
+ actions: []
8900
+ });
8901
+ } else {
8902
+ prevState = successState;
8903
+ }
8904
+ transitionCount++;
8905
+ continue;
8906
+ }
8907
+ if ((seg.kind === "parallel" || seg.kind === "race") && seg.parallelCallees) {
8908
+ if (pendingSyncStmts.length > 0) {
8909
+ const block = t22.blockStatement(pendingSyncStmts);
8910
+ const transpiled = transpileBlock(block, { allMutable: true, derivedVarMap: buildDerivedVarMap(awaitBindings), parameterMap });
8911
+ if (!transpiled.pure) bodyIsPure = false;
8912
+ pendingSyncStmts = [];
8913
+ }
8914
+ const groupId = `p${transitionCount}`;
8915
+ const dispatchKind = seg.kind === "parallel" ? "parallel" : "race";
8916
+ const stateName2 = uniqueState(`awaiting_${dispatchKind}_${transitionCount}`, usedStateNames);
8917
+ states.push({ name: stateName2, type: "REGULAR", on_enter: [], during: [], on_exit: [] });
8918
+ const actions2 = [];
8919
+ for (let ci = 0; ci < seg.parallelCallees.length; ci++) {
8920
+ const callee = seg.parallelCallees[ci];
8921
+ const slug = toSnakeCase4(callee.callee);
8922
+ actions2.push({
8923
+ id: `call_${slug}_${ci}`,
8924
+ type: "call_workflow",
8925
+ mode: "auto",
8926
+ config: {
8927
+ definition_slug: callee.callee,
8928
+ result_key: slug,
8929
+ [`${dispatchKind}_group`]: groupId
8930
+ }
8931
+ });
8932
+ if (callee.binding) {
8933
+ awaitBindings.set(callee.binding, `action_results.${slug}`);
8934
+ }
8935
+ }
8936
+ const transName2 = transitionCount === 0 ? "execute" : `on_${getStateSuffix(prevState)}_complete`;
8937
+ transitions.push({ name: transName2, from: [prevState], to: stateName2, actions: actions2 });
8938
+ prevState = stateName2;
8939
+ transitionCount++;
8940
+ continue;
8941
+ }
8942
+ if (seg.kind === "loop" && seg.loopBodySegments) {
8943
+ if (pendingSyncStmts.length > 0) {
8944
+ const block = t22.blockStatement(pendingSyncStmts);
8945
+ const transpiled = transpileBlock(block, { allMutable: true, derivedVarMap: buildDerivedVarMap(awaitBindings), parameterMap });
8946
+ if (!transpiled.pure) bodyIsPure = false;
8947
+ pendingSyncStmts = [];
8948
+ }
8949
+ const loopState = uniqueState(`loop_${toSnakeCase4(seg.loopBinding ?? "item")}`, usedStateNames);
8950
+ const postLoop = uniqueState("post_loop", usedStateNames);
8951
+ states.push({ name: loopState, type: "REGULAR", on_enter: [], during: [], on_exit: [] });
8952
+ states.push({ name: postLoop, type: "REGULAR", on_enter: [], during: [], on_exit: [] });
8953
+ const initTransName = transitionCount === 0 ? "execute" : `on_${getStateSuffix(prevState)}_complete`;
8954
+ transitions.push({
8955
+ name: initTransName,
8956
+ from: [prevState],
8957
+ to: loopState,
8958
+ actions: [{
8959
+ id: `loop_init_${transitionCount}`,
8960
+ type: "eval",
8961
+ mode: "auto",
8962
+ config: { expression: `let __loop_idx = 0; let __loop_items = ${seg.loopIterable ? toSnakeCase4(seg.loopBinding ?? "items") : "[]"}` }
8963
+ }]
8964
+ });
8965
+ const awaitSegs = seg.loopBodySegments.filter((s) => s.kind === "await");
8966
+ if (awaitSegs.length > 0) {
8967
+ const firstAwait = awaitSegs[0];
8968
+ const slug = toSnakeCase4(firstAwait.awaitTarget ?? "action");
8969
+ transitions.push({
8970
+ name: `loop_body_${transitionCount}`,
8971
+ from: [loopState],
8972
+ to: loopState,
8973
+ actions: [{
8974
+ id: `loop_call_${slug}`,
8975
+ type: "call_workflow",
8976
+ mode: "auto",
8977
+ config: {
8978
+ definition_slug: firstAwait.awaitTarget,
8979
+ result_key: slug,
8980
+ loop_iteration: true
8981
+ }
8982
+ }],
8983
+ conditions: [{ expression: "__loop_idx < length(__loop_items)", type: "expression" }]
8984
+ });
8985
+ }
8986
+ transitions.push({
8987
+ name: `loop_done_${transitionCount}`,
8988
+ from: [loopState],
8989
+ to: postLoop,
8990
+ actions: [],
8991
+ conditions: [{ expression: "__loop_idx >= length(__loop_items)", type: "expression" }]
8992
+ });
8993
+ prevState = postLoop;
8994
+ transitionCount++;
8995
+ continue;
8996
+ }
8997
+ const targetSlug = toSnakeCase4(seg.awaitTarget ?? "unknown");
6243
8998
  let stateName = `awaiting_${targetSlug}`;
6244
8999
  if (usedStateNames.has(stateName)) {
6245
9000
  let suffix = 2;
@@ -6250,7 +9005,7 @@ function generateMultiStateIR(segments, _warnings, parameterMap) {
6250
9005
  states.push({ name: stateName, type: "REGULAR", on_enter: [], during: [], on_exit: [] });
6251
9006
  const actions = [];
6252
9007
  if (pendingSyncStmts.length > 0) {
6253
- const block = t18.blockStatement(pendingSyncStmts);
9008
+ const block = t22.blockStatement(pendingSyncStmts);
6254
9009
  const transpiled = transpileBlock(block, {
6255
9010
  allMutable: true,
6256
9011
  derivedVarMap: buildDerivedVarMap(awaitBindings),
@@ -6273,9 +9028,9 @@ function generateMultiStateIR(segments, _warnings, parameterMap) {
6273
9028
  const params = {};
6274
9029
  for (let i = 0; i < seg.awaitArgs.length; i++) {
6275
9030
  const arg = seg.awaitArgs[i];
6276
- if (t18.isObjectExpression(arg)) {
9031
+ if (t22.isObjectExpression(arg)) {
6277
9032
  for (const prop of arg.properties) {
6278
- if (t18.isObjectProperty(prop) && t18.isIdentifier(prop.key)) {
9033
+ if (t22.isObjectProperty(prop) && t22.isIdentifier(prop.key)) {
6279
9034
  const { expression: valExpr } = transpileArgExpression(prop.value, awaitBindings);
6280
9035
  params[prop.key.name] = valExpr;
6281
9036
  }
@@ -6308,7 +9063,7 @@ function generateMultiStateIR(segments, _warnings, parameterMap) {
6308
9063
  states.push({ name: "done", type: "END", on_enter: [], during: [], on_exit: [] });
6309
9064
  const finalActions = [];
6310
9065
  if (pendingSyncStmts.length > 0) {
6311
- const block = t18.blockStatement(pendingSyncStmts);
9066
+ const block = t22.blockStatement(pendingSyncStmts);
6312
9067
  const transpiled = transpileBlock(block, {
6313
9068
  allMutable: true,
6314
9069
  derivedVarMap: buildDerivedVarMap(awaitBindings),
@@ -6331,46 +9086,57 @@ function generateMultiStateIR(segments, _warnings, parameterMap) {
6331
9086
  });
6332
9087
  return { states, transitions, bodyIsPure };
6333
9088
  }
9089
+ function uniqueState(base, used) {
9090
+ if (!used.has(base)) {
9091
+ used.add(base);
9092
+ return base;
9093
+ }
9094
+ let suffix = 2;
9095
+ while (used.has(`${base}_${suffix}`)) suffix++;
9096
+ const name = `${base}_${suffix}`;
9097
+ used.add(name);
9098
+ return name;
9099
+ }
6334
9100
  function getStateSuffix(stateName) {
6335
9101
  return stateName.replace(/^awaiting_/, "");
6336
9102
  }
6337
9103
  function transpileArgExpression(expr, bindings) {
6338
- if (t18.isIdentifier(expr)) {
9104
+ if (t22.isIdentifier(expr)) {
6339
9105
  const replacement = bindings.get(expr.name);
6340
9106
  if (replacement) return { expression: replacement };
6341
- return { expression: `state_data.${toSnakeCase3(expr.name)}` };
9107
+ return { expression: `state_data.${toSnakeCase4(expr.name)}` };
6342
9108
  }
6343
- if (t18.isMemberExpression(expr) && t18.isIdentifier(expr.object)) {
9109
+ if (t22.isMemberExpression(expr) && t22.isIdentifier(expr.object)) {
6344
9110
  const replacement = bindings.get(expr.object.name);
6345
- if (replacement && t18.isIdentifier(expr.property)) {
9111
+ if (replacement && t22.isIdentifier(expr.property)) {
6346
9112
  return { expression: `${replacement}.${expr.property.name}` };
6347
9113
  }
6348
9114
  }
6349
- if (t18.isStringLiteral(expr)) return { expression: `'${expr.value}'` };
6350
- if (t18.isNumericLiteral(expr)) return { expression: String(expr.value) };
6351
- if (t18.isBooleanLiteral(expr)) return { expression: String(expr.value) };
9115
+ if (t22.isStringLiteral(expr)) return { expression: `'${expr.value}'` };
9116
+ if (t22.isNumericLiteral(expr)) return { expression: String(expr.value) };
9117
+ if (t22.isBooleanLiteral(expr)) return { expression: String(expr.value) };
6352
9118
  const { transpile: transpile2 } = (init_ts_to_expression(), __toCommonJS(ts_to_expression_exports));
6353
9119
  return { expression: transpile2(expr, { derivedVarMap: buildDerivedVarMap(bindings) }) };
6354
9120
  }
6355
9121
  function buildDerivedVarMap(bindings) {
6356
9122
  const map = /* @__PURE__ */ new Map();
6357
9123
  for (const [varName, path] of bindings) {
6358
- map.set(varName, t18.identifier(path));
9124
+ map.set(varName, t22.identifier(path));
6359
9125
  }
6360
9126
  return map;
6361
9127
  }
6362
9128
  function toKebabCase(name) {
6363
9129
  return name.replace(/([A-Z])/g, "-$1").toLowerCase().replace(/^-/, "");
6364
9130
  }
6365
- function toSnakeCase3(name) {
9131
+ function toSnakeCase4(name) {
6366
9132
  return name.replace(/([A-Z])/g, "_$1").toLowerCase().replace(/^_/, "");
6367
9133
  }
6368
- var import_parser, t18;
9134
+ var import_parser, t22;
6369
9135
  var init_action_extractor = __esm({
6370
9136
  "src/babel/extractors/action-extractor.ts"() {
6371
9137
  "use strict";
6372
9138
  import_parser = require("@babel/parser");
6373
- t18 = __toESM(require("@babel/types"));
9139
+ t22 = __toESM(require("@babel/types"));
6374
9140
  init_ts_to_expression();
6375
9141
  }
6376
9142
  });