Skip to content

Overview

@fkn/lib gives a web app sockets, a fetch free of the page’s cross-origin rules, a file system with a copy in the user’s account, another website in an iframe you can drive, and third-party packages. It runs on a page, in a worker the page relays, and inside a package, an npm module FKN loads on a sandbox origin of its own. This page covers which backend answers a call and what every page here teaches.

To see it working first, the quickstart is the whole idea in one page.

A backend is where a call runs. The cloud is FKN’s own infrastructure and needs nothing installed. The extension is the FKN browser extension, so a call runs in the user’s own browser and asks them before it spends something of theirs. The desktop app is planned, and desktop.available() answers false today.

A cloud call leaves the page over the broker, the connection your page holds into FKN. cloud.fetch then goes through the proxy, the server that makes the request for you, and net and dgram through the relay, the server that holds the real socket. The root exports pick a backend for you, and each namespace pins one:

app.ts
import {
const fetch: (input: RequestInfo | URL, init?: RequestInit & {
reason?: string;
render?: boolean;
}) => Promise<Response>
fetch
,
(alias) namespace cloud
import cloud
cloud
,
(alias) namespace extension
import extension
extension
,
(alias) namespace desktop
import desktop
desktop
} from '@fkn/lib'
await
function fetch(input: RequestInfo | URL, init?: RequestInit & {
reason?: string;
render?: boolean;
}): Promise<Response>
fetch
('https://example.org/api/catalog.json') // the extension when exposed on this page, otherwise the cloud
await
(alias) namespace cloud
import cloud
cloud
.
cloud_d_exports.fetch(input: ProxyFetchInput, init?: ProxyFetchInit): Promise<Response>
export cloud_d_exports.fetch
fetch
('https://example.org/api/catalog.json') // always the cloud, through the proxy
await
(alias) namespace extension
import extension
extension
.
extension_d_exports.fetch(input: RequestInfo | URL, init?: extension.FetchInit): Promise<Response>
export extension_d_exports.fetch
fetch
('https://example.org/api/catalog.json') // always the user's browser, so it needs the extension
(alias) namespace desktop
import desktop
desktop
.
desktop_d_exports.available(): boolean
export desktop_d_exports.available

Typed placeholder for the planned desktop backend. Always false in this release.

available
() // false, the desktop backend is planned

The first call runs with or without the extension, and the other three name their backend. What each backend can do is the table on backends.

  • quickstart builds a page in six steps that fetches a URL the browser cannot, keeps the result, and reads a heading out of a real site, with nothing installed.
  • install adds the package and names the three shims your bundler must supply.

Read these in order the first time: they build on each other.

  • backends says where a call runs, what available() answers on each backend, and how the root exports choose.
  • fetch() follows the three fetches and the header rules, and shows how the proxy reports a refusal without throwing.
  • TCP and UDP sockets is Node’s net and dgram over the relay, from connect and bind to the one bounded wait.
  • HTTP and DNS is Node’s http over an FKN socket, why there is no https, and dns.lookup.
  • workers explains what relayWorker does, what a worker nobody relayed does, and which calls work inside a relayed one.
  • storage covers the three file systems, fs, opfs and cloud.fs, and the in-memory layer behind the synchronous calls.
  • sync and conflicts covers what the account copy, the copy of a file kept in the account, asks of your app: the read and write rules, conflicts and deletes.
  • encryption covers the one state an app sees, locked, key epochs, and the messages a changed key produces.
  • frames covers attachFrame(), its two backends, every option, goto(), frame.fetch(), and what is refused.
  • locators and actions covers the locator chain, a Locator built by chaining selectors, every selector and action, and the video handle.
  • permissions and consent covers the consent sheet, the prompt the extension shows before an action that needs approval, the twenty permission keys such as read.text, and the activity log, the on-device record of what an app did.
  • account and quota covers connect(), what an app may read of the account, the connect button, and the metered volume behind cloud.quota().
  • packages covers both sides of the contract: the host app that installs, connects to and shows a package, and the package that answers with onConnect.
  • rooms covers a realtime room: the invite, sealed messages, the permission model, what survives a reconnect, and the identity a member carries.
  • connection and lifecycle covers what waits for the broker and what gives up, a broker replaced under a call, and busy tokens, the reasons a page reports itself busy.
  • every error is the catalogue: every message @fkn/lib 0.9.28 can produce, filterable, with what happened and whether a retry can succeed.
  • handling errors says which fields of an error survive the trip out of the broker, and how to test each family.
  • entry points lists every import path, what each one gives you, and what importing it starts.
  • TypeScript says which entry point exports each type, and how to derive the shapes the library does not export.
  • limits and timeouts lists every deadline, cap and clamp with its value and what happens past it.
  • limitations is the honest list of what stays impossible or different, with the workaround where there is one.
  • how it works explains the broker frame, the hidden fkn.app iframe that carries the broker, how calls keep working when the broker is replaced, the overlay, and what the library stores on your origin.

The pages under API reference are generated from the source, so check an exact signature there.