@core-pilot/client-vue 0.0.9 → 0.0.11

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 (67) hide show
  1. package/dist/cjs/client-vue.css +1 -1
  2. package/dist/cjs/components/bubble-list/index.js +1 -1
  3. package/dist/cjs/components/bubble-list/index.js.map +1 -1
  4. package/dist/cjs/components/core-upload/index.js +1 -1
  5. package/dist/cjs/components/core-upload/index.js.map +1 -1
  6. package/dist/cjs/components/editor-sender/index.js +1 -1
  7. package/dist/cjs/components/editor-sender/index.js.map +1 -1
  8. package/dist/cjs/components/x-markdown/composables/useFormHandler.js +2 -0
  9. package/dist/cjs/components/x-markdown/composables/useFormHandler.js.map +1 -0
  10. package/dist/cjs/components/x-markdown/composables/useImageLoader.js +2 -0
  11. package/dist/cjs/components/x-markdown/composables/useImageLoader.js.map +1 -0
  12. package/dist/cjs/components/x-markdown/composables/useMarkdownProcessor.js +2 -0
  13. package/dist/cjs/components/x-markdown/composables/useMarkdownProcessor.js.map +1 -0
  14. package/dist/cjs/components/x-markdown/composables/useRefHandler.js +2 -0
  15. package/dist/cjs/components/x-markdown/composables/useRefHandler.js.map +1 -0
  16. package/dist/cjs/components/x-markdown/composables/useStreamHandler.js +2 -0
  17. package/dist/cjs/components/x-markdown/composables/useStreamHandler.js.map +1 -0
  18. package/dist/cjs/components/x-markdown/index.js +1 -1
  19. package/dist/cjs/components/x-markdown/index.js.map +1 -1
  20. package/dist/cjs/components/x-markdown/renderers/hastRenderer.js +2 -0
  21. package/dist/cjs/components/x-markdown/renderers/hastRenderer.js.map +1 -0
  22. package/dist/cjs/components/x-markdown/utils/disabledUtils.js +2 -0
  23. package/dist/cjs/components/x-markdown/utils/disabledUtils.js.map +1 -0
  24. package/dist/cjs/components/x-markdown/utils/formUtils.js +2 -0
  25. package/dist/cjs/components/x-markdown/utils/formUtils.js.map +1 -0
  26. package/dist/cjs/components/x-markdown/utils/jsonUtils.js +2 -0
  27. package/dist/cjs/components/x-markdown/utils/jsonUtils.js.map +1 -0
  28. package/dist/cjs/components/x-markdown/utils/parseCorePilotSchema.js +1 -1
  29. package/dist/cjs/components/x-markdown/utils/parseCorePilotSchema.js.map +1 -1
  30. package/dist/cjs/components/x-markdown/utils/refUtils.js +2 -0
  31. package/dist/cjs/components/x-markdown/utils/refUtils.js.map +1 -0
  32. package/dist/cjs/components/x-markdown/utils/textFormatUtils.js +2 -0
  33. package/dist/cjs/components/x-markdown/utils/textFormatUtils.js.map +1 -0
  34. package/dist/es/client-vue.css +1 -1
  35. package/dist/es/components/bubble-list/index.js +3 -0
  36. package/dist/es/components/bubble-list/index.js.map +1 -1
  37. package/dist/es/components/core-upload/index.js +33 -24
  38. package/dist/es/components/core-upload/index.js.map +1 -1
  39. package/dist/es/components/editor-sender/index.js +39 -16
  40. package/dist/es/components/editor-sender/index.js.map +1 -1
  41. package/dist/es/components/x-markdown/composables/useFormHandler.js +66 -0
  42. package/dist/es/components/x-markdown/composables/useFormHandler.js.map +1 -0
  43. package/dist/es/components/x-markdown/composables/useImageLoader.js +58 -0
  44. package/dist/es/components/x-markdown/composables/useImageLoader.js.map +1 -0
  45. package/dist/es/components/x-markdown/composables/useMarkdownProcessor.js +48 -0
  46. package/dist/es/components/x-markdown/composables/useMarkdownProcessor.js.map +1 -0
  47. package/dist/es/components/x-markdown/composables/useRefHandler.js +80 -0
  48. package/dist/es/components/x-markdown/composables/useRefHandler.js.map +1 -0
  49. package/dist/es/components/x-markdown/composables/useStreamHandler.js +45 -0
  50. package/dist/es/components/x-markdown/composables/useStreamHandler.js.map +1 -0
  51. package/dist/es/components/x-markdown/index.js +85 -646
  52. package/dist/es/components/x-markdown/index.js.map +1 -1
  53. package/dist/es/components/x-markdown/renderers/hastRenderer.js +427 -0
  54. package/dist/es/components/x-markdown/renderers/hastRenderer.js.map +1 -0
  55. package/dist/es/components/x-markdown/utils/disabledUtils.js +15 -0
  56. package/dist/es/components/x-markdown/utils/disabledUtils.js.map +1 -0
  57. package/dist/es/components/x-markdown/utils/formUtils.js +82 -0
  58. package/dist/es/components/x-markdown/utils/formUtils.js.map +1 -0
  59. package/dist/es/components/x-markdown/utils/jsonUtils.js +20 -0
  60. package/dist/es/components/x-markdown/utils/jsonUtils.js.map +1 -0
  61. package/dist/es/components/x-markdown/utils/parseCorePilotSchema.js +10 -0
  62. package/dist/es/components/x-markdown/utils/parseCorePilotSchema.js.map +1 -1
  63. package/dist/es/components/x-markdown/utils/refUtils.js +18 -0
  64. package/dist/es/components/x-markdown/utils/refUtils.js.map +1 -0
  65. package/dist/es/components/x-markdown/utils/textFormatUtils.js +46 -0
  66. package/dist/es/components/x-markdown/utils/textFormatUtils.js.map +1 -0
  67. package/package.json +1 -1
@@ -0,0 +1,58 @@
1
+ const useImageLoader = (container) => {
2
+ const pendingImages = /* @__PURE__ */ new Set();
3
+ const setPlaceholderDimensions = (img) => {
4
+ var _a;
5
+ const containerWidth = ((_a = img.parentElement) == null ? void 0 : _a.offsetWidth) || 0;
6
+ if (img.naturalWidth > containerWidth) {
7
+ img.style.maxWidth = "100%";
8
+ }
9
+ if (img.naturalWidth && img.naturalHeight) {
10
+ const ratio = img.naturalHeight / img.naturalWidth;
11
+ img.style.maxHeight = `${Math.min(500, containerWidth * ratio)}px`;
12
+ }
13
+ };
14
+ const handleImageLoad = (event) => {
15
+ const img = event.currentTarget;
16
+ if (!img) return;
17
+ pendingImages.delete(img);
18
+ img.setAttribute("data-processed", "true");
19
+ img.classList.add("loaded");
20
+ img.style.opacity = "1";
21
+ img.removeEventListener("load", handleImageLoad);
22
+ img.removeEventListener("error", handleImageError);
23
+ };
24
+ const handleImageError = (event) => {
25
+ const img = event.currentTarget;
26
+ if (!img) return;
27
+ pendingImages.delete(img);
28
+ img.setAttribute("data-processed", "true");
29
+ img.classList.add("load-error");
30
+ img.style.maxHeight = "200px";
31
+ img.removeEventListener("load", handleImageLoad);
32
+ img.removeEventListener("error", handleImageError);
33
+ };
34
+ const processNewImages = () => {
35
+ if (!container.value) return;
36
+ const newImages = container.value.querySelectorAll(
37
+ "img:not([data-processed='true'])"
38
+ );
39
+ newImages.forEach((img) => {
40
+ if (pendingImages.has(img)) return;
41
+ pendingImages.add(img);
42
+ setPlaceholderDimensions(img);
43
+ if (img.complete) {
44
+ handleImageLoad(new Event("load"));
45
+ } else {
46
+ img.addEventListener("load", handleImageLoad);
47
+ img.addEventListener("error", handleImageError);
48
+ }
49
+ });
50
+ };
51
+ return {
52
+ processNewImages
53
+ };
54
+ };
55
+ export {
56
+ useImageLoader
57
+ };
58
+ //# sourceMappingURL=useImageLoader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useImageLoader.js","sources":["../../../../../src/components/x-markdown/composables/useImageLoader.ts"],"sourcesContent":["/**\n * 图片加载处理 Composable\n * 处理图片的渐进式加载和错误处理\n */\n\nimport { ref, Ref, nextTick } from 'vue';\n\nexport const useImageLoader = (container: Ref<HTMLElement | undefined>) => {\n const pendingImages = new Set<HTMLImageElement>();\n\n /**\n * 设置图片占位尺寸\n */\n const setPlaceholderDimensions = (img: HTMLImageElement) => {\n const containerWidth = img.parentElement?.offsetWidth || 0;\n if (img.naturalWidth > containerWidth) {\n img.style.maxWidth = \"100%\";\n }\n \n if (img.naturalWidth && img.naturalHeight) {\n const ratio = img.naturalHeight / img.naturalWidth;\n img.style.maxHeight = `${Math.min(500, containerWidth * ratio)}px`;\n }\n };\n\n /**\n * 图片加载成功处理\n */\n const handleImageLoad = (event: Event) => {\n const img = event.currentTarget as HTMLImageElement | null;\n if (!img) return;\n\n pendingImages.delete(img);\n img.setAttribute(\"data-processed\", \"true\");\n img.classList.add(\"loaded\");\n img.style.opacity = \"1\";\n img.removeEventListener(\"load\", handleImageLoad as EventListener);\n img.removeEventListener(\"error\", handleImageError as EventListener);\n };\n\n /**\n * 图片加载失败处理\n */\n const handleImageError = (event: Event) => {\n const img = event.currentTarget as HTMLImageElement | null;\n if (!img) return;\n\n pendingImages.delete(img);\n img.setAttribute(\"data-processed\", \"true\");\n img.classList.add(\"load-error\");\n img.style.maxHeight = \"200px\";\n img.removeEventListener(\"load\", handleImageLoad as EventListener);\n img.removeEventListener(\"error\", handleImageError as EventListener);\n };\n\n /**\n * 处理新加载的图片\n * 核心逻辑:设置占位尺寸,渐进式加载\n */\n const processNewImages = () => {\n if (!container.value) return;\n \n const newImages = container.value.querySelectorAll(\n \"img:not([data-processed='true'])\"\n ) as NodeListOf<HTMLImageElement>;\n \n newImages.forEach((img) => {\n if (pendingImages.has(img)) return;\n pendingImages.add(img);\n \n // 设置占位尺寸,避免布局重排\n setPlaceholderDimensions(img);\n \n // 处理已加载的图片\n if (img.complete) {\n // 手动构造一个事件对象以复用处理逻辑\n handleImageLoad(new Event(\"load\"));\n } else {\n img.addEventListener(\"load\", handleImageLoad as EventListener);\n img.addEventListener(\"error\", handleImageError as EventListener);\n }\n });\n };\n\n return {\n processNewImages,\n };\n};\n\n"],"names":[],"mappings":"AAOO,MAAM,iBAAiB,CAAC,cAA4C;AACzE,QAAM,oCAAoB,IAAA;AAK1B,QAAM,2BAA2B,CAAC,QAA0B;AANvD;AAOH,UAAM,mBAAiB,SAAI,kBAAJ,mBAAmB,gBAAe;AACzD,QAAI,IAAI,eAAe,gBAAgB;AACrC,UAAI,MAAM,WAAW;AAAA,IACvB;AAEA,QAAI,IAAI,gBAAgB,IAAI,eAAe;AACzC,YAAM,QAAQ,IAAI,gBAAgB,IAAI;AACtC,UAAI,MAAM,YAAY,GAAG,KAAK,IAAI,KAAK,iBAAiB,KAAK,CAAC;AAAA,IAChE;AAAA,EACF;AAKA,QAAM,kBAAkB,CAAC,UAAiB;AACxC,UAAM,MAAM,MAAM;AAClB,QAAI,CAAC,IAAK;AAEV,kBAAc,OAAO,GAAG;AACxB,QAAI,aAAa,kBAAkB,MAAM;AACzC,QAAI,UAAU,IAAI,QAAQ;AAC1B,QAAI,MAAM,UAAU;AACpB,QAAI,oBAAoB,QAAQ,eAAgC;AAChE,QAAI,oBAAoB,SAAS,gBAAiC;AAAA,EACpE;AAKA,QAAM,mBAAmB,CAAC,UAAiB;AACzC,UAAM,MAAM,MAAM;AAClB,QAAI,CAAC,IAAK;AAEV,kBAAc,OAAO,GAAG;AACxB,QAAI,aAAa,kBAAkB,MAAM;AACzC,QAAI,UAAU,IAAI,YAAY;AAC9B,QAAI,MAAM,YAAY;AACtB,QAAI,oBAAoB,QAAQ,eAAgC;AAChE,QAAI,oBAAoB,SAAS,gBAAiC;AAAA,EACpE;AAMA,QAAM,mBAAmB,MAAM;AAC7B,QAAI,CAAC,UAAU,MAAO;AAEtB,UAAM,YAAY,UAAU,MAAM;AAAA,MAChC;AAAA,IAAA;AAGF,cAAU,QAAQ,CAAC,QAAQ;AACzB,UAAI,cAAc,IAAI,GAAG,EAAG;AAC5B,oBAAc,IAAI,GAAG;AAGrB,+BAAyB,GAAG;AAG5B,UAAI,IAAI,UAAU;AAEhB,wBAAgB,IAAI,MAAM,MAAM,CAAC;AAAA,MACnC,OAAO;AACL,YAAI,iBAAiB,QAAQ,eAAgC;AAC7D,YAAI,iBAAiB,SAAS,gBAAiC;AAAA,MACjE;AAAA,IACF,CAAC;AAAA,EACH;AAEA,SAAO;AAAA,IACL;AAAA,EAAA;AAEJ;"}
@@ -0,0 +1,48 @@
1
+ import { ref, watch, nextTick } from "vue";
2
+ import { normalizeHistoryInputs, computedForm } from "../utils/formUtils.js";
3
+ import { unified } from "../../../node_modules/.pnpm/unified@11.0.5/node_modules/unified/lib/index.js";
4
+ import remarkParse from "../../../node_modules/.pnpm/remark-parse@11.0.0/node_modules/remark-parse/lib/index.js";
5
+ import remarkBreaks from "../../../node_modules/.pnpm/remark-breaks@4.0.0/node_modules/remark-breaks/lib/index.js";
6
+ import remarkGfm from "../../../node_modules/.pnpm/remark-gfm@4.0.1/node_modules/remark-gfm/lib/index.js";
7
+ import remarkMath from "../../../node_modules/.pnpm/remark-math@6.0.0/node_modules/remark-math/lib/index.js";
8
+ import remarkGemoji from "../../../node_modules/.pnpm/remark-gemoji@8.0.0/node_modules/remark-gemoji/lib/index.js";
9
+ import remarkRehype from "../../../node_modules/.pnpm/remark-rehype@11.1.2/node_modules/remark-rehype/lib/index.js";
10
+ import rehypeRaw from "../../../node_modules/.pnpm/rehype-raw@7.0.0/node_modules/rehype-raw/lib/index.js";
11
+ import rehypeKatex from "../../../node_modules/.pnpm/rehype-katex@7.0.1/node_modules/rehype-katex/lib/index.js";
12
+ import rehypeStringify from "../../../node_modules/.pnpm/rehype-stringify@10.0.1/node_modules/rehype-stringify/lib/index.js";
13
+ const useMarkdownProcessor = (formatText, historyInputs) => {
14
+ const ast = ref(null);
15
+ const hitlData = ref([]);
16
+ const md = unified().use(remarkParse).use(remarkBreaks).use(remarkGfm, { singleTilde: false }).use(remarkMath).use(remarkGemoji).use(remarkRehype, { allowDangerousHtml: true }).use(rehypeRaw).use(rehypeKatex).use(rehypeStringify);
17
+ watch(
18
+ formatText,
19
+ async (text) => {
20
+ if (!text) {
21
+ ast.value = null;
22
+ hitlData.value = [];
23
+ return;
24
+ }
25
+ try {
26
+ const mdAst = await md.run(md.parse(text));
27
+ const historyInputsMap = (historyInputs == null ? void 0 : historyInputs.value) ? normalizeHistoryInputs(historyInputs.value) : void 0;
28
+ const formDataList = computedForm(mdAst, historyInputsMap);
29
+ hitlData.value = formDataList;
30
+ await nextTick();
31
+ ast.value = mdAst;
32
+ } catch (error) {
33
+ console.error("Failed to process markdown:", error);
34
+ ast.value = null;
35
+ hitlData.value = [];
36
+ }
37
+ },
38
+ { immediate: true }
39
+ );
40
+ return {
41
+ ast,
42
+ hitlData
43
+ };
44
+ };
45
+ export {
46
+ useMarkdownProcessor
47
+ };
48
+ //# sourceMappingURL=useMarkdownProcessor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useMarkdownProcessor.js","sources":["../../../../../src/components/x-markdown/composables/useMarkdownProcessor.ts"],"sourcesContent":["/**\n * Markdown 处理 Composable\n * 处理 Markdown 到 AST 的转换和表单数据提取\n */\n\nimport { ref, Ref, computed, watch, nextTick } from 'vue';\nimport { unified } from \"unified\";\nimport remarkParse from \"remark-parse\";\nimport remarkBreaks from \"remark-breaks\";\nimport remarkGfm from \"remark-gfm\";\nimport remarkMath from \"remark-math\";\nimport remarkGemoji from \"remark-gemoji\";\nimport remarkRehype from \"remark-rehype\";\nimport rehypeRaw from \"rehype-raw\";\nimport rehypeKatex from \"rehype-katex\";\nimport rehypeStringify from \"rehype-stringify\";\nimport { computedForm, normalizeHistoryInputs, FormDataMap } from '../utils/formUtils';\n\nexport const useMarkdownProcessor = (\n formatText: Ref<string>,\n historyInputs?: Ref<Record<string, any> | FormDataMap | undefined>\n) => {\n const ast = ref<any>(null);\n const hitlData = ref<Array<Record<string, any>>>([]);\n\n // 初始化 unified 处理链\n const md = unified()\n .use(remarkParse) // 解析Markdown为AST\n .use(remarkBreaks) // 处理换行符\n .use(remarkGfm, { singleTilde: false }) // GitHub Flavored Markdown支持\n .use(remarkMath) // 数学公式支持\n .use(remarkGemoji) // Emoji支持\n .use(remarkRehype, { allowDangerousHtml: true }) // 转换为HTML AST\n .use(rehypeRaw)\n .use(rehypeKatex)\n .use(rehypeStringify);\n\n // 处理 Markdown 文本变化\n watch(\n formatText,\n async (text) => {\n if (!text) {\n ast.value = null;\n hitlData.value = [];\n return;\n }\n\n try {\n // 处理Markdown到hast再到VNode的转换\n const mdAst = await md.run(md.parse(text));\n \n // 递归遍历所有 CorePilot schema,收集 form 表单及其预定义数据\n const historyInputsMap = historyInputs?.value \n ? normalizeHistoryInputs(historyInputs.value)\n : undefined;\n const formDataList = computedForm(mdAst, historyInputsMap);\n hitlData.value = formDataList;\n\n await nextTick();\n ast.value = mdAst;\n } catch (error) {\n console.error('Failed to process markdown:', error);\n ast.value = null;\n hitlData.value = [];\n }\n },\n { immediate: true }\n );\n\n return {\n ast,\n hitlData,\n };\n};\n\n"],"names":[],"mappings":";;;;;;;;;;;;AAkBO,MAAM,uBAAuB,CAClC,YACA,kBACG;AACH,QAAM,MAAM,IAAS,IAAI;AACzB,QAAM,WAAW,IAAgC,EAAE;AAGnD,QAAM,KAAK,QAAA,EACR,IAAI,WAAW,EACf,IAAI,YAAY,EAChB,IAAI,WAAW,EAAE,aAAa,MAAA,CAAO,EACrC,IAAI,UAAU,EACd,IAAI,YAAY,EAChB,IAAI,cAAc,EAAE,oBAAoB,KAAA,CAAM,EAC9C,IAAI,SAAS,EACb,IAAI,WAAW,EACf,IAAI,eAAe;AAGtB;AAAA,IACE;AAAA,IACA,OAAO,SAAS;AACd,UAAI,CAAC,MAAM;AACT,YAAI,QAAQ;AACZ,iBAAS,QAAQ,CAAA;AACjB;AAAA,MACF;AAEA,UAAI;AAEF,cAAM,QAAQ,MAAM,GAAG,IAAI,GAAG,MAAM,IAAI,CAAC;AAGzC,cAAM,oBAAmB,+CAAe,SACpC,uBAAuB,cAAc,KAAK,IAC1C;AACJ,cAAM,eAAe,aAAa,OAAO,gBAAgB;AACzD,iBAAS,QAAQ;AAEjB,cAAM,SAAA;AACN,YAAI,QAAQ;AAAA,MACd,SAAS,OAAO;AACd,gBAAQ,MAAM,+BAA+B,KAAK;AAClD,YAAI,QAAQ;AACZ,iBAAS,QAAQ,CAAA;AAAA,MACnB;AAAA,IACF;AAAA,IACA,EAAE,WAAW,KAAA;AAAA,EAAK;AAGpB,SAAO;AAAA,IACL;AAAA,IACA;AAAA,EAAA;AAEJ;"}
@@ -0,0 +1,80 @@
1
+ import { ref, watch } from "vue";
2
+ const useRefHandler = (container, emit) => {
3
+ const refConfig = ref([]);
4
+ const activeRef = ref(null);
5
+ const getRefConfig = () => {
6
+ var _a;
7
+ const refContainer = (_a = container.value) == null ? void 0 : _a.querySelector("div[hidden]");
8
+ try {
9
+ refConfig.value = JSON.parse((refContainer == null ? void 0 : refContainer.textContent) || "[]");
10
+ emit("refConfigUpdate", refConfig.value);
11
+ } catch (error) {
12
+ refConfig.value = [];
13
+ }
14
+ };
15
+ const getTargeElement = (e) => {
16
+ const target = e.target;
17
+ if (target.tagName === "SPAN") {
18
+ const isInRefContainer = target.classList.contains("x-markdown-split");
19
+ const isRefContainer = target.classList.contains("x-markdown-sub");
20
+ if (isInRefContainer || isRefContainer) {
21
+ if (!isRefContainer) {
22
+ return target.parentElement;
23
+ }
24
+ return target;
25
+ }
26
+ }
27
+ return null;
28
+ };
29
+ const handleMouseOver = (e) => {
30
+ const target = getTargeElement(e);
31
+ if (target) {
32
+ activeRef.value = target;
33
+ return;
34
+ }
35
+ activeRef.value = null;
36
+ };
37
+ const handleClick = (e) => {
38
+ const target = getTargeElement(e);
39
+ if (target) {
40
+ const text = target.getAttribute("dataherf");
41
+ const highlight = JSON.parse(target.getAttribute("datahighlight") || "[]");
42
+ const page = Number(target.getAttribute("datanumber"));
43
+ const id = target.getAttribute("id");
44
+ const source = refConfig.value.find((item) => {
45
+ return item.link === text;
46
+ });
47
+ const data = {
48
+ ...source,
49
+ highlight,
50
+ page,
51
+ id
52
+ };
53
+ emit("clickActiveRefTrigger", data);
54
+ }
55
+ };
56
+ watch(activeRef, (newVal, oldVal) => {
57
+ if (newVal !== oldVal) {
58
+ if (newVal) {
59
+ const text = newVal.getAttribute("dataherf");
60
+ const target = refConfig.value.find((item) => {
61
+ return item.link === text;
62
+ });
63
+ emit("hoverActiveRefTrigger", target);
64
+ } else {
65
+ emit("hoverActiveRefTrigger", "");
66
+ }
67
+ }
68
+ });
69
+ return {
70
+ refConfig,
71
+ activeRef,
72
+ getRefConfig,
73
+ handleMouseOver,
74
+ handleClick
75
+ };
76
+ };
77
+ export {
78
+ useRefHandler
79
+ };
80
+ //# sourceMappingURL=useRefHandler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useRefHandler.js","sources":["../../../../../src/components/x-markdown/composables/useRefHandler.ts"],"sourcesContent":["/**\n * 引用处理 Composable\n * 处理文档引用的悬停、点击等交互\n */\n\nimport { ref, Ref, watch } from 'vue';\nimport { RefConfig } from '../utils/refUtils';\n\nexport const useRefHandler = (\n container: Ref<HTMLElement | undefined>,\n emit: (event: 'hoverActiveRefTrigger' | 'clickActiveRefTrigger' | 'refConfigUpdate', ...args: any[]) => void\n) => {\n const refConfig = ref<Array<RefConfig>>([]);\n const activeRef = ref<HTMLElement | null>(null);\n\n /**\n * 获取所有的ref配置\n */\n const getRefConfig = () => {\n const refContainer = (container.value as HTMLElement)?.querySelector('div[hidden]');\n try {\n refConfig.value = JSON.parse(refContainer?.textContent || '[]');\n emit('refConfigUpdate', refConfig.value);\n } catch (error) {\n refConfig.value = [];\n }\n };\n\n /**\n * 获取目标元素\n */\n const getTargeElement = (e: MouseEvent): HTMLElement | null => {\n const target = e.target as HTMLElement;\n if (target.tagName === 'SPAN') {\n const isInRefContainer = target.classList.contains('x-markdown-split');\n const isRefContainer = target.classList.contains('x-markdown-sub');\n if (isInRefContainer || isRefContainer) {\n if (!isRefContainer) {\n return target.parentElement as HTMLElement;\n }\n return target;\n }\n }\n return null;\n };\n\n /**\n * 处理鼠标悬停\n */\n const handleMouseOver = (e: MouseEvent) => {\n const target = getTargeElement(e);\n if (target) {\n activeRef.value = target;\n return;\n }\n activeRef.value = null;\n };\n\n /**\n * 处理点击事件\n */\n const handleClick = (e: MouseEvent) => {\n const target = getTargeElement(e);\n if (target) {\n const text = target.getAttribute('dataherf');\n const highlight = JSON.parse(target.getAttribute('datahighlight') || '[]') as Array<string>;\n const page = Number(target.getAttribute('datanumber'));\n const id = target.getAttribute('id');\n const source = refConfig.value.find((item) => {\n return item.link === text;\n });\n const data = {\n ...source,\n highlight,\n page,\n id,\n };\n emit('clickActiveRefTrigger', data);\n }\n };\n\n // 监听 activeRef 变化\n watch(activeRef, (newVal, oldVal) => {\n if (newVal !== oldVal) {\n if (newVal) {\n const text = newVal.getAttribute('dataherf');\n const target = refConfig.value.find((item) => {\n return item.link === text;\n });\n emit('hoverActiveRefTrigger', target);\n } else {\n emit('hoverActiveRefTrigger', '');\n }\n }\n });\n\n return {\n refConfig,\n activeRef,\n getRefConfig,\n handleMouseOver,\n handleClick,\n };\n};\n\n"],"names":[],"mappings":";AAQO,MAAM,gBAAgB,CAC3B,WACA,SACG;AACH,QAAM,YAAY,IAAsB,EAAE;AAC1C,QAAM,YAAY,IAAwB,IAAI;AAK9C,QAAM,eAAe,MAAM;;AACzB,UAAM,gBAAgB,eAAU,UAAV,mBAAiC,cAAc;AACrE,QAAI;AACF,gBAAU,QAAQ,KAAK,OAAM,6CAAc,gBAAe,IAAI;AAC9D,WAAK,mBAAmB,UAAU,KAAK;AAAA,IACzC,SAAS,OAAO;AACd,gBAAU,QAAQ,CAAA;AAAA,IACpB;AAAA,EACF;AAKA,QAAM,kBAAkB,CAAC,MAAsC;AAC7D,UAAM,SAAS,EAAE;AACjB,QAAI,OAAO,YAAY,QAAQ;AAC7B,YAAM,mBAAmB,OAAO,UAAU,SAAS,kBAAkB;AACrE,YAAM,iBAAiB,OAAO,UAAU,SAAS,gBAAgB;AACjE,UAAI,oBAAoB,gBAAgB;AACtC,YAAI,CAAC,gBAAgB;AACnB,iBAAO,OAAO;AAAA,QAChB;AACA,eAAO;AAAA,MACT;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAKA,QAAM,kBAAkB,CAAC,MAAkB;AACzC,UAAM,SAAS,gBAAgB,CAAC;AAChC,QAAI,QAAQ;AACV,gBAAU,QAAQ;AAClB;AAAA,IACF;AACA,cAAU,QAAQ;AAAA,EACpB;AAKA,QAAM,cAAc,CAAC,MAAkB;AACrC,UAAM,SAAS,gBAAgB,CAAC;AAChC,QAAI,QAAQ;AACV,YAAM,OAAO,OAAO,aAAa,UAAU;AAC3C,YAAM,YAAY,KAAK,MAAM,OAAO,aAAa,eAAe,KAAK,IAAI;AACzE,YAAM,OAAO,OAAO,OAAO,aAAa,YAAY,CAAC;AACrD,YAAM,KAAK,OAAO,aAAa,IAAI;AACnC,YAAM,SAAS,UAAU,MAAM,KAAK,CAAC,SAAS;AAC5C,eAAO,KAAK,SAAS;AAAA,MACvB,CAAC;AACD,YAAM,OAAO;AAAA,QACX,GAAG;AAAA,QACH;AAAA,QACA;AAAA,QACA;AAAA,MAAA;AAEF,WAAK,yBAAyB,IAAI;AAAA,IACpC;AAAA,EACF;AAGA,QAAM,WAAW,CAAC,QAAQ,WAAW;AACnC,QAAI,WAAW,QAAQ;AACrB,UAAI,QAAQ;AACV,cAAM,OAAO,OAAO,aAAa,UAAU;AAC3C,cAAM,SAAS,UAAU,MAAM,KAAK,CAAC,SAAS;AAC5C,iBAAO,KAAK,SAAS;AAAA,QACvB,CAAC;AACD,aAAK,yBAAyB,MAAM;AAAA,MACtC,OAAO;AACL,aAAK,yBAAyB,EAAE;AAAA,MAClC;AAAA,IACF;AAAA,EACF,CAAC;AAED,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA;AAEJ;"}
@@ -0,0 +1,45 @@
1
+ import { ref, watch } from "vue";
2
+ import { createStreamGenerator } from "../utils/mockStream.js";
3
+ const useStreamHandler = (text, typing, speed) => {
4
+ const context = ref("");
5
+ const tagComplete = ref(false);
6
+ const streamCall = (stream) => {
7
+ context.value = context.value + stream;
8
+ };
9
+ const streamGener = ref(
10
+ createStreamGenerator(streamCall, speed.value)
11
+ );
12
+ watch(() => [text.value, typing.value], (v, o) => {
13
+ var _a, _b, _c, _d;
14
+ const [newText, newTyping] = v;
15
+ const [oldText] = o || [];
16
+ if (!newText.startsWith(oldText)) {
17
+ (_a = streamGener.value) == null ? void 0 : _a.reset();
18
+ context.value = "";
19
+ tagComplete.value = false;
20
+ }
21
+ if (newText) {
22
+ (_b = streamGener.value) == null ? void 0 : _b.update(newText);
23
+ if (!newTyping) {
24
+ (_c = streamGener.value) == null ? void 0 : _c.stop();
25
+ return;
26
+ }
27
+ const checkReg = /<summary>资料整合<\/summary>\r?\n(.|\s)+?/;
28
+ if (!tagComplete.value && checkReg.test(newText)) {
29
+ tagComplete.value = true;
30
+ (_d = streamGener.value) == null ? void 0 : _d.setSpeed(500);
31
+ return;
32
+ }
33
+ }
34
+ }, {
35
+ immediate: true
36
+ });
37
+ return {
38
+ context,
39
+ tagComplete
40
+ };
41
+ };
42
+ export {
43
+ useStreamHandler
44
+ };
45
+ //# sourceMappingURL=useStreamHandler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useStreamHandler.js","sources":["../../../../../src/components/x-markdown/composables/useStreamHandler.ts"],"sourcesContent":["/**\n * 流式渲染处理 Composable\n * 处理流式文本渲染和速度控制\n */\n\nimport { ref, Ref, watch } from 'vue';\nimport { createStreamGenerator } from '../utils/mockStream';\n\nexport const useStreamHandler = (\n text: Ref<string>,\n typing: Ref<boolean>,\n speed: Ref<number>\n) => {\n const context = ref('');\n const tagComplete = ref(false);\n\n const streamCall = (stream: string) => {\n context.value = context.value + stream;\n };\n\n const streamGener = ref<ReturnType<typeof createStreamGenerator>>(\n createStreamGenerator(streamCall, speed.value)\n );\n\n // 监听 text 和 typing 变化\n watch(() => [text.value, typing.value], (v, o) => {\n const [newText, newTyping] = v;\n const [oldText] = o || [];\n \n if (!(newText as string).startsWith(oldText as string)) {\n streamGener.value?.reset();\n context.value = '';\n tagComplete.value = false;\n }\n \n if (newText) {\n streamGener.value?.update(newText as string);\n if (!newTyping) {\n streamGener.value?.stop();\n return;\n }\n \n // 资料整合 标签之后,采用服务端流式速度\n const checkReg = /<summary>资料整合<\\/summary>\\r?\\n(.|\\s)+?/;\n if (!tagComplete.value && checkReg.test(newText as string)) {\n tagComplete.value = true;\n streamGener.value?.setSpeed(500);\n return;\n }\n }\n }, {\n immediate: true,\n });\n\n return {\n context,\n tagComplete,\n };\n};\n\n"],"names":[],"mappings":";;AAQO,MAAM,mBAAmB,CAC9B,MACA,QACA,UACG;AACH,QAAM,UAAU,IAAI,EAAE;AACtB,QAAM,cAAc,IAAI,KAAK;AAE7B,QAAM,aAAa,CAAC,WAAmB;AACrC,YAAQ,QAAQ,QAAQ,QAAQ;AAAA,EAClC;AAEA,QAAM,cAAc;AAAA,IAClB,sBAAsB,YAAY,MAAM,KAAK;AAAA,EAAA;AAI/C,QAAM,MAAM,CAAC,KAAK,OAAO,OAAO,KAAK,GAAG,CAAC,GAAG,MAAM;;AAChD,UAAM,CAAC,SAAS,SAAS,IAAI;AAC7B,UAAM,CAAC,OAAO,IAAI,KAAK,CAAA;AAEvB,QAAI,CAAE,QAAmB,WAAW,OAAiB,GAAG;AACtD,wBAAY,UAAZ,mBAAmB;AACnB,cAAQ,QAAQ;AAChB,kBAAY,QAAQ;AAAA,IACtB;AAEA,QAAI,SAAS;AACX,wBAAY,UAAZ,mBAAmB,OAAO;AAC1B,UAAI,CAAC,WAAW;AACd,0BAAY,UAAZ,mBAAmB;AACnB;AAAA,MACF;AAGA,YAAM,WAAW;AACjB,UAAI,CAAC,YAAY,SAAS,SAAS,KAAK,OAAiB,GAAG;AAC1D,oBAAY,QAAQ;AACpB,0BAAY,UAAZ,mBAAmB,SAAS;AAC5B;AAAA,MACF;AAAA,IACF;AAAA,EACF,GAAG;AAAA,IACD,WAAW;AAAA,EAAA,CACZ;AAED,SAAO;AAAA,IACL;AAAA,IACA;AAAA,EAAA;AAEJ;"}