@decartai/sdk 0.0.68 → 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.
Files changed (47) hide show
  1. package/README.md +49 -9
  2. package/dist/files/client.d.ts +33 -0
  3. package/dist/files/client.js +65 -0
  4. package/dist/files/types.d.ts +22 -0
  5. package/dist/files/types.js +4 -0
  6. package/dist/index.d.ts +19 -4
  7. package/dist/index.js +50 -28
  8. package/dist/process/client.js +1 -3
  9. package/dist/process/request.js +1 -3
  10. package/dist/queue/client.js +1 -3
  11. package/dist/queue/polling.js +1 -2
  12. package/dist/queue/request.js +1 -3
  13. package/dist/realtime/client.d.ts +23 -11
  14. package/dist/realtime/client.js +85 -156
  15. package/dist/realtime/config-realtime.js +49 -0
  16. package/dist/realtime/event-buffer.js +1 -3
  17. package/dist/realtime/initial-state-gate.js +21 -0
  18. package/dist/realtime/media-channel.js +82 -0
  19. package/dist/realtime/methods.js +25 -43
  20. package/dist/realtime/mirror-stream.js +1 -2
  21. package/dist/realtime/observability/diagnostics.d.ts +14 -53
  22. package/dist/realtime/observability/livekit-stats-provider.js +25 -0
  23. package/dist/realtime/observability/realtime-observability.js +70 -6
  24. package/dist/realtime/observability/telemetry-reporter.js +9 -28
  25. package/dist/realtime/observability/webrtc-stats.d.ts +5 -4
  26. package/dist/realtime/observability/webrtc-stats.js +3 -5
  27. package/dist/realtime/signaling-channel.js +302 -0
  28. package/dist/realtime/stream-session.js +257 -0
  29. package/dist/realtime/subscribe-client.d.ts +2 -3
  30. package/dist/realtime/subscribe-client.js +115 -11
  31. package/dist/realtime/types.d.ts +25 -1
  32. package/dist/shared/model.d.ts +11 -1
  33. package/dist/shared/model.js +51 -14
  34. package/dist/shared/request.js +1 -3
  35. package/dist/shared/types.js +1 -3
  36. package/dist/tokens/client.js +1 -3
  37. package/dist/utils/env.js +1 -2
  38. package/dist/utils/errors.d.ts +3 -0
  39. package/dist/utils/errors.js +4 -2
  40. package/dist/utils/logger.js +1 -2
  41. package/dist/utils/media.js +43 -0
  42. package/dist/utils/platform.js +13 -0
  43. package/dist/utils/user-agent.js +1 -3
  44. package/dist/version.js +1 -2
  45. package/package.json +2 -1
  46. package/dist/realtime/webrtc-connection.js +0 -500
  47. package/dist/realtime/webrtc-manager.js +0 -210
package/README.md CHANGED
@@ -15,12 +15,15 @@ yarn add @decartai/sdk
15
15
  ## Documentation
16
16
 
17
17
  For complete documentation, guides, and examples, visit:
18
- **https://docs.platform.decart.ai/sdks/javascript**
18
+ **[https://docs.platform.decart.ai/sdks/javascript](https://docs.platform.decart.ai/sdks/javascript)**
19
19
 
20
20
  ## Quick Start
21
21
 
22
22
  ### Real-time Video Transformation
23
23
 
24
+ Realtime connections are LiveKit-backed in the SDK. Existing client usage stays the same: provide a
25
+ camera `MediaStream`, choose a realtime model, and handle the transformed remote stream.
26
+
24
27
  ```typescript
25
28
  import { createDecartClient, models } from "@decartai/sdk";
26
29
 
@@ -79,16 +82,53 @@ Options:
79
82
  - `"auto"` — mirror when the input track reports `facingMode: "user"` (mobile front cameras).
80
83
  - `true` — always mirror (e.g. desktop webcams).
81
84
 
82
- #### Output resolution
85
+ ### Watch a Stream
83
86
 
84
- ```ts
87
+ A connected realtime session exposes an SDK `subscribeToken` once it reaches a
88
+ connected state. Share that SDK token with viewers — `client.realtime.subscribe`
89
+ uses it to request receive-only LiveKit credentials from Decart, then connects to
90
+ the LiveKit room for the styled output stream. No viewer camera is required.
91
+
92
+ **Producer** — capture the token from the active session:
93
+
94
+ ```typescript
85
95
  const realtimeClient = await client.realtime.connect(stream, {
86
96
  model,
87
- resolution: "1080p", // default: "720p"
88
- // ...
97
+ onRemoteStream: (transformedStream) => {
98
+ videoElement.srcObject = transformedStream;
99
+ },
100
+ });
101
+
102
+ realtimeClient.on("connectionChange", (state) => {
103
+ if ((state === "connected" || state === "generating") && realtimeClient.subscribeToken) {
104
+ const subscribeToken = realtimeClient.subscribeToken;
105
+ // Pass `subscribeToken` to the viewer snippet below.
106
+ }
89
107
  });
90
108
  ```
91
109
 
110
+ **Viewer** — attach to the producer's stream with the token:
111
+
112
+ ```typescript
113
+ import { createDecartClient, type RealTimeSubscribeClient } from "@decartai/sdk";
114
+
115
+ const client = createDecartClient({ apiKey: "your-api-key-here" });
116
+
117
+ const subscriber: RealTimeSubscribeClient = await client.realtime.subscribe({
118
+ token: subscribeToken,
119
+ onRemoteStream: (stream) => {
120
+ videoElement.srcObject = stream;
121
+ },
122
+ });
123
+
124
+ subscriber.on("connectionChange", (state) => {
125
+ console.log(`Viewer state: ${state}`);
126
+ });
127
+
128
+ // Disconnect when done
129
+ subscriber.disconnect();
130
+ ```
131
+
92
132
  ### Async Processing (Queue API)
93
133
 
94
134
  For video generation jobs, use the queue API to submit jobs and poll for results:
@@ -161,12 +201,12 @@ pnpm install
161
201
 
162
202
  1. **Version bump**: Run `pnpm release` to bump the version (this uses `bumpp` to create a new version tag) and push it to GitHub
163
203
  2. **Automated publish**: The GitHub Actions workflow will:
164
- - Build the project
165
- - Publish to npm
166
- - Create a GitHub release with changelog
204
+ - Build the project
205
+ - Publish to npm
206
+ - Create a GitHub release with changelog
167
207
 
168
208
  The package is published to npm as `@decartai/sdk`.
169
209
 
170
210
  ## License
171
211
 
172
- MIT
212
+ MIT
@@ -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 };
@@ -0,0 +1,4 @@
1
+ /** True if `value` is a `"file_..."` reference id from `client.files.upload(...)`. */
2
+ const isFileRefId = (value) => typeof value === "string" && value.startsWith("file_");
3
+ //#endregion
4
+ export { isFileRefId };
package/dist/index.d.ts CHANGED
@@ -1,16 +1,18 @@
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";
7
9
  import { DecartSDKError, ERROR_CODES } from "./utils/errors.js";
8
- import { ConnectionState } from "./realtime/types.js";
9
- import { ConnectionPhase, DiagnosticEvent, DiagnosticEventName, DiagnosticEvents, IceCandidateEvent, IceStateEvent, PeerConnectionStateEvent, PhaseTimingEvent, ReconnectEvent, SelectedCandidatePairEvent, SignalingStateEvent, VideoStallEvent } from "./realtime/observability/diagnostics.js";
10
+ import { ClientSessionConnectionBreakdownEvent, ClientSessionConnectionBreakdownPhase, DiagnosticEvent, DiagnosticEventName, DiagnosticEvents, ReconnectEvent, VideoStallEvent } from "./realtime/observability/diagnostics.js";
10
11
  import { WebRTCStats } from "./realtime/observability/webrtc-stats.js";
12
+ import { ConnectionState, GenerationEndedMessage, QueuePosition, QueuePositionMessage } from "./realtime/types.js";
11
13
  import { SetInput } from "./realtime/methods.js";
12
- import { RealTimeSubscribeClient, SubscribeEvents, SubscribeOptions } from "./realtime/subscribe-client.js";
13
14
  import { Events, RealTimeClient, RealTimeClientConnectOptions, RealTimeClientInitialState } from "./realtime/client.js";
15
+ import { RealTimeSubscribeClient, SubscribeEvents, SubscribeOptions } from "./realtime/subscribe-client.js";
14
16
  import { ModelState } from "./shared/types.js";
15
17
  import { CreateTokenOptions, CreateTokenResponse, TokensClient } from "./tokens/client.js";
16
18
 
@@ -42,6 +44,8 @@ type DecartClientOptions = {
42
44
  * @param options.realtimeBaseUrl - Override the default WebSocket base URL for realtime connections.
43
45
  * @param options.integration - Optional integration identifier.
44
46
  *
47
+ * Realtime media uses LiveKit only (inference must enable it in `TRANSPORTS_ENABLED`).
48
+ *
45
49
  * @example
46
50
  * ```ts
47
51
  * // (direct API access)Option 1: Explicit API key
@@ -132,6 +136,17 @@ declare const createDecartClient: (options?: DecartClientOptions) => {
132
136
  * ```
133
137
  */
134
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;
135
150
  };
136
151
  //#endregion
137
- export { type CanonicalModel, type ConnectionPhase, type ConnectionState, type CreateTokenOptions, type CreateTokenResponse, type CustomModelDefinition, DecartClientOptions, type DecartSDKError, type DiagnosticEvent, type DiagnosticEventName, type DiagnosticEvents, ERROR_CODES, type FileInput, type IceCandidateEvent, type IceStateEvent, 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 PeerConnectionStateEvent, type PhaseTimingEvent, 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 ReconnectEvent, type SelectedCandidatePairEvent, type SetInput, type SignalingStateEvent, 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,13 +1,14 @@
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";
6
+ import { createConsoleLogger, noopLogger } from "./utils/logger.js";
5
7
  import { createRealTimeClient } from "./realtime/client.js";
8
+ import { createRealTimeSubscribeClient } from "./realtime/subscribe-client.js";
6
9
  import { createTokensClient } from "./tokens/client.js";
7
10
  import { readEnv } from "./utils/env.js";
8
- import { createConsoleLogger, noopLogger } from "./utils/logger.js";
9
11
  import { z } from "zod";
10
-
11
12
  //#region src/index.ts
12
13
  const proxySchema = z.union([z.string().url(), z.string().startsWith("/")]);
13
14
  const decartClientOptionsSchema = z.object({
@@ -31,6 +32,8 @@ const decartClientOptionsSchema = z.object({
31
32
  * @param options.realtimeBaseUrl - Override the default WebSocket base URL for realtime connections.
32
33
  * @param options.integration - Optional integration identifier.
33
34
  *
35
+ * Realtime media uses LiveKit only (inference must enable it in `TRANSPORTS_ENABLED`).
36
+ *
34
37
  * @example
35
38
  * ```ts
36
39
  * // (direct API access)Option 1: Explicit API key
@@ -59,33 +62,52 @@ const createDecartClient = (options = {}) => {
59
62
  if (isProxyMode && "proxy" in parsedOptions.data && parsedOptions.data.proxy) baseUrl = parsedOptions.data.proxy;
60
63
  else baseUrl = parsedOptions.data.baseUrl || "https://api.decart.ai";
61
64
  const { integration } = parsedOptions.data;
62
- const logger = "logger" in options && options.logger ? options.logger : noopLogger;
63
- const telemetryEnabled = "telemetry" in options && options.telemetry === false ? false : true;
65
+ const logger = "logger" in options && options.logger ? options.logger : createConsoleLogger("info");
66
+ const telemetryEnabled = !("telemetry" in options && options.telemetry === false);
67
+ const wsBaseUrl = parsedOptions.data.realtimeBaseUrl || "wss://api3.decart.ai";
68
+ const realtimePublish = createRealTimeClient({
69
+ baseUrl: wsBaseUrl,
70
+ apiKey: apiKey || "",
71
+ integration,
72
+ logger,
73
+ telemetryEnabled
74
+ });
75
+ const realtimeSubscribe = createRealTimeSubscribeClient({
76
+ baseUrl: isProxyMode || parsedOptions.data.baseUrl !== void 0 ? baseUrl : wsBaseUrl.replace(/^wss?:\/\//i, "https://"),
77
+ apiKey: apiKey || "",
78
+ integration,
79
+ logger
80
+ });
81
+ const process = createProcessClient({
82
+ baseUrl,
83
+ apiKey: apiKey || "",
84
+ integration
85
+ });
86
+ const queue = createQueueClient({
87
+ baseUrl,
88
+ apiKey: apiKey || "",
89
+ integration
90
+ });
91
+ const tokens = createTokensClient({
92
+ baseUrl,
93
+ apiKey: apiKey || "",
94
+ integration
95
+ });
96
+ const files = createFilesClient({
97
+ baseUrl,
98
+ apiKey: apiKey || "",
99
+ integration
100
+ });
64
101
  return {
65
- realtime: createRealTimeClient({
66
- baseUrl: parsedOptions.data.realtimeBaseUrl || "wss://api3.decart.ai",
67
- apiKey: apiKey || "",
68
- integration,
69
- logger,
70
- telemetryEnabled
71
- }),
72
- process: createProcessClient({
73
- baseUrl,
74
- apiKey: apiKey || "",
75
- integration
76
- }),
77
- queue: createQueueClient({
78
- baseUrl,
79
- apiKey: apiKey || "",
80
- integration
81
- }),
82
- tokens: createTokensClient({
83
- baseUrl,
84
- apiKey: apiKey || "",
85
- integration
86
- })
102
+ realtime: {
103
+ connect: realtimePublish.connect,
104
+ subscribe: realtimeSubscribe.subscribe
105
+ },
106
+ process,
107
+ queue,
108
+ tokens,
109
+ files
87
110
  };
88
111
  };
89
-
90
112
  //#endregion
91
- export { ERROR_CODES, createConsoleLogger, createDecartClient, isCanonicalModel, isImageModel, isModel, isRealtimeModel, isVideoModel, listModels, modelAliases, models, noopLogger, resolveCanonicalModelAlias, resolveModelAlias };
113
+ export { ERROR_CODES, createConsoleLogger, createDecartClient, isCanonicalModel, isImageModel, isModel, isRealtimeModel, isVideoModel, listModels, modelAliases, models, noopLogger, resolveCanonicalModelAlias, resolveModelAlias };
@@ -1,7 +1,6 @@
1
1
  import { createInvalidInputError } from "../utils/errors.js";
2
2
  import { fileInputToBlob } from "../shared/request.js";
3
3
  import { sendRequest } from "./request.js";
4
-
5
4
  //#region src/process/client.ts
6
5
  const createProcessClient = (opts) => {
7
6
  const { apiKey, baseUrl, integration } = opts;
@@ -23,6 +22,5 @@ const createProcessClient = (opts) => {
23
22
  };
24
23
  return _process;
25
24
  };
26
-
27
25
  //#endregion
28
- export { createProcessClient };
26
+ export { createProcessClient };
@@ -1,6 +1,5 @@
1
1
  import { createSDKError } from "../utils/errors.js";
2
2
  import { buildAuthHeaders, buildFormData } from "../shared/request.js";
3
-
4
3
  //#region src/process/request.ts
5
4
  async function sendRequest({ baseUrl, apiKey, model, inputs, signal, integration }) {
6
5
  const formData = buildFormData(inputs);
@@ -21,6 +20,5 @@ async function sendRequest({ baseUrl, apiKey, model, inputs, signal, integration
21
20
  }
22
21
  return response.blob();
23
22
  }
24
-
25
23
  //#endregion
26
- export { sendRequest };
24
+ export { sendRequest };
@@ -2,7 +2,6 @@ import { createInvalidInputError } from "../utils/errors.js";
2
2
  import { fileInputToBlob } from "../shared/request.js";
3
3
  import { pollUntilComplete } from "./polling.js";
4
4
  import { getJobContent, getJobStatus, submitJob } from "./request.js";
5
-
6
5
  //#region src/queue/client.ts
7
6
  const createQueueClient = (opts) => {
8
7
  const { apiKey, baseUrl, integration } = opts;
@@ -68,6 +67,5 @@ const createQueueClient = (opts) => {
68
67
  submitAndPoll
69
68
  };
70
69
  };
71
-
72
70
  //#endregion
73
- export { createQueueClient };
71
+ export { createQueueClient };
@@ -35,6 +35,5 @@ async function pollUntilComplete({ checkStatus, getContent, onStatusChange, sign
35
35
  await sleep(POLLING_DEFAULTS.interval);
36
36
  }
37
37
  }
38
-
39
38
  //#endregion
40
- export { pollUntilComplete };
39
+ export { pollUntilComplete };
@@ -1,6 +1,5 @@
1
1
  import { createQueueResultError, createQueueStatusError, createQueueSubmitError } from "../utils/errors.js";
2
2
  import { buildAuthHeaders, buildFormData } from "../shared/request.js";
3
-
4
3
  //#region src/queue/request.ts
5
4
  /**
6
5
  * Submit a job to the queue.
@@ -68,6 +67,5 @@ async function getJobContent({ baseUrl, apiKey, jobId, signal, integration }) {
68
67
  }
69
68
  return response.blob();
70
69
  }
71
-
72
70
  //#endregion
73
- export { getJobContent, getJobStatus, submitJob };
71
+ export { getJobContent, getJobStatus, submitJob };
@@ -1,8 +1,8 @@
1
1
  import { CustomModelDefinition, ModelDefinition } from "../shared/model.js";
2
2
  import { DecartSDKError } from "../utils/errors.js";
3
- import { ConnectionState } from "./types.js";
4
3
  import { DiagnosticEvent } from "./observability/diagnostics.js";
5
4
  import { WebRTCStats } from "./observability/webrtc-stats.js";
5
+ import { ConnectionState, GenerationEnded, GenerationTick, ImageSetOptions, QueuePosition } from "./types.js";
6
6
  import { SetInput } from "./methods.js";
7
7
  import { z } from "zod";
8
8
 
@@ -16,18 +16,27 @@ declare const realTimeClientInitialStateSchema: z.ZodObject<{
16
16
  image: z.ZodOptional<z.ZodUnion<readonly [z.ZodCustom<Blob, Blob>, z.ZodCustom<File, File>, z.ZodString]>>;
17
17
  }, z.core.$strip>;
18
18
  type OnRemoteStreamFn = (stream: MediaStream) => void;
19
+ type OnConnectionChangeFn = (state: ConnectionState) => void;
20
+ type OnQueuePositionFn = (queuePosition: QueuePosition) => void;
19
21
  type RealTimeClientInitialState = z.infer<typeof realTimeClientInitialStateSchema>;
20
22
  declare const realTimeClientConnectOptionsSchema: z.ZodObject<{
21
23
  model: z.ZodObject<{
22
24
  name: z.ZodString;
23
25
  urlPath: z.ZodString;
24
26
  queueUrlPath: z.ZodOptional<z.ZodString>;
25
- fps: z.ZodNumber;
27
+ fps: z.ZodUnion<readonly [z.ZodNumber, z.ZodObject<{
28
+ max: z.ZodOptional<z.ZodNumber>;
29
+ min: z.ZodOptional<z.ZodNumber>;
30
+ ideal: z.ZodOptional<z.ZodNumber>;
31
+ exact: z.ZodOptional<z.ZodNumber>;
32
+ }, z.core.$strip>]>;
26
33
  width: z.ZodNumber;
27
34
  height: z.ZodNumber;
28
35
  inputSchema: z.ZodOptional<z.ZodAny>;
29
36
  }, z.core.$strip>;
30
37
  onRemoteStream: z.ZodCustom<OnRemoteStreamFn, OnRemoteStreamFn>;
38
+ onConnectionChange: z.ZodOptional<z.ZodCustom<OnConnectionChangeFn, OnConnectionChangeFn>>;
39
+ onQueuePosition: z.ZodOptional<z.ZodCustom<OnQueuePositionFn, OnQueuePositionFn>>;
31
40
  initialState: z.ZodOptional<z.ZodObject<{
32
41
  prompt: z.ZodOptional<z.ZodObject<{
33
42
  text: z.ZodString;
@@ -35,7 +44,7 @@ declare const realTimeClientConnectOptionsSchema: z.ZodObject<{
35
44
  }, z.core.$strip>>;
36
45
  image: z.ZodOptional<z.ZodUnion<readonly [z.ZodCustom<Blob, Blob>, z.ZodCustom<File, File>, z.ZodString]>>;
37
46
  }, z.core.$strip>>;
38
- customizeOffer: z.ZodOptional<z.ZodCustom<z.core.$InferInnerFunctionTypeAsync<z.core.$ZodFunctionArgs, z.core.$ZodFunctionOut>, z.core.$InferInnerFunctionTypeAsync<z.core.$ZodFunctionArgs, z.core.$ZodFunctionOut>>>;
47
+ queryParams: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
39
48
  mirror: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<"auto">, z.ZodBoolean]>>;
40
49
  resolution: z.ZodOptional<z.ZodEnum<{
41
50
  "720p": "720p";
@@ -47,10 +56,10 @@ type RealTimeClientConnectOptions = Omit<z.infer<typeof realTimeClientConnectOpt
47
56
  };
48
57
  type Events = {
49
58
  connectionChange: ConnectionState;
59
+ queuePosition: QueuePosition;
50
60
  error: DecartSDKError;
51
- generationTick: {
52
- seconds: number;
53
- };
61
+ generationTick: GenerationTick;
62
+ generationEnded: GenerationEnded;
54
63
  diagnostic: DiagnosticEvent;
55
64
  stats: WebRTCStats;
56
65
  };
@@ -68,11 +77,14 @@ type RealTimeClient = {
68
77
  off: <K extends keyof Events>(event: K, listener: (data: Events[K]) => void) => void;
69
78
  sessionId: string | null;
70
79
  subscribeToken: string | null;
71
- setImage: (image: Blob | File | string | null, options?: {
72
- prompt?: string;
73
- enhance?: boolean;
74
- timeout?: number;
75
- }) => Promise<void>;
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
+ */
87
+ setImage: (image: Blob | File | string | null, options?: ImageSetOptions) => Promise<void>;
76
88
  };
77
89
  //#endregion
78
90
  export { Events, RealTimeClient, RealTimeClientConnectOptions, RealTimeClientInitialState };