@floegence/floe-webapp-core 0.86.47 → 0.86.49

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,43 @@
1
+ import type { Links, Marked, Token, TokensList } from 'marked';
2
+ export type MarkdownBlock = Readonly<{
3
+ id: number;
4
+ start: number;
5
+ token: Token;
6
+ }>;
7
+ export type MarkdownBlockChange = Readonly<{
8
+ kind: 'replace';
9
+ block: MarkdownBlock;
10
+ }> | Readonly<{
11
+ kind: 'remove';
12
+ id: number;
13
+ }> | Readonly<{
14
+ kind: 'append_text';
15
+ id: number;
16
+ text: string;
17
+ code: boolean;
18
+ inlineIndex?: number;
19
+ }> | Readonly<{
20
+ kind: 'inline';
21
+ id: number;
22
+ from: number;
23
+ deleteCount: number;
24
+ tokens: readonly Token[];
25
+ }>;
26
+ export type MarkdownUpdate = Readonly<{
27
+ changes: readonly MarkdownBlockChange[];
28
+ links: Links;
29
+ sourceLength: number;
30
+ }>;
31
+ /** One append-only source, Marked semantics, and explicit changed blocks. */
32
+ export declare function createIncrementalMarkdownParser(markdown: Marked<string, string>): {
33
+ append: (delta: string) => MarkdownUpdate;
34
+ reset: (text?: string) => MarkdownUpdate;
35
+ finish: () => MarkdownUpdate;
36
+ snapshot: () => TokensList;
37
+ readonly sourceLength: number;
38
+ diagnostics: () => {
39
+ fullParses: number;
40
+ parsedCharacters: number;
41
+ blocks: number;
42
+ };
43
+ };
@@ -0,0 +1,258 @@
1
+ function X(k) {
2
+ let L = 0, b = [], C = 0, I = !1, l = [], p = /* @__PURE__ */ Object.create(null), v = /* @__PURE__ */ Object.create(null), R = 1, o = 0, g, O, S = !1, M = 0, W = 0;
3
+ const m = /* @__PURE__ */ new Map();
4
+ function U(e) {
5
+ let t = 0, n = b.length;
6
+ for (; t < n; ) {
7
+ const s = t + n >>> 1;
8
+ b[s].start <= e ? t = s + 1 : n = s;
9
+ }
10
+ const i = Math.max(0, t - 1);
11
+ return b.slice(i).map((s, a) => a === 0 ? s.text.slice(e - s.start) : s.text).join("");
12
+ }
13
+ function F(e, t) {
14
+ W += e.length;
15
+ const n = new k.Lexer({ ...k.defaults });
16
+ return n.tokens.links = { ...t }, n.lex(e);
17
+ }
18
+ function w(e) {
19
+ return { changes: e, links: p, sourceLength: C };
20
+ }
21
+ function $(e) {
22
+ return { id: e.id, start: e.start, token: structuredClone(e.token) };
23
+ }
24
+ function q(e) {
25
+ for (const t of e.token.raw.matchAll(/\[((?:\\[^\n]|[^\]\n\\])+)\]/g)) {
26
+ const n = t[1].toLowerCase().replace(/\s+/g, " ");
27
+ e.references.add(n);
28
+ let i = m.get(n);
29
+ i || m.set(n, i = /* @__PURE__ */ new Set()), i.add(e);
30
+ }
31
+ }
32
+ function B(e) {
33
+ for (const t of e.references) {
34
+ const n = m.get(t);
35
+ n?.delete(e), n?.size || m.delete(t);
36
+ }
37
+ }
38
+ function E(e, t) {
39
+ for (const n of e)
40
+ if (n === `
41
+ `) {
42
+ if (t.candidate && t.count >= t.minimum) return !0;
43
+ t.count = 0, t.indent = 0, t.candidate = !0;
44
+ } else t.candidate && (n === t.mark && t.indent <= 3 ? t.count++ : n === " " && t.count === 0 && t.indent < 3 ? t.indent++ : (n !== " " && n !== " " || t.count === 0) && (t.candidate = !1));
45
+ return t.candidate && t.count >= t.minimum;
46
+ }
47
+ function z(e) {
48
+ const t = k.defaults.extensions;
49
+ if (!t || !t.inline?.length) return !1;
50
+ const n = t.startInline ?? [];
51
+ if (n.length < t.inline.length) return !0;
52
+ const i = new k.Lexer({ ...k.defaults });
53
+ return n.some((s) => {
54
+ const a = s.call({ lexer: i }, e);
55
+ return typeof a == "number" && a >= 0;
56
+ });
57
+ }
58
+ function _(e, t = 0) {
59
+ const n = e.tokens;
60
+ let i = -1;
61
+ for (let f = t; f < n.length; f++) {
62
+ const u = n[f];
63
+ if (u.type === "text" && (/[\\\x60*_[<~]/u.test(u.raw) || z(u.raw))) {
64
+ i = f;
65
+ break;
66
+ }
67
+ }
68
+ let s = i >= 0 ? i : Math.max(t, n.length - 1);
69
+ s > t && n[s]?.type === "text" && !/\s/u.test(n[s].raw) && n[s - 1]?.type === "link" && s--;
70
+ const a = n[s];
71
+ if (i < 0 && a?.type === "text" && a.raw === a.text) {
72
+ const f = a.raw.lastIndexOf(" ");
73
+ if (f > 0) {
74
+ const u = a;
75
+ n.splice(
76
+ s,
77
+ 1,
78
+ { ...u, raw: u.raw.slice(0, f), text: u.text.slice(0, f) },
79
+ { ...u, raw: u.raw.slice(f), text: u.text.slice(f) }
80
+ ), s++;
81
+ }
82
+ }
83
+ const d = n.slice(s).map((f) => f.raw).join("");
84
+ O = {
85
+ from: s,
86
+ source: d,
87
+ unresolved: i >= 0,
88
+ extensionPending: z(d),
89
+ lastChar: d.slice(-1)
90
+ };
91
+ }
92
+ function G() {
93
+ g = void 0, O = void 0, S = !1;
94
+ const e = l.at(-1)?.token;
95
+ if (e?.type === "paragraph") {
96
+ _(e);
97
+ const a = e.raw.lastIndexOf(`
98
+ `) + 1, d = e.raw.slice(a, a + 32);
99
+ S = !e.raw.endsWith(`
100
+ `) && !/^(?: {0,3}(?:[-+*_]+|[0-9]{1,9}[.)]?)[ \t]*$| {0,3}[[<\x60~#|=])/u.test(d);
101
+ }
102
+ if (e?.type !== "code") return;
103
+ const t = /^(\x60{3,}|~{3,})[^\n]*\n/.exec(e.raw);
104
+ if (!t) return;
105
+ const n = t[1], i = e.raw.slice(t[0].length), s = {
106
+ mark: n[0],
107
+ minimum: n.length,
108
+ count: 0,
109
+ indent: 0,
110
+ candidate: !0,
111
+ pendingNewline: i.endsWith(`
112
+ `)
113
+ };
114
+ E(i, s) || (g = s);
115
+ }
116
+ function N(e = !1) {
117
+ const t = l[o]?.start ?? 0, n = l.splice(o);
118
+ for (const r of n) B(r);
119
+ const i = F(U(t), v), s = p;
120
+ p = Object.freeze(
121
+ Object.fromEntries(
122
+ Object.entries(i.links).map(([r, c]) => [r, Object.freeze({ ...c })])
123
+ )
124
+ );
125
+ const a = [];
126
+ let d = t;
127
+ for (let r = 0; r < i.length; r++) {
128
+ const c = i[r], h = n[r], x = {
129
+ id: h?.start === d ? h.id : R++,
130
+ start: d,
131
+ token: c,
132
+ references: /* @__PURE__ */ new Set()
133
+ };
134
+ l.push(x), q(x), r === i.length - 1 && c.type === "paragraph" && _(c), (!e || !h || JSON.stringify(h.token) !== JSON.stringify(c)) && a.push({ kind: "replace", block: $(x) }), d += c.raw.length;
135
+ }
136
+ const f = new Set(l.slice(o).map((r) => r.id));
137
+ for (const r of n)
138
+ f.has(r.id) || a.push({ kind: "remove", id: r.id });
139
+ const u = /* @__PURE__ */ new Set();
140
+ for (const r of /* @__PURE__ */ new Set([...Object.keys(s), ...Object.keys(p)]))
141
+ if (!(s[r]?.href === p[r]?.href && s[r]?.title === p[r]?.title))
142
+ for (const c of m.get(r) ?? [])
143
+ c.start < t && u.add(c);
144
+ for (const r of u) {
145
+ const c = F(r.token.raw, p);
146
+ c.length === 1 && (r.token = c[0], a.push({ kind: "replace", block: $(r) }));
147
+ }
148
+ const P = o;
149
+ o = Math.max(0, l.length - 1), l[o]?.token.type === "space" ? o = Math.max(0, o - 1) : o > 0 && !l[o - 1].token.raw.endsWith(`
150
+
151
+ `) && (l[o - 1]?.token.type !== "space" ? o-- : /\n[ \t]*\n/u.test(l[o - 1].token.raw) || (o = Math.max(0, o - 2)));
152
+ const y = l.at(-1)?.token;
153
+ o > 1 && l[o - 1]?.token.type === "space" && l[o - 2]?.token.type === "list" && (y?.type === "list" || y?.type === "paragraph" && /^ {0,3}(?:[0-9]{1,9}[.)]?|[-+*])[ \t]*$/u.test(y.raw)) && (o -= 2);
154
+ for (let r = P; r < o; r++) {
155
+ const c = l[r].token;
156
+ c.type === "def" && !v[c.tag] && (v[c.tag] = { href: c.href, title: c.title });
157
+ }
158
+ return G(), w(a);
159
+ }
160
+ function J(e) {
161
+ const t = I && e.startsWith(`
162
+ `);
163
+ return I = e.endsWith("\r"), (t ? e.slice(1) : e).replace(/\r\n?/g, `
164
+ `);
165
+ }
166
+ function H(e) {
167
+ if (!e) return w([]);
168
+ if (C += e.length, e = J(e), !e) return w([]);
169
+ b.push({ start: L, text: e }), L += e.length;
170
+ const t = l.at(-1), n = t?.token;
171
+ if (t && o === l.length - 1 && n?.type === "code" && g && !e.includes("\r") && !E(e, g)) {
172
+ const s = (g.pendingNewline ? `
173
+ ` : "") + (e.endsWith(`
174
+ `) ? e.slice(0, -1) : e);
175
+ return g.pendingNewline = e.endsWith(`
176
+ `), n.raw += e, n.text += s, w(s ? [{ kind: "append_text", id: t.id, text: s, code: !0 }] : []);
177
+ }
178
+ const i = n?.type === "paragraph" ? n : void 0;
179
+ if (t && o === l.length - 1 && i && O && S && !/[\n\r]/u.test(e)) {
180
+ const s = O, a = i.tokens.at(-1), d = a?.type === "text" && s.from === i.tokens.length - 1 && !z(e) && !s.extensionPending && !/[\\\x60*_[\]<>~&:/.@;|="'()-]/u.test(e) && !/[\\\x60*_[\]<>~&:/.@;|="'()-]$/u.test(s.lastChar);
181
+ if (i.raw += e, i.text += e, d) {
182
+ const c = a, h = s.unresolved ? -1 : e.lastIndexOf(" "), x = h > 0 ? e.slice(0, h) : h === 0 ? "" : e, T = [], A = i.tokens.length - 1;
183
+ if (x && (c.raw += x, c.text += x, T.push({
184
+ kind: "append_text",
185
+ id: t.id,
186
+ text: x,
187
+ code: !1,
188
+ inlineIndex: A
189
+ })), h >= 0) {
190
+ const j = e.slice(h), D = { type: "text", raw: j, text: j };
191
+ i.tokens.push(D), T.push({
192
+ kind: "inline",
193
+ id: t.id,
194
+ from: A + 1,
195
+ deleteCount: 0,
196
+ tokens: [structuredClone(D)]
197
+ }), O = {
198
+ from: A + 1,
199
+ source: j,
200
+ unresolved: !1,
201
+ extensionPending: !1,
202
+ lastChar: j.slice(-1)
203
+ };
204
+ } else
205
+ s.source += e, s.lastChar = e.slice(-1);
206
+ return w(T);
207
+ }
208
+ const f = new k.Lexer({ ...k.defaults });
209
+ f.tokens.links = p;
210
+ const u = s.source + e;
211
+ W += u.length;
212
+ const P = f.inlineTokens(u), y = i.tokens.length - s.from;
213
+ i.tokens.splice(s.from, y, ...P), _(i, s.from);
214
+ const r = i.tokens.slice(s.from);
215
+ return w([
216
+ {
217
+ kind: "inline",
218
+ id: t.id,
219
+ from: s.from,
220
+ deleteCount: y,
221
+ tokens: structuredClone(r)
222
+ }
223
+ ]);
224
+ }
225
+ return N();
226
+ }
227
+ function K(e = "") {
228
+ const t = l.map((s) => ({
229
+ kind: "remove",
230
+ id: s.id
231
+ }));
232
+ C = e.length, I = !1;
233
+ const n = J(e);
234
+ L = n.length, b = n ? [{ start: 0, text: n }] : [], l = [], p = /* @__PURE__ */ Object.create(null), v = /* @__PURE__ */ Object.create(null), m.clear(), o = 0, g = void 0, M++;
235
+ const i = N();
236
+ return { ...i, changes: [...t, ...i.changes] };
237
+ }
238
+ function Q() {
239
+ const e = l.map((t) => structuredClone(t.token));
240
+ return e.links = { ...p }, e;
241
+ }
242
+ function V() {
243
+ return M++, o = 0, v = /* @__PURE__ */ Object.create(null), N(!0);
244
+ }
245
+ return {
246
+ append: H,
247
+ reset: K,
248
+ finish: V,
249
+ snapshot: Q,
250
+ get sourceLength() {
251
+ return C;
252
+ },
253
+ diagnostics: () => ({ fullParses: M, parsedCharacters: W, blocks: l.length })
254
+ };
255
+ }
256
+ export {
257
+ X as createIncrementalMarkdownParser
258
+ };
@@ -1 +1,3 @@
1
1
  export { createMarkdownParser } from './components/chat/markdown/parser';
2
+ export { createIncrementalMarkdownParser } from './components/chat/markdown/incremental';
3
+ export type { MarkdownBlock, MarkdownBlockChange, MarkdownUpdate, } from './components/chat/markdown/incremental';
package/dist/markdown.js CHANGED
@@ -1,4 +1,6 @@
1
1
  import { createMarkdownParser as a } from "./components/chat/markdown/parser.js";
2
+ import { createIncrementalMarkdownParser as t } from "./components/chat/markdown/incremental.js";
2
3
  export {
4
+ t as createIncrementalMarkdownParser,
3
5
  a as createMarkdownParser
4
6
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@floegence/floe-webapp-core",
3
- "version": "0.86.47",
3
+ "version": "0.86.49",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",