@mujian/js-sdk 0.0.6-beta.2 → 0.0.6-beta.21
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.
- package/dist/index.js +6 -1
- package/dist/react/chat/useChat/inner/chatStreaming.d.ts +1 -0
- package/dist/react/components/MdRenderer/index.d.ts +2 -3
- package/dist/react/components/MdRenderer/utils/height.d.ts +5 -0
- package/dist/react/components/MdRenderer/utils/iframe.d.ts +9 -0
- package/dist/react/components/MdRenderer/utils/scripts.d.ts +4 -0
- package/dist/react.css +51 -55
- package/dist/react.js +213 -12
- package/package.json +2 -1
- /package/dist/react/components/MdRenderer/{utils.d.ts → utils/md.d.ts} +0 -0
package/dist/index.js
CHANGED
|
@@ -113,9 +113,14 @@ class MujianSdk {
|
|
|
113
113
|
pendingRequests = new Map();
|
|
114
114
|
async init() {
|
|
115
115
|
const handshake = new postmate.Model({
|
|
116
|
-
reply: ({ id, complete, data })=>{
|
|
116
|
+
reply: ({ id, complete, data, error })=>{
|
|
117
117
|
const call = this.pendingRequests.get(id);
|
|
118
118
|
if (!call) return;
|
|
119
|
+
if (error) {
|
|
120
|
+
call.reject(error);
|
|
121
|
+
this.pendingRequests.delete(id);
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
119
124
|
call.onData?.(data);
|
|
120
125
|
if (complete) {
|
|
121
126
|
call.onComplete?.();
|
|
@@ -8,6 +8,7 @@ interface ChatStreamingProps {
|
|
|
8
8
|
setMessages: Dispatch<SetStateAction<Message[]>>;
|
|
9
9
|
mujian: MujianSdk;
|
|
10
10
|
}
|
|
11
|
+
export declare const NOT_SAVED_MSG_ID_PREFIX = "not_saved";
|
|
11
12
|
export declare const useChatStreaming: ({ common, setError, setMessages, mujian, }: ChatStreamingProps) => {
|
|
12
13
|
chatStreaming: ({ query, regenerate, is_continue, signal, }: {
|
|
13
14
|
/** 用户输入 */
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export declare const unescapeHTML: (str: string) => string;
|
|
2
|
+
export declare const replaceVhInContent: (content: string) => string;
|
|
3
|
+
/**
|
|
4
|
+
* 转义 HTML 属性值中的引号,防止破坏 HTML 属性
|
|
5
|
+
* @param value 需要转义的属性值
|
|
6
|
+
* @returns 转义后的值
|
|
7
|
+
*/
|
|
8
|
+
export declare function escapeHtmlAttribute(value: string): string;
|
|
9
|
+
export declare function createSrcContent(content: string): string;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export declare const iframeDOMLoaded = "\n(function () {\n function emit_loaded_event() {\n window.parent.postMessage({ type: 'MJ_DOM_CONTENT_LOADED', iframeId: '123' }, '*');\n }\n\n if (window.document.readyState === 'loading') {\n window.document.addEventListener('DOMContentLoaded', emit_loaded_event, { once: true });\n } else {\n emit_loaded_event();\n }\n})();\n";
|
|
2
|
+
export declare const iframeAdjustViewport: string;
|
|
3
|
+
export declare const init = "\n(async function () {\n\nwindow.$mujian2 = window.parent.$mujian;\nconst result = await $mujian2?.ai.chat.project.getInfo();\nconsole.log('result', result);\n\n})();\n";
|
|
4
|
+
export declare const thirdParty = "\n<script src=\"https://cdn.jsdmirror.com/npm/@fortawesome/fontawesome-free/js/all.min.js\"></script>\n<script src=\"https://cdn.jsdmirror.com/npm/@tailwindcss/browser/dist/index.global.min.js\"></script>\n<script src=\"https://cdn.jsdmirror.com/npm/jquery/dist/jquery.min.js\"></script>\n<script src=\"https://cdn.jsdmirror.com/npm/jquery-ui/dist/jquery-ui.min.js\"></script>\n<link rel=\"stylesheet\" href=\"https://cdn.jsdmirror.com/npm/jquery-ui/themes/base/theme.min.css\" />\n<script src=\"https://cdn.jsdmirror.com/npm/jquery-ui-touch-punch\"></script>\n";
|
package/dist/react.css
CHANGED
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
--SmartThemeBodyColor: #abc6df;
|
|
43
43
|
--SmartThemeEmColor: #fff;
|
|
44
44
|
--SmartThemeUnderlineColor: #bce7cf;
|
|
45
|
-
--SmartThemeQuoteColor: #
|
|
45
|
+
--SmartThemeQuoteColor: #b983ff;
|
|
46
46
|
--SmartThemeBlurTintColor: #171717;
|
|
47
47
|
--SmartThemeChatTintColor: #171717;
|
|
48
48
|
--SmartThemeUserMesBlurTintColor: #0000004d;
|
|
@@ -89,76 +89,72 @@
|
|
|
89
89
|
-moz-osx-font-smoothing: grayscale;
|
|
90
90
|
}
|
|
91
91
|
|
|
92
|
-
|
|
93
|
-
-
|
|
94
|
-
-
|
|
95
|
-
-webkit-transform: translateZ(0);
|
|
92
|
+
.spin-overlay {
|
|
93
|
+
background-color: #000;
|
|
94
|
+
animation: 3s ease-in-out infinite breath;
|
|
96
95
|
}
|
|
97
96
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
padding: 0;
|
|
97
|
+
@keyframes breath {
|
|
98
|
+
0% {
|
|
99
|
+
background-color: #0009;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
50% {
|
|
103
|
+
background-color: #00000080;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
100% {
|
|
107
|
+
background-color: #0009;
|
|
108
|
+
}
|
|
111
109
|
}
|
|
112
110
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
111
|
+
.wave-text span {
|
|
112
|
+
font-family: var(--mainFontFamily);
|
|
113
|
+
animation: 2s ease-in-out infinite wave;
|
|
114
|
+
display: inline-block;
|
|
116
115
|
}
|
|
117
116
|
|
|
118
|
-
|
|
119
|
-
|
|
117
|
+
.wave-text span:first-child {
|
|
118
|
+
animation-delay: 0s;
|
|
120
119
|
}
|
|
121
120
|
|
|
122
|
-
|
|
123
|
-
|
|
121
|
+
.wave-text span:nth-child(2) {
|
|
122
|
+
animation-delay: .2s;
|
|
124
123
|
}
|
|
125
124
|
|
|
126
|
-
|
|
127
|
-
|
|
125
|
+
.wave-text span:nth-child(3) {
|
|
126
|
+
animation-delay: .4s;
|
|
128
127
|
}
|
|
129
128
|
|
|
130
|
-
|
|
131
|
-
|
|
129
|
+
.wave-text span:nth-child(4) {
|
|
130
|
+
animation-delay: .6s;
|
|
132
131
|
}
|
|
133
132
|
|
|
134
|
-
.
|
|
135
|
-
|
|
133
|
+
.wave-text span:nth-child(5) {
|
|
134
|
+
animation-delay: .8s;
|
|
136
135
|
}
|
|
137
136
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
box-shadow: inset 0 0 0 1px var(--black50a);
|
|
141
|
-
background-clip: content-box;
|
|
142
|
-
border: 2px solid #0000;
|
|
143
|
-
border-radius: 10px;
|
|
144
|
-
min-height: 40px;
|
|
137
|
+
.wave-text span:nth-child(6) {
|
|
138
|
+
animation-delay: 1s;
|
|
145
139
|
}
|
|
146
140
|
|
|
147
|
-
|
|
148
|
-
|
|
141
|
+
.wave-text span:nth-child(7) {
|
|
142
|
+
animation-delay: 1.2s;
|
|
149
143
|
}
|
|
150
144
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
145
|
+
@keyframes wave {
|
|
146
|
+
0%, 100% {
|
|
147
|
+
transform: translateY(0);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
50% {
|
|
151
|
+
transform: translateY(-8px);
|
|
152
|
+
}
|
|
158
153
|
}
|
|
159
154
|
|
|
160
|
-
|
|
161
|
-
|
|
155
|
+
body {
|
|
156
|
+
font-size: var(--mainFontSize);
|
|
157
|
+
color: var(--SmartThemeBodyColor);
|
|
162
158
|
}
|
|
163
159
|
|
|
164
160
|
.mes_text table, .mes_reasoning table {
|
|
@@ -217,8 +213,10 @@ body.movingUI ::-webkit-scrollbar-thumb:vertical {
|
|
|
217
213
|
margin-bottom: 16px;
|
|
218
214
|
}
|
|
219
215
|
|
|
220
|
-
.mes_text {
|
|
221
|
-
|
|
216
|
+
.mes_text, .mes_reasoning {
|
|
217
|
+
line-height: calc(var(--mainFontSize) + .5rem);
|
|
218
|
+
overflow-wrap: anywhere;
|
|
219
|
+
max-width: 100%;
|
|
222
220
|
}
|
|
223
221
|
|
|
224
222
|
.mes_text p:only-child, .mes_text p:only-of-type {
|
|
@@ -229,7 +227,7 @@ body.movingUI ::-webkit-scrollbar-thumb:vertical {
|
|
|
229
227
|
unicode-bidi: isolate;
|
|
230
228
|
margin-block: 1em;
|
|
231
229
|
margin-inline: 0;
|
|
232
|
-
padding-inline-start:
|
|
230
|
+
padding-inline-start: 24px;
|
|
233
231
|
list-style-type: decimal;
|
|
234
232
|
display: block;
|
|
235
233
|
}
|
|
@@ -326,11 +324,9 @@ body.movingUI ::-webkit-scrollbar-thumb:vertical {
|
|
|
326
324
|
code {
|
|
327
325
|
font-family: var(--monoFontFamily);
|
|
328
326
|
white-space: pre-wrap;
|
|
329
|
-
border: 1px solid var(--SmartThemeBorderColor);
|
|
330
|
-
background-color: var(--black70a);
|
|
331
327
|
line-height: var(--mainFontSize);
|
|
332
328
|
color: var(--white70a);
|
|
333
|
-
border
|
|
329
|
+
border: 1px solid #fff;
|
|
334
330
|
padding: 0 3px;
|
|
335
331
|
}
|
|
336
332
|
|
package/dist/react.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { useMount, useRequest, useUpdateEffect } from "ahooks";
|
|
2
|
-
import react, { createContext, forwardRef, useCallback, useContext, useEffect, useState } from "react";
|
|
2
|
+
import react, { createContext, forwardRef, useCallback, useContext, useEffect, useRef, useState } from "react";
|
|
3
3
|
import { jsx } from "react/jsx-runtime";
|
|
4
4
|
import css_tools from "@adobe/css-tools";
|
|
5
5
|
import dompurify from "dompurify";
|
|
6
6
|
import showdown from "showdown";
|
|
7
|
+
import { v4 } from "uuid";
|
|
7
8
|
import postmate from "postmate";
|
|
8
9
|
import { Virtualizer } from "virtua";
|
|
9
10
|
addDOMPurifyHooks();
|
|
@@ -234,18 +235,208 @@ function messageFormatting(mes, sanitizerOverrides = {}) {
|
|
|
234
235
|
});
|
|
235
236
|
return mes;
|
|
236
237
|
}
|
|
238
|
+
window.parent.innerHeight, window.parent.innerHeight;
|
|
239
|
+
const init = `
|
|
240
|
+
(async function () {
|
|
241
|
+
|
|
242
|
+
window.$mujian2 = window.parent.$mujian;
|
|
243
|
+
const result = await $mujian2?.ai.chat.project.getInfo();
|
|
244
|
+
console.log('result', result);
|
|
245
|
+
|
|
246
|
+
})();
|
|
247
|
+
`;
|
|
248
|
+
const thirdParty = `
|
|
249
|
+
<script src="https://cdn.jsdmirror.com/npm/@fortawesome/fontawesome-free/js/all.min.js"></script>
|
|
250
|
+
<script src="https://cdn.jsdmirror.com/npm/@tailwindcss/browser/dist/index.global.min.js"></script>
|
|
251
|
+
<script src="https://cdn.jsdmirror.com/npm/jquery/dist/jquery.min.js"></script>
|
|
252
|
+
<script src="https://cdn.jsdmirror.com/npm/jquery-ui/dist/jquery-ui.min.js"></script>
|
|
253
|
+
<link rel="stylesheet" href="https://cdn.jsdmirror.com/npm/jquery-ui/themes/base/theme.min.css" />
|
|
254
|
+
<script src="https://cdn.jsdmirror.com/npm/jquery-ui-touch-punch"></script>
|
|
255
|
+
`;
|
|
256
|
+
const unescapeHTML = (str)=>{
|
|
257
|
+
const named = {
|
|
258
|
+
amp: "&",
|
|
259
|
+
lt: "<",
|
|
260
|
+
gt: ">",
|
|
261
|
+
quot: '"',
|
|
262
|
+
apos: "'",
|
|
263
|
+
nbsp: "\u00A0"
|
|
264
|
+
};
|
|
265
|
+
return str.replace(/&(#x?[0-9a-fA-F]+|[a-zA-Z]+);/g, (_m, body)=>{
|
|
266
|
+
if ("#" === body[0]) {
|
|
267
|
+
const isHex = body[1]?.toLowerCase() === "x";
|
|
268
|
+
const numStr = isHex ? body.slice(2) : body.slice(1);
|
|
269
|
+
const codePoint = parseInt(numStr, isHex ? 16 : 10);
|
|
270
|
+
if (Number.isFinite(codePoint)) try {
|
|
271
|
+
return String.fromCodePoint(codePoint);
|
|
272
|
+
} catch {}
|
|
273
|
+
return _m;
|
|
274
|
+
}
|
|
275
|
+
const lower = body.toLowerCase();
|
|
276
|
+
return Object.hasOwn(named, lower) ? named[lower] : _m;
|
|
277
|
+
});
|
|
278
|
+
};
|
|
279
|
+
const replaceVhInContent = (content)=>{
|
|
280
|
+
const has_css_min_vh = /min-height\s*:\s*[^;{}]*\d+(?:\.\d+)?vh/gi.test(content);
|
|
281
|
+
const has_inline_style_vh = /style\s*=\s*(["'])[\s\S]*?min-height\s*:\s*[^;]*?\d+(?:\.\d+)?vh[\s\S]*?\1/gi.test(content);
|
|
282
|
+
const has_js_vh = /(\.style\.minHeight\s*=\s*(["']))([\s\S]*?vh)(\2)/gi.test(content) || /(setProperty\s*\(\s*(["'])min-height\2\s*,\s*(["']))([\s\S]*?vh)(\3\s*\))/gi.test(content);
|
|
283
|
+
if (!has_css_min_vh && !has_inline_style_vh && !has_js_vh) return content;
|
|
284
|
+
const convertVhToVariable = (value)=>value.replace(/(\d+(?:\.\d+)?)vh\b/gi, (match, value)=>{
|
|
285
|
+
const parsed = parseFloat(value);
|
|
286
|
+
if (!isFinite(parsed)) return match;
|
|
287
|
+
const VARIABLE_EXPRESSION = "var(--MJ-iframe-height)";
|
|
288
|
+
if (100 === parsed) return VARIABLE_EXPRESSION;
|
|
289
|
+
return `calc(${VARIABLE_EXPRESSION} * ${parsed / 100})`;
|
|
290
|
+
});
|
|
291
|
+
content = content.replace(/(min-height\s*:\s*)([^;{}]*?\d+(?:\.\d+)?vh)(?=\s*[;}])/gi, (_m, prefix, value)=>`${prefix}${convertVhToVariable(value)}`);
|
|
292
|
+
content = content.replace(/(style\s*=\s*(["']))([^"'"]*?)(\2)/gi, (match, prefix, _quote, styleContent, suffix)=>{
|
|
293
|
+
if (!/min-height\s*:\s*[^;]*vh/i.test(styleContent)) return match;
|
|
294
|
+
const replaced = styleContent.replace(/(min-height\s*:\s*)([^;]*?\d+(?:\.\d+)?vh)/gi, (_m, p1, p2)=>`${p1}${convertVhToVariable(p2)}`);
|
|
295
|
+
return `${prefix}${replaced}${suffix}`;
|
|
296
|
+
});
|
|
297
|
+
content = content.replace(/(\.style\.minHeight\s*=\s*(["']))([\s\S]*?)(\2)/gi, (match, prefix, _q, val, suffix)=>{
|
|
298
|
+
if (!/\b\d+(?:\.\d+)?vh\b/i.test(val)) return match;
|
|
299
|
+
const converted = convertVhToVariable(val);
|
|
300
|
+
return `${prefix}${converted}${suffix}`;
|
|
301
|
+
});
|
|
302
|
+
content = content.replace(/(setProperty\s*\(\s*(["'])min-height\2\s*,\s*(["']))([\s\S]*?)(\3\s*\))/gi, (match, prefix, _q1, _q2, val, suffix)=>{
|
|
303
|
+
if (!/\b\d+(?:\.\d+)?vh\b/i.test(val)) return match;
|
|
304
|
+
const converted = convertVhToVariable(val);
|
|
305
|
+
return `${prefix}${converted}${suffix}`;
|
|
306
|
+
});
|
|
307
|
+
return content;
|
|
308
|
+
};
|
|
309
|
+
function escapeHtmlAttribute(value) {
|
|
310
|
+
return value.replace(/"/g, """).replace(/'/g, "'");
|
|
311
|
+
}
|
|
312
|
+
function createSrcContent(content) {
|
|
313
|
+
content = replaceVhInContent(content);
|
|
314
|
+
const getUserAvatarPath = ()=>"https://www.mujian.com/avatar.png";
|
|
315
|
+
const getCharAvatarPath = ()=>"https://www.mujian.com/avatar.png";
|
|
316
|
+
return `
|
|
317
|
+
<html>
|
|
318
|
+
<head>
|
|
319
|
+
<style>
|
|
320
|
+
|
|
321
|
+
html,body{margin:0;padding:0;overflow:hidden!important;max-width:100%!important;box-sizing:border-box}
|
|
322
|
+
.user_avatar,.user-avatar{background-image:url('${getUserAvatarPath()}')}
|
|
323
|
+
.char_avatar,.char-avatar{background-image:url('${getCharAvatarPath()}')}
|
|
324
|
+
|
|
325
|
+
</style>
|
|
326
|
+
${thirdParty}
|
|
327
|
+
<script>
|
|
328
|
+
${init}
|
|
329
|
+
</script>
|
|
330
|
+
</head>
|
|
331
|
+
<body>
|
|
332
|
+
${content}
|
|
333
|
+
</body>
|
|
334
|
+
</html>
|
|
335
|
+
`;
|
|
336
|
+
}
|
|
337
|
+
function adjustIframeHeight(iframe) {
|
|
338
|
+
if (!iframe.contentWindow) return;
|
|
339
|
+
const document1 = iframe.contentWindow.document;
|
|
340
|
+
const height = Math.max(document1.body.offsetHeight, document1.documentElement.offsetHeight);
|
|
341
|
+
if (!Number.isFinite(height) || height <= 0) return;
|
|
342
|
+
iframe.style.height = `${height}px`;
|
|
343
|
+
}
|
|
344
|
+
const observed_elements = new Map();
|
|
345
|
+
const observer = new ResizeObserver((entries)=>{
|
|
346
|
+
for (const entry of entries){
|
|
347
|
+
const element = entry.target;
|
|
348
|
+
const iframe = observed_elements.get(element);
|
|
349
|
+
if (iframe) adjustIframeHeight(iframe);
|
|
350
|
+
}
|
|
351
|
+
});
|
|
352
|
+
function useHeightObserver() {
|
|
353
|
+
return {
|
|
354
|
+
observe: (iframe)=>{
|
|
355
|
+
if (!iframe?.contentWindow?.document?.body) return;
|
|
356
|
+
const body = iframe.contentWindow.document.body;
|
|
357
|
+
observed_elements.set(body, iframe);
|
|
358
|
+
observer.observe(body);
|
|
359
|
+
adjustIframeHeight(iframe);
|
|
360
|
+
},
|
|
361
|
+
unobserve: (iframe)=>{
|
|
362
|
+
if (!iframe.contentWindow?.document?.body) return;
|
|
363
|
+
const body = iframe.contentWindow.document.body;
|
|
364
|
+
observed_elements.delete(body);
|
|
365
|
+
observer.unobserve(body);
|
|
366
|
+
}
|
|
367
|
+
};
|
|
368
|
+
}
|
|
237
369
|
const MdRendererBase = ({ content })=>{
|
|
238
|
-
const
|
|
370
|
+
const containerRef = useRef(null);
|
|
371
|
+
const [iframeIdList, setIframeIdList] = useState([]);
|
|
372
|
+
const { observe, unobserve } = useHeightObserver();
|
|
373
|
+
useEffect(()=>{
|
|
374
|
+
let mes = messageFormatting(content);
|
|
375
|
+
mes = mes.replace(/<pre><code(.*)>[\s\S]*?<\/code><\/pre>/g, (match)=>{
|
|
376
|
+
if (!match.includes("<body>") && !match.includes("</body>")) return match;
|
|
377
|
+
const code = match.replace("<pre><code>", "").replace("</code></pre>", "");
|
|
378
|
+
const srcdoc = createSrcContent(unescapeHTML(code));
|
|
379
|
+
const id = v4();
|
|
380
|
+
setIframeIdList((prev)=>[
|
|
381
|
+
...prev,
|
|
382
|
+
id
|
|
383
|
+
]);
|
|
384
|
+
const escapedSrcdoc = escapeHtmlAttribute(srcdoc);
|
|
385
|
+
return `
|
|
386
|
+
<div class="MJ-iframe-container" id="MJ-iframe-container-${id}" style="display:flex;width:100%;height:100%;position:relative;">
|
|
387
|
+
<div class="spin-overlay" id="MJ-spin-${id}" style="width:100%;height:100%;position:absolute;top:0;left:0;z-index:1000;background-color:rgba(0,0,0,0.5);display:flex;justify-content:center;align-items:center;">
|
|
388
|
+
<div class="spin-inner wave-text" style="font-weight:500;font-size:16px;color:white;display:flex;justify-content:center;align-items:center;">
|
|
389
|
+
<span>加</span>
|
|
390
|
+
<span>载</span>
|
|
391
|
+
<span>中</span>
|
|
392
|
+
<span>.</span>
|
|
393
|
+
<span>.</span>
|
|
394
|
+
<span>.</span>
|
|
395
|
+
</div>
|
|
396
|
+
</div>
|
|
397
|
+
<iframe id="MJ-iframe-${id}" sandbox="allow-scripts allow-same-origin" loading="lazy" referrerpolicy="no-referrer" style="width:100%;height:100%;border:none;" srcdoc="` + escapedSrcdoc + `"></iframe>
|
|
398
|
+
</div>
|
|
399
|
+
`;
|
|
400
|
+
});
|
|
401
|
+
if (containerRef.current) containerRef.current.innerHTML = mes;
|
|
402
|
+
}, [
|
|
403
|
+
content
|
|
404
|
+
]);
|
|
405
|
+
useEffect(()=>{
|
|
406
|
+
iframeIdList.forEach((id)=>{
|
|
407
|
+
const iframe = document.getElementById("MJ-iframe-" + id);
|
|
408
|
+
if (!iframe) return;
|
|
409
|
+
iframe.addEventListener("load", ()=>{
|
|
410
|
+
observe(iframe);
|
|
411
|
+
const spinElement = iframe.parentElement?.querySelector("#MJ-spin-" + id);
|
|
412
|
+
if (spinElement) spinElement.remove();
|
|
413
|
+
});
|
|
414
|
+
});
|
|
415
|
+
return ()=>{
|
|
416
|
+
iframeIdList.forEach((id)=>{
|
|
417
|
+
const iframe = document.getElementById("MJ-iframe-" + id);
|
|
418
|
+
if (!iframe) return;
|
|
419
|
+
unobserve(iframe);
|
|
420
|
+
const spinElement = iframe.parentElement?.querySelector("#MJ-spin-" + iframe.id);
|
|
421
|
+
if (spinElement) spinElement.remove();
|
|
422
|
+
iframe.removeEventListener("load", ()=>{
|
|
423
|
+
console.log("iframe loaded", iframe.id);
|
|
424
|
+
});
|
|
425
|
+
});
|
|
426
|
+
};
|
|
427
|
+
}, [
|
|
428
|
+
iframeIdList,
|
|
429
|
+
observe,
|
|
430
|
+
unobserve
|
|
431
|
+
]);
|
|
239
432
|
return /*#__PURE__*/ jsx("div", {
|
|
240
433
|
className: "mes_text",
|
|
241
|
-
|
|
242
|
-
__html: mes
|
|
243
|
-
}
|
|
434
|
+
ref: containerRef
|
|
244
435
|
});
|
|
245
436
|
};
|
|
246
437
|
const MdRenderer = /*#__PURE__*/ react.memo(MdRendererBase, (prev, next)=>prev.content === next.content);
|
|
247
|
-
MdRendererBase.displayName =
|
|
248
|
-
MdRenderer.displayName =
|
|
438
|
+
MdRendererBase.displayName = "MdRenderer";
|
|
439
|
+
MdRenderer.displayName = "MdRenderer";
|
|
249
440
|
const chat_complete = async function(message, onData, signal) {
|
|
250
441
|
return await this.call("mujian:ai:chat:complete", {
|
|
251
442
|
content: message
|
|
@@ -341,9 +532,14 @@ class MujianSdk {
|
|
|
341
532
|
pendingRequests = new Map();
|
|
342
533
|
async init() {
|
|
343
534
|
const handshake = new postmate.Model({
|
|
344
|
-
reply: ({ id, complete, data })=>{
|
|
535
|
+
reply: ({ id, complete, data, error })=>{
|
|
345
536
|
const call = this.pendingRequests.get(id);
|
|
346
537
|
if (!call) return;
|
|
538
|
+
if (error) {
|
|
539
|
+
call.reject(error);
|
|
540
|
+
this.pendingRequests.delete(id);
|
|
541
|
+
return;
|
|
542
|
+
}
|
|
347
543
|
call.onData?.(data);
|
|
348
544
|
if (complete) {
|
|
349
545
|
call.onComplete?.();
|
|
@@ -574,6 +770,7 @@ async function* callSdk(mujian, content, type = 'generate', signal) {
|
|
|
574
770
|
resolveWait = resolve;
|
|
575
771
|
});
|
|
576
772
|
}
|
|
773
|
+
const NOT_SAVED_MSG_ID_PREFIX = 'not_saved';
|
|
577
774
|
const useChatStreaming = ({ common, setError, setMessages, mujian })=>{
|
|
578
775
|
const { body } = common;
|
|
579
776
|
const [isStreaming, setIsStreaming] = useState(false);
|
|
@@ -582,7 +779,7 @@ const useChatStreaming = ({ common, setError, setMessages, mujian })=>{
|
|
|
582
779
|
setError(void 0);
|
|
583
780
|
setIsStreaming(true);
|
|
584
781
|
const userMessage = {
|
|
585
|
-
id: Date.now()
|
|
782
|
+
id: `${NOT_SAVED_MSG_ID_PREFIX}_user_${Date.now()}`,
|
|
586
783
|
content: query || '',
|
|
587
784
|
role: 'user',
|
|
588
785
|
swipes: [],
|
|
@@ -591,7 +788,7 @@ const useChatStreaming = ({ common, setError, setMessages, mujian })=>{
|
|
|
591
788
|
sendAt: new Date()
|
|
592
789
|
};
|
|
593
790
|
const aiMessage = {
|
|
594
|
-
id: Date.now()
|
|
791
|
+
id: `${NOT_SAVED_MSG_ID_PREFIX}_assistant_${Date.now()}`,
|
|
595
792
|
content: '',
|
|
596
793
|
role: 'assistant',
|
|
597
794
|
swipes: [],
|
|
@@ -636,7 +833,7 @@ const useChatStreaming = ({ common, setError, setMessages, mujian })=>{
|
|
|
636
833
|
const data = line.slice(6);
|
|
637
834
|
try {
|
|
638
835
|
const parsedData = JSON.parse(data);
|
|
639
|
-
if (!regenerate && parsedData.
|
|
836
|
+
if (!regenerate && parsedData.reply_id) {
|
|
640
837
|
const { question_id, reply_id } = parsedData;
|
|
641
838
|
setMessages((prev)=>{
|
|
642
839
|
const newMessages = [
|
|
@@ -803,7 +1000,11 @@ const useChat = ({ body, onError, onFinish })=>{
|
|
|
803
1000
|
setMessages((prev)=>prev.map((msg)=>msg.id === messageId ? patchMessage(msg) : msg));
|
|
804
1001
|
};
|
|
805
1002
|
const deleteMessage = async (messageId)=>{
|
|
806
|
-
|
|
1003
|
+
if (!messageId.startsWith(NOT_SAVED_MSG_ID_PREFIX)) try {
|
|
1004
|
+
await mujian.ai.chat.message.deleteOne(messageId);
|
|
1005
|
+
} catch (e) {
|
|
1006
|
+
if (e?.code !== 2011030004) throw e;
|
|
1007
|
+
}
|
|
807
1008
|
setMessages((prev)=>prev.filter((msg)=>msg.id !== messageId));
|
|
808
1009
|
};
|
|
809
1010
|
return {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mujian/js-sdk",
|
|
3
|
-
"version": "0.0.6-beta.
|
|
3
|
+
"version": "0.0.6-beta.21",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": {
|
|
@@ -76,6 +76,7 @@
|
|
|
76
76
|
},
|
|
77
77
|
"dependencies": {
|
|
78
78
|
"dompurify": "^3.2.6",
|
|
79
|
+
"uuid": "^13.0.0",
|
|
79
80
|
"@adobe/css-tools": "^4.4.4",
|
|
80
81
|
"showdown": "^2.1.0",
|
|
81
82
|
"postmate": "^1.5.2",
|
|
File without changes
|