@decartai/sdk 0.0.44 → 0.0.46
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.ts +4 -2
- package/dist/realtime/client.d.ts +5 -3
- package/dist/realtime/client.js +68 -14
- package/dist/realtime/event-buffer.js +35 -0
- package/dist/realtime/methods.js +1 -1
- package/dist/realtime/subscribe-client.d.ts +22 -0
- package/dist/realtime/subscribe-client.js +20 -0
- package/dist/realtime/types.d.ts +5 -0
- package/dist/realtime/webrtc-connection.js +27 -7
- package/dist/realtime/webrtc-manager.js +10 -8
- package/package.json +1 -2
- package/dist/realtime/webrtc-connection.d.ts +0 -7
package/dist/index.d.ts
CHANGED
|
@@ -4,8 +4,9 @@ import { ProcessClient } from "./process/client.js";
|
|
|
4
4
|
import { JobStatus, JobStatusResponse, JobSubmitResponse, QueueJobResult, QueueSubmitAndPollOptions, QueueSubmitOptions } from "./queue/types.js";
|
|
5
5
|
import { QueueClient } from "./queue/client.js";
|
|
6
6
|
import { DecartSDKError, ERROR_CODES } from "./utils/errors.js";
|
|
7
|
-
import { ConnectionState } from "./realtime/
|
|
7
|
+
import { ConnectionState } from "./realtime/types.js";
|
|
8
8
|
import { SetInput } from "./realtime/methods.js";
|
|
9
|
+
import { RealTimeSubscribeClient, SubscribeEvents, SubscribeOptions } from "./realtime/subscribe-client.js";
|
|
9
10
|
import { AvatarOptions, Events, RealTimeClient, RealTimeClientConnectOptions, RealTimeClientInitialState } from "./realtime/client.js";
|
|
10
11
|
import { ModelState } from "./shared/types.js";
|
|
11
12
|
import { CreateTokenResponse, TokensClient } from "./tokens/client.js";
|
|
@@ -46,6 +47,7 @@ type DecartClientOptions = {
|
|
|
46
47
|
declare const createDecartClient: (options?: DecartClientOptions) => {
|
|
47
48
|
realtime: {
|
|
48
49
|
connect: (stream: MediaStream | null, options: RealTimeClientConnectOptions) => Promise<RealTimeClient>;
|
|
50
|
+
subscribe: (options: SubscribeOptions) => Promise<RealTimeSubscribeClient>;
|
|
49
51
|
};
|
|
50
52
|
/**
|
|
51
53
|
* Client for synchronous image generation.
|
|
@@ -119,4 +121,4 @@ declare const createDecartClient: (options?: DecartClientOptions) => {
|
|
|
119
121
|
tokens: TokensClient;
|
|
120
122
|
};
|
|
121
123
|
//#endregion
|
|
122
|
-
export { type AvatarOptions, type ConnectionState, type CreateTokenResponse, DecartClientOptions, type DecartSDKError, ERROR_CODES, type FileInput, type ImageModelDefinition, type ImageModels, type JobStatus, type JobStatusResponse, type JobSubmitResponse, type Model, type ModelDefinition, type ModelState, type ProcessClient, type ProcessOptions, type QueueClient, type QueueJobResult, type QueueSubmitAndPollOptions, type QueueSubmitOptions, type ReactNativeFile, type RealTimeClient, type RealTimeClientConnectOptions, type RealTimeClientInitialState, type Events as RealTimeEvents, type RealTimeModels, type SetInput, type TokensClient, type VideoModelDefinition, type VideoModels, createDecartClient, isImageModel, isRealtimeModel, isVideoModel, models };
|
|
124
|
+
export { type AvatarOptions, type ConnectionState, type CreateTokenResponse, DecartClientOptions, type DecartSDKError, ERROR_CODES, type FileInput, type ImageModelDefinition, type ImageModels, type JobStatus, type JobStatusResponse, type JobSubmitResponse, type Model, type ModelDefinition, type ModelState, type ProcessClient, type ProcessOptions, type QueueClient, type QueueJobResult, type QueueSubmitAndPollOptions, type QueueSubmitOptions, type ReactNativeFile, type RealTimeClient, type RealTimeClientConnectOptions, type RealTimeClientInitialState, type Events as RealTimeEvents, type RealTimeModels, type RealTimeSubscribeClient, type SetInput, type SubscribeEvents, type SubscribeOptions, type TokensClient, type VideoModelDefinition, type VideoModels, createDecartClient, isImageModel, isRealtimeModel, isVideoModel, models };
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { DecartSDKError } from "../utils/errors.js";
|
|
2
|
+
import { ConnectionState } from "./types.js";
|
|
2
3
|
import { SetInput } from "./methods.js";
|
|
3
4
|
import { z } from "zod";
|
|
4
5
|
|
|
@@ -40,7 +41,7 @@ declare const realTimeClientConnectOptionsSchema: z.ZodObject<{
|
|
|
40
41
|
}, z.core.$strip>;
|
|
41
42
|
type RealTimeClientConnectOptions = z.infer<typeof realTimeClientConnectOptionsSchema>;
|
|
42
43
|
type Events = {
|
|
43
|
-
connectionChange:
|
|
44
|
+
connectionChange: ConnectionState;
|
|
44
45
|
error: DecartSDKError;
|
|
45
46
|
};
|
|
46
47
|
type RealTimeClient = {
|
|
@@ -51,11 +52,12 @@ type RealTimeClient = {
|
|
|
51
52
|
enhance?: boolean;
|
|
52
53
|
}) => Promise<void>;
|
|
53
54
|
isConnected: () => boolean;
|
|
54
|
-
getConnectionState: () =>
|
|
55
|
+
getConnectionState: () => ConnectionState;
|
|
55
56
|
disconnect: () => void;
|
|
56
57
|
on: <K extends keyof Events>(event: K, listener: (data: Events[K]) => void) => void;
|
|
57
58
|
off: <K extends keyof Events>(event: K, listener: (data: Events[K]) => void) => void;
|
|
58
|
-
sessionId: string;
|
|
59
|
+
sessionId: string | null;
|
|
60
|
+
subscribeToken: string | null;
|
|
59
61
|
setImage: (image: Blob | File | string | null, options?: {
|
|
60
62
|
prompt?: string;
|
|
61
63
|
enhance?: boolean;
|
package/dist/realtime/client.js
CHANGED
|
@@ -2,11 +2,11 @@ import { createWebrtcError } from "../utils/errors.js";
|
|
|
2
2
|
import { modelDefinitionSchema } from "../shared/model.js";
|
|
3
3
|
import { modelStateSchema } from "../shared/types.js";
|
|
4
4
|
import { AudioStreamManager } from "./audio-stream-manager.js";
|
|
5
|
+
import { createEventBuffer } from "./event-buffer.js";
|
|
5
6
|
import { realtimeMethods } from "./methods.js";
|
|
7
|
+
import { decodeSubscribeToken, encodeSubscribeToken } from "./subscribe-client.js";
|
|
6
8
|
import { WebRTCManager } from "./webrtc-manager.js";
|
|
7
9
|
import { z } from "zod";
|
|
8
|
-
import mitt from "mitt";
|
|
9
|
-
import { v4 } from "uuid";
|
|
10
10
|
|
|
11
11
|
//#region src/realtime/client.ts
|
|
12
12
|
async function blobToBase64(blob) {
|
|
@@ -66,10 +66,8 @@ const realTimeClientConnectOptionsSchema = z.object({
|
|
|
66
66
|
const createRealTimeClient = (opts) => {
|
|
67
67
|
const { baseUrl, apiKey, integration } = opts;
|
|
68
68
|
const connect = async (stream, options) => {
|
|
69
|
-
const eventEmitter = mitt();
|
|
70
69
|
const parsedOptions = realTimeClientConnectOptionsSchema.safeParse(options);
|
|
71
70
|
if (!parsedOptions.success) throw parsedOptions.error;
|
|
72
|
-
const sessionId = v4();
|
|
73
71
|
const isAvatarLive = options.model.name === "live_avatar";
|
|
74
72
|
const { onRemoteStream, initialState, avatar } = parsedOptions.data;
|
|
75
73
|
let audioStreamManager;
|
|
@@ -90,16 +88,18 @@ const createRealTimeClient = (opts) => {
|
|
|
90
88
|
text: initialState.prompt.text,
|
|
91
89
|
enhance: initialState.prompt.enhance
|
|
92
90
|
} : void 0;
|
|
91
|
+
const url = `${baseUrl}${options.model.urlPath}`;
|
|
92
|
+
const { emitter: eventEmitter, emitOrBuffer, flush, stop } = createEventBuffer();
|
|
93
93
|
webrtcManager = new WebRTCManager({
|
|
94
|
-
webrtcUrl: `${
|
|
94
|
+
webrtcUrl: `${url}?api_key=${encodeURIComponent(apiKey)}&model=${encodeURIComponent(options.model.name)}`,
|
|
95
95
|
integration,
|
|
96
96
|
onRemoteStream,
|
|
97
97
|
onConnectionStateChange: (state) => {
|
|
98
|
-
|
|
98
|
+
emitOrBuffer("connectionChange", state);
|
|
99
99
|
},
|
|
100
100
|
onError: (error) => {
|
|
101
101
|
console.error("WebRTC error:", error);
|
|
102
|
-
|
|
102
|
+
emitOrBuffer("error", createWebrtcError(error));
|
|
103
103
|
},
|
|
104
104
|
customizeOffer: options.customizeOffer,
|
|
105
105
|
vp8MinBitrate: 300,
|
|
@@ -109,6 +109,13 @@ const createRealTimeClient = (opts) => {
|
|
|
109
109
|
initialPrompt
|
|
110
110
|
});
|
|
111
111
|
const manager = webrtcManager;
|
|
112
|
+
let sessionId = null;
|
|
113
|
+
let subscribeToken = null;
|
|
114
|
+
const sessionIdListener = (msg) => {
|
|
115
|
+
subscribeToken = encodeSubscribeToken(msg.session_id, msg.server_ip, msg.server_port);
|
|
116
|
+
sessionId = msg.session_id;
|
|
117
|
+
};
|
|
118
|
+
manager.getWebsocketMessageEmitter().on("sessionId", sessionIdListener);
|
|
112
119
|
await manager.connect(inputStream);
|
|
113
120
|
const methods = realtimeMethods(manager, imageToBase64);
|
|
114
121
|
if (!isAvatarLive && initialState?.prompt) {
|
|
@@ -121,22 +128,29 @@ const createRealTimeClient = (opts) => {
|
|
|
121
128
|
isConnected: () => manager.isConnected(),
|
|
122
129
|
getConnectionState: () => manager.getConnectionState(),
|
|
123
130
|
disconnect: () => {
|
|
131
|
+
stop();
|
|
124
132
|
manager.cleanup();
|
|
125
133
|
audioStreamManager?.cleanup();
|
|
126
134
|
},
|
|
127
135
|
on: eventEmitter.on,
|
|
128
136
|
off: eventEmitter.off,
|
|
129
|
-
sessionId
|
|
130
|
-
|
|
131
|
-
|
|
137
|
+
get sessionId() {
|
|
138
|
+
return sessionId;
|
|
139
|
+
},
|
|
140
|
+
get subscribeToken() {
|
|
141
|
+
return subscribeToken;
|
|
142
|
+
},
|
|
143
|
+
setImage: async (image, options) => {
|
|
144
|
+
if (image === null) return manager.setImage(null, options);
|
|
132
145
|
const base64 = await imageToBase64(image);
|
|
133
|
-
return manager.setImage(base64, options
|
|
146
|
+
return manager.setImage(base64, options);
|
|
134
147
|
}
|
|
135
148
|
};
|
|
136
149
|
if (isAvatarLive && audioStreamManager) {
|
|
137
|
-
const manager
|
|
138
|
-
client.playAudio = (audio) => manager
|
|
150
|
+
const manager = audioStreamManager;
|
|
151
|
+
client.playAudio = (audio) => manager.playAudio(audio);
|
|
139
152
|
}
|
|
153
|
+
flush();
|
|
140
154
|
return client;
|
|
141
155
|
} catch (error) {
|
|
142
156
|
webrtcManager?.cleanup();
|
|
@@ -144,7 +158,47 @@ const createRealTimeClient = (opts) => {
|
|
|
144
158
|
throw error;
|
|
145
159
|
}
|
|
146
160
|
};
|
|
147
|
-
|
|
161
|
+
const subscribe = async (options) => {
|
|
162
|
+
const { sid, ip, port } = decodeSubscribeToken(options.token);
|
|
163
|
+
const subscribeUrl = `${baseUrl}/subscribe/${encodeURIComponent(sid)}?IP=${encodeURIComponent(ip)}&port=${encodeURIComponent(port)}&api_key=${encodeURIComponent(apiKey)}`;
|
|
164
|
+
const { emitter: eventEmitter, emitOrBuffer, flush, stop } = createEventBuffer();
|
|
165
|
+
let webrtcManager;
|
|
166
|
+
try {
|
|
167
|
+
webrtcManager = new WebRTCManager({
|
|
168
|
+
webrtcUrl: subscribeUrl,
|
|
169
|
+
integration,
|
|
170
|
+
onRemoteStream: options.onRemoteStream,
|
|
171
|
+
onConnectionStateChange: (state) => {
|
|
172
|
+
emitOrBuffer("connectionChange", state);
|
|
173
|
+
},
|
|
174
|
+
onError: (error) => {
|
|
175
|
+
console.error("WebRTC subscribe error:", error);
|
|
176
|
+
emitOrBuffer("error", createWebrtcError(error));
|
|
177
|
+
}
|
|
178
|
+
});
|
|
179
|
+
const manager = webrtcManager;
|
|
180
|
+
await manager.connect(null);
|
|
181
|
+
const client = {
|
|
182
|
+
isConnected: () => manager.isConnected(),
|
|
183
|
+
getConnectionState: () => manager.getConnectionState(),
|
|
184
|
+
disconnect: () => {
|
|
185
|
+
stop();
|
|
186
|
+
manager.cleanup();
|
|
187
|
+
},
|
|
188
|
+
on: eventEmitter.on,
|
|
189
|
+
off: eventEmitter.off
|
|
190
|
+
};
|
|
191
|
+
flush();
|
|
192
|
+
return client;
|
|
193
|
+
} catch (error) {
|
|
194
|
+
webrtcManager?.cleanup();
|
|
195
|
+
throw error;
|
|
196
|
+
}
|
|
197
|
+
};
|
|
198
|
+
return {
|
|
199
|
+
connect,
|
|
200
|
+
subscribe
|
|
201
|
+
};
|
|
148
202
|
};
|
|
149
203
|
|
|
150
204
|
//#endregion
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import mitt from "mitt";
|
|
2
|
+
|
|
3
|
+
//#region src/realtime/event-buffer.ts
|
|
4
|
+
function createEventBuffer() {
|
|
5
|
+
const emitter = mitt();
|
|
6
|
+
const buffer = [];
|
|
7
|
+
let buffering = true;
|
|
8
|
+
const emitOrBuffer = (event, data) => {
|
|
9
|
+
if (buffering) buffer.push({
|
|
10
|
+
event,
|
|
11
|
+
data
|
|
12
|
+
});
|
|
13
|
+
else emitter.emit(event, data);
|
|
14
|
+
};
|
|
15
|
+
const flush = () => {
|
|
16
|
+
setTimeout(() => {
|
|
17
|
+
buffering = false;
|
|
18
|
+
for (const { event, data } of buffer) emitter.emit(event, data);
|
|
19
|
+
buffer.length = 0;
|
|
20
|
+
}, 0);
|
|
21
|
+
};
|
|
22
|
+
const stop = () => {
|
|
23
|
+
buffering = false;
|
|
24
|
+
buffer.length = 0;
|
|
25
|
+
};
|
|
26
|
+
return {
|
|
27
|
+
emitter,
|
|
28
|
+
emitOrBuffer,
|
|
29
|
+
flush,
|
|
30
|
+
stop
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
//#endregion
|
|
35
|
+
export { createEventBuffer };
|
package/dist/realtime/methods.js
CHANGED
|
@@ -20,7 +20,7 @@ const setPromptInputSchema = z.object({
|
|
|
20
20
|
const realtimeMethods = (webrtcManager, imageToBase64) => {
|
|
21
21
|
const assertConnected = () => {
|
|
22
22
|
const state = webrtcManager.getConnectionState();
|
|
23
|
-
if (state !== "connected") throw new Error(`Cannot send message: connection is ${state}`);
|
|
23
|
+
if (state !== "connected" && state !== "generating") throw new Error(`Cannot send message: connection is ${state}`);
|
|
24
24
|
};
|
|
25
25
|
const set = async (input) => {
|
|
26
26
|
assertConnected();
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { DecartSDKError } from "../utils/errors.js";
|
|
2
|
+
import { ConnectionState } from "./types.js";
|
|
3
|
+
|
|
4
|
+
//#region src/realtime/subscribe-client.d.ts
|
|
5
|
+
|
|
6
|
+
type SubscribeEvents = {
|
|
7
|
+
connectionChange: ConnectionState;
|
|
8
|
+
error: DecartSDKError;
|
|
9
|
+
};
|
|
10
|
+
type RealTimeSubscribeClient = {
|
|
11
|
+
isConnected: () => boolean;
|
|
12
|
+
getConnectionState: () => ConnectionState;
|
|
13
|
+
disconnect: () => void;
|
|
14
|
+
on: <K extends keyof SubscribeEvents>(event: K, listener: (data: SubscribeEvents[K]) => void) => void;
|
|
15
|
+
off: <K extends keyof SubscribeEvents>(event: K, listener: (data: SubscribeEvents[K]) => void) => void;
|
|
16
|
+
};
|
|
17
|
+
type SubscribeOptions = {
|
|
18
|
+
token: string;
|
|
19
|
+
onRemoteStream: (stream: MediaStream) => void;
|
|
20
|
+
};
|
|
21
|
+
//#endregion
|
|
22
|
+
export { RealTimeSubscribeClient, SubscribeEvents, SubscribeOptions };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
//#region src/realtime/subscribe-client.ts
|
|
2
|
+
function encodeSubscribeToken(sessionId, serverIp, serverPort) {
|
|
3
|
+
return btoa(JSON.stringify({
|
|
4
|
+
sid: sessionId,
|
|
5
|
+
ip: serverIp,
|
|
6
|
+
port: serverPort
|
|
7
|
+
}));
|
|
8
|
+
}
|
|
9
|
+
function decodeSubscribeToken(token) {
|
|
10
|
+
try {
|
|
11
|
+
const payload = JSON.parse(atob(token));
|
|
12
|
+
if (!payload.sid || !payload.ip || !payload.port) throw new Error("Invalid subscribe token format");
|
|
13
|
+
return payload;
|
|
14
|
+
} catch {
|
|
15
|
+
throw new Error("Invalid subscribe token");
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
//#endregion
|
|
20
|
+
export { decodeSubscribeToken, encodeSubscribeToken };
|
|
@@ -58,7 +58,7 @@ var WebRTCConnection = class {
|
|
|
58
58
|
await this.setupNewPeerConnection();
|
|
59
59
|
await Promise.race([new Promise((resolve, reject) => {
|
|
60
60
|
const checkConnection = setInterval(() => {
|
|
61
|
-
if (this.state === "connected") {
|
|
61
|
+
if (this.state === "connected" || this.state === "generating") {
|
|
62
62
|
clearInterval(checkConnection);
|
|
63
63
|
resolve();
|
|
64
64
|
} else if (this.state === "disconnected") {
|
|
@@ -94,6 +94,14 @@ var WebRTCConnection = class {
|
|
|
94
94
|
this.websocketMessagesEmitter.emit("promptAck", msg);
|
|
95
95
|
return;
|
|
96
96
|
}
|
|
97
|
+
if (msg.type === "generation_started") {
|
|
98
|
+
this.setState("generating");
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
if (msg.type === "session_id") {
|
|
102
|
+
this.websocketMessagesEmitter.emit("sessionId", msg);
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
97
105
|
if (!this.pc) return;
|
|
98
106
|
switch (msg.type) {
|
|
99
107
|
case "ready": {
|
|
@@ -221,7 +229,6 @@ var WebRTCConnection = class {
|
|
|
221
229
|
}
|
|
222
230
|
}
|
|
223
231
|
async setupNewPeerConnection(turnConfig) {
|
|
224
|
-
if (!this.localStream) throw new Error("No local stream found");
|
|
225
232
|
if (this.pc) {
|
|
226
233
|
this.pc.getSenders().forEach((sender) => {
|
|
227
234
|
if (sender.track && this.pc) this.pc.removeTrack(sender);
|
|
@@ -236,12 +243,23 @@ var WebRTCConnection = class {
|
|
|
236
243
|
});
|
|
237
244
|
this.pc = new RTCPeerConnection({ iceServers });
|
|
238
245
|
this.setState("connecting");
|
|
239
|
-
if (this.
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
246
|
+
if (this.localStream) {
|
|
247
|
+
if (this.callbacks.isAvatarLive) this.pc.addTransceiver("video", { direction: "recvonly" });
|
|
248
|
+
this.localStream.getTracks().forEach((track) => {
|
|
249
|
+
if (this.pc && this.localStream) this.pc.addTrack(track, this.localStream);
|
|
250
|
+
});
|
|
251
|
+
} else {
|
|
252
|
+
this.pc.addTransceiver("video", { direction: "recvonly" });
|
|
253
|
+
this.pc.addTransceiver("audio", { direction: "recvonly" });
|
|
254
|
+
}
|
|
255
|
+
let fallbackStream = null;
|
|
243
256
|
this.pc.ontrack = (e) => {
|
|
244
257
|
if (e.streams?.[0]) this.callbacks.onRemoteStream?.(e.streams[0]);
|
|
258
|
+
else {
|
|
259
|
+
if (!fallbackStream) fallbackStream = new MediaStream();
|
|
260
|
+
fallbackStream.addTrack(e.track);
|
|
261
|
+
this.callbacks.onRemoteStream?.(fallbackStream);
|
|
262
|
+
}
|
|
245
263
|
};
|
|
246
264
|
this.pc.onicecandidate = (e) => {
|
|
247
265
|
this.send({
|
|
@@ -252,7 +270,9 @@ var WebRTCConnection = class {
|
|
|
252
270
|
this.pc.onconnectionstatechange = () => {
|
|
253
271
|
if (!this.pc) return;
|
|
254
272
|
const s = this.pc.connectionState;
|
|
255
|
-
|
|
273
|
+
const nextState = s === "connected" ? "connected" : ["connecting", "new"].includes(s) ? "connecting" : "disconnected";
|
|
274
|
+
if (this.state === "generating" && nextState !== "disconnected") return;
|
|
275
|
+
this.setState(nextState);
|
|
256
276
|
};
|
|
257
277
|
this.pc.oniceconnectionstatechange = () => {
|
|
258
278
|
if (this.pc?.iceConnectionState === "failed") {
|
|
@@ -21,6 +21,7 @@ var WebRTCManager = class {
|
|
|
21
21
|
connection;
|
|
22
22
|
config;
|
|
23
23
|
localStream = null;
|
|
24
|
+
subscribeMode = false;
|
|
24
25
|
managerState = "disconnected";
|
|
25
26
|
hasConnected = false;
|
|
26
27
|
isReconnecting = false;
|
|
@@ -43,7 +44,7 @@ var WebRTCManager = class {
|
|
|
43
44
|
emitState(state) {
|
|
44
45
|
if (this.managerState !== state) {
|
|
45
46
|
this.managerState = state;
|
|
46
|
-
if (state === "connected") this.hasConnected = true;
|
|
47
|
+
if (state === "connected" || state === "generating") this.hasConnected = true;
|
|
47
48
|
this.config.onConnectionStateChange?.(state);
|
|
48
49
|
}
|
|
49
50
|
}
|
|
@@ -53,9 +54,9 @@ var WebRTCManager = class {
|
|
|
53
54
|
return;
|
|
54
55
|
}
|
|
55
56
|
if (this.isReconnecting) {
|
|
56
|
-
if (state === "connected") {
|
|
57
|
+
if (state === "connected" || state === "generating") {
|
|
57
58
|
this.isReconnecting = false;
|
|
58
|
-
this.emitState(
|
|
59
|
+
this.emitState(state);
|
|
59
60
|
}
|
|
60
61
|
return;
|
|
61
62
|
}
|
|
@@ -66,17 +67,17 @@ var WebRTCManager = class {
|
|
|
66
67
|
this.emitState(state);
|
|
67
68
|
}
|
|
68
69
|
async reconnect() {
|
|
69
|
-
if (this.isReconnecting || this.intentionalDisconnect
|
|
70
|
+
if (this.isReconnecting || this.intentionalDisconnect) return;
|
|
71
|
+
if (!this.subscribeMode && !this.localStream) return;
|
|
70
72
|
const reconnectGeneration = ++this.reconnectGeneration;
|
|
71
73
|
this.isReconnecting = true;
|
|
72
74
|
this.emitState("reconnecting");
|
|
73
75
|
try {
|
|
74
76
|
await pRetry(async () => {
|
|
75
77
|
if (this.intentionalDisconnect || reconnectGeneration !== this.reconnectGeneration) throw new AbortError("Reconnect cancelled");
|
|
76
|
-
|
|
77
|
-
if (!stream) throw new AbortError("Reconnect cancelled: no local stream");
|
|
78
|
+
if (!this.subscribeMode && !this.localStream) throw new AbortError("Reconnect cancelled: no local stream");
|
|
78
79
|
this.connection.cleanup();
|
|
79
|
-
await this.connection.connect(this.config.webrtcUrl,
|
|
80
|
+
await this.connection.connect(this.config.webrtcUrl, this.localStream, CONNECTION_TIMEOUT, this.config.integration);
|
|
80
81
|
if (this.intentionalDisconnect || reconnectGeneration !== this.reconnectGeneration) {
|
|
81
82
|
this.connection.cleanup();
|
|
82
83
|
throw new AbortError("Reconnect cancelled");
|
|
@@ -103,6 +104,7 @@ var WebRTCManager = class {
|
|
|
103
104
|
}
|
|
104
105
|
async connect(localStream) {
|
|
105
106
|
this.localStream = localStream;
|
|
107
|
+
this.subscribeMode = localStream === null;
|
|
106
108
|
this.intentionalDisconnect = false;
|
|
107
109
|
this.hasConnected = false;
|
|
108
110
|
this.isReconnecting = false;
|
|
@@ -137,7 +139,7 @@ var WebRTCManager = class {
|
|
|
137
139
|
this.emitState("disconnected");
|
|
138
140
|
}
|
|
139
141
|
isConnected() {
|
|
140
|
-
return this.managerState === "connected";
|
|
142
|
+
return this.managerState === "connected" || this.managerState === "generating";
|
|
141
143
|
}
|
|
142
144
|
getConnectionState() {
|
|
143
145
|
return this.managerState;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@decartai/sdk",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.46",
|
|
4
4
|
"description": "Decart's JavaScript SDK",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -43,7 +43,6 @@
|
|
|
43
43
|
"dependencies": {
|
|
44
44
|
"mitt": "^3.0.1",
|
|
45
45
|
"p-retry": "^6.2.1",
|
|
46
|
-
"uuid": "^13.0.0",
|
|
47
46
|
"zod": "^4.0.17"
|
|
48
47
|
},
|
|
49
48
|
"scripts": {
|