@mailwoman/map-tui 9.1.1 → 9.2.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.
package/out/input.js ADDED
@@ -0,0 +1,214 @@
1
+ /**
2
+ * @copyright Sister Software.
3
+ * @license AGPL-3.0
4
+ * @author Teffen Ellis, et al.
5
+ */
6
+ /**
7
+ * Terminal input decoding for the interactive map browser.
8
+ *
9
+ * `decodeInputChunk` turns a raw-mode stdin chunk into zero or more {@link MapTUIInput} events. It stays pure — the
10
+ * caller owns the only state there is, the unresolved trailing fragment the function hands back — so one chunk in gives
11
+ * the same events out every time.
12
+ *
13
+ * THE FALLBACK IS THE DANGEROUS PART. An ESC this decoder had no rule for used to mean "the Esc key", i.e. QUIT, which
14
+ * made every unrecognized escape sequence a quit: F1 (`ESC O P`), an OSC reply the terminal sends unasked (`ESC ] 11 ;
15
+ * rgb:… BEL`), and — worst, because it needs no exotic key at all — a mouse report split across two stdin reads, whose
16
+ * first half ends inside the sequence. So the fallback now separates three cases:
17
+ *
18
+ * - A sequence this decoder recognizes is consumed and acted on (arrows, SGR mouse).
19
+ * - A sequence it does NOT recognize is consumed WHOLE and ignored: CSI (`ESC [ … final`), SS3 (`ESC O final`), and the
20
+ * string family (OSC/DCS/SOS/PM/APC, terminated by BEL or ST). Re-scanning their bodies as characters is how a `q`
21
+ * inside a cursor-position report quit the app.
22
+ * - A chunk that ENDS mid-sequence — including a lone trailing ESC, which is byte-for-byte the start of one — is not
23
+ * decoded at all: it comes back as {@link DecodedInput.pending} for the caller to prepend to the next chunk. Quit is
24
+ * emitted only for an ESC that is neither, i.e. one whose following byte cannot continue a sequence.
25
+ *
26
+ * Holding costs a lone Esc keypress its effect until the next byte arrives. That is the right side of the trade for a
27
+ * browser whose advertised quit keys are `q` and Ctrl+C: the alternative is a drag ending the session because the
28
+ * kernel split a read.
29
+ *
30
+ * Mouse reports are SGR-encoded (DEC private mode 1006), which is what {@link MOUSE_ENABLE} asks for. Their coordinates
31
+ * are 1-based on the wire and 0-based in every event here — the off-by-one lives at this boundary and nowhere else.
32
+ */
33
+ /**
34
+ * Enables mouse reporting: button events (1000), drag/button-motion tracking (1002), and SGR extended coordinates
35
+ * (1006) so columns past 223 survive.
36
+ */
37
+ export const MOUSE_ENABLE = "\u001B[?1000h\u001B[?1002h\u001B[?1006h";
38
+ /**
39
+ * Disables mouse reporting, in the reverse order it was enabled.
40
+ */
41
+ export const MOUSE_DISABLE = "\u001B[?1006l\u001B[?1002l\u001B[?1000l";
42
+ const ESC = "\u001B";
43
+ const CTRL_C = "\u0003";
44
+ /* oxlint-disable no-control-regex -- ESC (U+001B) is the byte every pattern below exists to match. A decoder of
45
+ terminal escape sequences cannot avoid the control character the sequences are made of. */
46
+ /**
47
+ * SGR mouse report: `ESC [ < button ; column ; row (M|m)`, where `M` is a press/motion and `m` a release.
48
+ */
49
+ const MOUSE_SGR_PATTERN = /\u001B\[<(\d+);(\d+);(\d+)([Mm])/y;
50
+ /**
51
+ * Cursor keys, in both normal (`ESC [ A`) and application (`ESC O A`) modes — a terminal may be left in either.
52
+ */
53
+ const ARROW_PATTERN = /\u001B(?:\[|O)([ABCD])/y;
54
+ /**
55
+ * Any other CSI sequence, consumed whole and ignored. Without this, an unhandled sequence's body would be re-scanned as
56
+ * individual key presses, and a stray `q` inside one would quit the app.
57
+ */
58
+ const UNKNOWN_CSI_PATTERN = /\u001B\[[\d;<>?]*[\u0020-\u002F]*[\u0040-\u007E]/y;
59
+ /**
60
+ * Any other SS3 sequence (`ESC O <final>`) — F1–F4 on xterm, and the numeric keypad in application mode. Two bytes
61
+ * shorter than a CSI, and until this pattern existed the likeliest key on a keyboard to quit the browser by accident.
62
+ */
63
+ const UNKNOWN_SS3_PATTERN = /\u001BO[\u0040-\u007E]/y;
64
+ /**
65
+ * The string-sequence family: OSC (`ESC ]`), DCS (`ESC P`), SOS (`ESC X`), PM (`ESC ^`), APC (`ESC _`), each running to
66
+ * a BEL or an ST (`ESC \`). A terminal sends these UNASKED — an OSC colour or clipboard reply lands on stdin with no
67
+ * key pressed — so consuming them is not a nicety.
68
+ */
69
+ const STRING_SEQUENCE_PATTERN = /\u001B[P\]X^_][\s\S]*?(?:\u0007|\u001B\\)/y;
70
+ /**
71
+ * Every "unrecognized but complete" sequence, in the order they are tried. Sharing one list is what keeps a new
72
+ * sequence family from being added to the consumer and forgotten in the incomplete test below.
73
+ */
74
+ const UNRECOGNIZED_PATTERNS = [UNKNOWN_CSI_PATTERN, UNKNOWN_SS3_PATTERN, STRING_SEQUENCE_PATTERN];
75
+ /**
76
+ * A chunk that STOPS inside a sequence. The end-anchors are what make these "incomplete" rather than "unrecognized":
77
+ * each requires the WHOLE remainder of the chunk to be a legal prefix and nothing more. The first covers both a lone
78
+ * trailing ESC and an `ESC O` still waiting for its final byte.
79
+ */
80
+ const PARTIAL_PATTERNS = [/\u001BO?$/y, /\u001B\[[\d;<>?]*[\u0020-\u002F]*$/y, /\u001B[P\]X^_][^\u0007]*$/y];
81
+ /* oxlint-enable no-control-regex */
82
+ /**
83
+ * Wheel reports set bit 6 of the button field; the low bit then separates up (0) from down (1).
84
+ */
85
+ const WHEEL_FLAG = 64;
86
+ /**
87
+ * Motion reports set bit 5. With mode 1002 that means "moved with a button held" — a drag.
88
+ */
89
+ const MOTION_FLAG = 32;
90
+ const BUTTON_MASK = 3;
91
+ const LEFT_BUTTON = 0;
92
+ /**
93
+ * The longest fragment worth holding for the next chunk (64 KB). See the drop site: this bounds an unterminated string
94
+ * sequence, not a real key.
95
+ */
96
+ const MAX_PENDING_LENGTH = 65_536;
97
+ const ARROW_INPUTS = {
98
+ A: { kind: "pan", dx: 0, dy: -1 },
99
+ B: { kind: "pan", dx: 0, dy: 1 },
100
+ C: { kind: "pan", dx: 1, dy: 0 },
101
+ D: { kind: "pan", dx: -1, dy: 0 },
102
+ };
103
+ /**
104
+ * Single-character bindings. `a`/`z` are mapscii's zoom keys, `+`/`-` the ones every other map uses, and `hjkl` the vim
105
+ * pan set mapscii also accepts. `y` joins `z` for zoom-out because on a QWERTZ keyboard it sits where `z` does on
106
+ * QWERTY — mapscii binds both for the same reason.
107
+ */
108
+ const CHARACTER_INPUTS = {
109
+ q: { kind: "quit" },
110
+ Q: { kind: "quit" },
111
+ "+": { kind: "zoom", delta: 1 },
112
+ "=": { kind: "zoom", delta: 1 },
113
+ a: { kind: "zoom", delta: 1 },
114
+ "-": { kind: "zoom", delta: -1 },
115
+ _: { kind: "zoom", delta: -1 },
116
+ z: { kind: "zoom", delta: -1 },
117
+ y: { kind: "zoom", delta: -1 },
118
+ h: { kind: "pan", dx: -1, dy: 0 },
119
+ j: { kind: "pan", dx: 0, dy: 1 },
120
+ k: { kind: "pan", dx: 0, dy: -1 },
121
+ l: { kind: "pan", dx: 1, dy: 0 },
122
+ };
123
+ /**
124
+ * The length of the unrecognized-but-complete sequence at `index`, or null when there isn't one.
125
+ */
126
+ function consumeUnrecognized(buffer, index) {
127
+ for (const pattern of UNRECOGNIZED_PATTERNS) {
128
+ pattern.lastIndex = index;
129
+ if (pattern.exec(buffer))
130
+ return pattern.lastIndex;
131
+ }
132
+ return null;
133
+ }
134
+ /**
135
+ * True when everything from `index` to the end of the chunk is a legal PREFIX of a sequence — i.e. the terminal is
136
+ * mid-sequence and the rest is in the next read.
137
+ */
138
+ function isIncompleteSequence(buffer, index) {
139
+ for (const pattern of PARTIAL_PATTERNS) {
140
+ pattern.lastIndex = index;
141
+ if (pattern.exec(buffer))
142
+ return true;
143
+ }
144
+ return false;
145
+ }
146
+ /**
147
+ * Builds the event for one SGR mouse report.
148
+ */
149
+ function mouseInput(button, column, row, final) {
150
+ if (button & WHEEL_FLAG) {
151
+ return { kind: "wheel", delta: button & 1 ? -1 : 1, column, row };
152
+ }
153
+ if (final === "m")
154
+ return { kind: "release" };
155
+ if ((button & BUTTON_MASK) !== LEFT_BUTTON)
156
+ return null;
157
+ return button & MOTION_FLAG ? { kind: "drag", column, row } : { kind: "press", column, row };
158
+ }
159
+ /**
160
+ * Decodes one raw-mode stdin chunk into input events. Unrecognized bytes are dropped; an unresolved trailing escape
161
+ * fragment is returned rather than decoded, and the caller passes it back as `pending` with the next chunk.
162
+ */
163
+ export function decodeInputChunk(chunk, pending = "") {
164
+ const events = [];
165
+ const buffer = pending + chunk;
166
+ let index = 0;
167
+ while (index < buffer.length) {
168
+ const character = buffer[index];
169
+ if (character !== ESC) {
170
+ const input = character === CTRL_C ? { kind: "interrupt" } : CHARACTER_INPUTS[character];
171
+ if (input) {
172
+ events.push(input);
173
+ }
174
+ index += 1;
175
+ continue;
176
+ }
177
+ MOUSE_SGR_PATTERN.lastIndex = index;
178
+ const mouse = MOUSE_SGR_PATTERN.exec(buffer);
179
+ if (mouse) {
180
+ const input = mouseInput(Number(mouse[1]), Number(mouse[2]) - 1, Number(mouse[3]) - 1, mouse[4]);
181
+ if (input) {
182
+ events.push(input);
183
+ }
184
+ index = MOUSE_SGR_PATTERN.lastIndex;
185
+ continue;
186
+ }
187
+ ARROW_PATTERN.lastIndex = index;
188
+ const arrow = ARROW_PATTERN.exec(buffer);
189
+ if (arrow) {
190
+ events.push(ARROW_INPUTS[arrow[1]]);
191
+ index = ARROW_PATTERN.lastIndex;
192
+ continue;
193
+ }
194
+ const consumed = consumeUnrecognized(buffer, index);
195
+ if (consumed !== null) {
196
+ index = consumed;
197
+ continue;
198
+ }
199
+ // The buffer stops inside a sequence — hand the fragment back instead of guessing at it.
200
+ if (isIncompleteSequence(buffer, index)) {
201
+ const fragment = buffer.slice(index);
202
+ // …unless it has stopped being plausible. An unterminated string sequence would otherwise grow the held
203
+ // fragment for the life of the process. Dropping is the safe failure: it emits nothing, where flushing
204
+ // the fragment back through the decoder would read its body as keys, which is the bug this all exists
205
+ // for. The cap is generous because an OSC 52 clipboard reply is legitimately large.
206
+ return { events, pending: fragment.length > MAX_PENDING_LENGTH ? "" : fragment };
207
+ }
208
+ // An ESC whose next byte cannot continue a sequence: the Esc KEY.
209
+ events.push({ kind: "quit" });
210
+ index += 1;
211
+ }
212
+ return { events, pending: "" };
213
+ }
214
+ //# sourceMappingURL=input.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"input.js","sourceRoot":"","sources":["../input.ts"],"names":[],"mappings":"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"}
package/out/renderer.d.ts CHANGED
@@ -15,7 +15,7 @@
15
15
  */
16
16
  import { type MapFrame } from "./frame.ts";
17
17
  import { type RGB } from "./style.ts";
18
- import type { TileSource } from "./tile-source.ts";
18
+ import type { TileProvider } from "./tile-source.ts";
19
19
  export interface Viewport {
20
20
  centerLon: number;
21
21
  centerLat: number;
@@ -41,7 +41,14 @@ export interface RingSpec {
41
41
  */
42
42
  export declare class MapRenderer {
43
43
  private readonly source;
44
- constructor(source: TileSource);
44
+ constructor(source: TileProvider);
45
+ /**
46
+ * Resolves each viewport slot to its native tile or, when the archive has none — a spatially sparse deep band, a
47
+ * zoom-capped extract — the nearest existing ancestor. Ancestors shared by several absent slots are deduplicated so
48
+ * their geometry rasterizes once, and coarse tiles sort first so native detail paints over the fallback wherever both
49
+ * cover a cell.
50
+ */
51
+ private resolveTiles;
45
52
  renderFrame(viewport: Viewport, overlays?: {
46
53
  markers?: MarkerSpec[];
47
54
  ring?: RingSpec;
@@ -1 +1 @@
1
- {"version":3,"file":"renderer.d.ts","sourceRoot":"","sources":["../renderer.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;;;;;;GASG;AAEH,OAAO,EAAE,KAAK,QAAQ,EAA8C,MAAM,YAAY,CAAA;AAItF,OAAO,EAAmB,KAAK,GAAG,EAAa,MAAM,YAAY,CAAA;AACjE,OAAO,KAAK,EAAe,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAE/D,MAAM,WAAW,QAAQ;IACxB,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;CACZ;AAED,MAAM,WAAW,UAAU;IAC1B,GAAG,EAAE,MAAM,CAAA;IACX,GAAG,EAAE,MAAM,CAAA;IACX,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,GAAG,CAAA;CACX;AAED,MAAM,WAAW,QAAQ;IACxB,GAAG,EAAE,MAAM,CAAA;IACX,GAAG,EAAE,MAAM,CAAA;IACX,YAAY,EAAE,MAAM,CAAA;CACpB;AAgKD;;;;GAIG;AACH,qBAAa,WAAW;IACvB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAY;gBAEvB,MAAM,EAAE,UAAU;IAIxB,WAAW,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,UAAU,EAAE,CAAC;QAAC,IAAI,CAAC,EAAE,QAAQ,CAAA;KAAE,GAAG,OAAO,CAAC,QAAQ,CAAC;CAiFhH"}
1
+ {"version":3,"file":"renderer.d.ts","sourceRoot":"","sources":["../renderer.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;;;;;;GASG;AAEH,OAAO,EAAE,KAAK,QAAQ,EAA8C,MAAM,YAAY,CAAA;AAItF,OAAO,EAAmB,KAAK,GAAG,EAAkC,MAAM,YAAY,CAAA;AACtF,OAAO,KAAK,EAAe,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAEjE,MAAM,WAAW,QAAQ;IACxB,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;CACZ;AAED,MAAM,WAAW,UAAU;IAC1B,GAAG,EAAE,MAAM,CAAA;IACX,GAAG,EAAE,MAAM,CAAA;IACX,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,GAAG,CAAA;CACX;AAED,MAAM,WAAW,QAAQ;IACxB,GAAG,EAAE,MAAM,CAAA;IACX,GAAG,EAAE,MAAM,CAAA;IACX,YAAY,EAAE,MAAM,CAAA;CACpB;AAsLD;;;;GAIG;AACH,qBAAa,WAAW;IACvB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAc;gBAEzB,MAAM,EAAE,YAAY;IAIhC;;;;;OAKG;YACW,YAAY;IA8BpB,WAAW,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,UAAU,EAAE,CAAC;QAAC,IAAI,CAAC,EAAE,QAAQ,CAAA;KAAE,GAAG,OAAO,CAAC,QAAQ,CAAC;CA2EhH"}
package/out/renderer.js CHANGED
@@ -16,7 +16,7 @@
16
16
  import { overlayText, rasterizeToFrame, rgbToPacked } from "./frame.js";
17
17
  import { lonLatToWorldPx, metersPerPixel, TILE_SIZE } from "./mercator.js";
18
18
  import { drawCircle, drawPolyline, fillPolygon, RGBAGrid } from "./raster.js";
19
- import { stylesFor } from "./style.js";
19
+ import { styleForFeatureKind, stylesFor } from "./style.js";
20
20
  const DEFAULT_MARKER_CHAR = "●";
21
21
  const DEFAULT_MARKER_COLOR = [255, 80, 80];
22
22
  /**
@@ -34,8 +34,8 @@ function clamp(value, min, max) {
34
34
  }
35
35
  function projectPoint(projection, gx, gy) {
36
36
  return {
37
- x: projection.tileX * TILE_SIZE + gx * projection.scale - projection.origin.x,
38
- y: projection.tileY * TILE_SIZE + gy * projection.scale - projection.origin.y,
37
+ x: projection.worldX + gx * projection.scale - projection.origin.x,
38
+ y: projection.worldY + gy * projection.scale - projection.origin.y,
39
39
  };
40
40
  }
41
41
  function rasterizeFill(grid, feature, projection, color) {
@@ -85,14 +85,20 @@ function rasterizeFeature(grid, feature, style, renderZoom, projection, pendingL
85
85
  * Rasterizes every layer/style/feature in one tile matching `kind`. Pulled out of {@link MapRenderer.renderFrame} so
86
86
  * that method's own tile loop doesn't accumulate this function's three nested loops on top of its own.
87
87
  */
88
- function rasterizeTileForKind(grid, tile, tileX, tileY, kind, renderZoom, origin, pendingLabels) {
89
- for (const layer of tile.layers) {
88
+ function rasterizeTileForKind(grid, resolved, kind, renderZoom, origin, pendingLabels) {
89
+ for (const layer of resolved.tile.layers) {
90
90
  const styles = stylesFor(layer.name, renderZoom).filter((style) => style.kind === kind);
91
91
  if (!styles.length)
92
92
  continue;
93
- const projection = { tileX, tileY, scale: TILE_SIZE / layer.extent, origin };
94
- for (const style of styles) {
95
- for (const feature of layer.features) {
93
+ const projection = {
94
+ worldX: resolved.tileX * resolved.span,
95
+ worldY: resolved.tileY * resolved.span,
96
+ scale: resolved.span / layer.extent,
97
+ origin,
98
+ };
99
+ for (const feature of layer.features) {
100
+ const style = styleForFeatureKind(styles, feature.properties.kind);
101
+ if (style) {
96
102
  rasterizeFeature(grid, feature, style, renderZoom, projection, pendingLabels);
97
103
  }
98
104
  }
@@ -108,6 +114,31 @@ export class MapRenderer {
108
114
  constructor(source) {
109
115
  this.source = source;
110
116
  }
117
+ /**
118
+ * Resolves each viewport slot to its native tile or, when the archive has none — a spatially sparse deep band, a
119
+ * zoom-capped extract — the nearest existing ancestor. Ancestors shared by several absent slots are deduplicated so
120
+ * their geometry rasterizes once, and coarse tiles sort first so native detail paints over the fallback wherever both
121
+ * cover a cell.
122
+ */
123
+ async resolveTiles(tileCoords, renderZoom) {
124
+ const resolved = new Map();
125
+ await Promise.all(tileCoords.map(async ({ x, y }) => {
126
+ for (let zoom = renderZoom; zoom >= this.source.minZoom; zoom--) {
127
+ const shift = renderZoom - zoom;
128
+ const tileX = x >> shift;
129
+ const tileY = y >> shift;
130
+ const key = `${zoom}/${tileX}/${tileY}`;
131
+ if (resolved.has(key))
132
+ return;
133
+ const tile = await this.source.getTile(zoom, tileX, tileY);
134
+ if (tile) {
135
+ resolved.set(key, { tile, tileX, tileY, span: TILE_SIZE * 2 ** shift });
136
+ return;
137
+ }
138
+ }
139
+ }));
140
+ return [...resolved.values()].toSorted((a, b) => b.span - a.span);
141
+ }
111
142
  async renderFrame(viewport, overlays) {
112
143
  const { centerLon, centerLat, columns, rows } = viewport;
113
144
  const subpixelW = columns * SUBPIXEL_COLUMNS_PER_CELL;
@@ -126,16 +157,12 @@ export class MapRenderer {
126
157
  tileCoords.push({ x: tileX, y: tileY });
127
158
  }
128
159
  }
129
- const tiles = await Promise.all(tileCoords.map((coord) => this.source.getTile(renderZoom, coord.x, coord.y)));
160
+ const resolvedTiles = await this.resolveTiles(tileCoords, renderZoom);
130
161
  const grid = new RGBAGrid(subpixelW, subpixelH);
131
162
  const pendingLabels = [];
132
163
  for (const kind of ["fill", "line", "label"]) {
133
- for (let i = 0; i < tileCoords.length; i++) {
134
- const tile = tiles[i];
135
- if (!tile)
136
- continue;
137
- const { x: tileX, y: tileY } = tileCoords[i];
138
- rasterizeTileForKind(grid, tile, tileX, tileY, kind, renderZoom, origin, pendingLabels);
164
+ for (const resolved of resolvedTiles) {
165
+ rasterizeTileForKind(grid, resolved, kind, renderZoom, origin, pendingLabels);
139
166
  }
140
167
  }
141
168
  if (overlays?.ring) {
@@ -1 +1 @@
1
- {"version":3,"file":"renderer.js","sourceRoot":"","sources":["../renderer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"renderer.js","sourceRoot":"","sources":["../renderer.ts"],"names":[],"mappings":"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"}
package/out/style.d.ts CHANGED
@@ -11,21 +11,25 @@
11
11
  * labels.
12
12
  */
13
13
  export type RGB = readonly [red: number, green: number, blue: number];
14
- export interface FillStyle {
15
- kind: "fill";
14
+ /**
15
+ * Fields shared by every style entry. `featureKinds` scopes an entry to features whose `kind` tile attribute is in the
16
+ * list; an entry without it is the layer's catch-all. Entries are consulted in table order and the first match wins, so
17
+ * kind-scoped entries precede the catch-all.
18
+ */
19
+ interface StyleBase {
16
20
  color: RGB;
17
21
  minZoom: number;
22
+ featureKinds?: readonly string[];
18
23
  }
19
- export interface LineStyle {
24
+ export interface FillStyle extends StyleBase {
25
+ kind: "fill";
26
+ }
27
+ export interface LineStyle extends StyleBase {
20
28
  kind: "line";
21
- color: RGB;
22
- minZoom: number;
23
29
  width: (zoom: number) => number;
24
30
  }
25
- export interface LabelStyle {
31
+ export interface LabelStyle extends StyleBase {
26
32
  kind: "label";
27
- color: RGB;
28
- minZoom: number;
29
33
  property: string;
30
34
  }
31
35
  export type LayerStyle = FillStyle | LineStyle | LabelStyle;
@@ -34,4 +38,11 @@ export type LayerStyle = FillStyle | LineStyle | LabelStyle;
34
38
  * unstyled/gated layers.
35
39
  */
36
40
  export declare function stylesFor(layerName: string, zoom: number): LayerStyle[];
41
+ /**
42
+ * The one style painting a feature: the first entry whose `featureKinds` contains the feature's `kind` attribute, or
43
+ * the first catch-all. A feature is painted at most once per draw pass — kind-scoped entries recolor, they never
44
+ * double-paint.
45
+ */
46
+ export declare function styleForFeatureKind(styles: readonly LayerStyle[], featureKind: unknown): LayerStyle | null;
47
+ export {};
37
48
  //# sourceMappingURL=style.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"style.d.ts","sourceRoot":"","sources":["../style.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;;;GAMG;AAEH,MAAM,MAAM,GAAG,GAAG,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,CAAA;AAErE,MAAM,WAAW,SAAS;IACzB,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,GAAG,CAAA;IACV,OAAO,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,SAAS;IACzB,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,GAAG,CAAA;IACV,OAAO,EAAE,MAAM,CAAA;IACf,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAA;CAC/B;AAED,MAAM,WAAW,UAAU;IAC1B,IAAI,EAAE,OAAO,CAAA;IACb,KAAK,EAAE,GAAG,CAAA;IACV,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,SAAS,GAAG,UAAU,CAAA;AAmB3D;;;GAGG;AACH,wBAAgB,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,UAAU,EAAE,CAEvE"}
1
+ {"version":3,"file":"style.d.ts","sourceRoot":"","sources":["../style.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;;;GAMG;AAEH,MAAM,MAAM,GAAG,GAAG,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,CAAA;AAErE;;;;GAIG;AACH,UAAU,SAAS;IAClB,KAAK,EAAE,GAAG,CAAA;IACV,OAAO,EAAE,MAAM,CAAA;IACf,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;CAChC;AAED,MAAM,WAAW,SAAU,SAAQ,SAAS;IAC3C,IAAI,EAAE,MAAM,CAAA;CACZ;AAED,MAAM,WAAW,SAAU,SAAQ,SAAS;IAC3C,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAA;CAC/B;AAED,MAAM,WAAW,UAAW,SAAQ,SAAS;IAC5C,IAAI,EAAE,OAAO,CAAA;IACb,QAAQ,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,SAAS,GAAG,UAAU,CAAA;AAoD3D;;;GAGG;AACH,wBAAgB,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,UAAU,EAAE,CAEvE;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,SAAS,UAAU,EAAE,EAAE,WAAW,EAAE,OAAO,GAAG,UAAU,GAAG,IAAI,CAQ1G"}
package/out/style.js CHANGED
@@ -5,15 +5,46 @@
5
5
  */
6
6
  // Zoom level at which roads render with 2px width instead of 1px.
7
7
  const ROAD_WIDTH_THRESHOLD = 14;
8
+ const roadWidth = (zoom) => (zoom >= ROAD_WIDTH_THRESHOLD ? 2 : 1);
9
+ // At braille scale every road is one dot wide and every fill is stipple, so CLASS has to ride on color instead of
10
+ // geometry: arteries brighten toward amber, paths dim toward the vegetation green, and urban landuse runs warmer and
11
+ // brighter than vegetation so a city reads as denser texture. Luminance is load-bearing — asciify's ordered dither
12
+ // turns it into stipple density.
13
+ const VEGETATION_KINDS = [
14
+ "allotments",
15
+ "cemetery",
16
+ "farmland",
17
+ "forest",
18
+ "garden",
19
+ "grass",
20
+ "meadow",
21
+ "nature_reserve",
22
+ "park",
23
+ "scrub",
24
+ "wetland",
25
+ "wood",
26
+ ];
8
27
  const STYLE_TABLE = {
9
28
  earth: [{ kind: "fill", color: [40, 44, 36], minZoom: 0 }],
10
29
  landcover: [{ kind: "fill", color: [36, 52, 32], minZoom: 4 }],
11
- landuse: [{ kind: "fill", color: [48, 48, 40], minZoom: 10 }],
30
+ landuse: [
31
+ { kind: "fill", color: [66, 60, 52], minZoom: 10, featureKinds: ["residential"] },
32
+ { kind: "fill", color: [72, 62, 50], minZoom: 10, featureKinds: ["commercial"] },
33
+ { kind: "fill", color: [58, 60, 64], minZoom: 10, featureKinds: ["industrial"] },
34
+ { kind: "fill", color: [36, 52, 32], minZoom: 10, featureKinds: VEGETATION_KINDS },
35
+ { kind: "fill", color: [48, 48, 40], minZoom: 10 },
36
+ ],
12
37
  water: [{ kind: "fill", color: [24, 48, 90], minZoom: 0 }],
13
38
  buildings: [{ kind: "fill", color: [70, 66, 60], minZoom: 13 }],
14
39
  boundaries: [{ kind: "line", color: [140, 110, 160], minZoom: 0, width: () => 1 }],
15
40
  roads: [
16
- { kind: "line", color: [170, 170, 150], minZoom: 6, width: (zoom) => (zoom >= ROAD_WIDTH_THRESHOLD ? 2 : 1) },
41
+ { kind: "line", color: [255, 190, 90], minZoom: 6, featureKinds: ["highway"], width: roadWidth },
42
+ { kind: "line", color: [215, 210, 180], minZoom: 6, featureKinds: ["major_road"], width: roadWidth },
43
+ { kind: "line", color: [185, 182, 158], minZoom: 6, featureKinds: ["medium_road"], width: roadWidth },
44
+ { kind: "line", color: [150, 150, 132], minZoom: 6, featureKinds: ["minor_road"], width: roadWidth },
45
+ { kind: "line", color: [105, 115, 98], minZoom: 6, featureKinds: ["path"], width: roadWidth },
46
+ { kind: "line", color: [115, 125, 140], minZoom: 6, featureKinds: ["rail"], width: () => 1 },
47
+ { kind: "line", color: [170, 170, 150], minZoom: 6, width: roadWidth },
17
48
  ],
18
49
  places: [{ kind: "label", color: [235, 235, 220], minZoom: 2, property: "name" }],
19
50
  pois: [{ kind: "label", color: [180, 200, 160], minZoom: 14, property: "name" }],
@@ -25,4 +56,18 @@ const STYLE_TABLE = {
25
56
  export function stylesFor(layerName, zoom) {
26
57
  return (STYLE_TABLE[layerName] ?? []).filter((style) => zoom >= style.minZoom);
27
58
  }
59
+ /**
60
+ * The one style painting a feature: the first entry whose `featureKinds` contains the feature's `kind` attribute, or
61
+ * the first catch-all. A feature is painted at most once per draw pass — kind-scoped entries recolor, they never
62
+ * double-paint.
63
+ */
64
+ export function styleForFeatureKind(styles, featureKind) {
65
+ for (const style of styles) {
66
+ if (style.featureKinds == null)
67
+ return style;
68
+ if (typeof featureKind === "string" && style.featureKinds.includes(featureKind))
69
+ return style;
70
+ }
71
+ return null;
72
+ }
28
73
  //# sourceMappingURL=style.js.map
package/out/style.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"style.js","sourceRoot":"","sources":["../style.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAkCH,kEAAkE;AAClE,MAAM,oBAAoB,GAAG,EAAE,CAAA;AAE/B,MAAM,WAAW,GAAiC;IACjD,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;IAC1D,SAAS,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;IAC9D,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;IAC7D,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;IAC1D,SAAS,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;IAC/D,UAAU,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC;IAClF,KAAK,EAAE;QACN,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,IAAI,oBAAoB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;KAC7G;IACD,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;IACjF,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;CAChF,CAAA;AAED;;;GAGG;AACH,MAAM,UAAU,SAAS,CAAC,SAAiB,EAAE,IAAY;IACxD,OAAO,CAAC,WAAW,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,CAAA;AAC/E,CAAC"}
1
+ {"version":3,"file":"style.js","sourceRoot":"","sources":["../style.ts"],"names":[],"mappings":"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"}
@@ -7,18 +7,39 @@ import { type DecodedLayer } from "./mvt.ts";
7
7
  export interface DecodedTile {
8
8
  layers: DecodedLayer[];
9
9
  }
10
- export declare class TileSource {
10
+ /**
11
+ * What a renderer needs from a tile archive — the read surface of {@link TileSource}, separated so a renderer can be
12
+ * driven by any provider: a single archive, a stub in tests, or a composite over several archives.
13
+ */
14
+ export interface TileProvider {
15
+ readonly minZoom: number;
16
+ readonly maxZoom: number;
17
+ readonly attribution: string;
18
+ getTile(z: number, x: number, y: number): Promise<DecodedTile | null>;
19
+ }
20
+ /**
21
+ * Plain-text attribution out of archive metadata (HTML tags stripped, entities decoded); empty string when absent.
22
+ */
23
+ export declare function readAttribution(metadata: unknown): string;
24
+ export declare class TileSource implements TileProvider {
11
25
  readonly minZoom: number;
12
26
  readonly maxZoom: number;
13
27
  /**
14
28
  * Plain-text attribution from archive metadata (HTML tags stripped); empty string when absent.
15
29
  */
16
30
  readonly attribution: string;
31
+ /**
32
+ * Null for HTTP sources — fetch connections have no handle to hold or close.
33
+ */
17
34
  private readonly handle;
18
35
  private readonly pmtiles;
19
36
  private readonly cache;
20
37
  private constructor();
21
- static open(path: string): Promise<TileSource>;
38
+ /**
39
+ * Opens a local `.pmtiles` path, or an `http(s)://` URL read via range requests — a hosted archive needs no tile
40
+ * server, only a host honoring `Range` (any static file server or object store does).
41
+ */
42
+ static open(pathOrURL: string): Promise<TileSource>;
22
43
  /**
23
44
  * Decoded tile, LRU-cached (64 entries). null = tile absent from the archive.
24
45
  */
@@ -1 +1 @@
1
- {"version":3,"file":"tile-source.d.ts","sourceRoot":"","sources":["../tile-source.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAcH,OAAO,EAAE,KAAK,YAAY,EAAa,MAAM,UAAU,CAAA;AAEvD,MAAM,WAAW,WAAW;IAC3B,MAAM,EAAE,YAAY,EAAE,CAAA;CACtB;AAkCD,qBAAa,UAAU;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IAExB;;OAEG;IACH,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAE5B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAY;IACnC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAgC;IAEtD,OAAO;WAQM,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAiBpD;;OAEG;IACG,OAAO,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IA6BrE,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAG5B"}
1
+ {"version":3,"file":"tile-source.d.ts","sourceRoot":"","sources":["../tile-source.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAcH,OAAO,EAAE,KAAK,YAAY,EAAa,MAAM,UAAU,CAAA;AAEvD,MAAM,WAAW,WAAW;IAC3B,MAAM,EAAE,YAAY,EAAE,CAAA;CACtB;AAED;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,OAAO,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAAA;CACrE;AAsCD;;GAEG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,OAAO,GAAG,MAAM,CAczD;AAWD,qBAAa,UAAW,YAAW,YAAY;IAC9C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IAExB;;OAEG;IACH,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAE5B;;OAEG;IACH,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAmB;IAC1C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAgC;IAEtD,OAAO;IAcP;;;OAGG;WACU,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAgBzD;;OAEG;IACG,OAAO,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IA6BrE,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAG5B"}