Archilyzer · Source

archilyzer

Archilyzer
git clone https://archilyzer.pages.dev/source/archilyzer.git
Log | Files | Refs | README | LICENSE

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:
Mcommon/lib/clipWindow.ts | 9+++++++++
Meditor/app/api/media/fetch-window/route.ts | 6+++---
Meditor/app/channels/[slug]/videos/[id]/videoActions.ts | 5-----
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.