refactor: de-duplicate the stub/monolith structure — one real module per class (#47)#71
Merged
Conversation
Second de-duplication step of #47, following the pattern proven in #62. - src/imgproc/imgproc.ts: replace the type-only stub with the REAL implementation moved verbatim from the monolith (grayscale, resample, box_blur_gray, gaussian_blur, hough_transform, pyrdown, scharr/sobel derivatives, compute_integral_image, equalize_histogram, canny, warp_perspective, warp_affine, skindetector). Only deliberate change: gaussian_blur instantiates the math module directly (import from ../math/math) instead of via the jsfeatNext.math static slot, removing an attach-order dependency on the aggregator. - src/jsfeatNext.ts: shrinks by ~1050 lines; attaches imgproc from its module (jsfeatNext.imgproc = imgproc). - Side effect: the latent trap in src/orb/rectify_patch.ts (it imports imgproc, which until now was the throwing stub) is healed — it resolves to the real implementation. Verified behavior-preserving: tsc --noEmit clean; npm test 57/57 (14 of those pin imgproc bit-for-bit vs original jsfeat); UMD build checked (instanceof chain, static-constant inheritance, grayscale + gaussian_blur smoke on the bundle). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Third de-duplication step of #47, following the #62/#63 pattern. - src/fast_corners/fast_corners.ts: replace the type-only stub with the REAL implementation moved verbatim from the monolith (set_threshold, detect, _cmp_offsets; imports _cmp_score_16 from ./fast_private, which was already a real module). - src/jsfeatNext.ts: shrinks by ~225 lines; attaches fast_corners from its module. Verified behavior-preserving: tsc --noEmit clean; npm test 57/57 (detector parity suite pins fast_corners.detect against original jsfeat); UMD bundle smoke-checked (instanceof chain, static inheritance, corner detection on a synthetic image). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Fourth de-duplication step of #47, following the established pattern. - src/pyramid_t/pyramid_t.ts: replace the type-only stub with the REAL implementation moved verbatim from the monolith (allocate, build). Only deliberate change: the constructor instantiates imgproc via direct module import instead of the jsfeatNext.imgproc static slot. - src/jsfeatNext.ts: shrinks by ~43 lines. Verified behavior-preserving: tsc --noEmit clean; npm test 57/57 (the optical_flow_lk parity test exercises pyramid_t against the oracle); UMD bundle smoke-checked (instanceof, allocate/build on a synthetic image with correct per-level dimensions). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Fifth de-duplication step of #47, following the established pattern. - src/linalg/linalg.ts: replace the type-only stub with the REAL implementation moved verbatim from the monolith (JacobiImpl, JacobiSVDImpl, lu_solve, cholesky_solve, svd_decompose, svd_solve, svd_invert, eigenVV). Imports swap/hypot from ./linalg_base and matmath — both already real modules. - src/jsfeatNext.ts: shrinks by ~740 lines (largest single extraction). Verified behavior-preserving: tsc --noEmit clean; npm test 57/57 (6 parity tests pin linalg: LU, Cholesky, SVD x3, eigenVV vs original jsfeat); UMD bundle smoke-checked (instanceof, static inheritance, lu_solve on an SPD system). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sixth de-duplication step of #47, following the established pattern. - src/orb/orb.ts: replace the type-only stub with the REAL implementation moved verbatim from the monolith (describe). Imports bit_pattern_31 and rectify_patch from their existing real modules; the constructor now instantiates imgproc via direct module import instead of the jsfeatNext.imgproc static slot. - src/jsfeatNext.ts: shrinks by ~107 lines. Verified behavior-preserving: tsc --noEmit clean; npm test 57/57 (the orb parity test pins describe() output byte-for-byte vs original jsfeat); UMD bundle smoke-checked (instanceof, descriptor computation). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Seventh de-duplication step of #47, following the established pattern. - src/yape06/yape06.ts: replace the type-only stub with the REAL implementation moved verbatim from the monolith (detect + laplacian / min-eigen-value thresholds). Imports compute_laplacian and hessian_min_eigen_value from ./yape06_utils (already a real module). - src/jsfeatNext.ts: shrinks by ~85 lines. Verified behavior-preserving: tsc --noEmit clean; npm test 57/57 (the yape06 parity test pins detect() against original jsfeat); UMD bundle smoke-checked (instanceof, default thresholds, detection on a synthetic image). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… kernels (#47) Eighth de-duplication step of #47 — the biggest structural win. - NEW src/motion_model/motion_model.ts: motion_model + affine2d + homography2d kernel classes, moved verbatim from the monolith (they were module-local classes there). Kernels instantiate linalg via direct module import instead of the jsfeatNext.linalg static slot. - src/motion_estimator/motion_estimator.ts: replace the type-only stub with the REAL implementation (get_subset, find_inliers, ransac, lmeds); lmeds instantiates math via direct module import. - src/core/core.ts: the temporary any-typed affine2d/homography2d static slots (a known TODO since #62) now have precise typeof types via type-only imports. - src/jsfeatNext.ts: down to ~380 lines — pure aggregator except for optical_flow_lk, the last inline module. Verified behavior-preserving: tsc --noEmit clean; npm test 57/57 (3 parity tests pin ransac/lmeds with identical models AND inlier masks vs original jsfeat on seeded data); UMD bundle smoke-checked (instanceof for estimator and both kernels, affine RANSAC recovers the synthetic model). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…s is now a thin aggregator (#47) Ninth and FINAL de-duplication step of #47. - src/optical_flow_lk/optical_flow_lk.ts: replace the type-only stub with the REAL implementation moved verbatim from the monolith (track). The constructor instantiates imgproc via direct module import instead of the jsfeatNext.imgproc static slot. - src/jsfeatNext.ts: now a 59-line THIN AGGREGATOR - it only imports the modules and attaches them to the public namespace. Unused helper imports (resample/convol kernels, linalg_base, fast_private, orb/yape06 utils, point_t, JSFEAT_CONSTANTS) pruned; they are consumed by the modules themselves now. This completes the stub/monolith de-duplication: every algorithm lives in its own real module under src/<module>/, extending the shared base from src/core/core.ts. No type-only stubs remain; the audit's section-4 target architecture (thin aggregator) is reached for the module layer. Verified behavior-preserving: tsc --noEmit clean; npm test 57/57 (the optical_flow_lk parity test pins track() vs original jsfeat across pyramid levels); UMD bundle checked - all 18 public modules attach and instanceof chains hold. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
One-shot artifact rebuild for the integration of the stub/monolith de-duplication (#62-#70) into dev, per the agreed convention (refactor PRs ship source only; artifacts are rebuilt at integration/release points). - dist/jsfeatNext.js (UMD) + dist/jsfeatNext.mjs (ESM) rebuilt from the refactored source - types/ regenerated: now mirrors the new module layout, including types/src/core/core.d.ts and types/src/motion_model/motion_model.d.ts Verified: npm test 57/57; all 18 public modules attach on the fresh UMD bundle; VERSION 0.7.6 intact; no .d.ts files leak into dist/. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Comprehensive documentation pass over all 34 source files: every class, interface, method, property and standalone function now carries a TSDoc block (summaries, @param/@returns, plus parity notes vs original jsfeat, e.g. the fixed hough_transform, the transform calling-convention difference and the per-instance cache). Tooling: - tsconfig: removeComments false, so the docs propagate into the generated .d.ts and consumers get hover documentation in their IDE - typedoc devDependency + 'npm run docs' script + typedoc.json (all modules, HTML output to docs/api — gitignored, generated on demand; publishing/hosting is an org-wide decision tracked separately) - dist/ + types/ rebuilt (JS behavior unchanged; declarations carry docs) Verified: typedoc generates with zero warnings (86 pages); tsc --noEmit clean; npm test 57/57; prettier clean. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Member
Author
|
📝 Documentation pass added (commit 9563db2): full TSDoc coverage across all 34 Tooling that came with it:
Further doc improvements will land in a separate PR; hosting the generated API docs is an org-wide decision tracked in webarkit/webarkit.github.io#49. |
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.
The complete #47 integration: nine reviewed slices (#62–#70) plus a one-shot artifact rebuild. Closes #47.
What this delivers
The audit's §4 target architecture for the module layer:
src/jsfeatNext.ts: ~3,900 lines → 59 lines — a thin aggregator that only imports modules and attaches them to the public namespacesrc/<module>/<module>.tsis now the real implementation (previously most threw"Method not implemented")src/core/core.ts— the shared base class (constants, cache/data-type helpers, precisely-typed static slots); every module extends it, no circular importssrc/motion_model/motion_model.ts—motion_model/affine2d/homography2dkernels, previously trapped as module-local classessrc/orb/rectify_patch.tsnow resolves to the realimgprocinstead of the throwing stubPublic API: unchanged
All 18
jsfeatNext.<module>attachments identical,instanceofchains and static-constant inheritance preserved,VERSIONintact. The only signature change:math.median()now honestly accepts typed arrays (the stub hid this behindany;lmedsalways passed aFloat32Array).Included artifact rebuild
Final commit rebuilds
dist/(UMD + ESM) andtypes/from the refactored source, per the agreed convention (refactor PRs ship source only; artifacts rebuilt at integration points).types/now mirrors the new layout (core/,motion_model/).Verification (every slice + final state)
tsc --noEmitclean;npm test57/57 parity tests vs original jsfeat at every stepexamples/*.htmlpass on this branch before merging —dist/here is the rebuilt refactored bundleReview guide
Best reviewed per-slice (all previously reviewed and merged into this branch): #62 core+math · #63 imgproc · #64 fast_corners · #65 pyramid_t · #66 linalg · #67 orb · #68 yape06 · #69 motion_estimator+kernels · #70 optical_flow_lk+aggregator.
🤖 Generated with Claude Code