### Implement Queue Listener with FastEvent Pipes (TypeScript) Source: https://github.com/zhangfisher/fastevent/blob/master/docs/en/guide/intro/get-started.md Demonstrates how to use listener pipes in FastEvent to wrap listener functions. This example shows the implementation of a queue pipe to manage messages in a queue with a specified size, preventing listener overload and ensuring ordered processing. ```typescript import { queue } from 'fastevent/pipes'; const events = new FastEvent(); // default queue size is 10 events.on( 'data/update', (data) => { console.log('Processing data:', data); }, { pipes: [queue({ size: 10 })], }, ); ``` -------------------------------- ### Hierarchical Event Publishing with Wildcards in TypeScript Source: https://github.com/zhangfisher/fastevent/blob/master/docs/en/guide/intro/get-started.md Explains and demonstrates FastEvent's support for hierarchical event publishing using path delimiters (default '/') and wildcards ('*' and '**'). This enables flexible event matching for complex systems. ```typescript const events = new FastEvent(); // Match user/*/login events.on('user/*/login', (message) => { console.log('Any user type login:', message.payload); }); // Match all events under user events.on('user/**', (message) => { console.log('All user-related events:', message.payload); }); // Trigger events events.emit('user/admin/login', { id: 1 }); // Both handlers will be called events.emit('user/admin/profile/update', { name: 'New' }); // Only the ** handler will be called ``` -------------------------------- ### Waiting for Events with Timeouts in TypeScript Source: https://github.com/zhangfisher/fastevent/blob/master/docs/en/guide/intro/get-started.md Demonstrates how to use the `waitFor` method in FastEvent to asynchronously wait for a specific event to occur, with support for configurable timeouts. This is useful for synchronizing operations based on event occurrences. ```typescript const events = new FastEvent(); async function waitForLogin() { try { // Wait for login event with a 5-second timeout const userData = await events.waitFor('user/login', 5000); console.log('User logged in:', userData); } catch (error) { console.log('Login wait timeout'); } } waitForLogin(); // Later trigger the login event events.emit('user/login', { id: 1, name: 'Alice' }); ``` -------------------------------- ### Basic Event Publishing and Subscription in TypeScript Source: https://github.com/zhangfisher/fastevent/blob/master/docs/en/guide/intro/get-started.md Demonstrates fundamental event emission and subscription using FastEvent. It covers basic emit, async emit, regular on, once, and wildcard listeners. Dependencies include the 'fastevent' package. No specific inputs/outputs are defined beyond event payloads. ```typescript import { FastEvent } from 'fastevent'; const events = new FastEvent(); // Basic event publishing const results = events.emit('user/login', { id: 1 }); // Asynchronous event emission const results = await events.emitAsync('data/process', { items: [...] }); // Event subscription events.on('user/login', (message) => { console.log('User login:', message.payload); }); // One-time listener events.once('startup', () => console.log('Application has started')); // Listener with options events.on('data/update', handler, { count: 3, // Maximum trigger count prepend: true, // Add to the beginning of the queue filter: (msg) => msg.payload.important // Only process important updates }); // Global listener events.onAny((message) => { console.log('Event occurred:', message.type); }); ``` -------------------------------- ### Forwarding Subscriptions and Publications with FastEvent (TypeScript) Source: https://github.com/zhangfisher/fastevent/blob/master/docs/en/guide/intro/get-started.md Illustrates how FastEvent can forward publishing and subscription events to another FastEvent instance. This enables centralized event management and cross-emitter communication, useful for decoupling components or managing shared event streams. ```typescript const otherEmitter = new FastEvent(); const emitter = new FastEvent({ onAddListener: (type, listener, options) => { // Subscription forwarding rule: when event name starts with `@/`, forward subscription to another `FastEvent` instance if (type.startsWith('@/')) { return otherEmitter.on(type.substring(2), listener, options); } }, onBeforeExecuteListener: (message, args) => { // Event forwarding rule: when event name starts with `@/`, publish to another `FastEvent` instance if (message.type.startsWith('@/')) { message.type = message.type.substring(2); return otherEmitter.emit(message, args); } }, }); const events: any[] = []; otherEmitter.on('data', ({ payload }) => { events.push(payload); }); // Subscribe to otherEmitter's data event emitter.on('@/data', ({ payload }) => { expect(payload).toBe(1); events.push(payload); }); // Publish data event to otherEmitter const subscriber = emitter.emit('@/data', 1); subscriber.off(); ``` -------------------------------- ### FastEvent Retained Events in TypeScript Source: https://github.com/zhangfisher/fastevent/blob/master/docs/en/guide/intro/get-started.md Demonstrates how to use retained events in FastEvent, allowing subscribers to immediately receive the last published event's data upon subscription. This is useful for configuration or state synchronization. ```typescript const events = new FastEvent(); // Publish and retain event events.emit('config/theme', { dark: true }, true); // Equivalent to events.emit('config/theme', { dark: true }, { retain: true }); // Subsequent subscribers immediately receive the retained value events.on('config/theme', (message) => { console.log('Theme:', message.payload); // Immediately outputs: { dark: true } }); ``` -------------------------------- ### Implementing Metadata with FastEvent (TypeScript) Source: https://github.com/zhangfisher/fastevent/blob/master/docs/en/guide/intro/get-started.md Shows how to use metadata in FastEvent to provide additional contextual information for events. Metadata can be set globally, at the scope level, or event-specifically, and listeners receive merged metadata including type, version, and environment. ```typescript const events = new FastEvent({ meta: { version: '1.0', environment: 'production', }, }); events.on('user/login', (message) => { console.log('Event data:', message.payload); console.log('Metadata:', message.meta); // Includes type, version, and environment }); // Using scope-level metadata const userScope = events.scope('user', { meta: { domain: 'user' }, }); // Add specific metadata when publishing events userScope.emit( 'login', { userId: '123' }, { meta: { timestamp: Date.now() }, // Event-specific metadata }, ); // Listeners receive merged metadata userScope.on('login', (message) => { console.log('Metadata:', message.meta); }); ``` -------------------------------- ### FastEvent Quick Start: TypeScript Source: https://github.com/zhangfisher/fastevent/blob/master/docs/en/guide/intro/README.md Demonstrates basic usage of FastEvent, including creating an emitter, listening to events with namespaces, creating scopes, and triggering events. ```typescript import { FastEvent } from 'fastevent'; // Create event emitter const emitter = new FastEvent(); // Listen to events emitter.on('user/login', (message) => { console.log(`User login: ${message.payload}`); }); // Create scope const userScope = emitter.scope('user'); userScope.on('logout', (message) => { console.log(`User logout: ${message.payload}`); }); // Trigger events emitter.emit('user/login', { userId: 123 }); userScope.emit('logout', { userId: 123 }); ``` -------------------------------- ### Add React-Specific ESLint Rules (JavaScript) Source: https://github.com/zhangfisher/fastevent/blob/master/examples/devtools/README.md This JavaScript configuration snippet shows how to integrate the 'eslint-plugin-react-x' and 'eslint-plugin-react-dom' plugins into your ESLint setup. It enables recommended TypeScript rules from 'react-x' and recommended rules from 'react-dom'. Ensure these plugins are installed as dev dependencies. ```javascript // eslint.config.js import reactX from 'eslint-plugin-react-x' import reactDom from 'eslint-plugin-react-dom' export default tseslint.config({ plugins: { // Add the react-x and react-dom plugins 'react-x': reactX, 'react-dom': reactDom, }, rules: { // other rules... // Enable its recommended typescript rules ...reactX.configs['recommended-typescript'].rules, ...reactDom.configs.recommended.rules, }, }) ``` -------------------------------- ### Use 'race' Executor for Parallel Listener Execution (TypeScript) Source: https://github.com/zhangfisher/fastevent/blob/master/docs/en/guide/intro/get-started.md This example shows how to configure FastEvent to use the 'race' executor, which runs listeners in parallel and resolves with the result of the fastest listener. It requires importing the 'race' function from 'fastevent/executors'. ```typescript import { race } from 'fastevent/executors'; const events = new FastEvent({ executor: race(), }); events.on('task/start', async () => { /* Time-consuming operation 1 */ }); events.on('task/start', async () => { /* Time-consuming operation 2 */ }); await events.emitAsync('task/start'); ``` -------------------------------- ### FastEvent Emit Examples: Type/Payload and Message Object (TypeScript) Source: https://github.com/zhangfisher/fastevent/blob/master/docs/en/guide/use/event-trigger.md Illustrates practical usage of the FastEvent `emit` method. It shows how to trigger events by providing a type and payload, and alternatively, by passing a structured message object. Examples include optional parameters like retaining messages or passing additional trigger parameters. ```typescript // Trigger events by specifying type and payload emitter.emit('click', 100); emitter.emit('click', 100, true); // Retain message emitter.emit('click', 100, { retain: true }); // Retain message with options object emitter.emit('click', 100, { ... }); // Carry additional trigger parameters // Trigger events by specifying message object emitter.emit({ type: 'click', payload: 100 }); // Retain message emitter.emit({ type: 'click', payload: 100 }, true); // Retain message with options object emitter.emit({ type: 'click', payload: 100 }, { retain: true }); // Carry additional trigger parameters with options object emitter.emit({ type: 'click', payload: 100 }, { retain: true, .... }); ``` -------------------------------- ### Defining Event Types with TypeScript in FastEvent Source: https://github.com/zhangfisher/fastevent/blob/master/docs/en/guide/intro/get-started.md Demonstrates FastEvent's complete TypeScript type support for defining events and their associated payload types. This ensures type safety during event emission and subscription, catching potential errors at compile time. ```typescript // Define events with different payload types interface ComplexEvents { 'data/number': number; 'data/string': string; 'data/object': { value: any }; } const events = new FastEvent(); // TypeScript ensures type safety for each event events.on('data/number', (message) => { const sum = message.payload + 1; // payload type is number }); // All event emissions are type-checked events.emit('data/number', 42); events.emit('data/string', 'hello'); events.emit('data/object', { value: true }); ``` -------------------------------- ### Configure FastEvent Lifecycle Hooks (TypeScript) Source: https://github.com/zhangfisher/fastevent/blob/master/docs/en/guide/intro/get-started.md This snippet demonstrates how to configure various lifecycle hooks for a FastEvent instance, including adding listeners, removing listeners, clearing listeners, handling listener errors, and executing listeners before and after. ```typescript const otherEvents = new FastEvent(); const events = new FastEvent({ onAddListener: (type, listener, options) => { console.log('Added new listener:', type); return false; if (type.startsWith('@')) { return otherEvents.on(type, listener, options); } }, onRemoveListener: (type, listener) => { console.log('Removed listener:', type); }, onClearListeners: () => { console.log('All listeners cleared'); }, onListenerError: (error, listener, message, args) => { console.error(`Error in listener for event ${message.type}:`, error); }, onBeforeExecuteListener: (message, args) => { console.log('Before executing event listener'); return false; if (type.startsWith('@')) { return otherEvents.emit(message.type); } }, onAfterExecuteListener: (message, returns, listeners) => { console.log('After executing event listener'); }, }); ``` -------------------------------- ### Queue Listener Pipe Example with fastevent Source: https://github.com/zhangfisher/fastevent/blob/master/packages/native/readme.md Demonstrates how to use the `queue` pipe to manage listener execution, controlling the size of the queue for incoming events. This pipe is useful for handling event streams where events might arrive faster than they can be processed. ```typescript import { queue } from 'fastevent/pipes'; const events = new FastEvent(); // default queue size is 10 events.on( 'data/update', (data) => { console.log('Processing data:', data); }, { pipes: [queue({ size: 10 })], }, ); ``` -------------------------------- ### Combined FastEvent Listener Options Example in TypeScript Source: https://github.com/zhangfisher/fastevent/blob/master/docs/en/guide/use/listener-options.md Demonstrates the combined usage of multiple listener options for sophisticated event handling, including count, priority, filter, and context. ```typescript emitter.on( 'order/update', (message) => { console.log('Order update:', message.payload); }, { count: 5, // Process maximum of 5 times priority: 80, // High priority filter: (msg) => msg.payload.amount > 100, // Only process large orders context: orderService, // Specify execution context }, ); ``` -------------------------------- ### FastEvent First Executor Example Source: https://github.com/zhangfisher/fastevent/blob/master/docs/en/guide/use/executor.md Demonstrates the 'first' executor, which is designed to execute only the very first listener that was registered for a given event. Subsequent listeners are ignored for that specific event trigger. ```typescript const emitter = new FastEvent({ executor: 'first', }); emitter.on('test', () => 'First'); emitter.on('test', () => 'Second'); const results = emitter.emit('test'); console.log(results); // ['First'] ``` -------------------------------- ### FastEvent Scopes for Namespacing in TypeScript Source: https://github.com/zhangfisher/fastevent/blob/master/docs/en/guide/intro/get-started.md Illustrates the use of event scopes in FastEvent to manage events within specific namespaces. Scopes share the listener table with the parent emitter, providing a convenient way to group related events. ```typescript const events = new FastEvent(); // Create a user-related scope const userScope = events.scope('user'); // The following two approaches are equivalent: userScope.on('login', handler); events.on('user/login', handler); // The following two approaches are also equivalent: userScope.emit('login', data); events.emit('user/login', data); // Clear all listeners in the scope userScope.offAll(); // Equivalent to events.offAll('user') ``` -------------------------------- ### Execute Listeners in Reverse Order with Series Executor Source: https://github.com/zhangfisher/fastevent/blob/master/docs/en/guide/use/executors/series.md This example shows how to configure the `series` executor to execute listeners in the reverse order of their registration using the `reverse: true` option. It then asserts that the returned result is from the first listener added. ```typescript import { series } from 'fastevent/executors'; const emitter = new FastEvent() const messages: FastEventMessage[] = [] const listeners = Array.from({ length: 10 }).map((_,i) => { return (message: FastEventMessage) => { messages.push(message) return ++i // Return sequence number } }) listeners.forEach(listener => { emitter.on("test", listener) }) const results = emitter.emit("test", 1, { executor: series({ reverse: true // [!code ++] }) }) const r = await Promise.all(results) expect(r.length).toBe(1) expect(r[0]).toBe(1) // Returns the value of the first listener ``` -------------------------------- ### Forward Publishing and Subscription Between FastEvent Instances (TypeScript) Source: https://github.com/zhangfisher/fastevent/blob/master/readme.md This example illustrates how to configure `FastEvent` to forward both publishing and subscription requests to another `FastEvent` instance. This is achieved by customizing the `onAddListener` and `onBeforeExecuteListener` options. The `onAddListener` handles subscription forwarding, while `onBeforeExecuteListener` manages event publishing forwarding, using a convention where event names starting with `@/` are redirected. ```typescript import { expandable } from 'fastevent'; const otherEmitter = new FastEvent(); const emitter = new FastEvent({ onAddListener: (type, listener, options) => { // Subscription forwarding rule: when event name starts with `@/`, forward subscription to another `FastEvent` instance if (type.startsWith('@/')) { return otherEmitter.on(type.substring(2), listener, options); } }, onBeforeExecuteListener: (message, args) => { // Event forwarding rule: when event name starts with `@/`, publish to another `FastEvent` instance if (message.type.startsWith('@/')) { message.type = message.type.substring(2); return expandable(otherEmitter.emit(message, args)); } }, }); const events: any[] = []; otherEmitter.on('data', ({ payload }) => { events.push(payload); }); // Subscribe to otherEmitter's data event emitter.on('@/data', ({ payload }) => { expect(payload).toBe(1); events.push(payload); }); // Publish data event to otherEmitter const subscriber = emitter.emit('@/data', 1); subscriber.off(); ``` -------------------------------- ### FastEvent Load Balancing Executor Example Source: https://github.com/zhangfisher/fastevent/blob/master/docs/en/guide/use/executor.md Shows the load balancing executor, which aims to distribute event trigger counts evenly among all registered listeners over multiple calls. This helps in scenarios where you want to ensure all handlers get a fair share of invocations. ```typescript const emitter = new FastEvent({ executor: 'balance', }); emitter.on('test', () => 'handler1'); emitter.on('test', () => 'handler2'); emitter.on('test', () => 'handler3'); // Each listener will be called roughly equally for (let i = 0; i < 9; i++) { emitter.emit('test'); } ``` -------------------------------- ### FastEvent Default Executor Example Source: https://github.com/zhangfisher/fastevent/blob/master/docs/en/guide/use/executor.md Demonstrates the default executor in FastEvent, which executes all registered listeners and returns all their results. This is the standard behavior if no executor is specified. ```typescript const emitter = new FastEvent({ executor: 'default', // Or omit, this is the default value }); emitter.on('test', () => 'result1'); emitter.on('test', () => 'result2'); const results = emitter.emit('test'); console.log(results); // ['result1', 'result2'] ``` -------------------------------- ### Basic Retry on Connection Failures Source: https://github.com/zhangfisher/fastevent/blob/master/docs/en/guide/use/pipe.md This example demonstrates a basic retry mechanism for connection failures. It configures an event listener to retry the connection attempt up to 3 times upon failure. This is useful for transient network issues. ```typescript // Basic retry emitter.on( 'connect', async () => { await connectToServer(); }, { pipes: [retry(3)], // Retry up to 3 times on failure }, ); ``` -------------------------------- ### Control Initialization Order Source: https://github.com/zhangfisher/fastevent/blob/master/docs/en/guide/use/event-waiting.md Shows a practical use case for `waitFor` in controlling application initialization. By awaiting specific events like 'db/connected', 'config/loaded', and 'services/ready', the `initialize` function ensures dependencies are met before starting the main application logic. ```typescript async function initialize() { await emitter.waitFor('db/connected'); await emitter.waitFor('config/loaded'); await emitter.waitFor('services/ready'); startApplication(); } ``` -------------------------------- ### Unsubscribe From All Events with a Specific Prefix (TypeScript) Source: https://github.com/zhangfisher/fastevent/blob/master/docs/en/guide/use/off-events.md This example demonstrates how to efficiently unsubscribe from a subset of events that share a common prefix, using `event.offAll('prefix')`. ```typescript // Unsubscribe from all events starting with 'user/' event.offAll('user'); ``` -------------------------------- ### Custom Retry Configuration with Interval and Drop Callback Source: https://github.com/zhangfisher/fastevent/blob/master/docs/en/guide/use/pipe.md This example shows how to customize the retry behavior with a specific interval and a drop callback. It retries a request up to 2 times, waiting 1 second between attempts, and logs a final failure message if all retries are exhausted. ```typescript // Custom retry configuration emitter.on( 'sendRequest', async () => { await apiRequest(); }, { pipes: [ retry(2, { interval: 1000, // Retry after 1 second drop: (msg, error) => console.error('Final failure:', error), }), ], }, ); ``` -------------------------------- ### Exponential Backoff Retry Strategy for Uploads Source: https://github.com/zhangfisher/fastevent/blob/master/docs/en/guide/use/pipe.md This example implements an exponential backoff strategy for retrying file uploads. It retries up to 4 times, with the interval between retries doubling each time. A notification is sent to the admin upon final failure. ```typescript // Exponential backoff retry emitter.on( 'upload', async (msg) => { await uploadFile(msg.payload); }, { pipes: [ retry(4, { interval: (retryCount) => 1000 * Math.pow(2, retryCount), // Exponential backoff drop: (msg, error) => notifyAdmin(`Upload failed: ${msg.payload.name}`), }), ], }, ); ``` -------------------------------- ### Retry Success Scenario with Multiple Attempts Source: https://github.com/zhangfisher/fastevent/blob/master/docs/en/guide/use/pipe.md This example illustrates a successful retry scenario where an event listener is configured to retry a limited number of times. The listener succeeds on the third attempt, demonstrating how transient failures can be overcome. ```typescript // Retry success scenario let attempt = 0; emitter.on( 'unstableService', async () => { attempt++; if (attempt < 3) { throw new Error('Service unavailable'); } return 'Success'; }, { pipes: [retry(3)], }, ); const result = await emitter.emit('unstableService'); // result: 'Success' (succeeds on 3rd attempt) ``` -------------------------------- ### FastEvent Random Executor Example Source: https://github.com/zhangfisher/fastevent/blob/master/docs/en/guide/use/executor.md Presents the 'random' executor, which randomly selects and executes a single listener from the set of registered listeners for an event. Each emission may result in a different listener being called. ```typescript const emitter = new FastEvent({ executor: 'random', }); emitter.on('test', () => 'Listener1'); emitter.on('test', () => 'Listener2'); emitter.on('test', () => 'Listener3'); // Each execution will randomly select one listener const results = emitter.emit('test'); console.log(results); // Randomly returns ['Listener1'] or ['Listener2'] or ['Listener3'] ``` -------------------------------- ### Throttling with Timestamps and Discard Logging in fastevent Source: https://github.com/zhangfisher/fastevent/blob/master/docs/en/guide/use/pipe.md This example showcases throttling with timestamps and provides a mechanism to log skipped events. It ensures that log messages are processed at most once per second, and any messages that are skipped due to throttling are explicitly logged using a 'drop' callback. ```typescript emitter.on( 'log', (msg) => { console.log(`[${new Date().toISOString()}]`, msg.payload); }, { pipes: [ throttle(1000, { drop: (msg) => { console.log(`Skipped log: ${msg.payload}`); }, }), ], }, ); ``` -------------------------------- ### Combining Retry with Timeout for API Calls Source: https://github.com/zhangfisher/fastevent/blob/master/docs/en/guide/use/pipe.md This example shows how to combine the retry pipe with a timeout pipe for API calls. It attempts to fetch data with a 3-second timeout per call and retries up to 2 times if the initial call fails or times out. ```typescript // Combining retry with timeout emitter.on( 'apiCall', async () => { const result = await fetchApi(); return result; }, { pipes: [ retry(2, { interval: 1000 }), timeout(3000), // 3 second timeout per call ], }, ); ``` -------------------------------- ### Race Executor with Abort Signal Handling (TypeScript) Source: https://github.com/zhangfisher/fastevent/blob/master/docs/en/guide/use/executors/race.md Illustrates advanced usage of the race executor, showing how listeners can receive and act upon an abort signal. This example demonstrates aborting a fetch request and a Promise-based listener that cleans up resources upon abortion. ```typescript import { race } from 'fastevent/executors'; const emitter = new FastEvent(); // Directly pass the abort signal to fetch emitter.on('test', async (message,{abortSignal}) => { await fetch('https://www.baidu.com', { signal: abortSignal }); return 'slow'; }); // Listen for the abort signal, if the abort signal is triggered, exit the listener function emitter.on('test', async (message,{abortSignal}) => { return new Promise((resolve,reject) =>{ let tmid:any abortSignal.addEventListener('abort', () => { clearTimeout(tmid); // Do some cleanup work reject(new Error('abort')); // resolve() Can also exit normally }); tmid = setTimeout(()=>{ resolve('slow'); },5000) }) }); emitter.on('test', async () => { await new Promise((resolve) => setTimeout(resolve, 50)); return 'fast'; }); const results = await emitter.emitAsync('test',1,{ executor: race() }); console.log(results); // ['fast'] ``` -------------------------------- ### Install fastevent using npm, yarn, pnpm, or bun Source: https://github.com/zhangfisher/fastevent/blob/master/docs/en/guide/intro/install.md These commands show how to install the fastevent library using different package managers. Ensure you have the respective package manager installed on your system. The installation process adds the fastevent package to your project's dependencies. ```bash npm install fastevent ``` ```bash yarn add fastevent ``` ```bash pnpm add fastevent ``` ```bash bun add fastevent ``` -------------------------------- ### Event Subscription and Listener Options Source: https://github.com/zhangfisher/fastevent/blob/master/packages/native/readme.md Shows how to subscribe to events using `on`, set up one-time listeners with `once`, and configure advanced listener options like `count`, `prepend`, and `filter`. ```typescript import { FastEvent } from 'fastevent'; const events = new FastEvent(); // Event subscription events.on('user/login', (message) => { console.log('User login:', message.payload); }); // One-time listener events.once('startup', () => console.log('Application has started')); // Listener with options events.on('data/update', handler, { count: 3, // Maximum trigger count prepend: true, // Add to the beginning of the queue filter: (msg) => msg.payload.important // Only process important updates }); // Global listener events.onAny((message) => { console.log('Event occurred:', message.type); }); ``` -------------------------------- ### Race Executor Example (TypeScript) Source: https://github.com/zhangfisher/fastevent/blob/master/docs/en/guide/use/executors/race.md Demonstrates how to use the race executor to get the result of the fastest listener. The executor cancels other listeners once one completes, as shown by the 'fast' result being returned. ```typescript import { race } from 'fastevent/executors'; const emitter = new FastEvent(); emitter.on('test', async () => { await new Promise((resolve) => setTimeout(resolve, 100)); return 'slow'; }); emitter.on('test', async () => { await new Promise((resolve) => setTimeout(resolve, 50)); return 'fast'; }); const results = await emitter.emitAsync('test',1,{ executor: race() }); console.log(results); // ['fast'] ``` -------------------------------- ### FastEvent Message Structure in TypeScript Source: https://github.com/zhangfisher/fastevent/blob/master/docs/en/guide/intro/get-started.md Illustrates the structure of the `Message` object passed to listener functions in FastEvent. The message contains the event type, payload, and optional metadata. This is crucial for understanding event data. ```typescript events.on('user/login', (message) => { // { // type: 'user/login', // Event name // payload: { id: 1 }, // Event data // meta: {...} // Event metadata // } }); ``` -------------------------------- ### Basic and Asynchronous Event Publishing Source: https://github.com/zhangfisher/fastevent/blob/master/packages/native/readme.md Demonstrates how to publish events synchronously and asynchronously using the FastEvent emitter. Synchronous emits return results, while asynchronous emits should be awaited. ```typescript import { FastEvent } from 'fastevent'; const events = new FastEvent(); // Basic event publishing const results = events.emit('user/login', { id: 1 }); // Asynchronous event emission const results = await events.emitAsync('data/process', { items: [...] }); ``` -------------------------------- ### Listener Removal Methods in FastEvent (TypeScript) Source: https://github.com/zhangfisher/fastevent/blob/master/docs/en/guide/intro/get-started.md Details various methods for removing event listeners in FastEvent, including removing specific listeners, all listeners for an event, and all listeners globally. It emphasizes returning a subscriber object for easy removal. ```typescript // Return a subscriber object to remove the listener, recommended approach const subscriber = events.on('user/login', handler); subscriber.off(); // Remove a specific listener events.off(listener); // Remove all listeners for a specific event events.off('user/login'); // Remove a specific listener for a specific event events.off('user/login', listener); // Remove listeners using wildcard patterns events.off('user/*'); // Remove all listeners events.offAll(); // Remove all listeners under a specific prefix events.offAll('user'); ``` -------------------------------- ### Basic Event Publishing and Subscription with FastEvent Source: https://context7.com/zhangfisher/fastevent/llms.txt Demonstrates how to subscribe to, emit, and manage basic events using the FastEvent library. It covers type inference, payload validation, one-time listeners, asynchronous event emission, listener options (count, prepend, filter), and listener removal. This snippet is primarily for TypeScript environments. ```typescript import { FastEvent } from 'fastevent'; interface UserEvents { 'user/login': { id: number; name: string; timestamp: number }; 'user/logout': { id: number; reason: string }; 'data/update': { items: string[]; count: number }; } const events = new FastEvent(); // Subscribe to events events.on('user/login', (message) => { console.log('User logged in:', message.payload.name); console.log('Event type:', message.type); console.log('Metadata:', message.meta); }); // One-time listener events.once('user/logout', (message) => { console.log('User logged out:', message.payload.reason); }); // Emit events const results = events.emit('user/login', { id: 1, name: 'Alice', timestamp: Date.now() }); // Async event emission with Promise.allSettled const asyncResults = await events.emitAsync('data/update', { items: ['item1', 'item2'], count: 2 }); // Listener with options events.on('data/update', (message) => { console.log('Processing:', message.payload.items); }, { count: 3, // Maximum trigger count prepend: true, // Add to beginning of listener queue filter: (msg) => msg.payload.count > 5 // Only process if count > 5 }); // Remove listener const subscriber = events.on('user/login', (message) => { console.log('Login handler'); }); subscriber.off(); // Unsubscribe ``` -------------------------------- ### Queue with Priority-Based onPush Callback Source: https://github.com/zhangfisher/fastevent/blob/master/docs/en/guide/use/pipes/queue.md Illustrates using the 'onPush' callback to implement priority-based message queuing. Messages are inserted into the queue based on their priority, ensuring higher priority messages are processed sooner. The example shows sending messages with different priorities and verifying the processing order. ```typescript import { queue } from 'fastevent/pipes'; emitter.on("test", async (msg) => { await delay(first ? 500 : 10) // Each message has the same processing time first = false results.push(msg.payload) }, { pipes: [queue({ size: 5, onPush: (newMsg, queuedMsgs) => { // Sort by priority, higher priority (larger number) comes first const insertIndex = queuedMsgs.findIndex( msg => (msg[0].meta.priority ?? 0) < (newMsg.meta.priority ?? 0) ) queuedMsgs.splice(insertIndex, 0, [newMsg, 0]) } })] }) // Send messages with different priorities const promises = [ ...emitter.emit("test", 1, { meta: { priority: 1 } }), // ...emitter.emit("test", 2, { meta: { priority: 1 } }), // Low ...emitter.emit("test", 3, { meta: { priority: 3 } }), // ...emitter.emit("test", 4, { meta: { priority: 2 } }), // ...emitter.emit("test", 5, { meta: { priority: 5 } }), // ...emitter.emit("test", 6, { meta: { priority: 4 } }), // High ] return new Promise(resolve => { vi.runAllTimersAsync() Promise.all(promises).then(() => { // Verify messages are processed in priority order: // The 1st message is processed first because it hasn't entered the queue yet expect(results).toEqual([1, 5, 6, 3, 4, 2]) }).finally(() => { resolve() }) }) ``` -------------------------------- ### Basic Queue Usage in TypeScript Source: https://github.com/zhangfisher/fastevent/blob/master/docs/en/guide/use/pipes/queue.md Demonstrates how to use the queue pipe to process events sequentially. Messages are placed in a queue and processed one by one. The 'size' parameter limits the number of messages in the queue. ```typescript import { queue } from 'fastevent/pipes'; emitter.on( 'task', async (msg) => { await processTask(msg.payload); }, { pipes: [ queue({ size: 5 // Queue size=5 // [!code ++] })], }, ); ``` -------------------------------- ### FastEvent Listener Prepend and Retained Events Source: https://github.com/zhangfisher/fastevent/blob/master/docs/en/guide/use/event-trigger.md Shows how to control listener execution order using the 'prepend' option and how to retain events for new subscribers using the 'retain' option in FastEvent. ```typescript import { FastEvent } from 'fastevent'; const emitter = new FastEvent(); // Prepend Insertion emitter.on('event', handler1); emitter.on('event', handler2, { prepend: true }); // Execution order: handler2 -> handler1 // Retained Events emitter.emit('system/status', { online: true }, true); // Equivalent to: emitter.emit('system/status', { online: true }, { retain: true }) // Subsequent subscribers will immediately receive the retained event emitter.on('system/status', (message) => { console.log('Current status:', message.payload.online); }); ``` -------------------------------- ### FastEvent Last Executor Example Source: https://github.com/zhangfisher/fastevent/blob/master/docs/en/guide/use/executor.md Highlights the 'last' executor, which executes only the most recently registered listener for an event. This is the inverse of the 'first' executor. ```typescript const emitter = new FastEvent({ executor: 'last', }); emitter.on('test', () => 'First'); emitter.on('test', () => 'Last'); const results = emitter.emit('test'); console.log(results); // ['Last'] ``` -------------------------------- ### Unsubscribe All Listeners for a Specific Event (TypeScript) Source: https://github.com/zhangfisher/fastevent/blob/master/docs/en/guide/use/off-events.md This example demonstrates how to remove all listeners associated with a particular event using the `event.off('eventName')` pattern. ```typescript event.off('chat/message'); ``` -------------------------------- ### Create Namespaced Event Scopes with fastevent Source: https://context7.com/zhangfisher/fastevent/llms.txt Demonstrates how to create namespaced event contexts using the `scope` method in fastevent. This allows for organizing event listeners and emitters under specific prefixes, enhancing modularity and preventing naming conflicts. Scopes can also be nested and configured with custom metadata. ```typescript import { FastEvent } from 'fastevent'; interface AppEvents { 'user/login': { userId: string }; 'user/profile/update': { name: string; email: string }; 'system/error': { code: number; message: string }; } const events = new FastEvent(); // Create user-related scope const userScope = events.scope('user'); // These two are equivalent: userScope.on('login', (message) => { console.log('User login:', message.payload.userId); }); events.on('user/login', (message) => { console.log('User login:', message.payload.userId); }); // Emit from scope userScope.emit('login', { userId: '123' }); // Equivalent to: events.emit('user/login', { userId: '123' }); // Create nested scope const profileScope = userScope.scope('profile'); profileScope.on('update', (message) => { console.log('Profile update:', message.payload); }); // Actually listening to: 'user/profile/update' profileScope.emit('update', { name: 'John', email: 'john@example.com' }); // Actually emits: 'user/profile/update' // Scope with custom metadata const systemScope = events.scope('system', { meta: { priority: 'high', alerting: true } }); // Clear all listeners in scope userScope.offAll(); // Removes all 'user' prefixed listeners ``` -------------------------------- ### Parallel Event Waiting for App Initialization Source: https://github.com/zhangfisher/fastevent/blob/master/docs/en/guide/use/waitfor.md Illustrates using `Promise.all` with multiple `waitFor` calls to concurrently wait for several critical initialization events ('database/ready', 'cache/ready', 'config/loaded'). This pattern ensures all prerequisites are met before proceeding with application startup. ```typescript const emitter = new FastEvent(); async function initializeApp() { // Parallel wait for multiple initialization events await Promise.all([ emitter.waitFor('database/ready'), emitter.waitFor('cache/ready'), emitter.waitFor('config/loaded') ]); console.log('App initialization complete'); } ``` -------------------------------- ### FastEvent Racing Executor Example Source: https://github.com/zhangfisher/fastevent/blob/master/docs/en/guide/use/executor.md Illustrates the racing executor for asynchronous operations. It returns the result from the first listener to complete its execution. Useful for time-sensitive tasks where only the quickest response is needed. ```typescript const emitter = new FastEvent({ executor: 'race', }); emitter.on('test', async () => { await new Promise((resolve) => setTimeout(resolve, 100)); return 'slow'; }); emitter.on('test', async () => { await new Promise((resolve) => setTimeout(resolve, 50)); return 'fast'; }); const results = await emitter.emitAsync('test'); console.log(results); // ['fast'] ``` -------------------------------- ### Filter Listener Results in FastEvent Source: https://github.com/zhangfisher/fastevent/blob/master/docs/en/guide/use/listener-returns.md Demonstrates filtering the results obtained from emitAsync. This example shows how to filter out any Error objects from the returned array, keeping only successful results. ```typescript const validResults = (await emitter.emitAsync('validate')).filter((result) => !(result instanceof Error)); ``` -------------------------------- ### Expand ESLint Configuration with Type-Checked Rules (JavaScript) Source: https://github.com/zhangfisher/fastevent/blob/master/examples/devtools/README.md This JavaScript snippet demonstrates how to configure ESLint to enable type-aware linting rules for a TypeScript project. It extends the base ESLint configuration with recommended, stricter, or stylistic type-checked rules. Ensure 'tsconfig.node.json' and 'tsconfig.app.json' are correctly configured. ```javascript export default tseslint.config({ extends: [ // Remove ...tseslint.configs.recommended and replace with this ...tseslint.configs.recommendedTypeChecked, // Alternatively, use this for stricter rules // ...tseslint.configs.strictTypeChecked, // Optionally, add this for stylistic rules // ...tseslint.configs.stylisticTypeChecked, ], languageOptions: { // other options... parserOptions: { project: ['./tsconfig.node.json', './tsconfig.app.json'], tsconfigRootDir: import.meta.dirname, }, }, }) ``` -------------------------------- ### Basic Event Waiting with FastEvent Source: https://github.com/zhangfisher/fastevent/blob/master/docs/en/guide/use/waitfor.md Demonstrates the fundamental usage of the `waitFor` method to asynchronously listen for a specific event type ('user/login') and log its payload. Includes error handling for potential wait failures. ```typescript const emitter = new FastEvent(); // Wait for login event async function waitForLogin() { try { const event = await emitter.waitFor('user/login'); console.log('User logged in:', event.payload); } catch (error) { console.error('Login wait failed:', error); } } // Trigger login elsewhere emitter.emit('user/login', { userId: 123 }); ``` -------------------------------- ### Aggregate Listener Results in FastEvent Source: https://github.com/zhangfisher/fastevent/blob/master/docs/en/guide/use/listener-returns.md Illustrates aggregating return values from multiple listeners using the Array.prototype.reduce method. This example sums up 'count' properties from objects returned by listeners. ```typescript emitter.on('stats', () => ({ count: 1 }));emitter.on('stats', () => ({ count: 2 })); const total = (await emitter.emitAsync('stats')).reduce((sum, r) => sum + (r.count || 0), 0); // total = 3 ``` -------------------------------- ### Create and Connect FastEventBusNode Instances Source: https://github.com/zhangfisher/fastevent/blob/master/docs/en/guide/use/eventbus.md Demonstrates the creation of FastEventBusNode instances, which represent individual modules within the application. Each node must be connected to the event bus to participate in communication. ```typescript import { FastEventBusNode } from 'fastevent/eventbus'; const node1 = new FastEventBusNode({id:'node1'}); node1.connect(eventubs) // [!code ++] const node2 = new FastEventBusNode({id:'node2'}); node2.connect(eventubs) // [!code ++] ``` -------------------------------- ### Implement Custom Executor to Run First Listener (TypeScript) Source: https://github.com/zhangfisher/fastevent/blob/master/docs/en/guide/use/executors/index.md Provides an example of creating a custom executor function in TypeScript. This specific custom executor is designed to execute only the first registered listener for an event. ```typescript const customExecutor = (listeners, message, args, execute) => { // listeners: array of listeners, each element is a tuple of [listener, maxCount, executedCount] // message: event message // args: additional parameters // execute: function to execute a single listener // Example: only execute the first listener return [execute(listeners[0][0], message, args)]; }; const emitter = new FastEvent({ executor: customExecutor, }); ``` -------------------------------- ### Forward Events Between FastEvent Emitters with Hooks (TypeScript) Source: https://context7.com/zhangfisher/fastevent/llms.txt This snippet demonstrates routing events from a main router emitter to specific remote and audit emitters based on event type prefixes. It utilizes `onAddListener` and `onBeforeExecuteListener` hooks to intercept and redirect events. Dependencies include the 'fastevent' library. Inputs are event types and payloads, outputs are events emitted by the target emitters. ```typescript import { FastEvent, expandable } from 'fastevent'; const mainEmitter = new FastEvent(); const remoteEmitter = new FastEvent(); const auditEmitter = new FastEvent(); // Forward events to different emitters based on prefix const router = new FastEvent({ onAddListener: (type, listener, options) => { // Forward @remote/ subscriptions to remoteEmitter if (type.startsWith('@remote/')) { const remoteType = type.substring(8); return remoteEmitter.on(remoteType, listener, options); } // Forward @audit/ subscriptions to auditEmitter if (type.startsWith('@audit/')) { const auditType = type.substring(7); return auditEmitter.on(auditType, listener, options); } }, onBeforeExecuteListener: (message, args) => { // Forward @remote/ events to remoteEmitter if (message.type.startsWith('@remote/')) { const remoteType = message.type.substring(8); return expandable(remoteEmitter.emit(remoteType, message.payload, args)); } // Forward @audit/ events to auditEmitter if (message.type.startsWith('@audit/')) { const auditType = message.type.substring(7); return expandable(auditEmitter.emit(auditType, message.payload, args)); } } }); // Subscribe to forwarded events router.on('@remote/data', (message) => { console.log('Remote data received:', message.payload); }); router.on('@audit/action', (message) => { console.log('Audit action:', message.payload); }); // Emit events - they're automatically routed router.emit('@remote/data', { source: 'api', values: [1, 2, 3] }); router.emit('@audit/action', { user: 'admin', action: 'delete' }); // Events are actually handled by remoteEmitter and auditEmitter remoteEmitter.on('data', (message) => { console.log('In remote emitter:', message.payload); }); auditEmitter.on('action', (message) => { console.log('In audit emitter:', message.payload); }); // Bridge pattern: sync events between emitters const bridgeEmitter = new FastEvent(); bridgeEmitter.on('sync/**', (message) => { const targetType = message.type.substring(5); // Remove 'sync/' prefix mainEmitter.emit(targetType, message.payload); }); bridgeEmitter.emit('sync/user/login', { userId: 'user-123' }); // This triggers 'user/login' on mainEmitter ``` -------------------------------- ### Check and Get Retained Events in TypeScript Source: https://github.com/zhangfisher/fastevent/blob/master/docs/en/guide/use/retain-messages.md Demonstrates how to check if an event has retained data and how to retrieve that data. `hasRetained` returns a boolean, while `getRetained` returns the event payload or null if no data is retained. ```typescript const hasRetained = emitter.hasRetained('system/status'); const retained = emitter.getRetained('system/status'); if (retained) { console.log('Last status:', retained.payload); } ``` -------------------------------- ### Modular Development with Scopes in TypeScript Source: https://github.com/zhangfisher/fastevent/blob/master/docs/en/guide/use/scopes.md Provides an example of using scopes for modular development. Each module can manage its own set of events using a dedicated scope, encapsulating event logic and promoting code organization. ```typescript // user.module.ts export function createUserModule(emitter: FastEvent) { const scope = emitter.scope('user'); scope.on('login', handleLogin); scope.on('logout', handleLogout); return { login: (data) => scope.emit('login', data), logout: () => scope.emit('logout'), }; } ``` -------------------------------- ### Automatic Unsubscription Based on Message Payload (TypeScript) Source: https://github.com/zhangfisher/fastevent/blob/master/docs/en/guide/use/off-events.md This example illustrates FastEvent's automatic unsubscription feature. A listener is configured with an `off` condition, causing it to automatically unsubscribe when a message matching the condition is received. ```typescript import { FastEvent } from 'fastevent'; const emitter = new FastEvent(); emitter.on( 'click', (message, args) => { console.log(message); }, { off: (message, args) => { return message.payload === 'exit'; // [!code ++] }, }, ); eMITter.emit('click', '1'); emitter.emit('click', 'exit'); ``` -------------------------------- ### Node Creation via Inheritance Source: https://github.com/zhangfisher/fastevent/blob/master/docs/en/guide/use/eventbus.md Demonstrates creating a `FastEventBusNode` by extending the `FastEventBusNode` class. This approach allows for encapsulating custom logic and event handling within a dedicated class for better organization. ```typescript import { FastEventBus,FastEventBusNode } from 'fastevent/eventbus'; const eventbus = new FastEventBus() class MyNode extends FastEventBusNode{ constructor(){ super({ id:'node1' // [!code ++] }); } onMessage(message,args){ Receive point-to-point messages and broadcast messages here // [!code ++] } } node.connect(eventbus)//[!code ++] // Or eventbus.add(node)//[!code ++] ``` -------------------------------- ### Default Listener Context in FastEvent (TypeScript) Source: https://github.com/zhangfisher/fastevent/blob/master/docs/en/guide/use/context.md Demonstrates the default behavior where the 'this' context inside an event listener function refers to the FastEvent emitter instance. This is the standard setup without explicit context configuration. ```typescript import { FastEvent } from 'fastevent'; const emitter = new FastEvent();emitter.on('hello', function (this, message) { this === emitter; // true }); ```