Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 7 additions & 23 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,13 @@ jobs:
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: lts/*
node-version: 22
cache: "pnpm"

- name: Setup pnpm
uses: pnpm/action-setup@v2
uses: pnpm/action-setup@v4
with:
version: 8
version: 10

- name: Install Rust stable
uses: dtolnay/rust-toolchain@stable
Expand All @@ -50,27 +51,10 @@ jobs:
targets: ${{ matrix.platform == 'macos-latest' && 'aarch64-apple-darwin,x86_64-apple-darwin' || '' }}

- name: Install frontend dependencies
run: pnpm install
run: pnpm install --frozen-lockfile

- name: Build bridge (Windows)
if: matrix.platform == 'windows-latest'
run: |
cd bridge
pnpm install --frozen-lockfile=false
npx esbuild src/index.ts --bundle --platform=node --outfile=dist/index.cjs --format=cjs --packages=external
cd ..
npm install -g pkg@5.8.1
pkg ./bridge/dist/index.cjs --target node18-win-x64 --output ./src-tauri/resources/bridge-x86_64-pc-windows-msvc.exe

- name: Build bridge (Linux)
if: matrix.platform == 'ubuntu-22.04'
run: |
cd bridge
pnpm install --frozen-lockfile=false
npx esbuild src/index.ts --bundle --platform=node --outfile=dist/index.cjs --format=cjs --packages=external
cd ..
npm install -g pkg@5.8.1
pkg ./bridge/dist/index.cjs --target node18-linux-x64 --output ./src-tauri/resources/bridge-x86_64-unknown-linux-gnu
- name: Install bridge dependencies
run: pnpm --dir bridge install --frozen-lockfile

- name: Build and release
uses: tauri-apps/tauri-action@v0
Expand Down
10 changes: 3 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,9 +124,7 @@ pnpm tauri dev
**Windows:**

```bash
cd bridge && pnpm build && cd ..
npx pkg ./bridge/dist/index.cjs --target node18-win-x64 \
--output ./src-tauri/resources/bridge-x86_64-pc-windows-msvc.exe
pnpm run package-bridge
pnpm tauri build
```

Expand All @@ -135,9 +133,7 @@ pnpm tauri build
```bash
sudo apt install libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf

cd bridge && pnpm build && cd ..
npx pkg ./bridge/dist/index.cjs --target node18-linux-x64 \
--output ./src-tauri/resources/bridge-x86_64-unknown-linux-gnu
pnpm --dir bridge run build:pkg:linux
pnpm tauri build
```

Expand Down Expand Up @@ -355,4 +351,4 @@ This project is licensed under the MIT License. See [LICENSE](LICENSE) for detai

[Star on GitHub](https://github.com/Relwave/relwave-app) · [Download](https://github.com/Relwave/relwave-app/releases) · [Report Issues](https://github.com/Relwave/relwave-app/issues) · [Request Features](https://github.com/Relwave/relwave-app/issues)

</div>
</div>
10 changes: 6 additions & 4 deletions bridge/package.json
Original file line number Diff line number Diff line change
@@ -1,22 +1,24 @@
{
"name": "db-visualizer-bridge",
"version": "0.4.0-beta.1",
"version": "v0.4.0-beta.2",
"type": "commonjs",
"main": "dist/index.cjs",
"scripts": {
"dev": "ts-node-dev --respawn --transpile-only src/index.ts",
"start": "node dist/index.cjs",
"build": "esbuild src/index.ts --bundle --platform=node --outfile=dist/index.cjs --format=cjs --packages=external",
"build:pkg": "pkg . --out-path exece",
"postpkg": "node scripts/copy-native.js",
"copy:native": "node scripts/copy-native.js",
"build:pkg": "node scripts/build-pkg.js",
"build:pkg:win": "pnpm run build && pnpm run copy:native && pnpm exec pkg . --target node18-win-x64 --output ../src-tauri/resources/bridge-x86_64-pc-windows-msvc.exe",
"build:pkg:linux": "pnpm run build && pnpm run copy:native && pnpm exec pkg . --target node18-linux-x64 --output ../src-tauri/resources/bridge-x86_64-unknown-linux-gnu",
"test": "jest",
"test:watch": "jest --watchAll --detectOpenHandles"
},
"dependencies": {
"@jest/globals": "^30.2.0",
"@napi-rs/keyring": "^1.2.0",
"bcryptjs": "^3.0.3",
"better-sqlite3": "^12.6.2",
"better-sqlite3": "^11.9.0",
"dotenv": "^17.2.3",
"mysql2": "^3.15.3",
"pg": "^8.16.3",
Expand Down
11 changes: 5 additions & 6 deletions bridge/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 2 additions & 4 deletions bridge/pnpm-workspace.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
packages: []

ignoredBuiltDependencies:
- better-sqlite3

onlyBuiltDependencies:
- keytar
- better-sqlite3
- "@napi-rs/keyring"
29 changes: 29 additions & 0 deletions bridge/scripts/build-pkg.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#!/usr/bin/env node

const { spawnSync } = require("child_process");

const targetScriptByPlatform = {
win32: "build:pkg:win",
linux: "build:pkg:linux",
};

const targetScript = targetScriptByPlatform[process.platform];

if (!targetScript) {
console.error(
`ERROR: Unsupported platform for bridge packaging: ${process.platform}`,
);
process.exit(1);
}

const pnpmCommand = process.platform === "win32" ? "pnpm.cmd" : "pnpm";
const result = spawnSync(pnpmCommand, ["run", targetScript], {
stdio: "inherit",
});

if (result.error) {
console.error(result.error.message);
process.exit(1);
}

process.exit(result.status ?? 1);
167 changes: 167 additions & 0 deletions bridge/scripts/copy-native.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
#!/usr/bin/env node
/**
* Packaging helper: copy a better-sqlite3 native addon that matches the
* packaged bridge runtime, not necessarily the host Node.js runtime.
*
* pkg 5.8.x embeds a Node 18.5.0 runtime for this project, so a host-built
* Node 22 addon will load in development but fail inside the packaged bridge
* with a NODE_MODULE_VERSION mismatch.
*/

const { execFileSync } = require("child_process");
const fs = require("fs");
const os = require("os");
const path = require("path");

const PKG_RUNTIME = {
nodeVersion: "18.5.0",
nodeModules: "108",
platform: process.platform,
arch: process.arch,
};

function findFirstExisting(candidates) {
return candidates.find((candidate) => fs.existsSync(candidate));
}

function findFirstNodeBinary(rootDir) {
const queue = [rootDir];

while (queue.length > 0) {
const currentDir = queue.shift();
const entries = fs.readdirSync(currentDir, { withFileTypes: true });

for (const entry of entries) {
const fullPath = path.join(currentDir, entry.name);
if (entry.isDirectory()) {
queue.push(fullPath);
continue;
}
if (entry.isFile() && fullPath.endsWith(".node")) {
return fullPath;
}
}
}

return undefined;
}

function downloadPkgRuntimeBinary(betterSqlite3Dir) {
const packageJsonPath = path.join(betterSqlite3Dir, "package.json");
const tempDir = fs.mkdtempSync(
path.join(os.tmpdir(), "relwave-better-sqlite3-"),
);
const prebuildInstallBin = require.resolve("prebuild-install/bin.js", {
paths: [betterSqlite3Dir],
});

fs.copyFileSync(packageJsonPath, path.join(tempDir, "package.json"));

try {
execFileSync(
process.execPath,
[
prebuildInstallBin,
"--target",
PKG_RUNTIME.nodeVersion,
"--runtime",
"node",
"--platform",
PKG_RUNTIME.platform,
"--arch",
PKG_RUNTIME.arch,
"--path",
tempDir,
],
{
cwd: betterSqlite3Dir,
stdio: "inherit",
},
);
} catch (error) {
console.error(
"ERROR: Failed to fetch a better-sqlite3 binary for the packaged bridge runtime.",
);
console.error(
` Packaged bridge runtime: Node ${PKG_RUNTIME.nodeVersion} (NODE_MODULE_VERSION ${PKG_RUNTIME.nodeModules})`,
);
console.error(
` Current build runtime: ${process.version} (NODE_MODULE_VERSION ${process.versions.modules})`,
);
console.error(
" Re-run the build with internet access, or rebuild better-sqlite3 for Node 18 before packaging.",
);
process.exit(error.status || 1);
}

const downloadedBinary = findFirstNodeBinary(tempDir);
if (!downloadedBinary) {
console.error(
"ERROR: prebuild-install completed, but no better_sqlite3.node was extracted.",
);
process.exit(1);
}

return downloadedBinary;
}

function resolveNativeBinarySource(betterSqlite3Dir) {
const runtimeSpecificCandidates = [
path.join(
betterSqlite3Dir,
"lib",
"binding",
`node-v${PKG_RUNTIME.nodeModules}-${PKG_RUNTIME.platform}-${PKG_RUNTIME.arch}`,
"better_sqlite3.node",
),
path.join(
betterSqlite3Dir,
"compiled",
PKG_RUNTIME.nodeVersion,
PKG_RUNTIME.platform,
PKG_RUNTIME.arch,
"better_sqlite3.node",
),
];

const runtimeSpecificBinary = findFirstExisting(runtimeSpecificCandidates);
if (runtimeSpecificBinary) {
return runtimeSpecificBinary;
}

if (process.versions.modules === PKG_RUNTIME.nodeModules) {
const localBuildBinary = findFirstExisting([
path.join(betterSqlite3Dir, "build", "Release", "better_sqlite3.node"),
path.join(betterSqlite3Dir, "build", "Debug", "better_sqlite3.node"),
]);

if (localBuildBinary) {
return localBuildBinary;
}
}

return downloadPkgRuntimeBinary(betterSqlite3Dir);
}

const betterSqlite3Pkg = require.resolve("better-sqlite3/package.json");
const betterSqlite3Dir = path.dirname(betterSqlite3Pkg);
const src = resolveNativeBinarySource(betterSqlite3Dir);

if (!src || !fs.existsSync(src)) {
console.error("ERROR: Could not resolve better_sqlite3.node for packaging.");
process.exit(1);
}

const repoRoot = path.resolve(__dirname, "..", "..");
const dest = path.join(
repoRoot,
"src-tauri",
"resources",
"better_sqlite3.node",
);

fs.mkdirSync(path.dirname(dest), { recursive: true });
fs.copyFileSync(src, dest);
console.log("Copied better_sqlite3.node");
console.log(" from:", src);
console.log(" to: ", dest);
Loading
Loading