Skip to content

Commit a061c89

Browse files
committed
feat(packages): add @sqliteai/sqlite-js Node package
1 parent 114f3f2 commit a061c89

File tree

14 files changed

+1018
-10
lines changed

14 files changed

+1018
-10
lines changed

.github/workflows/main.yml

Lines changed: 82 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ jobs:
1010
build:
1111
runs-on: ${{ matrix.os }}
1212
container: ${{ matrix.container && matrix.container || '' }}
13-
name: ${{ matrix.name }}${{ matrix.arch && format('-{0}', matrix.arch) || '' }} build${{ matrix.arch != 'arm64-v8a' && matrix.name != 'ios-sim' && matrix.name != 'ios' && matrix.name != 'apple-xcframework' && matrix.name != 'android-aar' && ' + test' || ''}}
13+
name: ${{ matrix.name }}${{ matrix.arch && format('-{0}', matrix.arch) || '' }} build${{ matrix.arch != 'arm64-v8a' && matrix.name != 'ios-sim' && matrix.name != 'ios' && matrix.name != 'apple-xcframework' && matrix.name != 'android-aar' && ( matrix.name != 'macos' || matrix.arch != 'x86_64' ) && ' + test' || ''}}
1414
timeout-minutes: 20
1515
strategy:
1616
fail-fast: false
@@ -31,6 +31,14 @@ jobs:
3131
name: linux-musl
3232
- os: macos-15
3333
name: macos
34+
- os: macos-15
35+
arch: x86_64
36+
name: macos
37+
make: ARCH=x86_64
38+
- os: macos-15
39+
arch: arm64
40+
name: macos
41+
make: ARCH=arm64
3442
- os: windows-2022
3543
arch: x86_64
3644
name: windows
@@ -171,7 +179,7 @@ jobs:
171179
adb shell "sh /data/local/tmp/commands.sh"
172180
173181
- name: test sqlite-js
174-
if: contains(matrix.name, 'linux') || matrix.name == 'windows' || matrix.name == 'macos'
182+
if: contains(matrix.name, 'linux') || matrix.name == 'windows' || ( matrix.name == 'macos' && matrix.arch != 'x86_64' )
175183
run: ${{ matrix.name == 'linux-musl' && matrix.arch == 'arm64' && 'docker exec alpine' || '' }} make test ${{ matrix.make && matrix.make || ''}}
176184

177185
- uses: actions/[email protected]
@@ -277,9 +285,81 @@ jobs:
277285
if: steps.tag.outputs.version != ''
278286
run: cd packages/android && ./gradlew publishAggregationToCentralPortal -PSIGNING_KEY="${{ secrets.SIGNING_KEY }}" -PSIGNING_PASSWORD="${{ secrets.SIGNING_PASSWORD }}" -PSONATYPE_USERNAME="${{ secrets.MAVEN_CENTRAL_USERNAME }}" -PSONATYPE_PASSWORD="${{ secrets.MAVEN_CENTRAL_TOKEN }}" -PVERSION="${{ steps.tag.outputs.version }}" -PAAR_PATH="../../artifacts/js-android-aar/js.aar"
279287

288+
- uses: actions/setup-node@v4
289+
if: steps.tag.outputs.version != ''
290+
with:
291+
node-version: '20'
292+
registry-url: 'https://registry.npmjs.org'
293+
294+
- name: build and publish npm packages
295+
if: steps.tag.outputs.version != ''
296+
env:
297+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
298+
run: |
299+
cd packages/node
300+
301+
# Update version in package.json
302+
echo "Updating versions to ${{ steps.tag.outputs.version }}..."
303+
304+
# Update package.json
305+
jq --arg version "${{ steps.tag.outputs.version }}" \
306+
'.version = $version | .optionalDependencies = (.optionalDependencies | with_entries(.value = $version))' \
307+
package.json > package.tmp.json && mv package.tmp.json package.json
308+
309+
echo "✓ Updated package.json to version ${{ steps.tag.outputs.version }}"
310+
311+
# Generate platform packages
312+
echo "Generating platform packages..."
313+
node generate-platform-packages.js "${{ steps.tag.outputs.version }}" "../../artifacts" "./platform-packages"
314+
echo "✓ Generated 7 platform packages"
315+
ls -la platform-packages/
316+
317+
# Build main package
318+
echo "Building main package..."
319+
npm install
320+
npm run build
321+
npm test
322+
echo "✓ Main package built and tested"
323+
324+
# Publish platform packages
325+
echo "Publishing platform packages to npm..."
326+
cd platform-packages
327+
for platform_dir in */; do
328+
platform_name=$(basename "$platform_dir")
329+
echo " Publishing @sqliteai/sqlite-js-${platform_name}..."
330+
cd "$platform_dir"
331+
npm publish --access public
332+
# TODO: Add --provenance flag after switching to OIDC (requires package to exist first)
333+
cd ..
334+
echo " ✓ Published @sqliteai/sqlite-js-${platform_name}"
335+
done
336+
cd ..
337+
338+
# Publish main package
339+
echo "Publishing main package to npm..."
340+
npm publish --access public
341+
# TODO: Add --provenance flag after switching to OIDC (requires package to exist first)
342+
echo "✓ Published @sqliteai/sqlite-js@${{ steps.tag.outputs.version }}"
343+
344+
echo ""
345+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
346+
echo "✅ Successfully published 8 packages to npm"
347+
echo " Main: @sqliteai/sqlite-js@${{ steps.tag.outputs.version }}"
348+
echo " Platform packages: 7"
349+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
350+
280351
- uses: softprops/[email protected]
281352
if: steps.tag.outputs.version != ''
282353
with:
354+
body: |
355+
# Packages
356+
357+
[**Node**](https://www.npmjs.com/package/@sqliteai/sqlite-js): `npm install @sqliteai/sqlite-js`
358+
[**Android**](https://central.sonatype.com/artifact/ai.sqlite/js): `ai.sqlite:js:${{ steps.tag.outputs.version }}`
359+
[**Swift**](https://github.com/sqliteai/sqlite-js#swift-package): [Installation Guide](https://github.com/sqliteai/sqlite-js#swift-package)
360+
361+
---
362+
283363
generate_release_notes: true
284364
tag_name: ${{ steps.tag.outputs.version }}
285365
files: js-*-${{ steps.tag.outputs.version }}.*

.gitignore

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Build artifacts
22
build/
3-
/dist
3+
dist/
44
.build
55
*.a
66
*.sqlite
@@ -20,10 +20,27 @@ jniLibs/
2020
*.ap_
2121
*.dex
2222

23+
# Node.js
24+
node_modules/
25+
package-lock.json
26+
*.tsbuildinfo
27+
coverage/
28+
*.log
29+
npm-debug.log*
30+
yarn-debug.log*
31+
yarn-error.log*
32+
packages/node/platform-packages/
33+
packages/node/test-artifacts/
34+
packages/node/test-output/
35+
packages/node/test-platform-packages/
36+
2337
# IDE
2438
.vscode
2539
.idea/
2640
*.iml
41+
*.swp
42+
*.swo
2743

2844
# System
29-
.DS_Store
45+
.DS_Store
46+
Thumbs.db

Makefile

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,14 @@ ifeq ($(PLATFORM),windows)
4545
STRIP = strip --strip-unneeded $@
4646
else ifeq ($(PLATFORM),macos)
4747
TARGET := $(DIST_DIR)/js.dylib
48-
LDFLAGS := -arch x86_64 -arch arm64 -dynamiclib -undefined dynamic_lookup
49-
# macOS-specific flags
50-
CFLAGS += -arch x86_64 -arch arm64
48+
ifndef ARCH
49+
LDFLAGS := -arch x86_64 -arch arm64
50+
CFLAGS += -arch x86_64 -arch arm64
51+
else
52+
LDFLAGS := -arch $(ARCH)
53+
CFLAGS += -arch $(ARCH)
54+
endif
55+
LDFLAGS += -dynamiclib -undefined dynamic_lookup -headerpad_max_install_names
5156
STRIP = strip -x -S $@
5257
else ifeq ($(PLATFORM),android)
5358
ifndef ARCH # Set ARCH to find Android NDK's Clang compiler, the user should set the ARCH
@@ -67,14 +72,14 @@ else ifeq ($(PLATFORM),android)
6772
else ifeq ($(PLATFORM),ios)
6873
TARGET := $(DIST_DIR)/js.dylib
6974
SDK := -isysroot $(shell xcrun --sdk iphoneos --show-sdk-path) -miphoneos-version-min=11.0
70-
LDFLAGS := -dynamiclib $(SDK)
75+
LDFLAGS := -dynamiclib $(SDK) -headerpad_max_install_names
7176
# iOS-specific flags
7277
CFLAGS += -arch arm64 $(SDK)
7378
STRIP = strip -x -S $@
7479
else ifeq ($(PLATFORM),ios-sim)
7580
TARGET := $(DIST_DIR)/js.dylib
7681
SDK := -isysroot $(shell xcrun --sdk iphonesimulator --show-sdk-path) -miphonesimulator-version-min=11.0
77-
LDFLAGS := -arch x86_64 -arch arm64 -dynamiclib $(SDK)
82+
LDFLAGS := -arch x86_64 -arch arm64 -dynamiclib $(SDK) -headerpad_max_install_names
7883
# iphonesimulator-specific flags
7984
CFLAGS += -arch x86_64 -arch arm64 $(SDK)
8085
STRIP = strip -x -S $@

packages/node/.npmignore

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# Development and build files
2+
src/
3+
*.test.ts
4+
*.test.js
5+
tsconfig.json
6+
tsup.config.ts
7+
8+
# Scripts (only for repo/CI)
9+
generate-platform-packages.js
10+
11+
# Development files
12+
node_modules/
13+
package-lock.json
14+
coverage/
15+
*.log
16+
17+
# Git
18+
.git/
19+
.gitignore

packages/node/LICENSE.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../../LICENSE.md

packages/node/README.md

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
# @sqliteai/sqlite-js
2+
3+
[![npm version](https://badge.fury.io/js/@sqliteai%2Fsqlite-js.svg)](https://www.npmjs.com/package/@sqliteai/sqlite-js)
4+
[![License](https://img.shields.io/badge/license-Elastic%202.0-blue.svg)](LICENSE.md)
5+
6+
> SQLite JS extension packaged for Node.js
7+
8+
**SQLite JS** is a powerful extension that brings JavaScript capabilities to SQLite. With this extension, you can create custom SQLite functions, aggregates, window functions, and collation sequences using JavaScript code, allowing for flexible and powerful data manipulation directly within your SQLite database.
9+
10+
## Features
11+
12+
-**JavaScript UDFs** - Custom SQLite functions in JavaScript
13+
-**QuickJS Integration** - Fast JavaScript execution inside SQLite
14+
-**Cross-platform** - Works on macOS, Linux (glibc/musl), and Windows
15+
-**Zero configuration** - Automatically detects and loads the correct binary for your platform
16+
-**TypeScript native** - Full type definitions included
17+
-**Modern ESM + CJS** - Works with both ES modules and CommonJS
18+
19+
## Installation
20+
21+
```bash
22+
npm install @sqliteai/sqlite-js
23+
```
24+
25+
The package automatically downloads the correct native extension for your platform during installation.
26+
27+
### Supported Platforms
28+
29+
| Platform | Architecture | Package |
30+
|----------|-------------|---------|
31+
| macOS | ARM64 (Apple Silicon) | `@sqliteai/sqlite-js-darwin-arm64` |
32+
| macOS | x86_64 (Intel) | `@sqliteai/sqlite-js-darwin-x86_64` |
33+
| Linux | ARM64 (glibc) | `@sqliteai/sqlite-js-linux-arm64` |
34+
| Linux | ARM64 (musl/Alpine) | `@sqliteai/sqlite-js-linux-arm64-musl` |
35+
| Linux | x86_64 (glibc) | `@sqliteai/sqlite-js-linux-x86_64` |
36+
| Linux | x86_64 (musl/Alpine) | `@sqliteai/sqlite-js-linux-x86_64-musl` |
37+
| Windows | x86_64 | `@sqliteai/sqlite-js-win32-x86_64` |
38+
39+
## sqlite-js API
40+
41+
For detailed information on how to use the JS extension features, see the [main documentation](https://github.com/sqliteai/sqlite-js/blob/main/README.md).
42+
43+
## Usage
44+
45+
```typescript
46+
import { getExtensionPath } from '@sqliteai/sqlite-js';
47+
import Database from 'better-sqlite3';
48+
49+
const db = new Database(':memory:');
50+
db.loadExtension(getExtensionPath());
51+
52+
// Ready to use
53+
const version = db.prepare('SELECT js_version()').pluck().get();
54+
console.log('JS extension version:', version);
55+
```
56+
57+
## Examples
58+
59+
For complete, runnable examples, see the [sqlite-extensions-guide](https://github.com/sqliteai/sqlite-extensions-guide/tree/main/examples/node).
60+
61+
These examples are generic and work with all SQLite extensions: `sqlite-vector`, `sqlite-sync`, `sqlite-js`, and `sqlite-ai`.
62+
63+
## API Reference
64+
65+
### `getExtensionPath(): string`
66+
67+
Returns the absolute path to the SQLite JS extension binary for the current platform.
68+
69+
**Returns:** `string` - Absolute path to the extension file (`.so`, `.dylib`, or `.dll`)
70+
71+
**Throws:** `ExtensionNotFoundError` - If the extension binary cannot be found for the current platform
72+
73+
**Example:**
74+
```typescript
75+
import { getExtensionPath } from '@sqliteai/sqlite-js';
76+
77+
const path = getExtensionPath();
78+
// => '/path/to/node_modules/@sqliteai/sqlite-js-darwin-arm64/js.dylib'
79+
```
80+
81+
---
82+
83+
### `getExtensionInfo(): ExtensionInfo`
84+
85+
Returns detailed information about the extension for the current platform.
86+
87+
**Returns:** `ExtensionInfo` object with the following properties:
88+
- `platform: Platform` - Current platform identifier (e.g., `'darwin-arm64'`)
89+
- `packageName: string` - Name of the platform-specific npm package
90+
- `binaryName: string` - Filename of the binary (e.g., `'js.dylib'`)
91+
- `path: string` - Full path to the extension binary
92+
93+
**Throws:** `ExtensionNotFoundError` - If the extension binary cannot be found
94+
95+
**Example:**
96+
```typescript
97+
import { getExtensionInfo } from '@sqliteai/sqlite-js';
98+
99+
const info = getExtensionInfo();
100+
console.log(`Running on ${info.platform}`);
101+
console.log(`Extension path: ${info.path}`);
102+
```
103+
104+
---
105+
106+
### `getCurrentPlatform(): Platform`
107+
108+
Returns the current platform identifier.
109+
110+
**Returns:** `Platform` - One of:
111+
- `'darwin-arm64'` - macOS ARM64
112+
- `'darwin-x86_64'` - macOS x86_64
113+
- `'linux-arm64'` - Linux ARM64 (glibc)
114+
- `'linux-arm64-musl'` - Linux ARM64 (musl)
115+
- `'linux-x86_64'` - Linux x86_64 (glibc)
116+
- `'linux-x86_64-musl'` - Linux x86_64 (musl)
117+
- `'win32-x86_64'` - Windows x86_64
118+
119+
**Throws:** `Error` - If the platform is unsupported
120+
121+
---
122+
123+
### `isMusl(): boolean`
124+
125+
Detects if the system uses musl libc (Alpine Linux, etc.).
126+
127+
**Returns:** `boolean` - `true` if musl is detected, `false` otherwise
128+
129+
---
130+
131+
### `class ExtensionNotFoundError extends Error`
132+
133+
Error thrown when the SQLite JS extension cannot be found for the current platform.
134+
135+
## Related Projects
136+
137+
- **[@sqliteai/sqlite-vector](https://www.npmjs.com/package/@sqliteai/sqlite-vector)** - Vector search and similarity matching
138+
- **[@sqliteai/sqlite-ai](https://www.npmjs.com/package/@sqliteai/sqlite-ai)** - On-device AI inference and embedding generation
139+
- **[@sqliteai/sqlite-sync](https://www.npmjs.com/package/@sqliteai/sqlite-sync)** - Sync on-device databases with the cloud
140+
141+
## License
142+
143+
This project is licensed under the [Elastic License 2.0](LICENSE.md).
144+
145+
For production or managed service use, please [contact SQLite Cloud, Inc](mailto:[email protected]) for a commercial license.
146+
147+
## Contributing
148+
149+
Contributions are welcome! Please see the [main repository](https://github.com/sqliteai/sqlite-js) to open an issue.
150+
151+
## Support
152+
153+
- 📖 [Documentation](https://github.com/sqliteai/sqlite-js/blob/main/README.md)
154+
- 🐛 [Report Issues](https://github.com/sqliteai/sqlite-js/issues)

0 commit comments

Comments
 (0)