@mmapp/react 0.1.0-alpha.3 → 0.1.0-alpha.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1,1091 +1,11 @@
1
- // ../player-core/dist/index.mjs
2
- var add = {
3
- name: "add",
4
- fn: (a, b) => Number(a) + Number(b),
5
- arity: 2
6
- };
7
- var subtract = {
8
- name: "subtract",
9
- fn: (a, b) => Number(a) - Number(b),
10
- arity: 2
11
- };
12
- var multiply = {
13
- name: "multiply",
14
- fn: (a, b) => Number(a) * Number(b),
15
- arity: 2
16
- };
17
- var divide = {
18
- name: "divide",
19
- fn: (a, b) => {
20
- const d = Number(b);
21
- return d === 0 ? 0 : Number(a) / d;
22
- },
23
- arity: 2
24
- };
25
- var abs = {
26
- name: "abs",
27
- fn: (a) => Math.abs(Number(a)),
28
- arity: 1
29
- };
30
- var round = {
31
- name: "round",
32
- fn: (a, decimals) => {
33
- const d = decimals != null ? Number(decimals) : 0;
34
- const factor = Math.pow(10, d);
35
- return Math.round(Number(a) * factor) / factor;
36
- },
37
- arity: -1
38
- };
39
- var min = {
40
- name: "min",
41
- fn: (...args) => {
42
- const nums = args.flat().map(Number).filter((n) => !isNaN(n));
43
- return nums.length === 0 ? 0 : Math.min(...nums);
44
- },
45
- arity: -1
46
- };
47
- var max = {
48
- name: "max",
49
- fn: (...args) => {
50
- const nums = args.flat().map(Number).filter((n) => !isNaN(n));
51
- return nums.length === 0 ? 0 : Math.max(...nums);
52
- },
53
- arity: -1
54
- };
55
- var eq = {
56
- name: "eq",
57
- fn: (a, b) => a === b || String(a) === String(b),
58
- arity: 2
59
- };
60
- var neq = {
61
- name: "neq",
62
- fn: (a, b) => a !== b && String(a) !== String(b),
63
- arity: 2
64
- };
65
- var gt = {
66
- name: "gt",
67
- fn: (a, b) => Number(a) > Number(b),
68
- arity: 2
69
- };
70
- var gte = {
71
- name: "gte",
72
- fn: (a, b) => Number(a) >= Number(b),
73
- arity: 2
74
- };
75
- var lt = {
76
- name: "lt",
77
- fn: (a, b) => Number(a) < Number(b),
78
- arity: 2
79
- };
80
- var lte = {
81
- name: "lte",
82
- fn: (a, b) => Number(a) <= Number(b),
83
- arity: 2
84
- };
85
- var if_fn = {
86
- name: "if",
87
- fn: (cond, then, else_) => cond ? then : else_,
88
- arity: 3
89
- };
90
- var and = {
91
- name: "and",
92
- fn: (...args) => args.every(Boolean),
93
- arity: -1
94
- };
95
- var or = {
96
- name: "or",
97
- fn: (...args) => args.some(Boolean),
98
- arity: -1
99
- };
100
- var not = {
101
- name: "not",
102
- fn: (a) => !a,
103
- arity: 1
104
- };
105
- var coalesce = {
106
- name: "coalesce",
107
- fn: (...args) => {
108
- for (const arg of args) {
109
- if (arg != null) return arg;
110
- }
111
- return null;
112
- },
113
- arity: -1
114
- };
115
- var concat = {
116
- name: "concat",
117
- fn: (...args) => args.map(String).join(""),
118
- arity: -1
119
- };
120
- var upper = {
121
- name: "upper",
122
- fn: (s) => String(s ?? "").toUpperCase(),
123
- arity: 1
124
- };
125
- var lower = {
126
- name: "lower",
127
- fn: (s) => String(s ?? "").toLowerCase(),
128
- arity: 1
129
- };
130
- var trim = {
131
- name: "trim",
132
- fn: (s) => String(s ?? "").trim(),
133
- arity: 1
134
- };
135
- var format = {
136
- name: "format",
137
- fn: (template, ...args) => {
138
- let result = String(template ?? "");
139
- args.forEach((arg, i) => {
140
- result = result.replace(`{${i}}`, String(arg ?? ""));
141
- });
142
- return result;
143
- },
144
- arity: -1
145
- };
146
- var length = {
147
- name: "length",
148
- fn: (v) => {
149
- if (Array.isArray(v)) return v.length;
150
- if (typeof v === "string") return v.length;
151
- if (v && typeof v === "object") return Object.keys(v).length;
152
- return 0;
153
- },
154
- arity: 1
155
- };
156
- var get = {
157
- name: "get",
158
- fn: (obj, path) => {
159
- if (obj == null || typeof path !== "string") return void 0;
160
- const parts = path.split(".");
161
- let current = obj;
162
- for (const part of parts) {
163
- if (current == null || typeof current !== "object") return void 0;
164
- current = current[part];
165
- }
166
- return current;
167
- },
168
- arity: 2
169
- };
170
- var includes = {
171
- name: "includes",
172
- fn: (collection, value) => {
173
- if (Array.isArray(collection)) return collection.includes(value);
174
- if (typeof collection === "string") return collection.includes(String(value));
175
- return false;
176
- },
177
- arity: 2
178
- };
179
- var is_defined = {
180
- name: "is_defined",
181
- fn: (v) => v !== void 0 && v !== null,
182
- arity: 1
183
- };
184
- var is_empty = {
185
- name: "is_empty",
186
- fn: (v) => {
187
- if (v == null) return true;
188
- if (typeof v === "string") return v.length === 0;
189
- if (Array.isArray(v)) return v.length === 0;
190
- if (typeof v === "object") return Object.keys(v).length === 0;
191
- return false;
192
- },
193
- arity: 1
194
- };
195
- var is_null = {
196
- name: "is_null",
197
- fn: (v) => v === null || v === void 0,
198
- arity: 1
199
- };
200
- var to_string = {
201
- name: "to_string",
202
- fn: (v) => {
203
- if (v == null) return "";
204
- if (typeof v === "object") return JSON.stringify(v);
205
- return String(v);
206
- },
207
- arity: 1
208
- };
209
- var CORE_FUNCTIONS = [
210
- // Math (8)
211
- add,
212
- subtract,
213
- multiply,
214
- divide,
215
- abs,
216
- round,
217
- min,
218
- max,
219
- // Comparison (6)
220
- eq,
221
- neq,
222
- gt,
223
- gte,
224
- lt,
225
- lte,
226
- // Logic (5)
227
- if_fn,
228
- and,
229
- or,
230
- not,
231
- coalesce,
232
- // String (6)
233
- concat,
234
- upper,
235
- lower,
236
- trim,
237
- format,
238
- length,
239
- // Path (3)
240
- get,
241
- includes,
242
- is_defined,
243
- // Type (3)
244
- is_empty,
245
- is_null,
246
- to_string
247
- ];
248
- function buildFunctionMap(functions) {
249
- const map = /* @__PURE__ */ new Map();
250
- for (const fn of functions) {
251
- map.set(fn.name, fn.fn);
252
- }
253
- return map;
254
- }
255
- var MAX_DEPTH = 50;
256
- var Parser = class {
257
- pos = 0;
258
- depth = 0;
259
- input;
260
- constructor(input) {
261
- this.input = input;
262
- }
263
- parse() {
264
- this.skipWhitespace();
265
- const node = this.parseExpression();
266
- this.skipWhitespace();
267
- if (this.pos < this.input.length) {
268
- throw new Error(`Unexpected character at position ${this.pos}: '${this.input[this.pos]}'`);
269
- }
270
- return node;
271
- }
272
- guardDepth() {
273
- if (++this.depth > MAX_DEPTH) {
274
- throw new Error("Expression too deeply nested");
275
- }
276
- }
277
- parseExpression() {
278
- this.guardDepth();
279
- try {
280
- return this.parseTernary();
281
- } finally {
282
- this.depth--;
283
- }
284
- }
285
- parseTernary() {
286
- let node = this.parseLogicalOr();
287
- this.skipWhitespace();
288
- if (this.peek() === "?") {
289
- this.advance();
290
- const consequent = this.parseExpression();
291
- this.skipWhitespace();
292
- this.expect(":");
293
- const alternate = this.parseExpression();
294
- node = { type: "ternary", condition: node, consequent, alternate };
295
- }
296
- return node;
297
- }
298
- parseLogicalOr() {
299
- let left = this.parseLogicalAnd();
300
- this.skipWhitespace();
301
- while (this.match("||")) {
302
- const right = this.parseLogicalAnd();
303
- left = { type: "binary", operator: "||", left, right };
304
- this.skipWhitespace();
305
- }
306
- return left;
307
- }
308
- parseLogicalAnd() {
309
- let left = this.parseEquality();
310
- this.skipWhitespace();
311
- while (this.match("&&")) {
312
- const right = this.parseEquality();
313
- left = { type: "binary", operator: "&&", left, right };
314
- this.skipWhitespace();
315
- }
316
- return left;
317
- }
318
- parseEquality() {
319
- let left = this.parseComparison();
320
- this.skipWhitespace();
321
- while (true) {
322
- if (this.match("==")) {
323
- const right = this.parseComparison();
324
- left = { type: "binary", operator: "==", left, right };
325
- } else if (this.match("!=")) {
326
- const right = this.parseComparison();
327
- left = { type: "binary", operator: "!=", left, right };
328
- } else {
329
- break;
330
- }
331
- this.skipWhitespace();
332
- }
333
- return left;
334
- }
335
- parseComparison() {
336
- let left = this.parseUnary();
337
- this.skipWhitespace();
338
- while (true) {
339
- if (this.match(">=")) {
340
- const right = this.parseUnary();
341
- left = { type: "binary", operator: ">=", left, right };
342
- } else if (this.match("<=")) {
343
- const right = this.parseUnary();
344
- left = { type: "binary", operator: "<=", left, right };
345
- } else if (this.peek() === ">" && !this.lookAhead(">=")) {
346
- this.advance();
347
- const right = this.parseUnary();
348
- left = { type: "binary", operator: ">", left, right };
349
- } else if (this.peek() === "<" && !this.lookAhead("<=")) {
350
- this.advance();
351
- const right = this.parseUnary();
352
- left = { type: "binary", operator: "<", left, right };
353
- } else {
354
- break;
355
- }
356
- this.skipWhitespace();
357
- }
358
- return left;
359
- }
360
- parseUnary() {
361
- this.skipWhitespace();
362
- if (this.peek() === "!") {
363
- this.advance();
364
- const operand = this.parseUnary();
365
- return { type: "unary", operator: "!", operand };
366
- }
367
- if (this.peek() === "-") {
368
- const nextChar = this.input[this.pos + 1];
369
- if (nextChar !== void 0 && (nextChar >= "0" && nextChar <= "9" || nextChar === ".")) {
370
- return this.parseCallChain();
371
- }
372
- }
373
- return this.parseCallChain();
374
- }
375
- parseCallChain() {
376
- let node = this.parsePrimary();
377
- while (true) {
378
- this.skipWhitespace();
379
- if (this.peek() === "(") {
380
- this.advance();
381
- const args = this.parseArgList();
382
- this.expect(")");
383
- if (node.type === "identifier") {
384
- node = { type: "call", name: node.name, args };
385
- } else if (node.type === "path") {
386
- const name = node.segments.join(".");
387
- node = { type: "call", name, args };
388
- } else if (node.type === "member") {
389
- node = { type: "method_call", object: node.object, method: node.property, args };
390
- } else {
391
- throw new Error("Cannot call non-function");
392
- }
393
- } else if (this.peek() === ".") {
394
- this.advance();
395
- const prop = this.parseIdentifierName();
396
- node = { type: "member", object: node, property: prop };
397
- } else {
398
- break;
399
- }
400
- }
401
- return node;
402
- }
403
- parsePrimary() {
404
- this.skipWhitespace();
405
- const ch = this.peek();
406
- if (ch === "(") {
407
- this.advance();
408
- const expr2 = this.parseExpression();
409
- this.skipWhitespace();
410
- this.expect(")");
411
- return expr2;
412
- }
413
- if (ch === "'" || ch === '"') {
414
- return this.parseString();
415
- }
416
- if (ch === "-" || ch >= "0" && ch <= "9") {
417
- return this.parseNumber();
418
- }
419
- if (this.isIdentStart(ch)) {
420
- return this.parseIdentifierOrPath();
421
- }
422
- throw new Error(
423
- `Unexpected character at position ${this.pos}: '${ch || "EOF"}'`
424
- );
425
- }
426
- parseString() {
427
- const quote = this.advance();
428
- let value = "";
429
- while (this.pos < this.input.length && this.peek() !== quote) {
430
- if (this.peek() === "\\") {
431
- this.advance();
432
- const esc = this.advance();
433
- if (esc === "n") value += "\n";
434
- else if (esc === "t") value += " ";
435
- else if (esc === "r") value += "\r";
436
- else value += esc;
437
- } else {
438
- value += this.advance();
439
- }
440
- }
441
- if (this.pos >= this.input.length) {
442
- throw new Error("Unterminated string literal");
443
- }
444
- this.advance();
445
- return { type: "string", value };
446
- }
447
- parseNumber() {
448
- let numStr = "";
449
- if (this.peek() === "-") {
450
- numStr += this.advance();
451
- }
452
- while (this.pos < this.input.length && (this.input[this.pos] >= "0" && this.input[this.pos] <= "9")) {
453
- numStr += this.advance();
454
- }
455
- if (this.peek() === "." && this.pos + 1 < this.input.length && this.input[this.pos + 1] >= "0" && this.input[this.pos + 1] <= "9") {
456
- numStr += this.advance();
457
- while (this.pos < this.input.length && (this.input[this.pos] >= "0" && this.input[this.pos] <= "9")) {
458
- numStr += this.advance();
459
- }
460
- }
461
- return { type: "number", value: Number(numStr) };
462
- }
463
- parseIdentifierOrPath() {
464
- const name = this.parseIdentifierName();
465
- if (name === "true") return { type: "boolean", value: true };
466
- if (name === "false") return { type: "boolean", value: false };
467
- if (name === "null") return { type: "null" };
468
- if (name === "undefined") return { type: "null" };
469
- return { type: "identifier", name };
470
- }
471
- parseIdentifierName() {
472
- let name = "";
473
- if (this.peek() === "$") name += this.advance();
474
- while (this.pos < this.input.length && this.isIdentPart(this.input[this.pos])) {
475
- name += this.advance();
476
- }
477
- if (!name) {
478
- throw new Error(`Expected identifier at position ${this.pos}`);
479
- }
480
- return name;
481
- }
482
- parseArgList() {
483
- this.skipWhitespace();
484
- if (this.peek() === ")") return [];
485
- const args = [];
486
- args.push(this.parseExpression());
487
- this.skipWhitespace();
488
- while (this.peek() === ",") {
489
- this.advance();
490
- args.push(this.parseExpression());
491
- this.skipWhitespace();
492
- }
493
- return args;
494
- }
495
- // Character utilities
496
- peek() {
497
- return this.input[this.pos] ?? "";
498
- }
499
- advance() {
500
- return this.input[this.pos++] ?? "";
501
- }
502
- match(str) {
503
- if (this.input.startsWith(str, this.pos)) {
504
- this.pos += str.length;
505
- return true;
506
- }
507
- return false;
508
- }
509
- lookAhead(str) {
510
- return this.input.startsWith(str, this.pos);
511
- }
512
- expect(ch) {
513
- this.skipWhitespace();
514
- if (this.peek() !== ch) {
515
- throw new Error(`Expected '${ch}' at position ${this.pos}, got '${this.peek() || "EOF"}'`);
516
- }
517
- this.advance();
518
- }
519
- skipWhitespace() {
520
- while (this.pos < this.input.length && " \n\r".includes(this.input[this.pos])) {
521
- this.pos++;
522
- }
523
- }
524
- isIdentStart(ch) {
525
- return ch >= "a" && ch <= "z" || ch >= "A" && ch <= "Z" || ch === "_" || ch === "$";
526
- }
527
- isIdentPart(ch) {
528
- return this.isIdentStart(ch) || ch >= "0" && ch <= "9";
529
- }
530
- };
531
- function evaluateAST(node, context, fnMap) {
532
- switch (node.type) {
533
- case "number":
534
- return node.value;
535
- case "string":
536
- return node.value;
537
- case "boolean":
538
- return node.value;
539
- case "null":
540
- return null;
541
- case "identifier":
542
- return resolvePath(node.name, context);
543
- case "path":
544
- return resolvePath(node.segments.join("."), context);
545
- case "member": {
546
- const obj = evaluateAST(node.object, context, fnMap);
547
- if (obj == null || typeof obj !== "object") return void 0;
548
- return obj[node.property];
549
- }
550
- case "call": {
551
- const fn = fnMap.get(node.name);
552
- if (!fn) return void 0;
553
- const args = node.args.map((a) => evaluateAST(a, context, fnMap));
554
- return fn(...args);
555
- }
556
- case "method_call": {
557
- const obj = evaluateAST(node.object, context, fnMap);
558
- if (obj != null && typeof obj === "object") {
559
- const method = obj[node.method];
560
- if (typeof method === "function") {
561
- const args = node.args.map((a) => evaluateAST(a, context, fnMap));
562
- return method.apply(obj, args);
563
- }
564
- }
565
- return void 0;
566
- }
567
- case "unary": {
568
- const operand = evaluateAST(node.operand, context, fnMap);
569
- return !operand;
570
- }
571
- case "binary": {
572
- if (node.operator === "&&") {
573
- const left2 = evaluateAST(node.left, context, fnMap);
574
- if (!left2) return left2;
575
- return evaluateAST(node.right, context, fnMap);
576
- }
577
- if (node.operator === "||") {
578
- const left2 = evaluateAST(node.left, context, fnMap);
579
- if (left2) return left2;
580
- return evaluateAST(node.right, context, fnMap);
581
- }
582
- const left = evaluateAST(node.left, context, fnMap);
583
- const right = evaluateAST(node.right, context, fnMap);
584
- switch (node.operator) {
585
- // eslint-disable-next-line eqeqeq
586
- case "==":
587
- return left == right;
588
- // eslint-disable-next-line eqeqeq
589
- case "!=":
590
- return left != right;
591
- case ">":
592
- return Number(left) > Number(right);
593
- case "<":
594
- return Number(left) < Number(right);
595
- case ">=":
596
- return Number(left) >= Number(right);
597
- case "<=":
598
- return Number(left) <= Number(right);
599
- default:
600
- return void 0;
601
- }
602
- }
603
- case "ternary": {
604
- const condition = evaluateAST(node.condition, context, fnMap);
605
- return condition ? evaluateAST(node.consequent, context, fnMap) : evaluateAST(node.alternate, context, fnMap);
606
- }
607
- }
608
- }
609
- var MAX_CACHE = 500;
610
- var astCache = /* @__PURE__ */ new Map();
611
- function evictIfNeeded() {
612
- if (astCache.size > MAX_CACHE) {
613
- const keys = Array.from(astCache.keys());
614
- const evictCount = Math.floor(MAX_CACHE * 0.25);
615
- for (let i = 0; i < evictCount; i++) {
616
- astCache.delete(keys[i]);
617
- }
618
- }
619
- }
620
- function parseAndCache(expr2) {
621
- const cached = astCache.get(expr2);
622
- if (cached) return cached;
623
- const parser = new Parser(expr2);
624
- const ast = parser.parse();
625
- astCache.set(expr2, ast);
626
- evictIfNeeded();
627
- return ast;
628
- }
629
- var TEMPLATE_RE = /\{\{(.+?)\}\}/g;
630
- function resolvePath(path, context) {
631
- const parts = path.split(".");
632
- let current = context;
633
- for (const part of parts) {
634
- if (current == null || typeof current !== "object") return void 0;
635
- current = current[part];
636
- }
637
- return current;
638
- }
639
- function evaluateExpression(expr2, context, fnMap) {
640
- const trimmed = expr2.trim();
641
- if (trimmed === "true") return true;
642
- if (trimmed === "false") return false;
643
- if (trimmed === "null") return null;
644
- if (trimmed === "undefined") return void 0;
645
- const num = Number(trimmed);
646
- if (!isNaN(num) && trimmed !== "") return num;
647
- if (trimmed.startsWith("'") && trimmed.endsWith("'") || trimmed.startsWith('"') && trimmed.endsWith('"')) {
648
- return trimmed.slice(1, -1);
649
- }
650
- if (/^[a-zA-Z_$][\w$.]*$/.test(trimmed)) {
651
- return resolvePath(trimmed, context);
652
- }
653
- const ast = parseAndCache(trimmed);
654
- return evaluateAST(ast, context, fnMap);
655
- }
656
- var WEB_FAILURE_POLICIES = {
657
- VIEW_BINDING: {
658
- on_error: "return_fallback",
659
- fallback_value: "",
660
- log_level: "warn"
661
- },
662
- EVENT_REACTION: {
663
- on_error: "log_and_skip",
664
- fallback_value: void 0,
665
- log_level: "error"
666
- },
667
- DURING_ACTION: {
668
- on_error: "log_and_skip",
669
- fallback_value: void 0,
670
- log_level: "error"
671
- },
672
- CONDITIONAL_VISIBILITY: {
673
- on_error: "return_fallback",
674
- fallback_value: true,
675
- // Show by default if condition fails
676
- log_level: "warn"
677
- }
678
- };
679
- function createEvaluator(config) {
680
- const allFunctions = [...CORE_FUNCTIONS, ...config.functions];
681
- const fnMap = buildFunctionMap(allFunctions);
682
- const policy = config.failurePolicy;
683
- function handleError(expr2, error) {
684
- const message = error instanceof Error ? error.message : String(error);
685
- if (policy.log_level === "error") {
686
- console.error(`[player-core] Expression error: "${expr2}" \u2014 ${message}`);
687
- } else if (policy.log_level === "warn") {
688
- console.warn(`[player-core] Expression error: "${expr2}" \u2014 ${message}`);
689
- }
690
- switch (policy.on_error) {
691
- case "throw":
692
- throw error;
693
- case "return_fallback":
694
- return { value: policy.fallback_value, status: "fallback", error: message };
695
- case "log_and_skip":
696
- default:
697
- return { value: policy.fallback_value, status: "error", error: message };
698
- }
699
- }
700
- return {
701
- evaluate(expression, context) {
702
- try {
703
- const value = evaluateExpression(expression, context, fnMap);
704
- return { value, status: "ok" };
705
- } catch (error) {
706
- return handleError(expression, error);
707
- }
708
- },
709
- evaluateTemplate(template, context) {
710
- try {
711
- if (!template.includes("{{")) {
712
- return { value: template, status: "ok" };
713
- }
714
- const result = template.replace(TEMPLATE_RE, (_match, expr2) => {
715
- const value = evaluateExpression(expr2, context, fnMap);
716
- return value != null ? String(value) : "";
717
- });
718
- return { value: result, status: "ok" };
719
- } catch (error) {
720
- return handleError(template, error);
721
- }
722
- },
723
- validate(expression) {
724
- const errors = [];
725
- try {
726
- parseAndCache(expression);
727
- } catch (e) {
728
- errors.push(e instanceof Error ? e.message : String(e));
729
- }
730
- return { valid: errors.length === 0, errors };
731
- }
732
- };
733
- }
734
- var MAX_AUTO_CHAIN = 10;
735
- var StateMachine = class {
736
- evaluator;
737
- actionHandlers;
738
- listeners = /* @__PURE__ */ new Set();
739
- instance;
740
- constructor(definition, initialData = {}, config) {
741
- this.evaluator = config.evaluator;
742
- this.actionHandlers = config.actionHandlers ?? /* @__PURE__ */ new Map();
743
- const startState = definition.states.find((s) => s.type === "START");
744
- if (!startState) {
745
- throw new Error(`No START state found in definition ${definition.slug}`);
746
- }
747
- this.instance = {
748
- definition,
749
- current_state: startState.name,
750
- state_data: { ...initialData },
751
- memory: {},
752
- status: "ACTIVE"
753
- };
754
- }
755
- /** Get the current instance snapshot (immutable copy) */
756
- getSnapshot() {
757
- return { ...this.instance, state_data: { ...this.instance.state_data }, memory: { ...this.instance.memory } };
758
- }
759
- /** Get current state name */
760
- get currentState() {
761
- return this.instance.current_state;
762
- }
763
- /** Get current state_data */
764
- get stateData() {
765
- return this.instance.state_data;
766
- }
767
- /** Get current status */
768
- get status() {
769
- return this.instance.status;
770
- }
771
- /** Subscribe to state machine events */
772
- on(listener) {
773
- this.listeners.add(listener);
774
- return () => this.listeners.delete(listener);
775
- }
776
- /** Register an action handler */
777
- registerAction(type, handler) {
778
- this.actionHandlers.set(type, handler);
779
- }
780
- /** Execute a named transition */
781
- async transition(transitionName, data) {
782
- if (this.instance.status !== "ACTIVE") {
783
- return {
784
- success: false,
785
- from_state: this.instance.current_state,
786
- to_state: this.instance.current_state,
787
- actions_executed: [],
788
- error: `Cannot transition: instance status is ${this.instance.status}`
789
- };
790
- }
791
- const transition2 = this.instance.definition.transitions.find(
792
- (t) => t.name === transitionName && t.from.includes(this.instance.current_state)
793
- );
794
- if (!transition2) {
795
- return {
796
- success: false,
797
- from_state: this.instance.current_state,
798
- to_state: this.instance.current_state,
799
- actions_executed: [],
800
- error: `Transition "${transitionName}" not valid from state "${this.instance.current_state}"`
801
- };
802
- }
803
- if (data) {
804
- this.instance.state_data = { ...this.instance.state_data, ...data };
805
- }
806
- if (transition2.conditions && transition2.conditions.length > 0) {
807
- const ctx = this.buildContext();
808
- for (const condition of transition2.conditions) {
809
- const result2 = this.evaluator.evaluate(condition, ctx);
810
- if (!result2.value) {
811
- return {
812
- success: false,
813
- from_state: this.instance.current_state,
814
- to_state: this.instance.current_state,
815
- actions_executed: [],
816
- error: `Transition condition not met: ${condition}`
817
- };
818
- }
819
- }
820
- }
821
- const result = await this.executeTransition(transition2);
822
- if (result.success) {
823
- await this.drainAutoTransitions();
824
- }
825
- return result;
826
- }
827
- /** Update state_data directly (for on_event set_field actions) */
828
- setField(field2, value) {
829
- this.instance.state_data = { ...this.instance.state_data, [field2]: value };
830
- }
831
- /** Update memory */
832
- setMemory(key, value) {
833
- this.instance.memory = { ...this.instance.memory, [key]: value };
834
- }
835
- /** Get available transitions from the current state */
836
- getAvailableTransitions() {
837
- return this.instance.definition.transitions.filter(
838
- (t) => t.from.includes(this.instance.current_state) && !t.auto
839
- );
840
- }
841
- /** Get the current state definition */
842
- getCurrentStateDefinition() {
843
- return this.instance.definition.states.find((s) => s.name === this.instance.current_state);
844
- }
845
- // ===========================================================================
846
- // Private implementation
847
- // ===========================================================================
848
- async executeTransition(transition2) {
849
- const fromState = this.instance.current_state;
850
- const allActionsExecuted = [];
851
- const fromStateDef = this.getCurrentStateDefinition();
852
- if (fromStateDef?.on_exit) {
853
- await this.executeActions(fromStateDef.on_exit, allActionsExecuted);
854
- }
855
- this.emit({
856
- type: "state_exit",
857
- instance_id: this.instance.definition.id,
858
- from_state: fromState
859
- });
860
- if (transition2.actions) {
861
- await this.executeActions(transition2.actions, allActionsExecuted);
862
- }
863
- this.instance.current_state = transition2.to;
864
- const toStateDef = this.instance.definition.states.find((s) => s.name === transition2.to);
865
- if (toStateDef?.type === "END") {
866
- this.instance.status = "COMPLETED";
867
- } else if (toStateDef?.type === "CANCELLED") {
868
- this.instance.status = "CANCELLED";
869
- }
870
- this.emit({
871
- type: "state_enter",
872
- instance_id: this.instance.definition.id,
873
- to_state: transition2.to
874
- });
875
- if (toStateDef?.on_enter) {
876
- await this.executeActions(toStateDef.on_enter, allActionsExecuted);
877
- }
878
- this.emit({
879
- type: "transition",
880
- instance_id: this.instance.definition.id,
881
- from_state: fromState,
882
- to_state: transition2.to
883
- });
884
- return {
885
- success: true,
886
- from_state: fromState,
887
- to_state: transition2.to,
888
- actions_executed: allActionsExecuted
889
- };
890
- }
891
- async drainAutoTransitions() {
892
- for (let depth = 0; depth < MAX_AUTO_CHAIN; depth++) {
893
- if (this.instance.status !== "ACTIVE") break;
894
- const autoTransition = this.findMatchingAutoTransition();
895
- if (!autoTransition) break;
896
- const result = await this.executeTransition(autoTransition);
897
- if (!result.success) break;
898
- }
899
- }
900
- findMatchingAutoTransition() {
901
- const candidates = this.instance.definition.transitions.filter(
902
- (t) => t.auto && t.from.includes(this.instance.current_state)
903
- );
904
- const ctx = this.buildContext();
905
- for (const candidate of candidates) {
906
- if (!candidate.conditions || candidate.conditions.length === 0) {
907
- return candidate;
908
- }
909
- const allMet = candidate.conditions.every((condition) => {
910
- const result = this.evaluator.evaluate(condition, ctx);
911
- return result.value === true;
912
- });
913
- if (allMet) return candidate;
914
- }
915
- return null;
916
- }
917
- async executeActions(actions, collector) {
918
- const ctx = this.buildContext();
919
- for (const action2 of actions) {
920
- if (action2.condition) {
921
- const condResult = this.evaluator.evaluate(action2.condition, ctx);
922
- if (!condResult.value) continue;
923
- }
924
- const handler = this.actionHandlers.get(action2.type);
925
- if (handler) {
926
- try {
927
- await handler(action2, ctx);
928
- collector.push(action2);
929
- this.emit({
930
- type: "action_executed",
931
- instance_id: this.instance.definition.id,
932
- action: action2
933
- });
934
- } catch (error) {
935
- this.emit({
936
- type: "error",
937
- instance_id: this.instance.definition.id,
938
- action: action2,
939
- error: error instanceof Error ? error.message : String(error)
940
- });
941
- }
942
- }
943
- }
944
- }
945
- buildContext() {
946
- return {
947
- state_data: this.instance.state_data,
948
- memory: this.instance.memory,
949
- current_state: this.instance.current_state,
950
- status: this.instance.status,
951
- // Spread state_data for direct field access (e.g., "title" instead of "state_data.title")
952
- ...this.instance.state_data
953
- };
954
- }
955
- emit(event) {
956
- for (const listener of this.listeners) {
957
- try {
958
- listener(event);
959
- } catch {
960
- }
961
- }
962
- }
963
- };
964
- var patternCache = /* @__PURE__ */ new Map();
965
- var MAX_CACHE2 = 200;
966
- function compilePattern(pattern) {
967
- const cached = patternCache.get(pattern);
968
- if (cached) return cached;
969
- const escaped = pattern.replace(/[.+?^${}()|[\]\\]/g, "\\$&").replace(/\*\*/g, "<<DOUBLESTAR>>").replace(/\*/g, "[^:.]+").replace(/<<DOUBLESTAR>>/g, ".*");
970
- const regex = new RegExp(`^${escaped}$`);
971
- if (patternCache.size >= MAX_CACHE2) {
972
- const firstKey = patternCache.keys().next().value;
973
- if (firstKey) patternCache.delete(firstKey);
974
- }
975
- patternCache.set(pattern, regex);
976
- return regex;
977
- }
978
- function matchTopic(pattern, topic) {
979
- return pattern.test(topic);
980
- }
981
- var EventBus = class {
982
- subscriptions = [];
983
- /**
984
- * Subscribe to events matching a glob pattern.
985
- * Returns an unsubscribe function.
986
- */
987
- subscribe(pattern, handler) {
988
- const regex = compilePattern(pattern);
989
- const subscription = { pattern, regex, handler };
990
- this.subscriptions.push(subscription);
991
- return () => {
992
- const idx = this.subscriptions.indexOf(subscription);
993
- if (idx !== -1) this.subscriptions.splice(idx, 1);
994
- };
995
- }
996
- /**
997
- * Publish an event. All matching subscriptions fire (async).
998
- * Errors in handlers are caught and logged, never propagated.
999
- */
1000
- async publish(topic, payload = {}) {
1001
- const event = { topic, payload };
1002
- for (const sub of this.subscriptions) {
1003
- if (matchTopic(sub.regex, topic)) {
1004
- try {
1005
- await sub.handler(event);
1006
- } catch (error) {
1007
- console.warn(
1008
- `[player-core] Event handler error for pattern "${sub.pattern}" on topic "${topic}":`,
1009
- error
1010
- );
1011
- }
1012
- }
1013
- }
1014
- }
1015
- /**
1016
- * Publish synchronously (fire-and-forget).
1017
- * Useful when you don't need to await handler completion.
1018
- */
1019
- emit(topic, payload = {}) {
1020
- void this.publish(topic, payload);
1021
- }
1022
- /** Get count of active subscriptions */
1023
- get size() {
1024
- return this.subscriptions.length;
1025
- }
1026
- /** Remove all subscriptions */
1027
- clear() {
1028
- this.subscriptions.length = 0;
1029
- }
1030
- };
1031
- var ActionDispatcher = class {
1032
- handlers = /* @__PURE__ */ new Map();
1033
- /** Register a handler for an action type */
1034
- register(type, handler) {
1035
- this.handlers.set(type, handler);
1036
- }
1037
- /** Unregister a handler */
1038
- unregister(type) {
1039
- this.handlers.delete(type);
1040
- }
1041
- /** Check if a handler is registered for the given type */
1042
- has(type) {
1043
- return this.handlers.has(type);
1044
- }
1045
- /**
1046
- * Execute a list of actions sequentially.
1047
- * Each action's condition is evaluated first (if present).
1048
- * Missing handlers are skipped with a warning.
1049
- */
1050
- async execute(actions, context, evaluator) {
1051
- const results = [];
1052
- for (const action2 of actions) {
1053
- if (action2.condition && evaluator) {
1054
- const condResult = evaluator.evaluate(action2.condition, context);
1055
- if (!condResult.value) continue;
1056
- }
1057
- const handler = this.handlers.get(action2.type);
1058
- if (!handler) {
1059
- console.warn(`[player-core] No handler registered for action type "${action2.type}" \u2014 unsupported action`);
1060
- results.push({ type: action2.type, success: false, error: `unsupported action: "${action2.type}"` });
1061
- continue;
1062
- }
1063
- try {
1064
- await handler(action2.config, context);
1065
- results.push({ type: action2.type, success: true });
1066
- } catch (error) {
1067
- const message = error instanceof Error ? error.message : String(error);
1068
- console.warn(`[player-core] Action "${action2.type}" failed: ${message}`);
1069
- results.push({ type: action2.type, success: false, error: message });
1070
- }
1071
- }
1072
- return results;
1073
- }
1074
- /** Get count of registered handlers */
1075
- get size() {
1076
- return this.handlers.size;
1077
- }
1078
- /** Get all registered action type names */
1079
- getRegisteredTypes() {
1080
- return Array.from(this.handlers.keys());
1081
- }
1082
- /** Remove all handlers */
1083
- clear() {
1084
- this.handlers.clear();
1085
- }
1086
- };
1087
-
1088
1
  // src/core/WorkflowRuntime.ts
2
+ import {
3
+ StateMachine,
4
+ EventBus,
5
+ ActionDispatcher,
6
+ createEvaluator,
7
+ WEB_FAILURE_POLICIES
8
+ } from "@mmapp/player-core";
1089
9
  var WorkflowRuntime = class {
1090
10
  sm;
1091
11
  eventBus;
@@ -1184,24 +104,24 @@ import { useEffect, useRef } from "react";
1184
104
  import { createContext, useContext } from "react";
1185
105
  var RuntimeContext = createContext(null);
1186
106
  function useRuntimeContext() {
1187
- const runtime = useContext(RuntimeContext);
1188
- if (!runtime) {
107
+ const runtime2 = useContext(RuntimeContext);
108
+ if (!runtime2) {
1189
109
  throw new Error(
1190
110
  "useRuntimeContext must be used within a WorkflowProvider or RuntimeContext.Provider"
1191
111
  );
1192
112
  }
1193
- return runtime;
113
+ return runtime2;
1194
114
  }
1195
115
 
1196
116
  // src/hooks/useOnEnter.ts
1197
117
  function useOnEnter(stateName, effect) {
1198
- const runtime = useRuntimeContext();
118
+ const runtime2 = useRuntimeContext();
1199
119
  const effectRef = useRef(effect);
1200
120
  effectRef.current = effect;
1201
121
  const cleanupRef = useRef(null);
1202
122
  const states = Array.isArray(stateName) ? stateName : [stateName];
1203
123
  useEffect(() => {
1204
- if (states.includes(runtime.sm.currentState)) {
124
+ if (states.includes(runtime2.sm.currentState)) {
1205
125
  const result = effectRef.current();
1206
126
  if (result instanceof Promise) {
1207
127
  result.then((cleanup) => {
@@ -1211,7 +131,7 @@ function useOnEnter(stateName, effect) {
1211
131
  cleanupRef.current = result;
1212
132
  }
1213
133
  }
1214
- const unsub = runtime.sm.on((event) => {
134
+ const unsub = runtime2.sm.on((event) => {
1215
135
  if (event.type === "state_enter" && event.to_state && states.includes(event.to_state)) {
1216
136
  cleanupRef.current?.();
1217
137
  const result = effectRef.current();
@@ -1232,34 +152,34 @@ function useOnEnter(stateName, effect) {
1232
152
  unsub();
1233
153
  cleanupRef.current?.();
1234
154
  };
1235
- }, [runtime, ...states]);
155
+ }, [runtime2, ...states]);
1236
156
  }
1237
157
 
1238
158
  // src/hooks/useOnExit.ts
1239
159
  import { useEffect as useEffect2, useRef as useRef2 } from "react";
1240
160
  function useOnExit(stateName, effect) {
1241
- const runtime = useRuntimeContext();
161
+ const runtime2 = useRuntimeContext();
1242
162
  const effectRef = useRef2(effect);
1243
163
  effectRef.current = effect;
1244
164
  const states = Array.isArray(stateName) ? stateName : [stateName];
1245
165
  useEffect2(() => {
1246
- const unsub = runtime.sm.on((event) => {
166
+ const unsub = runtime2.sm.on((event) => {
1247
167
  if (event.type === "state_exit" && event.from_state && states.includes(event.from_state)) {
1248
168
  effectRef.current();
1249
169
  }
1250
170
  });
1251
171
  return unsub;
1252
- }, [runtime, ...states]);
172
+ }, [runtime2, ...states]);
1253
173
  }
1254
174
 
1255
175
  // src/hooks/useOnTransition.ts
1256
176
  import { useEffect as useEffect3, useRef as useRef3 } from "react";
1257
177
  function useOnTransition(effect) {
1258
- const runtime = useRuntimeContext();
178
+ const runtime2 = useRuntimeContext();
1259
179
  const effectRef = useRef3(effect);
1260
180
  effectRef.current = effect;
1261
181
  useEffect3(() => {
1262
- const unsub = runtime.sm.on((event) => {
182
+ const unsub = runtime2.sm.on((event) => {
1263
183
  if (event.type === "transition") {
1264
184
  effectRef.current({
1265
185
  from: event.from_state,
@@ -1268,33 +188,33 @@ function useOnTransition(effect) {
1268
188
  }
1269
189
  });
1270
190
  return unsub;
1271
- }, [runtime]);
191
+ }, [runtime2]);
1272
192
  }
1273
193
 
1274
194
  // src/hooks/useOnEvent.ts
1275
195
  import { useEffect as useEffect4, useRef as useRef4 } from "react";
1276
196
  function useOnEvent(pattern, handler, options) {
1277
- const runtime = useRuntimeContext();
197
+ const runtime2 = useRuntimeContext();
1278
198
  const handlerRef = useRef4(handler);
1279
199
  handlerRef.current = handler;
1280
200
  useEffect4(() => {
1281
- const unsub = runtime.eventBus.subscribe(pattern, (event) => {
1282
- if (options?.while && runtime.sm.currentState !== options.while) return;
201
+ const unsub = runtime2.eventBus.subscribe(pattern, (event) => {
202
+ if (options?.while && runtime2.sm.currentState !== options.while) return;
1283
203
  handlerRef.current(event);
1284
204
  });
1285
205
  return unsub;
1286
- }, [runtime, pattern, options?.while]);
206
+ }, [runtime2, pattern, options?.while]);
1287
207
  }
1288
208
 
1289
209
  // src/hooks/useOnChange.ts
1290
210
  import { useEffect as useEffect5, useRef as useRef5 } from "react";
1291
211
  function useOnChange(field2, handler) {
1292
- const runtime = useRuntimeContext();
212
+ const runtime2 = useRuntimeContext();
1293
213
  const handlerRef = useRef5(handler);
1294
214
  handlerRef.current = handler;
1295
- const prevRef = useRef5(runtime.sm.stateData[field2]);
215
+ const prevRef = useRef5(runtime2.sm.stateData[field2]);
1296
216
  useEffect5(() => {
1297
- const unsub = runtime.subscribe((snap) => {
217
+ const unsub = runtime2.subscribe((snap) => {
1298
218
  const newVal = snap.stateData[field2];
1299
219
  if (newVal !== prevRef.current) {
1300
220
  handlerRef.current(newVal, prevRef.current);
@@ -1302,13 +222,13 @@ function useOnChange(field2, handler) {
1302
222
  }
1303
223
  });
1304
224
  return unsub;
1305
- }, [runtime, field2]);
225
+ }, [runtime2, field2]);
1306
226
  }
1307
227
 
1308
228
  // src/hooks/useWhileIn.ts
1309
229
  import { useEffect as useEffect6, useRef as useRef6 } from "react";
1310
230
  function useWhileIn(stateName, intervalMs, effect) {
1311
- const runtime = useRuntimeContext();
231
+ const runtime2 = useRuntimeContext();
1312
232
  const effectRef = useRef6(effect);
1313
233
  effectRef.current = effect;
1314
234
  useEffect6(() => {
@@ -1323,8 +243,8 @@ function useWhileIn(stateName, intervalMs, effect) {
1323
243
  timer = null;
1324
244
  }
1325
245
  }
1326
- if (runtime.sm.currentState === stateName) startInterval();
1327
- const unsub = runtime.sm.on((event) => {
246
+ if (runtime2.sm.currentState === stateName) startInterval();
247
+ const unsub = runtime2.sm.on((event) => {
1328
248
  if (event.type === "state_enter" && event.to_state === stateName) startInterval();
1329
249
  if (event.type === "state_exit" && event.from_state === stateName) stopInterval();
1330
250
  });
@@ -1332,13 +252,13 @@ function useWhileIn(stateName, intervalMs, effect) {
1332
252
  unsub();
1333
253
  stopInterval();
1334
254
  };
1335
- }, [runtime, stateName, intervalMs]);
255
+ }, [runtime2, stateName, intervalMs]);
1336
256
  }
1337
257
 
1338
258
  // src/hooks/useDuringAction.ts
1339
259
  import { useEffect as useEffect7, useRef as useRef7 } from "react";
1340
260
  function useDuringAction(config) {
1341
- const runtime = useRuntimeContext();
261
+ const runtime2 = useRuntimeContext();
1342
262
  const actionRef = useRef7(config.action);
1343
263
  actionRef.current = config.action;
1344
264
  const states = Array.isArray(config.state) ? config.state : [config.state];
@@ -1376,10 +296,10 @@ function useDuringAction(config) {
1376
296
  timer = null;
1377
297
  }
1378
298
  }
1379
- if (states.includes(runtime.sm.currentState)) {
299
+ if (states.includes(runtime2.sm.currentState)) {
1380
300
  startAction();
1381
301
  }
1382
- const unsub = runtime.sm.on((event) => {
302
+ const unsub = runtime2.sm.on((event) => {
1383
303
  if (event.type === "state_enter" && event.to_state && states.includes(event.to_state)) {
1384
304
  startAction();
1385
305
  }
@@ -1391,7 +311,7 @@ function useDuringAction(config) {
1391
311
  unsub();
1392
312
  stopAction();
1393
313
  };
1394
- }, [runtime, intervalMs, immediate, enabled, ...states]);
314
+ }, [runtime2, intervalMs, immediate, enabled, ...states]);
1395
315
  }
1396
316
 
1397
317
  // src/hooks/useQuery.ts
@@ -1884,29 +804,29 @@ function useServerState(instanceId, options = {}) {
1884
804
  // src/hooks/useWorkflow.ts
1885
805
  import { useState as useState7, useEffect as useEffect12, useMemo, useCallback as useCallback7 } from "react";
1886
806
  function useWorkflow(definition, options) {
1887
- const runtime = useMemo(() => new WorkflowRuntime({
807
+ const runtime2 = useMemo(() => new WorkflowRuntime({
1888
808
  definition,
1889
809
  initialData: options?.initialData,
1890
810
  actionHandlers: options?.actionHandlers
1891
811
  }), [definition.id]);
1892
- const [snapshot, setSnapshot] = useState7(() => runtime.getSnapshot());
812
+ const [snapshot, setSnapshot] = useState7(() => runtime2.getSnapshot());
1893
813
  useEffect12(() => {
1894
- const unsub = runtime.subscribe(setSnapshot);
814
+ const unsub = runtime2.subscribe(setSnapshot);
1895
815
  return unsub;
1896
- }, [runtime]);
816
+ }, [runtime2]);
1897
817
  const transition2 = useCallback7(async (name, data) => {
1898
- const result = await runtime.transition(name, data);
818
+ const result = await runtime2.transition(name, data);
1899
819
  options?.onTransition?.(result);
1900
820
  return result;
1901
- }, [runtime, options?.onTransition]);
821
+ }, [runtime2, options?.onTransition]);
1902
822
  const handle = {
1903
823
  slug: definition.slug,
1904
824
  ...snapshot,
1905
825
  transition: transition2,
1906
- setField: runtime.setField.bind(runtime),
1907
- setMemory: runtime.setMemory.bind(runtime),
1908
- publishEvent: runtime.publishEvent.bind(runtime),
1909
- runtime
826
+ setField: runtime2.setField.bind(runtime2),
827
+ setMemory: runtime2.setMemory.bind(runtime2),
828
+ publishEvent: runtime2.publishEvent.bind(runtime2),
829
+ runtime: runtime2
1910
830
  };
1911
831
  return handle;
1912
832
  }
@@ -1914,17 +834,17 @@ function useWorkflow(definition, options) {
1914
834
  // src/hooks/useTransition.ts
1915
835
  import { useCallback as useCallback8, useState as useState8 } from "react";
1916
836
  function useTransition(transitionName, _config) {
1917
- const runtime = useRuntimeContext();
837
+ const runtime2 = useRuntimeContext();
1918
838
  const [pending, setPending] = useState8(false);
1919
- const available = runtime.sm.getAvailableTransitions().some((t) => t.name === transitionName);
839
+ const available = runtime2.sm.getAvailableTransitions().some((t) => t.name === transitionName);
1920
840
  const fire = useCallback8(async (data) => {
1921
841
  setPending(true);
1922
842
  try {
1923
- return await runtime.transition(transitionName, data);
843
+ return await runtime2.transition(transitionName, data);
1924
844
  } finally {
1925
845
  setPending(false);
1926
846
  }
1927
- }, [runtime, transitionName]);
847
+ }, [runtime2, transitionName]);
1928
848
  const handle = { fire, available, pending };
1929
849
  return handle;
1930
850
  }
@@ -1936,12 +856,12 @@ function setRoleHierarchy(hierarchy) {
1936
856
  _globalHierarchy = hierarchy;
1937
857
  }
1938
858
  function useRole(roleName, options = {}) {
1939
- const runtime = useRuntimeContext();
859
+ const runtime2 = useRuntimeContext();
1940
860
  const hierarchy = options.hierarchy ?? _globalHierarchy ?? [];
1941
861
  const inheritPermissions = options.inheritPermissions ?? true;
1942
862
  const result = useMemo2(() => {
1943
- const snapshot = runtime.getSnapshot();
1944
- const definition = runtime.config?.definition;
863
+ const snapshot = runtime2.getSnapshot();
864
+ const definition = runtime2.config?.definition;
1945
865
  const userRoles = snapshot.stateData?._userRoles ?? snapshot.stateData?.user_roles ?? [];
1946
866
  let hasRole2 = userRoles.includes(roleName);
1947
867
  if (!hasRole2 && hierarchy.length > 0) {
@@ -1989,7 +909,7 @@ function useRole(roleName, options = {}) {
1989
909
  }
1990
910
  }
1991
911
  return { hasRole: hasRole2, permissions, roles: userRoles, highestRole };
1992
- }, [runtime, roleName, hierarchy, inheritPermissions]);
912
+ }, [runtime2, roleName, hierarchy, inheritPermissions]);
1993
913
  const isAbove = useCallback9(
1994
914
  (role) => {
1995
915
  if (hierarchy.length === 0) return false;
@@ -2040,21 +960,21 @@ function useRole(roleName, options = {}) {
2040
960
  // src/hooks/useParams.ts
2041
961
  import { useMemo as useMemo3 } from "react";
2042
962
  function useParams() {
2043
- const runtime = useRuntimeContext();
963
+ const runtime2 = useRuntimeContext();
2044
964
  return useMemo3(() => {
2045
- const snapshot = runtime.getSnapshot();
965
+ const snapshot = runtime2.getSnapshot();
2046
966
  const params = snapshot.stateData?._params ?? snapshot.memory?._callParams ?? {};
2047
967
  return params;
2048
- }, [runtime]);
968
+ }, [runtime2]);
2049
969
  }
2050
970
 
2051
971
  // src/hooks/usePackage.ts
2052
972
  import { useMemo as useMemo4 } from "react";
2053
973
  function usePackage(packageSlug) {
2054
- const runtime = useRuntimeContext();
974
+ const runtime2 = useRuntimeContext();
2055
975
  return useMemo4(() => {
2056
- const snapshot = runtime.getSnapshot();
2057
- const definition = runtime.config?.definition;
976
+ const snapshot = runtime2.getSnapshot();
977
+ const definition = runtime2.config?.definition;
2058
978
  const childDefs = definition?.child_definitions ?? [];
2059
979
  const metadata = definition?.metadata ?? {};
2060
980
  if (definition?.slug === packageSlug && definition?.category === "blueprint") {
@@ -2117,7 +1037,7 @@ function usePackage(packageSlug) {
2117
1037
  isResolved: false,
2118
1038
  dependencySlugs: []
2119
1039
  };
2120
- }, [runtime, packageSlug]);
1040
+ }, [runtime2, packageSlug]);
2121
1041
  }
2122
1042
 
2123
1043
  // src/hooks/useRouter.ts
@@ -2243,16 +1163,16 @@ function useRouter(options = {}) {
2243
1163
  };
2244
1164
  setIsNavigating(true);
2245
1165
  try {
2246
- for (const guard of guardsRef.current) {
2247
- const allowed = await guard(to, location);
1166
+ for (const guard2 of guardsRef.current) {
1167
+ const allowed = await guard2(to, location);
2248
1168
  if (!allowed) {
2249
1169
  onRejectRef.current?.(to);
2250
1170
  return false;
2251
1171
  }
2252
1172
  }
2253
1173
  if (found?.route?.guards) {
2254
- for (const guard of found.route.guards) {
2255
- const allowed = await guard(to, location);
1174
+ for (const guard2 of found.route.guards) {
1175
+ const allowed = await guard2(to, location);
2256
1176
  if (!allowed) {
2257
1177
  if (found.route.redirectOnFail) {
2258
1178
  const fullRedirect = basePathRef.current + found.route.redirectOnFail;
@@ -2678,7 +1598,7 @@ function useGeolocation(options = {}) {
2678
1598
  const {
2679
1599
  enableHighAccuracy = false,
2680
1600
  maximumAge = 0,
2681
- timeout = 1e4,
1601
+ timeout: timeout2 = 1e4,
2682
1602
  watch = false,
2683
1603
  enabled = true
2684
1604
  } = options;
@@ -2689,8 +1609,8 @@ function useGeolocation(options = {}) {
2689
1609
  const watchIdRef = useRef18(null);
2690
1610
  const supported = typeof navigator !== "undefined" && "geolocation" in navigator;
2691
1611
  const positionOptions = useMemo8(
2692
- () => ({ enableHighAccuracy, maximumAge, timeout }),
2693
- [enableHighAccuracy, maximumAge, timeout]
1612
+ () => ({ enableHighAccuracy, maximumAge, timeout: timeout2 }),
1613
+ [enableHighAccuracy, maximumAge, timeout2]
2694
1614
  );
2695
1615
  const handleSuccess = useCallback13((pos) => {
2696
1616
  setPosition({
@@ -3050,7 +1970,7 @@ import { useState as useState16, useCallback as useCallback16, useMemo as useMem
3050
1970
  function useForm(config) {
3051
1971
  const {
3052
1972
  initialValues,
3053
- validate,
1973
+ validate: validate2,
3054
1974
  fieldValidators,
3055
1975
  onSubmit,
3056
1976
  onError,
@@ -3063,8 +1983,8 @@ function useForm(config) {
3063
1983
  const [isSubmitting, setIsSubmitting] = useState16(false);
3064
1984
  const [submitCount, setSubmitCount] = useState16(0);
3065
1985
  const initialRef = useRef20(initialValues);
3066
- const validateRef = useRef20(validate);
3067
- validateRef.current = validate;
1986
+ const validateRef = useRef20(validate2);
1987
+ validateRef.current = validate2;
3068
1988
  const fieldValidatorsRef = useRef20(fieldValidators);
3069
1989
  fieldValidatorsRef.current = fieldValidators;
3070
1990
  const onSubmitRef = useRef20(onSubmit);
@@ -3281,7 +2201,7 @@ function useNotification() {
3281
2201
  setPermission(result);
3282
2202
  return result;
3283
2203
  }, [supported]);
3284
- const notify2 = useCallback17(
2204
+ const notify3 = useCallback17(
3285
2205
  (title, options = {}) => {
3286
2206
  if (!supported || permission !== "granted") return null;
3287
2207
  const {
@@ -3314,8 +2234,8 @@ function useNotification() {
3314
2234
  [supported, permission]
3315
2235
  );
3316
2236
  return useMemo12(
3317
- () => ({ permission, supported, requestPermission, notify: notify2 }),
3318
- [permission, supported, requestPermission, notify2]
2237
+ () => ({ permission, supported, requestPermission, notify: notify3 }),
2238
+ [permission, supported, requestPermission, notify3]
3319
2239
  );
3320
2240
  }
3321
2241
 
@@ -3332,12 +2252,12 @@ function notifyListeners() {
3332
2252
  }
3333
2253
  function addToast(config) {
3334
2254
  const id = `toast-${++_nextId}`;
3335
- const instance = {
2255
+ const instance2 = {
3336
2256
  ...config,
3337
2257
  id,
3338
2258
  createdAt: Date.now()
3339
2259
  };
3340
- _toasts = [..._toasts, instance];
2260
+ _toasts = [..._toasts, instance2];
3341
2261
  const duration = config.duration ?? 5e3;
3342
2262
  if (duration > 0) {
3343
2263
  const timer = setTimeout(() => {
@@ -3388,8 +2308,191 @@ function useToast() {
3388
2308
  );
3389
2309
  }
3390
2310
 
2311
+ // src/hooks/useVisibility.ts
2312
+ import { useMemo as useMemo14 } from "react";
2313
+ function useVisibility(model2, role, playerType) {
2314
+ return useMemo14(() => {
2315
+ return computeVisibility(model2, role, playerType);
2316
+ }, [model2, role, playerType]);
2317
+ }
2318
+ function computeVisibility(model2, role, playerType) {
2319
+ const allFields = Object.keys(model2.fields || {});
2320
+ const allStates = Object.keys(model2.states || {});
2321
+ const vis = model2.orchestration?.visibility;
2322
+ if (!vis) {
2323
+ return makeResult(allFields, allStates);
2324
+ }
2325
+ let roleFields;
2326
+ let roleStates;
2327
+ let playerFields;
2328
+ if (role && vis.roles && vis.roles[role]) {
2329
+ const rv = vis.roles[role];
2330
+ roleFields = rv.fields === "*" ? "*" : [...rv.fields];
2331
+ roleStates = rv.states === "*" ? "*" : rv.states ? [...rv.states] : "*";
2332
+ }
2333
+ if (playerType && vis.players && vis.players[playerType]) {
2334
+ const pv = vis.players[playerType];
2335
+ playerFields = pv.fields === "*" ? "*" : [...pv.fields];
2336
+ }
2337
+ if (roleFields === void 0 && playerFields === void 0) {
2338
+ return makeResult(allFields, allStates);
2339
+ }
2340
+ let resolvedFields;
2341
+ if (roleFields === "*" && playerFields === "*") {
2342
+ resolvedFields = allFields;
2343
+ } else if (roleFields === "*") {
2344
+ resolvedFields = playerFields === void 0 ? allFields : playerFields;
2345
+ } else if (playerFields === "*") {
2346
+ resolvedFields = roleFields === void 0 ? allFields : roleFields;
2347
+ } else if (roleFields !== void 0 && playerFields !== void 0) {
2348
+ const roleSet = new Set(roleFields);
2349
+ resolvedFields = playerFields.filter((f) => roleSet.has(f));
2350
+ } else {
2351
+ resolvedFields = roleFields || playerFields || allFields;
2352
+ }
2353
+ const resolvedStates = roleStates === "*" || roleStates === void 0 ? allStates : roleStates;
2354
+ return makeResult(resolvedFields, resolvedStates);
2355
+ }
2356
+ function makeResult(fields, states) {
2357
+ const fieldSet = new Set(fields);
2358
+ const stateSet = new Set(states);
2359
+ return {
2360
+ visibleFields: fields,
2361
+ visibleStates: states,
2362
+ canSeeField: (f) => fieldSet.has(f),
2363
+ canSeeState: (s) => stateSet.has(s)
2364
+ };
2365
+ }
2366
+
2367
+ // src/hooks/usePresence.ts
2368
+ import { useState as useState19, useEffect as useEffect20, useCallback as useCallback19, useRef as useRef22 } from "react";
2369
+ var PRESENCE_EVENTS = {
2370
+ JOIN: "presence:join",
2371
+ LEAVE: "presence:leave",
2372
+ HEARTBEAT: "presence:heartbeat",
2373
+ EDIT_START: "presence:edit_start",
2374
+ EDIT_STOP: "presence:edit_stop"
2375
+ };
2376
+ function usePresence(instanceId, options = {}) {
2377
+ const {
2378
+ userId = "anonymous",
2379
+ userName = "Anonymous",
2380
+ wsUrl,
2381
+ enabled = true,
2382
+ heartbeatInterval = 15e3,
2383
+ staleTimeout = 45e3
2384
+ } = options;
2385
+ const channelName = `presence:${instanceId}`;
2386
+ const { publish, subscribe, connected } = useChannel(channelName, {
2387
+ wsUrl,
2388
+ enabled
2389
+ });
2390
+ const [viewers, setViewers] = useState19([]);
2391
+ const [editors, setEditors] = useState19([]);
2392
+ const viewersRef = useRef22(/* @__PURE__ */ new Map());
2393
+ const editorsRef = useRef22(/* @__PURE__ */ new Map());
2394
+ useEffect20(() => {
2395
+ if (!connected || !enabled) return;
2396
+ publish(PRESENCE_EVENTS.JOIN, { id: userId, name: userName, connectedAt: Date.now() });
2397
+ const hb = setInterval(() => {
2398
+ publish(PRESENCE_EVENTS.HEARTBEAT, { id: userId, name: userName });
2399
+ }, heartbeatInterval);
2400
+ return () => {
2401
+ clearInterval(hb);
2402
+ publish(PRESENCE_EVENTS.LEAVE, { id: userId });
2403
+ };
2404
+ }, [connected, enabled, userId, userName, heartbeatInterval, publish]);
2405
+ useEffect20(() => {
2406
+ if (!enabled) return;
2407
+ const cleanup = setInterval(() => {
2408
+ const now = Date.now();
2409
+ const stale = [];
2410
+ for (const [id, v] of viewersRef.current) {
2411
+ if (now - v.connectedAt > staleTimeout) stale.push(id);
2412
+ }
2413
+ if (stale.length > 0) {
2414
+ for (const id of stale) {
2415
+ viewersRef.current.delete(id);
2416
+ editorsRef.current.delete(id);
2417
+ }
2418
+ setViewers(Array.from(viewersRef.current.values()));
2419
+ setEditors(Array.from(editorsRef.current.values()));
2420
+ }
2421
+ }, staleTimeout / 3);
2422
+ return () => clearInterval(cleanup);
2423
+ }, [enabled, staleTimeout]);
2424
+ useEffect20(() => {
2425
+ if (!enabled) return;
2426
+ const unsubs = [];
2427
+ unsubs.push(subscribe(PRESENCE_EVENTS.JOIN, (data) => {
2428
+ if (data.id === userId) return;
2429
+ viewersRef.current.set(data.id, {
2430
+ id: data.id,
2431
+ name: data.name || "Anonymous",
2432
+ connectedAt: data.connectedAt || Date.now()
2433
+ });
2434
+ setViewers(Array.from(viewersRef.current.values()));
2435
+ }));
2436
+ unsubs.push(subscribe(PRESENCE_EVENTS.LEAVE, (data) => {
2437
+ viewersRef.current.delete(data.id);
2438
+ editorsRef.current.delete(data.id);
2439
+ setViewers(Array.from(viewersRef.current.values()));
2440
+ setEditors(Array.from(editorsRef.current.values()));
2441
+ }));
2442
+ unsubs.push(subscribe(PRESENCE_EVENTS.HEARTBEAT, (data) => {
2443
+ if (data.id === userId) return;
2444
+ const existing = viewersRef.current.get(data.id);
2445
+ if (existing) {
2446
+ existing.connectedAt = Date.now();
2447
+ } else {
2448
+ viewersRef.current.set(data.id, {
2449
+ id: data.id,
2450
+ name: data.name || "Anonymous",
2451
+ connectedAt: Date.now()
2452
+ });
2453
+ setViewers(Array.from(viewersRef.current.values()));
2454
+ }
2455
+ }));
2456
+ unsubs.push(subscribe(PRESENCE_EVENTS.EDIT_START, (data) => {
2457
+ if (data.id === userId) return;
2458
+ editorsRef.current.set(data.id, {
2459
+ id: data.id,
2460
+ name: data.name || "Anonymous",
2461
+ field: data.field,
2462
+ startedAt: Date.now()
2463
+ });
2464
+ setEditors(Array.from(editorsRef.current.values()));
2465
+ }));
2466
+ unsubs.push(subscribe(PRESENCE_EVENTS.EDIT_STOP, (data) => {
2467
+ editorsRef.current.delete(data.id);
2468
+ setEditors(Array.from(editorsRef.current.values()));
2469
+ }));
2470
+ return () => unsubs.forEach((fn) => fn());
2471
+ }, [enabled, userId, subscribe]);
2472
+ const startEditing = useCallback19((field2) => {
2473
+ publish(PRESENCE_EVENTS.EDIT_START, { id: userId, name: userName, field: field2 });
2474
+ }, [publish, userId, userName]);
2475
+ const stopEditing = useCallback19((_field) => {
2476
+ publish(PRESENCE_EVENTS.EDIT_STOP, { id: userId });
2477
+ }, [publish, userId]);
2478
+ const isEditing = useCallback19((field2) => {
2479
+ for (const editor of editorsRef.current.values()) {
2480
+ if (editor.field === field2 && editor.id !== userId) return true;
2481
+ }
2482
+ return false;
2483
+ }, [userId]);
2484
+ return {
2485
+ viewers,
2486
+ editors,
2487
+ viewerCount: viewers.length,
2488
+ isEditing,
2489
+ startEditing,
2490
+ stopEditing
2491
+ };
2492
+ }
2493
+
3391
2494
  // src/hooks/useMiddleware.ts
3392
- import { useState as useState19, useEffect as useEffect20, useRef as useRef22, useMemo as useMemo14 } from "react";
2495
+ import { useState as useState20, useEffect as useEffect21, useRef as useRef23, useMemo as useMemo15 } from "react";
3393
2496
  function requireAuth(loginPath = "/login") {
3394
2497
  return (ctx) => {
3395
2498
  if (!ctx.token) {
@@ -3461,24 +2564,24 @@ function useMiddleware(middlewares, options = {}) {
3461
2564
  watchPathname = true,
3462
2565
  onRedirect
3463
2566
  } = options;
3464
- const [ready, setReady] = useState19(false);
3465
- const [loading, setLoading] = useState19(true);
3466
- const [redirect, setRedirect] = useState19(null);
3467
- const [error, setError] = useState19(null);
3468
- const [data, setData] = useState19({});
3469
- const [runKey, setRunKey] = useState19(0);
3470
- const middlewaresRef = useRef22(middlewares);
2567
+ const [ready, setReady] = useState20(false);
2568
+ const [loading, setLoading] = useState20(true);
2569
+ const [redirect, setRedirect] = useState20(null);
2570
+ const [error, setError] = useState20(null);
2571
+ const [data, setData] = useState20({});
2572
+ const [runKey, setRunKey] = useState20(0);
2573
+ const middlewaresRef = useRef23(middlewares);
3471
2574
  middlewaresRef.current = middlewares;
3472
- const onRedirectRef = useRef22(onRedirect);
2575
+ const onRedirectRef = useRef23(onRedirect);
3473
2576
  onRedirectRef.current = onRedirect;
3474
- const [pathname, setPathname] = useState19(getPathname);
3475
- useEffect20(() => {
2577
+ const [pathname, setPathname] = useState20(getPathname);
2578
+ useEffect21(() => {
3476
2579
  if (!watchPathname) return;
3477
2580
  const handler = () => setPathname(getPathname());
3478
2581
  window.addEventListener("popstate", handler);
3479
2582
  return () => window.removeEventListener("popstate", handler);
3480
2583
  }, [watchPathname]);
3481
- useEffect20(() => {
2584
+ useEffect21(() => {
3482
2585
  if (!enabled) {
3483
2586
  setReady(true);
3484
2587
  setLoading(false);
@@ -3525,11 +2628,11 @@ function useMiddleware(middlewares, options = {}) {
3525
2628
  cancelled = true;
3526
2629
  };
3527
2630
  }, [enabled, pathname, runKey]);
3528
- const rerun = useMemo14(
2631
+ const rerun = useMemo15(
3529
2632
  () => () => setRunKey((k) => k + 1),
3530
2633
  []
3531
2634
  );
3532
- return useMemo14(
2635
+ return useMemo15(
3533
2636
  () => ({ ready, loading, redirect, error, data, rerun }),
3534
2637
  [ready, loading, redirect, error, data, rerun]
3535
2638
  );
@@ -3539,8 +2642,8 @@ function useMiddleware(middlewares, options = {}) {
3539
2642
  import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
3540
2643
  import { jsx } from "react/jsx-runtime";
3541
2644
  var defaultQueryClient = new QueryClient();
3542
- function WorkflowProvider({ runtime, queryClient, children }) {
3543
- return /* @__PURE__ */ jsx(QueryClientProvider, { client: queryClient ?? defaultQueryClient, children: /* @__PURE__ */ jsx(RuntimeContext.Provider, { value: runtime, children }) });
2645
+ function WorkflowProvider({ runtime: runtime2, queryClient, children }) {
2646
+ return /* @__PURE__ */ jsx(QueryClientProvider, { client: queryClient ?? defaultQueryClient, children: /* @__PURE__ */ jsx(RuntimeContext.Provider, { value: runtime2, children }) });
3544
2647
  }
3545
2648
 
3546
2649
  // src/local/LocalEngine.ts
@@ -3601,8 +2704,8 @@ var LocalWorkflowEngine = class {
3601
2704
  * Process all pending events from a transition result.
3602
2705
  * Emits locally and returns the events for P2P broadcast.
3603
2706
  */
3604
- processPendingEvents(instance) {
3605
- const events = instance._pendingEvents;
2707
+ processPendingEvents(instance2) {
2708
+ const events = instance2._pendingEvents;
3606
2709
  if (!events?.length) return [];
3607
2710
  for (const evt of events) {
3608
2711
  this.emitEvent(evt);
@@ -3645,18 +2748,18 @@ var LocalWorkflowEngine = class {
3645
2748
  };
3646
2749
  }
3647
2750
  /** Check if a transition can fire from the instance's current state */
3648
- canTransition(instance, transitionName) {
3649
- const def = this.definitions.get(instance.definitionSlug);
2751
+ canTransition(instance2, transitionName) {
2752
+ const def = this.definitions.get(instance2.definitionSlug);
3650
2753
  if (!def) return false;
3651
2754
  const transition2 = def.transitions.find((t) => t.name === transitionName);
3652
2755
  if (!transition2) return false;
3653
- return transition2.from.includes(instance.currentState);
2756
+ return transition2.from.includes(instance2.currentState);
3654
2757
  }
3655
2758
  /** Get all transitions available from the instance's current state */
3656
- getAvailableTransitions(instance) {
3657
- const def = this.definitions.get(instance.definitionSlug);
2759
+ getAvailableTransitions(instance2) {
2760
+ const def = this.definitions.get(instance2.definitionSlug);
3658
2761
  if (!def) return [];
3659
- return def.transitions.filter((t) => t.from.includes(instance.currentState)).map((t) => t.name);
2762
+ return def.transitions.filter((t) => t.from.includes(instance2.currentState)).map((t) => t.name);
3660
2763
  }
3661
2764
  /**
3662
2765
  * Apply a transition, returning a new WorkflowInstance (immutable).
@@ -3667,29 +2770,29 @@ var LocalWorkflowEngine = class {
3667
2770
  * @returns New WorkflowInstance with updated state and version
3668
2771
  * @throws If transition is not valid from current state
3669
2772
  */
3670
- applyTransition(instance, transitionName, data) {
3671
- const def = this.definitions.get(instance.definitionSlug);
2773
+ applyTransition(instance2, transitionName, data) {
2774
+ const def = this.definitions.get(instance2.definitionSlug);
3672
2775
  if (!def) {
3673
- throw new Error(`Definition not found: ${instance.definitionSlug}`);
2776
+ throw new Error(`Definition not found: ${instance2.definitionSlug}`);
3674
2777
  }
3675
2778
  const transition2 = def.transitions.find((t) => t.name === transitionName);
3676
2779
  if (!transition2) {
3677
2780
  throw new Error(
3678
- `Transition "${transitionName}" not found in ${instance.definitionSlug}`
2781
+ `Transition "${transitionName}" not found in ${instance2.definitionSlug}`
3679
2782
  );
3680
2783
  }
3681
- if (!transition2.from.includes(instance.currentState)) {
2784
+ if (!transition2.from.includes(instance2.currentState)) {
3682
2785
  throw new Error(
3683
- `Transition "${transitionName}" cannot fire from state "${instance.currentState}" (allowed from: ${transition2.from.join(", ")})`
2786
+ `Transition "${transitionName}" cannot fire from state "${instance2.currentState}" (allowed from: ${transition2.from.join(", ")})`
3684
2787
  );
3685
2788
  }
3686
- const nextState = transition2.to ?? instance.currentState;
3687
- const fields = data ? { ...instance.fields, ...data } : { ...instance.fields };
2789
+ const nextState = transition2.to ?? instance2.currentState;
2790
+ const fields = data ? { ...instance2.fields, ...data } : { ...instance2.fields };
3688
2791
  let result = {
3689
- ...instance,
2792
+ ...instance2,
3690
2793
  currentState: nextState,
3691
2794
  fields,
3692
- version: instance.version + 1,
2795
+ version: instance2.version + 1,
3693
2796
  updatedAt: Date.now()
3694
2797
  };
3695
2798
  const targetStateDef = def.states.find((s) => s.name === nextState);
@@ -3762,14 +2865,14 @@ var LocalWorkflowEngine = class {
3762
2865
  * Apply a transition only if the incoming version is newer.
3763
2866
  * Used for P2P sync — skips stale transitions.
3764
2867
  */
3765
- applyRemoteTransition(instance, transitionName, data, remoteVersion) {
3766
- if (remoteVersion <= instance.version) {
2868
+ applyRemoteTransition(instance2, transitionName, data, remoteVersion) {
2869
+ if (remoteVersion <= instance2.version) {
3767
2870
  return null;
3768
2871
  }
3769
- if (!this.canTransition(instance, transitionName)) {
2872
+ if (!this.canTransition(instance2, transitionName)) {
3770
2873
  return null;
3771
2874
  }
3772
- const updated = this.applyTransition(instance, transitionName, data);
2875
+ const updated = this.applyTransition(instance2, transitionName, data);
3773
2876
  return { ...updated, version: remoteVersion };
3774
2877
  }
3775
2878
  };
@@ -4035,6 +3138,155 @@ function defineModel(def) {
4035
3138
  return def;
4036
3139
  }
4037
3140
 
3141
+ // src/config/orchestration-presets.ts
3142
+ var SOLO = {
3143
+ strategy: "solo",
3144
+ evaluation: { pure: "local" },
3145
+ scheduling: { coordinator: "any" },
3146
+ events: { evaluator: "any-subscriber" },
3147
+ errorHandling: { strategy: "manual" },
3148
+ conflicts: { default: "last-writer-wins", fields: {} },
3149
+ visibility: { roles: {}, players: {} },
3150
+ presence: { enabled: false, showEditing: false, showViewing: false },
3151
+ services: {},
3152
+ actionRouting: {}
3153
+ };
3154
+ var CLIENT_SERVER = {
3155
+ strategy: "client-server",
3156
+ evaluation: { pure: "local" },
3157
+ scheduling: { coordinator: "server" },
3158
+ events: { evaluator: "server" },
3159
+ errorHandling: { strategy: "rollback" },
3160
+ conflicts: { default: "last-writer-wins", fields: {} },
3161
+ visibility: { roles: {}, players: {} },
3162
+ presence: { enabled: false, showEditing: false, showViewing: false },
3163
+ services: {},
3164
+ actionRouting: {}
3165
+ };
3166
+ var MULTI_CLIENT = {
3167
+ strategy: "multi-client",
3168
+ evaluation: { pure: "local" },
3169
+ scheduling: { coordinator: "server" },
3170
+ events: { evaluator: "server" },
3171
+ errorHandling: { strategy: "compensate" },
3172
+ conflicts: { default: "last-writer-wins", fields: {} },
3173
+ visibility: { roles: {}, players: {} },
3174
+ presence: { enabled: true, showEditing: true, showViewing: true, conflictHighlight: true },
3175
+ services: {},
3176
+ actionRouting: {}
3177
+ };
3178
+ var SERVICE_MESH = {
3179
+ strategy: "service-mesh",
3180
+ evaluation: { pure: "local" },
3181
+ scheduling: { coordinator: "server" },
3182
+ events: { evaluator: "all" },
3183
+ errorHandling: { strategy: "saga" },
3184
+ conflicts: { default: "first-write-wins", fields: {} },
3185
+ visibility: { roles: {}, players: {} },
3186
+ presence: { enabled: false, showEditing: false, showViewing: false },
3187
+ services: {},
3188
+ actionRouting: {}
3189
+ };
3190
+ var PEER_TO_PEER = {
3191
+ strategy: "peer-to-peer",
3192
+ evaluation: { pure: "local" },
3193
+ scheduling: { coordinator: "any" },
3194
+ events: { evaluator: "any-subscriber" },
3195
+ errorHandling: { strategy: "compensate" },
3196
+ conflicts: { default: "crdt", fields: {} },
3197
+ visibility: { roles: {}, players: {} },
3198
+ presence: { enabled: true, showEditing: true, showViewing: true, conflictHighlight: false },
3199
+ services: {},
3200
+ actionRouting: {}
3201
+ };
3202
+ var HYBRID = {
3203
+ strategy: "hybrid",
3204
+ evaluation: { pure: "local" },
3205
+ scheduling: { coordinator: "server" },
3206
+ events: { evaluator: "server" },
3207
+ errorHandling: { strategy: "saga" },
3208
+ conflicts: { default: "last-writer-wins", fields: {} },
3209
+ visibility: { roles: {}, players: {} },
3210
+ presence: { enabled: true, showEditing: true, showViewing: false, conflictHighlight: false },
3211
+ services: {},
3212
+ actionRouting: {}
3213
+ };
3214
+ var HEADLESS = {
3215
+ strategy: "headless",
3216
+ evaluation: { pure: "local" },
3217
+ // expression engine runs server-local (native Rust, fastest)
3218
+ scheduling: { coordinator: "server" },
3219
+ // server manages cron/interval/timeout
3220
+ events: { evaluator: "server" },
3221
+ // server matches events, no clients involved
3222
+ errorHandling: { strategy: "compensate" },
3223
+ conflicts: { default: "first-write-wins", fields: {} },
3224
+ // no concurrent clients
3225
+ visibility: { roles: {}, players: {} },
3226
+ presence: { enabled: false, showEditing: false, showViewing: false, conflictHighlight: false },
3227
+ services: {},
3228
+ actionRouting: {}
3229
+ };
3230
+ var ORCHESTRATION_PRESETS = {
3231
+ "solo": SOLO,
3232
+ "client-server": CLIENT_SERVER,
3233
+ "multi-client": MULTI_CLIENT,
3234
+ "service-mesh": SERVICE_MESH,
3235
+ "peer-to-peer": PEER_TO_PEER,
3236
+ "hybrid": HYBRID,
3237
+ "headless": HEADLESS,
3238
+ "custom": CLIENT_SERVER
3239
+ // custom uses client-server as base
3240
+ };
3241
+ var DEFAULT_RESOLVED = {
3242
+ strategy: "client-server",
3243
+ evaluation: { pure: "local" },
3244
+ scheduling: { coordinator: "server" },
3245
+ events: { evaluator: "server" },
3246
+ errorHandling: { strategy: "rollback" },
3247
+ conflicts: { default: "last-writer-wins", fields: {} },
3248
+ visibility: { roles: {}, players: {} },
3249
+ presence: { enabled: false, showEditing: false, showViewing: false, conflictHighlight: false },
3250
+ services: {},
3251
+ actionRouting: {}
3252
+ };
3253
+ function resolveOrchestration(config) {
3254
+ if (!config) return { ...DEFAULT_RESOLVED };
3255
+ const strategy = config.strategy || "client-server";
3256
+ const preset = ORCHESTRATION_PRESETS[strategy] || CLIENT_SERVER;
3257
+ return {
3258
+ strategy,
3259
+ evaluation: {
3260
+ pure: config.evaluation?.pure ?? preset.evaluation?.pure ?? "local"
3261
+ },
3262
+ scheduling: {
3263
+ coordinator: config.scheduling?.coordinator ?? preset.scheduling?.coordinator ?? "server"
3264
+ },
3265
+ events: {
3266
+ evaluator: config.events?.evaluator ?? preset.events?.evaluator ?? "server"
3267
+ },
3268
+ errorHandling: {
3269
+ strategy: config.errorHandling?.strategy ?? preset.errorHandling?.strategy ?? "rollback"
3270
+ },
3271
+ conflicts: {
3272
+ default: config.conflicts?.default ?? preset.conflicts?.default ?? "last-writer-wins",
3273
+ fields: { ...preset.conflicts?.fields || {}, ...config.conflicts?.fields || {} }
3274
+ },
3275
+ visibility: {
3276
+ roles: { ...preset.visibility?.roles || {}, ...config.visibility?.roles || {} },
3277
+ players: { ...preset.visibility?.players || {}, ...config.visibility?.players || {} }
3278
+ },
3279
+ presence: {
3280
+ enabled: config.presence?.enabled ?? preset.presence?.enabled ?? false,
3281
+ showEditing: config.presence?.showEditing ?? preset.presence?.showEditing ?? false,
3282
+ showViewing: config.presence?.showViewing ?? preset.presence?.showViewing ?? false,
3283
+ conflictHighlight: config.presence?.conflictHighlight ?? preset.presence?.conflictHighlight ?? false
3284
+ },
3285
+ services: { ...preset.services || {}, ...config.services || {} },
3286
+ actionRouting: { ...preset.actionRouting || {}, ...config.actionRouting || {} }
3287
+ };
3288
+ }
3289
+
4038
3290
  // src/config/defineBlueprint.ts
4039
3291
  function defineBlueprint(config) {
4040
3292
  if (!config.slug) {
@@ -4148,13 +3400,13 @@ function inState(state2) {
4148
3400
  function notInState(state2) {
4149
3401
  return { type: "expression", expression: `current_state != "${state2}"` };
4150
3402
  }
4151
- function and2(...conditions) {
3403
+ function and(...conditions) {
4152
3404
  return { AND: conditions.map(normalize) };
4153
3405
  }
4154
- function or2(...conditions) {
3406
+ function or(...conditions) {
4155
3407
  return { OR: conditions.map(normalize) };
4156
3408
  }
4157
- function not2(condition) {
3409
+ function not(condition) {
4158
3410
  const c = normalize(condition);
4159
3411
  if (c.type === "expression" && c.expression) {
4160
3412
  return { type: "expression", expression: `NOT(${c.expression})` };
@@ -4199,7 +3451,7 @@ function refHasAnyRole(slug, lookupField, lookupValue, roles) {
4199
3451
  }
4200
3452
 
4201
3453
  // src/hooks/useModel.ts
4202
- import { useCallback as useCallback19, useRef as useRef23, useMemo as useMemo15 } from "react";
3454
+ import { useCallback as useCallback20, useRef as useRef24, useMemo as useMemo16 } from "react";
4203
3455
  function getDefaultFields(definition) {
4204
3456
  const defaults = {};
4205
3457
  for (const [key, field2] of Object.entries(definition.fields)) {
@@ -4254,18 +3506,18 @@ function useModel(definition, options = {}) {
4254
3506
  if (options.state) queryParams.state = options.state;
4255
3507
  const query = useQuery(slug, queryParams);
4256
3508
  const mutation = useMutation(slug);
4257
- const instance = query.data?.[0];
4258
- const instanceId = instance?.id ?? null;
4259
- const currentState = instance?.currentState ?? "";
4260
- const instanceFields = instance?.fields ?? null;
4261
- const defaultFields = useMemo15(() => getDefaultFields(definition), [definition]);
4262
- const fields = useMemo15(() => {
3509
+ const instance2 = query.data?.[0];
3510
+ const instanceId = instance2?.id ?? null;
3511
+ const currentState = instance2?.currentState ?? "";
3512
+ const instanceFields = instance2?.fields ?? null;
3513
+ const defaultFields = useMemo16(() => getDefaultFields(definition), [definition]);
3514
+ const fields = useMemo16(() => {
4263
3515
  if (!instanceFields) return defaultFields;
4264
3516
  return { ...defaultFields, ...instanceFields };
4265
3517
  }, [instanceFields, defaultFields]);
4266
- const instanceIdRef = useRef23(instanceId);
3518
+ const instanceIdRef = useRef24(instanceId);
4267
3519
  instanceIdRef.current = instanceId;
4268
- const trigger = useCallback19(async (name, input) => {
3520
+ const trigger = useCallback20(async (name, input) => {
4269
3521
  const id = instanceIdRef.current;
4270
3522
  if (!id) {
4271
3523
  throw new Error(`useModel(${slug}): No instance loaded. Cannot trigger '${name}'.`);
@@ -4273,12 +3525,12 @@ function useModel(definition, options = {}) {
4273
3525
  await mutation.transition(id, name, input);
4274
3526
  await query.refetch();
4275
3527
  }, [slug, mutation, query]);
4276
- const create = useCallback19(async (input) => {
3528
+ const create = useCallback20(async (input) => {
4277
3529
  const id = await mutation.create(input);
4278
3530
  await query.refetch();
4279
3531
  return id;
4280
3532
  }, [mutation, query]);
4281
- const update = useCallback19(async (fieldUpdates) => {
3533
+ const update = useCallback20(async (fieldUpdates) => {
4282
3534
  const id = instanceIdRef.current;
4283
3535
  if (!id) {
4284
3536
  throw new Error(`useModel(${slug}): No instance loaded. Cannot update.`);
@@ -4307,27 +3559,27 @@ function useCollection(definition, options = {}) {
4307
3559
  const slug = definition.slug;
4308
3560
  const query = useQuery(slug, options);
4309
3561
  const mutation = useMutation(slug);
4310
- const items = useMemo15(() => {
4311
- return (query.data || []).map((instance) => ({
4312
- id: instance.id,
4313
- fields: instance.fields ?? {},
4314
- state: instance.currentState ?? ""
3562
+ const items = useMemo16(() => {
3563
+ return (query.data || []).map((instance2) => ({
3564
+ id: instance2.id,
3565
+ fields: instance2.fields ?? {},
3566
+ state: instance2.currentState ?? ""
4315
3567
  }));
4316
3568
  }, [query.data]);
4317
- const trigger = useCallback19(async (instanceId, name, input) => {
3569
+ const trigger = useCallback20(async (instanceId, name, input) => {
4318
3570
  await mutation.transition(instanceId, name, input);
4319
3571
  await query.refetch();
4320
3572
  }, [mutation, query]);
4321
- const create = useCallback19(async (input) => {
3573
+ const create = useCallback20(async (input) => {
4322
3574
  const id = await mutation.create(input);
4323
3575
  await query.refetch();
4324
3576
  return id;
4325
3577
  }, [mutation, query]);
4326
- const update = useCallback19(async (instanceId, fieldUpdates) => {
3578
+ const update = useCallback20(async (instanceId, fieldUpdates) => {
4327
3579
  await mutation.update(instanceId, fieldUpdates);
4328
3580
  await query.refetch();
4329
3581
  }, [mutation, query]);
4330
- const remove = useCallback19(async (instanceId) => {
3582
+ const remove = useCallback20(async (instanceId) => {
4331
3583
  await mutation.remove(instanceId);
4332
3584
  await query.refetch();
4333
3585
  }, [mutation, query]);
@@ -4351,7 +3603,7 @@ function useCollection(definition, options = {}) {
4351
3603
  function stub(displayName) {
4352
3604
  const Component = () => {
4353
3605
  throw new Error(
4354
- `<${displayName}> is a compile-time stub from @mindmatrix/react/atoms. It should only appear in .workflow.tsx files processed by the compiler. At runtime, use the ComponentTreeRenderer which resolves "${displayName}" from the component registry.`
3606
+ `<${displayName}> is a compile-time stub from @mmapp/react/atoms. It should only appear in .workflow.tsx files processed by the compiler. At runtime, use the ComponentTreeRenderer which resolves "${displayName}" from the component registry.`
4355
3607
  );
4356
3608
  };
4357
3609
  Component.displayName = displayName;
@@ -4478,7 +3730,7 @@ function djb2Hash(str) {
4478
3730
  }
4479
3731
 
4480
3732
  // src/authoring.ts
4481
- function useState20(_defaultOrKey) {
3733
+ function useState21(_defaultOrKey) {
4482
3734
  return [void 0, () => {
4483
3735
  }];
4484
3736
  }
@@ -4489,10 +3741,10 @@ function defineWorkspace(config) {
4489
3741
  }
4490
3742
 
4491
3743
  // src/hooks/useModule.ts
4492
- import { useMemo as useMemo16 } from "react";
3744
+ import { useMemo as useMemo17 } from "react";
4493
3745
  function useModule(slug, config = {}, options = {}) {
4494
3746
  const { enabled = true } = options;
4495
- return useMemo16(() => ({
3747
+ return useMemo17(() => ({
4496
3748
  slug,
4497
3749
  config,
4498
3750
  isLoaded: enabled
@@ -4500,7 +3752,7 @@ function useModule(slug, config = {}, options = {}) {
4500
3752
  }
4501
3753
 
4502
3754
  // src/hooks/useModuleConfig.ts
4503
- import { useCallback as useCallback20, useMemo as useMemo17, useState as useState21 } from "react";
3755
+ import { useCallback as useCallback21, useMemo as useMemo18, useState as useState22 } from "react";
4504
3756
  var installedModulesStore = [];
4505
3757
  var configDefaultsStore = /* @__PURE__ */ new Map();
4506
3758
  function setInstalledModules(modules) {
@@ -4516,7 +3768,7 @@ function getInstalledModules() {
4516
3768
  return installedModulesStore;
4517
3769
  }
4518
3770
  function useModuleConfig(moduleSlug) {
4519
- return useMemo17(() => {
3771
+ return useMemo18(() => {
4520
3772
  const installed = getInstalledModule(moduleSlug);
4521
3773
  const defaults = configDefaultsStore.get(moduleSlug) ?? {};
4522
3774
  const persisted = persistedConfigStore.get(moduleSlug) ?? {};
@@ -4564,8 +3816,8 @@ async function updateDefinitionConfig(values, definitionId) {
4564
3816
  }
4565
3817
  function useModuleConfigWithMutation(moduleSlug) {
4566
3818
  const config = useModuleConfig(moduleSlug);
4567
- const [isSaving, setIsSaving] = useState21(false);
4568
- const updateConfig = useCallback20(async (values) => {
3819
+ const [isSaving, setIsSaving] = useState22(false);
3820
+ const updateConfig = useCallback21(async (values) => {
4569
3821
  setIsSaving(true);
4570
3822
  try {
4571
3823
  return await updateDefinitionConfig(values);
@@ -6078,7 +5330,7 @@ function approval(config = {}) {
6078
5330
  }
6079
5331
  function escalation(config) {
6080
5332
  const {
6081
- timeout,
5333
+ timeout: timeout2,
6082
5334
  notifyRole = "admin",
6083
5335
  fromState = "pending_approval",
6084
5336
  escalatedState = "escalated"
@@ -6090,7 +5342,7 @@ function escalation(config) {
6090
5342
  });
6091
5343
  if (def.states[fromState]) {
6092
5344
  def.states[fromState].timeout = {
6093
- duration: timeout,
5345
+ duration: timeout2,
6094
5346
  fallback: { transition: "escalate" }
6095
5347
  };
6096
5348
  }
@@ -6109,8 +5361,8 @@ function escalation(config) {
6109
5361
  from: fromState,
6110
5362
  to: escalatedState,
6111
5363
  auto: true,
6112
- description: `Auto-escalate after ${timeout}`,
6113
- actions: [logEvent("escalated", { timeout })]
5364
+ description: `Auto-escalate after ${timeout2}`,
5365
+ actions: [logEvent("escalated", { timeout: timeout2 })]
6114
5366
  }
6115
5367
  });
6116
5368
  return def;
@@ -6768,7 +6020,14 @@ function describeModel(def) {
6768
6020
  }
6769
6021
 
6770
6022
  // src/hooks/usePlayer.ts
6771
- import { useCallback as useCallback21, useEffect as useEffect21, useMemo as useMemo18, useRef as useRef24, useState as useState22 } from "react";
6023
+ import { useCallback as useCallback22, useEffect as useEffect22, useMemo as useMemo19, useRef as useRef25, useState as useState23 } from "react";
6024
+ import {
6025
+ StateMachine as StateMachine2,
6026
+ EventBus as EventBus2,
6027
+ ActionDispatcher as ActionDispatcher2,
6028
+ createEvaluator as createEvaluator2,
6029
+ WEB_FAILURE_POLICIES as WEB_FAILURE_POLICIES2
6030
+ } from "@mmapp/player-core";
6772
6031
 
6773
6032
  // src/logger.ts
6774
6033
  var debugEnabled = false;
@@ -6808,18 +6067,18 @@ function computePlayerState(sm) {
6808
6067
  };
6809
6068
  }
6810
6069
  function usePlayer(config) {
6811
- const configRef = useRef24(config);
6070
+ const configRef = useRef25(config);
6812
6071
  configRef.current = config;
6813
- useEffect21(() => {
6072
+ useEffect22(() => {
6814
6073
  if (config.debug) setPlayerDebug(true);
6815
6074
  }, [config.debug]);
6816
- const evaluator = useMemo18(() => {
6817
- return createEvaluator({
6075
+ const evaluator = useMemo19(() => {
6076
+ return createEvaluator2({
6818
6077
  functions: config.functions ?? [],
6819
- failurePolicy: WEB_FAILURE_POLICIES.EVENT_REACTION
6078
+ failurePolicy: WEB_FAILURE_POLICIES2.EVENT_REACTION
6820
6079
  });
6821
6080
  }, [config.definition.id]);
6822
- const engine = useMemo18(() => {
6081
+ const engine = useMemo19(() => {
6823
6082
  const actionHandlers = /* @__PURE__ */ new Map();
6824
6083
  if (config.actionHandlers) {
6825
6084
  for (const [type, handler] of Object.entries(config.actionHandlers)) {
@@ -6847,14 +6106,14 @@ function usePlayer(config) {
6847
6106
  });
6848
6107
  }
6849
6108
  });
6850
- const sm2 = new StateMachine(
6109
+ const sm2 = new StateMachine2(
6851
6110
  config.definition,
6852
6111
  config.initialData ?? {},
6853
6112
  { evaluator, actionHandlers }
6854
6113
  );
6855
6114
  smRef = sm2;
6856
- const eventBus2 = new EventBus();
6857
- const dispatcher = new ActionDispatcher();
6115
+ const eventBus2 = new EventBus2();
6116
+ const dispatcher = new ActionDispatcher2();
6858
6117
  dispatcher.register("set_field", (cfg) => {
6859
6118
  if (smRef && typeof cfg.field === "string") {
6860
6119
  smRef.setField(cfg.field, cfg.value);
@@ -6873,8 +6132,8 @@ function usePlayer(config) {
6873
6132
  return { sm: sm2, eventBus: eventBus2, dispatcher };
6874
6133
  }, [config.definition.id, evaluator]);
6875
6134
  const { sm, eventBus } = engine;
6876
- const [playerState, setPlayerState] = useState22(() => computePlayerState(sm));
6877
- useEffect21(() => {
6135
+ const [playerState, setPlayerState] = useState23(() => computePlayerState(sm));
6136
+ useEffect22(() => {
6878
6137
  const stateDef = sm.getCurrentStateDefinition();
6879
6138
  if (!stateDef?.on_event?.length) return;
6880
6139
  const unsubs = [];
@@ -6938,7 +6197,7 @@ function usePlayer(config) {
6938
6197
  for (const unsub of unsubs) unsub();
6939
6198
  };
6940
6199
  }, [sm, eventBus, evaluator, engine.dispatcher, playerState.currentState]);
6941
- useEffect21(() => {
6200
+ useEffect22(() => {
6942
6201
  const unsub = sm.on((event) => {
6943
6202
  if (event.type === "transition" || event.type === "state_enter") {
6944
6203
  setPlayerState(computePlayerState(sm));
@@ -6954,7 +6213,7 @@ function usePlayer(config) {
6954
6213
  });
6955
6214
  return unsub;
6956
6215
  }, [sm]);
6957
- const transition2 = useCallback21(
6216
+ const transition2 = useCallback22(
6958
6217
  async (name, data) => {
6959
6218
  playerLog({
6960
6219
  level: "info",
@@ -6981,20 +6240,20 @@ function usePlayer(config) {
6981
6240
  },
6982
6241
  [sm]
6983
6242
  );
6984
- const setField2 = useCallback21(
6243
+ const setField2 = useCallback22(
6985
6244
  (field2, value) => {
6986
6245
  sm.setField(field2, value);
6987
6246
  setPlayerState(computePlayerState(sm));
6988
6247
  },
6989
6248
  [sm]
6990
6249
  );
6991
- const setMemory = useCallback21(
6250
+ const setMemory = useCallback22(
6992
6251
  (key, value) => {
6993
6252
  sm.setMemory(key, value);
6994
6253
  },
6995
6254
  [sm]
6996
6255
  );
6997
- const publishEvent = useCallback21(
6256
+ const publishEvent = useCallback22(
6998
6257
  (topic, payload) => {
6999
6258
  playerLog({
7000
6259
  level: "debug",
@@ -7020,11 +6279,11 @@ function usePlayer(config) {
7020
6279
  }
7021
6280
 
7022
6281
  // src/hooks/useDomainSubscription.ts
7023
- import { useEffect as useEffect22, useRef as useRef25 } from "react";
6282
+ import { useEffect as useEffect23, useRef as useRef26 } from "react";
7024
6283
  function useDomainSubscription(eventBus, transport, config) {
7025
- const configRef = useRef25(config);
6284
+ const configRef = useRef26(config);
7026
6285
  configRef.current = config;
7027
- useEffect22(() => {
6286
+ useEffect23(() => {
7028
6287
  if (!transport || config.enabled === false) return;
7029
6288
  const unsub = transport.subscribe(
7030
6289
  {
@@ -7077,11 +6336,11 @@ function useDomainSubscription(eventBus, transport, config) {
7077
6336
  }
7078
6337
 
7079
6338
  // src/hooks/useExperienceState.ts
7080
- import { useCallback as useCallback22, useRef as useRef26 } from "react";
6339
+ import { useCallback as useCallback23, useRef as useRef27 } from "react";
7081
6340
  function useExperienceState(player, selector) {
7082
- const selectorRef = useRef26(selector);
6341
+ const selectorRef = useRef27(selector);
7083
6342
  selectorRef.current = selector;
7084
- const getSnapshot = useCallback22(() => {
6343
+ const getSnapshot = useCallback23(() => {
7085
6344
  return selectorRef.current({
7086
6345
  currentState: player.currentState,
7087
6346
  stateData: player.stateData,
@@ -7097,20 +6356,20 @@ function useStateField(player, field2, defaultValue) {
7097
6356
  }
7098
6357
 
7099
6358
  // src/hooks/useComputed.ts
7100
- import { useMemo as useMemo19, useRef as useRef27 } from "react";
6359
+ import { useMemo as useMemo20, useRef as useRef28 } from "react";
7101
6360
  function useComputed(_name, compute, options) {
7102
6361
  const mode = options?.mode ?? "read-time";
7103
6362
  const deps = options?.deps ?? [];
7104
- const computeRef = useRef27(compute);
6363
+ const computeRef = useRef28(compute);
7105
6364
  computeRef.current = compute;
7106
6365
  if (mode === "read-time") {
7107
- return useMemo19(() => computeRef.current(), [
6366
+ return useMemo20(() => computeRef.current(), [
7108
6367
  // We intentionally depend on deps.join to recompute when tracked fields change
7109
6368
  // The actual dependency tracking happens at the compiler level
7110
6369
  deps.join(",")
7111
6370
  ]);
7112
6371
  }
7113
- return useMemo19(() => computeRef.current(), [deps.join(",")]);
6372
+ return useMemo20(() => computeRef.current(), [deps.join(",")]);
7114
6373
  }
7115
6374
  function useComputedWithMeta(name, compute, options) {
7116
6375
  const value = useComputed(name, compute, options);
@@ -7143,7 +6402,7 @@ function usePlayerContextSafe() {
7143
6402
  }
7144
6403
 
7145
6404
  // src/components/ExperienceWorkflowBridge.tsx
7146
- import { useMemo as useMemo20 } from "react";
6405
+ import { useMemo as useMemo21 } from "react";
7147
6406
  import { jsx as jsx3, jsxs } from "react/jsx-runtime";
7148
6407
  function ExperienceWorkflowBridgeInner({
7149
6408
  definition,
@@ -7161,7 +6420,7 @@ function ExperienceWorkflowBridgeInner({
7161
6420
  actionHandlers,
7162
6421
  debug
7163
6422
  });
7164
- const viewConfig = useMemo20(() => {
6423
+ const viewConfig = useMemo21(() => {
7165
6424
  if (!definition.state_views) return void 0;
7166
6425
  return definition.state_views[player.currentState];
7167
6426
  }, [definition.state_views, player.currentState]);
@@ -7517,7 +6776,7 @@ var BrowserPlayer = class {
7517
6776
  this.ensureInitialized();
7518
6777
  const id = crypto.randomUUID();
7519
6778
  const now = (/* @__PURE__ */ new Date()).toISOString();
7520
- const instance = {
6779
+ const instance2 = {
7521
6780
  id,
7522
6781
  definitionId: options.definitionId ?? definitionSlug,
7523
6782
  definitionSlug,
@@ -7529,15 +6788,15 @@ var BrowserPlayer = class {
7529
6788
  createdAt: now,
7530
6789
  updatedAt: now
7531
6790
  };
7532
- await this.putInstance(instance);
6791
+ await this.putInstance(instance2);
7533
6792
  this.log("info", `Instance created: ${id} (${definitionSlug})`);
7534
6793
  this.emit({
7535
6794
  type: "instance:created",
7536
6795
  instanceId: id,
7537
- data: { definitionSlug, currentState: instance.currentState },
6796
+ data: { definitionSlug, currentState: instance2.currentState },
7538
6797
  timestamp: Date.now()
7539
6798
  });
7540
- return instance;
6799
+ return instance2;
7541
6800
  }
7542
6801
  /** Get an instance by ID. */
7543
6802
  async getInstance(id) {
@@ -7546,13 +6805,13 @@ var BrowserPlayer = class {
7546
6805
  }
7547
6806
  /** Get the current state of an instance. */
7548
6807
  async getState(id) {
7549
- const instance = await this.getInstance(id);
7550
- if (!instance) return null;
6808
+ const instance2 = await this.getInstance(id);
6809
+ if (!instance2) return null;
7551
6810
  return {
7552
- currentState: instance.currentState,
7553
- status: instance.status,
7554
- stateData: instance.stateData,
7555
- lockVersion: instance.lockVersion
6811
+ currentState: instance2.currentState,
6812
+ status: instance2.status,
6813
+ stateData: instance2.stateData,
6814
+ lockVersion: instance2.lockVersion
7556
6815
  };
7557
6816
  }
7558
6817
  /**
@@ -7563,34 +6822,34 @@ var BrowserPlayer = class {
7563
6822
  */
7564
6823
  async transition(instanceId, transitionName, data = {}) {
7565
6824
  this.ensureInitialized();
7566
- const instance = await this.getInstanceFromDb(instanceId);
7567
- if (!instance) {
6825
+ const instance2 = await this.getInstanceFromDb(instanceId);
6826
+ if (!instance2) {
7568
6827
  return {
7569
6828
  success: false,
7570
6829
  instance: null,
7571
6830
  error: `Instance ${instanceId} not found`
7572
6831
  };
7573
6832
  }
7574
- if (instance.status !== "ACTIVE") {
6833
+ if (instance2.status !== "ACTIVE") {
7575
6834
  return {
7576
6835
  success: false,
7577
- instance,
7578
- error: `Instance is ${instance.status}, cannot transition`
6836
+ instance: instance2,
6837
+ error: `Instance is ${instance2.status}, cannot transition`
7579
6838
  };
7580
6839
  }
7581
6840
  try {
7582
- const newStateData = { ...instance.stateData, ...data };
7583
- const newLockVersion = instance.lockVersion + 1;
6841
+ const newStateData = { ...instance2.stateData, ...data };
6842
+ const newLockVersion = instance2.lockVersion + 1;
7584
6843
  if (this.wasm.execute_transition) {
7585
6844
  const request = {
7586
6845
  instance: {
7587
- id: instance.id,
7588
- definition_id: instance.definitionId,
7589
- current_state: instance.currentState,
7590
- status: instance.status,
6846
+ id: instance2.id,
6847
+ definition_id: instance2.definitionId,
6848
+ current_state: instance2.currentState,
6849
+ status: instance2.status,
7591
6850
  state_data: newStateData,
7592
- memory: instance.memory,
7593
- execution_lock_version: instance.lockVersion
6851
+ memory: instance2.memory,
6852
+ execution_lock_version: instance2.lockVersion
7594
6853
  },
7595
6854
  transition_name: transitionName,
7596
6855
  actor_id: this.peerId,
@@ -7599,26 +6858,26 @@ var BrowserPlayer = class {
7599
6858
  const resultJson = this.wasm.execute_transition(JSON.stringify(request));
7600
6859
  const result = JSON.parse(resultJson);
7601
6860
  if (result.success === false || result.error) {
7602
- return { success: false, instance, error: result.error ?? "Transition failed" };
6861
+ return { success: false, instance: instance2, error: result.error ?? "Transition failed" };
7603
6862
  }
7604
- instance.currentState = result.to_state ?? instance.currentState;
7605
- instance.status = result.status ?? instance.status;
7606
- instance.stateData = result.state_data ?? newStateData;
7607
- instance.memory = result.memory ?? instance.memory;
6863
+ instance2.currentState = result.to_state ?? instance2.currentState;
6864
+ instance2.status = result.status ?? instance2.status;
6865
+ instance2.stateData = result.state_data ?? newStateData;
6866
+ instance2.memory = result.memory ?? instance2.memory;
7608
6867
  } else {
7609
- instance.stateData = newStateData;
6868
+ instance2.stateData = newStateData;
7610
6869
  }
7611
- instance.lockVersion = newLockVersion;
7612
- instance.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
7613
- await this.putInstance(instance);
6870
+ instance2.lockVersion = newLockVersion;
6871
+ instance2.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
6872
+ await this.putInstance(instance2);
7614
6873
  this.log("info", `Transition: ${instanceId} ${transitionName}`);
7615
6874
  this.emit({
7616
6875
  type: "instance:transition",
7617
6876
  instanceId,
7618
6877
  data: {
7619
6878
  transitionName,
7620
- fromState: instance.currentState,
7621
- toState: instance.currentState,
6879
+ fromState: instance2.currentState,
6880
+ toState: instance2.currentState,
7622
6881
  lockVersion: newLockVersion
7623
6882
  },
7624
6883
  timestamp: Date.now()
@@ -7628,7 +6887,7 @@ var BrowserPlayer = class {
7628
6887
  type: "TransitionReplication",
7629
6888
  instance_id: instanceId,
7630
6889
  transition_name: transitionName,
7631
- state_data: instance.stateData,
6890
+ state_data: instance2.stateData,
7632
6891
  lock_version: newLockVersion
7633
6892
  });
7634
6893
  const envelope = this.wasm.sign_envelope(this.secretKeyHex, payload);
@@ -7638,11 +6897,11 @@ var BrowserPlayer = class {
7638
6897
  envelope
7639
6898
  }));
7640
6899
  }
7641
- return { success: true, instance };
6900
+ return { success: true, instance: instance2 };
7642
6901
  } catch (err) {
7643
6902
  const error = err instanceof Error ? err.message : String(err);
7644
6903
  this.log("error", `Transition failed: ${error}`);
7645
- return { success: false, instance, error };
6904
+ return { success: false, instance: instance2, error };
7646
6905
  }
7647
6906
  }
7648
6907
  // ─── Subscriptions ──────────────────────────────────────────────────
@@ -7722,12 +6981,12 @@ var BrowserPlayer = class {
7722
6981
  request.onerror = () => reject(request.error);
7723
6982
  });
7724
6983
  }
7725
- async putInstance(instance) {
6984
+ async putInstance(instance2) {
7726
6985
  if (!this.db) return;
7727
6986
  return new Promise((resolve, reject) => {
7728
6987
  const tx = this.db.transaction(INSTANCE_STORE_NAME, "readwrite");
7729
6988
  const store = tx.objectStore(INSTANCE_STORE_NAME);
7730
- store.put(instance);
6989
+ store.put(instance2);
7731
6990
  tx.oncomplete = () => resolve();
7732
6991
  tx.onerror = () => reject(tx.error);
7733
6992
  });
@@ -7874,9 +7133,381 @@ var BrowserPlayer = class {
7874
7133
  }
7875
7134
  }
7876
7135
  };
7136
+
7137
+ // src/middleware-def.ts
7138
+ function defineMiddleware(def) {
7139
+ if (process.env.NODE_ENV !== "production") {
7140
+ if (!def.name || typeof def.name !== "string") {
7141
+ throw new Error("defineMiddleware: name is required and must be a string");
7142
+ }
7143
+ if (!def.match) {
7144
+ throw new Error("defineMiddleware: match pattern is required");
7145
+ }
7146
+ const patterns = Array.isArray(def.match) ? def.match : [def.match];
7147
+ for (const p of patterns) {
7148
+ if (typeof p !== "string") {
7149
+ throw new Error(`defineMiddleware: match pattern must be a string, got ${typeof p}`);
7150
+ }
7151
+ }
7152
+ if (def.priority !== void 0 && typeof def.priority !== "number") {
7153
+ throw new Error("defineMiddleware: priority must be a number");
7154
+ }
7155
+ if (!def.before && !def.after && !def.around) {
7156
+ throw new Error("defineMiddleware: at least one of before, after, or around must be provided");
7157
+ }
7158
+ }
7159
+ return def;
7160
+ }
7161
+ function extendMiddleware(base, overrides) {
7162
+ let introduce;
7163
+ if (base.introduce || overrides.introduce) {
7164
+ introduce = {
7165
+ fields: { ...base.introduce?.fields, ...overrides.introduce?.fields },
7166
+ states: { ...base.introduce?.states, ...overrides.introduce?.states },
7167
+ transitions: { ...base.introduce?.transitions, ...overrides.introduce?.transitions }
7168
+ };
7169
+ if (introduce.fields && Object.keys(introduce.fields).length === 0) introduce.fields = void 0;
7170
+ if (introduce.states && Object.keys(introduce.states).length === 0) introduce.states = void 0;
7171
+ if (introduce.transitions && Object.keys(introduce.transitions).length === 0) introduce.transitions = void 0;
7172
+ }
7173
+ const merged = {
7174
+ ...base,
7175
+ ...overrides,
7176
+ // Config is merged (overrides win per-key)
7177
+ config: base.config || overrides.config ? { ...base.config, ...overrides.config } : void 0
7178
+ };
7179
+ if (introduce) {
7180
+ merged.introduce = introduce;
7181
+ }
7182
+ if (process.env.NODE_ENV !== "production") {
7183
+ if (!merged.name || typeof merged.name !== "string") {
7184
+ throw new Error("extendMiddleware: resulting middleware must have a name");
7185
+ }
7186
+ if (!merged.match) {
7187
+ throw new Error("extendMiddleware: resulting middleware must have a match pattern");
7188
+ }
7189
+ if (!merged.before && !merged.after && !merged.around) {
7190
+ throw new Error("extendMiddleware: resulting middleware must have at least one of before, after, or around");
7191
+ }
7192
+ }
7193
+ return merged;
7194
+ }
7195
+ function withAuth(opts) {
7196
+ const _redirectTo = opts?.redirectTo;
7197
+ return {
7198
+ name: "mm:auth",
7199
+ match: "*:*:transition.execute",
7200
+ priority: 90,
7201
+ before(ctx) {
7202
+ if (!ctx.actor.id) {
7203
+ ctx.block(_redirectTo ? `redirect:${_redirectTo}` : "Authentication required");
7204
+ }
7205
+ }
7206
+ };
7207
+ }
7208
+ function withAuditLog(opts) {
7209
+ const _level = opts?.level ?? "info";
7210
+ return {
7211
+ name: "mm:audit-log",
7212
+ match: "*:*:transition.execute",
7213
+ priority: 0,
7214
+ after(ctx) {
7215
+ ctx.modify({
7216
+ __audit: {
7217
+ level: _level,
7218
+ actor: ctx.actor.id,
7219
+ transition: ctx.transition?.name,
7220
+ from: ctx.transition?.from,
7221
+ to: ctx.transition?.to,
7222
+ timestamp: ctx.timestamp
7223
+ }
7224
+ });
7225
+ }
7226
+ };
7227
+ }
7228
+ function withRateLimit(opts) {
7229
+ const _max = opts?.maxPerMinute ?? 60;
7230
+ return {
7231
+ name: "mm:rate-limit",
7232
+ match: "*:*:transition.execute",
7233
+ priority: 80,
7234
+ config: {
7235
+ maxPerMinute: { type: "number", default: _max }
7236
+ },
7237
+ before(ctx) {
7238
+ const fields = ctx.instance.fields;
7239
+ const counter = fields.__rateCounter || 0;
7240
+ if (counter >= _max) {
7241
+ ctx.block(`Rate limit exceeded: ${_max} per minute`);
7242
+ }
7243
+ }
7244
+ };
7245
+ }
7246
+ function withValidation(opts) {
7247
+ const _rules = opts?.rules ?? [];
7248
+ return {
7249
+ name: "mm:validation",
7250
+ match: "*:*:field.change",
7251
+ priority: 70,
7252
+ config: {
7253
+ rules: { type: "json", default: _rules }
7254
+ },
7255
+ before(ctx) {
7256
+ if (!ctx.field) return;
7257
+ for (const rule of _rules) {
7258
+ if (rule.fields.includes(ctx.field.name)) {
7259
+ ctx.block(rule.message);
7260
+ }
7261
+ }
7262
+ }
7263
+ };
7264
+ }
7265
+ function withMetrics(opts) {
7266
+ const _endpoint = opts?.endpoint;
7267
+ return {
7268
+ name: "mm:metrics",
7269
+ match: "*:*:*",
7270
+ priority: 100,
7271
+ config: {
7272
+ endpoint: { type: "string", default: _endpoint }
7273
+ },
7274
+ async around(ctx, next) {
7275
+ const start = ctx.timestamp;
7276
+ await next();
7277
+ const duration = Date.now() - start;
7278
+ ctx.modify({
7279
+ __metrics: {
7280
+ duration,
7281
+ endpoint: _endpoint,
7282
+ actor: ctx.actor.id
7283
+ }
7284
+ });
7285
+ }
7286
+ };
7287
+ }
7288
+
7289
+ // src/actor.ts
7290
+ function compileTimeOnly(name) {
7291
+ throw new Error(
7292
+ `${name}() is a compile-time function and cannot be called at runtime. Use \`mmrc build\` to compile your workflow.`
7293
+ );
7294
+ }
7295
+ var DEFAULT_SUPERVISION = {
7296
+ strategy: "escalate"
7297
+ };
7298
+ var DEFAULT_MAILBOX = {
7299
+ capacity: 1e3,
7300
+ overflow: "error",
7301
+ priority: "fifo"
7302
+ };
7303
+ function configureActor(config) {
7304
+ void config;
7305
+ return {
7306
+ __actor: true,
7307
+ supervision: config.supervision ?? DEFAULT_SUPERVISION,
7308
+ mailbox: config.mailbox ?? DEFAULT_MAILBOX,
7309
+ hierarchy: config.hierarchy ?? {}
7310
+ };
7311
+ }
7312
+ function spawnActor(_slug, _options) {
7313
+ compileTimeOnly("spawnActor");
7314
+ }
7315
+ function sendMessage(_instanceId, _action, _payload) {
7316
+ compileTimeOnly("sendMessage");
7317
+ }
7318
+ function isActorConfig(value) {
7319
+ return typeof value === "object" && value !== null && value.__actor === true;
7320
+ }
7321
+
7322
+ // src/constraints.ts
7323
+ var BUILT_IN_CONSTRAINTS = /* @__PURE__ */ new Set([
7324
+ "every state is reachable",
7325
+ "no deadlocks",
7326
+ "no unreachable states",
7327
+ "deterministic guards",
7328
+ "terminates",
7329
+ "no guard overlaps",
7330
+ "all roles defined",
7331
+ "all fields validated"
7332
+ ]);
7333
+ function constraints(...rules) {
7334
+ if (process.env.NODE_ENV !== "production") {
7335
+ if (rules.length === 0) {
7336
+ throw new Error("constraints(): at least one constraint rule is required");
7337
+ }
7338
+ for (let i = 0; i < rules.length; i++) {
7339
+ const rule = rules[i];
7340
+ if (typeof rule !== "string" || rule.trim() === "") {
7341
+ throw new Error(
7342
+ `constraints(): rule at index ${i} must be a non-empty string, got ${typeof rule}`
7343
+ );
7344
+ }
7345
+ }
7346
+ }
7347
+ return {
7348
+ __constraints: true,
7349
+ rules: Object.freeze([...rules])
7350
+ };
7351
+ }
7352
+ function isConstraintDeclaration(value) {
7353
+ return typeof value === "object" && value !== null && value.__constraints === true && Array.isArray(value.rules);
7354
+ }
7355
+ function isBuiltInConstraint(rule) {
7356
+ return BUILT_IN_CONSTRAINTS.has(rule);
7357
+ }
7358
+
7359
+ // src/extend.ts
7360
+ function extend(base, options) {
7361
+ const _metadata = {
7362
+ __extend: true,
7363
+ base,
7364
+ options
7365
+ };
7366
+ throw new Error(
7367
+ `extend() is a compile-time declaration and cannot be called at runtime. Ensure your build pipeline includes the @mmapp/react-compiler Babel plugin or compile your workflow files with \`mmrc build\` before execution.
7368
+
7369
+ Base workflow: ${base?.name ?? "(anonymous)"}
7370
+ Derived slug: ${options.slug ?? "(not specified)"}`
7371
+ );
7372
+ return _metadata;
7373
+ }
7374
+
7375
+ // src/compose.ts
7376
+ function compose(workflow, ...mixins) {
7377
+ for (let i = 0; i < mixins.length; i++) {
7378
+ const mixin = mixins[i];
7379
+ if (!mixin || mixin.__mixin !== true) {
7380
+ throw new Error(
7381
+ `compose() argument ${i + 2} is not a valid WorkflowMixin. Each mixin must be created by a mixin factory (e.g. withAuditTrail(), withSoftDelete()). Received: ${typeof mixin === "object" ? JSON.stringify(mixin) : String(mixin)}`
7382
+ );
7383
+ }
7384
+ }
7385
+ const metadata = {
7386
+ __composed: true,
7387
+ workflow,
7388
+ mixins: Object.freeze([...mixins])
7389
+ };
7390
+ const composed = (async (...args) => {
7391
+ return workflow(...args);
7392
+ });
7393
+ Object.defineProperty(composed, "__composed", {
7394
+ value: metadata,
7395
+ writable: false,
7396
+ enumerable: false,
7397
+ configurable: false
7398
+ });
7399
+ Object.defineProperty(composed, "name", {
7400
+ value: `composed(${workflow.name || "anonymous"})`,
7401
+ writable: false,
7402
+ configurable: true
7403
+ });
7404
+ return composed;
7405
+ }
7406
+
7407
+ // src/imperative.ts
7408
+ function compileTimeOnly2(name) {
7409
+ throw new Error(
7410
+ `${name}() is a compile-time function and cannot be called at runtime. Use \`mmrc build\` to compile your workflow.`
7411
+ );
7412
+ }
7413
+ function compileTimeProxy(label) {
7414
+ return new Proxy(
7415
+ {},
7416
+ {
7417
+ get(_target, prop) {
7418
+ throw new Error(
7419
+ `Cannot access \`${label}.${String(prop)}\` at runtime. \`${label}\` is a compile-time constant. Use \`mmrc build\` to compile your workflow.`
7420
+ );
7421
+ }
7422
+ }
7423
+ );
7424
+ }
7425
+ function validate(_condition, _message, _severity) {
7426
+ compileTimeOnly2("validate");
7427
+ }
7428
+ function log(_event, _data) {
7429
+ compileTimeOnly2("log");
7430
+ }
7431
+ function notify2(_to, _message, _opts) {
7432
+ compileTimeOnly2("notify");
7433
+ }
7434
+ function emit(_event, _payload) {
7435
+ compileTimeOnly2("emit");
7436
+ }
7437
+ function requireRole2(..._roles) {
7438
+ compileTimeOnly2("requireRole");
7439
+ }
7440
+ function requireField(..._fields) {
7441
+ compileTimeOnly2("requireField");
7442
+ }
7443
+ function guard(_expression) {
7444
+ compileTimeOnly2("guard");
7445
+ }
7446
+ function every(_interval, _fn) {
7447
+ compileTimeOnly2("every");
7448
+ }
7449
+ function cron2(_expression, _fn) {
7450
+ compileTimeOnly2("cron");
7451
+ }
7452
+ function after(_delay, _fn) {
7453
+ compileTimeOnly2("after");
7454
+ }
7455
+ function on(_pattern, _handlerOrOpts) {
7456
+ compileTimeOnly2("on");
7457
+ }
7458
+ function timeout(_duration, _handler) {
7459
+ compileTimeOnly2("timeout");
7460
+ }
7461
+ function userAction(_name, _opts) {
7462
+ compileTimeOnly2("userAction");
7463
+ }
7464
+ function userChoice(_options) {
7465
+ compileTimeOnly2("userChoice");
7466
+ }
7467
+ function named(_name, _stateCall) {
7468
+ compileTimeOnly2("named");
7469
+ }
7470
+ function delay(_duration) {
7471
+ compileTimeOnly2("delay");
7472
+ }
7473
+ function allowTransition(_name, _opts) {
7474
+ compileTimeOnly2("allowTransition");
7475
+ }
7476
+ function restrict(_field, _opts) {
7477
+ compileTimeOnly2("restrict");
7478
+ }
7479
+ function visibleTo(..._roles) {
7480
+ compileTimeOnly2("visibleTo");
7481
+ }
7482
+ function editableBy(..._roles) {
7483
+ compileTimeOnly2("editableBy");
7484
+ }
7485
+ function editableIn(..._states) {
7486
+ compileTimeOnly2("editableIn");
7487
+ }
7488
+ function defineRoles(roles) {
7489
+ void roles;
7490
+ compileTimeOnly2("defineRoles");
7491
+ }
7492
+ function runtime(_target) {
7493
+ compileTimeOnly2("runtime");
7494
+ }
7495
+ function orchestration(config) {
7496
+ void config;
7497
+ compileTimeOnly2("orchestration");
7498
+ }
7499
+ function blueprint(_slug, _config) {
7500
+ compileTimeOnly2("blueprint");
7501
+ }
7502
+ function patch(_id, _overrides) {
7503
+ compileTimeOnly2("patch");
7504
+ }
7505
+ var actor = compileTimeProxy("actor");
7506
+ var instance = compileTimeProxy("instance");
7877
7507
  export {
7878
7508
  Accordion,
7879
7509
  AnimatedBox,
7510
+ BUILT_IN_CONSTRAINTS,
7880
7511
  Badge,
7881
7512
  Blueprint,
7882
7513
  BrowserPlayer,
@@ -7903,6 +7534,7 @@ export {
7903
7534
  Modal,
7904
7535
  ModelBuilder,
7905
7536
  NavLink,
7537
+ ORCHESTRATION_PRESETS,
7906
7538
  PlayerProvider,
7907
7539
  RoleGuard,
7908
7540
  Route,
@@ -7926,12 +7558,19 @@ export {
7926
7558
  WorkflowProvider,
7927
7559
  WorkflowRuntime,
7928
7560
  action,
7929
- and2 as and,
7561
+ actor,
7562
+ after,
7563
+ allowTransition,
7564
+ and,
7930
7565
  applyMixins,
7931
7566
  approval,
7932
7567
  assertModelValid,
7933
7568
  cedar,
7569
+ compose,
7570
+ computeVisibility,
7571
+ configureActor,
7934
7572
  connector,
7573
+ constraints,
7935
7574
  createActions,
7936
7575
  createCRUD,
7937
7576
  createLocalDataResolver,
@@ -7940,16 +7579,26 @@ export {
7940
7579
  cron,
7941
7580
  crud,
7942
7581
  defineBlueprint,
7582
+ blueprint as defineImperativeBlueprint,
7583
+ defineMiddleware,
7943
7584
  defineModel,
7944
7585
  defineModule,
7586
+ defineRoles,
7945
7587
  defineWorkspace,
7588
+ delay,
7946
7589
  deriveInstanceKey,
7947
7590
  deriveInstanceKeySync,
7948
7591
  describeModel,
7949
7592
  deviceAction,
7950
7593
  dmn,
7594
+ editableBy,
7595
+ editableIn,
7596
+ emit,
7951
7597
  escalation,
7598
+ every,
7952
7599
  expr,
7600
+ extend,
7601
+ extendMiddleware,
7953
7602
  field,
7954
7603
  fieldContains,
7955
7604
  fieldEquals,
@@ -7964,12 +7613,21 @@ export {
7964
7613
  getInstalledModule,
7965
7614
  getInstalledModules,
7966
7615
  graphql,
7616
+ guard,
7967
7617
  hasAnyRole,
7968
7618
  hasRole,
7619
+ cron2 as imperativeCron,
7620
+ log as imperativeLog,
7621
+ notify2 as imperativeNotify,
7622
+ requireRole2 as imperativeRequireRole,
7969
7623
  inState,
7970
7624
  inputEquals,
7971
7625
  inputRequired,
7626
+ instance,
7972
7627
  isActor,
7628
+ isActorConfig,
7629
+ isBuiltInConstraint,
7630
+ isConstraintDeclaration,
7973
7631
  isCreator,
7974
7632
  isOwner,
7975
7633
  isPlayerDebug,
@@ -7979,19 +7637,28 @@ export {
7979
7637
  loadExperienceWorkflow,
7980
7638
  logEvent,
7981
7639
  model,
7640
+ named,
7982
7641
  normalizeDefinition,
7983
- not2 as not,
7642
+ not,
7984
7643
  notInState,
7985
7644
  notify,
7986
- or2 as or,
7645
+ on,
7646
+ or,
7647
+ orchestration,
7648
+ patch,
7987
7649
  pipe,
7988
7650
  playerLog,
7989
7651
  prefetchData,
7990
7652
  refHasAnyRole,
7991
7653
  refHasRole,
7992
7654
  requireAuth,
7655
+ requireField,
7993
7656
  requireRole,
7657
+ resolveOrchestration,
7658
+ restrict,
7994
7659
  review,
7660
+ runtime,
7661
+ sendMessage,
7995
7662
  serverAction,
7996
7663
  setAuthResolver,
7997
7664
  setChannelTransport,
@@ -8011,10 +7678,12 @@ export {
8011
7678
  setServerStateResolver,
8012
7679
  setViewResolver,
8013
7680
  spawn,
7681
+ spawnActor,
8014
7682
  sql,
8015
7683
  state,
8016
7684
  syncConfigDefaults,
8017
7685
  testModel,
7686
+ timeout,
8018
7687
  transition,
8019
7688
  updateDefinitionConfig,
8020
7689
  useAuth,
@@ -8047,6 +7716,7 @@ export {
8047
7716
  usePlayer,
8048
7717
  usePlayerContext,
8049
7718
  usePlayerContextSafe,
7719
+ usePresence,
8050
7720
  useQuery,
8051
7721
  useRealtimeQuery,
8052
7722
  useRole,
@@ -8059,20 +7729,30 @@ export {
8059
7729
  useToast,
8060
7730
  useTransition,
8061
7731
  useView,
7732
+ useVisibility,
8062
7733
  useWhileIn,
8063
7734
  useWorkflow,
8064
- useState20 as useWorkflowState,
7735
+ useState21 as useWorkflowState,
7736
+ userAction,
7737
+ userChoice,
7738
+ validate,
8065
7739
  validateExperienceWorkflow,
8066
7740
  validateModel,
7741
+ visibleTo,
8067
7742
  when,
7743
+ withAuditLog,
8068
7744
  withAuditTrail,
7745
+ withAuth,
7746
+ withMetrics,
8069
7747
  withOwnership,
8070
7748
  withPagination,
8071
7749
  withRBAC,
7750
+ withRateLimit,
8072
7751
  withSearch,
8073
7752
  withSlug,
8074
7753
  withSoftDelete,
8075
7754
  withTags,
8076
7755
  withTimestamps,
7756
+ withValidation,
8077
7757
  withVersioning
8078
7758
  };