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

@rawback/sdk

v0.3.3

Published

Proprietary Node.js SDK and shared application kernel for Rawback clients.

Readme

@rawback/sdkcodecov

The shared Node.js application kernel for Rawback clients. It provides typed authentication, REST and GraphQL access, photo and library operations, direct SFTP uploads, resumable transfer state, and the local ~/.rawback/ configuration contract used by Rawback CLI and Desktop.

Proprietary: this package is published publicly so Rawback-controlled applications can install it without registry credentials. It is UNLICENSED and is not licensed for third-party use, modification, or redistribution.

The source repository is private. npm trusted publishing uses GitHub Actions OIDC without a long-lived registry token; npm provenance is unavailable for packages built from private source repositories.

Requirements

  • Node.js 26.5 or newer (.node-version), or a compatible Bun runtime
  • ESM (import); CommonJS is not published
  • To develop this package: pnpm 11.18.0 (pinned in packageManager)

Install

pnpm add @rawback/sdk

Create a client

import { createRawbackSdk } from "@rawback/sdk";

const rawback = await createRawbackSdk({
  identity: {
    source: "desktop",
    version: "1.0.19",
    userAgent: "rawback-desktop/1.0.19",
  },
});

const library = await rawback.services.photos.library({
  pagination: { page: 1, pageSize: 40 },
});

Searching photos

photos.search takes a plain-language request and lets the server work out the filters behind it:

const first = await rawback.services.photos.search({
  prompt: "from 2012, all images in NYC",
  pagination: { page: 1, pageSize: 24 },
});

// What the server understood, for showing back to the user.
console.log(first.data?.images.aiSearch?.summary);

Resolving a prompt costs one AI credit. The reply carries images.aiSearch.id — send it back as aiSearchId on every following page and the translation is replayed for free:

const second = await rawback.services.photos.search({
  prompt: "from 2012, all images in NYC",
  aiSearchId: first.data?.images.aiSearch?.id,
  pagination: { page: 2, pageSize: 24 },
});

Pass both. The server prefers the id and quietly re-resolves the prompt if the id has expired, so callers never have to handle an expiry. photos.list still takes the full structured ImageFilter for callers that build filters themselves.

By default the SDK reads ~/.rawback/config.yml and ~/.rawback/credentials.json. Explicit constructor options take precedence. Secret-bearing files are written atomically with restrictive permissions on Linux and macOS.

Local metadata parsing is automatically sized from available CPU and memory. To force an exact worker count for Rawback-controlled clients, add an integer from 1 through 64 to the shared configuration:

metadata:
  concurrency: 8

Omit the metadata block to retain automatic sizing. An explicit value bypasses the memory-aware choice, so benchmark representative files before increasing it.

Services

  • auth — password and device authentication, session restore, refresh, and logout
  • services.photos — search (plain-language, the primary path), list (structured ImageFilter), and library
  • services.albums, services.articles, services.dreams, and services.shares — typed domain operations
  • services.uploadSessions, services.usage, and services.pricing — account and activity reads
  • services.sftpCredentials — create, list, and revoke upload credentials
  • UploadManager and UploadStateStore — direct SFTP orchestration, progress, portable persistence, and legacy-state imports

SftpClientOptions.channelCount assigns simultaneous uploads to independent SFTP subsystem channels on one authenticated SSH connection. UploadManager sets it from the configured upload concurrency automatically.

Upload duplicate checks read only the required capture-time tags with ExifTool. Unless a caller supplies an explicit concurrency override, the extractor chooses up to twice the available CPU parallelism while accounting for free and total memory. Reclaimable operating-system cache does not reduce the pool below one worker per available CPU when total memory safely supports it. Workers start together for high-throughput folder reviews, with an automatic ceiling of 64 ExifTool processes.

SDK consumers can pass the shared value into either extraction API:

const result = await extractUploadIdentities(candidates, {
  concurrency: rawback.client.config.metadata?.concurrency,
});

const manager = new UploadManager({
  // ...account, credential, and transport options
  identityConcurrency: rawback.client.config.metadata?.concurrency,
});

resolveMetadataWorkerCount() exposes the same automatic policy for other local metadata workloads. Upload capture-time extraction requests only the required tags and uses ExifTool's fast mode; full catalog readers should retain the tags their UI exposes.

See Architecture and Migration for the consumer and persistence contracts.

Development

pnpm install --frozen-lockfile
pnpm check

# Optional: benchmark metadata extraction against a local photo directory
pnpm benchmark:metadata -- /path/to/photos
pnpm benchmark:metadata -- /path/to/photos --concurrency 8

Video attachment preparation and repair

prepareVideoUpload(path, options) probes the original file, extracts a poster, and prepares audio chunks. Pass onPreparationError(attachment, error) to report best-effort thumbnail/audio extraction failures. Use skipThumbnail or skipAudio when repairing only missing attachments; an explicit thumbnail takes precedence over skipThumbnail. Cancellation rejects the preparation and removes temporary audio files. Always call the returned cleanup() in a finally block, including when opening or uploading the original fails.

VideoService.uploadVideo reports best-effort attachment upload failures through onAttachmentError. Neither callback indicates a failure to upload the video body. Audio upload does not mean speech-to-text has completed: transcription is a separate server job.

The Video detail operation includes hasAudio, audioChunkCount, and transcript status. After checking ownership through the API and matching the original file, clients can use uploadThumbnail and uploadAudio to attach missing assets to an already completed video. These methods do not reupload the video body. Preserve existing audio and completed or active transcripts; attachment repair does not restart failed or disabled transcription jobs.

Multilingual articles

An album keeps one article identity. services.articles.byAlbum includes defaultLanguage, availableLanguages, and full editable versions. Lists and ordinary write responses include only language/revision metadata for versions, avoiding repeated translation bodies in paginated responses. Use byAlbum to read translated text. Pass language and expectedRevision to articles.upsert; omitted language edits the default. articles.translate({ input: { articleId, sourceLanguage: "en", targetLanguage: "fr", expectedSourceRevision, requestId: crypto.randomUUID(), overwrite: false } }) saves a complete target version for 10 credits. Reuse the same request ID and input on retry. Existing targets require overwrite and expectedTargetRevision. All versions share publication and public-web visibility. Use setDefaultLanguage, labelVersion (including migration from und), and deleteVersion to manage languages.