refactor(examples): add shared ESM demo helpers, convert 2 pilots (refs #79)#98
Merged
Merged
Conversation
#79) Phase 1 of #79: create the shared helper modules and prove them on two representative examples before applying the pattern to the remaining 15. New `examples/js/demo-utils.mjs`: - `loadCamera()` / `stopCamera()` — modern `navigator.mediaDevices.getUserMedia` + `srcObject`, replacing the ~50 lines of camera/retry/error boilerplate each demo carried. - `renderCorners()` — was duplicated verbatim in 5 demos. - `renderMonoImage()` — was duplicated verbatim in 3 demos. - `showCameraError()` — the "WebRTC not available" path, previously hand-rolled with jQuery in every demo. New `examples/js/profiler.mjs`: a thin ES-module wrapper that loads the legacy global-IIFE `profiler.js` once and re-exports it, so ESM examples can import the profiler without duplicating its ~140 lines. Unlike compatibility.js the profiler is not obsolete — it is the working stopwatch/FPS readout. Converted pilots (ESM + de-jQuery in one pass, behaviour unchanged): - `grayscale.html` — simple case (was already jQuery-free) - `sample_fast_corners.html` — full case: jQuery + compatibility.js + profiler + dat.GUI, so it exercises the whole helper surface Both now use `<script type="module">` with `import jsfeatNext from '../dist/jsfeatNext.mjs'`, and no longer load jQuery or `js/compatibility.js`. That shim was audited and is obsolete: its `getUserMedia` only tries the removed callback-style API + vendor prefixes (falling through to its own error stub), its rAF/URL helpers are long-universal, and `detectEndian`/`isLittleEndian` are referenced by zero examples. The file stays in the repo for the UMD examples. Per the plan the 5 API-demo examples (browser, linalg_example, mat_math_example, matrix_t_example, orb_test) deliberately stay on the UMD script tag, so the folder documents both consumption paths — and they keep working from file:// (ES modules require http://). Verified in a real browser over a local HTTP server: both pilots load with no module/import errors; `profiler.mjs` loads and its `log()` works; jQuery and the compatibility shim are absent; dat.GUI still works; and `browser.html` still works unchanged via the UMD global (v0.10.0, matrix_t + singletons OK). Both pilots additionally confirmed working with a real webcam by the maintainer. Prettier clean.
kalwalt
added a commit
that referenced
this pull request
Jul 25, 2026
Phase 2 of #79: applies the helper API validated in phase 1 (#98) to the simple and medium tiers — 13 of the remaining 15 camera examples. Converted (ESM + de-jQuery in one pass, behaviour unchanged): - simple: boxblur, canny_edge, equalize_hist, gaussblur, scharr, sobel, warp_affine, warp_perspective - medium: oflow_lk, pyrdown, sobel_edge, yape, yape06 Each now uses `<script type="module">` with `import jsfeatNext from '../dist/jsfeatNext.mjs'`, `loadCamera()`/`stopCamera()`/`showCameraError()` from `demo-utils.mjs`, and the profiler via `profiler.mjs`. jQuery and `js/compatibility.js` are gone from all of them; the inline grayscale->RGBA expansion loops and the duplicated `render_corners`/`render_mono_image` functions are replaced by the shared `renderMonoImage()`/`renderCorners()`. Net -684 lines (364 insertions, 1048 deletions) — all boilerplate. Note on a bug caught during conversion: the mechanical pass initially left `var ctx, canvasWidth, canvasHeight;` in 10 files. That would have shadowed the module-level `ctx` with `undefined` and left `canvasWidth`/`canvasHeight` undefined — `sample_yape.html` passes those straight into `jsfeatNext.yape.init(...)`. The stale declarations are removed and the two variables mapped to the `WIDTH`/`HEIGHT` constants (the canvas is 640x480, so they are identical). `sample_orb.html` and `sample_orb_pinball.html` are deliberately NOT in this batch: at ~556/586 lines with four render helpers each plus pattern-training logic, they are a different risk profile and get their own focused PR. Verified with an iframe harness loading all 15 ESM examples (these 13 plus the two phase-1 pilots): every one has a module script, zero jQuery, zero compatibility shim, and zero non-camera errors. The harness was removed afterwards. Prettier clean. All 13 additionally confirmed working with a real webcam by the maintainer.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Phase 1 of #79 — creates the shared helper modules and proves them on two representative examples before applying the pattern to the remaining 15. (Plan is in #79.)
New shared modules
examples/js/demo-utils.mjs— kills the real duplication:loadCamera()/stopCamera()renderCorners()renderMonoImage()showCameraError()examples/js/profiler.mjs— a thin wrapper that loads the legacy global-IIFEprofiler.jsonce and re-exports it, so ESM examples canimportthe profiler without duplicating its ~140 lines. Single source of truth for both UMD and ESM examples.Pilots converted (ESM + de-jQuery in one pass, behaviour unchanged)
grayscale.html— the simple case (already jQuery-free)sample_fast_corners.html— the full case (jQuery + compatibility.js + profiler + dat.GUI), so it exercises the entire helper surface. It sheds ~120 net lines of boilerplate.Why
compatibility.jsis dropped hereAudited — it's obsolete: its
getUserMediaonly tries the removed callback-style API + vendor prefixes (so it falls through to its own error stub on any current browser), rAF/URLhave been universal for a decade, anddetectEndian/isLittleEndianare referenced by zero examples.grayscale.htmlalready bypassed it. The file stays in the repo so the UMD examples and external links keep working.The 5 UMD examples stay as-is — deliberately
browser,linalg_example,mat_math_example,matrix_t_example,orb_testkeep the UMD script tag, soexamples/documents both consumption paths — and they still open straight fromfile://(ES modules requirehttp://).Verification
Served over a local HTTP server and checked in a real browser:
profiler.mjsloads andlog()works · dat.GUI works · jQuery and the compatibility shim are goneshowCameraError()correctly handles a denied camerabrowser.htmlstill works unchanged via the UMD global (v0.10.0,matrix_t+ singletons OK)Next
Phase 2+: convert the remaining 15 camera examples in batches, now that the helper API is validated.
🤖 Generated with Claude Code