@principal-ai/control-tower-core 0.1.25 → 0.2.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.
- package/dist/abstractions/AuthAdapter.d.ts +1 -1
- package/dist/abstractions/AuthAdapter.d.ts.map +1 -1
- package/dist/abstractions/DefaultLockManager.d.ts +2 -2
- package/dist/abstractions/DefaultLockManager.d.ts.map +1 -1
- package/dist/abstractions/DefaultLockManager.js +7 -8
- package/dist/abstractions/DefaultPresenceManager.d.ts +4 -4
- package/dist/abstractions/DefaultPresenceManager.d.ts.map +1 -1
- package/dist/abstractions/DefaultPresenceManager.js +25 -25
- package/dist/abstractions/DefaultRoomManager.d.ts +3 -3
- package/dist/abstractions/DefaultRoomManager.d.ts.map +1 -1
- package/dist/abstractions/DefaultRoomManager.js +6 -4
- package/dist/abstractions/EventEmitter.d.ts.map +1 -1
- package/dist/abstractions/LockManager.d.ts +1 -1
- package/dist/abstractions/LockManager.d.ts.map +1 -1
- package/dist/abstractions/LockManager.js +1 -1
- package/dist/abstractions/PresenceExtension.d.ts +2 -2
- package/dist/abstractions/PresenceExtension.d.ts.map +1 -1
- package/dist/abstractions/PresenceManager.d.ts +1 -1
- package/dist/abstractions/PresenceManager.d.ts.map +1 -1
- package/dist/abstractions/PresenceManager.js +5 -5
- package/dist/abstractions/RoomManager.d.ts +2 -2
- package/dist/abstractions/RoomManager.d.ts.map +1 -1
- package/dist/abstractions/StorageAdapter.d.ts +4 -4
- package/dist/abstractions/StorageAdapter.d.ts.map +1 -1
- package/dist/abstractions/TransportAdapter.d.ts +4 -4
- package/dist/abstractions/TransportAdapter.d.ts.map +1 -1
- package/dist/abstractions/index.d.ts +11 -11
- package/dist/abstractions/index.d.ts.map +1 -1
- package/dist/abstractions/index.js +9 -9
- package/dist/adapters/mock/MockAuthAdapter.d.ts +2 -2
- package/dist/adapters/mock/MockAuthAdapter.d.ts.map +1 -1
- package/dist/adapters/mock/MockAuthAdapter.js +13 -11
- package/dist/adapters/mock/MockRTCDataChannel.d.ts +83 -0
- package/dist/adapters/mock/MockRTCDataChannel.d.ts.map +1 -0
- package/dist/adapters/mock/MockRTCDataChannel.js +146 -0
- package/dist/adapters/mock/MockRTCPeerConnection.d.ts +168 -0
- package/dist/adapters/mock/MockRTCPeerConnection.d.ts.map +1 -0
- package/dist/adapters/mock/MockRTCPeerConnection.js +449 -0
- package/dist/adapters/mock/MockStorageAdapter.d.ts +1 -1
- package/dist/adapters/mock/MockStorageAdapter.d.ts.map +1 -1
- package/dist/adapters/mock/MockStorageAdapter.js +18 -18
- package/dist/adapters/mock/MockTransportAdapter.d.ts +2 -2
- package/dist/adapters/mock/MockTransportAdapter.d.ts.map +1 -1
- package/dist/adapters/mock/MockTransportAdapter.js +38 -38
- package/dist/adapters/mock/index.d.ts +5 -3
- package/dist/adapters/mock/index.d.ts.map +1 -1
- package/dist/adapters/mock/index.js +10 -5
- package/dist/adapters/webrtc/WebRTCSignalingAdapter.d.ts +135 -0
- package/dist/adapters/webrtc/WebRTCSignalingAdapter.d.ts.map +1 -0
- package/dist/adapters/webrtc/WebRTCSignalingAdapter.js +368 -0
- package/dist/adapters/webrtc/index.d.ts +2 -0
- package/dist/adapters/webrtc/index.d.ts.map +1 -0
- package/dist/adapters/webrtc/index.js +5 -0
- package/dist/adapters/websocket/BrowserWebSocketTransportAdapter.d.ts +75 -0
- package/dist/adapters/websocket/BrowserWebSocketTransportAdapter.d.ts.map +1 -0
- package/dist/adapters/websocket/BrowserWebSocketTransportAdapter.js +231 -0
- package/dist/adapters/websocket/WebSocketClientTransportAdapter.d.ts +3 -3
- package/dist/adapters/websocket/WebSocketClientTransportAdapter.d.ts.map +1 -1
- package/dist/adapters/websocket/WebSocketClientTransportAdapter.js +38 -38
- package/dist/adapters/websocket/WebSocketServerTransportAdapter.d.ts +7 -7
- package/dist/adapters/websocket/WebSocketServerTransportAdapter.d.ts.map +1 -1
- package/dist/adapters/websocket/WebSocketServerTransportAdapter.js +94 -91
- package/dist/adapters/websocket/browser.d.ts +2 -0
- package/dist/adapters/websocket/browser.d.ts.map +1 -0
- package/dist/adapters/websocket/browser.js +6 -0
- package/dist/adapters/websocket/index.d.ts +3 -2
- package/dist/adapters/websocket/index.d.ts.map +1 -1
- package/dist/adapters/websocket/index.js +7 -3
- package/dist/adapters/websocket/node.d.ts +3 -0
- package/dist/adapters/websocket/node.d.ts.map +1 -0
- package/dist/adapters/websocket/node.js +8 -0
- package/dist/client/BaseClient.d.ts +6 -6
- package/dist/client/BaseClient.d.ts.map +1 -1
- package/dist/client/BaseClient.js +86 -72
- package/dist/client/ClientBuilder.d.ts +5 -5
- package/dist/client/ClientBuilder.d.ts.map +1 -1
- package/dist/client/ClientBuilder.js +3 -3
- package/dist/client/PresenceClient.d.ts +4 -4
- package/dist/client/PresenceClient.d.ts.map +1 -1
- package/dist/client/PresenceClient.js +30 -30
- package/dist/client/index.d.ts +3 -3
- package/dist/client/index.d.ts.map +1 -1
- package/dist/index.d.ts +7 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +27 -19
- package/dist/index.js.map +27 -23
- package/dist/index.mjs +1585 -558
- package/dist/index.mjs.map +27 -23
- package/dist/server/BaseServer.d.ts +13 -13
- package/dist/server/BaseServer.d.ts.map +1 -1
- package/dist/server/BaseServer.js +218 -143
- package/dist/server/ExperimentalAPI.d.ts +7 -7
- package/dist/server/ExperimentalAPI.d.ts.map +1 -1
- package/dist/server/ExperimentalAPI.js +22 -22
- package/dist/server/ServerBuilder.d.ts +11 -11
- package/dist/server/ServerBuilder.d.ts.map +1 -1
- package/dist/server/ServerBuilder.js +10 -10
- package/dist/server/index.d.ts +3 -3
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +3 -3
- package/dist/types/auth.d.ts.map +1 -1
- package/dist/types/events.d.ts +10 -10
- package/dist/types/events.d.ts.map +1 -1
- package/dist/types/experimental.d.ts +2 -2
- package/dist/types/experimental.d.ts.map +1 -1
- package/dist/types/experimental.js +1 -1
- package/dist/types/index.d.ts +7 -7
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +2 -2
- package/dist/types/lock.d.ts +2 -2
- package/dist/types/lock.d.ts.map +1 -1
- package/dist/types/presence.d.ts +3 -3
- package/dist/types/presence.d.ts.map +1 -1
- package/dist/types/room.d.ts +4 -4
- package/dist/types/room.d.ts.map +1 -1
- package/dist/types/room.js +2 -2
- package/package.json +15 -7
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { IAuthAdapter } from
|
|
2
|
-
import type { TokenPayload } from
|
|
1
|
+
import type { IAuthAdapter } from "../../abstractions/AuthAdapter.js";
|
|
2
|
+
import type { TokenPayload } from "../../types/index.js";
|
|
3
3
|
export declare class MockAuthAdapter implements IAuthAdapter {
|
|
4
4
|
private tokens;
|
|
5
5
|
private revokedTokens;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MockAuthAdapter.d.ts","sourceRoot":"","sources":["../../../src/adapters/mock/MockAuthAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mCAAmC,CAAC;AACtE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEzD,qBAAa,eAAgB,YAAW,YAAY;
|
|
1
|
+
{"version":3,"file":"MockAuthAdapter.d.ts","sourceRoot":"","sources":["../../../src/adapters/mock/MockAuthAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mCAAmC,CAAC;AACtE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEzD,qBAAa,eAAgB,YAAW,YAAY;IACnD,OAAO,CAAC,MAAM,CAAwC;IACtD,OAAO,CAAC,aAAa,CAA0B;IAC/C,OAAO,CAAC,eAAe,CAAa;IACpC,OAAO,CAAC,cAAc,CAAkB;IACxC,OAAO,CAAC,YAAY,CAAa;IACjC,OAAO,CAAC,YAAY,CAAuB;gBAE/B,OAAO,CAAC,EAAE;QACrB,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,cAAc,CAAC,EAAE,OAAO,CAAC;KACzB;IAKK,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IAyBnD,aAAa,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC;IAgBrD,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAqB5C,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAW/C,eAAe,IAAI,MAAM,GAAG,IAAI;IAIhC,cAAc,IAAI,OAAO;IAIzB,cAAc,IAAI,MAAM;YAKV,aAAa;IAM3B;;OAEG;IACG,eAAe,CACpB,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE;QACT,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;QACvB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACnC,SAAS,CAAC,EAAE,MAAM,CAAC;KACnB,GACC,OAAO,CAAC,MAAM,CAAC;IAclB,aAAa,IAAI,MAAM;IAIvB,oBAAoB,IAAI,MAAM;IAI9B,WAAW,IAAI,IAAI;IAMnB,WAAW,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI;IAIhC,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;CAG3C"}
|
|
@@ -15,26 +15,26 @@ class MockAuthAdapter {
|
|
|
15
15
|
async validateToken(token) {
|
|
16
16
|
await this.simulateDelay();
|
|
17
17
|
if (this.shouldFailAuth) {
|
|
18
|
-
throw new Error(
|
|
18
|
+
throw new Error("Mock auth validation failed");
|
|
19
19
|
}
|
|
20
20
|
if (this.revokedTokens.has(token)) {
|
|
21
|
-
throw new Error(
|
|
21
|
+
throw new Error("Token has been revoked");
|
|
22
22
|
}
|
|
23
23
|
const payload = this.tokens.get(token);
|
|
24
24
|
if (!payload) {
|
|
25
|
-
throw new Error(
|
|
25
|
+
throw new Error("Invalid token");
|
|
26
26
|
}
|
|
27
27
|
// Check expiration
|
|
28
28
|
if (payload.expiresAt && payload.expiresAt < Date.now()) {
|
|
29
29
|
this.tokens.delete(token);
|
|
30
|
-
throw new Error(
|
|
30
|
+
throw new Error("Token expired");
|
|
31
31
|
}
|
|
32
32
|
return payload;
|
|
33
33
|
}
|
|
34
34
|
async generateToken(payload) {
|
|
35
35
|
await this.simulateDelay();
|
|
36
36
|
if (this.shouldFailAuth) {
|
|
37
|
-
throw new Error(
|
|
37
|
+
throw new Error("Mock token generation failed");
|
|
38
38
|
}
|
|
39
39
|
const token = `mock-token-${++this.tokenCounter}`;
|
|
40
40
|
// Set default expiration to 1 hour if not specified
|
|
@@ -45,7 +45,7 @@ class MockAuthAdapter {
|
|
|
45
45
|
async refreshToken(token) {
|
|
46
46
|
await this.simulateDelay();
|
|
47
47
|
if (this.shouldFailAuth) {
|
|
48
|
-
throw new Error(
|
|
48
|
+
throw new Error("Mock token refresh failed");
|
|
49
49
|
}
|
|
50
50
|
const payload = await this.validateToken(token);
|
|
51
51
|
// Revoke old token
|
|
@@ -53,14 +53,14 @@ class MockAuthAdapter {
|
|
|
53
53
|
// Generate new token with extended expiration
|
|
54
54
|
const newPayload = {
|
|
55
55
|
...payload,
|
|
56
|
-
expiresAt: Date.now() + 3600000 // 1 hour from now
|
|
56
|
+
expiresAt: Date.now() + 3600000, // 1 hour from now
|
|
57
57
|
};
|
|
58
58
|
return this.generateToken(newPayload);
|
|
59
59
|
}
|
|
60
60
|
async revokeToken(token) {
|
|
61
61
|
await this.simulateDelay();
|
|
62
62
|
if (this.shouldFailAuth) {
|
|
63
|
-
throw new Error(
|
|
63
|
+
throw new Error("Mock token revocation failed");
|
|
64
64
|
}
|
|
65
65
|
this.tokens.delete(token);
|
|
66
66
|
this.revokedTokens.add(token);
|
|
@@ -77,7 +77,7 @@ class MockAuthAdapter {
|
|
|
77
77
|
// Test helper methods
|
|
78
78
|
async simulateDelay() {
|
|
79
79
|
if (this.simulateLatency > 0) {
|
|
80
|
-
await new Promise(resolve => setTimeout(resolve, this.simulateLatency));
|
|
80
|
+
await new Promise((resolve) => setTimeout(resolve, this.simulateLatency));
|
|
81
81
|
}
|
|
82
82
|
}
|
|
83
83
|
/**
|
|
@@ -86,9 +86,11 @@ class MockAuthAdapter {
|
|
|
86
86
|
async createTestToken(userId, options) {
|
|
87
87
|
const payload = {
|
|
88
88
|
userId,
|
|
89
|
-
permissions: options?.permissions ?? [
|
|
89
|
+
permissions: options?.permissions ?? ["read", "write"],
|
|
90
90
|
metadata: options?.metadata,
|
|
91
|
-
expiresAt: options?.expiresIn
|
|
91
|
+
expiresAt: options?.expiresIn
|
|
92
|
+
? Date.now() + options.expiresIn
|
|
93
|
+
: undefined,
|
|
92
94
|
};
|
|
93
95
|
const token = await this.generateToken(payload);
|
|
94
96
|
this.currentToken = token;
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mock RTCDataChannel for simulation testing
|
|
3
|
+
*
|
|
4
|
+
* Simulates WebRTC data channel behavior without actual network I/O.
|
|
5
|
+
* Supports linking two channels for bidirectional message passing.
|
|
6
|
+
*/
|
|
7
|
+
export type RTCDataChannelState = "connecting" | "open" | "closing" | "closed";
|
|
8
|
+
export interface MockRTCDataChannelConfig {
|
|
9
|
+
/**
|
|
10
|
+
* Simulated message delivery latency (ms)
|
|
11
|
+
* @default 1
|
|
12
|
+
*/
|
|
13
|
+
simulateLatency?: number;
|
|
14
|
+
/**
|
|
15
|
+
* Maximum message size in bytes
|
|
16
|
+
* @default 262144 (256 KB)
|
|
17
|
+
*/
|
|
18
|
+
maxMessageSize?: number;
|
|
19
|
+
}
|
|
20
|
+
export declare class MockRTCDataChannel {
|
|
21
|
+
readonly label: string;
|
|
22
|
+
readonly ordered: boolean;
|
|
23
|
+
readonly id: number;
|
|
24
|
+
private _readyState;
|
|
25
|
+
private _bufferedAmount;
|
|
26
|
+
private _linkedChannel;
|
|
27
|
+
private messageQueue;
|
|
28
|
+
private config;
|
|
29
|
+
private static channelIdCounter;
|
|
30
|
+
onopen: (() => void) | null;
|
|
31
|
+
onclose: (() => void) | null;
|
|
32
|
+
onerror: ((event: {
|
|
33
|
+
error: Error;
|
|
34
|
+
}) => void) | null;
|
|
35
|
+
onmessage: ((event: {
|
|
36
|
+
data: string | ArrayBuffer;
|
|
37
|
+
}) => void) | null;
|
|
38
|
+
onbufferedamountlow: (() => void) | null;
|
|
39
|
+
bufferedAmountLowThreshold: number;
|
|
40
|
+
constructor(label: string, options?: {
|
|
41
|
+
ordered?: boolean;
|
|
42
|
+
id?: number;
|
|
43
|
+
}, config?: MockRTCDataChannelConfig);
|
|
44
|
+
get readyState(): RTCDataChannelState;
|
|
45
|
+
get bufferedAmount(): number;
|
|
46
|
+
/**
|
|
47
|
+
* Send data to the linked peer channel
|
|
48
|
+
*/
|
|
49
|
+
send(data: string | ArrayBuffer): void;
|
|
50
|
+
/**
|
|
51
|
+
* Close the data channel
|
|
52
|
+
*/
|
|
53
|
+
close(): void;
|
|
54
|
+
/**
|
|
55
|
+
* Link this channel to a remote channel for message passing
|
|
56
|
+
* @internal
|
|
57
|
+
*/
|
|
58
|
+
_linkChannel(channel: MockRTCDataChannel): void;
|
|
59
|
+
/**
|
|
60
|
+
* Open the channel (called when peer connection is established)
|
|
61
|
+
* @internal
|
|
62
|
+
*/
|
|
63
|
+
_open(): void;
|
|
64
|
+
/**
|
|
65
|
+
* Handle remote channel closing
|
|
66
|
+
* @internal
|
|
67
|
+
*/
|
|
68
|
+
_handleRemoteClose(): void;
|
|
69
|
+
/**
|
|
70
|
+
* Get the linked channel (for testing)
|
|
71
|
+
* @internal
|
|
72
|
+
*/
|
|
73
|
+
_getLinkedChannel(): MockRTCDataChannel | null;
|
|
74
|
+
/**
|
|
75
|
+
* Flush queued messages to linked channel
|
|
76
|
+
*/
|
|
77
|
+
private _flushQueue;
|
|
78
|
+
/**
|
|
79
|
+
* Reset the channel ID counter (for testing)
|
|
80
|
+
*/
|
|
81
|
+
static resetIdCounter(): void;
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=MockRTCDataChannel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MockRTCDataChannel.d.ts","sourceRoot":"","sources":["../../../src/adapters/mock/MockRTCDataChannel.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,MAAM,mBAAmB,GAAG,YAAY,GAAG,MAAM,GAAG,SAAS,GAAG,QAAQ,CAAC;AAE/E,MAAM,WAAW,wBAAwB;IACxC;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,qBAAa,kBAAkB;IAC9B,SAAgB,KAAK,EAAE,MAAM,CAAC;IAC9B,SAAgB,OAAO,EAAE,OAAO,CAAC;IACjC,SAAgB,EAAE,EAAE,MAAM,CAAC;IAE3B,OAAO,CAAC,WAAW,CAAqC;IACxD,OAAO,CAAC,eAAe,CAAK;IAC5B,OAAO,CAAC,cAAc,CAAmC;IACzD,OAAO,CAAC,YAAY,CAAmC;IACvD,OAAO,CAAC,MAAM,CAAqC;IACnD,OAAO,CAAC,MAAM,CAAC,gBAAgB,CAAK;IAG7B,MAAM,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,IAAI,CAAQ;IACnC,OAAO,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,IAAI,CAAQ;IACpC,OAAO,EAAE,CAAC,CAAC,KAAK,EAAE;QAAE,KAAK,EAAE,KAAK,CAAA;KAAE,KAAK,IAAI,CAAC,GAAG,IAAI,CAAQ;IAC3D,SAAS,EAAE,CAAC,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,GAAG,WAAW,CAAA;KAAE,KAAK,IAAI,CAAC,GAAG,IAAI,CACpE;IACC,mBAAmB,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,IAAI,CAAQ;IAEhD,0BAA0B,SAAK;gBAGrC,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,OAAO,CAAC;QAAC,EAAE,CAAC,EAAE,MAAM,CAAA;KAAE,EAC5C,MAAM,CAAC,EAAE,wBAAwB;IAWlC,IAAI,UAAU,IAAI,mBAAmB,CAEpC;IAED,IAAI,cAAc,IAAI,MAAM,CAE3B;IAED;;OAEG;IACH,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI;IAiCtC;;OAEG;IACH,KAAK,IAAI,IAAI;IAoBb;;;OAGG;IACH,YAAY,CAAC,OAAO,EAAE,kBAAkB,GAAG,IAAI;IAS/C;;;OAGG;IACH,KAAK,IAAI,IAAI;IAYb;;;OAGG;IACH,kBAAkB,IAAI,IAAI;IAO1B;;;OAGG;IACH,iBAAiB,IAAI,kBAAkB,GAAG,IAAI;IAI9C;;OAEG;IACH,OAAO,CAAC,WAAW;IAWnB;;OAEG;IACH,MAAM,CAAC,cAAc,IAAI,IAAI;CAG7B"}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Mock RTCDataChannel for simulation testing
|
|
4
|
+
*
|
|
5
|
+
* Simulates WebRTC data channel behavior without actual network I/O.
|
|
6
|
+
* Supports linking two channels for bidirectional message passing.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.MockRTCDataChannel = void 0;
|
|
10
|
+
class MockRTCDataChannel {
|
|
11
|
+
constructor(label, options, config) {
|
|
12
|
+
this._readyState = "connecting";
|
|
13
|
+
this._bufferedAmount = 0;
|
|
14
|
+
this._linkedChannel = null;
|
|
15
|
+
this.messageQueue = [];
|
|
16
|
+
// Event handlers
|
|
17
|
+
this.onopen = null;
|
|
18
|
+
this.onclose = null;
|
|
19
|
+
this.onerror = null;
|
|
20
|
+
this.onmessage = null;
|
|
21
|
+
this.onbufferedamountlow = null;
|
|
22
|
+
this.bufferedAmountLowThreshold = 0;
|
|
23
|
+
this.label = label;
|
|
24
|
+
this.ordered = options?.ordered ?? true;
|
|
25
|
+
this.id = options?.id ?? MockRTCDataChannel.channelIdCounter++;
|
|
26
|
+
this.config = {
|
|
27
|
+
simulateLatency: config?.simulateLatency ?? 1,
|
|
28
|
+
maxMessageSize: config?.maxMessageSize ?? 262144,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
get readyState() {
|
|
32
|
+
return this._readyState;
|
|
33
|
+
}
|
|
34
|
+
get bufferedAmount() {
|
|
35
|
+
return this._bufferedAmount;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Send data to the linked peer channel
|
|
39
|
+
*/
|
|
40
|
+
send(data) {
|
|
41
|
+
if (this._readyState !== "open") {
|
|
42
|
+
throw new Error(`Cannot send on channel in state: ${this._readyState}`);
|
|
43
|
+
}
|
|
44
|
+
const size = typeof data === "string" ? data.length : data.byteLength;
|
|
45
|
+
if (size > this.config.maxMessageSize) {
|
|
46
|
+
throw new Error(`Message size ${size} exceeds maximum ${this.config.maxMessageSize}`);
|
|
47
|
+
}
|
|
48
|
+
this._bufferedAmount += size;
|
|
49
|
+
// Deliver to linked channel
|
|
50
|
+
if (this._linkedChannel && this._linkedChannel._readyState === "open") {
|
|
51
|
+
setTimeout(() => {
|
|
52
|
+
this._bufferedAmount -= size;
|
|
53
|
+
// Check buffered amount low threshold
|
|
54
|
+
if (this._bufferedAmount <= this.bufferedAmountLowThreshold) {
|
|
55
|
+
this.onbufferedamountlow?.();
|
|
56
|
+
}
|
|
57
|
+
this._linkedChannel?.onmessage?.({ data });
|
|
58
|
+
}, this.config.simulateLatency);
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
// Queue for later delivery when channel opens
|
|
62
|
+
this.messageQueue.push(data);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Close the data channel
|
|
67
|
+
*/
|
|
68
|
+
close() {
|
|
69
|
+
if (this._readyState === "closed" || this._readyState === "closing") {
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
this._readyState = "closing";
|
|
73
|
+
setTimeout(() => {
|
|
74
|
+
this._readyState = "closed";
|
|
75
|
+
this.onclose?.();
|
|
76
|
+
// Notify linked channel
|
|
77
|
+
if (this._linkedChannel && this._linkedChannel._readyState !== "closed") {
|
|
78
|
+
this._linkedChannel._handleRemoteClose();
|
|
79
|
+
}
|
|
80
|
+
}, this.config.simulateLatency);
|
|
81
|
+
}
|
|
82
|
+
// Internal methods (called by MockRTCPeerConnection)
|
|
83
|
+
/**
|
|
84
|
+
* Link this channel to a remote channel for message passing
|
|
85
|
+
* @internal
|
|
86
|
+
*/
|
|
87
|
+
_linkChannel(channel) {
|
|
88
|
+
this._linkedChannel = channel;
|
|
89
|
+
// Deliver any queued messages once linked and both are open
|
|
90
|
+
if (this._readyState === "open" && channel._readyState === "open") {
|
|
91
|
+
this._flushQueue();
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Open the channel (called when peer connection is established)
|
|
96
|
+
* @internal
|
|
97
|
+
*/
|
|
98
|
+
_open() {
|
|
99
|
+
if (this._readyState === "connecting") {
|
|
100
|
+
this._readyState = "open";
|
|
101
|
+
this.onopen?.();
|
|
102
|
+
// Flush queued messages
|
|
103
|
+
if (this._linkedChannel?._readyState === "open") {
|
|
104
|
+
this._flushQueue();
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Handle remote channel closing
|
|
110
|
+
* @internal
|
|
111
|
+
*/
|
|
112
|
+
_handleRemoteClose() {
|
|
113
|
+
if (this._readyState !== "closed" && this._readyState !== "closing") {
|
|
114
|
+
this._readyState = "closed";
|
|
115
|
+
this.onclose?.();
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Get the linked channel (for testing)
|
|
120
|
+
* @internal
|
|
121
|
+
*/
|
|
122
|
+
_getLinkedChannel() {
|
|
123
|
+
return this._linkedChannel;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Flush queued messages to linked channel
|
|
127
|
+
*/
|
|
128
|
+
_flushQueue() {
|
|
129
|
+
for (const data of this.messageQueue) {
|
|
130
|
+
const size = typeof data === "string" ? data.length : data.byteLength;
|
|
131
|
+
setTimeout(() => {
|
|
132
|
+
this._bufferedAmount -= size;
|
|
133
|
+
this._linkedChannel?.onmessage?.({ data });
|
|
134
|
+
}, this.config.simulateLatency);
|
|
135
|
+
}
|
|
136
|
+
this.messageQueue = [];
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Reset the channel ID counter (for testing)
|
|
140
|
+
*/
|
|
141
|
+
static resetIdCounter() {
|
|
142
|
+
MockRTCDataChannel.channelIdCounter = 0;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
exports.MockRTCDataChannel = MockRTCDataChannel;
|
|
146
|
+
MockRTCDataChannel.channelIdCounter = 0;
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mock RTCPeerConnection for simulation testing
|
|
3
|
+
*
|
|
4
|
+
* Simulates WebRTC peer connection behavior without actual network I/O.
|
|
5
|
+
* Supports linking two mock connections for bidirectional testing.
|
|
6
|
+
*/
|
|
7
|
+
import { MockRTCDataChannel, type MockRTCDataChannelConfig } from "./MockRTCDataChannel.js";
|
|
8
|
+
export interface MockRTCPeerConnectionConfig {
|
|
9
|
+
/**
|
|
10
|
+
* Simulated latency for operations (ms)
|
|
11
|
+
* @default 10
|
|
12
|
+
*/
|
|
13
|
+
simulateLatency?: number;
|
|
14
|
+
/**
|
|
15
|
+
* Probability of ICE failure (0-1)
|
|
16
|
+
* @default 0
|
|
17
|
+
*/
|
|
18
|
+
iceFailureProbability?: number;
|
|
19
|
+
/**
|
|
20
|
+
* Simulated ICE gathering time (ms)
|
|
21
|
+
* @default 50
|
|
22
|
+
*/
|
|
23
|
+
iceGatheringTime?: number;
|
|
24
|
+
/**
|
|
25
|
+
* Whether to auto-generate ICE candidates
|
|
26
|
+
* @default true
|
|
27
|
+
*/
|
|
28
|
+
autoGenerateIceCandidates?: boolean;
|
|
29
|
+
/**
|
|
30
|
+
* Number of ICE candidates to generate
|
|
31
|
+
* @default 3
|
|
32
|
+
*/
|
|
33
|
+
iceCandidateCount?: number;
|
|
34
|
+
/**
|
|
35
|
+
* Configuration for data channels
|
|
36
|
+
*/
|
|
37
|
+
dataChannelConfig?: MockRTCDataChannelConfig;
|
|
38
|
+
}
|
|
39
|
+
export type RTCSignalingState = "stable" | "have-local-offer" | "have-remote-offer" | "have-local-pranswer" | "have-remote-pranswer" | "closed";
|
|
40
|
+
export type RTCIceConnectionState = "new" | "checking" | "connected" | "completed" | "disconnected" | "failed" | "closed";
|
|
41
|
+
export type RTCIceGatheringState = "new" | "gathering" | "complete";
|
|
42
|
+
export type RTCPeerConnectionState = "new" | "connecting" | "connected" | "disconnected" | "failed" | "closed";
|
|
43
|
+
export interface MockICECandidate {
|
|
44
|
+
candidate: string;
|
|
45
|
+
sdpMid: string | null;
|
|
46
|
+
sdpMLineIndex: number | null;
|
|
47
|
+
usernameFragment: string | null;
|
|
48
|
+
}
|
|
49
|
+
export interface MockSessionDescription {
|
|
50
|
+
type: "offer" | "answer" | "pranswer" | "rollback";
|
|
51
|
+
sdp: string;
|
|
52
|
+
}
|
|
53
|
+
export declare class MockRTCPeerConnection {
|
|
54
|
+
private _signalingState;
|
|
55
|
+
private _iceConnectionState;
|
|
56
|
+
private _iceGatheringState;
|
|
57
|
+
private _connectionState;
|
|
58
|
+
private _localDescription;
|
|
59
|
+
private _remoteDescription;
|
|
60
|
+
private _pendingLocalDescription;
|
|
61
|
+
private _pendingRemoteDescription;
|
|
62
|
+
private _localCandidates;
|
|
63
|
+
private _remoteCandidates;
|
|
64
|
+
private _pendingRemoteCandidates;
|
|
65
|
+
private _dataChannels;
|
|
66
|
+
onicecandidate: ((event: {
|
|
67
|
+
candidate: MockICECandidate | null;
|
|
68
|
+
}) => void) | null;
|
|
69
|
+
onicecandidateerror: ((event: {
|
|
70
|
+
errorCode: number;
|
|
71
|
+
errorText: string;
|
|
72
|
+
}) => void) | null;
|
|
73
|
+
oniceconnectionstatechange: (() => void) | null;
|
|
74
|
+
onicegatheringstatechange: (() => void) | null;
|
|
75
|
+
onconnectionstatechange: (() => void) | null;
|
|
76
|
+
onsignalingstatechange: (() => void) | null;
|
|
77
|
+
ondatachannel: ((event: {
|
|
78
|
+
channel: MockRTCDataChannel;
|
|
79
|
+
}) => void) | null;
|
|
80
|
+
onnegotiationneeded: (() => void) | null;
|
|
81
|
+
private _linkedPeer;
|
|
82
|
+
private config;
|
|
83
|
+
private offerCounter;
|
|
84
|
+
private iceUfrag;
|
|
85
|
+
private icePwd;
|
|
86
|
+
constructor(config?: MockRTCPeerConnectionConfig);
|
|
87
|
+
get signalingState(): RTCSignalingState;
|
|
88
|
+
get iceConnectionState(): RTCIceConnectionState;
|
|
89
|
+
get iceGatheringState(): RTCIceGatheringState;
|
|
90
|
+
get connectionState(): RTCPeerConnectionState;
|
|
91
|
+
get localDescription(): MockSessionDescription | null;
|
|
92
|
+
get remoteDescription(): MockSessionDescription | null;
|
|
93
|
+
get pendingLocalDescription(): MockSessionDescription | null;
|
|
94
|
+
get pendingRemoteDescription(): MockSessionDescription | null;
|
|
95
|
+
get currentLocalDescription(): MockSessionDescription | null;
|
|
96
|
+
get currentRemoteDescription(): MockSessionDescription | null;
|
|
97
|
+
/**
|
|
98
|
+
* Link two MockRTCPeerConnections for bidirectional testing.
|
|
99
|
+
* When linked, data channels automatically connect to the peer.
|
|
100
|
+
*/
|
|
101
|
+
static createLinkedPair(configA?: MockRTCPeerConnectionConfig, configB?: MockRTCPeerConnectionConfig): [MockRTCPeerConnection, MockRTCPeerConnection];
|
|
102
|
+
/**
|
|
103
|
+
* Create an SDP offer
|
|
104
|
+
*/
|
|
105
|
+
createOffer(): Promise<MockSessionDescription>;
|
|
106
|
+
/**
|
|
107
|
+
* Create an SDP answer
|
|
108
|
+
*/
|
|
109
|
+
createAnswer(): Promise<MockSessionDescription>;
|
|
110
|
+
/**
|
|
111
|
+
* Set local description (offer or answer)
|
|
112
|
+
*/
|
|
113
|
+
setLocalDescription(description?: MockSessionDescription): Promise<void>;
|
|
114
|
+
/**
|
|
115
|
+
* Set remote description (offer or answer from peer)
|
|
116
|
+
*/
|
|
117
|
+
setRemoteDescription(description: MockSessionDescription): Promise<void>;
|
|
118
|
+
/**
|
|
119
|
+
* Add ICE candidate from peer
|
|
120
|
+
*/
|
|
121
|
+
addIceCandidate(candidate?: MockICECandidate | null): Promise<void>;
|
|
122
|
+
/**
|
|
123
|
+
* Create a data channel
|
|
124
|
+
*/
|
|
125
|
+
createDataChannel(label: string, options?: {
|
|
126
|
+
ordered?: boolean;
|
|
127
|
+
id?: number;
|
|
128
|
+
}): MockRTCDataChannel;
|
|
129
|
+
/**
|
|
130
|
+
* Close the peer connection
|
|
131
|
+
*/
|
|
132
|
+
close(): void;
|
|
133
|
+
/**
|
|
134
|
+
* Get statistics (mock implementation)
|
|
135
|
+
*/
|
|
136
|
+
getStats(): Promise<Map<string, unknown>>;
|
|
137
|
+
/**
|
|
138
|
+
* Restart ICE (mock implementation)
|
|
139
|
+
*/
|
|
140
|
+
restartIce(): void;
|
|
141
|
+
/**
|
|
142
|
+
* Get all data channels
|
|
143
|
+
*/
|
|
144
|
+
getDataChannels(): Map<string, MockRTCDataChannel>;
|
|
145
|
+
/**
|
|
146
|
+
* Get local ICE candidates
|
|
147
|
+
*/
|
|
148
|
+
getLocalCandidates(): MockICECandidate[];
|
|
149
|
+
/**
|
|
150
|
+
* Get remote ICE candidates
|
|
151
|
+
*/
|
|
152
|
+
getRemoteCandidates(): MockICECandidate[];
|
|
153
|
+
/**
|
|
154
|
+
* Get the linked peer (for testing)
|
|
155
|
+
*/
|
|
156
|
+
getLinkedPeer(): MockRTCPeerConnection | null;
|
|
157
|
+
/**
|
|
158
|
+
* Manually trigger connection established (for testing)
|
|
159
|
+
*/
|
|
160
|
+
_forceConnected(): void;
|
|
161
|
+
private simulateDelay;
|
|
162
|
+
private generateMockSDP;
|
|
163
|
+
private startIceGathering;
|
|
164
|
+
private startIceConnection;
|
|
165
|
+
private openDataChannels;
|
|
166
|
+
private receiveDataChannelsFromPeer;
|
|
167
|
+
}
|
|
168
|
+
//# sourceMappingURL=MockRTCPeerConnection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MockRTCPeerConnection.d.ts","sourceRoot":"","sources":["../../../src/adapters/mock/MockRTCPeerConnection.ts"],"names":[],"mappings":"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"}
|