@floegence/floe-webapp-core 0.86.47 → 0.86.48

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