@reearth/ezu 0.2.0 → 0.3.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 CHANGED
@@ -1,9 +1,10 @@
1
- # ezu
1
+ # @reearth/ezu
2
2
 
3
3
  Painterly map renderer compiled to WebAssembly. The JS side owns all I/O
4
4
  (HTTP, PMTiles, asset fetching); this package exposes a stateful
5
- `Renderer` that holds a parsed style document, its built graph, and an
6
- in-memory brush bank — it renders one tile at a time from raw MVT bytes.
5
+ `Renderer` that holds a parsed style document, its built graph, an
6
+ in-memory brush bank, and a per-tile binding buffer that mirrors the
7
+ style's `sources` block.
7
8
 
8
9
  ## Install
9
10
 
@@ -29,7 +30,9 @@ The package ships three builds and picks one automatically via the
29
30
  import { Renderer } from "@reearth/ezu";
30
31
 
31
32
  const renderer = new Renderer(styleJson);
32
- const png = renderer.render(mvtBytes, z, x, y);
33
+ renderer.bindSource("basemap", mvtBytes);
34
+ const png = renderer.renderTile(z, x, y);
35
+ renderer.clearSources();
33
36
  ```
34
37
 
35
38
  ### Browser (native ESM, no bundler)
@@ -54,34 +57,81 @@ function simdEnabled(): boolean;
54
57
  class Renderer {
55
58
  constructor(styleJson: string);
56
59
 
57
- setStyle(styleJson: string): number;
58
- registerBrush(name: string, mybJson: string): void;
59
- unregisterBrush(name: string): boolean;
60
- clearBrushes(): void;
61
- brushCount(): number;
60
+ setStyle(styleJson: string): number; // → new node count
62
61
  readonly tileSize: number;
63
62
 
64
- render(mvtBytes: Uint8Array | null, z: number, x: number, y: number): Uint8Array; // PNG
65
- renderWebp(mvtBytes: Uint8Array | null, z: number, x: number, y: number): Uint8Array; // lossless WebP
66
- renderRgba(mvtBytes: Uint8Array | null, z: number, x: number, y: number): Uint8Array; // straight RGBA
67
-
68
- renderAt(mvtBytes: Uint8Array | null, z: number, x: number, y: number,
69
- tileSize: number, pad: number): Uint8Array;
70
- renderWebpAt(mvtBytes: Uint8Array | null, z: number, x: number, y: number,
71
- tileSize: number, pad: number): Uint8Array;
72
- renderRgbaAt(mvtBytes: Uint8Array | null, z: number, x: number, y: number,
73
- tileSize: number, pad: number): Uint8Array;
63
+ // Bind tile bytes under a `sources.<name>` entry from the style.
64
+ // The renderer dispatches on the source's declared `type`:
65
+ // - brush → parse `.myb` JSON, persistent
66
+ // - image → decode PNG/WebP, persistent
67
+ // - mvt/pmtiles → decode at render time, cleared by `clearSources`
68
+ // - dem → decode + stitch at render time. Pass each neighbour
69
+ // tile with `{ coord: [dx, dy] }` (dx, dy ∈ {-1, 0, 1}).
70
+ bindSource(name: string, bytes: Uint8Array,
71
+ opts?: { coord?: [number, number] }): void;
72
+ clearSources(): void;
73
+ boundSources(): string[]; // names with at least one pending tile-scoped binding
74
+
75
+ // Single unified render. `opts.format` picks the encoder; `tileSize`
76
+ // / `pad` override the canvas for hi-DPI / preview.
77
+ renderTile(z: number, x: number, y: number, opts?: {
78
+ format?: "png" | "webp" | "rgba"; // default "png"
79
+ tileSize?: number;
80
+ pad?: number;
81
+ png?: { compression?: "fast" | "default" | "best" };
82
+ }): Uint8Array;
74
83
 
75
84
  free(): void;
76
85
  }
77
86
  ```
78
87
 
79
- Pass `null` for `mvtBytes` to render the style's paper background only
80
- (out-of-range tiles, archive misses, etc.).
88
+ ## Output formats
89
+
90
+ - **`format: "png"`** (default) returns PNG bytes — feed to `<img>`
91
+ via `URL.createObjectURL(new Blob([buf], { type: "image/png" }))`.
92
+ - **`format: "webp"`** returns lossless WebP bytes (~15 % smaller
93
+ than PNG on painterly tiles). Pure-Rust encoder, no native deps.
94
+ - **`format: "rgba"`** returns straight (un-premultiplied) 8-bit
95
+ RGBA bytes (`tile_size * tile_size * 4`) — feed directly to
96
+ `ctx.putImageData(new ImageData(new Uint8ClampedArray(buf.buffer), w, h), 0, 0)`
97
+ and skip the PNG decode round trip.
98
+
99
+ WebP is lossless via `image-webp` and has no quality knob — for
100
+ lossy WebP without C deps, render as `"rgba"` then call
101
+ `OffscreenCanvas.convertToBlob({ type: "image/webp", quality })`.
102
+
103
+ ## Missing tiles
104
+
105
+ Don't bind any MVT source for that tile — `renderTile` returns the
106
+ style's paper background. `features` source nodes see no
107
+ `tile.<layer>` binding and emit an empty layer, so downstream paint
108
+ nodes short-circuit.
109
+
110
+ ## Errors
81
111
 
82
- Errors are thrown as JavaScript `Error` instances whose `.name`
83
- discriminates the kind: `InvalidStyle`, `BrushParse`, `MvtDecode`,
84
- `RenderFailed`, `PngEncode`, `WebpEncode`.
112
+ Every fallible method throws a JavaScript `Error` whose `.name`
113
+ discriminates the kind:
114
+
115
+ | `.name` | When |
116
+ |---|---|
117
+ | `InvalidStyle` | `new Renderer(...)` / `setStyle(...)` rejected the JSON |
118
+ | `BrushParse` | `registerBrush(...)` or `bindSource` on a brush source couldn't parse the `.myb` JSON |
119
+ | `MvtDecode` | `bindSource` (mvt/pmtiles) or render couldn't decode the MVT bytes |
120
+ | `DemDecode` | `bindSource` (dem) couldn't decode the raster-DEM tile |
121
+ | `UnknownSource`| `bindSource` was given a name not in the style's `sources` block, or `coord` was malformed |
122
+ | `RenderFailed` | A node `eval` failed (e.g. missing brush, downcast mismatch) |
123
+ | `PngEncode` | PNG encoding failed |
124
+ | `WebpEncode` | WebP encoding failed |
125
+
126
+ ```js
127
+ try {
128
+ await loadAndRender();
129
+ } catch (e) {
130
+ if (e.name === "InvalidStyle") showStyleError(e.message);
131
+ else if (e.name === "MvtDecode") showFetchError(e.message);
132
+ else throw e;
133
+ }
134
+ ```
85
135
 
86
136
  ## License
87
137
 
package/bundler/ezu.d.ts CHANGED
@@ -58,64 +58,50 @@ export class Renderer {
58
58
  free(): void;
59
59
  [Symbol.dispose](): void;
60
60
  /**
61
- * Number of brushes currently registered.
62
- */
63
- brushCount(): number;
64
- /**
65
- * Drop every registered brush.
66
- */
67
- clearBrushes(): void;
68
- /**
69
- * Build a renderer from a style JSON document.
70
- */
71
- constructor(style_json: string);
72
- /**
73
- * Register a `.myb` brush under `name` so a `brush-file` node with
74
- * `src: "@name"` (via the style's `assets` map) resolves to it.
75
- * Re-registering the same name replaces the previous entry.
76
- */
77
- registerBrush(name: string, myb_json: string): void;
78
- /**
79
- * Render a single tile to PNG bytes using the style's `tile-size` / `pad`.
80
- * Pass `null` for `mvtBytes` to get a paper-only tile.
61
+ * Bind raw tile bytes under a `sources.<name>` entry from the style.
62
+ * The renderer dispatches on the source's declared `type`:
81
63
  *
82
- * Optional `options`: `{ png: { compression: 'fast' | 'default' | 'best' } }`.
83
- */
84
- render(mvt_bytes: Uint8Array | null | undefined, z: number, x: number, y: number, options?: object | null): Uint8Array;
85
- /**
86
- * Like `render` but with `tile_size` / `pad` overridden — useful for
87
- * hi-DPI / preview rendering without mutating the style.
64
+ * - `mvt` / `pmtiles` → decode MVT layers eagerly; layers are bound
65
+ * as `tile.<layer>` when [`render_tile`] runs.
66
+ * - `dem` → store the raw raster-DEM bytes per `(dx, dy)` neighbour
67
+ * offset. The centre tile is `coord: [0, 0]` (default). Decoding
68
+ * and 3×3 stitching happen at render time once the tile id is known.
69
+ *
70
+ * `opts` is a JS object: `{ coord?: [dx, dy] }`. Throws
71
+ * `UnknownSource` if `name` doesn't match any entry in the style's
72
+ * `sources` block, `MvtDecode` if MVT bytes don't parse, and
73
+ * `DemDecode` for non-image DEM bytes (the decode itself runs at
74
+ * render time, but obvious cases are caught here).
88
75
  */
89
- renderAt(mvt_bytes: Uint8Array | null | undefined, z: number, x: number, y: number, tile_size: number, pad: number, options?: object | null): Uint8Array;
76
+ bindSource(name: string, bytes: Uint8Array, opts?: object | null): void;
90
77
  /**
91
- * Render a single tile to straight RGBA8 bytes (`tile_w * tile_h * 4`).
78
+ * Names of every source with at least one pending binding.
79
+ * Order matches the style's `sources` declaration order.
92
80
  */
93
- renderRgba(mvt_bytes: Uint8Array | null | undefined, z: number, x: number, y: number): Uint8Array;
81
+ boundSources(): string[];
94
82
  /**
95
- * Like `renderRgba` but with `tile_size` / `pad` overridden.
83
+ * Drop every pending source binding. Call between tile renders.
96
84
  */
97
- renderRgbaAt(mvt_bytes: Uint8Array | null | undefined, z: number, x: number, y: number, tile_size: number, pad: number): Uint8Array;
85
+ clearSources(): void;
98
86
  /**
99
- * Render a single tile to lossless WebP bytes. Smaller than PNG
100
- * for the same painterly content and decoded natively by every
101
- * modern browser. WebP is lossless-only via the pure-Rust
102
- * `image-webp` codec; for lossy WebP, see the
103
- * `OffscreenCanvas.convertToBlob` recipe in the crate README.
87
+ * Build a renderer from a style JSON document.
104
88
  */
105
- renderWebp(mvt_bytes: Uint8Array | null | undefined, z: number, x: number, y: number, options?: object | null): Uint8Array;
89
+ constructor(style_json: string);
106
90
  /**
107
- * Like `renderWebp` but with `tile_size` / `pad` overridden.
91
+ * Render a single tile using whatever sources are currently bound.
92
+ *
93
+ * `opts` (JS object, all fields optional):
94
+ * - `format`: `"png"` (default) / `"webp"` / `"rgba"`
95
+ * - `tileSize`, `pad`: override the style's canvas size for this
96
+ * call (hi-DPI / preview)
97
+ * - `png`: `{ compression?: "fast" | "default" | "best" }`
108
98
  */
109
- renderWebpAt(mvt_bytes: Uint8Array | null | undefined, z: number, x: number, y: number, tile_size: number, pad: number, options?: object | null): Uint8Array;
99
+ renderTile(z: number, x: number, y: number, opts?: object | null): Uint8Array;
110
100
  /**
111
101
  * Replace the active style. Returns the new node count. Invalidates
112
- * the intermediate cache.
102
+ * the intermediate cache and drops any pending source bindings.
113
103
  */
114
104
  setStyle(style_json: string): number;
115
- /**
116
- * Remove a brush by name. Returns `true` if the brush existed.
117
- */
118
- unregisterBrush(name: string): boolean;
119
105
  /**
120
106
  * `tile-size` declared by the current style.
121
107
  */
package/bundler/ezu_bg.js CHANGED
@@ -109,18 +109,50 @@ export class Renderer {
109
109
  wasm.__wbg_renderer_free(ptr, 0);
110
110
  }
111
111
  /**
112
- * Number of brushes currently registered.
113
- * @returns {number}
112
+ * Bind raw tile bytes under a `sources.<name>` entry from the style.
113
+ * The renderer dispatches on the source's declared `type`:
114
+ *
115
+ * - `mvt` / `pmtiles` → decode MVT layers eagerly; layers are bound
116
+ * as `tile.<layer>` when [`render_tile`] runs.
117
+ * - `dem` → store the raw raster-DEM bytes per `(dx, dy)` neighbour
118
+ * offset. The centre tile is `coord: [0, 0]` (default). Decoding
119
+ * and 3×3 stitching happen at render time once the tile id is known.
120
+ *
121
+ * `opts` is a JS object: `{ coord?: [dx, dy] }`. Throws
122
+ * `UnknownSource` if `name` doesn't match any entry in the style's
123
+ * `sources` block, `MvtDecode` if MVT bytes don't parse, and
124
+ * `DemDecode` for non-image DEM bytes (the decode itself runs at
125
+ * render time, but obvious cases are caught here).
126
+ * @param {string} name
127
+ * @param {Uint8Array} bytes
128
+ * @param {object | null} [opts]
114
129
  */
115
- brushCount() {
116
- const ret = wasm.renderer_brushCount(this.__wbg_ptr);
117
- return ret >>> 0;
130
+ bindSource(name, bytes, opts) {
131
+ const ptr0 = passStringToWasm0(name, wasm.__wbindgen_malloc_command_export, wasm.__wbindgen_realloc_command_export);
132
+ const len0 = WASM_VECTOR_LEN;
133
+ const ptr1 = passArray8ToWasm0(bytes, wasm.__wbindgen_malloc_command_export);
134
+ const len1 = WASM_VECTOR_LEN;
135
+ const ret = wasm.renderer_bindSource(this.__wbg_ptr, ptr0, len0, ptr1, len1, isLikeNone(opts) ? 0 : addToExternrefTable0(opts));
136
+ if (ret[1]) {
137
+ throw takeFromExternrefTable0(ret[0]);
138
+ }
139
+ }
140
+ /**
141
+ * Names of every source with at least one pending binding.
142
+ * Order matches the style's `sources` declaration order.
143
+ * @returns {string[]}
144
+ */
145
+ boundSources() {
146
+ const ret = wasm.renderer_boundSources(this.__wbg_ptr);
147
+ var v1 = getArrayJsValueFromWasm0(ret[0], ret[1]).slice();
148
+ wasm.__wbindgen_free_command_export(ret[0], ret[1] * 4, 4);
149
+ return v1;
118
150
  }
119
151
  /**
120
- * Drop every registered brush.
152
+ * Drop every pending source binding. Call between tile renders.
121
153
  */
122
- clearBrushes() {
123
- wasm.renderer_clearBrushes(this.__wbg_ptr);
154
+ clearSources() {
155
+ wasm.renderer_clearSources(this.__wbg_ptr);
124
156
  }
125
157
  /**
126
158
  * Build a renderer from a style JSON document.
@@ -138,157 +170,31 @@ export class Renderer {
138
170
  return this;
139
171
  }
140
172
  /**
141
- * Register a `.myb` brush under `name` so a `brush-file` node with
142
- * `src: "@name"` (via the style's `assets` map) resolves to it.
143
- * Re-registering the same name replaces the previous entry.
144
- * @param {string} name
145
- * @param {string} myb_json
146
- */
147
- registerBrush(name, myb_json) {
148
- const ptr0 = passStringToWasm0(name, wasm.__wbindgen_malloc_command_export, wasm.__wbindgen_realloc_command_export);
149
- const len0 = WASM_VECTOR_LEN;
150
- const ptr1 = passStringToWasm0(myb_json, wasm.__wbindgen_malloc_command_export, wasm.__wbindgen_realloc_command_export);
151
- const len1 = WASM_VECTOR_LEN;
152
- const ret = wasm.renderer_registerBrush(this.__wbg_ptr, ptr0, len0, ptr1, len1);
153
- if (ret[1]) {
154
- throw takeFromExternrefTable0(ret[0]);
155
- }
156
- }
157
- /**
158
- * Render a single tile to PNG bytes using the style's `tile-size` / `pad`.
159
- * Pass `null` for `mvtBytes` to get a paper-only tile.
173
+ * Render a single tile using whatever sources are currently bound.
160
174
  *
161
- * Optional `options`: `{ png: { compression: 'fast' | 'default' | 'best' } }`.
162
- * @param {Uint8Array | null | undefined} mvt_bytes
163
- * @param {number} z
164
- * @param {number} x
165
- * @param {number} y
166
- * @param {object | null} [options]
167
- * @returns {Uint8Array}
168
- */
169
- render(mvt_bytes, z, x, y, options) {
170
- var ptr0 = isLikeNone(mvt_bytes) ? 0 : passArray8ToWasm0(mvt_bytes, wasm.__wbindgen_malloc_command_export);
171
- var len0 = WASM_VECTOR_LEN;
172
- const ret = wasm.renderer_render(this.__wbg_ptr, ptr0, len0, z, x, y, isLikeNone(options) ? 0 : addToExternrefTable0(options));
173
- if (ret[3]) {
174
- throw takeFromExternrefTable0(ret[2]);
175
- }
176
- var v2 = getArrayU8FromWasm0(ret[0], ret[1]).slice();
177
- wasm.__wbindgen_free_command_export(ret[0], ret[1] * 1, 1);
178
- return v2;
179
- }
180
- /**
181
- * Like `render` but with `tile_size` / `pad` overridden — useful for
182
- * hi-DPI / preview rendering without mutating the style.
183
- * @param {Uint8Array | null | undefined} mvt_bytes
184
- * @param {number} z
185
- * @param {number} x
186
- * @param {number} y
187
- * @param {number} tile_size
188
- * @param {number} pad
189
- * @param {object | null} [options]
190
- * @returns {Uint8Array}
191
- */
192
- renderAt(mvt_bytes, z, x, y, tile_size, pad, options) {
193
- var ptr0 = isLikeNone(mvt_bytes) ? 0 : passArray8ToWasm0(mvt_bytes, wasm.__wbindgen_malloc_command_export);
194
- var len0 = WASM_VECTOR_LEN;
195
- const ret = wasm.renderer_renderAt(this.__wbg_ptr, ptr0, len0, z, x, y, tile_size, pad, isLikeNone(options) ? 0 : addToExternrefTable0(options));
196
- if (ret[3]) {
197
- throw takeFromExternrefTable0(ret[2]);
198
- }
199
- var v2 = getArrayU8FromWasm0(ret[0], ret[1]).slice();
200
- wasm.__wbindgen_free_command_export(ret[0], ret[1] * 1, 1);
201
- return v2;
202
- }
203
- /**
204
- * Render a single tile to straight RGBA8 bytes (`tile_w * tile_h * 4`).
205
- * @param {Uint8Array | null | undefined} mvt_bytes
206
- * @param {number} z
207
- * @param {number} x
208
- * @param {number} y
209
- * @returns {Uint8Array}
210
- */
211
- renderRgba(mvt_bytes, z, x, y) {
212
- var ptr0 = isLikeNone(mvt_bytes) ? 0 : passArray8ToWasm0(mvt_bytes, wasm.__wbindgen_malloc_command_export);
213
- var len0 = WASM_VECTOR_LEN;
214
- const ret = wasm.renderer_renderRgba(this.__wbg_ptr, ptr0, len0, z, x, y);
215
- if (ret[3]) {
216
- throw takeFromExternrefTable0(ret[2]);
217
- }
218
- var v2 = getArrayU8FromWasm0(ret[0], ret[1]).slice();
219
- wasm.__wbindgen_free_command_export(ret[0], ret[1] * 1, 1);
220
- return v2;
221
- }
222
- /**
223
- * Like `renderRgba` but with `tile_size` / `pad` overridden.
224
- * @param {Uint8Array | null | undefined} mvt_bytes
225
- * @param {number} z
226
- * @param {number} x
227
- * @param {number} y
228
- * @param {number} tile_size
229
- * @param {number} pad
230
- * @returns {Uint8Array}
231
- */
232
- renderRgbaAt(mvt_bytes, z, x, y, tile_size, pad) {
233
- var ptr0 = isLikeNone(mvt_bytes) ? 0 : passArray8ToWasm0(mvt_bytes, wasm.__wbindgen_malloc_command_export);
234
- var len0 = WASM_VECTOR_LEN;
235
- const ret = wasm.renderer_renderRgbaAt(this.__wbg_ptr, ptr0, len0, z, x, y, tile_size, pad);
236
- if (ret[3]) {
237
- throw takeFromExternrefTable0(ret[2]);
238
- }
239
- var v2 = getArrayU8FromWasm0(ret[0], ret[1]).slice();
240
- wasm.__wbindgen_free_command_export(ret[0], ret[1] * 1, 1);
241
- return v2;
242
- }
243
- /**
244
- * Render a single tile to lossless WebP bytes. Smaller than PNG
245
- * for the same painterly content and decoded natively by every
246
- * modern browser. WebP is lossless-only via the pure-Rust
247
- * `image-webp` codec; for lossy WebP, see the
248
- * `OffscreenCanvas.convertToBlob` recipe in the crate README.
249
- * @param {Uint8Array | null | undefined} mvt_bytes
250
- * @param {number} z
251
- * @param {number} x
252
- * @param {number} y
253
- * @param {object | null} [options]
254
- * @returns {Uint8Array}
255
- */
256
- renderWebp(mvt_bytes, z, x, y, options) {
257
- var ptr0 = isLikeNone(mvt_bytes) ? 0 : passArray8ToWasm0(mvt_bytes, wasm.__wbindgen_malloc_command_export);
258
- var len0 = WASM_VECTOR_LEN;
259
- const ret = wasm.renderer_renderWebp(this.__wbg_ptr, ptr0, len0, z, x, y, isLikeNone(options) ? 0 : addToExternrefTable0(options));
260
- if (ret[3]) {
261
- throw takeFromExternrefTable0(ret[2]);
262
- }
263
- var v2 = getArrayU8FromWasm0(ret[0], ret[1]).slice();
264
- wasm.__wbindgen_free_command_export(ret[0], ret[1] * 1, 1);
265
- return v2;
266
- }
267
- /**
268
- * Like `renderWebp` but with `tile_size` / `pad` overridden.
269
- * @param {Uint8Array | null | undefined} mvt_bytes
175
+ * `opts` (JS object, all fields optional):
176
+ * - `format`: `"png"` (default) / `"webp"` / `"rgba"`
177
+ * - `tileSize`, `pad`: override the style's canvas size for this
178
+ * call (hi-DPI / preview)
179
+ * - `png`: `{ compression?: "fast" | "default" | "best" }`
270
180
  * @param {number} z
271
181
  * @param {number} x
272
182
  * @param {number} y
273
- * @param {number} tile_size
274
- * @param {number} pad
275
- * @param {object | null} [options]
183
+ * @param {object | null} [opts]
276
184
  * @returns {Uint8Array}
277
185
  */
278
- renderWebpAt(mvt_bytes, z, x, y, tile_size, pad, options) {
279
- var ptr0 = isLikeNone(mvt_bytes) ? 0 : passArray8ToWasm0(mvt_bytes, wasm.__wbindgen_malloc_command_export);
280
- var len0 = WASM_VECTOR_LEN;
281
- const ret = wasm.renderer_renderWebpAt(this.__wbg_ptr, ptr0, len0, z, x, y, tile_size, pad, isLikeNone(options) ? 0 : addToExternrefTable0(options));
186
+ renderTile(z, x, y, opts) {
187
+ const ret = wasm.renderer_renderTile(this.__wbg_ptr, z, x, y, isLikeNone(opts) ? 0 : addToExternrefTable0(opts));
282
188
  if (ret[3]) {
283
189
  throw takeFromExternrefTable0(ret[2]);
284
190
  }
285
- var v2 = getArrayU8FromWasm0(ret[0], ret[1]).slice();
191
+ var v1 = getArrayU8FromWasm0(ret[0], ret[1]).slice();
286
192
  wasm.__wbindgen_free_command_export(ret[0], ret[1] * 1, 1);
287
- return v2;
193
+ return v1;
288
194
  }
289
195
  /**
290
196
  * Replace the active style. Returns the new node count. Invalidates
291
- * the intermediate cache.
197
+ * the intermediate cache and drops any pending source bindings.
292
198
  * @param {string} style_json
293
199
  * @returns {number}
294
200
  */
@@ -309,17 +215,6 @@ export class Renderer {
309
215
  const ret = wasm.renderer_tileSize(this.__wbg_ptr);
310
216
  return ret >>> 0;
311
217
  }
312
- /**
313
- * Remove a brush by name. Returns `true` if the brush existed.
314
- * @param {string} name
315
- * @returns {boolean}
316
- */
317
- unregisterBrush(name) {
318
- const ptr0 = passStringToWasm0(name, wasm.__wbindgen_malloc_command_export, wasm.__wbindgen_realloc_command_export);
319
- const len0 = WASM_VECTOR_LEN;
320
- const ret = wasm.renderer_unregisterBrush(this.__wbg_ptr, ptr0, len0);
321
- return ret !== 0;
322
- }
323
218
  }
324
219
  if (Symbol.dispose) Renderer.prototype[Symbol.dispose] = Renderer.prototype.free;
325
220
 
@@ -332,6 +227,20 @@ export function simdEnabled() {
332
227
  const ret = wasm.simdEnabled();
333
228
  return ret !== 0;
334
229
  }
230
+ export function __wbg___wbindgen_is_null_2042690d351e14f0(arg0) {
231
+ const ret = arg0 === null;
232
+ return ret;
233
+ }
234
+ export function __wbg___wbindgen_is_undefined_35bb9f4c7fd651d5(arg0) {
235
+ const ret = arg0 === undefined;
236
+ return ret;
237
+ }
238
+ export function __wbg___wbindgen_number_get_f73a1244370fcc2c(arg0, arg1) {
239
+ const obj = arg1;
240
+ const ret = typeof(obj) === 'number' ? obj : undefined;
241
+ getDataViewMemory0().setFloat64(arg0 + 8 * 1, isLikeNone(ret) ? 0 : ret, true);
242
+ getDataViewMemory0().setInt32(arg0 + 4 * 0, !isLikeNone(ret), true);
243
+ }
335
244
  export function __wbg___wbindgen_string_get_d109740c0d18f4d7(arg0, arg1) {
336
245
  const obj = arg1;
337
246
  const ret = typeof(obj) === 'string' ? obj : undefined;
@@ -358,6 +267,10 @@ export function __wbg_error_a6fa202b58aa1cd3(arg0, arg1) {
358
267
  wasm.__wbindgen_free_command_export(deferred0_0, deferred0_1, 1);
359
268
  }
360
269
  }
270
+ export function __wbg_get_98fdf51d029a75eb(arg0, arg1) {
271
+ const ret = arg0[arg1 >>> 0];
272
+ return ret;
273
+ }
361
274
  export function __wbg_get_dcf82ab8aad1a593() { return handleError(function (arg0, arg1) {
362
275
  const ret = Reflect.get(arg0, arg1);
363
276
  return ret;
@@ -372,6 +285,14 @@ export function __wbg_instanceof_Object_03924e0dbda74bd8(arg0) {
372
285
  const ret = result;
373
286
  return ret;
374
287
  }
288
+ export function __wbg_isArray_94898ed3aad6947b(arg0) {
289
+ const ret = Array.isArray(arg0);
290
+ return ret;
291
+ }
292
+ export function __wbg_length_2591a0f4f659a55c(arg0) {
293
+ const ret = arg0.length;
294
+ return ret;
295
+ }
375
296
  export function __wbg_new_02d162bc6cf02f60() {
376
297
  const ret = new Object();
377
298
  return ret;
Binary file
@@ -11,19 +11,13 @@ export const logsink_len: (a: number) => number;
11
11
  export const logsink_new: (a: number, b: number) => [number, number, number];
12
12
  export const logsink_onEvent: (a: number, b: number) => void;
13
13
  export const logsink_setCapacity: (a: number, b: number) => void;
14
- export const renderer_brushCount: (a: number) => number;
15
- export const renderer_clearBrushes: (a: number) => void;
14
+ export const renderer_bindSource: (a: number, b: number, c: number, d: number, e: number, f: number) => [number, number];
15
+ export const renderer_boundSources: (a: number) => [number, number];
16
+ export const renderer_clearSources: (a: number) => void;
16
17
  export const renderer_new: (a: number, b: number) => [number, number, number];
17
- export const renderer_registerBrush: (a: number, b: number, c: number, d: number, e: number) => [number, number];
18
- export const renderer_render: (a: number, b: number, c: number, d: number, e: number, f: number, g: number) => [number, number, number, number];
19
- export const renderer_renderAt: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number) => [number, number, number, number];
20
- export const renderer_renderRgba: (a: number, b: number, c: number, d: number, e: number, f: number) => [number, number, number, number];
21
- export const renderer_renderRgbaAt: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number) => [number, number, number, number];
22
- export const renderer_renderWebp: (a: number, b: number, c: number, d: number, e: number, f: number, g: number) => [number, number, number, number];
23
- export const renderer_renderWebpAt: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number) => [number, number, number, number];
18
+ export const renderer_renderTile: (a: number, b: number, c: number, d: number, e: number) => [number, number, number, number];
24
19
  export const renderer_setStyle: (a: number, b: number, c: number) => [number, number, number];
25
20
  export const renderer_tileSize: (a: number) => number;
26
- export const renderer_unregisterBrush: (a: number, b: number, c: number) => number;
27
21
  export const simdEnabled: () => number;
28
22
  export const __wbindgen_malloc_command_export: (a: number, b: number) => number;
29
23
  export const __wbindgen_realloc_command_export: (a: number, b: number, c: number, d: number) => number;
package/nodejs/ezu.d.ts CHANGED
@@ -58,64 +58,50 @@ export class Renderer {
58
58
  free(): void;
59
59
  [Symbol.dispose](): void;
60
60
  /**
61
- * Number of brushes currently registered.
62
- */
63
- brushCount(): number;
64
- /**
65
- * Drop every registered brush.
66
- */
67
- clearBrushes(): void;
68
- /**
69
- * Build a renderer from a style JSON document.
70
- */
71
- constructor(style_json: string);
72
- /**
73
- * Register a `.myb` brush under `name` so a `brush-file` node with
74
- * `src: "@name"` (via the style's `assets` map) resolves to it.
75
- * Re-registering the same name replaces the previous entry.
76
- */
77
- registerBrush(name: string, myb_json: string): void;
78
- /**
79
- * Render a single tile to PNG bytes using the style's `tile-size` / `pad`.
80
- * Pass `null` for `mvtBytes` to get a paper-only tile.
61
+ * Bind raw tile bytes under a `sources.<name>` entry from the style.
62
+ * The renderer dispatches on the source's declared `type`:
81
63
  *
82
- * Optional `options`: `{ png: { compression: 'fast' | 'default' | 'best' } }`.
83
- */
84
- render(mvt_bytes: Uint8Array | null | undefined, z: number, x: number, y: number, options?: object | null): Uint8Array;
85
- /**
86
- * Like `render` but with `tile_size` / `pad` overridden — useful for
87
- * hi-DPI / preview rendering without mutating the style.
64
+ * - `mvt` / `pmtiles` → decode MVT layers eagerly; layers are bound
65
+ * as `tile.<layer>` when [`render_tile`] runs.
66
+ * - `dem` → store the raw raster-DEM bytes per `(dx, dy)` neighbour
67
+ * offset. The centre tile is `coord: [0, 0]` (default). Decoding
68
+ * and 3×3 stitching happen at render time once the tile id is known.
69
+ *
70
+ * `opts` is a JS object: `{ coord?: [dx, dy] }`. Throws
71
+ * `UnknownSource` if `name` doesn't match any entry in the style's
72
+ * `sources` block, `MvtDecode` if MVT bytes don't parse, and
73
+ * `DemDecode` for non-image DEM bytes (the decode itself runs at
74
+ * render time, but obvious cases are caught here).
88
75
  */
89
- renderAt(mvt_bytes: Uint8Array | null | undefined, z: number, x: number, y: number, tile_size: number, pad: number, options?: object | null): Uint8Array;
76
+ bindSource(name: string, bytes: Uint8Array, opts?: object | null): void;
90
77
  /**
91
- * Render a single tile to straight RGBA8 bytes (`tile_w * tile_h * 4`).
78
+ * Names of every source with at least one pending binding.
79
+ * Order matches the style's `sources` declaration order.
92
80
  */
93
- renderRgba(mvt_bytes: Uint8Array | null | undefined, z: number, x: number, y: number): Uint8Array;
81
+ boundSources(): string[];
94
82
  /**
95
- * Like `renderRgba` but with `tile_size` / `pad` overridden.
83
+ * Drop every pending source binding. Call between tile renders.
96
84
  */
97
- renderRgbaAt(mvt_bytes: Uint8Array | null | undefined, z: number, x: number, y: number, tile_size: number, pad: number): Uint8Array;
85
+ clearSources(): void;
98
86
  /**
99
- * Render a single tile to lossless WebP bytes. Smaller than PNG
100
- * for the same painterly content and decoded natively by every
101
- * modern browser. WebP is lossless-only via the pure-Rust
102
- * `image-webp` codec; for lossy WebP, see the
103
- * `OffscreenCanvas.convertToBlob` recipe in the crate README.
87
+ * Build a renderer from a style JSON document.
104
88
  */
105
- renderWebp(mvt_bytes: Uint8Array | null | undefined, z: number, x: number, y: number, options?: object | null): Uint8Array;
89
+ constructor(style_json: string);
106
90
  /**
107
- * Like `renderWebp` but with `tile_size` / `pad` overridden.
91
+ * Render a single tile using whatever sources are currently bound.
92
+ *
93
+ * `opts` (JS object, all fields optional):
94
+ * - `format`: `"png"` (default) / `"webp"` / `"rgba"`
95
+ * - `tileSize`, `pad`: override the style's canvas size for this
96
+ * call (hi-DPI / preview)
97
+ * - `png`: `{ compression?: "fast" | "default" | "best" }`
108
98
  */
109
- renderWebpAt(mvt_bytes: Uint8Array | null | undefined, z: number, x: number, y: number, tile_size: number, pad: number, options?: object | null): Uint8Array;
99
+ renderTile(z: number, x: number, y: number, opts?: object | null): Uint8Array;
110
100
  /**
111
101
  * Replace the active style. Returns the new node count. Invalidates
112
- * the intermediate cache.
102
+ * the intermediate cache and drops any pending source bindings.
113
103
  */
114
104
  setStyle(style_json: string): number;
115
- /**
116
- * Remove a brush by name. Returns `true` if the brush existed.
117
- */
118
- unregisterBrush(name: string): boolean;
119
105
  /**
120
106
  * `tile-size` declared by the current style.
121
107
  */