@almadar/ui 4.23.0 → 4.25.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.
@@ -47023,7 +47023,8 @@ function renderPatternChildren(children, onDismiss, parentId = "root", parentPat
47023
47023
  if (!child || typeof child !== "object") return null;
47024
47024
  const childId = `${parentId}-${index}`;
47025
47025
  const childPath = parentPath === "root" ? `root.children.${index}` : `${parentPath}.children.${index}`;
47026
- const { type: _childType, props: nestedProps, _id: _childNodeId, children: _childChildren, ...flatProps } = child;
47026
+ const childAsRecord = child;
47027
+ const { type: _childType, props: nestedProps, _id: _childNodeId, children: _childChildren, ...flatProps } = childAsRecord;
47027
47028
  const resolvedProps = nestedProps !== void 0 ? nestedProps : flatProps;
47028
47029
  if (_childChildren !== void 0 && nestedProps === void 0) {
47029
47030
  resolvedProps.children = _childChildren;
@@ -47051,7 +47052,46 @@ function renderPatternChildren(children, onDismiss, parentId = "root", parentPat
47051
47052
  });
47052
47053
  }
47053
47054
  function isPatternConfig(value) {
47054
- return value !== null && typeof value === "object" && !Array.isArray(value) && "type" in value && typeof value.type === "string";
47055
+ if (value === null || value === void 0) return false;
47056
+ if (typeof value !== "object") return false;
47057
+ if (Array.isArray(value)) return false;
47058
+ if (React127__namespace.default.isValidElement(value)) return false;
47059
+ if (value instanceof Date) return false;
47060
+ if (typeof value === "function") return false;
47061
+ const record = value;
47062
+ return "type" in record && typeof record.type === "string";
47063
+ }
47064
+ function isPlainConfigObject(value) {
47065
+ if (React127__namespace.default.isValidElement(value)) return false;
47066
+ if (value instanceof Date) return false;
47067
+ const proto = Object.getPrototypeOf(value);
47068
+ return proto === Object.prototype || proto === null;
47069
+ }
47070
+ function substituteTraitRefsDeep(value, pathKey) {
47071
+ if (typeof value === "string") {
47072
+ const match = TRAIT_BINDING_RE.exec(value);
47073
+ if (match) {
47074
+ const traitName = match[1];
47075
+ return /* @__PURE__ */ jsxRuntime.jsx(TraitFrame, { traitName }, `${pathKey}:${traitName}`);
47076
+ }
47077
+ return value;
47078
+ }
47079
+ if (typeof value === "number" || typeof value === "boolean" || value === null || value === void 0 || typeof value === "function") {
47080
+ return value;
47081
+ }
47082
+ if (Array.isArray(value)) {
47083
+ return value.map(
47084
+ (item, i) => substituteTraitRefsDeep(item, `${pathKey}[${i}]`)
47085
+ );
47086
+ }
47087
+ if (typeof value === "object" && isPlainConfigObject(value)) {
47088
+ const out = {};
47089
+ for (const [k, v] of Object.entries(value)) {
47090
+ out[k] = substituteTraitRefsDeep(v, `${pathKey}.${k}`);
47091
+ }
47092
+ return out;
47093
+ }
47094
+ return value;
47055
47095
  }
47056
47096
  function renderPatternProps(props, onDismiss) {
47057
47097
  const rendered = {};
@@ -47059,17 +47099,19 @@ function renderPatternProps(props, onDismiss) {
47059
47099
  if (key === "children") {
47060
47100
  rendered[key] = value;
47061
47101
  } else if (isPatternConfig(value)) {
47102
+ const nestedProps = {};
47103
+ for (const [k, v] of Object.entries(value)) {
47104
+ if (k !== "type") nestedProps[k] = v;
47105
+ }
47062
47106
  const childContent = {
47063
47107
  id: `prop-${key}`,
47064
47108
  pattern: value.type,
47065
- props: Object.fromEntries(
47066
- Object.entries(value).filter(([k]) => k !== "type")
47067
- ),
47109
+ props: nestedProps,
47068
47110
  priority: 0
47069
47111
  };
47070
47112
  rendered[key] = /* @__PURE__ */ jsxRuntime.jsx(SlotContentRenderer, { content: childContent, onDismiss });
47071
47113
  } else {
47072
- rendered[key] = value;
47114
+ rendered[key] = substituteTraitRefsDeep(value, `prop:${key}`);
47073
47115
  }
47074
47116
  }
47075
47117
  return rendered;
@@ -51680,7 +51722,7 @@ function resolveLambdaBindings(body, argName, arg) {
51680
51722
  let cur = arg;
51681
51723
  for (const seg of path.split(".")) {
51682
51724
  if (cur === null || cur === void 0) return void 0;
51683
- if (typeof cur !== "object") return void 0;
51725
+ if (typeof cur !== "object" || Array.isArray(cur)) return void 0;
51684
51726
  cur = cur[seg];
51685
51727
  }
51686
51728
  return cur;
@@ -51696,7 +51738,7 @@ function resolveLambdaBindings(body, argName, arg) {
51696
51738
  if (Array.isArray(body)) {
51697
51739
  return body.map((b) => resolveLambdaBindings(b, argName, arg));
51698
51740
  }
51699
- if (body !== null && typeof body === "object") {
51741
+ if (body !== null && typeof body === "object" && !React127__namespace.default.isValidElement(body) && !(body instanceof Date) && typeof body !== "function") {
51700
51742
  const out = {};
51701
51743
  for (const [k, v] of Object.entries(body)) {
51702
51744
  out[k] = resolveLambdaBindings(v, argName, arg);
@@ -51715,7 +51757,7 @@ function getSlotContentRenderer2() {
51715
51757
  function makeLambdaFn(argName, lambdaBody, callerKey) {
51716
51758
  return (item, index) => {
51717
51759
  const resolvedBody = resolveLambdaBindings(lambdaBody, argName, item);
51718
- if (resolvedBody === null || typeof resolvedBody !== "object" || Array.isArray(resolvedBody)) {
51760
+ if (resolvedBody === null || typeof resolvedBody !== "object" || Array.isArray(resolvedBody) || typeof resolvedBody === "function" || React127__namespace.default.isValidElement(resolvedBody) || resolvedBody instanceof Date) {
51719
51761
  return null;
51720
51762
  }
51721
51763
  const record = resolvedBody;
@@ -51723,12 +51765,14 @@ function makeLambdaFn(argName, lambdaBody, callerKey) {
51723
51765
  return null;
51724
51766
  }
51725
51767
  const SlotContentRenderer2 = getSlotContentRenderer2();
51768
+ const childProps = {};
51769
+ for (const [k, v] of Object.entries(record)) {
51770
+ if (k !== "type") childProps[k] = v;
51771
+ }
51726
51772
  const childContent = {
51727
51773
  id: `lambda-${callerKey}-${index}`,
51728
51774
  pattern: record.type,
51729
- props: Object.fromEntries(
51730
- Object.entries(record).filter(([k]) => k !== "type")
51731
- ),
51775
+ props: childProps,
51732
51776
  priority: 0
51733
51777
  };
51734
51778
  return React127__namespace.default.createElement(SlotContentRenderer2, { content: childContent });
@@ -51741,15 +51785,16 @@ function convertNode(node, callerKey) {
51741
51785
  const [, argName, body] = node;
51742
51786
  return makeLambdaFn(argName, body, callerKey);
51743
51787
  }
51788
+ const arr = node;
51744
51789
  let anyChanged = false;
51745
- const mapped = node.map((item, i) => {
51790
+ const mapped = arr.map((item, i) => {
51746
51791
  const next = convertNode(item, `${callerKey}[${i}]`);
51747
51792
  if (next !== item) anyChanged = true;
51748
51793
  return next;
51749
51794
  });
51750
51795
  return anyChanged ? mapped : node;
51751
51796
  }
51752
- if (typeof node === "object") {
51797
+ if (typeof node === "object" && !React127__namespace.default.isValidElement(node) && !(node instanceof Date)) {
51753
51798
  return convertObjectProps(node);
51754
51799
  }
51755
51800
  return node;
@@ -52773,6 +52818,7 @@ function prepareSchemaForPreview(input) {
52773
52818
  // runtime/OrbPreview.tsx
52774
52819
  init_logger();
52775
52820
  var xOrbitalLog2 = createLogger("almadar:runtime:cross-orbital");
52821
+ var navLog = createLogger("almadar:runtime:navigation");
52776
52822
  function normalizeChild(child) {
52777
52823
  if (typeof child === "string") return child;
52778
52824
  if (child === null || typeof child !== "object" || Array.isArray(child)) {
@@ -52848,6 +52894,19 @@ function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFa
52848
52894
  }, [bridge.connected, bridge.sendEvent, orbitalNames, uiSlots, onNavigate, embeddedTraits]);
52849
52895
  const opts = orbitalNames ? { onEventProcessed, navigate: onNavigate, traitConfigsByName, orbitalsByTrait, embeddedTraits } : { navigate: onNavigate, persistence, traitConfigsByName, orbitalsByTrait, embeddedTraits };
52850
52896
  const { sendEvent } = useTraitStateMachine(traits2, uiSlots, opts);
52897
+ const prevTraitNamesRef = React127.useRef("");
52898
+ React127.useEffect(() => {
52899
+ const traitNames = traits2.map((b) => b.trait?.name ?? "").filter(Boolean).sort().join(",");
52900
+ if (prevTraitNamesRef.current && prevTraitNamesRef.current !== traitNames) {
52901
+ navLog.info("page:trait-set-changed", {
52902
+ from: prevTraitNamesRef.current,
52903
+ to: traitNames,
52904
+ action: "clearAll-slots"
52905
+ });
52906
+ uiSlots.clearAll();
52907
+ }
52908
+ prevTraitNamesRef.current = traitNames;
52909
+ }, [traits2, uiSlots]);
52851
52910
  const initSentRef = React127.useRef(false);
52852
52911
  React127.useEffect(() => {
52853
52912
  if (!orbitalNames?.length) {
@@ -52862,6 +52921,10 @@ function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFa
52862
52921
  }, 5e3);
52863
52922
  return () => clearTimeout(fallback);
52864
52923
  }, [traits2, orbitalNames, sendEvent, onLocalFallback]);
52924
+ const orbitalsKey = (orbitalNames ?? []).slice().sort().join(",");
52925
+ React127.useEffect(() => {
52926
+ initSentRef.current = false;
52927
+ }, [orbitalsKey]);
52865
52928
  React127.useEffect(() => {
52866
52929
  if (!bridge.connected || !orbitalNames?.length || initSentRef.current) return;
52867
52930
  initSentRef.current = true;
@@ -53102,8 +53165,19 @@ function OrbPreview({
53102
53165
  }, [initialPageName, currentPage]);
53103
53166
  const handleNavigate = React127.useCallback((path) => {
53104
53167
  const match = pages.find(({ page }) => page.path === path);
53168
+ navLog.info("handleNavigate", {
53169
+ path,
53170
+ matched: match?.page.name ?? null,
53171
+ availablePaths: pages.map((p2) => p2.page.path)
53172
+ });
53105
53173
  if (match) {
53106
53174
  setCurrentPage(match.page.name);
53175
+ if (typeof window !== "undefined") {
53176
+ const url = new URL(window.location.href);
53177
+ url.searchParams.set("page", path);
53178
+ window.history.pushState({}, "", url.toString());
53179
+ window.dispatchEvent(new PopStateEvent("popstate"));
53180
+ }
53107
53181
  }
53108
53182
  }, [pages]);
53109
53183
  if (!parseResult.ok) {
@@ -53115,18 +53189,30 @@ function OrbPreview({
53115
53189
  const containerRef = React127.useRef(null);
53116
53190
  React127.useEffect(() => {
53117
53191
  const el = containerRef.current;
53118
- if (!el || pages.length <= 1) return;
53192
+ if (!el) return;
53193
+ if (pages.length <= 1) {
53194
+ navLog.info("interceptor:skipped", { reason: "single-page schema", pageCount: pages.length });
53195
+ return;
53196
+ }
53119
53197
  const handler = (e) => {
53120
53198
  const anchor = e.target.closest("a");
53121
53199
  if (!anchor) return;
53122
53200
  const href = anchor.getAttribute("href") ?? anchor.getAttribute("to") ?? "";
53123
- if (!href || href.startsWith("http") || href.startsWith("mailto:") || href.startsWith("#")) return;
53201
+ navLog.info("click:intercepted", {
53202
+ href,
53203
+ anchorText: anchor.textContent?.trim().slice(0, 40)
53204
+ });
53205
+ if (!href || href.startsWith("http") || href.startsWith("mailto:") || href.startsWith("#")) {
53206
+ navLog.info("click:skipped", { href, reason: "external/empty/hash" });
53207
+ return;
53208
+ }
53124
53209
  e.preventDefault();
53125
53210
  e.stopPropagation();
53126
53211
  e.stopImmediatePropagation();
53127
53212
  handleNavigate(href);
53128
53213
  };
53129
53214
  el.addEventListener("click", handler, true);
53215
+ navLog.info("interceptor:installed", { pageCount: pages.length, paths: pages.map((p2) => p2.page.path) });
53130
53216
  return () => el.removeEventListener("click", handler, true);
53131
53217
  }, [pages, handleNavigate]);
53132
53218
  return /* @__PURE__ */ jsxRuntime.jsxs(
package/dist/avl/index.js CHANGED
@@ -46977,7 +46977,8 @@ function renderPatternChildren(children, onDismiss, parentId = "root", parentPat
46977
46977
  if (!child || typeof child !== "object") return null;
46978
46978
  const childId = `${parentId}-${index}`;
46979
46979
  const childPath = parentPath === "root" ? `root.children.${index}` : `${parentPath}.children.${index}`;
46980
- const { type: _childType, props: nestedProps, _id: _childNodeId, children: _childChildren, ...flatProps } = child;
46980
+ const childAsRecord = child;
46981
+ const { type: _childType, props: nestedProps, _id: _childNodeId, children: _childChildren, ...flatProps } = childAsRecord;
46981
46982
  const resolvedProps = nestedProps !== void 0 ? nestedProps : flatProps;
46982
46983
  if (_childChildren !== void 0 && nestedProps === void 0) {
46983
46984
  resolvedProps.children = _childChildren;
@@ -47005,7 +47006,46 @@ function renderPatternChildren(children, onDismiss, parentId = "root", parentPat
47005
47006
  });
47006
47007
  }
47007
47008
  function isPatternConfig(value) {
47008
- return value !== null && typeof value === "object" && !Array.isArray(value) && "type" in value && typeof value.type === "string";
47009
+ if (value === null || value === void 0) return false;
47010
+ if (typeof value !== "object") return false;
47011
+ if (Array.isArray(value)) return false;
47012
+ if (React127__default.isValidElement(value)) return false;
47013
+ if (value instanceof Date) return false;
47014
+ if (typeof value === "function") return false;
47015
+ const record = value;
47016
+ return "type" in record && typeof record.type === "string";
47017
+ }
47018
+ function isPlainConfigObject(value) {
47019
+ if (React127__default.isValidElement(value)) return false;
47020
+ if (value instanceof Date) return false;
47021
+ const proto = Object.getPrototypeOf(value);
47022
+ return proto === Object.prototype || proto === null;
47023
+ }
47024
+ function substituteTraitRefsDeep(value, pathKey) {
47025
+ if (typeof value === "string") {
47026
+ const match = TRAIT_BINDING_RE.exec(value);
47027
+ if (match) {
47028
+ const traitName = match[1];
47029
+ return /* @__PURE__ */ jsx(TraitFrame, { traitName }, `${pathKey}:${traitName}`);
47030
+ }
47031
+ return value;
47032
+ }
47033
+ if (typeof value === "number" || typeof value === "boolean" || value === null || value === void 0 || typeof value === "function") {
47034
+ return value;
47035
+ }
47036
+ if (Array.isArray(value)) {
47037
+ return value.map(
47038
+ (item, i) => substituteTraitRefsDeep(item, `${pathKey}[${i}]`)
47039
+ );
47040
+ }
47041
+ if (typeof value === "object" && isPlainConfigObject(value)) {
47042
+ const out = {};
47043
+ for (const [k, v] of Object.entries(value)) {
47044
+ out[k] = substituteTraitRefsDeep(v, `${pathKey}.${k}`);
47045
+ }
47046
+ return out;
47047
+ }
47048
+ return value;
47009
47049
  }
47010
47050
  function renderPatternProps(props, onDismiss) {
47011
47051
  const rendered = {};
@@ -47013,17 +47053,19 @@ function renderPatternProps(props, onDismiss) {
47013
47053
  if (key === "children") {
47014
47054
  rendered[key] = value;
47015
47055
  } else if (isPatternConfig(value)) {
47056
+ const nestedProps = {};
47057
+ for (const [k, v] of Object.entries(value)) {
47058
+ if (k !== "type") nestedProps[k] = v;
47059
+ }
47016
47060
  const childContent = {
47017
47061
  id: `prop-${key}`,
47018
47062
  pattern: value.type,
47019
- props: Object.fromEntries(
47020
- Object.entries(value).filter(([k]) => k !== "type")
47021
- ),
47063
+ props: nestedProps,
47022
47064
  priority: 0
47023
47065
  };
47024
47066
  rendered[key] = /* @__PURE__ */ jsx(SlotContentRenderer, { content: childContent, onDismiss });
47025
47067
  } else {
47026
- rendered[key] = value;
47068
+ rendered[key] = substituteTraitRefsDeep(value, `prop:${key}`);
47027
47069
  }
47028
47070
  }
47029
47071
  return rendered;
@@ -51634,7 +51676,7 @@ function resolveLambdaBindings(body, argName, arg) {
51634
51676
  let cur = arg;
51635
51677
  for (const seg of path.split(".")) {
51636
51678
  if (cur === null || cur === void 0) return void 0;
51637
- if (typeof cur !== "object") return void 0;
51679
+ if (typeof cur !== "object" || Array.isArray(cur)) return void 0;
51638
51680
  cur = cur[seg];
51639
51681
  }
51640
51682
  return cur;
@@ -51650,7 +51692,7 @@ function resolveLambdaBindings(body, argName, arg) {
51650
51692
  if (Array.isArray(body)) {
51651
51693
  return body.map((b) => resolveLambdaBindings(b, argName, arg));
51652
51694
  }
51653
- if (body !== null && typeof body === "object") {
51695
+ if (body !== null && typeof body === "object" && !React127__default.isValidElement(body) && !(body instanceof Date) && typeof body !== "function") {
51654
51696
  const out = {};
51655
51697
  for (const [k, v] of Object.entries(body)) {
51656
51698
  out[k] = resolveLambdaBindings(v, argName, arg);
@@ -51669,7 +51711,7 @@ function getSlotContentRenderer2() {
51669
51711
  function makeLambdaFn(argName, lambdaBody, callerKey) {
51670
51712
  return (item, index) => {
51671
51713
  const resolvedBody = resolveLambdaBindings(lambdaBody, argName, item);
51672
- if (resolvedBody === null || typeof resolvedBody !== "object" || Array.isArray(resolvedBody)) {
51714
+ if (resolvedBody === null || typeof resolvedBody !== "object" || Array.isArray(resolvedBody) || typeof resolvedBody === "function" || React127__default.isValidElement(resolvedBody) || resolvedBody instanceof Date) {
51673
51715
  return null;
51674
51716
  }
51675
51717
  const record = resolvedBody;
@@ -51677,12 +51719,14 @@ function makeLambdaFn(argName, lambdaBody, callerKey) {
51677
51719
  return null;
51678
51720
  }
51679
51721
  const SlotContentRenderer2 = getSlotContentRenderer2();
51722
+ const childProps = {};
51723
+ for (const [k, v] of Object.entries(record)) {
51724
+ if (k !== "type") childProps[k] = v;
51725
+ }
51680
51726
  const childContent = {
51681
51727
  id: `lambda-${callerKey}-${index}`,
51682
51728
  pattern: record.type,
51683
- props: Object.fromEntries(
51684
- Object.entries(record).filter(([k]) => k !== "type")
51685
- ),
51729
+ props: childProps,
51686
51730
  priority: 0
51687
51731
  };
51688
51732
  return React127__default.createElement(SlotContentRenderer2, { content: childContent });
@@ -51695,15 +51739,16 @@ function convertNode(node, callerKey) {
51695
51739
  const [, argName, body] = node;
51696
51740
  return makeLambdaFn(argName, body, callerKey);
51697
51741
  }
51742
+ const arr = node;
51698
51743
  let anyChanged = false;
51699
- const mapped = node.map((item, i) => {
51744
+ const mapped = arr.map((item, i) => {
51700
51745
  const next = convertNode(item, `${callerKey}[${i}]`);
51701
51746
  if (next !== item) anyChanged = true;
51702
51747
  return next;
51703
51748
  });
51704
51749
  return anyChanged ? mapped : node;
51705
51750
  }
51706
- if (typeof node === "object") {
51751
+ if (typeof node === "object" && !React127__default.isValidElement(node) && !(node instanceof Date)) {
51707
51752
  return convertObjectProps(node);
51708
51753
  }
51709
51754
  return node;
@@ -52727,6 +52772,7 @@ function prepareSchemaForPreview(input) {
52727
52772
  // runtime/OrbPreview.tsx
52728
52773
  init_logger();
52729
52774
  var xOrbitalLog2 = createLogger("almadar:runtime:cross-orbital");
52775
+ var navLog = createLogger("almadar:runtime:navigation");
52730
52776
  function normalizeChild(child) {
52731
52777
  if (typeof child === "string") return child;
52732
52778
  if (child === null || typeof child !== "object" || Array.isArray(child)) {
@@ -52802,6 +52848,19 @@ function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFa
52802
52848
  }, [bridge.connected, bridge.sendEvent, orbitalNames, uiSlots, onNavigate, embeddedTraits]);
52803
52849
  const opts = orbitalNames ? { onEventProcessed, navigate: onNavigate, traitConfigsByName, orbitalsByTrait, embeddedTraits } : { navigate: onNavigate, persistence, traitConfigsByName, orbitalsByTrait, embeddedTraits };
52804
52850
  const { sendEvent } = useTraitStateMachine(traits2, uiSlots, opts);
52851
+ const prevTraitNamesRef = useRef("");
52852
+ useEffect(() => {
52853
+ const traitNames = traits2.map((b) => b.trait?.name ?? "").filter(Boolean).sort().join(",");
52854
+ if (prevTraitNamesRef.current && prevTraitNamesRef.current !== traitNames) {
52855
+ navLog.info("page:trait-set-changed", {
52856
+ from: prevTraitNamesRef.current,
52857
+ to: traitNames,
52858
+ action: "clearAll-slots"
52859
+ });
52860
+ uiSlots.clearAll();
52861
+ }
52862
+ prevTraitNamesRef.current = traitNames;
52863
+ }, [traits2, uiSlots]);
52805
52864
  const initSentRef = useRef(false);
52806
52865
  useEffect(() => {
52807
52866
  if (!orbitalNames?.length) {
@@ -52816,6 +52875,10 @@ function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFa
52816
52875
  }, 5e3);
52817
52876
  return () => clearTimeout(fallback);
52818
52877
  }, [traits2, orbitalNames, sendEvent, onLocalFallback]);
52878
+ const orbitalsKey = (orbitalNames ?? []).slice().sort().join(",");
52879
+ useEffect(() => {
52880
+ initSentRef.current = false;
52881
+ }, [orbitalsKey]);
52819
52882
  useEffect(() => {
52820
52883
  if (!bridge.connected || !orbitalNames?.length || initSentRef.current) return;
52821
52884
  initSentRef.current = true;
@@ -53056,8 +53119,19 @@ function OrbPreview({
53056
53119
  }, [initialPageName, currentPage]);
53057
53120
  const handleNavigate = useCallback((path) => {
53058
53121
  const match = pages.find(({ page }) => page.path === path);
53122
+ navLog.info("handleNavigate", {
53123
+ path,
53124
+ matched: match?.page.name ?? null,
53125
+ availablePaths: pages.map((p2) => p2.page.path)
53126
+ });
53059
53127
  if (match) {
53060
53128
  setCurrentPage(match.page.name);
53129
+ if (typeof window !== "undefined") {
53130
+ const url = new URL(window.location.href);
53131
+ url.searchParams.set("page", path);
53132
+ window.history.pushState({}, "", url.toString());
53133
+ window.dispatchEvent(new PopStateEvent("popstate"));
53134
+ }
53061
53135
  }
53062
53136
  }, [pages]);
53063
53137
  if (!parseResult.ok) {
@@ -53069,18 +53143,30 @@ function OrbPreview({
53069
53143
  const containerRef = useRef(null);
53070
53144
  useEffect(() => {
53071
53145
  const el = containerRef.current;
53072
- if (!el || pages.length <= 1) return;
53146
+ if (!el) return;
53147
+ if (pages.length <= 1) {
53148
+ navLog.info("interceptor:skipped", { reason: "single-page schema", pageCount: pages.length });
53149
+ return;
53150
+ }
53073
53151
  const handler = (e) => {
53074
53152
  const anchor = e.target.closest("a");
53075
53153
  if (!anchor) return;
53076
53154
  const href = anchor.getAttribute("href") ?? anchor.getAttribute("to") ?? "";
53077
- if (!href || href.startsWith("http") || href.startsWith("mailto:") || href.startsWith("#")) return;
53155
+ navLog.info("click:intercepted", {
53156
+ href,
53157
+ anchorText: anchor.textContent?.trim().slice(0, 40)
53158
+ });
53159
+ if (!href || href.startsWith("http") || href.startsWith("mailto:") || href.startsWith("#")) {
53160
+ navLog.info("click:skipped", { href, reason: "external/empty/hash" });
53161
+ return;
53162
+ }
53078
53163
  e.preventDefault();
53079
53164
  e.stopPropagation();
53080
53165
  e.stopImmediatePropagation();
53081
53166
  handleNavigate(href);
53082
53167
  };
53083
53168
  el.addEventListener("click", handler, true);
53169
+ navLog.info("interceptor:installed", { pageCount: pages.length, paths: pages.map((p2) => p2.page.path) });
53084
53170
  return () => el.removeEventListener("click", handler, true);
53085
53171
  }, [pages, handleNavigate]);
53086
53172
  return /* @__PURE__ */ jsxs(
@@ -37769,7 +37769,8 @@ function renderPatternChildren(children, onDismiss, parentId = "root", parentPat
37769
37769
  if (!child || typeof child !== "object") return null;
37770
37770
  const childId = `${parentId}-${index}`;
37771
37771
  const childPath = parentPath === "root" ? `root.children.${index}` : `${parentPath}.children.${index}`;
37772
- const { type: _childType, props: nestedProps, _id: _childNodeId, children: _childChildren, ...flatProps } = child;
37772
+ const childAsRecord = child;
37773
+ const { type: _childType, props: nestedProps, _id: _childNodeId, children: _childChildren, ...flatProps } = childAsRecord;
37773
37774
  const resolvedProps = nestedProps !== void 0 ? nestedProps : flatProps;
37774
37775
  if (_childChildren !== void 0 && nestedProps === void 0) {
37775
37776
  resolvedProps.children = _childChildren;
@@ -37797,7 +37798,46 @@ function renderPatternChildren(children, onDismiss, parentId = "root", parentPat
37797
37798
  });
37798
37799
  }
37799
37800
  function isPatternConfig(value) {
37800
- return value !== null && typeof value === "object" && !Array.isArray(value) && "type" in value && typeof value.type === "string";
37801
+ if (value === null || value === void 0) return false;
37802
+ if (typeof value !== "object") return false;
37803
+ if (Array.isArray(value)) return false;
37804
+ if (React110__namespace.default.isValidElement(value)) return false;
37805
+ if (value instanceof Date) return false;
37806
+ if (typeof value === "function") return false;
37807
+ const record = value;
37808
+ return "type" in record && typeof record.type === "string";
37809
+ }
37810
+ function isPlainConfigObject(value) {
37811
+ if (React110__namespace.default.isValidElement(value)) return false;
37812
+ if (value instanceof Date) return false;
37813
+ const proto = Object.getPrototypeOf(value);
37814
+ return proto === Object.prototype || proto === null;
37815
+ }
37816
+ function substituteTraitRefsDeep(value, pathKey) {
37817
+ if (typeof value === "string") {
37818
+ const match = TRAIT_BINDING_RE.exec(value);
37819
+ if (match) {
37820
+ const traitName = match[1];
37821
+ return /* @__PURE__ */ jsxRuntime.jsx(TraitFrame, { traitName }, `${pathKey}:${traitName}`);
37822
+ }
37823
+ return value;
37824
+ }
37825
+ if (typeof value === "number" || typeof value === "boolean" || value === null || value === void 0 || typeof value === "function") {
37826
+ return value;
37827
+ }
37828
+ if (Array.isArray(value)) {
37829
+ return value.map(
37830
+ (item, i) => substituteTraitRefsDeep(item, `${pathKey}[${i}]`)
37831
+ );
37832
+ }
37833
+ if (typeof value === "object" && isPlainConfigObject(value)) {
37834
+ const out = {};
37835
+ for (const [k, v] of Object.entries(value)) {
37836
+ out[k] = substituteTraitRefsDeep(v, `${pathKey}.${k}`);
37837
+ }
37838
+ return out;
37839
+ }
37840
+ return value;
37801
37841
  }
37802
37842
  function renderPatternProps(props, onDismiss) {
37803
37843
  const rendered = {};
@@ -37805,17 +37845,19 @@ function renderPatternProps(props, onDismiss) {
37805
37845
  if (key === "children") {
37806
37846
  rendered[key] = value;
37807
37847
  } else if (isPatternConfig(value)) {
37848
+ const nestedProps = {};
37849
+ for (const [k, v] of Object.entries(value)) {
37850
+ if (k !== "type") nestedProps[k] = v;
37851
+ }
37808
37852
  const childContent = {
37809
37853
  id: `prop-${key}`,
37810
37854
  pattern: value.type,
37811
- props: Object.fromEntries(
37812
- Object.entries(value).filter(([k]) => k !== "type")
37813
- ),
37855
+ props: nestedProps,
37814
37856
  priority: 0
37815
37857
  };
37816
37858
  rendered[key] = /* @__PURE__ */ jsxRuntime.jsx(SlotContentRenderer, { content: childContent, onDismiss });
37817
37859
  } else {
37818
- rendered[key] = value;
37860
+ rendered[key] = substituteTraitRefsDeep(value, `prop:${key}`);
37819
37861
  }
37820
37862
  }
37821
37863
  return rendered;
@@ -37724,7 +37724,8 @@ function renderPatternChildren(children, onDismiss, parentId = "root", parentPat
37724
37724
  if (!child || typeof child !== "object") return null;
37725
37725
  const childId = `${parentId}-${index}`;
37726
37726
  const childPath = parentPath === "root" ? `root.children.${index}` : `${parentPath}.children.${index}`;
37727
- const { type: _childType, props: nestedProps, _id: _childNodeId, children: _childChildren, ...flatProps } = child;
37727
+ const childAsRecord = child;
37728
+ const { type: _childType, props: nestedProps, _id: _childNodeId, children: _childChildren, ...flatProps } = childAsRecord;
37728
37729
  const resolvedProps = nestedProps !== void 0 ? nestedProps : flatProps;
37729
37730
  if (_childChildren !== void 0 && nestedProps === void 0) {
37730
37731
  resolvedProps.children = _childChildren;
@@ -37752,7 +37753,46 @@ function renderPatternChildren(children, onDismiss, parentId = "root", parentPat
37752
37753
  });
37753
37754
  }
37754
37755
  function isPatternConfig(value) {
37755
- return value !== null && typeof value === "object" && !Array.isArray(value) && "type" in value && typeof value.type === "string";
37756
+ if (value === null || value === void 0) return false;
37757
+ if (typeof value !== "object") return false;
37758
+ if (Array.isArray(value)) return false;
37759
+ if (React110__default.isValidElement(value)) return false;
37760
+ if (value instanceof Date) return false;
37761
+ if (typeof value === "function") return false;
37762
+ const record = value;
37763
+ return "type" in record && typeof record.type === "string";
37764
+ }
37765
+ function isPlainConfigObject(value) {
37766
+ if (React110__default.isValidElement(value)) return false;
37767
+ if (value instanceof Date) return false;
37768
+ const proto = Object.getPrototypeOf(value);
37769
+ return proto === Object.prototype || proto === null;
37770
+ }
37771
+ function substituteTraitRefsDeep(value, pathKey) {
37772
+ if (typeof value === "string") {
37773
+ const match = TRAIT_BINDING_RE.exec(value);
37774
+ if (match) {
37775
+ const traitName = match[1];
37776
+ return /* @__PURE__ */ jsx(TraitFrame, { traitName }, `${pathKey}:${traitName}`);
37777
+ }
37778
+ return value;
37779
+ }
37780
+ if (typeof value === "number" || typeof value === "boolean" || value === null || value === void 0 || typeof value === "function") {
37781
+ return value;
37782
+ }
37783
+ if (Array.isArray(value)) {
37784
+ return value.map(
37785
+ (item, i) => substituteTraitRefsDeep(item, `${pathKey}[${i}]`)
37786
+ );
37787
+ }
37788
+ if (typeof value === "object" && isPlainConfigObject(value)) {
37789
+ const out = {};
37790
+ for (const [k, v] of Object.entries(value)) {
37791
+ out[k] = substituteTraitRefsDeep(v, `${pathKey}.${k}`);
37792
+ }
37793
+ return out;
37794
+ }
37795
+ return value;
37756
37796
  }
37757
37797
  function renderPatternProps(props, onDismiss) {
37758
37798
  const rendered = {};
@@ -37760,17 +37800,19 @@ function renderPatternProps(props, onDismiss) {
37760
37800
  if (key === "children") {
37761
37801
  rendered[key] = value;
37762
37802
  } else if (isPatternConfig(value)) {
37803
+ const nestedProps = {};
37804
+ for (const [k, v] of Object.entries(value)) {
37805
+ if (k !== "type") nestedProps[k] = v;
37806
+ }
37763
37807
  const childContent = {
37764
37808
  id: `prop-${key}`,
37765
37809
  pattern: value.type,
37766
- props: Object.fromEntries(
37767
- Object.entries(value).filter(([k]) => k !== "type")
37768
- ),
37810
+ props: nestedProps,
37769
37811
  priority: 0
37770
37812
  };
37771
37813
  rendered[key] = /* @__PURE__ */ jsx(SlotContentRenderer, { content: childContent, onDismiss });
37772
37814
  } else {
37773
- rendered[key] = value;
37815
+ rendered[key] = substituteTraitRefsDeep(value, `prop:${key}`);
37774
37816
  }
37775
37817
  }
37776
37818
  return rendered;
@@ -19,7 +19,7 @@
19
19
  * @packageDocumentation
20
20
  */
21
21
  import React from 'react';
22
- import { type UISlotManager, type UISlot, type SlotContent, type RenderUIConfig, type SlotAnimation, type SlotChangeCallback } from '../hooks/useUISlots';
22
+ import { type UISlotManager, type UISlot, type SlotContent, type SlotProps, type SlotPropValue, type SlotCallback, type RenderUIConfig, type SlotAnimation, type SlotChangeCallback } from '../hooks/useUISlots';
23
23
  /**
24
24
  * Context for the UI Slot Manager
25
25
  */
@@ -72,4 +72,4 @@ export declare function useSlotContent(slot: UISlot): SlotContent | null;
72
72
  * Hook to check if a slot has content.
73
73
  */
74
74
  export declare function useSlotHasContent(slot: UISlot): boolean;
75
- export { UISlotContext, type UISlotManager, type UISlot, type SlotContent, type RenderUIConfig, type SlotAnimation, type SlotChangeCallback, };
75
+ export { UISlotContext, type UISlotManager, type UISlot, type SlotContent, type SlotProps, type SlotPropValue, type SlotCallback, type RenderUIConfig, type SlotAnimation, type SlotChangeCallback, };