diff --git a/components.d.ts b/components.d.ts
index 6bb0d6b..4015fa9 100644
--- a/components.d.ts
+++ b/components.d.ts
@@ -14,6 +14,7 @@ declare module 'vue' {
AButton: typeof import('ant-design-vue/es')['Button']
RouterLink: typeof import('vue-router')['RouterLink']
RouterView: typeof import('vue-router')['RouterView']
+ StreamMarkdownRender: typeof import('./src/components/StreamMarkdownRender.vue')['default']
SvgIcon: typeof import('./src/components/SvgIcon.vue')['default']
}
}
diff --git a/package.json b/package.json
index 057c4ac..694cfcb 100644
--- a/package.json
+++ b/package.json
@@ -18,6 +18,9 @@
"dependencies": {
"@tailwindcss/vite": "^4.1.15",
"ant-design-vue": "~4.2.6",
+ "highlight.js": "^11.11.1",
+ "markdown-it": "^14.1.0",
+ "markdown-it-highlightjs": "^4.2.0",
"pinia": "^3.0.3",
"tailwindcss": "^4.1.15",
"vue": "^3.5.22",
@@ -25,6 +28,7 @@
},
"devDependencies": {
"@tsconfig/node22": "^22.0.2",
+ "@types/markdown-it": "^14.1.2",
"@types/node": "^22.18.6",
"@vitejs/plugin-vue": "^6.0.1",
"@vue/eslint-config-prettier": "^10.2.0",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 602a1f7..4e9be45 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -14,6 +14,15 @@ importers:
ant-design-vue:
specifier: ~4.2.6
version: 4.2.6(vue@3.5.22(typescript@5.9.3))
+ highlight.js:
+ specifier: ^11.11.1
+ version: 11.11.1
+ markdown-it:
+ specifier: ^14.1.0
+ version: 14.1.0
+ markdown-it-highlightjs:
+ specifier: ^4.2.0
+ version: 4.2.0
pinia:
specifier: ^3.0.3
version: 3.0.3(typescript@5.9.3)(vue@3.5.22(typescript@5.9.3))
@@ -30,6 +39,9 @@ importers:
'@tsconfig/node22':
specifier: ^22.0.2
version: 22.0.2
+ '@types/markdown-it':
+ specifier: ^14.1.2
+ version: 14.1.2
'@types/node':
specifier: ^22.18.6
version: 22.18.12
@@ -710,6 +722,15 @@ packages:
'@types/json-schema@7.0.15':
resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==}
+ '@types/linkify-it@5.0.0':
+ resolution: {integrity: sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==}
+
+ '@types/markdown-it@14.1.2':
+ resolution: {integrity: sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==}
+
+ '@types/mdurl@2.0.0':
+ resolution: {integrity: sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==}
+
'@types/node@22.18.12':
resolution: {integrity: sha512-BICHQ67iqxQGFSzfCFTT7MRQ5XcBjG5aeKh5Ok38UBbPe5fxTyE+aHFxwVrGyr8GNlqFMLKD1D3P2K/1ks8tog==}
@@ -1612,6 +1633,10 @@ packages:
resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==}
hasBin: true
+ highlight.js@11.11.1:
+ resolution: {integrity: sha512-Xwwo44whKBVCYoliBQwaPvtd/2tYFkRQtXDWj1nackaV2JPXx3L0+Jvd8/qCJ2p+ML0/XVkJ2q+Mr+UVdpJK5w==}
+ engines: {node: '>=12.0.0'}
+
hookable@5.5.3:
resolution: {integrity: sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==}
@@ -1968,6 +1993,9 @@ packages:
resolution: {integrity: sha512-utfs7Pr5uJyyvDETitgsaqSyjCb2qNRAtuqUeWIAKztsOYdcACf2KtARYXg2pSvhkt+9NfoaNY7fxjl6nuMjIQ==}
engines: {node: '>= 12.0.0'}
+ linkify-it@5.0.0:
+ resolution: {integrity: sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==}
+
loader-utils@1.4.2:
resolution: {integrity: sha512-I5d00Pd/jwMD2QCduo657+YM/6L3KZu++pmX9VFncxaxvHcru9jx1lBaFft+r4Mt2jK0Yhp41XlRAihzPxHNCg==}
engines: {node: '>=4.0.0'}
@@ -2007,6 +2035,13 @@ packages:
resolution: {integrity: sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w==}
engines: {node: '>=0.10.0'}
+ markdown-it-highlightjs@4.2.0:
+ resolution: {integrity: sha512-NC7pXE8KkOl6xWJVRNt8p6wgJVznXKsE0HgYGdk6DD2tn1l4L9f0ALf3VIoGVkotNU1uGQatSxfBF1zZPUMmuQ==}
+
+ markdown-it@14.1.0:
+ resolution: {integrity: sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==}
+ hasBin: true
+
math-intrinsics@1.1.0:
resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==}
engines: {node: '>= 0.4'}
@@ -2014,6 +2049,9 @@ packages:
mdn-data@2.0.14:
resolution: {integrity: sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==}
+ mdurl@2.0.0:
+ resolution: {integrity: sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==}
+
memorystream@0.3.1:
resolution: {integrity: sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==}
engines: {node: '>= 0.10.0'}
@@ -2270,6 +2308,10 @@ packages:
engines: {node: '>=14'}
hasBin: true
+ punycode.js@2.3.1:
+ resolution: {integrity: sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==}
+ engines: {node: '>=6'}
+
punycode@2.3.1:
resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==}
engines: {node: '>=6'}
@@ -2622,6 +2664,9 @@ packages:
engines: {node: '>=14.17'}
hasBin: true
+ uc.micro@2.1.0:
+ resolution: {integrity: sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==}
+
ufo@1.6.1:
resolution: {integrity: sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==}
@@ -3382,6 +3427,15 @@ snapshots:
'@types/json-schema@7.0.15': {}
+ '@types/linkify-it@5.0.0': {}
+
+ '@types/markdown-it@14.1.2':
+ dependencies:
+ '@types/linkify-it': 5.0.0
+ '@types/mdurl': 2.0.0
+
+ '@types/mdurl@2.0.0': {}
+
'@types/node@22.18.12':
dependencies:
undici-types: 6.21.0
@@ -4508,6 +4562,8 @@ snapshots:
he@1.2.0: {}
+ highlight.js@11.11.1: {}
+
hookable@5.5.3: {}
htmlparser2@3.10.1:
@@ -4814,6 +4870,10 @@ snapshots:
lightningcss-win32-arm64-msvc: 1.30.2
lightningcss-win32-x64-msvc: 1.30.2
+ linkify-it@5.0.0:
+ dependencies:
+ uc.micro: 2.1.0
+
loader-utils@1.4.2:
dependencies:
big.js: 5.2.2
@@ -4854,10 +4914,25 @@ snapshots:
dependencies:
object-visit: 1.0.1
+ markdown-it-highlightjs@4.2.0:
+ dependencies:
+ highlight.js: 11.11.1
+
+ markdown-it@14.1.0:
+ dependencies:
+ argparse: 2.0.1
+ entities: 4.5.0
+ linkify-it: 5.0.0
+ mdurl: 2.0.0
+ punycode.js: 2.3.1
+ uc.micro: 2.1.0
+
math-intrinsics@1.1.0: {}
mdn-data@2.0.14: {}
+ mdurl@2.0.0: {}
+
memorystream@0.3.1: {}
merge-options@1.0.1:
@@ -5129,6 +5204,8 @@ snapshots:
prettier@3.6.2: {}
+ punycode.js@2.3.1: {}
+
punycode@2.3.1: {}
quansync@0.2.11: {}
@@ -5578,6 +5655,8 @@ snapshots:
typescript@5.9.3: {}
+ uc.micro@2.1.0: {}
+
ufo@1.6.1: {}
unbox-primitive@1.1.0:
diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml
index efc037a..3e94409 100644
--- a/pnpm-workspace.yaml
+++ b/pnpm-workspace.yaml
@@ -1,2 +1,3 @@
onlyBuiltDependencies:
+ - core-js
- esbuild
diff --git a/src/components/StreamMarkdownRender.vue b/src/components/StreamMarkdownRender.vue
new file mode 100644
index 0000000..60fd761
--- /dev/null
+++ b/src/components/StreamMarkdownRender.vue
@@ -0,0 +1,426 @@
+
+
+
+
+
+
+
diff --git a/src/components/SvgIcon.vue b/src/components/SvgIcon.vue
index d960704..63dbe35 100644
--- a/src/components/SvgIcon.vue
+++ b/src/components/SvgIcon.vue
@@ -5,7 +5,7 @@