@alpha2-sh/editor 0.0.0-stage → 0.1.0
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.
- package/LICENSE.md +21 -0
- package/README.md +108 -2
- package/dist/browser/bridge.d.ts +44 -0
- package/dist/browser/bridge.js +2176 -0
- package/dist/browser/extensions-worker-entry.d.ts +1 -0
- package/dist/browser/extensions-worker-entry.js +3 -0
- package/dist/browser/extensions-worker.d.ts +46 -0
- package/dist/browser/extensions-worker.js +149 -0
- package/dist/browser/hash-worker-entry.d.ts +1 -0
- package/dist/browser/hash-worker-entry.js +3 -0
- package/dist/browser/hash-worker.d.ts +24 -0
- package/dist/browser/hash-worker.js +87 -0
- package/dist/browser/index.d.ts +11 -0
- package/dist/browser/index.js +9 -0
- package/dist/browser/jobs.d.ts +82 -0
- package/dist/browser/jobs.js +291 -0
- package/dist/browser/resources.d.ts +40 -0
- package/dist/browser/resources.js +83 -0
- package/dist/browser/runtime/assets.d.ts +233 -0
- package/dist/browser/runtime/assets.js +633 -0
- package/dist/browser/runtime/audio.d.ts +60 -0
- package/dist/browser/runtime/audio.js +549 -0
- package/dist/browser/runtime/budget.d.ts +11 -0
- package/dist/browser/runtime/budget.js +26 -0
- package/dist/browser/runtime/caption-fonts.d.ts +34 -0
- package/dist/browser/runtime/caption-fonts.js +69 -0
- package/dist/browser/runtime/color.d.ts +7 -0
- package/dist/browser/runtime/color.js +12 -0
- package/dist/browser/runtime/engine.d.ts +91 -0
- package/dist/browser/runtime/engine.js +352 -0
- package/dist/browser/runtime/export-audio.d.ts +23 -0
- package/dist/browser/runtime/export-audio.js +75 -0
- package/dist/browser/runtime/exporter.d.ts +140 -0
- package/dist/browser/runtime/exporter.js +751 -0
- package/dist/browser/runtime/extension-import.d.ts +196 -0
- package/dist/browser/runtime/extension-import.js +521 -0
- package/dist/browser/runtime/fingerprint.d.ts +57 -0
- package/dist/browser/runtime/fingerprint.js +157 -0
- package/dist/browser/runtime/generators.d.ts +188 -0
- package/dist/browser/runtime/generators.js +173 -0
- package/dist/browser/runtime/locks.d.ts +32 -0
- package/dist/browser/runtime/locks.js +86 -0
- package/dist/browser/runtime/output.d.ts +87 -0
- package/dist/browser/runtime/output.js +230 -0
- package/dist/browser/runtime/preview-utils.d.ts +3 -0
- package/dist/browser/runtime/preview-utils.js +49 -0
- package/dist/browser/runtime/proxies.d.ts +72 -0
- package/dist/browser/runtime/proxies.js +369 -0
- package/dist/browser/runtime/proxy-storage.d.ts +59 -0
- package/dist/browser/runtime/proxy-storage.js +119 -0
- package/dist/browser/runtime/sources.d.ts +82 -0
- package/dist/browser/runtime/sources.js +819 -0
- package/dist/browser/runtime/staging.d.ts +10 -0
- package/dist/browser/runtime/staging.js +32 -0
- package/dist/browser/runtime/still.d.ts +21 -0
- package/dist/browser/runtime/still.js +52 -0
- package/dist/browser/runtime/wasm.d.ts +9 -0
- package/dist/browser/runtime/wasm.js +20 -0
- package/dist/browser/types.d.ts +549 -0
- package/dist/browser/types.js +1 -0
- package/dist/browser/worker-entry.d.ts +1 -0
- package/dist/browser/worker-entry.js +2 -0
- package/dist/browser/worker.d.ts +24 -0
- package/dist/browser/worker.js +239 -0
- package/dist/core/captions.d.ts +34 -0
- package/dist/core/captions.js +108 -0
- package/dist/core/clip-time.d.ts +31 -0
- package/dist/core/clip-time.js +125 -0
- package/dist/core/commands.d.ts +413 -0
- package/dist/core/commands.js +1118 -0
- package/dist/core/compositions.d.ts +234 -0
- package/dist/core/compositions.js +851 -0
- package/dist/core/document.d.ts +245 -0
- package/dist/core/document.js +683 -0
- package/dist/core/keyframes.d.ts +82 -0
- package/dist/core/keyframes.js +153 -0
- package/dist/core/presets.d.ts +64 -0
- package/dist/core/presets.js +241 -0
- package/dist/core/session.d.ts +150 -0
- package/dist/core/session.js +541 -0
- package/dist/core/text.d.ts +17 -0
- package/dist/core/text.js +17 -0
- package/dist/core/time.d.ts +19 -0
- package/dist/core/time.js +39 -0
- package/dist/core/timeline-index.d.ts +44 -0
- package/dist/core/timeline-index.js +59 -0
- package/dist/core/transitions.d.ts +20 -0
- package/dist/core/transitions.js +118 -0
- package/dist/core/validated.d.ts +23 -0
- package/dist/core/validated.js +52 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +11 -0
- package/dist/native-client/index.d.ts +131 -0
- package/dist/native-client/index.js +354 -0
- package/dist/ports/index.d.ts +146 -0
- package/dist/ports/index.js +1 -0
- package/dist/react/index.d.ts +37 -0
- package/dist/react/index.js +94 -0
- package/package.json +79 -4
|
@@ -0,0 +1,549 @@
|
|
|
1
|
+
import type { MediaFingerprint, Project } from "alpha2/project";
|
|
2
|
+
import type { AssetBinding, ConformReport, MediaPurpose } from "alpha2/assets";
|
|
3
|
+
import type { BuiltinEffectCatalog } from "alpha2/effects";
|
|
4
|
+
import type { EditorSession } from "../core/session.js";
|
|
5
|
+
import type { CapabilityReport, PlaybackPolicy } from "alpha2";
|
|
6
|
+
import type { Capability } from "../ports/index.js";
|
|
7
|
+
import type { Json } from "../core/document.js";
|
|
8
|
+
import type { ExportJob } from "./jobs.js";
|
|
9
|
+
/**
|
|
10
|
+
* Where a bundler put the runtime's code and data. Each URL defaults to the location the
|
|
11
|
+
* packaged module resolves on its own.
|
|
12
|
+
*/
|
|
13
|
+
export interface RuntimeAssets {
|
|
14
|
+
/**
|
|
15
|
+
* Creates a worker running `installEditorWorker`. With one, the preview renders in that
|
|
16
|
+
* worker; without, it renders on the main thread.
|
|
17
|
+
*/
|
|
18
|
+
readonly workerFactory?: () => Worker;
|
|
19
|
+
/**
|
|
20
|
+
* Creates a worker running the `@alpha2-sh/editor/hash-worker` entry. With one, each imported or
|
|
21
|
+
* relinked file is hashed in a worker of its own; without, on the page's thread, which lets
|
|
22
|
+
* other tasks run every few milliseconds but spends the page's CPU (about 5 ms a megabyte).
|
|
23
|
+
*/
|
|
24
|
+
readonly hashWorkerFactory?: () => Worker;
|
|
25
|
+
/**
|
|
26
|
+
* Creates a worker running the `@alpha2-sh/editor/extensions-worker` entry. With one, each file an
|
|
27
|
+
* extension provider reads (SVG, animated image, Lottie, OpenEXR) is probed, opened and drawn for
|
|
28
|
+
* its thumbnail at import, and an SVG opened again for its font report, in a worker of its own,
|
|
29
|
+
* which a cancelled import terminates, as does a call running past `EXTENSIONS_CALL_TIMEOUT_MS`
|
|
30
|
+
* (40 s; the import fails as `provider_stalled`). Without one, or when the worker cannot start,
|
|
31
|
+
* those calls run on the page's thread, which waits for each: an animated image's open decodes
|
|
32
|
+
* every frame.
|
|
33
|
+
*/
|
|
34
|
+
readonly extensionsWorkerFactory?: () => Worker;
|
|
35
|
+
/** The engine's wasm binary (`alpha2/wasm`). */
|
|
36
|
+
readonly wasmUrl?: string | URL;
|
|
37
|
+
/**
|
|
38
|
+
* Where a bundler put `alpha2_extensions_bg.wasm`, loaded when an SVG, animated image, or image
|
|
39
|
+
* sequence is opened.
|
|
40
|
+
*/
|
|
41
|
+
readonly extensionsWasmUrl?: string | URL;
|
|
42
|
+
/** The audio worklet's wasm binary, loaded on the first Play. */
|
|
43
|
+
readonly audioWasmUrl?: string | URL;
|
|
44
|
+
/** The audio worklet processor module. */
|
|
45
|
+
readonly workletUrl?: string | URL;
|
|
46
|
+
/**
|
|
47
|
+
* Fonts the runtime provides beyond the document's font assets. They follow those in the
|
|
48
|
+
* fallback order for captions and SVG text, and native exports receive them too.
|
|
49
|
+
*/
|
|
50
|
+
readonly fonts?: readonly RuntimeFont[];
|
|
51
|
+
}
|
|
52
|
+
/** A font file the runtime registers with the engine. */
|
|
53
|
+
export interface RuntimeFont {
|
|
54
|
+
readonly id: string;
|
|
55
|
+
readonly name: string;
|
|
56
|
+
readonly bytes: Uint8Array;
|
|
57
|
+
/** The face to read in a collection file (`.ttc`/`.otc`); 0 for a single-face file. */
|
|
58
|
+
readonly faceIndex: number;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* A source's media as this browser session holds it. Never part of the project document or its
|
|
62
|
+
* history.
|
|
63
|
+
*/
|
|
64
|
+
export interface RuntimeAsset {
|
|
65
|
+
readonly id: string;
|
|
66
|
+
/** `video`, `image`, `audio`, `text`, `font`, `lut3d`, or `generated`. */
|
|
67
|
+
readonly kind: string;
|
|
68
|
+
readonly name?: string;
|
|
69
|
+
/**
|
|
70
|
+
* What the source is read from. A still is decoded from it each time a frame needs its raster and
|
|
71
|
+
* the cache does not hold it: no decoded picture stays with the asset.
|
|
72
|
+
*/
|
|
73
|
+
readonly file?: File;
|
|
74
|
+
/** Small preview canvas; `dataUrl` is a ready-to-use image URL. */
|
|
75
|
+
readonly thumbnail?: {
|
|
76
|
+
readonly dataUrl?: string;
|
|
77
|
+
readonly width: number;
|
|
78
|
+
readonly height: number;
|
|
79
|
+
} | null;
|
|
80
|
+
/** Display size in pixels, where the media has one. */
|
|
81
|
+
readonly width?: number;
|
|
82
|
+
readonly height?: number;
|
|
83
|
+
/** Seconds; 0 for a still. */
|
|
84
|
+
readonly duration?: number;
|
|
85
|
+
/**
|
|
86
|
+
* Whether the file has an audio stream: what the document records as the source's `has_audio`,
|
|
87
|
+
* whichever browser imported it.
|
|
88
|
+
*/
|
|
89
|
+
readonly hasAudio?: boolean;
|
|
90
|
+
/**
|
|
91
|
+
* `false` when this browser cannot decode the file's audio (Safari before 26 has no
|
|
92
|
+
* `AudioDecoder`): it plays and exports silent in this session, and the document still says the
|
|
93
|
+
* source has audio, which a native host and other browsers hear.
|
|
94
|
+
*/
|
|
95
|
+
readonly audioDecodable?: boolean;
|
|
96
|
+
/** Per-bucket peak magnitudes across the whole file, for audio sources. */
|
|
97
|
+
readonly peaks?: Float32Array | null;
|
|
98
|
+
/** `native`: drawn centred at its own pixel size (text); otherwise contained. */
|
|
99
|
+
readonly fit?: "native" | "contain";
|
|
100
|
+
}
|
|
101
|
+
/** A file decoded and probed for import, before it enters the document. */
|
|
102
|
+
export interface StagedAsset {
|
|
103
|
+
readonly runtime: RuntimeAsset;
|
|
104
|
+
/** The asset's authoring description, recorded in the document. */
|
|
105
|
+
readonly description: Json;
|
|
106
|
+
/** Evidence of the file, recorded with the asset and its project source. */
|
|
107
|
+
readonly fingerprint?: MediaFingerprint;
|
|
108
|
+
/** Releases what staging opened. Called once the bridge no longer holds the runtime. */
|
|
109
|
+
dispose(): void;
|
|
110
|
+
}
|
|
111
|
+
/** Decodes and probes files for import. `createMediaAdapter` makes the default one. */
|
|
112
|
+
export interface BrowserMediaAdapter {
|
|
113
|
+
/**
|
|
114
|
+
* Stages one file. Rejects with an `EditorError`: `unsupported_media` for a file that is no media
|
|
115
|
+
* the adapter imports, `unreadable_media` for media this browser could not read (a codec it does
|
|
116
|
+
* not decode, a damaged file, or one an extension provider refuses, such as one whose drawing is
|
|
117
|
+
* past its budgets; the decoder's or provider's reason is in the message and is the `cause`),
|
|
118
|
+
* `too_large` for a Lottie, dotLottie or SVG file larger than the engine parses
|
|
119
|
+
* (`MAX_LOTTIE_DOCUMENT_BYTES`, `MAX_PROVIDER_DOCUMENT_BYTES` for a dotLottie package,
|
|
120
|
+
* `MAX_SVG_DOCUMENT_BYTES`), `provider_stalled` for one the extensions worker read past
|
|
121
|
+
* `EXTENSIONS_CALL_TIMEOUT_MS`, and when `signal` aborts.
|
|
122
|
+
*/
|
|
123
|
+
stage(file: File, signal: AbortSignal, options?: {
|
|
124
|
+
/**
|
|
125
|
+
* `false` when the caller has no use for the file's fingerprint and it need not be computed:
|
|
126
|
+
* the bridge adopts a kept proxy by its original's hash. Default `true`.
|
|
127
|
+
*/
|
|
128
|
+
readonly fingerprint?: boolean;
|
|
129
|
+
}): Promise<StagedAsset>;
|
|
130
|
+
/** Stages numbered PNGs or OpenEXR images as one image sequence. */
|
|
131
|
+
stageSequence?(files: readonly File[], options: {
|
|
132
|
+
readonly frameRate: {
|
|
133
|
+
readonly num: number;
|
|
134
|
+
readonly den: number;
|
|
135
|
+
};
|
|
136
|
+
readonly missing: "reject" | "hold" | "blank";
|
|
137
|
+
/**
|
|
138
|
+
* The source ID the frames are staged under: the asset's own for a relink, a new one
|
|
139
|
+
* otherwise.
|
|
140
|
+
*/
|
|
141
|
+
readonly id?: string;
|
|
142
|
+
}, signal: AbortSignal): Promise<StagedAsset & {
|
|
143
|
+
readonly name?: string;
|
|
144
|
+
}>;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* What `installEditorWorker` uses of a dedicated worker's global (`self` in the worker): its
|
|
148
|
+
* message handler and `postMessage`.
|
|
149
|
+
*/
|
|
150
|
+
export interface EditorWorkerScope {
|
|
151
|
+
onmessage: ((event: MessageEvent) => void) | null;
|
|
152
|
+
postMessage(message: unknown, transfer?: Transferable[]): void;
|
|
153
|
+
}
|
|
154
|
+
/** Options of `createBrowserBridge`. */
|
|
155
|
+
export interface BrowserBridgeOptions {
|
|
156
|
+
/**
|
|
157
|
+
* The session the bridge previews, imports into, and exports. Disposing it disposes the bridge.
|
|
158
|
+
*/
|
|
159
|
+
readonly editor: EditorSession;
|
|
160
|
+
readonly runtimeAssets?: RuntimeAssets;
|
|
161
|
+
/** Defaults to `createMediaAdapter(runtimeAssets)`. */
|
|
162
|
+
readonly mediaAdapter?: BrowserMediaAdapter;
|
|
163
|
+
/**
|
|
164
|
+
* The most runtime resources (imported media, rasterized text, proxies) held at once,
|
|
165
|
+
* default 128. An import past it is refused with `EditorError` `resource_budget`.
|
|
166
|
+
*/
|
|
167
|
+
readonly resourceLimit?: number;
|
|
168
|
+
/**
|
|
169
|
+
* `false` renders picture only: no AudioContext is opened and playback runs on the wall clock
|
|
170
|
+
* (thumbnails and other silent previews).
|
|
171
|
+
*/
|
|
172
|
+
readonly audio?: boolean;
|
|
173
|
+
/**
|
|
174
|
+
* Receives errors no caller awaits: a preview render that failed, audio that did not start,
|
|
175
|
+
* a refresh after an edit. The bridge keeps running after each.
|
|
176
|
+
*/
|
|
177
|
+
readonly onError?: (error: unknown) => void;
|
|
178
|
+
/**
|
|
179
|
+
* The engine's asset decisions (fingerprint comparison, conform). Defaults to the packaged wasm
|
|
180
|
+
* module, loaded on first use.
|
|
181
|
+
*/
|
|
182
|
+
readonly assetDecisions?: AssetBinding;
|
|
183
|
+
}
|
|
184
|
+
/** Options of `BrowserBridge.startExport`. The file is an MP4. */
|
|
185
|
+
export interface BrowserExportOptions {
|
|
186
|
+
/**
|
|
187
|
+
* Default `avc`. Whether this browser encodes it is the browser's to say ({@link
|
|
188
|
+
* BrowserBridge.videoEncoders}); an export with one it does not is refused before it renders, as
|
|
189
|
+
* `INVALID_INPUT`.
|
|
190
|
+
*/
|
|
191
|
+
readonly videoCodec?: "avc" | "hevc" | "vp9" | "av1";
|
|
192
|
+
/**
|
|
193
|
+
* One of the engine's quality levels (`very-low`, `low`, `medium`, `high`, `very-high`),
|
|
194
|
+
* default `high`. The engine resolves it to a bitrate for the codec, size, and frame rate,
|
|
195
|
+
* as it does for a native export.
|
|
196
|
+
*/
|
|
197
|
+
readonly videoQuality?: string;
|
|
198
|
+
/** An engine quality level for the audio, default `high`. */
|
|
199
|
+
readonly audioQuality?: string;
|
|
200
|
+
/**
|
|
201
|
+
* Default `true`. Audio is written only when an audible source is shown. An export with
|
|
202
|
+
* audio is refused before it renders on a browser that encodes neither AAC nor Opus.
|
|
203
|
+
*/
|
|
204
|
+
readonly includeAudio?: boolean;
|
|
205
|
+
/**
|
|
206
|
+
* The exact rate to export at instead of the project's, frames per second as `num / den`
|
|
207
|
+
* (`{ num: 30000, den: 1001 }` for 29.97), as the project states its own: both backends export
|
|
208
|
+
* exactly this rate. One the engine cannot read (`num` and `den` positive 32-bit integers, a
|
|
209
|
+
* frame at least one tick long) is refused when the export starts, with an `EditorError`
|
|
210
|
+
* `invalid_frame_rate`.
|
|
211
|
+
*/
|
|
212
|
+
readonly frameRate?: {
|
|
213
|
+
readonly num: number;
|
|
214
|
+
readonly den: number;
|
|
215
|
+
};
|
|
216
|
+
/**
|
|
217
|
+
* `original` (the default) reads originals and refuses without them; `proxies` reads fresh
|
|
218
|
+
* proxies where there are some.
|
|
219
|
+
*/
|
|
220
|
+
readonly media?: "original" | "proxies";
|
|
221
|
+
/**
|
|
222
|
+
* Where the file is written. `opfs` (the default where the browser supports it) streams it to a
|
|
223
|
+
* temporary origin-private file, which the job's artifact holds until released; `file` streams it
|
|
224
|
+
* into a file the user picked (`showSaveFilePicker`, obtained during the click that started the
|
|
225
|
+
* export); `memory` keeps it in memory, for small outputs only: the export is refused before it
|
|
226
|
+
* starts when its estimated size, with room for the buffer's growth and copies, passes `maxBytes`
|
|
227
|
+
* (default 512 MiB). Without a disk API the export falls back to `memory` under the same limit,
|
|
228
|
+
* never to an unbounded buffer.
|
|
229
|
+
*/
|
|
230
|
+
readonly output?: ExportOutputTarget;
|
|
231
|
+
/**
|
|
232
|
+
* `inFlightBytes` bounds the rendered frames the export holds at once (GPU readbacks and the
|
|
233
|
+
* copies queued for the encoder), default 128 MiB. The export submits a frame only when it fits,
|
|
234
|
+
* gives back the renderer's idle GPU memory when the budget stops it, and is refused before it
|
|
235
|
+
* starts when one frame's readback and copy cannot fit. The result's `performance.memory` reports
|
|
236
|
+
* the budget, the least one frame needed, the most held, and how often the budget waited.
|
|
237
|
+
*/
|
|
238
|
+
readonly memory?: {
|
|
239
|
+
readonly inFlightBytes?: number;
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
/** Where a browser export writes its file. */
|
|
243
|
+
export type ExportOutputTarget = {
|
|
244
|
+
readonly kind: "opfs";
|
|
245
|
+
} | {
|
|
246
|
+
readonly kind: "file";
|
|
247
|
+
readonly handle: FileSystemFileHandle;
|
|
248
|
+
} | {
|
|
249
|
+
readonly kind: "memory";
|
|
250
|
+
readonly maxBytes?: number;
|
|
251
|
+
};
|
|
252
|
+
/** A source's proxy, as the bridge keeps it. */
|
|
253
|
+
export interface ProxyStatus {
|
|
254
|
+
/** Whether a proxy made from the recorded media is kept. */
|
|
255
|
+
readonly available: boolean;
|
|
256
|
+
/** Progress of one being made, from 0 to 1, or `null`. */
|
|
257
|
+
readonly generating: number | null;
|
|
258
|
+
/** What preview reads for the source now. */
|
|
259
|
+
readonly reading: "original" | "proxy" | "unavailable";
|
|
260
|
+
}
|
|
261
|
+
/** A proxy kept in this browser's storage, by its original's SHA-256. */
|
|
262
|
+
export interface KeptProxy {
|
|
263
|
+
readonly hash: string;
|
|
264
|
+
readonly bytes: number;
|
|
265
|
+
}
|
|
266
|
+
/** What a proxy removal did: the hashes removed, and those left because a page reads them. */
|
|
267
|
+
export interface ProxyRemoval {
|
|
268
|
+
readonly removed: readonly string[];
|
|
269
|
+
readonly inUse: readonly string[];
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* The browser runtime of one editor session, made by `createBrowserBridge`. Times are integer
|
|
273
|
+
* ticks (120000 per second). Methods that change the document dispatch through the session, so
|
|
274
|
+
* they are undoable.
|
|
275
|
+
*/
|
|
276
|
+
export interface BrowserBridge {
|
|
277
|
+
/** Where the preview renders: nowhere until `bindPreview`, then a worker or the main thread. */
|
|
278
|
+
readonly previewBackend: "unbound" | "worker" | "main-thread";
|
|
279
|
+
/** How many times the preview was made again after its GPU device or WebGL context was lost. */
|
|
280
|
+
readonly previewRecoveries: number;
|
|
281
|
+
/** What this page can do; `gpu` and `color` are `null` until a preview is bound. */
|
|
282
|
+
readonly capabilities: CapabilityReport<null, null> & {
|
|
283
|
+
readonly features: Readonly<Record<"preview" | "audioPreview" | "transportRate" | "worker" | "export", Capability>>;
|
|
284
|
+
};
|
|
285
|
+
/** The playhead. */
|
|
286
|
+
readonly tick: number;
|
|
287
|
+
readonly playing: boolean;
|
|
288
|
+
/** Runtime resources currently held (see `BrowserBridgeOptions.resourceLimit`). */
|
|
289
|
+
readonly resourceCount: number;
|
|
290
|
+
/**
|
|
291
|
+
* Preview output volume from 0 to 1; a monitor control, not part of the project or exports.
|
|
292
|
+
* The bridge keeps it: set before a preview is bound, or across bindings, it applies to every
|
|
293
|
+
* preview's sound. Throws for a value outside that range.
|
|
294
|
+
*/
|
|
295
|
+
setMonitorVolume(value: number): void;
|
|
296
|
+
/** The monitor volume `setMonitorVolume` last set; 1 until then. */
|
|
297
|
+
readonly monitorVolume: number;
|
|
298
|
+
/** Logs every source upload of the preview engine to the console, for debugging. */
|
|
299
|
+
setTraceUploads(value: boolean): void;
|
|
300
|
+
/** The preview engine's latest diagnostics sample (taken at most every 250 ms), or `null`. */
|
|
301
|
+
readonly diagnostics: Readonly<Record<string, unknown>> | null;
|
|
302
|
+
/** The engine's built-in effects and transitions; `null` until a preview is bound. */
|
|
303
|
+
readonly catalog: BuiltinEffectCatalog | null;
|
|
304
|
+
/**
|
|
305
|
+
* What preview reads for source `id` of the draft: its original, or the kept proxy standing in
|
|
306
|
+
* while the original is offline; opened with the provider settings the document names. Use {@link
|
|
307
|
+
* BrowserBridge.hasOriginal} to ask whether the original itself is linked.
|
|
308
|
+
*/
|
|
309
|
+
getAsset(id: string): RuntimeAsset | null;
|
|
310
|
+
/**
|
|
311
|
+
* Notifies when derived runtime data (such as waveform peaks) becomes available for an already
|
|
312
|
+
* imported asset.
|
|
313
|
+
*/
|
|
314
|
+
subscribeAssets(listener: () => void): () => void;
|
|
315
|
+
/**
|
|
316
|
+
* Why the viewer holds its last frame instead of the current one, or `null` when it is current: a
|
|
317
|
+
* composition the playhead shows cannot draw its output yet.
|
|
318
|
+
*/
|
|
319
|
+
readonly previewIssue: string | null;
|
|
320
|
+
/** Notifies when {@link previewIssue} changes. */
|
|
321
|
+
subscribePreview(listener: () => void): () => void;
|
|
322
|
+
/**
|
|
323
|
+
* Draws the preview on `canvas`. Rejects only when the surface cannot be bound (the GPU would not
|
|
324
|
+
* start); a first frame that cannot render, such as one whose media is not linked yet, goes to
|
|
325
|
+
* `onError` like any later frame and is drawn by the next edit or seek. A preview worker that
|
|
326
|
+
* fails, to start or later, is given up for the main-thread renderer, which draws on the same
|
|
327
|
+
* surface: `previewBackend` then says `main-thread` and `onError` hears why, once, as an
|
|
328
|
+
* `EditorError` `preview_worker_failed` (a worker that lost its GPU is recovered from without a
|
|
329
|
+
* report, as a lost GPU on the main thread is). A given-up worker is not started again until the
|
|
330
|
+
* next `bindPreview`, not even by a preview made again after a lost GPU.
|
|
331
|
+
*/
|
|
332
|
+
bindPreview(canvas: HTMLCanvasElement | OffscreenCanvas): Promise<{
|
|
333
|
+
readonly canvas: HTMLCanvasElement | OffscreenCanvas;
|
|
334
|
+
dispose(): Promise<void>;
|
|
335
|
+
}>;
|
|
336
|
+
/**
|
|
337
|
+
* Stages `files` and adds them to the document in one undoable transaction. With `relinkId`,
|
|
338
|
+
* the single file replaces that asset's media, keeping its ID and clips.
|
|
339
|
+
*
|
|
340
|
+
* Rejects when staging fails, when `signal` aborts, when the session loads another project
|
|
341
|
+
* meanwhile (`stale_import`), for an unknown relink target (`missing_asset`), and for a relink
|
|
342
|
+
* that is not one file of the same kind and recorded media (`relink_conflict`). Nothing is added
|
|
343
|
+
* when any file fails.
|
|
344
|
+
*/
|
|
345
|
+
importFiles(files: readonly File[], options?: {
|
|
346
|
+
signal?: AbortSignal;
|
|
347
|
+
relinkId?: string;
|
|
348
|
+
}): Promise<{
|
|
349
|
+
assetIds: string[];
|
|
350
|
+
}>;
|
|
351
|
+
/** `importFiles([file], { relinkId: id })`. */
|
|
352
|
+
relink(id: string, file: File, options?: {
|
|
353
|
+
signal?: AbortSignal;
|
|
354
|
+
}): Promise<{
|
|
355
|
+
assetIds: string[];
|
|
356
|
+
}>;
|
|
357
|
+
/**
|
|
358
|
+
* Imports numbered PNGs as one image sequence at `frameRate` (the project's by default). A gap in
|
|
359
|
+
* the numbering is refused unless `missing` holds or blanks it.
|
|
360
|
+
*/
|
|
361
|
+
importSequence(files: readonly File[], options?: {
|
|
362
|
+
frameRate?: {
|
|
363
|
+
readonly num: number;
|
|
364
|
+
readonly den: number;
|
|
365
|
+
};
|
|
366
|
+
missing?: "reject" | "hold" | "blank";
|
|
367
|
+
signal?: AbortSignal;
|
|
368
|
+
}): Promise<{
|
|
369
|
+
assetIds: string[];
|
|
370
|
+
}>;
|
|
371
|
+
/**
|
|
372
|
+
* Relinks an image sequence to its frames, at the frame rate and gap rule the project recorded:
|
|
373
|
+
* the asset keeps its ID and clips, and the engine decides whether the frames are the sequence it
|
|
374
|
+
* recorded. Refused for an asset that is not an image sequence.
|
|
375
|
+
*/
|
|
376
|
+
relinkSequence(id: string, files: readonly File[], options?: {
|
|
377
|
+
signal?: AbortSignal;
|
|
378
|
+
}): Promise<{
|
|
379
|
+
assetIds: string[];
|
|
380
|
+
}>;
|
|
381
|
+
/**
|
|
382
|
+
* Moves the playhead to `tick`, pausing playback, and renders that frame. Resolves `true` when
|
|
383
|
+
* the frame was drawn and `false` when a later seek or edit superseded it or nothing is bound.
|
|
384
|
+
* Rejects for a tick that is not a non-negative safe integer (`invalid_time`) and when the
|
|
385
|
+
* frame fails to render.
|
|
386
|
+
*/
|
|
387
|
+
seek(tick: number): Promise<boolean>;
|
|
388
|
+
/**
|
|
389
|
+
* Plays from the playhead at `rate` (negative plays backwards) under a playback `policy`
|
|
390
|
+
* (default `drop_video_keep_audio`), stopping at the end of the export range (else of the
|
|
391
|
+
* content), or looping with `loop`. Sound plays only at rate 1 under a policy that allows it;
|
|
392
|
+
* when it cannot start within 3 s the picture plays silently and `onError` hears why. Rejects
|
|
393
|
+
* for a zero or non-finite rate (`invalid_rate`) and an unknown policy (`invalid_policy`).
|
|
394
|
+
*/
|
|
395
|
+
play(rate?: number, options?: {
|
|
396
|
+
loop?: boolean;
|
|
397
|
+
policy?: PlaybackPolicy;
|
|
398
|
+
}): Promise<void>;
|
|
399
|
+
/** Stops playback and audio; the playhead stays where it was. */
|
|
400
|
+
pause(): void;
|
|
401
|
+
/**
|
|
402
|
+
* Reads a subtitle file (`.srt`, or `.vtt` for WebVTT) into a captions asset in the bin
|
|
403
|
+
* (`captionsAsset`); `skipped` counts blocks that were not cues. Nothing reaches the timeline
|
|
404
|
+
* until the asset is inserted (`captionTrackCommands`).
|
|
405
|
+
*
|
|
406
|
+
* Throws an `EditorError` (`invalid_captions`) for a file larger than `MAX_CAPTION_FILE_BYTES`,
|
|
407
|
+
* which is not read, and for one the engine refuses: a WebVTT file without its header, more than
|
|
408
|
+
* `MAX_CAPTION_FILE_CUES` cues, or cues that need more caption tracks than a project holds.
|
|
409
|
+
*/
|
|
410
|
+
importCaptions(file: File): Promise<{
|
|
411
|
+
assetId: string;
|
|
412
|
+
skipped: number;
|
|
413
|
+
}>;
|
|
414
|
+
/**
|
|
415
|
+
* The font families caption styles can name in `font_family`: those of the document's font assets
|
|
416
|
+
* and the runtime's fonts, in fallback order, each once, as the engine reads them from the fonts'
|
|
417
|
+
* name tables.
|
|
418
|
+
*/
|
|
419
|
+
captionFontFamilies(): Promise<string[]>;
|
|
420
|
+
/**
|
|
421
|
+
* The files a native export of `document` (the current one by default) needs, for upload:
|
|
422
|
+
* shown media (or their proxies with `media: "proxies"`), an image sequence's frames, font
|
|
423
|
+
* files, LUTs, and text rendered to PNG. Rejects as `startExport` does when the media is not
|
|
424
|
+
* ready (`ConformError`) or the document does not compile.
|
|
425
|
+
*/
|
|
426
|
+
nativeAssets(document?: import("../core/document.js").EditorDocument, options?: Pick<BrowserExportOptions, "media">): Promise<import("../native-client/index.js").NativeAsset[]>;
|
|
427
|
+
/**
|
|
428
|
+
* Whether the document's media is ready for `purpose`, as the engine decides from this session's
|
|
429
|
+
* originals and kept proxies.
|
|
430
|
+
*/
|
|
431
|
+
conform(purpose: MediaPurpose, document?: import("../core/document.js").EditorDocument): Promise<ConformReport>;
|
|
432
|
+
/**
|
|
433
|
+
* Makes and keeps a proxy of a source whose original this session holds. Proxies are made one
|
|
434
|
+
* at a time and never beside an export: this waits for a running export and for a proxy of
|
|
435
|
+
* another source being made, and an export that starts stops the conversion, which starts again
|
|
436
|
+
* from the beginning once the export ends (`proxyStatus` shows its progress back at 0). Rejects
|
|
437
|
+
* for a source without a single video file (`unsupported_media`, including HDR video), without
|
|
438
|
+
* its original in this session (`missing_asset`), with a proxy of it already being made
|
|
439
|
+
* (`proxy_busy`), or when `signal` aborts.
|
|
440
|
+
*/
|
|
441
|
+
generateProxy(id: string, options?: {
|
|
442
|
+
signal?: AbortSignal;
|
|
443
|
+
}): Promise<void>;
|
|
444
|
+
/** Whether a source has a kept proxy, the progress of one being made, and what preview reads. */
|
|
445
|
+
proxyStatus(id: string): ProxyStatus;
|
|
446
|
+
/**
|
|
447
|
+
* Which video codecs this browser encodes for an export of the current document (its size and
|
|
448
|
+
* frame rate) at `videoQuality` (default `high`). WebCodecs leaves the codecs to the browser;
|
|
449
|
+
* an export with one answered `false` is refused before it renders (`INVALID_INPUT`).
|
|
450
|
+
*/
|
|
451
|
+
videoEncoders(options?: {
|
|
452
|
+
readonly videoQuality?: string;
|
|
453
|
+
}): Promise<Readonly<Record<NonNullable<BrowserExportOptions["videoCodec"]>, boolean>>>;
|
|
454
|
+
/**
|
|
455
|
+
* The proxies this browser keeps, for every project: each original's SHA-256 and the bytes its
|
|
456
|
+
* proxy takes.
|
|
457
|
+
*/
|
|
458
|
+
listProxies(): Promise<KeptProxy[]>;
|
|
459
|
+
/**
|
|
460
|
+
* Removes the kept proxies of `hashes` (originals' SHA-256). This session lets go of its own
|
|
461
|
+
* first and refreshes the preview; a proxy still read after that (by the preview, for a source
|
|
462
|
+
* whose original is offline, by an export, or by another page of the origin) is left and listed
|
|
463
|
+
* in `inUse`.
|
|
464
|
+
*/
|
|
465
|
+
removeProxies(hashes: Iterable<string>): Promise<ProxyRemoval>;
|
|
466
|
+
/**
|
|
467
|
+
* Whether this session holds the original media of asset `id` at the document's content revision;
|
|
468
|
+
* a proxy standing in for it does not count.
|
|
469
|
+
*/
|
|
470
|
+
hasOriginal(id: string): boolean;
|
|
471
|
+
/**
|
|
472
|
+
* Shows a composition node in the viewer instead of the composition's output, for preview only;
|
|
473
|
+
* `null` shows the outputs.
|
|
474
|
+
*/
|
|
475
|
+
setPreviewOutput(target: {
|
|
476
|
+
readonly compositionId: string;
|
|
477
|
+
readonly nodeId: string;
|
|
478
|
+
} | null): void;
|
|
479
|
+
/** The node {@link BrowserBridge.setPreviewOutput} shows, or `null`. */
|
|
480
|
+
readonly previewOutput: {
|
|
481
|
+
readonly compositionId: string;
|
|
482
|
+
readonly nodeId: string;
|
|
483
|
+
} | null;
|
|
484
|
+
/**
|
|
485
|
+
* Shows another animation of a dotLottie source, keeping its clips. Throws `EditorError`
|
|
486
|
+
* `unsupported_media` for another kind of source or an animation the package lacks.
|
|
487
|
+
*/
|
|
488
|
+
selectAnimation(id: string, animation: string): void;
|
|
489
|
+
/**
|
|
490
|
+
* Reads an OpenEXR source's linear RGB in `primaries`, overriding what the file declares; `null`
|
|
491
|
+
* goes back to the file's.
|
|
492
|
+
* Throws `EditorError` `unsupported_media` for a source whose primaries cannot be chosen.
|
|
493
|
+
*/
|
|
494
|
+
setLinearPrimaries(id: string, primaries: import("alpha2").LinearPrimaries | null): void;
|
|
495
|
+
/**
|
|
496
|
+
* Exports the document as it is now; later edits do not affect the job. The engine's asset
|
|
497
|
+
* decisions must be loaded: call {@link BrowserBridge.conform} first, or pass `assetDecisions`.
|
|
498
|
+
*
|
|
499
|
+
* Throws synchronously when the bridge is disposed (`disposed`), another export runs
|
|
500
|
+
* (`export_busy`), `frameRate` is not one the engine reads (`invalid_frame_rate`), the asset
|
|
501
|
+
* decisions are not loaded (`conform_pending`), the media is not ready (`ConformError`), or the
|
|
502
|
+
* document does not compile. Everything later is reported through the job's `result`.
|
|
503
|
+
*/
|
|
504
|
+
startExport(options?: BrowserExportOptions): ExportJob;
|
|
505
|
+
/**
|
|
506
|
+
* Cancels exports and imports, stops playback, and releases the preview, audio, and every
|
|
507
|
+
* runtime resource. Idempotent; later calls reject or throw `disposed`.
|
|
508
|
+
*/
|
|
509
|
+
dispose(): Promise<void>;
|
|
510
|
+
}
|
|
511
|
+
/** Options of `createWorkerPreview`. */
|
|
512
|
+
export interface WorkerPreviewOptions {
|
|
513
|
+
/** `seek` returns the rendered frame as an `ImageBitmap`, default `false`. */
|
|
514
|
+
readonly bitmapOutput?: boolean;
|
|
515
|
+
/** Initial size of the worker's own canvas when no `canvas` is given, default 16x16. */
|
|
516
|
+
readonly width?: number;
|
|
517
|
+
readonly height?: number;
|
|
518
|
+
/** Tags every message; replies for another session are dropped. A random UUID by default. */
|
|
519
|
+
readonly sessionId?: string;
|
|
520
|
+
readonly runtimeAssets?: RuntimeAssets;
|
|
521
|
+
/** A canvas to render into, transferred to the worker. */
|
|
522
|
+
readonly canvas?: OffscreenCanvas;
|
|
523
|
+
}
|
|
524
|
+
/** The main-thread side of a preview renderer running in a worker. */
|
|
525
|
+
export interface WorkerPreview {
|
|
526
|
+
/** Settles when the worker's engine has started; rejects if it cannot start. */
|
|
527
|
+
readonly ready: Promise<void>;
|
|
528
|
+
/**
|
|
529
|
+
* Loads `project`. `assets` are the runtime assets it adds or changes; `keep` names those the
|
|
530
|
+
* previous call sent that stay as they were, so their decoders stay open. Any other asset is
|
|
531
|
+
* released. `fonts: null` keeps the registered fonts.
|
|
532
|
+
*/
|
|
533
|
+
replaceProject(project: Project, revision: number, assets?: readonly RuntimeAsset[], fonts?: readonly RuntimeFont[] | null, keep?: readonly string[]): Promise<void>;
|
|
534
|
+
/**
|
|
535
|
+
* Renders the frame at `tick`. `rendered` is `false` for an empty project or a render
|
|
536
|
+
* cancelled meanwhile. `bitmap` is present only with `bitmapOutput`, and the caller owns it.
|
|
537
|
+
*/
|
|
538
|
+
seek(tick: number): Promise<{
|
|
539
|
+
rendered: boolean;
|
|
540
|
+
bitmap?: ImageBitmap;
|
|
541
|
+
diagnostics: Readonly<Record<string, number>>;
|
|
542
|
+
}>;
|
|
543
|
+
/** Mixes `frames` project-rate samples from `startSample`, one array per channel. */
|
|
544
|
+
mix(startSample: number, frames: number): Promise<Float32Array[]>;
|
|
545
|
+
/** Drops the render in flight; its `seek` resolves with `rendered: false`. */
|
|
546
|
+
cancel(): Promise<void>;
|
|
547
|
+
/** Releases the worker's engine and terminates the worker. Idempotent. */
|
|
548
|
+
dispose(): Promise<void>;
|
|
549
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Serves the editor's preview protocol (`createWorkerPreview`) on `scope`, a dedicated worker's
|
|
3
|
+
* global. Importing this module has no effect until this is called. Requests run one at a
|
|
4
|
+
* time in arrival order. A `cancel` or `replace-project` stops the render in flight and drops the
|
|
5
|
+
* seeks that arrived before it, not those sent after it. Requests from another session or an
|
|
6
|
+
* older revision are answered with an error.
|
|
7
|
+
* @param {import("./types.js").EditorWorkerScope} scope
|
|
8
|
+
* @returns {{ dispose(): Promise<void> }} Waits for queued requests, releases the engine and
|
|
9
|
+
* decoders, and detaches the message handler.
|
|
10
|
+
*/
|
|
11
|
+
export function installEditorWorker(scope: import("./types.js").EditorWorkerScope): {
|
|
12
|
+
dispose(): Promise<void>;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Drives a preview renderer in `worker`, which must run `installEditorWorker`. The caller owns
|
|
16
|
+
* the worker; `dispose()` terminates it. This port renders picture and mixes audio blocks only:
|
|
17
|
+
* it is separate from a bridge's main-thread audio output. Every call waits for `ready`, which
|
|
18
|
+
* rejects if the worker cannot start its engine; a disposed preview rejects new calls, and a
|
|
19
|
+
* worker error rejects every pending one.
|
|
20
|
+
* @param {Worker} worker
|
|
21
|
+
* @param {import("./types.js").WorkerPreviewOptions} [options]
|
|
22
|
+
* @returns {import("./types.js").WorkerPreview}
|
|
23
|
+
*/
|
|
24
|
+
export function createWorkerPreview(worker: Worker, { sessionId, runtimeAssets, canvas, bitmapOutput, width, height, }?: import("./types.js").WorkerPreviewOptions): import("./types.js").WorkerPreview;
|