@simon_he/vue-tui 1.1.13 → 1.1.15
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/agent.cjs +827 -24
- package/dist/agent.js +1 -1
- package/dist/experimental.cjs +16 -3
- package/dist/experimental.js +1 -1
- package/dist/markdown.cjs +811 -21
- package/dist/{tlog-theme-DKq1YOQF.js → tlog-theme-zAInqC2W.js} +46 -0
- package/package.json +9 -9
|
@@ -1787,6 +1787,20 @@ const EMPTY_LAYOUT = Object.freeze({
|
|
|
1787
1787
|
rowCount: 0
|
|
1788
1788
|
});
|
|
1789
1789
|
const MAX_KEYED_ROW_LAYOUT_CACHE_ENTRIES = 2048;
|
|
1790
|
+
/**
|
|
1791
|
+
* How far outside the drawn window a fixed-row transcript keeps a row's layout.
|
|
1792
|
+
*
|
|
1793
|
+
* The fixed-row path lays a frame's rows out on demand, so its cache is the one structure that
|
|
1794
|
+
* grows with a transcript nobody re-reads: a reply appended while the view follows the bottom draws
|
|
1795
|
+
* every one of its new rows exactly once, and without a retention margin every one of them stayed
|
|
1796
|
+
* for the life of the component (measured in an agent TUI: ~2 MB of retained layout per turn of
|
|
1797
|
+
* 152 KB of appended code). The margin is what makes releasing them safe to do: scrolling back
|
|
1798
|
+
* within it still finds its layouts, and a row that returns after it is laid out again on demand —
|
|
1799
|
+
* the same work its first draw did — while the retained row space stays bounded at the drawn window
|
|
1800
|
+
* plus this margin on each side. The wrapped path is untouched: it keeps its layouts for the whole
|
|
1801
|
+
* row space in `previousWrappedLayout`, which its incremental repaint reads.
|
|
1802
|
+
*/
|
|
1803
|
+
const RETAINED_ROW_LAYOUT_MARGIN_ROWS = 512;
|
|
1790
1804
|
function clamp$9(n, min, max) {
|
|
1791
1805
|
return Math.max(min, Math.min(max, n));
|
|
1792
1806
|
}
|
|
@@ -1957,6 +1971,8 @@ const TTranscriptView = defineComponent({
|
|
|
1957
1971
|
const focusedRegion = ref(null);
|
|
1958
1972
|
const rowLayoutCache = new Map();
|
|
1959
1973
|
const keyedRowLayoutCache = new Map();
|
|
1974
|
+
/** The retained row window the last release ran for (see `pruneRowLayoutCacheOutsideWindow`). */
|
|
1975
|
+
let retainedWindow = null;
|
|
1960
1976
|
let previousWrappedLayout = null;
|
|
1961
1977
|
let previousWrappedDeps = null;
|
|
1962
1978
|
let canUseWrappedChangedRangeRepaint = false;
|
|
@@ -2053,6 +2069,34 @@ const TTranscriptView = defineComponent({
|
|
|
2053
2069
|
function pruneRowLayoutCache(count) {
|
|
2054
2070
|
for (const rowIndex of rowLayoutCache.keys()) if (rowIndex >= count) rowLayoutCache.delete(rowIndex);
|
|
2055
2071
|
}
|
|
2072
|
+
/**
|
|
2073
|
+
* Drops the layouts of rows that scrolled out of the drawn window's retention margin.
|
|
2074
|
+
*
|
|
2075
|
+
* The alternative — letting the cache keep every row it ever laid out — makes a followed
|
|
2076
|
+
* transcript's retention follow its row space, without bound, so the release has to happen here,
|
|
2077
|
+
* where rows are laid out per frame on demand. A released row is laid out again when it is drawn
|
|
2078
|
+
* again, and its identity entry goes with it: that map holds the same entry object, so leaving it
|
|
2079
|
+
* behind would keep the row retained through the keyed cache instead of releasing it.
|
|
2080
|
+
*
|
|
2081
|
+
* The scan runs when the retained window changes, which is exactly when rows can fall out of it
|
|
2082
|
+
* (a jump, a scroll, a grown or shrunk row space); a repaint of the same window finds nothing to
|
|
2083
|
+
* release, so it does not pay for the walk.
|
|
2084
|
+
*/
|
|
2085
|
+
function pruneRowLayoutCacheOutsideWindow(count, top, bottom) {
|
|
2086
|
+
const start = Math.max(0, top - RETAINED_ROW_LAYOUT_MARGIN_ROWS);
|
|
2087
|
+
const end = Math.min(count, bottom + RETAINED_ROW_LAYOUT_MARGIN_ROWS);
|
|
2088
|
+
if (retainedWindow && retainedWindow.start === start && retainedWindow.end === end) return;
|
|
2089
|
+
retainedWindow = {
|
|
2090
|
+
start,
|
|
2091
|
+
end
|
|
2092
|
+
};
|
|
2093
|
+
for (const [rowIndex, entry] of rowLayoutCache) {
|
|
2094
|
+
if (rowIndex >= start && rowIndex < end) continue;
|
|
2095
|
+
const identity = rowLayoutIdentityKey(entry.rowKey, entry.rowVersion);
|
|
2096
|
+
if (keyedRowLayoutCache.get(identity) === entry) keyedRowLayoutCache.delete(identity);
|
|
2097
|
+
rowLayoutCache.delete(rowIndex);
|
|
2098
|
+
}
|
|
2099
|
+
}
|
|
2056
2100
|
function sameWrappedDeps(a, b) {
|
|
2057
2101
|
return Boolean(a) && a.width === b.width && a.baseStyle === b.baseStyle && a.hoverStyle === b.hoverStyle && a.focusStyle === b.focusStyle && a.hoverRegionId === b.hoverRegionId && a.focusedRegionId === b.focusedRegionId;
|
|
2058
2102
|
}
|
|
@@ -2135,6 +2179,7 @@ const TTranscriptView = defineComponent({
|
|
|
2135
2179
|
if (!count) {
|
|
2136
2180
|
rowLayoutCache.clear();
|
|
2137
2181
|
keyedRowLayoutCache.clear();
|
|
2182
|
+
retainedWindow = null;
|
|
2138
2183
|
previousWrappedLayout = null;
|
|
2139
2184
|
previousWrappedDeps = null;
|
|
2140
2185
|
if (perfEnabled) observability.framePerf.recordComponent({
|
|
@@ -2191,6 +2236,7 @@ const TTranscriptView = defineComponent({
|
|
|
2191
2236
|
visualRows[rowIndex] = row;
|
|
2192
2237
|
regions.push(...row.hitRegions);
|
|
2193
2238
|
}
|
|
2239
|
+
pruneRowLayoutCacheOutsideWindow(count, top, bottom);
|
|
2194
2240
|
} else {
|
|
2195
2241
|
const incremental = tryUpdateWrappedLayoutFromChangedRange(count, sourceChangedRange, wrappedDeps);
|
|
2196
2242
|
if (incremental) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@simon_he/vue-tui",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.15",
|
|
4
4
|
"description": "Vue 3 terminal UI components and renderers for browser DOM, CLI stdout, logs, markdown transcripts, and agent consoles",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"agent-console",
|
|
@@ -259,14 +259,14 @@
|
|
|
259
259
|
"access": "public"
|
|
260
260
|
},
|
|
261
261
|
"dependencies": {
|
|
262
|
-
"stream-markdown-parser": "1.2.
|
|
262
|
+
"stream-markdown-parser": "1.2.20"
|
|
263
263
|
},
|
|
264
264
|
"devDependencies": {
|
|
265
265
|
"@arethetypeswrong/core": "^0.18.5",
|
|
266
|
-
"@playwright/test": "^1.
|
|
266
|
+
"@playwright/test": "^1.64.0",
|
|
267
267
|
"@resvg/resvg-js": "^2.6.2",
|
|
268
268
|
"@types/node": "^18.19.130",
|
|
269
|
-
"@vitest/coverage-v8": "^4.1.
|
|
269
|
+
"@vitest/coverage-v8": "^4.1.11",
|
|
270
270
|
"beautiful-mermaid": "^1.1.3",
|
|
271
271
|
"bumpp": "^8.2.1",
|
|
272
272
|
"bun-webgpu": "0.1.7",
|
|
@@ -276,18 +276,18 @@
|
|
|
276
276
|
"lint-staged": "^13.3.0",
|
|
277
277
|
"mathjax-full": "^3.2.2",
|
|
278
278
|
"oxfmt": "^0.47.0",
|
|
279
|
-
"oxlint": "^1.
|
|
279
|
+
"oxlint": "^1.88.0",
|
|
280
280
|
"picocolors": "^1.1.1",
|
|
281
281
|
"pinia": "^3.0.4",
|
|
282
|
-
"publint": "^0.3.
|
|
282
|
+
"publint": "^0.3.25",
|
|
283
283
|
"rimraf": "^3.0.2",
|
|
284
284
|
"tsdown": "^0.9.9",
|
|
285
|
-
"tsx": "^4.23.
|
|
285
|
+
"tsx": "^4.23.15",
|
|
286
286
|
"typescript": "^5.9.3",
|
|
287
287
|
"vite": "8.0.16",
|
|
288
288
|
"vitepress": "^1.6.4",
|
|
289
|
-
"vitest": "^4.1.
|
|
290
|
-
"vue": "^3.5.
|
|
289
|
+
"vitest": "^4.1.11",
|
|
290
|
+
"vue": "^3.5.44"
|
|
291
291
|
},
|
|
292
292
|
"peerDependencies": {
|
|
293
293
|
"@resvg/resvg-js": "^2.6.2",
|