termcut 0.6.3 → 0.7.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/README.md +17 -1
- package/package.json +1 -1
- package/scripts/build-themes.ts +10 -6
- package/src/browser.ts +3 -3
- package/src/cast.ts +2 -0
- package/src/cli.ts +137 -27
- package/src/config.ts +35 -2
- package/src/diff.ts +3 -13
- package/src/duration.ts +4 -8
- package/src/edit.ts +188 -0
- package/src/export/frames.ts +18 -1
- package/src/export/html.ts +6 -2
- package/src/export/svg.ts +31 -3
- package/src/index.ts +6 -2
- package/src/keylabels.ts +28 -27
- package/src/keys.ts +18 -18
- package/src/live.ts +18 -7
- package/src/loop.ts +14 -9
- package/src/presets.ts +2 -2
- package/src/publish.ts +19 -21
- package/src/recorder.ts +22 -5
- package/src/render.ts +69 -2
- package/src/renderer/encoder.ts +49 -11
- package/src/renderer/generated/page.js +1 -1
- package/src/renderer/page-entry.ts +18 -6
- package/src/renderer/page.ts +99 -3
- package/src/renderer/png.ts +189 -0
- package/src/renderer/webview.ts +37 -11
- package/src/screen.ts +9 -3
- package/src/scriptgen.ts +31 -30
- package/src/themes.ts +9 -11
- package/src/timeline.ts +21 -5
- package/src/types.ts +63 -2
- package/src/video.ts +15 -12
package/src/video.ts
CHANGED
|
@@ -3,8 +3,8 @@ import path from "node:path";
|
|
|
3
3
|
import { readCast, writeCast } from "./cast";
|
|
4
4
|
import { applyOverrides, resolveConfig } from "./config";
|
|
5
5
|
import { record } from "./recorder";
|
|
6
|
-
import {
|
|
7
|
-
import type { CastEvent, RecordOptions, Recording, RenderOptions, ResolvedConfig, Script, VideoConfig } from "./types";
|
|
6
|
+
import { renderSelection, type RenderResult } from "./render";
|
|
7
|
+
import type { CastEvent, ClipSelection, RecordOptions, Recording, RenderOptions, ResolvedConfig, Script, VideoConfig } from "./types";
|
|
8
8
|
|
|
9
9
|
export interface VideoRecordOptions extends RecordOptions {
|
|
10
10
|
/** Re-record even if a cached cast matches. */
|
|
@@ -69,8 +69,7 @@ export class Video {
|
|
|
69
69
|
if (!(await file.exists())) return undefined;
|
|
70
70
|
const hasher = new Bun.CryptoHasher("sha256");
|
|
71
71
|
hasher.update(await file.arrayBuffer());
|
|
72
|
-
const subset
|
|
73
|
-
for (const key of RECORD_KEYS) subset[key] = this.config[key];
|
|
72
|
+
const subset = Object.fromEntries(RECORD_KEYS.map((key) => [key, this.config[key]]));
|
|
74
73
|
hasher.update(JSON.stringify(subset));
|
|
75
74
|
return hasher.digest("hex");
|
|
76
75
|
}
|
|
@@ -113,7 +112,7 @@ export class Video {
|
|
|
113
112
|
async render(recording?: Recording, opts: RenderOptions = {}): Promise<RenderResult> {
|
|
114
113
|
const rec = recording ?? (await readCast(this.config.cast));
|
|
115
114
|
const config = applyOverrides(this.config, opts.overrides);
|
|
116
|
-
return
|
|
115
|
+
return renderSelection(rec, config, opts.clip, opts.onProgress);
|
|
117
116
|
}
|
|
118
117
|
|
|
119
118
|
async run(opts: RunOptions = {}): Promise<RunResult> {
|
|
@@ -132,8 +131,9 @@ export function defineVideo(config: VideoConfig, script: Script): Video {
|
|
|
132
131
|
return new Video(config, script);
|
|
133
132
|
}
|
|
134
133
|
|
|
135
|
-
|
|
136
|
-
|
|
134
|
+
/** True for a `defineVideo()` result — checked by brand, so a Video built by another copy of tcut still counts. */
|
|
135
|
+
export function isVideo<T>(value: T): value is T & Video {
|
|
136
|
+
return value instanceof Object && "__bunVideo" in value && value.__bunVideo === true;
|
|
137
137
|
}
|
|
138
138
|
|
|
139
139
|
/** Render an existing .cast file (from tcut or asciinema) with the given settings. */
|
|
@@ -141,11 +141,14 @@ export async function renderCast(
|
|
|
141
141
|
castFile: string,
|
|
142
142
|
overrides: Partial<VideoConfig> & { output?: string | string[] },
|
|
143
143
|
onProgress?: RenderOptions["onProgress"],
|
|
144
|
+
clip?: ClipSelection,
|
|
144
145
|
): Promise<RenderResult> {
|
|
145
146
|
const rec = await readCast(castFile);
|
|
146
|
-
const
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
147
|
+
const config = applyOverrides(castConfig(rec, castFile, overrides.output), overrides);
|
|
148
|
+
return renderSelection(rec, config, clip, onProgress);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/** The config a cast should be rendered with: the one recorded in its header, or sensible defaults for foreign casts. */
|
|
152
|
+
export function castConfig(rec: Recording, castFile: string, output?: string | string[]): ResolvedConfig {
|
|
153
|
+
return rec.header.bunVideo ?? resolveConfig({ output: output ?? castFile.replace(/\.cast$/, "") + ".mp4", cols: rec.header.width, rows: rec.header.height });
|
|
151
154
|
}
|