@reactor-team/js-sdk 2.0.2 → 2.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/index.mjs CHANGED
@@ -57,6 +57,155 @@ var ConflictError = class extends Error {
57
57
  }
58
58
  };
59
59
 
60
+ // src/core/types.ts
61
+ import { z } from "zod";
62
+ var SessionState = /* @__PURE__ */ ((SessionState2) => {
63
+ SessionState2[SessionState2["CREATED"] = 0] = "CREATED";
64
+ SessionState2[SessionState2["PENDING"] = 1] = "PENDING";
65
+ SessionState2[SessionState2["SUSPENDED"] = 2] = "SUSPENDED";
66
+ SessionState2[SessionState2["WAITING"] = 3] = "WAITING";
67
+ SessionState2[SessionState2["ACTIVE"] = 4] = "ACTIVE";
68
+ SessionState2[SessionState2["INACTIVE"] = 5] = "INACTIVE";
69
+ SessionState2[SessionState2["CLOSED"] = 6] = "CLOSED";
70
+ return SessionState2;
71
+ })(SessionState || {});
72
+ var ModelSchema = z.object({
73
+ name: z.string()
74
+ });
75
+ var CreateSessionRequestSchema = z.object({
76
+ model: ModelSchema,
77
+ sdp_offer: z.string(),
78
+ extra_args: z.record(z.string(), z.any())
79
+ // Dictionary
80
+ });
81
+ var CreateSessionResponseSchema = z.object({
82
+ session_id: z.uuidv4()
83
+ });
84
+ var SessionStatusResponseSchema = z.object({
85
+ session_id: z.uuidv4(),
86
+ state: SessionState
87
+ });
88
+ var SessionInfoResponseSchema = SessionStatusResponseSchema.extend({
89
+ session_info: CreateSessionRequestSchema.extend({
90
+ session_id: z.uuidv4()
91
+ })
92
+ });
93
+ var SDPParamsRequestSchema = z.object({
94
+ sdp_offer: z.string(),
95
+ extra_args: z.record(z.string(), z.any())
96
+ // Dictionary
97
+ });
98
+ var SDPParamsResponseSchema = z.object({
99
+ sdp_answer: z.string(),
100
+ extra_args: z.record(z.string(), z.any())
101
+ // Dictionary
102
+ });
103
+ var IceServersResponseSchema = z.object({
104
+ ice_servers: z.array(
105
+ z.object({
106
+ uris: z.array(z.string()),
107
+ credentials: z.object({
108
+ username: z.string(),
109
+ password: z.string()
110
+ }).optional()
111
+ })
112
+ )
113
+ });
114
+
115
+ // src/utils/webrtc.ts
116
+ var DEFAULT_DATA_CHANNEL_LABEL = "data";
117
+ var FORCE_RELAY_MODE = false;
118
+ function createPeerConnection(config) {
119
+ return new RTCPeerConnection({
120
+ iceServers: config.iceServers,
121
+ iceTransportPolicy: FORCE_RELAY_MODE ? "relay" : "all"
122
+ });
123
+ }
124
+ function createDataChannel(pc, label) {
125
+ return pc.createDataChannel(label != null ? label : DEFAULT_DATA_CHANNEL_LABEL);
126
+ }
127
+ function createOffer(pc) {
128
+ return __async(this, null, function* () {
129
+ const offer = yield pc.createOffer();
130
+ yield pc.setLocalDescription(offer);
131
+ yield waitForIceGathering(pc);
132
+ const localDescription = pc.localDescription;
133
+ if (!localDescription) {
134
+ throw new Error("Failed to create local description");
135
+ }
136
+ return localDescription.sdp;
137
+ });
138
+ }
139
+ function setRemoteDescription(pc, sdp) {
140
+ return __async(this, null, function* () {
141
+ const sessionDescription = new RTCSessionDescription({
142
+ sdp,
143
+ type: "answer"
144
+ });
145
+ yield pc.setRemoteDescription(sessionDescription);
146
+ });
147
+ }
148
+ function getLocalDescription(pc) {
149
+ const desc = pc.localDescription;
150
+ if (!desc) return void 0;
151
+ return desc.sdp;
152
+ }
153
+ function transformIceServers(response) {
154
+ return response.ice_servers.map((server) => {
155
+ const rtcServer = {
156
+ urls: server.uris
157
+ };
158
+ if (server.credentials) {
159
+ rtcServer.username = server.credentials.username;
160
+ rtcServer.credential = server.credentials.password;
161
+ }
162
+ return rtcServer;
163
+ });
164
+ }
165
+ function waitForIceGathering(pc, timeoutMs = 5e3) {
166
+ return new Promise((resolve) => {
167
+ if (pc.iceGatheringState === "complete") {
168
+ resolve();
169
+ return;
170
+ }
171
+ const onGatheringStateChange = () => {
172
+ if (pc.iceGatheringState === "complete") {
173
+ pc.removeEventListener(
174
+ "icegatheringstatechange",
175
+ onGatheringStateChange
176
+ );
177
+ resolve();
178
+ }
179
+ };
180
+ pc.addEventListener("icegatheringstatechange", onGatheringStateChange);
181
+ setTimeout(() => {
182
+ pc.removeEventListener("icegatheringstatechange", onGatheringStateChange);
183
+ resolve();
184
+ }, timeoutMs);
185
+ });
186
+ }
187
+ function sendMessage(channel, command, data) {
188
+ if (channel.readyState !== "open") {
189
+ throw new Error(`Data channel not open: ${channel.readyState}`);
190
+ }
191
+ const jsonData = typeof data === "string" ? JSON.parse(data) : data;
192
+ const payload = { type: command, data: jsonData };
193
+ channel.send(JSON.stringify(payload));
194
+ }
195
+ function parseMessage(data) {
196
+ if (typeof data === "string") {
197
+ try {
198
+ return JSON.parse(data);
199
+ } catch (e) {
200
+ return data;
201
+ }
202
+ }
203
+ return data;
204
+ }
205
+ function closePeerConnection(pc) {
206
+ pc.close();
207
+ }
208
+
60
209
  // src/core/CoordinatorClient.ts
61
210
  var INITIAL_BACKOFF_MS = 500;
62
211
  var MAX_BACKOFF_MS = 3e4;
@@ -75,9 +224,31 @@ var CoordinatorClient = class {
75
224
  Authorization: `Bearer ${this.jwtToken}`
76
225
  };
77
226
  }
227
+ /**
228
+ * Fetches ICE servers from the coordinator.
229
+ * @returns Array of RTCIceServer objects for WebRTC peer connection configuration
230
+ */
78
231
  getIceServers() {
79
232
  return __async(this, null, function* () {
80
- return [{ urls: "stun:stun.l.google.com:19302" }];
233
+ console.debug("[CoordinatorClient] Fetching ICE servers...");
234
+ const response = yield fetch(
235
+ `${this.baseUrl}/ice_servers?model=${this.model}`,
236
+ {
237
+ method: "GET",
238
+ headers: this.getAuthHeaders()
239
+ }
240
+ );
241
+ if (!response.ok) {
242
+ throw new Error(`Failed to fetch ICE servers: ${response.status}`);
243
+ }
244
+ const data = yield response.json();
245
+ const parsed = IceServersResponseSchema.parse(data);
246
+ const iceServers = transformIceServers(parsed);
247
+ console.debug(
248
+ "[CoordinatorClient] Received ICE servers:",
249
+ iceServers.length
250
+ );
251
+ return iceServers;
81
252
  });
82
253
  }
83
254
  /**
@@ -89,7 +260,7 @@ var CoordinatorClient = class {
89
260
  return __async(this, null, function* () {
90
261
  console.debug("[CoordinatorClient] Creating session...");
91
262
  const requestBody = {
92
- model: this.model,
263
+ model: { name: this.model },
93
264
  sdp_offer,
94
265
  extra_args: {}
95
266
  };
@@ -330,11 +501,13 @@ var LocalCoordinatorClient = class extends CoordinatorClient {
330
501
  throw new Error("Failed to get ICE servers from local coordinator.");
331
502
  }
332
503
  const data = yield response.json();
504
+ const parsed = IceServersResponseSchema.parse(data);
505
+ const iceServers = transformIceServers(parsed);
333
506
  console.debug(
334
507
  "[LocalCoordinatorClient] Received ICE servers:",
335
- data.ice_servers
508
+ iceServers.length
336
509
  );
337
- return data.ice_servers;
510
+ return iceServers;
338
511
  });
339
512
  }
340
513
  /**
@@ -397,88 +570,6 @@ var LocalCoordinatorClient = class extends CoordinatorClient {
397
570
  }
398
571
  };
399
572
 
400
- // src/utils/webrtc.ts
401
- var DEFAULT_DATA_CHANNEL_LABEL = "data";
402
- var FORCE_RELAY_MODE = false;
403
- function createPeerConnection(config) {
404
- return new RTCPeerConnection({
405
- iceServers: config.iceServers,
406
- iceTransportPolicy: FORCE_RELAY_MODE ? "relay" : "all"
407
- });
408
- }
409
- function createDataChannel(pc, label) {
410
- return pc.createDataChannel(label != null ? label : DEFAULT_DATA_CHANNEL_LABEL);
411
- }
412
- function createOffer(pc) {
413
- return __async(this, null, function* () {
414
- const offer = yield pc.createOffer();
415
- yield pc.setLocalDescription(offer);
416
- yield waitForIceGathering(pc);
417
- const localDescription = pc.localDescription;
418
- if (!localDescription) {
419
- throw new Error("Failed to create local description");
420
- }
421
- return localDescription.sdp;
422
- });
423
- }
424
- function setRemoteDescription(pc, sdp) {
425
- return __async(this, null, function* () {
426
- const sessionDescription = new RTCSessionDescription({
427
- sdp,
428
- type: "answer"
429
- });
430
- yield pc.setRemoteDescription(sessionDescription);
431
- });
432
- }
433
- function getLocalDescription(pc) {
434
- const desc = pc.localDescription;
435
- if (!desc) return void 0;
436
- return desc.sdp;
437
- }
438
- function waitForIceGathering(pc, timeoutMs = 5e3) {
439
- return new Promise((resolve) => {
440
- if (pc.iceGatheringState === "complete") {
441
- resolve();
442
- return;
443
- }
444
- const onGatheringStateChange = () => {
445
- if (pc.iceGatheringState === "complete") {
446
- pc.removeEventListener(
447
- "icegatheringstatechange",
448
- onGatheringStateChange
449
- );
450
- resolve();
451
- }
452
- };
453
- pc.addEventListener("icegatheringstatechange", onGatheringStateChange);
454
- setTimeout(() => {
455
- pc.removeEventListener("icegatheringstatechange", onGatheringStateChange);
456
- resolve();
457
- }, timeoutMs);
458
- });
459
- }
460
- function sendMessage(channel, command, data) {
461
- if (channel.readyState !== "open") {
462
- throw new Error(`Data channel not open: ${channel.readyState}`);
463
- }
464
- const jsonData = typeof data === "string" ? JSON.parse(data) : data;
465
- const payload = { type: command, data: jsonData };
466
- channel.send(JSON.stringify(payload));
467
- }
468
- function parseMessage(data) {
469
- if (typeof data === "string") {
470
- try {
471
- return JSON.parse(data);
472
- } catch (e) {
473
- return data;
474
- }
475
- }
476
- return data;
477
- }
478
- function closePeerConnection(pc) {
479
- pc.close();
480
- }
481
-
482
573
  // src/core/GPUMachineClient.ts
483
574
  var GPUMachineClient = class {
484
575
  constructor(config) {
@@ -765,13 +856,13 @@ var GPUMachineClient = class {
765
856
  };
766
857
 
767
858
  // src/core/Reactor.ts
768
- import { z } from "zod";
859
+ import { z as z2 } from "zod";
769
860
  var LOCAL_COORDINATOR_URL = "http://localhost:8080";
770
861
  var PROD_COORDINATOR_URL = "https://api.reactor.inc";
771
- var OptionsSchema = z.object({
772
- coordinatorUrl: z.string().default(PROD_COORDINATOR_URL),
773
- modelName: z.string(),
774
- local: z.boolean().default(false)
862
+ var OptionsSchema = z2.object({
863
+ coordinatorUrl: z2.string().default(PROD_COORDINATOR_URL),
864
+ modelName: z2.string(),
865
+ local: z2.boolean().default(false)
775
866
  });
776
867
  var Reactor = class {
777
868
  constructor(options) {