/******************************************************************************** * Copyright (c) 2026 CrossBreeze, EclipseSource and others. * * This program and the accompanying materials are made available under the * terms of the MIT License which is available in the project root. * * SPDX-License-Identifier: MIT ********************************************************************************/ import type { DataConnection, DataServerProtocol, DataSession, DiagnosticOf, TransferElement } from '@hydranium/protocol'; import { FrontendApplicationContribution, type OnWillStopAction } from '@theia/core/lib/browser/frontend-application-contribution'; import { type interfaces } from '@theia/core/shared/inversify'; /** * Ends a Theia frontend's data sessions with its page, and holds the page * while one of them is still saving. {@link bindDataConnection} binds it and * has it {@link track} each data connection bound through it. * * **Stop.** {@link onStop} disposes every tracked session, which sends its * `closeSession`, so the server ends it as closed: each document it was the * last to hold is released at once. Otherwise the server learns of the page only * when its connection goes, which Theia may hold open for its reconnect * timeout, and then ends the sessions as lost, so their documents wait out the * release grace. The close is best effort: under load the page's last frames * can be lost on the way, and the server then ends the sessions as lost. A * session with calls still in flight at the stop closes after them, which is * too late for a page going away, and is left to the server's connection-close * cleanup. A call a session makes in the same tick as the stop is refused and * never sent. * * **Veto.** While a tracked session has a save in flight, {@link onWillStop} * vetoes, including a session disposed meanwhile. In Electron, Theia awaits * the veto's action, which waits for the saves to answer, a save started during * the wait included, up to {@link maxSettlePasses} times. The browser runs no * action before unload, so there the veto shows the leave-page prompt and * nothing more. Theia ignores every veto under * `application.confirmExit: 'never'`, so there a save in flight at the stop * may be cut off. */ export declare class DataSessionStopContribution implements FrontendApplicationContribution { /** The sessions to end at the stop, and to wait for while they save. */ protected readonly sessions: Set>>; /** * How many times the veto's action waits for the saves in flight before it * lets the stop go. Each wait ends by the session's own bound, so a save * that never answers holds the stop for a few bounds, not for good. */ protected readonly maxSettlePasses: number; /** * Take every session of `connection` into the stop: the ones it has * started already, and each one it starts from now on. Generic, so a * connection of any transfer root, server and client fits. */ track>, TClient extends object>(connection: DataConnection): void; /** * Take `session` into the stop. It leaves once it has ended and its saves * have answered, so a session disposed with a save in flight still holds * the page. */ protected trackSession(session: DataSession): void; onWillStop(): OnWillStopAction | undefined; /** The tracked sessions with a save in flight. */ protected savingSessions(): DataSession[]; onStop(): void; } /** * Bind `connectionClass` in singleton scope, its sessions tracked by the * {@link DataSessionStopContribution}, and bind that contribution and the * `ConnectionReporter` the connection's port injects unless they are bound * already. The binding's `onActivation` is taken; a frontend's own hook on the * connection goes on the container's `onActivation`, which runs after it. A * subclass of the contribution is rebound after this call: one bound before it * is never registered as a frontend contribution, so its stop never runs. * Call it once per connection class: a second call makes the class's lookup * ambiguous. */ export declare function bindDataConnection>, TClient extends object>(bind: interfaces.Bind, isBound: interfaces.IsBound, connectionClass: interfaces.Newable>): void; //# sourceMappingURL=data-session-stop-contribution.d.ts.map