Packages renamed to the @uhhm scope (@uhhm/buuh, @uhhm/buuh-html, @uhhm/buuh-component, @uhhm/buuh-devtools, @uhhm/buuh-migrate, @uhhm/bankai). Scoping is load-bearing twice over: npm routes registries per scope so @uhhm/* resolves against project.uhhm.no while everything else stays on npmjs, and it means this fork never squats upstream's names anywhere. The codemod now migrates choo v7 apps to the @uhhm names. README rewritten with the fork framing and full upstream credit; the choojs RFC moves to docs/upstream-rfc-draft.md, in the drawer for if this work ever goes home. API unchanged — choo() is still choo(). Also: Gitea Actions CI + release workflows (npm publish to the uhhm registry on tag push, CDN bundle uploaded as a generic package), npm run bundle producing dist-cdn/buuh.js (the whole framework as one minified ES module for import-map use), docs/publishing.md explaining what Gitea Packages is (a real npm registry) and is not (a CDN — serve the bundle from a static host with module-safe MIME instead), and onload.js constructing window.MutationObserver to match its own guard (surfaced by smoke-testing the bundle outside a full browser). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014NgfSjHE11oFpoSnLVKLXd
3.6 KiB
Publishing buuh on project.uhhm.no
Two different distribution problems, two different mechanisms. Gitea handles one of them natively; the other needs a static host.
1. npm install — Gitea Packages (yes, it does what you hope)
Gitea ships a real npm registry per user/org. For the uhhm org the
endpoint is:
https://project.uhhm.no/api/packages/uhhm/npm/
Publishing happens from the release workflow
(.gitea/workflows/release.yml): tag v8.0.0, push the tag, and every
workspace package is published with a package:write token stored as
the PACKAGES_TOKEN repo secret. Bump the workspace versions before
tagging.
Consuming needs one line of .npmrc in a project (or ~/.npmrc):
@uhhm:registry=https://project.uhhm.no/api/packages/uhhm/npm/
Then plain npm works, and this is why the packages are scoped: npm
routes by scope, so @uhhm/* resolves against your Gitea while
everything else still comes from npmjs.org. No token is needed to
install if the packages are public (they inherit visibility from the
owner). Starting a project is:
$ echo "@uhhm:registry=https://project.uhhm.no/api/packages/uhhm/npm/" >> .npmrc
$ npm i @uhhm/buuh @uhhm/buuh-html
$ npm i -D @uhhm/bankai
$ npx bankai start app.js
2. "CDN require" — the part Gitea does NOT do
This is the misunderstanding worth clearing up: Gitea's npm registry
serves tarballs to package managers, not individual JavaScript files to
browsers. There is no unpkg-style https://…/@uhhm/buuh/index.js
endpoint, and the generic-package download URLs serve
application/octet-stream — browsers refuse that for ES modules (strict
MIME checking). So an import map cannot point at Gitea directly.
What works instead, in order of effort:
a. The single-file bundle + any static host (recommended).
npm run bundle produces dist-cdn/buuh.js — the whole framework as
one minified ES module with named exports. The release workflow uploads
it to Gitea's generic package store as the archive of record; to make it
importable, serve a copy from any host that sends
text/javascript + CORS. Since you run uhhm.no, that's a few lines of
Caddy:
cdn.uhhm.no {
root * /srv/cdn
file_server
header Access-Control-Allow-Origin *
header /buuh@* Cache-Control "public, max-age=31536000, immutable"
}
Drop each release in as buuh@8.0.0.js (a curl from the generic
package URL, or an extra scp step in the workflow), and every project
on earth can do:
<script type="importmap">
{ "imports": { "buuh": "https://cdn.uhhm.no/buuh@8.0.0.js" } }
</script>
<script type="module">
import { choo, html } from 'buuh'
</script>
That is the zero-build story with your own domain on it.
b. Self-hosted esm.sh. esm.sh is open source and can be pointed at a custom npm registry — run it against the Gitea endpoint and you get real CDN semantics (per-package URLs, versioning, bundling) for everything you publish. More moving parts; worth it only if you want per-package URLs rather than the one-file bundle.
c. Raw Gitea file URLs — don't. Gitea serves raw .js as
text/plain for safety, which module loading rejects. Fronting raw
URLs with a MIME-rewriting proxy works but is a hack with none of the
caching benefits of (a).
Version hygiene
- Workspace versions are currently
8.0.0-dev; set real versions before the first tag (npm version 8.0.0 --workspaces --no-git-tag-version). - The tag drives the generic-package version in the workflow, so keep tags and package.json versions in step.
bankaithe bin name survives; the package is@uhhm/bankaiso scope routing works.