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

@stackonward/identity-browser

v0.0.2

Published

Framework-neutral browser client for opaque identity sessions

Readme

@stackonward/identity-browser

Framework-neutral browser client for a same-origin opaque identity-session contract. It validates server projections, owns CSRF synchronization, exposes a subscribable session store, and converts WebAuthn challenges into browser API requests.

The browser never receives access tokens or refresh tokens through this API.

Install

pnpm add @stackonward/identity-browser @stackonward/identity-session

Quick start

import { IdentityBrowserClient } from "@stackonward/identity-browser";

const identity = new IdentityBrowserClient({ basePath: "/api/onex" });

const unsubscribe = identity.store.subscribe((session) => {
  renderSession(session);
});

const session = await identity.getSession();
await identity.login({ email, password });

basePath must be a relative same-origin path. Requests always use credentials: "include" and manual redirect handling.

Operations

| Area | Methods | | ------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | | Session | getSession, logout | | Registration and login | register, login, loginWithOAuth | | MFA and WebAuthn | verifyMfa, beginWebAuthn, finishWebAuthn | | Guest identity | createGuest, requestGuestActivation | | Verification and recovery | verifyEmail, resendVerification, requestPasswordRecovery, verifyPasswordRecoveryCode, exchangePasswordRecoveryLink, resetPassword | | Account | changePassword, updateProfile, requestAccountDeletion, cancelAccountDeletion |

Each mutation first synchronizes the server-authoritative session, extracts its CSRF token, and then sends the command. Mutations are never replayed automatically.

WebAuthn

import {
  isWebAuthnAssertionSupported,
  requestWebAuthnAssertion,
} from "@stackonward/identity-browser";

if (isWebAuthnAssertionSupported()) {
  const challenge = await identity.beginWebAuthn();
  const action = challenge.next_action;
  if (action?.type === "webauthn" && action.public_key_credential_request_options) {
    const assertion = await requestWebAuthnAssertion(
      action.public_key_credential_request_options,
      navigator.credentials,
    );
    await identity.finishWebAuthn(assertion);
  }
}

The WebAuthn helpers validate request options, decode base64url fields, call the Credentials API, and serialize the assertion. Failures are classified by WebAuthnAssertionError as unsupported, invalid options, credential-request failure, or invalid credential.

Coordination and lifecycle

  • Concurrent session operations share one exclusive coordinator.
  • Browsers use the Web Locks API so same-origin contexts do not interleave a session read and mutation.
  • Non-browser test runtimes use a process-local coordinator.
  • Request waits are bounded from 500 to 30,000 milliseconds; the default is 10,000.
  • IdentitySessionStore.load deduplicates concurrent loads, and subscribe returns an unsubscribe function.
  • Call the returned unsubscribe function when the owning UI lifecycle ends.

Browser runtimes fail closed when the Web Locks API is unavailable. There is no uncoordinated mutation fallback.

Errors and session invalidation

IdentityBrowserError exposes type, code, HTTP status, optional param, field errors, and decoded retry delay. Responses must use the declared JSON media type and exact identity projection shape.

A canonical HTTP 401 authentication_error clears the in-memory projection immediately. Transient upstream failures preserve the last projection and do not trigger mutation replay. logout clears the local store even if the remote operation fails.

Public API

The main entry exports IdentityBrowserClient, IdentitySessionStore, IdentityBrowserError, challenge-selection helpers, WebAuthn helpers, and the browser-safe contracts re-exported from @stackonward/identity-session.

Compatibility

  • Node.js 20 or newer for the package runtime contract
  • Modern browsers with Fetch, Web Locks, WebAuthn, and Credentials APIs for the corresponding operations
  • ESM with TypeScript declarations

Related packages

  • @stackonward/identity-session owns shared contracts and the server engine.
  • @stackonward/onex-identity-nuxt provides the complete OneX Nuxt BFF integration.

License

MIT