@deloc/client
v0.3.1
Published
Browser SDK for calling Deloc Actions from published apps
Maintainers
Readme
@deloc/client
Browser SDK for calling Deloc Actions from a published app.
Actions are server-side endpoints (HTTP, SQL, scheduled jobs) that the app owner configures on Deloc's dashboard. This package is what the browser-side code calls to invoke them and to read back the history of recent invocations.
Install
npm install @deloc/clientRequirements
This SDK is designed to run inside a Deloc-hosted app (a page served from *.deloc.dev or a custom domain pointed at Deloc). It talks to the Worker-hosted dispatch endpoints on the same origin and relies on the viewer's session cookie for authentication — there are no API keys to manage and no configuration to pass.
It will not work when loaded from a third-party origin.
Usage
Vanilla
import { action } from "@deloc/client";
const result = await action<{ ok: boolean }>("submit_form", {
email: "[email protected]",
message: "hello",
});
if (result.success) {
console.log(result.data); // { ok: true }
} else {
console.error(result.error, result.errorType);
}action() never throws for well-formed failures — it returns a discriminated union ({ success: true, data } or { success: false, error, errorType }). It only throws on transport errors (offline, aborted fetch, malformed response).
React
import { useDelocAction } from "@deloc/client/react";
function SubmitButton() {
const { invoke, loading, error, data } = useDelocAction("submit_form");
return (
<button
onClick={() => invoke({ email: "[email protected]" })}
disabled={loading}
>
{loading ? "Sending…" : "Submit"}
{error && <span>{error.message}</span>}
{data && <span>Sent!</span>}
</button>
);
}Pending requests are aborted automatically on unmount or when invoke is called again before the previous one resolves.
Reading invocations
Actions write every invocation to an append-only log. This is useful for "show pending updates before the next data refresh" UIs — overlay recent writes on top of the bundled JSON your app ships with.
import { invocations } from "@deloc/client";
const { invocations: rows } = await invocations({
action: "update_status",
status: "success",
limit: 50,
});Or as a React hook with auto-pagination:
import { useDelocInvocations } from "@deloc/client/react";
const { invocations, loading } = useDelocInvocations({
action: "update_status",
autoPaginate: true,
maxRows: 500,
});For idempotency checks keyed on an external id:
import { useDelocInvocationsByExternalId } from "@deloc/client/react";
const { invocations } = useDelocInvocationsByExternalId(row.id);The hook stays idle (no request) when the id is nullish.
API
| Export | What it does |
| --- | --- |
| action(name, body?, options?) | Invoke an action. Returns ActionResult<T>. |
| invocations(filters?) | Fetch one page of the invocation log. |
| fetchAllInvocations(options?) | Auto-paginate. Capped at maxRows (default 1000). |
| useDelocAction(name) | React hook wrapping action(). |
| useDelocInvocations(options) | React hook wrapping invocations(). Supports polling and auto-pagination. |
| useDelocInvocationsByExternalId(id, options?) | Convenience wrapper for idempotency lookups. |
Filters on invocations() / useDelocInvocations:
action— machine name of a single actionexternalId— the id recorded at invocation timesince,before— ISO-8601 datetime boundsstatus—"success"or"error"limit— 1..200 (clamped silently)
Error types
Failures carry an errorType so you can branch on cause:
timeout— the upstream didn't respond in timerate_limit— the viewer hit the per-session rate limitssrf_blocked,domain_not_allowed,content_type_blocked— the action's URL or response was blocked by policyforbidden_role— the viewer's role isn't allowed to invoke this actionupstream_error— HTTP 5xx from the upstream, or malformed responseschema_invalid— the request body didn't match the action's input schemaresponse_too_large— the upstream response exceeded the size limit
License
MIT
