mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-11-02 19:57:13 +00:00
* feat(studio): load GSAP from the CLI's bundled copy by default Studio preview now loads the GSAP, CustomEase and MotionPathPlugin scripts it adds from files the CLI ships and serves same-origin at /api/vendor/npm, instead of jsDelivr. HYPERFRAMES_GSAP_BASE_URL still wins when set, and a composition on another GSAP version gets its plugin from jsDelivr. Renders now honor HYPERFRAMES_GSAP_BASE_URL when they replace a missing local GSAP script, and the setting accepts plain http only for loopback hosts. Closes #6205 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * refactor(studio): keep comment share flat for the GSAP local root Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(cli): find the installed gsap with node resolution when run from source The Windows CI lane installs with the hoisted linker, so gsap is not under packages/core/node_modules there. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(producer): load a nested composition's missing GSAP from the mirror A sub-composition's missing local gsap/dist script was hoisted into the render unchanged, so HYPERFRAMES_GSAP_BASE_URL (and the jsDelivr fallback) only reached the entry document. Run the same rewrite on every sub-composition before it is compiled, resolving its path the way the inliner will hoist it. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
173 lines
7.2 KiB
Plaintext
173 lines
7.2 KiB
Plaintext
---
|
|
title: "@hyperframes/studio-server"
|
|
description: "Mount the Studio project and preview API in your own server."
|
|
---
|
|
|
|
`@hyperframes/studio-server` is the backend used by Studio. It serves projects
|
|
and previews, applies source mutations, creates thumbnails, and starts render
|
|
jobs.
|
|
|
|
Most users do not need it. The CLI wires the server and Studio together when
|
|
you run `npx hyperframes preview`. Use this package only when your own
|
|
application must host the Studio backend.
|
|
|
|
```bash
|
|
npm install @hyperframes/studio-server
|
|
```
|
|
|
|
## Mount the API
|
|
|
|
`createStudioApi()` returns a Hono application. The adapter is the boundary
|
|
between Studio and your project storage, bundler, linter, and renderer.
|
|
|
|
```ts
|
|
import type { Hono } from "hono";
|
|
import {
|
|
createStudioApi,
|
|
type StudioApiAdapter,
|
|
} from "@hyperframes/studio-server";
|
|
|
|
export function mountStudioApi(
|
|
app: Hono,
|
|
adapter: StudioApiAdapter,
|
|
) {
|
|
app.route("/api", createStudioApi(adapter));
|
|
}
|
|
```
|
|
|
|
When it is served from loopback (`localhost`, `127.0.0.1` or `[::1]`), Studio
|
|
sends its API requests without cookies, so they don't queue behind the
|
|
preview's media. On any other origin it sends them as usual, so remote and
|
|
proxied setups (Codespaces, tunnels, an access proxy) keep their cookies by
|
|
default. A loopback host that authenticates its mounted API with same-origin
|
|
cookies sets `VITE_STUDIO_API_SAME_ORIGIN_CREDENTIALS=true`, at build time or at
|
|
runtime in `window.__HF_STUDIO_ENV__`; it costs that host the connection
|
|
speedup.
|
|
Studio reads the flag once, when its modules load, so set
|
|
`window.__HF_STUDIO_ENV__` before loading Studio; the CLI injects it, but a host
|
|
that mounts the API itself must inject it too.
|
|
|
|
A `StudioApiAdapter` supplies:
|
|
|
|
- project listing and resolution;
|
|
- composition bundling and linting;
|
|
- render output storage and job startup;
|
|
- optional thumbnails, sessions, registry installation, and background removal.
|
|
|
|
Use the interface exported by your installed version as the exact contract. It
|
|
changes as Studio gains capabilities.
|
|
|
|
`bundle(projectDir, options)` must pass `options` through to `bundleToSingleHtml`,
|
|
spread over your own options. The preview sets `stampHfIds` there so each element
|
|
is served with the id its source file mints. If a host drops it, a composition
|
|
the bundler inlines can be served with ids that a later save does not mint.
|
|
|
|
```ts
|
|
bundle: (dir, options) => bundleToSingleHtml(dir, { runtime: "inline", ...options }),
|
|
```
|
|
|
|
## Where Studio loads GSAP from
|
|
|
|
Studio adds GSAP scripts to previews when a composition needs them: the GSAP
|
|
core and CustomEase for motion you edit in Studio, and MotionPathPlugin for
|
|
motion paths. It picks the source in this order:
|
|
|
|
1. `HYPERFRAMES_GSAP_BASE_URL`, when set. Studio uses only that mirror and
|
|
never retries through jsDelivr.
|
|
2. The host's bundled copy, when the host passes `gsapLocalRoot`. The
|
|
HyperFrames CLI ships GSAP `3.15.0` and serves it from
|
|
`/api/vendor/npm`, so `npx hyperframes preview` makes no jsDelivr request for
|
|
these scripts. The bundled copy holds one version: a composition that loads
|
|
another GSAP version, such as `gsap@3.14.2`, still gets the matching plugin
|
|
from jsDelivr.
|
|
3. jsDelivr (`https://cdn.jsdelivr.net/npm`), for hosts without a bundled copy.
|
|
|
|
A host embedding this package opts in by serving the files and naming the
|
|
root:
|
|
|
|
```ts
|
|
gsapLocalRoot: "/api/vendor/npm", // serves /api/vendor/npm/gsap@3.15.0/dist/gsap.min.js
|
|
```
|
|
|
|
`gsapLocalRoot` must be a path on the preview's own origin, such as
|
|
`/api/vendor/npm`, with no query or fragment.
|
|
|
|
### Use your own mirror
|
|
|
|
Set `HYPERFRAMES_GSAP_BASE_URL` before starting the preview server or creating
|
|
the Studio API:
|
|
|
|
```bash
|
|
HYPERFRAMES_GSAP_BASE_URL=http://127.0.0.1:8080/vendor/npm \
|
|
npx hyperframes preview ./my-video
|
|
```
|
|
|
|
The mirror is an HTTP server, not a folder: a file path is refused. Serve the
|
|
GSAP distribution files under that URL with this layout, using the versions
|
|
your compositions need:
|
|
|
|
```text
|
|
<mirror-root>/gsap@3.15.0/dist/gsap.min.js
|
|
<mirror-root>/gsap@3.15.0/dist/CustomEase.min.js
|
|
<mirror-root>/gsap@3.15.0/dist/MotionPathPlugin.min.js
|
|
```
|
|
|
|
Keep `gsap@<version>` in authored GSAP URLs so the server can infer which
|
|
plugin version to add. When it cannot infer a version, it uses the framework's
|
|
default, currently `3.15.0`.
|
|
|
|
The base must be an absolute URL without credentials, a query string, or a
|
|
fragment. Use HTTPS. Plain `http://` is accepted only for this machine:
|
|
`localhost`, `127.0.0.0/8`, and `::1`. Surrounding whitespace and trailing
|
|
slashes are removed. An invalid nonempty value stops API startup with a
|
|
configuration error.
|
|
|
|
The server reads this setting once at startup. Restart it after changing the
|
|
value. For a managed CLI preview, run `npx hyperframes preview ./my-video --stop`
|
|
before starting it again with the new setting. Cached preview HTML is keyed
|
|
by the GSAP source, so a different mirror takes effect after restart
|
|
without deleting the preview cache.
|
|
|
|
Renders read the same setting. When a composition points at a local
|
|
`gsap/dist/` script that does not exist, the render compiler loads that file
|
|
from the mirror instead of jsDelivr and inlines it, as it does for other
|
|
remote scripts. An invalid value fails that render with the same
|
|
configuration error. Renders do not use the CLI's bundled copy.
|
|
|
|
This setting changes only GSAP scripts HyperFrames adds. Your composition's
|
|
own script, font, image, and media URLs stay as authored, including a GSAP
|
|
`<script>` that points at jsDelivr; serve those locally too for an offline
|
|
project. When Studio writes GSAP into a composition file, for example when you
|
|
add the first animation to a file without one, it writes the jsDelivr URL so
|
|
the file still renders outside Studio. If the selected mirror is unavailable or lacks a requested file,
|
|
Studio does not retry that dependency through jsDelivr.
|
|
|
|
## Other entry points
|
|
|
|
| Import | Purpose |
|
|
| --- | --- |
|
|
| `@hyperframes/studio-server/source-mutation` | Apply guarded changes to composition source |
|
|
| `@hyperframes/studio-server/screenshot-clip` | Calculate element screenshot geometry |
|
|
| `@hyperframes/studio-server/safe-path` | Resolve paths inside a project and walk its files, without the server |
|
|
| `@hyperframes/studio-server/hf-ids` | Stamp stable element ids into a project's HTML, without the server |
|
|
| `@hyperframes/studio-server/history` | Open a project's undo history, without the server |
|
|
| `@hyperframes/studio-server/manual-edits-render-script` | Reapply Studio manual edits during render |
|
|
| `@hyperframes/studio-server/studio-motion-render-script` | Reapply Studio motion edits during render |
|
|
| `@hyperframes/studio-server/draft-markers` | Work with draft gesture markers |
|
|
| `@hyperframes/studio-server/finite-mutation` | Guard source mutations against non-finite values |
|
|
| `@hyperframes/studio-server/media-proxy-preview` | Support proxied media in preview |
|
|
|
|
`@hyperframes/core/studio-api` remains a deprecated compatibility re-export.
|
|
New integrations should import from `@hyperframes/studio-server`.
|
|
|
|
## Related topics
|
|
|
|
<CardGroup cols={2}>
|
|
<Card title="@hyperframes/studio" icon="palette" href="/packages/studio">
|
|
Embed lower-level Studio interface components.
|
|
</Card>
|
|
<Card title="Studio guide" icon="display" href="/studio">
|
|
Use the complete editor that ships with HyperFrames.
|
|
</Card>
|
|
</CardGroup>
|