jsql-neo 5.5.0 → 6.0.0

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.
Files changed (81) hide show
  1. package/LICENSE +202 -202
  2. package/README.md +8155 -8097
  3. package/bin/jsql +320 -320
  4. package/bin/jsql-server +90 -90
  5. package/bin/jsql-server-control.js +177 -177
  6. package/index.d.ts +412 -385
  7. package/index.js +128 -124
  8. package/lib/ast.js +214 -214
  9. package/lib/btree.js +478 -413
  10. package/lib/cache.js +328 -328
  11. package/lib/client.js +125 -125
  12. package/lib/database.js +1741 -1744
  13. package/lib/date-types.js +182 -182
  14. package/lib/errors.js +89 -89
  15. package/lib/jsql_format.js +497 -497
  16. package/lib/migrate.js +254 -254
  17. package/lib/mod.js +292 -292
  18. package/lib/mongo_server.js +607 -607
  19. package/lib/multiserver.js +140 -140
  20. package/lib/mysql_compat.js +413 -413
  21. package/lib/mysql_server.js +1237 -1237
  22. package/lib/native_client.js +722 -732
  23. package/lib/nedb_compat.js +506 -506
  24. package/lib/pg_server.js +864 -864
  25. package/lib/plugin.js +259 -35
  26. package/lib/plugins/audit.js +37 -0
  27. package/lib/plugins/index.js +72 -0
  28. package/lib/plugins/logger.js +35 -0
  29. package/lib/plugins/metrics.js +38 -0
  30. package/lib/plugins/timestamps.js +57 -0
  31. package/lib/plugins/validation.js +128 -0
  32. package/lib/prepared.js +37 -0
  33. package/lib/query.js +834 -815
  34. package/lib/redis_server.js +571 -571
  35. package/lib/sql.js +4053 -3460
  36. package/lib/sqlite_compat.js +323 -323
  37. package/lib/sqlite_worker.js +264 -264
  38. package/lib/table.js +1351 -1304
  39. package/lib/tui.js +502 -502
  40. package/lib/wasm.js +1 -1
  41. package/lib/wasm_client.js +715 -718
  42. package/lib/web_ui.js +257 -257
  43. package/native/jsql-neo-native.node +0 -0
  44. package/nativesrc/jsql-neo-core/Cargo.lock +462 -455
  45. package/nativesrc/jsql-neo-core/Cargo.toml +26 -24
  46. package/nativesrc/jsql-neo-core/src/engine/hybrid.rs +492 -455
  47. package/nativesrc/jsql-neo-core/src/engine/memory.rs +191 -168
  48. package/nativesrc/jsql-neo-core/src/engine/mod.rs +74 -62
  49. package/nativesrc/jsql-neo-core/src/engine/table.rs +996 -700
  50. package/nativesrc/jsql-neo-core/src/lib.rs +2 -2
  51. package/nativesrc/jsql-neo-core/src/storage/mod.rs +2 -2
  52. package/nativesrc/jsql-neo-core/src/storage/persistent.rs +1 -1
  53. package/nativesrc/jsql-neo-core/src/storage/wal.rs +298 -85
  54. package/nativesrc/jsql-neo-core/src/types.rs +93 -93
  55. package/nativesrc/jsql-neo-native/Cargo.lock +613 -606
  56. package/nativesrc/jsql-neo-native/Cargo.toml +24 -16
  57. package/nativesrc/jsql-neo-native/build.rs +3 -3
  58. package/nativesrc/jsql-neo-native/package.json +7 -7
  59. package/nativesrc/jsql-neo-native/src/lib.rs +281 -269
  60. package/nativesrc/jsql-neo-wasm/Cargo.lock +472 -465
  61. package/nativesrc/jsql-neo-wasm/Cargo.toml +22 -15
  62. package/nativesrc/jsql-neo-wasm/src/lib.rs +463 -447
  63. package/package.json +87 -87
  64. package/postinstall.js +158 -158
  65. package/test/btree.test.js +144 -128
  66. package/test/coverage.js +187 -187
  67. package/test/join.test.js +110 -110
  68. package/test/native.test.js +158 -158
  69. package/test/query-opt.test.js +109 -0
  70. package/test/regress-5.1.0.js +271 -271
  71. package/test/smoke.js +58 -58
  72. package/test/sql-parser.test.js +450 -273
  73. package/test/wasm.test.js +110 -110
  74. package/wasm/browser.d.ts +89 -89
  75. package/wasm/browser.mjs +591 -569
  76. package/wasm/browser_bg.mjs +618 -597
  77. package/wasm/jsql_neo_wasm.d.ts +44 -38
  78. package/wasm/jsql_neo_wasm.js +641 -520
  79. package/wasm/jsql_neo_wasm_bg.wasm +0 -0
  80. package/wasm/jsql_neo_wasm_bg.wasm.d.ts +26 -26
  81. package/wasm/package.json +11 -11
package/package.json CHANGED
@@ -1,87 +1,87 @@
1
- {
2
- "name": "jsql-neo",
3
- "version": "5.5.0",
4
- "description": "JSQL-NEO — Rust-powered embedded database with WASM, REST API, B-Tree indexes, WAL, crash recovery",
5
- "main": "index.js",
6
- "types": "index.d.ts",
7
- "exports": {
8
- ".": {
9
- "types": "./index.d.ts",
10
- "browser": "./wasm/browser.mjs",
11
- "import": "./index.js",
12
- "require": "./index.js",
13
- "default": "./index.js"
14
- },
15
- "./cli": "./bin/jsql",
16
- "./mysql2": "./lib/mysql_compat.js",
17
- "./mysql": "./lib/mysql_compat.js",
18
- "./wasm/browser.mjs": {
19
- "types": "./wasm/browser.d.ts",
20
- "default": "./wasm/browser.mjs"
21
- },
22
- "./wasm/browser.d.ts": "./wasm/browser.d.ts",
23
- "./wasm/*": "./wasm/*",
24
- "./lib/*.js": "./lib/*.js",
25
- "./lib/*": "./lib/*.js",
26
- "./package.json": "./package.json",
27
- "./sqlite": "./lib/sqlite_compat.js"
28
- },
29
- "bin": {
30
- "jsql": "./bin/jsql"
31
- },
32
- "files": [
33
- "index.js",
34
- "index.d.ts",
35
- "lib/",
36
- "bin/",
37
- "wasm/",
38
- "native/",
39
- "nativesrc/",
40
- "!nativesrc/**/target/",
41
- "postinstall.js",
42
- "test/",
43
- "README.md",
44
- "LICENSE"
45
- ],
46
- "scripts": {
47
- "postinstall": "node postinstall.js",
48
- "test": "node test/smoke.js && node test/sql-parser.test.js",
49
- "test:parser": "node test/sql-parser.test.js",
50
- "test:btree": "node test/btree.test.js",
51
- "test:native": "node test/native.test.js",
52
- "test:regress": "node test/regress-5.1.0.js",
53
- "test:all": "node test/smoke.js && node test/sql-parser.test.js && node test/native.test.js && node test/wasm.test.js && node test/coverage.js && node test/regress-5.1.0.js && node test/join.test.js && node test/btree.test.js",
54
- "test:coverage": "c8 --all --include='lib/**' --exclude='lib/mysql_server.js' --exclude='lib/native_client.js' --exclude='lib/wasm_client.js' --exclude='lib/mysql_compat.js' --exclude='lib/nedb_compat.js' --exclude='lib/plugin.js' --reporter=text --reporter=lcov node test/coverage.js",
55
- "test:orms": "node examples/orms/run-all.js"
56
- },
57
- "keywords": [
58
- "database",
59
- "sql",
60
- "embedded",
61
- "rust",
62
- "wasm",
63
- "json",
64
- "javascript",
65
- "jsql",
66
- "nosql",
67
- "rest-api",
68
- "high-performance"
69
- ],
70
- "author": "Vexify",
71
- "license": "Apache-2.0",
72
- "repository": {
73
- "type": "git",
74
- "url": "https://github.com/vexify-org/JSQL-neo.git"
75
- },
76
- "bugs": "https://github.com/vexify-org/JSQL-neo/issues",
77
- "homepage": "https://github.com/vexify-org/JSQL-neo#readme",
78
- "engines": {
79
- "node": ">=14.0.0"
80
- },
81
- "dependencies": {
82
- "@vexify-org/yaggs": "^8.1.0"
83
- },
84
- "devDependencies": {
85
- "c8": "^10.1.2"
86
- }
87
- }
1
+ {
2
+ "name": "jsql-neo",
3
+ "version": "6.0.0",
4
+ "description": "JSQL-NEO — Rust-powered embedded database with WASM, REST API, B-Tree indexes, WAL, crash recovery",
5
+ "main": "index.js",
6
+ "types": "index.d.ts",
7
+ "exports": {
8
+ ".": {
9
+ "types": "./index.d.ts",
10
+ "browser": "./wasm/browser.mjs",
11
+ "import": "./index.js",
12
+ "require": "./index.js",
13
+ "default": "./index.js"
14
+ },
15
+ "./cli": "./bin/jsql",
16
+ "./mysql2": "./lib/mysql_compat.js",
17
+ "./mysql": "./lib/mysql_compat.js",
18
+ "./wasm/browser.mjs": {
19
+ "types": "./wasm/browser.d.ts",
20
+ "default": "./wasm/browser.mjs"
21
+ },
22
+ "./wasm/browser.d.ts": "./wasm/browser.d.ts",
23
+ "./wasm/*": "./wasm/*",
24
+ "./lib/*.js": "./lib/*.js",
25
+ "./lib/*": "./lib/*.js",
26
+ "./package.json": "./package.json",
27
+ "./sqlite": "./lib/sqlite_compat.js"
28
+ },
29
+ "bin": {
30
+ "jsql": "./bin/jsql"
31
+ },
32
+ "files": [
33
+ "index.js",
34
+ "index.d.ts",
35
+ "lib/",
36
+ "bin/",
37
+ "wasm/",
38
+ "native/",
39
+ "nativesrc/",
40
+ "!nativesrc/**/target/",
41
+ "postinstall.js",
42
+ "test/",
43
+ "README.md",
44
+ "LICENSE"
45
+ ],
46
+ "scripts": {
47
+ "postinstall": "node postinstall.js",
48
+ "test": "node test/smoke.js && node test/sql-parser.test.js && node test/query-opt.test.js",
49
+ "test:parser": "node test/sql-parser.test.js",
50
+ "test:btree": "node test/btree.test.js",
51
+ "test:native": "node test/native.test.js",
52
+ "test:regress": "node test/regress-5.1.0.js",
53
+ "test:all": "node test/smoke.js && node test/sql-parser.test.js && node test/native.test.js && node test/wasm.test.js && node test/coverage.js && node test/regress-5.1.0.js && node test/join.test.js && node test/btree.test.js",
54
+ "test:coverage": "c8 --all --include='lib/**' --exclude='lib/mysql_server.js' --exclude='lib/native_client.js' --exclude='lib/wasm_client.js' --exclude='lib/mysql_compat.js' --exclude='lib/nedb_compat.js' --exclude='lib/plugin.js' --reporter=text --reporter=lcov node test/coverage.js",
55
+ "test:orms": "node examples/orms/run-all.js"
56
+ },
57
+ "keywords": [
58
+ "database",
59
+ "sql",
60
+ "embedded",
61
+ "rust",
62
+ "wasm",
63
+ "json",
64
+ "javascript",
65
+ "jsql",
66
+ "nosql",
67
+ "rest-api",
68
+ "high-performance"
69
+ ],
70
+ "author": "Vexify",
71
+ "license": "Apache-2.0",
72
+ "repository": {
73
+ "type": "git",
74
+ "url": "https://github.com/vexify-org/JSQL-neo.git"
75
+ },
76
+ "bugs": "https://github.com/vexify-org/JSQL-neo/issues",
77
+ "homepage": "https://github.com/vexify-org/JSQL-neo#readme",
78
+ "engines": {
79
+ "node": ">=14.0.0"
80
+ },
81
+ "dependencies": {
82
+ "@vexify-org/yaggs": "^8.1.0"
83
+ },
84
+ "devDependencies": {
85
+ "c8": "^10.1.2"
86
+ }
87
+ }
package/postinstall.js CHANGED
@@ -1,159 +1,159 @@
1
- const { execSync } = require('child_process');
2
- const fs = require('fs');
3
- const path = require('path');
4
- const http = require('http');
5
- const https = require('https');
6
-
7
- const ROOT = __dirname;
8
- const pkg = JSON.parse(fs.readFileSync(path.join(ROOT, 'package.json'), 'utf8'));
9
-
10
- // Server CLI binary (bin/jsql-neo-server)
11
- const BIN_NAME = process.platform === 'win32' ? 'jsql-neo-server.exe' : 'jsql-neo-server';
12
- const BP = path.join(ROOT, 'bin', BIN_NAME);
13
-
14
- // Native N-API module (native/jsql-neo-native.node)
15
- const NATIVE_PATH = path.join(ROOT, 'native', 'jsql-neo-native.node');
16
-
17
- // GitHub 加速代理前缀;把原始 github 链接直接拼在后面即可
18
- const GHPROXY = 'https://gh-proxy.com/';
19
- const TAG = `v${pkg.version}`;
20
-
21
- // 从 repository 字段提取 owner/repo,例如 vexify-org/JSQL-neo
22
- const REPO = (pkg.repository && pkg.repository.url)
23
- ? pkg.repository.url.replace(/\.git$/, '').replace(/^.*github\.com\//i, '')
24
- : 'vexify-org/JSQL-neo';
25
-
26
- // 与 .github/workflows/build-native.yml 中发布的资产命名保持一致
27
- function nativeTargetSuffix(platform = process.platform, arch = process.arch) {
28
- const p = platform === 'win32' ? 'win32' : platform === 'darwin' ? 'darwin' : 'linux';
29
- const a = arch === 'x64' ? 'x64' : arch === 'arm64' ? 'arm64' : arch;
30
- if (p === 'linux') return `${p}-${a}-gnu`;
31
- if (p === 'darwin') return `${p}-${a}`;
32
- return `${p}-${a}-msvc`;
33
- }
34
-
35
- function download(url, dest) {
36
- return new Promise((resolve, reject) => {
37
- const mod = url.startsWith('https:') ? https : http;
38
- const req = mod.get(url, (res) => {
39
- if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
40
- res.resume();
41
- download(res.headers.location, dest).then(resolve, reject);
42
- return;
43
- }
44
- if (res.statusCode !== 200) {
45
- res.resume();
46
- reject(new Error(`HTTP ${res.statusCode} for ${url}`));
47
- return;
48
- }
49
- fs.mkdirSync(path.dirname(dest), { recursive: true });
50
- const ws = fs.createWriteStream(dest);
51
- ws.on('error', reject);
52
- res.pipe(ws);
53
- res.on('end', () => ws.end(() => resolve()));
54
- });
55
- req.on('error', reject);
56
- });
57
- }
58
-
59
- function buildNativeFromSource() {
60
- const crate = path.join(ROOT, 'nativesrc', 'jsql-neo-native');
61
- if (!fs.existsSync(path.join(crate, 'Cargo.toml'))) return;
62
- console.log('[jsql-neo] building native module from source...');
63
- try {
64
- execSync('cargo build --release', { cwd: crate, stdio: 'inherit' });
65
- const rel = path.join(crate, 'target', 'release');
66
- const src = process.platform === 'win32'
67
- ? path.join(rel, 'jsql_neo_native.dll')
68
- : process.platform === 'darwin'
69
- ? path.join(rel, 'libjsql_neo_native.dylib')
70
- : path.join(rel, 'libjsql_neo_native.so');
71
- if (fs.existsSync(src)) {
72
- fs.mkdirSync(path.dirname(NATIVE_PATH), { recursive: true });
73
- fs.copyFileSync(src, NATIVE_PATH);
74
- fs.chmodSync(NATIVE_PATH, 0o755);
75
- console.log(`[jsql-neo] native module built: native/jsql-neo-native.node`);
76
- }
77
- } catch (e) {
78
- console.warn('[jsql-neo] native build failed:', e.message);
79
- }
80
- }
81
-
82
- // 尝试加载 native 模块;能成功 require 才算「可用」,否则视为不可用
83
- function tryLoadNative() {
84
- if (!fs.existsSync(NATIVE_PATH)) return false;
85
- try {
86
- require(NATIVE_PATH);
87
- fs.chmodSync(NATIVE_PATH, 0o755);
88
- return true;
89
- } catch (e) {
90
- console.warn(`[jsql-neo] existing native module cannot be loaded (${e.code || e.message}), will re-acquire.`);
91
- try { fs.unlinkSync(NATIVE_PATH); } catch (_) { /* ignore */ }
92
- return false;
93
- }
94
- }
95
-
96
- async function downloadAndVerify() {
97
- const asset = `jsql-neo-native.${nativeTargetSuffix()}.node`;
98
- const url = `${GHPROXY}https://github.com/${REPO}/releases/download/${TAG}/${asset}`;
99
- console.log(`[jsql-neo] downloading native module: ${url}`);
100
- try {
101
- await download(url, NATIVE_PATH);
102
- if (!tryLoadNative()) {
103
- console.warn('[jsql-neo] downloaded module also invalid, removed.');
104
- return false;
105
- }
106
- console.log('[jsql-neo] native module downloaded: native/jsql-neo-native.node');
107
- return true;
108
- } catch (e) {
109
- console.warn('[jsql-neo] download failed, falling back to source build:', e.message);
110
- return false;
111
- }
112
- }
113
-
114
- async function ensureNativeNode() {
115
- // 已存在且能加载 → 直接用;否则删掉并从 gh-proxy.com 下载,找不到才回退源码编译
116
- if (tryLoadNative()) {
117
- console.log('[jsql-neo] native module ready: native/jsql-neo-native.node');
118
- return;
119
- }
120
- if (await downloadAndVerify()) return;
121
- buildNativeFromSource();
122
- }
123
-
124
- function ensureServerBinary() {
125
- if (fs.existsSync(BP)) {
126
- fs.chmodSync(BP, 0o755);
127
- console.log(`[jsql-neo] binary ready: ${BP}`);
128
- return;
129
- }
130
-
131
- // Build from source
132
- const serverDir = path.join(ROOT, '..', 'jsql-neo-server');
133
- if (fs.existsSync(path.join(serverDir, 'Cargo.toml'))) {
134
- console.log('[jsql-neo] building Rust server from source...');
135
- try {
136
- execSync('cargo build --release', { cwd: serverDir, stdio: 'inherit' });
137
- const src = path.join(serverDir, 'target', 'release', BIN_NAME);
138
- if (fs.existsSync(src)) {
139
- fs.mkdirSync(path.join(ROOT, 'bin'), { recursive: true });
140
- fs.copyFileSync(src, BP);
141
- fs.chmodSync(BP, 0o755);
142
- console.log(`[jsql-neo] binary built: ${BP}`);
143
- return;
144
- }
145
- } catch (e) {
146
- console.warn('[jsql-neo] cargo build failed:', e.message);
147
- }
148
- }
149
-
150
- console.warn(`[jsql-neo] server binary not found at ${BP}`);
151
- console.warn('[jsql-neo] install Rust from https://rustup.rs and run: npm run build');
152
- }
153
-
154
- async function main() {
155
- await ensureNativeNode();
156
- ensureServerBinary();
157
- }
158
-
1
+ const { execSync } = require('child_process');
2
+ const fs = require('fs');
3
+ const path = require('path');
4
+ const http = require('http');
5
+ const https = require('https');
6
+
7
+ const ROOT = __dirname;
8
+ const pkg = JSON.parse(fs.readFileSync(path.join(ROOT, 'package.json'), 'utf8'));
9
+
10
+ // Server CLI binary (bin/jsql-neo-server)
11
+ const BIN_NAME = process.platform === 'win32' ? 'jsql-neo-server.exe' : 'jsql-neo-server';
12
+ const BP = path.join(ROOT, 'bin', BIN_NAME);
13
+
14
+ // Native N-API module (native/jsql-neo-native.node)
15
+ const NATIVE_PATH = path.join(ROOT, 'native', 'jsql-neo-native.node');
16
+
17
+ // GitHub 加速代理前缀;把原始 github 链接直接拼在后面即可
18
+ const GHPROXY = 'https://gh-proxy.com/';
19
+ const TAG = `v${pkg.version}`;
20
+
21
+ // 从 repository 字段提取 owner/repo,例如 vexify-org/JSQL-neo
22
+ const REPO = (pkg.repository && pkg.repository.url)
23
+ ? pkg.repository.url.replace(/\.git$/, '').replace(/^.*github\.com\//i, '')
24
+ : 'vexify-org/JSQL-neo';
25
+
26
+ // 与 .github/workflows/build-native.yml 中发布的资产命名保持一致
27
+ function nativeTargetSuffix(platform = process.platform, arch = process.arch) {
28
+ const p = platform === 'win32' ? 'win32' : platform === 'darwin' ? 'darwin' : 'linux';
29
+ const a = arch === 'x64' ? 'x64' : arch === 'arm64' ? 'arm64' : arch;
30
+ if (p === 'linux') return `${p}-${a}-gnu`;
31
+ if (p === 'darwin') return `${p}-${a}`;
32
+ return `${p}-${a}-msvc`;
33
+ }
34
+
35
+ function download(url, dest) {
36
+ return new Promise((resolve, reject) => {
37
+ const mod = url.startsWith('https:') ? https : http;
38
+ const req = mod.get(url, (res) => {
39
+ if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
40
+ res.resume();
41
+ download(res.headers.location, dest).then(resolve, reject);
42
+ return;
43
+ }
44
+ if (res.statusCode !== 200) {
45
+ res.resume();
46
+ reject(new Error(`HTTP ${res.statusCode} for ${url}`));
47
+ return;
48
+ }
49
+ fs.mkdirSync(path.dirname(dest), { recursive: true });
50
+ const ws = fs.createWriteStream(dest);
51
+ ws.on('error', reject);
52
+ res.pipe(ws);
53
+ res.on('end', () => ws.end(() => resolve()));
54
+ });
55
+ req.on('error', reject);
56
+ });
57
+ }
58
+
59
+ function buildNativeFromSource() {
60
+ const crate = path.join(ROOT, 'nativesrc', 'jsql-neo-native');
61
+ if (!fs.existsSync(path.join(crate, 'Cargo.toml'))) return;
62
+ console.log('[jsql-neo] building native module from source...');
63
+ try {
64
+ execSync('cargo build --release', { cwd: crate, stdio: 'inherit' });
65
+ const rel = path.join(crate, 'target', 'release');
66
+ const src = process.platform === 'win32'
67
+ ? path.join(rel, 'jsql_neo_native.dll')
68
+ : process.platform === 'darwin'
69
+ ? path.join(rel, 'libjsql_neo_native.dylib')
70
+ : path.join(rel, 'libjsql_neo_native.so');
71
+ if (fs.existsSync(src)) {
72
+ fs.mkdirSync(path.dirname(NATIVE_PATH), { recursive: true });
73
+ fs.copyFileSync(src, NATIVE_PATH);
74
+ fs.chmodSync(NATIVE_PATH, 0o755);
75
+ console.log(`[jsql-neo] native module built: native/jsql-neo-native.node`);
76
+ }
77
+ } catch (e) {
78
+ console.warn('[jsql-neo] native build failed:', e.message);
79
+ }
80
+ }
81
+
82
+ // 尝试加载 native 模块;能成功 require 才算「可用」,否则视为不可用
83
+ function tryLoadNative() {
84
+ if (!fs.existsSync(NATIVE_PATH)) return false;
85
+ try {
86
+ require(NATIVE_PATH);
87
+ fs.chmodSync(NATIVE_PATH, 0o755);
88
+ return true;
89
+ } catch (e) {
90
+ console.warn(`[jsql-neo] existing native module cannot be loaded (${e.code || e.message}), will re-acquire.`);
91
+ try { fs.unlinkSync(NATIVE_PATH); } catch (_) { /* ignore */ }
92
+ return false;
93
+ }
94
+ }
95
+
96
+ async function downloadAndVerify() {
97
+ const asset = `jsql-neo-native.${nativeTargetSuffix()}.node`;
98
+ const url = `${GHPROXY}https://github.com/${REPO}/releases/download/${TAG}/${asset}`;
99
+ console.log(`[jsql-neo] downloading native module: ${url}`);
100
+ try {
101
+ await download(url, NATIVE_PATH);
102
+ if (!tryLoadNative()) {
103
+ console.warn('[jsql-neo] downloaded module also invalid, removed.');
104
+ return false;
105
+ }
106
+ console.log('[jsql-neo] native module downloaded: native/jsql-neo-native.node');
107
+ return true;
108
+ } catch (e) {
109
+ console.warn('[jsql-neo] download failed, falling back to source build:', e.message);
110
+ return false;
111
+ }
112
+ }
113
+
114
+ async function ensureNativeNode() {
115
+ // 已存在且能加载 → 直接用;否则删掉并从 gh-proxy.com 下载,找不到才回退源码编译
116
+ if (tryLoadNative()) {
117
+ console.log('[jsql-neo] native module ready: native/jsql-neo-native.node');
118
+ return;
119
+ }
120
+ if (await downloadAndVerify()) return;
121
+ buildNativeFromSource();
122
+ }
123
+
124
+ function ensureServerBinary() {
125
+ if (fs.existsSync(BP)) {
126
+ fs.chmodSync(BP, 0o755);
127
+ console.log(`[jsql-neo] binary ready: ${BP}`);
128
+ return;
129
+ }
130
+
131
+ // Build from source
132
+ const serverDir = path.join(ROOT, '..', 'jsql-neo-server');
133
+ if (fs.existsSync(path.join(serverDir, 'Cargo.toml'))) {
134
+ console.log('[jsql-neo] building Rust server from source...');
135
+ try {
136
+ execSync('cargo build --release', { cwd: serverDir, stdio: 'inherit' });
137
+ const src = path.join(serverDir, 'target', 'release', BIN_NAME);
138
+ if (fs.existsSync(src)) {
139
+ fs.mkdirSync(path.join(ROOT, 'bin'), { recursive: true });
140
+ fs.copyFileSync(src, BP);
141
+ fs.chmodSync(BP, 0o755);
142
+ console.log(`[jsql-neo] binary built: ${BP}`);
143
+ return;
144
+ }
145
+ } catch (e) {
146
+ console.warn('[jsql-neo] cargo build failed:', e.message);
147
+ }
148
+ }
149
+
150
+ console.warn(`[jsql-neo] server binary not found at ${BP}`);
151
+ console.warn('[jsql-neo] install Rust from https://rustup.rs and run: npm run build');
152
+ }
153
+
154
+ async function main() {
155
+ await ensureNativeNode();
156
+ ensureServerBinary();
157
+ }
158
+
159
159
  main();