@assistant-ui/react 0.3.1 → 0.3.3

Sign up to get free protection for your applications and to get access to all the features.
package/dist/index.mjs CHANGED
@@ -668,7 +668,7 @@ var useContentPartDisplay = () => {
668
668
  throw new Error(
669
669
  "This component can only be used inside ui content parts."
670
670
  );
671
- return c.part.display;
671
+ return c;
672
672
  });
673
673
  return display;
674
674
  };
@@ -681,7 +681,7 @@ var useContentPartImage = () => {
681
681
  throw new Error(
682
682
  "ContentPartImage can only be used inside image content parts."
683
683
  );
684
- return c.part.image;
684
+ return c;
685
685
  });
686
686
  return image;
687
687
  };
@@ -1163,13 +1163,92 @@ var ContentPartProvider = ({
1163
1163
  // src/primitives/contentPart/ContentPartText.tsx
1164
1164
  import { Primitive as Primitive4 } from "@radix-ui/react-primitive";
1165
1165
  import { forwardRef as forwardRef7 } from "react";
1166
+
1167
+ // src/utils/hooks/useSmooth.tsx
1168
+ import { useEffect as useEffect8, useState as useState5 } from "react";
1169
+ var TextStreamAnimator = class {
1170
+ constructor(setText) {
1171
+ this.setText = setText;
1172
+ }
1173
+ animationFrameId = null;
1174
+ lastUpdateTime = Date.now();
1175
+ targetText = "";
1176
+ start() {
1177
+ if (this.animationFrameId !== null) return;
1178
+ this.lastUpdateTime = Date.now();
1179
+ this.animate();
1180
+ }
1181
+ stop() {
1182
+ if (this.animationFrameId !== null) {
1183
+ cancelAnimationFrame(this.animationFrameId);
1184
+ this.animationFrameId = null;
1185
+ }
1186
+ }
1187
+ animate = () => {
1188
+ const currentTime = Date.now();
1189
+ const deltaTime = currentTime - this.lastUpdateTime;
1190
+ let timeToConsume = deltaTime;
1191
+ this.setText((currentText) => {
1192
+ const targetText = this.targetText;
1193
+ if (currentText === targetText) {
1194
+ this.animationFrameId = null;
1195
+ return currentText;
1196
+ }
1197
+ const remainingChars = targetText.length - currentText.length;
1198
+ const baseTimePerChar = Math.min(5, 250 / remainingChars);
1199
+ let charsToAdd = 0;
1200
+ while (timeToConsume >= baseTimePerChar && charsToAdd < remainingChars) {
1201
+ charsToAdd++;
1202
+ timeToConsume -= baseTimePerChar;
1203
+ }
1204
+ this.animationFrameId = requestAnimationFrame(this.animate);
1205
+ if (charsToAdd === 0) {
1206
+ return currentText;
1207
+ }
1208
+ const newText = targetText.slice(0, currentText.length + charsToAdd);
1209
+ this.lastUpdateTime = currentTime - timeToConsume;
1210
+ return newText;
1211
+ });
1212
+ };
1213
+ };
1214
+ var useSmooth = (text, smooth = false) => {
1215
+ const [displayedText, setDisplayedText] = useState5(text);
1216
+ const [animatorRef] = useState5(
1217
+ new TextStreamAnimator(setDisplayedText)
1218
+ );
1219
+ useEffect8(() => {
1220
+ console.log("smooth", smooth);
1221
+ if (!smooth) {
1222
+ animatorRef.stop();
1223
+ return;
1224
+ }
1225
+ if (!text.startsWith(animatorRef.targetText)) {
1226
+ setDisplayedText(text);
1227
+ animatorRef.targetText = text;
1228
+ animatorRef.stop();
1229
+ return;
1230
+ }
1231
+ animatorRef.targetText = text;
1232
+ animatorRef.start();
1233
+ console.log("animating");
1234
+ }, [animatorRef, smooth, text]);
1235
+ useEffect8(() => {
1236
+ return () => {
1237
+ animatorRef.stop();
1238
+ };
1239
+ }, [animatorRef]);
1240
+ return smooth ? displayedText : text;
1241
+ };
1242
+
1243
+ // src/primitives/contentPart/ContentPartText.tsx
1166
1244
  import { jsx as jsx14 } from "react/jsx-runtime";
1167
- var ContentPartPrimitiveText = forwardRef7((props, forwardedRef) => {
1245
+ var ContentPartPrimitiveText = forwardRef7(({ smooth = true, ...rest }, forwardedRef) => {
1168
1246
  const {
1169
- part: { text },
1170
- status
1247
+ status,
1248
+ part: { text }
1171
1249
  } = useContentPartText();
1172
- return /* @__PURE__ */ jsx14(Primitive4.span, { "data-status": status, ...props, ref: forwardedRef, children: text });
1250
+ const smoothText = useSmooth(text, smooth);
1251
+ return /* @__PURE__ */ jsx14(Primitive4.span, { "data-status": status, ...rest, ref: forwardedRef, children: smoothText });
1173
1252
  });
1174
1253
  ContentPartPrimitiveText.displayName = "ContentPartPrimitive.Text";
1175
1254
 
@@ -1178,14 +1257,18 @@ import { Primitive as Primitive5 } from "@radix-ui/react-primitive";
1178
1257
  import { forwardRef as forwardRef8 } from "react";
1179
1258
  import { jsx as jsx15 } from "react/jsx-runtime";
1180
1259
  var ContentPartPrimitiveImage = forwardRef8((props, forwardedRef) => {
1181
- const image = useContentPartImage();
1260
+ const {
1261
+ part: { image }
1262
+ } = useContentPartImage();
1182
1263
  return /* @__PURE__ */ jsx15(Primitive5.img, { src: image, ...props, ref: forwardedRef });
1183
1264
  });
1184
1265
  ContentPartPrimitiveImage.displayName = "ContentPartPrimitive.Image";
1185
1266
 
1186
1267
  // src/primitives/contentPart/ContentPartDisplay.tsx
1187
1268
  var ContentPartPrimitiveDisplay = () => {
1188
- const display = useContentPartDisplay();
1269
+ const {
1270
+ part: { display }
1271
+ } = useContentPartDisplay();
1189
1272
  return display ?? null;
1190
1273
  };
1191
1274
  ContentPartPrimitiveDisplay.displayName = "ContentPartPrimitive.Display";
@@ -1331,7 +1414,7 @@ import { Slot } from "@radix-ui/react-slot";
1331
1414
  import {
1332
1415
  forwardRef as forwardRef11,
1333
1416
  useCallback as useCallback15,
1334
- useEffect as useEffect8,
1417
+ useEffect as useEffect9,
1335
1418
  useRef as useRef4
1336
1419
  } from "react";
1337
1420
  import TextareaAutosize from "react-textarea-autosize";
@@ -1375,7 +1458,7 @@ var ComposerPrimitiveInput = forwardRef11(
1375
1458
  textareaRef.current.value.length
1376
1459
  );
1377
1460
  }, [autoFocusEnabled]);
1378
- useEffect8(() => focus(), [focus]);
1461
+ useEffect9(() => focus(), [focus]);
1379
1462
  useOnComposerFocus(() => {
1380
1463
  if (type === "new") {
1381
1464
  focus();
@@ -1536,11 +1619,11 @@ var useOnResizeContent = (callback) => {
1536
1619
 
1537
1620
  // src/utils/hooks/useOnScrollToBottom.tsx
1538
1621
  import { useCallbackRef as useCallbackRef3 } from "@radix-ui/react-use-callback-ref";
1539
- import { useEffect as useEffect9 } from "react";
1622
+ import { useEffect as useEffect10 } from "react";
1540
1623
  var useOnScrollToBottom = (callback) => {
1541
1624
  const callbackRef = useCallbackRef3(callback);
1542
1625
  const { useViewport } = useThreadContext();
1543
- useEffect9(() => {
1626
+ useEffect10(() => {
1544
1627
  return useViewport.getState().onScrollToBottom(() => {
1545
1628
  callbackRef();
1546
1629
  });
@@ -1615,7 +1698,7 @@ ThreadPrimitiveViewport.displayName = "ThreadPrimitive.Viewport";
1615
1698
  import { memo as memo3 } from "react";
1616
1699
 
1617
1700
  // src/context/providers/MessageProvider.tsx
1618
- import { useEffect as useEffect10, useState as useState5 } from "react";
1701
+ import { useEffect as useEffect11, useState as useState6 } from "react";
1619
1702
  import { create as create12 } from "zustand";
1620
1703
 
1621
1704
  // src/context/stores/EditComposer.ts
@@ -1677,7 +1760,7 @@ var syncMessage = (messages, getBranches, useMessage, messageIndex) => {
1677
1760
  };
1678
1761
  var useMessageContext2 = (messageIndex) => {
1679
1762
  const { useThreadMessages, useThreadActions } = useThreadContext();
1680
- const [context] = useState5(() => {
1763
+ const [context] = useState6(() => {
1681
1764
  const useMessage = create12(() => ({}));
1682
1765
  const useMessageUtils = makeMessageUtilsStore();
1683
1766
  const useEditComposer = makeEditComposerStore({
@@ -1714,7 +1797,7 @@ var useMessageContext2 = (messageIndex) => {
1714
1797
  );
1715
1798
  return { useMessage, useMessageUtils, useEditComposer };
1716
1799
  });
1717
- useEffect10(() => {
1800
+ useEffect11(() => {
1718
1801
  return useThreadMessages.subscribe((thread) => {
1719
1802
  syncMessage(
1720
1803
  thread,
@@ -1797,7 +1880,7 @@ var ThreadPrimitiveSuggestion = createActionButton(
1797
1880
  );
1798
1881
 
1799
1882
  // src/runtime/local/useLocalRuntime.tsx
1800
- import { useInsertionEffect as useInsertionEffect3, useState as useState6 } from "react";
1883
+ import { useInsertionEffect as useInsertionEffect3, useState as useState7 } from "react";
1801
1884
 
1802
1885
  // src/runtime/utils/idUtils.tsx
1803
1886
  import { customAlphabet } from "nanoid/non-secure";
@@ -2139,7 +2222,7 @@ var LocalThreadRuntime = class {
2139
2222
 
2140
2223
  // src/runtime/local/useLocalRuntime.tsx
2141
2224
  var useLocalRuntime = (adapter) => {
2142
- const [runtime] = useState6(() => new LocalRuntime(adapter));
2225
+ const [runtime] = useState7(() => new LocalRuntime(adapter));
2143
2226
  useInsertionEffect3(() => {
2144
2227
  runtime.adapter = adapter;
2145
2228
  });
@@ -2151,7 +2234,8 @@ var internal_exports = {};
2151
2234
  __export(internal_exports, {
2152
2235
  BaseAssistantRuntime: () => BaseAssistantRuntime,
2153
2236
  MessageRepository: () => MessageRepository,
2154
- ProxyConfigProvider: () => ProxyConfigProvider
2237
+ ProxyConfigProvider: () => ProxyConfigProvider,
2238
+ useSmooth: () => useSmooth
2155
2239
  });
2156
2240
  export {
2157
2241
  actionBar_exports as ActionBarPrimitive,