event-emission 0.1.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/README.md +228 -27
  2. package/dist/{eventful.d.ts → event-emission.d.ts} +22 -19
  3. package/dist/event-emission.d.ts.map +1 -0
  4. package/dist/factory.d.ts +1 -1
  5. package/dist/factory.d.ts.map +1 -1
  6. package/dist/index.cjs +811 -354
  7. package/dist/index.cjs.map +8 -8
  8. package/dist/index.d.ts +2 -6
  9. package/dist/index.d.ts.map +1 -1
  10. package/dist/index.js +787 -348
  11. package/dist/index.js.map +8 -8
  12. package/dist/interoperability.cjs +1605 -0
  13. package/dist/interoperability.cjs.map +15 -0
  14. package/dist/{interop.d.ts → interoperability.d.ts} +12 -11
  15. package/dist/interoperability.d.ts.map +1 -0
  16. package/dist/interoperability.js +1555 -0
  17. package/dist/interoperability.js.map +15 -0
  18. package/dist/observable.cjs +286 -0
  19. package/dist/observable.cjs.map +11 -0
  20. package/dist/observable.d.ts +36 -0
  21. package/dist/observable.d.ts.map +1 -0
  22. package/dist/observable.js +253 -0
  23. package/dist/observable.js.map +11 -0
  24. package/dist/observe.cjs +344 -0
  25. package/dist/observe.cjs.map +10 -0
  26. package/dist/observe.d.ts +9 -4
  27. package/dist/observe.d.ts.map +1 -1
  28. package/dist/observe.js +313 -0
  29. package/dist/observe.js.map +10 -0
  30. package/dist/symbols.d.ts +1 -1
  31. package/dist/types.cjs +35 -0
  32. package/dist/types.cjs.map +9 -0
  33. package/dist/types.d.ts +105 -24
  34. package/dist/types.d.ts.map +1 -1
  35. package/dist/types.js +3 -0
  36. package/dist/types.js.map +9 -0
  37. package/package.json +27 -1
  38. package/src/{eventful.ts → event-emission.ts} +45 -28
  39. package/src/factory.ts +639 -269
  40. package/src/index.ts +7 -29
  41. package/src/{interop.ts → interoperability.ts} +55 -35
  42. package/src/observable.ts +310 -0
  43. package/src/observe.ts +70 -33
  44. package/src/symbols.ts +1 -1
  45. package/src/types.ts +130 -29
  46. package/dist/eventful.d.ts.map +0 -1
  47. package/dist/interop.d.ts.map +0 -1
package/dist/index.js CHANGED
@@ -4,16 +4,252 @@ var SymbolObservable = typeof Symbol === "function" && Symbol.observable || Symb
4
4
  if (typeof Symbol === "function") {
5
5
  Symbol.observable = SymbolObservable;
6
6
  }
7
- // src/errors.ts
8
- class BufferOverflowError extends Error {
9
- constructor(eventType, bufferSize) {
10
- super(`Buffer overflow for event type "${eventType}" (max: ${bufferSize})`);
11
- this.name = "BufferOverflowError";
7
+
8
+ // src/observable.ts
9
+ function getMethod(obj, key) {
10
+ if (obj === null || obj === undefined)
11
+ return;
12
+ const value = obj[key];
13
+ if (value == null)
14
+ return;
15
+ if (typeof value !== "function") {
16
+ throw new TypeError(value + " is not a function");
17
+ }
18
+ return value;
19
+ }
20
+ function hostReportError(e) {
21
+ if (typeof queueMicrotask === "function") {
22
+ queueMicrotask(() => {
23
+ throw e;
24
+ });
25
+ } else {
26
+ setTimeout(() => {
27
+ throw e;
28
+ });
29
+ }
30
+ }
31
+ function SubscriptionObserverImpl(subscription) {
32
+ this._subscription = subscription;
33
+ }
34
+ SubscriptionObserverImpl.prototype = Object.create(Object.prototype);
35
+ Object.defineProperties(SubscriptionObserverImpl.prototype, {
36
+ constructor: { value: Object, configurable: true, writable: true },
37
+ closed: {
38
+ get() {
39
+ return this._subscription._closed;
40
+ },
41
+ configurable: true
42
+ },
43
+ next: {
44
+ value: function next(value) {
45
+ const subscription = this._subscription;
46
+ if (subscription._closed)
47
+ return;
48
+ const observer = subscription._observer;
49
+ try {
50
+ const m = getMethod(observer, "next");
51
+ if (!m)
52
+ return;
53
+ return m.call(observer, value);
54
+ } catch (e) {
55
+ try {
56
+ this.error(e);
57
+ } catch (err) {
58
+ hostReportError(err);
59
+ }
60
+ }
61
+ },
62
+ configurable: true,
63
+ writable: true
64
+ },
65
+ error: {
66
+ value: function error(errorValue) {
67
+ const subscription = this._subscription;
68
+ if (subscription._closed)
69
+ throw errorValue;
70
+ subscription._closed = true;
71
+ const observer = subscription._observer;
72
+ try {
73
+ const m = getMethod(observer, "error");
74
+ if (m) {
75
+ return m.call(observer, errorValue);
76
+ }
77
+ throw errorValue;
78
+ } finally {
79
+ subscription._cleanup();
80
+ }
81
+ },
82
+ configurable: true,
83
+ writable: true
84
+ },
85
+ complete: {
86
+ value: function complete(value) {
87
+ const subscription = this._subscription;
88
+ if (subscription._closed)
89
+ return;
90
+ subscription._closed = true;
91
+ const observer = subscription._observer;
92
+ try {
93
+ const m = getMethod(observer, "complete");
94
+ if (m) {
95
+ return m.call(observer, value);
96
+ }
97
+ return;
98
+ } finally {
99
+ subscription._cleanup();
100
+ }
101
+ },
102
+ configurable: true,
103
+ writable: true
104
+ }
105
+ });
106
+ Object.defineProperty(SubscriptionObserverImpl.prototype.next, "length", { value: 1 });
107
+ Object.defineProperty(SubscriptionObserverImpl.prototype.error, "length", { value: 1 });
108
+ Object.defineProperty(SubscriptionObserverImpl.prototype.complete, "length", {
109
+ value: 1
110
+ });
111
+ function Subscription(observer, subscriber) {
112
+ this._observer = observer;
113
+ this._cleanupFn = undefined;
114
+ this._closed = false;
115
+ const subscriptionObserver = new SubscriptionObserverImpl(this);
116
+ try {
117
+ const start = getMethod(observer, "start");
118
+ if (start) {
119
+ start.call(observer, this);
120
+ }
121
+ } catch (e) {
122
+ hostReportError(e);
123
+ }
124
+ if (this._closed)
125
+ return;
126
+ try {
127
+ const cleanup = subscriber(subscriptionObserver);
128
+ if (cleanup != null) {
129
+ if (typeof cleanup !== "function" && typeof cleanup.unsubscribe !== "function") {
130
+ throw new TypeError(cleanup + " is not a function or a subscription");
131
+ }
132
+ this._cleanupFn = cleanup;
133
+ if (this._closed) {
134
+ this._cleanup();
135
+ }
136
+ }
137
+ } catch (e) {
138
+ subscriptionObserver.error(e);
12
139
  }
13
140
  }
141
+ Subscription.prototype = Object.create(Object.prototype);
142
+ Object.defineProperties(Subscription.prototype, {
143
+ constructor: { value: Object, configurable: true, writable: true },
144
+ closed: {
145
+ get() {
146
+ return this._closed;
147
+ },
148
+ configurable: true
149
+ },
150
+ unsubscribe: {
151
+ value: function unsubscribe() {
152
+ if (this._closed)
153
+ return;
154
+ this._closed = true;
155
+ this._cleanup();
156
+ },
157
+ configurable: true,
158
+ writable: true
159
+ },
160
+ _cleanup: {
161
+ value: function _cleanup() {
162
+ const cleanup = this._cleanupFn;
163
+ if (!cleanup)
164
+ return;
165
+ this._cleanupFn = undefined;
166
+ try {
167
+ if (typeof cleanup === "function") {
168
+ cleanup();
169
+ } else if (cleanup && typeof cleanup.unsubscribe === "function") {
170
+ cleanup.unsubscribe();
171
+ }
172
+ } catch (e) {
173
+ hostReportError(e);
174
+ }
175
+ },
176
+ configurable: true,
177
+ writable: true
178
+ }
179
+ });
180
+
181
+ class Observable {
182
+ _subscriber;
183
+ constructor(subscriber) {
184
+ if (typeof subscriber !== "function") {
185
+ throw new TypeError("Observable initializer must be a function");
186
+ }
187
+ this._subscriber = subscriber;
188
+ }
189
+ subscribe(observerOrNext, error2, complete2) {
190
+ let observer;
191
+ if (typeof observerOrNext === "function") {
192
+ observer = {
193
+ next: observerOrNext,
194
+ error: error2,
195
+ complete: complete2
196
+ };
197
+ } else if (typeof observerOrNext !== "object" || observerOrNext === null) {
198
+ throw new TypeError(observerOrNext + " is not an object");
199
+ } else {
200
+ observer = observerOrNext;
201
+ }
202
+ return new Subscription(observer, this._subscriber);
203
+ }
204
+ [SymbolObservable]() {
205
+ return this;
206
+ }
207
+ static of(...items) {
208
+ const C = typeof this === "function" ? this : Observable;
209
+ return new C((observer) => {
210
+ for (let i = 0;i < items.length; ++i) {
211
+ observer.next(items[i]);
212
+ if (observer.closed)
213
+ return;
214
+ }
215
+ observer.complete();
216
+ });
217
+ }
218
+ static from(x) {
219
+ const C = typeof this === "function" ? this : Observable;
220
+ if (x == null)
221
+ throw new TypeError(x + " is not an object");
222
+ const method = x[SymbolObservable];
223
+ if (method != null) {
224
+ if (typeof method !== "function") {
225
+ throw new TypeError(method + " is not a function");
226
+ }
227
+ const observable = method.call(x);
228
+ if (Object(observable) !== observable) {
229
+ throw new TypeError(observable + " is not an object");
230
+ }
231
+ if (observable.constructor === C) {
232
+ return observable;
233
+ }
234
+ return new C((observer) => observable.subscribe(observer));
235
+ }
236
+ if (Symbol.iterator in x) {
237
+ return new C((observer) => {
238
+ for (const item of x) {
239
+ observer.next(item);
240
+ if (observer.closed)
241
+ return;
242
+ }
243
+ observer.complete();
244
+ });
245
+ }
246
+ throw new TypeError(x + " is not observable");
247
+ }
248
+ }
249
+
14
250
  // src/observe.ts
15
- var PROXY_MARKER = Symbol.for("@lasercat/eventful/proxy");
16
- var ORIGINAL_TARGET = Symbol.for("@lasercat/eventful/original");
251
+ var PROXY_MARKER = Symbol.for("@lasercat/event-emission/proxy");
252
+ var ORIGINAL_TARGET = Symbol.for("@lasercat/event-emission/original");
17
253
  var ARRAY_MUTATORS = new Set([
18
254
  "push",
19
255
  "pop",
@@ -35,17 +271,13 @@ function isArrayMutator(prop) {
35
271
  return typeof prop === "string" && ARRAY_MUTATORS.has(prop);
36
272
  }
37
273
  function cloneAlongPath(obj, path) {
38
- if (obj === null || typeof obj !== "object") {
39
- return obj;
40
- }
41
- if (!path) {
42
- 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;
43
278
  }
44
279
  const parts = path.split(".");
45
- if (Array.isArray(obj)) {
46
- return [...obj];
47
- }
48
- const result = { ...obj };
280
+ const result = rootClone;
49
281
  let current = result;
50
282
  for (let i = 0;i < parts.length; i++) {
51
283
  const key = parts[i];
@@ -61,13 +293,19 @@ function cloneAlongPath(obj, path) {
61
293
  }
62
294
  return result;
63
295
  }
64
- function cloneForComparison(obj, strategy, changedPath) {
296
+ function cloneForComparison(obj, strategy, changedPath, deepClone) {
65
297
  if (obj === null || typeof obj !== "object")
66
298
  return obj;
67
299
  switch (strategy) {
68
300
  case "shallow":
69
301
  return Array.isArray(obj) ? [...obj] : { ...obj };
70
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
+ }
71
309
  return structuredClone(obj);
72
310
  case "path":
73
311
  return cloneAlongPath(obj, changedPath);
@@ -115,7 +353,7 @@ function getContextRegistry(target) {
115
353
  function createArrayMethodInterceptor(array, method, path, context) {
116
354
  const original = array[method];
117
355
  return function(...args) {
118
- const previousState = cloneForComparison(context.originalRoot, context.options.cloneStrategy, path);
356
+ const previousState = cloneForComparison(context.originalRoot, context.options.cloneStrategy, path, context.options.deepClone);
119
357
  const previousItems = [...array];
120
358
  const result = original.apply(this, args);
121
359
  const { added, removed } = computeArrayDiff(method, previousItems, array, args);
@@ -187,7 +425,7 @@ function createObservableProxyInternal(target, path, context) {
187
425
  return true;
188
426
  }
189
427
  const propPath = path ? `${path}.${prop}` : prop;
190
- const previousState = cloneForComparison(context.originalRoot, context.options.cloneStrategy, propPath);
428
+ const previousState = cloneForComparison(context.originalRoot, context.options.cloneStrategy, propPath, context.options.deepClone);
191
429
  const success = Reflect.set(obj, prop, value, receiver);
192
430
  if (success) {
193
431
  context.eventTarget.dispatchEvent({
@@ -213,7 +451,7 @@ function createObservableProxyInternal(target, path, context) {
213
451
  return Reflect.deleteProperty(obj, prop);
214
452
  }
215
453
  const propPath = path ? `${path}.${String(prop)}` : String(prop);
216
- const previousState = cloneForComparison(context.originalRoot, context.options.cloneStrategy, propPath);
454
+ const previousState = cloneForComparison(context.originalRoot, context.options.cloneStrategy, propPath, context.options.deepClone);
217
455
  const success = Reflect.deleteProperty(obj, prop);
218
456
  if (success) {
219
457
  context.eventTarget.dispatchEvent({
@@ -246,6 +484,8 @@ function isEventTarget(obj) {
246
484
  }
247
485
  function setupEventForwarding(source, target) {
248
486
  const handlers = new Map;
487
+ const sourceAddEventListener = source.addEventListener.bind(source);
488
+ const sourceRemoveEventListener = source.removeEventListener.bind(source);
249
489
  const forwardHandler = (type) => (event) => {
250
490
  const detail = event.detail ?? event;
251
491
  target.dispatchEvent({
@@ -258,7 +498,7 @@ function setupEventForwarding(source, target) {
258
498
  if (!handlers.has(type) && type !== "update" && !type.startsWith("update:")) {
259
499
  const handler = forwardHandler(type);
260
500
  handlers.set(type, handler);
261
- source.addEventListener(type, handler);
501
+ sourceAddEventListener(type, handler);
262
502
  }
263
503
  return originalAddEventListener(type, listener, options);
264
504
  };
@@ -266,7 +506,7 @@ function setupEventForwarding(source, target) {
266
506
  return () => {
267
507
  target.addEventListener = originalAddEventListener;
268
508
  for (const [type, handler] of handlers) {
269
- source.removeEventListener(type, handler);
509
+ sourceRemoveEventListener(type, handler);
270
510
  }
271
511
  handlers.clear();
272
512
  };
@@ -283,7 +523,8 @@ function getOriginal(proxy) {
283
523
  function createObservableProxy(target, eventTarget, options) {
284
524
  const resolvedOptions = {
285
525
  deep: options?.deep ?? true,
286
- cloneStrategy: options?.cloneStrategy ?? "path"
526
+ cloneStrategy: options?.cloneStrategy ?? "path",
527
+ deepClone: options?.deepClone
287
528
  };
288
529
  const context = {
289
530
  eventTarget,
@@ -292,21 +533,36 @@ function createObservableProxy(target, eventTarget, options) {
292
533
  };
293
534
  const proxy = createObservableProxyInternal(target, "", context);
294
535
  if (isEventTarget(target)) {
295
- 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
+ }
296
549
  }
297
550
  return proxy;
298
551
  }
299
-
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
+ }
300
559
  // src/factory.ts
301
560
  function matchesWildcard(eventType, pattern) {
302
561
  if (pattern === "*")
303
562
  return true;
304
- if (pattern.endsWith(":*")) {
305
- const namespace = pattern.slice(0, -2);
306
- return eventType.startsWith(namespace + ":");
307
- }
308
- return false;
563
+ return pattern.endsWith(":*") && eventType.startsWith(pattern.slice(0, -2) + ":");
309
564
  }
565
+ var EVENT_STATE = Symbol("event-emission:event-state");
310
566
  function createEventTarget(targetOrOpts, opts) {
311
567
  if (opts?.observe === true && targetOrOpts && typeof targetOrOpts === "object") {
312
568
  const target = targetOrOpts;
@@ -315,13 +571,15 @@ function createEventTarget(targetOrOpts, opts) {
315
571
  });
316
572
  const proxy = createObservableProxy(target, eventTarget, {
317
573
  deep: opts.deep,
318
- cloneStrategy: opts.cloneStrategy
574
+ cloneStrategy: opts.cloneStrategy,
575
+ deepClone: opts.deepClone
319
576
  });
320
577
  const methodNames = [
321
578
  "addEventListener",
322
579
  "removeEventListener",
323
580
  "dispatchEvent",
324
581
  "clear",
582
+ "on",
325
583
  "once",
326
584
  "removeAllListeners",
327
585
  "pipe",
@@ -354,43 +612,241 @@ function createEventTargetInternal(opts) {
354
612
  const wildcardListeners = new Set;
355
613
  let isCompleted = false;
356
614
  const completionCallbacks = new Set;
357
- const handleListenerError = (eventType, error) => {
615
+ const now = () => typeof globalThis.performance?.now === "function" ? globalThis.performance.now() : Date.now();
616
+ const initializeEventState = (state, type, bubbles, cancelable) => {
617
+ state.initializedFlag = true;
618
+ state.stopPropagationFlag = false;
619
+ state.stopImmediatePropagationFlag = false;
620
+ state.canceledFlag = false;
621
+ state.isTrusted = false;
622
+ state.target = null;
623
+ state.currentTarget = null;
624
+ state.eventPhase = 0;
625
+ state.type = type;
626
+ state.bubbles = bubbles;
627
+ state.cancelable = cancelable;
628
+ };
629
+ const setCanceledFlag = (state) => {
630
+ if (state.cancelable && !state.inPassiveListenerFlag) {
631
+ state.canceledFlag = true;
632
+ }
633
+ };
634
+ const createEvent = (type, detail, init) => {
635
+ const state = {
636
+ dispatchFlag: false,
637
+ initializedFlag: true,
638
+ stopPropagationFlag: false,
639
+ stopImmediatePropagationFlag: false,
640
+ canceledFlag: false,
641
+ inPassiveListenerFlag: false,
642
+ composedFlag: Boolean(init?.composed),
643
+ eventPhase: init?.eventPhase ?? 0,
644
+ currentTarget: init?.currentTarget ?? init?.target ?? null,
645
+ target: init?.target ?? null,
646
+ timeStamp: init?.timeStamp ?? now(),
647
+ path: [],
648
+ type,
649
+ bubbles: Boolean(init?.bubbles),
650
+ cancelable: Boolean(init?.cancelable),
651
+ isTrusted: false
652
+ };
653
+ const event = { detail };
654
+ Object.defineProperties(event, {
655
+ type: {
656
+ get: () => state.type,
657
+ enumerable: true,
658
+ configurable: true
659
+ },
660
+ bubbles: {
661
+ get: () => state.bubbles,
662
+ enumerable: true,
663
+ configurable: true
664
+ },
665
+ cancelable: {
666
+ get: () => state.cancelable,
667
+ enumerable: true,
668
+ configurable: true
669
+ },
670
+ cancelBubble: {
671
+ get: () => state.stopPropagationFlag,
672
+ set: (value) => {
673
+ if (value)
674
+ state.stopPropagationFlag = true;
675
+ },
676
+ enumerable: true,
677
+ configurable: true
678
+ },
679
+ composed: {
680
+ get: () => state.composedFlag,
681
+ enumerable: true,
682
+ configurable: true
683
+ },
684
+ currentTarget: {
685
+ get: () => state.currentTarget,
686
+ enumerable: true,
687
+ configurable: true
688
+ },
689
+ defaultPrevented: {
690
+ get: () => state.canceledFlag,
691
+ enumerable: true,
692
+ configurable: true
693
+ },
694
+ eventPhase: {
695
+ get: () => state.eventPhase,
696
+ enumerable: true,
697
+ configurable: true
698
+ },
699
+ isTrusted: {
700
+ get: () => state.isTrusted,
701
+ enumerable: true,
702
+ configurable: true
703
+ },
704
+ returnValue: {
705
+ get: () => !state.canceledFlag,
706
+ set: (value) => {
707
+ if (value === false)
708
+ setCanceledFlag(state);
709
+ },
710
+ enumerable: true,
711
+ configurable: true
712
+ },
713
+ srcElement: {
714
+ get: () => state.target,
715
+ enumerable: true,
716
+ configurable: true
717
+ },
718
+ target: {
719
+ get: () => state.target,
720
+ enumerable: true,
721
+ configurable: true
722
+ },
723
+ timeStamp: {
724
+ get: () => state.timeStamp,
725
+ enumerable: true,
726
+ configurable: true
727
+ },
728
+ composedPath: {
729
+ value: () => state.path.map((entry) => entry.invocationTarget),
730
+ enumerable: true,
731
+ configurable: true
732
+ },
733
+ initEvent: {
734
+ value: (newType, bubbles = false, cancelable = false) => {
735
+ if (state.dispatchFlag)
736
+ return;
737
+ initializeEventState(state, newType, Boolean(bubbles), Boolean(cancelable));
738
+ },
739
+ enumerable: true,
740
+ configurable: true
741
+ },
742
+ preventDefault: {
743
+ value: () => setCanceledFlag(state),
744
+ enumerable: true,
745
+ configurable: true
746
+ },
747
+ stopImmediatePropagation: {
748
+ value: () => {
749
+ state.stopPropagationFlag = true;
750
+ state.stopImmediatePropagationFlag = true;
751
+ },
752
+ enumerable: true,
753
+ configurable: true
754
+ },
755
+ stopPropagation: {
756
+ value: () => {
757
+ state.stopPropagationFlag = true;
758
+ },
759
+ enumerable: true,
760
+ configurable: true
761
+ },
762
+ NONE: { value: 0, enumerable: true, configurable: true },
763
+ CAPTURING_PHASE: { value: 1, enumerable: true, configurable: true },
764
+ AT_TARGET: { value: 2, enumerable: true, configurable: true },
765
+ BUBBLING_PHASE: { value: 3, enumerable: true, configurable: true },
766
+ [EVENT_STATE]: {
767
+ value: state,
768
+ enumerable: false,
769
+ configurable: false
770
+ }
771
+ });
772
+ return event;
773
+ };
774
+ const getEventState = (event) => event[EVENT_STATE];
775
+ const normalizeAddListenerOptions = (options) => {
776
+ if (typeof options === "boolean") {
777
+ return {
778
+ capture: options,
779
+ passive: false,
780
+ once: false,
781
+ signal: null
782
+ };
783
+ }
784
+ return {
785
+ capture: Boolean(options?.capture),
786
+ passive: Boolean(options?.passive),
787
+ once: Boolean(options?.once),
788
+ signal: options?.signal ?? null
789
+ };
790
+ };
791
+ const normalizeCaptureOption = (options) => {
792
+ if (typeof options === "boolean")
793
+ return options;
794
+ return Boolean(options?.capture);
795
+ };
796
+ const removeListenerRecord = (type, record) => {
797
+ if (record.removed)
798
+ return;
799
+ record.removed = true;
800
+ const list = listeners.get(type);
801
+ if (list) {
802
+ const idx = list.indexOf(record);
803
+ if (idx >= 0)
804
+ list.splice(idx, 1);
805
+ if (list.length === 0)
806
+ listeners.delete(type);
807
+ }
808
+ if (record.signal && record.abortHandler) {
809
+ record.signal.removeEventListener("abort", record.abortHandler);
810
+ }
811
+ };
812
+ const handleListenerError = (eventType, error2) => {
358
813
  if (eventType === "error")
359
814
  return;
360
815
  if (opts?.onListenerError) {
361
- opts.onListenerError(eventType, error);
816
+ opts.onListenerError(eventType, error2);
362
817
  return;
363
818
  }
364
819
  const errorListeners = listeners.get("error");
365
- if (errorListeners && errorListeners.size > 0) {
366
- for (const rec of Array.from(errorListeners)) {
367
- try {
368
- rec.fn({ type: "error", detail: error });
369
- } catch {}
370
- if (rec.once)
371
- errorListeners.delete(rec);
372
- }
820
+ if (errorListeners && errorListeners.length > 0) {
821
+ dispatchEvent({ type: "error", detail: error2 });
373
822
  } else {
374
- throw error;
823
+ throw error2;
375
824
  }
376
825
  };
377
- const notifyWildcardListeners = (eventType, detail) => {
826
+ const notifyWildcardListeners = (eventType, event) => {
378
827
  if (wildcardListeners.size === 0)
379
828
  return;
380
829
  for (const rec of Array.from(wildcardListeners)) {
381
830
  if (!matchesWildcard(eventType, rec.pattern))
382
831
  continue;
383
- const wildcardEvent = {
384
- type: rec.pattern,
385
- originalType: eventType,
386
- detail
387
- };
832
+ const baseEvent = createEvent(rec.pattern, event.detail, {
833
+ target,
834
+ currentTarget: target,
835
+ eventPhase: 2,
836
+ bubbles: event.bubbles,
837
+ cancelable: event.cancelable,
838
+ composed: event.composed
839
+ });
840
+ const wildcardEvent = Object.defineProperties(baseEvent, {
841
+ originalType: { value: eventType, enumerable: true, configurable: true }
842
+ });
388
843
  try {
389
- const res = rec.fn(wildcardEvent);
844
+ const fn = rec.fn;
845
+ const res = fn(wildcardEvent);
390
846
  if (res && typeof res.then === "function") {
391
- res.catch((error) => {
847
+ res.catch((error2) => {
392
848
  try {
393
- handleListenerError(eventType, error);
849
+ handleListenerError(eventType, error2);
394
850
  } catch (rethrown) {
395
851
  queueMicrotask(() => {
396
852
  throw rethrown;
@@ -398,50 +854,65 @@ function createEventTargetInternal(opts) {
398
854
  }
399
855
  });
400
856
  }
401
- } catch (error) {
402
- handleListenerError(eventType, error);
857
+ } catch (error2) {
858
+ handleListenerError(eventType, error2);
403
859
  } finally {
404
860
  if (rec.once)
405
861
  wildcardListeners.delete(rec);
406
862
  }
863
+ const state = getEventState(wildcardEvent);
864
+ if (state?.stopImmediatePropagationFlag || state?.stopPropagationFlag) {
865
+ break;
866
+ }
407
867
  }
408
868
  };
409
869
  const addEventListener = (type, listener, options) => {
410
- if (isCompleted) {
870
+ if (isCompleted || !listener) {
411
871
  return () => {};
412
872
  }
413
- const opts2 = options ?? {};
414
- const record = {
415
- fn: listener,
416
- once: opts2.once,
417
- signal: opts2.signal
418
- };
419
- let set = listeners.get(type);
420
- if (!set) {
421
- set = new Set;
422
- listeners.set(type, set);
873
+ const { capture, passive, once, signal } = normalizeAddListenerOptions(options);
874
+ let list = listeners.get(type);
875
+ if (!list) {
876
+ list = [];
877
+ listeners.set(type, list);
423
878
  }
424
- set.add(record);
425
- const unsubscribe = () => {
426
- const setNow = listeners.get(type);
427
- setNow?.delete(record);
428
- if (record.signal && record.abortHandler) {
429
- record.signal.removeEventListener("abort", record.abortHandler);
879
+ for (const existing of list) {
880
+ if (existing.original === listener && existing.capture === capture) {
881
+ return () => removeEventListener(type, listener, options);
430
882
  }
883
+ }
884
+ const original = listener;
885
+ const callback = typeof listener === "function" ? listener : (event) => listener.handleEvent(event);
886
+ const record = {
887
+ type,
888
+ original,
889
+ callback,
890
+ capture,
891
+ passive,
892
+ once,
893
+ signal,
894
+ removed: false
431
895
  };
432
- if (opts2.signal) {
433
- const onAbort = () => unsubscribe();
896
+ list.push(record);
897
+ const unsubscribe2 = () => removeListenerRecord(type, record);
898
+ if (signal) {
899
+ const onAbort = () => removeListenerRecord(type, record);
434
900
  record.abortHandler = onAbort;
435
- opts2.signal.addEventListener("abort", onAbort, { once: true });
436
- if (opts2.signal.aborted)
901
+ signal.addEventListener("abort", onAbort, { once: true });
902
+ if (signal.aborted)
437
903
  onAbort();
438
904
  }
439
- return unsubscribe;
905
+ return unsubscribe2;
440
906
  };
441
907
  const addWildcardListener = (pattern, listener, options) => {
442
908
  if (isCompleted)
443
909
  return () => {};
444
910
  const opts2 = options ?? {};
911
+ for (const existing of wildcardListeners) {
912
+ if (existing.pattern === pattern && existing.fn === listener) {
913
+ return () => removeWildcardListener(pattern, listener);
914
+ }
915
+ }
445
916
  const record = {
446
917
  fn: listener,
447
918
  pattern,
@@ -449,46 +920,55 @@ function createEventTargetInternal(opts) {
449
920
  signal: opts2.signal
450
921
  };
451
922
  wildcardListeners.add(record);
452
- const unsubscribe = () => {
923
+ const unsubscribe2 = () => {
453
924
  wildcardListeners.delete(record);
454
925
  if (record.signal && record.abortHandler) {
455
926
  record.signal.removeEventListener("abort", record.abortHandler);
456
927
  }
457
928
  };
458
929
  if (opts2.signal) {
459
- const onAbort = () => unsubscribe();
930
+ const onAbort = () => unsubscribe2();
460
931
  record.abortHandler = onAbort;
461
932
  opts2.signal.addEventListener("abort", onAbort, { once: true });
462
933
  if (opts2.signal.aborted)
463
934
  onAbort();
464
935
  }
465
- return unsubscribe;
936
+ return unsubscribe2;
466
937
  };
467
938
  const removeWildcardListener = (pattern, listener) => {
468
- for (const record of wildcardListeners) {
939
+ for (const record of Array.from(wildcardListeners)) {
469
940
  if (record.pattern === pattern && record.fn === listener) {
470
941
  wildcardListeners.delete(record);
471
942
  if (record.signal && record.abortHandler) {
472
943
  record.signal.removeEventListener("abort", record.abortHandler);
473
944
  }
474
- break;
475
945
  }
476
946
  }
477
947
  };
478
- const dispatchEvent = (event) => {
479
- if (isCompleted)
480
- return false;
481
- notifyWildcardListeners(event.type, event.detail);
482
- const set = listeners.get(event.type);
483
- if (!set || set.size === 0)
484
- return true;
485
- for (const rec of Array.from(set)) {
948
+ const invokeListeners = (eventType, event, phase, listenersSnapshot) => {
949
+ const state = getEventState(event);
950
+ if (!state || state.stopPropagationFlag)
951
+ return;
952
+ state.currentTarget = target;
953
+ state.target = target;
954
+ state.eventPhase = event.AT_TARGET;
955
+ for (const rec of listenersSnapshot) {
956
+ if (rec.removed)
957
+ continue;
958
+ if (phase === "capturing" && !rec.capture)
959
+ continue;
960
+ if (phase === "bubbling" && rec.capture)
961
+ continue;
962
+ if (rec.once)
963
+ removeListenerRecord(rec.type, rec);
964
+ if (rec.passive)
965
+ state.inPassiveListenerFlag = true;
486
966
  try {
487
- const res = rec.fn(event);
967
+ const res = rec.callback.call(state.currentTarget, event);
488
968
  if (res && typeof res.then === "function") {
489
- res.catch((error) => {
969
+ res.catch((error2) => {
490
970
  try {
491
- handleListenerError(event.type, error);
971
+ handleListenerError(eventType, error2);
492
972
  } catch (rethrown) {
493
973
  queueMicrotask(() => {
494
974
  throw rethrown;
@@ -496,37 +976,95 @@ function createEventTargetInternal(opts) {
496
976
  }
497
977
  });
498
978
  }
499
- } catch (error) {
500
- handleListenerError(event.type, error);
979
+ } catch (error2) {
980
+ handleListenerError(eventType, error2);
501
981
  } finally {
502
- if (rec.once)
503
- set.delete(rec);
982
+ if (rec.passive)
983
+ state.inPassiveListenerFlag = false;
504
984
  }
985
+ if (state.stopImmediatePropagationFlag)
986
+ break;
505
987
  }
506
- return true;
507
988
  };
508
- const removeEventListener = (type, listener) => {
509
- const set = listeners.get(type);
510
- if (!set)
511
- return;
512
- for (const record of set) {
513
- if (record.fn === listener) {
514
- set.delete(record);
515
- if (record.signal && record.abortHandler) {
516
- record.signal.removeEventListener("abort", record.abortHandler);
989
+ const dispatchEvent = (eventInput) => {
990
+ if (isCompleted)
991
+ return false;
992
+ let event;
993
+ let state;
994
+ if (eventInput && typeof eventInput === "object") {
995
+ state = getEventState(eventInput);
996
+ if (state) {
997
+ event = eventInput;
998
+ } else {
999
+ const input = eventInput;
1000
+ if (typeof input.type !== "string") {
1001
+ throw new TypeError("Event type must be a string");
517
1002
  }
518
- break;
1003
+ event = createEvent(input.type, input.detail, {
1004
+ bubbles: input.bubbles,
1005
+ cancelable: input.cancelable,
1006
+ composed: input.composed,
1007
+ timeStamp: input.timeStamp
1008
+ });
1009
+ state = getEventState(event);
1010
+ }
1011
+ } else {
1012
+ throw new TypeError("dispatchEvent expects an event object");
1013
+ }
1014
+ const dispatchState = state ?? getEventState(event);
1015
+ if (dispatchState.dispatchFlag || !dispatchState.initializedFlag) {
1016
+ const message = "Failed to execute dispatchEvent: event is already being dispatched";
1017
+ if (typeof globalThis.DOMException === "function") {
1018
+ throw new globalThis.DOMException(message, "InvalidStateError");
1019
+ }
1020
+ const err = new Error(message);
1021
+ err.name = "InvalidStateError";
1022
+ throw err;
1023
+ }
1024
+ dispatchState.isTrusted = false;
1025
+ dispatchState.dispatchFlag = true;
1026
+ dispatchState.path = [
1027
+ {
1028
+ invocationTarget: target,
1029
+ invocationTargetInShadowTree: false,
1030
+ shadowAdjustedTarget: target,
1031
+ relatedTarget: null,
1032
+ touchTargets: [],
1033
+ rootOfClosedTree: false,
1034
+ slotInClosedTree: false
1035
+ }
1036
+ ];
1037
+ notifyWildcardListeners(dispatchState.type, event);
1038
+ const list = listeners.get(dispatchState.type);
1039
+ const snapshot = list ? list.slice() : [];
1040
+ invokeListeners(dispatchState.type, event, "capturing", snapshot);
1041
+ invokeListeners(dispatchState.type, event, "bubbling", snapshot);
1042
+ dispatchState.eventPhase = event.NONE;
1043
+ dispatchState.currentTarget = null;
1044
+ dispatchState.path = [];
1045
+ dispatchState.dispatchFlag = false;
1046
+ dispatchState.stopPropagationFlag = false;
1047
+ dispatchState.stopImmediatePropagationFlag = false;
1048
+ return !dispatchState.canceledFlag;
1049
+ };
1050
+ const removeEventListener = (type, listener, options) => {
1051
+ if (!listener)
1052
+ return;
1053
+ const capture = normalizeCaptureOption(options);
1054
+ const list = listeners.get(type);
1055
+ if (!list)
1056
+ return;
1057
+ for (const record of [...list]) {
1058
+ if (record.original === listener && record.capture === capture) {
1059
+ removeListenerRecord(type, record);
519
1060
  }
520
1061
  }
521
1062
  };
522
1063
  const clear = () => {
523
- for (const set of listeners.values()) {
524
- for (const record of set) {
525
- if (record.signal && record.abortHandler) {
526
- record.signal.removeEventListener("abort", record.abortHandler);
527
- }
1064
+ for (const [type, list] of Array.from(listeners.entries())) {
1065
+ for (const record of [...list]) {
1066
+ removeListenerRecord(type, record);
528
1067
  }
529
- set.clear();
530
1068
  }
531
1069
  listeners.clear();
532
1070
  for (const record of wildcardListeners) {
@@ -536,29 +1074,66 @@ function createEventTargetInternal(opts) {
536
1074
  }
537
1075
  wildcardListeners.clear();
538
1076
  };
539
- const once = (type, listener, options) => {
540
- return addEventListener(type, listener, { ...options, once: true });
1077
+ const on = (type, options) => {
1078
+ return new Observable((observer) => {
1079
+ let opts2;
1080
+ if (typeof options === "boolean") {
1081
+ opts2 = { capture: options };
1082
+ } else {
1083
+ opts2 = options ?? {};
1084
+ }
1085
+ const handler = opts2.handler;
1086
+ const once = opts2.once;
1087
+ const eventHandler = (e) => {
1088
+ let success = false;
1089
+ try {
1090
+ if (handler) {
1091
+ handler(e);
1092
+ }
1093
+ observer.next(e);
1094
+ success = true;
1095
+ } finally {
1096
+ if (once && success) {
1097
+ observer.complete();
1098
+ }
1099
+ }
1100
+ };
1101
+ const errorHandler = (e) => {
1102
+ observer.error(e.detail);
1103
+ };
1104
+ const unsubscribeEvent = addEventListener(type, eventHandler, opts2);
1105
+ let unsubscribeError;
1106
+ if (opts2.receiveError) {
1107
+ unsubscribeError = addEventListener("error", errorHandler, opts2);
1108
+ }
1109
+ return () => {
1110
+ unsubscribeEvent();
1111
+ if (unsubscribeError) {
1112
+ unsubscribeError();
1113
+ }
1114
+ };
1115
+ });
1116
+ };
1117
+ const onceMethod = (type, listener, options) => {
1118
+ if (typeof options === "boolean") {
1119
+ return addEventListener(type, listener, { capture: options, once: true });
1120
+ }
1121
+ return addEventListener(type, listener, { ...options ?? {}, once: true });
541
1122
  };
542
1123
  const removeAllListeners = (type) => {
543
1124
  if (type !== undefined) {
544
- const set = listeners.get(type);
545
- if (set) {
546
- for (const record of set) {
547
- if (record.signal && record.abortHandler) {
548
- record.signal.removeEventListener("abort", record.abortHandler);
549
- }
1125
+ const list = listeners.get(type);
1126
+ if (list) {
1127
+ for (const record of [...list]) {
1128
+ removeListenerRecord(type, record);
550
1129
  }
551
- set.clear();
552
1130
  listeners.delete(type);
553
1131
  }
554
1132
  } else {
555
- for (const set of listeners.values()) {
556
- for (const record of set) {
557
- if (record.signal && record.abortHandler) {
558
- record.signal.removeEventListener("abort", record.abortHandler);
559
- }
1133
+ for (const [eventType, list] of Array.from(listeners.entries())) {
1134
+ for (const record of [...list]) {
1135
+ removeListenerRecord(eventType, record);
560
1136
  }
561
- set.clear();
562
1137
  }
563
1138
  listeners.clear();
564
1139
  for (const record of wildcardListeners) {
@@ -573,41 +1148,36 @@ function createEventTargetInternal(opts) {
573
1148
  if (isCompleted) {
574
1149
  return () => {};
575
1150
  }
576
- const unsubscribes = [];
577
- const subscribedTypes = new Set;
578
- const subscribeToType = (type) => {
579
- if (subscribedTypes.has(type))
580
- return;
581
- subscribedTypes.add(type);
582
- const unsub = addEventListener(type, (event) => {
583
- if (mapFn) {
584
- const mapped = mapFn(event);
585
- if (mapped !== null) {
586
- target2.dispatchEvent(mapped);
587
- }
588
- } else {
589
- target2.dispatchEvent(event);
1151
+ const unsubscribe2 = addWildcardListener("*", (event) => {
1152
+ if (mapFn) {
1153
+ const mapped = mapFn(createEvent(event.originalType, event.detail, {
1154
+ target: target2,
1155
+ currentTarget: target2,
1156
+ eventPhase: 2,
1157
+ bubbles: event.bubbles,
1158
+ cancelable: event.cancelable,
1159
+ composed: event.composed
1160
+ }));
1161
+ if (mapped !== null) {
1162
+ target2.dispatchEvent(mapped);
590
1163
  }
591
- });
592
- unsubscribes.push(unsub);
593
- };
594
- for (const type of listeners.keys()) {
595
- subscribeToType(type);
596
- }
597
- const completionUnsub = () => {
598
- for (const unsub of unsubscribes) {
599
- unsub();
1164
+ } else {
1165
+ target2.dispatchEvent({
1166
+ type: event.originalType,
1167
+ detail: event.detail
1168
+ });
600
1169
  }
1170
+ });
1171
+ const completionUnsub = () => {
1172
+ unsubscribe2();
601
1173
  };
602
1174
  completionCallbacks.add(completionUnsub);
603
1175
  return () => {
604
1176
  completionCallbacks.delete(completionUnsub);
605
- for (const unsub of unsubscribes) {
606
- unsub();
607
- }
1177
+ unsubscribe2();
608
1178
  };
609
1179
  };
610
- const complete = () => {
1180
+ const complete2 = () => {
611
1181
  if (isCompleted)
612
1182
  return;
613
1183
  isCompleted = true;
@@ -621,13 +1191,10 @@ function createEventTargetInternal(opts) {
621
1191
  }
622
1192
  }
623
1193
  completionCallbacks.clear();
624
- for (const set of listeners.values()) {
625
- for (const record of set) {
626
- if (record.signal && record.abortHandler) {
627
- record.signal.removeEventListener("abort", record.abortHandler);
628
- }
1194
+ for (const [eventType, list] of Array.from(listeners.entries())) {
1195
+ for (const record of [...list]) {
1196
+ removeListenerRecord(eventType, record);
629
1197
  }
630
- set.clear();
631
1198
  }
632
1199
  listeners.clear();
633
1200
  for (const record of wildcardListeners) {
@@ -637,12 +1204,12 @@ function createEventTargetInternal(opts) {
637
1204
  }
638
1205
  wildcardListeners.clear();
639
1206
  };
640
- const subscribe = (type, observerOrNext, error, completeHandler) => {
1207
+ const subscribe = (type, observerOrNext, error2, completeHandler) => {
641
1208
  let observer;
642
1209
  if (typeof observerOrNext === "function") {
643
1210
  observer = {
644
1211
  next: observerOrNext,
645
- error,
1212
+ error: error2,
646
1213
  complete: completeHandler
647
1214
  };
648
1215
  } else {
@@ -704,81 +1271,31 @@ function createEventTargetInternal(opts) {
704
1271
  };
705
1272
  };
706
1273
  const toObservable = () => {
707
- const observable = {
708
- subscribe: (observerOrNext, errorFn, completeFn) => {
709
- let next;
710
- let error;
711
- let completeCallback;
712
- if (typeof observerOrNext === "function") {
713
- next = observerOrNext;
714
- error = errorFn;
715
- completeCallback = completeFn;
716
- } else if (observerOrNext) {
717
- next = observerOrNext.next?.bind(observerOrNext);
718
- error = observerOrNext.error?.bind(observerOrNext);
719
- completeCallback = observerOrNext.complete?.bind(observerOrNext);
720
- }
721
- let closed = false;
722
- if (isCompleted) {
723
- if (completeCallback) {
724
- try {
725
- completeCallback();
726
- } catch {}
727
- }
728
- return {
729
- unsubscribe: () => {
730
- closed = true;
731
- },
732
- get closed() {
733
- return true;
734
- }
735
- };
736
- }
737
- const wildcardListener = (event) => {
738
- if (closed)
739
- return;
740
- if (next) {
741
- try {
742
- next({ type: event.originalType, detail: event.detail });
743
- } catch (err) {
744
- if (error) {
745
- try {
746
- error(err);
747
- } catch {}
748
- }
749
- }
750
- }
751
- };
752
- const unsubscribe = addWildcardListener("*", wildcardListener);
753
- const onComplete = () => {
754
- if (closed)
755
- return;
756
- closed = true;
757
- if (completeCallback) {
758
- try {
759
- completeCallback();
760
- } catch {}
761
- }
762
- };
763
- completionCallbacks.add(onComplete);
764
- return {
765
- unsubscribe: () => {
766
- if (closed)
767
- return;
768
- closed = true;
769
- unsubscribe();
770
- completionCallbacks.delete(onComplete);
771
- },
772
- get closed() {
773
- return closed || isCompleted;
774
- }
775
- };
776
- },
777
- [SymbolObservable]() {
778
- return observable;
1274
+ return new Observable((observer) => {
1275
+ if (isCompleted) {
1276
+ observer.complete();
1277
+ return;
779
1278
  }
780
- };
781
- return observable;
1279
+ const wildcardListener = (event) => {
1280
+ observer.next(createEvent(event.originalType, event.detail, {
1281
+ target,
1282
+ currentTarget: target,
1283
+ eventPhase: 2,
1284
+ bubbles: event.bubbles,
1285
+ cancelable: event.cancelable,
1286
+ composed: event.composed
1287
+ }));
1288
+ };
1289
+ const unsubscribe2 = addWildcardListener("*", wildcardListener);
1290
+ const onComplete = () => {
1291
+ observer.complete();
1292
+ };
1293
+ completionCallbacks.add(onComplete);
1294
+ return () => {
1295
+ unsubscribe2();
1296
+ completionCallbacks.delete(onComplete);
1297
+ };
1298
+ });
782
1299
  };
783
1300
  function events(type, options) {
784
1301
  if (isCompleted) {
@@ -807,19 +1324,26 @@ function createEventTargetInternal(opts) {
807
1324
  let resolve = null;
808
1325
  let done = false;
809
1326
  let hasOverflow = false;
1327
+ let onAbort = null;
1328
+ const cleanupAbortListener = () => {
1329
+ if (signal && onAbort) {
1330
+ signal.removeEventListener("abort", onAbort);
1331
+ }
1332
+ };
810
1333
  const unsub = addEventListener(type, (event) => {
811
1334
  if (done)
812
1335
  return;
1336
+ const typedEvent = event;
813
1337
  if (resolve) {
814
1338
  const r = resolve;
815
1339
  resolve = null;
816
- r({ value: event, done: false });
1340
+ r({ value: typedEvent, done: false });
817
1341
  } else {
818
1342
  if (buffer.length >= bufferSize && bufferSize !== Infinity) {
819
1343
  switch (overflowStrategy) {
820
1344
  case "drop-oldest":
821
1345
  buffer.shift();
822
- buffer.push(event);
1346
+ buffer.push(typedEvent);
823
1347
  break;
824
1348
  case "drop-latest":
825
1349
  break;
@@ -828,15 +1352,17 @@ function createEventTargetInternal(opts) {
828
1352
  completionCallbacks.delete(onComplete);
829
1353
  done = true;
830
1354
  hasOverflow = true;
1355
+ cleanupAbortListener();
831
1356
  return;
832
1357
  }
833
1358
  } else {
834
- buffer.push(event);
1359
+ buffer.push(typedEvent);
835
1360
  }
836
1361
  }
837
1362
  });
838
1363
  const onComplete = () => {
839
1364
  done = true;
1365
+ cleanupAbortListener();
840
1366
  if (resolve) {
841
1367
  const r = resolve;
842
1368
  resolve = null;
@@ -844,7 +1370,6 @@ function createEventTargetInternal(opts) {
844
1370
  }
845
1371
  };
846
1372
  completionCallbacks.add(onComplete);
847
- let onAbort = null;
848
1373
  if (signal) {
849
1374
  onAbort = () => {
850
1375
  done = true;
@@ -868,26 +1393,22 @@ function createEventTargetInternal(opts) {
868
1393
  if (buffer.length > 0) {
869
1394
  return { value: buffer.shift(), done: false };
870
1395
  }
871
- if (hasOverflow) {
872
- hasOverflow = false;
873
- throw new BufferOverflowError(type, bufferSize);
874
- }
875
- if (done) {
876
- return { value: undefined, done: true };
877
- }
878
1396
  if (resolve !== null) {
879
1397
  return Promise.reject(new Error("Concurrent calls to next() are not supported on this async iterator"));
880
1398
  }
881
1399
  return new Promise((_resolve, _reject) => {
882
- if (done) {
883
- _resolve({ value: undefined, done: true });
884
- return;
885
- }
886
1400
  if (hasOverflow) {
887
1401
  hasOverflow = false;
888
1402
  _reject(new BufferOverflowError(type, bufferSize));
889
1403
  return;
890
1404
  }
1405
+ if (done) {
1406
+ _resolve({
1407
+ value: undefined,
1408
+ done: true
1409
+ });
1410
+ return;
1411
+ }
891
1412
  resolve = _resolve;
892
1413
  });
893
1414
  },
@@ -900,9 +1421,7 @@ function createEventTargetInternal(opts) {
900
1421
  done = true;
901
1422
  completionCallbacks.delete(onComplete);
902
1423
  unsub();
903
- if (signal && onAbort) {
904
- signal.removeEventListener("abort", onAbort);
905
- }
1424
+ cleanupAbortListener();
906
1425
  return Promise.resolve({
907
1426
  value: undefined,
908
1427
  done: true
@@ -916,12 +1435,13 @@ function createEventTargetInternal(opts) {
916
1435
  removeEventListener,
917
1436
  dispatchEvent,
918
1437
  clear,
919
- once,
1438
+ on,
1439
+ once: onceMethod,
920
1440
  removeAllListeners,
921
1441
  pipe,
922
1442
  addWildcardListener,
923
1443
  removeWildcardListener,
924
- complete,
1444
+ complete: complete2,
925
1445
  get completed() {
926
1446
  return isCompleted;
927
1447
  },
@@ -934,84 +1454,8 @@ function createEventTargetInternal(opts) {
934
1454
  };
935
1455
  return target;
936
1456
  }
937
- // src/interop.ts
938
- function forwardToEventTarget(source, target, options) {
939
- const unsubscribe = source.addWildcardListener("*", (event) => {
940
- const domEvent = {
941
- type: event.originalType,
942
- detail: event.detail
943
- };
944
- target.dispatchEvent(domEvent);
945
- }, options);
946
- return unsubscribe;
947
- }
948
- function fromEventTarget(domTarget, eventTypes, options) {
949
- const eventful = createEventTarget({
950
- onListenerError: options?.onListenerError
951
- });
952
- const handlers = new Map;
953
- for (const type of eventTypes) {
954
- const handler = (event) => {
955
- eventful.dispatchEvent({
956
- type,
957
- detail: event.detail ?? event
958
- });
959
- };
960
- handlers.set(type, handler);
961
- domTarget.addEventListener(type, handler);
962
- }
963
- let onAbort = null;
964
- if (options?.signal) {
965
- onAbort = () => {
966
- for (const [type, handler] of handlers) {
967
- domTarget.removeEventListener(type, handler);
968
- }
969
- handlers.clear();
970
- eventful.complete();
971
- };
972
- options.signal.addEventListener("abort", onAbort, { once: true });
973
- if (options.signal.aborted)
974
- onAbort();
975
- }
976
- return {
977
- addEventListener: eventful.addEventListener,
978
- removeEventListener: eventful.removeEventListener,
979
- dispatchEvent: eventful.dispatchEvent,
980
- clear: eventful.clear,
981
- once: eventful.once,
982
- removeAllListeners: eventful.removeAllListeners,
983
- pipe: eventful.pipe,
984
- addWildcardListener: eventful.addWildcardListener,
985
- removeWildcardListener: eventful.removeWildcardListener,
986
- subscribe: eventful.subscribe,
987
- toObservable: eventful.toObservable,
988
- complete: eventful.complete,
989
- get completed() {
990
- return eventful.completed;
991
- },
992
- events: eventful.events,
993
- destroy: () => {
994
- if (options?.signal && onAbort) {
995
- options.signal.removeEventListener("abort", onAbort);
996
- }
997
- for (const [type, handler] of handlers) {
998
- domTarget.removeEventListener(type, handler);
999
- }
1000
- handlers.clear();
1001
- eventful.complete();
1002
- }
1003
- };
1004
- }
1005
- function pipe(source, target, options) {
1006
- return source.addWildcardListener("*", (event) => {
1007
- target.dispatchEvent({
1008
- type: event.originalType,
1009
- detail: event.detail
1010
- });
1011
- }, options);
1012
- }
1013
- // src/eventful.ts
1014
- class Eventful {
1457
+ // src/event-emission.ts
1458
+ class EventEmission {
1015
1459
  #target;
1016
1460
  constructor() {
1017
1461
  this.#target = createEventTarget();
@@ -1019,12 +1463,15 @@ class Eventful {
1019
1463
  addEventListener(type, listener, options) {
1020
1464
  return this.#target.addEventListener(type, listener, options);
1021
1465
  }
1022
- removeEventListener(type, listener) {
1023
- this.#target.removeEventListener(type, listener);
1466
+ removeEventListener(type, listener, options) {
1467
+ this.#target.removeEventListener(type, listener, options);
1024
1468
  }
1025
1469
  dispatchEvent(event) {
1026
1470
  return this.#target.dispatchEvent(event);
1027
1471
  }
1472
+ on(type, options) {
1473
+ return this.#target.on(type, options);
1474
+ }
1028
1475
  once(type, listener, options) {
1029
1476
  return this.#target.once(type, listener, options);
1030
1477
  }
@@ -1043,9 +1490,9 @@ class Eventful {
1043
1490
  removeWildcardListener(pattern, listener) {
1044
1491
  this.#target.removeWildcardListener(pattern, listener);
1045
1492
  }
1046
- subscribe(typeOrObserver, observerOrNext, error, completeHandler) {
1493
+ subscribe(typeOrObserver, observerOrNext, error2, completeHandler) {
1047
1494
  if (typeof typeOrObserver === "string") {
1048
- return this.#target.subscribe(typeOrObserver, observerOrNext, error, completeHandler);
1495
+ return this.#target.subscribe(typeOrObserver, observerOrNext, error2, completeHandler);
1049
1496
  }
1050
1497
  if (typeof typeOrObserver === "function") {
1051
1498
  return this.#target.toObservable().subscribe(typeOrObserver);
@@ -1076,18 +1523,10 @@ class Eventful {
1076
1523
  }
1077
1524
  }
1078
1525
  export {
1079
- setupEventForwarding,
1080
- pipe,
1081
- isObserved,
1082
- getOriginal,
1083
- fromEventTarget,
1084
- forwardToEventTarget,
1085
1526
  createEventTarget,
1086
1527
  SymbolObservable,
1087
- PROXY_MARKER,
1088
- ORIGINAL_TARGET,
1089
- Eventful,
1528
+ EventEmission,
1090
1529
  BufferOverflowError
1091
1530
  };
1092
1531
 
1093
- //# debugId=2E6AB805E4C6152664756E2164756E21
1532
+ //# debugId=60621EDDB80DC90E64756E2164756E21