- Every state and Watch-later write goes through features/video/videoWrites, which marks the never-refetched lists (related lists, live searches) once the server has it; a contract test holds it. The Notification Center's undo, the feed's reset and the Watch-later toggles skipped it before. - Confirmed marks are also kept apart (qk.videoMarks) and laid over the related rows: a Show more page landing later rebuilt them from the pages it read when it started, and dropped a mark made meanwhile. - Restart on a related video starts at 0 (the session's stored position won before), and on the one already playing it seeks. - The watched toggle remembers each video's mark: Back showed the opened video's launch-time state after a related one was marked. - The help sheet leaves out the player's keys while a layer above it has them waiting. - After a refusal a retry cannot answer, neither Show more (related) nor Load more (live search) is offered; a failed live-search page keeps the results already read and says why under them. - The related cap message counts requests, as the cap does.
95 lines
3.3 KiB
TypeScript
95 lines
3.3 KiB
TypeScript
// The API façade. This file owns NO endpoint logic and NO types of its own — every domain lives in
|
|
// its own api/<domain>.ts module (types + method slice together). This barrel only:
|
|
// 1. re-exports the shared HTTP machinery from api/core,
|
|
// 2. re-exports each domain's TYPES (`export type *`) so consumers import them from "./api"
|
|
// unchanged,
|
|
// 3. spreads each domain's method slice into the single `api` object consumers call.
|
|
// A new endpoint therefore has nowhere to land except a domain module — the interleave that
|
|
// motivated the split cannot re-grow here. (lib/api/facade.test.ts guards that invariant.)
|
|
import { HttpError, refusalReason, setUnauthorizedHandler } from "./api/core";
|
|
|
|
// Re-export the shared HTTP machinery so consumers keep importing these from "./api" unchanged.
|
|
export { HttpError, refusalReason, setUnauthorizedHandler };
|
|
|
|
import { accountApi } from "./api/account";
|
|
export type * from "./api/account";
|
|
import { authApi } from "./api/auth";
|
|
export type * from "./api/auth";
|
|
export { loginBlocked, deadResetLink } from "./api/auth";
|
|
import { setupApi } from "./api/setup";
|
|
export type * from "./api/setup";
|
|
import { feedApi } from "./api/feed";
|
|
export type * from "./api/feed";
|
|
export { TAKEOUT_JOB } from "./api/feed";
|
|
import { discoverApi } from "./api/discover";
|
|
export type * from "./api/discover";
|
|
export { DISCOVER_BUDGETS, HERO_TIERS, discoverCardKey } from "./api/discover";
|
|
export type * from "./api/tagModes";
|
|
export {
|
|
DEFAULT_TAG_MODES,
|
|
TAG_CATEGORIES,
|
|
NO_TAG_SENTINEL,
|
|
coerceTagModes,
|
|
coerceUntagged,
|
|
} from "./api/tagModes";
|
|
import { channelsApi } from "./api/channels";
|
|
export type * from "./api/channels";
|
|
import { syncApi } from "./api/sync";
|
|
export type * from "./api/sync";
|
|
import { playlistsApi } from "./api/playlists";
|
|
export type * from "./api/playlists";
|
|
import { tagsApi } from "./api/tags";
|
|
export type * from "./api/tags";
|
|
import { notificationsApi } from "./api/notifications";
|
|
export type * from "./api/notifications";
|
|
import { savedViewsApi } from "./api/savedViews";
|
|
export type * from "./api/savedViews";
|
|
import { quotaApi } from "./api/quota";
|
|
export type * from "./api/quota";
|
|
import { adminApi } from "./api/admin";
|
|
export type * from "./api/admin";
|
|
import { plexApi } from "./api/plex";
|
|
export type * from "./api/plex";
|
|
export {
|
|
EMPTY_PLEX_FILTERS,
|
|
plexFilterCount,
|
|
coercePlexFilters,
|
|
plexFiltersSignature,
|
|
plexFiltersToParams,
|
|
parsePlexFilters,
|
|
isIntrinsicReadOnly,
|
|
} from "./api/plex";
|
|
import { downloadsApi } from "./api/downloads";
|
|
export type * from "./api/downloads";
|
|
import { filesApi } from "./api/files";
|
|
export type * from "./api/files";
|
|
export { FILES_LIST_CAP, FILE_SORTS } from "./api/files";
|
|
import { tokensApi } from "./api/tokens";
|
|
export type * from "./api/tokens";
|
|
export { TOKEN_EXPIRY_DAYS, TOKEN_EXPIRY_DEFAULT, TOKEN_RIGHTS } from "./api/tokens";
|
|
import { debugSessionsApi, diagnosticsApi } from "./api/diagnostics";
|
|
export type * from "./api/diagnostics";
|
|
export { DIAGNOSTICS_EVENTS_PATH } from "./api/diagnostics";
|
|
|
|
export const api = {
|
|
...accountApi,
|
|
...authApi,
|
|
...setupApi,
|
|
...feedApi,
|
|
...discoverApi,
|
|
...channelsApi,
|
|
...syncApi,
|
|
...playlistsApi,
|
|
...tagsApi,
|
|
...notificationsApi,
|
|
...savedViewsApi,
|
|
...quotaApi,
|
|
...adminApi,
|
|
...plexApi,
|
|
...downloadsApi,
|
|
...filesApi,
|
|
...tokensApi,
|
|
...diagnosticsApi,
|
|
...debugSessionsApi,
|
|
};
|