Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Normalize all text files to LF, including in Windows working trees.
# Prettier (endOfLine: lf, its default) and the CI format-check assume LF;
# without this, Windows checkouts get CRLF and local format-checks disagree
# with CI.
* text=auto eol=lf
4 changes: 2 additions & 2 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

The full guidance is in **[`AGENTS.md`](../AGENTS.md)** (source of truth) and the roadmap in [`docs/jsfeat-parity-and-refactor-audit.md`](../docs/jsfeat-parity-and-refactor-audit.md). Critical points, inlined because Copilot injects this file directly:

- **TypeScript port of [jsfeat](https://github.com/inspirit/jsfeat)** for WebARKit. npm: `@webarkit/jsfeat-next`. Node v20.18.0.
- Build: `npm run build-ts` → `dist/jsfeatNext.js` (UMD) + `types/`. Watch: `npm run dev-ts`. Format: `npm run format` (Prettier). **No test suite** — verify via `examples/*.html`.
- **TypeScript port of [jsfeat](https://github.com/inspirit/jsfeat)** for WebARKit. npm: `@webarkit/jsfeat-next`. Node v24.18.0 (npm 11).
- Build: `npm run build-ts` → `dist/jsfeatNext.js` (UMD) + `types/`. Watch: `npm run dev-ts`. Format: `npm run format` (Prettier). **Tests:** `npm test` (Vitest, parity vs original jsfeat); also verify via `examples/*.html`.
- **Architecture:** most algorithms live **inline in `src/jsfeatNext.ts` (~3,900 lines)**, attached as `jsfeatNext.X = class X extends jsfeatNext`. Edit *there* for `imgproc, fast_corners, math, linalg, orb, yape06, motion_estimator, optical_flow_lk, pyramid_t`.
- **⚠️ Trap:** several `src/<module>/<module>.ts` files are **type-only stubs** that `throw new Error("Method not implemented.")` (e.g. `src/imgproc/imgproc.ts`). Do not treat them as the implementation and never instantiate them.
- **API notes:** consumers use `jsfeatNext.jsfeatNext` (double namespace); algorithm modules require `new` (instance methods), unlike jsfeat's static namespace; each `new` allocates its own cache. `haar` and `bbf` are not ported.
Expand Down
3 changes: 1 addition & 2 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,7 @@ jobs:
${{ runner.os }}-node-

- name: Install
run: |
npm install
run: npm ci

- name: Format check
run: npm run format-check
Expand Down
2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v20.18.0
v24.18.0
4 changes: 2 additions & 2 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@

## Environment & commands

- **Node:** v20.18.0 (see `.nvmrc`). **Package manager:** npm.
- **Node:** v24.18.0 (see `.nvmrc`; npm 11). **Package manager:** npm.
- Install: `npm install`
- Build (prod): `npm run build-ts` → runs `tsc` (emits `.d.ts` to `types/`) then webpack → `dist/jsfeatNext.js`
- Watch/dev: `npm run dev-ts`
- Format: `npm run format` (write) · `npm run format-check` (verify) — Prettier, config in `.prettierrc.json`
- **Tests:** none yet. The only verification is manual: open `examples/*.html` in a browser after building. Do **not** claim behavior is verified without a real check.
- **Test:** `npm test` (Vitest) runs characterization tests asserting parity against the original `jsfeat` (see `tests/`). Also verify visually via `examples/*.html` after building. Do **not** claim behavior is verified without a real check.

## Architecture — read this before editing

Expand Down
140 changes: 70 additions & 70 deletions examples/js/compatibility.js
Original file line number Diff line number Diff line change
@@ -1,71 +1,71 @@
/**
* this code is from all around the web :)
* if u want to put some credits u are welcome!
*/
var compatibility = (function() {
var lastTime = 0,
isLittleEndian = true,
URL = window.URL || window.webkitURL,
requestAnimationFrame = function(callback, element) {
var requestAnimationFrame =
window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function(callback, element) {
var currTime = new Date().getTime();
var timeToCall = Math.max(0, 16 - (currTime - lastTime));
var id = window.setTimeout(function() {
callback(currTime + timeToCall);
}, timeToCall);
lastTime = currTime + timeToCall;
return id;
};
return requestAnimationFrame.call(window, callback, element);
},
cancelAnimationFrame = function(id) {
var cancelAnimationFrame = window.cancelAnimationFrame ||
function(id) {
clearTimeout(id);
};
return cancelAnimationFrame.call(window, id);
},
getUserMedia = function(options, success, error) {
var getUserMedia =
window.navigator.getUserMedia ||
window.navigator.mozGetUserMedia ||
window.navigator.webkitGetUserMedia ||
window.navigator.msGetUserMedia ||
function(options, success, error) {
error();
};
return getUserMedia.call(window.navigator, options, success, error);
},
detectEndian = function() {
var buf = new ArrayBuffer(8);
var data = new Uint32Array(buf);
data[0] = 0xff000000;
isLittleEndian = true;
if (buf[0] === 0xff) {
isLittleEndian = false;
}
return isLittleEndian;
};
return {
URL: URL,
requestAnimationFrame: requestAnimationFrame,
cancelAnimationFrame: cancelAnimationFrame,
getUserMedia: getUserMedia,
detectEndian: detectEndian,
isLittleEndian: isLittleEndian
};
/**
* this code is from all around the web :)
* if u want to put some credits u are welcome!
*/
var compatibility = (function() {
var lastTime = 0,
isLittleEndian = true,

URL = window.URL || window.webkitURL,

requestAnimationFrame = function(callback, element) {
var requestAnimationFrame =
window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function(callback, element) {
var currTime = new Date().getTime();
var timeToCall = Math.max(0, 16 - (currTime - lastTime));
var id = window.setTimeout(function() {
callback(currTime + timeToCall);
}, timeToCall);
lastTime = currTime + timeToCall;
return id;
};

return requestAnimationFrame.call(window, callback, element);
},

cancelAnimationFrame = function(id) {
var cancelAnimationFrame = window.cancelAnimationFrame ||
function(id) {
clearTimeout(id);
};
return cancelAnimationFrame.call(window, id);
},

getUserMedia = function(options, success, error) {
var getUserMedia =
window.navigator.getUserMedia ||
window.navigator.mozGetUserMedia ||
window.navigator.webkitGetUserMedia ||
window.navigator.msGetUserMedia ||
function(options, success, error) {
error();
};

return getUserMedia.call(window.navigator, options, success, error);
},

detectEndian = function() {
var buf = new ArrayBuffer(8);
var data = new Uint32Array(buf);
data[0] = 0xff000000;
isLittleEndian = true;
if (buf[0] === 0xff) {
isLittleEndian = false;
}
return isLittleEndian;
};

return {
URL: URL,
requestAnimationFrame: requestAnimationFrame,
cancelAnimationFrame: cancelAnimationFrame,
getUserMedia: getUserMedia,
detectEndian: detectEndian,
isLittleEndian: isLittleEndian
};
})();
Loading
Loading