@abloatai/ablo 0.45.0 → 0.46.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 +13 -0
- package/docs/coordination.md +10 -4
- package/docs/data-sources.md +25 -10
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.46.0
|
|
4
|
+
|
|
5
|
+
### Pre-existing rows arrive on their own
|
|
6
|
+
|
|
7
|
+
Connecting a database that already holds data no longer leaves those rows
|
|
8
|
+
invisible until something touches them. Ablo snapshots the pre-existing rows
|
|
9
|
+
automatically, `ablo connect check` refuses to report ready until that
|
|
10
|
+
snapshot completes, and `ablo status --json` exposes the progress as
|
|
11
|
+
`initialSnapshot.status`: `loading`, `retrying` with the underlying error, or
|
|
12
|
+
`complete`. Keep an existing read fallback in place until the status reads
|
|
13
|
+
`complete`. Row-touch backfill scripts are unnecessary; the snapshot is the
|
|
14
|
+
engine's job.
|
|
15
|
+
|
|
3
16
|
## 0.45.0
|
|
4
17
|
|
|
5
18
|
### Claim admission is authoritative
|
package/docs/coordination.md
CHANGED
|
@@ -97,10 +97,9 @@ claim](#writing-under-a-claim)), and the [errors](#errors) you can catch.
|
|
|
97
97
|
>
|
|
98
98
|
> **Testing exclusion:** mint two sessions with different `agent.id` values,
|
|
99
99
|
> assert those values differ, let A acquire the row, and inspect
|
|
100
|
-
> `claim.state({ id })` before B calls
|
|
101
|
-
>
|
|
102
|
-
>
|
|
103
|
-
> does not relax the authoritative lease check.
|
|
100
|
+
> `claim.state({ id })` before B calls
|
|
101
|
+
> `claim({ id, contention: { mode: 'skip' } })`. B must receive `null`.
|
|
102
|
+
> Creating two clients from the same key tests re-entrancy, not contention.
|
|
104
103
|
|
|
105
104
|
---
|
|
106
105
|
|
|
@@ -502,6 +501,13 @@ ablo.<model>.claim.state({ id })
|
|
|
502
501
|
Read who's currently working on a row, for observers and UI. Synchronous and
|
|
503
502
|
reactive (it reads the local coordination snapshot). Never blocks.
|
|
504
503
|
|
|
504
|
+
The first call also starts row-scoped observation. Because that subscription is
|
|
505
|
+
asynchronous, an imperative script may briefly read `null` before the reactive
|
|
506
|
+
snapshot arrives; subscribe to changes or wait for the expected holder when the
|
|
507
|
+
observation itself is the test. Late subscriptions are backfilled across server
|
|
508
|
+
instances, and a skipped conflict attempt seeds its authoritative holder
|
|
509
|
+
summary into the same snapshot immediately.
|
|
510
|
+
|
|
505
511
|
**You don't subscribe to anything first.** Reading or claiming a row
|
|
506
512
|
automatically enrolls you in that row's sync group: reading it (including
|
|
507
513
|
`retrieve`/`get`, or `claim.state` itself) gives you **read-interest**, and
|
package/docs/data-sources.md
CHANGED
|
@@ -74,6 +74,19 @@ yourself. Rotate the scoped passwords any time with `ablo connect rotate`.
|
|
|
74
74
|
The rest of this page is what that command sets up, step by step, for when you want
|
|
75
75
|
to run it by hand or review exactly what changes.
|
|
76
76
|
|
|
77
|
+
### Existing rows load automatically
|
|
78
|
+
|
|
79
|
+
When Ablo creates the replication slot, it takes a consistent initial snapshot of
|
|
80
|
+
every mapped table in the publication before following new changes. Rows that
|
|
81
|
+
predate `ablo connect` therefore become available to `retrieve`, `list`, and
|
|
82
|
+
reactive `local.*` reads without an application backfill.
|
|
83
|
+
|
|
84
|
+
Run `ablo connect check` before removing an existing HTTP/database read fallback.
|
|
85
|
+
It reports the initial load as `loading` until the snapshot is complete. Do not
|
|
86
|
+
write a script that updates every row to make it visible: an Ablo update requires
|
|
87
|
+
the row to be visible already, and touching application rows is neither necessary
|
|
88
|
+
nor a safe bootstrap mechanism.
|
|
89
|
+
|
|
77
90
|
## The setup, step by step
|
|
78
91
|
|
|
79
92
|
### 1. Enable logical decoding
|
|
@@ -172,6 +185,8 @@ checklist or the precise per-item fix:
|
|
|
172
185
|
`REPLICA IDENTITY FULL`) so `UPDATE`/`DELETE` can replicate
|
|
173
186
|
- the writer role is DML-ready — scoped, non-superuser, with the idempotency
|
|
174
187
|
ledger in place
|
|
188
|
+
- the initial snapshot is complete, so rows that existed before connecting are
|
|
189
|
+
available to Ablo reads
|
|
175
190
|
|
|
176
191
|
Because Ablo checks from its own network, a database your own machine can't reach —
|
|
177
192
|
IPv6-only, IP-allowlisted, behind a VPN — still verifies. Re-run it until every
|
|
@@ -195,8 +210,8 @@ export const ablo = Ablo({
|
|
|
195
210
|
```
|
|
196
211
|
|
|
197
212
|
The Ablo schema describes **only your synced, collaborative models** — the rows
|
|
198
|
-
Ablo coordinates and fans out in realtime. It is
|
|
199
|
-
and does
|
|
213
|
+
Ablo coordinates and fans out in realtime. It is _not_ your whole-database schema
|
|
214
|
+
and does _not_ replace your `schema.prisma` (or Drizzle schema). Your auth,
|
|
200
215
|
billing, and other tables stay in your own ORM schema, owned by your own
|
|
201
216
|
migrations. `ablo check` reflects this — it reports tables you didn't declare as
|
|
202
217
|
"ignored / owned by you," which is exactly right.
|
|
@@ -226,13 +241,13 @@ state means and when to wait.
|
|
|
226
241
|
|
|
227
242
|
This is the complete list. Nothing else.
|
|
228
243
|
|
|
229
|
-
| Object
|
|
230
|
-
|
|
231
|
-
| `ablo_publication`
|
|
232
|
-
| `ablo_replicator` role | A `REPLICATION` + `SELECT` role Ablo reads and confirms through.
|
|
233
|
-
| `ablo_writer` role
|
|
234
|
-
| Replication slot
|
|
235
|
-
| `wal_level = logical`
|
|
244
|
+
| Object | What it is | Owned by |
|
|
245
|
+
| ---------------------- | -------------------------------------------------------------------------------- | ------------------------------------------- |
|
|
246
|
+
| `ablo_publication` | A publication naming the tables Ablo reads and confirms against. | You create it (step 2). |
|
|
247
|
+
| `ablo_replicator` role | A `REPLICATION` + `SELECT` role Ablo reads and confirms through. | You create it (step 2). |
|
|
248
|
+
| `ablo_writer` role | A scoped DML role Ablo writes your rows through: row DML + ledger, nothing more. | You create it (step 2). |
|
|
249
|
+
| Replication slot | A logical slot Ablo subscribes through to track its WAL position. | Ablo's runtime creates it on first connect. |
|
|
250
|
+
| `wal_level = logical` | A server setting that **requires a restart**. | You set it (step 1). |
|
|
236
251
|
|
|
237
252
|
Operational reality you should know up front:
|
|
238
253
|
|
|
@@ -254,7 +269,7 @@ have.
|
|
|
254
269
|
|
|
255
270
|
## What Ablo stores on its side
|
|
256
271
|
|
|
257
|
-
Your schema
|
|
272
|
+
Your schema _definition_ (model names, fields, types — pushed with `ablo push`),
|
|
258
273
|
your hashed API keys, a safe projection of the connection registration (host,
|
|
259
274
|
database, schema — the connection string itself is sealed and never echoed back),
|
|
260
275
|
the replication slot position, and the ordered transaction log that drives sync and
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@abloatai/ablo",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.46.0",
|
|
4
4
|
"description": "The public Ablo SDK for coordinated reads, commits, claims, observation, and reactive applications.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
@@ -124,8 +124,8 @@
|
|
|
124
124
|
"directory": "packages/ablo"
|
|
125
125
|
},
|
|
126
126
|
"dependencies": {
|
|
127
|
-
"@abloatai/humans": "^0.
|
|
128
|
-
"@abloatai/transaction": "^0.
|
|
127
|
+
"@abloatai/humans": "^0.46.0",
|
|
128
|
+
"@abloatai/transaction": "^0.46.0"
|
|
129
129
|
},
|
|
130
130
|
"peerDependencies": {
|
|
131
131
|
"ai": "^6.0.0 || ^7.0.0",
|