@mmapp/react 0.1.0-alpha.18 → 0.1.0-alpha.19

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.
Files changed (52) hide show
  1. package/dist/actions-MFI2V4DX.mjs +116 -0
  2. package/dist/atoms/index.d.mts +2 -2
  3. package/dist/atoms/index.d.ts +2 -2
  4. package/dist/atoms/index.js +1 -1
  5. package/dist/atoms/index.mjs +1 -1
  6. package/dist/builtin-atoms-C-sNyYJl.d.mts +647 -0
  7. package/dist/builtin-atoms-C-sNyYJl.d.ts +647 -0
  8. package/dist/builtin-atoms-DCKrjG7i.d.mts +96 -0
  9. package/dist/builtin-atoms-DCKrjG7i.d.ts +96 -0
  10. package/dist/builtin-atoms-DRD3EwG6.d.mts +648 -0
  11. package/dist/builtin-atoms-DRD3EwG6.d.ts +648 -0
  12. package/dist/builtin-atoms-jt04b7Rw.d.mts +643 -0
  13. package/dist/builtin-atoms-jt04b7Rw.d.ts +643 -0
  14. package/dist/chunk-247T4GDJ.mjs +677 -0
  15. package/dist/chunk-3H6CR7E7.mjs +1924 -0
  16. package/dist/chunk-3PL6FL6I.mjs +96 -0
  17. package/dist/chunk-3SJSW3C4.mjs +2039 -0
  18. package/dist/chunk-5OI2VI57.mjs +1964 -0
  19. package/dist/chunk-CL6FYZ43.mjs +105 -0
  20. package/dist/chunk-ENQOCZI5.mjs +1938 -0
  21. package/dist/chunk-FB3WCZAU.mjs +512 -0
  22. package/dist/chunk-GLJ7VC7Z.mjs +684 -0
  23. package/dist/chunk-HHMWR6NA.mjs +504 -0
  24. package/dist/chunk-HULEMSN2.mjs +120 -0
  25. package/dist/chunk-J5MW6CRU.mjs +1938 -0
  26. package/dist/chunk-PNTTKNYU.mjs +677 -0
  27. package/dist/chunk-TY5OTJP4.mjs +684 -0
  28. package/dist/chunk-WV7DVCP6.mjs +513 -0
  29. package/dist/chunk-YFMPTGUF.mjs +677 -0
  30. package/dist/{chunk-2VJQJM7S.mjs → chunk-ZDWACXZN.mjs} +1 -1
  31. package/dist/composition-BJ6QQTWT.mjs +12 -0
  32. package/dist/composition-XBGKKCI7.mjs +57 -0
  33. package/dist/content-QVPFUG4P.mjs +246 -0
  34. package/dist/control-flow-CBREHWJW.mjs +35 -0
  35. package/dist/control-flow-FWBOI6SM.mjs +35 -0
  36. package/dist/control-flow-ZWUGCDSP.mjs +35 -0
  37. package/dist/data-WCMIZYKD.mjs +97 -0
  38. package/dist/grouping-E6F377VZ.mjs +204 -0
  39. package/dist/grouping-FRPOEXO3.mjs +233 -0
  40. package/dist/index.d.mts +4 -433
  41. package/dist/index.d.ts +4 -433
  42. package/dist/index.js +3648 -581
  43. package/dist/index.mjs +335 -1040
  44. package/dist/input-PUOZDNSI.mjs +222 -0
  45. package/dist/layout-RATDMCLP.mjs +106 -0
  46. package/dist/navigation-VCT7ZBMA.mjs +15 -0
  47. package/dist/navigation-WFV7YWOU.mjs +14 -0
  48. package/dist/player/index.d.mts +37 -11
  49. package/dist/player/index.d.ts +37 -11
  50. package/dist/player/index.js +3280 -174
  51. package/dist/player/index.mjs +55 -5
  52. package/package.json +4 -4
package/dist/index.js CHANGED
@@ -5,6 +5,9 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
6
  var __getProtoOf = Object.getPrototypeOf;
7
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __esm = (fn, res) => function __init() {
9
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
10
+ };
8
11
  var __export = (target, all) => {
9
12
  for (var name in all)
10
13
  __defProp(target, name, { get: all[name], enumerable: true });
@@ -27,135 +30,1988 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
27
30
  ));
28
31
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
32
 
30
- // src/index.ts
31
- var index_exports = {};
32
- __export(index_exports, {
33
- Accordion: () => Accordion,
34
- AnimatedBox: () => AnimatedBox,
35
- BUILT_IN_CONSTRAINTS: () => BUILT_IN_CONSTRAINTS,
36
- Badge: () => Badge2,
37
- Blueprint: () => Blueprint,
38
- BrowserPlayer: () => BrowserPlayer,
39
- Button: () => Button2,
40
- Canvas3D: () => Canvas3D,
41
- Card: () => Card2,
42
- Chart: () => Chart,
43
- Column: () => Column2,
44
- ComponentTreeRenderer: () => ComponentTreeRenderer,
45
- DataGrid: () => DataGrid,
46
- DevPlayer: () => DevPlayer,
47
- Divider: () => Divider2,
48
- Each: () => Each2,
49
- ExperienceWorkflowBridge: () => ExperienceWorkflowBridge,
50
- Field: () => Field2,
51
- FieldBuilder: () => FieldBuilder,
52
- Grid: () => Grid2,
53
- Heading: () => Heading2,
33
+ // src/player/expression-engine.ts
34
+ function classifyExpression(expr2) {
35
+ const cached = classificationCache.get(expr2);
36
+ if (cached) return cached;
37
+ const cls = classifyUncached(expr2);
38
+ classificationCache.set(expr2, cls);
39
+ return cls;
40
+ }
41
+ function classifyUncached(expr2) {
42
+ const t = expr2.trim();
43
+ if (t === "[Expression]" || t.includes("[Expression]")) return "literal";
44
+ if (t.startsWith("$expr(") && t.endsWith(")")) return "condition";
45
+ if (t.startsWith('"') && t.endsWith('"') || t.startsWith("'") && t.endsWith("'")) return "literal";
46
+ if (/^-?\d+(\.\d+)?$/.test(t)) return "literal";
47
+ if (t === "true" || t === "false" || t === "null" || t === "undefined") return "literal";
48
+ if (t === "[]" || t === "{}") return "literal";
49
+ if (/^\$fn\.\w+\(/.test(t)) return "function";
50
+ if (/^\$action\.\w+\(/.test(t)) return "action";
51
+ if (t.startsWith("$action.") && !t.includes("(")) return "action";
52
+ if (t.startsWith("$") && !/[!=<>&|+\-*/%?:]/.test(t) && !t.includes("(")) return "path";
53
+ if (/^[a-zA-Z_]\w*(\.\w+)+$/.test(t) && !/[!=<>&|+\-*/%?:]/.test(t)) return "path";
54
+ if (/^[a-zA-Z_]\w*$/.test(t)) return "path";
55
+ return "condition";
56
+ }
57
+ function resolvePath(path, scope) {
58
+ const parts = path.split(".");
59
+ let current = scope;
60
+ for (const part of parts) {
61
+ if (current == null) return void 0;
62
+ if (typeof current !== "object") return void 0;
63
+ const asNum = Number(part);
64
+ if (Array.isArray(current) && !isNaN(asNum)) {
65
+ current = current[asNum];
66
+ } else {
67
+ current = current[part];
68
+ }
69
+ }
70
+ return current;
71
+ }
72
+ function validateExpression(expr2) {
73
+ for (const pat of FORBIDDEN_PATTERNS) {
74
+ if (pat.test(expr2)) {
75
+ return { valid: false, error: `Forbidden pattern: ${pat.source}` };
76
+ }
77
+ }
78
+ const depth = (expr2.match(/\(/g) || []).length;
79
+ if (depth > 15) return { valid: false, error: "Expression too deeply nested" };
80
+ return { valid: true };
81
+ }
82
+ function compileToFunction(expr2, paramNames) {
83
+ const cached = compiledCache.get(expr2);
84
+ if (cached) return cached;
85
+ const validation = validateExpression(expr2);
86
+ if (!validation.valid) {
87
+ console.warn(`[expression-engine] Unsafe expression blocked: ${validation.error} in "${expr2}"`);
88
+ return null;
89
+ }
90
+ try {
91
+ const fn = new Function(...paramNames, `"use strict"; try { return (${expr2}); } catch(e) { return undefined; }`);
92
+ compiledCache.set(expr2, fn);
93
+ return fn;
94
+ } catch {
95
+ try {
96
+ const fn = new Function(...paramNames, `"use strict"; try { ${expr2} } catch(e) { return undefined; }`);
97
+ compiledCache.set(expr2, fn);
98
+ return fn;
99
+ } catch {
100
+ return null;
101
+ }
102
+ }
103
+ }
104
+ function evaluateExpression(expr2, context) {
105
+ const trimmed = expr2.trim();
106
+ if (!trimmed) return void 0;
107
+ const cls = classifyExpression(trimmed);
108
+ if (cls === "literal") return parseLiteral(trimmed);
109
+ if (cls === "path") return resolveScopePath(trimmed, context);
110
+ let evalExpr = trimmed;
111
+ if (evalExpr.startsWith("$expr(") && evalExpr.endsWith(")")) {
112
+ evalExpr = evalExpr.slice(6, -1);
113
+ }
114
+ if (_wasmAvailable && _wasmModule) {
115
+ try {
116
+ const translated = translateForWasm(evalExpr);
117
+ const contextJson = JSON.stringify(buildWasmContext(context));
118
+ const resultJson = _wasmModule.evaluateExpressionSync(translated, contextJson);
119
+ return JSON.parse(resultJson);
120
+ } catch {
121
+ }
122
+ }
123
+ return evaluateWithJS(evalExpr, context);
124
+ }
125
+ function parseLiteral(expr2) {
126
+ if (expr2.startsWith('"') && expr2.endsWith('"') || expr2.startsWith("'") && expr2.endsWith("'")) {
127
+ return expr2.slice(1, -1);
128
+ }
129
+ if (/^-?\d+(\.\d+)?$/.test(expr2)) return Number(expr2);
130
+ if (expr2 === "true") return true;
131
+ if (expr2 === "false") return false;
132
+ if (expr2 === "null") return null;
133
+ if (expr2 === "undefined") return void 0;
134
+ if (expr2 === "[]") return [];
135
+ if (expr2 === "{}") return {};
136
+ if (expr2 === "[Expression]") return void 0;
137
+ return void 0;
138
+ }
139
+ function resolveScopePath(expr2, context) {
140
+ const trimmed = expr2.trim();
141
+ if (trimmed.startsWith("$")) {
142
+ const dotIdx = trimmed.indexOf(".");
143
+ if (dotIdx === -1) {
144
+ return context[trimmed];
145
+ }
146
+ const root = trimmed.slice(0, dotIdx);
147
+ const rest = trimmed.slice(dotIdx + 1);
148
+ const rootVal = context[root];
149
+ if (rootVal == null) return void 0;
150
+ return resolvePath(rest, rootVal);
151
+ }
152
+ return resolvePath(trimmed, context);
153
+ }
154
+ function translateForWasm(expr2) {
155
+ return expr2.replace(/\$fn\./g, "").replace(/\$instance\./g, "state_data.").replace(/\$data\./g, "state_data.").replace(/\$row\./g, "state_data.");
156
+ }
157
+ function buildWasmContext(context) {
158
+ const wasmCtx = {};
159
+ if (context.$instance && typeof context.$instance === "object") {
160
+ const inst = context.$instance;
161
+ wasmCtx.state_data = inst.fields ?? inst;
162
+ }
163
+ if (context.$local) wasmCtx.$local = context.$local;
164
+ if (context.$user) wasmCtx.$user = context.$user;
165
+ if (context.$entity) wasmCtx.$entity = context.$entity;
166
+ if (context.state_data) wasmCtx.state_data = context.state_data;
167
+ if (context.memory) wasmCtx.memory = context.memory;
168
+ if (context.context) wasmCtx.context = context.context;
169
+ return wasmCtx;
170
+ }
171
+ function evaluateWithJS(expr2, context) {
172
+ const paramNames = [];
173
+ const paramValues = [];
174
+ for (const [key, value] of Object.entries(context)) {
175
+ if (key.startsWith("$")) {
176
+ paramNames.push(key);
177
+ paramValues.push(value);
178
+ }
179
+ }
180
+ if (context.$fn && typeof context.$fn === "object") {
181
+ for (const [name, fn2] of Object.entries(context.$fn)) {
182
+ if (!paramNames.includes(name)) {
183
+ paramNames.push(name);
184
+ paramValues.push(fn2);
185
+ }
186
+ }
187
+ }
188
+ if ("item" in context) {
189
+ paramNames.push("item");
190
+ paramValues.push(context.item);
191
+ }
192
+ if ("index" in context) {
193
+ paramNames.push("index");
194
+ paramValues.push(context.index);
195
+ }
196
+ if (context.$instances) {
197
+ paramNames.push("items");
198
+ paramValues.push(context.$instances);
199
+ }
200
+ if (context.$instance) {
201
+ paramNames.push("instance");
202
+ paramValues.push(context.$instance);
203
+ }
204
+ if ("loading" in context) {
205
+ paramNames.push("loading");
206
+ paramValues.push(context.loading);
207
+ }
208
+ if (context.$local && typeof context.$local === "object") {
209
+ for (const [k, v] of Object.entries(context.$local)) {
210
+ if (!paramNames.includes(k)) {
211
+ paramNames.push(k);
212
+ paramValues.push(v);
213
+ }
214
+ }
215
+ }
216
+ const fn = compileToFunction(expr2, paramNames);
217
+ if (!fn) return void 0;
218
+ try {
219
+ return fn(...paramValues);
220
+ } catch {
221
+ return void 0;
222
+ }
223
+ }
224
+ var _wasmModule, _wasmAvailable, LRUCache, classificationCache, builtinFunctions, compiledCache, FORBIDDEN_PATTERNS;
225
+ var init_expression_engine = __esm({
226
+ "src/player/expression-engine.ts"() {
227
+ "use strict";
228
+ _wasmModule = null;
229
+ _wasmAvailable = false;
230
+ LRUCache = class {
231
+ constructor(maxSize) {
232
+ this.maxSize = maxSize;
233
+ }
234
+ map = /* @__PURE__ */ new Map();
235
+ get(key) {
236
+ const val = this.map.get(key);
237
+ if (val !== void 0) {
238
+ this.map.delete(key);
239
+ this.map.set(key, val);
240
+ }
241
+ return val;
242
+ }
243
+ set(key, value) {
244
+ if (this.map.has(key)) this.map.delete(key);
245
+ this.map.set(key, value);
246
+ if (this.map.size > this.maxSize) {
247
+ const first = this.map.keys().next().value;
248
+ if (first !== void 0) this.map.delete(first);
249
+ }
250
+ }
251
+ has(key) {
252
+ return this.map.has(key);
253
+ }
254
+ };
255
+ classificationCache = new LRUCache(500);
256
+ builtinFunctions = {
257
+ // Array
258
+ filter: (arr, fn) => {
259
+ if (!Array.isArray(arr)) return [];
260
+ if (typeof fn === "function") return arr.filter(fn);
261
+ return arr;
262
+ },
263
+ map: (arr, fn) => {
264
+ if (!Array.isArray(arr)) return [];
265
+ if (typeof fn === "function") return arr.map(fn);
266
+ return arr;
267
+ },
268
+ reduce: (arr, fn, init) => {
269
+ if (!Array.isArray(arr)) return init;
270
+ if (typeof fn === "function") return arr.reduce(fn, init);
271
+ return init;
272
+ },
273
+ find: (arr, fn) => {
274
+ if (!Array.isArray(arr)) return void 0;
275
+ if (typeof fn === "function") return arr.find(fn);
276
+ return void 0;
277
+ },
278
+ includes: (arr, item) => {
279
+ if (Array.isArray(arr)) return arr.includes(item);
280
+ if (typeof arr === "string") return arr.includes(String(item));
281
+ return false;
282
+ },
283
+ indexOf: (arr, item) => {
284
+ if (Array.isArray(arr)) return arr.indexOf(item);
285
+ if (typeof arr === "string") return arr.indexOf(String(item));
286
+ return -1;
287
+ },
288
+ slice: (arr, start, end) => {
289
+ if (Array.isArray(arr) || typeof arr === "string") {
290
+ return arr.slice(Number(start) || 0, end != null ? Number(end) : void 0);
291
+ }
292
+ return arr;
293
+ },
294
+ sort: (arr, fn) => {
295
+ if (!Array.isArray(arr)) return [];
296
+ const copy = [...arr];
297
+ if (typeof fn === "function") return copy.sort(fn);
298
+ return copy.sort();
299
+ },
300
+ reverse: (arr) => {
301
+ if (!Array.isArray(arr)) return [];
302
+ return [...arr].reverse();
303
+ },
304
+ unique: (arr) => {
305
+ if (!Array.isArray(arr)) return [];
306
+ return [...new Set(arr)];
307
+ },
308
+ flat: (arr, depth) => {
309
+ if (!Array.isArray(arr)) return [];
310
+ return arr.flat(Number(depth) || 1);
311
+ },
312
+ concat: (a, b) => {
313
+ if (Array.isArray(a)) return a.concat(Array.isArray(b) ? b : [b]);
314
+ if (typeof a === "string") return a + String(b ?? "");
315
+ return [a, b];
316
+ },
317
+ any: (arr, fn) => {
318
+ if (!Array.isArray(arr)) return false;
319
+ if (typeof fn === "function") return arr.some(fn);
320
+ return arr.length > 0;
321
+ },
322
+ all: (arr, fn) => {
323
+ if (!Array.isArray(arr)) return false;
324
+ if (typeof fn === "function") return arr.every(fn);
325
+ return false;
326
+ },
327
+ group_by: (arr, key) => {
328
+ if (!Array.isArray(arr) || typeof key !== "string") return {};
329
+ const groups = {};
330
+ for (const item of arr) {
331
+ const k = String(item?.[key] ?? "undefined");
332
+ (groups[k] ??= []).push(item);
333
+ }
334
+ return groups;
335
+ },
336
+ count: (arr) => Array.isArray(arr) ? arr.length : 0,
337
+ sum: (arr, key) => {
338
+ if (!Array.isArray(arr)) return 0;
339
+ if (typeof key === "string") {
340
+ return arr.reduce((s, item) => s + (Number(item?.[key]) || 0), 0);
341
+ }
342
+ return arr.reduce((s, v) => s + (Number(v) || 0), 0);
343
+ },
344
+ avg: (arr, key) => {
345
+ if (!Array.isArray(arr) || arr.length === 0) return 0;
346
+ const s = builtinFunctions.sum(arr, key);
347
+ return s / arr.length;
348
+ },
349
+ min: (...args) => {
350
+ if (args.length === 1 && Array.isArray(args[0])) return Math.min(...args[0].map(Number));
351
+ return Math.min(...args.map(Number));
352
+ },
353
+ max: (...args) => {
354
+ if (args.length === 1 && Array.isArray(args[0])) return Math.max(...args[0].map(Number));
355
+ return Math.max(...args.map(Number));
356
+ },
357
+ // String
358
+ len: (v) => {
359
+ if (Array.isArray(v)) return v.length;
360
+ if (typeof v === "string") return v.length;
361
+ return 0;
362
+ },
363
+ upper: (v) => typeof v === "string" ? v.toUpperCase() : String(v ?? "").toUpperCase(),
364
+ lower: (v) => typeof v === "string" ? v.toLowerCase() : String(v ?? "").toLowerCase(),
365
+ trim: (v) => typeof v === "string" ? v.trim() : String(v ?? "").trim(),
366
+ contains: (haystack, needle) => {
367
+ if (typeof haystack === "string") return haystack.includes(String(needle));
368
+ if (Array.isArray(haystack)) return haystack.includes(needle);
369
+ return false;
370
+ },
371
+ starts_with: (v, prefix) => typeof v === "string" ? v.startsWith(String(prefix)) : false,
372
+ ends_with: (v, suffix) => typeof v === "string" ? v.endsWith(String(suffix)) : false,
373
+ replace: (v, search, rep) => typeof v === "string" ? v.replaceAll(String(search), String(rep)) : v,
374
+ split: (v, sep) => typeof v === "string" ? v.split(String(sep)) : [],
375
+ join: (arr, sep) => Array.isArray(arr) ? arr.join(String(sep ?? ",")) : String(arr),
376
+ substr: (v, start, len) => {
377
+ if (typeof v !== "string") return "";
378
+ return v.substring(Number(start) || 0, len != null ? (Number(start) || 0) + Number(len) : void 0);
379
+ },
380
+ format: (template, ...args) => {
381
+ if (typeof template !== "string") return String(template);
382
+ return template.replace(/\{(\d+)\}/g, (_, i) => String(args[Number(i)] ?? ""));
383
+ },
384
+ // Math
385
+ abs: (v) => Math.abs(Number(v) || 0),
386
+ ceil: (v) => Math.ceil(Number(v) || 0),
387
+ floor: (v) => Math.floor(Number(v) || 0),
388
+ round: (v, decimals) => {
389
+ const n = Number(v) || 0;
390
+ const d = Number(decimals) || 0;
391
+ const f = Math.pow(10, d);
392
+ return Math.round(n * f) / f;
393
+ },
394
+ pow: (base, exp) => Math.pow(Number(base) || 0, Number(exp) || 0),
395
+ sqrt: (v) => Math.sqrt(Number(v) || 0),
396
+ random: () => Math.random(),
397
+ clamp: (v, lo, hi) => Math.min(Math.max(Number(v), Number(lo)), Number(hi)),
398
+ // Date
399
+ now: () => (/* @__PURE__ */ new Date()).toISOString(),
400
+ formatDate: (v, fmt) => {
401
+ try {
402
+ const d = new Date(v);
403
+ if (isNaN(d.getTime())) return String(v);
404
+ if (fmt === "relative") {
405
+ const diff = Date.now() - d.getTime();
406
+ if (diff < 6e4) return "just now";
407
+ if (diff < 36e5) return `${Math.floor(diff / 6e4)}m ago`;
408
+ if (diff < 864e5) return `${Math.floor(diff / 36e5)}h ago`;
409
+ return `${Math.floor(diff / 864e5)}d ago`;
410
+ }
411
+ return d.toLocaleDateString();
412
+ } catch {
413
+ return String(v);
414
+ }
415
+ },
416
+ // Utility
417
+ coalesce: (...args) => args.find((a) => a != null),
418
+ default: (v, fallback) => v ?? fallback,
419
+ json: (v) => JSON.stringify(v),
420
+ keys: (v) => v && typeof v === "object" && !Array.isArray(v) ? Object.keys(v) : [],
421
+ values: (v) => v && typeof v === "object" && !Array.isArray(v) ? Object.values(v) : [],
422
+ entries: (v) => v && typeof v === "object" && !Array.isArray(v) ? Object.entries(v) : [],
423
+ merge: (...args) => Object.assign({}, ...args.filter((a) => a && typeof a === "object")),
424
+ debug: (v, label) => {
425
+ console.log(label ? `[debug:${label}]` : "[debug]", v);
426
+ return v;
427
+ },
428
+ Boolean: (v) => Boolean(v),
429
+ Number: (v) => Number(v),
430
+ String: (v) => String(v ?? "")
431
+ };
432
+ compiledCache = new LRUCache(2e3);
433
+ FORBIDDEN_PATTERNS = [
434
+ /\beval\b/,
435
+ /\bFunction\b/,
436
+ /\bfetch\b/,
437
+ /\bdocument\b/,
438
+ /\bwindow\b/,
439
+ /\bprocess\b/,
440
+ /\bglobalThis\b/,
441
+ /\bimport\b/,
442
+ /\brequire\b/,
443
+ /\b__proto__\b/,
444
+ /\bconstructor\b/
445
+ ];
446
+ }
447
+ });
448
+
449
+ // src/player/scope-builder.ts
450
+ function useScope() {
451
+ return (0, import_react35.useContext)(ScopeContext);
452
+ }
453
+ function buildScope(opts) {
454
+ const {
455
+ dataSources = {},
456
+ localState = {},
457
+ auth,
458
+ entity,
459
+ parentScope,
460
+ actionScope,
461
+ functions = {}
462
+ } = opts;
463
+ const scope = {
464
+ ...parentScope ?? emptyScopeData,
465
+ $local: { ...parentScope?.$local ?? {}, ...localState },
466
+ $fn: { ...builtinFunctions, ...parentScope?.$fn ?? {}, ...functions }
467
+ };
468
+ if (auth) {
469
+ scope.$user = { id: auth.userId, roles: auth.roles ?? [] };
470
+ }
471
+ if (entity) {
472
+ scope.$entity = entity;
473
+ }
474
+ if (actionScope) {
475
+ scope.$action = actionScope;
476
+ }
477
+ if (Object.keys(dataSources).length > 0) {
478
+ const allInstances = [];
479
+ let primaryInstance;
480
+ let primaryDefinition;
481
+ let primaryPagination;
482
+ for (const [name, result] of Object.entries(dataSources)) {
483
+ if (result.instance) {
484
+ primaryInstance = result.instance;
485
+ scope[name] = result.instance;
486
+ }
487
+ if (result.instances) {
488
+ allInstances.push(...result.instances);
489
+ scope[name] = result.instances;
490
+ }
491
+ if (result.definition) {
492
+ primaryDefinition = result.definition;
493
+ }
494
+ if (result.pagination) {
495
+ primaryPagination = result.pagination;
496
+ }
497
+ }
498
+ if (primaryInstance) scope.$instance = primaryInstance;
499
+ if (allInstances.length > 0) scope.$instances = allInstances;
500
+ if (primaryDefinition) scope.$definition = primaryDefinition;
501
+ if (primaryPagination) scope.$pagination = primaryPagination;
502
+ const anyLoading = Object.values(dataSources).some((r) => r.loading);
503
+ scope.loading = anyLoading;
504
+ }
505
+ return scope;
506
+ }
507
+ function mergeScope(parent, child) {
508
+ return {
509
+ ...parent,
510
+ ...child,
511
+ $local: { ...parent.$local, ...child.$local ?? {} },
512
+ $fn: { ...parent.$fn, ...child.$fn ?? {} },
513
+ $action: child.$action ?? parent.$action
514
+ };
515
+ }
516
+ function buildLoopScope(parent, item, index, as) {
517
+ return {
518
+ ...parent,
519
+ $item: item,
520
+ $index: index,
521
+ [as]: item,
522
+ // Convenience: flatten item fields for direct access
523
+ item,
524
+ index
525
+ };
526
+ }
527
+ var import_react35, emptyScopeData, ScopeContext;
528
+ var init_scope_builder = __esm({
529
+ "src/player/scope-builder.ts"() {
530
+ "use strict";
531
+ import_react35 = require("react");
532
+ init_expression_engine();
533
+ emptyScopeData = {
534
+ $local: {},
535
+ $user: { roles: [] },
536
+ $fn: builtinFunctions,
537
+ $action: {}
538
+ };
539
+ ScopeContext = (0, import_react35.createContext)(emptyScopeData);
540
+ }
541
+ });
542
+
543
+ // src/player/atoms/layout.tsx
544
+ var layout_exports = {};
545
+ __export(layout_exports, {
546
+ Column: () => Column,
547
+ Divider: () => Divider,
548
+ Grid: () => Grid,
549
+ Row: () => Row,
550
+ Spacer: () => Spacer,
551
+ Stack: () => Stack
552
+ });
553
+ var import_jsx_runtime2, filterHtmlProps, Stack, Row, Grid, Column, Divider, Spacer;
554
+ var init_layout = __esm({
555
+ "src/player/atoms/layout.tsx"() {
556
+ "use strict";
557
+ import_jsx_runtime2 = require("react/jsx-runtime");
558
+ filterHtmlProps = (props) => {
559
+ const html = {};
560
+ for (const [k, v] of Object.entries(props)) {
561
+ if (["className", "style", "id", "role", "tabIndex", "title", "onClick", "data-node-id"].includes(k)) {
562
+ html[k] = v;
563
+ }
564
+ if (k.startsWith("data-") || k.startsWith("aria-")) html[k] = v;
565
+ }
566
+ return html;
567
+ };
568
+ Stack = ({ children, gap, padding, align, justify, className, style, ...rest }) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
569
+ "div",
570
+ {
571
+ ...filterHtmlProps(rest),
572
+ className,
573
+ style: {
574
+ display: "flex",
575
+ flexDirection: "column",
576
+ gap: gap != null ? Number(gap) * 4 : void 0,
577
+ padding: padding != null ? Number(padding) * 4 : void 0,
578
+ alignItems: align,
579
+ justifyContent: justify,
580
+ ...style
581
+ },
582
+ children
583
+ }
584
+ );
585
+ Row = ({ children, gap, padding, align, justify, wrap, className, style, ...rest }) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
586
+ "div",
587
+ {
588
+ ...filterHtmlProps(rest),
589
+ className,
590
+ style: {
591
+ display: "flex",
592
+ flexDirection: "row",
593
+ gap: gap != null ? Number(gap) * 4 : void 0,
594
+ padding: padding != null ? Number(padding) * 4 : void 0,
595
+ alignItems: align ?? "center",
596
+ justifyContent: justify,
597
+ flexWrap: wrap ? "wrap" : void 0,
598
+ ...style
599
+ },
600
+ children
601
+ }
602
+ );
603
+ Grid = ({ children, columns, gap, padding, minChildWidth, className, style, ...rest }) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
604
+ "div",
605
+ {
606
+ ...filterHtmlProps(rest),
607
+ className,
608
+ style: {
609
+ display: "grid",
610
+ gridTemplateColumns: minChildWidth ? `repeat(auto-fill, minmax(${Number(minChildWidth)}px, 1fr))` : columns ? `repeat(${Number(columns)}, 1fr)` : "repeat(auto-fill, minmax(200px, 1fr))",
611
+ gap: gap != null ? Number(gap) * 4 : 16,
612
+ padding: padding != null ? Number(padding) * 4 : void 0,
613
+ ...style
614
+ },
615
+ children
616
+ }
617
+ );
618
+ Column = ({ children, span, className, style, ...rest }) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
619
+ "div",
620
+ {
621
+ ...filterHtmlProps(rest),
622
+ className,
623
+ style: {
624
+ gridColumn: span ? `span ${Number(span)}` : void 0,
625
+ ...style
626
+ },
627
+ children
628
+ }
629
+ );
630
+ Divider = ({ orientation, className, style }) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
631
+ "hr",
632
+ {
633
+ className,
634
+ style: {
635
+ border: "none",
636
+ borderTop: orientation === "vertical" ? "none" : "1px solid #e2e8f0",
637
+ borderLeft: orientation === "vertical" ? "1px solid #e2e8f0" : "none",
638
+ margin: orientation === "vertical" ? "0 8px" : "8px 0",
639
+ alignSelf: orientation === "vertical" ? "stretch" : void 0,
640
+ ...style
641
+ }
642
+ }
643
+ );
644
+ Spacer = ({ size, className, style }) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
645
+ "div",
646
+ {
647
+ className,
648
+ style: {
649
+ flex: size ? `0 0 ${Number(size) * 4}px` : "1",
650
+ ...style
651
+ }
652
+ }
653
+ );
654
+ }
655
+ });
656
+
657
+ // src/player/atoms/content.tsx
658
+ var content_exports = {};
659
+ __export(content_exports, {
660
+ Alert: () => Alert,
661
+ Badge: () => Badge,
662
+ EmptyState: () => EmptyState,
663
+ Field: () => Field,
664
+ Heading: () => Heading,
54
665
  Icon: () => Icon,
55
666
  Image: () => Image,
56
- Link: () => Link,
57
- LocalEngineProvider: () => LocalEngineProvider,
58
- LocalWorkflowEngine: () => LocalWorkflowEngine,
59
667
  Markdown: () => Markdown,
60
- MetricCard: () => MetricCard,
61
- Modal: () => Modal,
62
- ModelBuilder: () => ModelBuilder,
63
- NavLink: () => NavLink,
64
- ORCHESTRATION_PRESETS: () => ORCHESTRATION_PRESETS,
65
- PlayerProvider: () => PlayerProvider,
66
- RoleGuard: () => RoleGuard,
67
- Route: () => Route,
68
- Router: () => Router,
69
- Row: () => Row2,
70
- RuntimeContext: () => RuntimeContext,
71
- ScrollArea: () => ScrollArea,
72
- Section: () => Section2,
73
- Select: () => Select,
74
- ServerGrid: () => ServerGrid,
75
- Show: () => Show2,
76
- Slot: () => Slot,
77
- Spacer: () => Spacer2,
78
- Stack: () => Stack2,
79
- StateBuilder: () => StateBuilder,
80
- Tabs: () => Tabs,
81
- Text: () => Text2,
82
- TextInput: () => TextInput2,
83
- TransitionBuilder: () => TransitionBuilder,
84
- TypedTransitionBuilder: () => TypedTransitionBuilder,
85
- WorkflowProvider: () => WorkflowProvider,
86
- WorkflowRuntime: () => WorkflowRuntime,
87
- action: () => action,
88
- actor: () => actor,
89
- after: () => after,
90
- allowTransition: () => allowTransition,
91
- and: () => and,
92
- applyMixins: () => applyMixins,
93
- approval: () => approval,
94
- assertModelValid: () => assertModelValid,
95
- builtinAtoms: () => builtinAtoms,
96
- cedar: () => cedar,
97
- compose: () => compose,
98
- computeVisibility: () => computeVisibility,
99
- configureActor: () => configureActor,
100
- connector: () => connector,
101
- constraints: () => constraints,
102
- createActions: () => createActions,
103
- createCRUD: () => createCRUD,
104
- createLocalDataResolver: () => createLocalDataResolver,
105
- createLocalEngineAdapter: () => createLocalEngineAdapter,
106
- createPipeline: () => createPipeline,
107
- cron: () => cron,
108
- crud: () => crud,
109
- defineBlueprint: () => defineBlueprint,
110
- defineImperativeBlueprint: () => blueprint,
111
- defineMiddleware: () => defineMiddleware,
112
- defineModel: () => defineModel,
113
- defineModule: () => defineModule,
114
- defineRoles: () => defineRoles,
115
- defineWorkspace: () => defineWorkspace,
116
- delay: () => delay,
117
- deriveInstanceKey: () => deriveInstanceKey,
118
- deriveInstanceKeySync: () => deriveInstanceKeySync,
119
- describeModel: () => describeModel,
120
- deviceAction: () => deviceAction,
121
- dmn: () => dmn,
122
- editableBy: () => editableBy,
123
- editableIn: () => editableIn,
124
- emit: () => emit,
125
- escalation: () => escalation,
126
- every: () => every,
127
- expr: () => expr,
128
- extend: () => extend,
129
- extendMiddleware: () => extendMiddleware,
130
- field: () => field,
131
- fieldContains: () => fieldContains,
132
- fieldEquals: () => fieldEquals,
133
- fieldGreaterThan: () => fieldGreaterThan,
134
- fieldIn: () => fieldIn,
135
- fieldIsEmpty: () => fieldIsEmpty,
136
- fieldIsSet: () => fieldIsSet,
137
- fieldLessThan: () => fieldLessThan,
138
- fieldMatches: () => fieldMatches,
139
- fieldNotEquals: () => fieldNotEquals,
140
- fieldNotIn: () => fieldNotIn,
141
- getInstalledModule: () => getInstalledModule,
142
- getInstalledModules: () => getInstalledModules,
143
- graphql: () => graphql,
144
- guard: () => guard,
145
- hasAnyRole: () => hasAnyRole,
146
- hasRole: () => hasRole,
147
- imperativeCron: () => cron2,
148
- imperativeLog: () => log,
149
- imperativeNotify: () => notify2,
150
- imperativeRequireRole: () => requireRole2,
151
- inState: () => inState,
152
- inputEquals: () => inputEquals,
153
- inputRequired: () => inputRequired,
154
- instance: () => instance,
155
- isActor: () => isActor,
156
- isActorConfig: () => isActorConfig,
157
- isBuiltInConstraint: () => isBuiltInConstraint,
158
- isConstraintDeclaration: () => isConstraintDeclaration,
668
+ Progress: () => Progress,
669
+ Separator: () => Separator,
670
+ Text: () => Text
671
+ });
672
+ var import_jsx_runtime3, Text, Heading, Field, Image, Badge, ICON_MAP, Icon, Alert, EmptyState, Markdown, Progress, Separator;
673
+ var init_content = __esm({
674
+ "src/player/atoms/content.tsx"() {
675
+ "use strict";
676
+ import_jsx_runtime3 = require("react/jsx-runtime");
677
+ Text = ({ value, children, variant, size, weight, color, align, className, style }) => {
678
+ const text = value ?? children;
679
+ const sizeMap = { xs: 11, sm: 13, md: 14, lg: 16, xl: 20, "2xl": 24 };
680
+ const weightMap = { light: 300, normal: 400, medium: 500, semibold: 600, bold: 700 };
681
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
682
+ "span",
683
+ {
684
+ className,
685
+ style: {
686
+ fontSize: size ? sizeMap[size] ?? Number(size) : void 0,
687
+ fontWeight: weight ? weightMap[weight] ?? weight : void 0,
688
+ color: variant === "muted" ? "#718096" : variant === "error" ? "#e53e3e" : variant === "success" ? "#38a169" : color,
689
+ textAlign: align,
690
+ ...style
691
+ },
692
+ children: text == null ? "" : String(text)
693
+ }
694
+ );
695
+ };
696
+ Heading = ({ value, children, level, className, style }) => {
697
+ const text = value ?? children;
698
+ const sizes = { 1: 32, 2: 24, 3: 20, 4: 16, 5: 14, 6: 12 };
699
+ const lvl = Number(level) || 2;
700
+ const Tag = `h${Math.min(Math.max(lvl, 1), 6)}`;
701
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
702
+ Tag,
703
+ {
704
+ className,
705
+ style: {
706
+ fontSize: sizes[lvl] ?? 20,
707
+ fontWeight: 600,
708
+ margin: "0 0 8px 0",
709
+ lineHeight: 1.3,
710
+ ...style
711
+ },
712
+ children: text == null ? "" : String(text)
713
+ }
714
+ );
715
+ };
716
+ Field = ({ label, value, type: _type, children, className, style }) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className, style: { marginBottom: 8, ...style }, children: [
717
+ label ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("label", { style: { display: "block", fontSize: 12, fontWeight: 500, color: "#718096", marginBottom: 2 }, children: String(label) }) : null,
718
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: { fontSize: 14 }, children: children ?? (value != null ? String(value) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { style: { color: "#a0aec0" }, children: "\u2014" })) })
719
+ ] });
720
+ Image = ({ src, alt, width, height, fit, radius, className, style }) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
721
+ "img",
722
+ {
723
+ src,
724
+ alt: alt ?? "",
725
+ className,
726
+ style: {
727
+ width: width ? Number(width) : void 0,
728
+ height: height ? Number(height) : void 0,
729
+ objectFit: fit ?? "cover",
730
+ borderRadius: radius ? Number(radius) : void 0,
731
+ maxWidth: "100%",
732
+ ...style
733
+ }
734
+ }
735
+ );
736
+ Badge = ({ value, children, variant, color, className, style }) => {
737
+ const text = value ?? children;
738
+ const colorMap = {
739
+ default: { bg: "#edf2f7", fg: "#4a5568" },
740
+ primary: { bg: "#ebf8ff", fg: "#2b6cb0" },
741
+ success: { bg: "#f0fff4", fg: "#276749" },
742
+ warning: { bg: "#fffaf0", fg: "#c05621" },
743
+ error: { bg: "#fff5f5", fg: "#c53030" },
744
+ info: { bg: "#ebf8ff", fg: "#2b6cb0" }
745
+ };
746
+ const c = colorMap[variant ?? "default"] ?? colorMap.default;
747
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
748
+ "span",
749
+ {
750
+ className,
751
+ style: {
752
+ display: "inline-block",
753
+ padding: "1px 8px",
754
+ borderRadius: 9999,
755
+ fontSize: 12,
756
+ fontWeight: 500,
757
+ background: color ? void 0 : c.bg,
758
+ color: color ?? c.fg,
759
+ ...style
760
+ },
761
+ children: text == null ? "" : String(text)
762
+ }
763
+ );
764
+ };
765
+ ICON_MAP = {
766
+ "check": "\u2713",
767
+ "x": "\u2715",
768
+ "plus": "+",
769
+ "minus": "\u2212",
770
+ "arrow-right": "\u2192",
771
+ "arrow-left": "\u2190",
772
+ "arrow-up": "\u2191",
773
+ "arrow-down": "\u2193",
774
+ "search": "\u{1F50D}",
775
+ "home": "\u{1F3E0}",
776
+ "user": "\u{1F464}",
777
+ "settings": "\u2699",
778
+ "star": "\u2B50",
779
+ "heart": "\u2764",
780
+ "mail": "\u2709",
781
+ "phone": "\u{1F4DE}",
782
+ "calendar": "\u{1F4C5}",
783
+ "clock": "\u{1F550}",
784
+ "edit": "\u270E",
785
+ "trash": "\u{1F5D1}",
786
+ "download": "\u2B07",
787
+ "upload": "\u2B06",
788
+ "share": "\u2197",
789
+ "lock": "\u{1F512}",
790
+ "unlock": "\u{1F513}",
791
+ "eye": "\u{1F441}",
792
+ "eye-off": "\u{1F648}",
793
+ "bell": "\u{1F514}",
794
+ "info": "\u2139",
795
+ "warning": "\u26A0",
796
+ "error": "\u274C",
797
+ "loading": "\u23F3",
798
+ "menu": "\u2630",
799
+ "close": "\u2715",
800
+ "chevron-right": "\u203A",
801
+ "chevron-left": "\u2039",
802
+ "chevron-up": "\u2038",
803
+ "chevron-down": "\u02EC",
804
+ "copy": "\u{1F4CB}",
805
+ "save": "\u{1F4BE}",
806
+ "refresh": "\u21BB",
807
+ "filter": "\u23CF",
808
+ "sort": "\u21C5"
809
+ };
810
+ Icon = ({ name, size, color, className, style }) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
811
+ "span",
812
+ {
813
+ className,
814
+ role: "img",
815
+ "aria-label": name,
816
+ style: {
817
+ fontSize: size ? Number(size) : 16,
818
+ color,
819
+ display: "inline-flex",
820
+ alignItems: "center",
821
+ justifyContent: "center",
822
+ ...style
823
+ },
824
+ children: ICON_MAP[name?.toLowerCase()] ?? name ?? "?"
825
+ }
826
+ );
827
+ Alert = ({ children, variant, title, message, className, style }) => {
828
+ const colorMap = {
829
+ info: { bg: "#ebf8ff", border: "#90cdf4", fg: "#2b6cb0" },
830
+ success: { bg: "#f0fff4", border: "#9ae6b4", fg: "#276749" },
831
+ warning: { bg: "#fffaf0", border: "#fbd38d", fg: "#c05621" },
832
+ error: { bg: "#fff5f5", border: "#feb2b2", fg: "#c53030" }
833
+ };
834
+ const c = colorMap[variant ?? "info"] ?? colorMap.info;
835
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
836
+ "div",
837
+ {
838
+ className,
839
+ role: "alert",
840
+ style: {
841
+ padding: "12px 16px",
842
+ borderRadius: 6,
843
+ border: `1px solid ${c.border}`,
844
+ background: c.bg,
845
+ color: c.fg,
846
+ fontSize: 14,
847
+ ...style
848
+ },
849
+ children: [
850
+ title ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: { fontWeight: 600, marginBottom: 4 }, children: String(title) }) : null,
851
+ message ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { children: String(message) }) : null,
852
+ children
853
+ ]
854
+ }
855
+ );
856
+ };
857
+ EmptyState = ({ children, title, description, icon, className, style }) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
858
+ "div",
859
+ {
860
+ className,
861
+ style: {
862
+ textAlign: "center",
863
+ padding: "32px 16px",
864
+ color: "#a0aec0",
865
+ ...style
866
+ },
867
+ children: [
868
+ icon ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: { fontSize: 40, marginBottom: 12 }, children: ICON_MAP[icon] ?? icon }) : null,
869
+ title ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: { fontSize: 16, fontWeight: 600, color: "#4a5568", marginBottom: 4 }, children: String(title) }) : null,
870
+ description ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: { fontSize: 14, marginBottom: 8 }, children: String(description) }) : null,
871
+ children
872
+ ]
873
+ }
874
+ );
875
+ Markdown = ({ value, children, className, style }) => {
876
+ const text = String(value ?? children ?? "");
877
+ const html = text.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/\*\*(.+?)\*\*/g, "<strong>$1</strong>").replace(/\*(.+?)\*/g, "<em>$1</em>").replace(/`(.+?)`/g, '<code style="background:#edf2f7;padding:1px 4px;border-radius:3px;font-size:13px">$1</code>').replace(/\n/g, "<br/>");
878
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
879
+ "div",
880
+ {
881
+ className,
882
+ style: { fontSize: 14, lineHeight: 1.6, ...style },
883
+ dangerouslySetInnerHTML: { __html: html }
884
+ }
885
+ );
886
+ };
887
+ Progress = ({ value, max, label, variant, className, style }) => {
888
+ const pct = Math.min(100, Math.max(0, Number(value) / (Number(max) || 100) * 100));
889
+ const colorMap = {
890
+ default: "#3182ce",
891
+ success: "#38a169",
892
+ warning: "#dd6b20",
893
+ error: "#e53e3e"
894
+ };
895
+ const color = colorMap[variant ?? "default"] ?? colorMap.default;
896
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className, style: { ...style }, children: [
897
+ label ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: { fontSize: 12, marginBottom: 4, color: "#718096" }, children: String(label) }) : null,
898
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: { height: 8, background: "#edf2f7", borderRadius: 4, overflow: "hidden" }, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: { height: "100%", width: `${pct}%`, background: color, borderRadius: 4, transition: "width 0.3s" } }) })
899
+ ] });
900
+ };
901
+ Separator = ({ className, style }) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
902
+ "hr",
903
+ {
904
+ className,
905
+ style: { border: "none", borderTop: "1px solid #e2e8f0", margin: "16px 0", ...style }
906
+ }
907
+ );
908
+ }
909
+ });
910
+
911
+ // src/player/atoms/actions.tsx
912
+ var actions_exports = {};
913
+ __export(actions_exports, {
914
+ Button: () => Button,
915
+ Link: () => Link
916
+ });
917
+ var import_react36, import_jsx_runtime4, VARIANT_STYLES, SIZE_STYLES, Button, Link;
918
+ var init_actions = __esm({
919
+ "src/player/atoms/actions.tsx"() {
920
+ "use strict";
921
+ import_react36 = require("react");
922
+ import_jsx_runtime4 = require("react/jsx-runtime");
923
+ VARIANT_STYLES = {
924
+ primary: { background: "#3182ce", color: "#fff", border: "1px solid #3182ce" },
925
+ secondary: { background: "#edf2f7", color: "#4a5568", border: "1px solid #e2e8f0" },
926
+ outline: { background: "transparent", color: "#3182ce", border: "1px solid #3182ce" },
927
+ ghost: { background: "transparent", color: "#4a5568", border: "1px solid transparent" },
928
+ danger: { background: "#e53e3e", color: "#fff", border: "1px solid #e53e3e" },
929
+ destructive: { background: "#e53e3e", color: "#fff", border: "1px solid #e53e3e" },
930
+ success: { background: "#38a169", color: "#fff", border: "1px solid #38a169" },
931
+ link: { background: "transparent", color: "#3182ce", border: "none", textDecoration: "underline" },
932
+ default: { background: "#fff", color: "#1a202c", border: "1px solid #e2e8f0" }
933
+ };
934
+ SIZE_STYLES = {
935
+ xs: { padding: "2px 8px", fontSize: 11 },
936
+ sm: { padding: "4px 12px", fontSize: 13 },
937
+ md: { padding: "6px 16px", fontSize: 14 },
938
+ lg: { padding: "8px 24px", fontSize: 16 },
939
+ xl: { padding: "12px 32px", fontSize: 18 }
940
+ };
941
+ Button = ({
942
+ children,
943
+ label,
944
+ value,
945
+ onClick,
946
+ variant,
947
+ size,
948
+ disabled,
949
+ loading: loadingProp,
950
+ icon,
951
+ iconRight,
952
+ fullWidth,
953
+ className,
954
+ style
955
+ }) => {
956
+ const [isLoading, setIsLoading] = (0, import_react36.useState)(false);
957
+ const text = children ?? label ?? value;
958
+ const isDisabled = Boolean(disabled) || isLoading || Boolean(loadingProp);
959
+ const vs = VARIANT_STYLES[variant ?? "default"] ?? VARIANT_STYLES.default;
960
+ const ss = SIZE_STYLES[size ?? "md"] ?? SIZE_STYLES.md;
961
+ const handleClick = (0, import_react36.useCallback)(async (e) => {
962
+ if (isDisabled) return;
963
+ if (typeof onClick === "function") {
964
+ const result = onClick(e);
965
+ if (result && typeof result === "object" && typeof result.then === "function") {
966
+ setIsLoading(true);
967
+ try {
968
+ await result;
969
+ } finally {
970
+ setIsLoading(false);
971
+ }
972
+ }
973
+ }
974
+ }, [onClick, isDisabled]);
975
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
976
+ "button",
977
+ {
978
+ className,
979
+ disabled: isDisabled,
980
+ onClick: handleClick,
981
+ style: {
982
+ ...vs,
983
+ ...ss,
984
+ borderRadius: 6,
985
+ cursor: isDisabled ? "not-allowed" : "pointer",
986
+ opacity: isDisabled ? 0.6 : 1,
987
+ fontWeight: 500,
988
+ display: "inline-flex",
989
+ alignItems: "center",
990
+ justifyContent: "center",
991
+ gap: 6,
992
+ width: fullWidth ? "100%" : void 0,
993
+ transition: "opacity 0.15s, background 0.15s",
994
+ ...style
995
+ },
996
+ children: [
997
+ isLoading || loadingProp ? "\u23F3" : icon ? String(icon) : null,
998
+ text != null ? String(text) : null,
999
+ iconRight ? String(iconRight) : null
1000
+ ]
1001
+ }
1002
+ );
1003
+ };
1004
+ Link = ({ children, href, to, label, onClick, external, className, style }) => {
1005
+ const text = children ?? label;
1006
+ const target = href ?? to;
1007
+ const handleClick = (0, import_react36.useCallback)((e) => {
1008
+ if (typeof onClick === "function") {
1009
+ e.preventDefault();
1010
+ onClick(e);
1011
+ }
1012
+ }, [onClick]);
1013
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1014
+ "a",
1015
+ {
1016
+ href: target ?? "#",
1017
+ className,
1018
+ onClick: handleClick,
1019
+ target: external ? "_blank" : void 0,
1020
+ rel: external ? "noopener noreferrer" : void 0,
1021
+ style: {
1022
+ color: "#3182ce",
1023
+ textDecoration: "none",
1024
+ cursor: "pointer",
1025
+ fontSize: 14,
1026
+ ...style
1027
+ },
1028
+ children: text != null ? String(text) : target ?? "Link"
1029
+ }
1030
+ );
1031
+ };
1032
+ }
1033
+ });
1034
+
1035
+ // src/player/atoms/control-flow.tsx
1036
+ var control_flow_exports = {};
1037
+ __export(control_flow_exports, {
1038
+ Each: () => Each,
1039
+ Show: () => Show
1040
+ });
1041
+ var import_jsx_runtime5, Show, Each;
1042
+ var init_control_flow = __esm({
1043
+ "src/player/atoms/control-flow.tsx"() {
1044
+ "use strict";
1045
+ init_scope_builder();
1046
+ import_jsx_runtime5 = require("react/jsx-runtime");
1047
+ Show = ({ when: when2, fallback, children }) => {
1048
+ if (when2) return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_jsx_runtime5.Fragment, { children });
1049
+ if (fallback) return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_jsx_runtime5.Fragment, { children: fallback });
1050
+ return null;
1051
+ };
1052
+ Each = ({ items, as: asName, keyField, children, renderItem, emptyState, className, style }) => {
1053
+ const parentScope = useScope();
1054
+ const itemArray = Array.isArray(items) ? items : [];
1055
+ const varName = asName ?? "item";
1056
+ const keyProp = keyField ?? "id";
1057
+ if (itemArray.length === 0) {
1058
+ if (emptyState) return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_jsx_runtime5.Fragment, { children: emptyState });
1059
+ return null;
1060
+ }
1061
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className, style, children: itemArray.map((item, index) => {
1062
+ const loopScope = buildLoopScope(parentScope, item, index, varName);
1063
+ const key = item && typeof item === "object" && keyProp in item ? String(item[keyProp]) : String(index);
1064
+ if (typeof renderItem === "function") {
1065
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ScopeContext.Provider, { value: loopScope, children: renderItem(item, index) }, key);
1066
+ }
1067
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ScopeContext.Provider, { value: loopScope, children }, key);
1068
+ }) });
1069
+ };
1070
+ }
1071
+ });
1072
+
1073
+ // src/player/atoms/input.tsx
1074
+ var input_exports = {};
1075
+ __export(input_exports, {
1076
+ Select: () => Select,
1077
+ Slider: () => Slider,
1078
+ TextInput: () => TextInput,
1079
+ Toggle: () => Toggle
1080
+ });
1081
+ var import_react37, import_jsx_runtime6, inputBase, TextInput, Select, Toggle, Slider;
1082
+ var init_input = __esm({
1083
+ "src/player/atoms/input.tsx"() {
1084
+ "use strict";
1085
+ import_react37 = require("react");
1086
+ import_jsx_runtime6 = require("react/jsx-runtime");
1087
+ inputBase = {
1088
+ padding: "6px 12px",
1089
+ border: "1px solid #e2e8f0",
1090
+ borderRadius: 6,
1091
+ fontSize: 14,
1092
+ outline: "none",
1093
+ width: "100%",
1094
+ boxSizing: "border-box",
1095
+ background: "#fff",
1096
+ color: "#1a202c",
1097
+ transition: "border-color 0.15s"
1098
+ };
1099
+ TextInput = ({
1100
+ value,
1101
+ onChange,
1102
+ onBlur,
1103
+ placeholder,
1104
+ label,
1105
+ type,
1106
+ name,
1107
+ disabled,
1108
+ required,
1109
+ error,
1110
+ helperText,
1111
+ multiline,
1112
+ rows,
1113
+ maxLength,
1114
+ className,
1115
+ style,
1116
+ bind: _bind
1117
+ }) => {
1118
+ const isControlled = typeof onChange === "function";
1119
+ const [localValue, setLocalValue] = (0, import_react37.useState)(value ?? "");
1120
+ (0, import_react37.useEffect)(() => {
1121
+ if (value != null && String(value) !== localValue) {
1122
+ setLocalValue(String(value));
1123
+ }
1124
+ }, [value]);
1125
+ const handleChange = (0, import_react37.useCallback)((e) => {
1126
+ setLocalValue(e.target.value);
1127
+ if (typeof onChange === "function") {
1128
+ onChange(e);
1129
+ }
1130
+ }, [onChange]);
1131
+ const displayValue = isControlled ? value ?? "" : localValue;
1132
+ const hasError = Boolean(error);
1133
+ const inputStyle = {
1134
+ ...inputBase,
1135
+ borderColor: hasError ? "#e53e3e" : "#e2e8f0",
1136
+ ...style
1137
+ };
1138
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className, style: { width: "100%" }, children: [
1139
+ label ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("label", { style: { display: "block", fontSize: 13, fontWeight: 500, marginBottom: 4, color: "#4a5568" }, children: [
1140
+ String(label),
1141
+ required ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { style: { color: "#e53e3e" }, children: " *" }) : null
1142
+ ] }) : null,
1143
+ multiline ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1144
+ "textarea",
1145
+ {
1146
+ value: displayValue,
1147
+ onChange: handleChange,
1148
+ onBlur,
1149
+ placeholder,
1150
+ name,
1151
+ disabled: Boolean(disabled),
1152
+ required: Boolean(required),
1153
+ rows: Number(rows) || 3,
1154
+ maxLength: maxLength ? Number(maxLength) : void 0,
1155
+ style: inputStyle
1156
+ }
1157
+ ) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1158
+ "input",
1159
+ {
1160
+ type: type ?? "text",
1161
+ value: displayValue,
1162
+ onChange: handleChange,
1163
+ onBlur,
1164
+ placeholder,
1165
+ name,
1166
+ disabled: Boolean(disabled),
1167
+ required: Boolean(required),
1168
+ maxLength: maxLength ? Number(maxLength) : void 0,
1169
+ style: inputStyle
1170
+ }
1171
+ ),
1172
+ error || helperText ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: { fontSize: 12, marginTop: 2, color: hasError ? "#e53e3e" : "#a0aec0" }, children: String(error || helperText) }) : null
1173
+ ] });
1174
+ };
1175
+ Select = ({
1176
+ value,
1177
+ onChange,
1178
+ options,
1179
+ placeholder,
1180
+ label,
1181
+ disabled,
1182
+ required,
1183
+ error,
1184
+ name,
1185
+ className,
1186
+ style
1187
+ }) => {
1188
+ const [localValue, setLocalValue] = (0, import_react37.useState)(value ?? "");
1189
+ const isControlled = typeof onChange === "function";
1190
+ (0, import_react37.useEffect)(() => {
1191
+ if (value != null && String(value) !== localValue) setLocalValue(String(value));
1192
+ }, [value]);
1193
+ const handleChange = (0, import_react37.useCallback)((e) => {
1194
+ setLocalValue(e.target.value);
1195
+ if (typeof onChange === "function") onChange(e);
1196
+ }, [onChange]);
1197
+ const displayValue = isControlled ? value ?? "" : localValue;
1198
+ const opts = Array.isArray(options) ? options : [];
1199
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className, children: [
1200
+ label ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("label", { style: { display: "block", fontSize: 13, fontWeight: 500, marginBottom: 4, color: "#4a5568" }, children: [
1201
+ String(label),
1202
+ required ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { style: { color: "#e53e3e" }, children: " *" }) : null
1203
+ ] }) : null,
1204
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
1205
+ "select",
1206
+ {
1207
+ value: displayValue,
1208
+ onChange: handleChange,
1209
+ disabled: Boolean(disabled),
1210
+ name,
1211
+ style: {
1212
+ ...inputBase,
1213
+ borderColor: error ? "#e53e3e" : "#e2e8f0",
1214
+ ...style
1215
+ },
1216
+ children: [
1217
+ placeholder ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("option", { value: "", children: String(placeholder) }) : null,
1218
+ opts.map((opt, i) => {
1219
+ const val = typeof opt === "object" ? opt.value : opt;
1220
+ const lbl = typeof opt === "object" ? opt.label ?? val : opt;
1221
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("option", { value: String(val), children: String(lbl) }, String(val) ?? i);
1222
+ })
1223
+ ]
1224
+ }
1225
+ )
1226
+ ] });
1227
+ };
1228
+ Toggle = ({ value, checked, onChange, label, disabled, className, style }) => {
1229
+ const isOn = Boolean(value ?? checked);
1230
+ const handleClick = (0, import_react37.useCallback)(() => {
1231
+ if (disabled) return;
1232
+ if (typeof onChange === "function") onChange(!isOn);
1233
+ }, [onChange, isOn, disabled]);
1234
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
1235
+ "div",
1236
+ {
1237
+ className,
1238
+ style: { display: "flex", alignItems: "center", gap: 8, ...style },
1239
+ children: [
1240
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1241
+ "button",
1242
+ {
1243
+ role: "switch",
1244
+ "aria-checked": isOn,
1245
+ disabled: Boolean(disabled),
1246
+ onClick: handleClick,
1247
+ style: {
1248
+ width: 40,
1249
+ height: 22,
1250
+ borderRadius: 11,
1251
+ border: "none",
1252
+ cursor: disabled ? "not-allowed" : "pointer",
1253
+ background: isOn ? "#3182ce" : "#cbd5e0",
1254
+ padding: 2,
1255
+ transition: "background 0.2s",
1256
+ display: "flex",
1257
+ alignItems: "center"
1258
+ },
1259
+ children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: {
1260
+ width: 18,
1261
+ height: 18,
1262
+ borderRadius: "50%",
1263
+ background: "#fff",
1264
+ transform: isOn ? "translateX(18px)" : "translateX(0)",
1265
+ transition: "transform 0.2s",
1266
+ boxShadow: "0 1px 3px rgba(0,0,0,0.2)"
1267
+ } })
1268
+ }
1269
+ ),
1270
+ label ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { style: { fontSize: 14 }, children: String(label) }) : null
1271
+ ]
1272
+ }
1273
+ );
1274
+ };
1275
+ Slider = ({ value, onChange, min, max, step, label, disabled, className, style }) => {
1276
+ const numVal = Number(value) || Number(min) || 0;
1277
+ const handleChange = (0, import_react37.useCallback)((e) => {
1278
+ if (typeof onChange === "function") onChange(Number(e.target.value));
1279
+ }, [onChange]);
1280
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className, style: { ...style }, children: [
1281
+ label ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: { display: "flex", justifyContent: "space-between", fontSize: 13, marginBottom: 4 }, children: [
1282
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { style: { color: "#4a5568", fontWeight: 500 }, children: String(label) }),
1283
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { style: { color: "#718096" }, children: numVal })
1284
+ ] }) : null,
1285
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1286
+ "input",
1287
+ {
1288
+ type: "range",
1289
+ value: numVal,
1290
+ onChange: handleChange,
1291
+ min: Number(min) ?? 0,
1292
+ max: Number(max) ?? 100,
1293
+ step: Number(step) ?? 1,
1294
+ disabled: Boolean(disabled),
1295
+ style: { width: "100%" }
1296
+ }
1297
+ )
1298
+ ] });
1299
+ };
1300
+ }
1301
+ });
1302
+
1303
+ // src/player/atoms/grouping.tsx
1304
+ var grouping_exports = {};
1305
+ __export(grouping_exports, {
1306
+ Accordion: () => Accordion,
1307
+ Card: () => Card,
1308
+ Modal: () => Modal,
1309
+ ScrollArea: () => ScrollArea,
1310
+ Section: () => Section,
1311
+ Tabs: () => Tabs
1312
+ });
1313
+ var import_react38, import_jsx_runtime7, Card, Section, Tabs, Accordion, Modal, ScrollArea;
1314
+ var init_grouping = __esm({
1315
+ "src/player/atoms/grouping.tsx"() {
1316
+ "use strict";
1317
+ import_react38 = __toESM(require("react"));
1318
+ import_jsx_runtime7 = require("react/jsx-runtime");
1319
+ Card = ({ children, title, subtitle, padding, variant, className, style }) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
1320
+ "div",
1321
+ {
1322
+ className,
1323
+ style: {
1324
+ background: variant === "outlined" ? "transparent" : "#fff",
1325
+ border: "1px solid #e2e8f0",
1326
+ borderRadius: 8,
1327
+ padding: padding != null ? Number(padding) * 4 : 16,
1328
+ boxShadow: variant === "elevated" ? "0 2px 8px rgba(0,0,0,0.08)" : void 0,
1329
+ ...style
1330
+ },
1331
+ children: [
1332
+ title ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: { fontWeight: 600, fontSize: 16, marginBottom: subtitle ? 2 : 12 }, children: String(title) }) : null,
1333
+ subtitle ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: { fontSize: 13, color: "#718096", marginBottom: 12 }, children: String(subtitle) }) : null,
1334
+ children
1335
+ ]
1336
+ }
1337
+ );
1338
+ Section = ({ children, title, description, collapsible, defaultOpen, className, style }) => {
1339
+ const [open, setOpen] = (0, import_react38.useState)(defaultOpen !== false);
1340
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className, style: { marginBottom: 16, ...style }, children: [
1341
+ title ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
1342
+ "div",
1343
+ {
1344
+ style: {
1345
+ display: "flex",
1346
+ alignItems: "center",
1347
+ justifyContent: "space-between",
1348
+ marginBottom: open ? 12 : 0,
1349
+ cursor: collapsible ? "pointer" : void 0
1350
+ },
1351
+ onClick: collapsible ? () => setOpen((v) => !v) : void 0,
1352
+ children: [
1353
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { children: [
1354
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: { fontWeight: 600, fontSize: 15 }, children: String(title) }),
1355
+ description ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: { fontSize: 13, color: "#718096", marginTop: 2 }, children: String(description) }) : null
1356
+ ] }),
1357
+ collapsible ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { style: { color: "#a0aec0", fontSize: 18 }, children: open ? "\u25BE" : "\u25B8" }) : null
1358
+ ]
1359
+ }
1360
+ ) : null,
1361
+ open ? children : null
1362
+ ] });
1363
+ };
1364
+ Tabs = ({ children, tabs, defaultTab, className, style }) => {
1365
+ const tabList = Array.isArray(tabs) ? tabs.map((t) => typeof t === "string" ? { label: t, value: t } : t) : [];
1366
+ const [active, setActive] = (0, import_react38.useState)(defaultTab ?? tabList[0]?.value ?? "");
1367
+ if (tabList.length === 0) {
1368
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className, style, children });
1369
+ }
1370
+ const childArray = import_react38.default.Children.toArray(children);
1371
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className, style, children: [
1372
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: { display: "flex", borderBottom: "2px solid #e2e8f0", marginBottom: 12, gap: 0 }, children: tabList.map((tab) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1373
+ "button",
1374
+ {
1375
+ onClick: () => setActive(tab.value),
1376
+ style: {
1377
+ padding: "8px 16px",
1378
+ fontSize: 14,
1379
+ fontWeight: 500,
1380
+ cursor: "pointer",
1381
+ border: "none",
1382
+ background: "none",
1383
+ borderBottom: "2px solid transparent",
1384
+ marginBottom: -2,
1385
+ color: active === tab.value ? "#3182ce" : "#718096",
1386
+ borderBottomColor: active === tab.value ? "#3182ce" : "transparent"
1387
+ },
1388
+ children: tab.label
1389
+ },
1390
+ tab.value
1391
+ )) }),
1392
+ childArray.map((child, i) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: { display: tabList[i]?.value === active ? "block" : "none" }, children: child }, i))
1393
+ ] });
1394
+ };
1395
+ Accordion = ({ children, items, allowMultiple, className, style }) => {
1396
+ const [openItems, setOpenItems] = (0, import_react38.useState)(/* @__PURE__ */ new Set([0]));
1397
+ const toggle = (0, import_react38.useCallback)((index) => {
1398
+ setOpenItems((prev) => {
1399
+ const next = new Set(allowMultiple ? prev : []);
1400
+ if (prev.has(index)) next.delete(index);
1401
+ else next.add(index);
1402
+ return next;
1403
+ });
1404
+ }, [allowMultiple]);
1405
+ const itemList = Array.isArray(items) ? items : [];
1406
+ if (itemList.length === 0) {
1407
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className, style, children });
1408
+ }
1409
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className, style: { border: "1px solid #e2e8f0", borderRadius: 8, overflow: "hidden", ...style }, children: itemList.map((item, i) => {
1410
+ const itm = item;
1411
+ const isOpen = openItems.has(i);
1412
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: { borderBottom: i < itemList.length - 1 ? "1px solid #e2e8f0" : "none" }, children: [
1413
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
1414
+ "button",
1415
+ {
1416
+ onClick: () => toggle(i),
1417
+ style: {
1418
+ width: "100%",
1419
+ padding: "12px 16px",
1420
+ background: "none",
1421
+ border: "none",
1422
+ textAlign: "left",
1423
+ cursor: "pointer",
1424
+ display: "flex",
1425
+ justifyContent: "space-between",
1426
+ alignItems: "center",
1427
+ fontSize: 14,
1428
+ fontWeight: 500
1429
+ },
1430
+ children: [
1431
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: String(itm.title ?? itm.label ?? `Item ${i + 1}`) }),
1432
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { style: { color: "#a0aec0" }, children: isOpen ? "\u25BE" : "\u25B8" })
1433
+ ]
1434
+ }
1435
+ ),
1436
+ isOpen ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: { padding: "0 16px 12px" }, children: itm.content ? String(itm.content) : null }) : null
1437
+ ] }, i);
1438
+ }) });
1439
+ };
1440
+ Modal = ({ children, open, isOpen, onClose, title, size, id, nodeId, className, style }) => {
1441
+ const modalId = id ?? nodeId;
1442
+ const [eventOpen, setEventOpen] = (0, import_react38.useState)(false);
1443
+ (0, import_react38.useEffect)(() => {
1444
+ if (!modalId) return;
1445
+ const handleOpen = (e) => {
1446
+ const detail = e.detail;
1447
+ if (detail === modalId || detail?.id === modalId) {
1448
+ setEventOpen(true);
1449
+ }
1450
+ };
1451
+ const handleClose = (e) => {
1452
+ const detail = e.detail;
1453
+ if (detail === modalId || detail?.id === modalId) {
1454
+ setEventOpen(false);
1455
+ }
1456
+ };
1457
+ window.addEventListener("openModal", handleOpen);
1458
+ window.addEventListener("closeModal", handleClose);
1459
+ return () => {
1460
+ window.removeEventListener("openModal", handleOpen);
1461
+ window.removeEventListener("closeModal", handleClose);
1462
+ };
1463
+ }, [modalId]);
1464
+ const visible = Boolean(open ?? isOpen ?? eventOpen);
1465
+ (0, import_react38.useEffect)(() => {
1466
+ if (visible) document.body.style.overflow = "hidden";
1467
+ return () => {
1468
+ document.body.style.overflow = "";
1469
+ };
1470
+ }, [visible]);
1471
+ if (!visible) return null;
1472
+ const widthMap = { sm: 400, md: 560, lg: 720, xl: 960, full: 9999 };
1473
+ const maxWidth = widthMap[size ?? "md"] ?? 560;
1474
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1475
+ "div",
1476
+ {
1477
+ style: {
1478
+ position: "fixed",
1479
+ inset: 0,
1480
+ zIndex: 9999,
1481
+ display: "flex",
1482
+ alignItems: "center",
1483
+ justifyContent: "center",
1484
+ background: "rgba(0,0,0,0.4)"
1485
+ },
1486
+ onClick: (e) => {
1487
+ if (e.target === e.currentTarget) {
1488
+ setEventOpen(false);
1489
+ if (typeof onClose === "function") onClose();
1490
+ }
1491
+ },
1492
+ children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
1493
+ "div",
1494
+ {
1495
+ className,
1496
+ style: {
1497
+ background: "#fff",
1498
+ borderRadius: 12,
1499
+ padding: 24,
1500
+ maxWidth,
1501
+ width: "90%",
1502
+ maxHeight: "85vh",
1503
+ overflow: "auto",
1504
+ boxShadow: "0 20px 60px rgba(0,0,0,0.2)",
1505
+ ...style
1506
+ },
1507
+ children: [
1508
+ title || onClose ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 16 }, children: [
1509
+ title ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: { fontWeight: 600, fontSize: 18 }, children: String(title) }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", {}),
1510
+ typeof onClose === "function" ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1511
+ "button",
1512
+ {
1513
+ onClick: () => {
1514
+ setEventOpen(false);
1515
+ onClose();
1516
+ },
1517
+ style: { background: "none", border: "none", fontSize: 20, cursor: "pointer", color: "#a0aec0", padding: 4 },
1518
+ children: "\u2715"
1519
+ }
1520
+ ) : null
1521
+ ] }) : null,
1522
+ children
1523
+ ]
1524
+ }
1525
+ )
1526
+ }
1527
+ );
1528
+ };
1529
+ ScrollArea = ({ children, maxHeight, className, style }) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1530
+ "div",
1531
+ {
1532
+ className,
1533
+ style: {
1534
+ overflow: "auto",
1535
+ maxHeight: maxHeight ? Number(maxHeight) : void 0,
1536
+ ...style
1537
+ },
1538
+ children
1539
+ }
1540
+ );
1541
+ }
1542
+ });
1543
+
1544
+ // src/player/atoms/navigation.tsx
1545
+ var navigation_exports = {};
1546
+ __export(navigation_exports, {
1547
+ NavLink: () => NavLink,
1548
+ RoleGuard: () => RoleGuard,
1549
+ Route: () => Route,
1550
+ Router: () => Router,
1551
+ usePlayerRouter: () => usePlayerRouter
1552
+ });
1553
+ function usePlayerRouter() {
1554
+ return (0, import_react39.useContext)(RouterCtx);
1555
+ }
1556
+ function matchPath(pattern, currentPath, exact) {
1557
+ const params = {};
1558
+ const patternParts = pattern.split("/").filter(Boolean);
1559
+ const pathParts = currentPath.split("/").filter(Boolean);
1560
+ if (exact && patternParts.length !== pathParts.length) {
1561
+ return { match: false, params };
1562
+ }
1563
+ if (patternParts.length > pathParts.length) {
1564
+ return { match: false, params };
1565
+ }
1566
+ for (let i = 0; i < patternParts.length; i++) {
1567
+ const pp = patternParts[i];
1568
+ if (pp.startsWith(":")) {
1569
+ params[pp.slice(1)] = pathParts[i];
1570
+ } else if (pp === "*") {
1571
+ return { match: true, params };
1572
+ } else if (pp !== pathParts[i]) {
1573
+ return { match: false, params };
1574
+ }
1575
+ }
1576
+ return { match: true, params };
1577
+ }
1578
+ var import_react39, import_jsx_runtime8, RouterCtx, Router, Route, NavLink, RoleGuard;
1579
+ var init_navigation = __esm({
1580
+ "src/player/atoms/navigation.tsx"() {
1581
+ "use strict";
1582
+ import_react39 = require("react");
1583
+ init_scope_builder();
1584
+ import_jsx_runtime8 = require("react/jsx-runtime");
1585
+ RouterCtx = (0, import_react39.createContext)({
1586
+ path: "/",
1587
+ navigate: () => {
1588
+ },
1589
+ params: {}
1590
+ });
1591
+ Router = ({ children, basePath, className, style }) => {
1592
+ const [path, setPath] = (0, import_react39.useState)(basePath ?? "/");
1593
+ const navigate = (0, import_react39.useCallback)((to) => {
1594
+ setPath(to);
1595
+ }, []);
1596
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(RouterCtx.Provider, { value: { path, navigate, params: {} }, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className, style, children }) });
1597
+ };
1598
+ Route = ({ children, path: routePath, exact, className, style }) => {
1599
+ const { path } = (0, import_react39.useContext)(RouterCtx);
1600
+ const pattern = routePath ?? "/";
1601
+ const { match, params } = matchPath(pattern, path, exact !== false);
1602
+ if (!match) return null;
1603
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(RouterCtx.Provider, { value: { path, navigate: (0, import_react39.useContext)(RouterCtx).navigate, params }, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className, style, children }) });
1604
+ };
1605
+ NavLink = ({
1606
+ children,
1607
+ to,
1608
+ label,
1609
+ icon,
1610
+ activeClassName,
1611
+ className,
1612
+ style,
1613
+ onClick
1614
+ }) => {
1615
+ const { path, navigate } = (0, import_react39.useContext)(RouterCtx);
1616
+ const target = to ?? "/";
1617
+ const isActive = path === target || path.startsWith(target + "/");
1618
+ const text = children ?? label;
1619
+ const handleClick = (0, import_react39.useCallback)((e) => {
1620
+ e.preventDefault();
1621
+ navigate(target);
1622
+ if (typeof onClick === "function") onClick(e);
1623
+ }, [navigate, target, onClick]);
1624
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
1625
+ "button",
1626
+ {
1627
+ className: `${className ?? ""} ${isActive && activeClassName ? activeClassName : ""}`.trim() || void 0,
1628
+ onClick: handleClick,
1629
+ style: {
1630
+ background: isActive ? "#ebf8ff" : "transparent",
1631
+ color: isActive ? "#2b6cb0" : "#4a5568",
1632
+ border: "none",
1633
+ borderRadius: 6,
1634
+ padding: "6px 12px",
1635
+ fontSize: 14,
1636
+ fontWeight: isActive ? 600 : 400,
1637
+ cursor: "pointer",
1638
+ display: "inline-flex",
1639
+ alignItems: "center",
1640
+ gap: 6,
1641
+ transition: "background 0.15s, color 0.15s",
1642
+ ...style
1643
+ },
1644
+ children: [
1645
+ icon ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { children: String(icon) }) : null,
1646
+ text != null ? String(text) : null
1647
+ ]
1648
+ }
1649
+ );
1650
+ };
1651
+ RoleGuard = ({ children, role, roles, fallback }) => {
1652
+ const scope = useScope();
1653
+ const allowed = (0, import_react39.useMemo)(() => {
1654
+ const required = Array.isArray(roles) ? roles : role != null ? [String(role)] : [];
1655
+ if (required.length === 0) return true;
1656
+ const userRoles = scope.$user?.roles ?? [];
1657
+ if (userRoles.length === 0) return false;
1658
+ return required.some((r) => userRoles.includes(r));
1659
+ }, [role, roles, scope.$user]);
1660
+ if (!allowed) {
1661
+ return fallback ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_jsx_runtime8.Fragment, { children: fallback }) : null;
1662
+ }
1663
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_jsx_runtime8.Fragment, { children });
1664
+ };
1665
+ }
1666
+ });
1667
+
1668
+ // src/player/atoms/composition.tsx
1669
+ var composition_exports = {};
1670
+ __export(composition_exports, {
1671
+ ModuleOutlet: () => ModuleOutlet,
1672
+ Slot: () => Slot,
1673
+ SlotRegistryProvider: () => SlotRegistryProvider,
1674
+ useSlotContributions: () => useSlotContributions
1675
+ });
1676
+ function useSlotContributions(name) {
1677
+ const registry = (0, import_react40.useContext)(SlotRegistryContext);
1678
+ return registry.get(name) ?? [];
1679
+ }
1680
+ var import_react40, import_jsx_runtime9, SlotRegistryContext, SlotRegistryProvider, Slot, ModuleOutlet;
1681
+ var init_composition = __esm({
1682
+ "src/player/atoms/composition.tsx"() {
1683
+ "use strict";
1684
+ import_react40 = __toESM(require("react"));
1685
+ import_jsx_runtime9 = require("react/jsx-runtime");
1686
+ SlotRegistryContext = (0, import_react40.createContext)(/* @__PURE__ */ new Map());
1687
+ SlotRegistryProvider = ({ contributions, children }) => {
1688
+ const registry = (0, import_react40.useMemo)(() => {
1689
+ const map = /* @__PURE__ */ new Map();
1690
+ for (const c of contributions) {
1691
+ const list = map.get(c.name) ?? [];
1692
+ list.push(c);
1693
+ map.set(c.name, list);
1694
+ }
1695
+ for (const [, list] of map) {
1696
+ list.sort((a, b) => (b.priority ?? 0) - (a.priority ?? 0));
1697
+ }
1698
+ return map;
1699
+ }, [contributions]);
1700
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(SlotRegistryContext.Provider, { value: registry, children });
1701
+ };
1702
+ Slot = ({ children, name, fallback, className, style }) => {
1703
+ const slotName = name ?? "";
1704
+ const contributions = useSlotContributions(slotName);
1705
+ const content = contributions.length > 0 ? contributions.map((c, i) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react40.default.Fragment, { children: c.tree }, i)) : children ?? fallback;
1706
+ if (!content) return null;
1707
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1708
+ "div",
1709
+ {
1710
+ className,
1711
+ "data-slot": slotName,
1712
+ style,
1713
+ children: content
1714
+ }
1715
+ );
1716
+ };
1717
+ ModuleOutlet = ({ children, module: moduleName, basePath, className, style }) => {
1718
+ const moduleKey = moduleName ?? "";
1719
+ const contributions = useSlotContributions(`module:${moduleKey}`);
1720
+ if (contributions.length > 0) {
1721
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1722
+ "div",
1723
+ {
1724
+ className,
1725
+ "data-module": moduleKey,
1726
+ style,
1727
+ children: contributions.map((c, i) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react40.default.Fragment, { children: c.tree }, i))
1728
+ }
1729
+ );
1730
+ }
1731
+ if (children) {
1732
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1733
+ "div",
1734
+ {
1735
+ className,
1736
+ "data-module": moduleKey,
1737
+ style,
1738
+ children
1739
+ }
1740
+ );
1741
+ }
1742
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
1743
+ "div",
1744
+ {
1745
+ className,
1746
+ "data-module": moduleKey,
1747
+ style: {
1748
+ padding: 16,
1749
+ border: "1px dashed #cbd5e0",
1750
+ borderRadius: 8,
1751
+ color: "#a0aec0",
1752
+ fontSize: 13,
1753
+ textAlign: "center",
1754
+ ...style
1755
+ },
1756
+ children: [
1757
+ "Module: ",
1758
+ String(moduleName ?? "unknown"),
1759
+ basePath ? /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { children: [
1760
+ " (",
1761
+ String(basePath),
1762
+ ")"
1763
+ ] }) : null
1764
+ ]
1765
+ }
1766
+ );
1767
+ };
1768
+ }
1769
+ });
1770
+
1771
+ // src/player/atoms/data.tsx
1772
+ var data_exports = {};
1773
+ __export(data_exports, {
1774
+ DataGrid: () => DataGrid,
1775
+ Table: () => Table
1776
+ });
1777
+ var import_react41, import_jsx_runtime10, Table, DataGrid;
1778
+ var init_data = __esm({
1779
+ "src/player/atoms/data.tsx"() {
1780
+ "use strict";
1781
+ import_react41 = require("react");
1782
+ import_jsx_runtime10 = require("react/jsx-runtime");
1783
+ Table = ({ data, columns, rows, onRowClick, striped, compact, className, style }) => {
1784
+ const items = Array.isArray(data ?? rows) ? data ?? rows : [];
1785
+ const cols = Array.isArray(columns) ? columns.map(
1786
+ (c) => typeof c === "string" ? { key: c, label: c, header: c } : c
1787
+ ) : items.length > 0 ? Object.keys(items[0]).filter((k) => k !== "id" && !k.startsWith("_")).map((k) => ({ key: k, label: k, header: k })) : [];
1788
+ const pad = compact ? "4px 8px" : "8px 12px";
1789
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className, style: { overflow: "auto", ...style }, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("table", { style: { width: "100%", borderCollapse: "collapse", fontSize: 14 }, children: [
1790
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("tr", { children: cols.map((col, i) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1791
+ "th",
1792
+ {
1793
+ style: {
1794
+ textAlign: "left",
1795
+ padding: pad,
1796
+ fontWeight: 600,
1797
+ fontSize: 12,
1798
+ color: "#718096",
1799
+ borderBottom: "2px solid #e2e8f0",
1800
+ textTransform: "uppercase",
1801
+ letterSpacing: "0.05em"
1802
+ },
1803
+ children: String(col.label ?? col.header ?? col.key ?? "")
1804
+ },
1805
+ String(col.key ?? i)
1806
+ )) }) }),
1807
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("tbody", { children: [
1808
+ items.map((row, ri) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1809
+ "tr",
1810
+ {
1811
+ onClick: typeof onRowClick === "function" ? () => onRowClick(row) : void 0,
1812
+ style: {
1813
+ cursor: typeof onRowClick === "function" ? "pointer" : void 0,
1814
+ background: striped && ri % 2 === 1 ? "#f7fafc" : void 0
1815
+ },
1816
+ children: cols.map((col, ci) => {
1817
+ const val = row[col.key];
1818
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1819
+ "td",
1820
+ {
1821
+ style: { padding: pad, borderBottom: "1px solid #edf2f7" },
1822
+ children: val != null ? String(val) : /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { style: { color: "#cbd5e0" }, children: "\u2014" })
1823
+ },
1824
+ String(col.key ?? ci)
1825
+ );
1826
+ })
1827
+ },
1828
+ String(row.id ?? ri)
1829
+ )),
1830
+ items.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("tr", { children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1831
+ "td",
1832
+ {
1833
+ colSpan: cols.length,
1834
+ style: { padding: "24px 12px", textAlign: "center", color: "#a0aec0", fontStyle: "italic" },
1835
+ children: "No data"
1836
+ }
1837
+ ) }) : null
1838
+ ] })
1839
+ ] }) });
1840
+ };
1841
+ DataGrid = ({ data, columns, onRowClick, searchable, className, style, children }) => {
1842
+ const [search, setSearch] = (0, import_react41.useState)("");
1843
+ const items = Array.isArray(data) ? data : [];
1844
+ const filtered = (0, import_react41.useMemo)(() => {
1845
+ if (!search) return items;
1846
+ const q = search.toLowerCase();
1847
+ return items.filter(
1848
+ (item) => Object.values(item).some((v) => v != null && String(v).toLowerCase().includes(q))
1849
+ );
1850
+ }, [items, search]);
1851
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className, style, children: [
1852
+ searchable ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { style: { marginBottom: 12 }, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1853
+ "input",
1854
+ {
1855
+ type: "text",
1856
+ placeholder: "Search...",
1857
+ value: search,
1858
+ onChange: (e) => setSearch(e.target.value),
1859
+ style: {
1860
+ padding: "6px 12px",
1861
+ border: "1px solid #e2e8f0",
1862
+ borderRadius: 6,
1863
+ fontSize: 14,
1864
+ width: "100%",
1865
+ boxSizing: "border-box"
1866
+ }
1867
+ }
1868
+ ) }) : null,
1869
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Table, { data: filtered, columns, onRowClick, striped: true }),
1870
+ children
1871
+ ] });
1872
+ };
1873
+ }
1874
+ });
1875
+
1876
+ // src/index.ts
1877
+ var index_exports = {};
1878
+ __export(index_exports, {
1879
+ Accordion: () => Accordion3,
1880
+ AnimatedBox: () => AnimatedBox,
1881
+ AtomRegistryImpl: () => AtomRegistryImpl,
1882
+ BUILT_IN_CONSTRAINTS: () => BUILT_IN_CONSTRAINTS,
1883
+ Badge: () => Badge3,
1884
+ Blueprint: () => Blueprint,
1885
+ BrowserPlayer: () => BrowserPlayer,
1886
+ Button: () => Button3,
1887
+ Canvas3D: () => Canvas3D,
1888
+ Card: () => Card3,
1889
+ Chart: () => Chart,
1890
+ Column: () => Column3,
1891
+ ComponentTreeRenderer: () => ComponentTreeRenderer,
1892
+ DataGrid: () => DataGrid2,
1893
+ DevPlayer: () => DevPlayer,
1894
+ Divider: () => Divider3,
1895
+ Each: () => Each3,
1896
+ ExperienceRenderer: () => ExperienceRenderer,
1897
+ ExperienceWorkflowBridge: () => ExperienceWorkflowBridge,
1898
+ Field: () => Field3,
1899
+ FieldBuilder: () => FieldBuilder,
1900
+ Grid: () => Grid3,
1901
+ Heading: () => Heading3,
1902
+ Icon: () => Icon3,
1903
+ Image: () => Image2,
1904
+ Link: () => Link2,
1905
+ LocalEngineProvider: () => LocalEngineProvider,
1906
+ LocalWorkflowEngine: () => LocalWorkflowEngine,
1907
+ Markdown: () => Markdown3,
1908
+ MetricCard: () => MetricCard,
1909
+ Modal: () => Modal3,
1910
+ ModelBuilder: () => ModelBuilder,
1911
+ NavLink: () => NavLink3,
1912
+ ORCHESTRATION_PRESETS: () => ORCHESTRATION_PRESETS,
1913
+ PlayerProvider: () => PlayerProvider,
1914
+ RoleGuard: () => RoleGuard3,
1915
+ Route: () => Route3,
1916
+ Router: () => Router3,
1917
+ Row: () => Row3,
1918
+ RuntimeContext: () => RuntimeContext,
1919
+ ScopeContext: () => ScopeContext,
1920
+ ScrollArea: () => ScrollArea3,
1921
+ Section: () => Section3,
1922
+ Select: () => Select2,
1923
+ ServerGrid: () => ServerGrid,
1924
+ Show: () => Show3,
1925
+ Slot: () => Slot3,
1926
+ Spacer: () => Spacer3,
1927
+ Stack: () => Stack3,
1928
+ StateBuilder: () => StateBuilder,
1929
+ Tabs: () => Tabs3,
1930
+ Text: () => Text3,
1931
+ TextInput: () => TextInput3,
1932
+ TransitionBuilder: () => TransitionBuilder,
1933
+ TypedTransitionBuilder: () => TypedTransitionBuilder,
1934
+ WorkflowProvider: () => WorkflowProvider,
1935
+ WorkflowRuntime: () => WorkflowRuntime,
1936
+ action: () => action,
1937
+ actor: () => actor,
1938
+ after: () => after,
1939
+ allowTransition: () => allowTransition,
1940
+ and: () => and,
1941
+ applyMixins: () => applyMixins,
1942
+ approval: () => approval,
1943
+ assertModelValid: () => assertModelValid,
1944
+ buildActionScope: () => buildActionScope,
1945
+ buildEvalContext: () => buildEvalContext,
1946
+ buildLoopScope: () => buildLoopScope,
1947
+ buildScope: () => buildScope,
1948
+ builtinAtoms: () => builtinAtoms,
1949
+ builtinFunctions: () => builtinFunctions,
1950
+ cedar: () => cedar,
1951
+ compose: () => compose,
1952
+ computeVisibility: () => computeVisibility,
1953
+ configureActor: () => configureActor,
1954
+ connector: () => connector,
1955
+ constraints: () => constraints,
1956
+ createActions: () => createActions,
1957
+ createApiResolver: () => createApiResolver,
1958
+ createCRUD: () => createCRUD,
1959
+ createCoreAtomRegistry: () => createCoreAtomRegistry,
1960
+ createLocalDataResolver: () => createLocalDataResolver,
1961
+ createLocalEngineAdapter: () => createLocalEngineAdapter,
1962
+ createPipeline: () => createPipeline,
1963
+ cron: () => cron,
1964
+ crud: () => crud,
1965
+ defineBlueprint: () => defineBlueprint,
1966
+ defineImperativeBlueprint: () => blueprint,
1967
+ defineMiddleware: () => defineMiddleware,
1968
+ defineModel: () => defineModel,
1969
+ defineModule: () => defineModule,
1970
+ defineRoles: () => defineRoles,
1971
+ defineWorkspace: () => defineWorkspace,
1972
+ delay: () => delay,
1973
+ deriveInstanceKey: () => deriveInstanceKey,
1974
+ deriveInstanceKeySync: () => deriveInstanceKeySync,
1975
+ describeModel: () => describeModel,
1976
+ deviceAction: () => deviceAction,
1977
+ dmn: () => dmn,
1978
+ editableBy: () => editableBy,
1979
+ editableIn: () => editableIn,
1980
+ emit: () => emit,
1981
+ escalation: () => escalation,
1982
+ every: () => every,
1983
+ expr: () => expr,
1984
+ extend: () => extend,
1985
+ extendMiddleware: () => extendMiddleware,
1986
+ field: () => field,
1987
+ fieldContains: () => fieldContains,
1988
+ fieldEquals: () => fieldEquals,
1989
+ fieldGreaterThan: () => fieldGreaterThan,
1990
+ fieldIn: () => fieldIn,
1991
+ fieldIsEmpty: () => fieldIsEmpty,
1992
+ fieldIsSet: () => fieldIsSet,
1993
+ fieldLessThan: () => fieldLessThan,
1994
+ fieldMatches: () => fieldMatches,
1995
+ fieldNotEquals: () => fieldNotEquals,
1996
+ fieldNotIn: () => fieldNotIn,
1997
+ getInstalledModule: () => getInstalledModule,
1998
+ getInstalledModules: () => getInstalledModules,
1999
+ graphql: () => graphql,
2000
+ guard: () => guard,
2001
+ hasAnyRole: () => hasAnyRole,
2002
+ hasRole: () => hasRole,
2003
+ imperativeCron: () => cron2,
2004
+ imperativeLog: () => log,
2005
+ imperativeNotify: () => notify2,
2006
+ imperativeRequireRole: () => requireRole2,
2007
+ inState: () => inState,
2008
+ inputEquals: () => inputEquals,
2009
+ inputRequired: () => inputRequired,
2010
+ instance: () => instance,
2011
+ isActor: () => isActor,
2012
+ isActorConfig: () => isActorConfig,
2013
+ isBuiltInConstraint: () => isBuiltInConstraint,
2014
+ isConstraintDeclaration: () => isConstraintDeclaration,
159
2015
  isCreator: () => isCreator,
160
2016
  isOwner: () => isOwner,
161
2017
  isPlayerDebug: () => isPlayerDebug,
@@ -164,6 +2020,8 @@ __export(index_exports, {
164
2020
  llm: () => llm,
165
2021
  loadExperienceWorkflow: () => loadExperienceWorkflow,
166
2022
  logEvent: () => logEvent,
2023
+ mergeRegistries: () => mergeRegistries,
2024
+ mergeScope: () => mergeScope,
167
2025
  model: () => model,
168
2026
  named: () => named,
169
2027
  normalizeDefinition: () => normalizeDefinition,
@@ -175,6 +2033,7 @@ __export(index_exports, {
175
2033
  orchestration: () => orchestration,
176
2034
  patch: () => patch,
177
2035
  pipe: () => pipe,
2036
+ playerEvaluateExpression: () => evaluateExpression,
178
2037
  playerLog: () => playerLog,
179
2038
  prefetchData: () => prefetchData,
180
2039
  refHasAnyRole: () => refHasAnyRole,
@@ -182,6 +2041,8 @@ __export(index_exports, {
182
2041
  requireAuth: () => requireAuth,
183
2042
  requireField: () => requireField,
184
2043
  requireRole: () => requireRole,
2044
+ resolveAllBindings: () => resolveAllBindings,
2045
+ resolveBinding: () => resolveBinding,
185
2046
  resolveOrchestration: () => resolveOrchestration,
186
2047
  restrict: () => restrict,
187
2048
  review: () => review,
@@ -251,6 +2112,7 @@ __export(index_exports, {
251
2112
  useRouteParams: () => useRouteParams,
252
2113
  useRouter: () => useRouter,
253
2114
  useRuntimeContext: () => useRuntimeContext,
2115
+ useScope: () => useScope,
254
2116
  useServerAction: () => useServerAction,
255
2117
  useServerState: () => useServerState,
256
2118
  useStateField: () => useStateField,
@@ -260,7 +2122,7 @@ __export(index_exports, {
260
2122
  useVisibility: () => useVisibility,
261
2123
  useWhileIn: () => useWhileIn,
262
2124
  useWorkflow: () => useWorkflow,
263
- useWorkflowState: () => useState22,
2125
+ useWorkflowState: () => useState28,
264
2126
  userAction: () => userAction,
265
2127
  userChoice: () => userChoice,
266
2128
  validate: () => validate,
@@ -3594,7 +5456,7 @@ function defineBlueprint(config) {
3594
5456
  ...config,
3595
5457
  mode: config.mode || "infer",
3596
5458
  defaultRuntime: config.defaultRuntime || "local",
3597
- category: config.category || "blueprint"
5459
+ category: config.category ? Array.isArray(config.category) ? config.category : [config.category] : ["blueprint"]
3598
5460
  };
3599
5461
  }
3600
5462
  function defineModule(manifest) {
@@ -3659,271 +5521,1343 @@ function fieldIsSet(field2) {
3659
5521
  function fieldIsEmpty(field2) {
3660
5522
  return { type: "field", field: field2, operator: "is_empty" };
3661
5523
  }
3662
- function fieldMatches(field2, pattern) {
3663
- return { type: "field", field: field2, operator: "matches", value: pattern };
5524
+ function fieldMatches(field2, pattern) {
5525
+ return { type: "field", field: field2, operator: "matches", value: pattern };
5526
+ }
5527
+ function inputRequired(...fields) {
5528
+ const conditions = fields.map((f) => ({
5529
+ type: "expression",
5530
+ expression: `input.${f} != null && LEN(input.${f}) > 0`
5531
+ }));
5532
+ if (conditions.length === 1) {
5533
+ return conditions[0];
5534
+ }
5535
+ return { AND: conditions };
5536
+ }
5537
+ function inputEquals(field2, value) {
5538
+ const formatted = typeof value === "string" ? `"${value}"` : String(value);
5539
+ return { type: "expression", expression: `input.${field2} == ${formatted}` };
5540
+ }
5541
+ function inState(state2) {
5542
+ return { type: "expression", expression: `current_state == "${state2}"` };
5543
+ }
5544
+ function notInState(state2) {
5545
+ return { type: "expression", expression: `current_state != "${state2}"` };
5546
+ }
5547
+ function and(...conditions) {
5548
+ return { AND: conditions.map(normalize) };
5549
+ }
5550
+ function or(...conditions) {
5551
+ return { OR: conditions.map(normalize) };
5552
+ }
5553
+ function not(condition) {
5554
+ const c = normalize(condition);
5555
+ if (c.type === "expression" && c.expression) {
5556
+ return { type: "expression", expression: `NOT(${c.expression})` };
5557
+ }
5558
+ if (c.type === "role" && c.role) {
5559
+ return { type: "expression", expression: `NOT(context.roles CONTAINS "${c.role}")` };
5560
+ }
5561
+ if (c.type === "field" && c.field) {
5562
+ const invertedOps = {
5563
+ eq: "ne",
5564
+ ne: "eq",
5565
+ gt: "lte",
5566
+ gte: "lt",
5567
+ lt: "gte",
5568
+ lte: "gt",
5569
+ in: "not_in",
5570
+ not_in: "in",
5571
+ is_set: "is_empty",
5572
+ is_empty: "is_set"
5573
+ };
5574
+ const op = c.operator ?? "eq";
5575
+ const inverted = invertedOps[op];
5576
+ if (inverted) {
5577
+ return { type: "field", field: c.field, operator: inverted, value: c.value };
5578
+ }
5579
+ return { type: "expression", expression: `NOT(state_data.${c.field} ${op.toUpperCase()} ${JSON.stringify(c.value)})` };
5580
+ }
5581
+ return { type: "expression", expression: `NOT(true)` };
5582
+ }
5583
+ function refHasRole(slug, lookupField, lookupValue, role) {
5584
+ return {
5585
+ type: "expression",
5586
+ expression: `$ref("${slug}", "${lookupField}", ${lookupValue}).role == "${role}"`
5587
+ };
5588
+ }
5589
+ function refHasAnyRole(slug, lookupField, lookupValue, roles) {
5590
+ const roleList = roles.map((r) => `"${r}"`).join(", ");
5591
+ return {
5592
+ type: "expression",
5593
+ expression: `$ref("${slug}", "${lookupField}", ${lookupValue}).role IN [${roleList}]`
5594
+ };
5595
+ }
5596
+
5597
+ // src/hooks/useModel.ts
5598
+ var import_react34 = require("react");
5599
+ function getDefaultFields(definition) {
5600
+ const defaults = {};
5601
+ for (const [key, field2] of Object.entries(definition.fields)) {
5602
+ if (field2.default !== void 0) {
5603
+ defaults[key] = field2.default;
5604
+ } else {
5605
+ switch (field2.type) {
5606
+ case "string":
5607
+ case "text":
5608
+ case "email":
5609
+ case "url":
5610
+ case "phone":
5611
+ case "color":
5612
+ case "select":
5613
+ case "rich_text":
5614
+ defaults[key] = "";
5615
+ break;
5616
+ case "number":
5617
+ case "integer":
5618
+ case "float":
5619
+ case "currency":
5620
+ case "percentage":
5621
+ case "rating":
5622
+ case "duration":
5623
+ defaults[key] = 0;
5624
+ break;
5625
+ case "boolean":
5626
+ defaults[key] = false;
5627
+ break;
5628
+ case "array":
5629
+ defaults[key] = [];
5630
+ break;
5631
+ case "object":
5632
+ case "json":
5633
+ defaults[key] = {};
5634
+ break;
5635
+ default:
5636
+ defaults[key] = void 0;
5637
+ }
5638
+ }
5639
+ }
5640
+ return defaults;
5641
+ }
5642
+ function useModel(definition, options = {}) {
5643
+ const slug = definition.slug;
5644
+ const queryParams = {
5645
+ limit: 1,
5646
+ enabled: options.enabled,
5647
+ refetchInterval: options.refetchInterval
5648
+ };
5649
+ if (options.filter) queryParams.filter = options.filter;
5650
+ if (options.state) queryParams.state = options.state;
5651
+ const query = useQuery(slug, queryParams);
5652
+ const mutation = useMutation(slug);
5653
+ const instance2 = query.data?.[0];
5654
+ const instanceId = instance2?.id ?? null;
5655
+ const currentState = instance2?.currentState ?? "";
5656
+ const instanceFields = instance2?.fields ?? null;
5657
+ const defaultFields = (0, import_react34.useMemo)(() => getDefaultFields(definition), [definition]);
5658
+ const fields = (0, import_react34.useMemo)(() => {
5659
+ if (!instanceFields) return defaultFields;
5660
+ return { ...defaultFields, ...instanceFields };
5661
+ }, [instanceFields, defaultFields]);
5662
+ const instanceIdRef = (0, import_react34.useRef)(instanceId);
5663
+ instanceIdRef.current = instanceId;
5664
+ const trigger = (0, import_react34.useCallback)(async (name, input) => {
5665
+ const id = instanceIdRef.current;
5666
+ if (!id) {
5667
+ throw new Error(`useModel(${slug}): No instance loaded. Cannot trigger '${name}'.`);
5668
+ }
5669
+ await mutation.transition(id, name, input);
5670
+ await query.refetch();
5671
+ }, [slug, mutation, query]);
5672
+ const create = (0, import_react34.useCallback)(async (input) => {
5673
+ const id = await mutation.create(input);
5674
+ await query.refetch();
5675
+ return id;
5676
+ }, [mutation, query]);
5677
+ const update = (0, import_react34.useCallback)(async (fieldUpdates) => {
5678
+ const id = instanceIdRef.current;
5679
+ if (!id) {
5680
+ throw new Error(`useModel(${slug}): No instance loaded. Cannot update.`);
5681
+ }
5682
+ await mutation.update(id, fieldUpdates);
5683
+ await query.refetch();
5684
+ }, [slug, mutation, query]);
5685
+ const handle = {
5686
+ fields,
5687
+ state: currentState,
5688
+ instanceId,
5689
+ trigger,
5690
+ transition: trigger,
5691
+ create,
5692
+ update,
5693
+ loading: query.loading,
5694
+ error: query.error ?? mutation.error,
5695
+ refetch: query.refetch,
5696
+ isPending: mutation.isPending,
5697
+ reset: mutation.reset,
5698
+ raw: { data: query.data, total: query.total }
5699
+ };
5700
+ return handle;
5701
+ }
5702
+ function useCollection(definition, options = {}) {
5703
+ const slug = definition.slug;
5704
+ const query = useQuery(slug, options);
5705
+ const mutation = useMutation(slug);
5706
+ const items = (0, import_react34.useMemo)(() => {
5707
+ return (query.data || []).map((instance2) => ({
5708
+ id: instance2.id,
5709
+ fields: instance2.fields ?? {},
5710
+ state: instance2.currentState ?? ""
5711
+ }));
5712
+ }, [query.data]);
5713
+ const trigger = (0, import_react34.useCallback)(async (instanceId, name, input) => {
5714
+ await mutation.transition(instanceId, name, input);
5715
+ await query.refetch();
5716
+ }, [mutation, query]);
5717
+ const create = (0, import_react34.useCallback)(async (input) => {
5718
+ const id = await mutation.create(input);
5719
+ await query.refetch();
5720
+ return id;
5721
+ }, [mutation, query]);
5722
+ const update = (0, import_react34.useCallback)(async (instanceId, fieldUpdates) => {
5723
+ await mutation.update(instanceId, fieldUpdates);
5724
+ await query.refetch();
5725
+ }, [mutation, query]);
5726
+ const remove = (0, import_react34.useCallback)(async (instanceId) => {
5727
+ await mutation.remove(instanceId);
5728
+ await query.refetch();
5729
+ }, [mutation, query]);
5730
+ const handle = {
5731
+ items,
5732
+ total: query.total ?? items.length,
5733
+ loading: query.loading,
5734
+ error: query.error ?? mutation.error,
5735
+ refetch: query.refetch,
5736
+ hasMore: query.hasMore ?? false,
5737
+ trigger,
5738
+ create,
5739
+ update,
5740
+ remove,
5741
+ isPending: mutation.isPending
5742
+ };
5743
+ return handle;
5744
+ }
5745
+
5746
+ // src/player/ExperienceRenderer.tsx
5747
+ var import_react44 = __toESM(require("react"));
5748
+ init_scope_builder();
5749
+
5750
+ // src/player/binding-resolver.ts
5751
+ init_expression_engine();
5752
+ function classifyBinding(expr2) {
5753
+ const t = expr2.trim();
5754
+ const type = classifyExpression(t);
5755
+ switch (type) {
5756
+ case "literal":
5757
+ return { type, value: parseLiteralValue(t) };
5758
+ case "path": {
5759
+ const dotIdx = t.indexOf(".");
5760
+ if (dotIdx === -1) return { type, root: t, rest: "" };
5761
+ return { type, root: t.slice(0, dotIdx), rest: t.slice(dotIdx + 1) };
5762
+ }
5763
+ case "function": {
5764
+ const fnCall = parseFunctionCall(t);
5765
+ if (fnCall) return { type, name: fnCall.name, rawArgs: fnCall.args };
5766
+ return { type, expression: t };
5767
+ }
5768
+ case "action": {
5769
+ const fnCall = parseFunctionCall(t);
5770
+ if (fnCall) return { type, name: fnCall.name, rawArgs: fnCall.args };
5771
+ if (t.startsWith("$action.")) return { type, name: t.slice("$action.".length), rawArgs: [] };
5772
+ return { type, expression: t };
5773
+ }
5774
+ case "condition":
5775
+ if (t.startsWith("$expr(") && t.endsWith(")")) return { type, expression: t.slice(6, -1) };
5776
+ return { type, expression: t };
5777
+ }
5778
+ }
5779
+ function parseLiteralValue(t) {
5780
+ if (t === "[Expression]" || t.includes("[Expression]")) return void 0;
5781
+ if (t.startsWith('"') && t.endsWith('"') || t.startsWith("'") && t.endsWith("'")) return t.slice(1, -1);
5782
+ if (/^-?\d+(\.\d+)?$/.test(t)) return Number(t);
5783
+ if (t === "true") return true;
5784
+ if (t === "false") return false;
5785
+ if (t === "null") return null;
5786
+ return void 0;
5787
+ }
5788
+ function parseFunctionCall(expr2) {
5789
+ const match = expr2.match(/^\$(fn|action)\.(\w+)\((.*)\)$/s);
5790
+ if (!match) return null;
5791
+ const [, namespace, name, argsStr] = match;
5792
+ const args = argsStr.trim() ? splitArgs(argsStr.trim()) : [];
5793
+ return { namespace, name, args };
5794
+ }
5795
+ function splitArgs(argsStr) {
5796
+ const args = [];
5797
+ let current = "";
5798
+ let depth = 0;
5799
+ let inString = null;
5800
+ for (let i = 0; i < argsStr.length; i++) {
5801
+ const ch = argsStr[i];
5802
+ if (inString) {
5803
+ current += ch;
5804
+ if (ch === inString && argsStr[i - 1] !== "\\") inString = null;
5805
+ } else if (ch === '"' || ch === "'") {
5806
+ current += ch;
5807
+ inString = ch;
5808
+ } else if (ch === "(" || ch === "[") {
5809
+ current += ch;
5810
+ depth++;
5811
+ } else if (ch === ")" || ch === "]") {
5812
+ current += ch;
5813
+ depth--;
5814
+ } else if (ch === "," && depth === 0) {
5815
+ args.push(current.trim());
5816
+ current = "";
5817
+ } else {
5818
+ current += ch;
5819
+ }
5820
+ }
5821
+ if (current.trim()) args.push(current.trim());
5822
+ return args;
5823
+ }
5824
+ function resolveBinding(expr2, scope) {
5825
+ const binding = classifyBinding(expr2);
5826
+ switch (binding.type) {
5827
+ case "literal":
5828
+ return binding.value;
5829
+ case "path":
5830
+ return resolveScopedPath(binding.root, binding.rest, scope);
5831
+ case "function":
5832
+ return resolveFunction(binding.name, binding.rawArgs, scope);
5833
+ case "action":
5834
+ return resolveAction(binding.name, binding.rawArgs, scope);
5835
+ case "condition":
5836
+ return resolveCondition(binding.expression ?? expr2, scope);
5837
+ default:
5838
+ return void 0;
5839
+ }
5840
+ }
5841
+ function resolveAllBindings(bindings, scope) {
5842
+ const resolved = {};
5843
+ for (const [propName, expr2] of Object.entries(bindings)) {
5844
+ try {
5845
+ resolved[propName] = resolveBinding(expr2, scope);
5846
+ } catch {
5847
+ resolved[propName] = void 0;
5848
+ }
5849
+ }
5850
+ return resolved;
3664
5851
  }
3665
- function inputRequired(...fields) {
3666
- const conditions = fields.map((f) => ({
3667
- type: "expression",
3668
- expression: `input.${f} != null && LEN(input.${f}) > 0`
3669
- }));
3670
- if (conditions.length === 1) {
3671
- return conditions[0];
5852
+ function resolveScopedPath(root, rest, scope) {
5853
+ let rootValue;
5854
+ switch (root) {
5855
+ case "$instance":
5856
+ rootValue = scope.$instance;
5857
+ break;
5858
+ case "$instances":
5859
+ rootValue = scope.$instances;
5860
+ break;
5861
+ case "$definition":
5862
+ rootValue = scope.$definition;
5863
+ break;
5864
+ case "$pagination":
5865
+ rootValue = scope.$pagination;
5866
+ break;
5867
+ case "$entity":
5868
+ rootValue = scope.$entity;
5869
+ break;
5870
+ case "$local":
5871
+ rootValue = scope.$local;
5872
+ break;
5873
+ case "$user":
5874
+ rootValue = scope.$user;
5875
+ break;
5876
+ case "$action":
5877
+ rootValue = scope.$action;
5878
+ break;
5879
+ case "$fn":
5880
+ rootValue = scope.$fn;
5881
+ break;
5882
+ case "$item":
5883
+ rootValue = scope.$item;
5884
+ break;
5885
+ case "$index":
5886
+ rootValue = scope.$index;
5887
+ break;
5888
+ default:
5889
+ rootValue = scope[root];
5890
+ if (rootValue === void 0) {
5891
+ rootValue = scope.$item;
5892
+ if (rootValue != null && rest) {
5893
+ return resolvePath(`${root}.${rest}`, { [root]: scope.$item });
5894
+ }
5895
+ }
3672
5896
  }
3673
- return { AND: conditions };
5897
+ if (!rest) return rootValue;
5898
+ if (rootValue == null) return void 0;
5899
+ return resolvePath(rest, rootValue);
3674
5900
  }
3675
- function inputEquals(field2, value) {
3676
- const formatted = typeof value === "string" ? `"${value}"` : String(value);
3677
- return { type: "expression", expression: `input.${field2} == ${formatted}` };
5901
+ function resolveFunction(name, rawArgs, scope) {
5902
+ const fn = scope.$fn?.[name] ?? builtinFunctions[name];
5903
+ if (typeof fn !== "function") {
5904
+ console.warn(`[binding-resolver] Unknown function: $fn.${name}`);
5905
+ return void 0;
5906
+ }
5907
+ const resolvedArgs = rawArgs.map((arg) => resolveBinding(arg.trim(), scope));
5908
+ try {
5909
+ return fn(...resolvedArgs);
5910
+ } catch (err) {
5911
+ console.warn(`[binding-resolver] Error calling $fn.${name}:`, err);
5912
+ return void 0;
5913
+ }
5914
+ }
5915
+ function resolveAction(name, rawArgs, scope) {
5916
+ const actions = scope.$action;
5917
+ if (!actions) return void 0;
5918
+ if (rawArgs.length === 0) {
5919
+ const actionFn2 = actions[name];
5920
+ if (typeof actionFn2 === "function") return actionFn2;
5921
+ return void 0;
5922
+ }
5923
+ const actionFn = actions[name];
5924
+ if (typeof actionFn !== "function") return void 0;
5925
+ return (...callArgs) => {
5926
+ const resolvedArgs = rawArgs.map((arg) => resolveBinding(arg.trim(), scope));
5927
+ return actionFn(...resolvedArgs, ...callArgs);
5928
+ };
3678
5929
  }
3679
- function inState(state2) {
3680
- return { type: "expression", expression: `current_state == "${state2}"` };
5930
+ function resolveCondition(expression, scope) {
5931
+ const context = buildEvalContext(scope);
5932
+ return evaluateExpression(expression, context);
5933
+ }
5934
+ function buildEvalContext(scope) {
5935
+ const ctx = {};
5936
+ ctx.$instance = scope.$instance;
5937
+ ctx.$instances = scope.$instances;
5938
+ ctx.$definition = scope.$definition;
5939
+ ctx.$pagination = scope.$pagination;
5940
+ ctx.$entity = scope.$entity;
5941
+ ctx.$local = scope.$local;
5942
+ ctx.$user = scope.$user;
5943
+ ctx.$action = scope.$action;
5944
+ ctx.$fn = scope.$fn;
5945
+ ctx.$item = scope.$item;
5946
+ ctx.$index = scope.$index;
5947
+ if (scope.$instances) ctx.items = scope.$instances;
5948
+ if (scope.$instance) {
5949
+ ctx.instance = scope.$instance;
5950
+ ctx.loading = false;
5951
+ }
5952
+ if (scope.$item) ctx.item = scope.$item;
5953
+ if (scope.$index != null) ctx.index = scope.$index;
5954
+ if (scope.state_data) ctx.state_data = scope.state_data;
5955
+ if (scope.memory) ctx.memory = scope.memory;
5956
+ if (scope.context) ctx.context = scope.context;
5957
+ return ctx;
3681
5958
  }
3682
- function notInState(state2) {
3683
- return { type: "expression", expression: `current_state != "${state2}"` };
5959
+ function buildActionScope(opts) {
5960
+ const { resolver, instanceId, slug, setLocal, router, toast, refreshQuery, onEvent } = opts;
5961
+ return {
5962
+ transition: async (name, id, data) => {
5963
+ const targetId = id ?? instanceId;
5964
+ if (!targetId) {
5965
+ console.warn("[action] transition called without instanceId");
5966
+ return;
5967
+ }
5968
+ await resolver.transition(targetId, name, data);
5969
+ refreshQuery?.();
5970
+ },
5971
+ create: async (targetSlug, data) => {
5972
+ const id = await resolver.create(targetSlug || slug || "", data);
5973
+ refreshQuery?.();
5974
+ return id;
5975
+ },
5976
+ update: async (id, fields) => {
5977
+ await resolver.update(id, fields);
5978
+ refreshQuery?.();
5979
+ },
5980
+ remove: async (id) => {
5981
+ await resolver.remove(id);
5982
+ refreshQuery?.();
5983
+ },
5984
+ setLocal: (key, value) => {
5985
+ setLocal(key, value);
5986
+ },
5987
+ navigate: (path) => {
5988
+ router?.push(path);
5989
+ },
5990
+ toast: (message, variant) => {
5991
+ toast?.(message, variant);
5992
+ },
5993
+ refreshQuery: (dataSourceName) => {
5994
+ refreshQuery?.(dataSourceName);
5995
+ },
5996
+ scrollTo: (elementId) => {
5997
+ if (typeof document !== "undefined") {
5998
+ const el = document.getElementById(elementId);
5999
+ el?.scrollIntoView({ behavior: "smooth" });
6000
+ }
6001
+ },
6002
+ openModal: (modalId) => {
6003
+ if (typeof window !== "undefined") {
6004
+ window.dispatchEvent(new CustomEvent("player:open_modal", { detail: { id: modalId } }));
6005
+ }
6006
+ },
6007
+ closeModal: (modalId) => {
6008
+ if (typeof window !== "undefined") {
6009
+ window.dispatchEvent(new CustomEvent("player:close_modal", { detail: { id: modalId } }));
6010
+ }
6011
+ },
6012
+ emit: (event, payload) => {
6013
+ onEvent?.(event, payload);
6014
+ }
6015
+ };
3684
6016
  }
3685
- function and(...conditions) {
3686
- return { AND: conditions.map(normalize) };
6017
+
6018
+ // src/player/ExperienceRenderer.tsx
6019
+ init_expression_engine();
6020
+
6021
+ // src/player/PlayerProvider.tsx
6022
+ var import_react43 = require("react");
6023
+
6024
+ // src/player/atom-registry.ts
6025
+ var import_react42 = __toESM(require("react"));
6026
+ function namedExport(loader, exportName) {
6027
+ return () => loader().then((mod) => ({ default: mod[exportName] }));
6028
+ }
6029
+ var AtomRegistryImpl = class _AtomRegistryImpl {
6030
+ loaders = /* @__PURE__ */ new Map();
6031
+ lazyCache = /* @__PURE__ */ new Map();
6032
+ eagerCache = /* @__PURE__ */ new Map();
6033
+ register(name, loader) {
6034
+ this.loaders.set(name, loader);
6035
+ this.lazyCache.delete(name);
6036
+ }
6037
+ registerEager(name, component) {
6038
+ this.eagerCache.set(name, component);
6039
+ }
6040
+ resolve(name) {
6041
+ const eager = this.eagerCache.get(name);
6042
+ if (eager) {
6043
+ const cached2 = this.lazyCache.get(name);
6044
+ if (cached2) return cached2;
6045
+ const lazy2 = import_react42.default.lazy(() => Promise.resolve({ default: eager }));
6046
+ this.lazyCache.set(name, lazy2);
6047
+ return lazy2;
6048
+ }
6049
+ const cached = this.lazyCache.get(name);
6050
+ if (cached) return cached;
6051
+ const loader = this.loaders.get(name);
6052
+ if (!loader) return null;
6053
+ const lazy = import_react42.default.lazy(loader);
6054
+ this.lazyCache.set(name, lazy);
6055
+ return lazy;
6056
+ }
6057
+ resolveSync(name) {
6058
+ return this.eagerCache.get(name) ?? null;
6059
+ }
6060
+ has(name) {
6061
+ return this.loaders.has(name) || this.eagerCache.has(name);
6062
+ }
6063
+ list() {
6064
+ const names = /* @__PURE__ */ new Set();
6065
+ for (const k of this.loaders.keys()) names.add(k);
6066
+ for (const k of this.eagerCache.keys()) names.add(k);
6067
+ return Array.from(names).sort();
6068
+ }
6069
+ merge(other) {
6070
+ const merged = new _AtomRegistryImpl();
6071
+ for (const [name, loader] of this.loaders) merged.loaders.set(name, loader);
6072
+ for (const [name, comp] of this.eagerCache) merged.eagerCache.set(name, comp);
6073
+ for (const name of other.list()) {
6074
+ const otherImpl = other;
6075
+ if (otherImpl.loaders?.has(name)) {
6076
+ merged.loaders.set(name, otherImpl.loaders.get(name));
6077
+ }
6078
+ if (otherImpl.eagerCache?.has(name)) {
6079
+ merged.eagerCache.set(name, otherImpl.eagerCache.get(name));
6080
+ }
6081
+ }
6082
+ return merged;
6083
+ }
6084
+ toRecord() {
6085
+ const record = {};
6086
+ for (const name of this.eagerCache.keys()) {
6087
+ record[name] = this.eagerCache.get(name);
6088
+ }
6089
+ return record;
6090
+ }
6091
+ };
6092
+ function createCoreAtomRegistry() {
6093
+ const registry = new AtomRegistryImpl();
6094
+ registry.register("Stack", namedExport(() => Promise.resolve().then(() => (init_layout(), layout_exports)), "Stack"));
6095
+ registry.register("Row", namedExport(() => Promise.resolve().then(() => (init_layout(), layout_exports)), "Row"));
6096
+ registry.register("Grid", namedExport(() => Promise.resolve().then(() => (init_layout(), layout_exports)), "Grid"));
6097
+ registry.register("Column", namedExport(() => Promise.resolve().then(() => (init_layout(), layout_exports)), "Column"));
6098
+ registry.register("Divider", namedExport(() => Promise.resolve().then(() => (init_layout(), layout_exports)), "Divider"));
6099
+ registry.register("Spacer", namedExport(() => Promise.resolve().then(() => (init_layout(), layout_exports)), "Spacer"));
6100
+ registry.register("Text", namedExport(() => Promise.resolve().then(() => (init_content(), content_exports)), "Text"));
6101
+ registry.register("Heading", namedExport(() => Promise.resolve().then(() => (init_content(), content_exports)), "Heading"));
6102
+ registry.register("Field", namedExport(() => Promise.resolve().then(() => (init_content(), content_exports)), "Field"));
6103
+ registry.register("Image", namedExport(() => Promise.resolve().then(() => (init_content(), content_exports)), "Image"));
6104
+ registry.register("Badge", namedExport(() => Promise.resolve().then(() => (init_content(), content_exports)), "Badge"));
6105
+ registry.register("Icon", namedExport(() => Promise.resolve().then(() => (init_content(), content_exports)), "Icon"));
6106
+ registry.register("Button", namedExport(() => Promise.resolve().then(() => (init_actions(), actions_exports)), "Button"));
6107
+ registry.register("Link", namedExport(() => Promise.resolve().then(() => (init_actions(), actions_exports)), "Link"));
6108
+ registry.register("Show", namedExport(() => Promise.resolve().then(() => (init_control_flow(), control_flow_exports)), "Show"));
6109
+ registry.register("Each", namedExport(() => Promise.resolve().then(() => (init_control_flow(), control_flow_exports)), "Each"));
6110
+ registry.register("TextInput", namedExport(() => Promise.resolve().then(() => (init_input(), input_exports)), "TextInput"));
6111
+ registry.register("Input", namedExport(() => Promise.resolve().then(() => (init_input(), input_exports)), "TextInput"));
6112
+ registry.register("Select", namedExport(() => Promise.resolve().then(() => (init_input(), input_exports)), "Select"));
6113
+ registry.register("Toggle", namedExport(() => Promise.resolve().then(() => (init_input(), input_exports)), "Toggle"));
6114
+ registry.register("Slider", namedExport(() => Promise.resolve().then(() => (init_input(), input_exports)), "Slider"));
6115
+ registry.register("Card", namedExport(() => Promise.resolve().then(() => (init_grouping(), grouping_exports)), "Card"));
6116
+ registry.register("Section", namedExport(() => Promise.resolve().then(() => (init_grouping(), grouping_exports)), "Section"));
6117
+ registry.register("Tabs", namedExport(() => Promise.resolve().then(() => (init_grouping(), grouping_exports)), "Tabs"));
6118
+ registry.register("Accordion", namedExport(() => Promise.resolve().then(() => (init_grouping(), grouping_exports)), "Accordion"));
6119
+ registry.register("Modal", namedExport(() => Promise.resolve().then(() => (init_grouping(), grouping_exports)), "Modal"));
6120
+ registry.register("Router", namedExport(() => Promise.resolve().then(() => (init_navigation(), navigation_exports)), "Router"));
6121
+ registry.register("Route", namedExport(() => Promise.resolve().then(() => (init_navigation(), navigation_exports)), "Route"));
6122
+ registry.register("NavLink", namedExport(() => Promise.resolve().then(() => (init_navigation(), navigation_exports)), "NavLink"));
6123
+ registry.register("RoleGuard", namedExport(() => Promise.resolve().then(() => (init_navigation(), navigation_exports)), "RoleGuard"));
6124
+ registry.register("Slot", namedExport(() => Promise.resolve().then(() => (init_composition(), composition_exports)), "Slot"));
6125
+ registry.register("ModuleOutlet", namedExport(() => Promise.resolve().then(() => (init_composition(), composition_exports)), "ModuleOutlet"));
6126
+ registry.register("Markdown", namedExport(() => Promise.resolve().then(() => (init_content(), content_exports)), "Markdown"));
6127
+ registry.register("ScrollArea", namedExport(() => Promise.resolve().then(() => (init_grouping(), grouping_exports)), "ScrollArea"));
6128
+ registry.register("Table", namedExport(() => Promise.resolve().then(() => (init_data(), data_exports)), "Table"));
6129
+ registry.register("DataGrid", namedExport(() => Promise.resolve().then(() => (init_data(), data_exports)), "DataGrid"));
6130
+ registry.register("Alert", namedExport(() => Promise.resolve().then(() => (init_content(), content_exports)), "Alert"));
6131
+ registry.register("EmptyState", namedExport(() => Promise.resolve().then(() => (init_content(), content_exports)), "EmptyState"));
6132
+ registry.register("Progress", namedExport(() => Promise.resolve().then(() => (init_content(), content_exports)), "Progress"));
6133
+ registry.register("Separator", namedExport(() => Promise.resolve().then(() => (init_content(), content_exports)), "Separator"));
6134
+ return registry;
6135
+ }
6136
+ function mergeRegistries(...registries) {
6137
+ let merged = new AtomRegistryImpl();
6138
+ for (const r of registries) {
6139
+ merged = merged.merge(r);
6140
+ }
6141
+ return merged;
3687
6142
  }
3688
- function or(...conditions) {
3689
- return { OR: conditions.map(normalize) };
6143
+
6144
+ // src/player/theme.ts
6145
+ var DEFAULT_DESIGN_TOKENS = {
6146
+ // Colors
6147
+ "token:primary": "#3182ce",
6148
+ "token:primary-hover": "#2b6cb0",
6149
+ "token:primary-light": "#ebf8ff",
6150
+ "token:secondary": "#718096",
6151
+ "token:secondary-hover": "#4a5568",
6152
+ "token:accent": "#805ad5",
6153
+ "token:success": "#38a169",
6154
+ "token:warning": "#dd6b20",
6155
+ "token:error": "#e53e3e",
6156
+ "token:info": "#3182ce",
6157
+ // Surfaces
6158
+ "token:surface": "#ffffff",
6159
+ "token:surface-hover": "#f7fafc",
6160
+ "token:surface-secondary": "#edf2f7",
6161
+ "token:background": "#f7fafc",
6162
+ "token:card": "#ffffff",
6163
+ "token:overlay": "rgba(0, 0, 0, 0.4)",
6164
+ // Borders
6165
+ "token:border": "#e2e8f0",
6166
+ "token:border-light": "#edf2f7",
6167
+ "token:border-focus": "#3182ce",
6168
+ // Text
6169
+ "token:text": "#1a202c",
6170
+ "token:text-secondary": "#718096",
6171
+ "token:text-muted": "#a0aec0",
6172
+ "token:text-inverse": "#ffffff",
6173
+ "token:text-link": "#3182ce",
6174
+ // Shadows
6175
+ "token:shadow-sm": "0 1px 2px rgba(0, 0, 0, 0.05)",
6176
+ "token:shadow": "0 1px 3px rgba(0, 0, 0, 0.1), 0 1px 2px rgba(0, 0, 0, 0.06)",
6177
+ "token:shadow-md": "0 4px 6px rgba(0, 0, 0, 0.1), 0 2px 4px rgba(0, 0, 0, 0.06)",
6178
+ "token:shadow-lg": "0 10px 15px rgba(0, 0, 0, 0.1), 0 4px 6px rgba(0, 0, 0, 0.05)",
6179
+ // Spacing
6180
+ "token:spacing-xs": "4px",
6181
+ "token:spacing-sm": "8px",
6182
+ "token:spacing-md": "16px",
6183
+ "token:spacing-lg": "24px",
6184
+ "token:spacing-xl": "32px",
6185
+ // Radius
6186
+ "token:radius-sm": "4px",
6187
+ "token:radius": "6px",
6188
+ "token:radius-md": "8px",
6189
+ "token:radius-lg": "12px",
6190
+ "token:radius-full": "9999px"
6191
+ };
6192
+
6193
+ // src/player/PlayerProvider.tsx
6194
+ var import_jsx_runtime11 = require("react/jsx-runtime");
6195
+ var PlayerContext = (0, import_react43.createContext)(null);
6196
+ function usePlayerContext() {
6197
+ return (0, import_react43.useContext)(PlayerContext);
3690
6198
  }
3691
- function not(condition) {
3692
- const c = normalize(condition);
3693
- if (c.type === "expression" && c.expression) {
3694
- return { type: "expression", expression: `NOT(${c.expression})` };
6199
+ var ThemeContext = (0, import_react43.createContext)(DEFAULT_DESIGN_TOKENS);
6200
+ function useTheme() {
6201
+ return (0, import_react43.useContext)(ThemeContext);
6202
+ }
6203
+ var PlayerProvider = ({
6204
+ resolver,
6205
+ atomRegistry: userAtomRegistry,
6206
+ auth,
6207
+ router,
6208
+ toast,
6209
+ onEvent,
6210
+ theme: userTheme,
6211
+ children
6212
+ }) => {
6213
+ const atomRegistry = (0, import_react43.useMemo)(
6214
+ () => userAtomRegistry ?? createCoreAtomRegistry(),
6215
+ [userAtomRegistry]
6216
+ );
6217
+ const mergedTheme = (0, import_react43.useMemo)(
6218
+ () => userTheme ? { ...DEFAULT_DESIGN_TOKENS, ...userTheme } : DEFAULT_DESIGN_TOKENS,
6219
+ [userTheme]
6220
+ );
6221
+ const resolverRef = (0, import_react43.useRef)(resolver);
6222
+ resolverRef.current = resolver;
6223
+ (0, import_react43.useEffect)(() => {
6224
+ if (!resolver) return;
6225
+ setQueryResolver({
6226
+ query: async (_slug, params) => {
6227
+ const r = resolverRef.current;
6228
+ if (!r) return { data: [] };
6229
+ const result = await r.query(_slug, {
6230
+ state: params.state,
6231
+ filter: params.filter,
6232
+ limit: params.limit,
6233
+ offset: params.offset,
6234
+ search: params.search,
6235
+ searchFields: params.searchFields,
6236
+ sort: params.sort
6237
+ });
6238
+ return { data: result.data, total: result.total };
6239
+ }
6240
+ });
6241
+ setMutationResolver({
6242
+ create: async (_slug, input) => {
6243
+ const r = resolverRef.current;
6244
+ if (!r) throw new Error("No resolver");
6245
+ return r.create(_slug, input);
6246
+ },
6247
+ update: async (_slug, instanceId, fields) => {
6248
+ const r = resolverRef.current;
6249
+ if (!r) throw new Error("No resolver");
6250
+ await r.update(instanceId, fields);
6251
+ },
6252
+ transition: async (_slug, instanceId, transitionName, input) => {
6253
+ const r = resolverRef.current;
6254
+ if (!r) throw new Error("No resolver");
6255
+ await r.transition(instanceId, transitionName, input);
6256
+ },
6257
+ remove: async (_slug, instanceId) => {
6258
+ const r = resolverRef.current;
6259
+ if (!r) throw new Error("No resolver");
6260
+ await r.remove(instanceId);
6261
+ }
6262
+ });
6263
+ return () => {
6264
+ setQueryResolver(null);
6265
+ setMutationResolver(null);
6266
+ };
6267
+ }, [resolver]);
6268
+ const value = (0, import_react43.useMemo)(() => ({
6269
+ resolver: resolver ?? null,
6270
+ atomRegistry,
6271
+ auth,
6272
+ router,
6273
+ toast,
6274
+ onEvent
6275
+ }), [resolver, atomRegistry, auth, router, toast, onEvent]);
6276
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(PlayerContext.Provider, { value, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ThemeContext.Provider, { value: mergedTheme, children }) });
6277
+ };
6278
+
6279
+ // src/player/ExperienceRenderer.tsx
6280
+ var import_jsx_runtime12 = require("react/jsx-runtime");
6281
+ var NodeErrorBoundary = class extends import_react44.default.Component {
6282
+ constructor(props) {
6283
+ super(props);
6284
+ this.state = { hasError: false };
3695
6285
  }
3696
- if (c.type === "role" && c.role) {
3697
- return { type: "expression", expression: `NOT(context.roles CONTAINS "${c.role}")` };
6286
+ static getDerivedStateFromError(error) {
6287
+ return { hasError: true, error };
3698
6288
  }
3699
- if (c.type === "field" && c.field) {
3700
- const invertedOps = {
3701
- eq: "ne",
3702
- ne: "eq",
3703
- gt: "lte",
3704
- gte: "lt",
3705
- lt: "gte",
3706
- lte: "gt",
3707
- in: "not_in",
3708
- not_in: "in",
3709
- is_set: "is_empty",
3710
- is_empty: "is_set"
6289
+ componentDidCatch(error, info) {
6290
+ console.error(`[ExperienceRenderer] Error in node ${this.props.nodeId}:`, error, info);
6291
+ }
6292
+ render() {
6293
+ if (this.state.hasError) {
6294
+ return this.props.fallback ?? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { style: { padding: 8, background: "#fff5f5", border: "1px solid #fed7d7", borderRadius: 6, fontSize: 12, color: "#c53030" }, children: [
6295
+ "Error: ",
6296
+ this.state.error?.message ?? "Render failed"
6297
+ ] });
6298
+ }
6299
+ return this.props.children;
6300
+ }
6301
+ };
6302
+ function useDataSources(dataSources, resolver, scope) {
6303
+ const [results, setResults] = (0, import_react44.useState)({});
6304
+ const mountedRef = (0, import_react44.useRef)(true);
6305
+ (0, import_react44.useEffect)(() => {
6306
+ mountedRef.current = true;
6307
+ return () => {
6308
+ mountedRef.current = false;
3711
6309
  };
3712
- const op = c.operator ?? "eq";
3713
- const inverted = invertedOps[op];
3714
- if (inverted) {
3715
- return { type: "field", field: c.field, operator: inverted, value: c.value };
6310
+ }, []);
6311
+ (0, import_react44.useEffect)(() => {
6312
+ if (!dataSources?.length || !resolver) return;
6313
+ const loading = {};
6314
+ for (const ds of dataSources) {
6315
+ loading[ds.name] = { loading: true, error: null };
6316
+ }
6317
+ setResults(loading);
6318
+ const fetchAll = async () => {
6319
+ const entries = await Promise.all(
6320
+ dataSources.map(async (ds) => {
6321
+ try {
6322
+ const result = await fetchDataSource(ds, resolver, scope);
6323
+ return [ds.name, result];
6324
+ } catch (err) {
6325
+ return [ds.name, { loading: false, error: err instanceof Error ? err : new Error(String(err)) }];
6326
+ }
6327
+ })
6328
+ );
6329
+ if (mountedRef.current) {
6330
+ setResults(Object.fromEntries(entries));
6331
+ }
6332
+ };
6333
+ fetchAll();
6334
+ }, [dataSources, resolver]);
6335
+ return results;
6336
+ }
6337
+ async function fetchDataSource(ds, resolver, scope) {
6338
+ switch (ds.type) {
6339
+ case "workflow": {
6340
+ const slug = ds.slug ?? "";
6341
+ if (!slug) return { loading: false, error: new Error("workflow dataSource missing slug") };
6342
+ const queryResult = await resolver.query(slug, {
6343
+ state: ds.filter?.current_state,
6344
+ filter: ds.filter,
6345
+ limit: ds.pageSize ?? 20,
6346
+ page: scope.$local?.[ds.pageKey ?? "page"] ?? 1,
6347
+ search: ds.search ? interpolateTemplate(ds.search, scope) : void 0,
6348
+ searchFields: ds.searchFields,
6349
+ sort: ds.sort,
6350
+ facets: ds.facets,
6351
+ entity: ds.entity,
6352
+ includeDefinition: ds.includeDefinition,
6353
+ parentInstanceId: ds.parentInstanceId ? interpolateTemplate(ds.parentInstanceId, scope) : void 0
6354
+ });
6355
+ const result = {
6356
+ instances: queryResult.data,
6357
+ loading: false,
6358
+ error: null
6359
+ };
6360
+ if (queryResult.data.length === 1 && ds.query !== "list") {
6361
+ result.instance = queryResult.data[0];
6362
+ }
6363
+ if (queryResult.definition) result.definition = queryResult.definition;
6364
+ if (queryResult.total != null) {
6365
+ result.pagination = {
6366
+ total: queryResult.total,
6367
+ page: queryResult.page,
6368
+ pageSize: queryResult.pageSize
6369
+ };
6370
+ }
6371
+ if (queryResult.facets) result.facets = queryResult.facets;
6372
+ if (queryResult.aggregates) result.aggregates = queryResult.aggregates;
6373
+ if (ds.autoStart && queryResult.data.length === 0) {
6374
+ try {
6375
+ const id = await resolver.create(slug, ds.initialData);
6376
+ const instance2 = await resolver.getInstance(id);
6377
+ result.instance = instance2;
6378
+ result.instances = [instance2];
6379
+ } catch {
6380
+ }
6381
+ }
6382
+ return result;
3716
6383
  }
3717
- return { type: "expression", expression: `NOT(state_data.${c.field} ${op.toUpperCase()} ${JSON.stringify(c.value)})` };
6384
+ case "api": {
6385
+ if (!resolver.fetch) return { loading: false, error: new Error("API datasource: resolver.fetch not implemented") };
6386
+ const endpoint = interpolateTemplate(ds.endpoint, scope);
6387
+ const raw = await resolver.fetch(endpoint, {
6388
+ method: ds.method,
6389
+ body: ds.body,
6390
+ headers: ds.headers
6391
+ });
6392
+ const mapped = mapApiResponse(raw, ds.mapping);
6393
+ return { instances: mapped.items, loading: false, error: null, pagination: mapped.pagination };
6394
+ }
6395
+ case "static": {
6396
+ const data = ds.data;
6397
+ if (Array.isArray(data)) {
6398
+ return {
6399
+ instances: data.map((d, i) => ({
6400
+ id: String(d.id ?? i),
6401
+ state: "static",
6402
+ fields: d
6403
+ })),
6404
+ loading: false,
6405
+ error: null
6406
+ };
6407
+ }
6408
+ return {
6409
+ instance: { id: "static", state: "static", fields: data },
6410
+ loading: false,
6411
+ error: null
6412
+ };
6413
+ }
6414
+ case "ref": {
6415
+ const ctx = buildEvalContext(scope);
6416
+ const resolved = evaluateExpression(ds.expression, ctx);
6417
+ if (Array.isArray(resolved)) {
6418
+ return {
6419
+ instances: resolved.map((item, i) => ({
6420
+ id: String(item?.id ?? i),
6421
+ state: String(item?.state ?? "ref"),
6422
+ fields: item && typeof item === "object" ? item : { value: item }
6423
+ })),
6424
+ loading: false,
6425
+ error: null
6426
+ };
6427
+ }
6428
+ if (resolved != null && typeof resolved === "object") {
6429
+ const obj = resolved;
6430
+ return {
6431
+ instance: {
6432
+ id: String(obj.id ?? "ref"),
6433
+ state: String(obj.state ?? "ref"),
6434
+ fields: obj
6435
+ },
6436
+ loading: false,
6437
+ error: null
6438
+ };
6439
+ }
6440
+ return { loading: false, error: null };
6441
+ }
6442
+ default:
6443
+ return { loading: false, error: new Error(`Unknown dataSource type: ${ds.type}`) };
3718
6444
  }
3719
- return { type: "expression", expression: `NOT(true)` };
3720
6445
  }
3721
- function refHasRole(slug, lookupField, lookupValue, role) {
3722
- return {
3723
- type: "expression",
3724
- expression: `$ref("${slug}", "${lookupField}", ${lookupValue}).role == "${role}"`
3725
- };
6446
+ function interpolateTemplate(template, scope) {
6447
+ return template.replace(/\{\{\s*([\w.]+)\s*\}\}/g, (_, path) => {
6448
+ const val = resolveBinding(`$${path}`, scope) ?? resolveBinding(path, scope);
6449
+ return val != null ? String(val) : "";
6450
+ });
3726
6451
  }
3727
- function refHasAnyRole(slug, lookupField, lookupValue, roles) {
3728
- const roleList = roles.map((r) => `"${r}"`).join(", ");
3729
- return {
3730
- type: "expression",
3731
- expression: `$ref("${slug}", "${lookupField}", ${lookupValue}).role IN [${roleList}]`
3732
- };
6452
+ function mapApiResponse(raw, mapping) {
6453
+ if (!raw || typeof raw !== "object") return { items: [] };
6454
+ const obj = raw;
6455
+ let items;
6456
+ if (mapping?.items || mapping?.data) {
6457
+ items = obj[mapping.items ?? mapping.data ?? "data"] ?? [];
6458
+ } else if (Array.isArray(raw)) {
6459
+ items = raw;
6460
+ } else if (Array.isArray(obj.data)) {
6461
+ items = obj.data;
6462
+ } else if (Array.isArray(obj.items)) {
6463
+ items = obj.items;
6464
+ } else {
6465
+ items = [raw];
6466
+ }
6467
+ const result = items.map((item, i) => ({
6468
+ id: String(item?.id ?? i),
6469
+ state: String(item?.state ?? "unknown"),
6470
+ fields: item ?? {}
6471
+ }));
6472
+ let pagination;
6473
+ const total = mapping?.total ? obj[mapping.total] : obj.total;
6474
+ if (total != null) {
6475
+ pagination = { total: Number(total), page: Number(obj.page ?? 1), pageSize: Number(obj.pageSize ?? items.length) };
6476
+ }
6477
+ return { items: result, pagination };
3733
6478
  }
3734
-
3735
- // src/hooks/useModel.ts
3736
- var import_react34 = require("react");
3737
- function getDefaultFields(definition) {
3738
- const defaults = {};
3739
- for (const [key, field2] of Object.entries(definition.fields)) {
3740
- if (field2.default !== void 0) {
3741
- defaults[key] = field2.default;
3742
- } else {
3743
- switch (field2.type) {
3744
- case "string":
3745
- case "text":
3746
- case "email":
3747
- case "url":
3748
- case "phone":
3749
- case "color":
3750
- case "select":
3751
- case "rich_text":
3752
- defaults[key] = "";
3753
- break;
3754
- case "number":
3755
- case "integer":
3756
- case "float":
3757
- case "currency":
3758
- case "percentage":
3759
- case "rating":
3760
- case "duration":
3761
- defaults[key] = 0;
3762
- break;
3763
- case "boolean":
3764
- defaults[key] = false;
3765
- break;
3766
- case "array":
3767
- defaults[key] = [];
3768
- break;
3769
- case "object":
3770
- case "json":
3771
- defaults[key] = {};
3772
- break;
3773
- default:
3774
- defaults[key] = void 0;
3775
- }
6479
+ function resolveTokens(value, tokens) {
6480
+ if (typeof value === "string" && value.startsWith("token:")) {
6481
+ return tokens[value] ?? value;
6482
+ }
6483
+ if (typeof value === "object" && value !== null && !Array.isArray(value)) {
6484
+ const resolved = {};
6485
+ for (const [k, v] of Object.entries(value)) {
6486
+ resolved[k] = resolveTokens(v, tokens);
6487
+ }
6488
+ return resolved;
6489
+ }
6490
+ return value;
6491
+ }
6492
+ var NodeRenderer = ({ node, fallback }) => {
6493
+ const parentScope = useScope();
6494
+ const playerCtx = usePlayerContext();
6495
+ const resolver = playerCtx?.resolver ?? null;
6496
+ const atomRegistry = playerCtx?.atomRegistry;
6497
+ const themeTokens = useTheme();
6498
+ const localDefaults = node.config?.localDefaults ?? {};
6499
+ const [localState, setLocalState] = (0, import_react44.useState)(() => ({
6500
+ ...localDefaults
6501
+ }));
6502
+ const handleSetLocal = (0, import_react44.useCallback)((key, value) => {
6503
+ setLocalState((prev) => ({ ...prev, [key]: value }));
6504
+ }, []);
6505
+ const [, setFetchVersion] = (0, import_react44.useState)(0);
6506
+ const handleRefreshQuery = (0, import_react44.useCallback)(() => {
6507
+ setFetchVersion((v) => v + 1);
6508
+ }, []);
6509
+ const dsResults = useDataSources(node.dataSources, resolver, parentScope);
6510
+ const primaryInstance = Object.values(dsResults).find((r) => r.instance)?.instance;
6511
+ const primarySlug = node.dataSources?.find((ds) => ds.type === "workflow")?.slug;
6512
+ const actionScope = (0, import_react44.useMemo)(() => {
6513
+ if (!resolver) {
6514
+ return {
6515
+ transition: async () => {
6516
+ },
6517
+ create: async () => "",
6518
+ update: async () => {
6519
+ },
6520
+ remove: async () => {
6521
+ },
6522
+ setLocal: handleSetLocal,
6523
+ navigate: () => {
6524
+ },
6525
+ toast: () => {
6526
+ },
6527
+ refreshQuery: handleRefreshQuery,
6528
+ scrollTo: () => {
6529
+ },
6530
+ openModal: () => {
6531
+ },
6532
+ closeModal: () => {
6533
+ },
6534
+ emit: () => {
6535
+ }
6536
+ };
3776
6537
  }
6538
+ return buildActionScope({
6539
+ resolver,
6540
+ instanceId: primaryInstance?.id,
6541
+ slug: primarySlug,
6542
+ setLocal: handleSetLocal,
6543
+ router: playerCtx?.router,
6544
+ toast: playerCtx?.toast,
6545
+ refreshQuery: handleRefreshQuery,
6546
+ onEvent: playerCtx?.onEvent
6547
+ });
6548
+ }, [resolver, primaryInstance?.id, primarySlug, handleSetLocal, handleRefreshQuery, playerCtx]);
6549
+ const scope = (0, import_react44.useMemo)(() => buildScope({
6550
+ dataSources: dsResults,
6551
+ localState,
6552
+ auth: playerCtx?.auth,
6553
+ entity: node.dataSources?.find((ds) => ds.type === "workflow")?.entity,
6554
+ parentScope,
6555
+ actionScope
6556
+ }), [dsResults, localState, parentScope, actionScope, playerCtx?.auth]);
6557
+ const enrichedScope = (0, import_react44.useMemo)(() => {
6558
+ const handleCreate = () => {
6559
+ if (primarySlug && resolver) {
6560
+ resolver.create(primarySlug).then(() => handleRefreshQuery());
6561
+ }
6562
+ };
6563
+ const setSearch = (e) => {
6564
+ const val = typeof e === "object" && e !== null && "target" in e ? e.target.value : String(e ?? "");
6565
+ handleSetLocal("search", val);
6566
+ };
6567
+ const enrichedAction = {
6568
+ ...scope.$action,
6569
+ handleCreate,
6570
+ setSearch
6571
+ };
6572
+ const enrichedInstance = scope.$instance ? { ...scope.$instance, handleCreate, setSearch } : void 0;
6573
+ return {
6574
+ ...scope,
6575
+ $action: enrichedAction,
6576
+ $instance: enrichedInstance,
6577
+ // Also add at top-level for direct access
6578
+ handleCreate,
6579
+ setSearch
6580
+ };
6581
+ }, [scope, primarySlug, resolver, handleRefreshQuery, handleSetLocal]);
6582
+ if (node.visible_when) {
6583
+ const ctx = buildEvalContext(enrichedScope);
6584
+ const visible = evaluateExpression(node.visible_when, ctx);
6585
+ if (!visible) return null;
3777
6586
  }
3778
- return defaults;
3779
- }
3780
- function useModel(definition, options = {}) {
3781
- const slug = definition.slug;
3782
- const queryParams = {
3783
- limit: 1,
3784
- enabled: options.enabled,
3785
- refetchInterval: options.refetchInterval
3786
- };
3787
- if (options.filter) queryParams.filter = options.filter;
3788
- if (options.state) queryParams.state = options.state;
3789
- const query = useQuery(slug, queryParams);
3790
- const mutation = useMutation(slug);
3791
- const instance2 = query.data?.[0];
3792
- const instanceId = instance2?.id ?? null;
3793
- const currentState = instance2?.currentState ?? "";
3794
- const instanceFields = instance2?.fields ?? null;
3795
- const defaultFields = (0, import_react34.useMemo)(() => getDefaultFields(definition), [definition]);
3796
- const fields = (0, import_react34.useMemo)(() => {
3797
- if (!instanceFields) return defaultFields;
3798
- return { ...defaultFields, ...instanceFields };
3799
- }, [instanceFields, defaultFields]);
3800
- const instanceIdRef = (0, import_react34.useRef)(instanceId);
3801
- instanceIdRef.current = instanceId;
3802
- const trigger = (0, import_react34.useCallback)(async (name, input) => {
3803
- const id = instanceIdRef.current;
3804
- if (!id) {
3805
- throw new Error(`useModel(${slug}): No instance loaded. Cannot trigger '${name}'.`);
6587
+ if (node.$if) {
6588
+ const ctx = buildEvalContext(enrichedScope);
6589
+ const visible = evaluateExpression(node.$if, ctx);
6590
+ if (!visible) return null;
6591
+ }
6592
+ const resolvedBindings = node.bindings ? resolveAllBindings(node.bindings, enrichedScope) : {};
6593
+ const config = node.config ?? node.props ?? {};
6594
+ const rawMerged = { ...config, ...resolvedBindings };
6595
+ const mergedProps = {};
6596
+ for (const [k, v] of Object.entries(rawMerged)) {
6597
+ mergedProps[k] = resolveTokens(v, themeTokens);
6598
+ }
6599
+ if (node.className) mergedProps.className = node.className;
6600
+ if (node.id) mergedProps["data-node-id"] = node.id;
6601
+ const loadingAny = Object.values(dsResults).some((r) => r.loading);
6602
+ if (Object.keys(dsResults).length > 0) {
6603
+ mergedProps.loading = loadingAny;
6604
+ const firstResult = Object.values(dsResults)[0];
6605
+ if (firstResult?.instances) mergedProps.data = firstResult.instances;
6606
+ if (firstResult?.instance) mergedProps.instance = firstResult.instance;
6607
+ if (firstResult?.pagination) mergedProps.pagination = firstResult.pagination;
6608
+ if (firstResult?.definition) mergedProps.definition = firstResult.definition;
6609
+ }
6610
+ const componentName = node.component ?? node.type ?? "";
6611
+ let AtomComponent = null;
6612
+ if (atomRegistry) {
6613
+ const lazy = atomRegistry.resolve(componentName);
6614
+ if (lazy) AtomComponent = lazy;
6615
+ }
6616
+ if (!AtomComponent) {
6617
+ if (!componentName && node.children?.length) {
6618
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ScopeContext.Provider, { value: enrichedScope, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: node.className, style: node.style, children: node.children.map((child, i) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(NodeErrorBoundary, { nodeId: child.id, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(NodeRenderer, { node: child, fallback }) }, child.id ?? i)) }) });
6619
+ }
6620
+ if (componentName) {
6621
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { style: { border: "1px dashed #e53e3e", borderRadius: 6, padding: "8px 12px", margin: 4, fontSize: 13, color: "#e53e3e", background: "#fff5f5" }, children: [
6622
+ "Unknown: ",
6623
+ componentName
6624
+ ] });
3806
6625
  }
3807
- await mutation.transition(id, name, input);
3808
- await query.refetch();
3809
- }, [slug, mutation, query]);
3810
- const create = (0, import_react34.useCallback)(async (input) => {
3811
- const id = await mutation.create(input);
3812
- await query.refetch();
3813
- return id;
3814
- }, [mutation, query]);
3815
- const update = (0, import_react34.useCallback)(async (fieldUpdates) => {
3816
- const id = instanceIdRef.current;
3817
- if (!id) {
3818
- throw new Error(`useModel(${slug}): No instance loaded. Cannot update.`);
6626
+ return null;
6627
+ }
6628
+ let children = null;
6629
+ if (node.children?.length) {
6630
+ children = node.children.map((child, i) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(NodeErrorBoundary, { nodeId: child.id, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(NodeRenderer, { node: child, fallback }) }, child.id ?? i));
6631
+ }
6632
+ if (!children && mergedProps.children != null) {
6633
+ children = mergedProps.children;
6634
+ delete mergedProps.children;
6635
+ }
6636
+ delete mergedProps.localDefaults;
6637
+ delete mergedProps.dataSources;
6638
+ delete mergedProps.bindings;
6639
+ delete mergedProps.visible_when;
6640
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ScopeContext.Provider, { value: enrichedScope, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(NodeErrorBoundary, { nodeId: node.id, fallback, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_react44.Suspense, { fallback: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { style: { padding: 8, color: "#a0aec0", fontSize: 13 }, children: [
6641
+ "Loading ",
6642
+ componentName,
6643
+ "..."
6644
+ ] }), children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(AtomComponent, { ...mergedProps, children }) }) }) });
6645
+ };
6646
+ var ExperienceRenderer = ({
6647
+ tree,
6648
+ initialScope,
6649
+ entity,
6650
+ fallback,
6651
+ className
6652
+ }) => {
6653
+ const playerCtx = usePlayerContext();
6654
+ const nodes = Array.isArray(tree) ? tree : [tree];
6655
+ const rootScope = (0, import_react44.useMemo)(() => buildScope({
6656
+ auth: playerCtx?.auth ?? initialScope?.auth,
6657
+ entity,
6658
+ localState: initialScope?.$local ?? {},
6659
+ actionScope: initialScope?.$action ?? {
6660
+ transition: async () => {
6661
+ },
6662
+ create: async () => "",
6663
+ update: async () => {
6664
+ },
6665
+ remove: async () => {
6666
+ },
6667
+ setLocal: () => {
6668
+ },
6669
+ navigate: () => {
6670
+ },
6671
+ toast: () => {
6672
+ },
6673
+ refreshQuery: () => {
6674
+ },
6675
+ scrollTo: () => {
6676
+ },
6677
+ openModal: () => {
6678
+ },
6679
+ closeModal: () => {
6680
+ },
6681
+ emit: () => {
6682
+ }
3819
6683
  }
3820
- await mutation.update(id, fieldUpdates);
3821
- await query.refetch();
3822
- }, [slug, mutation, query]);
3823
- const handle = {
3824
- fields,
3825
- state: currentState,
3826
- instanceId,
3827
- trigger,
3828
- transition: trigger,
3829
- create,
3830
- update,
3831
- loading: query.loading,
3832
- error: query.error ?? mutation.error,
3833
- refetch: query.refetch,
3834
- isPending: mutation.isPending,
3835
- reset: mutation.reset,
3836
- raw: { data: query.data, total: query.total }
6684
+ }), [playerCtx?.auth, entity, initialScope]);
6685
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ScopeContext.Provider, { value: rootScope, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className, children: nodes.map((node, i) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(NodeErrorBoundary, { nodeId: node.id, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(NodeRenderer, { node, fallback }) }, node.id ?? i)) }) });
6686
+ };
6687
+
6688
+ // src/player/resolver.ts
6689
+ function getToken5(token) {
6690
+ if (!token) return null;
6691
+ if (typeof token === "function") return token();
6692
+ return token;
6693
+ }
6694
+ function normalizeInstance(raw) {
6695
+ return {
6696
+ id: String(raw.id ?? ""),
6697
+ state: String(raw.current_state ?? raw.state ?? "unknown"),
6698
+ fields: raw.state_data ?? raw.fields ?? {},
6699
+ slug: raw.definition_slug,
6700
+ created_at: raw.created_at,
6701
+ updated_at: raw.updated_at,
6702
+ ...raw
3837
6703
  };
3838
- return handle;
3839
6704
  }
3840
- function useCollection(definition, options = {}) {
3841
- const slug = definition.slug;
3842
- const query = useQuery(slug, options);
3843
- const mutation = useMutation(slug);
3844
- const items = (0, import_react34.useMemo)(() => {
3845
- return (query.data || []).map((instance2) => ({
3846
- id: instance2.id,
3847
- fields: instance2.fields ?? {},
3848
- state: instance2.currentState ?? ""
3849
- }));
3850
- }, [query.data]);
3851
- const trigger = (0, import_react34.useCallback)(async (instanceId, name, input) => {
3852
- await mutation.transition(instanceId, name, input);
3853
- await query.refetch();
3854
- }, [mutation, query]);
3855
- const create = (0, import_react34.useCallback)(async (input) => {
3856
- const id = await mutation.create(input);
3857
- await query.refetch();
3858
- return id;
3859
- }, [mutation, query]);
3860
- const update = (0, import_react34.useCallback)(async (instanceId, fieldUpdates) => {
3861
- await mutation.update(instanceId, fieldUpdates);
3862
- await query.refetch();
3863
- }, [mutation, query]);
3864
- const remove = (0, import_react34.useCallback)(async (instanceId) => {
3865
- await mutation.remove(instanceId);
3866
- await query.refetch();
3867
- }, [mutation, query]);
3868
- const handle = {
3869
- items,
3870
- total: query.total ?? items.length,
3871
- loading: query.loading,
3872
- error: query.error ?? mutation.error,
3873
- refetch: query.refetch,
3874
- hasMore: query.hasMore ?? false,
3875
- trigger,
3876
- create,
3877
- update,
3878
- remove,
3879
- isPending: mutation.isPending
6705
+ function createApiResolver(config) {
6706
+ const { baseUrl, defaults } = config;
6707
+ const fetchFn = config.fetch ?? globalThis.fetch.bind(globalThis);
6708
+ const defCache = /* @__PURE__ */ new Map();
6709
+ async function apiRequest(path, options = {}) {
6710
+ const tok = getToken5(config.token);
6711
+ const headers = {
6712
+ "Content-Type": "application/json",
6713
+ ...options.headers ?? {}
6714
+ };
6715
+ if (tok) headers["Authorization"] = `Bearer ${tok}`;
6716
+ const response = await fetchFn(`${baseUrl}${path}`, {
6717
+ ...options,
6718
+ headers
6719
+ });
6720
+ if (!response.ok) {
6721
+ const body = await response.text().catch(() => "");
6722
+ let message = `API error ${response.status}: ${response.statusText}`;
6723
+ try {
6724
+ const parsed = JSON.parse(body);
6725
+ if (parsed.message) message = parsed.message;
6726
+ if (parsed.error) message = `${parsed.error}: ${parsed.message || ""}`;
6727
+ } catch {
6728
+ }
6729
+ throw new Error(message);
6730
+ }
6731
+ return response.json();
6732
+ }
6733
+ const resolver = {
6734
+ async query(slug, params) {
6735
+ const searchParams = new URLSearchParams();
6736
+ searchParams.set("definition", slug);
6737
+ if (params.state) {
6738
+ const states = Array.isArray(params.state) ? params.state : [params.state];
6739
+ states.forEach((s) => searchParams.append("state", s));
6740
+ }
6741
+ if (params.status) searchParams.set("status", params.status);
6742
+ if (params.limit ?? defaults?.limit) searchParams.set("limit", String(params.limit ?? defaults?.limit ?? 20));
6743
+ if (params.page) searchParams.set("page", String(params.page));
6744
+ if (params.offset) searchParams.set("offset", String(params.offset));
6745
+ if (params.search) searchParams.set("search", params.search);
6746
+ if (params.searchFields?.length) searchParams.set("search_fields", params.searchFields.join(","));
6747
+ if (params.sort) {
6748
+ if (typeof params.sort === "string") {
6749
+ searchParams.set("sort", params.sort);
6750
+ } else if (Array.isArray(params.sort)) {
6751
+ const sortStr = params.sort.map((s) => `${s.direction === "desc" ? "-" : ""}${s.field}`).join(",");
6752
+ searchParams.set("sort", sortStr);
6753
+ }
6754
+ }
6755
+ if (params.filter) {
6756
+ searchParams.set("state_filter", JSON.stringify(params.filter));
6757
+ }
6758
+ if (params.facets?.length) {
6759
+ searchParams.set("facets", params.facets.join(","));
6760
+ }
6761
+ if (params.entity) {
6762
+ searchParams.set("entity_type", params.entity.type);
6763
+ searchParams.set("entity_id", params.entity.id);
6764
+ }
6765
+ if (params.parentInstanceId) {
6766
+ searchParams.set("spawned_by_instance_id", params.parentInstanceId);
6767
+ }
6768
+ if (params.includeDefinition) {
6769
+ searchParams.set("include_definition", "true");
6770
+ }
6771
+ const raw = await apiRequest(
6772
+ `/workflow/instances?${searchParams.toString()}`
6773
+ );
6774
+ const items = raw.items ?? raw.data ?? [];
6775
+ const total = Number(raw.total ?? raw.count ?? items.length);
6776
+ const page = Number(raw.page ?? params.page ?? 1);
6777
+ const pageSize = Number(raw.page_size ?? raw.pageSize ?? params.limit ?? defaults?.limit ?? 20);
6778
+ const result = {
6779
+ data: items.map(normalizeInstance),
6780
+ total,
6781
+ page,
6782
+ pageSize
6783
+ };
6784
+ if (raw.definition) result.definition = raw.definition;
6785
+ if (raw.facets) result.facets = raw.facets;
6786
+ if (raw.aggregates) result.aggregates = raw.aggregates;
6787
+ if (raw.grouped) result.grouped = raw.grouped;
6788
+ return result;
6789
+ },
6790
+ async getInstance(id) {
6791
+ const raw = await apiRequest(`/workflow/instances/${id}`);
6792
+ return normalizeInstance(raw);
6793
+ },
6794
+ async getDefinition(slug) {
6795
+ const cached = defCache.get(slug);
6796
+ if (cached && cached.expires > Date.now()) return cached.data;
6797
+ const raw = await apiRequest(`/workflow/definitions/slug/${slug}`);
6798
+ defCache.set(slug, { data: raw, expires: Date.now() + 5 * 60 * 1e3 });
6799
+ return raw;
6800
+ },
6801
+ async create(slug, data) {
6802
+ const raw = await apiRequest("/workflow/instances", {
6803
+ method: "POST",
6804
+ body: JSON.stringify({
6805
+ definition_slug: slug,
6806
+ state_data: data ?? {}
6807
+ })
6808
+ });
6809
+ return String(raw.id);
6810
+ },
6811
+ async update(id, fields) {
6812
+ await apiRequest(`/workflow/instances/${id}/state-data`, {
6813
+ method: "PATCH",
6814
+ body: JSON.stringify(fields)
6815
+ });
6816
+ },
6817
+ async transition(id, name, data) {
6818
+ const raw = await apiRequest(
6819
+ `/workflow/instances/${id}/transitions/${name}`,
6820
+ {
6821
+ method: "POST",
6822
+ body: JSON.stringify({ data: data ?? {} })
6823
+ }
6824
+ );
6825
+ return raw;
6826
+ },
6827
+ async remove(id) {
6828
+ await apiRequest(`/workflow/instances/${id}`, { method: "DELETE" });
6829
+ },
6830
+ async availableTransitions(id) {
6831
+ const raw = await apiRequest(`/workflow/instances/${id}/transitions`);
6832
+ return Array.isArray(raw) ? raw : [];
6833
+ },
6834
+ async fetch(endpoint, fetchConfig) {
6835
+ return apiRequest(endpoint, {
6836
+ method: fetchConfig.method ?? "GET",
6837
+ body: fetchConfig.body ? JSON.stringify(fetchConfig.body) : void 0,
6838
+ headers: fetchConfig.headers
6839
+ });
6840
+ }
3880
6841
  };
3881
- return handle;
6842
+ return resolver;
3882
6843
  }
3883
6844
 
3884
- // src/player/ComponentTreeRenderer.tsx
3885
- var import_react35 = __toESM(require("react"));
6845
+ // src/index.ts
6846
+ init_expression_engine();
6847
+ init_scope_builder();
3886
6848
 
3887
- // src/player/evaluator.ts
6849
+ // src/player/ComponentTreeRenderer.tsx
6850
+ var import_react45 = __toESM(require("react"));
6851
+ init_expression_engine();
6852
+ var import_jsx_runtime13 = require("react/jsx-runtime");
3888
6853
  var EXPR_PATTERN = /\{\{(.+?)\}\}/g;
3889
6854
  function containsExpression(value) {
3890
6855
  return typeof value === "string" && EXPR_PATTERN.test(value);
3891
6856
  }
3892
- function resolvePath(path, scope) {
3893
- const parts = path.trim().split(".");
3894
- let current = scope;
3895
- for (const part of parts) {
3896
- if (current == null || typeof current !== "object") return void 0;
3897
- current = current[part];
3898
- }
3899
- return current;
3900
- }
3901
- function evaluateExpression(expr2, scopes) {
3902
- const trimmed = expr2.trim();
3903
- if (trimmed.startsWith("'") && trimmed.endsWith("'") || trimmed.startsWith('"') && trimmed.endsWith('"')) {
3904
- return trimmed.slice(1, -1);
3905
- }
3906
- if (/^-?\d+(\.\d+)?$/.test(trimmed)) {
3907
- return Number(trimmed);
3908
- }
3909
- if (trimmed === "true") return true;
3910
- if (trimmed === "false") return false;
3911
- if (trimmed === "null" || trimmed === "undefined") return void 0;
3912
- const flatScope = { ...scopes };
3913
- if (scopes.state_data && typeof scopes.state_data === "object") {
3914
- Object.assign(flatScope, scopes.state_data);
3915
- }
3916
- if (scopes.context && typeof scopes.context === "object") {
3917
- Object.assign(flatScope, scopes.context);
3918
- }
3919
- return resolvePath(trimmed, flatScope);
3920
- }
3921
6857
  function evaluateProp(value, scopes) {
3922
6858
  if (typeof value !== "string") return value;
3923
6859
  const fullMatch = value.match(/^\{\{(.+)\}\}$/s);
3924
- if (fullMatch) {
3925
- return evaluateExpression(fullMatch[1], scopes);
3926
- }
6860
+ if (fullMatch) return evaluateExpression(fullMatch[1], scopes);
3927
6861
  if (containsExpression(value)) {
3928
6862
  return value.replace(EXPR_PATTERN, (_, expr2) => {
3929
6863
  const result = evaluateExpression(expr2, scopes);
@@ -3932,17 +6866,16 @@ function evaluateProp(value, scopes) {
3932
6866
  }
3933
6867
  return value;
3934
6868
  }
3935
-
3936
- // src/player/ComponentTreeRenderer.tsx
3937
- var import_jsx_runtime2 = require("react/jsx-runtime");
3938
- var UnknownAtom = ({ type, children }) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { border: "1px dashed #e53e3e", borderRadius: 6, padding: "8px 12px", margin: 4, fontSize: 13, color: "#e53e3e", background: "#fff5f5" }, children: [
3939
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { style: { fontWeight: 600 }, children: [
6869
+ var UnknownAtom = ({ type, children }) => /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { style: { border: "1px dashed #e53e3e", borderRadius: 6, padding: "8px 12px", margin: 4, fontSize: 13, color: "#e53e3e", background: "#fff5f5" }, children: [
6870
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { style: { fontWeight: 600 }, children: [
3940
6871
  "Unknown: ",
3941
6872
  type
3942
6873
  ] }),
3943
- children && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { marginTop: 4 }, children })
6874
+ children && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { style: { marginTop: 4 }, children })
3944
6875
  ] });
3945
6876
  var RenderNode = ({ node, scopes, atoms, onEvent }) => {
6877
+ const nodeType = node.type || node.component || "";
6878
+ const nodeProps = node.props || node.config || {};
3946
6879
  if (node.$if) {
3947
6880
  const condition = evaluateProp(node.$if, scopes);
3948
6881
  if (!condition) return null;
@@ -3951,7 +6884,7 @@ var RenderNode = ({ node, scopes, atoms, onEvent }) => {
3951
6884
  const { each, as, key: keyField } = node.$for;
3952
6885
  const items = evaluateProp(each, scopes);
3953
6886
  if (!Array.isArray(items)) return null;
3954
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_jsx_runtime2.Fragment, { children: items.map((item, index) => {
6887
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_jsx_runtime13.Fragment, { children: items.map((item, index) => {
3955
6888
  const loopScopes = {
3956
6889
  ...scopes,
3957
6890
  state_data: {
@@ -3962,27 +6895,27 @@ var RenderNode = ({ node, scopes, atoms, onEvent }) => {
3962
6895
  };
3963
6896
  const nodeWithoutFor = { ...node, $for: void 0 };
3964
6897
  const itemKey = keyField ? String(item[keyField] ?? index) : String(index);
3965
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(RenderNode, { node: nodeWithoutFor, scopes: loopScopes, atoms, onEvent }, itemKey);
6898
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(RenderNode, { node: nodeWithoutFor, scopes: loopScopes, atoms, onEvent }, itemKey);
3966
6899
  }) });
3967
6900
  }
3968
- const Component = atoms[node.type];
6901
+ const Component = atoms[nodeType];
3969
6902
  if (!Component) {
3970
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(UnknownAtom, { type: node.type });
6903
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(UnknownAtom, { type: nodeType });
3971
6904
  }
3972
6905
  const evaluatedProps = {};
3973
- if (node.props) {
3974
- for (const [key, value] of Object.entries(node.props)) {
3975
- if (key.startsWith("on") && typeof value === "string") {
3976
- evaluatedProps[key] = (...args) => {
3977
- if (containsExpression(value)) {
3978
- evaluateExpression(value.replace(/^\{\{|\}\}$/g, ""), scopes);
3979
- } else {
3980
- onEvent(value, args[0]);
3981
- }
3982
- };
3983
- } else {
3984
- evaluatedProps[key] = evaluateProp(value, scopes);
3985
- }
6906
+ if (node.className) evaluatedProps.className = node.className;
6907
+ if (node.id) evaluatedProps["data-node-id"] = node.id;
6908
+ for (const [key, value] of Object.entries(nodeProps)) {
6909
+ if (key.startsWith("on") && typeof value === "string") {
6910
+ evaluatedProps[key] = (...args) => {
6911
+ if (containsExpression(value)) {
6912
+ evaluateExpression(value.replace(/^\{\{|\}\}$/g, ""), scopes);
6913
+ } else {
6914
+ onEvent(value, args[0]);
6915
+ }
6916
+ };
6917
+ } else {
6918
+ evaluatedProps[key] = evaluateProp(value, scopes);
3986
6919
  }
3987
6920
  }
3988
6921
  let children = null;
@@ -3990,12 +6923,12 @@ var RenderNode = ({ node, scopes, atoms, onEvent }) => {
3990
6923
  if (typeof node.children === "string") {
3991
6924
  children = evaluateProp(node.children, scopes);
3992
6925
  } else if (Array.isArray(node.children)) {
3993
- children = node.children.map((child, index) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(RenderNode, { node: child, scopes, atoms, onEvent }, index));
6926
+ children = node.children.map((child, index) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(RenderNode, { node: child, scopes, atoms, onEvent }, child.id || index));
3994
6927
  }
3995
6928
  }
3996
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Component, { ...evaluatedProps, children });
6929
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Component, { ...evaluatedProps, children });
3997
6930
  };
3998
- var CTRErrorBoundary = class extends import_react35.default.Component {
6931
+ var CTRErrorBoundary = class extends import_react45.default.Component {
3999
6932
  constructor(props) {
4000
6933
  super(props);
4001
6934
  this.state = { hasError: false };
@@ -4008,9 +6941,9 @@ var CTRErrorBoundary = class extends import_react35.default.Component {
4008
6941
  }
4009
6942
  render() {
4010
6943
  if (this.state.hasError) {
4011
- return this.props.fallback || /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { padding: 16, background: "#fff5f5", border: "1px solid #fed7d7", borderRadius: 8 }, children: [
4012
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("strong", { style: { color: "#c53030" }, children: "Rendering Error" }),
4013
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { style: { color: "#e53e3e", fontSize: 14, marginTop: 4 }, children: this.state.error?.message || "An error occurred while rendering" })
6944
+ return this.props.fallback || /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { style: { padding: 16, background: "#fff5f5", border: "1px solid #fed7d7", borderRadius: 8 }, children: [
6945
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("strong", { style: { color: "#c53030" }, children: "Rendering Error" }),
6946
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { style: { color: "#e53e3e", fontSize: 14, marginTop: 4 }, children: this.state.error?.message || "An error occurred while rendering" })
4014
6947
  ] });
4015
6948
  }
4016
6949
  return this.props.children;
@@ -4024,43 +6957,44 @@ var ComponentTreeRenderer = ({
4024
6957
  },
4025
6958
  fallback
4026
6959
  }) => {
4027
- const allAtoms = (0, import_react35.useMemo)(() => ({ ...atoms }), [atoms]);
4028
- const handleEvent = (0, import_react35.useCallback)(
6960
+ const allAtoms = (0, import_react45.useMemo)(() => ({ ...atoms }), [atoms]);
6961
+ const handleEvent = (0, import_react45.useCallback)(
4029
6962
  (eventName, payload) => onEvent(eventName, payload),
4030
6963
  [onEvent]
4031
6964
  );
4032
6965
  const nodes = Array.isArray(tree) ? tree : [tree];
4033
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(CTRErrorBoundary, { fallback, children: nodes.map((node, index) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(RenderNode, { node, scopes, atoms: allAtoms, onEvent: handleEvent }, index)) });
6966
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(CTRErrorBoundary, { fallback, children: nodes.map((node, index) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(RenderNode, { node, scopes, atoms: allAtoms, onEvent: handleEvent }, index)) });
4034
6967
  };
4035
6968
 
4036
6969
  // src/player/DevPlayer.tsx
4037
- var import_react36 = require("react");
6970
+ var import_react47 = require("react");
4038
6971
 
4039
6972
  // src/player/builtin-atoms.tsx
4040
- var import_jsx_runtime3 = require("react/jsx-runtime");
4041
- var Stack = ({ children, gap = 8, style, ...rest }) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: { display: "flex", flexDirection: "column", gap, ...style }, ...rest, children });
4042
- var Row = ({ children, gap = 8, align, justify, style, ...rest }) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: { display: "flex", flexDirection: "row", gap, alignItems: align, justifyContent: justify, ...style }, ...rest, children });
4043
- var Column = ({ children, span, style, ...rest }) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: { flex: span ? `0 0 ${Number(span) / 12 * 100}%` : 1, ...style }, ...rest, children });
4044
- var Grid = ({ children, columns = 2, gap = 8, style, ...rest }) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: { display: "grid", gridTemplateColumns: `repeat(${columns}, 1fr)`, gap, ...style }, ...rest, children });
4045
- var Divider = ({ style }) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("hr", { style: { border: "none", borderTop: "1px solid #e2e8f0", margin: "8px 0", ...style } });
4046
- var Spacer = ({ size = 16 }) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: { height: size, flexShrink: 0 } });
4047
- var Text = ({ children, size, weight, color, style, ...rest }) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { style: { fontSize: size, fontWeight: weight, color, ...style }, ...rest, children });
4048
- var Heading = ({ children, level = 2, style, ...rest }) => {
6973
+ var import_react46 = __toESM(require("react"));
6974
+ var import_jsx_runtime14 = require("react/jsx-runtime");
6975
+ var Stack2 = ({ children, gap = 8, style, ...rest }) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { style: { display: "flex", flexDirection: "column", gap, ...style }, ...rest, children });
6976
+ var Row2 = ({ children, gap = 8, align, justify, style, ...rest }) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { style: { display: "flex", flexDirection: "row", gap, alignItems: align, justifyContent: justify, ...style }, ...rest, children });
6977
+ var Column2 = ({ children, span, style, ...rest }) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { style: { flex: span ? `0 0 ${Number(span) / 12 * 100}%` : 1, ...style }, ...rest, children });
6978
+ var Grid2 = ({ children, columns = 2, gap = 8, style, ...rest }) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { style: { display: "grid", gridTemplateColumns: `repeat(${columns}, 1fr)`, gap, ...style }, ...rest, children });
6979
+ var Divider2 = ({ style }) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("hr", { style: { border: "none", borderTop: "1px solid #e2e8f0", margin: "8px 0", ...style } });
6980
+ var Spacer2 = ({ size = 16 }) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { style: { height: size, flexShrink: 0 } });
6981
+ var Text2 = ({ children, size, weight, color, style, ...rest }) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { style: { fontSize: size, fontWeight: weight, color, ...style }, ...rest, children });
6982
+ var Heading2 = ({ children, level = 2, style, ...rest }) => {
4049
6983
  const lvl = Math.min(Math.max(Number(level), 1), 6);
4050
6984
  const s = { margin: "0 0 8px", ...style };
4051
6985
  const c = children;
4052
- if (lvl === 1) return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h1", { style: s, ...rest, children: c });
4053
- if (lvl === 2) return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h2", { style: s, ...rest, children: c });
4054
- if (lvl === 3) return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h3", { style: s, ...rest, children: c });
4055
- if (lvl === 4) return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h4", { style: s, ...rest, children: c });
4056
- if (lvl === 5) return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h5", { style: s, ...rest, children: c });
4057
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h6", { style: s, ...rest, children: c });
6986
+ if (lvl === 1) return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("h1", { style: s, ...rest, children: c });
6987
+ if (lvl === 2) return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("h2", { style: s, ...rest, children: c });
6988
+ if (lvl === 3) return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("h3", { style: s, ...rest, children: c });
6989
+ if (lvl === 4) return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("h4", { style: s, ...rest, children: c });
6990
+ if (lvl === 5) return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("h5", { style: s, ...rest, children: c });
6991
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("h6", { style: s, ...rest, children: c });
4058
6992
  };
4059
- var Field = ({ label, value, children, style }) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: { marginBottom: 8, ...style }, children: [
4060
- label ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: { fontSize: 12, color: "#718096", marginBottom: 2 }, children: label }) : null,
4061
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: { fontSize: 14 }, children: children ?? value ?? "\u2014" })
6993
+ var Field2 = ({ label, value, children, style }) => /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { style: { marginBottom: 8, ...style }, children: [
6994
+ label ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { style: { fontSize: 12, color: "#718096", marginBottom: 2 }, children: label }) : null,
6995
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { style: { fontSize: 14 }, children: children ?? value ?? "\u2014" })
4062
6996
  ] });
4063
- var Badge = ({ children, variant = "default", style }) => {
6997
+ var Badge2 = ({ children, variant = "default", style }) => {
4064
6998
  const colors = {
4065
6999
  default: { bg: "#edf2f7", fg: "#4a5568" },
4066
7000
  success: { bg: "#c6f6d5", fg: "#276749" },
@@ -4069,10 +7003,10 @@ var Badge = ({ children, variant = "default", style }) => {
4069
7003
  info: { bg: "#bee3f8", fg: "#2a4365" }
4070
7004
  };
4071
7005
  const c = colors[variant] ?? colors.default;
4072
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { style: { display: "inline-block", padding: "2px 8px", borderRadius: 9999, fontSize: 12, fontWeight: 500, background: c.bg, color: c.fg, ...style }, children });
7006
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { style: { display: "inline-block", padding: "2px 8px", borderRadius: 9999, fontSize: 12, fontWeight: 500, background: c.bg, color: c.fg, ...style }, children });
4073
7007
  };
4074
- var ImageAtom = ({ src, alt, width, height, style, ...rest }) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("img", { src, alt: alt ?? "", width, height, style: { maxWidth: "100%", ...style }, ...rest });
4075
- var Button = ({ children, onClick, variant = "primary", disabled, style, ...rest }) => {
7008
+ var ImageAtom = ({ src, alt, width, height, style, ...rest }) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("img", { src, alt: alt ?? "", width, height, style: { maxWidth: "100%", ...style }, ...rest });
7009
+ var Button2 = ({ children, onClick, variant = "primary", disabled, style, ...rest }) => {
4076
7010
  const styles = {
4077
7011
  primary: { background: "#3182ce", color: "#fff", border: "none" },
4078
7012
  secondary: { background: "#edf2f7", color: "#4a5568", border: "1px solid #e2e8f0" },
@@ -4080,7 +7014,7 @@ var Button = ({ children, onClick, variant = "primary", disabled, style, ...rest
4080
7014
  ghost: { background: "transparent", color: "#4a5568", border: "none" }
4081
7015
  };
4082
7016
  const base = styles[variant] ?? styles.primary;
4083
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
7017
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
4084
7018
  "button",
4085
7019
  {
4086
7020
  onClick,
@@ -4091,78 +7025,202 @@ var Button = ({ children, onClick, variant = "primary", disabled, style, ...rest
4091
7025
  }
4092
7026
  );
4093
7027
  };
4094
- var LinkAtom = ({ children, href, style, ...rest }) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("a", { href, style: { color: "#3182ce", textDecoration: "underline", ...style }, ...rest, children });
4095
- var TextInput = ({ value, onChange, placeholder, label, style, ...rest }) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: { marginBottom: 8 }, children: [
4096
- label ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("label", { style: { display: "block", fontSize: 12, color: "#718096", marginBottom: 2 }, children: label }) : null,
4097
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
4098
- "input",
4099
- {
4100
- type: "text",
4101
- value: value ?? "",
4102
- onChange,
4103
- placeholder,
4104
- style: { width: "100%", padding: "6px 10px", border: "1px solid #e2e8f0", borderRadius: 6, fontSize: 14, ...style },
4105
- ...rest
4106
- }
4107
- )
4108
- ] });
4109
- var SelectAtom = ({ value, onChange, options, label, placeholder, style }) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: { marginBottom: 8 }, children: [
4110
- label ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("label", { style: { display: "block", fontSize: 12, color: "#718096", marginBottom: 2 }, children: label }) : null,
4111
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
7028
+ var LinkAtom = ({ children, href, style, ...rest }) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("a", { href, style: { color: "#3182ce", textDecoration: "underline", ...style }, ...rest, children });
7029
+ var TextInput2 = ({ value, onChange, placeholder, label, bind: _bind, style }) => {
7030
+ const isControlled = typeof onChange === "function";
7031
+ const [localValue, setLocalValue] = import_react46.default.useState(value ?? "");
7032
+ const handleChange = (e) => {
7033
+ setLocalValue(e.target.value);
7034
+ if (typeof onChange === "function") onChange(e);
7035
+ };
7036
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { style: { marginBottom: 8 }, children: [
7037
+ label ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("label", { style: { display: "block", fontSize: 12, color: "#718096", marginBottom: 2 }, children: label }) : null,
7038
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
7039
+ "input",
7040
+ {
7041
+ type: "text",
7042
+ value: isControlled ? value ?? "" : localValue,
7043
+ onChange: handleChange,
7044
+ placeholder,
7045
+ style: { width: "100%", padding: "6px 10px", border: "1px solid #e2e8f0", borderRadius: 6, fontSize: 14, ...style }
7046
+ }
7047
+ )
7048
+ ] });
7049
+ };
7050
+ var SelectAtom = ({ value, onChange, options, label, placeholder, style }) => /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { style: { marginBottom: 8 }, children: [
7051
+ label ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("label", { style: { display: "block", fontSize: 12, color: "#718096", marginBottom: 2 }, children: label }) : null,
7052
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
4112
7053
  "select",
4113
7054
  {
4114
7055
  value: value ?? "",
4115
7056
  onChange,
4116
7057
  style: { width: "100%", padding: "6px 10px", border: "1px solid #e2e8f0", borderRadius: 6, fontSize: 14, ...style },
4117
7058
  children: [
4118
- placeholder ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("option", { value: "", children: placeholder }) : null,
7059
+ placeholder ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("option", { value: "", children: placeholder }) : null,
4119
7060
  Array.isArray(options) && options.map((opt) => {
4120
7061
  const v = typeof opt === "string" ? opt : opt.value;
4121
7062
  const l = typeof opt === "string" ? opt : opt.label;
4122
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("option", { value: v, children: l }, v);
7063
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("option", { value: v, children: l }, v);
4123
7064
  })
4124
7065
  ]
4125
7066
  }
4126
7067
  )
4127
7068
  ] });
4128
- var Card = ({ children, title, style, ...rest }) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: { border: "1px solid #e2e8f0", borderRadius: 8, padding: 16, background: "#fff", ...style }, ...rest, children: [
4129
- title ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: { fontWeight: 600, fontSize: 16, marginBottom: 12 }, children: title }) : null,
7069
+ var Card2 = ({ children, title, style, ...rest }) => /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { style: { border: "1px solid #e2e8f0", borderRadius: 8, padding: 16, background: "#fff", ...style }, ...rest, children: [
7070
+ title ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { style: { fontWeight: 600, fontSize: 16, marginBottom: 12 }, children: title }) : null,
4130
7071
  children
4131
7072
  ] });
4132
- var Section = ({ children, title, style, ...rest }) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("section", { style: { marginBottom: 24, ...style }, ...rest, children: [
4133
- title ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h3", { style: { fontSize: 18, fontWeight: 600, marginBottom: 8 }, children: title }) : null,
7073
+ var Section2 = ({ children, title, style, ...rest }) => /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("section", { style: { marginBottom: 24, ...style }, ...rest, children: [
7074
+ title ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("h3", { style: { fontSize: 18, fontWeight: 600, marginBottom: 8 }, children: title }) : null,
4134
7075
  children
4135
7076
  ] });
4136
- var Show = ({ when: when2, children, fallback }) => when2 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_jsx_runtime3.Fragment, { children }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_jsx_runtime3.Fragment, { children: fallback ?? null });
4137
- var Each = ({ items, children, renderItem }) => {
7077
+ var Show2 = ({ when: when2, children, fallback }) => when2 ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_jsx_runtime14.Fragment, { children }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_jsx_runtime14.Fragment, { children: fallback ?? null });
7078
+ var Each2 = ({ items, children, renderItem }) => {
4138
7079
  if (!Array.isArray(items)) return null;
4139
- if (typeof renderItem === "function") return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_jsx_runtime3.Fragment, { children: items.map((item, i) => renderItem(item, i)) });
4140
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_jsx_runtime3.Fragment, { children });
7080
+ if (typeof renderItem === "function") return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_jsx_runtime14.Fragment, { children: items.map((item, i) => renderItem(item, i)) });
7081
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_jsx_runtime14.Fragment, { children });
7082
+ };
7083
+ var RouterContext = import_react46.default.createContext({ path: "/", navigate: () => {
7084
+ } });
7085
+ var Router2 = ({ children, basePath, className, style, ...rest }) => {
7086
+ const [path, setPath] = import_react46.default.useState("/");
7087
+ const navigate = import_react46.default.useCallback((to) => setPath(to), []);
7088
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(RouterContext.Provider, { value: { path, navigate }, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className, style, ...rest, children }) });
7089
+ };
7090
+ var Route2 = ({ children, path, exact, fallback: _fallback, className, style }) => {
7091
+ const { path: currentPath } = import_react46.default.useContext(RouterContext);
7092
+ const routePath = path || "/";
7093
+ const isExact = exact !== false;
7094
+ const matches = isExact ? currentPath === routePath || routePath === "/" && currentPath === "/" : currentPath.startsWith(routePath);
7095
+ if (!matches) return null;
7096
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className, style, children });
7097
+ };
7098
+ var NavLink2 = ({ children, to, label, icon, className, style, ...rest }) => {
7099
+ const { path, navigate } = import_react46.default.useContext(RouterContext);
7100
+ const target = to || "/";
7101
+ const isActive = path === target;
7102
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
7103
+ "button",
7104
+ {
7105
+ onClick: () => navigate(target),
7106
+ className,
7107
+ style: {
7108
+ background: isActive ? "#edf2f7" : "transparent",
7109
+ border: "none",
7110
+ borderRadius: 4,
7111
+ padding: "4px 12px",
7112
+ fontSize: 13,
7113
+ cursor: "pointer",
7114
+ fontWeight: isActive ? 600 : 400,
7115
+ color: isActive ? "#2d3748" : "#718096",
7116
+ ...style
7117
+ },
7118
+ ...rest,
7119
+ children: children || label || target
7120
+ }
7121
+ );
7122
+ };
7123
+ var RoleGuard2 = ({ children, role: _role, fallback: _fallback }) => {
7124
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_jsx_runtime14.Fragment, { children });
7125
+ };
7126
+ var Icon2 = ({ name, size = 16, color, style }) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { style: { display: "inline-flex", alignItems: "center", justifyContent: "center", width: size, height: size, fontSize: size, color, ...style }, title: name, children: iconGlyphs[name] || "\u25A1" });
7127
+ var iconGlyphs = {
7128
+ home: "\u2302",
7129
+ settings: "\u2699",
7130
+ plus: "+",
7131
+ search: "\u{1F50D}",
7132
+ box: "\u25A1",
7133
+ inbox: "\u2709",
7134
+ chevronRight: "\u203A",
7135
+ chevronLeft: "\u2039",
7136
+ x: "\u2715",
7137
+ check: "\u2713",
7138
+ edit: "\u270E",
7139
+ trash: "\u{1F5D1}",
7140
+ star: "\u2605",
7141
+ heart: "\u2665",
7142
+ user: "\u{1F464}",
7143
+ menu: "\u2630",
7144
+ close: "\u2715",
7145
+ arrow_right: "\u2192",
7146
+ arrow_left: "\u2190"
7147
+ };
7148
+ var Tabs2 = ({ children, tabs, defaultTab, style }) => {
7149
+ const tabList = tabs || [];
7150
+ const [active, setActive] = import_react46.default.useState(defaultTab || tabList[0]?.id || "");
7151
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { style, children: [
7152
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { style: { display: "flex", borderBottom: "1px solid #e2e8f0", marginBottom: 12 }, children: tabList.map((t) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
7153
+ "button",
7154
+ {
7155
+ onClick: () => setActive(t.id),
7156
+ style: { padding: "6px 16px", border: "none", borderBottom: active === t.id ? "2px solid #3182ce" : "2px solid transparent", background: "none", cursor: "pointer", fontWeight: active === t.id ? 600 : 400, color: active === t.id ? "#3182ce" : "#718096" },
7157
+ children: t.label
7158
+ },
7159
+ t.id
7160
+ )) }),
7161
+ children
7162
+ ] });
4141
7163
  };
7164
+ var Accordion2 = ({ children, style }) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { style, children });
7165
+ var Modal2 = ({ children, open, title, onClose: _onClose, style }) => {
7166
+ if (!open) return null;
7167
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { style: { position: "fixed", inset: 0, background: "rgba(0,0,0,0.5)", display: "flex", alignItems: "center", justifyContent: "center", zIndex: 1e3 }, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { style: { background: "#fff", borderRadius: 12, padding: 24, maxWidth: 480, width: "100%", ...style }, children: [
7168
+ title ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { style: { fontWeight: 600, fontSize: 18, marginBottom: 16 }, children: String(title) }) : null,
7169
+ children
7170
+ ] }) });
7171
+ };
7172
+ var Markdown2 = ({ content, children, style }) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { style: { lineHeight: 1.6, ...style }, children: content || children });
7173
+ var ScrollArea2 = ({ children, maxHeight = 400, style }) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { style: { overflow: "auto", maxHeight, ...style }, children });
7174
+ var Slot2 = ({ children, fallback }) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_jsx_runtime14.Fragment, { children: children || fallback || null });
7175
+ var ModuleOutlet2 = ({ children, module: moduleName, fallback }) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { "data-module": moduleName, children: children || fallback || /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { style: { color: "#a0aec0", fontSize: 13 }, children: [
7176
+ "Module: ",
7177
+ moduleName
7178
+ ] }) });
4142
7179
  var builtinAtoms = {
4143
- Stack,
4144
- Row,
4145
- Column,
4146
- Grid,
4147
- Divider,
4148
- Spacer,
4149
- Text,
4150
- Heading,
4151
- Field,
4152
- Badge,
7180
+ // Layout
7181
+ Stack: Stack2,
7182
+ Row: Row2,
7183
+ Column: Column2,
7184
+ Grid: Grid2,
7185
+ Divider: Divider2,
7186
+ Spacer: Spacer2,
7187
+ // Typography
7188
+ Text: Text2,
7189
+ Heading: Heading2,
7190
+ Field: Field2,
7191
+ Badge: Badge2,
4153
7192
  Image: ImageAtom,
4154
- Button,
7193
+ Icon: Icon2,
7194
+ // Interactive
7195
+ Button: Button2,
4155
7196
  Link: LinkAtom,
4156
- TextInput,
7197
+ // Form
7198
+ TextInput: TextInput2,
4157
7199
  Select: SelectAtom,
4158
- Card,
4159
- Section,
4160
- Show,
4161
- Each
7200
+ // Containers
7201
+ Card: Card2,
7202
+ Section: Section2,
7203
+ Tabs: Tabs2,
7204
+ Accordion: Accordion2,
7205
+ Modal: Modal2,
7206
+ // Content
7207
+ Markdown: Markdown2,
7208
+ ScrollArea: ScrollArea2,
7209
+ // Control Flow
7210
+ Show: Show2,
7211
+ Each: Each2,
7212
+ // Routing
7213
+ Router: Router2,
7214
+ Route: Route2,
7215
+ NavLink: NavLink2,
7216
+ RoleGuard: RoleGuard2,
7217
+ // Composition
7218
+ Slot: Slot2,
7219
+ ModuleOutlet: ModuleOutlet2
4162
7220
  };
4163
7221
 
4164
7222
  // src/player/DevPlayer.tsx
4165
- var import_jsx_runtime4 = require("react/jsx-runtime");
7223
+ var import_jsx_runtime15 = require("react/jsx-runtime");
4166
7224
  var S = {
4167
7225
  shell: {
4168
7226
  display: "flex",
@@ -4257,9 +7315,9 @@ var S = {
4257
7315
  })
4258
7316
  };
4259
7317
  function useDevSocket(wsUrl, onReload) {
4260
- const [connected, setConnected] = (0, import_react36.useState)(false);
4261
- const wsRef = (0, import_react36.useRef)(null);
4262
- (0, import_react36.useEffect)(() => {
7318
+ const [connected, setConnected] = (0, import_react47.useState)(false);
7319
+ const wsRef = (0, import_react47.useRef)(null);
7320
+ (0, import_react47.useEffect)(() => {
4263
7321
  if (typeof window === "undefined") return;
4264
7322
  const url = wsUrl ?? `ws://${window.location.host}/__mm_dev`;
4265
7323
  let ws;
@@ -4305,15 +7363,15 @@ var DevPlayer = ({
4305
7363
  onReload,
4306
7364
  onEvent: externalOnEvent
4307
7365
  }) => {
4308
- const [showSidebar, setShowSidebar] = (0, import_react36.useState)(true);
4309
- const [events, setEvents] = (0, import_react36.useState)([]);
4310
- const nextId = (0, import_react36.useRef)(0);
7366
+ const [showSidebar, setShowSidebar] = (0, import_react47.useState)(true);
7367
+ const [events, setEvents] = (0, import_react47.useState)([]);
7368
+ const nextId = (0, import_react47.useRef)(0);
4311
7369
  const connected = useDevSocket(wsUrl, onReload);
4312
- const mergedAtoms = (0, import_react36.useMemo)(
7370
+ const mergedAtoms = (0, import_react47.useMemo)(
4313
7371
  () => ({ ...builtinAtoms, ...userAtoms }),
4314
7372
  [userAtoms]
4315
7373
  );
4316
- const handleEvent = (0, import_react36.useCallback)(
7374
+ const handleEvent = (0, import_react47.useCallback)(
4317
7375
  (name, payload) => {
4318
7376
  setEvents((prev) => {
4319
7377
  const entry = {
@@ -4330,7 +7388,7 @@ var DevPlayer = ({
4330
7388
  [externalOnEvent]
4331
7389
  );
4332
7390
  if (bare) {
4333
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
7391
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
4334
7392
  ComponentTreeRenderer,
4335
7393
  {
4336
7394
  tree,
@@ -4340,21 +7398,21 @@ var DevPlayer = ({
4340
7398
  }
4341
7399
  );
4342
7400
  }
4343
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: S.shell, children: [
4344
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: S.toolbar, children: [
4345
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: S.dot(connected), title: connected ? "HMR connected" : "HMR disconnected" }),
4346
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { style: S.toolbarTitle, children: title }),
4347
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { style: S.toolbarBadge, children: [
7401
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { style: S.shell, children: [
7402
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { style: S.toolbar, children: [
7403
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { style: S.dot(connected), title: connected ? "HMR connected" : "HMR disconnected" }),
7404
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { style: S.toolbarTitle, children: title }),
7405
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("span", { style: S.toolbarBadge, children: [
4348
7406
  Array.isArray(tree) ? tree.length : 1,
4349
7407
  " node",
4350
7408
  Array.isArray(tree) && tree.length !== 1 ? "s" : ""
4351
7409
  ] }),
4352
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { style: S.toolbarBadge, children: [
7410
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("span", { style: S.toolbarBadge, children: [
4353
7411
  Object.keys(mergedAtoms).length,
4354
7412
  " atoms"
4355
7413
  ] }),
4356
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: { flex: 1 } }),
4357
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
7414
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { style: { flex: 1 } }),
7415
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
4358
7416
  "button",
4359
7417
  {
4360
7418
  style: { ...S.toolbarBtn, ...showSidebar ? S.toolbarBtnActive : {} },
@@ -4363,8 +7421,8 @@ var DevPlayer = ({
4363
7421
  }
4364
7422
  )
4365
7423
  ] }),
4366
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: S.body, children: [
4367
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: S.preview, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
7424
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { style: S.body, children: [
7425
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { style: S.preview, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
4368
7426
  ComponentTreeRenderer,
4369
7427
  {
4370
7428
  tree,
@@ -4373,18 +7431,18 @@ var DevPlayer = ({
4373
7431
  onEvent: handleEvent
4374
7432
  }
4375
7433
  ) }),
4376
- showSidebar && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: S.sidebar, children: [
4377
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: S.sidebarSection, children: [
4378
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: S.sidebarHeading, children: "Scopes" }),
4379
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("pre", { style: S.pre, children: JSON.stringify(scopes, null, 2) })
7434
+ showSidebar && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { style: S.sidebar, children: [
7435
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { style: S.sidebarSection, children: [
7436
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { style: S.sidebarHeading, children: "Scopes" }),
7437
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("pre", { style: S.pre, children: JSON.stringify(scopes, null, 2) })
4380
7438
  ] }),
4381
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: S.sidebarSection, children: [
4382
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: S.sidebarHeading, children: [
7439
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { style: S.sidebarSection, children: [
7440
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { style: S.sidebarHeading, children: [
4383
7441
  "Atoms (",
4384
7442
  Object.keys(mergedAtoms).length,
4385
7443
  ")"
4386
7444
  ] }),
4387
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: { display: "flex", flexWrap: "wrap", gap: 4 }, children: Object.keys(mergedAtoms).sort().map((name) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
7445
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { style: { display: "flex", flexWrap: "wrap", gap: 4 }, children: Object.keys(mergedAtoms).sort().map((name) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
4388
7446
  "span",
4389
7447
  {
4390
7448
  style: {
@@ -4402,14 +7460,14 @@ var DevPlayer = ({
4402
7460
  name
4403
7461
  )) })
4404
7462
  ] }),
4405
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: S.sidebarSection, children: [
4406
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 8 }, children: [
4407
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: S.sidebarHeading, children: [
7463
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { style: S.sidebarSection, children: [
7464
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 8 }, children: [
7465
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { style: S.sidebarHeading, children: [
4408
7466
  "Events (",
4409
7467
  events.length,
4410
7468
  ")"
4411
7469
  ] }),
4412
- events.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
7470
+ events.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
4413
7471
  "button",
4414
7472
  {
4415
7473
  style: { background: "none", border: "none", color: "#a0aec0", fontSize: 11, cursor: "pointer" },
@@ -4418,16 +7476,16 @@ var DevPlayer = ({
4418
7476
  }
4419
7477
  )
4420
7478
  ] }),
4421
- events.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: { color: "#a0aec0", fontSize: 12, fontStyle: "italic" }, children: "No events yet" }),
4422
- events.slice(0, 50).map((e) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: S.eventRow, children: [
4423
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { style: S.eventTime, children: e.time }),
4424
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { style: S.eventName, children: e.name }),
4425
- e.payload !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { style: { color: "#718096", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, children: JSON.stringify(e.payload) })
7479
+ events.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { style: { color: "#a0aec0", fontSize: 12, fontStyle: "italic" }, children: "No events yet" }),
7480
+ events.slice(0, 50).map((e) => /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { style: S.eventRow, children: [
7481
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { style: S.eventTime, children: e.time }),
7482
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { style: S.eventName, children: e.name }),
7483
+ e.payload !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { style: { color: "#718096", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, children: JSON.stringify(e.payload) })
4426
7484
  ] }, e.id))
4427
7485
  ] }),
4428
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: S.sidebarSection, children: [
4429
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: S.sidebarHeading, children: "Tree (JSON)" }),
4430
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("pre", { style: { ...S.pre, maxHeight: 400 }, children: JSON.stringify(tree, null, 2) })
7486
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { style: S.sidebarSection, children: [
7487
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { style: S.sidebarHeading, children: "Tree (JSON)" }),
7488
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("pre", { style: { ...S.pre, maxHeight: 400 }, children: JSON.stringify(tree, null, 2) })
4431
7489
  ] })
4432
7490
  ] })
4433
7491
  ] })
@@ -4444,39 +7502,39 @@ function stub(displayName) {
4444
7502
  Component.displayName = displayName;
4445
7503
  return Component;
4446
7504
  }
4447
- var Stack2 = stub("Stack");
4448
- var Row2 = stub("Row");
4449
- var Column2 = stub("Column");
4450
- var Grid2 = stub("Grid");
4451
- var Divider2 = stub("Divider");
4452
- var Spacer2 = stub("Spacer");
4453
- var Text2 = stub("Text");
4454
- var Heading2 = stub("Heading");
4455
- var Field2 = stub("Field");
4456
- var Image = stub("Image");
4457
- var Badge2 = stub("Badge");
4458
- var Icon = stub("Icon");
4459
- var Button2 = stub("Button");
4460
- var Link = stub("Link");
4461
- var Show2 = stub("Show");
4462
- var Each2 = stub("Each");
4463
- var Card2 = stub("Card");
4464
- var Tabs = stub("Tabs");
4465
- var Accordion = stub("Accordion");
4466
- var Section2 = stub("Section");
4467
- var Modal = stub("Modal");
4468
- var TextInput2 = stub("TextInput");
4469
- var Select = stub("Select");
4470
- var Markdown = stub("Markdown");
4471
- var ScrollArea = stub("ScrollArea");
7505
+ var Stack3 = stub("Stack");
7506
+ var Row3 = stub("Row");
7507
+ var Column3 = stub("Column");
7508
+ var Grid3 = stub("Grid");
7509
+ var Divider3 = stub("Divider");
7510
+ var Spacer3 = stub("Spacer");
7511
+ var Text3 = stub("Text");
7512
+ var Heading3 = stub("Heading");
7513
+ var Field3 = stub("Field");
7514
+ var Image2 = stub("Image");
7515
+ var Badge3 = stub("Badge");
7516
+ var Icon3 = stub("Icon");
7517
+ var Button3 = stub("Button");
7518
+ var Link2 = stub("Link");
7519
+ var Show3 = stub("Show");
7520
+ var Each3 = stub("Each");
7521
+ var Card3 = stub("Card");
7522
+ var Tabs3 = stub("Tabs");
7523
+ var Accordion3 = stub("Accordion");
7524
+ var Section3 = stub("Section");
7525
+ var Modal3 = stub("Modal");
7526
+ var TextInput3 = stub("TextInput");
7527
+ var Select2 = stub("Select");
7528
+ var Markdown3 = stub("Markdown");
7529
+ var ScrollArea3 = stub("ScrollArea");
4472
7530
  var Canvas3D = stub("Canvas3D");
4473
- var DataGrid = stub("DataGrid");
7531
+ var DataGrid2 = stub("DataGrid");
4474
7532
  var AnimatedBox = stub("AnimatedBox");
4475
7533
  var ServerGrid = stub("ServerGrid");
4476
7534
  var Chart = stub("Chart");
4477
7535
  var MetricCard = stub("MetricCard");
4478
- var Slot = stub("Slot");
4479
- var ModuleOutlet = stub("ModuleOutlet");
7536
+ var Slot3 = stub("Slot");
7537
+ var ModuleOutlet3 = stub("ModuleOutlet");
4480
7538
  var MetricsGrid = stub("MetricsGrid");
4481
7539
  var AdaptiveCardGrid = stub("AdaptiveCardGrid");
4482
7540
  var AdaptiveFilters = stub("AdaptiveFilters");
@@ -4493,10 +7551,10 @@ var HierarchyBreadcrumb = stub("HierarchyBreadcrumb");
4493
7551
  var SearchInput = stub("SearchInput");
4494
7552
  var SortControl = stub("SortControl");
4495
7553
  var AggregateStats = stub("AggregateStats");
4496
- var Router = stub("Router");
4497
- var Route = stub("Route");
4498
- var NavLink = stub("NavLink");
4499
- var RoleGuard = stub("RoleGuard");
7554
+ var Router3 = stub("Router");
7555
+ var Route3 = stub("Route");
7556
+ var NavLink3 = stub("NavLink");
7557
+ var RoleGuard3 = stub("RoleGuard");
4500
7558
 
4501
7559
  // src/grammar/index.ts
4502
7560
  function createIsland(contextTag, strings, values) {
@@ -4565,7 +7623,7 @@ function djb2Hash(str) {
4565
7623
  }
4566
7624
 
4567
7625
  // src/authoring.ts
4568
- function useState22(_defaultOrKey) {
7626
+ function useState28(_defaultOrKey) {
4569
7627
  return [void 0, () => {
4570
7628
  }];
4571
7629
  }
@@ -4576,10 +7634,10 @@ function defineWorkspace(config) {
4576
7634
  }
4577
7635
 
4578
7636
  // src/hooks/useModule.ts
4579
- var import_react37 = require("react");
7637
+ var import_react48 = require("react");
4580
7638
  function useModule(slug, config = {}, options = {}) {
4581
7639
  const { enabled = true } = options;
4582
- return (0, import_react37.useMemo)(() => ({
7640
+ return (0, import_react48.useMemo)(() => ({
4583
7641
  slug,
4584
7642
  config,
4585
7643
  isLoaded: enabled
@@ -4587,7 +7645,7 @@ function useModule(slug, config = {}, options = {}) {
4587
7645
  }
4588
7646
 
4589
7647
  // src/hooks/useModuleConfig.ts
4590
- var import_react38 = require("react");
7648
+ var import_react49 = require("react");
4591
7649
  var installedModulesStore = [];
4592
7650
  var configDefaultsStore = /* @__PURE__ */ new Map();
4593
7651
  function setInstalledModules(modules) {
@@ -4603,7 +7661,7 @@ function getInstalledModules() {
4603
7661
  return installedModulesStore;
4604
7662
  }
4605
7663
  function useModuleConfig(moduleSlug) {
4606
- return (0, import_react38.useMemo)(() => {
7664
+ return (0, import_react49.useMemo)(() => {
4607
7665
  const installed = getInstalledModule(moduleSlug);
4608
7666
  const defaults = configDefaultsStore.get(moduleSlug) ?? {};
4609
7667
  const persisted = persistedConfigStore.get(moduleSlug) ?? {};
@@ -4651,8 +7709,8 @@ async function updateDefinitionConfig(values, definitionId) {
4651
7709
  }
4652
7710
  function useModuleConfigWithMutation(moduleSlug) {
4653
7711
  const config = useModuleConfig(moduleSlug);
4654
- const [isSaving, setIsSaving] = (0, import_react38.useState)(false);
4655
- const updateConfig = (0, import_react38.useCallback)(async (values) => {
7712
+ const [isSaving, setIsSaving] = (0, import_react49.useState)(false);
7713
+ const updateConfig = (0, import_react49.useCallback)(async (values) => {
4656
7714
  setIsSaving(true);
4657
7715
  try {
4658
7716
  return await updateDefinitionConfig(values);
@@ -6855,7 +9913,7 @@ function describeModel(def) {
6855
9913
  }
6856
9914
 
6857
9915
  // src/hooks/usePlayer.ts
6858
- var import_react39 = require("react");
9916
+ var import_react50 = require("react");
6859
9917
  var import_player_core2 = require("@mmapp/player-core");
6860
9918
 
6861
9919
  // src/logger.ts
@@ -6896,18 +9954,18 @@ function computePlayerState(sm) {
6896
9954
  };
6897
9955
  }
6898
9956
  function usePlayer(config) {
6899
- const configRef = (0, import_react39.useRef)(config);
9957
+ const configRef = (0, import_react50.useRef)(config);
6900
9958
  configRef.current = config;
6901
- (0, import_react39.useEffect)(() => {
9959
+ (0, import_react50.useEffect)(() => {
6902
9960
  if (config.debug) setPlayerDebug(true);
6903
9961
  }, [config.debug]);
6904
- const evaluator = (0, import_react39.useMemo)(() => {
9962
+ const evaluator = (0, import_react50.useMemo)(() => {
6905
9963
  return (0, import_player_core2.createEvaluator)({
6906
9964
  functions: config.functions ?? [],
6907
9965
  failurePolicy: import_player_core2.WEB_FAILURE_POLICIES.EVENT_REACTION
6908
9966
  });
6909
9967
  }, [config.definition.id]);
6910
- const engine = (0, import_react39.useMemo)(() => {
9968
+ const engine = (0, import_react50.useMemo)(() => {
6911
9969
  const actionHandlers = /* @__PURE__ */ new Map();
6912
9970
  if (config.actionHandlers) {
6913
9971
  for (const [type, handler] of Object.entries(config.actionHandlers)) {
@@ -6961,8 +10019,8 @@ function usePlayer(config) {
6961
10019
  return { sm: sm2, eventBus: eventBus2, dispatcher };
6962
10020
  }, [config.definition.id, evaluator]);
6963
10021
  const { sm, eventBus } = engine;
6964
- const [playerState, setPlayerState] = (0, import_react39.useState)(() => computePlayerState(sm));
6965
- (0, import_react39.useEffect)(() => {
10022
+ const [playerState, setPlayerState] = (0, import_react50.useState)(() => computePlayerState(sm));
10023
+ (0, import_react50.useEffect)(() => {
6966
10024
  const stateDef = sm.getCurrentStateDefinition();
6967
10025
  if (!stateDef?.on_event?.length) return;
6968
10026
  const unsubs = [];
@@ -7026,7 +10084,7 @@ function usePlayer(config) {
7026
10084
  for (const unsub of unsubs) unsub();
7027
10085
  };
7028
10086
  }, [sm, eventBus, evaluator, engine.dispatcher, playerState.currentState]);
7029
- (0, import_react39.useEffect)(() => {
10087
+ (0, import_react50.useEffect)(() => {
7030
10088
  const unsub = sm.on((event) => {
7031
10089
  if (event.type === "transition" || event.type === "state_enter") {
7032
10090
  setPlayerState(computePlayerState(sm));
@@ -7042,7 +10100,7 @@ function usePlayer(config) {
7042
10100
  });
7043
10101
  return unsub;
7044
10102
  }, [sm]);
7045
- const transition2 = (0, import_react39.useCallback)(
10103
+ const transition2 = (0, import_react50.useCallback)(
7046
10104
  async (name, data) => {
7047
10105
  playerLog({
7048
10106
  level: "info",
@@ -7069,20 +10127,20 @@ function usePlayer(config) {
7069
10127
  },
7070
10128
  [sm]
7071
10129
  );
7072
- const setField2 = (0, import_react39.useCallback)(
10130
+ const setField2 = (0, import_react50.useCallback)(
7073
10131
  (field2, value) => {
7074
10132
  sm.setField(field2, value);
7075
10133
  setPlayerState(computePlayerState(sm));
7076
10134
  },
7077
10135
  [sm]
7078
10136
  );
7079
- const setMemory = (0, import_react39.useCallback)(
10137
+ const setMemory = (0, import_react50.useCallback)(
7080
10138
  (key, value) => {
7081
10139
  sm.setMemory(key, value);
7082
10140
  },
7083
10141
  [sm]
7084
10142
  );
7085
- const publishEvent = (0, import_react39.useCallback)(
10143
+ const publishEvent = (0, import_react50.useCallback)(
7086
10144
  (topic, payload) => {
7087
10145
  playerLog({
7088
10146
  level: "debug",
@@ -7108,11 +10166,11 @@ function usePlayer(config) {
7108
10166
  }
7109
10167
 
7110
10168
  // src/hooks/useDomainSubscription.ts
7111
- var import_react40 = require("react");
10169
+ var import_react51 = require("react");
7112
10170
  function useDomainSubscription(eventBus, transport, config) {
7113
- const configRef = (0, import_react40.useRef)(config);
10171
+ const configRef = (0, import_react51.useRef)(config);
7114
10172
  configRef.current = config;
7115
- (0, import_react40.useEffect)(() => {
10173
+ (0, import_react51.useEffect)(() => {
7116
10174
  if (!transport || config.enabled === false) return;
7117
10175
  const unsub = transport.subscribe(
7118
10176
  {
@@ -7165,11 +10223,11 @@ function useDomainSubscription(eventBus, transport, config) {
7165
10223
  }
7166
10224
 
7167
10225
  // src/hooks/useExperienceState.ts
7168
- var import_react41 = require("react");
10226
+ var import_react52 = require("react");
7169
10227
  function useExperienceState(player, selector) {
7170
- const selectorRef = (0, import_react41.useRef)(selector);
10228
+ const selectorRef = (0, import_react52.useRef)(selector);
7171
10229
  selectorRef.current = selector;
7172
- const getSnapshot = (0, import_react41.useCallback)(() => {
10230
+ const getSnapshot = (0, import_react52.useCallback)(() => {
7173
10231
  return selectorRef.current({
7174
10232
  currentState: player.currentState,
7175
10233
  stateData: player.stateData,
@@ -7185,20 +10243,20 @@ function useStateField(player, field2, defaultValue) {
7185
10243
  }
7186
10244
 
7187
10245
  // src/hooks/useComputed.ts
7188
- var import_react42 = require("react");
10246
+ var import_react53 = require("react");
7189
10247
  function useComputed(_name, compute, options) {
7190
10248
  const mode = options?.mode ?? "read-time";
7191
10249
  const deps = options?.deps ?? [];
7192
- const computeRef = (0, import_react42.useRef)(compute);
10250
+ const computeRef = (0, import_react53.useRef)(compute);
7193
10251
  computeRef.current = compute;
7194
10252
  if (mode === "read-time") {
7195
- return (0, import_react42.useMemo)(() => computeRef.current(), [
10253
+ return (0, import_react53.useMemo)(() => computeRef.current(), [
7196
10254
  // We intentionally depend on deps.join to recompute when tracked fields change
7197
10255
  // The actual dependency tracking happens at the compiler level
7198
10256
  deps.join(",")
7199
10257
  ]);
7200
10258
  }
7201
- return (0, import_react42.useMemo)(() => computeRef.current(), [deps.join(",")]);
10259
+ return (0, import_react53.useMemo)(() => computeRef.current(), [deps.join(",")]);
7202
10260
  }
7203
10261
  function useComputedWithMeta(name, compute, options) {
7204
10262
  const value = useComputed(name, compute, options);
@@ -7213,26 +10271,19 @@ function useComputedWithMeta(name, compute, options) {
7213
10271
  }
7214
10272
 
7215
10273
  // src/components/PlayerProvider.tsx
7216
- var import_react43 = require("react");
7217
- var import_jsx_runtime5 = require("react/jsx-runtime");
7218
- var PlayerContext = (0, import_react43.createContext)(null);
7219
- function PlayerProvider({ player, children }) {
7220
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(PlayerContext.Provider, { value: player, children });
7221
- }
7222
- function usePlayerContext() {
7223
- const ctx = (0, import_react43.useContext)(PlayerContext);
7224
- if (!ctx) {
7225
- throw new Error("usePlayerContext must be used within a <PlayerProvider>");
7226
- }
7227
- return ctx;
10274
+ var import_react54 = require("react");
10275
+ var import_jsx_runtime16 = require("react/jsx-runtime");
10276
+ var PlayerContext2 = (0, import_react54.createContext)(null);
10277
+ function PlayerProvider2({ player, children }) {
10278
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(PlayerContext2.Provider, { value: player, children });
7228
10279
  }
7229
10280
  function usePlayerContextSafe() {
7230
- return (0, import_react43.useContext)(PlayerContext);
10281
+ return (0, import_react54.useContext)(PlayerContext2);
7231
10282
  }
7232
10283
 
7233
10284
  // src/components/ExperienceWorkflowBridge.tsx
7234
- var import_react44 = require("react");
7235
- var import_jsx_runtime6 = require("react/jsx-runtime");
10285
+ var import_react55 = require("react");
10286
+ var import_jsx_runtime17 = require("react/jsx-runtime");
7236
10287
  function ExperienceWorkflowBridgeInner({
7237
10288
  definition,
7238
10289
  initialData,
@@ -7249,12 +10300,12 @@ function ExperienceWorkflowBridgeInner({
7249
10300
  actionHandlers,
7250
10301
  debug
7251
10302
  });
7252
- const viewConfig = (0, import_react44.useMemo)(() => {
10303
+ const viewConfig = (0, import_react55.useMemo)(() => {
7253
10304
  if (!definition.state_views) return void 0;
7254
10305
  return definition.state_views[player.currentState];
7255
10306
  }, [definition.state_views, player.currentState]);
7256
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(PlayerProvider, { player, children: [
7257
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
10307
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(PlayerProvider2, { player, children: [
10308
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
7258
10309
  DomainSubscriptionBridge,
7259
10310
  {
7260
10311
  player,
@@ -7280,12 +10331,12 @@ function DomainSubscriptionBridge({
7280
10331
  return null;
7281
10332
  }
7282
10333
  function ExperienceWorkflowBridge(props) {
7283
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ExperienceWorkflowBridgeInner, { ...props });
10334
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(ExperienceWorkflowBridgeInner, { ...props });
7284
10335
  }
7285
10336
 
7286
10337
  // src/components/atoms/index.tsx
7287
- var import_react45 = __toESM(require("react"));
7288
- var import_jsx_runtime7 = require("react/jsx-runtime");
10338
+ var import_react56 = __toESM(require("react"));
10339
+ var import_jsx_runtime18 = require("react/jsx-runtime");
7289
10340
 
7290
10341
  // src/loader/experience-workflow-loader.ts
7291
10342
  function validateExperienceWorkflow(def) {
@@ -8337,6 +11388,7 @@ var instance = compileTimeProxy("instance");
8337
11388
  0 && (module.exports = {
8338
11389
  Accordion,
8339
11390
  AnimatedBox,
11391
+ AtomRegistryImpl,
8340
11392
  BUILT_IN_CONSTRAINTS,
8341
11393
  Badge,
8342
11394
  Blueprint,
@@ -8351,6 +11403,7 @@ var instance = compileTimeProxy("instance");
8351
11403
  DevPlayer,
8352
11404
  Divider,
8353
11405
  Each,
11406
+ ExperienceRenderer,
8354
11407
  ExperienceWorkflowBridge,
8355
11408
  Field,
8356
11409
  FieldBuilder,
@@ -8373,6 +11426,7 @@ var instance = compileTimeProxy("instance");
8373
11426
  Router,
8374
11427
  Row,
8375
11428
  RuntimeContext,
11429
+ ScopeContext,
8376
11430
  ScrollArea,
8377
11431
  Section,
8378
11432
  Select,
@@ -8397,7 +11451,12 @@ var instance = compileTimeProxy("instance");
8397
11451
  applyMixins,
8398
11452
  approval,
8399
11453
  assertModelValid,
11454
+ buildActionScope,
11455
+ buildEvalContext,
11456
+ buildLoopScope,
11457
+ buildScope,
8400
11458
  builtinAtoms,
11459
+ builtinFunctions,
8401
11460
  cedar,
8402
11461
  compose,
8403
11462
  computeVisibility,
@@ -8405,7 +11464,9 @@ var instance = compileTimeProxy("instance");
8405
11464
  connector,
8406
11465
  constraints,
8407
11466
  createActions,
11467
+ createApiResolver,
8408
11468
  createCRUD,
11469
+ createCoreAtomRegistry,
8409
11470
  createLocalDataResolver,
8410
11471
  createLocalEngineAdapter,
8411
11472
  createPipeline,
@@ -8469,6 +11530,8 @@ var instance = compileTimeProxy("instance");
8469
11530
  llm,
8470
11531
  loadExperienceWorkflow,
8471
11532
  logEvent,
11533
+ mergeRegistries,
11534
+ mergeScope,
8472
11535
  model,
8473
11536
  named,
8474
11537
  normalizeDefinition,
@@ -8480,6 +11543,7 @@ var instance = compileTimeProxy("instance");
8480
11543
  orchestration,
8481
11544
  patch,
8482
11545
  pipe,
11546
+ playerEvaluateExpression,
8483
11547
  playerLog,
8484
11548
  prefetchData,
8485
11549
  refHasAnyRole,
@@ -8487,6 +11551,8 @@ var instance = compileTimeProxy("instance");
8487
11551
  requireAuth,
8488
11552
  requireField,
8489
11553
  requireRole,
11554
+ resolveAllBindings,
11555
+ resolveBinding,
8490
11556
  resolveOrchestration,
8491
11557
  restrict,
8492
11558
  review,
@@ -8556,6 +11622,7 @@ var instance = compileTimeProxy("instance");
8556
11622
  useRouteParams,
8557
11623
  useRouter,
8558
11624
  useRuntimeContext,
11625
+ useScope,
8559
11626
  useServerAction,
8560
11627
  useServerState,
8561
11628
  useStateField,