@mui/internal-docs-infra
Version:
MUI Infra - internal documentation creation tools.
96 lines • 4.32 kB
text/typescript
/**
* 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;