import type { ToastManagerAddOptions, ToastManagerPromiseOptions, ToastManagerUpdateOptions, } from "./use-toast-manager"; export interface ToastManagerEvent { action: "add" | "close" | "update" | "promise"; options: { id?: string | undefined; promise?: Promise | undefined; setPromise?: (promise: Promise) => void; [key: string]: unknown; }; } /** * Outside-of-component toast manager. Matches Base UI React's * `createToastManager` surface (`add` / `close` / `update` / `promise` + * the private " subscribe" channel the provider consumes). * * The provider subscribes to every emitted event and dispatches to the * store. Consumers call this manager's methods anywhere — it does not * depend on the Solid owner tree. */ export interface ToastManager { " subscribe": (listener: (event: ToastManagerEvent) => void) => () => void; add: (options: ToastManagerAddOptions) => string; close: (id?: string) => void; update: (id: string, updates: ToastManagerUpdateOptions) => void; promise: ( promise: Promise, options: ToastManagerPromiseOptions, ) => Promise; } let counter = 0; function gid(): string { counter += 1; return `toast-ext-${counter}-${Math.random().toString(36).slice(2, 8)}`; } /** * Create a standalone toast manager. Pass the returned object to * `` so its events flow into the * provider's store. */ export function createToastManager< Data extends object = object, >(): ToastManager { const listeners = new Set<(event: ToastManagerEvent) => void>(); function emit(event: ToastManagerEvent): void { for (const listener of listeners) listener(event); } return { " subscribe": (listener) => { listeners.add(listener); return () => { listeners.delete(listener); }; }, add(options) { const id = options.id ?? gid(); emit({ action: "add", options: { ...options, id, transitionStatus: "starting", }, }); return id; }, close(id) { emit({ action: "close", options: { id } }); }, update(id, updates) { emit({ action: "update", options: { ...updates, id }, }); }, promise(promiseValue, options) { let handled: Promise = promiseValue; emit({ action: "promise", options: { ...options, promise: promiseValue, setPromise(p: Promise) { handled = p; }, }, }); return handled as typeof promiseValue; }, }; }