@fkn/lib/contract
Type Aliases
Section titled “Type Aliases”Account
Section titled “Account”type Account = object;The signed-in account, or null when nobody is.
Properties
Section titled “Properties”image: string | null;name: string;premium
Section titled “premium”premium: boolean;premiumUntil
Section titled “premiumUntil”premiumUntil: string | null;AccountChange
Section titled “AccountChange”type AccountChange = object;What the broker’s account change notification says. switched is true only when the account the
broker acts as changed: another account, a sign-out or a sign-in. A renewal of the same account’s
token is false. A broker older than this sends no payload at all.
Properties
Section titled “Properties”switched
Section titled “switched”switched: boolean;AccountPinOptions
Section titled “AccountPinOptions”type AccountPinOptions = object;The trailing option of every pinned storage call: a value accountPin() answered. The api refuses the
call ACCOUNT_CHANGED when the signed-in account (or the app) is not the one the pin was taken under.
Absent, the call is unpinned.
Properties
Section titled “Properties”accountPin?
Section titled “accountPin?”optional accountPin?: string;AddressLookupResult
Section titled “AddressLookupResult”type AddressLookupResult = object;Properties
Section titled “Properties”address
Section titled “address”address: string;family
Section titled “family”family: 0 | 4 | 6;AdoptRequest
Section titled “AdoptRequest”type AdoptRequest = object;Properties
Section titled “Properties”bytes: number;files: number;AdoptState
Section titled “AdoptState”type AdoptState = object;Properties
Section titled “Properties”bytes: number;files: number;ConflictChoice
Section titled “ConflictChoice”type ConflictChoice = "local" | "cloud" | null;ConflictRequest
Section titled “ConflictRequest”type ConflictRequest = object;Properties
Section titled “Properties”cloud: ConflictSide;local: ConflictSide;path: string;ConflictSide
Section titled “ConflictSide”type ConflictSide = object;Properties
Section titled “Properties”size: number;updatedAt
Section titled “updatedAt”updatedAt: string | null;ConnectAvailability
Section titled “ConnectAvailability”type ConnectAvailability = "connected" | "disconnected" | "unknown";Three answers where available() has two. disconnected is an ANSWER and unknown is nobody
having been asked; the library’s local-first queue drops its cloud obligation only on the first
and keeps the write queued on the second.
ConnectOptions
Section titled “ConnectOptions”type ConnectOptions = object;Properties
Section titled “Properties”optional path?: string;an absolute inner route to mount the package at, e.g. ‘/watch/1’; defaults to its root
protocol?
Section titled “protocol?”optional protocol?: string;opaque contract tag delivered to the package’s onConnect, e.g. ‘stub-source@1’
DisplayCause
Section titled “DisplayCause”type DisplayCause = "not-rendered" | "clipped" | "not-shown";DisplayLevel
Section titled “DisplayLevel”type DisplayLevel = "full" | "liveness";full means this engine reported a boolean isVisible; liveness means we only know it paints
DnsLookup
Section titled “DnsLookup”type DnsLookup = <T>(hostname, options?) => Promise<T extends true ? AddressLookupResult[] : AddressLookupResult | undefined>;Type Parameters
Section titled “Type Parameters”T extends boolean = false
Parameters
Section titled “Parameters”hostname
Section titled “hostname”string
options?
Section titled “options?”T
family?
Section titled “family?”0 | 4 | 6
Returns
Section titled “Returns”Promise<T extends true ? AddressLookupResult[] : AddressLookupResult | undefined>
EncryptionState
Section titled “EncryptionState”type EncryptionState = object;Encryption state of the account’s cloud storage.
Properties
Section titled “Properties”enrolled
Section titled “enrolled”enrolled: boolean;keyEpoch
Section titled “keyEpoch”keyEpoch: number | null;unlocked
Section titled “unlocked”unlocked: boolean;FrameConsentAnswer
Section titled “FrameConsentAnswer”type FrameConsentAnswer = "once" | "session" | false;'once' is a critical row answered Once, a handoff the middle page takes for that attachment only; 'session' a standing row, remembered until removed from the FKN bar, for a category and a critical key alike; false a refusal.
FrameConsentRequest
Section titled “FrameConsentRequest”type FrameConsentRequest = | { category: "interaction" | "storage" | "network" | "evaluation"; hosts: string[];} | { attach?: string; hosts: string[]; key: string;} | { hosts: string[]; scope: FrameFetchScope;};One row on the cloud consent card.
A category asks for every capability in it; a key asks for one critical permission’s own row,
and is refused unless the registry has that key at severity 4 (none today). A critical grant
covers that key alone, never another key or its category. attach binds an “Allow once” answer
to the attachment that asked, so no other attachment can consume it.
FrameFetchScope
Section titled “FrameFetchScope”type FrameFetchScope = "frame.fetchRead" | "frame.fetchWrite";Deprecated
Section titled “Deprecated”the pre-category fetch scopes. Still exported so a pinned library keeps compiling; the card maps them to network.
FrameMessageRelay
Section titled “FrameMessageRelay”type FrameMessageRelay = | { attach: string; data: unknown; kind: "message"; origin: string; type: typeof FRAME_MESSAGE;} | { attach: string; kind: "document"; origin: string; type: typeof FRAME_MESSAGE;};origin is the page’s origin as the site knows it, which the shell derives from the browser-set
origin of the page’s own post, never from anything the page wrote.
HiddenSurface
Section titled “HiddenSurface”type HiddenSurface = object;Properties
Section titled “Properties”cause: DisplayCause;kind: string;level: DisplayLevel;InstalledPackage
Section titled “InstalledPackage”type InstalledPackage = object;Properties
Section titled “Properties”appId?
Section titled “appId?”optional appId?: string;the app id this pin last verified as, version-free. Absent until a verified resolve has run.
installedAt
Section titled “installedAt”installedAt: number;name: string;uri: string;version
Section titled “version”version: string | null;null when the handler addresses code directly and has no version to pin, e.g. a dev server
InstallOptions
Section titled “InstallOptions”type InstallOptions = object;Properties
Section titled “Properties”latest?
Section titled “latest?”optional latest?: boolean;Re-pin an existing record to whatever the source now calls latest, instead of answering the record already held. A host page pinning its own package on every load is what this exists for. An unreachable source keeps the record rather than dropping it.
noConfirm?
Section titled “noConfirm?”optional noConfirm?: boolean;skip the confirm prompt and report the install with a notice instead; the record stays scoped to the calling app
version?
Section titled “version?”optional version?: string;exact version to pin; defaults to the packument’s latest dist-tag
IpFamily
Section titled “IpFamily”type IpFamily = "IPv4" | "IPv6";MiddleControl
Section titled “MiddleControl”type MiddleControl = object;What a middle page exposes to the library, inline (ATTACH_FRAME_KEY) and for a window
(ATTACH_WINDOW_KEY). documentHost, where the frame actually is, is absent from a middle page
deployed before categories.
Methods
Section titled “Methods”blank()?
Section titled “blank()?”optional blank(): Promise<string>;The url the attachment’s empty page is armed for while the frame still holds that page, ''
when none, once the first goto was sent, and once the frame reported any other url, even on the
same host. The library sends a blank attach as ?blank= and refuses it by name unless this
echoes that url after ready, and reads it again before it skips the Evaluation card on a
fresh jar, so it asks whenever this page’s fresh-jar rule has ended. A middle page that serves
it refuses ready when its shell does not answer blank() with the same url. Absent from a
middle page that predates blank pages, which mounts its shell with no target.
Returns
Section titled “Returns”Promise<string>
clearCookies()?
Section titled “clearCookies()?”optional clearCookies(filter): Promise<void>;Removes the cookies filter matches from the attachment’s jar, among the cookies of the sites
the attachment reaches: the middle page hands its shell the boundary’s hosts (declared, plus the
host of the attach url and of every goto from its send) as ShellControl.clearCookies’ scope.
No options travel as {}, and each option is { equals } for now. Resolves undefined whatever
the shell answered, so nothing about the jar crosses back, and the shell takes the same steps
when nothing matched, so neither its time nor its refusals say whether the jar held a cookie
there. Never gated: it asks for no grant and draws no card, and a frame holding no document is
served, since a no-src attachment is what a sign-out runs on.
Refuses, each with the library’s own message and before anything is sent to the shell: a
{ pattern, flags } option (a TypeError frame.clearCookies: <key> is a RegExp, and clearCookies takes strings for name, domain and path for now), since the shell would test it against every
cookie in reach; a filter of any other shape (a TypeError frame.clearCookies: malformed filter); an attachment that reaches no site (LocatorDeniedError); and a shell that predates it
(LocatorUnsupportedError). The shell’s own refusals reach the library as they came. Absent from
a middle page that predates it, which the library refuses by name.
Parameters
Section titled “Parameters”filter
Section titled “filter”ClearCookiesWire
Returns
Section titled “Returns”Promise<void>
documentHost()?
Section titled “documentHost()?”optional documentHost(): Promise<string>;The host of the document the frame holds now, as the render proxy last reported it, and ''
before the first one. A document outside the attachment boundary answers '#outside', which is
no hostname: the library refuses on it with its boundary message and never learns where the
frame went. The middle page’s own gate keeps checking the real host.
Returns
Section titled “Returns”Promise<string>
executeLocator()
Section titled “executeLocator()”executeLocator( parts, operation,args): Promise<unknown>;Parameters
Section titled “Parameters”operation
Section titled “operation”string
unknown[]
Returns
Section titled “Returns”Promise<unknown>
goto()
Section titled “goto()”goto(url, options?): Promise<void>;Parameters
Section titled “Parameters”string
options?
Section titled “options?”Returns
Section titled “Returns”Promise<void>
messaging()?
Section titled “messaging()?”optional messaging(): Promise<true>;Present on a middle page that gates postMessage and relays the page’s messages
(FRAME_MESSAGE). Absent from one deployed before messaging, which the library refuses by name.
Returns
Section titled “Returns”Promise<true>
ready()
Section titled “ready()”ready(): Promise<boolean>;Returns
Section titled “Returns”Promise<boolean>
seed()?
Section titled “seed()?”optional seed(state): Promise<void>;Seeds the attachment’s fresh jar and storage namespace from a storageState in the app’s own
shape (milliseconds expires), which the middle page checks as the library does, turns into
the jar’s shape and hands its shell (ShellControl.seed). Once per attachment, before its first
goto: the library mounts a seeded attach with no target and sends the attach url as that goto
once this resolves. That goto is the attachment’s first load, so it takes the first load’s rule
(ShellGotoOptions.commitFallback). Resolves undefined, so nothing about the jar crosses back.
Refuses, before anything reaches the shell: a seed on the shared jar (the TypeError attachFrame: storageState seeds a fresh jar, so it needs cookies: 'ephemeral'), a malformed one (the
library’s own TypeErrors), a second seed, one sent once a goto was, even one still in flight, and
one on an attachment mounted on a url, which its shell loads itself (each an Error), and a shell
that predates seeding (LocatorUnsupportedError). Absent from a middle page that predates it,
which the library refuses by name.
Parameters
Section titled “Parameters”Returns
Section titled “Returns”Promise<void>
MiddleGotoOptions
Section titled “MiddleGotoOptions”type MiddleGotoOptions = object;A goto on the middle page’s control channel, as a library sends it; the middle page hands it on to
the shell as it came. Its own names, which never change with the public GotoOptions: the public
timeout travels as timeoutMs.
Properties
Section titled “Properties”domains?
Section titled “domains?”optional domains?: string[];timeoutMs?
Section titled “timeoutMs?”optional timeoutMs?: number;The goto’s deadline in milliseconds, 30000 when absent.
waitUntil?
Section titled “waitUntil?”optional waitUntil?: "load" | "commit" | "documentstart";'load', the default, once the goto’s document fired load. 'commit', the public value: the
goto resolves once its document holds the frame, and rejects when none came by the deadline. A
shell that predates it reads 'commit' as 'load', which never resolves before commit.
'documentstart', which no current library sends, keeps its wire meaning for every library that
predates 'commit': resolving as soon as the navigation starts.
MountDescriptor
Section titled “MountDescriptor”type MountDescriptor = object;Everything an app needs to mount a package’s tenant in its OWN document.
Properties
Section titled “Properties”from: string;the connecting app, as the BROKER knows it
name: string;origin
Section titled “origin”origin: string;the tenant origin alone, which is what a postMessage to that frame must target
uri: string;the version-free identity, echoed to the package in the port message
url: string;where to point the iframe: the tenant origin plus the package’s path
version
Section titled “version”version: string | null;OverlayRect
Section titled “OverlayRect”type OverlayRect = object;Viewport rect plus optional corner radii, as the overlay host reports them.
Properties
Section titled “Properties”height
Section titled “height”height: number;radius?
Section titled “radius?”optional radius?: [number, number, number, number];width: number;x: number;y: number;OverlayState
Section titled “OverlayState”type OverlayState = object;What the host page pushes to the broker frame so its UI stays clickable through app chrome.
Properties
Section titled “Properties”hidden
Section titled “hidden”hidden: HiddenSurface[];inset: object;top: number;modal: boolean;rects: OverlayRect[];view: object;height
Section titled “height”height: number;width: number;PackageQuery
Section titled “PackageQuery”type PackageQuery = object;Properties
Section titled “Properties”optional id?: string;host app scope, e.g. ‘stub’ - becomes the keyword fkn-<type>--<id>
origin?
Section titled “origin?”optional origin?: "npm";package source; npm is the only origin implemented
optional size?: number;result count, clamped to 1..100
optional text?: string;free text mixed into the registry query
type: string;package kind, e.g. ‘plugin’ - becomes the keyword fkn-type:<type>
PackageResult
Section titled “PackageResult”type PackageResult = object;Properties
Section titled “Properties”description
Section titled “description”description: string;downloadsMonthly
Section titled “downloadsMonthly”downloadsMonthly: number | null;installed
Section titled “installed”installed: boolean;installed by the calling app
keywords
Section titled “keywords”keywords: string[];links: object;homepage?
Section titled “homepage?”optional homepage?: string;optional npm?: string;repository?
Section titled “repository?”optional repository?: string;name: string;origin
Section titled “origin”origin: "npm";publisher
Section titled “publisher”publisher: string | null;uri: string;normalized version-free uri, e.g. ‘npm:@banou/stub-plugin-foo’
version
Section titled “version”version: string;latest version per the search index - display only, install re-resolves from the packument
PackagesErrorCode
Section titled “PackagesErrorCode”type PackagesErrorCode = | "invalid" | "not-installed" | "unaddressable" | "timeout" | "unavailable" | "denied";PackagesFail
Section titled “PackagesFail”type PackagesFail = object;Properties
Section titled “Properties”error: PackagesErrorCode;message
Section titled “message”message: string;PickOptions
Section titled “PickOptions”type PickOptions = object;Properties
Section titled “Properties”multiple?
Section titled “multiple?”optional multiple?: boolean;title?
Section titled “title?”optional title?: string;untrusted, rendered as text in the picker header
Placement
Section titled “Placement”type Placement = object;Properties
Section titled “Properties”optional clip?: SurfaceRect;the part of rect still visible after the placeholder’s scroll ancestors clip it
radius?
Section titled “radius?”optional radius?: Radii;the placeholder’s corner radii, so the frame follows a rounded container
rect: SurfaceRect;where the package frame sits, so its own layout gets the full box
ProxyFetch
Section titled “ProxyFetch”type ProxyFetch = (input, init) => Promise<Response>;Parameters
Section titled “Parameters”Returns
Section titled “Returns”Promise<Response>
ProxyFetchInit
Section titled “ProxyFetchInit”type ProxyFetchInit = RequestInit & object | undefined;What a cloud.fetch accepts beyond the platform’s own RequestInit.
spread sends THIS request through any healthy node, taken in turn, instead of the node the
WebVPN session is on. The default keeps every request on that one node: it is the node the header
names, and it is what an upstream that remembers a source address expects. Spreading is for an
upstream that meters per address, where it multiplies the budget by the number of healthy nodes.
AniList is the measured case: its live bucket answers x-ratelimit-limit: 30 a minute per
address, shared by every user behind one node.
A spread request is the app’s own choice and is not announced: the header keeps naming the session’s node, which every request not carrying this flag still goes through. Only the cloud backend reads it; the extension and the desktop fetch from the user’s own address and ignore it.
ProxyFetchInput
Section titled “ProxyFetchInput”type ProxyFetchInput = string | URL | Request;type Quota = object;Metered proxy usage for the account behind the broker.
Properties
Section titled “Properties”bytesPerSecond
Section titled “bytesPerSecond”bytesPerSecond: number;limitBytes
Section titled “limitBytes”limitBytes: number;overQuota
Section titled “overQuota”overQuota: boolean;premium
Section titled “premium”premium: boolean;remaining
Section titled “remaining”remaining: number;usedBytes
Section titled “usedBytes”usedBytes: number;type Radii = [number, number, number, number];corner radii in css order: top-left, top-right, bottom-right, bottom-left
Resolvers
Section titled “Resolvers”type Resolvers = object;Everything the broker exposes over osra.
The flat members at the bottom duplicate members of cloud and overlay. They predate the
namespaced form and are kept because a published consumer may still be calling them: they are
contract, not dead code.
Properties
Section titled “Properties”account
Section titled “account”account: object;info: () => Promise<Account | null>;Returns
Section titled “Returns”login: (consumerOrigin) => Promise<boolean>;Parameters
Section titled “Parameters”consumerOrigin
Section titled “consumerOrigin”string
Returns
Section titled “Returns”Promise<boolean>
logout
Section titled “logout”logout: () => void;Returns
Section titled “Returns”void
onChange
Section titled “onChange”onChange: (listener) => () => void;Parameters
Section titled “Parameters”listener
Section titled “listener”(change?) => void
Returns
Section titled “Returns”() => void
cloud: object;dns: object;dns.lookup
Section titled “dns.lookup”lookup: DnsLookup;fetch: ProxyFetch;fs: object;fs.accountPin
Section titled “fs.accountPin”accountPin: () => Promise<string>;A fresh opaque pin for the account signed in now, under the calling app. It names nobody: every call answers a new value and two pins cannot be compared. A broker without this member cannot pin, and the library sends it no storage call at all.
Returns
Section titled “Returns”Promise<string>
fs.availability
Section titled “fs.availability”availability: () => Promise<ConnectAvailability>;Returns
Section titled “Returns”fs.available
Section titled “fs.available”available: () => Promise<boolean>;Returns
Section titled “Returns”Promise<boolean>
fs.encryption
Section titled “fs.encryption”encryption: () => Promise<EncryptionState>;Returns
Section titled “Returns”fs.list
Section titled “fs.list”list: (opts?) => Promise<StorageEntry[]>;Parameters
Section titled “Parameters”Returns
Section titled “Returns”fs.promptAdopt
Section titled “fs.promptAdopt”promptAdopt: (request) => Promise<boolean>;Parameters
Section titled “Parameters”request
Section titled “request”Returns
Section titled “Returns”Promise<boolean>
fs.promptConflict
Section titled “fs.promptConflict”promptConflict: (request) => Promise<ConflictChoice>;Parameters
Section titled “Parameters”request
Section titled “request”Returns
Section titled “Returns”fs.quota
Section titled “fs.quota”quota: () => Promise<StorageQuota>;Returns
Section titled “Returns”fs.readFile
Section titled “fs.readFile”readFile: (path, opts?) => Promise<Uint8Array>;Parameters
Section titled “Parameters”string
Returns
Section titled “Returns”Promise<Uint8Array>
fs.readFileSealed
Section titled “fs.readFileSealed”readFileSealed: (path, opts?) => Promise<{ bytes: Uint8Array; sealedAt: number | null;}>;The same read as readFile, plus the seal time the envelope authenticates, in milliseconds,
or null for an envelope that carries no such field.
Authenticated means the server can neither forge nor alter it, because it is covered by the envelope’s AAD; it is still the WRITER’s own claim about when it sealed, so on its own it does not prove that this copy is the newest one.
Parameters
Section titled “Parameters”string
Returns
Section titled “Returns”Promise<{
bytes: Uint8Array;
sealedAt: number | null;
}>
fs.remove
Section titled “fs.remove”remove: (path, opts?) => Promise<void>;Parameters
Section titled “Parameters”string
Returns
Section titled “Returns”Promise<void>
fs.setAdoptSource
Section titled “fs.setAdoptSource”setAdoptSource: (next, run) => void;Parameters
Section titled “Parameters”AdoptState | null
(() => Promise<void>) | null
Returns
Section titled “Returns”void
fs.unlock
Section titled “fs.unlock”unlock: () => Promise<boolean>;Returns
Section titled “Returns”Promise<boolean>
fs.writeFile
Section titled “fs.writeFile”writeFile: (path, data, contentType, opts?) => Promise<void>;Parameters
Section titled “Parameters”string
contentType
Section titled “contentType”string | null
Returns
Section titled “Returns”Promise<void>
quota: () => Promise<Quota>;Returns
Section titled “Returns”webvpn
Section titled “webvpn”webvpn: object;webvpn.tcpSocket
Section titled “webvpn.tcpSocket”tcpSocket: (options) => Promise<TcpSocketResult>;Parameters
Section titled “Parameters”options
Section titled “options”Returns
Section titled “Returns”webvpn.tcpSocketListener
Section titled “webvpn.tcpSocketListener”tcpSocketListener: (options) => Promise<TcpSocketListenerResult>;Parameters
Section titled “Parameters”options
Section titled “options”Returns
Section titled “Returns”Promise<TcpSocketListenerResult>
webvpn.udpSocket
Section titled “webvpn.udpSocket”udpSocket: (options) => Promise<UdpSocketResult>;Parameters
Section titled “Parameters”options
Section titled “options”Returns
Section titled “Returns”connect
Section titled “connect”connect: object;prompt
Section titled “prompt”prompt: (consumerOrigin) => Promise<boolean>;Parameters
Section titled “Parameters”consumerOrigin
Section titled “consumerOrigin”string
Returns
Section titled “Returns”Promise<boolean>
dnsLookup
Section titled “dnsLookup”dnsLookup: DnsLookup;frameConsent
Section titled “frameConsent”frameConsent: object;ensure
Section titled “ensure”ensure: (request) => Promise<boolean>;the legacy single-row entry, kept so a pinned library keeps working
Parameters
Section titled “Parameters”request
Section titled “request”Returns
Section titled “Returns”Promise<boolean>
request
Section titled “request”request: (requests) => Promise<FrameConsentAnswer[]>;one card with a row per request; answers in request order
Parameters
Section titled “Parameters”requests
Section titled “requests”Returns
Section titled “Returns”hideInstallPrompt
Section titled “hideInstallPrompt”hideInstallPrompt: () => void;Returns
Section titled “Returns”void
installPrompt
Section titled “installPrompt”installPrompt: object;hide: () => void;Returns
Section titled “Returns”void
show: (reason?) => Promise<void>;Parameters
Section titled “Parameters”reason?
Section titled “reason?”string
Returns
Section titled “Returns”Promise<void>
overlay
Section titled “overlay”overlay: object;setHost
Section titled “setHost”setHost: SetOverlayHost;packages
Section titled “packages”packages: object;connect
Section titled “connect”connect: (uri, options?) => Promise< | PackagesFail | { closed: Promise<void>; port: MessagePort;}>;Parameters
Section titled “Parameters”string
options?
Section titled “options?”Returns
Section titled “Returns”Promise<
| PackagesFail
| {
closed: Promise<void>;
port: MessagePort;
}>
frame: (uri) => Promise<PackagesFail | MountDescriptor>;Parameters
Section titled “Parameters”string
Returns
Section titled “Returns”Promise<PackagesFail | MountDescriptor>
hide: (uri) => Promise< | PackagesFail | { ok: true;}>;Parameters
Section titled “Parameters”string
Returns
Section titled “Returns”Promise<
| PackagesFail
| {
ok: true;
}>
install
Section titled “install”install: (uri, options?) => Promise< | PackagesFail | { installed: InstalledPackage;} | { declined: true;}>;Parameters
Section titled “Parameters”string
options?
Section titled “options?”Returns
Section titled “Returns”Promise<
| PackagesFail
| {
installed: InstalledPackage;
}
| {
declined: true;
}>
list: () => Promise<{ results: InstalledPackage[];}>;Returns
Section titled “Returns”Promise<{
results: InstalledPackage[];
}>
pick: (query, options?) => Promise< | PackagesFail | { failed: string[]; results: PackageResult[];} | { declined: true;}>;Parameters
Section titled “Parameters”options?
Section titled “options?”Returns
Section titled “Returns”Promise<
| PackagesFail
| {
failed: string[];
results: PackageResult[];
}
| {
declined: true;
}>
search
Section titled “search”search: (query) => Promise< | PackagesFail | { results: PackageResult[];}>;Parameters
Section titled “Parameters”Returns
Section titled “Returns”Promise<
| PackagesFail
| {
results: PackageResult[];
}>
show: (uri, placement) => Promise< | PackagesFail | { ok: true;}>;Parameters
Section titled “Parameters”string
placement
Section titled “placement”Returns
Section titled “Returns”Promise<
| PackagesFail
| {
ok: true;
}>
uninstall
Section titled “uninstall”uninstall: (uri) => Promise< | PackagesFail | { ok: true;}>;Parameters
Section titled “Parameters”string
Returns
Section titled “Returns”Promise<
| PackagesFail
| {
ok: true;
}>
proxyFetch
Section titled “proxyFetch”proxyFetch: ProxyFetch;relay: object;prompt
Section titled “prompt”prompt: () => Promise<string>;Returns
Section titled “Returns”Promise<string>
rooms: object;available
Section titled “available”available: () => Promise<boolean>;Returns
Section titled “Returns”Promise<boolean>
create
Section titled “create”create: (options?) => Promise<RoomsFail | RoomHandle>;open under a random name
Parameters
Section titled “Parameters”options?
Section titled “options?”Returns
Section titled “Returns”Promise<RoomsFail | RoomHandle>
join: (invite, options?) => Promise<RoomsFail | RoomHandle>;Parameters
Section titled “Parameters”invite
Section titled “invite”string
options?
Section titled “options?”Returns
Section titled “Returns”Promise<RoomsFail | RoomHandle>
open: (name, options?) => Promise<RoomsFail | RoomHandle>;a name under the calling app’s scope, or global/<name>; the room comes into being when nothing is there
Parameters
Section titled “Parameters”string
options?
Section titled “options?”Returns
Section titled “Returns”Promise<RoomsFail | RoomHandle>
setOverlayHost
Section titled “setOverlayHost”setOverlayHost: SetOverlayHost;shell: object;applyUpdate
Section titled “applyUpdate”applyUpdate: () => Promise<boolean>;Returns
Section titled “Returns”Promise<boolean>
onUpdate
Section titled “onUpdate”onUpdate: (callback) => () => void;Parameters
Section titled “Parameters”callback
Section titled “callback”() => void
Returns
Section titled “Returns”() => void
onUpdateTaken
Section titled “onUpdateTaken”onUpdateTaken: (callback) => () => void;Parameters
Section titled “Parameters”callback
Section titled “callback”() => void
Returns
Section titled “Returns”() => void
updateReady
Section titled “updateReady”updateReady: () => Promise<boolean>;Returns
Section titled “Returns”Promise<boolean>
showInstallPrompt
Section titled “showInstallPrompt”showInstallPrompt: (reason?) => Promise<void>;Parameters
Section titled “Parameters”reason?
Section titled “reason?”string
Returns
Section titled “Returns”Promise<void>
storage
Section titled “storage”storage: object;Objects sealed here under a key the app holds and served to anyone holding the url. put, list
and delete act for the calling app under the account its pin was taken under; get needs no
account at all. The data and the key cross to this frame and stay in the browser: the api hears
only sizes and ids, the store only sealed bytes.
available
Section titled “available”available: () => Promise<boolean>;whether put, list and delete can run here: storage is configured, the data plane serves it, and an account is connected under the caller
Returns
Section titled “Returns”Promise<boolean>
delete
Section titled “delete”delete: (url, options) => Promise< | StorageFail | { ok: true;}>;Parameters
Section titled “Parameters”string
options
Section titled “options”accountPin
Section titled “accountPin”string
Returns
Section titled “Returns”Promise<
| StorageFail
| {
ok: true;
}>
get: (url, key, options?) => Promise<StorageFail | StoredHandle>;Parameters
Section titled “Parameters”string
string
options?
Section titled “options?”signal?
Section titled “signal?”AbortSignal
Returns
Section titled “Returns”Promise<StorageFail | StoredHandle>
list: (options) => Promise<StorageFail | StoredPage>;Parameters
Section titled “Parameters”options
Section titled “options”accountPin
Section titled “accountPin”string
cursor?
Section titled “cursor?”string
limit?
Section titled “limit?”number
Returns
Section titled “Returns”Promise<StorageFail | StoredPage>
put: (data, options) => Promise< | StorageFail| StoredObject & object>;Parameters
Section titled “Parameters”Blob | ReadableStream<Uint8Array>
options
Section titled “options”Returns
Section titled “Returns”Promise<
| StorageFail
| StoredObject & object>
webVpnTcpSocket
Section titled “webVpnTcpSocket”webVpnTcpSocket: (options) => Promise<TcpSocketResult>;Parameters
Section titled “Parameters”options
Section titled “options”Returns
Section titled “Returns”webVpnTcpSocketListener
Section titled “webVpnTcpSocketListener”webVpnTcpSocketListener: (options) => Promise<TcpSocketListenerResult>;Parameters
Section titled “Parameters”options
Section titled “options”Returns
Section titled “Returns”Promise<TcpSocketListenerResult>
webVpnUdpSocket
Section titled “webVpnUdpSocket”webVpnUdpSocket: (options) => Promise<UdpSocketResult>;Parameters
Section titled “Parameters”options
Section titled “options”Returns
Section titled “Returns”RoomBacklog
Section titled “RoomBacklog”type RoomBacklog = object;What a backlog page answered: the highest seq it sent, and whether another page follows.
Properties
Section titled “Properties”last: number;more: boolean;RoomClaimOptions
Section titled “RoomClaimOptions”type RoomClaimOptions = object;What a claim carries besides the name.
Properties
Section titled “Properties”description?
Section titled “description?”optional description?: string;What the room is for, in the app’s own words. The account reads it beside the room in its fkn.app
settings, where it can clear or unclaim the room, so say what would be lost. One line of plain text:
trimmed, then 1 to 200 characters as String.length counts them, with no control character, line or
paragraph separator, or bidi control; anything else is refused invalid, never cut short. Not sealed:
stored with the claim and shown to the account only. Claiming again with one replaces it: on a room
under an app’s scope from the app that claimed the room only (the same app once it is verified), and
from another app it is refused denied (rooms: only the app that claimed the room can describe it);
on a global room from any app of the account. Claiming without one keeps it.
mailbox?
Section titled “mailbox?”optional mailbox?: boolean;Whether the room keeps its messages. false claims the name and stores nothing: a message reaches
whoever is present and is kept nowhere, backlog answers an empty page, and edit and delete are
refused invalid (rooms: the room keeps no messages). The claim still reserves the name, locks it
to the key and keeps the owner, the blocks and the overrides when everyone leaves, and it still needs
premium. true or no value keeps a mailbox. Anything else is refused invalid (rooms: malformed frame).
Read only when the call starts the claim: on a room the account already holds it is ignored, so an
app that claims on every open never undoes what the owner chose since. A claim landing after a
temporary one ran out starts a new claim, so it reads it again. A broker too old to carry it refuses
false unavailable (rooms: the mailbox switch is not available) rather than store what the app
asked it not to.
temporary?
Section titled “temporary?”optional temporary?: boolean | number;Makes the claim end by itself, in milliseconds: true is 7 days (ROOM_TEMPORARY_MS.default), a
number is that many milliseconds, a whole number from 60,000 (1 minute) to 31,536,000,000 (365 days),
and anything else is refused invalid. false or no value makes the claim permanent.
The clock restarts on every claim, so a temporary room ends that long after its LAST claim: a room
the app keeps claiming on open stays, and an abandoned one goes. Restarting the clock needs the
service: while it cannot be reached, a claim answers unavailable and the room keeps the end it had,
so a room in use can still end if an outage outlasts the time it has left. Pick a duration with margin
over how often the app is opened. When it ends, it ends exactly as an
Unclaim from the account’s fkn.app settings does: the name is given back, the stored messages are
deleted, and whoever is present hears a claim event with claimed: false and stays in an ordinary
room. It counts toward the account’s room limit while it lasts and frees the slot when it ends.
The latest claim decides: claiming again without it makes the room permanent, and with it makes it
temporary again. On a room under an app’s scope only the app that claimed the room (the same app
once it is verified) sets or changes it, and from another app it is refused denied (rooms: only the app that claimed the room can set when it expires); on a global room any app of the account
does. A claim from another app without it leaves the room as it was, on either kind of room.
RoomCreateOptions
Section titled “RoomCreateOptions”type RoomCreateOptions = RoomOpenOptions;RoomDefaults
Section titled “RoomDefaults”type RoomDefaults = Readonly<{ maxMessageBytes: number; receive: boolean; send: boolean;}>;What a member gets unless an override says otherwise. maxMessageBytes is measured on the wire: nonce plus ciphertext, base64url.
RoomEnd
Section titled “RoomEnd”type RoomEnd = object;Why the room ended for this app. It ends once.
Properties
Section titled “Properties”reason
Section titled “reason”reason: "left" | "removed" | "blocked" | "ended" | "unavailable";RoomEvent
Section titled “RoomEvent”type RoomEvent = | { message: RoomMessage; replayed: boolean; type: "message";} | { message: RoomMessage; type: "edited";} | { from: number; to: number; type: "deleted";} | { member: RoomMember; type: "joined";} | { id: string; reason: "left" | "removed" | "blocked"; type: "left";} | { id: string; maxMessageBytes: number; permissions: RoomPermissions; type: "permissions";} | { defaults: RoomDefaults; type: "defaults";} | { claimed: boolean; mailbox: boolean; owner: string; type: "claim";};Union Members
Section titled “Union Members”Type Literal
Section titled “Type Literal”{ message: RoomMessage; replayed: boolean; type: "message";}replayed when the message predates this connection: a backlog page, never a live send
Type Literal
Section titled “Type Literal”{ message: RoomMessage; type: "edited";}Type Literal
Section titled “Type Literal”{ from: number; to: number; type: "deleted";}stored messages dropped: by a member, or all of them when the account clears the room in its fkn.app settings
Type Literal
Section titled “Type Literal”{ member: RoomMember; type: "joined";}Type Literal
Section titled “Type Literal”{ id: string; reason: "left" | "removed" | "blocked"; type: "left";}Type Literal
Section titled “Type Literal”{ id: string; maxMessageBytes: number; permissions: RoomPermissions; type: "permissions";}Type Literal
Section titled “Type Literal”{ defaults: RoomDefaults; type: "defaults";}Type Literal
Section titled “Type Literal”{ claimed: boolean; mailbox: boolean; owner: string; type: "claim";}the room was claimed, released (by its app, or by the account in its fkn.app settings) or
dissolved, or its mailbox was turned off or on; owner is the owner’s member id, or ” while a
claimed room’s owner has never joined. mailbox is whether the room now keeps messages, always
false while claimed is false. Turning a mailbox off sends no deleted: what the app shows stays.
RoomHandle
Section titled “RoomHandle”type RoomHandle = object;A joined room, held by the broker: it owns the socket, the room key and the derived message key, and hands the app plaintext and member ids only.
Every member that can be refused answers with a RoomsFail rather than throwing, so a refusal
survives the osra hop as data. leave and on cannot be refused.
Properties
Section titled “Properties”backlog
Section titled “backlog”backlog: (after, limit?) => Promise<RoomsFail | RoomBacklog>;replays stored messages above after as message events marked replayed, one page at a time
Parameters
Section titled “Parameters”number
limit?
Section titled “limit?”number
Returns
Section titled “Returns”Promise<RoomsFail | RoomBacklog>
block: (id) => Promise< | RoomsFail | { ok: true;}>;a member sent out and kept out, with the block permission (denied, rooms: permission denied).
From another app of the claim’s account on a room claimed under an app’s scope, denied (rooms: only the app that claimed the room can change it), as claim says.
Parameters
Section titled “Parameters”string
Returns
Section titled “Returns”Promise<
| RoomsFail
| {
ok: true;
}>
claim: (options?) => Promise< | RoomsFail | { ok: true;}>;keeps the name for the signed-in premium account, and a mailbox unless mailbox is false; the only
thing in rooms that premium buys. description says what the room is for, shown to the account in
its fkn.app settings. temporary makes the claim end by itself that many milliseconds after its last
claim (true is 7 days); the broker carries it as a number of milliseconds and never as true.
mailbox is read only when the call starts the claim.
A room under an app’s scope, which is every room but a global one, is changed by the claim’s
account only through the app that claimed it (the same app once it is verified): from another app of
the account setDefault, limit, grant, revoke, remove, block, unblock, setMailbox,
edit and delete answer denied (rooms: only the app that claimed the room can change it), the
account’s own messages included, and unavailable while the room cannot tell whether two apps are
one. A claimed global room is changed by any app of the account, which also describes it, sets its
temporary and releases it. The account’s fkn.app settings
change every room it claimed, and members of other accounts are answered as in any room.
Past the account’s room limit the call waits while fkn.app shows the person their claimed rooms over
your app, with Unclaim on each: it answers { ok: true } once one is unclaimed and this claim is
made, and full (rooms: too many claims) when they close the card or when fkn.app cannot show it.
Nothing about the account’s other rooms reaches your app.
Parameters
Section titled “Parameters”options?
Section titled “options?”Returns
Section titled “Returns”Promise<
| RoomsFail
| {
ok: true;
}>
claimed
Section titled “claimed”claimed: boolean;closed
Section titled “closed”closed: Promise<RoomEnd>;settles once, when the room ends for this app. Never rejects.
defaults
Section titled “defaults”defaults: () => Promise<RoomDefaults>;Returns
Section titled “Returns”delete
Section titled “delete”delete: (from, to?) => Promise< | RoomsFail | { ok: true;}>;stored messages dropped: one of the sender’s own, or any range as the owner. From another app of the
claim’s account on a room claimed under an app’s scope, denied (rooms: only the app that claimed the room can change it), the account’s own messages included, as claim says.
Parameters
Section titled “Parameters”number
number
Returns
Section titled “Returns”Promise<
| RoomsFail
| {
ok: true;
}>
edit: (seq, text) => Promise< | RoomsFail | { ok: true;}>;a stored message’s text, replaced: the sender’s own, or any as the owner. From another app of the
claim’s account on a room claimed under an app’s scope, denied (rooms: only the app that claimed the room can change it), the account’s own messages included, as claim says.
Parameters
Section titled “Parameters”number
string
Returns
Section titled “Returns”Promise<
| RoomsFail
| {
ok: true;
}>
grant: (id, permission) => Promise< | RoomsFail | { ok: true;}>;a member’s override of a permission, set to true, from the owner only (denied, rooms: not the room owner). From another app of the claim’s account on a room claimed under an app’s scope,
denied (rooms: only the app that claimed the room can change it), as claim says.
Parameters
Section titled “Parameters”string
permission
Section titled “permission”Returns
Section titled “Returns”Promise<
| RoomsFail
| {
ok: true;
}>
id: string;<scope>/<name>: the name under the app’s own scope, or under global
invite
Section titled “invite”invite: string;<key>.<id> as one string, the thing to put in a link
key: string;the room key, base64url. The server never sees it. Anyone holding it and the id can join.
leave: () => Promise<void>;Returns
Section titled “Returns”Promise<void>
limit: (maxMessageBytes, id?) => Promise< | RoomsFail | { ok: true;}>;the message size cap: the room default when no member is named, that member’s override otherwise,
cleared by null. From the owner only (denied, rooms: not the room owner); from another app of the
claim’s account on a room claimed under an app’s scope, denied (rooms: only the app that claimed the room can change it), as claim says.
Parameters
Section titled “Parameters”maxMessageBytes
Section titled “maxMessageBytes”number | null
string
Returns
Section titled “Returns”Promise<
| RoomsFail
| {
ok: true;
}>
mailbox
Section titled “mailbox”mailbox: RoomMailbox | null;mailboxSwitch?
Section titled “mailboxSwitch?”optional mailboxSwitch?: true;set by a broker that carries mailbox on a claim and sends setMailbox. A broker older than that
drops the option and claims with a mailbox, and has no setMailbox, so the lib refuses both on a
handle without it rather than store what the app asked it not to.
members
Section titled “members”members: () => Promise<RoomMember[]>;Returns
Section titled “Returns”name: string;on: (listener) => () => void;the account.onChange shape: one broker-side registration, unsubscribed by the returned function
Parameters
Section titled “Parameters”listener
Section titled “listener”(event) => void
Returns
Section titled “Returns”() => void
owner: string;release
Section titled “release”release: () => Promise< | RoomsFail | { ok: true;}>;Returns
Section titled “Returns”Promise<
| RoomsFail
| {
ok: true;
}>
remove
Section titled “remove”remove: (id) => Promise< | RoomsFail | { ok: true;}>;a member sent out, free to join again, with the remove permission (denied, rooms: permission denied). From another app of the claim’s account on a room claimed under an app’s scope, denied
(rooms: only the app that claimed the room can change it), as claim says.
Parameters
Section titled “Parameters”string
Returns
Section titled “Returns”Promise<
| RoomsFail
| {
ok: true;
}>
revoke
Section titled “revoke”revoke: (id, permission) => Promise< | RoomsFail | { ok: true;}>;a member’s override of a permission, set to false, from the owner only (denied, rooms: not the room owner). From another app of the claim’s account on a room claimed under an app’s scope,
denied (rooms: only the app that claimed the room can change it), as claim says.
Parameters
Section titled “Parameters”string
permission
Section titled “permission”Returns
Section titled “Returns”Promise<
| RoomsFail
| {
ok: true;
}>
self: RoomMember;send: (text) => Promise< | RoomsFail | { ok: true;}>;sealed before it leaves the browser and refused, never truncated, past this member’s maxMessageBytes on the wire
Parameters
Section titled “Parameters”string
Returns
Section titled “Returns”Promise<
| RoomsFail
| {
ok: true;
}>
setDefault
Section titled “setDefault”setDefault: (permission, value) => Promise< | RoomsFail | { ok: true;}>;the room default for send or receive, from the owner only (denied, rooms: not the room owner). From another app of the claim’s account on a room claimed under an app’s scope, denied
(rooms: only the app that claimed the room can change it), as claim says.
Parameters
Section titled “Parameters”permission
Section titled “permission”"send" | "receive"
boolean
Returns
Section titled “Returns”Promise<
| RoomsFail
| {
ok: true;
}>
setMailbox
Section titled “setMailbox”setMailbox: (on) => Promise< | RoomsFail | { ok: true;}>;the owner turns a claimed room’s mailbox off, deleting what it stored, or on, starting it empty.
Answers once the room is in that state and has tried to tell the api its storage figure; the answer
does not say whether the api heard it. From another app of the claim’s account on a room claimed
under an app’s scope, denied (rooms: only the app that claimed the room can change it), as claim says.
Parameters
Section titled “Parameters”boolean
Returns
Section titled “Returns”Promise<
| RoomsFail
| {
ok: true;
}>
temporaryClaims?
Section titled “temporaryClaims?”optional temporaryClaims?: true;set by a broker that carries temporary on a claim. A broker older than that drops the option and
makes the claim permanent, so the lib refuses a temporary claim on a handle without it rather than
let the room outlive what the app asked for.
unblock
Section titled “unblock”unblock: (id) => Promise< | RoomsFail | { ok: true;}>;a block lifted, with the block permission (denied, rooms: permission denied). From another app
of the claim’s account on a room claimed under an app’s scope, denied (rooms: only the app that claimed the room can change it), as claim says.
Parameters
Section titled “Parameters”string
Returns
Section titled “Returns”Promise<
| RoomsFail
| {
ok: true;
}>
usage: () => Promise<RoomsFail | RoomMailbox | null>;Returns
Section titled “Returns”Promise<RoomsFail | RoomMailbox | null>
RoomJoinOptions
Section titled “RoomJoinOptions”type RoomJoinOptions = object;Properties
Section titled “Properties”signal?
Section titled “signal?”optional signal?: AbortSignal;RoomMailbox
Section titled “RoomMailbox”type RoomMailbox = object;What a claimed room’s mailbox holds, as the room last said. Null for a room that keeps no messages:
one nobody has claimed, or a claim whose mailbox is off. cap is the most it stores: 500 MB, or the
size limit the account set in its fkn.app settings.
Properties
Section titled “Properties”archived
Section titled “archived”archived: boolean;bytes: number;cap: number;messages
Section titled “messages”messages: number;RoomMember
Section titled “RoomMember”type RoomMember = object;A participant as this room sees them. The id is fresh in every room.
Properties
Section titled “Properties”id: string;maxMessageBytes
Section titled “maxMessageBytes”maxMessageBytes: number;permissions
Section titled “permissions”permissions: RoomPermissions;RoomMessage
Section titled “RoomMessage”type RoomMessage = object;Properties
Section titled “Properties”at: number;from: string;seq: number;text: string;RoomOpenOptions
Section titled “RoomOpenOptions”type RoomOpenOptions = object;Properties
Section titled “Properties”defaults?
Section titled “defaults?”optional defaults?: Partial<RoomDefaults>;optional key?: string;the room key, 32 bytes base64url, minted when absent. Deriving one from something people already share is how a name becomes a rendezvous.
members?
Section titled “members?”optional members?: number;honoured only by the join that brings the room into being
signal?
Section titled “signal?”optional signal?: AbortSignal;aborting it leaves the room; it never bounds the wait for the broker
RoomPermission
Section titled “RoomPermission”type RoomPermission = "send" | "receive" | "remove" | "block";RoomPermissions
Section titled “RoomPermissions”type RoomPermissions = Readonly<Record<RoomPermission, boolean>>;RoomsErrorCode
Section titled “RoomsErrorCode”type RoomsErrorCode = | "invalid" | "not-found" | "bad-key" | "full" | "blocked" | "denied" | "rate-limited" | "too-large" | "storage" | "quota" | "unavailable" | "closed";RoomsFail
Section titled “RoomsFail”type RoomsFail = object;A refusal, as data. packages crosses the hop the same way, and for the same reason.
Properties
Section titled “Properties”error: RoomsErrorCode;message
Section titled “message”message: string;SetOverlayHost
Section titled “SetOverlayHost”type SetOverlayHost = (push, options?) => void;Parameters
Section titled “Parameters”(state) => unknown
options?
Section titled “options?”exactClips?
Section titled “exactClips?”boolean
Returns
Section titled “Returns”void
ShellControl
Section titled “ShellControl”type ShellControl = object;The render proxy shell’s control channel (SHELL_CONTROL_KEY), as its middle page drives it.
policy is the middle page’s realm policy for the call; flushCookies and sweepStorage are
absent from a shell deployed before windows.
Methods
Section titled “Methods”blank()?
Section titled “blank()?”optional blank(): Promise<string>;The url this shell’s empty page is armed for (?blank=), '' when none: a shell mounted with
?url= or nothing, or one whose first goto disarmed it. Absent from a shell that predates blank
pages, which reads no target from ?blank= and so loads nothing.
Returns
Section titled “Returns”Promise<string>
carry()?
Section titled “carry()?”optional carry(hosts): Promise<void>;The hosts this shell’s extension carrier may send a blank page’s own fetch and XHR requests to: the
attachment’s approved set, each call replacing the last. The shell drops every FKN platform host whatever it
is told, and a shell with nothing to carry (a window, an 'ephemeral' jar, a page that is not blank, no
extension that announces the carrier) resolves and carries nothing. A TypeError for anything but an array of
non-empty strings. Absent from a shell that predates the carrier, which sends every request through WebVPN.
Parameters
Section titled “Parameters”string[]
Returns
Section titled “Returns”Promise<void>
clearCookies()?
Section titled “clearCookies()?”optional clearCookies(filter, scope): Promise<void>;Removes the cookies filter matches from this shell’s jar, among the cookies of scope.hosts’
sites only: a cookie is in reach when its domain’s own registered domain is that of one of the
hosts, or its domain is exactly a host that is itself a public suffix, so amazonaws.com reaches
no mybucket.s3.amazonaws.com cookie, a site of its own under s3.amazonaws.com. Resolves
undefined once its live realms dropped them (waiting at most 2000 ms) and the removal is
committed, and takes the same steps when nothing matched, so neither its answer nor its time says
whether the jar held a cookie there. That holds for { equals } options, the only ones its
middle page sends for now: a { pattern, flags } one is still rebuilt and tested against every
cookie in reach, so its running time on them would be part of the call’s.
Refuses, before anything is removed: a filter of any other shape (a TypeError
frame.clearCookies: malformed filter), an empty scope.hosts, and a string domain whose
registered domain is none of the hosts’ (each a LocatorDeniedError naming why). Rejects with the
library’s own message when the jar’s store did not take the removal. Absent from a shell that
predates it.
Parameters
Section titled “Parameters”filter
Section titled “filter”ClearCookiesWire
string[]
Returns
Section titled “Returns”Promise<void>
executeLocator()
Section titled “executeLocator()”executeLocator( parts, operation, args,policy?): Promise<unknown>;Parameters
Section titled “Parameters”operation
Section titled “operation”string
unknown[]
policy?
Section titled “policy?”unknown
Returns
Section titled “Returns”Promise<unknown>
flushCookies()?
Section titled “flushCookies()?”optional flushCookies(): Promise<void>;Resolves once every cookie change made so far is committed to the jar’s store.
Returns
Section titled “Returns”Promise<void>
goto()
Section titled “goto()”goto(url, options?): Promise<void>;Pulls the committed jar first, so a sign-in another realm committed rides this navigation.
Parameters
Section titled “Parameters”string
options?
Section titled “options?”Returns
Section titled “Returns”Promise<void>
ready()
Section titled “ready()”ready(): Promise<boolean>;Returns
Section titled “Returns”Promise<boolean>
seed()?
Section titled “seed()?”optional seed(seed): Promise<void>;Seeds this shell’s jar and storage namespace: the cookies join the jar, recorded as its own,
and each origin’s localStorage items are written where that origin’s pages read them, by the
frame host serving it before the host takes a navigation. Resolves once the jar holds the
cookies and the items of every origin a host serves now are written, so a goto sent afterwards
carries them. Only on a jar of the attachment’s own with a namespace of its own: on the shared
jar (an empty session, a window on its opener’s) a TypeError attachFrame: storageState seeds a fresh jar, so it needs cookies: 'ephemeral', with nothing seeded. A seed of another shape is a
TypeError from the shell’s controller. Absent from a shell that predates it.
Parameters
Section titled “Parameters”JarSeed
Returns
Section titled “Returns”Promise<void>
sweepStorage()?
Section titled “sweepStorage()?”optional sweepStorage(): Promise<void>;Removes a window shell’s own site storage; resolves at once for a shell whose storage is shared.
Returns
Section titled “Returns”Promise<void>
ShellFrameMessage
Section titled “ShellFrameMessage”type ShellFrameMessage = | { data: unknown; kind: "message"; origin: string; targetOrigin: string; transfer: Transferable[]; type: typeof SHELL_FRAME_MESSAGE;} | { kind: "document"; origin: string; type: typeof SHELL_FRAME_MESSAGE;};targetOrigin is the page’s own, normalized: what it addressed the message to. transfer is what
the page moved with it, also the post’s transfer list, for the middle page to move on.
ShellGotoOptions
Section titled “ShellGotoOptions”type ShellGotoOptions = MiddleGotoOptions & object;A goto on the shell’s control channel.
Type Declaration
Section titled “Type Declaration”commitFallback?
Section titled “commitFallback?”optional commitFallback?: boolean;For an attachment’s first navigation: past its deadline, a document that committed but never fired load counts as loaded, the rule the inline attachment’s first load follows. Ignored by a shell deployed before windows, which rejects at the deadline instead.
ShellJarUnreachable
Section titled “ShellJarUnreachable”type ShellJarUnreachable = typeof SHELL_JAR_UNREACHABLE[number];StorageEntry
Section titled “StorageEntry”type StorageEntry = object;Properties
Section titled “Properties”contentType
Section titled “contentType”contentType: string | null;encryption
Section titled “encryption”encryption: string | null;path: string;size: number;updatedAt
Section titled “updatedAt”updatedAt: string;StorageErrorCode
Section titled “StorageErrorCode”type StorageErrorCode = | "invalid" | "not-found" | "integrity" | "denied" | "quota" | "too-many" | "account-changed" | "unavailable";What a storage refusal is about. Branch on it, never on the message.
StorageFail
Section titled “StorageFail”type StorageFail = object;A refusal, as data, the RoomsFail shape. aborted is the app’s own signal, which the library turns
back into the signal’s reason rather than a StorageError.
Properties
Section titled “Properties”error: StorageErrorCode | "aborted";message
Section titled “message”message: string;StorageProgress
Section titled “StorageProgress”type StorageProgress = object;Progress of an upload, ProgressEvent’s two figures, in bytes of the file itself.
Properties
Section titled “Properties”loaded
Section titled “loaded”loaded: number;total: number;StoragePutOptions
Section titled “StoragePutOptions”type StoragePutOptions = object;Properties
Section titled “Properties”optional key?: string;the key that opens the object, 32 bytes as canonical unpadded base64url (43 characters), minted when absent. It never reaches FKN’s servers and never appears in the url: whoever holds the url and the key reads the object.
onProgress?
Section titled “onProgress?”optional onProgress?: (progress) => void;called as each part lands
Parameters
Section titled “Parameters”progress
Section titled “progress”Returns
Section titled “Returns”void
signal?
Section titled “signal?”optional signal?: AbortSignal;aborts the upload and releases the storage it reserved
optional size?: number;required for a ReadableStream: the bytes it will deliver, exactly
StoragePutWire
Section titled “StoragePutWire”type StoragePutWire = StoragePutOptions & object;What the library hands the broker for a put, resolved at the moment of the call.
Type Declaration
Section titled “Type Declaration”accountPin
Section titled “accountPin”accountPin: string;StorageQuota
Section titled “StorageQuota”type StorageQuota = object;Properties
Section titled “Properties”limitBytes
Section titled “limitBytes”limitBytes: number;maxObjects
Section titled “maxObjects”maxObjects: number;objects
Section titled “objects”objects: number;remaining
Section titled “remaining”remaining: number;usedBytes
Section titled “usedBytes”usedBytes: number;StoredHandle
Section titled “StoredHandle”type StoredHandle = object;An object the broker opened: its plaintext size, and its bytes from start to end (exclusive) by
range, each 1 MiB record checked before it is handed over. The stream errors on the first record
that does not open under the key.
Properties
Section titled “Properties”read: (start, end) => Promise<StorageFail | ReadableStream<Uint8Array>>;Parameters
Section titled “Parameters”number
number
Returns
Section titled “Returns”Promise<StorageFail | ReadableStream<Uint8Array>>
size: number;StoredObject
Section titled “StoredObject”type StoredObject = object;A stored object as put and list answer it. Every time is epoch milliseconds.
Properties
Section titled “Properties”created
Section titled “created”created: number;size: number;the file’s own bytes; the account’s storage counts 28 bytes more per 1 MiB
status
Section titled “status”status: "uploading" | "ready";uploading until every part has landed
url: string;https://cdn.fkn.app/<uuid> in production: anyone holding it can download the sealed bytes, and nothing more
StoredPage
Section titled “StoredPage”type StoredPage = object;One page of list, newest first. cursor is present only while more objects remain.
Properties
Section titled “Properties”cursor?
Section titled “cursor?”optional cursor?: string;objects
Section titled “objects”objects: StoredObject[];SurfaceRect
Section titled “SurfaceRect”type SurfaceRect = object;viewport coordinates, the space both the app and the broker frame measure in
Properties
Section titled “Properties”height
Section titled “height”height: number;width: number;x: number;y: number;TcpSocketListenerOptions
Section titled “TcpSocketListenerOptions”type TcpSocketListenerOptions = object;Properties
Section titled “Properties”localAddress
Section titled “localAddress”localAddress: string;localPort
Section titled “localPort”localPort: number;onClose?
Section titled “onClose?”optional onClose?: (error?) => void | Promise<void>;Parameters
Section titled “Parameters”error?
Section titled “error?”Error
Returns
Section titled “Returns”void | Promise<void>
onConnection
Section titled “onConnection”onConnection: (connection) => void | Promise<void>;Parameters
Section titled “Parameters”connection
Section titled “connection”Returns
Section titled “Returns”void | Promise<void>
TcpSocketListenerResult
Section titled “TcpSocketListenerResult”type TcpSocketListenerResult = object;Properties
Section titled “Properties”close: () => Promise<void>;Returns
Section titled “Returns”Promise<void>
localAddress
Section titled “localAddress”localAddress: string;localFamily
Section titled “localFamily”localFamily: IpFamily;localPort
Section titled “localPort”localPort: number;TcpSocketOptions
Section titled “TcpSocketOptions”type TcpSocketOptions = object;Properties
Section titled “Properties”remoteAddress
Section titled “remoteAddress”remoteAddress: string;remotePort
Section titled “remotePort”remotePort: number;TcpSocketResult
Section titled “TcpSocketResult”type TcpSocketResult = object;Properties
Section titled “Properties”dataReadableStream
Section titled “dataReadableStream”dataReadableStream: ReadableStream<Uint8Array>;dataWritableStream
Section titled “dataWritableStream”dataWritableStream: WritableStream<Uint8Array>;destroy
Section titled “destroy”destroy: () => Promise<void>;Returns
Section titled “Returns”Promise<void>
destroySoon
Section titled “destroySoon”destroySoon: () => Promise<void>;Returns
Section titled “Returns”Promise<void>
end: () => Promise<void>;Returns
Section titled “Returns”Promise<void>
localAddress
Section titled “localAddress”localAddress: string;localFamily
Section titled “localFamily”localFamily: IpFamily;localPort
Section titled “localPort”localPort: number;remoteAddress
Section titled “remoteAddress”remoteAddress: string;remoteFamily
Section titled “remoteFamily”remoteFamily: IpFamily;remotePort
Section titled “remotePort”remotePort: number;resetAndDestroy
Section titled “resetAndDestroy”resetAndDestroy: () => Promise<void>;Returns
Section titled “Returns”Promise<void>
setOption
Section titled “setOption”setOption: (option) => Promise<void>;Parameters
Section titled “Parameters”option
Section titled “option”Returns
Section titled “Returns”Promise<void>
UdpDatagram
Section titled “UdpDatagram”type UdpDatagram = object;Properties
Section titled “Properties”address
Section titled “address”address: string;data: ArrayBuffer;family
Section titled “family”family: IpFamily;port: number;size: number;UdpSocketOptions
Section titled “UdpSocketOptions”type UdpSocketOptions = object;Properties
Section titled “Properties”address
Section titled “address”address: string;dataPort?
Section titled “dataPort?”optional dataPort?: boolean;port: number;type: "udp4" | "udp6";UdpSocketResult
Section titled “UdpSocketResult”type UdpSocketResult = object;Properties
Section titled “Properties”close: () => Promise<void>;Returns
Section titled “Returns”Promise<void>
closed
Section titled “closed”closed: Promise<{ reason: string;}>;connect
Section titled “connect”connect: (options) => Promise<{ address: string; family: IpFamily; local: boolean; port: number;}>;Parameters
Section titled “Parameters”options
Section titled “options”remoteAddress
Section titled “remoteAddress”string
remotePort
Section titled “remotePort”number
Returns
Section titled “Returns”Promise<{
address: string;
family: IpFamily;
local: boolean;
port: number;
}>
dataPort
Section titled “dataPort”dataPort: MessagePort | undefined;dataPortAcks
Section titled “dataPortAcks”dataPortAcks: true | undefined;dataReadableStream
Section titled “dataReadableStream”dataReadableStream: ReadableStream<UdpDatagram>;disconnect
Section titled “disconnect”disconnect: () => Promise<void>;Returns
Section titled “Returns”Promise<void>
localAddress
Section titled “localAddress”localAddress: string;localFamily
Section titled “localFamily”localFamily: IpFamily;localPort
Section titled “localPort”localPort: number;send: (options) => Promise<void>;Parameters
Section titled “Parameters”options
Section titled “options”address?
Section titled “address?”string
message
Section titled “message”ArrayBuffer
number
Returns
Section titled “Returns”Promise<void>
setOption
Section titled “setOption”setOption: (option) => Promise<void>;Parameters
Section titled “Parameters”option
Section titled “option”Returns
Section titled “Returns”Promise<void>
socketId
Section titled “socketId”socketId: number;WindowMiddleControl
Section titled “WindowMiddleControl”type WindowMiddleControl = MiddleControl & object;What a window’s middle page adds to its channel.
Type Declaration
Section titled “Type Declaration”flushCookies()
Section titled “flushCookies()”flushCookies(): Promise<void>;Resolves once every cookie change made in the window so far is committed to its jar.
Returns
Section titled “Returns”Promise<void>
ping()
Section titled “ping()”ping(): Promise<true>;The app’s heartbeat: a window that hears none for long enough stops answering.
Returns
Section titled “Returns”Promise<true>
requestConsent()
Section titled “requestConsent()”requestConsent(requests): Promise<FrameConsentAnswer[]>;Draws the consent card in the window and answers each request in order.
Parameters
Section titled “Parameters”requests
Section titled “requests”Returns
Section titled “Returns”sweepStorage()
Section titled “sweepStorage()”sweepStorage(): Promise<void>;Removes the proxied site storage this window kept to itself, for an app about to close it. Resolves at once for a window on the web origin’s own jar, whose storage is the app’s.
Returns
Section titled “Returns”Promise<void>
WriteData
Section titled “WriteData”type WriteData = ArrayBuffer | Uint8Array | string;Variables
Section titled “Variables”ATTACH_FRAME_KEY
Section titled “ATTACH_FRAME_KEY”const ATTACH_FRAME_KEY: "fkn-attach-frame" = 'fkn-attach-frame';The osra key of an inline attachment’s channel, which /attach-frame exposes to the library.
ATTACH_WINDOW_KEY
Section titled “ATTACH_WINDOW_KEY”const ATTACH_WINDOW_KEY: "fkn-attach-window" = 'fkn-attach-window';The osra key of a window attachment’s channel, which /attach-window exposes to its opener.
ATTACH_WINDOW_MESSAGE
Section titled “ATTACH_WINDOW_MESSAGE”const ATTACH_WINDOW_MESSAGE: object;What an app and its window post to each other, every message carrying the attach id.
Type Declaration
Section titled “Type Declaration”detach
Section titled “detach”readonly detach: "fkn-attach-window-detach" = 'fkn-attach-window-detach';app to window, whenever the app ends the attachment (its pagehide included): stop answering this
app. unanswered: true when it ended because the window stopped answering its pings.
readonly gone: "fkn-attach-window-gone" = 'fkn-attach-window-gone';window to app: this window no longer answers the app, because it is going away or was dropped
readonly hello: "fkn-attach-window" = 'fkn-attach-window';app to window, repeated until the channel connects
refused
Section titled “refused”readonly refused: "fkn-attach-window-refused" = 'fkn-attach-window-refused';window to app, { reason }: the window loaded nothing and exposes nothing
FRAME_MESSAGE
Section titled “FRAME_MESSAGE”const FRAME_MESSAGE: "fkn-frame-message" = 'fkn-frame-message';Posted by a middle page to its app for the Frame’s listeners (FrameMessageRelay), with the page’s
ports as the transfer list. Only for a document inside the attachment, and a message only when the
page addressed it to the app’s own origin.
JAR_ANCHOR_MESSAGE
Section titled “JAR_ANCHOR_MESSAGE”const JAR_ANCHOR_MESSAGE: object;What a window’s middle page, the jar anchor its app mounted (/attach-jar) and the anchor’s jar
host say, all with the attach id.
Type Declaration
Section titled “Type Declaration”readonly hello: "fkn-jar-hello" = 'fkn-jar-hello';window to each frame of its opener: is the anchor for this attachment here?
readonly host: "fkn-jar-host" = 'fkn-jar-host';jar host to anchor: the answer, the only one a port is relayed to
readonly port: "fkn-jar-port" = 'fkn-jar-port';window to anchor, and anchor to jar host, carrying exactly one port
readonly ready: "fkn-jar-ready" = 'fkn-jar-ready';anchor to the window it accepted
readonly who: "fkn-jar-who" = 'fkn-jar-who';anchor to jar host, after every load of the host frame: are you the jar host?
ROOM_TEMPORARY_MS
Section titled “ROOM_TEMPORARY_MS”const ROOM_TEMPORARY_MS: object;How long a temporary claim may last, in milliseconds: default is what temporary: true means (7
days), and a number outside min (1 minute) to max (365 days) is refused invalid.
Type Declaration
Section titled “Type Declaration”default
Section titled “default”readonly default: 604800000 = 604_800_000;readonly max: 31536000000 = 31_536_000_000;readonly min: 60000 = 60_000;SHELL_ATTACH_ERROR
Section titled “SHELL_ATTACH_ERROR”const SHELL_ATTACH_ERROR: "sdbx-attach-error" = 'sdbx-attach-error';Posted by a shell that could not start, { type, message }, to the middle page framing it.
SHELL_CONTROL_KEY
Section titled “SHELL_CONTROL_KEY”const SHELL_CONTROL_KEY: "sdbx-control" = 'sdbx-control';The osra key of the render proxy shell’s control channel, which its middle page drives.
SHELL_FRAME_MESSAGE
Section titled “SHELL_FRAME_MESSAGE”const SHELL_FRAME_MESSAGE: "sdbx-frame-message" = 'sdbx-frame-message';Posted by the render proxy shell to its middle page (ShellFrameMessage), with the page’s ports as
the transfer list: what the page posted to an origin not its own, and each document’s arrival. The
shell does not know the app, so the middle page decides what reaches it.
SHELL_JAR_MESSAGE
Section titled “SHELL_JAR_MESSAGE”const SHELL_JAR_MESSAGE: object;What a window’s shell and its middle page say about the shell’s cookie jar, all with the attach id.
Type Declaration
Section titled “Type Declaration”readonly mode: "sdbx-jar-mode" = 'sdbx-jar-mode';shell to middle page, { mode, reason? }, before the first navigation
readonly port: "sdbx-jar-port" = 'sdbx-jar-port';middle page to shell, carrying exactly one port
request
Section titled “request”readonly request: "sdbx-jar-request" = 'sdbx-jar-request';shell to middle page, once per shell document: send me the port to the opener’s jar host
SHELL_JAR_UNREACHABLE
Section titled “SHELL_JAR_UNREACHABLE”const SHELL_JAR_UNREACHABLE: readonly ["bad-attach", "no-storage", "bad-jar", "no-parent", "no-jar-host", "no-token", "no-indexeddb", "failed"];Why a window’s shell reached no jar, sent as the reason of an 'unreachable' mode report. Only
these names cross the wire, never a value or an error’s own text.
STORAGE_REFUSALS
Section titled “STORAGE_REFUSALS”const STORAGE_REFUSALS: object;Every storage refusal, worded once for the library and the broker. Branch on code, never on the
message. notFound is one answer for an object that was never made, was deleted, or is still
uploading.
Type Declaration
Section titled “Type Declaration”accountChanged
Section titled “accountChanged”readonly accountChanged: object;accountChanged.code
Section titled “accountChanged.code”readonly code: "account-changed" = 'account-changed';accountChanged.message
Section titled “accountChanged.message”readonly message: "storage: the signed-in account changed" = 'storage: the signed-in account changed';badCursor
Section titled “badCursor”readonly badCursor: object;badCursor.code
Section titled “badCursor.code”readonly code: "invalid" = 'invalid';badCursor.message
Section titled “badCursor.message”readonly message: "storage: the cursor is not one list answered" = 'storage: the cursor is not one list answered';badKey
Section titled “badKey”readonly badKey: object;badKey.code
Section titled “badKey.code”readonly code: "invalid" = 'invalid';badKey.message
Section titled “badKey.message”readonly message: "storage: the key is not 32 bytes base64url" = 'storage: the key is not 32 bytes base64url';badLimit
Section titled “badLimit”readonly badLimit: object;badLimit.code
Section titled “badLimit.code”readonly code: "invalid" = 'invalid';badLimit.message
Section titled “badLimit.message”readonly message: "storage: the limit is out of range" = 'storage: the limit is out of range';badSize
Section titled “badSize”readonly badSize: object;badSize.code
Section titled “badSize.code”readonly code: "invalid" = 'invalid';badSize.message
Section titled “badSize.message”readonly message: "storage: a stream needs the size it will deliver, a whole number of bytes" = 'storage: a stream needs the size it will deliver, a whole number of bytes';badUrl
Section titled “badUrl”readonly badUrl: object;badUrl.code
Section titled “badUrl.code”readonly code: "invalid" = 'invalid';badUrl.message
Section titled “badUrl.message”readonly message: "storage: the url does not name a stored object" = 'storage: the url does not name a stored object';integrity
Section titled “integrity”readonly integrity: object;integrity.code
Section titled “integrity.code”readonly code: "integrity" = 'integrity';integrity.message
Section titled “integrity.message”readonly message: "storage: the object does not match its key" = 'storage: the object does not match its key';needsAccount
Section titled “needsAccount”readonly needsAccount: object;needsAccount.code
Section titled “needsAccount.code”readonly code: "denied" = 'denied';needsAccount.message
Section titled “needsAccount.message”readonly message: "storage: storing needs an account" = 'storage: storing needs an account';notAFile
Section titled “notAFile”readonly notAFile: object;notAFile.code
Section titled “notAFile.code”readonly code: "invalid" = 'invalid';notAFile.message
Section titled “notAFile.message”readonly message: "storage: the data is not a Blob or a ReadableStream" = 'storage: the data is not a Blob or a ReadableStream';notCreator
Section titled “notCreator”readonly notCreator: object;notCreator.code
Section titled “notCreator.code”readonly code: "denied" = 'denied';notCreator.message
Section titled “notCreator.message”readonly message: "storage: only the app that stored the object can delete it" = 'storage: only the app that stored the object can delete it';notFound
Section titled “notFound”readonly notFound: object;notFound.code
Section titled “notFound.code”readonly code: "not-found" = 'not-found';notFound.message
Section titled “notFound.message”readonly message: "storage: no object at this url" = 'storage: no object at this url';readonly quota: object;quota.code
Section titled “quota.code”readonly code: "quota" = 'quota';quota.message
Section titled “quota.message”readonly message: "storage: storage quota exceeded" = 'storage: storage quota exceeded';shortStream
Section titled “shortStream”readonly shortStream: object;shortStream.code
Section titled “shortStream.code”readonly code: "invalid" = 'invalid';shortStream.message
Section titled “shortStream.message”readonly message: "storage: the stream did not deliver the size it declared" = 'storage: the stream did not deliver the size it declared';tooLarge
Section titled “tooLarge”readonly tooLarge: object;tooLarge.code
Section titled “tooLarge.code”readonly code: "invalid" = 'invalid';tooLarge.message
Section titled “tooLarge.message”readonly message: "storage: the file is too large to store" = 'storage: the file is too large to store';tooMany
Section titled “tooMany”readonly tooMany: object;tooMany.code
Section titled “tooMany.code”readonly code: "too-many" = 'too-many';tooMany.message
Section titled “tooMany.message”readonly message: "storage: too many stored objects" = 'storage: too many stored objects';tooManyThisHour
Section titled “tooManyThisHour”readonly tooManyThisHour: object;tooManyThisHour.code
Section titled “tooManyThisHour.code”readonly code: "too-many" = 'too-many';tooManyThisHour.message
Section titled “tooManyThisHour.message”readonly message: "storage: too many objects stored this hour, try again later" = 'storage: too many objects stored this hour, try again later';unavailable
Section titled “unavailable”readonly unavailable: object;unavailable.code
Section titled “unavailable.code”readonly code: "unavailable" = 'unavailable';unavailable.message
Section titled “unavailable.message”readonly message: "storage: storage is unavailable" = 'storage: storage is unavailable';WINDOW_HANDSHAKE_TIMEOUT_MS
Section titled “WINDOW_HANDSHAKE_TIMEOUT_MS”const WINDOW_HANDSHAKE_TIMEOUT_MS: number;How long an app waits for a window’s channel. The window exposes it only once it has heard the app’s hello and its shell has reported a jar, each on its own deadline above and one after the other, and says by name when it cannot; the margin covers the window’s own page load and the channel’s handshake after it. Any shorter and the app gives up on a window that is about to connect, or to say why it cannot.
WINDOW_HELLO_TIMEOUT_MS
Section titled “WINDOW_HELLO_TIMEOUT_MS”const WINDOW_HELLO_TIMEOUT_MS: 20000 = 20_000;How long a window waits for its app’s first hello, from when its page runs. The app says hello every 250 ms from the moment it opens the window, so only an app that went away misses it.
WINDOW_JAR_MODE_TIMEOUT_MS
Section titled “WINDOW_JAR_MODE_TIMEOUT_MS”const WINDOW_JAR_MODE_TIMEOUT_MS: 30000 = 30_000;How long a window waits, from mounting its shell, for the shell to report the jar it runs on: the shell’s jar port wait (12 s), its partition token read (5 s) and a controller boot. The window exposes its channel only after that report, so the app waits for both of these and more.
References
Section titled “References”TcpSocketOption
Section titled “TcpSocketOption”Re-exports TcpSocketOption
UdpSocketOption
Section titled “UdpSocketOption”Re-exports UdpSocketOption