@vectojs/core 1.23.0 → 1.25.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.
@@ -176,6 +176,11 @@ export interface SceneOptions {
176
176
  * and not marked dirty) to save power/CPU. Default is `true`.
177
177
  */
178
178
  autoThrottle?: boolean;
179
+ /**
180
+ * Emit User Timing marks and measures for render phases. Default `false`.
181
+ * Intended for short profiler captures; enable only while collecting one.
182
+ */
183
+ userTiming?: boolean;
179
184
  /**
180
185
  * Mirror static text from entities implementing
181
186
  * {@link Entity.getContentProjection} as transparent, position-synced DOM
@@ -341,6 +346,7 @@ export declare class Scene {
341
346
  /** Cap on distinct recorded dirty reasons (see `recordDirtyReason`). */
342
347
  private static readonly MAX_DIRTY_REASONS;
343
348
  private _phaseTiming;
349
+ private _userTiming;
344
350
  private _phaseTotals;
345
351
  /**
346
352
  * Start or stop per-phase render timing.
@@ -358,6 +364,15 @@ export declare class Scene {
358
364
  setPhaseTiming(enabled: boolean): void;
359
365
  /** Whether per-phase render timing is being recorded. */
360
366
  get phaseTiming(): boolean;
367
+ /**
368
+ * Enable or disable browser User Timing phase instrumentation.
369
+ *
370
+ * Off by default. The disabled frame path performs only boolean checks and
371
+ * emits no Performance Timeline entries.
372
+ */
373
+ setUserTiming(enabled: boolean): void;
374
+ /** Whether browser User Timing phase instrumentation is enabled. */
375
+ get userTiming(): boolean;
361
376
  /**
362
377
  * Accumulate one phase sample.
363
378
  *
@@ -521,6 +536,8 @@ export declare class Scene {
521
536
  private fullViewportElements;
522
537
  private normalElements;
523
538
  private activeIds;
539
+ /** Per-parent insertion cursor, reused by `enforceA11yDomOrder`. */
540
+ private a11yOrderCursors;
524
541
  private activePortalsThisFrame;
525
542
  private activePortalsPrevFrame;
526
543
  private portalEntities;
@@ -1258,12 +1275,23 @@ export declare class Scene {
1258
1275
  private enforceA11yDomOrder;
1259
1276
  /**
1260
1277
  * Reorder `normalElements` (in place) into visual reading order using the
1261
- * world positions `syncA11y` already wrote to each element's inline style
1278
+ * positions `syncA11y` already wrote to each element's inline style
1262
1279
  * (`top`/`left`/`height`). Elements are grouped into rows top-to-bottom (an
1263
1280
  * element belongs to the current row while its top is above the row's
1264
1281
  * running bottom edge), then sorted within a row by `left` — ascending for
1265
1282
  * `'ltr'`, descending for `'rtl'`. The sort is stable, so entities at the
1266
1283
  * same position keep their scene-graph (collection) order as a tiebreak.
1284
+ *
1285
+ * Those inline values are world coordinates for a top-level mirror but
1286
+ * PARENT-RELATIVE for a nested one, so this list mixes coordinate spaces.
1287
+ * That is sound because the result is only ever applied per DOM parent
1288
+ * ({@link enforceA11yDomOrder} advances a cursor per parent), and all of one
1289
+ * parent's children share one space: a `grid`'s rows are all grid-relative, a
1290
+ * `row`'s cells all row-relative. Comparisons ACROSS spaces do happen while
1291
+ * banding, but they only affect the relative order of elements in different
1292
+ * parents, which no `insertBefore` ever acts on. Normalizing everything back
1293
+ * to world coordinates here would cost a transform per element per frame to
1294
+ * change nothing observable.
1267
1295
  */
1268
1296
  private sortNormalElementsVisually;
1269
1297
  /** Keep DOM/WebGL overlay layers aligned with the canvas's CSS box. */
@@ -1281,6 +1309,26 @@ export declare class Scene {
1281
1309
  /**
1282
1310
  * Render the entire scene graph onto the specified renderer.
1283
1311
  *
1312
+ * Main-frame causal order is a correctness contract:
1313
+ *
1314
+ * 1. Browser/input callbacks finish before the scheduled frame begins.
1315
+ * 2. Batched property drivers and particle simulation advance.
1316
+ * 3. Entity `update()` hooks run.
1317
+ * 4. Transform inputs are gathered and world matrices are composed.
1318
+ * 5. Updated world bounds are tested for culling.
1319
+ * 6. Visible entities paint in scene-graph order.
1320
+ * 7. Canvas/GPU batches flush and retained renderers present.
1321
+ * 8. The rAF loop synchronizes content and accessibility projections after
1322
+ * this method returns.
1323
+ *
1324
+ * The causal order is fixed; physical walks may stay fused. The JavaScript
1325
+ * transform path interleaves update → compose → cull → paint per node in
1326
+ * pre-order. The WASM path updates the whole tree first, then gathers and
1327
+ * composes it in one store pass before the same cull/paint walk. Both must
1328
+ * expose an update's transform mutation in that same rendered frame.
1329
+ * Secondary renderers are read-only snapshots: they skip simulation and
1330
+ * updates, then compose/cull/paint/flush the current state.
1331
+ *
1284
1332
  * @param renderer - The renderer instance to draw to.
1285
1333
  * @param dt - Delta time in milliseconds (default 0).
1286
1334
  * @param time - Current absolute time in milliseconds (default 0).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vectojs/core",
3
- "version": "1.23.0",
3
+ "version": "1.25.0",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -61,19 +61,20 @@
61
61
  "scripts": {
62
62
  "build": "(cd ../math && bun run build) && (cd ../text && bun run build) && (cd ../layout && bun run build) && (cd ../animation && bun run build) && tsup && tsc -p tsconfig.build.json",
63
63
  "test": "vitest run",
64
- "test:e2e": "bun e2e/hidpi.e2e.ts && bun e2e/text-projection.e2e.ts"
64
+ "test:e2e": "bun e2e/hidpi.e2e.ts && bun e2e/text-projection.e2e.ts && bun e2e/svg-fallback.e2e.ts && bun e2e/msdf-atlas-decode.e2e.ts && bun e2e/layout-worker-fallback.e2e.ts"
65
65
  },
66
66
  "dependencies": {
67
67
  "@vectojs/animation": "^0.1.1",
68
- "@vectojs/layout": "^0.4.0",
68
+ "@vectojs/layout": "^0.5.0",
69
69
  "@vectojs/math": "^0.1.1",
70
- "@vectojs/text": "^0.2.0"
70
+ "@vectojs/text": "^0.3.0"
71
71
  },
72
72
  "devDependencies": {
73
+ "@guidepup/virtual-screen-reader": "0.32.1",
73
74
  "@vitest/coverage-v8": "^4.1.10",
74
75
  "esbuild": "^0.28.1",
75
- "jsdom": "^29.1.1",
76
- "puppeteer-core": "^25.3.0",
76
+ "jsdom": "^30.0.1",
77
+ "puppeteer-core": "^25.4.0",
77
78
  "tsup": "^8.3.5",
78
79
  "vitest": "^4.1.10"
79
80
  }