mirror of
https://github.com/pnpm/pnpm.git
synced 2026-07-19 12:12:34 -04:00
e164bdbf36f60bcc80fddf45fc0f74480f264556
Foundation for porting pnpm's side-effects cache (item #10 of #397). This PR lands the three pieces that the actual cache read/write paths depend on: - **New `pacquet-graph-hasher` crate** porting pnpm's `@pnpm/crypto.object-hasher` (`hashObject` / `hashObjectWithoutSorting`) plus `@pnpm/deps.graph-hasher` (`calcDepState` / `calcDepGraphHash`) and `ENGINE_NAME`. Byte-for-byte parity with the JS [`object-hash@3.0.0`](https://github.com/puleos/object-hash/blob/v3.0.0/index.js) bytestream format is load-bearing — the cache key is persisted on disk and shared with pnpm. The headline parity test pins `hashObject({b:1,a:2}) == "48AVoXIXcTKcnHt8qVKp5vNw4gyOB5VfztHwtYBRcAQ="` against the upstream fixture in [`crypto/object-hasher/test/index.ts:6`](https://github.com/pnpm/pnpm/blob/b4f8f47ac2/crypto/object-hasher/test/index.ts#L6). - **`VerifyResult.side_effects_maps`** in `pacquet-store-dir`. The verify path (`check_pkg_files_integrity` and `build_file_maps_from_index`) used to drop `PackageFilesIndex.side_effects` after extraction. It now applies the `added`/`deleted` overlay per cache key and surfaces a `HashMap<cache_key, FilesMap>` — the same shape pnpm uses for its `PackageFilesResponse.sideEffectsMaps`. Mirrors [`applySideEffectsDiffWithMaps`](https://github.com/pnpm/pnpm/blob/b4f8f47ac2/store/create-cafs-store/src/index.ts#L103-L121). - **`Config.side_effects_cache`** config knob (default `true`, matching pnpm). Surfaced on the wire **only** — no consumer yet. Wires up cleanly once the build-phase gate lands in #421, with no config migration needed for downstream callers. ## Scoped narrowly This is **only the foundation**. There is no `is_built` field, no `BuildModules` skip gate, and no end-to-end test of the rebuild-skip behavior. Those land in a separate follow-up tracked in #421, which also covers the WRITE path (pacquet seeding the cache itself). The natural slice for review: graph-hasher unblocks both READ and WRITE, the verify-path surfacing is the only intrusive cross-crate change, and the config knob is forward-looking. ### Hashing scope, explicitly The `pacquet-graph-hasher` port implements only the type arms pacquet actually feeds into `hashObject` for the cache-key path: strings, objects, numbers, booleans, null, and arrays in their ordered form. `Set` / `Map` / `Date` / `Buffer` / `Array` unordered-permutation arms from [upstream `object-hash`](https://github.com/puleos/object-hash/blob/v3.0.0/index.js#L257-L389) are unimplemented — no caller in pacquet's tree feeds them in today, and the test fixtures upstream uses (`hashObject({ b: new Set([…]), a: [...] })`) hash deterministically across orderings only because they're testing the library, not exercising a real call path. Adding them can land alongside a future caller that needs them.
Description
Languages
Rust
60.5%
TypeScript
38.9%
JavaScript
0.5%