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

@financedistrict/idle-session

v0.1.1

Published

Cross-tab idle-timeout detection for FD apps — tracks aggregate inactivity across every open tab on the same origin and fires a callback once none of them have seen activity for the configured timeout.

Readme

@financedistrict/idle-session

Cross-tab idle-timeout detection for FD apps. Every FD app that mounts this hook on the same origin (e.g. everything under apps.test.1stdigital.tech) shares one idle clock: activity in any open tab keeps the session alive; only once every tab has been quiet for the configured timeout does onIdle fire.

Why cross-tab, not per-tab

A per-tab timer logs a user out while they're actively working in a different tab on the same origin — this package exists specifically to avoid that. It broadcasts activity through a shared localStorage key (not the usual app-namespaced kind — the whole point is that every app reads and writes the same one) and reconciles across tabs via the storage event, plus a visibilitychange recheck to catch up when a backgrounded tab's own timer gets throttled by the browser.

Usage

import { useIdleSession } from "@financedistrict/idle-session";
import { useMsal } from "@azure/msal-react";

function App() {
  const { instance } = useMsal();

  useIdleSession({
    timeoutMs: 15 * 60 * 1000, // 15 minutes
    onIdle: () => instance.logoutRedirect(),
  });

  return <Routes />;
}

Mount the hook once, near the root, alongside the other session-scoped providers. onIdle is expected to end the session — an MSAL logout is the norm — the hook itself never touches auth state or calls MSAL.

API

useIdleSession({
  timeoutMs: number; // required — ms of aggregate cross-tab inactivity before onIdle fires
  onIdle: () => void; // required — called once, in every open tab, when the timeout is reached
  activityEvents?: string[]; // default: mousedown, mousemove, keydown, scroll, touchstart, wheel
  activityThrottleMs?: number; // default: 1000 — how often activity is broadcast to other tabs
  checkIntervalMs?: number; // default: 5000 — how often each tab re-derives elapsed idle time
  storagePrefix?: string; // default: "fd:idle-session" — shared across every app on the origin;
  // override only if this app deliberately wants its own, isolated idle clock
  enabled?: boolean; // default: true
});

onIdle fires once per tab, per idle period. A tab that already fired won't fire again until fresh activity resumes the shared clock — in practice a page reload after logout resets this naturally.

If you pass a custom activityEvents array, memoize it (useMemo): it's a dependency of the hook's internal effect, so a fresh array identity on every render resubscribes the listeners every render.

What this package does not do

  • It does not call MSAL, or decide what "logged out" means for your app — that's onIdle's job.
  • It does not show a "you're about to be logged out" warning before firing. A product that wants one needs a second, shorter-fused useIdleSession call (or a follow-up to this package) — not built in here.
  • Like a route guard, this is a UX affordance, not a security control: actual session and token lifetime are enforced by MSAL and the BFF, not by this timer. A tampered or bypassed client-side timer never grants extra access.