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

@panomapp/arc

v0.1.3

Published

Camera-readable ARC authentication toolkit for shared grid rendering, Vue scanning flows, Express server routes, and realistic end-to-end simulations.

Readme

@panomapp/arc

Camera-readable ARC authentication toolkit.

ARC sign-in demo

@panomapp/arc packages the full ARC stack in one place:

  • shared grid and detection primitives
  • Vue client helpers for rendering and camera scanning
  • Express-friendly server routes
  • realistic testing and simulation utilities

It is designed for device-linking flows like WhatsApp Web or Steam Guard, where one device shows a short-lived visual code and another authenticated device scans it.

Installation

Install only the entrypoints you need.

npm install @panomapp/arc

Optional peer dependencies:

  • vue for @panomapp/arc/client
  • express for @panomapp/arc/server

Package entrypoints

@panomapp/arc

Shared types and low-level helpers:

  • applyArcAnchors
  • payloadBits
  • hammingDistance
  • renderArcToPixels
  • detectArcPatternFromRgba
  • makeArcFixtures
  • makeArcScenarios

@panomapp/arc/client

Vue-facing client helpers:

  • createArcHttpClient()
  • useArcAuthScanner()
  • useArcSlotPlayback()
  • createArcScannerEngine()

@panomapp/arc/server

Server helpers:

  • createArcRouter()
  • createArcRouteHarness()
  • createArcChallenge()
  • getArcChallengeStatus()
  • scanArcPattern()
  • bindArcChallengeUser()

@panomapp/arc/testing

Simulation and self-test helpers:

  • runArcCameraRoundTrip()
  • runArcDifficultySweep()
  • runArcRealisticAuthLoop()
  • runArcNetworkProfileSweep()
  • runArcStartupSelfTests()

Quick start

1. Server

import express, { Router } from 'express';
import {
  createArcRouter,
} from '@panomapp/arc/server';

const app = express();

app.use('/auth/arc', createArcRouter({
  routerFactory: () => Router(),
  authContext: (req) => ({
    ipHash: req.ip,
    ipEnc: null,
    userAgent: req.get('user-agent') ?? null,
    userId: req.user?.id ?? null,
  }),
  issueSession: async ({ user, res, accessToken, refreshToken }) => {
    res.json({ user, accessToken, refreshToken });
  },
  publicSessionUser: (user) => user,
  getUserById: async (userId) => findUser(userId),
  logArcLogin: async () => {},
  authMiddleware,
  optionalAuthMiddleware,
  privacySanitizer,
  requireFeature,
  ipLimiter,
}));

2. Client HTTP adapter

import axios from 'axios';
import { createArcHttpClient } from '@panomapp/arc/client';

const api = axios.create({ baseURL: '/api' });
const arcClient = createArcHttpClient(api);

3. Code display page

import type { ArcSlot } from '@panomapp/arc';
import { useArcSlotPlayback } from '@panomapp/arc/client';

Use useArcSlotPlayback() to render the active 4x4 ARC slot sequence on the device that needs to sign in.

4. Scanner page

import { ref } from 'vue';
import { useArcAuthScanner } from '@panomapp/arc/client';

const videoRef = ref<HTMLVideoElement | null>(null);
const canvasRef = ref<HTMLCanvasElement | null>(null);

const scanner = useArcAuthScanner({
  videoRef,
  canvasRef,
  scan: (observedBits, candidateId) => arcClient.scan(observedBits, candidateId),
  onVerified: async (result) => {
    console.log('ARC verified', result.user?.id);
  },
});

Then:

await scanner.startCamera();
scanner.startScanning();

Device-linking model

Typical ARC flow:

  1. Device A opens the ARC code page and requests createChallenge().
  2. Device A displays the animated 4x4 ARC sequence.
  3. Device B is already authenticated and opens the scanner page.
  4. Device B scans the ARC sequence and sends scan(observedBits, candidateId?).
  5. The server locks onto the correct challenge, verifies three slots, and binds the challenge to the scanning user.
  6. Device A keeps polling pollStatus(challengeId) until the challenge becomes verified.
  7. Device A receives the issued session tokens and signs in.

Testing and simulation

Run the built-in self-test suite:

npm run selftest

This covers:

  • baseline detector round-trips
  • realistic camera degradation
  • frontend-scanner plus backend-route auth loop
  • network latency and jitter profiles
  • PNG and JSON artifacts in test-logs/

Notes

  • The client entry is ESM-only at runtime.
  • The server entry does not directly import Express; you pass your own router and middleware.
  • The testing entry is intended for Node environments.
  • test-logs/ is generated output and is not published.