From d0150235c2c09dc976890a60f59864af0a71021c Mon Sep 17 00:00:00 2001 From: Roger Qiu Date: Sun, 25 Jun 2023 20:26:10 +1000 Subject: [PATCH] WIP --- package.json | 2 - src/native/rocksdb.ts | 99 +++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 96 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index ace0d391..e4146c66 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,6 @@ "gypfile": true, "scripts": { "prepare": "tsc -p ./tsconfig.build.json", - "install": "node-gyp-build", "prebuild": "node ./scripts/prebuild.js", "build": "shx rm -rf ./dist && tsc -p ./tsconfig.build.json", "version": "node ./scripts/version.js", @@ -35,7 +34,6 @@ "@matrixai/logger": "^3.1.0", "@matrixai/resources": "^1.1.5", "@matrixai/workers": "^1.3.7", - "node-gyp-build": "4.4.0", "threads": "^1.6.5" }, "optionalDependencies": { diff --git a/src/native/rocksdb.ts b/src/native/rocksdb.ts index f97265c7..0d2ec1de 100644 --- a/src/native/rocksdb.ts +++ b/src/native/rocksdb.ts @@ -19,7 +19,6 @@ import type { RocksDBCountOptions, } from './types'; import path from 'path'; -import nodeGypBuild from 'node-gyp-build'; interface RocksDB { dbInit(): RocksDBDatabase; @@ -271,8 +270,102 @@ interface RocksDB { ): void; } -const rocksdb: RocksDB = nodeGypBuild(path.join(__dirname, '../../')); +const projectRoot = path.join(__dirname, '../../'); +const prebuildPath = path.join(projectRoot, 'prebuild'); -export default rocksdb; +/** + * Try require on all prebuild targets first, then + * try require on all npm targets second. + */ +function requireBinding(targets: Array): RocksDB { + const prebuildTargets = targets.map((target) => + path.join(prebuildPath, `db-${target}.node`), + ); + for (const prebuildTarget of prebuildTargets) { + try { + return require(prebuildTarget); + } catch (e) { + if (e.code !== 'MODULE_NOT_FOUND') throw e; + } + } + const npmTargets = targets.map((target) => `@matrixai/db-${target}`); + for (const npmTarget of npmTargets) { + try { + return require(npmTarget); + } catch (e) { + if (e.code !== 'MODULE_NOT_FOUND') throw e; + } + } + throw new Error( + `Failed requiring possible native bindings: ${prebuildTargets.concat( + npmTargets, + )}`, + ); +} + +let nativeBinding: RocksDB; + +/** + * For desktop we only support win32, darwin and linux. + * Mobile OS support is pending. + */ +switch (process.platform) { + case 'win32': + switch (process.arch) { + case 'x64': + nativeBinding = requireBinding(['win32-x64']); + break; + case 'ia32': + nativeBinding = requireBinding(['win32-ia32']); + break; + case 'arm64': + nativeBinding = requireBinding(['win32-arm64']); + break; + default: + throw new Error(`Unsupported architecture on Windows: ${process.arch}`); + } + break; + case 'darwin': + switch (process.arch) { + case 'x64': + nativeBinding = requireBinding([ + 'darwin-x64', + 'darwin-x64+arm64', + 'darwin-arm64+x64', + ]); + break; + case 'arm64': + nativeBinding = requireBinding([ + 'darwin-arm64', + 'darwin-arm64+x64', + 'darwin-x64+arm64', + ]); + break; + default: + throw new Error(`Unsupported architecture on macOS: ${process.arch}`); + } + break; + case 'linux': + switch (process.arch) { + case 'x64': + nativeBinding = requireBinding(['linux-x64']); + break; + case 'arm64': + nativeBinding = requireBinding(['linux-arm64']); + break; + case 'arm': + nativeBinding = requireBinding(['linux-arm']); + break; + default: + throw new Error(`Unsupported architecture on Linux: ${process.arch}`); + } + break; + default: + throw new Error( + `Unsupported OS: ${process.platform}, architecture: ${process.arch}`, + ); +} + +export default nativeBinding; export type { RocksDB };