fix(lib-node): version-key extraction path to bust ESM module cache - #7
Merged
Conversation
ensureArtefact extracted updated plugins to a stable path
(<artefactId>/<buildTuple>), so a long-lived process re-importing the
plugin kept serving the stale module graph: Node's ESM registry is keyed
by resolved URL, and the existing ?imported=Date.now() cache-bust only
re-evaluated the entry module, not its siblings or bundled deps.
Extract into a content-versioned dir instead:
<artefactId>/
.pointer-<buildTuple>.json # stable: { dataUpdatedAt, version, dir }
<version>+<epochSeconds>/<buildTuple>/
The stable pointer drives the conditional GET; on 304 we return its
existing dir, on 200 we extract to a new dir, atomically repoint, and
prune dirs no pointer references. Pruning keeps every dir referenced by
any buildTuple pointer, so a build-side download can't delete the js
consumer's still-current dir.
The path discriminator is dataUpdatedAt at epoch-second precision,
matching the registry's If-Modified-Since criterion exactly: the same
equivalence relation gates both the 304/200 decision and the cache-bust.
Keying on dataUpdatedAt (not version) also handles same-version
re-publishes and an empty x-artefact-version header.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The discriminator switched to epoch-seconds; the JSDoc still said <hash>. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.
Rework
lib-node'sensureArtefactto extract each artefact into a content-versioned directory behind a stable per-buildTuple pointer file, so a changed artefact resolves to a brand-new path and Node's ESM module registry reloads the entire graph (entry + siblings + bundled deps), not just the query-busted entry.Why: plugins were not refreshed in memory after a registry update in long-lived processes.
ensureArtefactre-extracted to a stable path, so the ESM registry (keyed by resolved URL) kept serving the stale module graph; the existing?imported=Date.now()only re-evaluated the entry module.New cache layout:
The stable pointer drives the conditional GET. On 304 we return its existing dir; on 200 we extract to a new dir, atomically repoint, then prune dirs no pointer references. The path discriminator is
dataUpdatedAtat epoch-second precision, matching the registry'sIf-Modified-Sincecriterion exactly — the same equivalence relation gates both the 304/200 decision and the cache-bust. Keying ondataUpdatedAt(notversion) also covers same-version re-publishes and an emptyx-artefact-versionheader. Released as@data-fair/lib-node-registry0.7.0.Regression risks:
<buildTuple>/.meta.jsonlayout, so the first call per artefact reads as cold (one re-download) and the old bare<buildTuple>dir is pruned. Intended, not a silent no-op.pathis no longer stable across versions (by design). Any consumer that persisted the path across an update must re-callensureArtefact; the processings API already re-calls on every prepare.hasNativeModulesis no longer stored in the cache metadata — safe, it was only ever read from the response header on the 200 path.