Bundles a stretch of in-progress work across the SPA tools so the
tree returns to a coherent shippable state ahead of cutting a new
zddc-server stable image:
- landing: substantial rework of the project picker (sortable/filterable
table, presets refactor, ?projects= filter, ?v= channel propagation,
loading/error states)
- archive: presets cleanup, source.js refactor, filtering/url-state
alignment with the landing page
- mdedit: file-system module split, resizer, file-tree improvements,
base/toc styling tweaks
- transmittal/classifier: small template touch-ups for shared chrome
- shared: build-lib.sh helpers, new favicon.svg
- bootstrap, build.sh: pick up the channel-aware install/track zip
generation
- tests: new landing.spec.js, expanded archive/mdedit/build-label specs
- docs: CLAUDE.md picks up the zddc-server section and freshens the
alpha-build exception note
- regenerated artifacts: install.zip, track-{alpha,beta,stable}.zip,
*_alpha.html — these are produced by `sh build.sh` and per project
convention are committed alongside the source changes
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
||
|---|---|---|
| .. | ||
| level1.html.tmpl | ||
| level2.html.tmpl | ||
| README.md | ||
Deployment bootstrap
ZDDC tools (archive, transmittal, classifier, mdedit, landing) are single-file HTML bundles. The bootstrap pattern lets you install once on a deployment and update by editing a few lines, without re-uploading multi-megabyte HTML files.
The two-level model
A typical zddc-server deployment looks like this:
<ZDDC_ROOT>/
index.html # landing tool (or bootstrap)
archive.html # archive tool (or bootstrap; site-wide channel switch lives here)
transmittal.html
classifier.html
mdedit.html
<project-A>/
archive.html # level-1 bootstrap → fetches ../archive.html
transmittal.html
classifier.html
mdedit.html
<project files…>
<project-B>/
archive.html # level-1 bootstrap (or pinned to a specific version)
…
- Level-1 stubs at
<project>/<tool>.htmlalways fetch the same-origin../<tool>.html. They never touchzddc.varasys.io. Install them once; they don't need to change. - At deployment root (
<ZDDC_ROOT>/<tool>.html), put either:- the actual built tool HTML — fully self-contained install, no external dependencies; or
- a level-2 bootstrap — fetches a specific channel or pinned version from
https://zddc.varasys.io/releases/<tool>_<channel|v…>.html.
The site administrator switches the whole site to a channel by replacing
the file at <ZDDC_ROOT>/<tool>.html with the matching level-2 stub from
track-<channel>.zip. A single project can override one tool by editing
just <project-X>/<tool>.html (replace the relative upstream URL with an
absolute zddc.varasys.io URL).
Why two levels
The level-1 stubs let projects share a single source of truth for "which build of the archive tool runs here." Switching channels is one file change at the root; pinning a single project is one file change in that directory.
document.write() chains across both levels: level-1 fetches and writes,
the new document's level-2 script runs and writes again, the third write
is the actual tool. Origin stays at the deployment domain throughout, so
File System Access API, crypto.subtle, and localStorage all work and
preferences stay scoped to the deployment.
Pinning options
There are two ways to choose a version: edit the stub for a permanent
pin, or pass a ?v= URL parameter for a per-request override.
1. Permanent pin (edit the stub)
Each stub has one fallback/upstream constant. Edit it once and the
choice sticks for everyone using that file.
| URL | Behavior |
|---|---|
https://zddc.varasys.io/releases/<tool>_stable.html |
current stable; auto-updates within stable |
https://zddc.varasys.io/releases/<tool>_beta.html |
latest beta build (mutable) |
https://zddc.varasys.io/releases/<tool>_alpha.html |
latest alpha build (mutable) |
https://zddc.varasys.io/releases/<tool>_v1.2.3.html |
pinned to exact stable version |
2. Per-request ?v= parameter
Both stub levels honor a ?v= URL parameter. The parameter survives the
document.write() chain, so it flows through level-1 → level-2 →
upstream automatically.
| URL parameter | Behavior |
|---|---|
?v=0.0.4 (or ?v=v0.0.4) |
tries <tool>_v0.0.4.html locally, then upstream |
?v=alpha |
switches to alpha channel |
?v=beta |
switches to beta channel |
?v=latest |
latest stable |
| (omitted) | the default baked into the stub |
When level-1 has ?v=…, it tries ../<tool>_<suffix>.html first (useful
when the admin has staged specific versions locally) and falls back to
../<tool>.html if 404 — which then forwards the parameter via level-2
if one is installed. So the same URL works whether the version is
staged locally, served by a level-2 stub, or both.
Stable releases are immutable. Alpha and beta channel files are overwritten in place each time their channel is rebuilt; expect them to change without notice. The build label rendered on the tool page tells you what you are running (date + commit SHA for alpha/beta, version number for stable).
Auditing what's installed
Every stub contains a fallback (level-1) or upstream (level-2)
constant. To see what each tool / project on the deployment points at:
grep -rn "fallback\|upstream" <ZDDC_ROOT>
CORS prerequisite (level-2 only)
A level-2 fetch is cross-origin (deployment → zddc.varasys.io). The
upstream must serve Access-Control-Allow-Origin: * (or a list including
your deployment origin) on the released HTML files. Verify with:
curl -I https://zddc.varasys.io/releases/archive_stable.html | grep -i access-control
Level-1 fetches are same-origin so no CORS is involved.
Templates
level1.html.tmpl and level2.html.tmpl are the source of truth. The
project's top-level build.sh substitutes {{TOOL}}, {{TOOL_TITLE}},
and {{CHANNEL}} to produce the per-tool stubs that ship in
install.zip and track-<channel>.zip.