@almadar/ui 5.113.0 → 5.114.0

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.
@@ -12,6 +12,8 @@ import { createPortal } from 'react-dom';
12
12
  import { useTranslate } from '@almadar/ui/hooks';
13
13
  import { useUISlots, UISlotProvider, useTheme } from '@almadar/ui/context';
14
14
  import { evaluateGuard, evaluate, createMinimalContext, executeEffects } from '@almadar/evaluator';
15
+ import { wrapCallbackForEvent, prepareSchemaForPreview, perfStore, pushPerfEntry, collectTraitRefsFromResolvedTrait, buildOrbitalsByTrait, collectEmbeddedTraits } from '@almadar/runtime/ui';
16
+ export { PERF_NAMESPACE, adjustSchemaForMockData, buildMockData, clearPerf, perfEnd, perfStart, perfTime, prepareSchemaForPreview, wrapCallbackForEvent } from '@almadar/runtime/ui';
15
17
  import { Link, Outlet, useLocation } from 'react-router-dom';
16
18
  import ELK from 'elkjs/lib/elk.bundled.js';
17
19
  import SyntaxHighlighter from 'react-syntax-highlighter/dist/esm/prism-light.js';
@@ -37,13 +39,14 @@ import ReactMarkdown from 'react-markdown';
37
39
  import remarkGfm from 'remark-gfm';
38
40
  import remarkMath from 'remark-math';
39
41
  import rehypeKatex from 'rehype-katex';
40
- import { isCircuitEvent, schemaToIR, getPage, clearSchemaCache as clearSchemaCache$1, isEntityCall, walkSExpr, mergeEntityFrame, isInlineTrait } from '@almadar/core';
42
+ import { isCircuitEvent, schemaToIR, getPage, clearSchemaCache as clearSchemaCache$1, walkSExpr, buildResolvedTraitConfigs, mergeEntityFrame, isInlineTrait, isSExpr, isEventPayloadValue } from '@almadar/core';
41
43
  import { DndContext, pointerWithin, rectIntersection, closestCorners, useSensors, useSensor, PointerSensor, KeyboardSensor, useDroppable } from '@dnd-kit/core';
42
44
  import { useSortable, arrayMove, sortableKeyboardCoordinates, SortableContext, rectSortingStrategy, verticalListSortingStrategy } from '@dnd-kit/sortable';
43
45
  import { CSS } from '@dnd-kit/utilities';
44
46
  import { useNodeId, ReactFlowProvider, Handle, Position } from '@xyflow/react';
45
47
  import { isDrawHostPattern, getPatternDefinition, getComponentForPattern as getComponentForPattern$1 } from '@almadar/core/patterns';
46
- import { StateMachineManager, collectDeclaredConfigDefaults, createServerEffectHandlers, EffectExecutor, createContextFromBindings, createTickScheduler, isValidCronExpression, parseDurationString, InMemoryPersistence, normalizeCallSiteConfigToValues } from '@almadar/runtime';
48
+ import { StateMachineManager, collectDeclaredConfigDefaults, resolveCallSitePayloadCaptures, createServerEffectHandlers, EffectExecutor, createContextFromBindings, createTickScheduler, isValidCronExpression, parseDurationString, InMemoryPersistence, normalizeCallSiteConfigToValues } from '@almadar/runtime';
49
+ import { isKnownStdOperator } from '@almadar/std/registry';
47
50
  import { OrbitalServerRuntime } from '@almadar/runtime/OrbitalServerRuntime';
48
51
 
49
52
  var __defProp = Object.defineProperty;
@@ -1017,41 +1020,6 @@ function kebabToPascal(name) {
1017
1020
  return part.charAt(0).toUpperCase() + part.slice(1);
1018
1021
  }).join("");
1019
1022
  }
1020
- function loadLib(key, importer) {
1021
- let p = libPromises.get(key);
1022
- if (!p) {
1023
- p = importer();
1024
- libPromises.set(key, p);
1025
- }
1026
- return p;
1027
- }
1028
- function lazyFamilyIcon(libKey, importer, pick, fallbackName, family) {
1029
- const Lazy = React81__default.lazy(async () => {
1030
- const lib = await loadLib(libKey, importer);
1031
- const Comp = pick(lib);
1032
- if (!Comp) {
1033
- warnFallback(fallbackName, family);
1034
- return { default: makeLucideAdapter(fallbackName, true) };
1035
- }
1036
- return { default: Comp };
1037
- });
1038
- const Wrapped = (props) => /* @__PURE__ */ jsx(
1039
- React81__default.Suspense,
1040
- {
1041
- fallback: /* @__PURE__ */ jsx(
1042
- "span",
1043
- {
1044
- "aria-hidden": true,
1045
- className: props.className,
1046
- style: { display: "inline-block", ...props.style }
1047
- }
1048
- ),
1049
- children: /* @__PURE__ */ jsx(Lazy, { ...props })
1050
- }
1051
- );
1052
- Wrapped.displayName = `Lazy.${libKey}.${fallbackName}`;
1053
- return Wrapped;
1054
- }
1055
1023
  function isComponentLike(v) {
1056
1024
  return v != null && (typeof v === "function" || typeof v === "object");
1057
1025
  }
@@ -1065,146 +1033,32 @@ function resolveLucide(name) {
1065
1033
  if (isComponentLike(asIs)) return asIs;
1066
1034
  return LucideIcons2.HelpCircle;
1067
1035
  }
1068
- function resolvePhosphor(name, weight, family) {
1069
- const target = phosphorAliases[name] ?? kebabToPascal(name);
1070
- return lazyFamilyIcon(
1071
- "phosphor",
1072
- () => import('@phosphor-icons/react'),
1073
- (lib) => {
1074
- const PhosphorComp = lib[target];
1075
- if (!PhosphorComp) return null;
1076
- const Component = PhosphorComp;
1077
- const Adapter = (props) => /* @__PURE__ */ jsx(
1078
- Component,
1079
- {
1080
- weight,
1081
- className: props.className,
1082
- style: props.style,
1083
- size: props.size ?? "1em"
1084
- }
1085
- );
1086
- Adapter.displayName = `Phosphor.${target}.${weight}`;
1087
- return Adapter;
1088
- },
1089
- name,
1090
- family
1091
- );
1092
- }
1093
- function resolveTabler(name, family) {
1094
- const suffix = tablerAliases[name] ?? kebabToPascal(name);
1095
- const target = `Icon${suffix}`;
1096
- return lazyFamilyIcon(
1097
- "tabler",
1098
- () => import('@tabler/icons-react'),
1099
- (lib) => {
1100
- const TablerComp = lib[target];
1101
- if (!TablerComp) return null;
1102
- const Component = TablerComp;
1103
- const Adapter = (props) => /* @__PURE__ */ jsx(
1104
- Component,
1105
- {
1106
- stroke: props.strokeWidth ?? 1.5,
1107
- className: props.className,
1108
- style: props.style,
1109
- size: props.size ?? 24
1110
- }
1111
- );
1112
- Adapter.displayName = `Tabler.${target}`;
1113
- return Adapter;
1114
- },
1115
- name,
1116
- family
1117
- );
1118
- }
1119
- function resolveFa(name, family) {
1120
- const suffix = faAliases[name] ?? kebabToPascal(name);
1121
- const target = `Fa${suffix}`;
1122
- return lazyFamilyIcon(
1123
- "fa",
1124
- () => import('react-icons/fa'),
1125
- (lib) => {
1126
- const FaComp = lib[target];
1127
- if (!FaComp) return null;
1128
- const Component = FaComp;
1129
- const Adapter = (props) => /* @__PURE__ */ jsx(
1130
- Component,
1131
- {
1132
- className: props.className,
1133
- style: props.style,
1134
- size: props.size ?? "1em"
1135
- }
1136
- );
1137
- Adapter.displayName = `Fa.${target}`;
1138
- return Adapter;
1139
- },
1140
- name,
1141
- family
1142
- );
1143
- }
1144
- function warnFallback(name, family) {
1145
- const key = `${family}::${name}`;
1146
- if (warned.has(key)) return;
1147
- warned.add(key);
1148
- if (typeof console !== "undefined") {
1149
- console.warn(
1150
- `[iconFamily] No '${name}' mapping in family '${family}'; falling back to lucide. Add an alias in lib/iconFamily.ts.`
1151
- );
1152
- }
1153
- }
1154
- function makeLucideAdapter(name, isFallback = false) {
1036
+ function makeLucideAdapter(name) {
1155
1037
  const LucideComp = resolveLucide(name);
1156
- const Adapter = (props) => {
1157
- const stroke = props.strokeWidth ?? (isFallback ? 2 : void 0);
1158
- const style = isFallback ? { ...props.style ?? {}, strokeWidth: stroke ?? 2 } : props.style;
1159
- return /* @__PURE__ */ jsx(
1160
- LucideComp,
1161
- {
1162
- className: props.className,
1163
- strokeWidth: stroke,
1164
- style,
1165
- size: props.size
1166
- }
1167
- );
1168
- };
1169
- Adapter.displayName = `Lucide.${name}${isFallback ? ".fallback" : ""}`;
1038
+ const Adapter = (props) => /* @__PURE__ */ jsx(
1039
+ LucideComp,
1040
+ {
1041
+ className: props.className,
1042
+ strokeWidth: props.strokeWidth,
1043
+ style: props.style,
1044
+ size: props.size
1045
+ }
1046
+ );
1047
+ Adapter.displayName = `Lucide.${name}`;
1170
1048
  return Adapter;
1171
1049
  }
1172
- function resolveIconForFamily(name, family) {
1173
- switch (family) {
1174
- case "lucide":
1175
- return makeLucideAdapter(name, false);
1176
- // Non-lucide families resolve to a lazy, Suspense-wrapped component that
1177
- // dynamic-imports the library on first render and falls back to lucide
1178
- // internally when the family lacks the icon (see lazyFamilyIcon).
1179
- case "phosphor-outline":
1180
- return resolvePhosphor(name, "regular", family);
1181
- case "phosphor-fill":
1182
- return resolvePhosphor(name, "fill", family);
1183
- case "phosphor-duotone":
1184
- return resolvePhosphor(name, "duotone", family);
1185
- case "tabler":
1186
- return resolveTabler(name, family);
1187
- case "fa-solid":
1188
- return resolveFa(name, family);
1189
- }
1190
- }
1191
- var DEFAULT_FAMILY, VALID_FAMILIES, cachedFamily, listeners, observer, libPromises, lucideAliases, phosphorAliases, tablerAliases, faAliases, warned;
1050
+ function resolveIconForFamily(name, _family) {
1051
+ return makeLucideAdapter(name);
1052
+ }
1053
+ var DEFAULT_FAMILY, VALID_FAMILIES, cachedFamily, listeners, observer, lucideAliases;
1192
1054
  var init_iconFamily = __esm({
1193
1055
  "lib/iconFamily.tsx"() {
1194
1056
  "use client";
1195
1057
  DEFAULT_FAMILY = "lucide";
1196
- VALID_FAMILIES = [
1197
- "lucide",
1198
- "phosphor-outline",
1199
- "phosphor-fill",
1200
- "phosphor-duotone",
1201
- "tabler",
1202
- "fa-solid"
1203
- ];
1058
+ VALID_FAMILIES = [DEFAULT_FAMILY];
1204
1059
  cachedFamily = null;
1205
1060
  listeners = /* @__PURE__ */ new Set();
1206
1061
  observer = null;
1207
- libPromises = /* @__PURE__ */ new Map();
1208
1062
  lucideAliases = {
1209
1063
  close: LucideIcons2.X,
1210
1064
  trash: LucideIcons2.Trash2,
@@ -1217,478 +1071,6 @@ var init_iconFamily = __esm({
1217
1071
  "sort-asc": LucideIcons2.ArrowUpNarrowWide,
1218
1072
  "sort-desc": LucideIcons2.ArrowDownNarrowWide
1219
1073
  };
1220
- phosphorAliases = {
1221
- // lucide name → phosphor PascalCase name
1222
- // Actions
1223
- plus: "Plus",
1224
- minus: "Minus",
1225
- x: "X",
1226
- check: "Check",
1227
- close: "X",
1228
- edit: "PencilSimple",
1229
- pencil: "PencilSimple",
1230
- trash: "Trash",
1231
- save: "FloppyDisk",
1232
- copy: "Copy",
1233
- share: "Share",
1234
- send: "PaperPlaneRight",
1235
- download: "DownloadSimple",
1236
- upload: "UploadSimple",
1237
- archive: "Archive",
1238
- refresh: "ArrowsClockwise",
1239
- loader: "CircleNotch",
1240
- link: "Link",
1241
- paperclip: "Paperclip",
1242
- // Navigation
1243
- "chevron-down": "CaretDown",
1244
- "chevron-up": "CaretUp",
1245
- "chevron-left": "CaretLeft",
1246
- "chevron-right": "CaretRight",
1247
- "arrow-up": "ArrowUp",
1248
- "arrow-down": "ArrowDown",
1249
- "arrow-left": "ArrowLeft",
1250
- "arrow-right": "ArrowRight",
1251
- menu: "List",
1252
- more: "DotsThree",
1253
- "more-vertical": "DotsThreeVertical",
1254
- "more-horizontal": "DotsThree",
1255
- external: "ArrowSquareOut",
1256
- "external-link": "ArrowSquareOut",
1257
- // Files
1258
- file: "File",
1259
- "file-text": "FileText",
1260
- "file-plus": "FilePlus",
1261
- "file-minus": "FileMinus",
1262
- folder: "Folder",
1263
- "folder-open": "FolderOpen",
1264
- document: "FileText",
1265
- // Charts
1266
- "bar-chart": "ChartBar",
1267
- "bar-chart-2": "ChartBar",
1268
- "bar-chart-3": "ChartBar",
1269
- "line-chart": "ChartLine",
1270
- "pie-chart": "ChartPie",
1271
- activity: "Pulse",
1272
- "trending-up": "TrendUp",
1273
- "trending-down": "TrendDown",
1274
- // Messages
1275
- message: "ChatCircle",
1276
- "message-circle": "ChatCircle",
1277
- "message-square": "ChatText",
1278
- "messages-square": "ChatsCircle",
1279
- comment: "ChatCircle",
1280
- comments: "ChatsCircle",
1281
- inbox: "Tray",
1282
- mail: "Envelope",
1283
- envelope: "Envelope",
1284
- // Status
1285
- "alert-circle": "WarningCircle",
1286
- "alert-triangle": "Warning",
1287
- "check-circle": "CheckCircle",
1288
- "x-circle": "XCircle",
1289
- info: "Info",
1290
- "help-circle": "Question",
1291
- "life-buoy": "Lifebuoy",
1292
- lifebuoy: "Lifebuoy",
1293
- warning: "Warning",
1294
- error: "WarningCircle",
1295
- // Media
1296
- image: "Image",
1297
- video: "VideoCamera",
1298
- film: "FilmStrip",
1299
- camera: "Camera",
1300
- music: "MusicNote",
1301
- play: "Play",
1302
- pause: "Pause",
1303
- stop: "Stop",
1304
- "skip-forward": "SkipForward",
1305
- "skip-back": "SkipBack",
1306
- volume: "SpeakerHigh",
1307
- "volume-2": "SpeakerHigh",
1308
- "volume-x": "SpeakerX",
1309
- mic: "Microphone",
1310
- "mic-off": "MicrophoneSlash",
1311
- // People
1312
- user: "User",
1313
- users: "Users",
1314
- "user-plus": "UserPlus",
1315
- "user-check": "UserCheck",
1316
- // Time
1317
- calendar: "Calendar",
1318
- clock: "Clock",
1319
- timer: "Timer",
1320
- // Location
1321
- map: "MapTrifold",
1322
- "map-pin": "MapPin",
1323
- navigation: "NavigationArrow",
1324
- compass: "Compass",
1325
- globe: "Globe",
1326
- target: "Target",
1327
- // Project / layout
1328
- kanban: "Kanban",
1329
- list: "List",
1330
- table: "Table",
1331
- grid: "GridFour",
1332
- layout: "Layout",
1333
- columns: "Columns",
1334
- rows: "Rows",
1335
- // Misc
1336
- bell: "Bell",
1337
- bookmark: "Bookmark",
1338
- briefcase: "Briefcase",
1339
- flag: "Flag",
1340
- tag: "Tag",
1341
- tags: "Tag",
1342
- star: "Star",
1343
- heart: "Heart",
1344
- home: "House",
1345
- settings: "Gear",
1346
- eye: "Eye",
1347
- "eye-off": "EyeSlash",
1348
- lock: "Lock",
1349
- unlock: "LockOpen",
1350
- key: "Key",
1351
- shield: "Shield",
1352
- search: "MagnifyingGlass",
1353
- filter: "Funnel",
1354
- "sort-asc": "SortAscending",
1355
- "sort-desc": "SortDescending",
1356
- zap: "Lightning",
1357
- sparkles: "Sparkle",
1358
- // Code
1359
- code: "Code",
1360
- terminal: "Terminal",
1361
- database: "Database",
1362
- server: "HardDrives",
1363
- cloud: "Cloud",
1364
- wifi: "WifiHigh",
1365
- package: "Package",
1366
- box: "Package",
1367
- // Theme
1368
- sun: "Sun",
1369
- moon: "Moon",
1370
- // Phone
1371
- phone: "Phone",
1372
- printer: "Printer",
1373
- // Hierarchy
1374
- tree: "Tree",
1375
- network: "Network"
1376
- };
1377
- tablerAliases = {
1378
- // lucide name → tabler suffix (after the `Icon` prefix)
1379
- // Actions
1380
- plus: "Plus",
1381
- minus: "Minus",
1382
- x: "X",
1383
- check: "Check",
1384
- close: "X",
1385
- edit: "Pencil",
1386
- pencil: "Pencil",
1387
- trash: "Trash",
1388
- save: "DeviceFloppy",
1389
- copy: "Copy",
1390
- share: "Share",
1391
- send: "Send",
1392
- download: "Download",
1393
- upload: "Upload",
1394
- archive: "Archive",
1395
- refresh: "Refresh",
1396
- loader: "Loader2",
1397
- link: "Link",
1398
- paperclip: "Paperclip",
1399
- external: "ExternalLink",
1400
- "external-link": "ExternalLink",
1401
- // Navigation
1402
- "chevron-down": "ChevronDown",
1403
- "chevron-up": "ChevronUp",
1404
- "chevron-left": "ChevronLeft",
1405
- "chevron-right": "ChevronRight",
1406
- "arrow-down": "ArrowDown",
1407
- "arrow-up": "ArrowUp",
1408
- "arrow-left": "ArrowLeft",
1409
- "arrow-right": "ArrowRight",
1410
- menu: "Menu2",
1411
- more: "Dots",
1412
- "more-vertical": "DotsVertical",
1413
- // Files
1414
- file: "File",
1415
- "file-text": "FileText",
1416
- "file-plus": "FilePlus",
1417
- "file-check": "FileCheck",
1418
- "file-minus": "FileMinus",
1419
- folder: "Folder",
1420
- "folder-open": "FolderOpen",
1421
- document: "FileText",
1422
- // Charts
1423
- "bar-chart": "ChartBar",
1424
- "bar-chart-2": "ChartBar",
1425
- "bar-chart-3": "ChartBar",
1426
- "line-chart": "ChartLine",
1427
- "pie-chart": "ChartPie",
1428
- activity: "Activity",
1429
- "trending-up": "TrendingUp",
1430
- "trending-down": "TrendingDown",
1431
- // Messages
1432
- message: "Message",
1433
- "message-circle": "MessageCircle",
1434
- "message-square": "Message2",
1435
- "messages-square": "Messages",
1436
- comment: "Message",
1437
- comments: "Messages",
1438
- inbox: "Inbox",
1439
- mail: "Mail",
1440
- envelope: "Mail",
1441
- // Status
1442
- "alert-circle": "AlertCircle",
1443
- "alert-triangle": "AlertTriangle",
1444
- "check-circle": "CircleCheck",
1445
- "x-circle": "CircleX",
1446
- info: "InfoCircle",
1447
- "help-circle": "HelpCircle",
1448
- "life-buoy": "Lifebuoy",
1449
- warning: "AlertTriangle",
1450
- error: "AlertOctagon",
1451
- // Media
1452
- image: "Photo",
1453
- video: "Video",
1454
- camera: "Camera",
1455
- music: "Music",
1456
- play: "PlayerPlay",
1457
- pause: "PlayerPause",
1458
- stop: "PlayerStop",
1459
- "skip-forward": "PlayerSkipForward",
1460
- "skip-back": "PlayerSkipBack",
1461
- volume: "Volume",
1462
- "volume-2": "Volume",
1463
- "volume-x": "VolumeOff",
1464
- mic: "Microphone",
1465
- "mic-off": "MicrophoneOff",
1466
- // People
1467
- user: "User",
1468
- users: "Users",
1469
- "user-plus": "UserPlus",
1470
- "user-check": "UserCheck",
1471
- // Time
1472
- calendar: "Calendar",
1473
- clock: "Clock",
1474
- timer: "Hourglass",
1475
- // Location
1476
- map: "Map",
1477
- "map-pin": "MapPin",
1478
- navigation: "Navigation",
1479
- compass: "Compass",
1480
- globe: "World",
1481
- target: "Target",
1482
- // Project / layout
1483
- kanban: "LayoutKanban",
1484
- list: "List",
1485
- table: "Table",
1486
- grid: "LayoutGrid",
1487
- layout: "Layout",
1488
- columns: "LayoutColumns",
1489
- rows: "LayoutRows",
1490
- // Misc
1491
- bell: "Bell",
1492
- bookmark: "Bookmark",
1493
- briefcase: "Briefcase",
1494
- flag: "Flag",
1495
- tag: "Tag",
1496
- tags: "Tags",
1497
- star: "Star",
1498
- heart: "Heart",
1499
- home: "Home",
1500
- settings: "Settings",
1501
- eye: "Eye",
1502
- "eye-off": "EyeOff",
1503
- lock: "Lock",
1504
- unlock: "LockOpen",
1505
- key: "Key",
1506
- shield: "Shield",
1507
- search: "Search",
1508
- filter: "Filter",
1509
- "sort-asc": "SortAscending",
1510
- "sort-desc": "SortDescending",
1511
- zap: "Bolt",
1512
- sparkles: "Sparkles",
1513
- // Code / data
1514
- code: "Code",
1515
- terminal: "Terminal",
1516
- database: "Database",
1517
- server: "Server",
1518
- cloud: "Cloud",
1519
- wifi: "Wifi",
1520
- package: "Package",
1521
- box: "Box",
1522
- // Theme
1523
- sun: "Sun",
1524
- moon: "Moon",
1525
- // Phone
1526
- phone: "Phone",
1527
- printer: "Printer",
1528
- // Hierarchy
1529
- tree: "Hierarchy",
1530
- network: "Network"
1531
- };
1532
- faAliases = {
1533
- // lucide name → fa-solid suffix (after the `Fa` prefix).
1534
- // react-icons/fa ships FontAwesome 5 — names like `FaFileText` don't exist
1535
- // (FA renamed to `FaFileAlt`). When you see a console.warn from
1536
- // [iconFamily] about an unmapped lucide name in this family, add the
1537
- // closest FA5 sibling here so the fallback stays in-family.
1538
- search: "Search",
1539
- close: "Times",
1540
- x: "Times",
1541
- loader: "Spinner",
1542
- refresh: "Sync",
1543
- "sort-asc": "SortAmountUp",
1544
- "sort-desc": "SortAmountDown",
1545
- "chevron-down": "ChevronDown",
1546
- "chevron-up": "ChevronUp",
1547
- "chevron-left": "ChevronLeft",
1548
- "chevron-right": "ChevronRight",
1549
- "help-circle": "QuestionCircle",
1550
- "alert-triangle": "ExclamationTriangle",
1551
- "alert-circle": "ExclamationCircle",
1552
- "check-circle": "CheckCircle",
1553
- "x-circle": "TimesCircle",
1554
- edit: "Edit",
1555
- pencil: "PencilAlt",
1556
- trash: "Trash",
1557
- send: "PaperPlane",
1558
- share: "ShareAlt",
1559
- external: "ExternalLinkAlt",
1560
- plus: "Plus",
1561
- minus: "Minus",
1562
- check: "Check",
1563
- star: "Star",
1564
- heart: "Heart",
1565
- home: "Home",
1566
- user: "User",
1567
- users: "Users",
1568
- "user-plus": "UserPlus",
1569
- "user-check": "UserCheck",
1570
- settings: "Cog",
1571
- menu: "Bars",
1572
- "arrow-up": "ArrowUp",
1573
- "arrow-down": "ArrowDown",
1574
- "arrow-left": "ArrowLeft",
1575
- "arrow-right": "ArrowRight",
1576
- copy: "Copy",
1577
- download: "Download",
1578
- upload: "Upload",
1579
- filter: "Filter",
1580
- calendar: "Calendar",
1581
- clock: "Clock",
1582
- bell: "Bell",
1583
- mail: "Envelope",
1584
- envelope: "Envelope",
1585
- lock: "Lock",
1586
- unlock: "LockOpen",
1587
- eye: "Eye",
1588
- "eye-off": "EyeSlash",
1589
- more: "EllipsisH",
1590
- "more-vertical": "EllipsisV",
1591
- info: "InfoCircle",
1592
- warning: "ExclamationTriangle",
1593
- error: "ExclamationCircle",
1594
- // Time
1595
- timer: "Hourglass",
1596
- // Files (FA renamed FileText → FileAlt)
1597
- file: "File",
1598
- "file-text": "FileAlt",
1599
- "file-plus": "FileMedical",
1600
- "file-minus": "FileExcel",
1601
- "file-check": "FileSignature",
1602
- document: "FileAlt",
1603
- // Charts (lucide BarChart2 / BarChart3 → FA ChartBar)
1604
- "bar-chart": "ChartBar",
1605
- "bar-chart-2": "ChartBar",
1606
- "bar-chart-3": "ChartBar",
1607
- "line-chart": "ChartLine",
1608
- "pie-chart": "ChartPie",
1609
- activity: "ChartLine",
1610
- "trending-up": "ChartLine",
1611
- "trending-down": "ChartLine",
1612
- // Messages (lucide MessageCircle/MessageSquare → FA CommentDots/CommentAlt)
1613
- message: "Comment",
1614
- "message-circle": "CommentDots",
1615
- "message-square": "CommentAlt",
1616
- "messages-square": "Comments",
1617
- comment: "Comment",
1618
- comments: "Comments",
1619
- inbox: "Inbox",
1620
- // Support / help
1621
- "life-buoy": "LifeRing",
1622
- lifebuoy: "LifeRing",
1623
- // Project / kanban (FA has no kanban; closest semantic is Tasks/Columns)
1624
- kanban: "Tasks",
1625
- columns: "Columns",
1626
- rows: "Bars",
1627
- layout: "ThLarge",
1628
- grid: "Th",
1629
- list: "List",
1630
- table: "Table",
1631
- // Storage / folders
1632
- folder: "Folder",
1633
- "folder-open": "FolderOpen",
1634
- archive: "Archive",
1635
- bookmark: "Bookmark",
1636
- briefcase: "Briefcase",
1637
- package: "Box",
1638
- box: "Box",
1639
- // Map / location
1640
- map: "Map",
1641
- "map-pin": "MapMarkerAlt",
1642
- navigation: "LocationArrow",
1643
- compass: "Compass",
1644
- globe: "Globe",
1645
- target: "Bullseye",
1646
- // Media
1647
- image: "Image",
1648
- video: "Video",
1649
- film: "Film",
1650
- camera: "Camera",
1651
- music: "Music",
1652
- play: "Play",
1653
- pause: "Pause",
1654
- stop: "Stop",
1655
- "skip-forward": "Forward",
1656
- "skip-back": "Backward",
1657
- volume: "VolumeUp",
1658
- "volume-2": "VolumeUp",
1659
- "volume-x": "VolumeMute",
1660
- mic: "Microphone",
1661
- "mic-off": "MicrophoneSlash",
1662
- phone: "Phone",
1663
- // Code / data
1664
- code: "Code",
1665
- terminal: "Terminal",
1666
- database: "Database",
1667
- server: "Server",
1668
- cloud: "Cloud",
1669
- wifi: "Wifi",
1670
- // Security
1671
- shield: "ShieldAlt",
1672
- key: "Key",
1673
- // Misc actions
1674
- printer: "Print",
1675
- save: "Save",
1676
- link: "Link",
1677
- unlink: "Unlink",
1678
- paperclip: "Paperclip",
1679
- flag: "Flag",
1680
- tag: "Tag",
1681
- tags: "Tags",
1682
- zap: "Bolt",
1683
- sparkles: "Magic",
1684
- // Theme
1685
- sun: "Sun",
1686
- moon: "Moon",
1687
- // Hierarchy (FA has no Tree icon for hierarchies; Sitemap is the org-chart icon)
1688
- tree: "Sitemap",
1689
- network: "NetworkWired"
1690
- };
1691
- warned = /* @__PURE__ */ new Set();
1692
1074
  }
1693
1075
  });
1694
1076
  function kebabToPascal2(name) {
@@ -1769,7 +1151,7 @@ var init_Icon = __esm({
1769
1151
  const family = useIconFamily();
1770
1152
  const RenderedComponent = React81__default.useMemo(() => {
1771
1153
  if (directIcon) return null;
1772
- return effectiveName ? resolveIconForFamily(effectiveName, family) : null;
1154
+ return effectiveName ? resolveIconForFamily(effectiveName) : null;
1773
1155
  }, [directIcon, effectiveName, family]);
1774
1156
  const effectiveStrokeWidth = strokeWidth ?? void 0;
1775
1157
  const inlineStyle = {
@@ -2148,7 +1530,7 @@ var init_Button = __esm({
2148
1530
  ref,
2149
1531
  disabled: disabled || isLoading,
2150
1532
  className: cn(
2151
- "inline-flex items-center justify-center gap-2",
1533
+ "relative inline-flex items-center justify-center gap-2",
2152
1534
  "font-medium",
2153
1535
  "rounded-sm",
2154
1536
  "cursor-pointer",
@@ -3916,6 +3298,7 @@ var init_Input = __esm({
3916
3298
  icon: iconProp,
3917
3299
  clearable,
3918
3300
  onClear,
3301
+ action,
3919
3302
  value,
3920
3303
  options,
3921
3304
  rows = 3,
@@ -3965,6 +3348,11 @@ var init_Input = __esm({
3965
3348
  onClear?.();
3966
3349
  }
3967
3350
  };
3351
+ const handleKeyDown = (e) => {
3352
+ if (action && e.key === "Enter") {
3353
+ eventBus.emit(`UI:${action}`, { value: e.currentTarget.value });
3354
+ }
3355
+ };
3968
3356
  const wrapField = (field) => /* @__PURE__ */ jsxs("div", { className: "w-full", children: [
3969
3357
  label && /* @__PURE__ */ jsx("label", { className: "block text-sm font-medium text-foreground mb-1", children: label }),
3970
3358
  field,
@@ -4038,6 +3426,7 @@ var init_Input = __esm({
4038
3426
  type,
4039
3427
  value,
4040
3428
  onChange: handleChange,
3429
+ onKeyDown: handleKeyDown,
4041
3430
  className: baseClassName,
4042
3431
  ...props
4043
3432
  }
@@ -4570,7 +3959,7 @@ var init_Card = __esm({
4570
3959
  });
4571
3960
  function GameIcon({ assetUrl, icon, size = "md", alt, className }) {
4572
3961
  const px = typeof size === "number" ? size : sizeMap[size];
4573
- const family = useIconFamily();
3962
+ useIconFamily();
4574
3963
  if (assetUrl?.url) {
4575
3964
  return /* @__PURE__ */ jsx(
4576
3965
  AtlasImage,
@@ -4582,7 +3971,7 @@ function GameIcon({ assetUrl, icon, size = "md", alt, className }) {
4582
3971
  }
4583
3972
  );
4584
3973
  }
4585
- const I = typeof icon === "string" ? resolveIconForFamily(icon, family) : icon;
3974
+ const I = typeof icon === "string" ? resolveIconForFamily(icon) : icon;
4586
3975
  return /* @__PURE__ */ jsx(I, { width: px, height: px, className: cn("flex-shrink-0", className) });
4587
3976
  }
4588
3977
  var sizeMap;
@@ -6979,8 +6368,8 @@ function Seigaiha({ size, color, strokeWidth }) {
6979
6368
  [s, s * 0.1]
6980
6369
  ];
6981
6370
  for (const [cx, cy] of centers) {
6982
- for (let ring2 = 1; ring2 <= 3; ring2++) {
6983
- const cr = r * (ring2 / 3);
6371
+ for (let ring = 1; ring <= 3; ring++) {
6372
+ const cr = r * (ring / 3);
6984
6373
  paths.push(
6985
6374
  `M ${f(cx - cr)},${f(cy)} A ${f(cr)} ${f(cr)} 0 0 1 ${f(cx + cr)},${f(cy)}`
6986
6375
  );
@@ -7077,8 +6466,8 @@ function Arch({ size, color, strokeWidth }) {
7077
6466
  const h = size * 1.5;
7078
6467
  const cx = w / 2;
7079
6468
  const paths = [];
7080
- for (let ring2 = 0; ring2 < 4; ring2++) {
7081
- const scale = 1 - ring2 * 0.2;
6469
+ for (let ring = 0; ring < 4; ring++) {
6470
+ const scale = 1 - ring * 0.2;
7082
6471
  const archW = w * 0.48 * scale;
7083
6472
  const archH = h * 0.7 * scale;
7084
6473
  const baseY = h * 0.85;
@@ -7093,7 +6482,7 @@ function Arch({ size, color, strokeWidth }) {
7093
6482
  paths.push(
7094
6483
  `M ${f(lx)},${f(baseY)} A ${f(radius)} ${f(radius)} 0 0 1 ${f(cx)},${f(tipY)} A ${f(radius)} ${f(radius)} 0 0 1 ${f(rx)},${f(baseY)}`
7095
6484
  );
7096
- if (ring2 === 0) {
6485
+ if (ring === 0) {
7097
6486
  paths.push(`M ${f(lx)},${f(baseY)} L ${f(rx)},${f(baseY)}`);
7098
6487
  }
7099
6488
  }
@@ -9501,9 +8890,9 @@ var init_webPainter2d = __esm({
9501
8890
  // lib/drawable/projector.ts
9502
8891
  function create2DProjector(opts) {
9503
8892
  const { scale, baseOffsetX, layout } = opts;
9504
- const tileWidth = TILE_WIDTH * scale;
9505
- const floorHeight = FLOOR_HEIGHT * scale;
9506
- const diamondTopY = (opts.diamondTopY ?? DIAMOND_TOP_Y) * scale;
8893
+ const tileWidth = layout === "free" ? 1 : TILE_WIDTH * scale;
8894
+ const floorHeight = layout === "free" ? 1 : FLOOR_HEIGHT * scale;
8895
+ const diamondTopY = layout === "free" ? 0 : (opts.diamondTopY ?? DIAMOND_TOP_Y) * scale;
9507
8896
  const squareGrid = layout === "flat" || layout === "free";
9508
8897
  const project = (pos) => layout === "free" ? { x: pos.x, y: pos.y } : isoToScreen(pos.x, pos.y, scale, baseOffsetX, layout);
9509
8898
  const anchorPoint = (pos, anchor) => {
@@ -9544,6 +8933,15 @@ var init_projector = __esm({
9544
8933
  }
9545
8934
  });
9546
8935
 
8936
+ // lib/drawable/contract.ts
8937
+ function isValidScenePos(pos) {
8938
+ return Number.isFinite(pos?.x) && Number.isFinite(pos?.y);
8939
+ }
8940
+ var init_contract = __esm({
8941
+ "lib/drawable/contract.ts"() {
8942
+ }
8943
+ });
8944
+
9547
8945
  // components/game/atoms/DrawSprite.tsx
9548
8946
  function DrawSprite(_props) {
9549
8947
  return null;
@@ -9553,10 +8951,12 @@ var init_DrawSprite = __esm({
9553
8951
  "components/game/atoms/DrawSprite.tsx"() {
9554
8952
  "use client";
9555
8953
  init_atlasSlice();
8954
+ init_contract();
9556
8955
  paintSprite = (painter, node, dctx) => {
8956
+ if (!node.asset?.url || !isValidScenePos(node.position)) return;
9557
8957
  const tex = painter.resolveTexture(node.asset.url);
9558
8958
  if (!tex) return;
9559
- let src = node.frame;
8959
+ let src = typeof node.frame === "object" ? node.frame : void 0;
9560
8960
  if (!src && isAtlasAsset(node.asset)) {
9561
8961
  const atlas = getAtlas(node.asset.atlas, dctx.invalidate);
9562
8962
  if (!atlas) return;
@@ -9601,7 +9001,9 @@ var paintShape;
9601
9001
  var init_DrawShape = __esm({
9602
9002
  "components/game/atoms/DrawShape.tsx"() {
9603
9003
  "use client";
9004
+ init_contract();
9604
9005
  paintShape = (painter, node, dctx) => {
9006
+ if (!isValidScenePos(node.position)) return;
9605
9007
  painter.save();
9606
9008
  if (node.opacity !== void 0 && node.opacity !== 1) painter.setAlpha(node.opacity);
9607
9009
  switch (node.shape) {
@@ -9655,7 +9057,9 @@ var paintText;
9655
9057
  var init_DrawText = __esm({
9656
9058
  "components/game/atoms/DrawText.tsx"() {
9657
9059
  "use client";
9060
+ init_contract();
9658
9061
  paintText = (painter, node, dctx) => {
9062
+ if (!isValidScenePos(node.position)) return;
9659
9063
  const p = dctx.projector.anchorPoint(node.position, node.anchor ?? "center");
9660
9064
  const x = p.x + (node.offsetX ?? 0);
9661
9065
  const y = p.y + (node.offsetY ?? 0);
@@ -9760,12 +9164,14 @@ function collectDrawnItems(nodes) {
9760
9164
  case "draw-sprite":
9761
9165
  case "draw-shape":
9762
9166
  case "draw-text":
9763
- out.push({ pos: n.position, id: n.id });
9167
+ if (isValidScenePos(n.position)) out.push({ pos: n.position, id: n.id });
9764
9168
  break;
9765
9169
  case "draw-sprite-layer":
9766
9170
  case "draw-shape-layer":
9767
9171
  case "draw-text-layer":
9768
- for (const it of n.items) out.push({ pos: it.position, id: it.id });
9172
+ for (const it of n.items) {
9173
+ if (isValidScenePos(it.position)) out.push({ pos: it.position, id: it.id });
9174
+ }
9769
9175
  break;
9770
9176
  }
9771
9177
  }
@@ -9780,6 +9186,7 @@ function buildHitIndex(items) {
9780
9186
  }
9781
9187
  var init_hitTest = __esm({
9782
9188
  "lib/drawable/hitTest.ts"() {
9189
+ init_contract();
9783
9190
  }
9784
9191
  });
9785
9192
  function normalizeBackdrop(bg) {
@@ -11819,21 +11226,6 @@ var init_renderer = __esm({
11819
11226
  init_slot_definitions();
11820
11227
  }
11821
11228
  });
11822
-
11823
- // lib/wrapCallbackForEvent.ts
11824
- function wrapCallbackForEvent(qualifiedEvent, callbackArgs, emit) {
11825
- const argNames = (callbackArgs ?? []).map((a) => a.name);
11826
- if (argNames.length === 0) {
11827
- return () => emit(qualifiedEvent);
11828
- }
11829
- return (...args) => {
11830
- const payload = {};
11831
- for (let i = 0; i < argNames.length; i += 1) {
11832
- payload[argNames[i]] = args[i];
11833
- }
11834
- emit(qualifiedEvent, payload);
11835
- };
11836
- }
11837
11229
  var init_wrapCallbackForEvent = __esm({
11838
11230
  "lib/wrapCallbackForEvent.ts"() {
11839
11231
  }
@@ -22724,7 +22116,8 @@ function DataGrid({
22724
22116
  const { t } = useTranslate();
22725
22117
  const [selectedIds, setSelectedIds] = useState(/* @__PURE__ */ new Set());
22726
22118
  const [visibleCount, setVisibleCount] = useState(pageSize || Infinity);
22727
- const fieldDefs = fields ?? columns ?? [];
22119
+ const fieldDefs = (Array.isArray(fields) ? fields : void 0) ?? (Array.isArray(columns) ? columns : void 0) ?? [];
22120
+ const actionDefs = Array.isArray(itemActions) ? itemActions : [];
22728
22121
  const allDataRaw = Array.isArray(entity) ? entity : entity ? [entity] : [];
22729
22122
  const dnd = useDataDnd({
22730
22123
  items: allDataRaw,
@@ -22768,8 +22161,8 @@ function DataGrid({
22768
22161
  const titleField = fieldDefs.find((f3) => f3.variant === "h3" || f3.variant === "h4") ?? fieldDefs[0];
22769
22162
  const badgeFields = fieldDefs.filter((f3) => f3.variant === "badge" && f3 !== titleField);
22770
22163
  const bodyFields = fieldDefs.filter((f3) => f3 !== titleField && !badgeFields.includes(f3));
22771
- const primaryActions = itemActions?.filter((a) => a.variant !== "danger") ?? [];
22772
- const dangerActions = itemActions?.filter((a) => a.variant === "danger") ?? [];
22164
+ const primaryActions = actionDefs.filter((a) => a.variant !== "danger");
22165
+ const dangerActions = actionDefs.filter((a) => a.variant === "danger");
22773
22166
  const handleActionClick = (action, itemData) => (e) => {
22774
22167
  e.stopPropagation();
22775
22168
  const payload = {
@@ -35299,7 +34692,7 @@ function measureLabelWidth(text) {
35299
34692
  if (typeof document === "undefined") return text.length * 6;
35300
34693
  if (!labelMeasureCtx) labelMeasureCtx = document.createElement("canvas").getContext("2d");
35301
34694
  if (!labelMeasureCtx) return text.length * 6;
35302
- labelMeasureCtx.font = "10px system-ui";
34695
+ labelMeasureCtx.font = "12px system-ui";
35303
34696
  return labelMeasureCtx.measureText(text).width;
35304
34697
  }
35305
34698
  function getGroupColor(group, groups) {
@@ -35345,6 +34738,7 @@ var init_GraphCanvas = __esm({
35345
34738
  actions,
35346
34739
  onNodeClick,
35347
34740
  onNodeDoubleClick,
34741
+ onBadgeClick,
35348
34742
  nodeClickEvent,
35349
34743
  selectedNodeId,
35350
34744
  repulsion = 800,
@@ -35492,7 +34886,9 @@ var init_GraphCanvas = __esm({
35492
34886
  const dx = target.x - source.x;
35493
34887
  const dy = target.y - source.y;
35494
34888
  const dist = Math.sqrt(dx * dx + dy * dy) || 1;
35495
- const force = (dist - linkDistance) * 0.05;
34889
+ const w2 = edge.weight ?? 1;
34890
+ const linkTarget = linkDistance * (1 + (1 - Math.min(1, Math.max(0, w2))) * 1.5);
34891
+ const force = (dist - linkTarget) * 0.05;
35496
34892
  const fx = dx / dist * force;
35497
34893
  const fy = dy / dist * force;
35498
34894
  source.fx += fx;
@@ -35514,7 +34910,7 @@ var init_GraphCanvas = __esm({
35514
34910
  node.y = Math.max(30, Math.min(h - 30, node.y));
35515
34911
  }
35516
34912
  const LABEL_GAP = 12;
35517
- const LABEL_H = 12;
34913
+ const LABEL_H = 16;
35518
34914
  const pad = nodeSpacing / 2;
35519
34915
  for (let i = 0; i < nodes.length; i++) {
35520
34916
  for (let j = i + 1; j < nodes.length; j++) {
@@ -35535,13 +34931,13 @@ var init_GraphCanvas = __esm({
35535
34931
  const overlapY = Math.min(aBot, bBot) - Math.max(aTop, bTop);
35536
34932
  if (overlapX > 0 && overlapY > 0) {
35537
34933
  if (overlapX <= overlapY) {
35538
- const push2 = overlapX / 2 * (b.x >= a.x ? 1 : -1);
35539
- a.x = Math.max(30, Math.min(w - 30, a.x - push2));
35540
- b.x = Math.max(30, Math.min(w - 30, b.x + push2));
34934
+ const push = overlapX / 2 * (b.x >= a.x ? 1 : -1);
34935
+ a.x = Math.max(30, Math.min(w - 30, a.x - push));
34936
+ b.x = Math.max(30, Math.min(w - 30, b.x + push));
35541
34937
  } else {
35542
- const push2 = overlapY / 2 * (bTop + bBot >= aTop + aBot ? 1 : -1);
35543
- a.y = Math.max(30, Math.min(h - 30, a.y - push2));
35544
- b.y = Math.max(30, Math.min(h - 30, b.y + push2));
34938
+ const push = overlapY / 2 * (bTop + bBot >= aTop + aBot ? 1 : -1);
34939
+ a.y = Math.max(30, Math.min(h - 30, a.y - push));
34940
+ b.y = Math.max(30, Math.min(h - 30, b.y + push));
35545
34941
  }
35546
34942
  }
35547
34943
  }
@@ -35569,6 +34965,11 @@ var init_GraphCanvas = __esm({
35569
34965
  const h = height;
35570
34966
  const nodes = nodesRef.current;
35571
34967
  const accentColor = resolveColor3("var(--color-accent)", canvas);
34968
+ const fontFamily = resolveColor3("var(--font-family)", canvas) || "system-ui";
34969
+ const fgColor = resolveColor3("var(--color-foreground)", canvas);
34970
+ const mutedColor = resolveColor3("var(--color-muted-foreground)", canvas) || fgColor;
34971
+ const bgColor = resolveColor3("var(--color-background)", canvas) || "#ffffff";
34972
+ const accentFg = resolveColor3("var(--color-accent-foreground)", canvas) || "#ffffff";
35572
34973
  const dpr = typeof window !== "undefined" && window.devicePixelRatio || 1;
35573
34974
  ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
35574
34975
  ctx.clearRect(0, 0, w, h);
@@ -35588,19 +34989,21 @@ var init_GraphCanvas = __esm({
35588
34989
  const target = nodes.find((n) => n.id === edge.target);
35589
34990
  if (!source || !target) continue;
35590
34991
  const incident = !!hoveredNode && (edge.source === hoveredNode || edge.target === hoveredNode);
35591
- ctx.globalAlpha = hoveredNode ? incident ? 1 : 0.05 : linkOpacity;
34992
+ const w2 = edge.weight ?? 1;
34993
+ ctx.globalAlpha = hoveredNode ? incident ? 1 : 0.05 : linkOpacity * w2;
35592
34994
  ctx.beginPath();
35593
34995
  ctx.moveTo(source.x, source.y);
35594
34996
  ctx.lineTo(target.x, target.y);
35595
34997
  ctx.strokeStyle = incident ? accentColor : edge.color || "#888888";
35596
- ctx.lineWidth = incident ? 2 : edge.weight ? Math.max(1, edge.weight) : 1;
34998
+ ctx.lineWidth = incident ? 2 : Math.max(0.75, w2);
35597
34999
  ctx.stroke();
35598
35000
  if (edge.label && showLabels) {
35599
35001
  const mx = (source.x + target.x) / 2;
35600
35002
  const my = (source.y + target.y) / 2;
35601
- ctx.fillStyle = "#888888";
35602
- ctx.font = "9px system-ui";
35003
+ ctx.fillStyle = mutedColor;
35004
+ ctx.font = `9px ${fontFamily}`;
35603
35005
  ctx.textAlign = "center";
35006
+ ctx.textBaseline = "alphabetic";
35604
35007
  ctx.fillText(edge.label, mx, my - 4);
35605
35008
  }
35606
35009
  }
@@ -35625,10 +35028,33 @@ var init_GraphCanvas = __esm({
35625
35028
  }
35626
35029
  ctx.stroke();
35627
35030
  if (showLabels && node.label) {
35628
- ctx.fillStyle = "#666666";
35629
- ctx.font = `${isSelected || isHovered ? "bold " : ""}10px system-ui`;
35031
+ ctx.font = `${isSelected || isHovered ? "600" : "500"} 12px ${fontFamily}`;
35032
+ ctx.textAlign = "center";
35033
+ ctx.textBaseline = "middle";
35034
+ const ly = node.y + radius + 14;
35035
+ ctx.lineWidth = 3;
35036
+ ctx.lineJoin = "round";
35037
+ ctx.strokeStyle = bgColor;
35038
+ ctx.strokeText(node.label, node.x, ly);
35039
+ ctx.fillStyle = isSelected || isHovered ? fgColor : mutedColor;
35040
+ ctx.fillText(node.label, node.x, ly);
35041
+ }
35042
+ if (node.badge && node.badge > 1) {
35043
+ const bx = node.x + radius * 0.7;
35044
+ const by = node.y - radius * 0.7;
35045
+ const br = Math.max(7, Math.min(11, radius * 0.45));
35046
+ ctx.beginPath();
35047
+ ctx.arc(bx, by, br, 0, Math.PI * 2);
35048
+ ctx.fillStyle = accentColor;
35049
+ ctx.fill();
35050
+ ctx.strokeStyle = bgColor;
35051
+ ctx.lineWidth = 2;
35052
+ ctx.stroke();
35053
+ ctx.fillStyle = accentFg;
35054
+ ctx.font = `600 9px ${fontFamily}`;
35630
35055
  ctx.textAlign = "center";
35631
- ctx.fillText(node.label, node.x, node.y + radius + 12);
35056
+ ctx.textBaseline = "middle";
35057
+ ctx.fillText(String(node.badge), bx, by + 0.5);
35632
35058
  }
35633
35059
  }
35634
35060
  ctx.restore();
@@ -35721,11 +35147,21 @@ var init_GraphCanvas = __esm({
35721
35147
  if (!coords) return;
35722
35148
  const node = nodeAt(coords.graphX, coords.graphY);
35723
35149
  if (node) {
35150
+ if (node.badge && node.badge > 1 && onBadgeClick) {
35151
+ const r = (node.size || 8) + (selectedNodeId === node.id ? 4 : 0);
35152
+ const bx = node.x + r * 0.7;
35153
+ const by = node.y - r * 0.7;
35154
+ const br = Math.max(7, Math.min(11, r * 0.45)) + 3;
35155
+ if (Math.hypot(coords.graphX - bx, coords.graphY - by) <= br) {
35156
+ onBadgeClick(node);
35157
+ return;
35158
+ }
35159
+ }
35724
35160
  handleNodeClick(node);
35725
35161
  }
35726
35162
  }
35727
35163
  },
35728
- [toCoords, nodeAt, handleNodeClick]
35164
+ [toCoords, nodeAt, handleNodeClick, onBadgeClick, selectedNodeId]
35729
35165
  );
35730
35166
  const handlePointerLeave = useCallback(() => {
35731
35167
  setHoveredNode(null);
@@ -40246,7 +39682,7 @@ function getAllEvents(traits2) {
40246
39682
  function EventDispatcherTab({ traits: traits2, schema }) {
40247
39683
  const eventBus = useEventBus();
40248
39684
  const { t } = useTranslate();
40249
- const [log10, setLog] = React81.useState([]);
39685
+ const [log9, setLog] = React81.useState([]);
40250
39686
  const prevStatesRef = React81.useRef(/* @__PURE__ */ new Map());
40251
39687
  React81.useEffect(() => {
40252
39688
  for (const trait of traits2) {
@@ -40310,9 +39746,9 @@ function EventDispatcherTab({ traits: traits2, schema }) {
40310
39746
  /* @__PURE__ */ jsx(Typography, { variant: "small", weight: "medium", className: "text-gray-500 mb-1", children: t("debug.otherEvents") }),
40311
39747
  /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-1", children: unavailableEvents.map((event) => /* @__PURE__ */ jsx(Badge, { variant: "default", size: "sm", className: "opacity-50", children: event }, event)) })
40312
39748
  ] }),
40313
- log10.length > 0 && /* @__PURE__ */ jsxs("div", { children: [
39749
+ log9.length > 0 && /* @__PURE__ */ jsxs("div", { children: [
40314
39750
  /* @__PURE__ */ jsx(Typography, { variant: "small", weight: "medium", className: "text-gray-500 mb-1", children: t("debug.recentTransitions") }),
40315
- /* @__PURE__ */ jsx(Stack, { gap: "xs", children: log10.map((entry, i) => /* @__PURE__ */ jsxs(Typography, { variant: "small", className: "font-mono text-xs", children: [
39751
+ /* @__PURE__ */ jsx(Stack, { gap: "xs", children: log9.map((entry, i) => /* @__PURE__ */ jsxs(Typography, { variant: "small", className: "font-mono text-xs", children: [
40316
39752
  /* @__PURE__ */ jsx("span", { className: "text-purple-400", children: entry.traitName }),
40317
39753
  " ",
40318
39754
  /* @__PURE__ */ jsx("span", { className: "text-gray-500", children: entry.from }),
@@ -43949,27 +43385,27 @@ var log2 = createLogger("almadar:ui:shared-entity-store");
43949
43385
  var EMPTY_ENTITY_STATE = {};
43950
43386
  function createSharedEntityStore() {
43951
43387
  const states = /* @__PURE__ */ new Map();
43952
- const subscribers2 = /* @__PURE__ */ new Map();
43953
- const getSnapshot3 = (entityId) => states.get(entityId) ?? EMPTY_ENTITY_STATE;
43954
- const subscribe2 = (entityId, callback) => {
43955
- let set = subscribers2.get(entityId);
43388
+ const subscribers = /* @__PURE__ */ new Map();
43389
+ const getSnapshot2 = (entityId) => states.get(entityId) ?? EMPTY_ENTITY_STATE;
43390
+ const subscribe = (entityId, callback) => {
43391
+ let set = subscribers.get(entityId);
43956
43392
  if (!set) {
43957
43393
  set = /* @__PURE__ */ new Set();
43958
- subscribers2.set(entityId, set);
43394
+ subscribers.set(entityId, set);
43959
43395
  }
43960
43396
  set.add(callback);
43961
43397
  return () => {
43962
- const current = subscribers2.get(entityId);
43398
+ const current = subscribers.get(entityId);
43963
43399
  if (!current) return;
43964
43400
  current.delete(callback);
43965
43401
  if (current.size === 0) {
43966
- subscribers2.delete(entityId);
43402
+ subscribers.delete(entityId);
43967
43403
  }
43968
43404
  };
43969
43405
  };
43970
43406
  const commit = (entityId, nextState) => {
43971
43407
  states.set(entityId, nextState);
43972
- const set = subscribers2.get(entityId);
43408
+ const set = subscribers.get(entityId);
43973
43409
  if (!set) return;
43974
43410
  set.forEach((callback) => {
43975
43411
  try {
@@ -43987,7 +43423,7 @@ function createSharedEntityStore() {
43987
43423
  states.set(entityId, initialState);
43988
43424
  }
43989
43425
  };
43990
- return { getSnapshot: getSnapshot3, subscribe: subscribe2, commit, seed };
43426
+ return { getSnapshot: getSnapshot2, subscribe, commit, seed };
43991
43427
  }
43992
43428
  function useSharedEntityStore() {
43993
43429
  const storeRef = useRef(null);
@@ -44063,6 +43499,11 @@ function createClientEffectHandlers(options) {
44063
43499
  };
44064
43500
  }
44065
43501
  var lambdaLog = createLogger("almadar:ui:fn-form-lambda");
43502
+ function isOperatorCall(value) {
43503
+ const first = value[0];
43504
+ if (typeof first !== "string") return false;
43505
+ return isKnownStdOperator(first) || first.includes("/") || first === "lambda" || first === "let";
43506
+ }
44066
43507
  function isFnFormLambda(value) {
44067
43508
  if (!Array.isArray(value)) return false;
44068
43509
  const arr = value;
@@ -44102,7 +43543,14 @@ function resolveLambdaBindings(body, params, item, index) {
44102
43543
  return body;
44103
43544
  }
44104
43545
  if (Array.isArray(body)) {
44105
- return body.map((b) => recur(b));
43546
+ if (isFnFormLambda(body)) return body;
43547
+ const arr = body;
43548
+ const substituted = arr.map((b) => recur(b));
43549
+ if (isOperatorCall(substituted) && isSExpr(substituted)) {
43550
+ const evaluated = evaluate(substituted, createMinimalContext());
43551
+ return isEventPayloadValue(evaluated) ? evaluated : String(evaluated);
43552
+ }
43553
+ return substituted;
44106
43554
  }
44107
43555
  if (body !== null && typeof body === "object" && !React81__default.isValidElement(body) && !(body instanceof Date) && typeof body !== "function") {
44108
43556
  const out = {};
@@ -44299,8 +43747,8 @@ function getBindingConfig(binding) {
44299
43747
  function evalFieldDefault(value) {
44300
43748
  if (!Array.isArray(value) || value.length === 0) return value;
44301
43749
  const head = value[0];
44302
- const isSExpr = typeof head === "string" && (head.includes("/") || head === "let" || head === "if" || head === "lambda");
44303
- if (!isSExpr) return value;
43750
+ const isSExpr2 = typeof head === "string" && (head.includes("/") || head === "let" || head === "if" || head === "lambda");
43751
+ if (!isSExpr2) return value;
44304
43752
  try {
44305
43753
  return evaluate(value, createMinimalContext({}, {}, ""));
44306
43754
  } catch {
@@ -44374,7 +43822,9 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
44374
43822
  const traitDefs = traitBindings.map(toTraitDefinition);
44375
43823
  const m = new StateMachineManager(traitDefs);
44376
43824
  for (const binding of traitBindings) {
44377
- const cfg = getBindingConfig(binding) ?? traitConfigsByName?.[binding.trait.name];
43825
+ const rawCfg = getBindingConfig(binding);
43826
+ const resolvedCfg = traitConfigsByName?.[binding.trait.name];
43827
+ const cfg = rawCfg || resolvedCfg ? { ...rawCfg ?? {}, ...resolvedCfg ?? {} } : void 0;
44378
43828
  if (cfg !== void 0) {
44379
43829
  m.setTraitConfig(binding.trait.name, cfg);
44380
43830
  }
@@ -44552,7 +44002,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
44552
44002
  };
44553
44003
  }, [traitBindings]);
44554
44004
  const executeTransitionEffects = useCallback(async (params) => {
44555
- const { binding, previousState, newState, payload, flushEvent, syncOnly, log: log10 } = params;
44005
+ const { binding, previousState, newState, payload, flushEvent, syncOnly, log: log9 } = params;
44556
44006
  const traitName = binding.trait.name;
44557
44007
  const linkedEntity = binding.linkedEntity || "";
44558
44008
  const entityId = payload?.entityId;
@@ -44626,10 +44076,20 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
44626
44076
  state: previousState
44627
44077
  };
44628
44078
  const sharedDeclared = collectDeclaredConfigDefaults(binding.trait);
44629
- const sharedCallSite = getBindingConfig(binding);
44630
- if (sharedDeclared || sharedCallSite) {
44079
+ const sharedResolved = traitConfigsByName?.[traitName];
44080
+ const sharedCallSiteRaw = getBindingConfig(binding);
44081
+ const sharedCallSite = sharedCallSiteRaw ? resolveCallSitePayloadCaptures(
44082
+ Object.fromEntries(
44083
+ Object.entries(sharedCallSiteRaw).filter(
44084
+ ([, v]) => !(typeof v === "string" && v.startsWith("@config."))
44085
+ )
44086
+ ),
44087
+ payload || {}
44088
+ ) : void 0;
44089
+ if (sharedDeclared || sharedResolved || sharedCallSite) {
44631
44090
  sharedBindings.config = {
44632
44091
  ...sharedDeclared ?? {},
44092
+ ...sharedResolved ?? {},
44633
44093
  ...sharedCallSite ?? {}
44634
44094
  };
44635
44095
  }
@@ -44663,7 +44123,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
44663
44123
  ...handlers,
44664
44124
  set: async (targetId, field, value) => {
44665
44125
  if (baseSet) await baseSet(targetId, field, value);
44666
- log10.debug("set:write", {
44126
+ log9.debug("set:write", {
44667
44127
  traitName,
44668
44128
  field,
44669
44129
  value: JSON.stringify(value),
@@ -44677,11 +44137,21 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
44677
44137
  state: previousState
44678
44138
  };
44679
44139
  const declaredDefaults = collectDeclaredConfigDefaults(binding.trait);
44140
+ const resolvedDefaults = traitConfigsByName?.[traitName];
44680
44141
  const callSiteConfig = getBindingConfig(binding);
44681
- if (declaredDefaults || callSiteConfig) {
44142
+ const callSiteOverrides = callSiteConfig ? resolveCallSitePayloadCaptures(
44143
+ Object.fromEntries(
44144
+ Object.entries(callSiteConfig).filter(
44145
+ ([, v]) => !(typeof v === "string" && v.startsWith("@config."))
44146
+ )
44147
+ ),
44148
+ payload || {}
44149
+ ) : void 0;
44150
+ if (declaredDefaults || resolvedDefaults || callSiteOverrides) {
44682
44151
  bindingCtx.config = {
44683
44152
  ...declaredDefaults ?? {},
44684
- ...callSiteConfig ?? {}
44153
+ ...resolvedDefaults ?? {},
44154
+ ...callSiteOverrides ?? {}
44685
44155
  };
44686
44156
  }
44687
44157
  if (traitName === "Authority" || traitName === "Hero") {
@@ -44730,7 +44200,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
44730
44200
  if (sharedKey !== void 0) {
44731
44201
  sharedEntityStore.commit(sharedKey, liveEntity);
44732
44202
  }
44733
- log10.debug("effects:executed", () => ({
44203
+ log9.debug("effects:executed", () => ({
44734
44204
  traitName,
44735
44205
  transition: `${previousState}->${newState}`,
44736
44206
  event: flushEvent,
@@ -44740,7 +44210,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
44740
44210
  slotsTouched: Array.from(pendingSlots.keys()).join(",")
44741
44211
  }));
44742
44212
  for (const [slot, patterns] of pendingSlots) {
44743
- log10.debug("flush:slot", {
44213
+ log9.debug("flush:slot", {
44744
44214
  traitName,
44745
44215
  slot,
44746
44216
  patternCount: patterns.length,
@@ -44755,7 +44225,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
44755
44225
  });
44756
44226
  }
44757
44227
  } catch (error) {
44758
- log10.error("effects:error", {
44228
+ log9.error("effects:error", {
44759
44229
  traitName,
44760
44230
  transition: `${previousState}->${newState}`,
44761
44231
  event: flushEvent,
@@ -44777,7 +44247,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
44777
44247
  payload: {},
44778
44248
  state: currentState
44779
44249
  };
44780
- const bindingCfg = getBindingConfig(binding);
44250
+ const bindingCfg = getBindingConfig(binding) ?? traitConfigsByName?.[traitName];
44781
44251
  if (bindingCfg) {
44782
44252
  guardCtx.config = bindingCfg;
44783
44253
  }
@@ -45140,17 +44610,19 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
45140
44610
  }, [traitBindings, eventBus, enqueueAndDrain]);
45141
44611
  useEffect(() => {
45142
44612
  const mgr = managerRef.current;
45143
- const inited = initedTraitsRef.current;
44613
+ const eventsToFire = /* @__PURE__ */ new Set();
45144
44614
  for (const binding of traitBindings) {
45145
44615
  const traitName = binding.trait.name;
45146
- if (inited.has(traitName)) continue;
45147
44616
  const lifecycleEvent = LIFECYCLE_EVENTS.find(
45148
44617
  (evt) => mgr.canHandleEvent(traitName, evt)
45149
44618
  );
45150
- if (lifecycleEvent === void 0) continue;
45151
- inited.add(traitName);
45152
- stateLog.debug("mount:fire-lifecycle", { traitName, event: lifecycleEvent });
45153
- enqueueAndDrain(lifecycleEvent, {});
44619
+ if (lifecycleEvent !== void 0) {
44620
+ eventsToFire.add(lifecycleEvent);
44621
+ }
44622
+ }
44623
+ for (const event of eventsToFire) {
44624
+ stateLog.debug("mount:fire-lifecycle", { event, traitCount: traitBindings.length });
44625
+ enqueueAndDrain(event, {});
45154
44626
  }
45155
44627
  return () => {
45156
44628
  initedTraitsRef.current = /* @__PURE__ */ new Set();
@@ -45265,343 +44737,8 @@ init_Typography();
45265
44737
  init_UISlotRenderer();
45266
44738
  init_useEventBus();
45267
44739
 
45268
- // lib/embedded-traits.ts
45269
- var TRAIT_BINDING_PREFIX = "@trait.";
45270
- function collectTraitRefsFromValue(value, into) {
45271
- if (value === null || value === void 0) return;
45272
- if (typeof value === "string") {
45273
- if (value.startsWith(TRAIT_BINDING_PREFIX)) {
45274
- const rest = value.slice(TRAIT_BINDING_PREFIX.length);
45275
- const dot = rest.indexOf(".");
45276
- const traitName = dot === -1 ? rest : rest.slice(0, dot);
45277
- if (traitName.length > 0) into.add(traitName);
45278
- }
45279
- return;
45280
- }
45281
- if (Array.isArray(value)) {
45282
- for (const item of value) collectTraitRefsFromValue(item, into);
45283
- return;
45284
- }
45285
- if (typeof value === "object") {
45286
- for (const v of Object.values(value)) {
45287
- collectTraitRefsFromValue(v, into);
45288
- }
45289
- }
45290
- }
45291
- function collectTraitRefsFromEffects(effects, into) {
45292
- if (!effects) return;
45293
- for (const effect of effects) {
45294
- if (!Array.isArray(effect)) continue;
45295
- if (effect[0] === "render-ui" && effect.length >= 3) {
45296
- collectTraitRefsFromValue(effect[2], into);
45297
- continue;
45298
- }
45299
- for (let i = 1; i < effect.length; i++) {
45300
- const arg = effect[i];
45301
- if (Array.isArray(arg)) collectTraitRefsFromEffects([arg], into);
45302
- else collectTraitRefsFromValue(arg, into);
45303
- }
45304
- }
45305
- }
45306
- function collectTraitRefsFromResolvedTrait(trait) {
45307
- const out = /* @__PURE__ */ new Set();
45308
- for (const transition of trait.transitions ?? []) {
45309
- collectTraitRefsFromEffects(transition.effects, out);
45310
- }
45311
- for (const tick of trait.ticks ?? []) {
45312
- collectTraitRefsFromEffects(tick.effects, out);
45313
- }
45314
- return out;
45315
- }
45316
- function collectEmbeddedTraits(schema) {
45317
- const out = /* @__PURE__ */ new Set();
45318
- if (!schema?.orbitals) return out;
45319
- for (const orbital of schema.orbitals) {
45320
- const traits2 = orbital.traits;
45321
- if (!Array.isArray(traits2)) continue;
45322
- for (const traitRef of traits2) {
45323
- if (!traitRef || typeof traitRef !== "object") continue;
45324
- const resolved = traitRef._resolved;
45325
- const target = resolved && typeof resolved === "object" ? resolved : traitRef;
45326
- if (target.config) {
45327
- collectTraitRefsFromValue(target.config, out);
45328
- }
45329
- const transitions = target.stateMachine?.transitions;
45330
- if (!Array.isArray(transitions)) continue;
45331
- for (const t of transitions) {
45332
- collectTraitRefsFromEffects(t.effects, out);
45333
- }
45334
- collectTraitRefsFromEffects(target.initialEffects, out);
45335
- const ticks2 = target.ticks;
45336
- if (Array.isArray(ticks2)) {
45337
- for (const tick of ticks2) {
45338
- collectTraitRefsFromEffects(tick.effects, out);
45339
- }
45340
- }
45341
- }
45342
- }
45343
- return out;
45344
- }
45345
-
45346
- // lib/orbitalsByTrait.ts
45347
- function buildOrbitalsByTrait(schema, resolvedPages = []) {
45348
- const map = {};
45349
- if (!schema?.orbitals) return map;
45350
- const pagePathToOrbital = {};
45351
- for (const orb of schema.orbitals) {
45352
- for (const traitRef of orb.traits ?? []) {
45353
- let traitName;
45354
- if (typeof traitRef === "string") {
45355
- const parts = traitRef.split(".");
45356
- traitName = parts[parts.length - 1];
45357
- } else if (typeof traitRef.ref === "string") {
45358
- const parts = traitRef.ref.split(".");
45359
- traitName = traitRef.name ?? parts[parts.length - 1];
45360
- } else if (typeof traitRef.name === "string") {
45361
- traitName = traitRef.name;
45362
- }
45363
- if (traitName) map[traitName] = orb.name;
45364
- }
45365
- for (const pg of orb.pages ?? []) {
45366
- const path = typeof pg === "string" ? pg : pg?.path;
45367
- if (path) pagePathToOrbital[path] = orb.name;
45368
- }
45369
- }
45370
- for (const page of resolvedPages) {
45371
- const orbital = page.path ? pagePathToOrbital[page.path] : void 0;
45372
- if (!orbital) continue;
45373
- for (const traitName of page.traitNames) {
45374
- if (traitName && !(traitName in map)) map[traitName] = orbital;
45375
- }
45376
- }
45377
- return map;
45378
- }
45379
-
45380
44740
  // runtime/OrbPreview.tsx
45381
44741
  init_verificationRegistry();
45382
- var PERF_NAMESPACE = "almadar:perf:canvas";
45383
- var log9 = createLogger(PERF_NAMESPACE);
45384
- var RING_SIZE = 50;
45385
- var ring = [];
45386
- var writeIdx = 0;
45387
- var subscribers = /* @__PURE__ */ new Set();
45388
- var notifyScheduled = false;
45389
- var revision = 0;
45390
- var cachedSnapshot = [];
45391
- var cachedRevision = -1;
45392
- function scheduleNotify() {
45393
- if (notifyScheduled) return;
45394
- notifyScheduled = true;
45395
- queueMicrotask(() => {
45396
- notifyScheduled = false;
45397
- revision++;
45398
- for (const fn of subscribers) fn();
45399
- });
45400
- }
45401
- function push(entry) {
45402
- if (ring.length < RING_SIZE) {
45403
- ring.push(entry);
45404
- } else {
45405
- ring[writeIdx] = entry;
45406
- }
45407
- writeIdx = (writeIdx + 1) % RING_SIZE;
45408
- scheduleNotify();
45409
- }
45410
- function isEnabled() {
45411
- return isLogLevelEnabled("DEBUG", PERF_NAMESPACE);
45412
- }
45413
- function now() {
45414
- return typeof performance !== "undefined" && typeof performance.now === "function" ? performance.now() : Date.now();
45415
- }
45416
- function perfStart(name) {
45417
- if (!isEnabled()) return -1;
45418
- if (typeof performance !== "undefined" && typeof performance.mark === "function") {
45419
- try {
45420
- performance.mark(`${name}-start`);
45421
- } catch {
45422
- }
45423
- }
45424
- return now();
45425
- }
45426
- function perfEnd(name, startToken, detail) {
45427
- if (startToken < 0 || !isEnabled()) return;
45428
- const endTs = now();
45429
- const durationMs = endTs - startToken;
45430
- if (typeof performance !== "undefined" && typeof performance.measure === "function") {
45431
- try {
45432
- performance.mark(`${name}-end`);
45433
- performance.measure(name, `${name}-start`, `${name}-end`);
45434
- } catch {
45435
- }
45436
- }
45437
- push({ name, durationMs, ts: endTs, detail });
45438
- log9.debug(name, () => ({ durationMs, ...detail ?? {} }));
45439
- }
45440
- function perfTime(name, fn, detail) {
45441
- const t = perfStart(name);
45442
- try {
45443
- return fn();
45444
- } finally {
45445
- perfEnd(name, t, detail);
45446
- }
45447
- }
45448
- var profilerOnRender = (id, phase, actualDuration, baseDuration, _startTime, commitTime) => {
45449
- if (!isEnabled()) return;
45450
- push({
45451
- name: `profiler:${id}:${phase}`,
45452
- durationMs: actualDuration,
45453
- ts: commitTime,
45454
- detail: { baseDuration }
45455
- });
45456
- log9.debug(`profiler:${id}:${phase}`, () => ({ actualDuration, baseDuration }));
45457
- };
45458
- function getPerfSnapshot() {
45459
- if (ring.length < RING_SIZE) return ring.slice();
45460
- return [...ring.slice(writeIdx), ...ring.slice(0, writeIdx)];
45461
- }
45462
- function getSnapshot2() {
45463
- if (cachedRevision !== revision) {
45464
- cachedSnapshot = getPerfSnapshot();
45465
- cachedRevision = revision;
45466
- }
45467
- return cachedSnapshot;
45468
- }
45469
- function subscribe(fn) {
45470
- subscribers.add(fn);
45471
- return () => {
45472
- subscribers.delete(fn);
45473
- };
45474
- }
45475
- function usePerfBuffer() {
45476
- return useSyncExternalStore(subscribe, getSnapshot2, getSnapshot2);
45477
- }
45478
- function clearPerf() {
45479
- ring.length = 0;
45480
- writeIdx = 0;
45481
- scheduleNotify();
45482
- }
45483
-
45484
- // lib/prepareSchemaForPreview.ts
45485
- function generateEntityRow(entity, idx) {
45486
- const row = { id: String(idx) };
45487
- for (const f3 of entity.fields) {
45488
- if (f3.name === void 0 || f3.name === "id") continue;
45489
- row[f3.name] = generateFieldValue(entity.name, f3, idx);
45490
- }
45491
- return row;
45492
- }
45493
- function generateFieldValue(entityName, field, idx) {
45494
- if ("values" in field && field.values && field.values.length > 0) {
45495
- return field.values[(idx - 1) % field.values.length];
45496
- }
45497
- const fieldName = field.name ?? "";
45498
- switch (field.type) {
45499
- case "string":
45500
- return `${entityName} ${fieldName.charAt(0).toUpperCase() + fieldName.slice(1)} ${idx}`;
45501
- case "number":
45502
- return idx * 10;
45503
- case "boolean":
45504
- return idx % 2 === 0;
45505
- default:
45506
- return field.default ?? null;
45507
- }
45508
- }
45509
- function buildMockData(schema) {
45510
- const t = perfStart("build-mock-data");
45511
- const result = {};
45512
- for (const orbital of schema.orbitals) {
45513
- const entity = orbital.entity;
45514
- if (!entity || typeof entity === "string") continue;
45515
- if (isEntityCall(entity)) continue;
45516
- const entityName = entity.name;
45517
- if (!entityName) continue;
45518
- if (entity.instances && entity.instances.length > 0) {
45519
- result[entityName] = entity.instances;
45520
- continue;
45521
- }
45522
- const rows = Array.from(
45523
- { length: 10 },
45524
- (_, i) => generateEntityRow(entity, i + 1)
45525
- );
45526
- result[entityName] = rows;
45527
- }
45528
- for (const orbital of schema.orbitals) {
45529
- for (const traitRef of orbital.traits ?? []) {
45530
- if (!isInlineTrait3(traitRef)) continue;
45531
- const trait = traitRef;
45532
- const sourceEntity = trait.sourceEntityDefinition;
45533
- if (!sourceEntity || isEntityCall(sourceEntity)) continue;
45534
- const sourceName = sourceEntity.name;
45535
- if (!sourceName) continue;
45536
- if (!result[sourceName]) {
45537
- result[sourceName] = sourceEntity.instances && sourceEntity.instances.length > 0 ? sourceEntity.instances : Array.from(
45538
- { length: 10 },
45539
- (_, i) => generateEntityRow(sourceEntity, i + 1)
45540
- );
45541
- }
45542
- const reboundName = trait.linkedEntity;
45543
- if (!reboundName || reboundName === sourceName) continue;
45544
- const reboundRows = result[reboundName];
45545
- if (!reboundRows || reboundRows.length === 0) continue;
45546
- reboundRows.forEach((row, i) => {
45547
- for (const f3 of sourceEntity.fields) {
45548
- if (f3.name === void 0 || f3.name === "id") continue;
45549
- if (row[f3.name] !== void 0) continue;
45550
- row[f3.name] = generateFieldValue(sourceName, f3, i + 1);
45551
- }
45552
- });
45553
- }
45554
- }
45555
- perfEnd("build-mock-data", t, { orbitalCount: schema.orbitals.length, entityCount: Object.keys(result).length });
45556
- return result;
45557
- }
45558
- function isInlineTrait3(traitRef) {
45559
- return typeof traitRef === "object" && traitRef !== null && "stateMachine" in traitRef;
45560
- }
45561
- function findDataState(sm, initialStateName) {
45562
- return sm.states.find((s) => {
45563
- if (s.name === initialStateName) return false;
45564
- return sm.transitions.some(
45565
- (t) => t.event === "INIT" && (t.from === s.name || Array.isArray(t.from) && t.from.includes(s.name))
45566
- );
45567
- });
45568
- }
45569
- function rewriteTraitInitialState(trait, mockData) {
45570
- const sm = trait.stateMachine;
45571
- if (!sm) return trait;
45572
- const linkedEntity = trait.linkedEntity;
45573
- if (!linkedEntity || !mockData[linkedEntity]?.length) return trait;
45574
- const initialStateName = sm.states.find((s) => s.isInitial)?.name ?? sm.states[0]?.name;
45575
- if (!initialStateName) return trait;
45576
- const dataState = findDataState(sm, initialStateName);
45577
- if (!dataState) return trait;
45578
- const updatedStates = sm.states.map((s) => {
45579
- if (s.name === initialStateName) return { ...s, isInitial: false };
45580
- if (s.name === dataState.name) return { ...s, isInitial: true };
45581
- return s;
45582
- });
45583
- return { ...trait, stateMachine: { ...sm, states: updatedStates } };
45584
- }
45585
- function adjustSchemaForMockData(schema, mockData) {
45586
- let changed = false;
45587
- const updatedOrbitals = schema.orbitals.map((orbital) => {
45588
- const traits2 = orbital.traits ?? [];
45589
- const updatedTraits = traits2.map((traitRef) => {
45590
- if (!isInlineTrait3(traitRef)) return traitRef;
45591
- const updated = rewriteTraitInitialState(traitRef, mockData);
45592
- if (updated !== traitRef) changed = true;
45593
- return updated;
45594
- });
45595
- return changed ? { ...orbital, traits: updatedTraits } : orbital;
45596
- });
45597
- return changed ? { ...schema, orbitals: updatedOrbitals } : schema;
45598
- }
45599
- function prepareSchemaForPreview(input) {
45600
- const parsed = typeof input === "string" ? JSON.parse(input) : input;
45601
- const mockData = buildMockData(parsed);
45602
- const schema = adjustSchemaForMockData(parsed, mockData);
45603
- return { schema, mockData };
45604
- }
45605
44742
  var xOrbitalLog = createLogger("almadar:runtime:cross-orbital");
45606
44743
  var navLog = createLogger("almadar:runtime:navigation");
45607
44744
  function normalizeChild(child) {
@@ -45835,24 +44972,10 @@ function SchemaRunner({ schema, serverUrl, transport, mockData, pageName, onNavi
45835
44972
  pageOrbitalNames: pageOrbitalNames.join(",")
45836
44973
  });
45837
44974
  }, [pageName, allPageTraits, orbitalsByTrait, pageOrbitalNames]);
45838
- const traitConfigsByName = useMemo(() => {
45839
- const map = {};
45840
- const orbitals = schema?.orbitals;
45841
- if (!orbitals) return map;
45842
- for (const orb of orbitals) {
45843
- const traitRefs = orb.traits;
45844
- if (!traitRefs) continue;
45845
- for (const t of traitRefs) {
45846
- if (typeof t === "string") continue;
45847
- const name = t.name ?? t.ref;
45848
- const config = t.config;
45849
- if (typeof name === "string" && config !== void 0) {
45850
- map[name] = config;
45851
- }
45852
- }
45853
- }
45854
- return map;
45855
- }, [schema]);
44975
+ const traitConfigsByName = useMemo(
44976
+ () => buildResolvedTraitConfigs(schema),
44977
+ [schema]
44978
+ );
45856
44979
  const embeddedTraits = useMemo(() => {
45857
44980
  const set = collectEmbeddedTraits(schema);
45858
44981
  xOrbitalLog.info("SchemaRunner:embeddedTraits", {
@@ -46114,5 +45237,16 @@ function BrowserPlayground({
46114
45237
  }
46115
45238
  );
46116
45239
  }
45240
+ function usePerfBuffer() {
45241
+ return useSyncExternalStore(perfStore.subscribe, perfStore.getSnapshot, perfStore.getSnapshot);
45242
+ }
45243
+ var profilerOnRender = (id, phase, actualDuration, baseDuration, _startTime, commitTime) => {
45244
+ pushPerfEntry({
45245
+ name: `profiler:${id}:${phase}`,
45246
+ durationMs: actualDuration,
45247
+ ts: commitTime,
45248
+ detail: { baseDuration }
45249
+ });
45250
+ };
46117
45251
 
46118
- export { BrowserPlayground, OrbPreview, PERF_NAMESPACE, adjustSchemaForMockData, buildMockData, clearPerf, clearSchemaCache, createClientEffectHandlers, perfEnd, perfStart, perfTime, prepareSchemaForPreview, profilerOnRender, usePerfBuffer, useResolvedSchema, useTraitStateMachine, wrapCallbackForEvent };
45252
+ export { BrowserPlayground, OrbPreview, clearSchemaCache, createClientEffectHandlers, profilerOnRender, usePerfBuffer, useResolvedSchema, useTraitStateMachine };