@o/database 0.16.11

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Nate Weinert
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,18 @@
1
+ # @o/database
2
+
3
+ SQLite database helpers for Orez hosts.
4
+
5
+ - `@o/database/sqlite`: `createSQLiteDatabase` builds typed Drizzle inside a
6
+ transaction the host owns (a Durable Object session, a native SQLite
7
+ connection). The host decides what a session is; Drizzle never emits BEGIN
8
+ or COMMIT. `createBunSQLiteTransactionProvider` is the Bun-native provider.
9
+ - `@o/database/better-auth`: `createBetterAuthSQLiteAdapter` gives Better
10
+ Auth its Drizzle adapter over the same host-owned transaction. Pass
11
+ `readTransactionProvider` so `findOne`, `findMany`, and `count` run on the
12
+ host's read lane instead of taking its writer turn.
13
+ - `@o/database/seed`: `applySeed` applies plain seed rows with
14
+ `INSERT ... ON CONFLICT DO NOTHING`; `SeedData` types them against a Drizzle
15
+ schema.
16
+ - `privateTable` marks a Drizzle table as excluded from Zero replication.
17
+
18
+ Moved here from `@take-out/database`, which keeps the Postgres helpers.
@@ -0,0 +1,19 @@
1
+ import { drizzleAdapter, type DrizzleAdapterConfig } from 'better-auth/adapters/drizzle';
2
+ import { type CreateSQLiteDatabaseOptions, type SQLiteSchema, type SQLiteTransactionProvider } from './sqlite';
3
+ import type { AnyRelations, EmptyRelations } from 'drizzle-orm';
4
+ export type CreateBetterAuthSQLiteAdapterOptions<TSchema extends SQLiteSchema, TRelations extends AnyRelations = EmptyRelations> = Pick<CreateSQLiteDatabaseOptions<TSchema, TRelations>, 'relations' | 'schema' | 'transactionProvider'> & {
5
+ /**
6
+ * runs the adapter's read-only operations (`findOne`, `findMany`, `count`).
7
+ * the SQLite host decides what a read session means; on a host that admits
8
+ * one writer at a time and readers together, a session lookup no longer
9
+ * waits for the writer turn. defaults to `transactionProvider`.
10
+ */
11
+ readTransactionProvider?: SQLiteTransactionProvider;
12
+ } & Omit<DrizzleAdapterConfig, 'provider' | 'schema' | 'transaction'>;
13
+ /**
14
+ * gives Better Auth its official Drizzle adapter inside the transaction
15
+ * callback owned by the SQLite host. the Drizzle adapter's transaction mode
16
+ * stays disabled because it must never emit its own BEGIN or COMMIT.
17
+ */
18
+ export declare function createBetterAuthSQLiteAdapter<TSchema extends SQLiteSchema, TRelations extends AnyRelations = EmptyRelations>(options: CreateBetterAuthSQLiteAdapterOptions<TSchema, TRelations>): ReturnType<typeof drizzleAdapter>;
19
+ //# sourceMappingURL=better-auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"better-auth.d.ts","sourceRoot":"","sources":["../src/better-auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,KAAK,oBAAoB,EAAE,MAAM,8BAA8B,CAAA;AAExF,OAAO,EAEL,KAAK,2BAA2B,EAChC,KAAK,YAAY,EAEjB,KAAK,yBAAyB,EAC/B,MAAM,UAAU,CAAA;AAEjB,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAE/D,MAAM,MAAM,oCAAoC,CAC9C,OAAO,SAAS,YAAY,EAC5B,UAAU,SAAS,YAAY,GAAG,cAAc,IAC9C,IAAI,CACN,2BAA2B,CAAC,OAAO,EAAE,UAAU,CAAC,EAChD,WAAW,GAAG,QAAQ,GAAG,qBAAqB,CAC/C,GAAG;IACF;;;;;OAKG;IACH,uBAAuB,CAAC,EAAE,yBAAyB,CAAA;CACpD,GAAG,IAAI,CAAC,oBAAoB,EAAE,UAAU,GAAG,QAAQ,GAAG,aAAa,CAAC,CAAA;AAMrE;;;;GAIG;AACH,wBAAgB,6BAA6B,CAC3C,OAAO,SAAS,YAAY,EAC5B,UAAU,SAAS,YAAY,GAAG,cAAc,EAEhD,OAAO,EAAE,oCAAoC,CAAC,OAAO,EAAE,UAAU,CAAC,GACjE,UAAU,CAAC,OAAO,cAAc,CAAC,CAgEnC"}
@@ -0,0 +1,56 @@
1
+ import { drizzleAdapter } from 'better-auth/adapters/drizzle';
2
+ import { createSQLiteDrizzle, } from './sqlite';
3
+ // the adapter operations that only SELECT. every other operation, and the
4
+ // explicit `transaction`, keeps the write provider.
5
+ const READ_OPERATIONS = new Set(['findOne', 'findMany', 'count']);
6
+ /**
7
+ * gives Better Auth its official Drizzle adapter inside the transaction
8
+ * callback owned by the SQLite host. the Drizzle adapter's transaction mode
9
+ * stays disabled because it must never emit its own BEGIN or COMMIT.
10
+ */
11
+ export function createBetterAuthSQLiteAdapter(options) {
12
+ const { relations, schema, transactionProvider, readTransactionProvider = transactionProvider, ...drizzleOptions } = options;
13
+ const adapterConfig = {
14
+ ...drizzleOptions,
15
+ provider: 'sqlite',
16
+ schema,
17
+ transaction: false,
18
+ };
19
+ const createAdapter = (executor, authOptions) => drizzleAdapter(createSQLiteDrizzle(executor, { relations, schema }), adapterConfig)(authOptions);
20
+ return (authOptions) => {
21
+ const unavailableExecutor = {
22
+ exec() {
23
+ throw new Error('Better Auth SQLite operations require a transaction callback');
24
+ },
25
+ query() {
26
+ throw new Error('Better Auth SQLite operations require a transaction callback');
27
+ },
28
+ queryAst() {
29
+ throw new Error('Better Auth SQLite operations require a transaction callback');
30
+ },
31
+ };
32
+ const target = createAdapter(unavailableExecutor, authOptions);
33
+ const transaction = (work) => transactionProvider(async (executor) => work(createAdapter(executor, authOptions)));
34
+ return new Proxy(target, {
35
+ get(_target, property, receiver) {
36
+ if (property === 'transaction')
37
+ return transaction;
38
+ const value = Reflect.get(target, property, receiver);
39
+ if (typeof value !== 'function')
40
+ return value;
41
+ const provider = typeof property === 'string' && READ_OPERATIONS.has(property)
42
+ ? readTransactionProvider
43
+ : transactionProvider;
44
+ return (...args) => provider(async (executor) => {
45
+ const adapter = createAdapter(executor, authOptions);
46
+ const operation = Reflect.get(adapter, property);
47
+ if (typeof operation !== 'function') {
48
+ throw new TypeError(`Better Auth adapter operation ${String(property)} is unavailable`);
49
+ }
50
+ return Reflect.apply(operation, adapter, args);
51
+ });
52
+ },
53
+ });
54
+ };
55
+ }
56
+ //# sourceMappingURL=better-auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"better-auth.js","sourceRoot":"","sources":["../src/better-auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAA6B,MAAM,8BAA8B,CAAA;AAExF,OAAO,EACL,mBAAmB,GAKpB,MAAM,UAAU,CAAA;AAoBjB,0EAA0E;AAC1E,oDAAoD;AACpD,MAAM,eAAe,GAAwB,IAAI,GAAG,CAAC,CAAC,SAAS,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC,CAAA;AAEtF;;;;GAIG;AACH,MAAM,UAAU,6BAA6B,CAI3C,OAAkE;IAElE,MAAM,EACJ,SAAS,EACT,MAAM,EACN,mBAAmB,EACnB,uBAAuB,GAAG,mBAAmB,EAC7C,GAAG,cAAc,EAClB,GAAG,OAAO,CAAA;IACX,MAAM,aAAa,GAAG;QACpB,GAAG,cAAc;QACjB,QAAQ,EAAE,QAAQ;QAClB,MAAM;QACN,WAAW,EAAE,KAAK;KACY,CAAA;IAChC,MAAM,aAAa,GAAG,CACpB,QAAmC,EACnC,WAA6D,EAC7D,EAAE,CACF,cAAc,CACZ,mBAAmB,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC,EACpD,aAAa,CACd,CAAC,WAAW,CAAC,CAAA;IAEhB,OAAO,CAAC,WAAW,EAAE,EAAE;QACrB,MAAM,mBAAmB,GAA8B;YACrD,IAAI;gBACF,MAAM,IAAI,KAAK,CAAC,8DAA8D,CAAC,CAAA;YACjF,CAAC;YACD,KAAK;gBACH,MAAM,IAAI,KAAK,CAAC,8DAA8D,CAAC,CAAA;YACjF,CAAC;YACD,QAAQ;gBACN,MAAM,IAAI,KAAK,CAAC,8DAA8D,CAAC,CAAA;YACjF,CAAC;SACF,CAAA;QACD,MAAM,MAAM,GAAG,aAAa,CAAC,mBAAmB,EAAE,WAAW,CAAC,CAAA;QAC9D,MAAM,WAAW,GAA8B,CAAC,IAAI,EAAE,EAAE,CACtD,mBAAmB,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC,CAAC,CAAA;QAErF,OAAO,IAAI,KAAK,CAAC,MAAM,EAAE;YACvB,GAAG,CAAC,OAAO,EAAE,QAAQ,EAAE,QAAQ;gBAC7B,IAAI,QAAQ,KAAK,aAAa;oBAAE,OAAO,WAAW,CAAA;gBAElD,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAA;gBACrD,IAAI,OAAO,KAAK,KAAK,UAAU;oBAAE,OAAO,KAAK,CAAA;gBAE7C,MAAM,QAAQ,GACZ,OAAO,QAAQ,KAAK,QAAQ,IAAI,eAAe,CAAC,GAAG,CAAC,QAAQ,CAAC;oBAC3D,CAAC,CAAC,uBAAuB;oBACzB,CAAC,CAAC,mBAAmB,CAAA;gBACzB,OAAO,CAAC,GAAG,IAAe,EAAE,EAAE,CAC5B,QAAQ,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE;oBAC1B,MAAM,OAAO,GAAG,aAAa,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAA;oBACpD,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAA;oBAChD,IAAI,OAAO,SAAS,KAAK,UAAU,EAAE,CAAC;wBACpC,MAAM,IAAI,SAAS,CACjB,iCAAiC,MAAM,CAAC,QAAQ,CAAC,iBAAiB,CACnE,CAAA;oBACH,CAAC;oBACD,OAAO,OAAO,CAAC,KAAK,CAAC,SAAS,EAAE,OAAO,EAAE,IAAI,CAAC,CAAA;gBAChD,CAAC,CAAC,CAAA;YACN,CAAC;SACF,CAAC,CAAA;IACJ,CAAC,CAAA;AACH,CAAC"}
@@ -0,0 +1,5 @@
1
+ export { createBetterAuthSQLiteAdapter, type CreateBetterAuthSQLiteAdapterOptions, } from './better-auth';
2
+ export { isPrivateTable, privateTable } from './private-table';
3
+ export { applySeed, type SeedClient, type SeedData, type SeedRows } from './seed';
4
+ export { createBunSQLiteExecutor, createBunSQLiteTransactionProvider, createSQLiteDatabase, createSQLiteDrizzle, type CreateBunSQLiteExecutorOptions, type CreateBunSQLiteTransactionProviderOptions, type CreateSQLiteDatabaseOptions, type SQLiteDatabase, type SQLiteDatabaseTransaction, type SQLiteExecResult, type SQLiteQueryFormat, type SQLiteSchema, type SQLiteTransactionExecutor, type SQLiteTransactionProvider, type SqlStatementMetadata, } from './sqlite';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,6BAA6B,EAC7B,KAAK,oCAAoC,GAC1C,MAAM,eAAe,CAAA;AACtB,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAC9D,OAAO,EAAE,SAAS,EAAE,KAAK,UAAU,EAAE,KAAK,QAAQ,EAAE,KAAK,QAAQ,EAAE,MAAM,QAAQ,CAAA;AACjF,OAAO,EACL,uBAAuB,EACvB,kCAAkC,EAClC,oBAAoB,EACpB,mBAAmB,EACnB,KAAK,8BAA8B,EACnC,KAAK,yCAAyC,EAC9C,KAAK,2BAA2B,EAChC,KAAK,cAAc,EACnB,KAAK,yBAAyB,EAC9B,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,EACtB,KAAK,YAAY,EACjB,KAAK,yBAAyB,EAC9B,KAAK,yBAAyB,EAC9B,KAAK,oBAAoB,GAC1B,MAAM,UAAU,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,5 @@
1
+ export { createBetterAuthSQLiteAdapter, } from './better-auth';
2
+ export { isPrivateTable, privateTable } from './private-table';
3
+ export { applySeed } from './seed';
4
+ export { createBunSQLiteExecutor, createBunSQLiteTransactionProvider, createSQLiteDatabase, createSQLiteDrizzle, } from './sqlite';
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,6BAA6B,GAE9B,MAAM,eAAe,CAAA;AACtB,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAC9D,OAAO,EAAE,SAAS,EAAiD,MAAM,QAAQ,CAAA;AACjF,OAAO,EACL,uBAAuB,EACvB,kCAAkC,EAClC,oBAAoB,EACpB,mBAAmB,GAYpB,MAAM,UAAU,CAAA"}
@@ -0,0 +1,3 @@
1
+ export declare function privateTable<T extends (...args: any[]) => any>(createTable: T): T;
2
+ export declare function isPrivateTable(table: unknown): boolean;
3
+ //# sourceMappingURL=private-table.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"private-table.d.ts","sourceRoot":"","sources":["../src/private-table.ts"],"names":[],"mappings":"AAKA,wBAAgB,YAAY,CAAC,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,EAAE,WAAW,EAAE,CAAC,GAAG,CAAC,CAMjF;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAEtD"}
@@ -0,0 +1,15 @@
1
+ // marks a Drizzle table as private: it stays out of Zero replication. the
2
+ // symbol key is shared with @take-out/database so a table marked by either
3
+ // package reads as private to the other while consumers migrate.
4
+ const PRIVATE = Symbol.for('take-out/database/private');
5
+ export function privateTable(createTable) {
6
+ return ((...args) => {
7
+ const table = createTable(...args);
8
+ table[PRIVATE] = true;
9
+ return table;
10
+ });
11
+ }
12
+ export function isPrivateTable(table) {
13
+ return !!(table && typeof table === 'object' && PRIVATE in table);
14
+ }
15
+ //# sourceMappingURL=private-table.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"private-table.js","sourceRoot":"","sources":["../src/private-table.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,2EAA2E;AAC3E,iEAAiE;AACjE,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAA;AAEvD,MAAM,UAAU,YAAY,CAAoC,WAAc;IAC5E,OAAO,CAAC,CAAC,GAAG,IAAW,EAAE,EAAE;QACzB,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,IAAI,CAAC,CACjC;QAAC,KAAa,CAAC,OAAO,CAAC,GAAG,IAAI,CAAA;QAC/B,OAAO,KAAK,CAAA;IACd,CAAC,CAAiB,CAAA;AACpB,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,KAAc;IAC3C,OAAO,CAAC,CAAC,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,IAAI,KAAK,CAAC,CAAA;AACnE,CAAC"}
package/dist/seed.d.ts ADDED
@@ -0,0 +1,10 @@
1
+ import type { InferInsertModel, Table } from 'drizzle-orm';
2
+ export type SeedRows = Record<string, Array<Record<string, unknown>>>;
3
+ export type SeedData<TSchema> = {
4
+ [K in keyof TSchema as TSchema[K] extends Table ? K : never]?: Array<InferInsertModel<Extract<TSchema[K], Table>>>;
5
+ };
6
+ export interface SeedClient {
7
+ query(sql: string, params?: unknown[]): Promise<unknown>;
8
+ }
9
+ export declare function applySeed(client: SeedClient, rows: SeedRows): Promise<void>;
10
+ //# sourceMappingURL=seed.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"seed.d.ts","sourceRoot":"","sources":["../src/seed.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,gBAAgB,EAAE,KAAK,EAAE,MAAM,aAAa,CAAA;AAG1D,MAAM,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,CAAA;AAKrE,MAAM,MAAM,QAAQ,CAAC,OAAO,IAAI;KAC7B,CAAC,IAAI,MAAM,OAAO,IAAI,OAAO,CAAC,CAAC,CAAC,SAAS,KAAK,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC,EAAE,KAAK,CAClE,gBAAgB,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAC7C;CACF,CAAA;AAID,MAAM,WAAW,UAAU;IACzB,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;CACzD;AAQD,wBAAsB,SAAS,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAajF"}
package/dist/seed.js ADDED
@@ -0,0 +1,22 @@
1
+ // standardized demo/world seed applier — the one mechanism every runtime uses
2
+ // to apply a project's database/seed.ts rows after migrations: pg via the
3
+ // --seed flag on database/migrate.ts, and the browser preview worker (PGlite)
4
+ // at cold boot. same rows, same insert semantics, only the client differs.
5
+ const quote = (id) => `"${id.replaceAll('"', '""')}"`;
6
+ // INSERT ... ON CONFLICT DO NOTHING per row, tables in key order. idempotent
7
+ // by construction: deterministic seed ids make re-application a no-op and a
8
+ // grown seed set back-fills only the missing rows. undefined columns are
9
+ // omitted so they fall to the DB default.
10
+ export async function applySeed(client, rows) {
11
+ for (const [table, tableRows] of Object.entries(rows)) {
12
+ for (const row of tableRows) {
13
+ const columns = Object.keys(row).filter((key) => row[key] !== undefined);
14
+ if (columns.length === 0)
15
+ continue;
16
+ const values = columns.map((key) => row[key]);
17
+ const placeholders = columns.map((_, i) => `$${i + 1}`).join(', ');
18
+ await client.query(`INSERT INTO ${quote(table)} (${columns.map(quote).join(', ')}) VALUES (${placeholders}) ON CONFLICT DO NOTHING`, values);
19
+ }
20
+ }
21
+ }
22
+ //# sourceMappingURL=seed.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"seed.js","sourceRoot":"","sources":["../src/seed.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,0EAA0E;AAC1E,8EAA8E;AAC9E,2EAA2E;AAsB3E,MAAM,KAAK,GAAG,CAAC,EAAU,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAA;AAE7D,6EAA6E;AAC7E,4EAA4E;AAC5E,yEAAyE;AACzE,0CAA0C;AAC1C,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,MAAkB,EAAE,IAAc;IAChE,KAAK,MAAM,CAAC,KAAK,EAAE,SAAS,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QACtD,KAAK,MAAM,GAAG,IAAI,SAAS,EAAE,CAAC;YAC5B,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,SAAS,CAAC,CAAA;YACxE,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;gBAAE,SAAQ;YAClC,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAA;YAC7C,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;YAClE,MAAM,MAAM,CAAC,KAAK,CAChB,eAAe,KAAK,CAAC,KAAK,CAAC,KAAK,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,YAAY,0BAA0B,EAChH,MAAM,CACP,CAAA;QACH,CAAC;IACH,CAAC;AACH,CAAC"}
@@ -0,0 +1,55 @@
1
+ import { type SqliteRemoteDatabase } from 'drizzle-orm/sqlite-proxy';
2
+ import type { Database } from 'bun:sqlite';
3
+ import type { AnyRelations, EmptyRelations } from 'drizzle-orm';
4
+ import type { SQLiteTable } from 'drizzle-orm/sqlite-core';
5
+ export type SqlStatementMetadata = {
6
+ table: string;
7
+ publicTable: string;
8
+ kind: 'delete' | 'insert' | 'update' | 'upsert';
9
+ };
10
+ export type SQLiteQueryFormat = {
11
+ relationships: Record<string, SQLiteQueryFormat>;
12
+ singular: boolean;
13
+ };
14
+ export type SQLiteExecResult = {
15
+ changes: number;
16
+ };
17
+ export type SQLiteTransactionExecutor = {
18
+ exec(sql: string, params?: readonly unknown[], metadata?: SqlStatementMetadata): SQLiteExecResult | Promise<SQLiteExecResult>;
19
+ query<Row extends Record<string, unknown> = Record<string, unknown>>(sql: string, params?: readonly unknown[]): Row[] | Promise<Row[]>;
20
+ queryAst<Result = unknown>(ast: unknown, format: SQLiteQueryFormat, queryName?: string): Result | Promise<Result>;
21
+ };
22
+ export type SQLiteTransactionProvider = <Value>(work: (executor: SQLiteTransactionExecutor) => Value | Promise<Value>) => Promise<Value>;
23
+ export type SQLiteSchema = Record<string, SQLiteTable>;
24
+ export type CreateSQLiteDatabaseOptions<TSchema extends SQLiteSchema, TRelations extends AnyRelations = EmptyRelations> = {
25
+ schema: TSchema;
26
+ relations?: TRelations;
27
+ transactionProvider: SQLiteTransactionProvider;
28
+ };
29
+ export type SQLiteDatabaseTransaction<TSchema extends SQLiteSchema, TRelations extends AnyRelations> = {
30
+ executor: SQLiteTransactionExecutor;
31
+ drizzle: SqliteRemoteDatabase<TSchema, TRelations>;
32
+ };
33
+ export type SQLiteDatabase<TSchema extends SQLiteSchema, TRelations extends AnyRelations> = {
34
+ transaction<Value>(work: (transaction: SQLiteDatabaseTransaction<TSchema, TRelations>) => Value | Promise<Value>): Promise<Value>;
35
+ };
36
+ /**
37
+ * Creates Drizzle only after the storage owner has started its transaction.
38
+ * The sqlite-proxy driver is used solely to turn its query callbacks into
39
+ * typed Drizzle operations; it never owns BEGIN or COMMIT.
40
+ */
41
+ export declare function createSQLiteDatabase<TSchema extends SQLiteSchema, TRelations extends AnyRelations = EmptyRelations>(options: CreateSQLiteDatabaseOptions<TSchema, TRelations>): SQLiteDatabase<TSchema, TRelations>;
42
+ export declare function createSQLiteDrizzle<TSchema extends SQLiteSchema, TRelations extends AnyRelations = EmptyRelations>(executor: SQLiteTransactionExecutor, options: Pick<CreateSQLiteDatabaseOptions<TSchema, TRelations>, 'relations' | 'schema'>): SqliteRemoteDatabase<TSchema, TRelations>;
43
+ export type CreateBunSQLiteExecutorOptions = {
44
+ database: Database;
45
+ queryAst<Result = unknown>(ast: unknown, format: SQLiteQueryFormat, queryName?: string): Result | Promise<Result>;
46
+ };
47
+ export declare function createBunSQLiteExecutor({ database, queryAst, }: CreateBunSQLiteExecutorOptions): SQLiteTransactionExecutor;
48
+ export type CreateBunSQLiteTransactionProviderOptions = CreateBunSQLiteExecutorOptions;
49
+ /**
50
+ * Bun's synchronous driver needs its own native transaction boundary. Remote
51
+ * and Durable Object hosts pass their protected callback directly to
52
+ * createSQLiteDatabase instead.
53
+ */
54
+ export declare function createBunSQLiteTransactionProvider({ database, queryAst, }: CreateBunSQLiteTransactionProviderOptions): SQLiteTransactionProvider;
55
+ //# sourceMappingURL=sqlite.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sqlite.d.ts","sourceRoot":"","sources":["../src/sqlite.ts"],"names":[],"mappings":"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"}
package/dist/sqlite.js ADDED
@@ -0,0 +1,105 @@
1
+ import { AsyncLocalStorage } from 'node:async_hooks';
2
+ import { drizzle } from 'drizzle-orm/sqlite-proxy';
3
+ /**
4
+ * Creates Drizzle only after the storage owner has started its transaction.
5
+ * The sqlite-proxy driver is used solely to turn its query callbacks into
6
+ * typed Drizzle operations; it never owns BEGIN or COMMIT.
7
+ */
8
+ export function createSQLiteDatabase(options) {
9
+ return {
10
+ transaction(work) {
11
+ return options.transactionProvider(async (executor) => work({
12
+ executor,
13
+ drizzle: createSQLiteDrizzle(executor, options),
14
+ }));
15
+ },
16
+ };
17
+ }
18
+ export function createSQLiteDrizzle(executor, options) {
19
+ return drizzle(async (sql, params, method) => {
20
+ if (method === 'run') {
21
+ const result = await executor.exec(sql, params);
22
+ return { changes: result.changes, rows: [] };
23
+ }
24
+ const rows = await executor.query(sql, params);
25
+ if (method === 'get') {
26
+ const row = rows[0];
27
+ return remoteRows(row ? rowValues(row) : undefined);
28
+ }
29
+ return remoteRows(rows.map(rowValues));
30
+ }, {
31
+ schema: options.schema,
32
+ relations: options.relations,
33
+ });
34
+ }
35
+ export function createBunSQLiteExecutor({ database, queryAst, }) {
36
+ return {
37
+ exec(sql, params = []) {
38
+ const result = database.prepare(sql).run(...bunBindings(params));
39
+ return { changes: result.changes };
40
+ },
41
+ query(sql, params = []) {
42
+ return database.prepare(sql).all(...bunBindings(params));
43
+ },
44
+ queryAst,
45
+ };
46
+ }
47
+ /**
48
+ * Bun's synchronous driver needs its own native transaction boundary. Remote
49
+ * and Durable Object hosts pass their protected callback directly to
50
+ * createSQLiteDatabase instead.
51
+ */
52
+ export function createBunSQLiteTransactionProvider({ database, queryAst, }) {
53
+ const executor = createBunSQLiteExecutor({ database, queryAst });
54
+ const transactionContext = new AsyncLocalStorage();
55
+ let tail = Promise.resolve();
56
+ return async (work) => {
57
+ if (transactionContext.getStore()) {
58
+ throw new Error('nested SQLite transactions are not supported');
59
+ }
60
+ // keep the native connection's transaction state exclusive across awaits.
61
+ const previous = tail;
62
+ let release;
63
+ tail = new Promise((resolve) => {
64
+ release = resolve;
65
+ });
66
+ await previous;
67
+ try {
68
+ return await transactionContext.run(true, async () => {
69
+ let began = false;
70
+ try {
71
+ database.exec('BEGIN');
72
+ began = true;
73
+ const value = await work(executor);
74
+ database.exec('COMMIT');
75
+ began = false;
76
+ return value;
77
+ }
78
+ catch (error) {
79
+ if (began)
80
+ database.exec('ROLLBACK');
81
+ throw error;
82
+ }
83
+ });
84
+ }
85
+ finally {
86
+ release();
87
+ }
88
+ };
89
+ }
90
+ function rowValues(row) {
91
+ return Object.values(row);
92
+ }
93
+ function remoteRows(rows) {
94
+ // Drizzle's sqlite-proxy declaration requires an array even though its get()
95
+ // implementation recognizes an absent row. Keep that transport mismatch at
96
+ // this one adapter boundary rather than turning a missing row into one full
97
+ // of undefined column values.
98
+ return { rows: rows };
99
+ }
100
+ function bunBindings(params) {
101
+ // on-zero accepts unknown bindings so every native provider can expose one
102
+ // structural contract. Bun validates these at its typed boundary.
103
+ return params;
104
+ }
105
+ //# sourceMappingURL=sqlite.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sqlite.js","sourceRoot":"","sources":["../src/sqlite.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,57 @@
1
+ {
2
+ "name": "@o/database",
3
+ "version": "0.16.11",
4
+ "description": "SQLite database helpers for Orez hosts: Drizzle over a host-owned transaction, a Better Auth adapter with read and write lanes, seed application, and private-table marking.",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "main": "dist/index.js",
8
+ "module": "dist/index.js",
9
+ "types": "./dist/index.d.ts",
10
+ "exports": {
11
+ "./package.json": "./package.json",
12
+ ".": {
13
+ "types": "./dist/index.d.ts",
14
+ "import": "./dist/index.js",
15
+ "default": "./dist/index.js"
16
+ },
17
+ "./sqlite": {
18
+ "types": "./dist/sqlite.d.ts",
19
+ "import": "./dist/sqlite.js",
20
+ "default": "./dist/sqlite.js"
21
+ },
22
+ "./better-auth": {
23
+ "types": "./dist/better-auth.d.ts",
24
+ "import": "./dist/better-auth.js",
25
+ "default": "./dist/better-auth.js"
26
+ },
27
+ "./seed": {
28
+ "types": "./dist/seed.d.ts",
29
+ "import": "./dist/seed.js",
30
+ "default": "./dist/seed.js"
31
+ }
32
+ },
33
+ "files": ["dist", "LICENSE", "README.md"],
34
+ "scripts": {
35
+ "build": "rm -rf dist && tsc -p tsconfig.build.json",
36
+ "format": "oxfmt",
37
+ "format:check": "oxfmt --check",
38
+ "lint": "oxlint src",
39
+ "test": "bun test src",
40
+ "typecheck": "tsc --noEmit -p tsconfig.json"
41
+ },
42
+ "peerDependencies": {
43
+ "better-auth": ">=1.6.0 <2",
44
+ "drizzle-orm": ">=1.0.0-beta.0 <2"
45
+ },
46
+ "devDependencies": {
47
+ "@types/bun": "1.3.14",
48
+ "better-auth": "1.6.30",
49
+ "drizzle-orm": "1.0.0-beta.9-e89174b",
50
+ "oxfmt": "0.28.0",
51
+ "oxlint": "1.43.0",
52
+ "typescript": "5.9.3"
53
+ },
54
+ "publishConfig": {
55
+ "access": "public"
56
+ }
57
+ }