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

@sonenta/in-context

v1.3.2

Published

In-context (on-device) translation editing for Sonenta — pair a live app to the editor and see edits apply in place. React (web) + React Native / Expo.

Readme

@sonenta/in-context

In-context (on-device) translation editing for Sonenta. A plugin of your existing @sonenta/react-i18next provider: pair your running app to the Sonenta editor, and translations the editor changes apply live, in place — no redeploy, no page reload. The plugin also reports which strings are on the current screen so the editor can highlight them.

  • @sonenta/in-context/react — the SonentaProvider plugin (web / React).
  • @sonenta/in-context/native — the same plugin for React Native / Expo.
  • @sonenta/in-context/core — the framework-agnostic client (InContextClient, parseEvent, applyEdit) for advanced / other-framework use.

In-context editing is headless: the SDK owns pairing, the live channel, applying edits, and reporting on-screen keys — your app owns the pairing UI (a short-code / paste box on web, a QR scan with your own camera on native).

MIT.

Install

npm i @sonenta/in-context
# peer: @sonenta/react-i18next >= 1.0.6 (needed so live edits repaint the
#       public useTranslation hooks in place — see "Apply edits" below)
# @sonenta/realtime (the Centrifugo transport) is pulled in automatically

Usage (web / React)

import { SonentaProvider } from "@sonenta/react-i18next";
import { inContextPlugin, type InContextController } from "@sonenta/in-context/react";

let controller: InContextController | null = null;

<SonentaProvider
  token="vrb_live_…"
  projectUuid="…"
  defaultLocale="fr"
  plugins={[
    inContextPlugin({
      device: "Marketing site · Chrome",
      onReady: (c) => (controller = c),
      onStatus: (s) => console.log("in-context:", s),
    }),
  ]}
>
  <App />
</SonentaProvider>;

// When the user pastes the short code shown in the editor:
await controller?.pair(codeFromInput);

// Call this on route / screen change so the editor tracks what's visible:
router.afterEach(() => controller?.reportKeys());

Usage (React Native / Expo)

Identical, importing from @sonenta/in-context/native. Scan the editor's QR with your own camera component (e.g. expo-camera / react-native-vision-camera) and hand the decoded pairing_token to controller.pair(token) — the SDK bundles no camera. The client uses only JSON-body POSTs (no URLSearchParams), so it is Hermes-safe.

import { inContextPlugin } from "@sonenta/in-context/native";

inContextPlugin({
  device: "iPhone 15 · Expo",
  onReady: (c) => setController(c),
});

// from your QR scanner's onScan handler:
await controller.pair(decodedPairingToken);

How it works

  1. Paircontroller.pair(pairingToken) calls POST /v1/in-context/pair with the single-use token and gets back a scoped, subscribe-only Centrifugo sub-token, the session channel, and the realtime rtUrl (server-provided — never hardcoded).
  2. Subscribe — opens that channel via the @sonenta/realtime LiveClient transport and listens for paired / edit / session_ended.
  3. Apply edits — each edit becomes an in-memory i18next override (addResource) followed by i18n.refresh() (react-i18next ≥1.0.6), which repaints both the SDK's useTranslation hooks and react-i18next-native consumers in place, without a CDN re-fetch (so the override isn't clobbered). On a host pinned to react-i18next <1.0.6 the public hooks won't repaint until the next render — bump to ≥1.0.6. Edits to a background language are stored silently and surface when you switch to it.
  4. Report on-screen keys — on pair, on language change, and whenever you call controller.reportKeys(), the keys rendered on the current view (read from the i18n SDK's __verbumia_key_registry__) are POSTed to /v1/in-context/sessions/{id}/keys so the editor can highlight them. Each item is the canonical shape { namespace, key, values? }, where values carries the value the device rendered on screen (the active locale's raw template). The SDK omits sourceValue. The backend's /keys endpoint is pass-through (it relays your items verbatim); the editor dashboard resolves the authoritative sourceValue and the full per-locale values from its own project data, so the device never has to know every locale. Reports are capped at 500 items.
  5. Teardown — the session ends gracefully on session_ended or when the sub-token expires (the pairing token is single-use and can't be re-authed).

Controller API

| Member | Description | | --- | --- | | pair(pairingToken, device?) | Start a session from a pairing token. Re-pairing ends the previous session first. | | reportKeys() | Re-report the keys on screen now (call on navigation). Best-effort. | | end() | Locally tear down the session. | | status | idle | connecting | connected | disconnected | ended. | | sessionId | The server-minted session id once paired. |