@phystack/hub-client 4.5.19-dev → 4.5.21-dev
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/index.d.ts +22 -28
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +252 -378
- package/dist/index.js.map +1 -1
- package/dist/peripheral-twin.d.ts +34 -0
- package/dist/peripheral-twin.d.ts.map +1 -0
- package/dist/peripheral-twin.js +234 -0
- package/dist/peripheral-twin.js.map +1 -0
- package/dist/services/phyhub-connection.service.d.ts +1 -0
- package/dist/services/phyhub-connection.service.d.ts.map +1 -1
- package/dist/services/phyhub-connection.service.js +17 -0
- package/dist/services/phyhub-connection.service.js.map +1 -1
- package/dist/services/phyhub-direct-connection.service.d.ts +21 -0
- package/dist/services/phyhub-direct-connection.service.d.ts.map +1 -0
- package/dist/services/phyhub-direct-connection.service.js +101 -0
- package/dist/services/phyhub-direct-connection.service.js.map +1 -0
- package/dist/services/webrtc/data-channel-handler.d.ts +45 -0
- package/dist/services/webrtc/data-channel-handler.d.ts.map +1 -0
- package/dist/services/webrtc/data-channel-handler.js +260 -0
- package/dist/services/webrtc/data-channel-handler.js.map +1 -0
- package/dist/services/webrtc/index.d.ts +8 -0
- package/dist/services/webrtc/index.d.ts.map +1 -0
- package/dist/services/webrtc/index.js +18 -0
- package/dist/services/webrtc/index.js.map +1 -0
- package/dist/services/webrtc/media-stream-handler.d.ts +57 -0
- package/dist/services/webrtc/media-stream-handler.d.ts.map +1 -0
- package/dist/services/webrtc/media-stream-handler.js +383 -0
- package/dist/services/webrtc/media-stream-handler.js.map +1 -0
- package/dist/services/webrtc/peer-connection-manager.d.ts +40 -0
- package/dist/services/webrtc/peer-connection-manager.d.ts.map +1 -0
- package/dist/services/webrtc/peer-connection-manager.js +336 -0
- package/dist/services/webrtc/peer-connection-manager.js.map +1 -0
- package/dist/services/webrtc/types.d.ts +134 -0
- package/dist/services/webrtc/types.d.ts.map +1 -0
- package/dist/services/webrtc/types.js +12 -0
- package/dist/services/webrtc/types.js.map +1 -0
- package/dist/services/webrtc/webrtc-globals.d.ts +4 -0
- package/dist/services/webrtc/webrtc-globals.d.ts.map +1 -0
- package/dist/services/webrtc/webrtc-globals.js +72 -0
- package/dist/services/webrtc/webrtc-globals.js.map +1 -0
- package/dist/services/webrtc/webrtc-manager.d.ts +35 -0
- package/dist/services/webrtc/webrtc-manager.d.ts.map +1 -0
- package/dist/services/webrtc/webrtc-manager.js +274 -0
- package/dist/services/webrtc/webrtc-manager.js.map +1 -0
- package/dist/test/communication-comprehensive-test.d.ts +8 -0
- package/dist/test/communication-comprehensive-test.d.ts.map +1 -0
- package/dist/test/communication-comprehensive-test.js +356 -0
- package/dist/test/communication-comprehensive-test.js.map +1 -0
- package/dist/test/webrtc-channel-names-test.d.ts +2 -0
- package/dist/test/webrtc-channel-names-test.d.ts.map +1 -0
- package/dist/test/webrtc-channel-names-test.js +177 -0
- package/dist/test/webrtc-channel-names-test.js.map +1 -0
- package/dist/test/webrtc-comprehensive-test.d.ts +2 -0
- package/dist/test/webrtc-comprehensive-test.d.ts.map +1 -0
- package/dist/test/webrtc-comprehensive-test.js +328 -0
- package/dist/test/webrtc-comprehensive-test.js.map +1 -0
- package/dist/test/webrtc-reconnect-test.d.ts +4 -0
- package/dist/test/webrtc-reconnect-test.d.ts.map +1 -0
- package/dist/test/webrtc-reconnect-test.js +244 -0
- package/dist/test/webrtc-reconnect-test.js.map +1 -0
- package/dist/test/webrtc-test-harness.d.ts +4 -0
- package/dist/test/webrtc-test-harness.d.ts.map +1 -0
- package/dist/test/webrtc-test-harness.js +169 -0
- package/dist/test/webrtc-test-harness.js.map +1 -0
- package/dist/twin-messaging.d.ts +20 -0
- package/dist/twin-messaging.d.ts.map +1 -0
- package/dist/twin-messaging.js +94 -0
- package/dist/twin-messaging.js.map +1 -0
- package/dist/twin-registry.d.ts +9 -0
- package/dist/twin-registry.d.ts.map +1 -0
- package/dist/twin-registry.js +26 -0
- package/dist/twin-registry.js.map +1 -0
- package/dist/types/index.d.ts +4 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +20 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/twin.types.d.ts +62 -14
- package/dist/types/twin.types.d.ts.map +1 -1
- package/dist/types/twin.types.js +8 -1
- package/dist/types/twin.types.js.map +1 -1
- package/docs/webrtc-howto.md +398 -0
- package/docs/webrtc-test.md +330 -0
- package/package.json +3 -3
- package/scripts/webrtc-test.sh +401 -0
- package/src/index.ts +378 -568
- package/src/peripheral-twin.ts +337 -0
- package/src/services/phyhub-connection.service.ts +24 -0
- package/src/services/phyhub-direct-connection.service.ts +159 -0
- package/src/services/webrtc/data-channel-handler.ts +362 -0
- package/src/services/webrtc/index.ts +36 -0
- package/src/services/webrtc/media-stream-handler.ts +536 -0
- package/src/services/webrtc/peer-connection-manager.ts +467 -0
- package/src/services/webrtc/types.ts +273 -0
- package/src/services/webrtc/webrtc-globals.ts +108 -0
- package/src/services/webrtc/webrtc-manager.ts +490 -0
- package/src/test/communication-comprehensive-test.ts +533 -0
- package/src/test/webrtc-channel-names-test.ts +266 -0
- package/src/test/webrtc-comprehensive-test.ts +494 -0
- package/src/test/webrtc-reconnect-test.ts +345 -0
- package/src/test/webrtc-test-harness.ts +254 -0
- package/src/twin-messaging.ts +184 -0
- package/src/twin-registry.ts +39 -0
- package/src/types/index.ts +3 -0
- package/src/types/twin.types.ts +80 -14
- package/dist/services/webrtc/datachannel.d.ts +0 -10
- package/dist/services/webrtc/datachannel.d.ts.map +0 -1
- package/dist/services/webrtc/datachannel.js +0 -290
- package/dist/services/webrtc/datachannel.js.map +0 -1
- package/dist/services/webrtc/mediastream.d.ts +0 -10
- package/dist/services/webrtc/mediastream.d.ts.map +0 -1
- package/dist/services/webrtc/mediastream.js +0 -396
- package/dist/services/webrtc/mediastream.js.map +0 -1
- package/dist/services/webrtc/peer-connection-ice.d.ts +0 -32
- package/dist/services/webrtc/peer-connection-ice.d.ts.map +0 -1
- package/dist/services/webrtc/peer-connection-ice.js +0 -483
- package/dist/services/webrtc/peer-connection-ice.js.map +0 -1
- package/src/services/webrtc/datachannel.ts +0 -421
- package/src/services/webrtc/mediastream.ts +0 -602
- package/src/services/webrtc/peer-connection-ice.ts +0 -689
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WebRTC Named Channels Test
|
|
3
|
+
*
|
|
4
|
+
* Tests multiple DataChannels with different names to the same peer.
|
|
5
|
+
*
|
|
6
|
+
* Usage (two terminals):
|
|
7
|
+
*
|
|
8
|
+
* Terminal 1 (initiator):
|
|
9
|
+
* ```
|
|
10
|
+
* PHYHUB_DIRECT=true \
|
|
11
|
+
* DEVICE_ID=<device-a-id> \
|
|
12
|
+
* ACCESS_KEY=<device-a-key> \
|
|
13
|
+
* PEER_TWIN_ID=<device-b-twin-id> \
|
|
14
|
+
* ROLE=initiator \
|
|
15
|
+
* npx ts-node src/test/webrtc-channel-names-test.ts
|
|
16
|
+
* ```
|
|
17
|
+
*
|
|
18
|
+
* Terminal 2 (responder):
|
|
19
|
+
* ```
|
|
20
|
+
* PHYHUB_DIRECT=true \
|
|
21
|
+
* DEVICE_ID=<device-b-id> \
|
|
22
|
+
* ACCESS_KEY=<device-b-key> \
|
|
23
|
+
* PEER_TWIN_ID=<device-a-twin-id> \
|
|
24
|
+
* ROLE=responder \
|
|
25
|
+
* npx ts-node src/test/webrtc-channel-names-test.ts
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
import { PhyHubClient } from '../index';
|
|
30
|
+
import { PhygridDataChannel } from '../services/webrtc/types';
|
|
31
|
+
|
|
32
|
+
interface TestResult {
|
|
33
|
+
channel: string;
|
|
34
|
+
sent: number;
|
|
35
|
+
received: number;
|
|
36
|
+
passed: boolean;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const CHANNEL_NAMES = [undefined, 'control', 'data', 'telemetry'] as const;
|
|
40
|
+
const MESSAGES_PER_CHANNEL = 3;
|
|
41
|
+
|
|
42
|
+
async function runInitiator(peerTwinId: string): Promise<void> {
|
|
43
|
+
console.log('\n=== Running as INITIATOR ===\n');
|
|
44
|
+
|
|
45
|
+
const client = await PhyHubClient.connect();
|
|
46
|
+
console.log('Connected to PhyHub!\n');
|
|
47
|
+
|
|
48
|
+
const results: TestResult[] = [];
|
|
49
|
+
const channels: Map<string, PhygridDataChannel> = new Map();
|
|
50
|
+
const receivedCounts: Map<string, number> = new Map();
|
|
51
|
+
|
|
52
|
+
// Test each channel name
|
|
53
|
+
for (const channelName of CHANNEL_NAMES) {
|
|
54
|
+
const displayName = channelName ?? 'default';
|
|
55
|
+
console.log(`\n--- Creating channel: "${displayName}" ---`);
|
|
56
|
+
|
|
57
|
+
try {
|
|
58
|
+
const channel = await client.getDataChannel(peerTwinId, channelName);
|
|
59
|
+
console.log(`Channel "${displayName}" created. Label: ${channel.getChannelName()}`);
|
|
60
|
+
|
|
61
|
+
// Verify channel name
|
|
62
|
+
const expectedName = channelName ?? 'default';
|
|
63
|
+
if (channel.getChannelName() !== expectedName) {
|
|
64
|
+
console.error(`ERROR: Expected channel name "${expectedName}", got "${channel.getChannelName()}"`);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
channels.set(displayName, channel);
|
|
68
|
+
receivedCounts.set(displayName, 0);
|
|
69
|
+
|
|
70
|
+
// Setup message handler
|
|
71
|
+
channel.onMessage((data) => {
|
|
72
|
+
console.log(`[${displayName}] RECEIVED:`, data);
|
|
73
|
+
receivedCounts.set(displayName, (receivedCounts.get(displayName) || 0) + 1);
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
} catch (error) {
|
|
77
|
+
console.error(`Failed to create channel "${displayName}":`, error);
|
|
78
|
+
results.push({ channel: displayName, sent: 0, received: 0, passed: false });
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Wait for responder to set up channels
|
|
83
|
+
console.log('\nWaiting 3 seconds for responder to set up...');
|
|
84
|
+
await sleep(3000);
|
|
85
|
+
|
|
86
|
+
// Send messages on each channel
|
|
87
|
+
console.log('\n--- Sending messages ---\n');
|
|
88
|
+
|
|
89
|
+
for (const [displayName, channel] of channels) {
|
|
90
|
+
if (!channel.isOpen()) {
|
|
91
|
+
console.log(`Channel "${displayName}" not open, skipping...`);
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
for (let i = 1; i <= MESSAGES_PER_CHANNEL; i++) {
|
|
96
|
+
const msg = {
|
|
97
|
+
channel: displayName,
|
|
98
|
+
messageNum: i,
|
|
99
|
+
from: 'initiator',
|
|
100
|
+
timestamp: Date.now(),
|
|
101
|
+
};
|
|
102
|
+
console.log(`[${displayName}] SENDING:`, msg);
|
|
103
|
+
channel.send(msg);
|
|
104
|
+
await sleep(200);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// Wait for responses
|
|
109
|
+
console.log('\nWaiting 5 seconds for responses...');
|
|
110
|
+
await sleep(5000);
|
|
111
|
+
|
|
112
|
+
// Compile results
|
|
113
|
+
console.log('\n--- Test Results ---\n');
|
|
114
|
+
|
|
115
|
+
for (const [displayName] of channels) {
|
|
116
|
+
const received = receivedCounts.get(displayName) || 0;
|
|
117
|
+
const passed = received >= MESSAGES_PER_CHANNEL;
|
|
118
|
+
results.push({
|
|
119
|
+
channel: displayName,
|
|
120
|
+
sent: MESSAGES_PER_CHANNEL,
|
|
121
|
+
received,
|
|
122
|
+
passed,
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// Print results
|
|
127
|
+
console.log('Channel'.padEnd(15) + 'Sent'.padEnd(8) + 'Received'.padEnd(10) + 'Status');
|
|
128
|
+
console.log('-'.repeat(45));
|
|
129
|
+
|
|
130
|
+
for (const result of results) {
|
|
131
|
+
const status = result.passed ? '✅ PASS' : '❌ FAIL';
|
|
132
|
+
console.log(
|
|
133
|
+
result.channel.padEnd(15) +
|
|
134
|
+
result.sent.toString().padEnd(8) +
|
|
135
|
+
result.received.toString().padEnd(10) +
|
|
136
|
+
status
|
|
137
|
+
);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// Summary
|
|
141
|
+
const allPassed = results.every((r) => r.passed);
|
|
142
|
+
console.log('\n' + '='.repeat(45));
|
|
143
|
+
console.log(allPassed ? '✅ ALL TESTS PASSED' : '❌ SOME TESTS FAILED');
|
|
144
|
+
|
|
145
|
+
// Close all channels
|
|
146
|
+
for (const channel of channels.values()) {
|
|
147
|
+
channel.close();
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
async function runResponder(peerTwinId: string): Promise<void> {
|
|
152
|
+
console.log('\n=== Running as RESPONDER ===\n');
|
|
153
|
+
|
|
154
|
+
const client = await PhyHubClient.connect();
|
|
155
|
+
console.log('Connected to PhyHub!\n');
|
|
156
|
+
|
|
157
|
+
const channels: Map<string, PhygridDataChannel> = new Map();
|
|
158
|
+
const receivedCounts: Map<string, number> = new Map();
|
|
159
|
+
let channelsReceived = 0;
|
|
160
|
+
|
|
161
|
+
return new Promise((resolve, reject) => {
|
|
162
|
+
const timeout = setTimeout(() => {
|
|
163
|
+
reject(new Error('Timeout waiting for channels (60s)'));
|
|
164
|
+
}, 60000);
|
|
165
|
+
|
|
166
|
+
// Accept each channel name
|
|
167
|
+
for (const channelName of CHANNEL_NAMES) {
|
|
168
|
+
const displayName = channelName ?? 'default';
|
|
169
|
+
console.log(`Waiting for channel: "${displayName}"`);
|
|
170
|
+
|
|
171
|
+
client.onDataChannel(peerTwinId, (channel: PhygridDataChannel) => {
|
|
172
|
+
console.log(`\n[${displayName}] Channel received! Label: ${channel.getChannelName()}`);
|
|
173
|
+
channels.set(displayName, channel);
|
|
174
|
+
receivedCounts.set(displayName, 0);
|
|
175
|
+
channelsReceived++;
|
|
176
|
+
|
|
177
|
+
channel.onMessage((data) => {
|
|
178
|
+
console.log(`[${displayName}] RECEIVED:`, data);
|
|
179
|
+
receivedCounts.set(displayName, (receivedCounts.get(displayName) || 0) + 1);
|
|
180
|
+
|
|
181
|
+
// Echo back
|
|
182
|
+
const response = {
|
|
183
|
+
channel: displayName,
|
|
184
|
+
type: 'echo',
|
|
185
|
+
originalMessage: data.messageNum,
|
|
186
|
+
from: 'responder',
|
|
187
|
+
timestamp: Date.now(),
|
|
188
|
+
};
|
|
189
|
+
console.log(`[${displayName}] SENDING:`, response);
|
|
190
|
+
channel.send(response);
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
channel.onClose(() => {
|
|
194
|
+
console.log(`[${displayName}] Channel closed`);
|
|
195
|
+
|
|
196
|
+
// Check if all channels closed
|
|
197
|
+
const openChannels = Array.from(channels.values()).filter((c) => c.isOpen());
|
|
198
|
+
if (openChannels.length === 0 && channelsReceived === CHANNEL_NAMES.length) {
|
|
199
|
+
clearTimeout(timeout);
|
|
200
|
+
|
|
201
|
+
// Print summary
|
|
202
|
+
console.log('\n--- Responder Summary ---\n');
|
|
203
|
+
console.log('Channel'.padEnd(15) + 'Messages Received');
|
|
204
|
+
console.log('-'.repeat(35));
|
|
205
|
+
|
|
206
|
+
for (const [name, count] of receivedCounts) {
|
|
207
|
+
console.log(name.padEnd(15) + count.toString());
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
resolve();
|
|
211
|
+
}
|
|
212
|
+
});
|
|
213
|
+
}, channelName);
|
|
214
|
+
}
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
function sleep(ms: number): Promise<void> {
|
|
219
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
async function main(): Promise<void> {
|
|
223
|
+
console.log('='.repeat(60));
|
|
224
|
+
console.log('WebRTC Named Channels Test');
|
|
225
|
+
console.log('='.repeat(60));
|
|
226
|
+
|
|
227
|
+
if (process.env.PHYHUB_DIRECT !== 'true') {
|
|
228
|
+
console.error('ERROR: Set PHYHUB_DIRECT=true');
|
|
229
|
+
process.exit(1);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
const peerTwinId = process.env.PEER_TWIN_ID;
|
|
233
|
+
const role = process.env.ROLE?.toLowerCase();
|
|
234
|
+
|
|
235
|
+
if (!peerTwinId) {
|
|
236
|
+
console.error('ERROR: Set PEER_TWIN_ID');
|
|
237
|
+
process.exit(1);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
if (role !== 'initiator' && role !== 'responder') {
|
|
241
|
+
console.error('ERROR: Set ROLE to initiator or responder');
|
|
242
|
+
process.exit(1);
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
console.log(`\nRole: ${role}`);
|
|
246
|
+
console.log(`Peer Twin ID: ${peerTwinId}`);
|
|
247
|
+
console.log(`Channels to test: ${CHANNEL_NAMES.map((n) => n ?? 'default').join(', ')}`);
|
|
248
|
+
|
|
249
|
+
try {
|
|
250
|
+
if (role === 'initiator') {
|
|
251
|
+
await runInitiator(peerTwinId);
|
|
252
|
+
} else {
|
|
253
|
+
await runResponder(peerTwinId);
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
console.log('\n[SUCCESS] Test completed!');
|
|
257
|
+
process.exit(0);
|
|
258
|
+
} catch (error) {
|
|
259
|
+
console.error('\n[FAILED]', error);
|
|
260
|
+
process.exit(1);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
if (require.main === module) {
|
|
265
|
+
main();
|
|
266
|
+
}
|