@almadar/ui 3.0.1 → 3.1.3

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.
@@ -2953,11 +2953,15 @@ function EventBusProvider({ children, debug: debug2 = false }) {
2953
2953
  deprecationWarningShown.current = true;
2954
2954
  }
2955
2955
  }, []);
2956
- const emit = React126.useCallback((type, payload) => {
2956
+ const emit = React126.useCallback((type, payload, source) => {
2957
2957
  const event = {
2958
2958
  type,
2959
+ // Narrow at the bus boundary: public emit takes Record for ergonomics
2960
+ // (generic UI components pass consumer-defined rows) while the envelope
2961
+ // stores the payload as EventPayload for listeners.
2959
2962
  payload,
2960
- timestamp: Date.now()
2963
+ timestamp: Date.now(),
2964
+ source
2961
2965
  };
2962
2966
  const listeners6 = listenersRef.current.get(type);
2963
2967
  const listenerCount = (listeners6?.size ?? 0) + anyListenersRef.current.size;
@@ -3107,8 +3111,8 @@ function useEventListener(event, handler) {
3107
3111
  function useEmitEvent() {
3108
3112
  const eventBus = useEventBus();
3109
3113
  return React126.useCallback(
3110
- (type, payload) => {
3111
- eventBus.emit(type, payload);
3114
+ (type, payload, source) => {
3115
+ eventBus.emit(type, payload, source);
3112
3116
  },
3113
3117
  [eventBus]
3114
3118
  );
@@ -3124,11 +3128,15 @@ var init_useEventBus = __esm({
3124
3128
  fallbackListeners = /* @__PURE__ */ new Map();
3125
3129
  fallbackAnyListeners = /* @__PURE__ */ new Set();
3126
3130
  fallbackEventBus = {
3127
- emit: (type, payload) => {
3131
+ emit: (type, payload, source) => {
3128
3132
  const event = {
3129
3133
  type,
3134
+ // Narrow at the bus boundary: public emit accepts an opaque object so
3135
+ // generic UI emit sites don't require casts; the envelope stores the
3136
+ // payload as EventPayload which listeners consume directly.
3130
3137
  payload,
3131
- timestamp: Date.now()
3138
+ timestamp: Date.now(),
3139
+ source
3132
3140
  };
3133
3141
  const handlers = fallbackListeners.get(type);
3134
3142
  log.debug("emit", { type, payloadKeys: payload ? Object.keys(payload).length : 0, listenerCount: (handlers?.size ?? 0) + fallbackAnyListeners.size });
@@ -51143,6 +51151,9 @@ function useTraitStateMachine(traitBindings, slotsActions, options) {
51143
51151
  const currentState = traitStatesRef.current.get(binding.trait.name)?.currentState ?? "";
51144
51152
  if (tick.appliesTo.length > 0 && !tick.appliesTo.includes(currentState)) return;
51145
51153
  const bindingCtx = { entity: {}, payload: {}, state: currentState };
51154
+ if (binding.config) {
51155
+ bindingCtx.config = binding.config;
51156
+ }
51146
51157
  const evalCtx = runtime.createContextFromBindings(bindingCtx);
51147
51158
  if (tick.guard !== void 0) {
51148
51159
  const passed = runtime.interpolateValue(tick.guard, evalCtx);
@@ -51275,6 +51286,9 @@ function useTraitStateMachine(traitBindings, slotsActions, options) {
51275
51286
  payload: payload || {},
51276
51287
  state: result.previousState
51277
51288
  };
51289
+ if (binding.config) {
51290
+ bindingCtx.config = binding.config;
51291
+ }
51278
51292
  const effectContext = {
51279
51293
  traitName: binding.trait.name,
51280
51294
  state: result.previousState,
package/dist/avl/index.js CHANGED
@@ -2907,11 +2907,15 @@ function EventBusProvider({ children, debug: debug2 = false }) {
2907
2907
  deprecationWarningShown.current = true;
2908
2908
  }
2909
2909
  }, []);
2910
- const emit = useCallback((type, payload) => {
2910
+ const emit = useCallback((type, payload, source) => {
2911
2911
  const event = {
2912
2912
  type,
2913
+ // Narrow at the bus boundary: public emit takes Record for ergonomics
2914
+ // (generic UI components pass consumer-defined rows) while the envelope
2915
+ // stores the payload as EventPayload for listeners.
2913
2916
  payload,
2914
- timestamp: Date.now()
2917
+ timestamp: Date.now(),
2918
+ source
2915
2919
  };
2916
2920
  const listeners6 = listenersRef.current.get(type);
2917
2921
  const listenerCount = (listeners6?.size ?? 0) + anyListenersRef.current.size;
@@ -3061,8 +3065,8 @@ function useEventListener(event, handler) {
3061
3065
  function useEmitEvent() {
3062
3066
  const eventBus = useEventBus();
3063
3067
  return useCallback(
3064
- (type, payload) => {
3065
- eventBus.emit(type, payload);
3068
+ (type, payload, source) => {
3069
+ eventBus.emit(type, payload, source);
3066
3070
  },
3067
3071
  [eventBus]
3068
3072
  );
@@ -3078,11 +3082,15 @@ var init_useEventBus = __esm({
3078
3082
  fallbackListeners = /* @__PURE__ */ new Map();
3079
3083
  fallbackAnyListeners = /* @__PURE__ */ new Set();
3080
3084
  fallbackEventBus = {
3081
- emit: (type, payload) => {
3085
+ emit: (type, payload, source) => {
3082
3086
  const event = {
3083
3087
  type,
3088
+ // Narrow at the bus boundary: public emit accepts an opaque object so
3089
+ // generic UI emit sites don't require casts; the envelope stores the
3090
+ // payload as EventPayload which listeners consume directly.
3084
3091
  payload,
3085
- timestamp: Date.now()
3092
+ timestamp: Date.now(),
3093
+ source
3086
3094
  };
3087
3095
  const handlers = fallbackListeners.get(type);
3088
3096
  log.debug("emit", { type, payloadKeys: payload ? Object.keys(payload).length : 0, listenerCount: (handlers?.size ?? 0) + fallbackAnyListeners.size });
@@ -51097,6 +51105,9 @@ function useTraitStateMachine(traitBindings, slotsActions, options) {
51097
51105
  const currentState = traitStatesRef.current.get(binding.trait.name)?.currentState ?? "";
51098
51106
  if (tick.appliesTo.length > 0 && !tick.appliesTo.includes(currentState)) return;
51099
51107
  const bindingCtx = { entity: {}, payload: {}, state: currentState };
51108
+ if (binding.config) {
51109
+ bindingCtx.config = binding.config;
51110
+ }
51100
51111
  const evalCtx = createContextFromBindings(bindingCtx);
51101
51112
  if (tick.guard !== void 0) {
51102
51113
  const passed = interpolateValue(tick.guard, evalCtx);
@@ -51229,6 +51240,9 @@ function useTraitStateMachine(traitBindings, slotsActions, options) {
51229
51240
  payload: payload || {},
51230
51241
  state: result.previousState
51231
51242
  };
51243
+ if (binding.config) {
51244
+ bindingCtx.config = binding.config;
51245
+ }
51232
51246
  const effectContext = {
51233
51247
  traitName: binding.trait.name,
51234
51248
  state: result.previousState,
@@ -208,8 +208,8 @@ function useEventListener(event, handler) {
208
208
  function useEmitEvent() {
209
209
  const eventBus = useEventBus();
210
210
  return React110.useCallback(
211
- (type, payload) => {
212
- eventBus.emit(type, payload);
211
+ (type, payload, source) => {
212
+ eventBus.emit(type, payload, source);
213
213
  },
214
214
  [eventBus]
215
215
  );
@@ -224,11 +224,15 @@ var init_useEventBus = __esm({
224
224
  fallbackListeners = /* @__PURE__ */ new Map();
225
225
  fallbackAnyListeners = /* @__PURE__ */ new Set();
226
226
  fallbackEventBus = {
227
- emit: (type, payload) => {
227
+ emit: (type, payload, source) => {
228
228
  const event = {
229
229
  type,
230
+ // Narrow at the bus boundary: public emit accepts an opaque object so
231
+ // generic UI emit sites don't require casts; the envelope stores the
232
+ // payload as EventPayload which listeners consume directly.
230
233
  payload,
231
- timestamp: Date.now()
234
+ timestamp: Date.now(),
235
+ source
232
236
  };
233
237
  const handlers = fallbackListeners.get(type);
234
238
  log.debug("emit", { type, payloadKeys: payload ? Object.keys(payload).length : 0, listenerCount: (handlers?.size ?? 0) + fallbackAnyListeners.size });
@@ -163,8 +163,8 @@ function useEventListener(event, handler) {
163
163
  function useEmitEvent() {
164
164
  const eventBus = useEventBus();
165
165
  return useCallback(
166
- (type, payload) => {
167
- eventBus.emit(type, payload);
166
+ (type, payload, source) => {
167
+ eventBus.emit(type, payload, source);
168
168
  },
169
169
  [eventBus]
170
170
  );
@@ -179,11 +179,15 @@ var init_useEventBus = __esm({
179
179
  fallbackListeners = /* @__PURE__ */ new Map();
180
180
  fallbackAnyListeners = /* @__PURE__ */ new Set();
181
181
  fallbackEventBus = {
182
- emit: (type, payload) => {
182
+ emit: (type, payload, source) => {
183
183
  const event = {
184
184
  type,
185
+ // Narrow at the bus boundary: public emit accepts an opaque object so
186
+ // generic UI emit sites don't require casts; the envelope stores the
187
+ // payload as EventPayload which listeners consume directly.
185
188
  payload,
186
- timestamp: Date.now()
189
+ timestamp: Date.now(),
190
+ source
187
191
  };
188
192
  const handlers = fallbackListeners.get(type);
189
193
  log.debug("emit", { type, payloadKeys: payload ? Object.keys(payload).length : 0, listenerCount: (handlers?.size ?? 0) + fallbackAnyListeners.size });
@@ -1436,11 +1436,15 @@ function getGlobalEventBus() {
1436
1436
  var fallbackListeners = /* @__PURE__ */ new Map();
1437
1437
  var fallbackAnyListeners = /* @__PURE__ */ new Set();
1438
1438
  var fallbackEventBus = {
1439
- emit: (type, payload) => {
1439
+ emit: (type, payload, source) => {
1440
1440
  const event = {
1441
1441
  type,
1442
+ // Narrow at the bus boundary: public emit accepts an opaque object so
1443
+ // generic UI emit sites don't require casts; the envelope stores the
1444
+ // payload as EventPayload which listeners consume directly.
1442
1445
  payload,
1443
- timestamp: Date.now()
1446
+ timestamp: Date.now(),
1447
+ source
1444
1448
  };
1445
1449
  const handlers = fallbackListeners.get(type);
1446
1450
  log.debug("emit", { type, payloadKeys: payload ? Object.keys(payload).length : 0, listenerCount: (handlers?.size ?? 0) + fallbackAnyListeners.size });
@@ -1503,8 +1507,8 @@ function useEventBus() {
1503
1507
  function useEmitEvent() {
1504
1508
  const eventBus = useEventBus();
1505
1509
  return React21.useCallback(
1506
- (type, payload) => {
1507
- eventBus.emit(type, payload);
1510
+ (type, payload, source) => {
1511
+ eventBus.emit(type, payload, source);
1508
1512
  },
1509
1513
  [eventBus]
1510
1514
  );
@@ -1412,11 +1412,15 @@ function getGlobalEventBus() {
1412
1412
  var fallbackListeners = /* @__PURE__ */ new Map();
1413
1413
  var fallbackAnyListeners = /* @__PURE__ */ new Set();
1414
1414
  var fallbackEventBus = {
1415
- emit: (type, payload) => {
1415
+ emit: (type, payload, source) => {
1416
1416
  const event = {
1417
1417
  type,
1418
+ // Narrow at the bus boundary: public emit accepts an opaque object so
1419
+ // generic UI emit sites don't require casts; the envelope stores the
1420
+ // payload as EventPayload which listeners consume directly.
1418
1421
  payload,
1419
- timestamp: Date.now()
1422
+ timestamp: Date.now(),
1423
+ source
1420
1424
  };
1421
1425
  const handlers = fallbackListeners.get(type);
1422
1426
  log.debug("emit", { type, payloadKeys: payload ? Object.keys(payload).length : 0, listenerCount: (handlers?.size ?? 0) + fallbackAnyListeners.size });
@@ -1479,8 +1483,8 @@ function useEventBus() {
1479
1483
  function useEmitEvent() {
1480
1484
  const eventBus = useEventBus();
1481
1485
  return useCallback(
1482
- (type, payload) => {
1483
- eventBus.emit(type, payload);
1486
+ (type, payload, source) => {
1487
+ eventBus.emit(type, payload, source);
1484
1488
  },
1485
1489
  [eventBus]
1486
1490
  );
@@ -2570,11 +2570,15 @@ function getGlobalEventBus() {
2570
2570
  var fallbackListeners = /* @__PURE__ */ new Map();
2571
2571
  var fallbackAnyListeners = /* @__PURE__ */ new Set();
2572
2572
  var fallbackEventBus = {
2573
- emit: (type, payload) => {
2573
+ emit: (type, payload, source) => {
2574
2574
  const event = {
2575
2575
  type,
2576
+ // Narrow at the bus boundary: public emit accepts an opaque object so
2577
+ // generic UI emit sites don't require casts; the envelope stores the
2578
+ // payload as EventPayload which listeners consume directly.
2576
2579
  payload,
2577
- timestamp: Date.now()
2580
+ timestamp: Date.now(),
2581
+ source
2578
2582
  };
2579
2583
  const handlers = fallbackListeners.get(type);
2580
2584
  log.debug("emit", { type, payloadKeys: payload ? Object.keys(payload).length : 0, listenerCount: (handlers?.size ?? 0) + fallbackAnyListeners.size });
@@ -295,7 +295,7 @@ interface InputProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, "
295
295
  /** onChange handler - accepts events from input, select, or textarea */
296
296
  onChange?: React.ChangeEventHandler<HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement>;
297
297
  }
298
- declare const Input: React.ForwardRefExoticComponent<InputProps & React.RefAttributes<HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement>>;
298
+ declare const Input: React.ForwardRefExoticComponent<InputProps & React.RefAttributes<HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement>>;
299
299
 
300
300
  /**
301
301
  * DocSidebar Molecule Component
@@ -2546,11 +2546,15 @@ function getGlobalEventBus() {
2546
2546
  var fallbackListeners = /* @__PURE__ */ new Map();
2547
2547
  var fallbackAnyListeners = /* @__PURE__ */ new Set();
2548
2548
  var fallbackEventBus = {
2549
- emit: (type, payload) => {
2549
+ emit: (type, payload, source) => {
2550
2550
  const event = {
2551
2551
  type,
2552
+ // Narrow at the bus boundary: public emit accepts an opaque object so
2553
+ // generic UI emit sites don't require casts; the envelope stores the
2554
+ // payload as EventPayload which listeners consume directly.
2552
2555
  payload,
2553
- timestamp: Date.now()
2556
+ timestamp: Date.now(),
2557
+ source
2554
2558
  };
2555
2559
  const handlers = fallbackListeners.get(type);
2556
2560
  log.debug("emit", { type, payloadKeys: payload ? Object.keys(payload).length : 0, listenerCount: (handlers?.size ?? 0) + fallbackAnyListeners.size });
@@ -1,42 +1,34 @@
1
1
  /**
2
2
  * Event Bus Types
3
3
  *
4
- * Type definitions for the page event bus system.
4
+ * Re-exports from @almadar/core so every package agrees on the same
5
+ * bus event envelope. @almadar/ui no longer owns its own KFlowEvent —
6
+ * that type was folded into core's BusEvent.
5
7
  *
6
8
  * @packageDocumentation
7
9
  */
8
- /**
9
- * A KFlow event that can be emitted on the event bus.
10
- */
11
- export interface KFlowEvent {
12
- /** Event type identifier (e.g., 'TASK_COMPLETED', 'VALIDATION_SUCCESS') */
13
- type: string;
14
- /** Optional payload data */
15
- payload?: Record<string, unknown>;
16
- /** Timestamp when the event was emitted */
17
- timestamp: number;
18
- /** Source trait or component that emitted the event */
19
- source?: string;
20
- }
21
- /**
22
- * Event listener callback function.
23
- */
24
- export type EventListener = (event: KFlowEvent) => void;
25
- /**
26
- * Function to unsubscribe from events.
27
- */
28
- export type Unsubscribe = () => void;
10
+ import type { BusEvent, BusEventSource, BusEventListener, Unsubscribe } from "@almadar/core";
11
+ export type { BusEvent, BusEventSource, Unsubscribe };
12
+ export type EventListener = BusEventListener;
29
13
  /**
30
14
  * Event bus context type.
15
+ *
16
+ * `emit` accepts `Record<string, unknown>` on its public surface so
17
+ * generic UI components (DataGrid, SortableList, ...) can pass
18
+ * consumer-defined row data without a cast at every emit site. The
19
+ * envelope stored in `BusEvent.payload` is narrowed to `EventPayload`
20
+ * inside the bus implementation — listeners always receive the typed
21
+ * shape.
31
22
  */
32
23
  export interface EventBusContextType {
33
24
  /**
34
25
  * Emit an event to all listeners.
35
26
  *
36
27
  * @param type - Event type identifier
37
- * @param payload - Optional payload data
28
+ * @param payload - Optional payload data (object-shaped)
29
+ * @param source - Optional origin info (orbital/trait/...)
38
30
  */
39
- emit: (type: string, payload?: Record<string, unknown>) => void;
31
+ emit: (type: string, payload?: Record<string, unknown>, source?: BusEventSource) => void;
40
32
  /**
41
33
  * Subscribe to an event type.
42
34
  *
@@ -44,7 +36,7 @@ export interface EventBusContextType {
44
36
  * @param listener - Callback function
45
37
  * @returns Unsubscribe function
46
38
  */
47
- on: (type: string, listener: EventListener) => Unsubscribe;
39
+ on: (type: string, listener: BusEventListener) => Unsubscribe;
48
40
  /**
49
41
  * Subscribe to an event type, but only fire once.
50
42
  *
@@ -52,7 +44,7 @@ export interface EventBusContextType {
52
44
  * @param listener - Callback function
53
45
  * @returns Unsubscribe function
54
46
  */
55
- once: (type: string, listener: EventListener) => Unsubscribe;
47
+ once: (type: string, listener: BusEventListener) => Unsubscribe;
56
48
  /**
57
49
  * Check if there are any listeners for an event type.
58
50
  *
@@ -67,5 +59,5 @@ export interface EventBusContextType {
67
59
  * @param listener - Callback function invoked for every emitted event
68
60
  * @returns Unsubscribe function
69
61
  */
70
- onAny?: (listener: EventListener) => Unsubscribe;
62
+ onAny?: (listener: BusEventListener) => Unsubscribe;
71
63
  }
@@ -935,11 +935,15 @@ function getGlobalEventBus() {
935
935
  var fallbackListeners = /* @__PURE__ */ new Map();
936
936
  var fallbackAnyListeners = /* @__PURE__ */ new Set();
937
937
  var fallbackEventBus = {
938
- emit: (type, payload) => {
938
+ emit: (type, payload, source) => {
939
939
  const event = {
940
940
  type,
941
+ // Narrow at the bus boundary: public emit accepts an opaque object so
942
+ // generic UI emit sites don't require casts; the envelope stores the
943
+ // payload as EventPayload which listeners consume directly.
941
944
  payload,
942
- timestamp: Date.now()
945
+ timestamp: Date.now(),
946
+ source
943
947
  };
944
948
  const handlers = fallbackListeners.get(type);
945
949
  log.debug("emit", { type, payloadKeys: payload ? Object.keys(payload).length : 0, listenerCount: (handlers?.size ?? 0) + fallbackAnyListeners.size });
@@ -1016,8 +1020,8 @@ function useEventListener(event, handler) {
1016
1020
  function useEmitEvent() {
1017
1021
  const eventBus = useEventBus();
1018
1022
  return React.useCallback(
1019
- (type, payload) => {
1020
- eventBus.emit(type, payload);
1023
+ (type, payload, source) => {
1024
+ eventBus.emit(type, payload, source);
1021
1025
  },
1022
1026
  [eventBus]
1023
1027
  );
@@ -11,7 +11,7 @@ export { useAgentChat } from './useAgentChat';
11
11
  export { useValidation } from './useValidation';
12
12
  export { useDeepAgentGeneration } from './useDeepAgentGeneration';
13
13
  export { useEventBus, useEventListener, useEmitEvent } from './useEventBus';
14
- export type { KFlowEvent, EventListener, Unsubscribe, EventBusContextType } from './event-bus-types';
14
+ export type { BusEvent, BusEventSource, EventListener, Unsubscribe, EventBusContextType, } from './event-bus-types';
15
15
  export { useUISlotManager, DEFAULT_SLOTS, type UISlot, type SlotAnimation, type SlotContent, type RenderUIConfig, type SlotChangeCallback, type UISlotManager, } from './useUISlots';
16
16
  export { useUIEvents, useSelectedEntity } from './useUIEvents';
17
17
  export { useEntityList, useEntityDetail, useEntity, useEntityListSuspense, useEntitySuspense, entityDataKeys, EntityDataProvider, useEntityDataAdapter, type EntityDataAdapter, type EntityDataRecord, type UseEntityListOptions, type UseEntityListResult, type UseEntityDetailResult, } from './useEntityData';
@@ -929,11 +929,15 @@ function getGlobalEventBus() {
929
929
  var fallbackListeners = /* @__PURE__ */ new Map();
930
930
  var fallbackAnyListeners = /* @__PURE__ */ new Set();
931
931
  var fallbackEventBus = {
932
- emit: (type, payload) => {
932
+ emit: (type, payload, source) => {
933
933
  const event = {
934
934
  type,
935
+ // Narrow at the bus boundary: public emit accepts an opaque object so
936
+ // generic UI emit sites don't require casts; the envelope stores the
937
+ // payload as EventPayload which listeners consume directly.
935
938
  payload,
936
- timestamp: Date.now()
939
+ timestamp: Date.now(),
940
+ source
937
941
  };
938
942
  const handlers = fallbackListeners.get(type);
939
943
  log.debug("emit", { type, payloadKeys: payload ? Object.keys(payload).length : 0, listenerCount: (handlers?.size ?? 0) + fallbackAnyListeners.size });
@@ -1010,8 +1014,8 @@ function useEventListener(event, handler) {
1010
1014
  function useEmitEvent() {
1011
1015
  const eventBus = useEventBus();
1012
1016
  return useCallback(
1013
- (type, payload) => {
1014
- eventBus.emit(type, payload);
1017
+ (type, payload, source) => {
1018
+ eventBus.emit(type, payload, source);
1015
1019
  },
1016
1020
  [eventBus]
1017
1021
  );
@@ -1,5 +1,5 @@
1
- import type { KFlowEvent, EventListener, Unsubscribe, EventBusContextType } from './event-bus-types';
2
- export type { KFlowEvent, EventListener, Unsubscribe, EventBusContextType };
1
+ import type { BusEvent, BusEventSource, EventListener, Unsubscribe, EventBusContextType } from './event-bus-types';
2
+ export type { BusEvent, BusEventSource, EventListener, Unsubscribe, EventBusContextType };
3
3
  declare global {
4
4
  interface Window {
5
5
  __kflowEventBus?: EventBusContextType | null;
@@ -92,5 +92,5 @@ export declare const useEventSubscription: typeof useEventListener;
92
92
  * };
93
93
  * ```
94
94
  */
95
- export declare function useEmitEvent(): (type: string, payload?: Record<string, unknown>) => void;
95
+ export declare function useEmitEvent(): (type: string, payload?: Record<string, unknown>, source?: BusEventSource) => void;
96
96
  export default useEventBus;
@@ -9,6 +9,7 @@
9
9
  *
10
10
  * @packageDocumentation
11
11
  */
12
+ import type { BusEvent, EventPayload } from '@almadar/core';
12
13
  export type CheckStatus = "pass" | "fail" | "pending" | "warn";
13
14
  export interface VerificationCheck {
14
15
  id: string;
@@ -91,7 +92,7 @@ export type AssetLoadStatus = "loaded" | "failed" | "pending";
91
92
  /** Event bus log entry for verification */
92
93
  export interface EventLogEntry {
93
94
  type: string;
94
- payload?: Record<string, unknown>;
95
+ payload?: EventPayload;
95
96
  timestamp: number;
96
97
  }
97
98
  /** Exposed on window for Playwright to query */
@@ -132,10 +133,7 @@ export declare function waitForTransition(event: string, timeoutMs?: number): Pr
132
133
  */
133
134
  export declare function bindEventBus(eventBus: {
134
135
  emit: (type: string, payload?: Record<string, unknown>) => void;
135
- onAny?: (listener: (event: {
136
- type: string;
137
- payload?: Record<string, unknown>;
138
- }) => void) => () => void;
136
+ onAny?: (listener: (event: BusEvent) => void) => () => void;
139
137
  }): void;
140
138
  /**
141
139
  * Bind a trait state getter so automation can query current states.
@@ -2570,11 +2570,15 @@ function getGlobalEventBus() {
2570
2570
  var fallbackListeners = /* @__PURE__ */ new Map();
2571
2571
  var fallbackAnyListeners = /* @__PURE__ */ new Set();
2572
2572
  var fallbackEventBus = {
2573
- emit: (type, payload) => {
2573
+ emit: (type, payload, source) => {
2574
2574
  const event = {
2575
2575
  type,
2576
+ // Narrow at the bus boundary: public emit accepts an opaque object so
2577
+ // generic UI emit sites don't require casts; the envelope stores the
2578
+ // payload as EventPayload which listeners consume directly.
2576
2579
  payload,
2577
- timestamp: Date.now()
2580
+ timestamp: Date.now(),
2581
+ source
2578
2582
  };
2579
2583
  const handlers = fallbackListeners.get(type);
2580
2584
  log.debug("emit", { type, payloadKeys: payload ? Object.keys(payload).length : 0, listenerCount: (handlers?.size ?? 0) + fallbackAnyListeners.size });
@@ -2546,11 +2546,15 @@ function getGlobalEventBus() {
2546
2546
  var fallbackListeners = /* @__PURE__ */ new Map();
2547
2547
  var fallbackAnyListeners = /* @__PURE__ */ new Set();
2548
2548
  var fallbackEventBus = {
2549
- emit: (type, payload) => {
2549
+ emit: (type, payload, source) => {
2550
2550
  const event = {
2551
2551
  type,
2552
+ // Narrow at the bus boundary: public emit accepts an opaque object so
2553
+ // generic UI emit sites don't require casts; the envelope stores the
2554
+ // payload as EventPayload which listeners consume directly.
2552
2555
  payload,
2553
- timestamp: Date.now()
2556
+ timestamp: Date.now(),
2557
+ source
2554
2558
  };
2555
2559
  const handlers = fallbackListeners.get(type);
2556
2560
  log.debug("emit", { type, payloadKeys: payload ? Object.keys(payload).length : 0, listenerCount: (handlers?.size ?? 0) + fallbackAnyListeners.size });
@@ -455,8 +455,8 @@ function useEventListener(event, handler) {
455
455
  function useEmitEvent() {
456
456
  const eventBus = useEventBus();
457
457
  return React115.useCallback(
458
- (type, payload) => {
459
- eventBus.emit(type, payload);
458
+ (type, payload, source) => {
459
+ eventBus.emit(type, payload, source);
460
460
  },
461
461
  [eventBus]
462
462
  );
@@ -471,11 +471,15 @@ var init_useEventBus = __esm({
471
471
  fallbackListeners = /* @__PURE__ */ new Map();
472
472
  fallbackAnyListeners = /* @__PURE__ */ new Set();
473
473
  fallbackEventBus = {
474
- emit: (type, payload) => {
474
+ emit: (type, payload, source) => {
475
475
  const event = {
476
476
  type,
477
+ // Narrow at the bus boundary: public emit accepts an opaque object so
478
+ // generic UI emit sites don't require casts; the envelope stores the
479
+ // payload as EventPayload which listeners consume directly.
477
480
  payload,
478
- timestamp: Date.now()
481
+ timestamp: Date.now(),
482
+ source
479
483
  };
480
484
  const handlers = fallbackListeners.get(type);
481
485
  log.debug("emit", { type, payloadKeys: payload ? Object.keys(payload).length : 0, listenerCount: (handlers?.size ?? 0) + fallbackAnyListeners.size });
@@ -38229,11 +38233,15 @@ function EventBusProvider({ children, debug: debug2 = false }) {
38229
38233
  deprecationWarningShown.current = true;
38230
38234
  }
38231
38235
  }, []);
38232
- const emit = React115.useCallback((type, payload) => {
38236
+ const emit = React115.useCallback((type, payload, source) => {
38233
38237
  const event = {
38234
38238
  type,
38239
+ // Narrow at the bus boundary: public emit takes Record for ergonomics
38240
+ // (generic UI components pass consumer-defined rows) while the envelope
38241
+ // stores the payload as EventPayload for listeners.
38235
38242
  payload,
38236
- timestamp: Date.now()
38243
+ timestamp: Date.now(),
38244
+ source
38237
38245
  };
38238
38246
  const listeners6 = listenersRef.current.get(type);
38239
38247
  const listenerCount = (listeners6?.size ?? 0) + anyListenersRef.current.size;
@@ -410,8 +410,8 @@ function useEventListener(event, handler) {
410
410
  function useEmitEvent() {
411
411
  const eventBus = useEventBus();
412
412
  return useCallback(
413
- (type, payload) => {
414
- eventBus.emit(type, payload);
413
+ (type, payload, source) => {
414
+ eventBus.emit(type, payload, source);
415
415
  },
416
416
  [eventBus]
417
417
  );
@@ -426,11 +426,15 @@ var init_useEventBus = __esm({
426
426
  fallbackListeners = /* @__PURE__ */ new Map();
427
427
  fallbackAnyListeners = /* @__PURE__ */ new Set();
428
428
  fallbackEventBus = {
429
- emit: (type, payload) => {
429
+ emit: (type, payload, source) => {
430
430
  const event = {
431
431
  type,
432
+ // Narrow at the bus boundary: public emit accepts an opaque object so
433
+ // generic UI emit sites don't require casts; the envelope stores the
434
+ // payload as EventPayload which listeners consume directly.
432
435
  payload,
433
- timestamp: Date.now()
436
+ timestamp: Date.now(),
437
+ source
434
438
  };
435
439
  const handlers = fallbackListeners.get(type);
436
440
  log.debug("emit", { type, payloadKeys: payload ? Object.keys(payload).length : 0, listenerCount: (handlers?.size ?? 0) + fallbackAnyListeners.size });
@@ -38184,11 +38188,15 @@ function EventBusProvider({ children, debug: debug2 = false }) {
38184
38188
  deprecationWarningShown.current = true;
38185
38189
  }
38186
38190
  }, []);
38187
- const emit = useCallback((type, payload) => {
38191
+ const emit = useCallback((type, payload, source) => {
38188
38192
  const event = {
38189
38193
  type,
38194
+ // Narrow at the bus boundary: public emit takes Record for ergonomics
38195
+ // (generic UI components pass consumer-defined rows) while the envelope
38196
+ // stores the payload as EventPayload for listeners.
38190
38197
  payload,
38191
- timestamp: Date.now()
38198
+ timestamp: Date.now(),
38199
+ source
38192
38200
  };
38193
38201
  const listeners6 = listenersRef.current.get(type);
38194
38202
  const listenerCount = (listeners6?.size ?? 0) + anyListenersRef.current.size;
@@ -202,8 +202,8 @@ function useEventListener(event, handler) {
202
202
  function useEmitEvent() {
203
203
  const eventBus = useEventBus();
204
204
  return React116.useCallback(
205
- (type, payload) => {
206
- eventBus.emit(type, payload);
205
+ (type, payload, source) => {
206
+ eventBus.emit(type, payload, source);
207
207
  },
208
208
  [eventBus]
209
209
  );
@@ -218,11 +218,15 @@ var init_useEventBus = __esm({
218
218
  fallbackListeners = /* @__PURE__ */ new Map();
219
219
  fallbackAnyListeners = /* @__PURE__ */ new Set();
220
220
  fallbackEventBus = {
221
- emit: (type, payload) => {
221
+ emit: (type, payload, source) => {
222
222
  const event = {
223
223
  type,
224
+ // Narrow at the bus boundary: public emit accepts an opaque object so
225
+ // generic UI emit sites don't require casts; the envelope stores the
226
+ // payload as EventPayload which listeners consume directly.
224
227
  payload,
225
- timestamp: Date.now()
228
+ timestamp: Date.now(),
229
+ source
226
230
  };
227
231
  const handlers = fallbackListeners.get(type);
228
232
  log.debug("emit", { type, payloadKeys: payload ? Object.keys(payload).length : 0, listenerCount: (handlers?.size ?? 0) + fallbackAnyListeners.size });
@@ -37940,6 +37944,9 @@ function useTraitStateMachine(traitBindings, slotsActions, options) {
37940
37944
  const currentState = traitStatesRef.current.get(binding.trait.name)?.currentState ?? "";
37941
37945
  if (tick.appliesTo.length > 0 && !tick.appliesTo.includes(currentState)) return;
37942
37946
  const bindingCtx = { entity: {}, payload: {}, state: currentState };
37947
+ if (binding.config) {
37948
+ bindingCtx.config = binding.config;
37949
+ }
37943
37950
  const evalCtx = runtime.createContextFromBindings(bindingCtx);
37944
37951
  if (tick.guard !== void 0) {
37945
37952
  const passed = runtime.interpolateValue(tick.guard, evalCtx);
@@ -38072,6 +38079,9 @@ function useTraitStateMachine(traitBindings, slotsActions, options) {
38072
38079
  payload: payload || {},
38073
38080
  state: result.previousState
38074
38081
  };
38082
+ if (binding.config) {
38083
+ bindingCtx.config = binding.config;
38084
+ }
38075
38085
  const effectContext = {
38076
38086
  traitName: binding.trait.name,
38077
38087
  state: result.previousState,
@@ -157,8 +157,8 @@ function useEventListener(event, handler) {
157
157
  function useEmitEvent() {
158
158
  const eventBus = useEventBus();
159
159
  return useCallback(
160
- (type, payload) => {
161
- eventBus.emit(type, payload);
160
+ (type, payload, source) => {
161
+ eventBus.emit(type, payload, source);
162
162
  },
163
163
  [eventBus]
164
164
  );
@@ -173,11 +173,15 @@ var init_useEventBus = __esm({
173
173
  fallbackListeners = /* @__PURE__ */ new Map();
174
174
  fallbackAnyListeners = /* @__PURE__ */ new Set();
175
175
  fallbackEventBus = {
176
- emit: (type, payload) => {
176
+ emit: (type, payload, source) => {
177
177
  const event = {
178
178
  type,
179
+ // Narrow at the bus boundary: public emit accepts an opaque object so
180
+ // generic UI emit sites don't require casts; the envelope stores the
181
+ // payload as EventPayload which listeners consume directly.
179
182
  payload,
180
- timestamp: Date.now()
183
+ timestamp: Date.now(),
184
+ source
181
185
  };
182
186
  const handlers = fallbackListeners.get(type);
183
187
  log.debug("emit", { type, payloadKeys: payload ? Object.keys(payload).length : 0, listenerCount: (handlers?.size ?? 0) + fallbackAnyListeners.size });
@@ -37895,6 +37899,9 @@ function useTraitStateMachine(traitBindings, slotsActions, options) {
37895
37899
  const currentState = traitStatesRef.current.get(binding.trait.name)?.currentState ?? "";
37896
37900
  if (tick.appliesTo.length > 0 && !tick.appliesTo.includes(currentState)) return;
37897
37901
  const bindingCtx = { entity: {}, payload: {}, state: currentState };
37902
+ if (binding.config) {
37903
+ bindingCtx.config = binding.config;
37904
+ }
37898
37905
  const evalCtx = createContextFromBindings(bindingCtx);
37899
37906
  if (tick.guard !== void 0) {
37900
37907
  const passed = interpolateValue(tick.guard, evalCtx);
@@ -38027,6 +38034,9 @@ function useTraitStateMachine(traitBindings, slotsActions, options) {
38027
38034
  payload: payload || {},
38028
38035
  state: result.previousState
38029
38036
  };
38037
+ if (binding.config) {
38038
+ bindingCtx.config = binding.config;
38039
+ }
38030
38040
  const effectContext = {
38031
38041
  traitName: binding.trait.name,
38032
38042
  state: result.previousState,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@almadar/ui",
3
- "version": "3.0.1",
3
+ "version": "3.1.3",
4
4
  "description": "React UI components, hooks, and providers for Almadar",
5
5
  "type": "module",
6
6
  "main": "./dist/components/index.js",
@@ -118,10 +118,10 @@
118
118
  "access": "public"
119
119
  },
120
120
  "dependencies": {
121
- "@almadar/core": ">=5.1.0",
122
- "@almadar/evaluator": ">=2.8.1",
121
+ "@almadar/core": ">=5.3.1",
122
+ "@almadar/evaluator": ">=2.9.2",
123
123
  "@almadar/patterns": ">=2.14.1",
124
- "@almadar/runtime": ">=4.0.0",
124
+ "@almadar/runtime": ">=4.3.0",
125
125
  "@almadar/std": ">=6.4.1",
126
126
  "@almadar/syntax": ">=1.3.1",
127
127
  "@xyflow/react": "12.10.1",