@decartai/sdk 0.1.0 → 0.1.1
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/files/client.d.ts +33 -0
- package/dist/files/client.js +65 -0
- package/dist/files/types.d.ts +22 -0
- package/dist/files/types.js +4 -0
- package/dist/index.d.ts +14 -1
- package/dist/index.js +8 -1
- package/dist/realtime/client.d.ts +6 -0
- package/dist/realtime/client.js +16 -3
- package/dist/realtime/methods.js +15 -3
- package/dist/realtime/signaling-channel.js +20 -4
- package/dist/realtime/stream-session.js +7 -2
- package/dist/utils/errors.d.ts +3 -0
- package/dist/utils/errors.js +3 -0
- package/package.json +1 -1
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { FileReference, FileUploadInput } from "./types.js";
|
|
2
|
+
|
|
3
|
+
//#region src/files/client.d.ts
|
|
4
|
+
|
|
5
|
+
type UploadFileOptions = {
|
|
6
|
+
signal?: AbortSignal;
|
|
7
|
+
/**
|
|
8
|
+
* Expiration:
|
|
9
|
+
* - omit → platform default (24 h)
|
|
10
|
+
* - a positive integer → TTL in seconds (60 .. 2_592_000)
|
|
11
|
+
* - `"persistent"` → never expires
|
|
12
|
+
*/
|
|
13
|
+
ttlSeconds?: number | "persistent";
|
|
14
|
+
};
|
|
15
|
+
type FilesClient = {
|
|
16
|
+
/**
|
|
17
|
+
* Upload a file once and get a reusable reference. Pass `ref.id` to
|
|
18
|
+
* realtime `set({ image })` to reuse the same asset across generations
|
|
19
|
+
* without re-uploading.
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```ts
|
|
23
|
+
* const ref = await client.files.upload(blob);
|
|
24
|
+
* await rt.set({ image: ref.id, prompt: "make it cinematic" });
|
|
25
|
+
* await rt.set({ image: ref.id, prompt: "now in noir" }); // reused, no re-upload
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
upload: (file: FileUploadInput, options?: UploadFileOptions) => Promise<FileReference>;
|
|
29
|
+
get: (fileId: string) => Promise<FileReference>;
|
|
30
|
+
delete: (fileId: string) => Promise<void>;
|
|
31
|
+
};
|
|
32
|
+
//#endregion
|
|
33
|
+
export { FilesClient, UploadFileOptions };
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { createInvalidInputError, createSDKError } from "../utils/errors.js";
|
|
2
|
+
import { buildAuthHeaders } from "../shared/request.js";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
//#region src/files/client.ts
|
|
5
|
+
const MAX_TTL_SECONDS = 720 * 60 * 60;
|
|
6
|
+
const ttlSecondsSchema = z.union([z.number().int().min(60).max(MAX_TTL_SECONDS), z.literal("persistent")]);
|
|
7
|
+
const createFilesClient = (opts) => {
|
|
8
|
+
const { baseUrl, apiKey, integration } = opts;
|
|
9
|
+
const upload = async (file, options) => {
|
|
10
|
+
if (options?.ttlSeconds !== void 0) {
|
|
11
|
+
if (!ttlSecondsSchema.safeParse(options.ttlSeconds).success) throw createInvalidInputError(`ttlSeconds must be an integer in [60, ${MAX_TTL_SECONDS}] or the literal "persistent"`);
|
|
12
|
+
}
|
|
13
|
+
const formData = new FormData();
|
|
14
|
+
formData.append("file", file);
|
|
15
|
+
if (options?.ttlSeconds !== void 0) formData.append("ttl_seconds", String(options.ttlSeconds));
|
|
16
|
+
const response = await fetch(`${baseUrl}/v1/files`, {
|
|
17
|
+
method: "POST",
|
|
18
|
+
headers: buildAuthHeaders({
|
|
19
|
+
apiKey,
|
|
20
|
+
integration
|
|
21
|
+
}),
|
|
22
|
+
body: formData,
|
|
23
|
+
signal: options?.signal
|
|
24
|
+
});
|
|
25
|
+
if (!response.ok) {
|
|
26
|
+
const errorText = await response.text().catch(() => "Unknown error");
|
|
27
|
+
throw createSDKError("FILES_UPLOAD_ERROR", `Failed to upload file: ${response.status} - ${errorText}`, { status: response.status });
|
|
28
|
+
}
|
|
29
|
+
return response.json();
|
|
30
|
+
};
|
|
31
|
+
const get = async (fileId) => {
|
|
32
|
+
const response = await fetch(`${baseUrl}/v1/files/${encodeURIComponent(fileId)}`, {
|
|
33
|
+
method: "GET",
|
|
34
|
+
headers: buildAuthHeaders({
|
|
35
|
+
apiKey,
|
|
36
|
+
integration
|
|
37
|
+
})
|
|
38
|
+
});
|
|
39
|
+
if (!response.ok) {
|
|
40
|
+
const errorText = await response.text().catch(() => "Unknown error");
|
|
41
|
+
throw createSDKError("FILES_GET_ERROR", `Failed to get file: ${response.status} - ${errorText}`, { status: response.status });
|
|
42
|
+
}
|
|
43
|
+
return response.json();
|
|
44
|
+
};
|
|
45
|
+
const deleteFile = async (fileId) => {
|
|
46
|
+
const response = await fetch(`${baseUrl}/v1/files/${encodeURIComponent(fileId)}`, {
|
|
47
|
+
method: "DELETE",
|
|
48
|
+
headers: buildAuthHeaders({
|
|
49
|
+
apiKey,
|
|
50
|
+
integration
|
|
51
|
+
})
|
|
52
|
+
});
|
|
53
|
+
if (!response.ok) {
|
|
54
|
+
const errorText = await response.text().catch(() => "Unknown error");
|
|
55
|
+
throw createSDKError("FILES_DELETE_ERROR", `Failed to delete file: ${response.status} - ${errorText}`, { status: response.status });
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
return {
|
|
59
|
+
upload,
|
|
60
|
+
get,
|
|
61
|
+
delete: deleteFile
|
|
62
|
+
};
|
|
63
|
+
};
|
|
64
|
+
//#endregion
|
|
65
|
+
export { createFilesClient };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { ReactNativeFile } from "../process/types.js";
|
|
2
|
+
|
|
3
|
+
//#region src/files/types.d.ts
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Metadata for a previously-uploaded file. Returned by `client.files.upload(...)`.
|
|
7
|
+
* Pass `ref.id` to `realtime.set({ image })` / `setImage(...)` to reuse it.
|
|
8
|
+
*
|
|
9
|
+
* Files expire after a server-configured TTL (default 24 h). `expires_at` is
|
|
10
|
+
* `null` when the upload was created with `persistent: true`.
|
|
11
|
+
*/
|
|
12
|
+
interface FileReference {
|
|
13
|
+
id: string;
|
|
14
|
+
filename: string | null;
|
|
15
|
+
mime_type: string;
|
|
16
|
+
size_bytes: number;
|
|
17
|
+
created_at: string;
|
|
18
|
+
expires_at: string | null;
|
|
19
|
+
}
|
|
20
|
+
type FileUploadInput = File | Blob | ReactNativeFile;
|
|
21
|
+
//#endregion
|
|
22
|
+
export { FileReference, FileUploadInput };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { LogLevel, Logger, createConsoleLogger, noopLogger } from "./utils/logger.js";
|
|
2
2
|
import { CanonicalModel, CustomModelDefinition, ImageModelDefinition, ImageModels, ListedModelDefinition, Model, ModelDefinition, ModelKind, RealTimeModels, VideoModelDefinition, VideoModels, isCanonicalModel, isImageModel, isModel, isRealtimeModel, isVideoModel, listModels, modelAliases, models, resolveCanonicalModelAlias, resolveModelAlias } from "./shared/model.js";
|
|
3
3
|
import { FileInput, ProcessOptions, ReactNativeFile } from "./process/types.js";
|
|
4
|
+
import { FileReference, FileUploadInput } from "./files/types.js";
|
|
5
|
+
import { FilesClient, UploadFileOptions } from "./files/client.js";
|
|
4
6
|
import { ProcessClient } from "./process/client.js";
|
|
5
7
|
import { JobStatus, JobStatusResponse, JobSubmitResponse, QueueJobResult, QueueSubmitAndPollOptions, QueueSubmitOptions } from "./queue/types.js";
|
|
6
8
|
import { QueueClient } from "./queue/client.js";
|
|
@@ -134,6 +136,17 @@ declare const createDecartClient: (options?: DecartClientOptions) => {
|
|
|
134
136
|
* ```
|
|
135
137
|
*/
|
|
136
138
|
tokens: TokensClient;
|
|
139
|
+
/**
|
|
140
|
+
* Upload files once and reuse them across generations.
|
|
141
|
+
*
|
|
142
|
+
* @example
|
|
143
|
+
* ```ts
|
|
144
|
+
* const ref = await client.files.upload(blob);
|
|
145
|
+
* await rt.set({ image: ref.id, prompt: "make it cinematic" });
|
|
146
|
+
* await rt.set({ image: ref.id, prompt: "now in noir" });
|
|
147
|
+
* ```
|
|
148
|
+
*/
|
|
149
|
+
files: FilesClient;
|
|
137
150
|
};
|
|
138
151
|
//#endregion
|
|
139
|
-
export { type CanonicalModel, type ClientSessionConnectionBreakdownEvent, type ClientSessionConnectionBreakdownPhase, type ConnectionState, type CreateTokenOptions, type CreateTokenResponse, type CustomModelDefinition, DecartClientOptions, type DecartSDKError, type DiagnosticEvent, type DiagnosticEventName, type DiagnosticEvents, ERROR_CODES, type FileInput, type GenerationEndedMessage, type ImageModelDefinition, type ImageModels, type JobStatus, type JobStatusResponse, type JobSubmitResponse, type ListedModelDefinition, type LogLevel, type Logger, type Model, type ModelDefinition, type ModelKind, type ModelState, type ProcessClient, type ProcessOptions, type QueueClient, type QueueJobResult, type QueuePosition, type QueuePositionMessage, type QueueSubmitAndPollOptions, type QueueSubmitOptions, type ReactNativeFile, type RealTimeClient, type RealTimeClientConnectOptions, type RealTimeClientInitialState, type Events as RealTimeEvents, type RealTimeModels, type RealTimeSubscribeClient, type ReconnectEvent, type SetInput, type SubscribeEvents, type SubscribeOptions, type TokensClient, type VideoModelDefinition, type VideoModels, type VideoStallEvent, type WebRTCStats, createConsoleLogger, createDecartClient, isCanonicalModel, isImageModel, isModel, isRealtimeModel, isVideoModel, listModels, modelAliases, models, noopLogger, resolveCanonicalModelAlias, resolveModelAlias };
|
|
152
|
+
export { type CanonicalModel, type ClientSessionConnectionBreakdownEvent, type ClientSessionConnectionBreakdownPhase, type ConnectionState, type CreateTokenOptions, type CreateTokenResponse, type CustomModelDefinition, DecartClientOptions, type DecartSDKError, type DiagnosticEvent, type DiagnosticEventName, type DiagnosticEvents, ERROR_CODES, type FileInput, type FileReference, type FileUploadInput, type FilesClient, type GenerationEndedMessage, type ImageModelDefinition, type ImageModels, type JobStatus, type JobStatusResponse, type JobSubmitResponse, type ListedModelDefinition, type LogLevel, type Logger, type Model, type ModelDefinition, type ModelKind, type ModelState, type ProcessClient, type ProcessOptions, type QueueClient, type QueueJobResult, type QueuePosition, type QueuePositionMessage, type QueueSubmitAndPollOptions, type QueueSubmitOptions, type ReactNativeFile, type RealTimeClient, type RealTimeClientConnectOptions, type RealTimeClientInitialState, type Events as RealTimeEvents, type RealTimeModels, type RealTimeSubscribeClient, type ReconnectEvent, type SetInput, type SubscribeEvents, type SubscribeOptions, type TokensClient, type UploadFileOptions, type VideoModelDefinition, type VideoModels, type VideoStallEvent, type WebRTCStats, createConsoleLogger, createDecartClient, isCanonicalModel, isImageModel, isModel, isRealtimeModel, isVideoModel, listModels, modelAliases, models, noopLogger, resolveCanonicalModelAlias, resolveModelAlias };
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ERROR_CODES, createInvalidApiKeyError, createInvalidBaseUrlError } from "./utils/errors.js";
|
|
2
|
+
import { createFilesClient } from "./files/client.js";
|
|
2
3
|
import { createProcessClient } from "./process/client.js";
|
|
3
4
|
import { createQueueClient } from "./queue/client.js";
|
|
4
5
|
import { isCanonicalModel, isImageModel, isModel, isRealtimeModel, isVideoModel, listModels, modelAliases, models, resolveCanonicalModelAlias, resolveModelAlias } from "./shared/model.js";
|
|
@@ -92,6 +93,11 @@ const createDecartClient = (options = {}) => {
|
|
|
92
93
|
apiKey: apiKey || "",
|
|
93
94
|
integration
|
|
94
95
|
});
|
|
96
|
+
const files = createFilesClient({
|
|
97
|
+
baseUrl,
|
|
98
|
+
apiKey: apiKey || "",
|
|
99
|
+
integration
|
|
100
|
+
});
|
|
95
101
|
return {
|
|
96
102
|
realtime: {
|
|
97
103
|
connect: realtimePublish.connect,
|
|
@@ -99,7 +105,8 @@ const createDecartClient = (options = {}) => {
|
|
|
99
105
|
},
|
|
100
106
|
process,
|
|
101
107
|
queue,
|
|
102
|
-
tokens
|
|
108
|
+
tokens,
|
|
109
|
+
files
|
|
103
110
|
};
|
|
104
111
|
};
|
|
105
112
|
//#endregion
|
|
@@ -78,6 +78,12 @@ type RealTimeClient = {
|
|
|
78
78
|
sessionId: string | null;
|
|
79
79
|
subscribeToken: string | null;
|
|
80
80
|
getSubscribeToken: () => string | null;
|
|
81
|
+
/**
|
|
82
|
+
* Set the reference image for the session.
|
|
83
|
+
* - `Blob`/`File`/data URL/http(s) URL/base64 string: bytes traverse the wire as base64.
|
|
84
|
+
* - `"file_..."` id (from `client.files.upload(...).id`): sent as a server-side reference.
|
|
85
|
+
* - `null`: clear the current image.
|
|
86
|
+
*/
|
|
81
87
|
setImage: (image: Blob | File | string | null, options?: ImageSetOptions) => Promise<void>;
|
|
82
88
|
};
|
|
83
89
|
//#endregion
|
package/dist/realtime/client.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { classifyWebrtcError } from "../utils/errors.js";
|
|
2
|
+
import { isFileRefId } from "../files/types.js";
|
|
2
3
|
import { modelDefinitionSchema, resolveFpsNumber } from "../shared/model.js";
|
|
3
4
|
import { modelStateSchema } from "../shared/types.js";
|
|
4
5
|
import { createConsoleLogger } from "../utils/logger.js";
|
|
@@ -44,7 +45,8 @@ const createRealTimeClient = (opts) => {
|
|
|
44
45
|
let session;
|
|
45
46
|
let observability;
|
|
46
47
|
try {
|
|
47
|
-
const
|
|
48
|
+
const initialImageRef = isFileRefId(initialState?.image) ? initialState.image : void 0;
|
|
49
|
+
const initialImage = initialImageRef === void 0 && initialState?.image ? await imageToBase64(initialState.image) : void 0;
|
|
48
50
|
const initialPrompt = initialState?.prompt ? {
|
|
49
51
|
text: initialState.prompt.text,
|
|
50
52
|
enhance: initialState.prompt.enhance
|
|
@@ -73,6 +75,7 @@ const createRealTimeClient = (opts) => {
|
|
|
73
75
|
observability,
|
|
74
76
|
localStream: inputStream,
|
|
75
77
|
initialImage,
|
|
78
|
+
initialImageRef,
|
|
76
79
|
initialPrompt,
|
|
77
80
|
logger,
|
|
78
81
|
videoCodec: safariCodec
|
|
@@ -121,9 +124,19 @@ const createRealTimeClient = (opts) => {
|
|
|
121
124
|
},
|
|
122
125
|
getSubscribeToken: () => subscribeToken,
|
|
123
126
|
setImage: async (image, imgOptions) => {
|
|
124
|
-
if (image
|
|
127
|
+
if (isFileRefId(image)) return activeSession.setImage({
|
|
128
|
+
kind: "ref",
|
|
129
|
+
ref: image
|
|
130
|
+
}, imgOptions);
|
|
131
|
+
if (image === null) return activeSession.setImage({
|
|
132
|
+
kind: "data",
|
|
133
|
+
data: null
|
|
134
|
+
}, imgOptions);
|
|
125
135
|
const base64 = await imageToBase64(image);
|
|
126
|
-
return activeSession.setImage(
|
|
136
|
+
return activeSession.setImage({
|
|
137
|
+
kind: "data",
|
|
138
|
+
data: base64
|
|
139
|
+
}, imgOptions);
|
|
127
140
|
}
|
|
128
141
|
};
|
|
129
142
|
flush();
|
package/dist/realtime/methods.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { isFileRefId } from "../files/types.js";
|
|
1
2
|
import { REALTIME_CONFIG } from "./config-realtime.js";
|
|
2
3
|
import { z } from "zod";
|
|
3
4
|
//#region src/realtime/methods.ts
|
|
@@ -20,12 +21,23 @@ const realtimeMethods = (session, imageToBase64) => {
|
|
|
20
21
|
const parsed = setInputSchema.safeParse(input);
|
|
21
22
|
if (!parsed.success) throw parsed.error;
|
|
22
23
|
const { prompt, enhance, image } = parsed.data;
|
|
23
|
-
const
|
|
24
|
-
await session.setImage(imageBase64, {
|
|
24
|
+
const options = {
|
|
25
25
|
prompt,
|
|
26
26
|
enhance,
|
|
27
27
|
timeout: REALTIME_CONFIG.methods.updateTimeoutMs
|
|
28
|
-
}
|
|
28
|
+
};
|
|
29
|
+
if (isFileRefId(image)) {
|
|
30
|
+
await session.setImage({
|
|
31
|
+
kind: "ref",
|
|
32
|
+
ref: image
|
|
33
|
+
}, options);
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
const imageBase64 = image !== void 0 && image !== null ? await imageToBase64(image) : null;
|
|
37
|
+
await session.setImage({
|
|
38
|
+
kind: "data",
|
|
39
|
+
data: imageBase64
|
|
40
|
+
}, options);
|
|
29
41
|
};
|
|
30
42
|
const setPrompt = async (prompt, { enhance } = {}) => {
|
|
31
43
|
const parsed = setPromptInputSchema.safeParse({
|
|
@@ -79,10 +79,13 @@ var SignalingChannel = class {
|
|
|
79
79
|
});
|
|
80
80
|
if (!ack.success) throw new Error(ack.error ?? "Failed to send prompt");
|
|
81
81
|
}
|
|
82
|
-
async setImage(
|
|
83
|
-
const message = {
|
|
82
|
+
async setImage(payload, opts = {}) {
|
|
83
|
+
const message = payload.kind === "ref" ? {
|
|
84
84
|
type: "set_image",
|
|
85
|
-
|
|
85
|
+
image_ref: payload.ref
|
|
86
|
+
} : {
|
|
87
|
+
type: "set_image",
|
|
88
|
+
image_data: payload.data
|
|
86
89
|
};
|
|
87
90
|
if (opts.prompt !== void 0) message.prompt = opts.prompt;
|
|
88
91
|
if (opts.enhance !== void 0) message.enhance_prompt = opts.enhance;
|
|
@@ -179,8 +182,21 @@ var SignalingChannel = class {
|
|
|
179
182
|
}
|
|
180
183
|
async sendInitialState(initialState) {
|
|
181
184
|
if (!initialState) return;
|
|
185
|
+
if (initialState.imageRef !== void 0) {
|
|
186
|
+
await this.setImage({
|
|
187
|
+
kind: "ref",
|
|
188
|
+
ref: initialState.imageRef
|
|
189
|
+
}, {
|
|
190
|
+
prompt: initialState.prompt,
|
|
191
|
+
enhance: initialState.enhance
|
|
192
|
+
});
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
182
195
|
if (initialState.image !== void 0) {
|
|
183
|
-
await this.setImage(
|
|
196
|
+
await this.setImage({
|
|
197
|
+
kind: "data",
|
|
198
|
+
data: initialState.image
|
|
199
|
+
}, {
|
|
184
200
|
prompt: initialState.prompt,
|
|
185
201
|
enhance: initialState.enhance
|
|
186
202
|
});
|
|
@@ -68,9 +68,9 @@ var StreamSession = class {
|
|
|
68
68
|
this.assertConnected();
|
|
69
69
|
return this.signaling.sendPrompt(text, opts);
|
|
70
70
|
}
|
|
71
|
-
async setImage(
|
|
71
|
+
async setImage(payload, opts) {
|
|
72
72
|
this.assertConnected();
|
|
73
|
-
return this.signaling.setImage(
|
|
73
|
+
return this.signaling.setImage(payload, opts);
|
|
74
74
|
}
|
|
75
75
|
disconnect() {
|
|
76
76
|
this.disposed = true;
|
|
@@ -141,6 +141,11 @@ var StreamSession = class {
|
|
|
141
141
|
}
|
|
142
142
|
}
|
|
143
143
|
getInitialState() {
|
|
144
|
+
if (this.config.initialImageRef !== void 0) return {
|
|
145
|
+
imageRef: this.config.initialImageRef,
|
|
146
|
+
prompt: this.config.initialPrompt?.text,
|
|
147
|
+
enhance: this.config.initialPrompt?.enhance
|
|
148
|
+
};
|
|
144
149
|
if (this.config.initialImage !== void 0) return {
|
|
145
150
|
image: this.config.initialImage,
|
|
146
151
|
prompt: this.config.initialPrompt?.text,
|
package/dist/utils/errors.d.ts
CHANGED
|
@@ -17,6 +17,9 @@ declare const ERROR_CODES: {
|
|
|
17
17
|
readonly QUEUE_RESULT_ERROR: "QUEUE_RESULT_ERROR";
|
|
18
18
|
readonly JOB_NOT_COMPLETED: "JOB_NOT_COMPLETED";
|
|
19
19
|
readonly TOKEN_CREATE_ERROR: "TOKEN_CREATE_ERROR";
|
|
20
|
+
readonly FILES_UPLOAD_ERROR: "FILES_UPLOAD_ERROR";
|
|
21
|
+
readonly FILES_GET_ERROR: "FILES_GET_ERROR";
|
|
22
|
+
readonly FILES_DELETE_ERROR: "FILES_DELETE_ERROR";
|
|
20
23
|
readonly WEBRTC_WEBSOCKET_ERROR: "WEBRTC_WEBSOCKET_ERROR";
|
|
21
24
|
readonly WEBRTC_ICE_ERROR: "WEBRTC_ICE_ERROR";
|
|
22
25
|
readonly WEBRTC_TIMEOUT_ERROR: "WEBRTC_TIMEOUT_ERROR";
|
package/dist/utils/errors.js
CHANGED
|
@@ -11,6 +11,9 @@ const ERROR_CODES = {
|
|
|
11
11
|
QUEUE_RESULT_ERROR: "QUEUE_RESULT_ERROR",
|
|
12
12
|
JOB_NOT_COMPLETED: "JOB_NOT_COMPLETED",
|
|
13
13
|
TOKEN_CREATE_ERROR: "TOKEN_CREATE_ERROR",
|
|
14
|
+
FILES_UPLOAD_ERROR: "FILES_UPLOAD_ERROR",
|
|
15
|
+
FILES_GET_ERROR: "FILES_GET_ERROR",
|
|
16
|
+
FILES_DELETE_ERROR: "FILES_DELETE_ERROR",
|
|
14
17
|
WEBRTC_WEBSOCKET_ERROR: "WEBRTC_WEBSOCKET_ERROR",
|
|
15
18
|
WEBRTC_ICE_ERROR: "WEBRTC_ICE_ERROR",
|
|
16
19
|
WEBRTC_TIMEOUT_ERROR: "WEBRTC_TIMEOUT_ERROR",
|