UNPKG

guardz-event

Version:

Type-safe event handling with runtime validation using guardz for unsafe data from 3rd parties

138 lines 6.45 kB
import type { TypeGuardFn } from 'guardz'; export interface EventOptions<T> { onSuccess: (data: T) => void; onError?: (message: string) => void; onTypeMismatch?: (message: string) => void; onSecurityViolation?: (origin: string, message: string) => void; tolerance?: boolean; allowedOrigins?: string[]; allowedSources?: string[]; identifier?: string; } export interface EventGuardOptions<T> extends EventOptions<T> { guard: TypeGuardFn<T>; } /** * Create a safe event handler for any event type * Usage: window.addEventListener('message', onEvent('message', isChatMessage, { onSuccess: handleData })) */ export declare function onEvent<T>(eventType: string, guard: TypeGuardFn<T>, options: EventOptions<T>): (event: Event) => void; /** * Create a safe message event handler * Usage: window.addEventListener('message', onMessage(isChatMessage, { onSuccess: handleData })) */ export declare function onMessage<T>(guard: TypeGuardFn<T>, options: EventOptions<T>): (event: MessageEvent) => void; /** * Create a safe DOM event handler * Usage: element.addEventListener('click', onClick(isClickData, { onSuccess: handleClick })) */ export declare function onClick<T>(guard: TypeGuardFn<T>, options: EventOptions<T>): (event: Event) => void; /** * Create a safe custom event handler * Usage: element.addEventListener('custom-event', onCustom('custom-event', isCustomData, { onSuccess: handleData })) */ export declare function onCustom<T>(eventType: string, guard: TypeGuardFn<T>, options: EventOptions<T>): (event: CustomEvent) => void; /** * Create a safe storage event handler * Usage: window.addEventListener('storage', onStorage(isStorageData, { onSuccess: handleStorage })) */ export declare function onStorage<T>(guard: TypeGuardFn<T>, options: EventOptions<T>): (event: StorageEvent) => void; export declare class EventGuard<T = unknown> { private eventType; private guard?; private options; type(eventType: string): EventGuard<T>; validate<U>(guard: TypeGuardFn<U>): EventGuard<U>; onSuccess(callback: (data: T) => void): EventGuard<T>; onError(callback: (message: string) => void): EventGuard<T>; onTypeMismatch(callback: (message: string) => void): EventGuard<T>; onSecurityViolation(callback: (origin: string, message: string) => void): EventGuard<T>; tolerance(enabled?: boolean): EventGuard<T>; allowedOrigins(origins: string[]): EventGuard<T>; allowedSources(sources: string[]): EventGuard<T>; identifier(id: string): EventGuard<T>; build(): (event: Event) => void; } /** * Create a fluent event guard builder * Usage: eventGuard().type('message').validate(isChatMessage).onSuccess(handleData).build() */ export declare function eventGuard<T = unknown>(): EventGuard<T>; export interface UseEventOptions<T> extends Omit<EventOptions<T>, 'onSuccess'> { onSuccess?: (data: T) => void; } export interface UseEventResult<T> { data: T | null; error: string | null; isLoading: boolean; refetch: () => void; } /** * React hook for safe event handling * Usage: const { data, error } = useEvent('message', isChatMessage, { tolerance: true }) * * Note: This is a framework-agnostic implementation. For React integration, * you would need to wrap this with React's useEffect and useState hooks. * * Example React implementation: * ```tsx * function useSafeEvent<T>(eventType: string, guard: TypeGuardFn<T>, options: UseEventOptions<T> = {}) { * const [data, setData] = useState<T | null>(null); * const [error, setError] = useState<string | null>(null); * const [isLoading, setIsLoading] = useState(false); * * useEffect(() => { * const handler = onEvent(eventType, guard, { * onSuccess: (data) => { * setData(data); * setError(null); * setIsLoading(false); * options.onSuccess?.(data); * }, * onError: (message) => { * setError(message); * setIsLoading(false); * options.onError?.(message); * }, * onTypeMismatch: options.onTypeMismatch, * onSecurityViolation: options.onSecurityViolation, * tolerance: options.tolerance, * allowedOrigins: options.allowedOrigins, * allowedSources: options.allowedSources, * identifier: options.identifier, * }); * * // Add event listener * window.addEventListener(eventType, handler); * * // Cleanup * return () => window.removeEventListener(eventType, handler); * }, [eventType, guard, options]); * * return { data, error, isLoading, refetch: () => setIsLoading(true) }; * } * ``` */ export declare function useEvent<T>(eventType: string, guard: TypeGuardFn<T>, options?: UseEventOptions<T>): UseEventResult<T>; /** * Create a safe event handler with minimal configuration * Usage: window.addEventListener('message', safeHandler(isChatMessage, handleData)) */ export declare function safeHandler<T>(guard: TypeGuardFn<T>, onSuccess: (data: T) => void, onError?: (message: string) => void): (event: Event) => void; /** * Create a safe event handler with tolerance mode * Usage: window.addEventListener('message', safeTolerant(isChatMessage, handleData, handleError)) */ export declare function safeTolerant<T>(guard: TypeGuardFn<T>, onSuccess: (data: T) => void, onError?: (message: string) => void): (event: Event) => void; /** * Infer the event data type from a guard function */ export type InferEventData<T> = T extends TypeGuardFn<infer U> ? U : never; /** * Create a typed event handler factory */ export declare function createTypedHandler<T>(guard: TypeGuardFn<T>): (options: EventOptions<T>) => (event: Event) => void; export { safeDOMEvent, safeWebSocket, safeEventSource, safeEvent, SafeEventBuilder, safe, createSafeEventContext, type SafeEventContext, type SafeEventContextConfig, type InferEventDataType, createTypedSafeDOMEvent, createTypedSafePostMessage, createTypedSafeWebSocket, createTypedSafeEventSource, createTypedSafeCustomEvent, createTypedSafeStorageEvent, safePostMessageListener, safeWebSocketListener, safeDOMEventListener, safeEventSourceListener, safeCustomEventListener, safeStorageEventListener, type SafeEventListenerConfig, type ErgonomicEventListenerConfig, type ErrorContext, } from './utils/safe-event-never-throws'; export * from './utils/additional-sources'; export { Status } from './domain/event/Status'; //# sourceMappingURL=index.d.ts.map