@decartai/sdk 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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,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
@@ -50,6 +50,10 @@ declare const realTimeClientConnectOptionsSchema: z.ZodObject<{
50
50
  "720p": "720p";
51
51
  "1080p": "1080p";
52
52
  }>>;
53
+ preferredVideoCodec: z.ZodOptional<z.ZodEnum<{
54
+ h264: "h264";
55
+ vp9: "vp9";
56
+ }>>;
53
57
  }, z.core.$strip>;
54
58
  type RealTimeClientConnectOptions = Omit<z.infer<typeof realTimeClientConnectOptionsSchema>, "model"> & {
55
59
  model: ModelDefinition | CustomModelDefinition;
@@ -78,6 +82,12 @@ type RealTimeClient = {
78
82
  sessionId: string | null;
79
83
  subscribeToken: string | null;
80
84
  getSubscribeToken: () => string | null;
85
+ /**
86
+ * Set the reference image for the session.
87
+ * - `Blob`/`File`/data URL/http(s) URL/base64 string: bytes traverse the wire as base64.
88
+ * - `"file_..."` id (from `client.files.upload(...).id`): sent as a server-side reference.
89
+ * - `null`: clear the current image.
90
+ */
81
91
  setImage: (image: Blob | File | string | null, options?: ImageSetOptions) => Promise<void>;
82
92
  };
83
93
  //#endregion
@@ -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";
@@ -20,7 +21,8 @@ const realTimeClientConnectOptionsSchema = z.object({
20
21
  initialState: realTimeClientInitialStateSchema.optional(),
21
22
  queryParams: z.record(z.string(), z.string()).optional(),
22
23
  mirror: z.union([z.literal("auto"), z.boolean()]).optional(),
23
- resolution: z.enum(["720p", "1080p"]).optional()
24
+ resolution: z.enum(["720p", "1080p"]).optional(),
25
+ preferredVideoCodec: z.enum(["h264", "vp9"]).optional()
24
26
  });
25
27
  const createRealTimeClient = (opts) => {
26
28
  const { baseUrl, apiKey, integration } = opts;
@@ -28,7 +30,7 @@ const createRealTimeClient = (opts) => {
28
30
  const connect = async (stream, options) => {
29
31
  const parsedOptions = realTimeClientConnectOptionsSchema.safeParse(options);
30
32
  if (!parsedOptions.success) throw parsedOptions.error;
31
- const { onRemoteStream, onConnectionChange, onQueuePosition, initialState, resolution } = parsedOptions.data;
33
+ const { onRemoteStream, onConnectionChange, onQueuePosition, initialState, resolution, preferredVideoCodec } = parsedOptions.data;
32
34
  const mirror = parsedOptions.data.mirror ?? false;
33
35
  let inputStream = stream ?? new MediaStream();
34
36
  let mirroredStream;
@@ -44,7 +46,8 @@ const createRealTimeClient = (opts) => {
44
46
  let session;
45
47
  let observability;
46
48
  try {
47
- const initialImage = initialState?.image ? await imageToBase64(initialState.image) : void 0;
49
+ const initialImageRef = isFileRefId(initialState?.image) ? initialState.image : void 0;
50
+ const initialImage = initialImageRef === void 0 && initialState?.image ? await imageToBase64(initialState.image) : void 0;
48
51
  const initialPrompt = initialState?.prompt ? {
49
52
  text: initialState.prompt.text,
50
53
  enhance: initialState.prompt.enhance
@@ -61,6 +64,7 @@ const createRealTimeClient = (opts) => {
61
64
  onStats: (stats) => emitOrBuffer("stats", stats)
62
65
  });
63
66
  const safariCodec = isDesktopSafari() ? "vp8" : void 0;
67
+ const publishCodec = safariCodec ?? preferredVideoCodec;
64
68
  session = new StreamSession({
65
69
  url: `${url}?${new URLSearchParams({
66
70
  ...safariCodec ? { livekit_server_codec: safariCodec } : {},
@@ -73,9 +77,10 @@ const createRealTimeClient = (opts) => {
73
77
  observability,
74
78
  localStream: inputStream,
75
79
  initialImage,
80
+ initialImageRef,
76
81
  initialPrompt,
77
82
  logger,
78
- videoCodec: safariCodec
83
+ videoCodec: publishCodec
79
84
  });
80
85
  let sessionId = null;
81
86
  let subscribeToken = null;
@@ -121,9 +126,19 @@ const createRealTimeClient = (opts) => {
121
126
  },
122
127
  getSubscribeToken: () => subscribeToken,
123
128
  setImage: async (image, imgOptions) => {
124
- if (image === null) return activeSession.setImage(null, imgOptions);
129
+ if (isFileRefId(image)) return activeSession.setImage({
130
+ kind: "ref",
131
+ ref: image
132
+ }, imgOptions);
133
+ if (image === null) return activeSession.setImage({
134
+ kind: "data",
135
+ data: null
136
+ }, imgOptions);
125
137
  const base64 = await imageToBase64(image);
126
- return activeSession.setImage(base64, imgOptions);
138
+ return activeSession.setImage({
139
+ kind: "data",
140
+ data: base64
141
+ }, imgOptions);
127
142
  }
128
143
  };
129
144
  flush();
@@ -34,6 +34,7 @@ const REALTIME_CONFIG = {
34
34
  },
35
35
  defaultVideoCodec: "h264",
36
36
  defaultMaxVideoBitrateBps: 35e5,
37
+ vp9MaxVideoBitrateBps: 3e6,
37
38
  defaultPublishFps: 30
38
39
  },
39
40
  observability: {
@@ -4,15 +4,16 @@ import mitt from "mitt";
4
4
  import { Room, RoomEvent, Track, TrackEvent } from "livekit-client";
5
5
  //#region src/realtime/media-channel.ts
6
6
  function getDefaultVideoPublishOptions(videoCodec) {
7
- const videoEncoding = {
8
- maxBitrate: REALTIME_CONFIG.livekit.defaultMaxVideoBitrateBps,
9
- maxFramerate: REALTIME_CONFIG.livekit.defaultPublishFps
10
- };
7
+ const resolvedCodec = videoCodec ?? REALTIME_CONFIG.livekit.defaultVideoCodec;
8
+ const maxBitrate = resolvedCodec === "vp9" ? REALTIME_CONFIG.livekit.vp9MaxVideoBitrateBps : REALTIME_CONFIG.livekit.defaultMaxVideoBitrateBps;
11
9
  return {
12
10
  source: Track.Source.Camera,
13
- videoCodec: videoCodec ?? REALTIME_CONFIG.livekit.defaultVideoCodec,
14
- simulcast: true,
15
- videoEncoding
11
+ videoCodec: resolvedCodec,
12
+ simulcast: resolvedCodec !== "vp9",
13
+ videoEncoding: {
14
+ maxBitrate,
15
+ maxFramerate: REALTIME_CONFIG.livekit.defaultPublishFps
16
+ }
16
17
  };
17
18
  }
18
19
  var MediaChannel = class {
@@ -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 imageBase64 = image !== void 0 && image !== null ? await imageToBase64(image) : null;
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(image, opts = {}) {
83
- const message = {
82
+ async setImage(payload, opts = {}) {
83
+ const message = payload.kind === "ref" ? {
84
84
  type: "set_image",
85
- image_data: image
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(initialState.image, {
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(image, opts) {
71
+ async setImage(payload, opts) {
72
72
  this.assertConnected();
73
- return this.signaling.setImage(image, opts);
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,
@@ -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";
@@ -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",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@decartai/sdk",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "Decart's JavaScript SDK",
5
5
  "type": "module",
6
6
  "license": "MIT",