Skip to content

refactor: move the esm.run provider into Importmap::EsmRun - #42

Merged
mhenrixon merged 1 commit into
mainfrom
refactor/esm-run-collaborator
Sep 19, 2026
Merged

mhenrixon merged 1 commit into
mainfrom
refactor/esm-run-collaborator

Conversation

@mhenrixon

@mhenrixon mhenrixon commented Sep 19, 2026

Copy link
Copy Markdown
Collaborator

Summary

lib/importmap/packager.rb was at 811 lines against the 800-line ceiling in
.claude/rules/coding-style.md, so the next addition to the command path had
nowhere to go. The esm.run path — the largest block of fork-only behaviour left
in that upstream-owned file — moves to lib/importmap/esm_run.rb: 811 → 743,
and the diff the next git merge upstream/main has to reconcile gets smaller,
which is what .claude/rules/upstream-sync.md asks of every change there.

Moved, as Importmap::EsmRun:

Was Is
Packager::ESM_RUN_PROVIDER EsmRun::PROVIDER
Packager::ESM_RUN_CDN EsmRun::CDN
Packager::ESM_RUN_URL_REGEXP EsmRun::URL_REGEXP
Packager::ESM_RUN_IMPORT_REGEXP EsmRun::IMPORT_REGEXP
Packager.esm_run_resolver EsmRun.resolverstill readable and writable under the old name
Packager#esm_run? EsmRun.provider? — the Packager method stays, as a delegator
Packager#rewrite_esm_run_imports EsmRun.rewrite_imports
Packager#import_from_esm_run EsmRun#imports
Packager#resolve_esm_run_version EsmRun#resolve_version
EsmRun.url_for(name, version, subpath), which the two URL-building sites shared

No behaviour change, and nothing user-facing: bin/importmap pin --from esm.run
prints the same sentences and writes the same pins. The :nodoc: ESM_RUN_*
constants are the only removed names, and CHANGELOG.md gets a ### Changed
bullet saying where they went.

  • lib/importmap/esm_run.rb — new, 118 lines
  • lib/importmap/packager.rb+17 −85
  • lib/importmap/module_inspector.rb, lib/importmap/package_graph.rb — two
    comments repointed at the regex's new home
  • CLAUDE.mdesm_run.rb added to the architecture map and the fork-only list
  • No docs/ change: docs/app/views/docs/pages/configuration.rb documents
    Importmap::Packager.esm_run_resolver, which still answers

Closes #31

Test plan

  • bundle exec rake test448 runs, 1714 assertions, 0 failures, 0 errors, 0 skips, with bun installed, so the --minify paths ran and the live jspm / jsDelivr / npm-registry cases went out
  • test/esm_run_test.rb written first and seen red (cannot load such file -- importmap/esm_run)
  • The manual check an app developer would do:
    bin/importmap pin md5@2.2.0 --from esm.run && cat config/importmap.rb
    
    is test/commands_test.rb's live --from esm.run cases, unchanged and green —
    pin "md5" # @2.2.0 (esm.run) plus the four dependency pins the bundle needs

Deviations & judgment calls

Deviations

  • The issue predicted ~75 lines out and "roughly 720". Actual: 811 → 743
    (−68)
    . packager.rb had grown from 799 to 811 since the issue was filed,
    and the two delegators plus the description: keyword add 17 lines back.

Discoveries

  • docs/app/views/docs/pages/configuration.rb documents
    Importmap::Packager.esm_run_resolver as public config, so it could not just
    move. It is now a delegator to Importmap::EsmRun.resolver — the same shape
    retry_attempts/retry_wait already use for Importmap::HttpRetries.
  • Nothing outside packager.rb ever referenced the ESM_RUN_* constants or
    esm_run?. commands.rb names esm.run only in comments and in
    pin_esm_run_dependencies, which works off the dependency list download
    returns. Two comments in module_inspector.rb and package_graph.rb pointed
    at Packager::ESM_RUN_IMPORT_REGEXP and were repointed.

Judgment calls

  • The version lookup goes through Packager#fetch_remote instead of keeping
    its own Net::HTTP.get_response + with_retries + handle_failure_response.
    HttpRetries#with_retries raises self.class::HTTPError, so an EsmRun with
    its own error classes would raise something ProviderChain's
    rescue Importmap::Packager::Error does not catch — a jsDelivr miss would
    crash the CDN fallback chain instead of reporting and trying the next
    provider. Routing the one request through the Packager keeps every error in
    the Packager hierarchy with no translation layer. Two costs, both accepted: an
    additive description: keyword on fetch_remote/get_response so the
    retry's message stays exactly resolving <uri>, and an unexpected
    non-retryable error on that request is now wrapped in HTTPError rather than
    raised raw.
  • esm_run.rb does not require "importmap/packager". It names
    Importmap::Packager::PACKAGE_SPEC_REGEXP, ::Error and ::HTTPError inside
    method bodies only, which is exactly what package_graph.rb does with
    Packager::Unvendorable. No require cycle, and test/esm_run_test.rb
    requires both, as package_graph_test.rb does.
  • Packager#esm_run? kept as a one-line delegator rather than deleted. It is
    public fork API with no :nodoc:; removing it is not part of this refactor.
  • A CHANGELOG.md entry under a new ### Changed even though no behaviour
    changed, because the :nodoc: ESM_RUN_* constants did move and someone may
    have reached for them.

https://claude.ai/code/session_01B8NAp4J4RS7BBUDDQtRA7W


Summary by cubic

Moves the esm.run provider out of Importmap::Packager into a new Importmap::EsmRun class, getting packager.rb back under the 800-line ceiling and shrinking the next upstream merge diff. Pinning with --from esm.run and reading or writing Importmap::Packager.esm_run_resolver behave exactly as before.

  • Only the :nodoc: Packager::ESM_RUN_* constants are gone; they now live as Importmap::EsmRun::PROVIDER, ::CDN, ::URL_REGEXP, and ::IMPORT_REGEXP.
  • The esm.run version request now uses Packager#fetch_remote, so failures still raise Importmap::Packager::Error and the CDN fallback chain keeps working.
  • Packager#esm_run? stays as a one-line delegator so existing callers don't break.
  • Adds test/esm_run_test.rb covering provider and URL detection, import rewriting, version resolution, and the resolver delegator.

Closes #31

Written for commit 730dd3b. Summary will update on new commits.

Review in cubic

packager.rb was at 811 lines against the 800-line ceiling, so the next
addition to the command path had nowhere to go but another round of
comment-trimming. The largest block of fork-only behaviour in that
upstream-owned file was the esm.run path — nine constants and methods that
between them know one CDN's URL shapes — and moving it out shrinks the diff
the next `git merge upstream/main` has to reconcile. 811 → 743.

The one request esm.run makes still goes out through Packager#fetch_remote.
HttpRetries#with_retries raises self.class::HTTPError, so a collaborator with
its own error classes would raise something ProviderChain's
`rescue Importmap::Packager::Error` doesn't catch, and a jsDelivr miss would
crash the CDN fallback chain instead of moving on to the next provider.
fetch_remote and get_response take the retry's description as a keyword so
that message stays exactly what it was.

No behaviour changes and no documented setting moved:
Importmap::Packager.esm_run_resolver, which docs/configuration.rb lists as
public config, delegates to Importmap::EsmRun.resolver the way retry_attempts
already delegates to HttpRetries.

## Test coverage
- test/esm_run_test.rb: the collaborator's own surface — provider and URL
  recognition, url_for, the import rewrite and its two-version warning, the
  Packager.esm_run_resolver delegation, a resolved version and a 404
- test/packager_test.rb, test/commands_test.rb: unchanged, and the regression
  net for the move — the esm.run cases and the live `--from esm.run` pins

Closes #31

Claude-Session: https://claude.ai/code/session_01B8NAp4J4RS7BBUDDQtRA7W
@mhenrixon mhenrixon self-assigned this Sep 19, 2026
@mhenrixon mhenrixon added the enhancement New feature or request label Sep 19, 2026
@mhenrixon
mhenrixon merged commit 9881bfe into main Sep 19, 2026
47 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

refactor: move the esm.run resolution out of packager.rb

1 participant