node-rtc-connection 2.0.4 → 2.0.5

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 (53) hide show
  1. package/index.cjs +1 -0
  2. package/index.mjs +1 -0
  3. package/package.json +10 -47
  4. package/dist/index.cjs +0 -32
  5. package/dist/index.mjs +0 -43
  6. package/src/crypto/der.ts +0 -205
  7. package/src/crypto/x509.ts +0 -146
  8. package/src/datachannel/RTCDataChannel.ts +0 -388
  9. package/src/dtls/RTCCertificate.ts +0 -396
  10. package/src/dtls/cipher.ts +0 -198
  11. package/src/dtls/connection.ts +0 -974
  12. package/src/dtls/prf.ts +0 -62
  13. package/src/dtls/protocol.ts +0 -204
  14. package/src/foundation/ByteBufferQueue.ts +0 -237
  15. package/src/foundation/RTCError.ts +0 -276
  16. package/src/ice/RTCIceCandidate.ts +0 -349
  17. package/src/ice/ice-agent.ts +0 -609
  18. package/src/ice/stun-message.ts +0 -260
  19. package/src/index.ts +0 -72
  20. package/src/peerconnection/RTCPeerConnection.ts +0 -430
  21. package/src/sctp/association.ts +0 -523
  22. package/src/sctp/chunks.ts +0 -350
  23. package/src/sctp/crc32c.ts +0 -57
  24. package/src/sctp/datachannel-manager.ts +0 -187
  25. package/src/sctp/dcep.ts +0 -94
  26. package/src/sdp/RTCSessionDescription.ts +0 -115
  27. package/src/sdp/sdp-utils.ts +0 -229
  28. package/src/stun/stun-client.ts +0 -936
  29. package/src/transport-stack.ts +0 -165
  30. /package/{dist/types → types}/crypto/der.d.ts +0 -0
  31. /package/{dist/types → types}/crypto/x509.d.ts +0 -0
  32. /package/{dist/types → types}/datachannel/RTCDataChannel.d.ts +0 -0
  33. /package/{dist/types → types}/dtls/RTCCertificate.d.ts +0 -0
  34. /package/{dist/types → types}/dtls/cipher.d.ts +0 -0
  35. /package/{dist/types → types}/dtls/connection.d.ts +0 -0
  36. /package/{dist/types → types}/dtls/prf.d.ts +0 -0
  37. /package/{dist/types → types}/dtls/protocol.d.ts +0 -0
  38. /package/{dist/types → types}/foundation/ByteBufferQueue.d.ts +0 -0
  39. /package/{dist/types → types}/foundation/RTCError.d.ts +0 -0
  40. /package/{dist/types → types}/ice/RTCIceCandidate.d.ts +0 -0
  41. /package/{dist/types → types}/ice/ice-agent.d.ts +0 -0
  42. /package/{dist/types → types}/ice/stun-message.d.ts +0 -0
  43. /package/{dist/types → types}/index.d.ts +0 -0
  44. /package/{dist/types → types}/peerconnection/RTCPeerConnection.d.ts +0 -0
  45. /package/{dist/types → types}/sctp/association.d.ts +0 -0
  46. /package/{dist/types → types}/sctp/chunks.d.ts +0 -0
  47. /package/{dist/types → types}/sctp/crc32c.d.ts +0 -0
  48. /package/{dist/types → types}/sctp/datachannel-manager.d.ts +0 -0
  49. /package/{dist/types → types}/sctp/dcep.d.ts +0 -0
  50. /package/{dist/types → types}/sdp/RTCSessionDescription.d.ts +0 -0
  51. /package/{dist/types → types}/sdp/sdp-utils.d.ts +0 -0
  52. /package/{dist/types → types}/stun/stun-client.d.ts +0 -0
  53. /package/{dist/types → types}/transport-stack.d.ts +0 -0
@@ -1,276 +0,0 @@
1
- /**
2
- * @file RTCError - WebRTC-specific error types.
3
- *
4
- * Implements the W3C RTCError interface
5
- * (https://www.w3.org/TR/webrtc/#rtcerror-interface).
6
- *
7
- * Provides WebRTC-specific error types extending the standard Error class
8
- * with additional error detail types and metadata fields.
9
- *
10
- * @license MIT
11
- * @author nmhung1210
12
- */
13
-
14
- 'use strict';
15
-
16
- /**
17
- * RTCErrorDetailType enum - Standardized WebRTC error details.
18
- * Maps to RTCErrorDetailType from the WebRTC spec.
19
- *
20
- * @readonly
21
- * @enum {string}
22
- */
23
- const RTCErrorDetailType = Object.freeze({
24
- NONE: 'none',
25
- DATA_CHANNEL_FAILURE: 'data-channel-failure',
26
- DTLS_FAILURE: 'dtls-failure',
27
- FINGERPRINT_FAILURE: 'fingerprint-failure',
28
- SCTP_FAILURE: 'sctp-failure',
29
- SDP_SYNTAX_ERROR: 'sdp-syntax-error',
30
- HARDWARE_ENCODER_NOT_AVAILABLE: 'hardware-encoder-not-available',
31
- HARDWARE_ENCODER_ERROR: 'hardware-encoder-error',
32
- INVALID_STATE: 'invalid-state',
33
- INVALID_MODIFICATION: 'invalid-modification',
34
- INVALID_ACCESS_ERROR: 'invalid-access-error',
35
- OPERATION_ERROR: 'operation-error',
36
- } as const);
37
-
38
- /**
39
- * Error detail type string union.
40
- */
41
- type RTCErrorDetail = typeof RTCErrorDetailType[keyof typeof RTCErrorDetailType];
42
-
43
- /**
44
- * Error initialization dictionary.
45
- */
46
- interface RTCErrorInit {
47
- errorDetail?: string;
48
- sdpLineNumber?: number | null;
49
- httpRequestStatusCode?: number | null;
50
- sctpCauseCode?: number | null;
51
- receivedAlert?: number | null;
52
- sentAlert?: number | null;
53
- }
54
-
55
- /**
56
- * Native WebRTC error object shape.
57
- */
58
- interface NativeRTCError {
59
- error_detail?: string;
60
- sctp_cause_code?: number;
61
- message?: string;
62
- }
63
-
64
- /**
65
- * JSON representation of an RTCError.
66
- */
67
- interface RTCErrorJSON {
68
- name: string;
69
- message: string;
70
- errorDetail: string;
71
- sdpLineNumber?: number;
72
- httpRequestStatusCode?: number;
73
- sctpCauseCode?: number;
74
- receivedAlert?: number;
75
- sentAlert?: number;
76
- }
77
-
78
- /**
79
- * RTCError extends Error with WebRTC-specific error details.
80
- *
81
- * @extends Error
82
- */
83
- class RTCError extends Error {
84
- /** Export error detail types as static property */
85
- static readonly DetailType = RTCErrorDetailType;
86
-
87
- /**
88
- * Specific error category.
89
- * @private {string}
90
- */
91
- #errorDetail: string;
92
-
93
- #sdpLineNumber: number | null;
94
- #httpRequestStatusCode: number | null;
95
- #sctpCauseCode: number | null;
96
- #receivedAlert: number | null;
97
- #sentAlert: number | null;
98
-
99
- /**
100
- * Creates a new RTCError.
101
- *
102
- * @param {RTCErrorInit} [init={}] - Error initialization dictionary
103
- * @param {string} [init.errorDetail='none'] - Error detail type
104
- * @param {number} [init.sdpLineNumber] - SDP line number where error occurred
105
- * @param {number} [init.httpRequestStatusCode] - HTTP status code if relevant
106
- * @param {number} [init.sctpCauseCode] - SCTP cause code
107
- * @param {number} [init.receivedAlert] - TLS alert received
108
- * @param {number} [init.sentAlert] - TLS alert sent
109
- * @param {string} [message=''] - Error message
110
- */
111
- constructor(init: RTCErrorInit = {}, message = '') {
112
- super(message);
113
-
114
- this.name = 'RTCError';
115
-
116
- // Maintain stack trace in V8
117
- if (Error.captureStackTrace) {
118
- Error.captureStackTrace(this, RTCError);
119
- }
120
-
121
- // Validate and set errorDetail
122
- const errorDetail = init.errorDetail || RTCErrorDetailType.NONE;
123
- if (typeof errorDetail !== 'string') {
124
- throw new TypeError('errorDetail must be a string');
125
- }
126
-
127
- this.#errorDetail = errorDetail;
128
-
129
- // Optional numeric fields with validation
130
- this.#sdpLineNumber = this.#validateInteger(init.sdpLineNumber, 'sdpLineNumber');
131
- this.#httpRequestStatusCode = this.#validateInteger(init.httpRequestStatusCode, 'httpRequestStatusCode');
132
- this.#sctpCauseCode = this.#validateInteger(init.sctpCauseCode, 'sctpCauseCode');
133
- this.#receivedAlert = this.#validateUnsignedInteger(init.receivedAlert, 'receivedAlert');
134
- this.#sentAlert = this.#validateUnsignedInteger(init.sentAlert, 'sentAlert');
135
- }
136
-
137
- /**
138
- * Validates that a value is an integer or null/undefined.
139
- * @private
140
- * @param {*} value - Value to validate
141
- * @param {string} fieldName - Field name for error messages
142
- * @returns {number|null}
143
- * @throws {TypeError} If value is not an integer
144
- */
145
- #validateInteger(value: number | null | undefined, fieldName: string): number | null {
146
- if (value === undefined || value === null) {
147
- return null;
148
- }
149
- const num = Number(value);
150
- if (!Number.isInteger(num)) {
151
- throw new TypeError(`${fieldName} must be an integer`);
152
- }
153
- return num;
154
- }
155
-
156
- /**
157
- * Validates that a value is an unsigned integer or null/undefined.
158
- * @private
159
- * @param {*} value - Value to validate
160
- * @param {string} fieldName - Field name for error messages
161
- * @returns {number|null}
162
- * @throws {TypeError} If value is not an unsigned integer
163
- */
164
- #validateUnsignedInteger(value: number | null | undefined, fieldName: string): number | null {
165
- if (value === undefined || value === null) {
166
- return null;
167
- }
168
- const num = Number(value);
169
- if (!Number.isInteger(num) || num < 0) {
170
- throw new TypeError(`${fieldName} must be an unsigned integer`);
171
- }
172
- return num;
173
- }
174
-
175
- /**
176
- * RTCErrorDetailType - specific error category.
177
- * @type {string}
178
- */
179
- get errorDetail(): string {
180
- return this.#errorDetail;
181
- }
182
-
183
- /**
184
- * SDP line number where the error occurred (if applicable).
185
- * @type {number|null}
186
- */
187
- get sdpLineNumber(): number | null {
188
- return this.#sdpLineNumber;
189
- }
190
-
191
- /**
192
- * HTTP request status code (if applicable).
193
- * @type {number|null}
194
- */
195
- get httpRequestStatusCode(): number | null {
196
- return this.#httpRequestStatusCode;
197
- }
198
-
199
- /**
200
- * SCTP cause code (if applicable).
201
- * @type {number|null}
202
- */
203
- get sctpCauseCode(): number | null {
204
- return this.#sctpCauseCode;
205
- }
206
-
207
- /**
208
- * TLS alert value received (if applicable).
209
- * @type {number|null}
210
- */
211
- get receivedAlert(): number | null {
212
- return this.#receivedAlert;
213
- }
214
-
215
- /**
216
- * TLS alert value sent (if applicable).
217
- * @type {number|null}
218
- */
219
- get sentAlert(): number | null {
220
- return this.#sentAlert;
221
- }
222
-
223
- /**
224
- * Converts error to JSON representation.
225
- * @returns {Object} JSON representation of the error
226
- */
227
- toJSON(): RTCErrorJSON {
228
- const json: RTCErrorJSON = {
229
- name: this.name,
230
- message: this.message,
231
- errorDetail: this.#errorDetail,
232
- };
233
-
234
- if (this.#sdpLineNumber !== null) {
235
- json.sdpLineNumber = this.#sdpLineNumber;
236
- }
237
- if (this.#httpRequestStatusCode !== null) {
238
- json.httpRequestStatusCode = this.#httpRequestStatusCode;
239
- }
240
- if (this.#sctpCauseCode !== null) {
241
- json.sctpCauseCode = this.#sctpCauseCode;
242
- }
243
- if (this.#receivedAlert !== null) {
244
- json.receivedAlert = this.#receivedAlert;
245
- }
246
- if (this.#sentAlert !== null) {
247
- json.sentAlert = this.#sentAlert;
248
- }
249
-
250
- return json;
251
- }
252
-
253
- /**
254
- * Creates RTCError from a native WebRTC error object.
255
- * @param {Object} nativeError - Native error object
256
- * @param {string} [nativeError.error_detail] - Error detail type
257
- * @param {number} [nativeError.sctp_cause_code] - SCTP cause code
258
- * @param {string} [nativeError.message] - Error message
259
- * @returns {RTCError}
260
- */
261
- static fromNative(nativeError: NativeRTCError): RTCError {
262
- const init: RTCErrorInit = {
263
- errorDetail: nativeError.error_detail || RTCErrorDetailType.NONE,
264
- };
265
-
266
- if (nativeError.sctp_cause_code !== undefined) {
267
- init.sctpCauseCode = nativeError.sctp_cause_code;
268
- }
269
-
270
- return new RTCError(init, nativeError.message || 'Unknown error');
271
- }
272
- }
273
-
274
- export default RTCError;
275
- export { RTCError, RTCErrorDetailType };
276
- export type { RTCErrorInit, RTCErrorDetail, NativeRTCError, RTCErrorJSON };
@@ -1,349 +0,0 @@
1
- /**
2
- * @file RTCIceCandidate - ICE candidate representation.
3
- *
4
- * Implements the W3C RTCIceCandidate interface
5
- * (https://www.w3.org/TR/webrtc/#rtcicecandidate-interface).
6
- *
7
- * Represents an ICE (Interactive Connectivity Establishment) candidate that
8
- * describes a potential way to establish a connection with a peer.
9
- *
10
- * @license MIT
11
- * @author nmhung1210
12
- */
13
-
14
- 'use strict';
15
-
16
- /**
17
- * Initialization dictionary for RTCIceCandidate.
18
- */
19
- interface RTCIceCandidateInit {
20
- candidate?: string;
21
- sdpMid?: string | null;
22
- sdpMLineIndex?: number | null;
23
- usernameFragment?: string | null;
24
- }
25
-
26
- /**
27
- * Parsed attributes extracted from an ICE candidate string.
28
- */
29
- interface ParsedCandidateAttributes {
30
- foundation: string | null;
31
- component: string | null;
32
- protocol: string | null;
33
- priority: number | null;
34
- address: string | null;
35
- port: number | null;
36
- type: string | null;
37
- tcpType: string | null;
38
- relatedAddress: string | null;
39
- relatedPort: number | null;
40
- }
41
-
42
- /**
43
- * JSON representation of an RTCIceCandidate.
44
- */
45
- interface RTCIceCandidateJSON {
46
- candidate: string;
47
- sdpMid: string | null;
48
- sdpMLineIndex: number | null;
49
- usernameFragment?: string;
50
- }
51
-
52
- /**
53
- * RTCIceCandidate represents a potential method for establishing connectivity.
54
- *
55
- * ICE candidates are described using SDP (Session Description Protocol) syntax.
56
- * Each candidate describes a single address/port combination and transport protocol.
57
- */
58
- class RTCIceCandidate {
59
- /**
60
- * SDP candidate string.
61
- * @private {string}
62
- */
63
- #candidate: string;
64
-
65
- /**
66
- * Media stream identification.
67
- * @private {string|null}
68
- */
69
- #sdpMid: string | null;
70
-
71
- /**
72
- * Media line index (zero-based).
73
- * @private {number|null}
74
- */
75
- #sdpMLineIndex: number | null;
76
-
77
- /**
78
- * ICE username fragment.
79
- * @private {string|null}
80
- */
81
- #usernameFragment: string | null;
82
-
83
- #parsedAttributes: ParsedCandidateAttributes;
84
-
85
- /**
86
- * Creates a new RTCIceCandidate.
87
- *
88
- * @param {RTCIceCandidateInit} [candidateInit={}] - Initialization dictionary
89
- * @param {string} [candidateInit.candidate=''] - SDP candidate string
90
- * @param {string|null} [candidateInit.sdpMid] - Media stream ID
91
- * @param {number|null} [candidateInit.sdpMLineIndex] - M-line index
92
- * @param {string} [candidateInit.usernameFragment] - ICE username fragment
93
- * @throws {TypeError} If both sdpMid and sdpMLineIndex are null
94
- */
95
- constructor(candidateInit: RTCIceCandidateInit = {}) {
96
- // Validate that at least one of sdpMid or sdpMLineIndex is present
97
- if (candidateInit.sdpMid === null && candidateInit.sdpMLineIndex === null) {
98
- throw new TypeError('sdpMid and sdpMLineIndex are both null');
99
- }
100
-
101
- this.#candidate = candidateInit.candidate || '';
102
-
103
- this.#sdpMid = candidateInit.sdpMid !== undefined ? candidateInit.sdpMid : null;
104
-
105
- this.#sdpMLineIndex = candidateInit.sdpMLineIndex !== undefined ?
106
- candidateInit.sdpMLineIndex : null;
107
-
108
- this.#usernameFragment = candidateInit.usernameFragment || null;
109
-
110
- // Parse candidate string for detailed attributes
111
- this.#parsedAttributes = this.#parseCandidate(this.#candidate);
112
- }
113
-
114
- /**
115
- * Parses an ICE candidate string to extract attributes.
116
- * Format: "candidate:foundation component protocol priority address port typ type [raddr reladdr] [rport relport]"
117
- *
118
- * @private
119
- * @param {string} candidateStr - Candidate string to parse
120
- * @returns {Object} Parsed attributes
121
- */
122
- #parseCandidate(candidateStr: string): ParsedCandidateAttributes {
123
- const attrs: ParsedCandidateAttributes = {
124
- foundation: null,
125
- component: null,
126
- protocol: null,
127
- priority: null,
128
- address: null,
129
- port: null,
130
- type: null,
131
- tcpType: null,
132
- relatedAddress: null,
133
- relatedPort: null,
134
- };
135
-
136
- if (!candidateStr || !candidateStr.startsWith('candidate:')) {
137
- return attrs;
138
- }
139
-
140
- // Remove "candidate:" prefix
141
- const parts = candidateStr.substring(10).trim().split(/\s+/);
142
-
143
- if (parts.length < 8) {
144
- return attrs;
145
- }
146
-
147
- // Parse fixed fields
148
- attrs.foundation = parts[0]!;
149
- attrs.component = parts[1]!;
150
- attrs.protocol = parts[2]!.toLowerCase();
151
- attrs.priority = parseInt(parts[3]!, 10);
152
- attrs.address = parts[4]!;
153
- attrs.port = parseInt(parts[5]!, 10);
154
-
155
- // parts[6] should be "typ"
156
- if (parts[6] === 'typ') {
157
- attrs.type = parts[7]!;
158
- }
159
-
160
- // Parse optional attributes
161
- for (let i = 8; i < parts.length; i += 2) {
162
- const key = parts[i];
163
- const value = parts[i + 1];
164
-
165
- if (key === 'raddr') {
166
- attrs.relatedAddress = value!;
167
- } else if (key === 'rport') {
168
- attrs.relatedPort = parseInt(value!, 10);
169
- } else if (key === 'tcptype') {
170
- attrs.tcpType = value!;
171
- }
172
- }
173
-
174
- return attrs;
175
- }
176
-
177
- /**
178
- * SDP candidate attribute containing the candidate description.
179
- * @type {string}
180
- */
181
- get candidate(): string {
182
- return this.#candidate;
183
- }
184
-
185
- /**
186
- * Media stream identification tag.
187
- * @type {string|null}
188
- */
189
- get sdpMid(): string | null {
190
- return this.#sdpMid;
191
- }
192
-
193
- /**
194
- * Index of the m-line in the SDP this candidate is associated with.
195
- * @type {number|null}
196
- */
197
- get sdpMLineIndex(): number | null {
198
- return this.#sdpMLineIndex;
199
- }
200
-
201
- /**
202
- * ICE username fragment.
203
- * @type {string|null}
204
- */
205
- get usernameFragment(): string | null {
206
- return this.#usernameFragment;
207
- }
208
-
209
- /**
210
- * Unique identifier for this candidate.
211
- * @type {string|null}
212
- */
213
- get foundation(): string | null {
214
- return this.#parsedAttributes.foundation;
215
- }
216
-
217
- /**
218
- * Component identifier (rtp=1, rtcp=2).
219
- * @type {string|null}
220
- */
221
- get component(): string | null {
222
- return this.#parsedAttributes.component;
223
- }
224
-
225
- /**
226
- * Priority value for this candidate.
227
- * Higher priority candidates are preferred.
228
- * @type {number|null}
229
- */
230
- get priority(): number | null {
231
- return this.#parsedAttributes.priority;
232
- }
233
-
234
- /**
235
- * IP address of this candidate.
236
- * @type {string|null}
237
- */
238
- get address(): string | null {
239
- return this.#parsedAttributes.address;
240
- }
241
-
242
- /**
243
- * Transport protocol (udp/tcp).
244
- * @type {string|null}
245
- */
246
- get protocol(): string | null {
247
- return this.#parsedAttributes.protocol;
248
- }
249
-
250
- /**
251
- * Port number.
252
- * @type {number|null}
253
- */
254
- get port(): number | null {
255
- return this.#parsedAttributes.port;
256
- }
257
-
258
- /**
259
- * Type of candidate (host, srflx, prflx, relay).
260
- * @type {string|null}
261
- */
262
- get type(): string | null {
263
- return this.#parsedAttributes.type;
264
- }
265
-
266
- /**
267
- * TCP candidate type (active, passive, so).
268
- * Only applicable for TCP candidates.
269
- * @type {string|null}
270
- */
271
- get tcpType(): string | null {
272
- return this.#parsedAttributes.tcpType;
273
- }
274
-
275
- /**
276
- * Related address for reflexive/relay candidates.
277
- * @type {string|null}
278
- */
279
- get relatedAddress(): string | null {
280
- return this.#parsedAttributes.relatedAddress;
281
- }
282
-
283
- /**
284
- * Related port for reflexive/relay candidates.
285
- * @type {number|null}
286
- */
287
- get relatedPort(): number | null {
288
- return this.#parsedAttributes.relatedPort;
289
- }
290
-
291
- /**
292
- * Converts candidate to JSON representation.
293
- * @returns {Object} JSON representation
294
- */
295
- toJSON(): RTCIceCandidateJSON {
296
- const json: RTCIceCandidateJSON = {
297
- candidate: this.#candidate,
298
- sdpMid: this.#sdpMid,
299
- sdpMLineIndex: this.#sdpMLineIndex,
300
- };
301
-
302
- if (this.#usernameFragment) {
303
- json.usernameFragment = this.#usernameFragment;
304
- }
305
-
306
- return json;
307
- }
308
-
309
- /**
310
- * Creates an RTCIceCandidate from a candidate string.
311
- *
312
- * @param {string} candidateStr - ICE candidate string
313
- * @param {string|null} [sdpMid=null] - Media stream ID
314
- * @param {number|null} [sdpMLineIndex=0] - M-line index
315
- * @returns {RTCIceCandidate}
316
- */
317
- static fromString(candidateStr: string, sdpMid: string | null = null, sdpMLineIndex: number | null = 0): RTCIceCandidate {
318
- return new RTCIceCandidate({
319
- candidate: candidateStr,
320
- sdpMid,
321
- sdpMLineIndex,
322
- });
323
- }
324
-
325
- /**
326
- * Validates if a string is a valid candidate format.
327
- *
328
- * @param {string} candidateStr - String to validate
329
- * @returns {boolean} True if valid candidate format
330
- */
331
- static isValid(candidateStr: string): boolean {
332
- if (!candidateStr || typeof candidateStr !== 'string') {
333
- return false;
334
- }
335
-
336
- // Must start with "candidate:"
337
- if (!candidateStr.startsWith('candidate:')) {
338
- return false;
339
- }
340
-
341
- // Must have at least the minimum required fields
342
- const parts = candidateStr.substring(10).trim().split(/\s+/);
343
- return parts.length >= 8;
344
- }
345
- }
346
-
347
- export default RTCIceCandidate;
348
- export { RTCIceCandidate };
349
- export type { RTCIceCandidateInit, ParsedCandidateAttributes, RTCIceCandidateJSON };