Skip to content
AbloAblo
Esc
navigateopen⌘Jpreview
On this page

v0.30.0

Minor Changes

  • The databaseUrl client option is gone. Your database connects to Ablo out of band, not through the client. Ablo is Stripe-shaped: the client only ever talks to the engine. You build it with Ablo({ schema, apiKey }) — add transport: 'http' for a stateless worker — and it reaches Ablo over WebSocket or HTTP. It never opens a Postgres connection of its own. How your data connects is a separate, one-time step, and it takes one of two shapes:

    • Logical replication, the default. ablo connect registers your database, and Ablo tails its write-ahead log. Your rows stay where they are; Ablo reads the change stream and keeps its own log.
    • A signed endpoint, the fallback. When a database can’t grant a REPLICATION role, your app exposes a signed HTTP endpoint for Ablo to call. Same principle — the credentials stay with your app.

    With no connection string in the client, ablo init no longer scaffolds the --storage direct connector, the last thing that wrote databaseUrl: process.env.DATABASE_URL into generated code. Run ablo init --storage replication (the default) or --storage endpoint.

  • A claim’s work label is description, not reason. A claim is an advisory lock: you take it on a row before editing, and other participants — agents or people — see it’s held and wait. The free-text note that says what you’re doing is now description, the line a peer reads when it lands on a row you hold: ablo.<model>.claim({ id, description: 'Renaming the task to match the brief' }). The old reason option is gone, with no alias, so a call still passing it won’t type-check — rename it. (This is a different field from the reason on a rejected or lost claim — 'conflict', 'expired', 'preempted' — which explains why coordination said no, and hasn’t changed.)

  • Claim a key Ablo hasn’t synced: ablo.<model>.claim(id). Claims now come in two shapes, matched to whether Ablo holds the row. The object form, claim({ id }), loads the row from Ablo’s synced pool and returns a HeldClaim<T> with its .data. The new string form, claim(id), locks a row that lives only in your database — one Ablo has never synced — skipping the pool load and the entity_not_found throw, and returns a HeldLease: a HeldClaim without the data. This is Rung 0 of the connect ladder: coordination with no replication grant, no schema change, no organization_id column — so you can coordinate agents against your database before wiring any sync at all. await using releases either shape at end of scope, and the object form is untouched, so nothing you’ve already written changes.

Patch Changes

  • ablo push defers provisioning instead of failing when a role can’t run DDL. When the engine role bound to a plane can’t create or alter tables, push no longer aborts. It records the schema and defers the table changes for a role that can run them — so your models still register, rather than the whole command stalling on a privilege the plane may never grant the engine.

  • Schema-drift stops false-alarming on selectModels / omitModels clients. A projected client carries a deliberate subset of the schema, so its hash differs from the full one by design. The check now compares against the projection’s own source hash — so a correctly projected app no longer sees a phantom drift warning at startup.

Was this page helpful?