zephyr-events 1.1.2 â 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -0
- package/README.md +215 -108
- package/dist/index.d.ts +6 -0
- package/dist/index.js +131 -30
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/zephyr-events.js +149 -1
- package/dist/zephyr-events.mjs +147 -1
- package/dist/zephyr-events.umd.js +155 -6
- package/package.json +15 -9
package/LICENSE
CHANGED
package/README.md
CHANGED
|
@@ -1,211 +1,318 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Zephyr Events â Tiny TypeScript Event Emitter
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A lightweight, type-safe event emitter for TypeScript and JavaScript. Zero dependencies, under 2KB, with built-in race-condition safety that larger alternatives like EventEmitter3 and Node.js EventEmitter lack.
|
|
4
4
|
|
|
5
5
|
[](https://www.npmjs.com/package/zephyr-events)
|
|
6
|
-
[](https://www.npmjs.com/package/zephyr-events)
|
|
7
|
+
[](https://bundlephobia.com/package/zephyr-events)
|
|
7
8
|
[](https://www.typescriptlang.org/)
|
|
9
|
+
[](https://github.com/ebogdum/zephyr-events/blob/main/LICENSE)
|
|
8
10
|
|
|
9
|
-
|
|
11
|
+
## Why Zephyr Events?
|
|
10
12
|
|
|
11
|
-
|
|
13
|
+
Most event emitter libraries break when handlers modify the listener list during emission â a handler that calls `off()` on itself can skip the next handler, or adding a new listener mid-emit can cause infinite loops. Zephyr Events solves this with snapshot-based iteration, making it safe for real-world use in UI frameworks, state machines, and plugin systems.
|
|
12
14
|
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
-
|
|
16
|
-
-
|
|
17
|
-
-
|
|
18
|
-
-
|
|
15
|
+
- **Under 2KB** â 1.9KB ESM, zero dependencies, tree-shakeable
|
|
16
|
+
- **Race-condition safe** â handlers can subscribe, unsubscribe, or clear during emit without side effects
|
|
17
|
+
- **Fast mode** â `zephyrEventsFast` drops snapshot safety for up to 82% faster emit
|
|
18
|
+
- **Full TypeScript support** â generic event maps, strict handler signatures, IDE autocompletion
|
|
19
|
+
- **Universal builds** â ESM, CommonJS, and UMD for browsers, Node.js, and bundlers
|
|
20
|
+
- **Wildcard listeners** â subscribe to all events with `*`
|
|
21
|
+
- **Shared state** â pass a handler map between emitters for cross-module communication
|
|
19
22
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
## ðĨ Installation
|
|
23
|
+
## Installation
|
|
23
24
|
|
|
24
25
|
```bash
|
|
25
26
|
npm install zephyr-events
|
|
26
27
|
```
|
|
27
28
|
|
|
28
|
-
|
|
29
|
+
```bash
|
|
30
|
+
yarn add zephyr-events
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
pnpm add zephyr-events
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Quick Start
|
|
29
38
|
|
|
30
|
-
|
|
39
|
+
### TypeScript Event Emitter
|
|
31
40
|
|
|
32
41
|
```typescript
|
|
33
42
|
import zephyrEvents from 'zephyr-events';
|
|
34
43
|
|
|
35
|
-
//
|
|
36
|
-
type
|
|
37
|
-
user: { id: number; name: string }
|
|
38
|
-
|
|
44
|
+
// Define your event types
|
|
45
|
+
type AppEvents = {
|
|
46
|
+
'user:login': { id: number; name: string }
|
|
47
|
+
'user:logout': { id: number }
|
|
48
|
+
'error': Error
|
|
39
49
|
}
|
|
40
50
|
|
|
41
|
-
const emitter = zephyrEvents<
|
|
51
|
+
const emitter = zephyrEvents<AppEvents>();
|
|
42
52
|
|
|
43
|
-
// Subscribe
|
|
44
|
-
const unsubscribe = emitter.on('user', (user) => {
|
|
45
|
-
console.log(`
|
|
53
|
+
// Subscribe â returns an unsubscribe function for easy cleanup
|
|
54
|
+
const unsubscribe = emitter.on('user:login', (user) => {
|
|
55
|
+
console.log(`Welcome, ${user.name}`);
|
|
46
56
|
});
|
|
47
57
|
|
|
48
|
-
// Emit
|
|
49
|
-
emitter.emit('user', { id: 1, name: 'Alice' });
|
|
58
|
+
// Emit with full type checking
|
|
59
|
+
emitter.emit('user:login', { id: 1, name: 'Alice' });
|
|
50
60
|
|
|
51
|
-
//
|
|
61
|
+
// Clean up when done
|
|
52
62
|
unsubscribe();
|
|
53
63
|
```
|
|
54
64
|
|
|
55
|
-
|
|
65
|
+
### Fast Mode
|
|
56
66
|
|
|
57
|
-
|
|
67
|
+
When handlers never modify the listener list during emit, use `zephyrEventsFast` for maximum throughput:
|
|
58
68
|
|
|
59
|
-
|
|
69
|
+
```typescript
|
|
70
|
+
import { zephyrEventsFast } from 'zephyr-events';
|
|
71
|
+
|
|
72
|
+
const emitter = zephyrEventsFast<AppEvents>();
|
|
73
|
+
// Same API â on(), off(), emit(), all
|
|
74
|
+
```
|
|
60
75
|
|
|
61
|
-
|
|
76
|
+
### JavaScript Event Emitter
|
|
77
|
+
|
|
78
|
+
```javascript
|
|
79
|
+
const zephyrEvents = require('zephyr-events');
|
|
80
|
+
const { zephyrEventsFast } = require('zephyr-events');
|
|
81
|
+
|
|
82
|
+
const emitter = zephyrEvents(); // safe (snapshot)
|
|
83
|
+
const fast = zephyrEventsFast(); // fast (no snapshot)
|
|
84
|
+
|
|
85
|
+
emitter.on('message', (data) => {
|
|
86
|
+
console.log('Received:', data);
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
emitter.emit('message', { text: 'Hello' });
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## API Reference
|
|
93
|
+
|
|
94
|
+
### `zephyrEvents<Events>(all?)`
|
|
95
|
+
|
|
96
|
+
Creates a new typed event emitter with snapshot-safe emission. Optionally accepts an existing handler map to share event state between emitters.
|
|
62
97
|
|
|
63
98
|
```typescript
|
|
64
99
|
const emitter = zephyrEvents<{
|
|
65
100
|
message: string
|
|
66
101
|
data: { value: number }
|
|
67
102
|
}>();
|
|
103
|
+
|
|
104
|
+
// Share handlers between emitters
|
|
105
|
+
const shared = new Map();
|
|
106
|
+
const emitterA = zephyrEvents(shared);
|
|
107
|
+
const emitterB = zephyrEvents(shared);
|
|
68
108
|
```
|
|
69
109
|
|
|
70
|
-
### `
|
|
110
|
+
### `zephyrEventsFast<Events>(all?)`
|
|
71
111
|
|
|
72
|
-
|
|
112
|
+
Creates a non-snapshot event emitter. Same API as `zephyrEvents`, but `emit()` iterates the live handler array instead of a copy. Up to 82% faster for single-handler emit. Use when handlers do not add/remove listeners during emission.
|
|
73
113
|
|
|
74
114
|
```typescript
|
|
115
|
+
import { zephyrEventsFast } from 'zephyr-events';
|
|
116
|
+
|
|
117
|
+
const emitter = zephyrEventsFast<{ tick: number }>();
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### `emitter.on(type, handler): Unsubscribe`
|
|
121
|
+
|
|
122
|
+
Registers an event handler. Returns an unsubscribe function for automatic cleanup â no need to keep a reference to the handler.
|
|
123
|
+
|
|
124
|
+
```typescript
|
|
125
|
+
// Type-safe subscription
|
|
75
126
|
const unsub = emitter.on('message', (msg) => {
|
|
76
127
|
console.log(msg);
|
|
77
128
|
});
|
|
78
129
|
|
|
79
|
-
// Wildcard listener
|
|
130
|
+
// Wildcard listener â receives every event
|
|
80
131
|
emitter.on('*', (type, event) => {
|
|
81
|
-
console.log(`
|
|
132
|
+
console.log(`[${String(type)}]`, event);
|
|
82
133
|
});
|
|
134
|
+
|
|
135
|
+
// Unsubscribe when no longer needed
|
|
136
|
+
unsub();
|
|
83
137
|
```
|
|
84
138
|
|
|
85
139
|
### `emitter.off(type, handler?)`
|
|
86
140
|
|
|
87
|
-
|
|
141
|
+
Removes a specific handler, or all handlers for an event type.
|
|
88
142
|
|
|
89
143
|
```typescript
|
|
90
|
-
// Remove specific handler
|
|
91
|
-
emitter.off('message',
|
|
144
|
+
// Remove a specific handler
|
|
145
|
+
emitter.off('message', myHandler);
|
|
92
146
|
|
|
93
|
-
// Remove all handlers for type
|
|
147
|
+
// Remove all handlers for an event type
|
|
94
148
|
emitter.off('message');
|
|
95
149
|
```
|
|
96
150
|
|
|
97
151
|
### `emitter.emit(type, event)`
|
|
98
152
|
|
|
99
|
-
|
|
153
|
+
Emits an event to all registered handlers. Handlers run synchronously from a snapshot, so the listener list can be safely modified during emission.
|
|
100
154
|
|
|
101
155
|
```typescript
|
|
102
156
|
emitter.emit('message', 'Hello World!');
|
|
103
157
|
emitter.emit('data', { value: 42 });
|
|
104
158
|
```
|
|
105
159
|
|
|
106
|
-
|
|
160
|
+
### `emitter.all`
|
|
161
|
+
|
|
162
|
+
The underlying `Map<EventType, Handler[]>` that stores all registered handlers. Can be inspected, serialized, or shared between emitter instances.
|
|
107
163
|
|
|
108
|
-
##
|
|
164
|
+
## Use Cases
|
|
109
165
|
|
|
110
|
-
###
|
|
166
|
+
### Event Bus for React Components
|
|
167
|
+
|
|
168
|
+
```typescript
|
|
169
|
+
import zephyrEvents from 'zephyr-events';
|
|
111
170
|
|
|
112
|
-
|
|
171
|
+
type UIEvents = {
|
|
172
|
+
'modal:open': { id: string }
|
|
173
|
+
'modal:close': { id: string }
|
|
174
|
+
'toast': { message: string; severity: 'info' | 'error' }
|
|
175
|
+
}
|
|
113
176
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
- **ES2023 optimizations**: Native optional chaining and nullish coalescing
|
|
177
|
+
// Create a shared event bus
|
|
178
|
+
export const uiBus = zephyrEvents<UIEvents>();
|
|
117
179
|
|
|
118
|
-
|
|
180
|
+
// In a React component â clean up on unmount
|
|
181
|
+
useEffect(() => {
|
|
182
|
+
const unsub = uiBus.on('toast', (toast) => {
|
|
183
|
+
showToast(toast.message, toast.severity);
|
|
184
|
+
});
|
|
185
|
+
return unsub;
|
|
186
|
+
}, []);
|
|
187
|
+
```
|
|
119
188
|
|
|
120
|
-
|
|
189
|
+
### Pub/Sub in Node.js Microservices
|
|
121
190
|
|
|
122
191
|
```typescript
|
|
123
|
-
|
|
124
|
-
|
|
192
|
+
import zephyrEvents from 'zephyr-events';
|
|
193
|
+
|
|
194
|
+
type ServiceEvents = {
|
|
195
|
+
'order:created': { orderId: string; total: number }
|
|
196
|
+
'order:shipped': { orderId: string; trackingId: string }
|
|
197
|
+
'inventory:low': { sku: string; remaining: number }
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
const events = zephyrEvents<ServiceEvents>();
|
|
201
|
+
|
|
202
|
+
// Multiple subscribers
|
|
203
|
+
events.on('order:created', sendConfirmationEmail);
|
|
204
|
+
events.on('order:created', updateAnalytics);
|
|
205
|
+
events.on('inventory:low', notifyWarehouse);
|
|
206
|
+
|
|
207
|
+
// Audit logging with wildcard
|
|
208
|
+
events.on('*', (type, data) => {
|
|
209
|
+
logger.info({ event: type, payload: data });
|
|
125
210
|
});
|
|
126
211
|
```
|
|
127
212
|
|
|
128
|
-
###
|
|
213
|
+
### Plugin System
|
|
214
|
+
|
|
215
|
+
```typescript
|
|
216
|
+
import zephyrEvents from 'zephyr-events';
|
|
129
217
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
218
|
+
type PluginEvents = {
|
|
219
|
+
'init': { config: Record<string, unknown> }
|
|
220
|
+
'transform': { input: string }
|
|
221
|
+
'destroy': undefined
|
|
222
|
+
}
|
|
133
223
|
|
|
134
|
-
|
|
224
|
+
function createPluginHost() {
|
|
225
|
+
const emitter = zephyrEvents<PluginEvents>();
|
|
135
226
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
227
|
+
return {
|
|
228
|
+
register(plugin: (on: typeof emitter.on) => void) {
|
|
229
|
+
plugin(emitter.on.bind(emitter));
|
|
230
|
+
},
|
|
231
|
+
emit: emitter.emit.bind(emitter),
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
```
|
|
139
235
|
|
|
140
|
-
|
|
236
|
+
## Race-Condition Safety
|
|
141
237
|
|
|
142
|
-
|
|
238
|
+
Unlike most event emitters, Zephyr Events handles listener modification during emission safely. Each `emit()` call iterates over a snapshot of the handler list, so adding or removing handlers mid-emit never causes skipped handlers or infinite loops:
|
|
143
239
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
| Bundle Size | 905B | 200B | 7KB |
|
|
147
|
-
| TypeScript | â
Native | â
| â
|
|
|
148
|
-
| Race-Safe | â
| â | â |
|
|
149
|
-
| ES2023 | â
| â | â |
|
|
150
|
-
| Performance | 33M ops/s | 15M ops/s | 10M ops/s |
|
|
240
|
+
```typescript
|
|
241
|
+
const emitter = zephyrEvents();
|
|
151
242
|
|
|
152
|
-
|
|
243
|
+
// Safe: handler removes itself during emit
|
|
244
|
+
emitter.on('data', function once(data) {
|
|
245
|
+
emitter.off('data', once);
|
|
246
|
+
process(data); // next handler still fires
|
|
247
|
+
});
|
|
153
248
|
|
|
154
|
-
|
|
249
|
+
// Safe: handler adds new listeners during emit
|
|
250
|
+
emitter.on('init', () => {
|
|
251
|
+
emitter.on('init', () => {
|
|
252
|
+
// this will NOT fire during the current emit cycle
|
|
253
|
+
});
|
|
254
|
+
});
|
|
255
|
+
```
|
|
155
256
|
|
|
156
|
-
##
|
|
257
|
+
## Comparison with Other Event Emitters
|
|
157
258
|
|
|
158
|
-
|
|
259
|
+
| Feature | Zephyr Events | mitt | EventEmitter3 | Node.js EventEmitter |
|
|
260
|
+
|---------|:---:|:---:|:---:|:---:|
|
|
261
|
+
| Bundle size | ~2KB | ~200B | ~7KB | Built-in |
|
|
262
|
+
| TypeScript types | Native | Native | Bundled | `@types/node` |
|
|
263
|
+
| Race-condition safe | Yes | No | No | No |
|
|
264
|
+
| Fast (no-snapshot) mode | Yes | No | No | No |
|
|
265
|
+
| Wildcard listeners | Yes | Yes | No | No |
|
|
266
|
+
| Unsubscribe function | Yes | No | No | No |
|
|
267
|
+
| Shared handler maps | Yes | Yes | No | No |
|
|
268
|
+
| Zero dependencies | Yes | Yes | Yes | N/A |
|
|
269
|
+
| Tree-shakeable ESM | Yes | Yes | Yes | No |
|
|
159
270
|
|
|
160
|
-
|
|
271
|
+
## Performance Benchmarks
|
|
161
272
|
|
|
162
|
-
|
|
163
|
-
|-----------|------------|-------------|
|
|
164
|
-
| **Emitter Creation** | **10.54M** | Creating new emitter instances |
|
|
165
|
-
| **Single Handler Emit** | **33.69M** | Emitting to one event handler |
|
|
166
|
-
| **Wildcard Emit** | **26.12M** | Emitting to wildcard listeners |
|
|
167
|
-
| **10 Handlers Emit** | **9.32M** | Emitting to 10 concurrent handlers |
|
|
168
|
-
| **100 Handlers Emit** | **1.57M** | Emitting to 100 concurrent handlers |
|
|
169
|
-
| **Mixed Operations** | **7.17M** | Realistic usage: on/emit/off cycle |
|
|
273
|
+
Tested on Apple Silicon M-series (ARM64), Node.js v25.2.1. Median of 3 runs in isolated V8 processes. Run `node benchmark-compare.js` to reproduce.
|
|
170
274
|
|
|
171
|
-
###
|
|
275
|
+
### Safe vs Fast
|
|
172
276
|
|
|
173
|
-
| Operation |
|
|
174
|
-
|
|
175
|
-
| **
|
|
176
|
-
| **
|
|
177
|
-
| **
|
|
178
|
-
| **
|
|
277
|
+
| Operation | Safe (snapshot) | Fast (no snapshot) | Delta |
|
|
278
|
+
|-----------|----------------:|-------------------:|------:|
|
|
279
|
+
| **Emit (1 handler)** | 49.4M ops/s | 89.9M ops/s | **+82%** |
|
|
280
|
+
| **Emit (10 handlers)** | 14.0M ops/s | 16.9M ops/s | **+21%** |
|
|
281
|
+
| **Emit (100 handlers)** | 1.9M ops/s | 2.1M ops/s | **+12%** |
|
|
282
|
+
| **Wildcard emit** | 38.4M ops/s | 62.7M ops/s | **+63%** |
|
|
283
|
+
| **Emit (no wildcards)** | 36.3M ops/s | 57.5M ops/s | **+59%** |
|
|
284
|
+
| **On + unsub cycle** | 11.0M ops/s | 11.0M ops/s | 0% |
|
|
285
|
+
| **Off (specific handler)** | 11.8M ops/s | 11.7M ops/s | 0% |
|
|
286
|
+
| **Mixed (on/emit/unsub)** | 8.6M ops/s | 9.3M ops/s | **+8%** |
|
|
179
287
|
|
|
180
|
-
|
|
288
|
+
All benchmarks use proper setup/run separation with warmup passes. No-op handlers measure emitter overhead only â real-world throughput depends on handler complexity.
|
|
181
289
|
|
|
182
|
-
|
|
183
|
-
- **⥠Instant cleanup**: Handler removal at **194.17M operations/second**
|
|
184
|
-
- **ð Scales efficiently**: Maintains high performance with multiple handlers
|
|
185
|
-
- **ðĄïļ Race-condition safe**: Minimal overhead for safety guarantees
|
|
186
|
-
- **ðŊ Real-world optimized**: **7.17M ops/sec** for typical usage patterns
|
|
290
|
+
## Bundle Formats
|
|
187
291
|
|
|
188
|
-
|
|
292
|
+
Zephyr Events ships three bundle formats for maximum compatibility:
|
|
189
293
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
-
|
|
193
|
-
|
|
294
|
+
| Format | File | Use case |
|
|
295
|
+
|--------|------|----------|
|
|
296
|
+
| ESM | `dist/zephyr-events.mjs` | Modern bundlers (Vite, Rollup, webpack 5+) |
|
|
297
|
+
| CommonJS | `dist/zephyr-events.js` | Node.js `require()`, older bundlers |
|
|
298
|
+
| UMD | `dist/zephyr-events.umd.js` | Script tags, AMD loaders, legacy environments |
|
|
194
299
|
|
|
195
|
-
|
|
300
|
+
## Requirements
|
|
196
301
|
|
|
197
|
-
|
|
302
|
+
- **Node.js** >= 18
|
|
303
|
+
- **TypeScript** >= 4.7 (for type features; runtime has no TS dependency)
|
|
304
|
+
- Works in all modern browsers (ES2020+ support)
|
|
198
305
|
|
|
199
|
-
|
|
306
|
+
## Contributing
|
|
200
307
|
|
|
201
|
-
|
|
308
|
+
Contributions are welcome. Please read [CONTRIBUTING.md](CONTRIBUTING.md) before opening a pull request.
|
|
202
309
|
|
|
203
|
-
##
|
|
310
|
+
## Acknowledgments
|
|
204
311
|
|
|
205
|
-
|
|
312
|
+
Zephyr Events is a modernization of [mitt](https://github.com/developit/mitt) by [Jason Miller](https://github.com/developit). Built on the same simple API with added type safety, race-condition handling, and universal module support.
|
|
206
313
|
|
|
207
|
-
##
|
|
314
|
+
## License
|
|
208
315
|
|
|
209
|
-
MIT
|
|
316
|
+
[MIT](LICENSE)
|
|
210
317
|
|
|
211
|
-
Original mitt: MIT
|
|
318
|
+
Original mitt: MIT (c) [Jason Miller](https://github.com/developit)
|
package/dist/index.d.ts
CHANGED
|
@@ -15,3 +15,9 @@ export interface Emitter<Events extends Record<EventType, unknown>> {
|
|
|
15
15
|
emit<Key extends keyof Events>(type: undefined extends Events[Key] ? Key : never): void;
|
|
16
16
|
}
|
|
17
17
|
export default function zephyrEvents<Events extends Record<EventType, unknown>>(all?: EventHandlerMap<Events>): Emitter<Events>;
|
|
18
|
+
/**
|
|
19
|
+
* Creates a fast, non-snapshot event emitter. Handlers that modify the
|
|
20
|
+
* listener list during emit may cause skipped or double-fired handlers.
|
|
21
|
+
* Use when maximum throughput matters and handlers do not mutate listeners.
|
|
22
|
+
*/
|
|
23
|
+
export declare function zephyrEventsFast<Events extends Record<EventType, unknown>>(all?: EventHandlerMap<Events>): Emitter<Events>;
|
package/dist/index.js
CHANGED
|
@@ -1,53 +1,154 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.default = zephyrEvents;
|
|
4
|
+
exports.zephyrEventsFast = zephyrEventsFast;
|
|
4
5
|
function zephyrEvents(all) {
|
|
5
6
|
all ??= new Map();
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
7
|
+
let hasWildcards = false;
|
|
8
|
+
let emitting = 0;
|
|
9
|
+
return {
|
|
10
|
+
all,
|
|
11
|
+
on(type, handler) {
|
|
12
|
+
let handlers = all.get(type);
|
|
13
|
+
if (!handlers) {
|
|
14
|
+
handlers = [];
|
|
15
|
+
all.set(type, handlers);
|
|
16
|
+
}
|
|
17
|
+
handlers.push(handler);
|
|
18
|
+
if ('*' === type)
|
|
19
|
+
hasWildcards = true;
|
|
20
|
+
return () => {
|
|
21
|
+
const current = all.get(type);
|
|
22
|
+
if (current) {
|
|
23
|
+
const idx = current.indexOf(handler);
|
|
24
|
+
if (-1 < idx) {
|
|
25
|
+
current.splice(idx, 1);
|
|
26
|
+
}
|
|
27
|
+
if (0 === current.length) {
|
|
28
|
+
all.delete(type);
|
|
29
|
+
if ('*' === type)
|
|
30
|
+
hasWildcards = false;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
},
|
|
35
|
+
off(type, handler) {
|
|
36
|
+
const handlers = all.get(type);
|
|
37
|
+
if (!handlers)
|
|
38
|
+
return;
|
|
39
|
+
if (handler) {
|
|
40
|
+
const idx = handlers.indexOf(handler);
|
|
41
|
+
if (-1 < idx) {
|
|
42
|
+
handlers.splice(idx, 1);
|
|
43
|
+
}
|
|
44
|
+
if (0 === handlers.length) {
|
|
45
|
+
all.delete(type);
|
|
46
|
+
if ('*' === type)
|
|
47
|
+
hasWildcards = false;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
all.delete(type);
|
|
52
|
+
if ('*' === type)
|
|
53
|
+
hasWildcards = false;
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
emit(type, evt) {
|
|
57
|
+
const handlers = all.get(type);
|
|
58
|
+
if (handlers) {
|
|
59
|
+
emitting++;
|
|
60
|
+
const snapshot = handlers.slice();
|
|
61
|
+
const len = snapshot.length;
|
|
62
|
+
for (let i = 0; i < len; i++) {
|
|
63
|
+
snapshot[i](evt);
|
|
64
|
+
}
|
|
65
|
+
emitting--;
|
|
66
|
+
}
|
|
67
|
+
if (hasWildcards && '*' !== type) {
|
|
68
|
+
const wildcards = all.get('*');
|
|
69
|
+
if (wildcards) {
|
|
70
|
+
emitting++;
|
|
71
|
+
const snapshot = wildcards.slice();
|
|
72
|
+
const len = snapshot.length;
|
|
73
|
+
for (let i = 0; i < len; i++) {
|
|
74
|
+
snapshot[i](type, evt);
|
|
75
|
+
}
|
|
76
|
+
emitting--;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
20
79
|
}
|
|
21
80
|
};
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Creates a fast, non-snapshot event emitter. Handlers that modify the
|
|
84
|
+
* listener list during emit may cause skipped or double-fired handlers.
|
|
85
|
+
* Use when maximum throughput matters and handlers do not mutate listeners.
|
|
86
|
+
*/
|
|
87
|
+
function zephyrEventsFast(all) {
|
|
88
|
+
all ??= new Map();
|
|
89
|
+
let hasWildcards = false;
|
|
22
90
|
return {
|
|
23
91
|
all,
|
|
24
92
|
on(type, handler) {
|
|
25
|
-
|
|
26
|
-
handlers
|
|
27
|
-
|
|
93
|
+
let handlers = all.get(type);
|
|
94
|
+
if (!handlers) {
|
|
95
|
+
handlers = [];
|
|
96
|
+
all.set(type, handlers);
|
|
97
|
+
}
|
|
98
|
+
handlers.push(handler);
|
|
99
|
+
if ('*' === type)
|
|
100
|
+
hasWildcards = true;
|
|
28
101
|
return () => {
|
|
29
|
-
|
|
30
|
-
|
|
102
|
+
const current = all.get(type);
|
|
103
|
+
if (current) {
|
|
104
|
+
const idx = current.indexOf(handler);
|
|
105
|
+
if (-1 < idx) {
|
|
106
|
+
current.splice(idx, 1);
|
|
107
|
+
}
|
|
108
|
+
if (0 === current.length) {
|
|
109
|
+
all.delete(type);
|
|
110
|
+
if ('*' === type)
|
|
111
|
+
hasWildcards = false;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
31
114
|
};
|
|
32
115
|
},
|
|
33
116
|
off(type, handler) {
|
|
34
|
-
const handlers =
|
|
117
|
+
const handlers = all.get(type);
|
|
35
118
|
if (!handlers)
|
|
36
119
|
return;
|
|
37
|
-
|
|
38
|
-
|
|
120
|
+
if (handler) {
|
|
121
|
+
const idx = handlers.indexOf(handler);
|
|
122
|
+
if (-1 < idx) {
|
|
123
|
+
handlers.splice(idx, 1);
|
|
124
|
+
}
|
|
125
|
+
if (0 === handlers.length) {
|
|
126
|
+
all.delete(type);
|
|
127
|
+
if ('*' === type)
|
|
128
|
+
hasWildcards = false;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
all.delete(type);
|
|
133
|
+
if ('*' === type)
|
|
134
|
+
hasWildcards = false;
|
|
135
|
+
}
|
|
39
136
|
},
|
|
40
137
|
emit(type, evt) {
|
|
41
|
-
const handlers =
|
|
42
|
-
if (handlers
|
|
43
|
-
|
|
44
|
-
|
|
138
|
+
const handlers = all.get(type);
|
|
139
|
+
if (handlers) {
|
|
140
|
+
const len = handlers.length;
|
|
141
|
+
for (let i = 0; i < len; i++) {
|
|
142
|
+
handlers[i](evt);
|
|
45
143
|
}
|
|
46
144
|
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
145
|
+
if (hasWildcards && '*' !== type) {
|
|
146
|
+
const wildcards = all.get('*');
|
|
147
|
+
if (wildcards) {
|
|
148
|
+
const len = wildcards.length;
|
|
149
|
+
for (let i = 0; i < len; i++) {
|
|
150
|
+
wildcards[i](type, evt);
|
|
151
|
+
}
|
|
51
152
|
}
|
|
52
153
|
}
|
|
53
154
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"root":["../src/index.ts"],"version":"5.9.
|
|
1
|
+
{"root":["../src/index.ts"],"version":"5.9.3"}
|
package/dist/zephyr-events.js
CHANGED
|
@@ -1 +1,149 @@
|
|
|
1
|
-
"use strict";
|
|
1
|
+
"use strict";
|
|
2
|
+
module.exports = function zephyrEvents(all) {
|
|
3
|
+
all ??= new Map();
|
|
4
|
+
let hasWildcards = false;
|
|
5
|
+
let emitting = 0;
|
|
6
|
+
return {
|
|
7
|
+
all,
|
|
8
|
+
on(type, handler) {
|
|
9
|
+
let handlers = all.get(type);
|
|
10
|
+
if (!handlers) {
|
|
11
|
+
handlers = [];
|
|
12
|
+
all.set(type, handlers);
|
|
13
|
+
}
|
|
14
|
+
handlers.push(handler);
|
|
15
|
+
if ('*' === type)
|
|
16
|
+
hasWildcards = true;
|
|
17
|
+
return () => {
|
|
18
|
+
const current = all.get(type);
|
|
19
|
+
if (current) {
|
|
20
|
+
const idx = current.indexOf(handler);
|
|
21
|
+
if (-1 < idx) {
|
|
22
|
+
current.splice(idx, 1);
|
|
23
|
+
}
|
|
24
|
+
if (0 === current.length) {
|
|
25
|
+
all.delete(type);
|
|
26
|
+
if ('*' === type)
|
|
27
|
+
hasWildcards = false;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
},
|
|
32
|
+
off(type, handler) {
|
|
33
|
+
const handlers = all.get(type);
|
|
34
|
+
if (!handlers)
|
|
35
|
+
return;
|
|
36
|
+
if (handler) {
|
|
37
|
+
const idx = handlers.indexOf(handler);
|
|
38
|
+
if (-1 < idx) {
|
|
39
|
+
handlers.splice(idx, 1);
|
|
40
|
+
}
|
|
41
|
+
if (0 === handlers.length) {
|
|
42
|
+
all.delete(type);
|
|
43
|
+
if ('*' === type)
|
|
44
|
+
hasWildcards = false;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
all.delete(type);
|
|
49
|
+
if ('*' === type)
|
|
50
|
+
hasWildcards = false;
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
emit(type, evt) {
|
|
54
|
+
const handlers = all.get(type);
|
|
55
|
+
if (handlers) {
|
|
56
|
+
emitting++;
|
|
57
|
+
const snapshot = handlers.slice();
|
|
58
|
+
const len = snapshot.length;
|
|
59
|
+
for (let i = 0; i < len; i++) {
|
|
60
|
+
snapshot[i](evt);
|
|
61
|
+
}
|
|
62
|
+
emitting--;
|
|
63
|
+
}
|
|
64
|
+
if (hasWildcards && '*' !== type) {
|
|
65
|
+
const wildcards = all.get('*');
|
|
66
|
+
if (wildcards) {
|
|
67
|
+
emitting++;
|
|
68
|
+
const snapshot = wildcards.slice();
|
|
69
|
+
const len = snapshot.length;
|
|
70
|
+
for (let i = 0; i < len; i++) {
|
|
71
|
+
snapshot[i](type, evt);
|
|
72
|
+
}
|
|
73
|
+
emitting--;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
module.exports.default = module.exports;
|
|
80
|
+
module.exports.zephyrEventsFast = function zephyrEventsFast(all) {
|
|
81
|
+
all ??= new Map();
|
|
82
|
+
let hasWildcards = false;
|
|
83
|
+
return {
|
|
84
|
+
all,
|
|
85
|
+
on(type, handler) {
|
|
86
|
+
let handlers = all.get(type);
|
|
87
|
+
if (!handlers) {
|
|
88
|
+
handlers = [];
|
|
89
|
+
all.set(type, handlers);
|
|
90
|
+
}
|
|
91
|
+
handlers.push(handler);
|
|
92
|
+
if ('*' === type)
|
|
93
|
+
hasWildcards = true;
|
|
94
|
+
return () => {
|
|
95
|
+
const current = all.get(type);
|
|
96
|
+
if (current) {
|
|
97
|
+
const idx = current.indexOf(handler);
|
|
98
|
+
if (-1 < idx) {
|
|
99
|
+
current.splice(idx, 1);
|
|
100
|
+
}
|
|
101
|
+
if (0 === current.length) {
|
|
102
|
+
all.delete(type);
|
|
103
|
+
if ('*' === type)
|
|
104
|
+
hasWildcards = false;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
},
|
|
109
|
+
off(type, handler) {
|
|
110
|
+
const handlers = all.get(type);
|
|
111
|
+
if (!handlers)
|
|
112
|
+
return;
|
|
113
|
+
if (handler) {
|
|
114
|
+
const idx = handlers.indexOf(handler);
|
|
115
|
+
if (-1 < idx) {
|
|
116
|
+
handlers.splice(idx, 1);
|
|
117
|
+
}
|
|
118
|
+
if (0 === handlers.length) {
|
|
119
|
+
all.delete(type);
|
|
120
|
+
if ('*' === type)
|
|
121
|
+
hasWildcards = false;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
all.delete(type);
|
|
126
|
+
if ('*' === type)
|
|
127
|
+
hasWildcards = false;
|
|
128
|
+
}
|
|
129
|
+
},
|
|
130
|
+
emit(type, evt) {
|
|
131
|
+
const handlers = all.get(type);
|
|
132
|
+
if (handlers) {
|
|
133
|
+
const len = handlers.length;
|
|
134
|
+
for (let i = 0; i < len; i++) {
|
|
135
|
+
handlers[i](evt);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
if (hasWildcards && '*' !== type) {
|
|
139
|
+
const wildcards = all.get('*');
|
|
140
|
+
if (wildcards) {
|
|
141
|
+
const len = wildcards.length;
|
|
142
|
+
for (let i = 0; i < len; i++) {
|
|
143
|
+
wildcards[i](type, evt);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
};
|
|
149
|
+
}
|
package/dist/zephyr-events.mjs
CHANGED
|
@@ -1 +1,147 @@
|
|
|
1
|
-
export default
|
|
1
|
+
export default function zephyrEvents(all) {
|
|
2
|
+
all ??= new Map();
|
|
3
|
+
let hasWildcards = false;
|
|
4
|
+
let emitting = 0;
|
|
5
|
+
return {
|
|
6
|
+
all,
|
|
7
|
+
on(type, handler) {
|
|
8
|
+
let handlers = all.get(type);
|
|
9
|
+
if (!handlers) {
|
|
10
|
+
handlers = [];
|
|
11
|
+
all.set(type, handlers);
|
|
12
|
+
}
|
|
13
|
+
handlers.push(handler);
|
|
14
|
+
if ('*' === type)
|
|
15
|
+
hasWildcards = true;
|
|
16
|
+
return () => {
|
|
17
|
+
const current = all.get(type);
|
|
18
|
+
if (current) {
|
|
19
|
+
const idx = current.indexOf(handler);
|
|
20
|
+
if (-1 < idx) {
|
|
21
|
+
current.splice(idx, 1);
|
|
22
|
+
}
|
|
23
|
+
if (0 === current.length) {
|
|
24
|
+
all.delete(type);
|
|
25
|
+
if ('*' === type)
|
|
26
|
+
hasWildcards = false;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
},
|
|
31
|
+
off(type, handler) {
|
|
32
|
+
const handlers = all.get(type);
|
|
33
|
+
if (!handlers)
|
|
34
|
+
return;
|
|
35
|
+
if (handler) {
|
|
36
|
+
const idx = handlers.indexOf(handler);
|
|
37
|
+
if (-1 < idx) {
|
|
38
|
+
handlers.splice(idx, 1);
|
|
39
|
+
}
|
|
40
|
+
if (0 === handlers.length) {
|
|
41
|
+
all.delete(type);
|
|
42
|
+
if ('*' === type)
|
|
43
|
+
hasWildcards = false;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
all.delete(type);
|
|
48
|
+
if ('*' === type)
|
|
49
|
+
hasWildcards = false;
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
emit(type, evt) {
|
|
53
|
+
const handlers = all.get(type);
|
|
54
|
+
if (handlers) {
|
|
55
|
+
emitting++;
|
|
56
|
+
const snapshot = handlers.slice();
|
|
57
|
+
const len = snapshot.length;
|
|
58
|
+
for (let i = 0; i < len; i++) {
|
|
59
|
+
snapshot[i](evt);
|
|
60
|
+
}
|
|
61
|
+
emitting--;
|
|
62
|
+
}
|
|
63
|
+
if (hasWildcards && '*' !== type) {
|
|
64
|
+
const wildcards = all.get('*');
|
|
65
|
+
if (wildcards) {
|
|
66
|
+
emitting++;
|
|
67
|
+
const snapshot = wildcards.slice();
|
|
68
|
+
const len = snapshot.length;
|
|
69
|
+
for (let i = 0; i < len; i++) {
|
|
70
|
+
snapshot[i](type, evt);
|
|
71
|
+
}
|
|
72
|
+
emitting--;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
export function zephyrEventsFast(all) {
|
|
79
|
+
all ??= new Map();
|
|
80
|
+
let hasWildcards = false;
|
|
81
|
+
return {
|
|
82
|
+
all,
|
|
83
|
+
on(type, handler) {
|
|
84
|
+
let handlers = all.get(type);
|
|
85
|
+
if (!handlers) {
|
|
86
|
+
handlers = [];
|
|
87
|
+
all.set(type, handlers);
|
|
88
|
+
}
|
|
89
|
+
handlers.push(handler);
|
|
90
|
+
if ('*' === type)
|
|
91
|
+
hasWildcards = true;
|
|
92
|
+
return () => {
|
|
93
|
+
const current = all.get(type);
|
|
94
|
+
if (current) {
|
|
95
|
+
const idx = current.indexOf(handler);
|
|
96
|
+
if (-1 < idx) {
|
|
97
|
+
current.splice(idx, 1);
|
|
98
|
+
}
|
|
99
|
+
if (0 === current.length) {
|
|
100
|
+
all.delete(type);
|
|
101
|
+
if ('*' === type)
|
|
102
|
+
hasWildcards = false;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
},
|
|
107
|
+
off(type, handler) {
|
|
108
|
+
const handlers = all.get(type);
|
|
109
|
+
if (!handlers)
|
|
110
|
+
return;
|
|
111
|
+
if (handler) {
|
|
112
|
+
const idx = handlers.indexOf(handler);
|
|
113
|
+
if (-1 < idx) {
|
|
114
|
+
handlers.splice(idx, 1);
|
|
115
|
+
}
|
|
116
|
+
if (0 === handlers.length) {
|
|
117
|
+
all.delete(type);
|
|
118
|
+
if ('*' === type)
|
|
119
|
+
hasWildcards = false;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
all.delete(type);
|
|
124
|
+
if ('*' === type)
|
|
125
|
+
hasWildcards = false;
|
|
126
|
+
}
|
|
127
|
+
},
|
|
128
|
+
emit(type, evt) {
|
|
129
|
+
const handlers = all.get(type);
|
|
130
|
+
if (handlers) {
|
|
131
|
+
const len = handlers.length;
|
|
132
|
+
for (let i = 0; i < len; i++) {
|
|
133
|
+
handlers[i](evt);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
if (hasWildcards && '*' !== type) {
|
|
137
|
+
const wildcards = all.get('*');
|
|
138
|
+
if (wildcards) {
|
|
139
|
+
const len = wildcards.length;
|
|
140
|
+
for (let i = 0; i < len; i++) {
|
|
141
|
+
wildcards[i](type, evt);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
};
|
|
147
|
+
}
|
|
@@ -1,7 +1,156 @@
|
|
|
1
1
|
(function (global, factory) {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
}(this, (function () {
|
|
6
|
-
|
|
7
|
-
|
|
2
|
+
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
|
|
3
|
+
typeof define === 'function' && define.amd ? define(['exports'], factory) :
|
|
4
|
+
(global = global || self, factory(global));
|
|
5
|
+
}(this, (function (exports) {
|
|
6
|
+
'use strict';
|
|
7
|
+
function zephyrEvents(all) {
|
|
8
|
+
all ??= new Map();
|
|
9
|
+
let hasWildcards = false;
|
|
10
|
+
let emitting = 0;
|
|
11
|
+
return {
|
|
12
|
+
all,
|
|
13
|
+
on(type, handler) {
|
|
14
|
+
let handlers = all.get(type);
|
|
15
|
+
if (!handlers) {
|
|
16
|
+
handlers = [];
|
|
17
|
+
all.set(type, handlers);
|
|
18
|
+
}
|
|
19
|
+
handlers.push(handler);
|
|
20
|
+
if ('*' === type)
|
|
21
|
+
hasWildcards = true;
|
|
22
|
+
return () => {
|
|
23
|
+
const current = all.get(type);
|
|
24
|
+
if (current) {
|
|
25
|
+
const idx = current.indexOf(handler);
|
|
26
|
+
if (-1 < idx) {
|
|
27
|
+
current.splice(idx, 1);
|
|
28
|
+
}
|
|
29
|
+
if (0 === current.length) {
|
|
30
|
+
all.delete(type);
|
|
31
|
+
if ('*' === type)
|
|
32
|
+
hasWildcards = false;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
},
|
|
37
|
+
off(type, handler) {
|
|
38
|
+
const handlers = all.get(type);
|
|
39
|
+
if (!handlers)
|
|
40
|
+
return;
|
|
41
|
+
if (handler) {
|
|
42
|
+
const idx = handlers.indexOf(handler);
|
|
43
|
+
if (-1 < idx) {
|
|
44
|
+
handlers.splice(idx, 1);
|
|
45
|
+
}
|
|
46
|
+
if (0 === handlers.length) {
|
|
47
|
+
all.delete(type);
|
|
48
|
+
if ('*' === type)
|
|
49
|
+
hasWildcards = false;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
all.delete(type);
|
|
54
|
+
if ('*' === type)
|
|
55
|
+
hasWildcards = false;
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
emit(type, evt) {
|
|
59
|
+
const handlers = all.get(type);
|
|
60
|
+
if (handlers) {
|
|
61
|
+
emitting++;
|
|
62
|
+
const snapshot = handlers.slice();
|
|
63
|
+
const len = snapshot.length;
|
|
64
|
+
for (let i = 0; i < len; i++) {
|
|
65
|
+
snapshot[i](evt);
|
|
66
|
+
}
|
|
67
|
+
emitting--;
|
|
68
|
+
}
|
|
69
|
+
if (hasWildcards && '*' !== type) {
|
|
70
|
+
const wildcards = all.get('*');
|
|
71
|
+
if (wildcards) {
|
|
72
|
+
emitting++;
|
|
73
|
+
const snapshot = wildcards.slice();
|
|
74
|
+
const len = snapshot.length;
|
|
75
|
+
for (let i = 0; i < len; i++) {
|
|
76
|
+
snapshot[i](type, evt);
|
|
77
|
+
}
|
|
78
|
+
emitting--;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
function zephyrEventsFast(all) {
|
|
85
|
+
all ??= new Map();
|
|
86
|
+
let hasWildcards = false;
|
|
87
|
+
return {
|
|
88
|
+
all,
|
|
89
|
+
on(type, handler) {
|
|
90
|
+
let handlers = all.get(type);
|
|
91
|
+
if (!handlers) {
|
|
92
|
+
handlers = [];
|
|
93
|
+
all.set(type, handlers);
|
|
94
|
+
}
|
|
95
|
+
handlers.push(handler);
|
|
96
|
+
if ('*' === type)
|
|
97
|
+
hasWildcards = true;
|
|
98
|
+
return () => {
|
|
99
|
+
const current = all.get(type);
|
|
100
|
+
if (current) {
|
|
101
|
+
const idx = current.indexOf(handler);
|
|
102
|
+
if (-1 < idx) {
|
|
103
|
+
current.splice(idx, 1);
|
|
104
|
+
}
|
|
105
|
+
if (0 === current.length) {
|
|
106
|
+
all.delete(type);
|
|
107
|
+
if ('*' === type)
|
|
108
|
+
hasWildcards = false;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
},
|
|
113
|
+
off(type, handler) {
|
|
114
|
+
const handlers = all.get(type);
|
|
115
|
+
if (!handlers)
|
|
116
|
+
return;
|
|
117
|
+
if (handler) {
|
|
118
|
+
const idx = handlers.indexOf(handler);
|
|
119
|
+
if (-1 < idx) {
|
|
120
|
+
handlers.splice(idx, 1);
|
|
121
|
+
}
|
|
122
|
+
if (0 === handlers.length) {
|
|
123
|
+
all.delete(type);
|
|
124
|
+
if ('*' === type)
|
|
125
|
+
hasWildcards = false;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
all.delete(type);
|
|
130
|
+
if ('*' === type)
|
|
131
|
+
hasWildcards = false;
|
|
132
|
+
}
|
|
133
|
+
},
|
|
134
|
+
emit(type, evt) {
|
|
135
|
+
const handlers = all.get(type);
|
|
136
|
+
if (handlers) {
|
|
137
|
+
const len = handlers.length;
|
|
138
|
+
for (let i = 0; i < len; i++) {
|
|
139
|
+
handlers[i](evt);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
if (hasWildcards && '*' !== type) {
|
|
143
|
+
const wildcards = all.get('*');
|
|
144
|
+
if (wildcards) {
|
|
145
|
+
const len = wildcards.length;
|
|
146
|
+
for (let i = 0; i < len; i++) {
|
|
147
|
+
wildcards[i](type, evt);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
exports.zephyrEvents = zephyrEvents;
|
|
155
|
+
exports.zephyrEventsFast = zephyrEventsFast;
|
|
156
|
+
})));
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zephyr-events",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "1.3.0",
|
|
4
|
+
"description": "Tiny typed event emitter with race-condition safety",
|
|
5
5
|
"main": "dist/zephyr-events.js",
|
|
6
6
|
"module": "dist/zephyr-events.mjs",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
@@ -19,23 +19,29 @@
|
|
|
19
19
|
],
|
|
20
20
|
"scripts": {
|
|
21
21
|
"build": "tsc --build && node build.js",
|
|
22
|
-
"
|
|
22
|
+
"test": "node test/index.js",
|
|
23
|
+
"prepublishOnly": "npm run build && npm test"
|
|
23
24
|
},
|
|
24
25
|
"repository": {
|
|
25
26
|
"type": "git",
|
|
26
27
|
"url": "git+https://github.com/ebogdum/zephyr-events.git"
|
|
27
28
|
},
|
|
28
29
|
"keywords": [
|
|
29
|
-
"
|
|
30
|
+
"event-emitter",
|
|
30
31
|
"eventemitter",
|
|
32
|
+
"events",
|
|
31
33
|
"emitter",
|
|
32
34
|
"pubsub",
|
|
35
|
+
"event-bus",
|
|
33
36
|
"typescript",
|
|
34
|
-
"
|
|
35
|
-
"
|
|
37
|
+
"typed-events",
|
|
38
|
+
"mitt-alternative",
|
|
39
|
+
"lightweight",
|
|
36
40
|
"tiny",
|
|
37
|
-
"
|
|
38
|
-
"
|
|
41
|
+
"subscribe",
|
|
42
|
+
"observer",
|
|
43
|
+
"race-condition-safe",
|
|
44
|
+
"wildcard"
|
|
39
45
|
],
|
|
40
46
|
"homepage": "https://github.com/ebogdum/zephyr-events",
|
|
41
47
|
"bugs": {
|
|
@@ -44,7 +50,7 @@
|
|
|
44
50
|
"author": "ebogdum <https://github.com/ebogdum>",
|
|
45
51
|
"license": "MIT",
|
|
46
52
|
"engines": {
|
|
47
|
-
"node": ">=
|
|
53
|
+
"node": ">=18"
|
|
48
54
|
},
|
|
49
55
|
"devDependencies": {
|
|
50
56
|
"typescript": "^5.9.2"
|