@will1123/lx-ui-utils 1.0.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.
@@ -0,0 +1,622 @@
1
+ (function(global, factory) {
2
+ typeof exports === "object" && typeof module !== "undefined" ? factory(exports) : typeof define === "function" && define.amd ? define(["exports"], factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self, factory(global.LxUIUtils = {}));
3
+ })(this, function(exports2) {
4
+ "use strict";var __defProp = Object.defineProperty;
5
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
8
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
9
+ var __spreadValues = (a, b) => {
10
+ for (var prop in b || (b = {}))
11
+ if (__hasOwnProp.call(b, prop))
12
+ __defNormalProp(a, prop, b[prop]);
13
+ if (__getOwnPropSymbols)
14
+ for (var prop of __getOwnPropSymbols(b)) {
15
+ if (__propIsEnum.call(b, prop))
16
+ __defNormalProp(a, prop, b[prop]);
17
+ }
18
+ return a;
19
+ };
20
+ var __async = (__this, __arguments, generator) => {
21
+ return new Promise((resolve, reject) => {
22
+ var fulfilled = (value) => {
23
+ try {
24
+ step(generator.next(value));
25
+ } catch (e) {
26
+ reject(e);
27
+ }
28
+ };
29
+ var rejected = (value) => {
30
+ try {
31
+ step(generator.throw(value));
32
+ } catch (e) {
33
+ reject(e);
34
+ }
35
+ };
36
+ var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
37
+ step((generator = generator.apply(__this, __arguments)).next());
38
+ });
39
+ };
40
+
41
+ class SSEConnection {
42
+ constructor() {
43
+ this.controller = null;
44
+ this.eventSource = null;
45
+ this.timeoutTimer = null;
46
+ }
47
+ /**
48
+ * 发起 SSE 请求
49
+ */
50
+ request(config, handlers) {
51
+ return __async(this, null, function* () {
52
+ var _a, _b, _c, _d, _e;
53
+ const { url, method = "GET", headers = {}, body, timeout = 3e4 } = config;
54
+ this.controller = new AbortController();
55
+ try {
56
+ if (timeout > 0) {
57
+ this.timeoutTimer = setTimeout(() => {
58
+ var _a2;
59
+ this.close();
60
+ (_a2 = handlers.onError) == null ? void 0 : _a2.call(handlers, new Error(`Request timeout after ${timeout}ms`));
61
+ }, timeout);
62
+ }
63
+ const response = yield fetch(url, {
64
+ method,
65
+ headers: __spreadValues({
66
+ "Content-Type": "application/json"
67
+ }, headers),
68
+ body: method === "POST" ? JSON.stringify(body) : void 0,
69
+ signal: this.controller.signal
70
+ });
71
+ if (this.timeoutTimer) {
72
+ clearTimeout(this.timeoutTimer);
73
+ this.timeoutTimer = null;
74
+ }
75
+ if (!response.ok) {
76
+ throw new Error(`HTTP error! status: ${response.status}`);
77
+ }
78
+ const contentType = response.headers.get("content-type");
79
+ if (!(contentType == null ? void 0 : contentType.includes("text/event-stream"))) {
80
+ throw new Error("Response is not a Server-Sent Events stream");
81
+ }
82
+ (_a = handlers.onOpen) == null ? void 0 : _a.call(handlers);
83
+ const reader = (_b = response.body) == null ? void 0 : _b.getReader();
84
+ const decoder = new TextDecoder();
85
+ let buffer = "";
86
+ if (!reader) {
87
+ throw new Error("Response body is null");
88
+ }
89
+ while (true) {
90
+ const { done, value } = yield reader.read();
91
+ if (done) {
92
+ (_c = handlers.onClose) == null ? void 0 : _c.call(handlers);
93
+ break;
94
+ }
95
+ buffer += decoder.decode(value, { stream: true });
96
+ const lines = buffer.split("\n\n");
97
+ buffer = lines.pop() || "";
98
+ for (const line of lines) {
99
+ if (line.trim()) {
100
+ const message = this.parseMessage(line);
101
+ (_d = handlers.onMessage) == null ? void 0 : _d.call(handlers, message);
102
+ }
103
+ }
104
+ }
105
+ } catch (error) {
106
+ if (this.timeoutTimer) {
107
+ clearTimeout(this.timeoutTimer);
108
+ this.timeoutTimer = null;
109
+ }
110
+ if (this.controller && !this.controller.signal.aborted) {
111
+ (_e = handlers.onError) == null ? void 0 : _e.call(handlers, error);
112
+ }
113
+ }
114
+ });
115
+ }
116
+ /**
117
+ * 使用 EventSource 连接(仅支持 GET 请求)
118
+ */
119
+ connect(url, handlers) {
120
+ this.eventSource = new EventSource(url);
121
+ this.eventSource.onopen = () => {
122
+ var _a;
123
+ (_a = handlers.onOpen) == null ? void 0 : _a.call(handlers);
124
+ };
125
+ this.eventSource.onmessage = (event) => {
126
+ var _a;
127
+ (_a = handlers.onMessage) == null ? void 0 : _a.call(handlers, {
128
+ data: event.data,
129
+ event: event.type
130
+ });
131
+ };
132
+ this.eventSource.onerror = (error) => {
133
+ var _a;
134
+ (_a = handlers.onError) == null ? void 0 : _a.call(handlers, new Error("EventSource error"));
135
+ this.close();
136
+ };
137
+ }
138
+ /**
139
+ * 解析 SSE 消息
140
+ */
141
+ parseMessage(line) {
142
+ const message = {
143
+ data: ""
144
+ };
145
+ const lines = line.split("\n");
146
+ for (const l of lines) {
147
+ if (l.startsWith("data: ")) {
148
+ message.data = l.slice(6);
149
+ } else if (l.startsWith("event: ")) {
150
+ message.event = l.slice(7);
151
+ } else if (l.startsWith("id: ")) {
152
+ message.id = l.slice(4);
153
+ } else if (l.startsWith("retry: ")) {
154
+ message.retry = parseInt(l.slice(7));
155
+ }
156
+ }
157
+ return message;
158
+ }
159
+ /**
160
+ * 关闭连接
161
+ */
162
+ close() {
163
+ if (this.controller) {
164
+ this.controller.abort();
165
+ this.controller = null;
166
+ }
167
+ if (this.eventSource) {
168
+ this.eventSource.close();
169
+ this.eventSource = null;
170
+ }
171
+ if (this.timeoutTimer) {
172
+ clearTimeout(this.timeoutTimer);
173
+ this.timeoutTimer = null;
174
+ }
175
+ }
176
+ }
177
+ function sse(config, handlers) {
178
+ const connection = new SSEConnection();
179
+ if (config.method === "POST" || config.timeout) {
180
+ connection.request(config, handlers);
181
+ } else {
182
+ connection.connect(config.url, handlers);
183
+ }
184
+ return connection;
185
+ }
186
+ function extractThinking(text, config = {}) {
187
+ const { tagName = "think", includeTags = false, removeRest = false } = config;
188
+ const openTag = `<${tagName}>`;
189
+ const closeTag = `</${tagName}>`;
190
+ const openIndex = text.indexOf(openTag);
191
+ const closeIndex = text.indexOf(closeTag);
192
+ if (openIndex === -1 || closeIndex === -1) {
193
+ return {
194
+ thinking: "",
195
+ rest: text,
196
+ hasThinking: false
197
+ };
198
+ }
199
+ const thinkingStart = openIndex + openTag.length;
200
+ const thinkingEnd = closeIndex;
201
+ const thinkingContent = text.slice(thinkingStart, thinkingEnd);
202
+ const beforeContent = text.slice(0, openIndex);
203
+ const afterContent = text.slice(closeIndex + closeTag.length);
204
+ const restContent = beforeContent + afterContent;
205
+ return {
206
+ thinking: includeTags ? `${openTag}${thinkingContent}${closeTag}` : thinkingContent,
207
+ rest: removeRest ? "" : restContent,
208
+ hasThinking: true
209
+ };
210
+ }
211
+ class ThinkingStreamExtractor {
212
+ constructor(config = {}) {
213
+ this.isComplete = false;
214
+ this.config = {
215
+ tagName: config.tagName || "think",
216
+ includeTags: config.includeTags || false,
217
+ removeRest: config.removeRest || false
218
+ };
219
+ this.state = {
220
+ inThinking: false,
221
+ tagBuffer: "",
222
+ contentBuffer: "",
223
+ beforeContent: "",
224
+ afterContent: ""
225
+ };
226
+ }
227
+ /**
228
+ * 追加文本并提取思考内容
229
+ */
230
+ append(text) {
231
+ if (this.isComplete) {
232
+ return {
233
+ thinking: this.getThinking(),
234
+ rest: this.getRest(),
235
+ isComplete: true
236
+ };
237
+ }
238
+ const { tagName } = this.config;
239
+ const openTag = `<${tagName}>`;
240
+ const closeTag = `</${tagName}>`;
241
+ for (let i = 0; i < text.length; i++) {
242
+ const char = text[i];
243
+ if (!this.state.inThinking) {
244
+ this.state.tagBuffer += char;
245
+ if (this.state.tagBuffer.endsWith(openTag)) {
246
+ const tagStart = this.state.tagBuffer.length - openTag.length;
247
+ this.state.beforeContent += this.state.tagBuffer.slice(0, tagStart);
248
+ this.state.tagBuffer = "";
249
+ this.state.inThinking = true;
250
+ continue;
251
+ }
252
+ if (this.state.tagBuffer.length > openTag.length) {
253
+ this.state.beforeContent += this.state.tagBuffer.slice(0, 1);
254
+ this.state.tagBuffer = this.state.tagBuffer.slice(1);
255
+ }
256
+ } else {
257
+ this.state.tagBuffer += char;
258
+ if (this.state.tagBuffer.endsWith(closeTag)) {
259
+ const tagEnd = this.state.tagBuffer.length - closeTag.length;
260
+ this.state.contentBuffer += this.state.tagBuffer.slice(0, tagEnd);
261
+ this.state.tagBuffer = "";
262
+ this.state.inThinking = false;
263
+ this.isComplete = true;
264
+ break;
265
+ }
266
+ if (this.state.tagBuffer.length > closeTag.length) {
267
+ const overflow = this.state.tagBuffer.slice(0, 1);
268
+ this.state.contentBuffer += overflow;
269
+ this.state.tagBuffer = this.state.tagBuffer.slice(1);
270
+ }
271
+ }
272
+ }
273
+ if (!this.state.inThinking && this.state.tagBuffer) {
274
+ if (this.isComplete) {
275
+ this.state.afterContent += this.state.tagBuffer;
276
+ } else {
277
+ this.state.beforeContent += this.state.tagBuffer;
278
+ }
279
+ this.state.tagBuffer = "";
280
+ }
281
+ return {
282
+ thinking: this.getThinking(),
283
+ rest: this.getRest(),
284
+ isComplete: this.isComplete
285
+ };
286
+ }
287
+ /**
288
+ * 获取当前提取的思考内容
289
+ */
290
+ getThinking() {
291
+ const { tagName, includeTags } = this.config;
292
+ const openTag = `<${tagName}>`;
293
+ const closeTag = `</${tagName}>`;
294
+ const content = this.state.contentBuffer;
295
+ if (includeTags) {
296
+ return this.state.inThinking ? `${openTag}${content}` : `${openTag}${content}${closeTag}`;
297
+ }
298
+ return content;
299
+ }
300
+ /**
301
+ * 获取剩余内容
302
+ */
303
+ getRest() {
304
+ const { removeRest } = this.config;
305
+ if (removeRest) {
306
+ return "";
307
+ }
308
+ return this.state.beforeContent + this.state.afterContent;
309
+ }
310
+ /**
311
+ * 是否已完成提取
312
+ */
313
+ complete() {
314
+ return this.isComplete;
315
+ }
316
+ /**
317
+ * 重置提取器
318
+ */
319
+ reset() {
320
+ this.state = {
321
+ inThinking: false,
322
+ tagBuffer: "",
323
+ contentBuffer: "",
324
+ beforeContent: "",
325
+ afterContent: ""
326
+ };
327
+ this.isComplete = false;
328
+ }
329
+ }
330
+ function createThinkingExtractor(config) {
331
+ return new ThinkingStreamExtractor(config);
332
+ }
333
+ class MarkdownRenderer {
334
+ constructor(config = {}) {
335
+ this.config = {
336
+ highlight: config.highlight || false,
337
+ highlightLanguages: config.highlightLanguages || {},
338
+ taskList: config.taskList !== false,
339
+ table: config.table !== false,
340
+ link: config.link !== false,
341
+ image: config.image !== false
342
+ };
343
+ }
344
+ /**
345
+ * 渲染 Markdown 为 HTML
346
+ */
347
+ render(markdown) {
348
+ let html = markdown;
349
+ html = this.escapeHtml(html);
350
+ html = this.renderCodeBlocks(html);
351
+ html = this.renderHeadings(html);
352
+ html = this.renderEmphasis(html);
353
+ if (this.config.taskList) {
354
+ html = this.renderTaskLists(html);
355
+ }
356
+ html = this.renderUnorderedLists(html);
357
+ html = this.renderOrderedLists(html);
358
+ if (this.config.table) {
359
+ html = this.renderTables(html);
360
+ }
361
+ if (this.config.link) {
362
+ html = this.renderLinks(html);
363
+ }
364
+ if (this.config.image) {
365
+ html = this.renderImages(html);
366
+ }
367
+ html = this.renderParagraphs(html);
368
+ html = this.renderLineBreaks(html);
369
+ return html;
370
+ }
371
+ /**
372
+ * 转义 HTML 特殊字符
373
+ */
374
+ escapeHtml(text) {
375
+ return text.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
376
+ }
377
+ /**
378
+ * 渲染代码块
379
+ */
380
+ renderCodeBlocks(text) {
381
+ return text.replace(
382
+ /`{3}(\w*)\n([\s\S]*?)`{3}/g,
383
+ (match, lang, code) => {
384
+ const language = lang || "text";
385
+ return `<pre><code class="language-${language}">${code.trim()}</code></pre>`;
386
+ }
387
+ );
388
+ }
389
+ /**
390
+ * 渲染标题
391
+ */
392
+ renderHeadings(text) {
393
+ return text.replace(/^#{6}\s+(.+)$/gm, "<h6>$1</h6>").replace(/^#{5}\s+(.+)$/gm, "<h5>$1</h5>").replace(/^#{4}\s+(.+)$/gm, "<h4>$1</h4>").replace(/^#{3}\s+(.+)$/gm, "<h3>$1</h3>").replace(/^#{2}\s+(.+)$/gm, "<h2>$1</h2>").replace(/^#{1}\s+(.+)$/gm, "<h1>$1</h1>");
394
+ }
395
+ /**
396
+ * 渲染粗体和斜体
397
+ */
398
+ renderEmphasis(text) {
399
+ text = text.replace(/\*\*\*(.+?)\*\*\*/g, "<strong><em>$1</em></strong>");
400
+ text = text.replace(/\*\*(.+?)\*\*/g, "<strong>$1</strong>");
401
+ text = text.replace(/___(.+?)___/g, "<strong><em>$1</em></strong>");
402
+ text = text.replace(/__(.+?)__/g, "<strong>$1</strong>");
403
+ text = text.replace(/\*(.+?)\*/g, "<em>$1</em>");
404
+ text = text.replace(/_(.+?)_/g, "<em>$1</em>");
405
+ return text;
406
+ }
407
+ /**
408
+ * 渲染任务列表
409
+ */
410
+ renderTaskLists(text) {
411
+ return text.replace(/^\s*-\s*\[x\]\s+(.+)$/gm, '<li class="task-checked"><input type="checkbox" checked disabled> $1</li>').replace(/^\s*-\s*\[\s*\]\s+(.+)$/gm, '<li><input type="checkbox" disabled> $1</li>');
412
+ }
413
+ /**
414
+ * 渲染无序列表
415
+ */
416
+ renderUnorderedLists(text) {
417
+ const lines = text.split("\n");
418
+ const result = [];
419
+ const listStack = [];
420
+ for (const line of lines) {
421
+ const match = line.match(/^(\s*)-\s+(.+)$/);
422
+ if (!match) {
423
+ while (listStack.length > 0) {
424
+ result.push(listStack.pop() || "");
425
+ }
426
+ result.push(line);
427
+ continue;
428
+ }
429
+ const [_, indent, content] = match;
430
+ const indentLevel = indent.length;
431
+ while (listStack.length > 0 && listStack.length < indentLevel / 2 + 1) {
432
+ result.push(listStack.pop() || "");
433
+ }
434
+ while (listStack.length < indentLevel / 2 + 1) {
435
+ listStack.push("<ul>");
436
+ result.push("<ul>");
437
+ }
438
+ result.push(`<li>${content}</li>`);
439
+ }
440
+ while (listStack.length > 0) {
441
+ result.push("</ul>");
442
+ listStack.pop();
443
+ }
444
+ return result.join("\n");
445
+ }
446
+ /**
447
+ * 渲染有序列表
448
+ */
449
+ renderOrderedLists(text) {
450
+ const lines = text.split("\n");
451
+ const result = [];
452
+ let inList = false;
453
+ for (const line of lines) {
454
+ const match = line.match(/^\s*\d+\.\s+(.+)$/);
455
+ if (!match) {
456
+ if (inList) {
457
+ result.push("</ol>");
458
+ inList = false;
459
+ }
460
+ result.push(line);
461
+ continue;
462
+ }
463
+ const [_, content] = match;
464
+ if (!inList) {
465
+ result.push("<ol>");
466
+ inList = true;
467
+ }
468
+ result.push(`<li>${content}</li>`);
469
+ }
470
+ if (inList) {
471
+ result.push("</ol>");
472
+ }
473
+ return result.join("\n");
474
+ }
475
+ /**
476
+ * 渲染表格
477
+ */
478
+ renderTables(text) {
479
+ const lines = text.split("\n");
480
+ const result = [];
481
+ let inTable = false;
482
+ let headerRendered = false;
483
+ for (let i = 0; i < lines.length; i++) {
484
+ const line = lines[i];
485
+ if (line.match(/^\|[\s\-:|]+\|$/)) {
486
+ continue;
487
+ }
488
+ const match = line.match(/^\|(.+)\|$/);
489
+ if (!match) {
490
+ if (inTable) {
491
+ result.push("</table>");
492
+ inTable = false;
493
+ headerRendered = false;
494
+ }
495
+ result.push(line);
496
+ continue;
497
+ }
498
+ const cells = match[1].split("|").map((cell) => cell.trim());
499
+ if (!inTable) {
500
+ result.push("<table>");
501
+ inTable = true;
502
+ }
503
+ if (!headerRendered) {
504
+ result.push("<thead><tr>");
505
+ cells.forEach((cell) => {
506
+ result.push(`<th>${cell}</th>`);
507
+ });
508
+ result.push("</tr></thead><tbody>");
509
+ headerRendered = true;
510
+ } else {
511
+ result.push("<tr>");
512
+ cells.forEach((cell) => {
513
+ result.push(`<td>${cell}</td>`);
514
+ });
515
+ result.push("</tr>");
516
+ }
517
+ }
518
+ if (inTable) {
519
+ result.push("</tbody></table>");
520
+ }
521
+ return result.join("\n");
522
+ }
523
+ /**
524
+ * 渲染链接
525
+ */
526
+ renderLinks(text) {
527
+ return text.replace(/\[([^\]]+)\]\(([^)]+)\)/g, '<a href="$2" target="_blank">$1</a>');
528
+ }
529
+ /**
530
+ * 渲染图片
531
+ */
532
+ renderImages(text) {
533
+ return text.replace(/!\[([^\]]*)\]\(([^)]+)\)/g, '<img src="$2" alt="$1" />');
534
+ }
535
+ /**
536
+ * 渲染段落
537
+ */
538
+ renderParagraphs(text) {
539
+ const lines = text.split("\n");
540
+ const result = [];
541
+ let inParagraph = false;
542
+ for (const line of lines) {
543
+ if (!line.trim() || line.match(/^<(h|ul|ol|li|table|pre|div)/)) {
544
+ if (inParagraph) {
545
+ result.push("</p>");
546
+ inParagraph = false;
547
+ }
548
+ result.push(line);
549
+ continue;
550
+ }
551
+ if (!inParagraph) {
552
+ result.push("<p>");
553
+ inParagraph = true;
554
+ }
555
+ result.push(line);
556
+ }
557
+ if (inParagraph) {
558
+ result.push("</p>");
559
+ }
560
+ return result.join("\n");
561
+ }
562
+ /**
563
+ * 渲染换行
564
+ */
565
+ renderLineBreaks(text) {
566
+ return text.replace(/(<p>.*?<\/p>|<li>.*?<\/li>)/g, (match) => {
567
+ return match.replace(/\n/g, "<br>\n");
568
+ });
569
+ }
570
+ }
571
+ function renderMarkdown(markdown, config) {
572
+ const renderer = new MarkdownRenderer(config);
573
+ return renderer.render(markdown);
574
+ }
575
+ class MarkdownStreamRenderer {
576
+ constructor(config = {}) {
577
+ this.buffer = "";
578
+ this.config = config;
579
+ this.renderer = new MarkdownRenderer(config);
580
+ }
581
+ /**
582
+ * 追加文本并渲染
583
+ */
584
+ append(text) {
585
+ this.buffer += text;
586
+ const html = this.renderer.render(this.buffer);
587
+ if (this.config.onUpdate) {
588
+ this.config.onUpdate(html);
589
+ }
590
+ return html;
591
+ }
592
+ /**
593
+ * 完成渲染
594
+ */
595
+ complete() {
596
+ const html = this.renderer.render(this.buffer);
597
+ if (this.config.onComplete) {
598
+ this.config.onComplete(html);
599
+ }
600
+ return html;
601
+ }
602
+ /**
603
+ * 重置渲染器
604
+ */
605
+ reset() {
606
+ this.buffer = "";
607
+ }
608
+ }
609
+ function createMarkdownRenderer(config) {
610
+ return new MarkdownStreamRenderer(config);
611
+ }
612
+ exports2.MarkdownRenderer = MarkdownRenderer;
613
+ exports2.MarkdownStreamRenderer = MarkdownStreamRenderer;
614
+ exports2.SSEConnection = SSEConnection;
615
+ exports2.ThinkingStreamExtractor = ThinkingStreamExtractor;
616
+ exports2.createMarkdownRenderer = createMarkdownRenderer;
617
+ exports2.createThinkingExtractor = createThinkingExtractor;
618
+ exports2.extractThinking = extractThinking;
619
+ exports2.renderMarkdown = renderMarkdown;
620
+ exports2.sse = sse;
621
+ Object.defineProperty(exports2, Symbol.toStringTag, { value: "Module" });
622
+ });
@@ -0,0 +1,14 @@
1
+ (function(r,a){typeof exports=="object"&&typeof module!="undefined"?a(exports):typeof define=="function"&&define.amd?define(["exports"],a):(r=typeof globalThis!="undefined"?globalThis:r||self,a(r.LxUIUtils={}))})(this,function(r){"use strict";var U=Object.defineProperty;var _=Object.getOwnPropertySymbols;var W=Object.prototype.hasOwnProperty,H=Object.prototype.propertyIsEnumerable;var M=(r,a,l)=>a in r?U(r,a,{enumerable:!0,configurable:!0,writable:!0,value:l}):r[a]=l,O=(r,a)=>{for(var l in a||(a={}))W.call(a,l)&&M(r,l,a[l]);if(_)for(var l of _(a))H.call(a,l)&&M(r,l,a[l]);return r};var j=(r,a,l)=>new Promise((S,d)=>{var v=g=>{try{T(l.next(g))}catch($){d($)}},k=g=>{try{T(l.throw(g))}catch($){d($)}},T=g=>g.done?S(g.value):Promise.resolve(g.value).then(v,k);T((l=l.apply(r,a)).next())});class a{constructor(){this.controller=null,this.eventSource=null,this.timeoutTimer=null}request(t,e){return j(this,null,function*(){var f,p,u,b,B;const{url:s,method:n="GET",headers:i={},body:c,timeout:h=3e4}=t;this.controller=new AbortController;try{h>0&&(this.timeoutTimer=setTimeout(()=>{var C;this.close(),(C=e.onError)==null||C.call(e,new Error(`Request timeout after ${h}ms`))},h));const m=yield fetch(s,{method:n,headers:O({"Content-Type":"application/json"},i),body:n==="POST"?JSON.stringify(c):void 0,signal:this.controller.signal});if(this.timeoutTimer&&(clearTimeout(this.timeoutTimer),this.timeoutTimer=null),!m.ok)throw new Error(`HTTP error! status: ${m.status}`);const w=m.headers.get("content-type");if(!(w!=null&&w.includes("text/event-stream")))throw new Error("Response is not a Server-Sent Events stream");(f=e.onOpen)==null||f.call(e);const y=(p=m.body)==null?void 0:p.getReader(),P=new TextDecoder;let E="";if(!y)throw new Error("Response body is null");for(;;){const{done:C,value:I}=yield y.read();if(C){(u=e.onClose)==null||u.call(e);break}E+=P.decode(I,{stream:!0});const L=E.split(`
2
+
3
+ `);E=L.pop()||"";for(const R of L)if(R.trim()){const N=this.parseMessage(R);(b=e.onMessage)==null||b.call(e,N)}}}catch(m){this.timeoutTimer&&(clearTimeout(this.timeoutTimer),this.timeoutTimer=null),this.controller&&!this.controller.signal.aborted&&((B=e.onError)==null||B.call(e,m))}})}connect(t,e){this.eventSource=new EventSource(t),this.eventSource.onopen=()=>{var s;(s=e.onOpen)==null||s.call(e)},this.eventSource.onmessage=s=>{var n;(n=e.onMessage)==null||n.call(e,{data:s.data,event:s.type})},this.eventSource.onerror=s=>{var n;(n=e.onError)==null||n.call(e,new Error("EventSource error")),this.close()}}parseMessage(t){const e={data:""},s=t.split(`
4
+ `);for(const n of s)n.startsWith("data: ")?e.data=n.slice(6):n.startsWith("event: ")?e.event=n.slice(7):n.startsWith("id: ")?e.id=n.slice(4):n.startsWith("retry: ")&&(e.retry=parseInt(n.slice(7)));return e}close(){this.controller&&(this.controller.abort(),this.controller=null),this.eventSource&&(this.eventSource.close(),this.eventSource=null),this.timeoutTimer&&(clearTimeout(this.timeoutTimer),this.timeoutTimer=null)}}function l(o,t){const e=new a;return o.method==="POST"||o.timeout?e.request(o,t):e.connect(o.url,t),e}function S(o,t={}){const{tagName:e="think",includeTags:s=!1,removeRest:n=!1}=t,i=`<${e}>`,c=`</${e}>`,h=o.indexOf(i),f=o.indexOf(c);if(h===-1||f===-1)return{thinking:"",rest:o,hasThinking:!1};const p=h+i.length,u=f,b=o.slice(p,u),B=o.slice(0,h),m=o.slice(f+c.length),w=B+m;return{thinking:s?`${i}${b}${c}`:b,rest:n?"":w,hasThinking:!0}}class d{constructor(t={}){this.isComplete=!1,this.config={tagName:t.tagName||"think",includeTags:t.includeTags||!1,removeRest:t.removeRest||!1},this.state={inThinking:!1,tagBuffer:"",contentBuffer:"",beforeContent:"",afterContent:""}}append(t){if(this.isComplete)return{thinking:this.getThinking(),rest:this.getRest(),isComplete:!0};const{tagName:e}=this.config,s=`<${e}>`,n=`</${e}>`;for(let i=0;i<t.length;i++){const c=t[i];if(this.state.inThinking){if(this.state.tagBuffer+=c,this.state.tagBuffer.endsWith(n)){const h=this.state.tagBuffer.length-n.length;this.state.contentBuffer+=this.state.tagBuffer.slice(0,h),this.state.tagBuffer="",this.state.inThinking=!1,this.isComplete=!0;break}if(this.state.tagBuffer.length>n.length){const h=this.state.tagBuffer.slice(0,1);this.state.contentBuffer+=h,this.state.tagBuffer=this.state.tagBuffer.slice(1)}}else{if(this.state.tagBuffer+=c,this.state.tagBuffer.endsWith(s)){const h=this.state.tagBuffer.length-s.length;this.state.beforeContent+=this.state.tagBuffer.slice(0,h),this.state.tagBuffer="",this.state.inThinking=!0;continue}this.state.tagBuffer.length>s.length&&(this.state.beforeContent+=this.state.tagBuffer.slice(0,1),this.state.tagBuffer=this.state.tagBuffer.slice(1))}}return!this.state.inThinking&&this.state.tagBuffer&&(this.isComplete?this.state.afterContent+=this.state.tagBuffer:this.state.beforeContent+=this.state.tagBuffer,this.state.tagBuffer=""),{thinking:this.getThinking(),rest:this.getRest(),isComplete:this.isComplete}}getThinking(){const{tagName:t,includeTags:e}=this.config,s=`<${t}>`,n=`</${t}>`,i=this.state.contentBuffer;return e?this.state.inThinking?`${s}${i}`:`${s}${i}${n}`:i}getRest(){const{removeRest:t}=this.config;return t?"":this.state.beforeContent+this.state.afterContent}complete(){return this.isComplete}reset(){this.state={inThinking:!1,tagBuffer:"",contentBuffer:"",beforeContent:"",afterContent:""},this.isComplete=!1}}function v(o){return new d(o)}class k{constructor(t={}){this.config={highlight:t.highlight||!1,highlightLanguages:t.highlightLanguages||{},taskList:t.taskList!==!1,table:t.table!==!1,link:t.link!==!1,image:t.image!==!1}}render(t){let e=t;return e=this.escapeHtml(e),e=this.renderCodeBlocks(e),e=this.renderHeadings(e),e=this.renderEmphasis(e),this.config.taskList&&(e=this.renderTaskLists(e)),e=this.renderUnorderedLists(e),e=this.renderOrderedLists(e),this.config.table&&(e=this.renderTables(e)),this.config.link&&(e=this.renderLinks(e)),this.config.image&&(e=this.renderImages(e)),e=this.renderParagraphs(e),e=this.renderLineBreaks(e),e}escapeHtml(t){return t.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}renderCodeBlocks(t){return t.replace(/`{3}(\w*)\n([\s\S]*?)`{3}/g,(e,s,n)=>`<pre><code class="language-${s||"text"}">${n.trim()}</code></pre>`)}renderHeadings(t){return t.replace(/^#{6}\s+(.+)$/gm,"<h6>$1</h6>").replace(/^#{5}\s+(.+)$/gm,"<h5>$1</h5>").replace(/^#{4}\s+(.+)$/gm,"<h4>$1</h4>").replace(/^#{3}\s+(.+)$/gm,"<h3>$1</h3>").replace(/^#{2}\s+(.+)$/gm,"<h2>$1</h2>").replace(/^#{1}\s+(.+)$/gm,"<h1>$1</h1>")}renderEmphasis(t){return t=t.replace(/\*\*\*(.+?)\*\*\*/g,"<strong><em>$1</em></strong>"),t=t.replace(/\*\*(.+?)\*\*/g,"<strong>$1</strong>"),t=t.replace(/___(.+?)___/g,"<strong><em>$1</em></strong>"),t=t.replace(/__(.+?)__/g,"<strong>$1</strong>"),t=t.replace(/\*(.+?)\*/g,"<em>$1</em>"),t=t.replace(/_(.+?)_/g,"<em>$1</em>"),t}renderTaskLists(t){return t.replace(/^\s*-\s*\[x\]\s+(.+)$/gm,'<li class="task-checked"><input type="checkbox" checked disabled> $1</li>').replace(/^\s*-\s*\[\s*\]\s+(.+)$/gm,'<li><input type="checkbox" disabled> $1</li>')}renderUnorderedLists(t){const e=t.split(`
5
+ `),s=[],n=[];for(const i of e){const c=i.match(/^(\s*)-\s+(.+)$/);if(!c){for(;n.length>0;)s.push(n.pop()||"");s.push(i);continue}const[h,f,p]=c,u=f.length;for(;n.length>0&&n.length<u/2+1;)s.push(n.pop()||"");for(;n.length<u/2+1;)n.push("<ul>"),s.push("<ul>");s.push(`<li>${p}</li>`)}for(;n.length>0;)s.push("</ul>"),n.pop();return s.join(`
6
+ `)}renderOrderedLists(t){const e=t.split(`
7
+ `),s=[];let n=!1;for(const i of e){const c=i.match(/^\s*\d+\.\s+(.+)$/);if(!c){n&&(s.push("</ol>"),n=!1),s.push(i);continue}const[h,f]=c;n||(s.push("<ol>"),n=!0),s.push(`<li>${f}</li>`)}return n&&s.push("</ol>"),s.join(`
8
+ `)}renderTables(t){const e=t.split(`
9
+ `),s=[];let n=!1,i=!1;for(let c=0;c<e.length;c++){const h=e[c];if(h.match(/^\|[\s\-:|]+\|$/))continue;const f=h.match(/^\|(.+)\|$/);if(!f){n&&(s.push("</table>"),n=!1,i=!1),s.push(h);continue}const p=f[1].split("|").map(u=>u.trim());n||(s.push("<table>"),n=!0),i?(s.push("<tr>"),p.forEach(u=>{s.push(`<td>${u}</td>`)}),s.push("</tr>")):(s.push("<thead><tr>"),p.forEach(u=>{s.push(`<th>${u}</th>`)}),s.push("</tr></thead><tbody>"),i=!0)}return n&&s.push("</tbody></table>"),s.join(`
10
+ `)}renderLinks(t){return t.replace(/\[([^\]]+)\]\(([^)]+)\)/g,'<a href="$2" target="_blank">$1</a>')}renderImages(t){return t.replace(/!\[([^\]]*)\]\(([^)]+)\)/g,'<img src="$2" alt="$1" />')}renderParagraphs(t){const e=t.split(`
11
+ `),s=[];let n=!1;for(const i of e){if(!i.trim()||i.match(/^<(h|ul|ol|li|table|pre|div)/)){n&&(s.push("</p>"),n=!1),s.push(i);continue}n||(s.push("<p>"),n=!0),s.push(i)}return n&&s.push("</p>"),s.join(`
12
+ `)}renderLineBreaks(t){return t.replace(/(<p>.*?<\/p>|<li>.*?<\/li>)/g,e=>e.replace(/\n/g,`<br>
13
+ `))}}function T(o,t){return new k(t).render(o)}class g{constructor(t={}){this.buffer="",this.config=t,this.renderer=new k(t)}append(t){this.buffer+=t;const e=this.renderer.render(this.buffer);return this.config.onUpdate&&this.config.onUpdate(e),e}complete(){const t=this.renderer.render(this.buffer);return this.config.onComplete&&this.config.onComplete(t),t}reset(){this.buffer=""}}function $(o){return new g(o)}r.MarkdownRenderer=k,r.MarkdownStreamRenderer=g,r.SSEConnection=a,r.ThinkingStreamExtractor=d,r.createMarkdownRenderer=$,r.createThinkingExtractor=v,r.extractThinking=S,r.renderMarkdown=T,r.sse=l,Object.defineProperty(r,Symbol.toStringTag,{value:"Module"})});
14
+ //# sourceMappingURL=index.umd.min.js.map