event-emission 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +158 -25
- package/dist/event-emission.d.ts +63 -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 +614 -291
- 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 +589 -284
- package/dist/index.js.map +8 -9
- package/dist/interoperability.cjs +1719 -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 +1669 -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 +73 -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 +140 -21
- package/src/factory.ts +686 -230
- package/src/index.ts +4 -33
- package/src/{interop.ts → interoperability.ts} +34 -6
- package/src/observe.ts +54 -17
- package/src/symbols.ts +1 -1
- package/src/types.ts +115 -33
- 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",
|
|
@@ -573,7 +588,17 @@ function createEventTarget(targetOrOpts, opts) {
|
|
|
573
588
|
"complete",
|
|
574
589
|
"subscribe",
|
|
575
590
|
"toObservable",
|
|
576
|
-
"events"
|
|
591
|
+
"events",
|
|
592
|
+
"emit",
|
|
593
|
+
"off",
|
|
594
|
+
"addListener",
|
|
595
|
+
"removeListener",
|
|
596
|
+
"prependListener",
|
|
597
|
+
"prependOnceListener",
|
|
598
|
+
"listeners",
|
|
599
|
+
"rawListeners",
|
|
600
|
+
"listenerCount",
|
|
601
|
+
"eventNames"
|
|
577
602
|
];
|
|
578
603
|
for (const name of methodNames) {
|
|
579
604
|
Object.defineProperty(proxy, name, {
|
|
@@ -597,38 +622,202 @@ function createEventTargetInternal(opts) {
|
|
|
597
622
|
const wildcardListeners = new Set;
|
|
598
623
|
let isCompleted = false;
|
|
599
624
|
const completionCallbacks = new Set;
|
|
600
|
-
const
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
625
|
+
const now = () => typeof globalThis.performance?.now === "function" ? globalThis.performance.now() : Date.now();
|
|
626
|
+
const initializeEventState = (state, type, bubbles, cancelable) => {
|
|
627
|
+
state.initializedFlag = true;
|
|
628
|
+
state.stopPropagationFlag = false;
|
|
629
|
+
state.stopImmediatePropagationFlag = false;
|
|
630
|
+
state.canceledFlag = false;
|
|
631
|
+
state.isTrusted = false;
|
|
632
|
+
state.target = null;
|
|
633
|
+
state.currentTarget = null;
|
|
634
|
+
state.eventPhase = 0;
|
|
635
|
+
state.type = type;
|
|
636
|
+
state.bubbles = bubbles;
|
|
637
|
+
state.cancelable = cancelable;
|
|
638
|
+
};
|
|
639
|
+
const setCanceledFlag = (state) => {
|
|
640
|
+
if (state.cancelable && !state.inPassiveListenerFlag) {
|
|
641
|
+
state.canceledFlag = true;
|
|
642
|
+
}
|
|
643
|
+
};
|
|
644
|
+
const createEvent = (type, detail, init) => {
|
|
645
|
+
const state = {
|
|
646
|
+
dispatchFlag: false,
|
|
647
|
+
initializedFlag: true,
|
|
648
|
+
stopPropagationFlag: false,
|
|
649
|
+
stopImmediatePropagationFlag: false,
|
|
650
|
+
canceledFlag: false,
|
|
651
|
+
inPassiveListenerFlag: false,
|
|
652
|
+
composedFlag: Boolean(init?.composed),
|
|
653
|
+
eventPhase: init?.eventPhase ?? 0,
|
|
654
|
+
currentTarget: init?.currentTarget ?? init?.target ?? null,
|
|
655
|
+
target: init?.target ?? null,
|
|
656
|
+
timeStamp: init?.timeStamp ?? now(),
|
|
657
|
+
path: [],
|
|
658
|
+
type,
|
|
659
|
+
bubbles: Boolean(init?.bubbles),
|
|
660
|
+
cancelable: Boolean(init?.cancelable),
|
|
661
|
+
isTrusted: false
|
|
616
662
|
};
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
663
|
+
const event = { detail };
|
|
664
|
+
Object.defineProperties(event, {
|
|
665
|
+
type: {
|
|
666
|
+
get: () => state.type,
|
|
667
|
+
enumerable: true,
|
|
668
|
+
configurable: true
|
|
669
|
+
},
|
|
670
|
+
bubbles: {
|
|
671
|
+
get: () => state.bubbles,
|
|
672
|
+
enumerable: true,
|
|
673
|
+
configurable: true
|
|
674
|
+
},
|
|
675
|
+
cancelable: {
|
|
676
|
+
get: () => state.cancelable,
|
|
677
|
+
enumerable: true,
|
|
678
|
+
configurable: true
|
|
679
|
+
},
|
|
680
|
+
cancelBubble: {
|
|
681
|
+
get: () => state.stopPropagationFlag,
|
|
682
|
+
set: (value) => {
|
|
683
|
+
if (value)
|
|
684
|
+
state.stopPropagationFlag = true;
|
|
685
|
+
},
|
|
686
|
+
enumerable: true,
|
|
687
|
+
configurable: true
|
|
688
|
+
},
|
|
689
|
+
composed: {
|
|
690
|
+
get: () => state.composedFlag,
|
|
691
|
+
enumerable: true,
|
|
692
|
+
configurable: true
|
|
693
|
+
},
|
|
694
|
+
currentTarget: {
|
|
695
|
+
get: () => state.currentTarget,
|
|
696
|
+
enumerable: true,
|
|
697
|
+
configurable: true
|
|
698
|
+
},
|
|
699
|
+
defaultPrevented: {
|
|
700
|
+
get: () => state.canceledFlag,
|
|
701
|
+
enumerable: true,
|
|
702
|
+
configurable: true
|
|
703
|
+
},
|
|
704
|
+
eventPhase: {
|
|
705
|
+
get: () => state.eventPhase,
|
|
706
|
+
enumerable: true,
|
|
707
|
+
configurable: true
|
|
708
|
+
},
|
|
709
|
+
isTrusted: {
|
|
710
|
+
get: () => state.isTrusted,
|
|
711
|
+
enumerable: true,
|
|
712
|
+
configurable: true
|
|
713
|
+
},
|
|
714
|
+
returnValue: {
|
|
715
|
+
get: () => !state.canceledFlag,
|
|
716
|
+
set: (value) => {
|
|
717
|
+
if (value === false)
|
|
718
|
+
setCanceledFlag(state);
|
|
719
|
+
},
|
|
720
|
+
enumerable: true,
|
|
721
|
+
configurable: true
|
|
722
|
+
},
|
|
723
|
+
srcElement: {
|
|
724
|
+
get: () => state.target,
|
|
725
|
+
enumerable: true,
|
|
726
|
+
configurable: true
|
|
727
|
+
},
|
|
728
|
+
target: {
|
|
729
|
+
get: () => state.target,
|
|
730
|
+
enumerable: true,
|
|
731
|
+
configurable: true
|
|
732
|
+
},
|
|
733
|
+
timeStamp: {
|
|
734
|
+
get: () => state.timeStamp,
|
|
735
|
+
enumerable: true,
|
|
736
|
+
configurable: true
|
|
737
|
+
},
|
|
738
|
+
composedPath: {
|
|
739
|
+
value: () => state.path.map((entry) => entry.invocationTarget),
|
|
740
|
+
enumerable: true,
|
|
741
|
+
configurable: true
|
|
742
|
+
},
|
|
743
|
+
initEvent: {
|
|
744
|
+
value: (newType, bubbles = false, cancelable = false) => {
|
|
745
|
+
if (state.dispatchFlag)
|
|
746
|
+
return;
|
|
747
|
+
initializeEventState(state, newType, Boolean(bubbles), Boolean(cancelable));
|
|
748
|
+
},
|
|
749
|
+
enumerable: true,
|
|
750
|
+
configurable: true
|
|
751
|
+
},
|
|
620
752
|
preventDefault: {
|
|
621
|
-
value:
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
753
|
+
value: () => setCanceledFlag(state),
|
|
754
|
+
enumerable: true,
|
|
755
|
+
configurable: true
|
|
756
|
+
},
|
|
757
|
+
stopImmediatePropagation: {
|
|
758
|
+
value: () => {
|
|
759
|
+
state.stopPropagationFlag = true;
|
|
760
|
+
state.stopImmediatePropagationFlag = true;
|
|
761
|
+
},
|
|
762
|
+
enumerable: true,
|
|
763
|
+
configurable: true
|
|
764
|
+
},
|
|
765
|
+
stopPropagation: {
|
|
766
|
+
value: () => {
|
|
767
|
+
state.stopPropagationFlag = true;
|
|
627
768
|
},
|
|
628
769
|
enumerable: true,
|
|
629
770
|
configurable: true
|
|
771
|
+
},
|
|
772
|
+
NONE: { value: 0, enumerable: true, configurable: true },
|
|
773
|
+
CAPTURING_PHASE: { value: 1, enumerable: true, configurable: true },
|
|
774
|
+
AT_TARGET: { value: 2, enumerable: true, configurable: true },
|
|
775
|
+
BUBBLING_PHASE: { value: 3, enumerable: true, configurable: true },
|
|
776
|
+
[EVENT_STATE]: {
|
|
777
|
+
value: state,
|
|
778
|
+
enumerable: false,
|
|
779
|
+
configurable: false
|
|
630
780
|
}
|
|
631
781
|
});
|
|
782
|
+
return event;
|
|
783
|
+
};
|
|
784
|
+
const getEventState = (event) => event[EVENT_STATE];
|
|
785
|
+
const normalizeAddListenerOptions = (options) => {
|
|
786
|
+
if (typeof options === "boolean") {
|
|
787
|
+
return {
|
|
788
|
+
capture: options,
|
|
789
|
+
passive: false,
|
|
790
|
+
once: false,
|
|
791
|
+
signal: null
|
|
792
|
+
};
|
|
793
|
+
}
|
|
794
|
+
return {
|
|
795
|
+
capture: Boolean(options?.capture),
|
|
796
|
+
passive: Boolean(options?.passive),
|
|
797
|
+
once: Boolean(options?.once),
|
|
798
|
+
signal: options?.signal ?? null
|
|
799
|
+
};
|
|
800
|
+
};
|
|
801
|
+
const normalizeCaptureOption = (options) => {
|
|
802
|
+
if (typeof options === "boolean")
|
|
803
|
+
return options;
|
|
804
|
+
return Boolean(options?.capture);
|
|
805
|
+
};
|
|
806
|
+
const removeListenerRecord = (type, record) => {
|
|
807
|
+
if (record.removed)
|
|
808
|
+
return;
|
|
809
|
+
record.removed = true;
|
|
810
|
+
const list = listeners.get(type);
|
|
811
|
+
if (list) {
|
|
812
|
+
const idx = list.indexOf(record);
|
|
813
|
+
if (idx >= 0)
|
|
814
|
+
list.splice(idx, 1);
|
|
815
|
+
if (list.length === 0)
|
|
816
|
+
listeners.delete(type);
|
|
817
|
+
}
|
|
818
|
+
if (record.signal && record.abortHandler) {
|
|
819
|
+
record.signal.removeEventListener("abort", record.abortHandler);
|
|
820
|
+
}
|
|
632
821
|
};
|
|
633
822
|
const handleListenerError = (eventType, error2) => {
|
|
634
823
|
if (eventType === "error")
|
|
@@ -638,28 +827,27 @@ function createEventTargetInternal(opts) {
|
|
|
638
827
|
return;
|
|
639
828
|
}
|
|
640
829
|
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
|
-
}
|
|
830
|
+
if (errorListeners && errorListeners.length > 0) {
|
|
831
|
+
dispatchEvent({ type: "error", detail: error2 });
|
|
651
832
|
} else {
|
|
652
833
|
throw error2;
|
|
653
834
|
}
|
|
654
835
|
};
|
|
655
|
-
const notifyWildcardListeners = (eventType,
|
|
836
|
+
const notifyWildcardListeners = (eventType, event) => {
|
|
656
837
|
if (wildcardListeners.size === 0)
|
|
657
838
|
return;
|
|
658
839
|
for (const rec of Array.from(wildcardListeners)) {
|
|
659
840
|
if (!matchesWildcard(eventType, rec.pattern))
|
|
660
841
|
continue;
|
|
661
|
-
const
|
|
662
|
-
|
|
842
|
+
const baseEvent = createEvent(rec.pattern, event.detail, {
|
|
843
|
+
target,
|
|
844
|
+
currentTarget: target,
|
|
845
|
+
eventPhase: 2,
|
|
846
|
+
bubbles: event.bubbles,
|
|
847
|
+
cancelable: event.cancelable,
|
|
848
|
+
composed: event.composed
|
|
849
|
+
});
|
|
850
|
+
const wildcardEvent = Object.defineProperties(baseEvent, {
|
|
663
851
|
originalType: { value: eventType, enumerable: true, configurable: true }
|
|
664
852
|
});
|
|
665
853
|
try {
|
|
@@ -682,44 +870,66 @@ function createEventTargetInternal(opts) {
|
|
|
682
870
|
if (rec.once)
|
|
683
871
|
wildcardListeners.delete(rec);
|
|
684
872
|
}
|
|
873
|
+
const state = getEventState(wildcardEvent);
|
|
874
|
+
if (state?.stopImmediatePropagationFlag || state?.stopPropagationFlag) {
|
|
875
|
+
break;
|
|
876
|
+
}
|
|
685
877
|
}
|
|
686
878
|
};
|
|
687
|
-
const
|
|
688
|
-
if (isCompleted) {
|
|
879
|
+
const addListenerInternal = (type, listener, options, position) => {
|
|
880
|
+
if (isCompleted || !listener) {
|
|
689
881
|
return () => {};
|
|
690
882
|
}
|
|
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);
|
|
883
|
+
const { capture, passive, once, signal } = normalizeAddListenerOptions(options);
|
|
884
|
+
let list = listeners.get(type);
|
|
885
|
+
if (!list) {
|
|
886
|
+
list = [];
|
|
887
|
+
listeners.set(type, list);
|
|
701
888
|
}
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
setNow?.delete(record);
|
|
706
|
-
if (record.signal && record.abortHandler) {
|
|
707
|
-
record.signal.removeEventListener("abort", record.abortHandler);
|
|
889
|
+
for (const existing of list) {
|
|
890
|
+
if (existing.original === listener && existing.capture === capture) {
|
|
891
|
+
return () => removeEventListener(type, listener, options);
|
|
708
892
|
}
|
|
893
|
+
}
|
|
894
|
+
const original = listener;
|
|
895
|
+
const callback = typeof listener === "function" ? listener : (event) => listener.handleEvent(event);
|
|
896
|
+
const record = {
|
|
897
|
+
type,
|
|
898
|
+
original,
|
|
899
|
+
callback,
|
|
900
|
+
capture,
|
|
901
|
+
passive,
|
|
902
|
+
once,
|
|
903
|
+
signal,
|
|
904
|
+
removed: false
|
|
709
905
|
};
|
|
710
|
-
if (
|
|
711
|
-
|
|
906
|
+
if (position === "prepend") {
|
|
907
|
+
list.unshift(record);
|
|
908
|
+
} else {
|
|
909
|
+
list.push(record);
|
|
910
|
+
}
|
|
911
|
+
const unsubscribe2 = () => removeListenerRecord(type, record);
|
|
912
|
+
if (signal) {
|
|
913
|
+
const onAbort = () => removeListenerRecord(type, record);
|
|
712
914
|
record.abortHandler = onAbort;
|
|
713
|
-
|
|
714
|
-
if (
|
|
915
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
916
|
+
if (signal.aborted)
|
|
715
917
|
onAbort();
|
|
716
918
|
}
|
|
717
919
|
return unsubscribe2;
|
|
718
920
|
};
|
|
921
|
+
const addEventListener = (type, listener, options) => {
|
|
922
|
+
return addListenerInternal(type, listener, options, "append");
|
|
923
|
+
};
|
|
719
924
|
const addWildcardListener = (pattern, listener, options) => {
|
|
720
925
|
if (isCompleted)
|
|
721
926
|
return () => {};
|
|
722
927
|
const opts2 = options ?? {};
|
|
928
|
+
for (const existing of wildcardListeners) {
|
|
929
|
+
if (existing.pattern === pattern && existing.fn === listener) {
|
|
930
|
+
return () => removeWildcardListener(pattern, listener);
|
|
931
|
+
}
|
|
932
|
+
}
|
|
723
933
|
const record = {
|
|
724
934
|
fn: listener,
|
|
725
935
|
pattern,
|
|
@@ -743,31 +953,39 @@ function createEventTargetInternal(opts) {
|
|
|
743
953
|
return unsubscribe2;
|
|
744
954
|
};
|
|
745
955
|
const removeWildcardListener = (pattern, listener) => {
|
|
746
|
-
for (const record of wildcardListeners) {
|
|
956
|
+
for (const record of Array.from(wildcardListeners)) {
|
|
747
957
|
if (record.pattern === pattern && record.fn === listener) {
|
|
748
958
|
wildcardListeners.delete(record);
|
|
749
959
|
if (record.signal && record.abortHandler) {
|
|
750
960
|
record.signal.removeEventListener("abort", record.abortHandler);
|
|
751
961
|
}
|
|
752
|
-
break;
|
|
753
962
|
}
|
|
754
963
|
}
|
|
755
964
|
};
|
|
756
|
-
const
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
965
|
+
const invokeListeners = (eventType, event, phase, listenersSnapshot) => {
|
|
966
|
+
const state = getEventState(event);
|
|
967
|
+
if (!state || state.stopPropagationFlag)
|
|
968
|
+
return;
|
|
969
|
+
state.currentTarget = target;
|
|
970
|
+
state.target = target;
|
|
971
|
+
state.eventPhase = event.AT_TARGET;
|
|
972
|
+
for (const rec of listenersSnapshot) {
|
|
973
|
+
if (rec.removed)
|
|
974
|
+
continue;
|
|
975
|
+
if (phase === "capturing" && !rec.capture)
|
|
976
|
+
continue;
|
|
977
|
+
if (phase === "bubbling" && rec.capture)
|
|
978
|
+
continue;
|
|
979
|
+
if (rec.once)
|
|
980
|
+
removeListenerRecord(rec.type, rec);
|
|
981
|
+
if (rec.passive)
|
|
982
|
+
state.inPassiveListenerFlag = true;
|
|
765
983
|
try {
|
|
766
|
-
const res = rec.
|
|
984
|
+
const res = rec.callback.call(state.currentTarget, event);
|
|
767
985
|
if (res && typeof res.then === "function") {
|
|
768
986
|
res.catch((error2) => {
|
|
769
987
|
try {
|
|
770
|
-
handleListenerError(
|
|
988
|
+
handleListenerError(eventType, error2);
|
|
771
989
|
} catch (rethrown) {
|
|
772
990
|
queueMicrotask(() => {
|
|
773
991
|
throw rethrown;
|
|
@@ -776,36 +994,94 @@ function createEventTargetInternal(opts) {
|
|
|
776
994
|
});
|
|
777
995
|
}
|
|
778
996
|
} catch (error2) {
|
|
779
|
-
handleListenerError(
|
|
997
|
+
handleListenerError(eventType, error2);
|
|
780
998
|
} finally {
|
|
781
|
-
if (rec.
|
|
782
|
-
|
|
999
|
+
if (rec.passive)
|
|
1000
|
+
state.inPassiveListenerFlag = false;
|
|
783
1001
|
}
|
|
1002
|
+
if (state.stopImmediatePropagationFlag)
|
|
1003
|
+
break;
|
|
784
1004
|
}
|
|
785
|
-
return true;
|
|
786
1005
|
};
|
|
787
|
-
const
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
1006
|
+
const dispatchEvent = (eventInput) => {
|
|
1007
|
+
if (isCompleted)
|
|
1008
|
+
return false;
|
|
1009
|
+
let event;
|
|
1010
|
+
let state;
|
|
1011
|
+
if (eventInput && typeof eventInput === "object") {
|
|
1012
|
+
state = getEventState(eventInput);
|
|
1013
|
+
if (state) {
|
|
1014
|
+
event = eventInput;
|
|
1015
|
+
} else {
|
|
1016
|
+
const input = eventInput;
|
|
1017
|
+
if (typeof input.type !== "string") {
|
|
1018
|
+
throw new TypeError("Event type must be a string");
|
|
796
1019
|
}
|
|
797
|
-
|
|
1020
|
+
event = createEvent(input.type, input.detail, {
|
|
1021
|
+
bubbles: input.bubbles,
|
|
1022
|
+
cancelable: input.cancelable,
|
|
1023
|
+
composed: input.composed,
|
|
1024
|
+
timeStamp: input.timeStamp
|
|
1025
|
+
});
|
|
1026
|
+
state = getEventState(event);
|
|
1027
|
+
}
|
|
1028
|
+
} else {
|
|
1029
|
+
throw new TypeError("dispatchEvent expects an event object");
|
|
1030
|
+
}
|
|
1031
|
+
const dispatchState = state ?? getEventState(event);
|
|
1032
|
+
if (dispatchState.dispatchFlag || !dispatchState.initializedFlag) {
|
|
1033
|
+
const message = "Failed to execute dispatchEvent: event is already being dispatched";
|
|
1034
|
+
if (typeof globalThis.DOMException === "function") {
|
|
1035
|
+
throw new globalThis.DOMException(message, "InvalidStateError");
|
|
1036
|
+
}
|
|
1037
|
+
const err = new Error(message);
|
|
1038
|
+
err.name = "InvalidStateError";
|
|
1039
|
+
throw err;
|
|
1040
|
+
}
|
|
1041
|
+
dispatchState.isTrusted = false;
|
|
1042
|
+
dispatchState.dispatchFlag = true;
|
|
1043
|
+
dispatchState.path = [
|
|
1044
|
+
{
|
|
1045
|
+
invocationTarget: target,
|
|
1046
|
+
invocationTargetInShadowTree: false,
|
|
1047
|
+
shadowAdjustedTarget: target,
|
|
1048
|
+
relatedTarget: null,
|
|
1049
|
+
touchTargets: [],
|
|
1050
|
+
rootOfClosedTree: false,
|
|
1051
|
+
slotInClosedTree: false
|
|
1052
|
+
}
|
|
1053
|
+
];
|
|
1054
|
+
notifyWildcardListeners(dispatchState.type, event);
|
|
1055
|
+
const list = listeners.get(dispatchState.type);
|
|
1056
|
+
const snapshot = list ? list.slice() : [];
|
|
1057
|
+
invokeListeners(dispatchState.type, event, "capturing", snapshot);
|
|
1058
|
+
invokeListeners(dispatchState.type, event, "bubbling", snapshot);
|
|
1059
|
+
dispatchState.eventPhase = event.NONE;
|
|
1060
|
+
dispatchState.currentTarget = null;
|
|
1061
|
+
dispatchState.path = [];
|
|
1062
|
+
dispatchState.dispatchFlag = false;
|
|
1063
|
+
dispatchState.stopPropagationFlag = false;
|
|
1064
|
+
dispatchState.stopImmediatePropagationFlag = false;
|
|
1065
|
+
return !dispatchState.canceledFlag;
|
|
1066
|
+
};
|
|
1067
|
+
const removeEventListener = (type, listener, options) => {
|
|
1068
|
+
if (!listener)
|
|
1069
|
+
return;
|
|
1070
|
+
const capture = normalizeCaptureOption(options);
|
|
1071
|
+
const list = listeners.get(type);
|
|
1072
|
+
if (!list)
|
|
1073
|
+
return;
|
|
1074
|
+
for (const record of [...list]) {
|
|
1075
|
+
if (record.original === listener && record.capture === capture) {
|
|
1076
|
+
removeListenerRecord(type, record);
|
|
798
1077
|
}
|
|
799
1078
|
}
|
|
800
1079
|
};
|
|
801
1080
|
const clear = () => {
|
|
802
|
-
for (const
|
|
803
|
-
for (const record of
|
|
804
|
-
|
|
805
|
-
record.signal.removeEventListener("abort", record.abortHandler);
|
|
806
|
-
}
|
|
1081
|
+
for (const [type, list] of Array.from(listeners.entries())) {
|
|
1082
|
+
for (const record of [...list]) {
|
|
1083
|
+
removeListenerRecord(type, record);
|
|
807
1084
|
}
|
|
808
|
-
set.clear();
|
|
809
1085
|
}
|
|
810
1086
|
listeners.clear();
|
|
811
1087
|
for (const record of wildcardListeners) {
|
|
@@ -815,11 +1091,22 @@ function createEventTargetInternal(opts) {
|
|
|
815
1091
|
}
|
|
816
1092
|
wildcardListeners.clear();
|
|
817
1093
|
};
|
|
818
|
-
const
|
|
1094
|
+
const isListenerArg = (arg) => {
|
|
1095
|
+
if (typeof arg === "function")
|
|
1096
|
+
return true;
|
|
1097
|
+
if (arg && typeof arg === "object" && typeof arg.handleEvent === "function")
|
|
1098
|
+
return true;
|
|
1099
|
+
return false;
|
|
1100
|
+
};
|
|
1101
|
+
const on = (type, optionsOrListener) => {
|
|
1102
|
+
if (isListenerArg(optionsOrListener)) {
|
|
1103
|
+
return addEventListener(type, optionsOrListener);
|
|
1104
|
+
}
|
|
1105
|
+
const options = optionsOrListener;
|
|
819
1106
|
return new Observable((observer) => {
|
|
820
1107
|
let opts2;
|
|
821
1108
|
if (typeof options === "boolean") {
|
|
822
|
-
opts2 = {
|
|
1109
|
+
opts2 = { capture: options };
|
|
823
1110
|
} else {
|
|
824
1111
|
opts2 = options ?? {};
|
|
825
1112
|
}
|
|
@@ -856,28 +1143,25 @@ function createEventTargetInternal(opts) {
|
|
|
856
1143
|
});
|
|
857
1144
|
};
|
|
858
1145
|
const onceMethod = (type, listener, options) => {
|
|
859
|
-
|
|
1146
|
+
if (typeof options === "boolean") {
|
|
1147
|
+
return addEventListener(type, listener, { capture: options, once: true });
|
|
1148
|
+
}
|
|
1149
|
+
return addEventListener(type, listener, { ...options ?? {}, once: true });
|
|
860
1150
|
};
|
|
861
1151
|
const removeAllListeners = (type) => {
|
|
862
1152
|
if (type !== undefined) {
|
|
863
|
-
const
|
|
864
|
-
if (
|
|
865
|
-
for (const record of
|
|
866
|
-
|
|
867
|
-
record.signal.removeEventListener("abort", record.abortHandler);
|
|
868
|
-
}
|
|
1153
|
+
const list = listeners.get(type);
|
|
1154
|
+
if (list) {
|
|
1155
|
+
for (const record of [...list]) {
|
|
1156
|
+
removeListenerRecord(type, record);
|
|
869
1157
|
}
|
|
870
|
-
set.clear();
|
|
871
1158
|
listeners.delete(type);
|
|
872
1159
|
}
|
|
873
1160
|
} else {
|
|
874
|
-
for (const
|
|
875
|
-
for (const record of
|
|
876
|
-
|
|
877
|
-
record.signal.removeEventListener("abort", record.abortHandler);
|
|
878
|
-
}
|
|
1161
|
+
for (const [eventType, list] of Array.from(listeners.entries())) {
|
|
1162
|
+
for (const record of [...list]) {
|
|
1163
|
+
removeListenerRecord(eventType, record);
|
|
879
1164
|
}
|
|
880
|
-
set.clear();
|
|
881
1165
|
}
|
|
882
1166
|
listeners.clear();
|
|
883
1167
|
for (const record of wildcardListeners) {
|
|
@@ -892,38 +1176,33 @@ function createEventTargetInternal(opts) {
|
|
|
892
1176
|
if (isCompleted) {
|
|
893
1177
|
return () => {};
|
|
894
1178
|
}
|
|
895
|
-
const
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
} else {
|
|
908
|
-
target2.dispatchEvent(event);
|
|
1179
|
+
const unsubscribe2 = addWildcardListener("*", (event) => {
|
|
1180
|
+
if (mapFn) {
|
|
1181
|
+
const mapped = mapFn(createEvent(event.originalType, event.detail, {
|
|
1182
|
+
target: target2,
|
|
1183
|
+
currentTarget: target2,
|
|
1184
|
+
eventPhase: 2,
|
|
1185
|
+
bubbles: event.bubbles,
|
|
1186
|
+
cancelable: event.cancelable,
|
|
1187
|
+
composed: event.composed
|
|
1188
|
+
}));
|
|
1189
|
+
if (mapped !== null) {
|
|
1190
|
+
target2.dispatchEvent(mapped);
|
|
909
1191
|
}
|
|
910
|
-
}
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
}
|
|
916
|
-
const completionUnsub = () => {
|
|
917
|
-
for (const unsub of unsubscribes) {
|
|
918
|
-
unsub();
|
|
1192
|
+
} else {
|
|
1193
|
+
target2.dispatchEvent({
|
|
1194
|
+
type: event.originalType,
|
|
1195
|
+
detail: event.detail
|
|
1196
|
+
});
|
|
919
1197
|
}
|
|
1198
|
+
});
|
|
1199
|
+
const completionUnsub = () => {
|
|
1200
|
+
unsubscribe2();
|
|
920
1201
|
};
|
|
921
1202
|
completionCallbacks.add(completionUnsub);
|
|
922
1203
|
return () => {
|
|
923
1204
|
completionCallbacks.delete(completionUnsub);
|
|
924
|
-
|
|
925
|
-
unsub();
|
|
926
|
-
}
|
|
1205
|
+
unsubscribe2();
|
|
927
1206
|
};
|
|
928
1207
|
};
|
|
929
1208
|
const complete2 = () => {
|
|
@@ -940,13 +1219,10 @@ function createEventTargetInternal(opts) {
|
|
|
940
1219
|
}
|
|
941
1220
|
}
|
|
942
1221
|
completionCallbacks.clear();
|
|
943
|
-
for (const
|
|
944
|
-
for (const record of
|
|
945
|
-
|
|
946
|
-
record.signal.removeEventListener("abort", record.abortHandler);
|
|
947
|
-
}
|
|
1222
|
+
for (const [eventType, list] of Array.from(listeners.entries())) {
|
|
1223
|
+
for (const record of [...list]) {
|
|
1224
|
+
removeListenerRecord(eventType, record);
|
|
948
1225
|
}
|
|
949
|
-
set.clear();
|
|
950
1226
|
}
|
|
951
1227
|
listeners.clear();
|
|
952
1228
|
for (const record of wildcardListeners) {
|
|
@@ -1029,7 +1305,14 @@ function createEventTargetInternal(opts) {
|
|
|
1029
1305
|
return;
|
|
1030
1306
|
}
|
|
1031
1307
|
const wildcardListener = (event) => {
|
|
1032
|
-
observer.next(
|
|
1308
|
+
observer.next(createEvent(event.originalType, event.detail, {
|
|
1309
|
+
target,
|
|
1310
|
+
currentTarget: target,
|
|
1311
|
+
eventPhase: 2,
|
|
1312
|
+
bubbles: event.bubbles,
|
|
1313
|
+
cancelable: event.cancelable,
|
|
1314
|
+
composed: event.composed
|
|
1315
|
+
}));
|
|
1033
1316
|
};
|
|
1034
1317
|
const unsubscribe2 = addWildcardListener("*", wildcardListener);
|
|
1035
1318
|
const onComplete = () => {
|
|
@@ -1069,19 +1352,26 @@ function createEventTargetInternal(opts) {
|
|
|
1069
1352
|
let resolve = null;
|
|
1070
1353
|
let done = false;
|
|
1071
1354
|
let hasOverflow = false;
|
|
1355
|
+
let onAbort = null;
|
|
1356
|
+
const cleanupAbortListener = () => {
|
|
1357
|
+
if (signal && onAbort) {
|
|
1358
|
+
signal.removeEventListener("abort", onAbort);
|
|
1359
|
+
}
|
|
1360
|
+
};
|
|
1072
1361
|
const unsub = addEventListener(type, (event) => {
|
|
1073
1362
|
if (done)
|
|
1074
1363
|
return;
|
|
1364
|
+
const typedEvent = event;
|
|
1075
1365
|
if (resolve) {
|
|
1076
1366
|
const r = resolve;
|
|
1077
1367
|
resolve = null;
|
|
1078
|
-
r({ value:
|
|
1368
|
+
r({ value: typedEvent, done: false });
|
|
1079
1369
|
} else {
|
|
1080
1370
|
if (buffer.length >= bufferSize && bufferSize !== Infinity) {
|
|
1081
1371
|
switch (overflowStrategy) {
|
|
1082
1372
|
case "drop-oldest":
|
|
1083
1373
|
buffer.shift();
|
|
1084
|
-
buffer.push(
|
|
1374
|
+
buffer.push(typedEvent);
|
|
1085
1375
|
break;
|
|
1086
1376
|
case "drop-latest":
|
|
1087
1377
|
break;
|
|
@@ -1090,15 +1380,17 @@ function createEventTargetInternal(opts) {
|
|
|
1090
1380
|
completionCallbacks.delete(onComplete);
|
|
1091
1381
|
done = true;
|
|
1092
1382
|
hasOverflow = true;
|
|
1383
|
+
cleanupAbortListener();
|
|
1093
1384
|
return;
|
|
1094
1385
|
}
|
|
1095
1386
|
} else {
|
|
1096
|
-
buffer.push(
|
|
1387
|
+
buffer.push(typedEvent);
|
|
1097
1388
|
}
|
|
1098
1389
|
}
|
|
1099
1390
|
});
|
|
1100
1391
|
const onComplete = () => {
|
|
1101
1392
|
done = true;
|
|
1393
|
+
cleanupAbortListener();
|
|
1102
1394
|
if (resolve) {
|
|
1103
1395
|
const r = resolve;
|
|
1104
1396
|
resolve = null;
|
|
@@ -1106,7 +1398,6 @@ function createEventTargetInternal(opts) {
|
|
|
1106
1398
|
}
|
|
1107
1399
|
};
|
|
1108
1400
|
completionCallbacks.add(onComplete);
|
|
1109
|
-
let onAbort = null;
|
|
1110
1401
|
if (signal) {
|
|
1111
1402
|
onAbort = () => {
|
|
1112
1403
|
done = true;
|
|
@@ -1130,26 +1421,22 @@ function createEventTargetInternal(opts) {
|
|
|
1130
1421
|
if (buffer.length > 0) {
|
|
1131
1422
|
return { value: buffer.shift(), done: false };
|
|
1132
1423
|
}
|
|
1133
|
-
if (hasOverflow) {
|
|
1134
|
-
hasOverflow = false;
|
|
1135
|
-
throw new BufferOverflowError(type, bufferSize);
|
|
1136
|
-
}
|
|
1137
|
-
if (done) {
|
|
1138
|
-
return { value: undefined, done: true };
|
|
1139
|
-
}
|
|
1140
1424
|
if (resolve !== null) {
|
|
1141
1425
|
return Promise.reject(new Error("Concurrent calls to next() are not supported on this async iterator"));
|
|
1142
1426
|
}
|
|
1143
1427
|
return new Promise((_resolve, _reject) => {
|
|
1144
|
-
if (done) {
|
|
1145
|
-
_resolve({ value: undefined, done: true });
|
|
1146
|
-
return;
|
|
1147
|
-
}
|
|
1148
1428
|
if (hasOverflow) {
|
|
1149
1429
|
hasOverflow = false;
|
|
1150
1430
|
_reject(new BufferOverflowError(type, bufferSize));
|
|
1151
1431
|
return;
|
|
1152
1432
|
}
|
|
1433
|
+
if (done) {
|
|
1434
|
+
_resolve({
|
|
1435
|
+
value: undefined,
|
|
1436
|
+
done: true
|
|
1437
|
+
});
|
|
1438
|
+
return;
|
|
1439
|
+
}
|
|
1153
1440
|
resolve = _resolve;
|
|
1154
1441
|
});
|
|
1155
1442
|
},
|
|
@@ -1162,9 +1449,7 @@ function createEventTargetInternal(opts) {
|
|
|
1162
1449
|
done = true;
|
|
1163
1450
|
completionCallbacks.delete(onComplete);
|
|
1164
1451
|
unsub();
|
|
1165
|
-
|
|
1166
|
-
signal.removeEventListener("abort", onAbort);
|
|
1167
|
-
}
|
|
1452
|
+
cleanupAbortListener();
|
|
1168
1453
|
return Promise.resolve({
|
|
1169
1454
|
value: undefined,
|
|
1170
1455
|
done: true
|
|
@@ -1173,6 +1458,72 @@ function createEventTargetInternal(opts) {
|
|
|
1173
1458
|
};
|
|
1174
1459
|
return iterator;
|
|
1175
1460
|
}
|
|
1461
|
+
const emit = (type, detail) => {
|
|
1462
|
+
if (isCompleted)
|
|
1463
|
+
return false;
|
|
1464
|
+
const list = listeners.get(type);
|
|
1465
|
+
const hasListeners = list !== undefined && list.length > 0;
|
|
1466
|
+
let hasWildcard = false;
|
|
1467
|
+
if (wildcardListeners.size > 0) {
|
|
1468
|
+
for (const rec of wildcardListeners) {
|
|
1469
|
+
if (matchesWildcard(type, rec.pattern)) {
|
|
1470
|
+
hasWildcard = true;
|
|
1471
|
+
break;
|
|
1472
|
+
}
|
|
1473
|
+
}
|
|
1474
|
+
}
|
|
1475
|
+
dispatchEvent({ type, detail });
|
|
1476
|
+
return hasListeners || hasWildcard;
|
|
1477
|
+
};
|
|
1478
|
+
const off = (type, listener) => {
|
|
1479
|
+
removeEventListener(type, listener);
|
|
1480
|
+
};
|
|
1481
|
+
const addListener = (type, listener) => {
|
|
1482
|
+
return addEventListener(type, listener);
|
|
1483
|
+
};
|
|
1484
|
+
const removeListener = (type, listener) => {
|
|
1485
|
+
removeEventListener(type, listener);
|
|
1486
|
+
};
|
|
1487
|
+
const prependListener = (type, listener) => {
|
|
1488
|
+
return addListenerInternal(type, listener, undefined, "prepend");
|
|
1489
|
+
};
|
|
1490
|
+
const prependOnceListener = (type, listener) => {
|
|
1491
|
+
return addListenerInternal(type, listener, { once: true }, "prepend");
|
|
1492
|
+
};
|
|
1493
|
+
const getListeners = (type) => {
|
|
1494
|
+
const list = listeners.get(type);
|
|
1495
|
+
if (!list)
|
|
1496
|
+
return [];
|
|
1497
|
+
return list.filter((r) => !r.removed).map((r) => r.original);
|
|
1498
|
+
};
|
|
1499
|
+
const rawListenersMethod = (type) => {
|
|
1500
|
+
const list = listeners.get(type);
|
|
1501
|
+
if (!list)
|
|
1502
|
+
return [];
|
|
1503
|
+
return list.filter((r) => !r.removed).map((r) => {
|
|
1504
|
+
if (r.once) {
|
|
1505
|
+
const wrapper = (...args) => r.callback(...args);
|
|
1506
|
+
wrapper.listener = r.original;
|
|
1507
|
+
return wrapper;
|
|
1508
|
+
}
|
|
1509
|
+
return r.original;
|
|
1510
|
+
});
|
|
1511
|
+
};
|
|
1512
|
+
const listenerCount = (type) => {
|
|
1513
|
+
const list = listeners.get(type);
|
|
1514
|
+
if (!list)
|
|
1515
|
+
return 0;
|
|
1516
|
+
return list.filter((r) => !r.removed).length;
|
|
1517
|
+
};
|
|
1518
|
+
const eventNamesMethod = () => {
|
|
1519
|
+
const names = [];
|
|
1520
|
+
for (const [type, list] of listeners) {
|
|
1521
|
+
if (list.some((r) => !r.removed)) {
|
|
1522
|
+
names.push(type);
|
|
1523
|
+
}
|
|
1524
|
+
}
|
|
1525
|
+
return names;
|
|
1526
|
+
};
|
|
1176
1527
|
const target = {
|
|
1177
1528
|
addEventListener,
|
|
1178
1529
|
removeEventListener,
|
|
@@ -1190,90 +1541,23 @@ function createEventTargetInternal(opts) {
|
|
|
1190
1541
|
},
|
|
1191
1542
|
subscribe,
|
|
1192
1543
|
toObservable,
|
|
1193
|
-
events
|
|
1544
|
+
events,
|
|
1545
|
+
emit,
|
|
1546
|
+
off,
|
|
1547
|
+
addListener,
|
|
1548
|
+
removeListener,
|
|
1549
|
+
prependListener,
|
|
1550
|
+
prependOnceListener,
|
|
1551
|
+
listeners: getListeners,
|
|
1552
|
+
rawListeners: rawListenersMethod,
|
|
1553
|
+
listenerCount,
|
|
1554
|
+
eventNames: eventNamesMethod
|
|
1194
1555
|
};
|
|
1195
1556
|
target[SymbolObservable] = () => {
|
|
1196
1557
|
return toObservable();
|
|
1197
1558
|
};
|
|
1198
1559
|
return target;
|
|
1199
1560
|
}
|
|
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
1561
|
// src/event-emission.ts
|
|
1278
1562
|
class EventEmission {
|
|
1279
1563
|
#target;
|
|
@@ -1283,14 +1567,14 @@ class EventEmission {
|
|
|
1283
1567
|
addEventListener(type, listener, options) {
|
|
1284
1568
|
return this.#target.addEventListener(type, listener, options);
|
|
1285
1569
|
}
|
|
1286
|
-
removeEventListener(type, listener) {
|
|
1287
|
-
this.#target.removeEventListener(type, listener);
|
|
1570
|
+
removeEventListener(type, listener, options) {
|
|
1571
|
+
this.#target.removeEventListener(type, listener, options);
|
|
1288
1572
|
}
|
|
1289
1573
|
dispatchEvent(event) {
|
|
1290
1574
|
return this.#target.dispatchEvent(event);
|
|
1291
1575
|
}
|
|
1292
|
-
on(type,
|
|
1293
|
-
return this.#target.on(type,
|
|
1576
|
+
on(type, optionsOrListener) {
|
|
1577
|
+
return this.#target.on(type, optionsOrListener);
|
|
1294
1578
|
}
|
|
1295
1579
|
once(type, listener, options) {
|
|
1296
1580
|
return this.#target.once(type, listener, options);
|
|
@@ -1304,6 +1588,36 @@ class EventEmission {
|
|
|
1304
1588
|
pipe(target, mapFn) {
|
|
1305
1589
|
return this.#target.pipe(target, mapFn);
|
|
1306
1590
|
}
|
|
1591
|
+
emit(type, detail) {
|
|
1592
|
+
return this.#target.emit(type, detail);
|
|
1593
|
+
}
|
|
1594
|
+
off(type, listener) {
|
|
1595
|
+
this.#target.off(type, listener);
|
|
1596
|
+
}
|
|
1597
|
+
addListener(type, listener) {
|
|
1598
|
+
return this.#target.addListener(type, listener);
|
|
1599
|
+
}
|
|
1600
|
+
removeListener(type, listener) {
|
|
1601
|
+
this.#target.removeListener(type, listener);
|
|
1602
|
+
}
|
|
1603
|
+
prependListener(type, listener) {
|
|
1604
|
+
return this.#target.prependListener(type, listener);
|
|
1605
|
+
}
|
|
1606
|
+
prependOnceListener(type, listener) {
|
|
1607
|
+
return this.#target.prependOnceListener(type, listener);
|
|
1608
|
+
}
|
|
1609
|
+
listeners(type) {
|
|
1610
|
+
return this.#target.listeners(type);
|
|
1611
|
+
}
|
|
1612
|
+
rawListeners(type) {
|
|
1613
|
+
return this.#target.rawListeners(type);
|
|
1614
|
+
}
|
|
1615
|
+
listenerCount(type) {
|
|
1616
|
+
return this.#target.listenerCount(type);
|
|
1617
|
+
}
|
|
1618
|
+
eventNames() {
|
|
1619
|
+
return this.#target.eventNames();
|
|
1620
|
+
}
|
|
1307
1621
|
addWildcardListener(pattern, listener, options) {
|
|
1308
1622
|
return this.#target.addWildcardListener(pattern, listener, options);
|
|
1309
1623
|
}
|
|
@@ -1343,19 +1657,10 @@ class EventEmission {
|
|
|
1343
1657
|
}
|
|
1344
1658
|
}
|
|
1345
1659
|
export {
|
|
1346
|
-
setupEventForwarding,
|
|
1347
|
-
pipe,
|
|
1348
|
-
isObserved,
|
|
1349
|
-
getOriginal,
|
|
1350
|
-
fromEventTarget,
|
|
1351
|
-
forwardToEventTarget,
|
|
1352
1660
|
createEventTarget,
|
|
1353
1661
|
SymbolObservable,
|
|
1354
|
-
PROXY_MARKER,
|
|
1355
|
-
Observable,
|
|
1356
|
-
ORIGINAL_TARGET,
|
|
1357
1662
|
EventEmission,
|
|
1358
1663
|
BufferOverflowError
|
|
1359
1664
|
};
|
|
1360
1665
|
|
|
1361
|
-
//# debugId=
|
|
1666
|
+
//# debugId=320F1C6E7F0CB63D64756E2164756E21
|