Files
OpenMAIC/packages
wyucandClaude Opus 5.5 3c5c02f994 fix(renderer): cancel idle typesetting with its own pair and keep release-gate tests stable (#1901)
* fix(renderer): cancel idle typesetting with the pair that scheduled it

whenIdle checked requestIdleCallback/cancelIdleCallback when scheduling but
read cancelIdleCallback again when cancelling. If the global was removed or
replaced in between (a test stub restored, a polyfill swapped in), unmounting
a text element with pending inline math threw "scope.cancelIdleCallback is not
a function", or handed the handle to an implementation that never issued it.
Capture the request/cancel pair, and setTimeout/clearTimeout for the fallback,
at schedule time and always cancel through the captured function.

Make the inline-math regression tests fast and deterministic on a loaded
runner without dropping what they pin:

- Budget tests use distinct formulas padded with trailing spaces to 1,900
  source characters. The budget counts source characters, so they cross it
  exactly like the old 1,357-character matrices, at a fraction of the
  typesetting cost.
- The uncacheable-render test uses 40 radicals per formula: each render is
  still over the 64,000-character cache entry limit (asserted), several times
  cheaper than a large matrix.
- Idle-time work runs through a stubbed idle queue that the test flushes,
  instead of polling wall-clock timers; a fake-timer test covers the
  setTimeout fallback.
- The snapshot tests replace KaTeX with a trivial typesetter (real
  typesetting is covered by the element tests), use the minimum fixture that
  crosses the per-root cap (2 x 501 formulas), wait for the deferred unmount
  before restoring stubs, and count formulas only within the tree being
  measured.

The [600, 600, 600, 600] measurement in the failed release run was a cascade:
slideToPng timed out, kept running, and its off-screen tree was still in
document.body when the next test counted roots across the whole body. Its
deferred unmount then ran after the idle stubs were restored, which is what
raised the unhandled TypeError.

New tests cancel after cancelIdleCallback is removed or replaced, and after
clearTimeout is replaced; they fail on the previous implementation.

Bump @openmaic/renderer to 0.1.14 so the next publish run releases it
(0.1.13 never reached the registry).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test(packages): keep release-gate tests stable on a loaded runner

The publish workflow runs every package's tests concurrently on one runner.
Two more checks in that step failed when the suites were run under CPU
contention:

- The macro-safety tests in editor, generation and importer asserted that a
  render takes under 100 ms. On a loaded runner a guarded render can exceed
  that. Raise the ceiling to 1 s: the unguarded nestedDef expansion takes tens
  of seconds, a guarded render a few milliseconds, and the output-size and
  error checks that follow are what show the definitions were dropped.
- Editor tests never unmounted their trees, because Testing Library only
  registers automatic cleanup when the runner exposes a global afterEach.
  React work still queued at the end of a file then ran after jsdom was torn
  down ("window is not defined"). Clean up after each test in the shared
  setup.

Test-only changes; no package version bumps are required.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 13:14:40 +08:00
..