@abloatai/ablo 0.58.0 → 0.59.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/docs/index.md CHANGED
@@ -1,198 +1,79 @@
1
- # Ablo Docs
1
+ # Introduction
2
2
 
3
- > Collaboration infrastructure for AI agents: one API for agents, apps, and services to claim, change, and confirm the same rows.
3
+ > Coordination infrastructure for agents, applications, services, and people working on shared state
4
4
 
5
- Two agents reach for the same row. One claims it, does slow work — an LLM call,
6
- a fetch, a chain of tools and commits. The second is neither rejected nor
7
- allowed to clobber: it waits in line, is handed the row as it now stands, and
8
- proceeds. Contention becomes an ordering problem instead of a retry loop.
5
+ Ablo is a framework-agnostic coordination layer for agents, applications,
6
+ services, and people working on shared state. It provides claims, waiting,
7
+ participant identity, stale-work rejection, confirmed writes, and live updates
8
+ through one typed interface. Whether you are adding agents to an existing
9
+ application or building a new multi-user system, Ablo lets you focus on your
10
+ product instead of rebuilding coordination infrastructure.
9
11
 
10
- ```ts
11
- // Take the row. Anyone else who wants it waits, then reads it fresh.
12
- await using claim = await ablo.reports.claim({ id: reportId });
12
+ Ablo works with your existing database, API, authorization, and business logic,
13
+ while providing a common coordination model across runtimes and frameworks.
13
14
 
14
- await ablo.reports.update({
15
- id: claim.data.id,
16
- data: { forecast: await generateForecast(claim.data) },
17
- });
18
- ```
15
+ ## Features
19
16
 
20
- Claims do not lock. A lock is held against a caller who may never come back; a
21
- claim is a durable lease with a wait-line behind it, so you can always ask who
22
- holds a row and who is queued for it. The write returns a receipt, and a write
23
- based on a row that has since changed is turned away rather than applied.
24
-
25
- ## What people build
17
+ Ablo provides a comprehensive set of coordination capabilities and a shared
18
+ model that can be used across agents, services, applications, and human
19
+ interfaces.
26
20
 
27
21
  <Columns>
28
- <Card title="Run agents in parallel" icon="users" href="/coordination">
29
- Many agents over one dataset. Claims put them in a line instead of a race.
22
+ <Card title="Claims and waiting" icon="handshake" href="/coordination">
23
+ Let one participant perform contested work while others wait, skip, or fail according to an explicit policy.
24
+ </Card>
25
+
26
+ <Card title="Existing PostgreSQL" icon="database" href="/coordinate-existing-work">
27
+ Keep the authoritative transaction, locks, constraints, and direct SQL paths your application already owns.
28
+ </Card>
29
+
30
+ <Card title="Participant identity" icon="fingerprint" href="/identity">
31
+ Give agents, people, and services distinct scoped credentials instead of treating every worker as the same caller.
32
+ </Card>
33
+
34
+ <Card title="Crash recovery" icon="rotate-ccw" href="/guarantees">
35
+ Expiring leases and heartbeats let later participants proceed when an owner disappears.
30
36
  </Card>
31
37
 
32
- <Card title="Hand work between agents" icon="arrow-left-right" href="/agent-messaging">
33
- One agent claims, works, releases. The next picks up with the fresh row and a durable note about why.
38
+ <Card title="Stale-work rejection" icon="shield-check" href="/concurrency-convention">
39
+ Carry the rows behind a decision into its write and reject the result when those premises changed.
34
40
  </Card>
35
41
 
36
- <Card title="Scope what an agent may write" icon="key-round" href="/api-keys">
37
- A revocable key bound to one project's models. Attribution comes from the credential, not the call site.
42
+ <Card title="Atomic commits" icon="git-merge" href="/api#atomic-commits">
43
+ Apply several Ablo writes together, with their captured premises, or apply none of them.
38
44
  </Card>
39
45
 
40
- <Card title="Confirm what landed" icon="receipt" href="/guarantees">
41
- Every write returns a receipt. Nothing is fire-and-forget, and stale writes are rejected.
46
+ <Card title="Confirmed writes" icon="receipt" href="/guarantees">
47
+ Know when a write reached the authoritative database and why a rejected write did not land.
42
48
  </Card>
43
49
 
44
- <Card title="Audit every agent action" icon="scroll-text" href="/audit">
45
- Trace any committed change back to the key that made it, and to the person who authorized that key.
50
+ <Card title="Humans and agents" icon="users" href="/react">
51
+ Coordinate stateless HTTP workers with live human interfaces over the same shared state.
46
52
  </Card>
47
53
 
48
- <Card title="Keep a person in the loop" icon="hand" href="/react">
49
- Add the `humans()` plugin and people get presence and live queries. A person's claim is just another holder the agent waits behind.
54
+ <Card title="Audit and visibility" icon="scroll-text" href="/audit">
55
+ Inspect ownership, contention, and committed changes with the responsible participant attached.
50
56
  </Card>
51
57
  </Columns>
52
58
 
53
- ## Using Ablo
54
-
55
- <Steps>
56
- <Step title="Declare the models agents share">
57
- `npx ablo init` scaffolds `ablo/schema.ts`, the typed client, and the type registration.
58
- Declare only the models agents coordinate over — your auth, billing, and everything else
59
- stay in your own migrations.
60
-
61
- ```bash
62
- npx ablo init
63
- npx ablo dev
64
- ```
65
-
66
- `dev` gives the current Git branch an isolated Ablo branch, wires its temporary key,
67
- pushes the schema, and watches for changes. Until the server has your schema, a write to
68
- a new model fails with `server_execute_unknown_model`. See
69
- [Branch-first development](./branch-development.md).
70
- </Step>
71
-
72
- <Step title="Connect the database the rows live in">
73
- Ablo writes through a scoped role and confirms by tailing your write-ahead log. It runs no
74
- DDL and owns no schema — your migration tool stays in charge of the shape of your database.
75
-
76
- ```bash
77
- npx ablo connect
78
- ```
79
-
80
- No database yet? Pass an `apiKey` only and Ablo keeps the rows in its own log, so you can
81
- build the whole system today and point it at Postgres when you are ready.
82
- </Step>
83
-
84
- <Step title="Build with Ablo">
85
- You are writing the agent yourself — a worker, a job handler, a tool inside a model loop.
86
- Agents hold no socket; the credential is the identity.
87
-
88
- ```ts
89
- const ablo = Ablo({ schema, apiKey: process.env.ABLO_API_KEY, transport: 'http' });
90
- ```
91
-
92
- Read with `list` / `get`, coordinate with `claim`, write with `create` / `update` /
93
- `delete`. See [Agents](./agents.md) for the loop and [API Reference](./api.md) for the shape.
94
- </Step>
95
-
96
- <Step title="Or point an MCP host at it">
97
- The agent is Claude, Cursor, or another MCP host, and you want it operating your data
98
- directly. The coordination server exposes the same claim-and-commit loop as tools.
99
-
100
- ```bash
101
- claude mcp add ablo -- npx -y @abloatai/mcp
102
- ```
103
-
104
- See [Model Context Protocol](./mcp.md) — and read the surface table below before you pick,
105
- because Ablo publishes two MCP servers and only one of them is a data plane.
106
- </Step>
107
- </Steps>
108
-
109
- ## Surfaces
110
-
111
- Every surface reaches the same coordinated state. Pick by who is calling.
112
-
113
- | Surface | Use it for |
114
- |---|---|
115
- | **SDK**: `@abloatai/ablo`, `transport: 'http'` | The agents themselves. Stateless, request/response, nothing held open. The main path. |
116
- | **Coordination MCP**: `@abloatai/mcp` | An agent living inside an MCP host that needs claim and commit as tools. A data plane. |
117
- | **`humans()`**: with `@abloatai/ablo/react` | The interfaces a person watches agent work arrive in: presence, live queries, a local copy. |
118
- | **CLI**: `ablo` | Scaffolding, schema push, connecting a database. Terminals and CI. |
119
- | **REST**: `/api/v1` | Runtimes with no SDK. |
120
- | **Integration-helper MCP**: hosted `/api/mcp` | Teaching a coding assistant the SDK while you build. Docs, lint, and scaffolds only. |
121
-
122
- The two MCP servers are not interchangeable. The coordination server changes
123
- your data; the integration-helper server serves documentation and has no
124
- per-model data tools at all. An agent that edits rows uses the SDK or the
125
- coordination server — never the helper.
126
-
127
- ### Where people fit
128
-
129
- The bare client is the coordination layer: commit, read, observe, claim. People
130
- are something you add to it. `humans()` is the plugin that declares the local,
131
- watchable copy — the offline store, live queries, presence, and the framework
132
- bindings — and it needs a duplex connection, so a stateless agent cannot install
133
- it and is told so at construction rather than left with a subscription that never
134
- delivers.
135
-
136
- There is no `agents()` plugin, and the absence is the point: agents are the
137
- default caller, not a special one.
138
-
139
- ## Concepts
140
-
141
- - [How Ablo Works](./how-it-works.md) — the mental model in one page: you write through Ablo, it lands in your Postgres, the write-ahead log confirms it. **Read this first.**
142
- - [Coordination](./coordination.md) — `claim`, `claim.state`, and `claim.queue`: who holds a row, and who is waiting.
143
- - [Concurrency Convention](./concurrency-convention.md) — the precise rule for guarded and unguarded writes.
144
- - [Guarantees](./guarantees.md) — what a confirmed write, a stale-write rejection, and a claim each promise.
145
- - [Idempotency](./idempotency.md) — make a retried write safe; what replays, what re-runs, and for how long.
146
- - [Schema Contract](./schema-contract.md) — one schema becomes typed clients, agent writes, React reads, and the push.
147
- - [Agents](./agents.md) — the stateless participant: wake, read, claim, commit, idle.
148
- - [Agent Messaging](./agent-messaging.md) — durable handoffs between agents, linked to the claim they discuss.
149
- - [Identity & Sync Groups](./identity.md) — who is connecting, and which slice of state they see.
150
- - [Change Propagation](./groups.md) — how one row's change reaches the actors that depend on it.
151
- - [Client Behavior](./client-behavior.md) — options, errors, retries, timeouts, and imports.
152
-
153
- ## Authority
154
-
155
- - [Projects](./projects.md) — one organization, many apps; each with its own schema, planes, and keys.
156
- - [API Keys](./api-keys.md) — the credential that carries an agent's identity and its scopes.
157
- - [Sessions](./sessions.md) — short-lived scoped credentials your backend mints.
158
- - [Customer Organizations](./customer-organizations.md) — serve many isolated customer organizations from one schema and backend.
159
- - [Audit Log](./audit.md) — trace any confirmed write back to the person behind it.
160
- - [Operating on Your Database](./operating-on-your-database.md) — which actions run freely, which to verify first, and which belong to a human.
161
- - [Session Settings](./session-settings.md) — point your row-level-security policies at Ablo's writes, by naming the settings they already read.
162
-
163
- ## Build
164
-
165
- - [Agent Integration Decision Guide](./agent-integration-decision-guide.md) — choose identifier or row claims, captured reads, atomic boundaries, persistence ownership, transport, and the smallest proof before opening an example.
166
- - [TypeScript Library](./libraries/typescript.md) — construct the server client,
167
- keep schema ownership beneath one boundary, and select an integration approach.
168
- - [GraphQL.js over an Existing Backend](./approaches/graphql/graphql-js.md) —
169
- keep resolvers thin and call one named Ablo-backed domain operation.
170
- - [Quickstart](./quickstart.md) — make your first coordinated write.
171
- - [Integration Guide](./integration-guide.md) — the canonical end-to-end integration.
172
- - [Integrations](./integrations.md) — long-running records, ingestion, and other application-edge runtimes.
173
- - [CLI & Migrations](./cli.md) — `init` / `connect` / `push` / `migrate` / `generate`.
174
- - [Connect Your Database](./data-sources.md) — where rows land when your own database is canonical.
175
- - [Deployment](./deployment.md) — the database, the keys, and the schema push that take an integration to production.
176
- - [React](./react.md) — provider, hooks, and reactive reads.
177
- - [Webhooks](./webhooks.md) — react to confirmed change from outside the SDK.
178
- - [Debugging & Logs](./debugging.md) — watch claims, queueing, and grants while you build.
179
-
180
- ## Reference
181
-
182
- - [API Reference](./api.md) — model-by-model method shape.
183
- - [Errors](./errors.md) — the code registry, its categories, and what to do about each.
184
- - [Upgrade Guide](./migration.md) — upgrade a pinned pre-1.0 SDK safely.
185
- - [Changelog](../CHANGELOG.md) — what shipped recently.
186
-
187
- ## Examples
188
-
189
- - [AI SDK Tool](./examples/ai-sdk-tool.md) — put Ablo inside a model's tool call.
190
- - [Agent + Human](./examples/agent-human.md) — yield when a person is holding the same report.
191
- - [Server Agent](./examples/server-agent.md) — a schema-backed worker.
192
- - [Existing Python Backend](./examples/existing-python-backend.md) — add coordination without replacing your API server.
193
- - [Next.js](./examples/nextjs.md) — app-router setup with React bindings.
194
-
195
- ## More
196
-
197
- - [README](../README.md) — product overview and first example.
198
- - [AGENTS.md](../AGENTS.md) — installation guidance for coding assistants.
59
+ ...and more.
60
+
61
+ ---
62
+
63
+ ## Get started
64
+
65
+ - [Installation](./installation.md) install Ablo, declare the shared models,
66
+ and create a client.
67
+ - [Basic usage](./basic-usage.md) — read, write, and coordinate one operation.
68
+ - [Comparison](./comparison.md) — see how Ablo relates to PostgreSQL locks,
69
+ Redis reservations, queues, workflow engines, and rolling your own.
70
+ - [Choose the Ablo operation](./implement.md) — route an existing use case to
71
+ the smallest correct implementation.
72
+
73
+ ## AI resources
74
+
75
+ Ablo is designed to be implemented by agents as well as people. Use
76
+ [llms.txt](https://docs.abloatai.com/llms.txt) for the public documentation
77
+ index, or connect an assistant to the [documentation MCP server](./mcp.md). The
78
+ coordination MCP package also ships its agent-facing skill as
79
+ `@abloatai/mcp/skill.md`.
@@ -0,0 +1,77 @@
1
+ # Installation
2
+
3
+ > Install Ablo, declare the models participants share, and create a typed client.
4
+
5
+ Install the Ablo TypeScript SDK in an existing or new project.
6
+
7
+ ## Install the package
8
+
9
+ ```bash
10
+ npm install @abloatai/ablo
11
+ npx ablo init
12
+ ```
13
+
14
+ `ablo init` creates the schema, registration, and client files and signs the
15
+ developer in. Keep these files together under one `ablo/` ownership boundary.
16
+
17
+ ## Declare shared models
18
+
19
+ Declare only the rows Ablo coordinates. Your other tables stay in the schema
20
+ and migrations the application already owns.
21
+
22
+ ```ts
23
+ // ablo/schema.ts
24
+ import { defineSchema, model, z } from '@abloatai/ablo/schema';
25
+
26
+ export const schema = defineSchema({
27
+ tasks: model({
28
+ title: z.string(),
29
+ status: z.enum(['open', 'done']),
30
+ }),
31
+ });
32
+ ```
33
+
34
+ Every model automatically has an `id`. Declare application fields such as
35
+ timestamps and actor ids yourself when you need them.
36
+
37
+ ## Start development
38
+
39
+ ```bash
40
+ npx ablo dev
41
+ ```
42
+
43
+ The development command prepares an isolated Ablo branch, supplies its
44
+ temporary `ABLO_API_KEY`, pushes the schema, and watches for changes. Runtime
45
+ code always reads `ABLO_API_KEY`; do not put management credentials in the
46
+ application.
47
+
48
+ ## Use your PostgreSQL database
49
+
50
+ ```bash
51
+ npx ablo connect
52
+ ```
53
+
54
+ Ablo runs no DDL and does not replace your migration tool. It writes the models
55
+ you declared and confirms changes from PostgreSQL's write-ahead log. Existing
56
+ APIs, direct SQL, constraints, and transactions can remain in place.
57
+
58
+ ## Create the client
59
+
60
+ `ablo init` scaffolds this file. Start with the HTTP client for an agent or
61
+ server operation; it has no persistent connection to manage.
62
+
63
+ ```ts
64
+ // ablo/client.ts
65
+ import Ablo from '@abloatai/ablo';
66
+ import { schema } from './schema';
67
+
68
+ export const ablo = Ablo({
69
+ schema,
70
+ apiKey: process.env.ABLO_API_KEY,
71
+ transport: 'http',
72
+ });
73
+ ```
74
+
75
+ Continue to [Basic usage](./basic-usage.md) to read, write, and coordinate one
76
+ operation. Use the [full Quickstart](./quickstart.md) when you need the detailed
77
+ branch, schema-registration, and database setup explanation.
@@ -0,0 +1,52 @@
1
+ # Instrumentation
2
+
3
+ > Connect Ablo coordination outcomes and durable activity to the observability tools you already use.
4
+
5
+ Ablo exposes two complementary signals: process-local coordination events for
6
+ live telemetry, and credential-scoped logs for durable inspection.
7
+
8
+ ## Capture coordination events
9
+
10
+ Pass an `observability` sink to the package-root client:
11
+
12
+ ```ts
13
+ const ablo = Ablo({
14
+ schema,
15
+ observability: {
16
+ captureClaim: (event) => telemetry.capture('ablo.claim', event),
17
+ captureConflict: (event) => telemetry.capture('ablo.conflict', event),
18
+ },
19
+ });
20
+ ```
21
+
22
+ `captureClaim` reports acquisition, queueing, grant, release, loss, and expiry.
23
+ `captureConflict` reports stale dependencies and writes rejected by another
24
+ participant's claim. The sink should return quickly and must not be the
25
+ correctness path for the operation it observes.
26
+
27
+ ## Inspect durable activity
28
+
29
+ The stateless client exposes `ablo.logs` for authoritative, credential-scoped
30
+ event pages. Use it for audit views, support tooling, and reconciliation rather
31
+ than treating process logs as durable truth.
32
+
33
+ Access is bounded by the same credential that created the client. Do not copy
34
+ customer-wide logs into a less restricted telemetry destination.
35
+
36
+ ## What to measure
37
+
38
+ Useful coordination measures include:
39
+
40
+ - claim acquisition, wait, and hold duration;
41
+ - queue depth and contention outcome;
42
+ - expired or lost claims;
43
+ - stale-context and foreign-claim rejections;
44
+ - retry count and request latency;
45
+ - durable-write backlog and replay outcome.
46
+
47
+ Alert on sustained changes in rates, not on every expected contention event.
48
+ Queueing and stale-write rejection are often the system preventing duplicate or
49
+ obsolete work, not failures by themselves.
50
+
51
+ See [Debugging & Logs](./debugging.md) for local diagnosis and event formatting,
52
+ and [Audit Log](./audit.md) for stored attribution and verification.
@@ -2,12 +2,21 @@
2
2
 
3
3
  > Run an Ablo agent with OS-enforced filesystem and network boundaries while its coordinated work remains durable outside the sandbox.
4
4
 
5
+ ## Choose the write owner first
6
+
7
+ - If the sandbox reads and writes shared Ablo rows itself, continue with this page.
8
+ - If the sandbox only returns a prepared result and the host process commits
9
+ through an existing application operation, **stop here and open**
10
+ [Coordinate existing work](../coordinate-existing-work.md).
11
+ That guide owns the implementation. Keep the operation, its database
12
+ transaction, and the existing Ablo wiring.
13
+
5
14
  Anthropic Sandbox Runtime and Ablo own different boundaries:
6
15
 
7
16
  | Concern | Owner |
8
17
  |---|---|
9
18
  | Filesystem, network, Unix sockets, process-tree restrictions | Sandbox Runtime |
10
- | Typed reads and writes, claims, fencing, idempotency, confirmation | Ablo |
19
+ | Typed reads and writes, claims, safe retries, and confirmation | Ablo |
11
20
  | Prompts, tools, model calls, and business behavior | Your application |
12
21
  | Authentication, branch creation, schema push, and database connection | A trusted host workflow |
13
22
 
package/docs/migration.md CHANGED
@@ -11,13 +11,14 @@ releases remain compatible within the same minor line.
11
11
  2. Read the changelog entries between your installed and target versions.
12
12
  3. Use the documentation bundled with the target package while changing code.
13
13
  4. Run type-checks and tests before updating a production branch.
14
- 5. Push schema changes deliberately after reviewing the generated diff.
14
+ 5. Run the three-state deployment plan, then push the exact reviewed plan.
15
15
 
16
16
  ```bash
17
17
  npm install @abloatai/ablo@0.48
18
18
  npx ablo docs
19
19
  npx ablo docs api
20
- npx ablo check
20
+ npx ablo plan
21
+ npx ablo plan --json
21
22
  ```
22
23
 
23
24
  `npx ablo docs` is version-matched to the installed package. Prefer it during an
@@ -41,17 +42,21 @@ types and server-confirmed identity instead.
41
42
 
42
43
  ## Schema and database safety
43
44
 
44
- An SDK upgrade and a database migration are separate operations.
45
+ An SDK upgrade and a database migration are separate operations coordinated by
46
+ one deployment plan.
45
47
 
46
- - `ablo push` updates Ablo's typed schema contract. It does not run application
47
- DDL or drop your tables.
48
- - `ablo check` compares the contract with the connected database without
49
- changing it.
48
+ - `ablo plan` compares source, the active Ablo artifact, and PostgreSQL without
49
+ changing any of them. Its fingerprint pins all three observations.
50
+ - `ablo push` consumes that reviewed fingerprint and refuses if any state moved.
51
+ - `ablo check` is the database-compatibility view of the same plan.
50
52
  - Your ORM or migration tool remains responsible for tables, columns,
51
53
  constraints, and application data migrations.
52
54
 
53
55
  When both need to change, deploy the database migration in a backwards-compatible
54
56
  form first, push the compatible Ablo schema, then remove old application paths.
57
+ For a live rename or required-field change, keep expand, dual-write, resumable
58
+ backfill, verification, switch, and contract as explicit gates. Contract is a
59
+ later, separately approved deployment—not the tail of expand.
55
60
 
56
61
  ## If an upgrade fails
57
62
 
@@ -0,0 +1,172 @@
1
+ # Options
2
+
3
+ > Every option accepted by the default `Ablo({ ... })` client.
4
+
5
+ Import `Ablo` from `@abloatai/ablo`. Only `schema` is required. A server can
6
+ usually rely on `ABLO_API_KEY` and keep the constructor small:
7
+
8
+ ```ts
9
+ import Ablo from '@abloatai/ablo';
10
+ import { schema } from './ablo/schema';
11
+
12
+ export const ablo = Ablo({ schema });
13
+ ```
14
+
15
+ These options configure the stateless HTTP client exported by the package root.
16
+ For a live human interface, use the [React guide](./react.md).
17
+
18
+ ## schema
19
+
20
+ The schema created with `defineSchema()`. It gives each declared model a typed
21
+ `ablo.<model>` client. This is the only required option.
22
+
23
+ ## apiKey
24
+
25
+ A server API key, or an async function that resolves a credential at request
26
+ time. When omitted, Ablo reads `ABLO_API_KEY`.
27
+
28
+ ```ts
29
+ const ablo = Ablo({ schema, apiKey: process.env.ABLO_API_KEY });
30
+ ```
31
+
32
+ Use a resolver for credentials that rotate. Return `null` when the login has
33
+ ended; throw when credential resolution failed temporarily. Do not pass both
34
+ `apiKey` and `authEndpoint`.
35
+
36
+ ## authEndpoint
37
+
38
+ A same-origin URL that mints a short-lived credential, or an async credential
39
+ resolver. The client sends a `POST` with cookies included and renews the token
40
+ when needed.
41
+
42
+ ```ts
43
+ const ablo = Ablo({ schema, authEndpoint: '/api/ablo-session' });
44
+ ```
45
+
46
+ Use this instead of placing a private API key in browser code.
47
+
48
+ ## authToken
49
+
50
+ A bearer token the caller already holds. This is mainly for self-hosted or
51
+ custom authentication layers. Hosted applications normally use `apiKey` or
52
+ `authEndpoint`.
53
+
54
+ ## baseURL
55
+
56
+ Overrides the Ablo API URL. Leave it unset for hosted Ablo. Use it for a private
57
+ deployment, local development proxy, or test server.
58
+
59
+ ```ts
60
+ const ablo = Ablo({ schema, baseURL: 'https://ablo.internal.example' });
61
+ ```
62
+
63
+ Because credentials are sent to this URL, Ablo rejects URLs containing embedded
64
+ credentials, query parameters, or fragments. Plain HTTP is accepted only for
65
+ local hosts.
66
+
67
+ ## dangerouslyAllowBrowser
68
+
69
+ Allows a credential-bearing client to run in a browser. Defaults to `false`.
70
+
71
+ Private API keys must not ship to browsers. Prefer `authEndpoint`; enable this
72
+ option only when the browser receives a narrowly scoped session credential or
73
+ all traffic passes through a controlled server proxy.
74
+
75
+ ## fetch
76
+
77
+ A custom `fetch` implementation for tests, proxies, or runtimes without the
78
+ standard global implementation.
79
+
80
+ ## authTimeoutMs
81
+
82
+ The deadline in milliseconds for a request to `authEndpoint`. Defaults to
83
+ `10000`. This is separate from `timeoutMs`, which covers ordinary Ablo API
84
+ requests.
85
+
86
+ ## allowCrossOriginAuthEndpoint
87
+
88
+ Allows `authEndpoint` to use a different origin. Defaults to `false`.
89
+
90
+ Keep the default unless the credential-minting service intentionally lives on a
91
+ different trusted origin.
92
+
93
+ ## bootstrapBaseUrl
94
+
95
+ Overrides the URL used for credential exchange and bootstrap. Most applications
96
+ should leave this unset and use `baseURL` for a private or test deployment.
97
+
98
+ ## defaultHeaders
99
+
100
+ Headers included with every Ablo HTTP request. A `null` value removes a default
101
+ header.
102
+
103
+ ```ts
104
+ const ablo = Ablo({
105
+ schema,
106
+ defaultHeaders: { 'x-deployment': 'worker-eu' },
107
+ });
108
+ ```
109
+
110
+ Do not use this option to duplicate the credential header; authentication is
111
+ owned by `apiKey`, `authEndpoint`, or `authToken`.
112
+
113
+ ## defaultQuery
114
+
115
+ Query parameters included with every Ablo HTTP request. This is primarily for
116
+ proxies and controlled test deployments.
117
+
118
+ ## observability
119
+
120
+ A sink for claim lifecycle and rejected-write events. It implements
121
+ `captureClaim(event)` and `captureConflict(event)`. Use it to connect Ablo's
122
+ coordination outcomes to the application's existing telemetry.
123
+
124
+ ```ts
125
+ const ablo = Ablo({
126
+ schema,
127
+ observability: {
128
+ captureClaim: (event) => telemetry.capture('ablo.claim', event),
129
+ captureConflict: (event) => telemetry.capture('ablo.conflict', event),
130
+ },
131
+ });
132
+ ```
133
+
134
+ ## durableWrites
135
+
136
+ Persists an outbound write before dispatch so a worker can recover an
137
+ unacknowledged `create`, `update`, or `delete` after a crash.
138
+
139
+ ```ts
140
+ const ablo = Ablo({
141
+ schema,
142
+ durableWrites: { store, namespace: 'invoice-worker' },
143
+ });
144
+ ```
145
+
146
+ The store must implement `seal()`, `list()`, and `remove()`. `namespace` separates
147
+ deployments or workflow lanes sharing the same authenticated actor. Most clients
148
+ do not need durable writes.
149
+
150
+ ## commitOutbox
151
+
152
+ Deprecated compatibility name for the durable write store. Use
153
+ `durableWrites: { store }`. Passing both forms is an error.
154
+
155
+ ## commitOutboxScope
156
+
157
+ Deprecated compatibility scope for `commitOutbox`. Authentication now resolves
158
+ actor identity. Use `durableWrites.namespace` when shared storage needs separate
159
+ workflow or deployment lanes.
160
+
161
+ ## transport
162
+
163
+ The package-root client uses request/response HTTP. `transport: 'http'` is
164
+ accepted but optional.
165
+
166
+ Live state, presence, and local reads belong to the reactive client described in
167
+ the [React guide](./react.md), rather than another value on this option.
168
+
169
+ ## timeoutMs
170
+
171
+ The deadline in milliseconds for an Ablo HTTP request. Defaults to `30000`. Pass
172
+ `0` only when the surrounding runtime already enforces a deadline.
@@ -281,6 +281,7 @@ await ablo.weatherReports.update({
281
281
  status: 'ready',
282
282
  forecast: weather.summary,
283
283
  },
284
+ claim: handle,
284
285
  });
285
286
  // scope exit releases the claim — no manual release, even if the work threw
286
287
  ```
@@ -307,7 +308,11 @@ if (active) {
307
308
  }
308
309
 
309
310
  await using handle = await ablo.weatherReports.claim({ id: 'weather_stockholm' });
310
- await ablo.weatherReports.update({ id: handle.data.id, data: { status: 'ready' } });
311
+ await ablo.weatherReports.update({
312
+ id: handle.data.id,
313
+ data: { status: 'ready' },
314
+ claim: handle,
315
+ });
311
316
  ```
312
317
 
313
318
  Use `contention: { mode: 'skip' }` when work should be skipped instead of