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/dist/index.js
CHANGED
|
@@ -4,13 +4,7 @@ var SymbolObservable = typeof Symbol === "function" && Symbol.observable || Symb
|
|
|
4
4
|
if (typeof Symbol === "function") {
|
|
5
5
|
Symbol.observable = SymbolObservable;
|
|
6
6
|
}
|
|
7
|
-
|
|
8
|
-
class BufferOverflowError extends Error {
|
|
9
|
-
constructor(eventType, bufferSize) {
|
|
10
|
-
super(`Buffer overflow for event type "${eventType}" (max: ${bufferSize})`);
|
|
11
|
-
this.name = "BufferOverflowError";
|
|
12
|
-
}
|
|
13
|
-
}
|
|
7
|
+
|
|
14
8
|
// src/observable.ts
|
|
15
9
|
function getMethod(obj, key) {
|
|
16
10
|
if (obj === null || obj === undefined)
|
|
@@ -277,17 +271,13 @@ function isArrayMutator(prop) {
|
|
|
277
271
|
return typeof prop === "string" && ARRAY_MUTATORS.has(prop);
|
|
278
272
|
}
|
|
279
273
|
function cloneAlongPath(obj, path) {
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
return Array.isArray(obj) ? [...obj] : { ...obj };
|
|
274
|
+
const isArray = Array.isArray(obj);
|
|
275
|
+
const rootClone = isArray ? [...obj] : { ...obj };
|
|
276
|
+
if (!path || isArray) {
|
|
277
|
+
return rootClone;
|
|
285
278
|
}
|
|
286
279
|
const parts = path.split(".");
|
|
287
|
-
|
|
288
|
-
return [...obj];
|
|
289
|
-
}
|
|
290
|
-
const result = { ...obj };
|
|
280
|
+
const result = rootClone;
|
|
291
281
|
let current = result;
|
|
292
282
|
for (let i = 0;i < parts.length; i++) {
|
|
293
283
|
const key = parts[i];
|
|
@@ -303,13 +293,19 @@ function cloneAlongPath(obj, path) {
|
|
|
303
293
|
}
|
|
304
294
|
return result;
|
|
305
295
|
}
|
|
306
|
-
function cloneForComparison(obj, strategy, changedPath) {
|
|
296
|
+
function cloneForComparison(obj, strategy, changedPath, deepClone) {
|
|
307
297
|
if (obj === null || typeof obj !== "object")
|
|
308
298
|
return obj;
|
|
309
299
|
switch (strategy) {
|
|
310
300
|
case "shallow":
|
|
311
301
|
return Array.isArray(obj) ? [...obj] : { ...obj };
|
|
312
302
|
case "deep":
|
|
303
|
+
if (deepClone) {
|
|
304
|
+
return deepClone(obj);
|
|
305
|
+
}
|
|
306
|
+
if (typeof structuredClone !== "function") {
|
|
307
|
+
throw new Error("structuredClone is not available in this runtime; provide observe.deepClone, or use cloneStrategy 'path' or 'shallow'.");
|
|
308
|
+
}
|
|
313
309
|
return structuredClone(obj);
|
|
314
310
|
case "path":
|
|
315
311
|
return cloneAlongPath(obj, changedPath);
|
|
@@ -357,7 +353,7 @@ function getContextRegistry(target) {
|
|
|
357
353
|
function createArrayMethodInterceptor(array, method, path, context) {
|
|
358
354
|
const original = array[method];
|
|
359
355
|
return function(...args) {
|
|
360
|
-
const previousState = cloneForComparison(context.originalRoot, context.options.cloneStrategy, path);
|
|
356
|
+
const previousState = cloneForComparison(context.originalRoot, context.options.cloneStrategy, path, context.options.deepClone);
|
|
361
357
|
const previousItems = [...array];
|
|
362
358
|
const result = original.apply(this, args);
|
|
363
359
|
const { added, removed } = computeArrayDiff(method, previousItems, array, args);
|
|
@@ -429,7 +425,7 @@ function createObservableProxyInternal(target, path, context) {
|
|
|
429
425
|
return true;
|
|
430
426
|
}
|
|
431
427
|
const propPath = path ? `${path}.${prop}` : prop;
|
|
432
|
-
const previousState = cloneForComparison(context.originalRoot, context.options.cloneStrategy, propPath);
|
|
428
|
+
const previousState = cloneForComparison(context.originalRoot, context.options.cloneStrategy, propPath, context.options.deepClone);
|
|
433
429
|
const success = Reflect.set(obj, prop, value, receiver);
|
|
434
430
|
if (success) {
|
|
435
431
|
context.eventTarget.dispatchEvent({
|
|
@@ -455,7 +451,7 @@ function createObservableProxyInternal(target, path, context) {
|
|
|
455
451
|
return Reflect.deleteProperty(obj, prop);
|
|
456
452
|
}
|
|
457
453
|
const propPath = path ? `${path}.${String(prop)}` : String(prop);
|
|
458
|
-
const previousState = cloneForComparison(context.originalRoot, context.options.cloneStrategy, propPath);
|
|
454
|
+
const previousState = cloneForComparison(context.originalRoot, context.options.cloneStrategy, propPath, context.options.deepClone);
|
|
459
455
|
const success = Reflect.deleteProperty(obj, prop);
|
|
460
456
|
if (success) {
|
|
461
457
|
context.eventTarget.dispatchEvent({
|
|
@@ -488,6 +484,8 @@ function isEventTarget(obj) {
|
|
|
488
484
|
}
|
|
489
485
|
function setupEventForwarding(source, target) {
|
|
490
486
|
const handlers = new Map;
|
|
487
|
+
const sourceAddEventListener = source.addEventListener.bind(source);
|
|
488
|
+
const sourceRemoveEventListener = source.removeEventListener.bind(source);
|
|
491
489
|
const forwardHandler = (type) => (event) => {
|
|
492
490
|
const detail = event.detail ?? event;
|
|
493
491
|
target.dispatchEvent({
|
|
@@ -500,7 +498,7 @@ function setupEventForwarding(source, target) {
|
|
|
500
498
|
if (!handlers.has(type) && type !== "update" && !type.startsWith("update:")) {
|
|
501
499
|
const handler = forwardHandler(type);
|
|
502
500
|
handlers.set(type, handler);
|
|
503
|
-
|
|
501
|
+
sourceAddEventListener(type, handler);
|
|
504
502
|
}
|
|
505
503
|
return originalAddEventListener(type, listener, options);
|
|
506
504
|
};
|
|
@@ -508,7 +506,7 @@ function setupEventForwarding(source, target) {
|
|
|
508
506
|
return () => {
|
|
509
507
|
target.addEventListener = originalAddEventListener;
|
|
510
508
|
for (const [type, handler] of handlers) {
|
|
511
|
-
|
|
509
|
+
sourceRemoveEventListener(type, handler);
|
|
512
510
|
}
|
|
513
511
|
handlers.clear();
|
|
514
512
|
};
|
|
@@ -525,7 +523,8 @@ function getOriginal(proxy) {
|
|
|
525
523
|
function createObservableProxy(target, eventTarget, options) {
|
|
526
524
|
const resolvedOptions = {
|
|
527
525
|
deep: options?.deep ?? true,
|
|
528
|
-
cloneStrategy: options?.cloneStrategy ?? "path"
|
|
526
|
+
cloneStrategy: options?.cloneStrategy ?? "path",
|
|
527
|
+
deepClone: options?.deepClone
|
|
529
528
|
};
|
|
530
529
|
const context = {
|
|
531
530
|
eventTarget,
|
|
@@ -534,21 +533,36 @@ function createObservableProxy(target, eventTarget, options) {
|
|
|
534
533
|
};
|
|
535
534
|
const proxy = createObservableProxyInternal(target, "", context);
|
|
536
535
|
if (isEventTarget(target)) {
|
|
537
|
-
setupEventForwarding(target, eventTarget);
|
|
536
|
+
const cleanupForwarding = setupEventForwarding(target, eventTarget);
|
|
537
|
+
const maybeComplete = eventTarget.complete;
|
|
538
|
+
if (typeof maybeComplete === "function") {
|
|
539
|
+
const originalComplete = maybeComplete.bind(eventTarget);
|
|
540
|
+
let cleaned = false;
|
|
541
|
+
eventTarget.complete = () => {
|
|
542
|
+
if (!cleaned) {
|
|
543
|
+
cleaned = true;
|
|
544
|
+
cleanupForwarding();
|
|
545
|
+
}
|
|
546
|
+
return originalComplete();
|
|
547
|
+
};
|
|
548
|
+
}
|
|
538
549
|
}
|
|
539
550
|
return proxy;
|
|
540
551
|
}
|
|
541
|
-
|
|
552
|
+
// src/errors.ts
|
|
553
|
+
class BufferOverflowError extends Error {
|
|
554
|
+
constructor(eventType, bufferSize) {
|
|
555
|
+
super(`Buffer overflow for event type "${eventType}" (max: ${bufferSize})`);
|
|
556
|
+
this.name = "BufferOverflowError";
|
|
557
|
+
}
|
|
558
|
+
}
|
|
542
559
|
// src/factory.ts
|
|
543
560
|
function matchesWildcard(eventType, pattern) {
|
|
544
561
|
if (pattern === "*")
|
|
545
562
|
return true;
|
|
546
|
-
|
|
547
|
-
const namespace = pattern.slice(0, -2);
|
|
548
|
-
return eventType.startsWith(namespace + ":");
|
|
549
|
-
}
|
|
550
|
-
return false;
|
|
563
|
+
return pattern.endsWith(":*") && eventType.startsWith(pattern.slice(0, -2) + ":");
|
|
551
564
|
}
|
|
565
|
+
var EVENT_STATE = Symbol("event-emission:event-state");
|
|
552
566
|
function createEventTarget(targetOrOpts, opts) {
|
|
553
567
|
if (opts?.observe === true && targetOrOpts && typeof targetOrOpts === "object") {
|
|
554
568
|
const target = targetOrOpts;
|
|
@@ -557,7 +571,8 @@ function createEventTarget(targetOrOpts, opts) {
|
|
|
557
571
|
});
|
|
558
572
|
const proxy = createObservableProxy(target, eventTarget, {
|
|
559
573
|
deep: opts.deep,
|
|
560
|
-
cloneStrategy: opts.cloneStrategy
|
|
574
|
+
cloneStrategy: opts.cloneStrategy,
|
|
575
|
+
deepClone: opts.deepClone
|
|
561
576
|
});
|
|
562
577
|
const methodNames = [
|
|
563
578
|
"addEventListener",
|
|
@@ -597,38 +612,202 @@ function createEventTargetInternal(opts) {
|
|
|
597
612
|
const wildcardListeners = new Set;
|
|
598
613
|
let isCompleted = false;
|
|
599
614
|
const completionCallbacks = new Set;
|
|
600
|
-
const
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
615
|
+
const now = () => typeof globalThis.performance?.now === "function" ? globalThis.performance.now() : Date.now();
|
|
616
|
+
const initializeEventState = (state, type, bubbles, cancelable) => {
|
|
617
|
+
state.initializedFlag = true;
|
|
618
|
+
state.stopPropagationFlag = false;
|
|
619
|
+
state.stopImmediatePropagationFlag = false;
|
|
620
|
+
state.canceledFlag = false;
|
|
621
|
+
state.isTrusted = false;
|
|
622
|
+
state.target = null;
|
|
623
|
+
state.currentTarget = null;
|
|
624
|
+
state.eventPhase = 0;
|
|
625
|
+
state.type = type;
|
|
626
|
+
state.bubbles = bubbles;
|
|
627
|
+
state.cancelable = cancelable;
|
|
628
|
+
};
|
|
629
|
+
const setCanceledFlag = (state) => {
|
|
630
|
+
if (state.cancelable && !state.inPassiveListenerFlag) {
|
|
631
|
+
state.canceledFlag = true;
|
|
632
|
+
}
|
|
633
|
+
};
|
|
634
|
+
const createEvent = (type, detail, init) => {
|
|
635
|
+
const state = {
|
|
636
|
+
dispatchFlag: false,
|
|
637
|
+
initializedFlag: true,
|
|
638
|
+
stopPropagationFlag: false,
|
|
639
|
+
stopImmediatePropagationFlag: false,
|
|
640
|
+
canceledFlag: false,
|
|
641
|
+
inPassiveListenerFlag: false,
|
|
642
|
+
composedFlag: Boolean(init?.composed),
|
|
643
|
+
eventPhase: init?.eventPhase ?? 0,
|
|
644
|
+
currentTarget: init?.currentTarget ?? init?.target ?? null,
|
|
645
|
+
target: init?.target ?? null,
|
|
646
|
+
timeStamp: init?.timeStamp ?? now(),
|
|
647
|
+
path: [],
|
|
648
|
+
type,
|
|
649
|
+
bubbles: Boolean(init?.bubbles),
|
|
650
|
+
cancelable: Boolean(init?.cancelable),
|
|
651
|
+
isTrusted: false
|
|
616
652
|
};
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
653
|
+
const event = { detail };
|
|
654
|
+
Object.defineProperties(event, {
|
|
655
|
+
type: {
|
|
656
|
+
get: () => state.type,
|
|
657
|
+
enumerable: true,
|
|
658
|
+
configurable: true
|
|
659
|
+
},
|
|
660
|
+
bubbles: {
|
|
661
|
+
get: () => state.bubbles,
|
|
662
|
+
enumerable: true,
|
|
663
|
+
configurable: true
|
|
664
|
+
},
|
|
665
|
+
cancelable: {
|
|
666
|
+
get: () => state.cancelable,
|
|
667
|
+
enumerable: true,
|
|
668
|
+
configurable: true
|
|
669
|
+
},
|
|
670
|
+
cancelBubble: {
|
|
671
|
+
get: () => state.stopPropagationFlag,
|
|
672
|
+
set: (value) => {
|
|
673
|
+
if (value)
|
|
674
|
+
state.stopPropagationFlag = true;
|
|
675
|
+
},
|
|
676
|
+
enumerable: true,
|
|
677
|
+
configurable: true
|
|
678
|
+
},
|
|
679
|
+
composed: {
|
|
680
|
+
get: () => state.composedFlag,
|
|
681
|
+
enumerable: true,
|
|
682
|
+
configurable: true
|
|
683
|
+
},
|
|
684
|
+
currentTarget: {
|
|
685
|
+
get: () => state.currentTarget,
|
|
686
|
+
enumerable: true,
|
|
687
|
+
configurable: true
|
|
688
|
+
},
|
|
689
|
+
defaultPrevented: {
|
|
690
|
+
get: () => state.canceledFlag,
|
|
691
|
+
enumerable: true,
|
|
692
|
+
configurable: true
|
|
693
|
+
},
|
|
694
|
+
eventPhase: {
|
|
695
|
+
get: () => state.eventPhase,
|
|
696
|
+
enumerable: true,
|
|
697
|
+
configurable: true
|
|
698
|
+
},
|
|
699
|
+
isTrusted: {
|
|
700
|
+
get: () => state.isTrusted,
|
|
701
|
+
enumerable: true,
|
|
702
|
+
configurable: true
|
|
703
|
+
},
|
|
704
|
+
returnValue: {
|
|
705
|
+
get: () => !state.canceledFlag,
|
|
706
|
+
set: (value) => {
|
|
707
|
+
if (value === false)
|
|
708
|
+
setCanceledFlag(state);
|
|
709
|
+
},
|
|
710
|
+
enumerable: true,
|
|
711
|
+
configurable: true
|
|
712
|
+
},
|
|
713
|
+
srcElement: {
|
|
714
|
+
get: () => state.target,
|
|
715
|
+
enumerable: true,
|
|
716
|
+
configurable: true
|
|
717
|
+
},
|
|
718
|
+
target: {
|
|
719
|
+
get: () => state.target,
|
|
720
|
+
enumerable: true,
|
|
721
|
+
configurable: true
|
|
722
|
+
},
|
|
723
|
+
timeStamp: {
|
|
724
|
+
get: () => state.timeStamp,
|
|
725
|
+
enumerable: true,
|
|
726
|
+
configurable: true
|
|
727
|
+
},
|
|
728
|
+
composedPath: {
|
|
729
|
+
value: () => state.path.map((entry) => entry.invocationTarget),
|
|
730
|
+
enumerable: true,
|
|
731
|
+
configurable: true
|
|
732
|
+
},
|
|
733
|
+
initEvent: {
|
|
734
|
+
value: (newType, bubbles = false, cancelable = false) => {
|
|
735
|
+
if (state.dispatchFlag)
|
|
736
|
+
return;
|
|
737
|
+
initializeEventState(state, newType, Boolean(bubbles), Boolean(cancelable));
|
|
738
|
+
},
|
|
739
|
+
enumerable: true,
|
|
740
|
+
configurable: true
|
|
741
|
+
},
|
|
620
742
|
preventDefault: {
|
|
621
|
-
value:
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
743
|
+
value: () => setCanceledFlag(state),
|
|
744
|
+
enumerable: true,
|
|
745
|
+
configurable: true
|
|
746
|
+
},
|
|
747
|
+
stopImmediatePropagation: {
|
|
748
|
+
value: () => {
|
|
749
|
+
state.stopPropagationFlag = true;
|
|
750
|
+
state.stopImmediatePropagationFlag = true;
|
|
627
751
|
},
|
|
628
752
|
enumerable: true,
|
|
629
753
|
configurable: true
|
|
754
|
+
},
|
|
755
|
+
stopPropagation: {
|
|
756
|
+
value: () => {
|
|
757
|
+
state.stopPropagationFlag = true;
|
|
758
|
+
},
|
|
759
|
+
enumerable: true,
|
|
760
|
+
configurable: true
|
|
761
|
+
},
|
|
762
|
+
NONE: { value: 0, enumerable: true, configurable: true },
|
|
763
|
+
CAPTURING_PHASE: { value: 1, enumerable: true, configurable: true },
|
|
764
|
+
AT_TARGET: { value: 2, enumerable: true, configurable: true },
|
|
765
|
+
BUBBLING_PHASE: { value: 3, enumerable: true, configurable: true },
|
|
766
|
+
[EVENT_STATE]: {
|
|
767
|
+
value: state,
|
|
768
|
+
enumerable: false,
|
|
769
|
+
configurable: false
|
|
630
770
|
}
|
|
631
771
|
});
|
|
772
|
+
return event;
|
|
773
|
+
};
|
|
774
|
+
const getEventState = (event) => event[EVENT_STATE];
|
|
775
|
+
const normalizeAddListenerOptions = (options) => {
|
|
776
|
+
if (typeof options === "boolean") {
|
|
777
|
+
return {
|
|
778
|
+
capture: options,
|
|
779
|
+
passive: false,
|
|
780
|
+
once: false,
|
|
781
|
+
signal: null
|
|
782
|
+
};
|
|
783
|
+
}
|
|
784
|
+
return {
|
|
785
|
+
capture: Boolean(options?.capture),
|
|
786
|
+
passive: Boolean(options?.passive),
|
|
787
|
+
once: Boolean(options?.once),
|
|
788
|
+
signal: options?.signal ?? null
|
|
789
|
+
};
|
|
790
|
+
};
|
|
791
|
+
const normalizeCaptureOption = (options) => {
|
|
792
|
+
if (typeof options === "boolean")
|
|
793
|
+
return options;
|
|
794
|
+
return Boolean(options?.capture);
|
|
795
|
+
};
|
|
796
|
+
const removeListenerRecord = (type, record) => {
|
|
797
|
+
if (record.removed)
|
|
798
|
+
return;
|
|
799
|
+
record.removed = true;
|
|
800
|
+
const list = listeners.get(type);
|
|
801
|
+
if (list) {
|
|
802
|
+
const idx = list.indexOf(record);
|
|
803
|
+
if (idx >= 0)
|
|
804
|
+
list.splice(idx, 1);
|
|
805
|
+
if (list.length === 0)
|
|
806
|
+
listeners.delete(type);
|
|
807
|
+
}
|
|
808
|
+
if (record.signal && record.abortHandler) {
|
|
809
|
+
record.signal.removeEventListener("abort", record.abortHandler);
|
|
810
|
+
}
|
|
632
811
|
};
|
|
633
812
|
const handleListenerError = (eventType, error2) => {
|
|
634
813
|
if (eventType === "error")
|
|
@@ -638,28 +817,27 @@ function createEventTargetInternal(opts) {
|
|
|
638
817
|
return;
|
|
639
818
|
}
|
|
640
819
|
const errorListeners = listeners.get("error");
|
|
641
|
-
if (errorListeners && errorListeners.
|
|
642
|
-
|
|
643
|
-
for (const rec of Array.from(errorListeners)) {
|
|
644
|
-
try {
|
|
645
|
-
const fn = rec.fn;
|
|
646
|
-
fn(errorEvent);
|
|
647
|
-
} catch {}
|
|
648
|
-
if (rec.once)
|
|
649
|
-
errorListeners.delete(rec);
|
|
650
|
-
}
|
|
820
|
+
if (errorListeners && errorListeners.length > 0) {
|
|
821
|
+
dispatchEvent({ type: "error", detail: error2 });
|
|
651
822
|
} else {
|
|
652
823
|
throw error2;
|
|
653
824
|
}
|
|
654
825
|
};
|
|
655
|
-
const notifyWildcardListeners = (eventType,
|
|
826
|
+
const notifyWildcardListeners = (eventType, event) => {
|
|
656
827
|
if (wildcardListeners.size === 0)
|
|
657
828
|
return;
|
|
658
829
|
for (const rec of Array.from(wildcardListeners)) {
|
|
659
830
|
if (!matchesWildcard(eventType, rec.pattern))
|
|
660
831
|
continue;
|
|
661
|
-
const
|
|
662
|
-
|
|
832
|
+
const baseEvent = createEvent(rec.pattern, event.detail, {
|
|
833
|
+
target,
|
|
834
|
+
currentTarget: target,
|
|
835
|
+
eventPhase: 2,
|
|
836
|
+
bubbles: event.bubbles,
|
|
837
|
+
cancelable: event.cancelable,
|
|
838
|
+
composed: event.composed
|
|
839
|
+
});
|
|
840
|
+
const wildcardEvent = Object.defineProperties(baseEvent, {
|
|
663
841
|
originalType: { value: eventType, enumerable: true, configurable: true }
|
|
664
842
|
});
|
|
665
843
|
try {
|
|
@@ -682,36 +860,46 @@ function createEventTargetInternal(opts) {
|
|
|
682
860
|
if (rec.once)
|
|
683
861
|
wildcardListeners.delete(rec);
|
|
684
862
|
}
|
|
863
|
+
const state = getEventState(wildcardEvent);
|
|
864
|
+
if (state?.stopImmediatePropagationFlag || state?.stopPropagationFlag) {
|
|
865
|
+
break;
|
|
866
|
+
}
|
|
685
867
|
}
|
|
686
868
|
};
|
|
687
869
|
const addEventListener = (type, listener, options) => {
|
|
688
|
-
if (isCompleted) {
|
|
870
|
+
if (isCompleted || !listener) {
|
|
689
871
|
return () => {};
|
|
690
872
|
}
|
|
691
|
-
const
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
};
|
|
697
|
-
let set = listeners.get(type);
|
|
698
|
-
if (!set) {
|
|
699
|
-
set = new Set;
|
|
700
|
-
listeners.set(type, set);
|
|
873
|
+
const { capture, passive, once, signal } = normalizeAddListenerOptions(options);
|
|
874
|
+
let list = listeners.get(type);
|
|
875
|
+
if (!list) {
|
|
876
|
+
list = [];
|
|
877
|
+
listeners.set(type, list);
|
|
701
878
|
}
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
setNow?.delete(record);
|
|
706
|
-
if (record.signal && record.abortHandler) {
|
|
707
|
-
record.signal.removeEventListener("abort", record.abortHandler);
|
|
879
|
+
for (const existing of list) {
|
|
880
|
+
if (existing.original === listener && existing.capture === capture) {
|
|
881
|
+
return () => removeEventListener(type, listener, options);
|
|
708
882
|
}
|
|
883
|
+
}
|
|
884
|
+
const original = listener;
|
|
885
|
+
const callback = typeof listener === "function" ? listener : (event) => listener.handleEvent(event);
|
|
886
|
+
const record = {
|
|
887
|
+
type,
|
|
888
|
+
original,
|
|
889
|
+
callback,
|
|
890
|
+
capture,
|
|
891
|
+
passive,
|
|
892
|
+
once,
|
|
893
|
+
signal,
|
|
894
|
+
removed: false
|
|
709
895
|
};
|
|
710
|
-
|
|
711
|
-
|
|
896
|
+
list.push(record);
|
|
897
|
+
const unsubscribe2 = () => removeListenerRecord(type, record);
|
|
898
|
+
if (signal) {
|
|
899
|
+
const onAbort = () => removeListenerRecord(type, record);
|
|
712
900
|
record.abortHandler = onAbort;
|
|
713
|
-
|
|
714
|
-
if (
|
|
901
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
902
|
+
if (signal.aborted)
|
|
715
903
|
onAbort();
|
|
716
904
|
}
|
|
717
905
|
return unsubscribe2;
|
|
@@ -720,6 +908,11 @@ function createEventTargetInternal(opts) {
|
|
|
720
908
|
if (isCompleted)
|
|
721
909
|
return () => {};
|
|
722
910
|
const opts2 = options ?? {};
|
|
911
|
+
for (const existing of wildcardListeners) {
|
|
912
|
+
if (existing.pattern === pattern && existing.fn === listener) {
|
|
913
|
+
return () => removeWildcardListener(pattern, listener);
|
|
914
|
+
}
|
|
915
|
+
}
|
|
723
916
|
const record = {
|
|
724
917
|
fn: listener,
|
|
725
918
|
pattern,
|
|
@@ -743,31 +936,39 @@ function createEventTargetInternal(opts) {
|
|
|
743
936
|
return unsubscribe2;
|
|
744
937
|
};
|
|
745
938
|
const removeWildcardListener = (pattern, listener) => {
|
|
746
|
-
for (const record of wildcardListeners) {
|
|
939
|
+
for (const record of Array.from(wildcardListeners)) {
|
|
747
940
|
if (record.pattern === pattern && record.fn === listener) {
|
|
748
941
|
wildcardListeners.delete(record);
|
|
749
942
|
if (record.signal && record.abortHandler) {
|
|
750
943
|
record.signal.removeEventListener("abort", record.abortHandler);
|
|
751
944
|
}
|
|
752
|
-
break;
|
|
753
945
|
}
|
|
754
946
|
}
|
|
755
947
|
};
|
|
756
|
-
const
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
948
|
+
const invokeListeners = (eventType, event, phase, listenersSnapshot) => {
|
|
949
|
+
const state = getEventState(event);
|
|
950
|
+
if (!state || state.stopPropagationFlag)
|
|
951
|
+
return;
|
|
952
|
+
state.currentTarget = target;
|
|
953
|
+
state.target = target;
|
|
954
|
+
state.eventPhase = event.AT_TARGET;
|
|
955
|
+
for (const rec of listenersSnapshot) {
|
|
956
|
+
if (rec.removed)
|
|
957
|
+
continue;
|
|
958
|
+
if (phase === "capturing" && !rec.capture)
|
|
959
|
+
continue;
|
|
960
|
+
if (phase === "bubbling" && rec.capture)
|
|
961
|
+
continue;
|
|
962
|
+
if (rec.once)
|
|
963
|
+
removeListenerRecord(rec.type, rec);
|
|
964
|
+
if (rec.passive)
|
|
965
|
+
state.inPassiveListenerFlag = true;
|
|
765
966
|
try {
|
|
766
|
-
const res = rec.
|
|
967
|
+
const res = rec.callback.call(state.currentTarget, event);
|
|
767
968
|
if (res && typeof res.then === "function") {
|
|
768
969
|
res.catch((error2) => {
|
|
769
970
|
try {
|
|
770
|
-
handleListenerError(
|
|
971
|
+
handleListenerError(eventType, error2);
|
|
771
972
|
} catch (rethrown) {
|
|
772
973
|
queueMicrotask(() => {
|
|
773
974
|
throw rethrown;
|
|
@@ -776,36 +977,94 @@ function createEventTargetInternal(opts) {
|
|
|
776
977
|
});
|
|
777
978
|
}
|
|
778
979
|
} catch (error2) {
|
|
779
|
-
handleListenerError(
|
|
980
|
+
handleListenerError(eventType, error2);
|
|
780
981
|
} finally {
|
|
781
|
-
if (rec.
|
|
782
|
-
|
|
982
|
+
if (rec.passive)
|
|
983
|
+
state.inPassiveListenerFlag = false;
|
|
783
984
|
}
|
|
985
|
+
if (state.stopImmediatePropagationFlag)
|
|
986
|
+
break;
|
|
784
987
|
}
|
|
785
|
-
return true;
|
|
786
988
|
};
|
|
787
|
-
const
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
989
|
+
const dispatchEvent = (eventInput) => {
|
|
990
|
+
if (isCompleted)
|
|
991
|
+
return false;
|
|
992
|
+
let event;
|
|
993
|
+
let state;
|
|
994
|
+
if (eventInput && typeof eventInput === "object") {
|
|
995
|
+
state = getEventState(eventInput);
|
|
996
|
+
if (state) {
|
|
997
|
+
event = eventInput;
|
|
998
|
+
} else {
|
|
999
|
+
const input = eventInput;
|
|
1000
|
+
if (typeof input.type !== "string") {
|
|
1001
|
+
throw new TypeError("Event type must be a string");
|
|
796
1002
|
}
|
|
797
|
-
|
|
1003
|
+
event = createEvent(input.type, input.detail, {
|
|
1004
|
+
bubbles: input.bubbles,
|
|
1005
|
+
cancelable: input.cancelable,
|
|
1006
|
+
composed: input.composed,
|
|
1007
|
+
timeStamp: input.timeStamp
|
|
1008
|
+
});
|
|
1009
|
+
state = getEventState(event);
|
|
1010
|
+
}
|
|
1011
|
+
} else {
|
|
1012
|
+
throw new TypeError("dispatchEvent expects an event object");
|
|
1013
|
+
}
|
|
1014
|
+
const dispatchState = state ?? getEventState(event);
|
|
1015
|
+
if (dispatchState.dispatchFlag || !dispatchState.initializedFlag) {
|
|
1016
|
+
const message = "Failed to execute dispatchEvent: event is already being dispatched";
|
|
1017
|
+
if (typeof globalThis.DOMException === "function") {
|
|
1018
|
+
throw new globalThis.DOMException(message, "InvalidStateError");
|
|
1019
|
+
}
|
|
1020
|
+
const err = new Error(message);
|
|
1021
|
+
err.name = "InvalidStateError";
|
|
1022
|
+
throw err;
|
|
1023
|
+
}
|
|
1024
|
+
dispatchState.isTrusted = false;
|
|
1025
|
+
dispatchState.dispatchFlag = true;
|
|
1026
|
+
dispatchState.path = [
|
|
1027
|
+
{
|
|
1028
|
+
invocationTarget: target,
|
|
1029
|
+
invocationTargetInShadowTree: false,
|
|
1030
|
+
shadowAdjustedTarget: target,
|
|
1031
|
+
relatedTarget: null,
|
|
1032
|
+
touchTargets: [],
|
|
1033
|
+
rootOfClosedTree: false,
|
|
1034
|
+
slotInClosedTree: false
|
|
1035
|
+
}
|
|
1036
|
+
];
|
|
1037
|
+
notifyWildcardListeners(dispatchState.type, event);
|
|
1038
|
+
const list = listeners.get(dispatchState.type);
|
|
1039
|
+
const snapshot = list ? list.slice() : [];
|
|
1040
|
+
invokeListeners(dispatchState.type, event, "capturing", snapshot);
|
|
1041
|
+
invokeListeners(dispatchState.type, event, "bubbling", snapshot);
|
|
1042
|
+
dispatchState.eventPhase = event.NONE;
|
|
1043
|
+
dispatchState.currentTarget = null;
|
|
1044
|
+
dispatchState.path = [];
|
|
1045
|
+
dispatchState.dispatchFlag = false;
|
|
1046
|
+
dispatchState.stopPropagationFlag = false;
|
|
1047
|
+
dispatchState.stopImmediatePropagationFlag = false;
|
|
1048
|
+
return !dispatchState.canceledFlag;
|
|
1049
|
+
};
|
|
1050
|
+
const removeEventListener = (type, listener, options) => {
|
|
1051
|
+
if (!listener)
|
|
1052
|
+
return;
|
|
1053
|
+
const capture = normalizeCaptureOption(options);
|
|
1054
|
+
const list = listeners.get(type);
|
|
1055
|
+
if (!list)
|
|
1056
|
+
return;
|
|
1057
|
+
for (const record of [...list]) {
|
|
1058
|
+
if (record.original === listener && record.capture === capture) {
|
|
1059
|
+
removeListenerRecord(type, record);
|
|
798
1060
|
}
|
|
799
1061
|
}
|
|
800
1062
|
};
|
|
801
1063
|
const clear = () => {
|
|
802
|
-
for (const
|
|
803
|
-
for (const record of
|
|
804
|
-
|
|
805
|
-
record.signal.removeEventListener("abort", record.abortHandler);
|
|
806
|
-
}
|
|
1064
|
+
for (const [type, list] of Array.from(listeners.entries())) {
|
|
1065
|
+
for (const record of [...list]) {
|
|
1066
|
+
removeListenerRecord(type, record);
|
|
807
1067
|
}
|
|
808
|
-
set.clear();
|
|
809
1068
|
}
|
|
810
1069
|
listeners.clear();
|
|
811
1070
|
for (const record of wildcardListeners) {
|
|
@@ -819,7 +1078,7 @@ function createEventTargetInternal(opts) {
|
|
|
819
1078
|
return new Observable((observer) => {
|
|
820
1079
|
let opts2;
|
|
821
1080
|
if (typeof options === "boolean") {
|
|
822
|
-
opts2 = {
|
|
1081
|
+
opts2 = { capture: options };
|
|
823
1082
|
} else {
|
|
824
1083
|
opts2 = options ?? {};
|
|
825
1084
|
}
|
|
@@ -856,28 +1115,25 @@ function createEventTargetInternal(opts) {
|
|
|
856
1115
|
});
|
|
857
1116
|
};
|
|
858
1117
|
const onceMethod = (type, listener, options) => {
|
|
859
|
-
|
|
1118
|
+
if (typeof options === "boolean") {
|
|
1119
|
+
return addEventListener(type, listener, { capture: options, once: true });
|
|
1120
|
+
}
|
|
1121
|
+
return addEventListener(type, listener, { ...options ?? {}, once: true });
|
|
860
1122
|
};
|
|
861
1123
|
const removeAllListeners = (type) => {
|
|
862
1124
|
if (type !== undefined) {
|
|
863
|
-
const
|
|
864
|
-
if (
|
|
865
|
-
for (const record of
|
|
866
|
-
|
|
867
|
-
record.signal.removeEventListener("abort", record.abortHandler);
|
|
868
|
-
}
|
|
1125
|
+
const list = listeners.get(type);
|
|
1126
|
+
if (list) {
|
|
1127
|
+
for (const record of [...list]) {
|
|
1128
|
+
removeListenerRecord(type, record);
|
|
869
1129
|
}
|
|
870
|
-
set.clear();
|
|
871
1130
|
listeners.delete(type);
|
|
872
1131
|
}
|
|
873
1132
|
} else {
|
|
874
|
-
for (const
|
|
875
|
-
for (const record of
|
|
876
|
-
|
|
877
|
-
record.signal.removeEventListener("abort", record.abortHandler);
|
|
878
|
-
}
|
|
1133
|
+
for (const [eventType, list] of Array.from(listeners.entries())) {
|
|
1134
|
+
for (const record of [...list]) {
|
|
1135
|
+
removeListenerRecord(eventType, record);
|
|
879
1136
|
}
|
|
880
|
-
set.clear();
|
|
881
1137
|
}
|
|
882
1138
|
listeners.clear();
|
|
883
1139
|
for (const record of wildcardListeners) {
|
|
@@ -892,38 +1148,33 @@ function createEventTargetInternal(opts) {
|
|
|
892
1148
|
if (isCompleted) {
|
|
893
1149
|
return () => {};
|
|
894
1150
|
}
|
|
895
|
-
const
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
} else {
|
|
908
|
-
target2.dispatchEvent(event);
|
|
1151
|
+
const unsubscribe2 = addWildcardListener("*", (event) => {
|
|
1152
|
+
if (mapFn) {
|
|
1153
|
+
const mapped = mapFn(createEvent(event.originalType, event.detail, {
|
|
1154
|
+
target: target2,
|
|
1155
|
+
currentTarget: target2,
|
|
1156
|
+
eventPhase: 2,
|
|
1157
|
+
bubbles: event.bubbles,
|
|
1158
|
+
cancelable: event.cancelable,
|
|
1159
|
+
composed: event.composed
|
|
1160
|
+
}));
|
|
1161
|
+
if (mapped !== null) {
|
|
1162
|
+
target2.dispatchEvent(mapped);
|
|
909
1163
|
}
|
|
910
|
-
}
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
}
|
|
916
|
-
const completionUnsub = () => {
|
|
917
|
-
for (const unsub of unsubscribes) {
|
|
918
|
-
unsub();
|
|
1164
|
+
} else {
|
|
1165
|
+
target2.dispatchEvent({
|
|
1166
|
+
type: event.originalType,
|
|
1167
|
+
detail: event.detail
|
|
1168
|
+
});
|
|
919
1169
|
}
|
|
1170
|
+
});
|
|
1171
|
+
const completionUnsub = () => {
|
|
1172
|
+
unsubscribe2();
|
|
920
1173
|
};
|
|
921
1174
|
completionCallbacks.add(completionUnsub);
|
|
922
1175
|
return () => {
|
|
923
1176
|
completionCallbacks.delete(completionUnsub);
|
|
924
|
-
|
|
925
|
-
unsub();
|
|
926
|
-
}
|
|
1177
|
+
unsubscribe2();
|
|
927
1178
|
};
|
|
928
1179
|
};
|
|
929
1180
|
const complete2 = () => {
|
|
@@ -940,13 +1191,10 @@ function createEventTargetInternal(opts) {
|
|
|
940
1191
|
}
|
|
941
1192
|
}
|
|
942
1193
|
completionCallbacks.clear();
|
|
943
|
-
for (const
|
|
944
|
-
for (const record of
|
|
945
|
-
|
|
946
|
-
record.signal.removeEventListener("abort", record.abortHandler);
|
|
947
|
-
}
|
|
1194
|
+
for (const [eventType, list] of Array.from(listeners.entries())) {
|
|
1195
|
+
for (const record of [...list]) {
|
|
1196
|
+
removeListenerRecord(eventType, record);
|
|
948
1197
|
}
|
|
949
|
-
set.clear();
|
|
950
1198
|
}
|
|
951
1199
|
listeners.clear();
|
|
952
1200
|
for (const record of wildcardListeners) {
|
|
@@ -1029,7 +1277,14 @@ function createEventTargetInternal(opts) {
|
|
|
1029
1277
|
return;
|
|
1030
1278
|
}
|
|
1031
1279
|
const wildcardListener = (event) => {
|
|
1032
|
-
observer.next(
|
|
1280
|
+
observer.next(createEvent(event.originalType, event.detail, {
|
|
1281
|
+
target,
|
|
1282
|
+
currentTarget: target,
|
|
1283
|
+
eventPhase: 2,
|
|
1284
|
+
bubbles: event.bubbles,
|
|
1285
|
+
cancelable: event.cancelable,
|
|
1286
|
+
composed: event.composed
|
|
1287
|
+
}));
|
|
1033
1288
|
};
|
|
1034
1289
|
const unsubscribe2 = addWildcardListener("*", wildcardListener);
|
|
1035
1290
|
const onComplete = () => {
|
|
@@ -1069,19 +1324,26 @@ function createEventTargetInternal(opts) {
|
|
|
1069
1324
|
let resolve = null;
|
|
1070
1325
|
let done = false;
|
|
1071
1326
|
let hasOverflow = false;
|
|
1327
|
+
let onAbort = null;
|
|
1328
|
+
const cleanupAbortListener = () => {
|
|
1329
|
+
if (signal && onAbort) {
|
|
1330
|
+
signal.removeEventListener("abort", onAbort);
|
|
1331
|
+
}
|
|
1332
|
+
};
|
|
1072
1333
|
const unsub = addEventListener(type, (event) => {
|
|
1073
1334
|
if (done)
|
|
1074
1335
|
return;
|
|
1336
|
+
const typedEvent = event;
|
|
1075
1337
|
if (resolve) {
|
|
1076
1338
|
const r = resolve;
|
|
1077
1339
|
resolve = null;
|
|
1078
|
-
r({ value:
|
|
1340
|
+
r({ value: typedEvent, done: false });
|
|
1079
1341
|
} else {
|
|
1080
1342
|
if (buffer.length >= bufferSize && bufferSize !== Infinity) {
|
|
1081
1343
|
switch (overflowStrategy) {
|
|
1082
1344
|
case "drop-oldest":
|
|
1083
1345
|
buffer.shift();
|
|
1084
|
-
buffer.push(
|
|
1346
|
+
buffer.push(typedEvent);
|
|
1085
1347
|
break;
|
|
1086
1348
|
case "drop-latest":
|
|
1087
1349
|
break;
|
|
@@ -1090,15 +1352,17 @@ function createEventTargetInternal(opts) {
|
|
|
1090
1352
|
completionCallbacks.delete(onComplete);
|
|
1091
1353
|
done = true;
|
|
1092
1354
|
hasOverflow = true;
|
|
1355
|
+
cleanupAbortListener();
|
|
1093
1356
|
return;
|
|
1094
1357
|
}
|
|
1095
1358
|
} else {
|
|
1096
|
-
buffer.push(
|
|
1359
|
+
buffer.push(typedEvent);
|
|
1097
1360
|
}
|
|
1098
1361
|
}
|
|
1099
1362
|
});
|
|
1100
1363
|
const onComplete = () => {
|
|
1101
1364
|
done = true;
|
|
1365
|
+
cleanupAbortListener();
|
|
1102
1366
|
if (resolve) {
|
|
1103
1367
|
const r = resolve;
|
|
1104
1368
|
resolve = null;
|
|
@@ -1106,7 +1370,6 @@ function createEventTargetInternal(opts) {
|
|
|
1106
1370
|
}
|
|
1107
1371
|
};
|
|
1108
1372
|
completionCallbacks.add(onComplete);
|
|
1109
|
-
let onAbort = null;
|
|
1110
1373
|
if (signal) {
|
|
1111
1374
|
onAbort = () => {
|
|
1112
1375
|
done = true;
|
|
@@ -1130,26 +1393,22 @@ function createEventTargetInternal(opts) {
|
|
|
1130
1393
|
if (buffer.length > 0) {
|
|
1131
1394
|
return { value: buffer.shift(), done: false };
|
|
1132
1395
|
}
|
|
1133
|
-
if (hasOverflow) {
|
|
1134
|
-
hasOverflow = false;
|
|
1135
|
-
throw new BufferOverflowError(type, bufferSize);
|
|
1136
|
-
}
|
|
1137
|
-
if (done) {
|
|
1138
|
-
return { value: undefined, done: true };
|
|
1139
|
-
}
|
|
1140
1396
|
if (resolve !== null) {
|
|
1141
1397
|
return Promise.reject(new Error("Concurrent calls to next() are not supported on this async iterator"));
|
|
1142
1398
|
}
|
|
1143
1399
|
return new Promise((_resolve, _reject) => {
|
|
1144
|
-
if (done) {
|
|
1145
|
-
_resolve({ value: undefined, done: true });
|
|
1146
|
-
return;
|
|
1147
|
-
}
|
|
1148
1400
|
if (hasOverflow) {
|
|
1149
1401
|
hasOverflow = false;
|
|
1150
1402
|
_reject(new BufferOverflowError(type, bufferSize));
|
|
1151
1403
|
return;
|
|
1152
1404
|
}
|
|
1405
|
+
if (done) {
|
|
1406
|
+
_resolve({
|
|
1407
|
+
value: undefined,
|
|
1408
|
+
done: true
|
|
1409
|
+
});
|
|
1410
|
+
return;
|
|
1411
|
+
}
|
|
1153
1412
|
resolve = _resolve;
|
|
1154
1413
|
});
|
|
1155
1414
|
},
|
|
@@ -1162,9 +1421,7 @@ function createEventTargetInternal(opts) {
|
|
|
1162
1421
|
done = true;
|
|
1163
1422
|
completionCallbacks.delete(onComplete);
|
|
1164
1423
|
unsub();
|
|
1165
|
-
|
|
1166
|
-
signal.removeEventListener("abort", onAbort);
|
|
1167
|
-
}
|
|
1424
|
+
cleanupAbortListener();
|
|
1168
1425
|
return Promise.resolve({
|
|
1169
1426
|
value: undefined,
|
|
1170
1427
|
done: true
|
|
@@ -1197,83 +1454,6 @@ function createEventTargetInternal(opts) {
|
|
|
1197
1454
|
};
|
|
1198
1455
|
return target;
|
|
1199
1456
|
}
|
|
1200
|
-
// src/interop.ts
|
|
1201
|
-
function forwardToEventTarget(source, target, options) {
|
|
1202
|
-
const unsubscribe2 = source.addWildcardListener("*", (event) => {
|
|
1203
|
-
const domEvent = {
|
|
1204
|
-
type: event.originalType,
|
|
1205
|
-
detail: event.detail
|
|
1206
|
-
};
|
|
1207
|
-
target.dispatchEvent(domEvent);
|
|
1208
|
-
}, options);
|
|
1209
|
-
return unsubscribe2;
|
|
1210
|
-
}
|
|
1211
|
-
function fromEventTarget(domTarget, eventTypes, options) {
|
|
1212
|
-
const emitter = createEventTarget({
|
|
1213
|
-
onListenerError: options?.onListenerError
|
|
1214
|
-
});
|
|
1215
|
-
const handlers = new Map;
|
|
1216
|
-
for (const type of eventTypes) {
|
|
1217
|
-
const handler = (event) => {
|
|
1218
|
-
emitter.dispatchEvent({
|
|
1219
|
-
type,
|
|
1220
|
-
detail: event.detail ?? event
|
|
1221
|
-
});
|
|
1222
|
-
};
|
|
1223
|
-
handlers.set(type, handler);
|
|
1224
|
-
domTarget.addEventListener(type, handler);
|
|
1225
|
-
}
|
|
1226
|
-
let onAbort = null;
|
|
1227
|
-
if (options?.signal) {
|
|
1228
|
-
onAbort = () => {
|
|
1229
|
-
for (const [type, handler] of handlers) {
|
|
1230
|
-
domTarget.removeEventListener(type, handler);
|
|
1231
|
-
}
|
|
1232
|
-
handlers.clear();
|
|
1233
|
-
emitter.complete();
|
|
1234
|
-
};
|
|
1235
|
-
options.signal.addEventListener("abort", onAbort, { once: true });
|
|
1236
|
-
if (options.signal.aborted)
|
|
1237
|
-
onAbort();
|
|
1238
|
-
}
|
|
1239
|
-
return {
|
|
1240
|
-
addEventListener: emitter.addEventListener,
|
|
1241
|
-
removeEventListener: emitter.removeEventListener,
|
|
1242
|
-
dispatchEvent: emitter.dispatchEvent,
|
|
1243
|
-
clear: emitter.clear,
|
|
1244
|
-
once: emitter.once,
|
|
1245
|
-
removeAllListeners: emitter.removeAllListeners,
|
|
1246
|
-
pipe: emitter.pipe,
|
|
1247
|
-
addWildcardListener: emitter.addWildcardListener,
|
|
1248
|
-
removeWildcardListener: emitter.removeWildcardListener,
|
|
1249
|
-
on: emitter.on,
|
|
1250
|
-
subscribe: emitter.subscribe,
|
|
1251
|
-
toObservable: emitter.toObservable,
|
|
1252
|
-
complete: emitter.complete,
|
|
1253
|
-
get completed() {
|
|
1254
|
-
return emitter.completed;
|
|
1255
|
-
},
|
|
1256
|
-
events: emitter.events,
|
|
1257
|
-
destroy: () => {
|
|
1258
|
-
if (options?.signal && onAbort) {
|
|
1259
|
-
options.signal.removeEventListener("abort", onAbort);
|
|
1260
|
-
}
|
|
1261
|
-
for (const [type, handler] of handlers) {
|
|
1262
|
-
domTarget.removeEventListener(type, handler);
|
|
1263
|
-
}
|
|
1264
|
-
handlers.clear();
|
|
1265
|
-
emitter.complete();
|
|
1266
|
-
}
|
|
1267
|
-
};
|
|
1268
|
-
}
|
|
1269
|
-
function pipe(source, target, options) {
|
|
1270
|
-
return source.addWildcardListener("*", (event) => {
|
|
1271
|
-
target.dispatchEvent({
|
|
1272
|
-
type: event.originalType,
|
|
1273
|
-
detail: event.detail
|
|
1274
|
-
});
|
|
1275
|
-
}, options);
|
|
1276
|
-
}
|
|
1277
1457
|
// src/event-emission.ts
|
|
1278
1458
|
class EventEmission {
|
|
1279
1459
|
#target;
|
|
@@ -1283,8 +1463,8 @@ class EventEmission {
|
|
|
1283
1463
|
addEventListener(type, listener, options) {
|
|
1284
1464
|
return this.#target.addEventListener(type, listener, options);
|
|
1285
1465
|
}
|
|
1286
|
-
removeEventListener(type, listener) {
|
|
1287
|
-
this.#target.removeEventListener(type, listener);
|
|
1466
|
+
removeEventListener(type, listener, options) {
|
|
1467
|
+
this.#target.removeEventListener(type, listener, options);
|
|
1288
1468
|
}
|
|
1289
1469
|
dispatchEvent(event) {
|
|
1290
1470
|
return this.#target.dispatchEvent(event);
|
|
@@ -1343,19 +1523,10 @@ class EventEmission {
|
|
|
1343
1523
|
}
|
|
1344
1524
|
}
|
|
1345
1525
|
export {
|
|
1346
|
-
setupEventForwarding,
|
|
1347
|
-
pipe,
|
|
1348
|
-
isObserved,
|
|
1349
|
-
getOriginal,
|
|
1350
|
-
fromEventTarget,
|
|
1351
|
-
forwardToEventTarget,
|
|
1352
1526
|
createEventTarget,
|
|
1353
1527
|
SymbolObservable,
|
|
1354
|
-
PROXY_MARKER,
|
|
1355
|
-
Observable,
|
|
1356
|
-
ORIGINAL_TARGET,
|
|
1357
1528
|
EventEmission,
|
|
1358
1529
|
BufferOverflowError
|
|
1359
1530
|
};
|
|
1360
1531
|
|
|
1361
|
-
//# debugId=
|
|
1532
|
+
//# debugId=60621EDDB80DC90E64756E2164756E21
|