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.cjs
CHANGED
|
@@ -27,37 +27,19 @@ var __export = (target, all) => {
|
|
|
27
27
|
});
|
|
28
28
|
};
|
|
29
29
|
|
|
30
|
-
// src/
|
|
31
|
-
var
|
|
32
|
-
__export(
|
|
33
|
-
|
|
34
|
-
pipe: () => pipe,
|
|
35
|
-
isObserved: () => isObserved,
|
|
36
|
-
getOriginal: () => getOriginal,
|
|
37
|
-
fromEventTarget: () => fromEventTarget,
|
|
38
|
-
forwardToEventTarget: () => forwardToEventTarget,
|
|
39
|
-
createEventTarget: () => createEventTarget,
|
|
40
|
-
SymbolObservable: () => SymbolObservable,
|
|
41
|
-
PROXY_MARKER: () => PROXY_MARKER,
|
|
42
|
-
Observable: () => Observable,
|
|
43
|
-
ORIGINAL_TARGET: () => ORIGINAL_TARGET,
|
|
44
|
-
EventEmission: () => EventEmission,
|
|
45
|
-
BufferOverflowError: () => BufferOverflowError
|
|
30
|
+
// src/observable.ts
|
|
31
|
+
var exports_observable = {};
|
|
32
|
+
__export(exports_observable, {
|
|
33
|
+
Observable: () => Observable
|
|
46
34
|
});
|
|
47
|
-
module.exports = __toCommonJS(
|
|
35
|
+
module.exports = __toCommonJS(exports_observable);
|
|
48
36
|
|
|
49
37
|
// src/symbols.ts
|
|
50
38
|
var SymbolObservable = typeof Symbol === "function" && Symbol.observable || Symbol.for("@@observable");
|
|
51
39
|
if (typeof Symbol === "function") {
|
|
52
40
|
Symbol.observable = SymbolObservable;
|
|
53
41
|
}
|
|
54
|
-
|
|
55
|
-
class BufferOverflowError extends Error {
|
|
56
|
-
constructor(eventType, bufferSize) {
|
|
57
|
-
super(`Buffer overflow for event type "${eventType}" (max: ${bufferSize})`);
|
|
58
|
-
this.name = "BufferOverflowError";
|
|
59
|
-
}
|
|
60
|
-
}
|
|
42
|
+
|
|
61
43
|
// src/observable.ts
|
|
62
44
|
function getMethod(obj, key) {
|
|
63
45
|
if (obj === null || obj === undefined)
|
|
@@ -301,6 +283,16 @@ class Observable {
|
|
|
301
283
|
}
|
|
302
284
|
|
|
303
285
|
// src/observe.ts
|
|
286
|
+
var exports_observe = {};
|
|
287
|
+
__export(exports_observe, {
|
|
288
|
+
setupEventForwarding: () => setupEventForwarding,
|
|
289
|
+
isObserved: () => isObserved,
|
|
290
|
+
getOriginal: () => getOriginal,
|
|
291
|
+
createObservableProxy: () => createObservableProxy,
|
|
292
|
+
PROXY_MARKER: () => PROXY_MARKER,
|
|
293
|
+
ORIGINAL_TARGET: () => ORIGINAL_TARGET
|
|
294
|
+
});
|
|
295
|
+
module.exports = __toCommonJS(exports_observe);
|
|
304
296
|
var PROXY_MARKER = Symbol.for("@lasercat/event-emission/proxy");
|
|
305
297
|
var ORIGINAL_TARGET = Symbol.for("@lasercat/event-emission/original");
|
|
306
298
|
var ARRAY_MUTATORS = new Set([
|
|
@@ -324,17 +316,13 @@ function isArrayMutator(prop) {
|
|
|
324
316
|
return typeof prop === "string" && ARRAY_MUTATORS.has(prop);
|
|
325
317
|
}
|
|
326
318
|
function cloneAlongPath(obj, path) {
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
return Array.isArray(obj) ? [...obj] : { ...obj };
|
|
319
|
+
const isArray = Array.isArray(obj);
|
|
320
|
+
const rootClone = isArray ? [...obj] : { ...obj };
|
|
321
|
+
if (!path || isArray) {
|
|
322
|
+
return rootClone;
|
|
332
323
|
}
|
|
333
324
|
const parts = path.split(".");
|
|
334
|
-
|
|
335
|
-
return [...obj];
|
|
336
|
-
}
|
|
337
|
-
const result = { ...obj };
|
|
325
|
+
const result = rootClone;
|
|
338
326
|
let current = result;
|
|
339
327
|
for (let i = 0;i < parts.length; i++) {
|
|
340
328
|
const key = parts[i];
|
|
@@ -350,13 +338,19 @@ function cloneAlongPath(obj, path) {
|
|
|
350
338
|
}
|
|
351
339
|
return result;
|
|
352
340
|
}
|
|
353
|
-
function cloneForComparison(obj, strategy, changedPath) {
|
|
341
|
+
function cloneForComparison(obj, strategy, changedPath, deepClone) {
|
|
354
342
|
if (obj === null || typeof obj !== "object")
|
|
355
343
|
return obj;
|
|
356
344
|
switch (strategy) {
|
|
357
345
|
case "shallow":
|
|
358
346
|
return Array.isArray(obj) ? [...obj] : { ...obj };
|
|
359
347
|
case "deep":
|
|
348
|
+
if (deepClone) {
|
|
349
|
+
return deepClone(obj);
|
|
350
|
+
}
|
|
351
|
+
if (typeof structuredClone !== "function") {
|
|
352
|
+
throw new Error("structuredClone is not available in this runtime; provide observe.deepClone, or use cloneStrategy 'path' or 'shallow'.");
|
|
353
|
+
}
|
|
360
354
|
return structuredClone(obj);
|
|
361
355
|
case "path":
|
|
362
356
|
return cloneAlongPath(obj, changedPath);
|
|
@@ -404,7 +398,7 @@ function getContextRegistry(target) {
|
|
|
404
398
|
function createArrayMethodInterceptor(array, method, path, context) {
|
|
405
399
|
const original = array[method];
|
|
406
400
|
return function(...args) {
|
|
407
|
-
const previousState = cloneForComparison(context.originalRoot, context.options.cloneStrategy, path);
|
|
401
|
+
const previousState = cloneForComparison(context.originalRoot, context.options.cloneStrategy, path, context.options.deepClone);
|
|
408
402
|
const previousItems = [...array];
|
|
409
403
|
const result = original.apply(this, args);
|
|
410
404
|
const { added, removed } = computeArrayDiff(method, previousItems, array, args);
|
|
@@ -476,7 +470,7 @@ function createObservableProxyInternal(target, path, context) {
|
|
|
476
470
|
return true;
|
|
477
471
|
}
|
|
478
472
|
const propPath = path ? `${path}.${prop}` : prop;
|
|
479
|
-
const previousState = cloneForComparison(context.originalRoot, context.options.cloneStrategy, propPath);
|
|
473
|
+
const previousState = cloneForComparison(context.originalRoot, context.options.cloneStrategy, propPath, context.options.deepClone);
|
|
480
474
|
const success = Reflect.set(obj, prop, value, receiver);
|
|
481
475
|
if (success) {
|
|
482
476
|
context.eventTarget.dispatchEvent({
|
|
@@ -502,7 +496,7 @@ function createObservableProxyInternal(target, path, context) {
|
|
|
502
496
|
return Reflect.deleteProperty(obj, prop);
|
|
503
497
|
}
|
|
504
498
|
const propPath = path ? `${path}.${String(prop)}` : String(prop);
|
|
505
|
-
const previousState = cloneForComparison(context.originalRoot, context.options.cloneStrategy, propPath);
|
|
499
|
+
const previousState = cloneForComparison(context.originalRoot, context.options.cloneStrategy, propPath, context.options.deepClone);
|
|
506
500
|
const success = Reflect.deleteProperty(obj, prop);
|
|
507
501
|
if (success) {
|
|
508
502
|
context.eventTarget.dispatchEvent({
|
|
@@ -535,6 +529,8 @@ function isEventTarget(obj) {
|
|
|
535
529
|
}
|
|
536
530
|
function setupEventForwarding(source, target) {
|
|
537
531
|
const handlers = new Map;
|
|
532
|
+
const sourceAddEventListener = source.addEventListener.bind(source);
|
|
533
|
+
const sourceRemoveEventListener = source.removeEventListener.bind(source);
|
|
538
534
|
const forwardHandler = (type) => (event) => {
|
|
539
535
|
const detail = event.detail ?? event;
|
|
540
536
|
target.dispatchEvent({
|
|
@@ -547,7 +543,7 @@ function setupEventForwarding(source, target) {
|
|
|
547
543
|
if (!handlers.has(type) && type !== "update" && !type.startsWith("update:")) {
|
|
548
544
|
const handler = forwardHandler(type);
|
|
549
545
|
handlers.set(type, handler);
|
|
550
|
-
|
|
546
|
+
sourceAddEventListener(type, handler);
|
|
551
547
|
}
|
|
552
548
|
return originalAddEventListener(type, listener, options);
|
|
553
549
|
};
|
|
@@ -555,7 +551,7 @@ function setupEventForwarding(source, target) {
|
|
|
555
551
|
return () => {
|
|
556
552
|
target.addEventListener = originalAddEventListener;
|
|
557
553
|
for (const [type, handler] of handlers) {
|
|
558
|
-
|
|
554
|
+
sourceRemoveEventListener(type, handler);
|
|
559
555
|
}
|
|
560
556
|
handlers.clear();
|
|
561
557
|
};
|
|
@@ -572,7 +568,8 @@ function getOriginal(proxy) {
|
|
|
572
568
|
function createObservableProxy(target, eventTarget, options) {
|
|
573
569
|
const resolvedOptions = {
|
|
574
570
|
deep: options?.deep ?? true,
|
|
575
|
-
cloneStrategy: options?.cloneStrategy ?? "path"
|
|
571
|
+
cloneStrategy: options?.cloneStrategy ?? "path",
|
|
572
|
+
deepClone: options?.deepClone
|
|
576
573
|
};
|
|
577
574
|
const context = {
|
|
578
575
|
eventTarget,
|
|
@@ -581,21 +578,47 @@ function createObservableProxy(target, eventTarget, options) {
|
|
|
581
578
|
};
|
|
582
579
|
const proxy = createObservableProxyInternal(target, "", context);
|
|
583
580
|
if (isEventTarget(target)) {
|
|
584
|
-
setupEventForwarding(target, eventTarget);
|
|
581
|
+
const cleanupForwarding = setupEventForwarding(target, eventTarget);
|
|
582
|
+
const maybeComplete = eventTarget.complete;
|
|
583
|
+
if (typeof maybeComplete === "function") {
|
|
584
|
+
const originalComplete = maybeComplete.bind(eventTarget);
|
|
585
|
+
let cleaned = false;
|
|
586
|
+
eventTarget.complete = () => {
|
|
587
|
+
if (!cleaned) {
|
|
588
|
+
cleaned = true;
|
|
589
|
+
cleanupForwarding();
|
|
590
|
+
}
|
|
591
|
+
return originalComplete();
|
|
592
|
+
};
|
|
593
|
+
}
|
|
585
594
|
}
|
|
586
595
|
return proxy;
|
|
587
596
|
}
|
|
588
597
|
|
|
598
|
+
// src/index.ts
|
|
599
|
+
var exports_src = {};
|
|
600
|
+
__export(exports_src, {
|
|
601
|
+
createEventTarget: () => createEventTarget,
|
|
602
|
+
SymbolObservable: () => SymbolObservable,
|
|
603
|
+
EventEmission: () => EventEmission,
|
|
604
|
+
BufferOverflowError: () => BufferOverflowError
|
|
605
|
+
});
|
|
606
|
+
module.exports = __toCommonJS(exports_src);
|
|
607
|
+
|
|
608
|
+
// src/errors.ts
|
|
609
|
+
class BufferOverflowError extends Error {
|
|
610
|
+
constructor(eventType, bufferSize) {
|
|
611
|
+
super(`Buffer overflow for event type "${eventType}" (max: ${bufferSize})`);
|
|
612
|
+
this.name = "BufferOverflowError";
|
|
613
|
+
}
|
|
614
|
+
}
|
|
589
615
|
// src/factory.ts
|
|
590
616
|
function matchesWildcard(eventType, pattern) {
|
|
591
617
|
if (pattern === "*")
|
|
592
618
|
return true;
|
|
593
|
-
|
|
594
|
-
const namespace = pattern.slice(0, -2);
|
|
595
|
-
return eventType.startsWith(namespace + ":");
|
|
596
|
-
}
|
|
597
|
-
return false;
|
|
619
|
+
return pattern.endsWith(":*") && eventType.startsWith(pattern.slice(0, -2) + ":");
|
|
598
620
|
}
|
|
621
|
+
var EVENT_STATE = Symbol("event-emission:event-state");
|
|
599
622
|
function createEventTarget(targetOrOpts, opts) {
|
|
600
623
|
if (opts?.observe === true && targetOrOpts && typeof targetOrOpts === "object") {
|
|
601
624
|
const target = targetOrOpts;
|
|
@@ -604,7 +627,8 @@ function createEventTarget(targetOrOpts, opts) {
|
|
|
604
627
|
});
|
|
605
628
|
const proxy = createObservableProxy(target, eventTarget, {
|
|
606
629
|
deep: opts.deep,
|
|
607
|
-
cloneStrategy: opts.cloneStrategy
|
|
630
|
+
cloneStrategy: opts.cloneStrategy,
|
|
631
|
+
deepClone: opts.deepClone
|
|
608
632
|
});
|
|
609
633
|
const methodNames = [
|
|
610
634
|
"addEventListener",
|
|
@@ -620,7 +644,17 @@ function createEventTarget(targetOrOpts, opts) {
|
|
|
620
644
|
"complete",
|
|
621
645
|
"subscribe",
|
|
622
646
|
"toObservable",
|
|
623
|
-
"events"
|
|
647
|
+
"events",
|
|
648
|
+
"emit",
|
|
649
|
+
"off",
|
|
650
|
+
"addListener",
|
|
651
|
+
"removeListener",
|
|
652
|
+
"prependListener",
|
|
653
|
+
"prependOnceListener",
|
|
654
|
+
"listeners",
|
|
655
|
+
"rawListeners",
|
|
656
|
+
"listenerCount",
|
|
657
|
+
"eventNames"
|
|
624
658
|
];
|
|
625
659
|
for (const name of methodNames) {
|
|
626
660
|
Object.defineProperty(proxy, name, {
|
|
@@ -644,38 +678,202 @@ function createEventTargetInternal(opts) {
|
|
|
644
678
|
const wildcardListeners = new Set;
|
|
645
679
|
let isCompleted = false;
|
|
646
680
|
const completionCallbacks = new Set;
|
|
647
|
-
const
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
681
|
+
const now = () => typeof globalThis.performance?.now === "function" ? globalThis.performance.now() : Date.now();
|
|
682
|
+
const initializeEventState = (state, type, bubbles, cancelable) => {
|
|
683
|
+
state.initializedFlag = true;
|
|
684
|
+
state.stopPropagationFlag = false;
|
|
685
|
+
state.stopImmediatePropagationFlag = false;
|
|
686
|
+
state.canceledFlag = false;
|
|
687
|
+
state.isTrusted = false;
|
|
688
|
+
state.target = null;
|
|
689
|
+
state.currentTarget = null;
|
|
690
|
+
state.eventPhase = 0;
|
|
691
|
+
state.type = type;
|
|
692
|
+
state.bubbles = bubbles;
|
|
693
|
+
state.cancelable = cancelable;
|
|
694
|
+
};
|
|
695
|
+
const setCanceledFlag = (state) => {
|
|
696
|
+
if (state.cancelable && !state.inPassiveListenerFlag) {
|
|
697
|
+
state.canceledFlag = true;
|
|
698
|
+
}
|
|
699
|
+
};
|
|
700
|
+
const createEvent = (type, detail, init) => {
|
|
701
|
+
const state = {
|
|
702
|
+
dispatchFlag: false,
|
|
703
|
+
initializedFlag: true,
|
|
704
|
+
stopPropagationFlag: false,
|
|
705
|
+
stopImmediatePropagationFlag: false,
|
|
706
|
+
canceledFlag: false,
|
|
707
|
+
inPassiveListenerFlag: false,
|
|
708
|
+
composedFlag: Boolean(init?.composed),
|
|
709
|
+
eventPhase: init?.eventPhase ?? 0,
|
|
710
|
+
currentTarget: init?.currentTarget ?? init?.target ?? null,
|
|
711
|
+
target: init?.target ?? null,
|
|
712
|
+
timeStamp: init?.timeStamp ?? now(),
|
|
713
|
+
path: [],
|
|
714
|
+
type,
|
|
715
|
+
bubbles: Boolean(init?.bubbles),
|
|
716
|
+
cancelable: Boolean(init?.cancelable),
|
|
717
|
+
isTrusted: false
|
|
663
718
|
};
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
719
|
+
const event = { detail };
|
|
720
|
+
Object.defineProperties(event, {
|
|
721
|
+
type: {
|
|
722
|
+
get: () => state.type,
|
|
723
|
+
enumerable: true,
|
|
724
|
+
configurable: true
|
|
725
|
+
},
|
|
726
|
+
bubbles: {
|
|
727
|
+
get: () => state.bubbles,
|
|
728
|
+
enumerable: true,
|
|
729
|
+
configurable: true
|
|
730
|
+
},
|
|
731
|
+
cancelable: {
|
|
732
|
+
get: () => state.cancelable,
|
|
733
|
+
enumerable: true,
|
|
734
|
+
configurable: true
|
|
735
|
+
},
|
|
736
|
+
cancelBubble: {
|
|
737
|
+
get: () => state.stopPropagationFlag,
|
|
738
|
+
set: (value) => {
|
|
739
|
+
if (value)
|
|
740
|
+
state.stopPropagationFlag = true;
|
|
741
|
+
},
|
|
742
|
+
enumerable: true,
|
|
743
|
+
configurable: true
|
|
744
|
+
},
|
|
745
|
+
composed: {
|
|
746
|
+
get: () => state.composedFlag,
|
|
747
|
+
enumerable: true,
|
|
748
|
+
configurable: true
|
|
749
|
+
},
|
|
750
|
+
currentTarget: {
|
|
751
|
+
get: () => state.currentTarget,
|
|
752
|
+
enumerable: true,
|
|
753
|
+
configurable: true
|
|
754
|
+
},
|
|
755
|
+
defaultPrevented: {
|
|
756
|
+
get: () => state.canceledFlag,
|
|
757
|
+
enumerable: true,
|
|
758
|
+
configurable: true
|
|
759
|
+
},
|
|
760
|
+
eventPhase: {
|
|
761
|
+
get: () => state.eventPhase,
|
|
762
|
+
enumerable: true,
|
|
763
|
+
configurable: true
|
|
764
|
+
},
|
|
765
|
+
isTrusted: {
|
|
766
|
+
get: () => state.isTrusted,
|
|
767
|
+
enumerable: true,
|
|
768
|
+
configurable: true
|
|
769
|
+
},
|
|
770
|
+
returnValue: {
|
|
771
|
+
get: () => !state.canceledFlag,
|
|
772
|
+
set: (value) => {
|
|
773
|
+
if (value === false)
|
|
774
|
+
setCanceledFlag(state);
|
|
775
|
+
},
|
|
776
|
+
enumerable: true,
|
|
777
|
+
configurable: true
|
|
778
|
+
},
|
|
779
|
+
srcElement: {
|
|
780
|
+
get: () => state.target,
|
|
781
|
+
enumerable: true,
|
|
782
|
+
configurable: true
|
|
783
|
+
},
|
|
784
|
+
target: {
|
|
785
|
+
get: () => state.target,
|
|
786
|
+
enumerable: true,
|
|
787
|
+
configurable: true
|
|
788
|
+
},
|
|
789
|
+
timeStamp: {
|
|
790
|
+
get: () => state.timeStamp,
|
|
791
|
+
enumerable: true,
|
|
792
|
+
configurable: true
|
|
793
|
+
},
|
|
794
|
+
composedPath: {
|
|
795
|
+
value: () => state.path.map((entry) => entry.invocationTarget),
|
|
796
|
+
enumerable: true,
|
|
797
|
+
configurable: true
|
|
798
|
+
},
|
|
799
|
+
initEvent: {
|
|
800
|
+
value: (newType, bubbles = false, cancelable = false) => {
|
|
801
|
+
if (state.dispatchFlag)
|
|
802
|
+
return;
|
|
803
|
+
initializeEventState(state, newType, Boolean(bubbles), Boolean(cancelable));
|
|
804
|
+
},
|
|
805
|
+
enumerable: true,
|
|
806
|
+
configurable: true
|
|
807
|
+
},
|
|
667
808
|
preventDefault: {
|
|
668
|
-
value:
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
809
|
+
value: () => setCanceledFlag(state),
|
|
810
|
+
enumerable: true,
|
|
811
|
+
configurable: true
|
|
812
|
+
},
|
|
813
|
+
stopImmediatePropagation: {
|
|
814
|
+
value: () => {
|
|
815
|
+
state.stopPropagationFlag = true;
|
|
816
|
+
state.stopImmediatePropagationFlag = true;
|
|
674
817
|
},
|
|
675
818
|
enumerable: true,
|
|
676
819
|
configurable: true
|
|
820
|
+
},
|
|
821
|
+
stopPropagation: {
|
|
822
|
+
value: () => {
|
|
823
|
+
state.stopPropagationFlag = true;
|
|
824
|
+
},
|
|
825
|
+
enumerable: true,
|
|
826
|
+
configurable: true
|
|
827
|
+
},
|
|
828
|
+
NONE: { value: 0, enumerable: true, configurable: true },
|
|
829
|
+
CAPTURING_PHASE: { value: 1, enumerable: true, configurable: true },
|
|
830
|
+
AT_TARGET: { value: 2, enumerable: true, configurable: true },
|
|
831
|
+
BUBBLING_PHASE: { value: 3, enumerable: true, configurable: true },
|
|
832
|
+
[EVENT_STATE]: {
|
|
833
|
+
value: state,
|
|
834
|
+
enumerable: false,
|
|
835
|
+
configurable: false
|
|
677
836
|
}
|
|
678
837
|
});
|
|
838
|
+
return event;
|
|
839
|
+
};
|
|
840
|
+
const getEventState = (event) => event[EVENT_STATE];
|
|
841
|
+
const normalizeAddListenerOptions = (options) => {
|
|
842
|
+
if (typeof options === "boolean") {
|
|
843
|
+
return {
|
|
844
|
+
capture: options,
|
|
845
|
+
passive: false,
|
|
846
|
+
once: false,
|
|
847
|
+
signal: null
|
|
848
|
+
};
|
|
849
|
+
}
|
|
850
|
+
return {
|
|
851
|
+
capture: Boolean(options?.capture),
|
|
852
|
+
passive: Boolean(options?.passive),
|
|
853
|
+
once: Boolean(options?.once),
|
|
854
|
+
signal: options?.signal ?? null
|
|
855
|
+
};
|
|
856
|
+
};
|
|
857
|
+
const normalizeCaptureOption = (options) => {
|
|
858
|
+
if (typeof options === "boolean")
|
|
859
|
+
return options;
|
|
860
|
+
return Boolean(options?.capture);
|
|
861
|
+
};
|
|
862
|
+
const removeListenerRecord = (type, record) => {
|
|
863
|
+
if (record.removed)
|
|
864
|
+
return;
|
|
865
|
+
record.removed = true;
|
|
866
|
+
const list = listeners.get(type);
|
|
867
|
+
if (list) {
|
|
868
|
+
const idx = list.indexOf(record);
|
|
869
|
+
if (idx >= 0)
|
|
870
|
+
list.splice(idx, 1);
|
|
871
|
+
if (list.length === 0)
|
|
872
|
+
listeners.delete(type);
|
|
873
|
+
}
|
|
874
|
+
if (record.signal && record.abortHandler) {
|
|
875
|
+
record.signal.removeEventListener("abort", record.abortHandler);
|
|
876
|
+
}
|
|
679
877
|
};
|
|
680
878
|
const handleListenerError = (eventType, error2) => {
|
|
681
879
|
if (eventType === "error")
|
|
@@ -685,28 +883,27 @@ function createEventTargetInternal(opts) {
|
|
|
685
883
|
return;
|
|
686
884
|
}
|
|
687
885
|
const errorListeners = listeners.get("error");
|
|
688
|
-
if (errorListeners && errorListeners.
|
|
689
|
-
|
|
690
|
-
for (const rec of Array.from(errorListeners)) {
|
|
691
|
-
try {
|
|
692
|
-
const fn = rec.fn;
|
|
693
|
-
fn(errorEvent);
|
|
694
|
-
} catch {}
|
|
695
|
-
if (rec.once)
|
|
696
|
-
errorListeners.delete(rec);
|
|
697
|
-
}
|
|
886
|
+
if (errorListeners && errorListeners.length > 0) {
|
|
887
|
+
dispatchEvent({ type: "error", detail: error2 });
|
|
698
888
|
} else {
|
|
699
889
|
throw error2;
|
|
700
890
|
}
|
|
701
891
|
};
|
|
702
|
-
const notifyWildcardListeners = (eventType,
|
|
892
|
+
const notifyWildcardListeners = (eventType, event) => {
|
|
703
893
|
if (wildcardListeners.size === 0)
|
|
704
894
|
return;
|
|
705
895
|
for (const rec of Array.from(wildcardListeners)) {
|
|
706
896
|
if (!matchesWildcard(eventType, rec.pattern))
|
|
707
897
|
continue;
|
|
708
|
-
const
|
|
709
|
-
|
|
898
|
+
const baseEvent = createEvent(rec.pattern, event.detail, {
|
|
899
|
+
target,
|
|
900
|
+
currentTarget: target,
|
|
901
|
+
eventPhase: 2,
|
|
902
|
+
bubbles: event.bubbles,
|
|
903
|
+
cancelable: event.cancelable,
|
|
904
|
+
composed: event.composed
|
|
905
|
+
});
|
|
906
|
+
const wildcardEvent = Object.defineProperties(baseEvent, {
|
|
710
907
|
originalType: { value: eventType, enumerable: true, configurable: true }
|
|
711
908
|
});
|
|
712
909
|
try {
|
|
@@ -729,44 +926,66 @@ function createEventTargetInternal(opts) {
|
|
|
729
926
|
if (rec.once)
|
|
730
927
|
wildcardListeners.delete(rec);
|
|
731
928
|
}
|
|
929
|
+
const state = getEventState(wildcardEvent);
|
|
930
|
+
if (state?.stopImmediatePropagationFlag || state?.stopPropagationFlag) {
|
|
931
|
+
break;
|
|
932
|
+
}
|
|
732
933
|
}
|
|
733
934
|
};
|
|
734
|
-
const
|
|
735
|
-
if (isCompleted) {
|
|
935
|
+
const addListenerInternal = (type, listener, options, position) => {
|
|
936
|
+
if (isCompleted || !listener) {
|
|
736
937
|
return () => {};
|
|
737
938
|
}
|
|
738
|
-
const
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
};
|
|
744
|
-
let set = listeners.get(type);
|
|
745
|
-
if (!set) {
|
|
746
|
-
set = new Set;
|
|
747
|
-
listeners.set(type, set);
|
|
939
|
+
const { capture, passive, once, signal } = normalizeAddListenerOptions(options);
|
|
940
|
+
let list = listeners.get(type);
|
|
941
|
+
if (!list) {
|
|
942
|
+
list = [];
|
|
943
|
+
listeners.set(type, list);
|
|
748
944
|
}
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
setNow?.delete(record);
|
|
753
|
-
if (record.signal && record.abortHandler) {
|
|
754
|
-
record.signal.removeEventListener("abort", record.abortHandler);
|
|
945
|
+
for (const existing of list) {
|
|
946
|
+
if (existing.original === listener && existing.capture === capture) {
|
|
947
|
+
return () => removeEventListener(type, listener, options);
|
|
755
948
|
}
|
|
949
|
+
}
|
|
950
|
+
const original = listener;
|
|
951
|
+
const callback = typeof listener === "function" ? listener : (event) => listener.handleEvent(event);
|
|
952
|
+
const record = {
|
|
953
|
+
type,
|
|
954
|
+
original,
|
|
955
|
+
callback,
|
|
956
|
+
capture,
|
|
957
|
+
passive,
|
|
958
|
+
once,
|
|
959
|
+
signal,
|
|
960
|
+
removed: false
|
|
756
961
|
};
|
|
757
|
-
if (
|
|
758
|
-
|
|
962
|
+
if (position === "prepend") {
|
|
963
|
+
list.unshift(record);
|
|
964
|
+
} else {
|
|
965
|
+
list.push(record);
|
|
966
|
+
}
|
|
967
|
+
const unsubscribe2 = () => removeListenerRecord(type, record);
|
|
968
|
+
if (signal) {
|
|
969
|
+
const onAbort = () => removeListenerRecord(type, record);
|
|
759
970
|
record.abortHandler = onAbort;
|
|
760
|
-
|
|
761
|
-
if (
|
|
971
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
972
|
+
if (signal.aborted)
|
|
762
973
|
onAbort();
|
|
763
974
|
}
|
|
764
975
|
return unsubscribe2;
|
|
765
976
|
};
|
|
977
|
+
const addEventListener = (type, listener, options) => {
|
|
978
|
+
return addListenerInternal(type, listener, options, "append");
|
|
979
|
+
};
|
|
766
980
|
const addWildcardListener = (pattern, listener, options) => {
|
|
767
981
|
if (isCompleted)
|
|
768
982
|
return () => {};
|
|
769
983
|
const opts2 = options ?? {};
|
|
984
|
+
for (const existing of wildcardListeners) {
|
|
985
|
+
if (existing.pattern === pattern && existing.fn === listener) {
|
|
986
|
+
return () => removeWildcardListener(pattern, listener);
|
|
987
|
+
}
|
|
988
|
+
}
|
|
770
989
|
const record = {
|
|
771
990
|
fn: listener,
|
|
772
991
|
pattern,
|
|
@@ -790,31 +1009,39 @@ function createEventTargetInternal(opts) {
|
|
|
790
1009
|
return unsubscribe2;
|
|
791
1010
|
};
|
|
792
1011
|
const removeWildcardListener = (pattern, listener) => {
|
|
793
|
-
for (const record of wildcardListeners) {
|
|
1012
|
+
for (const record of Array.from(wildcardListeners)) {
|
|
794
1013
|
if (record.pattern === pattern && record.fn === listener) {
|
|
795
1014
|
wildcardListeners.delete(record);
|
|
796
1015
|
if (record.signal && record.abortHandler) {
|
|
797
1016
|
record.signal.removeEventListener("abort", record.abortHandler);
|
|
798
1017
|
}
|
|
799
|
-
break;
|
|
800
1018
|
}
|
|
801
1019
|
}
|
|
802
1020
|
};
|
|
803
|
-
const
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
1021
|
+
const invokeListeners = (eventType, event, phase, listenersSnapshot) => {
|
|
1022
|
+
const state = getEventState(event);
|
|
1023
|
+
if (!state || state.stopPropagationFlag)
|
|
1024
|
+
return;
|
|
1025
|
+
state.currentTarget = target;
|
|
1026
|
+
state.target = target;
|
|
1027
|
+
state.eventPhase = event.AT_TARGET;
|
|
1028
|
+
for (const rec of listenersSnapshot) {
|
|
1029
|
+
if (rec.removed)
|
|
1030
|
+
continue;
|
|
1031
|
+
if (phase === "capturing" && !rec.capture)
|
|
1032
|
+
continue;
|
|
1033
|
+
if (phase === "bubbling" && rec.capture)
|
|
1034
|
+
continue;
|
|
1035
|
+
if (rec.once)
|
|
1036
|
+
removeListenerRecord(rec.type, rec);
|
|
1037
|
+
if (rec.passive)
|
|
1038
|
+
state.inPassiveListenerFlag = true;
|
|
812
1039
|
try {
|
|
813
|
-
const res = rec.
|
|
1040
|
+
const res = rec.callback.call(state.currentTarget, event);
|
|
814
1041
|
if (res && typeof res.then === "function") {
|
|
815
1042
|
res.catch((error2) => {
|
|
816
1043
|
try {
|
|
817
|
-
handleListenerError(
|
|
1044
|
+
handleListenerError(eventType, error2);
|
|
818
1045
|
} catch (rethrown) {
|
|
819
1046
|
queueMicrotask(() => {
|
|
820
1047
|
throw rethrown;
|
|
@@ -823,36 +1050,94 @@ function createEventTargetInternal(opts) {
|
|
|
823
1050
|
});
|
|
824
1051
|
}
|
|
825
1052
|
} catch (error2) {
|
|
826
|
-
handleListenerError(
|
|
1053
|
+
handleListenerError(eventType, error2);
|
|
827
1054
|
} finally {
|
|
828
|
-
if (rec.
|
|
829
|
-
|
|
1055
|
+
if (rec.passive)
|
|
1056
|
+
state.inPassiveListenerFlag = false;
|
|
830
1057
|
}
|
|
1058
|
+
if (state.stopImmediatePropagationFlag)
|
|
1059
|
+
break;
|
|
831
1060
|
}
|
|
832
|
-
return true;
|
|
833
1061
|
};
|
|
834
|
-
const
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
1062
|
+
const dispatchEvent = (eventInput) => {
|
|
1063
|
+
if (isCompleted)
|
|
1064
|
+
return false;
|
|
1065
|
+
let event;
|
|
1066
|
+
let state;
|
|
1067
|
+
if (eventInput && typeof eventInput === "object") {
|
|
1068
|
+
state = getEventState(eventInput);
|
|
1069
|
+
if (state) {
|
|
1070
|
+
event = eventInput;
|
|
1071
|
+
} else {
|
|
1072
|
+
const input = eventInput;
|
|
1073
|
+
if (typeof input.type !== "string") {
|
|
1074
|
+
throw new TypeError("Event type must be a string");
|
|
843
1075
|
}
|
|
844
|
-
|
|
1076
|
+
event = createEvent(input.type, input.detail, {
|
|
1077
|
+
bubbles: input.bubbles,
|
|
1078
|
+
cancelable: input.cancelable,
|
|
1079
|
+
composed: input.composed,
|
|
1080
|
+
timeStamp: input.timeStamp
|
|
1081
|
+
});
|
|
1082
|
+
state = getEventState(event);
|
|
1083
|
+
}
|
|
1084
|
+
} else {
|
|
1085
|
+
throw new TypeError("dispatchEvent expects an event object");
|
|
1086
|
+
}
|
|
1087
|
+
const dispatchState = state ?? getEventState(event);
|
|
1088
|
+
if (dispatchState.dispatchFlag || !dispatchState.initializedFlag) {
|
|
1089
|
+
const message = "Failed to execute dispatchEvent: event is already being dispatched";
|
|
1090
|
+
if (typeof globalThis.DOMException === "function") {
|
|
1091
|
+
throw new globalThis.DOMException(message, "InvalidStateError");
|
|
1092
|
+
}
|
|
1093
|
+
const err = new Error(message);
|
|
1094
|
+
err.name = "InvalidStateError";
|
|
1095
|
+
throw err;
|
|
1096
|
+
}
|
|
1097
|
+
dispatchState.isTrusted = false;
|
|
1098
|
+
dispatchState.dispatchFlag = true;
|
|
1099
|
+
dispatchState.path = [
|
|
1100
|
+
{
|
|
1101
|
+
invocationTarget: target,
|
|
1102
|
+
invocationTargetInShadowTree: false,
|
|
1103
|
+
shadowAdjustedTarget: target,
|
|
1104
|
+
relatedTarget: null,
|
|
1105
|
+
touchTargets: [],
|
|
1106
|
+
rootOfClosedTree: false,
|
|
1107
|
+
slotInClosedTree: false
|
|
1108
|
+
}
|
|
1109
|
+
];
|
|
1110
|
+
notifyWildcardListeners(dispatchState.type, event);
|
|
1111
|
+
const list = listeners.get(dispatchState.type);
|
|
1112
|
+
const snapshot = list ? list.slice() : [];
|
|
1113
|
+
invokeListeners(dispatchState.type, event, "capturing", snapshot);
|
|
1114
|
+
invokeListeners(dispatchState.type, event, "bubbling", snapshot);
|
|
1115
|
+
dispatchState.eventPhase = event.NONE;
|
|
1116
|
+
dispatchState.currentTarget = null;
|
|
1117
|
+
dispatchState.path = [];
|
|
1118
|
+
dispatchState.dispatchFlag = false;
|
|
1119
|
+
dispatchState.stopPropagationFlag = false;
|
|
1120
|
+
dispatchState.stopImmediatePropagationFlag = false;
|
|
1121
|
+
return !dispatchState.canceledFlag;
|
|
1122
|
+
};
|
|
1123
|
+
const removeEventListener = (type, listener, options) => {
|
|
1124
|
+
if (!listener)
|
|
1125
|
+
return;
|
|
1126
|
+
const capture = normalizeCaptureOption(options);
|
|
1127
|
+
const list = listeners.get(type);
|
|
1128
|
+
if (!list)
|
|
1129
|
+
return;
|
|
1130
|
+
for (const record of [...list]) {
|
|
1131
|
+
if (record.original === listener && record.capture === capture) {
|
|
1132
|
+
removeListenerRecord(type, record);
|
|
845
1133
|
}
|
|
846
1134
|
}
|
|
847
1135
|
};
|
|
848
1136
|
const clear = () => {
|
|
849
|
-
for (const
|
|
850
|
-
for (const record of
|
|
851
|
-
|
|
852
|
-
record.signal.removeEventListener("abort", record.abortHandler);
|
|
853
|
-
}
|
|
1137
|
+
for (const [type, list] of Array.from(listeners.entries())) {
|
|
1138
|
+
for (const record of [...list]) {
|
|
1139
|
+
removeListenerRecord(type, record);
|
|
854
1140
|
}
|
|
855
|
-
set.clear();
|
|
856
1141
|
}
|
|
857
1142
|
listeners.clear();
|
|
858
1143
|
for (const record of wildcardListeners) {
|
|
@@ -862,11 +1147,22 @@ function createEventTargetInternal(opts) {
|
|
|
862
1147
|
}
|
|
863
1148
|
wildcardListeners.clear();
|
|
864
1149
|
};
|
|
865
|
-
const
|
|
1150
|
+
const isListenerArg = (arg) => {
|
|
1151
|
+
if (typeof arg === "function")
|
|
1152
|
+
return true;
|
|
1153
|
+
if (arg && typeof arg === "object" && typeof arg.handleEvent === "function")
|
|
1154
|
+
return true;
|
|
1155
|
+
return false;
|
|
1156
|
+
};
|
|
1157
|
+
const on = (type, optionsOrListener) => {
|
|
1158
|
+
if (isListenerArg(optionsOrListener)) {
|
|
1159
|
+
return addEventListener(type, optionsOrListener);
|
|
1160
|
+
}
|
|
1161
|
+
const options = optionsOrListener;
|
|
866
1162
|
return new Observable((observer) => {
|
|
867
1163
|
let opts2;
|
|
868
1164
|
if (typeof options === "boolean") {
|
|
869
|
-
opts2 = {
|
|
1165
|
+
opts2 = { capture: options };
|
|
870
1166
|
} else {
|
|
871
1167
|
opts2 = options ?? {};
|
|
872
1168
|
}
|
|
@@ -903,28 +1199,25 @@ function createEventTargetInternal(opts) {
|
|
|
903
1199
|
});
|
|
904
1200
|
};
|
|
905
1201
|
const onceMethod = (type, listener, options) => {
|
|
906
|
-
|
|
1202
|
+
if (typeof options === "boolean") {
|
|
1203
|
+
return addEventListener(type, listener, { capture: options, once: true });
|
|
1204
|
+
}
|
|
1205
|
+
return addEventListener(type, listener, { ...options ?? {}, once: true });
|
|
907
1206
|
};
|
|
908
1207
|
const removeAllListeners = (type) => {
|
|
909
1208
|
if (type !== undefined) {
|
|
910
|
-
const
|
|
911
|
-
if (
|
|
912
|
-
for (const record of
|
|
913
|
-
|
|
914
|
-
record.signal.removeEventListener("abort", record.abortHandler);
|
|
915
|
-
}
|
|
1209
|
+
const list = listeners.get(type);
|
|
1210
|
+
if (list) {
|
|
1211
|
+
for (const record of [...list]) {
|
|
1212
|
+
removeListenerRecord(type, record);
|
|
916
1213
|
}
|
|
917
|
-
set.clear();
|
|
918
1214
|
listeners.delete(type);
|
|
919
1215
|
}
|
|
920
1216
|
} else {
|
|
921
|
-
for (const
|
|
922
|
-
for (const record of
|
|
923
|
-
|
|
924
|
-
record.signal.removeEventListener("abort", record.abortHandler);
|
|
925
|
-
}
|
|
1217
|
+
for (const [eventType, list] of Array.from(listeners.entries())) {
|
|
1218
|
+
for (const record of [...list]) {
|
|
1219
|
+
removeListenerRecord(eventType, record);
|
|
926
1220
|
}
|
|
927
|
-
set.clear();
|
|
928
1221
|
}
|
|
929
1222
|
listeners.clear();
|
|
930
1223
|
for (const record of wildcardListeners) {
|
|
@@ -939,38 +1232,33 @@ function createEventTargetInternal(opts) {
|
|
|
939
1232
|
if (isCompleted) {
|
|
940
1233
|
return () => {};
|
|
941
1234
|
}
|
|
942
|
-
const
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
} else {
|
|
955
|
-
target2.dispatchEvent(event);
|
|
1235
|
+
const unsubscribe2 = addWildcardListener("*", (event) => {
|
|
1236
|
+
if (mapFn) {
|
|
1237
|
+
const mapped = mapFn(createEvent(event.originalType, event.detail, {
|
|
1238
|
+
target: target2,
|
|
1239
|
+
currentTarget: target2,
|
|
1240
|
+
eventPhase: 2,
|
|
1241
|
+
bubbles: event.bubbles,
|
|
1242
|
+
cancelable: event.cancelable,
|
|
1243
|
+
composed: event.composed
|
|
1244
|
+
}));
|
|
1245
|
+
if (mapped !== null) {
|
|
1246
|
+
target2.dispatchEvent(mapped);
|
|
956
1247
|
}
|
|
957
|
-
}
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
}
|
|
963
|
-
const completionUnsub = () => {
|
|
964
|
-
for (const unsub of unsubscribes) {
|
|
965
|
-
unsub();
|
|
1248
|
+
} else {
|
|
1249
|
+
target2.dispatchEvent({
|
|
1250
|
+
type: event.originalType,
|
|
1251
|
+
detail: event.detail
|
|
1252
|
+
});
|
|
966
1253
|
}
|
|
1254
|
+
});
|
|
1255
|
+
const completionUnsub = () => {
|
|
1256
|
+
unsubscribe2();
|
|
967
1257
|
};
|
|
968
1258
|
completionCallbacks.add(completionUnsub);
|
|
969
1259
|
return () => {
|
|
970
1260
|
completionCallbacks.delete(completionUnsub);
|
|
971
|
-
|
|
972
|
-
unsub();
|
|
973
|
-
}
|
|
1261
|
+
unsubscribe2();
|
|
974
1262
|
};
|
|
975
1263
|
};
|
|
976
1264
|
const complete2 = () => {
|
|
@@ -987,13 +1275,10 @@ function createEventTargetInternal(opts) {
|
|
|
987
1275
|
}
|
|
988
1276
|
}
|
|
989
1277
|
completionCallbacks.clear();
|
|
990
|
-
for (const
|
|
991
|
-
for (const record of
|
|
992
|
-
|
|
993
|
-
record.signal.removeEventListener("abort", record.abortHandler);
|
|
994
|
-
}
|
|
1278
|
+
for (const [eventType, list] of Array.from(listeners.entries())) {
|
|
1279
|
+
for (const record of [...list]) {
|
|
1280
|
+
removeListenerRecord(eventType, record);
|
|
995
1281
|
}
|
|
996
|
-
set.clear();
|
|
997
1282
|
}
|
|
998
1283
|
listeners.clear();
|
|
999
1284
|
for (const record of wildcardListeners) {
|
|
@@ -1076,7 +1361,14 @@ function createEventTargetInternal(opts) {
|
|
|
1076
1361
|
return;
|
|
1077
1362
|
}
|
|
1078
1363
|
const wildcardListener = (event) => {
|
|
1079
|
-
observer.next(
|
|
1364
|
+
observer.next(createEvent(event.originalType, event.detail, {
|
|
1365
|
+
target,
|
|
1366
|
+
currentTarget: target,
|
|
1367
|
+
eventPhase: 2,
|
|
1368
|
+
bubbles: event.bubbles,
|
|
1369
|
+
cancelable: event.cancelable,
|
|
1370
|
+
composed: event.composed
|
|
1371
|
+
}));
|
|
1080
1372
|
};
|
|
1081
1373
|
const unsubscribe2 = addWildcardListener("*", wildcardListener);
|
|
1082
1374
|
const onComplete = () => {
|
|
@@ -1116,19 +1408,26 @@ function createEventTargetInternal(opts) {
|
|
|
1116
1408
|
let resolve = null;
|
|
1117
1409
|
let done = false;
|
|
1118
1410
|
let hasOverflow = false;
|
|
1411
|
+
let onAbort = null;
|
|
1412
|
+
const cleanupAbortListener = () => {
|
|
1413
|
+
if (signal && onAbort) {
|
|
1414
|
+
signal.removeEventListener("abort", onAbort);
|
|
1415
|
+
}
|
|
1416
|
+
};
|
|
1119
1417
|
const unsub = addEventListener(type, (event) => {
|
|
1120
1418
|
if (done)
|
|
1121
1419
|
return;
|
|
1420
|
+
const typedEvent = event;
|
|
1122
1421
|
if (resolve) {
|
|
1123
1422
|
const r = resolve;
|
|
1124
1423
|
resolve = null;
|
|
1125
|
-
r({ value:
|
|
1424
|
+
r({ value: typedEvent, done: false });
|
|
1126
1425
|
} else {
|
|
1127
1426
|
if (buffer.length >= bufferSize && bufferSize !== Infinity) {
|
|
1128
1427
|
switch (overflowStrategy) {
|
|
1129
1428
|
case "drop-oldest":
|
|
1130
1429
|
buffer.shift();
|
|
1131
|
-
buffer.push(
|
|
1430
|
+
buffer.push(typedEvent);
|
|
1132
1431
|
break;
|
|
1133
1432
|
case "drop-latest":
|
|
1134
1433
|
break;
|
|
@@ -1137,15 +1436,17 @@ function createEventTargetInternal(opts) {
|
|
|
1137
1436
|
completionCallbacks.delete(onComplete);
|
|
1138
1437
|
done = true;
|
|
1139
1438
|
hasOverflow = true;
|
|
1439
|
+
cleanupAbortListener();
|
|
1140
1440
|
return;
|
|
1141
1441
|
}
|
|
1142
1442
|
} else {
|
|
1143
|
-
buffer.push(
|
|
1443
|
+
buffer.push(typedEvent);
|
|
1144
1444
|
}
|
|
1145
1445
|
}
|
|
1146
1446
|
});
|
|
1147
1447
|
const onComplete = () => {
|
|
1148
1448
|
done = true;
|
|
1449
|
+
cleanupAbortListener();
|
|
1149
1450
|
if (resolve) {
|
|
1150
1451
|
const r = resolve;
|
|
1151
1452
|
resolve = null;
|
|
@@ -1153,7 +1454,6 @@ function createEventTargetInternal(opts) {
|
|
|
1153
1454
|
}
|
|
1154
1455
|
};
|
|
1155
1456
|
completionCallbacks.add(onComplete);
|
|
1156
|
-
let onAbort = null;
|
|
1157
1457
|
if (signal) {
|
|
1158
1458
|
onAbort = () => {
|
|
1159
1459
|
done = true;
|
|
@@ -1177,26 +1477,22 @@ function createEventTargetInternal(opts) {
|
|
|
1177
1477
|
if (buffer.length > 0) {
|
|
1178
1478
|
return { value: buffer.shift(), done: false };
|
|
1179
1479
|
}
|
|
1180
|
-
if (hasOverflow) {
|
|
1181
|
-
hasOverflow = false;
|
|
1182
|
-
throw new BufferOverflowError(type, bufferSize);
|
|
1183
|
-
}
|
|
1184
|
-
if (done) {
|
|
1185
|
-
return { value: undefined, done: true };
|
|
1186
|
-
}
|
|
1187
1480
|
if (resolve !== null) {
|
|
1188
1481
|
return Promise.reject(new Error("Concurrent calls to next() are not supported on this async iterator"));
|
|
1189
1482
|
}
|
|
1190
1483
|
return new Promise((_resolve, _reject) => {
|
|
1191
|
-
if (done) {
|
|
1192
|
-
_resolve({ value: undefined, done: true });
|
|
1193
|
-
return;
|
|
1194
|
-
}
|
|
1195
1484
|
if (hasOverflow) {
|
|
1196
1485
|
hasOverflow = false;
|
|
1197
1486
|
_reject(new BufferOverflowError(type, bufferSize));
|
|
1198
1487
|
return;
|
|
1199
1488
|
}
|
|
1489
|
+
if (done) {
|
|
1490
|
+
_resolve({
|
|
1491
|
+
value: undefined,
|
|
1492
|
+
done: true
|
|
1493
|
+
});
|
|
1494
|
+
return;
|
|
1495
|
+
}
|
|
1200
1496
|
resolve = _resolve;
|
|
1201
1497
|
});
|
|
1202
1498
|
},
|
|
@@ -1209,9 +1505,7 @@ function createEventTargetInternal(opts) {
|
|
|
1209
1505
|
done = true;
|
|
1210
1506
|
completionCallbacks.delete(onComplete);
|
|
1211
1507
|
unsub();
|
|
1212
|
-
|
|
1213
|
-
signal.removeEventListener("abort", onAbort);
|
|
1214
|
-
}
|
|
1508
|
+
cleanupAbortListener();
|
|
1215
1509
|
return Promise.resolve({
|
|
1216
1510
|
value: undefined,
|
|
1217
1511
|
done: true
|
|
@@ -1220,6 +1514,72 @@ function createEventTargetInternal(opts) {
|
|
|
1220
1514
|
};
|
|
1221
1515
|
return iterator;
|
|
1222
1516
|
}
|
|
1517
|
+
const emit = (type, detail) => {
|
|
1518
|
+
if (isCompleted)
|
|
1519
|
+
return false;
|
|
1520
|
+
const list = listeners.get(type);
|
|
1521
|
+
const hasListeners = list !== undefined && list.length > 0;
|
|
1522
|
+
let hasWildcard = false;
|
|
1523
|
+
if (wildcardListeners.size > 0) {
|
|
1524
|
+
for (const rec of wildcardListeners) {
|
|
1525
|
+
if (matchesWildcard(type, rec.pattern)) {
|
|
1526
|
+
hasWildcard = true;
|
|
1527
|
+
break;
|
|
1528
|
+
}
|
|
1529
|
+
}
|
|
1530
|
+
}
|
|
1531
|
+
dispatchEvent({ type, detail });
|
|
1532
|
+
return hasListeners || hasWildcard;
|
|
1533
|
+
};
|
|
1534
|
+
const off = (type, listener) => {
|
|
1535
|
+
removeEventListener(type, listener);
|
|
1536
|
+
};
|
|
1537
|
+
const addListener = (type, listener) => {
|
|
1538
|
+
return addEventListener(type, listener);
|
|
1539
|
+
};
|
|
1540
|
+
const removeListener = (type, listener) => {
|
|
1541
|
+
removeEventListener(type, listener);
|
|
1542
|
+
};
|
|
1543
|
+
const prependListener = (type, listener) => {
|
|
1544
|
+
return addListenerInternal(type, listener, undefined, "prepend");
|
|
1545
|
+
};
|
|
1546
|
+
const prependOnceListener = (type, listener) => {
|
|
1547
|
+
return addListenerInternal(type, listener, { once: true }, "prepend");
|
|
1548
|
+
};
|
|
1549
|
+
const getListeners = (type) => {
|
|
1550
|
+
const list = listeners.get(type);
|
|
1551
|
+
if (!list)
|
|
1552
|
+
return [];
|
|
1553
|
+
return list.filter((r) => !r.removed).map((r) => r.original);
|
|
1554
|
+
};
|
|
1555
|
+
const rawListenersMethod = (type) => {
|
|
1556
|
+
const list = listeners.get(type);
|
|
1557
|
+
if (!list)
|
|
1558
|
+
return [];
|
|
1559
|
+
return list.filter((r) => !r.removed).map((r) => {
|
|
1560
|
+
if (r.once) {
|
|
1561
|
+
const wrapper = (...args) => r.callback(...args);
|
|
1562
|
+
wrapper.listener = r.original;
|
|
1563
|
+
return wrapper;
|
|
1564
|
+
}
|
|
1565
|
+
return r.original;
|
|
1566
|
+
});
|
|
1567
|
+
};
|
|
1568
|
+
const listenerCount = (type) => {
|
|
1569
|
+
const list = listeners.get(type);
|
|
1570
|
+
if (!list)
|
|
1571
|
+
return 0;
|
|
1572
|
+
return list.filter((r) => !r.removed).length;
|
|
1573
|
+
};
|
|
1574
|
+
const eventNamesMethod = () => {
|
|
1575
|
+
const names = [];
|
|
1576
|
+
for (const [type, list] of listeners) {
|
|
1577
|
+
if (list.some((r) => !r.removed)) {
|
|
1578
|
+
names.push(type);
|
|
1579
|
+
}
|
|
1580
|
+
}
|
|
1581
|
+
return names;
|
|
1582
|
+
};
|
|
1223
1583
|
const target = {
|
|
1224
1584
|
addEventListener,
|
|
1225
1585
|
removeEventListener,
|
|
@@ -1237,90 +1597,23 @@ function createEventTargetInternal(opts) {
|
|
|
1237
1597
|
},
|
|
1238
1598
|
subscribe,
|
|
1239
1599
|
toObservable,
|
|
1240
|
-
events
|
|
1600
|
+
events,
|
|
1601
|
+
emit,
|
|
1602
|
+
off,
|
|
1603
|
+
addListener,
|
|
1604
|
+
removeListener,
|
|
1605
|
+
prependListener,
|
|
1606
|
+
prependOnceListener,
|
|
1607
|
+
listeners: getListeners,
|
|
1608
|
+
rawListeners: rawListenersMethod,
|
|
1609
|
+
listenerCount,
|
|
1610
|
+
eventNames: eventNamesMethod
|
|
1241
1611
|
};
|
|
1242
1612
|
target[SymbolObservable] = () => {
|
|
1243
1613
|
return toObservable();
|
|
1244
1614
|
};
|
|
1245
1615
|
return target;
|
|
1246
1616
|
}
|
|
1247
|
-
// src/interop.ts
|
|
1248
|
-
function forwardToEventTarget(source, target, options) {
|
|
1249
|
-
const unsubscribe2 = source.addWildcardListener("*", (event) => {
|
|
1250
|
-
const domEvent = {
|
|
1251
|
-
type: event.originalType,
|
|
1252
|
-
detail: event.detail
|
|
1253
|
-
};
|
|
1254
|
-
target.dispatchEvent(domEvent);
|
|
1255
|
-
}, options);
|
|
1256
|
-
return unsubscribe2;
|
|
1257
|
-
}
|
|
1258
|
-
function fromEventTarget(domTarget, eventTypes, options) {
|
|
1259
|
-
const emitter = createEventTarget({
|
|
1260
|
-
onListenerError: options?.onListenerError
|
|
1261
|
-
});
|
|
1262
|
-
const handlers = new Map;
|
|
1263
|
-
for (const type of eventTypes) {
|
|
1264
|
-
const handler = (event) => {
|
|
1265
|
-
emitter.dispatchEvent({
|
|
1266
|
-
type,
|
|
1267
|
-
detail: event.detail ?? event
|
|
1268
|
-
});
|
|
1269
|
-
};
|
|
1270
|
-
handlers.set(type, handler);
|
|
1271
|
-
domTarget.addEventListener(type, handler);
|
|
1272
|
-
}
|
|
1273
|
-
let onAbort = null;
|
|
1274
|
-
if (options?.signal) {
|
|
1275
|
-
onAbort = () => {
|
|
1276
|
-
for (const [type, handler] of handlers) {
|
|
1277
|
-
domTarget.removeEventListener(type, handler);
|
|
1278
|
-
}
|
|
1279
|
-
handlers.clear();
|
|
1280
|
-
emitter.complete();
|
|
1281
|
-
};
|
|
1282
|
-
options.signal.addEventListener("abort", onAbort, { once: true });
|
|
1283
|
-
if (options.signal.aborted)
|
|
1284
|
-
onAbort();
|
|
1285
|
-
}
|
|
1286
|
-
return {
|
|
1287
|
-
addEventListener: emitter.addEventListener,
|
|
1288
|
-
removeEventListener: emitter.removeEventListener,
|
|
1289
|
-
dispatchEvent: emitter.dispatchEvent,
|
|
1290
|
-
clear: emitter.clear,
|
|
1291
|
-
once: emitter.once,
|
|
1292
|
-
removeAllListeners: emitter.removeAllListeners,
|
|
1293
|
-
pipe: emitter.pipe,
|
|
1294
|
-
addWildcardListener: emitter.addWildcardListener,
|
|
1295
|
-
removeWildcardListener: emitter.removeWildcardListener,
|
|
1296
|
-
on: emitter.on,
|
|
1297
|
-
subscribe: emitter.subscribe,
|
|
1298
|
-
toObservable: emitter.toObservable,
|
|
1299
|
-
complete: emitter.complete,
|
|
1300
|
-
get completed() {
|
|
1301
|
-
return emitter.completed;
|
|
1302
|
-
},
|
|
1303
|
-
events: emitter.events,
|
|
1304
|
-
destroy: () => {
|
|
1305
|
-
if (options?.signal && onAbort) {
|
|
1306
|
-
options.signal.removeEventListener("abort", onAbort);
|
|
1307
|
-
}
|
|
1308
|
-
for (const [type, handler] of handlers) {
|
|
1309
|
-
domTarget.removeEventListener(type, handler);
|
|
1310
|
-
}
|
|
1311
|
-
handlers.clear();
|
|
1312
|
-
emitter.complete();
|
|
1313
|
-
}
|
|
1314
|
-
};
|
|
1315
|
-
}
|
|
1316
|
-
function pipe(source, target, options) {
|
|
1317
|
-
return source.addWildcardListener("*", (event) => {
|
|
1318
|
-
target.dispatchEvent({
|
|
1319
|
-
type: event.originalType,
|
|
1320
|
-
detail: event.detail
|
|
1321
|
-
});
|
|
1322
|
-
}, options);
|
|
1323
|
-
}
|
|
1324
1617
|
// src/event-emission.ts
|
|
1325
1618
|
class EventEmission {
|
|
1326
1619
|
#target;
|
|
@@ -1330,14 +1623,14 @@ class EventEmission {
|
|
|
1330
1623
|
addEventListener(type, listener, options) {
|
|
1331
1624
|
return this.#target.addEventListener(type, listener, options);
|
|
1332
1625
|
}
|
|
1333
|
-
removeEventListener(type, listener) {
|
|
1334
|
-
this.#target.removeEventListener(type, listener);
|
|
1626
|
+
removeEventListener(type, listener, options) {
|
|
1627
|
+
this.#target.removeEventListener(type, listener, options);
|
|
1335
1628
|
}
|
|
1336
1629
|
dispatchEvent(event) {
|
|
1337
1630
|
return this.#target.dispatchEvent(event);
|
|
1338
1631
|
}
|
|
1339
|
-
on(type,
|
|
1340
|
-
return this.#target.on(type,
|
|
1632
|
+
on(type, optionsOrListener) {
|
|
1633
|
+
return this.#target.on(type, optionsOrListener);
|
|
1341
1634
|
}
|
|
1342
1635
|
once(type, listener, options) {
|
|
1343
1636
|
return this.#target.once(type, listener, options);
|
|
@@ -1351,6 +1644,36 @@ class EventEmission {
|
|
|
1351
1644
|
pipe(target, mapFn) {
|
|
1352
1645
|
return this.#target.pipe(target, mapFn);
|
|
1353
1646
|
}
|
|
1647
|
+
emit(type, detail) {
|
|
1648
|
+
return this.#target.emit(type, detail);
|
|
1649
|
+
}
|
|
1650
|
+
off(type, listener) {
|
|
1651
|
+
this.#target.off(type, listener);
|
|
1652
|
+
}
|
|
1653
|
+
addListener(type, listener) {
|
|
1654
|
+
return this.#target.addListener(type, listener);
|
|
1655
|
+
}
|
|
1656
|
+
removeListener(type, listener) {
|
|
1657
|
+
this.#target.removeListener(type, listener);
|
|
1658
|
+
}
|
|
1659
|
+
prependListener(type, listener) {
|
|
1660
|
+
return this.#target.prependListener(type, listener);
|
|
1661
|
+
}
|
|
1662
|
+
prependOnceListener(type, listener) {
|
|
1663
|
+
return this.#target.prependOnceListener(type, listener);
|
|
1664
|
+
}
|
|
1665
|
+
listeners(type) {
|
|
1666
|
+
return this.#target.listeners(type);
|
|
1667
|
+
}
|
|
1668
|
+
rawListeners(type) {
|
|
1669
|
+
return this.#target.rawListeners(type);
|
|
1670
|
+
}
|
|
1671
|
+
listenerCount(type) {
|
|
1672
|
+
return this.#target.listenerCount(type);
|
|
1673
|
+
}
|
|
1674
|
+
eventNames() {
|
|
1675
|
+
return this.#target.eventNames();
|
|
1676
|
+
}
|
|
1354
1677
|
addWildcardListener(pattern, listener, options) {
|
|
1355
1678
|
return this.#target.addWildcardListener(pattern, listener, options);
|
|
1356
1679
|
}
|
|
@@ -1391,4 +1714,4 @@ class EventEmission {
|
|
|
1391
1714
|
}
|
|
1392
1715
|
})
|
|
1393
1716
|
|
|
1394
|
-
//# debugId=
|
|
1717
|
+
//# debugId=FAADC5AA76187FDD64756E2164756E21
|