ExperimentalOptional ExperimentalabortCancels opening, and closes the session if it is already open.
Optional ExperimentalendpointThe endpoint to open, when the extension's default is not the one wanted. Declared HERE because the KERNEL reads it — an extension never has to redeclare it, and a third-party extension that forgets to would otherwise strand its callers unable to select an endpoint.
OptionalonInbound application data, once per message.
Deliberately a string rather than a parsed object: the kernel cannot know a model's schema, and pretending otherwise would put one protocol's vocabulary in the transport. The extension delivers; the application parses and validates.
Declared for every extension rather than only the ones that obviously need it, because "media up, data down" is a shape any of them can take, and an extension whose surface omits this cannot express it even when its protocol allows it.
OptionalonProgress and failure reports. See RealtimeDiagnostic.
OptionalonThe terminal FAILURE, delivered once: the error that failed opening, or the transport failure
an extension reported through context.fail(). A caller's own cancellation — close() or an
aborted abortSignal — is an orderly ending, not a failure: it reaches onState("closed") and
rejects ready, and deliberately never fires this.
This is the failure channel for the synchronous open() shape — there is no returned promise
whose rejection could carry it, and requiring every caller to attach to ready would turn an
optional convenience into an obligation.
OptionalonInbound media, once per stream, for any extension that returns some.
Named HERE rather than per extension because "a remote stream arrived" is one concept, and left
to the extensions it acquires one name per protocol — every one of them defensible, none of them
shared. An application offering two extensions then needs a branch to do the single thing it
actually wants, which is attach a video element. Same tax onState removes for lifecycle.
Not every extension calls it. An app can send a camera up and get its answer back as data with no inbound media at all, which is why this is optional on both sides rather than part of opening.
OptionalonCoarse lifecycle transitions, uniform across every extension.
Options the KERNEL reads, accepted alongside whatever an extension declares.
Separate from an extension's own
Optionsbecause they belong to different owners: the extension defines its product inputs, the kernel defines cancellation and reporting. Declaring them here is what makes them reachable through the typedopen(extension, options)overload, which otherwise types the options bag as the extension's alone and rejects every kernel option at the call site.An extension with NO options of its own must declare
Record<never, never>, notRecord<string, never>. The latter asserts that every string key maps tonever, which makesOptions & RealtimeOpenOptionscontradictory and rejectsonMedia,onStateandonDiagnosticat the call site — leaving an extension that takes no product inputs unable to receive any kernel option at all.The
fal.realtime.open()extension API is experimental and may change in a minor release.