@rolder/kit 3.0.0-alpha.85 → 3.0.0-alpha.87

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 (48) hide show
  1. package/dist/ai/ui/chat/Root.d.ts +2 -0
  2. package/dist/ai/ui/chat/Root.js +1 -1
  3. package/dist/ai/ui/chat/chatInput/store/input.js +2 -2
  4. package/dist/ai/ui/chat/index.d.ts +8 -8
  5. package/dist/ai/ui/chat/index.js +9 -7
  6. package/dist/ai/ui/chat/messages/Empty.d.ts +4 -0
  7. package/dist/ai/ui/chat/messages/Empty.js +11 -0
  8. package/dist/ai/ui/chat/messages/Loader.d.ts +5 -0
  9. package/dist/ai/ui/chat/{Loader.js → messages/Loader.js} +3 -3
  10. package/dist/ai/ui/chat/messages/Message.d.ts +11 -0
  11. package/dist/ai/ui/chat/messages/Message.js +15 -0
  12. package/dist/ai/ui/chat/messages/Messages.d.ts +2 -0
  13. package/dist/ai/ui/chat/messages/Messages.js +36 -0
  14. package/dist/ai/ui/chat/messages/index.d.ts +2 -0
  15. package/dist/ai/ui/chat/messages/index.js +2 -0
  16. package/dist/ai/ui/chat/parts/File.d.ts +6 -0
  17. package/dist/ai/ui/chat/{File.js → parts/File.js} +4 -5
  18. package/dist/ai/ui/chat/parts/PartPaper.d.ts +8 -0
  19. package/dist/ai/ui/chat/parts/PartPaper.js +14 -0
  20. package/dist/ai/ui/chat/parts/TextPart.d.ts +6 -0
  21. package/dist/ai/ui/chat/parts/TextPart.js +12 -0
  22. package/dist/ai/ui/chat/parts/ToolExecution.d.ts +7 -0
  23. package/dist/ai/ui/chat/parts/ToolExecution.js +54 -0
  24. package/dist/ai/ui/chat/parts/ToolPart.d.ts +9 -0
  25. package/dist/ai/ui/chat/parts/ToolPart.js +25 -0
  26. package/dist/ai/ui/chat/parts/index.d.ts +3 -0
  27. package/dist/ai/ui/chat/parts/index.js +3 -0
  28. package/dist/ai/ui/chat/store/index.d.ts +1 -2
  29. package/dist/ai/ui/chat/store/index.js +1 -2
  30. package/dist/ai/ui/chat/store/messages.d.ts +9 -0
  31. package/dist/ai/ui/chat/store/{messageIds.js → messages.js} +9 -5
  32. package/dist/ai/ui/chat/store/states.d.ts +0 -1
  33. package/dist/ai/ui/chat/store/states.js +1 -2
  34. package/dist/ai/ui/chat/store/useInitChat.js +1 -1
  35. package/package.json +77 -77
  36. package/dist/ai/ui/chat/Empty.d.ts +0 -1
  37. package/dist/ai/ui/chat/Empty.js +0 -21
  38. package/dist/ai/ui/chat/File.d.ts +0 -3
  39. package/dist/ai/ui/chat/Loader.d.ts +0 -2
  40. package/dist/ai/ui/chat/Message.d.ts +0 -3
  41. package/dist/ai/ui/chat/Message.js +0 -23
  42. package/dist/ai/ui/chat/Messages.d.ts +0 -2
  43. package/dist/ai/ui/chat/Messages.js +0 -28
  44. package/dist/ai/ui/chat/store/messageIds.d.ts +0 -8
  45. package/dist/ai/ui/chat/store/messagesMap.d.ts +0 -5
  46. package/dist/ai/ui/chat/store/messagesMap.js +0 -15
  47. /package/dist/ai/ui/chat/{FileIcon.d.ts → parts/FileIcon.d.ts} +0 -0
  48. /package/dist/ai/ui/chat/{FileIcon.js → parts/FileIcon.js} +0 -0
@@ -10,6 +10,8 @@ export interface ChatRootProps extends PaperProps {
10
10
  scrollAreaProps?: Omit<ScrollAreaProps, 'children' | 'h'>;
11
11
  withScrollButton?: boolean;
12
12
  stackProps?: Omit<StackProps, 'p'>;
13
+ emptyComponent?: ReactNode;
14
+ loaderComponent?: ReactNode;
13
15
  chatOptions?: UseChatOptions<UIMessage> & ChatInit<UIMessage>;
14
16
  }
15
17
  /**
@@ -1,5 +1,5 @@
1
1
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
2
- import { Messages } from "./Messages.js";
2
+ import { Messages } from "./messages/index.js";
3
3
  import { useInitChat } from "./store/index.js";
4
4
  const ChatInitializer = ({ chatOptions })=>{
5
5
  useInitChat(chatOptions);
@@ -68,11 +68,11 @@ ${fileContent}
68
68
  } catch (error) {
69
69
  fileErrorNotificaton(error);
70
70
  }
71
- if (onSubmit) onSubmit({
71
+ if (onSubmit && text.trim()) onSubmit({
72
72
  text,
73
73
  file: fileUIPart
74
74
  });
75
- sendMessage({
75
+ if (text.trim()) sendMessage({
76
76
  text,
77
77
  file: fileUIPart
78
78
  });
@@ -1,13 +1,13 @@
1
1
  export declare const Chat: {
2
2
  Root: ({ chatOptions, ...props }: import("./Root").ChatRootProps) => import("react/jsx-runtime").JSX.Element;
3
- Message: ({ messageId }: {
4
- messageId: string;
5
- }) => import("react/jsx-runtime").JSX.Element | null;
6
- File: ({ messageId }: {
7
- messageId: string;
8
- }) => import("react/jsx-runtime").JSX.Element | null;
9
- Empty: () => import("react/jsx-runtime").JSX.Element | null;
10
- Loader: (props: import("@mantine/core").LoaderProps) => import("react/jsx-runtime").JSX.Element | null;
3
+ Message: <TMessage extends import("ai").UIMessage>(props: import("./messages").MessageProps<TMessage>) => React.JSX.Element;
4
+ TextPart: import("react").MemoExoticComponent<({ part, role }: import("./parts").TextPartProps) => import("react/jsx-runtime").JSX.Element>;
5
+ ToolPart: <TPart extends import("ai").ToolUIPart = {
6
+ type: `tool-${string}`;
7
+ } & import("ai").UIToolInvocation<import("ai").UITool>>(props: import("./parts").ToolPartProps<TPart>) => import("react").ReactNode;
8
+ ToolExecution: ({ part, onError }: import("./parts/ToolExecution").ToolExecutionProps) => string | number | bigint | boolean | Iterable<import("react").ReactNode> | Promise<string | number | bigint | boolean | import("react").ReactPortal | import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | Iterable<import("react").ReactNode> | null | undefined> | import("react/jsx-runtime").JSX.Element | null | undefined;
9
+ FilePart: import("react").MemoExoticComponent<({ part, messageId }: import("./parts/File").FilePartProps) => import("react/jsx-runtime").JSX.Element | null>;
10
+ PartPaper: ({ children, chatRole, ...props }: import("./parts").PartPaperProps) => import("react/jsx-runtime").JSX.Element;
11
11
  };
12
12
  export { ChatInput } from './chatInput';
13
13
  export * from './store';
@@ -1,15 +1,17 @@
1
- import { Empty } from "./Empty.js";
2
- import { File } from "./File.js";
3
- import { Loader } from "./Loader.js";
4
- import { Message } from "./Message.js";
1
+ import { Message } from "./messages/index.js";
2
+ import { PartPaper, TextPart, ToolPart } from "./parts/index.js";
3
+ import { FilePart } from "./parts/File.js";
4
+ import { ToolExecution } from "./parts/ToolExecution.js";
5
5
  import { Root } from "./Root.js";
6
6
  import { ChatInput } from "./chatInput/index.js";
7
7
  export * from "./store/index.js";
8
8
  const Chat = {
9
9
  Root: Root,
10
10
  Message: Message,
11
- File: File,
12
- Empty: Empty,
13
- Loader: Loader
11
+ TextPart: TextPart,
12
+ ToolPart: ToolPart,
13
+ ToolExecution: ToolExecution,
14
+ FilePart: FilePart,
15
+ PartPaper: PartPaper
14
16
  };
15
17
  export { Chat, ChatInput };
@@ -0,0 +1,4 @@
1
+ import type { ReactNode } from 'react';
2
+ export declare const Empty: ({ emptyComponent }: {
3
+ emptyComponent?: ReactNode;
4
+ }) => string | number | bigint | boolean | Iterable<ReactNode> | Promise<string | number | bigint | boolean | import("react").ReactPortal | import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | Iterable<ReactNode> | null | undefined> | import("react/jsx-runtime").JSX.Element | null;
@@ -0,0 +1,11 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { Stack, Text } from "@mantine/core";
3
+ import { getIsEmpty } from "../store/index.js";
4
+ const Empty = ({ emptyComponent })=>getIsEmpty() ? emptyComponent ?? /*#__PURE__*/ jsx(Stack, {
5
+ align: "center",
6
+ gap: 0,
7
+ children: /*#__PURE__*/ jsx(Text, {
8
+ children: "Нет сообщений"
9
+ })
10
+ }) : null;
11
+ export { Empty };
@@ -0,0 +1,5 @@
1
+ import { type LoaderProps } from '@mantine/core';
2
+ import type { ReactNode } from 'react';
3
+ export declare const Loader: ({ loaderComponent, ...props }: LoaderProps & {
4
+ loaderComponent?: ReactNode;
5
+ }) => string | number | bigint | boolean | Iterable<ReactNode> | Promise<string | number | bigint | boolean | import("react").ReactPortal | import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | Iterable<ReactNode> | null | undefined> | import("react/jsx-runtime").JSX.Element | null;
@@ -1,10 +1,10 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
2
  import { Loader } from "@mantine/core";
3
- import { useIsLoading, useIsStreaming } from "./store/index.js";
4
- const Loader_Loader = (props)=>{
3
+ import { useIsLoading, useIsStreaming } from "../store/index.js";
4
+ const Loader_Loader = ({ loaderComponent, ...props })=>{
5
5
  const isLoading = useIsLoading();
6
6
  const isStreaming = useIsStreaming();
7
- return isLoading && !isStreaming ? /*#__PURE__*/ jsx(Loader, {
7
+ return isLoading && !isStreaming ? loaderComponent ?? /*#__PURE__*/ jsx(Loader, {
8
8
  size: 28,
9
9
  type: "dots",
10
10
  ...props
@@ -0,0 +1,11 @@
1
+ import { type StackProps } from '@mantine/core';
2
+ import type { UIMessage } from 'ai';
3
+ import { type ReactNode } from 'react';
4
+ export interface MessageProps<TMessage extends UIMessage> extends Omit<StackProps, 'children'> {
5
+ children: ({ parts, role, }: {
6
+ parts: TMessage['parts'];
7
+ role: TMessage['role'];
8
+ }) => ReactNode;
9
+ messageId: string;
10
+ }
11
+ export declare const Message: <TMessage extends UIMessage>(props: MessageProps<TMessage>) => React.JSX.Element;
@@ -0,0 +1,15 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { Stack } from "@mantine/core";
3
+ import { memo } from "react";
4
+ import { useChatMessage } from "../store/index.js";
5
+ const Message = /*#__PURE__*/ memo(({ children, messageId, ...props })=>{
6
+ const message = useChatMessage(messageId);
7
+ return /*#__PURE__*/ jsx(Stack, {
8
+ ...props,
9
+ children: 'function' == typeof children ? children({
10
+ parts: message.parts,
11
+ role: message.role
12
+ }) : null
13
+ });
14
+ });
15
+ export { Message };
@@ -0,0 +1,2 @@
1
+ import type { ChatRootProps } from '../Root';
2
+ export declare const Messages: ({ children, height, radius, padding, scrollAreaProps, withScrollButton, stackProps, emptyComponent, loaderComponent, ...props }: Omit<ChatRootProps, "chatOptions">) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,36 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { Paper, Stack } from "@mantine/core";
3
+ import { ScrollArea } from "../../../../ui/index.js";
4
+ import { useChatMessageIds } from "../store/index.js";
5
+ import { Empty } from "./Empty.js";
6
+ import { Loader } from "./Loader.js";
7
+ const Messages = ({ children, height, radius = 'md', padding = 'md', scrollAreaProps, withScrollButton = true, stackProps, emptyComponent, loaderComponent, ...props })=>{
8
+ const messageIds = useChatMessageIds();
9
+ return /*#__PURE__*/ jsx(Paper, {
10
+ withBorder: true,
11
+ radius: radius,
12
+ ...props,
13
+ children: /*#__PURE__*/ jsxs(ScrollArea.Root, {
14
+ autoScroll: true,
15
+ height: height,
16
+ radius: radius,
17
+ ...scrollAreaProps,
18
+ children: [
19
+ /*#__PURE__*/ jsxs(Stack, {
20
+ p: padding,
21
+ ...stackProps,
22
+ children: [
23
+ messageIds.length ? 'function' == typeof children ? children(messageIds) : null : /*#__PURE__*/ jsx(Empty, {
24
+ emptyComponent: emptyComponent
25
+ }),
26
+ /*#__PURE__*/ jsx(Loader, {
27
+ loaderComponent: loaderComponent
28
+ })
29
+ ]
30
+ }),
31
+ withScrollButton && /*#__PURE__*/ jsx(ScrollArea.ScrollButton, {})
32
+ ]
33
+ })
34
+ });
35
+ };
36
+ export { Messages };
@@ -0,0 +1,2 @@
1
+ export * from './Message';
2
+ export * from './Messages';
@@ -0,0 +1,2 @@
1
+ export * from "./Message.js";
2
+ export * from "./Messages.js";
@@ -0,0 +1,6 @@
1
+ import type { FileUIPart } from 'ai';
2
+ export interface FilePartProps<TPart extends FileUIPart = FileUIPart> {
3
+ part: TPart;
4
+ messageId: string;
5
+ }
6
+ export declare const FilePart: import("react").MemoExoticComponent<({ part, messageId }: FilePartProps) => import("react/jsx-runtime").JSX.Element | null>;
@@ -1,9 +1,8 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
2
  import { Image, Paper } from "@mantine/core";
3
+ import { memo } from "react";
3
4
  import { FileIcon } from "./FileIcon.js";
4
- import { useChatMessagePart } from "./store/index.js";
5
- const File = ({ messageId })=>{
6
- const part = useChatMessagePart(messageId, 'file');
5
+ const FilePart = /*#__PURE__*/ memo(({ part, messageId })=>{
7
6
  const textFileType = messageId.split('-')[1];
8
7
  const FileComponent = ()=>{
9
8
  switch(textFileType){
@@ -39,5 +38,5 @@ const File = ({ messageId })=>{
39
38
  bg: "var(--mantine-color-default-hover)",
40
39
  children: /*#__PURE__*/ jsx(FileComponent, {})
41
40
  }) : null;
42
- };
43
- export { File };
41
+ });
42
+ export { FilePart };
@@ -0,0 +1,8 @@
1
+ import { type PaperProps } from '@mantine/core';
2
+ import type { UIMessage } from 'ai';
3
+ import type { ReactNode } from 'react';
4
+ export interface PartPaperProps extends PaperProps {
5
+ children: ReactNode;
6
+ chatRole: UIMessage['role'];
7
+ }
8
+ export declare const PartPaper: ({ children, chatRole, ...props }: PartPaperProps) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,14 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { Paper } from "@mantine/core";
3
+ const PartPaper = ({ children, chatRole, ...props })=>/*#__PURE__*/ jsx(Paper, {
4
+ radius: "md",
5
+ px: "md",
6
+ py: "sm",
7
+ maw: "80%",
8
+ ml: 'user' === chatRole ? 'auto' : void 0,
9
+ bg: 'user' === chatRole ? 'var(--mantine-color-default-hover)' : 'var(--mantine-primary-color-light)',
10
+ fz: "sm",
11
+ ...props,
12
+ children: children
13
+ });
14
+ export { PartPaper };
@@ -0,0 +1,6 @@
1
+ import type { TextUIPart, UIMessage } from 'ai';
2
+ export interface TextPartProps {
3
+ part: TextUIPart;
4
+ role: UIMessage['role'];
5
+ }
6
+ export declare const TextPart: import("react").MemoExoticComponent<({ part, role }: TextPartProps) => import("react/jsx-runtime").JSX.Element>;
@@ -0,0 +1,12 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { memo } from "react";
3
+ import { Streamdown } from "streamdown";
4
+ import { PartPaper } from "./PartPaper.js";
5
+ const TextPart = /*#__PURE__*/ memo(({ part, role })=>/*#__PURE__*/ jsx(PartPaper, {
6
+ chatRole: role,
7
+ children: /*#__PURE__*/ jsx(Streamdown, {
8
+ isAnimating: 'streaming' === part.state,
9
+ children: part?.text
10
+ })
11
+ }));
12
+ export { TextPart };
@@ -0,0 +1,7 @@
1
+ import type { ToolUIPart } from 'ai';
2
+ import type { ReactNode } from 'react';
3
+ export interface ToolExecutionProps {
4
+ part: ToolUIPart;
5
+ onError?: (error: string) => ReactNode;
6
+ }
7
+ export declare const ToolExecution: ({ part, onError }: ToolExecutionProps) => string | number | bigint | boolean | Iterable<ReactNode> | Promise<string | number | bigint | boolean | import("react").ReactPortal | import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | Iterable<ReactNode> | null | undefined> | import("react/jsx-runtime").JSX.Element | null | undefined;
@@ -0,0 +1,54 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { Group, Loader, Text } from "@mantine/core";
3
+ import { IconCheck } from "@tabler/icons-react";
4
+ const ToolExecution = ({ part, onError })=>{
5
+ switch(part.state){
6
+ case 'input-available':
7
+ return /*#__PURE__*/ jsxs(Group, {
8
+ gap: "xs",
9
+ children: [
10
+ /*#__PURE__*/ jsx(Loader, {
11
+ size: 28,
12
+ type: "dots"
13
+ }),
14
+ /*#__PURE__*/ jsxs(Text, {
15
+ size: "sm",
16
+ children: [
17
+ 'Запускаю "',
18
+ part.title,
19
+ '"...'
20
+ ]
21
+ })
22
+ ]
23
+ });
24
+ case 'output-available':
25
+ return /*#__PURE__*/ jsxs(Group, {
26
+ gap: "xs",
27
+ children: [
28
+ /*#__PURE__*/ jsx(IconCheck, {
29
+ size: 28,
30
+ color: "green"
31
+ }),
32
+ /*#__PURE__*/ jsxs(Text, {
33
+ size: "sm",
34
+ children: [
35
+ '"',
36
+ part.title,
37
+ '" выполнен'
38
+ ]
39
+ })
40
+ ]
41
+ });
42
+ case 'output-error':
43
+ return onError ? onError(part.errorText) : /*#__PURE__*/ jsxs(Text, {
44
+ c: "red",
45
+ children: [
46
+ "Ошибка: ",
47
+ part.errorText
48
+ ]
49
+ });
50
+ default:
51
+ return null;
52
+ }
53
+ };
54
+ export { ToolExecution };
@@ -0,0 +1,9 @@
1
+ import type { ToolUIPart } from 'ai';
2
+ import { type ReactNode } from 'react';
3
+ export interface ToolPartProps<TPart extends ToolUIPart = ToolUIPart> {
4
+ children: (toolOutput: NonNullable<TPart['output']>) => ReactNode;
5
+ part: TPart;
6
+ loader?: ReactNode;
7
+ onError?: (error: string) => ReactNode;
8
+ }
9
+ export declare const ToolPart: <TPart extends ToolUIPart = ToolUIPart>(props: ToolPartProps<TPart>) => ReactNode;
@@ -0,0 +1,25 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { Loader, Text } from "@mantine/core";
3
+ import { memo } from "react";
4
+ const ToolPart = /*#__PURE__*/ memo(({ children, part, loader, onError })=>{
5
+ switch(part.state){
6
+ case 'input-available':
7
+ return loader || /*#__PURE__*/ jsx(Loader, {
8
+ size: 28,
9
+ type: "dots"
10
+ });
11
+ case 'output-available':
12
+ return part.output ? children(part.output) : null;
13
+ case 'output-error':
14
+ return onError ? onError(part.errorText) : /*#__PURE__*/ jsxs(Text, {
15
+ c: "red",
16
+ children: [
17
+ "Ошибка: ",
18
+ part.errorText
19
+ ]
20
+ });
21
+ default:
22
+ return null;
23
+ }
24
+ });
25
+ export { ToolPart };
@@ -0,0 +1,3 @@
1
+ export * from './PartPaper';
2
+ export * from './TextPart';
3
+ export * from './ToolPart';
@@ -0,0 +1,3 @@
1
+ export * from "./PartPaper.js";
2
+ export * from "./TextPart.js";
3
+ export * from "./ToolPart.js";
@@ -1,5 +1,4 @@
1
- export * from './messageIds';
2
- export * from './messagesMap';
1
+ export * from './messages';
3
2
  export * from './send';
4
3
  export * from './states';
5
4
  export * from './useInitChat';
@@ -1,5 +1,4 @@
1
- export * from "./messageIds.js";
2
- export * from "./messagesMap.js";
1
+ export * from "./messages.js";
3
2
  export * from "./send.js";
4
3
  export * from "./states.js";
5
4
  export * from "./useInitChat.js";
@@ -0,0 +1,9 @@
1
+ import type { UIMessage } from 'ai';
2
+ export declare const $chatMessageIds: import("nanostores").PreinitializedWritableAtom<string[]> & object;
3
+ export declare const useChatMessageIds: () => string[];
4
+ export declare const $chatMessages: import("nanostores").PreinitializedMapStore<Record<string, UIMessage<unknown, import("ai").UIDataTypes, import("ai").UITools>>> & object;
5
+ export declare const getChatMessage: <TMessage extends UIMessage>(messageId: string) => TMessage | undefined;
6
+ export declare const useChatMessage: <TMessage extends UIMessage>(messageId: string) => TMessage;
7
+ export declare const addChatMessage: <TMessage extends UIMessage>(newMessage: TMessage) => void;
8
+ export declare const setChatMessages: <TMessage extends UIMessage>(messages: TMessage[]) => void;
9
+ export declare const getIsEmpty: () => boolean;
@@ -1,13 +1,18 @@
1
1
  import { useStore } from "@nanostores/react";
2
- import { atom, computed, onSet } from "nanostores";
3
- import { $chatMessages } from "./messagesMap.js";
2
+ import { atom, computed, map, onSet } from "nanostores";
4
3
  const $chatMessageIds = atom([]);
5
- const getChatMessages = ()=>$chatMessageIds.get().map((id)=>$chatMessages.get()[id]);
6
4
  const useChatMessageIds = ()=>useStore($chatMessageIds);
7
5
  onSet($chatMessageIds, ({ newValue, abort })=>{
8
6
  const currentValue = $chatMessageIds.get();
9
7
  if (currentValue.length === newValue.length && currentValue.every((id, index)=>id === newValue[index])) abort();
10
8
  });
9
+ const $chatMessages = map({});
10
+ const getChatMessage = (messageId)=>$chatMessages.get()[messageId];
11
+ const useChatMessage = (messageId)=>useStore($chatMessages, {
12
+ keys: [
13
+ messageId
14
+ ]
15
+ })[messageId];
11
16
  const addChatMessage = (newMessage)=>{
12
17
  $chatMessageIds.set([
13
18
  ...$chatMessageIds.get(),
@@ -37,5 +42,4 @@ const setChatMessages = (messages)=>{
37
42
  };
38
43
  const $isEmpty = computed($chatMessageIds, (messages)=>0 === messages.length);
39
44
  const getIsEmpty = ()=>$isEmpty.get();
40
- const useIsEmpty = ()=>useStore($isEmpty);
41
- export { $chatMessageIds, addChatMessage, getChatMessages, getIsEmpty, setChatMessages, useChatMessageIds, useIsEmpty };
45
+ export { $chatMessageIds, $chatMessages, addChatMessage, getChatMessage, getIsEmpty, setChatMessages, useChatMessage, useChatMessageIds };
@@ -4,7 +4,6 @@ export declare const setChatStatus: (status: ChatStatus) => void;
4
4
  export declare const useChatStatus: () => ChatStatus;
5
5
  export declare const getIsLoading: () => boolean;
6
6
  export declare const useIsLoading: () => boolean;
7
- export declare const getIsStreaming: () => boolean;
8
7
  export declare const useIsStreaming: () => boolean;
9
8
  export declare const getChatError: () => string | undefined;
10
9
  export declare const setChatError: (error: string | undefined) => void;
@@ -8,10 +8,9 @@ const $isLoading = computed($chatStatus, (status)=>'ready' !== status);
8
8
  const getIsLoading = ()=>$isLoading.get();
9
9
  const useIsLoading = ()=>useStore($isLoading);
10
10
  const $isStreaming = computed($chatStatus, (status)=>'streaming' === status);
11
- const getIsStreaming = ()=>$isStreaming.get();
12
11
  const useIsStreaming = ()=>useStore($isStreaming);
13
12
  const $chatError = atom();
14
13
  const getChatError = ()=>$chatError.get();
15
14
  const setChatError = (error)=>$chatError.set(error);
16
15
  const useChatError = ()=>useStore($chatError);
17
- export { getChatError, getChatStatus, getIsLoading, getIsStreaming, setChatError, setChatStatus, useChatError, useChatStatus, useIsLoading, useIsStreaming };
16
+ export { getChatError, getChatStatus, getIsLoading, setChatError, setChatStatus, useChatError, useChatStatus, useIsLoading, useIsStreaming };
@@ -1,7 +1,7 @@
1
1
  import { useChat } from "@ai-sdk/react";
2
2
  import { notifications } from "@mantine/notifications";
3
3
  import { useEffect } from "react";
4
- import { setChatMessages } from "./messageIds.js";
4
+ import { setChatMessages } from "./messages.js";
5
5
  import { setChatSendMessage } from "./send.js";
6
6
  import { setChatError, setChatStatus } from "./states.js";
7
7
  const useInitChat = (props)=>{
package/package.json CHANGED
@@ -1,79 +1,79 @@
1
1
  {
2
- "name": "@rolder/kit",
3
- "version": "3.0.0-alpha.85",
4
- "type": "module",
5
- "exports": {
6
- ".": {
7
- "types": "./dist/index.d.ts",
8
- "import": "./dist/index.js"
9
- },
10
- "./styles.css": "./dist/styles.css"
11
- },
12
- "sideEffects": false,
13
- "files": [
14
- "dist"
15
- ],
16
- "scripts": {
17
- "build": "rslib build",
18
- "dev": "rslib build --watch",
19
- "prepublishOnly": "bun run build",
20
- "check": "biome check --write && tsgo --noEmit"
21
- },
22
- "devDependencies": {
23
- "@rsbuild/plugin-react": "^1.4.3",
24
- "@rslib/core": "^0.19.3",
25
- "@types/bun": "^1.3.6",
26
- "@types/js-cookie": "^3.0.6",
27
- "@types/omgopass": "^3.2.3",
28
- "@types/react": "^19.2.9",
29
- "@typescript/native-preview": "^7.0.0-dev.20260122.3",
30
- "typescript": "6.0.0-dev.20260122"
31
- },
32
- "peerDependencies": {
33
- "@ai-sdk/react": "^3.0.47",
34
- "@better-upload/client": "^3.0.12",
35
- "@better-upload/server": "^3.0.12",
36
- "@codemirror/lang-json": "^6.0.2",
37
- "@codemirror/lint": "^6.9.2",
38
- "@mantine/core": "^8.3.13",
39
- "@mantine/hooks": "^8.3.13",
40
- "@mantine/notifications": "^8.3.13",
41
- "@mantine/tiptap": "^8.3.13",
42
- "@nanostores/react": "^1.0.0",
43
- "@tanstack/react-form": "^1.27.7",
44
- "@tanstack/react-query": "^5.90.19",
45
- "@tanstack/react-router": "^1.154.7",
46
- "@tanstack/react-router-ssr-query": "^1.154.7",
47
- "@tanstack/react-start": "^1.154.7",
48
- "@tiptap/extension-highlight": "^3.16.0",
49
- "@tiptap/extension-placeholder": "^3.16.0",
50
- "@tiptap/extension-table": "^3.16.0",
51
- "@tiptap/extension-task-item": "^3.16.0",
52
- "@tiptap/extension-task-list": "^3.16.0",
53
- "@tiptap/extension-text-align": "^3.16.0",
54
- "@tiptap/react": "^3.16.0",
55
- "@tiptap/starter-kit": "^3.16.0",
56
- "@uiw/codemirror-theme-vscode": "^4.25.4",
57
- "@uiw/react-codemirror": "^4.25.4",
58
- "ai": "^6.0.45",
59
- "clsx": "^2.1.1",
60
- "js-cookie": "^3.0.5",
61
- "mammoth": "^1.11.0",
62
- "nanoid": "^5.1.6",
63
- "nanostores": "^1.1.0",
64
- "omgopass": "^3.2.1",
65
- "react": "^19.2.3",
66
- "react-dom": "^19.2.3",
67
- "streamdown": "^2.1.0",
68
- "surrealdb": "2.0.0-alpha.16",
69
- "xlsx": "^0.18.5",
70
- "zod": "^4.3.5"
71
- },
72
- "trustedDependencies": [
73
- "core-js",
74
- "esbuild"
75
- ],
76
- "dependencies": {
77
- "@tabler/icons-react": "^3.36.1"
78
- }
2
+ "name": "@rolder/kit",
3
+ "version": "3.0.0-alpha.87",
4
+ "type": "module",
5
+ "exports": {
6
+ ".": {
7
+ "types": "./dist/index.d.ts",
8
+ "import": "./dist/index.js"
9
+ },
10
+ "./styles.css": "./dist/styles.css"
11
+ },
12
+ "sideEffects": false,
13
+ "files": [
14
+ "dist"
15
+ ],
16
+ "scripts": {
17
+ "build": "rslib build",
18
+ "dev": "rslib build --watch",
19
+ "prepublishOnly": "bun run build",
20
+ "check": "biome check --write && tsgo --noEmit"
21
+ },
22
+ "devDependencies": {
23
+ "@rsbuild/plugin-react": "^1.4.3",
24
+ "@rslib/core": "^0.19.3",
25
+ "@types/bun": "^1.3.6",
26
+ "@types/js-cookie": "^3.0.6",
27
+ "@types/omgopass": "^3.2.3",
28
+ "@types/react": "^19.2.9",
29
+ "@typescript/native-preview": "^7.0.0-dev.20260122.3",
30
+ "typescript": "6.0.0-dev.20260122"
31
+ },
32
+ "peerDependencies": {
33
+ "@ai-sdk/react": "^3.0.47",
34
+ "@better-upload/client": "^3.0.12",
35
+ "@better-upload/server": "^3.0.12",
36
+ "@codemirror/lang-json": "^6.0.2",
37
+ "@codemirror/lint": "^6.9.2",
38
+ "@mantine/core": "^8.3.13",
39
+ "@mantine/hooks": "^8.3.13",
40
+ "@mantine/notifications": "^8.3.13",
41
+ "@mantine/tiptap": "^8.3.13",
42
+ "@nanostores/react": "^1.0.0",
43
+ "@tanstack/react-form": "^1.27.7",
44
+ "@tanstack/react-query": "^5.90.19",
45
+ "@tanstack/react-router": "^1.154.7",
46
+ "@tanstack/react-router-ssr-query": "^1.154.7",
47
+ "@tanstack/react-start": "^1.154.7",
48
+ "@tiptap/extension-highlight": "^3.16.0",
49
+ "@tiptap/extension-placeholder": "^3.16.0",
50
+ "@tiptap/extension-table": "^3.16.0",
51
+ "@tiptap/extension-task-item": "^3.16.0",
52
+ "@tiptap/extension-task-list": "^3.16.0",
53
+ "@tiptap/extension-text-align": "^3.16.0",
54
+ "@tiptap/react": "^3.16.0",
55
+ "@tiptap/starter-kit": "^3.16.0",
56
+ "@uiw/codemirror-theme-vscode": "^4.25.4",
57
+ "@uiw/react-codemirror": "^4.25.4",
58
+ "ai": "^6.0.45",
59
+ "clsx": "^2.1.1",
60
+ "js-cookie": "^3.0.5",
61
+ "mammoth": "^1.11.0",
62
+ "nanoid": "^5.1.6",
63
+ "nanostores": "^1.1.0",
64
+ "omgopass": "^3.2.1",
65
+ "react": "^19.2.3",
66
+ "react-dom": "^19.2.3",
67
+ "streamdown": "^2.1.0",
68
+ "surrealdb": "2.0.0-alpha.16",
69
+ "xlsx": "^0.18.5",
70
+ "zod": "^4.3.5"
71
+ },
72
+ "trustedDependencies": [
73
+ "core-js",
74
+ "esbuild"
75
+ ],
76
+ "dependencies": {
77
+ "@tabler/icons-react": "^3.36.1"
78
+ }
79
79
  }
@@ -1 +0,0 @@
1
- export declare const Empty: () => import("react/jsx-runtime").JSX.Element | null;
@@ -1,21 +0,0 @@
1
- import { jsx, jsxs } from "react/jsx-runtime";
2
- import { Stack, Text } from "@mantine/core";
3
- import { useIsEmpty } from "./store/index.js";
4
- const Empty = ()=>{
5
- const isEmpty = useIsEmpty();
6
- return isEmpty ? /*#__PURE__*/ jsxs(Stack, {
7
- align: "center",
8
- gap: 0,
9
- children: [
10
- /*#__PURE__*/ jsx(Text, {
11
- children: "Нет сообщений"
12
- }),
13
- /*#__PURE__*/ jsx(Text, {
14
- size: "sm",
15
- c: "dimmed",
16
- children: "Начните общение, чтобы увидеть сообщения здесь"
17
- })
18
- ]
19
- }) : null;
20
- };
21
- export { Empty };
@@ -1,3 +0,0 @@
1
- export declare const File: ({ messageId }: {
2
- messageId: string;
3
- }) => import("react/jsx-runtime").JSX.Element | null;
@@ -1,2 +0,0 @@
1
- import { type LoaderProps } from '@mantine/core';
2
- export declare const Loader: (props: LoaderProps) => import("react/jsx-runtime").JSX.Element | null;
@@ -1,3 +0,0 @@
1
- export declare const Message: ({ messageId }: {
2
- messageId: string;
3
- }) => import("react/jsx-runtime").JSX.Element | null;
@@ -1,23 +0,0 @@
1
- import { jsx } from "react/jsx-runtime";
2
- import { Paper } from "@mantine/core";
3
- import { Streamdown } from "streamdown";
4
- import { getIsStreaming, useChatMessage, useChatMessagePart } from "./store/index.js";
5
- const Message = ({ messageId })=>{
6
- const message = useChatMessage(messageId);
7
- const part = useChatMessagePart(messageId, 'text');
8
- console.log('Message render', message);
9
- return part?.text ? /*#__PURE__*/ jsx(Paper, {
10
- radius: "md",
11
- px: "md",
12
- py: "sm",
13
- maw: "80%",
14
- ml: 'user' === message.role ? 'auto' : void 0,
15
- bg: 'user' === message.role ? 'var(--mantine-color-default-hover)' : 'var(--mantine-primary-color-light)',
16
- fz: "sm",
17
- children: /*#__PURE__*/ jsx(Streamdown, {
18
- isAnimating: getIsStreaming() && 'assistant' === message.role,
19
- children: part?.text
20
- })
21
- }) : null;
22
- };
23
- export { Message };
@@ -1,2 +0,0 @@
1
- import type { ChatRootProps } from './Root';
2
- export declare const Messages: ({ children, height, radius, padding, scrollAreaProps, withScrollButton, stackProps, ...props }: Omit<ChatRootProps, "chatOptions">) => import("react/jsx-runtime").JSX.Element;
@@ -1,28 +0,0 @@
1
- import { jsx, jsxs } from "react/jsx-runtime";
2
- import { Paper, Stack } from "@mantine/core";
3
- import { ScrollArea } from "../../../ui/index.js";
4
- import { useChatMessageIds } from "./store/index.js";
5
- const Messages = ({ children, height, radius = 'md', padding = 'md', scrollAreaProps, withScrollButton = true, stackProps, ...props })=>{
6
- const messageIds = useChatMessageIds();
7
- console.log('Messages render');
8
- return /*#__PURE__*/ jsx(Paper, {
9
- withBorder: true,
10
- radius: radius,
11
- ...props,
12
- children: /*#__PURE__*/ jsxs(ScrollArea.Root, {
13
- autoScroll: true,
14
- height: height,
15
- radius: radius,
16
- ...scrollAreaProps,
17
- children: [
18
- /*#__PURE__*/ jsx(Stack, {
19
- p: padding,
20
- ...stackProps,
21
- children: 'function' == typeof children ? children(messageIds) : null
22
- }),
23
- withScrollButton && /*#__PURE__*/ jsx(ScrollArea.ScrollButton, {})
24
- ]
25
- })
26
- });
27
- };
28
- export { Messages };
@@ -1,8 +0,0 @@
1
- import type { UIMessage } from 'ai';
2
- export declare const $chatMessageIds: import("nanostores").PreinitializedWritableAtom<string[]> & object;
3
- export declare const getChatMessages: <T extends UIMessage>() => T[];
4
- export declare const useChatMessageIds: () => string[];
5
- export declare const addChatMessage: (newMessage: UIMessage) => void;
6
- export declare const setChatMessages: <T extends UIMessage>(messages: T[]) => void;
7
- export declare const getIsEmpty: () => boolean;
8
- export declare const useIsEmpty: () => boolean;
@@ -1,5 +0,0 @@
1
- import type { UIDataTypes, UIMessage, UIMessagePart, UITools } from 'ai';
2
- export declare const $chatMessages: import("nanostores").PreinitializedMapStore<Record<string, UIMessage<unknown, UIDataTypes, UITools>>> & object;
3
- export declare const getChatMessage: (messageId: string) => UIMessage<unknown, UIDataTypes, UITools>;
4
- export declare const useChatMessage: <T extends UIMessage>(messageId: string) => T;
5
- export declare const useChatMessagePart: <M extends UIMessage, T extends UIMessagePart<UIDataTypes, UITools>>(messageId: string, type?: T["type"]) => T | undefined;
@@ -1,15 +0,0 @@
1
- import { useStore } from "@nanostores/react";
2
- import { map } from "nanostores";
3
- const $chatMessages = map({});
4
- const getChatMessage = (messageId)=>$chatMessages.get()[messageId];
5
- const useChatMessage = (messageId)=>useStore($chatMessages, {
6
- keys: [
7
- messageId
8
- ]
9
- })[messageId];
10
- const useChatMessagePart = (messageId, type)=>{
11
- const message = useChatMessage(messageId);
12
- const part = message?.parts?.find((i)=>i.type === type);
13
- return part;
14
- };
15
- export { $chatMessages, getChatMessage, useChatMessage, useChatMessagePart };