@cartesia/cartesia-js 0.0.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/.turbo/turbo-build.log +47 -0
  2. package/CHANGELOG.md +7 -0
  3. package/README.md +38 -0
  4. package/dist/audio/index.d.mts +4 -0
  5. package/dist/audio/index.d.ts +4 -0
  6. package/dist/audio/index.js +354 -0
  7. package/dist/audio/index.mjs +9 -0
  8. package/dist/audio/utils.d.mts +4 -0
  9. package/dist/audio/utils.d.ts +4 -0
  10. package/dist/audio/utils.js +113 -0
  11. package/dist/audio/utils.mjs +21 -0
  12. package/dist/chunk-35HX6ML3.mjs +39 -0
  13. package/dist/chunk-5RMUZJV7.mjs +240 -0
  14. package/dist/chunk-BTFHUVNH.mjs +71 -0
  15. package/dist/chunk-ERFCRIWU.mjs +18 -0
  16. package/dist/index-Ds4LDkmk.d.ts +127 -0
  17. package/dist/index-Dt9A_pEb.d.mts +127 -0
  18. package/dist/lib/client.d.mts +9 -0
  19. package/dist/lib/client.d.ts +9 -0
  20. package/dist/lib/client.js +43 -0
  21. package/dist/lib/client.mjs +7 -0
  22. package/dist/lib/constants.d.mts +5 -0
  23. package/dist/lib/constants.d.ts +5 -0
  24. package/dist/lib/constants.js +38 -0
  25. package/dist/lib/constants.mjs +10 -0
  26. package/dist/lib/index.d.mts +11 -0
  27. package/dist/lib/index.d.ts +11 -0
  28. package/dist/lib/index.js +368 -0
  29. package/dist/lib/index.mjs +19 -0
  30. package/dist/react/index.d.mts +22 -0
  31. package/dist/react/index.d.ts +22 -0
  32. package/dist/react/index.js +431 -0
  33. package/dist/react/index.mjs +82 -0
  34. package/dist/types/index.d.mts +6 -0
  35. package/dist/types/index.d.ts +6 -0
  36. package/dist/types/index.js +18 -0
  37. package/dist/types/index.mjs +0 -0
  38. package/index.ts +3 -0
  39. package/package.json +50 -0
  40. package/src/audio/index.ts +242 -0
  41. package/src/audio/utils.ts +138 -0
  42. package/src/lib/client.ts +17 -0
  43. package/src/lib/constants.ts +6 -0
  44. package/src/lib/index.ts +13 -0
  45. package/src/react/index.ts +91 -0
  46. package/src/types/index.ts +4 -0
  47. package/tsconfig.json +3 -0
@@ -0,0 +1,431 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __knownSymbol = (name, symbol) => {
9
+ return (symbol = Symbol[name]) ? symbol : Symbol.for("Symbol." + name);
10
+ };
11
+ var __export = (target, all) => {
12
+ for (var name in all)
13
+ __defProp(target, name, { get: all[name], enumerable: true });
14
+ };
15
+ var __copyProps = (to, from, except, desc) => {
16
+ if (from && typeof from === "object" || typeof from === "function") {
17
+ for (let key of __getOwnPropNames(from))
18
+ if (!__hasOwnProp.call(to, key) && key !== except)
19
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
20
+ }
21
+ return to;
22
+ };
23
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
24
+ // If the importer is in node compatibility mode or this is not an ESM
25
+ // file that has been converted to a CommonJS file using a Babel-
26
+ // compatible transform (i.e. "__esModule" has not been set), then set
27
+ // "default" to the CommonJS "module.exports" for node compatibility.
28
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
29
+ mod
30
+ ));
31
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
32
+ var __async = (__this, __arguments, generator) => {
33
+ return new Promise((resolve, reject) => {
34
+ var fulfilled = (value) => {
35
+ try {
36
+ step(generator.next(value));
37
+ } catch (e) {
38
+ reject(e);
39
+ }
40
+ };
41
+ var rejected = (value) => {
42
+ try {
43
+ step(generator.throw(value));
44
+ } catch (e) {
45
+ reject(e);
46
+ }
47
+ };
48
+ var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
49
+ step((generator = generator.apply(__this, __arguments)).next());
50
+ });
51
+ };
52
+ var __forAwait = (obj, it, method) => (it = obj[__knownSymbol("asyncIterator")]) ? it.call(obj) : (obj = obj[__knownSymbol("iterator")](), it = {}, method = (key, fn) => (fn = obj[key]) && (it[key] = (arg) => new Promise((yes, no, done) => (arg = fn.call(obj, arg), done = arg.done, Promise.resolve(arg.value).then((value) => yes({ value, done }), no)))), method("next"), method("return"), it);
53
+
54
+ // src/react/index.ts
55
+ var react_exports = {};
56
+ __export(react_exports, {
57
+ useAudio: () => useAudio
58
+ });
59
+ module.exports = __toCommonJS(react_exports);
60
+ var import_react = require("react");
61
+
62
+ // src/audio/index.ts
63
+ var import_emittery = __toESM(require("emittery"));
64
+ var import_human_id = require("human-id");
65
+
66
+ // src/lib/constants.ts
67
+ var BASE_URL = "https://api.cartesia.ai/v0";
68
+ var SAMPLE_RATE = 44100;
69
+ var constructWebsocketUrl = (baseUrl) => {
70
+ return new URL(`${baseUrl.replace(/^http/, "ws")}/ws`);
71
+ };
72
+
73
+ // src/lib/client.ts
74
+ var Client = class {
75
+ constructor(options = {}) {
76
+ if (!(options.apiKey || process.env.CARTESIA_API_KEY)) {
77
+ throw new Error("Missing Cartesia API key.");
78
+ }
79
+ this.apiKey = options.apiKey || process.env.CARTESIA_API_KEY;
80
+ this.baseUrl = options.baseUrl || BASE_URL;
81
+ }
82
+ };
83
+
84
+ // src/audio/utils.ts
85
+ var import_base64_js = __toESM(require("base64-js"));
86
+ function getBufferDuration(b64) {
87
+ const floats = base64ToArray(b64);
88
+ return floats.length / SAMPLE_RATE;
89
+ }
90
+ function base64ToArray(b64) {
91
+ return filterSentinel(b64).reduce((acc, b) => {
92
+ const floats = new Float32Array(import_base64_js.default.toByteArray(b).buffer);
93
+ const newAcc = new Float32Array(acc.length + floats.length);
94
+ newAcc.set(acc, 0);
95
+ newAcc.set(floats, acc.length);
96
+ return newAcc;
97
+ }, new Float32Array(0));
98
+ }
99
+ function playAudioBuffer(b64, context, maybeStartAt = null, onEnded = null) {
100
+ const startAt = maybeStartAt != null ? maybeStartAt : context.currentTime;
101
+ const floats = base64ToArray(b64);
102
+ const source = context.createBufferSource();
103
+ const buffer = context.createBuffer(1, floats.length, SAMPLE_RATE);
104
+ buffer.getChannelData(0).set(floats);
105
+ source.buffer = buffer;
106
+ source.connect(context.destination);
107
+ source.start(startAt);
108
+ source.onended = onEnded;
109
+ return buffer.duration;
110
+ }
111
+ function createMessageHandlerForContextId(contextId, handler) {
112
+ return (event) => {
113
+ const message = JSON.parse(event.data);
114
+ if (message.context_id !== contextId) {
115
+ return;
116
+ }
117
+ let chunk;
118
+ if (message.done) {
119
+ chunk = getSentinel();
120
+ } else {
121
+ chunk = message.data;
122
+ }
123
+ handler({ chunk, message });
124
+ };
125
+ }
126
+ function getSentinel() {
127
+ return null;
128
+ }
129
+ function isSentinel(x) {
130
+ return x === getSentinel();
131
+ }
132
+ function filterSentinel(collection) {
133
+ return collection.filter(
134
+ (x) => !isSentinel(x)
135
+ );
136
+ }
137
+ function isComplete(chunks) {
138
+ return isSentinel(chunks[chunks.length - 1]);
139
+ }
140
+
141
+ // src/audio/index.ts
142
+ var audio_default = class extends Client {
143
+ constructor() {
144
+ super(...arguments);
145
+ this.isConnected = false;
146
+ }
147
+ /**
148
+ * Stream audio from a model.
149
+ *
150
+ * @param inputs - Stream options. Includes a `model` key and some `parameters`, which
151
+ * are model-specific and can be found in the model's documentation.
152
+ * @param options - Options for the stream.
153
+ * @param options.timeout - The maximum time to wait for a chunk before cancelling the stream.
154
+ * If `0`, the stream will not time out.
155
+ * @returns An object with a method `play` of type `(bufferDuration: number) => Promise<void>`
156
+ * that plays the audio as it arrives, with `bufferDuration` seconds of audio buffered before
157
+ * starting playback.
158
+ */
159
+ stream(inputs, { timeout = 0 } = {}) {
160
+ var _a, _b, _c, _d;
161
+ if (!this.isConnected) {
162
+ throw new Error("Not connected to WebSocket. Call .connect() first.");
163
+ }
164
+ const contextId = this.generateId();
165
+ (_a = this.socket) == null ? void 0 : _a.send(
166
+ JSON.stringify({
167
+ data: inputs,
168
+ context_id: contextId
169
+ })
170
+ );
171
+ const streamCompleteController = new AbortController();
172
+ let timeoutId = null;
173
+ if (timeout > 0) {
174
+ timeoutId = setTimeout(streamCompleteController.abort, timeout);
175
+ }
176
+ const chunks = [];
177
+ const emitter = new import_emittery.default();
178
+ const handleMessage = createMessageHandlerForContextId(
179
+ contextId,
180
+ (_0) => __async(this, [_0], function* ({ chunk, message }) {
181
+ chunks.push(chunk);
182
+ yield emitter.emit("chunk", {
183
+ chunk,
184
+ chunks
185
+ });
186
+ yield emitter.emit("message", message);
187
+ if (isSentinel(chunk)) {
188
+ streamCompleteController.abort();
189
+ } else if (timeoutId) {
190
+ clearTimeout(timeoutId);
191
+ timeoutId = setTimeout(streamCompleteController.abort, timeout);
192
+ }
193
+ })
194
+ );
195
+ (_b = this.socket) == null ? void 0 : _b.addEventListener("message", handleMessage, {
196
+ signal: streamCompleteController.signal
197
+ });
198
+ (_c = this.socket) == null ? void 0 : _c.addEventListener("close", streamCompleteController.abort, {
199
+ once: true
200
+ });
201
+ (_d = this.socket) == null ? void 0 : _d.addEventListener("error", streamCompleteController.abort, {
202
+ once: true
203
+ });
204
+ streamCompleteController.signal.addEventListener("abort", () => {
205
+ emitter.clearListeners();
206
+ });
207
+ const play = (_0) => __async(this, [_0], function* ({ bufferDuration }) {
208
+ const context = new AudioContext({
209
+ sampleRate: SAMPLE_RATE
210
+ });
211
+ let startNextPlaybackAt = 0;
212
+ const playLatestChunk = (chunk) => {
213
+ if (isSentinel(chunk)) {
214
+ return true;
215
+ }
216
+ startNextPlaybackAt = playAudioBuffer([chunk], context, startNextPlaybackAt) + Math.max(context.currentTime, startNextPlaybackAt);
217
+ return false;
218
+ };
219
+ const playChunks = (chunks2) => {
220
+ startNextPlaybackAt += playAudioBuffer(
221
+ chunks2,
222
+ context,
223
+ startNextPlaybackAt
224
+ );
225
+ if (isComplete(chunks2)) {
226
+ return;
227
+ }
228
+ };
229
+ const tryStart = (chunks2) => __async(this, null, function* () {
230
+ startNextPlaybackAt = context.currentTime;
231
+ if (isComplete(chunks2) || streamCompleteController.signal.aborted) {
232
+ playChunks(chunks2);
233
+ return true;
234
+ }
235
+ if (getBufferDuration(chunks2) > bufferDuration) {
236
+ playChunks(chunks2);
237
+ try {
238
+ for (var iter2 = __forAwait(emitter.events("chunk")), more2, temp2, error2; more2 = !(temp2 = yield iter2.next()).done; more2 = false) {
239
+ const { chunk } = temp2.value;
240
+ if (playLatestChunk(chunk)) {
241
+ break;
242
+ }
243
+ }
244
+ } catch (temp2) {
245
+ error2 = [temp2];
246
+ } finally {
247
+ try {
248
+ more2 && (temp2 = iter2.return) && (yield temp2.call(iter2));
249
+ } finally {
250
+ if (error2)
251
+ throw error2[0];
252
+ }
253
+ }
254
+ return true;
255
+ }
256
+ return false;
257
+ });
258
+ if (!(yield tryStart(chunks))) {
259
+ try {
260
+ for (var iter = __forAwait(emitter.events("chunk")), more, temp, error; more = !(temp = yield iter.next()).done; more = false) {
261
+ const { chunks: chunks2 } = temp.value;
262
+ if (yield tryStart(chunks2)) {
263
+ break;
264
+ }
265
+ }
266
+ } catch (temp) {
267
+ error = [temp];
268
+ } finally {
269
+ try {
270
+ more && (temp = iter.return) && (yield temp.call(iter));
271
+ } finally {
272
+ if (error)
273
+ throw error[0];
274
+ }
275
+ }
276
+ }
277
+ });
278
+ return {
279
+ play,
280
+ on: emitter.on.bind(emitter),
281
+ off: emitter.off.bind(emitter),
282
+ once: emitter.once.bind(emitter),
283
+ events: emitter.events.bind(emitter)
284
+ };
285
+ }
286
+ /**
287
+ * Generate a unique ID suitable for a streaming context.
288
+ *
289
+ * Not suitable for security purposes or as a primary key, since
290
+ * it lacks the amount of entropy required for those use cases.
291
+ *
292
+ * @returns A unique ID.
293
+ */
294
+ generateId() {
295
+ return (0, import_human_id.humanId)({
296
+ separator: "-",
297
+ capitalize: false
298
+ });
299
+ }
300
+ /**
301
+ * Authenticate and connect to a Cartesia streaming WebSocket.
302
+ *
303
+ * @returns A promise that resolves when the WebSocket is connected.
304
+ * @throws {Error} If the WebSocket fails to connect.
305
+ */
306
+ connect() {
307
+ const url = constructWebsocketUrl(this.baseUrl);
308
+ url.searchParams.set("api_key", this.apiKey);
309
+ this.socket = new WebSocket(url);
310
+ this.socket.onopen = () => {
311
+ this.isConnected = true;
312
+ };
313
+ this.socket.onclose = () => {
314
+ this.isConnected = false;
315
+ };
316
+ return new Promise((resolve, reject) => {
317
+ var _a, _b, _c;
318
+ (_a = this.socket) == null ? void 0 : _a.addEventListener(
319
+ "open",
320
+ () => {
321
+ resolve();
322
+ },
323
+ {
324
+ once: true
325
+ }
326
+ );
327
+ const aborter = new AbortController();
328
+ (_b = this.socket) == null ? void 0 : _b.addEventListener(
329
+ "error",
330
+ () => {
331
+ aborter.abort();
332
+ reject(new Error("WebSocket failed to connect."));
333
+ },
334
+ {
335
+ signal: aborter.signal
336
+ }
337
+ );
338
+ (_c = this.socket) == null ? void 0 : _c.addEventListener(
339
+ "close",
340
+ () => {
341
+ aborter.abort();
342
+ reject(new Error("WebSocket closed before it could connect."));
343
+ },
344
+ {
345
+ signal: aborter.signal
346
+ }
347
+ );
348
+ });
349
+ }
350
+ /**
351
+ * Disconnect from the Cartesia streaming WebSocket.
352
+ */
353
+ disconnect() {
354
+ var _a;
355
+ (_a = this.socket) == null ? void 0 : _a.close();
356
+ }
357
+ };
358
+
359
+ // src/react/index.ts
360
+ function useAudio({ apiKey, baseUrl }) {
361
+ if (typeof window === "undefined" || !apiKey) {
362
+ return {
363
+ stream: () => {
364
+ },
365
+ play: () => __async(this, null, function* () {
366
+ }),
367
+ isPlaying: false,
368
+ chunks: [],
369
+ messages: []
370
+ };
371
+ }
372
+ const audio = (0, import_react.useMemo)(() => {
373
+ const audio2 = new audio_default({ apiKey, baseUrl });
374
+ return audio2;
375
+ }, [apiKey, baseUrl]);
376
+ const streamReturn = (0, import_react.useRef)(null);
377
+ const [isPlaying, setIsPlaying] = (0, import_react.useState)(false);
378
+ const [chunks, setChunks] = (0, import_react.useState)([]);
379
+ const [messages, setMessages] = (0, import_react.useState)([]);
380
+ const stream = (0, import_react.useCallback)(
381
+ (options) => {
382
+ var _a;
383
+ streamReturn.current = (_a = audio == null ? void 0 : audio.stream(options)) != null ? _a : null;
384
+ streamReturn.current.on(
385
+ "chunk",
386
+ ({ chunks: chunks2 }) => {
387
+ setChunks(chunks2);
388
+ }
389
+ );
390
+ streamReturn.current.on(
391
+ "message",
392
+ (message) => {
393
+ setMessages((messages2) => [...messages2, message]);
394
+ }
395
+ );
396
+ },
397
+ [audio]
398
+ );
399
+ (0, import_react.useEffect)(() => {
400
+ function initialize() {
401
+ return __async(this, null, function* () {
402
+ try {
403
+ yield audio == null ? void 0 : audio.connect();
404
+ } catch (e) {
405
+ console.error(e);
406
+ }
407
+ return () => {
408
+ audio == null ? void 0 : audio.disconnect();
409
+ };
410
+ });
411
+ }
412
+ initialize();
413
+ }, [audio]);
414
+ const play = (0, import_react.useCallback)(
415
+ (bufferDuration = 0) => __async(this, null, function* () {
416
+ var _a;
417
+ if (isPlaying || !streamReturn.current) {
418
+ return;
419
+ }
420
+ setIsPlaying(true);
421
+ yield (_a = streamReturn.current) == null ? void 0 : _a.play({ bufferDuration });
422
+ setIsPlaying(false);
423
+ }),
424
+ [isPlaying]
425
+ );
426
+ return { stream, play, isPlaying, chunks, messages };
427
+ }
428
+ // Annotate the CommonJS export names for ESM import in node:
429
+ 0 && (module.exports = {
430
+ useAudio
431
+ });
@@ -0,0 +1,82 @@
1
+ import {
2
+ audio_default
3
+ } from "../chunk-5RMUZJV7.mjs";
4
+ import "../chunk-BTFHUVNH.mjs";
5
+ import "../chunk-ERFCRIWU.mjs";
6
+ import {
7
+ __async
8
+ } from "../chunk-35HX6ML3.mjs";
9
+
10
+ // src/react/index.ts
11
+ import { useCallback, useEffect, useMemo, useRef, useState } from "react";
12
+ function useAudio({ apiKey, baseUrl }) {
13
+ if (typeof window === "undefined" || !apiKey) {
14
+ return {
15
+ stream: () => {
16
+ },
17
+ play: () => __async(this, null, function* () {
18
+ }),
19
+ isPlaying: false,
20
+ chunks: [],
21
+ messages: []
22
+ };
23
+ }
24
+ const audio = useMemo(() => {
25
+ const audio2 = new audio_default({ apiKey, baseUrl });
26
+ return audio2;
27
+ }, [apiKey, baseUrl]);
28
+ const streamReturn = useRef(null);
29
+ const [isPlaying, setIsPlaying] = useState(false);
30
+ const [chunks, setChunks] = useState([]);
31
+ const [messages, setMessages] = useState([]);
32
+ const stream = useCallback(
33
+ (options) => {
34
+ var _a;
35
+ streamReturn.current = (_a = audio == null ? void 0 : audio.stream(options)) != null ? _a : null;
36
+ streamReturn.current.on(
37
+ "chunk",
38
+ ({ chunks: chunks2 }) => {
39
+ setChunks(chunks2);
40
+ }
41
+ );
42
+ streamReturn.current.on(
43
+ "message",
44
+ (message) => {
45
+ setMessages((messages2) => [...messages2, message]);
46
+ }
47
+ );
48
+ },
49
+ [audio]
50
+ );
51
+ useEffect(() => {
52
+ function initialize() {
53
+ return __async(this, null, function* () {
54
+ try {
55
+ yield audio == null ? void 0 : audio.connect();
56
+ } catch (e) {
57
+ console.error(e);
58
+ }
59
+ return () => {
60
+ audio == null ? void 0 : audio.disconnect();
61
+ };
62
+ });
63
+ }
64
+ initialize();
65
+ }, [audio]);
66
+ const play = useCallback(
67
+ (bufferDuration = 0) => __async(this, null, function* () {
68
+ var _a;
69
+ if (isPlaying || !streamReturn.current) {
70
+ return;
71
+ }
72
+ setIsPlaying(true);
73
+ yield (_a = streamReturn.current) == null ? void 0 : _a.play({ bufferDuration });
74
+ setIsPlaying(false);
75
+ }),
76
+ [isPlaying]
77
+ );
78
+ return { stream, play, isPlaying, chunks, messages };
79
+ }
80
+ export {
81
+ useAudio
82
+ };
@@ -0,0 +1,6 @@
1
+ interface ClientOptions {
2
+ apiKey?: string;
3
+ baseUrl?: string;
4
+ }
5
+
6
+ export type { ClientOptions };
@@ -0,0 +1,6 @@
1
+ interface ClientOptions {
2
+ apiKey?: string;
3
+ baseUrl?: string;
4
+ }
5
+
6
+ export type { ClientOptions };
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __copyProps = (to, from, except, desc) => {
7
+ if (from && typeof from === "object" || typeof from === "function") {
8
+ for (let key of __getOwnPropNames(from))
9
+ if (!__hasOwnProp.call(to, key) && key !== except)
10
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
11
+ }
12
+ return to;
13
+ };
14
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
15
+
16
+ // src/types/index.ts
17
+ var types_exports = {};
18
+ module.exports = __toCommonJS(types_exports);
File without changes
package/index.ts ADDED
@@ -0,0 +1,3 @@
1
+ export { Cartesia as default } from "./src/lib";
2
+ export * from "./src/lib";
3
+ export * from "./src/types";
package/package.json ADDED
@@ -0,0 +1,50 @@
1
+ {
2
+ "name": "@cartesia/cartesia-js",
3
+ "author": {
4
+ "name": "Cartesia",
5
+ "url": "https://cartesia.ai"
6
+ },
7
+ "version": "0.0.1",
8
+ "description": "Client for the Cartesia API.",
9
+ "main": "./dist/index.js",
10
+ "module": "./dist/index.mjs",
11
+ "types": "./dist/index.d.ts",
12
+ "exports": {
13
+ ".": {
14
+ "import": "./dist/index.mjs",
15
+ "require": "./dist/index.js"
16
+ },
17
+ "./react": {
18
+ "import": "./dist/react/index.mjs",
19
+ "require": "./dist/react/index.js"
20
+ }
21
+ },
22
+ "dependencies": {
23
+ "base64-js": "^1.5.1",
24
+ "emittery": "^1.0.3",
25
+ "human-id": "^4.1.1"
26
+ },
27
+ "publishConfig": {
28
+ "access": "restricted"
29
+ },
30
+ "scripts": {
31
+ "build": "tsup src/ --format cjs,esm --dts --clean",
32
+ "dev": "bun run build -- --watch"
33
+ },
34
+ "peerDependencies": {
35
+ "react": "^18.2.0",
36
+ "@types/react": "^18.2.58"
37
+ },
38
+ "peerDependenciesMeta": {
39
+ "react": {
40
+ "optional": true
41
+ },
42
+ "@types/react": {
43
+ "optional": true
44
+ }
45
+ },
46
+ "devDependencies": {
47
+ "@repo/config-typescript": "workspace:*",
48
+ "tsup": "^8.0.2"
49
+ }
50
+ }