App Browser SDK
The App Browser SDK is the browser-side SDK for embedded app frontends inside Lombok. An app UI runs inside an <iframe> hosted by the platform shell, and this package gives that iframe everything it needs to participate in the platform: a handshake with the parent window, an authenticated API client, navigation that stays in sync with the shell, theme propagation, a realtime socket for app events, and helpers for calling your app’s own workers.
Package
Section titled “Package”@lombokapp/app-browser-sdkThe package targets the browser and ships React bindings. The build externalizes bun, socket.io-client, @lombokapp/auth-utils, @lombokapp/types, and @lombokapp/sdk; the remaining React/browser-facing pieces are bundled into the package output.
Mental model
Section titled “Mental model”Your app frontend is served at a hostname like app-server--<app>.<platform_host> and embedded as an iframe by the Lombok shell. The two communicate over window.postMessage:
- On startup the SDK creates an
IframeCommunicatorand postsAPP_READYto the parent. - The shell replies with an
AUTHENTICATIONmessage carrying the initial tokens, theme, and path. This marks the SDK initialized. - From then on the shell can push
THEME_CHANGE,PARENT_NAVIGATE_TO,LOGOUT, andERRORmessages; the app can postNAVIGATE_TOback.
Because tokens arrive asynchronously via this handshake, most of the SDK is built around “wait until initialized, then act.” The React bindings hide that wait for you.
Quick start (React)
Section titled “Quick start (React)”Wrap your app in the provider, then read everything through the hook:
import { AppBrowserSdkContextProvider, useAppBrowserSdk,} from '@lombokapp/app-browser-sdk'
function Root() { return ( <AppBrowserSdkContextProvider onNavigateTo={(to) => router.push(to.pathAndQuery)} onThemeChange={(theme) => (document.documentElement.dataset.theme = theme) } > <App /> </AppBrowserSdkContextProvider> )}
function App() { const { isInitialized, apiClient, theme, authState } = useAppBrowserSdk() if (!isInitialized) return <Splash /> return <Dashboard />}Exports
Section titled “Exports”| Export | Kind | Purpose |
|---|---|---|
AppBrowserSdkContextProvider | React component | Instantiates and owns a single AppBrowserSdk, exposes it via context. |
useAppBrowserSdk | React hook | Reads the SDK context (ISdkContext). Throws if no provider is mounted. |
ISdkContext | type | Shape of the value returned by useAppBrowserSdk. |
SdkContext | React context | The underlying context object. |
AppUserSocketProvider | React component | Opens a shared authenticated /app-user socket for the current app + user. |
useAppUserSocket | React hook | Access the raw socket, connection state, and subscribe. |
useAppUserSocketEvent | React hook | Subscribe to a single raw socket.io event by name. |
useAppEvent | React hook | Subscribe to a custom app event (app:<app>:<event>) by app + event identifier. |
AppEventPayload | type | Payload shape for custom app events emitted from a worker. |
Link | React component | Navigates within the shell via the SDK instead of a hard browser nav. |
createBridgeConnection | function | Open a direct WebSocket to the Docker bridge. |
BridgeConnection / BridgeConnectionOptions / BridgeSessionCredentials | types | Bridge connection contract. |
IframeMessage | type | Envelope for messages exchanged with the parent window. |
TokenData | type | Re-export of InitialData: the auth/theme/path payload from the shell. |
AppBrowserSdk
Section titled “AppBrowserSdk”The core class implements AppBrowserSdkInstance and holds most of its lifecycle state on static fields, so a single iframe shares one initialization regardless of how many instances are created.
Configuration — AppBrowserSdkConfig
Section titled “Configuration — AppBrowserSdkConfig”interface AppBrowserSdkConfig { onInitialize?: () => void onNavigateTo?: (to: { pathAndQuery: string }) => void onThemeChange?: (theme: string) => void}Key properties
Section titled “Key properties”| Member | Type | Description |
| ------------------- | ----------------------------- | --------------------------------------------------------------------------------- | ----------------------------------------------------------------------- |
| sdk | LombokSdk | The underlying core SDK, wired to a token store backed by the iframe handshake. |
| apiClient | typed API client | Typed API client (sdk.apiClient). |
| authenticator | Authenticator | Auth controller (sdk.authenticator). |
| communicator | Promise<IframeCommunicator> | Resolves once initialized; lazily creates the communicator and sends APP_READY. |
| isInitialized | boolean | Whether the AUTHENTICATION handshake has completed. |
| theme | string | Current theme. |
| initialData | InitialData | undefined | The accessToken/refreshToken/pathAndQuery/theme delivered by the shell. |
| lombokApiBasePath | string | Platform API origin, derived from the iframe hostname. |
| appIdentifier | string | App id parsed from the app-server--<app> hostname label. |
Methods
Section titled “Methods”waitForInitialized()handleNavigateTo()executeWorkerScriptUrl()destroy()
Calling app workers — executeWorkerScriptUrl
Section titled “Calling app workers — executeWorkerScriptUrl”Issues an authenticated fetch to one of your app’s workers. The worker is addressed cross-origin at api-server--<worker>--<app>.<platform_host> and the current app-user access token is attached as a bearer token.
const res = await sdk.executeWorkerScriptUrl( { workerIdentifier: 'my-worker', url: '/do-thing' }, { method: 'POST', body: JSON.stringify({ ... }) },)React bindings
Section titled “React bindings”AppBrowserSdkContextProvider
Section titled “AppBrowserSdkContextProvider”Creates exactly one AppBrowserSdk for its subtree and exposes it via context. Props mirror AppBrowserSdkConfig.
useAppBrowserSdk(): ISdkContext
Section titled “useAppBrowserSdk(): ISdkContext”Returns the context value. Throws if no provider is mounted.
interface ISdkContext { isInitialized: boolean apiClient: AppBrowserSdk['apiClient'] theme: string authState: Authenticator['state'] navigateTo: (to: { pathAndQuery: string }) => Promise<void> lombokApiBasePath: string appIdentifier: string currentPathAndQuery: string getAccessToken: () => Promise<string | undefined> executeWorkerScriptUrl: AppBrowserSdk['executeWorkerScriptUrl']}A lightweight in-shell navigation element. Instead of a real anchor it routes through navigateTo, keeping the parent shell URL in sync.
App user realtime socket
Section titled “App user realtime socket”The app-user socket delivers custom events your workers emit toward a specific user, fanned out to that user’s open tabs.
AppUserSocketProvider
Section titled “AppUserSocketProvider”Opens a single authenticated socket.io connection on the /app-user namespace once the SDK is initialized and the user is authenticated.
useAppUserSocket()useAppUserSocketEvent(eventName, handler)useAppEvent(appIdentifier, eventIdentifier, handler)
Bridge connection
Section titled “Bridge connection”For features that need a direct, low-latency channel to the Docker bridge, createBridgeConnection opens a WebSocket straight to the bridge using session-scoped credentials.
import { createBridgeConnection } from '@lombokapp/app-browser-sdk'
const conn = await createBridgeConnection({ credentials, onData: (bytes) => term.write(bytes), onClose: () => term.dispose(), onError: (msg) => console.error(msg),})The iframe protocol (low level)
Section titled “The iframe protocol (low level)”IframeCommunicator wraps window.postMessage. It only accepts messages whose event.source is the parent window and dispatches by message.type.
Message types in use include:
APP_READYAPP_ERRORNAVIGATE_TOAUTHENTICATIONTHEME_CHANGEPARENT_NAVIGATE_TOLOGOUTERROR
Supporting types
Section titled “Supporting types”interface InitialData { accessToken: string refreshToken: string pathAndQuery: string theme: string}
interface AppBrowserSdkInstance { sdk: LombokSdk communicator: Promise<IframeCommunicator> apiClient: AppBrowserSdk['apiClient'] authenticator: Authenticator destroy: () => void}