@lobehub/ui
Version:
Lobe UI is an open-source UI component library for building AIGC web apps
64 lines (63 loc) • 2.24 kB
JavaScript
import { STREAM_FADE_DURATION } from "@lobehub/streamdown";
//#region src/Highlighter/SyntaxHighlighter/tokenFade.ts
const MIN_GAP_MS = 16;
const MAX_GAP_MS = 160;
const MIN_CHAR_PACE_MS = 2;
const MAX_CHAR_PACE_MS = 18;
const createTokenFadeStore = () => ({
births: [],
lastCommitTs: 0,
styles: /* @__PURE__ */ new Map()
});
const clamp = (value, min, max) => Math.min(max, Math.max(min, value));
const RETOKENIZED_LINES = 2;
const markTokenBirths = (store, lines, now) => {
const lineStarts = [];
const tokens = [];
let offset = 0;
for (const [lineIndex, line] of lines.entries()) {
if (lineIndex > 0) offset += 1;
lineStarts.push(offset);
if (lineIndex >= lines.length - RETOKENIZED_LINES) for (const token of line) {
tokens.push({
length: token.content.length,
offset
});
offset += token.content.length;
}
else for (const token of line) offset += token.content.length;
}
const { births } = store;
const newChars = offset - births.length;
if (newChars > 0) {
const gapMs = store.lastCommitTs === 0 ? MIN_GAP_MS : clamp(now - store.lastCommitTs, MIN_GAP_MS, MAX_GAP_MS);
const pace = clamp(gapMs / newChars, MIN_CHAR_PACE_MS, MAX_CHAR_PACE_MS);
const cap = now + gapMs + STREAM_FADE_DURATION;
for (let i = births.length; i < offset; i++) {
const chained = i > 0 ? births[i - 1] + pace : now;
births.push(Math.min(cap, Math.max(chained, now)));
}
store.lastCommitTs = now;
}
for (const token of tokens) {
let birth = births[token.offset];
for (let i = token.offset + 1; i < token.offset + token.length; i++) if (births[i] < birth) birth = births[i];
for (let i = token.offset; i < token.offset + token.length; i++) births[i] = birth;
}
return lineStarts;
};
const resolveTokenFadeStyle = (store, offset, now) => {
const birth = store.births[offset];
const cached = store.styles.get(offset);
if (cached && cached.birth === birth) return cached.style;
const elapsed = now - birth;
const style = elapsed >= STREAM_FADE_DURATION ? null : { animationDelay: `${-elapsed}ms` };
store.styles.set(offset, {
birth,
style
});
return style;
};
//#endregion
export { createTokenFadeStore, markTokenBirths, resolveTokenFadeStyle };
//# sourceMappingURL=tokenFade.mjs.map