@decartai/sdk 0.1.13 → 0.1.14

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.
Files changed (42) hide show
  1. package/README.md +85 -1
  2. package/dist/create-client.d.ts +46 -0
  3. package/dist/create-client.js +106 -0
  4. package/dist/index.d.ts +8 -150
  5. package/dist/index.js +6 -116
  6. package/dist/index.react-native.d.ts +36 -0
  7. package/dist/index.react-native.js +9 -0
  8. package/dist/realtime/browser/glass-to-glass-diagnostics.js +27 -0
  9. package/dist/realtime/{observability → browser}/glass-to-glass.js +2 -19
  10. package/dist/realtime/browser/index.js +32 -0
  11. package/dist/realtime/{mirror-stream.js → browser/mirror-stream.js} +1 -1
  12. package/dist/realtime/{observability → browser}/pixel-marker.js +1 -1
  13. package/dist/realtime/{preflight.js → browser/preflight.js} +14 -108
  14. package/dist/realtime/browser/prepare-connection.js +39 -0
  15. package/dist/realtime/client.d.ts +11 -4
  16. package/dist/realtime/client.js +33 -37
  17. package/dist/realtime/livekit.js +26 -0
  18. package/dist/realtime/media-channel.js +17 -10
  19. package/dist/realtime/methods.d.ts +1 -1
  20. package/dist/realtime/methods.js +3 -2
  21. package/dist/realtime/observability/g2g.d.ts +14 -0
  22. package/dist/realtime/observability/realtime-observability.js +8 -18
  23. package/dist/realtime/observability/webrtc-stats.d.ts +1 -1
  24. package/dist/realtime/preflight-connectivity.js +102 -0
  25. package/dist/realtime/preflight-types.d.ts +30 -0
  26. package/dist/realtime/react-native/index.js +36 -0
  27. package/dist/realtime/react-native/preflight.js +10 -0
  28. package/dist/realtime/react-native/prepare-connection.js +26 -0
  29. package/dist/realtime/stream-session.js +1 -2
  30. package/dist/realtime/subscribe-client.js +10 -9
  31. package/dist/shared/model.d.ts +36 -36
  32. package/dist/shared/model.js +5 -17
  33. package/dist/shared/request.js +5 -4
  34. package/dist/shared/types.d.ts +1 -1
  35. package/dist/shared/types.js +3 -2
  36. package/dist/utils/errors.d.ts +3 -0
  37. package/dist/utils/errors.js +16 -1
  38. package/dist/utils/platform.js +17 -1
  39. package/dist/utils/runtime.js +13 -0
  40. package/package.json +10 -3
  41. package/dist/realtime/observability/glass-to-glass.d.ts +0 -41
  42. package/dist/realtime/preflight.d.ts +0 -59
package/README.md CHANGED
@@ -243,6 +243,90 @@ if (status.status === "completed") {
243
243
  }
244
244
  ```
245
245
 
246
+ ### React Native / Expo
247
+
248
+ React Native realtime requires [LiveKit's React Native packages](https://github.com/livekit/client-sdk-react-native)
249
+ and an early `registerGlobals()` call. Plain `react-native-webrtc` is not
250
+ supported. SDK imports and `createDecartClient(...)` usage stay the same.
251
+
252
+ ```sh
253
+ npm install @decartai/sdk livekit-client@2.20.1 \
254
+ @livekit/react-native@2.11.1 \
255
+ @livekit/react-native-webrtc@144.1.1
256
+ ```
257
+
258
+ Call LiveKit setup from a side-effect module that runs before your router or app
259
+ entrypoint:
260
+
261
+ ```ts
262
+ // livekit-bootstrap.ts
263
+ import { registerGlobals } from "@livekit/react-native";
264
+
265
+ registerGlobals();
266
+ ```
267
+
268
+ ```ts
269
+ // index.ts
270
+ import "./livekit-bootstrap";
271
+ import "expo-router/entry"; // or import your root App component
272
+ ```
273
+
274
+ With the globals registered, realtime usage is the same as on the web. Use the
275
+ model's numeric FPS when configuring native camera capture, then pass that
276
+ `MediaStream` to the SDK:
277
+
278
+ ```ts
279
+ import { createDecartClient, models, resolveFpsNumber } from "@decartai/sdk";
280
+ import { mediaDevices } from "@livekit/react-native-webrtc";
281
+
282
+ const client = createDecartClient({ apiKey: "your-api-key-here" });
283
+ const model = models.realtime("lucy-2.5");
284
+ const captureFps = resolveFpsNumber(model.fps);
285
+
286
+ const cameraStream = await mediaDevices.getUserMedia({
287
+ audio: false,
288
+ video: {
289
+ facingMode: "user",
290
+ frameRate: captureFps,
291
+ width: model.width,
292
+ height: model.height,
293
+ },
294
+ });
295
+
296
+ const realtimeClient = await client.realtime.connect(cameraStream, {
297
+ model,
298
+ preferredVideoCodec: "vp8",
299
+ onRemoteStream,
300
+ });
301
+ ```
302
+
303
+ For Expo, install the config plugins:
304
+
305
+ ```sh
306
+ npm install @livekit/react-native-expo-plugin@1.0.2 \
307
+ @config-plugins/react-native-webrtc
308
+ ```
309
+
310
+ Add them to `app.json`:
311
+
312
+ ```json
313
+ {
314
+ "expo": {
315
+ "plugins": [
316
+ "@livekit/react-native-expo-plugin",
317
+ "@config-plugins/react-native-webrtc"
318
+ ]
319
+ }
320
+ }
321
+ ```
322
+
323
+ Run `npx expo prebuild` and rebuild the native app. LiveKit does not run in Expo
324
+ Go. Bare React Native apps must follow LiveKit's native setup instructions.
325
+
326
+ Outgoing `mirror`, `debugQuality`, and deep connectivity preflight are browser-only
327
+ and fail with `UNSUPPORTED_PLATFORM_FEATURE` on React Native. Mirror the local
328
+ preview with your native video view instead.
329
+
246
330
  ## Development
247
331
 
248
332
  ### Setup
@@ -273,4 +357,4 @@ The package is published to npm as `@decartai/sdk`.
273
357
 
274
358
  ## License
275
359
 
276
- MIT
360
+ MIT
@@ -0,0 +1,46 @@
1
+ import { Logger } from "./utils/logger.js";
2
+
3
+ //#region src/create-client.d.ts
4
+ type DecartClientOptions = {
5
+ proxy: string;
6
+ apiKey?: never;
7
+ baseUrl?: string;
8
+ realtimeBaseUrl?: string;
9
+ integration?: string;
10
+ logger?: Logger;
11
+ telemetry?: boolean;
12
+ } | {
13
+ proxy?: never;
14
+ apiKey?: string;
15
+ baseUrl?: string;
16
+ realtimeBaseUrl?: string;
17
+ integration?: string;
18
+ logger?: Logger;
19
+ telemetry?: boolean;
20
+ };
21
+ /**
22
+ * Create a Decart API client.
23
+ *
24
+ * @param options - Configuration options
25
+ * @param options.proxy - URL of the proxy server. When set, the client will use the proxy instead of direct API access and apiKey is not required.
26
+ * @param options.apiKey - API key for authentication.
27
+ * @param options.baseUrl - Override the default API base URL.
28
+ * @param options.realtimeBaseUrl - Override the default WebSocket base URL for realtime connections.
29
+ * @param options.integration - Optional integration identifier.
30
+ *
31
+ * Realtime media uses LiveKit only (inference must enable it in `TRANSPORTS_ENABLED`).
32
+ *
33
+ * @example
34
+ * ```ts
35
+ * // Option 1: Explicit API key (direct API access)
36
+ * const client = createDecartClient({ apiKey: "your-api-key" });
37
+ *
38
+ * // Option 2: Using DECART_API_KEY environment variable
39
+ * const client = createDecartClient();
40
+ *
41
+ * // Option 3: Using proxy (client-side, no API key needed)
42
+ * const client = createDecartClient({ proxy: "https://your-server.com/api/decart" });
43
+ * ```
44
+ */
45
+ //#endregion
46
+ export { DecartClientOptions };
@@ -0,0 +1,106 @@
1
+ import { createInvalidApiKeyError, createInvalidBaseUrlError } from "./utils/errors.js";
2
+ import { createFilesClient } from "./files/client.js";
3
+ import { createProcessClient } from "./process/client.js";
4
+ import { createQueueClient } from "./queue/client.js";
5
+ import { createTokensClient } from "./tokens/client.js";
6
+ import { readEnv } from "./utils/env.js";
7
+ import { createConsoleLogger } from "./utils/logger.js";
8
+ import { z } from "zod";
9
+ //#region src/create-client.ts
10
+ const proxySchema = z.union([z.string().url(), z.string().startsWith("/")]);
11
+ const decartClientOptionsSchema = z.object({
12
+ apiKey: z.string().min(1).optional(),
13
+ baseUrl: z.url().optional(),
14
+ proxy: proxySchema.optional(),
15
+ integration: z.string().optional(),
16
+ realtimeBaseUrl: z.url().optional()
17
+ }).refine((data) => {
18
+ const hasProxy = !!data.proxy;
19
+ const hasApiKey = !!data.apiKey;
20
+ return !(hasProxy && hasApiKey);
21
+ }, { message: "Cannot provide both 'proxy' and 'apiKey'. Use 'proxy' for proxy mode or 'apiKey' for direct API access." });
22
+ /**
23
+ * Create a Decart API client.
24
+ *
25
+ * @param options - Configuration options
26
+ * @param options.proxy - URL of the proxy server. When set, the client will use the proxy instead of direct API access and apiKey is not required.
27
+ * @param options.apiKey - API key for authentication.
28
+ * @param options.baseUrl - Override the default API base URL.
29
+ * @param options.realtimeBaseUrl - Override the default WebSocket base URL for realtime connections.
30
+ * @param options.integration - Optional integration identifier.
31
+ *
32
+ * Realtime media uses LiveKit only (inference must enable it in `TRANSPORTS_ENABLED`).
33
+ *
34
+ * @example
35
+ * ```ts
36
+ * // Option 1: Explicit API key (direct API access)
37
+ * const client = createDecartClient({ apiKey: "your-api-key" });
38
+ *
39
+ * // Option 2: Using DECART_API_KEY environment variable
40
+ * const client = createDecartClient();
41
+ *
42
+ * // Option 3: Using proxy (client-side, no API key needed)
43
+ * const client = createDecartClient({ proxy: "https://your-server.com/api/decart" });
44
+ * ```
45
+ */
46
+ const createDecartClientForPlatform = (createRealtime, options = {}) => {
47
+ const parsedOptions = decartClientOptionsSchema.safeParse(options);
48
+ if (!parsedOptions.success) {
49
+ const issue = parsedOptions.error.issues[0];
50
+ if (issue.path.includes("apiKey")) throw createInvalidApiKeyError();
51
+ if (issue.path.includes("baseUrl") || issue.path.includes("realtimeBaseUrl")) throw createInvalidBaseUrlError(options[issue.path.includes("realtimeBaseUrl") ? "realtimeBaseUrl" : "baseUrl"]);
52
+ if (issue.path.includes("proxy")) throw createInvalidBaseUrlError(issue.path.includes("proxy") ? options.proxy : void 0);
53
+ throw parsedOptions.error;
54
+ }
55
+ const isProxyMode = "proxy" in parsedOptions.data && !!parsedOptions.data.proxy;
56
+ const apiKey = isProxyMode ? void 0 : ("apiKey" in parsedOptions.data ? parsedOptions.data.apiKey : void 0) ?? readEnv("DECART_API_KEY");
57
+ if (!isProxyMode && !apiKey) throw createInvalidApiKeyError();
58
+ let baseUrl;
59
+ if (isProxyMode && "proxy" in parsedOptions.data && parsedOptions.data.proxy) baseUrl = parsedOptions.data.proxy;
60
+ else baseUrl = parsedOptions.data.baseUrl || "https://api.decart.ai";
61
+ const { integration } = parsedOptions.data;
62
+ const logger = "logger" in options && options.logger ? options.logger : createConsoleLogger("info");
63
+ const telemetryEnabled = !("telemetry" in options && options.telemetry === false);
64
+ const wsBaseUrl = parsedOptions.data.realtimeBaseUrl || "wss://api3.decart.ai";
65
+ const realtime = createRealtime({
66
+ publishBaseUrl: wsBaseUrl,
67
+ subscribeBaseUrl: isProxyMode || parsedOptions.data.baseUrl !== void 0 ? baseUrl : wsBaseUrl.replace(/^wss?:\/\//i, "https://"),
68
+ apiKey: apiKey || "",
69
+ integration,
70
+ logger,
71
+ telemetryEnabled
72
+ });
73
+ const process = createProcessClient({
74
+ baseUrl,
75
+ apiKey: apiKey || "",
76
+ integration
77
+ });
78
+ const queue = createQueueClient({
79
+ baseUrl,
80
+ apiKey: apiKey || "",
81
+ integration
82
+ });
83
+ const tokens = createTokensClient({
84
+ baseUrl,
85
+ apiKey: apiKey || "",
86
+ integration
87
+ });
88
+ const files = createFilesClient({
89
+ baseUrl,
90
+ apiKey: apiKey || "",
91
+ integration
92
+ });
93
+ return {
94
+ realtime: {
95
+ connect: realtime.connect,
96
+ subscribe: realtime.subscribe,
97
+ checkConnectivity: realtime.checkConnectivity
98
+ },
99
+ process,
100
+ queue,
101
+ tokens,
102
+ files
103
+ };
104
+ };
105
+ //#endregion
106
+ export { createDecartClientForPlatform };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,4 @@
1
- import { LogLevel, Logger, createConsoleLogger, noopLogger } from "./utils/logger.js";
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";
1
+ import { CanonicalModel, CustomModelDefinition, ImageModelDefinition, ImageModels, ListedModelDefinition, Model, ModelDefinition, ModelFps, ModelKind, RealTimeModels, VideoModelDefinition, VideoModels, isCanonicalModel, isImageModel, isModel, isRealtimeModel, isVideoModel, listModels, modelAliases, models, resolveCanonicalModelAlias, resolveFpsNumber, resolveModelAlias } from "./shared/model.js";
3
2
  import { FileInput, ProcessOptions, ReactNativeFile } from "./process/types.js";
4
3
  import { FileReference, FileUploadInput } from "./files/types.js";
5
4
  import { FilesClient, UploadFileOptions } from "./files/client.js";
@@ -7,172 +6,31 @@ import { ProcessClient } from "./process/client.js";
7
6
  import { JobStatus, JobStatusResponse, JobSubmitResponse, QueueJobResult, QueueSubmitAndPollOptions, QueueSubmitOptions } from "./queue/types.js";
8
7
  import { QueueClient } from "./queue/client.js";
9
8
  import { DecartSDKError, ERROR_CODES } from "./utils/errors.js";
10
- import { G2GMetrics } from "./realtime/observability/glass-to-glass.js";
9
+ import { LogLevel, Logger, createConsoleLogger, noopLogger } from "./utils/logger.js";
10
+ import { G2GMetrics } from "./realtime/observability/g2g.js";
11
11
  import { WebRTCStats } from "./realtime/observability/webrtc-stats.js";
12
12
  import { ConnectionQuality, ConnectionQualityLimitingFactor, ConnectionQualityMetrics, ConnectionQualityReport } from "./realtime/observability/connection-quality.js";
13
13
  import { ClientSessionConnectionBreakdownEvent, ClientSessionConnectionBreakdownPhase, DiagnosticEvent, DiagnosticEventName, DiagnosticEvents, ReconnectEvent, VideoStallEvent } from "./realtime/observability/diagnostics.js";
14
14
  import { ConnectionState, GenerationEndedMessage, QueuePosition, QueuePositionMessage } from "./realtime/types.js";
15
15
  import { SetInput } from "./realtime/methods.js";
16
- import { Events, RealTimeClient, RealTimeClientConnectOptions, RealTimeClientInitialState } from "./realtime/client.js";
17
- import { CheckConnectivityOptions, ConnectivityMetrics, ConnectivityReport, ConnectivityTransport } from "./realtime/preflight.js";
16
+ import { Events, RealTimeClient, RealTimeClientConnectOptions, RealTimeClientInitialState, RealtimeMediaStream } from "./realtime/client.js";
17
+ import { CheckConnectivityOptions, ConnectivityMetrics, ConnectivityReport, ConnectivityTransport } from "./realtime/preflight-types.js";
18
18
  import { RealTimeSubscribeClient, SubscribeEvents, SubscribeOptions } from "./realtime/subscribe-client.js";
19
19
  import { ModelState } from "./shared/types.js";
20
20
  import { CreateTokenOptions, CreateTokenResponse, TokensClient } from "./tokens/client.js";
21
+ import { DecartClientOptions } from "./create-client.js";
21
22
 
22
23
  //#region src/index.d.ts
23
- type DecartClientOptions = {
24
- proxy: string;
25
- apiKey?: never;
26
- baseUrl?: string;
27
- realtimeBaseUrl?: string;
28
- integration?: string;
29
- logger?: Logger;
30
- telemetry?: boolean;
31
- } | {
32
- proxy?: never;
33
- apiKey?: string;
34
- baseUrl?: string;
35
- realtimeBaseUrl?: string;
36
- integration?: string;
37
- logger?: Logger;
38
- telemetry?: boolean;
39
- };
40
- /**
41
- * Create a Decart API client.
42
- *
43
- * @param options - Configuration options
44
- * @param options.proxy - URL of the proxy server. When set, the client will use the proxy instead of direct API access and apiKey is not required.
45
- * @param options.apiKey - API key for authentication.
46
- * @param options.baseUrl - Override the default API base URL.
47
- * @param options.realtimeBaseUrl - Override the default WebSocket base URL for realtime connections.
48
- * @param options.integration - Optional integration identifier.
49
- *
50
- * Realtime media uses LiveKit only (inference must enable it in `TRANSPORTS_ENABLED`).
51
- *
52
- * @example
53
- * ```ts
54
- * // (direct API access)Option 1: Explicit API key
55
- * const client = createDecartClient({ apiKey: "your-api-key" });
56
- *
57
- * // Option 2: Using DECART_API_KEY environment variable
58
- * const client = createDecartClient();
59
- *
60
- * // Option 3: Using proxy (client-side, no API key needed)
61
- * const client = createDecartClient({ proxy: "https://your-server.com/api/decart" });
62
- * ```
63
- */
64
24
  declare const createDecartClient: (options?: DecartClientOptions) => {
65
25
  realtime: {
66
- connect: (stream: MediaStream | null, options: RealTimeClientConnectOptions) => Promise<RealTimeClient>;
26
+ connect: <TStream extends RealtimeMediaStream = MediaStream>(stream: TStream | null, options: RealTimeClientConnectOptions<TStream>) => Promise<RealTimeClient>;
67
27
  subscribe: (options: SubscribeOptions) => Promise<RealTimeSubscribeClient>;
68
- /**
69
- * Check whether the user's network can support a real-time session
70
- * *before* connecting — so you can gate showing the integration.
71
- *
72
- * Default (STUN-only): validates WebRTC reachability (UDP egress / TURN
73
- * need) and approximate latency via a throwaway peer connection — no
74
- * session, instant. Opt-in deep probe (`{ deep: true, model }`): briefly
75
- * opens a real session with a synthetic source and measures *true*
76
- * glass-to-glass latency (and end-to-end drops / upstream loss+jitter),
77
- * then tears it down — accurate, but costs a short GPU session.
78
- *
79
- * @example
80
- * ```ts
81
- * // Fast, pre-session reachability check
82
- * const { quality, reasons } = await client.realtime.checkConnectivity();
83
- * if (quality === "critical") showFallbackUI(reasons);
84
- *
85
- * // Accurate, measured glass-to-glass verdict
86
- * const probe = await client.realtime.checkConnectivity({ deep: true, model: models.realtime("mirage") });
87
- * console.log(probe.metrics.g2gMs);
88
- * ```
89
- */
90
28
  checkConnectivity: (options?: CheckConnectivityOptions) => Promise<ConnectivityReport>;
91
29
  };
92
- /**
93
- * Client for synchronous image generation.
94
- * Only image models support the sync/process API.
95
- *
96
- * @example
97
- * ```ts
98
- * const client = createDecartClient({ apiKey: "your-api-key" });
99
- * const result = await client.process({
100
- * model: models.image("lucy-pro-i2i"),
101
- * prompt: "Transform into anime style",
102
- * data: imageBlob
103
- * });
104
- * ```
105
- */
106
30
  process: ProcessClient;
107
- /**
108
- * Client for queue-based async video generation.
109
- * Only video models support the queue API.
110
- * Jobs are submitted and processed asynchronously.
111
- *
112
- * @example
113
- * ```ts
114
- * const client = createDecartClient({ apiKey: "your-api-key" });
115
- *
116
- * // Option 1: Submit and poll automatically
117
- * const result = await client.queue.submitAndPoll({
118
- * model: models.video("lucy-pro-v2v"),
119
- * prompt: "Transform into anime style",
120
- * data: videoBlob,
121
- * onStatusChange: (job) => console.log(`Job ${job.job_id}: ${job.status}`)
122
- * });
123
- *
124
- * // Option 2: Submit and poll manually
125
- * const job = await client.queue.submit({
126
- * model: models.video("lucy-pro-v2v"),
127
- * prompt: "Transform into anime style",
128
- * data: videoBlob
129
- * });
130
- *
131
- * // Poll until completion
132
- * while (true) {
133
- * const status = await client.queue.status(job.job_id);
134
- * console.log(`Job ${status.job_id}: ${status.status}`);
135
- *
136
- * if (status.status === "completed") {
137
- * const blob = await client.queue.result(job.job_id);
138
- * break;
139
- * }
140
- * if (status.status === "failed") {
141
- * throw new Error("Job failed");
142
- * }
143
- * await new Promise(resolve => setTimeout(resolve, 1500));
144
- * }
145
- * ```
146
- */
147
31
  queue: QueueClient;
148
- /**
149
- * Client for creating client tokens.
150
- * Client tokens are short-lived API keys safe for client-side use.
151
- *
152
- * @example
153
- * ```ts
154
- * // Server-side: Create a client token
155
- * const serverClient = createDecartClient({ apiKey: process.env.DECART_API_KEY });
156
- * const token = await serverClient.tokens.create();
157
- * // Returns: { apiKey: "ek_...", expiresAt: "2024-12-15T12:10:00Z" }
158
- *
159
- * // Client-side: Use the client token
160
- * const client = createDecartClient({ apiKey: token.apiKey });
161
- * const realtimeClient = await client.realtime.connect(stream, options);
162
- * ```
163
- */
164
32
  tokens: TokensClient;
165
- /**
166
- * Upload files once and reuse them across generations.
167
- *
168
- * @example
169
- * ```ts
170
- * const ref = await client.files.upload(blob);
171
- * await rt.set({ image: ref.id, prompt: "make it cinematic" });
172
- * await rt.set({ image: ref.id, prompt: "now in noir" });
173
- * ```
174
- */
175
33
  files: FilesClient;
176
34
  };
177
35
  //#endregion
178
- export { type CanonicalModel, type CheckConnectivityOptions, type ClientSessionConnectionBreakdownEvent, type ClientSessionConnectionBreakdownPhase, type ConnectionQuality, type ConnectionQualityLimitingFactor, type ConnectionQualityMetrics, type ConnectionQualityReport, type ConnectionState, type ConnectivityMetrics, type ConnectivityReport, type ConnectivityTransport, 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 G2GMetrics, 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 };
36
+ export { CanonicalModel, CheckConnectivityOptions, ClientSessionConnectionBreakdownEvent, ClientSessionConnectionBreakdownPhase, ConnectionQuality, ConnectionQualityLimitingFactor, ConnectionQualityMetrics, ConnectionQualityReport, ConnectionState, ConnectivityMetrics, ConnectivityReport, ConnectivityTransport, CreateTokenOptions, CreateTokenResponse, CustomModelDefinition, type DecartClientOptions, DecartSDKError, DiagnosticEvent, DiagnosticEventName, DiagnosticEvents, ERROR_CODES, FileInput, FileReference, FileUploadInput, FilesClient, G2GMetrics, GenerationEndedMessage, ImageModelDefinition, ImageModels, JobStatus, JobStatusResponse, JobSubmitResponse, ListedModelDefinition, LogLevel, Logger, Model, ModelDefinition, ModelFps, ModelKind, ModelState, ProcessClient, ProcessOptions, QueueClient, QueueJobResult, QueuePosition, QueuePositionMessage, QueueSubmitAndPollOptions, QueueSubmitOptions, ReactNativeFile, RealTimeClient, RealTimeClientConnectOptions, RealTimeClientInitialState, Events as RealTimeEvents, RealTimeModels, RealTimeSubscribeClient, RealtimeMediaStream, ReconnectEvent, SetInput, SubscribeEvents, SubscribeOptions, TokensClient, UploadFileOptions, VideoModelDefinition, VideoModels, VideoStallEvent, WebRTCStats, createConsoleLogger, createDecartClient, isCanonicalModel, isImageModel, isModel, isRealtimeModel, isVideoModel, listModels, modelAliases, models, noopLogger, resolveCanonicalModelAlias, resolveFpsNumber, resolveModelAlias };
package/dist/index.js CHANGED
@@ -1,119 +1,9 @@
1
- import { ERROR_CODES, createInvalidApiKeyError, createInvalidBaseUrlError } from "./utils/errors.js";
2
- import { createFilesClient } from "./files/client.js";
3
- import { createProcessClient } from "./process/client.js";
4
- import { createQueueClient } from "./queue/client.js";
5
- import { isCanonicalModel, isImageModel, isModel, isRealtimeModel, isVideoModel, listModels, modelAliases, models, resolveCanonicalModelAlias, resolveModelAlias } from "./shared/model.js";
1
+ import { ERROR_CODES } from "./utils/errors.js";
6
2
  import { createConsoleLogger, noopLogger } from "./utils/logger.js";
7
- import { createRealTimeClient } from "./realtime/client.js";
8
- import { createPreflight } from "./realtime/preflight.js";
9
- import { createRealTimeSubscribeClient } from "./realtime/subscribe-client.js";
10
- import { createTokensClient } from "./tokens/client.js";
11
- import { readEnv } from "./utils/env.js";
12
- import { z } from "zod";
3
+ import { createDecartClientForPlatform } from "./create-client.js";
4
+ import { isCanonicalModel, isImageModel, isModel, isRealtimeModel, isVideoModel, listModels, modelAliases, models, resolveCanonicalModelAlias, resolveFpsNumber, resolveModelAlias } from "./shared/model.js";
5
+ import { createBrowserRealtime } from "./realtime/browser/index.js";
13
6
  //#region src/index.ts
14
- const proxySchema = z.union([z.string().url(), z.string().startsWith("/")]);
15
- const decartClientOptionsSchema = z.object({
16
- apiKey: z.string().min(1).optional(),
17
- baseUrl: z.url().optional(),
18
- proxy: proxySchema.optional(),
19
- integration: z.string().optional(),
20
- realtimeBaseUrl: z.url().optional()
21
- }).refine((data) => {
22
- const hasProxy = !!data.proxy;
23
- const hasApiKey = !!data.apiKey;
24
- return !(hasProxy && hasApiKey);
25
- }, { message: "Cannot provide both 'proxy' and 'apiKey'. Use 'proxy' for proxy mode or 'apiKey' for direct API access." });
26
- /**
27
- * Create a Decart API client.
28
- *
29
- * @param options - Configuration options
30
- * @param options.proxy - URL of the proxy server. When set, the client will use the proxy instead of direct API access and apiKey is not required.
31
- * @param options.apiKey - API key for authentication.
32
- * @param options.baseUrl - Override the default API base URL.
33
- * @param options.realtimeBaseUrl - Override the default WebSocket base URL for realtime connections.
34
- * @param options.integration - Optional integration identifier.
35
- *
36
- * Realtime media uses LiveKit only (inference must enable it in `TRANSPORTS_ENABLED`).
37
- *
38
- * @example
39
- * ```ts
40
- * // (direct API access)Option 1: Explicit API key
41
- * const client = createDecartClient({ apiKey: "your-api-key" });
42
- *
43
- * // Option 2: Using DECART_API_KEY environment variable
44
- * const client = createDecartClient();
45
- *
46
- * // Option 3: Using proxy (client-side, no API key needed)
47
- * const client = createDecartClient({ proxy: "https://your-server.com/api/decart" });
48
- * ```
49
- */
50
- const createDecartClient = (options = {}) => {
51
- const parsedOptions = decartClientOptionsSchema.safeParse(options);
52
- if (!parsedOptions.success) {
53
- const issue = parsedOptions.error.issues[0];
54
- if (issue.path.includes("apiKey")) throw createInvalidApiKeyError();
55
- if (issue.path.includes("baseUrl") || issue.path.includes("realtimeBaseUrl")) throw createInvalidBaseUrlError(options[issue.path.includes("realtimeBaseUrl") ? "realtimeBaseUrl" : "baseUrl"]);
56
- if (issue.path.includes("proxy")) throw createInvalidBaseUrlError(issue.path.includes("proxy") ? options.proxy : void 0);
57
- throw parsedOptions.error;
58
- }
59
- const isProxyMode = "proxy" in parsedOptions.data && !!parsedOptions.data.proxy;
60
- const apiKey = isProxyMode ? void 0 : ("apiKey" in parsedOptions.data ? parsedOptions.data.apiKey : void 0) ?? readEnv("DECART_API_KEY");
61
- if (!isProxyMode && !apiKey) throw createInvalidApiKeyError();
62
- let baseUrl;
63
- if (isProxyMode && "proxy" in parsedOptions.data && parsedOptions.data.proxy) baseUrl = parsedOptions.data.proxy;
64
- else baseUrl = parsedOptions.data.baseUrl || "https://api.decart.ai";
65
- const { integration } = parsedOptions.data;
66
- const logger = "logger" in options && options.logger ? options.logger : createConsoleLogger("info");
67
- const telemetryEnabled = !("telemetry" in options && options.telemetry === false);
68
- const wsBaseUrl = parsedOptions.data.realtimeBaseUrl || "wss://api3.decart.ai";
69
- const realtimePublish = createRealTimeClient({
70
- baseUrl: wsBaseUrl,
71
- apiKey: apiKey || "",
72
- integration,
73
- logger,
74
- telemetryEnabled
75
- });
76
- const realtimeSubscribe = createRealTimeSubscribeClient({
77
- baseUrl: isProxyMode || parsedOptions.data.baseUrl !== void 0 ? baseUrl : wsBaseUrl.replace(/^wss?:\/\//i, "https://"),
78
- apiKey: apiKey || "",
79
- integration,
80
- logger
81
- });
82
- const preflight = createPreflight({
83
- logger,
84
- connect: realtimePublish.connect
85
- });
86
- const process = createProcessClient({
87
- baseUrl,
88
- apiKey: apiKey || "",
89
- integration
90
- });
91
- const queue = createQueueClient({
92
- baseUrl,
93
- apiKey: apiKey || "",
94
- integration
95
- });
96
- const tokens = createTokensClient({
97
- baseUrl,
98
- apiKey: apiKey || "",
99
- integration
100
- });
101
- const files = createFilesClient({
102
- baseUrl,
103
- apiKey: apiKey || "",
104
- integration
105
- });
106
- return {
107
- realtime: {
108
- connect: realtimePublish.connect,
109
- subscribe: realtimeSubscribe.subscribe,
110
- checkConnectivity: preflight.checkConnectivity
111
- },
112
- process,
113
- queue,
114
- tokens,
115
- files
116
- };
117
- };
7
+ const createDecartClient = (options = {}) => createDecartClientForPlatform(createBrowserRealtime, options);
118
8
  //#endregion
119
- export { ERROR_CODES, createConsoleLogger, createDecartClient, isCanonicalModel, isImageModel, isModel, isRealtimeModel, isVideoModel, listModels, modelAliases, models, noopLogger, resolveCanonicalModelAlias, resolveModelAlias };
9
+ export { ERROR_CODES, createConsoleLogger, createDecartClient, isCanonicalModel, isImageModel, isModel, isRealtimeModel, isVideoModel, listModels, modelAliases, models, noopLogger, resolveCanonicalModelAlias, resolveFpsNumber, resolveModelAlias };
@@ -0,0 +1,36 @@
1
+ import { CanonicalModel, CustomModelDefinition, ImageModelDefinition, ImageModels, ListedModelDefinition, Model, ModelDefinition, ModelFps, ModelKind, RealTimeModels, VideoModelDefinition, VideoModels, isCanonicalModel, isImageModel, isModel, isRealtimeModel, isVideoModel, listModels, modelAliases, models, resolveCanonicalModelAlias, resolveFpsNumber, resolveModelAlias } from "./shared/model.js";
2
+ import { FileInput, ProcessOptions, ReactNativeFile } from "./process/types.js";
3
+ import { FileReference, FileUploadInput } from "./files/types.js";
4
+ import { FilesClient, UploadFileOptions } from "./files/client.js";
5
+ import { ProcessClient } from "./process/client.js";
6
+ import { JobStatus, JobStatusResponse, JobSubmitResponse, QueueJobResult, QueueSubmitAndPollOptions, QueueSubmitOptions } from "./queue/types.js";
7
+ import { QueueClient } from "./queue/client.js";
8
+ import { DecartSDKError, ERROR_CODES } from "./utils/errors.js";
9
+ import { LogLevel, Logger, createConsoleLogger, noopLogger } from "./utils/logger.js";
10
+ import { G2GMetrics } from "./realtime/observability/g2g.js";
11
+ import { WebRTCStats } from "./realtime/observability/webrtc-stats.js";
12
+ import { ConnectionQuality, ConnectionQualityLimitingFactor, ConnectionQualityMetrics, ConnectionQualityReport } from "./realtime/observability/connection-quality.js";
13
+ import { ClientSessionConnectionBreakdownEvent, ClientSessionConnectionBreakdownPhase, DiagnosticEvent, DiagnosticEventName, DiagnosticEvents, ReconnectEvent, VideoStallEvent } from "./realtime/observability/diagnostics.js";
14
+ import { ConnectionState, GenerationEndedMessage, QueuePosition, QueuePositionMessage } from "./realtime/types.js";
15
+ import { SetInput } from "./realtime/methods.js";
16
+ import { Events, RealTimeClient, RealTimeClientConnectOptions, RealTimeClientInitialState, RealtimeMediaStream } from "./realtime/client.js";
17
+ import { CheckConnectivityOptions, ConnectivityMetrics, ConnectivityReport, ConnectivityTransport } from "./realtime/preflight-types.js";
18
+ import { RealTimeSubscribeClient, SubscribeEvents, SubscribeOptions } from "./realtime/subscribe-client.js";
19
+ import { ModelState } from "./shared/types.js";
20
+ import { CreateTokenOptions, CreateTokenResponse, TokensClient } from "./tokens/client.js";
21
+ import { DecartClientOptions } from "./create-client.js";
22
+
23
+ //#region src/index.react-native.d.ts
24
+ declare const createDecartClient: (options?: DecartClientOptions) => {
25
+ realtime: {
26
+ connect: <TStream extends RealtimeMediaStream = MediaStream>(stream: TStream | null, options: RealTimeClientConnectOptions<TStream>) => Promise<RealTimeClient>;
27
+ subscribe: (options: SubscribeOptions) => Promise<RealTimeSubscribeClient>;
28
+ checkConnectivity: (options?: CheckConnectivityOptions) => Promise<ConnectivityReport>;
29
+ };
30
+ process: ProcessClient;
31
+ queue: QueueClient;
32
+ tokens: TokensClient;
33
+ files: FilesClient;
34
+ };
35
+ //#endregion
36
+ export { CanonicalModel, CheckConnectivityOptions, ClientSessionConnectionBreakdownEvent, ClientSessionConnectionBreakdownPhase, ConnectionQuality, ConnectionQualityLimitingFactor, ConnectionQualityMetrics, ConnectionQualityReport, ConnectionState, ConnectivityMetrics, ConnectivityReport, ConnectivityTransport, CreateTokenOptions, CreateTokenResponse, CustomModelDefinition, type DecartClientOptions, DecartSDKError, DiagnosticEvent, DiagnosticEventName, DiagnosticEvents, ERROR_CODES, FileInput, FileReference, FileUploadInput, FilesClient, G2GMetrics, GenerationEndedMessage, ImageModelDefinition, ImageModels, JobStatus, JobStatusResponse, JobSubmitResponse, ListedModelDefinition, LogLevel, Logger, Model, ModelDefinition, ModelFps, ModelKind, ModelState, ProcessClient, ProcessOptions, QueueClient, QueueJobResult, QueuePosition, QueuePositionMessage, QueueSubmitAndPollOptions, QueueSubmitOptions, ReactNativeFile, RealTimeClient, RealTimeClientConnectOptions, RealTimeClientInitialState, Events as RealTimeEvents, RealTimeModels, RealTimeSubscribeClient, RealtimeMediaStream, ReconnectEvent, SetInput, SubscribeEvents, SubscribeOptions, TokensClient, UploadFileOptions, VideoModelDefinition, VideoModels, VideoStallEvent, WebRTCStats, createConsoleLogger, createDecartClient, isCanonicalModel, isImageModel, isModel, isRealtimeModel, isVideoModel, listModels, modelAliases, models, noopLogger, resolveCanonicalModelAlias, resolveFpsNumber, resolveModelAlias };
@@ -0,0 +1,9 @@
1
+ import { ERROR_CODES } from "./utils/errors.js";
2
+ import { createConsoleLogger, noopLogger } from "./utils/logger.js";
3
+ import { createDecartClientForPlatform } from "./create-client.js";
4
+ import { isCanonicalModel, isImageModel, isModel, isRealtimeModel, isVideoModel, listModels, modelAliases, models, resolveCanonicalModelAlias, resolveFpsNumber, resolveModelAlias } from "./shared/model.js";
5
+ import { createReactNativeRealtime } from "./realtime/react-native/index.js";
6
+ //#region src/index.react-native.ts
7
+ const createDecartClient = (options = {}) => createDecartClientForPlatform(createReactNativeRealtime, options);
8
+ //#endregion
9
+ export { ERROR_CODES, createConsoleLogger, createDecartClient, isCanonicalModel, isImageModel, isModel, isRealtimeModel, isVideoModel, listModels, modelAliases, models, noopLogger, resolveCanonicalModelAlias, resolveFpsNumber, resolveModelAlias };
@@ -0,0 +1,27 @@
1
+ import { SeqTracker, createMarkerReader, createStampPump } from "./glass-to-glass.js";
2
+ //#region src/realtime/browser/glass-to-glass-diagnostics.ts
3
+ function createBrowserGlassToGlassDiagnostics() {
4
+ const tracker = new SeqTracker();
5
+ const reader = createMarkerReader(tracker);
6
+ let pump;
7
+ return {
8
+ attachOutgoingStream: (stream, fps) => {
9
+ pump?.dispose();
10
+ pump = createStampPump(stream, {
11
+ tracker,
12
+ fps
13
+ });
14
+ return pump.stream;
15
+ },
16
+ attachRemoteVideoTrack: (track) => reader.attach(track),
17
+ markStart: () => tracker.markStart(performance.now()),
18
+ snapshot: () => tracker.snapshot(),
19
+ dispose: () => {
20
+ pump?.dispose();
21
+ pump = void 0;
22
+ reader.dispose();
23
+ }
24
+ };
25
+ }
26
+ //#endregion
27
+ export { createBrowserGlassToGlassDiagnostics };