Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions docs/docs/installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -166,3 +166,7 @@ pre_install do |installer|
end
end
```

## NodeJS support

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.
37 changes: 37 additions & 0 deletions node/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Dependencies
node_modules/

# Build output
dist/
*.tsbuildinfo

# Test databases
*.sqlite
*.sqlite3
*.db

# Logs
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*

# OS files
.DS_Store
Thumbs.db

# IDE
.vscode/
.idea/
*.swp
*.swo
*~

# Environment
.env
.env.local
.env.*.local

# Build artifacts
build/
*.node
70 changes: 70 additions & 0 deletions node/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# @op-engineering/op-sqlite-node

Node.js adapter for the `@op-engineering/op-sqlite` API using `better-sqlite3`.

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.

## Usage

The API is identical to the React Native version, so you can share code between platforms:

```typescript
import { open } from '@op-engineering/op-sqlite-node';

// Open a database
const db = open({
name: 'mydb.sqlite',
location: './data' // optional, defaults to current directory
});

// Execute queries synchronously
const result = db.executeSync('SELECT * FROM users WHERE id = ?', [1]);
console.log(result.rows);

// Or asynchronously
const asyncResult = await db.execute('SELECT * FROM users');
console.log(asyncResult.rows);

// Use transactions
await db.transaction(async (tx) => {
await tx.execute('INSERT INTO users (name) VALUES (?)', ['John']);
await tx.execute('INSERT INTO posts (user_id, title) VALUES (?, ?)', [1, 'Hello']);
});

// Execute batch operations
await db.executeBatch([
['CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, name TEXT)'],
['INSERT INTO users (name) VALUES (?)', ['Alice']],
['INSERT INTO users (name) VALUES (?)', ['Bob']],
]);

// Close the database
db.close();
```

## API Differences from React Native

While the API surface is identical, there are some behavioral differences:

### Supported Features
- ✅ `open()` - Open database with name and location
- ✅ `openV2()` - Open database with full path
- ✅ `execute()` / `executeSync()` - Query execution
- ✅ `executeRaw()` / `executeRawSync()` - Raw array results
- ✅ `executeBatch()` - Batch operations in transaction
- ✅ `transaction()` - Transaction support
- ✅ `prepareStatement()` - Prepared statements
- ✅ `attach()` / `detach()` - Database attachment
- ✅ `loadFile()` - Load and execute SQL files
- ✅ `loadExtension()` - SQLite extensions (if enabled in better-sqlite3)
- ✅ `close()` / `delete()` - Database management

### Not Supported / Limited
- ❌ `openRemote()` - LibSQL remote connections (use libsql client directly)
- ❌ `openSync()` - LibSQL sync functionality (use libsql client directly)
- ❌ `sync()` - LibSQL sync method
- ❌ `reactiveExecute()` - Reactive queries (React Native specific)
- ❌ `updateHook()` - Update hooks (not supported by better-sqlite3)
- ❌ `setReservedBytes()` / `getReservedBytes()` - SQLCipher specific
- ⚠️ `encryptionKey` - Not supported (use @journeyapps/sqlcipher instead)
- ⚠️ `executeWithHostObjects()` - Falls back to regular execute
28 changes: 28 additions & 0 deletions node/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
export default {
preset: 'ts-jest/presets/default-esm',
testEnvironment: 'node',
extensionsToTreatAsEsm: ['.ts'],
moduleNameMapper: {
'^(\\.{1,2}/.*)\\.js$': '$1',
},
transform: {
'^.+\\.tsx?$': [
'ts-jest',
{
useESM: true,
tsconfig: {
module: 'ESNext',
moduleResolution: 'bundler',
verbatimModuleSyntax: false,
esModuleInterop: true,
allowSyntheticDefaultImports: true,
target: 'ES2020',
lib: ['ES2020'],
types: ['node', 'jest'],
},
},
],
},
testMatch: ['**/*.spec.ts', '**/*.test.ts'],
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
};
16 changes: 16 additions & 0 deletions node/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"name": "node",
"version": "1.0.0",
"type": "module",
"private": true,
"scripts": {
"build": "tsc",
"test": "NODE_OPTIONS=--experimental-vm-modules jest",
"example": "tsc && node example.js"
},
"devDependencies": {
"@types/jest": "^29.5.0",
"jest": "^29.5.0",
"ts-jest": "^29.1.0"
}
}
Loading
Loading