@dolthub/doltlite 0.10.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/README.md ADDED
@@ -0,0 +1,167 @@
1
+ # @dolthub/doltlite
2
+
3
+ Node.js native bindings for [DoltLite](https://github.com/dolthub/doltlite) — a SQLite fork that adds Git-style version control (branches, commits, merges, diffs, blame) to your SQL database.
4
+
5
+ [![CI](https://github.com/dolthub/doltlite-node/actions/workflows/ci.yml/badge.svg)](https://github.com/dolthub/doltlite-node/actions/workflows/ci.yml)
6
+ [![npm](https://img.shields.io/npm/v/@dolthub/doltlite)](https://www.npmjs.com/package/@dolthub/doltlite)
7
+
8
+ ## Install
9
+
10
+ ```bash
11
+ npm install @dolthub/doltlite
12
+ # or
13
+ bun add @dolthub/doltlite
14
+ ```
15
+
16
+ Prebuilt binaries are provided for Linux x64/arm64, macOS x64/arm64, and Windows x64. On unsupported platforms the package builds from source via `node-gyp`, which requires a C/C++ toolchain and Python 3.
17
+
18
+ ## Drop-in compatibility with `node:sqlite`
19
+
20
+ `DatabaseSync` and `StatementSync` match the [Node.js `node:sqlite`](https://nodejs.org/api/sqlite.html) API exactly. Switch by changing one import line:
21
+
22
+ ```diff
23
+ -import { DatabaseSync } from "node:sqlite"
24
+ +import { DatabaseSync } from "@dolthub/doltlite"
25
+ ```
26
+
27
+ ## Basic usage
28
+
29
+ ```ts
30
+ import { DatabaseSync } from "@dolthub/doltlite"
31
+
32
+ const db = new DatabaseSync("myapp.db")
33
+
34
+ db.exec(`CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, name TEXT)`)
35
+
36
+ const insert = db.prepare("INSERT INTO users (name) VALUES (?)")
37
+ insert.run("Alice")
38
+ insert.run("Bob")
39
+
40
+ const all = db.prepare("SELECT * FROM users")
41
+ console.log(all.all())
42
+ // [{ id: 1, name: 'Alice' }, { id: 2, name: 'Bob' }]
43
+
44
+ db.close()
45
+ ```
46
+
47
+ ## Version control
48
+
49
+ All Dolt features are methods on `DatabaseSync` under `dolt*` names:
50
+
51
+ ```ts
52
+ const db = new DatabaseSync("versioned.db")
53
+
54
+ db.exec(`CREATE TABLE orders (id INTEGER PRIMARY KEY, amount REAL)`)
55
+ db.exec(`INSERT INTO orders VALUES (1, 99.99)`)
56
+
57
+ // Commit the current state
58
+ const hash = db.doltCommit("initial data")
59
+
60
+ // Branch and make changes
61
+ db.doltBranch("experiment")
62
+ db.doltCheckout("experiment")
63
+ db.exec(`INSERT INTO orders VALUES (2, 49.99)`)
64
+ db.doltCommit("add order 2")
65
+
66
+ // See what changed
67
+ console.log(db.doltStatus())
68
+ console.log(db.doltLog({ limit: 5 }))
69
+
70
+ // Merge back to main
71
+ db.doltCheckout("main")
72
+ const result = db.doltMerge("experiment")
73
+ console.log(result) // { fast_forward: 0, conflicts: 0 }
74
+
75
+ // Inspect history
76
+ console.log(db.doltDiff("HEAD~1", "HEAD", "orders"))
77
+ console.log(db.doltHistoryOf("orders"))
78
+ console.log(db.doltBlameOf("orders"))
79
+
80
+ // Tag a release
81
+ db.doltTag("v1.0.0")
82
+
83
+ db.close()
84
+ ```
85
+
86
+ You can also call Dolt SQL functions directly if you prefer:
87
+
88
+ ```ts
89
+ db.exec("SELECT dolt_commit('-Am', 'my message')")
90
+ ```
91
+
92
+ ## API
93
+
94
+ ### `new DatabaseSync(path, options?)`
95
+
96
+ | Option | Type | Default | Description |
97
+ |--------|------|---------|-------------|
98
+ | `open` | boolean | `true` | Open immediately |
99
+ | `readOnly` | boolean | `false` | Read-only mode |
100
+
101
+ ### node:sqlite-compatible methods
102
+
103
+ | Method | Description |
104
+ |--------|-------------|
105
+ | `exec(sql)` | Run SQL, no return value |
106
+ | `prepare(sql)` | Compile a `StatementSync` |
107
+ | `close()` | Close the connection |
108
+ | `open(path)` | (Re-)open at path |
109
+ | `location()` | Filesystem path, or `null` for `:memory:` |
110
+ | `createFunction(name, fn)` | Register a scalar UDF |
111
+ | `.isOpen` | `true` if connection is open |
112
+ | `.inTransaction` | `true` if inside a transaction |
113
+
114
+ ### StatementSync
115
+
116
+ | Method | Returns |
117
+ |--------|---------|
118
+ | `run(...params)` | `{ changes, lastInsertRowid }` |
119
+ | `get(...params)` | First row object, or `undefined` |
120
+ | `all(...params)` | All row objects |
121
+ | `iterate(...params)` | `IterableIterator` |
122
+ | `columns()` | Column metadata array |
123
+ | `.sourceSQL` | Original SQL text |
124
+ | `.expandedSQL` | SQL with parameters expanded |
125
+
126
+ ### Dolt methods
127
+
128
+ | Method | Returns | Description |
129
+ |--------|---------|-------------|
130
+ | `doltCommit(message)` | `string` (hash) | Stage all and commit |
131
+ | `doltBranch(name, from?)` | `void` | Create a branch |
132
+ | `doltCheckout(branch)` | `void` | Switch branch |
133
+ | `doltMerge(branch)` | `{ fast_forward, conflicts }` | Merge a branch |
134
+ | `doltReset(flag?)` | `void` | Reset HEAD; pass `"--hard"` for hard reset |
135
+ | `doltAdd(table?)` | `void` | Stage a table, or all tables |
136
+ | `doltStatus()` | `DoltStatusEntry[]` | Working-set status |
137
+ | `doltLog(opts?)` | `DoltCommit[]` | Commit history, newest first |
138
+ | `doltBranches()` | `DoltBranchInfo[]` | All branches |
139
+ | `doltActiveBranch()` | `string` | Currently checked-out branch |
140
+ | `doltDiff(from, to, table)` | `DoltDiffRow[]` | Row-level diff between two refs |
141
+ | `doltHashOf(ref?)` | `string` | Content hash of the DB at a ref |
142
+ | `doltVersion()` | `string` | DoltLite version string |
143
+ | `doltTag(name)` | `void` | Create a tag at HEAD |
144
+ | `doltTags()` | `DoltTagInfo[]` | All tags |
145
+ | `doltHistoryOf(table)` | `object[]` | Full row history across all commits |
146
+ | `doltBlameOf(table)` | `object[]` | Per-row blame |
147
+ | `doltCherryPick(hash)` | `void` | Cherry-pick a commit onto HEAD |
148
+ | `doltRevert(ref?)` | `void` | Revert a commit (default: HEAD) |
149
+
150
+ ## Building from source
151
+
152
+ ```bash
153
+ git clone https://github.com/dolthub/doltlite-node
154
+ cd doltlite-node
155
+ npm install # downloads amalgamation + compiles
156
+ bun test # run the test suite
157
+ ```
158
+
159
+ **Requirements:** Python 3, and a C/C++ compiler (`gcc`/`clang` on Linux/macOS, MSVC Build Tools on Windows).
160
+
161
+ ## Versioning
162
+
163
+ The package version tracks the DoltLite version. `@dolthub/doltlite@0.10.0` ships the DoltLite 0.10.0 amalgamation.
164
+
165
+ ## License
166
+
167
+ Apache-2.0. See [DoltLite](https://github.com/dolthub/doltlite) for the underlying library.
package/binding.gyp ADDED
@@ -0,0 +1,54 @@
1
+ {
2
+ "targets": [
3
+ {
4
+ "target_name": "doltlite",
5
+ "sources": [
6
+ "amalgamation/doltlite_orig.c",
7
+ "amalgamation/doltlite.c",
8
+ "src/addon.cpp",
9
+ "src/database.cpp",
10
+ "src/statement.cpp"
11
+ ],
12
+ "include_dirs": [
13
+ "amalgamation",
14
+ "doltlite-src",
15
+ "doltlite-src/src",
16
+ "doltlite-src/ext/blake3",
17
+ "<!@(node -p \"require('node-addon-api').include\")"
18
+ ],
19
+ "defines": [
20
+ "NAPI_DISABLE_CPP_EXCEPTIONS",
21
+ "SQLITE_THREADSAFE=1",
22
+ "SQLITE_ENABLE_FTS5",
23
+ "SQLITE_ENABLE_JSON1",
24
+ "SQLITE_ENABLE_RTREE",
25
+ "SQLITE_ENABLE_COLUMN_METADATA",
26
+ "DOLTLITE_PROLLY=1"
27
+ ],
28
+ "cflags": ["-std=c11", "-fvisibility=hidden"],
29
+ "cflags_cc": ["-std=c++17", "-fvisibility=hidden"],
30
+ "xcode_settings": {
31
+ "GCC_ENABLE_CPP_EXCEPTIONS": "NO",
32
+ "CLANG_CXX_LANGUAGE_STANDARD": "c++17",
33
+ "MACOSX_DEPLOYMENT_TARGET": "10.15"
34
+ },
35
+ "msvs_settings": {
36
+ "VCCLCompilerTool": {
37
+ "AdditionalOptions": ["/std:c++17"]
38
+ }
39
+ },
40
+ "conditions": [
41
+ ["OS=='linux'", {
42
+ "libraries": ["-lpthread", "-ldl", "-lm"],
43
+ "cflags": ["-fPIC"]
44
+ }],
45
+ ["OS=='mac'", {
46
+ "libraries": ["-lpthread"]
47
+ }],
48
+ ["OS=='win'", {
49
+ "defines": ["strncasecmp=_strnicmp"]
50
+ }]
51
+ ]
52
+ }
53
+ ]
54
+ }
package/index.d.ts ADDED
@@ -0,0 +1,192 @@
1
+ /**
2
+ * @dolthub/doltlite — Node.js bindings for DoltLite
3
+ *
4
+ * `DatabaseSync` and `StatementSync` are intentionally compatible with the
5
+ * Node.js built-in `node:sqlite` module so existing consumers can switch by
6
+ * changing their import. Dolt-specific methods are added under `dolt*` names.
7
+ */
8
+
9
+ export interface ColumnInfo {
10
+ name: string | null
11
+ column: string | null
12
+ table: string | null
13
+ database: string | null
14
+ type: string | null
15
+ }
16
+
17
+ export interface RunResult {
18
+ changes: number
19
+ lastInsertRowid: number
20
+ }
21
+
22
+ export interface MergeResult {
23
+ fast_forward: number
24
+ conflicts: number
25
+ }
26
+
27
+ export interface DoltCommit {
28
+ commit_hash: string
29
+ committer: string
30
+ committer_email: string
31
+ message: string
32
+ date: string
33
+ parents: string
34
+ }
35
+
36
+ export interface DoltBranchInfo {
37
+ name: string
38
+ hash: string
39
+ latest_committer: string
40
+ latest_committer_email: string
41
+ latest_commit_date: string
42
+ latest_commit_message: string
43
+ }
44
+
45
+ export interface DoltStatusEntry {
46
+ table_name: string
47
+ staged: number
48
+ status: string
49
+ }
50
+
51
+ export interface DoltDiffRow {
52
+ from_commit: string
53
+ from_commit_date: string
54
+ to_commit: string
55
+ to_commit_date: string
56
+ diff_type: "added" | "removed" | "modified"
57
+ [column: string]: unknown
58
+ }
59
+
60
+ export interface DoltTagInfo {
61
+ tag_name: string
62
+ tag_hash: string
63
+ tagger: string
64
+ tagger_email: string
65
+ date: string
66
+ message: string
67
+ }
68
+
69
+ export interface DatabaseSyncOptions {
70
+ /** Open the database immediately (default: true). */
71
+ open?: boolean
72
+ /** Open in read-only mode (default: false). */
73
+ readOnly?: boolean
74
+ }
75
+
76
+ export class StatementSync {
77
+ /** Execute the statement and return change metadata. */
78
+ run(...params: unknown[]): RunResult
79
+ /** Return the first result row, or undefined. */
80
+ get(...params: unknown[]): Record<string, unknown> | undefined
81
+ /** Return all result rows. */
82
+ all(...params: unknown[]): Record<string, unknown>[]
83
+ /** Return an iterator over result rows. */
84
+ iterate(...params: unknown[]): IterableIterator<Record<string, unknown>>
85
+ /** Return column metadata for the statement. */
86
+ columns(): ColumnInfo[]
87
+ /** The SQL source text of the statement. */
88
+ readonly sourceSQL: string
89
+ /** The SQL text with bound parameters expanded. */
90
+ readonly expandedSQL: string
91
+ }
92
+
93
+ export class DatabaseSync {
94
+ constructor(path: string, options?: DatabaseSyncOptions)
95
+
96
+ // ── node:sqlite-compatible API ──────────────────────────────────────────
97
+
98
+ /** Execute one or more SQL statements (no result returned). */
99
+ exec(sql: string): void
100
+ /** Compile a SQL statement for repeated execution. */
101
+ prepare(sql: string): StatementSync
102
+ /** Close the database connection. */
103
+ close(): void
104
+ /** (Re-)open the database at the given path. */
105
+ open(path: string): void
106
+ /** Return the filesystem path of the database, or null for :memory:. */
107
+ location(): string | null
108
+ /** Register a user-defined scalar SQL function. */
109
+ createFunction(name: string, fn: (...args: unknown[]) => unknown): void
110
+
111
+ /** True if the database connection is open. */
112
+ readonly isOpen: boolean
113
+ /** True if a transaction is currently active. */
114
+ readonly inTransaction: boolean
115
+
116
+ // ── Dolt version-control API ────────────────────────────────────────────
117
+
118
+ /**
119
+ * Stage all modified tables and create a commit.
120
+ * Returns the new commit hash.
121
+ */
122
+ doltCommit(message: string): string
123
+
124
+ /**
125
+ * Create a new branch, optionally from a specific source branch.
126
+ */
127
+ doltBranch(name: string, fromBranch?: string): void
128
+
129
+ /** Check out an existing branch. */
130
+ doltCheckout(branch: string): void
131
+
132
+ /**
133
+ * Merge a branch into HEAD.
134
+ * Returns `{fast_forward, conflicts}`.
135
+ */
136
+ doltMerge(branch: string): MergeResult
137
+
138
+ /** Reset HEAD. Pass `"--hard"` for a hard reset. */
139
+ doltReset(flag?: "--hard"): void
140
+
141
+ /** Return the working-set status (staged/unstaged changes). */
142
+ doltStatus(): DoltStatusEntry[]
143
+
144
+ /** Return commit history, newest first. */
145
+ doltLog(options?: { limit?: number }): DoltCommit[]
146
+
147
+ /** Return all branches. */
148
+ doltBranches(): DoltBranchInfo[]
149
+
150
+ /** Return the name of the currently active branch. */
151
+ doltActiveBranch(): string
152
+
153
+ /**
154
+ * Stage a table (or all tables if no argument) for the next commit.
155
+ */
156
+ doltAdd(table?: string): void
157
+
158
+ /**
159
+ * Return row-level diff between two refs for a given table.
160
+ */
161
+ doltDiff(fromRef: string, toRef: string, table: string): DoltDiffRow[]
162
+
163
+ /** Return the content hash of the database at a ref (default: HEAD). */
164
+ doltHashOf(ref?: string): string
165
+
166
+ /** Return the DoltLite version string. */
167
+ doltVersion(): string
168
+
169
+ /** Create a tag at HEAD. */
170
+ doltTag(name: string): void
171
+
172
+ /** Return all tags. */
173
+ doltTags(): DoltTagInfo[]
174
+
175
+ /**
176
+ * Return the full history of rows in a table across all commits.
177
+ * Equivalent to `SELECT * FROM dolt_history_<table>`.
178
+ */
179
+ doltHistoryOf(table: string): Record<string, unknown>[]
180
+
181
+ /**
182
+ * Return blame information for a table — which commit last modified each row.
183
+ * Equivalent to `SELECT * FROM dolt_blame_<table>`.
184
+ */
185
+ doltBlameOf(table: string): Record<string, unknown>[]
186
+
187
+ /** Cherry-pick a commit onto HEAD. */
188
+ doltCherryPick(commitHash: string): void
189
+
190
+ /** Revert a commit (default: HEAD). */
191
+ doltRevert(ref?: string): void
192
+ }
package/index.js ADDED
@@ -0,0 +1,27 @@
1
+ "use strict"
2
+
3
+ const path = require("path")
4
+
5
+ // Try a prebuilt binary first (shipped with published packages),
6
+ // then fall back to a locally compiled build.
7
+ function loadAddon() {
8
+ const platform = process.platform
9
+ const arch = process.arch
10
+ const prebuilt = path.join(__dirname, "prebuilds", `${platform}-${arch}`, "doltlite.node")
11
+ const compiled = path.join(__dirname, "build", "Release", "doltlite.node")
12
+
13
+ for (const candidate of [prebuilt, compiled]) {
14
+ try {
15
+ return require(candidate)
16
+ } catch {}
17
+ }
18
+
19
+ throw new Error(
20
+ `@dolthub/doltlite: no native binary found for ${platform}-${arch}.\n` +
21
+ `Run \`npm install\` to build from source, or file an issue at ` +
22
+ `https://github.com/dolthub/doltlite-node/issues`
23
+ )
24
+ }
25
+
26
+ const { DatabaseSync, StatementSync } = loadAddon()
27
+ module.exports = { DatabaseSync, StatementSync }
package/package.json ADDED
@@ -0,0 +1,51 @@
1
+ {
2
+ "name": "@dolthub/doltlite",
3
+ "version": "0.10.0",
4
+ "description": "Node.js bindings for DoltLite — a SQLite fork with Git-style version control",
5
+ "license": "Apache-2.0",
6
+ "main": "index.js",
7
+ "types": "index.d.ts",
8
+ "type": "commonjs",
9
+ "files": [
10
+ "index.js",
11
+ "index.d.ts",
12
+ "src/",
13
+ "binding.gyp",
14
+ "scripts/download.js",
15
+ "prebuilds/"
16
+ ],
17
+ "scripts": {
18
+ "install": "node scripts/download.js && node-gyp rebuild",
19
+ "build": "node-gyp rebuild",
20
+ "build:debug": "node-gyp rebuild --debug",
21
+ "test": "bun test test/",
22
+ "test:watch": "bun test --watch test/"
23
+ },
24
+ "dependencies": {
25
+ "node-addon-api": "^8.0.0"
26
+ },
27
+ "devDependencies": {
28
+ "@types/node": "^22.0.0",
29
+ "bun-types": "latest"
30
+ },
31
+ "engines": {
32
+ "node": ">=18.0.0"
33
+ },
34
+ "keywords": [
35
+ "sqlite",
36
+ "dolt",
37
+ "doltlite",
38
+ "database",
39
+ "version-control",
40
+ "sql",
41
+ "git"
42
+ ],
43
+ "repository": {
44
+ "type": "git",
45
+ "url": "https://github.com/dolthub/doltlite-node.git"
46
+ },
47
+ "bugs": {
48
+ "url": "https://github.com/dolthub/doltlite-node/issues"
49
+ },
50
+ "homepage": "https://github.com/dolthub/doltlite-node#readme"
51
+ }
@@ -0,0 +1,87 @@
1
+ #!/usr/bin/env node
2
+ // Downloads the doltlite autoconf source tarball from GitHub releases and
3
+ // builds a complete amalgamation from it.
4
+ //
5
+ // The autoconf tarball contains both sqlite3.c (the base SQLite amalgamation
6
+ // with doltlite's storage patches) and the prolly tree + dolt SQL function
7
+ // source files under src/. We stitch them into a single doltlite.c that,
8
+ // when compiled with -DDOLTLITE_PROLLY=1, has full version-control support.
9
+
10
+ "use strict"
11
+
12
+ const https = require("https")
13
+ const fs = require("fs")
14
+ const path = require("path")
15
+ const { execSync } = require("child_process")
16
+
17
+ const pkg = require("../package.json")
18
+ const version = pkg.version
19
+
20
+ const amalgDir = path.join(__dirname, "../amalgamation")
21
+ const outC = path.join(amalgDir, "doltlite.c")
22
+ const outH = path.join(amalgDir, "doltlite.h")
23
+ const srcRoot = path.join(__dirname, "../doltlite-src")
24
+
25
+ // Skip if already built.
26
+ if (fs.existsSync(outC) && fs.existsSync(outH)) {
27
+ process.exit(0)
28
+ }
29
+
30
+ const tarballUrl = `https://github.com/dolthub/doltlite/releases/download/v${version}/doltlite-autoconf-${version}.tar.gz`
31
+ const tarballPath = path.join(__dirname, `../doltlite-autoconf-${version}.tar.gz`)
32
+
33
+ console.log(`Downloading doltlite source v${version}...`)
34
+
35
+ function download(url, dest, cb) {
36
+ const file = fs.createWriteStream(dest)
37
+ function get(url) {
38
+ https.get(url, (res) => {
39
+ if (res.statusCode === 301 || res.statusCode === 302) {
40
+ return get(res.headers.location)
41
+ }
42
+ if (res.statusCode !== 200) {
43
+ cb(new Error(`HTTP ${res.statusCode} downloading ${url}`))
44
+ return
45
+ }
46
+ res.pipe(file)
47
+ file.on("finish", () => file.close(cb))
48
+ }).on("error", cb)
49
+ }
50
+ get(url)
51
+ }
52
+
53
+ download(tarballUrl, tarballPath, (err) => {
54
+ if (err) {
55
+ console.error("Failed to download doltlite source:", err.message)
56
+ process.exit(1)
57
+ }
58
+
59
+ try {
60
+ fs.rmSync(srcRoot, { recursive: true, force: true })
61
+ fs.mkdirSync(srcRoot, { recursive: true })
62
+
63
+ // Extract tarball — tar is available on Linux, macOS, and Windows 10+.
64
+ execSync(`tar xzf "${tarballPath}" -C "${srcRoot}"`, { stdio: "inherit" })
65
+ fs.unlinkSync(tarballPath)
66
+
67
+ // The tarball nests everything under doltlite-autoconf-${version}/.
68
+ // Flatten it so doltlite-src/src/ and doltlite-src/sqlite3.c are the
69
+ // canonical paths that build-amalgamation.js expects.
70
+ const entries = fs.readdirSync(srcRoot)
71
+ if (entries.length === 1 && fs.statSync(path.join(srcRoot, entries[0])).isDirectory()) {
72
+ const subdir = path.join(srcRoot, entries[0])
73
+ for (const f of fs.readdirSync(subdir)) {
74
+ fs.renameSync(path.join(subdir, f), path.join(srcRoot, f))
75
+ }
76
+ fs.rmdirSync(subdir)
77
+ }
78
+
79
+ // Build the complete amalgamation.
80
+ execSync(`node "${path.join(__dirname, "build-amalgamation.js")}"`, { stdio: "inherit" })
81
+
82
+ console.log("Source ready.")
83
+ } catch (e) {
84
+ console.error("Failed to prepare doltlite source:", e.message)
85
+ process.exit(1)
86
+ }
87
+ })
package/src/addon.cpp ADDED
@@ -0,0 +1,15 @@
1
+ #include "database.h"
2
+ #include "statement.h"
3
+
4
+ extern "C" int doltliteInstallAutoExt(void);
5
+
6
+ Napi::Object Init(Napi::Env env, Napi::Object exports) {
7
+ doltliteInstallAutoExt();
8
+ // StatementSync must be initialised first so its constructor_ is set before
9
+ // Database::Prepare() can call Statement::Create().
10
+ Statement::Init(env, exports);
11
+ Database::Init(env, exports);
12
+ return exports;
13
+ }
14
+
15
+ NODE_API_MODULE(doltlite, Init)