Skip to content

shell (namespace of @fkn/lib)

function applyUpdate(): Promise<boolean>;

Apply a ready update by reloading the FKN frame this page mounted. Resolves true when the reload was taken, false when there is nothing to apply or this caller does not own the frame.

Nothing calls this on the app’s behalf. The broker’s own header offers the same action to the user; this is the app’s way to offer it on its own terms, or to take it at a moment it knows is safe. Check busyReasons() first if the app has no better signal of its own.

Promise<boolean>


function busyReasons(): string[];

What a shell reload would sever right now, as a list of human-readable reasons, empty when nothing is bound to the broker connection.

This is the evidence for deciding whether to call applyUpdate yet: open sockets and listening servers, a streaming proxy response, a mounted package, a live frame attachment, unflushed write-behind. An empty list is not a promise that a reload is free, only that this realm holds nothing the lib knows about, so an app with state of its own should weigh that too.

It is per REALM, and that distinction has already caused a wrong reading once. A worker that imports @fkn/lib/net keeps its own tally, which this function cannot see from the window. An app whose transfers live in a worker should ask the worker, not the page.

string[]


function onUpdate(callback): Promise<() => void>;

Subscribe to “a newer FKN shell is ready”. Fires immediately when an update is already waiting at subscribe time, so a late subscriber misses nothing. Returns an unsubscribe that stays valid across broker replacements.

() => void

Promise<() => void>


function onUpdateTaken(handler): () => void;

Handle “the FKN shell was just updated”, which arrives in EVERY open page, not only the one where the person pressed the button. Activating a new shell claims every client on the origin, so each page’s broker frame learns about it and tells its app.

The default, with no handler registered, is to RELOAD THIS PAGE. That is deliberate: after an update every tab is running the new worker against a document from the old build, and the only way out of that mix is a reload. Doing it for the whole browser at once is what a person means when they press update.

Registering a handler REPLACES that default, and then reloading is entirely the app’s business. That is the escape hatch for an app that cannot be interrupted:

shell.onUpdateTaken(() => {
if (downloads.idle()) location.reload()
else banner.show('FKN updated. Reload when you are ready.')
})

Unsubscribing restores the default. Note the difference from onUpdate, which fires when an update is merely READY and nothing has happened yet.

() => void

() => void


function updateReady(): Promise<boolean>;

Whether a newer FKN shell is downloaded and ready to apply.

Promise<boolean>