@mirawision/observer
v1.0.1
Published
A lightweight and flexible observer pattern implementation for TypeScript, providing a simple way to implement event-driven architecture with type safety.
Readme
@mirawision/observer
A lightweight and flexible observer pattern implementation for TypeScript, providing a simple way to implement event-driven architecture with type safety. This library offers a clean and intuitive API for implementing the observer pattern in your applications.
Features
- Type Safety: Full TypeScript support with generic types for type-safe event data
- Simple API: Clean and intuitive interface for subscribing, unsubscribing, and notifying observers
- Memory Efficient: Uses Set for efficient observer management and automatic cleanup
- Flexible: Generic implementation allows for any data type to be passed to observers
- Lightweight: Minimal footprint with no external dependencies
- Unsubscribe Support: Individual and bulk unsubscribe methods for proper cleanup
Installation
npm install @mirawision/observeror
yarn add @mirawision/observerUsage
Basic Example
import { Observer } from '@mirawision/observer';
// Create an observer instance for string events
const observer = new Observer<string>();
// Subscribe to events
const listener1 = (data: string) => {
console.log('Listener 1 received:', data);
};
const listener2 = (data: string) => {
console.log('Listener 2 received:', data);
};
observer.subscribe(listener1);
observer.subscribe(listener2);
// Notify all observers
observer.notify('Hello, World!');
// Output:
// Listener 1 received: Hello, World!
// Listener 2 received: Hello, World!Working with Custom Types
import { Observer } from '@mirawision/observer';
// Define a custom type for your events
interface UserEvent {
id: number;
name: string;
action: 'login' | 'logout';
}
// Create an observer for your custom type
const userObserver = new Observer<UserEvent>();
// Subscribe with type-safe listeners
userObserver.subscribe((event: UserEvent) => {
console.log(`User ${event.name} (ID: ${event.id}) performed ${event.action}`);
});
// Notify with type-safe data
userObserver.notify({
id: 123,
name: 'John Doe',
action: 'login'
});
// Output: User John Doe (ID: 123) performed loginManaging Subscriptions
import { Observer } from '@mirawision/observer';
const observer = new Observer<number>();
const listener = (data: number) => {
console.log('Received:', data);
};
// Subscribe
observer.subscribe(listener);
// Notify
observer.notify(42);
// Output: Received: 42
// Unsubscribe specific listener
observer.unsubscribe(listener);
// Notify again (no output since listener was removed)
observer.notify(100);
// Unsubscribe all listeners
observer.unsubscribeAll();Real-world Example: Event System
import { Observer } from '@mirawision/observer';
// Define event types
interface AppEvent {
type: 'user-login' | 'user-logout' | 'data-update';
payload: any;
timestamp: Date;
}
// Create a global event bus
class EventBus {
private observer = new Observer<AppEvent>();
subscribe(listener: (event: AppEvent) => void) {
this.observer.subscribe(listener);
}
unsubscribe(listener: (event: AppEvent) => void) {
this.observer.unsubscribe(listener);
}
emit(event: AppEvent) {
this.observer.notify(event);
}
}
// Usage
const eventBus = new EventBus();
// Subscribe to events
eventBus.subscribe((event) => {
console.log(`[${event.timestamp.toISOString()}] ${event.type}:`, event.payload);
});
// Emit events
eventBus.emit({
type: 'user-login',
payload: { userId: 123, username: 'john' },
timestamp: new Date()
});
eventBus.emit({
type: 'data-update',
payload: { items: ['item1', 'item2'] },
timestamp: new Date()
});React Integration Example
import React, { useEffect, useState } from 'react';
import { Observer } from '@mirawision/observer';
// Create a global observer for app state
const appStateObserver = new Observer<{ theme: 'light' | 'dark' }>();
function ThemeToggle() {
const [theme, setTheme] = useState<'light' | 'dark'>('light');
useEffect(() => {
const handleThemeChange = (data: { theme: 'light' | 'dark' }) => {
setTheme(data.theme);
};
appStateObserver.subscribe(handleThemeChange);
// Cleanup on unmount
return () => {
appStateObserver.unsubscribe(handleThemeChange);
};
}, []);
const toggleTheme = () => {
const newTheme = theme === 'light' ? 'dark' : 'light';
appStateObserver.notify({ theme: newTheme });
};
return (
<button onClick={toggleTheme}>
Current theme: {theme}
</button>
);
}API Reference
Observer
A generic observer class that manages a collection of listeners for a specific data type.
Methods
subscribe(observer: ObserverListener<T>): void- Adds a listener to the observer
- The listener will be called whenever
notify()is called
unsubscribe(observer: ObserverListener<T>): void- Removes a specific listener from the observer
- Useful for cleanup to prevent memory leaks
unsubscribeAll(): void- Removes all listeners from the observer
- Clears the entire observer collection
notify(data: T): void- Notifies all subscribed listeners with the provided data
- Calls each listener function with the data parameter
Type Definitions
type ObserverListener<T> = (data: T) => void;
class Observer<T> {
// ... methods
}Contributing
Contributions are always welcome! Feel free to open issues or submit pull requests.
License
This project is licensed under the MIT License.
