Fix #60: restore root use.{js,cjs,mjs} CDN mirrors broken by 8.14.0 src/ move#61
Conversation
Adding .gitkeep for PR creation (default mode). This file will be removed when the task is complete. Issue: #60
The 8.14.0 release moved use.js/use.cjs/use.mjs under src/, which 404'd the historical bootstrap URL https://unpkg.com/use-m/use.js. unpkg/jsdelivr serve raw files and ignore package.json "exports", so the bare path could no longer resolve. A naive eval() of the 404 body ("Not found: /[email protected]/use.js") throws the cryptic "SyntaxError: Unexpected identifier 'found'" from the issue. This script reproduces the failure end to end and confirms src/use.js still eval()s cleanly, pinpointing the fix: restore root-level mirrors of src/.
Republish root-level use.js/use.cjs/use.mjs so the long-standing CDN bootstrap URLs (https://unpkg.com/use-m/use.js, .cjs, .mjs) resolve again after the 8.14.0 move to src/. unpkg/jsdelivr serve raw published files and ignore package.json "exports", so a bare /use-m/use.js only resolves when a real file lives at the package root. The mirrors are FULL copies, not require('./src/use.js') shims: the historical bootstrap fetches and eval()s use.js directly, and a require/import shim cannot work in an eval() context (require is undefined; the relative base is the caller, not use-m). src/ stays the single source of truth. - scripts/sync-root-entries.mjs regenerates the mirrors (npm run sync:entries) - package.json: add mirrors to files[], bump 8.14.0 -> 8.14.1, add sync:entries - exports map keeps ./use.cjs and ./use.mjs (real modules); use.js stays eval-only and is intentionally not advertised as an importable subpath Refs #60
tests/root-entries.test.mjs asserts the root use.{js,cjs,mjs} mirrors exist,
stay byte-for-byte in sync with src/ (via scripts/sync-root-entries.mjs),
eval()/import() to a working use function, and are shipped in the npm package
while src/ remains canonical. It also pins the core regression: eval()'ing the
404 "Not found" body throws a SyntaxError, whereas the restored mirror does not.
Passes across all three runtimes (Jest/Node, Bun, Deno) via the cross-runtime
test adapter.
Refs #60
- README: add a "Troubleshooting: SyntaxError: Unexpected identifier 'found'" subsection explaining the 8.14.0 regression and three remedies (upgrade to 8.14.1, switch the URL to the /src/ path on any CDN, or harden the bootstrap with use-m/load). Verified against the live CDNs that the bare /use.js 404s on unpkg AND jsDelivr on 8.14.0, so switching host alone does not help. - CHANGELOG: add a CRITICAL Fixed entry for the restored root mirrors and note on the src/ move that bare URLs work again via the mirrors. - CONTRIBUTING: document the generated root mirrors, the npm run sync:entries step after editing src/use.*, and the guarding test. Refs #60
Verified against the live CDNs and runtimes:
- jsDelivr's *unversioned* bare URL returns 200 but serves a STALE pre-src/-move
copy (silently outdated code); the *pinned* @8.14.0/use.js 404s. unpkg 404s for
both. So README now recommends the /src/ path as the reliable cross-CDN fix and
warns about jsDelivr's stale unversioned response, instead of claiming the bare
path uniformly 404s.
- The maintainer-suggested shim (module.exports = require('./src/use.js')) cannot
fix the eval bootstrap: in the real ESM consumer it throws "ReferenceError:
module is not defined"; in a browser "require is not defined"; in CJS with the
wrong CWD "Cannot find module"; and src/use.js has no module.exports so it would
yield {} anyway. The experiment now demonstrates this, justifying full copies.
Refs #60
🤖 Solution Draft LogThis log file contains the complete execution trace of the AI solution draft process. 💰 Cost estimation:
📊 Context and tokens usage:Claude Opus 4.8: (2 sub-sessions)
Total: (20.1K new + 262.2K cache writes + 7.3M cache reads) input tokens, 90.5K output tokens, $7.648964 cost 🤖 Models used:
📎 Log file uploaded as Gist (3339KB)Now working session is ended, feel free to review and add any feedback on the solution draft. |
✅ Ready to mergeThis pull request is now ready to be merged:
Monitored by hive-mind with --auto-restart-until-mergeable flag |
This reverts commit 914928e.
|
We need to fix CI/CD, and double check all changes are correct, and requirements from the issue fully addressed. |
|
🤖 AI Work Session Started Starting automated work session at 2026-06-15T12:30:42.459Z The PR has been converted to draft mode while work is in progress. This comment marks the beginning of an AI work session. Please wait for the session to finish, and provide your feedback. |
✅ CI fixed, changes re-verifiedCI/CDThe only failing check was Test on deno (ubuntu-latest), and the failure was a transient external-CDN flake — not a regression from this PR: Evidence it's a flake, not our code:
I re-ran the failed job and all 7 checks are now green. Re-verification of the fix (requirements from #60)
Local verification on this branch:
Ready for review. |
Working session summaryI've resolved the situation. Here's the summary: What was wrongThe PR (#61) for issue #60 had one failing check: Test on deno (ubuntu-latest). Root cause of the CI failureA transient external-CDN flake in the
Verification of the fix itself (issue #60 requirements)I re-checked both requirements:
Local results on the branch:
Actions taken
I deliberately did not modify the flaky This summary was automatically extracted from the AI working session output. |
🤖 Solution Draft LogThis log file contains the complete execution trace of the AI solution draft process. 💰 Cost estimation:
📊 Context and tokens usage:
Total: (3.3K new + 37.9K cache writes + 873.6K cache reads) input tokens, 9.1K output tokens, $0.916566 cost 🤖 Models used:
📎 Log file uploaded as Gist (755KB)Now working session is ended, feel free to review and add any feedback on the solution draft. |
🔄 Auto-restart 1/5Detected uncommitted changes from previous run. Starting new session to review and commit or discard them. Uncommitted files: Auto-restart will stop after changes are committed or discarded, or after 4 more iterations. Please wait until working session will end and give your feedback. |
Working session summaryWorking tree is clean, the lockfile is committed, and The uncommitted change has been resolved. Here's the summary: What the uncommitted change was
Action takenCommitted the lockfile sync and pushed:
Verification
This was a legitimate, focused change (lockfile version alignment for the release), not stray work — so committing rather than reverting was correct. The PR (#61) state is otherwise unchanged and remains the fix for issue #60. This summary was automatically extracted from the AI working session output. |
🔄 Auto-restart 1/5 LogThis log file contains the complete execution trace of the AI solution draft process. 💰 Cost estimation:
📊 Context and tokens usage:
Total: (2.9K new + 18.1K cache writes + 120.4K cache reads) input tokens, 1.5K output tokens, $0.225594 cost 🤖 Models used:
📎 Log file uploaded as Gist (1109KB)Now working session is ended, feel free to review and add any feedback on the solution draft. |
✅ Ready to mergeThis pull request is now ready to be merged:
Monitored by hive-mind with --auto-restart-until-mergeable flag |
Summary
Fixes #60. After
[email protected]moved the entry files intosrc/, the historical CDN bootstrap URLhttps://unpkg.com/use-m/use.jsstarted returning 404. Consumers thateval()the response body without checking the HTTP status evaluated the 404 text as JavaScript and crashed with the cryptic:This PR restores the root-level
use.js/use.cjs/use.mjsfiles while keepingsrc/as the single source of truth, so every existing consumer keeps working unchanged after upgrading — and documents how to fix affected projects on any version.Root cause
8.14.0(PR Resilient CDN loading: shared loadWithFallback engine + per-package fallback + robust use-m/load bootstrap (#58) #59, commitecee09e) moveduse.{js,cjs,mjs}and friends intosrc/and updated the package.jsonexportsmap.exportsmap. A bare URL likehttps://unpkg.com/use-m/use.jsonly resolves if a real file lives at the package root. After the move, that path 404'd:Not found: /[email protected]/use.js→eval()→SyntaxError: Unexpected identifier 'found'@link-assistant/hive-mind'suse-m-bootstrap.lib.mjs) doeseval(await (await fetch(url)).text()), so the 404 body was eval'd directly.Reproduced end-to-end in
experiments/issue60-root-url-regression.mjs.CDN behavior, verified against the live services (2026-06-15)
https://unpkg.com/use-m/use.jsNot foundhttps://unpkg.com/[email protected]/use.jsNot foundhttps://cdn.jsdelivr.net/npm/[email protected]/use.jsCouldn't find the requested filehttps://cdn.jsdelivr.net/npm/use-m/use.js(unversioned)src/copyhttps://unpkg.com/use-m/src/use.jshttps://cdn.jsdelivr.net/npm/use-m/src/use.jsThe fix
use.js,use.cjs,use.mjsas full copies ofsrc/use.*, generated byscripts/sync-root-entries.mjs(npm run sync:entries).src/remains canonical; the mirrors carry anAUTO-GENERATEDheader.require('./src/use.js')shims? (The shim was the maintainer's first suggestion.) The bootstrap fetches andeval()suse.jsdirectly, so a shim runs in the consumer's scope, where it just swaps one cryptic error for another instead of returning a workinguse. Verified experimentally:use-m-bootstrap.lib.mjs):ReferenceError: module is not definedReferenceError: require is not definedCannot find module './src/use.js'src/use.jshas nomodule.exports(it ends in a baremakeUse(...)expression), so a shim yields{}— never a workinguse.files[], bumped8.14.0→8.14.1(triggers the release workflow), and added thesync:entriesscript. Theexportsmap still maps./use.cjsand./use.mjstosrc/(real modules);use.jsstays eval-only and is intentionally not advertised as an importable subpath (matching historical behavior).tests/root-entries.test.mjs(14 cases) asserts the mirrors exist, stay byte-for-byte in sync withsrc/, eval/import to a workinguse, and ship in the npm tarball — and pins the regression (the 404 body throwsSyntaxError; the mirror does not).Confirmed via
npm pack --dry-runthat the published tarball now contains both the root mirrors andsrc/(15 files).How to fix projects that use use-m (also in the README)
A new README subsection — Troubleshooting:
SyntaxError: Unexpected identifier 'found'— documents three remedies:8.14.1+ (e.g. pinhttps://unpkg.com/[email protected]/use.js). No code change needed.8.14.0). Point the URL at thesrc/path on any CDN:https://unpkg.com/use-m/use.js→https://unpkg.com/use-m/src/use.jshttps://cdn.jsdelivr.net/npm/use-m/use.js→https://cdn.jsdelivr.net/npm/use-m/src/use.jseval(await (await fetch(url)).text())with a guarded loader that checksresponse.ok, rejects non-JS bodies, and falls back across mirrors — the packageduse-m/loadhelper or the self-contained snippet in the README. This prevents any future 404/redirect from being silently eval'd.Testing
All three runtimes pass, including the new regression test:
bun test)deno test …)CI (node/bun/deno × ubuntu/macos) is green on the latest commit.
Files changed
experiments/issue60-root-url-regression.mjs— reproduction (incl. shim-failure demo)scripts/sync-root-entries.mjs— mirror generator (npm run sync:entries)use.js,use.cjs,use.mjs— restored root mirrors (auto-generated)package.json—files[], version8.14.1,sync:entriesscripttests/root-entries.test.mjs— drift + regression guardREADME.md,CHANGELOG.md,CONTRIBUTING.md— docsCloses #60