import type { ElementType } from 'react'; import type { DevRuntime as RolldownDevRuntime } from 'rolldown/experimental/runtime-types'; import { type HmrInfo } from './hmr-protocol.ts'; /** Lexical base class injected into the runtime chunk by Rolldown; typed via the contract. */ declare const DevRuntime: new (clientId: string) => RolldownDevRuntime; /** Mode-independent patch metadata consumed by the shared sequence and graph reducer. */ export type RuntimePatch = Readonly<{ seq: number; /** Stable ids of the changed modules; synchronous application walks the graph from these roots. */ changedIds: readonly string[]; }>; type AcceptCallback = (moduleExports: unknown) => void; /** * Per-module hot state, mirroring Rolldown's web runtime: accept is a passive registration; * the propagation invokes the previous execution's callbacks with the fresh exports. */ declare class MiniHotContext { readonly _internal: Readonly<{ updateStyle(): void; removeStyle(): void; }>; /** * Callbacks registered by this module execution. The array is allocated on first accept, * remains attached to the old execution across cache eviction, and is invoked by the next * boundary execution. Undefined means this context stays passive. */ private acceptCallbacks; /** Stable module identity and shared sparse index used only when this context accepts. */ private readonly moduleId; private readonly acceptingContexts; constructor(moduleId: string, acceptingContexts: Map); accept(callback?: AcceptCallback): void; /** Invokes this old context's callbacks; invalidation aborts the update synchronously. */ runAccept(moduleExports: unknown): void; invalidate(reason?: string): never; prune(_callback?: () => void): void; } /** Task-scoped socket surface shared by the WX and Alipay Mini Program APIs. */ export type MiniSocketTask = Readonly<{ send(options: Readonly<{ data: string; }>): void; close(options: Readonly<{ code: number; reason: string; }>): void; onOpen(listener: () => void): void; onClose(listener: () => void): void; onError(listener: () => void): void; onMessage(listener: (result: Readonly<{ data: unknown; }>) => void): void; }>; /** Connects one App-level HMR socket using the active platform API. */ export type ConnectMiniSocket = (endpoint: string) => MiniSocketTask; /** Shared Mini Program host mechanics extending the Rolldown contract instead of reimplementing it. */ export declare class MiniHmrRuntime extends DevRuntime { /** * One session for the running App. Undefined only before the mode-selected entry initializes the runtime; its identity then * stays fixed while appliedSeq records the committed frontier. */ private session; private socket; /** * Sparse current-generation accepting boundaries keyed by module id. Entries alone must * outlive Rolldown module-cache eviction so old callbacks can receive fresh exports. * createModuleHotContext removes the prior generation immediately; first accept inserts * the new one. Passive contexts are never retained, so space is O(number of boundaries). */ private readonly moduleHotContexts; /** Immutable platform socket constructor retained until the running App initializes. */ private readonly connectSocket; constructor(connectSocket: ConnectMiniSocket); /** * Generated code always calls this before registerModule and reads `_internal` from the * return value. Each execution immediately retires its previous accepting boundary; * calling accept registers the new context after the apply plan captured old callbacks. */ createModuleHotContext(moduleId: string): MiniHotContext; /** Resolves a cold Page against patches installed before its physical capsule first executed. */ resolvePageComponent(moduleId: string, baseline: ElementType): ElementType; /** Computes accepting boundaries and every executed module that must be re-armed. */ private computeHmrUpdate; /** Walks executed importers until an accepting boundary is found. */ private bubble; /** * Applies one patch in three phases: capture old contexts, evict the whole update set, * then re-run accepting modules and pass their fresh exports to the old contexts. */ private applyHmrUpdate; /** * Initializes exactly once each time DevTools loads the App. Repeated entry evaluation must not replace the identity or reset `appliedSeq`, because * either change could acknowledge factories against another host client or replay already committed application generations. */ initialize(info: HmrInfo): void; /** Receives mode-specific Vite custom events after shared control messages have been handled. */ protected onSocketEvent(_info: HmrInfo, _event: string, _data: unknown): void; /** Closes the sole socket after terminal host control or patch failure in either mode. */ protected stopSocket(reason: string): void; /** * Applies one mode-delivered cumulative payload through its mode-specific patch installer. * * Application is deliberately synchronous so every later message observes the committed module generation. The installer is * the only mode seam; sequence validation and ACK reporting stay here so no mode can mistake delivery for application. */ protected applyPatchPayload(payload: Readonly<{ buildId: string; patches: readonly Patch[]; }>, installPatch: (patch: Patch) => void): void; /** * Folds one cumulative mode delivery into a single logical HMR update. * * A delivery may contain several unacknowledged application patches and may be replayed by its mode—for DevTools, every * affected live Page evaluates the same physical file. The runtime therefore ignores old sequences, rejects a missing one, * and moves directly from the live module generation to the latest published one without intermediate renders. * * For an appliedSeq of 4: * * - [5, 6, 7] installs every patch, applies their unioned changedIds, commits appliedSeq 7, and reports 7; * - a replay of [5, 6, 7] leaves the latest factories untouched; * - [5, 7] fails at expected sequence 6, keeps appliedSeq 4, and requests a complete rebuild. */ private applyPatchBatch; /** Sends one application-frontier or rebuild report through the shared Vite WebSocket. */ private sendReport; } export {};