@almadar/ui 6.57.0 → 6.58.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.
@@ -108,8 +108,6 @@ interface ServerBridgeContextValue {
108
108
  */
109
109
  type ServerBridgeTransport = EventTransport;
110
110
 
111
- /** Whether a `ServerBridgeProvider` is already above — a nested preview (a lazy page) reuses its registration. */
112
- declare function useHasServerBridge(): boolean;
113
111
  /**
114
112
  * Access the server bridge. Returns a no-op stub when outside the provider —
115
113
  * `useCircuitKernel` treats an absent/no-op transport as offline (plan G7).
@@ -230,4 +228,4 @@ declare function useAwaitingSkeleton(target: {
230
228
  trait: string;
231
229
  }): SkeletonNode | undefined;
232
230
 
233
- export { type AwaitingSkeletonSource as A, type EntityBindingSource as E, type ServerBridgeTransport as S, TraitContext as T, type EntitySchemaContextValue as a, EntitySchemaProvider as b, type EntitySchemaProviderProps as c, type ServerBridgeContextValue as d, ServerBridgeProvider as e, type TraitContextValue as f, type TraitInstance as g, TraitProvider as h, type TraitProviderProps as i, useEntitySchemaOptional as j, useServerBridge as k, useTrait as l, useTraitContext as m, AwaitingSkeletonContext as n, EntityBindingContext as o, type ServerBridgeProviderProps as p, useAwaitingSkeleton as q, useEntityBindingSnapshot as r, useHasServerBridge as s, useEntitySchema as u };
231
+ export { type AwaitingSkeletonSource as A, type EntityBindingSource as E, type ServerBridgeTransport as S, TraitContext as T, type EntitySchemaContextValue as a, EntitySchemaProvider as b, type EntitySchemaProviderProps as c, type ServerBridgeContextValue as d, ServerBridgeProvider as e, type TraitContextValue as f, type TraitInstance as g, TraitProvider as h, type TraitProviderProps as i, useEntitySchemaOptional as j, useServerBridge as k, useTrait as l, useTraitContext as m, AwaitingSkeletonContext as n, EntityBindingContext as o, type ServerBridgeProviderProps as p, useAwaitingSkeleton as q, useEntityBindingSnapshot as r, useEntitySchema as u };
@@ -1,7 +1,7 @@
1
1
  import { AnimationName, Asset, ScenePos, EventEmit, EventKey } from '@almadar/core';
2
2
  import React__default from 'react';
3
3
  import * as THREE from 'three';
4
- import { D as DrawableNode } from './paintDispatch-_6EhJCiL.js';
4
+ import { D as DrawableNode } from './paintDispatch-BN8Vbzgs.js';
5
5
 
6
6
  /**
7
7
  * Sprite Sheet Animation Types
@@ -1,6 +1,6 @@
1
1
  import React__default from 'react';
2
2
  import { AudioManifest } from '@almadar/core';
3
- import { U as UiError } from './paintDispatch-_6EhJCiL.js';
3
+ import { U as UiError } from './paintDispatch-BN8Vbzgs.js';
4
4
 
5
5
  /** Core owns the sound-manifest shape (`@almadar/core` `types/asset.ts`) so the
6
6
  * pattern extractor and the generated `.lolo` factories resolve the same
@@ -1,4 +1,4 @@
1
- export { SlotContainedContext, SlotContentRenderer, SuspenseConfigProvider, UISlotComponent, UISlotRenderer, renderPatternValue } from './chunk-PYJ2UQWM.js';
1
+ export { SlotContainedContext, SlotContentRenderer, SuspenseConfigProvider, UISlotComponent, UISlotRenderer, renderPatternValue } from './chunk-I2ZNE5TD.js';
2
2
  import './chunk-HA7CJWQX.js';
3
3
  import './chunk-4ZGXIW3B.js';
4
4
  import './chunk-I5QOYW2Z.js';
@@ -78,6 +78,7 @@ var utilities = require('@dnd-kit/utilities');
78
78
  var emojilib = require('emojilib');
79
79
  var d3Force = require('d3-force');
80
80
  var OrbitalServerRuntime = require('@almadar/runtime/OrbitalServerRuntime');
81
+ var mock = require('@almadar/db/mock');
81
82
 
82
83
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
83
84
 
@@ -17004,6 +17005,7 @@ var init_Tabs = __esm({
17004
17005
  }
17005
17006
  };
17006
17007
  const activeTabContent = safeItems.find((item) => item.id === activeTab)?.content;
17008
+ const rendersPanel = activeTabContent !== void 0 && activeTabContent !== null;
17007
17009
  if (safeItems.length === 0) {
17008
17010
  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") }) });
17009
17011
  }
@@ -17054,7 +17056,7 @@ var init_Tabs = __esm({
17054
17056
  id: tabId(item.id),
17055
17057
  role: "tab",
17056
17058
  "aria-selected": isActive,
17057
- "aria-controls": isActive ? panelId(item.id) : void 0,
17059
+ "aria-controls": isActive && rendersPanel ? panelId(item.id) : void 0,
17058
17060
  "aria-disabled": isDisabled,
17059
17061
  tabIndex: isActive ? 0 : -1,
17060
17062
  onClick: () => !isDisabled && handleTabChange(item.id, item.event),
@@ -17114,7 +17116,7 @@ var init_Tabs = __esm({
17114
17116
  )
17115
17117
  ] })
17116
17118
  ] }) : tablist,
17117
- activeTabContent !== void 0 && activeTabContent !== null && /* @__PURE__ */ jsxRuntime.jsx(
17119
+ rendersPanel && /* @__PURE__ */ jsxRuntime.jsx(
17118
17120
  Box,
17119
17121
  {
17120
17122
  role: "tabpanel",
@@ -35137,8 +35139,11 @@ function DataGrid({
35137
35139
  children: [
35138
35140
  imageField && (() => {
35139
35141
  const imgUrl = resolveImageUrl(core.getNestedValue(itemData, imageField));
35140
- if (!imgUrl) return null;
35141
- 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(
35142
+ const mediaClass = asRows ? "w-12 h-12 flex-shrink-0 overflow-hidden rounded-container" : "w-full aspect-video overflow-hidden rounded-t-container";
35143
+ if (!imgUrl) {
35144
+ 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" }) });
35145
+ }
35146
+ return /* @__PURE__ */ jsxRuntime.jsx(Box, { className: mediaClass, children: /* @__PURE__ */ jsxRuntime.jsx(
35142
35147
  "img",
35143
35148
  {
35144
35149
  src: imgUrl,
@@ -35171,7 +35176,7 @@ function DataGrid({
35171
35176
  Typography,
35172
35177
  {
35173
35178
  variant: titleField?.variant === "h3" && !asRows ? "h3" : "h4",
35174
- className: "font-semibold truncate min-w-0",
35179
+ className: cn("font-semibold min-w-0", asRows ? "truncate" : "line-clamp-2 break-words"),
35175
35180
  children: titleDisplay
35176
35181
  }
35177
35182
  )
@@ -35300,24 +35305,33 @@ var init_DataGrid = __esm({
35300
35305
  DataGrid.displayName = "DataGrid";
35301
35306
  }
35302
35307
  });
35303
- function renderIconInput2(icon, props) {
35304
- return typeof icon === "string" ? /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: icon, ...props }) : /* @__PURE__ */ jsxRuntime.jsx(Icon, { icon, ...props });
35305
- }
35306
- function formatValue2(value, format, fmt2, relationOptions) {
35307
- const relationDisplay = resolveRelationCellDisplay(value, relationOptions);
35308
- if (relationDisplay !== void 0) return relationDisplay;
35309
- return formatValue(value, format, fmt2);
35310
- }
35311
- function groupData(items, field) {
35308
+
35309
+ // lib/groupRows.ts
35310
+ function groupRows(items, field, format, fmt2 = {}) {
35312
35311
  const groups = /* @__PURE__ */ new Map();
35313
35312
  for (const item of items) {
35314
- const key = String(core.getNestedValue(item, field) ?? "");
35313
+ const raw = core.getNestedValue(item, field);
35314
+ const key = format ? formatValue(raw ?? void 0, format, fmt2) : String(raw ?? "");
35315
35315
  const group = groups.get(key);
35316
35316
  if (group) group.push(item);
35317
35317
  else groups.set(key, [item]);
35318
35318
  }
35319
35319
  return Array.from(groups.entries()).map(([label, groupItems]) => ({ label, items: groupItems }));
35320
35320
  }
35321
+ var init_groupRows = __esm({
35322
+ "lib/groupRows.ts"() {
35323
+ init_format();
35324
+ init_getNestedValue();
35325
+ }
35326
+ });
35327
+ function renderIconInput2(icon, props) {
35328
+ return typeof icon === "string" ? /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: icon, ...props }) : /* @__PURE__ */ jsxRuntime.jsx(Icon, { icon, ...props });
35329
+ }
35330
+ function formatValue2(value, format, fmt2, relationOptions) {
35331
+ const relationDisplay = resolveRelationCellDisplay(value, relationOptions);
35332
+ if (relationDisplay !== void 0) return relationDisplay;
35333
+ return formatValue(value, format, fmt2);
35334
+ }
35321
35335
  function DataList({
35322
35336
  entity,
35323
35337
  fields,
@@ -35328,6 +35342,7 @@ function DataList({
35328
35342
  gap = "none",
35329
35343
  variant = "default",
35330
35344
  groupBy,
35345
+ groupFormat,
35331
35346
  senderField,
35332
35347
  senderLabelField,
35333
35348
  currentUser,
@@ -35435,9 +35450,9 @@ function DataList({
35435
35450
  e.stopPropagation();
35436
35451
  fireRowAction(action, itemData, String(itemData.id ?? ""));
35437
35452
  };
35438
- const renderItemActions = (itemData, onPrimary = false) => {
35453
+ const renderItemActions = (itemData, onPrimary = false, only) => {
35439
35454
  if (!itemActions || itemActions.length === 0) return null;
35440
- const shown = rowActions(itemActions, itemData);
35455
+ const shown = only ?? rowActions(itemActions, itemData);
35441
35456
  if (shown.length === 0) return null;
35442
35457
  const inline = maxInlineActions != null ? shown.slice(0, maxInlineActions) : shown;
35443
35458
  const overflow = maxInlineActions != null ? shown.slice(maxInlineActions) : [];
@@ -35521,7 +35536,7 @@ function DataList({
35521
35536
  const isMessage = variant === "message";
35522
35537
  if (isMessage) {
35523
35538
  const items2 = [...data];
35524
- const groups2 = groupBy ? groupData(items2, groupBy) : [{ label: "", items: items2 }];
35539
+ const groups2 = groupBy ? groupRows(items2, groupBy, groupFormat, fmt2) : [{ label: "", items: items2 }];
35525
35540
  const contentField = (fieldDefs.find((f3) => f3.variant === "body") ?? titleField)?.name ?? "";
35526
35541
  const senderLabel = (itemData, raw) => {
35527
35542
  if (!senderLabelField) return raw;
@@ -35618,7 +35633,7 @@ function DataList({
35618
35633
  ] });
35619
35634
  }
35620
35635
  const items = [...data];
35621
- const groups = groupBy ? groupData(items, groupBy) : [{ label: "", items }];
35636
+ const groups = groupBy ? groupRows(items, groupBy, groupFormat, fmt2) : [{ label: "", items }];
35622
35637
  const idFieldName = dndItemIdField ?? "id";
35623
35638
  const renderItem = (itemData, index, isLast) => {
35624
35639
  const dndId = itemData[idFieldName] ?? `__idx_${index}`;
@@ -35629,7 +35644,11 @@ function DataList({
35629
35644
  const divider = (isCard || isCompact) && !isLast ? /* @__PURE__ */ jsxRuntime.jsx(Box, { className: cn("border-b border-border/40", isCompact ? "mx-4" : "mx-6") }) : null;
35630
35645
  if (hasRenderProp) {
35631
35646
  const id2 = itemData.id || String(index);
35632
- const actions = renderItemActions(itemData);
35647
+ const allActions = itemActions ? rowActions(itemActions, itemData) : [];
35648
+ const primaryActions = allActions.filter((a) => a.variant === "primary");
35649
+ const otherActions = allActions.filter((a) => a.variant !== "primary");
35650
+ const primary = primaryActions.length > 0 ? renderItemActions(itemData, false, primaryActions) : null;
35651
+ const actions = otherActions.length > 0 ? renderItemActions(itemData, false, otherActions) : null;
35633
35652
  return wrapDnd(
35634
35653
  /* @__PURE__ */ jsxRuntime.jsxs(
35635
35654
  Box,
@@ -35650,6 +35669,7 @@ function DataList({
35650
35669
  }
35651
35670
  ),
35652
35671
  /* @__PURE__ */ jsxRuntime.jsx(Box, { className: cn(onOpen && "relative"), children: itemRenderer(itemData, index) }),
35672
+ primary && /* @__PURE__ */ jsxRuntime.jsx(HStack, { justify: "end", className: cn("relative px-4 pb-3", STRETCHED_ABOVE), children: primary }),
35653
35673
  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: [
35654
35674
  /* @__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 }),
35655
35675
  /* @__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(
@@ -35657,7 +35677,7 @@ function DataList({
35657
35677
  {
35658
35678
  position: "bottom-end",
35659
35679
  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" }) }),
35660
- items: rowActions(itemActions ?? [], itemData).map((action) => ({
35680
+ items: otherActions.map((action) => ({
35661
35681
  label: action.label,
35662
35682
  icon: action.icon,
35663
35683
  variant: action.variant === "danger" ? "danger" : "default",
@@ -35848,6 +35868,7 @@ var init_DataList = __esm({
35848
35868
  init_format();
35849
35869
  init_relationLabel();
35850
35870
  init_getNestedValue();
35871
+ init_groupRows();
35851
35872
  init_useEventBus();
35852
35873
  init_useRowActions();
35853
35874
  init_Box();
@@ -36282,7 +36303,7 @@ var init_MapView = __esm({
36282
36303
  shadowSize: [41, 41]
36283
36304
  });
36284
36305
  L.Marker.prototype.options.icon = defaultIcon;
36285
- const { useEffect: useEffect85, useRef: useRef90, useCallback: useCallback108, useState: useState120 } = React96__namespace.default;
36306
+ const { useEffect: useEffect85, useRef: useRef90, useCallback: useCallback109, useState: useState120 } = React96__namespace.default;
36286
36307
  const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
36287
36308
  const { useEventBus: useEventBus2 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
36288
36309
  function MapUpdater({ centerLat, centerLng, zoom }) {
@@ -36331,7 +36352,7 @@ var init_MapView = __esm({
36331
36352
  const contentSurface = providers.useContentSurface(surface);
36332
36353
  const eventBus = useEventBus2();
36333
36354
  const [clickedPosition, setClickedPosition] = useState120(null);
36334
- const handleMapClick = useCallback108((lat, lng) => {
36355
+ const handleMapClick = useCallback109((lat, lng) => {
36335
36356
  if (showClickedPin) {
36336
36357
  setClickedPosition({ lat, lng });
36337
36358
  }
@@ -36340,7 +36361,7 @@ var init_MapView = __esm({
36340
36361
  eventBus.emit(`UI:${mapClickEvent}`, { latitude: lat, longitude: lng });
36341
36362
  }
36342
36363
  }, [onMapClick, mapClickEvent, eventBus, showClickedPin]);
36343
- const handleMarkerClick = useCallback108((marker) => {
36364
+ const handleMarkerClick = useCallback109((marker) => {
36344
36365
  onMarkerClick?.(marker);
36345
36366
  if (markerClickEvent) {
36346
36367
  eventBus.emit(`UI:${markerClickEvent}`, { ...marker });
@@ -36941,16 +36962,6 @@ function asFieldValue(v) {
36941
36962
  if (t === "object") return v;
36942
36963
  return void 0;
36943
36964
  }
36944
- function groupData2(items, field) {
36945
- const groups = /* @__PURE__ */ new Map();
36946
- for (const item of items) {
36947
- const key = String(core.getNestedValue(item, field) ?? "");
36948
- const group = groups.get(key);
36949
- if (group) group.push(item);
36950
- else groups.set(key, [item]);
36951
- }
36952
- return Array.from(groups.entries()).map(([label, groupItems]) => ({ label, items: groupItems }));
36953
- }
36954
36965
  function TableView({
36955
36966
  entity,
36956
36967
  columns,
@@ -37261,7 +37272,7 @@ function TableView({
37261
37272
  return dnd.isZone ? /* @__PURE__ */ jsxRuntime.jsx(dnd.SortableItem, { id: row[idField] ?? id, children: rowInner }, id) : /* @__PURE__ */ jsxRuntime.jsx(React96__namespace.default.Fragment, { children: rowInner }, id);
37262
37273
  };
37263
37274
  const items = Array.from(data);
37264
- const groups = groupBy ? groupData2(items, groupBy) : [{ label: "", items }];
37275
+ const groups = groupBy ? groupRows(items, groupBy) : [{ label: "", items }];
37265
37276
  let runningIndex = 0;
37266
37277
  const body = /* @__PURE__ */ jsxRuntime.jsx(Box, { role: "rowgroup", children: groups.map((group, gi) => /* @__PURE__ */ jsxRuntime.jsxs(React96__namespace.default.Fragment, { children: [
37267
37278
  group.label && /* @__PURE__ */ jsxRuntime.jsx(Divider, { label: group.label, className: gi > 0 ? "mt-3" : "mt-0" }),
@@ -37300,6 +37311,7 @@ var init_TableView = __esm({
37300
37311
  init_format();
37301
37312
  init_relationLabel();
37302
37313
  init_getNestedValue();
37314
+ init_groupRows();
37303
37315
  init_useEventBus();
37304
37316
  init_useRowActions();
37305
37317
  init_Box();
@@ -64609,6 +64621,22 @@ function useBusIngress(traitBindings, traitIndex, settle, eventBus, appTraitName
64609
64621
  });
64610
64622
  unsubscribes.push(unsub);
64611
64623
  }
64624
+ const routedBareEvents = /* @__PURE__ */ new Set();
64625
+ for (const binding of traitBindings) {
64626
+ for (const listen of binding.trait.listens ?? []) {
64627
+ if (listen.source !== void 0 && listen.source.kind !== "any") routedBareEvents.add(listen.event);
64628
+ }
64629
+ }
64630
+ for (const eventKey of routedBareEvents) {
64631
+ const unsub = eventBus.on(`UI:${eventKey}`, (event) => {
64632
+ if (deliveredHere(event.source) || event.source?.trait === void 0) return;
64633
+ for (const target of runtime.collectListenerTargets(traitIndex, event.source, eventKey, event.payload)) {
64634
+ log13.debug("listen-bare:fire", { event: eventKey, source: event.source.trait, listener: target.listenerTrait, triggers: target.triggers });
64635
+ dispatch(target.listenerTrait, target.triggers, target.payload, event.source);
64636
+ }
64637
+ });
64638
+ unsubscribes.push(unsub);
64639
+ }
64612
64640
  return () => {
64613
64641
  for (const unsub of unsubscribes) unsub();
64614
64642
  };
@@ -65519,9 +65547,16 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
65519
65547
  React96.useEffect(() => {
65520
65548
  if (!transport?.subscribe) return;
65521
65549
  return transport.subscribe((emitted, target) => {
65522
- for (const t2 of runtime.collectListenerTargets(traitIndex, emitted.source, emitted.event, emitted.payload)) {
65523
- void (target === "origin" ? progressAndSettle(t2.listenerTrait, t2.triggers, t2.payload) : dispatchAndSettle(t2.listenerTrait, t2.triggers, t2.payload));
65550
+ const listeners7 = runtime.collectListenerTargets(traitIndex, emitted.source, emitted.event, emitted.payload);
65551
+ if (target !== "origin") {
65552
+ for (const t2 of listeners7) void dispatchAndSettle(t2.listenerTrait, t2.triggers, t2.payload);
65553
+ return;
65524
65554
  }
65555
+ const caller = emitted.source?.trait;
65556
+ if (caller !== void 0 && traitIndex.byName.has(caller) && !listeners7.some((t2) => t2.listenerTrait === caller && t2.triggers === emitted.event)) {
65557
+ void progressAndSettle(caller, emitted.event, emitted.payload);
65558
+ }
65559
+ for (const t2 of listeners7) void progressAndSettle(t2.listenerTrait, t2.triggers, t2.payload);
65525
65560
  }, { clientId: getTabClientId() });
65526
65561
  }, [transport, traitIndex, progressAndSettle, dispatchAndSettle]);
65527
65562
  React96.useEffect(() => {
@@ -65531,7 +65566,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
65531
65566
  if (traitName === void 0 || !traitIndex.byName.has(traitName)) return;
65532
65567
  const composedBefore = new Map(store.callsitePayloads);
65533
65568
  void kernel.foldHostDispatch(request, response).then((outcome) => settleOutcome(traitName, request.event, request.payload, outcome, composedBefore));
65534
- });
65569
+ }, { clientId: getTabClientId() });
65535
65570
  }, [transport, traitIndex, kernel, store, settleOutcome]);
65536
65571
  const mountAndSettle = React96.useCallback(async (seeds, payload) => {
65537
65572
  const composedBefore = new Map(store.callsitePayloads);
@@ -65592,6 +65627,13 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
65592
65627
  prevActiveTraitNamesRef.current = nextActiveTraitNames;
65593
65628
  }, [traitBindings, uiSlots]);
65594
65629
  const mountedRef = React96.useRef(null);
65630
+ const aliveRef = React96.useRef(true);
65631
+ React96.useEffect(() => {
65632
+ aliveRef.current = true;
65633
+ return () => {
65634
+ aliveRef.current = false;
65635
+ };
65636
+ }, []);
65595
65637
  const mountKey = `${options.mountKey ?? ""}\0${JSON.stringify(Object.entries(options.initPayload ?? {}).sort(([a], [b]) => a.localeCompare(b)))}`;
65596
65638
  React96.useEffect(() => {
65597
65639
  const prev = mountedRef.current;
@@ -65622,6 +65664,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
65622
65664
  const failed = err instanceof runtime.TraitMountError ? err.trait : traits2.join(", ");
65623
65665
  const cause = err instanceof runtime.TraitMountError ? err.original : err;
65624
65666
  stateLog.warn("mount:failed", { traits: traits2, failed, error: message, stack: cause instanceof Error ? cause.stack : void 0 });
65667
+ if (!aliveRef.current) return;
65625
65668
  uiSlots.render({
65626
65669
  target: "main",
65627
65670
  pattern: "error-state",
@@ -65754,6 +65797,7 @@ function TraitInitializer({ traits: traits2, routeParams, mountKey, orbitals, on
65754
65797
  }
65755
65798
  var CONTENT_STAGE_WIDTH = 480;
65756
65799
  var NO_ORBITALS = [];
65800
+ var LazyPageOfRegisteredProgram = React96.createContext(false);
65757
65801
  function FitToBox({ children, mode = "box" }) {
65758
65802
  const outerRef = React96.useRef(null);
65759
65803
  const innerRef = React96.useRef(null);
@@ -66025,7 +66069,7 @@ function OrbPreview({
66025
66069
  if (localFallback) return;
66026
66070
  setLocalFallback(true);
66027
66071
  }, [localFallback]);
66028
- const hasOuterBridge = providers.useHasServerBridge();
66072
+ const isLazyPageOfRegisteredProgram = React96.useContext(LazyPageOfRegisteredProgram);
66029
66073
  const parseResult = React96.useMemo(() => {
66030
66074
  let parsed;
66031
66075
  if (typeof schema === "string") {
@@ -66049,7 +66093,7 @@ function OrbPreview({
66049
66093
  const persistence = React96.useMemo(() => {
66050
66094
  if (!parsedSchema || serverUrl || transport) return void 0;
66051
66095
  if (!autoMock) return void 0;
66052
- const adapter = new runtime.InMemoryPersistence();
66096
+ const adapter = new mock.InMemoryPersistence();
66053
66097
  adapter.seed(effectiveMockData);
66054
66098
  return adapter;
66055
66099
  }, [parsedSchema, serverUrl, transport, autoMock, effectiveMockData]);
@@ -66217,13 +66261,13 @@ function OrbPreview({
66217
66261
  navLog.info("interceptor:installed", { pageCount: pages.length, paths: pages.map((p) => p.page.path) });
66218
66262
  return () => el.removeEventListener("click", handler, true);
66219
66263
  }, [pages, handleNavigate, isolated, hostHrefBase]);
66220
- const withBridge = (node) => (serverUrl || transport) && !hasOuterBridge ? /* @__PURE__ */ jsxRuntime.jsx(providers.ServerBridgeProvider, { schema: parseResult.schema, serverUrl, transport, getAccessToken, children: node }) : node;
66264
+ const withBridge = (node) => (serverUrl || transport) && !isLazyPageOfRegisteredProgram ? /* @__PURE__ */ jsxRuntime.jsx(providers.ServerBridgeProvider, { schema: parseResult.schema, serverUrl, transport, getAccessToken, children: node }) : node;
66221
66265
  if (lazyRoute) {
66222
66266
  return withBridge(
66223
66267
  /* @__PURE__ */ jsxRuntime.jsxs(Box, { ref: containerRef, className: `overflow-auto ${className ?? ""}`, style: { height }, children: [
66224
66268
  lazyLoad.status === "loading" && /* @__PURE__ */ jsxRuntime.jsx(LoadingState, {}),
66225
66269
  lazyLoad.status === "error" && /* @__PURE__ */ jsxRuntime.jsx(ErrorState, { "data-testid": "lazy-page-error", message: lazyLoad.error }),
66226
- lazyLoad.status === "ready" && /* @__PURE__ */ jsxRuntime.jsx(
66270
+ lazyLoad.status === "ready" && /* @__PURE__ */ jsxRuntime.jsx(LazyPageOfRegisteredProgram.Provider, { value: true, children: /* @__PURE__ */ jsxRuntime.jsx(
66227
66271
  OrbPreview,
66228
66272
  {
66229
66273
  schema: lazyLoad.schema,
@@ -66243,7 +66287,7 @@ function OrbPreview({
66243
66287
  onUnmatchedNavigate: handleNavigate
66244
66288
  },
66245
66289
  lazyRoute.page.orbRef
66246
- )
66290
+ ) })
66247
66291
  ] })
66248
66292
  );
66249
66293
  }
@@ -66340,21 +66384,28 @@ function BrowserPlayground({
66340
66384
  runtime$1.resumeTicks();
66341
66385
  }
66342
66386
  }, [runtime$1, paused]);
66343
- const registrationReady = React96.useMemo(() => {
66344
- const orbitalNames = schema.orbitals.map((o) => o.name);
66345
- playgroundLog.debug("register:start", { schema: schema.name, orbitalNames });
66387
+ const lazySchemas = React96.useMemo(() => {
66346
66388
  const lazyPages = schema.lazyPages ?? [];
66347
- const lazy6 = lazyPages.length > 0 && lazyLoader !== void 0 ? Promise.all(lazyPages.map(async (page) => {
66389
+ if (lazyPages.length === 0 || lazyLoader === void 0) return Promise.resolve([]);
66390
+ return Promise.all(lazyPages.map(async (page) => {
66348
66391
  const loaded = await runtime.loadLazyPage(lazyLoader, page, schemaPath);
66349
66392
  if (!loaded.success) throw new Error(loaded.error);
66350
66393
  return loaded.data;
66351
- })) : Promise.resolve([]);
66352
- return lazy6.then(
66353
- (lazySchemas) => runtime$1.register(schema, { ...messages !== void 0 ? { messages } : {}, lazy: lazySchemas })
66354
- ).then(() => {
66355
- playgroundLog.debug("register:done", { schema: schema.name, orbitalNames });
66394
+ }));
66395
+ }, [schema.lazyPages, lazyLoader, schemaPath]);
66396
+ const registerProgram = React96.useCallback((program) => {
66397
+ const orbitalNames = program.orbitals.map((o) => o.name);
66398
+ playgroundLog.debug("register:start", { schema: program.name, orbitalNames });
66399
+ return lazySchemas.then((lazy6) => runtime$1.register(program, { ...messages !== void 0 ? { messages } : {}, lazy: lazy6 })).then(() => {
66400
+ playgroundLog.debug("register:done", { schema: program.name, orbitalNames });
66356
66401
  });
66357
- }, [runtime$1, schema, messages, lazyLoader, schemaPath]);
66402
+ }, [runtime$1, lazySchemas, messages]);
66403
+ const latestRegistration = React96.useRef(Promise.resolve());
66404
+ const registrationReady = React96.useMemo(() => {
66405
+ const ready = registerProgram(schema);
66406
+ latestRegistration.current = ready;
66407
+ return ready;
66408
+ }, [registerProgram, schema]);
66358
66409
  const teardownTimerRef = React96.useRef(null);
66359
66410
  React96.useEffect(() => {
66360
66411
  if (teardownTimerRef.current !== null) {
@@ -66372,18 +66423,22 @@ function BrowserPlayground({
66372
66423
  const transport = React96.useMemo(
66373
66424
  () => runtime.createInProcessTransport(
66374
66425
  async (orbitalName, request) => {
66375
- await registrationReady;
66426
+ await latestRegistration.current;
66376
66427
  return runtime$1.processOrbitalEvent(orbitalName, request);
66377
66428
  },
66378
66429
  {
66379
- // The program (lazy behaviors included) is registered above; the bridge only waits for it.
66380
- onRegister: () => registrationReady,
66430
+ // Registers what the bridge hands over (lazy behaviors included): a bridge that unregistered first gets it back.
66431
+ onRegister: (program) => {
66432
+ const ready = registerProgram(program);
66433
+ latestRegistration.current = ready;
66434
+ return ready;
66435
+ },
66381
66436
  onUnregister: () => {
66382
66437
  runtime$1.unregisterAll();
66383
66438
  }
66384
66439
  }
66385
66440
  ),
66386
- [runtime$1, registrationReady]
66441
+ [runtime$1, registerProgram, registrationReady]
66387
66442
  );
66388
66443
  const viewerLocale = locale ?? schema.locales?.[0];
66389
66444
  const i18n$1 = React96.useMemo(() => {
package/dist/avl/index.js CHANGED
@@ -1,11 +1,11 @@
1
- import { BrowserPlayground, collectEmbeddedTraits } from '../chunk-RHP5WL55.js';
1
+ import { BrowserPlayground, collectEmbeddedTraits } from '../chunk-HB3D3HUJ.js';
2
2
  import { zoomReducer, initialZoomState, getBreadcrumbs } from '../chunk-GZGDBS4S.js';
3
3
  import { useTranslate as useTranslate$1 } from '../chunk-N7JIG57B.js';
4
4
  import '../chunk-VHTJRS2N.js';
5
5
  import '../chunk-YYYHH5BA.js';
6
6
  import { spacingTokenOf, positionOf, withPosition, snapToSpacingStep, defaultSpacingStepPx, spacingOf, withSizing, withSpacing, layoutOf, withLayout, sizingOf, DESIGN_COLOR_TOKENS, DESIGN_RADIUS_TOKENS, DESIGN_SPACING_SCALE, sizeLimitOf, withSizeLimit, isArbitraryClass, tokenOfDesignClass } from '../chunk-D2E44ODB.js';
7
- import { AvlGlyph, Popover, Button, Icon, Select, Badge, IconButton, AvlStateMachine, Input, AvlOrbital, AvlTrait, AvlEntity, AvlPage, AvlEvent, AvlGuard, AvlEffect, AvlState, useAlmadarDndSensors, almadarDndCollisionDetection, TagInput, Checkbox, Switch, CodeBlock, AvlFieldType, FileTree, AvlTransitionDetail, RangeSlider, computeTraitLayout, edgePath, Accordion, FormField, Radio, useCompactLayout, ButtonGroup } from '../chunk-PYJ2UQWM.js';
8
- export { AVL_GLYPH_KINDS, AvlApplication, AvlBinding, AvlBindingRef, AvlCircuit, AvlEffect, AvlEffectChip, AvlEntity, AvlEvent, AvlField, AvlFieldType, AvlGlyph, AvlGuard, AvlLiteral, AvlOperator, AvlOrbital, AvlPage, AvlPersistence, AvlSExpr, AvlState, AvlStateMachine, AvlTrait, AvlTransition, AvlTransitionDetail, AvlTransitionExplainer, BehaviorView, FIELD_TYPE_SHAPES, MiniStateMachine, ModuleCard, computeTraitLayout, edgePath } from '../chunk-PYJ2UQWM.js';
7
+ import { AvlGlyph, Popover, Button, Icon, Select, Badge, IconButton, AvlStateMachine, Input, AvlOrbital, AvlTrait, AvlEntity, AvlPage, AvlEvent, AvlGuard, AvlEffect, AvlState, useAlmadarDndSensors, almadarDndCollisionDetection, TagInput, Checkbox, Switch, CodeBlock, AvlFieldType, FileTree, AvlTransitionDetail, RangeSlider, computeTraitLayout, edgePath, Accordion, FormField, Radio, useCompactLayout, ButtonGroup } from '../chunk-I2ZNE5TD.js';
8
+ export { AVL_GLYPH_KINDS, AvlApplication, AvlBinding, AvlBindingRef, AvlCircuit, AvlEffect, AvlEffectChip, AvlEntity, AvlEvent, AvlField, AvlFieldType, AvlGlyph, AvlGuard, AvlLiteral, AvlOperator, AvlOrbital, AvlPage, AvlPersistence, AvlSExpr, AvlState, AvlStateMachine, AvlTrait, AvlTransition, AvlTransitionDetail, AvlTransitionExplainer, BehaviorView, FIELD_TYPE_SHAPES, MiniStateMachine, ModuleCard, computeTraitLayout, edgePath } from '../chunk-I2ZNE5TD.js';
9
9
  import { avlSeries, STATE_COLORS, Box, HStack, VStack, avlTint, CONNECTION_COLORS, parseTraitLevel, parseApplicationLevel, parseOrbitalLevel, getStateRole, effectCategoryOf, EFFECT_CATEGORY_COLORS, pressableProps, traitTransitionRenderUi, traitEventWires } from '../chunk-HA7CJWQX.js';
10
10
  export { CONNECTION_COLORS, EFFECT_CATEGORY_COLORS, OPERATOR_CATEGORY_COLORS, STATE_COLORS, effectCategoryOf, getStateRole, parseApplicationLevel, parseOrbitalLevel, parseTraitLevel, parseTransitionLevel, traitLevelFromTrait } from '../chunk-HA7CJWQX.js';
11
11
  import { Typography, INLINE_TEXT_ATTR } from '../chunk-4ZGXIW3B.js';