@abloatai/ablo 0.16.2 → 0.17.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 +50 -0
- package/dist/BaseSyncedStore.d.ts +3 -1
- package/dist/BaseSyncedStore.js +27 -4
- package/dist/cli.cjs +366 -211
- package/dist/client/Ablo.js +24 -11
- package/dist/schema/diff.d.ts +14 -0
- package/docs/agent-messaging.md +149 -0
- package/docs/agents.md +104 -0
- package/docs/data-sources.md +164 -287
- package/docs/index.md +0 -1
- package/docs/projects.md +97 -0
- package/docs/quickstart.md +51 -63
- package/docs/react.md +1 -1
- package/docs/sessions.md +239 -0
- package/docs/webhooks.md +231 -0
- package/package.json +4 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,55 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.17.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- **Bring-your-own database is now one model.** Ablo connects to your Postgres and
|
|
8
|
+
never operates it. There used to be two confusing BYO paths, and the
|
|
9
|
+
connection-string one would create roles, force row-level security, transfer
|
|
10
|
+
table ownership, and push you to run `ablo migrate` before anything worked. That
|
|
11
|
+
cascade is gone. Ablo now follows the shape every serious "sync over your own
|
|
12
|
+
Postgres" engine uses (ElectricSQL, PowerSync, Zero): it reads your database via
|
|
13
|
+
Postgres logical replication and never runs DDL, creates roles, forces RLS, or
|
|
14
|
+
rewrites your `DATABASE_URL`. You own your schema; Ablo reads it.
|
|
15
|
+
- **New: `ablo connect`.** One command prints the exact, copy-pasteable setup for
|
|
16
|
+
your own Postgres — enable `wal_level=logical`, create the `ablo_publication`
|
|
17
|
+
publication and a least-privilege `ablo_replicator` role — and
|
|
18
|
+
`ablo connect --check` validates readiness (wal level, publication, replication
|
|
19
|
+
grant, replica identity). This is the single supported way to connect a real
|
|
20
|
+
database.
|
|
21
|
+
- **`ablo migrate` left the happy path.** It no longer creates roles, transfers
|
|
22
|
+
ownership, or rewrites your connection string, and `ablo dev` no longer attempts
|
|
23
|
+
a scoped-role creation on every watch loop. `migrate` is now an optional escape
|
|
24
|
+
hatch for generating starter DDL (`--dry-run` prints the SQL).
|
|
25
|
+
- **Clearer failures.** `ablo push` permission errors lead with the server's actual
|
|
26
|
+
reason code and per-code remediation instead of a generic "needs `schema:push`
|
|
27
|
+
scope," and the schema-conflict message names which environment/version a prior
|
|
28
|
+
push came from and when.
|
|
29
|
+
- **Logical-replication runtime is in Preview.** The setup (`ablo connect`) and the
|
|
30
|
+
connection model are live; the server-side WAL consumer that streams your changes
|
|
31
|
+
is implemented and journey-tested but not yet generally available.
|
|
32
|
+
|
|
33
|
+
The previous connection-string-operate and adapter/outbox modes are demoted to a
|
|
34
|
+
clearly-labeled **Legacy / not recommended** section — they still work, but new
|
|
35
|
+
integrations should use logical replication.
|
|
36
|
+
|
|
37
|
+
## 0.16.3
|
|
38
|
+
|
|
39
|
+
### Patch Changes
|
|
40
|
+
|
|
41
|
+
- **Docs.** The bundled SDK docs are now the single source for the documentation
|
|
42
|
+
site, and several pages were expanded or corrected:
|
|
43
|
+
- The sessions/identity model is reframed around **projects** — push one schema
|
|
44
|
+
to a project, mint an `ek_` per user (your users need no Ablo account), and
|
|
45
|
+
all of them commit to that one schema. Per-customer org isolation
|
|
46
|
+
(`schemaProject`) is presented as the add-on it is, not the default.
|
|
47
|
+
- The declarative `conflict` schema axis (Axis 3) is now documented.
|
|
48
|
+
- The agent docs were corrected to the current claim vocabulary
|
|
49
|
+
(`reason`/`queue`, not the pre-0.12.0 `action`/`wait`).
|
|
50
|
+
|
|
51
|
+
No code changes.
|
|
52
|
+
|
|
3
53
|
## 0.16.2
|
|
4
54
|
|
|
5
55
|
### Patch Changes
|
|
@@ -702,7 +702,9 @@ export declare class BaseSyncedStore<TCollaboration extends EventMap<TCollaborat
|
|
|
702
702
|
* sync-group mutations). Does NOT schedule a flush — callers decide
|
|
703
703
|
* whether to debounce (live) or flush atomically (catch-up frame).
|
|
704
704
|
*/
|
|
705
|
-
protected enqueueDelta(delta: SyncDelta
|
|
705
|
+
protected enqueueDelta(delta: SyncDelta, options?: {
|
|
706
|
+
authoritative?: boolean;
|
|
707
|
+
}): boolean;
|
|
706
708
|
/** Debounce a flush for live single-delta traffic. */
|
|
707
709
|
protected scheduleDeltaFlush(): void;
|
|
708
710
|
/**
|
package/dist/BaseSyncedStore.js
CHANGED
|
@@ -1713,7 +1713,25 @@ export class BaseSyncedStore {
|
|
|
1713
1713
|
applyDeltaFrame(deltas) {
|
|
1714
1714
|
let enqueuedAny = false;
|
|
1715
1715
|
for (const delta of deltas) {
|
|
1716
|
-
|
|
1716
|
+
// A delta_batch frame is the server's AUTHORITATIVE, ordered answer to
|
|
1717
|
+
// "everything in my stream after cursor C" (reconnect/catch-up replay or
|
|
1718
|
+
// post-bootstrap drain). Apply every delta it carries — do NOT subject it
|
|
1719
|
+
// to the live-traffic watermark dedup (`id <= applied`).
|
|
1720
|
+
//
|
|
1721
|
+
// That watermark is only valid under in-order delivery, and reconnect
|
|
1722
|
+
// breaks the assumption: an in-flight LIVE broadcast for a gap delta can
|
|
1723
|
+
// land out of order BEFORE the catch-up fills the ids below it (e.g. the
|
|
1724
|
+
// server acks a write, then the test/client reconnects, then that write's
|
|
1725
|
+
// pending broadcast arrives on the fresh socket — id 4 live before the
|
|
1726
|
+
// catch-up's [2,3,4]). Applying id 4 advances `applied` to 4, and the
|
|
1727
|
+
// watermark would then drop 2 and 3 from the catch-up as "already seen" —
|
|
1728
|
+
// a poisoned gap and a cursor that lies (applied=4 with rows 2,3 absent).
|
|
1729
|
+
//
|
|
1730
|
+
// Re-applying a delta the live path already applied is safe: the
|
|
1731
|
+
// downstream `Database.processDeltaBatch` + `SyncClient.applyDeltaBatchToPool`
|
|
1732
|
+
// are idempotent (echo detection, no row resurrection, conflict
|
|
1733
|
+
// resolution), so the redundant id 4 is a no-op while 2 and 3 land.
|
|
1734
|
+
if (this.enqueueDelta(delta, { authoritative: true }))
|
|
1717
1735
|
enqueuedAny = true;
|
|
1718
1736
|
}
|
|
1719
1737
|
if (!enqueuedAny)
|
|
@@ -1734,10 +1752,15 @@ export class BaseSyncedStore {
|
|
|
1734
1752
|
* sync-group mutations). Does NOT schedule a flush — callers decide
|
|
1735
1753
|
* whether to debounce (live) or flush atomically (catch-up frame).
|
|
1736
1754
|
*/
|
|
1737
|
-
enqueueDelta(delta) {
|
|
1738
|
-
// Dedup guard — skip already-processed deltas
|
|
1739
|
-
|
|
1755
|
+
enqueueDelta(delta, options = {}) {
|
|
1756
|
+
// Dedup guard — skip already-processed deltas. The `applied` watermark is a
|
|
1757
|
+
// valid skip threshold ONLY for in-order live traffic; an authoritative
|
|
1758
|
+
// catch-up frame bypasses it (see `applyDeltaFrame`) so an out-of-order
|
|
1759
|
+
// live delta that advanced the watermark can't cause the frame's lower ids
|
|
1760
|
+
// to be silently dropped.
|
|
1761
|
+
if (!options.authoritative && delta.id > 0 && delta.id <= this.highestProcessedSyncId) {
|
|
1740
1762
|
return false;
|
|
1763
|
+
}
|
|
1741
1764
|
// Confirm awaiting transactions via sync ID threshold (before batching)
|
|
1742
1765
|
this.syncClient.onDeltaReceived(delta.id);
|
|
1743
1766
|
// Update version vector
|