event-emission 0.2.0 → 0.2.1

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.
Files changed (43) hide show
  1. package/README.md +80 -24
  2. package/dist/event-emission.d.ts +13 -14
  3. package/dist/event-emission.d.ts.map +1 -1
  4. package/dist/factory.d.ts +1 -1
  5. package/dist/factory.d.ts.map +1 -1
  6. package/dist/index.cjs +474 -285
  7. package/dist/index.cjs.map +8 -9
  8. package/dist/index.d.ts +1 -7
  9. package/dist/index.d.ts.map +1 -1
  10. package/dist/index.js +449 -278
  11. package/dist/index.js.map +8 -9
  12. package/dist/interoperability.cjs +1605 -0
  13. package/dist/interoperability.cjs.map +15 -0
  14. package/dist/{interop.d.ts → interoperability.d.ts} +2 -1
  15. package/dist/interoperability.d.ts.map +1 -0
  16. package/dist/interoperability.js +1555 -0
  17. package/dist/interoperability.js.map +15 -0
  18. package/dist/observable.cjs +286 -0
  19. package/dist/observable.cjs.map +11 -0
  20. package/dist/observable.js +253 -0
  21. package/dist/observable.js.map +11 -0
  22. package/dist/observe.cjs +344 -0
  23. package/dist/observe.cjs.map +10 -0
  24. package/dist/observe.d.ts +6 -1
  25. package/dist/observe.d.ts.map +1 -1
  26. package/dist/observe.js +313 -0
  27. package/dist/observe.js.map +10 -0
  28. package/dist/symbols.d.ts +1 -1
  29. package/dist/types.cjs +35 -0
  30. package/dist/types.cjs.map +9 -0
  31. package/dist/types.d.ts +60 -25
  32. package/dist/types.d.ts.map +1 -1
  33. package/dist/types.js +3 -0
  34. package/dist/types.js.map +9 -0
  35. package/package.json +25 -1
  36. package/src/event-emission.ts +26 -20
  37. package/src/factory.ts +538 -218
  38. package/src/index.ts +4 -33
  39. package/src/{interop.ts → interoperability.ts} +24 -6
  40. package/src/observe.ts +54 -17
  41. package/src/symbols.ts +1 -1
  42. package/src/types.ts +75 -30
  43. package/dist/interop.d.ts.map +0 -1
package/src/index.ts CHANGED
@@ -21,18 +21,16 @@ declare global {
21
21
  export type {
22
22
  AddEventListenerOptionsLike,
23
23
  AsyncIteratorOptions,
24
- DOMEventLike,
25
- DOMEventTargetLike,
24
+ DispatchEventInput,
26
25
  EmissionEvent,
26
+ EventListenerLike,
27
+ EventListenerObject,
28
+ EventListenerOptionsLike,
27
29
  EventsIteratorOptions,
28
30
  EventTargetLike,
29
- InteropOptions,
30
31
  Listener,
31
32
  MinimalAbortSignal,
32
- ObservableLike,
33
- Observer,
34
33
  OverflowStrategy,
35
- Subscription,
36
34
  WildcardEvent,
37
35
  WildcardListener,
38
36
  } from './types';
@@ -47,32 +45,5 @@ export type {
47
45
  } from './factory';
48
46
  export { createEventTarget } from './factory';
49
47
 
50
- // Re-export observation utilities and types
51
- export type {
52
- ArrayMutationDetail,
53
- ArrayMutationMethod,
54
- ObservableEventMap,
55
- ObserveOptions,
56
- PropertyChangeDetail,
57
- } from './observe';
58
- export {
59
- getOriginal,
60
- isObserved,
61
- ORIGINAL_TARGET,
62
- PROXY_MARKER,
63
- setupEventForwarding,
64
- } from './observe';
65
-
66
- // Re-export Observable
67
- export type {
68
- Subscriber,
69
- SubscriptionObserverInterface as SubscriptionObserver,
70
- } from './observable';
71
- export { Observable } from './observable';
72
-
73
- // Re-export interop
74
- export type { FromEventTargetOptions } from './interop';
75
- export { forwardToEventTarget, fromEventTarget, pipe } from './interop';
76
-
77
48
  // Re-export EventEmission class
78
49
  export { EventEmission } from './event-emission';
@@ -7,6 +7,8 @@ import type {
7
7
  InteropOptions,
8
8
  } from './types';
9
9
 
10
+ export type { DOMEventLike, DOMEventTargetLike, InteropOptions } from './types';
11
+
10
12
  /**
11
13
  * Forward events from an EventEmission target to a DOM EventTarget.
12
14
  *
@@ -43,11 +45,24 @@ export function forwardToEventTarget<E extends Record<string, unknown>>(
43
45
  const unsubscribe = source.addWildcardListener(
44
46
  '*',
45
47
  (event) => {
46
- // Create a DOM-like event object
47
- const domEvent: DOMEventLike = {
48
- type: event.originalType,
49
- detail: event.detail,
50
- };
48
+ // Use CustomEvent when available to preserve DOM event semantics.
49
+ const CustomEventCtor = (globalThis as { CustomEvent?: typeof CustomEvent })
50
+ .CustomEvent;
51
+ const domEvent: DOMEventLike =
52
+ typeof CustomEventCtor === 'function'
53
+ ? new CustomEventCtor(event.originalType, {
54
+ detail: event.detail,
55
+ bubbles: event.bubbles,
56
+ cancelable: event.cancelable,
57
+ composed: event.composed,
58
+ })
59
+ : {
60
+ type: event.originalType,
61
+ detail: event.detail,
62
+ bubbles: event.bubbles,
63
+ cancelable: event.cancelable,
64
+ composed: event.composed,
65
+ };
51
66
  target.dispatchEvent(domEvent);
52
67
  },
53
68
  options,
@@ -144,6 +159,9 @@ export function fromEventTarget<E extends Record<string, unknown>>(
144
159
  emitter.dispatchEvent({
145
160
  type,
146
161
  detail: (event.detail ?? event) as E[typeof type],
162
+ bubbles: event.bubbles,
163
+ cancelable: event.cancelable,
164
+ composed: event.composed,
147
165
  } as unknown as EmissionEvent<E[keyof E & string]>);
148
166
  };
149
167
  handlers.set(type, handler);
@@ -266,7 +284,7 @@ export function pipe<E extends Record<string, unknown>>(
266
284
  target.dispatchEvent({
267
285
  type: event.originalType,
268
286
  detail: event.detail as E[keyof E & string],
269
- } as unknown as EmissionEvent<E[keyof E & string]>);
287
+ } as unknown as Parameters<typeof target.dispatchEvent>[0]);
270
288
  },
271
289
  options,
272
290
  );
package/src/observe.ts CHANGED
@@ -45,8 +45,10 @@ export const ORIGINAL_TARGET = Symbol.for('@lasercat/event-emission/original');
45
45
  export interface ObserveOptions {
46
46
  /** Enable deep observation of nested objects (default: true) */
47
47
  deep?: boolean;
48
- /** Clone strategy for previous state (default: 'path') */
48
+ /** Clone strategy for previous state (default: 'path'); 'deep' uses structuredClone or deepClone */
49
49
  cloneStrategy?: 'shallow' | 'deep' | 'path';
50
+ /** Optional deep clone fallback for runtimes without structuredClone */
51
+ deepClone?: <T>(value: T) => T;
50
52
  }
51
53
 
52
54
  /** Event detail for property changes */
@@ -115,11 +117,17 @@ const ARRAY_MUTATORS = new Set<ArrayMutationMethod>([
115
117
  // Internal Types
116
118
  // =============================================================================
117
119
 
120
+ type ResolvedObserveOptions = {
121
+ deep: boolean;
122
+ cloneStrategy: 'shallow' | 'deep' | 'path';
123
+ deepClone?: ObserveOptions['deepClone'];
124
+ };
125
+
118
126
  interface ProxyContext<T extends object> {
119
127
  eventTarget: EventTargetLike<ObservableEventMap<T>>;
120
128
  /** Reference to the original (unproxied) root object for cloning */
121
129
  originalRoot: T;
122
- options: Required<ObserveOptions>;
130
+ options: ResolvedObserveOptions;
123
131
  }
124
132
 
125
133
  // =============================================================================
@@ -161,22 +169,18 @@ function isArrayMutator(prop: string | symbol): prop is ArrayMutationMethod {
161
169
 
162
170
  /** Clone along changed path for efficiency */
163
171
  function cloneAlongPath(obj: unknown, path?: string): unknown {
164
- if (obj === null || typeof obj !== 'object') {
165
- return obj;
166
- }
172
+ const isArray = Array.isArray(obj);
173
+ const rootClone = isArray
174
+ ? [...(obj as unknown[])]
175
+ : { ...(obj as Record<string, unknown>) };
167
176
 
168
- if (!path) {
169
- return Array.isArray(obj) ? [...obj] : { ...obj };
177
+ if (!path || isArray) {
178
+ return rootClone;
170
179
  }
171
180
 
172
181
  const parts = path.split('.');
173
182
 
174
- if (Array.isArray(obj)) {
175
- // For arrays, shallow copy
176
- return [...obj];
177
- }
178
-
179
- const result: Record<string, unknown> = { ...obj };
183
+ const result = rootClone as Record<string, unknown>;
180
184
 
181
185
  let current: Record<string, unknown> = result;
182
186
  // Clone all objects along the path, INCLUDING the leaf
@@ -202,6 +206,7 @@ function cloneForComparison(
202
206
  obj: unknown,
203
207
  strategy: 'shallow' | 'deep' | 'path',
204
208
  changedPath?: string,
209
+ deepClone?: ObserveOptions['deepClone'],
205
210
  ): unknown {
206
211
  if (obj === null || typeof obj !== 'object') return obj;
207
212
 
@@ -210,6 +215,14 @@ function cloneForComparison(
210
215
  return Array.isArray(obj) ? [...obj] : { ...obj };
211
216
 
212
217
  case 'deep':
218
+ if (deepClone) {
219
+ return deepClone(obj);
220
+ }
221
+ if (typeof structuredClone !== 'function') {
222
+ throw new Error(
223
+ "structuredClone is not available in this runtime; provide observe.deepClone, or use cloneStrategy 'path' or 'shallow'.",
224
+ );
225
+ }
213
226
  return structuredClone(obj);
214
227
 
215
228
  case 'path':
@@ -300,6 +313,7 @@ function createArrayMethodInterceptor<T extends object>(
300
313
  context.originalRoot,
301
314
  context.options.cloneStrategy,
302
315
  path,
316
+ context.options.deepClone,
303
317
  );
304
318
  const previousItems = [...array];
305
319
 
@@ -418,6 +432,7 @@ function createObservableProxyInternal<T extends object>(
418
432
  context.originalRoot,
419
433
  context.options.cloneStrategy,
420
434
  propPath,
435
+ context.options.deepClone,
421
436
  );
422
437
 
423
438
  const success = Reflect.set(obj, prop, value, receiver);
@@ -457,6 +472,7 @@ function createObservableProxyInternal<T extends object>(
457
472
  context.originalRoot,
458
473
  context.options.cloneStrategy,
459
474
  propPath,
475
+ context.options.deepClone,
460
476
  );
461
477
 
462
478
  const success = Reflect.deleteProperty(obj, prop);
@@ -544,6 +560,8 @@ export function setupEventForwarding<T extends object>(
544
560
  target: EventTargetLike<ObservableEventMap<T>>,
545
561
  ): () => void {
546
562
  const handlers = new Map<string, (event: unknown) => void>();
563
+ const sourceAddEventListener = source.addEventListener.bind(source);
564
+ const sourceRemoveEventListener = source.removeEventListener.bind(source);
547
565
 
548
566
  const forwardHandler = (type: string) => (event: unknown) => {
549
567
  const detail = (event as MinimalCustomEvent).detail ?? event;
@@ -566,7 +584,7 @@ export function setupEventForwarding<T extends object>(
566
584
  if (!handlers.has(type) && type !== 'update' && !type.startsWith('update:')) {
567
585
  const handler = forwardHandler(type);
568
586
  handlers.set(type, handler);
569
- source.addEventListener(type, handler);
587
+ sourceAddEventListener(type, handler);
570
588
  }
571
589
  return originalAddEventListener(
572
590
  type as keyof ObservableEventMap<T> & string,
@@ -587,7 +605,7 @@ export function setupEventForwarding<T extends object>(
587
605
  originalAddEventListener;
588
606
  // Clean up all forwarding handlers
589
607
  for (const [type, handler] of handlers) {
590
- source.removeEventListener(type, handler);
608
+ sourceRemoveEventListener(type, handler);
591
609
  }
592
610
  handlers.clear();
593
611
  };
@@ -664,6 +682,9 @@ export function getOriginal<T extends object>(proxy: T): T {
664
682
  * including nested objects and array mutations. Events are dispatched to the
665
683
  * provided event target for each change.
666
684
  *
685
+ * If the target is an EventTarget, event forwarding is set up automatically and
686
+ * cleaned up when the event target completes.
687
+ *
667
688
  * Note: This is typically called internally by createEventTarget with observe: true.
668
689
  * You usually don't need to call this directly.
669
690
  *
@@ -709,9 +730,10 @@ export function createObservableProxy<T extends object>(
709
730
  eventTarget: EventTargetLike<ObservableEventMap<T>>,
710
731
  options?: ObserveOptions,
711
732
  ): T {
712
- const resolvedOptions: Required<ObserveOptions> = {
733
+ const resolvedOptions: ResolvedObserveOptions = {
713
734
  deep: options?.deep ?? true,
714
735
  cloneStrategy: options?.cloneStrategy ?? 'path',
736
+ deepClone: options?.deepClone,
715
737
  };
716
738
 
717
739
  const context: ProxyContext<T> = {
@@ -724,7 +746,22 @@ export function createObservableProxy<T extends object>(
724
746
 
725
747
  // Set up event forwarding if target is already an EventTarget
726
748
  if (isEventTarget(target)) {
727
- setupEventForwarding(target as unknown as MinimalEventTarget, eventTarget);
749
+ const cleanupForwarding = setupEventForwarding(
750
+ target as unknown as MinimalEventTarget,
751
+ eventTarget,
752
+ );
753
+ const maybeComplete = (eventTarget as { complete?: () => void }).complete;
754
+ if (typeof maybeComplete === 'function') {
755
+ const originalComplete = maybeComplete.bind(eventTarget);
756
+ let cleaned = false;
757
+ (eventTarget as { complete: () => void }).complete = () => {
758
+ if (!cleaned) {
759
+ cleaned = true;
760
+ cleanupForwarding();
761
+ }
762
+ return originalComplete();
763
+ };
764
+ }
728
765
  }
729
766
 
730
767
  return proxy;
package/src/symbols.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Symbol.observable polyfill for TC39 Observable interop.
2
+ * Symbol.observable polyfill for TC39 Observable interoperability.
3
3
  * This ensures the symbol exists even in environments that don't support it natively.
4
4
  */
5
5
  export const SymbolObservable: symbol =
package/src/types.ts CHANGED
@@ -10,9 +10,9 @@ declare global {
10
10
  * Event structure passed to listeners.
11
11
  * Matches the shape of a DOM CustomEvent to ensure compatibility.
12
12
  */
13
- export interface EmissionEvent<Detail> {
13
+ export interface EmissionEvent<Detail, Type extends string = string> {
14
14
  /** The event type identifier. */
15
- readonly type: string;
15
+ readonly type: Type;
16
16
  /** The event payload data. */
17
17
  readonly detail: Detail;
18
18
 
@@ -20,6 +20,8 @@ export interface EmissionEvent<Detail> {
20
20
  readonly bubbles: boolean;
21
21
  /** DOM Event compatibility: true if the event can be cancelled. */
22
22
  readonly cancelable: boolean;
23
+ /** DOM Event compatibility: legacy alias for stopPropagation(). */
24
+ cancelBubble: boolean;
23
25
  /** DOM Event compatibility: true if the event can cross Shadow DOM boundaries. */
24
26
  readonly composed: boolean;
25
27
  /** DOM Event compatibility: the object currently processing the event. */
@@ -30,6 +32,10 @@ export interface EmissionEvent<Detail> {
30
32
  readonly eventPhase: number;
31
33
  /** DOM Event compatibility: true if the event was dispatched by the user agent. */
32
34
  readonly isTrusted: boolean;
35
+ /** DOM Event compatibility: legacy alias for defaultPrevented. */
36
+ returnValue: boolean;
37
+ /** DOM Event compatibility: legacy alias for target. */
38
+ readonly srcElement: unknown;
33
39
  /** DOM Event compatibility: the object that originally dispatched the event. */
34
40
  readonly target: unknown;
35
41
  /** DOM Event compatibility: the time at which the event was created. */
@@ -37,6 +43,8 @@ export interface EmissionEvent<Detail> {
37
43
 
38
44
  /** DOM Event compatibility: returns the path of nodes the event will travel through. */
39
45
  composedPath(): unknown[];
46
+ /** DOM Event compatibility: legacy initializer. */
47
+ initEvent(type: string, bubbles?: boolean, cancelable?: boolean): void;
40
48
  /** DOM Event compatibility: cancels the event if it is cancelable. */
41
49
  preventDefault(): void;
42
50
  /** DOM Event compatibility: prevents other listeners from being called. */
@@ -55,11 +63,11 @@ export interface EmissionEvent<Detail> {
55
63
  * Event passed to wildcard listeners, includes the original event type.
56
64
  */
57
65
  export interface WildcardEvent<E extends Record<string, unknown>> extends EmissionEvent<
58
- E[keyof E]
66
+ E[keyof E],
67
+ '*' | `${string}:*`
59
68
  > {
60
69
  readonly type: '*' | `${string}:*`;
61
70
  readonly originalType: keyof E & string;
62
- readonly detail: E[keyof E];
63
71
  }
64
72
 
65
73
  /**
@@ -75,11 +83,41 @@ export interface MinimalAbortSignal {
75
83
  /**
76
84
  * Options for addEventListener.
77
85
  */
78
- export type AddEventListenerOptionsLike = {
86
+ export interface EventListenerOptionsLike {
87
+ capture?: boolean;
88
+ }
89
+
90
+ /**
91
+ * Options for addEventListener.
92
+ */
93
+ export type AddEventListenerOptionsLike = EventListenerOptionsLike & {
79
94
  once?: boolean;
95
+ passive?: boolean;
80
96
  signal?: MinimalAbortSignal;
81
97
  };
82
98
 
99
+ /**
100
+ * EventListener-like callback (function or object with handleEvent).
101
+ */
102
+ export type EventListenerObject<T> = {
103
+ handleEvent: (event: T) => void | Promise<void>;
104
+ };
105
+
106
+ export type EventListenerLike<T> =
107
+ | ((event: T) => void | Promise<void>)
108
+ | EventListenerObject<T>;
109
+
110
+ /**
111
+ * Minimal event input accepted by dispatchEvent.
112
+ */
113
+ export type DispatchEventInput<Detail, Type extends string = string> = {
114
+ type: Type;
115
+ detail: Detail;
116
+ bubbles?: boolean;
117
+ cancelable?: boolean;
118
+ composed?: boolean;
119
+ };
120
+
83
121
  /**
84
122
  * TC39 Observable observer interface.
85
123
  */
@@ -130,22 +168,26 @@ export interface AsyncIteratorOptions {
130
168
  export type EventsIteratorOptions = AsyncIteratorOptions;
131
169
 
132
170
  /**
133
- * Options for interop helpers.
171
+ * Options for interoperability helpers.
134
172
  */
135
173
  export interface InteropOptions {
136
174
  signal?: MinimalAbortSignal;
137
175
  }
138
176
 
139
177
  /**
140
- * Minimal DOM Event interface for interop.
178
+ * Minimal DOM Event interface for interoperability.
141
179
  */
142
180
  export interface DOMEventLike {
143
181
  type: string;
144
182
  detail?: unknown;
183
+ bubbles?: boolean;
184
+ cancelable?: boolean;
185
+ composed?: boolean;
186
+ defaultPrevented?: boolean;
145
187
  }
146
188
 
147
189
  /**
148
- * Minimal DOM EventTarget interface for interop.
190
+ * Minimal DOM EventTarget interface for interoperability.
149
191
  */
150
192
  export interface DOMEventTargetLike {
151
193
  addEventListener(type: string, listener: (event: DOMEventLike) => void): void;
@@ -157,9 +199,14 @@ export interface DOMEventTargetLike {
157
199
  * Internal listener record type.
158
200
  */
159
201
  export type Listener<E> = {
160
- fn: (event: EmissionEvent<E>) => void | Promise<void>;
161
- once?: boolean;
162
- signal?: MinimalAbortSignal;
202
+ type: string;
203
+ original: EventListenerLike<EmissionEvent<E>>;
204
+ callback: (event: EmissionEvent<E>) => void | Promise<void>;
205
+ capture: boolean;
206
+ passive: boolean;
207
+ once: boolean;
208
+ signal?: MinimalAbortSignal | null;
209
+ removed: boolean;
163
210
  abortHandler?: () => void;
164
211
  };
165
212
 
@@ -180,12 +227,8 @@ export type WildcardListener<E extends Record<string, unknown>> = {
180
227
  export interface OnOptions extends AddEventListenerOptionsLike {
181
228
  /** Listen for an "error" event and send it to the observer's error method. */
182
229
  receiveError?: boolean;
183
- /** Member indicates that the callback will not cancel the event. */
184
- passive?: boolean;
185
230
  /** Handler function called before the event is dispatched to observers. */
186
231
  handler?: (event: EmissionEvent<unknown>) => void;
187
- /** Member indicates that the Observable will complete after one event. */
188
- once?: boolean;
189
232
  }
190
233
 
191
234
  /**
@@ -196,38 +239,40 @@ export interface OnOptions extends AddEventListenerOptionsLike {
196
239
  export interface EventTargetLike<E extends Record<string, any>> {
197
240
  addEventListener: <K extends keyof E & string>(
198
241
  type: K,
199
- listener: (event: EmissionEvent<E[K]>) => void | Promise<void>,
200
- options?: AddEventListenerOptionsLike,
242
+ listener: EventListenerLike<EmissionEvent<E[K], K>> | null,
243
+ options?: AddEventListenerOptionsLike | boolean,
201
244
  ) => () => void;
202
245
  removeEventListener: <K extends keyof E & string>(
203
246
  type: K,
204
- listener: (event: EmissionEvent<E[K]>) => void | Promise<void>,
247
+ listener: EventListenerLike<EmissionEvent<E[K], K>> | null,
248
+ options?: EventListenerOptionsLike | boolean,
205
249
  ) => void;
206
- dispatchEvent: <K extends keyof E & string>(event: EmissionEvent<E[K]>) => boolean;
250
+ dispatchEvent: <K extends keyof E & string>(
251
+ event: DispatchEventInput<E[K], K> | DOMEventLike,
252
+ ) => boolean;
207
253
  clear: () => void;
208
254
 
209
255
  // Ergonomics
210
256
  on: <K extends keyof E & string>(
211
257
  type: K,
212
258
  options?: OnOptions | boolean,
213
- ) => ObservableLike<EmissionEvent<E[K]>>;
259
+ ) => ObservableLike<EmissionEvent<E[K], K>>;
214
260
  once: <K extends keyof E & string>(
215
261
  type: K,
216
- listener: (event: EmissionEvent<E[K]>) => void | Promise<void>,
217
- options?: Omit<AddEventListenerOptionsLike, 'once'>,
262
+ listener: EventListenerLike<EmissionEvent<E[K], K>> | null,
263
+ options?: Omit<AddEventListenerOptionsLike, 'once'> | boolean,
218
264
  ) => () => void;
219
265
  removeAllListeners: <K extends keyof E & string>(type?: K) => void;
220
266
  /**
221
267
  * Pipe events from this emitter to another target.
222
- * Note: Only forwards events for types that have listeners when pipe() is called.
223
- * Events for types registered after piping won't be forwarded automatically.
268
+ * Forwards all events. If mapFn returns null, the event is skipped.
224
269
  */
225
270
  // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Generic constraint requires any
226
271
  pipe: <T extends Record<string, any>>(
227
272
  target: EventTargetLike<T>,
228
273
  mapFn?: <K extends keyof E & string>(
229
- event: EmissionEvent<E[K]>,
230
- ) => EmissionEvent<T[keyof T & string]> | null,
274
+ event: EmissionEvent<E[K], K>,
275
+ ) => DispatchEventInput<T[keyof T & string], keyof T & string> | null,
231
276
  ) => () => void;
232
277
  complete: () => void;
233
278
  readonly completed: boolean;
@@ -243,12 +288,12 @@ export interface EventTargetLike<E extends Record<string, any>> {
243
288
  listener: (event: WildcardEvent<E>) => void | Promise<void>,
244
289
  ) => void;
245
290
 
246
- // Observable interop
291
+ // Observable interoperability
247
292
  subscribe: <K extends keyof E & string>(
248
293
  type: K,
249
294
  observerOrNext?:
250
- | Observer<EmissionEvent<E[K]>>
251
- | ((value: EmissionEvent<E[K]>) => void),
295
+ | Observer<EmissionEvent<E[K], K>>
296
+ | ((value: EmissionEvent<E[K], K>) => void),
252
297
  error?: (err: unknown) => void,
253
298
  complete?: () => void,
254
299
  ) => Subscription;
@@ -258,5 +303,5 @@ export interface EventTargetLike<E extends Record<string, any>> {
258
303
  events: <K extends keyof E & string>(
259
304
  type: K,
260
305
  options?: AsyncIteratorOptions,
261
- ) => AsyncIterableIterator<EmissionEvent<E[K]>>;
306
+ ) => AsyncIterableIterator<EmissionEvent<E[K], K>>;
262
307
  }
@@ -1 +0,0 @@
1
- {"version":3,"file":"interop.d.ts","sourceRoot":"","sources":["../src/interop.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAEV,kBAAkB,EAElB,eAAe,EACf,cAAc,EACf,MAAM,SAAS,CAAC;AAEjB;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,oBAAoB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACpE,MAAM,EAAE,eAAe,CAAC,CAAC,CAAC,EAC1B,MAAM,EAAE,kBAAkB,EAC1B,OAAO,CAAC,EAAE,cAAc,GACvB,MAAM,IAAI,CAeZ;AAED;;GAEG;AACH,MAAM,WAAW,sBAAuB,SAAQ,cAAc;IAC5D;;;OAGG;IACH,eAAe,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;CAC1D;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4DG;AACH,wBAAgB,eAAe,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/D,SAAS,EAAE,kBAAkB,EAC7B,UAAU,EAAE,KAAK,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC,EACnC,OAAO,CAAC,EAAE,sBAAsB,GAC/B,eAAe,CAAC,CAAC,CAAC,GAAG;IAAE,OAAO,EAAE,MAAM,IAAI,CAAA;CAAE,CAgE9C;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwDG;AACH,wBAAgB,IAAI,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACpD,MAAM,EAAE,eAAe,CAAC,CAAC,CAAC,EAC1B,MAAM,EAAE,eAAe,CAAC,CAAC,CAAC,EAC1B,OAAO,CAAC,EAAE,cAAc,GACvB,MAAM,IAAI,CAWZ"}