@anabranch/db-postgres 0.1.5 → 0.1.7

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/esm/db/index.d.ts CHANGED
@@ -1,61 +1,81 @@
1
1
  /**
2
- * @abranch/db
2
+ * @anabranch/db
3
3
  *
4
4
  * Database primitives with Task/Stream semantics for error-tolerant async operations.
5
+ * Integrates with anabranch's {@link Task}, {@link Stream}, {@link Source}, and
6
+ * {@link Channel} types for composable error handling and concurrent processing.
5
7
  *
6
8
  * ## Adapters vs Connectors
7
9
  *
8
10
  * A **DBConnector** produces connected **DBAdapter** instances. Use connectors for
9
11
  * production code to properly manage connection lifecycles:
10
12
  *
13
+ * - **Connector**: Manages connection pool/lifecycle, produces adapters
14
+ * - **Adapter**: Low-level query/execute/close interface
15
+ * - **DB**: Wrapper providing Task/Stream semantics over an adapter
16
+ *
17
+ * ## Core Types
18
+ *
19
+ * - {@link DBConnector} - Interface for connection factories
20
+ * - {@link DBAdapter} - Low-level database operations interface
21
+ * - {@link DB} - High-level wrapper with Task/Stream methods
22
+ * - {@link DBTransaction} - Transaction scope with commit/rollback
23
+ *
24
+ * ## Error Types
25
+ *
26
+ * All errors are typed for catchable handling:
27
+ * - {@link ConnectionFailed} - Connection establishment failed
28
+ * - {@link QueryFailed} - Query execution error
29
+ * - {@link ConstraintViolation} - Constraint violation (UNIQUE, FOREIGN KEY, etc.)
30
+ * - {@link TransactionFailed} - Transaction error
31
+ *
32
+ * @example Basic query with Task semantics
11
33
  * ```ts
12
34
  * import { DB, createInMemory } from "@anabranch/db";
13
35
  *
14
- * // Idiomatic usage with connector (recommended)
15
- * const result = await DB.withConnection(createInMemory(), (db) =>
16
- * db.query("SELECT * FROM users")
36
+ * const users = await DB.withConnection(createInMemory(), (db) =>
37
+ * db.query("SELECT * FROM users WHERE active = ?", [true])
17
38
  * ).run();
18
- *
19
- * // Bare adapter for testing or custom lifecycle management
20
- * const adapter = await createInMemory().connect();
21
- * const db = new DB(adapter);
22
39
  * ```
23
40
  *
24
- * ## Usage
25
- *
41
+ * @example Streaming large result sets with error collection
26
42
  * ```ts
27
43
  * import { DB, createInMemory } from "@anabranch/db";
28
44
  *
29
- * // Using withConnection for automatic lifecycle management
30
- * await DB.withConnection(createInMemory(), async (db) => {
31
- * await db.execute("CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT)").run();
32
- * await db.execute("INSERT INTO users (name) VALUES (?)", ["Alice"]).run();
33
- * return db.query("SELECT * FROM users").run();
34
- * }).run();
45
+ * const { successes, errors } = await DB.withConnection(createInMemory(), (db) =>
46
+ * db.stream("SELECT * FROM large_table")
47
+ * .withConcurrency(10)
48
+ * .map(row => processRow(row))
49
+ * .partition()
50
+ * ).run();
51
+ * ```
35
52
  *
36
- * // Stream large result sets
37
- * const { successes, errors } = await db.stream("SELECT * FROM users")
38
- * .map(u => processUser(u))
39
- * .partition();
53
+ * @example Transactions with automatic rollback on error
54
+ * ```ts
55
+ * import { DB, ConstraintViolation, createInMemory } from "@anabranch/db";
40
56
  *
41
- * // Transactions with automatic rollback on error
42
57
  * const result = await DB.withConnection(createInMemory(), (db) =>
43
58
  * db.withTransaction(async (tx) => {
44
- * await tx.execute("INSERT INTO users (name) VALUES (?)", ["Bob"]).run();
45
- * return tx.query("SELECT last_insert_rowid()").run();
59
+ * await tx.execute("INSERT INTO orders (user_id) VALUES (?)", [userId]);
60
+ * await tx.execute("UPDATE users SET order_count = order_count + 1 WHERE id = ?", [userId]);
61
+ * return tx.query("SELECT last_insert_rowid()");
46
62
  * })
63
+ * ).recoverWhen(
64
+ * (e) => e instanceof ConstraintViolation,
65
+ * (e) => ({ id: 0, error: e.message })
47
66
  * ).run();
48
67
  * ```
49
68
  *
50
- * ## Error Types
51
- *
52
- * The following error types are exported for adapter implementors:
69
+ * @example Retry with exponential backoff
70
+ * ```ts
71
+ * import { DB, createPostgres } from "@anabranch/db";
72
+ * import { createPostgres } from "@anabranch/db-postgres";
53
73
  *
54
- * - {@link ConnectionFailed} - Throw from connector's `connect()` on failure
55
- * - {@link CloseError} - Throw from adapter's `close()` on failure
56
- * - {@link QueryFailed} - Thrown for query execution errors
57
- * - {@link ConstraintViolation} - Thrown for constraint violations (e.g., UNIQUE, FOREIGN KEY)
58
- * - {@link TransactionFailed} - Thrown for transaction errors
74
+ * const users = await DB.withConnection(createPostgres(), (db) =>
75
+ * db.query("SELECT * FROM users")
76
+ * .retry({ attempts: 3, delay: (attempt) => 100 * Math.pow(2, attempt) })
77
+ * ).run();
78
+ * ```
59
79
  *
60
80
  * @module
61
81
  */
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/db/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4DG;AACH,OAAO,EAAE,EAAE,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC5C,YAAY,EACV,SAAS,EACT,WAAW,EACX,oBAAoB,GACrB,MAAM,cAAc,CAAC;AACtB,cAAc,aAAa,CAAC;AAC5B,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/db/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgFG;AACH,OAAO,EAAE,EAAE,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC5C,YAAY,EACV,SAAS,EACT,WAAW,EACX,oBAAoB,GACrB,MAAM,cAAc,CAAC;AACtB,cAAc,aAAa,CAAC;AAC5B,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC"}
package/esm/db/index.js CHANGED
@@ -1,61 +1,81 @@
1
1
  /**
2
- * @abranch/db
2
+ * @anabranch/db
3
3
  *
4
4
  * Database primitives with Task/Stream semantics for error-tolerant async operations.
5
+ * Integrates with anabranch's {@link Task}, {@link Stream}, {@link Source}, and
6
+ * {@link Channel} types for composable error handling and concurrent processing.
5
7
  *
6
8
  * ## Adapters vs Connectors
7
9
  *
8
10
  * A **DBConnector** produces connected **DBAdapter** instances. Use connectors for
9
11
  * production code to properly manage connection lifecycles:
10
12
  *
13
+ * - **Connector**: Manages connection pool/lifecycle, produces adapters
14
+ * - **Adapter**: Low-level query/execute/close interface
15
+ * - **DB**: Wrapper providing Task/Stream semantics over an adapter
16
+ *
17
+ * ## Core Types
18
+ *
19
+ * - {@link DBConnector} - Interface for connection factories
20
+ * - {@link DBAdapter} - Low-level database operations interface
21
+ * - {@link DB} - High-level wrapper with Task/Stream methods
22
+ * - {@link DBTransaction} - Transaction scope with commit/rollback
23
+ *
24
+ * ## Error Types
25
+ *
26
+ * All errors are typed for catchable handling:
27
+ * - {@link ConnectionFailed} - Connection establishment failed
28
+ * - {@link QueryFailed} - Query execution error
29
+ * - {@link ConstraintViolation} - Constraint violation (UNIQUE, FOREIGN KEY, etc.)
30
+ * - {@link TransactionFailed} - Transaction error
31
+ *
32
+ * @example Basic query with Task semantics
11
33
  * ```ts
12
34
  * import { DB, createInMemory } from "@anabranch/db";
13
35
  *
14
- * // Idiomatic usage with connector (recommended)
15
- * const result = await DB.withConnection(createInMemory(), (db) =>
16
- * db.query("SELECT * FROM users")
36
+ * const users = await DB.withConnection(createInMemory(), (db) =>
37
+ * db.query("SELECT * FROM users WHERE active = ?", [true])
17
38
  * ).run();
18
- *
19
- * // Bare adapter for testing or custom lifecycle management
20
- * const adapter = await createInMemory().connect();
21
- * const db = new DB(adapter);
22
39
  * ```
23
40
  *
24
- * ## Usage
25
- *
41
+ * @example Streaming large result sets with error collection
26
42
  * ```ts
27
43
  * import { DB, createInMemory } from "@anabranch/db";
28
44
  *
29
- * // Using withConnection for automatic lifecycle management
30
- * await DB.withConnection(createInMemory(), async (db) => {
31
- * await db.execute("CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT)").run();
32
- * await db.execute("INSERT INTO users (name) VALUES (?)", ["Alice"]).run();
33
- * return db.query("SELECT * FROM users").run();
34
- * }).run();
45
+ * const { successes, errors } = await DB.withConnection(createInMemory(), (db) =>
46
+ * db.stream("SELECT * FROM large_table")
47
+ * .withConcurrency(10)
48
+ * .map(row => processRow(row))
49
+ * .partition()
50
+ * ).run();
51
+ * ```
35
52
  *
36
- * // Stream large result sets
37
- * const { successes, errors } = await db.stream("SELECT * FROM users")
38
- * .map(u => processUser(u))
39
- * .partition();
53
+ * @example Transactions with automatic rollback on error
54
+ * ```ts
55
+ * import { DB, ConstraintViolation, createInMemory } from "@anabranch/db";
40
56
  *
41
- * // Transactions with automatic rollback on error
42
57
  * const result = await DB.withConnection(createInMemory(), (db) =>
43
58
  * db.withTransaction(async (tx) => {
44
- * await tx.execute("INSERT INTO users (name) VALUES (?)", ["Bob"]).run();
45
- * return tx.query("SELECT last_insert_rowid()").run();
59
+ * await tx.execute("INSERT INTO orders (user_id) VALUES (?)", [userId]);
60
+ * await tx.execute("UPDATE users SET order_count = order_count + 1 WHERE id = ?", [userId]);
61
+ * return tx.query("SELECT last_insert_rowid()");
46
62
  * })
63
+ * ).recoverWhen(
64
+ * (e) => e instanceof ConstraintViolation,
65
+ * (e) => ({ id: 0, error: e.message })
47
66
  * ).run();
48
67
  * ```
49
68
  *
50
- * ## Error Types
51
- *
52
- * The following error types are exported for adapter implementors:
69
+ * @example Retry with exponential backoff
70
+ * ```ts
71
+ * import { DB, createPostgres } from "@anabranch/db";
72
+ * import { createPostgres } from "@anabranch/db-postgres";
53
73
  *
54
- * - {@link ConnectionFailed} - Throw from connector's `connect()` on failure
55
- * - {@link CloseError} - Throw from adapter's `close()` on failure
56
- * - {@link QueryFailed} - Thrown for query execution errors
57
- * - {@link ConstraintViolation} - Thrown for constraint violations (e.g., UNIQUE, FOREIGN KEY)
58
- * - {@link TransactionFailed} - Thrown for transaction errors
74
+ * const users = await DB.withConnection(createPostgres(), (db) =>
75
+ * db.query("SELECT * FROM users")
76
+ * .retry({ attempts: 3, delay: (attempt) => 100 * Math.pow(2, attempt) })
77
+ * ).run();
78
+ * ```
59
79
  *
60
80
  * @module
61
81
  */
@@ -1,2 +1,29 @@
1
+ /**
2
+ * @anabranch/db-postgres
3
+ *
4
+ * PostgreSQL database connector for the @anabranch/db package using `node:pg`.
5
+ *
6
+ * Provides a `DBConnector` implementation with connection pooling and
7
+ * cursor-based streaming via `pg-cursor` for memory-efficient processing
8
+ * of large result sets.
9
+ *
10
+ * @example
11
+ * ```ts
12
+ * import { DB } from "@anabranch/db";
13
+ * import { createPostgres } from "@anabranch/db-postgres";
14
+ *
15
+ * const db = new DB(
16
+ * await createPostgres({
17
+ * connectionString: "postgresql://user:pass@localhost:5432/mydb",
18
+ * }).connect(),
19
+ * );
20
+ *
21
+ * const users = await db
22
+ * .query<{ id: number; name: string }>("SELECT * FROM users")
23
+ * .run();
24
+ * ```
25
+ *
26
+ * @module
27
+ */
1
28
  export { createPostgres, type PostgresConnector, type PostgresOptions, } from "./postgres.js";
2
29
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/db-postgres/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,KAAK,iBAAiB,EACtB,KAAK,eAAe,GACrB,MAAM,eAAe,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/db-postgres/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,OAAO,EACL,cAAc,EACd,KAAK,iBAAiB,EACtB,KAAK,eAAe,GACrB,MAAM,eAAe,CAAC"}
@@ -1 +1,28 @@
1
+ /**
2
+ * @anabranch/db-postgres
3
+ *
4
+ * PostgreSQL database connector for the @anabranch/db package using `node:pg`.
5
+ *
6
+ * Provides a `DBConnector` implementation with connection pooling and
7
+ * cursor-based streaming via `pg-cursor` for memory-efficient processing
8
+ * of large result sets.
9
+ *
10
+ * @example
11
+ * ```ts
12
+ * import { DB } from "@anabranch/db";
13
+ * import { createPostgres } from "@anabranch/db-postgres";
14
+ *
15
+ * const db = new DB(
16
+ * await createPostgres({
17
+ * connectionString: "postgresql://user:pass@localhost:5432/mydb",
18
+ * }).connect(),
19
+ * );
20
+ *
21
+ * const users = await db
22
+ * .query<{ id: number; name: string }>("SELECT * FROM users")
23
+ * .run();
24
+ * ```
25
+ *
26
+ * @module
27
+ */
1
28
  export { createPostgres, } from "./postgres.js";
@@ -1,19 +1,71 @@
1
1
  import type { DBAdapter } from "../db/index.js";
2
+ /**
3
+ * Creates a PostgreSQL connector with connection pooling.
4
+ *
5
+ * Returns a connector that can be used with {@link DB.withConnection} to
6
+ * acquire connections. Each call to `connect()` returns a new adapter with
7
+ * query, execute, and stream methods. The stream method uses pg-cursor for
8
+ * memory-efficient streaming of large result sets.
9
+ *
10
+ * @example Connect and query with error handling
11
+ * ```ts
12
+ * import { DB } from "@anabranch/db";
13
+ * import { createPostgres } from "@anabranch/db-postgres";
14
+ *
15
+ * const users = await DB.withConnection(createPostgres(), (db) =>
16
+ * db.query("SELECT * FROM users WHERE active = ?", [true])
17
+ * ).run();
18
+ * ```
19
+ *
20
+ * @example Stream large result sets with concurrency
21
+ * ```ts
22
+ * import { DB } from "@anabranch/db";
23
+ * import { createPostgres } from "@anabranch/db-postgres";
24
+ *
25
+ * const { successes, errors } = await DB.withConnection(createPostgres(), (db) =>
26
+ * db.stream("SELECT * FROM large_table")
27
+ * .withConcurrency(10)
28
+ * .map(row => processRow(row))
29
+ * .partition()
30
+ * ).run();
31
+ * ```
32
+ *
33
+ * @example Transactions with automatic rollback
34
+ * ```ts
35
+ * import { DB } from "@anabranch/db";
36
+ * import { createPostgres } from "@anabranch/db-postgres";
37
+ *
38
+ * const result = await DB.withConnection(createPostgres(), (db) =>
39
+ * db.withTransaction(async (tx) => {
40
+ * await tx.execute("INSERT INTO orders (user_id) VALUES (?)", [userId]);
41
+ * return tx.query("SELECT last_insert_rowid()");
42
+ * })
43
+ * ).run();
44
+ * ```
45
+ */
2
46
  export declare function createPostgres(options?: PostgresOptions): PostgresConnector;
3
- type PostgresOptions = {
47
+ /** Connection options for PostgreSQL. */
48
+ export type PostgresOptions = {
49
+ /** @default "localhost" */
4
50
  host?: string;
51
+ /** @default 5432 */
5
52
  port?: number;
53
+ /** @default "postgres" */
6
54
  user?: string;
55
+ /** @default "" */
7
56
  password?: string;
57
+ /** @default "postgres" */
8
58
  database?: string;
9
59
  connectionString?: string;
10
60
  max?: number;
11
61
  idleTimeoutMillis?: number;
12
62
  connectionTimeoutMillis?: number;
13
63
  };
64
+ /** PostgreSQL database connector. */
14
65
  export interface PostgresConnector {
66
+ /** Connects and returns a DBAdapter for query execution. */
15
67
  connect(signal?: AbortSignal): Promise<DBAdapter>;
68
+ /** Closes the connection pool. */
16
69
  end(): Promise<void>;
17
70
  }
18
- export type { PostgresOptions };
19
71
  //# sourceMappingURL=postgres.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"postgres.d.ts","sourceRoot":"","sources":["../../src/db-postgres/postgres.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAKhD,wBAAgB,cAAc,CAC5B,OAAO,GAAE,eAAoB,GAC5B,iBAAiB,CA4CnB;AAED,KAAK,eAAe,GAAG;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,uBAAuB,CAAC,EAAE,MAAM,CAAC;CAClC,CAAC;AAuBF,MAAM,WAAW,iBAAiB;IAChC,OAAO,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;IAClD,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACtB;AAED,YAAY,EAAE,eAAe,EAAE,CAAC"}
1
+ {"version":3,"file":"postgres.d.ts","sourceRoot":"","sources":["../../src/db-postgres/postgres.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAKhD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AACH,wBAAgB,cAAc,CAC5B,OAAO,GAAE,eAAoB,GAC5B,iBAAiB,CA4CnB;AAED,yCAAyC;AACzC,MAAM,MAAM,eAAe,GAAG;IAC5B,2BAA2B;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,oBAAoB;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,0BAA0B;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,kBAAkB;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,0BAA0B;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,uBAAuB,CAAC,EAAE,MAAM,CAAC;CAClC,CAAC;AAEF,qCAAqC;AACrC,MAAM,WAAW,iBAAiB;IAChC,4DAA4D;IAC5D,OAAO,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;IAClD,kCAAkC;IAClC,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACtB"}
@@ -2,6 +2,50 @@ import pg from "pg";
2
2
  import Cursor from "pg-cursor";
3
3
  import process from "node:process";
4
4
  const { Pool } = pg;
5
+ /**
6
+ * Creates a PostgreSQL connector with connection pooling.
7
+ *
8
+ * Returns a connector that can be used with {@link DB.withConnection} to
9
+ * acquire connections. Each call to `connect()` returns a new adapter with
10
+ * query, execute, and stream methods. The stream method uses pg-cursor for
11
+ * memory-efficient streaming of large result sets.
12
+ *
13
+ * @example Connect and query with error handling
14
+ * ```ts
15
+ * import { DB } from "@anabranch/db";
16
+ * import { createPostgres } from "@anabranch/db-postgres";
17
+ *
18
+ * const users = await DB.withConnection(createPostgres(), (db) =>
19
+ * db.query("SELECT * FROM users WHERE active = ?", [true])
20
+ * ).run();
21
+ * ```
22
+ *
23
+ * @example Stream large result sets with concurrency
24
+ * ```ts
25
+ * import { DB } from "@anabranch/db";
26
+ * import { createPostgres } from "@anabranch/db-postgres";
27
+ *
28
+ * const { successes, errors } = await DB.withConnection(createPostgres(), (db) =>
29
+ * db.stream("SELECT * FROM large_table")
30
+ * .withConcurrency(10)
31
+ * .map(row => processRow(row))
32
+ * .partition()
33
+ * ).run();
34
+ * ```
35
+ *
36
+ * @example Transactions with automatic rollback
37
+ * ```ts
38
+ * import { DB } from "@anabranch/db";
39
+ * import { createPostgres } from "@anabranch/db-postgres";
40
+ *
41
+ * const result = await DB.withConnection(createPostgres(), (db) =>
42
+ * db.withTransaction(async (tx) => {
43
+ * await tx.execute("INSERT INTO orders (user_id) VALUES (?)", [userId]);
44
+ * return tx.query("SELECT last_insert_rowid()");
45
+ * })
46
+ * ).run();
47
+ * ```
48
+ */
5
49
  export function createPostgres(options = {}) {
6
50
  const pool = new Pool(toPoolConfig(options));
7
51
  return {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@anabranch/db-postgres",
3
- "version": "0.1.5",
3
+ "version": "0.1.7",
4
4
  "description": "TODO: Add description",
5
5
  "repository": {
6
6
  "type": "git",