Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

Detailed changelog for Perry. See CLAUDE.md for concise summaries.

## v0.5.909 — feat: add `libDirs` to native library manifest (#762). New optional `targets.<target>.libDirs` field in `package.json`'s `perry.nativeLibrary` block — array of linker search paths emitted ahead of the `libs` list. **Surface.** Documented in `docs/src/native-libraries/manifest-v1.md` alongside the existing `libs` / `frameworks` / `pkgConfig` entries. Use it when a wrapper ships a vendored `.a`/`.dylib` outside the cargo crate (the standard `lib_name` lookup probes `target/<triple>/release/`); previously the only escape hatch was an absolute path glued into `libs` via a workaround. **Plumbing.** Three edits — (1) `TargetNativeConfig.lib_dirs: Vec<PathBuf>` field added in `crates/perry/src/commands/compile.rs`; (2) `parse_native_library_manifest` parses `libDirs` and anchors relative entries to `package_dir` via `package_dir.join(p)` — mirrors the existing `swift_sources` / `metal_sources` pattern so a `"./vendor/lib"` in the manifest resolves against the wrapper's directory, not the user's cwd (absolute entries pass through unchanged since `PathBuf::join` ignores the base on an absolute right-hand side); (3) `build_and_run_link` in `crates/perry/src/commands/compile/link.rs` emits each entry between the `frameworks` loop and the `libs` loop — `-L<dir>` on every non-Windows target, `/LIBPATH:<dir>` when `is_windows` (mirrors the `libs` loop's existing `{lib}.lib` vs `-l{lib}` MSVC/Unix split, so a `targets.windows.libDirs` entry actually resolves the `{lib}.lib` lookups instead of being a silent no-op against link.exe). **Validation.** Two new unit tests in `crates/perry/src/commands/compile/resolve.rs::manifest_parse_tests` — `lib_dirs_relative_paths_anchored_to_package_dir` round-trips a manifest with both `"vendor/lib"` and `"/abs/path"` and asserts the package_dir-anchored / pass-through behavior; `lib_dirs_defaults_to_empty_when_absent` confirms the field is optional. `cargo build --release` clean; `cargo test -p perry --lib` green. **Version-bump note.** Renumbered v0.5.908 → v0.5.909 because #760 (test: argon2 + ethers parity) landed on main mid-review and took the v0.5.908 slot. **Contributor.** Implementation by @Lebei2046; MSVC `/LIBPATH:` branch + `package_dir` anchoring + tests + manifest doc entry + this changelog folded in at merge time.

## v0.5.908 — test: #698 — behavioral parity tests for argon2 + ethers integrations (#760). Follow-up to #694, addressing #698. Adds two new parity fixtures and a `@covers` block on `test_parity_crypto.ts`, moving 18 FFI entries out of `test_ffi_surface_stdlib_integrations.ts` (156 → 138 unique names) into behavioral coverage. **`test_parity_argon2.ts`** — round-trips `argon2.hash` / `argon2.verify` against the `perry-ext-argon2` wrapper; non-deterministic salt is handled by shape-checking the `$argon2id$` prefix and asserting verify round-trips against a freshly produced hash. Only the async path is in `NativeModSig`, so this covers the two FFI entries (`js_argon2_hash`, `js_argon2_verify`) reachable end-to-end. **`test_parity_ethers.ts`** — pure deterministic helpers from `perry-ext-ethers`: `getAddress` (EIP-55 checksum on lower- and upper-case input), `parseEther`/`formatEther` round-trip on 1.5 ETH, `parseUnits`/`formatUnits` at 6- (USDC) and 9-decimal (gwei) positions. Covers the five `js_ethers_*` helpers. Both new fixtures use the `test-parity/expected/` mechanism — Perry routes the npm-style imports to the bundled `perry-ext-*` wrappers, but Node can't resolve the same names without `node_modules`, so they fall through to stored expected-output comparison. **`test_parity_crypto.ts`** — adds a `@covers` block declaring the crypto/webcrypto/crypto_e2e FFI surface it already exercises via `node:crypto` and `crypto.subtle` (digest, hash, pbkdf2/hkdf, subtle.sign/verify); no behavioral change. **Out of scope (each gets its own follow-up).** `jsonwebtoken.sign` — `NativeModSig` passes `payload`/`secret` as `NA_F64` (NaN-boxed) but `js_jwt_sign` reads them as `*const StringHeader`, producing garbage tokens (calling-convention mismatch, same shape as the #591 argon2 fix). `bcrypt.hash` — return value reports `typeof === "object"` in user code; `compare` round-trips correctly but `.startsWith(...)` on the hash fails. `cheerio` — `$.select(...)` returns a bare-number handle, so `.length()` / `.first()` etc. fail with `(number).method is not a function` at the prototype check. Service-backed integrations (MongoDB, MySQL, PG, ioredis, Nodemailer, Sharp) also remain in the inventory pending the local-container / opt-in test setup described in #698. **Audit.** `./test-coverage/audit.sh --markdown` keeps TS-side and combined FFI coverage at **1791/1791 (100.0%)**. `test_ffi_surface_stdlib_integrations.ts` re-regenerated via `regen_ts_surface_inventory.py` to fold in the new `@covers` blocks. Comment-only changes; no behavioral or runtime impact. Contributor: @TheHypnoo.

## v0.5.907 — test(stdlib): #697 — move stdlib_io FFI coverage into behavioral tests (#758). Follow-up to #694: relocates the 155 inventory entries from `test_ffi_surface_stdlib_io.ts` into `@covers` annotations attached to the existing behavioral fixtures for each surface — `fetch.rs` (43 names) → `test_gap_fetch_response.ts`; `streams.rs` (37) → `test_parity_stream_web.ts`; `http.rs` (13) → `test_parity_http.ts`; `net/mod.rs` (10) → `test_net_socket.ts`; `readline.rs` (5) → `test_parity_readline.ts`; `worker_threads.rs` (6) → `test_parity_worker_threads.ts`; `ws.rs` (11) → `test_node_http_ws_upgrade.ts`; `framework/{multipart,request,response,server}.rs` (28) → `test_fastify_integration.ts`. Each receiving fixture already exercises real behavior on its surface (local loopback servers / deterministic in-memory probes / Headers + Blob + Response API roundtrips) — no external services added. **Mechanism.** `regen_ts_surface_inventory.py` excludes the six `test_ffi_surface_*.ts` inventory files when scanning for `@covers` references, so any FFI name that appears in a non-inventory fixture's `@covers` block is dropped from its inventory file on the next regen. After this PR, `test_ffi_surface_stdlib_io.ts` shrinks from **155 → 0** unique FFI names. **Audit.** `./test-coverage/audit.sh --markdown` keeps TypeScript and combined FFI coverage at **1791/1791 (100.0%)**. `test_ffi_surface_runtime_core.ts` re-regenerated against current `main` post-rebase — the inventory drift visible in the diff (added `js_array_flat_depth`, `js_template_raw`, `js_path_matches_glob`, `js_async_first_call`, the 7 new `webassembly.rs` exports; removed `js_mul`, `js_net_socket_destroy/end/write`, the 9 `js_ws_*` stubs from `stdlib_stubs.rs`) reflects upstream Rust refactors, not hand edits. Comment-only changes; no behavioral or runtime impact. Contributor: @TheHypnoo.
Expand Down
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co

Perry is a native TypeScript compiler written in Rust that compiles TypeScript source code directly to native executables. It uses SWC for TypeScript parsing and LLVM for code generation.

**Current Version:** 0.5.908
**Current Version:** 0.5.909


## TypeScript Parity Status
Expand Down
Loading
Loading