@react-x11/components 0.8.0 → 0.9.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/README.md +95 -34
- package/dist/charts/node.d.ts +1 -1
- package/dist/charts/node.d.ts.map +1 -1
- package/dist/charts/node.js +6 -2
- package/dist/charts/node.js.map +1 -1
- package/dist/embed/client.d.ts +48 -3
- package/dist/embed/client.d.ts.map +1 -1
- package/dist/embed/client.js +79 -5
- package/dist/embed/client.js.map +1 -1
- package/dist/embed/index.d.ts +1 -1
- package/dist/embed/index.d.ts.map +1 -1
- package/dist/embed/index.js +1 -1
- package/dist/embed/index.js.map +1 -1
- package/dist/html/node.d.ts +3 -1
- package/dist/html/node.d.ts.map +1 -1
- package/dist/html/node.js +7 -5
- package/dist/html/node.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/{markdown → internal/markdown}/ast.d.ts +12 -0
- package/dist/internal/markdown/ast.d.ts.map +1 -0
- package/dist/internal/markdown/ast.js +22 -0
- package/dist/internal/markdown/ast.js.map +1 -0
- package/dist/internal/markdown/parse.d.ts.map +1 -0
- package/dist/{markdown → internal/markdown}/parse.js +112 -22
- package/dist/internal/markdown/parse.js.map +1 -0
- package/dist/internal/markdown/stringify.d.ts +4 -0
- package/dist/internal/markdown/stringify.d.ts.map +1 -0
- package/dist/internal/markdown/stringify.js +684 -0
- package/dist/internal/markdown/stringify.js.map +1 -0
- package/dist/internal/markdown/tags.d.ts.map +1 -0
- package/dist/internal/markdown/tags.js.map +1 -0
- package/dist/internal/scroll.d.ts +3 -2
- package/dist/internal/scroll.d.ts.map +1 -1
- package/dist/internal/scroll.js +1 -0
- package/dist/internal/scroll.js.map +1 -1
- package/dist/maps/anchors.d.ts +98 -0
- package/dist/maps/anchors.d.ts.map +1 -0
- package/dist/maps/anchors.js +531 -0
- package/dist/maps/anchors.js.map +1 -0
- package/dist/maps/controller.d.ts +283 -0
- package/dist/maps/controller.d.ts.map +1 -0
- package/dist/maps/controller.js +743 -0
- package/dist/maps/controller.js.map +1 -0
- package/dist/maps/gl/buckets.d.ts +95 -0
- package/dist/maps/gl/buckets.d.ts.map +1 -0
- package/dist/maps/gl/buckets.js +362 -0
- package/dist/maps/gl/buckets.js.map +1 -0
- package/dist/maps/gl/build-worker.d.ts +13 -0
- package/dist/maps/gl/build-worker.d.ts.map +1 -0
- package/dist/maps/gl/build-worker.js +44 -0
- package/dist/maps/gl/build-worker.js.map +1 -0
- package/dist/maps/gl/color.d.ts +8 -0
- package/dist/maps/gl/color.d.ts.map +1 -0
- package/dist/maps/gl/color.js +57 -0
- package/dist/maps/gl/color.js.map +1 -0
- package/dist/maps/gl/cover.d.ts +51 -0
- package/dist/maps/gl/cover.d.ts.map +1 -0
- package/dist/maps/gl/cover.js +124 -0
- package/dist/maps/gl/cover.js.map +1 -0
- package/dist/maps/gl/index.d.ts +3 -0
- package/dist/maps/gl/index.d.ts.map +1 -0
- package/dist/maps/gl/index.js +20 -0
- package/dist/maps/gl/index.js.map +1 -0
- package/dist/maps/gl/markers.d.ts +28 -0
- package/dist/maps/gl/markers.d.ts.map +1 -0
- package/dist/maps/gl/markers.js +60 -0
- package/dist/maps/gl/markers.js.map +1 -0
- package/dist/maps/gl/overlays.d.ts +68 -0
- package/dist/maps/gl/overlays.d.ts.map +1 -0
- package/dist/maps/gl/overlays.js +300 -0
- package/dist/maps/gl/overlays.js.map +1 -0
- package/dist/maps/gl/pane.d.ts +12 -0
- package/dist/maps/gl/pane.d.ts.map +1 -0
- package/dist/maps/gl/pane.js +37 -0
- package/dist/maps/gl/pane.js.map +1 -0
- package/dist/maps/gl/placement.d.ts +111 -0
- package/dist/maps/gl/placement.d.ts.map +1 -0
- package/dist/maps/gl/placement.js +567 -0
- package/dist/maps/gl/placement.js.map +1 -0
- package/dist/maps/gl/renderer.d.ts +352 -0
- package/dist/maps/gl/renderer.d.ts.map +1 -0
- package/dist/maps/gl/renderer.js +1127 -0
- package/dist/maps/gl/renderer.js.map +1 -0
- package/dist/maps/gl/shaders.d.ts +120 -0
- package/dist/maps/gl/shaders.d.ts.map +1 -0
- package/dist/maps/gl/shaders.js +451 -0
- package/dist/maps/gl/shaders.js.map +1 -0
- package/dist/maps/gl/store.d.ts +115 -0
- package/dist/maps/gl/store.d.ts.map +1 -0
- package/dist/maps/gl/store.js +469 -0
- package/dist/maps/gl/store.js.map +1 -0
- package/dist/maps/gl/text.d.ts +154 -0
- package/dist/maps/gl/text.d.ts.map +1 -0
- package/dist/maps/gl/text.js +382 -0
- package/dist/maps/gl/text.js.map +1 -0
- package/dist/maps/gl/view.d.ts +54 -0
- package/dist/maps/gl/view.d.ts.map +1 -0
- package/dist/maps/gl/view.js +974 -0
- package/dist/maps/gl/view.js.map +1 -0
- package/dist/maps/index.d.ts +1 -1
- package/dist/maps/index.d.ts.map +1 -1
- package/dist/maps/index.js +216 -52
- package/dist/maps/index.js.map +1 -1
- package/dist/maps/labels.d.ts +37 -16
- package/dist/maps/labels.d.ts.map +1 -1
- package/dist/maps/labels.js +188 -119
- package/dist/maps/labels.js.map +1 -1
- package/dist/maps/node.d.ts +162 -56
- package/dist/maps/node.d.ts.map +1 -1
- package/dist/maps/node.js +607 -515
- package/dist/maps/node.js.map +1 -1
- package/dist/maps/overlay.d.ts +72 -9
- package/dist/maps/overlay.d.ts.map +1 -1
- package/dist/maps/overlay.js +108 -28
- package/dist/maps/overlay.js.map +1 -1
- package/dist/maps/paint.d.ts +3 -0
- package/dist/maps/paint.d.ts.map +1 -1
- package/dist/maps/paint.js.map +1 -1
- package/dist/maps/proj.d.ts +14 -0
- package/dist/maps/proj.d.ts.map +1 -1
- package/dist/maps/proj.js +28 -0
- package/dist/maps/proj.js.map +1 -1
- package/dist/maps/renderer.d.ts +69 -0
- package/dist/maps/renderer.d.ts.map +1 -0
- package/dist/maps/renderer.js +66 -0
- package/dist/maps/renderer.js.map +1 -0
- package/dist/maps/sources.d.ts +25 -3
- package/dist/maps/sources.d.ts.map +1 -1
- package/dist/maps/sources.js +17 -0
- package/dist/maps/sources.js.map +1 -1
- package/dist/maps/theme.d.ts +19 -0
- package/dist/maps/theme.d.ts.map +1 -0
- package/dist/maps/theme.js +44 -0
- package/dist/maps/theme.js.map +1 -0
- package/dist/maps/tiles.d.ts +117 -17
- package/dist/maps/tiles.d.ts.map +1 -1
- package/dist/maps/tiles.js +163 -30
- package/dist/maps/tiles.js.map +1 -1
- package/dist/maps/types.d.ts +188 -20
- package/dist/maps/types.d.ts.map +1 -1
- package/dist/markdown/expressions.d.ts +1 -1
- package/dist/markdown/expressions.d.ts.map +1 -1
- package/dist/markdown/expressions.js.map +1 -1
- package/dist/markdown/index.d.ts +7 -6
- package/dist/markdown/index.d.ts.map +1 -1
- package/dist/markdown/index.js +9 -7
- package/dist/markdown/index.js.map +1 -1
- package/dist/markdown/spans.d.ts +1 -1
- package/dist/markdown/spans.d.ts.map +1 -1
- package/dist/media-player/index.d.ts +11 -3
- package/dist/media-player/index.d.ts.map +1 -1
- package/dist/media-player/index.js +13 -2
- package/dist/media-player/index.js.map +1 -1
- package/dist/rich-text-editor/clipboard.d.ts +23 -0
- package/dist/rich-text-editor/clipboard.d.ts.map +1 -0
- package/dist/rich-text-editor/clipboard.js +307 -0
- package/dist/rich-text-editor/clipboard.js.map +1 -0
- package/dist/rich-text-editor/collab.d.ts +32 -0
- package/dist/rich-text-editor/collab.d.ts.map +1 -0
- package/dist/rich-text-editor/collab.js +55 -0
- package/dist/rich-text-editor/collab.js.map +1 -0
- package/dist/rich-text-editor/commands.d.ts +50 -0
- package/dist/rich-text-editor/commands.d.ts.map +1 -0
- package/dist/rich-text-editor/commands.js +376 -0
- package/dist/rich-text-editor/commands.js.map +1 -0
- package/dist/rich-text-editor/drag.d.ts +68 -0
- package/dist/rich-text-editor/drag.d.ts.map +1 -0
- package/dist/rich-text-editor/drag.js +148 -0
- package/dist/rich-text-editor/drag.js.map +1 -0
- package/dist/rich-text-editor/html.d.ts +145 -0
- package/dist/rich-text-editor/html.d.ts.map +1 -0
- package/dist/rich-text-editor/html.js +516 -0
- package/dist/rich-text-editor/html.js.map +1 -0
- package/dist/rich-text-editor/index.d.ts +263 -0
- package/dist/rich-text-editor/index.d.ts.map +1 -0
- package/dist/rich-text-editor/index.js +822 -0
- package/dist/rich-text-editor/index.js.map +1 -0
- package/dist/rich-text-editor/inline.d.ts +94 -0
- package/dist/rich-text-editor/inline.d.ts.map +1 -0
- package/dist/rich-text-editor/inline.js +252 -0
- package/dist/rich-text-editor/inline.js.map +1 -0
- package/dist/rich-text-editor/keymap.d.ts +71 -0
- package/dist/rich-text-editor/keymap.d.ts.map +1 -0
- package/dist/rich-text-editor/keymap.js +393 -0
- package/dist/rich-text-editor/keymap.js.map +1 -0
- package/dist/rich-text-editor/keys.d.ts +29 -0
- package/dist/rich-text-editor/keys.d.ts.map +1 -0
- package/dist/rich-text-editor/keys.js +93 -0
- package/dist/rich-text-editor/keys.js.map +1 -0
- package/dist/rich-text-editor/look.d.ts +71 -0
- package/dist/rich-text-editor/look.d.ts.map +1 -0
- package/dist/rich-text-editor/look.js +342 -0
- package/dist/rich-text-editor/look.js.map +1 -0
- package/dist/rich-text-editor/markdown.d.ts +18 -0
- package/dist/rich-text-editor/markdown.d.ts.map +1 -0
- package/dist/rich-text-editor/markdown.js +496 -0
- package/dist/rich-text-editor/markdown.js.map +1 -0
- package/dist/rich-text-editor/nodes.d.ts +135 -0
- package/dist/rich-text-editor/nodes.d.ts.map +1 -0
- package/dist/rich-text-editor/nodes.js +397 -0
- package/dist/rich-text-editor/nodes.js.map +1 -0
- package/dist/rich-text-editor/render.d.ts +68 -0
- package/dist/rich-text-editor/render.d.ts.map +1 -0
- package/dist/rich-text-editor/render.js +500 -0
- package/dist/rich-text-editor/render.js.map +1 -0
- package/dist/rich-text-editor/schema.d.ts +16 -0
- package/dist/rich-text-editor/schema.d.ts.map +1 -0
- package/dist/rich-text-editor/schema.js +386 -0
- package/dist/rich-text-editor/schema.js.map +1 -0
- package/dist/rich-text-editor/store.d.ts +11 -0
- package/dist/rich-text-editor/store.d.ts.map +1 -0
- package/dist/rich-text-editor/store.js +43 -0
- package/dist/rich-text-editor/store.js.map +1 -0
- package/dist/rich-text-editor/suggest.d.ts +127 -0
- package/dist/rich-text-editor/suggest.d.ts.map +1 -0
- package/dist/rich-text-editor/suggest.js +0 -0
- package/dist/rich-text-editor/suggest.js.map +1 -0
- package/dist/rich-text-editor/tables.d.ts +41 -0
- package/dist/rich-text-editor/tables.d.ts.map +1 -0
- package/dist/rich-text-editor/tables.js +204 -0
- package/dist/rich-text-editor/tables.js.map +1 -0
- package/dist/rich-text-editor/toolbar.d.ts +58 -0
- package/dist/rich-text-editor/toolbar.d.ts.map +1 -0
- package/dist/rich-text-editor/toolbar.js +548 -0
- package/dist/rich-text-editor/toolbar.js.map +1 -0
- package/dist/rich-text-editor/view.d.ts +368 -0
- package/dist/rich-text-editor/view.d.ts.map +1 -0
- package/dist/rich-text-editor/view.js +1968 -0
- package/dist/rich-text-editor/view.js.map +1 -0
- package/dist/rich-text-editor/virtual.d.ts +54 -0
- package/dist/rich-text-editor/virtual.d.ts.map +1 -0
- package/dist/rich-text-editor/virtual.js +262 -0
- package/dist/rich-text-editor/virtual.js.map +1 -0
- package/dist/richtext/node.d.ts +25 -2
- package/dist/richtext/node.d.ts.map +1 -1
- package/dist/richtext/node.js +46 -24
- package/dist/richtext/node.js.map +1 -1
- package/dist/terminal/backends.d.ts +4 -1
- package/dist/terminal/backends.d.ts.map +1 -1
- package/dist/terminal/backends.js.map +1 -1
- package/dist/terminal/index.d.ts +18 -7
- package/dist/terminal/index.d.ts.map +1 -1
- package/dist/terminal/index.js +28 -11
- package/dist/terminal/index.js.map +1 -1
- package/package.json +23 -4
- package/src/charts/node.ts +6 -2
- package/src/embed/client.ts +102 -8
- package/src/embed/index.ts +2 -0
- package/src/html/node.ts +7 -5
- package/src/index.ts +2 -0
- package/src/{markdown → internal/markdown}/ast.ts +24 -7
- package/src/{markdown → internal/markdown}/parse.ts +134 -24
- package/src/internal/markdown/stringify.ts +772 -0
- package/src/internal/scroll.ts +5 -3
- package/src/maps/anchors.ts +607 -0
- package/src/maps/controller.ts +999 -0
- package/src/maps/gl/buckets.ts +457 -0
- package/src/maps/gl/build-worker.ts +55 -0
- package/src/maps/gl/color.ts +62 -0
- package/src/maps/gl/cover.ts +170 -0
- package/src/maps/gl/index.ts +23 -0
- package/src/maps/gl/markers.ts +83 -0
- package/src/maps/gl/overlays.ts +379 -0
- package/src/maps/gl/pane.ts +42 -0
- package/src/maps/gl/placement.ts +816 -0
- package/src/maps/gl/renderer.ts +1576 -0
- package/src/maps/gl/shaders.ts +486 -0
- package/src/maps/gl/store.ts +566 -0
- package/src/maps/gl/text.ts +495 -0
- package/src/maps/gl/view.ts +1224 -0
- package/src/maps/index.ts +270 -81
- package/src/maps/labels.ts +214 -121
- package/src/maps/node.ts +763 -629
- package/src/maps/overlay.ts +148 -43
- package/src/maps/paint.ts +3 -0
- package/src/maps/proj.ts +31 -0
- package/src/maps/renderer.ts +155 -0
- package/src/maps/sources.ts +38 -3
- package/src/maps/theme.ts +51 -0
- package/src/maps/tiles.ts +191 -33
- package/src/maps/types.ts +188 -20
- package/src/markdown/expressions.ts +5 -1
- package/src/markdown/index.ts +14 -11
- package/src/markdown/spans.ts +1 -1
- package/src/media-player/index.ts +18 -4
- package/src/rich-text-editor/clipboard.ts +439 -0
- package/src/rich-text-editor/collab.ts +91 -0
- package/src/rich-text-editor/commands.ts +448 -0
- package/src/rich-text-editor/dom-globals.d.ts +23 -0
- package/src/rich-text-editor/drag.ts +211 -0
- package/src/rich-text-editor/html.ts +619 -0
- package/src/rich-text-editor/index.ts +1331 -0
- package/src/rich-text-editor/inline.ts +345 -0
- package/src/rich-text-editor/keymap.ts +510 -0
- package/src/rich-text-editor/keys.ts +119 -0
- package/src/rich-text-editor/look.ts +427 -0
- package/src/rich-text-editor/markdown.ts +653 -0
- package/src/rich-text-editor/nodes.ts +497 -0
- package/src/rich-text-editor/render.ts +800 -0
- package/src/rich-text-editor/schema.ts +431 -0
- package/src/rich-text-editor/store.ts +39 -0
- package/src/rich-text-editor/suggest.ts +597 -0
- package/src/rich-text-editor/tables.ts +272 -0
- package/src/rich-text-editor/toolbar.ts +724 -0
- package/src/rich-text-editor/view.ts +2287 -0
- package/src/rich-text-editor/virtual.ts +347 -0
- package/src/richtext/node.ts +59 -30
- package/src/terminal/backends.ts +4 -1
- package/src/terminal/index.ts +43 -15
- package/dist/markdown/ast.d.ts.map +0 -1
- package/dist/markdown/ast.js +0 -17
- package/dist/markdown/ast.js.map +0 -1
- package/dist/markdown/parse.d.ts.map +0 -1
- package/dist/markdown/parse.js.map +0 -1
- package/dist/markdown/tags.d.ts.map +0 -1
- package/dist/markdown/tags.js.map +0 -1
- /package/dist/{markdown → internal/markdown}/parse.d.ts +0 -0
- /package/dist/{markdown → internal/markdown}/tags.d.ts +0 -0
- /package/dist/{markdown → internal/markdown}/tags.js +0 -0
- /package/src/{markdown → internal/markdown}/tags.ts +0 -0
package/src/maps/tiles.ts
CHANGED
|
@@ -18,6 +18,14 @@
|
|
|
18
18
|
// scaled. Only an integer zoom change, a style change or a display-scale
|
|
19
19
|
// change invalidates one.
|
|
20
20
|
//
|
|
21
|
+
// Both are filed under the **source object**, not under its `id`. An id is
|
|
22
|
+
// only what a source is called, and two providers can share one — a source
|
|
23
|
+
// without one is named for its slot in `sources`, and `osmRasterSource` is
|
|
24
|
+
// `osm-raster` whichever server it points at — so filing by id handed a map
|
|
25
|
+
// switched to another provider the old one's tiles wherever it had them,
|
|
26
|
+
// until eviction got round to them. Filed by object, a new provider starts
|
|
27
|
+
// empty, and an old one keeps its tiles for when it comes back.
|
|
28
|
+
//
|
|
21
29
|
// The surface is the expensive half — on the corpus in `scripts/bench/`, a
|
|
22
30
|
// dense city tile is 50-140 ms to rasterize and about 0.05 ms to composite
|
|
23
31
|
// — so the cache's job is to make sure that cost is paid once per tile per
|
|
@@ -80,6 +88,14 @@ export interface TileRender {
|
|
|
80
88
|
zoom: number;
|
|
81
89
|
/** The cache generation it was drawn under. */
|
|
82
90
|
generation: number;
|
|
91
|
+
/**
|
|
92
|
+
* Whether its pixels depend on the style. A vector tile's do — they are
|
|
93
|
+
* the style, rasterized — and a raster tile's do not: they are the
|
|
94
|
+
* provider's image, uploaded as it arrived. So an unstyled rendering
|
|
95
|
+
* belongs to every generation, and a restyle neither redraws it nor stops
|
|
96
|
+
* showing it.
|
|
97
|
+
*/
|
|
98
|
+
styled: boolean;
|
|
83
99
|
/** The next style run to draw, or `-1` when it is finished. */
|
|
84
100
|
progress: number;
|
|
85
101
|
/** …and how far into that run's active layers, because a run is not a
|
|
@@ -97,6 +113,12 @@ export interface TileRender {
|
|
|
97
113
|
*/
|
|
98
114
|
export interface TileDataEntry {
|
|
99
115
|
readonly key: string;
|
|
116
|
+
/** Who answers for it — and so which provider the bytes came from,
|
|
117
|
+
* since tiles are filed under the source object. */
|
|
118
|
+
readonly source: MapSource;
|
|
119
|
+
/** What that source is called: the `sourceId` its `load` requests carry
|
|
120
|
+
* and `onError` reports. */
|
|
121
|
+
readonly sourceId: string;
|
|
100
122
|
readonly tile: TileId;
|
|
101
123
|
status: TileStatus;
|
|
102
124
|
error: unknown;
|
|
@@ -141,7 +163,15 @@ export class CachedTile {
|
|
|
141
163
|
* keeps being composited until it is ready to be replaced.
|
|
142
164
|
*/
|
|
143
165
|
shown: TileRender | null = null;
|
|
144
|
-
/**
|
|
166
|
+
/**
|
|
167
|
+
* The rendering being drawn, or null when there is nothing to draw.
|
|
168
|
+
*
|
|
169
|
+
* Finished ones do not usually stay: a draft is {@link TileCache.promote}d
|
|
170
|
+
* in the frame it is done. The exception is a restyle, which holds the
|
|
171
|
+
* previous style's whole picture up until the view is redrawn — so there
|
|
172
|
+
* a finished draft waits here until {@link TileCache.swap} puts every one
|
|
173
|
+
* on screen at once.
|
|
174
|
+
*/
|
|
145
175
|
drawing: TileRender | null = null;
|
|
146
176
|
/** Frame counter of the last frame that wanted it — what eviction sorts
|
|
147
177
|
* on. */
|
|
@@ -207,6 +237,10 @@ export class TileCache {
|
|
|
207
237
|
private readonly _entries = new Map<string, CachedTile>();
|
|
208
238
|
/** The source's own tiles, shared by every rendering that draws one. */
|
|
209
239
|
private readonly _data = new Map<string, TileDataEntry>();
|
|
240
|
+
/** The key prefix of each source object — per object and not per id,
|
|
241
|
+
* for the reason at the top of this file. */
|
|
242
|
+
private readonly _prefixes = new WeakMap<MapSource, string>();
|
|
243
|
+
private _prefixCount = 0;
|
|
210
244
|
private readonly _options: TileCacheOptions;
|
|
211
245
|
private _frame = 0;
|
|
212
246
|
private _surfaceBytes = 0;
|
|
@@ -227,7 +261,16 @@ export class TileCache {
|
|
|
227
261
|
return this._generation;
|
|
228
262
|
}
|
|
229
263
|
|
|
230
|
-
/**
|
|
264
|
+
/**
|
|
265
|
+
* Every styled surface is stale: a new style, or `refresh()` after an
|
|
266
|
+
* edit to one. The data behind them stays, and so does a raster tile's
|
|
267
|
+
* rendering, which no style drew (see {@link TileRender.styled}).
|
|
268
|
+
*
|
|
269
|
+
* A new display scale needs none of this, because a rendering's size is
|
|
270
|
+
* already part of what makes it valid. And nothing on screen is thrown
|
|
271
|
+
* away here: each picture stays until its replacement is finished —
|
|
272
|
+
* {@link promote} for one tile, {@link swap} for the whole view at once.
|
|
273
|
+
*/
|
|
231
274
|
invalidateStyle(): void {
|
|
232
275
|
this._generation++;
|
|
233
276
|
}
|
|
@@ -241,21 +284,31 @@ export class TileCache {
|
|
|
241
284
|
return this._entries.size;
|
|
242
285
|
}
|
|
243
286
|
|
|
244
|
-
|
|
245
|
-
|
|
287
|
+
/** What a source's tile is filed under: a prefix of the source object's
|
|
288
|
+
* own, then `z/x/y`. The id is in the prefix only so that a key reads
|
|
289
|
+
* well in a debugger; two objects with one id get two prefixes. */
|
|
290
|
+
key(source: MapSource, tile: TileId): string {
|
|
291
|
+
let prefix = this._prefixes.get(source);
|
|
292
|
+
if (prefix === undefined) {
|
|
293
|
+
prefix = `${source.id ?? 'source'}#${++this._prefixCount}`;
|
|
294
|
+
this._prefixes.set(source, prefix);
|
|
295
|
+
}
|
|
296
|
+
return `${prefix}:${tileKey(tile)}`;
|
|
246
297
|
}
|
|
247
298
|
|
|
248
|
-
peek(
|
|
249
|
-
return this._entries.get(this.key(
|
|
299
|
+
peek(source: MapSource, tile: TileId): CachedTile | undefined {
|
|
300
|
+
return this._entries.get(this.key(source, tile));
|
|
250
301
|
}
|
|
251
302
|
|
|
252
303
|
/**
|
|
253
304
|
* The entry for a tile the cover asked for, and the data behind it,
|
|
254
305
|
* asking the source for that data if nothing has yet.
|
|
255
306
|
*
|
|
256
|
-
* `
|
|
257
|
-
*
|
|
258
|
-
*
|
|
307
|
+
* Filed under `source`; `sourceId` is only what it is called. `dataTile`
|
|
308
|
+
* is the tile whose bytes serve this one — itself, until the cover goes
|
|
309
|
+
* deeper than the source cuts. Marks both used by the current frame,
|
|
310
|
+
* which is what keeps them out of the next eviction — and a load still
|
|
311
|
+
* in flight from being cancelled by {@link sweep}.
|
|
259
312
|
*/
|
|
260
313
|
want(
|
|
261
314
|
source: MapSource,
|
|
@@ -265,7 +318,7 @@ export class TileCache {
|
|
|
265
318
|
sub: { x: number; y: number; span: number } = { x: 0, y: 0, span: 1 },
|
|
266
319
|
): CachedTile {
|
|
267
320
|
const data = this._wantData(source, sourceId, dataTile);
|
|
268
|
-
const key = this.key(
|
|
321
|
+
const key = this.key(source, tile);
|
|
269
322
|
let entry = this._entries.get(key);
|
|
270
323
|
if (!entry) {
|
|
271
324
|
entry = new CachedTile(key, sourceId, tile, data, sub);
|
|
@@ -280,11 +333,13 @@ export class TileCache {
|
|
|
280
333
|
sourceId: string,
|
|
281
334
|
tile: TileId,
|
|
282
335
|
): TileDataEntry {
|
|
283
|
-
const key = this.key(
|
|
336
|
+
const key = this.key(source, tile);
|
|
284
337
|
let data = this._data.get(key);
|
|
285
338
|
if (!data) {
|
|
286
339
|
data = {
|
|
287
340
|
key,
|
|
341
|
+
source,
|
|
342
|
+
sourceId,
|
|
288
343
|
tile,
|
|
289
344
|
status: 'idle',
|
|
290
345
|
error: null,
|
|
@@ -299,23 +354,19 @@ export class TileCache {
|
|
|
299
354
|
}
|
|
300
355
|
data.lastUsed = this._frame;
|
|
301
356
|
if (data.status === 'idle') {
|
|
302
|
-
this._load(
|
|
357
|
+
this._load(data);
|
|
303
358
|
} else if (data.status === 'error' && Date.now() >= data.retryAt) {
|
|
304
359
|
// A failed tile is retried, but on a backoff rather than on every
|
|
305
360
|
// frame. Without it a source that is down — or an application whose
|
|
306
361
|
// `load` throws on the first call, which is how this was found — is
|
|
307
362
|
// asked for every visible tile sixty times a second, which is a
|
|
308
363
|
// retry storm pointed at somebody else's servers.
|
|
309
|
-
this._load(
|
|
364
|
+
this._load(data);
|
|
310
365
|
}
|
|
311
366
|
return data;
|
|
312
367
|
}
|
|
313
368
|
|
|
314
|
-
private _load(
|
|
315
|
-
source: MapSource,
|
|
316
|
-
sourceId: string,
|
|
317
|
-
entry: TileDataEntry,
|
|
318
|
-
): void {
|
|
369
|
+
private _load(entry: TileDataEntry): void {
|
|
319
370
|
entry.status = 'loading';
|
|
320
371
|
entry.error = null;
|
|
321
372
|
// A **real** `AbortController` where the runtime has one. A look-alike
|
|
@@ -365,7 +416,11 @@ export class TileCache {
|
|
|
365
416
|
};
|
|
366
417
|
let result: TileData | Promise<TileData>;
|
|
367
418
|
try {
|
|
368
|
-
result = source.load({
|
|
419
|
+
result = entry.source.load({
|
|
420
|
+
...entry.tile,
|
|
421
|
+
sourceId: entry.sourceId,
|
|
422
|
+
signal,
|
|
423
|
+
});
|
|
369
424
|
} catch (error) {
|
|
370
425
|
settle(() => fail(error));
|
|
371
426
|
return;
|
|
@@ -408,20 +463,24 @@ export class TileCache {
|
|
|
408
463
|
* under the fine one until it arrives — which is the difference between a
|
|
409
464
|
* map that fills in and a map that flashes empty. Bounded, because
|
|
410
465
|
* scaling one tile over sixteen screenfuls is worse than the hole.
|
|
466
|
+
*
|
|
467
|
+
* With a `generation`, only a picture drawn in it counts: a map showing
|
|
468
|
+
* one style must not cover a hole with a tile drawn in another.
|
|
411
469
|
*/
|
|
412
470
|
ancestorWithSurface(
|
|
413
|
-
|
|
471
|
+
source: MapSource,
|
|
414
472
|
tile: TileId,
|
|
415
473
|
levels = 5,
|
|
474
|
+
generation?: number,
|
|
416
475
|
): CachedTile | null {
|
|
417
476
|
let z = tile.z - 1;
|
|
418
477
|
let x = tile.x >> 1;
|
|
419
478
|
let y = tile.y >> 1;
|
|
420
479
|
for (let up = 0; up < levels && z >= 0; up++, z--, x >>= 1, y >>= 1) {
|
|
421
|
-
const entry = this._entries.get(this.key(
|
|
480
|
+
const entry = this._entries.get(this.key(source, { z, x, y }));
|
|
422
481
|
// `shown` is finished by construction, so an ancestor is never a
|
|
423
482
|
// half-drawn picture.
|
|
424
|
-
if (entry?.shown) {
|
|
483
|
+
if (entry?.shown && drawnFor(entry.shown, generation)) {
|
|
425
484
|
// Stamped, because for as long as it is covering a hole it is on
|
|
426
485
|
// screen — and an unstamped entry is the *first* thing eviction
|
|
427
486
|
// takes, which would drop the only picture the map is showing.
|
|
@@ -445,11 +504,14 @@ export class TileCache {
|
|
|
445
504
|
* `depth` is how many levels down to look, and it is small on purpose: a
|
|
446
505
|
* level down is 4 tiles, two is 16, and beyond that the pieces are too
|
|
447
506
|
* small to be worth the composites.
|
|
507
|
+
*
|
|
508
|
+
* `generation` as for {@link ancestorWithSurface}.
|
|
448
509
|
*/
|
|
449
510
|
descendantsWithSurface(
|
|
450
|
-
|
|
511
|
+
source: MapSource,
|
|
451
512
|
tile: TileId,
|
|
452
513
|
depth = 2,
|
|
514
|
+
generation?: number,
|
|
453
515
|
): { entry: CachedTile; x: number; y: number; span: number }[] {
|
|
454
516
|
for (let down = 1; down <= depth; down++) {
|
|
455
517
|
const span = 1 << down;
|
|
@@ -458,13 +520,13 @@ export class TileCache {
|
|
|
458
520
|
for (let dy = 0; dy < span; dy++) {
|
|
459
521
|
for (let dx = 0; dx < span; dx++) {
|
|
460
522
|
const entry = this._entries.get(
|
|
461
|
-
this.key(
|
|
523
|
+
this.key(source, {
|
|
462
524
|
z: tile.z + down,
|
|
463
525
|
x: (tile.x << down) + dx,
|
|
464
526
|
y: (tile.y << down) + dy,
|
|
465
527
|
}),
|
|
466
528
|
);
|
|
467
|
-
if (entry?.shown) {
|
|
529
|
+
if (entry?.shown && drawnFor(entry.shown, generation)) {
|
|
468
530
|
entry.lastUsed = this._frame;
|
|
469
531
|
found.push({ entry, x: dx, y: dy, span });
|
|
470
532
|
}
|
|
@@ -493,12 +555,19 @@ export class TileCache {
|
|
|
493
555
|
* the tile is blank for the several frames it takes to redraw, which
|
|
494
556
|
* above a source's `maxZoom` happens at every integer zoom — the same
|
|
495
557
|
* z14 tile serves 15, 16, 17 and on.
|
|
558
|
+
*
|
|
559
|
+
* A draft that is finished but not yet promoted — a restyle holding the
|
|
560
|
+
* old style up until the whole view is ready — matches like any other and
|
|
561
|
+
* comes back as it is, so it is not drawn twice.
|
|
496
562
|
*/
|
|
497
563
|
beginRender(
|
|
498
564
|
entry: CachedTile,
|
|
499
565
|
size: number,
|
|
500
566
|
zoom: number,
|
|
501
567
|
make: SurfaceFactory,
|
|
568
|
+
/** False for a raster tile, whose pixels are the provider's and no
|
|
569
|
+
* style's — see {@link TileRender.styled}. */
|
|
570
|
+
styled = true,
|
|
502
571
|
): TileRender | null {
|
|
503
572
|
if (this._matches(entry.shown, size, zoom)) return null;
|
|
504
573
|
if (this._matches(entry.drawing, size, zoom)) return entry.drawing;
|
|
@@ -515,6 +584,7 @@ export class TileCache {
|
|
|
515
584
|
size,
|
|
516
585
|
zoom,
|
|
517
586
|
generation: this._generation,
|
|
587
|
+
styled,
|
|
518
588
|
progress: 0,
|
|
519
589
|
progressLayer: 0,
|
|
520
590
|
};
|
|
@@ -530,7 +600,7 @@ export class TileCache {
|
|
|
530
600
|
render !== null &&
|
|
531
601
|
render.size === size &&
|
|
532
602
|
render.zoom === zoom &&
|
|
533
|
-
render
|
|
603
|
+
drawnFor(render, this._generation)
|
|
534
604
|
);
|
|
535
605
|
}
|
|
536
606
|
|
|
@@ -545,6 +615,33 @@ export class TileCache {
|
|
|
545
615
|
return true;
|
|
546
616
|
}
|
|
547
617
|
|
|
618
|
+
/**
|
|
619
|
+
* Put the current generation on screen in one go: every finished draft
|
|
620
|
+
* becomes its tile's picture, and every picture and draft of an earlier
|
|
621
|
+
* generation is released — apart from a raster tile's, which no style
|
|
622
|
+
* drew.
|
|
623
|
+
*
|
|
624
|
+
* The other half of a restyle. While the element holds the previous style
|
|
625
|
+
* up it does not {@link promote}, so finished drafts wait in `drawing`,
|
|
626
|
+
* and this is the frame they all land in. What is released is more than
|
|
627
|
+
* what they replace: a tile off screen still holds whatever it was last
|
|
628
|
+
* drawn in, which is now a picture of a style the map has left — never
|
|
629
|
+
* composited again, and otherwise kept until eviction got round to it.
|
|
630
|
+
*/
|
|
631
|
+
swap(): void {
|
|
632
|
+
for (const entry of this._entries.values()) {
|
|
633
|
+
if (entry.drawing && !drawnFor(entry.drawing, this._generation)) {
|
|
634
|
+
this._release(entry.drawing);
|
|
635
|
+
entry.drawing = null;
|
|
636
|
+
}
|
|
637
|
+
if (this.promote(entry)) continue;
|
|
638
|
+
if (entry.shown && !drawnFor(entry.shown, this._generation)) {
|
|
639
|
+
this._release(entry.shown);
|
|
640
|
+
entry.shown = null;
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
|
|
548
645
|
/** Note where a tile's rasterization stopped: at run `run`, having
|
|
549
646
|
* finished `layer` of its active layers (`-1` for all of them). */
|
|
550
647
|
advance(
|
|
@@ -558,14 +655,18 @@ export class TileCache {
|
|
|
558
655
|
}
|
|
559
656
|
|
|
560
657
|
/**
|
|
561
|
-
* Drop what is no longer worth keeping.
|
|
658
|
+
* Drop what is no longer worth keeping. Called once a frame, after every
|
|
659
|
+
* tile the frame still needs has been through {@link want}.
|
|
562
660
|
*
|
|
563
|
-
*
|
|
661
|
+
* A load the frame did not want is cancelled outright (see
|
|
662
|
+
* `_cancelUnwanted`). What has arrived is kept on budgets instead:
|
|
663
|
+
* surfaces first and by least-recently-wanted, because they are two
|
|
564
664
|
* orders of magnitude larger than the data behind them and much cheaper
|
|
565
|
-
* to lose
|
|
566
|
-
* network request.
|
|
665
|
+
* to lose — a dropped surface is one re-rasterization, a dropped tile is
|
|
666
|
+
* a network request.
|
|
567
667
|
*/
|
|
568
668
|
sweep(): void {
|
|
669
|
+
this._cancelUnwanted();
|
|
569
670
|
if (
|
|
570
671
|
this._surfaceBytes >
|
|
571
672
|
(this._options.surfaceBudget ?? DEFAULT_SURFACE_BUDGET)
|
|
@@ -605,6 +706,45 @@ export class TileCache {
|
|
|
605
706
|
}
|
|
606
707
|
}
|
|
607
708
|
|
|
709
|
+
/**
|
|
710
|
+
* Cancel every load the frame just drawn did not ask for.
|
|
711
|
+
*
|
|
712
|
+
* A tile panned or zoomed out of the cover — or every tile of a source
|
|
713
|
+
* taken out of `sources` — would otherwise load to the end: a request
|
|
714
|
+
* nobody is waiting for, then a full-pane repaint when it lands, because
|
|
715
|
+
* a landing tile is an `onChange`. The cover is padded, so a tile just off
|
|
716
|
+
* screen is still wanted and keeps loading. That is also the contract on
|
|
717
|
+
* the element: it wants the whole cover on every frame, clipped and
|
|
718
|
+
* mid-gesture ones included, or what it skipped is aborted here and
|
|
719
|
+
* fetched again.
|
|
720
|
+
*
|
|
721
|
+
* Only loads: data that has arrived stays on the budgets above, and is
|
|
722
|
+
* what makes panning back, or switching back to a provider, free.
|
|
723
|
+
*
|
|
724
|
+
* And forgotten rather than parked. An aborted load never settles
|
|
725
|
+
* (`settle` ignores it), so an entry left in `_data` would say `'loading'`
|
|
726
|
+
* forever and never be asked for again; its renderings go with it, since
|
|
727
|
+
* each reads through to the same entry for life, and none has a surface to
|
|
728
|
+
* lose. The next frame that wants the tile starts over, with a new request
|
|
729
|
+
* and a new signal.
|
|
730
|
+
*/
|
|
731
|
+
private _cancelUnwanted(): void {
|
|
732
|
+
let unwanted: Set<TileDataEntry> | null = null;
|
|
733
|
+
for (const data of this._data.values()) {
|
|
734
|
+
if (data.status === 'loading' && data.lastUsed < this._frame) {
|
|
735
|
+
(unwanted ??= new Set<TileDataEntry>()).add(data);
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
if (!unwanted) return;
|
|
739
|
+
for (const entry of [...this._entries.values()]) {
|
|
740
|
+
if (unwanted.has(entry.data)) this._drop(entry);
|
|
741
|
+
}
|
|
742
|
+
for (const data of unwanted) {
|
|
743
|
+
data.abort?.();
|
|
744
|
+
this._data.delete(data.key);
|
|
745
|
+
}
|
|
746
|
+
}
|
|
747
|
+
|
|
608
748
|
private _dropSurface(entry: CachedTile): void {
|
|
609
749
|
if (entry.shown) this._release(entry.shown);
|
|
610
750
|
if (entry.drawing) this._release(entry.drawing);
|
|
@@ -647,14 +787,32 @@ export class TileCache {
|
|
|
647
787
|
return this._entries.values();
|
|
648
788
|
}
|
|
649
789
|
|
|
650
|
-
/** Every source tile whose bytes are held
|
|
651
|
-
*
|
|
652
|
-
* source
|
|
790
|
+
/** Every source tile whose bytes are held — including those of sources no
|
|
791
|
+
* longer on the map, which is what makes switching back free and why a
|
|
792
|
+
* reader filters on `source`. What labels are collected from: a label
|
|
793
|
+
* belongs to the tile the data came from, and past a source's depth many
|
|
794
|
+
* renderings share one of those. */
|
|
653
795
|
dataEntries(): IterableIterator<TileDataEntry> {
|
|
654
796
|
return this._data.values();
|
|
655
797
|
}
|
|
656
798
|
}
|
|
657
799
|
|
|
800
|
+
/**
|
|
801
|
+
* Whether a rendering can be shown for `generation`: any can when none is
|
|
802
|
+
* given, which is `progressive`; one no style drew — a raster tile's — can
|
|
803
|
+
* in every generation; any other only in the one it was drawn under.
|
|
804
|
+
*/
|
|
805
|
+
export function drawnFor(
|
|
806
|
+
render: TileRender,
|
|
807
|
+
generation: number | undefined,
|
|
808
|
+
): boolean {
|
|
809
|
+
return (
|
|
810
|
+
generation === undefined ||
|
|
811
|
+
!render.styled ||
|
|
812
|
+
render.generation === generation
|
|
813
|
+
);
|
|
814
|
+
}
|
|
815
|
+
|
|
658
816
|
/** A source's pyramid, memoized per source object so the defaults are not
|
|
659
817
|
* refilled per frame. */
|
|
660
818
|
const pyramids = new WeakMap<
|