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:
commit
0946660c1c
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue