Merge pull request #184 from storytold/docs/164-165-169-174-180-web-packaging

Docs and packaging: web hosting guide matches the build; Linux packages describe a compositor (#164, #165, #169, #174, #180)
This commit is contained in:
BFlat 2026-10-07 13:58:59 +07:00 committed by GitHub
commit 0946660c1c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 45 additions and 31 deletions

View File

@ -31,9 +31,11 @@ isolated like a production deployment should be. Any static server works
(`python3 -m http.server -d target/web/dist 8765`); it must serve `.wasm` as `application/wasm`.
Service workers need a secure context: `https://`, or `http://localhost` / `127.0.0.1`.
The release `.wasm` is about 38 MB before `wasm-opt` (code: the effects, codecs, the expression
engine and the UI; data, mostly the bundled fonts; function names for readable panics). Served
compressed it is a fraction of that, and the service worker caches it after the first visit.
The release `.wasm` is about 58 MB before `wasm-opt` (v0.3.1; code: the effects, codecs, the
expression engine and the UI; data, mostly the bundled fonts; function names for readable
panics). Served compressed it is about 17 MB with gzip or 10 MB with Brotli, and the service
worker caches it after the first visit. Its name doesn't change between releases, so hosts
revalidate it rather than caching it for long (`packaging/web/README.md`).
On other targets the web crate holds only its portable storage model (`store.rs`, unit-tested by
`cargo test --workspace`); `cargo xtask wasm` (part of `cargo xtask ci`) checks the whole crate,

View File

@ -12,7 +12,9 @@
</developer>
<description>
<p>
EffectCraft is a motion graphics editor. Motion graphics and visual effects compositor
EffectCraft is an open-source motion graphics and visual effects compositor: layers with
keyframes and a graph editor, masks and shapes, text animators, expressions, 3D cameras and
lights, over 300 effects and a render queue, with GPU compositing.
</p>
</description>
<launchable type="desktop-id">ai.storyteller.effectcraft.desktop</launchable>

View File

@ -17,10 +17,11 @@ vendor: Learning Machines LLC
homepage: https://getartcraft.com/apps/effectcraft
license: MIT OR Apache-2.0
description: |-
Open-source, native image editor that works the way Photoshop users expect.
Layers, masks, adjustment layers, layer styles, type and brushes; opens and
saves layered PSD/PSB files; 8/16/32-bit documents; GPU compositing (wgpu).
Includes effectcraft-cli, a headless converter and command runner.
Open-source motion graphics and visual effects compositor.
Layers with keyframes and a graph editor, masks and shapes, text animators,
expressions, 3D cameras and lights, over 300 effects and a render queue
(H.264, HEVC, AV1, ProRes, WebM, image sequences); GPU compositing (wgpu).
Includes effectcraft-cli, a headless renderer, command runner and MCP server.
# The binaries link only glibc and libgcc_s directly. Windowing (X11/Wayland, xkbcommon) and the
# GPU (Vulkan, EGL/GL) are loaded at runtime, so they are dependencies/recommendations here

View File

@ -7,10 +7,8 @@ AddType text/javascript .js
</IfModule>
<IfModule mod_headers.c>
<FilesMatch "\.(wasm|js)$">
Header set Cache-Control "public, max-age=31536000, immutable"
</FilesMatch>
<FilesMatch "^index\.html$">
# The file names don't change between releases: revalidate them (HOSTING.md).
<FilesMatch "(\.(wasm|js)|^index\.html)$">
Header set Cache-Control "no-cache"
</FilesMatch>
</IfModule>

View File

@ -6,29 +6,38 @@ static site in `effectcraft-web-<version>/`:
| File | What it is |
|---|---|
| `index.html` | The page. It loads everything through relative URLs. |
| `effectcraft-web-<hash>.js` | wasm-bindgen glue (generated, ES module) |
| `effectcraft-web-<hash>_bg.wasm` | The app, about 13 MB, or 5 MB with compression |
| `effectcraft_web.js` | wasm-bindgen glue (generated, ES module) |
| `effectcraft_web_bg.wasm` | The app: about 58 MB, about 17 MB with gzip and 10 MB with Brotli (v0.3.1) |
| `snippets/…/js/host.js` | Browser glue (storage, audio, workers) |
| `worker.js`, `audio-worklet.js` | Render and frame workers, and audio playback |
| `sw.js`, `manifest.webmanifest`, icons | Offline install: the service worker and the app manifest |
| `_headers`, `.htaccess` | Sample header rules for Netlify/Cloudflare Pages and Apache |
There is no server-side code. Upload the folder's contents anywhere that serves static files.
## Any path works
All URLs in `index.html` are relative (`public_url = "./"` in `apps/effectcraft-web/Trunk.toml`),
so the site works at a domain root (`https://example.com/`), under a prefix
(`https://example.com/tools/effectcraft/`) and from a CDN bucket. The asset names carry a content
hash, so they can be cached forever. Only `index.html` needs revalidation.
All URLs in `index.html` are relative: the page is written that way
(`apps/effectcraft-web/web/index.html`), and `package.sh` refuses a build with root-absolute
URLs. So the site works at a domain root (`https://example.com/`), under a prefix
(`https://example.com/tools/effectcraft/`) and from a CDN bucket.
The file names are the same in every release (`effectcraft_web_bg.wasm` and so on), so browsers
must revalidate them: a long-lived cache would keep returning visitors on the old version after
you upgrade in place. Revalidation is cheap (an unchanged file answers `304 Not Modified`), and
the service worker keeps the app for offline use after the first visit. To cache the files for
longer, serve each release from its own versioned path (`/effectcraft/0.4.0/`).
## Required server settings
- **MIME type:** serve `.wasm` as `application/wasm`. Browsers refuse to stream-compile it under
any other type, and the app then loads slowly or not at all. Serve `.js` as `text/javascript`.
Most hosts already do both. For nginx, check that `mime.types` has `application/wasm wasm;`.
- **Compression:** turn on gzip or Brotli for `.wasm`, `.js` and `.html`. That takes the
download from about 13 MB to about 5 MB. You can also precompress (`brotli -k *.wasm`) and let
the server send `Content-Encoding: br`.
- **Caching:** `Cache-Control: public, max-age=31536000, immutable` on the hashed `.wasm` and
`.js` files, and `no-cache` on `index.html`.
- **Compression:** turn on gzip or Brotli for `.wasm`, `.js` and `.html`. For v0.3.1 that takes
the download from about 58 MB to about 17 MB (gzip) or 10 MB (Brotli). You can also
precompress (`brotli -k *.wasm`) and let the server send `Content-Encoding: br`.
- **Caching:** `Cache-Control: no-cache` (revalidate) on `index.html`, `sw.js` and the `.wasm`
and `.js` files, since their names don't change between releases (see above).
- **HTTPS:** WebGPU (and the clipboard) only work in a secure context, which means `https://`
or `http://localhost`. Over plain HTTP elsewhere, the app falls back to WebGL2.
- **No special isolation headers:** EffectCraft doesn't use `SharedArrayBuffer`, so it doesn't
@ -43,8 +52,7 @@ location /effectcraft/ {
types { application/wasm wasm; text/javascript js; text/html html; }
gzip on;
gzip_types application/wasm text/javascript text/html;
location ~* \.(wasm|js)$ { add_header Cache-Control "public, max-age=31536000, immutable"; }
location ~* index\.html$ { add_header Cache-Control "no-cache"; }
location ~* (\.(wasm|js)|index\.html)$ { add_header Cache-Control "no-cache"; }
}
```
@ -55,7 +63,7 @@ Local test: `python3 -m http.server 8765` inside the folder, then open http://lo
```html
<iframe
src="https://example.com/effectcraft/"
title="EffectCraft image editor"
title="EffectCraft"
style="width: 100%; height: 720px; border: 0;"
allow="fullscreen; clipboard-read; clipboard-write"
allowfullscreen>
@ -64,9 +72,11 @@ Local test: `python3 -m http.server 8765` inside the folder, then open http://lo
- The app fills the iframe and follows its size, so size the iframe and not the app.
- Keyboard shortcuts go to the iframe after the user clicks into it, as with any embedded app.
- **Cross-origin embeds** work. Preferences are kept in the iframe's `localStorage`. Browsers
that partition or block third-party storage may forget them between visits, and the app
then starts with defaults.
- **Cross-origin embeds** work. Preferences, projects and imported media are kept in the
iframe origin's browser storage: the Origin Private File System, else IndexedDB, else memory
only (`effectcraft.info().storage.backend` says which; see `docs/web.md` › Persistence).
Browsers that partition or block third-party storage may forget them between visits, and the
app then starts with defaults.
- **Sandboxed iframes** need at least
`sandbox="allow-scripts allow-same-origin allow-downloads allow-popups"`. Without
`allow-same-origin` there's no storage. Without `allow-downloads`, Save and Export (browser

View File

@ -2,12 +2,13 @@
/*
X-Content-Type-Options: nosniff
# The file names don't change between releases: revalidate them (HOSTING.md › Any path works).
/*.wasm
Content-Type: application/wasm
Cache-Control: public, max-age=31536000, immutable
Cache-Control: no-cache
/*.js
Cache-Control: public, max-age=31536000, immutable
Cache-Control: no-cache
/index.html
Cache-Control: no-cache