@avidian/duckdb-bun 0.0.0-stage → 1.0.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/LICENSE +22 -0
- package/README.md +286 -2
- package/package.json +96 -4
- package/src/bindings/api/appender.ts +288 -0
- package/src/bindings/api/data-chunk.ts +58 -0
- package/src/bindings/api/database.ts +232 -0
- package/src/bindings/api/datetime.ts +158 -0
- package/src/bindings/api/index.ts +13 -0
- package/src/bindings/api/logical-types.ts +227 -0
- package/src/bindings/api/query.ts +616 -0
- package/src/bindings/api/scalar-function.ts +274 -0
- package/src/bindings/api/table-function.ts +339 -0
- package/src/bindings/api/values.ts +546 -0
- package/src/bindings/api/vector.ts +266 -0
- package/src/bindings/generated/capi.ts +695 -0
- package/src/bindings/generated/contract.ts +162 -0
- package/src/bindings/index.ts +10 -0
- package/src/bindings/runtime/convert.ts +307 -0
- package/src/bindings/runtime/diagnostics.ts +45 -0
- package/src/bindings/runtime/dispatch.ts +213 -0
- package/src/bindings/runtime/exception.ts +103 -0
- package/src/bindings/runtime/flags.ts +19 -0
- package/src/bindings/runtime/handle.ts +217 -0
- package/src/bindings/runtime/kinds.ts +53 -0
- package/src/bindings/runtime/marshal.ts +190 -0
- package/src/bindings/runtime/native.ts +153 -0
- package/src/bindings/runtime/ring.ts +54 -0
- package/src/bindings/runtime/scope.ts +133 -0
- package/src/bindings/runtime/trace.ts +65 -0
- package/src/connection.ts +35 -0
- package/src/database.ts +27 -0
- package/src/errors.ts +30 -0
- package/src/file-assets.d.ts +10 -0
- package/src/index.ts +17 -0
- package/src/library.ts +83 -0
- package/src/neo.ts +16 -0
- package/src/reader.ts +47 -0
- package/src/statement.ts +61 -0
- package/src/types.ts +52 -0
- package/src/version.ts +6 -0
- package/vendor/node-api/LICENSE +7 -0
- package/vendor/node-api/PROVENANCE.md +54 -0
- package/vendor/node-api/node-bindings.d.ts +1669 -0
- package/vendor/node-api/src/DuckDBAppender.ts +237 -0
- package/vendor/node-api/src/DuckDBClientContext.ts +13 -0
- package/vendor/node-api/src/DuckDBConnection.ts +315 -0
- package/vendor/node-api/src/DuckDBDataChunk.ts +412 -0
- package/vendor/node-api/src/DuckDBDataChunkWriter.ts +144 -0
- package/vendor/node-api/src/DuckDBExtractedStatements.ts +37 -0
- package/vendor/node-api/src/DuckDBInstance.ts +35 -0
- package/vendor/node-api/src/DuckDBInstanceCache.ts +29 -0
- package/vendor/node-api/src/DuckDBLogicalType.ts +446 -0
- package/vendor/node-api/src/DuckDBMaterializedResult.ts +39 -0
- package/vendor/node-api/src/DuckDBPendingResult.ts +83 -0
- package/vendor/node-api/src/DuckDBPreparedStatement.ts +376 -0
- package/vendor/node-api/src/DuckDBPreparedStatementCollection.ts +5 -0
- package/vendor/node-api/src/DuckDBPreparedStatementWeakRefCollection.ts +31 -0
- package/vendor/node-api/src/DuckDBResult.ts +403 -0
- package/vendor/node-api/src/DuckDBResultReader.ts +283 -0
- package/vendor/node-api/src/DuckDBScalarFunction.ts +149 -0
- package/vendor/node-api/src/DuckDBScalarFunctionBindInfo.ts +34 -0
- package/vendor/node-api/src/DuckDBScalarFunctionInfo.ts +34 -0
- package/vendor/node-api/src/DuckDBScalarFunctionInitInfo.ts +35 -0
- package/vendor/node-api/src/DuckDBTableFunction.ts +149 -0
- package/vendor/node-api/src/DuckDBTableFunctionBindInfo.ts +56 -0
- package/vendor/node-api/src/DuckDBTableFunctionInfo.ts +36 -0
- package/vendor/node-api/src/DuckDBTableFunctionInitInfo.ts +52 -0
- package/vendor/node-api/src/DuckDBType.ts +1 -0
- package/vendor/node-api/src/DuckDBTypeId.ts +46 -0
- package/vendor/node-api/src/DuckDBValueConverter.ts +23 -0
- package/vendor/node-api/src/DuckDBValueConverters.ts +461 -0
- package/vendor/node-api/src/DuckDBVector.ts +1 -0
- package/vendor/node-api/src/JS.ts +11 -0
- package/vendor/node-api/src/JSDuckDBValueConverter.ts +85 -0
- package/vendor/node-api/src/JSInputTypeForTypeId.ts +101 -0
- package/vendor/node-api/src/JSToDuckDBValueConverter.ts +136 -0
- package/vendor/node-api/src/JSTypeForTypeId.ts +78 -0
- package/vendor/node-api/src/Json.ts +7 -0
- package/vendor/node-api/src/JsonDuckDBValueConverter.ts +72 -0
- package/vendor/node-api/src/JsonTypeForTypeId.ts +86 -0
- package/vendor/node-api/src/ToDuckDBValueConverter.ts +68 -0
- package/vendor/node-api/src/ToDuckDBValueConverters.ts +303 -0
- package/vendor/node-api/src/configurationOptionDescriptions.ts +13 -0
- package/vendor/node-api/src/conversion/bytesFromString.ts +5 -0
- package/vendor/node-api/src/conversion/dateTimeStringConversion.ts +343 -0
- package/vendor/node-api/src/conversion/displayStringForDuckDBValue.ts +12 -0
- package/vendor/node-api/src/conversion/stringFromBlob.ts +48 -0
- package/vendor/node-api/src/conversion/stringFromDecimal.ts +129 -0
- package/vendor/node-api/src/conversion/varintDecode.ts +42 -0
- package/vendor/node-api/src/convertColumnsFromChunks.ts +28 -0
- package/vendor/node-api/src/convertColumnsObjectFromChunks.ts +29 -0
- package/vendor/node-api/src/convertRowObjectsFromChunks.ts +21 -0
- package/vendor/node-api/src/convertRowsFromChunks.ts +16 -0
- package/vendor/node-api/src/createConfig.ts +14 -0
- package/vendor/node-api/src/createDuckDBValueConverter.ts +17 -0
- package/vendor/node-api/src/createResult.ts +15 -0
- package/vendor/node-api/src/createValue.ts +355 -0
- package/vendor/node-api/src/duckdb.ts +51 -0
- package/vendor/node-api/src/enums.ts +7 -0
- package/vendor/node-api/src/getColumnsFromChunks.ts +13 -0
- package/vendor/node-api/src/getColumnsObjectFromChunks.ts +16 -0
- package/vendor/node-api/src/getRowObjectsFromChunks.ts +13 -0
- package/vendor/node-api/src/getRowsFromChunks.ts +12 -0
- package/vendor/node-api/src/index.ts +3 -0
- package/vendor/node-api/src/readValue.ts +31 -0
- package/vendor/node-api/src/sleep.ts +5 -0
- package/vendor/node-api/src/sql.ts +7 -0
- package/vendor/node-api/src/tsconfig.json +7 -0
- package/vendor/node-api/src/typeForValue.ts +144 -0
- package/vendor/node-api/src/types/BaseDuckDBType.ts +31 -0
- package/vendor/node-api/src/types/DuckDBAnyType.ts +13 -0
- package/vendor/node-api/src/types/DuckDBArrayType.ts +43 -0
- package/vendor/node-api/src/types/DuckDBBigIntType.ts +21 -0
- package/vendor/node-api/src/types/DuckDBBigNumType.ts +21 -0
- package/vendor/node-api/src/types/DuckDBBitType.ts +13 -0
- package/vendor/node-api/src/types/DuckDBBlobType.ts +13 -0
- package/vendor/node-api/src/types/DuckDBBooleanType.ts +13 -0
- package/vendor/node-api/src/types/DuckDBDateType.ts +29 -0
- package/vendor/node-api/src/types/DuckDBDecimalType.ts +46 -0
- package/vendor/node-api/src/types/DuckDBDoubleType.ts +21 -0
- package/vendor/node-api/src/types/DuckDBEnumType.ts +111 -0
- package/vendor/node-api/src/types/DuckDBFloatType.ts +21 -0
- package/vendor/node-api/src/types/DuckDBGeometryType.ts +36 -0
- package/vendor/node-api/src/types/DuckDBHugeIntType.ts +21 -0
- package/vendor/node-api/src/types/DuckDBIntegerLiteralType.ts +13 -0
- package/vendor/node-api/src/types/DuckDBIntegerType.ts +21 -0
- package/vendor/node-api/src/types/DuckDBIntervalType.ts +13 -0
- package/vendor/node-api/src/types/DuckDBListType.ts +35 -0
- package/vendor/node-api/src/types/DuckDBMapType.ts +47 -0
- package/vendor/node-api/src/types/DuckDBSQLNullType.ts +17 -0
- package/vendor/node-api/src/types/DuckDBSmallIntType.ts +21 -0
- package/vendor/node-api/src/types/DuckDBStringLiteralType.ts +13 -0
- package/vendor/node-api/src/types/DuckDBStructType.ts +104 -0
- package/vendor/node-api/src/types/DuckDBTimeNSType.ts +20 -0
- package/vendor/node-api/src/types/DuckDBTimeTZType.ts +23 -0
- package/vendor/node-api/src/types/DuckDBTimeType.ts +20 -0
- package/vendor/node-api/src/types/DuckDBTimestampMillisecondsType.ts +29 -0
- package/vendor/node-api/src/types/DuckDBTimestampNanosecondsType.ts +29 -0
- package/vendor/node-api/src/types/DuckDBTimestampSecondsType.ts +29 -0
- package/vendor/node-api/src/types/DuckDBTimestampTZNanosecondsType.ts +32 -0
- package/vendor/node-api/src/types/DuckDBTimestampTZType.ts +32 -0
- package/vendor/node-api/src/types/DuckDBTimestampType.ts +32 -0
- package/vendor/node-api/src/types/DuckDBTinyIntType.ts +21 -0
- package/vendor/node-api/src/types/DuckDBType.ts +86 -0
- package/vendor/node-api/src/types/DuckDBUBigIntType.ts +21 -0
- package/vendor/node-api/src/types/DuckDBUHugeIntType.ts +21 -0
- package/vendor/node-api/src/types/DuckDBUIntegerType.ts +21 -0
- package/vendor/node-api/src/types/DuckDBUSmallIntType.ts +21 -0
- package/vendor/node-api/src/types/DuckDBUTinyIntType.ts +21 -0
- package/vendor/node-api/src/types/DuckDBUUIDType.ts +20 -0
- package/vendor/node-api/src/types/DuckDBUnionType.ts +74 -0
- package/vendor/node-api/src/types/DuckDBVarCharType.ts +13 -0
- package/vendor/node-api/src/types/DuckDBVariantType.ts +13 -0
- package/vendor/node-api/src/types/index.ts +44 -0
- package/vendor/node-api/src/values/DuckDBArrayValue.ts +18 -0
- package/vendor/node-api/src/values/DuckDBBitValue.ts +117 -0
- package/vendor/node-api/src/values/DuckDBBlobValue.ts +26 -0
- package/vendor/node-api/src/values/DuckDBDateValue.ts +43 -0
- package/vendor/node-api/src/values/DuckDBDecimalValue.ts +44 -0
- package/vendor/node-api/src/values/DuckDBGeometryValue.ts +30 -0
- package/vendor/node-api/src/values/DuckDBIntervalValue.ts +22 -0
- package/vendor/node-api/src/values/DuckDBListValue.ts +18 -0
- package/vendor/node-api/src/values/DuckDBMapValue.ts +25 -0
- package/vendor/node-api/src/values/DuckDBStructValue.ts +22 -0
- package/vendor/node-api/src/values/DuckDBTimeNSValue.ts +23 -0
- package/vendor/node-api/src/values/DuckDBTimeTZValue.ts +96 -0
- package/vendor/node-api/src/values/DuckDBTimeValue.ts +34 -0
- package/vendor/node-api/src/values/DuckDBTimestampMillisecondsValue.ts +29 -0
- package/vendor/node-api/src/values/DuckDBTimestampNanosecondsValue.ts +28 -0
- package/vendor/node-api/src/values/DuckDBTimestampSecondsValue.ts +28 -0
- package/vendor/node-api/src/values/DuckDBTimestampTZNanosecondsValue.ts +44 -0
- package/vendor/node-api/src/values/DuckDBTimestampTZValue.ts +54 -0
- package/vendor/node-api/src/values/DuckDBTimestampValue.ts +45 -0
- package/vendor/node-api/src/values/DuckDBTupleValue.ts +22 -0
- package/vendor/node-api/src/values/DuckDBUUIDValue.ts +48 -0
- package/vendor/node-api/src/values/DuckDBUnionValue.ts +22 -0
- package/vendor/node-api/src/values/DuckDBValue.ts +53 -0
- package/vendor/node-api/src/values/DuckDBVariantValue.ts +34 -0
- package/vendor/node-api/src/values/index.ts +24 -0
- package/vendor/node-api/src/vectors/DuckDBArrayVector.ts +107 -0
- package/vendor/node-api/src/vectors/DuckDBBigIntVector.ts +75 -0
- package/vendor/node-api/src/vectors/DuckDBBigNumVector.ts +98 -0
- package/vendor/node-api/src/vectors/DuckDBBitVector.ts +102 -0
- package/vendor/node-api/src/vectors/DuckDBBlobVector.ts +112 -0
- package/vendor/node-api/src/vectors/DuckDBBooleanVector.ts +84 -0
- package/vendor/node-api/src/vectors/DuckDBDateVector.ts +80 -0
- package/vendor/node-api/src/vectors/DuckDBDecimal128Vector.ts +107 -0
- package/vendor/node-api/src/vectors/DuckDBDecimal16Vector.ts +104 -0
- package/vendor/node-api/src/vectors/DuckDBDecimal32Vector.ts +104 -0
- package/vendor/node-api/src/vectors/DuckDBDecimal64Vector.ts +104 -0
- package/vendor/node-api/src/vectors/DuckDBDoubleVector.ts +68 -0
- package/vendor/node-api/src/vectors/DuckDBEnum16Vector.ts +75 -0
- package/vendor/node-api/src/vectors/DuckDBEnum32Vector.ts +75 -0
- package/vendor/node-api/src/vectors/DuckDBEnum8Vector.ts +75 -0
- package/vendor/node-api/src/vectors/DuckDBFloatVector.ts +68 -0
- package/vendor/node-api/src/vectors/DuckDBGeometryVector.ts +97 -0
- package/vendor/node-api/src/vectors/DuckDBHugeIntVector.ts +89 -0
- package/vendor/node-api/src/vectors/DuckDBIntegerVector.ts +75 -0
- package/vendor/node-api/src/vectors/DuckDBIntervalVector.ts +100 -0
- package/vendor/node-api/src/vectors/DuckDBListVector.ts +221 -0
- package/vendor/node-api/src/vectors/DuckDBMapVector.ts +88 -0
- package/vendor/node-api/src/vectors/DuckDBSQLNullVector.ts +53 -0
- package/vendor/node-api/src/vectors/DuckDBSmallIntVector.ts +75 -0
- package/vendor/node-api/src/vectors/DuckDBStructVector.ts +138 -0
- package/vendor/node-api/src/vectors/DuckDBTimeNSVector.ts +80 -0
- package/vendor/node-api/src/vectors/DuckDBTimeTZVector.ts +80 -0
- package/vendor/node-api/src/vectors/DuckDBTimeVector.ts +80 -0
- package/vendor/node-api/src/vectors/DuckDBTimestampMillisecondsVector.ts +88 -0
- package/vendor/node-api/src/vectors/DuckDBTimestampNanosecondsVector.ts +88 -0
- package/vendor/node-api/src/vectors/DuckDBTimestampSecondsVector.ts +88 -0
- package/vendor/node-api/src/vectors/DuckDBTimestampTZNanosecondsVector.ts +88 -0
- package/vendor/node-api/src/vectors/DuckDBTimestampTZVector.ts +86 -0
- package/vendor/node-api/src/vectors/DuckDBTimestampVector.ts +83 -0
- package/vendor/node-api/src/vectors/DuckDBTinyIntVector.ts +75 -0
- package/vendor/node-api/src/vectors/DuckDBTupleVector.ts +125 -0
- package/vendor/node-api/src/vectors/DuckDBUBigIntVector.ts +75 -0
- package/vendor/node-api/src/vectors/DuckDBUHugeIntVector.ts +89 -0
- package/vendor/node-api/src/vectors/DuckDBUIntegerVector.ts +75 -0
- package/vendor/node-api/src/vectors/DuckDBUSmallIntVector.ts +75 -0
- package/vendor/node-api/src/vectors/DuckDBUTinyIntVector.ts +75 -0
- package/vendor/node-api/src/vectors/DuckDBUUIDVector.ts +89 -0
- package/vendor/node-api/src/vectors/DuckDBUnionVector.ts +84 -0
- package/vendor/node-api/src/vectors/DuckDBValidity.ts +104 -0
- package/vendor/node-api/src/vectors/DuckDBVarCharVector.ts +100 -0
- package/vendor/node-api/src/vectors/DuckDBVariantVector.ts +609 -0
- package/vendor/node-api/src/vectors/DuckDBVector.ts +33 -0
- package/vendor/node-api/src/vectors/createVector.ts +269 -0
- package/vendor/node-api/src/vectors/dataAccessors.ts +387 -0
- package/vendor/node-api/src/vectors/index.ts +50 -0
- package/vendor/node-api/src/vectors/vectorRegistry.ts +24 -0
- package/vendor/node-api/src/version.ts +5 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Josh Cano
|
|
4
|
+
Copyright (c) 2026 John Michael Manlupig
|
|
5
|
+
|
|
6
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
7
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
8
|
+
in the Software without restriction, including without limitation the rights
|
|
9
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
10
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
11
|
+
furnished to do so, subject to the following conditions:
|
|
12
|
+
|
|
13
|
+
The above copyright notice and this permission notice shall be included in all
|
|
14
|
+
copies or substantial portions of the Software.
|
|
15
|
+
|
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
17
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
18
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
19
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
20
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
21
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
22
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,287 @@
|
|
|
1
|
-
#
|
|
1
|
+
# duckdb-bun
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://github.com/avidianity/duckdb-bun/actions/workflows/ci.yml)
|
|
4
|
+
[](./LICENSE)
|
|
5
|
+

|
|
6
|
+

|
|
7
|
+
|
|
8
|
+
A Bun-native, drop-in reimplementation of [`@duckdb/node-api`](https://www.npmjs.com/package/@duckdb/node-api) over the libduckdb C API through [`bun:ffi`](https://bun.com/docs/runtime/ffi), with no N-API addon.
|
|
9
|
+
It runs the official `@duckdb/node-api` TypeScript layer unmodified over its own bindings, so it has the same API and returns the same value objects.
|
|
10
|
+
It loads libduckdb as a plain shared library, so `bun build --compile` produces one self-contained executable, which the official addon cannot do.
|
|
11
|
+
|
|
12
|
+
```ts
|
|
13
|
+
import { DuckDBInstance } from "@avidian/duckdb-bun"; // was "@duckdb/node-api"
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Version 1.0.0 bundles DuckDB v2.0.0 and matches `@duckdb/node-api` 2.0.0-r.1; [Versions](#versions) maps every release.
|
|
17
|
+
|
|
18
|
+
## Install
|
|
19
|
+
|
|
20
|
+
```sh
|
|
21
|
+
bun add @avidian/duckdb-bun
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
The package depends on one optional package per platform, which ships libduckdb and the native shim:
|
|
25
|
+
|
|
26
|
+
| Platform | Package |
|
|
27
|
+
| --- | --- |
|
|
28
|
+
| Linux x64, glibc 2.36 or newer | `@avidian/duckdb-bun-linux-x64` |
|
|
29
|
+
| Linux arm64, glibc 2.36 or newer | `@avidian/duckdb-bun-linux-arm64` |
|
|
30
|
+
| macOS arm64 | `@avidian/duckdb-bun-darwin-arm64` |
|
|
31
|
+
|
|
32
|
+
The linux-arm64 package also serves Docker containers on Apple silicon Macs, which run arm64 Linux images by default.
|
|
33
|
+
Bun installs only the one that matches the host.
|
|
34
|
+
Do not install with `--no-optional`.
|
|
35
|
+
Other platforms are not supported yet, because the native shim is built per platform.
|
|
36
|
+
|
|
37
|
+
## Versions
|
|
38
|
+
|
|
39
|
+
The package has its own semantic version, independent of DuckDB's:
|
|
40
|
+
|
|
41
|
+
- A minor release upgrades DuckDB without breaking the API.
|
|
42
|
+
- A patch release fixes the binding between DuckDB releases.
|
|
43
|
+
- A major release breaks the API.
|
|
44
|
+
|
|
45
|
+
Every release is a stable version, so a range such as `^1.0.0` takes every compatible release.
|
|
46
|
+
|
|
47
|
+
| `@avidian/duckdb-bun` | DuckDB | `@duckdb/node-api` it matches |
|
|
48
|
+
| --- | --- | --- |
|
|
49
|
+
| 1.0.0 | 2.0.0 | 2.0.0-r.1 |
|
|
50
|
+
| 1.0.1 | 2.0.0 | 2.0.0-r.1 |
|
|
51
|
+
|
|
52
|
+
At run time, `DUCKDB_VERSION` holds the bundled DuckDB version, and `diagnostics().versions` holds all of them:
|
|
53
|
+
|
|
54
|
+
```ts
|
|
55
|
+
import { DUCKDB_VERSION } from "@avidian/duckdb-bun";
|
|
56
|
+
|
|
57
|
+
console.log(DUCKDB_VERSION); // "2.0.0"
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Usage
|
|
61
|
+
|
|
62
|
+
```ts
|
|
63
|
+
import { DuckDBInstance } from "@avidian/duckdb-bun";
|
|
64
|
+
|
|
65
|
+
const instance = await DuckDBInstance.create(":memory:");
|
|
66
|
+
const connection = await instance.connect();
|
|
67
|
+
const reader = await connection.runAndReadAll("SELECT 42 AS answer");
|
|
68
|
+
console.log(reader.getRowObjects()); // [{ answer: 42 }]
|
|
69
|
+
connection.closeSync();
|
|
70
|
+
instance.closeSync();
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Everything in the [`@duckdb/node-api` documentation](https://duckdb.org/docs/stable/clients/node_neo/overview) applies.
|
|
74
|
+
The one difference: it runs under Bun, not Node.js.
|
|
75
|
+
|
|
76
|
+
## Compile to a standalone binary
|
|
77
|
+
|
|
78
|
+
```sh
|
|
79
|
+
bun build --compile app.ts --outfile app
|
|
80
|
+
./app
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
The executable embeds libduckdb and the shim.
|
|
84
|
+
At start-up it copies both to a temporary directory, because `dlopen` cannot read Bun's embedded file system.
|
|
85
|
+
|
|
86
|
+
## Diagnostics
|
|
87
|
+
|
|
88
|
+
`diagnostics()` returns a snapshot of the binding's native state:
|
|
89
|
+
|
|
90
|
+
```ts
|
|
91
|
+
import { diagnostics } from "@avidian/duckdb-bun";
|
|
92
|
+
|
|
93
|
+
console.log(diagnostics());
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
```js
|
|
97
|
+
{
|
|
98
|
+
versions: { package: "1.0.0", duckdb: "v2.0.0", bun: "1.4.4", shim: "0.1.0" },
|
|
99
|
+
paths: { libduckdb: "/…/libduckdb.so", shim: "/…/libduckdb_bun_shim.so" },
|
|
100
|
+
crashHandler: "installed",
|
|
101
|
+
flags: { debug: false, traceSql: false, crashHandler: true },
|
|
102
|
+
tracingChannel: "duckdb-bun:call",
|
|
103
|
+
nativeThreads: { running: 0, peak: 1 },
|
|
104
|
+
jobs: { started: 4, completed: 4, inFlight: 0 },
|
|
105
|
+
callbacks: { posted: 0, completed: 0, inline: 0 },
|
|
106
|
+
ringEntries: 10,
|
|
107
|
+
liveHandles: { database: 1, connection: 1, result: 2 },
|
|
108
|
+
}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
| Field | Meaning |
|
|
112
|
+
| --- | --- |
|
|
113
|
+
| `versions` | The package, libduckdb, Bun and native shim versions. |
|
|
114
|
+
| `paths` | The libduckdb and shim files that were loaded. |
|
|
115
|
+
| `crashHandler` | `installed`, `disabled`, or `failed: <reason>`. Queries work without it. |
|
|
116
|
+
| `flags` | The [environment flags](#environment-flags) read at load. |
|
|
117
|
+
| `nativeThreads` | Native threads running blocking calls now, and the most at once. |
|
|
118
|
+
| `jobs` | Blocking calls run on native threads: started, completed, and awaited by JavaScript now. |
|
|
119
|
+
| `callbacks` | Scalar and table function callbacks: posted from DuckDB threads, completed, and run inline on the JS thread. |
|
|
120
|
+
| `ringEntries` | Events written to the crash report's ring buffer. |
|
|
121
|
+
| `liveHandles` | Native handles not yet freed, by kind. A count that only grows points to a leak. |
|
|
122
|
+
|
|
123
|
+
### Tracing
|
|
124
|
+
|
|
125
|
+
Every call that runs on a native thread (`open`, `connect`, `query`, `prepare`, `execute_prepared`, `fetch_chunk` and the others) is published on the [`node:diagnostics_channel`](https://nodejs.org/api/diagnostics_channel.html#class-tracingchannel) tracing channel `duckdb-bun:call`.
|
|
126
|
+
The context has `op`, the binding function name, and `sql` when `DUCKDB_BUN_TRACE_SQL=1`.
|
|
127
|
+
|
|
128
|
+
```ts
|
|
129
|
+
import { tracingChannel } from "node:diagnostics_channel";
|
|
130
|
+
|
|
131
|
+
tracingChannel("duckdb-bun:call").subscribe({
|
|
132
|
+
start: (context) => console.time(context.op),
|
|
133
|
+
asyncEnd: (context) => console.timeEnd(context.op),
|
|
134
|
+
error: (context) => console.error(context.op, context.error),
|
|
135
|
+
});
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
A call costs nothing extra while no subscriber is attached.
|
|
139
|
+
|
|
140
|
+
### SQL redaction
|
|
141
|
+
|
|
142
|
+
SQL text leaves the binding only when `DUCKDB_BUN_TRACE_SQL=1`, and always redacted.
|
|
143
|
+
In a statement that can carry credentials, every string literal becomes `'<redacted>'`.
|
|
144
|
+
That covers `CREATE SECRET`, `ATTACH`, and any statement that names a secret, password, token, credential, key ID, access key, account key, account name or connection string:
|
|
145
|
+
|
|
146
|
+
```sql
|
|
147
|
+
CREATE SECRET s (TYPE s3, KEY_ID '<redacted>', SECRET '<redacted>')
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### Crash reports
|
|
151
|
+
|
|
152
|
+
On a fatal signal (SIGSEGV, SIGBUS, SIGILL, SIGFPE, SIGABRT) the binding writes a report to stderr before Bun's own crash report:
|
|
153
|
+
|
|
154
|
+
```
|
|
155
|
+
[duckdb-bun] fatal signal 11 (SIGSEGV) on thread duckdb-bun:query
|
|
156
|
+
[duckdb-bun] package 1.0.0, duckdb v2.0.0, bun 1.4.4, shim 0.1.0
|
|
157
|
+
[duckdb-bun] in flight: 1 native calls, 1 threads
|
|
158
|
+
[duckdb-bun] last binding events, oldest first:
|
|
159
|
+
[duckdb-bun] #5 +0.009s query event conn=0 handle=0x0 thread=0x1b8849f text="SELECT 1"
|
|
160
|
+
[duckdb-bun] #6 +0.009s query start conn=0 handle=0x9bc93a420 thread=0x1b884dc
|
|
161
|
+
[duckdb-bun] native backtrace:
|
|
162
|
+
…
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
The events come from a ring buffer of the last 256 binding events.
|
|
166
|
+
The process still dies of the original signal, with the same exit status.
|
|
167
|
+
Include the report when you open an issue.
|
|
168
|
+
|
|
169
|
+
## Environment flags
|
|
170
|
+
|
|
171
|
+
| Variable | Effect |
|
|
172
|
+
| --- | --- |
|
|
173
|
+
| `DUCKDB_BUN_DEBUG=1` | Writes one stderr line per native call, with its outcome and duration, plus the loaded library paths. |
|
|
174
|
+
| `DUCKDB_BUN_TRACE_SQL=1` | Adds redacted SQL to the tracing channel context, the debug lines and crash reports. |
|
|
175
|
+
| `DUCKDB_BUN_CRASH_HANDLER=0` | Leaves the fatal-signal handler uninstalled. |
|
|
176
|
+
| `DUCKDB_BUN_LIBRARY_PATH=/path/libduckdb.so` | Loads this libduckdb instead of the platform package's. It must be the same DuckDB version. |
|
|
177
|
+
| `DUCKDB_BUN_OFFLINE=1` | Test suite only: skips the tests that install DuckDB extensions from the network. |
|
|
178
|
+
|
|
179
|
+
## How it works
|
|
180
|
+
|
|
181
|
+
- The official `@duckdb/node-api` code is vendored in `vendor/node-api/src` and runs unmodified, except that its `@duckdb/node-bindings` import points at `src/bindings/`.
|
|
182
|
+
- `src/bindings/` reimplements the `@duckdb/node-bindings` contract over the libduckdb C API with `bun:ffi`.
|
|
183
|
+
Its FFI tables are generated from DuckDB's C API specification (`bun run gen:ffi`).
|
|
184
|
+
- `native/` is a small Rust library, the shim.
|
|
185
|
+
Every C API call from JavaScript goes through a generated C++ wrapper in it that turns a C++ exception from libduckdb into a JavaScript `Error` with DuckDB's message, where it would otherwise abort the process.
|
|
186
|
+
The same wrappers pass the structs that C functions take or return by value, which `bun:ffi` cannot pass.
|
|
187
|
+
It runs every blocking call (open, connect, query, prepare, execute, fetch) on a native thread, so the JS thread never waits for a query.
|
|
188
|
+
It installs the crash handler.
|
|
189
|
+
- Every native pointer is owned by a handle object, freed by a `FinalizationRegistry` or by an explicit close, and never while a native call is using it.
|
|
190
|
+
- A Worker that ends, including through `terminate()` in the middle of a query, interrupts its queries and frees its databases, connections and other handles; the main thread's databases keep working ([ADR 0008](docs/adr/0008-a-worker-closes-its-context-in-an-n-api-cleanup-hook.md)).
|
|
191
|
+
|
|
192
|
+
The design decisions are recorded in [`docs/adr/`](docs/adr/).
|
|
193
|
+
|
|
194
|
+
## Performance
|
|
195
|
+
|
|
196
|
+
Both packages run the same DuckDB, so query time is DuckDB's; the bindings differ only in the calls around it.
|
|
197
|
+
On the Linux CI runner, ours reads results and runs prepared statements faster than the official `@duckdb/node-api`, and is on par or lighter elsewhere.
|
|
198
|
+
The macOS CI runner is noisy and gives mixed results; see below.
|
|
199
|
+
|
|
200
|
+
Linux x64 (GitHub runner, 4 vCPU Intel Xeon Platinum 8573C), Bun 1.4.4, DuckDB 2.0.0, median of 10 runs in ABBA order, [CI run 43148152278](https://github.com/avidianity/duckdb-bun/actions/runs/43148152278):
|
|
201
|
+
|
|
202
|
+
| Scenario | Official | Ours | Ours vs official |
|
|
203
|
+
| --- | --- | --- | --- |
|
|
204
|
+
| `ingest-json`, 1M rows | 220.4 ms | 216.3 ms | on par |
|
|
205
|
+
| `ingest-csv`, 1M rows | 176.6 ms | 170.9 ms | on par; 11% less peak memory (297 vs 334 MiB) |
|
|
206
|
+
| `parquet-write`, 1M rows | 157.7 ms | 124.8 ms | on par; 10% less peak memory (302 vs 334 MiB) |
|
|
207
|
+
| `read-all`, 1M rows to objects | 1039.2 ms | 882.0 ms | 15% faster; 7% more peak memory (1041 vs 969 MiB) |
|
|
208
|
+
| `prepared`, 10,000 bind and run | 580 us per call | 534 us per call | 8% faster |
|
|
209
|
+
| `event-loop-lag`, largest timer gap | 10.7 ms | 10.7 ms | on par |
|
|
210
|
+
|
|
211
|
+
A row claims a difference only where a one-sided Mann-Whitney U test over the 10 runs of each package gives p < 0.01; "on par" means it does not.
|
|
212
|
+
The `parquet-write` time looks 21% faster but gives p = 0.044, so it is not claimed.
|
|
213
|
+
On the macOS runner (3 vCPU, virtualized) runs of one scenario spread by up to 60%.
|
|
214
|
+
In the same CI run there, ours was slower on `ingest-json` (264 vs 205 ms, p = 0.0086) and used more peak memory on `read-all` (821 vs 658 MiB, p = 0.0057), both still inside the gate's 10% limit at 99% confidence.
|
|
215
|
+
On an Apple M5 Mac, both scenarios were on par in time, and `read-all` used 17% more peak memory without reaching p < 0.01.
|
|
216
|
+
A query that runs out of memory (duckdb-node-neo #3060) rejects with DuckDB's `Out of Memory Error` and leaves the process alive in both packages, on Linux in `oven/bun:1.4.4-slim` and on macOS.
|
|
217
|
+
CI fails any change whose bench runs show ours more than 10% slower or 10% heavier than the official package at 99% confidence; [`bench/README.md`](bench/README.md) describes the scenarios and the gate.
|
|
218
|
+
Each CI run uploads its full tables as the `bench-<platform>` artifact.
|
|
219
|
+
|
|
220
|
+
## Known issues
|
|
221
|
+
|
|
222
|
+
- In a `bun build --compile` binary, each Worker that loads the package copies libduckdb and the shim into a new temporary folder and loads its own copy.
|
|
223
|
+
Starting many Workers leaves those folders behind, and the main thread's `diagnostics()` does not count the Workers' native work.
|
|
224
|
+
- A Worker terminated in the few microseconds between a query's native thread starting and DuckDB beginning that query does not interrupt it.
|
|
225
|
+
The query runs to its end before the Worker's handles are freed; nothing crashes or leaks.
|
|
226
|
+
- One process can load the package in at most 4094 Workers over its whole life, because each JS thread takes a context id that is never reused (`native/ABI.md`, `dbs_init`).
|
|
227
|
+
A Worker past that limit throws when it loads the package.
|
|
228
|
+
|
|
229
|
+
## Develop
|
|
230
|
+
|
|
231
|
+
```sh
|
|
232
|
+
bun install
|
|
233
|
+
bun run fetch-lib # libduckdb for the host platform, into packages/duckdb-bun-<platform>/
|
|
234
|
+
bun run build:native # the Rust shim, next to it
|
|
235
|
+
bun run test:official # the vendored @duckdb/node-api suite
|
|
236
|
+
bun run test:bindings # the vendored @duckdb/node-bindings suite
|
|
237
|
+
bun run parity # side-by-side results against the real @duckdb/node-api
|
|
238
|
+
bun run fuzz # generated values and binding calls against the real packages (tests/fuzz/config.ts)
|
|
239
|
+
bun run test:unit # everything else
|
|
240
|
+
bun run bench # benchmarks against the real @duckdb/node-api (bench/README.md)
|
|
241
|
+
bun run check # Biome and the type check
|
|
242
|
+
bun run coverage # line and function coverage of src/ and the shim, with floors (CONTRIBUTING.md)
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
[`CONTRIBUTING.md`](CONTRIBUTING.md) has the rules, and [`MAINTENANCE.md`](MAINTENANCE.md) the upgrade and release procedures.
|
|
246
|
+
|
|
247
|
+
## Native-JS binding
|
|
248
|
+
|
|
249
|
+
An older, narrower binding is available at the `/native-js` subpath.
|
|
250
|
+
It wraps the main API and returns plain JavaScript values: dates as `YYYY-MM-DD` strings, decimals as numbers, and no wrapper objects.
|
|
251
|
+
|
|
252
|
+
```ts
|
|
253
|
+
import { DuckDBInstance } from "@avidian/duckdb-bun/native-js";
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
| DuckDB type | JS value |
|
|
257
|
+
| --- | --- |
|
|
258
|
+
| BOOLEAN | `boolean` |
|
|
259
|
+
| TINYINT to INTEGER, unsigned up to 32 bits | `number` |
|
|
260
|
+
| BIGINT, UBIGINT, HUGEINT, UHUGEINT | `bigint` |
|
|
261
|
+
| FLOAT, DOUBLE, DECIMAL | `number` |
|
|
262
|
+
| VARCHAR, UUID, ENUM, TIME, TIME_TZ, TIME_NS, BIT | `string` |
|
|
263
|
+
| DATE | `string` (`YYYY-MM-DD`) |
|
|
264
|
+
| TIMESTAMP, TIMESTAMP_S, _MS, _NS, _TZ | `Date` |
|
|
265
|
+
| BLOB | `Uint8Array` |
|
|
266
|
+
| INTERVAL | `{ months, days, micros }` |
|
|
267
|
+
| LIST, ARRAY | array |
|
|
268
|
+
| STRUCT | object |
|
|
269
|
+
| MAP | array of `{ key, value }` |
|
|
270
|
+
| NULL | `null` |
|
|
271
|
+
|
|
272
|
+
Values inside LIST, ARRAY, STRUCT and MAP follow the same mapping.
|
|
273
|
+
|
|
274
|
+
## Alternatives
|
|
275
|
+
|
|
276
|
+
If you do not need `bun build --compile`, another driver may fit:
|
|
277
|
+
|
|
278
|
+
| Package | Bun FFI | Embeds libduckdb | Notes |
|
|
279
|
+
| --- | --- | --- | --- |
|
|
280
|
+
| `@avidian/duckdb-bun` (this) | yes | yes | The `@duckdb/node-api` API on Bun, compile-ready. |
|
|
281
|
+
| [`@duckdb/node-api`](https://www.npmjs.com/package/@duckdb/node-api) | no, N-API | no | The official package and the reference this one is tested against. |
|
|
282
|
+
| [`duckdb-bun`](https://github.com/shreeve/duckdb-bun) | yes | no, needs a system libduckdb | Its own driver API. |
|
|
283
|
+
|
|
284
|
+
## License
|
|
285
|
+
|
|
286
|
+
MIT.
|
|
287
|
+
The vendored `@duckdb/node-api` code is MIT, from DuckDB Labs: see [`vendor/node-api/LICENSE`](vendor/node-api/LICENSE).
|
package/package.json
CHANGED
|
@@ -1,6 +1,98 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@avidian/duckdb-bun",
|
|
3
|
-
"version": "
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "1.0.1",
|
|
4
|
+
"description": "Bun-native, drop-in reimplementation of @duckdb/node-api via bun:ffi over the libduckdb C API. Embeds libduckdb so `bun build --compile` yields a self-contained binary.",
|
|
5
|
+
"author": "John Michael Manlupig",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"homepage": "https://github.com/avidianity/duckdb-bun#readme",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/avidianity/duckdb-bun.git"
|
|
11
|
+
},
|
|
12
|
+
"bugs": {
|
|
13
|
+
"url": "https://github.com/avidianity/duckdb-bun/issues"
|
|
14
|
+
},
|
|
15
|
+
"type": "module",
|
|
16
|
+
"module": "src/neo.ts",
|
|
17
|
+
"types": "src/neo.ts",
|
|
18
|
+
"exports": {
|
|
19
|
+
".": "./src/neo.ts",
|
|
20
|
+
"./native-js": "./src/index.ts"
|
|
21
|
+
},
|
|
22
|
+
"publishConfig": {
|
|
23
|
+
"access": "public"
|
|
24
|
+
},
|
|
25
|
+
"files": [
|
|
26
|
+
"src",
|
|
27
|
+
"vendor/node-api/src",
|
|
28
|
+
"vendor/node-api/node-bindings.d.ts",
|
|
29
|
+
"vendor/node-api/LICENSE",
|
|
30
|
+
"vendor/node-api/PROVENANCE.md"
|
|
31
|
+
],
|
|
32
|
+
"workspaces": [
|
|
33
|
+
"packages/*"
|
|
34
|
+
],
|
|
35
|
+
"scripts": {
|
|
36
|
+
"fetch-lib": "bun run scripts/fetch-lib.ts",
|
|
37
|
+
"build:native": "bun run scripts/build-native.ts",
|
|
38
|
+
"bench": "bun run bench/main.ts",
|
|
39
|
+
"test": "bun test",
|
|
40
|
+
"test:official": "bun test tests/official/api.test.ts",
|
|
41
|
+
"test:bindings": "bun test tests/official/bindings.test.ts",
|
|
42
|
+
"parity": "bun test tests/parity.test.ts tests/parity/",
|
|
43
|
+
"fuzz": "bun test tests/fuzz/",
|
|
44
|
+
"fuzz:nightly": "bun run scripts/fuzz-nightly.ts",
|
|
45
|
+
"test:compile": "bun test tests/compile/compile.test.ts",
|
|
46
|
+
"test:leak": "bun test tests/heavy/leak.test.ts",
|
|
47
|
+
"test:stress": "bun test tests/heavy/event-loop-stress.test.ts",
|
|
48
|
+
"test:concurrency": "bun test tests/heavy/concurrency-stress.test.ts",
|
|
49
|
+
"soak": "bun run scripts/soak.ts",
|
|
50
|
+
"test:crash": "bun test tests/heavy/crash-report.test.ts",
|
|
51
|
+
"test:issue-3060": "bun test tests/heavy/issue-3060.test.ts",
|
|
52
|
+
"test:worker-terminate": "bun test tests/heavy/worker-terminate.test.ts",
|
|
53
|
+
"test:unit": "bun test --path-ignore-patterns 'tests/official/**' --path-ignore-patterns 'tests/heavy/**' --path-ignore-patterns 'tests/compile/**' --path-ignore-patterns tests/parity.test.ts --path-ignore-patterns 'tests/parity/**' --path-ignore-patterns 'tests/fuzz/**'",
|
|
54
|
+
"coverage": "bun run scripts/coverage.ts",
|
|
55
|
+
"check-version": "bun run scripts/check-version.ts",
|
|
56
|
+
"first-publish": "bun run scripts/first-publish.ts",
|
|
57
|
+
"lint": "bun --bun biome check src tests scripts examples bench commitlint.config.ts",
|
|
58
|
+
"lint:ci": "bun --bun biome ci src tests scripts examples bench commitlint.config.ts",
|
|
59
|
+
"format": "bun --bun biome format --write src tests scripts examples bench commitlint.config.ts",
|
|
60
|
+
"typecheck": "bun check --no-script -p tsconfig.check.json",
|
|
61
|
+
"check": "bun run lint && bun run typecheck",
|
|
62
|
+
"gen:ffi": "bun run scripts/gen-ffi.ts",
|
|
63
|
+
"vendor:api-spec": "bun run scripts/vendor-api-spec.ts",
|
|
64
|
+
"gen:contract": "bun run scripts/gen-contract.ts",
|
|
65
|
+
"upgrade-duckdb": "bun run scripts/upgrade-duckdb.ts"
|
|
66
|
+
},
|
|
67
|
+
"keywords": [
|
|
68
|
+
"duckdb",
|
|
69
|
+
"bun",
|
|
70
|
+
"ffi",
|
|
71
|
+
"sql",
|
|
72
|
+
"analytics"
|
|
73
|
+
],
|
|
74
|
+
"optionalDependencies": {
|
|
75
|
+
"@avidian/duckdb-bun-darwin-arm64": "1.0.1",
|
|
76
|
+
"@avidian/duckdb-bun-linux-arm64": "1.0.1",
|
|
77
|
+
"@avidian/duckdb-bun-linux-x64": "1.0.1"
|
|
78
|
+
},
|
|
79
|
+
"devDependencies": {
|
|
80
|
+
"@biomejs/biome": "2.6.7",
|
|
81
|
+
"@commitlint/cli": "21.2.4",
|
|
82
|
+
"@commitlint/config-conventional": "21.2.4",
|
|
83
|
+
"@commitlint/types": "21.2.3",
|
|
84
|
+
"@duckdb/node-api": "2.0.0-r.1",
|
|
85
|
+
"@types/bun": "1.4.4",
|
|
86
|
+
"@types/chai": "5.2.3",
|
|
87
|
+
"chai": "6.3.0",
|
|
88
|
+
"fast-check": "4.10.2",
|
|
89
|
+
"lefthook": "2.2.2"
|
|
90
|
+
},
|
|
91
|
+
"trustedDependencies": [
|
|
92
|
+
"lefthook"
|
|
93
|
+
],
|
|
94
|
+
"engines": {
|
|
95
|
+
"bun": "1.4.4"
|
|
96
|
+
},
|
|
97
|
+
"packageManager": "bun@1.4.4"
|
|
98
|
+
}
|