@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.js +182 -91
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +182 -91
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -100,6 +100,155 @@ 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["CREATED"] = 0] = "CREATED";
|
|
107
|
+
SessionState2[SessionState2["PENDING"] = 1] = "PENDING";
|
|
108
|
+
SessionState2[SessionState2["SUSPENDED"] = 2] = "SUSPENDED";
|
|
109
|
+
SessionState2[SessionState2["WAITING"] = 3] = "WAITING";
|
|
110
|
+
SessionState2[SessionState2["ACTIVE"] = 4] = "ACTIVE";
|
|
111
|
+
SessionState2[SessionState2["INACTIVE"] = 5] = "INACTIVE";
|
|
112
|
+
SessionState2[SessionState2["CLOSED"] = 6] = "CLOSED";
|
|
113
|
+
return SessionState2;
|
|
114
|
+
})(SessionState || {});
|
|
115
|
+
var ModelSchema = import_zod.z.object({
|
|
116
|
+
name: import_zod.z.string()
|
|
117
|
+
});
|
|
118
|
+
var CreateSessionRequestSchema = import_zod.z.object({
|
|
119
|
+
model: ModelSchema,
|
|
120
|
+
sdp_offer: import_zod.z.string(),
|
|
121
|
+
extra_args: import_zod.z.record(import_zod.z.string(), import_zod.z.any())
|
|
122
|
+
// Dictionary
|
|
123
|
+
});
|
|
124
|
+
var CreateSessionResponseSchema = import_zod.z.object({
|
|
125
|
+
session_id: import_zod.z.uuidv4()
|
|
126
|
+
});
|
|
127
|
+
var SessionStatusResponseSchema = import_zod.z.object({
|
|
128
|
+
session_id: import_zod.z.uuidv4(),
|
|
129
|
+
state: SessionState
|
|
130
|
+
});
|
|
131
|
+
var SessionInfoResponseSchema = SessionStatusResponseSchema.extend({
|
|
132
|
+
session_info: CreateSessionRequestSchema.extend({
|
|
133
|
+
session_id: import_zod.z.uuidv4()
|
|
134
|
+
})
|
|
135
|
+
});
|
|
136
|
+
var SDPParamsRequestSchema = import_zod.z.object({
|
|
137
|
+
sdp_offer: import_zod.z.string(),
|
|
138
|
+
extra_args: import_zod.z.record(import_zod.z.string(), import_zod.z.any())
|
|
139
|
+
// Dictionary
|
|
140
|
+
});
|
|
141
|
+
var SDPParamsResponseSchema = import_zod.z.object({
|
|
142
|
+
sdp_answer: import_zod.z.string(),
|
|
143
|
+
extra_args: import_zod.z.record(import_zod.z.string(), import_zod.z.any())
|
|
144
|
+
// Dictionary
|
|
145
|
+
});
|
|
146
|
+
var IceServersResponseSchema = import_zod.z.object({
|
|
147
|
+
ice_servers: import_zod.z.array(
|
|
148
|
+
import_zod.z.object({
|
|
149
|
+
uris: import_zod.z.array(import_zod.z.string()),
|
|
150
|
+
credentials: import_zod.z.object({
|
|
151
|
+
username: import_zod.z.string(),
|
|
152
|
+
password: import_zod.z.string()
|
|
153
|
+
}).optional()
|
|
154
|
+
})
|
|
155
|
+
)
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
// src/utils/webrtc.ts
|
|
159
|
+
var DEFAULT_DATA_CHANNEL_LABEL = "data";
|
|
160
|
+
var FORCE_RELAY_MODE = false;
|
|
161
|
+
function createPeerConnection(config) {
|
|
162
|
+
return new RTCPeerConnection({
|
|
163
|
+
iceServers: config.iceServers,
|
|
164
|
+
iceTransportPolicy: FORCE_RELAY_MODE ? "relay" : "all"
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
function createDataChannel(pc, label) {
|
|
168
|
+
return pc.createDataChannel(label != null ? label : DEFAULT_DATA_CHANNEL_LABEL);
|
|
169
|
+
}
|
|
170
|
+
function createOffer(pc) {
|
|
171
|
+
return __async(this, null, function* () {
|
|
172
|
+
const offer = yield pc.createOffer();
|
|
173
|
+
yield pc.setLocalDescription(offer);
|
|
174
|
+
yield waitForIceGathering(pc);
|
|
175
|
+
const localDescription = pc.localDescription;
|
|
176
|
+
if (!localDescription) {
|
|
177
|
+
throw new Error("Failed to create local description");
|
|
178
|
+
}
|
|
179
|
+
return localDescription.sdp;
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
function setRemoteDescription(pc, sdp) {
|
|
183
|
+
return __async(this, null, function* () {
|
|
184
|
+
const sessionDescription = new RTCSessionDescription({
|
|
185
|
+
sdp,
|
|
186
|
+
type: "answer"
|
|
187
|
+
});
|
|
188
|
+
yield pc.setRemoteDescription(sessionDescription);
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
function getLocalDescription(pc) {
|
|
192
|
+
const desc = pc.localDescription;
|
|
193
|
+
if (!desc) return void 0;
|
|
194
|
+
return desc.sdp;
|
|
195
|
+
}
|
|
196
|
+
function transformIceServers(response) {
|
|
197
|
+
return response.ice_servers.map((server) => {
|
|
198
|
+
const rtcServer = {
|
|
199
|
+
urls: server.uris
|
|
200
|
+
};
|
|
201
|
+
if (server.credentials) {
|
|
202
|
+
rtcServer.username = server.credentials.username;
|
|
203
|
+
rtcServer.credential = server.credentials.password;
|
|
204
|
+
}
|
|
205
|
+
return rtcServer;
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
function waitForIceGathering(pc, timeoutMs = 5e3) {
|
|
209
|
+
return new Promise((resolve) => {
|
|
210
|
+
if (pc.iceGatheringState === "complete") {
|
|
211
|
+
resolve();
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
const onGatheringStateChange = () => {
|
|
215
|
+
if (pc.iceGatheringState === "complete") {
|
|
216
|
+
pc.removeEventListener(
|
|
217
|
+
"icegatheringstatechange",
|
|
218
|
+
onGatheringStateChange
|
|
219
|
+
);
|
|
220
|
+
resolve();
|
|
221
|
+
}
|
|
222
|
+
};
|
|
223
|
+
pc.addEventListener("icegatheringstatechange", onGatheringStateChange);
|
|
224
|
+
setTimeout(() => {
|
|
225
|
+
pc.removeEventListener("icegatheringstatechange", onGatheringStateChange);
|
|
226
|
+
resolve();
|
|
227
|
+
}, timeoutMs);
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
function sendMessage(channel, command, data) {
|
|
231
|
+
if (channel.readyState !== "open") {
|
|
232
|
+
throw new Error(`Data channel not open: ${channel.readyState}`);
|
|
233
|
+
}
|
|
234
|
+
const jsonData = typeof data === "string" ? JSON.parse(data) : data;
|
|
235
|
+
const payload = { type: command, data: jsonData };
|
|
236
|
+
channel.send(JSON.stringify(payload));
|
|
237
|
+
}
|
|
238
|
+
function parseMessage(data) {
|
|
239
|
+
if (typeof data === "string") {
|
|
240
|
+
try {
|
|
241
|
+
return JSON.parse(data);
|
|
242
|
+
} catch (e) {
|
|
243
|
+
return data;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
return data;
|
|
247
|
+
}
|
|
248
|
+
function closePeerConnection(pc) {
|
|
249
|
+
pc.close();
|
|
250
|
+
}
|
|
251
|
+
|
|
103
252
|
// src/core/CoordinatorClient.ts
|
|
104
253
|
var INITIAL_BACKOFF_MS = 500;
|
|
105
254
|
var MAX_BACKOFF_MS = 3e4;
|
|
@@ -118,9 +267,31 @@ var CoordinatorClient = class {
|
|
|
118
267
|
Authorization: `Bearer ${this.jwtToken}`
|
|
119
268
|
};
|
|
120
269
|
}
|
|
270
|
+
/**
|
|
271
|
+
* Fetches ICE servers from the coordinator.
|
|
272
|
+
* @returns Array of RTCIceServer objects for WebRTC peer connection configuration
|
|
273
|
+
*/
|
|
121
274
|
getIceServers() {
|
|
122
275
|
return __async(this, null, function* () {
|
|
123
|
-
|
|
276
|
+
console.debug("[CoordinatorClient] Fetching ICE servers...");
|
|
277
|
+
const response = yield fetch(
|
|
278
|
+
`${this.baseUrl}/ice_servers?model=${this.model}`,
|
|
279
|
+
{
|
|
280
|
+
method: "GET",
|
|
281
|
+
headers: this.getAuthHeaders()
|
|
282
|
+
}
|
|
283
|
+
);
|
|
284
|
+
if (!response.ok) {
|
|
285
|
+
throw new Error(`Failed to fetch ICE servers: ${response.status}`);
|
|
286
|
+
}
|
|
287
|
+
const data = yield response.json();
|
|
288
|
+
const parsed = IceServersResponseSchema.parse(data);
|
|
289
|
+
const iceServers = transformIceServers(parsed);
|
|
290
|
+
console.debug(
|
|
291
|
+
"[CoordinatorClient] Received ICE servers:",
|
|
292
|
+
iceServers.length
|
|
293
|
+
);
|
|
294
|
+
return iceServers;
|
|
124
295
|
});
|
|
125
296
|
}
|
|
126
297
|
/**
|
|
@@ -132,7 +303,7 @@ var CoordinatorClient = class {
|
|
|
132
303
|
return __async(this, null, function* () {
|
|
133
304
|
console.debug("[CoordinatorClient] Creating session...");
|
|
134
305
|
const requestBody = {
|
|
135
|
-
model: this.model,
|
|
306
|
+
model: { name: this.model },
|
|
136
307
|
sdp_offer,
|
|
137
308
|
extra_args: {}
|
|
138
309
|
};
|
|
@@ -373,11 +544,13 @@ var LocalCoordinatorClient = class extends CoordinatorClient {
|
|
|
373
544
|
throw new Error("Failed to get ICE servers from local coordinator.");
|
|
374
545
|
}
|
|
375
546
|
const data = yield response.json();
|
|
547
|
+
const parsed = IceServersResponseSchema.parse(data);
|
|
548
|
+
const iceServers = transformIceServers(parsed);
|
|
376
549
|
console.debug(
|
|
377
550
|
"[LocalCoordinatorClient] Received ICE servers:",
|
|
378
|
-
|
|
551
|
+
iceServers.length
|
|
379
552
|
);
|
|
380
|
-
return
|
|
553
|
+
return iceServers;
|
|
381
554
|
});
|
|
382
555
|
}
|
|
383
556
|
/**
|
|
@@ -440,88 +613,6 @@ var LocalCoordinatorClient = class extends CoordinatorClient {
|
|
|
440
613
|
}
|
|
441
614
|
};
|
|
442
615
|
|
|
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
616
|
// src/core/GPUMachineClient.ts
|
|
526
617
|
var GPUMachineClient = class {
|
|
527
618
|
constructor(config) {
|
|
@@ -808,13 +899,13 @@ var GPUMachineClient = class {
|
|
|
808
899
|
};
|
|
809
900
|
|
|
810
901
|
// src/core/Reactor.ts
|
|
811
|
-
var
|
|
902
|
+
var import_zod2 = require("zod");
|
|
812
903
|
var LOCAL_COORDINATOR_URL = "http://localhost:8080";
|
|
813
904
|
var PROD_COORDINATOR_URL = "https://api.reactor.inc";
|
|
814
|
-
var OptionsSchema =
|
|
815
|
-
coordinatorUrl:
|
|
816
|
-
modelName:
|
|
817
|
-
local:
|
|
905
|
+
var OptionsSchema = import_zod2.z.object({
|
|
906
|
+
coordinatorUrl: import_zod2.z.string().default(PROD_COORDINATOR_URL),
|
|
907
|
+
modelName: import_zod2.z.string(),
|
|
908
|
+
local: import_zod2.z.boolean().default(false)
|
|
818
909
|
});
|
|
819
910
|
var Reactor = class {
|
|
820
911
|
constructor(options) {
|