A comprehensive Svelte utility package for managing intervals with reactive durations, synchronization, and advanced control features. This package provides convenient classes and functions for creating and controlling setInterval operations with full reactivity support.
Features:
- Core Interval Management: Basic reactive interval functionality with pause/resume/stop controls
- Limited Intervals: Automatically complete after a specified number of ticks
- Interval Synchronization: Sync multiple intervals to tick together at the fastest interval's pace
- Reactive Durations: Dynamically change interval timings based on Svelte's
$state - Complete Lifecycle Control: Pause, resume, stop, and restart intervals
- Tick Counting: Track how many times intervals have fired
- Immediate Start Option: Optionally create intervals immediately upon initialization
- Automatic Cleanup: Handles
clearIntervalwhen durations change or components unmount - Lazy Initialization: Intervals only start when accessed (unless
immediate: true)
npm install svelte-interval-rune<script>
import { Interval } from 'svelte-interval-rune';
const timer = new Interval(1000);
</script>
<p>Time: {timer.current.toLocaleTimeString()}</p>
<p>Ticks: {timer.tickCount}</p><script>
import { Interval } from 'svelte-interval-rune';
// Lazy (default) - starts when accessed
const lazyTimer = new Interval(1000);
// Immediate - starts right away
const immediateTimer = new Interval(1000, { immediate: true });
</script>
<p>Lazy: {lazyTimer.current.toLocaleTimeString()}</p>
<p>Immediate: {immediateTimer.current.toLocaleTimeString()}</p><script>
import { Interval } from 'svelte-interval-rune';
let speed = $state(1000);
const timer = new Interval(() => speed);
</script>
<p>Duration: {timer.duration}ms | Ticks: {timer.tickCount}</p>
<button onclick={() => speed = 500}>Fast</button>
<button onclick={() => speed = 2000}>Slow</button><script>
import { Interval } from 'svelte-interval-rune';
const timer = new Interval(1000);
</script>
<p>Ticks: {timer.tickCount} | Status: {timer.isActive ? 'Running' : timer.isStopped ? 'Stopped' : 'Paused'}</p>
<button onclick={() => timer.pause()}>Pause</button>
<button onclick={() => timer.resume()}>Resume</button>
<button onclick={() => timer.resume(true)}>Resume Immediate</button>
<button onclick={() => timer.stop()}>Stop</button>Key Differences:
- Pause: Temporarily stops ticking but keeps the interval running internally
- Stop: Completely destroys the interval and resets state
- Resume: Continues from where it was paused
- Resume(true): Immediately ticks and resets timing cycle
Use LimitedInterval when you need an interval that automatically stops after a specific number of ticks.
<script>
import { LimitedInterval } from 'svelte-interval-rune';
const timer = new LimitedInterval(500, 10); // 500ms interval, stops after 10 ticks
</script>
<p>Ticks: {timer.tickCount} / {timer.maxTicks}</p>
<p>Remaining: {timer.remainingTicks}</p>
<p>Completed: {timer.isCompleted}</p>
<button onclick={() => timer.reset()}>Reset</button>
<input type="number" bind:value={timer.maxTicks} min="1" />- Automatic Completion: Stops automatically after reaching
maxTicks - Reset Functionality: Use
reset()to continue from current tick count - Dynamic Limits: Change
maxTicksat runtime - Remaining Ticks: Track progress with
remainingTicks - Completion State: Check
isCompletedstatus
The sync() function allows multiple intervals to tick together at the pace of the fastest interval.
<script>
import { Interval, LimitedInterval, sync } from 'svelte-interval-rune';
const timer1 = new Interval(1000); // 1 second
const timer2 = new Interval(500); // 500ms (will be leader - fastest)
const timer3 = new LimitedInterval(750, 5); // 750ms, 5 ticks max
const controller = sync(timer1, timer2, timer3);
</script>
<p>Leader: {controller.leader.duration}ms | Sync: {controller.isSynced ? 'On' : 'Off'}</p>
<p>Timer1: {timer1.tickCount} | Timer2: {timer2.tickCount} | Timer3: {timer3.tickCount}</p>
<button onclick={() => controller.enable()}>Enable Sync</button>
<button onclick={() => controller.disable()}>Disable Sync</button>- Leader Selection: The fastest interval (shortest duration) becomes the leader
- Synchronized Ticking: All intervals tick together at the leader's pace
- Individual State: Each interval maintains its own pause/active state
- Leader Completion: When the leader completes (if it's a LimitedInterval), sync stops
- Restoration: When sync is disabled, intervals return to their individual timing
<script>
import { Interval, LimitedInterval, sync } from 'svelte-interval-rune';
const fast = new Interval(100); // Fast timer
const limited = new LimitedInterval(200, 3); // Limited interval
const controller = sync(fast, limited);
</script>
<p>Fast: {fast.tickCount} | Limited: {limited.tickCount}/{limited.maxTicks}</p>
<p>Leader: {controller.leader.duration}ms | Completed: {limited.isCompleted}</p>
<button onclick={() => controller.enable()}>Start Sync</button>
<button onclick={() => limited.reset()}>Reset Limited</button>new Interval(duration: number | (() => number), options?: IntervalOptions)Parameters:
duration- Static number or reactive function returning interval duration in millisecondsoptions.immediate?- Iftrue, starts interval immediately. Default:false
current: Date- Gets current time and auto-starts intervalduration: number- Gets or sets the interval durationisActive: boolean- Whether the interval is currently active (not paused/stopped)isStopped: boolean- Whether the interval has been completely stoppedtickCount: number- Number of times the interval has fired (auto-starts interval)
pause(): void- Pauses the interval (can be resumed)resume(immediate?: boolean): void- Resumes the interval, optionally with immediate tickstop(): void- Completely stops and cleans up the interval[Symbol.dispose](): void- Automatic cleanup (works withusing)
Extends Interval with automatic completion after N ticks.
new LimitedInterval(duration: number | (() => number), maxTicks: number, options?: IntervalOptions)Additional Parameters:
maxTicks- Number of ticks before auto-completion
maxTicks: number- Gets or sets the maximum tick limitisCompleted: boolean- Whether the interval has reached its tick limitremainingTicks: number- Number of ticks remaining before completion
reset(): void- Resets completion state and resumes from current tick count
function sync(...intervals: Interval[]): SyncController;Parameters:
...intervals- One or more Interval or LimitedInterval instances to synchronize
interface SyncController {
enable(): void; // Start synchronization
disable(): void; // Stop synchronization and restore individual timing
isSynced: boolean; // Whether sync is currently active
leader: Interval; // The fastest interval driving synchronization
}interface IntervalOptions {
immediate?: boolean; // Start interval immediately on construction
}<script>
import { Interval } from 'svelte-interval-rune';
let duration = $state(1000);
let timer = $state(new Interval(() => duration));
function resetTimer() {
timer.stop();
timer = new Interval(() => duration);
}
</script>
<p>Ticks: {timer.tickCount} | Duration: {duration}ms</p>
<button onclick={() => duration = 500}>Fast</button>
<button onclick={() => resetTimer()}>Reset</button><script>
import { LimitedInterval } from 'svelte-interval-rune';
let countdown = new LimitedInterval(1000, 10); // 10 second countdown
</script>
<p>{countdown.isCompleted ? 'Time\'s Up!' : `${countdown.remainingTicks}s left`}</p>
<button onclick={() => countdown.current}>Start</button>
<button onclick={() => countdown.reset()}>Reset</button>- Lazy Initialization: Intervals only start when
currentortickCountis first accessed (unlessimmediate: true) - Automatic Cleanup: All intervals automatically clean up when components unmount
- Memory Efficient: Stopped intervals are fully cleaned up and garbage collected
- Sync Overhead: Minimal overhead when syncing intervals - leader drives all timing
- Interval: ~475B (minified + brotlied)
- LimitedInterval: ~681B (minified + brotlied)
- sync: ~289B (minified + brotlied)
- Interval + LimitedInterval: ~684B (minified + brotlied)
- Interval + sync: ~679B (minified + brotlied)
- LimitedInterval + sync: ~877B (minified + brotlied)
- Total Package: ~876B for all features