Skip to content

Commit 361ac71

Browse files
authored
Node js (partial and experimental) support (#373)
* testing nodejs support * working funky async transactions * bump version * lock * types * Add docs
1 parent fec3b2c commit 361ac71

16 files changed

Lines changed: 2328 additions & 66 deletions

docs/docs/installation.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,3 +166,7 @@ pre_install do |installer|
166166
end
167167
end
168168
```
169+
170+
## NodeJS support
171+
172+
It's impossible to run a React Native JSI module in Node. However, the library does provide a NodeJS compatible façade with the same API as the RN version. The idea is to enable you to write simple Jest tests that test your queries, NOT to prove the correctness of the library. The NodeJS façade is a convenience and it's not meant for production usage. If you find any issues please report them with a reproducible example.module.

node/.gitignore

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# Dependencies
2+
node_modules/
3+
4+
# Build output
5+
dist/
6+
*.tsbuildinfo
7+
8+
# Test databases
9+
*.sqlite
10+
*.sqlite3
11+
*.db
12+
13+
# Logs
14+
npm-debug.log*
15+
yarn-debug.log*
16+
yarn-error.log*
17+
pnpm-debug.log*
18+
19+
# OS files
20+
.DS_Store
21+
Thumbs.db
22+
23+
# IDE
24+
.vscode/
25+
.idea/
26+
*.swp
27+
*.swo
28+
*~
29+
30+
# Environment
31+
.env
32+
.env.local
33+
.env.*.local
34+
35+
# Build artifacts
36+
build/
37+
*.node

node/README.md

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
# @op-engineering/op-sqlite-node
2+
3+
Node.js adapter for the `@op-engineering/op-sqlite` API using `better-sqlite3`.
4+
5+
This package provides the same TypeScript API as the React Native version but runs on Node.js, allowing you to share database logic between your React Native app and Node.js services.
6+
7+
## Usage
8+
9+
The API is identical to the React Native version, so you can share code between platforms:
10+
11+
```typescript
12+
import { open } from '@op-engineering/op-sqlite-node';
13+
14+
// Open a database
15+
const db = open({
16+
name: 'mydb.sqlite',
17+
location: './data' // optional, defaults to current directory
18+
});
19+
20+
// Execute queries synchronously
21+
const result = db.executeSync('SELECT * FROM users WHERE id = ?', [1]);
22+
console.log(result.rows);
23+
24+
// Or asynchronously
25+
const asyncResult = await db.execute('SELECT * FROM users');
26+
console.log(asyncResult.rows);
27+
28+
// Use transactions
29+
await db.transaction(async (tx) => {
30+
await tx.execute('INSERT INTO users (name) VALUES (?)', ['John']);
31+
await tx.execute('INSERT INTO posts (user_id, title) VALUES (?, ?)', [1, 'Hello']);
32+
});
33+
34+
// Execute batch operations
35+
await db.executeBatch([
36+
['CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, name TEXT)'],
37+
['INSERT INTO users (name) VALUES (?)', ['Alice']],
38+
['INSERT INTO users (name) VALUES (?)', ['Bob']],
39+
]);
40+
41+
// Close the database
42+
db.close();
43+
```
44+
45+
## API Differences from React Native
46+
47+
While the API surface is identical, there are some behavioral differences:
48+
49+
### Supported Features
50+
-`open()` - Open database with name and location
51+
-`openV2()` - Open database with full path
52+
-`execute()` / `executeSync()` - Query execution
53+
-`executeRaw()` / `executeRawSync()` - Raw array results
54+
-`executeBatch()` - Batch operations in transaction
55+
-`transaction()` - Transaction support
56+
-`prepareStatement()` - Prepared statements
57+
-`attach()` / `detach()` - Database attachment
58+
-`loadFile()` - Load and execute SQL files
59+
-`loadExtension()` - SQLite extensions (if enabled in better-sqlite3)
60+
-`close()` / `delete()` - Database management
61+
62+
### Not Supported / Limited
63+
-`openRemote()` - LibSQL remote connections (use libsql client directly)
64+
-`openSync()` - LibSQL sync functionality (use libsql client directly)
65+
-`sync()` - LibSQL sync method
66+
-`reactiveExecute()` - Reactive queries (React Native specific)
67+
-`updateHook()` - Update hooks (not supported by better-sqlite3)
68+
-`setReservedBytes()` / `getReservedBytes()` - SQLCipher specific
69+
- ⚠️ `encryptionKey` - Not supported (use @journeyapps/sqlcipher instead)
70+
- ⚠️ `executeWithHostObjects()` - Falls back to regular execute

node/jest.config.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
export default {
2+
preset: 'ts-jest/presets/default-esm',
3+
testEnvironment: 'node',
4+
extensionsToTreatAsEsm: ['.ts'],
5+
moduleNameMapper: {
6+
'^(\\.{1,2}/.*)\\.js$': '$1',
7+
},
8+
transform: {
9+
'^.+\\.tsx?$': [
10+
'ts-jest',
11+
{
12+
useESM: true,
13+
tsconfig: {
14+
module: 'ESNext',
15+
moduleResolution: 'bundler',
16+
verbatimModuleSyntax: false,
17+
esModuleInterop: true,
18+
allowSyntheticDefaultImports: true,
19+
target: 'ES2020',
20+
lib: ['ES2020'],
21+
types: ['node', 'jest'],
22+
},
23+
},
24+
],
25+
},
26+
testMatch: ['**/*.spec.ts', '**/*.test.ts'],
27+
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
28+
};

node/package.json

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"name": "node",
3+
"version": "1.0.0",
4+
"type": "module",
5+
"private": true,
6+
"scripts": {
7+
"build": "tsc",
8+
"test": "NODE_OPTIONS=--experimental-vm-modules jest",
9+
"example": "tsc && node example.js"
10+
},
11+
"devDependencies": {
12+
"@types/jest": "^29.5.0",
13+
"jest": "^29.5.0",
14+
"ts-jest": "^29.1.0"
15+
}
16+
}

0 commit comments

Comments
 (0)