@reactor-team/js-sdk 2.0.2 → 2.1.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/index.js CHANGED
@@ -100,6 +100,151 @@ var ConflictError = class extends Error {
100
100
  }
101
101
  };
102
102
 
103
+ // src/core/types.ts
104
+ var import_zod = require("zod");
105
+ var SessionState = /* @__PURE__ */ ((SessionState2) => {
106
+ SessionState2[SessionState2["SESSION_STATE_UNKNOWN"] = 0] = "SESSION_STATE_UNKNOWN";
107
+ SessionState2[SessionState2["SESSION_STATE_WAITING"] = 1] = "SESSION_STATE_WAITING";
108
+ SessionState2[SessionState2["SESSION_STATE_ACTIVE"] = 2] = "SESSION_STATE_ACTIVE";
109
+ SessionState2[SessionState2["SESSION_STATE_DISCONNECTED"] = 3] = "SESSION_STATE_DISCONNECTED";
110
+ SessionState2[SessionState2["SESSION_STATE_CLOSED"] = 4] = "SESSION_STATE_CLOSED";
111
+ SessionState2[SessionState2["UNRECOGNIZED"] = -1] = "UNRECOGNIZED";
112
+ return SessionState2;
113
+ })(SessionState || {});
114
+ var CreateSessionRequestSchema = import_zod.z.object({
115
+ model: import_zod.z.string(),
116
+ sdp_offer: import_zod.z.string(),
117
+ extra_args: import_zod.z.record(import_zod.z.string(), import_zod.z.any())
118
+ // Dictionary
119
+ });
120
+ var CreateSessionResponseSchema = import_zod.z.object({
121
+ session_id: import_zod.z.uuidv4()
122
+ });
123
+ var SessionStatusResponseSchema = import_zod.z.object({
124
+ session_id: import_zod.z.uuidv4(),
125
+ state: SessionState
126
+ });
127
+ var SessionInfoResponseSchema = SessionStatusResponseSchema.extend({
128
+ session_info: CreateSessionRequestSchema.extend({
129
+ session_id: import_zod.z.uuidv4()
130
+ })
131
+ });
132
+ var SDPParamsRequestSchema = import_zod.z.object({
133
+ sdp_offer: import_zod.z.string(),
134
+ extra_args: import_zod.z.record(import_zod.z.string(), import_zod.z.any())
135
+ // Dictionary
136
+ });
137
+ var SDPParamsResponseSchema = import_zod.z.object({
138
+ sdp_answer: import_zod.z.string(),
139
+ extra_args: import_zod.z.record(import_zod.z.string(), import_zod.z.any())
140
+ // Dictionary
141
+ });
142
+ var IceServersResponseSchema = import_zod.z.object({
143
+ ice_servers: import_zod.z.array(
144
+ import_zod.z.object({
145
+ uris: import_zod.z.array(import_zod.z.string()),
146
+ credentials: import_zod.z.object({
147
+ username: import_zod.z.string(),
148
+ password: import_zod.z.string()
149
+ }).optional()
150
+ })
151
+ )
152
+ });
153
+
154
+ // src/utils/webrtc.ts
155
+ var DEFAULT_DATA_CHANNEL_LABEL = "data";
156
+ var FORCE_RELAY_MODE = false;
157
+ function createPeerConnection(config) {
158
+ return new RTCPeerConnection({
159
+ iceServers: config.iceServers,
160
+ iceTransportPolicy: FORCE_RELAY_MODE ? "relay" : "all"
161
+ });
162
+ }
163
+ function createDataChannel(pc, label) {
164
+ return pc.createDataChannel(label != null ? label : DEFAULT_DATA_CHANNEL_LABEL);
165
+ }
166
+ function createOffer(pc) {
167
+ return __async(this, null, function* () {
168
+ const offer = yield pc.createOffer();
169
+ yield pc.setLocalDescription(offer);
170
+ yield waitForIceGathering(pc);
171
+ const localDescription = pc.localDescription;
172
+ if (!localDescription) {
173
+ throw new Error("Failed to create local description");
174
+ }
175
+ return localDescription.sdp;
176
+ });
177
+ }
178
+ function setRemoteDescription(pc, sdp) {
179
+ return __async(this, null, function* () {
180
+ const sessionDescription = new RTCSessionDescription({
181
+ sdp,
182
+ type: "answer"
183
+ });
184
+ yield pc.setRemoteDescription(sessionDescription);
185
+ });
186
+ }
187
+ function getLocalDescription(pc) {
188
+ const desc = pc.localDescription;
189
+ if (!desc) return void 0;
190
+ return desc.sdp;
191
+ }
192
+ function transformIceServers(response) {
193
+ return response.ice_servers.map((server) => {
194
+ const rtcServer = {
195
+ urls: server.uris
196
+ };
197
+ if (server.credentials) {
198
+ rtcServer.username = server.credentials.username;
199
+ rtcServer.credential = server.credentials.password;
200
+ }
201
+ return rtcServer;
202
+ });
203
+ }
204
+ function waitForIceGathering(pc, timeoutMs = 5e3) {
205
+ return new Promise((resolve) => {
206
+ if (pc.iceGatheringState === "complete") {
207
+ resolve();
208
+ return;
209
+ }
210
+ const onGatheringStateChange = () => {
211
+ if (pc.iceGatheringState === "complete") {
212
+ pc.removeEventListener(
213
+ "icegatheringstatechange",
214
+ onGatheringStateChange
215
+ );
216
+ resolve();
217
+ }
218
+ };
219
+ pc.addEventListener("icegatheringstatechange", onGatheringStateChange);
220
+ setTimeout(() => {
221
+ pc.removeEventListener("icegatheringstatechange", onGatheringStateChange);
222
+ resolve();
223
+ }, timeoutMs);
224
+ });
225
+ }
226
+ function sendMessage(channel, command, data) {
227
+ if (channel.readyState !== "open") {
228
+ throw new Error(`Data channel not open: ${channel.readyState}`);
229
+ }
230
+ const jsonData = typeof data === "string" ? JSON.parse(data) : data;
231
+ const payload = { type: command, data: jsonData };
232
+ channel.send(JSON.stringify(payload));
233
+ }
234
+ function parseMessage(data) {
235
+ if (typeof data === "string") {
236
+ try {
237
+ return JSON.parse(data);
238
+ } catch (e) {
239
+ return data;
240
+ }
241
+ }
242
+ return data;
243
+ }
244
+ function closePeerConnection(pc) {
245
+ pc.close();
246
+ }
247
+
103
248
  // src/core/CoordinatorClient.ts
104
249
  var INITIAL_BACKOFF_MS = 500;
105
250
  var MAX_BACKOFF_MS = 3e4;
@@ -118,9 +263,31 @@ var CoordinatorClient = class {
118
263
  Authorization: `Bearer ${this.jwtToken}`
119
264
  };
120
265
  }
266
+ /**
267
+ * Fetches ICE servers from the coordinator.
268
+ * @returns Array of RTCIceServer objects for WebRTC peer connection configuration
269
+ */
121
270
  getIceServers() {
122
271
  return __async(this, null, function* () {
123
- return [{ urls: "stun:stun.l.google.com:19302" }];
272
+ console.debug("[CoordinatorClient] Fetching ICE servers...");
273
+ const response = yield fetch(
274
+ `${this.baseUrl}/ice_servers?model=${this.model}`,
275
+ {
276
+ method: "GET",
277
+ headers: this.getAuthHeaders()
278
+ }
279
+ );
280
+ if (!response.ok) {
281
+ throw new Error(`Failed to fetch ICE servers: ${response.status}`);
282
+ }
283
+ const data = yield response.json();
284
+ const parsed = IceServersResponseSchema.parse(data);
285
+ const iceServers = transformIceServers(parsed);
286
+ console.debug(
287
+ "[CoordinatorClient] Received ICE servers:",
288
+ iceServers.length
289
+ );
290
+ return iceServers;
124
291
  });
125
292
  }
126
293
  /**
@@ -373,11 +540,13 @@ var LocalCoordinatorClient = class extends CoordinatorClient {
373
540
  throw new Error("Failed to get ICE servers from local coordinator.");
374
541
  }
375
542
  const data = yield response.json();
543
+ const parsed = IceServersResponseSchema.parse(data);
544
+ const iceServers = transformIceServers(parsed);
376
545
  console.debug(
377
546
  "[LocalCoordinatorClient] Received ICE servers:",
378
- data.ice_servers
547
+ iceServers.length
379
548
  );
380
- return data.ice_servers;
549
+ return iceServers;
381
550
  });
382
551
  }
383
552
  /**
@@ -440,88 +609,6 @@ var LocalCoordinatorClient = class extends CoordinatorClient {
440
609
  }
441
610
  };
442
611
 
443
- // src/utils/webrtc.ts
444
- var DEFAULT_DATA_CHANNEL_LABEL = "data";
445
- var FORCE_RELAY_MODE = false;
446
- function createPeerConnection(config) {
447
- return new RTCPeerConnection({
448
- iceServers: config.iceServers,
449
- iceTransportPolicy: FORCE_RELAY_MODE ? "relay" : "all"
450
- });
451
- }
452
- function createDataChannel(pc, label) {
453
- return pc.createDataChannel(label != null ? label : DEFAULT_DATA_CHANNEL_LABEL);
454
- }
455
- function createOffer(pc) {
456
- return __async(this, null, function* () {
457
- const offer = yield pc.createOffer();
458
- yield pc.setLocalDescription(offer);
459
- yield waitForIceGathering(pc);
460
- const localDescription = pc.localDescription;
461
- if (!localDescription) {
462
- throw new Error("Failed to create local description");
463
- }
464
- return localDescription.sdp;
465
- });
466
- }
467
- function setRemoteDescription(pc, sdp) {
468
- return __async(this, null, function* () {
469
- const sessionDescription = new RTCSessionDescription({
470
- sdp,
471
- type: "answer"
472
- });
473
- yield pc.setRemoteDescription(sessionDescription);
474
- });
475
- }
476
- function getLocalDescription(pc) {
477
- const desc = pc.localDescription;
478
- if (!desc) return void 0;
479
- return desc.sdp;
480
- }
481
- function waitForIceGathering(pc, timeoutMs = 5e3) {
482
- return new Promise((resolve) => {
483
- if (pc.iceGatheringState === "complete") {
484
- resolve();
485
- return;
486
- }
487
- const onGatheringStateChange = () => {
488
- if (pc.iceGatheringState === "complete") {
489
- pc.removeEventListener(
490
- "icegatheringstatechange",
491
- onGatheringStateChange
492
- );
493
- resolve();
494
- }
495
- };
496
- pc.addEventListener("icegatheringstatechange", onGatheringStateChange);
497
- setTimeout(() => {
498
- pc.removeEventListener("icegatheringstatechange", onGatheringStateChange);
499
- resolve();
500
- }, timeoutMs);
501
- });
502
- }
503
- function sendMessage(channel, command, data) {
504
- if (channel.readyState !== "open") {
505
- throw new Error(`Data channel not open: ${channel.readyState}`);
506
- }
507
- const jsonData = typeof data === "string" ? JSON.parse(data) : data;
508
- const payload = { type: command, data: jsonData };
509
- channel.send(JSON.stringify(payload));
510
- }
511
- function parseMessage(data) {
512
- if (typeof data === "string") {
513
- try {
514
- return JSON.parse(data);
515
- } catch (e) {
516
- return data;
517
- }
518
- }
519
- return data;
520
- }
521
- function closePeerConnection(pc) {
522
- pc.close();
523
- }
524
-
525
612
  // src/core/GPUMachineClient.ts
526
613
  var GPUMachineClient = class {
527
614
  constructor(config) {
@@ -808,13 +895,13 @@ var GPUMachineClient = class {
808
895
  };
809
896
 
810
897
  // src/core/Reactor.ts
811
- var import_zod = require("zod");
898
+ var import_zod2 = require("zod");
812
899
  var LOCAL_COORDINATOR_URL = "http://localhost:8080";
813
900
  var PROD_COORDINATOR_URL = "https://api.reactor.inc";
814
- var OptionsSchema = import_zod.z.object({
815
- coordinatorUrl: import_zod.z.string().default(PROD_COORDINATOR_URL),
816
- modelName: import_zod.z.string(),
817
- local: import_zod.z.boolean().default(false)
901
+ var OptionsSchema = import_zod2.z.object({
902
+ coordinatorUrl: import_zod2.z.string().default(PROD_COORDINATOR_URL),
903
+ modelName: import_zod2.z.string(),
904
+ local: import_zod2.z.boolean().default(false)
818
905
  });
819
906
  var Reactor = class {
820
907
  constructor(options) {