Report exports only used in their own file

This commit is contained in:
Kalle
2026-11-01 13:57:10 +02:00
parent b0ad7e147d
commit 3e1ffe8e47
49 changed files with 205 additions and 202 deletions

View File

@@ -38,7 +38,7 @@ const TOOLTIP_FLIP_RATIO = 0.55;
const SIDES = [0, 1] as const;
/** One objective-counter read, values in `[alpha, bravo]` order. */
export interface ObjectiveTimelineSample {
interface ObjectiveTimelineSample {
/** seconds shown on the match timer at the read ("3:35" = 215); null = unreadable */
time: number | null;
/** displayed count per team; null = unreadable */

View File

@@ -2,7 +2,7 @@ import clsx from "clsx";
import { ArrowDown, ArrowUp, ChevronsUpDown } from "lucide-react";
import styles from "./SortableTableHeader.module.css";
export type SortDirection = "asc" | "desc";
type SortDirection = "asc" | "desc";
export type SortState<Key extends string = string> = {
key: Key;

View File

@@ -7,7 +7,7 @@ import { Flipper } from "../Flipper";
import { SendouButton } from "./Button";
import styles from "./Toast.module.css";
export interface SendouToast {
interface SendouToast {
message: string;
variant: "error" | "success" | "info";
}

View File

@@ -4,11 +4,9 @@ import { SEARCH_DEBOUNCE_MS } from "~/features/search/search-constants";
import { useDebounce } from "~/hooks/useDebounce";
/** Sentinel items rendered in place of real results while loading or when empty. */
export type EntitySearchPlaceholder =
| { id: "PLACEHOLDER" }
| { id: "NO_RESULTS" };
type EntitySearchPlaceholder = { id: "PLACEHOLDER" } | { id: "NO_RESULTS" };
export type EntitySearchItem<TItem> = TItem | EntitySearchPlaceholder;
type EntitySearchItem<TItem> = TItem | EntitySearchPlaceholder;
interface UseEntitySearchArgs<TItem extends { id: number }> {
/** Builds the loader URL queried (debounced) as the user types. */

View File

@@ -50,7 +50,7 @@ const WEAPON_DESTINATIONS = [
"art",
"lfg",
] as const;
export type WeaponDestination = (typeof WEAPON_DESTINATIONS)[number];
type WeaponDestination = (typeof WEAPON_DESTINATIONS)[number];
export interface SelectedWeapon {
id: MainWeaponId;

View File

@@ -52,12 +52,12 @@ const ABILITY_NAMES: ReadonlySet<string> = new Set(
type MatchSide = "ALPHA" | "BRAVO";
export interface TimelineTeam {
interface TimelineTeam {
name: string;
avatar?: string;
}
export interface TimelineScoreboardPlayer {
interface TimelineScoreboardPlayer {
name: string;
weaponSplId: MainWeaponId | null;
ka: number | null;

File diff suppressed because it is too large Load Diff

View File

@@ -125,7 +125,7 @@ export interface BaseWeaponStats extends RangeParams {
/** A way of shooting a main weapon with its own flight, e.g. a roller's vertical or horizontal swing */
export type RangeVariantKey = (typeof RANGE_VARIANT_KEYS)[number];
export interface RangeVariantParams extends RangeParams {
interface RangeVariantParams extends RangeParams {
Range_VariantKey: RangeVariantKey;
}

View File

@@ -26,6 +26,7 @@ interface AttentionEnvironment {
export type Tracker = ReturnType<typeof createTracker>;
// Whether the user is paying attention to this tab. It has to be visible, window focused, and be interacted with in the last 3 minutes
/** @internal */
export function createTracker(
getEnvironment: () => AttentionEnvironment,
{ idleAfterMs = IDLE_AFTER_MS }: { idleAfterMs?: number } = {},

View File

@@ -1,3 +1,4 @@
/** @internal */
export const CHAT_STICKERS = [
{ id: "booyah", name: "Booyah" },
{ id: "despair", name: "Despair" },

View File

@@ -8,7 +8,7 @@ export type CapturedSource =
| "uncaught error"
| "unhandled rejection";
export interface CapturedEntry {
interface CapturedEntry {
id: number;
level: CapturedLevel;
source: CapturedSource;

View File

@@ -6,7 +6,7 @@ import type { ServerEvent } from "~/features/events/events-types";
const MAX_ENTRIES = 300;
export type RecordedEvent =
type RecordedEvent =
| { id: number; at: number; type: "event"; event: ServerEvent }
| { id: number; at: number; type: "connection"; state: EventsReadyState };

View File

@@ -10,7 +10,7 @@ const UNTRACKED_PATH_PREFIXES = ["/dev/", "/sse"];
export type RequestKind = "document" | "data" | "action" | "resource";
export interface LoggedQuery {
interface LoggedQuery {
sql: string;
parameters: unknown[];
durationMs: number;

View File

@@ -84,7 +84,7 @@ export interface TeammateHistory {
}
/** A candidate split of the players into two teams, scored by {@link splitCost}. */
export interface Split {
interface Split {
alpha: ShufflePlayer[];
bravo: ShufflePlayer[];
}

View File

@@ -162,7 +162,7 @@ export const ROLLABLE_WEAPON_IDS = mainWeaponIds.filter(
(weaponId) => weaponIdToType(weaponId) !== "ALT_SKIN",
);
export interface WeaponRollCost {
interface WeaponRollCost {
strength: number;
shape: number;
shapeMismatch: number;

View File

@@ -27,7 +27,7 @@ import { SendouMenu, SendouMenuItem } from "~/components/elements/Menu";
import * as CoachPlayback from "../core/CoachPlayback";
import styles from "./CoachControls.module.css";
export type CoachStep = "GAME" | "LIFE" | "EVENT" | "SECONDS";
type CoachStep = "GAME" | "LIFE" | "EVENT" | "SECONDS";
interface StepControl {
label: string;

View File

@@ -103,11 +103,11 @@ const NO_SOURCE_ERROR =
const MISSING_ATLASES_ERROR =
"Some of the scanner's game data could not be downloaded — check the connection and start the capture again";
export type LiveStatus = "idle" | "starting" | "running" | "error";
type LiveStatus = "idle" | "starting" | "running" | "error";
/** `unsupported`: no WebCodecs/track processor; `failed`: the encoder refused this stream */
export type ClipsState = "on" | "off" | "unsupported" | "failed";
type ClipsState = "on" | "off" | "unsupported" | "failed";
/** `muted`: the browser gets nothing from the device; `silent`: it gets samples, all of them silence; `ended`: the track stopped (a share ended, say); `failed`: the encoder gave up */
export type AudioSignal = "ok" | "silent" | "muted" | "ended" | "failed";
type AudioSignal = "ok" | "silent" | "muted" | "ended" | "failed";
export interface LiveSnapshot {
status: LiveStatus;

View File

@@ -60,7 +60,7 @@ import { describeError } from "./errors";
import { scannedTeamComps } from "./montage-comps";
import { cancelVodScan, startVodScan } from "./vod-scan";
export interface MontageFolder {
interface MontageFolder {
manifest: MontageManifest;
/** the manifest's VoDs found in the folder */
vods: MontageManifestVod[];
@@ -69,7 +69,7 @@ export interface MontageFolder {
directory: FileSystemDirectoryHandle | null;
}
export type MontageScan =
type MontageScan =
| { state: "scanning"; file: string; index: number; total: number }
| { state: "done"; failed: string[] };
@@ -93,7 +93,7 @@ type GraphicCapture = (graphic: MontageGraphic) => Promise<{
revealRects: CardRevealRect[];
}>;
export type MontageRender =
type MontageRender =
| ({ state: "rendering" } & MontageRenderProgress)
| { state: "done"; error: string | null };

View File

@@ -26,7 +26,7 @@ export interface ScannerSettings {
}
export const CLIP_MIN_KILLS_OPTIONS = [3, 4, 5] as const;
export type ClipMinKills = (typeof CLIP_MIN_KILLS_OPTIONS)[number];
type ClipMinKills = (typeof CLIP_MIN_KILLS_OPTIONS)[number];
/**
* `source`: the video input's own audio side; `desktop`: the system's sound

View File

@@ -73,13 +73,13 @@ const UI_UPDATE_INTERVAL_MS = 250;
*/
const EVENTS_PUBLISH_INTERVAL_MS = 1000;
export type VodScanStatus = "idle" | "scanning" | "done" | "error";
type VodScanStatus = "idle" | "scanning" | "done" | "error";
export type ClipsWork =
type ClipsWork =
| { state: "cutting"; done: number; total: number }
| { state: "done"; saved: number; error: string | null };
export type VodScanMode = "active" | "skim";
type VodScanMode = "active" | "skim";
/** One worker's slice of the file. */
export interface VodScanLane {
@@ -93,7 +93,7 @@ export interface VodScanLane {
failed: boolean;
}
export interface VodScanProgress {
interface VodScanProgress {
t: number;
duration: number;
/** scan speed as a multiple of realtime */

View File

@@ -483,7 +483,7 @@ export interface CoachLife {
summary: CoachLifeSummary | null;
}
export interface CoachLifeSummary {
interface CoachLifeSummary {
/** seconds alive, the first life counted from the game clock's start when read */
duration: number;
/** the POV player's splats in the life (a trade on the death's second included); null without a kill feed read */

View File

@@ -13,7 +13,7 @@ const INTERVAL_EPSILON_S = 1e-6;
/** Stepped samples remembered, so a plan made behind the decoder can be replayed up to it. */
const HISTORY_LIMIT = 512;
export interface DetectorCheckPlan {
interface DetectorCheckPlan {
lastCheckT: number;
/** intervals the detector's next check may come after */
next: readonly number[];

View File

@@ -70,7 +70,7 @@ import { readTrackSteps, trackComb } from "./track";
export type ObjectiveData = ZonesObjectiveData | TrackObjectiveData;
/** Splat Zones / Clam Blitz plates. */
export interface ZonesObjectiveData {
interface ZonesObjectiveData {
/** names the plates overlay: CB draws it too, so the match's mode tells the two apart */
mode: "SZ";
/** match timer seconds ("3:35" = 215); null = unreadable. Overtime display unattested so far. */
@@ -92,7 +92,10 @@ export interface ZonesObjectiveData {
teamColor: [InkRgb | null, InkRgb | null];
}
/** Tower Control / Rainmaker: one overlay, told apart only by its checkpoint markers. */
/**
* Tower Control / Rainmaker: one overlay, told apart only by its checkpoint markers.
* @internal
*/
export interface TrackObjectiveData {
/** off the checkpoint markers; null when none read (the match's mode decides) */
mode: "TC" | "RM" | null;

View File

@@ -29,7 +29,7 @@ import {
export const STRIP_WEAPONS_EVENT_TYPE = "StripWeapons";
export interface StripWeaponCandidate {
interface StripWeaponCandidate {
weaponId: MainWeaponId;
score: number;
}

View File

@@ -37,7 +37,7 @@ import {
export const X_RANK_POSITION_EVENT_TYPE = "XRankPosition";
export type XRankPositionDirection = "UP" | "DOWN" | "SAME";
type XRankPositionDirection = "UP" | "DOWN" | "SAME";
export interface XRankPositionData {
mode: RankedModeShort | null;

View File

@@ -48,7 +48,7 @@ import {
export const X_SET_RESULT_EVENT_TYPE = "XSetResult";
export type XSetGameResult = "WIN" | "LOSE";
type XSetGameResult = "WIN" | "LOSE";
export interface XSetResultData {
mode: RankedModeShort | null;

View File

@@ -57,7 +57,7 @@ export type MontageManifestTopTeam = MontageManifestTeam & {
placement: number;
};
export interface MontageManifestTeam {
interface MontageManifestTeam {
id: number;
name: string;
logo: string | null;

View File

@@ -76,6 +76,7 @@ export interface ScannerMatchObjective {
samples: ScannerMatchObjectiveSample[];
}
/** @internal */
export type ScannerMatchPlayerFlags = [boolean, boolean, boolean, boolean];
export interface ScannerMatchPlayerStatusSample {

View File

@@ -80,7 +80,7 @@ const UNIX_FILE_TYPE_MASK = 0o170000;
const UNIX_REGULAR_FILE = 0o100000;
/** One analyzed frame of the game, as unpacked. */
export interface GameDataFrame {
interface GameDataFrame {
/** folder relative to the output directory, e.g. `frames/012-Death-1m42s` */
folder: string;
eventType: (typeof EVENT_TYPES)[number];

View File

@@ -23,9 +23,9 @@ const STORAGE_RESERVE_BYTES = 250_000_000;
/** clips saved before their size was kept were all encoded at 16 Mbps */
const LEGACY_BYTES_PER_SECOND = 2_000_000;
export type ClipBucket = "session" | "history" | "vod";
type ClipBucket = "session" | "history" | "vod";
export type ClipSource =
type ClipSource =
| { kind: "live"; sessionKey: number }
/** `visit`: the page load that cut it (see visit.ts) */
| { kind: "vod"; name: string; visit: string };

View File

@@ -10,7 +10,7 @@ import { test as vitestTest } from "vitest";
type SubtestBody = () => void | Promise<void>;
export interface SubtestOptions {
interface SubtestOptions {
skip?: boolean | string;
expectFailure?: string;
}

View File

@@ -23,7 +23,7 @@ export interface DoneInfo {
telemetry: ScanTelemetry | null;
}
export type DoneHandler = (t: number, info: DoneInfo) => void;
export type ChunkProgress = Extract<WorkerResponse, { kind: "chunkProgress" }>;
type ChunkProgress = Extract<WorkerResponse, { kind: "chunkProgress" }>;
export type ChunkProgressHandler = (progress: ChunkProgress) => void;
/** Each chunk worker decodes and analyzes on its own; leave a core for the main thread and one for the media stack. */

View File

@@ -56,7 +56,7 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>, @builtin(num_workgroups)
`;
/** The part of a source picture to upscale: `box` of an RGBA buffer `stride` pixels wide. */
export interface UpscaleSource {
interface UpscaleSource {
buffer: GPUBuffer;
stride: number;
box: { x: number; y: number; w: number; h: number };

View File

@@ -326,7 +326,7 @@ function resolveJob(job: Job, score: number) {
job.cache?.set(job.cacheKey, score);
}
export interface GpuMatcherStats {
interface GpuMatcherStats {
steps: number;
dispatches: number;
jobs: number;

View File

@@ -43,7 +43,7 @@ export interface ScanChunkRequest {
tEnd: number;
}
export interface AbortChunkRequest {
interface AbortChunkRequest {
kind: "abortChunk";
}

View File

@@ -68,7 +68,7 @@ interface ScrimPostTeam {
avatarUrl: string | null;
}
export interface TimeRange {
interface TimeRange {
start: string;
end: string;
}

View File

@@ -11,7 +11,7 @@ import * as RejoinVote from "../core/RejoinVote";
import { matchSchema } from "../q-match-schemas";
import styles from "./RematchVotePanel.module.css";
export type RematchVoteMember = {
type RematchVoteMember = {
id: number;
username: string;
avatar: string | null;

View File

@@ -72,7 +72,7 @@ export type SidebarEvent = {
scrimStatus?: "booked" | "looking" | "requestPending";
};
export type SidebarFriend = {
type SidebarFriend = {
id: number;
name: string;
avatar: CommonUser["avatar"];

View File

@@ -1,3 +1,3 @@
export const SPLATOON_ROTATION_TYPES = ["SERIES", "OPEN", "X"] as const;
const SPLATOON_ROTATION_TYPES = ["SERIES", "OPEN", "X"] as const;
export type SplatoonRotationType = (typeof SPLATOON_ROTATION_TYPES)[number];

View File

@@ -516,6 +516,7 @@ export function isStageLegal({
return pool.some((m) => m.stageId === stageId && m.isLegal);
}
/** @internal */
export interface PickBanEvent {
type: string;
stageId: StageId | null;
@@ -769,6 +770,7 @@ const MAP_PICK_ACTIONS: ReadonlySet<ActionType> = new Set([
"PICK_NO_MODE_REPEAT",
]);
/** @internal */
export const CUSTOM_FLOW_VALIDATION_ERRORS = {
STEP_MISSING_ACTION: "STEP_MISSING_ACTION",
STEP_MISSING_WHO: "STEP_MISSING_WHO",

View File

@@ -17,7 +17,7 @@ export interface DBSource {
rest?: boolean;
}
export interface EditableSource {
interface EditableSource {
/** Frontend-only id while editing, replaced by an index once set. See DBSource.bracketIdx. */
bracketId: string;
/** User editable, "1-3" and "1,2,3" mean the same. See DBSource.placements for the validated version. */

View File

@@ -22,6 +22,7 @@ const SIZE_BONUS = {
MAX_BONUS_PER_10_TEAMS: 1.5,
} as const;
/** @internal */
export const TIER_TO_NUMBER = {
X: 1,
"S+": 2,

View File

@@ -17,7 +17,7 @@ export interface Vod {
submitterUserId: Tables["Video"]["submitterUserId"];
}
export type VodMatch = Pick<
type VodMatch = Pick<
Tables["VideoMatch"],
"id" | "mode" | "stageId" | "startsAt"
> & {

View File

@@ -20,7 +20,7 @@ import {
import type { VoiceClientErrorKind, VoiceInputMode } from "./voice-constants";
import { useVoiceRooms, useVoiceSnapshot } from "./voice-hooks";
export type VoiceActivityStatus = "AVAILABLE" | VoiceCallStatus;
type VoiceActivityStatus = "AVAILABLE" | VoiceCallStatus;
export interface VoiceActivityParticipant {
key: string;
@@ -49,7 +49,7 @@ export interface VoiceActivityState {
latencyMs: number | null;
}
export interface VoiceActivityActions {
interface VoiceActivityActions {
join: () => void;
leave: () => void;
setMicEnabled: (enabled: boolean) => void;

View File

@@ -81,14 +81,14 @@ export interface VoiceSnapshot {
inputMode: VoiceInputMode;
}
export interface VoiceCallHandle {
interface VoiceCallHandle {
setLocalAudio: (enabled: boolean) => void;
ensureMic: (options: { mayAsk: boolean }) => Promise<boolean>;
leave: () => Promise<void>;
resumeAudio: () => void;
}
export interface VoiceTelemetrySummary {
interface VoiceTelemetrySummary {
lowQualitySeconds: number;
talkSeconds: number;
}

View File

@@ -104,7 +104,7 @@ export interface FormRenderProps<T extends v.ObjectEntries> {
FormField: TypedFormFieldComponent<T>;
}
export type FormMode = "submit" | "autoSubmit" | "client";
type FormMode = "submit" | "autoSubmit" | "client";
type BaseFormProps<T extends v.ObjectEntries> = {
children: React.ReactNode | ((props: FormRenderProps<T>) => React.ReactNode);
@@ -159,7 +159,7 @@ type FormModeProps<T extends v.ObjectEntries> =
saveAttempted?: boolean;
};
export type FormDefaultValues<T extends v.ObjectEntries> = Partial<
type FormDefaultValues<T extends v.ObjectEntries> = Partial<
v.InferInput<v.ObjectSchema<T, undefined>>
>;

View File

@@ -300,7 +300,7 @@ type FormFieldChildrenProps = {
disabled?: boolean;
};
export type TypedFormFieldProps<
type TypedFormFieldProps<
TSchema extends v.ObjectEntries,
TName extends keyof TSchema & string,
> = {
@@ -324,7 +324,7 @@ export type TypedFormFieldProps<
type NestedPath = `${string}.${string}` | `${string}[${string}`;
/** FormField props with a free-form name, for nested paths like `${itemName}.field` */
export type FlexibleFormFieldProps = {
type FlexibleFormFieldProps = {
name: NestedPath;
label?: string;
disabled?: boolean;

View File

@@ -1,4 +1,4 @@
export type Permissions = Record<string, number[]>;
type Permissions = Record<string, number[]>;
export type EntityWithPermissions = {
permissions: Permissions;

View File

@@ -1,8 +1,4 @@
const config = {
ignoreExportsUsedInFile: {
interface: true,
type: true,
},
tags: ["-lintignore"],
ignoreBinaries: ["ffmpeg", "ffprobe", "yt-dlp"],
astro: {