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 @@