UNPKG

resig.js

Version:

Universal reactive signal library with complete platform features: signals, animations, CRDTs, scheduling, DOM integration. Works identically across React, SolidJS, Svelte, Vue, and Qwik.

308 lines 22.6 kB
/** * Plugin Engine - Zero-runtime cost category functors * Each plugin is a category functor that rewrites the AST lazily */ import { debounce, throttle } from '../algebras/time'; /** * Debounce plugin - delays signal updates */ export const debouncePlugin = (ms) => (signal) => { return debounce(ms, signal); }; /** * Throttle plugin - limits signal update frequency */ export const throttlePlugin = (ms) => (signal) => { return throttle(ms, signal); }; /** * Cache plugin - caches signal values in localStorage */ export const cachePlugin = (key, ttl = 300000) => (signal) => { // Try to load from cache try { const cached = localStorage.getItem(`signal_cache_${key}`); const cacheTime = localStorage.getItem(`signal_cache_time_${key}`); if (cached && cacheTime) { const age = Date.now() - parseInt(cacheTime); if (age < ttl) { // Return cached signal const cachedSignal = signal.map(() => JSON.parse(cached)); return cachedSignal; } } } catch (e) { // Cache read failed, proceed without cache } // Subscribe to signal changes and cache them signal.subscribe((value) => { try { localStorage.setItem(`signal_cache_${key}`, JSON.stringify(value)); localStorage.setItem(`signal_cache_time_${key}`, Date.now().toString()); } catch (e) { // Cache write failed, continue without caching } }); return signal; }; /** * Logger plugin - logs signal changes */ export const loggerPlugin = (prefix = 'Signal') => (signal) => { signal.subscribe((value) => { console.log(`${prefix}:`, value); }); return signal; }; /** * Filter plugin - only emits values that pass predicate */ export const filterPlugin = (predicate) => (signal) => { return signal.map((value) => (predicate(value) ? value : signal.value())); }; /** * Transform plugin - applies transformation to signal values */ export const transformPlugin = (transform) => (signal) => { return signal.map(transform); }; /** * Validation plugin - validates signal values */ export const validatePlugin = (validator, onError) => (signal) => { signal.subscribe((value) => { if (!validator(value)) { onError?.(value); } }); return signal; }; /** * Persistence plugin - persists signal state */ export const persistPlugin = (key) => (signal) => { // Load initial state from storage try { const stored = localStorage.getItem(`persist_${key}`); if (stored) { const parsedValue = JSON.parse(stored); // Create new signal with stored value const persistedSignal = signal.map(() => parsedValue); // Subscribe to changes and persist them persistedSignal.subscribe((value) => { try { localStorage.setItem(`persist_${key}`, JSON.stringify(value)); } catch (e) { // Persist failed, continue without persistence } }); return persistedSignal; } } catch (e) { // Load failed, proceed with original signal } // Subscribe to changes and persist them signal.subscribe((value) => { try { localStorage.setItem(`persist_${key}`, JSON.stringify(value)); } catch (e) { // Persist failed, continue without persistence } }); return signal; }; /** * Compose multiple plugins */ export const compose = (...plugins) => (signal) => { return plugins.reduce((acc, plugin) => plugin(acc), signal); }; /** * Apply plugin to signal */ export const apply = (plugin) => (signal) => { return plugin(signal); }; /** * Conditional plugin application */ export const when = (condition, plugin) => (signal) => { return condition ? plugin(signal) : signal; }; /** * Plugin that applies different plugins based on signal value */ export const switchPlugin = (selector, plugins, defaultPlugin) => (signal) => { const currentValue = signal.value(); const key = selector(currentValue); const selectedPlugin = plugins[key] || defaultPlugin; return selectedPlugin ? selectedPlugin(signal) : signal; }; /** * Async plugin - handles async operations with loading states */ export const asyncPlugin = (asyncFn, initialValue) => (signal) => { const asyncSignal = signal.map(() => ({ data: initialValue, loading: false, error: undefined, })); signal.subscribe(async (value) => { // Set loading state asyncSignal._set({ data: asyncSignal.value().data, loading: true, error: undefined, }); try { const result = await asyncFn(value); asyncSignal._set({ data: result, loading: false, error: undefined, }); } catch (error) { asyncSignal._set({ data: asyncSignal.value().data, loading: false, error: error instanceof Error ? error : new Error(String(error)), }); } }); return asyncSignal; }; /** * Validation plugin with real-time feedback */ export const validationPlugin = (validator, onValidChange) => (signal) => { const validatedSignal = signal.map((value) => ({ value, isValid: validator(value), })); if (onValidChange) { validatedSignal.subscribe(({ isValid }) => onValidChange(isValid)); } return validatedSignal; }; /** * State machine plugin */ export const stateMachinePlugin = (initialState, reducer) => (actionSignal) => { let currentState = initialState; const stateSignal = actionSignal.map(() => currentState); actionSignal.subscribe((action) => { currentState = reducer(currentState, action); stateSignal._set(currentState); }); return stateSignal; }; /** * Fetch plugin - HTTP operations with retry and caching */ export const fetchPlugin = (fetcher, options = {}) => (triggerSignal) => { const { retries = 0, cacheKey, cacheTtl = 300000 } = options; const fetchSignal = triggerSignal.map(() => ({ data: undefined, loading: false, error: undefined, })); const performFetch = async (attempt = 0) => { // Check cache first if (cacheKey) { try { const cached = localStorage.getItem(`fetch_cache_${cacheKey}`); const cacheTime = localStorage.getItem(`fetch_cache_time_${cacheKey}`); if (cached && cacheTime) { const age = Date.now() - parseInt(cacheTime); if (age < cacheTtl) { fetchSignal._set({ data: JSON.parse(cached), loading: false, error: undefined, }); return; } } } catch (e) { // Cache read failed, proceed with fetch } } fetchSignal._set({ data: fetchSignal.value().data, loading: true, error: undefined, }); try { const result = await fetcher(); // Cache the result if (cacheKey) { try { localStorage.setItem(`fetch_cache_${cacheKey}`, JSON.stringify(result)); localStorage.setItem(`fetch_cache_time_${cacheKey}`, Date.now().toString()); } catch (e) { // Cache write failed, continue without caching } } fetchSignal._set({ data: result, loading: false, error: undefined, }); } catch (error) { if (attempt < retries) { // Retry after delay setTimeout(() => performFetch(attempt + 1), 1000 * Math.pow(2, attempt)); } else { fetchSignal._set({ data: fetchSignal.value().data, loading: false, error: error instanceof Error ? error : new Error(String(error)), }); } } }; triggerSignal.subscribe(() => performFetch()); return fetchSignal; }; /** * Built-in plugin combinations */ export const commonPlugins = { /** * Debug plugin - combines logging and validation */ debug: (name, validator) => compose(loggerPlugin(`Debug[${name}]`), validator ? validatePlugin(validator, (value) => console.warn(`Invalid value in ${name}:`, value)) : (s) => s), /** * Performance plugin - combines debounce and cache */ performance: (key, debounceMs = 100, cacheTtl = 300000) => compose(debouncePlugin(debounceMs), cachePlugin(key, cacheTtl)), /** * Persistent state plugin - combines persistence and validation */ persistentState: (key, validator) => compose(persistPlugin(key), validator ? validatePlugin(validator) : (s) => s), /** * Form field plugin - combines validation, debouncing, and persistence */ formField: (key, validator, debounceMs = 300) => compose(debouncePlugin(debounceMs), validationPlugin(validator), persistPlugin(key)), /** * API data plugin - combines fetch, caching, and error handling */ apiData: (fetcher, cacheKey, retries = 3) => compose(fetchPlugin(fetcher, { retries, cacheKey }), loggerPlugin(`API[${cacheKey}]`)), /** * Real-time data plugin - combines debouncing and logging for live updates */ realTime: (name, debounceMs = 100) => compose(debouncePlugin(debounceMs), loggerPlugin(`RealTime[${name}]`)), }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvcGx1Z2lucy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7O0dBR0c7QUFFSCxPQUFPLEVBQUUsUUFBUSxFQUFFLFFBQVEsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBTXREOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sY0FBYyxHQUN6QixDQUFJLEVBQVUsRUFBYSxFQUFFLENBQzdCLENBQUMsTUFBaUIsRUFBRSxFQUFFO0lBQ3BCLE9BQU8sUUFBUSxDQUFDLEVBQUUsRUFBRSxNQUFtQixDQUFDLENBQUM7QUFDM0MsQ0FBQyxDQUFDO0FBRUo7O0dBRUc7QUFDSCxNQUFNLENBQUMsTUFBTSxjQUFjLEdBQ3pCLENBQUksRUFBVSxFQUFhLEVBQUUsQ0FDN0IsQ0FBQyxNQUFpQixFQUFFLEVBQUU7SUFDcEIsT0FBTyxRQUFRLENBQUMsRUFBRSxFQUFFLE1BQW1CLENBQUMsQ0FBQztBQUMzQyxDQUFDLENBQUM7QUFFSjs7R0FFRztBQUNILE1BQU0sQ0FBQyxNQUFNLFdBQVcsR0FDdEIsQ0FBSSxHQUFXLEVBQUUsTUFBYyxNQUFNLEVBQWEsRUFBRSxDQUNwRCxDQUFDLE1BQWlCLEVBQUUsRUFBRTtJQUNwQix5QkFBeUI7SUFDekIsSUFBSSxDQUFDO1FBQ0gsTUFBTSxNQUFNLEdBQUcsWUFBWSxDQUFDLE9BQU8sQ0FBQyxnQkFBZ0IsR0FBRyxFQUFFLENBQUMsQ0FBQztRQUMzRCxNQUFNLFNBQVMsR0FBRyxZQUFZLENBQUMsT0FBTyxDQUFDLHFCQUFxQixHQUFHLEVBQUUsQ0FBQyxDQUFDO1FBRW5FLElBQUksTUFBTSxJQUFJLFNBQVMsRUFBRSxDQUFDO1lBQ3hCLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsR0FBRyxRQUFRLENBQUMsU0FBUyxDQUFDLENBQUM7WUFDN0MsSUFBSSxHQUFHLEdBQUcsR0FBRyxFQUFFLENBQUM7Z0JBQ2Qs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