@avidian/duckdb-bun 0.0.0-stage → 1.0.0
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 +284 -2
- package/package.json +95 -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 +200 -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 +150 -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/src/errors.ts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// A real Error subclass so callers can keep
|
|
2
|
+
// using `err instanceof Error` and message regex checks (e.g. /Out of Memory/i).
|
|
3
|
+
export class DuckDBError extends Error {
|
|
4
|
+
readonly duckdbMessage: string;
|
|
5
|
+
constructor(message: string, options?: ErrorOptions) {
|
|
6
|
+
super(message, options);
|
|
7
|
+
this.name = "DuckDBError";
|
|
8
|
+
this.duckdbMessage = message;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/** Runs `action`, rethrowing any error as a DuckDBError with the same message and the original as its cause. */
|
|
13
|
+
export async function asDuckDBError<T>(action: () => Promise<T>): Promise<T> {
|
|
14
|
+
try {
|
|
15
|
+
return await action();
|
|
16
|
+
} catch (error) {
|
|
17
|
+
if (error instanceof DuckDBError) throw error;
|
|
18
|
+
throw new DuckDBError(error instanceof Error ? error.message : String(error), { cause: error });
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/** The synchronous form of asDuckDBError. */
|
|
23
|
+
export function asDuckDBErrorSync<T>(action: () => T): T {
|
|
24
|
+
try {
|
|
25
|
+
return action();
|
|
26
|
+
} catch (error) {
|
|
27
|
+
if (error instanceof DuckDBError) throw error;
|
|
28
|
+
throw new DuckDBError(error instanceof Error ? error.message : String(error), { cause: error });
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// Files imported with `with { type: "file" }` resolve to their path at run time
|
|
2
|
+
// (and to their /$bunfs/ path inside a `bun build --compile` executable).
|
|
3
|
+
declare module "*.so" {
|
|
4
|
+
const path: string;
|
|
5
|
+
export default path;
|
|
6
|
+
}
|
|
7
|
+
declare module "*.dylib" {
|
|
8
|
+
const path: string;
|
|
9
|
+
export default path;
|
|
10
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// The native-JS binding: a narrow API over the same bindings as the main entry,
|
|
2
|
+
// returning plain JavaScript values (README.md, "Native-JS binding").
|
|
3
|
+
|
|
4
|
+
export { DuckDBConnection } from "./connection.ts";
|
|
5
|
+
export { DuckDBInstance } from "./database.ts";
|
|
6
|
+
export { DuckDBError } from "./errors.ts";
|
|
7
|
+
export { Reader } from "./reader.ts";
|
|
8
|
+
export { PreparedStatement } from "./statement.ts";
|
|
9
|
+
export type { ColumnType, QueryResultShape } from "./types.ts";
|
|
10
|
+
export { DuckDBType } from "./types.ts";
|
|
11
|
+
|
|
12
|
+
import { version } from "../vendor/node-api/src/index.ts";
|
|
13
|
+
|
|
14
|
+
/** The linked libduckdb version, e.g. "v2.0.0". */
|
|
15
|
+
export function libraryVersion(): string {
|
|
16
|
+
return version();
|
|
17
|
+
}
|
package/src/library.ts
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
// Resolves the two native libraries: libduckdb and the Rust shim
|
|
2
|
+
// (libduckdb_bun_shim), both shipped in the optional platform package for this
|
|
3
|
+
// platform (@avidian/duckdb-bun-<platform>), the way @duckdb/node-api ships its
|
|
4
|
+
// native addon.
|
|
5
|
+
//
|
|
6
|
+
// Resolution is synchronous so the bindings module has no top-level await and
|
|
7
|
+
// stays loadable through require(), which worker_threads and CommonJS callers
|
|
8
|
+
// use.
|
|
9
|
+
//
|
|
10
|
+
// The shim links libduckdb and finds it beside itself through its rpath
|
|
11
|
+
// ($ORIGIN, @loader_path). Two cases copy both libraries side by side into a
|
|
12
|
+
// fresh temporary directory, so the shim and JavaScript load one and the same
|
|
13
|
+
// libduckdb: DUCKDB_BUN_LIBRARY_PATH, which overrides libduckdb with one of the
|
|
14
|
+
// same DuckDB version, and a `bun build --compile` executable, whose files live
|
|
15
|
+
// in Bun's virtual `/$bunfs/` filesystem that dlopen cannot read.
|
|
16
|
+
import { mkdtempSync, readFileSync, writeFileSync } from "node:fs";
|
|
17
|
+
import { tmpdir } from "node:os";
|
|
18
|
+
import { basename, join } from "node:path";
|
|
19
|
+
|
|
20
|
+
export interface NativePaths {
|
|
21
|
+
/** Absolute path to libduckdb. */
|
|
22
|
+
libPath: string;
|
|
23
|
+
/** Absolute path to the shim cdylib, built from native/. */
|
|
24
|
+
shimPath: string;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
interface PlatformPackage {
|
|
28
|
+
default: string;
|
|
29
|
+
shimPath: string;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const SUPPORTED = "the supported platforms are linux-x64 (glibc), linux-arm64 (glibc) and darwin-arm64";
|
|
33
|
+
|
|
34
|
+
function load(name: string, require: () => unknown): PlatformPackage {
|
|
35
|
+
try {
|
|
36
|
+
return require() as PlatformPackage;
|
|
37
|
+
} catch (cause) {
|
|
38
|
+
throw new Error(`duckdb-bun: the optional package ${name} is not installed. Reinstall without --no-optional.`, {
|
|
39
|
+
cause,
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function platformPackage(): PlatformPackage {
|
|
45
|
+
// Each test reads process.platform and process.arch directly: `bun build --compile`
|
|
46
|
+
// folds them to constants, so it embeds the target's package and skips the others,
|
|
47
|
+
// whose native files are absent on this machine.
|
|
48
|
+
if (process.platform === "linux" && process.arch === "x64") {
|
|
49
|
+
return load("@avidian/duckdb-bun-linux-x64", () => require("@avidian/duckdb-bun-linux-x64"));
|
|
50
|
+
}
|
|
51
|
+
if (process.platform === "linux" && process.arch === "arm64") {
|
|
52
|
+
return load("@avidian/duckdb-bun-linux-arm64", () => require("@avidian/duckdb-bun-linux-arm64"));
|
|
53
|
+
}
|
|
54
|
+
if (process.platform === "darwin" && process.arch === "arm64") {
|
|
55
|
+
return load("@avidian/duckdb-bun-darwin-arm64", () => require("@avidian/duckdb-bun-darwin-arm64"));
|
|
56
|
+
}
|
|
57
|
+
throw new Error(`duckdb-bun: no native package for ${process.platform}-${process.arch}; ${SUPPORTED}.`);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function copyTo(dir: string, path: string, name = basename(path)): string {
|
|
61
|
+
const target = join(dir, name);
|
|
62
|
+
writeFileSync(target, readFileSync(path));
|
|
63
|
+
return target;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
let cached: NativePaths | undefined;
|
|
67
|
+
|
|
68
|
+
export function nativePaths(): NativePaths {
|
|
69
|
+
if (cached) return cached;
|
|
70
|
+
const pkg = platformPackage();
|
|
71
|
+
const override = process.env.DUCKDB_BUN_LIBRARY_PATH;
|
|
72
|
+
if (!override && !pkg.default.startsWith("/$bunfs/")) {
|
|
73
|
+
cached = { libPath: pkg.default, shimPath: pkg.shimPath };
|
|
74
|
+
return cached;
|
|
75
|
+
}
|
|
76
|
+
const dir = mkdtempSync(join(tmpdir(), "duckdb-bun-"));
|
|
77
|
+
cached = {
|
|
78
|
+
// Under the file name the shim links against, whatever the override is called.
|
|
79
|
+
libPath: copyTo(dir, override || pkg.default, basename(pkg.default)),
|
|
80
|
+
shimPath: copyTo(dir, pkg.shimPath),
|
|
81
|
+
};
|
|
82
|
+
return cached;
|
|
83
|
+
}
|
package/src/neo.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// Public entry for the drop-in `@duckdb/node-api` replacement. Re-exports the full
|
|
2
|
+
// vendored official TypeScript API (running over our bun:ffi bindings), so:
|
|
3
|
+
//
|
|
4
|
+
// import { DuckDBInstance } from "@avidian/duckdb-bun";
|
|
5
|
+
//
|
|
6
|
+
// behaves like `@duckdb/node-api`, with the same classes and value objects, but
|
|
7
|
+
// embeds libduckdb, so `bun build --compile` yields a self-contained binary.
|
|
8
|
+
//
|
|
9
|
+
// It adds diagnostics(), DUCKDB_VERSION and the "duckdb-bun:call" tracing channel (README.md).
|
|
10
|
+
// The narrow, native-JS binding is still available at `@avidian/duckdb-bun/native-js`.
|
|
11
|
+
export * from "../vendor/node-api/src/index.ts";
|
|
12
|
+
export { default } from "../vendor/node-api/src/index.ts";
|
|
13
|
+
export { type Diagnostics, diagnostics } from "./bindings/runtime/diagnostics.ts";
|
|
14
|
+
export type { CallContext } from "./bindings/runtime/trace.ts";
|
|
15
|
+
/** The DuckDB version this package bundles, such as "2.0.0". */
|
|
16
|
+
export { DUCKDB_VERSION } from "./version.ts";
|
package/src/reader.ts
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
// The native-JS value mapping over the vendored @duckdb/node-api reader: the
|
|
2
|
+
// official JS converter, except that DATE, TIME, TIME_TZ, TIME_NS and BIT come
|
|
3
|
+
// back as their SQL text (DATE as YYYY-MM-DD). Nested values use the same mapping.
|
|
4
|
+
import {
|
|
5
|
+
type DuckDBResultReader,
|
|
6
|
+
DuckDBTypeId,
|
|
7
|
+
type DuckDBValueConverter,
|
|
8
|
+
JSDuckDBValueConverter,
|
|
9
|
+
} from "../vendor/node-api/src/index.ts";
|
|
10
|
+
|
|
11
|
+
const AS_TEXT = new Set<DuckDBTypeId>([
|
|
12
|
+
DuckDBTypeId.DATE,
|
|
13
|
+
DuckDBTypeId.TIME,
|
|
14
|
+
DuckDBTypeId.TIME_TZ,
|
|
15
|
+
DuckDBTypeId.TIME_NS,
|
|
16
|
+
DuckDBTypeId.BIT,
|
|
17
|
+
]);
|
|
18
|
+
|
|
19
|
+
const nativeJsConverter: DuckDBValueConverter<unknown> = (value, type, converter) => {
|
|
20
|
+
if (value === null) return null;
|
|
21
|
+
if (AS_TEXT.has(type.typeId)) return String(value);
|
|
22
|
+
return JSDuckDBValueConverter(value, type, converter as never);
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
/** A materialized query result. Mirrors the slice of @duckdb/node-api's reader used downstream. */
|
|
26
|
+
export class Reader {
|
|
27
|
+
#columns: string[];
|
|
28
|
+
#rows: Record<string, unknown>[];
|
|
29
|
+
constructor(columns: string[], rows: Record<string, unknown>[]) {
|
|
30
|
+
this.#columns = columns;
|
|
31
|
+
this.#rows = rows;
|
|
32
|
+
}
|
|
33
|
+
columnNames(): string[] {
|
|
34
|
+
return this.#columns;
|
|
35
|
+
}
|
|
36
|
+
getRowObjects(): Record<string, unknown>[] {
|
|
37
|
+
return this.#rows;
|
|
38
|
+
}
|
|
39
|
+
get rowCount(): number {
|
|
40
|
+
return this.#rows.length;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/** Converts a fully read official reader into a native-JS Reader. */
|
|
45
|
+
export function readerFrom(reader: DuckDBResultReader): Reader {
|
|
46
|
+
return new Reader(reader.columnNames(), reader.convertRowObjects(nativeJsConverter) as Record<string, unknown>[]);
|
|
47
|
+
}
|
package/src/statement.ts
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import type { DuckDBPreparedStatement } from "../vendor/node-api/src/index.ts";
|
|
2
|
+
import { asDuckDBError, asDuckDBErrorSync } from "./errors.ts";
|
|
3
|
+
import { type Reader, readerFrom } from "./reader.ts";
|
|
4
|
+
|
|
5
|
+
const INT64_MIN = -9_223_372_036_854_775_808n;
|
|
6
|
+
const INT64_MAX = 9_223_372_036_854_775_807n;
|
|
7
|
+
|
|
8
|
+
/** A prepared statement with 1-based parameter binding. */
|
|
9
|
+
export class PreparedStatement {
|
|
10
|
+
#statement: DuckDBPreparedStatement;
|
|
11
|
+
#closed = false;
|
|
12
|
+
|
|
13
|
+
constructor(statement: DuckDBPreparedStatement) {
|
|
14
|
+
this.#statement = statement;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/** Number of `?` parameters in the statement. */
|
|
18
|
+
get paramCount(): number {
|
|
19
|
+
return this.#statement.parameterCount;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/** Bind a single 1-based parameter, dispatching by JS type. */
|
|
23
|
+
bind(index: number, value: unknown): this {
|
|
24
|
+
const statement = this.#statement;
|
|
25
|
+
asDuckDBErrorSync(() => {
|
|
26
|
+
if (value === null || value === undefined) statement.bindNull(index);
|
|
27
|
+
else if (typeof value === "boolean") statement.bindBoolean(index, value);
|
|
28
|
+
else if (typeof value === "bigint") {
|
|
29
|
+
if (value >= INT64_MIN && value <= INT64_MAX) statement.bindBigInt(index, value);
|
|
30
|
+
else statement.bindVarchar(index, value.toString());
|
|
31
|
+
} else if (typeof value === "number") {
|
|
32
|
+
if (Number.isSafeInteger(value)) statement.bindBigInt(index, BigInt(value));
|
|
33
|
+
else statement.bindDouble(index, value);
|
|
34
|
+
} else if (value instanceof Date) statement.bindVarchar(index, value.toISOString());
|
|
35
|
+
else statement.bindVarchar(index, String(value));
|
|
36
|
+
});
|
|
37
|
+
return this;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/** Bind all parameters positionally (1-based under the hood). */
|
|
41
|
+
bindAll(values: unknown[]): this {
|
|
42
|
+
for (let i = 0; i < values.length; i++) this.bind(i + 1, values[i]);
|
|
43
|
+
return this;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/** Execute and discard the result. */
|
|
47
|
+
async run(): Promise<void> {
|
|
48
|
+
await asDuckDBError(() => this.#statement.run());
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/** Execute and read every row. */
|
|
52
|
+
async readAll(): Promise<Reader> {
|
|
53
|
+
return readerFrom(await asDuckDBError(() => this.#statement.runAndReadAll()));
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
close(): void {
|
|
57
|
+
if (this.#closed) return;
|
|
58
|
+
this.#statement.destroySync();
|
|
59
|
+
this.#closed = true;
|
|
60
|
+
}
|
|
61
|
+
}
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
// Mirror of the `DUCKDB_TYPE` enum from vendor/duckdb.h.
|
|
2
|
+
export const DuckDBType = {
|
|
3
|
+
INVALID: 0,
|
|
4
|
+
BOOLEAN: 1,
|
|
5
|
+
TINYINT: 2,
|
|
6
|
+
SMALLINT: 3,
|
|
7
|
+
INTEGER: 4,
|
|
8
|
+
BIGINT: 5,
|
|
9
|
+
UTINYINT: 6,
|
|
10
|
+
USMALLINT: 7,
|
|
11
|
+
UINTEGER: 8,
|
|
12
|
+
UBIGINT: 9,
|
|
13
|
+
FLOAT: 10,
|
|
14
|
+
DOUBLE: 11,
|
|
15
|
+
TIMESTAMP: 12,
|
|
16
|
+
DATE: 13,
|
|
17
|
+
TIME: 14,
|
|
18
|
+
INTERVAL: 15,
|
|
19
|
+
HUGEINT: 16,
|
|
20
|
+
VARCHAR: 17,
|
|
21
|
+
BLOB: 18,
|
|
22
|
+
DECIMAL: 19,
|
|
23
|
+
TIMESTAMP_S: 20,
|
|
24
|
+
TIMESTAMP_MS: 21,
|
|
25
|
+
TIMESTAMP_NS: 22,
|
|
26
|
+
ENUM: 23,
|
|
27
|
+
LIST: 24,
|
|
28
|
+
STRUCT: 25,
|
|
29
|
+
MAP: 26,
|
|
30
|
+
UUID: 27,
|
|
31
|
+
BIT: 29,
|
|
32
|
+
TIME_TZ: 30,
|
|
33
|
+
TIMESTAMP_TZ: 31,
|
|
34
|
+
UHUGEINT: 32,
|
|
35
|
+
ARRAY: 33,
|
|
36
|
+
BIGNUM: 35,
|
|
37
|
+
SQLNULL: 36,
|
|
38
|
+
} as const;
|
|
39
|
+
|
|
40
|
+
// Metadata needed to decode a result column: its type id plus (for DECIMAL) the
|
|
41
|
+
// scale and the integer storage type the decimal is stored as.
|
|
42
|
+
export interface ColumnType {
|
|
43
|
+
id: number;
|
|
44
|
+
scale?: number;
|
|
45
|
+
internal?: number;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export interface QueryResultShape {
|
|
49
|
+
columns: string[];
|
|
50
|
+
rows: Record<string, unknown>[];
|
|
51
|
+
rowCount: number;
|
|
52
|
+
}
|
package/src/version.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
// Single source of truth for the DuckDB version this binding targets. Bump this
|
|
2
|
+
// when upgrading, then re-run `bun run fetch-lib`. See MAINTENANCE.md.
|
|
3
|
+
export const DUCKDB_VERSION = "2.0.0";
|
|
4
|
+
|
|
5
|
+
/** The version tag as it appears on GitHub releases and from duckdb_library_version(). */
|
|
6
|
+
export const DUCKDB_VERSION_TAG = `v${DUCKDB_VERSION}`;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
Copyright 2018-2025 Stichting DuckDB Foundation
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
4
|
+
|
|
5
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
6
|
+
|
|
7
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# Vendored `@duckdb/node-api` and `@duckdb/node-bindings` tests
|
|
2
|
+
|
|
3
|
+
These trees are copied **verbatim** from the official DuckDB Node "Neo" monorepo.
|
|
4
|
+
We reimplement the bindings over `bun:ffi` and prove parity against the official test suites.
|
|
5
|
+
|
|
6
|
+
| | |
|
|
7
|
+
| ------------------------------- | --------------------------------------------------------------------- |
|
|
8
|
+
| Upstream repo | https://github.com/duckdb/duckdb-node-neo |
|
|
9
|
+
| Tag | `v2.0.0-r.1` |
|
|
10
|
+
| Commit | `769e55196b7e68c953c72618adbce553d54b777d` |
|
|
11
|
+
| `@duckdb/node-api` version | `2.0.0-r.1` |
|
|
12
|
+
| `@duckdb/node-bindings` version | `2.0.0-r.1` (DuckDB core v2.0.0) |
|
|
13
|
+
| License | MIT, see `./LICENSE` and `../node-bindings/LICENSE` |
|
|
14
|
+
|
|
15
|
+
## Layout
|
|
16
|
+
|
|
17
|
+
- `src/` is copied from `api/src/`.
|
|
18
|
+
It is the full TypeScript API layer, **unmodified on disk** except for the import rewrite described below.
|
|
19
|
+
- `test/` is copied from `api/test/`.
|
|
20
|
+
It is the official `@duckdb/node-api` Vitest suite, with `util/` and `bench/`; we do not run `bench/`.
|
|
21
|
+
It is **unmodified on disk**.
|
|
22
|
+
- `node-bindings.d.ts` is copied from `bindings/pkgs/@duckdb/node-bindings/duckdb.d.ts`.
|
|
23
|
+
It is the exact interface contract that our `src/bindings/` reimplements, and the source of truth for `scripts/gen-contract.ts`.
|
|
24
|
+
- `../node-bindings/test/` is copied from `bindings/test/`.
|
|
25
|
+
It is the official `@duckdb/node-bindings` Vitest suite, with `utils/`, `fixtures/` and `stress/`.
|
|
26
|
+
It is **unmodified on disk**.
|
|
27
|
+
- `../node-bindings/LICENSE` is the upstream license that covers the bindings tests.
|
|
28
|
+
|
|
29
|
+
## How it's wired
|
|
30
|
+
|
|
31
|
+
- The `@duckdb/node-bindings` imports in `src/` are rewritten **on disk** to a relative import of our `src/bindings/` by `scripts/vendor-rewrite-bindings.ts`.
|
|
32
|
+
That is the only modification against upstream; every other line is byte-identical.
|
|
33
|
+
It makes the published package a plugin-free drop-in: consumers `import { DuckDBInstance } from '@avidian/duckdb-bun'`, and the vendored layer loads our `bun:ffi` bindings directly, with nothing else in the resolution path.
|
|
34
|
+
- The `vitest` imports in both test suites can't be rewritten on disk the same way, because they would need `vitest` installed for the editor and the type checker.
|
|
35
|
+
`bun test` also hard-remaps `vitest` to `bun:test`, which lacks an `assert` export, before tsconfig `paths` or a plugin `onResolve` run.
|
|
36
|
+
So `tests/preload.ts` uses an **`onLoad`** plugin, scoped to the two `test/` directories, that rewrites `vitest` to `tests/vitest-shim.ts` at load time.
|
|
37
|
+
The shim re-exports the `bun:test` runner primitives and chai's `assert`, which is what vitest's `assert` is.
|
|
38
|
+
- The same `onLoad` plugin rewrites the bindings suite's ESM `@duckdb/node-bindings` imports to our `src/bindings/`.
|
|
39
|
+
- The bindings suite also resolves `@duckdb/node-bindings` through CommonJS: `worker_threads.test.ts` calls `createRequire(...).resolve()`, and `scalar_function_exit.test.ts` spawns `bun` on `fixtures/scalarFunctionExit.cjs`, which calls `require()`.
|
|
40
|
+
`tests/node-bindings-resolve.ts` overrides `Module._resolveFilename` for requests from `../node-bindings/test/`, and `tests/preload.ts` loads it in the test process and adds it to `BUN_OPTIONS` for every spawned `bun` process.
|
|
41
|
+
- `tests/official/api.test.ts` (`bun run test:official`) and `tests/official/bindings.test.ts` (`bun run test:bindings`) import every test file of the respective suite.
|
|
42
|
+
`bindings.test.ts` leaves out `stress/`, which is heavy and runs one file at a time.
|
|
43
|
+
|
|
44
|
+
## Updating (on a DuckDB version bump)
|
|
45
|
+
|
|
46
|
+
`scripts/upgrade-duckdb.ts` (`bun run upgrade-duckdb`) does steps 1 to 5 and updates the table above; MAINTENANCE.md "Upgrading DuckDB" describes when it runs.
|
|
47
|
+
|
|
48
|
+
1. Check out the upstream tag `v<version>` whose `api/pkgs/@duckdb/node-api/package.json` carries the new `@duckdb/node-api` version, built on the new `DUCKDB_VERSION` pin (`src/version.ts`).
|
|
49
|
+
2. Re-copy `api/src` to `src/`, `api/test` to `test/`, `bindings/test` to `../node-bindings/test/`, `LICENSE` to both `LICENSE` files, and the bindings `duckdb.d.ts` to `node-bindings.d.ts`.
|
|
50
|
+
3. Run `bun run scripts/vendor-rewrite-bindings.ts` to rewrite the `@duckdb/node-bindings` imports to our bindings; it is idempotent.
|
|
51
|
+
4. Add any new bindings test file to `tests/official/bindings.test.ts`, and any new API test file to `tests/official/api.test.ts`.
|
|
52
|
+
5. Run `bun run gen:contract` to regenerate `src/bindings/generated/contract.ts` from `node-bindings.d.ts`.
|
|
53
|
+
6. Implement any newly added binding functions.
|
|
54
|
+
Verify with `bun run test:official` and `bun run test:bindings`.
|