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.
203 lines • 14.4 kB
JavaScript
/**
* Time Algebra - Clock ticks and temporal operations
* Extends Effect with time-based operations
*/
import { effect } from '../core/effect';
/**
* Creates a Time effect with temporal operations
*/
export const time = (initial) => {
const baseEffect = effect(initial);
const timeInstance = {
value: baseEffect.value,
map: baseEffect.map,
subscribe: baseEffect.subscribe,
bind: baseEffect.bind,
chain: baseEffect.chain,
_set: baseEffect._set,
delay: (ms) => {
const delayed = time(baseEffect.value());
setTimeout(() => {
delayed._set(baseEffect.value());
}, ms);
// Subscribe to original changes with delay
baseEffect.subscribe((newValue) => {
setTimeout(() => {
delayed._set(newValue);
}, ms);
});
return delayed;
},
timeout: (ms) => {
const timedOut = time(baseEffect.value());
let hasCompleted = false;
// Set timeout
const timeoutId = setTimeout(() => {
if (!hasCompleted) {
timedOut._set(new Error(`Timeout after ${ms}ms`));
}
}, ms);
// Subscribe to original completion
baseEffect.subscribe((newValue) => {
if (!hasCompleted) {
hasCompleted = true;
clearTimeout(timeoutId);
timedOut._set(newValue);
}
});
return timedOut;
},
interval: (ms) => {
const intervalTime = time(baseEffect.value());
let intervalId;
let subscriberCount = 0;
let tickCount = 0;
// Create a new Time object with custom subscribe
const customIntervalTime = {
...intervalTime,
subscribe: (fn) => {
subscriberCount++;
// Start interval when first subscriber is added
if (subscriberCount === 1) {
intervalId = setInterval(() => {
tickCount++;
// Force a change by setting a slightly different value
// For primitive types, we can append tick count
const currentValue = baseEffect.value();
if (typeof currentValue === 'number') {
intervalTime._set((currentValue + tickCount * 0.000001));
}
else if (typeof currentValue === 'string') {
intervalTime._set((currentValue + ''));
}
else {
// For objects, create a new reference
intervalTime._set({
...currentValue,
_tick: tickCount,
});
}
}, ms);
}
const unsubscribe = intervalTime.subscribe(fn);
return () => {
subscriberCount--;
if (subscriberCount === 0 && intervalId) {
clearInterval(intervalId);
}
unsubscribe();
};
},
};
return customIntervalTime;
},
// Compatibility methods for factories
now: () => baseEffect.value(),
update: () => {
// Force an update by setting the current value
baseEffect._set(baseEffect.value());
},
};
return timeInstance;
};
/**
* Creates a current time effect that updates with the current timestamp
*/
export const currentTime = () => {
const timeEffect = time(Date.now());
// Override the now method to return current timestamp
const currentTimeEffect = {
...timeEffect,
now: () => Date.now(),
update: () => {
timeEffect._set(Date.now());
},
};
return currentTimeEffect;
};
/**
* Creates a delayed effect
*/
export const delay = (ms, value) => {
return time(value).delay(ms);
};
/**
* Creates a timeout effect
*/
export const timeout = (ms, effect) => {
const timeEffect = time(effect.value());
effect.subscribe((value) => timeEffect._set(value));
return timeEffect.timeout(ms);
};
/**
* Creates an interval effect
*/
export const interval = (ms, value) => {
const intervalTime = time(value);
let intervalId;
let subscriberCount = 0;
let tickCount = 0;
// Create a new Time object with custom subscribe
const customIntervalTime = {
...intervalTime,
subscribe: (fn) => {
subscriberCount++;
// Start interval when first subscriber is added
if (subscriberCount === 1) {
intervalId = setInterval(() => {
tickCount++;
// Force a change by setting a slightly different value
if (typeof value === 'number') {
intervalTime._set((value + tickCount * 0.000001));
}
else if (typeof value === 'string') {
intervalTime._set((value + ''));
}
else {
// For objects, create a new reference
intervalTime._set({ ...value, _tick: tickCount });
}
}, ms);
}
const unsubscribe = intervalTime.subscribe(fn);
return () => {
subscriberCount--;
if (subscriberCount === 0 && intervalId) {
clearInterval(intervalId);
}
unsubscribe();
};
},
};
return customIntervalTime;
};
/**
* Debounce utility using Time algebra
*/
export const debounce = (ms, effect) => {
const debounced = time(effect.value());
let timeoutId;
effect.subscribe((newValue) => {
clearTimeout(timeoutId);
timeoutId = setTimeout(() => {
debounced._set(newValue);
}, ms);
});
return debounced;
};
/**
* Throttle utility using Time algebra
*/
export const throttle = (ms, effect) => {
const throttled = time(effect.value());
let lastExecution = 0;
effect.subscribe((newValue) => {
const now = Date.now();
if (now - lastExecution >= ms) {
throttled._set(newValue);
lastExecution = now;
}
});
return throttled;
};
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGltZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9hbGdlYnJhcy90aW1lLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7R0FHRztBQUVILE9BQU8sRUFBVSxNQUFNLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQVdoRDs7R0FFRztBQUNILE1BQU0sQ0FBQyxNQUFNLElBQUksR0FBRyxDQUFJLE9BQVUsRUFBMEMsRUFBRTtJQUM1RSxNQUFNLFVBQVUsR0FBRyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUM7SUFFbkMsTUFBTSxZQUFZLEdBQTJDO1FBQzNELEtBQUssRUFBRSxVQUFVLENBQUMsS0FBSztRQUN2QixHQUFHLEVBQUUsVUFBVSxDQUFDLEdBQUc7UUFDbkIsU0FBUyxFQUFFLFVBQVUsQ0FBQyxTQUFTO1FBQy9CLElBQUksRUFBRSxVQUFVLENBQUMsSUFBSTtRQUNyQixLQUFLLEVBQUUsVUFBVSxDQUFDLEtBQUs7UUFDdkIsSUFBSSxFQUFFLFVBQVUsQ0FBQyxJQUFJO1FBRXJCLEtBQUssRUFBRSxDQUFDLEVBQVUsRUFBVyxFQUFFO1lBQzdCLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQztZQUV6QyxVQUFVLENBQUMsR0FBRyxFQUFFO2dCQUNkLE9BQU8sQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUM7WUFDbkMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1lBRVAsMkNBQTJDO1lBQzNDLFVBQVUsQ0FBQyxTQUFTLENBQUMsQ0FBQyxRQUFRLEVBQUUsRUFBRTtnQkFDaEMsVUFBVSxDQUFDLEdBQUcsRUFBRTtvQkFDZCxPQUFPLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO2dCQUN6QixDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUM7WUFDVCxDQUFDLENBQUMsQ0FBQztZQUVILE9BQU8sT0FBTyxDQUFDO1FBQ2pCLENB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