native-recorder-nodejs 1.0.8 → 1.1.2

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 (41) hide show
  1. package/README.md +14 -0
  2. package/dist/bindings.js +129 -4
  3. package/package.json +6 -2
  4. package/prebuilds/darwin-arm64/electron-v29/NativeAudioSDK.node +0 -0
  5. package/prebuilds/darwin-arm64/electron-v30/NativeAudioSDK.node +0 -0
  6. package/prebuilds/darwin-arm64/electron-v31/NativeAudioSDK.node +0 -0
  7. package/prebuilds/darwin-arm64/electron-v32/NativeAudioSDK.node +0 -0
  8. package/prebuilds/darwin-arm64/electron-v33/NativeAudioSDK.node +0 -0
  9. package/prebuilds/darwin-arm64/electron-v34/NativeAudioSDK.node +0 -0
  10. package/prebuilds/darwin-arm64/electron-v35/NativeAudioSDK.node +0 -0
  11. package/prebuilds/darwin-arm64/electron-v36/NativeAudioSDK.node +0 -0
  12. package/prebuilds/darwin-arm64/electron-v37/NativeAudioSDK.node +0 -0
  13. package/prebuilds/darwin-arm64/electron-v38/NativeAudioSDK.node +0 -0
  14. package/prebuilds/darwin-arm64/electron-v39/NativeAudioSDK.node +0 -0
  15. package/prebuilds/darwin-arm64/electron-v40/NativeAudioSDK.node +0 -0
  16. package/prebuilds/darwin-x64/electron-v29/NativeAudioSDK.node +0 -0
  17. package/prebuilds/darwin-x64/electron-v30/NativeAudioSDK.node +0 -0
  18. package/prebuilds/darwin-x64/electron-v31/NativeAudioSDK.node +0 -0
  19. package/prebuilds/darwin-x64/electron-v32/NativeAudioSDK.node +0 -0
  20. package/prebuilds/darwin-x64/electron-v33/NativeAudioSDK.node +0 -0
  21. package/prebuilds/darwin-x64/electron-v34/NativeAudioSDK.node +0 -0
  22. package/prebuilds/darwin-x64/electron-v35/NativeAudioSDK.node +0 -0
  23. package/prebuilds/darwin-x64/electron-v36/NativeAudioSDK.node +0 -0
  24. package/prebuilds/darwin-x64/electron-v37/NativeAudioSDK.node +0 -0
  25. package/prebuilds/darwin-x64/electron-v38/NativeAudioSDK.node +0 -0
  26. package/prebuilds/darwin-x64/electron-v39/NativeAudioSDK.node +0 -0
  27. package/prebuilds/darwin-x64/electron-v40/NativeAudioSDK.node +0 -0
  28. package/prebuilds/win32-x64/NativeAudioSDK.node +0 -0
  29. package/prebuilds/win32-x64/electron-v29/NativeAudioSDK.node +0 -0
  30. package/prebuilds/win32-x64/electron-v30/NativeAudioSDK.node +0 -0
  31. package/prebuilds/win32-x64/electron-v31/NativeAudioSDK.node +0 -0
  32. package/prebuilds/win32-x64/electron-v32/NativeAudioSDK.node +0 -0
  33. package/prebuilds/win32-x64/electron-v33/NativeAudioSDK.node +0 -0
  34. package/prebuilds/win32-x64/electron-v34/NativeAudioSDK.node +0 -0
  35. package/prebuilds/win32-x64/electron-v35/NativeAudioSDK.node +0 -0
  36. package/prebuilds/win32-x64/electron-v36/NativeAudioSDK.node +0 -0
  37. package/prebuilds/win32-x64/electron-v37/NativeAudioSDK.node +0 -0
  38. package/prebuilds/win32-x64/electron-v38/NativeAudioSDK.node +0 -0
  39. package/prebuilds/win32-x64/electron-v39/NativeAudioSDK.node +0 -0
  40. package/prebuilds/win32-x64/electron-v40/NativeAudioSDK.node +0 -0
  41. package/src/bindings.ts +161 -5
package/README.md CHANGED
@@ -41,6 +41,20 @@ npm install native-recorder-nodejs
41
41
 
42
42
  Prebuilt binaries are available for most platforms. If a prebuild is not available, the package will compile from source (requires CMake and a C++ compiler).
43
43
 
44
+ ### Electron Support
45
+
46
+ This package includes prebuilt binaries for Electron 29-40. In most cases, it will work out of the box. If you encounter issues:
47
+
48
+ ```bash
49
+ # Option 1: Use electron-rebuild (recommended)
50
+ npx electron-rebuild
51
+
52
+ # Option 2: Rebuild using cmake-js with Electron runtime
53
+ npx cmake-js compile --runtime=electron --runtime-version=YOUR_ELECTRON_VERSION --arch=x64
54
+ ```
55
+
56
+ **Note**: Make sure to rebuild native modules after updating Electron version.
57
+
44
58
  ## Quick Start
45
59
 
46
60
  ```typescript
package/dist/bindings.js CHANGED
@@ -2,30 +2,155 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const path_1 = require("path");
4
4
  const fs_1 = require("fs");
5
+ /**
6
+ * Detect if running in Electron environment
7
+ */
8
+ function isElectron() {
9
+ // Check for Electron-specific process properties
10
+ if (typeof process !== "undefined") {
11
+ // @ts-ignore
12
+ if (process.versions && process.versions.electron) {
13
+ return true;
14
+ }
15
+ // Check for Electron renderer process
16
+ if (typeof globalThis !== "undefined" &&
17
+ // @ts-ignore
18
+ globalThis.window &&
19
+ // @ts-ignore
20
+ globalThis.window.process &&
21
+ // @ts-ignore
22
+ globalThis.window.process.type === "renderer") {
23
+ return true;
24
+ }
25
+ }
26
+ return false;
27
+ }
28
+ /**
29
+ * Get Electron major version number
30
+ */
31
+ function getElectronMajorVersion() {
32
+ try {
33
+ // @ts-ignore
34
+ const electronVersion = process.versions.electron;
35
+ if (!electronVersion)
36
+ return null;
37
+ return parseInt(electronVersion.split(".")[0], 10);
38
+ }
39
+ catch {
40
+ return null;
41
+ }
42
+ }
43
+ /**
44
+ * Find available Electron prebuild versions in the prebuilds directory
45
+ */
46
+ function findAvailableElectronVersions(platformDir) {
47
+ try {
48
+ if (!(0, fs_1.existsSync)(platformDir))
49
+ return [];
50
+ const dirs = (0, fs_1.readdirSync)(platformDir, { withFileTypes: true });
51
+ const versions = [];
52
+ for (const dir of dirs) {
53
+ if (dir.isDirectory() && dir.name.startsWith("electron-v")) {
54
+ const version = parseInt(dir.name.replace("electron-v", ""), 10);
55
+ if (!isNaN(version)) {
56
+ versions.push(version);
57
+ }
58
+ }
59
+ }
60
+ return versions.sort((a, b) => b - a); // Sort descending (newest first)
61
+ }
62
+ catch {
63
+ return [];
64
+ }
65
+ }
66
+ /**
67
+ * Find the closest available Electron prebuild version
68
+ * Prefers newer versions that are closest to the target
69
+ */
70
+ function findClosestElectronVersion(targetVersion, availableVersions) {
71
+ if (availableVersions.length === 0)
72
+ return null;
73
+ // First, try to find an exact match
74
+ if (availableVersions.includes(targetVersion)) {
75
+ return targetVersion;
76
+ }
77
+ // Find the closest version (prefer slightly older over much newer for stability)
78
+ let closest = null;
79
+ let minDiff = Infinity;
80
+ for (const version of availableVersions) {
81
+ const diff = Math.abs(version - targetVersion);
82
+ // Prefer older versions when diff is the same (more stable)
83
+ if (diff < minDiff || (diff === minDiff && version < targetVersion)) {
84
+ minDiff = diff;
85
+ closest = version;
86
+ }
87
+ }
88
+ return closest;
89
+ }
5
90
  function getBinding() {
6
91
  const moduleName = "NativeAudioSDK.node";
7
92
  // Try prebuild first (installed via npm)
8
93
  const prebuildsDir = (0, path_1.join)(__dirname, "..", "prebuilds");
9
94
  const platform = process.platform;
10
95
  const arch = process.arch;
96
+ const platformDir = (0, path_1.join)(prebuildsDir, `${platform}-${arch}`);
97
+ const paths = [];
98
+ // For Electron, try Electron-specific prebuild first
99
+ if (isElectron()) {
100
+ const electronMajor = getElectronMajorVersion();
101
+ if (electronMajor) {
102
+ // Try exact version match first
103
+ const exactPath = (0, path_1.join)(platformDir, `electron-v${electronMajor}`, moduleName);
104
+ paths.push(exactPath);
105
+ if ((0, fs_1.existsSync)(exactPath)) {
106
+ return require(exactPath);
107
+ }
108
+ // Fallback: find closest available Electron version
109
+ const availableVersions = findAvailableElectronVersions(platformDir);
110
+ const closestVersion = findClosestElectronVersion(electronMajor, availableVersions);
111
+ if (closestVersion && closestVersion !== electronMajor) {
112
+ const fallbackPath = (0, path_1.join)(platformDir, `electron-v${closestVersion}`, moduleName);
113
+ paths.push(fallbackPath);
114
+ if ((0, fs_1.existsSync)(fallbackPath)) {
115
+ console.warn(`[native-recorder-nodejs] No prebuild for Electron ${electronMajor}, ` +
116
+ `using Electron ${closestVersion} prebuild as fallback. ` +
117
+ `Consider running 'npx electron-rebuild' for best compatibility.`);
118
+ return require(fallbackPath);
119
+ }
120
+ }
121
+ }
122
+ }
123
+ // Try N-API prebuild (works for both Node.js and Electron with N-API support)
124
+ // Since this module uses N-API, the Node.js prebuild should work in Electron too
11
125
  // prebuild-install stores binaries in: prebuilds/{platform}-{arch}/
12
- const prebuildPath = (0, path_1.join)(prebuildsDir, `${platform}-${arch}`, moduleName);
126
+ const prebuildPath = (0, path_1.join)(platformDir, moduleName);
127
+ paths.push(prebuildPath);
13
128
  if ((0, fs_1.existsSync)(prebuildPath)) {
14
129
  return require(prebuildPath);
15
130
  }
131
+ // Also try napi-v8 subfolder format
132
+ const napiPrebuildPath = (0, path_1.join)(platformDir, "napi-v8", moduleName);
133
+ paths.push(napiPrebuildPath);
134
+ if ((0, fs_1.existsSync)(napiPrebuildPath)) {
135
+ return require(napiPrebuildPath);
136
+ }
16
137
  // Fallback to local build (development)
17
138
  const localPath = (0, path_1.join)(__dirname, "..", "build", "Release", moduleName);
139
+ paths.push(localPath);
18
140
  if ((0, fs_1.existsSync)(localPath)) {
19
141
  return require(localPath);
20
142
  }
21
143
  // Final fallback for different build configurations
22
144
  const debugPath = (0, path_1.join)(__dirname, "..", "build", "Debug", moduleName);
145
+ paths.push(debugPath);
23
146
  if ((0, fs_1.existsSync)(debugPath)) {
24
147
  return require(debugPath);
25
148
  }
26
- throw new Error(`Could not find native module ${moduleName}. ` +
27
- `Tried:\n - ${prebuildPath}\n - ${localPath}\n - ${debugPath}\n` +
28
- `Please run 'npm run build:native' or reinstall the package.`);
149
+ const runtime = isElectron() ? "Electron" : "Node.js";
150
+ throw new Error(`Could not find native module ${moduleName} for ${runtime}. ` +
151
+ `Tried:\n - ${paths.join("\n - ")}\n` +
152
+ `Please run 'npm run build:native' or reinstall the package.\n` +
153
+ `For Electron users: try running 'npx electron-rebuild' in your project.`);
29
154
  }
30
155
  const bindings = getBinding();
31
156
  exports.default = bindings;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "native-recorder-nodejs",
3
- "version": "1.0.8",
3
+ "version": "1.1.2",
4
4
  "description": "Cross-platform (Win/Mac) Native Audio SDK for Node.js",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -11,11 +11,14 @@
11
11
  "build:native:debug": "cmake-js compile --debug",
12
12
  "build:tests": "cmake -S . -B build -DBUILD_TESTS=ON && cmake --build build --config Release --target NativeTests",
13
13
  "prebuild": "prebuild --backend cmake-js -r napi --strip",
14
+ "prebuild:electron": "prebuild --backend cmake-js -r electron -t 29.0.0 -t 30.0.0 -t 31.0.0 -t 32.0.0 -t 33.0.0 -t 34.0.0 -t 35.0.0 -t 36.0.0 -t 37.0.0 -t 38.0.0 -t 39.0.0 -t 40.0.0 --strip",
15
+ "prebuild:all": "npm run prebuild && npm run prebuild:electron",
14
16
  "prebuild:upload": "prebuild --upload-all ${GITHUB_TOKEN}",
15
17
  "test": "jest",
16
18
  "test:native": "npm run build:tests && cd build && ctest -C Release --output-on-failure",
17
19
  "test:cli": "node ./test/cli_test.js",
18
20
  "clean": "rimraf dist build prebuilds",
21
+ "install": "prebuild-install || npm run build:native",
19
22
  "prepublishOnly": "npm run build:ts",
20
23
  "release": "npm version patch && git push && git push --tags",
21
24
  "release:minor": "npm version minor && git push && git push --tags",
@@ -57,7 +60,8 @@
57
60
  ]
58
61
  },
59
62
  "dependencies": {
60
- "node-addon-api": "^7.0.0"
63
+ "node-addon-api": "^7.0.0",
64
+ "prebuild-install": "^7.1.2"
61
65
  },
62
66
  "devDependencies": {
63
67
  "@types/jest": "^29.5.0",
package/src/bindings.ts CHANGED
@@ -1,5 +1,102 @@
1
1
  import { join, dirname } from "path";
2
- import { existsSync } from "fs";
2
+ import { existsSync, readdirSync } from "fs";
3
+
4
+ /**
5
+ * Detect if running in Electron environment
6
+ */
7
+ function isElectron(): boolean {
8
+ // Check for Electron-specific process properties
9
+ if (typeof process !== "undefined") {
10
+ // @ts-ignore
11
+ if (process.versions && process.versions.electron) {
12
+ return true;
13
+ }
14
+ // Check for Electron renderer process
15
+ if (
16
+ typeof globalThis !== "undefined" &&
17
+ // @ts-ignore
18
+ globalThis.window &&
19
+ // @ts-ignore
20
+ globalThis.window.process &&
21
+ // @ts-ignore
22
+ globalThis.window.process.type === "renderer"
23
+ ) {
24
+ return true;
25
+ }
26
+ }
27
+ return false;
28
+ }
29
+
30
+ /**
31
+ * Get Electron major version number
32
+ */
33
+ function getElectronMajorVersion(): number | null {
34
+ try {
35
+ // @ts-ignore
36
+ const electronVersion = process.versions.electron;
37
+ if (!electronVersion) return null;
38
+
39
+ return parseInt(electronVersion.split(".")[0], 10);
40
+ } catch {
41
+ return null;
42
+ }
43
+ }
44
+
45
+ /**
46
+ * Find available Electron prebuild versions in the prebuilds directory
47
+ */
48
+ function findAvailableElectronVersions(platformDir: string): number[] {
49
+ try {
50
+ if (!existsSync(platformDir)) return [];
51
+
52
+ const dirs = readdirSync(platformDir, { withFileTypes: true });
53
+ const versions: number[] = [];
54
+
55
+ for (const dir of dirs) {
56
+ if (dir.isDirectory() && dir.name.startsWith("electron-v")) {
57
+ const version = parseInt(dir.name.replace("electron-v", ""), 10);
58
+ if (!isNaN(version)) {
59
+ versions.push(version);
60
+ }
61
+ }
62
+ }
63
+
64
+ return versions.sort((a, b) => b - a); // Sort descending (newest first)
65
+ } catch {
66
+ return [];
67
+ }
68
+ }
69
+
70
+ /**
71
+ * Find the closest available Electron prebuild version
72
+ * Prefers newer versions that are closest to the target
73
+ */
74
+ function findClosestElectronVersion(
75
+ targetVersion: number,
76
+ availableVersions: number[],
77
+ ): number | null {
78
+ if (availableVersions.length === 0) return null;
79
+
80
+ // First, try to find an exact match
81
+ if (availableVersions.includes(targetVersion)) {
82
+ return targetVersion;
83
+ }
84
+
85
+ // Find the closest version (prefer slightly older over much newer for stability)
86
+ let closest: number | null = null;
87
+ let minDiff = Infinity;
88
+
89
+ for (const version of availableVersions) {
90
+ const diff = Math.abs(version - targetVersion);
91
+ // Prefer older versions when diff is the same (more stable)
92
+ if (diff < minDiff || (diff === minDiff && version < targetVersion)) {
93
+ minDiff = diff;
94
+ closest = version;
95
+ }
96
+ }
97
+
98
+ return closest;
99
+ }
3
100
 
4
101
  function getBinding() {
5
102
  const moduleName = "NativeAudioSDK.node";
@@ -8,30 +105,89 @@ function getBinding() {
8
105
  const prebuildsDir = join(__dirname, "..", "prebuilds");
9
106
  const platform = process.platform;
10
107
  const arch = process.arch;
108
+ const platformDir = join(prebuildsDir, `${platform}-${arch}`);
109
+
110
+ const paths: string[] = [];
11
111
 
112
+ // For Electron, try Electron-specific prebuild first
113
+ if (isElectron()) {
114
+ const electronMajor = getElectronMajorVersion();
115
+ if (electronMajor) {
116
+ // Try exact version match first
117
+ const exactPath = join(
118
+ platformDir,
119
+ `electron-v${electronMajor}`,
120
+ moduleName,
121
+ );
122
+ paths.push(exactPath);
123
+ if (existsSync(exactPath)) {
124
+ return require(exactPath);
125
+ }
126
+
127
+ // Fallback: find closest available Electron version
128
+ const availableVersions = findAvailableElectronVersions(platformDir);
129
+ const closestVersion = findClosestElectronVersion(
130
+ electronMajor,
131
+ availableVersions,
132
+ );
133
+
134
+ if (closestVersion && closestVersion !== electronMajor) {
135
+ const fallbackPath = join(
136
+ platformDir,
137
+ `electron-v${closestVersion}`,
138
+ moduleName,
139
+ );
140
+ paths.push(fallbackPath);
141
+ if (existsSync(fallbackPath)) {
142
+ console.warn(
143
+ `[native-recorder-nodejs] No prebuild for Electron ${electronMajor}, ` +
144
+ `using Electron ${closestVersion} prebuild as fallback. ` +
145
+ `Consider running 'npx electron-rebuild' for best compatibility.`,
146
+ );
147
+ return require(fallbackPath);
148
+ }
149
+ }
150
+ }
151
+ }
152
+
153
+ // Try N-API prebuild (works for both Node.js and Electron with N-API support)
154
+ // Since this module uses N-API, the Node.js prebuild should work in Electron too
12
155
  // prebuild-install stores binaries in: prebuilds/{platform}-{arch}/
13
- const prebuildPath = join(prebuildsDir, `${platform}-${arch}`, moduleName);
156
+ const prebuildPath = join(platformDir, moduleName);
157
+ paths.push(prebuildPath);
14
158
 
15
159
  if (existsSync(prebuildPath)) {
16
160
  return require(prebuildPath);
17
161
  }
18
162
 
163
+ // Also try napi-v8 subfolder format
164
+ const napiPrebuildPath = join(platformDir, "napi-v8", moduleName);
165
+ paths.push(napiPrebuildPath);
166
+
167
+ if (existsSync(napiPrebuildPath)) {
168
+ return require(napiPrebuildPath);
169
+ }
170
+
19
171
  // Fallback to local build (development)
20
172
  const localPath = join(__dirname, "..", "build", "Release", moduleName);
173
+ paths.push(localPath);
21
174
  if (existsSync(localPath)) {
22
175
  return require(localPath);
23
176
  }
24
177
 
25
178
  // Final fallback for different build configurations
26
179
  const debugPath = join(__dirname, "..", "build", "Debug", moduleName);
180
+ paths.push(debugPath);
27
181
  if (existsSync(debugPath)) {
28
182
  return require(debugPath);
29
183
  }
30
184
 
185
+ const runtime = isElectron() ? "Electron" : "Node.js";
31
186
  throw new Error(
32
- `Could not find native module ${moduleName}. ` +
33
- `Tried:\n - ${prebuildPath}\n - ${localPath}\n - ${debugPath}\n` +
34
- `Please run 'npm run build:native' or reinstall the package.`
187
+ `Could not find native module ${moduleName} for ${runtime}. ` +
188
+ `Tried:\n - ${paths.join("\n - ")}\n` +
189
+ `Please run 'npm run build:native' or reinstall the package.\n` +
190
+ `For Electron users: try running 'npx electron-rebuild' in your project.`,
35
191
  );
36
192
  }
37
193