From 83c331da6300e4cb6dc47584ab2c056da29ae4c1 Mon Sep 17 00:00:00 2001 From: 4gray Date: Thu, 16 Apr 2026 21:59:03 +0200 Subject: [PATCH] docs: update Stalker portal and store API documentation for clarity and consistency Entire-Checkpoint: c6e522b4276c --- docs/architecture/stalker-portal.md | 31 +++++++++++++++++-- .../stalker-store-api-baseline.md | 19 ++++++++---- 2 files changed, 41 insertions(+), 9 deletions(-) diff --git a/docs/architecture/stalker-portal.md b/docs/architecture/stalker-portal.md index e3ef1247b..429a9b6b3 100644 --- a/docs/architecture/stalker-portal.md +++ b/docs/architecture/stalker-portal.md @@ -48,11 +48,11 @@ Primary route tree lives in `/Users/4gray/Code/iptvnator/libs/portal/stalker/fea ## Main UI Components - `/Users/4gray/Code/iptvnator/libs/portal/stalker/feature/src/lib/stalker-main-container.component.ts` - - Category + content layout for `vod` and `series` + - Category + content layout for `vod` and `series` - `/Users/4gray/Code/iptvnator/libs/portal/stalker/feature/src/lib/stalker-live-stream-layout/stalker-live-stream-layout.component.ts` - - ITV live playback, channel navigation, EPG panel integration + - ITV live playback, channel navigation, EPG panel integration - `/Users/4gray/Code/iptvnator/libs/ui/components/src/lib/stalker-series-view/stalker-series-view.component.ts` - - Season/episode UI for all Stalker series modes + - Season/episode UI for all Stalker series modes - `/Users/4gray/Code/iptvnator/libs/portal/stalker/feature/src/lib/stalker-favorites/stalker-favorites.component.ts` - `/Users/4gray/Code/iptvnator/libs/portal/stalker/feature/src/lib/recently-viewed/recently-viewed.component.ts` - `/Users/4gray/Code/iptvnator/libs/portal/stalker/feature/src/lib/stalker-search/stalker-search.component.ts` @@ -75,19 +75,44 @@ Important store responsibilities: - Playback link creation (`create_link` flow) - Favorites and recently viewed persistence helpers +Internal structure to preserve: + +- `stalker.store.ts` stays as the thin facade that composes feature slices. +- Cross-slice contracts live in `stores/stalker-store.contracts.ts` so + feature dependencies are declared instead of repeated `unknown` casts. +- Request execution is centralized in `stores/utils/stalker-request.utils.ts` + for both authenticated full-portal calls and simple IPC-backed requests. +- Playback link resolution and Stalker collection persistence live in + dedicated `stores/utils/` helpers so player/favorites/recent slices stay + focused on orchestration. +- Category/content resources stay internal to the store slices. Feature + consumers should read `getCategoryResource()` and `getPaginatedContent()`, + which now always return arrays, and pair them with + `isCategoryResourceFailed()` / `isPaginatedContentFailed()` for explicit + error handling. + +Failure-handling rule: + +- Failed category or content requests must degrade into empty/error UI state, + not `undefined` collections or renderer exceptions. The workspace Stalker + context panel and live layout rely on this guarantee. + ## VOD/Series Modes Stalker has multiple real-world data shapes. The current implementation supports all three: 1. Regular Series (`/series`): + - Seasons come from API resource (`serialSeasonsResource`). - Episodes are derived from season payload. 2. VOD with Embedded `series[]`: + - Item is opened under VOD, but already contains episodes. - `StalkerSeriesViewComponent` creates a pseudo-season and renders episodes directly. 3. VOD with `is_series=1` (Ministra plugin behavior): + - Treated as series flow from VOD context. - Seasons are fetched lazily. - Episodes are fetched on season select. diff --git a/docs/architecture/stalker-store-api-baseline.md b/docs/architecture/stalker-store-api-baseline.md index cc7c641d5..b29f957e9 100644 --- a/docs/architecture/stalker-store-api-baseline.md +++ b/docs/architecture/stalker-store-api-baseline.md @@ -21,7 +21,7 @@ Direct signal properties currently exposed by `signalStore`: - `limit: number` - `page: number` - `searchPhrase: string` -- `currentPlaylist: PlaylistMeta` +- `currentPlaylist: PlaylistMeta | undefined` - `totalCount: number` - `selectedItem: StalkerVodSource | null | undefined` - `vodCategories: StalkerCategoryItem[]` @@ -36,7 +36,7 @@ Direct signal properties currently exposed by `signalStore`: ## Public Computed Selectors - `getTotalPages: number` -- `getPaginatedContent: StalkerContentItem[] | undefined` +- `getPaginatedContent: StalkerContentItem[]` - `isPaginatedContentLoading: boolean` - `isPaginatedContentFailed: unknown` - `getSerialSeasonsResource: StalkerSeason[]` @@ -52,13 +52,15 @@ Direct signal properties currently exposed by `signalStore`: These are currently reachable on the store object and used internally by computed selectors: -- `getCategoryResource` (resource) +- `getCategoryResource` (computed selector with stable array output) +- `categoryResource` (internal resource) - `getContentResource` (resource) - `serialSeasonsResource` (resource) - `vodSeriesSeasonsResource` (resource) - `makeStalkerRequest(...)` During refactor: + - Keep compatibility for external callers that may read these directly. - If moved/renamed internally, provide facade aliases. @@ -80,6 +82,7 @@ During refactor: - `setSearchPhrase(phrase: string): void` - `fetchVodSeriesEpisodes(videoId: string, seasonId: string): Promise` - `getSelectedCategory(): { id: string | number; name: string; type: 'vod' | 'itv' | 'series' }` + Backed by `withComputed` for compatibility, not by `withMethods`. - `fetchLinkToPlay(portalUrl: string, macAddress: string, cmd: string, series?: number): Promise` - `getExpireDate(): Promise` - `addToFavorites(item: any, onDone?: () => void): void` @@ -117,10 +120,14 @@ Consumer directories sampled: - Selection IDs (`selectedVodId`, `selectedSerialId`, `selectedItvId`) are synchronized in `setSelectedItem`. - `setSelectedCategory(...)` resets `page` to `0`. +- `getPaginatedContent()` and `getCategoryResource()` always return arrays, + even when the underlying request fails. +- Request failures must surface through `isPaginatedContentFailed()` and + `isCategoryResourceFailed()` rather than resource reads that throw. - `createLinkToPlayVod(...)` continues to: - - support episode playback metadata - - append recently viewed - - preserve external player payload shape + - support episode playback metadata + - append recently viewed + - preserve external player payload shape - Full-portal auth path continues through `StalkerSessionService`. - Non-auth/simple path continues through `DataService.sendIpcEvent(STALKER_REQUEST, ...)`. - Resource-driven loading signals preserve existing names.