Skip to content

Server rendering

@sealpixel/server renders edit logs with the same WebAssembly core the browser uses. The primitive is a fetch-style handler.

ts
import { createSealpixelHandler, inlineSource, s3Destination, s3Source, urlSource } from '@sealpixel/server';
import { awsObjectStore } from '@sealpixel/server/aws';
import { defaultPlugins } from '@sealpixel/plugins';

const store = awsObjectStore(new S3Client({}));
export const handler = createSealpixelHandler({
  plugins: defaultPlugins,
  sources: [s3Source({ store, bucket: 'uploads' }), urlSource({ allowHosts: ['cdn.example.com'] }), inlineSource()],
  destinations: [s3Destination({ store, bucket: 'renders' })],
  limits: { maxMegapixels: 80, maxBytes: 100e6, timeoutMs: 25_000 },
  cors: ['https://app.example.com'],
});

Contract

POST /render

json
{
  "source": { "kind": "s3", "key": "uploads/IMG_0042.jpg" },
  "editLog": { "...": "..." },
  "output": { "format": "image/jpeg", "quality": 0.9 },
  "mode": "render",
  "destination": { "kind": "s3" }
}
ResponseMeaning
200 bytesdestination.kind: 'response'; headers x-sealpixel-hash, x-sealpixel-job, content-disposition: attachment
200 JSON{ key, bucket, objectKey, url, hash, width, height, mimeType, cached, timings }
200 image/pngmode: 'proxy': a deterministic proxy with x-sealpixel-descriptor
400INVALID_REQUEST, INVALID_EDIT_LOG, UNKNOWN_PLUGIN
403FORBIDDEN_SOURCE
404SOURCE_UNAVAILABLE
413TOO_LARGE
415UNSUPPORTED_FORMAT
422SOURCE_MISMATCH, MISSING_ASSET
504TIMEOUT

GET /health returns the core and plugin versions. Client and server must register the same plugin list.