@rawback/sdk
v0.3.3
Published
Proprietary Node.js SDK and shared application kernel for Rawback clients.
Readme
@rawback/sdk
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
UNLICENSEDand 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/sdkCreate 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: 8Omit 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 logoutservices.photos—search(plain-language, the primary path),list(structuredImageFilter), andlibraryservices.albums,services.articles,services.dreams, andservices.shares— typed domain operationsservices.uploadSessions,services.usage, andservices.pricing— account and activity readsservices.sftpCredentials— create, list, and revoke upload credentialsUploadManagerandUploadStateStore— 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 8Video 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.
