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

@pura-ai/sdk

v0.1.1

Published

Official Pura LLM OAuth and delegated inference SDK

Readme

@pura-ai/sdk

Registry version · API 2026-10-01 · Proprietary license

Official proprietary SDK for registered Pura LLM integrations. The app receives OAuth tokens, never the account's internal virtual key. Install after registry publication with npm install @pura-ai/sdk. Registry status is tracked in the release guide; build locally with pnpm --dir packages --filter @pura-ai/sdk build. pnpm pack rebuilds the current source automatically. To build installable artifacts and verify them in isolated consumers, follow release and integration verification.

Subscription usage exposes monthly_used_percent, monthly_remaining_percent, weekly_used_percent, weekly_remaining_percent and 100% scope limits. weekly_share_percent is 25% of the monthly allowance. Budget/cost amounts are never returned; only the subscription price is monetary. Lifecycle paid-period snapshots likewise contain percentage allowances and available services.

Browser Connect

import {createConnectButton, completeBrowserConnection} from '@pura-ai/sdk';

const options = {
  apiBase: 'https://ai.puradigital.it/v1',
  clientId: 'YOUR_REGISTERED_CLIENT_ID',
  redirectUri: 'https://YOUR-APP/pura/callback',
};
document.querySelector('#pura-connect')!.append(createConnectButton({
  ...options, locale: 'it', onError: error => console.error(error),
}));

// On the registered callback page, in the same browser tab:
const tokens = await completeBrowserConnection(options);
// Store OAuth tokens according to your application's session architecture.
// Never put a confidential client secret into browser code.

The button uses authorization-code + PKCE S256, random state and per-tab pending flow storage. Return validation happens before exchanging the code. Authorization errors and expired flows require restarting Connect.

Backend integration and inference

For confidential apps, keep the pending authorization and client secret in your backend session. Use createAuthorization, redirect the user to its url, then new PuraOAuthClient(options).exchange(callbackUrl, pending) on return.

import {PuraInferenceClient} from '@pura-ai/sdk';

const pura = new PuraInferenceClient({
  ...options,
  // A separate encrypted OAuth TokenStore per connected user.
  store: userTokenStore,
});
const result = await pura.chat({
  messages: [{role: 'user', content: 'Ciao'}],
});
const usage = await pura.usage();
const response = await pura.streamChat({messages});
// response.body is the native SSE ReadableStream.

TokenStore.get/set must persist refresh-token rotation. A client instance coalesces concurrent refreshes. For multiple workers, implement TokenStore.withRefreshLock(operation) with a database/application lock bound to the connected user's grant. The SDK invokes operation under that lock, rereads the saved tokens, refreshes only if another worker has not already done so, and persists rotation before releasing the lock. Reads and writes must use the same transaction/lock context, shared across every instance for that grant. A failed operation must release the lock; a removed connection must return null. Do not lock unrelated users together. Without this adapter only refreshes in one client instance are coordinated. Reuse of a rotated refresh token revokes its token family. No inference or budget error triggers a wallet fallback. PuraError exposes HTTP status and the stable error code.

The server remains authoritative for scopes, revocation, model availability and shared monthly/weekly usage. SDK v0 targets API version 2026-10-01.

Audio transcription

const transcript = await pura.transcribe({
  file: audioBlob, filename: 'recording.wav', language: 'it',
});
console.log(transcript.text);

Audio uses the same OAuth grant, account-wide pending slots and percentage budgets as chat. The SDK sends multipart data without overriding its boundary and replays the complete immutable Blob if access-token renewal is needed. Files must be nonempty and at most 25,000,000 bytes. Only JSON/verbose JSON responses are supported; audio realtime/streaming is outside this endpoint. Use capabilities() to check services.chat and services.audio_transcription. Model selection is configured only on the Pura server, per service.

This endpoint is implemented but remains disabled until Pura configures a verified EU audio deployment, cost tracking and subscription allowlist. A 503 subscription_transcription_not_configured means it is unavailable; it never triggers another provider or wallet. No provider credentials belong in this SDK.

Lifecycle webhook verification (receiver contract)

Delivery requires a configured endpoint and Pura’s separately running webhook worker. These helpers verify received events; they do not register an endpoint. The wire contract uses X-Pura-Signature: t=<unix-seconds>,v1=<hex-HMAC-SHA256> over UTF-8 timestamp + . + the original request bytes. Default tolerance is ±300 seconds. Every retry receives a fresh signed delivery timestamp; event_id, created and app-local sequence stay fixed.

import {verifyWebhook, createWebhookHandler} from '@pura-ai/sdk';

// Use Express raw-body middleware or the native Request.arrayBuffer().
const event = await verifyWebhook(rawBody, requestHeaders, {
  signingSecret: serverSigningSecret,
  integrationId: registeredClientId,
});

const receive = createWebhookHandler({
  signingSecret: serverSigningSecret,
  integrationId: registeredClientId,
  store: persistentEventStore,
  onEvent: async event => applyEventInTheSameTransaction(event),
});
const result = await receive(rawBody, requestHeaders);

WebhookEventStore.processOnce(eventId, handler) must lock and execute the handler in the same database transaction as event-ID persistence, returning false for an already committed ID. Failures must roll back so delivery can retry. Coordinate all workers and implement external effects with your own transactional outbox. Return 2xx only after commit (duplicates can return 2xx). The SDK does not independently ensure delivery ordering; use sequence to reject stale snapshots or detect gaps. Invalid signatures never reach the store. The verifier binds the payload to your app, rejects unsupported API versions and rejects credential fields even when nested. There is deliberately no account-key decryption function.

OAuth responses include verified pura_user_id, persisted alongside tokens. Bind it to the authenticated local user in your own server-side exchange, then match lifecycle user.pura_user_id to that saved mapping. Do not accept identity from an unverified browser submission. SDK refresh rejects an account identity change before saving new tokens or sending inference.

Integration requests must not include model. Pura maps chat/streaming through INTEGRATION_CHAT_MODEL and audio through INTEGRATION_TRANSCRIPTION_MODEL in its server environment. The SDK and API reject client model overrides.