@mailwoman/map-tui 10.0.0 → 10.1.0

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.
Files changed (58) hide show
  1. package/README.md +5 -6
  2. package/{lib/cli → cli}/args.ts +49 -28
  3. package/{lib/cli/index.ts → cli/main.ts} +12 -23
  4. package/lib/browser.ts +33 -76
  5. package/lib/frame.ts +50 -28
  6. package/lib/input.ts +46 -69
  7. package/lib/mercator.ts +13 -12
  8. package/lib/mvt.ts +2 -2
  9. package/lib/raster.ts +53 -27
  10. package/lib/renderer.ts +19 -38
  11. package/lib/style.ts +21 -15
  12. package/lib/tile-source.ts +30 -19
  13. package/out/browser.d.ts +24 -33
  14. package/out/browser.d.ts.map +1 -1
  15. package/out/browser.js +27 -72
  16. package/out/browser.js.map +1 -1
  17. package/out/cli/args.d.ts +18 -8
  18. package/out/cli/args.d.ts.map +1 -1
  19. package/out/cli/args.js +41 -25
  20. package/out/cli/args.js.map +1 -1
  21. package/out/cli/{index.d.ts → main.d.ts} +1 -1
  22. package/out/cli/main.d.ts.map +1 -0
  23. package/out/cli/{index.js → main.js} +13 -24
  24. package/out/cli/main.js.map +1 -0
  25. package/out/cli/tsconfig.tsbuildinfo +1 -0
  26. package/out/frame.d.ts +40 -23
  27. package/out/frame.d.ts.map +1 -1
  28. package/out/frame.js +48 -26
  29. package/out/frame.js.map +1 -1
  30. package/out/input.d.ts +18 -36
  31. package/out/input.d.ts.map +1 -1
  32. package/out/input.js +37 -63
  33. package/out/input.js.map +1 -1
  34. package/out/mercator.d.ts +12 -11
  35. package/out/mercator.d.ts.map +1 -1
  36. package/out/mercator.js +4 -10
  37. package/out/mercator.js.map +1 -1
  38. package/out/mvt.js +2 -2
  39. package/out/raster.d.ts +45 -23
  40. package/out/raster.d.ts.map +1 -1
  41. package/out/raster.js +44 -22
  42. package/out/raster.js.map +1 -1
  43. package/out/renderer.d.ts +6 -7
  44. package/out/renderer.d.ts.map +1 -1
  45. package/out/renderer.js +13 -22
  46. package/out/renderer.js.map +1 -1
  47. package/out/style.d.ts +17 -11
  48. package/out/style.d.ts.map +1 -1
  49. package/out/style.js +11 -9
  50. package/out/style.js.map +1 -1
  51. package/out/tile-source.d.ts +12 -8
  52. package/out/tile-source.d.ts.map +1 -1
  53. package/out/tile-source.js +21 -14
  54. package/out/tile-source.js.map +1 -1
  55. package/out/tsconfig.test.tsbuildinfo +1 -1
  56. package/package.json +35 -83
  57. package/out/cli/index.d.ts.map +0 -1
  58. package/out/cli/index.js.map +0 -1
package/lib/renderer.ts CHANGED
@@ -5,14 +5,8 @@
5
5
  */
6
6
 
7
7
  /**
8
- * Viewport-to-braille-frame renderer for map-tui's debug view.
9
- *
10
- * `MapRenderer.renderFrame` is the package's single public entry point: given a `Viewport` (center lon/lat, zoom, cell
11
- * columns/rows), it fetches the covering tiles from a `TileSource`, rasterizes styled geometry (./style.ts,
12
- * ./raster.ts) into a subpixel RGBA grid, converts that grid to braille cells (./frame.ts), then overlays collected
13
- * labels and marker/ring annotations on top. Draw order is fill → line → label per the layer style table, with overlays
14
- * (ring, labels, markers) layered afterward in that order — markers deliberately skip the label collision bitmap so a
15
- * requested marker always wins the cell.
8
+ * Draw order is fill → line → label per the layer style table, then overlays (ring, labels, markers),
9
+ * and markers deliberately skip the label collision bitmap so a requested marker always wins the cell.
16
10
  */
17
11
 
18
12
  import { clamp } from "@mailwoman/core/numeric"
@@ -55,8 +49,7 @@ const DEFAULT_MARKER_CHAR = "●"
55
49
  const DEFAULT_MARKER_COLOR: RGB = [255, 80, 80]
56
50
 
57
51
  /**
58
- * Minimum ring radius (in device pixels) worth drawing — smaller than this, the midpoint circle algorithm degenerates
59
- * to a single point or nothing useful.
52
+ * A ring radius below this many device pixels degenerates the midpoint circle algorithm to a single point.
60
53
  */
61
54
  const MIN_RING_RADIUS_PX = 2
62
55
 
@@ -72,24 +65,15 @@ interface PendingLabel {
72
65
  color: number
73
66
  }
74
67
 
75
- /**
76
- * Origin of the render's subpixel grid, in world (Mercator) pixels — everything projected onto the grid is offset by
77
- * this pair.
78
- */
79
68
  interface GridOrigin {
80
69
  x: number
81
70
  y: number
82
71
  }
83
72
 
84
73
  /**
85
- * Everything a point projection needs, bundled so the per-feature rasterizers below take one parameter instead of four
86
- * — that's what keeps `rasterizeFeature` under `max-params` (8) once `style`, `renderZoom`, and `pendingLabels` join
87
- * it. Threaded through as a value rather than closed over so those rasterizers stay free functions (no nesting inside
88
- * `renderFrame` deep enough to trip `max-depth`).
89
- *
90
- * `worldX`/`worldY` are the tile's top-left corner in render-zoom world pixels — for a native tile that is `tileX *
91
- * TILE_SIZE`, for an overzoomed parent it is scaled by the tile's span, so the projection needs no zoom arithmetic of
92
- * its own.
74
+ * Bundled so the per-feature rasterizers take one parameter instead of four,
75
+ * with `worldX`/`worldY` the tile's top-left corner in render-zoom world pixels —
76
+ * `tileX * TILE_SIZE` for a native tile, span-scaled for an overzoomed parent.
93
77
  */
94
78
  interface TileProjection {
95
79
  worldX: number
@@ -99,10 +83,9 @@ interface TileProjection {
99
83
  }
100
84
 
101
85
  /**
102
- * A tile chosen for a viewport slot: the native tile when the archive has one, otherwise the nearest ancestor that
103
- * exists. `span` is how many render-zoom world pixels the tile covers (`TILE_SIZE << dz` for an ancestor `dz` levels
104
- * up) — a spatially sparse archive (deep zooms only where people are) degrades to coarse geometry instead of blank
105
- * cells.
86
+ * A tile chosen for a viewport slot — the native tile when the archive has one,
87
+ * otherwise the nearest existing ancestor — with `span` the render-zoom world pixels
88
+ * it covers (`TILE_SIZE << dz` for an ancestor `dz` levels up).
106
89
  */
107
90
  interface ResolvedTile {
108
91
  tile: DecodedTile
@@ -166,9 +149,8 @@ function collectLabels(
166
149
  }
167
150
 
168
151
  /**
169
- * Rasterizes (or, for labels, collects) one feature under one style. The `style.kind` dispatch is the only branching
170
- * here — the actual per-kind work lives in {@link rasterizeFill}/{@link rasterizeLine}/{@link collectLabels} so this
171
- * stays a flat one-level `if`/`else` regardless of how deeply its caller is already nested.
152
+ * Rasterizes (or, for labels, collects) one feature under one style, keeping the `style.kind`
153
+ * dispatch as the only branching so this stays a flat one-level `if`/`else`.
172
154
  */
173
155
  function rasterizeFeature(
174
156
  grid: RGBAGrid,
@@ -188,8 +170,8 @@ function rasterizeFeature(
188
170
  }
189
171
 
190
172
  /**
191
- * Rasterizes every layer/style/feature in one tile matching `kind`. Pulled out of {@link MapRenderer.renderFrame} so
192
- * that method's own tile loop doesn't accumulate this function's three nested loops on top of its own.
173
+ * Pulled out of {@link MapRenderer.renderFrame} so its tile loop does not accumulate
174
+ * this function's three nested loops on top of its own.
193
175
  */
194
176
  function rasterizeTileForKind(
195
177
  grid: RGBAGrid,
@@ -222,9 +204,9 @@ function rasterizeTileForKind(
222
204
  }
223
205
 
224
206
  /**
225
- * Walks a viewport's rendering pipeline: tile fetch, style-ordered rasterization, braille conversion, then overlay
226
- * annotations (ring, labels, markers). One `MapRenderer` can render any number of viewports against the same
227
- * `TileSource` — it holds no per-frame state itself.
207
+ * Walks a viewport's rendering pipeline (tile fetch, style-ordered rasterization,
208
+ * braille conversion, then ring/label/marker overlays) and holds no per-frame state,
209
+ * so one instance can render any number of viewports against the same `TileSource`.
228
210
  */
229
211
  export class MapRenderer {
230
212
  private readonly source: TileProvider
@@ -234,10 +216,9 @@ export class MapRenderer {
234
216
  }
235
217
 
236
218
  /**
237
- * Resolves each viewport slot to its native tile or, when the archive has none — a spatially sparse deep band, a
238
- * zoom-capped extract — the nearest existing ancestor. Ancestors shared by several absent slots are deduplicated so
239
- * their geometry rasterizes once, and coarse tiles sort first so native detail paints over the fallback wherever both
240
- * cover a cell.
219
+ * Resolves each viewport slot to its native tile or the nearest existing ancestor,
220
+ * deduplicated so shared ancestors rasterize once and sorted coarse-first
221
+ * so native detail paints over the fallback.
241
222
  */
242
223
  private async resolveTiles(
243
224
  tileCoords: ReadonlyArray<{ x: number; y: number }>,
package/lib/style.ts CHANGED
@@ -7,17 +7,21 @@
7
7
  /**
8
8
  * Protomaps-basemap style table for the map-tui debug view.
9
9
  *
10
- * Defines fill, line, and label styles for each of the nine protomaps-basemap layers, restricted by zoom level. Color
11
- * palette calibrated for dark-terminal rendering: dim fills (read as stipple density via dithering), bright lines and
12
- * labels.
10
+ * Defines fill, line and label styles for the nine Protomaps basemap layers, restricted by zoom level.
11
+ * Color palette calibrated for dark-terminal rendering: dim fills
12
+ * (read as stipple density via dithering), bright lines and labels.
13
13
  */
14
14
 
15
15
  export type RGB = readonly [red: number, green: number, blue: number]
16
16
 
17
17
  /**
18
- * Fields shared by every style entry. `featureKinds` scopes an entry to features whose `kind` tile attribute is in the
19
- * list; an entry without it is the layer's catch-all. Entries are consulted in table order and the first match wins, so
20
- * kind-scoped entries precede the catch-all.
18
+ * Fields shared by every style entry.
19
+ *
20
+ * `featureKinds` scopes an entry to features whose `kind` tile attribute is in the list.
21
+ * An entry without it is the layer's catch-all.
22
+ *
23
+ * Entries are consulted in table order and the first match wins, so kind-scoped
24
+ * entries precede the catch-all.
21
25
  */
22
26
  interface StyleBase {
23
27
  color: RGB
@@ -46,10 +50,10 @@ const ROAD_WIDTH_THRESHOLD = 14
46
50
 
47
51
  const roadWidth = (zoom: number) => (zoom >= ROAD_WIDTH_THRESHOLD ? 2 : 1)
48
52
 
49
- // At braille scale every road is one dot wide and every fill is stipple, so CLASS has to ride on color instead of
50
- // geometry: arteries brighten toward amber, paths dim toward the vegetation green, and urban landuse runs warmer and
51
- // brighter than vegetation so a city reads as denser texture. Luminance is required — asciify's ordered dither
52
- // turns it into stipple density.
53
+ // At braille scale, each road is one dot wide and each fill is stippled.
54
+ // Color encodes class information: arteries brighten toward amber and paths dim toward vegetation green.
55
+ // Urban land use is warmer and brighter than vegetation, so cities read as denser texture.
56
+ // Luminance is required — asciify's ordered dither turns it into stipple density.
53
57
  const VEGETATION_KINDS = [
54
58
  "allotments",
55
59
  "cemetery",
@@ -92,17 +96,19 @@ const STYLE_TABLE: Record<string, LayerStyle[]> = {
92
96
  }
93
97
 
94
98
  /**
95
- * Styles applying to a protomaps-basemap layer at a zoom, draw-ordered (fills < lines < labels). Empty for unstyled or
96
- * zoom-restricted layers.
99
+ * Styles applying to a protomaps-basemap layer at a zoom, draw-ordered (fills < lines < labels).
100
+ *
101
+ * Empty for unstyled or zoom-restricted layers.
97
102
  */
98
103
  export function stylesFor(layerName: string, zoom: number): LayerStyle[] {
99
104
  return (STYLE_TABLE[layerName] ?? []).filter((style) => zoom >= style.minZoom)
100
105
  }
101
106
 
102
107
  /**
103
- * The one style painting a feature: the first entry whose `featureKinds` contains the feature's `kind` attribute, or
104
- * the first catch-all. A feature is painted at most once per draw pass — kind-scoped entries recolor, they never
105
- * double-paint.
108
+ * The one style painting a feature: the first entry whose `featureKinds` contains
109
+ * the feature's `kind` attribute, or the first catch-all.
110
+ *
111
+ * A feature is painted at most once per draw pass — kind-scoped entries recolor, they never double-paint.
106
112
  */
107
113
  export function styleForFeatureKind(styles: readonly LayerStyle[], featureKind: unknown): LayerStyle | null {
108
114
  for (const style of styles) {
@@ -7,12 +7,14 @@
7
7
  /**
8
8
  * PMTiles archive reader for map-tui.
9
9
  *
10
- * TileSource wraps a local `.pmtiles` file (node:fs/promises FileHandle) behind the pmtiles `Source` interface, decodes
11
- * each requested tile's MVT payload via ./mvt.ts, and keeps a small LRU cache of decoded tiles so repeated draws of the
12
- * same viewport don't re-decode.
10
+ * TileSource wraps a local `.pmtiles` file (node:fs/promises FileHandle) behind
11
+ * the pmtiles `Source` interface.
12
+ * It decodes each requested tile's MVT payload via ./mvt.ts and keeps a small LRU cache
13
+ * of decoded tiles so repeated draws of the same viewport don't re-decode.
13
14
  */
14
15
 
15
16
  import { type FileHandle, open } from "@mailwoman/core/fs/readers"
17
+ import { normalizeWhitespace } from "@mailwoman/core/strings/format"
16
18
  import { Parser } from "htmlparser2"
17
19
  import { PMTiles, type RangeResponse, type Source } from "pmtiles"
18
20
 
@@ -23,8 +25,10 @@ export interface DecodedTile {
23
25
  }
24
26
 
25
27
  /**
26
- * What a renderer needs from a tile archive — the read surface of {@link TileSource}, separated so a renderer can be
27
- * driven by any provider: a single archive, a stub in tests, or a composite over several archives.
28
+ * What a renderer needs from a tile archive.
29
+ *
30
+ * The read surface of {@link TileSource}, separated so a renderer can be driven by any
31
+ * provider: a single archive, a stub in tests, or a composite over several archives.
28
32
  */
29
33
  export interface TileProvider {
30
34
  readonly minZoom: number
@@ -57,7 +61,8 @@ class FilePMTilesSource implements Source {
57
61
  const TILE_CACHE_LIMIT = 64
58
62
 
59
63
  /**
60
- * Plain-text attribution out of archive metadata (HTML tags stripped, entities decoded); empty string when absent.
64
+ * Plain-text attribution out of archive metadata (html tags stripped, entities decoded);
65
+ * empty string when absent.
61
66
  */
62
67
  export function readAttribution(metadata: unknown): string {
63
68
  if (
@@ -73,10 +78,13 @@ export function readAttribution(metadata: unknown): string {
73
78
  }
74
79
 
75
80
  /**
76
- * Plain text out of an HTML fragment via `htmlparser2`'s event parser — a hand scan misreads `<` inside attribute
77
- * values and unclosed tags, and the parser's own entity decoding covers the full named set a metadata field can carry.
78
- * Local rather than `@mailwoman/core`'s `htmlToText`: this package stays standalone by design, and one attribution
79
- * string does not price core's shipped data into every consumer.
81
+ * Plain text out of an html fragment via `htmlparser2`'s event parser — a hand scan
82
+ * misreads `<` inside attribute values and unclosed tags.
83
+ *
84
+ * The parser's own entity decoding covers the full set of labels supported by the metadata field.
85
+ *
86
+ * Local rather than `@mailwoman/core`'s `htmlToText` because this package stays standalone by design.
87
+ * One attribution string should not add core's shipped data to every consumer.
80
88
  */
81
89
  function htmlText(html: string): string {
82
90
  let text = ""
@@ -86,13 +94,15 @@ function htmlText(html: string): string {
86
94
  parser.write(html)
87
95
  parser.end()
88
96
 
89
- return text.replaceAll(/\s+/gu, " ").trim()
97
+ return normalizeWhitespace(text)
90
98
  }
91
99
 
92
100
  /**
93
- * A single LRU cache slot. Wrapping the decoded tile in an object lets `getTile` tell "cached and known absent" (`{
94
- * tile: null }`) apart from "not yet cached" (no entry in the Map) using plain presence, with no comparison against
95
- * `undefined` needed.
101
+ * A single LRU cache slot.
102
+ *
103
+ * The decoded tile wrapper lets `getTile` distinguish "cached and known absent"
104
+ * (`{ tile: null }`) apart from "not yet cached" (no entry in the Map) using plain
105
+ * presence, with no comparison against `undefined` needed.
96
106
  */
97
107
  interface CacheEntry {
98
108
  tile: DecodedTile | null
@@ -103,12 +113,12 @@ export class TileSource implements TileProvider, AsyncDisposable {
103
113
  readonly maxZoom: number
104
114
 
105
115
  /**
106
- * Plain-text attribution from archive metadata (HTML tags stripped); empty string when absent.
116
+ * Plain-text attribution from archive metadata (html tags stripped); empty string when absent.
107
117
  */
108
118
  readonly attribution: string
109
119
 
110
120
  /**
111
- * Null for HTTP sources — fetch connections have no handle to hold or close.
121
+ * Null for http sources — fetch connections have no handle to hold or close.
112
122
  */
113
123
  private readonly handle: FileHandle | null
114
124
  private readonly pmtiles: PMTiles
@@ -129,8 +139,8 @@ export class TileSource implements TileProvider, AsyncDisposable {
129
139
  }
130
140
 
131
141
  /**
132
- * Opens a local `.pmtiles` path, or an `http(s)://` URL read via range requests — a hosted archive needs no tile
133
- * server, only a host honoring `Range` (any static file server or object store does).
142
+ * Opens a local `.pmtiles` path, or an `http(s)://` URL read via range requests — a hosted archive
143
+ * needs no tile server, only a host honoring `Range` (any static file server or object store does).
134
144
  */
135
145
  static async open(pathOrURL: string): Promise<TileSource> {
136
146
  if (/^https?:\/\//u.test(pathOrURL)) {
@@ -149,7 +159,8 @@ export class TileSource implements TileProvider, AsyncDisposable {
149
159
  }
150
160
 
151
161
  /**
152
- * Decoded tile, LRU-cached (64 entries). null = tile absent from the archive.
162
+ * Decoded tile, LRU-cached (64 entries).
163
+ * Null = tile absent from the archive.
153
164
  */
154
165
  async getTile(z: number, x: number, y: number): Promise<DecodedTile | null> {
155
166
  const key = `${z}/${x}/${y}`
package/out/browser.d.ts CHANGED
@@ -5,8 +5,8 @@
5
5
  */
6
6
  import type { TileSource } from "#tile-source";
7
7
  /**
8
- * The subset of a readable stream the browser drives. Structural so `process.stdin` satisfies it without the app being
9
- * welded to it — the same reasoning asciify applies to its own output type.
8
+ * The subset of a readable stream the browser uses, kept structural so that
9
+ * `process.stdin` and test doubles both satisfy it.
10
10
  */
11
11
  export interface BrowserInput {
12
12
  setRawMode?(mode: boolean): unknown;
@@ -17,7 +17,7 @@ export interface BrowserInput {
17
17
  off(event: "data", listener: (chunk: string) => void): unknown;
18
18
  }
19
19
  /**
20
- * The subset of a writable terminal the browser drives.
20
+ * The subset of a writable terminal the browser uses.
21
21
  */
22
22
  export interface BrowserOutput {
23
23
  write(chunk: string): unknown;
@@ -26,6 +26,9 @@ export interface BrowserOutput {
26
26
  on(event: "resize", listener: () => void): unknown;
27
27
  off(event: "resize", listener: () => void): unknown;
28
28
  }
29
+ /**
30
+ * Options for {@link MapBrowser}: the tile source, the terminal streams and the initial viewport.
31
+ */
29
32
  export interface MapBrowserOptions {
30
33
  source: TileSource;
31
34
  input: BrowserInput;
@@ -34,6 +37,10 @@ export interface MapBrowserOptions {
34
37
  lon: number;
35
38
  zoom: number;
36
39
  }
40
+ /**
41
+ * A full-screen terminal map browser built on `MapRenderer` that owns terminal modes,
42
+ * viewport state and output, leaving the bottom row as a status bar.
43
+ */
37
44
  export declare class MapBrowser {
38
45
  private readonly source;
39
46
  private readonly renderer;
@@ -53,69 +60,53 @@ export declare class MapBrowser {
53
60
  private error;
54
61
  private resolveExit;
55
62
  /**
56
- * The trailing bytes of the last chunk that could not be decoded yet — a sequence the kernel split across two reads.
57
- * Threading it back through `decodeInputChunk` is what keeps a split mouse report from being read as an Esc keypress
58
- * (which used to quit); the decoder itself stays pure.
63
+ * The next `decodeInputChunk` call receives trailing bytes from an incomplete escape sequence
64
+ * so a mouse report split across reads does not decode as an Esc keypress.
59
65
  */
60
66
  private pendingInput;
61
67
  private readonly onData;
62
68
  private readonly onResize;
63
69
  constructor(options: MapBrowserOptions);
64
70
  /**
65
- * Runs until the user quits, resolving with the process exit code (0 for a normal quit, 130 for Ctrl+C). The terminal
66
- * is restored before this resolves.
71
+ * Runs until the user quits, resolving with the exit code (0 for a normal quit, 130 for Ctrl+C)
72
+ * after the terminal is restored.
67
73
  */
68
74
  run(): Promise<number>;
69
75
  /**
70
- * Asks the browser to exit with a code. Safe to call from a signal handler, and a no-op once an exit is already under
71
- * way.
76
+ * Asks the browser to exit with a code, ignoring calls after the first
77
+ * so that a signal handler may call it.
72
78
  */
73
79
  requestExit(code: number): void;
74
- /**
75
- * Enters the alternate screen and takes over input. Paired with {@link restore}.
76
- */
77
80
  start(): void;
78
- /**
79
- * Puts the terminal back exactly as it was found. Idempotent: the normal exit path, a signal handler and a
80
- * process-level `exit` hook may each call it.
81
- */
82
81
  restore(): void;
83
82
  private handleInput;
84
83
  private panBySteps;
85
84
  /**
86
- * Moves the center by a cell delta, through world pixels so the step is the same distance on screen at every latitude
87
- * — the naive degrees-per-keypress version crawls at the equator and sprints near the poles.
85
+ * Moves the center by a cell delta in world pixels, so one step covers the
86
+ * same screen distance at every latitude.
88
87
  */
89
88
  private panByCells;
90
89
  private setCenter;
91
- /**
92
- * Longitude/latitude at the center of a pane cell.
93
- */
94
90
  private cellToLonLat;
95
91
  /**
96
- * Zooms one or more whole levels. With an anchor cell (the wheel's pointer), the center shifts so whatever was under
97
- * the pointer stays under it; without one, the pane center holds.
92
+ * Zooms by whole levels, shifting the center so the point under an anchor cell stays under it.
98
93
  */
99
94
  private zoomBy;
100
95
  private withinPane;
101
96
  private beginDrag;
102
97
  /**
103
- * Pans relative to where the drag STARTED, not the previous motion report. Accumulating per-report deltas would
104
- * drift, since each one is rounded to a whole cell.
98
+ * Pans relative to the drag's starting point, because summing per-report deltas
99
+ * would drift as each report is rounded to a whole cell.
105
100
  */
106
101
  private continueDrag;
107
102
  /**
108
- * A press and release with no motion between them is a click, which centers the map — mapscii's behavior, and the
109
- * reason centering waits for the release rather than acting on the press.
103
+ * A press and release without motion counts as a click that centers the map on the clicked cell.
110
104
  */
111
105
  private endDrag;
112
- /**
113
- * Reads the terminal's size and re-sizes the pane around the status bar.
114
- */
115
106
  private measure;
116
107
  /**
117
- * Requests a frame. Renders never overlap: a request arriving mid-render is coalesced into one more pass, so a held
118
- * arrow key queues a single redraw rather than a backlog of them.
108
+ * Requests a frame, collapsing requests that arrive during a render into one
109
+ * follow-up so renders never overlap.
119
110
  */
120
111
  private scheduleRender;
121
112
  private renderLoop;
@@ -1 +1 @@
1
- {"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../lib/browser.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../lib/browser.ts"],"names":[],"mappings":"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"}