Skip to content

Commit b2ea123

Browse files
committed
Add Node.js driver first implementation
1 parent d8c6ed2 commit b2ea123

5 files changed

Lines changed: 71 additions & 26 deletions

File tree

.github/workflows/test.yml

Lines changed: 1 addition & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ permissions:
99
contents: read
1010
jobs:
1111
full:
12-
name: Node.js Latest Full
12+
name: Node.js Latest
1313
runs-on: ubuntu-latest
1414
steps:
1515
- name: Checkout the repository
@@ -27,28 +27,3 @@ jobs:
2727
run: pnpm install --ignore-scripts
2828
- name: Run tests
2929
run: pnpm test
30-
short:
31-
runs-on: ubuntu-latest
32-
strategy:
33-
matrix:
34-
node-version:
35-
- 24
36-
- 22
37-
- 20
38-
name: Node.js ${{ matrix.node-version }} Quick
39-
steps:
40-
- name: Checkout the repository
41-
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
42-
- name: Install pnpm
43-
uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0
44-
with:
45-
version: 10
46-
- name: Install Node.js ${{ matrix.node-version }}
47-
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
48-
with:
49-
node-version: ${{ matrix.node-version }}
50-
cache: pnpm
51-
- name: Install dependencies
52-
run: pnpm install --ignore-scripts
53-
- name: Run unit tests
54-
run: pnpm bnt

README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,19 @@ import { expoDriver } from '@nanostores/sql/expo'
8383
export const db = openDb(expoDriver('app.sqlite'))
8484
```
8585

86+
### Node.js
87+
88+
For CI test you can use `nodeDriver`.
89+
90+
`node:sqlite` has no live queries and we use hacks for that, so it is not very efficient.
91+
92+
```ts
93+
import { openDb } from '@nanostores/sql'
94+
import { nodeDriver } from '@nanostores/sql/node'
95+
96+
export const db = openDb(nodeDriver(':memory:'))
97+
```
98+
8699
### PGLite
87100

88101
[PGLite](https://pglite.dev) to use PostgreSQL rich features in browsers:

node/index.d.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import type { Driver } from '../index.js'
2+
3+
export function nodeDriver(filename: string): Driver

node/index.js

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import { DatabaseSync } from 'node:sqlite'
2+
3+
export function nodeDriver(filename) {
4+
let db = new DatabaseSync(filename)
5+
let subscribers = new Map()
6+
let nextId = 0
7+
8+
function notifySubscribers() {
9+
for (let [, sub] of subscribers) {
10+
let rows = db.prepare(sub.query).all(...sub.params)
11+
sub.cb(rows)
12+
}
13+
}
14+
15+
let driver = {
16+
subscribe(query, params, cb) {
17+
let id = nextId++
18+
subscribers.set(id, { query, params, cb })
19+
let rows = db.prepare(query).all(...params)
20+
cb(rows)
21+
return () => {
22+
subscribers.delete(id)
23+
}
24+
},
25+
26+
exec(query, params) {
27+
return new Promise(resolve => {
28+
let result = db.prepare(query).run(...params)
29+
notifySubscribers()
30+
resolve(result)
31+
})
32+
},
33+
34+
async transaction(callback) {
35+
db.exec('BEGIN')
36+
try {
37+
let result = await callback(driver)
38+
db.exec('COMMIT')
39+
notifySubscribers()
40+
return result
41+
} catch (e) {
42+
db.exec('ROLLBACK')
43+
throw e
44+
}
45+
},
46+
47+
close() {
48+
subscribers.clear()
49+
db.close()
50+
}
51+
}
52+
return driver
53+
}

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
".": "./index.js",
2929
"./expo": "./expo/index.js",
3030
"./sqlocal": "./sqlocal/index.js",
31+
"./node": "./node/index.js",
3132
"./pglite": "./pglite/index.js",
3233
"./package.json": "./package.json"
3334
},

0 commit comments

Comments
 (0)