chore(deps): pin libheif-js 1.23.2 in the lockfile so CI tests what consumers install - #389
Merged
Merged
Conversation
…onsumers install core declares libheif-js as an optionalDependency with `^1.19.8`. The workspace lockfile pinned 1.19.8, but a lockfile-less install — the package smoke consumer, and every real user — resolves 1.23.2, the newest 1.x. So the HEIC integration suite proved a decoder that nobody installs, and `smoke:packages` installs 1.23.2 but only measures bundle shape and size (assertConsumerBundleShape never executes a decode). Nothing in CI exercised the version users actually get. Verified before pinning: 1.23.2 decodes the repo's real 64x64 HEIC fixture through heic-decode.ts unchanged — same module shape (default factory), same HeifDecoder/decode/display/free API, 406 source bytes -> 64x64 -> a 785-byte JPEG with valid SOI/EOI markers, byte-for-byte the same result as 1.19.8. Applied as a three-hunk lockfile edit rather than through pnpm: both `pnpm update libheif-js --filter @useupup/core` and `pnpm add libheif-js@^1.19.8 --filter @useupup/core --save-optional` re-resolved unrelated peer graphs (1194-2828 changed lines, including a vitest 4.1.11 -> 4.1.2 downgrade), and the first also rewrote core's manifest range. A control `pnpm install` with no dependency change produced no diff, so the churn came from the re-resolution, not from lockfile drift. `pnpm install --frozen-lockfile` accepts the edited lockfile — it refuses to rewrite one — which is what proves it self-consistent. core's `^1.19.8` range is unchanged, so consumers receive exactly what they did before; this moves only what we test.
Review or Edit in CodeSandboxOpen the branch in Web Editor • VS Code • Insiders |
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.
Pins
libheif-jsat 1.23.2 in the lockfile so the HEIC integration suite runs against the version consumers actually install. Four lines, one package;packages/core/package.jsonis untouched.Why
^1.19.8(core optionalDependency)^1.19.8npm view libheif-js version; the published 1.x list ends…1.18.2, 1.19.8, 1.23.2)So
packages/core/tests/integration/heic-decode.integration.test.ts— the only place a real HEIC is decoded throughheic-decode.ts— proved a decoder nobody installs.smoke:packagesdoes install 1.23.2, butassertConsumerBundleShapeonly measures bundle shape and asset size; it never executes a decode. Nothing in CI exercised the version users get, which is how #378 could re-base the opt-in chunk budget from ~1425 KiB to 1939.4 KiB for a decoder that had never been run.Verified before pinning
1.23.2 decodes the repo's real 64×64 HEIC fixture through our own code path, unchanged:
defaultis the factory;HeifDecoder/decode/get_width/get_height/display/free/heif_context_freeall behave asheic-decode.tsexpects.64x64decoded → 785-byte JPEG, SOI0xff 0xd8, EOI0xff 0xd9, re-decoded back to64x64by@napi-rs/canvas. Byte-identical to 1.19.8 on every one of those numbers.Why the lockfile was edited by hand
pnpm's own commands could not produce a narrow diff:
pnpm update libheif-js --filter @useupup/core^1.23.2pnpm add libheif-js@^1.19.8 --filter @useupup/core --save-optional@typescript-eslint/*,@vue/language-core,ts-api-utilsControl experiment: a plain
pnpm installwith no dependency change produced no lockfile diff, so that churn comes from the re-resolution itself, not from pre-existing lockfile drift. Both attempts were reverted and the tree restored with--frozen-lockfilebefore the hand edit.The edit is three hunks — the importer's resolved version, the
packagesentry (version + integrity, taken fromnpm view libheif-js@1.23.2 dist.integrity), and thesnapshotsentry. 1.23.2 has no dependencies and the sameenginesas 1.19.8, so nothing else in the graph moves.pnpm install --frozen-lockfileaccepts it — that command refuses to rewrite a lockfile, so its success is the proof that the file is self-consistent, and it left the diff at exactly those four lines.Confirming the bump did something
Three independent checks after installing:
packages/core/node_modules/libheif-js/package.json→1.23.2pnpm --filter @useupup/core list libheif-js→libheif-js 1.23.2require.resolve('libheif-js/libheif-wasm/libheif-bundle.mjs')→node_modules/.pnpm/libheif-js@1.23.2/…No changeset
Deliberate, not an oversight:
libheif-jsis an optionalDependency resolved at the consumer's own install, and core's^1.19.8range is unchanged — consumers already received 1.23.2 and still will. This moves what we test, not what anyone receives, so there is no published-artifact change to describe.Gates (all via
rtk proxy, raw exit codes)pnpm install --frozen-lockfilepnpm --filter @useupup/core exec vitest run tests/integration/heic-decode.integration.test.tspnpm --filter @useupup/core testpnpm run typecheckpnpm-lock.yamlis listed in.prettierignoreandprettier --checkreports it clean either way.Related, not in scope
.size-limit.jsonhas no HEIC/libheif entry — core's 410 KB budget covers the mandatory path only, which is why a ~1.9 MB opt-in chunk cannot red it. That is by design (the opt-in path is guarded byconsumerOptionalChunkBudgetin the smoke consumer), so this PR leaves it alone.