@gobing-ai/ts-db 0.4.27 → 0.4.30
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 +26 -19
- package/dist/inbox-message-dao.d.ts +3 -1
- package/dist/inbox-message-dao.d.ts.map +1 -1
- package/dist/inbox-message-dao.js +8 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -1
- package/dist/schema/define-table.d.ts +3 -6
- package/dist/schema/define-table.d.ts.map +1 -1
- package/dist/schema/define-table.js +1 -1
- package/package.json +3 -3
- package/src/inbox-message-dao.ts +8 -1
- package/src/index.ts +0 -1
- package/src/schema/define-table.ts +3 -6
package/README.md
CHANGED
|
@@ -6,7 +6,9 @@ A **drizzle-free database facade**: typed DAOs over Bun SQLite / Cloudflare D1,
|
|
|
6
6
|
|
|
7
7
|
## Overview
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Data-access code imports the main `@gobing-ai/ts-db` facade; schema definitions import
|
|
10
|
+
`@gobing-ai/ts-db/schema`. Consumer code never imports `drizzle-orm` directly, which keeps the
|
|
11
|
+
storage engine swappable and the query surface small and auditable. Two tiers, your choice:
|
|
10
12
|
|
|
11
13
|
- **Structured tier** (`EntityDao`) — typed `create`/`createMany`/`upsert`/`findById`/`findBy`/`update`/`delete`/`list`/`listByCursor`/`count`, filtered by a small predicate spec (`{ col, op, value }`).
|
|
12
14
|
- **Raw tier** (`BaseDao`) — `query`/`one`/`tx` for table-agnostic access; ETL/analytics/reporting DAOs extend this directly.
|
|
@@ -16,15 +18,15 @@ Application code imports only `@gobing-ai/ts-db` — never `drizzle-orm`. drizzl
|
|
|
16
18
|
|-----------|---------|
|
|
17
19
|
| `createDbAdapter` / `DbAdapter` | Construction + lifecycle + string-SQL escape + atomic batch; exposes an internal typed db to the DAO layer only |
|
|
18
20
|
| `BunSqliteAdapter` | Bun SQLite implementation with statement caching and WAL pragmas (`@gobing-ai/ts-db/bun-sqlite`) |
|
|
19
|
-
| `D1Adapter` | Cloudflare D1 implementation (no `@cloudflare/workers-types` dependency) |
|
|
21
|
+
| `D1Adapter` | Cloudflare D1 implementation (`@gobing-ai/ts-db/d1`; no `@cloudflare/workers-types` dependency) |
|
|
20
22
|
| `BaseDao` | Raw tier — `query`/`one`/`tx`, drizzle-free signatures |
|
|
21
23
|
| `EntityDao` | Structured CRUD — predicate filters, soft delete, RETURNING, batch, upsert, cursor pagination, composite PK |
|
|
22
|
-
| `defineTable` | Single source of truth — one table → drizzle table + derived zod insert/select schemas (optional peers) |
|
|
24
|
+
| `defineTable` | Single source of truth — one table → drizzle table + derived zod insert/select schemas (`@gobing-ai/ts-db/schema`; optional peers) |
|
|
23
25
|
| `Predicate` / `ListSpec` / `OrderTerm` | The drizzle-free query vocabulary |
|
|
24
26
|
| `QueueJobDao` | Job queue persistence — `enqueue`, `claimReady`, `markCompleted`, `failExpiredJobs` |
|
|
25
27
|
| `InboxMessageDao` | Durable inter-agent message persistence (`@gobing-ai/ts-db/inbox`) |
|
|
26
28
|
| `applyMigrations` | Drizzle migration runner (file-based + embedded fallback) |
|
|
27
|
-
| `schema` helpers | `standardColumns`, `appendOnlyColumns`, soft-delete columns |
|
|
29
|
+
| `schema` helpers | `standardColumns`, `appendOnlyColumns`, soft-delete columns (`@gobing-ai/ts-db/schema`) |
|
|
28
30
|
| `SpanContext` | Re-exported from `@gobing-ai/ts-runtime` for telemetry |
|
|
29
31
|
|
|
30
32
|
### Optional peers (validation)
|
|
@@ -187,18 +189,18 @@ await adapter.batch([
|
|
|
187
189
|
```
|
|
188
190
|
### EntityDao — CRUD with soft delete
|
|
189
191
|
|
|
190
|
-
Define a
|
|
192
|
+
Define a table through the schema subpath, extend `EntityDao`, get full CRUD for free:
|
|
191
193
|
|
|
192
194
|
```ts
|
|
193
|
-
import {
|
|
194
|
-
import {
|
|
195
|
+
import { type DbAdapter, EntityDao } from '@gobing-ai/ts-db';
|
|
196
|
+
import { defineTable, standardColumns, text } from '@gobing-ai/ts-db/schema';
|
|
195
197
|
|
|
196
|
-
const users =
|
|
198
|
+
const users = defineTable('users', {
|
|
197
199
|
id: text('id').primaryKey(),
|
|
198
200
|
name: text('name').notNull(),
|
|
199
201
|
email: text('email').notNull(),
|
|
200
202
|
...standardColumns,
|
|
201
|
-
});
|
|
203
|
+
}).table;
|
|
202
204
|
|
|
203
205
|
class UsersDao extends EntityDao<typeof users, typeof users.id> {
|
|
204
206
|
constructor(adapter: DbAdapter) {
|
|
@@ -347,22 +349,28 @@ await applyMigrations(adapter);
|
|
|
347
349
|
### Schema helpers
|
|
348
350
|
|
|
349
351
|
```ts
|
|
350
|
-
import {
|
|
351
|
-
|
|
352
|
+
import {
|
|
353
|
+
defineTable,
|
|
354
|
+
inboxMessages,
|
|
355
|
+
queueJobs,
|
|
356
|
+
standardColumns,
|
|
357
|
+
standardColumnsWithSoftDelete,
|
|
358
|
+
text,
|
|
359
|
+
} from '@gobing-ai/ts-db/schema';
|
|
352
360
|
|
|
353
361
|
// Standard columns (createdAt, updatedAt)
|
|
354
|
-
const docs =
|
|
362
|
+
const docs = defineTable('docs', {
|
|
355
363
|
id: text('id').primaryKey(),
|
|
356
364
|
title: text('title').notNull(),
|
|
357
365
|
...standardColumns,
|
|
358
|
-
});
|
|
366
|
+
}).table;
|
|
359
367
|
|
|
360
368
|
// With soft delete (adds inUsed column)
|
|
361
|
-
const projects =
|
|
369
|
+
const projects = defineTable('projects', {
|
|
362
370
|
id: text('id').primaryKey(),
|
|
363
371
|
name: text('name').notNull(),
|
|
364
372
|
...standardColumnsWithSoftDelete,
|
|
365
|
-
});
|
|
373
|
+
}).table;
|
|
366
374
|
|
|
367
375
|
// queue_jobs table is pre-built for use with QueueJobDao
|
|
368
376
|
|
|
@@ -382,15 +390,14 @@ bun add -D drizzle-kit
|
|
|
382
390
|
|
|
383
391
|
```ts
|
|
384
392
|
// src/schema.ts
|
|
385
|
-
import {
|
|
386
|
-
import { standardColumns } from '@gobing-ai/ts-db';
|
|
393
|
+
import { defineTable, standardColumns, text } from '@gobing-ai/ts-db/schema';
|
|
387
394
|
|
|
388
|
-
export const todos =
|
|
395
|
+
export const todos = defineTable('todos', {
|
|
389
396
|
id: text('id').primaryKey(),
|
|
390
397
|
title: text('title').notNull(),
|
|
391
398
|
done: text('done').notNull().default('0'),
|
|
392
399
|
...standardColumns,
|
|
393
|
-
});
|
|
400
|
+
}).table;
|
|
394
401
|
```
|
|
395
402
|
|
|
396
403
|
### Create a DAO
|
|
@@ -63,7 +63,9 @@ export declare class InboxMessageDao extends EntityDao<typeof inboxMessages, typ
|
|
|
63
63
|
private readonly events?;
|
|
64
64
|
constructor(adapter: DbAdapter, options?: InboxMessageDaoOptions);
|
|
65
65
|
enqueue(fromId: string | null, toId: string, body: string, inReplyTo?: string): Promise<string>;
|
|
66
|
-
drainPending(toId: string
|
|
66
|
+
drainPending(toId: string, options?: {
|
|
67
|
+
limit?: number;
|
|
68
|
+
}): Promise<InboxMessage[]>;
|
|
67
69
|
markDelivered(msgId: string): Promise<void>;
|
|
68
70
|
markFailed(msgId: string, error: string): Promise<void>;
|
|
69
71
|
inbox(toId: string, limit?: number, offset?: number): Promise<InboxMessage[]>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"inbox-message-dao.d.ts","sourceRoot":"","sources":["../src/inbox-message-dao.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAE3C,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAExD,gEAAgE;AAChE,MAAM,MAAM,YAAY,GAAG,OAAO,aAAa,CAAC,YAAY,CAAC;AAM7D,8CAA8C;AAC9C,MAAM,WAAW,qBAAqB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACrB;AAED,uFAAuF;AACvF,MAAM,WAAW,qBAAqB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;CACrB;AAED,+CAA+C;AAC/C,MAAM,WAAW,sBAAsB;IACnC,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;CACrB;AAED,4CAA4C;AAC5C,MAAM,WAAW,mBAAmB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACrB;AAED,+DAA+D;AAC/D,MAAM,MAAM,kBAAkB,GAAG;IAC7B,kBAAkB,EAAE,CAAC,MAAM,EAAE,qBAAqB,KAAK,IAAI,CAAC;IAC5D,kBAAkB,EAAE,CAAC,MAAM,EAAE,qBAAqB,KAAK,IAAI,CAAC;IAC5D,mBAAmB,EAAE,CAAC,MAAM,EAAE,sBAAsB,KAAK,IAAI,CAAC;IAC9D,gBAAgB,EAAE,CAAC,MAAM,EAAE,mBAAmB,KAAK,IAAI,CAAC;CAC3D,CAAC;AAEF;;;;GAIG;AACH,MAAM,WAAW,qBAAqB;IAClC,IAAI,CAAC,CAAC,SAAS,MAAM,kBAAkB,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,UAAU,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;CACxG;AAED,yCAAyC;AACzC,MAAM,WAAW,sBAAsB;IACnC,0EAA0E;IAC1E,MAAM,CAAC,EAAE,qBAAqB,CAAC;CAClC;AAcD;;GAEG;AACH,qBAAa,eAAgB,SAAQ,SAAS,CAAC,OAAO,aAAa,EAAE,OAAO,aAAa,CAAC,EAAE,CAAC;IACzF,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAwB;gBAEpC,OAAO,EAAE,SAAS,EAAE,OAAO,GAAE,sBAA2B;IAK9D,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAwB/F,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"inbox-message-dao.d.ts","sourceRoot":"","sources":["../src/inbox-message-dao.ts"],"names":[],"mappings":"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"}
|
|
@@ -41,7 +41,13 @@ export class InboxMessageDao extends EntityDao {
|
|
|
41
41
|
});
|
|
42
42
|
return id;
|
|
43
43
|
}
|
|
44
|
-
async drainPending(toId) {
|
|
44
|
+
async drainPending(toId, options) {
|
|
45
|
+
// A backed-up inbox is claimed in pages of at most `limit` (default 100) so one
|
|
46
|
+
// recipient's queue cannot be monopolised by a single drain (task 0060 F10).
|
|
47
|
+
const limit = options?.limit ?? 100;
|
|
48
|
+
if (!Number.isInteger(limit) || limit <= 0) {
|
|
49
|
+
throw new RangeError(`drainPending limit must be a positive integer; received ${limit}`);
|
|
50
|
+
}
|
|
45
51
|
const now = this.now();
|
|
46
52
|
const rows = (await this.db
|
|
47
53
|
.update(inboxMessages)
|
|
@@ -56,6 +62,7 @@ export class InboxMessageDao extends EntityDao {
|
|
|
56
62
|
WHERE to_id = ${toId}
|
|
57
63
|
AND status = 'queued'
|
|
58
64
|
ORDER BY created_at
|
|
65
|
+
LIMIT ${limit}
|
|
59
66
|
)
|
|
60
67
|
AND ${inboxMessages.status} = 'queued'`)
|
|
61
68
|
.returning());
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
export { createDbAdapter, type DbAdapter, type DbAdapterConfig, type DbBatchOp, type InternalDb } from './adapter';
|
|
2
|
-
export { D1Adapter } from './adapters/d1';
|
|
3
2
|
export { BaseDao, type TxHandle } from './base-dao';
|
|
4
3
|
export { type EmbeddedMigration, embeddedMigrations } from './embedded-migrations';
|
|
5
4
|
export { type CursorListSpec, type DaoValidator, EntityDao, type EntityDaoOptions, type EntityListSpec, type EntityTable, type PKColumn, type PKValue, type SoftDeletableTable, } from './entity-dao';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,KAAK,SAAS,EAAE,KAAK,eAAe,EAAE,KAAK,SAAS,EAAE,KAAK,UAAU,EAAE,MAAM,WAAW,CAAC;AACnH,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,KAAK,SAAS,EAAE,KAAK,eAAe,EAAE,KAAK,SAAS,EAAE,KAAK,UAAU,EAAE,MAAM,WAAW,CAAC;AACnH,OAAO,EAAE,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEpD,OAAO,EAAE,KAAK,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AACnF,OAAO,EACH,KAAK,cAAc,EACnB,KAAK,YAAY,EACjB,SAAS,EACT,KAAK,gBAAgB,EACrB,KAAK,cAAc,EACnB,KAAK,WAAW,EAChB,KAAK,QAAQ,EACb,KAAK,OAAO,EACZ,KAAK,kBAAkB,GAC1B,MAAM,cAAc,CAAC;AACtB,OAAO,EACH,KAAK,sBAAsB,EAC3B,KAAK,qBAAqB,EAC1B,KAAK,mBAAmB,EACxB,KAAK,YAAY,EACjB,eAAe,EACf,KAAK,sBAAsB,EAC3B,KAAK,qBAAqB,EAC1B,KAAK,kBAAkB,EACvB,KAAK,qBAAqB,GAC7B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,eAAe,EAAE,KAAK,eAAe,EAAE,KAAK,gBAAgB,EAAE,MAAM,WAAW,CAAC;AACzF,OAAO,EACH,KAAK,MAAM,EACX,KAAK,YAAY,EACjB,cAAc,EACd,gBAAgB,EAChB,KAAK,QAAQ,EACb,KAAK,SAAS,EACd,KAAK,SAAS,GACjB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,WAAW,EAAE,KAAK,cAAc,EAAE,KAAK,UAAU,EAAE,MAAM,iBAAiB,CAAC;AACpF,YAAY,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -12,11 +12,8 @@ import type { ZodType } from 'zod';
|
|
|
12
12
|
* time they are read — so a consumer that only needs the table pays nothing
|
|
13
13
|
* extra.
|
|
14
14
|
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
* don't need generated DDL can use `createDbAdapter` + raw `sqliteTable` +
|
|
18
|
-
* column helpers without installing those peers. Import from
|
|
19
|
-
* `@gobing-ai/ts-db/schema` to opt in.
|
|
15
|
+
* The `/schema` subpath requires the optional peers `zod` and `drizzle-zod`.
|
|
16
|
+
* Consumers using only the main facade do not need them.
|
|
20
17
|
*/
|
|
21
18
|
export interface DefinedTable<TTable> {
|
|
22
19
|
/** The underlying drizzle table — pass to DAOs, migrations, queries. */
|
|
@@ -33,7 +30,7 @@ export interface DefinedTable<TTable> {
|
|
|
33
30
|
*
|
|
34
31
|
* @example
|
|
35
32
|
* ```ts
|
|
36
|
-
* import { defineTable } from '@gobing-ai/ts-db/schema';
|
|
33
|
+
* import { defineTable, standardColumns, text } from '@gobing-ai/ts-db/schema';
|
|
37
34
|
*
|
|
38
35
|
* export const users = defineTable('users', {
|
|
39
36
|
* id: text('id').primaryKey(),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"define-table.d.ts","sourceRoot":"","sources":["../../src/schema/define-table.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,uBAAuB,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAEpF,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC;AAGnC
|
|
1
|
+
{"version":3,"file":"define-table.d.ts","sourceRoot":"","sources":["../../src/schema/define-table.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,uBAAuB,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAEpF,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC;AAGnC;;;;;;;;;;;;;;GAcG;AACH,MAAM,WAAW,YAAY,CAAC,MAAM;IAChC,wEAAwE;IACxE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,iDAAiD;IACjD,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC;IAC/B,4CAA4C;IAC5C,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC;IAC/B,mFAAmF;IACnF,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;CACnC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,WAAW,CAAC,KAAK,SAAS,MAAM,EAAE,QAAQ,SAAS,MAAM,CAAC,MAAM,EAAE,uBAAuB,CAAC,EACtG,IAAI,EAAE,KAAK,EACX,OAAO,EAAE,QAAQ,GAClB,YAAY,CAAC,UAAU,CAAC,OAAO,WAAW,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,CA4B/D"}
|
|
@@ -6,7 +6,7 @@ import { generateCreateTableSql } from './ddl.js';
|
|
|
6
6
|
*
|
|
7
7
|
* @example
|
|
8
8
|
* ```ts
|
|
9
|
-
* import { defineTable } from '@gobing-ai/ts-db/schema';
|
|
9
|
+
* import { defineTable, standardColumns, text } from '@gobing-ai/ts-db/schema';
|
|
10
10
|
*
|
|
11
11
|
* export const users = defineTable('users', {
|
|
12
12
|
* id: text('id').primaryKey(),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gobing-ai/ts-db",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.30",
|
|
4
4
|
"description": "@gobing-ai/ts-db — a drizzle-free database facade: typed DAOs over Bun SQLite / Cloudflare D1, a small predicate query spec, single-source-of-truth tables, and migrations. Drizzle stays an internal detail.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"typescript",
|
|
@@ -66,8 +66,8 @@
|
|
|
66
66
|
"release": "echo 'Manual publish is disabled. Releases go through GitHub Actions via Trusted Publishing — push a tag: git tag @gobing-ai/ts-db-v<version> && git push --tags' && exit 1"
|
|
67
67
|
},
|
|
68
68
|
"dependencies": {
|
|
69
|
-
"@gobing-ai/ts-runtime": "^0.4.
|
|
70
|
-
"@gobing-ai/ts-utils": "^0.4.
|
|
69
|
+
"@gobing-ai/ts-runtime": "^0.4.30",
|
|
70
|
+
"@gobing-ai/ts-utils": "^0.4.30"
|
|
71
71
|
},
|
|
72
72
|
"peerDependencies": {
|
|
73
73
|
"drizzle-orm": ">=0.38.0",
|
package/src/inbox-message-dao.ts
CHANGED
|
@@ -118,7 +118,13 @@ export class InboxMessageDao extends EntityDao<typeof inboxMessages, typeof inbo
|
|
|
118
118
|
return id;
|
|
119
119
|
}
|
|
120
120
|
|
|
121
|
-
async drainPending(toId: string): Promise<InboxMessage[]> {
|
|
121
|
+
async drainPending(toId: string, options?: { limit?: number }): Promise<InboxMessage[]> {
|
|
122
|
+
// A backed-up inbox is claimed in pages of at most `limit` (default 100) so one
|
|
123
|
+
// recipient's queue cannot be monopolised by a single drain (task 0060 F10).
|
|
124
|
+
const limit = options?.limit ?? 100;
|
|
125
|
+
if (!Number.isInteger(limit) || limit <= 0) {
|
|
126
|
+
throw new RangeError(`drainPending limit must be a positive integer; received ${limit}`);
|
|
127
|
+
}
|
|
122
128
|
const now = this.now();
|
|
123
129
|
const rows = (await (this.db as UpdateReturningDb)
|
|
124
130
|
.update(inboxMessages)
|
|
@@ -134,6 +140,7 @@ export class InboxMessageDao extends EntityDao<typeof inboxMessages, typeof inbo
|
|
|
134
140
|
WHERE to_id = ${toId}
|
|
135
141
|
AND status = 'queued'
|
|
136
142
|
ORDER BY created_at
|
|
143
|
+
LIMIT ${limit}
|
|
137
144
|
)
|
|
138
145
|
AND ${inboxMessages.status} = 'queued'`,
|
|
139
146
|
)
|
package/src/index.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
export { createDbAdapter, type DbAdapter, type DbAdapterConfig, type DbBatchOp, type InternalDb } from './adapter';
|
|
2
|
-
export { D1Adapter } from './adapters/d1';
|
|
3
2
|
export { BaseDao, type TxHandle } from './base-dao';
|
|
4
3
|
|
|
5
4
|
export { type EmbeddedMigration, embeddedMigrations } from './embedded-migrations';
|
|
@@ -15,11 +15,8 @@ import { generateCreateTableSql } from './ddl';
|
|
|
15
15
|
* time they are read — so a consumer that only needs the table pays nothing
|
|
16
16
|
* extra.
|
|
17
17
|
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
* don't need generated DDL can use `createDbAdapter` + raw `sqliteTable` +
|
|
21
|
-
* column helpers without installing those peers. Import from
|
|
22
|
-
* `@gobing-ai/ts-db/schema` to opt in.
|
|
18
|
+
* The `/schema` subpath requires the optional peers `zod` and `drizzle-zod`.
|
|
19
|
+
* Consumers using only the main facade do not need them.
|
|
23
20
|
*/
|
|
24
21
|
export interface DefinedTable<TTable> {
|
|
25
22
|
/** The underlying drizzle table — pass to DAOs, migrations, queries. */
|
|
@@ -37,7 +34,7 @@ export interface DefinedTable<TTable> {
|
|
|
37
34
|
*
|
|
38
35
|
* @example
|
|
39
36
|
* ```ts
|
|
40
|
-
* import { defineTable } from '@gobing-ai/ts-db/schema';
|
|
37
|
+
* import { defineTable, standardColumns, text } from '@gobing-ai/ts-db/schema';
|
|
41
38
|
*
|
|
42
39
|
* export const users = defineTable('users', {
|
|
43
40
|
* id: text('id').primaryKey(),
|