Files
orca/mobile/scripts/terminal-document-module-order.mjs
T
Jinwoo-H 4dd1b16039 fix(mobile): start the terminal document per mount (ruling 20)
Round 1's blocking finding: ES module bodies run once per page, so the page's
second mount re-imported nothing and inherited the first mount's elements,
listeners and error reporter. Measured after a remount: zero .xterm nodes in
the live DOM, no selection overlay, nothing reaching onEngineError, and
onWebReady still firing.

Ruling 20: no emitted module does work as it is parsed. Every top-level effect
moved into an exported per-module start function — 86 statements across 14
modules, plus three parse-time captures whose declarations became typed lets.
The generator emits one call sequence in module order at the foot of the
document, so the native script still runs them once at parse; the page runs the
same sequence per mount and dispose undoes the three that outlive the host
element (tap-dispatch, webgl-recovery, host-notify).

installErrorReporter now hands back its own undo, so it stays five seams at six
document sites rather than growing a sixth.

M2: a failed document chunk was an unhandled rejection with no engine error.
It now goes down the document's own reporting path, so the overlay names the
cause instead of the 15s readiness watchdog. Pinned by refusing that chunk at
the wire in the render check.

L3: the seam count now reads five fields / six sites / three files everywhere.
L4: three unrelated web-overrides entries keep main's escaping.

Golden: 106116 -> 108134 bytes; payload 724150 -> 726168, sha256
2d089b8d9ab9491eed79cf7fe353dde6444799a3d297269ab660aee63ba56c82.

Claude-Session: https://claude.ai/code/session_01JNnE9qzUZMMnqpZWCqM3nb
2026-09-20 13:45:55 -04:00

73 lines
2.2 KiB
JavaScript

/**
* The order the document's modules are spliced back into the script, which is the order the
* hand-written document had. It is data, not a dependency graph: the document is one function
* scope, so declarations must land where they landed before.
*
* Both the generator and the equivalence test read this, so neither can drift from the other.
*/
/**
* The host seams, emitted ahead of the scope object: the scope's defaults *are* these functions,
* and the factory that reads them runs as the script is parsed.
*/
export const TERMINAL_DOCUMENT_HOST_SEAMS_MODULE = 'document-host-seams'
/** The scope object, emitted ahead of everything else because everything else reads it. */
export const TERMINAL_DOCUMENT_SCOPE_MODULE = 'document-scope'
export const TERMINAL_DOCUMENT_MODULE_ORDER = [
'runtime-constants',
'terminal-handle',
'query-reply',
'surface-swap',
'text-scaling',
'viewport-transform',
'terminal-theme',
'fit-scale',
'mouse-mode-decset-scan',
'write-queue',
'webgl-recovery',
'terminal-init',
'reflow',
'host-notify',
'host-message-router',
'selection-state-and-eviction',
'mode-mirroring',
'keyboard-avoidance-metrics',
'term-observers',
'viewport-cell',
'mouse-report-cell',
'mouse-input-encoding',
'normal-buffer-smooth-scroll',
'cell-geometry',
'path-tap',
'url-tap',
'osc-link-tap',
'surface-tap',
'selection-range',
'selection-overlay',
'tap-dispatch',
'wheel-scroll',
'mouse-click-drag',
'selection-menu-buttons',
'surface-touch-gestures',
'message-bridge'
]
/**
* The per-module start function's name, by convention rather than by a second list.
*
* Ruling 20: no module does work as it is parsed, so each one that had a top-level effect now
* exports one function holding it. The generator calls the ones that exist, in module order, at
* the foot of the document; the page calls the same names per mount. A convention rather than a
* list because a list is a second place to forget.
*/
export function terminalDocumentStartFunctionName(moduleName) {
return (
'start' +
moduleName
.split('-')
.map((part) => part.charAt(0).toUpperCase() + part.slice(1))
.join('')
)
}