okmodel 0.0.0 → 0.1.1
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/README.md +246 -1
- package/dist/adapters/capabilities.d.ts +62 -0
- package/dist/adapters/error.d.ts +91 -0
- package/dist/adapters/failure.d.ts +39 -0
- package/dist/adapters/pg/batch.d.ts +36 -0
- package/dist/adapters/pg/call.d.ts +59 -0
- package/dist/adapters/pg/pglite.d.ts +21 -0
- package/dist/adapters/pg/postgres-extra.d.ts +43 -0
- package/dist/adapters/pg/postgresjs.d.ts +95 -0
- package/dist/adapters/pg/result.d.ts +30 -0
- package/dist/contracts/catalog/build.d.ts +18 -0
- package/dist/contracts/catalog/document.d.ts +79 -0
- package/dist/contracts/catalog/enum.d.ts +35 -0
- package/dist/contracts/catalog/identifier.d.ts +71 -0
- package/dist/contracts/catalog/identity.d.ts +98 -0
- package/dist/contracts/catalog/index.d.ts +11 -0
- package/dist/contracts/catalog/json.d.ts +17 -0
- package/dist/contracts/catalog/object.d.ts +142 -0
- package/dist/contracts/catalog/order.d.ts +43 -0
- package/dist/contracts/catalog/rewrite.d.ts +18 -0
- package/dist/contracts/catalog/types.d.ts +292 -0
- package/dist/contracts/catalog/words.d.ts +13 -0
- package/dist/contracts/connection.d.ts +33 -0
- package/dist/contracts/driver.d.ts +163 -0
- package/dist/contracts/error.d.ts +298 -0
- package/dist/contracts/index.d.ts +11 -0
- package/dist/contracts/index.js +16 -0
- package/dist/contracts/internal.d.ts +15 -0
- package/dist/contracts/internal.js +68 -0
- package/dist/contracts/nearest.d.ts +15 -0
- package/dist/contracts/rows.d.ts +84 -0
- package/dist/contracts/sha256.d.ts +14 -0
- package/dist/contracts/utf8.d.ts +33 -0
- package/dist/dialects/pg/array-literal.d.ts +25 -0
- package/dist/dialects/pg/bool.d.ts +46 -0
- package/dist/dialects/pg/column.d.ts +386 -0
- package/dist/dialects/pg/compile.d.ts +81 -0
- package/dist/dialects/pg/custom.d.ts +21 -0
- package/dist/dialects/pg/ddl.d.ts +70 -0
- package/dist/dialects/pg/decimal.d.ts +62 -0
- package/dist/dialects/pg/declarations.d.ts +34 -0
- package/dist/dialects/pg/emit.d.ts +18 -0
- package/dist/dialects/pg/enum.d.ts +30 -0
- package/dist/dialects/pg/errors.d.ts +30 -0
- package/dist/dialects/pg/finite.d.ts +15 -0
- package/dist/dialects/pg/geometry.d.ts +55 -0
- package/dist/dialects/pg/index.d.ts +45 -0
- package/dist/dialects/pg/index.js +1821 -0
- package/dist/dialects/pg/integer.d.ts +96 -0
- package/dist/dialects/pg/introspect.d.ts +43 -0
- package/dist/dialects/pg/json.d.ts +43 -0
- package/dist/dialects/pg/keys.d.ts +32 -0
- package/dist/dialects/pg/misuse.d.ts +31 -0
- package/dist/dialects/pg/model.d.ts +71 -0
- package/dist/dialects/pg/namespace.d.ts +63 -0
- package/dist/dialects/pg/network.d.ts +28 -0
- package/dist/dialects/pg/operators.d.ts +71 -0
- package/dist/dialects/pg/ops/between.d.ts +10 -0
- package/dist/dialects/pg/ops/contains.d.ts +8 -0
- package/dist/dialects/pg/ops/endsWith.d.ts +8 -0
- package/dist/dialects/pg/ops/eq.d.ts +9 -0
- package/dist/dialects/pg/ops/every.d.ts +9 -0
- package/dist/dialects/pg/ops/gt.d.ts +9 -0
- package/dist/dialects/pg/ops/gte.d.ts +9 -0
- package/dist/dialects/pg/ops/has.d.ts +9 -0
- package/dist/dialects/pg/ops/ilike.d.ts +8 -0
- package/dist/dialects/pg/ops/inList.d.ts +9 -0
- package/dist/dialects/pg/ops/inc.d.ts +13 -0
- package/dist/dialects/pg/ops/like.d.ts +8 -0
- package/dist/dialects/pg/ops/lt.d.ts +9 -0
- package/dist/dialects/pg/ops/lte.d.ts +9 -0
- package/dist/dialects/pg/ops/none.d.ts +9 -0
- package/dist/dialects/pg/ops/not.d.ts +9 -0
- package/dist/dialects/pg/ops/notIn.d.ts +9 -0
- package/dist/dialects/pg/ops/or.d.ts +9 -0
- package/dist/dialects/pg/ops/startsWith.d.ts +8 -0
- package/dist/dialects/pg/quote.d.ts +24 -0
- package/dist/dialects/pg/range.d.ts +50 -0
- package/dist/dialects/pg/relations.d.ts +45 -0
- package/dist/dialects/pg/schema.d.ts +77 -0
- package/dist/dialects/pg/search.d.ts +23 -0
- package/dist/dialects/pg/table.d.ts +201 -0
- package/dist/dialects/pg/temporal.d.ts +211 -0
- package/dist/dialects/pg/text.d.ts +44 -0
- package/dist/dialects/pg/time.d.ts +46 -0
- package/dist/okm.js +2 -0
- package/dist/okmodel.js +2 -0
- package/dist/runtime/client.d.ts +47 -0
- package/dist/runtime/conflict.d.ts +38 -0
- package/dist/runtime/drift-detail.d.ts +32 -0
- package/dist/runtime/drift.d.ts +29 -0
- package/dist/runtime/include.d.ts +15 -0
- package/dist/runtime/pg/pglite.d.ts +25 -0
- package/dist/runtime/pg/pglite.js +48 -0
- package/dist/runtime/pg/postgresjs.d.ts +29 -0
- package/dist/runtime/pg/postgresjs.js +62 -0
- package/dist/runtime/plan.d.ts +167 -0
- package/dist/runtime/tx.d.ts +29 -0
- package/dist/runtime/types.d.ts +385 -0
- package/dist/runtime/write.d.ts +48 -0
- package/dist/shared/05w44d8g.js +1524 -0
- package/dist/shared/523ft3e8.js +171 -0
- package/dist/shared/8b04d28c.js +14 -0
- package/dist/shared/cn0n68ft.js +16 -0
- package/dist/shared/dkn3y60a.js +374 -0
- package/dist/shared/dynq16vb.js +81 -0
- package/dist/shared/fgqgsb5z.js +281 -0
- package/dist/shared/g5fhqmwe.js +188 -0
- package/dist/shared/gk7cs7sp.js +566 -0
- package/dist/shared/hadrfb9h.js +398 -0
- package/dist/shared/hd293j9g.js +98 -0
- package/dist/shared/j5cn2963.js +701 -0
- package/dist/shared/jjb7yht9.js +37 -0
- package/dist/shared/kprcwaha.js +30 -0
- package/dist/shared/m3ypagh5.js +347 -0
- package/dist/shared/mkjmqjv4.js +456 -0
- package/dist/shared/mtkwv8wx.js +18 -0
- package/dist/shared/ngk8gj61.js +40 -0
- package/dist/shared/p0cbr3g2.js +79 -0
- package/dist/shared/qk3hxfja.js +83 -0
- package/dist/shared/rgs0st28.js +1066 -0
- package/dist/shared/w8samvk1.js +18 -0
- package/dist/shared/x5x59srr.js +566 -0
- package/dist/shared/xqbhg6cn.js +119 -0
- package/dist/shared/xy79j5hq.js +177 -0
- package/dist/shared/y9m15dfv.js +888 -0
- package/dist/shared/ycwz42az.js +412 -0
- package/dist/shared/yd1kzwn2.js +148 -0
- package/dist/shared/zhc5vmgf.js +257 -0
- package/dist/tooling/cli.d.ts +1 -0
- package/dist/tooling/cli.js +193 -0
- package/dist/tooling/errors/registry.d.ts +33 -0
- package/dist/tooling/migrate/apply.d.ts +86 -0
- package/dist/tooling/migrate/commands.d.ts +21 -0
- package/dist/tooling/migrate/config.d.ts +48 -0
- package/dist/tooling/migrate/dev.d.ts +16 -0
- package/dist/tooling/migrate/equal.d.ts +15 -0
- package/dist/tooling/migrate/files.d.ts +19 -0
- package/dist/tooling/migrate/index.d.ts +7 -0
- package/dist/tooling/migrate/index.js +7 -0
- package/dist/tooling/migrate/plan.d.ts +76 -0
- package/dist/tooling/migrate/policy.d.ts +78 -0
- package/dist/tooling/migrate/project.d.ts +69 -0
- package/dist/tooling/migrate/status.d.ts +74 -0
- package/dist/tooling/migrate/values.d.ts +29 -0
- package/package.json +109 -7
- package/dist/index.js +0 -0
package/README.md
CHANGED
|
@@ -1 +1,246 @@
|
|
|
1
|
-
|
|
1
|
+
# OKModel
|
|
2
|
+
|
|
3
|
+
okmodel is a catalog-first TypeScript ORM, PostgreSQL first. Other SQL databases are the direction. Version 0.1 supports PostgreSQL only. The schema is the single source. Migrations and queries come from it.
|
|
4
|
+
|
|
5
|
+
Version 0.1.1. Apache-2.0.
|
|
6
|
+
|
|
7
|
+
## Contents
|
|
8
|
+
|
|
9
|
+
- [Install](#install)
|
|
10
|
+
- [Quickstart](#quickstart)
|
|
11
|
+
- [Configure](#configure)
|
|
12
|
+
- [Schema](#schema)
|
|
13
|
+
- [Push](#push)
|
|
14
|
+
- [Reviewed migrations](#reviewed-migrations)
|
|
15
|
+
- [One client](#one-client)
|
|
16
|
+
- [Insert](#insert)
|
|
17
|
+
- [Find](#find)
|
|
18
|
+
- [Errors](#errors)
|
|
19
|
+
- [Close](#close)
|
|
20
|
+
- [Commands](#commands)
|
|
21
|
+
- [Roadmap](#roadmap)
|
|
22
|
+
- [Size](#size)
|
|
23
|
+
- [Docs](#docs)
|
|
24
|
+
|
|
25
|
+
## Install
|
|
26
|
+
|
|
27
|
+
Install okmodel and the postgres.js driver.
|
|
28
|
+
|
|
29
|
+
```sh
|
|
30
|
+
bun add okmodel postgres
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
PGlite is the in-process driver.
|
|
34
|
+
|
|
35
|
+
```sh
|
|
36
|
+
bun add okmodel @electric-sql/pglite
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
okmodel has no runtime dependencies. The driver is a peer.
|
|
40
|
+
|
|
41
|
+
## Quickstart
|
|
42
|
+
|
|
43
|
+
`DATABASE_URL` is a direct Postgres URL, not a pooler. The client, insert, find, and error blocks are one script, `run.ts`. `script.ts` is the `await using` form. The last block calls `db.close()`.
|
|
44
|
+
|
|
45
|
+
### Configure
|
|
46
|
+
|
|
47
|
+
Point the CLI at the schema and at that URL.
|
|
48
|
+
|
|
49
|
+
`okmodel.config.ts`:
|
|
50
|
+
|
|
51
|
+
```ts
|
|
52
|
+
import { defineConfig } from "okmodel/migrate";
|
|
53
|
+
|
|
54
|
+
const url = process.env.DATABASE_URL;
|
|
55
|
+
if (url === undefined || url.length === 0) {
|
|
56
|
+
throw new Error("DATABASE_URL is not set");
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export default defineConfig({
|
|
60
|
+
schema: "./schema.ts",
|
|
61
|
+
database: url,
|
|
62
|
+
});
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Schema
|
|
66
|
+
|
|
67
|
+
`t.identity()` is the primary key. An insert omits the id, and the row that comes back carries it. Identity ids come back as strings by default. `t.identity({ as: "number" })` returns numbers. Push and reviewed migrations are two ways to do the same job: pick one per database.
|
|
68
|
+
|
|
69
|
+
Tested on PostgreSQL 15 to 18.
|
|
70
|
+
|
|
71
|
+
`schema.ts`:
|
|
72
|
+
|
|
73
|
+
```ts
|
|
74
|
+
import { one, schema, table, t } from "okmodel/pg";
|
|
75
|
+
|
|
76
|
+
const authors = table("authors", {
|
|
77
|
+
id: t.identity(),
|
|
78
|
+
name: t.text().unique(),
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
const notes = table(
|
|
82
|
+
"notes",
|
|
83
|
+
{
|
|
84
|
+
id: t.identity(),
|
|
85
|
+
title: t.text(),
|
|
86
|
+
authorId: t.bigint().references("authors", { columns: ["id"] }),
|
|
87
|
+
},
|
|
88
|
+
{ relations: { author: one("authors") } },
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
const tables = [authors, notes];
|
|
92
|
+
|
|
93
|
+
export default schema({ tables });
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### Push
|
|
97
|
+
|
|
98
|
+
Create the tables with push, which is allowed because this target is not protected.
|
|
99
|
+
|
|
100
|
+
```sh
|
|
101
|
+
bunx okm push
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
A protected target refuses push. Production settings are in the [production checklist](https://github.com/omqkhafi/okmodel/blob/main/docs/production.md).
|
|
105
|
+
|
|
106
|
+
### Reviewed migrations
|
|
107
|
+
|
|
108
|
+
Generate writes a SQL file and `.okm`, and apply runs that file later so you can read the migration first.
|
|
109
|
+
|
|
110
|
+
```sh
|
|
111
|
+
bunx okm generate init
|
|
112
|
+
bunx okm migrate apply
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### One client
|
|
116
|
+
|
|
117
|
+
This module is cached, so the process has one client.
|
|
118
|
+
|
|
119
|
+
`db.ts`:
|
|
120
|
+
|
|
121
|
+
```ts
|
|
122
|
+
import { connect } from "okmodel/pg/postgresjs";
|
|
123
|
+
|
|
124
|
+
import schema from "./schema.ts";
|
|
125
|
+
|
|
126
|
+
const url = process.env.DATABASE_URL;
|
|
127
|
+
if (url === undefined || url.length === 0) throw new Error("DATABASE_URL is not set");
|
|
128
|
+
|
|
129
|
+
export const db = connect(url, { schema });
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### Insert
|
|
133
|
+
|
|
134
|
+
Insert an author, then a note that points at the author's id.
|
|
135
|
+
|
|
136
|
+
```ts
|
|
137
|
+
import { db } from "./db.ts";
|
|
138
|
+
|
|
139
|
+
const author = await db.authors.insert({ name: "Ada" });
|
|
140
|
+
const note = await db.notes.insert({
|
|
141
|
+
title: "hello",
|
|
142
|
+
authorId: author.id,
|
|
143
|
+
});
|
|
144
|
+
if (author.name !== "Ada" || note.title !== "hello" || author.id.length === 0) {
|
|
145
|
+
throw new Error("insert did not return the row");
|
|
146
|
+
}
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### Find
|
|
150
|
+
|
|
151
|
+
Load that note and its author by the id the insert returned.
|
|
152
|
+
|
|
153
|
+
```ts
|
|
154
|
+
const found = await db.notes.find({
|
|
155
|
+
where: { id: note.id },
|
|
156
|
+
limit: 5,
|
|
157
|
+
include: { author: true },
|
|
158
|
+
});
|
|
159
|
+
const row = found[0];
|
|
160
|
+
if (row?.title !== "hello" || row.author?.name !== "Ada") {
|
|
161
|
+
throw new Error("find did not return the note and its author");
|
|
162
|
+
}
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### Errors
|
|
166
|
+
|
|
167
|
+
`safe` returns the `OkmError` instead of throwing when the author name is already used.
|
|
168
|
+
|
|
169
|
+
```ts
|
|
170
|
+
import { OkmError, safe } from "okmodel";
|
|
171
|
+
|
|
172
|
+
const duplicate = await safe(db.authors.insert({ name: "Ada" }));
|
|
173
|
+
if (duplicate.ok || !(duplicate.error instanceof OkmError) || duplicate.error.kind !== "unique") {
|
|
174
|
+
throw new Error("expected an OkmError of kind unique");
|
|
175
|
+
}
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
### Close
|
|
179
|
+
|
|
180
|
+
A script exits when its queries finish. It does not need `close()` for that. `await using` closes the pool at the end of the block. `db.close()` is that call on a line you choose. A server keeps the client and its connections. A pool opened with `ssl` still waits out the driver's 30 second idle timer.
|
|
181
|
+
|
|
182
|
+
`script.ts`:
|
|
183
|
+
|
|
184
|
+
```ts
|
|
185
|
+
import { connect } from "okmodel/pg/postgresjs";
|
|
186
|
+
|
|
187
|
+
import schema from "./schema.ts";
|
|
188
|
+
|
|
189
|
+
const url = process.env.DATABASE_URL;
|
|
190
|
+
if (url === undefined || url.length === 0) throw new Error("DATABASE_URL is not set");
|
|
191
|
+
|
|
192
|
+
await using db = connect(url, { schema });
|
|
193
|
+
const author = await db.authors.insert({ name: "Lin" });
|
|
194
|
+
if (author.name !== "Lin" || author.id.length === 0) {
|
|
195
|
+
throw new Error("insert did not return the row");
|
|
196
|
+
}
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
```ts
|
|
200
|
+
await db.close();
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
## Commands
|
|
204
|
+
|
|
205
|
+
| Command | What it does |
|
|
206
|
+
| ------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
|
|
207
|
+
| `okm build` | Validates the schema and writes `.okm/` (catalog, hash, emitted row types). `okm generate` writes those files too. |
|
|
208
|
+
| `okm check` | Reports a stale `renamedFrom` and a table file the schema does not import. |
|
|
209
|
+
| `okm generate [name]` | Writes a SQL migration and `.okm/`. The name defaults to `migration`. Prints `no changes` when the schema matches. |
|
|
210
|
+
| `okm dev` | Uses a target named `dev`, or creates a PGlite database in `.okm/dev-db`. It does not apply migrations or write the catalog. |
|
|
211
|
+
| `okm push` | Applies the schema directly. Refused when the target is protected. |
|
|
212
|
+
| `okm migrate plan <name>` | Prints the plan and its class. The name is required. |
|
|
213
|
+
| `okm migrate apply` | Replays migration files on the database. |
|
|
214
|
+
| `okm migrate status` | Prints version, catalog hash, and state for each target. |
|
|
215
|
+
| `okm --version` | Prints the package version. |
|
|
216
|
+
|
|
217
|
+
`okmodel` and `okm` are the same command.
|
|
218
|
+
|
|
219
|
+
## Roadmap
|
|
220
|
+
|
|
221
|
+
- [x] 0.1 — Schema, queries, and migrations on PostgreSQL, with postgres.js and PGlite.
|
|
222
|
+
- [ ] 0.2 — Hidden and sensitive fields, validation, traits, tenancy, archive and restore, richer relations, presets, transactions, and operators for JSON, arrays, ranges, and search.
|
|
223
|
+
- [ ] 0.3 — Extensions, domains, functions, triggers, views, roles, and grants.
|
|
224
|
+
- [ ] 0.4 — Safer migration plans, backfill, drift checks, provisioning, reference data, and a testing package.
|
|
225
|
+
- [ ] 0.5 — A primary with replicas, read routing, and a reference app.
|
|
226
|
+
|
|
227
|
+
`okmodel/internal` has no stability promise. Names on that subpath can change or disappear in any release.
|
|
228
|
+
|
|
229
|
+
Each limit, with the version that lifts it, is in [known limits](https://github.com/omqkhafi/okmodel/blob/main/docs/known-limits.md).
|
|
230
|
+
|
|
231
|
+
## Size
|
|
232
|
+
|
|
233
|
+
Measured on this release.
|
|
234
|
+
|
|
235
|
+
| | Minified | Gzip | Cold import |
|
|
236
|
+
| --------------------------------- | -------: | -----: | ----------: |
|
|
237
|
+
| Runtime entry | 5,525 | 2,042 | 1.758 ms |
|
|
238
|
+
| App startup (10 tables, one find) | 77,537 | 25,625 | 9.922 ms |
|
|
239
|
+
|
|
240
|
+
The rest of the measurements are in [size](https://github.com/omqkhafi/okmodel/blob/main/docs/size.md).
|
|
241
|
+
|
|
242
|
+
## Docs
|
|
243
|
+
|
|
244
|
+
- [Quickstart](https://github.com/omqkhafi/okmodel/blob/main/docs/quickstart.md)
|
|
245
|
+
- [Production checklist](https://github.com/omqkhafi/okmodel/blob/main/docs/production.md)
|
|
246
|
+
- [Known limits](https://github.com/omqkhafi/okmodel/blob/main/docs/known-limits.md)
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Driver capability registry.
|
|
3
|
+
*
|
|
4
|
+
* The flags are data (spec §4). A helper reads them. Spec section 21 has no
|
|
5
|
+
* OKM11xx for a driver that lacks a flag: OKM1110 is the engine-version gate,
|
|
6
|
+
* and OKM1801 is a dialect mismatch. This module does not invent a code and
|
|
7
|
+
* does not throw for a missing flag.
|
|
8
|
+
*/
|
|
9
|
+
import type { DriverCapabilities } from "../contracts/driver.js";
|
|
10
|
+
/** Capability names a caller can read. */
|
|
11
|
+
export declare const CAPABILITY_NAMES: readonly ["transactions", "stream", "listen", "cancel", "prepared", "describe"];
|
|
12
|
+
/** One name in {@link DriverCapabilities}. */
|
|
13
|
+
export type CapabilityName = (typeof CAPABILITY_NAMES)[number];
|
|
14
|
+
/**
|
|
15
|
+
* postgres.js execution flags.
|
|
16
|
+
*
|
|
17
|
+
* Interactive transactions, streaming, listen, cancel, and describe.
|
|
18
|
+
* Statements use the unnamed extended protocol so a plain execute is one
|
|
19
|
+
* round trip. Named prepares are a later opt-in.
|
|
20
|
+
*/
|
|
21
|
+
export declare const POSTGRESJS_CAPABILITIES: {
|
|
22
|
+
readonly transactions: "interactive";
|
|
23
|
+
readonly stream: true;
|
|
24
|
+
readonly listen: true;
|
|
25
|
+
readonly cancel: true;
|
|
26
|
+
readonly prepared: "unnamed";
|
|
27
|
+
readonly describe: true;
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* PGlite execution flags.
|
|
31
|
+
*
|
|
32
|
+
* A pool of one with interactive transactions, listen, and describe.
|
|
33
|
+
* `cancel` is false: an in-flight statement cannot be aborted, and
|
|
34
|
+
* `statement_timeout` is not enforced.
|
|
35
|
+
*/
|
|
36
|
+
export declare const PGLITE_CAPABILITIES: {
|
|
37
|
+
readonly transactions: "interactive";
|
|
38
|
+
readonly stream: false;
|
|
39
|
+
readonly listen: true;
|
|
40
|
+
readonly cancel: false;
|
|
41
|
+
readonly prepared: "unnamed";
|
|
42
|
+
readonly describe: true;
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* Reads one capability flag.
|
|
46
|
+
*
|
|
47
|
+
* @param flags - Declared capabilities
|
|
48
|
+
* @param name - Flag name
|
|
49
|
+
* @returns The flag value
|
|
50
|
+
*/
|
|
51
|
+
export declare function readCapability<Name extends CapabilityName>(flags: DriverCapabilities, name: Name): DriverCapabilities[Name];
|
|
52
|
+
/**
|
|
53
|
+
* Reports whether a boolean capability is set.
|
|
54
|
+
*
|
|
55
|
+
* `transactions` and `prepared` are not boolean. Use {@link readCapability}
|
|
56
|
+
* for those.
|
|
57
|
+
*
|
|
58
|
+
* @param flags - Declared capabilities
|
|
59
|
+
* @param name - `stream`, `listen`, `cancel`, or `describe`
|
|
60
|
+
* @returns The flag
|
|
61
|
+
*/
|
|
62
|
+
export declare function hasCapability(flags: DriverCapabilities, name: "stream" | "listen" | "cancel" | "describe"): boolean;
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Errors an adapter throws.
|
|
3
|
+
*
|
|
4
|
+
* Database failures stay {@link DriverError}. The Postgres dialect maps that
|
|
5
|
+
* to {@link OkmError}. Acquire exhaustion is OKM1846 on {@link OkmError}:
|
|
6
|
+
* that code is the pool's own deadline (spec §15.2), not a SQLSTATE.
|
|
7
|
+
*/
|
|
8
|
+
import { OkmError } from "../contracts/error.js";
|
|
9
|
+
import type { DriverErrorFields, DriverFailureKind } from "../contracts/driver.js";
|
|
10
|
+
/**
|
|
11
|
+
* A driver failure normalised to the contract fields.
|
|
12
|
+
*
|
|
13
|
+
* `batchIndex` is `null` except on a failed batch statement, where it is that
|
|
14
|
+
* statement's index. A commit failure (a deferred constraint) stays `null`.
|
|
15
|
+
*/
|
|
16
|
+
export declare class DriverError extends Error {
|
|
17
|
+
/** SQLSTATE, when the server sent one. */
|
|
18
|
+
readonly sqlstate: string | undefined;
|
|
19
|
+
/** Constraint name, when the server sent one. */
|
|
20
|
+
readonly constraint: string | undefined;
|
|
21
|
+
/** Table name, when the server sent one. */
|
|
22
|
+
readonly table: string | undefined;
|
|
23
|
+
/** Column name, when the server sent one. */
|
|
24
|
+
readonly column: string | undefined;
|
|
25
|
+
/** Server detail line. */
|
|
26
|
+
readonly detail: string | undefined;
|
|
27
|
+
/** Driver or server error underneath. */
|
|
28
|
+
readonly cause: unknown;
|
|
29
|
+
/** Statement index inside a batch, or `null` when this is not that case. */
|
|
30
|
+
readonly batchIndex: number | null;
|
|
31
|
+
/** `timeout` or `cancelled`. Absent on a database error. */
|
|
32
|
+
readonly kind: DriverFailureKind | undefined;
|
|
33
|
+
/**
|
|
34
|
+
* @param message - Error text
|
|
35
|
+
* @param fields - Normalised fields
|
|
36
|
+
*/
|
|
37
|
+
constructor(message: string, fields?: DriverErrorFields);
|
|
38
|
+
/**
|
|
39
|
+
* Same error with a batch index.
|
|
40
|
+
*
|
|
41
|
+
* @param batchIndex - Statement index, or `null` at commit
|
|
42
|
+
* @returns A new error when the index differs
|
|
43
|
+
*/
|
|
44
|
+
at(batchIndex: number | null): DriverError;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* An abort from the caller's `signal` (D124).
|
|
48
|
+
*
|
|
49
|
+
* @param cause - Underlying error, when one exists
|
|
50
|
+
* @returns Kind `cancelled`
|
|
51
|
+
*/
|
|
52
|
+
export declare function cancelled(cause?: unknown): DriverError;
|
|
53
|
+
/**
|
|
54
|
+
* A statement, transaction, or batch deadline (D124).
|
|
55
|
+
*
|
|
56
|
+
* @param cause - Underlying error, when one exists
|
|
57
|
+
* @returns Kind `timeout`
|
|
58
|
+
*/
|
|
59
|
+
export declare function timedOut(cause?: unknown): DriverError;
|
|
60
|
+
/**
|
|
61
|
+
* A commit was sent and its result never arrived (OKM1401 once mapped).
|
|
62
|
+
*
|
|
63
|
+
* @param cause - Underlying error, when one exists
|
|
64
|
+
* @returns Kind `outcome_unknown`, batch index `null`
|
|
65
|
+
*/
|
|
66
|
+
export declare function outcomeUnknown(cause?: unknown): DriverError;
|
|
67
|
+
/**
|
|
68
|
+
* The pool did not hand out a connection within `timeouts.acquire`.
|
|
69
|
+
*
|
|
70
|
+
* @returns OKM1846, kind `timeout`
|
|
71
|
+
*/
|
|
72
|
+
export declare function acquireTimeout(): OkmError;
|
|
73
|
+
/**
|
|
74
|
+
* Reads a string field from an unknown error object.
|
|
75
|
+
*
|
|
76
|
+
* @param error - Caught value
|
|
77
|
+
* @param key - Field name
|
|
78
|
+
* @returns The string, or `undefined`
|
|
79
|
+
*/
|
|
80
|
+
export declare function errorField(error: unknown, key: string): string | undefined;
|
|
81
|
+
/**
|
|
82
|
+
* Maps a driver exception into {@link DriverError}.
|
|
83
|
+
*
|
|
84
|
+
* {@link OkmError} and {@link DriverError} pass through. A batch index on an
|
|
85
|
+
* existing {@link DriverError} is applied with {@link DriverError.at}.
|
|
86
|
+
*
|
|
87
|
+
* @param error - Caught value
|
|
88
|
+
* @param batchIndex - Statement index, or `null` at commit
|
|
89
|
+
* @returns A normalised error
|
|
90
|
+
*/
|
|
91
|
+
export declare function mapDriverError(error: unknown, batchIndex?: number | null): unknown;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Driver-error constructors, loaded on the first failure.
|
|
3
|
+
*
|
|
4
|
+
* A successful `execute` does not import {@link import("./error.js")}.
|
|
5
|
+
*/
|
|
6
|
+
type ErrorModule = typeof import("./error.js");
|
|
7
|
+
/**
|
|
8
|
+
* Loads driver-error constructors once.
|
|
9
|
+
*
|
|
10
|
+
* @returns The error module
|
|
11
|
+
*/
|
|
12
|
+
export declare function driverErrors(): Promise<ErrorModule>;
|
|
13
|
+
/**
|
|
14
|
+
* Rejects with a closed-pool {@link import("./error.js").DriverError}.
|
|
15
|
+
*
|
|
16
|
+
* @param message - Error text
|
|
17
|
+
* @returns A rejected promise
|
|
18
|
+
*/
|
|
19
|
+
export declare function rejectClosed(message?: string): Promise<never>;
|
|
20
|
+
/**
|
|
21
|
+
* Rejects with kind `cancelled`.
|
|
22
|
+
*
|
|
23
|
+
* @returns A rejected promise
|
|
24
|
+
*/
|
|
25
|
+
export declare function rejectCancelled(): Promise<never>;
|
|
26
|
+
/**
|
|
27
|
+
* Rejects with kind `timeout`.
|
|
28
|
+
*
|
|
29
|
+
* @returns A rejected promise
|
|
30
|
+
*/
|
|
31
|
+
export declare function rejectTimedOut(): Promise<never>;
|
|
32
|
+
/**
|
|
33
|
+
* Maps a caught driver exception.
|
|
34
|
+
*
|
|
35
|
+
* @param error - Caught value
|
|
36
|
+
* @returns A normalised error
|
|
37
|
+
*/
|
|
38
|
+
export declare function mapFailure(error: unknown): Promise<unknown>;
|
|
39
|
+
export {};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Atomic batch for an interactive connection.
|
|
3
|
+
*
|
|
4
|
+
* Statements run one at a time. A failure rolls the unit back. Inside an open
|
|
5
|
+
* transaction the unit is a savepoint and the outer transaction stays open
|
|
6
|
+
* (D124). A timeout stays kind `timeout`. An abort stays kind `cancelled`.
|
|
7
|
+
*/
|
|
8
|
+
import type { ExecuteResult, Statement, WireValue } from "../../contracts/driver.js";
|
|
9
|
+
import type { Watch } from "./call.js";
|
|
10
|
+
/** A connection that can run the batch protocol. */
|
|
11
|
+
export type BatchSession = {
|
|
12
|
+
/** This driver can abort an in-flight statement. */
|
|
13
|
+
readonly canCancel: boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Runs one statement.
|
|
16
|
+
*
|
|
17
|
+
* @param text - SQL
|
|
18
|
+
* @param params - Wire parameters
|
|
19
|
+
* @param watch - Shared deadline for the batch, when there is one
|
|
20
|
+
* @returns The statement result
|
|
21
|
+
*/
|
|
22
|
+
query(text: string, params: readonly WireValue[] | undefined, watch: Watch | undefined): Promise<ExecuteResult>;
|
|
23
|
+
/** Reports whether a transaction is open on this connection. */
|
|
24
|
+
inTransaction(): boolean;
|
|
25
|
+
/** Forgets a transaction after a rollback that did not complete. */
|
|
26
|
+
abandon(): void;
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* Runs statements as one atomic unit.
|
|
30
|
+
*
|
|
31
|
+
* @param session - Connection to use
|
|
32
|
+
* @param statements - Statements in order
|
|
33
|
+
* @param watch - Deadline for the whole batch
|
|
34
|
+
* @returns One result per statement
|
|
35
|
+
*/
|
|
36
|
+
export declare function runAtomicBatch(session: BatchSession, statements: readonly Statement[], watch: Watch | undefined): Promise<readonly ExecuteResult[]>;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One deadline for a call.
|
|
3
|
+
*
|
|
4
|
+
* Created only when the caller passed `signal` or `timeout`. A plain execute
|
|
5
|
+
* does not allocate one.
|
|
6
|
+
*/
|
|
7
|
+
import type { DriverFailureKind, ExecuteOptions } from "../../contracts/driver.js";
|
|
8
|
+
/** A signal plus the reason it aborted. */
|
|
9
|
+
export type Watch = {
|
|
10
|
+
/** Aborts on the caller's signal or on the deadline. */
|
|
11
|
+
readonly signal: AbortSignal;
|
|
12
|
+
/** Stops the timer and drops the caller's listener. */
|
|
13
|
+
finish(): void;
|
|
14
|
+
/**
|
|
15
|
+
* Why {@link signal} aborted.
|
|
16
|
+
*
|
|
17
|
+
* `undefined` until it aborts.
|
|
18
|
+
*/
|
|
19
|
+
reason(): DriverFailureKind | undefined;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Reports whether `options` carries a signal or a timeout.
|
|
23
|
+
*
|
|
24
|
+
* @param options - Per-call options
|
|
25
|
+
* @returns True when a {@link Watch} is required
|
|
26
|
+
*/
|
|
27
|
+
export declare function needsWatch(options: ExecuteOptions | undefined): boolean;
|
|
28
|
+
/**
|
|
29
|
+
* Next transaction depth after one statement.
|
|
30
|
+
*
|
|
31
|
+
* Only a whole command matches, so `ROLLBACK TO SAVEPOINT` stays inside the
|
|
32
|
+
* transaction. Kept here so a read does not load the batch runner.
|
|
33
|
+
*
|
|
34
|
+
* @param depth - Depth before the statement
|
|
35
|
+
* @param text - Statement text
|
|
36
|
+
* @returns Depth after a successful statement
|
|
37
|
+
*/
|
|
38
|
+
export declare function nextTransactionDepth(depth: number, text: string): number;
|
|
39
|
+
/**
|
|
40
|
+
* Opens a watch for one call.
|
|
41
|
+
*
|
|
42
|
+
* The caller has already rejected a pre-aborted signal and a non-positive
|
|
43
|
+
* timeout.
|
|
44
|
+
*
|
|
45
|
+
* @param options - Options that include a signal or a timeout
|
|
46
|
+
* @returns The watch. The caller must {@link Watch.finish} it
|
|
47
|
+
*/
|
|
48
|
+
export declare function openWatch(options: ExecuteOptions): Watch;
|
|
49
|
+
/**
|
|
50
|
+
* Runs `fn` with a watch when the caller set a signal or a timeout.
|
|
51
|
+
*
|
|
52
|
+
* A plain call passes `undefined` and returns `fn`'s promise unchanged.
|
|
53
|
+
*
|
|
54
|
+
* @param closed - The pool has been closed
|
|
55
|
+
* @param options - Per-call options
|
|
56
|
+
* @param fn - Work that receives the watch
|
|
57
|
+
* @returns Whatever `fn` returns
|
|
58
|
+
*/
|
|
59
|
+
export declare function runCall<T>(closed: boolean, options: ExecuteOptions | undefined, fn: (watch: Watch | undefined) => Promise<T>): Promise<T>;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PGlite adapter (`okmodel/pg/pglite`).
|
|
3
|
+
*
|
|
4
|
+
* One database is a pool of one. `cancel` is false: a statement already
|
|
5
|
+
* running cannot be aborted. `@electric-sql/pglite` is a peer of this entry.
|
|
6
|
+
*/
|
|
7
|
+
import type { DriverPool, DriverPoolConfig } from "../../contracts/driver.js";
|
|
8
|
+
export { hasCapability, PGLITE_CAPABILITIES as capabilities, readCapability, } from "../capabilities.js";
|
|
9
|
+
export { DriverError } from "../error.js";
|
|
10
|
+
/** Options for {@link open}. The pool size is always one. */
|
|
11
|
+
export type PgliteConfig = DriverPoolConfig & {
|
|
12
|
+
/** Data directory. `memory://` when omitted. */
|
|
13
|
+
readonly dataDir?: string;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Opens a PGlite pool of one.
|
|
17
|
+
*
|
|
18
|
+
* @param config - Data directory and acquire timeout. `max` is ignored
|
|
19
|
+
* @returns The pool
|
|
20
|
+
*/
|
|
21
|
+
export declare function open(config?: PgliteConfig): Promise<DriverPool>;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pool operations a read does not use: checkout, describe, and stream.
|
|
3
|
+
*
|
|
4
|
+
* Loaded on the first reserve, batch, describe, or stream.
|
|
5
|
+
*/
|
|
6
|
+
import type { Sql } from "postgres";
|
|
7
|
+
import type { DescribeResult, DriverConnection, WireValue } from "../../contracts/driver.js";
|
|
8
|
+
import { type Canceller, type Counters, type NoticeBuffer } from "./postgresjs.js";
|
|
9
|
+
/** State `open` shares with a checkout. */
|
|
10
|
+
export type HeldPool = {
|
|
11
|
+
readonly sql: Sql;
|
|
12
|
+
readonly acquireMs: number | undefined;
|
|
13
|
+
readonly counters: Counters;
|
|
14
|
+
readonly isClosed: () => boolean;
|
|
15
|
+
readonly notices: NoticeBuffer;
|
|
16
|
+
readonly named: boolean;
|
|
17
|
+
readonly poolInflight: Set<Canceller>;
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Checks out one connection and clears it on release.
|
|
21
|
+
*
|
|
22
|
+
* @param pool - The open pool
|
|
23
|
+
* @returns A connection the caller must release
|
|
24
|
+
*/
|
|
25
|
+
export declare function checkout(pool: HeldPool): Promise<DriverConnection>;
|
|
26
|
+
/**
|
|
27
|
+
* Describes a statement.
|
|
28
|
+
*
|
|
29
|
+
* @param sql - Pool client
|
|
30
|
+
* @param text - SQL
|
|
31
|
+
* @param params - Wire parameters
|
|
32
|
+
* @returns Column names and the parameter count
|
|
33
|
+
*/
|
|
34
|
+
export declare function describe(sql: Sql, text: string, params?: readonly WireValue[]): Promise<DescribeResult>;
|
|
35
|
+
/**
|
|
36
|
+
* Yields cursor chunks.
|
|
37
|
+
*
|
|
38
|
+
* @param sql - Pool client
|
|
39
|
+
* @param text - SQL
|
|
40
|
+
* @param params - Wire parameters
|
|
41
|
+
* @returns Chunks of wire rows
|
|
42
|
+
*/
|
|
43
|
+
export declare function stream(sql: Sql, text: string, params?: readonly WireValue[]): AsyncIterable<readonly (readonly WireValue[])[]>;
|