@almadar/ui 5.60.0 → 5.61.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.
@@ -8421,16 +8421,6 @@ var init_Skeleton = __esm({
8421
8421
  Skeleton.displayName = "Skeleton";
8422
8422
  }
8423
8423
  });
8424
- function isKnownPattern(type) {
8425
- return type in componentMapping;
8426
- }
8427
- var componentMapping;
8428
- var init_pattern_resolver = __esm({
8429
- "renderer/pattern-resolver.ts"() {
8430
- createLogger("almadar:ui:pattern-resolver");
8431
- componentMapping = {};
8432
- }
8433
- });
8434
8424
 
8435
8425
  // renderer/slot-definitions.ts
8436
8426
  function isPortalSlot(slot) {
@@ -8539,7 +8529,6 @@ var init_navigation = __esm({
8539
8529
  // renderer/index.ts
8540
8530
  var init_renderer = __esm({
8541
8531
  "renderer/index.ts"() {
8542
- init_pattern_resolver();
8543
8532
  init_slot_definitions();
8544
8533
  }
8545
8534
  });
@@ -10243,7 +10232,7 @@ function recordTransition(trace) {
10243
10232
  ...trace,
10244
10233
  id: `t-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`
10245
10234
  };
10246
- log5.debug("transition:recorded", { trait: trace.traitName, from: trace.from, to: trace.to, event: trace.event, effectCount: trace.effects.length });
10235
+ log4.debug("transition:recorded", { trait: trace.traitName, from: trace.from, to: trace.to, event: trace.event, effectCount: trace.effects.length });
10247
10236
  getState().transitions.push(entry);
10248
10237
  if (getState().transitions.length > MAX_TRANSITIONS) {
10249
10238
  getState().transitions.shift();
@@ -10342,7 +10331,7 @@ function getTraitSnapshots() {
10342
10331
  try {
10343
10332
  snapshots.push(getter());
10344
10333
  } catch (err) {
10345
- log5.error("traitSnapshot getter failed", { trait: traitName, err: String(err) });
10334
+ log4.error("traitSnapshot getter failed", { trait: traitName, err: String(err) });
10346
10335
  }
10347
10336
  }
10348
10337
  return snapshots;
@@ -10441,10 +10430,10 @@ function updateAssetStatus(url, status) {
10441
10430
  window.__orbitalVerification.assetStatus[url] = status;
10442
10431
  }
10443
10432
  }
10444
- var log5, MAX_TRANSITIONS;
10433
+ var log4, MAX_TRANSITIONS;
10445
10434
  var init_verificationRegistry = __esm({
10446
10435
  "lib/verificationRegistry.ts"() {
10447
- log5 = createLogger("almadar:bridge");
10436
+ log4 = createLogger("almadar:bridge");
10448
10437
  MAX_TRANSITIONS = 500;
10449
10438
  exposeOnWindow();
10450
10439
  }
@@ -12773,7 +12762,7 @@ var init_avl_elk_layout = __esm({
12773
12762
  elk = new ELK();
12774
12763
  }
12775
12764
  });
12776
- var log6, SWIM_GUTTER, CENTER_W, BehaviorView;
12765
+ var log5, SWIM_GUTTER, CENTER_W, BehaviorView;
12777
12766
  var init_BehaviorView = __esm({
12778
12767
  "components/avl/molecules/BehaviorView.tsx"() {
12779
12768
  "use client";
@@ -12782,7 +12771,7 @@ var init_BehaviorView = __esm({
12782
12771
  init_AvlSwimLane();
12783
12772
  init_types();
12784
12773
  init_avl_elk_layout();
12785
- log6 = createLogger("almadar:ui:avl:behavior-view");
12774
+ log5 = createLogger("almadar:ui:avl:behavior-view");
12786
12775
  SWIM_GUTTER = 120;
12787
12776
  CENTER_W = 360;
12788
12777
  BehaviorView = ({ data }) => {
@@ -12793,7 +12782,7 @@ var init_BehaviorView = __esm({
12793
12782
  const dataKey = useMemo(() => JSON.stringify(traitData), [traitData]);
12794
12783
  useEffect(() => {
12795
12784
  if (!traitData) return;
12796
- computeTraitLayout(traitData).then(setLayout).catch((err) => log6.error("compute-trait-layout-failed", { error: err instanceof Error ? err : String(err) }));
12785
+ computeTraitLayout(traitData).then(setLayout).catch((err) => log5.error("compute-trait-layout-failed", { error: err instanceof Error ? err : String(err) }));
12797
12786
  }, [dataKey]);
12798
12787
  if (!traitData) {
12799
12788
  return /* @__PURE__ */ jsx("div", { className: "rounded-lg border border-[var(--color-border)] bg-[var(--color-card)] p-4 text-center text-[var(--color-muted-foreground)] text-sm", children: t("avl.noTraitData") });
@@ -13204,7 +13193,7 @@ function generateDiff(oldVal, newVal) {
13204
13193
  }
13205
13194
  return diff;
13206
13195
  }
13207
- var orbStyleOverrides, orbStyle, loloStyleOverrides, loloStyle, log7, CODE_LANGUAGES, CODE_LANGUAGE_SET, DIFF_STYLES, LINE_PROPS_FN, HIDDEN_LINE_NUMBERS, CodeBlock;
13196
+ var orbStyleOverrides, orbStyle, loloStyleOverrides, loloStyle, log6, CODE_LANGUAGES, CODE_LANGUAGE_SET, DIFF_STYLES, LINE_PROPS_FN, HIDDEN_LINE_NUMBERS, CodeBlock;
13208
13197
  var init_CodeBlock = __esm({
13209
13198
  "components/core/molecules/markdown/CodeBlock.tsx"() {
13210
13199
  init_cn();
@@ -13287,7 +13276,7 @@ var init_CodeBlock = __esm({
13287
13276
  "lolo-op-async": { color: ORB_COLORS.dark.async }
13288
13277
  };
13289
13278
  loloStyle = { ...dark, ...loloStyleOverrides };
13290
- log7 = createLogger("almadar:ui:markdown-code");
13279
+ log6 = createLogger("almadar:ui:markdown-code");
13291
13280
  CODE_LANGUAGES = [
13292
13281
  "text",
13293
13282
  "json",
@@ -13551,7 +13540,7 @@ var init_CodeBlock = __esm({
13551
13540
  eventBus.emit("UI:COPY_CODE", { language: activeLanguage, success: true });
13552
13541
  setTimeout(() => setCopied(false), 2e3);
13553
13542
  } catch (err) {
13554
- log7.error("Failed to copy code", { error: err instanceof Error ? err : String(err) });
13543
+ log6.error("Failed to copy code", { error: err instanceof Error ? err : String(err) });
13555
13544
  eventBus.emit("UI:COPY_CODE", { language: activeLanguage, success: false });
13556
13545
  }
13557
13546
  };
@@ -17432,14 +17421,14 @@ function useSafeEventBus2() {
17432
17421
  } };
17433
17422
  }
17434
17423
  }
17435
- var log8, lookStyles4, ButtonGroup;
17424
+ var log7, lookStyles4, ButtonGroup;
17436
17425
  var init_ButtonGroup = __esm({
17437
17426
  "components/core/molecules/ButtonGroup.tsx"() {
17438
17427
  "use client";
17439
17428
  init_cn();
17440
17429
  init_atoms2();
17441
17430
  init_useEventBus();
17442
- log8 = createLogger("almadar:ui:button-group");
17431
+ log7 = createLogger("almadar:ui:button-group");
17443
17432
  lookStyles4 = {
17444
17433
  "right-aligned-buttons": "",
17445
17434
  "floating-bar": "fixed bottom-section left-1/2 -translate-x-1/2 shadow-elevation-toast bg-card p-card-sm rounded-container",
@@ -17520,7 +17509,7 @@ var init_ButtonGroup = __esm({
17520
17509
  {
17521
17510
  variant: "ghost",
17522
17511
  onClick: () => {
17523
- log8.debug("Filter clicked", { field: filter.field });
17512
+ log7.debug("Filter clicked", { field: filter.field });
17524
17513
  },
17525
17514
  children: filter.label
17526
17515
  },
@@ -25182,9 +25171,9 @@ function debug(...args) {
25182
25171
  const [first, ...rest] = args;
25183
25172
  const message = typeof first === "string" ? first : "<debug>";
25184
25173
  if (rest.length === 0 && typeof first === "string") {
25185
- log9.debug(message);
25174
+ log8.debug(message);
25186
25175
  } else {
25187
- log9.debug(message, { args: rest.length > 0 ? formatArgs(rest) : formatArgs([first]) });
25176
+ log8.debug(message, { args: rest.length > 0 ? formatArgs(rest) : formatArgs([first]) });
25188
25177
  }
25189
25178
  }
25190
25179
  function debugGroup(label) {
@@ -25212,11 +25201,11 @@ function toLogMetaValue(v) {
25212
25201
  }
25213
25202
  return String(v);
25214
25203
  }
25215
- var NAMESPACE, log9;
25204
+ var NAMESPACE, log8;
25216
25205
  var init_debug = __esm({
25217
25206
  "lib/debug.ts"() {
25218
25207
  NAMESPACE = "almadar:ui:debug";
25219
- log9 = createLogger(NAMESPACE);
25208
+ log8 = createLogger(NAMESPACE);
25220
25209
  createLogger("almadar:ui:debug:input");
25221
25210
  createLogger("almadar:ui:debug:collision");
25222
25211
  createLogger("almadar:ui:debug:physics");
@@ -37656,6 +37645,7 @@ var init_GraphCanvas = __esm({
37656
37645
  draggable = true,
37657
37646
  actions,
37658
37647
  onNodeClick,
37648
+ onNodeDoubleClick,
37659
37649
  nodeClickEvent,
37660
37650
  selectedNodeId,
37661
37651
  repulsion = 800,
@@ -37675,6 +37665,19 @@ var init_GraphCanvas = __esm({
37675
37665
  const [hoveredNode, setHoveredNode] = useState(null);
37676
37666
  const nodesRef = useRef([]);
37677
37667
  const [, forceUpdate] = useState(0);
37668
+ const [logicalW, setLogicalW] = useState(800);
37669
+ useEffect(() => {
37670
+ const canvas = canvasRef.current;
37671
+ if (!canvas || typeof ResizeObserver === "undefined") return;
37672
+ const measure = () => {
37673
+ const width = Math.round(canvas.clientWidth);
37674
+ if (width > 0) setLogicalW(width);
37675
+ };
37676
+ measure();
37677
+ const ro = new ResizeObserver(measure);
37678
+ ro.observe(canvas);
37679
+ return () => ro.disconnect();
37680
+ }, []);
37678
37681
  const interactionRef = useRef({
37679
37682
  mode: "none",
37680
37683
  dragNodeId: null,
@@ -37687,10 +37690,8 @@ var init_GraphCanvas = __esm({
37687
37690
  const canvas = canvasRef.current;
37688
37691
  if (!canvas) return null;
37689
37692
  const rect = canvas.getBoundingClientRect();
37690
- const scaleX = rect.width > 0 ? canvas.width / rect.width : 1;
37691
- const scaleY = rect.height > 0 ? canvas.height / rect.height : 1;
37692
- const screenX = (e.clientX - rect.left) * scaleX;
37693
- const screenY = (e.clientY - rect.top) * scaleY;
37693
+ const screenX = e.clientX - rect.left;
37694
+ const screenY = e.clientY - rect.top;
37694
37695
  return {
37695
37696
  screenX,
37696
37697
  screenY,
@@ -37730,8 +37731,8 @@ var init_GraphCanvas = __esm({
37730
37731
  useEffect(() => {
37731
37732
  const canvas = canvasRef.current;
37732
37733
  if (!canvas || propNodes.length === 0) return;
37733
- const w = canvas.width;
37734
- const h = canvas.height;
37734
+ const w = logicalW;
37735
+ const h = height;
37735
37736
  const simNodes = propNodes.map((n, idx) => {
37736
37737
  let x = n.x ?? 0;
37737
37738
  let y = n.y ?? 0;
@@ -37821,29 +37822,41 @@ var init_GraphCanvas = __esm({
37821
37822
  return () => {
37822
37823
  cancelAnimationFrame(animRef.current);
37823
37824
  };
37824
- }, [propNodes, propEdges, layout, repulsion, linkDistance]);
37825
+ }, [propNodes, propEdges, layout, repulsion, linkDistance, logicalW, height]);
37825
37826
  useEffect(() => {
37826
37827
  const canvas = canvasRef.current;
37827
37828
  if (!canvas) return;
37828
37829
  const ctx = canvas.getContext("2d");
37829
37830
  if (!ctx) return;
37830
- const w = canvas.width;
37831
- const h = canvas.height;
37831
+ const w = logicalW;
37832
+ const h = height;
37832
37833
  const nodes = nodesRef.current;
37833
37834
  const accentColor = resolveColor2("var(--color-accent)", canvas);
37835
+ const dpr = typeof window !== "undefined" && window.devicePixelRatio || 1;
37836
+ ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
37834
37837
  ctx.clearRect(0, 0, w, h);
37835
37838
  ctx.save();
37836
37839
  ctx.translate(offset.x, offset.y);
37837
37840
  ctx.scale(zoom, zoom);
37841
+ const neighbors = /* @__PURE__ */ new Set();
37842
+ if (hoveredNode) {
37843
+ neighbors.add(hoveredNode);
37844
+ for (const edge of propEdges) {
37845
+ if (edge.source === hoveredNode) neighbors.add(String(edge.target));
37846
+ else if (edge.target === hoveredNode) neighbors.add(String(edge.source));
37847
+ }
37848
+ }
37838
37849
  for (const edge of propEdges) {
37839
37850
  const source = nodes.find((n) => n.id === edge.source);
37840
37851
  const target = nodes.find((n) => n.id === edge.target);
37841
37852
  if (!source || !target) continue;
37853
+ const incident = !!hoveredNode && (edge.source === hoveredNode || edge.target === hoveredNode);
37854
+ ctx.globalAlpha = hoveredNode ? incident ? 1 : 0.12 : 1;
37842
37855
  ctx.beginPath();
37843
37856
  ctx.moveTo(source.x, source.y);
37844
37857
  ctx.lineTo(target.x, target.y);
37845
- ctx.strokeStyle = edge.color || "#88888866";
37846
- ctx.lineWidth = edge.weight ? Math.max(1, edge.weight) : 1;
37858
+ ctx.strokeStyle = incident ? accentColor : edge.color || "#88888866";
37859
+ ctx.lineWidth = incident ? 2 : edge.weight ? Math.max(1, edge.weight) : 1;
37847
37860
  ctx.stroke();
37848
37861
  if (edge.label && showLabels) {
37849
37862
  const mx = (source.x + target.x) / 2;
@@ -37854,11 +37867,13 @@ var init_GraphCanvas = __esm({
37854
37867
  ctx.fillText(edge.label, mx, my - 4);
37855
37868
  }
37856
37869
  }
37870
+ ctx.globalAlpha = 1;
37857
37871
  for (const node of nodes) {
37858
37872
  const size = node.size || 8;
37859
37873
  const color = resolveColor2(node.color || getGroupColor(node.group, groups), canvas);
37860
37874
  const isHovered = hoveredNode === node.id;
37861
37875
  const isSelected = selectedNodeId !== void 0 && node.id === selectedNodeId;
37876
+ ctx.globalAlpha = hoveredNode && !neighbors.has(node.id) ? 0.2 : 1;
37862
37877
  const radius = isSelected ? size + 4 : isHovered ? size + 2 : size;
37863
37878
  ctx.beginPath();
37864
37879
  ctx.arc(node.x, node.y, radius, 0, Math.PI * 2);
@@ -37978,6 +37993,15 @@ var init_GraphCanvas = __esm({
37978
37993
  interactionRef.current.dragNodeId = null;
37979
37994
  setHoveredNode(null);
37980
37995
  }, []);
37996
+ const handleDoubleClick = useCallback(
37997
+ (e) => {
37998
+ const coords = toCoords(e);
37999
+ if (!coords) return;
38000
+ const node = nodeAt(coords.graphX, coords.graphY);
38001
+ if (node) onNodeDoubleClick?.(node);
38002
+ },
38003
+ [toCoords, nodeAt, onNodeDoubleClick]
38004
+ );
37981
38005
  if (isLoading) {
37982
38006
  return /* @__PURE__ */ jsx(LoadingState, { message: t("common.loading"), className });
37983
38007
  }
@@ -38035,15 +38059,16 @@ var init_GraphCanvas = __esm({
38035
38059
  "canvas",
38036
38060
  {
38037
38061
  ref: canvasRef,
38038
- width: 800,
38039
- height,
38062
+ width: Math.round(logicalW * (typeof window !== "undefined" && window.devicePixelRatio || 1)),
38063
+ height: Math.round(height * (typeof window !== "undefined" && window.devicePixelRatio || 1)),
38040
38064
  className: "w-full cursor-grab active:cursor-grabbing",
38041
38065
  style: { height },
38042
38066
  onWheel: handleWheel,
38043
38067
  onMouseDown: handleMouseDown,
38044
38068
  onMouseMove: handleMouseMove,
38045
38069
  onMouseUp: handleMouseUp,
38046
- onMouseLeave: handleMouseLeave
38070
+ onMouseLeave: handleMouseLeave,
38071
+ onDoubleClick: handleDoubleClick
38047
38072
  }
38048
38073
  ) }),
38049
38074
  groups.length > 1 && /* @__PURE__ */ jsx(HStack, { gap: "md", className: "px-4 py-2 border-t border-border", wrap: true, children: groups.map((group, idx) => /* @__PURE__ */ jsxs(HStack, { gap: "xs", align: "center", children: [
@@ -41637,11 +41662,11 @@ var init_Canvas3DErrorBoundary = __esm({
41637
41662
  "components/game/molecules/three/components/Canvas3DErrorBoundary.css"() {
41638
41663
  }
41639
41664
  });
41640
- var log10, Canvas3DErrorBoundary;
41665
+ var log9, Canvas3DErrorBoundary;
41641
41666
  var init_Canvas3DErrorBoundary2 = __esm({
41642
41667
  "components/game/molecules/three/components/Canvas3DErrorBoundary.tsx"() {
41643
41668
  init_Canvas3DErrorBoundary();
41644
- log10 = createLogger("almadar:ui:game:canvas3d:error-boundary");
41669
+ log9 = createLogger("almadar:ui:game:canvas3d:error-boundary");
41645
41670
  Canvas3DErrorBoundary = class extends Component {
41646
41671
  constructor(props) {
41647
41672
  super(props);
@@ -41669,8 +41694,8 @@ var init_Canvas3DErrorBoundary2 = __esm({
41669
41694
  componentDidCatch(error, errorInfo) {
41670
41695
  this.setState({ errorInfo });
41671
41696
  this.props.onError?.(error, errorInfo);
41672
- log10.error("Error caught", { error });
41673
- log10.error("Component stack", { componentStack: errorInfo.componentStack ?? "<none>" });
41697
+ log9.error("Error caught", { error });
41698
+ log9.error("Component stack", { componentStack: errorInfo.componentStack ?? "<none>" });
41674
41699
  }
41675
41700
  render() {
41676
41701
  if (this.state.hasError) {
@@ -41733,7 +41758,7 @@ function useGLTFModel(url, resourceBasePath) {
41733
41758
  setState({ model: null, isLoading: false, error: null });
41734
41759
  return;
41735
41760
  }
41736
- log11.debug("Loading", { url });
41761
+ log10.debug("Loading", { url });
41737
41762
  setState((prev) => ({ ...prev, isLoading: true, error: null }));
41738
41763
  const assetRoot = resourceBasePath || detectAssetRoot2(url);
41739
41764
  const loader = new GLTFLoader$1();
@@ -41741,7 +41766,7 @@ function useGLTFModel(url, resourceBasePath) {
41741
41766
  loader.load(
41742
41767
  url,
41743
41768
  (gltf) => {
41744
- log11.debug("Loaded", { url });
41769
+ log10.debug("Loaded", { url });
41745
41770
  setState({
41746
41771
  model: gltf.scene,
41747
41772
  isLoading: false,
@@ -41750,7 +41775,7 @@ function useGLTFModel(url, resourceBasePath) {
41750
41775
  },
41751
41776
  void 0,
41752
41777
  (err) => {
41753
- log11.warn("Failed", { url, error: err instanceof Error ? err : String(err) });
41778
+ log10.warn("Failed", { url, error: err instanceof Error ? err : String(err) });
41754
41779
  setState({
41755
41780
  model: null,
41756
41781
  isLoading: false,
@@ -41866,11 +41891,11 @@ function ModelLoader({
41866
41891
  }
41867
41892
  );
41868
41893
  }
41869
- var log11;
41894
+ var log10;
41870
41895
  var init_ModelLoader = __esm({
41871
41896
  "components/game/molecules/three/components/ModelLoader.tsx"() {
41872
41897
  "use client";
41873
- log11 = createLogger("almadar:ui:game:model-loader");
41898
+ log10 = createLogger("almadar:ui:game:model-loader");
41874
41899
  }
41875
41900
  });
41876
41901
 
@@ -42131,24 +42156,28 @@ var init_GameCanvas3D2 = __esm({
42131
42156
  const cameraConfig = useMemo(() => {
42132
42157
  const size = Math.max(
42133
42158
  gridBounds.maxX - gridBounds.minX,
42134
- gridBounds.maxZ - gridBounds.minZ
42159
+ gridBounds.maxZ - gridBounds.minZ,
42160
+ 4
42161
+ // minimum framing distance so a tiny board isn't zoomed in
42135
42162
  );
42136
- const distance = size * 1.5;
42163
+ const cx = (gridBounds.minX + gridBounds.maxX) / 2;
42164
+ const cz = (gridBounds.minZ + gridBounds.maxZ) / 2;
42165
+ const d = size * 1.5;
42137
42166
  switch (cameraMode) {
42138
42167
  case "isometric":
42139
42168
  return {
42140
- position: [distance, distance * 0.8, distance],
42169
+ position: [cx + d, d * 0.8, cz + d],
42141
42170
  fov: 45
42142
42171
  };
42143
42172
  case "top-down":
42144
42173
  return {
42145
- position: [0, distance * 2, 0],
42174
+ position: [cx, d * 2, cz],
42146
42175
  fov: 45
42147
42176
  };
42148
42177
  case "perspective":
42149
42178
  default:
42150
42179
  return {
42151
- position: [distance, distance, distance],
42180
+ position: [cx + d, d, cz + d],
42152
42181
  fov: 45
42153
42182
  };
42154
42183
  }
@@ -42387,7 +42416,8 @@ var init_GameCanvas3D2 = __esm({
42387
42416
  "div",
42388
42417
  {
42389
42418
  ref: containerRef,
42390
- className: cn("game-canvas-3d relative w-full h-full min-h-[85vh] overflow-hidden", className),
42419
+ className: cn("game-canvas-3d relative w-full overflow-hidden", className),
42420
+ style: { minHeight: "85vh" },
42391
42421
  "data-orientation": orientation,
42392
42422
  "data-camera-mode": cameraMode,
42393
42423
  "data-overlay": overlay,
@@ -42402,7 +42432,7 @@ var init_GameCanvas3D2 = __esm({
42402
42432
  near: 0.1,
42403
42433
  far: 1e3
42404
42434
  },
42405
- style: { background: backgroundColor },
42435
+ style: { background: backgroundColor, height: "85vh", width: "100%" },
42406
42436
  onClick: (e) => {
42407
42437
  if (e.target === e.currentTarget) {
42408
42438
  eventHandlers.handleCanvasClick(e);
@@ -46204,7 +46234,7 @@ function getAllEvents(traits2) {
46204
46234
  function EventDispatcherTab({ traits: traits2, schema }) {
46205
46235
  const eventBus = useEventBus();
46206
46236
  const { t } = useTranslate();
46207
- const [log15, setLog] = React81.useState([]);
46237
+ const [log14, setLog] = React81.useState([]);
46208
46238
  const prevStatesRef = React81.useRef(/* @__PURE__ */ new Map());
46209
46239
  React81.useEffect(() => {
46210
46240
  for (const trait of traits2) {
@@ -46268,9 +46298,9 @@ function EventDispatcherTab({ traits: traits2, schema }) {
46268
46298
  /* @__PURE__ */ jsx(Typography, { variant: "small", weight: "medium", className: "text-gray-500 mb-1", children: t("debug.otherEvents") }),
46269
46299
  /* @__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)) })
46270
46300
  ] }),
46271
- log15.length > 0 && /* @__PURE__ */ jsxs("div", { children: [
46301
+ log14.length > 0 && /* @__PURE__ */ jsxs("div", { children: [
46272
46302
  /* @__PURE__ */ jsx(Typography, { variant: "small", weight: "medium", className: "text-gray-500 mb-1", children: t("debug.recentTransitions") }),
46273
- /* @__PURE__ */ jsx(Stack, { gap: "xs", children: log15.map((entry, i) => /* @__PURE__ */ jsxs(Typography, { variant: "small", className: "font-mono text-xs", children: [
46303
+ /* @__PURE__ */ jsx(Stack, { gap: "xs", children: log14.map((entry, i) => /* @__PURE__ */ jsxs(Typography, { variant: "small", className: "font-mono text-xs", children: [
46274
46304
  /* @__PURE__ */ jsx("span", { className: "text-purple-400", children: entry.traitName }),
46275
46305
  " ",
46276
46306
  /* @__PURE__ */ jsx("span", { className: "text-gray-500", children: entry.from }),
@@ -51285,7 +51315,7 @@ function isPatternConfig(value) {
51285
51315
  if (value instanceof Date) return false;
51286
51316
  if (typeof value === "function") return false;
51287
51317
  const record = value;
51288
- return "type" in record && typeof record.type === "string" && isKnownPattern(record.type);
51318
+ return "type" in record && typeof record.type === "string" && getComponentForPattern$1(record.type) !== null;
51289
51319
  }
51290
51320
  function isPlainConfigObject(value) {
51291
51321
  if (React81__default.isValidElement(value)) return false;
@@ -52032,7 +52062,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
52032
52062
  };
52033
52063
  }, [traitBindings]);
52034
52064
  const executeTransitionEffects = useCallback(async (params) => {
52035
- const { binding, previousState, newState, payload, flushEvent, syncOnly, log: log15 } = params;
52065
+ const { binding, previousState, newState, payload, flushEvent, syncOnly, log: log14 } = params;
52036
52066
  const traitName = binding.trait.name;
52037
52067
  const linkedEntity = binding.linkedEntity || "";
52038
52068
  const entityId = payload?.entityId;
@@ -52120,7 +52150,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
52120
52150
  ...handlers,
52121
52151
  set: async (targetId, field, value) => {
52122
52152
  if (baseSet) await baseSet(targetId, field, value);
52123
- log15.debug("set:write", {
52153
+ log14.debug("set:write", {
52124
52154
  traitName,
52125
52155
  field,
52126
52156
  value: JSON.stringify(value),
@@ -52160,7 +52190,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
52160
52190
  const executor = new EffectExecutor({ handlers: trackingHandlers, bindings: bindingCtx, context: effectContext });
52161
52191
  try {
52162
52192
  await executor.executeAll(effects);
52163
- log15.debug("effects:executed", () => ({
52193
+ log14.debug("effects:executed", () => ({
52164
52194
  traitName,
52165
52195
  transition: `${previousState}->${newState}`,
52166
52196
  event: flushEvent,
@@ -52170,7 +52200,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
52170
52200
  slotsTouched: Array.from(pendingSlots.keys()).join(",")
52171
52201
  }));
52172
52202
  for (const [slot, patterns] of pendingSlots) {
52173
- log15.debug("flush:slot", {
52203
+ log14.debug("flush:slot", {
52174
52204
  traitName,
52175
52205
  slot,
52176
52206
  patternCount: patterns.length,
@@ -52185,7 +52215,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
52185
52215
  });
52186
52216
  }
52187
52217
  } catch (error) {
52188
- log15.error("effects:error", {
52218
+ log14.error("effects:error", {
52189
52219
  traitName,
52190
52220
  transition: `${previousState}->${newState}`,
52191
52221
  event: flushEvent,
@@ -52660,7 +52690,7 @@ function clearSchemaCache() {
52660
52690
 
52661
52691
  // runtime/index.ts
52662
52692
  init_EntitySchemaContext();
52663
- var log12 = createLogger("almadar:ui:trait-provider");
52693
+ var log11 = createLogger("almadar:ui:trait-provider");
52664
52694
  var TraitContext = createContext(null);
52665
52695
  function TraitProvider({
52666
52696
  traits: traitBindings,
@@ -52677,7 +52707,7 @@ function TraitProvider({
52677
52707
  currentState: stateName,
52678
52708
  availableEvents: trait.transitions.filter((t) => t.from === stateName).map((t) => t.event),
52679
52709
  dispatch: (eventKey, payload) => {
52680
- log12.debug("Dispatch", () => ({
52710
+ log11.debug("Dispatch", () => ({
52681
52711
  trait: trait.name,
52682
52712
  event: eventKey,
52683
52713
  payloadKeys: payload ? Object.keys(payload) : []
@@ -53427,7 +53457,7 @@ OrbitalThemeProvider.displayName = "OrbitalThemeProvider";
53427
53457
  init_navigation();
53428
53458
  init_verificationRegistry();
53429
53459
  var PERF_NAMESPACE = "almadar:perf:canvas";
53430
- var log14 = createLogger(PERF_NAMESPACE);
53460
+ var log13 = createLogger(PERF_NAMESPACE);
53431
53461
  var RING_SIZE = 50;
53432
53462
  var ring = [];
53433
53463
  var writeIdx = 0;
@@ -53482,7 +53512,7 @@ function perfEnd(name, startToken, detail) {
53482
53512
  }
53483
53513
  }
53484
53514
  push({ name, durationMs, ts: endTs, detail });
53485
- log14.debug(name, () => ({ durationMs, ...detail ?? {} }));
53515
+ log13.debug(name, () => ({ durationMs, ...detail ?? {} }));
53486
53516
  }
53487
53517
  function perfTime(name, fn, detail) {
53488
53518
  const t = perfStart(name);
@@ -53500,7 +53530,7 @@ var profilerOnRender = (id, phase, actualDuration, baseDuration, _startTime, com
53500
53530
  ts: commitTime,
53501
53531
  detail: { baseDuration }
53502
53532
  });
53503
- log14.debug(`profiler:${id}:${phase}`, () => ({ actualDuration, baseDuration }));
53533
+ log13.debug(`profiler:${id}:${phase}`, () => ({ actualDuration, baseDuration }));
53504
53534
  };
53505
53535
  function getPerfSnapshot() {
53506
53536
  if (ring.length < RING_SIZE) return ring.slice();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@almadar/ui",
3
- "version": "5.60.0",
3
+ "version": "5.61.0",
4
4
  "description": "React UI components, hooks, and providers for Almadar",
5
5
  "type": "module",
6
6
  "sideEffects": [