librats 0.5.0 → 0.5.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.
- package/README.md +1 -1
- package/binding.gyp +1 -0
- package/lib/index.d.ts +2 -1
- package/native-src/3rdparty/android/ifaddrs-android.c +600 -0
- package/native-src/3rdparty/android/ifaddrs-android.h +54 -0
- package/native-src/CMakeLists.txt +360 -0
- package/native-src/LICENSE +21 -0
- package/native-src/src/bencode.cpp +485 -0
- package/native-src/src/bencode.h +145 -0
- package/native-src/src/bittorrent.cpp +3682 -0
- package/native-src/src/bittorrent.h +731 -0
- package/native-src/src/dht.cpp +2460 -0
- package/native-src/src/dht.h +508 -0
- package/native-src/src/encrypted_socket.cpp +817 -0
- package/native-src/src/encrypted_socket.h +239 -0
- package/native-src/src/file_transfer.cpp +1808 -0
- package/native-src/src/file_transfer.h +567 -0
- package/native-src/src/fs.cpp +639 -0
- package/native-src/src/fs.h +108 -0
- package/native-src/src/gossipsub.cpp +1137 -0
- package/native-src/src/gossipsub.h +403 -0
- package/native-src/src/ice.cpp +1386 -0
- package/native-src/src/ice.h +328 -0
- package/native-src/src/json.hpp +25526 -0
- package/native-src/src/krpc.cpp +558 -0
- package/native-src/src/krpc.h +145 -0
- package/native-src/src/librats.cpp +2735 -0
- package/native-src/src/librats.h +1732 -0
- package/native-src/src/librats_bittorrent.cpp +167 -0
- package/native-src/src/librats_c.cpp +1333 -0
- package/native-src/src/librats_c.h +239 -0
- package/native-src/src/librats_encryption.cpp +123 -0
- package/native-src/src/librats_file_transfer.cpp +226 -0
- package/native-src/src/librats_gossipsub.cpp +293 -0
- package/native-src/src/librats_ice.cpp +515 -0
- package/native-src/src/librats_logging.cpp +158 -0
- package/native-src/src/librats_mdns.cpp +171 -0
- package/native-src/src/librats_nat.cpp +571 -0
- package/native-src/src/librats_persistence.cpp +815 -0
- package/native-src/src/logger.h +412 -0
- package/native-src/src/mdns.cpp +1178 -0
- package/native-src/src/mdns.h +253 -0
- package/native-src/src/network_utils.cpp +598 -0
- package/native-src/src/network_utils.h +162 -0
- package/native-src/src/noise.cpp +981 -0
- package/native-src/src/noise.h +227 -0
- package/native-src/src/os.cpp +371 -0
- package/native-src/src/os.h +40 -0
- package/native-src/src/rats_export.h +17 -0
- package/native-src/src/sha1.cpp +163 -0
- package/native-src/src/sha1.h +42 -0
- package/native-src/src/socket.cpp +1376 -0
- package/native-src/src/socket.h +309 -0
- package/native-src/src/stun.cpp +484 -0
- package/native-src/src/stun.h +349 -0
- package/native-src/src/threadmanager.cpp +105 -0
- package/native-src/src/threadmanager.h +53 -0
- package/native-src/src/tracker.cpp +1110 -0
- package/native-src/src/tracker.h +268 -0
- package/native-src/src/version.cpp +24 -0
- package/native-src/src/version.h.in +45 -0
- package/native-src/version.rc.in +31 -0
- package/package.json +2 -8
- package/scripts/build-librats.js +59 -12
- package/scripts/prepare-package.js +133 -37
- package/src/librats_node.cpp +46 -1
|
@@ -7,36 +7,156 @@ const path = require('path');
|
|
|
7
7
|
* Prepare package script
|
|
8
8
|
*
|
|
9
9
|
* This script runs before packing and publishing to ensure the package
|
|
10
|
-
* is ready for distribution. It
|
|
10
|
+
* is ready for distribution. It copies the native C++ source files into
|
|
11
|
+
* the nodejs package directory so they can be included in the npm package.
|
|
11
12
|
*/
|
|
12
13
|
|
|
13
14
|
console.log('Preparing package for distribution...');
|
|
14
15
|
|
|
15
16
|
const projectRoot = path.resolve(__dirname, '..', '..');
|
|
16
17
|
const nodejsRoot = path.resolve(__dirname, '..');
|
|
18
|
+
const nativeSrcDir = path.join(nodejsRoot, 'native-src');
|
|
17
19
|
|
|
18
|
-
//
|
|
20
|
+
// Helper function to copy a file
|
|
21
|
+
function copyFile(src, dest) {
|
|
22
|
+
const destDir = path.dirname(dest);
|
|
23
|
+
if (!fs.existsSync(destDir)) {
|
|
24
|
+
fs.mkdirSync(destDir, { recursive: true });
|
|
25
|
+
}
|
|
26
|
+
fs.copyFileSync(src, dest);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// Helper function to copy a directory recursively
|
|
30
|
+
function copyDir(src, dest, filter = () => true) {
|
|
31
|
+
if (!fs.existsSync(dest)) {
|
|
32
|
+
fs.mkdirSync(dest, { recursive: true });
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const entries = fs.readdirSync(src, { withFileTypes: true });
|
|
36
|
+
for (const entry of entries) {
|
|
37
|
+
const srcPath = path.join(src, entry.name);
|
|
38
|
+
const destPath = path.join(dest, entry.name);
|
|
39
|
+
|
|
40
|
+
if (entry.isDirectory()) {
|
|
41
|
+
copyDir(srcPath, destPath, filter);
|
|
42
|
+
} else if (filter(entry.name)) {
|
|
43
|
+
copyFile(srcPath, destPath);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Check that we're in the project root with the source files
|
|
49
|
+
if (!fs.existsSync(path.join(projectRoot, 'CMakeLists.txt'))) {
|
|
50
|
+
console.error('\n❌ ERROR: Cannot find CMakeLists.txt in project root.');
|
|
51
|
+
console.error('This script must be run from within the librats repository.');
|
|
52
|
+
console.error(`Expected project root: ${projectRoot}`);
|
|
53
|
+
process.exit(1);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (!fs.existsSync(path.join(projectRoot, 'src'))) {
|
|
57
|
+
console.error('\n❌ ERROR: Cannot find src/ directory in project root.');
|
|
58
|
+
console.error('This script must be run from within the librats repository.');
|
|
59
|
+
process.exit(1);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Clean up existing native-src directory
|
|
63
|
+
if (fs.existsSync(nativeSrcDir)) {
|
|
64
|
+
console.log('Cleaning existing native-src directory...');
|
|
65
|
+
fs.rmSync(nativeSrcDir, { recursive: true, force: true });
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
console.log('\nCopying native source files to native-src/...');
|
|
69
|
+
|
|
70
|
+
// Create native-src directory
|
|
71
|
+
fs.mkdirSync(nativeSrcDir, { recursive: true });
|
|
72
|
+
|
|
73
|
+
// Copy CMakeLists.txt
|
|
74
|
+
console.log(' Copying CMakeLists.txt...');
|
|
75
|
+
copyFile(
|
|
76
|
+
path.join(projectRoot, 'CMakeLists.txt'),
|
|
77
|
+
path.join(nativeSrcDir, 'CMakeLists.txt')
|
|
78
|
+
);
|
|
79
|
+
|
|
80
|
+
// Copy LICENSE
|
|
81
|
+
if (fs.existsSync(path.join(projectRoot, 'LICENSE'))) {
|
|
82
|
+
console.log(' Copying LICENSE...');
|
|
83
|
+
copyFile(
|
|
84
|
+
path.join(projectRoot, 'LICENSE'),
|
|
85
|
+
path.join(nativeSrcDir, 'LICENSE')
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Copy version.rc.in
|
|
90
|
+
if (fs.existsSync(path.join(projectRoot, 'version.rc.in'))) {
|
|
91
|
+
console.log(' Copying version.rc.in...');
|
|
92
|
+
copyFile(
|
|
93
|
+
path.join(projectRoot, 'version.rc.in'),
|
|
94
|
+
path.join(nativeSrcDir, 'version.rc.in')
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// Copy src/ directory (only .cpp, .h, .hpp, .in files, excluding main.cpp)
|
|
99
|
+
console.log(' Copying src/ directory...');
|
|
100
|
+
const srcFilter = (name) => {
|
|
101
|
+
if (name === 'main.cpp') return false;
|
|
102
|
+
return name.endsWith('.cpp') || name.endsWith('.h') ||
|
|
103
|
+
name.endsWith('.hpp') || name.endsWith('.in');
|
|
104
|
+
};
|
|
105
|
+
copyDir(
|
|
106
|
+
path.join(projectRoot, 'src'),
|
|
107
|
+
path.join(nativeSrcDir, 'src'),
|
|
108
|
+
srcFilter
|
|
109
|
+
);
|
|
110
|
+
|
|
111
|
+
// Copy 3rdparty/ directory
|
|
112
|
+
if (fs.existsSync(path.join(projectRoot, '3rdparty'))) {
|
|
113
|
+
console.log(' Copying 3rdparty/ directory...');
|
|
114
|
+
copyDir(
|
|
115
|
+
path.join(projectRoot, '3rdparty'),
|
|
116
|
+
path.join(nativeSrcDir, '3rdparty')
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// Count copied files
|
|
121
|
+
let cppCount = 0;
|
|
122
|
+
let hCount = 0;
|
|
123
|
+
const countFiles = (dir) => {
|
|
124
|
+
if (!fs.existsSync(dir)) return;
|
|
125
|
+
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
126
|
+
for (const entry of entries) {
|
|
127
|
+
const fullPath = path.join(dir, entry.name);
|
|
128
|
+
if (entry.isDirectory()) {
|
|
129
|
+
countFiles(fullPath);
|
|
130
|
+
} else if (entry.name.endsWith('.cpp')) {
|
|
131
|
+
cppCount++;
|
|
132
|
+
} else if (entry.name.endsWith('.h') || entry.name.endsWith('.hpp')) {
|
|
133
|
+
hCount++;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
countFiles(nativeSrcDir);
|
|
138
|
+
|
|
139
|
+
console.log(`\n✓ Copied ${cppCount} source files and ${hCount} header files`);
|
|
140
|
+
|
|
141
|
+
// Verify critical files in nodejs package
|
|
19
142
|
const criticalFiles = [
|
|
20
|
-
// Node.js binding files
|
|
21
143
|
{ path: path.join(nodejsRoot, 'binding.gyp'), desc: 'Node.js binding configuration' },
|
|
22
144
|
{ path: path.join(nodejsRoot, 'lib', 'index.js'), desc: 'JavaScript wrapper' },
|
|
23
145
|
{ path: path.join(nodejsRoot, 'lib', 'index.d.ts'), desc: 'TypeScript definitions' },
|
|
24
146
|
{ path: path.join(nodejsRoot, 'src', 'librats_node.cpp'), desc: 'Node.js binding source' },
|
|
25
147
|
{ path: path.join(nodejsRoot, 'scripts', 'build-librats.js'), desc: 'Build script' },
|
|
26
148
|
{ path: path.join(nodejsRoot, 'scripts', 'postinstall.js'), desc: 'Post-install script' },
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
{ path: path.join(
|
|
30
|
-
{ path: path.join(
|
|
31
|
-
{ path: path.join(
|
|
32
|
-
{ path: path.join(projectRoot, 'src', 'librats_c.cpp'), desc: 'Librats C API' },
|
|
33
|
-
{ path: path.join(projectRoot, 'src', 'librats_c.h'), desc: 'Librats C API header' },
|
|
149
|
+
{ path: path.join(nativeSrcDir, 'CMakeLists.txt'), desc: 'CMake configuration (copied)' },
|
|
150
|
+
{ path: path.join(nativeSrcDir, 'src', 'librats.cpp'), desc: 'Librats main source (copied)' },
|
|
151
|
+
{ path: path.join(nativeSrcDir, 'src', 'librats.h'), desc: 'Librats main header (copied)' },
|
|
152
|
+
{ path: path.join(nativeSrcDir, 'src', 'librats_c.cpp'), desc: 'Librats C API (copied)' },
|
|
153
|
+
{ path: path.join(nativeSrcDir, 'src', 'librats_c.h'), desc: 'Librats C API header (copied)' },
|
|
34
154
|
];
|
|
35
155
|
|
|
36
156
|
let allFilesPresent = true;
|
|
37
157
|
let missingFiles = [];
|
|
38
158
|
|
|
39
|
-
console.log('\
|
|
159
|
+
console.log('\nVerifying required files:');
|
|
40
160
|
for (const file of criticalFiles) {
|
|
41
161
|
if (fs.existsSync(file.path)) {
|
|
42
162
|
console.log(` ✓ ${file.desc}`);
|
|
@@ -58,34 +178,10 @@ if (!allFilesPresent) {
|
|
|
58
178
|
process.exit(1);
|
|
59
179
|
}
|
|
60
180
|
|
|
61
|
-
// Check that lib directory exists and has content
|
|
62
|
-
const libDir = path.join(nodejsRoot, 'lib');
|
|
63
|
-
if (!fs.existsSync(libDir)) {
|
|
64
|
-
console.error('\n❌ ERROR: lib directory does not exist!');
|
|
65
|
-
console.error('Create it with the JavaScript wrapper and TypeScript definitions.');
|
|
66
|
-
process.exit(1);
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
// Check that scripts directory exists
|
|
70
|
-
const scriptsDir = path.join(nodejsRoot, 'scripts');
|
|
71
|
-
if (!fs.existsSync(scriptsDir)) {
|
|
72
|
-
console.error('\n❌ ERROR: scripts directory does not exist!');
|
|
73
|
-
console.error('This directory is required for the build process.');
|
|
74
|
-
process.exit(1);
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
// Count source files
|
|
78
|
-
const srcDir = path.join(projectRoot, 'src');
|
|
79
|
-
if (fs.existsSync(srcDir)) {
|
|
80
|
-
const sourceFiles = fs.readdirSync(srcDir)
|
|
81
|
-
.filter(f => f.endsWith('.cpp') || f.endsWith('.h'));
|
|
82
|
-
console.log(`\n✓ Found ${sourceFiles.length} source files in src/`);
|
|
83
|
-
}
|
|
84
|
-
|
|
85
181
|
console.log('\n✅ Package is ready for distribution!\n');
|
|
86
|
-
console.log('
|
|
182
|
+
console.log('The native-src/ directory now contains all C++ source files needed to build.');
|
|
183
|
+
console.log('\nWhen users install this package via npm:');
|
|
87
184
|
console.log(' 1. The preinstall script will build the librats C++ library');
|
|
88
185
|
console.log(' 2. The install script will build the Node.js native addon');
|
|
89
186
|
console.log(' 3. The postinstall script will verify the installation');
|
|
90
187
|
console.log('\nNo manual build steps are required by users!\n');
|
|
91
|
-
|
package/src/librats_node.cpp
CHANGED
|
@@ -473,7 +473,52 @@ private:
|
|
|
473
473
|
std::string content_hash = info[0].As<Napi::String>().Utf8Value();
|
|
474
474
|
int port = info[1].As<Napi::Number>().Int32Value();
|
|
475
475
|
|
|
476
|
-
|
|
476
|
+
// Check if optional callback is provided
|
|
477
|
+
rats_peers_found_cb c_callback = nullptr;
|
|
478
|
+
void* callback_user_data = nullptr;
|
|
479
|
+
Napi::ThreadSafeFunction* tsfn_ptr = nullptr;
|
|
480
|
+
|
|
481
|
+
if (info.Length() >= 3 && info[2].IsFunction()) {
|
|
482
|
+
// Create thread-safe function for callback
|
|
483
|
+
auto tsfn = new Napi::ThreadSafeFunction();
|
|
484
|
+
*tsfn = Napi::ThreadSafeFunction::New(
|
|
485
|
+
env,
|
|
486
|
+
info[2].As<Napi::Function>(),
|
|
487
|
+
"AnnounceForHashCallback",
|
|
488
|
+
0,
|
|
489
|
+
1,
|
|
490
|
+
[](Napi::Env) {} // Release callback
|
|
491
|
+
);
|
|
492
|
+
tsfn_ptr = tsfn;
|
|
493
|
+
|
|
494
|
+
c_callback = [](void* user_data, const char** peer_addresses, int count) {
|
|
495
|
+
auto* tsfn = static_cast<Napi::ThreadSafeFunction*>(user_data);
|
|
496
|
+
if (!tsfn) return;
|
|
497
|
+
|
|
498
|
+
// Copy peer addresses for async callback
|
|
499
|
+
std::vector<std::string>* peers = new std::vector<std::string>();
|
|
500
|
+
for (int i = 0; i < count; i++) {
|
|
501
|
+
if (peer_addresses[i]) {
|
|
502
|
+
peers->push_back(peer_addresses[i]);
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
tsfn->BlockingCall(peers, [](Napi::Env env, Napi::Function jsCallback, std::vector<std::string>* data) {
|
|
507
|
+
Napi::Array arr = Napi::Array::New(env, data->size());
|
|
508
|
+
for (size_t i = 0; i < data->size(); i++) {
|
|
509
|
+
arr.Set(static_cast<uint32_t>(i), Napi::String::New(env, (*data)[i]));
|
|
510
|
+
}
|
|
511
|
+
jsCallback.Call({arr});
|
|
512
|
+
delete data;
|
|
513
|
+
});
|
|
514
|
+
|
|
515
|
+
tsfn->Release();
|
|
516
|
+
delete tsfn;
|
|
517
|
+
};
|
|
518
|
+
callback_user_data = tsfn_ptr;
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
rats_error_t result = rats_announce_for_hash(client_, content_hash.c_str(), port, c_callback, callback_user_data);
|
|
477
522
|
return Napi::Boolean::New(env, result == RATS_SUCCESS);
|
|
478
523
|
}
|
|
479
524
|
|