@reactor-team/js-sdk 2.0.1 → 2.0.2
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.mts +4 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.js +55 -10
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +54 -10
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -11,6 +11,9 @@ interface ReactorError {
|
|
|
11
11
|
component: "coordinator" | "gpu" | "livekit";
|
|
12
12
|
retryAfter?: number;
|
|
13
13
|
}
|
|
14
|
+
declare class ConflictError extends Error {
|
|
15
|
+
constructor(message: string);
|
|
16
|
+
}
|
|
14
17
|
interface ReactorState$1 {
|
|
15
18
|
status: ReactorStatus;
|
|
16
19
|
lastError?: ReactorError;
|
|
@@ -184,4 +187,4 @@ declare function useReactorMessage(handler: (message: any) => void): void;
|
|
|
184
187
|
*/
|
|
185
188
|
declare function fetchInsecureJwtToken(apiKey: string, coordinatorUrl?: string): Promise<string>;
|
|
186
189
|
|
|
187
|
-
export { type Options, PROD_COORDINATOR_URL, Reactor, ReactorController, type ReactorControllerProps, type ReactorError, type ReactorEvent, ReactorProvider, type ReactorState$1 as ReactorState, type ReactorStatus, ReactorView, type ReactorViewProps, WebcamStream, fetchInsecureJwtToken, useReactor, useReactorMessage, useReactorStore };
|
|
190
|
+
export { ConflictError, type Options, PROD_COORDINATOR_URL, Reactor, ReactorController, type ReactorControllerProps, type ReactorError, type ReactorEvent, ReactorProvider, type ReactorState$1 as ReactorState, type ReactorStatus, ReactorView, type ReactorViewProps, WebcamStream, fetchInsecureJwtToken, useReactor, useReactorMessage, useReactorStore };
|
package/dist/index.d.ts
CHANGED
|
@@ -11,6 +11,9 @@ interface ReactorError {
|
|
|
11
11
|
component: "coordinator" | "gpu" | "livekit";
|
|
12
12
|
retryAfter?: number;
|
|
13
13
|
}
|
|
14
|
+
declare class ConflictError extends Error {
|
|
15
|
+
constructor(message: string);
|
|
16
|
+
}
|
|
14
17
|
interface ReactorState$1 {
|
|
15
18
|
status: ReactorStatus;
|
|
16
19
|
lastError?: ReactorError;
|
|
@@ -184,4 +187,4 @@ declare function useReactorMessage(handler: (message: any) => void): void;
|
|
|
184
187
|
*/
|
|
185
188
|
declare function fetchInsecureJwtToken(apiKey: string, coordinatorUrl?: string): Promise<string>;
|
|
186
189
|
|
|
187
|
-
export { type Options, PROD_COORDINATOR_URL, Reactor, ReactorController, type ReactorControllerProps, type ReactorError, type ReactorEvent, ReactorProvider, type ReactorState$1 as ReactorState, type ReactorStatus, ReactorView, type ReactorViewProps, WebcamStream, fetchInsecureJwtToken, useReactor, useReactorMessage, useReactorStore };
|
|
190
|
+
export { ConflictError, type Options, PROD_COORDINATOR_URL, Reactor, ReactorController, type ReactorControllerProps, type ReactorError, type ReactorEvent, ReactorProvider, type ReactorState$1 as ReactorState, type ReactorStatus, ReactorView, type ReactorViewProps, WebcamStream, fetchInsecureJwtToken, useReactor, useReactorMessage, useReactorStore };
|
package/dist/index.js
CHANGED
|
@@ -79,6 +79,7 @@ var __async = (__this, __arguments, generator) => {
|
|
|
79
79
|
// src/index.ts
|
|
80
80
|
var index_exports = {};
|
|
81
81
|
__export(index_exports, {
|
|
82
|
+
ConflictError: () => ConflictError,
|
|
82
83
|
PROD_COORDINATOR_URL: () => PROD_COORDINATOR_URL,
|
|
83
84
|
Reactor: () => Reactor,
|
|
84
85
|
ReactorController: () => ReactorController,
|
|
@@ -92,6 +93,13 @@ __export(index_exports, {
|
|
|
92
93
|
});
|
|
93
94
|
module.exports = __toCommonJS(index_exports);
|
|
94
95
|
|
|
96
|
+
// src/types.ts
|
|
97
|
+
var ConflictError = class extends Error {
|
|
98
|
+
constructor(message) {
|
|
99
|
+
super(message);
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
|
|
95
103
|
// src/core/CoordinatorClient.ts
|
|
96
104
|
var INITIAL_BACKOFF_MS = 500;
|
|
97
105
|
var MAX_BACKOFF_MS = 3e4;
|
|
@@ -110,6 +118,11 @@ var CoordinatorClient = class {
|
|
|
110
118
|
Authorization: `Bearer ${this.jwtToken}`
|
|
111
119
|
};
|
|
112
120
|
}
|
|
121
|
+
getIceServers() {
|
|
122
|
+
return __async(this, null, function* () {
|
|
123
|
+
return [{ urls: "stun:stun.l.google.com:19302" }];
|
|
124
|
+
});
|
|
125
|
+
}
|
|
113
126
|
/**
|
|
114
127
|
* Creates a new session with the coordinator.
|
|
115
128
|
* Expects a 200 response and stores the session ID.
|
|
@@ -346,6 +359,27 @@ var LocalCoordinatorClient = class extends CoordinatorClient {
|
|
|
346
359
|
});
|
|
347
360
|
this.localBaseUrl = baseUrl;
|
|
348
361
|
}
|
|
362
|
+
/**
|
|
363
|
+
* Gets ICE servers from the local HTTP runtime.
|
|
364
|
+
* @returns The ICE server configuration
|
|
365
|
+
*/
|
|
366
|
+
getIceServers() {
|
|
367
|
+
return __async(this, null, function* () {
|
|
368
|
+
console.debug("[LocalCoordinatorClient] Fetching ICE servers...");
|
|
369
|
+
const response = yield fetch(`${this.localBaseUrl}/ice_servers`, {
|
|
370
|
+
method: "GET"
|
|
371
|
+
});
|
|
372
|
+
if (!response.ok) {
|
|
373
|
+
throw new Error("Failed to get ICE servers from local coordinator.");
|
|
374
|
+
}
|
|
375
|
+
const data = yield response.json();
|
|
376
|
+
console.debug(
|
|
377
|
+
"[LocalCoordinatorClient] Received ICE servers:",
|
|
378
|
+
data.ice_servers
|
|
379
|
+
);
|
|
380
|
+
return data.ice_servers;
|
|
381
|
+
});
|
|
382
|
+
}
|
|
349
383
|
/**
|
|
350
384
|
* Creates a local session by posting to /start_session.
|
|
351
385
|
* @returns always "local"
|
|
@@ -386,6 +420,9 @@ var LocalCoordinatorClient = class extends CoordinatorClient {
|
|
|
386
420
|
body: JSON.stringify(sdpBody)
|
|
387
421
|
});
|
|
388
422
|
if (!response.ok) {
|
|
423
|
+
if (response.status === 409) {
|
|
424
|
+
throw new ConflictError("Connection superseded by newer request");
|
|
425
|
+
}
|
|
389
426
|
throw new Error("Failed to get SDP answer from local coordinator.");
|
|
390
427
|
}
|
|
391
428
|
const sdpAnswer = yield response.json();
|
|
@@ -404,15 +441,12 @@ var LocalCoordinatorClient = class extends CoordinatorClient {
|
|
|
404
441
|
};
|
|
405
442
|
|
|
406
443
|
// src/utils/webrtc.ts
|
|
407
|
-
var DEFAULT_ICE_SERVERS = [
|
|
408
|
-
{ urls: "stun:stun.l.google.com:19302" },
|
|
409
|
-
{ urls: "stun:stun1.l.google.com:19302" }
|
|
410
|
-
];
|
|
411
444
|
var DEFAULT_DATA_CHANNEL_LABEL = "data";
|
|
445
|
+
var FORCE_RELAY_MODE = false;
|
|
412
446
|
function createPeerConnection(config) {
|
|
413
|
-
var _a;
|
|
414
447
|
return new RTCPeerConnection({
|
|
415
|
-
iceServers:
|
|
448
|
+
iceServers: config.iceServers,
|
|
449
|
+
iceTransportPolicy: FORCE_RELAY_MODE ? "relay" : "all"
|
|
416
450
|
});
|
|
417
451
|
}
|
|
418
452
|
function createDataChannel(pc, label) {
|
|
@@ -493,7 +527,7 @@ var GPUMachineClient = class {
|
|
|
493
527
|
constructor(config) {
|
|
494
528
|
this.eventListeners = /* @__PURE__ */ new Map();
|
|
495
529
|
this.status = "disconnected";
|
|
496
|
-
this.config = config
|
|
530
|
+
this.config = config;
|
|
497
531
|
}
|
|
498
532
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
499
533
|
// Event Emitter API
|
|
@@ -890,9 +924,14 @@ var Reactor = class {
|
|
|
890
924
|
console.warn("[Reactor] No active session to reconnect to.");
|
|
891
925
|
return;
|
|
892
926
|
}
|
|
927
|
+
if (this.status === "ready") {
|
|
928
|
+
console.warn("[Reactor] Already connected, no need to reconnect.");
|
|
929
|
+
return;
|
|
930
|
+
}
|
|
893
931
|
this.setStatus("connecting");
|
|
894
932
|
if (!this.machineClient) {
|
|
895
|
-
|
|
933
|
+
const iceServers = yield this.coordinatorClient.getIceServers();
|
|
934
|
+
this.machineClient = new GPUMachineClient({ iceServers });
|
|
896
935
|
this.setupMachineClientHandlers();
|
|
897
936
|
}
|
|
898
937
|
const sdpOffer = yield this.machineClient.createOffer();
|
|
@@ -904,8 +943,12 @@ var Reactor = class {
|
|
|
904
943
|
yield this.machineClient.connect(sdpAnswer);
|
|
905
944
|
this.setStatus("ready");
|
|
906
945
|
} catch (error) {
|
|
946
|
+
let recoverable = false;
|
|
947
|
+
if (error instanceof ConflictError) {
|
|
948
|
+
recoverable = true;
|
|
949
|
+
}
|
|
907
950
|
console.error("[Reactor] Failed to reconnect:", error);
|
|
908
|
-
this.disconnect(
|
|
951
|
+
this.disconnect(recoverable);
|
|
909
952
|
this.createError(
|
|
910
953
|
"RECONNECTION_FAILED",
|
|
911
954
|
`Failed to reconnect: ${error}`,
|
|
@@ -940,7 +983,8 @@ var Reactor = class {
|
|
|
940
983
|
// Safe: validated on line 186-188
|
|
941
984
|
model: this.model
|
|
942
985
|
});
|
|
943
|
-
|
|
986
|
+
const iceServers = yield this.coordinatorClient.getIceServers();
|
|
987
|
+
this.machineClient = new GPUMachineClient({ iceServers });
|
|
944
988
|
this.setupMachineClientHandlers();
|
|
945
989
|
const sdpOffer = yield this.machineClient.createOffer();
|
|
946
990
|
const sessionId = yield this.coordinatorClient.createSession(sdpOffer);
|
|
@@ -2152,6 +2196,7 @@ function fetchInsecureJwtToken(_0) {
|
|
|
2152
2196
|
}
|
|
2153
2197
|
// Annotate the CommonJS export names for ESM import in node:
|
|
2154
2198
|
0 && (module.exports = {
|
|
2199
|
+
ConflictError,
|
|
2155
2200
|
PROD_COORDINATOR_URL,
|
|
2156
2201
|
Reactor,
|
|
2157
2202
|
ReactorController,
|