Mosh implements local “tentative echo”, which makes network latency less a problem. DomTerm implements this leveraging the “deferred deletion” mechanism (used for line mode echo).
To do this we use a <span> that contains predicted input:
an optional text node, the _caretNode, and an optional text node.
The node has 3 additional properties: textBefore, textAfter,
and pendingEcho. When output arrives from the server,
the function _doDeferredDeletion is called,
which replaces the span by the textBefore and textAfter,
with the _caretNode in between; this is “real” (confirmed) output,
before processing the new output.
We also _doDeferredDeletion when unable to do echo predication.
Handling keyboard input is as follows:
First, if _deferredForDeletion is null, we set it to a fresh span
that wraps the _caretNode.
As needed, any text node immediately before or after can be moved
into the _deferredForDeletion span, also setting textBefore
and textAfter.
Then, for a printing character, we insert it before the caret,
and append it to pendingEcho.
For left or right arrow, delete, or backspace, if possible we adjust the
_deferredForDeletion span appropriately,
and add a special code to pendingEcho.
If not possible, we _doDeferredDeletion, which we
also do for other keys.
Calling _doDeferredDeletion just before handling output
is correct but suboptimal if the output only contains part
of the pending echo.
In that case we try to create (after handling output) a new
_deferredForDeletion span, whose pendingEcho string
is a tail of the previous value.
(We only do this if there are no changes to any other (logical) line.)