@almadar/ui 6.15.0 → 6.16.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.
@@ -3388,7 +3388,7 @@ var init_Textarea = __esm({
3388
3388
  init_cn();
3389
3389
  init_useEventBus();
3390
3390
  Textarea = React89__default.forwardRef(
3391
- ({ className, error, onChange, ...props }, ref) => {
3391
+ ({ className, error, onChange, action, onKeyDown, ...props }, ref) => {
3392
3392
  const eventBus = useEventBus();
3393
3393
  const handleChange = (e) => {
3394
3394
  if (typeof onChange === "string") {
@@ -3397,11 +3397,18 @@ var init_Textarea = __esm({
3397
3397
  onChange?.(e);
3398
3398
  }
3399
3399
  };
3400
+ const handleKeyDown = (e) => {
3401
+ onKeyDown?.(e);
3402
+ if (!action || e.key !== "Enter" || !(e.metaKey || e.ctrlKey)) return;
3403
+ e.preventDefault();
3404
+ eventBus.emit(`UI:${action}`, { value: e.currentTarget.value });
3405
+ };
3400
3406
  return /* @__PURE__ */ jsx(
3401
3407
  "textarea",
3402
3408
  {
3403
3409
  ref,
3404
3410
  onChange: handleChange,
3411
+ onKeyDown: handleKeyDown,
3405
3412
  className: cn(
3406
3413
  "block w-full border-[length:var(--border-width)] shadow-sm",
3407
3414
  "px-3 py-2 text-sm text-foreground",
@@ -8936,6 +8943,29 @@ var init_useCanvasGestures = __esm({
8936
8943
  }
8937
8944
  });
8938
8945
 
8946
+ // lib/keyMapEvent.ts
8947
+ function isEditableTarget(target) {
8948
+ if (!(target instanceof HTMLElement)) return false;
8949
+ const tag = target.tagName;
8950
+ if (tag === "INPUT" || tag === "TEXTAREA" || tag === "SELECT") return true;
8951
+ return target.isContentEditable || target.contentEditable === "true";
8952
+ }
8953
+ function keyMapCode(e) {
8954
+ let code = e.code;
8955
+ if (e.altKey) code = `Alt+${code}`;
8956
+ if (e.shiftKey) code = `Shift+${code}`;
8957
+ if (e.metaKey || e.ctrlKey) code = `Mod+${code}`;
8958
+ return code;
8959
+ }
8960
+ function resolveKeyMapEvent(map, e) {
8961
+ if (!map || isEditableTarget(e.target)) return void 0;
8962
+ return map[keyMapCode(e)] ?? map[e.code];
8963
+ }
8964
+ var init_keyMapEvent = __esm({
8965
+ "lib/keyMapEvent.ts"() {
8966
+ }
8967
+ });
8968
+
8939
8969
  // lib/imageCache.ts
8940
8970
  function startLoad(url, onReady, existing) {
8941
8971
  const img = new Image();
@@ -10861,14 +10891,14 @@ function Canvas2D({
10861
10891
  useEffect(() => {
10862
10892
  if (!keyMap && !keyUpMap) return;
10863
10893
  const onDown = (e) => {
10864
- const ev = keyMap?.[e.code];
10894
+ const ev = resolveKeyMapEvent(keyMap, e);
10865
10895
  if (ev) {
10866
10896
  eventBus.emit(`UI:${ev}`, {});
10867
10897
  e.preventDefault();
10868
10898
  }
10869
10899
  };
10870
10900
  const onUp = (e) => {
10871
- const ev = keyUpMap?.[e.code];
10901
+ const ev = resolveKeyMapEvent(keyUpMap, e);
10872
10902
  if (ev) eventBus.emit(`UI:${ev}`, {});
10873
10903
  };
10874
10904
  window.addEventListener("keydown", onDown);
@@ -10992,6 +11022,7 @@ var init_Canvas2D = __esm({
10992
11022
  init_useCamera();
10993
11023
  init_useCanvasGestures();
10994
11024
  init_verificationRegistry();
11025
+ init_keyMapEvent();
10995
11026
  init_webPainter2d();
10996
11027
  init_projector();
10997
11028
  init_paintDispatch();
@@ -27430,6 +27461,40 @@ var init_DashboardLayout = __esm({
27430
27461
  NavLinkBottom.displayName = "NavLinkBottom";
27431
27462
  }
27432
27463
  });
27464
+
27465
+ // lib/relationLabel.ts
27466
+ function relationLabel(value) {
27467
+ if (value === null || typeof value !== "object" || Array.isArray(value) || value instanceof Date)
27468
+ return null;
27469
+ for (const key of ["name", "title", "label"]) {
27470
+ const candidate = value[key];
27471
+ if (typeof candidate === "string" && candidate !== "") return candidate;
27472
+ }
27473
+ const id = value.id;
27474
+ return id !== void 0 && id !== null ? String(id) : null;
27475
+ }
27476
+ function relationDisplayLabels(value, options) {
27477
+ if (value === void 0 || value === null || value === "") return [];
27478
+ if (Array.isArray(value)) {
27479
+ return value.flatMap((item) => relationDisplayLabels(item, options));
27480
+ }
27481
+ const hydrated = relationLabel(value);
27482
+ if (hydrated !== null) return [hydrated];
27483
+ const raw = String(value);
27484
+ const match = options?.find((opt) => opt.value === raw);
27485
+ return [match ? match.label : raw];
27486
+ }
27487
+ function resolveRelationCellDisplay(value, options) {
27488
+ if (value === null || value === void 0 || value === "") return void 0;
27489
+ const isObjectShaped = typeof value === "object" && !(value instanceof Date) || Array.isArray(value) && value.some((v) => v !== null && typeof v === "object" && !(v instanceof Date));
27490
+ if (!isObjectShaped && !options) return void 0;
27491
+ const labels = relationDisplayLabels(value, options);
27492
+ return labels.length > 0 ? labels.join(", ") : void 0;
27493
+ }
27494
+ var init_relationLabel = __esm({
27495
+ "lib/relationLabel.ts"() {
27496
+ }
27497
+ });
27433
27498
  function downloadItemUrl(url, label) {
27434
27499
  const a = document.createElement("a");
27435
27500
  a.href = url;
@@ -28261,7 +28326,8 @@ function DataGrid({
28261
28326
  positionEvent,
28262
28327
  dndItemIdField,
28263
28328
  dndRoot,
28264
- look = "dense"
28329
+ look = "dense",
28330
+ relationsData
28265
28331
  }) {
28266
28332
  const eventBus = useEventBus();
28267
28333
  const { t } = useTranslate();
@@ -28451,6 +28517,10 @@ function DataGrid({
28451
28517
  );
28452
28518
  }
28453
28519
  const titleValue = getNestedValue(itemData, titleField?.name ?? "");
28520
+ const titleDisplay = resolveRelationCellDisplay(
28521
+ titleValue,
28522
+ titleField ? relationsData?.[titleField.name] : void 0
28523
+ ) ?? (titleValue !== void 0 && titleValue !== null ? String(titleValue) : void 0);
28454
28524
  return wrapDnd(
28455
28525
  /* @__PURE__ */ jsxs(
28456
28526
  Box,
@@ -28475,7 +28545,7 @@ function DataGrid({
28475
28545
  "img",
28476
28546
  {
28477
28547
  src: imgUrl,
28478
- alt: titleValue !== void 0 ? String(titleValue) : "",
28548
+ alt: titleDisplay ?? "",
28479
28549
  className: "w-full h-full object-cover",
28480
28550
  loading: "lazy"
28481
28551
  }
@@ -28490,18 +28560,18 @@ function DataGrid({
28490
28560
  onChange: () => toggleSelection(id),
28491
28561
  onClick: (e) => e.stopPropagation(),
28492
28562
  className: "w-4 h-4 mt-1 flex-shrink-0 accent-primary",
28493
- "aria-label": t("card.selectItem", { item: titleValue !== void 0 ? String(titleValue) : t("card.itemFallback") })
28563
+ "aria-label": t("card.selectItem", { item: titleDisplay ?? t("card.itemFallback") })
28494
28564
  }
28495
28565
  ),
28496
28566
  /* @__PURE__ */ jsxs(VStack, { gap: "xs", className: "flex-1 min-w-0", children: [
28497
- titleValue !== void 0 && titleValue !== null && /* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "items-center min-w-0", children: [
28567
+ titleDisplay !== void 0 && /* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "items-center min-w-0", children: [
28498
28568
  titleField?.icon && renderIconInput(titleField.icon, { size: "sm", className: "text-primary flex-shrink-0" }),
28499
28569
  /* @__PURE__ */ jsx(
28500
28570
  Typography,
28501
28571
  {
28502
28572
  variant: titleField?.variant === "h3" ? "h3" : "h4",
28503
28573
  className: "font-semibold truncate min-w-0",
28504
- children: String(titleValue)
28574
+ children: titleDisplay
28505
28575
  }
28506
28576
  )
28507
28577
  ] }),
@@ -28510,7 +28580,7 @@ function DataGrid({
28510
28580
  if (val === void 0 || val === null || val === "") return null;
28511
28581
  return /* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "items-center", children: [
28512
28582
  field.icon && renderIconInput(field.icon, { size: "xs" }),
28513
- /* @__PURE__ */ jsx(Badge, { variant: resolveBadgeVariant(field, String(val)), children: humanizeEnumValue(formatValue(val, field.format)) })
28583
+ /* @__PURE__ */ jsx(Badge, { variant: resolveBadgeVariant(field, String(val)), children: resolveRelationCellDisplay(val, relationsData?.[field.name]) ?? humanizeEnumValue(formatValue(val, field.format)) })
28514
28584
  ] }, field.name);
28515
28585
  }) })
28516
28586
  ] }),
@@ -28549,7 +28619,7 @@ function DataGrid({
28549
28619
  bodyFields.filter((f3) => f3.variant === "caption" && f3.format !== "boolean").map((field) => {
28550
28620
  const value = getNestedValue(itemData, field.name);
28551
28621
  if (value === void 0 || value === null || value === "") return null;
28552
- return /* @__PURE__ */ jsx(Typography, { variant: "small", color: "secondary", className: "line-clamp-2", children: formatValue(value, field.format) }, field.name);
28622
+ return /* @__PURE__ */ jsx(Typography, { variant: "small", color: "secondary", className: "line-clamp-2", children: resolveRelationCellDisplay(value, relationsData?.[field.name]) ?? formatValue(value, field.format) }, field.name);
28553
28623
  }),
28554
28624
  /* @__PURE__ */ jsx(HStack, { gap: "md", className: "flex-wrap gap-y-1", children: bodyFields.filter((f3) => f3.variant !== "caption" || f3.format === "boolean").map((field) => {
28555
28625
  const value = getNestedValue(itemData, field.name);
@@ -28564,7 +28634,7 @@ function DataGrid({
28564
28634
  return /* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "items-center", children: [
28565
28635
  field.icon && renderIconInput(field.icon, { size: "xs", className: "text-muted-foreground" }),
28566
28636
  /* @__PURE__ */ jsx(Typography, { variant: "caption", color: "secondary", className: "sr-only", children: (field.label ?? fieldLabel2(field.name)) + ":" }),
28567
- /* @__PURE__ */ jsx(Typography, { variant: "small", color: "secondary", children: formatValue(value, field.format) })
28637
+ /* @__PURE__ */ jsx(Typography, { variant: "small", color: "secondary", children: resolveRelationCellDisplay(value, relationsData?.[field.name]) ?? formatValue(value, field.format) })
28568
28638
  ] }, field.name);
28569
28639
  }) })
28570
28640
  ] }) })
@@ -28608,6 +28678,7 @@ var init_DataGrid = __esm({
28608
28678
  "use client";
28609
28679
  init_cn();
28610
28680
  init_format();
28681
+ init_relationLabel();
28611
28682
  init_getNestedValue();
28612
28683
  init_useEventBus();
28613
28684
  init_Box();
@@ -28660,7 +28731,9 @@ function statusVariant3(value) {
28660
28731
  if (["new", "created", "scheduled", "queued", "info"].includes(v)) return "info";
28661
28732
  return "default";
28662
28733
  }
28663
- function formatValue2(value, format, boolLabels) {
28734
+ function formatValue2(value, format, boolLabels, relationOptions) {
28735
+ const relationDisplay = resolveRelationCellDisplay(value, relationOptions);
28736
+ if (relationDisplay !== void 0) return relationDisplay;
28664
28737
  if (value !== void 0 && value !== null && (format === "boolean" || typeof value === "boolean")) {
28665
28738
  const isNo = value === false || value === 0 || String(value) === "false";
28666
28739
  return isNo ? boolLabels?.no ?? "No" : boolLabels?.yes ?? "Yes";
@@ -28720,7 +28793,8 @@ function DataList({
28720
28793
  positionEvent,
28721
28794
  dndItemIdField,
28722
28795
  dndRoot,
28723
- look = "dense"
28796
+ look = "dense",
28797
+ relationsData
28724
28798
  }) {
28725
28799
  const eventBus = useEventBus();
28726
28800
  const { t } = useTranslate();
@@ -28908,13 +28982,13 @@ function DataList({
28908
28982
  return f3.variant === "badge" ? (
28909
28983
  // `format` applies here too — a boolean field badged
28910
28984
  // without it renders the raw "false" instead of "No".
28911
- /* @__PURE__ */ jsx(Badge, { variant: statusVariant3(String(v)), children: formatValue2(v, f3.format) }, f3.name)
28985
+ /* @__PURE__ */ jsx(Badge, { variant: statusVariant3(String(v)), children: formatValue2(v, f3.format, void 0, relationsData?.[f3.name]) }, f3.name)
28912
28986
  ) : /* @__PURE__ */ jsx(
28913
28987
  Typography,
28914
28988
  {
28915
28989
  variant: "caption",
28916
28990
  className: cn("text-xs", isSent ? "opacity-70" : "text-muted-foreground"),
28917
- children: formatValue2(v, f3.format)
28991
+ children: formatValue2(v, f3.format, void 0, relationsData?.[f3.name])
28918
28992
  },
28919
28993
  f3.name
28920
28994
  );
@@ -28992,6 +29066,10 @@ function DataList({
28992
29066
  }
28993
29067
  const id = itemData.id || String(index);
28994
29068
  const titleValue = getNestedValue(itemData, titleField?.name ?? "");
29069
+ const titleDisplay = resolveRelationCellDisplay(
29070
+ titleValue,
29071
+ titleField ? relationsData?.[titleField.name] : void 0
29072
+ ) ?? (titleValue !== void 0 && titleValue !== null ? String(titleValue) : void 0);
28995
29073
  return wrapDnd(
28996
29074
  /* @__PURE__ */ jsxs(Box, { "data-entity-row": true, "data-entity-id": id, onClick: rowClickEvent ? handleRowClick(itemData) : void 0, className: cn(rowClickEvent && "cursor-pointer"), children: [
28997
29075
  /* @__PURE__ */ jsxs(
@@ -29016,7 +29094,7 @@ function DataList({
29016
29094
  {
29017
29095
  variant: titleField?.variant === "h3" ? "h3" : "h4",
29018
29096
  className: cn("font-semibold truncate flex-1", isCompact && "text-sm"),
29019
- children: String(titleValue)
29097
+ children: titleDisplay
29020
29098
  }
29021
29099
  ),
29022
29100
  badgeFields.map((field) => {
@@ -29024,7 +29102,7 @@ function DataList({
29024
29102
  if (val === void 0 || val === null) return null;
29025
29103
  return /* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "items-center flex-shrink-0", children: [
29026
29104
  field.icon && renderIconInput2(field.icon, { size: "xs" }),
29027
- /* @__PURE__ */ jsx(Badge, { variant: statusVariant3(String(val)), children: formatValue2(val, field.format) })
29105
+ /* @__PURE__ */ jsx(Badge, { variant: statusVariant3(String(val)), children: formatValue2(val, field.format, void 0, relationsData?.[field.name]) })
29028
29106
  ] }, field.name);
29029
29107
  })
29030
29108
  ] }),
@@ -29045,7 +29123,7 @@ function DataList({
29045
29123
  ]
29046
29124
  }
29047
29125
  ),
29048
- /* @__PURE__ */ jsx(Typography, { variant: "small", color: "secondary", children: formatValue2(value, field.format, { yes: t("common.yes"), no: t("common.no") }) })
29126
+ /* @__PURE__ */ jsx(Typography, { variant: "small", color: "secondary", children: formatValue2(value, field.format, { yes: t("common.yes"), no: t("common.no") }, relationsData?.[field.name]) })
29049
29127
  ] }, field.name);
29050
29128
  }) }),
29051
29129
  progressFields.map((field) => {
@@ -29125,6 +29203,7 @@ var init_DataList = __esm({
29125
29203
  "use client";
29126
29204
  init_cn();
29127
29205
  init_format();
29206
+ init_relationLabel();
29128
29207
  init_getNestedValue();
29129
29208
  init_useEventBus();
29130
29209
  init_Box();
@@ -32969,6 +33048,7 @@ var init_MathCanvas = __esm({
32969
33048
  "use client";
32970
33049
  init_useEventBus();
32971
33050
  init_perf();
33051
+ init_keyMapEvent();
32972
33052
  init_atoms();
32973
33053
  init_Stack();
32974
33054
  init_gameFonts();
@@ -33022,14 +33102,14 @@ var init_MathCanvas = __esm({
33022
33102
  useEffect(() => {
33023
33103
  if (!stableKeyMap && !stableKeyUpMap) return;
33024
33104
  const onDown = (e) => {
33025
- const ev = stableKeyMap?.[e.code];
33105
+ const ev = resolveKeyMapEvent(stableKeyMap, e);
33026
33106
  if (ev) {
33027
33107
  eventBus.emit(`UI:${ev}`, {});
33028
33108
  e.preventDefault();
33029
33109
  }
33030
33110
  };
33031
33111
  const onUp = (e) => {
33032
- const ev = stableKeyUpMap?.[e.code];
33112
+ const ev = resolveKeyMapEvent(stableKeyUpMap, e);
33033
33113
  if (ev) eventBus.emit(`UI:${ev}`, {});
33034
33114
  };
33035
33115
  window.addEventListener("keydown", onDown);
@@ -35445,33 +35525,6 @@ var init_Lightbox = __esm({
35445
35525
  Lightbox.displayName = "Lightbox";
35446
35526
  }
35447
35527
  });
35448
-
35449
- // lib/relationLabel.ts
35450
- function relationLabel(value) {
35451
- if (value === null || typeof value !== "object" || Array.isArray(value) || value instanceof Date)
35452
- return null;
35453
- for (const key of ["name", "title", "label"]) {
35454
- const candidate = value[key];
35455
- if (typeof candidate === "string" && candidate !== "") return candidate;
35456
- }
35457
- const id = value.id;
35458
- return id !== void 0 && id !== null ? String(id) : null;
35459
- }
35460
- function relationDisplayLabels(value, options) {
35461
- if (value === void 0 || value === null || value === "") return [];
35462
- if (Array.isArray(value)) {
35463
- return value.flatMap((item) => relationDisplayLabels(item, options));
35464
- }
35465
- const hydrated = relationLabel(value);
35466
- if (hydrated !== null) return [hydrated];
35467
- const raw = String(value);
35468
- const match = options?.find((opt) => opt.value === raw);
35469
- return [match ? match.label : raw];
35470
- }
35471
- var init_relationLabel = __esm({
35472
- "lib/relationLabel.ts"() {
35473
- }
35474
- });
35475
35528
  function renderIconInput3(icon, props) {
35476
35529
  return typeof icon === "string" ? /* @__PURE__ */ jsx(Icon, { name: icon, ...props }) : /* @__PURE__ */ jsx(Icon, { icon, ...props });
35477
35530
  }
@@ -35535,7 +35588,8 @@ function TableView({
35535
35588
  reorderEvent,
35536
35589
  positionEvent,
35537
35590
  dndItemIdField,
35538
- dndRoot
35591
+ dndRoot,
35592
+ relationsData
35539
35593
  }) {
35540
35594
  const eventBus = useEventBus();
35541
35595
  const { t } = useTranslate();
@@ -35620,7 +35674,7 @@ function TableView({
35620
35674
  const colFloors = React89__default.useMemo(
35621
35675
  () => colDefs.map((col) => {
35622
35676
  const longest = data.reduce((widest, row) => {
35623
- const cell = formatCell(asFieldValue(getNestedValue(row, col.field ?? col.key)), col.format);
35677
+ const cell = formatCell(asFieldValue(getNestedValue(row, col.field ?? col.key)), col.format, relationsData?.[col.field ?? col.key]);
35624
35678
  return Math.max(widest, cell.length);
35625
35679
  }, columnLabel(col).length);
35626
35680
  const chrome = col.format === "badge" ? BADGE_CHROME_CH : 0;
@@ -35720,9 +35774,11 @@ function TableView({
35720
35774
  col.className
35721
35775
  );
35722
35776
  if (col.format === "badge" && raw != null && raw !== "") {
35723
- return /* @__PURE__ */ jsx(Box, { role: "cell", className: cellBase, children: /* @__PURE__ */ jsx(Badge, { variant: statusVariant4(String(raw)), size: "sm", className: "whitespace-nowrap", children: humanizeEnumValue(String(raw)) }) }, col.key);
35777
+ const relationDisplay = resolveRelationCellDisplay(raw, relationsData?.[col.field ?? col.key]);
35778
+ const label = relationDisplay ?? humanizeEnumValue(String(raw));
35779
+ return /* @__PURE__ */ jsx(Box, { role: "cell", className: cellBase, children: /* @__PURE__ */ jsx(Badge, { variant: statusVariant4(String(raw)), size: "sm", className: "whitespace-nowrap", children: label }) }, col.key);
35724
35780
  }
35725
- return /* @__PURE__ */ jsx(Box, { role: "cell", className: cellBase, children: /* @__PURE__ */ jsx("span", { className: "truncate text-foreground", children: formatCell(raw, col.format) }) }, col.key);
35781
+ return /* @__PURE__ */ jsx(Box, { role: "cell", className: cellBase, children: /* @__PURE__ */ jsx("span", { className: "truncate text-foreground", children: formatCell(raw, col.format, relationsData?.[col.field ?? col.key]) }) }, col.key);
35726
35782
  }),
35727
35783
  hasActions && /* @__PURE__ */ jsxs(
35728
35784
  HStack,
@@ -35824,11 +35880,9 @@ var init_TableView = __esm({
35824
35880
  init_Menu();
35825
35881
  init_useDataDnd();
35826
35882
  tableViewLog = createLogger("almadar:ui:table-view");
35827
- formatCell = (value, format) => {
35828
- if (value !== null && value !== void 0 && typeof value === "object" && !(value instanceof Date)) {
35829
- const labels = relationDisplayLabels(value);
35830
- if (labels.length > 0) return labels.join(", ");
35831
- }
35883
+ formatCell = (value, format, relationOptions) => {
35884
+ const relationDisplay = resolveRelationCellDisplay(value, relationOptions);
35885
+ if (relationDisplay !== void 0) return relationDisplay;
35832
35886
  return formatValue(value, format);
35833
35887
  };
35834
35888
  MAX_MEASURED_COL_CH = 32;
@@ -44538,7 +44592,8 @@ function DataTable({
44538
44592
  headerActions,
44539
44593
  showTotal = true,
44540
44594
  className,
44541
- look = "dense"
44595
+ look = "dense",
44596
+ relationsData
44542
44597
  }) {
44543
44598
  const [openActionMenu, setOpenActionMenu] = useState(
44544
44599
  null
@@ -44833,6 +44888,11 @@ function DataTable({
44833
44888
  "data-column": String(col.key),
44834
44889
  className: "px-4 py-3 text-sm text-foreground whitespace-nowrap sm:whitespace-normal",
44835
44890
  children: col.render ? col.render(cellValue, row, rowIndex) : (() => {
44891
+ const relationDisplay = resolveRelationCellDisplay(
44892
+ cellValue,
44893
+ relationsData?.[String(col.key)]
44894
+ );
44895
+ if (relationDisplay !== void 0) return relationDisplay;
44836
44896
  const boolVal = asBooleanValue2(cellValue);
44837
44897
  if (boolVal !== null) {
44838
44898
  return boolVal ? /* @__PURE__ */ jsx(Badge, { variant: "success", children: t("common.yes") }) : /* @__PURE__ */ jsx(Badge, { variant: "neutral", children: t("common.no") });
@@ -44921,6 +44981,7 @@ var init_DataTable = __esm({
44921
44981
  init_cn();
44922
44982
  init_format();
44923
44983
  init_getNestedValue();
44984
+ init_relationLabel();
44924
44985
  init_atoms();
44925
44986
  init_Box();
44926
44987
  init_Stack();
@@ -54367,6 +54428,26 @@ function createCommandSendPump() {
54367
54428
  }
54368
54429
  };
54369
54430
  }
54431
+
54432
+ // lib/cascadeEcho.ts
54433
+ function stampLocallyDeliveredEchoes(dispatchedEvent, emitted, locallyEmitted) {
54434
+ const remainingLocal = /* @__PURE__ */ new Map();
54435
+ for (const name of locallyEmitted) {
54436
+ remainingLocal.set(name, (remainingLocal.get(name) ?? 0) + 1);
54437
+ }
54438
+ const result = [];
54439
+ for (const entry of emitted) {
54440
+ if (entry.event === dispatchedEvent) continue;
54441
+ const remaining = remainingLocal.get(entry.event) ?? 0;
54442
+ if (remaining > 0) {
54443
+ remainingLocal.set(entry.event, remaining - 1);
54444
+ result.push({ ...entry, source: { ...entry.source, dispatched: true } });
54445
+ } else {
54446
+ result.push(entry);
54447
+ }
54448
+ }
54449
+ return result;
54450
+ }
54370
54451
  var xOrbitalLog = createLogger("almadar:runtime:cross-orbital");
54371
54452
  var serverBridgeLog = createLogger("almadar:ui:server-bridge");
54372
54453
  function reEmitServerEvent(eventBus, emitted, origin) {
@@ -54523,7 +54604,7 @@ function ServerBridgeProvider({
54523
54604
  disposedRef.current = true;
54524
54605
  };
54525
54606
  }, []);
54526
- const sendEvent = useCallback(async (orbitalName, event, payload, tick, sourceTrait) => {
54607
+ const sendEvent = useCallback(async (orbitalName, event, payload, tick, sourceTrait, locallyEmitted) => {
54527
54608
  const emptyMeta = { success: false, transitioned: false, clientEffects: 0, dataEntities: {}, emittedEvents: [] };
54528
54609
  if (!connected) return { effects: [], meta: emptyMeta };
54529
54610
  if (tick !== void 0) {
@@ -54583,13 +54664,8 @@ function ServerBridgeProvider({
54583
54664
  }
54584
54665
  }
54585
54666
  if (result.emittedEvents) {
54586
- for (const emitted of result.emittedEvents) {
54587
- if (emitted.event === event) continue;
54588
- reEmitServerEvent(
54589
- eventBus,
54590
- { ...emitted, source: { ...emitted.source, dispatched: true } },
54591
- orbitalName
54592
- );
54667
+ for (const emitted of stampLocallyDeliveredEchoes(event, result.emittedEvents, locallyEmitted ?? [])) {
54668
+ reEmitServerEvent(eventBus, emitted, orbitalName);
54593
54669
  }
54594
54670
  }
54595
54671
  } else if (result.error) {