@reearth/ezu 0.4.2 → 0.5.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/web/ezu.js CHANGED
@@ -180,6 +180,71 @@ export class Renderer {
180
180
  clearSources() {
181
181
  wasm.renderer_clearSources(this.__wbg_ptr);
182
182
  }
183
+ /**
184
+ * What this renderer is holding, in bytes, so a host can shed load
185
+ * *before* an allocation fails rather than after.
186
+ *
187
+ * Returns a JS object:
188
+ * - `heapBytes` — wasm linear memory committed to the **module**,
189
+ * shared by every `Renderer` in this instance. This is the number
190
+ * that meets an isolate's memory cap. It is a high-water mark:
191
+ * freeing Rust values returns them to the allocator, never to the
192
+ * host, so it only ever grows.
193
+ * - `glyphBytes` / `glyphRanges` — SDF bitmaps resident in the
194
+ * glyph bank, and how many 256-codepoint blocks they span. Glyphs
195
+ * accumulate for the life of the renderer and survive
196
+ * `clearSources`, so on a long-lived instance this is usually
197
+ * what grew. `glyphBudget` is the per-fontstack ceiling
198
+ * `setGlyphBudget` put on them, or `Infinity` if none — note
199
+ * `glyphBytes` totals *every* fontstack, so it can exceed the
200
+ * budget legitimately.
201
+ * - `fontBytes` — outline font files held in the font bank.
202
+ * - `imageBytes` — decoded pixels of bound images and sprite
203
+ * atlases.
204
+ * - `cacheBytes` / `cacheBudget` — the render cache's pixel
205
+ * payload against its own eviction budget; it bounds itself, so
206
+ * `cacheBytes` near `cacheBudget` is steady state, not a leak.
207
+ *
208
+ * These are payload sizes, not an accounting of the heap: they omit
209
+ * allocator overhead, decoded features, per-font glyph-path caches,
210
+ * and the buffers a render is using right now. Expect the parts to
211
+ * sum to less than `heapBytes`.
212
+ * @returns {object}
213
+ */
214
+ memoryUsage() {
215
+ const ret = wasm.renderer_memoryUsage(this.__wbg_ptr);
216
+ if (ret[2]) {
217
+ throw takeFromExternrefTable0(ret[1]);
218
+ }
219
+ return takeFromExternrefTable0(ret[0]);
220
+ }
221
+ /**
222
+ * Codepoints the currently bound features can require, as
223
+ * `{ [glyphsSourceName]: number[] }` sorted ascending.
224
+ *
225
+ * This is the precise form of
226
+ * [`neededGlyphRanges`](Self::needed_glyph_ranges): a host that
227
+ * can build its own glyph PBF — one message holding just these
228
+ * codepoints — transfers only the glyphs the tile draws instead
229
+ * of the whole 256-codepoint block around each of them. On CJK
230
+ * labels that is the difference between a few thousand glyphs and
231
+ * a few tens of megabytes. `bindSource` files each glyph by its
232
+ * own id, so such a subset may span any number of blocks and
233
+ * needs no particular `range` string.
234
+ *
235
+ * Hosts that can only fetch whole `{range}.pbf` files off a
236
+ * MapLibre glyphs endpoint want `neededGlyphRanges` instead. Both
237
+ * calls see the same set of codepoints and carry the same
238
+ * over-approximation caveat.
239
+ * @returns {object}
240
+ */
241
+ neededCodepoints() {
242
+ const ret = wasm.renderer_neededCodepoints(this.__wbg_ptr);
243
+ if (ret[2]) {
244
+ throw takeFromExternrefTable0(ret[1]);
245
+ }
246
+ return takeFromExternrefTable0(ret[0]);
247
+ }
183
248
  /**
184
249
  * Glyph ranges the currently bound features can require, as
185
250
  * `{ [glyphsSourceName]: number[] }` where each number is a range
@@ -191,6 +256,11 @@ export class Renderer {
191
256
  * scraping every string in the MVT, call this after binding the
192
257
  * vector sources and bind exactly the listed ranges.
193
258
  *
259
+ * A range holds 256 codepoints and a tile typically draws a
260
+ * handful of them, so this is a coarse unit to fetch in. Hosts
261
+ * that can assemble their own subset PBF should call
262
+ * [`neededCodepoints`](Self::needed_codepoints) instead.
263
+ *
194
264
  * It is an over-approximation, deliberately: a range is listed if
195
265
  * *any* feature in a text layer carries the codepoint in a property
196
266
  * the layer's `text` expression reads, without evaluating filters,
@@ -273,6 +343,34 @@ export class Renderer {
273
343
  }
274
344
  return takeFromExternrefTable0(ret[0]);
275
345
  }
346
+ /**
347
+ * Cap the glyph bytes each bound fontstack keeps resident, in
348
+ * bytes. Unset, a fontstack keeps every range ever bound to it for
349
+ * the life of the renderer — `clearSources` does not touch glyphs,
350
+ * and on a long-lived instance rendering across a basemap that is
351
+ * usually what grew.
352
+ *
353
+ * Trimming happens **after** each `renderTile`, not while binding,
354
+ * so a render never loses glyphs that were bound for it. The tile
355
+ * that just drew is therefore the most recently used, and a budget
356
+ * large enough for one tile's glyphs always keeps that tile's; what
357
+ * goes is what earlier tiles needed and this one did not. Set it
358
+ * below one tile's worth and the ceiling still holds — the stack
359
+ * empties after every render and nothing carries over, which
360
+ * renders correctly but buys no reuse.
361
+ *
362
+ * It is a per-fontstack ceiling: a style with a regular, a medium
363
+ * and an italic stack can hold three times what is set here.
364
+ *
365
+ * This host cannot refetch, so anything trimmed must be bound again
366
+ * before the next tile that needs it. `neededCodepoints()` already
367
+ * names exactly what to bind, and a host that re-binds every tile
368
+ * (rather than tracking what it sent) needs no other change.
369
+ * @param {number} bytes
370
+ */
371
+ setGlyphBudget(bytes) {
372
+ wasm.renderer_setGlyphBudget(this.__wbg_ptr, bytes);
373
+ }
276
374
  /**
277
375
  * Replace the active style. Returns the new node count. Invalidates
278
376
  * the intermediate cache and drops any pending source bindings.
@@ -299,6 +397,26 @@ export class Renderer {
299
397
  }
300
398
  if (Symbol.dispose) Renderer.prototype[Symbol.dispose] = Renderer.prototype.free;
301
399
 
400
+ /**
401
+ * Wasm linear memory currently committed to this module, in bytes.
402
+ *
403
+ * This is the figure an isolate's memory cap applies to, and the one
404
+ * to watch to shed load before an allocation fails — a refused
405
+ * `memory.grow` throws [`OutOfMemory`](oom) and ends the instance.
406
+ * It never falls: freed Rust values return to the allocator for reuse,
407
+ * but wasm cannot hand pages back to the host. So a drop in demand
408
+ * leaves the number where its peak left it, and only a fresh instance
409
+ * resets it.
410
+ *
411
+ * Module-wide, not per-`Renderer`. For what a given renderer is
412
+ * holding, and which bank to evict, call `memoryUsage()`.
413
+ * @returns {number}
414
+ */
415
+ export function heapBytes() {
416
+ const ret = wasm.heapBytes();
417
+ return ret >>> 0;
418
+ }
419
+
302
420
  /**
303
421
  * Whether the wasm binary was compiled with `+simd128`. Lets the demo
304
422
  * page label the renderer build accurately.
@@ -323,29 +441,29 @@ export function threadsEnabled() {
323
441
  function __wbg_get_imports() {
324
442
  const import0 = {
325
443
  __proto__: null,
326
- __wbg___wbindgen_boolean_get_2304fb8c853028c8: function(arg0) {
444
+ __wbg___wbindgen_boolean_get_fa956cfa2d1bd751: function(arg0) {
327
445
  const v = arg0;
328
446
  const ret = typeof(v) === 'boolean' ? v : undefined;
329
447
  return isLikeNone(ret) ? 0xFFFFFF : ret ? 1 : 0;
330
448
  },
331
- __wbg___wbindgen_is_null_2042690d351e14f0: function(arg0) {
449
+ __wbg___wbindgen_is_null_ea9085d691f535d3: function(arg0) {
332
450
  const ret = arg0 === null;
333
451
  return ret;
334
452
  },
335
- __wbg___wbindgen_is_undefined_35bb9f4c7fd651d5: function(arg0) {
453
+ __wbg___wbindgen_is_undefined_c05833b95a3cf397: function(arg0) {
336
454
  const ret = arg0 === undefined;
337
455
  return ret;
338
456
  },
339
- __wbg___wbindgen_number_get_f73a1244370fcc2c: function(arg0, arg1) {
457
+ __wbg___wbindgen_number_get_394265ed1e1b84ee: function(arg0, arg1) {
340
458
  const obj = arg1;
341
459
  const ret = typeof(obj) === 'number' ? obj : undefined;
342
460
  getDataViewMemory0().setFloat64(arg0 + 8 * 1, isLikeNone(ret) ? 0 : ret, true);
343
461
  getDataViewMemory0().setInt32(arg0 + 4 * 0, !isLikeNone(ret), true);
344
462
  },
345
- __wbg___wbindgen_rethrow_2b7cc655458909c2: function(arg0) {
463
+ __wbg___wbindgen_rethrow_4915403b40f010b4: function(arg0) {
346
464
  throw arg0;
347
465
  },
348
- __wbg___wbindgen_string_get_d109740c0d18f4d7: function(arg0, arg1) {
466
+ __wbg___wbindgen_string_get_b0ca35b86a603356: function(arg0, arg1) {
349
467
  const obj = arg1;
350
468
  const ret = typeof(obj) === 'string' ? obj : undefined;
351
469
  var ptr1 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_malloc_command_export, wasm.__wbindgen_realloc_command_export);
@@ -353,10 +471,10 @@ function __wbg_get_imports() {
353
471
  getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
354
472
  getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
355
473
  },
356
- __wbg___wbindgen_throw_9c31b086c2b26051: function(arg0, arg1) {
474
+ __wbg___wbindgen_throw_344f42d3211c4765: function(arg0, arg1) {
357
475
  throw new Error(getStringFromWasm0(arg0, arg1));
358
476
  },
359
- __wbg_call_dfde26266607c996: function() { return handleError(function (arg0, arg1, arg2) {
477
+ __wbg_call_a6e5c5dce5018821: function() { return handleError(function (arg0, arg1, arg2) {
360
478
  const ret = arg0.call(arg1, arg2);
361
479
  return ret;
362
480
  }, arguments); },
@@ -371,15 +489,15 @@ function __wbg_get_imports() {
371
489
  wasm.__wbindgen_free_command_export(deferred0_0, deferred0_1, 1);
372
490
  }
373
491
  },
374
- __wbg_get_98fdf51d029a75eb: function(arg0, arg1) {
492
+ __wbg_get_507a50627bffa49b: function(arg0, arg1) {
375
493
  const ret = arg0[arg1 >>> 0];
376
494
  return ret;
377
495
  },
378
- __wbg_get_dcf82ab8aad1a593: function() { return handleError(function (arg0, arg1) {
496
+ __wbg_get_78f252d074a84d0b: function() { return handleError(function (arg0, arg1) {
379
497
  const ret = Reflect.get(arg0, arg1);
380
498
  return ret;
381
499
  }, arguments); },
382
- __wbg_instanceof_Object_03924e0dbda74bd8: function(arg0) {
500
+ __wbg_instanceof_Object_33f20e6f12439f3e: function(arg0) {
383
501
  let result;
384
502
  try {
385
503
  result = arg0 instanceof Object;
@@ -389,43 +507,43 @@ function __wbg_get_imports() {
389
507
  const ret = result;
390
508
  return ret;
391
509
  },
392
- __wbg_isArray_94898ed3aad6947b: function(arg0) {
510
+ __wbg_isArray_0677c962b281d01a: function(arg0) {
393
511
  const ret = Array.isArray(arg0);
394
512
  return ret;
395
513
  },
396
- __wbg_length_2591a0f4f659a55c: function(arg0) {
514
+ __wbg_length_370319915dc99107: function(arg0) {
397
515
  const ret = arg0.length;
398
516
  return ret;
399
517
  },
400
- __wbg_new_02d162bc6cf02f60: function() {
401
- const ret = new Object();
518
+ __wbg_new_227d7c05414eb861: function() {
519
+ const ret = new Error();
402
520
  return ret;
403
521
  },
404
- __wbg_new_1f236d63ba0c4784: function(arg0, arg1) {
405
- const ret = new Error(getStringFromWasm0(arg0, arg1));
522
+ __wbg_new_32b398fb48b6d94a: function() {
523
+ const ret = new Array();
406
524
  return ret;
407
525
  },
408
- __wbg_new_227d7c05414eb861: function() {
409
- const ret = new Error();
526
+ __wbg_new_b667d279fd5aa943: function(arg0, arg1) {
527
+ const ret = new Error(getStringFromWasm0(arg0, arg1));
410
528
  return ret;
411
529
  },
412
- __wbg_new_310879b66b6e95e1: function() {
413
- const ret = new Array();
530
+ __wbg_new_da52cf8fe3429cb2: function() {
531
+ const ret = new Object();
414
532
  return ret;
415
533
  },
416
- __wbg_now_81363d44c96dd239: function() {
534
+ __wbg_now_86c0d4ba3fa605b8: function() {
417
535
  const ret = Date.now();
418
536
  return ret;
419
537
  },
420
- __wbg_push_b77c476b01548d0a: function(arg0, arg1) {
538
+ __wbg_push_d2ae3af0c1217ae6: function(arg0, arg1) {
421
539
  const ret = arg0.push(arg1);
422
540
  return ret;
423
541
  },
424
- __wbg_set_a0e911be3da02782: function() { return handleError(function (arg0, arg1, arg2) {
542
+ __wbg_set_8535240470bf2500: function() { return handleError(function (arg0, arg1, arg2) {
425
543
  const ret = Reflect.set(arg0, arg1, arg2);
426
544
  return ret;
427
545
  }, arguments); },
428
- __wbg_set_name_e500733c75ec36b0: function(arg0, arg1, arg2) {
546
+ __wbg_set_name_3bbc583faefa4193: function(arg0, arg1, arg2) {
429
547
  arg0.name = getStringFromWasm0(arg1, arg2);
430
548
  },
431
549
  __wbg_stack_3b0d974bbf31e44f: function(arg0, arg1) {
package/web/ezu_bg.wasm CHANGED
Binary file
@@ -3,6 +3,7 @@
3
3
  export const memory: WebAssembly.Memory;
4
4
  export const __wbg_logsink_free: (a: number, b: number) => void;
5
5
  export const __wbg_renderer_free: (a: number, b: number) => void;
6
+ export const heapBytes: () => number;
6
7
  export const logsink_clear: (a: number) => void;
7
8
  export const logsink_drain: (a: number) => any;
8
9
  export const logsink_drainLines: (a: number) => [number, number];
@@ -15,10 +16,13 @@ export const renderer_attribution: (a: number) => [number, number];
15
16
  export const renderer_bindSource: (a: number, b: number, c: number, d: number, e: number, f: number) => [number, number];
16
17
  export const renderer_boundSources: (a: number) => [number, number];
17
18
  export const renderer_clearSources: (a: number) => void;
19
+ export const renderer_memoryUsage: (a: number) => [number, number, number];
20
+ export const renderer_neededCodepoints: (a: number) => [number, number, number];
18
21
  export const renderer_neededGlyphRanges: (a: number) => [number, number, number];
19
22
  export const renderer_new: (a: number, b: number) => [number, number, number];
20
23
  export const renderer_renderTile: (a: number, b: number, c: number, d: number, e: number) => [number, number, number, number];
21
24
  export const renderer_requestedNeighborOffsets: (a: number, b: number, c: number) => [number, number, number];
25
+ export const renderer_setGlyphBudget: (a: number, b: number) => void;
22
26
  export const renderer_setStyle: (a: number, b: number, c: number) => [number, number, number];
23
27
  export const renderer_tileSize: (a: number) => number;
24
28
  export const simdEnabled: () => number;
package/workerd/ezu.js CHANGED
@@ -9,5 +9,5 @@ glue.__wbg_set_wasm(instance.exports);
9
9
  instance.exports.__wbindgen_start();
10
10
 
11
11
  export {
12
- LogSink, Renderer, simdEnabled, threadsEnabled
12
+ LogSink, Renderer, heapBytes, simdEnabled, threadsEnabled
13
13
  } from "../bundler/ezu_bg.js";