@assistant-ui/react-native 0.1.44 → 0.1.45
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/LICENSE +1 -1
- package/dist/primitives/actionBar/ActionBarCopy.js.map +1 -1
- package/dist/primitives/actionBar/ActionBarEdit.js.map +1 -1
- package/dist/primitives/actionBar/ActionBarFeedbackNegative.js.map +1 -1
- package/dist/primitives/actionBar/ActionBarFeedbackPositive.js.map +1 -1
- package/dist/primitives/actionBar/ActionBarReload.js.map +1 -1
- package/dist/primitives/actionBar/ActionBarSpeak.js.map +1 -1
- package/dist/primitives/actionBar/ActionBarStopSpeaking.js.map +1 -1
- package/dist/primitives/attachment/AttachmentName.js.map +1 -1
- package/dist/primitives/attachment/AttachmentRemove.js.map +1 -1
- package/dist/primitives/attachment/AttachmentRoot.js.map +1 -1
- package/dist/primitives/attachment/AttachmentThumb.js.map +1 -1
- package/dist/primitives/branchPicker/BranchPickerCount.js.map +1 -1
- package/dist/primitives/branchPicker/BranchPickerNext.js.map +1 -1
- package/dist/primitives/branchPicker/BranchPickerNumber.js.map +1 -1
- package/dist/primitives/branchPicker/BranchPickerPrevious.js.map +1 -1
- package/dist/primitives/chainOfThought/ChainOfThoughtAccordionTrigger.js.map +1 -1
- package/dist/primitives/chainOfThought/ChainOfThoughtRoot.js.map +1 -1
- package/dist/primitives/composer/ComposerAddAttachment.js.map +1 -1
- package/dist/primitives/composer/ComposerCancel.js.map +1 -1
- package/dist/primitives/composer/ComposerInput.js.map +1 -1
- package/dist/primitives/composer/ComposerQuote.js.map +1 -1
- package/dist/primitives/composer/ComposerQuoteDismiss.js.map +1 -1
- package/dist/primitives/composer/ComposerQuoteText.js.map +1 -1
- package/dist/primitives/composer/ComposerRoot.js.map +1 -1
- package/dist/primitives/composer/ComposerSend.js.map +1 -1
- package/dist/primitives/error/ErrorMessage.js.map +1 -1
- package/dist/primitives/error/ErrorRoot.js.map +1 -1
- package/dist/primitives/message/MessageContent.d.ts.map +1 -1
- package/dist/primitives/message/MessageContent.js +43 -33
- package/dist/primitives/message/MessageContent.js.map +1 -1
- package/dist/primitives/message/MessageIf.js.map +1 -1
- package/dist/primitives/message/MessageParts.js.map +1 -1
- package/dist/primitives/message/MessageRoot.js.map +1 -1
- package/dist/primitives/messagePart/MessagePartImage.js.map +1 -1
- package/dist/primitives/messagePart/MessagePartText.js.map +1 -1
- package/dist/primitives/queueItem/QueueItemRemove.js.map +1 -1
- package/dist/primitives/queueItem/QueueItemSteer.js.map +1 -1
- package/dist/primitives/queueItem/QueueItemText.js.map +1 -1
- package/dist/primitives/suggestion/SuggestionDescription.js.map +1 -1
- package/dist/primitives/suggestion/SuggestionTitle.js.map +1 -1
- package/dist/primitives/suggestion/SuggestionTrigger.js.map +1 -1
- package/dist/primitives/thread/ThreadEmpty.js.map +1 -1
- package/dist/primitives/thread/ThreadIf.js.map +1 -1
- package/dist/primitives/thread/ThreadMessages.js.map +1 -1
- package/dist/primitives/thread/ThreadRoot.js.map +1 -1
- package/dist/primitives/thread/ThreadSuggestion.js.map +1 -1
- package/dist/primitives/threadList/ThreadListItems.js.map +1 -1
- package/dist/primitives/threadList/ThreadListNew.js.map +1 -1
- package/dist/primitives/threadList/ThreadListRoot.js.map +1 -1
- package/dist/primitives/threadListItem/ThreadListItemArchive.js.map +1 -1
- package/dist/primitives/threadListItem/ThreadListItemDelete.js.map +1 -1
- package/dist/primitives/threadListItem/ThreadListItemRoot.js.map +1 -1
- package/dist/primitives/threadListItem/ThreadListItemTrigger.js.map +1 -1
- package/dist/primitives/threadListItem/ThreadListItemUnarchive.js.map +1 -1
- package/package.json +12 -9
- package/src/primitives/message/MessageContent.test.tsx +46 -1
- package/src/primitives/message/MessageContent.tsx +3 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { act, type ReactElement } from "react";
|
|
1
|
+
import { act, useState, type ReactElement } from "react";
|
|
2
2
|
import { createRoot, type Root } from "react-dom/client";
|
|
3
3
|
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
4
4
|
import { MessageContent } from "./MessageContent";
|
|
@@ -79,6 +79,51 @@ describe("MessageContent", () => {
|
|
|
79
79
|
});
|
|
80
80
|
};
|
|
81
81
|
|
|
82
|
+
it("keeps a text seed while streaming and resets it for a replacement id", async () => {
|
|
83
|
+
const SeededText = ({ text }: { text: string }) => {
|
|
84
|
+
const [seed] = useState(text);
|
|
85
|
+
return <span>{`${seed}:${text}`}</span>;
|
|
86
|
+
};
|
|
87
|
+
const renderText: NonNullable<
|
|
88
|
+
Parameters<typeof MessageContent>[0]["renderText"]
|
|
89
|
+
> = ({ part }) => <SeededText text={part.text} />;
|
|
90
|
+
|
|
91
|
+
h.state.message.content = [{ type: "text", id: "p1", text: "old" }];
|
|
92
|
+
await mount({ renderText });
|
|
93
|
+
h.state.message.content = [
|
|
94
|
+
{ type: "text", id: "p1", text: "old streamed" },
|
|
95
|
+
];
|
|
96
|
+
await mount({ renderText });
|
|
97
|
+
expect(container.textContent).toBe("old:old streamed");
|
|
98
|
+
|
|
99
|
+
h.state.message.content = [{ type: "text", id: "p2", text: "new" }];
|
|
100
|
+
await mount({ renderText });
|
|
101
|
+
expect(container.textContent).toBe("new:new");
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
it("keeps each seed with its id when identified parts swap", async () => {
|
|
105
|
+
const SeededText = ({ text }: { text: string }) => {
|
|
106
|
+
const [seed] = useState(text);
|
|
107
|
+
return <span>{`${seed}:${text}`}</span>;
|
|
108
|
+
};
|
|
109
|
+
const renderText: NonNullable<
|
|
110
|
+
Parameters<typeof MessageContent>[0]["renderText"]
|
|
111
|
+
> = ({ part }) => <SeededText text={part.text} />;
|
|
112
|
+
h.state.message.content = [
|
|
113
|
+
{ type: "text", id: "p1", text: "first" },
|
|
114
|
+
{ type: "text", id: "p2", text: "second" },
|
|
115
|
+
];
|
|
116
|
+
await mount({ renderText });
|
|
117
|
+
h.state.message.content = [
|
|
118
|
+
{ type: "text", id: "p2", text: "second updated" },
|
|
119
|
+
{ type: "text", id: "p1", text: "first updated" },
|
|
120
|
+
];
|
|
121
|
+
await mount({ renderText });
|
|
122
|
+
expect(
|
|
123
|
+
Array.from(container.querySelectorAll("span"), (el) => el.textContent),
|
|
124
|
+
).toEqual(["second:second updated", "first:first updated"]);
|
|
125
|
+
});
|
|
126
|
+
|
|
82
127
|
it("renders a text part through the default text renderer", async () => {
|
|
83
128
|
h.state.message.content = [{ type: "text", text: "hello world" }];
|
|
84
129
|
await mount();
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type ReactElement, Fragment, useMemo } from "react";
|
|
2
2
|
import { Text } from "react-native";
|
|
3
|
+
import { getMessagePartKeys } from "@assistant-ui/core/internal";
|
|
3
4
|
import type {
|
|
4
5
|
ThreadUserMessagePart,
|
|
5
6
|
ThreadAssistantMessagePart,
|
|
@@ -124,11 +125,12 @@ export const MessageContent = ({
|
|
|
124
125
|
renderData,
|
|
125
126
|
}: MessageContentProps) => {
|
|
126
127
|
const content = useAuiState((s) => s.message.parts);
|
|
128
|
+
const partKeys = getMessagePartKeys(content);
|
|
127
129
|
|
|
128
130
|
return (
|
|
129
131
|
<>
|
|
130
132
|
{content.map((part, index) => {
|
|
131
|
-
const key =
|
|
133
|
+
const key = partKeys[index];
|
|
132
134
|
switch (part.type) {
|
|
133
135
|
case "text":
|
|
134
136
|
return (
|