@anvia/react-ui 0.6.2 → 0.6.3
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/chat/index.js +3 -3
- package/dist/{chunk-LM5SU5AP.js → chunk-FABSIZZ7.js} +2 -2
- package/dist/{chunk-7I6XUWM7.js → chunk-JWZDNM5D.js} +2 -2
- package/dist/{chunk-UESNSQGQ.js → chunk-ULGJLLZE.js} +127 -49
- package/dist/chunk-ULGJLLZE.js.map +1 -0
- package/dist/index.js +3 -3
- package/dist/message/index.js +2 -2
- package/dist/stream/index.js +1 -1
- package/dist/stream/styles.css +9 -1
- package/dist/styles.css +3 -1
- package/package.json +2 -2
- package/dist/chunk-UESNSQGQ.js.map +0 -1
- /package/dist/{chunk-LM5SU5AP.js.map → chunk-FABSIZZ7.js.map} +0 -0
- /package/dist/{chunk-7I6XUWM7.js.map → chunk-JWZDNM5D.js.map} +0 -0
package/dist/chat/index.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
Composer,
|
|
3
3
|
Thread
|
|
4
|
-
} from "../chunk-
|
|
5
|
-
import "../chunk-
|
|
6
|
-
import "../chunk-
|
|
4
|
+
} from "../chunk-FABSIZZ7.js";
|
|
5
|
+
import "../chunk-JWZDNM5D.js";
|
|
6
|
+
import "../chunk-ULGJLLZE.js";
|
|
7
7
|
import "../chunk-SBYUKODG.js";
|
|
8
8
|
import "../chunk-T3ZFZ3NP.js";
|
|
9
9
|
import {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
Message,
|
|
3
3
|
shiftComposerEntityRanges
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-JWZDNM5D.js";
|
|
5
5
|
import {
|
|
6
6
|
Attachment
|
|
7
7
|
} from "./chunk-SBYUKODG.js";
|
|
@@ -1572,4 +1572,4 @@ export {
|
|
|
1572
1572
|
Composer,
|
|
1573
1573
|
Thread
|
|
1574
1574
|
};
|
|
1575
|
-
//# sourceMappingURL=chunk-
|
|
1575
|
+
//# sourceMappingURL=chunk-FABSIZZ7.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
StreamMarkdown
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-ULGJLLZE.js";
|
|
4
4
|
import {
|
|
5
5
|
Attachment
|
|
6
6
|
} from "./chunk-SBYUKODG.js";
|
|
@@ -1057,4 +1057,4 @@ export {
|
|
|
1057
1057
|
shiftComposerEntityRanges,
|
|
1058
1058
|
Message
|
|
1059
1059
|
};
|
|
1060
|
-
//# sourceMappingURL=chunk-
|
|
1060
|
+
//# sourceMappingURL=chunk-JWZDNM5D.js.map
|
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
createElement,
|
|
8
8
|
forwardRef,
|
|
9
9
|
memo,
|
|
10
|
+
useCallback,
|
|
10
11
|
useMemo,
|
|
11
12
|
useRef
|
|
12
13
|
} from "react";
|
|
@@ -53,16 +54,22 @@ function splitStreamMarkdownBlocks(content, options = {}) {
|
|
|
53
54
|
// src/stream/markdown-reveal.ts
|
|
54
55
|
var streamRevealConfig = {
|
|
55
56
|
bandGraphemes: 2,
|
|
57
|
+
durationMs: 180,
|
|
56
58
|
minimumOpacity: 0.12,
|
|
57
59
|
tailGraphemes: 24
|
|
58
60
|
};
|
|
59
|
-
function createStreamGradientRevealPlugin(
|
|
61
|
+
function createStreamGradientRevealPlugin(lifecycleScope, lifecycle) {
|
|
60
62
|
return function streamGradientRevealPlugin() {
|
|
61
63
|
return (tree) => {
|
|
64
|
+
if (lifecycle.activeScope !== lifecycleScope) {
|
|
65
|
+
lifecycle.activeScope = lifecycleScope;
|
|
66
|
+
lifecycle.settledRevealIds.clear();
|
|
67
|
+
lifecycle.startedAtByRevealId.clear();
|
|
68
|
+
}
|
|
62
69
|
const targets = collectTextTargets(tree);
|
|
63
70
|
const renderedText = targets.map((target) => target.node.value ?? "").join("");
|
|
64
|
-
const
|
|
65
|
-
|
|
71
|
+
const graphemes = createRevealGraphemes(renderedText);
|
|
72
|
+
wrapStreamRevealGraphemes(targets, graphemes, lifecycleScope, lifecycle);
|
|
66
73
|
};
|
|
67
74
|
};
|
|
68
75
|
}
|
|
@@ -95,56 +102,77 @@ function collectTextTargets(tree) {
|
|
|
95
102
|
visit(tree, void 0, 0);
|
|
96
103
|
return targets;
|
|
97
104
|
}
|
|
98
|
-
function
|
|
105
|
+
function createRevealGraphemes(content) {
|
|
99
106
|
const tail = segmentTailGraphemeRanges(content, streamRevealConfig.tailGraphemes);
|
|
100
|
-
const
|
|
101
|
-
for (let index = 0; index < tail.length; index +=
|
|
102
|
-
const
|
|
103
|
-
const
|
|
104
|
-
const
|
|
105
|
-
if (
|
|
107
|
+
const graphemes = [];
|
|
108
|
+
for (let index = 0; index < tail.length; index += 1) {
|
|
109
|
+
const grapheme = tail[index];
|
|
110
|
+
const bandStartIndex = Math.floor(index / streamRevealConfig.bandGraphemes) * streamRevealConfig.bandGraphemes;
|
|
111
|
+
const bandEndIndex = Math.min(bandStartIndex + streamRevealConfig.bandGraphemes, tail.length) - 1;
|
|
112
|
+
if (grapheme === void 0) {
|
|
106
113
|
continue;
|
|
107
114
|
}
|
|
108
|
-
const progress = tail.length === 1 ? 1 :
|
|
109
|
-
|
|
110
|
-
startOffset:
|
|
111
|
-
endOffset:
|
|
115
|
+
const progress = tail.length === 1 ? 1 : bandEndIndex / (tail.length - 1);
|
|
116
|
+
graphemes.push({
|
|
117
|
+
startOffset: grapheme.startOffset,
|
|
118
|
+
endOffset: grapheme.endOffset,
|
|
112
119
|
opacity: Math.max(
|
|
113
120
|
streamRevealConfig.minimumOpacity,
|
|
114
121
|
1 - progress * (1 - streamRevealConfig.minimumOpacity)
|
|
115
122
|
)
|
|
116
123
|
});
|
|
117
124
|
}
|
|
118
|
-
return
|
|
125
|
+
return graphemes;
|
|
119
126
|
}
|
|
120
|
-
function
|
|
127
|
+
function wrapStreamRevealGraphemes(targets, graphemes, lifecycleScope, lifecycle) {
|
|
128
|
+
const activeRevealIds = /* @__PURE__ */ new Set();
|
|
129
|
+
const nowMs = Date.now();
|
|
121
130
|
for (const target of [...targets].reverse()) {
|
|
122
131
|
const value = target.node.value ?? "";
|
|
123
|
-
const
|
|
124
|
-
(
|
|
132
|
+
const intersectingGraphemes = graphemes.filter(
|
|
133
|
+
(grapheme) => grapheme.endOffset > target.startOffset && grapheme.startOffset < target.endOffset
|
|
125
134
|
);
|
|
126
|
-
if (
|
|
135
|
+
if (intersectingGraphemes.length === 0) {
|
|
127
136
|
continue;
|
|
128
137
|
}
|
|
129
138
|
const replacement = [];
|
|
130
139
|
let cursor = 0;
|
|
131
|
-
for (const
|
|
132
|
-
const start = Math.max(0,
|
|
133
|
-
const end = Math.min(value.length,
|
|
140
|
+
for (const grapheme of intersectingGraphemes) {
|
|
141
|
+
const start = Math.max(0, grapheme.startOffset - target.startOffset);
|
|
142
|
+
const end = Math.min(value.length, grapheme.endOffset - target.startOffset);
|
|
134
143
|
if (start > cursor) {
|
|
135
144
|
replacement.push({ type: "text", value: value.slice(cursor, start) });
|
|
136
145
|
}
|
|
137
146
|
if (end > start) {
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
147
|
+
const text = value.slice(start, end);
|
|
148
|
+
const absoluteStart = target.startOffset + start;
|
|
149
|
+
const absoluteEnd = target.startOffset + end;
|
|
150
|
+
const revealId = `${lifecycleScope}:${absoluteStart}:${absoluteEnd}:${hashText(text)}`;
|
|
151
|
+
activeRevealIds.add(revealId);
|
|
152
|
+
const startedAt = lifecycle.startedAtByRevealId.get(revealId) ?? nowMs;
|
|
153
|
+
lifecycle.startedAtByRevealId.set(revealId, startedAt);
|
|
154
|
+
const elapsedMs = Math.max(0, nowMs - startedAt);
|
|
155
|
+
if (elapsedMs >= streamRevealConfig.durationMs) {
|
|
156
|
+
lifecycle.settledRevealIds.add(revealId);
|
|
157
|
+
}
|
|
158
|
+
if (lifecycle.settledRevealIds.has(revealId)) {
|
|
159
|
+
replacement.push({ type: "text", value: text });
|
|
160
|
+
} else {
|
|
161
|
+
const progress = Math.min(elapsedMs / streamRevealConfig.durationMs, 1);
|
|
162
|
+
const opacity = grapheme.opacity + (1 - grapheme.opacity) * progress;
|
|
163
|
+
const remainingMs = Math.max(1, streamRevealConfig.durationMs - elapsedMs);
|
|
164
|
+
replacement.push({
|
|
165
|
+
type: "element",
|
|
166
|
+
tagName: "span",
|
|
167
|
+
properties: {
|
|
168
|
+
"data-anvia-stream-duration-ms": String(remainingMs),
|
|
169
|
+
"data-anvia-stream-opacity": String(opacity),
|
|
170
|
+
"data-anvia-stream-reveal": "",
|
|
171
|
+
"data-anvia-stream-reveal-id": revealId
|
|
172
|
+
},
|
|
173
|
+
children: [{ type: "text", value: text }]
|
|
174
|
+
});
|
|
175
|
+
}
|
|
148
176
|
}
|
|
149
177
|
cursor = Math.max(cursor, end);
|
|
150
178
|
}
|
|
@@ -153,6 +181,23 @@ function wrapStreamRevealBands(targets, bands, frameId) {
|
|
|
153
181
|
}
|
|
154
182
|
target.parent.children?.splice(target.index, 1, ...replacement);
|
|
155
183
|
}
|
|
184
|
+
pruneRevealLifecycle(lifecycle, activeRevealIds);
|
|
185
|
+
}
|
|
186
|
+
function pruneRevealLifecycle(lifecycle, activeRevealIds) {
|
|
187
|
+
for (const revealId of lifecycle.startedAtByRevealId.keys()) {
|
|
188
|
+
if (!activeRevealIds.has(revealId)) lifecycle.startedAtByRevealId.delete(revealId);
|
|
189
|
+
}
|
|
190
|
+
for (const revealId of lifecycle.settledRevealIds) {
|
|
191
|
+
if (!activeRevealIds.has(revealId)) lifecycle.settledRevealIds.delete(revealId);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
function hashText(text) {
|
|
195
|
+
let hash = 2166136261;
|
|
196
|
+
for (let index = 0; index < text.length; index += 1) {
|
|
197
|
+
hash ^= text.charCodeAt(index);
|
|
198
|
+
hash = Math.imul(hash, 16777619);
|
|
199
|
+
}
|
|
200
|
+
return (hash >>> 0).toString(36);
|
|
156
201
|
}
|
|
157
202
|
function segmentTailGraphemeRanges(content, limit) {
|
|
158
203
|
if (typeof Intl !== "undefined" && typeof Intl.Segmenter === "function") {
|
|
@@ -196,19 +241,41 @@ import { createElement as createElement2 } from "react";
|
|
|
196
241
|
var defaultRemarkPlugins = [remarkGfm];
|
|
197
242
|
var StreamMarkdown = forwardRef(
|
|
198
243
|
function StreamMarkdown2({ components, content, live = false, remarkPlugins, remarkRehypeOptions, ...props }, ref) {
|
|
199
|
-
const
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
244
|
+
const revealLifecycleRef = useRef({
|
|
245
|
+
activeScope: null,
|
|
246
|
+
content,
|
|
247
|
+
id: 0,
|
|
248
|
+
settledRevealIds: /* @__PURE__ */ new Set(),
|
|
249
|
+
startedAtByRevealId: /* @__PURE__ */ new Map()
|
|
250
|
+
});
|
|
251
|
+
const revealLifecycle = revealLifecycleRef.current;
|
|
252
|
+
if (revealLifecycle.content !== content) {
|
|
253
|
+
if (!content.startsWith(revealLifecycle.content)) {
|
|
254
|
+
revealLifecycle.id += 1;
|
|
255
|
+
revealLifecycle.activeScope = null;
|
|
256
|
+
revealLifecycle.settledRevealIds.clear();
|
|
257
|
+
revealLifecycle.startedAtByRevealId.clear();
|
|
258
|
+
}
|
|
259
|
+
revealLifecycle.content = content;
|
|
260
|
+
}
|
|
261
|
+
if (!live && revealLifecycle.activeScope !== null) {
|
|
262
|
+
for (const revealId of revealLifecycle.startedAtByRevealId.keys()) {
|
|
263
|
+
revealLifecycle.settledRevealIds.add(revealId);
|
|
264
|
+
}
|
|
204
265
|
}
|
|
266
|
+
const settleReveal = useCallback((revealId) => {
|
|
267
|
+
revealLifecycleRef.current.settledRevealIds.add(revealId);
|
|
268
|
+
}, []);
|
|
205
269
|
const blocks = useMemo(
|
|
206
270
|
() => splitStreamMarkdownBlocks(content, {
|
|
207
271
|
singleDocument: remarkPlugins !== void 0
|
|
208
272
|
}),
|
|
209
273
|
[content, remarkPlugins]
|
|
210
274
|
);
|
|
211
|
-
const streamingComponents = useMemo(
|
|
275
|
+
const streamingComponents = useMemo(
|
|
276
|
+
() => withStreamRevealComponent(components, settleReveal),
|
|
277
|
+
[components, settleReveal]
|
|
278
|
+
);
|
|
212
279
|
return renderPrimitive(
|
|
213
280
|
"div",
|
|
214
281
|
{
|
|
@@ -218,8 +285,9 @@ var StreamMarkdown = forwardRef(
|
|
|
218
285
|
{
|
|
219
286
|
components: streamingComponents,
|
|
220
287
|
content: block.content,
|
|
221
|
-
frameId: live && index === blocks.length - 1 ? frameIdRef.current : 0,
|
|
222
288
|
live: live && index === blocks.length - 1,
|
|
289
|
+
revealLifecycle,
|
|
290
|
+
revealScope: `${revealLifecycle.id}:${block.startOffset}`,
|
|
223
291
|
remarkPlugins: remarkPlugins ?? defaultRemarkPlugins,
|
|
224
292
|
remarkRehypeOptions
|
|
225
293
|
},
|
|
@@ -234,8 +302,8 @@ var StreamMarkdown = forwardRef(
|
|
|
234
302
|
);
|
|
235
303
|
var StreamMarkdownBlock = memo(function StreamMarkdownBlock2(props) {
|
|
236
304
|
const revealPlugin = useMemo(
|
|
237
|
-
() => createStreamGradientRevealPlugin(props.
|
|
238
|
-
[props.
|
|
305
|
+
() => createStreamGradientRevealPlugin(props.revealScope, props.revealLifecycle),
|
|
306
|
+
[props.revealScope, props.revealLifecycle]
|
|
239
307
|
);
|
|
240
308
|
return /* @__PURE__ */ jsx(
|
|
241
309
|
ReactMarkdown,
|
|
@@ -248,7 +316,7 @@ var StreamMarkdownBlock = memo(function StreamMarkdownBlock2(props) {
|
|
|
248
316
|
}
|
|
249
317
|
);
|
|
250
318
|
});
|
|
251
|
-
function withStreamRevealComponent(components) {
|
|
319
|
+
function withStreamRevealComponent(components, onRevealSettled) {
|
|
252
320
|
const consumerSpan = components?.span;
|
|
253
321
|
return {
|
|
254
322
|
...components,
|
|
@@ -256,7 +324,7 @@ function withStreamRevealComponent(components) {
|
|
|
256
324
|
const safeProps = componentPropsWithoutKey(spanProps);
|
|
257
325
|
const internalProps = safeProps;
|
|
258
326
|
if (internalProps["data-anvia-stream-reveal"] !== void 0) {
|
|
259
|
-
return streamRevealSpan(internalProps);
|
|
327
|
+
return streamRevealSpan(internalProps, onRevealSettled);
|
|
260
328
|
}
|
|
261
329
|
if (consumerSpan !== void 0) {
|
|
262
330
|
return createElement(consumerSpan, safeProps);
|
|
@@ -275,22 +343,32 @@ function componentPropsWithoutKey(props) {
|
|
|
275
343
|
}
|
|
276
344
|
return result;
|
|
277
345
|
}
|
|
278
|
-
function streamRevealSpan(props) {
|
|
346
|
+
function streamRevealSpan(props, onRevealSettled) {
|
|
279
347
|
const {
|
|
280
348
|
children,
|
|
281
349
|
node: _node,
|
|
282
|
-
"data-anvia-stream-
|
|
350
|
+
"data-anvia-stream-duration-ms": durationMs,
|
|
283
351
|
"data-anvia-stream-opacity": opacity,
|
|
352
|
+
"data-anvia-stream-reveal-id": revealId,
|
|
353
|
+
onAnimationEnd,
|
|
284
354
|
...elementProps
|
|
285
355
|
} = props;
|
|
286
356
|
const parsedOpacity = Number(opacity);
|
|
357
|
+
const parsedDurationMs = Number(durationMs);
|
|
287
358
|
return /* @__PURE__ */ createElement2(
|
|
288
359
|
"span",
|
|
289
360
|
{
|
|
290
361
|
...elementProps,
|
|
291
|
-
"data-anvia-stream-
|
|
292
|
-
key:
|
|
293
|
-
|
|
362
|
+
"data-anvia-stream-reveal-id": revealId,
|
|
363
|
+
key: revealId ?? "stream-reveal",
|
|
364
|
+
onAnimationEnd: (event) => {
|
|
365
|
+
onAnimationEnd?.(event);
|
|
366
|
+
if (revealId !== void 0) onRevealSettled(revealId);
|
|
367
|
+
},
|
|
368
|
+
style: {
|
|
369
|
+
"--anvia-stream-reveal-opacity": Number.isFinite(parsedOpacity) ? parsedOpacity : 1,
|
|
370
|
+
"--anvia-stream-reveal-duration": `${Number.isFinite(parsedDurationMs) ? parsedDurationMs : 180}ms`
|
|
371
|
+
}
|
|
294
372
|
},
|
|
295
373
|
children
|
|
296
374
|
);
|
|
@@ -299,4 +377,4 @@ function streamRevealSpan(props) {
|
|
|
299
377
|
export {
|
|
300
378
|
StreamMarkdown
|
|
301
379
|
};
|
|
302
|
-
//# sourceMappingURL=chunk-
|
|
380
|
+
//# sourceMappingURL=chunk-ULGJLLZE.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/stream/markdown.tsx","../src/stream/markdown-blocks.ts","../src/stream/markdown-reveal.ts"],"sourcesContent":["import {\n type ComponentPropsWithoutRef,\n type CSSProperties,\n createElement,\n forwardRef,\n memo,\n type ReactNode,\n useCallback,\n useMemo,\n useRef,\n} from \"react\";\nimport ReactMarkdown, {\n type Components,\n type Options as ReactMarkdownOptions,\n} from \"react-markdown\";\nimport remarkGfm from \"remark-gfm\";\n\nimport { type PrimitiveProps, renderPrimitive } from \"../primitives\";\nimport { splitStreamMarkdownBlocks } from \"./markdown-blocks\";\nimport { createStreamGradientRevealPlugin, type StreamRevealLifecycle } from \"./markdown-reveal\";\n\nexport type StreamMarkdownProps = Omit<PrimitiveProps<\"div\">, \"children\"> & {\n components?: Components;\n content: string;\n live?: boolean;\n remarkPlugins?: ReactMarkdownOptions[\"remarkPlugins\"];\n remarkRehypeOptions?: ReactMarkdownOptions[\"remarkRehypeOptions\"];\n};\n\nconst defaultRemarkPlugins: NonNullable<ReactMarkdownOptions[\"remarkPlugins\"]> = [remarkGfm];\n\nexport const StreamMarkdown = forwardRef<HTMLDivElement, StreamMarkdownProps>(\n function StreamMarkdown(\n { components, content, live = false, remarkPlugins, remarkRehypeOptions, ...props },\n ref,\n ) {\n const revealLifecycleRef = useRef({\n activeScope: null,\n content,\n id: 0,\n settledRevealIds: new Set<string>(),\n startedAtByRevealId: new Map<string, number>(),\n } satisfies StreamRevealLifecycle & { content: string; id: number });\n const revealLifecycle = revealLifecycleRef.current;\n if (revealLifecycle.content !== content) {\n if (!content.startsWith(revealLifecycle.content)) {\n revealLifecycle.id += 1;\n revealLifecycle.activeScope = null;\n revealLifecycle.settledRevealIds.clear();\n revealLifecycle.startedAtByRevealId.clear();\n }\n revealLifecycle.content = content;\n }\n if (!live && revealLifecycle.activeScope !== null) {\n for (const revealId of revealLifecycle.startedAtByRevealId.keys()) {\n revealLifecycle.settledRevealIds.add(revealId);\n }\n }\n const settleReveal = useCallback((revealId: string) => {\n revealLifecycleRef.current.settledRevealIds.add(revealId);\n }, []);\n\n const blocks = useMemo(\n () =>\n splitStreamMarkdownBlocks(content, {\n singleDocument: remarkPlugins !== undefined,\n }),\n [content, remarkPlugins],\n );\n const streamingComponents = useMemo(\n () => withStreamRevealComponent(components, settleReveal),\n [components, settleReveal],\n );\n\n return renderPrimitive(\n \"div\",\n {\n ...props,\n children: blocks.map((block, index) => (\n <StreamMarkdownBlock\n components={streamingComponents}\n content={block.content}\n live={live && index === blocks.length - 1}\n revealLifecycle={revealLifecycle}\n revealScope={`${revealLifecycle.id}:${block.startOffset}`}\n remarkPlugins={remarkPlugins ?? defaultRemarkPlugins}\n remarkRehypeOptions={remarkRehypeOptions}\n key={block.startOffset}\n />\n )),\n \"data-anvia-stream-markdown\": \"\",\n \"data-live\": live ? \"\" : undefined,\n } as PrimitiveProps<\"div\">,\n ref,\n );\n },\n);\n\nconst StreamMarkdownBlock = memo(function StreamMarkdownBlock(props: {\n components: Components;\n content: string;\n live: boolean;\n revealLifecycle: StreamRevealLifecycle;\n revealScope: string;\n remarkPlugins: ReactMarkdownOptions[\"remarkPlugins\"];\n remarkRehypeOptions: ReactMarkdownOptions[\"remarkRehypeOptions\"];\n}) {\n const revealPlugin = useMemo(\n () => createStreamGradientRevealPlugin(props.revealScope, props.revealLifecycle),\n [props.revealScope, props.revealLifecycle],\n );\n return (\n <ReactMarkdown\n components={props.components}\n rehypePlugins={props.live ? [revealPlugin] : undefined}\n remarkPlugins={props.remarkPlugins}\n remarkRehypeOptions={props.remarkRehypeOptions}\n >\n {props.content}\n </ReactMarkdown>\n );\n});\n\nfunction withStreamRevealComponent(\n components: Components | undefined,\n onRevealSettled: (revealId: string) => void,\n): Components {\n const consumerSpan = components?.span;\n return {\n ...components,\n span(spanProps) {\n const safeProps = componentPropsWithoutKey(spanProps);\n const internalProps = safeProps as typeof safeProps & {\n \"data-anvia-stream-duration-ms\"?: string | undefined;\n \"data-anvia-stream-opacity\"?: string | undefined;\n \"data-anvia-stream-reveal\"?: string | undefined;\n \"data-anvia-stream-reveal-id\"?: string | undefined;\n };\n if (internalProps[\"data-anvia-stream-reveal\"] !== undefined) {\n return streamRevealSpan(internalProps, onRevealSettled);\n }\n if (consumerSpan !== undefined) {\n return createElement(consumerSpan, safeProps);\n }\n const { node: _node, ...elementProps } = safeProps;\n return <span {...elementProps} />;\n },\n };\n}\n\nfunction componentPropsWithoutKey<T extends object>(props: T): T {\n const result: Record<string, unknown> = {};\n for (const name of Object.keys(props)) {\n if (name !== \"key\") {\n result[name] = (props as Record<string, unknown>)[name];\n }\n }\n return result as T;\n}\n\nfunction streamRevealSpan(\n props: ComponentPropsWithoutRef<\"span\"> & {\n node?: unknown;\n \"data-anvia-stream-duration-ms\"?: string | undefined;\n \"data-anvia-stream-opacity\"?: string | undefined;\n \"data-anvia-stream-reveal\"?: string | undefined;\n \"data-anvia-stream-reveal-id\"?: string | undefined;\n },\n onRevealSettled: (revealId: string) => void,\n): ReactNode {\n const {\n children,\n node: _node,\n \"data-anvia-stream-duration-ms\": durationMs,\n \"data-anvia-stream-opacity\": opacity,\n \"data-anvia-stream-reveal-id\": revealId,\n onAnimationEnd,\n ...elementProps\n } = props;\n const parsedOpacity = Number(opacity);\n const parsedDurationMs = Number(durationMs);\n return (\n <span\n {...elementProps}\n data-anvia-stream-reveal-id={revealId}\n key={revealId ?? \"stream-reveal\"}\n onAnimationEnd={(event) => {\n onAnimationEnd?.(event);\n if (revealId !== undefined) onRevealSettled(revealId);\n }}\n style={\n {\n \"--anvia-stream-reveal-opacity\": Number.isFinite(parsedOpacity) ? parsedOpacity : 1,\n \"--anvia-stream-reveal-duration\": `${Number.isFinite(parsedDurationMs) ? parsedDurationMs : 180}ms`,\n } as CSSProperties\n }\n >\n {children}\n </span>\n );\n}\n","import { lexer } from \"marked\";\n\nexport type StreamMarkdownBlock = {\n content: string;\n startOffset: number;\n};\n\nexport function splitStreamMarkdownBlocks(\n content: string,\n options: { singleDocument?: boolean } = {},\n): StreamMarkdownBlock[] {\n if (content.length === 0) {\n return [];\n }\n if (options.singleDocument === true) {\n return [{ content, startOffset: 0 }];\n }\n\n try {\n const tokens = lexer(content, { gfm: false });\n if (tokens.some((token) => token.type === \"def\") || Object.keys(tokens.links).length > 0) {\n return [{ content, startOffset: 0 }];\n }\n\n const rawBlocks: string[] = [];\n for (const token of tokens) {\n if (token.type === \"space\" && rawBlocks.length > 0) {\n const lastIndex = rawBlocks.length - 1;\n rawBlocks[lastIndex] = `${rawBlocks[lastIndex] ?? \"\"}${token.raw}`;\n } else {\n rawBlocks.push(token.raw);\n }\n }\n\n if (rawBlocks.length === 0 || rawBlocks.join(\"\") !== content) {\n return [{ content, startOffset: 0 }];\n }\n\n let startOffset = 0;\n return rawBlocks.map((block) => {\n const result = { content: block, startOffset };\n startOffset += block.length;\n return result;\n });\n } catch {\n return [{ content, startOffset: 0 }];\n }\n}\n","export const streamRevealConfig = {\n bandGraphemes: 2,\n durationMs: 180,\n minimumOpacity: 0.12,\n tailGraphemes: 24,\n} as const;\n\nexport type StreamRevealLifecycle = {\n activeScope: string | null;\n settledRevealIds: Set<string>;\n startedAtByRevealId: Map<string, number>;\n};\n\ntype MarkdownNode = {\n type: string;\n tagName?: string;\n value?: string;\n properties?: Record<string, unknown>;\n children?: MarkdownNode[];\n};\n\ntype TextTarget = {\n endOffset: number;\n index: number;\n node: MarkdownNode;\n parent: MarkdownNode;\n startOffset: number;\n};\n\ntype RevealGrapheme = {\n endOffset: number;\n opacity: number;\n startOffset: number;\n};\n\nexport function createStreamGradientRevealPlugin(\n lifecycleScope: string,\n lifecycle: StreamRevealLifecycle,\n) {\n return function streamGradientRevealPlugin() {\n return (tree: MarkdownNode) => {\n if (lifecycle.activeScope !== lifecycleScope) {\n lifecycle.activeScope = lifecycleScope;\n lifecycle.settledRevealIds.clear();\n lifecycle.startedAtByRevealId.clear();\n }\n const targets = collectTextTargets(tree);\n const renderedText = targets.map((target) => target.node.value ?? \"\").join(\"\");\n const graphemes = createRevealGraphemes(renderedText);\n wrapStreamRevealGraphemes(targets, graphemes, lifecycleScope, lifecycle);\n };\n };\n}\n\nfunction collectTextTargets(tree: MarkdownNode): TextTarget[] {\n const targets: TextTarget[] = [];\n let offset = 0;\n\n function visit(node: MarkdownNode, parent: MarkdownNode | undefined, index: number): void {\n if (node.type === \"element\" && node.tagName === \"pre\") {\n return;\n }\n if (node.type === \"text\" && node.value !== undefined && parent !== undefined) {\n if (!/\\S/u.test(node.value)) {\n return;\n }\n const startOffset = offset;\n offset += node.value.length;\n targets.push({\n endOffset: offset,\n index,\n node,\n parent,\n startOffset,\n });\n return;\n }\n for (const [childIndex, child] of (node.children ?? []).entries()) {\n visit(child, node, childIndex);\n }\n }\n\n visit(tree, undefined, 0);\n return targets;\n}\n\nfunction createRevealGraphemes(content: string): RevealGrapheme[] {\n const tail = segmentTailGraphemeRanges(content, streamRevealConfig.tailGraphemes);\n const graphemes: RevealGrapheme[] = [];\n\n for (let index = 0; index < tail.length; index += 1) {\n const grapheme = tail[index];\n const bandStartIndex =\n Math.floor(index / streamRevealConfig.bandGraphemes) * streamRevealConfig.bandGraphemes;\n const bandEndIndex =\n Math.min(bandStartIndex + streamRevealConfig.bandGraphemes, tail.length) - 1;\n if (grapheme === undefined) {\n continue;\n }\n const progress = tail.length === 1 ? 1 : bandEndIndex / (tail.length - 1);\n graphemes.push({\n startOffset: grapheme.startOffset,\n endOffset: grapheme.endOffset,\n opacity: Math.max(\n streamRevealConfig.minimumOpacity,\n 1 - progress * (1 - streamRevealConfig.minimumOpacity),\n ),\n });\n }\n return graphemes;\n}\n\nfunction wrapStreamRevealGraphemes(\n targets: readonly TextTarget[],\n graphemes: readonly RevealGrapheme[],\n lifecycleScope: string,\n lifecycle: StreamRevealLifecycle,\n): void {\n const activeRevealIds = new Set<string>();\n const nowMs = Date.now();\n for (const target of [...targets].reverse()) {\n const value = target.node.value ?? \"\";\n const intersectingGraphemes = graphemes.filter(\n (grapheme) =>\n grapheme.endOffset > target.startOffset && grapheme.startOffset < target.endOffset,\n );\n if (intersectingGraphemes.length === 0) {\n continue;\n }\n\n const replacement: MarkdownNode[] = [];\n let cursor = 0;\n for (const grapheme of intersectingGraphemes) {\n const start = Math.max(0, grapheme.startOffset - target.startOffset);\n const end = Math.min(value.length, grapheme.endOffset - target.startOffset);\n if (start > cursor) {\n replacement.push({ type: \"text\", value: value.slice(cursor, start) });\n }\n if (end > start) {\n const text = value.slice(start, end);\n const absoluteStart = target.startOffset + start;\n const absoluteEnd = target.startOffset + end;\n const revealId = `${lifecycleScope}:${absoluteStart}:${absoluteEnd}:${hashText(text)}`;\n activeRevealIds.add(revealId);\n const startedAt = lifecycle.startedAtByRevealId.get(revealId) ?? nowMs;\n lifecycle.startedAtByRevealId.set(revealId, startedAt);\n const elapsedMs = Math.max(0, nowMs - startedAt);\n if (elapsedMs >= streamRevealConfig.durationMs) {\n lifecycle.settledRevealIds.add(revealId);\n }\n if (lifecycle.settledRevealIds.has(revealId)) {\n replacement.push({ type: \"text\", value: text });\n } else {\n const progress = Math.min(elapsedMs / streamRevealConfig.durationMs, 1);\n const opacity = grapheme.opacity + (1 - grapheme.opacity) * progress;\n const remainingMs = Math.max(1, streamRevealConfig.durationMs - elapsedMs);\n replacement.push({\n type: \"element\",\n tagName: \"span\",\n properties: {\n \"data-anvia-stream-duration-ms\": String(remainingMs),\n \"data-anvia-stream-opacity\": String(opacity),\n \"data-anvia-stream-reveal\": \"\",\n \"data-anvia-stream-reveal-id\": revealId,\n },\n children: [{ type: \"text\", value: text }],\n });\n }\n }\n cursor = Math.max(cursor, end);\n }\n if (cursor < value.length) {\n replacement.push({ type: \"text\", value: value.slice(cursor) });\n }\n target.parent.children?.splice(target.index, 1, ...replacement);\n }\n\n pruneRevealLifecycle(lifecycle, activeRevealIds);\n}\n\nfunction pruneRevealLifecycle(\n lifecycle: StreamRevealLifecycle,\n activeRevealIds: ReadonlySet<string>,\n): void {\n for (const revealId of lifecycle.startedAtByRevealId.keys()) {\n if (!activeRevealIds.has(revealId)) lifecycle.startedAtByRevealId.delete(revealId);\n }\n for (const revealId of lifecycle.settledRevealIds) {\n if (!activeRevealIds.has(revealId)) lifecycle.settledRevealIds.delete(revealId);\n }\n}\n\nfunction hashText(text: string): string {\n let hash = 2_166_136_261;\n for (let index = 0; index < text.length; index += 1) {\n hash ^= text.charCodeAt(index);\n hash = Math.imul(hash, 16_777_619);\n }\n return (hash >>> 0).toString(36);\n}\n\nfunction segmentTailGraphemeRanges(\n content: string,\n limit: number,\n): Array<{\n endOffset: number;\n startOffset: number;\n}> {\n if (typeof Intl !== \"undefined\" && typeof Intl.Segmenter === \"function\") {\n const segmenter = new Intl.Segmenter(undefined, { granularity: \"grapheme\" });\n const segments = segmenter.segment(content);\n const ranges: Array<{ endOffset: number; startOffset: number }> = [];\n let cursor = content.length;\n while (cursor > 0 && ranges.length < limit) {\n const segment = segments.containing(cursor - 1);\n if (segment === undefined) {\n break;\n }\n ranges.unshift({\n startOffset: segment.index,\n endOffset: segment.index + segment.segment.length,\n });\n cursor = segment.index;\n }\n return ranges;\n }\n\n const ranges: Array<{ endOffset: number; startOffset: number }> = [];\n let cursor = content.length;\n while (cursor > 0 && ranges.length < limit) {\n let startOffset = cursor - 1;\n const code = content.charCodeAt(startOffset);\n if (code >= 0xdc00 && code <= 0xdfff && startOffset > 0) {\n const previousCode = content.charCodeAt(startOffset - 1);\n if (previousCode >= 0xd800 && previousCode <= 0xdbff) {\n startOffset -= 1;\n }\n }\n ranges.unshift({ startOffset, endOffset: cursor });\n cursor = startOffset;\n }\n return ranges;\n}\n"],"mappings":"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","names":["ranges","cursor","createElement","StreamMarkdown","StreamMarkdownBlock"]}
|
package/dist/index.js
CHANGED
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
import {
|
|
9
9
|
Composer,
|
|
10
10
|
Thread
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-FABSIZZ7.js";
|
|
12
12
|
import {
|
|
13
13
|
Completion
|
|
14
14
|
} from "./chunk-VEYJNQVW.js";
|
|
@@ -20,10 +20,10 @@ import {
|
|
|
20
20
|
} from "./chunk-7HR34SOF.js";
|
|
21
21
|
import {
|
|
22
22
|
Message
|
|
23
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-JWZDNM5D.js";
|
|
24
24
|
import {
|
|
25
25
|
StreamMarkdown
|
|
26
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-ULGJLLZE.js";
|
|
27
27
|
import {
|
|
28
28
|
Attachment
|
|
29
29
|
} from "./chunk-SBYUKODG.js";
|
package/dist/message/index.js
CHANGED
package/dist/stream/index.js
CHANGED
package/dist/stream/styles.css
CHANGED
|
@@ -5,5 +5,13 @@
|
|
|
5
5
|
}
|
|
6
6
|
|
|
7
7
|
[data-anvia-stream-reveal] {
|
|
8
|
-
|
|
8
|
+
opacity: var(--anvia-stream-reveal-opacity, 1);
|
|
9
|
+
animation: anvia-stream-gradient-settle var(--anvia-stream-reveal-duration, 180ms) linear both;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
@media (prefers-reduced-motion: reduce) {
|
|
13
|
+
[data-anvia-stream-reveal] {
|
|
14
|
+
opacity: 1;
|
|
15
|
+
animation: none;
|
|
16
|
+
}
|
|
9
17
|
}
|
package/dist/styles.css
CHANGED
|
@@ -96,11 +96,13 @@
|
|
|
96
96
|
}
|
|
97
97
|
|
|
98
98
|
[data-anvia-stream-reveal] {
|
|
99
|
-
|
|
99
|
+
opacity: var(--anvia-stream-reveal-opacity, 1);
|
|
100
|
+
animation: anvia-stream-gradient-settle var(--anvia-stream-reveal-duration, 180ms) linear both;
|
|
100
101
|
}
|
|
101
102
|
|
|
102
103
|
@media (prefers-reduced-motion: reduce) {
|
|
103
104
|
[data-anvia-stream-reveal] {
|
|
105
|
+
opacity: 1;
|
|
104
106
|
animation: none;
|
|
105
107
|
}
|
|
106
108
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@anvia/react-ui",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.3",
|
|
4
4
|
"description": "Composable React UI primitives for Anvia chat and completion experiences.",
|
|
5
5
|
"author": "anvia",
|
|
6
6
|
"maintainer": "Indra Zulfi",
|
|
@@ -100,7 +100,7 @@
|
|
|
100
100
|
"tsup": "^8.5.0",
|
|
101
101
|
"typescript": "^5.9.3",
|
|
102
102
|
"vitest": "^4.0.8",
|
|
103
|
-
"@anvia/react": "0.
|
|
103
|
+
"@anvia/react": "0.10.3"
|
|
104
104
|
},
|
|
105
105
|
"scripts": {
|
|
106
106
|
"build": "tsup src/index.ts src/attachment/index.ts src/chat/index.ts src/completion/index.ts src/human-input/index.ts src/image/index.ts src/message/index.ts src/selection-toolbar/index.ts src/shared.ts src/stream/index.ts src/thread-list/index.ts --format esm --dts --sourcemap --clean --external react --external react-dom && cp src/styles.css dist/styles.css && cp src/stream/styles.css dist/stream/styles.css",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/stream/markdown.tsx","../src/stream/markdown-blocks.ts","../src/stream/markdown-reveal.ts"],"sourcesContent":["import {\n type ComponentPropsWithoutRef,\n createElement,\n forwardRef,\n memo,\n type ReactNode,\n useMemo,\n useRef,\n} from \"react\";\nimport ReactMarkdown, {\n type Components,\n type Options as ReactMarkdownOptions,\n} from \"react-markdown\";\nimport remarkGfm from \"remark-gfm\";\n\nimport { type PrimitiveProps, renderPrimitive } from \"../primitives\";\nimport { splitStreamMarkdownBlocks } from \"./markdown-blocks\";\nimport { createStreamGradientRevealPlugin } from \"./markdown-reveal\";\n\nexport type StreamMarkdownProps = Omit<PrimitiveProps<\"div\">, \"children\"> & {\n components?: Components;\n content: string;\n live?: boolean;\n remarkPlugins?: ReactMarkdownOptions[\"remarkPlugins\"];\n remarkRehypeOptions?: ReactMarkdownOptions[\"remarkRehypeOptions\"];\n};\n\nconst defaultRemarkPlugins: NonNullable<ReactMarkdownOptions[\"remarkPlugins\"]> = [remarkGfm];\n\nexport const StreamMarkdown = forwardRef<HTMLDivElement, StreamMarkdownProps>(\n function StreamMarkdown(\n { components, content, live = false, remarkPlugins, remarkRehypeOptions, ...props },\n ref,\n ) {\n const previousContentRef = useRef(content);\n const frameIdRef = useRef(0);\n if (previousContentRef.current !== content) {\n previousContentRef.current = content;\n frameIdRef.current += 1;\n }\n\n const blocks = useMemo(\n () =>\n splitStreamMarkdownBlocks(content, {\n singleDocument: remarkPlugins !== undefined,\n }),\n [content, remarkPlugins],\n );\n const streamingComponents = useMemo(() => withStreamRevealComponent(components), [components]);\n\n return renderPrimitive(\n \"div\",\n {\n ...props,\n children: blocks.map((block, index) => (\n <StreamMarkdownBlock\n components={streamingComponents}\n content={block.content}\n frameId={live && index === blocks.length - 1 ? frameIdRef.current : 0}\n live={live && index === blocks.length - 1}\n remarkPlugins={remarkPlugins ?? defaultRemarkPlugins}\n remarkRehypeOptions={remarkRehypeOptions}\n key={block.startOffset}\n />\n )),\n \"data-anvia-stream-markdown\": \"\",\n \"data-live\": live ? \"\" : undefined,\n } as PrimitiveProps<\"div\">,\n ref,\n );\n },\n);\n\nconst StreamMarkdownBlock = memo(function StreamMarkdownBlock(props: {\n components: Components;\n content: string;\n frameId: number;\n live: boolean;\n remarkPlugins: ReactMarkdownOptions[\"remarkPlugins\"];\n remarkRehypeOptions: ReactMarkdownOptions[\"remarkRehypeOptions\"];\n}) {\n const revealPlugin = useMemo(\n () => createStreamGradientRevealPlugin(props.frameId),\n [props.frameId],\n );\n return (\n <ReactMarkdown\n components={props.components}\n rehypePlugins={props.live ? [revealPlugin] : undefined}\n remarkPlugins={props.remarkPlugins}\n remarkRehypeOptions={props.remarkRehypeOptions}\n >\n {props.content}\n </ReactMarkdown>\n );\n});\n\nfunction withStreamRevealComponent(components: Components | undefined): Components {\n const consumerSpan = components?.span;\n return {\n ...components,\n span(spanProps) {\n const safeProps = componentPropsWithoutKey(spanProps);\n const internalProps = safeProps as typeof safeProps & {\n \"data-anvia-stream-frame-id\"?: string | undefined;\n \"data-anvia-stream-opacity\"?: string | undefined;\n \"data-anvia-stream-reveal\"?: string | undefined;\n };\n if (internalProps[\"data-anvia-stream-reveal\"] !== undefined) {\n return streamRevealSpan(internalProps);\n }\n if (consumerSpan !== undefined) {\n return createElement(consumerSpan, safeProps);\n }\n const { node: _node, ...elementProps } = safeProps;\n return <span {...elementProps} />;\n },\n };\n}\n\nfunction componentPropsWithoutKey<T extends object>(props: T): T {\n const result: Record<string, unknown> = {};\n for (const name of Object.keys(props)) {\n if (name !== \"key\") {\n result[name] = (props as Record<string, unknown>)[name];\n }\n }\n return result as T;\n}\n\nfunction streamRevealSpan(\n props: ComponentPropsWithoutRef<\"span\"> & {\n node?: unknown;\n \"data-anvia-stream-frame-id\"?: string | undefined;\n \"data-anvia-stream-opacity\"?: string | undefined;\n \"data-anvia-stream-reveal\"?: string | undefined;\n },\n): ReactNode {\n const {\n children,\n node: _node,\n \"data-anvia-stream-frame-id\": frameId,\n \"data-anvia-stream-opacity\": opacity,\n ...elementProps\n } = props;\n const parsedOpacity = Number(opacity);\n return (\n <span\n {...elementProps}\n data-anvia-stream-frame-id={frameId}\n key={frameId ?? \"stream-frame\"}\n style={{ opacity: Number.isFinite(parsedOpacity) ? parsedOpacity : 1 }}\n >\n {children}\n </span>\n );\n}\n","import { lexer } from \"marked\";\n\nexport type StreamMarkdownBlock = {\n content: string;\n startOffset: number;\n};\n\nexport function splitStreamMarkdownBlocks(\n content: string,\n options: { singleDocument?: boolean } = {},\n): StreamMarkdownBlock[] {\n if (content.length === 0) {\n return [];\n }\n if (options.singleDocument === true) {\n return [{ content, startOffset: 0 }];\n }\n\n try {\n const tokens = lexer(content, { gfm: false });\n if (tokens.some((token) => token.type === \"def\") || Object.keys(tokens.links).length > 0) {\n return [{ content, startOffset: 0 }];\n }\n\n const rawBlocks: string[] = [];\n for (const token of tokens) {\n if (token.type === \"space\" && rawBlocks.length > 0) {\n const lastIndex = rawBlocks.length - 1;\n rawBlocks[lastIndex] = `${rawBlocks[lastIndex] ?? \"\"}${token.raw}`;\n } else {\n rawBlocks.push(token.raw);\n }\n }\n\n if (rawBlocks.length === 0 || rawBlocks.join(\"\") !== content) {\n return [{ content, startOffset: 0 }];\n }\n\n let startOffset = 0;\n return rawBlocks.map((block) => {\n const result = { content: block, startOffset };\n startOffset += block.length;\n return result;\n });\n } catch {\n return [{ content, startOffset: 0 }];\n }\n}\n","export const streamRevealConfig = {\n bandGraphemes: 2,\n minimumOpacity: 0.12,\n tailGraphemes: 24,\n} as const;\n\ntype MarkdownNode = {\n type: string;\n tagName?: string;\n value?: string;\n properties?: Record<string, unknown>;\n children?: MarkdownNode[];\n};\n\ntype TextTarget = {\n endOffset: number;\n index: number;\n node: MarkdownNode;\n parent: MarkdownNode;\n startOffset: number;\n};\n\ntype RevealBand = {\n endOffset: number;\n opacity: number;\n startOffset: number;\n};\n\nexport function createStreamGradientRevealPlugin(frameId: number) {\n return function streamGradientRevealPlugin() {\n return (tree: MarkdownNode) => {\n const targets = collectTextTargets(tree);\n const renderedText = targets.map((target) => target.node.value ?? \"\").join(\"\");\n const bands = createRevealBands(renderedText);\n wrapStreamRevealBands(targets, bands, frameId);\n };\n };\n}\n\nfunction collectTextTargets(tree: MarkdownNode): TextTarget[] {\n const targets: TextTarget[] = [];\n let offset = 0;\n\n function visit(node: MarkdownNode, parent: MarkdownNode | undefined, index: number): void {\n if (node.type === \"element\" && node.tagName === \"pre\") {\n return;\n }\n if (node.type === \"text\" && node.value !== undefined && parent !== undefined) {\n if (!/\\S/u.test(node.value)) {\n return;\n }\n const startOffset = offset;\n offset += node.value.length;\n targets.push({\n endOffset: offset,\n index,\n node,\n parent,\n startOffset,\n });\n return;\n }\n for (const [childIndex, child] of (node.children ?? []).entries()) {\n visit(child, node, childIndex);\n }\n }\n\n visit(tree, undefined, 0);\n return targets;\n}\n\nfunction createRevealBands(content: string): RevealBand[] {\n const tail = segmentTailGraphemeRanges(content, streamRevealConfig.tailGraphemes);\n const bands: RevealBand[] = [];\n\n for (let index = 0; index < tail.length; index += streamRevealConfig.bandGraphemes) {\n const first = tail[index];\n const endIndex = Math.min(index + streamRevealConfig.bandGraphemes, tail.length) - 1;\n const last = tail[endIndex];\n if (first === undefined || last === undefined) {\n continue;\n }\n const progress = tail.length === 1 ? 1 : endIndex / (tail.length - 1);\n bands.push({\n startOffset: first.startOffset,\n endOffset: last.endOffset,\n opacity: Math.max(\n streamRevealConfig.minimumOpacity,\n 1 - progress * (1 - streamRevealConfig.minimumOpacity),\n ),\n });\n }\n return bands;\n}\n\nfunction wrapStreamRevealBands(\n targets: readonly TextTarget[],\n bands: readonly RevealBand[],\n frameId: number,\n): void {\n for (const target of [...targets].reverse()) {\n const value = target.node.value ?? \"\";\n const intersectingBands = bands.filter(\n (band) => band.endOffset > target.startOffset && band.startOffset < target.endOffset,\n );\n if (intersectingBands.length === 0) {\n continue;\n }\n\n const replacement: MarkdownNode[] = [];\n let cursor = 0;\n for (const band of intersectingBands) {\n const start = Math.max(0, band.startOffset - target.startOffset);\n const end = Math.min(value.length, band.endOffset - target.startOffset);\n if (start > cursor) {\n replacement.push({ type: \"text\", value: value.slice(cursor, start) });\n }\n if (end > start) {\n replacement.push({\n type: \"element\",\n tagName: \"span\",\n properties: {\n \"data-anvia-stream-frame-id\": `${frameId}:${band.startOffset}`,\n \"data-anvia-stream-opacity\": String(band.opacity),\n \"data-anvia-stream-reveal\": \"\",\n },\n children: [{ type: \"text\", value: value.slice(start, end) }],\n });\n }\n cursor = Math.max(cursor, end);\n }\n if (cursor < value.length) {\n replacement.push({ type: \"text\", value: value.slice(cursor) });\n }\n target.parent.children?.splice(target.index, 1, ...replacement);\n }\n}\n\nfunction segmentTailGraphemeRanges(\n content: string,\n limit: number,\n): Array<{\n endOffset: number;\n startOffset: number;\n}> {\n if (typeof Intl !== \"undefined\" && typeof Intl.Segmenter === \"function\") {\n const segmenter = new Intl.Segmenter(undefined, { granularity: \"grapheme\" });\n const segments = segmenter.segment(content);\n const ranges: Array<{ endOffset: number; startOffset: number }> = [];\n let cursor = content.length;\n while (cursor > 0 && ranges.length < limit) {\n const segment = segments.containing(cursor - 1);\n if (segment === undefined) {\n break;\n }\n ranges.unshift({\n startOffset: segment.index,\n endOffset: segment.index + segment.segment.length,\n });\n cursor = segment.index;\n }\n return ranges;\n }\n\n const ranges: Array<{ endOffset: number; startOffset: number }> = [];\n let cursor = content.length;\n while (cursor > 0 && ranges.length < limit) {\n let startOffset = cursor - 1;\n const code = content.charCodeAt(startOffset);\n if (code >= 0xdc00 && code <= 0xdfff && startOffset > 0) {\n const previousCode = content.charCodeAt(startOffset - 1);\n if (previousCode >= 0xd800 && previousCode <= 0xdbff) {\n startOffset -= 1;\n }\n }\n ranges.unshift({ startOffset, endOffset: cursor });\n cursor = startOffset;\n }\n return ranges;\n}\n"],"mappings":"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","names":["ranges","cursor","createElement","StreamMarkdown","StreamMarkdownBlock"]}
|
|
File without changes
|
|
File without changes
|