Client
createRasterClient, its methods for libraries, assets, uploads, variants, and search, and the image URL helpers and formatters.
createRasterClient creates a client for the Raster REST API. It runs in the
browser and Node.js, and @raster-app/react re-exports it.
import { createRasterClient, localStorageCredentialStore } from '@raster-app/sdk'
const raster = createRasterClient({
host: { name: 'My App', openExternal: (url) => window.open(url, '_blank') },
credentials: localStorageCredentialStore(),
})
const libraries = await raster.libraries.list({ organizationId: 'acme' })
const assets = await raster.assets.list({ organizationId: 'acme', libraryId: 'lib-1' })Create one client and reuse it. Each client keeps its own session.
Configuration
| Option | Type | Description |
|---|---|---|
host | RasterHost | Required. Your app's name and openExternal function. See The host. |
credentials | CredentialStore | Required. Where the credential is stored. See Where the credential is stored. |
The host
host.name is your app's name on Raster's Connect page and in Settings →
Connected apps.
host.openExternal(url) opens a URL in the user's browser: the sign-in page,
and Open in Raster in RasterPicker. Its return value is ignored, so
window.open and async functions both work.
Methods
| Method | Resolves with |
|---|---|
me() | The organizations and libraries the credential reaches. |
libraries.list(options) | Every library in an organization. |
assets.list(options) | One page of a library's assets. |
assets.get(options) | One asset, with its variants. |
assets.upload(options) | The new asset, once Raster has the file. |
assets.waitUntilProcessed(options) | The processed asset, or null. |
assets.promote(options) | The ids the promote touches, once Raster accepts it. |
assets.waitUntilPromoted(options) | The asset once the promote lands, or null. |
search(options) | One page of search results. |
auth.signInWithDevice(options) | The stored credentials. See Device sign-in. |
auth.connect({ apiKey }) | The stored credentials. See API keys. |
auth.signOut() | Nothing. See Sign out. |
Failed calls reject with a RasterApiError.
Cancelling a call
Library, asset, and search methods take an optional signal. Aborting it
rejects the call with ABORTED; a signal from AbortSignal.timeout() rejects
with TIMEOUT. isAbortError(error) tells a cancel from a failure:
import { isAbortError, toUserMessage } from '@raster-app/sdk'
const controller = new AbortController()
try {
await raster.search({ organizationId: 'acme', query: 'sunset', signal: controller.signal })
} catch (error) {
if (!isAbortError(error)) alert(toUserMessage(error))
}Device sign-in takes a signal too.
What the credential reaches
raster.me() resolves with GET /me. To read it:
meOrganizationList(me):{ id, name, libraryCount }per organization.meOrganizations(me):{ organizationId, organizationName, plan, libraries }per organization.meLibraryAccess(me, organizationId, libraryId):'read','write', ornull.
Libraries
libraries.list({ organizationId, organizationName?, signal? }) resolves with
every Library in the organization, each with
organizationId and organizationName (what you passed, or null).
Assets
assets.list({ organizationId, libraryId, page?, pageSize?, signal? })
resolves with one page of assets. page starts at 1;
pageSize defaults to 50. assets.hasMorePages(pageLength, pageSize?) is
true when a page came back full.
assets.get({ organizationId, libraryId, assetId, signal? }) resolves with one
asset and its variants.
Uploads
async function uploadFile(file: File) {
const uploaded = await raster.assets.upload({
organizationId: 'acme',
libraryId: 'lib-1',
source: file,
})
return raster.assets.waitUntilProcessed({
organizationId: 'acme',
libraryId: 'lib-1',
assetId: uploaded.id,
parentId: uploaded.parentId,
})
}| Option | Description |
|---|---|
organizationId, libraryId | Required. The target library. |
source | Required. A Blob, a File, or { bytes, filename, contentType } with Uint8Array bytes. |
filename | Overrides the source's name. An unnamed Blob is named upload. |
parentId | Uploads the file as a variant of this asset. |
signal | Cancels the upload. |
assets.upload resolves once Raster has the file, with id, parentId,
url, appUrl, and name. Raster then adds dimensions, sizes, and
blurhash. assets.waitUntilProcessed resolves with the processed
Asset, or null if it's still processing when the wait
ends. For a variant, it resolves with the parent. Limits and accepted files:
POST …/assets.
Variants
const promotion = {
organizationId: 'acme',
libraryId: 'lib-1',
assetId: 'abc123',
variantId: 'var789',
}
await raster.assets.promote(promotion)
const asset = await raster.assets.waitUntilPromoted(promotion)assets.promote makes a variant the asset's default, served at the same URL.
It resolves with assetId, promotedVariantId, and demotedVariantId (the
new variant holding the previous default). assets.waitUntilPromoted resolves
with the asset once the promote lands, or null. Rules:
POST …/promote.
Search
const { hits, found } = await raster.search({ organizationId: 'acme', query: 'sunset' })search resolves with one page of a SearchResult:
assets whose name, description, or tags match, ranked by relevance.
| Option | Description |
|---|---|
organizationId | Required. The organization to search. |
query | Required. The search text. |
libraryIds | Limits the search to these libraries. Defaults to every library the credential reaches. |
page | The page, starting at 1. |
pageSize | Hits per page. Defaults to 50. |
signal | Cancels the search. |
Blank queries and unreachable library ids:
GET …/search/assets.
Session
Outside React, raster.session tracks whether the user is signed in. In React,
use useSession().
| Member | Description |
|---|---|
isSignedIn() | true when the credential is a sign-in, not an API key. |
isConfigured() | true when there is a sign-in or an API key. |
current() | The stored credentials, or undefined until read. |
subscribe(listener) | Calls listener when the credential changes. Returns an unsubscribe function. |
hydrate() | Reads the stored credential. Call it at startup, before the others. |
Image helpers
Each helper takes an Asset, AssetVariant, or SearchHit.
| Helper | Returns |
|---|---|
getThumbUrl(asset) | A small URL for grids. undefined when there's none. |
getPreviewUrl(asset) | A large URL for previews. undefined when there's none. |
getFullSizeUrl(asset) | The full-size URL to hand your app on pick. null when there's none. |
getBlurhashPlaceholder(asset) | A blurred data: URL to show while loading. null without a blurhash or outside a browser. |
isReady(asset) | true once the asset is processed and has a full-size URL. |
These URLs change when the asset's file is replaced, as by a promote.
To choose a size yourself:
parseSizes(asset.sizes)returns an object from size to URL, ornull.pickSizeUrl(sizes, targetEdge)returns the smallest size at leasttargetEdgepixels on its longest edge, or the largest one.versionedUrl(url, asset.contentVersion)makes the URL change when the file is replaced.
Formatters
Formatters match the Raster app: decimal units (1 MB is 1,000,000 bytes) and
en-US dates.
| Function | Returns |
|---|---|
formatBytes(bytes) | 512 B, 2 KB, 4.2 MB, 3.00 GB. |
formatFileSize(bytes) | formatBytes, or '' for null, undefined, negative, or non-finite. |
formatDate(date) | Jan 15, 2024. |
formatDateLong(date) | The date with weekday and time. |
formatRelativeTime(date) | just now, 5m ago, 3h ago, 2d ago, then formatDate from 7 days on. |
Date formatters take a Date or Unix milliseconds (as in created and
updated) and return '' for null.
Constants and types
| Export | Description |
|---|---|
API_VERSION | The Api-Version the client sends. See The Api-Version header. |
ASSETS_PAGE_SIZE, SEARCH_PAGE_SIZE | Default pageSize for assets.list and search: 50. |
Asset, AssetVariant, Library, Tag, Uploader, SearchHit, and
SearchResult match the API's objects.