@assistant-ui/react-markdown 0.10.4 → 0.10.6
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/memoization.d.ts.map +1 -1
- package/dist/memoization.js +5 -2
- package/dist/memoization.js.map +1 -1
- package/dist/memoization.test.d.ts +2 -0
- package/dist/memoization.test.d.ts.map +1 -0
- package/dist/primitives/MarkdownText.d.ts.map +1 -1
- package/dist/primitives/MarkdownText.js +3 -9
- package/dist/primitives/MarkdownText.js.map +1 -1
- package/package.json +10 -7
- package/src/memoization.test.tsx +34 -0
- package/src/memoization.tsx +12 -5
- package/src/primitives/MarkdownText.tsx +4 -9
- package/styles/dot.css +3 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memoization.d.ts","sourceRoot":"","sources":["../src/memoization.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAC/B,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,WAAW,EAAQ,MAAM,OAAO,CAAC;AACzE,OAAO,EAAE,eAAe,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAE5E,KAAK,UAAU,GAAG;KACf,GAAG,IAAI,OAAO,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,aAAa,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC;CAC3E,GAAG;IACF,iBAAiB,CAAC,EACd,aAAa,CAAC,IAAI,CAAC,sBAAsB,EAAE,MAAM,CAAC,CAAC,GACnD,SAAS,CAAC;IACd,UAAU,CAAC,EAAE,aAAa,CAAC,IAAI,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC,GAAG,SAAS,CAAC;CACvE,CAAC;AAOF,eAAO,MAAM,aAAa,GACxB,MAAM,OAAO,GAAG,SAAS,EACzB,MAAM,OAAO,GAAG,SAAS,
|
|
1
|
+
{"version":3,"file":"memoization.d.ts","sourceRoot":"","sources":["../src/memoization.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAC/B,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,WAAW,EAAQ,MAAM,OAAO,CAAC;AACzE,OAAO,EAAE,eAAe,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAE5E,KAAK,UAAU,GAAG;KACf,GAAG,IAAI,OAAO,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,aAAa,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC;CAC3E,GAAG;IACF,iBAAiB,CAAC,EACd,aAAa,CAAC,IAAI,CAAC,sBAAsB,EAAE,MAAM,CAAC,CAAC,GACnD,SAAS,CAAC;IACd,UAAU,CAAC,EAAE,aAAa,CAAC,IAAI,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC,GAAG,SAAS,CAAC;CACvE,CAAC;AAOF,eAAO,MAAM,aAAa,GACxB,MAAM,OAAO,GAAG,SAAS,EACzB,MAAM,OAAO,GAAG,SAAS,YAe1B,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAC3B,MAAM;IAAE,IAAI,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;CAAE,EACpC,MAAM;IAAE,IAAI,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;CAAE,YAGrC,CAAC;AAEF,eAAO,MAAM,yBAAyB,GAAI,aAAY,UAAe;0EAMtB;QAAE,IAAI,CAAC,EAAE,OAAO,CAAA;KAAE;CAMhE,CAAC"}
|
package/dist/memoization.js
CHANGED
|
@@ -7,8 +7,11 @@ var areChildrenEqual = (prev, next) => {
|
|
|
7
7
|
};
|
|
8
8
|
var areNodesEqual = (prev, next) => {
|
|
9
9
|
if (!prev || !next) return false;
|
|
10
|
-
const
|
|
11
|
-
|
|
10
|
+
const excludeMetadata = (props) => {
|
|
11
|
+
const { position, data, ...rest } = props || {};
|
|
12
|
+
return rest;
|
|
13
|
+
};
|
|
14
|
+
return JSON.stringify(excludeMetadata(prev.properties)) === JSON.stringify(excludeMetadata(next.properties)) && areChildrenEqual(prev.children, next.children);
|
|
12
15
|
};
|
|
13
16
|
var memoCompareNodes = (prev, next) => {
|
|
14
17
|
return areNodesEqual(prev.node, next.node);
|
package/dist/memoization.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/memoization.tsx"],"sourcesContent":["import { Element } from \"hast\";\nimport { ComponentProps, ComponentType, ElementType, memo } from \"react\";\nimport { CodeHeaderProps, SyntaxHighlighterProps } from \"./overrides/types\";\n\ntype Components = {\n [Key in Extract<ElementType, string>]?: ComponentType<ComponentProps<Key>>;\n} & {\n SyntaxHighlighter?:\n | ComponentType<Omit<SyntaxHighlighterProps, \"node\">>\n | undefined;\n CodeHeader?: ComponentType<Omit<CodeHeaderProps, \"node\">> | undefined;\n};\n\nconst areChildrenEqual = (prev: string | unknown, next: string | unknown) => {\n if (typeof prev === \"string\") return prev === next;\n return JSON.stringify(prev) === JSON.stringify(next);\n};\n\nexport const areNodesEqual = (\n prev: Element | undefined,\n next: Element | undefined,\n) => {\n
|
|
1
|
+
{"version":3,"sources":["../src/memoization.tsx"],"sourcesContent":["import { Element } from \"hast\";\nimport { ComponentProps, ComponentType, ElementType, memo } from \"react\";\nimport { CodeHeaderProps, SyntaxHighlighterProps } from \"./overrides/types\";\n\ntype Components = {\n [Key in Extract<ElementType, string>]?: ComponentType<ComponentProps<Key>>;\n} & {\n SyntaxHighlighter?:\n | ComponentType<Omit<SyntaxHighlighterProps, \"node\">>\n | undefined;\n CodeHeader?: ComponentType<Omit<CodeHeaderProps, \"node\">> | undefined;\n};\n\nconst areChildrenEqual = (prev: string | unknown, next: string | unknown) => {\n if (typeof prev === \"string\") return prev === next;\n return JSON.stringify(prev) === JSON.stringify(next);\n};\n\nexport const areNodesEqual = (\n prev: Element | undefined,\n next: Element | undefined,\n) => {\n if (!prev || !next) return false;\n\n const excludeMetadata = (props: Element[\"properties\"]) => {\n const { position, data, ...rest } =\n (props as Record<string, unknown>) || {};\n return rest;\n };\n\n return (\n JSON.stringify(excludeMetadata(prev.properties)) ===\n JSON.stringify(excludeMetadata(next.properties)) &&\n areChildrenEqual(prev.children, next.children)\n );\n};\n\nexport const memoCompareNodes = (\n prev: { node?: Element | undefined },\n next: { node?: Element | undefined },\n) => {\n return areNodesEqual(prev.node, next.node);\n};\n\nexport const memoizeMarkdownComponents = (components: Components = {}) => {\n return Object.fromEntries(\n Object.entries(components ?? {}).map(([key, value]) => {\n if (!value) return [key, value];\n\n const Component = value as ComponentType;\n const WithoutNode = ({ node, ...props }: { node?: Element }) => {\n return <Component {...props} />;\n };\n return [key, memo(WithoutNode, memoCompareNodes)];\n }),\n );\n};\n"],"mappings":";AACA,SAAqD,YAAY;AAkDlD;AAtCf,IAAM,mBAAmB,CAAC,MAAwB,SAA2B;AAC3E,MAAI,OAAO,SAAS,SAAU,QAAO,SAAS;AAC9C,SAAO,KAAK,UAAU,IAAI,MAAM,KAAK,UAAU,IAAI;AACrD;AAEO,IAAM,gBAAgB,CAC3B,MACA,SACG;AACH,MAAI,CAAC,QAAQ,CAAC,KAAM,QAAO;AAE3B,QAAM,kBAAkB,CAAC,UAAiC;AACxD,UAAM,EAAE,UAAU,MAAM,GAAG,KAAK,IAC7B,SAAqC,CAAC;AACzC,WAAO;AAAA,EACT;AAEA,SACE,KAAK,UAAU,gBAAgB,KAAK,UAAU,CAAC,MAC7C,KAAK,UAAU,gBAAgB,KAAK,UAAU,CAAC,KACjD,iBAAiB,KAAK,UAAU,KAAK,QAAQ;AAEjD;AAEO,IAAM,mBAAmB,CAC9B,MACA,SACG;AACH,SAAO,cAAc,KAAK,MAAM,KAAK,IAAI;AAC3C;AAEO,IAAM,4BAA4B,CAAC,aAAyB,CAAC,MAAM;AACxE,SAAO,OAAO;AAAA,IACZ,OAAO,QAAQ,cAAc,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,KAAK,KAAK,MAAM;AACrD,UAAI,CAAC,MAAO,QAAO,CAAC,KAAK,KAAK;AAE9B,YAAM,YAAY;AAClB,YAAM,cAAc,CAAC,EAAE,MAAM,GAAG,MAAM,MAA0B;AAC9D,eAAO,oBAAC,aAAW,GAAG,OAAO;AAAA,MAC/B;AACA,aAAO,CAAC,KAAK,KAAK,aAAa,gBAAgB,CAAC;AAAA,IAClD,CAAC;AAAA,EACH;AACF;","names":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memoization.test.d.ts","sourceRoot":"","sources":["../src/memoization.test.tsx"],"names":[],"mappings":""}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MarkdownText.d.ts","sourceRoot":"","sources":["../../src/primitives/MarkdownText.tsx"],"names":[],"mappings":"AAGA,OAAO,EAEL,WAAW,EAGX,yBAAyB,EACzB,aAAa,EAEb,KAAK,wBAAwB,EAC7B,KAAK,aAAa,EACnB,MAAM,OAAO,CAAC;AACf,OAAsB,EAAE,KAAK,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAC7D,OAAO,EAAE,sBAAsB,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAU7E,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAMtD,KAAK,iBAAiB,GAAG,wBAAwB,CAAC,OAAO,SAAS,CAAC,GAAG,CAAC,CAAC;AAExE,MAAM,MAAM,0BAA0B,GAAG,IAAI,CAC3C,OAAO,EACP,YAAY,GAAG,UAAU,CAC1B,GAAG;IACF,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,cAAc,CAAC,EAAE,IAAI,CAAC,iBAAiB,EAAE,UAAU,GAAG,SAAS,CAAC,GAAG,SAAS,CAAC;IAC7E,kBAAkB,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC;IAC7C,UAAU,CAAC,EACP,CAAC,WAAW,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,GAAG;QACpC,iBAAiB,CAAC,EAAE,aAAa,CAAC,sBAAsB,CAAC,GAAG,SAAS,CAAC;QACtE,UAAU,CAAC,EAAE,aAAa,CAAC,eAAe,CAAC,GAAG,SAAS,CAAC;KACzD,CAAC,GACF,SAAS,CAAC;IACd,oBAAoB,CAAC,EACjB,MAAM,CACJ,MAAM,EACN;QACE,UAAU,CAAC,EAAE,aAAa,CAAC,eAAe,CAAC,GAAG,SAAS,CAAC;QACxD,iBAAiB,CAAC,EAAE,aAAa,CAAC,sBAAsB,CAAC,GAAG,SAAS,CAAC;KACvE,CACF,GACD,SAAS,CAAC;IACd,MAAM,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAC9B,CAAC;
|
|
1
|
+
{"version":3,"file":"MarkdownText.d.ts","sourceRoot":"","sources":["../../src/primitives/MarkdownText.tsx"],"names":[],"mappings":"AAGA,OAAO,EAEL,WAAW,EAGX,yBAAyB,EACzB,aAAa,EAEb,KAAK,wBAAwB,EAC7B,KAAK,aAAa,EACnB,MAAM,OAAO,CAAC;AACf,OAAsB,EAAE,KAAK,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAC7D,OAAO,EAAE,sBAAsB,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAU7E,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAMtD,KAAK,iBAAiB,GAAG,wBAAwB,CAAC,OAAO,SAAS,CAAC,GAAG,CAAC,CAAC;AAExE,MAAM,MAAM,0BAA0B,GAAG,IAAI,CAC3C,OAAO,EACP,YAAY,GAAG,UAAU,CAC1B,GAAG;IACF,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,cAAc,CAAC,EAAE,IAAI,CAAC,iBAAiB,EAAE,UAAU,GAAG,SAAS,CAAC,GAAG,SAAS,CAAC;IAC7E,kBAAkB,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC;IAC7C,UAAU,CAAC,EACP,CAAC,WAAW,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,GAAG;QACpC,iBAAiB,CAAC,EAAE,aAAa,CAAC,sBAAsB,CAAC,GAAG,SAAS,CAAC;QACtE,UAAU,CAAC,EAAE,aAAa,CAAC,eAAe,CAAC,GAAG,SAAS,CAAC;KACzD,CAAC,GACF,SAAS,CAAC;IACd,oBAAoB,CAAC,EACjB,MAAM,CACJ,MAAM,EACN;QACE,UAAU,CAAC,EAAE,aAAa,CAAC,eAAe,CAAC,GAAG,SAAS,CAAC;QACxD,iBAAiB,CAAC,EAAE,aAAa,CAAC,sBAAsB,CAAC,GAAG,SAAS,CAAC;KACvE,CACF,GACD,SAAS,CAAC;IACd,MAAM,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAC9B,CAAC;AA+EF,eAAO,MAAM,qBAAqB,uFAEjC,CAAC"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
3
|
// src/primitives/MarkdownText.tsx
|
|
4
|
-
import { INTERNAL,
|
|
4
|
+
import { INTERNAL, useMessagePartText } from "@assistant-ui/react";
|
|
5
5
|
import {
|
|
6
6
|
forwardRef,
|
|
7
7
|
useMemo
|
|
@@ -25,7 +25,7 @@ var MarkdownTextInner = ({
|
|
|
25
25
|
smooth = true,
|
|
26
26
|
...rest
|
|
27
27
|
}) => {
|
|
28
|
-
const { text } = useSmooth(
|
|
28
|
+
const { text } = useSmooth(useMessagePartText(), smooth);
|
|
29
29
|
const {
|
|
30
30
|
pre = DefaultPre,
|
|
31
31
|
code = DefaultCode,
|
|
@@ -49,13 +49,7 @@ var MarkdownTextInner = ({
|
|
|
49
49
|
}
|
|
50
50
|
));
|
|
51
51
|
const components = useMemo(() => {
|
|
52
|
-
const {
|
|
53
|
-
pre: pre2 = DefaultPre,
|
|
54
|
-
code: code2 = DefaultCode,
|
|
55
|
-
SyntaxHighlighter: SyntaxHighlighter2 = DefaultCodeBlockContent,
|
|
56
|
-
CodeHeader: CodeHeader2 = DefaultCodeHeader,
|
|
57
|
-
...componentsRest
|
|
58
|
-
} = userComponents ?? {};
|
|
52
|
+
const { pre: pre2, code: code2, SyntaxHighlighter: SyntaxHighlighter2, CodeHeader: CodeHeader2, ...componentsRest } = userComponents ?? {};
|
|
59
53
|
return {
|
|
60
54
|
...componentsRest,
|
|
61
55
|
pre: PreOverride,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/primitives/MarkdownText.tsx"],"sourcesContent":["\"use client\";\n\nimport { INTERNAL,
|
|
1
|
+
{"version":3,"sources":["../../src/primitives/MarkdownText.tsx"],"sourcesContent":["\"use client\";\n\nimport { INTERNAL, useMessagePartText } from \"@assistant-ui/react\";\nimport {\n ComponentRef,\n ElementType,\n FC,\n forwardRef,\n ForwardRefExoticComponent,\n RefAttributes,\n useMemo,\n type ComponentPropsWithoutRef,\n type ComponentType,\n} from \"react\";\nimport ReactMarkdown, { type Options } from \"react-markdown\";\nimport { SyntaxHighlighterProps, CodeHeaderProps } from \"../overrides/types\";\nimport { PreOverride } from \"../overrides/PreOverride\";\nimport {\n DefaultPre,\n DefaultCode,\n DefaultCodeBlockContent,\n DefaultCodeHeader,\n} from \"../overrides/defaultComponents\";\nimport { useCallbackRef } from \"@radix-ui/react-use-callback-ref\";\nimport { CodeOverride } from \"../overrides/CodeOverride\";\nimport { Primitive } from \"@radix-ui/react-primitive\";\nimport classNames from \"classnames\";\n\nconst { useSmooth, useSmoothStatus, withSmoothContextProvider } = INTERNAL;\n\ntype MarkdownTextPrimitiveElement = ComponentRef<typeof Primitive.div>;\ntype PrimitiveDivProps = ComponentPropsWithoutRef<typeof Primitive.div>;\n\nexport type MarkdownTextPrimitiveProps = Omit<\n Options,\n \"components\" | \"children\"\n> & {\n className?: string | undefined;\n containerProps?: Omit<PrimitiveDivProps, \"children\" | \"asChild\"> | undefined;\n containerComponent?: ElementType | undefined;\n components?:\n | (NonNullable<Options[\"components\"]> & {\n SyntaxHighlighter?: ComponentType<SyntaxHighlighterProps> | undefined;\n CodeHeader?: ComponentType<CodeHeaderProps> | undefined;\n })\n | undefined;\n componentsByLanguage?:\n | Record<\n string,\n {\n CodeHeader?: ComponentType<CodeHeaderProps> | undefined;\n SyntaxHighlighter?: ComponentType<SyntaxHighlighterProps> | undefined;\n }\n >\n | undefined;\n smooth?: boolean | undefined;\n};\n\nconst MarkdownTextInner: FC<MarkdownTextPrimitiveProps> = ({\n components: userComponents,\n componentsByLanguage,\n smooth = true,\n ...rest\n}) => {\n const { text } = useSmooth(useMessagePartText(), smooth);\n\n const {\n pre = DefaultPre,\n code = DefaultCode,\n SyntaxHighlighter = DefaultCodeBlockContent,\n CodeHeader = DefaultCodeHeader,\n } = userComponents ?? {};\n const useCodeOverrideComponents = useMemo(() => {\n return {\n Pre: pre,\n Code: code,\n SyntaxHighlighter,\n CodeHeader,\n };\n }, [pre, code, SyntaxHighlighter, CodeHeader]);\n const CodeComponent = useCallbackRef((props) => (\n <CodeOverride\n components={useCodeOverrideComponents}\n componentsByLanguage={componentsByLanguage}\n {...props}\n />\n ));\n\n const components: Options[\"components\"] = useMemo(() => {\n const { pre, code, SyntaxHighlighter, CodeHeader, ...componentsRest } =\n userComponents ?? {};\n return {\n ...componentsRest,\n pre: PreOverride,\n code: CodeComponent,\n };\n }, [CodeComponent, userComponents]);\n\n return (\n <ReactMarkdown components={components} {...rest}>\n {text}\n </ReactMarkdown>\n );\n};\n\nconst MarkdownTextPrimitiveImpl: ForwardRefExoticComponent<MarkdownTextPrimitiveProps> &\n RefAttributes<MarkdownTextPrimitiveElement> = forwardRef<\n MarkdownTextPrimitiveElement,\n MarkdownTextPrimitiveProps\n>(\n (\n {\n className,\n containerProps,\n containerComponent: Container = \"div\",\n ...rest\n },\n forwardedRef,\n ) => {\n const status = useSmoothStatus();\n return (\n <Container\n data-status={status.type}\n {...containerProps}\n className={classNames(className, containerProps?.className)}\n ref={forwardedRef}\n >\n <MarkdownTextInner {...rest}></MarkdownTextInner>\n </Container>\n );\n },\n);\n\nMarkdownTextPrimitiveImpl.displayName = \"MarkdownTextPrimitive\";\n\nexport const MarkdownTextPrimitive = withSmoothContextProvider(\n MarkdownTextPrimitiveImpl,\n);\n"],"mappings":";;;AAEA,SAAS,UAAU,0BAA0B;AAC7C;AAAA,EAIE;AAAA,EAGA;AAAA,OAGK;AACP,OAAO,mBAAqC;AAE5C,SAAS,mBAAmB;AAC5B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,sBAAsB;AAC/B,SAAS,oBAAoB;AAE7B,OAAO,gBAAgB;AAuDnB;AArDJ,IAAM,EAAE,WAAW,iBAAiB,0BAA0B,IAAI;AA8BlE,IAAM,oBAAoD,CAAC;AAAA,EACzD,YAAY;AAAA,EACZ;AAAA,EACA,SAAS;AAAA,EACT,GAAG;AACL,MAAM;AACJ,QAAM,EAAE,KAAK,IAAI,UAAU,mBAAmB,GAAG,MAAM;AAEvD,QAAM;AAAA,IACJ,MAAM;AAAA,IACN,OAAO;AAAA,IACP,oBAAoB;AAAA,IACpB,aAAa;AAAA,EACf,IAAI,kBAAkB,CAAC;AACvB,QAAM,4BAA4B,QAAQ,MAAM;AAC9C,WAAO;AAAA,MACL,KAAK;AAAA,MACL,MAAM;AAAA,MACN;AAAA,MACA;AAAA,IACF;AAAA,EACF,GAAG,CAAC,KAAK,MAAM,mBAAmB,UAAU,CAAC;AAC7C,QAAM,gBAAgB,eAAe,CAAC,UACpC;AAAA,IAAC;AAAA;AAAA,MACC,YAAY;AAAA,MACZ;AAAA,MACC,GAAG;AAAA;AAAA,EACN,CACD;AAED,QAAM,aAAoC,QAAQ,MAAM;AACtD,UAAM,EAAE,KAAAA,MAAK,MAAAC,OAAM,mBAAAC,oBAAmB,YAAAC,aAAY,GAAG,eAAe,IAClE,kBAAkB,CAAC;AACrB,WAAO;AAAA,MACL,GAAG;AAAA,MACH,KAAK;AAAA,MACL,MAAM;AAAA,IACR;AAAA,EACF,GAAG,CAAC,eAAe,cAAc,CAAC;AAElC,SACE,oBAAC,iBAAc,YAAyB,GAAG,MACxC,gBACH;AAEJ;AAEA,IAAM,4BAC0C;AAAA,EAI9C,CACE;AAAA,IACE;AAAA,IACA;AAAA,IACA,oBAAoB,YAAY;AAAA,IAChC,GAAG;AAAA,EACL,GACA,iBACG;AACH,UAAM,SAAS,gBAAgB;AAC/B,WACE;AAAA,MAAC;AAAA;AAAA,QACC,eAAa,OAAO;AAAA,QACnB,GAAG;AAAA,QACJ,WAAW,WAAW,WAAW,gBAAgB,SAAS;AAAA,QAC1D,KAAK;AAAA,QAEL,8BAAC,qBAAmB,GAAG,MAAM;AAAA;AAAA,IAC/B;AAAA,EAEJ;AACF;AAEA,0BAA0B,cAAc;AAEjC,IAAM,wBAAwB;AAAA,EACnC;AACF;","names":["pre","code","SyntaxHighlighter","CodeHeader"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@assistant-ui/react-markdown",
|
|
3
|
-
"version": "0.10.
|
|
3
|
+
"version": "0.10.6",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"react-markdown": "^10.1.0"
|
|
31
31
|
},
|
|
32
32
|
"peerDependencies": {
|
|
33
|
-
"@assistant-ui/react": "^0.10.
|
|
33
|
+
"@assistant-ui/react": "^0.10.25",
|
|
34
34
|
"@types/react": "*",
|
|
35
35
|
"react": "^18 || ^19 || ^19.0.0-rc"
|
|
36
36
|
},
|
|
@@ -40,13 +40,14 @@
|
|
|
40
40
|
}
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
|
-
"@types/node": "^
|
|
43
|
+
"@types/node": "^24.0.4",
|
|
44
44
|
"eslint": "^9",
|
|
45
|
-
"eslint-config-next": "15.3.
|
|
45
|
+
"eslint-config-next": "15.3.4",
|
|
46
46
|
"react": "19.1.0",
|
|
47
47
|
"react-dom": "19.1.0",
|
|
48
|
-
"tsx": "^4.
|
|
49
|
-
"
|
|
48
|
+
"tsx": "^4.20.3",
|
|
49
|
+
"vitest": "^3.2.3",
|
|
50
|
+
"@assistant-ui/react": "0.10.25",
|
|
50
51
|
"@assistant-ui/x-buildutils": "0.0.1"
|
|
51
52
|
},
|
|
52
53
|
"publishConfig": {
|
|
@@ -63,6 +64,8 @@
|
|
|
63
64
|
},
|
|
64
65
|
"scripts": {
|
|
65
66
|
"build": "tsx scripts/build.mts",
|
|
66
|
-
"lint": "eslint ."
|
|
67
|
+
"lint": "eslint .",
|
|
68
|
+
"test": "vitest run",
|
|
69
|
+
"test:watch": "vitest"
|
|
67
70
|
}
|
|
68
71
|
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import type { Element } from "hast";
|
|
3
|
+
import { areNodesEqual } from "./memoization";
|
|
4
|
+
|
|
5
|
+
const createNode = (overrides: Partial<Element> = {}): Element => ({
|
|
6
|
+
type: "element",
|
|
7
|
+
tagName: "p",
|
|
8
|
+
properties: { className: "foo" },
|
|
9
|
+
children: [],
|
|
10
|
+
...overrides,
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
describe("areNodesEqual", () => {
|
|
14
|
+
it("returns false if either node is undefined", () => {
|
|
15
|
+
expect(areNodesEqual(undefined, createNode())).toBe(false);
|
|
16
|
+
expect(areNodesEqual(createNode(), undefined)).toBe(false);
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
it("ignores position when comparing properties", () => {
|
|
20
|
+
const prev = createNode({ properties: { className: "foo", position: 1 } });
|
|
21
|
+
const next = createNode({ properties: { className: "foo", position: 2 } });
|
|
22
|
+
expect(areNodesEqual(prev, next)).toBe(true);
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
it("detects differences in children", () => {
|
|
26
|
+
const prev = createNode({
|
|
27
|
+
children: [{ type: "text", value: "a" }] as any,
|
|
28
|
+
});
|
|
29
|
+
const next = createNode({
|
|
30
|
+
children: [{ type: "text", value: "b" }] as any,
|
|
31
|
+
});
|
|
32
|
+
expect(areNodesEqual(prev, next)).toBe(false);
|
|
33
|
+
});
|
|
34
|
+
});
|
package/src/memoization.tsx
CHANGED
|
@@ -20,12 +20,19 @@ export const areNodesEqual = (
|
|
|
20
20
|
prev: Element | undefined,
|
|
21
21
|
next: Element | undefined,
|
|
22
22
|
) => {
|
|
23
|
-
// TODO troubleshoot why this is triggering for code blocks
|
|
24
23
|
if (!prev || !next) return false;
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
24
|
+
|
|
25
|
+
const excludeMetadata = (props: Element["properties"]) => {
|
|
26
|
+
const { position, data, ...rest } =
|
|
27
|
+
(props as Record<string, unknown>) || {};
|
|
28
|
+
return rest;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
return (
|
|
32
|
+
JSON.stringify(excludeMetadata(prev.properties)) ===
|
|
33
|
+
JSON.stringify(excludeMetadata(next.properties)) &&
|
|
34
|
+
areChildrenEqual(prev.children, next.children)
|
|
35
|
+
);
|
|
29
36
|
};
|
|
30
37
|
|
|
31
38
|
export const memoCompareNodes = (
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
|
-
import { INTERNAL,
|
|
3
|
+
import { INTERNAL, useMessagePartText } from "@assistant-ui/react";
|
|
4
4
|
import {
|
|
5
5
|
ComponentRef,
|
|
6
6
|
ElementType,
|
|
@@ -62,7 +62,7 @@ const MarkdownTextInner: FC<MarkdownTextPrimitiveProps> = ({
|
|
|
62
62
|
smooth = true,
|
|
63
63
|
...rest
|
|
64
64
|
}) => {
|
|
65
|
-
const { text } = useSmooth(
|
|
65
|
+
const { text } = useSmooth(useMessagePartText(), smooth);
|
|
66
66
|
|
|
67
67
|
const {
|
|
68
68
|
pre = DefaultPre,
|
|
@@ -87,13 +87,8 @@ const MarkdownTextInner: FC<MarkdownTextPrimitiveProps> = ({
|
|
|
87
87
|
));
|
|
88
88
|
|
|
89
89
|
const components: Options["components"] = useMemo(() => {
|
|
90
|
-
const {
|
|
91
|
-
|
|
92
|
-
code = DefaultCode,
|
|
93
|
-
SyntaxHighlighter = DefaultCodeBlockContent,
|
|
94
|
-
CodeHeader = DefaultCodeHeader,
|
|
95
|
-
...componentsRest
|
|
96
|
-
} = userComponents ?? {};
|
|
90
|
+
const { pre, code, SyntaxHighlighter, CodeHeader, ...componentsRest } =
|
|
91
|
+
userComponents ?? {};
|
|
97
92
|
return {
|
|
98
93
|
...componentsRest,
|
|
99
94
|
pre: PreOverride,
|
package/styles/dot.css
CHANGED
|
@@ -24,8 +24,9 @@
|
|
|
24
24
|
> :where(:is(ol, ul):last-child)
|
|
25
25
|
> :where(li:last-child)::after {
|
|
26
26
|
animation: aui-pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
|
|
27
|
-
font-family:
|
|
28
|
-
|
|
27
|
+
font-family:
|
|
28
|
+
ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji",
|
|
29
|
+
"Segoe UI Symbol", "Noto Color Emoji";
|
|
29
30
|
--aui-content: "\25cf";
|
|
30
31
|
content: var(--aui-content);
|
|
31
32
|
margin-left: 0.25rem;
|