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.
- package/README.md +80 -24
- package/dist/event-emission.d.ts +13 -14
- package/dist/event-emission.d.ts.map +1 -1
- package/dist/factory.d.ts +1 -1
- package/dist/factory.d.ts.map +1 -1
- package/dist/index.cjs +474 -285
- package/dist/index.cjs.map +8 -9
- package/dist/index.d.ts +1 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +449 -278
- package/dist/index.js.map +8 -9
- package/dist/interoperability.cjs +1605 -0
- package/dist/interoperability.cjs.map +15 -0
- package/dist/{interop.d.ts → interoperability.d.ts} +2 -1
- package/dist/interoperability.d.ts.map +1 -0
- package/dist/interoperability.js +1555 -0
- package/dist/interoperability.js.map +15 -0
- package/dist/observable.cjs +286 -0
- package/dist/observable.cjs.map +11 -0
- package/dist/observable.js +253 -0
- package/dist/observable.js.map +11 -0
- package/dist/observe.cjs +344 -0
- package/dist/observe.cjs.map +10 -0
- package/dist/observe.d.ts +6 -1
- package/dist/observe.d.ts.map +1 -1
- package/dist/observe.js +313 -0
- package/dist/observe.js.map +10 -0
- package/dist/symbols.d.ts +1 -1
- package/dist/types.cjs +35 -0
- package/dist/types.cjs.map +9 -0
- package/dist/types.d.ts +60 -25
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +3 -0
- package/dist/types.js.map +9 -0
- package/package.json +25 -1
- package/src/event-emission.ts +26 -20
- package/src/factory.ts +538 -218
- package/src/index.ts +4 -33
- package/src/{interop.ts → interoperability.ts} +24 -6
- package/src/observe.ts +54 -17
- package/src/symbols.ts +1 -1
- package/src/types.ts +75 -30
- 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
|
-
|
|
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
|
-
//
|
|
47
|
-
const
|
|
48
|
-
|
|
49
|
-
|
|
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
|
|
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:
|
|
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
|
-
|
|
165
|
-
|
|
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
|
|
177
|
+
if (!path || isArray) {
|
|
178
|
+
return rootClone;
|
|
170
179
|
}
|
|
171
180
|
|
|
172
181
|
const parts = path.split('.');
|
|
173
182
|
|
|
174
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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:
|
|
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
|
-
|
|
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
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:
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
161
|
-
|
|
162
|
-
|
|
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:
|
|
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:
|
|
247
|
+
listener: EventListenerLike<EmissionEvent<E[K], K>> | null,
|
|
248
|
+
options?: EventListenerOptionsLike | boolean,
|
|
205
249
|
) => void;
|
|
206
|
-
dispatchEvent: <K extends keyof E & string>(
|
|
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:
|
|
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
|
-
*
|
|
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
|
-
) =>
|
|
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
|
|
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
|
}
|
package/dist/interop.d.ts.map
DELETED
|
@@ -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"}
|