@almadar/ui 4.6.14 → 4.8.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.
package/dist/avl/index.js CHANGED
@@ -5328,13 +5328,23 @@ function SlotsProvider({ children }) {
5328
5328
  const setSlotPatterns = useCallback((slot, patterns, source) => {
5329
5329
  const sourceKey = source?.trait ?? DEFAULT_SOURCE_KEY2;
5330
5330
  const entityProp = patterns[0]?.pattern && typeof patterns[0].pattern === "object" ? patterns[0].pattern.entity : void 0;
5331
+ const firstPatternType = patterns[0]?.pattern && typeof patterns[0].pattern === "object" ? patterns[0].pattern.type : void 0;
5331
5332
  slotLog.debug("setSlotPatterns", {
5332
5333
  slot,
5333
5334
  sourceKey,
5334
5335
  patternCount: patterns.length,
5335
- firstPatternType: patterns[0]?.pattern && typeof patterns[0].pattern === "object" ? patterns[0].pattern.type : void 0,
5336
+ firstPatternType,
5336
5337
  entityRefId: refId(entityProp)
5337
5338
  });
5339
+ if (source?.trait) {
5340
+ xOrbitalLog.info("slot-set", {
5341
+ slot,
5342
+ sourceTrait: source.trait,
5343
+ patternCount: patterns.length,
5344
+ firstPatternType,
5345
+ state: source.state
5346
+ });
5347
+ }
5338
5348
  setSlots((prev) => {
5339
5349
  const prevSlot = prev[slot] ?? {};
5340
5350
  return {
@@ -5356,6 +5366,7 @@ function SlotsProvider({ children }) {
5356
5366
  });
5357
5367
  }, []);
5358
5368
  const clearSlotForSource = useCallback((slot, sourceTrait) => {
5369
+ xOrbitalLog.info("slot-clear-source", { slot, sourceTrait });
5359
5370
  setSlots((prev) => {
5360
5371
  const existing = prev[slot];
5361
5372
  if (!existing || !(sourceTrait in existing)) return prev;
@@ -5392,11 +5403,12 @@ function useSlotsActions() {
5392
5403
  }
5393
5404
  return actions;
5394
5405
  }
5395
- var slotLog, refIds, nextRefId, DEFAULT_SOURCE_KEY2, SlotsStateContext, SlotsActionsContext;
5406
+ var slotLog, xOrbitalLog, refIds, nextRefId, DEFAULT_SOURCE_KEY2, SlotsStateContext, SlotsActionsContext;
5396
5407
  var init_SlotsContext = __esm({
5397
5408
  "runtime/ui/SlotsContext.tsx"() {
5398
5409
  init_logger();
5399
5410
  slotLog = createLogger("almadar:ui:slot-render");
5411
+ xOrbitalLog = createLogger("almadar:runtime:cross-orbital");
5400
5412
  refIds = /* @__PURE__ */ new WeakMap();
5401
5413
  nextRefId = 1;
5402
5414
  DEFAULT_SOURCE_KEY2 = "__default__";
@@ -11132,7 +11144,7 @@ var init_MapView = __esm({
11132
11144
  shadowSize: [41, 41]
11133
11145
  });
11134
11146
  L.Marker.prototype.options.icon = defaultIcon;
11135
- const { useEffect: useEffect87, useRef: useRef87, useCallback: useCallback125, useState: useState125 } = React127__default;
11147
+ const { useEffect: useEffect87, useRef: useRef87, useCallback: useCallback125, useState: useState124 } = React127__default;
11136
11148
  const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
11137
11149
  const { useEventBus: useEventBus3 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
11138
11150
  function MapUpdater({ centerLat, centerLng, zoom }) {
@@ -11176,7 +11188,7 @@ var init_MapView = __esm({
11176
11188
  showAttribution = true
11177
11189
  }) {
11178
11190
  const eventBus = useEventBus3();
11179
- const [clickedPosition, setClickedPosition] = useState125(null);
11191
+ const [clickedPosition, setClickedPosition] = useState124(null);
11180
11192
  const handleMapClick = useCallback125((lat, lng) => {
11181
11193
  if (showClickedPin) {
11182
11194
  setClickedPosition({ lat, lng });
@@ -12277,9 +12289,9 @@ function bindEventBus(eventBus) {
12277
12289
  log2.info("bindEventBus", { hasOnAny: !!eventBus.onAny });
12278
12290
  exposeOnWindow();
12279
12291
  if (window.__orbitalVerification) {
12280
- window.__orbitalVerification.sendEvent = (event, payload) => {
12281
- const prefixed = event.startsWith("UI:") ? event : `UI:${event}`;
12282
- log2.debug("sendEvent", { event: prefixed, payloadKeys: payload ? Object.keys(payload) : [] });
12292
+ window.__orbitalVerification.sendEvent = (event, payload, traitScope) => {
12293
+ const prefixed = event.startsWith("UI:") ? event : traitScope ? `UI:${traitScope}.${event}` : `UI:${event}`;
12294
+ log2.debug("sendEvent", { event: prefixed, traitScope, payloadKeys: payload ? Object.keys(payload) : [] });
12283
12295
  eventBus.emit(prefixed, payload);
12284
12296
  };
12285
12297
  const eventLog = [];
@@ -21884,8 +21896,7 @@ function formatValue(value, format) {
21884
21896
  }
21885
21897
  function DataGrid({
21886
21898
  entity,
21887
- fields: fieldsProp,
21888
- columns: columnsProp,
21899
+ fields,
21889
21900
  itemActions,
21890
21901
  cols,
21891
21902
  gap = "md",
@@ -21906,7 +21917,6 @@ function DataGrid({
21906
21917
  const { t } = useTranslate();
21907
21918
  const [selectedIds, setSelectedIds] = useState(/* @__PURE__ */ new Set());
21908
21919
  const [visibleCount, setVisibleCount] = useState(pageSize || Infinity);
21909
- const fields = fieldsProp ?? columnsProp ?? [];
21910
21920
  const allData = Array.isArray(entity) ? entity : entity ? [entity] : [];
21911
21921
  const data = pageSize > 0 ? allData.slice(0, visibleCount) : allData;
21912
21922
  const hasMoreLocal = pageSize > 0 && visibleCount < allData.length;
@@ -22249,8 +22259,7 @@ function groupData(items, field) {
22249
22259
  }
22250
22260
  function DataList({
22251
22261
  entity,
22252
- fields: fieldsProp,
22253
- columns: columnsProp,
22262
+ fields,
22254
22263
  itemActions,
22255
22264
  gap = "none",
22256
22265
  variant = "default",
@@ -22279,7 +22288,6 @@ function DataList({
22279
22288
  const eventBus = useEventBus();
22280
22289
  const { t } = useTranslate();
22281
22290
  const [visibleCount, setVisibleCount] = React127__default.useState(pageSize || Infinity);
22282
- const fields = fieldsProp ?? columnsProp ?? [];
22283
22291
  const allData = Array.isArray(entity) ? entity : entity ? [entity] : [];
22284
22292
  const data = pageSize > 0 ? allData.slice(0, visibleCount) : allData;
22285
22293
  const hasMoreLocal = pageSize > 0 && visibleCount < allData.length;
@@ -51454,6 +51462,7 @@ function useTraitStateMachine(traitBindings, slotsActions, options) {
51454
51462
  const eventBus = useEventBus();
51455
51463
  const { entities } = useEntitySchema();
51456
51464
  const traitConfigsByName = options?.traitConfigsByName;
51465
+ const orbitalsByTrait = options?.orbitalsByTrait;
51457
51466
  const manager = useMemo(() => {
51458
51467
  const traitDefs = traitBindings.map(toTraitDefinition);
51459
51468
  const m = new StateMachineManager(traitDefs);
@@ -51902,7 +51911,10 @@ function useTraitStateMachine(traitBindings, slotsActions, options) {
51902
51911
  if (!LIFECYCLE_EVENTS.has(normalizedEvent)) {
51903
51912
  for (const { traitName, result } of results) {
51904
51913
  if (!result.executed) continue;
51905
- eventBus.emit(normalizedEvent, payload, {
51914
+ const orbitalName = orbitalsByTrait?.[traitName];
51915
+ if (!orbitalName) continue;
51916
+ eventBus.emit(`UI:${orbitalName}.${traitName}.${normalizedEvent}`, payload, {
51917
+ orbital: orbitalName,
51906
51918
  trait: traitName,
51907
51919
  fromBridge: true
51908
51920
  });
@@ -51913,7 +51925,13 @@ function useTraitStateMachine(traitBindings, slotsActions, options) {
51913
51925
  }
51914
51926
  const onEventProcessed = optionsRef.current?.onEventProcessed;
51915
51927
  if (onEventProcessed) {
51916
- await onEventProcessed(normalizedEvent, payload);
51928
+ const dispatchedOrbitals = /* @__PURE__ */ new Set();
51929
+ for (const { traitName, result } of results) {
51930
+ if (!result.executed) continue;
51931
+ const orbital = orbitalsByTrait?.[traitName];
51932
+ if (orbital) dispatchedOrbitals.add(orbital);
51933
+ }
51934
+ await onEventProcessed(normalizedEvent, payload, dispatchedOrbitals);
51917
51935
  }
51918
51936
  }, [entities, eventBus]);
51919
51937
  const drainEventQueue = useCallback(async () => {
@@ -51957,26 +51975,34 @@ function useTraitStateMachine(traitBindings, slotsActions, options) {
51957
51975
  }
51958
51976
  console.log("[TraitStateMachine] Subscribing to events:", Array.from(allEvents));
51959
51977
  const unsubscribes = [];
51960
- for (const eventKey of allEvents) {
51961
- if (eventKey === "INIT" || eventKey === "LOAD" || eventKey === "$MOUNT") {
51962
- continue;
51978
+ for (const binding of traitBindings) {
51979
+ const traitName = binding.trait.name;
51980
+ const orbitalName = orbitalsByTrait?.[traitName];
51981
+ if (!orbitalName) continue;
51982
+ for (const transition of binding.trait.transitions) {
51983
+ const eventKey = transition.event;
51984
+ if (eventKey === "INIT" || eventKey === "LOAD" || eventKey === "$MOUNT") {
51985
+ continue;
51986
+ }
51987
+ const unsub = eventBus.on(`UI:${orbitalName}.${traitName}.${eventKey}`, (event) => {
51988
+ if (event.source && event.source.fromBridge) {
51989
+ return;
51990
+ }
51991
+ enqueueAndDrain(eventKey, event.payload);
51992
+ });
51993
+ unsubscribes.push(unsub);
51963
51994
  }
51964
- const unsub = eventBus.on(`UI:${eventKey}`, (event) => {
51965
- console.log("[TraitStateMachine] Received event:", `UI:${eventKey}`, event);
51966
- enqueueAndDrain(eventKey, event.payload);
51967
- });
51968
- unsubscribes.push(unsub);
51969
51995
  }
51970
51996
  for (const binding of traitBindings) {
51997
+ const ownOrbital = orbitalsByTrait?.[binding.trait.name];
51971
51998
  const listens = binding.trait.listens ?? [];
51972
51999
  for (const listen of listens) {
51973
- const expectedTrait = listen.source?.trait;
51974
- const unsub = eventBus.on(listen.event, (event) => {
51975
- if (expectedTrait) {
51976
- const emitTrait = event.source?.trait;
51977
- if (emitTrait !== expectedTrait) return;
51978
- }
51979
- console.log("[TraitStateMachine] listens", binding.trait.name, listen.event, "\u2192", listen.triggers, "from", event.source?.trait);
52000
+ const sourceTrait = listen.source?.trait;
52001
+ if (!sourceTrait) continue;
52002
+ const sourceOrbital = listen.source?.orbital ?? ownOrbital;
52003
+ if (!sourceOrbital) continue;
52004
+ const busKey = `UI:${sourceOrbital}.${sourceTrait}.${listen.event}`;
52005
+ const unsub = eventBus.on(busKey, (event) => {
51980
52006
  enqueueAndDrain(listen.triggers, event.payload);
51981
52007
  });
51982
52008
  unsubscribes.push(unsub);
@@ -52002,6 +52028,8 @@ init_EntitySchemaContext();
52002
52028
 
52003
52029
  // runtime/ServerBridge.tsx
52004
52030
  init_useEventBus();
52031
+ init_logger();
52032
+ var xOrbitalLog2 = createLogger("almadar:runtime:cross-orbital");
52005
52033
  var ServerBridgeContext = createContext(null);
52006
52034
  function useServerBridge() {
52007
52035
  const ctx = useContext(ServerBridgeContext);
@@ -52079,8 +52107,22 @@ function ServerBridgeProvider({
52079
52107
  }
52080
52108
  if (result.emittedEvents) {
52081
52109
  for (const emitted of result.emittedEvents) {
52082
- eventBus.emit(`UI:${emitted.event}`, emitted.payload);
52083
- eventBus.emit(emitted.event, emitted.payload);
52110
+ const evTrait = emitted.source?.trait;
52111
+ if (!evTrait) {
52112
+ xOrbitalLog2.warn("emit:dropped-no-source", {
52113
+ event: emitted.event,
52114
+ dispatchOrbital: orbitalName
52115
+ });
52116
+ continue;
52117
+ }
52118
+ const key = emitted.source?.orbital ? `UI:${emitted.source.orbital}.${evTrait}.${emitted.event}` : `UI:${evTrait}.${emitted.event}`;
52119
+ xOrbitalLog2.info("emit:rebroadcast", {
52120
+ busKey: key,
52121
+ sourceOrbital: emitted.source?.orbital,
52122
+ sourceTrait: evTrait,
52123
+ dispatchOrbital: orbitalName
52124
+ });
52125
+ eventBus.emit(key, emitted.payload);
52084
52126
  }
52085
52127
  }
52086
52128
  } else if (result.error) {
@@ -52201,6 +52243,10 @@ function prepareSchemaForPreview(input) {
52201
52243
  const schema = adjustSchemaForMockData(parsed, mockData);
52202
52244
  return { schema, mockData };
52203
52245
  }
52246
+
52247
+ // runtime/OrbPreview.tsx
52248
+ init_logger();
52249
+ var xOrbitalLog3 = createLogger("almadar:runtime:cross-orbital");
52204
52250
  function normalizeChild(child) {
52205
52251
  if (typeof child === "string") return child;
52206
52252
  if (child === null || typeof child !== "object" || Array.isArray(child)) {
@@ -52280,6 +52326,11 @@ function applyServerEffects(effects, uiSlots, onNavigate) {
52280
52326
  const patternRecord = eff.pattern;
52281
52327
  const { type: patternType, children, ...inlineProps } = patternRecord;
52282
52328
  const normalizedChildren = Array.isArray(children) ? children.map((c) => normalizeChild(c)) : children;
52329
+ xOrbitalLog3.info("slot-write", {
52330
+ slot: eff.slot,
52331
+ sourceTrait: eff.traitName ?? "server",
52332
+ patternType: typeof patternType === "string" ? patternType : void 0
52333
+ });
52283
52334
  uiSlots.render({
52284
52335
  target: eff.slot,
52285
52336
  pattern: patternType,
@@ -52294,19 +52345,26 @@ function applyServerEffects(effects, uiSlots, onNavigate) {
52294
52345
  }
52295
52346
  }
52296
52347
  }
52297
- function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFallback, persistence, traitConfigsByName }) {
52348
+ function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFallback, persistence, traitConfigsByName, orbitalsByTrait }) {
52298
52349
  const slotsActions = useSlotsActions();
52299
52350
  const bridge = useServerBridge();
52300
52351
  const uiSlots = useUISlots();
52301
- const onEventProcessed = useCallback(async (event, payload) => {
52352
+ const onEventProcessed = useCallback(async (event, payload, dispatchedOrbitals) => {
52302
52353
  if (!bridge.connected || !orbitalNames?.length) return;
52303
- for (const name of orbitalNames) {
52354
+ const targets = dispatchedOrbitals && dispatchedOrbitals.size > 0 ? orbitalNames.filter((n) => dispatchedOrbitals.has(n)) : orbitalNames;
52355
+ xOrbitalLog3.info("TraitInitializer:fanout", {
52356
+ event,
52357
+ sentTo: targets,
52358
+ skipped: orbitalNames.filter((n) => !targets.includes(n)),
52359
+ dispatchedOrbitalsSize: dispatchedOrbitals?.size ?? 0
52360
+ });
52361
+ for (const name of targets) {
52304
52362
  const { effects, meta } = await bridge.sendEvent(name, event, payload);
52305
52363
  recordServerResponse(name, event, meta);
52306
52364
  applyServerEffects(effects, uiSlots, onNavigate);
52307
52365
  }
52308
52366
  }, [bridge.connected, bridge.sendEvent, orbitalNames, uiSlots, onNavigate]);
52309
- const opts = orbitalNames ? { onEventProcessed, navigate: onNavigate, traitConfigsByName } : { navigate: onNavigate, persistence, traitConfigsByName };
52367
+ const opts = orbitalNames ? { onEventProcessed, navigate: onNavigate, traitConfigsByName, orbitalsByTrait } : { navigate: onNavigate, persistence, traitConfigsByName, orbitalsByTrait };
52310
52368
  const { sendEvent } = useTraitStateMachine(traits2, slotsActions, opts);
52311
52369
  const initSentRef = useRef(false);
52312
52370
  useEffect(() => {
@@ -52356,27 +52414,68 @@ function SchemaRunner({ schema, serverUrl, mockData, pageName, onNavigate, onLoc
52356
52414
  const allPageTraits = useMemo(() => {
52357
52415
  if (pageName && traits2.length > 0) return traits2;
52358
52416
  if (!ir?.pages || ir.pages.size <= 1) return traits2;
52359
- const combined = [];
52417
+ const firstPage = ir.pages.values().next().value;
52418
+ if (!firstPage) return traits2;
52419
+ const firstPageTraits = [];
52360
52420
  const seen = /* @__PURE__ */ new Set();
52361
- for (const page of ir.pages.values()) {
52362
- for (const t of page.traits) {
52363
- const binding = t;
52364
- const traitObj = binding.trait;
52365
- const name = traitObj?.name ?? binding.name ?? "";
52366
- if (name && !seen.has(name)) {
52367
- seen.add(name);
52368
- combined.push(t);
52369
- }
52421
+ for (const binding of firstPage.traits) {
52422
+ const name = binding.trait.name;
52423
+ if (name && !seen.has(name)) {
52424
+ seen.add(name);
52425
+ firstPageTraits.push(binding);
52370
52426
  }
52371
52427
  }
52372
- return combined.length > 0 ? combined : traits2;
52428
+ return firstPageTraits.length > 0 ? firstPageTraits : traits2;
52373
52429
  }, [ir, traits2, pageName]);
52374
- const orbitalNames = useMemo(() => {
52430
+ useMemo(() => {
52375
52431
  const parsed = schema;
52376
52432
  const orbitals = parsed?.orbitals;
52377
52433
  if (!orbitals) return [];
52378
52434
  return orbitals.filter((o) => typeof o.name === "string").map((o) => o.name);
52379
52435
  }, [schema]);
52436
+ const orbitalsByTrait = useMemo(() => {
52437
+ const map = {};
52438
+ const parsed = schema;
52439
+ if (!parsed?.orbitals) return map;
52440
+ for (const orb of parsed.orbitals) {
52441
+ for (const traitRef of orb.traits) {
52442
+ let traitName;
52443
+ if (typeof traitRef === "string") {
52444
+ const parts = traitRef.split(".");
52445
+ traitName = parts[parts.length - 1];
52446
+ } else if ("ref" in traitRef && typeof traitRef.ref === "string") {
52447
+ const parts = traitRef.ref.split(".");
52448
+ traitName = traitRef.name ?? parts[parts.length - 1];
52449
+ } else if ("name" in traitRef && typeof traitRef.name === "string") {
52450
+ traitName = traitRef.name;
52451
+ }
52452
+ if (traitName) map[traitName] = orb.name;
52453
+ }
52454
+ }
52455
+ return map;
52456
+ }, [schema]);
52457
+ const pageOrbitalNames = useMemo(() => {
52458
+ const set = /* @__PURE__ */ new Set();
52459
+ for (const binding of allPageTraits) {
52460
+ const orb = orbitalsByTrait[binding.trait.name];
52461
+ if (orb) set.add(orb);
52462
+ }
52463
+ return Array.from(set);
52464
+ }, [allPageTraits, orbitalsByTrait]);
52465
+ useEffect(() => {
52466
+ const traitNames = allPageTraits.map((b) => b.trait.name);
52467
+ const orbitalsByTraitForPage = {};
52468
+ for (const name of traitNames) {
52469
+ const orb = orbitalsByTrait[name];
52470
+ if (orb) orbitalsByTraitForPage[name] = orb;
52471
+ }
52472
+ xOrbitalLog3.info("SchemaRunner:mount", {
52473
+ pageName,
52474
+ traitNames,
52475
+ orbitalsByTraitForPage,
52476
+ pageOrbitalNames: pageOrbitalNames.join(",")
52477
+ });
52478
+ }, [pageName, allPageTraits, orbitalsByTrait, pageOrbitalNames]);
52380
52479
  const traitConfigsByName = useMemo(() => {
52381
52480
  const map = {};
52382
52481
  const parsed = schema;
@@ -52417,8 +52516,9 @@ function SchemaRunner({ schema, serverUrl, mockData, pageName, onNavigate, onLoc
52417
52516
  TraitInitializer,
52418
52517
  {
52419
52518
  traits: allPageTraits,
52420
- orbitalNames: serverUrl ? orbitalNames : void 0,
52519
+ orbitalNames: serverUrl ? pageOrbitalNames : void 0,
52421
52520
  traitConfigsByName,
52521
+ orbitalsByTrait,
52422
52522
  onNavigate,
52423
52523
  onLocalFallback,
52424
52524
  persistence
@@ -52440,7 +52540,8 @@ function OrbPreview({
52440
52540
  autoMock = false,
52441
52541
  height = "400px",
52442
52542
  className,
52443
- serverUrl
52543
+ serverUrl,
52544
+ initialPagePath
52444
52545
  }) {
52445
52546
  const [localFallback, setLocalFallback] = useState(false);
52446
52547
  const eventBus = useEventBus();
@@ -52486,7 +52587,17 @@ function OrbPreview({
52486
52587
  return [];
52487
52588
  }
52488
52589
  }, [parsedSchema]);
52489
- const [currentPage, setCurrentPage] = useState(void 0);
52590
+ const initialPageName = useMemo(() => {
52591
+ if (!initialPagePath) return void 0;
52592
+ const match = pages.find(({ page }) => page.path === initialPagePath);
52593
+ return match?.page.name;
52594
+ }, [pages, initialPagePath]);
52595
+ const [currentPage, setCurrentPage] = useState(initialPageName);
52596
+ useEffect(() => {
52597
+ if (initialPageName && initialPageName !== currentPage) {
52598
+ setCurrentPage(initialPageName);
52599
+ }
52600
+ }, [initialPageName, currentPage]);
52490
52601
  const handleNavigate = useCallback((path) => {
52491
52602
  const match = pages.find(({ page }) => page.path === path);
52492
52603
  if (match) {
@@ -9,6 +9,8 @@ export interface CardProps extends React.HTMLAttributes<HTMLDivElement> {
9
9
  subtitle?: string;
10
10
  /** Shadow size override */
11
11
  shadow?: CardShadow;
12
+ /** Card content */
13
+ children?: React.ReactNode;
12
14
  }
13
15
  export declare const Card: React.ForwardRefExoticComponent<CardProps & React.RefAttributes<HTMLDivElement>>;
14
16
  export declare const CardHeader: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLDivElement> & React.RefAttributes<HTMLDivElement>>;
@@ -4897,6 +4897,7 @@ var init_SlotsContext = __esm({
4897
4897
  "runtime/ui/SlotsContext.tsx"() {
4898
4898
  init_logger();
4899
4899
  slotLog = createLogger("almadar:ui:slot-render");
4900
+ createLogger("almadar:runtime:cross-orbital");
4900
4901
  refIds = /* @__PURE__ */ new WeakMap();
4901
4902
  nextRefId = 1;
4902
4903
  React111.createContext({});
@@ -6311,7 +6312,7 @@ var init_MapView = __esm({
6311
6312
  shadowSize: [41, 41]
6312
6313
  });
6313
6314
  L.Marker.prototype.options.icon = defaultIcon;
6314
- const { useEffect: useEffect66, useRef: useRef65, useCallback: useCallback115, useState: useState100 } = React111__namespace.default;
6315
+ const { useEffect: useEffect66, useRef: useRef65, useCallback: useCallback115, useState: useState99 } = React111__namespace.default;
6315
6316
  const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
6316
6317
  const { useEventBus: useEventBus2 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
6317
6318
  function MapUpdater({ centerLat, centerLng, zoom }) {
@@ -6355,7 +6356,7 @@ var init_MapView = __esm({
6355
6356
  showAttribution = true
6356
6357
  }) {
6357
6358
  const eventBus = useEventBus2();
6358
- const [clickedPosition, setClickedPosition] = useState100(null);
6359
+ const [clickedPosition, setClickedPosition] = useState99(null);
6359
6360
  const handleMapClick = useCallback115((lat, lng) => {
6360
6361
  if (showClickedPin) {
6361
6362
  setClickedPosition({ lat, lng });
@@ -17334,8 +17335,7 @@ function formatValue(value, format) {
17334
17335
  }
17335
17336
  function DataGrid({
17336
17337
  entity,
17337
- fields: fieldsProp,
17338
- columns: columnsProp,
17338
+ fields,
17339
17339
  itemActions,
17340
17340
  cols,
17341
17341
  gap = "md",
@@ -17356,7 +17356,6 @@ function DataGrid({
17356
17356
  const { t } = useTranslate();
17357
17357
  const [selectedIds, setSelectedIds] = React111.useState(/* @__PURE__ */ new Set());
17358
17358
  const [visibleCount, setVisibleCount] = React111.useState(pageSize || Infinity);
17359
- const fields = fieldsProp ?? columnsProp ?? [];
17360
17359
  const allData = Array.isArray(entity) ? entity : entity ? [entity] : [];
17361
17360
  const data = pageSize > 0 ? allData.slice(0, visibleCount) : allData;
17362
17361
  const hasMoreLocal = pageSize > 0 && visibleCount < allData.length;
@@ -17699,8 +17698,7 @@ function groupData(items, field) {
17699
17698
  }
17700
17699
  function DataList({
17701
17700
  entity,
17702
- fields: fieldsProp,
17703
- columns: columnsProp,
17701
+ fields,
17704
17702
  itemActions,
17705
17703
  gap = "none",
17706
17704
  variant = "default",
@@ -17729,7 +17727,6 @@ function DataList({
17729
17727
  const eventBus = useEventBus();
17730
17728
  const { t } = useTranslate();
17731
17729
  const [visibleCount, setVisibleCount] = React111__namespace.default.useState(pageSize || Infinity);
17732
- const fields = fieldsProp ?? columnsProp ?? [];
17733
17730
  const allData = Array.isArray(entity) ? entity : entity ? [entity] : [];
17734
17731
  const data = pageSize > 0 ? allData.slice(0, visibleCount) : allData;
17735
17732
  const hasMoreLocal = pageSize > 0 && visibleCount < allData.length;
@@ -41123,87 +41120,58 @@ function useUISlotManager() {
41123
41120
  // hooks/useUIEvents.ts
41124
41121
  init_useEventBus();
41125
41122
  var UI_PREFIX = "UI:";
41126
- function useUIEvents(dispatch, validEvents, eventBusInstance) {
41123
+ function useUIEvents(dispatch, traitName, validEvents, eventBusInstance) {
41127
41124
  const defaultEventBus = useEventBus();
41128
41125
  const eventBus = eventBusInstance ?? defaultEventBus;
41129
- const validEventsKey = validEvents ? validEvents.slice().sort().join(",") : "";
41126
+ const validEventsKey = validEvents.slice().sort().join(",");
41130
41127
  const stableValidEvents = React111.useMemo(
41131
41128
  () => validEvents,
41132
41129
  [validEventsKey]
41133
- // intentional — validEventsKey is the stable dep, not validEvents array ref
41130
+ // intentional — validEventsKey is the stable dep
41134
41131
  );
41135
41132
  React111.useEffect(() => {
41136
41133
  const unsubscribes = [];
41137
- if (stableValidEvents) {
41138
- for (const smEvent of stableValidEvents) {
41139
- const prefixedHandler = (event) => {
41140
- dispatch(smEvent, event.payload);
41141
- };
41142
- unsubscribes.push(eventBus.on(`${UI_PREFIX}${smEvent}`, prefixedHandler));
41143
- const directHandler = (event) => {
41144
- if (event.source && event.source.fromBridge) {
41145
- return;
41146
- }
41147
- dispatch(smEvent, event.payload);
41148
- };
41149
- unsubscribes.push(eventBus.on(smEvent, directHandler));
41150
- }
41151
- }
41152
- const genericHandler = (event) => {
41153
- const eventName = event.payload?.event;
41154
- if (eventName) {
41155
- const smEvent = eventName;
41156
- if (!stableValidEvents || stableValidEvents.includes(smEvent)) {
41157
- dispatch(smEvent, event.payload);
41134
+ for (const smEvent of stableValidEvents) {
41135
+ const handler = (event) => {
41136
+ if (event.source && event.source.fromBridge) {
41137
+ return;
41158
41138
  }
41159
- }
41160
- };
41161
- unsubscribes.push(eventBus.on(`${UI_PREFIX}DISPATCH`, genericHandler));
41139
+ dispatch(smEvent, event.payload);
41140
+ };
41141
+ unsubscribes.push(
41142
+ eventBus.on(`${UI_PREFIX}${traitName}.${smEvent}`, handler)
41143
+ );
41144
+ }
41162
41145
  return () => {
41163
41146
  for (const unsub of unsubscribes) {
41164
41147
  if (typeof unsub === "function") unsub();
41165
41148
  }
41166
41149
  };
41167
- }, [eventBus, dispatch, stableValidEvents]);
41150
+ }, [eventBus, dispatch, traitName, stableValidEvents]);
41168
41151
  }
41169
- function useSelectedEntity(eventBusInstance) {
41152
+ function useTraitListens(dispatch, listens, eventBusInstance) {
41170
41153
  const defaultEventBus = useEventBus();
41171
41154
  const eventBus = eventBusInstance ?? defaultEventBus;
41172
- const selectionContext = useSelectionContext();
41173
- const [localSelected, setLocalSelected] = React111.useState(null);
41174
- const usingContext = selectionContext !== null;
41155
+ const stableKey = listens.map((l) => `${l.sourceKey}->${l.trigger}`).sort().join("|");
41156
+ const stableListens = React111.useMemo(
41157
+ () => listens,
41158
+ [stableKey]
41159
+ // intentional
41160
+ );
41175
41161
  React111.useEffect(() => {
41176
- if (usingContext) return;
41177
- const handleSelect = (event) => {
41178
- const row = event.payload?.row;
41179
- if (row) {
41180
- setLocalSelected(row);
41181
- }
41182
- };
41183
- const handleDeselect = () => {
41184
- setLocalSelected(null);
41185
- };
41186
- const unsubSelect = eventBus.on("UI:SELECT", handleSelect);
41187
- const unsubView = eventBus.on("UI:VIEW", handleSelect);
41188
- const unsubDeselect = eventBus.on("UI:DESELECT", handleDeselect);
41189
- const unsubClose = eventBus.on("UI:CLOSE", handleDeselect);
41190
- const unsubCancel = eventBus.on("UI:CANCEL", handleDeselect);
41162
+ const unsubscribes = [];
41163
+ for (const spec of stableListens) {
41164
+ const handler = (event) => {
41165
+ dispatch(spec.trigger, event.payload);
41166
+ };
41167
+ unsubscribes.push(eventBus.on(`${UI_PREFIX}${spec.sourceKey}`, handler));
41168
+ }
41191
41169
  return () => {
41192
- [unsubSelect, unsubView, unsubDeselect, unsubClose, unsubCancel].forEach(
41193
- (unsub) => {
41194
- if (typeof unsub === "function") unsub();
41195
- }
41196
- );
41170
+ for (const unsub of unsubscribes) {
41171
+ if (typeof unsub === "function") unsub();
41172
+ }
41197
41173
  };
41198
- }, [eventBus, usingContext]);
41199
- if (selectionContext) {
41200
- return [selectionContext.selected, selectionContext.setSelected];
41201
- }
41202
- return [localSelected, setLocalSelected];
41203
- }
41204
- function useSelectionContext() {
41205
- const context = React111.useContext(providers.SelectionContext);
41206
- return context;
41174
+ }, [eventBus, dispatch, stableListens]);
41207
41175
  }
41208
41176
 
41209
41177
  // hooks/index.ts
@@ -41738,10 +41706,10 @@ exports.usePlayer = usePlayer;
41738
41706
  exports.usePreview = usePreview;
41739
41707
  exports.usePullToRefresh = usePullToRefresh;
41740
41708
  exports.useQuerySingleton = useQuerySingleton;
41741
- exports.useSelectedEntity = useSelectedEntity;
41742
41709
  exports.useSingletonEntity = useSingletonEntity;
41743
41710
  exports.useSpriteAnimations = useSpriteAnimations;
41744
41711
  exports.useSwipeGesture = useSwipeGesture;
41712
+ exports.useTraitListens = useTraitListens;
41745
41713
  exports.useTranslate = useTranslate;
41746
41714
  exports.useUIEvents = useUIEvents;
41747
41715
  exports.useUISlotManager = useUISlotManager;