mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-01 19:42:03 +00:00
docs: add package pages for parsers, lint, and studio-server (#1772)
New docs pages for the three packages extracted from core (#1755, #1756, #1757), wired into the Packages nav after @hyperframes/core. Each covers when-to-use, exports, and API with cross-links. Core's parser/lint sections now point at the dedicated packages and its Related Packages lists all three.
This commit is contained in:
@@ -323,6 +323,9 @@
|
||||
"group": "Packages",
|
||||
"pages": [
|
||||
"packages/core",
|
||||
"packages/parsers",
|
||||
"packages/lint",
|
||||
"packages/studio-server",
|
||||
"packages/sdk",
|
||||
"packages/engine",
|
||||
"packages/player",
|
||||
|
||||
+17
-3
@@ -177,6 +177,10 @@ const result = validateCompositionHtml(html);
|
||||
|
||||
### GSAP Script Parsing
|
||||
|
||||
<Info>
|
||||
The GSAP + HTML parsing layer now lives in its own standalone package, [`@hyperframes/parsers`](/packages/parsers). Core re-exports the API below for back-compat; import from `@hyperframes/parsers` directly in new code.
|
||||
</Info>
|
||||
|
||||
```typescript
|
||||
import {
|
||||
parseGsapScript,
|
||||
@@ -243,6 +247,10 @@ const styles = getStageStyles('portrait');
|
||||
|
||||
## Linter
|
||||
|
||||
<Info>
|
||||
The composition linter now lives in its own package, [`@hyperframes/lint`](/packages/lint) — install it directly to lint a project or HTML string from Node without the CLI. `@hyperframes/core/lint` remains a back-compat re-export.
|
||||
</Info>
|
||||
|
||||
The composition linter checks for structural issues that would cause rendering failures or unexpected behavior. You can run it from the CLI with `npx hyperframes lint`, or call it programmatically:
|
||||
|
||||
```typescript
|
||||
@@ -431,6 +439,15 @@ import type {
|
||||
## Related Packages
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="@hyperframes/parsers" icon="code" href="/packages/parsers">
|
||||
The standalone GSAP + HTML parsing layer extracted from core.
|
||||
</Card>
|
||||
<Card title="@hyperframes/lint" icon="circle-check" href="/packages/lint">
|
||||
The composition linter as a standalone library.
|
||||
</Card>
|
||||
<Card title="@hyperframes/studio-server" icon="server" href="/packages/studio-server">
|
||||
The mountable studio preview/editor backend.
|
||||
</Card>
|
||||
<Card title="CLI" icon="terminal" href="/packages/cli">
|
||||
The easiest way to create, preview, lint, and render compositions.
|
||||
</Card>
|
||||
@@ -440,7 +457,4 @@ import type {
|
||||
<Card title="Producer" icon="film" href="/packages/producer">
|
||||
Full rendering pipeline built on top of core and engine.
|
||||
</Card>
|
||||
<Card title="Studio" icon="palette" href="/packages/studio">
|
||||
Visual composition editor that embeds the core runtime for preview.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
---
|
||||
title: "@hyperframes/lint"
|
||||
description: "The composition linter as a standalone library — lint a directory or a single HTML file without the CLI."
|
||||
---
|
||||
|
||||
The lint package is the composition linter extracted from core into a dedicated, independently-installable package. It's the **single source of truth** for linting: both the CLI's `hyperframes lint` command and the render-time render-gate consume the same rule engine from here.
|
||||
|
||||
```bash
|
||||
npm install @hyperframes/lint
|
||||
```
|
||||
|
||||
## When to Use
|
||||
|
||||
<Tip>
|
||||
This package is the payoff of running validation **as a library** instead of shelling out to the CLI. A Node app (an agent harness, a CI step, an editor plugin) can `import { lintProject } from '@hyperframes/lint'` and lint a composition directory directly — no `npx hyperframes lint` subprocess, no stdout parsing.
|
||||
</Tip>
|
||||
|
||||
**Use `@hyperframes/lint` when you need to:**
|
||||
- Lint a composition project (an index + sub-compositions) from Node
|
||||
- Lint a single HTML string programmatically
|
||||
- Gate a render on lint findings (`shouldBlockRender`)
|
||||
- Surface lint findings in your own UI or CI annotations
|
||||
|
||||
<Info>
|
||||
`@hyperframes/core/lint` still resolves (via a back-compat re-export stub), so existing imports keep working. New code should import from `@hyperframes/lint` directly.
|
||||
</Info>
|
||||
|
||||
## Package Exports
|
||||
|
||||
The lint package has a single entry point:
|
||||
|
||||
```typescript
|
||||
import {
|
||||
lintHyperframeHtml,
|
||||
lintMediaUrls,
|
||||
lintProject,
|
||||
shouldBlockRender,
|
||||
} from '@hyperframes/lint';
|
||||
import type {
|
||||
HyperframeLintResult,
|
||||
HyperframeLintFinding,
|
||||
HyperframeLintSeverity, // "error" | "warning"
|
||||
HyperframeLinterOptions,
|
||||
ProjectLintResult,
|
||||
} from '@hyperframes/lint';
|
||||
```
|
||||
|
||||
## Linting a Single Composition
|
||||
|
||||
```typescript
|
||||
import { lintHyperframeHtml, lintMediaUrls } from '@hyperframes/lint';
|
||||
|
||||
const result = lintHyperframeHtml(html, { filePath: 'index.html' });
|
||||
// result.ok, result.errorCount, result.warningCount, result.findings
|
||||
|
||||
for (const finding of result.findings) {
|
||||
console.log(finding.severity, finding.code, finding.message);
|
||||
// finding.file, finding.selector, finding.elementId, finding.fixHint, finding.snippet
|
||||
}
|
||||
|
||||
// Additional media URL validation
|
||||
const mediaFindings = lintMediaUrls(result.findings);
|
||||
```
|
||||
|
||||
## Linting a Project
|
||||
|
||||
`lintProject` walks a composition directory — the index plus any sub-compositions — and returns aggregated findings. It takes a **directory path string**, so it's callable from any Node context with nothing but a path:
|
||||
|
||||
```typescript
|
||||
import { lintProject, shouldBlockRender } from '@hyperframes/lint';
|
||||
import type { ProjectLintResult } from '@hyperframes/lint';
|
||||
|
||||
const result: ProjectLintResult = await lintProject('./my-composition');
|
||||
// result.totalErrors, result.totalWarnings, result.results[]
|
||||
// each result entry: { file, result: HyperframeLintResult }
|
||||
|
||||
if (shouldBlockRender(result)) {
|
||||
throw new Error(`Lint found ${result.totalErrors} blocking error(s)`);
|
||||
}
|
||||
```
|
||||
|
||||
## What the Linter Catches
|
||||
|
||||
Detected issues include:
|
||||
|
||||
- Missing timeline registration (`window.__timelines`)
|
||||
- Unmuted video elements (causes autoplay failures)
|
||||
- Missing `class="clip"` on timed visible elements
|
||||
- Deprecated attribute names
|
||||
- Missing composition dimensions (`data-width`, `data-height`)
|
||||
- Invalid `data-start` references to nonexistent clip IDs
|
||||
|
||||
<Info>
|
||||
For a full list of what the linter catches and how to fix each issue, see [Common Mistakes](/guides/common-mistakes) and [Troubleshooting](/guides/troubleshooting).
|
||||
</Info>
|
||||
|
||||
## Related Packages
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="@hyperframes/parsers" icon="code" href="/packages/parsers">
|
||||
The HTML + GSAP parsing layer the linter builds on.
|
||||
</Card>
|
||||
<Card title="@hyperframes/core" icon="cube" href="/packages/core">
|
||||
Types and runtime; re-exports the linter for back-compat.
|
||||
</Card>
|
||||
<Card title="CLI" icon="terminal" href="/packages/cli">
|
||||
`npx hyperframes lint` wraps this package.
|
||||
</Card>
|
||||
<Card title="Studio" icon="palette" href="/packages/studio">
|
||||
Surfaces lint findings in the editor.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
@@ -0,0 +1,157 @@
|
||||
---
|
||||
title: "@hyperframes/parsers"
|
||||
description: "The GSAP + HTML parser/writer suite — standalone, zero @hyperframes/* dependencies."
|
||||
---
|
||||
|
||||
The parsers package is the standalone foundation extracted from core. It owns the GSAP animation parser/writer (recast **and** acorn implementations), the HTML composition parser, hf-id stamping, and spring-ease generation. It has **no `@hyperframes/*` dependencies**, so it's the base every other package builds on.
|
||||
|
||||
```bash
|
||||
npm install @hyperframes/parsers
|
||||
```
|
||||
|
||||
## When to Use
|
||||
|
||||
<Tip>
|
||||
**Most users do not need to install `@hyperframes/parsers` directly.** [`@hyperframes/core`](/packages/core) re-exports the parser API it needs, and the [CLI](/packages/cli) / [studio](/packages/studio) depend on it transitively. Reach for it directly only when you want the parsing layer **without** pulling in the rest of core.
|
||||
</Tip>
|
||||
|
||||
**Use `@hyperframes/parsers` when you need to:**
|
||||
- Parse HTML compositions into structured TypeScript objects
|
||||
- Parse, edit, and re-serialize GSAP timeline scripts (AST round-trip)
|
||||
- Stamp deterministic `hf-id` attributes onto a document
|
||||
- Build tooling that touches the parsing layer but doesn't need core's runtime, compiler, or generators
|
||||
|
||||
## Package Exports
|
||||
|
||||
| Import | Description |
|
||||
|--------|-------------|
|
||||
| `@hyperframes/parsers` | HTML parser, GSAP serialize/validate helpers, hf-ids, shared types |
|
||||
| `@hyperframes/parsers/gsap-parser-acorn` | Acorn-based GSAP parser (browser-safe, read path) |
|
||||
| `@hyperframes/parsers/gsap-writer-acorn` | Acorn-based GSAP writer (mutation helpers) |
|
||||
| `@hyperframes/parsers/gsap-parser-recast` | Recast-based GSAP parser/writer (legacy implementation) |
|
||||
| `@hyperframes/parsers/gsap-constants` | `SUPPORTED_PROPS`, `SUPPORTED_EASES`, property groups |
|
||||
| `@hyperframes/parsers/spring-ease` | Spring-ease curve generation |
|
||||
| `@hyperframes/parsers/hf-ids` | Deterministic element id stamping |
|
||||
|
||||
<Info>
|
||||
The package ships subpath entries so consumers tree-shake to what they use — importing `@hyperframes/parsers/hf-ids` (a couple KB) does **not** pull in the GSAP AST machinery (recast/babel/acorn).
|
||||
</Info>
|
||||
|
||||
## HTML Parsing
|
||||
|
||||
Round-trip between HTML and structured data:
|
||||
|
||||
```typescript
|
||||
import {
|
||||
parseHtml,
|
||||
extractCompositionMetadata,
|
||||
validateCompositionHtml,
|
||||
} from '@hyperframes/parsers';
|
||||
import type { ParsedHtml, CompositionMetadata } from '@hyperframes/parsers';
|
||||
|
||||
// Parse HTML into structured data
|
||||
const parsed: ParsedHtml = parseHtml(htmlString);
|
||||
// parsed.elements, parsed.gsapScript, parsed.styles, parsed.resolution, parsed.keyframes
|
||||
|
||||
// Extract composition metadata (id, duration, dimensions, variables)
|
||||
const meta: CompositionMetadata = extractCompositionMetadata(htmlString);
|
||||
|
||||
// Validate HTML structure
|
||||
const result = validateCompositionHtml(htmlString);
|
||||
// result.valid, result.errors
|
||||
```
|
||||
|
||||
### Modifying HTML
|
||||
|
||||
```typescript
|
||||
import {
|
||||
updateElementInHtml,
|
||||
addElementToHtml,
|
||||
removeElementFromHtml,
|
||||
} from '@hyperframes/parsers';
|
||||
|
||||
const updated = updateElementInHtml(html, 'el-1', { start: 5 });
|
||||
const added = addElementToHtml(html, newElement);
|
||||
const cleaned = removeElementFromHtml(html, 'el-1');
|
||||
```
|
||||
|
||||
## GSAP Script Parsing
|
||||
|
||||
The acorn parser/writer is the primary path (browser-safe). Parse a timeline script, mutate it, and serialize it back without losing surrounding code:
|
||||
|
||||
```typescript
|
||||
import { parseGsapScriptAcorn, extractGsapLabels } from '@hyperframes/parsers/gsap-parser-acorn';
|
||||
import {
|
||||
updateAnimationInScript,
|
||||
addAnimationToScript,
|
||||
removeAnimationFromScript,
|
||||
updateKeyframeInScript,
|
||||
addKeyframeToScript,
|
||||
shiftPositionsInScript,
|
||||
scalePositionsInScript,
|
||||
} from '@hyperframes/parsers/gsap-writer-acorn';
|
||||
import type { GsapAnimation, GsapMethod, ParsedGsap } from '@hyperframes/parsers';
|
||||
|
||||
const parsed: ParsedGsap = parseGsapScriptAcorn(scriptContent);
|
||||
// parsed.animations, parsed.timelineVar, parsed.preamble, parsed.postamble
|
||||
|
||||
// Mutation helpers operate on the script text and preserve unrelated code
|
||||
const next = updateAnimationInScript(scriptContent, animationId, { duration: 2 });
|
||||
```
|
||||
|
||||
High-level serialize / validate / keyframe-conversion helpers are on the main entry:
|
||||
|
||||
```typescript
|
||||
import {
|
||||
serializeGsapAnimations,
|
||||
getAnimationsForElementId,
|
||||
validateCompositionGsap,
|
||||
keyframesToGsapAnimations,
|
||||
gsapAnimationsToKeyframes,
|
||||
} from '@hyperframes/parsers';
|
||||
```
|
||||
|
||||
### GSAP Constants
|
||||
|
||||
```typescript
|
||||
import {
|
||||
SUPPORTED_PROPS, // animatable properties
|
||||
SUPPORTED_EASES, // available easing functions
|
||||
PROPERTY_GROUPS,
|
||||
} from '@hyperframes/parsers/gsap-constants';
|
||||
import type { PropertyGroupName } from '@hyperframes/parsers/gsap-constants';
|
||||
```
|
||||
|
||||
## hf-ids
|
||||
|
||||
Deterministic element identity for stable diffing and editing:
|
||||
|
||||
```typescript
|
||||
import { ensureHfIds, mintHfId } from '@hyperframes/parsers/hf-ids';
|
||||
|
||||
// Stamp hf-id attributes onto every editable element in a document
|
||||
const withIds = ensureHfIds(htmlString);
|
||||
```
|
||||
|
||||
## Spring Ease
|
||||
|
||||
```typescript
|
||||
import { generateSpringEaseData, SPRING_PRESETS } from '@hyperframes/parsers/spring-ease';
|
||||
```
|
||||
|
||||
## Related Packages
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="@hyperframes/core" icon="cube" href="/packages/core">
|
||||
Types, generators, runtime, and compiler — re-exports the parser API it needs.
|
||||
</Card>
|
||||
<Card title="@hyperframes/lint" icon="circle-check" href="/packages/lint">
|
||||
The composition linter, built on the parsers.
|
||||
</Card>
|
||||
<Card title="@hyperframes/studio-server" icon="server" href="/packages/studio-server">
|
||||
The studio preview server, built on the parsers.
|
||||
</Card>
|
||||
<Card title="CLI" icon="terminal" href="/packages/cli">
|
||||
Create, preview, lint, and render compositions.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
@@ -0,0 +1,96 @@
|
||||
---
|
||||
title: "@hyperframes/studio-server"
|
||||
description: "The studio preview/editor backend — a mountable Hono API, extracted from core."
|
||||
---
|
||||
|
||||
The studio-server package is the HTTP backend that powers studio preview and editing — project routes, file serving, preview bundling, thumbnails, and source-mutation helpers. It was extracted from `@hyperframes/core/studio-api` into a dedicated package so an embedder can mount the studio backend **without** depending on core's full surface, and so core no longer ships a web server it doesn't need at render time.
|
||||
|
||||
```bash
|
||||
npm install @hyperframes/studio-server
|
||||
```
|
||||
|
||||
## When to Use
|
||||
|
||||
<Tip>
|
||||
**Most users do not need this package directly.** The [CLI](/packages/cli) (`npx hyperframes preview`) and [studio](/packages/studio) wire it up for you. Reach for it when you're **embedding** the studio backend into your own server.
|
||||
</Tip>
|
||||
|
||||
**Use `@hyperframes/studio-server` when you need to:**
|
||||
- Mount the studio preview/editing API into an existing Node/Hono server
|
||||
- Serve project files and bundled preview HTML to a custom frontend
|
||||
- Drive source mutations (manual edits, draft markers) from your own tooling
|
||||
|
||||
<Info>
|
||||
`@hyperframes/core/studio-api` still resolves (via a back-compat re-export stub), so existing imports keep working. New code should import from `@hyperframes/studio-server` directly.
|
||||
</Info>
|
||||
|
||||
## Package Exports
|
||||
|
||||
| Import | Description |
|
||||
|--------|-------------|
|
||||
| `@hyperframes/studio-server` | `createStudioApi`, helpers, types |
|
||||
| `@hyperframes/studio-server/screenshot-clip` | Element screenshot-clip geometry |
|
||||
| `@hyperframes/studio-server/manual-edits-render-script` | Manual-edits render body script |
|
||||
| `@hyperframes/studio-server/studio-motion-render-script` | Studio motion render body script |
|
||||
| `@hyperframes/studio-server/draft-markers` | Draft gesture-marker attributes |
|
||||
| `@hyperframes/studio-server/finite-mutation` | Finite-mutation safety checks |
|
||||
|
||||
## Mounting the API
|
||||
|
||||
`createStudioApi` returns a [Hono](https://hono.dev) app you can mount into any server. You supply a `StudioApiAdapter` that tells the API how to resolve projects, bundle preview HTML, and lint:
|
||||
|
||||
```typescript
|
||||
import { createStudioApi } from '@hyperframes/studio-server';
|
||||
import type { StudioApiAdapter, ResolvedProject } from '@hyperframes/studio-server';
|
||||
|
||||
const adapter: StudioApiAdapter = {
|
||||
listProjects: () => projects,
|
||||
resolveProject: (id) => projectsById.get(id) ?? null,
|
||||
bundle: async (projectDir) => bundleToSingleHtml(projectDir),
|
||||
lint: (html, opts) => lintHyperframeHtml(html, opts),
|
||||
runtimeUrl: '/hyperframe-runtime.js',
|
||||
};
|
||||
|
||||
const api = createStudioApi(adapter); // → Hono app
|
||||
|
||||
// Mount under /api in your own Hono server
|
||||
app.route('/api', api);
|
||||
```
|
||||
|
||||
The adapter is the seam between the framework-agnostic route logic and your storage / bundling / lint implementation — the [CLI](/packages/cli) supplies a filesystem-backed adapter, but you can back it with anything.
|
||||
|
||||
## Helpers
|
||||
|
||||
```typescript
|
||||
import {
|
||||
createProjectSignature, // cache key for a project's files
|
||||
isSafePath, // path-traversal guard
|
||||
walkDir,
|
||||
getMimeType,
|
||||
buildSubCompositionHtml,
|
||||
getElementScreenshotClip,
|
||||
} from '@hyperframes/studio-server';
|
||||
import type {
|
||||
ResolvedProject,
|
||||
RenderJobState,
|
||||
LintResult,
|
||||
ScreenshotClip,
|
||||
} from '@hyperframes/studio-server';
|
||||
```
|
||||
|
||||
## Related Packages
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Studio" icon="palette" href="/packages/studio">
|
||||
The browser editor UI this server backs.
|
||||
</Card>
|
||||
<Card title="@hyperframes/parsers" icon="code" href="/packages/parsers">
|
||||
The HTML + GSAP parsing layer it builds on.
|
||||
</Card>
|
||||
<Card title="@hyperframes/core" icon="cube" href="/packages/core">
|
||||
Types and runtime; re-exports the studio API for back-compat.
|
||||
</Card>
|
||||
<Card title="CLI" icon="terminal" href="/packages/cli">
|
||||
`npx hyperframes preview` wires this server up for you.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
Reference in New Issue
Block a user