Overview
Middleware handlers receive events when:- A listener is added to an observable
- A listener is removed from an observable
- All listeners are cleared from an observable
Type Signatures
Basic Usage
Event Types
listener-added
Fired when a listener is added to an observable:listener-removed
Fired when a listener is removed from an observable:listeners-cleared
Fired when all listeners are cleared from an observable:Multiple Handlers
You can register multiple handlers for the same event type:Event Batching
Middleware events are batched and processed in a microtask for better performance:Node-Specific Events
Middleware is registered per-node, so events don’t bubble up the tree:Error Handling
Errors in middleware handlers are caught and logged without affecting other handlers:Use Cases
Debugging Listener Leaks
Track when listeners are added/removed to detect memory leaks:Performance Monitoring
Measure the number of active listeners:Custom Sync Logic
Implement custom behavior when observables become active or inactive:DevTools Integration
Integrate with browser DevTools or debugging tools:Event Validation
Middleware events are validated before being dispatched:listener-added: Only fired if the listener is actually in the node’s listener setlistener-removed: Only fired if the listener was successfully removedlisteners-cleared: Only fired if all listeners are truly cleared
Performance Considerations
- Batching: Events are batched in microtasks to avoid excessive handler calls
- Fast path: If no handlers are registered, event dispatch is skipped entirely
- Weak references: Handler maps use WeakMap to avoid memory leaks
- Array pooling: Internal arrays are reused to minimize allocations
Best Practices
- Clean up handlers: Always call the unregister function when you’re done
- Keep handlers lightweight: Middleware runs frequently, so keep handlers fast
- Use specific event types: Register only for events you need
- Handle errors: Wrap handler logic in try/catch if it might throw
- Avoid side effects: Don’t modify observables inside middleware handlers
Related
- getNode() - Get the internal node of an observable
- onChange() - Listen to observable changes
- observe() - Track observable access