events-ex 2.2.0 → 2.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,26 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [commit-and-tag-version](https://github.com/absolute-version/commit-and-tag-version) for commit guidelines.
4
4
 
5
+ ## [2.3.1](https://github.com/snowyu/events-ex.js/compare/v2.3.0...v2.3.1) (2026-04-17)
6
+
7
+
8
+ ### Performance
9
+
10
+ * minor optimition for index ([f6c4415](https://github.com/snowyu/events-ex.js/commit/f6c44157ffda17957fad5ad2e0aedbb8ec521be7))
11
+
12
+ ## [2.3.0](https://github.com/snowyu/events-ex.js/compare/v2.2.0...v2.3.0) (2026-04-17)
13
+
14
+
15
+ ### Features
16
+
17
+ * support special index values 'first' and 'last' for listener ordering ([53cfb5b](https://github.com/snowyu/events-ex.js/commit/53cfb5bb3f7229cb549e99d410c0d6d39665eb0a))
18
+
19
+ ## [2.3.0](https://github.com/snowyu/events-ex.js/compare/v2.2.0...v2.3.0) (2025-05-15)
20
+
21
+ ### Features
22
+
23
+ * **index:** support special index values 'first' and 'last' in on/once methods to maintain regional ordering.
24
+
5
25
  ## [2.2.0](https://github.com/snowyu/events-ex.js/compare/v2.1.1...v2.2.0) (2026-03-10)
6
26
 
7
27
 
package/README.cn.md CHANGED
@@ -7,7 +7,7 @@
7
7
  * **模块化 Event-able 能力**:通过 `eventable(MyClass)` 将事件功能注入任何类,无需强制继承。
8
8
  * **核心事件增强**:
9
9
  * **冒泡与中断**:全面支持事件传播控制及中途取消。
10
- * **监听器排序**:通过 `on()` 和 `once()` 的可选 `index` 参数精确控制执行顺序。
10
+ * **监听器排序**:通过 `on()` 和 `once()` 的可选 `index` 参数精确控制执行顺序。支持特殊值 `'first'` 和 `'last'` 以确保监听器始终保持在边界。
11
11
  * **正则表达式订阅**:支持使用正则表达式订阅多个匹配的事件。
12
12
  * **可挂载(Hook-able)系统**:允许在核心层面拦截并修改事件行为。
13
13
  * **高级异步特性 (仅针对 `emitAsync`)**:
@@ -38,8 +38,11 @@
38
38
  * `first`: 返回第一个成功的非 undefined 结果(自动跳过错误)。
39
39
  * `collect`: 按注册顺序以数组形式返回所有结果。
40
40
  * **流式配置**: 使用 `.parallel()` 或 `.configure({...})` 进行单次定制化异步发射。
41
- * **事件监听器 API**: `on/once(event: string|RegExp, listener, index?:number)`
42
- * 📌 **Index 参数** (可选): 允许在监听器数组中指定插入位置。
41
+ * **事件监听器 API**: `on/once(event: string|RegExp, listener, index?: number|'first'|'last')`
42
+ * 📌 **Index 参数** (可选): 在监听器数组中指定插入位置。
43
+ * `'first'` (`-Infinity`): 始终保持在 **Head** 区。先注册的 `'first'` 监听器排在最前面。
44
+ * `'last'` (`Infinity`): 始终保持在 **Tail** 区。先注册为 `'last'` 的监听器将始终位于数组的绝对末尾。
45
+ * `number`: 常规 **Body** 区内的相对索引。
43
46
  * 🧪 **正则事件匹配**: 允许使用正则表达式绑定多个相关事件。
44
47
 
45
48
  * **与 [event-emitter](https://github.com/medikoo/event-emitter) 的区别**
@@ -59,13 +62,17 @@
59
62
 
60
63
  ```js
61
64
  const ee = new EventEmitter();
62
- ee.on('test', () => console.log('second'), 1);
63
- ee.on('test', () => console.log('first'), 0); // 在索引 0 处插入
65
+ ee.on('test', () => console.log('third'));
66
+ ee.on('test', () => console.log('first'), 'first'); // 始终在最前
67
+ ee.on('test', () => console.log('last'), 'last'); // 始终在最后
68
+ ee.on('test', () => console.log('second'), 1); // 常规区域索引 1 (相对于 Head)
64
69
 
65
70
  ee.emit('test');
66
71
  // 输出:
67
72
  // first
68
73
  // second
74
+ // third
75
+ // last
69
76
  ```
70
77
 
71
78
  #### 核心特性:正则表达式订阅
package/README.md CHANGED
@@ -7,7 +7,7 @@ Browser-friendly enhanced event emitter [ability][Ability] and class. It's modif
7
7
  * **Modular Event-able Ability**: Inject event capabilities into any class using `eventable(MyClass)` without forced inheritance.
8
8
  * **Core Event Enhancements**:
9
9
  * **Bubbling & Interruption**: Full support for event propagation and mid-stream cancellation.
10
- * **Listener Ordering**: Precise control via the optional `index` parameter in `on()` and `once()`.
10
+ * **Listener Ordering**: Precise control via the optional `index` parameter in `on()` and `once()`. Supports special values `'first'` and `'last'` to ensure listeners stay at the boundaries.
11
11
  * **Regex Subscription**: Subscribe to multiple events using Regular Expressions.
12
12
  * **Hook-able System**: Intercept and modify event behavior at the core level.
13
13
  * **Advanced Asynchronous Features (Specific to `emitAsync`)**:
@@ -38,8 +38,11 @@ Browser-friendly enhanced event emitter [ability][Ability] and class. It's modif
38
38
  * `first`: Returns the first successful non-undefined result (skips errors).
39
39
  * `collect`: Returns an array of all results in registration order.
40
40
  * **Fluent Configuration**: Use `.parallel()` or `.configure({...})` for one-time customized async emits.
41
- * **Listener APIs**: `on/once(event: string|RegExp, listener, index?: number)`
42
- * 📌 **Index Parameter** (Optional): Allows specifying the insertion position in the listener array.
41
+ * **Listener APIs**: `on/once(event: string|RegExp, listener, index?: number|'first'|'last')`
42
+ * 📌 **Index Parameter** (Optional): Insertion position in the listener array.
43
+ * `'first'` (`-Infinity`): Stays in the **Head** zone. The first listener added as `'first'` is placed at the very front.
44
+ * `'last'` (`Infinity`): Stays in the **Tail** zone. The first listener added as `'last'` will always remain at the absolute end.
45
+ * `number`: Relative index within the **Body** zone.
43
46
  * 🧪 **Regex Event Matching**: Listeners can bind to multiple events via regex patterns.
44
47
 
45
48
  * **Difference with [event-emitter](https://github.com/medikoo/event-emitter)**
@@ -89,13 +92,17 @@ eventable(MyClass);
89
92
 
90
93
  ```js
91
94
  const ee = new EventEmitter();
92
- ee.on('test', () => console.log('second'), 1);
93
- ee.on('test', () => console.log('first'), 0); // Insert at index 0
95
+ ee.on('test', () => console.log('third'));
96
+ ee.on('test', () => console.log('first'), 'first'); // Always at the front
97
+ ee.on('test', () => console.log('last'), 'last'); // Always at the end
98
+ ee.on('test', () => console.log('second'), 1); // Body index 1 (relative to Head)
94
99
 
95
100
  ee.emit('test');
96
101
  // Output:
97
102
  // first
98
103
  // second
104
+ // third
105
+ // last
99
106
  ```
100
107
 
101
108
  #### Core Feature: Regex Subscription
package/docs/README.md CHANGED
@@ -11,7 +11,7 @@ Browser-friendly enhanced event emitter [ability][Ability] and class. It's modif
11
11
  * **Modular Event-able Ability**: Inject event capabilities into any class using `eventable(MyClass)` without forced inheritance.
12
12
  * **Core Event Enhancements**:
13
13
  * **Bubbling & Interruption**: Full support for event propagation and mid-stream cancellation.
14
- * **Listener Ordering**: Precise control via the optional `index` parameter in `on()` and `once()`.
14
+ * **Listener Ordering**: Precise control via the optional `index` parameter in `on()` and `once()`. Supports special values `'first'` and `'last'` to ensure listeners stay at the boundaries.
15
15
  * **Regex Subscription**: Subscribe to multiple events using Regular Expressions.
16
16
  * **Hook-able System**: Intercept and modify event behavior at the core level.
17
17
  * **Advanced Asynchronous Features (Specific to `emitAsync`)**:
@@ -42,8 +42,11 @@ Browser-friendly enhanced event emitter [ability][Ability] and class. It's modif
42
42
  * `first`: Returns the first successful non-undefined result (skips errors).
43
43
  * `collect`: Returns an array of all results in registration order.
44
44
  * **Fluent Configuration**: Use `.parallel()` or `.configure({...})` for one-time customized async emits.
45
- * **Listener APIs**: `on/once(event: string|RegExp, listener, index?: number)`
46
- * 📌 **Index Parameter** (Optional): Allows specifying the insertion position in the listener array.
45
+ * **Listener APIs**: `on/once(event: string|RegExp, listener, index?: number|'first'|'last')`
46
+ * 📌 **Index Parameter** (Optional): Insertion position in the listener array.
47
+ * `'first'` (`-Infinity`): Stays in the **Head** zone. The first listener added as `'first'` is placed at the very front.
48
+ * `'last'` (`Infinity`): Stays in the **Tail** zone. The first listener added as `'last'` will always remain at the absolute end.
49
+ * `number`: Relative index within the **Body** zone.
47
50
  * 🧪 **Regex Event Matching**: Listeners can bind to multiple events via regex patterns.
48
51
 
49
52
  * **Difference with [event-emitter](https://github.com/medikoo/event-emitter)**
@@ -93,13 +96,17 @@ eventable(MyClass);
93
96
 
94
97
  ```js
95
98
  const ee = new EventEmitter();
96
- ee.on('test', () => console.log('second'), 1);
97
- ee.on('test', () => console.log('first'), 0); // Insert at index 0
99
+ ee.on('test', () => console.log('third'));
100
+ ee.on('test', () => console.log('first'), 'first'); // Always at the front
101
+ ee.on('test', () => console.log('last'), 'last'); // Always at the end
102
+ ee.on('test', () => console.log('second'), 1); // Body index 1 (relative to Head)
98
103
 
99
104
  ee.emit('test');
100
105
  // Output:
101
106
  // first
102
107
  // second
108
+ // third
109
+ // last
103
110
  ```
104
111
 
105
112
  #### Core Feature: Regex Subscription
@@ -8,7 +8,7 @@
8
8
 
9
9
  > **allOff**(`emitter`, `type?`): [`EventEmitter`](../../event-emitter/classes/EventEmitter.md)
10
10
 
11
- Defined in: [src/all-off.js:12](https://github.com/snowyu/events-ex.js/blob/fb077063a0ea7231fa89bf74a09be2f52f8401e4/src/all-off.js#L12)
11
+ Defined in: [src/all-off.js:12](https://github.com/snowyu/events-ex.js/blob/f6c44157ffda17957fad5ad2e0aedbb8ec521be7/src/all-off.js#L12)
12
12
 
13
13
  Removes all listeners for a specific event or all events from an event emitter.
14
14
 
@@ -8,4 +8,4 @@
8
8
 
9
9
  > `const` **RegExpEventSymbol**: `symbol` \| `"@@RegExpEvent"`
10
10
 
11
- Defined in: [src/consts.js:13](https://github.com/snowyu/events-ex.js/blob/fb077063a0ea7231fa89bf74a09be2f52f8401e4/src/consts.js#L13)
11
+ Defined in: [src/consts.js:13](https://github.com/snowyu/events-ex.js/blob/f6c44157ffda17957fad5ad2e0aedbb8ec521be7/src/consts.js#L13)
@@ -8,7 +8,7 @@
8
8
 
9
9
  > `const` **states**: `object`
10
10
 
11
- Defined in: [src/consts.js:6](https://github.com/snowyu/events-ex.js/blob/fb077063a0ea7231fa89bf74a09be2f52f8401e4/src/consts.js#L6)
11
+ Defined in: [src/consts.js:6](https://github.com/snowyu/events-ex.js/blob/f6c44157ffda17957fad5ad2e0aedbb8ec521be7/src/consts.js#L6)
12
12
 
13
13
  ## Type Declaration
14
14
 
@@ -8,7 +8,7 @@
8
8
 
9
9
  > **getEventableMethods**(`aClass`): `object`
10
10
 
11
- Defined in: [src/default-methods.js:15](https://github.com/snowyu/events-ex.js/blob/fb077063a0ea7231fa89bf74a09be2f52f8401e4/src/default-methods.js#L15)
11
+ Defined in: [src/default-methods.js:15](https://github.com/snowyu/events-ex.js/blob/f6c44157ffda17957fad5ad2e0aedbb8ec521be7/src/default-methods.js#L15)
12
12
 
13
13
  ## Parameters
14
14
 
@@ -172,9 +172,13 @@ The listener function to be called when the event is emitted.
172
172
 
173
173
  ##### index?
174
174
 
175
- `number`
175
+ The index at which to insert the listener.
176
+ - 'first' or -Infinity: Adds to the "Head" zone. The first listener added as 'first' is placed at the very front.
177
+ - 'last' or Infinity: Adds to the "Tail" zone. The first listener added as 'last' will always be the very last one to execute.
178
+ - number: Inserts at the specified index within the "Body" (normal) zone.
179
+ If not specified, the listener is added to the end of the "Body" zone.
176
180
 
177
- The index at which to insert the listener. If not specified, the listener will be added at the end of the listeners array.
181
+ `number` | `"first"` | `"last"`
178
182
 
179
183
  #### Returns
180
184
 
@@ -208,9 +212,13 @@ The listener function to be called once when the event is emitted.
208
212
 
209
213
  ##### index?
210
214
 
211
- `number`
215
+ The index at which to insert the listener.
216
+ - 'first' or -Infinity: Adds to the "Head" zone. The first listener added as 'first' is placed at the very front.
217
+ - 'last' or Infinity: Adds to the "Tail" zone. The first listener added as 'last' will always be the very last one to execute.
218
+ - number: Inserts at the specified index within the "Body" (normal) zone.
219
+ If not specified, the listener is added to the end of the "Body" zone.
212
220
 
213
- The index at which to insert the listener. If not specified, the listener will be added at the end of the listeners array.
221
+ `number` | `"first"` | `"last"`
214
222
 
215
223
  #### Returns
216
224
 
@@ -6,7 +6,7 @@
6
6
 
7
7
  # Class: Event
8
8
 
9
- Defined in: [src/event.js:8](https://github.com/snowyu/events-ex.js/blob/fb077063a0ea7231fa89bf74a09be2f52f8401e4/src/event.js#L8)
9
+ Defined in: [src/event.js:8](https://github.com/snowyu/events-ex.js/blob/f6c44157ffda17957fad5ad2e0aedbb8ec521be7/src/event.js#L8)
10
10
 
11
11
  Creates a new Event object instance that contains information about the event, such as the target element and the return value of the event.
12
12
 
@@ -24,7 +24,7 @@ Who trigger the event
24
24
 
25
25
  > **new Event**(`target`, `type`): `Event`
26
26
 
27
- Defined in: [src/event.js:8](https://github.com/snowyu/events-ex.js/blob/fb077063a0ea7231fa89bf74a09be2f52f8401e4/src/event.js#L8)
27
+ Defined in: [src/event.js:8](https://github.com/snowyu/events-ex.js/blob/f6c44157ffda17957fad5ad2e0aedbb8ec521be7/src/event.js#L8)
28
28
 
29
29
  Creates a new Event object instance that contains information about the event, such as the target element and the return value of the event.
30
30
 
@@ -56,7 +56,7 @@ Event Object that contains information about the event, such as the target eleme
56
56
 
57
57
  > **resolved**: `boolean`
58
58
 
59
- Defined in: [src/event.js:38](https://github.com/snowyu/events-ex.js/blob/fb077063a0ea7231fa89bf74a09be2f52f8401e4/src/event.js#L38)
59
+ Defined in: [src/event.js:38](https://github.com/snowyu/events-ex.js/blob/f6c44157ffda17957fad5ad2e0aedbb8ec521be7/src/event.js#L38)
60
60
 
61
61
  Whether a result has been resolved (for 'first' result mode)
62
62
 
@@ -66,7 +66,7 @@ Whether a result has been resolved (for 'first' result mode)
66
66
 
67
67
  > **result**: `any`
68
68
 
69
- Defined in: [src/event.js:44](https://github.com/snowyu/events-ex.js/blob/fb077063a0ea7231fa89bf74a09be2f52f8401e4/src/event.js#L44)
69
+ Defined in: [src/event.js:44](https://github.com/snowyu/events-ex.js/blob/f6c44157ffda17957fad5ad2e0aedbb8ec521be7/src/event.js#L44)
70
70
 
71
71
  Keep your event result here if any.
72
72
 
@@ -76,7 +76,7 @@ Keep your event result here if any.
76
76
 
77
77
  > **stopped**: `boolean`
78
78
 
79
- Defined in: [src/event.js:32](https://github.com/snowyu/events-ex.js/blob/fb077063a0ea7231fa89bf74a09be2f52f8401e4/src/event.js#L32)
79
+ Defined in: [src/event.js:32](https://github.com/snowyu/events-ex.js/blob/f6c44157ffda17957fad5ad2e0aedbb8ec521be7/src/event.js#L32)
80
80
 
81
81
  Whether stop the bubbling event
82
82
 
@@ -86,7 +86,7 @@ Whether stop the bubbling event
86
86
 
87
87
  > **target**: `any`
88
88
 
89
- Defined in: [src/event.js:26](https://github.com/snowyu/events-ex.js/blob/fb077063a0ea7231fa89bf74a09be2f52f8401e4/src/event.js#L26)
89
+ Defined in: [src/event.js:26](https://github.com/snowyu/events-ex.js/blob/f6c44157ffda17957fad5ad2e0aedbb8ec521be7/src/event.js#L26)
90
90
 
91
91
  Who trigger the event
92
92
 
@@ -96,7 +96,7 @@ Who trigger the event
96
96
 
97
97
  > **type**: `string`
98
98
 
99
- Defined in: [src/event.js:50](https://github.com/snowyu/events-ex.js/blob/fb077063a0ea7231fa89bf74a09be2f52f8401e4/src/event.js#L50)
99
+ Defined in: [src/event.js:50](https://github.com/snowyu/events-ex.js/blob/f6c44157ffda17957fad5ad2e0aedbb8ec521be7/src/event.js#L50)
100
100
 
101
101
  The type of the event.
102
102
 
@@ -106,7 +106,7 @@ The type of the event.
106
106
 
107
107
  > **end**(): `any`
108
108
 
109
- Defined in: [src/event.js:57](https://github.com/snowyu/events-ex.js/blob/fb077063a0ea7231fa89bf74a09be2f52f8401e4/src/event.js#L57)
109
+ Defined in: [src/event.js:57](https://github.com/snowyu/events-ex.js/blob/f6c44157ffda17957fad5ad2e0aedbb8ec521be7/src/event.js#L57)
110
110
 
111
111
  Ends the event and returns the result.
112
112
 
@@ -122,7 +122,7 @@ The result of the event.
122
122
 
123
123
  > **init**(`target`, `type`): `void`
124
124
 
125
- Defined in: [src/event.js:20](https://github.com/snowyu/events-ex.js/blob/fb077063a0ea7231fa89bf74a09be2f52f8401e4/src/event.js#L20)
125
+ Defined in: [src/event.js:20](https://github.com/snowyu/events-ex.js/blob/f6c44157ffda17957fad5ad2e0aedbb8ec521be7/src/event.js#L20)
126
126
 
127
127
  Initializes the event with the target object.
128
128
 
@@ -6,7 +6,7 @@
6
6
 
7
7
  # Class: EventEmitter
8
8
 
9
- Defined in: [src/event-emitter.js:8](https://github.com/snowyu/events-ex.js/blob/fb077063a0ea7231fa89bf74a09be2f52f8401e4/src/event-emitter.js#L8)
9
+ Defined in: [src/event-emitter.js:8](https://github.com/snowyu/events-ex.js/blob/f6c44157ffda17957fad5ad2e0aedbb8ec521be7/src/event-emitter.js#L8)
10
10
 
11
11
  ## Classdesc
12
12
 
@@ -18,7 +18,7 @@ Class that represents an event emitter.
18
18
 
19
19
  > **new EventEmitter**(): `EventEmitter`
20
20
 
21
- Defined in: [src/event-emitter.js:8](https://github.com/snowyu/events-ex.js/blob/fb077063a0ea7231fa89bf74a09be2f52f8401e4/src/event-emitter.js#L8)
21
+ Defined in: [src/event-emitter.js:8](https://github.com/snowyu/events-ex.js/blob/f6c44157ffda17957fad5ad2e0aedbb8ec521be7/src/event-emitter.js#L8)
22
22
 
23
23
  #### Returns
24
24
 
@@ -6,7 +6,7 @@
6
6
 
7
7
  # Class: EventEmitter
8
8
 
9
- Defined in: [src/event-emitter.d.ts:6](https://github.com/snowyu/events-ex.js/blob/fb077063a0ea7231fa89bf74a09be2f52f8401e4/src/event-emitter.d.ts#L6)
9
+ Defined in: [src/event-emitter.d.ts:6](https://github.com/snowyu/events-ex.js/blob/f6c44157ffda17957fad5ad2e0aedbb8ec521be7/src/event-emitter.d.ts#L6)
10
10
 
11
11
  Class that represents an event emitter.
12
12
 
@@ -26,7 +26,7 @@ Class that represents an event emitter.
26
26
 
27
27
  > `static` **defaultMaxListeners**: `number`
28
28
 
29
- Defined in: [src/event-emitter.d.ts:7](https://github.com/snowyu/events-ex.js/blob/fb077063a0ea7231fa89bf74a09be2f52f8401e4/src/event-emitter.d.ts#L7)
29
+ Defined in: [src/event-emitter.d.ts:7](https://github.com/snowyu/events-ex.js/blob/f6c44157ffda17957fad5ad2e0aedbb8ec521be7/src/event-emitter.d.ts#L7)
30
30
 
31
31
  ## Methods
32
32
 
@@ -34,7 +34,7 @@ Defined in: [src/event-emitter.d.ts:7](https://github.com/snowyu/events-ex.js/bl
34
34
 
35
35
  > **emit**(`eventName`, ...`args`): `any`
36
36
 
37
- Defined in: [src/event-emitter.d.ts:48](https://github.com/snowyu/events-ex.js/blob/fb077063a0ea7231fa89bf74a09be2f52f8401e4/src/event-emitter.d.ts#L48)
37
+ Defined in: [src/event-emitter.d.ts:58](https://github.com/snowyu/events-ex.js/blob/f6c44157ffda17957fad5ad2e0aedbb8ec521be7/src/event-emitter.d.ts#L58)
38
38
 
39
39
  Emits the specified event type with the given arguments.
40
40
 
@@ -62,7 +62,7 @@ The result of the event.
62
62
 
63
63
  > **emitAsync**(`eventName`, ...`args`): `Promise`\<`any`\>
64
64
 
65
- Defined in: [src/event-emitter.d.ts:54](https://github.com/snowyu/events-ex.js/blob/fb077063a0ea7231fa89bf74a09be2f52f8401e4/src/event-emitter.d.ts#L54)
65
+ Defined in: [src/event-emitter.d.ts:64](https://github.com/snowyu/events-ex.js/blob/f6c44157ffda17957fad5ad2e0aedbb8ec521be7/src/event-emitter.d.ts#L64)
66
66
 
67
67
  Asynchronously emits the specified event type with the given arguments.
68
68
 
@@ -90,7 +90,7 @@ A promise that resolves with the result of the event.
90
90
 
91
91
  > **listenerCount**(`eventName`): `number`
92
92
 
93
- Defined in: [src/event-emitter.d.ts:83](https://github.com/snowyu/events-ex.js/blob/fb077063a0ea7231fa89bf74a09be2f52f8401e4/src/event-emitter.d.ts#L83)
93
+ Defined in: [src/event-emitter.d.ts:93](https://github.com/snowyu/events-ex.js/blob/f6c44157ffda17957fad5ad2e0aedbb8ec521be7/src/event-emitter.d.ts#L93)
94
94
 
95
95
  Returns the count of listeners that are registered to listen for the specified event.
96
96
 
@@ -114,7 +114,7 @@ The name of the event to get the listeners for.
114
114
 
115
115
  > **listeners**(`eventName`): `Function`[]
116
116
 
117
- Defined in: [src/event-emitter.d.ts:76](https://github.com/snowyu/events-ex.js/blob/fb077063a0ea7231fa89bf74a09be2f52f8401e4/src/event-emitter.d.ts#L76)
117
+ Defined in: [src/event-emitter.d.ts:86](https://github.com/snowyu/events-ex.js/blob/f6c44157ffda17957fad5ad2e0aedbb8ec521be7/src/event-emitter.d.ts#L86)
118
118
 
119
119
  Returns an array of functions that are registered to listen for the specified event.
120
120
 
@@ -138,7 +138,7 @@ The name of the event to get the listeners for.
138
138
 
139
139
  > **off**(`eventName`, `listener`): `EventEmitter`
140
140
 
141
- Defined in: [src/event-emitter.d.ts:33](https://github.com/snowyu/events-ex.js/blob/fb077063a0ea7231fa89bf74a09be2f52f8401e4/src/event-emitter.d.ts#L33)
141
+ Defined in: [src/event-emitter.d.ts:43](https://github.com/snowyu/events-ex.js/blob/f6c44157ffda17957fad5ad2e0aedbb8ec521be7/src/event-emitter.d.ts#L43)
142
142
 
143
143
  Removes a listener function from the specified event type.
144
144
 
@@ -172,9 +172,9 @@ If the listener is not a function.
172
172
 
173
173
  ### on()
174
174
 
175
- > **on**(`eventName`, `listener`): `EventEmitter`
175
+ > **on**(`eventName`, `listener`, `index?`): `EventEmitter`
176
176
 
177
- Defined in: [src/event-emitter.d.ts:16](https://github.com/snowyu/events-ex.js/blob/fb077063a0ea7231fa89bf74a09be2f52f8401e4/src/event-emitter.d.ts#L16)
177
+ Defined in: [src/event-emitter.d.ts:21](https://github.com/snowyu/events-ex.js/blob/f6c44157ffda17957fad5ad2e0aedbb8ec521be7/src/event-emitter.d.ts#L21)
178
178
 
179
179
  Adds a listener function to the specified event type.
180
180
 
@@ -190,6 +190,16 @@ Adds a listener function to the specified event type.
190
190
 
191
191
  The listener function to be called when the event is emitted.
192
192
 
193
+ ##### index?
194
+
195
+ The index at which to insert the listener.
196
+ - 'first' or -Infinity: adds to the beginning of the listeners (stay at the front).
197
+ - 'last' or Infinity: adds to the end of the listeners (stay at the back).
198
+ - number: inserts at the specified index within the normal listeners zone.
199
+ If not specified, the listener will be added at the end of the normal listeners.
200
+
201
+ `number` | `"first"` | `"last"`
202
+
193
203
  #### Returns
194
204
 
195
205
  `EventEmitter`
@@ -204,9 +214,9 @@ If the listener is not a function.
204
214
 
205
215
  ### once()
206
216
 
207
- > **once**(`eventName`, `listener`): `EventEmitter`
217
+ > **once**(`eventName`, `listener`, `index?`): `EventEmitter`
208
218
 
209
- Defined in: [src/event-emitter.d.ts:24](https://github.com/snowyu/events-ex.js/blob/fb077063a0ea7231fa89bf74a09be2f52f8401e4/src/event-emitter.d.ts#L24)
219
+ Defined in: [src/event-emitter.d.ts:34](https://github.com/snowyu/events-ex.js/blob/f6c44157ffda17957fad5ad2e0aedbb8ec521be7/src/event-emitter.d.ts#L34)
210
220
 
211
221
  Adds a one-time listener function to the specified event type.
212
222
 
@@ -222,6 +232,16 @@ Adds a one-time listener function to the specified event type.
222
232
 
223
233
  The listener function to be called once when the event is emitted.
224
234
 
235
+ ##### index?
236
+
237
+ The index at which to insert the listener.
238
+ - 'first' or -Infinity: adds to the beginning of the listeners (stay at the front).
239
+ - 'last' or Infinity: adds to the end of the listeners (stay at the back).
240
+ - number: inserts at the specified index within the normal listeners zone.
241
+ If not specified, the listener will be added at the end of the normal listeners.
242
+
243
+ `number` | `"first"` | `"last"`
244
+
225
245
  #### Returns
226
246
 
227
247
  `EventEmitter`
@@ -238,7 +258,7 @@ If the listener is not a function.
238
258
 
239
259
  > **removeAllListeners**(`eventName?`): `EventEmitter`
240
260
 
241
- Defined in: [src/event-emitter.d.ts:61](https://github.com/snowyu/events-ex.js/blob/fb077063a0ea7231fa89bf74a09be2f52f8401e4/src/event-emitter.d.ts#L61)
261
+ Defined in: [src/event-emitter.d.ts:71](https://github.com/snowyu/events-ex.js/blob/f6c44157ffda17957fad5ad2e0aedbb8ec521be7/src/event-emitter.d.ts#L71)
242
262
 
243
263
  Removes all listeners for a specific event or all events from an event emitter.
244
264
 
@@ -262,7 +282,7 @@ The event to remove listeners for. If not provided, all listeners for all events
262
282
 
263
283
  > **removeListener**(`eventName`, `listener`): `EventEmitter`
264
284
 
265
- Defined in: [src/event-emitter.d.ts:42](https://github.com/snowyu/events-ex.js/blob/fb077063a0ea7231fa89bf74a09be2f52f8401e4/src/event-emitter.d.ts#L42)
285
+ Defined in: [src/event-emitter.d.ts:52](https://github.com/snowyu/events-ex.js/blob/f6c44157ffda17957fad5ad2e0aedbb8ec521be7/src/event-emitter.d.ts#L52)
266
286
 
267
287
  Removes a listener function from the specified event type.
268
288
 
@@ -298,7 +318,7 @@ If the listener is not a function.
298
318
 
299
319
  > **setMaxListeners**(`n`): `EventEmitter`
300
320
 
301
- Defined in: [src/event-emitter.d.ts:69](https://github.com/snowyu/events-ex.js/blob/fb077063a0ea7231fa89bf74a09be2f52f8401e4/src/event-emitter.d.ts#L69)
321
+ Defined in: [src/event-emitter.d.ts:79](https://github.com/snowyu/events-ex.js/blob/f6c44157ffda17957fad5ad2e0aedbb8ec521be7/src/event-emitter.d.ts#L79)
302
322
 
303
323
  Sets the maximum number of listeners allowed for the event emitter.
304
324
 
@@ -326,7 +346,7 @@ If `n` is not a positive integer.
326
346
 
327
347
  > `static` **listenerCount**(`emitter`, `eventName`): `number`
328
348
 
329
- Defined in: [src/event-emitter.d.ts:91](https://github.com/snowyu/events-ex.js/blob/fb077063a0ea7231fa89bf74a09be2f52f8401e4/src/event-emitter.d.ts#L91)
349
+ Defined in: [src/event-emitter.d.ts:101](https://github.com/snowyu/events-ex.js/blob/f6c44157ffda17957fad5ad2e0aedbb8ec521be7/src/event-emitter.d.ts#L101)
330
350
 
331
351
  Returns the count of listeners that are registered to listen for the specified event.
332
352
 
@@ -8,7 +8,7 @@
8
8
 
9
9
  > **eventable**\<`T`\>(`targetClass?`, `options?`): `EnhancedClass`\<`T`, (`aClass?`) => `Function`\>
10
10
 
11
- Defined in: [src/eventable.js:89](https://github.com/snowyu/events-ex.js/blob/fb077063a0ea7231fa89bf74a09be2f52f8401e4/src/eventable.js#L89)
11
+ Defined in: [src/eventable.js:89](https://github.com/snowyu/events-ex.js/blob/f6c44157ffda17957fad5ad2e0aedbb8ec521be7/src/eventable.js#L89)
12
12
 
13
13
  Adds event-emitting capabilities to a class by injecting necessary methods and properties.
14
14
 
@@ -8,7 +8,7 @@
8
8
 
9
9
  > **hasListeners**(`obj`, `type?`): `boolean`
10
10
 
11
- Defined in: [src/has-listeners.js:20](https://github.com/snowyu/events-ex.js/blob/fb077063a0ea7231fa89bf74a09be2f52f8401e4/src/has-listeners.js#L20)
11
+ Defined in: [src/has-listeners.js:20](https://github.com/snowyu/events-ex.js/blob/f6c44157ffda17957fad5ad2e0aedbb8ec521be7/src/has-listeners.js#L20)
12
12
 
13
13
  Checks if an object has event listeners.
14
14
 
@@ -8,7 +8,7 @@
8
8
 
9
9
  > **pipe**(`e1`, `e2`, ...`args`): `any`
10
10
 
11
- Defined in: [src/pipe.js:21](https://github.com/snowyu/events-ex.js/blob/fb077063a0ea7231fa89bf74a09be2f52f8401e4/src/pipe.js#L21)
11
+ Defined in: [src/pipe.js:21](https://github.com/snowyu/events-ex.js/blob/f6c44157ffda17957fad5ad2e0aedbb8ec521be7/src/pipe.js#L21)
12
12
 
13
13
  Creates a pipeline between two event emitters, so that any events emitted by the first emitter are also emitted by the second emitter.
14
14
 
@@ -8,7 +8,7 @@
8
8
 
9
9
  > **pipeAsync**(`e1`, `e2`, ...`args`): `any`
10
10
 
11
- Defined in: [src/pipe-async.js:24](https://github.com/snowyu/events-ex.js/blob/fb077063a0ea7231fa89bf74a09be2f52f8401e4/src/pipe-async.js#L24)
11
+ Defined in: [src/pipe-async.js:24](https://github.com/snowyu/events-ex.js/blob/f6c44157ffda17957fad5ad2e0aedbb8ec521be7/src/pipe-async.js#L24)
12
12
 
13
13
  Creates a pipeline between two event emitters, so that any events emitted by the first emitter are also emitted by the second emitter.
14
14
 
@@ -8,7 +8,7 @@
8
8
 
9
9
  > **unify**(`e1`, `e2`): `void`
10
10
 
11
- Defined in: [src/unify.js:17](https://github.com/snowyu/events-ex.js/blob/fb077063a0ea7231fa89bf74a09be2f52f8401e4/src/unify.js#L17)
11
+ Defined in: [src/unify.js:17](https://github.com/snowyu/events-ex.js/blob/f6c44157ffda17957fad5ad2e0aedbb8ec521be7/src/unify.js#L17)
12
12
 
13
13
  Unifies the event listeners of two event emitter objects so that they share the same set of listeners for each event.
14
14
 
@@ -8,7 +8,7 @@
8
8
 
9
9
  > **remove**(...`args`): `void`
10
10
 
11
- Defined in: [src/util/array-remove.js:5](https://github.com/snowyu/events-ex.js/blob/fb077063a0ea7231fa89bf74a09be2f52f8401e4/src/util/array-remove.js#L5)
11
+ Defined in: [src/util/array-remove.js:5](https://github.com/snowyu/events-ex.js/blob/f6c44157ffda17957fad5ad2e0aedbb8ec521be7/src/util/array-remove.js#L5)
12
12
 
13
13
  ## Parameters
14
14
 
@@ -8,7 +8,7 @@
8
8
 
9
9
  > **forEach**(`obj`, `cb`, ...`args`): `void`
10
10
 
11
- Defined in: [src/util/object-for-each.js:6](https://github.com/snowyu/events-ex.js/blob/fb077063a0ea7231fa89bf74a09be2f52f8401e4/src/util/object-for-each.js#L6)
11
+ Defined in: [src/util/object-for-each.js:6](https://github.com/snowyu/events-ex.js/blob/f6c44157ffda17957fad5ad2e0aedbb8ec521be7/src/util/object-for-each.js#L6)
12
12
 
13
13
  ## Parameters
14
14
 
@@ -8,7 +8,7 @@
8
8
 
9
9
  > **pad**(`fill`, ...`args`): `string`
10
10
 
11
- Defined in: [src/util/string-pad.js:8](https://github.com/snowyu/events-ex.js/blob/fb077063a0ea7231fa89bf74a09be2f52f8401e4/src/util/string-pad.js#L8)
11
+ Defined in: [src/util/string-pad.js:8](https://github.com/snowyu/events-ex.js/blob/f6c44157ffda17957fad5ad2e0aedbb8ec521be7/src/util/string-pad.js#L8)
12
12
 
13
13
  ## Parameters
14
14
 
@@ -8,7 +8,7 @@
8
8
 
9
9
  > **toInt**(`value`): `any`
10
10
 
11
- Defined in: [src/util/to-int.js:2](https://github.com/snowyu/events-ex.js/blob/fb077063a0ea7231fa89bf74a09be2f52f8401e4/src/util/to-int.js#L2)
11
+ Defined in: [src/util/to-int.js:2](https://github.com/snowyu/events-ex.js/blob/f6c44157ffda17957fad5ad2e0aedbb8ec521be7/src/util/to-int.js#L2)
12
12
 
13
13
  ## Parameters
14
14
 
@@ -8,7 +8,7 @@
8
8
 
9
9
  > **validCallable**(`fn`): `any`
10
10
 
11
- Defined in: [src/util/valid-callable.js:1](https://github.com/snowyu/events-ex.js/blob/fb077063a0ea7231fa89bf74a09be2f52f8401e4/src/util/valid-callable.js#L1)
11
+ Defined in: [src/util/valid-callable.js:1](https://github.com/snowyu/events-ex.js/blob/f6c44157ffda17957fad5ad2e0aedbb8ec521be7/src/util/valid-callable.js#L1)
12
12
 
13
13
  ## Parameters
14
14
 
@@ -8,7 +8,7 @@
8
8
 
9
9
  > **validObject**(`value`): `any`
10
10
 
11
- Defined in: [src/util/valid-object.js:3](https://github.com/snowyu/events-ex.js/blob/fb077063a0ea7231fa89bf74a09be2f52f8401e4/src/util/valid-object.js#L3)
11
+ Defined in: [src/util/valid-object.js:3](https://github.com/snowyu/events-ex.js/blob/f6c44157ffda17957fad5ad2e0aedbb8ec521be7/src/util/valid-object.js#L3)
12
12
 
13
13
  ## Parameters
14
14
 
@@ -8,7 +8,7 @@
8
8
 
9
9
  > **wrapEventEmitter**(`o?`, `options?`): `any`
10
10
 
11
- Defined in: [src/wrap-event-emitter.js:37](https://github.com/snowyu/events-ex.js/blob/fb077063a0ea7231fa89bf74a09be2f52f8401e4/src/wrap-event-emitter.js#L37)
11
+ Defined in: [src/wrap-event-emitter.js:37](https://github.com/snowyu/events-ex.js/blob/f6c44157ffda17957fad5ad2e0aedbb8ec521be7/src/wrap-event-emitter.js#L37)
12
12
 
13
13
  Create or inject the eventable instance into the object
14
14
 
@@ -8,4 +8,4 @@
8
8
 
9
9
  > `const` **methods**: `any`
10
10
 
11
- Defined in: [src/wrap-event-emitter.js:7](https://github.com/snowyu/events-ex.js/blob/fb077063a0ea7231fa89bf74a09be2f52f8401e4/src/wrap-event-emitter.js#L7)
11
+ Defined in: [src/wrap-event-emitter.js:7](https://github.com/snowyu/events-ex.js/blob/f6c44157ffda17957fad5ad2e0aedbb8ec521be7/src/wrap-event-emitter.js#L7)
@@ -26,20 +26,28 @@ export function getEventableMethods(aClass: any): {
26
26
  * Adds a listener function to the specified event type.
27
27
  * @param {string|RegExp} type - The event type to listen for.
28
28
  * @param {Function} listener - The listener function to be called when the event is emitted.
29
- * @param {number} [index] - The index at which to insert the listener. If not specified, the listener will be added at the end of the listeners array.
29
+ * @param {number|'first'|'last'} [index] - The index at which to insert the listener.
30
+ * - 'first' or -Infinity: Adds to the "Head" zone. The first listener added as 'first' is placed at the very front.
31
+ * - 'last' or Infinity: Adds to the "Tail" zone. The first listener added as 'last' will always be the very last one to execute.
32
+ * - number: Inserts at the specified index within the "Body" (normal) zone.
33
+ * If not specified, the listener is added to the end of the "Body" zone.
30
34
  * @returns {import('./event-emitter').EventEmitter} The EventEmitter instance to allow chaining.
31
35
  * @throws {TypeError} If the listener is not a function.
32
36
  */
33
- on(type: string | RegExp, listener: Function, index?: number): import("./event-emitter").EventEmitter;
37
+ on(type: string | RegExp, listener: Function, index?: number | "first" | "last"): import("./event-emitter").EventEmitter;
34
38
  /**
35
39
  * Adds a one-time listener function to the specified event type.
36
40
  * @param {string|RegExp} type - The event type to listen for.
37
41
  * @param {Function} listener - The listener function to be called once when the event is emitted.
38
- * @param {number} [index] - The index at which to insert the listener. If not specified, the listener will be added at the end of the listeners array.
42
+ * @param {number|'first'|'last'} [index] - The index at which to insert the listener.
43
+ * - 'first' or -Infinity: Adds to the "Head" zone. The first listener added as 'first' is placed at the very front.
44
+ * - 'last' or Infinity: Adds to the "Tail" zone. The first listener added as 'last' will always be the very last one to execute.
45
+ * - number: Inserts at the specified index within the "Body" (normal) zone.
46
+ * If not specified, the listener is added to the end of the "Body" zone.
39
47
  * @returns {import('./event-emitter').EventEmitter} The EventEmitter instance to allow chaining.
40
48
  * @throws {TypeError} If the listener is not a function.
41
49
  */
42
- once(type: string | RegExp, listener: Function, index?: number): import("./event-emitter").EventEmitter;
50
+ once(type: string | RegExp, listener: Function, index?: number | "first" | "last"): import("./event-emitter").EventEmitter;
43
51
  /**
44
52
  * Emits the specified event type with the given arguments.
45
53
  * @param {...*} args - The event type followed by any number of arguments to be passed to the listener functions.
@@ -68,7 +68,11 @@ function getEventableMethods(aClass) {
68
68
  * Adds a listener function to the specified event type.
69
69
  * @param {string|RegExp} type - The event type to listen for.
70
70
  * @param {Function} listener - The listener function to be called when the event is emitted.
71
- * @param {number} [index] - The index at which to insert the listener. If not specified, the listener will be added at the end of the listeners array.
71
+ * @param {number|'first'|'last'} [index] - The index at which to insert the listener.
72
+ * - 'first' or -Infinity: Adds to the "Head" zone. The first listener added as 'first' is placed at the very front.
73
+ * - 'last' or Infinity: Adds to the "Tail" zone. The first listener added as 'last' will always be the very last one to execute.
74
+ * - number: Inserts at the specified index within the "Body" (normal) zone.
75
+ * If not specified, the listener is added to the end of the "Body" zone.
72
76
  * @returns {import('./event-emitter').EventEmitter} The EventEmitter instance to allow chaining.
73
77
  * @throws {TypeError} If the listener is not a function.
74
78
  */
@@ -91,16 +95,35 @@ function getEventableMethods(aClass) {
91
95
  if (isRegExp(type)) {
92
96
  data = data[_consts.RegExpEventSymbol] || (data[_consts.RegExpEventSymbol] = create(null));
93
97
  }
98
+ const isFirst = index === -Infinity || index === 'first';
99
+ const isLast = index === Infinity || index === 'last';
94
100
  if (!data[type]) {
95
- data[type] = listener;
96
- } else if ((0, _utilEx.isObject)(data[type])) {
97
- if (typeof index === 'number') {
98
- data[type].splice(index, 0, listener);
101
+ if (isFirst || isLast || typeof index === 'number') {
102
+ data[type] = [listener];
103
+ if (isFirst) data[type]._headCount = 1;
104
+ if (isLast) data[type]._tailCount = 1;
99
105
  } else {
100
- data[type].push(listener);
106
+ data[type] = listener;
101
107
  }
102
108
  } else {
103
- data[type] = [data[type], listener];
109
+ if ((0, _utilEx.isFunction)(data[type])) {
110
+ data[type] = [data[type]];
111
+ }
112
+ const listeners = data[type];
113
+ const headCount = listeners._headCount || 0;
114
+ const tailCount = listeners._tailCount || 0;
115
+ if (isFirst) {
116
+ listeners.splice(headCount, 0, listener);
117
+ listeners._headCount = headCount + 1;
118
+ } else if (isLast) {
119
+ listeners.splice(listeners.length - tailCount, 0, listener);
120
+ listeners._tailCount = tailCount + 1;
121
+ } else if (typeof index === 'number' && !isNaN(index)) {
122
+ const pos = Math.min(Math.max(headCount + index, headCount), listeners.length - tailCount);
123
+ listeners.splice(pos, 0, listener);
124
+ } else {
125
+ listeners.splice(listeners.length - tailCount, 0, listener);
126
+ }
104
127
  }
105
128
  // Check for listener leak
106
129
  if ((0, _utilEx.isObject)(data[type]) && !data[type].warned) {
@@ -121,7 +144,11 @@ function getEventableMethods(aClass) {
121
144
  * Adds a one-time listener function to the specified event type.
122
145
  * @param {string|RegExp} type - The event type to listen for.
123
146
  * @param {Function} listener - The listener function to be called once when the event is emitted.
124
- * @param {number} [index] - The index at which to insert the listener. If not specified, the listener will be added at the end of the listeners array.
147
+ * @param {number|'first'|'last'} [index] - The index at which to insert the listener.
148
+ * - 'first' or -Infinity: Adds to the "Head" zone. The first listener added as 'first' is placed at the very front.
149
+ * - 'last' or Infinity: Adds to the "Tail" zone. The first listener added as 'last' will always be the very last one to execute.
150
+ * - number: Inserts at the specified index within the "Body" (normal) zone.
151
+ * If not specified, the listener is added to the end of the "Body" zone.
125
152
  * @returns {import('./event-emitter').EventEmitter} The EventEmitter instance to allow chaining.
126
153
  * @throws {TypeError} If the listener is not a function.
127
154
  */
@@ -295,10 +322,14 @@ function getEventableMethods(aClass) {
295
322
  if (i < 0) {
296
323
  return this;
297
324
  }
325
+ if (listeners._headCount && i < listeners._headCount) {
326
+ listeners._headCount--;
327
+ } else if (listeners._tailCount && i >= listeners.length - listeners._tailCount) {
328
+ listeners._tailCount--;
329
+ }
298
330
  if (listeners.length === 1) {
299
- listeners.length = 0;
300
331
  delete data[type];
301
- } else if (listeners.length === 2) {
332
+ } else if (listeners.length === 2 && !listeners._headCount && !listeners._tailCount) {
302
333
  data[type] = listeners[i ? 0 : 1];
303
334
  listeners.length = 1;
304
335
  } else {
@@ -10,18 +10,28 @@ export class EventEmitter {
10
10
  * Adds a listener function to the specified event type.
11
11
  * @param {string|RegExp} type - The event type to listen for.
12
12
  * @param {Function} listener - The listener function to be called when the event is emitted.
13
+ * @param {number|'first'|'last'} [index] - The index at which to insert the listener.
14
+ * - 'first' or -Infinity: adds to the beginning of the listeners (stay at the front).
15
+ * - 'last' or Infinity: adds to the end of the listeners (stay at the back).
16
+ * - number: inserts at the specified index within the normal listeners zone.
17
+ * If not specified, the listener will be added at the end of the normal listeners.
13
18
  * @returns {EventEmitter} The EventEmitter instance to allow chaining.
14
19
  * @throws {TypeError} If the listener is not a function.
15
20
  */
16
- on(eventName: string|RegExp, listener: ListenerCallbackFunc): EventEmitter;
21
+ on(eventName: string|RegExp, listener: ListenerCallbackFunc, index?: number|'first'|'last'): EventEmitter;
17
22
  /**
18
23
  * Adds a one-time listener function to the specified event type.
19
24
  * @param {string|RegExp} type - The event type to listen for.
20
25
  * @param {Function} listener - The listener function to be called once when the event is emitted.
26
+ * @param {number|'first'|'last'} [index] - The index at which to insert the listener.
27
+ * - 'first' or -Infinity: adds to the beginning of the listeners (stay at the front).
28
+ * - 'last' or Infinity: adds to the end of the listeners (stay at the back).
29
+ * - number: inserts at the specified index within the normal listeners zone.
30
+ * If not specified, the listener will be added at the end of the normal listeners.
21
31
  * @returns {EventEmitter} The EventEmitter instance to allow chaining.
22
32
  * @throws {TypeError} If the listener is not a function.
23
33
  */
24
- once(eventName: string|RegExp, listener: ListenerCallbackFunc): EventEmitter;
34
+ once(eventName: string|RegExp, listener: ListenerCallbackFunc, index?: number|'first'|'last'): EventEmitter;
25
35
  /**
26
36
  * Removes a listener function from the specified event type.
27
37
  * @param {string|RegExp} type - The event type to remove the listener from.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "events-ex",
3
- "version": "2.2.0",
3
+ "version": "2.3.1",
4
4
  "description": "Browser-friendly enhanced events most compatible with standard node.js, it's powerful eventable ability.",
5
5
  "contributors": [
6
6
  {
@@ -62,7 +62,11 @@ export function getEventableMethods(aClass) {
62
62
  * Adds a listener function to the specified event type.
63
63
  * @param {string|RegExp} type - The event type to listen for.
64
64
  * @param {Function} listener - The listener function to be called when the event is emitted.
65
- * @param {number} [index] - The index at which to insert the listener. If not specified, the listener will be added at the end of the listeners array.
65
+ * @param {number|'first'|'last'} [index] - The index at which to insert the listener.
66
+ * - 'first' or -Infinity: Adds to the "Head" zone. The first listener added as 'first' is placed at the very front.
67
+ * - 'last' or Infinity: Adds to the "Tail" zone. The first listener added as 'last' will always be the very last one to execute.
68
+ * - number: Inserts at the specified index within the "Body" (normal) zone.
69
+ * If not specified, the listener is added to the end of the "Body" zone.
66
70
  * @returns {import('./event-emitter').EventEmitter} The EventEmitter instance to allow chaining.
67
71
  * @throws {TypeError} If the listener is not a function.
68
72
  */
@@ -83,16 +87,38 @@ export function getEventableMethods(aClass) {
83
87
  if (isRegExp(type)) {
84
88
  data = data[RegExpEventSymbol] || (data[RegExpEventSymbol] = create(null))
85
89
  }
86
- if (!data[type]) {
87
- data[type] = listener
88
- } else if (isObject(data[type])) {
89
- if (typeof index === 'number') {
90
- data[type].splice(index, 0, listener)
90
+
91
+ const isFirst = index === -Infinity || index === 'first'
92
+ const isLast = index === Infinity || index === 'last'
93
+
94
+ if (!data[type]) {
95
+ if (isFirst || isLast || typeof index === 'number') {
96
+ data[type] = [listener]
97
+ if (isFirst) data[type]._headCount = 1
98
+ if (isLast) data[type]._tailCount = 1
91
99
  } else {
92
- data[type].push(listener)
100
+ data[type] = listener
93
101
  }
94
102
  } else {
95
- data[type] = [data[type], listener]
103
+ if (isFunction(data[type])) {
104
+ data[type] = [data[type]]
105
+ }
106
+ const listeners = data[type]
107
+ const headCount = listeners._headCount || 0
108
+ const tailCount = listeners._tailCount || 0
109
+
110
+ if (isFirst) {
111
+ listeners.splice(headCount, 0, listener)
112
+ listeners._headCount = headCount + 1
113
+ } else if (isLast) {
114
+ listeners.splice(listeners.length - tailCount, 0, listener)
115
+ listeners._tailCount = tailCount + 1
116
+ } else if (typeof index === 'number' && !isNaN(index)) {
117
+ const pos = Math.min(Math.max(headCount + index, headCount), listeners.length - tailCount)
118
+ listeners.splice(pos, 0, listener)
119
+ } else {
120
+ listeners.splice(listeners.length - tailCount, 0, listener)
121
+ }
96
122
  }
97
123
  // Check for listener leak
98
124
  if (isObject(data[type]) && !data[type].warned) {
@@ -119,7 +145,11 @@ export function getEventableMethods(aClass) {
119
145
  * Adds a one-time listener function to the specified event type.
120
146
  * @param {string|RegExp} type - The event type to listen for.
121
147
  * @param {Function} listener - The listener function to be called once when the event is emitted.
122
- * @param {number} [index] - The index at which to insert the listener. If not specified, the listener will be added at the end of the listeners array.
148
+ * @param {number|'first'|'last'} [index] - The index at which to insert the listener.
149
+ * - 'first' or -Infinity: Adds to the "Head" zone. The first listener added as 'first' is placed at the very front.
150
+ * - 'last' or Infinity: Adds to the "Tail" zone. The first listener added as 'last' will always be the very last one to execute.
151
+ * - number: Inserts at the specified index within the "Body" (normal) zone.
152
+ * If not specified, the listener is added to the end of the "Body" zone.
123
153
  * @returns {import('./event-emitter').EventEmitter} The EventEmitter instance to allow chaining.
124
154
  * @throws {TypeError} If the listener is not a function.
125
155
  */
@@ -275,10 +305,16 @@ export function getEventableMethods(aClass) {
275
305
  if (candidate === listener || candidate.listener === listener) {break}
276
306
  }
277
307
  if (i < 0) {return this}
308
+
309
+ if (listeners._headCount && i < listeners._headCount) {
310
+ listeners._headCount--
311
+ } else if (listeners._tailCount && i >= listeners.length - listeners._tailCount) {
312
+ listeners._tailCount--
313
+ }
314
+
278
315
  if (listeners.length === 1) {
279
- listeners.length = 0
280
316
  delete data[type]
281
- } else if (listeners.length === 2) {
317
+ } else if (listeners.length === 2 && !listeners._headCount && !listeners._tailCount) {
282
318
  data[type] = listeners[(i ? 0 : 1)]
283
319
  listeners.length = 1
284
320
  } else {
@@ -10,18 +10,28 @@ export class EventEmitter {
10
10
  * Adds a listener function to the specified event type.
11
11
  * @param {string|RegExp} type - The event type to listen for.
12
12
  * @param {Function} listener - The listener function to be called when the event is emitted.
13
+ * @param {number|'first'|'last'} [index] - The index at which to insert the listener.
14
+ * - 'first' or -Infinity: adds to the beginning of the listeners (stay at the front).
15
+ * - 'last' or Infinity: adds to the end of the listeners (stay at the back).
16
+ * - number: inserts at the specified index within the normal listeners zone.
17
+ * If not specified, the listener will be added at the end of the normal listeners.
13
18
  * @returns {EventEmitter} The EventEmitter instance to allow chaining.
14
19
  * @throws {TypeError} If the listener is not a function.
15
20
  */
16
- on(eventName: string|RegExp, listener: ListenerCallbackFunc): EventEmitter;
21
+ on(eventName: string|RegExp, listener: ListenerCallbackFunc, index?: number|'first'|'last'): EventEmitter;
17
22
  /**
18
23
  * Adds a one-time listener function to the specified event type.
19
24
  * @param {string|RegExp} type - The event type to listen for.
20
25
  * @param {Function} listener - The listener function to be called once when the event is emitted.
26
+ * @param {number|'first'|'last'} [index] - The index at which to insert the listener.
27
+ * - 'first' or -Infinity: adds to the beginning of the listeners (stay at the front).
28
+ * - 'last' or Infinity: adds to the end of the listeners (stay at the back).
29
+ * - number: inserts at the specified index within the normal listeners zone.
30
+ * If not specified, the listener will be added at the end of the normal listeners.
21
31
  * @returns {EventEmitter} The EventEmitter instance to allow chaining.
22
32
  * @throws {TypeError} If the listener is not a function.
23
33
  */
24
- once(eventName: string|RegExp, listener: ListenerCallbackFunc): EventEmitter;
34
+ once(eventName: string|RegExp, listener: ListenerCallbackFunc, index?: number|'first'|'last'): EventEmitter;
25
35
  /**
26
36
  * Removes a listener function from the specified event type.
27
37
  * @param {string|RegExp} type - The event type to remove the listener from.
package/.npmrcx DELETED
@@ -1,5 +0,0 @@
1
- //registry.npmjs.org/:_authToken=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 // riceball
2
- registry=https://registry.npmjs.org/
3
- # 只支持http代理,所以需要 yarn global add http-proxy-to-socks, 将socks代理转为http代理
4
- # hpts -s localhost:1081 -p 8880
5
- # https-proxy=http://localhost:8880