videowright 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/README.md +91 -0
- package/dist/cli/argv.d.ts +28 -0
- package/dist/cli/argv.d.ts.map +1 -0
- package/dist/cli/argv.js +115 -0
- package/dist/cli/argv.js.map +1 -0
- package/dist/cli/bin.d.ts +7 -0
- package/dist/cli/bin.d.ts.map +1 -0
- package/dist/cli/bin.js +10 -0
- package/dist/cli/bin.js.map +1 -0
- package/dist/cli/dev.d.ts +19 -0
- package/dist/cli/dev.d.ts.map +1 -0
- package/dist/cli/dev.js +104 -0
- package/dist/cli/dev.js.map +1 -0
- package/dist/cli/discover.d.ts +29 -0
- package/dist/cli/discover.d.ts.map +1 -0
- package/dist/cli/discover.js +104 -0
- package/dist/cli/discover.js.map +1 -0
- package/dist/cli/discover_project.d.ts +29 -0
- package/dist/cli/discover_project.d.ts.map +1 -0
- package/dist/cli/discover_project.js +108 -0
- package/dist/cli/discover_project.js.map +1 -0
- package/dist/cli/errors.d.ts +10 -0
- package/dist/cli/errors.d.ts.map +1 -0
- package/dist/cli/errors.js +13 -0
- package/dist/cli/errors.js.map +1 -0
- package/dist/cli/ffmpeg.d.ts +57 -0
- package/dist/cli/ffmpeg.d.ts.map +1 -0
- package/dist/cli/ffmpeg.js +122 -0
- package/dist/cli/ffmpeg.js.map +1 -0
- package/dist/cli/index.d.ts +7 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +152 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/playwright_check.d.ts +44 -0
- package/dist/cli/playwright_check.d.ts.map +1 -0
- package/dist/cli/playwright_check.js +20 -0
- package/dist/cli/playwright_check.js.map +1 -0
- package/dist/cli/prompt.d.ts +13 -0
- package/dist/cli/prompt.d.ts.map +1 -0
- package/dist/cli/prompt.js +47 -0
- package/dist/cli/prompt.js.map +1 -0
- package/dist/cli/render.d.ts +60 -0
- package/dist/cli/render.d.ts.map +1 -0
- package/dist/cli/render.js +471 -0
- package/dist/cli/render.js.map +1 -0
- package/dist/cli/script_cmd.d.ts +26 -0
- package/dist/cli/script_cmd.d.ts.map +1 -0
- package/dist/cli/script_cmd.js +88 -0
- package/dist/cli/script_cmd.js.map +1 -0
- package/dist/cli/time_shim.d.ts +44 -0
- package/dist/cli/time_shim.d.ts.map +1 -0
- package/dist/cli/time_shim.js +390 -0
- package/dist/cli/time_shim.js.map +1 -0
- package/dist/cli/ts_loader.d.ts +28 -0
- package/dist/cli/ts_loader.d.ts.map +1 -0
- package/dist/cli/ts_loader.js +95 -0
- package/dist/cli/ts_loader.js.map +1 -0
- package/dist/cli/vite_helpers.d.ts +62 -0
- package/dist/cli/vite_helpers.d.ts.map +1 -0
- package/dist/cli/vite_helpers.js +273 -0
- package/dist/cli/vite_helpers.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -0
- package/dist/player/hash_router.d.ts +23 -0
- package/dist/player/hash_router.d.ts.map +1 -0
- package/dist/player/hash_router.js +49 -0
- package/dist/player/hash_router.js.map +1 -0
- package/dist/player/hud.d.ts +33 -0
- package/dist/player/hud.d.ts.map +1 -0
- package/dist/player/hud.js +357 -0
- package/dist/player/hud.js.map +1 -0
- package/dist/player/index.d.ts +123 -0
- package/dist/player/index.d.ts.map +1 -0
- package/dist/player/index.js +848 -0
- package/dist/player/index.js.map +1 -0
- package/dist/player/input.d.ts +14 -0
- package/dist/player/input.d.ts.map +1 -0
- package/dist/player/input.js +90 -0
- package/dist/player/input.js.map +1 -0
- package/dist/player/slot.d.ts +22 -0
- package/dist/player/slot.d.ts.map +1 -0
- package/dist/player/slot.js +43 -0
- package/dist/player/slot.js.map +1 -0
- package/dist/player/transitions/cut.d.ts +7 -0
- package/dist/player/transitions/cut.d.ts.map +1 -0
- package/dist/player/transitions/cut.js +9 -0
- package/dist/player/transitions/cut.js.map +1 -0
- package/dist/player/transitions/fade.d.ts +7 -0
- package/dist/player/transitions/fade.d.ts.map +1 -0
- package/dist/player/transitions/fade.js +18 -0
- package/dist/player/transitions/fade.js.map +1 -0
- package/dist/player/transitions/index.d.ts +4 -0
- package/dist/player/transitions/index.d.ts.map +1 -0
- package/dist/player/transitions/index.js +4 -0
- package/dist/player/transitions/index.js.map +1 -0
- package/dist/player/transitions/slide.d.ts +6 -0
- package/dist/player/transitions/slide.d.ts.map +1 -0
- package/dist/player/transitions/slide.js +35 -0
- package/dist/player/transitions/slide.js.map +1 -0
- package/dist/script/index.d.ts +2 -0
- package/dist/script/index.d.ts.map +1 -0
- package/dist/script/index.js +2 -0
- package/dist/script/index.js.map +1 -0
- package/dist/script/script.d.ts +10 -0
- package/dist/script/script.d.ts.map +1 -0
- package/dist/script/script.js +41 -0
- package/dist/script/script.js.map +1 -0
- package/dist/segment/SegmentRunner.d.ts +52 -0
- package/dist/segment/SegmentRunner.d.ts.map +1 -0
- package/dist/segment/SegmentRunner.js +187 -0
- package/dist/segment/SegmentRunner.js.map +1 -0
- package/dist/segment/defineConfig.d.ts +6 -0
- package/dist/segment/defineConfig.d.ts.map +1 -0
- package/dist/segment/defineConfig.js +7 -0
- package/dist/segment/defineConfig.js.map +1 -0
- package/dist/segment/defineSegment.d.ts +7 -0
- package/dist/segment/defineSegment.d.ts.map +1 -0
- package/dist/segment/defineSegment.js +25 -0
- package/dist/segment/defineSegment.js.map +1 -0
- package/dist/segment/index.d.ts +5 -0
- package/dist/segment/index.d.ts.map +1 -0
- package/dist/segment/index.js +4 -0
- package/dist/segment/index.js.map +1 -0
- package/dist/timeline/index.d.ts +73 -0
- package/dist/timeline/index.d.ts.map +1 -0
- package/dist/timeline/index.js +142 -0
- package/dist/timeline/index.js.map +1 -0
- package/dist/timeline/loadAudioTrack.d.ts +18 -0
- package/dist/timeline/loadAudioTrack.d.ts.map +1 -0
- package/dist/timeline/loadAudioTrack.js +44 -0
- package/dist/timeline/loadAudioTrack.js.map +1 -0
- package/dist/timeline/loadVoiceover.d.ts +18 -0
- package/dist/timeline/loadVoiceover.d.ts.map +1 -0
- package/dist/timeline/loadVoiceover.js +38 -0
- package/dist/timeline/loadVoiceover.js.map +1 -0
- package/dist/timeline/resolveTiming.d.ts +28 -0
- package/dist/timeline/resolveTiming.d.ts.map +1 -0
- package/dist/timeline/resolveTiming.js +63 -0
- package/dist/timeline/resolveTiming.js.map +1 -0
- package/dist/timeline/validateTiming.d.ts +29 -0
- package/dist/timeline/validateTiming.d.ts.map +1 -0
- package/dist/timeline/validateTiming.js +62 -0
- package/dist/timeline/validateTiming.js.map +1 -0
- package/dist/types.d.ts +216 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +6 -0
- package/dist/types.js.map +1 -0
- package/package.json +47 -0
- package/skill/SKILL.md +64 -0
- package/skill/assets/hello_world/PLAN.md +31 -0
- package/skill/assets/hello_world/README.md +27 -0
- package/skill/assets/hello_world/audio/audio_plan.md +14 -0
- package/skill/assets/hello_world/segments/hello_intro.ts +69 -0
- package/skill/assets/hello_world/segments/hello_outro.ts +71 -0
- package/skill/assets/hello_world/timeline.ts +15 -0
- package/skill/assets/hello_world/voiceover_script/script.md +10 -0
- package/skill/assets/install/package.json +10 -0
- package/skill/assets/install/tsconfig.json +23 -0
- package/skill/assets/styles/editorial-mono/STYLE.md +124 -0
- package/skill/assets/styles/editorial-mono/brand.md +85 -0
- package/skill/assets/styles/editorial-mono/reference/animations.jsx +752 -0
- package/skill/assets/styles/editorial-mono/reference/scenes.html +563 -0
- package/skill/assets/styles/editorial-mono/sample/bullet.ts +101 -0
- package/skill/assets/styles/editorial-mono/sample/content.ts +104 -0
- package/skill/assets/styles/editorial-mono/sample/cta.ts +113 -0
- package/skill/assets/styles/editorial-mono/sample/feature.ts +111 -0
- package/skill/assets/styles/editorial-mono/sample/grid.ts +97 -0
- package/skill/assets/styles/editorial-mono/sample/kinetic.ts +96 -0
- package/skill/assets/styles/editorial-mono/sample/section.ts +101 -0
- package/skill/assets/styles/editorial-mono/sample/stat.ts +128 -0
- package/skill/assets/styles/editorial-mono/sample/title.ts +97 -0
- package/skill/assets/styles/editorial-mono/sample/ui-showcase.ts +159 -0
- package/skill/assets/styles/editorial-mono/tokens.css +44 -0
- package/skill/assets/styles/iso-diagram/STYLE.md +109 -0
- package/skill/assets/styles/iso-diagram/brand.md +32 -0
- package/skill/assets/styles/iso-diagram/reference/animations.jsx +673 -0
- package/skill/assets/styles/iso-diagram/reference/scenes.html +427 -0
- package/skill/assets/styles/iso-diagram/sample/bullet.ts +144 -0
- package/skill/assets/styles/iso-diagram/sample/content.ts +192 -0
- package/skill/assets/styles/iso-diagram/sample/cta.ts +162 -0
- package/skill/assets/styles/iso-diagram/sample/feature.ts +205 -0
- package/skill/assets/styles/iso-diagram/sample/grid.ts +181 -0
- package/skill/assets/styles/iso-diagram/sample/kinetic.ts +102 -0
- package/skill/assets/styles/iso-diagram/sample/section.ts +149 -0
- package/skill/assets/styles/iso-diagram/sample/stat.ts +164 -0
- package/skill/assets/styles/iso-diagram/sample/title.ts +173 -0
- package/skill/assets/styles/iso-diagram/sample/ui-showcase.ts +162 -0
- package/skill/assets/styles/iso-diagram/tokens.css +40 -0
- package/skill/assets/styles/motion-engineering/STYLE.md +106 -0
- package/skill/assets/styles/motion-engineering/brand.md +29 -0
- package/skill/assets/styles/motion-engineering/reference/animations.jsx +673 -0
- package/skill/assets/styles/motion-engineering/reference/scenes.html +513 -0
- package/skill/assets/styles/motion-engineering/sample/bullet.ts +176 -0
- package/skill/assets/styles/motion-engineering/sample/content.ts +228 -0
- package/skill/assets/styles/motion-engineering/sample/cta.ts +209 -0
- package/skill/assets/styles/motion-engineering/sample/feature.ts +299 -0
- package/skill/assets/styles/motion-engineering/sample/grid.ts +190 -0
- package/skill/assets/styles/motion-engineering/sample/kinetic.ts +159 -0
- package/skill/assets/styles/motion-engineering/sample/section.ts +196 -0
- package/skill/assets/styles/motion-engineering/sample/stat.ts +230 -0
- package/skill/assets/styles/motion-engineering/sample/title.ts +219 -0
- package/skill/assets/styles/motion-engineering/sample/ui-showcase.ts +267 -0
- package/skill/assets/styles/motion-engineering/tokens.css +40 -0
- package/skill/assets/styles/neon-terminal/STYLE.md +105 -0
- package/skill/assets/styles/neon-terminal/brand.md +27 -0
- package/skill/assets/styles/neon-terminal/reference/animations.jsx +673 -0
- package/skill/assets/styles/neon-terminal/reference/scenes.html +387 -0
- package/skill/assets/styles/neon-terminal/sample/bullet.ts +113 -0
- package/skill/assets/styles/neon-terminal/sample/content.ts +117 -0
- package/skill/assets/styles/neon-terminal/sample/cta.ts +131 -0
- package/skill/assets/styles/neon-terminal/sample/feature.ts +112 -0
- package/skill/assets/styles/neon-terminal/sample/grid.ts +128 -0
- package/skill/assets/styles/neon-terminal/sample/kinetic.ts +105 -0
- package/skill/assets/styles/neon-terminal/sample/section.ts +96 -0
- package/skill/assets/styles/neon-terminal/sample/stat.ts +123 -0
- package/skill/assets/styles/neon-terminal/sample/title.ts +122 -0
- package/skill/assets/styles/neon-terminal/sample/ui-showcase.ts +127 -0
- package/skill/assets/styles/neon-terminal/tokens.css +39 -0
- package/skill/assets/styles/risograph/STYLE.md +110 -0
- package/skill/assets/styles/risograph/brand.md +26 -0
- package/skill/assets/styles/risograph/reference/animations.jsx +673 -0
- package/skill/assets/styles/risograph/reference/scenes.html +403 -0
- package/skill/assets/styles/risograph/sample/bullet.ts +124 -0
- package/skill/assets/styles/risograph/sample/content.ts +135 -0
- package/skill/assets/styles/risograph/sample/cta.ts +149 -0
- package/skill/assets/styles/risograph/sample/feature.ts +152 -0
- package/skill/assets/styles/risograph/sample/grid.ts +123 -0
- package/skill/assets/styles/risograph/sample/kinetic.ts +125 -0
- package/skill/assets/styles/risograph/sample/section.ts +130 -0
- package/skill/assets/styles/risograph/sample/stat.ts +145 -0
- package/skill/assets/styles/risograph/sample/title.ts +132 -0
- package/skill/assets/styles/risograph/sample/ui-showcase.ts +147 -0
- package/skill/assets/styles/risograph/tokens.css +39 -0
- package/skill/assets/styles/swiss-console/STYLE.md +107 -0
- package/skill/assets/styles/swiss-console/brand.md +37 -0
- package/skill/assets/styles/swiss-console/reference/animations.jsx +673 -0
- package/skill/assets/styles/swiss-console/reference/scenes.html +420 -0
- package/skill/assets/styles/swiss-console/sample/bullet.ts +122 -0
- package/skill/assets/styles/swiss-console/sample/content.ts +137 -0
- package/skill/assets/styles/swiss-console/sample/cta.ts +109 -0
- package/skill/assets/styles/swiss-console/sample/feature.ts +163 -0
- package/skill/assets/styles/swiss-console/sample/grid.ts +145 -0
- package/skill/assets/styles/swiss-console/sample/kinetic.ts +117 -0
- package/skill/assets/styles/swiss-console/sample/section.ts +127 -0
- package/skill/assets/styles/swiss-console/sample/stat.ts +148 -0
- package/skill/assets/styles/swiss-console/sample/title.ts +148 -0
- package/skill/assets/styles/swiss-console/sample/ui-showcase.ts +198 -0
- package/skill/assets/styles/swiss-console/tokens.css +39 -0
- package/skill/install/INSTALL.md +400 -0
- package/skill/references/audio/audio_plan.md +199 -0
- package/skill/references/audio/build.md +208 -0
- package/skill/references/audio/cue_template.md +219 -0
- package/skill/references/audio/ffmpeg_cookbook.md +267 -0
- package/skill/references/audio/music/music.md +171 -0
- package/skill/references/audio/music/providers/elevenlabs.md +170 -0
- package/skill/references/audio/music/providers/manual.md +140 -0
- package/skill/references/audio/music/providers/openverse.md +265 -0
- package/skill/references/audio/sfx/providers/elevenlabs.md +152 -0
- package/skill/references/audio/sfx/providers/manual.md +117 -0
- package/skill/references/audio/sfx/providers/openverse.md +243 -0
- package/skill/references/audio/sfx/sfx.md +149 -0
- package/skill/references/audio/styles.md +102 -0
- package/skill/references/audio/sync.md +237 -0
- package/skill/references/audio/voiceover/animation_sync.md +142 -0
- package/skill/references/audio/voiceover/provider_script.md +153 -0
- package/skill/references/audio/voiceover/providers/elevenlabs.md +288 -0
- package/skill/references/audio/voiceover/providers/manual.md +100 -0
- package/skill/references/audio/voiceover/script_writing.md +100 -0
- package/skill/references/audio/voiceover/style_intake.md +56 -0
- package/skill/references/audio/voiceover/sync_algorithm.md +167 -0
- package/skill/references/audio/voiceover.md +296 -0
- package/skill/references/audio.md +135 -0
- package/skill/references/authoring_segment.md +446 -0
- package/skill/references/create_or_edit_video.md +232 -0
- package/skill/references/dev_server.md +157 -0
- package/skill/references/export.md +145 -0
- package/skill/references/new_video.md +117 -0
- package/skill/references/project_structure.md +144 -0
- package/skill/references/setup.md +109 -0
- package/skill/references/setup_new_style.md +158 -0
- package/skill/references/styles.md +154 -0
- package/skill/references/testing.md +115 -0
- package/skill/references/types.md +240 -0
- package/src/cli/entry/components/copy_button.ts +42 -0
- package/src/cli/entry/components/download_modal.ts +204 -0
- package/src/cli/entry/components/empty_state.ts +55 -0
- package/src/cli/entry/components/hide_hud_tab.ts +37 -0
- package/src/cli/entry/components/icons.ts +31 -0
- package/src/cli/entry/components/top_bar.ts +69 -0
- package/src/cli/entry/components/video_card.ts +57 -0
- package/src/cli/entry/dev_frame.ts +189 -0
- package/src/cli/entry/entry_index.ts +16 -0
- package/src/cli/entry/entry_video.ts +24 -0
- package/src/cli/entry/index.html +12 -0
- package/src/cli/entry/parse_slug.ts +14 -0
- package/src/cli/entry/render.html +17 -0
- package/src/cli/entry/render_entry.ts +121 -0
- package/src/cli/entry/styles/base.css +45 -0
- package/src/cli/entry/styles/components.css +605 -0
- package/src/cli/entry/styles/tokens.css +44 -0
- package/src/cli/entry/video.html +22 -0
- package/src/cli/entry/views/homepage.ts +66 -0
- package/src/cli/entry/views/video_view.ts +286 -0
- package/src/cli/entry/virtual.d.ts +8 -0
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Thrown when a segment's play() is interrupted by unmount.
|
|
3
|
+
* Framework code catches this to cleanly unwind segment teardown.
|
|
4
|
+
*
|
|
5
|
+
* Extends DOMException so that `isAbortError` can match both this class
|
|
6
|
+
* and the native AbortError raised by fetch/AbortController in browsers.
|
|
7
|
+
* The `(message, name)` constructor signature is supported in all modern
|
|
8
|
+
* browsers and jsdom (our test runner); Node 17+ also supports it.
|
|
9
|
+
*/
|
|
10
|
+
export class SegmentAbortError extends DOMException {
|
|
11
|
+
constructor() {
|
|
12
|
+
super("Segment aborted", "AbortError");
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
/** Type guard: true for SegmentAbortError or any DOMException with name "AbortError". */
|
|
16
|
+
export function isAbortError(e) {
|
|
17
|
+
return e instanceof DOMException && e.name === "AbortError";
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Per-mount wrapper around a Segment. Owns beat counter, resolver queue,
|
|
21
|
+
* abort controller, and produces the PlayerContext for lifecycle methods.
|
|
22
|
+
*
|
|
23
|
+
* Internal to the library -- not exported from the public barrel.
|
|
24
|
+
*/
|
|
25
|
+
export class SegmentRunner {
|
|
26
|
+
segment;
|
|
27
|
+
mode;
|
|
28
|
+
resolvers = [];
|
|
29
|
+
beatCounter = 0;
|
|
30
|
+
seekBeatsRemaining;
|
|
31
|
+
abortCtrl = new AbortController();
|
|
32
|
+
mountedAt = 0;
|
|
33
|
+
_playPromise = null;
|
|
34
|
+
state = "created";
|
|
35
|
+
constructor(segment, opts) {
|
|
36
|
+
this.segment = segment;
|
|
37
|
+
this.mode = opts.mode;
|
|
38
|
+
this.seekBeatsRemaining = opts.seekBeats ?? 0;
|
|
39
|
+
}
|
|
40
|
+
async mount(el) {
|
|
41
|
+
if (this.state !== "created") {
|
|
42
|
+
throw new Error("SegmentRunner: already mounted");
|
|
43
|
+
}
|
|
44
|
+
this.mountedAt = performance.now();
|
|
45
|
+
if (this.segment.mount) {
|
|
46
|
+
await this.segment.mount(el, this.makeContext());
|
|
47
|
+
}
|
|
48
|
+
this.state = "mounted";
|
|
49
|
+
}
|
|
50
|
+
startPlay() {
|
|
51
|
+
if (this.state !== "mounted") {
|
|
52
|
+
throw new Error("SegmentRunner: not mounted");
|
|
53
|
+
}
|
|
54
|
+
this.state = "playing";
|
|
55
|
+
this._playPromise = this.segment
|
|
56
|
+
.play(this.makeContext())
|
|
57
|
+
.catch((e) => {
|
|
58
|
+
// Re-throw non-abort errors; swallow AbortError so play()
|
|
59
|
+
// resolves cleanly on unmount-triggered teardown.
|
|
60
|
+
if (!isAbortError(e))
|
|
61
|
+
throw e;
|
|
62
|
+
})
|
|
63
|
+
.finally(() => {
|
|
64
|
+
if (this.state !== "unmounted") {
|
|
65
|
+
this.state = "done";
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
return this._playPromise;
|
|
69
|
+
}
|
|
70
|
+
triggerNext() {
|
|
71
|
+
if (this.segment.next) {
|
|
72
|
+
const consumed = this.segment.next();
|
|
73
|
+
if (consumed === true) {
|
|
74
|
+
this.beatCounter++;
|
|
75
|
+
return true;
|
|
76
|
+
}
|
|
77
|
+
if (consumed === false)
|
|
78
|
+
return false;
|
|
79
|
+
// undefined -> fall through to default
|
|
80
|
+
}
|
|
81
|
+
return this.defaultNext();
|
|
82
|
+
}
|
|
83
|
+
triggerPrev() {
|
|
84
|
+
if (this.segment.prev) {
|
|
85
|
+
const consumed = this.segment.prev();
|
|
86
|
+
if (consumed === true)
|
|
87
|
+
return true;
|
|
88
|
+
}
|
|
89
|
+
return false;
|
|
90
|
+
}
|
|
91
|
+
unmount() {
|
|
92
|
+
if (this.state === "unmounted")
|
|
93
|
+
return;
|
|
94
|
+
this.abortCtrl.abort();
|
|
95
|
+
if (this.segment.unmount) {
|
|
96
|
+
try {
|
|
97
|
+
this.segment.unmount();
|
|
98
|
+
}
|
|
99
|
+
catch (e) {
|
|
100
|
+
console.error("unmount() threw", e);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
// Drain pending resolvers with AbortError so play() unwinds cleanly
|
|
104
|
+
const abortErr = new SegmentAbortError();
|
|
105
|
+
while (this.resolvers.length) {
|
|
106
|
+
const r = this.resolvers.shift();
|
|
107
|
+
if (r)
|
|
108
|
+
r.reject(abortErr);
|
|
109
|
+
}
|
|
110
|
+
this.state = "unmounted";
|
|
111
|
+
}
|
|
112
|
+
get currentBeat() {
|
|
113
|
+
return this.beatCounter;
|
|
114
|
+
}
|
|
115
|
+
get isDone() {
|
|
116
|
+
return this.state === "done";
|
|
117
|
+
}
|
|
118
|
+
get playPromise() {
|
|
119
|
+
return this._playPromise;
|
|
120
|
+
}
|
|
121
|
+
get currentState() {
|
|
122
|
+
return this.state;
|
|
123
|
+
}
|
|
124
|
+
get elapsedSinceMount() {
|
|
125
|
+
return this.mountedAt > 0 ? performance.now() - this.mountedAt : 0;
|
|
126
|
+
}
|
|
127
|
+
// ---- Private -----
|
|
128
|
+
defaultNext() {
|
|
129
|
+
if (this.resolvers.length === 0)
|
|
130
|
+
return false;
|
|
131
|
+
const r = this.resolvers.shift();
|
|
132
|
+
if (r) {
|
|
133
|
+
this.beatCounter++;
|
|
134
|
+
r.resolve();
|
|
135
|
+
}
|
|
136
|
+
return true;
|
|
137
|
+
}
|
|
138
|
+
makeContext() {
|
|
139
|
+
return {
|
|
140
|
+
waitForNext: () => {
|
|
141
|
+
if (this.seekBeatsRemaining > 0) {
|
|
142
|
+
this.seekBeatsRemaining--;
|
|
143
|
+
this.beatCounter++;
|
|
144
|
+
return Promise.resolve();
|
|
145
|
+
}
|
|
146
|
+
return new Promise((resolve, reject) => {
|
|
147
|
+
if (this.state === "unmounted") {
|
|
148
|
+
reject(new SegmentAbortError());
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
this.resolvers.push({ resolve, reject });
|
|
152
|
+
});
|
|
153
|
+
},
|
|
154
|
+
hold: (ms) => {
|
|
155
|
+
// Both modes use real setTimeout. In render mode, the JS time shim
|
|
156
|
+
// virtualizes setTimeout so it fires when the driver advances the
|
|
157
|
+
// virtual clock, giving deterministic behavior.
|
|
158
|
+
return new Promise((resolve, reject) => {
|
|
159
|
+
if (this.abortCtrl.signal.aborted) {
|
|
160
|
+
reject(new SegmentAbortError());
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
const onAbort = () => {
|
|
164
|
+
clearTimeout(t);
|
|
165
|
+
reject(new SegmentAbortError());
|
|
166
|
+
};
|
|
167
|
+
const t = setTimeout(() => {
|
|
168
|
+
this.abortCtrl.signal.removeEventListener("abort", onAbort);
|
|
169
|
+
resolve();
|
|
170
|
+
}, ms);
|
|
171
|
+
this.abortCtrl.signal.addEventListener("abort", onAbort, {
|
|
172
|
+
once: true,
|
|
173
|
+
});
|
|
174
|
+
});
|
|
175
|
+
},
|
|
176
|
+
signal: this.abortCtrl.signal,
|
|
177
|
+
mode: this.mode,
|
|
178
|
+
clock: () => {
|
|
179
|
+
// Both modes use performance.now(). In render mode, the JS time
|
|
180
|
+
// shim virtualizes performance.now() so this returns deterministic
|
|
181
|
+
// virtual time.
|
|
182
|
+
return performance.now() - this.mountedAt;
|
|
183
|
+
},
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
//# sourceMappingURL=SegmentRunner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SegmentRunner.js","sourceRoot":"","sources":["../../src/segment/SegmentRunner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"defineConfig.d.ts","sourceRoot":"","sources":["../../src/segment/defineConfig.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAE1C;;GAEG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEnD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"defineConfig.js","sourceRoot":"","sources":["../../src/segment/defineConfig.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,UAAU,YAAY,CAAC,MAAc;IAC1C,OAAO,MAAM,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type Segment, type SegmentSpec } from "../types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Author a segment with strict typing and brand validation.
|
|
4
|
+
* Runtime guards cover JS consumers; TS strict catches at compile time.
|
|
5
|
+
*/
|
|
6
|
+
export declare function defineSegment(spec: SegmentSpec): Segment;
|
|
7
|
+
//# sourceMappingURL=defineSegment.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"defineSegment.d.ts","sourceRoot":"","sources":["../../src/segment/defineSegment.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,KAAK,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,aAAa,CAAC;AAE5E;;;GAGG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAsBxD"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { SEGMENT_BRAND } from "../types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Author a segment with strict typing and brand validation.
|
|
4
|
+
* Runtime guards cover JS consumers; TS strict catches at compile time.
|
|
5
|
+
*/
|
|
6
|
+
export function defineSegment(spec) {
|
|
7
|
+
if (!spec.id)
|
|
8
|
+
throw new TypeError("defineSegment: id is required");
|
|
9
|
+
if (!spec.play)
|
|
10
|
+
throw new TypeError("defineSegment: play is required");
|
|
11
|
+
if (!spec.advances || !Array.isArray(spec.advances) || spec.advances.length === 0) {
|
|
12
|
+
throw new TypeError(`defineSegment: advances is required and must be a non-empty array (segment "${spec.id}")`);
|
|
13
|
+
}
|
|
14
|
+
for (let i = 0; i < spec.advances.length; i++) {
|
|
15
|
+
const v = spec.advances[i];
|
|
16
|
+
if (typeof v !== "number" || v <= 0 || !Number.isFinite(v)) {
|
|
17
|
+
throw new TypeError(`defineSegment: advances[${i}] must be a positive number (segment "${spec.id}", got ${v})`);
|
|
18
|
+
}
|
|
19
|
+
if (i > 0 && v <= spec.advances[i - 1]) {
|
|
20
|
+
throw new TypeError(`defineSegment: advances must be monotonically increasing (segment "${spec.id}", advances[${i}]=${v} <= advances[${i - 1}]=${spec.advances[i - 1]})`);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return Object.freeze({ ...spec, [SEGMENT_BRAND]: true });
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=defineSegment.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"defineSegment.js","sourceRoot":"","sources":["../../src/segment/defineSegment.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAkC,MAAM,aAAa,CAAC;AAE5E;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,IAAiB;IAC9C,IAAI,CAAC,IAAI,CAAC,EAAE;QAAE,MAAM,IAAI,SAAS,CAAC,+BAA+B,CAAC,CAAC;IACnE,IAAI,CAAC,IAAI,CAAC,IAAI;QAAE,MAAM,IAAI,SAAS,CAAC,iCAAiC,CAAC,CAAC;IACvE,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACnF,MAAM,IAAI,SAAS,CAClB,+EAA+E,IAAI,CAAC,EAAE,IAAI,CAC1F,CAAC;IACH,CAAC;IACD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC/C,MAAM,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;QAC3B,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;YAC5D,MAAM,IAAI,SAAS,CAClB,2BAA2B,CAAC,yCAAyC,IAAI,CAAC,EAAE,UAAU,CAAC,GAAG,CAC1F,CAAC;QACH,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;YACxC,MAAM,IAAI,SAAS,CAClB,sEAAsE,IAAI,CAAC,EAAE,eAAe,CAAC,KAAK,CAAC,gBAAgB,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CACpJ,CAAC;QACH,CAAC;IACF,CAAC;IACD,OAAO,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,IAAa,EAAE,CAAC,CAAC;AACnE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/segment/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,YAAY,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/segment/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import type { Config, ResolvedTimelineMeta, Segment, Timeline, Transition } from "../types.js";
|
|
2
|
+
export { resolveTiming } from "./resolveTiming.js";
|
|
3
|
+
export type { ResolvedTiming, ResolveTimingArgs, TimingSegment } from "./resolveTiming.js";
|
|
4
|
+
export type SegmentLoaderMap = Map<string, () => Promise<{
|
|
5
|
+
default: Segment;
|
|
6
|
+
}>>;
|
|
7
|
+
export type TransitionLoaderMap = Map<string, () => Promise<{
|
|
8
|
+
default: Transition;
|
|
9
|
+
}>>;
|
|
10
|
+
export type TimelineError = {
|
|
11
|
+
kind: "missing-segment";
|
|
12
|
+
segmentId: string;
|
|
13
|
+
timelineTitle: string;
|
|
14
|
+
} | {
|
|
15
|
+
kind: "missing-transition";
|
|
16
|
+
transitionName: string;
|
|
17
|
+
segmentId: string;
|
|
18
|
+
} | {
|
|
19
|
+
kind: "missing-title";
|
|
20
|
+
} | {
|
|
21
|
+
kind: "malformed-segment-path";
|
|
22
|
+
path: string;
|
|
23
|
+
};
|
|
24
|
+
export type TimelineValidationResult = {
|
|
25
|
+
ok: true;
|
|
26
|
+
timeline: Timeline;
|
|
27
|
+
} | {
|
|
28
|
+
ok: false;
|
|
29
|
+
errors: TimelineError[];
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* Build a segment id -> loader map from a Vite glob result.
|
|
33
|
+
* Input: Record<string, () => Promise<unknown>> from import.meta.glob('/segments/* /index.ts').
|
|
34
|
+
*/
|
|
35
|
+
export declare function buildSegmentLoaderMap(globResult: Record<string, () => Promise<unknown>>): SegmentLoaderMap;
|
|
36
|
+
/**
|
|
37
|
+
* Build a transition name -> loader map, combining built-ins with user-registered transitions.
|
|
38
|
+
*/
|
|
39
|
+
export declare function buildTransitionLoaderMap(config: Config): TransitionLoaderMap;
|
|
40
|
+
/**
|
|
41
|
+
* Validate a timeline against segment and transition loader maps.
|
|
42
|
+
* Returns ok:true with the timeline, or ok:false with accumulated errors.
|
|
43
|
+
*/
|
|
44
|
+
export declare function validateTimeline(timeline: Timeline, segmentLoaders: SegmentLoaderMap, transitionLoaders: TransitionLoaderMap): TimelineValidationResult;
|
|
45
|
+
export type AdvancesValidationResult = {
|
|
46
|
+
ok: true;
|
|
47
|
+
} | {
|
|
48
|
+
ok: false;
|
|
49
|
+
errors: string[];
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* Validate that all segments referenced by a timeline have valid `advances` arrays.
|
|
53
|
+
*
|
|
54
|
+
* Accepts a `Record<string, number[]>` mapping segment id to its advances array.
|
|
55
|
+
* This map is produced in the browser context (entry_video.ts / render_entry.ts)
|
|
56
|
+
* where segment modules are loaded via Vite and can import browser-only assets
|
|
57
|
+
* (CSS, JSON, images) that Node's tsImport cannot handle.
|
|
58
|
+
*
|
|
59
|
+
* Checks per segment:
|
|
60
|
+
* - `advances` is defined and non-empty.
|
|
61
|
+
* - `advances` is monotonically increasing.
|
|
62
|
+
* - All entries are positive numbers.
|
|
63
|
+
*/
|
|
64
|
+
export declare function validateSegmentAdvances(timeline: Timeline, advancesMap: Record<string, number[]>): AdvancesValidationResult;
|
|
65
|
+
/**
|
|
66
|
+
* Apply config defaults to timeline meta. Returns a new Timeline without mutating.
|
|
67
|
+
* Priority: timeline meta > config.defaults > hardcoded fallbacks.
|
|
68
|
+
* The returned meta is guaranteed to have resolution, fps, and aspectRatio set.
|
|
69
|
+
*/
|
|
70
|
+
export declare function applyMetaDefaults(timeline: Timeline, config: Config): Timeline & {
|
|
71
|
+
meta: ResolvedTimelineMeta;
|
|
72
|
+
};
|
|
73
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/timeline/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,oBAAoB,EAAE,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAM/F,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,YAAY,EAAE,cAAc,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAI3F,MAAM,MAAM,gBAAgB,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC,CAAC,CAAC;AAChF,MAAM,MAAM,mBAAmB,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,OAAO,CAAC;IAAE,OAAO,EAAE,UAAU,CAAA;CAAE,CAAC,CAAC,CAAC;AAItF,MAAM,MAAM,aAAa,GACtB;IAAE,IAAI,EAAE,iBAAiB,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,GACrE;IAAE,IAAI,EAAE,oBAAoB,CAAC;IAAC,cAAc,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,GACzE;IAAE,IAAI,EAAE,eAAe,CAAA;CAAE,GACzB;IAAE,IAAI,EAAE,wBAAwB,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAEpD,MAAM,MAAM,wBAAwB,GACjC;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,EAAE,QAAQ,CAAA;CAAE,GAChC;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,aAAa,EAAE,CAAA;CAAE,CAAC;AAQ1C;;;GAGG;AACH,wBAAgB,qBAAqB,CACpC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC,GAChD,gBAAgB,CAsBlB;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,MAAM,GAAG,mBAAmB,CA4B5E;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAC/B,QAAQ,EAAE,QAAQ,EAClB,cAAc,EAAE,gBAAgB,EAChC,iBAAiB,EAAE,mBAAmB,GACpC,wBAAwB,CAoC1B;AAID,MAAM,MAAM,wBAAwB,GAAG;IAAE,EAAE,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC;AAEtF;;;;;;;;;;;;GAYG;AACH,wBAAgB,uBAAuB,CACtC,QAAQ,EAAE,QAAQ,EAClB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,GACnC,wBAAwB,CA+B1B;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAChC,QAAQ,EAAE,QAAQ,EAClB,MAAM,EAAE,MAAM,GACZ,QAAQ,GAAG;IAAE,IAAI,EAAE,oBAAoB,CAAA;CAAE,CAW3C"}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
// Re-export browser-safe helpers only.
|
|
2
|
+
// Node-only helpers (loadVoiceover, loadAudioTrack, validateTiming, validateAudioTrack) are
|
|
3
|
+
// imported directly from their own modules by CLI code to avoid pulling
|
|
4
|
+
// node:fs into browser bundles.
|
|
5
|
+
export { resolveTiming } from "./resolveTiming.js";
|
|
6
|
+
// ---- Segment path regex ----
|
|
7
|
+
const SEGMENT_PATH_RE = /^\/segments\/([^/]+)\/index\.ts$/;
|
|
8
|
+
// ---- Functions ----
|
|
9
|
+
/**
|
|
10
|
+
* Build a segment id -> loader map from a Vite glob result.
|
|
11
|
+
* Input: Record<string, () => Promise<unknown>> from import.meta.glob('/segments/* /index.ts').
|
|
12
|
+
*/
|
|
13
|
+
export function buildSegmentLoaderMap(globResult) {
|
|
14
|
+
const map = new Map();
|
|
15
|
+
const warnings = [];
|
|
16
|
+
for (const path of Object.keys(globResult)) {
|
|
17
|
+
const m = path.match(SEGMENT_PATH_RE);
|
|
18
|
+
if (!m) {
|
|
19
|
+
warnings.push({ kind: "malformed-segment-path", path });
|
|
20
|
+
continue;
|
|
21
|
+
}
|
|
22
|
+
const id = m[1];
|
|
23
|
+
if (map.has(id)) {
|
|
24
|
+
throw new Error(`Duplicate segment id: ${id} (path: ${path})`);
|
|
25
|
+
}
|
|
26
|
+
map.set(id, globResult[path]);
|
|
27
|
+
}
|
|
28
|
+
if (warnings.length) {
|
|
29
|
+
console.warn("buildSegmentLoaderMap: some paths skipped", warnings);
|
|
30
|
+
}
|
|
31
|
+
return map;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Build a transition name -> loader map, combining built-ins with user-registered transitions.
|
|
35
|
+
*/
|
|
36
|
+
export function buildTransitionLoaderMap(config) {
|
|
37
|
+
const map = new Map();
|
|
38
|
+
// Built-ins
|
|
39
|
+
map.set("cut", () => import("../player/transitions/cut.js"));
|
|
40
|
+
map.set("fade", () => import("../player/transitions/fade.js"));
|
|
41
|
+
map.set("slideLeft", () => import("../player/transitions/slide.js").then((m) => ({ default: m.slideLeft })));
|
|
42
|
+
map.set("slideRight", () => import("../player/transitions/slide.js").then((m) => ({ default: m.slideRight })));
|
|
43
|
+
map.set("slideUp", () => import("../player/transitions/slide.js").then((m) => ({ default: m.slideUp })));
|
|
44
|
+
map.set("slideDown", () => import("../player/transitions/slide.js").then((m) => ({ default: m.slideDown })));
|
|
45
|
+
// User-registered
|
|
46
|
+
for (const [name, loader] of Object.entries(config.transitions ?? {})) {
|
|
47
|
+
if (map.has(name)) {
|
|
48
|
+
console.warn(`Custom transition "${name}" shadows a built-in.`);
|
|
49
|
+
}
|
|
50
|
+
map.set(name, loader);
|
|
51
|
+
}
|
|
52
|
+
return map;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Validate a timeline against segment and transition loader maps.
|
|
56
|
+
* Returns ok:true with the timeline, or ok:false with accumulated errors.
|
|
57
|
+
*/
|
|
58
|
+
export function validateTimeline(timeline, segmentLoaders, transitionLoaders) {
|
|
59
|
+
const errors = [];
|
|
60
|
+
if (!timeline.meta.title || timeline.meta.title.trim() === "") {
|
|
61
|
+
errors.push({ kind: "missing-title" });
|
|
62
|
+
}
|
|
63
|
+
const titleForErrors = timeline.meta.title && timeline.meta.title.trim() !== "" ? timeline.meta.title : "(untitled)";
|
|
64
|
+
for (const entry of timeline.segments) {
|
|
65
|
+
if (!segmentLoaders.has(entry.id)) {
|
|
66
|
+
errors.push({
|
|
67
|
+
kind: "missing-segment",
|
|
68
|
+
segmentId: entry.id,
|
|
69
|
+
timelineTitle: titleForErrors,
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
if (entry.transition) {
|
|
73
|
+
const transitionName = typeof entry.transition === "string" ? entry.transition : entry.transition.type;
|
|
74
|
+
if (!transitionLoaders.has(transitionName)) {
|
|
75
|
+
errors.push({
|
|
76
|
+
kind: "missing-transition",
|
|
77
|
+
transitionName,
|
|
78
|
+
segmentId: entry.id,
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
if (errors.length > 0) {
|
|
84
|
+
return { ok: false, errors };
|
|
85
|
+
}
|
|
86
|
+
return { ok: true, timeline };
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Validate that all segments referenced by a timeline have valid `advances` arrays.
|
|
90
|
+
*
|
|
91
|
+
* Accepts a `Record<string, number[]>` mapping segment id to its advances array.
|
|
92
|
+
* This map is produced in the browser context (entry_video.ts / render_entry.ts)
|
|
93
|
+
* where segment modules are loaded via Vite and can import browser-only assets
|
|
94
|
+
* (CSS, JSON, images) that Node's tsImport cannot handle.
|
|
95
|
+
*
|
|
96
|
+
* Checks per segment:
|
|
97
|
+
* - `advances` is defined and non-empty.
|
|
98
|
+
* - `advances` is monotonically increasing.
|
|
99
|
+
* - All entries are positive numbers.
|
|
100
|
+
*/
|
|
101
|
+
export function validateSegmentAdvances(timeline, advancesMap) {
|
|
102
|
+
const errors = [];
|
|
103
|
+
for (const entry of timeline.segments) {
|
|
104
|
+
const advances = advancesMap[entry.id];
|
|
105
|
+
if (!advances || !Array.isArray(advances) || advances.length === 0) {
|
|
106
|
+
errors.push(`Segment "${entry.id}": missing or empty 'advances' array. Every segment must declare advances for render timing.`);
|
|
107
|
+
continue;
|
|
108
|
+
}
|
|
109
|
+
for (let i = 0; i < advances.length; i++) {
|
|
110
|
+
const v = advances[i];
|
|
111
|
+
if (typeof v !== "number" || v <= 0 || !Number.isFinite(v)) {
|
|
112
|
+
errors.push(`Segment "${entry.id}": advances[${i}] must be a positive number (got ${v})`);
|
|
113
|
+
}
|
|
114
|
+
if (i > 0 && v <= advances[i - 1]) {
|
|
115
|
+
errors.push(`Segment "${entry.id}": advances must be monotonically increasing ` +
|
|
116
|
+
`(advances[${i}]=${v} <= advances[${i - 1}]=${advances[i - 1]})`);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
if (errors.length > 0) {
|
|
121
|
+
return { ok: false, errors };
|
|
122
|
+
}
|
|
123
|
+
return { ok: true };
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Apply config defaults to timeline meta. Returns a new Timeline without mutating.
|
|
127
|
+
* Priority: timeline meta > config.defaults > hardcoded fallbacks.
|
|
128
|
+
* The returned meta is guaranteed to have resolution, fps, and aspectRatio set.
|
|
129
|
+
*/
|
|
130
|
+
export function applyMetaDefaults(timeline, config) {
|
|
131
|
+
const d = config.defaults ?? {};
|
|
132
|
+
return {
|
|
133
|
+
...timeline,
|
|
134
|
+
meta: {
|
|
135
|
+
...timeline.meta,
|
|
136
|
+
resolution: timeline.meta.resolution ?? d.resolution ?? [1920, 1080],
|
|
137
|
+
fps: timeline.meta.fps ?? d.fps ?? 60,
|
|
138
|
+
aspectRatio: timeline.meta.aspectRatio ?? d.aspectRatio ?? "16:9",
|
|
139
|
+
},
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/timeline/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Load an audio track module from disk.
|
|
3
|
+
*
|
|
4
|
+
* Resolves the track.ts file via the shared ts-loader, then
|
|
5
|
+
* resolves audio_file to an absolute path.
|
|
6
|
+
*/
|
|
7
|
+
import type { AudioTrack } from "../types.js";
|
|
8
|
+
export interface LoadAudioTrackArgs {
|
|
9
|
+
videoFolder: string;
|
|
10
|
+
trackId: string;
|
|
11
|
+
}
|
|
12
|
+
export interface LoadAudioTrackResult {
|
|
13
|
+
audioTrack: AudioTrack;
|
|
14
|
+
trackFolder: string;
|
|
15
|
+
audioFilePath: string;
|
|
16
|
+
}
|
|
17
|
+
export declare function loadAudioTrack(args: LoadAudioTrackArgs): Promise<LoadAudioTrackResult>;
|
|
18
|
+
//# sourceMappingURL=loadAudioTrack.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loadAudioTrack.d.ts","sourceRoot":"","sources":["../../src/timeline/loadAudioTrack.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C,MAAM,WAAW,kBAAkB;IAClC,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,oBAAoB;IACpC,UAAU,EAAE,UAAU,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;CACtB;AAED,wBAAsB,cAAc,CAAC,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAAC,oBAAoB,CAAC,CA0D5F"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Load an audio track module from disk.
|
|
3
|
+
*
|
|
4
|
+
* Resolves the track.ts file via the shared ts-loader, then
|
|
5
|
+
* resolves audio_file to an absolute path.
|
|
6
|
+
*/
|
|
7
|
+
import { existsSync } from "node:fs";
|
|
8
|
+
import { dirname, resolve } from "node:path";
|
|
9
|
+
import { UserError } from "../cli/errors.js";
|
|
10
|
+
import { loadModule } from "../cli/ts_loader.js";
|
|
11
|
+
export async function loadAudioTrack(args) {
|
|
12
|
+
const { videoFolder, trackId } = args;
|
|
13
|
+
const trackPath = resolve(videoFolder, "audio", "tracks", trackId, "track.ts");
|
|
14
|
+
if (!existsSync(trackPath)) {
|
|
15
|
+
throw new UserError(`Audio track not found: ${trackPath}`, `Check that audio/tracks/${trackId}/track.ts exists in your video folder.`);
|
|
16
|
+
}
|
|
17
|
+
const mod = await loadModule(trackPath);
|
|
18
|
+
const audioTrack = mod.default;
|
|
19
|
+
if (!audioTrack || typeof audioTrack !== "object" || !audioTrack.audio_file) {
|
|
20
|
+
throw new UserError(`Invalid audio track module at ${trackPath}`, "The track.ts file must default-export an AudioTrack with audio_file, length_s, and timing.");
|
|
21
|
+
}
|
|
22
|
+
if (typeof audioTrack.length_s !== "number" || !Number.isFinite(audioTrack.length_s)) {
|
|
23
|
+
throw new UserError(`Audio track missing valid length_s in ${trackPath}`, `track.ts must export length_s as a finite number (got ${typeof audioTrack.length_s}).`);
|
|
24
|
+
}
|
|
25
|
+
if (!audioTrack.timing ||
|
|
26
|
+
typeof audioTrack.timing !== "object" ||
|
|
27
|
+
typeof audioTrack.timing.perSegment !== "object" ||
|
|
28
|
+
audioTrack.timing.perSegment === null) {
|
|
29
|
+
throw new UserError(`Audio track missing valid timing in ${trackPath}`, "track.ts must export a timing object with a perSegment field.");
|
|
30
|
+
}
|
|
31
|
+
const trackFolder = dirname(trackPath);
|
|
32
|
+
// audio_file is relative to the video folder (the same convention used when
|
|
33
|
+
// the track is imported as default_audio_track in timeline.ts).
|
|
34
|
+
const audioFilePath = resolve(videoFolder, audioTrack.audio_file);
|
|
35
|
+
if (!existsSync(audioFilePath)) {
|
|
36
|
+
throw new UserError(`Audio track file not found: ${audioFilePath}`, `The audio_file "${audioTrack.audio_file}" referenced in ${trackPath} does not exist. Re-run the audio build step.`);
|
|
37
|
+
}
|
|
38
|
+
const resolvedAudioTrack = {
|
|
39
|
+
...audioTrack,
|
|
40
|
+
audio_file: audioFilePath,
|
|
41
|
+
};
|
|
42
|
+
return { audioTrack: resolvedAudioTrack, trackFolder, audioFilePath };
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=loadAudioTrack.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loadAudioTrack.js","sourceRoot":"","sources":["../../src/timeline/loadAudioTrack.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAcjD,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,IAAwB;IAC5D,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAEtC,MAAM,SAAS,GAAG,OAAO,CAAC,WAAW,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC;IAC/E,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,SAAS,CAClB,0BAA0B,SAAS,EAAE,EACrC,2BAA2B,OAAO,wCAAwC,CAC1E,CAAC;IACH,CAAC;IAED,MAAM,GAAG,GAAG,MAAM,UAAU,CAAC,SAAS,CAAC,CAAC;IACxC,MAAM,UAAU,GAAG,GAAG,CAAC,OAAqB,CAAC;IAE7C,IAAI,CAAC,UAAU,IAAI,OAAO,UAAU,KAAK,QAAQ,IAAI,CAAC,UAAU,CAAC,UAAU,EAAE,CAAC;QAC7E,MAAM,IAAI,SAAS,CAClB,iCAAiC,SAAS,EAAE,EAC5C,4FAA4F,CAC5F,CAAC;IACH,CAAC;IAED,IAAI,OAAO,UAAU,CAAC,QAAQ,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QACtF,MAAM,IAAI,SAAS,CAClB,yCAAyC,SAAS,EAAE,EACpD,yDAAyD,OAAO,UAAU,CAAC,QAAQ,IAAI,CACvF,CAAC;IACH,CAAC;IAED,IACC,CAAC,UAAU,CAAC,MAAM;QAClB,OAAO,UAAU,CAAC,MAAM,KAAK,QAAQ;QACrC,OAAO,UAAU,CAAC,MAAM,CAAC,UAAU,KAAK,QAAQ;QAChD,UAAU,CAAC,MAAM,CAAC,UAAU,KAAK,IAAI,EACpC,CAAC;QACF,MAAM,IAAI,SAAS,CAClB,uCAAuC,SAAS,EAAE,EAClD,+DAA+D,CAC/D,CAAC;IACH,CAAC;IAED,MAAM,WAAW,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;IACvC,4EAA4E;IAC5E,gEAAgE;IAChE,MAAM,aAAa,GAAG,OAAO,CAAC,WAAW,EAAE,UAAU,CAAC,UAAU,CAAC,CAAC;IAElE,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC;QAChC,MAAM,IAAI,SAAS,CAClB,+BAA+B,aAAa,EAAE,EAC9C,mBAAmB,UAAU,CAAC,UAAU,mBAAmB,SAAS,+CAA+C,CACnH,CAAC;IACH,CAAC;IAED,MAAM,kBAAkB,GAAe;QACtC,GAAG,UAAU;QACb,UAAU,EAAE,aAAa;KACzB,CAAC;IAEF,OAAO,EAAE,UAAU,EAAE,kBAAkB,EAAE,WAAW,EAAE,aAAa,EAAE,CAAC;AACvE,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Load a voiceover module from disk.
|
|
3
|
+
*
|
|
4
|
+
* Resolves the voiceover.ts file via the shared ts-loader, then
|
|
5
|
+
* resolves audio_file and provider_timing_file to absolute paths.
|
|
6
|
+
*/
|
|
7
|
+
import type { Voiceover } from "../types.js";
|
|
8
|
+
export interface LoadVoiceoverArgs {
|
|
9
|
+
videoFolder: string;
|
|
10
|
+
slug: string;
|
|
11
|
+
}
|
|
12
|
+
export interface LoadVoiceoverResult {
|
|
13
|
+
voiceover: Voiceover;
|
|
14
|
+
voiceoverFolder: string;
|
|
15
|
+
audioFilePath: string;
|
|
16
|
+
}
|
|
17
|
+
export declare function loadVoiceover(args: LoadVoiceoverArgs): Promise<LoadVoiceoverResult>;
|
|
18
|
+
//# sourceMappingURL=loadVoiceover.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loadVoiceover.d.ts","sourceRoot":"","sources":["../../src/timeline/loadVoiceover.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7C,MAAM,WAAW,iBAAiB;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,mBAAmB;IACnC,SAAS,EAAE,SAAS,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC;IACxB,aAAa,EAAE,MAAM,CAAC;CACtB;AAED,wBAAsB,aAAa,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAiDzF"}
|