@hyperframes/studio-server 0.7.60 → 0.7.61

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/dist/chunk-4ETS2LXI.js +192 -0
  2. package/dist/chunk-4ETS2LXI.js.map +1 -0
  3. package/dist/chunk-6XMC64FJ.js +584 -0
  4. package/dist/chunk-6XMC64FJ.js.map +1 -0
  5. package/dist/chunk-LVXVG4V6.js +282 -0
  6. package/dist/chunk-LVXVG4V6.js.map +1 -0
  7. package/dist/chunk-W2SBTCO2.js +32 -0
  8. package/dist/chunk-W2SBTCO2.js.map +1 -0
  9. package/dist/chunk-X62ASOGO.js +30 -0
  10. package/dist/chunk-X62ASOGO.js.map +1 -0
  11. package/dist/chunk-XVQX2JHE.js +422 -0
  12. package/dist/chunk-XVQX2JHE.js.map +1 -0
  13. package/dist/chunk-YBR7MXIO.js +459 -0
  14. package/dist/chunk-YBR7MXIO.js.map +1 -0
  15. package/dist/chunk-ZUW4PULZ.js +66 -0
  16. package/dist/chunk-ZUW4PULZ.js.map +1 -0
  17. package/dist/helpers/finiteMutation.js +4 -24
  18. package/dist/helpers/finiteMutation.js.map +1 -1
  19. package/dist/helpers/manualEditsRenderScript.js +5 -577
  20. package/dist/helpers/manualEditsRenderScript.js.map +1 -1
  21. package/dist/helpers/mediaCodecMap.d.ts +100 -0
  22. package/dist/helpers/mediaCodecMap.js +25 -0
  23. package/dist/helpers/mediaCodecMap.js.map +1 -0
  24. package/dist/helpers/mediaProxyPreview.d.ts +4 -0
  25. package/dist/helpers/mediaProxyPreview.js +17 -0
  26. package/dist/helpers/mediaProxyPreview.js.map +1 -0
  27. package/dist/helpers/proxyTranscoder.d.ts +61 -0
  28. package/dist/helpers/proxyTranscoder.js +30 -0
  29. package/dist/helpers/proxyTranscoder.js.map +1 -0
  30. package/dist/helpers/screenshotClip.js +3 -22
  31. package/dist/helpers/screenshotClip.js.map +1 -1
  32. package/dist/helpers/sourceMutation.js +9 -419
  33. package/dist/helpers/sourceMutation.js.map +1 -1
  34. package/dist/helpers/studioMotionRenderScript.js +4 -186
  35. package/dist/helpers/studioMotionRenderScript.js.map +1 -1
  36. package/dist/index.d.ts +6 -202
  37. package/dist/index.js +172 -1373
  38. package/dist/index.js.map +1 -1
  39. package/dist/mediaProxyPreview-CeshDUjE.d.ts +259 -0
  40. package/package.json +15 -3
@@ -0,0 +1,259 @@
1
+ import * as _hyperframes_core from '@hyperframes/core';
2
+ import { RegistryItem } from '@hyperframes/core';
3
+ import { CanvasResolution } from '@hyperframes/parsers';
4
+ import { MediaCodecProbeCache, HtmlSourceLike } from './helpers/mediaCodecMap.js';
5
+
6
+ /** Resolved info about a single project. */
7
+ interface ResolvedProject {
8
+ id: string;
9
+ dir: string;
10
+ title?: string;
11
+ sessionId?: string;
12
+ }
13
+ /** Observable render job state, polled by the SSE progress handler. */
14
+ interface RenderJobState {
15
+ id: string;
16
+ status: "rendering" | "complete" | "failed" | "cancelled";
17
+ progress: number;
18
+ stage?: string;
19
+ outputPath: string;
20
+ error?: string;
21
+ /**
22
+ * Optional abort hook set by the adapter. The cancel route calls this to
23
+ * stop an in-flight render; adapters that can't abort may omit it (the
24
+ * route still marks the job cancelled so the SSE stream terminates).
25
+ */
26
+ cancel?: () => void;
27
+ }
28
+ interface MediaProcessingJobState {
29
+ id: string;
30
+ status: "processing" | "complete" | "failed";
31
+ progress: number;
32
+ stage?: string;
33
+ inputAssetPath: string;
34
+ outputAssetPath: string;
35
+ outputPath: string;
36
+ backgroundOutputAssetPath?: string;
37
+ backgroundOutputPath?: string;
38
+ error?: string;
39
+ provider?: string;
40
+ framesProcessed?: number;
41
+ durationSeconds?: number;
42
+ avgMsPerFrame?: number;
43
+ }
44
+ /** Lint result from the core linter. */
45
+ interface LintResult {
46
+ findings: Array<{
47
+ severity: string;
48
+ message: string;
49
+ file?: string;
50
+ fixHint?: string;
51
+ }>;
52
+ }
53
+ interface StudioSelectionTextField {
54
+ key: string;
55
+ label: string;
56
+ value: string;
57
+ tagName: string;
58
+ source: "self" | "child" | "text-node";
59
+ }
60
+ interface StudioSelectionSnapshot {
61
+ schemaVersion: 1;
62
+ projectId: string;
63
+ compositionPath: string;
64
+ sourceFile: string;
65
+ currentTime: number;
66
+ target: {
67
+ id?: string | null;
68
+ hfId?: string;
69
+ selector?: string;
70
+ selectorIndex?: number;
71
+ };
72
+ label: string;
73
+ tagName: string;
74
+ boundingBox: {
75
+ x: number;
76
+ y: number;
77
+ width: number;
78
+ height: number;
79
+ };
80
+ textContent: string | null;
81
+ dataAttributes: Record<string, string>;
82
+ inlineStyles: Record<string, string>;
83
+ computedStyles: Record<string, string>;
84
+ textFields: StudioSelectionTextField[];
85
+ capabilities: Record<string, boolean | string | undefined>;
86
+ thumbnailUrl: string;
87
+ }
88
+ interface StudioSelectionResponse {
89
+ selection: StudioSelectionSnapshot | null;
90
+ updatedAt: string | null;
91
+ }
92
+ /**
93
+ * Adapter interface — injected by each consumer to handle host-specific behavior.
94
+ * The shared API module calls these methods; each host (vite dev, CLI embedded)
95
+ * provides its own implementation.
96
+ */
97
+ interface StudioApiAdapter {
98
+ /** List all available projects. */
99
+ listProjects(): Promise<ResolvedProject[]> | ResolvedProject[];
100
+ /** Resolve a project ID (or session ID) to its directory. Returns null if not found. */
101
+ resolveProject(id: string): Promise<ResolvedProject | null> | ResolvedProject | null;
102
+ /** Bundle a project directory into a single HTML string. Returns null if unavailable. */
103
+ bundle(projectDir: string): Promise<string | null>;
104
+ /** Optional: cached signature for project files that should invalidate preview frame caches. */
105
+ getProjectSignature?: (projectDir: string) => string;
106
+ /** Lint a single HTML string. */
107
+ lint(html: string, opts?: {
108
+ filePath?: string;
109
+ }): Promise<LintResult> | LintResult;
110
+ /** URL to the hyperframe runtime JS (injected into preview HTML). */
111
+ runtimeUrl: string;
112
+ /**
113
+ * Optional: post-process preview HTML before Studio augments it.
114
+ * Useful when preview must mirror render-time compilation steps.
115
+ */
116
+ transformPreviewHtml?: (opts: {
117
+ html: string;
118
+ project: ResolvedProject;
119
+ activeCompositionPath: string;
120
+ }) => Promise<string> | string;
121
+ /** Directory where render output files are stored. */
122
+ rendersDir(project: ResolvedProject): string;
123
+ /**
124
+ * Start a render job. The adapter owns the async execution and must
125
+ * update the returned RenderJobState object reactively.
126
+ */
127
+ startRender(opts: {
128
+ project: ResolvedProject;
129
+ outputPath: string;
130
+ format: "mp4" | "webm" | "mov";
131
+ /**
132
+ * Frame rate as an exact rational. The HTTP layer (POST
133
+ * `/projects/:id/render`) accepts either a JSON number (integer fps,
134
+ * `30`) or a JSON string (ffmpeg-style rational, `"30000/1001"`); the
135
+ * route normalizes both into `Fps` before invoking the adapter, so
136
+ * adapter implementations only ever see the rational form.
137
+ */
138
+ fps: _hyperframes_core.Fps;
139
+ quality: string;
140
+ jobId: string;
141
+ /**
142
+ * Optional output resolution preset. See `resolveDeviceScaleFactor` in
143
+ * the producer for the integer-scale + aspect + HDR constraints.
144
+ */
145
+ outputResolution?: CanvasResolution;
146
+ /** Entry file relative to projectDir (e.g. "compositions/intro.html"). Defaults to index.html. */
147
+ composition?: string;
148
+ /**
149
+ * Composition-variable overrides ({variableId: value}), forwarded to the
150
+ * producer's RenderConfig.variables and injected as window.__hfVariables —
151
+ * the same channel `hyperframes render --variables` uses.
152
+ */
153
+ variables?: Record<string, unknown>;
154
+ /**
155
+ * Telemetry id of the browser user who triggered the render. Lets the
156
+ * adapter attribute the server-emitted render_complete/render_error to
157
+ * that user so the studio render funnel is joinable. Undefined for older
158
+ * clients → falls back to the install's anonymous id.
159
+ */
160
+ distinctId?: string;
161
+ }): RenderJobState;
162
+ startBackgroundRemoval?: (opts: {
163
+ project: ResolvedProject;
164
+ inputPath: string;
165
+ inputAssetPath: string;
166
+ outputPath: string;
167
+ outputAssetPath: string;
168
+ backgroundOutputPath?: string;
169
+ backgroundOutputAssetPath?: string;
170
+ quality: "fast" | "balanced" | "best";
171
+ device?: "auto" | "cpu" | "coreml" | "cuda";
172
+ jobId: string;
173
+ }) => MediaProcessingJobState;
174
+ /** Optional: generate a JPEG thumbnail via Puppeteer or similar. */
175
+ generateThumbnail?: (opts: {
176
+ project: ResolvedProject;
177
+ compPath: string;
178
+ seekTime: number;
179
+ width: number;
180
+ height: number;
181
+ previewUrl: string;
182
+ selector?: string;
183
+ format?: "jpeg" | "png";
184
+ selectorIndex?: number;
185
+ }) => Promise<Buffer | null>;
186
+ /** Optional: resolve session ID to project (multi-project mode). */
187
+ resolveSession?: (sessionId: string) => Promise<{
188
+ projectId: string;
189
+ title: string;
190
+ } | null>;
191
+ /** Optional: list all registry items (blocks + components) for the catalog. */
192
+ listRegistryCatalog?(): Promise<RegistryItem[]>;
193
+ /** Optional: install a registry item into a project directory. */
194
+ installRegistryBlock?(opts: {
195
+ project: ResolvedProject;
196
+ blockName: string;
197
+ }): Promise<{
198
+ written: string[];
199
+ block: RegistryItem;
200
+ }>;
201
+ }
202
+
203
+ /**
204
+ * Transparent-media-proxy wiring shared by `routes/preview.ts`
205
+ * (docs/plans/2026-07-14-002-feat-transparent-media-proxies-plan.md, unit U3).
206
+ * Split out of the route module to keep it under the repo's 600-line file cap.
207
+ */
208
+ /**
209
+ * Preview-route-local adapter surface for the auto-proxy feature. Both
210
+ * fields are optional so any existing `StudioApiAdapter` value remains
211
+ * structurally assignable without editing the shared interface:
212
+ * `autoProxy` defaults to true (on) when omitted — a later unit wires the
213
+ * CLI `--no-proxy` flag / `hyperframes.json` setting through it;
214
+ * `mediaCodecProbeCache` lets a host share one probe cache across
215
+ * preview/play/static-server surfaces instead of each constructing its own.
216
+ */
217
+ type PreviewApiAdapter = StudioApiAdapter & {
218
+ autoProxy?: boolean;
219
+ mediaCodecProbeCache?: MediaCodecProbeCache;
220
+ };
221
+ declare function isAutoProxyEnabled(adapter: PreviewApiAdapter): boolean;
222
+ /** One probe cache per server instance — construct once in `registerPreviewRoutes`
223
+ * and reuse across every request so the mtime-cache benefit in
224
+ * `scanProjectMediaCodecMap` actually applies. A host that wants to share the
225
+ * cache across other surfaces (play, static project server) can pass its own
226
+ * via `adapter.mediaCodecProbeCache`. */
227
+ declare function resolvePreviewMediaCodecProbeCache(adapter: PreviewApiAdapter): MediaCodecProbeCache;
228
+ /**
229
+ * ETag salt for `?hf-proxy=` asset requests, mirroring `variablesEtagSalt` in
230
+ * preview.ts: salted by the raw param value plus the transcoder's params
231
+ * version, so a future proxy-recipe change (which bumps `PROXY_PARAMS_VERSION`)
232
+ * or a different proxy variant invalidates cached 304s without needing to
233
+ * touch the proxy file itself.
234
+ */
235
+ declare function proxyEtagSalt(raw: string | undefined): string;
236
+ /**
237
+ * Injects `window.__HF_MEDIA_CODEC_MAP__` (the U1 codec-facts scan) into
238
+ * served composition HTML, and fire-and-forget pre-warms `resolveProxy` for
239
+ * every browser-hostile entry so an element's proactive swap usually hits a
240
+ * warm cache (KTD: protects the per-origin connection budget under held
241
+ * responses). No second concurrency limiter here — the transcoder's own
242
+ * global bound throttles both pre-warm and element-triggered calls.
243
+ * Pre-warm failures are swallowed; an actual `?hf-proxy=` request surfaces
244
+ * them as a 502. Alpha-bearing entries pre-warm their VP9/WebM variant.
245
+ *
246
+ * The single shared implementation for every auto-proxy surface — the studio
247
+ * preview route (via `injectMediaCodecMap` below) and the CLI's composition /
248
+ * static project servers (via the `./media-proxy-preview` subpath export).
249
+ * Empty maps leave HTML untouched, preserving the normal no-hostile-media
250
+ * preview path. On-demand proxy requests enforce the same eligibility gate.
251
+ */
252
+ declare function injectMediaCodecMapIntoHtml(html: string, projectDir: string, htmlSources: HtmlSourceLike[], probeCache?: MediaCodecProbeCache): Promise<string>;
253
+ /**
254
+ * Adapter-aware wrapper used by the studio preview routes: skipped entirely
255
+ * (no scan, no injection) when auto-proxy is off for this adapter.
256
+ */
257
+ declare function injectMediaCodecMap(html: string, adapter: PreviewApiAdapter, projectDir: string, compSrcPath: string, probeCache: MediaCodecProbeCache): Promise<string>;
258
+
259
+ export { type LintResult as L, type MediaProcessingJobState as M, type PreviewApiAdapter as P, type RenderJobState as R, type StudioApiAdapter as S, type ResolvedProject as a, type StudioSelectionResponse as b, type StudioSelectionSnapshot as c, type StudioSelectionTextField as d, injectMediaCodecMapIntoHtml as e, isAutoProxyEnabled as f, injectMediaCodecMap as i, proxyEtagSalt as p, resolvePreviewMediaCodecProbeCache as r };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hyperframes/studio-server",
3
- "version": "0.7.60",
3
+ "version": "0.7.61",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/heygen-com/hyperframes",
@@ -42,6 +42,18 @@
42
42
  "./source-mutation": {
43
43
  "import": "./dist/helpers/sourceMutation.js",
44
44
  "types": "./dist/helpers/sourceMutation.d.ts"
45
+ },
46
+ "./media-codec-map": {
47
+ "import": "./dist/helpers/mediaCodecMap.js",
48
+ "types": "./dist/helpers/mediaCodecMap.d.ts"
49
+ },
50
+ "./proxy-transcoder": {
51
+ "import": "./dist/helpers/proxyTranscoder.js",
52
+ "types": "./dist/helpers/proxyTranscoder.d.ts"
53
+ },
54
+ "./media-proxy-preview": {
55
+ "import": "./dist/helpers/mediaProxyPreview.js",
56
+ "types": "./dist/helpers/mediaProxyPreview.d.ts"
45
57
  }
46
58
  },
47
59
  "publishConfig": {
@@ -52,8 +64,8 @@
52
64
  "linkedom": "^0.18.12",
53
65
  "postcss": "^8.5.8",
54
66
  "postcss-selector-parser": "^7.1.2",
55
- "@hyperframes/parsers": "0.7.60",
56
- "@hyperframes/core": "0.7.60"
67
+ "@hyperframes/core": "0.7.61",
68
+ "@hyperframes/parsers": "0.7.61"
57
69
  },
58
70
  "devDependencies": {
59
71
  "@types/node": "^25.0.10",