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
JavaScript
/**
* 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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