A Val Town port of Reactor's SANA-Streaming example ā their real-time video editing model. Point your webcam at it, type an edit instruction, and watch yourself transformed frame-by-frame. Re-prompt mid-stream and the new edit lands at the next chunk boundary (~1s).
The original is a Next.js 15 + React 19 app. This port keeps the same architecture but runs on Val Town's Deno runtime: a Hono server serves a client-side React SPA and mints the Reactor JWT; the browser connects directly to api.reactor.inc over WebRTC, so Val Town never proxies realtime media.
Rendering mermaid diagram...
The REACTOR_API_KEY stays on the server. The browser only ever receives a short-lived JWT, cached by its HTTP cache until expiry.
| Path | What it is |
|---|---|
index.ts | Hono server: serves the SPA, mints the JWT (/api/reactor/token), /source redirect |
frontend/index.html | SPA shell ā Twind (runtime Tailwind) + the React entry |
frontend/index.tsx | React root |
frontend/App.tsx | Provider + connection, seed, start/pause/resume/reset, live re-prompt, webcam self-view, edited output |
One env var, the Reactor production key (rk_...):
š Add REACTOR_API_KEY here: https://www.val.town/x/dcm31/sana-streaming/environment-variables?key=REACTOR_API_KEY
Faithful to the reference app: the server-side JWT mint (browser never sees the key), the model-as-source-of-truth reducer fed only by the typed state message, status-gated commands, the set_mode("live") ā start flow, mid-stream re-prompting, and the typed-SDK surface (useSanaStreaming, useSanaStreamingState, SanaStreamingMainVideoView).
Simplified for a single-file Val Town SPA:
<SanaStreamingCameraView>, which auto-acquires the webcam and auto-publishes the camera track. The reference app's second input source (streaming a video clip into camera via captureStream(), with the split source/edited stage) and its manual contentHint = "detail" publish are not ported.@reactor-team/js-sdk clip recorder).@reactor-team/ui design tokens.All three are straightforward to add on top ā the SDK exports the same hooks the reference uses.
react >=18) so the browser loads exactly one React instance from esm.sh.