@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
|
@@ -0,0 +1,449 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Mock RTCPeerConnection for simulation testing
|
|
4
|
+
*
|
|
5
|
+
* Simulates WebRTC peer connection behavior without actual network I/O.
|
|
6
|
+
* Supports linking two mock connections for bidirectional testing.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.MockRTCPeerConnection = void 0;
|
|
10
|
+
const MockRTCDataChannel_js_1 = require("./MockRTCDataChannel.js");
|
|
11
|
+
class MockRTCPeerConnection {
|
|
12
|
+
constructor(config) {
|
|
13
|
+
// State
|
|
14
|
+
this._signalingState = "stable";
|
|
15
|
+
this._iceConnectionState = "new";
|
|
16
|
+
this._iceGatheringState = "new";
|
|
17
|
+
this._connectionState = "new";
|
|
18
|
+
// Descriptions
|
|
19
|
+
this._localDescription = null;
|
|
20
|
+
this._remoteDescription = null;
|
|
21
|
+
this._pendingLocalDescription = null;
|
|
22
|
+
this._pendingRemoteDescription = null;
|
|
23
|
+
// ICE candidates
|
|
24
|
+
this._localCandidates = [];
|
|
25
|
+
this._remoteCandidates = [];
|
|
26
|
+
this._pendingRemoteCandidates = [];
|
|
27
|
+
// Data channels
|
|
28
|
+
this._dataChannels = new Map();
|
|
29
|
+
// Event handlers
|
|
30
|
+
this.onicecandidate = null;
|
|
31
|
+
this.onicecandidateerror = null;
|
|
32
|
+
this.oniceconnectionstatechange = null;
|
|
33
|
+
this.onicegatheringstatechange = null;
|
|
34
|
+
this.onconnectionstatechange = null;
|
|
35
|
+
this.onsignalingstatechange = null;
|
|
36
|
+
this.ondatachannel = null;
|
|
37
|
+
this.onnegotiationneeded = null;
|
|
38
|
+
// Linked peer for simulation
|
|
39
|
+
this._linkedPeer = null;
|
|
40
|
+
this.offerCounter = 0;
|
|
41
|
+
this.config = {
|
|
42
|
+
simulateLatency: config?.simulateLatency ?? 10,
|
|
43
|
+
iceFailureProbability: config?.iceFailureProbability ?? 0,
|
|
44
|
+
iceGatheringTime: config?.iceGatheringTime ?? 50,
|
|
45
|
+
autoGenerateIceCandidates: config?.autoGenerateIceCandidates ?? true,
|
|
46
|
+
iceCandidateCount: config?.iceCandidateCount ?? 3,
|
|
47
|
+
dataChannelConfig: config?.dataChannelConfig,
|
|
48
|
+
};
|
|
49
|
+
// Generate random ICE credentials
|
|
50
|
+
this.iceUfrag = "mock" + Math.random().toString(36).substring(2, 6);
|
|
51
|
+
this.icePwd = "mock" + Math.random().toString(36).substring(2, 26);
|
|
52
|
+
}
|
|
53
|
+
// Getters
|
|
54
|
+
get signalingState() {
|
|
55
|
+
return this._signalingState;
|
|
56
|
+
}
|
|
57
|
+
get iceConnectionState() {
|
|
58
|
+
return this._iceConnectionState;
|
|
59
|
+
}
|
|
60
|
+
get iceGatheringState() {
|
|
61
|
+
return this._iceGatheringState;
|
|
62
|
+
}
|
|
63
|
+
get connectionState() {
|
|
64
|
+
return this._connectionState;
|
|
65
|
+
}
|
|
66
|
+
get localDescription() {
|
|
67
|
+
return this._localDescription;
|
|
68
|
+
}
|
|
69
|
+
get remoteDescription() {
|
|
70
|
+
return this._remoteDescription;
|
|
71
|
+
}
|
|
72
|
+
get pendingLocalDescription() {
|
|
73
|
+
return this._pendingLocalDescription;
|
|
74
|
+
}
|
|
75
|
+
get pendingRemoteDescription() {
|
|
76
|
+
return this._pendingRemoteDescription;
|
|
77
|
+
}
|
|
78
|
+
get currentLocalDescription() {
|
|
79
|
+
return this._localDescription;
|
|
80
|
+
}
|
|
81
|
+
get currentRemoteDescription() {
|
|
82
|
+
return this._remoteDescription;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Link two MockRTCPeerConnections for bidirectional testing.
|
|
86
|
+
* When linked, data channels automatically connect to the peer.
|
|
87
|
+
*/
|
|
88
|
+
static createLinkedPair(configA, configB) {
|
|
89
|
+
const peerA = new MockRTCPeerConnection(configA);
|
|
90
|
+
const peerB = new MockRTCPeerConnection(configB);
|
|
91
|
+
peerA._linkedPeer = peerB;
|
|
92
|
+
peerB._linkedPeer = peerA;
|
|
93
|
+
return [peerA, peerB];
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Create an SDP offer
|
|
97
|
+
*/
|
|
98
|
+
async createOffer() {
|
|
99
|
+
if (this._signalingState === "closed") {
|
|
100
|
+
throw new Error("Cannot create offer on closed connection");
|
|
101
|
+
}
|
|
102
|
+
await this.simulateDelay();
|
|
103
|
+
this.offerCounter++;
|
|
104
|
+
const sdp = this.generateMockSDP("offer");
|
|
105
|
+
return {
|
|
106
|
+
type: "offer",
|
|
107
|
+
sdp,
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Create an SDP answer
|
|
112
|
+
*/
|
|
113
|
+
async createAnswer() {
|
|
114
|
+
if (this._signalingState !== "have-remote-offer") {
|
|
115
|
+
throw new Error(`Cannot create answer in signaling state: ${this._signalingState}`);
|
|
116
|
+
}
|
|
117
|
+
await this.simulateDelay();
|
|
118
|
+
const sdp = this.generateMockSDP("answer");
|
|
119
|
+
return {
|
|
120
|
+
type: "answer",
|
|
121
|
+
sdp,
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Set local description (offer or answer)
|
|
126
|
+
*/
|
|
127
|
+
async setLocalDescription(description) {
|
|
128
|
+
if (this._signalingState === "closed") {
|
|
129
|
+
throw new Error("Cannot set local description on closed connection");
|
|
130
|
+
}
|
|
131
|
+
await this.simulateDelay();
|
|
132
|
+
// If no description provided, create one automatically
|
|
133
|
+
if (!description) {
|
|
134
|
+
if (this._signalingState === "have-remote-offer") {
|
|
135
|
+
description = await this.createAnswer();
|
|
136
|
+
}
|
|
137
|
+
else {
|
|
138
|
+
description = await this.createOffer();
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
this._localDescription = description;
|
|
142
|
+
this._pendingLocalDescription = null;
|
|
143
|
+
// Update signaling state
|
|
144
|
+
if (description.type === "offer") {
|
|
145
|
+
this._signalingState = "have-local-offer";
|
|
146
|
+
}
|
|
147
|
+
else if (description.type === "answer") {
|
|
148
|
+
this._signalingState = "stable";
|
|
149
|
+
// Answerer also needs to start ICE connection
|
|
150
|
+
this.startIceConnection();
|
|
151
|
+
}
|
|
152
|
+
this.onsignalingstatechange?.();
|
|
153
|
+
// Start ICE gathering
|
|
154
|
+
if (this.config.autoGenerateIceCandidates) {
|
|
155
|
+
this.startIceGathering();
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Set remote description (offer or answer from peer)
|
|
160
|
+
*/
|
|
161
|
+
async setRemoteDescription(description) {
|
|
162
|
+
if (this._signalingState === "closed") {
|
|
163
|
+
throw new Error("Cannot set remote description on closed connection");
|
|
164
|
+
}
|
|
165
|
+
await this.simulateDelay();
|
|
166
|
+
this._remoteDescription = description;
|
|
167
|
+
this._pendingRemoteDescription = null;
|
|
168
|
+
// Update signaling state
|
|
169
|
+
if (description.type === "offer") {
|
|
170
|
+
this._signalingState = "have-remote-offer";
|
|
171
|
+
}
|
|
172
|
+
else if (description.type === "answer") {
|
|
173
|
+
this._signalingState = "stable";
|
|
174
|
+
// Start ICE connection after answer is set
|
|
175
|
+
this.startIceConnection();
|
|
176
|
+
}
|
|
177
|
+
this.onsignalingstatechange?.();
|
|
178
|
+
// Process any pending ICE candidates
|
|
179
|
+
for (const candidate of this._pendingRemoteCandidates) {
|
|
180
|
+
this._remoteCandidates.push(candidate);
|
|
181
|
+
}
|
|
182
|
+
this._pendingRemoteCandidates = [];
|
|
183
|
+
// If we received an offer, check for incoming data channels from linked peer
|
|
184
|
+
if (description.type === "offer" && this._linkedPeer) {
|
|
185
|
+
this.receiveDataChannelsFromPeer();
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Add ICE candidate from peer
|
|
190
|
+
*/
|
|
191
|
+
async addIceCandidate(candidate) {
|
|
192
|
+
if (this._signalingState === "closed") {
|
|
193
|
+
throw new Error("Cannot add ICE candidate on closed connection");
|
|
194
|
+
}
|
|
195
|
+
// Null candidate signals end of candidates
|
|
196
|
+
if (!candidate) {
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
// Queue candidates if remote description not set yet
|
|
200
|
+
if (!this._remoteDescription) {
|
|
201
|
+
this._pendingRemoteCandidates.push(candidate);
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
await this.simulateDelay();
|
|
205
|
+
this._remoteCandidates.push(candidate);
|
|
206
|
+
// Simulate ICE checking
|
|
207
|
+
if (this._iceConnectionState === "new") {
|
|
208
|
+
this._iceConnectionState = "checking";
|
|
209
|
+
this.oniceconnectionstatechange?.();
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Create a data channel
|
|
214
|
+
*/
|
|
215
|
+
createDataChannel(label, options) {
|
|
216
|
+
if (this._signalingState === "closed") {
|
|
217
|
+
throw new Error("Cannot create data channel on closed connection");
|
|
218
|
+
}
|
|
219
|
+
const channel = new MockRTCDataChannel_js_1.MockRTCDataChannel(label, options, this.config.dataChannelConfig);
|
|
220
|
+
this._dataChannels.set(label, channel);
|
|
221
|
+
// Trigger negotiation needed
|
|
222
|
+
setTimeout(() => {
|
|
223
|
+
this.onnegotiationneeded?.();
|
|
224
|
+
}, 0);
|
|
225
|
+
return channel;
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Close the peer connection
|
|
229
|
+
*/
|
|
230
|
+
close() {
|
|
231
|
+
if (this._signalingState === "closed") {
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
this._signalingState = "closed";
|
|
235
|
+
this._iceConnectionState = "closed";
|
|
236
|
+
this._connectionState = "closed";
|
|
237
|
+
// Close all data channels
|
|
238
|
+
for (const channel of this._dataChannels.values()) {
|
|
239
|
+
channel.close();
|
|
240
|
+
}
|
|
241
|
+
this._dataChannels.clear();
|
|
242
|
+
this.onsignalingstatechange?.();
|
|
243
|
+
this.oniceconnectionstatechange?.();
|
|
244
|
+
this.onconnectionstatechange?.();
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Get statistics (mock implementation)
|
|
248
|
+
*/
|
|
249
|
+
async getStats() {
|
|
250
|
+
return new Map([
|
|
251
|
+
[
|
|
252
|
+
"peer-connection",
|
|
253
|
+
{
|
|
254
|
+
type: "peer-connection",
|
|
255
|
+
timestamp: Date.now(),
|
|
256
|
+
dataChannelsOpened: this._dataChannels.size,
|
|
257
|
+
localCandidates: this._localCandidates.length,
|
|
258
|
+
remoteCandidates: this._remoteCandidates.length,
|
|
259
|
+
signalingState: this._signalingState,
|
|
260
|
+
iceConnectionState: this._iceConnectionState,
|
|
261
|
+
connectionState: this._connectionState,
|
|
262
|
+
},
|
|
263
|
+
],
|
|
264
|
+
]);
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* Restart ICE (mock implementation)
|
|
268
|
+
*/
|
|
269
|
+
restartIce() {
|
|
270
|
+
// Generate new ICE credentials
|
|
271
|
+
this.iceUfrag = "mock" + Math.random().toString(36).substring(2, 6);
|
|
272
|
+
this.icePwd = "mock" + Math.random().toString(36).substring(2, 26);
|
|
273
|
+
// Clear existing candidates
|
|
274
|
+
this._localCandidates = [];
|
|
275
|
+
this._remoteCandidates = [];
|
|
276
|
+
// Reset ICE states
|
|
277
|
+
this._iceGatheringState = "new";
|
|
278
|
+
this._iceConnectionState = "new";
|
|
279
|
+
this.onicegatheringstatechange?.();
|
|
280
|
+
this.oniceconnectionstatechange?.();
|
|
281
|
+
}
|
|
282
|
+
// Test helper methods
|
|
283
|
+
/**
|
|
284
|
+
* Get all data channels
|
|
285
|
+
*/
|
|
286
|
+
getDataChannels() {
|
|
287
|
+
return new Map(this._dataChannels);
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* Get local ICE candidates
|
|
291
|
+
*/
|
|
292
|
+
getLocalCandidates() {
|
|
293
|
+
return [...this._localCandidates];
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* Get remote ICE candidates
|
|
297
|
+
*/
|
|
298
|
+
getRemoteCandidates() {
|
|
299
|
+
return [...this._remoteCandidates];
|
|
300
|
+
}
|
|
301
|
+
/**
|
|
302
|
+
* Get the linked peer (for testing)
|
|
303
|
+
*/
|
|
304
|
+
getLinkedPeer() {
|
|
305
|
+
return this._linkedPeer;
|
|
306
|
+
}
|
|
307
|
+
/**
|
|
308
|
+
* Manually trigger connection established (for testing)
|
|
309
|
+
*/
|
|
310
|
+
_forceConnected() {
|
|
311
|
+
this._iceConnectionState = "connected";
|
|
312
|
+
this._connectionState = "connected";
|
|
313
|
+
this.oniceconnectionstatechange?.();
|
|
314
|
+
this.onconnectionstatechange?.();
|
|
315
|
+
// Open all data channels
|
|
316
|
+
for (const channel of this._dataChannels.values()) {
|
|
317
|
+
channel._open();
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
// Private methods
|
|
321
|
+
async simulateDelay() {
|
|
322
|
+
if (this.config.simulateLatency > 0) {
|
|
323
|
+
await new Promise((resolve) => setTimeout(resolve, this.config.simulateLatency));
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
generateMockSDP(type) {
|
|
327
|
+
const sessionId = Date.now();
|
|
328
|
+
const version = this.offerCounter;
|
|
329
|
+
// Generate SDP with data channel info
|
|
330
|
+
const lines = [
|
|
331
|
+
"v=0",
|
|
332
|
+
`o=- ${sessionId} ${version} IN IP4 127.0.0.1`,
|
|
333
|
+
"s=-",
|
|
334
|
+
"t=0 0",
|
|
335
|
+
"a=group:BUNDLE 0",
|
|
336
|
+
"a=extmap-allow-mixed",
|
|
337
|
+
"a=msid-semantic: WMS",
|
|
338
|
+
"m=application 9 UDP/DTLS/SCTP webrtc-datachannel",
|
|
339
|
+
"c=IN IP4 0.0.0.0",
|
|
340
|
+
`a=ice-ufrag:${this.iceUfrag}`,
|
|
341
|
+
`a=ice-pwd:${this.icePwd}`,
|
|
342
|
+
"a=ice-options:trickle",
|
|
343
|
+
"a=fingerprint:sha-256 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00",
|
|
344
|
+
type === "offer" ? "a=setup:actpass" : "a=setup:active",
|
|
345
|
+
"a=mid:0",
|
|
346
|
+
"a=sctp-port:5000",
|
|
347
|
+
"a=max-message-size:262144",
|
|
348
|
+
];
|
|
349
|
+
return lines.join("\r\n") + "\r\n";
|
|
350
|
+
}
|
|
351
|
+
startIceGathering() {
|
|
352
|
+
if (this._iceGatheringState !== "new") {
|
|
353
|
+
return;
|
|
354
|
+
}
|
|
355
|
+
this._iceGatheringState = "gathering";
|
|
356
|
+
this.onicegatheringstatechange?.();
|
|
357
|
+
// Simulate generating ICE candidates
|
|
358
|
+
const candidateDelay = this.config.iceGatheringTime / this.config.iceCandidateCount;
|
|
359
|
+
for (let i = 0; i < this.config.iceCandidateCount; i++) {
|
|
360
|
+
setTimeout(() => {
|
|
361
|
+
if (this._signalingState === "closed")
|
|
362
|
+
return;
|
|
363
|
+
// Simulate ICE failure
|
|
364
|
+
if (Math.random() < this.config.iceFailureProbability) {
|
|
365
|
+
this.onicecandidateerror?.({
|
|
366
|
+
errorCode: 701,
|
|
367
|
+
errorText: "Simulated ICE failure",
|
|
368
|
+
});
|
|
369
|
+
return;
|
|
370
|
+
}
|
|
371
|
+
const candidate = {
|
|
372
|
+
candidate: `candidate:${i} 1 udp ${2000000000 - i * 100} 192.168.1.${100 + i} ${50000 + i} typ host generation 0 ufrag ${this.iceUfrag}`,
|
|
373
|
+
sdpMid: "0",
|
|
374
|
+
sdpMLineIndex: 0,
|
|
375
|
+
usernameFragment: this.iceUfrag,
|
|
376
|
+
};
|
|
377
|
+
this._localCandidates.push(candidate);
|
|
378
|
+
this.onicecandidate?.({ candidate });
|
|
379
|
+
// Last candidate - signal gathering complete
|
|
380
|
+
if (i === this.config.iceCandidateCount - 1) {
|
|
381
|
+
setTimeout(() => {
|
|
382
|
+
if (this._signalingState === "closed")
|
|
383
|
+
return;
|
|
384
|
+
this._iceGatheringState = "complete";
|
|
385
|
+
this.onicegatheringstatechange?.();
|
|
386
|
+
this.onicecandidate?.({ candidate: null });
|
|
387
|
+
}, this.config.simulateLatency);
|
|
388
|
+
}
|
|
389
|
+
}, candidateDelay * i);
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
startIceConnection() {
|
|
393
|
+
// Simulate ICE connection establishment
|
|
394
|
+
this._iceConnectionState = "checking";
|
|
395
|
+
this._connectionState = "connecting";
|
|
396
|
+
this.oniceconnectionstatechange?.();
|
|
397
|
+
this.onconnectionstatechange?.();
|
|
398
|
+
setTimeout(() => {
|
|
399
|
+
if (this._signalingState === "closed")
|
|
400
|
+
return;
|
|
401
|
+
// Simulate connection success
|
|
402
|
+
this._iceConnectionState = "connected";
|
|
403
|
+
this._connectionState = "connected";
|
|
404
|
+
this.oniceconnectionstatechange?.();
|
|
405
|
+
this.onconnectionstatechange?.();
|
|
406
|
+
// Open data channels and link with peer
|
|
407
|
+
this.openDataChannels();
|
|
408
|
+
}, this.config.iceGatheringTime + this.config.simulateLatency);
|
|
409
|
+
}
|
|
410
|
+
openDataChannels() {
|
|
411
|
+
// Open local data channels
|
|
412
|
+
for (const channel of this._dataChannels.values()) {
|
|
413
|
+
channel._open();
|
|
414
|
+
}
|
|
415
|
+
// If linked, connect data channels
|
|
416
|
+
if (this._linkedPeer) {
|
|
417
|
+
for (const [label, localChannel] of this._dataChannels) {
|
|
418
|
+
const remoteChannel = this._linkedPeer._dataChannels.get(label);
|
|
419
|
+
if (remoteChannel) {
|
|
420
|
+
localChannel._linkChannel(remoteChannel);
|
|
421
|
+
remoteChannel._linkChannel(localChannel);
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
// Also open peer's data channels
|
|
425
|
+
for (const channel of this._linkedPeer._dataChannels.values()) {
|
|
426
|
+
if (channel.readyState === "connecting") {
|
|
427
|
+
channel._open();
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
receiveDataChannelsFromPeer() {
|
|
433
|
+
if (!this._linkedPeer)
|
|
434
|
+
return;
|
|
435
|
+
// Create matching data channels for any channels the peer has that we don't
|
|
436
|
+
for (const [label, peerChannel] of this._linkedPeer._dataChannels) {
|
|
437
|
+
if (!this._dataChannels.has(label)) {
|
|
438
|
+
const localChannel = new MockRTCDataChannel_js_1.MockRTCDataChannel(label, { ordered: peerChannel.ordered, id: peerChannel.id }, this.config.dataChannelConfig);
|
|
439
|
+
this._dataChannels.set(label, localChannel);
|
|
440
|
+
// Link the channels
|
|
441
|
+
localChannel._linkChannel(peerChannel);
|
|
442
|
+
peerChannel._linkChannel(localChannel);
|
|
443
|
+
// Notify via ondatachannel
|
|
444
|
+
this.ondatachannel?.({ channel: localChannel });
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
exports.MockRTCPeerConnection = MockRTCPeerConnection;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MockStorageAdapter.d.ts","sourceRoot":"","sources":["../../../src/adapters/mock/MockStorageAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"MockStorageAdapter.d.ts","sourceRoot":"","sources":["../../../src/adapters/mock/MockStorageAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,eAAe,EACf,gBAAgB,EAChB,MAAM,sCAAsC,CAAC;AAE9C,UAAU,WAAW;IACpB,KAAK,EAAE,OAAO,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,qBAAa,kBAAmB,YAAW,eAAe;IACzD,OAAO,CAAC,OAAO,CAAuC;IACtD,OAAO,CAAC,eAAe,CAAa;IACpC,OAAO,CAAC,oBAAoB,CAAkB;gBAElC,OAAO,CAAC,EAAE;QACrB,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,oBAAoB,CAAC,EAAE,OAAO,CAAC;KAC/B;IAKK,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC;IAmBtC,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAe1D,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAUlC,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAmBrC,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAiCxC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAUtB,WAAW,CAAC,CAAC,EAAE,UAAU,EAAE,gBAAgB,EAAE,GAAG,OAAO,CAAC,CAAC,CAAC;YA6DlD,aAAa;IAM3B,OAAO,IAAI,MAAM;IAIjB,aAAa,IAAI,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC;IAIzC,iBAAiB,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI;CAGtC"}
|
|
@@ -12,7 +12,7 @@ class MockStorageAdapter {
|
|
|
12
12
|
async get(key) {
|
|
13
13
|
await this.simulateDelay();
|
|
14
14
|
if (this.shouldFailOperations) {
|
|
15
|
-
throw new Error(
|
|
15
|
+
throw new Error("Mock storage operation failed");
|
|
16
16
|
}
|
|
17
17
|
const item = this.storage.get(key);
|
|
18
18
|
if (!item)
|
|
@@ -27,25 +27,25 @@ class MockStorageAdapter {
|
|
|
27
27
|
async set(key, value, ttl) {
|
|
28
28
|
await this.simulateDelay();
|
|
29
29
|
if (this.shouldFailOperations) {
|
|
30
|
-
throw new Error(
|
|
30
|
+
throw new Error("Mock storage operation failed");
|
|
31
31
|
}
|
|
32
32
|
const item = {
|
|
33
33
|
value,
|
|
34
|
-
expiresAt: ttl ? Date.now() + ttl : undefined
|
|
34
|
+
expiresAt: ttl ? Date.now() + ttl : undefined,
|
|
35
35
|
};
|
|
36
36
|
this.storage.set(key, item);
|
|
37
37
|
}
|
|
38
38
|
async delete(key) {
|
|
39
39
|
await this.simulateDelay();
|
|
40
40
|
if (this.shouldFailOperations) {
|
|
41
|
-
throw new Error(
|
|
41
|
+
throw new Error("Mock storage operation failed");
|
|
42
42
|
}
|
|
43
43
|
this.storage.delete(key);
|
|
44
44
|
}
|
|
45
45
|
async exists(key) {
|
|
46
46
|
await this.simulateDelay();
|
|
47
47
|
if (this.shouldFailOperations) {
|
|
48
|
-
throw new Error(
|
|
48
|
+
throw new Error("Mock storage operation failed");
|
|
49
49
|
}
|
|
50
50
|
const item = this.storage.get(key);
|
|
51
51
|
if (!item)
|
|
@@ -60,15 +60,15 @@ class MockStorageAdapter {
|
|
|
60
60
|
async scan(pattern) {
|
|
61
61
|
await this.simulateDelay();
|
|
62
62
|
if (this.shouldFailOperations) {
|
|
63
|
-
throw new Error(
|
|
63
|
+
throw new Error("Mock storage operation failed");
|
|
64
64
|
}
|
|
65
65
|
// Convert pattern to regex (simple glob to regex conversion)
|
|
66
66
|
const regexPattern = pattern
|
|
67
|
-
.replace(/\*/g,
|
|
68
|
-
.replace(/\?/g,
|
|
69
|
-
.replace(/\[!/g,
|
|
70
|
-
.replace(/\[/g,
|
|
71
|
-
.replace(/\]/g,
|
|
67
|
+
.replace(/\*/g, ".*")
|
|
68
|
+
.replace(/\?/g, ".")
|
|
69
|
+
.replace(/\[!/g, "[^")
|
|
70
|
+
.replace(/\[/g, "[")
|
|
71
|
+
.replace(/\]/g, "]");
|
|
72
72
|
const regex = new RegExp(`^${regexPattern}$`);
|
|
73
73
|
const keys = [];
|
|
74
74
|
for (const [key, item] of this.storage.entries()) {
|
|
@@ -86,26 +86,26 @@ class MockStorageAdapter {
|
|
|
86
86
|
async clear() {
|
|
87
87
|
await this.simulateDelay();
|
|
88
88
|
if (this.shouldFailOperations) {
|
|
89
|
-
throw new Error(
|
|
89
|
+
throw new Error("Mock storage operation failed");
|
|
90
90
|
}
|
|
91
91
|
this.storage.clear();
|
|
92
92
|
}
|
|
93
93
|
async transaction(operations) {
|
|
94
94
|
await this.simulateDelay();
|
|
95
95
|
if (this.shouldFailOperations) {
|
|
96
|
-
throw new Error(
|
|
96
|
+
throw new Error("Mock storage operation failed");
|
|
97
97
|
}
|
|
98
98
|
const results = [];
|
|
99
99
|
const rollback = [];
|
|
100
100
|
try {
|
|
101
101
|
for (const op of operations) {
|
|
102
102
|
switch (op.type) {
|
|
103
|
-
case
|
|
103
|
+
case "get": {
|
|
104
104
|
const value = await this.get(op.key);
|
|
105
105
|
results.push(value);
|
|
106
106
|
break;
|
|
107
107
|
}
|
|
108
|
-
case
|
|
108
|
+
case "set": {
|
|
109
109
|
const oldValue = await this.get(op.key);
|
|
110
110
|
await this.set(op.key, op.value, op.ttl);
|
|
111
111
|
rollback.push(() => {
|
|
@@ -119,7 +119,7 @@ class MockStorageAdapter {
|
|
|
119
119
|
results.push(true);
|
|
120
120
|
break;
|
|
121
121
|
}
|
|
122
|
-
case
|
|
122
|
+
case "delete": {
|
|
123
123
|
const oldValue = await this.get(op.key);
|
|
124
124
|
await this.delete(op.key);
|
|
125
125
|
rollback.push(() => {
|
|
@@ -130,7 +130,7 @@ class MockStorageAdapter {
|
|
|
130
130
|
results.push(true);
|
|
131
131
|
break;
|
|
132
132
|
}
|
|
133
|
-
case
|
|
133
|
+
case "exists": {
|
|
134
134
|
const exists = await this.exists(op.key);
|
|
135
135
|
results.push(exists);
|
|
136
136
|
break;
|
|
@@ -150,7 +150,7 @@ class MockStorageAdapter {
|
|
|
150
150
|
// Test helper methods
|
|
151
151
|
async simulateDelay() {
|
|
152
152
|
if (this.simulateLatency > 0) {
|
|
153
|
-
await new Promise(resolve => setTimeout(resolve, this.simulateLatency));
|
|
153
|
+
await new Promise((resolve) => setTimeout(resolve, this.simulateLatency));
|
|
154
154
|
}
|
|
155
155
|
}
|
|
156
156
|
getSize() {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { ITransportAdapter } from
|
|
2
|
-
import type {
|
|
1
|
+
import type { ITransportAdapter } from "../../abstractions/TransportAdapter.js";
|
|
2
|
+
import type { CloseHandler, ConnectionOptions, ConnectionState, ErrorHandler, Message, MessageHandler } from "../../types/index.js";
|
|
3
3
|
export declare class MockTransportAdapter implements ITransportAdapter {
|
|
4
4
|
private state;
|
|
5
5
|
private messageHandlers;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MockTransportAdapter.d.ts","sourceRoot":"","sources":["../../../src/adapters/mock/MockTransportAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wCAAwC,CAAC;AAChF,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"MockTransportAdapter.d.ts","sourceRoot":"","sources":["../../../src/adapters/mock/MockTransportAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wCAAwC,CAAC;AAChF,OAAO,KAAK,EACX,YAAY,EACZ,iBAAiB,EACjB,eAAe,EACf,YAAY,EACZ,OAAO,EACP,cAAc,EACd,MAAM,sBAAsB,CAAC;AAE9B,qBAAa,oBAAqB,YAAW,iBAAiB;IAC7D,OAAO,CAAC,KAAK,CAAmC;IAChD,OAAO,CAAC,eAAe,CAAkC;IACzD,OAAO,CAAC,aAAa,CAAgC;IACrD,OAAO,CAAC,aAAa,CAAgC;IACrD,OAAO,CAAC,YAAY,CAAiB;IACrC,OAAO,CAAC,eAAe,CAAa;IACpC,OAAO,CAAC,oBAAoB,CAAkB;IAC9C,OAAO,CAAC,YAAY,CAAuB;IAC3C,OAAO,CAAC,kBAAkB,CAAa;gBAE3B,OAAO,CAAC,EAAE;QACrB,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,oBAAoB,CAAC,EAAE,OAAO,CAAC;KAC/B;IAKK,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAqBjE,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAkB3B,IAAI,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAa3C,SAAS,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI;IAIxC,OAAO,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI;IAIpC,OAAO,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI;IAIpC,QAAQ,IAAI,eAAe;IAI3B,WAAW,IAAI,OAAO;IAKtB,eAAe,CACd,OAAO,EAAE,OAAO,EAChB,qBAAqB,GAAE,OAAe,GACpC,IAAI;IAOP,aAAa,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;IAIjC,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAKjD,eAAe,IAAI,OAAO,EAAE;IAI5B,iBAAiB,IAAI,IAAI;IAIzB,eAAe,IAAI,MAAM,GAAG,IAAI;IAIhC,qBAAqB,IAAI,MAAM;IAI/B,uBAAuB,IAAI,IAAI;IAK/B;;;OAGG;IACG,kBAAkB,CACvB,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE;QACR,aAAa,CAAC,EAAE,OAAO,CAAC;QACxB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KAC9B,GACJ,OAAO,CAAC,IAAI,CAAC;IAsBhB;;OAEG;IACG,kBAAkB,CACvB,QAAQ,EAAE,MAAM,EAChB,MAAM,GAAE,MAAyB,GAC/B,OAAO,CAAC,IAAI,CAAC;IAehB;;;;;;;OAOG;IACG,qBAAqB,CAC1B,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,EACnB,cAAc,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GAC1C,OAAO,CAAC,IAAI,CAAC;IAehB;;;OAGG;IACH,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,GAAG,EAAE;IAYxC;;;;OAIG;IACH,uBAAuB,CAAC,OAAO,EAAE,GAAG,GAAG,IAAI;CAW3C"}
|