git-sqlite-vfs 0.0.11 → 0.0.12
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 +33 -6
- package/index.d.ts +8 -0
- package/index.js +28 -4
- package/package.json +4 -2
package/README.md
CHANGED
|
@@ -34,19 +34,33 @@ The custom SQLite merge driver scopes to the designated database directory via `
|
|
|
34
34
|
|
|
35
35
|
The VFS operates in Node.js and Deno environments. Calling `bootstrapGitVFS()` prior to initializing `@libsql/client` loads the extension process-wide.
|
|
36
36
|
|
|
37
|
+
To ensure the VFS correctly intercepts database connections and executes required PRAGMAs, use `createVFSClient` to initialize your connection instead of `@libsql/client`'s `createClient`.
|
|
38
|
+
|
|
39
|
+
### Native Binding Isolation (libsql version mismatch)
|
|
40
|
+
|
|
41
|
+
`git-sqlite-vfs` internally loads the `libsql` native C extension. If your project uses a different version of `@libsql/client` (and thus a different `libsql` binding), Node/Deno may spawn two isolated native C instances in memory, causing the VFS registration to fail silently.
|
|
42
|
+
|
|
43
|
+
To prevent this, you can inject your own `libsql` instance directly into the VFS via `options.libsql`:
|
|
44
|
+
|
|
45
|
+
```typescript
|
|
46
|
+
import * as myLibsql from 'libsql';
|
|
47
|
+
import { bootstrapGitVFS } from 'git-sqlite-vfs';
|
|
48
|
+
|
|
49
|
+
await bootstrapGitVFS({ dir: '.my-db', libsql: myLibsql });
|
|
50
|
+
```
|
|
51
|
+
|
|
37
52
|
### Example with `@libsql/client` and Drizzle ORM
|
|
38
53
|
|
|
39
54
|
```typescript
|
|
40
|
-
import {
|
|
55
|
+
import { bootstrapGitVFS, createVFSClient } from 'git-sqlite-vfs';
|
|
41
56
|
import { drizzle } from 'drizzle-orm/libsql';
|
|
42
57
|
import { sqliteTable, integer, text } from 'drizzle-orm/sqlite-core';
|
|
43
|
-
import { bootstrapGitVFS } from 'git-sqlite-vfs';
|
|
44
58
|
|
|
45
59
|
// Load the native extension process-wide and set the VFS directory
|
|
46
60
|
await bootstrapGitVFS({ dir: '.my-db' });
|
|
47
61
|
|
|
48
|
-
// Initialize the database connection
|
|
49
|
-
const client =
|
|
62
|
+
// Initialize the database connection (automates required PRAGMAs and natively supports Deno)
|
|
63
|
+
const client = await createVFSClient({
|
|
50
64
|
url: 'file:.my-db/local.db'
|
|
51
65
|
});
|
|
52
66
|
|
|
@@ -66,11 +80,24 @@ const allUsers = await db.select().from(users);
|
|
|
66
80
|
console.log(allUsers);
|
|
67
81
|
```
|
|
68
82
|
|
|
83
|
+
### Usage with Deno
|
|
84
|
+
|
|
85
|
+
By default, Deno resolves `npm:@libsql/client` to its browser-compatible implementation, which bypasses native C extensions entirely. This means the VFS never runs.
|
|
86
|
+
|
|
87
|
+
To work around this, lock the dependency directly to the Node environment. `createVFSClient` will gracefully default to the Node native bindings under the hood (`npm:@libsql/client/node`).
|
|
88
|
+
|
|
89
|
+
If you still need to bypass `createVFSClient`, import using the `/node` path directly:
|
|
90
|
+
```typescript
|
|
91
|
+
import { createClient } from 'npm:@libsql/client@0.14.0/node';
|
|
92
|
+
```
|
|
93
|
+
|
|
69
94
|
## Database Compaction
|
|
70
95
|
|
|
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,
|
|
96
|
+
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, it requires `FULL` auto-vacuuming and `DELETE` journaling to actively split and compact out-of-bounds shards.
|
|
97
|
+
|
|
98
|
+
When you use `createVFSClient()`, it automatically executes these PRAGMAs for you upon connection initialization.
|
|
72
99
|
|
|
73
|
-
|
|
100
|
+
If you create your client manually without `createVFSClient`, you must run them yourself:
|
|
74
101
|
|
|
75
102
|
```sql
|
|
76
103
|
PRAGMA auto_vacuum = FULL;
|
package/index.d.ts
CHANGED
|
@@ -2,10 +2,18 @@ export const GITVFS_EXTENSION_PATH: string;
|
|
|
2
2
|
|
|
3
3
|
export interface BootstrapOptions {
|
|
4
4
|
dir?: string;
|
|
5
|
+
libsql?: any;
|
|
5
6
|
}
|
|
6
7
|
|
|
7
8
|
export function bootstrapGitVFS(options?: BootstrapOptions): Promise<void>;
|
|
8
9
|
|
|
10
|
+
export interface CreateVFSClientOptions {
|
|
11
|
+
clientOptions: any;
|
|
12
|
+
createClient?: any;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function createVFSClient(options: CreateVFSClientOptions | any): Promise<any>;
|
|
16
|
+
|
|
9
17
|
export interface ConfigureGitOptions {
|
|
10
18
|
repoDir: string;
|
|
11
19
|
vfsDir: string;
|
package/index.js
CHANGED
|
@@ -33,16 +33,18 @@ export async function bootstrapGitVFS(options = {}) {
|
|
|
33
33
|
|
|
34
34
|
let currentExtPath = extensionPath;
|
|
35
35
|
if (!fs.existsSync(currentExtPath)) {
|
|
36
|
-
const writableDir = path.join(
|
|
36
|
+
const writableDir = path.join(__dirname, '.git-sqlite-vfs-bin');
|
|
37
37
|
await downloadOrBuild(writableDir);
|
|
38
38
|
currentExtPath = path.join(writableDir, `gitvfs.${ext}`);
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
// Dynamically import libsql so that we load the extension into its isolated native memory space.
|
|
42
42
|
let Database;
|
|
43
|
-
if (
|
|
43
|
+
if (options.libsql) {
|
|
44
|
+
Database = options.libsql.default || options.libsql.Database || options.libsql;
|
|
45
|
+
} else if (typeof Deno !== 'undefined') {
|
|
44
46
|
// Deno environment
|
|
45
|
-
const lib = await import('libsql');
|
|
47
|
+
const lib = await import('npm:libsql');
|
|
46
48
|
Database = lib.default || lib.Database || lib;
|
|
47
49
|
} else {
|
|
48
50
|
// Node.js environment
|
|
@@ -63,6 +65,28 @@ export async function bootstrapGitVFS(options = {}) {
|
|
|
63
65
|
}
|
|
64
66
|
}
|
|
65
67
|
|
|
68
|
+
export async function createVFSClient(options) {
|
|
69
|
+
let createClientFn = options.createClient;
|
|
70
|
+
if (!createClientFn) {
|
|
71
|
+
if (typeof Deno !== 'undefined') {
|
|
72
|
+
// Gracefully default to Node native bindings in Deno to prevent bypassing the VFS
|
|
73
|
+
const mod = await import('npm:@libsql/client/node');
|
|
74
|
+
createClientFn = mod.createClient;
|
|
75
|
+
} else {
|
|
76
|
+
const mod = await import('@libsql/client');
|
|
77
|
+
createClientFn = mod.createClient;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const client = createClientFn(options.clientOptions || options);
|
|
82
|
+
|
|
83
|
+
// Execute required PRAGMAs for the VFS to actively split and compact out-of-bounds shards
|
|
84
|
+
await client.execute('PRAGMA auto_vacuum = FULL;');
|
|
85
|
+
await client.execute('PRAGMA journal_mode = DELETE;');
|
|
86
|
+
|
|
87
|
+
return client;
|
|
88
|
+
}
|
|
89
|
+
|
|
66
90
|
export async function configureGitIntegration({ repoDir, vfsDir }) {
|
|
67
91
|
let driverDir = path.resolve(__dirname, 'c', 'output');
|
|
68
92
|
let driverPath = path.join(driverDir, 'git-merge-sqlitevfs');
|
|
@@ -71,7 +95,7 @@ export async function configureGitIntegration({ repoDir, vfsDir }) {
|
|
|
71
95
|
}
|
|
72
96
|
|
|
73
97
|
if (!fs.existsSync(driverPath)) {
|
|
74
|
-
driverDir = path.join(
|
|
98
|
+
driverDir = path.join(__dirname, '.git-sqlite-vfs-bin');
|
|
75
99
|
await downloadOrBuild(driverDir);
|
|
76
100
|
driverPath = path.join(driverDir, 'git-merge-sqlitevfs');
|
|
77
101
|
if (platform === 'win32' && !fs.existsSync(driverPath) && fs.existsSync(driverPath + '.exe')) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "git-sqlite-vfs",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.12",
|
|
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",
|
|
@@ -29,8 +29,10 @@
|
|
|
29
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
|
+
"drizzle-orm": "^0.33.0"
|
|
33
|
+
},
|
|
34
|
+
"peerDependencies": {
|
|
32
35
|
"@libsql/client": "^0.14.0",
|
|
33
|
-
"drizzle-orm": "^0.33.0",
|
|
34
36
|
"libsql": "^0.4.5"
|
|
35
37
|
},
|
|
36
38
|
"author": "",
|