@phystack/hub-client 4.5.19-dev → 4.5.20-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.
Files changed (119) hide show
  1. package/dist/index.d.ts +22 -28
  2. package/dist/index.d.ts.map +1 -1
  3. package/dist/index.js +252 -378
  4. package/dist/index.js.map +1 -1
  5. package/dist/peripheral-twin.d.ts +34 -0
  6. package/dist/peripheral-twin.d.ts.map +1 -0
  7. package/dist/peripheral-twin.js +234 -0
  8. package/dist/peripheral-twin.js.map +1 -0
  9. package/dist/services/phyhub-connection.service.d.ts +1 -0
  10. package/dist/services/phyhub-connection.service.d.ts.map +1 -1
  11. package/dist/services/phyhub-connection.service.js +17 -0
  12. package/dist/services/phyhub-connection.service.js.map +1 -1
  13. package/dist/services/phyhub-direct-connection.service.d.ts +21 -0
  14. package/dist/services/phyhub-direct-connection.service.d.ts.map +1 -0
  15. package/dist/services/phyhub-direct-connection.service.js +101 -0
  16. package/dist/services/phyhub-direct-connection.service.js.map +1 -0
  17. package/dist/services/webrtc/data-channel-handler.d.ts +45 -0
  18. package/dist/services/webrtc/data-channel-handler.d.ts.map +1 -0
  19. package/dist/services/webrtc/data-channel-handler.js +260 -0
  20. package/dist/services/webrtc/data-channel-handler.js.map +1 -0
  21. package/dist/services/webrtc/index.d.ts +8 -0
  22. package/dist/services/webrtc/index.d.ts.map +1 -0
  23. package/dist/services/webrtc/index.js +18 -0
  24. package/dist/services/webrtc/index.js.map +1 -0
  25. package/dist/services/webrtc/media-stream-handler.d.ts +57 -0
  26. package/dist/services/webrtc/media-stream-handler.d.ts.map +1 -0
  27. package/dist/services/webrtc/media-stream-handler.js +383 -0
  28. package/dist/services/webrtc/media-stream-handler.js.map +1 -0
  29. package/dist/services/webrtc/peer-connection-manager.d.ts +40 -0
  30. package/dist/services/webrtc/peer-connection-manager.d.ts.map +1 -0
  31. package/dist/services/webrtc/peer-connection-manager.js +336 -0
  32. package/dist/services/webrtc/peer-connection-manager.js.map +1 -0
  33. package/dist/services/webrtc/types.d.ts +134 -0
  34. package/dist/services/webrtc/types.d.ts.map +1 -0
  35. package/dist/services/webrtc/types.js +12 -0
  36. package/dist/services/webrtc/types.js.map +1 -0
  37. package/dist/services/webrtc/webrtc-globals.d.ts +4 -0
  38. package/dist/services/webrtc/webrtc-globals.d.ts.map +1 -0
  39. package/dist/services/webrtc/webrtc-globals.js +72 -0
  40. package/dist/services/webrtc/webrtc-globals.js.map +1 -0
  41. package/dist/services/webrtc/webrtc-manager.d.ts +35 -0
  42. package/dist/services/webrtc/webrtc-manager.d.ts.map +1 -0
  43. package/dist/services/webrtc/webrtc-manager.js +274 -0
  44. package/dist/services/webrtc/webrtc-manager.js.map +1 -0
  45. package/dist/test/communication-comprehensive-test.d.ts +8 -0
  46. package/dist/test/communication-comprehensive-test.d.ts.map +1 -0
  47. package/dist/test/communication-comprehensive-test.js +356 -0
  48. package/dist/test/communication-comprehensive-test.js.map +1 -0
  49. package/dist/test/webrtc-channel-names-test.d.ts +2 -0
  50. package/dist/test/webrtc-channel-names-test.d.ts.map +1 -0
  51. package/dist/test/webrtc-channel-names-test.js +177 -0
  52. package/dist/test/webrtc-channel-names-test.js.map +1 -0
  53. package/dist/test/webrtc-comprehensive-test.d.ts +2 -0
  54. package/dist/test/webrtc-comprehensive-test.d.ts.map +1 -0
  55. package/dist/test/webrtc-comprehensive-test.js +328 -0
  56. package/dist/test/webrtc-comprehensive-test.js.map +1 -0
  57. package/dist/test/webrtc-reconnect-test.d.ts +4 -0
  58. package/dist/test/webrtc-reconnect-test.d.ts.map +1 -0
  59. package/dist/test/webrtc-reconnect-test.js +244 -0
  60. package/dist/test/webrtc-reconnect-test.js.map +1 -0
  61. package/dist/test/webrtc-test-harness.d.ts +4 -0
  62. package/dist/test/webrtc-test-harness.d.ts.map +1 -0
  63. package/dist/test/webrtc-test-harness.js +169 -0
  64. package/dist/test/webrtc-test-harness.js.map +1 -0
  65. package/dist/twin-messaging.d.ts +20 -0
  66. package/dist/twin-messaging.d.ts.map +1 -0
  67. package/dist/twin-messaging.js +94 -0
  68. package/dist/twin-messaging.js.map +1 -0
  69. package/dist/twin-registry.d.ts +9 -0
  70. package/dist/twin-registry.d.ts.map +1 -0
  71. package/dist/twin-registry.js +26 -0
  72. package/dist/twin-registry.js.map +1 -0
  73. package/dist/types/index.d.ts +4 -0
  74. package/dist/types/index.d.ts.map +1 -0
  75. package/dist/types/index.js +20 -0
  76. package/dist/types/index.js.map +1 -0
  77. package/dist/types/twin.types.d.ts +62 -14
  78. package/dist/types/twin.types.d.ts.map +1 -1
  79. package/dist/types/twin.types.js +8 -1
  80. package/dist/types/twin.types.js.map +1 -1
  81. package/docs/webrtc-howto.md +398 -0
  82. package/docs/webrtc-test.md +330 -0
  83. package/package.json +3 -3
  84. package/scripts/webrtc-test.sh +401 -0
  85. package/src/index.ts +378 -568
  86. package/src/peripheral-twin.ts +337 -0
  87. package/src/services/phyhub-connection.service.ts +24 -0
  88. package/src/services/phyhub-direct-connection.service.ts +159 -0
  89. package/src/services/webrtc/data-channel-handler.ts +362 -0
  90. package/src/services/webrtc/index.ts +36 -0
  91. package/src/services/webrtc/media-stream-handler.ts +536 -0
  92. package/src/services/webrtc/peer-connection-manager.ts +467 -0
  93. package/src/services/webrtc/types.ts +273 -0
  94. package/src/services/webrtc/webrtc-globals.ts +108 -0
  95. package/src/services/webrtc/webrtc-manager.ts +490 -0
  96. package/src/test/communication-comprehensive-test.ts +533 -0
  97. package/src/test/webrtc-channel-names-test.ts +266 -0
  98. package/src/test/webrtc-comprehensive-test.ts +494 -0
  99. package/src/test/webrtc-reconnect-test.ts +345 -0
  100. package/src/test/webrtc-test-harness.ts +254 -0
  101. package/src/twin-messaging.ts +184 -0
  102. package/src/twin-registry.ts +39 -0
  103. package/src/types/index.ts +3 -0
  104. package/src/types/twin.types.ts +80 -14
  105. package/dist/services/webrtc/datachannel.d.ts +0 -10
  106. package/dist/services/webrtc/datachannel.d.ts.map +0 -1
  107. package/dist/services/webrtc/datachannel.js +0 -290
  108. package/dist/services/webrtc/datachannel.js.map +0 -1
  109. package/dist/services/webrtc/mediastream.d.ts +0 -10
  110. package/dist/services/webrtc/mediastream.d.ts.map +0 -1
  111. package/dist/services/webrtc/mediastream.js +0 -396
  112. package/dist/services/webrtc/mediastream.js.map +0 -1
  113. package/dist/services/webrtc/peer-connection-ice.d.ts +0 -32
  114. package/dist/services/webrtc/peer-connection-ice.d.ts.map +0 -1
  115. package/dist/services/webrtc/peer-connection-ice.js +0 -483
  116. package/dist/services/webrtc/peer-connection-ice.js.map +0 -1
  117. package/src/services/webrtc/datachannel.ts +0 -421
  118. package/src/services/webrtc/mediastream.ts +0 -602
  119. 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
+ }