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

@meeeetup/camera-web

v0.6.0

Published

Web SDK for meeeetup-cam — MediaPipe BlazeFace + React hooks

Readme

@meeeetup/camera-web

Browser face-capture SDK for the Meeeetup face-ID service. Detects faces with MediaPipe BlazeFace, tracks them, picks the best-quality frame per person, and hands you the images through a callback.

Transport is yours. The SDK never makes a network request and never holds a credential: it calls onBatchCapture (passive) or onCapture (interactive) with base64 JPEG data URLs, and sending them is your code.

Requires React 18 or 19. ESM-only. Served over HTTPS or localhost — getUserMedia is a secure-context API.

Install

npm i @meeeetup/camera-web react react-dom

@meeeetup/camera-core arrives as a dependency — add it explicitly only if you import from it directly (this package already re-exports SelectedFace, LiveFacePreview and PersonResult).

import "@meeeetup/camera-web/styles.css";

Passive capture — continuous, batched

Faces are flushed to onBatchCapture every 10 s.

import {
  MeeeetUpCamProvider,
  CameraViewport,
  FaceCounter,
  FaceGrid,
  type SelectedFace,
} from "@meeeetup/camera-web";

export function PassiveCamera({ captureKey }: { captureKey: string }) {
  return (
    <MeeeetUpCamProvider
      mode="passive"
      onBatchCapture={async (faces: SelectedFace[]) => {
        const res = await fetch("https://api.example.com/capture", {
          method: "POST",
          headers: {
            Authorization: `Bearer ${captureKey}`,
            "Content-Type": "application/json",
          },
          body: JSON.stringify({
            images: faces.map((f) => ({
              image: f.dataUrl,
              capturedAt: new Date(f.createdAt).toISOString(),
            })),
          }),
        });
        // Throw to report failure. A missing status, <400 or >=500 is retried;
        // 4xx drops that batch (resending an unchanged rejected payload
        // livelocks).
        if (!res.ok) throw Object.assign(new Error("send failed"), { status: res.status });
      }}
    >
      <CameraViewport />
      <FaceCounter />
      <FaceGrid />
    </MeeeetUpCamProvider>
  );
}

Interactive capture — user-triggered

import {
  MeeeetUpCamProvider,
  CameraViewport,
  AlignmentRing,
  CaptureButton,
} from "@meeeetup/camera-web";

export function KioskCamera() {
  return (
    <MeeeetUpCamProvider
      mode="interactive"
      onCapture={async (faceImage, fullCircleImage) => {
        await upload(faceImage, fullCircleImage);
      }}
    >
      <CameraViewport />
      <AlignmentRing />
      <CaptureButton />
    </MeeeetUpCamProvider>
  );
}

Custom UI

useMeeeetUpCam() exposes everything the built-in components render. Narrow on cam.mode first; it throws outside a provider.

const cam = useMeeeetUpCam();
if (cam.mode === "passive") {
  // cam.ready, cam.error, cam.trackedCount, cam.totalCount,
  // cam.selectedFaces, cam.livePreviews, cam.flushBatch()
}

Shared across modes: ready, error, videoRef, devices, currentDeviceId, setDeviceId, currentFacingMode, toggleCamera.

Components

| Component | Mode | Renders | |---|---|---| | CameraViewport | both | <video> + overlay canvas (passive) / circular viewport (interactive) | | FaceCounter | passive | Tracked + total badge | | FaceGrid | passive | Grid of selected face crops | | DevicePicker | both | Camera dropdown | | CameraToggle | both | Front/back switch | | AlignmentRing | interactive | Alignment ring, progress, countdown | | CaptureButton | interactive | Manual capture trigger |

Every component except AlignmentRing accepts className. The skin is CSS custom properties (--mfc-*) with dark defaults — re-theme by setting them on any ancestor.

Provider props

Both modes accept children and mediapipeWasmUrl; the capture gates (cooldownMs and the three below) are passive-only.

| Prop | Mode | Type | Default | |---|---|---|---| | onBatchCapture | passive | (faces: SelectedFace[]) => void \| Promise<void> | required | | onCapture | interactive | (faceImage: string, fullCircleImage: string) => void \| Promise<void> | required | | cooldownMs | passive | number | 10000 — minimum ms between sends for the same face | | mediapipeWasmUrl | passive | string | jsDelivr CDN — point it at a self-hosted WASM directory | | alignmentCaptureDelayMs | interactive | number | 2000 — how long a face must stay aligned before auto-capture | | minDetectionScore | passive | number | 0.5 — detector confidence floor, applied before any pose analysis | | minFaceHeight | passive | number | 0 — minimum face-box height as a fraction of frame height (0–1); off by default | | minFrontalness | passive | number | 50 — minimum pose score (0–100) a frame must reach to be captured | | captureWindowMs | passive | number | 0 — per-track best-shot window in ms; 0 keeps settle-based capture |

With captureWindowMs set, each tracked face is searched for that long and the best frame is published as final at expiry. useMeeeetUpCam() in passive mode returns rearm(), which starts every window's search again.

Runtime network access

MediaPipe assets are fetched on demand, so the browser must reach:

  • https://cdn.jsdelivr.net — WASM runtime (override with mediapipeWasmUrl)
  • https://storage.googleapis.com — the .tflite detection model

A strict CSP needs both in connect-src, plus script-src 'wasm-unsafe-eval'.

Licence

Proprietary — see LICENSE. Use requires a current agreement with MeeeetUp1120.