@anvia/react-ui 1.2.2 → 1.3.1

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 (131) hide show
  1. package/dist/attachment/index.d.ts +3 -21
  2. package/dist/attachment/index.js +3 -12
  3. package/dist/attachment-DsKTPumt.js +89 -0
  4. package/dist/attachment-DsKTPumt.js.map +1 -0
  5. package/dist/chat/index.d.ts +3 -144
  6. package/dist/chat/index.js +3 -25
  7. package/dist/chat-CAnvUEAv.js +1210 -0
  8. package/dist/chat-CAnvUEAv.js.map +1 -0
  9. package/dist/completion/index.d.ts +3 -29
  10. package/dist/completion/index.js +3 -16
  11. package/dist/completion-DDTKoZRJ.js +124 -0
  12. package/dist/completion-DDTKoZRJ.js.map +1 -0
  13. package/dist/connection-DeNq8wHS.js +203 -0
  14. package/dist/connection-DeNq8wHS.js.map +1 -0
  15. package/dist/contexts-B4ijG24z.js +212 -0
  16. package/dist/contexts-B4ijG24z.js.map +1 -0
  17. package/dist/elements-D4vmkkF8.js +19 -0
  18. package/dist/elements-D4vmkkF8.js.map +1 -0
  19. package/dist/graph-explorer/index.d.ts +54 -73
  20. package/dist/graph-explorer/index.d.ts.map +1 -0
  21. package/dist/graph-explorer/index.js +181 -248
  22. package/dist/graph-explorer/index.js.map +1 -1
  23. package/dist/human-input/index.d.ts +3 -78
  24. package/dist/human-input/index.js +3 -21
  25. package/dist/human-input-CsCbZomZ.js +314 -0
  26. package/dist/human-input-CsCbZomZ.js.map +1 -0
  27. package/dist/image/index.d.ts +3 -40
  28. package/dist/image/index.js +3 -12
  29. package/dist/image-D_7vaQCR.js +302 -0
  30. package/dist/image-D_7vaQCR.js.map +1 -0
  31. package/dist/index-B1Qs2Cjv.d.ts +145 -0
  32. package/dist/index-B1Qs2Cjv.d.ts.map +1 -0
  33. package/dist/index-BCBVcl0D.d.ts +277 -0
  34. package/dist/index-BCBVcl0D.d.ts.map +1 -0
  35. package/dist/index-CE22tsua.d.ts +20 -0
  36. package/dist/index-CE22tsua.d.ts.map +1 -0
  37. package/dist/index-CGqtpc6b.d.ts +25 -0
  38. package/dist/index-CGqtpc6b.d.ts.map +1 -0
  39. package/dist/index-DqdyM0Jm.d.ts +7 -0
  40. package/dist/index-DqdyM0Jm.d.ts.map +1 -0
  41. package/dist/index-Mw3ltwSG.d.ts +318 -0
  42. package/dist/index-Mw3ltwSG.d.ts.map +1 -0
  43. package/dist/index.d.ts +7 -40
  44. package/dist/index.js +34 -118
  45. package/dist/index.js.map +1 -1
  46. package/dist/message/index.d.ts +3 -105
  47. package/dist/message/index.js +3 -20
  48. package/dist/message-Dn3wW6yy.js +783 -0
  49. package/dist/message-Dn3wW6yy.js.map +1 -0
  50. package/dist/primitives-xfE7zfwJ.js +15 -0
  51. package/dist/primitives-xfE7zfwJ.js.map +1 -0
  52. package/dist/refs-Djj9rSvB.js +10 -0
  53. package/dist/refs-Djj9rSvB.js.map +1 -0
  54. package/dist/sandbox-desktop/index.d.ts +100 -104
  55. package/dist/sandbox-desktop/index.d.ts.map +1 -0
  56. package/dist/sandbox-desktop/index.js +344 -342
  57. package/dist/sandbox-desktop/index.js.map +1 -1
  58. package/dist/sandbox-terminal/index.d.ts +52 -56
  59. package/dist/sandbox-terminal/index.d.ts.map +1 -0
  60. package/dist/sandbox-terminal/index.js +217 -208
  61. package/dist/sandbox-terminal/index.js.map +1 -1
  62. package/dist/selection-toolbar/index.d.ts +3 -21
  63. package/dist/selection-toolbar/index.js +3 -13
  64. package/dist/selection-toolbar-CIkOoM-7.js +171 -0
  65. package/dist/selection-toolbar-CIkOoM-7.js.map +1 -0
  66. package/dist/shared-BSYElFU2.d.ts +2 -0
  67. package/dist/shared.d.ts +4 -14
  68. package/dist/shared.js +1 -43
  69. package/dist/stream/index.d.ts +2 -22
  70. package/dist/stream/index.js +1 -8
  71. package/dist/stream-CAO0x8_1.js +298 -0
  72. package/dist/stream-CAO0x8_1.js.map +1 -0
  73. package/dist/thread-list/index.d.ts +3 -47
  74. package/dist/thread-list/index.js +3 -18
  75. package/dist/thread-list-xJbGXFrE.js +228 -0
  76. package/dist/thread-list-xJbGXFrE.js.map +1 -0
  77. package/dist/ticket-CoJHBpdF.d.ts +32 -0
  78. package/dist/ticket-CoJHBpdF.d.ts.map +1 -0
  79. package/dist/value-BGGrx72L.js +13 -0
  80. package/dist/value-BGGrx72L.js.map +1 -0
  81. package/package.json +22 -22
  82. package/dist/attachment/index.js.map +0 -1
  83. package/dist/attachment-mbjsroli.d.ts +0 -9
  84. package/dist/chat/index.js.map +0 -1
  85. package/dist/chat-PSj1Fo4W.d.ts +0 -88
  86. package/dist/chunk-22EZJUPM.js +0 -120
  87. package/dist/chunk-22EZJUPM.js.map +0 -1
  88. package/dist/chunk-5FZKTDZR.js +0 -201
  89. package/dist/chunk-5FZKTDZR.js.map +0 -1
  90. package/dist/chunk-6XOJFLX4.js +0 -22
  91. package/dist/chunk-6XOJFLX4.js.map +0 -1
  92. package/dist/chunk-CKA4CE26.js +0 -25
  93. package/dist/chunk-CKA4CE26.js.map +0 -1
  94. package/dist/chunk-DLBNFBXQ.js +0 -425
  95. package/dist/chunk-DLBNFBXQ.js.map +0 -1
  96. package/dist/chunk-E73S3SOF.js +0 -404
  97. package/dist/chunk-E73S3SOF.js.map +0 -1
  98. package/dist/chunk-F6AKBUO3.js +0 -380
  99. package/dist/chunk-F6AKBUO3.js.map +0 -1
  100. package/dist/chunk-HGOPGZNQ.js +0 -195
  101. package/dist/chunk-HGOPGZNQ.js.map +0 -1
  102. package/dist/chunk-KHB5CHAU.js +0 -220
  103. package/dist/chunk-KHB5CHAU.js.map +0 -1
  104. package/dist/chunk-LHABOAOP.js +0 -316
  105. package/dist/chunk-LHABOAOP.js.map +0 -1
  106. package/dist/chunk-N5XQU36W.js +0 -410
  107. package/dist/chunk-N5XQU36W.js.map +0 -1
  108. package/dist/chunk-T3ZFZ3NP.js +0 -30
  109. package/dist/chunk-T3ZFZ3NP.js.map +0 -1
  110. package/dist/chunk-W2AHKMRS.js +0 -1092
  111. package/dist/chunk-W2AHKMRS.js.map +0 -1
  112. package/dist/chunk-Y2KAMPVJ.js +0 -1582
  113. package/dist/chunk-Y2KAMPVJ.js.map +0 -1
  114. package/dist/completion/index.js.map +0 -1
  115. package/dist/completion-input-DHlwrhxB.d.ts +0 -24
  116. package/dist/composer-6iCSIq6L.d.ts +0 -111
  117. package/dist/human-input/index.js.map +0 -1
  118. package/dist/human-input-CkLrZ8IC.d.ts +0 -27
  119. package/dist/image/index.js.map +0 -1
  120. package/dist/image-VZv6Ddsn.d.ts +0 -14
  121. package/dist/message/index.js.map +0 -1
  122. package/dist/message-CNRnZQwU.d.ts +0 -14
  123. package/dist/render-CRKWam2v.d.ts +0 -8
  124. package/dist/selection-toolbar/index.js.map +0 -1
  125. package/dist/selection-toolbar-Cwjbuv5S.d.ts +0 -14
  126. package/dist/shared.js.map +0 -1
  127. package/dist/stream/index.js.map +0 -1
  128. package/dist/thread-Bz6-1zaJ.d.ts +0 -12
  129. package/dist/thread-list/index.js.map +0 -1
  130. package/dist/thread-list-On8db4XL.d.ts +0 -34
  131. package/dist/ticket-pexI1zIa.d.ts +0 -33
@@ -0,0 +1,171 @@
1
+ import { l as InternalSelectionToolbarProvider, u as useSelectionToolbar } from "./contexts-B4ijG24z.js";
2
+ import { t as messageElementFromNode } from "./elements-D4vmkkF8.js";
3
+ import { t as renderPrimitive } from "./primitives-xfE7zfwJ.js";
4
+ import { forwardRef, useCallback, useEffect, useMemo, useState } from "react";
5
+ import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
6
+ import { createPortal } from "react-dom";
7
+ // src/selection-toolbar/parts.tsx
8
+ const SelectionToolbarRoot = forwardRef(function SelectionToolbarRoot({ children, container, onQuote, onSelectionChange, style, ...props }, ref) {
9
+ const [selection, setSelectionState] = useState();
10
+ const portalContainer = container ?? globalThis.document?.body;
11
+ const setSelection = useCallback((nextSelection) => {
12
+ setSelectionState((currentSelection) => {
13
+ if (sameSelection(currentSelection, nextSelection)) return currentSelection;
14
+ onSelectionChange?.(nextSelection);
15
+ return nextSelection;
16
+ });
17
+ }, [onSelectionChange]);
18
+ const clear = useCallback(() => {
19
+ globalThis.document?.getSelection()?.removeAllRanges();
20
+ setSelection(void 0);
21
+ }, [setSelection]);
22
+ const copy = useCallback(async () => {
23
+ if (selection === void 0) return;
24
+ await globalThis.navigator?.clipboard?.writeText(selection.text);
25
+ clear();
26
+ }, [clear, selection]);
27
+ const quote = useCallback(() => {
28
+ if (selection === void 0) return;
29
+ onQuote?.(selection);
30
+ clear();
31
+ }, [
32
+ clear,
33
+ onQuote,
34
+ selection
35
+ ]);
36
+ const value = useMemo(() => {
37
+ const context = {
38
+ quote,
39
+ copy,
40
+ clear
41
+ };
42
+ if (selection !== void 0) context.selection = selection;
43
+ return context;
44
+ }, [
45
+ clear,
46
+ copy,
47
+ quote,
48
+ selection
49
+ ]);
50
+ useEffect(() => {
51
+ const document = globalThis.document;
52
+ if (document === void 0) return;
53
+ const handleSelectionChange = () => {
54
+ setSelection(selectionFromDocument(document));
55
+ };
56
+ document.addEventListener("selectionchange", handleSelectionChange);
57
+ document.addEventListener("mouseup", handleSelectionChange);
58
+ document.addEventListener("keyup", handleSelectionChange);
59
+ document.addEventListener("scroll", handleSelectionChange, true);
60
+ return () => {
61
+ document.removeEventListener("selectionchange", handleSelectionChange);
62
+ document.removeEventListener("mouseup", handleSelectionChange);
63
+ document.removeEventListener("keyup", handleSelectionChange);
64
+ document.removeEventListener("scroll", handleSelectionChange, true);
65
+ };
66
+ }, [setSelection]);
67
+ if (selection === void 0 || portalContainer === void 0) return null;
68
+ const toolbarStyle = {
69
+ position: "fixed",
70
+ top: selection.rect.top,
71
+ left: selection.rect.left + selection.rect.width / 2,
72
+ transform: "translate(-50%, calc(-100% - 8px))",
73
+ ...style
74
+ };
75
+ const toolbar = /* @__PURE__ */ jsx(InternalSelectionToolbarProvider, {
76
+ value,
77
+ children: renderPrimitive("div", {
78
+ ...props,
79
+ children: children ?? /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(SelectionToolbarQuote, {}), /* @__PURE__ */ jsx(SelectionToolbarCopy, {})] }),
80
+ style: toolbarStyle,
81
+ role: props.role ?? "toolbar"
82
+ }, ref)
83
+ });
84
+ return createPortal(toolbar, portalContainer);
85
+ });
86
+ const SelectionToolbarQuote = forwardRef(function SelectionToolbarQuote({ onClick, ...props }, ref) {
87
+ const { disabled, handleClick } = useSelectionToolbarAction("quote", props.disabled, onClick);
88
+ return renderPrimitive("button", {
89
+ ...props,
90
+ children: props.children ?? "Quote",
91
+ disabled,
92
+ onClick: handleClick,
93
+ type: props.type ?? "button",
94
+ "data-state": disabled ? "disabled" : "enabled"
95
+ }, ref);
96
+ });
97
+ const SelectionToolbarCopy = forwardRef(function SelectionToolbarCopy({ onClick, ...props }, ref) {
98
+ const { disabled, handleClick } = useSelectionToolbarAction("copy", props.disabled, onClick);
99
+ return renderPrimitive("button", {
100
+ ...props,
101
+ children: props.children ?? "Copy",
102
+ disabled,
103
+ onClick: handleClick,
104
+ type: props.type ?? "button",
105
+ "data-state": disabled ? "disabled" : "enabled"
106
+ }, ref);
107
+ });
108
+ function useSelectionToolbarAction(actionName, disabledProp, onClick) {
109
+ const toolbar = useSelectionToolbar();
110
+ const disabled = disabledProp ?? toolbar.selection === void 0;
111
+ const action = toolbar[actionName];
112
+ return {
113
+ disabled,
114
+ handleClick: useCallback((event) => {
115
+ onClick?.(event);
116
+ if (event.defaultPrevented || disabled) return;
117
+ action();
118
+ }, [
119
+ action,
120
+ disabled,
121
+ onClick
122
+ ])
123
+ };
124
+ }
125
+ function selectionFromDocument(document) {
126
+ const selection = document.getSelection();
127
+ if (selection === null || selection.rangeCount === 0) return;
128
+ const text = selection.toString();
129
+ if (text.trim().length === 0) return;
130
+ const anchorMessage = messageElementFromNode(selection.anchorNode);
131
+ const focusMessage = messageElementFromNode(selection.focusNode);
132
+ if (anchorMessage === void 0 || focusMessage === void 0 || anchorMessage.element !== focusMessage.element) return;
133
+ const range = selection.getRangeAt(0);
134
+ return {
135
+ text,
136
+ messageId: anchorMessage.messageId,
137
+ rect: selectionRect(range)
138
+ };
139
+ }
140
+ function selectionRect(range) {
141
+ const rect = range.getBoundingClientRect?.();
142
+ if (rect !== void 0 && (rect.width > 0 || rect.height > 0)) return rect;
143
+ const firstRect = range.getClientRects().item(0);
144
+ if (firstRect !== null) return firstRect;
145
+ const DOMRectConstructor = globalThis.DOMRect;
146
+ if (DOMRectConstructor !== void 0) return new DOMRectConstructor(0, 0, 0, 0);
147
+ return {
148
+ bottom: 0,
149
+ height: 0,
150
+ left: 0,
151
+ right: 0,
152
+ top: 0,
153
+ width: 0,
154
+ x: 0,
155
+ y: 0,
156
+ toJSON: () => ({})
157
+ };
158
+ }
159
+ function sameSelection(currentSelection, nextSelection) {
160
+ if (currentSelection === void 0 || nextSelection === void 0) return currentSelection === nextSelection;
161
+ return currentSelection.text === nextSelection.text && currentSelection.messageId === nextSelection.messageId && currentSelection.rect.left === nextSelection.rect.left && currentSelection.rect.top === nextSelection.rect.top && currentSelection.rect.width === nextSelection.rect.width && currentSelection.rect.height === nextSelection.rect.height;
162
+ }
163
+ // src/selection-toolbar/index.ts
164
+ const SelectionToolbarPrimitive = {
165
+ Root: SelectionToolbarRoot,
166
+ Quote: SelectionToolbarQuote,
167
+ Copy: SelectionToolbarCopy
168
+ };
169
+ export { SelectionToolbarPrimitive as t };
170
+
171
+ //# sourceMappingURL=selection-toolbar-CIkOoM-7.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"selection-toolbar-CIkOoM-7.js","names":["rangeWithRect"],"sources":["../src/selection-toolbar/parts.tsx","../src/selection-toolbar/index.ts"],"sourcesContent":["import {\n type CSSProperties,\n forwardRef,\n type MouseEvent,\n type ReactNode,\n useCallback,\n useEffect,\n useMemo,\n useState,\n} from \"react\";\nimport { createPortal } from \"react-dom\";\n\nimport {\n InternalSelectionToolbarProvider,\n type SelectionToolbarContextValue,\n type SelectionToolbarSelection,\n useSelectionToolbar,\n} from \"../contexts\";\nimport { messageElementFromNode } from \"../message/elements\";\nimport { type PrimitiveProps, renderPrimitive } from \"../primitives\";\n\ntype SelectionToolbarRootProps = Omit<PrimitiveProps<\"div\">, \"children\"> & {\n children?: ReactNode;\n container?: Element | DocumentFragment;\n onQuote?: (selection: SelectionToolbarSelection) => void;\n onSelectionChange?: (selection: SelectionToolbarSelection | undefined) => void;\n};\n\nconst SelectionToolbarRoot = forwardRef<HTMLDivElement, SelectionToolbarRootProps>(\n function SelectionToolbarRoot(\n { children, container, onQuote, onSelectionChange, style, ...props },\n ref,\n ) {\n const [selection, setSelectionState] = useState<SelectionToolbarSelection | undefined>();\n const portalContainer = container ?? globalThis.document?.body;\n\n const setSelection = useCallback(\n (nextSelection: SelectionToolbarSelection | undefined) => {\n setSelectionState((currentSelection) => {\n if (sameSelection(currentSelection, nextSelection)) {\n return currentSelection;\n }\n onSelectionChange?.(nextSelection);\n return nextSelection;\n });\n },\n [onSelectionChange],\n );\n\n const clear = useCallback(() => {\n globalThis.document?.getSelection()?.removeAllRanges();\n setSelection(undefined);\n }, [setSelection]);\n\n const copy = useCallback(async () => {\n if (selection === undefined) {\n return;\n }\n await globalThis.navigator?.clipboard?.writeText(selection.text);\n clear();\n }, [clear, selection]);\n\n const quote = useCallback(() => {\n if (selection === undefined) {\n return;\n }\n onQuote?.(selection);\n clear();\n }, [clear, onQuote, selection]);\n\n const value = useMemo<SelectionToolbarContextValue>(() => {\n const context: SelectionToolbarContextValue = { quote, copy, clear };\n if (selection !== undefined) context.selection = selection;\n return context;\n }, [clear, copy, quote, selection]);\n\n useEffect(() => {\n const document = globalThis.document;\n if (document === undefined) {\n return;\n }\n\n const handleSelectionChange = () => {\n setSelection(selectionFromDocument(document));\n };\n\n document.addEventListener(\"selectionchange\", handleSelectionChange);\n document.addEventListener(\"mouseup\", handleSelectionChange);\n document.addEventListener(\"keyup\", handleSelectionChange);\n document.addEventListener(\"scroll\", handleSelectionChange, true);\n return () => {\n document.removeEventListener(\"selectionchange\", handleSelectionChange);\n document.removeEventListener(\"mouseup\", handleSelectionChange);\n document.removeEventListener(\"keyup\", handleSelectionChange);\n document.removeEventListener(\"scroll\", handleSelectionChange, true);\n };\n }, [setSelection]);\n\n if (selection === undefined || portalContainer === undefined) {\n return null;\n }\n\n const toolbarStyle: CSSProperties = {\n position: \"fixed\",\n top: selection.rect.top,\n left: selection.rect.left + selection.rect.width / 2,\n transform: \"translate(-50%, calc(-100% - 8px))\",\n ...style,\n };\n\n const toolbar = (\n <InternalSelectionToolbarProvider value={value}>\n {renderPrimitive(\n \"div\",\n {\n ...props,\n children: children ?? (\n <>\n <SelectionToolbarQuote />\n <SelectionToolbarCopy />\n </>\n ),\n style: toolbarStyle,\n role: props.role ?? \"toolbar\",\n } as PrimitiveProps<\"div\">,\n ref,\n )}\n </InternalSelectionToolbarProvider>\n );\n\n return createPortal(toolbar, portalContainer);\n },\n);\n\nconst SelectionToolbarQuote = forwardRef<HTMLButtonElement, PrimitiveProps<\"button\">>(\n function SelectionToolbarQuote({ onClick, ...props }, ref) {\n const { disabled, handleClick } = useSelectionToolbarAction(\"quote\", props.disabled, onClick);\n\n return renderPrimitive(\n \"button\",\n {\n ...props,\n children: props.children ?? \"Quote\",\n disabled,\n onClick: handleClick,\n type: props.type ?? \"button\",\n \"data-state\": disabled ? \"disabled\" : \"enabled\",\n } as PrimitiveProps<\"button\">,\n ref,\n );\n },\n);\n\nconst SelectionToolbarCopy = forwardRef<HTMLButtonElement, PrimitiveProps<\"button\">>(\n function SelectionToolbarCopy({ onClick, ...props }, ref) {\n const { disabled, handleClick } = useSelectionToolbarAction(\"copy\", props.disabled, onClick);\n\n return renderPrimitive(\n \"button\",\n {\n ...props,\n children: props.children ?? \"Copy\",\n disabled,\n onClick: handleClick,\n type: props.type ?? \"button\",\n \"data-state\": disabled ? \"disabled\" : \"enabled\",\n } as PrimitiveProps<\"button\">,\n ref,\n );\n },\n);\n\ntype SelectionToolbarAction = \"copy\" | \"quote\";\n\nfunction useSelectionToolbarAction(\n actionName: SelectionToolbarAction,\n disabledProp: boolean | undefined,\n onClick: ((event: MouseEvent<HTMLButtonElement>) => void) | undefined,\n): {\n disabled: boolean;\n handleClick(event: MouseEvent<HTMLButtonElement>): void;\n} {\n const toolbar = useSelectionToolbar();\n const disabled = disabledProp ?? toolbar.selection === undefined;\n const action = toolbar[actionName];\n const handleClick = useCallback(\n (event: MouseEvent<HTMLButtonElement>) => {\n onClick?.(event);\n if (event.defaultPrevented || disabled) {\n return;\n }\n void action();\n },\n [action, disabled, onClick],\n );\n return { disabled, handleClick };\n}\n\nfunction selectionFromDocument(document: Document): SelectionToolbarSelection | undefined {\n const selection = document.getSelection();\n if (selection === null || selection.rangeCount === 0) {\n return undefined;\n }\n const text = selection.toString();\n if (text.trim().length === 0) {\n return undefined;\n }\n\n const anchorMessage = messageElementFromNode(selection.anchorNode);\n const focusMessage = messageElementFromNode(selection.focusNode);\n if (\n anchorMessage === undefined ||\n focusMessage === undefined ||\n anchorMessage.element !== focusMessage.element\n ) {\n return undefined;\n }\n\n const range = selection.getRangeAt(0);\n return {\n text,\n messageId: anchorMessage.messageId,\n rect: selectionRect(range),\n };\n}\n\nfunction selectionRect(range: Range): DOMRect {\n const rangeWithRect = range as Range & {\n getBoundingClientRect?: () => DOMRect;\n };\n const rect = rangeWithRect.getBoundingClientRect?.();\n if (rect !== undefined && (rect.width > 0 || rect.height > 0)) {\n return rect;\n }\n const firstRect = range.getClientRects().item(0);\n if (firstRect !== null) {\n return firstRect;\n }\n const DOMRectConstructor = globalThis.DOMRect;\n if (DOMRectConstructor !== undefined) {\n return new DOMRectConstructor(0, 0, 0, 0);\n }\n return {\n bottom: 0,\n height: 0,\n left: 0,\n right: 0,\n top: 0,\n width: 0,\n x: 0,\n y: 0,\n toJSON: () => ({}),\n } as DOMRect;\n}\n\nfunction sameSelection(\n currentSelection: SelectionToolbarSelection | undefined,\n nextSelection: SelectionToolbarSelection | undefined,\n): boolean {\n if (currentSelection === undefined || nextSelection === undefined) {\n return currentSelection === nextSelection;\n }\n return (\n currentSelection.text === nextSelection.text &&\n currentSelection.messageId === nextSelection.messageId &&\n currentSelection.rect.left === nextSelection.rect.left &&\n currentSelection.rect.top === nextSelection.rect.top &&\n currentSelection.rect.width === nextSelection.rect.width &&\n currentSelection.rect.height === nextSelection.rect.height\n );\n}\n\nexport { SelectionToolbarCopy, SelectionToolbarQuote, SelectionToolbarRoot };\n","import { SelectionToolbarCopy, SelectionToolbarQuote, SelectionToolbarRoot } from \"./parts\";\n\nexport const SelectionToolbarPrimitive = {\n Root: SelectionToolbarRoot,\n Quote: SelectionToolbarQuote,\n Copy: SelectionToolbarCopy,\n} as const;\n\nexport type { SelectionToolbarContextValue, SelectionToolbarSelection } from \"../contexts\";\nexport { useSelectionToolbar } from \"../contexts\";\n"],"mappings":";;;;;;;AA4BA,MAAM,uBAAuB,WAC3B,SAAS,qBACP,EAAE,UAAU,WAAW,SAAS,mBAAmB,OAAO,GAAG,SAC7D,KACA;CACA,MAAM,CAAC,WAAW,qBAAqB,SAAgD;CACvF,MAAM,kBAAkB,aAAa,WAAW,UAAU;CAE1D,MAAM,eAAe,aAClB,kBAAyD;EACxD,mBAAmB,qBAAqB;GACtC,IAAI,cAAc,kBAAkB,aAAa,GAC/C,OAAO;GAET,oBAAoB,aAAa;GACjC,OAAO;EACT,CAAC;CACH,GACA,CAAC,iBAAiB,CACpB;CAEA,MAAM,QAAQ,kBAAkB;EAC9B,WAAW,UAAU,aAAa,CAAC,EAAE,gBAAgB;EACrD,aAAa,KAAA,CAAS;CACxB,GAAG,CAAC,YAAY,CAAC;CAEjB,MAAM,OAAO,YAAY,YAAY;EACnC,IAAI,cAAc,KAAA,GAChB;EAEF,MAAM,WAAW,WAAW,WAAW,UAAU,UAAU,IAAI;EAC/D,MAAM;CACR,GAAG,CAAC,OAAO,SAAS,CAAC;CAErB,MAAM,QAAQ,kBAAkB;EAC9B,IAAI,cAAc,KAAA,GAChB;EAEF,UAAU,SAAS;EACnB,MAAM;CACR,GAAG;EAAC;EAAO;EAAS;CAAS,CAAC;CAE9B,MAAM,QAAQ,cAA4C;EACxD,MAAM,UAAwC;GAAE;GAAO;GAAM;EAAM;EACnE,IAAI,cAAc,KAAA,GAAW,QAAQ,YAAY;EACjD,OAAO;CACT,GAAG;EAAC;EAAO;EAAM;EAAO;CAAS,CAAC;CAElC,gBAAgB;EACd,MAAM,WAAW,WAAW;EAC5B,IAAI,aAAa,KAAA,GACf;EAGF,MAAM,8BAA8B;GAClC,aAAa,sBAAsB,QAAQ,CAAC;EAC9C;EAEA,SAAS,iBAAiB,mBAAmB,qBAAqB;EAClE,SAAS,iBAAiB,WAAW,qBAAqB;EAC1D,SAAS,iBAAiB,SAAS,qBAAqB;EACxD,SAAS,iBAAiB,UAAU,uBAAuB,IAAI;EAC/D,aAAa;GACX,SAAS,oBAAoB,mBAAmB,qBAAqB;GACrE,SAAS,oBAAoB,WAAW,qBAAqB;GAC7D,SAAS,oBAAoB,SAAS,qBAAqB;GAC3D,SAAS,oBAAoB,UAAU,uBAAuB,IAAI;EACpE;CACF,GAAG,CAAC,YAAY,CAAC;CAEjB,IAAI,cAAc,KAAA,KAAa,oBAAoB,KAAA,GACjD,OAAO;CAGT,MAAM,eAA8B;EAClC,UAAU;EACV,KAAK,UAAU,KAAK;EACpB,MAAM,UAAU,KAAK,OAAO,UAAU,KAAK,QAAQ;EACnD,WAAW;EACX,GAAG;CACL;CAEA,MAAM,UACJ,oBAAC,kCAAD;EAAyC;EACtC,UAAA,gBACC,OACA;GACE,GAAG;GACH,UAAU,YACR,qBAAA,YAAA,EAAA,UAAA,CACE,oBAAC,uBAAD,CAAwB,CAAA,GACxB,oBAAC,sBAAD,CAAuB,CAAA,CACvB,EAAA,CAAA;GAEJ,OAAO;GACP,MAAM,MAAM,QAAQ;EACtB,GACA,GACF;CACgC,CAAA;CAGpC,OAAO,aAAa,SAAS,eAAe;AAC9C,CACF;AAEA,MAAM,wBAAwB,WAC5B,SAAS,sBAAsB,EAAE,SAAS,GAAG,SAAS,KAAK;CACzD,MAAM,EAAE,UAAU,gBAAgB,0BAA0B,SAAS,MAAM,UAAU,OAAO;CAE5F,OAAO,gBACL,UACA;EACE,GAAG;EACH,UAAU,MAAM,YAAY;EAC5B;EACA,SAAS;EACT,MAAM,MAAM,QAAQ;EACpB,cAAc,WAAW,aAAa;CACxC,GACA,GACF;AACF,CACF;AAEA,MAAM,uBAAuB,WAC3B,SAAS,qBAAqB,EAAE,SAAS,GAAG,SAAS,KAAK;CACxD,MAAM,EAAE,UAAU,gBAAgB,0BAA0B,QAAQ,MAAM,UAAU,OAAO;CAE3F,OAAO,gBACL,UACA;EACE,GAAG;EACH,UAAU,MAAM,YAAY;EAC5B;EACA,SAAS;EACT,MAAM,MAAM,QAAQ;EACpB,cAAc,WAAW,aAAa;CACxC,GACA,GACF;AACF,CACF;AAIA,SAAS,0BACP,YACA,cACA,SAIA;CACA,MAAM,UAAU,oBAAoB;CACpC,MAAM,WAAW,gBAAgB,QAAQ,cAAc,KAAA;CACvD,MAAM,SAAS,QAAQ;CAWvB,OAAO;EAAE;EAAU,aAVC,aACjB,UAAyC;GACxC,UAAU,KAAK;GACf,IAAI,MAAM,oBAAoB,UAC5B;GAEF,OAAY;EACd,GACA;GAAC;GAAQ;GAAU;EAAO,CAEC;CAAE;AACjC;AAEA,SAAS,sBAAsB,UAA2D;CACxF,MAAM,YAAY,SAAS,aAAa;CACxC,IAAI,cAAc,QAAQ,UAAU,eAAe,GACjD;CAEF,MAAM,OAAO,UAAU,SAAS;CAChC,IAAI,KAAK,KAAK,CAAC,CAAC,WAAW,GACzB;CAGF,MAAM,gBAAgB,uBAAuB,UAAU,UAAU;CACjE,MAAM,eAAe,uBAAuB,UAAU,SAAS;CAC/D,IACE,kBAAkB,KAAA,KAClB,iBAAiB,KAAA,KACjB,cAAc,YAAY,aAAa,SAEvC;CAGF,MAAM,QAAQ,UAAU,WAAW,CAAC;CACpC,OAAO;EACL;EACA,WAAW,cAAc;EACzB,MAAM,cAAc,KAAK;CAC3B;AACF;AAEA,SAAS,cAAc,OAAuB;CAI5C,MAAM,OAAOA,MAAc,wBAAwB;CACnD,IAAI,SAAS,KAAA,MAAc,KAAK,QAAQ,KAAK,KAAK,SAAS,IACzD,OAAO;CAET,MAAM,YAAY,MAAM,eAAe,CAAC,CAAC,KAAK,CAAC;CAC/C,IAAI,cAAc,MAChB,OAAO;CAET,MAAM,qBAAqB,WAAW;CACtC,IAAI,uBAAuB,KAAA,GACzB,OAAO,IAAI,mBAAmB,GAAG,GAAG,GAAG,CAAC;CAE1C,OAAO;EACL,QAAQ;EACR,QAAQ;EACR,MAAM;EACN,OAAO;EACP,KAAK;EACL,OAAO;EACP,GAAG;EACH,GAAG;EACH,eAAe,CAAC;CAClB;AACF;AAEA,SAAS,cACP,kBACA,eACS;CACT,IAAI,qBAAqB,KAAA,KAAa,kBAAkB,KAAA,GACtD,OAAO,qBAAqB;CAE9B,OACE,iBAAiB,SAAS,cAAc,QACxC,iBAAiB,cAAc,cAAc,aAC7C,iBAAiB,KAAK,SAAS,cAAc,KAAK,QAClD,iBAAiB,KAAK,QAAQ,cAAc,KAAK,OACjD,iBAAiB,KAAK,UAAU,cAAc,KAAK,SACnD,iBAAiB,KAAK,WAAW,cAAc,KAAK;AAExD;;AC5QA,MAAa,4BAA4B;CACvC,MAAM;CACN,OAAO;CACP,MAAM;AACR"}
@@ -0,0 +1,2 @@
1
+ import "./index-Mw3ltwSG.js";
2
+ import "./index-DqdyM0Jm.js";
package/dist/shared.d.ts CHANGED
@@ -1,14 +1,4 @@
1
- export { A as AttachmentContextValue, u as useAttachment } from './attachment-mbjsroli.js';
2
- export { C as ChatController, a as ChatProvider, b as ChatProviderProps, u as useChatContext, c as useHumanInput } from './chat-PSj1Fo4W.js';
3
- export { C as CompletionController, a as CompletionInputContextValue, b as CompletionProvider, c as CompletionProviderProps, u as useCompletionContext, d as useCompletionInput } from './completion-input-DHlwrhxB.js';
4
- export { C as ComposerAttachmentInput, a as ComposerAttachmentsUpdate, b as ComposerContextValue, c as ComposerEntitiesUpdate, d as ComposerEntity, e as ComposerEntityData, f as ComposerMessageMetadata, g as ComposerQuote, h as ComposerTriggerDefinition, i as ComposerTriggerItem, j as ComposerTriggerItems, k as ComposerTriggerItemsArgs, l as ComposerTriggerState, m as ComposerTriggerStateUpdate, u as useComposer } from './composer-6iCSIq6L.js';
5
- export { A as ApprovalContextValue, Q as QuestionContextValue, a as QuestionPromptContextValue, u as useApproval, b as useQuestion, c as useQuestionPrompt } from './human-input-CkLrZ8IC.js';
6
- export { I as ImageContextValue, u as useImage } from './image-VZv6Ddsn.js';
7
- export { M as MessageContextValue, a as MessagePartContextValue, u as useMessage, b as useMessagePart } from './message-CNRnZQwU.js';
8
- export { S as SelectionToolbarContextValue, a as SelectionToolbarSelection, u as useSelectionToolbar } from './selection-toolbar-Cwjbuv5S.js';
9
- export { T as ThreadContextValue, u as useThread } from './thread-Bz6-1zaJ.js';
10
- export { T as ThreadListController, a as ThreadListItemContextValue, b as ThreadListProvider, c as ThreadListProviderProps, d as ThreadListRecord, u as useThreadList, e as useThreadListItem } from './thread-list-On8db4XL.js';
11
- export { P as PrimitiveProps, a as PrimitiveRef } from './render-CRKWam2v.js';
12
- import '@anvia/client';
13
- import '@anvia/react';
14
- import 'react';
1
+ import { $ as CompletionProvider, A as ComposerEntitiesUpdate, B as ComposerTriggerStateUpdate, C as QuestionPromptContextValue, D as ComposerAttachmentInput, E as useQuestionPrompt, F as ComposerTriggerDefinition, H as CompletionInputContextValue, I as ComposerTriggerItem, L as ComposerTriggerItems, M as ComposerEntityData, N as ComposerMessageMetadata, O as ComposerAttachmentsUpdate, P as ComposerQuote, Q as CompletionController, R as ComposerTriggerItemsArgs, T as useQuestion, U as useCompletionInput, V as useComposer, _ as ImageContextValue, a as ThreadListRecord, at as useChatContext, c as ThreadContextValue, ct as useAttachment, d as SelectionToolbarSelection, et as CompletionProviderProps, f as useSelectionToolbar, g as useMessagePart, h as useMessage, i as ThreadListProviderProps, it as ChatProviderProps, j as ComposerEntity, k as ComposerContextValue, l as useThread, m as MessagePartContextValue, n as ThreadListItemContextValue, nt as ChatController, o as useThreadList, ot as useHumanInput, p as MessageContextValue, r as ThreadListProvider, rt as ChatProvider, s as useThreadListItem, st as AttachmentContextValue, t as ThreadListController, tt as useCompletionContext, u as SelectionToolbarContextValue, v as useImage, w as useApproval, x as QuestionContextValue, y as ApprovalContextValue, z as ComposerTriggerState } from "./index-Mw3ltwSG.js";
2
+ import { n as PrimitiveRef, t as PrimitiveProps } from "./index-DqdyM0Jm.js";
3
+ import "./shared-BSYElFU2.js";
4
+ export { type ApprovalContextValue, type AttachmentContextValue, type ChatController, ChatProvider, type ChatProviderProps, type CompletionController, type CompletionInputContextValue, CompletionProvider, type CompletionProviderProps, type ComposerAttachmentInput, type ComposerAttachmentsUpdate, type ComposerContextValue, type ComposerEntitiesUpdate, type ComposerEntity, type ComposerEntityData, type ComposerMessageMetadata, type ComposerQuote, type ComposerTriggerDefinition, type ComposerTriggerItem, type ComposerTriggerItems, type ComposerTriggerItemsArgs, type ComposerTriggerState, type ComposerTriggerStateUpdate, type ImageContextValue, type MessageContextValue, type MessagePartContextValue, type PrimitiveProps, type PrimitiveRef, type QuestionContextValue, type QuestionPromptContextValue, type SelectionToolbarContextValue, type SelectionToolbarSelection, type ThreadContextValue, type ThreadListController, type ThreadListItemContextValue, ThreadListProvider, type ThreadListProviderProps, type ThreadListRecord, useApproval, useAttachment, useChatContext, useCompletionContext, useCompletionInput, useComposer, useHumanInput, useImage, useMessage, useMessagePart, useQuestion, useQuestionPrompt, useSelectionToolbar, useThread, useThreadList, useThreadListItem };
package/dist/shared.js CHANGED
@@ -1,43 +1 @@
1
- import {
2
- ChatProvider,
3
- CompletionProvider,
4
- ThreadListProvider,
5
- useApproval,
6
- useAttachment,
7
- useChatContext,
8
- useCompletionContext,
9
- useCompletionInput,
10
- useComposer,
11
- useHumanInput,
12
- useImage,
13
- useMessage,
14
- useMessagePart,
15
- useQuestion,
16
- useQuestionPrompt,
17
- useSelectionToolbar,
18
- useThread,
19
- useThreadList,
20
- useThreadListItem
21
- } from "./chunk-E73S3SOF.js";
22
- export {
23
- ChatProvider,
24
- CompletionProvider,
25
- ThreadListProvider,
26
- useApproval,
27
- useAttachment,
28
- useChatContext,
29
- useCompletionContext,
30
- useCompletionInput,
31
- useComposer,
32
- useHumanInput,
33
- useImage,
34
- useMessage,
35
- useMessagePart,
36
- useQuestion,
37
- useQuestionPrompt,
38
- useSelectionToolbar,
39
- useThread,
40
- useThreadList,
41
- useThreadListItem
42
- };
43
- //# sourceMappingURL=shared.js.map
1
+ export { F as ChatProvider, N as CompletionProvider, r as ThreadListProvider, x as useApproval, z as useAttachment, I as useChatContext, P as useCompletionContext, D as useCompletionInput, T as useComposer, L as useHumanInput, _ as useImage, p as useMessage, m as useMessagePart, S as useQuestion, C as useQuestionPrompt, u as useSelectionToolbar, c as useThread, a as useThreadList, o as useThreadListItem } from "./contexts-B4ijG24z.js";
@@ -1,22 +1,2 @@
1
- import * as react from 'react';
2
- import { Components, Options } from 'react-markdown';
3
- import { P as PrimitiveProps } from '../render-CRKWam2v.js';
4
-
5
- type StreamMarkdownProps = Omit<PrimitiveProps<"div">, "children"> & {
6
- "data-state"?: string | undefined;
7
- components?: Components;
8
- content: string;
9
- live?: boolean;
10
- remarkPlugins?: Options["remarkPlugins"];
11
- remarkRehypeOptions?: Options["remarkRehypeOptions"];
12
- };
13
- declare const StreamMarkdown: react.ForwardRefExoticComponent<Omit<PrimitiveProps<"div">, "children"> & {
14
- "data-state"?: string | undefined;
15
- components?: Components;
16
- content: string;
17
- live?: boolean;
18
- remarkPlugins?: Options["remarkPlugins"];
19
- remarkRehypeOptions?: Options["remarkRehypeOptions"];
20
- } & react.RefAttributes<HTMLDivElement>>;
21
-
22
- export { StreamMarkdown, type StreamMarkdownProps };
1
+ import { n as StreamMarkdownProps, t as StreamMarkdown } from "../index-CE22tsua.js";
2
+ export { StreamMarkdown, type StreamMarkdownProps };
@@ -1,8 +1 @@
1
- import {
2
- StreamMarkdown
3
- } from "../chunk-F6AKBUO3.js";
4
- import "../chunk-T3ZFZ3NP.js";
5
- export {
6
- StreamMarkdown
7
- };
8
- //# sourceMappingURL=index.js.map
1
+ export { t as StreamMarkdown } from "../stream-CAO0x8_1.js";
@@ -0,0 +1,298 @@
1
+ import { t as renderPrimitive } from "./primitives-xfE7zfwJ.js";
2
+ import { createElement, forwardRef, memo, useCallback, useMemo, useRef } from "react";
3
+ import { jsx } from "react/jsx-runtime";
4
+ import remarkGfm from "remark-gfm";
5
+ import ReactMarkdown from "react-markdown";
6
+ import { lexer } from "marked";
7
+ // src/stream/markdown-blocks.ts
8
+ function splitStreamMarkdownBlocks(content, options = {}) {
9
+ if (content.length === 0) return [];
10
+ if (options.singleDocument === true) return [{
11
+ content,
12
+ startOffset: 0
13
+ }];
14
+ try {
15
+ const tokens = lexer(content, { gfm: false });
16
+ if (tokens.some((token) => token.type === "def") || Object.keys(tokens.links).length > 0) return [{
17
+ content,
18
+ startOffset: 0
19
+ }];
20
+ const rawBlocks = [];
21
+ for (const token of tokens) if (token.type === "space" && rawBlocks.length > 0) {
22
+ const lastIndex = rawBlocks.length - 1;
23
+ rawBlocks[lastIndex] = `${rawBlocks[lastIndex] ?? ""}${token.raw}`;
24
+ } else rawBlocks.push(token.raw);
25
+ if (rawBlocks.length === 0 || rawBlocks.join("") !== content) return [{
26
+ content,
27
+ startOffset: 0
28
+ }];
29
+ let startOffset = 0;
30
+ return rawBlocks.map((block) => {
31
+ const result = {
32
+ content: block,
33
+ startOffset
34
+ };
35
+ startOffset += block.length;
36
+ return result;
37
+ });
38
+ } catch {
39
+ return [{
40
+ content,
41
+ startOffset: 0
42
+ }];
43
+ }
44
+ }
45
+ // src/stream/markdown-reveal.ts
46
+ const streamRevealConfig = {
47
+ bandGraphemes: 2,
48
+ durationMs: 180,
49
+ minimumOpacity: .12,
50
+ tailGraphemes: 24
51
+ };
52
+ function createStreamGradientRevealPlugin(lifecycleScope, lifecycle) {
53
+ return function streamGradientRevealPlugin() {
54
+ return (tree) => {
55
+ if (lifecycle.activeScope !== lifecycleScope) {
56
+ lifecycle.activeScope = lifecycleScope;
57
+ lifecycle.settledRevealIds.clear();
58
+ lifecycle.startedAtByRevealId.clear();
59
+ }
60
+ const targets = collectTextTargets(tree);
61
+ wrapStreamRevealGraphemes(targets, createRevealGraphemes(targets.map((target) => target.node.value ?? "").join("")), lifecycleScope, lifecycle);
62
+ };
63
+ };
64
+ }
65
+ function collectTextTargets(tree) {
66
+ const targets = [];
67
+ let offset = 0;
68
+ function visit(node, parent, index) {
69
+ if (node.type === "element" && node.tagName === "pre") return;
70
+ if (node.type === "text" && node.value !== void 0 && parent !== void 0) {
71
+ if (!/\S/u.test(node.value)) return;
72
+ const startOffset = offset;
73
+ offset += node.value.length;
74
+ targets.push({
75
+ endOffset: offset,
76
+ index,
77
+ node,
78
+ parent,
79
+ startOffset
80
+ });
81
+ return;
82
+ }
83
+ for (const [childIndex, child] of (node.children ?? []).entries()) visit(child, node, childIndex);
84
+ }
85
+ visit(tree, void 0, 0);
86
+ return targets;
87
+ }
88
+ function createRevealGraphemes(content) {
89
+ const tail = segmentTailGraphemeRanges(content, streamRevealConfig.tailGraphemes);
90
+ const graphemes = [];
91
+ for (let index = 0; index < tail.length; index += 1) {
92
+ const grapheme = tail[index];
93
+ const bandStartIndex = Math.floor(index / streamRevealConfig.bandGraphemes) * streamRevealConfig.bandGraphemes;
94
+ const bandEndIndex = Math.min(bandStartIndex + streamRevealConfig.bandGraphemes, tail.length) - 1;
95
+ if (grapheme === void 0) continue;
96
+ const progress = tail.length === 1 ? 1 : bandEndIndex / (tail.length - 1);
97
+ graphemes.push({
98
+ startOffset: grapheme.startOffset,
99
+ endOffset: grapheme.endOffset,
100
+ opacity: Math.max(streamRevealConfig.minimumOpacity, 1 - progress * (1 - streamRevealConfig.minimumOpacity))
101
+ });
102
+ }
103
+ return graphemes;
104
+ }
105
+ function wrapStreamRevealGraphemes(targets, graphemes, lifecycleScope, lifecycle) {
106
+ const activeRevealIds = /* @__PURE__ */ new Set();
107
+ const nowMs = Date.now();
108
+ for (const target of [...targets].reverse()) {
109
+ const value = target.node.value ?? "";
110
+ const intersectingGraphemes = graphemes.filter((grapheme) => grapheme.endOffset > target.startOffset && grapheme.startOffset < target.endOffset);
111
+ if (intersectingGraphemes.length === 0) continue;
112
+ const replacement = [];
113
+ let cursor = 0;
114
+ for (const grapheme of intersectingGraphemes) {
115
+ const start = Math.max(0, grapheme.startOffset - target.startOffset);
116
+ const end = Math.min(value.length, grapheme.endOffset - target.startOffset);
117
+ if (start > cursor) replacement.push({
118
+ type: "text",
119
+ value: value.slice(cursor, start)
120
+ });
121
+ if (end > start) {
122
+ const text = value.slice(start, end);
123
+ const revealId = `${lifecycleScope}:${target.startOffset + start}:${target.startOffset + end}:${hashText(text)}`;
124
+ activeRevealIds.add(revealId);
125
+ const startedAt = lifecycle.startedAtByRevealId.get(revealId) ?? nowMs;
126
+ lifecycle.startedAtByRevealId.set(revealId, startedAt);
127
+ const elapsedMs = Math.max(0, nowMs - startedAt);
128
+ if (elapsedMs >= streamRevealConfig.durationMs) lifecycle.settledRevealIds.add(revealId);
129
+ if (lifecycle.settledRevealIds.has(revealId)) replacement.push({
130
+ type: "text",
131
+ value: text
132
+ });
133
+ else {
134
+ const progress = Math.min(elapsedMs / streamRevealConfig.durationMs, 1);
135
+ const opacity = grapheme.opacity + (1 - grapheme.opacity) * progress;
136
+ const remainingMs = Math.max(1, streamRevealConfig.durationMs - elapsedMs);
137
+ replacement.push({
138
+ type: "element",
139
+ tagName: "span",
140
+ properties: {
141
+ "data-reveal-duration-ms": String(remainingMs),
142
+ "data-reveal-opacity": String(opacity),
143
+ "data-reveal-id": revealId,
144
+ "data-state": "revealing"
145
+ },
146
+ children: [{
147
+ type: "text",
148
+ value: text
149
+ }]
150
+ });
151
+ }
152
+ }
153
+ cursor = Math.max(cursor, end);
154
+ }
155
+ if (cursor < value.length) replacement.push({
156
+ type: "text",
157
+ value: value.slice(cursor)
158
+ });
159
+ target.parent.children?.splice(target.index, 1, ...replacement);
160
+ }
161
+ pruneRevealLifecycle(lifecycle, activeRevealIds);
162
+ }
163
+ function pruneRevealLifecycle(lifecycle, activeRevealIds) {
164
+ for (const revealId of lifecycle.startedAtByRevealId.keys()) if (!activeRevealIds.has(revealId)) lifecycle.startedAtByRevealId.delete(revealId);
165
+ for (const revealId of lifecycle.settledRevealIds) if (!activeRevealIds.has(revealId)) lifecycle.settledRevealIds.delete(revealId);
166
+ }
167
+ function hashText(text) {
168
+ let hash = 2166136261;
169
+ for (let index = 0; index < text.length; index += 1) {
170
+ hash ^= text.charCodeAt(index);
171
+ hash = Math.imul(hash, 16777619);
172
+ }
173
+ return (hash >>> 0).toString(36);
174
+ }
175
+ function segmentTailGraphemeRanges(content, limit) {
176
+ if (typeof Intl !== "undefined" && typeof Intl.Segmenter === "function") {
177
+ const segments = new Intl.Segmenter(void 0, { granularity: "grapheme" }).segment(content);
178
+ const ranges = [];
179
+ let cursor = content.length;
180
+ while (cursor > 0 && ranges.length < limit) {
181
+ const segment = segments.containing(cursor - 1);
182
+ if (segment === void 0) break;
183
+ ranges.unshift({
184
+ startOffset: segment.index,
185
+ endOffset: segment.index + segment.segment.length
186
+ });
187
+ cursor = segment.index;
188
+ }
189
+ return ranges;
190
+ }
191
+ const ranges = [];
192
+ let cursor = content.length;
193
+ while (cursor > 0 && ranges.length < limit) {
194
+ let startOffset = cursor - 1;
195
+ const code = content.charCodeAt(startOffset);
196
+ if (code >= 56320 && code <= 57343 && startOffset > 0) {
197
+ const previousCode = content.charCodeAt(startOffset - 1);
198
+ if (previousCode >= 55296 && previousCode <= 56319) startOffset -= 1;
199
+ }
200
+ ranges.unshift({
201
+ startOffset,
202
+ endOffset: cursor
203
+ });
204
+ cursor = startOffset;
205
+ }
206
+ return ranges;
207
+ }
208
+ // src/stream/markdown.tsx
209
+ const defaultRemarkPlugins = [remarkGfm];
210
+ const StreamMarkdown = forwardRef(function StreamMarkdown({ components, content, live = false, remarkPlugins, remarkRehypeOptions, ...props }, ref) {
211
+ const revealLifecycleRef = useRef({
212
+ activeScope: null,
213
+ content,
214
+ id: 0,
215
+ settledRevealIds: /* @__PURE__ */ new Set(),
216
+ startedAtByRevealId: /* @__PURE__ */ new Map()
217
+ });
218
+ const revealLifecycle = revealLifecycleRef.current;
219
+ if (revealLifecycle.content !== content) {
220
+ if (!content.startsWith(revealLifecycle.content)) {
221
+ revealLifecycle.id += 1;
222
+ revealLifecycle.activeScope = null;
223
+ revealLifecycle.settledRevealIds.clear();
224
+ revealLifecycle.startedAtByRevealId.clear();
225
+ }
226
+ revealLifecycle.content = content;
227
+ }
228
+ if (!live && revealLifecycle.activeScope !== null) for (const revealId of revealLifecycle.startedAtByRevealId.keys()) revealLifecycle.settledRevealIds.add(revealId);
229
+ const settleReveal = useCallback((revealId) => {
230
+ revealLifecycleRef.current.settledRevealIds.add(revealId);
231
+ }, []);
232
+ const blocks = useMemo(() => splitStreamMarkdownBlocks(content, { singleDocument: remarkPlugins !== void 0 }), [content, remarkPlugins]);
233
+ const streamingComponents = useMemo(() => withStreamRevealComponent(components, settleReveal), [components, settleReveal]);
234
+ return renderPrimitive("div", {
235
+ ...props,
236
+ children: blocks.map((block, index) => /* @__PURE__ */ jsx(StreamMarkdownBlock, {
237
+ components: streamingComponents,
238
+ content: block.content,
239
+ live: live && index === blocks.length - 1,
240
+ revealLifecycle,
241
+ revealScope: `${revealLifecycle.id}:${block.startOffset}`,
242
+ remarkPlugins: remarkPlugins ?? defaultRemarkPlugins,
243
+ remarkRehypeOptions
244
+ }, block.startOffset)),
245
+ "data-role": "markdown",
246
+ "data-state": props["data-state"] ?? (live ? "streaming" : "idle")
247
+ }, ref);
248
+ });
249
+ const StreamMarkdownBlock = memo(function StreamMarkdownBlock(props) {
250
+ const revealPlugin = useMemo(() => createStreamGradientRevealPlugin(props.revealScope, props.revealLifecycle), [props.revealScope, props.revealLifecycle]);
251
+ return /* @__PURE__ */ jsx(ReactMarkdown, {
252
+ components: props.components,
253
+ rehypePlugins: props.live ? [revealPlugin] : void 0,
254
+ remarkPlugins: props.remarkPlugins,
255
+ remarkRehypeOptions: props.remarkRehypeOptions,
256
+ children: props.content
257
+ });
258
+ });
259
+ function withStreamRevealComponent(components, onRevealSettled) {
260
+ const consumerSpan = components?.span;
261
+ return {
262
+ ...components,
263
+ span(spanProps) {
264
+ const safeProps = componentPropsWithoutKey(spanProps);
265
+ const internalProps = safeProps;
266
+ if (internalProps["data-state"] === "revealing") return streamRevealSpan(internalProps, onRevealSettled);
267
+ if (consumerSpan !== void 0) return createElement(consumerSpan, safeProps);
268
+ const { node: _node, ...elementProps } = safeProps;
269
+ return /* @__PURE__ */ jsx("span", { ...elementProps });
270
+ }
271
+ };
272
+ }
273
+ function componentPropsWithoutKey(props) {
274
+ const result = {};
275
+ for (const name of Object.keys(props)) if (name !== "key") result[name] = props[name];
276
+ return result;
277
+ }
278
+ function streamRevealSpan(props, onRevealSettled) {
279
+ const { children, node: _node, "data-reveal-duration-ms": durationMs, "data-reveal-opacity": opacity, "data-reveal-id": revealId, onAnimationEnd, ...elementProps } = props;
280
+ const parsedOpacity = Number(opacity);
281
+ const parsedDurationMs = Number(durationMs);
282
+ return /* @__PURE__ */ createElement("span", {
283
+ ...elementProps,
284
+ "data-state": "revealing",
285
+ key: revealId ?? "stream-reveal",
286
+ onAnimationEnd: (event) => {
287
+ onAnimationEnd?.(event);
288
+ if (revealId !== void 0) onRevealSettled(revealId);
289
+ },
290
+ style: {
291
+ "--anvia-stream-reveal-opacity": Number.isFinite(parsedOpacity) ? parsedOpacity : 1,
292
+ "--anvia-stream-reveal-duration": `${Number.isFinite(parsedDurationMs) ? parsedDurationMs : 180}ms`
293
+ }
294
+ }, children);
295
+ }
296
+ export { StreamMarkdown as t };
297
+
298
+ //# sourceMappingURL=stream-CAO0x8_1.js.map