@opentiny/tiny-robot 0.1.0-alpha.0

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 (260) hide show
  1. package/.vscode/extensions.json +3 -0
  2. package/README.md +1 -0
  3. package/dist/_virtual/_plugin-vue_export-helper.js +9 -0
  4. package/dist/bubble-item/components/actions/copy.vue.d.ts +10 -0
  5. package/dist/bubble-item/components/actions/index.d.ts +2 -0
  6. package/dist/bubble-item/components/actions/refresh.vue.d.ts +2 -0
  7. package/dist/bubble-item/components/icons/ai.vue.d.ts +2 -0
  8. package/dist/bubble-item/components/icons/index.d.ts +2 -0
  9. package/dist/bubble-item/components/icons/user.vue.d.ts +2 -0
  10. package/dist/bubble-item/index.d.ts +7 -0
  11. package/dist/bubble-list/bubble-list.vue.d.ts +5 -0
  12. package/dist/bubble-list/index.d.ts +8 -0
  13. package/dist/bubble-list/index.type.d.ts +55 -0
  14. package/dist/conversations/index.d.ts +7 -0
  15. package/dist/conversations/index.vue.d.ts +2 -0
  16. package/dist/index.d.ts +12 -0
  17. package/dist/index.js +29 -0
  18. package/dist/node_modules/.pnpm/@opentiny_utils@3.22.0/node_modules/@opentiny/utils/dist/index.es.js +2202 -0
  19. package/dist/node_modules/.pnpm/@opentiny_vue-button@3.22.0/node_modules/@opentiny/vue-button/lib/index.js +113 -0
  20. package/dist/node_modules/.pnpm/@opentiny_vue-button@3.22.0/node_modules/@opentiny/vue-button/lib/pc.js +93 -0
  21. package/dist/node_modules/.pnpm/@opentiny_vue-common@3.22.0/node_modules/@opentiny/vue-common/lib/index.js +725 -0
  22. package/dist/node_modules/.pnpm/@opentiny_vue-dialog-box@3.22.0/node_modules/@opentiny/vue-dialog-box/lib/index.js +198 -0
  23. package/dist/node_modules/.pnpm/@opentiny_vue-dialog-box@3.22.0/node_modules/@opentiny/vue-dialog-box/lib/pc.js +204 -0
  24. package/dist/node_modules/.pnpm/@opentiny_vue-directive@3.22.0/node_modules/@opentiny/vue-directive/index.js +57 -0
  25. package/dist/node_modules/.pnpm/@opentiny_vue-hooks@3.22.0/node_modules/@opentiny/vue-hooks/dist/src/useEventListener.js +10 -0
  26. package/dist/node_modules/.pnpm/@opentiny_vue-hooks@3.22.0/node_modules/@opentiny/vue-hooks/dist/src/useInstanceSlots.js +14 -0
  27. package/dist/node_modules/.pnpm/@opentiny_vue-hooks@3.22.0/node_modules/@opentiny/vue-hooks/dist/src/useRelation.js +54 -0
  28. package/dist/node_modules/.pnpm/@opentiny_vue-hooks@3.22.0/node_modules/@opentiny/vue-hooks/dist/src/vue-popper.js +85 -0
  29. package/dist/node_modules/.pnpm/@opentiny_vue-hooks@3.22.0/node_modules/@opentiny/vue-hooks/dist/src/vue-popup.js +69 -0
  30. package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/close.js +29 -0
  31. package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/eyeclose.js +42 -0
  32. package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/eyeopen.js +43 -0
  33. package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/finish.js +34 -0
  34. package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/fullscreen.js +30 -0
  35. package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/loading-shadow.js +78 -0
  36. package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/minscreen.js +30 -0
  37. package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/rich-text-add-column-after.js +24 -0
  38. package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/rich-text-add-column-before.js +24 -0
  39. package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/rich-text-add-row-after.js +24 -0
  40. package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/rich-text-add-row-before.js +24 -0
  41. package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/rich-text-align-center.js +24 -0
  42. package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/rich-text-align-left.js +24 -0
  43. package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/rich-text-align-right.js +24 -0
  44. package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/rich-text-bold.js +24 -0
  45. package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/rich-text-code-block.js +24 -0
  46. package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/rich-text-code-view.js +24 -0
  47. package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/rich-text-color.js +24 -0
  48. package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/rich-text-delete-column.js +24 -0
  49. package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/rich-text-delete-row.js +24 -0
  50. package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/rich-text-delete-table.js +24 -0
  51. package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/rich-text-font-size.js +24 -0
  52. package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/rich-text-format-clear.js +24 -0
  53. package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/rich-text-h1.js +24 -0
  54. package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/rich-text-h2.js +24 -0
  55. package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/rich-text-h3.js +24 -0
  56. package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/rich-text-h4.js +24 -0
  57. package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/rich-text-h5.js +24 -0
  58. package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/rich-text-h6.js +24 -0
  59. package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/rich-text-heading.js +24 -0
  60. package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/rich-text-high-light.js +24 -0
  61. package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/rich-text-image.js +24 -0
  62. package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/rich-text-italic.js +24 -0
  63. package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/rich-text-line-height.js +24 -0
  64. package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/rich-text-link-unlink.js +24 -0
  65. package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/rich-text-link.js +24 -0
  66. package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/rich-text-list-ordered.js +24 -0
  67. package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/rich-text-list-unordered.js +24 -0
  68. package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/rich-text-merge-cells-vertical.js +24 -0
  69. package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/rich-text-merge-cells.js +24 -0
  70. package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/rich-text-node-delete.js +24 -0
  71. package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/rich-text-paragraph.js +24 -0
  72. package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/rich-text-quote-text.js +24 -0
  73. package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/rich-text-redo.js +24 -0
  74. package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/rich-text-split-cells-horizontal.js +24 -0
  75. package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/rich-text-split-cells-vertical.js +24 -0
  76. package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/rich-text-strike-through.js +24 -0
  77. package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/rich-text-subscript.js +24 -0
  78. package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/rich-text-superscript.js +24 -0
  79. package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/rich-text-table.js +24 -0
  80. package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/rich-text-task-list.js +24 -0
  81. package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/rich-text-underline.js +24 -0
  82. package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/rich-text-undo.js +24 -0
  83. package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/sub-script.js +29 -0
  84. package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/warn.js +26 -0
  85. package/dist/node_modules/.pnpm/@opentiny_vue-input@3.22.0/node_modules/@opentiny/vue-input/lib/index.js +196 -0
  86. package/dist/node_modules/.pnpm/@opentiny_vue-input@3.22.0/node_modules/@opentiny/vue-input/lib/pc.js +568 -0
  87. package/dist/node_modules/.pnpm/@opentiny_vue-locale@3.22.0/node_modules/@opentiny/vue-locale/lib/index.js +1783 -0
  88. package/dist/node_modules/.pnpm/@opentiny_vue-renderless@3.22.0/node_modules/@opentiny/vue-renderless/button/index.js +13 -0
  89. package/dist/node_modules/.pnpm/@opentiny_vue-renderless@3.22.0/node_modules/@opentiny/vue-renderless/button/vue.js +34 -0
  90. package/dist/node_modules/.pnpm/@opentiny_vue-renderless@3.22.0/node_modules/@opentiny/vue-renderless/chunk-G2ADBYYC.js +12 -0
  91. package/dist/node_modules/.pnpm/@opentiny_vue-renderless@3.22.0/node_modules/@opentiny/vue-renderless/dialog-box/index.js +135 -0
  92. package/dist/node_modules/.pnpm/@opentiny_vue-renderless@3.22.0/node_modules/@opentiny/vue-renderless/dialog-box/vue.js +149 -0
  93. package/dist/node_modules/.pnpm/@opentiny_vue-renderless@3.22.0/node_modules/@opentiny/vue-renderless/input/index.js +228 -0
  94. package/dist/node_modules/.pnpm/@opentiny_vue-renderless@3.22.0/node_modules/@opentiny/vue-renderless/input/vue.js +263 -0
  95. package/dist/node_modules/.pnpm/@opentiny_vue-renderless@3.22.0/node_modules/@opentiny/vue-renderless/tall-storage/index.js +63 -0
  96. package/dist/node_modules/.pnpm/@opentiny_vue-renderless@3.22.0/node_modules/@opentiny/vue-renderless/tall-storage/vue-storage-box.js +16 -0
  97. package/dist/node_modules/.pnpm/@opentiny_vue-renderless@3.22.0/node_modules/@opentiny/vue-renderless/tall-storage/vue.js +23 -0
  98. package/dist/node_modules/.pnpm/@opentiny_vue-renderless@3.22.0/node_modules/@opentiny/vue-renderless/tooltip/index.js +77 -0
  99. package/dist/node_modules/.pnpm/@opentiny_vue-renderless@3.22.0/node_modules/@opentiny/vue-renderless/tooltip/vue.js +90 -0
  100. package/dist/node_modules/.pnpm/@opentiny_vue-tooltip@3.22.0/node_modules/@opentiny/vue-tooltip/lib/index.js +176 -0
  101. package/dist/node_modules/.pnpm/@opentiny_vue-tooltip@3.22.0/node_modules/@opentiny/vue-tooltip/lib/pc.js +248 -0
  102. package/dist/node_modules/.pnpm/entities@4.5.0/node_modules/entities/lib/esm/decode.js +277 -0
  103. package/dist/node_modules/.pnpm/entities@4.5.0/node_modules/entities/lib/esm/decode_codepoint.js +46 -0
  104. package/dist/node_modules/.pnpm/entities@4.5.0/node_modules/entities/lib/esm/generated/decode-data-html.js +7 -0
  105. package/dist/node_modules/.pnpm/entities@4.5.0/node_modules/entities/lib/esm/generated/decode-data-xml.js +7 -0
  106. package/dist/node_modules/.pnpm/linkify-it@5.0.0/node_modules/linkify-it/index.js +187 -0
  107. package/dist/node_modules/.pnpm/linkify-it@5.0.0/node_modules/linkify-it/lib/re.js +19 -0
  108. package/dist/node_modules/.pnpm/lodash-es@4.17.21/node_modules/lodash-es/_Symbol.js +5 -0
  109. package/dist/node_modules/.pnpm/lodash-es@4.17.21/node_modules/lodash-es/_baseGetTag.js +10 -0
  110. package/dist/node_modules/.pnpm/lodash-es@4.17.21/node_modules/lodash-es/_baseTrim.js +8 -0
  111. package/dist/node_modules/.pnpm/lodash-es@4.17.21/node_modules/lodash-es/_freeGlobal.js +4 -0
  112. package/dist/node_modules/.pnpm/lodash-es@4.17.21/node_modules/lodash-es/_getRawTag.js +15 -0
  113. package/dist/node_modules/.pnpm/lodash-es@4.17.21/node_modules/lodash-es/_objectToString.js +7 -0
  114. package/dist/node_modules/.pnpm/lodash-es@4.17.21/node_modules/lodash-es/_root.js +5 -0
  115. package/dist/node_modules/.pnpm/lodash-es@4.17.21/node_modules/lodash-es/_trimmedEndIndex.js +9 -0
  116. package/dist/node_modules/.pnpm/lodash-es@4.17.21/node_modules/lodash-es/debounce.js +54 -0
  117. package/dist/node_modules/.pnpm/lodash-es@4.17.21/node_modules/lodash-es/isObject.js +7 -0
  118. package/dist/node_modules/.pnpm/lodash-es@4.17.21/node_modules/lodash-es/isObjectLike.js +6 -0
  119. package/dist/node_modules/.pnpm/lodash-es@4.17.21/node_modules/lodash-es/isSymbol.js +9 -0
  120. package/dist/node_modules/.pnpm/lodash-es@4.17.21/node_modules/lodash-es/now.js +7 -0
  121. package/dist/node_modules/.pnpm/lodash-es@4.17.21/node_modules/lodash-es/toNumber.js +22 -0
  122. package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/common/html_blocks.js +67 -0
  123. package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/common/html_re.js +5 -0
  124. package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/common/utils.js +164 -0
  125. package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/helpers/index.js +8 -0
  126. package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/helpers/parse_link_destination.js +44 -0
  127. package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/helpers/parse_link_label.js +21 -0
  128. package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/helpers/parse_link_title.js +37 -0
  129. package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/index.js +112 -0
  130. package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/parser_block.js +63 -0
  131. package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/parser_core.js +34 -0
  132. package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/parser_inline.js +96 -0
  133. package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/presets/commonmark.js +78 -0
  134. package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/presets/default.js +40 -0
  135. package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/presets/zero.js +59 -0
  136. package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/renderer.js +127 -0
  137. package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/ruler.js +95 -0
  138. package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_block/blockquote.js +59 -0
  139. package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_block/code.js +23 -0
  140. package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_block/fence.js +30 -0
  141. package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_block/heading.js +28 -0
  142. package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_block/hr.js +27 -0
  143. package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_block/html_block.js +37 -0
  144. package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_block/lheading.js +43 -0
  145. package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_block/list.js +110 -0
  146. package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_block/paragraph.js +25 -0
  147. package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_block/reference.js +95 -0
  148. package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_block/state_block.js +84 -0
  149. package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_block/table.js +99 -0
  150. package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_core/block.js +7 -0
  151. package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_core/inline.js +10 -0
  152. package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_core/linkify.js +57 -0
  153. package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_core/normalize.js +9 -0
  154. package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_core/replacements.js +31 -0
  155. package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_core/smartquotes.js +80 -0
  156. package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_core/state_core.js +8 -0
  157. package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_core/text_join.js +16 -0
  158. package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_inline/autolink.js +46 -0
  159. package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_inline/backticks.js +31 -0
  160. package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_inline/balance_pairs.js +34 -0
  161. package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_inline/emphasis.js +57 -0
  162. package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_inline/entity.js +33 -0
  163. package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_inline/escape.js +32 -0
  164. package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_inline/fragments_join.js +10 -0
  165. package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_inline/html_inline.js +32 -0
  166. package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_inline/image.js +48 -0
  167. package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_inline/link.js +40 -0
  168. package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_inline/linkify.js +28 -0
  169. package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_inline/newline.js +23 -0
  170. package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_inline/state_inline.js +27 -0
  171. package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_inline/strikethrough.js +54 -0
  172. package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_inline/text.js +39 -0
  173. package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/token.js +31 -0
  174. package/dist/node_modules/.pnpm/mdurl@2.0.0/node_modules/mdurl/index.js +10 -0
  175. package/dist/node_modules/.pnpm/mdurl@2.0.0/node_modules/mdurl/lib/decode.js +61 -0
  176. package/dist/node_modules/.pnpm/mdurl@2.0.0/node_modules/mdurl/lib/encode.js +48 -0
  177. package/dist/node_modules/.pnpm/mdurl@2.0.0/node_modules/mdurl/lib/format.js +7 -0
  178. package/dist/node_modules/.pnpm/mdurl@2.0.0/node_modules/mdurl/lib/parse.js +74 -0
  179. package/dist/node_modules/.pnpm/punycode.js@2.3.1/node_modules/punycode.js/punycode.es6.js +139 -0
  180. package/dist/node_modules/.pnpm/uc.micro@2.1.0/node_modules/uc.micro/categories/Cc/regex.js +4 -0
  181. package/dist/node_modules/.pnpm/uc.micro@2.1.0/node_modules/uc.micro/categories/Cf/regex.js +4 -0
  182. package/dist/node_modules/.pnpm/uc.micro@2.1.0/node_modules/uc.micro/categories/P/regex.js +4 -0
  183. package/dist/node_modules/.pnpm/uc.micro@2.1.0/node_modules/uc.micro/categories/S/regex.js +4 -0
  184. package/dist/node_modules/.pnpm/uc.micro@2.1.0/node_modules/uc.micro/categories/Z/regex.js +4 -0
  185. package/dist/node_modules/.pnpm/uc.micro@2.1.0/node_modules/uc.micro/index.js +14 -0
  186. package/dist/node_modules/.pnpm/uc.micro@2.1.0/node_modules/uc.micro/properties/Any/regex.js +4 -0
  187. package/dist/packages/components/src/assets/icons/accessory.svg.js +4 -0
  188. package/dist/packages/components/src/assets/icons/loading-speech.svg.js +4 -0
  189. package/dist/packages/components/src/assets/icons/loading.svg.js +4 -0
  190. package/dist/packages/components/src/assets/icons/send.svg.js +4 -0
  191. package/dist/packages/components/src/assets/icons/voice.svg.js +4 -0
  192. package/dist/packages/components/src/bubble-item/bubble-item.vue.js +7 -0
  193. package/dist/packages/components/src/bubble-item/bubble-item.vue2.js +111 -0
  194. package/dist/packages/components/src/bubble-item/components/actions/copy.vue.js +46 -0
  195. package/dist/packages/components/src/bubble-item/components/actions/copy.vue2.js +4 -0
  196. package/dist/packages/components/src/bubble-item/components/actions/refresh.vue.js +12 -0
  197. package/dist/packages/components/src/bubble-item/components/icons/ai.vue.js +45 -0
  198. package/dist/packages/components/src/bubble-item/components/icons/user.vue.js +63 -0
  199. package/dist/packages/components/src/bubble-item/index.js +9 -0
  200. package/dist/packages/components/src/bubble-list/bubble-list.vue.js +7 -0
  201. package/dist/packages/components/src/bubble-list/bubble-list.vue2.js +52 -0
  202. package/dist/packages/components/src/bubble-list/index.js +9 -0
  203. package/dist/packages/components/src/conversations/index.js +9 -0
  204. package/dist/packages/components/src/conversations/index.vue.js +9 -0
  205. package/dist/packages/components/src/sender/components/ActionButtons.vue.js +161 -0
  206. package/dist/packages/components/src/sender/components/ActionButtons.vue2.js +4 -0
  207. package/dist/packages/components/src/sender/composables/useInputHandler.js +34 -0
  208. package/dist/packages/components/src/sender/composables/useKeyboardHandler.js +31 -0
  209. package/dist/packages/components/src/sender/composables/useSpeechHandler.js +67 -0
  210. package/dist/packages/components/src/sender/index.js +9 -0
  211. package/dist/packages/components/src/sender/index.vue.js +233 -0
  212. package/dist/packages/components/src/sender/index.vue2.js +4 -0
  213. package/dist/packages/components/src/welcome/index.js +9 -0
  214. package/dist/packages/components/src/welcome/index.vue.js +9 -0
  215. package/dist/sender/components/ActionButtons.vue.d.ts +23 -0
  216. package/dist/sender/composables/useInputHandler.d.ts +17 -0
  217. package/dist/sender/composables/useKeyboardHandler.d.ts +18 -0
  218. package/dist/sender/composables/useSpeechHandler.d.ts +14 -0
  219. package/dist/sender/index.d.ts +7 -0
  220. package/dist/sender/index.type.d.ts +90 -0
  221. package/dist/sender/index.vue.d.ts +948 -0
  222. package/dist/style.css +1 -0
  223. package/dist/welcome/index.d.ts +7 -0
  224. package/dist/welcome/index.vue.d.ts +2 -0
  225. package/package.json +42 -0
  226. package/src/assets/icons/accessory.svg +12 -0
  227. package/src/assets/icons/loading-speech.svg +16 -0
  228. package/src/assets/icons/loading.svg +17 -0
  229. package/src/assets/icons/send.svg +21 -0
  230. package/src/assets/icons/voice.svg +22 -0
  231. package/src/bubble-item/bubble-item.vue +264 -0
  232. package/src/bubble-item/components/actions/copy.vue +47 -0
  233. package/src/bubble-item/components/actions/index.ts +2 -0
  234. package/src/bubble-item/components/actions/refresh.vue +27 -0
  235. package/src/bubble-item/components/icons/ai.vue +30 -0
  236. package/src/bubble-item/components/icons/index.ts +2 -0
  237. package/src/bubble-item/components/icons/user.vue +78 -0
  238. package/src/bubble-item/index.ts +12 -0
  239. package/src/bubble-list/bubble-list.vue +53 -0
  240. package/src/bubble-list/index.ts +14 -0
  241. package/src/bubble-list/index.type.ts +65 -0
  242. package/src/conversations/index.ts +12 -0
  243. package/src/conversations/index.vue +3 -0
  244. package/src/index.ts +30 -0
  245. package/src/sender/components/ActionButtons.vue +165 -0
  246. package/src/sender/composables/useInputHandler.ts +69 -0
  247. package/src/sender/composables/useKeyboardHandler.ts +99 -0
  248. package/src/sender/composables/useSpeechHandler.ts +128 -0
  249. package/src/sender/global.d.ts +44 -0
  250. package/src/sender/index.less +344 -0
  251. package/src/sender/index.ts +12 -0
  252. package/src/sender/index.type.ts +111 -0
  253. package/src/sender/index.vue +289 -0
  254. package/src/sender/vars.less +84 -0
  255. package/src/vite-env.d.ts +1 -0
  256. package/src/welcome/index.ts +12 -0
  257. package/src/welcome/index.vue +3 -0
  258. package/tsconfig.json +37 -0
  259. package/tsconfig.node.json +10 -0
  260. package/vite.config.ts +53 -0
@@ -0,0 +1,65 @@
1
+ import { Options as MarkdownItOptions } from 'markdown-it'
2
+ import { Component, CSSProperties, VNode } from 'vue'
3
+
4
+ export type BubbleRole = 'ai' | 'user'
5
+
6
+ export interface BubbleRoleConfig {
7
+ avatar?: VNode
8
+ align: 'left' | 'right'
9
+ }
10
+
11
+ export type BubbleStatus = 'loading' | 'generating' | 'aborted' | 'complete' | 'error'
12
+
13
+ export interface BubbleActionOptions {
14
+ name: string
15
+ vnode: VNode | Component
16
+ show?: boolean | ((props: BubbleItemProps) => boolean)
17
+ }
18
+
19
+ export type BubbleAction = 'copy' | 'regenerate' | 'like' | 'dislike' | 'continue' | 'edit' | BubbleActionOptions
20
+
21
+ export interface BubbleItemProps {
22
+ /**
23
+ * 角色,`ai` 或 `user`
24
+ */
25
+ role: BubbleRole
26
+ /**
27
+ * 内容
28
+ */
29
+ content?: string
30
+ /**
31
+ * 内容类型
32
+ */
33
+ type?: 'text' | 'markdown'
34
+ /**
35
+ * 气泡状态
36
+ */
37
+ status?: BubbleStatus
38
+ /**
39
+ * 角色配置项
40
+ */
41
+ roleConfig?: BubbleRoleConfig
42
+ /**
43
+ * type 为 'markdown' 时,markdown 的配置项
44
+ */
45
+ mdConfig?: MarkdownItOptions
46
+ showActions?: boolean
47
+ actions?: BubbleAction[]
48
+ // 样式相关
49
+ maxWidth?: CSSProperties['maxWidth']
50
+ }
51
+
52
+ export interface BubbleActionConfig {
53
+ show?: boolean
54
+ actions?: BubbleAction[]
55
+ }
56
+
57
+ export interface BubbleListProps {
58
+ items: BubbleItemProps[]
59
+ roleConfigs?: Partial<Record<BubbleRole, BubbleRoleConfig>>
60
+ mdConfig?: MarkdownItOptions
61
+ actionConfigs?: Partial<Record<BubbleRole, BubbleActionConfig>>
62
+ autoScroll?: boolean
63
+ // 样式相关
64
+ maxWidth?: CSSProperties['maxWidth']
65
+ }
@@ -0,0 +1,12 @@
1
+ import { App } from 'vue'
2
+ import Conversations from './index.vue'
3
+
4
+ Conversations.name = 'TrConversations'
5
+
6
+ const install = function <T>(app: App<T>) {
7
+ app.component(Conversations.name!, Conversations)
8
+ }
9
+
10
+ Conversations.install = install
11
+
12
+ export default Conversations as typeof Conversations & { install: typeof install }
@@ -0,0 +1,3 @@
1
+ <script setup lang="ts"></script>
2
+
3
+ <template>conversations</template>
package/src/index.ts ADDED
@@ -0,0 +1,30 @@
1
+ import { App } from 'vue'
2
+ import Welcome from './welcome'
3
+ import Conversations from './conversations'
4
+ import BubbleItem from './bubble-item'
5
+ import BubbleList from './bubble-list'
6
+ import Sender from './sender'
7
+
8
+ export * from './bubble-list/index.type'
9
+
10
+ const components = [Welcome, Conversations, BubbleItem, BubbleList, Sender]
11
+
12
+ export default {
13
+ install<T>(app: App<T>) {
14
+ components.forEach((component) => {
15
+ const name = component.name?.replace(/^Tiny/, '').replace(/^Tr/, '')
16
+ app.component(`Tr${name}`, component)
17
+ app.component(`Tiny${name}`, component)
18
+ })
19
+ },
20
+ }
21
+
22
+ export {
23
+ Welcome as TrWelcome,
24
+ Conversations as TrConversations,
25
+ BubbleItem as TrBubbleItem,
26
+ BubbleItem as TinyBubbleItem,
27
+ BubbleList as TrBubbleList,
28
+ BubbleList as TinyBubbleList,
29
+ Sender as TrSender,
30
+ }
@@ -0,0 +1,165 @@
1
+ <script setup lang="ts">
2
+ import { computed } from 'vue'
3
+ import { TinyButton, TinyTooltip } from '@opentiny/vue'
4
+ import { IconClose } from '@opentiny/vue-icon'
5
+ import { ActionButtonsProps } from '../index.type'
6
+
7
+ const TinyIconCloseSquare = IconClose()
8
+
9
+ const props = withDefaults(defineProps<ActionButtonsProps>(), {
10
+ /**
11
+ * 是否显示加载状态
12
+ * @default false
13
+ */
14
+ loading: false,
15
+ /**
16
+ * 是否禁用所有操作
17
+ * @default false
18
+ */
19
+ disabled: false,
20
+ /**
21
+ * 是否显示清除按钮
22
+ * @default true
23
+ */
24
+ showClear: true,
25
+ /**
26
+ * 输入框是否有内容
27
+ * @default false
28
+ */
29
+ hasContent: false,
30
+ /**
31
+ * 是否允许语音功能
32
+ */
33
+ allowSpeech: false,
34
+ speechStatus: () => ({
35
+ isRecording: false,
36
+ isSupported: false,
37
+ }),
38
+ /**
39
+ * 是否允许附件功能
40
+ */
41
+ allowFiles: false,
42
+ /**
43
+ * 提交快捷方式
44
+ * @default 'enter'
45
+ */
46
+ submitType: 'enter',
47
+ })
48
+
49
+ const emit = defineEmits({
50
+ /**
51
+ * 清除内容事件
52
+ */
53
+ clear: () => true,
54
+ /**
55
+ * 切换语音识别状态事件
56
+ * @param {boolean} state - 新的语音识别状态
57
+ */
58
+ 'toggle-speech': (state: boolean) => Boolean(state),
59
+ /**
60
+ * 提交内容事件
61
+ */
62
+ submit: () => true,
63
+ })
64
+
65
+ /**
66
+ * 是否启用语音功能
67
+ */
68
+ const speechEnabled = computed(() => props.allowSpeech)
69
+
70
+ /**
71
+ * 语音按钮提示文本
72
+ */
73
+ const speechButtonText = computed(() => (props.speechStatus.isRecording ? '停止录音' : '开始语音输入'))
74
+
75
+ const isSpeechRecording = computed(() => props.speechStatus.isRecording)
76
+
77
+ /**
78
+ * 提交按钮tooltip
79
+ */
80
+ const submitTooltip = computed(() => {
81
+ return props.loading ? `发送中...` : '发送消息'
82
+ })
83
+
84
+ /**
85
+ * 整体禁用状态
86
+ */
87
+ const isDisabled = computed(() => props.disabled)
88
+
89
+ /**
90
+ * 处理清除操作
91
+ */
92
+ const handleClear = () => {
93
+ if (!isDisabled.value) {
94
+ emit('clear')
95
+ }
96
+ }
97
+
98
+ /**
99
+ * 切换语音识别状态
100
+ */
101
+ const handleToggleSpeech = () => {
102
+ if (!isDisabled.value) {
103
+ const newState = !props.speechStatus.isRecording
104
+ emit('toggle-speech', newState)
105
+ }
106
+ }
107
+
108
+ /**
109
+ * 处理提交操作
110
+ */
111
+ const handleSubmit = () => {
112
+ if (!isDisabled.value) {
113
+ emit('submit')
114
+ }
115
+ }
116
+ </script>
117
+
118
+ <template>
119
+ <div class="action-buttons">
120
+ <!-- 文件上传按钮 -->
121
+ <template v-if="allowFiles && !loading">
122
+ <tiny-tooltip content="上传文件" placement="top">
123
+ <tiny-button type="text" :disabled="isDisabled">
124
+ <img src="../../assets/icons/accessory.svg" class="button-icon" alt="上传文件" />
125
+ </tiny-button>
126
+ </tiny-tooltip>
127
+ </template>
128
+
129
+ <!-- 语音按钮:仅在启用语音功能时显示 -->
130
+ <template v-if="speechEnabled && !loading">
131
+ <tiny-tooltip :content="speechButtonText" placement="top">
132
+ <tiny-button
133
+ type="text"
134
+ :disabled="isDisabled"
135
+ @click="handleToggleSpeech"
136
+ class="speech-button"
137
+ :class="{ 'is-recording': isSpeechRecording }"
138
+ >
139
+ <img v-if="!isSpeechRecording" src="../../assets/icons/voice.svg" class="button-icon" alt="录音" />
140
+ <img v-else src="../../assets/icons/loading-speech.svg" class="button-icon recording-icon" alt="语音中" />
141
+ </tiny-button>
142
+ </tiny-tooltip>
143
+ </template>
144
+
145
+ <template v-if="showClear">
146
+ <tiny-tooltip content="清空内容" placement="top">
147
+ <tiny-button type="text" :disabled="isDisabled || !hasContent" @click="handleClear" style="margin-left: 0">
148
+ <component :is="TinyIconCloseSquare" class="button-icon" />
149
+ </tiny-button>
150
+ </tiny-tooltip>
151
+ </template>
152
+
153
+ <!-- 提交按钮:主操作按钮 -->
154
+ <template v-if="hasContent || loading">
155
+ <tiny-tooltip :content="submitTooltip" placement="top">
156
+ <tiny-button type="text" @click="handleSubmit" class="submit-button" :disabled="isDisabled">
157
+ <div class="button-content">
158
+ <img v-if="!loading" src="../../assets/icons/send.svg" alt="发送" />
159
+ <img v-else src="../../assets/icons/loading.svg" alt="加载中" class="loading" />
160
+ </div>
161
+ </tiny-button>
162
+ </tiny-tooltip>
163
+ </template>
164
+ </div>
165
+ </template>
@@ -0,0 +1,69 @@
1
+ import { ref, watch } from 'vue'
2
+ import { debounce } from 'lodash-es'
3
+ import type { SenderProps, SenderEmits } from '../index.type'
4
+
5
+ /**
6
+ * 输入框值处理 Hook
7
+ * 对输入框的值进行集中处理
8
+ *
9
+ * @param props 组件属性
10
+ * @param emit 组件方法
11
+ */
12
+ export function useInputHandler(props: SenderProps, emit: SenderEmits) {
13
+ const inputValue = ref(props.defaultValue || '')
14
+ const inputWrapper = ref<HTMLElement | null>(null)
15
+
16
+ // 同步外部值变化
17
+ watch(
18
+ () => props.modelValue,
19
+ (val) => {
20
+ if (val !== undefined && val !== inputValue.value) {
21
+ inputValue.value = val
22
+ }
23
+ },
24
+ )
25
+
26
+ // 双向绑定处理
27
+ const handleChange = (value: string) => {
28
+ inputValue.value = value
29
+ emit('update:modelValue', value)
30
+ }
31
+
32
+ // 防抖提交
33
+ const debouncedSubmit = debounce((value: string) => {
34
+ if (!props.disabled && !props.loading && value.trim()) {
35
+ emit('submit', value)
36
+ }
37
+ }, props.debounceSubmit)
38
+
39
+ // 提交处理
40
+ const handleSubmit = (event?: Event) => {
41
+ event?.preventDefault()
42
+ debouncedSubmit(inputValue.value)
43
+ }
44
+
45
+ // 清空输入
46
+ const handleClear = () => {
47
+ inputValue.value = ''
48
+ emit('update:modelValue', '')
49
+ emit('clear')
50
+ }
51
+
52
+ // 输入法状态
53
+ const isComposing = ref(false)
54
+
55
+ // 清除输入
56
+ const clearInput = () => {
57
+ handleClear()
58
+ }
59
+
60
+ return {
61
+ inputValue,
62
+ inputWrapper,
63
+ isComposing,
64
+ handleChange,
65
+ handleSubmit,
66
+ handleClear,
67
+ clearInput,
68
+ }
69
+ }
@@ -0,0 +1,99 @@
1
+ import { Ref } from 'vue'
2
+ import type { SenderProps, SenderEmits, SpeechState, SubmitTrigger } from '../index.type'
3
+
4
+ /**
5
+ * 键盘处理Hook
6
+ * 集中管理组件的键盘相关操作
7
+ *
8
+ * @param props - 组件属性
9
+ * @param emit - 组件方法
10
+ * @param inputValue - 输入值
11
+ * @param isComposing - 是否处于输入法组合状态(即编辑态)
12
+ * @param speechState - 语音识别状态
13
+ * @param showSuggestions - 是否显示建议列表
14
+ * @param toggleSpeech - 切换语音识别函数
15
+ */
16
+ export function useKeyboardHandler(
17
+ props: SenderProps,
18
+ emit: SenderEmits,
19
+ inputValue: Ref<string>,
20
+ isComposing: Ref<boolean>,
21
+ speechState: SpeechState,
22
+ showSuggestions: Ref<boolean>,
23
+ toggleSpeech: () => void,
24
+ ) {
25
+ /**
26
+ * 验证提交条件
27
+ */
28
+ const validateSubmission = (value: string) => {
29
+ return !props.disabled && !props.loading && value.trim().length > 0
30
+ }
31
+
32
+ /**
33
+ * 触发提交
34
+ */
35
+ const triggerSubmit = () => {
36
+ if (!validateSubmission(inputValue.value)) return
37
+ alert('提交成功')
38
+ emit('submit', inputValue.value.trim())
39
+ }
40
+
41
+ /**
42
+ * 检查是否为指定的提交快捷键
43
+ * @param event 键盘事件
44
+ * @param submitType 提交类型
45
+ */
46
+ const checkSubmitShortcut = (event: KeyboardEvent, submitType: SubmitTrigger): boolean => {
47
+ const isEnter = event.key === 'Enter'
48
+ if (!isEnter) return false
49
+
50
+ switch (submitType) {
51
+ case 'enter':
52
+ console.log('enter')
53
+ return !event.shiftKey && !event.ctrlKey && !event.metaKey
54
+ case 'ctrlEnter':
55
+ console.log('ctrlEnter')
56
+ return (event.ctrlKey || event.metaKey) && !event.shiftKey
57
+ case 'shiftEnter':
58
+ console.log('shiftEnter')
59
+ return event.shiftKey && !event.ctrlKey && !event.metaKey
60
+ default:
61
+ return false
62
+ }
63
+ }
64
+
65
+ /**
66
+ * 处理键盘按下事件
67
+ */
68
+ const handleKeyPress = (event: KeyboardEvent) => {
69
+ if (isComposing.value) return // 阻止输入法状态下的提交
70
+
71
+ // 处理Esc键 - 关闭建议列表或停止语音录制
72
+ if (event.key === 'Escape') {
73
+ if (showSuggestions.value) {
74
+ showSuggestions.value = false
75
+ event.preventDefault()
76
+ } else if (speechState.isRecording) {
77
+ toggleSpeech()
78
+ event.preventDefault()
79
+ }
80
+
81
+ emit('escape-press')
82
+ return
83
+ }
84
+
85
+ // 检查是否匹配当前的提交快捷键
86
+ const shouldSubmit = checkSubmitShortcut(event, props.submitType as SubmitTrigger)
87
+
88
+ // 只有当满足提交条件且输入框有内容时才提交
89
+ if (shouldSubmit && validateSubmission(inputValue.value)) {
90
+ event.preventDefault()
91
+ triggerSubmit()
92
+ }
93
+ }
94
+
95
+ return {
96
+ handleKeyPress,
97
+ triggerSubmit,
98
+ }
99
+ }
@@ -0,0 +1,128 @@
1
+ import { reactive } from 'vue'
2
+ import type { SpeechHookOptions, SpeechHandler, SpeechState } from '../index.type'
3
+
4
+ declare global {
5
+ interface Window {
6
+ webkitSpeechRecognition: typeof SpeechRecognition
7
+ SpeechRecognition: typeof SpeechRecognition
8
+ }
9
+ }
10
+
11
+ /**
12
+ * 语音识别处理 Hook
13
+ * 集中管理语音识别相关逻辑
14
+ *
15
+ * @param options 语音识别配置
16
+ */
17
+
18
+ export function useSpeechHandler(options: SpeechHookOptions): SpeechHandler {
19
+ // 语音识别状态
20
+ const speechState = reactive<SpeechState>({
21
+ isRecording: false,
22
+ isSupported: 'webkitSpeechRecognition' in window || 'SpeechRecognition' in window,
23
+ error: undefined,
24
+ })
25
+
26
+ // 创建语音识别实例
27
+ const recognition = speechState.isSupported
28
+ ? new (window.webkitSpeechRecognition || window.SpeechRecognition)()
29
+ : null
30
+
31
+ // 初始化语音识别配置
32
+ if (recognition) {
33
+ recognition.continuous = options.continuous ?? false
34
+ recognition.interimResults = options.interimResults ?? true
35
+ recognition.lang = options.lang ?? navigator.language
36
+
37
+ // 开始识别事件
38
+ recognition.onstart = () => {
39
+ speechState.isRecording = true
40
+ speechState.error = undefined
41
+ options.onStart?.()
42
+ }
43
+
44
+ // 结束识别事件
45
+ recognition.onend = () => {
46
+ speechState.isRecording = false
47
+ options.onEnd?.()
48
+ }
49
+
50
+ // 中间结果事件
51
+ recognition.onresult = (event: SpeechRecognitionEvent) => {
52
+ const transcript = Array.from(event.results)
53
+ .map((result) => result[0].transcript)
54
+ .join('')
55
+
56
+ if (event.results[0].isFinal) {
57
+ options.onFinal?.(transcript)
58
+ } else {
59
+ options.onInterim?.(transcript)
60
+ }
61
+ }
62
+
63
+ // 错误处理
64
+ recognition.onerror = (event: SpeechRecognitionErrorEvent) => {
65
+ speechState.error = new Error(event.error)
66
+ speechState.isRecording = false
67
+ options.onError?.(speechState.error)
68
+ }
69
+ }
70
+
71
+ // 开始录音
72
+ const start = () => {
73
+ if (!recognition) {
74
+ const error = new Error('浏览器不支持语音识别')
75
+ speechState.error = error
76
+ options.onError?.(error)
77
+ return
78
+ }
79
+
80
+ // 已经在录音中则先停止当前会话
81
+ if (speechState.isRecording) {
82
+ try {
83
+ recognition.stop()
84
+ // 短暂延迟后再开始新的录音会话
85
+ setTimeout(() => {
86
+ try {
87
+ recognition.start()
88
+ } catch (err) {
89
+ handleError(err)
90
+ }
91
+ }, 100)
92
+ } catch (err) {
93
+ handleError(err)
94
+ }
95
+ return
96
+ }
97
+
98
+ try {
99
+ recognition.start()
100
+ } catch (error) {
101
+ handleError(error)
102
+ }
103
+ }
104
+
105
+ // 停止录音
106
+ const stop = () => {
107
+ if (recognition && speechState.isRecording) {
108
+ try {
109
+ recognition.stop()
110
+ } catch (error) {
111
+ handleError(error)
112
+ }
113
+ }
114
+ }
115
+
116
+ // 处理错误
117
+ const handleError = (error: unknown) => {
118
+ speechState.error = error instanceof Error ? error : new Error('语音识别操作失败')
119
+ speechState.isRecording = false
120
+ options.onError?.(speechState.error)
121
+ }
122
+
123
+ return {
124
+ speechState,
125
+ start,
126
+ stop,
127
+ }
128
+ }
@@ -0,0 +1,44 @@
1
+ interface SpeechRecognitionEvent extends Event {
2
+ results: SpeechRecognitionResultList
3
+ resultIndex: number
4
+ emma?: Document
5
+ }
6
+
7
+ interface SpeechRecognitionErrorEvent extends Event {
8
+ error:
9
+ | 'no-speech'
10
+ | 'aborted'
11
+ | 'audio-capture'
12
+ | 'network'
13
+ | 'not-allowed'
14
+ | 'service-not-allowed'
15
+ | 'bad-grammar'
16
+ | 'language-not-supported'
17
+ message: string
18
+ }
19
+
20
+ interface SpeechRecognition extends EventTarget {
21
+ // 属性
22
+ lang: string
23
+ continuous: boolean
24
+ interimResults: boolean
25
+ maxAlternatives: number
26
+ serviceURI: string
27
+
28
+ // 事件处理器
29
+ onend: (this: SpeechRecognition, ev: Event) => void
30
+ onerror: (ev: SpeechRecognitionErrorEvent) => void
31
+ onresult: (this: SpeechRecognition, ev: SpeechRecognitionEvent) => void
32
+ onstart: (this: SpeechRecognition, ev: Event) => void
33
+
34
+ // 方法
35
+ start(): void
36
+ stop(): void
37
+ abort(): void
38
+ }
39
+
40
+ // 声明全局变量
41
+ declare let SpeechRecognition: {
42
+ new (): SpeechRecognition
43
+ prototype: SpeechRecognition
44
+ }