UNPKG

@mui/internal-docs-infra

Version:

MUI Infra - internal documentation creation tools.

96 lines 4.32 kB
/** * Fallback ceiling for {@link createSettleGate}: if a registered source never * settles (its swap errored or hung), the gate opens anyway after this many * milliseconds so coordination can never be blocked forever. Matches the * coordinator's default `ultimateTimeoutMs` and the value the module-global * `layoutShiftGate` shipped with. */ export declare const SETTLE_SAFETY_TIMEOUT_MS = 10000; /** * A reusable "all sources settled" gate. * * The module-global page-wide layout-shift gate (`layoutShiftGate`) is one * instance; each `StreamController` and `CoordinatedLazy` swap registers with * one too. The behavior is the original layout-shift gate's, plus two opt-in * completion signals (`expect` / `markLast`) for sources that arrive over time * (chunks streaming in across ticks) rather than all within the initial * hydration commit. * * Lifecycle: a source `register()`s and later calls the returned settle * function when it reaches its stable state. The gate opens once every * registered source has settled (and any completion constraint is met). It * opens **once** and never re-closes - a source that registers after the gate * has opened adopts the open state rather than re-closing it for everyone * ("all sources" means "all present by the initial settle"). */ export interface SettleGate { /** * Register a pending source. Returns an idempotent settle function; call it * when the source reaches its stable state. Calling it more than once is a * no-op. Registering after the gate has already opened returns a no-op settle * and does not re-close the gate. */ register(): () => void; /** * `true` before any source registers (nothing to wait for) and once every * registered source has settled and any completion constraint is met. */ isSettled(): boolean; /** * Resolves once {@link isSettled} is `true`. Returns `null` synchronously * when already settled so callers can take a fast path (mirrors the original * `whenLayoutShiftsSettled`). Rejects with an `AbortError` if `signal` aborts * first, so a superseding wait can be abandoned. */ whenSettled(signal?: AbortSignal): Promise<void> | null; /** * Declare how many sources will register in total. The gate then holds until * at least `count` sources have registered (and all have settled), so it * won't open during a momentary lull while later sources are still arriving - * e.g. chunks streaming in across separate ticks. This is **known-count** * completion. * * Pass a non-finite value (e.g. `Number.POSITIVE_INFINITY`) to hold the gate * open-indefinitely for an unknown-count stream, then call {@link markLast} * when the stream ends. */ expect(count: number): void; /** * Terminal signal for **last-chunk** completion. Once called, the gate opens * as soon as every outstanding source has settled, regardless of any `expect` * count. Use it to end an unknown-count stream held open via * `expect(Infinity)`, or to finish early before an `expect(n)` count is * reached. Standalone - it does not require `expect` to have been called. */ markLast(): void; /** Reset all state to the initial unarmed gate. Test-only. */ reset(): void; } /** * Options for {@link createSettleGate}. */ export interface CreateSettleGateOptions { /** * Fallback ceiling (ms): open the gate even if a registered source never * settles. * @default SETTLE_SAFETY_TIMEOUT_MS */ safetyTimeoutMs?: number; /** * Schedule the deferred settle check. Defaults to `queueMicrotask`, which * batches a burst of same-tick registrations before declaring the gate * settled. Injectable so tests can drive the check synchronously. */ scheduleCheck?: (callback: () => void) => void; } /** * Create an independent "all sources settled" gate. See {@link SettleGate} for * the contract. * * Isomorphic - it touches only `setTimeout` and the injectable `scheduleCheck` * (default `queueMicrotask`), so it runs in tests and during SSR without the * DOM. Client-only consumers are responsible for never registering during SSR * (the page-wide layout-shift gate is only ever touched on the client for this * reason). */ export declare function createSettleGate(options?: CreateSettleGateOptions): SettleGate;