Store Subscription Model
Relevant source files
The following files were used as context for generating this wiki page:
The Store Subscription Model in the @pcstyle/toast library is a centralized state management system designed to handle the lifecycle of notification toasts. It utilizes an observer pattern to decouple the logic of adding, updating, and removing notifications from the UI components that render them. This architecture ensures that toast state remains synchronized across the application regardless of where a notification is triggered.
The core of this model is the ToastStore class, which maintains an internal list of active toasts and a list of subscriber functions. By using a subscription-based approach, the system allows the ToastProvider to reactively update the UI whenever the store's state changes.
Core Architecture
The architecture is built around a singleton store instance that acts as the "Source of Truth" for all toast notifications.
ToastStore Class
The ToastStore manages an array of Toast objects and a collection of Observer callbacks. It provides methods to modify the state and notify all active subscribers.
Sources: src/store.ts:21-61
Data Structures
The store utilizes specific interfaces to ensure type safety, particularly for the different types of notifications and the structure of individual toast objects.
| Type/Interface | Properties / Values | Description |
|---|---|---|
ToastType | success, error, info, warning, loading, default | Categorizes the toast for styling and behavior logic. |
Toast | id, message, type, duration?, action? | The primary data object representing a notification. |
Observer | (toasts: Toast[]) => void | Callback function type used for subscriptions. |
Sources: src/store.ts:5-19
Subscription Mechanism
The subscription mechanism allows React components to hook into the store's lifecycle. The ToastProvider uses the useEffect hook to register a state-setter function as an observer when the component mounts.
Subscription Flow
- Registration: A component calls
toastStore.subscribe(), passing a callback function. - Unsubscription: The
subscribemethod returns a cleanup function that filters the observer out of the internal list. - Notification: Whenever
add,remove, orupdateis called, the store executesnotify(), which iterates through all observers with a fresh copy of thetoastsarray.
Sources: src/store.ts:25-36, src/provider.tsx:16-19
Notification Lifecycle Management
The store is responsible for more than just storage; it handles automatic dismissal and constraints on the number of active notifications.
Automatic Dismissal
When a toast is added via the add() method, the store automatically sets a timeout to call remove() after the specified duration (defaulting to 4000ms), unless the toast type is loading.
Display Constraints
To prevent UI clutter, the store enforces a maximum limit of 5 visible toasts at any given time. This is managed during the addition of new items by slicing the array.
add(toast: Omit<Toast, "id">) {
const id = Math.random().toString(36).substring(2, 9);
const newToast = { ...toast, id };
this.toasts = [newToast, ...this.toasts].slice(0, 5); // Limit to 5 visible
this.notify();
if (toast.type !== "loading") {
setTimeout(() => this.remove(id), toast.duration || 4000);
}
return id;
}
Sources: src/store.ts:38-51
Integration with Public API
The toast utility functions exported from the library act as a high-level wrapper around the ToastStore singleton instance.
| Function | Store Method Called | Behavior |
|---|---|---|
toast() | add() | Creates a default type toast. |
toast.error() | add() | Creates an error type toast. |
toast.dismiss() | remove() | Manually removes a toast by ID. |
toast.promise() | add() then update() | Tracks a promise, updating the toast state on resolution or rejection. |
Sources: src/index.ts:10-53
Promise Handling Flow
The toast.promise function demonstrates the update capability of the subscription model. It creates a "loading" toast and subsequently modifies its properties based on the asynchronous result of a provided promise.
Sources: src/index.ts:36-53
Summary
The Store Subscription Model provides a robust foundation for the PCSTYLE toast system by separating state logic from React's rendering cycle. By using a class-based store with an observer pattern, the library achieves strict type safety (as required by cubic.yaml) and a clean, imperative API for developers while maintaining reactive UI updates through the ToastProvider.
Sources: src/store.ts, src/provider.tsx, cubic.yaml:24-26