Skip to content

feat: expose the extension package size in the API and web UI - #2168

Draft
netomi wants to merge 1 commit into
mainfrom
feat/extension-download-size
Draft

feat: expose the extension package size in the API and web UI#2168
netomi wants to merge 1 commit into
mainfrom
feat/extension-download-size

Conversation

@netomi

@netomi netomi commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

Closes #367.

Context

The issue asks for the extension size to be displayed, packagephobia-style. Half of what that needs already exists: file_resource.size has been recorded since V1_73__File_Resource_Size.sql (#2089, #2095), set on publish in PublishExtensionVersionService and StorageUtilService, and backfilled for older rows by FileResourceSizeJobRequestHandler. Nothing ever read it back out, though — it reached no API response and no page.

Change

  • ExtensionJson.downloadSize — size in bytes of the file behind files.download, for this version and target platform. Set by all three JSON builders, so /api/{ns}/{ext}, the query API and v2 all carry it.
  • Web UI — a Size entry in the More Info box, next to the unique identifier, which is where the issue suggested it. Rendered with the existing formatFileSize helper.

Two decisions worth calling out:

It reads the download resource, not a SUM over the version's files. Readme, icon, changelog and license are stored as rows of their own but hold content that is already inside the .vsix, so summing counts it twice. (Web resources don't distort it either way — those are extracted to a cache on demand, not stored as rows.)

Unknown is omitted, not zero. A package published before the column existed that the backfill hasn't reached has size = null; ExtensionJson is @JsonInclude(NON_NULL), so the field is simply absent, and the UI leaves the section out. A client has no way to tell a zero-byte file from an unknown one, so it gets neither.

Download size, not install size

The issue asks about install size — the reporter's example is a ~110MB .vsix that's over 200MB on disk — and this is the download size. The two differ by the package's compression ratio, which is exactly the reporter's point about bundled .map files and stray node_modules.

Install size isn't stored and isn't cheaply derivable. It's computable at publish (the code already walks zip entries in ArchiveUtil and SecretDetector, and ExtensionVersionIntegrityService sums entry.getSize() into the signature manifest), but backfilling it means re-reading every existing .vsix out of storage — a much larger job than V1_73's was. That seems worth its own issue and its own decision, rather than holding up the number we already have.

One query, not two

The detail path used StorageUtilService.getFileUrls, which discards everything but the URL. Rather than add a second query for the size, getFiles now returns the resources and getFileUrls is a shorthand over it, unchanged for its nine other callers. The detail builder then uses the toFilesJson mapping the other two builders already share, which also removes the duplicated public-key-alongside-signature handling it had grown.

Testing

  • RegistryAPITest.testExtensionDownloadSize / testExtensionDownloadSizeUnknown — the value reaches the JSON; a null size leaves the field out.
  • extension-detail-overview.spec.tsx (new) — the Size section renders, and is absent when the registry doesn't know the size.
  • Full server suite green (1165 tests), full webui suite green (278 tests, 55 files), tsc --noEmit and yarn lint clean.

Three existing tests stubbed getFileUrls for the detail path and now stub getFiles.

🤖 Generated with Claude Code

@netomi
netomi force-pushed the feat/extension-download-size branch from 9df36d8 to a98d4b1 Compare September 5, 2026 11:47
@netomi
netomi marked this pull request as draft September 5, 2026 12:33
file_resource.size has been recorded since V1_73, populated on publish and
backfilled for older rows, but nothing ever read it back out: it reaches no
API response and no page. Issue #367 asks to display it.

Add ExtensionJson.downloadSize - the size in bytes of the file behind
files.download - and a Size entry in the web UI's More Info box beside the
unique identifier, where #367 suggested it belongs.

The size is read from the download resource rather than summed over the
version's files: readme, icon, changelog and license are rows of their own
holding content that is already inside the package, so a sum counts it
twice. It is null, and omitted from the JSON, for a package published before
the column existed that the backfill has not reached - a client cannot tell
a zero from an unknown, so it gets neither.

Note this is the download size. The install size the issue asks about is
larger by whatever the package's compression ratio happens to be, and is not
something the registry stores; it would need its own column and a job that
re-reads every existing .vsix.

The detail endpoint now takes StorageUtilService.getFiles instead of
getFileUrls so the size comes from the same query as the URLs rather than a
second one, and builds its file map with the toFilesJson the other two
builders already share - which also drops the duplicated public-key handling
it had grown.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@netomi
netomi force-pushed the feat/extension-download-size branch from a98d4b1 to bdc14f9 Compare September 5, 2026 12:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[site feature] Display extension size

1 participant