Skip to content

API

@ogygia/federation

Fragment federation, with federate(), mount() and the signed wire.

On this page

This page is generated from the package’s own .d.ts files on every build, so the signatures, descriptions and examples below always match the source.

import { … } from '@ogygia/federation';

Exports child_traceparent · federate · mount · sign_headers · user · verify_signed_request · FederateConfig · FragmentDocument · KitMountOptions · MountOptions · Peer · PeerConfig · RemoteDials · VerifyConfig · WidgetDocument · WidgetInfo · Claims · VisitorResolver · Widget

child_traceparent

function

Continue the caller's trace (same trace-id, fresh span) or mint one.

function child_traceparent(incoming?: string | null): {
  traceparent: string;
  trace_id: string;
  span_id: string;
};

federate

function

federate({ name, key, peers, visitor, expose?, widgets? }). Returns the peer handles keyed by their config names: const { cms, dash } = federate({ … }).

function federate<P extends Record<string, PeerConfig>>(config: FederateConfig<P>): { [K in keyof P]: Peer; };

mount

function

mount(peer) in a table, or mount.kit(peer) from a Kit catchall.

const mount: typeof mount_fn & {
  kit: typeof kit_mount;
}

sign_headers

function

Caller side: headers proving "the holder of this private key sent EXACTLY this request, to THIS audience, now". audience defaults to the target URL's host.

function sign_headers(privateKey: string, method: string, url: URL, body?: ArrayBuffer | Uint8Array | null, claims?: Claims, audience?: string): Record<string, string>;

user

function

Read the VERIFIED visitor claims in any load / action / endpoint of an exposed router (and in a widget's info.user). undefined on the standalone front door and for anonymous calls.

function user<T extends Claims = Claims>(c: {
  request: Request;
}): T | undefined;

verify_signed_request

function

Receiver side: fresh, valid, non-replayed signature from an authorized caller, bound to THIS audience? Returns the (signature-bound) visitor claims on success, null on any failure.

function verify_signed_request(cfg: VerifyConfig, request: Request, url: URL, body?: ArrayBuffer | Uint8Array | null): {
  user?: Claims;
} | null;

FederateConfig

interface

interface FederateConfig<P extends Record<string, PeerConfig> = Record<string, PeerConfig>> {/*…*/}

FederateConfig.name

This app's name — the tag prefix peers file its fragments under (r:<name>:…).

name: string;

FederateConfig.key

This app's Ed25519 PRIVATE key (base64 PKCS8 DER; npx ogygia keys <name>). Signs every outbound hop and thaw notice. Omit for an app that only ANSWERS (never calls).

key?: string;

FederateConfig.peers

Everyone this app talks to, in either direction.

peers?: P;

FederateConfig.visitor

THE visitor identity for outbound hops (on-behalf-of, signed, never via the browser).

visitor?: VisitorResolver;

FederateConfig.expose

Serve this route table as fragments at /og/fragment/page (the MFE side).

expose?: Router;

FederateConfig.base

The mount base the exposed table renders under (routes(table, { base })).

base?: string;

FederateConfig.widgets

Named widget catalog served at /og/fragment/<name>; __catalog = the unsigned manifest.

widgets?: Record<string, WidgetDef>;

FederateConfig.audience

The audience(s) THIS app verifies inbound calls against. Defaults to the request host; set when a reverse proxy rewrites Host between the hops.

audience?: string | string[];

FederateConfig.skewMs

Clock skew / replay window for inbound signatures (ms, default 120 000).

skewMs?: number;

FederateConfig.open

Acknowledge an intentionally OPEN endpoint (mTLS / mesh): serve expose/widgets with no peer keys configured. Without it, exposing with nobody allowed to call is a config error.

open?: boolean;

FederateConfig.maxBodyBytes

Cap on a forwarded fragment body (bytes, default 1 MiB).

maxBodyBytes?: number;

FederateConfig.deploy

Deploy detection: 'auto' (default) broadcasts a thaw-all to peers on boot with a new build id; 'manual' leaves it to the app (postrender.invalidateWhere({ prefix: '/' })).

deploy?: "auto" | "manual";

FragmentDocument

interface

The wire document an exposed route table answers with.

interface FragmentDocument {/*…*/}

FragmentDocument.status

status: number;

FragmentDocument.location

3xx target (already in the answering app's OWN base space, e.g. /cms/posts/1).

location?: string;

FragmentDocument.title

title: string;

FragmentDocument.css

<link rel="stylesheet"> / <style> tags, asset hrefs absolute to the answering origin.

css: string[];

FragmentDocument.head

HEAD CHANNEL: the page's SEO/social head bits (<meta> + canonical links; never charset/viewport/http-equiv — those are the shell's).

head?: string;

FragmentDocument.body

body: string;

FragmentDocument.runtime

Absolute URL of the answering app's OWN ogygia runtime (a foreign host loads it to wake the fragment's islands).

runtime?: string;

FragmentDocument.path

The answering app's OWN canonical pathname for this page (base + path) — the shell files its stored page under p:<peer>:<path>, so postrender.invalidate('<path>') on the peer thaws it (see internal/notes/federation.md §3–4).

path?: string;

FragmentDocument.sources

PROVENANCE: the receipt tags this render consumed — its own s:<id>:<fp> (og.source) plus any r:…/p:…/a:… it adopted from ITS peers (a chain). The consumer prefixes each with this peer's name and files its stored page under them.

sources?: string[];

FragmentDocument.build

The answering app's build id — changes per deploy.

build?: string;

FragmentDocument.trace

OBSERVABILITY: the trace this render belonged to + how long it took.

trace?: {
    trace_id: string;
    span_id: string;
  };

FragmentDocument.server_ms

server_ms?: number;

KitMountOptions

interface

interface KitMountOptions {/*…*/}

KitMountOptions.user

Visitor claims for each hop — a plain Kit app has no c.visitor, so identity is read off the EVENT (cookies / locals) explicitly.

user?: (e: KitMountEvent) => Claims | undefined;

KitMountOptions.param

The catchall param name (src/routes/cms/[...rest] → 'rest'). Default 'rest'.

param?: string;

MountOptions

interface

interface MountOptions {/*…*/}

MountOptions.user

OVERRIDE the visitor claims for this mount. Default: the federation's visitor as it reaches c.visitor, plus the table's experiment buckets, auto-carried.

user?: (c: Ctx) => Claims | undefined;

MountOptions.stream

STREAM the mount: the shell's page flushes immediately with fallback in the slot, and the fragment swaps in down the SAME response when the peer answers. GET only.

stream?: boolean | {
    fallback?: string | unknown;
  };

Peer

interface

A peer handle — what federate() returns per peer.

interface Peer {/*…*/}

Peer.name

readonly name: string;

Peer.origin

readonly origin: string;

Peer.label

readonly label: string;

Peer.page

A remote ROUTE of this peer's exposed table as a region value. Static: awaits the hop and bakes; deferred: a signed hole.

page(path: string, dials?: RemoteDials & {
    search?: string;
  }): Promise<RegionValue>;

Peer.widget

A named widget of this peer's catalog as a region value.

widget(name: string, props?: Record<string, string>, dials?: RemoteDials): Promise<RegionValue>;

Peer.doc

Transport (used by mount()): the page DOCUMENT for a path (cache/SWR/coalescing).

doc(path: string, search: string, claims?: Claims, traceparent?: string): Promise<FragmentDocument>;

Peer.postDoc

Transport: a mutation document — bypasses and invalidates the cache.

postDoc(path: string, search: string, body: ArrayBuffer, content_type: string, claims?: Claims, traceparent?: string): Promise<FragmentDocument>;

Peer.widgetDoc

Transport: a raw widget document.

widgetDoc(name: string, props?: Record<string, string>, opts?: {
    claims?: Claims;
    traceparent?: string;
  }): Promise<WidgetDocument>;

Peer.drop

Thaw: drop cached documents carrying any of these tags ('all' = every entry).

drop(tags: ReadonlySet<string> | "all"): void;

PeerConfig

interface

One peer — an app this app talks to, in either direction.

interface PeerConfig {/*…*/}

PeerConfig.origin

Origin(s). Extra entries are same-build REPLICAS tried in order for READS (a retried mutation risks a double write — POSTs stay on the first).

origin: string | string[];

PeerConfig.key

The peer's Ed25519 PUBLIC key(s), base64 SPKI DER — verifies calls and thaw notices FROM it. A list = rotation overlap. Omit for a peer this app only CALLS (never hears from).

key?: string | string[];

PeerConfig.timeout

Max ms per UNCACHED hop; a miss becomes a boundary card, never a hung shell. Default 5000.

timeout?: number;

PeerConfig.cache

Stale-while-revalidate cache for this peer's documents (ms). Entries carry the fragment's source tags, so a thaw notice drops exactly the stale ones. Off when omitted.

cache?: {
    ttl: number;
    max?: number;
  };

PeerConfig.audience

The audience signed into hops TO this peer (must equal what it verifies as its own). Defaults to the origin's host — set both ends only when a proxy rewrites Host.

audience?: string;

PeerConfig.label

Server-Timing label (default: the peer's name).

label?: string;

RemoteDials

interface

The dials a remote region takes — the region dials, with the same meanings.

interface RemoteDials {/*…*/}

RemoteDials.render

'static' (default): one buffered signed hop during THIS render, HTML baked. 'deferred': a hole — the browser fetches it from the SHELL's handle (signed capability), which forwards to the peer with the visitor's claims derived at hole time.

render?: "static" | "deferred";

RemoteDials.claims

Override the visitor claims for this hop (default: the federation's visitor, plus every experiment bucket the request decided).

claims?: Claims;

VerifyConfig

interface

interface VerifyConfig {/*…*/}

VerifyConfig.publicKeys

base64 SPKI DER Ed25519 public keys of AUTHORIZED callers (a list = rotation overlap).

publicKeys: readonly string[];

VerifyConfig.skewMs

Max clock skew / replay window in ms (default 120s).

skewMs?: number;

VerifyConfig.audience

The audience(s) THIS app answers to. Defaults to the request URL's host.

audience?: string | string[];

WidgetDocument

interface

What a named widget (/og/fragment/<name>) answers with.

interface WidgetDocument {/*…*/}

WidgetDocument.html

html: string;

WidgetDocument.origin

origin?: string;

WidgetDocument.sources

sources?: string[];

WidgetDocument.build

build?: string;

WidgetDocument.trace

trace?: {
    trace_id: string;
    span_id: string;
  };

WidgetDocument.server_ms

server_ms?: number;

WidgetInfo

interface

What a catalog widget receives alongside the caller-chosen props.

interface WidgetInfo {/*…*/}

WidgetInfo.user

Signature-bound visitor claims (undefined when anonymous). AUTHORIZE against THESE — props are caller-chosen, claims are not.

user?: Claims;

WidgetInfo.request

request: Request;

WidgetInfo.url

url: URL;

Claims

type

Visitor claims — who is BROWSING (the caller signature says who is CALLING). Bound into the signed payload: forging claims means forging the Ed25519 signature. They never transit the browser — the shell attaches them server-side from its own session.

type Claims = Record<string, unknown>;

VisitorResolver

type

Visitor claims resolver — federate({ visitor }). Reads the LIVE event (cookies, locals); runs on the shell for every hop, including hole-time fetches of deferred remote regions.

type VisitorResolver = (event: {
  request: Request;
  url: URL;
  cookies?: {
    get(name: string): string | undefined;
  };
  locals?: unknown;
}) => Claims | undefined;

Widget

type

A widget: props in, an awaitable { html } out — region(Comp, props) IS that shape.

type Widget = (props: Record<string, string>, info: WidgetInfo) => PromiseLike<{
  html: string | null;
}> | {
  html: string | null;
};