npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@leonardocodes/user-away

v1.1.0

Published

Detects user idle/inactivity via activity-event timestamps — accurate even in throttled background tabs, unlike timer-based approaches.

Readme

Purpose

This library is used to track user idle activity and respond to those events when they occur. Since it uses rxjs, the events can be piped to react to multiple stages of the idle lifecycle. For example, you can configure a five minute idle detection listener which displays a notice of idle detection, then subsequently start an additional two minute listener which executes some action such as logging a user out.

NPM install

npm install @leonardocodes/user-away

Mechanism

The library uses timestamps instead of timers so that it can still function when the application is throttled or timed-out by the system. The following are the events which reset the idle counter:

  • mousemove
  • mousedown
  • mousewheel
  • DOMMouseScroll
  • keydown
  • touchstart
  • touchmove
  • MSPointerDown
  • MSPointerMove
  • wheel
  • -visibilityChange

Examples

React to inactivity

const  t1  =  new  TrackUser(5000);

t1.startIdleTracking().subscribe(event  =>  {
    console.log('You were idle for 5 seconds');
    console.log(`Started idle: ${event.idleStartTimestamp}`);
    console.log(`Became inactive:${event.inactiveTimestamp}`);
});

Chain idle events

t1.startIdleTracking()
    .pipe(
        tap(() => console.log('Warning you are idle and will be logged out in 5 seconds.')),
        switchMap(() => t2.startIdleTracking())
    )
    .subscribe(() => console.log('You were logged out'));

Stop idle tracking

const t1 = new TrackUser(5000);
const t2 = new TrackUser(5000);

t1.startIdleTracking()
    .pipe(
        tap(() => console.log('Warning you are idle and will be logged out in 5 seconds.')),
        switchMap(() => t2.startIdleTracking())
    )
    .subscribe(() => {
        console.log('You were logged out');
        t1.stopIdleTracking();
        t2.stopIdleTracking();
    });

Use

To get started you can import create an idle tracker object as follows.

import  { TrackUser }  from  '@leonardocodes/user-away'
const  t1  =  new  TrackUser(1000);

Here we configure a tracker "t1" which is the handler which we can use to listen to and react to events. The constructor takes a parameter which is the duration of time in milliseconds for which we will use to consider the user as inactive. In addition, we can pass additional arguments.

constructor(idleTimeMs:  number, element:  HTMLElement  =  document.body, pollIntervalMs:  number  =  250)
  • idleTimeMs: This is the only required argument. It specifies the duration of idle time before we consider the user inactive.
  • element: The HTML element to which we will listen for events. By default it uses the document.body element.
  • pollIntervalMs: This is the poll interval which determines how often we check the idle start timestamp to the current datetime.

To start tracking the idle status of the user we call

t1.startIdleTracking()

This method returns an observable of type IsInactiveEvent. We could then subscribe to the method call and react to the users inactivity.

The IsInactiveEvent provides two properties which include:

  • idleStartTimestamp: A Date object which includes the timestamp of when the users last input occurred and idle count started.
  • inactiveTimestamp: A Date object which includes the timestamp of when the user became inactive.

Idle tracking does not stop after after the IsInactiveEvent emits, it will keep tracking idle state and loop through indefinetley. There are multiple ways we can stop tracking the idle state including rxjs mechanisms such as (take(), takeUntilDestroyed() etc). The library also includes:

public  stopIdleTracking():  void

This method completes the observable and destroys the internal subscription.

The trackers also expose the observables for idle and inactivity detection for use in other locations of your application:

  • idleStart$: This observable emits when the idle period starts (After users last input). It emits an object with a timestamp property of when the idle period started.
  • idleStopped$: This observable emits when the idle period is stops due to user input. It emits an object with a timestamp property of when the idle period stopped.
  • inactive$: This observable emits when the idle period has elapsed and the user is considered inactive. It emits an object with a two properties, a timestamp of when the tracker started to idle and a timestamp of when the tracker became inactive.

Example:

t1.idleStart$.subscribe(event => {
    console.log(`Idle started on ${event.timestamp}`);
});
t1.idleStopped$.subscribe(event => {
    console.log(`Idle stopped on ${event.timestamp}`);
});
t1.inactive$.subscribe(event => {
    console.log(`Idle started on ${event.idleStartTimestamp}`);
    console.log(`Inactive on ${event.inactiveTimestamp}`);
});

Lastly, the library class also exposes inactiveTimestamp which is of type Date or undefined and contains the timestamp of when the tracker became inactive.

console.log(t1.inactiveTimestamp ? `Inactive since: ${t1.inactiveTimestamp}` : `Not inactive`);