New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details →
Socket
Book a DemoSign in
Socket

shared-timer-manager

Package Overview
Dependencies
Maintainers
1
Versions
4
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

shared-timer-manager

Manage multiple timer tasks with a single SharedWebWorker

latest
Source
npmnpm
Version
1.0.3
Version published
Maintainers
1
Created
Source

Shared Timer Manager

Manage multiple timer tasks with a single SharedWebWorker. Perfect for handling recurring tasks like token refresh, inactivity detection, and sleep mode across your application.

Features

  • Single SharedWebWorker - All timers run in one worker, reducing overhead
  • Named Task Management - Easy to manage with unique task identifiers
  • Repeating & One-time Tasks - Flexible timer control
  • Cross-tab Synchronization - Shared timers across browser tabs
  • TypeScript Support - Full type definitions included
  • Zero Dependencies - Lightweight and fast
  • Framework Agnostic - Works with React, Vue, Angular, Svelte, and vanilla JS

Why use a SharedWorker for precise timing

Using a SharedWorker for scheduling time-sensitive tasks is often preferable to relying on setInterval/setTimeout on the main thread:

  • Runs off the main thread: timers in a SharedWorker are not blocked by main-thread work (UI rendering, long-running scripts), which reduces jitter and missed ticks.
  • Less affected by event-loop blocking: main-thread timers pause or drift when the event loop is busy; a worker provides an isolated execution context so scheduled tasks execute more reliably.
  • Cross-tab single source of truth: a SharedWorker can serve multiple tabs/windows, avoiding duplicated timers and reducing cumulative drift when the same task would otherwise run in many contexts.
  • Resource-efficient: centralizing timers avoids redundant timers across contexts and reduces overall CPU usage.
  • Background behavior: while browsers may throttle background activity, a SharedWorker centralizes coordination so connectivity-dependent tasks (e.g., token refresh) remain consistent across open pages.

Installation

npm install shared-timer-manager

Quick Start

1. Copy the worker file to your public directory

cp node_modules/shared-timer-manager/dist/shared-timer-worker.js public/

2. Use in your application

import TimerManager from 'shared-timer-manager';

// Initialize
const timerManager = new TimerManager('/shared-timer-worker.js');

// Add a repeating task
timerManager.addTimerTask(
  'token-refresh',
  15 * 60 * 1000, // 15 minutes
  () => {
    console.log('Refreshing token...');
    refreshToken();
  },
  true // repeats
);

// Add a one-time task
timerManager.addTimerTask(
  'inactivity-logout',
  5 * 60 * 1000, // 5 minutes
  () => {
    console.log('Logging out due to inactivity');
    logout();
  },
  false // doesn't repeat
);

// Clear a specific task
timerManager.clearTimerTask('token-refresh');

// Remove all tasks
timerManager.removeAllTimerTasks();

API Reference

Constructor

new TimerManager(workerPath)

Creates a new TimerManager instance.

Parameters:

  • workerPath (string, optional): Path to the shared worker file. Default: '/shared-timer-worker.js'

Example:

const timerManager = new TimerManager('/workers/shared-timer-worker.js');

Methods

addTimerTask(taskName, intervalTime, callback, canRepeat)

Adds a new timer task.

Parameters:

  • taskName (string): Unique identifier for the task
  • intervalTime (number): Interval in milliseconds
  • callback (function): Function to execute on each interval. Receives (taskName, timestamp) as arguments
  • canRepeat (boolean, optional): Whether the task should repeat. Default: true

Example:

timerManager.addTimerTask('my-task', 5000, (name, timestamp) => {
  console.log(`${name} executed at ${timestamp}`);
}, true);

clearTimerTask(taskName)

Clears a specific timer task.

Parameters:

  • taskName (string): Name of the task to clear

Example:

timerManager.clearTimerTask('my-task');

removeAllTimerTasks()

Removes all timer tasks.

Example:

timerManager.removeAllTimerTasks();

hasTask(taskName)

Check if a task exists.

Parameters:

  • taskName (string): Name of the task

Returns:

  • boolean: Whether the task exists

Example:

if (timerManager.hasTask('token-refresh')) {
  console.log('Token refresh task is active');
}

getActiveTasks()

Get list of active task names.

Returns:

  • Array<string>: Array of active task names

Example:

const tasks = timerManager.getActiveTasks();
console.log('Active tasks:', tasks); // ['token-refresh', 'inactivity-logout']

ping(taskName)

Check if the worker is connected (health check).

Parameters:

  • taskName (string, optional): Task name for ping. Default: 'health-check'

Returns:

  • boolean: Connection status

Example:

const isConnected = timerManager.ping();

Common Use Cases

Access Token Refresh

Automatically refresh authentication tokens at regular intervals:

timerManager.addTimerTask(
  'token-refresh',
  15 * 60 * 1000, // Every 15 minutes
  async () => {
    try {
      await refreshAccessToken();
      console.log('Token refreshed successfully');
    } catch (error) {
      console.error('Token refresh failed:', error);
    }
  },
  true
);

Inactivity Logout

Log out users after a period of inactivity:

function setupInactivityTimer() {
  timerManager.addTimerTask(
    'inactivity-logout',
    5 * 60 * 1000, // 5 minutes
    () => {
      console.log('User inactive - logging out');
      logout();
    },
    false
  );
}

// Reset timer on user activity
const resetTimer = () => {
  timerManager.clearTimerTask('inactivity-logout');
  setupInactivityTimer();
};

document.addEventListener('mousemove', resetTimer);
document.addEventListener('keydown', resetTimer);
document.addEventListener('click', resetTimer);

// Initialize
setupInactivityTimer();

Sleep Mode

Reduce backend requests after inactivity:

function setupSleepMode() {
  timerManager.addTimerTask(
    'sleep-mode',
    5 * 60 * 1000, // 5 minutes
    () => {
      console.log('Activating sleep mode');
      activateSleepMode();
      // Stop non-critical API polling
      stopBackgroundSync();
    },
    false
  );
}

// Reset on user activity
const resetSleepMode = () => {
  if (timerManager.hasTask('sleep-mode')) {
    timerManager.clearTimerTask('sleep-mode');
    deactivateSleepMode();
    setupSleepMode();
  }
};

window.addEventListener('focus', resetSleepMode);
document.addEventListener('visibilitychange', () => {
  if (!document.hidden) {
    resetSleepMode();
  }
});

setupSleepMode();

Framework Integration

React

Create a custom hook for easy integration:

// hooks/useTimerManager.js
import { useEffect, useRef } from 'react';
import TimerManager from 'shared-timer-manager';

export function useTimerManager() {
  const timerManagerRef = useRef(null);

  useEffect(() => {
    timerManagerRef.current = new TimerManager('/shared-timer-worker.js');

    return () => {
      timerManagerRef.current?.removeAllTimerTasks();
    };
  }, []);

  return timerManagerRef.current;
}

// Usage in component
function App() {
  const timerManager = useTimerManager();

  useEffect(() => {
    if (timerManager) {
      timerManager.addTimerTask('token-refresh', 15 * 60 * 1000, () => {
        refreshToken();
      }, true);
    }
  }, [timerManager]);

  return <div>My App</div>;
}

Vue 3 (Composition API)

// composables/useTimerManager.js
import { onUnmounted } from 'vue';
import TimerManager from 'shared-timer-manager';

const timerManager = new TimerManager('/shared-timer-worker.js');

export function useTimerManager() {
  onUnmounted(() => {
    timerManager.removeAllTimerTasks();
  });

  return {
    addTask: (name, interval, callback, repeat = true) => 
      timerManager.addTimerTask(name, interval, callback, repeat),
    clearTask: (name) => timerManager.clearTimerTask(name),
    removeAll: () => timerManager.removeAllTimerTasks(),
    hasTask: (name) => timerManager.hasTask(name),
    getActiveTasks: () => timerManager.getActiveTasks()
  };
}

// Usage in component
<script setup>
import { onMounted } from 'vue';
import { useTimerManager } from '@/composables/useTimerManager';

const { addTask, clearTask } = useTimerManager();

onMounted(() => {
  addTask('token-refresh', 15 * 60 * 1000, () => {
    console.log('Refreshing token...');
  });
});
</script>

Angular

// services/timer-manager.service.ts
import { Injectable, OnDestroy } from '@angular/core';
import TimerManager from 'shared-timer-manager';

@Injectable({
  providedIn: 'root'
})
export class TimerManagerService implements OnDestroy {
  private timerManager: TimerManager;

  constructor() {
    this.timerManager = new TimerManager('/shared-timer-worker.js');
  }

  addTask(name: string, interval: number, callback: Function, repeat = true): void {
    this.timerManager.addTimerTask(name, interval, callback as any, repeat);
  }

  clearTask(name: string): void {
    this.timerManager.clearTimerTask(name);
  }

  removeAllTasks(): void {
    this.timerManager.removeAllTimerTasks();
  }

  hasTask(name: string): boolean {
    return this.timerManager.hasTask(name);
  }

  getActiveTasks(): string[] {
    return this.timerManager.getActiveTasks();
  }

  ngOnDestroy(): void {
    this.timerManager.removeAllTimerTasks();
  }
}

// Usage in component
export class AppComponent {
  constructor(private timerService: TimerManagerService) {
    this.timerService.addTask('token-refresh', 15 * 60 * 1000, () => {
      console.log('Refreshing token...');
    }, true);
  }
}

Svelte

// stores/timerStore.js
import { onDestroy } from 'svelte';
import TimerManager from 'shared-timer-manager';

const timerManager = new TimerManager('/shared-timer-worker.js');

export function useTimer() {
  onDestroy(() => {
    timerManager.removeAllTimerTasks();
  });

  return timerManager;
}

// Usage in component
<script>
  import { onMount } from 'svelte';
  import { useTimer } from './stores/timerStore';
  
  const timer = useTimer();
  
  onMount(() => {
    timer.addTimerTask('my-task', 5000, () => {
      console.log('Timer tick!');
    }, true);
  });
</script>

Vanilla JavaScript

import TimerManager from 'shared-timer-manager';

const timerManager = new TimerManager('/shared-timer-worker.js');

// Add tasks
timerManager.addTimerTask('periodic-sync', 30000, () => {
  syncData();
}, true);

// Clear when needed
document.getElementById('stop-btn').addEventListener('click', () => {
  timerManager.clearTimerTask('periodic-sync');
});

Browser Support

SharedWebWorker is supported in:

  • ✅ Chrome/Edge 4+
  • ✅ Firefox 29+
  • ✅ Safari 16+
  • ❌ Internet Explorer (not supported)

Note: For browsers that don't support SharedWebWorker, consider implementing a fallback using regular setInterval or Web Workers.

TypeScript Support

This package includes TypeScript definitions. No additional types package needed!

import TimerManager from 'shared-timer-manager';

const timerManager: TimerManager = new TimerManager('/shared-timer-worker.js');

timerManager.addTimerTask(
  'my-task',
  5000,
  (taskName: string, timestamp: number) => {
    console.log(`Task ${taskName} executed at ${timestamp}`);
  },
  true
);

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

  • Fork the repository
  • Create your feature branch (git checkout -b feature/amazing-feature)
  • Commit your changes (git commit -m 'Add some amazing feature')
  • Push to the branch (git push origin feature/amazing-feature)
  • Open a Pull Request

License

MIT © [Dario Espina]

Support

If you encounter any issues or have questions:

  • 📝 Open an issue
  • 💬 Start a discussion

Changelog

1.0.0

  • Initial release
  • Support for multiple timer tasks with single SharedWebWorker
  • Cross-tab synchronization
  • TypeScript support
  • Framework-agnostic implementation

Keywords

timer

FAQs

Package last updated on 15 Jan 2026

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts