@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 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
  /** 用户输入 */
@@ -1,6 +1,5 @@
1
- /** biome-ignore-all lint/security/noDangerouslySetInnerHtml: <explanation> */
2
- import React from 'react';
3
- import './MdTheme.css';
1
+ import React from "react";
2
+ import "./MdTheme.css";
4
3
  export type MdRendererProps = {
5
4
  /**
6
5
  * The markdown content to render
@@ -0,0 +1,5 @@
1
+ export declare function adjustIframeHeight(iframe: HTMLIFrameElement): void;
2
+ export declare function useHeightObserver(): {
3
+ observe: (iframe: HTMLIFrameElement) => void;
4
+ unobserve: (iframe: HTMLIFrameElement) => void;
5
+ };
@@ -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: #6f85fd;
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
- html {
93
- -webkit-backface-visibility: hidden;
94
- -webkit-perspective: 1000px;
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
- body {
99
- background-color: var(--SmartThemeBlurTintColor);
100
- width: 100%;
101
- height: 100dvh;
102
- font-family: var(--mainFontFamily);
103
- font-size: var(--mainFontSize);
104
- color: var(--SmartThemeBodyColor);
105
- color-scheme: light only;
106
- background-repeat: no-repeat;
107
- background-size: cover;
108
- background-attachment: fixed;
109
- margin: 0;
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
- ::-webkit-scrollbar {
114
- scrollbar-gutter: stable;
115
- width: .7rem;
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
- ::-webkit-scrollbar-track {
119
- cursor: default;
117
+ .wave-text span:first-child {
118
+ animation-delay: 0s;
120
119
  }
121
120
 
122
- ::-webkit-scrollbar-track:hover {
123
- background-color: #7e7e7e33;
121
+ .wave-text span:nth-child(2) {
122
+ animation-delay: .2s;
124
123
  }
125
124
 
126
- ::-webkit-scrollbar-thumb {
127
- cursor: grab;
125
+ .wave-text span:nth-child(3) {
126
+ animation-delay: .4s;
128
127
  }
129
128
 
130
- ::-webkit-scrollbar-thumb:active {
131
- cursor: grabbing;
129
+ .wave-text span:nth-child(4) {
130
+ animation-delay: .6s;
132
131
  }
133
132
 
134
- .scrollY {
135
- overflow-y: auto !important;
133
+ .wave-text span:nth-child(5) {
134
+ animation-delay: .8s;
136
135
  }
137
136
 
138
- ::-webkit-scrollbar-thumb:vertical {
139
- background-color: var(--grey7070a);
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
- body.movingUI ::-webkit-scrollbar-thumb:vertical {
148
- border-top: 20px solid #0000;
141
+ .wave-text span:nth-child(7) {
142
+ animation-delay: 1.2s;
149
143
  }
150
144
 
151
- ::-webkit-scrollbar-thumb:horizontal {
152
- background-color: var(--grey7070a);
153
- box-shadow: inset 0 0 0 1px var(--black50a);
154
- background-clip: content-box;
155
- border: 2px solid #0000;
156
- border-radius: 10px;
157
- min-width: 40px;
145
+ @keyframes wave {
146
+ 0%, 100% {
147
+ transform: translateY(0);
148
+ }
149
+
150
+ 50% {
151
+ transform: translateY(-8px);
152
+ }
158
153
  }
159
154
 
160
- ::-webkit-scrollbar-corner {
161
- background-color: #0000;
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
- color: var(--SmartThemeBodyColor);
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: 40px;
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-radius: 5px;
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, "&quot;").replace(/'/g, "&#39;");
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 mes = messageFormatting(content);
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("&lt;body&gt;") && !match.includes("&lt;/body&gt;")) 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
- dangerouslySetInnerHTML: {
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 = 'MdRenderer';
248
- MdRenderer.displayName = 'MdRenderer';
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().toString(),
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().toString() + '1',
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.question_id) {
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
- await mujian.ai.chat.message.deleteOne(messageId);
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.2",
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",