git-sqlite-vfs 0.0.9 → 0.0.11
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 +27 -29
- package/index.js +8 -0
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -1,42 +1,40 @@
|
|
|
1
1
|
# git-sqlite-vfs
|
|
2
2
|
|
|
3
|
-
A Git-
|
|
3
|
+
A Git-versioned SQLite database utilizing a custom Virtual File System (VFS).
|
|
4
4
|
|
|
5
|
-
By
|
|
5
|
+
By integrating SQLite, Drizzle ORM, and libSQL with Git, `git-sqlite-vfs` enables versioning, diffing, and merging of SQLite databases. It is compatible with Node.js and Deno.
|
|
6
6
|
|
|
7
7
|
## Architecture
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Standard SQLite databases are stored as a single file. This limits version control compatibility, as minor insertions cause cascading byte shifts, negating delta-compression and creating unresolvable binary merge conflicts.
|
|
10
10
|
|
|
11
|
-
This package
|
|
11
|
+
This package provides a loadable SQLite C extension that overrides the default VFS behavior. It shards the database into deterministic 4KB binary pages within a specified directory (e.g. `.my-db`).
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
During a Git merge, a custom `git-merge-sqlitevfs` driver integrates with Git's conflict resolution pipeline to reconcile B-Tree page conflicts.
|
|
14
14
|
|
|
15
15
|
## Installation
|
|
16
16
|
|
|
17
|
-
Install the VFS package alongside your libSQL and Drizzle tools:
|
|
18
|
-
|
|
19
17
|
```bash
|
|
20
18
|
npm install git-sqlite-vfs @libsql/client drizzle-orm
|
|
21
19
|
```
|
|
22
20
|
|
|
23
|
-
## Git
|
|
21
|
+
## Git Configuration
|
|
24
22
|
|
|
25
|
-
|
|
23
|
+
The repository must be configured to use the custom merge driver. This configuration occurs automatically when `bootstrapGitVFS()` is called:
|
|
26
24
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
25
|
+
1. Registers `git-merge-sqlitevfs` as a custom Git merge driver in the local `.git/config`.
|
|
26
|
+
2. Updates `.gitattributes` in the repository root to route files matching the configured directory (e.g., `.my-db/*`) through the custom merge driver.
|
|
27
|
+
3. Updates `.gitignore` to ignore SQLite transient files (`*-journal`, `*-wal`, `*-shm`).
|
|
28
|
+
|
|
29
|
+
### Source Code Compatibility
|
|
30
30
|
|
|
31
|
-
|
|
32
|
-
1. Register `git-merge-sqlitevfs` as a custom Git merge driver in your local `.git/config`.
|
|
33
|
-
2. Create or append to a `.gitattributes` file in your repo root to route all files in `.my-db/*` through the custom merge driver.
|
|
31
|
+
The custom SQLite merge driver scopes to the designated database directory via `.gitattributes`. Other repository files continue using Git's default text-based merge algorithms.
|
|
34
32
|
|
|
35
|
-
## Usage
|
|
33
|
+
## Usage
|
|
36
34
|
|
|
37
|
-
The VFS
|
|
35
|
+
The VFS operates in Node.js and Deno environments. Calling `bootstrapGitVFS()` prior to initializing `@libsql/client` loads the extension process-wide.
|
|
38
36
|
|
|
39
|
-
###
|
|
37
|
+
### Example with `@libsql/client` and Drizzle ORM
|
|
40
38
|
|
|
41
39
|
```typescript
|
|
42
40
|
import { createClient } from '@libsql/client'; // In Deno: 'npm:@libsql/client/node'
|
|
@@ -44,47 +42,47 @@ import { drizzle } from 'drizzle-orm/libsql';
|
|
|
44
42
|
import { sqliteTable, integer, text } from 'drizzle-orm/sqlite-core';
|
|
45
43
|
import { bootstrapGitVFS } from 'git-sqlite-vfs';
|
|
46
44
|
|
|
47
|
-
//
|
|
45
|
+
// Load the native extension process-wide and set the VFS directory
|
|
48
46
|
await bootstrapGitVFS({ dir: '.my-db' });
|
|
49
47
|
|
|
50
|
-
//
|
|
48
|
+
// Initialize the database connection using a file URL
|
|
51
49
|
const client = createClient({
|
|
52
50
|
url: 'file:.my-db/local.db'
|
|
53
51
|
});
|
|
54
52
|
|
|
55
|
-
//
|
|
53
|
+
// Wrap with Drizzle ORM
|
|
56
54
|
const db = drizzle(client);
|
|
57
55
|
|
|
58
|
-
//
|
|
56
|
+
// Define the schema
|
|
59
57
|
const users = sqliteTable('users', {
|
|
60
58
|
id: integer('id').primaryKey(),
|
|
61
59
|
name: text('name')
|
|
62
60
|
});
|
|
63
61
|
|
|
64
|
-
//
|
|
62
|
+
// Execute queries
|
|
65
63
|
await db.insert(users).values({ id: 1, name: 'Alice' });
|
|
66
64
|
const allUsers = await db.select().from(users);
|
|
67
65
|
|
|
68
66
|
console.log(allUsers);
|
|
69
67
|
```
|
|
70
68
|
|
|
71
|
-
##
|
|
69
|
+
## Database Compaction
|
|
72
70
|
|
|
73
|
-
|
|
71
|
+
SQLite often zeroes out deleted data pages rather than shrinking the file size, causing unneeded `.bin` pages to remain. To allow the Git VFS to remove these unused shards, configure SQLite to use `FULL` auto-vacuuming and `DELETE` journaling.
|
|
74
72
|
|
|
75
|
-
|
|
73
|
+
Execute these PRAGMA statements during connection initialization:
|
|
76
74
|
|
|
77
75
|
```sql
|
|
78
76
|
PRAGMA auto_vacuum = FULL;
|
|
79
77
|
PRAGMA journal_mode = DELETE;
|
|
80
78
|
```
|
|
81
79
|
|
|
82
|
-
|
|
80
|
+
Alternatively, executing `VACUUM;` periodically reduces the database file size, and the VFS `xTruncate` implementation will remove out-of-bounds `.bin` shards.
|
|
83
81
|
|
|
84
82
|
## Compatibility
|
|
85
83
|
|
|
86
|
-
- **Node.js**: v22.5+ (using the
|
|
87
|
-
- **Deno**: Supported
|
|
84
|
+
- **Node.js**: v22.5+ (using the internal `node:sqlite` API) or fallback to `better-sqlite3`.
|
|
85
|
+
- **Deno**: Supported natively (loads the extension dynamically via `jsr:@db/sqlite`).
|
|
88
86
|
|
|
89
87
|
## License
|
|
90
88
|
|
package/index.js
CHANGED
|
@@ -53,6 +53,14 @@ export async function bootstrapGitVFS(options = {}) {
|
|
|
53
53
|
const db = new Database(':memory:');
|
|
54
54
|
db.loadExtension(currentExtPath);
|
|
55
55
|
db.close();
|
|
56
|
+
|
|
57
|
+
try {
|
|
58
|
+
const repoDir = typeof Deno !== 'undefined' ? Deno.cwd() : process.cwd();
|
|
59
|
+
const vfsDir = options.dir || '.db';
|
|
60
|
+
await configureGitIntegration({ repoDir, vfsDir });
|
|
61
|
+
} catch (e) {
|
|
62
|
+
// Ignore errors if git is not available or not in a git repository
|
|
63
|
+
}
|
|
56
64
|
}
|
|
57
65
|
|
|
58
66
|
export async function configureGitIntegration({ repoDir, vfsDir }) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "git-sqlite-vfs",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.11",
|
|
4
4
|
"description": "A Git-Versioned SQLite Database via a Custom Virtual File System (VFS)",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"types": "index.d.ts",
|
|
@@ -24,9 +24,9 @@
|
|
|
24
24
|
"scripts": {
|
|
25
25
|
"build": "cd c && make",
|
|
26
26
|
"postinstall": "node install.js",
|
|
27
|
-
"pretest": "npm run build && rm -rf .db test.db .test-db .compaction-db .git && git init --initial-branch=master",
|
|
27
|
+
"pretest": "npm run build && rm -rf .db test.db .test-db .compaction-db .git .gitattributes .gitignore && git init --initial-branch=master",
|
|
28
28
|
"test": "node --test test/*.node.test.js",
|
|
29
|
-
"test:deno": "npm run build && rm -rf .db test.db .test-db .git && git init --initial-branch=master && deno test -A test/*.deno.test.ts"
|
|
29
|
+
"test:deno": "npm run build && rm -rf .db test.db .test-db .git .gitattributes .gitignore && git init --initial-branch=master && deno test -A test/*.deno.test.ts"
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
32
|
"@libsql/client": "^0.14.0",
|