node-datachannel 0.29.0 → 0.30.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 (33) hide show
  1. package/.clang-format +17 -0
  2. package/CMakeLists.txt +5 -1
  3. package/dist/cjs/polyfill/RTCPeerConnection.cjs +6 -1
  4. package/dist/cjs/polyfill/RTCPeerConnection.cjs.map +1 -1
  5. package/dist/esm/polyfill/RTCPeerConnection.mjs +6 -1
  6. package/dist/esm/polyfill/RTCPeerConnection.mjs.map +1 -1
  7. package/dist/types/polyfill/RTCPeerConnection.d.ts +1 -2
  8. package/package.json +3 -2
  9. package/src/cpp/data-channel-wrapper.cpp +432 -411
  10. package/src/cpp/data-channel-wrapper.h +0 -2
  11. package/src/cpp/ice-udp-mux-listener-wrapper.cpp +104 -97
  12. package/src/cpp/main.cpp +11 -11
  13. package/src/cpp/media-audio-wrapper.cpp +291 -294
  14. package/src/cpp/media-audio-wrapper.h +1 -3
  15. package/src/cpp/media-direction.cpp +32 -32
  16. package/src/cpp/media-direction.h +1 -1
  17. package/src/cpp/media-rtcpreceivingsession-wrapper.cpp +24 -28
  18. package/src/cpp/media-rtcpreceivingsession-wrapper.h +0 -5
  19. package/src/cpp/media-track-wrapper.cpp +350 -339
  20. package/src/cpp/media-track-wrapper.h +0 -3
  21. package/src/cpp/media-video-wrapper.cpp +312 -313
  22. package/src/cpp/media-video-wrapper.h +1 -3
  23. package/src/cpp/peer-connection-wrapper.cpp +1094 -1047
  24. package/src/cpp/peer-connection-wrapper.h +0 -2
  25. package/src/cpp/rtc-wrapper.cpp +142 -138
  26. package/src/cpp/rtc-wrapper.h +8 -10
  27. package/src/cpp/thread-safe-callback.cpp +39 -50
  28. package/src/cpp/thread-safe-callback.h +26 -28
  29. package/src/cpp/web-socket-server-wrapper.cpp +205 -199
  30. package/src/cpp/web-socket-server-wrapper.h +0 -4
  31. package/src/cpp/web-socket-wrapper.cpp +625 -598
  32. package/src/cpp/web-socket-wrapper.h +0 -3
  33. package/src/polyfill/RTCPeerConnection.ts +9 -3
@@ -1,5 +1,4 @@
1
1
  #include "data-channel-wrapper.h"
2
-
3
2
  #include "plog/Log.h"
4
3
 
5
4
  Napi::FunctionReference DataChannelWrapper::constructor = Napi::FunctionReference();
@@ -7,503 +6,525 @@ std::unordered_set<DataChannelWrapper *> DataChannelWrapper::instances;
7
6
 
8
7
  void DataChannelWrapper::CloseAll()
9
8
  {
10
- PLOG_DEBUG << "CloseAll() called";
11
- auto copy(instances);
12
- for (auto inst : copy)
13
- inst->doClose();
9
+ PLOG_DEBUG << "CloseAll() called";
10
+ auto copy(instances);
11
+ for (auto inst : copy)
12
+ inst->doClose();
14
13
  }
15
14
 
16
15
  void DataChannelWrapper::CleanupAll()
17
16
  {
18
- PLOG_DEBUG << "CleanupAll() called";
19
- auto copy(instances);
20
- for (auto inst : copy)
21
- inst->doCleanup();
17
+ PLOG_DEBUG << "CleanupAll() called";
18
+ auto copy(instances);
19
+ for (auto inst : copy)
20
+ inst->doCleanup();
22
21
  }
23
22
 
24
23
  Napi::Object DataChannelWrapper::Init(Napi::Env env, Napi::Object exports)
25
24
  {
26
- Napi::HandleScope scope(env);
27
-
28
- Napi::Function func = DefineClass(
29
- env,
30
- "DataChannel",
31
- {
32
- InstanceMethod("close", &DataChannelWrapper::close),
33
- InstanceMethod("getLabel", &DataChannelWrapper::getLabel),
34
- InstanceMethod("getId", &DataChannelWrapper::getId),
35
- InstanceMethod("getProtocol", &DataChannelWrapper::getProtocol),
36
- InstanceMethod("sendMessage", &DataChannelWrapper::sendMessage),
37
- InstanceMethod("sendMessageBinary", &DataChannelWrapper::sendMessageBinary),
38
- InstanceMethod("isOpen", &DataChannelWrapper::isOpen),
39
- InstanceMethod("bufferedAmount", &DataChannelWrapper::bufferedAmount),
40
- InstanceMethod("maxMessageSize", &DataChannelWrapper::maxMessageSize),
41
- InstanceMethod("setBufferedAmountLowThreshold", &DataChannelWrapper::setBufferedAmountLowThreshold),
42
- InstanceMethod("onOpen", &DataChannelWrapper::onOpen),
43
- InstanceMethod("onClosed", &DataChannelWrapper::onClosed),
44
- InstanceMethod("onError", &DataChannelWrapper::onError),
45
- InstanceMethod("onBufferedAmountLow", &DataChannelWrapper::onBufferedAmountLow),
46
- InstanceMethod("onMessage", &DataChannelWrapper::onMessage),
47
- });
48
-
49
- // If this is not the first call, we don't want to reassign the constructor (hot-reload problem)
50
- if(constructor.IsEmpty())
51
- {
52
- constructor = Napi::Persistent(func);
53
- constructor.SuppressDestruct();
54
- }
55
-
56
- exports.Set("DataChannel", func);
57
- return exports;
25
+ Napi::HandleScope scope(env);
26
+
27
+ Napi::Function func = DefineClass(
28
+ env, "DataChannel",
29
+ {
30
+ InstanceMethod("close", &DataChannelWrapper::close),
31
+ InstanceMethod("getLabel", &DataChannelWrapper::getLabel),
32
+ InstanceMethod("getId", &DataChannelWrapper::getId),
33
+ InstanceMethod("getProtocol", &DataChannelWrapper::getProtocol),
34
+ InstanceMethod("sendMessage", &DataChannelWrapper::sendMessage),
35
+ InstanceMethod("sendMessageBinary", &DataChannelWrapper::sendMessageBinary),
36
+ InstanceMethod("isOpen", &DataChannelWrapper::isOpen),
37
+ InstanceMethod("bufferedAmount", &DataChannelWrapper::bufferedAmount),
38
+ InstanceMethod("maxMessageSize", &DataChannelWrapper::maxMessageSize),
39
+ InstanceMethod("setBufferedAmountLowThreshold", &DataChannelWrapper::setBufferedAmountLowThreshold),
40
+ InstanceMethod("onOpen", &DataChannelWrapper::onOpen),
41
+ InstanceMethod("onClosed", &DataChannelWrapper::onClosed),
42
+ InstanceMethod("onError", &DataChannelWrapper::onError),
43
+ InstanceMethod("onBufferedAmountLow", &DataChannelWrapper::onBufferedAmountLow),
44
+ InstanceMethod("onMessage", &DataChannelWrapper::onMessage),
45
+ });
46
+
47
+ // If this is not the first call, we don't want to reassign the constructor (hot-reload problem)
48
+ if (constructor.IsEmpty())
49
+ {
50
+ constructor = Napi::Persistent(func);
51
+ constructor.SuppressDestruct();
52
+ }
53
+
54
+ exports.Set("DataChannel", func);
55
+ return exports;
58
56
  }
59
57
 
60
58
  DataChannelWrapper::DataChannelWrapper(const Napi::CallbackInfo &info) : Napi::ObjectWrap<DataChannelWrapper>(info)
61
59
  {
62
- PLOG_DEBUG << "Constructor called";
63
- mDataChannelPtr = *(info[0].As<Napi::External<std::shared_ptr<rtc::DataChannel>>>().Data());
64
- PLOG_DEBUG << "Data Channel created";
60
+ PLOG_DEBUG << "Constructor called";
61
+ mDataChannelPtr = *(info[0].As<Napi::External<std::shared_ptr<rtc::DataChannel>>>().Data());
62
+ PLOG_DEBUG << "Data Channel created";
65
63
 
66
- // Closed callback must be set to trigger cleanup
67
- mOnClosedCallback = std::make_unique<ThreadSafeCallback>(Napi::Function::New(info.Env(), [](const Napi::CallbackInfo&){}));
64
+ // Closed callback must be set to trigger cleanup
65
+ mOnClosedCallback =
66
+ std::make_unique<ThreadSafeCallback>(Napi::Function::New(info.Env(), [](const Napi::CallbackInfo &) {}));
68
67
 
69
- instances.insert(this);
68
+ instances.insert(this);
70
69
  }
71
70
 
72
71
  DataChannelWrapper::~DataChannelWrapper()
73
72
  {
74
- PLOG_DEBUG << "Destructor called";
75
- doClose();
73
+ PLOG_DEBUG << "Destructor called";
74
+ doClose();
76
75
  }
77
76
 
78
77
  void DataChannelWrapper::doClose()
79
78
  {
80
- PLOG_DEBUG << "doClose() called";
81
- if (mDataChannelPtr)
79
+ PLOG_DEBUG << "doClose() called";
80
+ if (mDataChannelPtr)
81
+ {
82
+ PLOG_DEBUG << "Closing...";
83
+ try
82
84
  {
83
- PLOG_DEBUG << "Closing...";
84
- try
85
- {
86
- mDataChannelPtr->close();
87
- mDataChannelPtr.reset();
88
- }
89
- catch (std::exception &ex)
90
- {
91
- std::cerr << std::string("libdatachannel error while closing data channel: ") + ex.what() << std::endl;
92
- return;
93
- }
85
+ mDataChannelPtr->close();
86
+ mDataChannelPtr.reset();
87
+ }
88
+ catch (std::exception &ex)
89
+ {
90
+ std::cerr << std::string("libdatachannel error while closing data channel: ") + ex.what() << std::endl;
91
+ return;
94
92
  }
93
+ }
95
94
 
96
- mOnOpenCallback.reset();
97
- mOnErrorCallback.reset();
98
- mOnBufferedAmountLowCallback.reset();
99
- mOnMessageCallback.reset();
95
+ mOnOpenCallback.reset();
96
+ mOnErrorCallback.reset();
97
+ mOnBufferedAmountLowCallback.reset();
98
+ mOnMessageCallback.reset();
100
99
  }
101
100
 
102
101
  void DataChannelWrapper::doCleanup()
103
102
  {
104
- PLOG_DEBUG << "doCleanup() called";
105
- mOnClosedCallback.reset();
106
-
107
- // For close there are 3 cases:
108
- // 1. Close was called from JS
109
- // 2. Close was called from RTC
110
- // 3. Close was not called from JS or RTC (we are destroying the object)
111
- // This could be coming from rtc (case 2)
112
- mDataChannelPtr.reset();
113
- mOnOpenCallback.reset();
114
- mOnErrorCallback.reset();
115
- mOnBufferedAmountLowCallback.reset();
116
- mOnMessageCallback.reset();
117
- instances.erase(this);
103
+ PLOG_DEBUG << "doCleanup() called";
104
+ mOnClosedCallback.reset();
105
+
106
+ // For close there are 3 cases:
107
+ // 1. Close was called from JS
108
+ // 2. Close was called from RTC
109
+ // 3. Close was not called from JS or RTC (we are destroying the object)
110
+ // This could be coming from rtc (case 2)
111
+ mDataChannelPtr.reset();
112
+ mOnOpenCallback.reset();
113
+ mOnErrorCallback.reset();
114
+ mOnBufferedAmountLowCallback.reset();
115
+ mOnMessageCallback.reset();
116
+ instances.erase(this);
118
117
  }
119
118
 
120
119
  void DataChannelWrapper::close(const Napi::CallbackInfo &info)
121
120
  {
122
- PLOG_DEBUG << "close() called";
123
- doClose();
121
+ PLOG_DEBUG << "close() called";
122
+ doClose();
124
123
  }
125
124
 
126
125
  Napi::Value DataChannelWrapper::getLabel(const Napi::CallbackInfo &info)
127
126
  {
128
- PLOG_DEBUG << "getLabel() called";
129
- if (!mDataChannelPtr)
130
- {
131
- Napi::Error::New(info.Env(), "getLabel() called on destroyed channel").ThrowAsJavaScriptException();
132
- return info.Env().Null();
133
- }
134
-
135
- return Napi::String::New(info.Env(), mDataChannelPtr->label());
127
+ PLOG_DEBUG << "getLabel() called";
128
+ if (!mDataChannelPtr)
129
+ {
130
+ Napi::Error::New(info.Env(), "getLabel() called on destroyed channel").ThrowAsJavaScriptException();
131
+ return info.Env().Null();
132
+ }
133
+
134
+ return Napi::String::New(info.Env(), mDataChannelPtr->label());
136
135
  }
137
136
 
138
137
  Napi::Value DataChannelWrapper::getId(const Napi::CallbackInfo &info)
139
138
  {
140
- PLOG_DEBUG << "getId() called";
141
- if (!mDataChannelPtr)
142
- {
143
- Napi::Error::New(info.Env(), "getId() called on destroyed channel").ThrowAsJavaScriptException();
144
- return info.Env().Null();
145
- }
146
-
147
- return Napi::Number::New(info.Env(), mDataChannelPtr->id().value_or(-1));
139
+ PLOG_DEBUG << "getId() called";
140
+ if (!mDataChannelPtr)
141
+ {
142
+ Napi::Error::New(info.Env(), "getId() called on destroyed channel").ThrowAsJavaScriptException();
143
+ return info.Env().Null();
144
+ }
145
+
146
+ return Napi::Number::New(info.Env(), mDataChannelPtr->id().value_or(-1));
148
147
  }
149
148
 
150
149
  Napi::Value DataChannelWrapper::getProtocol(const Napi::CallbackInfo &info)
151
150
  {
152
- PLOG_DEBUG << "getProtocol() called";
153
- if (!mDataChannelPtr)
154
- {
155
- Napi::Error::New(info.Env(), "getProtocol() called on destroyed channel").ThrowAsJavaScriptException();
156
- return info.Env().Null();
157
- }
158
-
159
- return Napi::String::New(info.Env(), mDataChannelPtr->protocol());
151
+ PLOG_DEBUG << "getProtocol() called";
152
+ if (!mDataChannelPtr)
153
+ {
154
+ Napi::Error::New(info.Env(), "getProtocol() called on destroyed channel").ThrowAsJavaScriptException();
155
+ return info.Env().Null();
156
+ }
157
+
158
+ return Napi::String::New(info.Env(), mDataChannelPtr->protocol());
160
159
  }
161
160
 
162
161
  Napi::Value DataChannelWrapper::sendMessage(const Napi::CallbackInfo &info)
163
162
  {
164
- PLOG_DEBUG << "sendMessage() called";
165
- if (!mDataChannelPtr)
166
- {
167
- Napi::Error::New(info.Env(), "sendMessage() called on destroyed channel").ThrowAsJavaScriptException();
168
- return info.Env().Null();
169
- }
170
-
171
- Napi::Env env = info.Env();
172
- int length = info.Length();
173
-
174
- // Allow call with NULL
175
- if (length < 1 || (!info[0].IsString() && !info[0].IsNull()))
176
- {
177
- Napi::TypeError::New(env, "String or Null expected").ThrowAsJavaScriptException();
178
- return info.Env().Null();
179
- }
180
-
181
- try
182
- {
183
- return Napi::Boolean::New(info.Env(), mDataChannelPtr->send(info[0].As<Napi::String>().ToString()));
184
- }
185
- catch (std::exception &ex)
186
- {
187
- Napi::Error::New(env, std::string("libdatachannel error while sending data channel message: ") + ex.what()).ThrowAsJavaScriptException();
188
- return Napi::Boolean::New(info.Env(), false);
189
- }
163
+ PLOG_DEBUG << "sendMessage() called";
164
+ if (!mDataChannelPtr)
165
+ {
166
+ Napi::Error::New(info.Env(), "sendMessage() called on destroyed channel").ThrowAsJavaScriptException();
167
+ return info.Env().Null();
168
+ }
169
+
170
+ Napi::Env env = info.Env();
171
+ int length = info.Length();
172
+
173
+ // Allow call with NULL
174
+ if (length < 1 || (!info[0].IsString() && !info[0].IsNull()))
175
+ {
176
+ Napi::TypeError::New(env, "String or Null expected").ThrowAsJavaScriptException();
177
+ return info.Env().Null();
178
+ }
179
+
180
+ try
181
+ {
182
+ return Napi::Boolean::New(info.Env(), mDataChannelPtr->send(info[0].As<Napi::String>().ToString()));
183
+ }
184
+ catch (std::exception &ex)
185
+ {
186
+ Napi::Error::New(env, std::string("libdatachannel error while sending data channel message: ") + ex.what())
187
+ .ThrowAsJavaScriptException();
188
+ return Napi::Boolean::New(info.Env(), false);
189
+ }
190
190
  }
191
191
 
192
192
  Napi::Value DataChannelWrapper::sendMessageBinary(const Napi::CallbackInfo &info)
193
193
  {
194
- PLOG_DEBUG << "sendMessageBinary() called";
195
- if (!mDataChannelPtr)
196
- {
197
- Napi::Error::New(info.Env(), "sendMessagBinary() called on destroyed channel").ThrowAsJavaScriptException();
198
- return info.Env().Null();
199
- }
200
-
201
- Napi::Env env = info.Env();
202
- int length = info.Length();
203
-
204
- if (length < 1 || !info[0].IsBuffer())
205
- {
206
- Napi::TypeError::New(env, "Buffer expected").ThrowAsJavaScriptException();
207
- return info.Env().Null();
208
- }
209
-
210
- try
211
- {
212
- Napi::Uint8Array buffer = info[0].As<Napi::Uint8Array>();
213
- return Napi::Boolean::New(info.Env(), mDataChannelPtr->send((std::byte *)buffer.Data(), buffer.ByteLength()));
214
- }
215
- catch (std::exception &ex)
216
- {
217
- Napi::Error::New(env, std::string("libdatachannel error while sending data channel message: ") + ex.what()).ThrowAsJavaScriptException();
218
- return Napi::Boolean::New(info.Env(), false);
219
- }
194
+ PLOG_DEBUG << "sendMessageBinary() called";
195
+ if (!mDataChannelPtr)
196
+ {
197
+ Napi::Error::New(info.Env(), "sendMessagBinary() called on destroyed channel").ThrowAsJavaScriptException();
198
+ return info.Env().Null();
199
+ }
200
+
201
+ Napi::Env env = info.Env();
202
+ int length = info.Length();
203
+
204
+ if (length < 1 || !info[0].IsBuffer())
205
+ {
206
+ Napi::TypeError::New(env, "Buffer expected").ThrowAsJavaScriptException();
207
+ return info.Env().Null();
208
+ }
209
+
210
+ try
211
+ {
212
+ Napi::Uint8Array buffer = info[0].As<Napi::Uint8Array>();
213
+ return Napi::Boolean::New(info.Env(), mDataChannelPtr->send((std::byte *)buffer.Data(), buffer.ByteLength()));
214
+ }
215
+ catch (std::exception &ex)
216
+ {
217
+ Napi::Error::New(env, std::string("libdatachannel error while sending data channel message: ") + ex.what())
218
+ .ThrowAsJavaScriptException();
219
+ return Napi::Boolean::New(info.Env(), false);
220
+ }
220
221
  }
221
222
 
222
223
  Napi::Value DataChannelWrapper::isOpen(const Napi::CallbackInfo &info)
223
224
  {
224
- PLOG_DEBUG << "isOpen() called";
225
- Napi::Env env = info.Env();
226
-
227
- if (!mDataChannelPtr)
228
- {
229
- return Napi::Boolean::New(info.Env(), false);
230
- }
231
-
232
- try
233
- {
234
- return Napi::Boolean::New(info.Env(), mDataChannelPtr->isOpen());
235
- }
236
- catch (std::exception &ex)
237
- {
238
- Napi::Error::New(env, std::string("libdatachannel error: ") + ex.what()).ThrowAsJavaScriptException();
239
- return Napi::Boolean::New(info.Env(), false);
240
- }
225
+ PLOG_DEBUG << "isOpen() called";
226
+ Napi::Env env = info.Env();
227
+
228
+ if (!mDataChannelPtr)
229
+ {
230
+ return Napi::Boolean::New(info.Env(), false);
231
+ }
232
+
233
+ try
234
+ {
235
+ return Napi::Boolean::New(info.Env(), mDataChannelPtr->isOpen());
236
+ }
237
+ catch (std::exception &ex)
238
+ {
239
+ Napi::Error::New(env, std::string("libdatachannel error: ") + ex.what()).ThrowAsJavaScriptException();
240
+ return Napi::Boolean::New(info.Env(), false);
241
+ }
241
242
  }
242
243
 
243
244
  Napi::Value DataChannelWrapper::bufferedAmount(const Napi::CallbackInfo &info)
244
245
  {
245
- PLOG_DEBUG << "bufferedAmount() called";
246
- Napi::Env env = info.Env();
247
-
248
- if (!mDataChannelPtr)
249
- {
250
- return Napi::Number::New(info.Env(), 0);
251
- }
252
-
253
- try
254
- {
255
- return Napi::Number::New(info.Env(), mDataChannelPtr->bufferedAmount());
256
- }
257
- catch (std::exception &ex)
258
- {
259
- Napi::Error::New(env, std::string("libdatachannel error: ") + ex.what()).ThrowAsJavaScriptException();
260
- return Napi::Number::New(info.Env(), 0);
261
- }
246
+ PLOG_DEBUG << "bufferedAmount() called";
247
+ Napi::Env env = info.Env();
248
+
249
+ if (!mDataChannelPtr)
250
+ {
251
+ return Napi::Number::New(info.Env(), 0);
252
+ }
253
+
254
+ try
255
+ {
256
+ return Napi::Number::New(info.Env(), mDataChannelPtr->bufferedAmount());
257
+ }
258
+ catch (std::exception &ex)
259
+ {
260
+ Napi::Error::New(env, std::string("libdatachannel error: ") + ex.what()).ThrowAsJavaScriptException();
261
+ return Napi::Number::New(info.Env(), 0);
262
+ }
262
263
  }
263
264
 
264
265
  Napi::Value DataChannelWrapper::maxMessageSize(const Napi::CallbackInfo &info)
265
266
  {
266
- PLOG_DEBUG << "maxMessageSize() called";
267
- Napi::Env env = info.Env();
268
-
269
- if (!mDataChannelPtr)
270
- {
271
- return Napi::Number::New(info.Env(), 0);
272
- }
273
-
274
- try
275
- {
276
- return Napi::Number::New(info.Env(), mDataChannelPtr->maxMessageSize());
277
- }
278
- catch (std::exception &ex)
279
- {
280
- Napi::Error::New(env, std::string("libdatachannel error: ") + ex.what()).ThrowAsJavaScriptException();
281
- return Napi::Number::New(info.Env(), 0);
282
- }
267
+ PLOG_DEBUG << "maxMessageSize() called";
268
+ Napi::Env env = info.Env();
269
+
270
+ if (!mDataChannelPtr)
271
+ {
272
+ return Napi::Number::New(info.Env(), 0);
273
+ }
274
+
275
+ try
276
+ {
277
+ return Napi::Number::New(info.Env(), mDataChannelPtr->maxMessageSize());
278
+ }
279
+ catch (std::exception &ex)
280
+ {
281
+ Napi::Error::New(env, std::string("libdatachannel error: ") + ex.what()).ThrowAsJavaScriptException();
282
+ return Napi::Number::New(info.Env(), 0);
283
+ }
283
284
  }
284
285
 
285
286
  void DataChannelWrapper::setBufferedAmountLowThreshold(const Napi::CallbackInfo &info)
286
287
  {
287
- PLOG_DEBUG << "setBufferedAmountLowThreshold() called";
288
- if (!mDataChannelPtr)
289
- {
290
- Napi::Error::New(info.Env(), "setBufferedAmountLowThreshold() called on destroyed channel").ThrowAsJavaScriptException();
291
- return;
292
- }
293
-
294
- Napi::Env env = info.Env();
295
- int length = info.Length();
296
-
297
- if (length < 1 || !info[0].IsNumber())
298
- {
299
- Napi::TypeError::New(env, "Number expected").ThrowAsJavaScriptException();
300
- return;
301
- }
302
-
303
- try
304
- {
305
- mDataChannelPtr->setBufferedAmountLowThreshold(info[0].ToNumber().Uint32Value());
306
- }
307
- catch (std::exception &ex)
308
- {
309
- Napi::Error::New(env, std::string("libdatachannel error: ") + ex.what()).ThrowAsJavaScriptException();
310
- return;
311
- }
288
+ PLOG_DEBUG << "setBufferedAmountLowThreshold() called";
289
+ if (!mDataChannelPtr)
290
+ {
291
+ Napi::Error::New(info.Env(), "setBufferedAmountLowThreshold() called on destroyed channel")
292
+ .ThrowAsJavaScriptException();
293
+ return;
294
+ }
295
+
296
+ Napi::Env env = info.Env();
297
+ int length = info.Length();
298
+
299
+ if (length < 1 || !info[0].IsNumber())
300
+ {
301
+ Napi::TypeError::New(env, "Number expected").ThrowAsJavaScriptException();
302
+ return;
303
+ }
304
+
305
+ try
306
+ {
307
+ mDataChannelPtr->setBufferedAmountLowThreshold(info[0].ToNumber().Uint32Value());
308
+ }
309
+ catch (std::exception &ex)
310
+ {
311
+ Napi::Error::New(env, std::string("libdatachannel error: ") + ex.what()).ThrowAsJavaScriptException();
312
+ return;
313
+ }
312
314
  }
313
315
 
314
316
  void DataChannelWrapper::onOpen(const Napi::CallbackInfo &info)
315
317
  {
316
- PLOG_DEBUG << "onOpen() called";
317
- if (!mDataChannelPtr)
318
- {
319
- Napi::Error::New(info.Env(), "onOpen() called on destroyed channel").ThrowAsJavaScriptException();
320
- return;
321
- }
322
-
323
- Napi::Env env = info.Env();
324
- int length = info.Length();
325
-
326
- if (length < 1 || !info[0].IsFunction())
327
- {
328
- Napi::TypeError::New(env, "Function expected").ThrowAsJavaScriptException();
329
- return;
330
- }
331
-
332
- // Callback
333
- mOnOpenCallback = std::make_unique<ThreadSafeCallback>(info[0].As<Napi::Function>());
334
-
335
- mDataChannelPtr->onOpen([&]()
336
- {
337
- PLOG_DEBUG << "onOpen cb received from rtc";
338
- if (mOnOpenCallback)
339
- mOnOpenCallback->call([this](Napi::Env env, std::vector<napi_value> &args) {
340
- PLOG_DEBUG << "mOnOpenCallback call(1)";
341
- // Check the data channel is not closed
342
- if(instances.find(this) == instances.end())
343
- throw ThreadSafeCallback::CancelException();
344
-
345
- // This will run in main thread and needs to construct the
346
- // arguments for the call
347
- args = {};
348
- PLOG_DEBUG << "mOnOpenCallback call(2)";
349
- }); });
318
+ PLOG_DEBUG << "onOpen() called";
319
+ if (!mDataChannelPtr)
320
+ {
321
+ Napi::Error::New(info.Env(), "onOpen() called on destroyed channel").ThrowAsJavaScriptException();
322
+ return;
323
+ }
324
+
325
+ Napi::Env env = info.Env();
326
+ int length = info.Length();
327
+
328
+ if (length < 1 || !info[0].IsFunction())
329
+ {
330
+ Napi::TypeError::New(env, "Function expected").ThrowAsJavaScriptException();
331
+ return;
332
+ }
333
+
334
+ // Callback
335
+ mOnOpenCallback = std::make_unique<ThreadSafeCallback>(info[0].As<Napi::Function>());
336
+
337
+ mDataChannelPtr->onOpen(
338
+ [&]()
339
+ {
340
+ PLOG_DEBUG << "onOpen cb received from rtc";
341
+ if (mOnOpenCallback)
342
+ mOnOpenCallback->call(
343
+ [this](Napi::Env env, std::vector<napi_value> &args)
344
+ {
345
+ PLOG_DEBUG << "mOnOpenCallback call(1)";
346
+ // Check the data channel is not closed
347
+ if (instances.find(this) == instances.end())
348
+ throw ThreadSafeCallback::CancelException();
349
+
350
+ // This will run in main thread and needs to construct the
351
+ // arguments for the call
352
+ args = {};
353
+ PLOG_DEBUG << "mOnOpenCallback call(2)";
354
+ });
355
+ });
350
356
  }
351
357
 
352
358
  void DataChannelWrapper::onClosed(const Napi::CallbackInfo &info)
353
359
  {
354
- PLOG_DEBUG << "onClosed() called";
355
- if (!mDataChannelPtr)
356
- {
357
- Napi::Error::New(info.Env(), "onClosed() called on destroyed channel").ThrowAsJavaScriptException();
358
- return;
359
- }
360
-
361
- Napi::Env env = info.Env();
362
- int length = info.Length();
363
-
364
- if (length < 1 || !info[0].IsFunction())
365
- {
366
- Napi::TypeError::New(env, "Function expected").ThrowAsJavaScriptException();
367
- return;
368
- }
369
-
370
- // Callback
371
- mOnClosedCallback = std::make_unique<ThreadSafeCallback>(info[0].As<Napi::Function>());
372
-
373
- mDataChannelPtr->onClosed([&]()
374
- {
375
- PLOG_DEBUG << "onClosed cb received from rtc";
376
- if (mOnClosedCallback)
377
- mOnClosedCallback->call([this](Napi::Env env, std::vector<napi_value> &args) {
378
- PLOG_DEBUG << "mOnClosedCallback call";
379
- // Do not check if the data channel has been closed here
380
-
381
- // This will run in main thread and needs to construct the
382
- // arguments for the call
383
- args = {};
384
- },[this]{
385
- doCleanup();
386
- }); });
360
+ PLOG_DEBUG << "onClosed() called";
361
+ if (!mDataChannelPtr)
362
+ {
363
+ Napi::Error::New(info.Env(), "onClosed() called on destroyed channel").ThrowAsJavaScriptException();
364
+ return;
365
+ }
366
+
367
+ Napi::Env env = info.Env();
368
+ int length = info.Length();
369
+
370
+ if (length < 1 || !info[0].IsFunction())
371
+ {
372
+ Napi::TypeError::New(env, "Function expected").ThrowAsJavaScriptException();
373
+ return;
374
+ }
375
+
376
+ // Callback
377
+ mOnClosedCallback = std::make_unique<ThreadSafeCallback>(info[0].As<Napi::Function>());
378
+
379
+ mDataChannelPtr->onClosed(
380
+ [&]()
381
+ {
382
+ PLOG_DEBUG << "onClosed cb received from rtc";
383
+ if (mOnClosedCallback)
384
+ mOnClosedCallback->call(
385
+ [this](Napi::Env env, std::vector<napi_value> &args)
386
+ {
387
+ PLOG_DEBUG << "mOnClosedCallback call";
388
+ // Do not check if the data channel has been closed here
389
+
390
+ // This will run in main thread and needs to construct the
391
+ // arguments for the call
392
+ args = {};
393
+ },
394
+ [this] { doCleanup(); });
395
+ });
387
396
  }
388
397
 
389
398
  void DataChannelWrapper::onError(const Napi::CallbackInfo &info)
390
399
  {
391
- PLOG_DEBUG << "onError() called";
392
- if (!mDataChannelPtr)
393
- {
394
- Napi::Error::New(info.Env(), "onError() called on destroyed channel").ThrowAsJavaScriptException();
395
- return;
396
- }
397
-
398
- Napi::Env env = info.Env();
399
- int length = info.Length();
400
-
401
- if (length < 1 || !info[0].IsFunction())
402
- {
403
- Napi::TypeError::New(env, "Function expected").ThrowAsJavaScriptException();
404
- return;
405
- }
406
-
407
- // Callback
408
- mOnErrorCallback = std::make_unique<ThreadSafeCallback>(info[0].As<Napi::Function>());
409
-
410
- mDataChannelPtr->onError([&](std::string error)
411
- {
412
- PLOG_DEBUG << "onError cb received from rtc";
413
- if (mOnErrorCallback)
414
- mOnErrorCallback->call([this, error = std::move(error)](Napi::Env env, std::vector<napi_value> &args) {
415
- PLOG_DEBUG << "mOnErrorCallback call(1)";
416
- // Check the data channel is not closed
417
- if(instances.find(this) == instances.end())
418
- throw ThreadSafeCallback::CancelException();
419
-
420
- // This will run in main thread and needs to construct the
421
- // arguments for the call
422
- args = {Napi::String::New(env, error)};
423
- PLOG_DEBUG << "mOnErrorCallback call(2)";
424
- }); });
400
+ PLOG_DEBUG << "onError() called";
401
+ if (!mDataChannelPtr)
402
+ {
403
+ Napi::Error::New(info.Env(), "onError() called on destroyed channel").ThrowAsJavaScriptException();
404
+ return;
405
+ }
406
+
407
+ Napi::Env env = info.Env();
408
+ int length = info.Length();
409
+
410
+ if (length < 1 || !info[0].IsFunction())
411
+ {
412
+ Napi::TypeError::New(env, "Function expected").ThrowAsJavaScriptException();
413
+ return;
414
+ }
415
+
416
+ // Callback
417
+ mOnErrorCallback = std::make_unique<ThreadSafeCallback>(info[0].As<Napi::Function>());
418
+
419
+ mDataChannelPtr->onError(
420
+ [&](std::string error)
421
+ {
422
+ PLOG_DEBUG << "onError cb received from rtc";
423
+ if (mOnErrorCallback)
424
+ mOnErrorCallback->call(
425
+ [this, error = std::move(error)](Napi::Env env, std::vector<napi_value> &args)
426
+ {
427
+ PLOG_DEBUG << "mOnErrorCallback call(1)";
428
+ // Check the data channel is not closed
429
+ if (instances.find(this) == instances.end())
430
+ throw ThreadSafeCallback::CancelException();
431
+
432
+ // This will run in main thread and needs to construct the
433
+ // arguments for the call
434
+ args = {Napi::String::New(env, error)};
435
+ PLOG_DEBUG << "mOnErrorCallback call(2)";
436
+ });
437
+ });
425
438
  }
426
439
 
427
440
  void DataChannelWrapper::onBufferedAmountLow(const Napi::CallbackInfo &info)
428
441
  {
429
- PLOG_DEBUG << "onBufferedAmountLow() called";
430
- if (!mDataChannelPtr)
431
- {
432
- Napi::Error::New(info.Env(), "onBufferedAmountLow() called on destroyed channel").ThrowAsJavaScriptException();
433
- return;
434
- }
435
-
436
- Napi::Env env = info.Env();
437
- int length = info.Length();
438
-
439
- if (length < 1 || !info[0].IsFunction())
440
- {
441
- Napi::TypeError::New(env, "Function expected").ThrowAsJavaScriptException();
442
- return;
443
- }
444
-
445
- // Callback
446
- mOnBufferedAmountLowCallback = std::make_unique<ThreadSafeCallback>(info[0].As<Napi::Function>());
447
-
448
- mDataChannelPtr->onBufferedAmountLow([&]()
449
- {
450
- PLOG_DEBUG << "onBufferedAmountLow cb received from rtc";
451
- if (mOnBufferedAmountLowCallback)
452
- mOnBufferedAmountLowCallback->call([this](Napi::Env env, std::vector<napi_value> &args) {
453
- PLOG_DEBUG << "mOnBufferedAmountLowCallback call(1)";
454
- // Check the data channel is not closed
455
- if(instances.find(this) == instances.end())
456
- throw ThreadSafeCallback::CancelException();
457
-
458
- // This will run in main thread and needs to construct the
459
- // arguments for the call
460
- args = {};
461
- PLOG_DEBUG << "mOnBufferedAmountLowCallback call(2)";
462
- }); });
442
+ PLOG_DEBUG << "onBufferedAmountLow() called";
443
+ if (!mDataChannelPtr)
444
+ {
445
+ Napi::Error::New(info.Env(), "onBufferedAmountLow() called on destroyed channel").ThrowAsJavaScriptException();
446
+ return;
447
+ }
448
+
449
+ Napi::Env env = info.Env();
450
+ int length = info.Length();
451
+
452
+ if (length < 1 || !info[0].IsFunction())
453
+ {
454
+ Napi::TypeError::New(env, "Function expected").ThrowAsJavaScriptException();
455
+ return;
456
+ }
457
+
458
+ // Callback
459
+ mOnBufferedAmountLowCallback = std::make_unique<ThreadSafeCallback>(info[0].As<Napi::Function>());
460
+
461
+ mDataChannelPtr->onBufferedAmountLow(
462
+ [&]()
463
+ {
464
+ PLOG_DEBUG << "onBufferedAmountLow cb received from rtc";
465
+ if (mOnBufferedAmountLowCallback)
466
+ mOnBufferedAmountLowCallback->call(
467
+ [this](Napi::Env env, std::vector<napi_value> &args)
468
+ {
469
+ PLOG_DEBUG << "mOnBufferedAmountLowCallback call(1)";
470
+ // Check the data channel is not closed
471
+ if (instances.find(this) == instances.end())
472
+ throw ThreadSafeCallback::CancelException();
473
+
474
+ // This will run in main thread and needs to construct the
475
+ // arguments for the call
476
+ args = {};
477
+ PLOG_DEBUG << "mOnBufferedAmountLowCallback call(2)";
478
+ });
479
+ });
463
480
  }
464
481
 
465
482
  void DataChannelWrapper::onMessage(const Napi::CallbackInfo &info)
466
483
  {
467
- PLOG_DEBUG << "onMessage() called";
468
- if (!mDataChannelPtr)
469
- {
470
- Napi::Error::New(info.Env(), "onMessage() called on destroyed channel").ThrowAsJavaScriptException();
471
- return;
472
- }
473
-
474
- Napi::Env env = info.Env();
475
- int length = info.Length();
476
-
477
- if (length < 1 || !info[0].IsFunction())
478
- {
479
- Napi::TypeError::New(env, "Function expected").ThrowAsJavaScriptException();
480
- return;
481
- }
482
-
483
- // Callback
484
- mOnMessageCallback = std::make_unique<ThreadSafeCallback>(info[0].As<Napi::Function>());
485
-
486
- mDataChannelPtr->onMessage([&](std::variant<rtc::binary, std::string> message)
487
- {
488
- PLOG_DEBUG << "onMessage cb received from rtc";
489
- if (mOnMessageCallback)
490
- mOnMessageCallback->call([this, message = std::move(message)](Napi::Env env, std::vector<napi_value> &args) {
491
- PLOG_DEBUG << "mOnMessageCallback call(1)";
492
- // Check the data channel is not closed
493
- if(instances.find(this) == instances.end())
494
- throw ThreadSafeCallback::CancelException();
495
-
496
- // This will run in main thread and needs to construct the
497
- // arguments for the call
498
- if (std::holds_alternative<std::string>(message))
499
- {
500
- args = {Napi::String::New(env, std::get<std::string>(message))};
501
- }
502
- else
503
- {
504
- auto bin = std::get<rtc::binary>(std::move(message));
505
- args = {Napi::Buffer<std::byte>::Copy(env, bin.data(), bin.size())};
506
- }
507
- PLOG_DEBUG << "mOnMessageCallback call(2)";
508
- }); });
484
+ PLOG_DEBUG << "onMessage() called";
485
+ if (!mDataChannelPtr)
486
+ {
487
+ Napi::Error::New(info.Env(), "onMessage() called on destroyed channel").ThrowAsJavaScriptException();
488
+ return;
489
+ }
490
+
491
+ Napi::Env env = info.Env();
492
+ int length = info.Length();
493
+
494
+ if (length < 1 || !info[0].IsFunction())
495
+ {
496
+ Napi::TypeError::New(env, "Function expected").ThrowAsJavaScriptException();
497
+ return;
498
+ }
499
+
500
+ // Callback
501
+ mOnMessageCallback = std::make_unique<ThreadSafeCallback>(info[0].As<Napi::Function>());
502
+
503
+ mDataChannelPtr->onMessage(
504
+ [&](std::variant<rtc::binary, std::string> message)
505
+ {
506
+ PLOG_DEBUG << "onMessage cb received from rtc";
507
+ if (mOnMessageCallback)
508
+ mOnMessageCallback->call(
509
+ [this, message = std::move(message)](Napi::Env env, std::vector<napi_value> &args)
510
+ {
511
+ PLOG_DEBUG << "mOnMessageCallback call(1)";
512
+ // Check the data channel is not closed
513
+ if (instances.find(this) == instances.end())
514
+ throw ThreadSafeCallback::CancelException();
515
+
516
+ // This will run in main thread and needs to construct the
517
+ // arguments for the call
518
+ if (std::holds_alternative<std::string>(message))
519
+ {
520
+ args = {Napi::String::New(env, std::get<std::string>(message))};
521
+ }
522
+ else
523
+ {
524
+ auto bin = std::get<rtc::binary>(std::move(message));
525
+ args = {Napi::Buffer<std::byte>::Copy(env, bin.data(), bin.size())};
526
+ }
527
+ PLOG_DEBUG << "mOnMessageCallback call(2)";
528
+ });
529
+ });
509
530
  }