@leonardovida-md/drizzle-neo-duckdb 1.0.1 → 1.0.3

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 CHANGED
@@ -7,7 +7,7 @@
7
7
  [![npm version](https://img.shields.io/npm/v/@leonardovida-md/drizzle-neo-duckdb)](https://www.npmjs.com/package/@leonardovida-md/drizzle-neo-duckdb)
8
8
  [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
9
9
 
10
- [Documentation](./docs) • [Examples](./example) • [Contributing](#contributing)
10
+ [Documentation](https://leonardovida-md.github.io/drizzle-neo-duckdb/) • [Examples](./example) • [Contributing](#contributing)
11
11
 
12
12
  </div>
13
13
 
@@ -119,7 +119,14 @@ Drizzle DuckDB uses `drizzle-orm/pg-core` for schema definitions since DuckDB's
119
119
 
120
120
  ```typescript
121
121
  import { sql } from 'drizzle-orm';
122
- import { integer, text, boolean, timestamp, pgTable, pgSchema } from 'drizzle-orm/pg-core';
122
+ import {
123
+ integer,
124
+ text,
125
+ boolean,
126
+ timestamp,
127
+ pgTable,
128
+ pgSchema,
129
+ } from 'drizzle-orm/pg-core';
123
130
 
124
131
  // Tables in default schema
125
132
  const posts = pgTable('posts', {
@@ -181,7 +188,7 @@ const products = pgTable('products', {
181
188
  });
182
189
  ```
183
190
 
184
- See [Column Types Documentation](./docs/columns.md) for complete reference.
191
+ See [Column Types Documentation](https://leonardovida-md.github.io/drizzle-neo-duckdb/api/columns) for complete reference.
185
192
 
186
193
  ## Querying
187
194
 
@@ -189,10 +196,15 @@ All standard Drizzle query methods work:
189
196
 
190
197
  ```typescript
191
198
  // Select
192
- const users = await db.select().from(usersTable).where(eq(usersTable.active, true));
199
+ const users = await db
200
+ .select()
201
+ .from(usersTable)
202
+ .where(eq(usersTable.active, true));
193
203
 
194
204
  // Insert
195
- await db.insert(usersTable).values({ name: 'Alice', email: 'alice@example.com' });
205
+ await db
206
+ .insert(usersTable)
207
+ .values({ name: 'Alice', email: 'alice@example.com' });
196
208
 
197
209
  // Insert with returning
198
210
  const inserted = await db
@@ -201,7 +213,10 @@ const inserted = await db
201
213
  .returning({ id: usersTable.id });
202
214
 
203
215
  // Update
204
- await db.update(usersTable).set({ name: 'Updated' }).where(eq(usersTable.id, 1));
216
+ await db
217
+ .update(usersTable)
218
+ .set({ name: 'Updated' })
219
+ .where(eq(usersTable.id, 1));
205
220
 
206
221
  // Delete
207
222
  await db.delete(usersTable).where(eq(usersTable.id, 1));
@@ -228,7 +243,9 @@ const results = await db
228
243
  const results = await db
229
244
  .select()
230
245
  .from(products)
231
- .where(duckDbArrayContained(products.tags, ['electronics', 'sale', 'featured']));
246
+ .where(
247
+ duckDbArrayContained(products.tags, ['electronics', 'sale', 'featured'])
248
+ );
232
249
 
233
250
  // Check if arrays overlap
234
251
  const results = await db
@@ -258,7 +275,7 @@ import { migrate } from '@leonardovida-md/drizzle-neo-duckdb';
258
275
  await migrate(db, { migrationsFolder: './drizzle' });
259
276
  ```
260
277
 
261
- Migration metadata is stored in `drizzle.__drizzle_migrations` by default. See [Migrations Documentation](./docs/migrations.md) for configuration options.
278
+ Migration metadata is stored in `drizzle.__drizzle_migrations` by default. See [Migrations Documentation](https://leonardovida-md.github.io/drizzle-neo-duckdb/guide/migrations) for configuration options.
262
279
 
263
280
  ## Schema Introspection
264
281
 
@@ -283,7 +300,7 @@ const result = await introspect(db, {
283
300
  console.log(result.files.schemaTs);
284
301
  ```
285
302
 
286
- See [Introspection Documentation](./docs/introspection.md) for all options.
303
+ See [Introspection Documentation](https://leonardovida-md.github.io/drizzle-neo-duckdb/guide/introspection) for all options.
287
304
 
288
305
  ## Configuration Options
289
306
 
@@ -307,22 +324,23 @@ const db = drizzle(connection, {
307
324
 
308
325
  This connector aims for compatibility with Drizzle's Postgres driver but has some differences:
309
326
 
310
- | Feature | Status |
311
- |---------|--------|
312
- | Basic CRUD operations | Full support |
313
- | Joins and subqueries | Full support |
314
- | Transactions | No savepoints (nested transactions reuse outer) |
315
- | JSON/JSONB columns | Use `duckDbJson()` instead |
316
- | Prepared statements | No statement caching |
317
- | Streaming results | Results are materialized |
327
+ | Feature | Status |
328
+ | --------------------- | ---------------------------------------------------------- |
329
+ | Basic CRUD operations | Full support |
330
+ | Joins and subqueries | Full support |
331
+ | Transactions | No savepoints (nested transactions reuse outer) |
332
+ | JSON/JSONB columns | Use `duckDbJson()` instead |
333
+ | Prepared statements | No statement caching |
334
+ | Streaming results | Materialized by default; use `executeBatches()` for chunks |
318
335
 
319
- See [Limitations Documentation](./docs/limitations.md) for details.
336
+ See [Limitations Documentation](https://leonardovida-md.github.io/drizzle-neo-duckdb/guide/limitations) for details.
320
337
 
321
338
  ## Examples
322
339
 
323
340
  - **[MotherDuck NYC Taxi](./example/motherduck-nyc.ts)** — Query the built-in NYC taxi dataset from MotherDuck cloud
324
341
 
325
342
  Run examples:
343
+
326
344
  ```bash
327
345
  MOTHERDUCK_TOKEN=your_token bun example/motherduck-nyc.ts
328
346
  ```
package/dist/client.d.ts CHANGED
@@ -8,3 +8,15 @@ export interface PrepareParamsOptions {
8
8
  export declare function prepareParams(params: unknown[], options?: PrepareParamsOptions): unknown[];
9
9
  export declare function closeClientConnection(connection: DuckDBConnection): Promise<void>;
10
10
  export declare function executeOnClient(client: DuckDBClientLike, query: string, params: unknown[]): Promise<RowData[]>;
11
+ export interface ExecuteInBatchesOptions {
12
+ rowsPerChunk?: number;
13
+ }
14
+ /**
15
+ * Stream results from DuckDB in batches to avoid fully materializing rows in JS.
16
+ */
17
+ export declare function executeInBatches(client: DuckDBClientLike, query: string, params: unknown[], options?: ExecuteInBatchesOptions): AsyncGenerator<RowData[], void, void>;
18
+ /**
19
+ * Return columnar results when the underlying node-api exposes an Arrow/columnar API.
20
+ * Falls back to column-major JS arrays when Arrow is unavailable.
21
+ */
22
+ export declare function executeArrowOnClient(client: DuckDBClientLike, query: string, params: unknown[]): Promise<unknown>;
package/dist/columns.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import { type SQL } from 'drizzle-orm';
2
2
  import type { SQLWrapper } from 'drizzle-orm/sql/sql';
3
+ import { type ListValueWrapper, type ArrayValueWrapper, type MapValueWrapper, type BlobValueWrapper, type JsonValueWrapper } from './value-wrappers.ts';
3
4
  type IntColType = 'SMALLINT' | 'INTEGER' | 'BIGINT' | 'HUGEINT' | 'USMALLINT' | 'UINTEGER' | 'UBIGINT' | 'UHUGEINT' | 'INT' | 'INT16' | 'INT32' | 'INT64' | 'INT128' | 'LONG' | 'VARINT';
4
5
  type FloatColType = 'FLOAT' | 'DOUBLE';
5
6
  type StringColType = 'STRING' | 'VARCHAR' | 'TEXT';
@@ -16,7 +17,7 @@ export declare const duckDbList: <TData = unknown>(name: string, elementType: An
16
17
  dataType: "custom";
17
18
  columnType: "PgCustomColumn";
18
19
  data: TData[];
19
- driverParam: string | unknown[] | SQL<unknown>;
20
+ driverParam: string | ListValueWrapper | unknown[];
20
21
  enumValues: undefined;
21
22
  }>;
22
23
  export declare const duckDbArray: <TData = unknown>(name: string, elementType: AnyColType, fixedLength?: number) => import("drizzle-orm/pg-core").PgCustomColumnBuilder<{
@@ -24,7 +25,7 @@ export declare const duckDbArray: <TData = unknown>(name: string, elementType: A
24
25
  dataType: "custom";
25
26
  columnType: "PgCustomColumn";
26
27
  data: TData[];
27
- driverParam: string | unknown[] | SQL<unknown>;
28
+ driverParam: string | unknown[] | ArrayValueWrapper;
28
29
  enumValues: undefined;
29
30
  }>;
30
31
  export declare const duckDbMap: <TData extends Record<string, any>>(name: string, valueType: AnyColType | ListColType | ArrayColType) => import("drizzle-orm/pg-core").PgCustomColumnBuilder<{
@@ -32,7 +33,7 @@ export declare const duckDbMap: <TData extends Record<string, any>>(name: string
32
33
  dataType: "custom";
33
34
  columnType: "PgCustomColumn";
34
35
  data: TData;
35
- driverParam: TData;
36
+ driverParam: MapValueWrapper | TData;
36
37
  enumValues: undefined;
37
38
  }>;
38
39
  export declare const duckDbStruct: <TData extends Record<string, any>>(name: string, schema: Record<string, Primitive>) => import("drizzle-orm/pg-core").PgCustomColumnBuilder<{
@@ -43,12 +44,19 @@ export declare const duckDbStruct: <TData extends Record<string, any>>(name: str
43
44
  driverParam: TData;
44
45
  enumValues: undefined;
45
46
  }>;
47
+ /**
48
+ * JSON column type that wraps values and delays JSON.stringify() to binding time.
49
+ * This ensures consistent handling with other wrapped types.
50
+ *
51
+ * Note: DuckDB stores JSON as VARCHAR internally, so the final binding
52
+ * is always a stringified JSON value.
53
+ */
46
54
  export declare const duckDbJson: <TData = unknown>(name: string) => import("drizzle-orm/pg-core").PgCustomColumnBuilder<{
47
55
  name: string;
48
56
  dataType: "custom";
49
57
  columnType: "PgCustomColumn";
50
58
  data: TData;
51
- driverParam: string | SQL<unknown>;
59
+ driverParam: string | JsonValueWrapper | SQL<unknown>;
52
60
  enumValues: undefined;
53
61
  }>;
54
62
  export declare const duckDbBlob: {
@@ -56,24 +64,24 @@ export declare const duckDbBlob: {
56
64
  name: "";
57
65
  dataType: "custom";
58
66
  columnType: "PgCustomColumn";
59
- data: Buffer;
60
- driverParam: unknown;
67
+ data: Buffer<ArrayBufferLike>;
68
+ driverParam: BlobValueWrapper;
61
69
  enumValues: undefined;
62
70
  }>;
63
71
  <TConfig extends Record<string, any>>(fieldConfig?: TConfig | undefined): import("drizzle-orm/pg-core").PgCustomColumnBuilder<{
64
72
  name: "";
65
73
  dataType: "custom";
66
74
  columnType: "PgCustomColumn";
67
- data: Buffer;
68
- driverParam: unknown;
75
+ data: Buffer<ArrayBufferLike>;
76
+ driverParam: BlobValueWrapper;
69
77
  enumValues: undefined;
70
78
  }>;
71
79
  <TName extends string>(dbName: TName, fieldConfig?: unknown): import("drizzle-orm/pg-core").PgCustomColumnBuilder<{
72
80
  name: TName;
73
81
  dataType: "custom";
74
82
  columnType: "PgCustomColumn";
75
- data: Buffer;
76
- driverParam: unknown;
83
+ data: Buffer<ArrayBufferLike>;
84
+ driverParam: BlobValueWrapper;
77
85
  enumValues: undefined;
78
86
  }>;
79
87
  };
package/dist/driver.d.ts CHANGED
@@ -4,10 +4,12 @@ import { PgDatabase } from 'drizzle-orm/pg-core/db';
4
4
  import type { SelectedFields } from 'drizzle-orm/pg-core/query-builders';
5
5
  import { type ExtractTablesWithRelations, type RelationalSchemaConfig, type TablesRelationalConfig } from 'drizzle-orm/relations';
6
6
  import { type DrizzleConfig } from 'drizzle-orm/utils';
7
+ import type { SQL } from 'drizzle-orm/sql/sql';
7
8
  import type { DuckDBClientLike, DuckDBQueryResultHKT, DuckDBTransaction } from './session.ts';
8
9
  import { DuckDBSession } from './session.ts';
9
10
  import { DuckDBDialect } from './dialect.ts';
10
11
  import { DuckDBSelectBuilder } from './select-builder.ts';
12
+ import type { ExecuteInBatchesOptions, RowData } from './client.ts';
11
13
  export interface PgDriverOptions {
12
14
  logger?: Logger;
13
15
  rewriteArrays?: boolean;
@@ -33,5 +35,7 @@ export declare class DuckDBDatabase<TFullSchema extends Record<string, unknown>
33
35
  constructor(dialect: DuckDBDialect, session: DuckDBSession<TFullSchema, TSchema>, schema: RelationalSchemaConfig<TSchema> | undefined);
34
36
  select(): DuckDBSelectBuilder<undefined>;
35
37
  select<TSelection extends SelectedFields>(fields: TSelection): DuckDBSelectBuilder<TSelection>;
38
+ executeBatches<T extends RowData = RowData>(query: SQL, options?: ExecuteInBatchesOptions): AsyncGenerator<T[], void, void>;
39
+ executeArrow(query: SQL): Promise<unknown>;
36
40
  transaction<T>(transaction: (tx: DuckDBTransaction<TFullSchema, TSchema>) => Promise<T>): Promise<T>;
37
41
  }