@khalidadil/filebot-react (0.1.0)
Installation
@khalidadil:registry=npm install @khalidadil/filebot-react@0.1.0"@khalidadil/filebot-react": "0.1.0"About this package
@khalidadil/filebot-react
React bindings over @khalidadil/filebot-client: a provider that carries the host client and server-signed bucket bases, an <Image> that builds a signed srcset by string concatenation (SSR-safe), a useGallery hook, and useUploader + <Uploader> + <QrUpload> components. No CSS, no data-fetching dependency, no server secrets — the browser only ever sees host-minted grants and signed bases.
Publishes to the private Gitea registry https://git.kadil.dev/api/packages/khalidadil/npm/ (never GitHub), installable with no token.
pnpm add @khalidadil/filebot-react
Peers: react >=18, react-dom >=18. Runtime deps: @khalidadil/filebot-client, @khalidadil/filebot-signing.
Provider and bucket bases
<FilebotProvider> gives the tree a host client (talking to your app's file router) and a map of bucket bases — a bucket uuid → a server-signed base URL plus its ladder and presets, so <Image fileRef> builds a srcset locally with no per-image round trip.
import { FilebotProvider } from "@khalidadil/filebot-react";
<FilebotProvider
mount="/api/filebot"
bases={initialBases} // seeded from the server render (bucket uuid → BucketBase)
refreshBases={async () => {
const r = await fetch("/demo/bases", { method: "POST" }); // YOUR host route (see below)
return r.json(); // Record<bucketId, { base, exp, ladder, presets }>
}}
>
<App />
</FilebotProvider>
A BucketBase is { base, exp, ladder, presets } where exp is unix seconds (or null for a public bucket).
refreshBases is host-supplied (E-5 / OI-1)
v1 has no built-in host {mount}/bases route — a signed base is a capability, so minting one is your app's authorization decision. You supply refreshBases; the examples/host-app reference implements it as POST /demo/bases. The provider then:
- schedules a refresh at
min(exp) − 300 s; - coalesces
<Image>-drivenrequestBaseRefresh()calls (missing/expiring base, or an imageonError) over a 1 s window; - runs refreshes single-flight — a failure keeps the old bases and the next automatic attempt waits at least 30 s;
- never lets an incoming base replace a fresher one (a later
expwins; a publicexp: nullalways applies).
Without refreshBases, bases stay exactly as seeded.
<Image>
import { Image } from "@khalidadil/filebot-react";
<Image fileRef={photo.ref} preset="card" maxWidth={640} alt="" /> // srcset from the provider's base
<Image media={signedMedia} alt="" /> // a FileMedia the server already signed
<Image src={absoluteSignedUrl} alt="" /> // an already-built URL
In fileRef mode the srcset is built over bases[bucketId]; when the bucket lacks the requested preset it falls back to a ladder width (w/<n>). On a missing/expiring base or a load error it asks the provider to refresh, once per base.
Hooks and components
const { items, isLoading, loadMore } = useGallery({ identifier: "album:42" });
const up = useUploader({ route: "avatars", maxFilesPerInit: 1 });
<Uploader route="avatars" onUploadAccepted={(e) => setAvatar(e.fileId)} />
<QrUpload route="avatars" /> // renders the QR, streams uploaded/ready counts
useUploader / <Uploader> wrap the client's createUploader; the callbacks (onUploadAccepted, onRejected, onRestored, onFileStatus) and Uppy's pause/resume/retry/remove are the same surface documented in @khalidadil/filebot-client.
SSR
Nothing touches window during render; timers only start in effects, so the provider and <Image> render identically on the server and hydrate cleanly.
Testing
pnpm --filter @khalidadil/filebot-react test runs the component suite under @happy-dom/global-registrator (no services). test/pack.test.ts asserts the published tarball ships dist/** + README.md + package.json only with the exact runtime deps. See Features/SDKs.md in the vault for the full picture.
Release
Part of the five-package lockstep set; packages/filebot-server/scripts/lockstep-check.ts prints (never runs) the gated publish. Publishing needs the lead's go and Khalid's approval.
Dependencies
Dependencies
| ID | Version |
|---|---|
| @khalidadil/filebot-client | 0.1.0 |
| @khalidadil/filebot-signing | 0.1.0 |
Development Dependencies
| ID | Version |
|---|---|
| @happy-dom/global-registrator | ^20.14.5 |
| @types/node | ^22.10.0 |
| @types/react | ^19 |
| @types/react-dom | ^19 |
| react | ^19.0.0 |
| react-dom | ^19.0.0 |
| tsx | ^4.19.2 |
| typescript | ^5.7.0 |
Peer Dependencies
| ID | Version |
|---|---|
| react | >=18 |
| react-dom | >=18 |