@abloatai/ablo 0.16.3 → 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 +34 -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/data-sources.md +164 -287
- package/docs/quickstart.md +51 -63
- package/package.json +1 -1
package/docs/quickstart.md
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
# Quickstart
|
|
2
2
|
|
|
3
3
|
Build with Ablo on **the Postgres you already have**. You declare a small Ablo
|
|
4
|
-
schema for the models humans and agents edit together,
|
|
5
|
-
|
|
6
|
-
`ablo.<model>`.
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
4
|
+
schema for the models humans and agents edit together, connect Ablo to your
|
|
5
|
+
database with **logical replication** (`ablo connect`), and coordinate every read
|
|
6
|
+
and claim through `ablo.<model>`. Your database stays the system of record: your
|
|
7
|
+
app keeps writing through its own backend, Ablo tails your write-ahead log (WAL),
|
|
8
|
+
and the confirmed rows fan out to every connected client. Ablo **never runs DDL,
|
|
9
|
+
owns, or migrates your schema**.
|
|
10
10
|
|
|
11
11
|
> No database yet? The hosted **sandbox** can host rows in Ablo's test plane —
|
|
12
|
-
> pass an `apiKey` only and
|
|
13
|
-
> try Ablo before
|
|
12
|
+
> pass an `apiKey` only and skip the database setup, like Stripe test mode — so
|
|
13
|
+
> you can try Ablo before connecting your Postgres.
|
|
14
14
|
|
|
15
15
|
## 1. Install and initialize
|
|
16
16
|
|
|
@@ -95,15 +95,34 @@ same idiom as tRPC's `typeof appRouter` and Drizzle's `typeof db`; it resolves
|
|
|
95
95
|
the typed overload at the call site. Avoid `ReturnType<typeof Ablo>`, which
|
|
96
96
|
collapses to the untyped client.
|
|
97
97
|
|
|
98
|
-
## 3.
|
|
98
|
+
## 3. Connect your database with `ablo connect`
|
|
99
99
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
100
|
+
Connecting a real database = Postgres logical replication, and `ablo connect` is
|
|
101
|
+
the one way to set it up. Ablo **reads** your WAL and never runs DDL, owns, or
|
|
102
|
+
migrates your schema — your app keeps writing through its own backend.
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
# 1. Enable logical decoding (then RESTART Postgres — wal_level is not reloadable)
|
|
106
|
+
# ALTER SYSTEM SET wal_level = 'logical';
|
|
107
|
+
# On RDS/Aurora: set rds.logical_replication = 1 in the parameter group, reboot.
|
|
108
|
+
|
|
109
|
+
# 2. Print the exact publication + replication-role SQL for YOUR Postgres, run it:
|
|
110
|
+
npx ablo connect
|
|
111
|
+
|
|
112
|
+
# 3. Put the replication role's connection string in DATABASE_URL, then validate:
|
|
113
|
+
npx ablo connect --check
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
`ablo connect` prints the copy-pasteable SQL (a publication named
|
|
117
|
+
`ablo_publication` and a least-privilege `ablo_replicator` role with
|
|
118
|
+
`REPLICATION` + `SELECT`, password you choose). `ablo connect --check` connects to
|
|
119
|
+
`DATABASE_URL` and verifies `wal_level=logical`, the publication, the role's
|
|
120
|
+
`REPLICATION` attribute, and that every published table has a usable
|
|
121
|
+
`REPLICA IDENTITY` — a green checklist or the precise fix per item.
|
|
103
122
|
|
|
104
123
|
```bash
|
|
105
124
|
# .env — server runtime only, never the browser
|
|
106
|
-
DATABASE_URL=postgres://
|
|
125
|
+
DATABASE_URL=postgres://ablo_replicator:<password>@host:5432/db?sslmode=require
|
|
107
126
|
ABLO_API_KEY=sk_test_...
|
|
108
127
|
```
|
|
109
128
|
|
|
@@ -115,50 +134,18 @@ import { schema } from './schema';
|
|
|
115
134
|
export const ablo = Ablo({
|
|
116
135
|
schema,
|
|
117
136
|
apiKey: process.env.ABLO_API_KEY,
|
|
118
|
-
databaseUrl: process.env.DATABASE_URL, // your Postgres, passed explicitly — rows live here
|
|
119
137
|
});
|
|
120
138
|
```
|
|
121
139
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
Use a dedicated **non-superuser role** for the connection — Ablo enforces
|
|
127
|
-
tenant isolation with row-level security, so the server rejects superuser or
|
|
128
|
-
`BYPASSRLS` roles outright (`database_role_cannot_enforce_rls`).
|
|
129
|
-
|
|
130
|
-
> **Neon / Supabase note:** the connection string those dashboards hand you
|
|
131
|
-
> uses the database OWNER role (e.g. `neondb_owner`), which is `BYPASSRLS` —
|
|
132
|
-
> Ablo will reject it. You don't have to fix that by hand: `npx ablo dev`
|
|
133
|
-
> (next step) detects the unsafe role and offers to create the scoped one for
|
|
134
|
-
> you — from your machine, so the owner credential never reaches Ablo. It
|
|
135
|
-
> writes the new `DATABASE_URL` into your env file (the generated password is
|
|
136
|
-
> never printed).
|
|
137
|
-
>
|
|
138
|
-
> Prefer to do it manually? The equivalent SQL:
|
|
139
|
-
>
|
|
140
|
-
> ```sql
|
|
141
|
-
> CREATE ROLE ablo_app LOGIN PASSWORD '<strong password>'
|
|
142
|
-
> NOSUPERUSER NOBYPASSRLS NOCREATEDB NOCREATEROLE;
|
|
143
|
-
> GRANT CREATE, CONNECT ON DATABASE <your_db> TO ablo_app;
|
|
144
|
-
> GRANT CREATE, USAGE ON SCHEMA public TO ablo_app;
|
|
145
|
-
> ```
|
|
146
|
-
>
|
|
147
|
-
> Then swap the user/password in the dashboard's string:
|
|
148
|
-
> `postgres://ablo_app:<password>@<same-host>/<same-db>?sslmode=require`.
|
|
149
|
-
|
|
150
|
-
Don't want a connection string to leave your infrastructure? Keep
|
|
151
|
-
`DATABASE_URL` in your app only and expose one signed **Data Source endpoint**
|
|
152
|
-
built from an ORM adapter instead — same product, same writes, see
|
|
153
|
-
[Connect Your Database](./data-sources.md). In that setup, omit `databaseUrl`
|
|
154
|
-
from `Ablo(...)`.
|
|
140
|
+
The full setup, the honest footprint (publication + slot + `REPLICATION` role +
|
|
141
|
+
the `wal_level` restart + slot/WAL retention Ablo monitors), and the Preview
|
|
142
|
+
status of the WAL runtime are in [Connect Your Database](./data-sources.md).
|
|
155
143
|
|
|
156
144
|
## 4. Push the schema, then map it to tables
|
|
157
145
|
|
|
158
146
|
```bash
|
|
159
|
-
npx ablo push #
|
|
160
|
-
#
|
|
161
|
-
# re-push on every save.
|
|
147
|
+
npx ablo push # pushes the schema definition and writes ABLO_API_KEY to
|
|
148
|
+
# .env.local. Add --watch to re-push on every save.
|
|
162
149
|
```
|
|
163
150
|
|
|
164
151
|
`ablo push` uploads the schema *definition* — model names, fields, types. That
|
|
@@ -166,21 +153,22 @@ metadata is what tells Ablo which models to coordinate. Skipping it makes every
|
|
|
166
153
|
write to a new or changed model fail with `server_execute_unknown_model` — that
|
|
167
154
|
error literally means "run `npx ablo push`."
|
|
168
155
|
|
|
169
|
-
Now
|
|
170
|
-
|
|
156
|
+
Now map those models to your real Postgres tables. **Your migration tool owns the
|
|
157
|
+
tables** — Ablo reads them, it does not create or migrate them:
|
|
158
|
+
|
|
159
|
+
- Run `npx ablo pull` to import the shape of your existing tables (created by
|
|
160
|
+
Prisma, Drizzle, or hand-written migrations) into your schema, or
|
|
161
|
+
`npx ablo check` to verify your schema and the live tables agree. Keep managing
|
|
162
|
+
the tables with your own migration tool; Ablo syncs the subset of models you
|
|
163
|
+
declared and reports the rest as "ignored / owned by you."
|
|
171
164
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
with your own migration tool; Ablo just syncs the subset of models you
|
|
177
|
-
declared.
|
|
178
|
-
- **Let Ablo provision them.** If Ablo should own the tables, `npx ablo migrate`
|
|
179
|
-
creates your synced-model tables (with row-level security) in the registered
|
|
180
|
-
database. Your other tables are left untouched.
|
|
165
|
+
> **Optional escape hatch:** if you have no tables yet and want Ablo to scaffold
|
|
166
|
+
> them, `npx ablo migrate` can create your synced-model tables for you. This is
|
|
167
|
+
> not the happy path — connecting a real database is `ablo connect` (step 3), and
|
|
168
|
+
> your own migrations stay in charge of your schema.
|
|
181
169
|
|
|
182
170
|
Nothing runs locally — there is no dev server to start. Your app talks to Ablo's
|
|
183
|
-
hosted API
|
|
171
|
+
hosted API; the rows live in your database.
|
|
184
172
|
|
|
185
173
|
## 5. Write through the model
|
|
186
174
|
|
|
@@ -279,5 +267,5 @@ Keep using the schema client for app and agent writes.
|
|
|
279
267
|
- [Schema Contract](./schema-contract.md) explains what the schema drives across SDK, React, agents, Data Source, and schema push.
|
|
280
268
|
- [Guarantees](./guarantees.md) explains what confirmed writes and stale checks mean.
|
|
281
269
|
- [Client Behavior](./client-behavior.md) covers errors, retries, and public imports.
|
|
282
|
-
- [Connect Your Database](./data-sources.md) covers
|
|
270
|
+
- [Connect Your Database](./data-sources.md) covers the logical-replication connect path end to end — `ablo connect`, the honest footprint, and the WAL runtime's Preview status.
|
|
283
271
|
- [AI SDK Tool](./examples/ai-sdk-tool.md) shows the same write path inside a tool call.
|