fastevent 1.1.3 → 2.0.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.
Files changed (80) hide show
  1. package/dist/devTools.js +2 -2
  2. package/dist/devTools.js.map +1 -1
  3. package/dist/devTools.mjs +2 -2
  4. package/dist/devTools.mjs.map +1 -1
  5. package/dist/index.d.mts +285 -53
  6. package/dist/index.d.ts +285 -53
  7. package/dist/index.js +1 -1
  8. package/dist/index.js.map +1 -1
  9. package/dist/index.mjs +1 -1
  10. package/dist/index.mjs.map +1 -1
  11. package/package.json +64 -50
  12. package/readme.md +517 -50
  13. package/.changeset/README.md +0 -8
  14. package/.changeset/config.json +0 -11
  15. package/.github/workflows/publish.yaml +0 -50
  16. package/.prettierrc.js +0 -20
  17. package/.vscode/launch.json +0 -20
  18. package/.vscode/settings.json +0 -18
  19. package/CHANGELOG.md +0 -60
  20. package/LICENSE +0 -21
  21. package/bench.png +0 -0
  22. package/dist/devTools.d.mts +0 -543
  23. package/dist/devTools.d.ts +0 -543
  24. package/example/README.md +0 -54
  25. package/example/eslint.config.js +0 -28
  26. package/example/index.html +0 -13
  27. package/example/package.json +0 -29
  28. package/example/pnpm-lock.yaml +0 -2047
  29. package/example/public/vite.svg +0 -1
  30. package/example/src/App.css +0 -42
  31. package/example/src/App.tsx +0 -60
  32. package/example/src/assets/react.svg +0 -1
  33. package/example/src/index.css +0 -68
  34. package/example/src/main.tsx +0 -10
  35. package/example/src/myEvent.ts +0 -32
  36. package/example/src/vite-env.d.ts +0 -1
  37. package/example/tsconfig.app.json +0 -26
  38. package/example/tsconfig.json +0 -7
  39. package/example/tsconfig.node.json +0 -24
  40. package/example/vite.config.ts +0 -7
  41. package/packages/native/index.ts +0 -1
  42. package/packages/turbo/.zig-cache/h/271c82d991949fd7788fd5451f0ca834.txt +0 -0
  43. package/packages/turbo/.zig-cache/h/timestamp +0 -0
  44. package/packages/turbo/.zig-cache/o/ebd7ddab8ffe003267120d598aecce68/dependencies.zig +0 -2
  45. package/packages/turbo/.zig-cache/z/c8114b040daa461a9e2eabd0357554a4 +0 -0
  46. package/packages/turbo/build.zig +0 -60
  47. package/packages/turbo/examples/basic.zig +0 -107
  48. package/packages/turbo/src/event.zig +0 -251
  49. package/packages/turbo/src/index.zig +0 -70
  50. package/packages/turbo/src/scope.zig +0 -104
  51. package/packages/turbo/src/types.zig +0 -88
  52. package/packages/turbo/src/utils.zig +0 -171
  53. package/readme_cn.md +0 -491
  54. package/src/__benchmarks__/index.ts +0 -3
  55. package/src/__benchmarks__/multi-level.ts +0 -40
  56. package/src/__benchmarks__/sample.ts +0 -40
  57. package/src/__benchmarks__/wildcard.ts +0 -41
  58. package/src/__tests__/emit.test.ts +0 -106
  59. package/src/__tests__/emitAsync.test.ts +0 -64
  60. package/src/__tests__/isPathMatched.test.ts +0 -205
  61. package/src/__tests__/many.test.ts +0 -22
  62. package/src/__tests__/meta.test.ts +0 -28
  63. package/src/__tests__/off.test.ts +0 -214
  64. package/src/__tests__/onany.test.ts +0 -212
  65. package/src/__tests__/once.test.ts +0 -70
  66. package/src/__tests__/retain.test.ts +0 -66
  67. package/src/__tests__/scope.test.ts +0 -110
  68. package/src/__tests__/types.test.ts +0 -145
  69. package/src/__tests__/waitFor.test.ts +0 -116
  70. package/src/__tests__/wildcard.test.ts +0 -185
  71. package/src/devTools.ts +0 -166
  72. package/src/event.ts +0 -741
  73. package/src/index.ts +0 -3
  74. package/src/scope.ts +0 -130
  75. package/src/types.ts +0 -66
  76. package/src/utils/WeakObjectMap.ts +0 -64
  77. package/src/utils/isPathMatched.ts +0 -40
  78. package/src/utils/removeItem.ts +0 -16
  79. package/tsconfig.json +0 -104
  80. package/tsup.config.ts +0 -30
package/readme.md CHANGED
@@ -48,10 +48,105 @@ events.emit({
48
48
  payload: { id: 1, name: 'Alice' },
49
49
  meta: { timestamp: Date.now() },
50
50
  });
51
+
52
+ // Using TypeScript with type safety
53
+ interface MyEvents {
54
+ 'user/login': { id: number; name: string };
55
+ 'user/logout': { id: number };
56
+ }
57
+
58
+ const typedEvents = new FastEvent<MyEvents>();
59
+
60
+ // TypeScript will enforce correct event types and payloads
61
+ typedEvents.on('user/login', (message) => {
62
+ const { id, name } = message.payload; // Properly typed
63
+ });
51
64
  ```
52
65
 
53
66
  # Guide
54
67
 
68
+ ## Event Triggering
69
+
70
+ FastEvent provides flexible ways to trigger events with different parameter combinations:
71
+
72
+ ### Basic Event Triggering
73
+
74
+ ```typescript
75
+ const events = new FastEvent();
76
+
77
+ // Method 1: Parameters form
78
+ events.emit('user/login', { id: 1, name: 'Alice' });
79
+
80
+ // Method 2: Message object form
81
+ events.emit({
82
+ type: 'user/login',
83
+ payload: { id: 1, name: 'Alice' },
84
+ meta: { timestamp: Date.now() },
85
+ });
86
+ ```
87
+
88
+ ### Retained Events
89
+
90
+ Set `retain=true` to store the event for new subscribers:
91
+
92
+ ```typescript
93
+ // Emit and retain the event
94
+ events.emit('config/update', { theme: 'dark' }, true);
95
+
96
+ // Later subscribers will immediately receive the retained event
97
+ events.on('config/update', (message) => {
98
+ console.log('Config:', message.payload); // { theme: 'dark' }
99
+ });
100
+ ```
101
+
102
+ ### Event Metadata
103
+
104
+ Metadata can be provided at different levels and will be merged:
105
+
106
+ ```typescript
107
+ const events = new FastEvent({
108
+ meta: { app: 'MyApp' }, // Global metadata
109
+ });
110
+
111
+ // Event-specific metadata
112
+ events.emit('order/create', { id: '123' }, false, {
113
+ timestamp: Date.now(),
114
+ });
115
+
116
+ // Listener receives merged metadata:
117
+ // { type: 'order/create', app: 'MyApp', timestamp: ... }
118
+ ```
119
+
120
+ ### Return Values
121
+
122
+ `emit()` returns an array of listener results:
123
+
124
+ ```typescript
125
+ events.on('calculate', () => 1);
126
+ events.on('calculate', () => 2);
127
+
128
+ const results = events.emit('calculate');
129
+ console.log(results); // [1, 2]
130
+ ```
131
+
132
+ ### Type-safe Event Triggering
133
+
134
+ With TypeScript, event payloads are type-checked:
135
+
136
+ ```typescript
137
+ interface MyEvents {
138
+ 'user/login': { id: number; name: string };
139
+ }
140
+
141
+ const events = new FastEvent<MyEvents>();
142
+
143
+ // Valid - payload matches type
144
+ events.emit('user/login', { id: 1, name: 'Alice' });
145
+
146
+ // Error - payload type mismatch
147
+ events.emit('user/login', { id: '1' }); // TypeScript error
148
+ ```
149
+
55
150
  ## Event Message Format
56
151
 
57
152
  FastEvent uses a standardized message format for all events:
@@ -111,8 +206,45 @@ events.emit('user/login', data);
111
206
 
112
207
  // Clear all listeners in the scope
113
208
  userScope.offAll(); // Equivalent to events.offAll('user')
209
+
210
+ // Nested scopes
211
+ const profileScope = userScope.scope('profile');
212
+ profileScope.on('update', (message) => {
213
+ // Will receive events emitted as 'user/profile/update'
214
+ console.log('Profile update:', message.payload);
215
+ });
216
+
217
+ // Scope with metadata
218
+ const adminScope = events.scope('admin', {
219
+ meta: { role: 'admin' },
220
+ context: { adminId: 1 },
221
+ });
222
+
223
+ adminScope.on('action', function (message) {
224
+ console.log('Admin meta:', message.meta); // Contains { role: 'admin' }
225
+ console.log('Context:', this.adminId); // Access to scope context
226
+ });
227
+
228
+ // Type-safe scopes
229
+ interface UserEvents {
230
+ login: { id: number };
231
+ logout: { id: number };
232
+ }
233
+
234
+ const typedUserScope = events.scope<'user', UserEvents>('user');
235
+ typedUserScope.on('login', (message) => {
236
+ const { id } = message.payload; // Properly typed as { id: number }
237
+ });
114
238
  ```
115
239
 
240
+ Scopes provide several benefits:
241
+
242
+ 1. Namespace organization - Group related events under a common prefix
243
+ 2. Code organization - Separate event handling logic by domain
244
+ 3. Metadata inheritance - Share common metadata across related events
245
+ 4. Context binding - Provide specific execution context for event handlers
246
+ 5. Type safety - Enforce type checking for scoped events
247
+
116
248
  ## Listener Options
117
249
 
118
250
  When subscribing to events, you can specify additional options:
@@ -253,18 +385,146 @@ events.on('config/update', (message) => {
253
385
  });
254
386
  ```
255
387
 
256
- ## Multi-level Events
388
+ ## Multi-level Events and Wildcards
257
389
 
258
- Support for publishing and subscribing to multi-level events.
390
+ FastEvent supports hierarchical event structures with powerful wildcard matching capabilities.
259
391
 
260
- By default, '/' is used as the event path delimiter, but you can use custom delimiters:
392
+ ### Event Path Structure
393
+
394
+ Events can be organized in a hierarchical structure using path delimiters (default is '/'):
261
395
 
262
396
  ```typescript
263
- const events = new FastEvent({
397
+ const events = new FastEvent();
398
+
399
+ // Basic multi-level events
400
+ events.on('user/profile/update', handler);
401
+ events.on('user/settings/theme/change', handler);
402
+
403
+ // Custom delimiter
404
+ const customEvents = new FastEvent({
264
405
  delimiter: '.',
265
406
  });
407
+ customEvents.on('user.profile.update', handler);
408
+ ```
409
+
410
+ ### Wildcard Patterns
411
+
412
+ FastEvent supports two types of wildcards:
413
+
414
+ 1. Single-level wildcard (`*`):
415
+ - Matches exactly one level in the event path
416
+ - Can be used at any level in the path
417
+
418
+ ```typescript
419
+ // Match any user type
420
+ events.on('user/*/login', (message) => {
421
+ console.log('User type:', message.type.split('/')[1]);
422
+ // Matches: user/admin/login, user/guest/login, etc.
423
+ });
424
+
425
+ // Match any action
426
+ events.on('api/users/*/action/*', (message) => {
427
+ const [, , userId, , action] = message.type.split('/');
428
+ console.log(`User ${userId} performed ${action}`);
429
+ // Matches: api/users/123/action/update, api/users/456/action/delete, etc.
430
+ });
431
+ ```
432
+
433
+ 2. Multi-level wildcard (`**`):
434
+ - Matches zero or more levels in the event path
435
+ - Must be used at the end of the path pattern
436
+
437
+ ```typescript
438
+ // Match all user-related events
439
+ events.on('user/**', (message) => {
440
+ console.log('User event:', message.type);
441
+ // Matches: user/login, user/profile/update, user/settings/theme/change, etc.
442
+ });
443
+
444
+ // Match all API events
445
+ events.on('api/**', (message) => {
446
+ console.log('API event:', message.type, message.payload);
447
+ // Matches: api/get, api/users/create, api/posts/123/comments/add, etc.
448
+ });
266
449
  ```
267
450
 
451
+ ### Advanced Wildcard Usage
452
+
453
+ ```typescript
454
+ const events = new FastEvent();
455
+
456
+ // Using single-level wildcards
457
+ events.on('service/*/user/update', (message) => {
458
+ // Matches patterns like:
459
+ // service/auth/user/update
460
+ // service/admin/user/update
461
+ const parts = message.type.split('/');
462
+ const serviceType = parts[1];
463
+ console.log(`${serviceType} service user update:`, message.payload);
464
+ });
465
+
466
+ // Using multi-level wildcard at the end
467
+ events.on('service/auth/**', (message) => {
468
+ // Matches patterns like:
469
+ // service/auth/user/update
470
+ // service/auth/user/profile/update
471
+ // service/auth/settings/theme/change
472
+ console.log('Auth service event:', message.type, message.payload);
473
+ });
474
+
475
+ // Type-safe events with TypeScript
476
+ interface ApiEvents {
477
+ 'api/users/profile': { userId: string; data: any };
478
+ 'api/posts/comments': { postId: string; commentId: string; text: string };
479
+ }
480
+
481
+ const typedEvents = new FastEvent<ApiEvents>();
482
+
483
+ // Exact match with type safety
484
+ typedEvents.on('api/users/profile', (message) => {
485
+ const { userId, data } = message.payload; // Properly typed
486
+ });
487
+
488
+ // Wildcard listeners still work but lose some type safety
489
+ typedEvents.on('api/*', (message) => {
490
+ // message.payload type is any here
491
+ console.log('API event:', message.type);
492
+ });
493
+
494
+ // Wildcard event monitoring
495
+ events.on('**', (message) => {
496
+ console.log('Event intercepted:', {
497
+ type: message.type,
498
+ timestamp: new Date(),
499
+ payload: message.payload,
500
+ });
501
+ });
502
+
503
+ // Example usage
504
+ events.emit('service/auth/user/profile/update', { name: 'John' });
505
+ events.emit('api/users/123/profile', { userId: '123', data: { age: 30 } });
506
+ ```
507
+
508
+ ### Important Notes
509
+
510
+ 1. Wildcard Limitations:
511
+
512
+ - `**` wildcard must be at the end of the path
513
+ - `*` can be used multiple times in a path
514
+ - Wildcards cannot be combined in a single segment (e.g., 'a/\*\*/b' is invalid)
515
+
516
+ 2. Performance Considerations:
517
+
518
+ - Specific patterns (without wildcards) are matched faster
519
+ - `*` wildcards are more efficient than `**`
520
+ - Excessive use of `**` wildcards may impact performance
521
+
522
+ 3. Best Practices:
523
+ - Use specific patterns when possible
524
+ - Limit the use of `**` wildcards
525
+ - Consider the event hierarchy carefully
526
+ - Use TypeScript interfaces for type safety
527
+
268
528
  ## Global Event Listening
269
529
 
270
530
  Use `onAny` to listen to all events:
@@ -282,7 +542,7 @@ events.onAny(handler, { prepend: true });
282
542
 
283
543
  ## Metadata (Meta)
284
544
 
285
- Metadata is a mechanism for providing additional context information for events. You can set metadata globally or add specific metadata for individual events.
545
+ Metadata is a mechanism for providing additional context information for events. You can set metadata at different levels: globally, scope-level, or event-specific.
286
546
 
287
547
  ### Global Metadata
288
548
 
@@ -302,30 +562,83 @@ events.on('user/login', (message) => {
302
562
  });
303
563
  ```
304
564
 
565
+ ### Scope Metadata
566
+
567
+ When creating a scope, you can provide metadata that will be merged with global metadata:
568
+
569
+ ```typescript
570
+ const events = new FastEvent({
571
+ meta: { app: 'MyApp' },
572
+ });
573
+
574
+ const userScope = events.scope('user', {
575
+ meta: { domain: 'user' },
576
+ });
577
+
578
+ userScope.on('login', (message) => {
579
+ console.log('Metadata:', message.meta);
580
+ // { type: 'user/login', app: 'MyApp', domain: 'user' }
581
+ });
582
+
583
+ // Nested scopes merge metadata recursively
584
+ const profileScope = userScope.scope('profile', {
585
+ meta: { section: 'profile' },
586
+ });
587
+
588
+ profileScope.on('update', (message) => {
589
+ console.log('Metadata:', message.meta);
590
+ // { type: 'user/profile/update', app: 'MyApp', domain: 'user', section: 'profile' }
591
+ });
592
+ ```
593
+
305
594
  ### Event-specific Metadata
306
595
 
307
- Additional metadata can be passed when publishing events, which will be merged with global metadata:
596
+ Additional metadata can be passed when publishing events, which will be merged with higher-level metadata:
308
597
 
309
598
  ```typescript
310
599
  const events = new FastEvent({
311
600
  meta: { app: 'MyApp' },
312
601
  });
313
602
 
603
+ const userScope = events.scope('user', {
604
+ meta: { domain: 'user' },
605
+ });
606
+
314
607
  // Add specific metadata when publishing event
315
- events.emit(
316
- 'order/create',
317
- { orderId: '123' }, // Event data
608
+ userScope.emit(
609
+ 'login',
610
+ { userId: '123' }, // Event data
318
611
  false, // Don't retain
319
612
  { timestamp: Date.now() }, // Event-specific metadata
320
613
  );
321
614
 
322
615
  // Listener receives merged metadata
323
- events.on('order/create', (message) => {
324
- console.log('Order:', message.payload); // { orderId: '123' }
325
- console.log('Metadata:', message.meta); // { type: 'order/create', app: 'MyApp', timestamp: ... }
616
+ userScope.on('login', (message) => {
617
+ console.log('Metadata:', message.meta);
618
+ // { type: 'user/login', app: 'MyApp', domain: 'user', timestamp: ... }
326
619
  });
327
620
  ```
328
621
 
622
+ ### Metadata Merge Rules
623
+
624
+ 1. Priority (highest to lowest):
625
+
626
+ - Event-specific metadata
627
+ - Scope metadata (innermost to outermost)
628
+ - Global metadata
629
+ - System metadata (type is always added)
630
+
631
+ 2. Merge behavior:
632
+
633
+ - Shallow merge (top-level properties only)
634
+ - Later values override earlier ones
635
+ - No deep merging of nested objects
636
+
637
+ 3. Special cases:
638
+ - `type` is always preserved as the full event path
639
+ - `undefined` values will remove the property from the result
640
+ - Arrays are replaced, not concatenated
641
+
329
642
  ## Error Handling
330
643
 
331
644
  FastEvent provides error handling mechanisms:
@@ -440,51 +753,205 @@ events.emit('data/string', 'hello');
440
753
  events.emit('data/object', { value: true });
441
754
  ```
442
755
 
443
- ## Custom Options
756
+ ## Event Hooks
757
+
758
+ FastEvent provides several hooks for monitoring and debugging the event system:
759
+
760
+ ```typescript
761
+ const events = new FastEvent({
762
+ // Called when a new listener is added
763
+ onAddListener: (path: string[], listener: Function) => {
764
+ console.log('New listener added for:', path.join('/'));
765
+ },
766
+
767
+ // Called when a listener is removed
768
+ onRemoveListener: (path: string[], listener: Function) => {
769
+ console.log('Listener removed from:', path.join('/'));
770
+ },
771
+
772
+ // Called when listeners are cleared
773
+ onClearListeners: () => {
774
+ console.log('All listeners cleared');
775
+ },
776
+
777
+ // Called when a listener throws an error
778
+ onListenerError: (type: string, error: Error) => {
779
+ console.error(`Error in listener for ${type}:`, error);
780
+ },
781
+
782
+ // Called after listeners are executed (debug mode only)
783
+ onExecuteListener: (message, returns, listeners) => {
784
+ console.log('Event executed:', {
785
+ type: message.type,
786
+ payload: message.payload,
787
+ results: returns,
788
+ listenerCount: listeners.length,
789
+ });
790
+ },
791
+ });
792
+ ```
793
+
794
+ These hooks provide valuable insights into the event system's operation:
795
+
796
+ 1. `onAddListener`: Monitor listener registration
797
+
798
+ - Called whenever a new event listener is added
799
+ - Receives the event path array and listener function
800
+ - Useful for tracking event subscriptions
444
801
 
445
- The FastEvent constructor supports multiple options:
802
+ 2. `onRemoveListener`: Track listener removal
803
+
804
+ - Called when a listener is removed
805
+ - Helps monitor event unsubscription patterns
806
+ - Receives the same parameters as onAddListener
807
+
808
+ 3. `onClearListeners`: Notifies of bulk listener removal
809
+
810
+ - Called when offAll() is invoked
811
+ - Useful for cleanup monitoring
812
+ - No parameters provided
813
+
814
+ 4. `onListenerError`: Error handling hook
815
+
816
+ - Called when a listener throws an error
817
+ - Receives the event type and error object
818
+ - Enables centralized error handling
819
+ - Only called if ignoreErrors is true
820
+
821
+ 5. `onExecuteListener`: Execution monitoring (debug mode)
822
+ - Only active when debug: true is set
823
+ - Provides detailed execution information
824
+ - Includes message, return values, and listener list
825
+ - Useful for debugging and performance monitoring
826
+
827
+ Example usage:
446
828
 
447
829
  ```typescript
448
830
  const events = new FastEvent({
449
- // Event path delimiter, default is '/'
450
- delimiter: '.',
451
- // Context for event handlers
452
- context: null,
453
- // Metadata, passed to all event handlers
454
- meta: { ... },
455
-
456
- // Error handling
457
- ignoreErrors: true,
458
- onListenerError: (type, error) => {
459
- console.error(`Event error:`, type, error);
460
- },
461
-
462
- // Callbacks for listener addition/removal
463
- onAddListener: (path, listener) => {
464
- console.log('Listener added:', path);
465
- },
466
- onRemoveListener: (path, listener) => {
467
- console.log('Listener removed:', path);
468
- }
469
- onClearListeners: () => {
470
- console.log('清空监听器:', path);
471
- },
472
- onExecuteListener: (message: FastEventMessage, returns: any[], listeners: (FastEventListener<any, any, any> | [FastEventListener<any, any>, number])[]) => {
473
- console.log('监听器执行后的回调:');
474
- }
475
- });
476
- ```
477
-
478
- ### debug
479
-
480
- Use `debug` option to enable debug mode and import `fastevent/devtools`, so that you can see the events in `Redux Dev Tools`.
481
-
482
- ```ts
831
+ debug: true, // Enable debug mode for onExecuteListener
832
+ onAddListener: (path, listener) => {
833
+ console.log(`Listener added for ${path.join('/')}`);
834
+ // Track listener count or patterns
835
+ },
836
+ onListenerError: (type, error) => {
837
+ console.error(`Error in ${type}:`, error);
838
+ // Log to monitoring system
839
+ },
840
+ onExecuteListener: (message, returns, listeners) => {
841
+ console.log(`Event ${message.type} executed:`, {
842
+ executionTime: Date.now(),
843
+ listenerCount: listeners.length,
844
+ results: returns,
845
+ });
846
+ // Monitor event execution patterns
847
+ },
848
+ });
849
+
850
+ // Example events that trigger hooks
851
+ events.on('user/login', () => {
852
+ // onAddListener will be called
853
+ });
854
+
855
+ events.on('data/process', () => {
856
+ throw new Error('Process failed');
857
+ // onListenerError will be called
858
+ });
859
+
860
+ events.emit('user/login', { id: 1 });
861
+ // onExecuteListener will be called (if debug: true)
862
+
863
+ events.offAll();
864
+ // onClearListeners will be called
865
+ ```
866
+
867
+ # Parameters
868
+
869
+ FastEvent constructor accepts the following configuration options:
870
+
871
+ ````typescript
872
+ interface FastEventOptions<Meta = Record<string, any>, Context = any> {
873
+ /**
874
+ * Unique identifier for the emitter instance
875
+ * @default Randomly generated string
876
+ */
877
+ id?: string;
878
+
879
+ /**
880
+ * Whether to enable debug mode
881
+ * @default false
882
+ * @remarks When true, events can be viewed in Redux DevTools
883
+ */
884
+ debug?: boolean;
885
+
886
+ /**
887
+ * Delimiter for event path segments
888
+ * @default '/'
889
+ * @example
890
+ * ```ts
891
+ * new FastEvent({ delimiter: '.' }); // Use dot as delimiter
892
+ * ```
893
+ */
894
+ delimiter?: string;
895
+
896
+ /**
897
+ * Default execution context for event handlers
898
+ * @default null
899
+ */
900
+ context?: Context;
901
+
902
+ /**
903
+ * Whether to ignore listener errors
904
+ * @default true
905
+ */
906
+ ignoreErrors?: boolean;
907
+
908
+ /**
909
+ * Global metadata attached to all events
910
+ * @default undefined
911
+ */
912
+ meta?: Meta;
913
+
914
+ /**
915
+ * Callback when a listener is added
916
+ * @param path - Array of path segments
917
+ * @param listener - The listener function
918
+ */
919
+ onAddListener?: (path: string[], listener: Function) => void;
920
+
921
+ /**
922
+ * Callback when a listener is removed
923
+ * @param path - Array of path segments
924
+ * @param listener - The listener function
925
+ */
926
+ onRemoveListener?: (path: string[], listener: Function) => void;
927
+
928
+ /**
929
+ * Callback when all listeners are cleared
930
+ */
931
+ onClearListeners?: () => void;
932
+
933
+ /**
934
+ * Callback when a listener throws an error
935
+ * @param type - Event type
936
+ * @param error - The error object
937
+ */
938
+ onListenerError?: (type: string, error: Error) => void;
939
+
940
+ /**
941
+ * Callback after listeners are executed (debug mode only)
942
+ * @param message - Event message
943
+ * @param returns - Array of listener return values
944
+ * @param listeners - Array of executed listeners
945
+ */
946
+ onExecuteListener?: (message: FastEventMessage, returns: any[], listeners: (FastEventListener<any, any, any> | [FastEventListener<any, any>, number])[]) => void;
947
+ }
948
+
949
+ // Debug mode usage
483
950
  import 'fastevent/devtools';
484
951
  const emitter = new FastEvent({
485
- debug: true,
952
+ debug: true, // Enable debug mode to view events in Redux DevTools
486
953
  });
487
- ```
954
+ ````
488
955
 
489
956
  # Performance
490
957
 
@@ -1,8 +0,0 @@
1
- # Changesets
2
-
3
- Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works
4
- with multi-package repos, or single-package repos to help you version and publish your code. You can
5
- find the full documentation for it [in our repository](https://github.com/changesets/changesets)
6
-
7
- We have a quick list of common questions to get you started engaging with this project in
8
- [our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md)
@@ -1,11 +0,0 @@
1
- {
2
- "$schema": "https://unpkg.com/@changesets/config@3.1.1/schema.json",
3
- "changelog": "@changesets/cli/changelog",
4
- "commit": true,
5
- "fixed": [],
6
- "linked": [],
7
- "access": "public",
8
- "baseBranch": "master",
9
- "updateInternalDependencies": "patch",
10
- "ignore": []
11
- }