@sqliteai/sqlite-sync 0.8.53

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -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:info@sqlitecloud.io) 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,0 +1,84 @@
1
+ /**
2
+ * Supported platform identifiers
3
+ */
4
+ type Platform = 'darwin-arm64' | 'darwin-x86_64' | 'linux-arm64' | 'linux-arm64-musl' | 'linux-x86_64' | 'linux-x86_64-musl' | 'win32-x86_64';
5
+ /**
6
+ * Detects if the system uses musl libc (Alpine Linux, etc.)
7
+ * Uses multiple detection strategies for reliability
8
+ */
9
+ declare function isMusl(): boolean;
10
+ /**
11
+ * Gets the current platform identifier
12
+ * @throws {Error} If the platform is unsupported
13
+ */
14
+ declare function getCurrentPlatform(): Platform;
15
+ /**
16
+ * Gets the package name for the current platform
17
+ */
18
+ declare function getPlatformPackageName(): string;
19
+ /**
20
+ * Gets the binary filename for the current platform
21
+ */
22
+ declare function getBinaryName(): string;
23
+
24
+ /**
25
+ * Error thrown when the SQLite Sync extension cannot be found
26
+ */
27
+ declare class ExtensionNotFoundError extends Error {
28
+ constructor(message: string);
29
+ }
30
+ /**
31
+ * Gets the absolute path to the SQLite Sync extension binary for the current platform
32
+ *
33
+ * @returns Absolute path to the extension binary (.so, .dylib, or .dll)
34
+ * @throws {ExtensionNotFoundError} If the extension binary cannot be found
35
+ *
36
+ * @example
37
+ * ```typescript
38
+ * import { getExtensionPath } from '@sqliteai/sqlite-sync';
39
+ *
40
+ * const extensionPath = getExtensionPath();
41
+ * // On macOS ARM64: /path/to/node_modules/@sqliteai/sqlite-sync-darwin-arm64/cloudsync.dylib
42
+ * ```
43
+ */
44
+ declare function getExtensionPath(): string;
45
+ /**
46
+ * Information about the current platform and extension
47
+ */
48
+ interface ExtensionInfo {
49
+ /** Current platform identifier (e.g., 'darwin-arm64') */
50
+ platform: Platform;
51
+ /** Name of the platform-specific npm package */
52
+ packageName: string;
53
+ /** Filename of the binary (e.g., 'cloudsync.dylib') */
54
+ binaryName: string;
55
+ /** Full path to the extension binary */
56
+ path: string;
57
+ }
58
+ /**
59
+ * Gets detailed information about the SQLite Sync extension
60
+ *
61
+ * @returns Extension information object
62
+ *
63
+ * @example
64
+ * ```typescript
65
+ * import { getExtensionInfo } from '@sqliteai/sqlite-sync';
66
+ *
67
+ * const info = getExtensionInfo();
68
+ * console.log(info);
69
+ * // {
70
+ * // platform: 'darwin-arm64',
71
+ * // packageName: '@sqliteai/sqlite-sync-darwin-arm64',
72
+ * // binaryName: 'cloudsync.dylib',
73
+ * // path: '/path/to/cloudsync.dylib'
74
+ * // }
75
+ * ```
76
+ */
77
+ declare function getExtensionInfo(): ExtensionInfo;
78
+ declare const _default: {
79
+ getExtensionPath: typeof getExtensionPath;
80
+ getExtensionInfo: typeof getExtensionInfo;
81
+ ExtensionNotFoundError: typeof ExtensionNotFoundError;
82
+ };
83
+
84
+ export { type ExtensionInfo, ExtensionNotFoundError, type Platform, _default as default, getBinaryName, getCurrentPlatform, getExtensionInfo, getExtensionPath, getPlatformPackageName, isMusl };
@@ -0,0 +1,84 @@
1
+ /**
2
+ * Supported platform identifiers
3
+ */
4
+ type Platform = 'darwin-arm64' | 'darwin-x86_64' | 'linux-arm64' | 'linux-arm64-musl' | 'linux-x86_64' | 'linux-x86_64-musl' | 'win32-x86_64';
5
+ /**
6
+ * Detects if the system uses musl libc (Alpine Linux, etc.)
7
+ * Uses multiple detection strategies for reliability
8
+ */
9
+ declare function isMusl(): boolean;
10
+ /**
11
+ * Gets the current platform identifier
12
+ * @throws {Error} If the platform is unsupported
13
+ */
14
+ declare function getCurrentPlatform(): Platform;
15
+ /**
16
+ * Gets the package name for the current platform
17
+ */
18
+ declare function getPlatformPackageName(): string;
19
+ /**
20
+ * Gets the binary filename for the current platform
21
+ */
22
+ declare function getBinaryName(): string;
23
+
24
+ /**
25
+ * Error thrown when the SQLite Sync extension cannot be found
26
+ */
27
+ declare class ExtensionNotFoundError extends Error {
28
+ constructor(message: string);
29
+ }
30
+ /**
31
+ * Gets the absolute path to the SQLite Sync extension binary for the current platform
32
+ *
33
+ * @returns Absolute path to the extension binary (.so, .dylib, or .dll)
34
+ * @throws {ExtensionNotFoundError} If the extension binary cannot be found
35
+ *
36
+ * @example
37
+ * ```typescript
38
+ * import { getExtensionPath } from '@sqliteai/sqlite-sync';
39
+ *
40
+ * const extensionPath = getExtensionPath();
41
+ * // On macOS ARM64: /path/to/node_modules/@sqliteai/sqlite-sync-darwin-arm64/cloudsync.dylib
42
+ * ```
43
+ */
44
+ declare function getExtensionPath(): string;
45
+ /**
46
+ * Information about the current platform and extension
47
+ */
48
+ interface ExtensionInfo {
49
+ /** Current platform identifier (e.g., 'darwin-arm64') */
50
+ platform: Platform;
51
+ /** Name of the platform-specific npm package */
52
+ packageName: string;
53
+ /** Filename of the binary (e.g., 'cloudsync.dylib') */
54
+ binaryName: string;
55
+ /** Full path to the extension binary */
56
+ path: string;
57
+ }
58
+ /**
59
+ * Gets detailed information about the SQLite Sync extension
60
+ *
61
+ * @returns Extension information object
62
+ *
63
+ * @example
64
+ * ```typescript
65
+ * import { getExtensionInfo } from '@sqliteai/sqlite-sync';
66
+ *
67
+ * const info = getExtensionInfo();
68
+ * console.log(info);
69
+ * // {
70
+ * // platform: 'darwin-arm64',
71
+ * // packageName: '@sqliteai/sqlite-sync-darwin-arm64',
72
+ * // binaryName: 'cloudsync.dylib',
73
+ * // path: '/path/to/cloudsync.dylib'
74
+ * // }
75
+ * ```
76
+ */
77
+ declare function getExtensionInfo(): ExtensionInfo;
78
+ declare const _default: {
79
+ getExtensionPath: typeof getExtensionPath;
80
+ getExtensionInfo: typeof getExtensionInfo;
81
+ ExtensionNotFoundError: typeof ExtensionNotFoundError;
82
+ };
83
+
84
+ export { type ExtensionInfo, ExtensionNotFoundError, type Platform, _default as default, getBinaryName, getCurrentPlatform, getExtensionInfo, getExtensionPath, getPlatformPackageName, isMusl };
package/dist/index.js ADDED
@@ -0,0 +1,162 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var path = require('path');
6
+ var fs = require('fs');
7
+ var os = require('os');
8
+ var child_process = require('child_process');
9
+
10
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
11
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
12
+ }) : x)(function(x) {
13
+ if (typeof require !== "undefined") return require.apply(this, arguments);
14
+ throw Error('Dynamic require of "' + x + '" is not supported');
15
+ });
16
+ var PLATFORM_EXTENSIONS = {
17
+ darwin: ".dylib",
18
+ linux: ".so",
19
+ win32: ".dll"
20
+ };
21
+ function isMusl() {
22
+ var _a, _b, _c;
23
+ if (os.platform() !== "linux") {
24
+ return false;
25
+ }
26
+ const muslFiles = [
27
+ "/lib/ld-musl-x86_64.so.1",
28
+ "/lib/ld-musl-aarch64.so.1",
29
+ "/lib/ld-musl-armhf.so.1"
30
+ ];
31
+ for (const file of muslFiles) {
32
+ if (fs.existsSync(file)) {
33
+ return true;
34
+ }
35
+ }
36
+ try {
37
+ const lddVersion = child_process.execSync("ldd --version 2>&1", {
38
+ encoding: "utf-8",
39
+ stdio: ["pipe", "pipe", "pipe"]
40
+ });
41
+ if (lddVersion.includes("musl")) {
42
+ return true;
43
+ }
44
+ } catch {
45
+ }
46
+ try {
47
+ if (fs.existsSync("/etc/os-release")) {
48
+ const osRelease = fs.readFileSync("/etc/os-release", "utf-8");
49
+ if (osRelease.includes("Alpine") || osRelease.includes("musl")) {
50
+ return true;
51
+ }
52
+ }
53
+ } catch {
54
+ }
55
+ try {
56
+ const report = (_b = (_a = process.report) == null ? void 0 : _a.getReport) == null ? void 0 : _b.call(_a);
57
+ if (((_c = report == null ? void 0 : report.header) == null ? void 0 : _c.glibcVersionRuntime) === "") {
58
+ return true;
59
+ }
60
+ } catch {
61
+ }
62
+ return false;
63
+ }
64
+ function getCurrentPlatform() {
65
+ const platformName = os.platform();
66
+ const archName = os.arch();
67
+ if (platformName === "darwin") {
68
+ if (archName === "arm64") return "darwin-arm64";
69
+ if (archName === "x64" || archName === "ia32") return "darwin-x86_64";
70
+ }
71
+ if (platformName === "linux") {
72
+ const muslSuffix = isMusl() ? "-musl" : "";
73
+ if (archName === "arm64") {
74
+ return `linux-arm64${muslSuffix}`;
75
+ }
76
+ if (archName === "x64" || archName === "ia32") {
77
+ return `linux-x86_64${muslSuffix}`;
78
+ }
79
+ }
80
+ if (platformName === "win32") {
81
+ if (archName === "x64" || archName === "ia32") return "win32-x86_64";
82
+ }
83
+ throw new Error(
84
+ `Unsupported platform: ${platformName}-${archName}. Supported platforms: darwin-arm64, darwin-x86_64, linux-arm64, linux-x86_64, win32-x86_64 (with glibc or musl support for Linux)`
85
+ );
86
+ }
87
+ function getPlatformPackageName() {
88
+ const currentPlatform = getCurrentPlatform();
89
+ return `@sqliteai/sqlite-sync-${currentPlatform}`;
90
+ }
91
+ function getBinaryName() {
92
+ const platformName = os.platform();
93
+ const extension = PLATFORM_EXTENSIONS[platformName];
94
+ if (!extension) {
95
+ throw new Error(`Unknown platform: ${platformName}`);
96
+ }
97
+ return `cloudsync${extension}`;
98
+ }
99
+
100
+ // src/index.ts
101
+ var ExtensionNotFoundError = class extends Error {
102
+ constructor(message) {
103
+ super(message);
104
+ this.name = "ExtensionNotFoundError";
105
+ }
106
+ };
107
+ function tryLoadPlatformPackage() {
108
+ try {
109
+ const packageName = getPlatformPackageName();
110
+ const platformPackage = __require(packageName);
111
+ if ((platformPackage == null ? void 0 : platformPackage.path) && typeof platformPackage.path === "string") {
112
+ if (fs.existsSync(platformPackage.path)) {
113
+ return platformPackage.path;
114
+ }
115
+ }
116
+ } catch (error) {
117
+ }
118
+ return null;
119
+ }
120
+ function getExtensionPath() {
121
+ const platformPath = tryLoadPlatformPackage();
122
+ if (platformPath) {
123
+ return path.resolve(platformPath);
124
+ }
125
+ const currentPlatform = getCurrentPlatform();
126
+ const packageName = getPlatformPackageName();
127
+ throw new ExtensionNotFoundError(
128
+ `SQLite Sync extension not found for platform: ${currentPlatform}
129
+
130
+ The platform-specific package "${packageName}" is not installed.
131
+ This usually happens when:
132
+ 1. Your platform is not supported
133
+ 2. npm failed to install optional dependencies
134
+ 3. You're installing with --no-optional flag
135
+
136
+ Try running: npm install --force`
137
+ );
138
+ }
139
+ function getExtensionInfo() {
140
+ return {
141
+ platform: getCurrentPlatform(),
142
+ packageName: getPlatformPackageName(),
143
+ binaryName: getBinaryName(),
144
+ path: getExtensionPath()
145
+ };
146
+ }
147
+ var index_default = {
148
+ getExtensionPath,
149
+ getExtensionInfo,
150
+ ExtensionNotFoundError
151
+ };
152
+
153
+ exports.ExtensionNotFoundError = ExtensionNotFoundError;
154
+ exports.default = index_default;
155
+ exports.getBinaryName = getBinaryName;
156
+ exports.getCurrentPlatform = getCurrentPlatform;
157
+ exports.getExtensionInfo = getExtensionInfo;
158
+ exports.getExtensionPath = getExtensionPath;
159
+ exports.getPlatformPackageName = getPlatformPackageName;
160
+ exports.isMusl = isMusl;
161
+ //# sourceMappingURL=index.js.map
162
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/platform.ts","../src/index.ts"],"names":["platform","existsSync","execSync","readFileSync","arch","resolve"],"mappings":"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","file":"index.js","sourcesContent":["import { platform, arch } from 'node:os';\nimport { existsSync, readFileSync } from 'node:fs';\nimport { execSync } from 'node:child_process';\n\n/**\n * Supported platform identifiers\n */\nexport type Platform =\n | 'darwin-arm64'\n | 'darwin-x86_64'\n | 'linux-arm64'\n | 'linux-arm64-musl'\n | 'linux-x86_64'\n | 'linux-x86_64-musl'\n | 'win32-x86_64';\n\n/**\n * Binary extension for each platform\n */\nexport const PLATFORM_EXTENSIONS: Record<string, string> = {\n darwin: '.dylib',\n linux: '.so',\n win32: '.dll',\n} as const;\n\n/**\n * Detects if the system uses musl libc (Alpine Linux, etc.)\n * Uses multiple detection strategies for reliability\n */\nexport function isMusl(): boolean {\n // Only relevant for Linux\n if (platform() !== 'linux') {\n return false;\n }\n\n // Strategy 1: Check for musl-specific files\n const muslFiles = [\n '/lib/ld-musl-x86_64.so.1',\n '/lib/ld-musl-aarch64.so.1',\n '/lib/ld-musl-armhf.so.1',\n ];\n\n for (const file of muslFiles) {\n if (existsSync(file)) {\n return true;\n }\n }\n\n // Strategy 2: Check ldd version output\n try {\n const lddVersion = execSync('ldd --version 2>&1', {\n encoding: 'utf-8',\n stdio: ['pipe', 'pipe', 'pipe'],\n });\n\n if (lddVersion.includes('musl')) {\n return true;\n }\n } catch {\n // ldd command failed, continue to next strategy\n }\n\n // Strategy 3: Check /etc/os-release for Alpine\n try {\n if (existsSync('/etc/os-release')) {\n const osRelease = readFileSync('/etc/os-release', 'utf-8');\n if (osRelease.includes('Alpine') || osRelease.includes('musl')) {\n return true;\n }\n }\n } catch {\n // File read failed, continue to next strategy\n }\n\n // Strategy 4: Check process.report.getReport() for musl\n try {\n const report = (process as any).report?.getReport?.();\n if (report?.header?.glibcVersionRuntime === '') {\n // Empty glibc version often indicates musl\n return true;\n }\n } catch {\n // Report not available\n }\n\n return false;\n}\n\n/**\n * Gets the current platform identifier\n * @throws {Error} If the platform is unsupported\n */\nexport function getCurrentPlatform(): Platform {\n const platformName = platform();\n const archName = arch();\n\n // macOS\n if (platformName === 'darwin') {\n if (archName === 'arm64') return 'darwin-arm64';\n if (archName === 'x64' || archName === 'ia32') return 'darwin-x86_64';\n }\n\n // Linux (with musl detection)\n if (platformName === 'linux') {\n const muslSuffix = isMusl() ? '-musl' : '';\n\n if (archName === 'arm64') {\n return `linux-arm64${muslSuffix}` as Platform;\n }\n if (archName === 'x64' || archName === 'ia32') {\n return `linux-x86_64${muslSuffix}` as Platform;\n }\n }\n\n // Windows\n if (platformName === 'win32') {\n if (archName === 'x64' || archName === 'ia32') return 'win32-x86_64';\n }\n\n // Unsupported platform\n throw new Error(\n `Unsupported platform: ${platformName}-${archName}. ` +\n `Supported platforms: darwin-arm64, darwin-x86_64, linux-arm64, linux-x86_64, win32-x86_64 ` +\n `(with glibc or musl support for Linux)`\n );\n}\n\n/**\n * Gets the package name for the current platform\n */\nexport function getPlatformPackageName(): string {\n const currentPlatform = getCurrentPlatform();\n return `@sqliteai/sqlite-sync-${currentPlatform}`;\n}\n\n/**\n * Gets the binary filename for the current platform\n */\nexport function getBinaryName(): string {\n const platformName = platform();\n const extension = PLATFORM_EXTENSIONS[platformName];\n\n if (!extension) {\n throw new Error(`Unknown platform: ${platformName}`);\n }\n\n return `cloudsync${extension}`;\n}\n","import { resolve } from 'node:path';\nimport { existsSync } from 'node:fs';\nimport {\n getCurrentPlatform,\n getPlatformPackageName,\n getBinaryName,\n type Platform\n} from './platform.js';\n\n/**\n * Error thrown when the SQLite Sync extension cannot be found\n */\nexport class ExtensionNotFoundError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'ExtensionNotFoundError';\n }\n}\n\n/**\n * Attempts to load the platform-specific package\n * @returns The path to the extension binary, or null if not found\n */\nfunction tryLoadPlatformPackage(): string | null {\n try {\n const packageName = getPlatformPackageName();\n\n // Try to dynamically import the platform package\n // This works in both CommonJS and ESM\n const platformPackage = require(packageName);\n\n if (platformPackage?.path && typeof platformPackage.path === 'string') {\n if (existsSync(platformPackage.path)) {\n return platformPackage.path;\n }\n }\n } catch (error) {\n // Platform package not installed or failed to load\n // This is expected when optionalDependencies fail\n }\n\n return null;\n}\n\n/**\n * Gets the absolute path to the SQLite Sync extension binary for the current platform\n *\n * @returns Absolute path to the extension binary (.so, .dylib, or .dll)\n * @throws {ExtensionNotFoundError} If the extension binary cannot be found\n *\n * @example\n * ```typescript\n * import { getExtensionPath } from '@sqliteai/sqlite-sync';\n *\n * const extensionPath = getExtensionPath();\n * // On macOS ARM64: /path/to/node_modules/@sqliteai/sqlite-sync-darwin-arm64/cloudsync.dylib\n * ```\n */\nexport function getExtensionPath(): string {\n // Try to load from platform-specific package\n const platformPath = tryLoadPlatformPackage();\n if (platformPath) {\n return resolve(platformPath);\n }\n\n // If we reach here, the platform package wasn't installed\n const currentPlatform = getCurrentPlatform();\n const packageName = getPlatformPackageName();\n\n throw new ExtensionNotFoundError(\n `SQLite Sync extension not found for platform: ${currentPlatform}\\n\\n` +\n `The platform-specific package \"${packageName}\" is not installed.\\n` +\n `This usually happens when:\\n` +\n ` 1. Your platform is not supported\\n` +\n ` 2. npm failed to install optional dependencies\\n` +\n ` 3. You're installing with --no-optional flag\\n\\n` +\n `Try running: npm install --force`\n );\n}\n\n/**\n * Information about the current platform and extension\n */\nexport interface ExtensionInfo {\n /** Current platform identifier (e.g., 'darwin-arm64') */\n platform: Platform;\n /** Name of the platform-specific npm package */\n packageName: string;\n /** Filename of the binary (e.g., 'cloudsync.dylib') */\n binaryName: string;\n /** Full path to the extension binary */\n path: string;\n}\n\n/**\n * Gets detailed information about the SQLite Sync extension\n *\n * @returns Extension information object\n *\n * @example\n * ```typescript\n * import { getExtensionInfo } from '@sqliteai/sqlite-sync';\n *\n * const info = getExtensionInfo();\n * console.log(info);\n * // {\n * // platform: 'darwin-arm64',\n * // packageName: '@sqliteai/sqlite-sync-darwin-arm64',\n * // binaryName: 'cloudsync.dylib',\n * // path: '/path/to/cloudsync.dylib'\n * // }\n * ```\n */\nexport function getExtensionInfo(): ExtensionInfo {\n return {\n platform: getCurrentPlatform(),\n packageName: getPlatformPackageName(),\n binaryName: getBinaryName(),\n path: getExtensionPath(),\n };\n}\n\n// Default export for CommonJS compatibility\nexport default {\n getExtensionPath,\n getExtensionInfo,\n ExtensionNotFoundError,\n};\n\n// Re-export platform utilities\nexport { getCurrentPlatform, getPlatformPackageName, getBinaryName, isMusl } from './platform.js';\nexport type { Platform } from './platform.js';\n"]}
package/dist/index.mjs ADDED
@@ -0,0 +1,151 @@
1
+ import { resolve } from 'path';
2
+ import { existsSync, readFileSync } from 'fs';
3
+ import { platform, arch } from 'os';
4
+ import { execSync } from 'child_process';
5
+
6
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
7
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
8
+ }) : x)(function(x) {
9
+ if (typeof require !== "undefined") return require.apply(this, arguments);
10
+ throw Error('Dynamic require of "' + x + '" is not supported');
11
+ });
12
+ var PLATFORM_EXTENSIONS = {
13
+ darwin: ".dylib",
14
+ linux: ".so",
15
+ win32: ".dll"
16
+ };
17
+ function isMusl() {
18
+ var _a, _b, _c;
19
+ if (platform() !== "linux") {
20
+ return false;
21
+ }
22
+ const muslFiles = [
23
+ "/lib/ld-musl-x86_64.so.1",
24
+ "/lib/ld-musl-aarch64.so.1",
25
+ "/lib/ld-musl-armhf.so.1"
26
+ ];
27
+ for (const file of muslFiles) {
28
+ if (existsSync(file)) {
29
+ return true;
30
+ }
31
+ }
32
+ try {
33
+ const lddVersion = execSync("ldd --version 2>&1", {
34
+ encoding: "utf-8",
35
+ stdio: ["pipe", "pipe", "pipe"]
36
+ });
37
+ if (lddVersion.includes("musl")) {
38
+ return true;
39
+ }
40
+ } catch {
41
+ }
42
+ try {
43
+ if (existsSync("/etc/os-release")) {
44
+ const osRelease = readFileSync("/etc/os-release", "utf-8");
45
+ if (osRelease.includes("Alpine") || osRelease.includes("musl")) {
46
+ return true;
47
+ }
48
+ }
49
+ } catch {
50
+ }
51
+ try {
52
+ const report = (_b = (_a = process.report) == null ? void 0 : _a.getReport) == null ? void 0 : _b.call(_a);
53
+ if (((_c = report == null ? void 0 : report.header) == null ? void 0 : _c.glibcVersionRuntime) === "") {
54
+ return true;
55
+ }
56
+ } catch {
57
+ }
58
+ return false;
59
+ }
60
+ function getCurrentPlatform() {
61
+ const platformName = platform();
62
+ const archName = arch();
63
+ if (platformName === "darwin") {
64
+ if (archName === "arm64") return "darwin-arm64";
65
+ if (archName === "x64" || archName === "ia32") return "darwin-x86_64";
66
+ }
67
+ if (platformName === "linux") {
68
+ const muslSuffix = isMusl() ? "-musl" : "";
69
+ if (archName === "arm64") {
70
+ return `linux-arm64${muslSuffix}`;
71
+ }
72
+ if (archName === "x64" || archName === "ia32") {
73
+ return `linux-x86_64${muslSuffix}`;
74
+ }
75
+ }
76
+ if (platformName === "win32") {
77
+ if (archName === "x64" || archName === "ia32") return "win32-x86_64";
78
+ }
79
+ throw new Error(
80
+ `Unsupported platform: ${platformName}-${archName}. Supported platforms: darwin-arm64, darwin-x86_64, linux-arm64, linux-x86_64, win32-x86_64 (with glibc or musl support for Linux)`
81
+ );
82
+ }
83
+ function getPlatformPackageName() {
84
+ const currentPlatform = getCurrentPlatform();
85
+ return `@sqliteai/sqlite-sync-${currentPlatform}`;
86
+ }
87
+ function getBinaryName() {
88
+ const platformName = platform();
89
+ const extension = PLATFORM_EXTENSIONS[platformName];
90
+ if (!extension) {
91
+ throw new Error(`Unknown platform: ${platformName}`);
92
+ }
93
+ return `cloudsync${extension}`;
94
+ }
95
+
96
+ // src/index.ts
97
+ var ExtensionNotFoundError = class extends Error {
98
+ constructor(message) {
99
+ super(message);
100
+ this.name = "ExtensionNotFoundError";
101
+ }
102
+ };
103
+ function tryLoadPlatformPackage() {
104
+ try {
105
+ const packageName = getPlatformPackageName();
106
+ const platformPackage = __require(packageName);
107
+ if ((platformPackage == null ? void 0 : platformPackage.path) && typeof platformPackage.path === "string") {
108
+ if (existsSync(platformPackage.path)) {
109
+ return platformPackage.path;
110
+ }
111
+ }
112
+ } catch (error) {
113
+ }
114
+ return null;
115
+ }
116
+ function getExtensionPath() {
117
+ const platformPath = tryLoadPlatformPackage();
118
+ if (platformPath) {
119
+ return resolve(platformPath);
120
+ }
121
+ const currentPlatform = getCurrentPlatform();
122
+ const packageName = getPlatformPackageName();
123
+ throw new ExtensionNotFoundError(
124
+ `SQLite Sync extension not found for platform: ${currentPlatform}
125
+
126
+ The platform-specific package "${packageName}" is not installed.
127
+ This usually happens when:
128
+ 1. Your platform is not supported
129
+ 2. npm failed to install optional dependencies
130
+ 3. You're installing with --no-optional flag
131
+
132
+ Try running: npm install --force`
133
+ );
134
+ }
135
+ function getExtensionInfo() {
136
+ return {
137
+ platform: getCurrentPlatform(),
138
+ packageName: getPlatformPackageName(),
139
+ binaryName: getBinaryName(),
140
+ path: getExtensionPath()
141
+ };
142
+ }
143
+ var index_default = {
144
+ getExtensionPath,
145
+ getExtensionInfo,
146
+ ExtensionNotFoundError
147
+ };
148
+
149
+ export { ExtensionNotFoundError, index_default as default, getBinaryName, getCurrentPlatform, getExtensionInfo, getExtensionPath, getPlatformPackageName, isMusl };
150
+ //# sourceMappingURL=index.mjs.map
151
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/platform.ts","../src/index.ts"],"names":["existsSync"],"mappings":"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","file":"index.mjs","sourcesContent":["import { platform, arch } from 'node:os';\nimport { existsSync, readFileSync } from 'node:fs';\nimport { execSync } from 'node:child_process';\n\n/**\n * Supported platform identifiers\n */\nexport type Platform =\n | 'darwin-arm64'\n | 'darwin-x86_64'\n | 'linux-arm64'\n | 'linux-arm64-musl'\n | 'linux-x86_64'\n | 'linux-x86_64-musl'\n | 'win32-x86_64';\n\n/**\n * Binary extension for each platform\n */\nexport const PLATFORM_EXTENSIONS: Record<string, string> = {\n darwin: '.dylib',\n linux: '.so',\n win32: '.dll',\n} as const;\n\n/**\n * Detects if the system uses musl libc (Alpine Linux, etc.)\n * Uses multiple detection strategies for reliability\n */\nexport function isMusl(): boolean {\n // Only relevant for Linux\n if (platform() !== 'linux') {\n return false;\n }\n\n // Strategy 1: Check for musl-specific files\n const muslFiles = [\n '/lib/ld-musl-x86_64.so.1',\n '/lib/ld-musl-aarch64.so.1',\n '/lib/ld-musl-armhf.so.1',\n ];\n\n for (const file of muslFiles) {\n if (existsSync(file)) {\n return true;\n }\n }\n\n // Strategy 2: Check ldd version output\n try {\n const lddVersion = execSync('ldd --version 2>&1', {\n encoding: 'utf-8',\n stdio: ['pipe', 'pipe', 'pipe'],\n });\n\n if (lddVersion.includes('musl')) {\n return true;\n }\n } catch {\n // ldd command failed, continue to next strategy\n }\n\n // Strategy 3: Check /etc/os-release for Alpine\n try {\n if (existsSync('/etc/os-release')) {\n const osRelease = readFileSync('/etc/os-release', 'utf-8');\n if (osRelease.includes('Alpine') || osRelease.includes('musl')) {\n return true;\n }\n }\n } catch {\n // File read failed, continue to next strategy\n }\n\n // Strategy 4: Check process.report.getReport() for musl\n try {\n const report = (process as any).report?.getReport?.();\n if (report?.header?.glibcVersionRuntime === '') {\n // Empty glibc version often indicates musl\n return true;\n }\n } catch {\n // Report not available\n }\n\n return false;\n}\n\n/**\n * Gets the current platform identifier\n * @throws {Error} If the platform is unsupported\n */\nexport function getCurrentPlatform(): Platform {\n const platformName = platform();\n const archName = arch();\n\n // macOS\n if (platformName === 'darwin') {\n if (archName === 'arm64') return 'darwin-arm64';\n if (archName === 'x64' || archName === 'ia32') return 'darwin-x86_64';\n }\n\n // Linux (with musl detection)\n if (platformName === 'linux') {\n const muslSuffix = isMusl() ? '-musl' : '';\n\n if (archName === 'arm64') {\n return `linux-arm64${muslSuffix}` as Platform;\n }\n if (archName === 'x64' || archName === 'ia32') {\n return `linux-x86_64${muslSuffix}` as Platform;\n }\n }\n\n // Windows\n if (platformName === 'win32') {\n if (archName === 'x64' || archName === 'ia32') return 'win32-x86_64';\n }\n\n // Unsupported platform\n throw new Error(\n `Unsupported platform: ${platformName}-${archName}. ` +\n `Supported platforms: darwin-arm64, darwin-x86_64, linux-arm64, linux-x86_64, win32-x86_64 ` +\n `(with glibc or musl support for Linux)`\n );\n}\n\n/**\n * Gets the package name for the current platform\n */\nexport function getPlatformPackageName(): string {\n const currentPlatform = getCurrentPlatform();\n return `@sqliteai/sqlite-sync-${currentPlatform}`;\n}\n\n/**\n * Gets the binary filename for the current platform\n */\nexport function getBinaryName(): string {\n const platformName = platform();\n const extension = PLATFORM_EXTENSIONS[platformName];\n\n if (!extension) {\n throw new Error(`Unknown platform: ${platformName}`);\n }\n\n return `cloudsync${extension}`;\n}\n","import { resolve } from 'node:path';\nimport { existsSync } from 'node:fs';\nimport {\n getCurrentPlatform,\n getPlatformPackageName,\n getBinaryName,\n type Platform\n} from './platform.js';\n\n/**\n * Error thrown when the SQLite Sync extension cannot be found\n */\nexport class ExtensionNotFoundError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'ExtensionNotFoundError';\n }\n}\n\n/**\n * Attempts to load the platform-specific package\n * @returns The path to the extension binary, or null if not found\n */\nfunction tryLoadPlatformPackage(): string | null {\n try {\n const packageName = getPlatformPackageName();\n\n // Try to dynamically import the platform package\n // This works in both CommonJS and ESM\n const platformPackage = require(packageName);\n\n if (platformPackage?.path && typeof platformPackage.path === 'string') {\n if (existsSync(platformPackage.path)) {\n return platformPackage.path;\n }\n }\n } catch (error) {\n // Platform package not installed or failed to load\n // This is expected when optionalDependencies fail\n }\n\n return null;\n}\n\n/**\n * Gets the absolute path to the SQLite Sync extension binary for the current platform\n *\n * @returns Absolute path to the extension binary (.so, .dylib, or .dll)\n * @throws {ExtensionNotFoundError} If the extension binary cannot be found\n *\n * @example\n * ```typescript\n * import { getExtensionPath } from '@sqliteai/sqlite-sync';\n *\n * const extensionPath = getExtensionPath();\n * // On macOS ARM64: /path/to/node_modules/@sqliteai/sqlite-sync-darwin-arm64/cloudsync.dylib\n * ```\n */\nexport function getExtensionPath(): string {\n // Try to load from platform-specific package\n const platformPath = tryLoadPlatformPackage();\n if (platformPath) {\n return resolve(platformPath);\n }\n\n // If we reach here, the platform package wasn't installed\n const currentPlatform = getCurrentPlatform();\n const packageName = getPlatformPackageName();\n\n throw new ExtensionNotFoundError(\n `SQLite Sync extension not found for platform: ${currentPlatform}\\n\\n` +\n `The platform-specific package \"${packageName}\" is not installed.\\n` +\n `This usually happens when:\\n` +\n ` 1. Your platform is not supported\\n` +\n ` 2. npm failed to install optional dependencies\\n` +\n ` 3. You're installing with --no-optional flag\\n\\n` +\n `Try running: npm install --force`\n );\n}\n\n/**\n * Information about the current platform and extension\n */\nexport interface ExtensionInfo {\n /** Current platform identifier (e.g., 'darwin-arm64') */\n platform: Platform;\n /** Name of the platform-specific npm package */\n packageName: string;\n /** Filename of the binary (e.g., 'cloudsync.dylib') */\n binaryName: string;\n /** Full path to the extension binary */\n path: string;\n}\n\n/**\n * Gets detailed information about the SQLite Sync extension\n *\n * @returns Extension information object\n *\n * @example\n * ```typescript\n * import { getExtensionInfo } from '@sqliteai/sqlite-sync';\n *\n * const info = getExtensionInfo();\n * console.log(info);\n * // {\n * // platform: 'darwin-arm64',\n * // packageName: '@sqliteai/sqlite-sync-darwin-arm64',\n * // binaryName: 'cloudsync.dylib',\n * // path: '/path/to/cloudsync.dylib'\n * // }\n * ```\n */\nexport function getExtensionInfo(): ExtensionInfo {\n return {\n platform: getCurrentPlatform(),\n packageName: getPlatformPackageName(),\n binaryName: getBinaryName(),\n path: getExtensionPath(),\n };\n}\n\n// Default export for CommonJS compatibility\nexport default {\n getExtensionPath,\n getExtensionInfo,\n ExtensionNotFoundError,\n};\n\n// Re-export platform utilities\nexport { getCurrentPlatform, getPlatformPackageName, getBinaryName, isMusl } from './platform.js';\nexport type { Platform } from './platform.js';\n"]}
package/package.json ADDED
@@ -0,0 +1,70 @@
1
+ {
2
+ "name": "@sqliteai/sqlite-sync",
3
+ "version": "0.8.53",
4
+ "description": "SQLite Sync extension for Node.js - Sync on-device databases with the cloud",
5
+ "main": "./dist/index.js",
6
+ "module": "./dist/index.mjs",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "import": {
11
+ "types": "./dist/index.d.mts",
12
+ "default": "./dist/index.mjs"
13
+ },
14
+ "require": {
15
+ "types": "./dist/index.d.ts",
16
+ "default": "./dist/index.js"
17
+ }
18
+ }
19
+ },
20
+ "files": [
21
+ "dist",
22
+ "README.md",
23
+ "LICENSE.md"
24
+ ],
25
+ "scripts": {
26
+ "build": "tsup",
27
+ "prepublishOnly": "npm run build",
28
+ "test": "vitest",
29
+ "typecheck": "tsc --noEmit",
30
+ "generate-platforms": "node generate-platform-packages.js"
31
+ },
32
+ "keywords": [
33
+ "sqlite",
34
+ "sync",
35
+ "cloud",
36
+ "replication",
37
+ "offline-first",
38
+ "database-sync",
39
+ "sqlite-extension"
40
+ ],
41
+ "author": "Gioele Cantoni (gioele@sqlitecloud.io)",
42
+ "license": "SEE LICENSE IN LICENSE.md",
43
+ "repository": {
44
+ "type": "git",
45
+ "url": "https://github.com/sqliteai/sqlite-sync.git",
46
+ "directory": "packages/node"
47
+ },
48
+ "homepage": "https://github.com/sqliteai/sqlite-sync#readme",
49
+ "bugs": {
50
+ "url": "https://github.com/sqliteai/sqlite-sync/issues"
51
+ },
52
+ "engines": {
53
+ "node": ">=16.0.0"
54
+ },
55
+ "optionalDependencies": {
56
+ "@sqliteai/sqlite-sync-darwin-arm64": "0.8.53",
57
+ "@sqliteai/sqlite-sync-darwin-x86_64": "0.8.53",
58
+ "@sqliteai/sqlite-sync-linux-arm64": "0.8.53",
59
+ "@sqliteai/sqlite-sync-linux-arm64-musl": "0.8.53",
60
+ "@sqliteai/sqlite-sync-linux-x86_64": "0.8.53",
61
+ "@sqliteai/sqlite-sync-linux-x86_64-musl": "0.8.53",
62
+ "@sqliteai/sqlite-sync-win32-x86_64": "0.8.53"
63
+ },
64
+ "devDependencies": {
65
+ "@types/node": "^20.0.0",
66
+ "tsup": "^8.0.0",
67
+ "typescript": "^5.3.0",
68
+ "vitest": "^3.2.4"
69
+ }
70
+ }