@zkmake/three-meter 0.11.5 → 0.12.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
@@ -182,6 +182,18 @@ hud.setBudgets({ gpu: null }); // null drops a default; false drops them all
182
182
 
183
183
  `PerfHud` takes the same `budgets` prop and applies changes live.
184
184
 
185
+ An app that keeps its budgets in one file with [three-audit](../three-audit)'s `defineBudgets`
186
+ passes that file as is. The HUD applies its `frame`: `fps` as `targetFps`, `calls` and
187
+ `triangles`. The same file holds the per-part budgets its tests and the `three-audit` CLI check.
188
+
189
+ ```ts
190
+ import budgets from "./budgets.ts"; // defineBudgets({ frame: { fps: 60, calls: 150, … }, parts })
191
+
192
+ mountPerfHud(monitor, { budgets });
193
+ ```
194
+
195
+ three-meter reads the file's shape (`AppBudgets`) and doesn't depend on three-audit.
196
+
185
197
  ## Top costs
186
198
 
187
199
  The HUD tells you there are 400 draw calls; **top costs** tells you which objects they come from.
package/dist/index.d.ts CHANGED
@@ -1,5 +1,4 @@
1
- import { a as GpuTiming, c as RenderBackend, d as Sample, f as SceneCost, i as FrameStats, l as RenderCounts, n as CostEntry, o as PerfRenderer, p as TimingMetric, r as Environment, s as PerformanceMonitorOptions, t as PerformanceMonitor, u as ResourceCounts } from "./performance-monitor-BoY_-GTt.js";
2
- //#region src/core/ring-buffer.d.ts
1
+ import { a as GpuTiming, c as RenderBackend, d as Sample, f as SceneCost, i as FrameStats, l as RenderCounts, n as CostEntry, o as PerfRenderer, p as TimingMetric, r as Environment, s as PerformanceMonitorOptions, t as PerformanceMonitor, u as ResourceCounts } from "./performance-monitor-CrYmNIdv.js";
3
2
  /**
4
3
  * Fixed-capacity numeric ring buffer. Backs the per-frame timing history the
5
4
  * view reads to draw sparklines. Push is O(1); `toArray()` returns values in
@@ -16,8 +15,6 @@ declare class RingBuffer {
16
15
  toArray(): number[];
17
16
  clear(): void;
18
17
  }
19
- //#endregion
20
- //#region src/core/wrap-animation-loop.d.ts
21
18
  type AnimationLoop<Args extends unknown[]> = (...args: Args) => void;
22
19
  /**
23
20
  * Wrap a `renderer.setAnimationLoop` callback so each tick is one frame:
@@ -31,6 +28,5 @@ type AnimationLoop<Args extends unknown[]> = (...args: Args) => void;
31
28
  * ```
32
29
  */
33
30
  declare function wrapAnimationLoop<Args extends unknown[]>(monitor: PerformanceMonitor, loop: AnimationLoop<Args>): AnimationLoop<Args>;
34
- //#endregion
35
31
  export { type CostEntry, type Environment, type FrameStats, type GpuTiming, type PerfRenderer, PerformanceMonitor, type PerformanceMonitorOptions, type RenderBackend, type RenderCounts, type ResourceCounts, RingBuffer, type Sample, type SceneCost, type TimingMetric, wrapAnimationLoop };
36
32
  //# sourceMappingURL=index.d.ts.map
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
- import { n as RingBuffer, t as PerformanceMonitor } from "./performance-monitor-BqnoiLEs.js";
2
- //#region src/core/wrap-animation-loop.ts
1
+ import { n as RingBuffer, t as PerformanceMonitor } from "./performance-monitor-CKAI0-Dp.js";
2
+ // src/core/wrap-animation-loop.ts
3
3
  /**
4
4
  * Wrap a `renderer.setAnimationLoop` callback so each tick is one frame:
5
5
  * `begin()` before your code, `end()` after it returns. CPU time is your
@@ -21,7 +21,6 @@ function wrapAnimationLoop(monitor, loop) {
21
21
  }
22
22
  };
23
23
  }
24
- //#endregion
25
24
  export { PerformanceMonitor, RingBuffer, wrapAnimationLoop };
26
25
 
27
26
  //# sourceMappingURL=index.js.map
@@ -1,12 +1,22 @@
1
- //#region src/ui/budgets.ts
1
+ // src/ui/budgets.ts
2
2
  const DEFAULT_TARGET_FPS = 60;
3
3
  const FLOORS = /* @__PURE__ */ new Set([
4
4
  "fps",
5
5
  "headroom",
6
6
  "low"
7
7
  ]);
8
+ const isAppBudgets = (budgets) => "frame" in budgets;
9
+ /** An app's frame budget as the HUD's: only the limits it sets, so the rest keep their defaults. */
10
+ const fromApp = ({ frame }) => {
11
+ const budgets = {};
12
+ if (frame.fps !== void 0) budgets.targetFps = frame.fps;
13
+ if (frame.calls !== void 0) budgets.calls = frame.calls;
14
+ if (frame.triangles !== void 0) budgets.triangles = frame.triangles;
15
+ return budgets;
16
+ };
8
17
  /** `detectedHz` is the monitor's refresh reading; an explicit `targetFps` wins over it. */
9
- const resolveBudgets = (budgets, detectedHz = null) => {
18
+ const resolveBudgets = (input, detectedHz = null) => {
19
+ const budgets = input && isAppBudgets(input) ? fromApp(input) : input;
10
20
  const targetFps = budgets && budgets.targetFps || detectedHz || DEFAULT_TARGET_FPS;
11
21
  const frameMs = 1e3 / targetFps;
12
22
  if (budgets === false) return {
@@ -38,8 +48,7 @@ const isOverBudget = (resolved, key, value) => {
38
48
  if (limit === void 0 || value === null) return false;
39
49
  return isFloor(key) ? value < limit : value > limit;
40
50
  };
41
- //#endregion
42
- //#region src/ui/theme.ts
51
+ // src/ui/theme.ts
43
52
  const THEME_MODES = [
44
53
  "dark",
45
54
  "light",
@@ -125,8 +134,7 @@ var HudTheme = class {
125
134
  const applyTheme = (element, theme) => {
126
135
  element.dataset.theme = theme.resolved;
127
136
  };
128
- //#endregion
129
- //#region src/ui/hud-settings.ts
137
+ // src/ui/hud-settings.ts
130
138
  const DEFAULT_STORAGE_KEY = "three-meter";
131
139
  const DEFAULT_DIM = false;
132
140
  const DEFAULT_INFO = false;
@@ -242,8 +250,7 @@ var HudSettings = class {
242
250
  for (const listener of this.listeners) listener();
243
251
  }
244
252
  };
245
- //#endregion
246
- //#region src/ui/dock-panel.ts
253
+ // src/ui/dock-panel.ts
247
254
  /**
248
255
  * Dock a fixed-position panel to a screen edge. Dragging the handle snaps it
249
256
  * to the nearest edge on drop; the edge and the offset along it persist under
@@ -458,8 +465,7 @@ const dockPanel = (element, options = {}) => {
458
465
  refresh: apply
459
466
  };
460
467
  };
461
- //#endregion
462
- //#region src/ui/icons.ts
468
+ // src/ui/icons.ts
463
469
  const ICON_MARKUP = {
464
470
  eye: "<path d=\"M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0\"/><circle cx=\"12\" cy=\"12\" r=\"3\"/>",
465
471
  eyeOff: "<path d=\"M10.733 5.076a10.744 10.744 0 0 1 11.205 6.575 1 1 0 0 1 0 .696 10.747 10.747 0 0 1-1.444 2.49\"/><path d=\"M14.084 14.158a3 3 0 0 1-4.242-4.242\"/><path d=\"M17.479 17.499a10.75 10.75 0 0 1-15.417-5.151 1 1 0 0 1 0-.696 10.75 10.75 0 0 1 4.446-5.143\"/><path d=\"m2 2 20 20\"/>",
@@ -503,8 +509,7 @@ const createIcon = (name, className) => {
503
509
  svg.innerHTML = ICON_MARKUP[name];
504
510
  return svg;
505
511
  };
506
- //#endregion
507
- //#region src/ui/styles.ts
512
+ // src/ui/styles.ts
508
513
  /**
509
514
  * The HUD stylesheet as a string, so the package works without a bundler and
510
515
  * injects itself once per document. `.perf-monitor` is the metrics card,
@@ -1245,8 +1250,7 @@ const injectStyles = (target = document) => {
1245
1250
  style.textContent = PERF_HUD_STYLES;
1246
1251
  target.head.append(style);
1247
1252
  };
1248
- //#endregion
1249
- //#region src/ui/dev-panel.ts
1253
+ // src/ui/dev-panel.ts
1250
1254
  /**
1251
1255
  * The frame every zkmake dev panel shares, so they look and handle alike: a fixed host docked to a
1252
1256
  * screen edge, a card with a brand label on top and the panel's content under it, and three discs
@@ -1294,6 +1298,7 @@ const mountDevPanel = (options) => {
1294
1298
  const host = document.createElement("div");
1295
1299
  host.className = "perf-hud";
1296
1300
  host.dataset.edge = "left";
1301
+ host.setAttribute("role", "group");
1297
1302
  host.setAttribute("aria-label", options.label);
1298
1303
  const hotspot = document.createElement("div");
1299
1304
  hotspot.className = "perf-hud__hotspot";
@@ -1393,12 +1398,10 @@ const mountDevPanel = (options) => {
1393
1398
  }
1394
1399
  };
1395
1400
  };
1396
- //#endregion
1397
- //#region package.json
1401
+ // package.json
1398
1402
  var name = "@zkmake/three-meter";
1399
- var version = "0.11.5";
1400
- //#endregion
1401
- //#region src/ui/clipboard.ts
1403
+ var version = "0.12.0";
1404
+ // src/ui/clipboard.ts
1402
1405
  /**
1403
1406
  * Copy text from a click handler. The async Clipboard API needs a secure
1404
1407
  * context and the `clipboard-write` permission; a dev server opened over a LAN
@@ -1432,8 +1435,7 @@ const copyText = async (text) => {
1432
1435
  return copyWithSelection(text);
1433
1436
  }
1434
1437
  };
1435
- //#endregion
1436
- //#region src/ui/format.ts
1438
+ // src/ui/format.ts
1437
1439
  /**
1438
1440
  * Number formatting for the card. Counts stay exact with thousands separators
1439
1441
  * while they fit the compact grid's 6ch value column (`99,999`), then switch
@@ -1447,8 +1449,7 @@ const compact = new Intl.NumberFormat("en-US", {
1447
1449
  notation: "compact"
1448
1450
  });
1449
1451
  const formatCount = (value) => Math.abs(value) < COMPACT_FROM ? exact.format(value) : compact.format(value);
1450
- //#endregion
1451
- //#region src/ui/hider.ts
1452
+ // src/ui/hider.ts
1452
1453
  var Hider = class {
1453
1454
  groups = /* @__PURE__ */ new Map();
1454
1455
  /** Each hidden object's `visible` from before the first group hid it. */
@@ -1486,8 +1487,7 @@ var Hider = class {
1486
1487
  return false;
1487
1488
  }
1488
1489
  };
1489
- //#endregion
1490
- //#region src/ui/metric-help.ts
1490
+ // src/ui/metric-help.ts
1491
1491
  /**
1492
1492
  * One plain-language line per metric: what it is, and what a bad reading
1493
1493
  * means. Shown as the label's tooltip and, with "explain metrics" on, under
@@ -1511,8 +1511,7 @@ const METRIC_HELP = {
1511
1511
  textures: "Textures held in GPU memory. Should level off; a steady climb is a leak, so dispose() what you remove.",
1512
1512
  triangles: "Triangles drawn this frame. Mostly GPU cost: use lower-poly models or level of detail to cut it."
1513
1513
  };
1514
- //#endregion
1515
- //#region src/ui/report.ts
1514
+ // src/ui/report.ts
1516
1515
  /**
1517
1516
  * A plain-text snapshot of the monitor for bug reports: versions, backend and
1518
1517
  * GPU, the current sample, stutter stats, the scene's top meshes and the page. Fenced as a `text`
@@ -1594,8 +1593,7 @@ const formatReport = (monitor) => renderReport({
1594
1593
  sample: monitor.getSample(),
1595
1594
  stats: monitor.getFrameStats()
1596
1595
  });
1597
- //#endregion
1598
- //#region src/ui/sparkline.ts
1596
+ // src/ui/sparkline.ts
1599
1597
  function drawSparkline(ctx, width, height, values, style, guide) {
1600
1598
  ctx.clearRect(0, 0, width, height);
1601
1599
  if (values.length < 2) return;
@@ -1627,8 +1625,7 @@ function drawSparkline(ctx, width, height, values, style, guide) {
1627
1625
  ctx.restore();
1628
1626
  }
1629
1627
  }
1630
- //#endregion
1631
- //#region src/ui/performance-view.ts
1628
+ // src/ui/performance-view.ts
1632
1629
  const TIMINGS = [
1633
1630
  {
1634
1631
  format: (value) => Math.round(value).toString(),
@@ -2496,8 +2493,7 @@ var PerformanceView = class {
2496
2493
  sizeAll(this.hudGraphs.values());
2497
2494
  }
2498
2495
  };
2499
- //#endregion
2500
- //#region src/ui/mount-perf-hud.ts
2496
+ // src/ui/mount-perf-hud.ts
2501
2497
  const mountPerfHud = (monitor, options = {}) => {
2502
2498
  const storageKey = options.storageKey === void 0 ? DEFAULT_STORAGE_KEY : options.storageKey;
2503
2499
  const settings = options.settings ?? new HudSettings({ storageKey });
@@ -2555,7 +2551,6 @@ const mountPerfHud = (monitor, options = {}) => {
2555
2551
  view
2556
2552
  };
2557
2553
  };
2558
- //#endregion
2559
2554
  export { PERF_HUD_STYLES as a, DEFAULT_STORAGE_KEY as c, THEME_MODES as d, isThemeMode as f, mountDevPanel as i, HudSettings as l, PerformanceView as n, injectStyles as o, resolveBudgets as p, formatReport as r, dockPanel as s, mountPerfHud as t, HudTheme as u };
2560
2555
 
2561
- //# sourceMappingURL=mount-perf-hud-Cu7Jjwmm.js.map
2556
+ //# sourceMappingURL=mount-perf-hud-CJju0oTc.js.map