Skip to content

Commit c171881

Browse files
committed
feat(packages): add @sqliteai/sqlite-sync Node package
1 parent 62337d8 commit c171881

File tree

13 files changed

+999
-8
lines changed

13 files changed

+999
-8
lines changed

.github/workflows/main.yml

Lines changed: 72 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -340,13 +340,82 @@ jobs:
340340
if: steps.tag.outputs.version != ''
341341
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/cloudsync-android-aar/cloudsync.aar"
342342

343+
- uses: actions/setup-node@v4
344+
if: steps.tag.outputs.version != ''
345+
with:
346+
node-version: '20'
347+
registry-url: 'https://registry.npmjs.org'
348+
349+
- name: build and publish npm packages
350+
if: steps.tag.outputs.version != ''
351+
env:
352+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
353+
run: |
354+
cd packages/node
355+
356+
# Update version in package.json
357+
echo "Updating versions to ${{ steps.tag.outputs.version }}..."
358+
359+
# Update package.json
360+
jq --arg version "${{ steps.tag.outputs.version }}" \
361+
'.version = $version | .optionalDependencies = (.optionalDependencies | with_entries(.value = $version))' \
362+
package.json > package.tmp.json && mv package.tmp.json package.json
363+
364+
echo "✓ Updated package.json to version ${{ steps.tag.outputs.version }}"
365+
366+
# Generate platform packages
367+
echo "Generating platform packages..."
368+
node generate-platform-packages.js "${{ steps.tag.outputs.version }}" "../../artifacts" "./platform-packages"
369+
echo "✓ Generated 7 platform packages"
370+
ls -la platform-packages/
371+
372+
# Build main package
373+
echo "Building main package..."
374+
npm install
375+
npm run build
376+
npm test
377+
echo "✓ Main package built and tested"
378+
379+
# Publish platform packages
380+
echo "Publishing platform packages to npm..."
381+
cd platform-packages
382+
for platform_dir in */; do
383+
platform_name=$(basename "$platform_dir")
384+
echo " Publishing @sqliteai/sqlite-sync-${platform_name}..."
385+
cd "$platform_dir"
386+
npm publish --access public
387+
# TODO: Add --provenance flag after switching to OIDC (requires package to exist first)
388+
cd ..
389+
echo " ✓ Published @sqliteai/sqlite-sync-${platform_name}"
390+
done
391+
cd ..
392+
393+
# Publish main package
394+
echo "Publishing main package to npm..."
395+
npm publish --access public
396+
# TODO: Add --provenance flag after switching to OIDC (requires package to exist first)
397+
echo "✓ Published @sqliteai/sqlite-sync@${{ steps.tag.outputs.version }}"
398+
399+
echo ""
400+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
401+
echo "✅ Successfully published 8 packages to npm"
402+
echo " Main: @sqliteai/sqlite-sync@${{ steps.tag.outputs.version }}"
403+
echo " Platform packages: 7"
404+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
405+
343406
- uses: softprops/[email protected]
344407
if: steps.tag.outputs.version != ''
345408
with:
346409
body: |
347-
# WASM Releases
348-
**WASM repository**: [sqlite-wasm](https://github.com/sqliteai/sqlite-wasm)
349-
**WASM package** is available on npm: [@sqliteai/sqlite-wasm](https://www.npmjs.com/package/@sqliteai/sqlite-wasm)
410+
# Packages
411+
412+
[**Node**](https://www.npmjs.com/package/@sqliteai/sqlite-sync): `npm install @sqliteai/sqlite-sync`
413+
[**WASM**](https://www.npmjs.com/package/@sqliteai/sqlite-wasm): `npm install @sqliteai/sqlite-wasm`
414+
[**Android**](https://central.sonatype.com/artifact/ai.sqlite/sync): `ai.sqlite:sync:${{ steps.tag.outputs.version }}`
415+
[**Swift**](https://github.com/sqliteai/sqlite-sync#swift-package): [Installation Guide](https://github.com/sqliteai/sqlite-sync#swift-package)
416+
417+
---
418+
350419
generate_release_notes: true
351420
tag_name: ${{ steps.tag.outputs.version }}
352421
files: |

.gitignore

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,28 @@
11
# Build artifacts
22
build/
3-
/dist
3+
dist/
44
.build
55
*.a
66
*.sqlite
77
/curl/src
8-
**/dist/**
98

109
# Test artifacts
1110
/coverage
1211
unittest
13-
**/node_modules/**
1412
.env
13+
14+
# Node.js
15+
**/node_modules/**
1516
package-lock.json
17+
*.tsbuildinfo
18+
*.log
19+
npm-debug.log*
20+
yarn-debug.log*
21+
yarn-error.log*
22+
packages/node/platform-packages/
23+
packages/node/test-artifacts/
24+
packages/node/test-output/
25+
packages/node/test-platform-packages/
1626

1727
# iOS/macOS
1828
*.xcworkspacedata
@@ -33,6 +43,9 @@ jniLibs/
3343
.vscode
3444
.idea/
3545
*.iml
46+
*.swp
47+
*.swo
3648

3749
# System
38-
.DS_Store
50+
.DS_Store
51+
Thumbs.db

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: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
# @sqliteai/sqlite-sync
2+
3+
[![npm version](https://badge.fury.io/js/@sqliteai%2Fsqlite-sync.svg)](https://www.npmjs.com/package/@sqliteai/sqlite-sync)
4+
[![License](https://img.shields.io/badge/license-Elastic%202.0-blue.svg)](LICENSE.md)
5+
[![sqlite-sync coverage](https://img.shields.io/badge/dynamic/regex?url=https%3A%2F%2Fsqliteai.github.io%2Fsqlite-sync%2F&search=%3Ctd%20class%3D%22headerItem%22%3EFunctions%3A%3C%5C%2Ftd%3E%5Cs*%3Ctd%20class%3D%22headerCovTableEntryHi%22%3E(%5B%5Cd.%5D%2B)%26nbsp%3B%25%3C%5C%2Ftd%3E&replace=%241%25&label=coverage&labelColor=rgb(85%2C%2085%2C%2085)%3B&color=rgb(167%2C%20252%2C%20157)%3B&link=https%3A%2F%2Fsqliteai.github.io%2Fsqlite-sync%2F)](https://sqliteai.github.io/sqlite-sync/)
6+
7+
> SQLite Sync extension packaged for Node.js
8+
9+
**SQLite Sync** is a multi-platform extension that brings a true **local-first experience** to your applications with minimal effort. It extends standard SQLite tables with built-in support for offline work and automatic synchronization, allowing multiple devices to operate independently—even without a network connection—and seamlessly stay in sync. With SQLite Sync, developers can easily build **distributed, collaborative applications** while continuing to rely on the **simplicity, reliability, and performance of SQLite**.
10+
11+
Under the hood, SQLite Sync uses advanced **CRDT (Conflict-free Replicated Data Type)** algorithms and data structures designed specifically for **collaborative, distributed systems**. This means:
12+
13+
- Devices can update data independently, even without a network connection.
14+
- When they reconnect, all changes are **merged automatically and without conflicts**.
15+
- **No data loss. No overwrites. No manual conflict resolution.**
16+
17+
In simple terms, CRDTs make it possible for multiple users to **edit shared data at the same time**, from anywhere, and everything just works.
18+
19+
## Features
20+
21+
-**Bidirectional Sync** - Sync local SQLite databases with cloud storage
22+
-**Conflict Resolution** - Intelligent conflict handling and resolution
23+
-**Offline-First** - Full functionality without network connectivity
24+
-**Cross-platform** - Works on macOS, Linux (glibc/musl), and Windows
25+
-**Zero configuration** - Automatically detects and loads the correct binary for your platform
26+
-**TypeScript native** - Full type definitions included
27+
-**Modern ESM + CJS** - Works with both ES modules and CommonJS
28+
29+
## Installation
30+
31+
```bash
32+
npm install @sqliteai/sqlite-sync
33+
```
34+
35+
The package automatically downloads the correct native extension for your platform during installation.
36+
37+
### Supported Platforms
38+
39+
| Platform | Architecture | Package |
40+
|----------|-------------|---------|
41+
| macOS | ARM64 (Apple Silicon) | `@sqliteai/sqlite-sync-darwin-arm64` |
42+
| macOS | x86_64 (Intel) | `@sqliteai/sqlite-sync-darwin-x86_64` |
43+
| Linux | ARM64 (glibc) | `@sqliteai/sqlite-sync-linux-arm64` |
44+
| Linux | ARM64 (musl/Alpine) | `@sqliteai/sqlite-sync-linux-arm64-musl` |
45+
| Linux | x86_64 (glibc) | `@sqliteai/sqlite-sync-linux-x86_64` |
46+
| Linux | x86_64 (musl/Alpine) | `@sqliteai/sqlite-sync-linux-x86_64-musl` |
47+
| Windows | x86_64 | `@sqliteai/sqlite-sync-win32-x86_64` |
48+
49+
## sqlite-sync API
50+
51+
For detailed information on how to use the sync extension features, see the [main documentation](https://github.com/sqliteai/sqlite-sync/blob/main/API.md).
52+
53+
## Usage
54+
55+
```typescript
56+
import { getExtensionPath } from '@sqliteai/sqlite-sync';
57+
import Database from 'better-sqlite3';
58+
59+
const db = new Database(':memory:');
60+
db.loadExtension(getExtensionPath());
61+
62+
// Ready to use
63+
const version = db.prepare('SELECT cloudsync_version()').pluck().get();
64+
console.log('Sync extension version:', version);
65+
```
66+
67+
## Examples
68+
69+
For complete, runnable examples, see the [sqlite-extensions-guide](https://github.com/sqliteai/sqlite-extensions-guide/tree/main/examples/node).
70+
71+
These examples are generic and work with all SQLite extensions: `sqlite-vector`, `sqlite-sync`, `sqlite-js`, and `sqlite-ai`.
72+
73+
## API Reference
74+
75+
### `getExtensionPath(): string`
76+
77+
Returns the absolute path to the SQLite Sync extension binary for the current platform.
78+
79+
**Returns:** `string` - Absolute path to the extension file (`.so`, `.dylib`, or `.dll`)
80+
81+
**Throws:** `ExtensionNotFoundError` - If the extension binary cannot be found for the current platform
82+
83+
---
84+
85+
### `getExtensionInfo(): ExtensionInfo`
86+
87+
Returns detailed information about the extension for the current platform.
88+
89+
**Returns:** `ExtensionInfo` object with the following properties:
90+
- `platform: Platform` - Current platform identifier (e.g., `'darwin-arm64'`)
91+
- `packageName: string` - Name of the platform-specific npm package
92+
- `binaryName: string` - Filename of the binary (e.g., `'cloudsync.dylib'`)
93+
- `path: string` - Full path to the extension binary
94+
95+
**Throws:** `ExtensionNotFoundError` - If the extension binary cannot be found
96+
97+
**Example:**
98+
```typescript
99+
import { getExtensionInfo } from '@sqliteai/sqlite-sync';
100+
101+
const info = getExtensionInfo();
102+
console.log(`Running on ${info.platform}`);
103+
console.log(`Extension path: ${info.path}`);
104+
```
105+
106+
---
107+
108+
### `getCurrentPlatform(): Platform`
109+
110+
Returns the current platform identifier.
111+
112+
**Returns:** `Platform` - One of:
113+
- `'darwin-arm64'` - macOS ARM64
114+
- `'darwin-x86_64'` - macOS x86_64
115+
- `'linux-arm64'` - Linux ARM64 (glibc)
116+
- `'linux-arm64-musl'` - Linux ARM64 (musl)
117+
- `'linux-x86_64'` - Linux x86_64 (glibc)
118+
- `'linux-x86_64-musl'` - Linux x86_64 (musl)
119+
- `'win32-x86_64'` - Windows x86_64
120+
121+
**Throws:** `Error` - If the platform is unsupported
122+
123+
---
124+
125+
### `isMusl(): boolean`
126+
127+
Detects if the system uses musl libc (Alpine Linux, etc.).
128+
129+
**Returns:** `boolean` - `true` if musl is detected, `false` otherwise
130+
131+
---
132+
133+
### `class ExtensionNotFoundError extends Error`
134+
135+
Error thrown when the SQLite Sync extension cannot be found for the current platform.
136+
137+
## Related Projects
138+
139+
- **[@sqliteai/sqlite-vector](https://www.npmjs.com/package/@sqliteai/sqlite-vector)** - Vector search and similarity matching
140+
- **[@sqliteai/sqlite-ai](https://www.npmjs.com/package/@sqliteai/sqlite-ai)** - On-device AI inference and embedding generation
141+
- **[@sqliteai/sqlite-js](https://www.npmjs.com/package/@sqliteai/sqlite-js)** - Define SQLite functions in JavaScript
142+
143+
## License
144+
145+
This project is licensed under the [Elastic License 2.0](LICENSE.md).
146+
147+
For production or managed service use, please [contact SQLite Cloud, Inc](mailto:[email protected]) for a commercial license.
148+
149+
## Contributing
150+
151+
Contributions are welcome! Please see the [main repository](https://github.com/sqliteai/sqlite-sync) to open an issue.
152+
153+
## Support
154+
155+
- 📖 [Documentation](https://github.com/sqliteai/sqlite-sync/blob/main/API.md)
156+
- 🐛 [Report Issues](https://github.com/sqliteai/sqlite-sync/issues)

0 commit comments

Comments
 (0)