@abloatai/ablo 0.35.0 → 0.36.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/CHANGELOG.md +713 -629
- package/README.md +56 -519
- package/bin/ablo.cjs +39 -0
- package/dist/BaseSyncedStore.d.ts +24 -4
- package/dist/BaseSyncedStore.js +53 -37
- package/dist/Database.d.ts +8 -20
- package/dist/Database.js +61 -59
- package/dist/InstanceCache.d.ts +6 -2
- package/dist/InstanceCache.js +18 -16
- package/dist/Model.d.ts +17 -7
- package/dist/Model.js +17 -7
- package/dist/ModelRegistry.d.ts +4 -0
- package/dist/ModelRegistry.js +17 -15
- package/dist/NetworkMonitor.d.ts +3 -1
- package/dist/NetworkMonitor.js +7 -5
- package/dist/SyncClient.d.ts +5 -15
- package/dist/SyncClient.js +60 -57
- package/dist/client/Ablo.js +30 -19
- package/dist/client/createInternalComponents.d.ts +4 -0
- package/dist/client/createInternalComponents.js +8 -2
- package/dist/client/createModelProxy.d.ts +21 -1
- package/dist/client/createModelProxy.js +123 -57
- package/dist/client/humans.d.ts +30 -9
- package/dist/client/humans.js +45 -19
- package/dist/client/reactiveEngine.d.ts +16 -11
- package/dist/client/reactiveEngine.js +113 -335
- package/dist/client/storeCluster.d.ts +47 -0
- package/dist/client/storeCluster.js +118 -0
- package/dist/client/storeLifecycle.d.ts +61 -0
- package/dist/client/storeLifecycle.js +231 -0
- package/dist/context.d.ts +13 -0
- package/dist/context.js +23 -0
- package/dist/core/index.d.ts +1 -1
- package/dist/docs/catalog.js +6 -3
- package/dist/index.d.ts +4 -2
- package/dist/index.js +4 -2
- package/dist/query/client.d.ts +3 -0
- package/dist/query/client.js +6 -5
- package/dist/react/AbloProvider.d.ts +13 -1
- package/dist/react/AbloProvider.js +5 -2
- package/dist/react/context.d.ts +2 -2
- package/dist/react/createAbloReact.d.ts +56 -0
- package/dist/react/createAbloReact.js +51 -0
- package/dist/react/index.d.ts +1 -0
- package/dist/react/index.js +3 -0
- package/dist/react/useAblo.d.ts +9 -2
- package/dist/react/useAblo.js +25 -7
- package/dist/schema/coordination.js +5 -1
- package/dist/schema/index.d.ts +1 -0
- package/dist/schema/index.js +4 -0
- package/dist/schema/select.js +3 -0
- package/dist/schema/serialize.js +3 -0
- package/dist/source/adapter.d.ts +7 -5
- package/dist/source/adapter.js +7 -5
- package/dist/source/index.d.ts +1 -1
- package/dist/source/index.js +1 -1
- package/dist/{core/storeContract.d.ts → storeContract.d.ts} +5 -5
- package/dist/{core → stores}/DatabaseManager.d.ts +3 -1
- package/dist/{core → stores}/DatabaseManager.js +13 -12
- package/dist/{core → stores}/StoreManager.d.ts +5 -3
- package/dist/{core → stores}/StoreManager.js +24 -22
- package/dist/stores/SyncActionStore.d.ts +3 -1
- package/dist/stores/SyncActionStore.js +9 -7
- package/dist/sync/BootstrapFetcher.d.ts +4 -0
- package/dist/sync/BootstrapFetcher.js +28 -26
- package/dist/sync/OnDemandLoader.d.ts +3 -0
- package/dist/sync/OnDemandLoader.js +1 -0
- package/dist/sync/bootstrapApply.d.ts +3 -0
- package/dist/sync/bootstrapApply.js +2 -2
- package/dist/sync/deltaPipeline.d.ts +13 -12
- package/dist/sync/deltaPipeline.js +21 -4
- package/dist/sync/groupChange.d.ts +3 -0
- package/dist/sync/groupChange.js +16 -14
- package/dist/sync/participants.d.ts +19 -2
- package/dist/sync/participants.js +3 -1
- package/dist/sync/schemas.d.ts +2 -1
- package/dist/sync/schemas.js +3 -3
- package/dist/syncLog/contract.d.ts +20 -0
- package/dist/syncLog/contract.js +19 -0
- package/dist/syncLog/index.d.ts +1 -0
- package/dist/syncLog/index.js +1 -0
- package/dist/transaction/auth/capability.d.ts +35 -0
- package/dist/transaction/auth/capability.js +25 -0
- package/dist/transaction/coordination/awaitClaimGrant.d.ts +7 -0
- package/dist/transaction/coordination/awaitClaimGrant.js +12 -0
- package/dist/transaction/coordination/claimHeartbeatLoop.d.ts +34 -0
- package/dist/transaction/coordination/claimHeartbeatLoop.js +20 -0
- package/dist/transaction/coordination/index.d.ts +4 -4
- package/dist/transaction/coordination/index.js +4 -3
- package/dist/transaction/coordination/locator.d.ts +23 -2
- package/dist/transaction/coordination/locator.js +22 -2
- package/dist/transaction/coordination/schema.d.ts +125 -62
- package/dist/transaction/coordination/schema.js +228 -64
- package/dist/transaction/coordination/targetConflict.js +32 -28
- package/dist/transaction/errorCodes.d.ts +2 -2
- package/dist/transaction/errorCodes.js +13 -9
- package/dist/transaction/plugin.d.ts +95 -2
- package/dist/transaction/plugin.js +21 -2
- package/dist/transaction/resources/httpResources.d.ts +57 -2
- package/dist/transaction/resources/modelOperations.d.ts +148 -40
- package/dist/transaction/resources/where.d.ts +16 -0
- package/dist/transaction/resources/where.js +45 -0
- package/dist/transaction/schema/field.d.ts +12 -18
- package/dist/transaction/schema/fieldRef.d.ts +38 -0
- package/dist/transaction/schema/fieldRef.js +11 -0
- package/dist/transaction/schema/openapi.d.ts +16 -15
- package/dist/transaction/schema/openapi.js +186 -25
- package/dist/transaction/schema/relation.d.ts +7 -2
- package/dist/transaction/schema/schema.d.ts +27 -0
- package/dist/transaction/schema/schema.js +20 -0
- package/dist/transaction/transactions/settlement/commitEnvelope.d.ts +1 -1
- package/dist/transaction/transactions/settlement/pendingWrite.d.ts +1 -1
- package/dist/transaction/transport/httpClient.d.ts +9 -1
- package/dist/transaction/transport/httpClient.js +1 -0
- package/dist/transaction/transport/httpTransport.js +156 -44
- package/dist/transaction/transport/wsTransport.d.ts +2 -4
- package/dist/transaction/transport/wsTransport.js +16 -10
- package/dist/transaction/types/streams.d.ts +10 -0
- package/dist/transaction/utils/duration.d.ts +25 -0
- package/dist/transaction/utils/duration.js +32 -0
- package/dist/transaction/wire/accountResponses.d.ts +69 -0
- package/dist/transaction/wire/accountResponses.js +36 -1
- package/dist/transaction/wire/auth.d.ts +9 -2
- package/dist/transaction/wire/auth.js +7 -1
- package/dist/transaction/wire/claims.d.ts +164 -97
- package/dist/transaction/wire/claims.js +126 -28
- package/dist/transaction/wire/commit.d.ts +1 -1
- package/dist/transaction/wire/feedEvent.d.ts +27 -0
- package/dist/transaction/wire/feedEvent.js +27 -1
- package/dist/transaction/wire/frames.d.ts +2 -2
- package/dist/transaction/wire/inboundFrames.d.ts +12 -2
- package/dist/transaction/wire/index.d.ts +10 -6
- package/dist/transaction/wire/index.js +12 -3
- package/dist/transaction/wire/modelMutations.d.ts +31 -0
- package/dist/transaction/wire/modelMutations.js +52 -0
- package/dist/transaction/wire/modelShape.d.ts +78 -0
- package/dist/transaction/wire/modelShape.js +74 -0
- package/dist/transactions/mutations/MutationQueue.d.ts +6 -0
- package/dist/transactions/mutations/MutationQueue.js +55 -45
- package/dist/transactions/mutations/commitPayload.d.ts +3 -2
- package/dist/transactions/mutations/commitPayload.js +5 -5
- package/dist/transactions/mutations/deltaConfirmation.d.ts +4 -0
- package/dist/transactions/mutations/deltaConfirmation.js +10 -8
- package/dist/transactions/mutations/replayValidation.d.ts +2 -1
- package/dist/transactions/mutations/replayValidation.js +3 -2
- package/dist/{core → views}/QueryView.d.ts +1 -1
- package/dist/{core → views}/QueryView.js +1 -1
- package/dist/{core → views}/ViewRegistry.d.ts +1 -1
- package/dist/{core/queryUtils.d.ts → views/incrementalView.d.ts} +6 -6
- package/dist/{core/queryUtils.js → views/incrementalView.js} +6 -6
- package/docs/agents.md +1 -1
- package/docs/api-keys.md +6 -6
- package/docs/api.md +5 -43
- package/docs/audit.md +4 -3
- package/docs/cli.md +11 -11
- package/docs/client-behavior.md +4 -4
- package/docs/concurrency-convention.md +28 -42
- package/docs/coordination.md +235 -83
- package/docs/data-sources.md +4 -4
- package/docs/debugging.md +34 -12
- package/docs/deployment.md +8 -8
- package/docs/examples/scoped-agent.md +3 -3
- package/docs/groups.md +57 -3
- package/docs/guarantees.md +37 -10
- package/docs/how-it-works.md +29 -5
- package/docs/idempotency.md +6 -6
- package/docs/identity.md +22 -23
- package/docs/index.md +8 -8
- package/docs/integration-guide.md +14 -3
- package/docs/mcp.md +7 -7
- package/docs/migration.md +34 -15
- package/docs/projects.md +1 -1
- package/docs/react.md +19 -8
- package/docs/sessions.md +1 -1
- package/docs/webhooks.md +9 -9
- package/llms.txt +4 -4
- package/package.json +13 -20
- package/dist/cli.cjs +0 -288600
- package/dist/testing/fixtures/bootstrap.d.ts +0 -49
- package/dist/testing/fixtures/bootstrap.js +0 -59
- package/dist/testing/fixtures/deltas.d.ts +0 -83
- package/dist/testing/fixtures/deltas.js +0 -136
- package/dist/testing/fixtures/httpResponses.d.ts +0 -70
- package/dist/testing/fixtures/httpResponses.js +0 -90
- package/dist/testing/fixtures/models.d.ts +0 -83
- package/dist/testing/fixtures/models.js +0 -272
- package/dist/testing/helpers/reactWrapper.d.ts +0 -69
- package/dist/testing/helpers/reactWrapper.js +0 -67
- package/dist/testing/helpers/syncEngineHarness.d.ts +0 -54
- package/dist/testing/helpers/syncEngineHarness.js +0 -73
- package/dist/testing/helpers/wait.d.ts +0 -30
- package/dist/testing/helpers/wait.js +0 -49
- package/dist/testing/index.d.ts +0 -23
- package/dist/testing/index.js +0 -33
- package/dist/testing/mocks/FakeDatabase.d.ts +0 -18
- package/dist/testing/mocks/FakeDatabase.js +0 -10
- package/dist/testing/mocks/MockMutationExecutor.d.ts +0 -87
- package/dist/testing/mocks/MockMutationExecutor.js +0 -186
- package/dist/testing/mocks/MockNetworkMonitor.d.ts +0 -20
- package/dist/testing/mocks/MockNetworkMonitor.js +0 -46
- package/dist/testing/mocks/MockSyncContext.d.ts +0 -51
- package/dist/testing/mocks/MockSyncContext.js +0 -72
- package/dist/testing/mocks/MockSyncStore.d.ts +0 -88
- package/dist/testing/mocks/MockSyncStore.js +0 -171
- package/dist/testing/mocks/MockWebSocket.d.ts +0 -71
- package/dist/testing/mocks/MockWebSocket.js +0 -118
- package/docs/interaction-model.md +0 -99
- /package/dist/{core → query}/QueryProcessor.d.ts +0 -0
- /package/dist/{core → query}/QueryProcessor.js +0 -0
- /package/dist/{core/storeContract.js → storeContract.js} +0 -0
- /package/dist/{core → stores}/openIDBWithTimeout.d.ts +0 -0
- /package/dist/{core → stores}/openIDBWithTimeout.js +0 -0
- /package/dist/{source → transaction}/footprint.d.ts +0 -0
- /package/dist/{source → transaction}/footprint.js +0 -0
- /package/dist/{core → views}/ViewRegistry.js +0 -0
package/docs/migration.md
CHANGED
|
@@ -13,6 +13,7 @@ change when you upgrade.
|
|
|
13
13
|
|
|
14
14
|
| Version | What changed | What to do |
|
|
15
15
|
|---|---|---|
|
|
16
|
+
| **0.36.0** | `ttlSeconds` deprecated on the join surfaces in favour of `ttl` | `useJoin({ scope, ttlSeconds: '5m' })` → `useJoin({ scope, ttl: '5m' })`; same for `ParticipantJoinOptions`. Both spellings work until 0.37.0 |
|
|
16
17
|
| **0.35.0** | Synchronous reads moved under `local`, mirroring the async verbs | `get(id)` → `local.retrieve(id)`; `getAll(options)` → `local.list(options)`; `getCount(options)` → `local.count(options)` |
|
|
17
18
|
| **0.35.0** | `causedByTaskId` write option + seven `turn_*` error codes removed | Delete the `causedByTaskId` argument from writes; a branch on `turn_validation_failed` was unreachable and can go with it |
|
|
18
19
|
| **0.34.0** | Presence verb renamed `watch` → `join` | `ablo.<model>.watch(ids)` → `ablo.<model>.join(ids)`; `useWatch` → `useJoin`; the `WatchOptions` / `UseWatchOptions` / `UseWatchReturn` types → `JoinOptions` / `UseJoinOptions` / `UseJoinReturn`; error code `model_watch_not_configured` → `model_join_not_configured` |
|
|
@@ -31,7 +32,25 @@ change when you upgrade.
|
|
|
31
32
|
|
|
32
33
|
---
|
|
33
34
|
|
|
34
|
-
## 0.
|
|
35
|
+
## 0.36.0: one lease is spelled `ttl`
|
|
36
|
+
|
|
37
|
+
```diff
|
|
38
|
+
- useJoin({ scope: { documents: [id] }, ttlSeconds: '5m' })
|
|
39
|
+
+ useJoin({ scope: { documents: [id] }, ttl: '5m' })
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
`ablo.<model>.join(ids, { ttl })` has always said `ttl`, and so does every other
|
|
43
|
+
lease in the SDK: `claim`'s `ttl`, `ClaimLeaseOptions.ttl`. The lower-level join
|
|
44
|
+
surfaces said `ttlSeconds` while accepting exactly the same values, including
|
|
45
|
+
duration strings, so a `ttl: '5m'` handed down from the model verb arrived as
|
|
46
|
+
`ttlSeconds: '5m'`, a field asserting a unit its value did not carry.
|
|
47
|
+
|
|
48
|
+
Both spellings work until 0.37.0, and `ttl` wins if you pass both. The wire is
|
|
49
|
+
unchanged: it has always carried seconds and still does.
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## 0.35.0: the synchronous reads move under `local`
|
|
35
54
|
|
|
36
55
|
```diff
|
|
37
56
|
- const task = ablo.tasks.get(id);
|
|
@@ -53,7 +72,7 @@ in most codebases it is outnumbered many times over by `Map.get` and
|
|
|
53
72
|
the compiler name the sites — each one is a type error at exactly the call that
|
|
54
73
|
has to move.
|
|
55
74
|
|
|
56
|
-
## 0.35.0
|
|
75
|
+
## 0.35.0: `causedByTaskId` and the `turn_*` error codes removed
|
|
57
76
|
|
|
58
77
|
0.9.2 retired the `turn` primitive but left one field standing: `causedByTaskId`
|
|
59
78
|
on the write options bag. It was never usable. The server validated it against a
|
|
@@ -85,7 +104,7 @@ migration of its own.
|
|
|
85
104
|
|
|
86
105
|
---
|
|
87
106
|
|
|
88
|
-
## 0.34.0
|
|
107
|
+
## 0.34.0: presence verb renamed `watch` → `join`
|
|
89
108
|
|
|
90
109
|
The model-level presence verb read like a data subscription but delivered
|
|
91
110
|
presence — who else is on a row and what they hold — so it now says what it
|
|
@@ -108,7 +127,7 @@ no compatibility alias — rename the call sites and the `WatchOptions` /
|
|
|
108
127
|
|
|
109
128
|
---
|
|
110
129
|
|
|
111
|
-
## 0.28.0
|
|
130
|
+
## 0.28.0: dead React multiplayer placeholders removed
|
|
112
131
|
|
|
113
132
|
Four React exports looked usable but had no live implementation:
|
|
114
133
|
|
|
@@ -123,7 +142,7 @@ Four React exports looked usable but had no live implementation:
|
|
|
123
142
|
There is no compatibility alias: the replacement APIs were already the only
|
|
124
143
|
working paths.
|
|
125
144
|
|
|
126
|
-
## 0.11.0
|
|
145
|
+
## 0.11.0: `intent` → `claim` rename completed
|
|
127
146
|
|
|
128
147
|
> **Historical note:** this section documents the 0.11.0 transition.
|
|
129
148
|
> `useClaim` was subsequently removed in 0.28.0 because its provider callback
|
|
@@ -166,7 +185,7 @@ contending holders (`AbloClaimedError.claims` and a policy reason folded into th
|
|
|
166
185
|
message), and `participantKind` is the canonical `'user' | 'agent' | 'system'`
|
|
167
186
|
on presence and claim state.
|
|
168
187
|
|
|
169
|
-
## 0.10.0
|
|
188
|
+
## 0.10.0: environment enum `sandbox` / `production`; stateless HTTP transport
|
|
170
189
|
|
|
171
190
|
### Environment enum rename (the only breaking change)
|
|
172
191
|
|
|
@@ -222,7 +241,7 @@ await ablo.tasks.update({ id, data: { status: 'done' } });
|
|
|
222
241
|
|
|
223
242
|
---
|
|
224
243
|
|
|
225
|
-
## 0.9.2
|
|
244
|
+
## 0.9.2: `turn` / agent-`tasks` removed; `intents` deprecated
|
|
226
245
|
|
|
227
246
|
The SDK's coordination surface is now exactly two things: `ablo.<model>` writes
|
|
228
247
|
and `claim`. The parallel `turn` / agent-`tasks` mechanism was redundant —
|
|
@@ -271,7 +290,7 @@ everywhere you coordinate concurrent work.
|
|
|
271
290
|
|
|
272
291
|
---
|
|
273
292
|
|
|
274
|
-
## 0.9.0
|
|
293
|
+
## 0.9.0: one options object per verb; disposable `claim`
|
|
275
294
|
|
|
276
295
|
Every model verb takes a single options object, so the id, the data, and every
|
|
277
296
|
modifier are named siblings. Reactive local reads stay on the synchronous
|
|
@@ -305,7 +324,7 @@ options object.
|
|
|
305
324
|
|
|
306
325
|
---
|
|
307
326
|
|
|
308
|
-
## 0.8.0
|
|
327
|
+
## 0.8.0: callable `claim` namespace
|
|
309
328
|
|
|
310
329
|
The flat coordination methods are gone; everything lives under `claim`.
|
|
311
330
|
|
|
@@ -318,7 +337,7 @@ The flat coordination methods are gone; everything lives under `claim`.
|
|
|
318
337
|
|
|
319
338
|
---
|
|
320
339
|
|
|
321
|
-
## 0.7.0
|
|
340
|
+
## 0.7.0: legacy React hooks removed
|
|
322
341
|
|
|
323
342
|
The query/mutation hooks were replaced by the single `useAblo()` accessor over
|
|
324
343
|
typed model methods.
|
|
@@ -340,7 +359,7 @@ shape with the canonical `{ type, code, message, doc_url, request_id }` envelope
|
|
|
340
359
|
|
|
341
360
|
---
|
|
342
361
|
|
|
343
|
-
## 0.6.0
|
|
362
|
+
## 0.6.0: `onChange` and the Resource → Model rename
|
|
344
363
|
|
|
345
364
|
```diff
|
|
346
365
|
- ablo.tasks.subscribe(cb)
|
|
@@ -356,7 +375,7 @@ Also renamed: `Ablo.Resource.*` → `Ablo.Model.*`, `ModelTarget.resource` →
|
|
|
356
375
|
|
|
357
376
|
---
|
|
358
377
|
|
|
359
|
-
## 0.5.0
|
|
378
|
+
## 0.5.0: intent-handle method renames
|
|
360
379
|
|
|
361
380
|
On the model intent handle (`ablo.<model>.intent(id)`):
|
|
362
381
|
|
|
@@ -373,7 +392,7 @@ unchanged at this release. (They were later folded under `claim` in 0.9.2.)
|
|
|
373
392
|
|
|
374
393
|
---
|
|
375
394
|
|
|
376
|
-
## 0.3.0
|
|
395
|
+
## 0.3.0: umbrella `<AbloProvider>`
|
|
377
396
|
|
|
378
397
|
One provider component now owns the full React lifecycle. `<SyncProvider>`,
|
|
379
398
|
`createAbloContext()`, and `withSync` were removed.
|
|
@@ -407,10 +426,10 @@ old code or old docs, this is the through-line:
|
|
|
407
426
|
|
|
408
427
|
| Release | State of coordination |
|
|
409
428
|
|---|---|
|
|
410
|
-
| 0.4.0 | `ablo.<model>.intent(id)` introduced
|
|
429
|
+
| 0.4.0 | `ablo.<model>.intent(id)` introduced: per-entity intent handle |
|
|
411
430
|
| 0.5.0 | Intent-handle methods renamed to claim vocabulary (`acquire`→`claim`, …) |
|
|
412
431
|
| 0.8.0 | Callable `claim` namespace (`claim(id)`, `claim.state`, `claim.queue`, …) |
|
|
413
432
|
| 0.9.0 | `claim` returns an `await using` disposable handle |
|
|
414
|
-
| 0.9.2 | `intents` deprecated and made `@internal
|
|
433
|
+
| 0.9.2 | `intents` deprecated and made `@internal`: **`claim` is the one coordination API** |
|
|
415
434
|
|
|
416
435
|
For the full chronological history, see the [Changelog](../CHANGELOG.md).
|
package/docs/projects.md
CHANGED
|
@@ -95,5 +95,5 @@ another org's project ids 404 — never confirm existence across orgs.
|
|
|
95
95
|
|
|
96
96
|
| Code | Status | Meaning |
|
|
97
97
|
|------|--------|---------|
|
|
98
|
-
| `project_scope_denied` | 403 | The model/resource belongs to another project in your org
|
|
98
|
+
| `project_scope_denied` | 403 | The model/resource belongs to another project in your org: use a key minted for that project. |
|
|
99
99
|
| `project_slug_taken` | 409 | A project with this slug already exists in the organization. |
|
package/docs/react.md
CHANGED
|
@@ -27,6 +27,7 @@ the thing, then pass it.
|
|
|
27
27
|
```ts
|
|
28
28
|
// lib/ablo.ts
|
|
29
29
|
import Ablo from '@abloatai/ablo';
|
|
30
|
+
import { createAbloReact } from '@abloatai/ablo/react';
|
|
30
31
|
import { schema } from '@/ablo/schema';
|
|
31
32
|
|
|
32
33
|
// The browser never holds your API key. It mints a short-lived session token
|
|
@@ -35,8 +36,18 @@ export const ablo = Ablo({
|
|
|
35
36
|
schema,
|
|
36
37
|
authEndpoint: '/api/ablo-session',
|
|
37
38
|
});
|
|
39
|
+
|
|
40
|
+
// The typed binding: capture the schema once, and every component imports
|
|
41
|
+
// born-typed hooks from this file — `useAblo()` takes no type arguments,
|
|
42
|
+
// and a selector's `ablo` parameter knows your models.
|
|
43
|
+
export const { AbloProvider, useAblo } = createAbloReact(schema);
|
|
38
44
|
```
|
|
39
45
|
|
|
46
|
+
Import `AbloProvider` and `useAblo` from `lib/ablo` rather than from the
|
|
47
|
+
package, and the schema generic never appears at a call site again — the
|
|
48
|
+
same one-binding-file convention as tRPC's `createTRPCReact` or
|
|
49
|
+
react-redux's typed hooks.
|
|
50
|
+
|
|
40
51
|
## AbloProvider
|
|
41
52
|
|
|
42
53
|
Mount it once near the root of your tree. It owns the connection, the local
|
|
@@ -67,10 +78,10 @@ export function Providers({
|
|
|
67
78
|
|
|
68
79
|
| Prop | Default | Purpose |
|
|
69
80
|
| ----------- | ---------------- | --------------------------------------------------------------------------------------------------------- |
|
|
70
|
-
| `client`
|
|
81
|
+
| `client` |: | **Required.** The `Ablo({ schema, apiKey })` instance. It carries the schema and connection config. |
|
|
71
82
|
| `userId` | resolved from auth | App participant id for app-owned fields and your `identityRoles`. Not the security boundary. |
|
|
72
83
|
| `fallback` | neutral spinner | Rendered during the *first* bootstrap only. Pass a branded skeleton, `null`, or `'passthrough'`. |
|
|
73
|
-
| `onError`
|
|
84
|
+
| `onError` |: | Engine / WebSocket / bootstrap errors. Wire to Sentry / Datadog. |
|
|
74
85
|
|
|
75
86
|
Everything that used to be a provider prop — `schema`, `url`, `apiKey`,
|
|
76
87
|
`teamIds`, `syncGroups`, `persistence`, `bootstrapMode` — now lives on
|
|
@@ -79,7 +90,7 @@ identity comes from, and why the API key never reaches the browser, is the whole
|
|
|
79
90
|
of [Identity & Sync Groups](./identity.md) — read that if it isn't obvious how
|
|
80
91
|
org / team / user map to what a participant can see.
|
|
81
92
|
|
|
82
|
-
## useAblo
|
|
93
|
+
## useAblo: model client
|
|
83
94
|
|
|
84
95
|
```tsx
|
|
85
96
|
'use client';
|
|
@@ -180,7 +191,7 @@ imperative work after an event or effect.
|
|
|
180
191
|
|
|
181
192
|
See [API reference](/docs/api) for the full options surface.
|
|
182
193
|
|
|
183
|
-
## useJoin
|
|
194
|
+
## useJoin: scoped presence + read interest
|
|
184
195
|
|
|
185
196
|
`useJoin` is the React form of `ablo.<model>.join`. It joins multiplayer for a
|
|
186
197
|
scope on the engine's existing socket (one TCP connection, N logical
|
|
@@ -209,10 +220,10 @@ Options (`UseJoinOptions`):
|
|
|
209
220
|
|
|
210
221
|
| Option | Default | Effect |
|
|
211
222
|
| --- | --- | --- |
|
|
212
|
-
| `scope`
|
|
213
|
-
| `claim` | `false` | Acquire a write-claim on the scope (sent so peers observe it; pins the scope so it never warm-drops while held). A viewer is not a claimant
|
|
223
|
+
| `scope` |: | Model-form scope (`{ slideDecks: id }`), resolved through the schema. Omit for engine-wide. |
|
|
224
|
+
| `claim` | `false` | Acquire a write-claim on the scope (sent so peers observe it; pins the scope so it never warm-drops while held). A viewer is not a claimant: leave `false` for read-only. |
|
|
214
225
|
| `hydrate` | `false` | Backfill the scope's current rows into the pool once on enter, then keep them fresh via the live tail. Set `true` for deep-linked / never-opened entities. Single-flight; soft-fails. |
|
|
215
|
-
| `ttlSeconds`
|
|
226
|
+
| `ttlSeconds` |: | Lease TTL for the scope claim. |
|
|
216
227
|
| `paused` | `false` | Tear down and don't re-join while true. |
|
|
217
228
|
|
|
218
229
|
Returns (`UseJoinReturn`): `{ participant, peers, claims, status, error }`.
|
|
@@ -220,7 +231,7 @@ Returns (`UseJoinReturn`): `{ participant, peers, claims, status, error }`.
|
|
|
220
231
|
write-claims; `status` is the join lifecycle. Auto-cleans up on unmount or when
|
|
221
232
|
`paused` flips true.
|
|
222
233
|
|
|
223
|
-
## usePeers
|
|
234
|
+
## usePeers: read-only presence
|
|
224
235
|
|
|
225
236
|
`usePeers` is a *pure reader* of the presence stream already flowing on the
|
|
226
237
|
connection. Unlike `useJoin`, it does **not** enter/leave a scope (no
|
package/docs/sessions.md
CHANGED
|
@@ -175,7 +175,7 @@ Your schema lives in a **project** — you push it once (`npx ablo push`) and ev
|
|
|
175
175
|
session you mint resolves against it. The flow for serving end-users:
|
|
176
176
|
|
|
177
177
|
1. **Push your schema** to your project.
|
|
178
|
-
2. **Mint an `ek_` per user
|
|
178
|
+
2. **Mint an `ek_` per user:** `sessions.create({ user: { id } })`. Your users
|
|
179
179
|
commit to that one schema.
|
|
180
180
|
|
|
181
181
|
**Your users do not have Ablo accounts.** You authenticate them however you
|
package/docs/webhooks.md
CHANGED
|
@@ -25,7 +25,7 @@ There are two ways data flows out of Ablo, and they're for different jobs:
|
|
|
25
25
|
| | reaches | use it for |
|
|
26
26
|
|---|---|---|
|
|
27
27
|
| **Realtime** (`useAblo`, WSS) | your live UI | instant, optimistic rendering |
|
|
28
|
-
| **Webhooks** (this page) | your database | a durable copy you own
|
|
28
|
+
| **Webhooks** (this page) | your database | a durable copy you own: analytics, backups, server logic |
|
|
29
29
|
|
|
30
30
|
Most apps use both: the realtime stream for the UI, the webhook stream to keep
|
|
31
31
|
their database in sync. This page is the webhook stream.
|
|
@@ -34,8 +34,8 @@ If you know Stripe, you already know the shape:
|
|
|
34
34
|
|
|
35
35
|
| Stripe | Ablo |
|
|
36
36
|
|---|---|
|
|
37
|
-
| `stripe.x.create(...)
|
|
38
|
-
| `/stripe-webhook
|
|
37
|
+
| `stripe.x.create(...)`: make the change | the Ablo client: make the change (+ live sync) |
|
|
38
|
+
| `/stripe-webhook`: confirm and persist | `/api/ablo/[...all]`: persist into your database |
|
|
39
39
|
| Stripe owns the charges | Ablo owns the transaction log |
|
|
40
40
|
| you mirror charges into your database | you mirror the log into your database |
|
|
41
41
|
|
|
@@ -50,11 +50,11 @@ Every delivery is a batch of events. Each event:
|
|
|
50
50
|
| field | meaning |
|
|
51
51
|
|---|---|
|
|
52
52
|
| `type` | `"<model>.<verb>"` with the model name lowercased, e.g. `task.updated` |
|
|
53
|
-
| `model` | the model name exactly as declared in your schema
|
|
53
|
+
| `model` | the model name exactly as declared in your schema: the table to write |
|
|
54
54
|
| `objectId` | the changed row's id |
|
|
55
55
|
| `data` | the post-change row, or `null` on delete (like Stripe's `event.data.object`) |
|
|
56
|
-
| `syncId` | monotonic log position
|
|
57
|
-
| `id` | `String(syncId)
|
|
56
|
+
| `syncId` | monotonic log position: **dedupe and order by this** |
|
|
57
|
+
| `id` | `String(syncId)`: the event id |
|
|
58
58
|
| `createdAt` | ISO commit timestamp |
|
|
59
59
|
|
|
60
60
|
```ts
|
|
@@ -200,8 +200,8 @@ sequenceDiagram
|
|
|
200
200
|
|
|
201
201
|
| behavior | how it works |
|
|
202
202
|
|---|---|
|
|
203
|
-
| **Ordering** | Every event carries `syncId`, a monotonic log position. Apply in `syncId` order
|
|
204
|
-
| **Retries** | A non-`2xx` (or no response within the timeout) is retried with backoff: immediate, 5s, 5m, 30m, 2h, 5h, 10h, 10h
|
|
203
|
+
| **Ordering** | Every event carries `syncId`, a monotonic log position. Apply in `syncId` order: Ablo guarantees the order because it owns the log. |
|
|
204
|
+
| **Retries** | A non-`2xx` (or no response within the timeout) is retried with backoff: immediate, 5s, 5m, 30m, 2h, 5h, 10h, 10h: 8 attempts over ~32h. |
|
|
205
205
|
| **Auto-disable** | After the retries exhaust, the endpoint is marked `disabled` and delivery stops until you `ablo webhooks enable <id>`. |
|
|
206
206
|
| **Replay** | Nothing is lost on failure: the log *is* the durable buffer, and delivery resumes from the endpoint's cursor once it's healthy. |
|
|
207
207
|
|
|
@@ -213,7 +213,7 @@ sequenceDiagram
|
|
|
213
213
|
- **Return `2xx` fast.** Acknowledge first, then do slow work asynchronously.
|
|
214
214
|
- **Subscribe to only what you need.** Set `enabledEvents` to the models you
|
|
215
215
|
mirror (`['*']` is the default = all).
|
|
216
|
-
- **Roll secrets periodically
|
|
216
|
+
- **Roll secrets periodically:** `ablo webhooks roll <id>` mints a new secret;
|
|
217
217
|
Standard Webhooks supports a rotation window so in-flight events still verify.
|
|
218
218
|
- **Verify the raw body.** Frameworks that re-serialize JSON will break the
|
|
219
219
|
signature — verify the bytes you received.
|
package/llms.txt
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
# Ablo
|
|
2
2
|
|
|
3
|
-
Ablo is
|
|
3
|
+
Ablo is collaboration infrastructure for AI agents: one API for agents, apps, and services to claim, change, and confirm the same rows.
|
|
4
4
|
|
|
5
|
-
Here is the problem it solves. Two agents reach for `report_stockholm` at once. One claims the row, does slow work (an LLM call, a fetch, a chain of tools), and commits. The second is neither rejected nor allowed to clobber: it waits in line, is handed the row as it now stands, and proceeds. Claims don't lock. If another writer holds the row, `claim` waits for them, re-reads the fresh row, then hands it to you — so writers serialize instead of colliding. A person editing that row is simply another holder; the agent waits behind them the same way.
|
|
5
|
+
Here is the problem it solves. Two agents reach for `report_stockholm` at once. One claims the row, does slow work (an LLM call, a fetch, a chain of tools), and commits. The second is neither rejected nor allowed to clobber: it waits in line, is handed the row as it now stands, and proceeds. Claims don't lock. If another writer holds the row, `claim` waits for them, re-reads the fresh row, then hands it to you — so writers serialize instead of colliding. A person editing that row is simply another holder; the agent waits behind them the same way. And a claim is as narrow as its target: name a `path`, a `range`, or a `field` and two claims on non-overlapping parts of the same row are both granted — region locking within one row, with no queueing between regions.
|
|
6
6
|
|
|
7
7
|
Use AI SDK for the agent loop. Use Ablo when agent reads and writes must persist, coordinate with concurrent work, and leave an audit trail.
|
|
8
8
|
|
|
9
|
-
## Surfaces
|
|
9
|
+
## Surfaces: pick by who is calling
|
|
10
10
|
|
|
11
11
|
Every surface reaches the same coordinated state. They are not interchangeable.
|
|
12
12
|
|
|
@@ -217,7 +217,7 @@ Import from these public paths only:
|
|
|
217
217
|
|
|
218
218
|
Do not teach `/api`, `/agent`, `/ai-sdk`, `/core`, `/realtime`, or internal subpaths. (`/source` IS public — it's the Data Source endpoint surface above.)
|
|
219
219
|
|
|
220
|
-
## CLI
|
|
220
|
+
## CLI: agents run it NON-INTERACTIVELY
|
|
221
221
|
|
|
222
222
|
`ablo init` and other prompts need a TTY; an agent/CI run has none and will HANG. Always:
|
|
223
223
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@abloatai/ablo",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.36.0",
|
|
4
4
|
"description": "The Collaboration Layer For AI Agents",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"main": "./dist/index.js",
|
|
11
11
|
"types": "./dist/index.d.ts",
|
|
12
12
|
"bin": {
|
|
13
|
-
"ablo": "./
|
|
13
|
+
"ablo": "./bin/ablo.cjs"
|
|
14
14
|
},
|
|
15
15
|
"exports": {
|
|
16
16
|
".": {
|
|
@@ -33,11 +33,6 @@
|
|
|
33
33
|
"import": "./dist/react/index.js",
|
|
34
34
|
"default": "./dist/react/index.js"
|
|
35
35
|
},
|
|
36
|
-
"./testing": {
|
|
37
|
-
"types": "./dist/testing/index.d.ts",
|
|
38
|
-
"import": "./dist/testing/index.js",
|
|
39
|
-
"default": "./dist/testing/index.js"
|
|
40
|
-
},
|
|
41
36
|
"./core": {
|
|
42
37
|
"types": "./dist/core/index.d.ts",
|
|
43
38
|
"import": "./dist/core/index.js",
|
|
@@ -98,6 +93,11 @@
|
|
|
98
93
|
"import": "./dist/wire/index.js",
|
|
99
94
|
"default": "./dist/wire/index.js"
|
|
100
95
|
},
|
|
96
|
+
"./syncLog": {
|
|
97
|
+
"types": "./dist/syncLog/index.d.ts",
|
|
98
|
+
"import": "./dist/syncLog/index.js",
|
|
99
|
+
"default": "./dist/syncLog/index.js"
|
|
100
|
+
},
|
|
101
101
|
"./server": {
|
|
102
102
|
"types": "./dist/server/index.d.ts",
|
|
103
103
|
"import": "./dist/server/index.js",
|
|
@@ -115,6 +115,7 @@
|
|
|
115
115
|
}
|
|
116
116
|
},
|
|
117
117
|
"files": [
|
|
118
|
+
"bin",
|
|
118
119
|
"dist",
|
|
119
120
|
"!dist/__type_probe.*",
|
|
120
121
|
"docs/*.md",
|
|
@@ -129,21 +130,21 @@
|
|
|
129
130
|
],
|
|
130
131
|
"scripts": {
|
|
131
132
|
"clean": "node -e \"require('fs').rmSync('dist',{recursive:true,force:true})\"",
|
|
132
|
-
"build": "npm run clean && tsc -p tsconfig.build.json
|
|
133
|
-
"
|
|
134
|
-
"typecheck": "npm run typecheck:src && npm run typecheck:cli && npm run typecheck:scripts",
|
|
133
|
+
"build": "npm run clean && tsc -p tsconfig.build.json",
|
|
134
|
+
"typecheck": "npm run typecheck:src && npm run typecheck:scripts",
|
|
135
135
|
"typecheck:src": "tsc -p tsconfig.json",
|
|
136
|
-
"typecheck:cli": "tsc -p tsconfig.cli.json",
|
|
137
136
|
"typecheck:scripts": "tsc -p tsconfig.scripts.json",
|
|
138
137
|
"prepack": "node scripts/strip-source-condition.mjs",
|
|
139
138
|
"postpack": "node scripts/restore-source-condition.mjs",
|
|
140
139
|
"pack:check": "node scripts/pack-check.mjs",
|
|
141
|
-
"lint": "npm run lint:imports && npm run lint:errors && npm run lint:docs && npm run lint:docs-site",
|
|
140
|
+
"lint": "npm run lint:imports && npm run lint:errors && npm run lint:openapi && npm run lint:docs && npm run lint:docs-site",
|
|
142
141
|
"build:docs": "node scripts/build-blume-docs.mjs",
|
|
143
142
|
"lint:docs-site": "node scripts/build-blume-docs.mjs --check",
|
|
144
143
|
"lint:imports": "node scripts/check-js-extensions.mjs",
|
|
145
144
|
"generate:errors": "tsx scripts/generate-error-docs.mts",
|
|
145
|
+
"generate:openapi": "tsx --conditions=@ablo/source scripts/generate-openapi.mts",
|
|
146
146
|
"lint:errors": "tsx scripts/check-error-docs.mts",
|
|
147
|
+
"lint:openapi": "tsx --conditions=@ablo/source scripts/generate-openapi.mts --check",
|
|
147
148
|
"lint:docs": "node scripts/check-doc-drift.mjs",
|
|
148
149
|
"lint:eslint": "eslint . --cache",
|
|
149
150
|
"lint:pkg": "publint",
|
|
@@ -151,7 +152,6 @@
|
|
|
151
152
|
"check:dist": "node scripts/check-dist-fresh.mjs",
|
|
152
153
|
"pretest": "node scripts/check-dist-fresh.mjs",
|
|
153
154
|
"test": "jest",
|
|
154
|
-
"test:quickstart": "node scripts/test-quickstart.mjs",
|
|
155
155
|
"test:unit": "jest --testPathPatterns __tests__/unit",
|
|
156
156
|
"test:integration": "jest --testPathPatterns __tests__/integration",
|
|
157
157
|
"test:contract": "jest --testPathPatterns __tests__/contract",
|
|
@@ -205,7 +205,6 @@
|
|
|
205
205
|
}
|
|
206
206
|
},
|
|
207
207
|
"dependencies": {
|
|
208
|
-
"jiti": "^2.7.0",
|
|
209
208
|
"mobx": "^6.13.7",
|
|
210
209
|
"mobx-react-lite": "^4.0.0",
|
|
211
210
|
"uuid": "^11.1.0",
|
|
@@ -213,9 +212,7 @@
|
|
|
213
212
|
},
|
|
214
213
|
"devDependencies": {
|
|
215
214
|
"@ai-sdk/provider": "^3.0.0",
|
|
216
|
-
"@clack/prompts": "^0.11.0",
|
|
217
215
|
"@jest/globals": "^30.2.0",
|
|
218
|
-
"@prisma/client": "^7.3.0",
|
|
219
216
|
"@types/jest": "^30.0.0",
|
|
220
217
|
"@types/node": "^22.0.0",
|
|
221
218
|
"@types/react": "^19.0.0",
|
|
@@ -230,13 +227,9 @@
|
|
|
230
227
|
"jest": "^30.2.0",
|
|
231
228
|
"jest-environment-jsdom": "^30.2.0",
|
|
232
229
|
"jest-environment-node": "^30.2.0",
|
|
233
|
-
"picocolors": "^1.1.0",
|
|
234
|
-
"postgres": "^3.4.0",
|
|
235
230
|
"react": "^19.0.0",
|
|
236
231
|
"react-dom": "^19.0.0",
|
|
237
232
|
"ts-jest": "^29.4.5",
|
|
238
|
-
"ts-morph": "^26.0.0",
|
|
239
|
-
"tsup": "^8.0.0",
|
|
240
233
|
"tsx": "^4.19.0",
|
|
241
234
|
"typescript": "^5.8.3",
|
|
242
235
|
"publint": "^0.3.21",
|