/** * ONE apps poller per client. * * The same shape as `approvals-feed.ts`, and for the same reason: the app * collection has more than one reader — every `useApps` caller, and the launcher * pill, which needs the unseen count to light its dot. A module store fed by * whichever of them happened to mount cannot do that: the count froze at the * moment of mount, so an app that arrived mid-session never lit the dot, * rendering one never cleared it, and a host whose surfaces never list apps read * zero forever. * * One request between them, at the FASTEST cadence any subscriber asked for. * `unseen` rides the rows that fetch already returns, so the dot costs no * request of its own — there is no second poller to keep in step with this one. */ import type { VendoClient } from "../client.js"; import type { AppListRow } from "../../core/apps/index.js"; export interface AppsSnapshot { data: AppListRow[]; error: Error | undefined; isLoading: boolean; } /** Stable first-render / SSR snapshot (useSyncExternalStore compares identity). */ export declare const APPS_LOADING: AppsSnapshot; declare class AppsFeed { private readonly list; private snapshot; /** Subscriber → the cadence it asked for (0 = read-only, no polling). */ private readonly cadences; private timer; private generation; constructor(list: () => Promise); read: () => AppsSnapshot; subscribe: (listener: () => void, pollMs: number) => (() => void); refresh: () => Promise; /** How many rows nobody has had rendered to them — the launcher's dot. */ unseenCount: () => number; private publish; private arm; private stop; /** The fastest cadence anybody asked for; undefined = nobody polls. */ private cadence; private onVisibility; } export declare function appsFeed(client: VendoClient): AppsFeed; export type { AppsFeed };