omk-tui 1.4.0 → 1.4.1
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/CHANGELOG.md +11 -0
- package/dist/components/editor.d.ts +3 -1
- package/dist/components/editor.d.ts.map +1 -1
- package/dist/components/editor.js +4 -7
- package/dist/components/editor.js.map +1 -1
- package/dist/editor-component.d.ts +2 -0
- package/dist/editor-component.d.ts.map +1 -1
- package/dist/editor-component.js.map +1 -1
- package/dist/tui.d.ts.map +1 -1
- package/dist/tui.js +2 -1
- package/dist/tui.js.map +1 -1
- package/dist/windowed-container.d.ts +61 -4
- package/dist/windowed-container.d.ts.map +1 -1
- package/dist/windowed-container.js +126 -127
- package/dist/windowed-container.js.map +1 -1
- package/dist/windowed-segments.d.ts +37 -0
- package/dist/windowed-segments.d.ts.map +1 -0
- package/dist/windowed-segments.js +133 -0
- package/dist/windowed-segments.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { releaseRenderCache, renderGeneration } from "./render-generation.js";
|
|
2
|
+
/**
|
|
3
|
+
* A frozen segment never grows past this many lines (a single larger child
|
|
4
|
+
* gets a segment of its own). Bounds the work of refreshing one changed child:
|
|
5
|
+
* only its segment's line buffer is rebuilt, never the whole frozen history.
|
|
6
|
+
*/
|
|
7
|
+
export const SEGMENT_MAX_LINES = 512;
|
|
8
|
+
/** Splice one child out of the segment table after `children[index]` was removed. */
|
|
9
|
+
export function dropFrozenChild(segments, index) {
|
|
10
|
+
for (const segment of segments) {
|
|
11
|
+
if (index < segment.from) {
|
|
12
|
+
segment.from -= 1;
|
|
13
|
+
}
|
|
14
|
+
else if (index < segment.from + segment.children.length) {
|
|
15
|
+
const j = index - segment.from;
|
|
16
|
+
let offset = 0;
|
|
17
|
+
for (let k = 0; k < j; k++)
|
|
18
|
+
offset += segment.lineCounts[k];
|
|
19
|
+
segment.lines.splice(offset, segment.lineCounts[j]);
|
|
20
|
+
segment.children.splice(j, 1);
|
|
21
|
+
segment.lineCounts.splice(j, 1);
|
|
22
|
+
segment.generations.splice(j, 1);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
for (let i = segments.length - 1; i >= 0; i--) {
|
|
26
|
+
if (segments[i].children.length === 0)
|
|
27
|
+
segments.splice(i, 1);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Drop unsettled segments and refresh children whose generation moved.
|
|
32
|
+
* Returns the kept segments, or null when a foreign edit of `children`
|
|
33
|
+
* invalidated every segment (the caller drops all state).
|
|
34
|
+
*/
|
|
35
|
+
export function reconcileSegments(segments, children, isSettled, width, stats) {
|
|
36
|
+
const kept = [];
|
|
37
|
+
for (const segment of segments) {
|
|
38
|
+
let dirty;
|
|
39
|
+
let settled = true;
|
|
40
|
+
for (let j = 0; j < segment.children.length; j++) {
|
|
41
|
+
const child = segment.children[j];
|
|
42
|
+
if (children[segment.from + j] !== child) {
|
|
43
|
+
// `children` was edited behind our back: nothing frozen can be trusted.
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
if (!isSettled(child)) {
|
|
47
|
+
settled = false;
|
|
48
|
+
break;
|
|
49
|
+
}
|
|
50
|
+
if (renderGeneration(child) !== segment.generations[j]) {
|
|
51
|
+
dirty ??= [];
|
|
52
|
+
dirty.push(j);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
if (!settled)
|
|
56
|
+
continue;
|
|
57
|
+
if (dirty)
|
|
58
|
+
refreshSegment(segment, dirty, width, stats);
|
|
59
|
+
kept.push(segment);
|
|
60
|
+
}
|
|
61
|
+
return kept;
|
|
62
|
+
}
|
|
63
|
+
function refreshSegment(segment, dirty, width, stats) {
|
|
64
|
+
const lines = [];
|
|
65
|
+
let offset = 0;
|
|
66
|
+
let next = 0;
|
|
67
|
+
for (let j = 0; j < segment.children.length; j++) {
|
|
68
|
+
const count = segment.lineCounts[j];
|
|
69
|
+
if (dirty[next] === j) {
|
|
70
|
+
next += 1;
|
|
71
|
+
const child = segment.children[j];
|
|
72
|
+
const fresh = child.render(width);
|
|
73
|
+
for (const line of fresh)
|
|
74
|
+
lines.push(line);
|
|
75
|
+
segment.lineCounts[j] = fresh.length;
|
|
76
|
+
segment.generations[j] = renderGeneration(child);
|
|
77
|
+
releaseRenderCache(child);
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
for (let l = offset; l < offset + count; l++)
|
|
81
|
+
lines.push(segment.lines[l]);
|
|
82
|
+
}
|
|
83
|
+
offset += count;
|
|
84
|
+
}
|
|
85
|
+
segment.lines = lines;
|
|
86
|
+
stats.refreshedChildren += dirty.length;
|
|
87
|
+
stats.refreshedSegments += 1;
|
|
88
|
+
}
|
|
89
|
+
/** Freeze settled live children that sit above the live-line budget. */
|
|
90
|
+
export function freezeAboveBudget(segments, children, isSettled, parts, partStarts, live, liveLines, budget) {
|
|
91
|
+
let acc = 0;
|
|
92
|
+
let liveStart = children.length;
|
|
93
|
+
for (let p = parts.length - 1; p >= 0; p--) {
|
|
94
|
+
acc += parts[p].length;
|
|
95
|
+
liveStart = partStarts[p];
|
|
96
|
+
if (acc >= budget)
|
|
97
|
+
break;
|
|
98
|
+
}
|
|
99
|
+
let segmentIndex = 0;
|
|
100
|
+
for (let n = 0; n < live.length && live[n] < liveStart; n++) {
|
|
101
|
+
const index = live[n];
|
|
102
|
+
const child = children[index];
|
|
103
|
+
if (!isSettled(child))
|
|
104
|
+
continue;
|
|
105
|
+
const lines = liveLines[n];
|
|
106
|
+
while (segmentIndex < segments.length && segments[segmentIndex].from < index)
|
|
107
|
+
segmentIndex += 1;
|
|
108
|
+
const previous = segments[segmentIndex - 1];
|
|
109
|
+
const generation = renderGeneration(child);
|
|
110
|
+
if (previous &&
|
|
111
|
+
previous.from + previous.children.length === index &&
|
|
112
|
+
previous.lines.length + lines.length <= SEGMENT_MAX_LINES) {
|
|
113
|
+
previous.children.push(child);
|
|
114
|
+
previous.lineCounts.push(lines.length);
|
|
115
|
+
previous.generations.push(generation);
|
|
116
|
+
for (const line of lines)
|
|
117
|
+
previous.lines.push(line);
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
const segment = {
|
|
121
|
+
from: index,
|
|
122
|
+
children: [child],
|
|
123
|
+
lineCounts: [lines.length],
|
|
124
|
+
generations: [generation],
|
|
125
|
+
lines: lines.slice(),
|
|
126
|
+
};
|
|
127
|
+
segments.splice(segmentIndex, 0, segment);
|
|
128
|
+
segmentIndex += 1;
|
|
129
|
+
}
|
|
130
|
+
releaseRenderCache(child);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
//# sourceMappingURL=windowed-segments.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"windowed-segments.js","sourceRoot":"","sources":["../src/windowed-segments.ts"],"names":[],"mappings":"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","sourcesContent":["import { releaseRenderCache, renderGeneration } from \"./render-generation.ts\";\nimport type { Component } from \"./tui.ts\";\n\n/**\n * A frozen segment never grows past this many lines (a single larger child\n * gets a segment of its own). Bounds the work of refreshing one changed child:\n * only its segment's line buffer is rebuilt, never the whole frozen history.\n */\nexport const SEGMENT_MAX_LINES = 512;\n\n/** Contiguous settled children whose rendered lines are reused verbatim. */\nexport type FrozenSegment = {\n\t/** Index in `children` of the first frozen child. */\n\tfrom: number;\n\t/** The frozen children themselves (identity-checked every frame). */\n\tchildren: Component[];\n\tlineCounts: number[];\n\t/** `getRenderGeneration()` of each child when its lines were taken. */\n\tgenerations: number[];\n\t/** Concatenation of the children's lines. */\n\tlines: string[];\n};\n\n/** Per-frame counters a refresh accumulates into. */\nexport type SegmentRefreshStats = { refreshedChildren: number; refreshedSegments: number };\n\ntype SettledCheck = (child: Component) => boolean;\n\n/** Splice one child out of the segment table after `children[index]` was removed. */\nexport function dropFrozenChild(segments: FrozenSegment[], index: number): void {\n\tfor (const segment of segments) {\n\t\tif (index < segment.from) {\n\t\t\tsegment.from -= 1;\n\t\t} else if (index < segment.from + segment.children.length) {\n\t\t\tconst j = index - segment.from;\n\t\t\tlet offset = 0;\n\t\t\tfor (let k = 0; k < j; k++) offset += segment.lineCounts[k];\n\t\t\tsegment.lines.splice(offset, segment.lineCounts[j]);\n\t\t\tsegment.children.splice(j, 1);\n\t\t\tsegment.lineCounts.splice(j, 1);\n\t\t\tsegment.generations.splice(j, 1);\n\t\t}\n\t}\n\tfor (let i = segments.length - 1; i >= 0; i--) {\n\t\tif (segments[i].children.length === 0) segments.splice(i, 1);\n\t}\n}\n\n/**\n * Drop unsettled segments and refresh children whose generation moved.\n * Returns the kept segments, or null when a foreign edit of `children`\n * invalidated every segment (the caller drops all state).\n */\nexport function reconcileSegments(\n\tsegments: FrozenSegment[],\n\tchildren: readonly Component[],\n\tisSettled: SettledCheck,\n\twidth: number,\n\tstats: SegmentRefreshStats,\n): FrozenSegment[] | null {\n\tconst kept: FrozenSegment[] = [];\n\tfor (const segment of segments) {\n\t\tlet dirty: number[] | undefined;\n\t\tlet settled = true;\n\t\tfor (let j = 0; j < segment.children.length; j++) {\n\t\t\tconst child = segment.children[j];\n\t\t\tif (children[segment.from + j] !== child) {\n\t\t\t\t// `children` was edited behind our back: nothing frozen can be trusted.\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tif (!isSettled(child)) {\n\t\t\t\tsettled = false;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (renderGeneration(child) !== segment.generations[j]) {\n\t\t\t\tdirty ??= [];\n\t\t\t\tdirty.push(j);\n\t\t\t}\n\t\t}\n\t\tif (!settled) continue;\n\t\tif (dirty) refreshSegment(segment, dirty, width, stats);\n\t\tkept.push(segment);\n\t}\n\treturn kept;\n}\n\nfunction refreshSegment(segment: FrozenSegment, dirty: number[], width: number, stats: SegmentRefreshStats): void {\n\tconst lines: string[] = [];\n\tlet offset = 0;\n\tlet next = 0;\n\tfor (let j = 0; j < segment.children.length; j++) {\n\t\tconst count = segment.lineCounts[j];\n\t\tif (dirty[next] === j) {\n\t\t\tnext += 1;\n\t\t\tconst child = segment.children[j];\n\t\t\tconst fresh = child.render(width);\n\t\t\tfor (const line of fresh) lines.push(line);\n\t\t\tsegment.lineCounts[j] = fresh.length;\n\t\t\tsegment.generations[j] = renderGeneration(child);\n\t\t\treleaseRenderCache(child);\n\t\t} else {\n\t\t\tfor (let l = offset; l < offset + count; l++) lines.push(segment.lines[l]);\n\t\t}\n\t\toffset += count;\n\t}\n\tsegment.lines = lines;\n\tstats.refreshedChildren += dirty.length;\n\tstats.refreshedSegments += 1;\n}\n\n/** Freeze settled live children that sit above the live-line budget. */\nexport function freezeAboveBudget(\n\tsegments: FrozenSegment[],\n\tchildren: readonly Component[],\n\tisSettled: SettledCheck,\n\tparts: string[][],\n\tpartStarts: number[],\n\tlive: number[],\n\tliveLines: string[][],\n\tbudget: number,\n): void {\n\tlet acc = 0;\n\tlet liveStart = children.length;\n\tfor (let p = parts.length - 1; p >= 0; p--) {\n\t\tacc += parts[p].length;\n\t\tliveStart = partStarts[p];\n\t\tif (acc >= budget) break;\n\t}\n\tlet segmentIndex = 0;\n\tfor (let n = 0; n < live.length && live[n] < liveStart; n++) {\n\t\tconst index = live[n];\n\t\tconst child = children[index];\n\t\tif (!isSettled(child)) continue;\n\t\tconst lines = liveLines[n];\n\t\twhile (segmentIndex < segments.length && segments[segmentIndex].from < index) segmentIndex += 1;\n\t\tconst previous = segments[segmentIndex - 1];\n\t\tconst generation = renderGeneration(child);\n\t\tif (\n\t\t\tprevious &&\n\t\t\tprevious.from + previous.children.length === index &&\n\t\t\tprevious.lines.length + lines.length <= SEGMENT_MAX_LINES\n\t\t) {\n\t\t\tprevious.children.push(child);\n\t\t\tprevious.lineCounts.push(lines.length);\n\t\t\tprevious.generations.push(generation);\n\t\t\tfor (const line of lines) previous.lines.push(line);\n\t\t} else {\n\t\t\tconst segment: FrozenSegment = {\n\t\t\t\tfrom: index,\n\t\t\t\tchildren: [child],\n\t\t\t\tlineCounts: [lines.length],\n\t\t\t\tgenerations: [generation],\n\t\t\t\tlines: lines.slice(),\n\t\t\t};\n\t\t\tsegments.splice(segmentIndex, 0, segment);\n\t\t\tsegmentIndex += 1;\n\t\t}\n\t\treleaseRenderCache(child);\n\t}\n}\n"]}
|