Files
paseo/plugin-examples/media-stream/README.md
T
Mohamed Boudra c689b5626e feat(plugins): stream events and bytes between plugins and the app
Plugins can declare a subscription with defineSubscription, handle it with
server.handle(contract, (input, { push, signal })), and listen from a surface
with useSubscription or client.subscribe. A top-level Uint8Array in an event,
an RPC output, or an RPC input crosses the wire as a binary frame (opcodes
0x20-0x2f) without JSON or base64; a nested one fails validation on the sender.

Each subscriber runs its own handler, owned by the session that subscribed,
so release, disconnect, plugin stop and reload need no plugin code. The
runtime buffers pushes until the subscribe response has gone out, so a client
never sees an event for a subscription it does not know yet.

Gated on server_info.features.pluginSubscriptions; binary outputs reach only
clients that advertise plugin_binary_payloads.
2026-11-02 05:30:01 +01:00

907 B

Media stream plugin example

One subscription carries two binary streams. Each pushed Uint8Array is a binary frame; its first byte says whether it is video, a keyframe, or audio.

paseo plugin add /absolute/path/to/paseo/plugin-examples/media-stream
  • shared/media-frames.ts owns the byte layout: encodeMediaFrame, decodeMediaFrame, and the media.stream contract. decodeMediaFrame returns a view, so the panel never copies a payload.
  • server/test-pattern.ts is a synthetic source; replace it with a real capture.
  • index.server.ts pushes each source callback as a frame and stops the source when the subscription's signal aborts.
  • client/media-panel.tsx decodes each frame and routes it by opcode.
  • shared/frame-check.ts is an RPC whose input is a Uint8Array: the panel uploads the picture on screen and server/frame-check.ts reports its size and checksum.