Overview
Every Lodekit app talks to the platform through @lodekit/sdk. One package, one import:
import { kv, files, events, tasks, gateways, secrets, settings, logs, appId } from "@lodekit/sdk";The one handle that doesn’t come from this import is db: your app builds its own
typed database handle in src/db.ts with createDb() (exported by @lodekit/sdk)
and imports it from there — see db.
How it works
Section titled “How it works”Each handle is a typed HTTP client against your app’s scoped API on the local
engine — /api/apps/<app-id>/<service>. There are no URLs to configure: in the
browser, requests are relative to the page origin; in a server function, the
engine hands the app worker its loopback base. Your app id is injected at build
time by the shared toolchain, and the SDK exports it back:
export const appId: stringOutside an app build appId is "" and the singleton handles are inert.
Where each handle works
Section titled “Where each handle works”| Handle | Browser | Server functions |
|---|---|---|
db |
Yes | Yes |
kv |
Yes | Yes |
files |
Yes | Yes |
events |
Yes | emit and list only — watch is client-only |
tasks |
Yes | Yes |
gateways |
No — server-only | Yes |
secrets |
No — server-only | Yes |
settings |
Yes | get and all only — watch is client-only |
logs |
Yes | Yes |
Calling events.watch() or settings.watch() on the server throws; calling
secrets.get() — or any gateways request — in the browser throws. Everything else is isomorphic — the same
call works on both sides.
Errors
Section titled “Errors”- A failed call rejects with an
Errorwhose message is the server’s error string (for example, a validation message like a bad TTL). If the server sent no message, the HTTP status text is used. - Gateway calls reject with
GatewayError, which carries a typedreason— see gateways. secrets.get()has a dedicated error type,SecretUnavailableError, with areasonof"unlinked"or"unavailable"— see secrets.logs.*are fire-and-forget: they returnvoid— not a promise — and never throw, so logging is safe on any code path.
Conventions
Section titled “Conventions”- TTLs are seconds — every
ttloption acrosskv,files, andeventstakes seconds. - Timestamps are ms-epoch — every
createdAt,updatedAt,expiresAt, and eventtsis milliseconds since the Unix epoch. - Pagination is keyset — list calls return
nextCursor; pass it back ascursorfor the next page, and stop when it’snull. - Request bodies cap at 100 kb on the scoped API — this bounds kv values and
task payloads. File bodies are exempt:
fileshas no size cap.
createClient()
Section titled “createClient()”createClient({ baseUrl, appId }: { baseUrl: string; appId: string }): LodekitClientbaseUrl— the engine origin to talk to (""for page-relative).appId— the app scope to talk to.
Builds a fresh set of all handles bound to an explicit engine and app id — the
singleton handles above are exactly createClient(...)’s handles bound to your
own app. You only need this in rare cases, such as a script running outside an
app build. LodekitClient is
{ kv, files, events, tasks, gateways, secrets, settings, logs }.