commit c7997a0941093ab7f3dfca65d9b3f9313ce17618
parent 89029b2c6fecf1f53b9ec1a2afe2c6d2f5956e52
Author: I Mean I'm Just Saying <imeanimjustsaying@kiwifarms.st>
Date: Sun, 20 Sep 2026 19:42:27 -0400
fetch-window: the span cap is a constant, so it cannot live in a server action
Every export of a "use server" module must be an async function; a `const`
there is a build error, not a lint. The cap is pure arithmetic about the
contract, so it belongs with the rest of the window's pure rules.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Diffstat:
3 files changed, 12 insertions(+), 8 deletions(-)
diff --git a/common/lib/clipWindow.ts b/common/lib/clipWindow.ts
@@ -43,6 +43,15 @@ export const CLIPS_DIR_NAME = "clips";
// one of them fetched is invisible to the other.
export const WIN_EPS = 0.02;
+// The widest window one request may ask for. Fifteen minutes is far past any
+// citation and well short of "you meant to download the video" — which is what
+// the full-source path is for, and which goes to the saved-video store instead.
+//
+// HERE rather than beside the action that enforces it: `videoActions.ts` is a
+// "use server" module, and every export of one must be an async function — a
+// constant there is a build error, not a lint.
+export const MAX_CLIP_WINDOW_SECONDS = 900;
+
export function clipsDirFor(videoDir: string): string {
return path.join(videoDir, CLIPS_DIR_NAME);
}
diff --git a/editor/app/api/media/fetch-window/route.ts b/editor/app/api/media/fetch-window/route.ts
@@ -1,7 +1,7 @@
import { NextResponse } from "next/server";
import { authorizeWorkerRequest } from "yt-dlp-transcript-common/lib/workerToken";
+import { MAX_CLIP_WINDOW_SECONDS } from "yt-dlp-transcript-common/lib/clipWindow";
import {
- MAX_WINDOW_SECONDS,
fetchFullSourceAction,
fetchWindowAction,
type FetchMediaOutcome,
@@ -160,11 +160,11 @@ export async function POST(request: Request) {
{ status: 400 },
);
}
- if (to - from > MAX_WINDOW_SECONDS) {
+ if (to - from > MAX_CLIP_WINDOW_SECONDS) {
return NextResponse.json(
{
error:
- `a window may be at most ${MAX_WINDOW_SECONDS}s ` +
+ `a window may be at most ${MAX_CLIP_WINDOW_SECONDS}s ` +
`(asked for ${Math.round(to - from)}s); pass full: true for the ` +
`whole recording`,
},
diff --git a/editor/app/channels/[slug]/videos/[id]/videoActions.ts b/editor/app/channels/[slug]/videos/[id]/videoActions.ts
@@ -742,11 +742,6 @@ export type FetchMediaOutcome =
platform?: string;
};
-// The widest window this will fetch in one go. Fifteen minutes is far past any
-// citation and well short of "you meant to download the video" — which is what
-// `full` is for, and which goes through the saved-video store instead.
-export const MAX_WINDOW_SECONDS = 900;
-
// A started job's stream has no reader here: the caller polls the job instead.
// Cancelling the stream is the documented way to say so — it marks the
// controller closed and leaves the job running into its on-disk log.