@almadar/ui 6.57.0 → 6.59.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.
Files changed (32) hide show
  1. package/dist/{AwaitingSkeletonContext-DPgW__WV.d.ts → AwaitingSkeletonContext-Bh399p1x.d.ts} +1 -3
  2. package/dist/{Canvas3DHost-DfAhg6EH.d.ts → Canvas3DHost-CNjANoaU.d.ts} +1 -1
  3. package/dist/{GameAudioProvider-DyBvYP2c.d.ts → GameAudioProvider-Dv_L-PHt.d.ts} +1 -1
  4. package/dist/{UISlotRenderer-NCGDIXN4.js → UISlotRenderer-YNY7V2UJ.js} +2 -2
  5. package/dist/avl/index.cjs +137 -71
  6. package/dist/avl/index.js +24 -8
  7. package/dist/{chunk-GZGDBS4S.js → chunk-7CVXM2KS.js} +1 -1
  8. package/dist/{chunk-PYJ2UQWM.js → chunk-E6MWYQVZ.js} +42 -35
  9. package/dist/{chunk-HA7CJWQX.js → chunk-J755QADM.js} +1184 -1184
  10. package/dist/{chunk-VHTJRS2N.js → chunk-L3MTZ3RH.js} +7 -0
  11. package/dist/{chunk-RHP5WL55.js → chunk-QJIAJ6EH.js} +77 -42
  12. package/dist/components/index.cjs +76 -32
  13. package/dist/components/index.d.ts +9 -7
  14. package/dist/components/index.js +5 -5
  15. package/dist/context/index.cjs +7 -0
  16. package/dist/context/index.js +1 -1
  17. package/dist/hooks/index.cjs +7 -0
  18. package/dist/hooks/index.js +1 -1
  19. package/dist/lib/drawable/three/index.d.ts +3 -3
  20. package/dist/lib/drawable/three/index.js +3 -3
  21. package/dist/lib/index.d.ts +2 -2
  22. package/dist/{paintDispatch-_6EhJCiL.d.ts → paintDispatch-Cp1_S93j.d.ts} +30 -2
  23. package/dist/providers/index.cjs +51 -50
  24. package/dist/providers/index.d.ts +4 -4
  25. package/dist/providers/index.js +8 -21
  26. package/dist/runtime/index.cjs +120 -70
  27. package/dist/runtime/index.d.ts +4 -4
  28. package/dist/runtime/index.js +4 -4
  29. package/dist/ssr/index.cjs +2 -0
  30. package/dist/ssr/index.js +2 -0
  31. package/dist/{verificationRegistry-CD7Xb40L.d.ts → verificationRegistry-B3dj1Zl8.d.ts} +1 -1
  32. package/package.json +9 -8
@@ -79,6 +79,7 @@ var utilities = require('@dnd-kit/utilities');
79
79
  var emojilib = require('emojilib');
80
80
  var d3Force = require('d3-force');
81
81
  var react = require('@xyflow/react');
82
+ var mock = require('@almadar/db/mock');
82
83
  var OrbitalServerRuntime = require('@almadar/runtime/OrbitalServerRuntime');
83
84
 
84
85
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
@@ -7663,6 +7664,7 @@ var init_Avatar = __esm({
7663
7664
  statusClasses[status],
7664
7665
  statusSizeClasses[size2]
7665
7666
  ),
7667
+ role: "img",
7666
7668
  "aria-label": t("avatar.status", { status: t(`avatar.status.${status}`) })
7667
7669
  }
7668
7670
  ),
@@ -10299,6 +10301,7 @@ var init_AnimatedGraphic = __esm({
10299
10301
  "div",
10300
10302
  {
10301
10303
  className: "w-full h-full [&>svg]:w-full [&>svg]:h-full",
10304
+ "aria-hidden": "true",
10302
10305
  dangerouslySetInnerHTML: { __html: resolvedSvg }
10303
10306
  }
10304
10307
  ) : children
@@ -18786,6 +18789,7 @@ var init_Tabs = __esm({
18786
18789
  }
18787
18790
  };
18788
18791
  const activeTabContent = safeItems.find((item) => item.id === activeTab)?.content;
18792
+ const rendersPanel = activeTabContent !== void 0 && activeTabContent !== null;
18789
18793
  if (safeItems.length === 0) {
18790
18794
  return /* @__PURE__ */ jsxRuntime.jsx(Box, { ...domPassthrough(rest), className: cn("w-full", className), children: /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "small", color: "muted", className: "py-4", children: t("empty.noItems") }) });
18791
18795
  }
@@ -18836,7 +18840,7 @@ var init_Tabs = __esm({
18836
18840
  id: tabId(item.id),
18837
18841
  role: "tab",
18838
18842
  "aria-selected": isActive,
18839
- "aria-controls": isActive ? panelId(item.id) : void 0,
18843
+ "aria-controls": isActive && rendersPanel ? panelId(item.id) : void 0,
18840
18844
  "aria-disabled": isDisabled,
18841
18845
  tabIndex: isActive ? 0 : -1,
18842
18846
  onClick: () => !isDisabled && handleTabChange(item.id, item.event),
@@ -18896,7 +18900,7 @@ var init_Tabs = __esm({
18896
18900
  )
18897
18901
  ] })
18898
18902
  ] }) : tablist,
18899
- activeTabContent !== void 0 && activeTabContent !== null && /* @__PURE__ */ jsxRuntime.jsx(
18903
+ rendersPanel && /* @__PURE__ */ jsxRuntime.jsx(
18900
18904
  Box,
18901
18905
  {
18902
18906
  role: "tabpanel",
@@ -25073,8 +25077,10 @@ var init_AvlFieldType = __esm({
25073
25077
  pattern: "hexagon",
25074
25078
  node: "hexagon",
25075
25079
  event: "hexagon",
25080
+ EventAddress: "hexagon",
25076
25081
  SExpr: "hexagon",
25077
25082
  array: "bars",
25083
+ tuple: "bars",
25078
25084
  relation: "link"
25079
25085
  };
25080
25086
  AvlFieldType = ({
@@ -34207,8 +34213,11 @@ function DataGrid({
34207
34213
  children: [
34208
34214
  imageField && (() => {
34209
34215
  const imgUrl = resolveImageUrl(core.getNestedValue(itemData, imageField));
34210
- if (!imgUrl) return null;
34211
- return /* @__PURE__ */ jsxRuntime.jsx(Box, { className: asRows ? "w-12 h-12 flex-shrink-0 overflow-hidden rounded-container" : "w-full aspect-video overflow-hidden rounded-t-container", children: /* @__PURE__ */ jsxRuntime.jsx(
34216
+ const mediaClass = asRows ? "w-12 h-12 flex-shrink-0 overflow-hidden rounded-container" : "w-full aspect-video overflow-hidden rounded-t-container";
34217
+ if (!imgUrl) {
34218
+ return /* @__PURE__ */ jsxRuntime.jsx(Box, { "data-media-placeholder": true, "aria-hidden": "true", className: cn(mediaClass, "flex items-center justify-center bg-muted text-muted-foreground"), children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "image", size: asRows ? "sm" : "lg" }) });
34219
+ }
34220
+ return /* @__PURE__ */ jsxRuntime.jsx(Box, { className: mediaClass, children: /* @__PURE__ */ jsxRuntime.jsx(
34212
34221
  "img",
34213
34222
  {
34214
34223
  src: imgUrl,
@@ -34241,7 +34250,7 @@ function DataGrid({
34241
34250
  Typography,
34242
34251
  {
34243
34252
  variant: titleField?.variant === "h3" && !asRows ? "h3" : "h4",
34244
- className: "font-semibold truncate min-w-0",
34253
+ className: cn("font-semibold min-w-0", asRows ? "truncate" : "line-clamp-2 break-words"),
34245
34254
  children: titleDisplay
34246
34255
  }
34247
34256
  )
@@ -34370,24 +34379,33 @@ var init_DataGrid = __esm({
34370
34379
  DataGrid.displayName = "DataGrid";
34371
34380
  }
34372
34381
  });
34373
- function renderIconInput2(icon, props) {
34374
- return typeof icon === "string" ? /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: icon, ...props }) : /* @__PURE__ */ jsxRuntime.jsx(Icon, { icon, ...props });
34375
- }
34376
- function formatValue2(value, format, fmt2, relationOptions) {
34377
- const relationDisplay = resolveRelationCellDisplay(value, relationOptions);
34378
- if (relationDisplay !== void 0) return relationDisplay;
34379
- return formatValue(value, format, fmt2);
34380
- }
34381
- function groupData(items, field) {
34382
+
34383
+ // lib/groupRows.ts
34384
+ function groupRows(items, field, format, fmt2 = {}) {
34382
34385
  const groups = /* @__PURE__ */ new Map();
34383
34386
  for (const item of items) {
34384
- const key = String(core.getNestedValue(item, field) ?? "");
34387
+ const raw = core.getNestedValue(item, field);
34388
+ const key = format ? formatValue(raw ?? void 0, format, fmt2) : String(raw ?? "");
34385
34389
  const group = groups.get(key);
34386
34390
  if (group) group.push(item);
34387
34391
  else groups.set(key, [item]);
34388
34392
  }
34389
34393
  return Array.from(groups.entries()).map(([label, groupItems]) => ({ label, items: groupItems }));
34390
34394
  }
34395
+ var init_groupRows = __esm({
34396
+ "lib/groupRows.ts"() {
34397
+ init_format();
34398
+ init_getNestedValue();
34399
+ }
34400
+ });
34401
+ function renderIconInput2(icon, props) {
34402
+ return typeof icon === "string" ? /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: icon, ...props }) : /* @__PURE__ */ jsxRuntime.jsx(Icon, { icon, ...props });
34403
+ }
34404
+ function formatValue2(value, format, fmt2, relationOptions) {
34405
+ const relationDisplay = resolveRelationCellDisplay(value, relationOptions);
34406
+ if (relationDisplay !== void 0) return relationDisplay;
34407
+ return formatValue(value, format, fmt2);
34408
+ }
34391
34409
  function DataList({
34392
34410
  entity,
34393
34411
  fields,
@@ -34398,6 +34416,7 @@ function DataList({
34398
34416
  gap = "none",
34399
34417
  variant = "default",
34400
34418
  groupBy,
34419
+ groupFormat,
34401
34420
  senderField,
34402
34421
  senderLabelField,
34403
34422
  currentUser,
@@ -34505,9 +34524,9 @@ function DataList({
34505
34524
  e.stopPropagation();
34506
34525
  fireRowAction(action, itemData, String(itemData.id ?? ""));
34507
34526
  };
34508
- const renderItemActions = (itemData, onPrimary = false) => {
34527
+ const renderItemActions = (itemData, onPrimary = false, only) => {
34509
34528
  if (!itemActions || itemActions.length === 0) return null;
34510
- const shown = rowActions(itemActions, itemData);
34529
+ const shown = only ?? rowActions(itemActions, itemData);
34511
34530
  if (shown.length === 0) return null;
34512
34531
  const inline = maxInlineActions != null ? shown.slice(0, maxInlineActions) : shown;
34513
34532
  const overflow = maxInlineActions != null ? shown.slice(maxInlineActions) : [];
@@ -34591,7 +34610,7 @@ function DataList({
34591
34610
  const isMessage = variant === "message";
34592
34611
  if (isMessage) {
34593
34612
  const items2 = [...data];
34594
- const groups2 = groupBy ? groupData(items2, groupBy) : [{ label: "", items: items2 }];
34613
+ const groups2 = groupBy ? groupRows(items2, groupBy, groupFormat, fmt2) : [{ label: "", items: items2 }];
34595
34614
  const contentField = (fieldDefs.find((f3) => f3.variant === "body") ?? titleField)?.name ?? "";
34596
34615
  const senderLabel = (itemData, raw) => {
34597
34616
  if (!senderLabelField) return raw;
@@ -34688,7 +34707,7 @@ function DataList({
34688
34707
  ] });
34689
34708
  }
34690
34709
  const items = [...data];
34691
- const groups = groupBy ? groupData(items, groupBy) : [{ label: "", items }];
34710
+ const groups = groupBy ? groupRows(items, groupBy, groupFormat, fmt2) : [{ label: "", items }];
34692
34711
  const idFieldName = dndItemIdField ?? "id";
34693
34712
  const renderItem = (itemData, index, isLast) => {
34694
34713
  const dndId = itemData[idFieldName] ?? `__idx_${index}`;
@@ -34699,7 +34718,11 @@ function DataList({
34699
34718
  const divider = (isCard || isCompact) && !isLast ? /* @__PURE__ */ jsxRuntime.jsx(Box, { className: cn("border-b border-border/40", isCompact ? "mx-4" : "mx-6") }) : null;
34700
34719
  if (hasRenderProp) {
34701
34720
  const id2 = itemData.id || String(index);
34702
- const actions = renderItemActions(itemData);
34721
+ const allActions = itemActions ? rowActions(itemActions, itemData) : [];
34722
+ const primaryActions = allActions.filter((a) => a.variant === "primary");
34723
+ const otherActions = allActions.filter((a) => a.variant !== "primary");
34724
+ const primary = primaryActions.length > 0 ? renderItemActions(itemData, false, primaryActions) : null;
34725
+ const actions = otherActions.length > 0 ? renderItemActions(itemData, false, otherActions) : null;
34703
34726
  return wrapDnd(
34704
34727
  /* @__PURE__ */ jsxRuntime.jsxs(
34705
34728
  Box,
@@ -34720,6 +34743,7 @@ function DataList({
34720
34743
  }
34721
34744
  ),
34722
34745
  /* @__PURE__ */ jsxRuntime.jsx(Box, { className: cn(onOpen && "relative"), children: itemRenderer(itemData, index) }),
34746
+ primary && /* @__PURE__ */ jsxRuntime.jsx(HStack, { justify: "end", className: cn("relative px-4 pb-3", STRETCHED_ABOVE), children: primary }),
34723
34747
  actions && /* @__PURE__ */ jsxRuntime.jsxs(Box, { onClick: (e) => e.stopPropagation(), className: "absolute top-2 right-2 z-10 opacity-0 group-hover/rowactions:opacity-100 focus-within:opacity-100 [@media(pointer:coarse)]:opacity-100 transition-opacity duration-fast", children: [
34724
34748
  /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "rounded-container border border-border bg-card/95 backdrop-blur-sm shadow-elevation-popover surface-material p-0.5 [@media(pointer:coarse)]:hidden", children: actions }),
34725
34749
  /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "hidden [@media(pointer:coarse)]:block rounded-container border border-border bg-card/95 backdrop-blur-sm shadow-elevation-popover surface-material p-0.5", children: /* @__PURE__ */ jsxRuntime.jsx(
@@ -34727,7 +34751,7 @@ function DataList({
34727
34751
  {
34728
34752
  position: "bottom-end",
34729
34753
  trigger: /* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "ghost", size: "sm", "aria-label": t("common.actions"), "data-testid": "action-overflow", children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "more-horizontal", size: "xs" }) }),
34730
- items: rowActions(itemActions ?? [], itemData).map((action) => ({
34754
+ items: otherActions.map((action) => ({
34731
34755
  label: action.label,
34732
34756
  icon: action.icon,
34733
34757
  variant: action.variant === "danger" ? "danger" : "default",
@@ -34918,6 +34942,7 @@ var init_DataList = __esm({
34918
34942
  init_format();
34919
34943
  init_relationLabel();
34920
34944
  init_getNestedValue();
34945
+ init_groupRows();
34921
34946
  init_useEventBus();
34922
34947
  init_useRowActions();
34923
34948
  init_Box();
@@ -35352,7 +35377,7 @@ var init_MapView = __esm({
35352
35377
  shadowSize: [41, 41]
35353
35378
  });
35354
35379
  L.Marker.prototype.options.icon = defaultIcon;
35355
- const { useEffect: useEffect82, useRef: useRef90, useCallback: useCallback100, useState: useState111 } = React98__namespace.default;
35380
+ const { useEffect: useEffect82, useRef: useRef90, useCallback: useCallback101, useState: useState111 } = React98__namespace.default;
35356
35381
  const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
35357
35382
  const { useEventBus: useEventBus2 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
35358
35383
  function MapUpdater({ centerLat, centerLng, zoom }) {
@@ -35401,7 +35426,7 @@ var init_MapView = __esm({
35401
35426
  const contentSurface = providers.useContentSurface(surface);
35402
35427
  const eventBus = useEventBus2();
35403
35428
  const [clickedPosition, setClickedPosition] = useState111(null);
35404
- const handleMapClick = useCallback100((lat, lng) => {
35429
+ const handleMapClick = useCallback101((lat, lng) => {
35405
35430
  if (showClickedPin) {
35406
35431
  setClickedPosition({ lat, lng });
35407
35432
  }
@@ -35410,7 +35435,7 @@ var init_MapView = __esm({
35410
35435
  eventBus.emit(`UI:${mapClickEvent}`, { latitude: lat, longitude: lng });
35411
35436
  }
35412
35437
  }, [onMapClick, mapClickEvent, eventBus, showClickedPin]);
35413
- const handleMarkerClick = useCallback100((marker) => {
35438
+ const handleMarkerClick = useCallback101((marker) => {
35414
35439
  onMarkerClick?.(marker);
35415
35440
  if (markerClickEvent) {
35416
35441
  eventBus.emit(`UI:${markerClickEvent}`, { ...marker });
@@ -36011,16 +36036,6 @@ function asFieldValue(v) {
36011
36036
  if (t === "object") return v;
36012
36037
  return void 0;
36013
36038
  }
36014
- function groupData2(items, field) {
36015
- const groups = /* @__PURE__ */ new Map();
36016
- for (const item of items) {
36017
- const key = String(core.getNestedValue(item, field) ?? "");
36018
- const group = groups.get(key);
36019
- if (group) group.push(item);
36020
- else groups.set(key, [item]);
36021
- }
36022
- return Array.from(groups.entries()).map(([label, groupItems]) => ({ label, items: groupItems }));
36023
- }
36024
36039
  function TableView({
36025
36040
  entity,
36026
36041
  columns,
@@ -36331,7 +36346,7 @@ function TableView({
36331
36346
  return dnd.isZone ? /* @__PURE__ */ jsxRuntime.jsx(dnd.SortableItem, { id: row[idField] ?? id, children: rowInner }, id) : /* @__PURE__ */ jsxRuntime.jsx(React98__namespace.default.Fragment, { children: rowInner }, id);
36332
36347
  };
36333
36348
  const items = Array.from(data);
36334
- const groups = groupBy ? groupData2(items, groupBy) : [{ label: "", items }];
36349
+ const groups = groupBy ? groupRows(items, groupBy) : [{ label: "", items }];
36335
36350
  let runningIndex = 0;
36336
36351
  const body = /* @__PURE__ */ jsxRuntime.jsx(Box, { role: "rowgroup", children: groups.map((group, gi) => /* @__PURE__ */ jsxRuntime.jsxs(React98__namespace.default.Fragment, { children: [
36337
36352
  group.label && /* @__PURE__ */ jsxRuntime.jsx(Divider, { label: group.label, className: gi > 0 ? "mt-3" : "mt-0" }),
@@ -36370,6 +36385,7 @@ var init_TableView = __esm({
36370
36385
  init_format();
36371
36386
  init_relationLabel();
36372
36387
  init_getNestedValue();
36388
+ init_groupRows();
36373
36389
  init_useEventBus();
36374
36390
  init_useRowActions();
36375
36391
  init_Box();
@@ -58089,6 +58105,22 @@ function useBusIngress(traitBindings, traitIndex, settle, eventBus, appTraitName
58089
58105
  });
58090
58106
  unsubscribes.push(unsub);
58091
58107
  }
58108
+ const routedBareEvents = /* @__PURE__ */ new Set();
58109
+ for (const binding of traitBindings) {
58110
+ for (const listen of binding.trait.listens ?? []) {
58111
+ if (listen.source !== void 0 && listen.source.kind !== "any") routedBareEvents.add(listen.event);
58112
+ }
58113
+ }
58114
+ for (const eventKey of routedBareEvents) {
58115
+ const unsub = eventBus.on(`UI:${eventKey}`, (event) => {
58116
+ if (deliveredHere(event.source) || event.source?.trait === void 0) return;
58117
+ for (const target of runtime.collectListenerTargets(traitIndex, event.source, eventKey, event.payload)) {
58118
+ log5.debug("listen-bare:fire", { event: eventKey, source: event.source.trait, listener: target.listenerTrait, triggers: target.triggers });
58119
+ dispatch(target.listenerTrait, target.triggers, target.payload, event.source);
58120
+ }
58121
+ });
58122
+ unsubscribes.push(unsub);
58123
+ }
58092
58124
  return () => {
58093
58125
  for (const unsub of unsubscribes) unsub();
58094
58126
  };
@@ -58999,9 +59031,16 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
58999
59031
  React98.useEffect(() => {
59000
59032
  if (!transport?.subscribe) return;
59001
59033
  return transport.subscribe((emitted, target) => {
59002
- for (const t2 of runtime.collectListenerTargets(traitIndex, emitted.source, emitted.event, emitted.payload)) {
59003
- void (target === "origin" ? progressAndSettle(t2.listenerTrait, t2.triggers, t2.payload) : dispatchAndSettle(t2.listenerTrait, t2.triggers, t2.payload));
59034
+ const listeners7 = runtime.collectListenerTargets(traitIndex, emitted.source, emitted.event, emitted.payload);
59035
+ if (target !== "origin") {
59036
+ for (const t2 of listeners7) void dispatchAndSettle(t2.listenerTrait, t2.triggers, t2.payload);
59037
+ return;
59004
59038
  }
59039
+ const caller = emitted.source?.trait;
59040
+ if (caller !== void 0 && traitIndex.byName.has(caller) && !listeners7.some((t2) => t2.listenerTrait === caller && t2.triggers === emitted.event)) {
59041
+ void progressAndSettle(caller, emitted.event, emitted.payload);
59042
+ }
59043
+ for (const t2 of listeners7) void progressAndSettle(t2.listenerTrait, t2.triggers, t2.payload);
59005
59044
  }, { clientId: getTabClientId() });
59006
59045
  }, [transport, traitIndex, progressAndSettle, dispatchAndSettle]);
59007
59046
  React98.useEffect(() => {
@@ -59011,7 +59050,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
59011
59050
  if (traitName === void 0 || !traitIndex.byName.has(traitName)) return;
59012
59051
  const composedBefore = new Map(store.callsitePayloads);
59013
59052
  void kernel.foldHostDispatch(request, response).then((outcome) => settleOutcome(traitName, request.event, request.payload, outcome, composedBefore));
59014
- });
59053
+ }, { clientId: getTabClientId() });
59015
59054
  }, [transport, traitIndex, kernel, store, settleOutcome]);
59016
59055
  const mountAndSettle = React98.useCallback(async (seeds, payload) => {
59017
59056
  const composedBefore = new Map(store.callsitePayloads);
@@ -59072,6 +59111,13 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
59072
59111
  prevActiveTraitNamesRef.current = nextActiveTraitNames;
59073
59112
  }, [traitBindings, uiSlots]);
59074
59113
  const mountedRef = React98.useRef(null);
59114
+ const aliveRef = React98.useRef(true);
59115
+ React98.useEffect(() => {
59116
+ aliveRef.current = true;
59117
+ return () => {
59118
+ aliveRef.current = false;
59119
+ };
59120
+ }, []);
59075
59121
  const mountKey = `${options.mountKey ?? ""}\0${JSON.stringify(Object.entries(options.initPayload ?? {}).sort(([a], [b]) => a.localeCompare(b)))}`;
59076
59122
  React98.useEffect(() => {
59077
59123
  const prev = mountedRef.current;
@@ -59102,6 +59148,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
59102
59148
  const failed = err instanceof runtime.TraitMountError ? err.trait : traits2.join(", ");
59103
59149
  const cause = err instanceof runtime.TraitMountError ? err.original : err;
59104
59150
  stateLog.warn("mount:failed", { traits: traits2, failed, error: message, stack: cause instanceof Error ? cause.stack : void 0 });
59151
+ if (!aliveRef.current) return;
59105
59152
  uiSlots.render({
59106
59153
  target: "main",
59107
59154
  pattern: "error-state",
@@ -59337,6 +59384,7 @@ function TraitInitializer({ traits: traits2, routeParams, mountKey, orbitals, on
59337
59384
  }
59338
59385
  var CONTENT_STAGE_WIDTH = 480;
59339
59386
  var NO_ORBITALS = [];
59387
+ var LazyPageOfRegisteredProgram = React98.createContext(false);
59340
59388
  function FitToBox({ children, mode = "box" }) {
59341
59389
  const outerRef = React98.useRef(null);
59342
59390
  const innerRef = React98.useRef(null);
@@ -59452,19 +59500,10 @@ function SchemaRunner({ schema, serverUrl, transport, getAccessToken, mockData,
59452
59500
  ),
59453
59501
  [schema, ir]
59454
59502
  );
59455
- const traitLinkedEntitiesMap = React98.useMemo(() => {
59456
- const map = /* @__PURE__ */ new Map();
59457
- if (ir) {
59458
- for (const page of ir.pages.values()) {
59459
- for (const binding of page.traits) {
59460
- if (binding.linkedEntity) {
59461
- map.set(binding.trait.name, binding.linkedEntity);
59462
- }
59463
- }
59464
- }
59465
- }
59466
- return map;
59467
- }, [ir]);
59503
+ const traitLinkedEntitiesMap = React98.useMemo(
59504
+ () => ir ? ui.buildTraitLinkedEntities(ir) : /* @__PURE__ */ new Map(),
59505
+ [ir]
59506
+ );
59468
59507
  const orbitalsByTraitMap = React98.useMemo(
59469
59508
  () => new Map(Object.entries(orbitalsByTrait)),
59470
59509
  [orbitalsByTrait]
@@ -59608,7 +59647,7 @@ function OrbPreview({
59608
59647
  if (localFallback) return;
59609
59648
  setLocalFallback(true);
59610
59649
  }, [localFallback]);
59611
- const hasOuterBridge = providers.useHasServerBridge();
59650
+ const isLazyPageOfRegisteredProgram = React98.useContext(LazyPageOfRegisteredProgram);
59612
59651
  const parseResult = React98.useMemo(() => {
59613
59652
  let parsed;
59614
59653
  if (typeof schema === "string") {
@@ -59632,7 +59671,7 @@ function OrbPreview({
59632
59671
  const persistence = React98.useMemo(() => {
59633
59672
  if (!parsedSchema || serverUrl || transport) return void 0;
59634
59673
  if (!autoMock) return void 0;
59635
- const adapter = new runtime.InMemoryPersistence();
59674
+ const adapter = new mock.InMemoryPersistence();
59636
59675
  adapter.seed(effectiveMockData);
59637
59676
  return adapter;
59638
59677
  }, [parsedSchema, serverUrl, transport, autoMock, effectiveMockData]);
@@ -59800,13 +59839,13 @@ function OrbPreview({
59800
59839
  navLog.info("interceptor:installed", { pageCount: pages.length, paths: pages.map((p) => p.page.path) });
59801
59840
  return () => el.removeEventListener("click", handler, true);
59802
59841
  }, [pages, handleNavigate, isolated, hostHrefBase]);
59803
- const withBridge = (node) => (serverUrl || transport) && !hasOuterBridge ? /* @__PURE__ */ jsxRuntime.jsx(providers.ServerBridgeProvider, { schema: parseResult.schema, serverUrl, transport, getAccessToken, children: node }) : node;
59842
+ const withBridge = (node) => (serverUrl || transport) && !isLazyPageOfRegisteredProgram ? /* @__PURE__ */ jsxRuntime.jsx(providers.ServerBridgeProvider, { schema: parseResult.schema, serverUrl, transport, getAccessToken, children: node }) : node;
59804
59843
  if (lazyRoute) {
59805
59844
  return withBridge(
59806
59845
  /* @__PURE__ */ jsxRuntime.jsxs(Box, { ref: containerRef, className: `overflow-auto ${className ?? ""}`, style: { height }, children: [
59807
59846
  lazyLoad.status === "loading" && /* @__PURE__ */ jsxRuntime.jsx(LoadingState, {}),
59808
59847
  lazyLoad.status === "error" && /* @__PURE__ */ jsxRuntime.jsx(ErrorState, { "data-testid": "lazy-page-error", message: lazyLoad.error }),
59809
- lazyLoad.status === "ready" && /* @__PURE__ */ jsxRuntime.jsx(
59848
+ lazyLoad.status === "ready" && /* @__PURE__ */ jsxRuntime.jsx(LazyPageOfRegisteredProgram.Provider, { value: true, children: /* @__PURE__ */ jsxRuntime.jsx(
59810
59849
  OrbPreview,
59811
59850
  {
59812
59851
  schema: lazyLoad.schema,
@@ -59826,7 +59865,7 @@ function OrbPreview({
59826
59865
  onUnmatchedNavigate: handleNavigate
59827
59866
  },
59828
59867
  lazyRoute.page.orbRef
59829
- )
59868
+ ) })
59830
59869
  ] })
59831
59870
  );
59832
59871
  }
@@ -59923,21 +59962,28 @@ function BrowserPlayground({
59923
59962
  runtime$1.resumeTicks();
59924
59963
  }
59925
59964
  }, [runtime$1, paused]);
59926
- const registrationReady = React98.useMemo(() => {
59927
- const orbitalNames = schema.orbitals.map((o) => o.name);
59928
- playgroundLog.debug("register:start", { schema: schema.name, orbitalNames });
59965
+ const lazySchemas = React98.useMemo(() => {
59929
59966
  const lazyPages = schema.lazyPages ?? [];
59930
- const lazy6 = lazyPages.length > 0 && lazyLoader !== void 0 ? Promise.all(lazyPages.map(async (page) => {
59967
+ if (lazyPages.length === 0 || lazyLoader === void 0) return Promise.resolve([]);
59968
+ return Promise.all(lazyPages.map(async (page) => {
59931
59969
  const loaded = await runtime.loadLazyPage(lazyLoader, page, schemaPath);
59932
59970
  if (!loaded.success) throw new Error(loaded.error);
59933
59971
  return loaded.data;
59934
- })) : Promise.resolve([]);
59935
- return lazy6.then(
59936
- (lazySchemas) => runtime$1.register(schema, { ...messages !== void 0 ? { messages } : {}, lazy: lazySchemas })
59937
- ).then(() => {
59938
- playgroundLog.debug("register:done", { schema: schema.name, orbitalNames });
59972
+ }));
59973
+ }, [schema.lazyPages, lazyLoader, schemaPath]);
59974
+ const registerProgram = React98.useCallback((program) => {
59975
+ const orbitalNames = program.orbitals.map((o) => o.name);
59976
+ playgroundLog.debug("register:start", { schema: program.name, orbitalNames });
59977
+ return lazySchemas.then((lazy6) => runtime$1.register(program, { ...messages !== void 0 ? { messages } : {}, lazy: lazy6 })).then(() => {
59978
+ playgroundLog.debug("register:done", { schema: program.name, orbitalNames });
59939
59979
  });
59940
- }, [runtime$1, schema, messages, lazyLoader, schemaPath]);
59980
+ }, [runtime$1, lazySchemas, messages]);
59981
+ const latestRegistration = React98.useRef(Promise.resolve());
59982
+ const registrationReady = React98.useMemo(() => {
59983
+ const ready = registerProgram(schema);
59984
+ latestRegistration.current = ready;
59985
+ return ready;
59986
+ }, [registerProgram, schema]);
59941
59987
  const teardownTimerRef = React98.useRef(null);
59942
59988
  React98.useEffect(() => {
59943
59989
  if (teardownTimerRef.current !== null) {
@@ -59955,18 +60001,22 @@ function BrowserPlayground({
59955
60001
  const transport = React98.useMemo(
59956
60002
  () => runtime.createInProcessTransport(
59957
60003
  async (orbitalName, request) => {
59958
- await registrationReady;
60004
+ await latestRegistration.current;
59959
60005
  return runtime$1.processOrbitalEvent(orbitalName, request);
59960
60006
  },
59961
60007
  {
59962
- // The program (lazy behaviors included) is registered above; the bridge only waits for it.
59963
- onRegister: () => registrationReady,
60008
+ // Registers what the bridge hands over (lazy behaviors included): a bridge that unregistered first gets it back.
60009
+ onRegister: (program) => {
60010
+ const ready = registerProgram(program);
60011
+ latestRegistration.current = ready;
60012
+ return ready;
60013
+ },
59964
60014
  onUnregister: () => {
59965
60015
  runtime$1.unregisterAll();
59966
60016
  }
59967
60017
  }
59968
60018
  ),
59969
- [runtime$1, registrationReady]
60019
+ [runtime$1, registerProgram, registrationReady]
59970
60020
  );
59971
60021
  const viewerLocale = locale ?? schema.locales?.[0];
59972
60022
  const i18n$1 = React98.useMemo(() => {
@@ -1,9 +1,9 @@
1
- import { EventPayload, OrbitalDefinition, ServiceParams, TraitConfig, UserContext, ResolvedTraitBinding, ResolvedPage, ResolvedEntity, ResolvedTrait, ResolvedIR, OrbitalSchema, PatternConfig, ResolvedPatternProps, EventSource, SExpr, EntityData, MessageCatalogs } from '@almadar/core';
1
+ import { EventPayload, OrbitalDefinition, PersistenceAdapter, ServiceParams, TraitConfig, UserContext, ResolvedTraitBinding, ResolvedPage, ResolvedEntity, ResolvedTrait, ResolvedIR, OrbitalSchema, PatternConfig, ResolvedPatternProps, EventSource, SExpr, EntityData, MessageCatalogs } from '@almadar/core';
2
2
  export { ResolvedEntity, ResolvedIR, ResolvedPage, ResolvedTrait, ResolvedTraitBinding } from '@almadar/core';
3
- import { TraitState, EventTransport, PersistenceAdapter, AccessTokenProvider, SchemaLoader } from '@almadar/runtime';
3
+ import { TraitState, EventTransport, AccessTokenProvider, SchemaLoader } from '@almadar/runtime';
4
4
  export { AccessTokenProvider, ClientEventBus, CreateClientEffectHandlersOptions, SlotSetter, createClientEffectHandlers } from '@almadar/runtime';
5
- import { E as EntityBindingSource, A as AwaitingSkeletonSource, S as ServerBridgeTransport } from '../AwaitingSkeletonContext-DPgW__WV.js';
6
- export { a as EntitySchemaContextValue, b as EntitySchemaProvider, c as EntitySchemaProviderProps, d as ServerBridgeContextValue, e as ServerBridgeProvider, T as TraitContext, f as TraitContextValue, g as TraitInstance, h as TraitProvider, i as TraitProviderProps, u as useEntitySchema, j as useEntitySchemaOptional, k as useServerBridge, l as useTrait, m as useTraitContext } from '../AwaitingSkeletonContext-DPgW__WV.js';
5
+ import { E as EntityBindingSource, A as AwaitingSkeletonSource, S as ServerBridgeTransport } from '../AwaitingSkeletonContext-Bh399p1x.js';
6
+ export { a as EntitySchemaContextValue, b as EntitySchemaProvider, c as EntitySchemaProviderProps, d as ServerBridgeContextValue, e as ServerBridgeProvider, T as TraitContext, f as TraitContextValue, g as TraitInstance, h as TraitProvider, i as TraitProviderProps, u as useEntitySchema, j as useEntitySchemaOptional, k as useServerBridge, l as useTrait, m as useTraitContext } from '../AwaitingSkeletonContext-Bh399p1x.js';
7
7
  import { c as useUISlots } from '../UISlotContext-CS487Uoc.js';
8
8
  export { PERF_NAMESPACE, PerfEntry, PreparedPreviewSchema, adjustSchemaForMockData, buildMockData, clearPerf, perfEnd, perfStart, perfTime, prepareSchemaForPreview, wrapCallbackForEvent } from '@almadar/runtime/ui';
9
9
  import React__default, { ReactNode } from 'react';
@@ -1,10 +1,10 @@
1
- export { BrowserPlayground, OrbPreview, adjustSchemaForMockData, buildMockData, clearSchemaCache, prepareSchemaForPreview, useResolvedSchema, useTraitStateMachine } from '../chunk-RHP5WL55.js';
1
+ export { BrowserPlayground, OrbPreview, adjustSchemaForMockData, buildMockData, clearSchemaCache, prepareSchemaForPreview, useResolvedSchema, useTraitStateMachine } from '../chunk-QJIAJ6EH.js';
2
2
  export { assertUniqueSlotsPerHost } from '../chunk-O2EIWXWE.js';
3
3
  import '../chunk-N7JIG57B.js';
4
- import '../chunk-VHTJRS2N.js';
4
+ import '../chunk-L3MTZ3RH.js';
5
5
  import '../chunk-YYYHH5BA.js';
6
- export { wrapCallbackForEvent } from '../chunk-PYJ2UQWM.js';
7
- import '../chunk-HA7CJWQX.js';
6
+ export { wrapCallbackForEvent } from '../chunk-E6MWYQVZ.js';
7
+ import '../chunk-J755QADM.js';
8
8
  import '../chunk-4ZGXIW3B.js';
9
9
  import '../chunk-I5QOYW2Z.js';
10
10
  import '../chunk-XJTHMW4G.js';
@@ -5836,6 +5836,7 @@ var Avatar = ({
5836
5836
  statusClasses[status],
5837
5837
  statusSizeClasses[size]
5838
5838
  ),
5839
+ role: "img",
5839
5840
  "aria-label": t("avatar.status", { status: t(`avatar.status.${status}`) })
5840
5841
  }
5841
5842
  ),
@@ -6903,6 +6904,7 @@ var AnimatedGraphic = React17__namespace.default.forwardRef(
6903
6904
  "div",
6904
6905
  {
6905
6906
  className: "w-full h-full [&>svg]:w-full [&>svg]:h-full",
6907
+ "aria-hidden": "true",
6906
6908
  dangerouslySetInnerHTML: { __html: resolvedSvg }
6907
6909
  }
6908
6910
  ) : children
package/dist/ssr/index.js CHANGED
@@ -5815,6 +5815,7 @@ var Avatar = ({
5815
5815
  statusClasses[status],
5816
5816
  statusSizeClasses[size]
5817
5817
  ),
5818
+ role: "img",
5818
5819
  "aria-label": t("avatar.status", { status: t(`avatar.status.${status}`) })
5819
5820
  }
5820
5821
  ),
@@ -6882,6 +6883,7 @@ var AnimatedGraphic = React17__default.forwardRef(
6882
6883
  "div",
6883
6884
  {
6884
6885
  className: "w-full h-full [&>svg]:w-full [&>svg]:h-full",
6886
+ "aria-hidden": "true",
6885
6887
  dangerouslySetInnerHTML: { __html: resolvedSvg }
6886
6888
  }
6887
6889
  ) : children
@@ -1,4 +1,4 @@
1
- import { D as DrawableNode } from './paintDispatch-_6EhJCiL.js';
1
+ import { D as DrawableNode } from './paintDispatch-Cp1_S93j.js';
2
2
  import { OrbitalVerificationAPI, TraitStateSnapshot, EventPayload, BusEvent, VerificationCheck, BridgeHealth, VerificationSnapshot, VerificationSummary, TransitionTrace, OrbitalEventRequest, OrbitalEventResponse, ServerResponseTrace, EffectTrace, CheckStatus, ServerEffectResult, AssetLoadStatus } from '@almadar/core';
3
3
  import { EventTransport } from '@almadar/runtime';
4
4
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@almadar/ui",
3
- "version": "6.57.0",
3
+ "version": "6.59.0",
4
4
  "description": "React UI components, hooks, and providers for Almadar",
5
5
  "type": "module",
6
6
  "sideEffects": [
@@ -126,12 +126,13 @@
126
126
  "access": "public"
127
127
  },
128
128
  "dependencies": {
129
- "@almadar/core": "^10.119.0",
130
- "@almadar/evaluator": "^2.55.0",
131
- "@almadar/logger": "^1.16.0",
132
- "@almadar/runtime": "^6.104.0",
133
- "@almadar/std": "^16.244.0",
134
- "@almadar/syntax": "^1.19.0",
129
+ "@almadar/core": "^10.121.0",
130
+ "@almadar/db": "^0.1.1",
131
+ "@almadar/evaluator": "^2.56.0",
132
+ "@almadar/logger": "^1.17.0",
133
+ "@almadar/runtime": "^6.106.0",
134
+ "@almadar/std": "^16.246.0",
135
+ "@almadar/syntax": "^1.19.1",
135
136
  "@dnd-kit/core": "^6.3.1",
136
137
  "@dnd-kit/sortable": "^10.0.0",
137
138
  "@dnd-kit/utilities": "^3.2.2",
@@ -191,7 +192,7 @@
191
192
  }
192
193
  },
193
194
  "devDependencies": {
194
- "@almadar-io/behaviors": "^0.16.191",
195
+ "@almadar-io/behaviors": "^0.16.194",
195
196
  "@almadar/eslint-plugin": "^2.21.0",
196
197
  "@react-three/drei": "^10.7.7",
197
198
  "@react-three/fiber": "^9.6.0",