@outkit-dev/react 0.0.3 → 0.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -22,6 +22,11 @@ var index_exports = {};
22
22
  __export(index_exports, {
23
23
  AIRenderer: () => AIRenderer,
24
24
  OUTKIT_TOKENS: () => import_renderer2.OUTKIT_TOKENS,
25
+ completePartialJson: () => completePartialJson,
26
+ expandWireBlock: () => expandWireBlock,
27
+ extractCompleteBlocks: () => extractCompleteBlocks,
28
+ isRenderableBlock: () => isRenderableBlock,
29
+ parseStreamingBlocks: () => parseStreamingBlocks,
25
30
  useBlockStream: () => useBlockStream
26
31
  });
27
32
  module.exports = __toCommonJS(index_exports);
@@ -223,6 +228,149 @@ var SingleComponent = (0, import_react.memo)(function SingleComponent2({
223
228
 
224
229
  // src/use-block-stream.ts
225
230
  var import_react2 = require("react");
231
+
232
+ // src/streaming/complete-partial-json.ts
233
+ function completePartialJson(partial) {
234
+ let inString = false;
235
+ let escaped = false;
236
+ const stack = [];
237
+ for (let i = 0; i < partial.length; i++) {
238
+ const ch = partial[i];
239
+ if (escaped) {
240
+ escaped = false;
241
+ continue;
242
+ }
243
+ if (ch === "\\" && inString) {
244
+ escaped = true;
245
+ continue;
246
+ }
247
+ if (ch === '"') {
248
+ inString = !inString;
249
+ continue;
250
+ }
251
+ if (inString) continue;
252
+ if (ch === "{") stack.push("}");
253
+ else if (ch === "[") stack.push("]");
254
+ else if ((ch === "}" || ch === "]") && stack.length > 0 && stack[stack.length - 1] === ch) {
255
+ stack.pop();
256
+ }
257
+ }
258
+ let result = partial;
259
+ if (inString) {
260
+ if (escaped) result = result.slice(0, -1);
261
+ const trailingUnicode = result.match(/\\u[0-9a-fA-F]{0,3}$/);
262
+ if (trailingUnicode) {
263
+ result = result.slice(0, -trailingUnicode[0].length);
264
+ }
265
+ result += '"';
266
+ }
267
+ while (stack.length > 0) {
268
+ result += stack.pop();
269
+ }
270
+ return result;
271
+ }
272
+
273
+ // src/streaming/parse-streaming-blocks.ts
274
+ function expandWireBlock(block) {
275
+ if ("type" in block && "component" in block) return block;
276
+ if ("type" in block && block.type === "text") return block;
277
+ if (typeof block.c === "string" && typeof block.p === "object" && block.p !== null) {
278
+ return {
279
+ type: "component",
280
+ component: block.c,
281
+ version: block.v ?? "1.0",
282
+ props: block.p,
283
+ ...block.f !== void 0 ? { fallback: block.f } : {},
284
+ ...block.m ? { meta: block.m } : {}
285
+ };
286
+ }
287
+ return block;
288
+ }
289
+ function isRenderableBlock(block) {
290
+ if (!block || typeof block !== "object") return false;
291
+ const b = block;
292
+ if (b.type === "text" && typeof b.content === "string" && b.content.length > 0)
293
+ return true;
294
+ if (b.type === "component" && typeof b.component === "string" && b.component.length >= 2 && typeof b.props === "object" && b.props !== null)
295
+ return true;
296
+ return false;
297
+ }
298
+ function extractCompleteBlocks(accumulated) {
299
+ const blocksIdx = accumulated.indexOf('"blocks"');
300
+ let arrayStart = -1;
301
+ if (blocksIdx !== -1) {
302
+ arrayStart = accumulated.indexOf("[", blocksIdx);
303
+ } else {
304
+ arrayStart = accumulated.indexOf("[");
305
+ }
306
+ if (arrayStart === -1) return [];
307
+ const content = accumulated.slice(arrayStart + 1);
308
+ const blocks = [];
309
+ let depth = 0;
310
+ let blockStart = -1;
311
+ let inString = false;
312
+ let escaped = false;
313
+ for (let i = 0; i < content.length; i++) {
314
+ const ch = content[i];
315
+ if (escaped) {
316
+ escaped = false;
317
+ continue;
318
+ }
319
+ if (ch === "\\" && inString) {
320
+ escaped = true;
321
+ continue;
322
+ }
323
+ if (ch === '"') {
324
+ inString = !inString;
325
+ continue;
326
+ }
327
+ if (inString) continue;
328
+ if (ch === "{") {
329
+ if (depth === 0) blockStart = i;
330
+ depth++;
331
+ } else if (ch === "}") {
332
+ depth--;
333
+ if (depth === 0 && blockStart !== -1) {
334
+ try {
335
+ const parsed = JSON.parse(content.slice(blockStart, i + 1));
336
+ const expanded = expandWireBlock(parsed);
337
+ if (isRenderableBlock(expanded)) blocks.push(expanded);
338
+ } catch {
339
+ }
340
+ blockStart = -1;
341
+ }
342
+ }
343
+ }
344
+ return blocks;
345
+ }
346
+ function parseStreamingBlocks(accumulated) {
347
+ if (!accumulated.trim()) return [];
348
+ let target = accumulated;
349
+ const blocksIdx = accumulated.indexOf('"blocks"');
350
+ if (blocksIdx > 0) {
351
+ let braceIdx = blocksIdx - 1;
352
+ while (braceIdx >= 0 && accumulated[braceIdx] !== "{") braceIdx--;
353
+ if (braceIdx > 0) target = accumulated.slice(braceIdx);
354
+ }
355
+ const patched = completePartialJson(target);
356
+ try {
357
+ const parsed = JSON.parse(patched);
358
+ const rawBlocks = parsed?.blocks ?? (Array.isArray(parsed) ? parsed : []);
359
+ return rawBlocks.map((b) => {
360
+ if (!b || typeof b !== "object") return b;
361
+ return expandWireBlock(b);
362
+ }).filter(isRenderableBlock).map((block) => {
363
+ if (!("version" in block)) {
364
+ return Object.assign({}, block, { version: "1.0" });
365
+ }
366
+ return block;
367
+ });
368
+ } catch {
369
+ return extractCompleteBlocks(accumulated);
370
+ }
371
+ }
372
+
373
+ // src/use-block-stream.ts
226
374
  function useBlockStream() {
227
375
  const [blocks, setBlocks] = (0, import_react2.useState)([]);
228
376
  const [isStreaming, setIsStreaming] = (0, import_react2.useState)(false);
@@ -230,6 +378,9 @@ function useBlockStream() {
230
378
  const pendingRef = (0, import_react2.useRef)(null);
231
379
  const rafRef = (0, import_react2.useRef)(0);
232
380
  const streamingRef = (0, import_react2.useRef)(false);
381
+ const accumulatedRef = (0, import_react2.useRef)("");
382
+ const designReceivedRef = (0, import_react2.useRef)(false);
383
+ const bufferedBlocksRef = (0, import_react2.useRef)(null);
233
384
  const flush = (0, import_react2.useCallback)(() => {
234
385
  rafRef.current = 0;
235
386
  if (pendingRef.current !== null) {
@@ -271,11 +422,50 @@ function useBlockStream() {
271
422
  rafRef.current = 0;
272
423
  }
273
424
  pendingRef.current = null;
425
+ accumulatedRef.current = "";
426
+ bufferedBlocksRef.current = null;
427
+ designReceivedRef.current = false;
274
428
  streamingRef.current = false;
275
429
  setBlocks([]);
276
430
  setIsStreaming(false);
277
431
  setDesignState(void 0);
278
432
  }, []);
433
+ const feedChunk = (0, import_react2.useCallback)(
434
+ (data) => {
435
+ accumulatedRef.current += data;
436
+ const parsed = parseStreamingBlocks(accumulatedRef.current);
437
+ if (parsed.length > 0) {
438
+ if (designReceivedRef.current) {
439
+ push(parsed);
440
+ } else {
441
+ bufferedBlocksRef.current = parsed;
442
+ }
443
+ }
444
+ },
445
+ [push]
446
+ );
447
+ const feedMeta = (0, import_react2.useCallback)(
448
+ (tokens) => {
449
+ designReceivedRef.current = true;
450
+ setDesignState(tokens);
451
+ if (bufferedBlocksRef.current) {
452
+ push(bufferedBlocksRef.current);
453
+ bufferedBlocksRef.current = null;
454
+ }
455
+ },
456
+ [push]
457
+ );
458
+ const feedDone = (0, import_react2.useCallback)(() => {
459
+ if (accumulatedRef.current) {
460
+ const parsed = parseStreamingBlocks(accumulatedRef.current);
461
+ if (parsed.length > 0) {
462
+ pendingRef.current = parsed;
463
+ }
464
+ }
465
+ accumulatedRef.current = "";
466
+ bufferedBlocksRef.current = null;
467
+ complete();
468
+ }, [complete]);
279
469
  (0, import_react2.useEffect)(() => {
280
470
  return () => {
281
471
  if (rafRef.current) {
@@ -283,7 +473,7 @@ function useBlockStream() {
283
473
  }
284
474
  };
285
475
  }, []);
286
- return { blocks, isStreaming, design, push, setDesign, complete, reset };
476
+ return { blocks, isStreaming, design, feedChunk, feedMeta, feedDone, push, setDesign, complete, reset };
287
477
  }
288
478
 
289
479
  // src/index.ts
@@ -292,5 +482,10 @@ var import_renderer2 = require("@outkit-dev/renderer");
292
482
  0 && (module.exports = {
293
483
  AIRenderer,
294
484
  OUTKIT_TOKENS,
485
+ completePartialJson,
486
+ expandWireBlock,
487
+ extractCompleteBlocks,
488
+ isRenderableBlock,
489
+ parseStreamingBlocks,
295
490
  useBlockStream
296
491
  });
package/dist/index.d.cts CHANGED
@@ -43,6 +43,12 @@ interface UseBlockStreamReturn {
43
43
  isStreaming: boolean;
44
44
  /** Design tokens received from the stream's meta event. Pass to <AIRenderer design={design} />. */
45
45
  design: Record<string, string> | undefined;
46
+ /** Append a raw SSE data chunk. Parses accumulated buffer and updates blocks. */
47
+ feedChunk: (data: string) => void;
48
+ /** Set design tokens from a meta SSE event. Alias for setDesign. */
49
+ feedMeta: (tokens: Record<string, string>) => void;
50
+ /** Signal end of stream. Final parse + flush + mark complete. */
51
+ feedDone: () => void;
46
52
  /** Push a new full blocks array (the latest snapshot). Batched at 60fps. */
47
53
  push: (blocks: ContentBlock[]) => void;
48
54
  /** Set design tokens (typically from a meta SSE event). */
@@ -71,4 +77,35 @@ interface UseBlockStreamReturn {
71
77
  */
72
78
  declare function useBlockStream(): UseBlockStreamReturn;
73
79
 
74
- export { AIRenderer, type AIRendererProps, type UseBlockStreamReturn, useBlockStream };
80
+ /**
81
+ * Close unclosed strings, arrays, and objects so partial JSON can be parsed.
82
+ *
83
+ * As the LLM streams a JSON structure token by token, this function patches
84
+ * the accumulated buffer into valid JSON at every chunk boundary. This lets
85
+ * content stream character-by-character while remaining parseable.
86
+ */
87
+ declare function completePartialJson(partial: string): string;
88
+
89
+ /** Expand a compact wire-format block (c/v/p/f/m) into the full ContentBlock shape. */
90
+ declare function expandWireBlock(block: Record<string, unknown>): Record<string, unknown>;
91
+ /** Check if a parsed object is a renderable block. */
92
+ declare function isRenderableBlock(block: unknown): block is ContentBlock;
93
+ /** Fallback: extract only fully brace-matched block objects from accumulated data. */
94
+ declare function extractCompleteBlocks(accumulated: string): ContentBlock[];
95
+ /**
96
+ * Parse streaming LLM JSON into renderable blocks.
97
+ *
98
+ * Call this with the full accumulated buffer on every chunk. It closes
99
+ * unclosed strings/arrays/objects via `completePartialJson`, parses the
100
+ * result, and returns all currently renderable blocks.
101
+ *
102
+ * Handles both wire format (`{ c, v, p }`) and expanded format
103
+ * (`{ type, component, version, props }`). The renderer's `normalizeBlock()`
104
+ * also handles wire format at render time as a further safety net.
105
+ *
106
+ * @param accumulated - The full accumulated raw LLM output so far
107
+ * @returns Array of renderable ContentBlock objects
108
+ */
109
+ declare function parseStreamingBlocks(accumulated: string): ContentBlock[];
110
+
111
+ export { AIRenderer, type AIRendererProps, type UseBlockStreamReturn, completePartialJson, expandWireBlock, extractCompleteBlocks, isRenderableBlock, parseStreamingBlocks, useBlockStream };
package/dist/index.d.ts CHANGED
@@ -43,6 +43,12 @@ interface UseBlockStreamReturn {
43
43
  isStreaming: boolean;
44
44
  /** Design tokens received from the stream's meta event. Pass to <AIRenderer design={design} />. */
45
45
  design: Record<string, string> | undefined;
46
+ /** Append a raw SSE data chunk. Parses accumulated buffer and updates blocks. */
47
+ feedChunk: (data: string) => void;
48
+ /** Set design tokens from a meta SSE event. Alias for setDesign. */
49
+ feedMeta: (tokens: Record<string, string>) => void;
50
+ /** Signal end of stream. Final parse + flush + mark complete. */
51
+ feedDone: () => void;
46
52
  /** Push a new full blocks array (the latest snapshot). Batched at 60fps. */
47
53
  push: (blocks: ContentBlock[]) => void;
48
54
  /** Set design tokens (typically from a meta SSE event). */
@@ -71,4 +77,35 @@ interface UseBlockStreamReturn {
71
77
  */
72
78
  declare function useBlockStream(): UseBlockStreamReturn;
73
79
 
74
- export { AIRenderer, type AIRendererProps, type UseBlockStreamReturn, useBlockStream };
80
+ /**
81
+ * Close unclosed strings, arrays, and objects so partial JSON can be parsed.
82
+ *
83
+ * As the LLM streams a JSON structure token by token, this function patches
84
+ * the accumulated buffer into valid JSON at every chunk boundary. This lets
85
+ * content stream character-by-character while remaining parseable.
86
+ */
87
+ declare function completePartialJson(partial: string): string;
88
+
89
+ /** Expand a compact wire-format block (c/v/p/f/m) into the full ContentBlock shape. */
90
+ declare function expandWireBlock(block: Record<string, unknown>): Record<string, unknown>;
91
+ /** Check if a parsed object is a renderable block. */
92
+ declare function isRenderableBlock(block: unknown): block is ContentBlock;
93
+ /** Fallback: extract only fully brace-matched block objects from accumulated data. */
94
+ declare function extractCompleteBlocks(accumulated: string): ContentBlock[];
95
+ /**
96
+ * Parse streaming LLM JSON into renderable blocks.
97
+ *
98
+ * Call this with the full accumulated buffer on every chunk. It closes
99
+ * unclosed strings/arrays/objects via `completePartialJson`, parses the
100
+ * result, and returns all currently renderable blocks.
101
+ *
102
+ * Handles both wire format (`{ c, v, p }`) and expanded format
103
+ * (`{ type, component, version, props }`). The renderer's `normalizeBlock()`
104
+ * also handles wire format at render time as a further safety net.
105
+ *
106
+ * @param accumulated - The full accumulated raw LLM output so far
107
+ * @returns Array of renderable ContentBlock objects
108
+ */
109
+ declare function parseStreamingBlocks(accumulated: string): ContentBlock[];
110
+
111
+ export { AIRenderer, type AIRendererProps, type UseBlockStreamReturn, completePartialJson, expandWireBlock, extractCompleteBlocks, isRenderableBlock, parseStreamingBlocks, useBlockStream };
package/dist/index.js CHANGED
@@ -195,6 +195,149 @@ var SingleComponent = memo(function SingleComponent2({
195
195
 
196
196
  // src/use-block-stream.ts
197
197
  import { useCallback, useEffect as useEffect2, useRef as useRef2, useState } from "react";
198
+
199
+ // src/streaming/complete-partial-json.ts
200
+ function completePartialJson(partial) {
201
+ let inString = false;
202
+ let escaped = false;
203
+ const stack = [];
204
+ for (let i = 0; i < partial.length; i++) {
205
+ const ch = partial[i];
206
+ if (escaped) {
207
+ escaped = false;
208
+ continue;
209
+ }
210
+ if (ch === "\\" && inString) {
211
+ escaped = true;
212
+ continue;
213
+ }
214
+ if (ch === '"') {
215
+ inString = !inString;
216
+ continue;
217
+ }
218
+ if (inString) continue;
219
+ if (ch === "{") stack.push("}");
220
+ else if (ch === "[") stack.push("]");
221
+ else if ((ch === "}" || ch === "]") && stack.length > 0 && stack[stack.length - 1] === ch) {
222
+ stack.pop();
223
+ }
224
+ }
225
+ let result = partial;
226
+ if (inString) {
227
+ if (escaped) result = result.slice(0, -1);
228
+ const trailingUnicode = result.match(/\\u[0-9a-fA-F]{0,3}$/);
229
+ if (trailingUnicode) {
230
+ result = result.slice(0, -trailingUnicode[0].length);
231
+ }
232
+ result += '"';
233
+ }
234
+ while (stack.length > 0) {
235
+ result += stack.pop();
236
+ }
237
+ return result;
238
+ }
239
+
240
+ // src/streaming/parse-streaming-blocks.ts
241
+ function expandWireBlock(block) {
242
+ if ("type" in block && "component" in block) return block;
243
+ if ("type" in block && block.type === "text") return block;
244
+ if (typeof block.c === "string" && typeof block.p === "object" && block.p !== null) {
245
+ return {
246
+ type: "component",
247
+ component: block.c,
248
+ version: block.v ?? "1.0",
249
+ props: block.p,
250
+ ...block.f !== void 0 ? { fallback: block.f } : {},
251
+ ...block.m ? { meta: block.m } : {}
252
+ };
253
+ }
254
+ return block;
255
+ }
256
+ function isRenderableBlock(block) {
257
+ if (!block || typeof block !== "object") return false;
258
+ const b = block;
259
+ if (b.type === "text" && typeof b.content === "string" && b.content.length > 0)
260
+ return true;
261
+ if (b.type === "component" && typeof b.component === "string" && b.component.length >= 2 && typeof b.props === "object" && b.props !== null)
262
+ return true;
263
+ return false;
264
+ }
265
+ function extractCompleteBlocks(accumulated) {
266
+ const blocksIdx = accumulated.indexOf('"blocks"');
267
+ let arrayStart = -1;
268
+ if (blocksIdx !== -1) {
269
+ arrayStart = accumulated.indexOf("[", blocksIdx);
270
+ } else {
271
+ arrayStart = accumulated.indexOf("[");
272
+ }
273
+ if (arrayStart === -1) return [];
274
+ const content = accumulated.slice(arrayStart + 1);
275
+ const blocks = [];
276
+ let depth = 0;
277
+ let blockStart = -1;
278
+ let inString = false;
279
+ let escaped = false;
280
+ for (let i = 0; i < content.length; i++) {
281
+ const ch = content[i];
282
+ if (escaped) {
283
+ escaped = false;
284
+ continue;
285
+ }
286
+ if (ch === "\\" && inString) {
287
+ escaped = true;
288
+ continue;
289
+ }
290
+ if (ch === '"') {
291
+ inString = !inString;
292
+ continue;
293
+ }
294
+ if (inString) continue;
295
+ if (ch === "{") {
296
+ if (depth === 0) blockStart = i;
297
+ depth++;
298
+ } else if (ch === "}") {
299
+ depth--;
300
+ if (depth === 0 && blockStart !== -1) {
301
+ try {
302
+ const parsed = JSON.parse(content.slice(blockStart, i + 1));
303
+ const expanded = expandWireBlock(parsed);
304
+ if (isRenderableBlock(expanded)) blocks.push(expanded);
305
+ } catch {
306
+ }
307
+ blockStart = -1;
308
+ }
309
+ }
310
+ }
311
+ return blocks;
312
+ }
313
+ function parseStreamingBlocks(accumulated) {
314
+ if (!accumulated.trim()) return [];
315
+ let target = accumulated;
316
+ const blocksIdx = accumulated.indexOf('"blocks"');
317
+ if (blocksIdx > 0) {
318
+ let braceIdx = blocksIdx - 1;
319
+ while (braceIdx >= 0 && accumulated[braceIdx] !== "{") braceIdx--;
320
+ if (braceIdx > 0) target = accumulated.slice(braceIdx);
321
+ }
322
+ const patched = completePartialJson(target);
323
+ try {
324
+ const parsed = JSON.parse(patched);
325
+ const rawBlocks = parsed?.blocks ?? (Array.isArray(parsed) ? parsed : []);
326
+ return rawBlocks.map((b) => {
327
+ if (!b || typeof b !== "object") return b;
328
+ return expandWireBlock(b);
329
+ }).filter(isRenderableBlock).map((block) => {
330
+ if (!("version" in block)) {
331
+ return Object.assign({}, block, { version: "1.0" });
332
+ }
333
+ return block;
334
+ });
335
+ } catch {
336
+ return extractCompleteBlocks(accumulated);
337
+ }
338
+ }
339
+
340
+ // src/use-block-stream.ts
198
341
  function useBlockStream() {
199
342
  const [blocks, setBlocks] = useState([]);
200
343
  const [isStreaming, setIsStreaming] = useState(false);
@@ -202,6 +345,9 @@ function useBlockStream() {
202
345
  const pendingRef = useRef2(null);
203
346
  const rafRef = useRef2(0);
204
347
  const streamingRef = useRef2(false);
348
+ const accumulatedRef = useRef2("");
349
+ const designReceivedRef = useRef2(false);
350
+ const bufferedBlocksRef = useRef2(null);
205
351
  const flush = useCallback(() => {
206
352
  rafRef.current = 0;
207
353
  if (pendingRef.current !== null) {
@@ -243,11 +389,50 @@ function useBlockStream() {
243
389
  rafRef.current = 0;
244
390
  }
245
391
  pendingRef.current = null;
392
+ accumulatedRef.current = "";
393
+ bufferedBlocksRef.current = null;
394
+ designReceivedRef.current = false;
246
395
  streamingRef.current = false;
247
396
  setBlocks([]);
248
397
  setIsStreaming(false);
249
398
  setDesignState(void 0);
250
399
  }, []);
400
+ const feedChunk = useCallback(
401
+ (data) => {
402
+ accumulatedRef.current += data;
403
+ const parsed = parseStreamingBlocks(accumulatedRef.current);
404
+ if (parsed.length > 0) {
405
+ if (designReceivedRef.current) {
406
+ push(parsed);
407
+ } else {
408
+ bufferedBlocksRef.current = parsed;
409
+ }
410
+ }
411
+ },
412
+ [push]
413
+ );
414
+ const feedMeta = useCallback(
415
+ (tokens) => {
416
+ designReceivedRef.current = true;
417
+ setDesignState(tokens);
418
+ if (bufferedBlocksRef.current) {
419
+ push(bufferedBlocksRef.current);
420
+ bufferedBlocksRef.current = null;
421
+ }
422
+ },
423
+ [push]
424
+ );
425
+ const feedDone = useCallback(() => {
426
+ if (accumulatedRef.current) {
427
+ const parsed = parseStreamingBlocks(accumulatedRef.current);
428
+ if (parsed.length > 0) {
429
+ pendingRef.current = parsed;
430
+ }
431
+ }
432
+ accumulatedRef.current = "";
433
+ bufferedBlocksRef.current = null;
434
+ complete();
435
+ }, [complete]);
251
436
  useEffect2(() => {
252
437
  return () => {
253
438
  if (rafRef.current) {
@@ -255,7 +440,7 @@ function useBlockStream() {
255
440
  }
256
441
  };
257
442
  }, []);
258
- return { blocks, isStreaming, design, push, setDesign, complete, reset };
443
+ return { blocks, isStreaming, design, feedChunk, feedMeta, feedDone, push, setDesign, complete, reset };
259
444
  }
260
445
 
261
446
  // src/index.ts
@@ -263,5 +448,10 @@ import { OUTKIT_TOKENS } from "@outkit-dev/renderer";
263
448
  export {
264
449
  AIRenderer,
265
450
  OUTKIT_TOKENS,
451
+ completePartialJson,
452
+ expandWireBlock,
453
+ extractCompleteBlocks,
454
+ isRenderableBlock,
455
+ parseStreamingBlocks,
266
456
  useBlockStream
267
457
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@outkit-dev/react",
3
- "version": "0.0.3",
3
+ "version": "0.0.5",
4
4
  "type": "module",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.js",
@@ -16,7 +16,7 @@
16
16
  "dist"
17
17
  ],
18
18
  "dependencies": {
19
- "@outkit-dev/renderer": "0.0.3"
19
+ "@outkit-dev/renderer": "0.0.5"
20
20
  },
21
21
  "peerDependencies": {
22
22
  "react": "^18.0.0 || ^19.0.0"