mirror of
https://github.com/stablyai/orca.git
synced 2026-11-01 09:37:33 +00:00
* [comment audit] Align legacy failure-read counts with cached display * [comment audit] Condense shared provider lifecycle and browser recovery comments [skip ci] * [comment audit] Condense shared generation, path and preview comments [skip ci] * [comment audit] Condense host, file and Git contract rationale [skip ci] * [comment audit] Tighten Git lifecycle and provider contract comments [skip ci] * [comment audit] Clarify shared host authority and launch isolation [skip ci] * [comment audit] simplify local access mobile and native chat contracts [skip ci] * [comment audit] simplify native chat presentation and state contracts [skip ci] * [comment audit] simplify native runtime and provider contracts [skip ci] * [comment audit] simplify migration and orchestration contracts [skip ci] * [comment audit] simplify plugin trust and process capture rationale [skip ci] * [comment audit] simplify terminal delivery and remote compatibility rationale [skip ci] * [comment audit] clarify remote recovery and launch wire rationale [skip ci] * [comment audit] shorten shared RPC compatibility and runtime evidence comments [skip ci] * [comment audit] simplify secure storage shell startup and sidebar rationale [skip ci] * [comment audit] clarify sidebar, skill and SSH invariants [skip ci] * [comment audit] condense structured chat delivery and timing rationale [skip ci] * [comment audit] condense terminal replay and telemetry invariants [skip ci] * [comment audit] clarify launch permission and terminal delivery rationale [skip ci] * [comment audit] clarify workspace ownership and layout contracts [skip ci] * [comment audit] wait for fitted and painted SSH terminal links * [comment audit] clarify layout persistence and session ownership [skip ci] * [comment audit] clarify host routing and workspace lifecycle contracts [skip ci] * [comment audit] clarify startup persistence and app lifetime comments [skip ci] * [comment audit] clarify recovery and activity boundaries [skip ci] * [comment audit] condense activity and artifact invariants [skip ci] * [comment audit] condense automation authority contracts [skip ci] * [comment audit] simplify automation scheduling and history contracts [skip ci] * [comment audit] clarify browser chrome and annotation lifecycles [skip ci] * [comment audit] clarify browser routing and retained guest ownership [skip ci] * [comment audit] clarify browser recovery and document ownership comments [skip ci] * [comment audit] restore hosted runners required by native IME fixtures * [comment audit] shorten preview, palette and dashboard invariants [skip ci] * [comment audit] clarify terminal preview, dashboard and retention comments [skip ci] * [comment audit] clarify diff-note recovery and editor lifecycle comments [skip ci] * [comment audit] shorten rich-text and combined-diff ownership comments [skip ci] * [comment audit] shorten autosave, draft recovery and model ownership comments [skip ci] * [comment audit] shorten save-queue, notebook and Markdown constraints [skip ci] * [comment audit] shorten Monaco, PDF and rich Markdown safeguards [skip ci] * [comment audit] clarify rich Markdown source and selection safeguards [skip ci] * [comment audit] clarify editor loading and emulator stream lifetimes [skip ci] * [comment audit] trim emulator and feature tour narration [skip ci] * [comment audit] clarify floating workspace and GitHub cache ownership [skip ci] * [comment audit] trim provider controls and Linear filter explanations [skip ci] * [comment audit] clarify pairing and chat resume lifetimes [skip ci] * [comment audit] clarify chat delivery and transcript lifetimes [skip ci] * [comment audit] clarify session options and host-owned status [skip ci] * [comment audit] clarify draft durability and live-status precedence [skip ci] * [comment audit] Trim chat send and model ownership explanations [skip ci] * [comment audit] Shorten transcript ownership and send recovery comments [skip ci] * [comment audit] Simplify native chat composer and transcript hook comments [skip ci] * [comment audit] Shorten native chat scroll and structured session explanations [skip ci] * [comment audit] Trim workspace picker and onboarding commentary [skip ci] * [comment audit] Simplify pet rendering, review cache and quick open comments [skip ci] * [comment audit] Trim sidebar and session history explanations [skip ci] * [comment audit] Condense session resume and review checks comments [skip ci] * [comment audit] Shorten checks state and file explorer refresh comments [skip ci] * [comment audit] Trim plugin bridge and source-control action rationale [skip ci] * [comment audit] Trim source-control listing and review rationale [skip ci] * [comment audit] Shorten sidebar lifecycle and explorer safeguards [skip ci] * [comment audit] Condense Settings account and appearance rationale [skip ci] * [comment audit] Trim pairing and repository Settings explanations [skip ci] * [comment audit] Condense Settings search SSH and terminal safeguards [skip ci] * [comment audit] Shorten Settings voice and provider ownership comments [skip ci] * [comment audit] Condense Settings draft persistence and host-state rationale [skip ci] * [comment audit] Trim Settings hooks and sidebar setup rationale [skip ci] * [comment audit] Condense sidebar deletion and board-filter safeguards [skip ci] * [comment audit] Condense worktree cards, host ownership and Markdown contracts [skip ci] * [comment audit] Condense sidebar drag, folder and filtering contracts [skip ci] * [comment audit] Condense sidebar parity, sleep and host ownership contracts [skip ci] * [comment audit] Prune focus-read baseline after comment cleanup * [comment audit] Clarify sidebar visibility, board drops and agent evidence [skip ci] * [comment audit] Tighten sidebar listing, drag and reveal contracts [skip ci] * [comment audit] Clarify viewport geometry and skill update safeguards [skip ci] * [comment audit] Tighten skill inventory, usage and host status comments [skip ci] * [comment audit] Clarify usage ownership and resource kill safeguards [skip ci] * [comment audit] Tighten tab selection, rename and search contracts [skip ci] * [comment audit] Tighten tab-strip geometry and drag ownership comments [skip ci] * [comment audit] Tighten Tasks recovery, pagination and mutation comments [skip ci] * [comment audit] Tighten provider loading and terminal recovery comments [skip ci] * [comment audit] Tighten completion, cadence and PTY ownership comments [skip ci] * [comment audit] Clarify terminal restore and parked-pane boundaries [skip ci] * [comment audit] Tighten PTY startup and replay explanations [skip ci] * [comment audit] Clarify PTY identity and delivery ownership [skip ci] * [comment audit] Shorten remote reconnect and input replay rationale [skip ci] * [comment audit] Condense terminal parking clipboard and file link comments [skip ci] * [comment audit] Clarify IME ownership and trim trace history [skip ci] * [comment audit] Shorten pane recovery and parked watcher explanations [skip ci] * [comment audit] Condense snapshot replay and visibility recovery rationale [skip ci] * [comment audit] Shorten terminal parking and keyboard ownership rationale [skip ci] * [comment audit] Trim renderer lifecycle and menu rationale [skip ci] * [comment audit] Condense workspace cleanup ownership and settlement notes [skip ci] * [comment audit] Clarify renderer hook evidence and source ownership [skip ci] * [comment audit] Tighten IPC ownership and reconnect explanations [skip ci] * [comment audit] Trim renderer focus, paste and attention comments [skip ci] * [comment audit] Shorten scroll, locale and agent lifecycle comments [skip ci] * [comment audit] Trim agent launch, resume and ownership commentary [skip ci] * [comment audit] Shorten account, browser and editor comments [skip ci] * [comment audit] Clarify host-mirror waits, previews and input ownership [skip ci] * [comment audit] Condense launch recovery and editor tokenization comments [skip ci] * [comment audit] Condense workspace selection and terminal pane rationale [skip ci] * [comment audit] Condense terminal fitting and rendering recovery comments [skip ci] * [comment audit] Condense terminal input and host routing explanations [skip ci] * [comment audit] Condense ownership and sleeping-session recovery rationale [skip ci] * [comment audit] Condense structured launch and terminal link explanations [skip ci] * [comment audit] Condense terminal ownership and workspace file routing rationale [skip ci] * [comment audit] Condense session persistence and workspace activation rationale [skip ci] * [comment audit] Condense workspace routing and browser ownership rationale [skip ci] * [comment audit] Condense mirror recovery and layout authority rationale [skip ci] * [comment audit] Condense runtime transport and file safety rationale [skip ci] * [comment audit] Condense runtime graph and structured session rationale [skip ci] * [comment audit] Condense browser creation and remote tab recovery rationale [skip ci] * [comment audit] Condense snapshot authority and publisher recovery rationale [skip ci] * [comment audit] Condense frame, startup and provider cache rationale [skip ci] * [comment audit] Condense host twin and agent lifecycle rationale [skip ci] * [comment audit] Condense browser authority and editor cleanup rationale [skip ci] * [comment audit] Condense editor buffer identity and review cache rationale [skip ci] * [comment audit] Condense provider lifetime and repository ownership rationale [skip ci] * [comment audit] Condense reconnect, hydration and terminal retirement rationale [skip ci] * [comment audit] Condense recovery, reconciliation and persistence rationale [skip ci] * [comment audit] Condense cleanup ownership and listing admission rationale [skip ci] * [comment audit] Condense teardown ordering and terminal ownership rationale [skip ci] * [comment audit] Condense recovery ledger and web host-boundary rationale [skip ci] * [comment audit] Condense web reconnect and credential lifecycle rationale [skip ci] * [comment audit] Condense cloud rollout and assignment safety rationale [skip ci] * [comment audit] Condense relay session and database recovery rationale [skip ci] * [comment audit] Condense relay placement and protocol compatibility rationale [skip ci] * [comment audit] Condense build and packaging constraints [skip ci] * [comment audit] Condense CI gates and validation isolation rationale [skip ci] * [comment audit] Condense catalog identity and browser validation rationale [skip ci] * [comment audit] Condense mobile browser and frame-budget rationale [skip ci] * [comment audit] Shorten mobile route and browser test explanations [skip ci] * [comment audit] Condense editor and session seam test rationale [skip ci] * [comment audit] Trim session and terminal closure history [skip ci] * [comment audit] Shorten terminal browser and census explanations [skip ci] * [comment audit] Preserve root-only E2E diagnostic baseline * [comment audit] Condense mobile seam and HTML preview test rationale [skip ci] * [comment audit] Condense preview instrumentation and render harness rationale [skip ci] * [comment audit] Condense bundle contracts and native-build constraints [skip ci] * [comment audit] Shorten native packaging and CI routing rationale [skip ci] * [comment audit] Condense release tooling and benchmark constraints [skip ci] * [comment audit] Condense packaging and platform gate rationale [skip ci] * [comment audit] Shorten mobile route and history rationale [skip ci] * [comment audit] Condense mobile browser and component rationale [skip ci] * [comment audit] Shorten drawer and workspace-form rationale [skip ci] * [comment audit] Trim mobile review and editor-document explanations [skip ci] * [comment audit] Condense editor lifecycle and Markdown explanations [skip ci] * [comment audit] Trim mobile file, diagnostics and dictation commentary [skip ci] * [comment audit] Simplify mobile host-list and workspace-view explanations [skip ci] * [comment audit] Clarify mobile shell lifetime and bridge delivery constraints [skip ci] * [comment audit] Condense bridge stream, native request and audio rationale [skip ci] * [comment audit] Reduce bridge schema and page-client commentary [skip ci] * [comment audit] Tighten mobile page bridge contracts [skip ci] * [comment audit] Clarify mobile cache and session constraints [skip ci] * [comment audit] Condense mobile route and lifecycle rationale [skip ci] * [comment audit] Tighten mobile shell hook timing rationale [skip ci] * [comment audit] Clarify route handoff and notification compatibility [skip ci] * [comment audit] Clarify push registration and dictation cleanup constraints [skip ci] * [comment audit] Condense keyboard geometry and native media ownership rationale [skip ci] * [comment audit] Tighten mobile chat scroll and composer concurrency rationale [skip ci] * [comment audit] Condense mobile reply compatibility and upload ownership rationale [skip ci] * [comment audit] Condense optimistic echo and scroll ownership rationale [skip ci] * [comment audit] Tighten stream replay and queued session ownership rationale [skip ci] * [comment audit] Condense mobile composer and reply-schema constraints [skip ci] * [comment audit] Clarify mobile transcript recovery and session ownership [skip ci] * [comment audit] Clarify mobile queue and source-control compatibility [skip ci] * [comment audit] Condense storage and task launch constraints [skip ci] * [comment audit] Clarify task schemas and terminal document ownership [skip ci] * [comment audit] Tighten terminal input and viewport rationale [skip ci] * [comment audit] Shorten terminal and RPC recorder contracts [skip ci] * [comment audit] Condense recorder engine and connection contracts [skip ci] * [comment audit] Shorten host credential and relay recovery comments [skip ci] * [comment audit] Tighten pairing recovery and bundle transport rationale [skip ci] * [comment audit] Clarify RPC delivery and workspace catalog boundaries [skip ci] * [comment audit] Condense catalog and relay entry contracts [skip ci] * [comment audit] Shorten shutdown and SSH relay delivery contracts [skip ci] * [comment audit] Condense WSL relay and E2E regression rationale [skip ci] * [comment audit] Shorten cross-version harness and renderer fixture explanations [skip ci] * [comment audit] Condense paired-host and E2E lifecycle rationale [skip ci] * [comment audit] Shorten layout oracle and regression explanations [skip ci] * [comment audit] Condense paired recovery and ownership regression contracts [skip ci] * [comment audit] Shorten restart, sidebar and SSH lifecycle contracts [skip ci] * [comment audit] Condense terminal rendering and IME regression rationale [skip ci] * [comment audit] Shorten terminal recovery and benchmark contracts [skip ci] * [comment audit] Condense tooling and Windows lifecycle proof rationale [skip ci] * [comment audit] Condense workflow routing and release rationale [skip ci] * [comment audit] Condense mobile security and installer contracts [skip ci] * [comment audit] Shorten native rationale and stylesheet workarounds [skip ci] * [comment audit] Shorten Windows visibility probe rationale [skip ci] * [comment audit] Condense embedded release and signing rationale [skip ci] * [comment audit] Retain current main test behavior in final reconciliation [skip ci] * [comment audit] Complete final comment review across current source inventory * [comment audit] Handle consolidated audit reports before final CI * [comment audit] Preserve credential storage census detail [skip ci] * [comment audit] Scale broad changed E2E selections with verified timing shards * [comment audit] Align E2E assertions with browser close and settled session metadata * [comment audit] Match existing E2Es to current resource and windowing contracts * [comment audit] Observe the shared server outage notice in reconnect coverage * [comment audit] Make existing renderer probes measure settled tab and PTY work * [comment audit] Align palette E2E selector with task search * [comment audit] Refresh remaining palette search selectors * [comment audit] Keep selector correction within selected audit specs * [comment audit] Await emoji fixture settings inside renderer evaluation * [comment audit] Cancel fixture fit retries between terminal tests --------- Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
253 lines
10 KiB
TypeScript
253 lines
10 KiB
TypeScript
// Count runtime graph publications at main’s invoke handler because contextBridge freezes renderer window.api.
|
||
// Long-task numbers are unproven until ORCA_TYPING_BENCH_GRAPH_PROBE_SELFTEST_MS yields its own nonzero entry; exclude that entry from workload summaries.
|
||
// Main-handler durations exclude renderer graph build: use a CPU profile for that cost.
|
||
// Diagnostic gate ORCA_TYPING_BENCH_GRAPH_PROBE=1 must stay off in acceptance timing runs.
|
||
import type { ElectronApplication, Page } from '@stablyai/playwright-test'
|
||
|
||
const GRAPH_CHANNEL = 'runtime:syncWindowGraph'
|
||
|
||
export type DurationSummary = {
|
||
count: number
|
||
totalMs: number
|
||
maxMs: number
|
||
p50Ms: number
|
||
p90Ms: number
|
||
}
|
||
|
||
export type LongTaskSample = { startEpochMs: number; durationMs: number }
|
||
|
||
/** Renderer-clock bounds of the injected busy-wait, same base as long-task entries. */
|
||
export type RendererLongTaskSelfTestWindow = { startEpochMs: number; endEpochMs: number }
|
||
|
||
export type RuntimeGraphPublicationProbeSnapshot = {
|
||
mainCounterInstalled: boolean
|
||
mainCounterReason: string
|
||
rendererObserverInstalled: boolean
|
||
rendererObserverReason: string
|
||
/** Publications counted at main's invoke handler. */
|
||
publications: number
|
||
/** Main-side handler duration (excludes the renderer-side graph build). */
|
||
mainHandler: DurationSummary
|
||
/** Gaps between consecutive publications, epoch ms. */
|
||
publicationIntervalMs: DurationSummary
|
||
/** Workload long tasks; the self-test's own entry is excluded. */
|
||
longTasks: DurationSummary
|
||
/** Non-zero only when the self-test's own entry was observed; proves the oracle is live. */
|
||
selfTestLongTaskMs: number
|
||
/** Long tasks whose window contains a publication's main-side arrival. */
|
||
longTasksAroundPublication: DurationSummary
|
||
longestLongTasks: LongTaskSample[]
|
||
}
|
||
|
||
type MainProbeGlobals = {
|
||
__orcaGraphPublicationMainProbe?: {
|
||
stop: () => { count: number; handlerMs: number[]; atEpochMs: number[] }
|
||
}
|
||
}
|
||
|
||
type RendererProbeWindow = Window & {
|
||
__orcaGraphPublicationRendererProbe?: {
|
||
stop: () => { timeOrigin: number; longTasks: { start: number; duration: number }[] }
|
||
}
|
||
}
|
||
|
||
function summarize(values: number[]): DurationSummary {
|
||
if (values.length === 0) {
|
||
return { count: 0, totalMs: 0, maxMs: 0, p50Ms: 0, p90Ms: 0 }
|
||
}
|
||
const sorted = [...values].sort((a, b) => a - b)
|
||
const at = (fraction: number): number =>
|
||
sorted[Math.min(sorted.length - 1, Math.floor(fraction * sorted.length))] ?? 0
|
||
const round = (value: number): number => Number(value.toFixed(1))
|
||
return {
|
||
count: sorted.length,
|
||
totalMs: round(sorted.reduce((sum, value) => sum + value, 0)),
|
||
maxMs: round(sorted.at(-1) ?? 0),
|
||
p50Ms: round(at(0.5)),
|
||
p90Ms: round(at(0.9))
|
||
}
|
||
}
|
||
|
||
// Inject a known renderer busy-wait and return its own clock bounds so unrelated setup tasks cannot prove observer liveness.
|
||
export async function injectRendererLongTaskSelfTest(
|
||
page: Page,
|
||
busyMs: number
|
||
): Promise<RendererLongTaskSelfTestWindow> {
|
||
return page.evaluate((durationMs) => {
|
||
const startedAt = performance.now()
|
||
const deadline = startedAt + durationMs
|
||
while (performance.now() < deadline) {
|
||
// Intentional busy wait: setTimeout would not produce a long task.
|
||
}
|
||
return {
|
||
startEpochMs: performance.timeOrigin + startedAt,
|
||
endEpochMs: performance.timeOrigin + performance.now()
|
||
}
|
||
}, busyMs)
|
||
}
|
||
|
||
// The nonoverlapping task containing the busy-wait midpoint is the self-test; earlier or merely overlapping entries cannot prove it.
|
||
export function partitionSelfTestLongTask(
|
||
longTasks: LongTaskSample[],
|
||
selfTest: RendererLongTaskSelfTestWindow | null
|
||
): { selfTestLongTaskMs: number; workloadLongTasks: LongTaskSample[] } {
|
||
if (!selfTest) {
|
||
return { selfTestLongTaskMs: 0, workloadLongTasks: longTasks }
|
||
}
|
||
const midpoint = (selfTest.startEpochMs + selfTest.endEpochMs) / 2
|
||
const selfTestTask = longTasks.find(
|
||
(task) => task.startEpochMs <= midpoint && midpoint <= task.startEpochMs + task.durationMs
|
||
)
|
||
if (!selfTestTask) {
|
||
return { selfTestLongTaskMs: 0, workloadLongTasks: longTasks }
|
||
}
|
||
return {
|
||
selfTestLongTaskMs: Number(selfTestTask.durationMs.toFixed(1)),
|
||
// Identity, not value: duplicate-looking entries must not be dropped too.
|
||
workloadLongTasks: longTasks.filter((task) => task !== selfTestTask)
|
||
}
|
||
}
|
||
|
||
export async function startRuntimeGraphPublicationProbe(
|
||
electronApp: ElectronApplication,
|
||
page: Page
|
||
): Promise<{ main: string; renderer: string }> {
|
||
const main = await electronApp.evaluate(({ ipcMain }, channel): string => {
|
||
// oxlint-disable-next-line typescript/consistent-type-assertions -- SAFETY: diagnostic-only read of Electron's private invoke-handler map; every use is guarded by the shape checks below.
|
||
const registry = (ipcMain as unknown as { _invokeHandlers?: Map<string, unknown> })
|
||
._invokeHandlers
|
||
if (!(registry instanceof Map)) {
|
||
return 'no-invoke-handler-registry'
|
||
}
|
||
const original = registry.get(channel)
|
||
if (typeof original !== 'function') {
|
||
return `handler-missing typeof=${typeof original}`
|
||
}
|
||
// oxlint-disable-next-line typescript/consistent-type-assertions -- SAFETY: Electron stores invoke handlers as callables; arguments are forwarded unchanged and never introspected.
|
||
const call = original as (...args: unknown[]) => unknown
|
||
const handlerMs: number[] = []
|
||
const atEpochMs: number[] = []
|
||
const publications = { count: 0, handlerMs, atEpochMs }
|
||
const wrapped = async (...args: unknown[]): Promise<unknown> => {
|
||
const startedAt = Date.now()
|
||
const startedHr = process.hrtime.bigint()
|
||
publications.count += 1
|
||
publications.atEpochMs.push(startedAt)
|
||
try {
|
||
return await call(...args)
|
||
} finally {
|
||
publications.handlerMs.push(Number(process.hrtime.bigint() - startedHr) / 1e6)
|
||
}
|
||
}
|
||
registry.set(channel, wrapped)
|
||
// oxlint-disable-next-line typescript/consistent-type-assertions -- SAFETY: main-process bag read back only by the paired stop() call in this same run.
|
||
const globals = globalThis as unknown as MainProbeGlobals
|
||
globals.__orcaGraphPublicationMainProbe = {
|
||
stop: () => {
|
||
if (registry.get(channel) === wrapped) {
|
||
registry.set(channel, original)
|
||
}
|
||
delete globals.__orcaGraphPublicationMainProbe
|
||
return publications
|
||
}
|
||
}
|
||
return 'installed'
|
||
}, GRAPH_CHANNEL)
|
||
|
||
const renderer = await page.evaluate((): string => {
|
||
const probeWindow: RendererProbeWindow = window
|
||
if (probeWindow.__orcaGraphPublicationRendererProbe) {
|
||
return 'already-installed'
|
||
}
|
||
const supported = PerformanceObserver.supportedEntryTypes ?? []
|
||
if (!supported.includes('longtask')) {
|
||
return `longtask-unsupported supported=${supported.join('|')}`
|
||
}
|
||
const longTasks: { start: number; duration: number }[] = []
|
||
let observer: PerformanceObserver
|
||
try {
|
||
observer = new PerformanceObserver((list) => {
|
||
for (const entry of list.getEntries()) {
|
||
longTasks.push({ start: entry.startTime, duration: entry.duration })
|
||
}
|
||
})
|
||
observer.observe({ entryTypes: ['longtask'] })
|
||
} catch (error) {
|
||
return `longtask-observer-unavailable ${String(error)}`
|
||
}
|
||
probeWindow.__orcaGraphPublicationRendererProbe = {
|
||
stop: () => {
|
||
for (const entry of observer.takeRecords()) {
|
||
longTasks.push({ start: entry.startTime, duration: entry.duration })
|
||
}
|
||
observer.disconnect()
|
||
delete probeWindow.__orcaGraphPublicationRendererProbe
|
||
return { timeOrigin: performance.timeOrigin, longTasks }
|
||
}
|
||
}
|
||
return 'installed'
|
||
})
|
||
|
||
return { main, renderer }
|
||
}
|
||
|
||
export async function stopRuntimeGraphPublicationProbe(
|
||
electronApp: ElectronApplication,
|
||
page: Page,
|
||
start: { main: string; renderer: string },
|
||
selfTest: RendererLongTaskSelfTestWindow | null = null
|
||
): Promise<RuntimeGraphPublicationProbeSnapshot> {
|
||
const mainResult =
|
||
start.main === 'installed'
|
||
? await electronApp.evaluate(() => {
|
||
// oxlint-disable-next-line typescript/consistent-type-assertions -- SAFETY: reads back the bag installed by startRuntimeGraphPublicationProbe in this run.
|
||
const globals = globalThis as unknown as MainProbeGlobals
|
||
return globals.__orcaGraphPublicationMainProbe?.stop() ?? null
|
||
})
|
||
: null
|
||
const rendererResult =
|
||
start.renderer === 'installed'
|
||
? await page.evaluate(() => {
|
||
const probeWindow: RendererProbeWindow = window
|
||
return probeWindow.__orcaGraphPublicationRendererProbe?.stop() ?? null
|
||
})
|
||
: null
|
||
|
||
const publicationEpochMs = mainResult?.atEpochMs ?? []
|
||
const intervals = publicationEpochMs
|
||
.slice(1)
|
||
.map((value, index) => value - (publicationEpochMs[index] ?? value))
|
||
const timeOrigin = rendererResult?.timeOrigin ?? 0
|
||
const longTasks: LongTaskSample[] = (rendererResult?.longTasks ?? []).map((task) => ({
|
||
startEpochMs: timeOrigin + task.start,
|
||
durationMs: task.duration
|
||
}))
|
||
const { selfTestLongTaskMs, workloadLongTasks } = partitionSelfTestLongTask(longTasks, selfTest)
|
||
// A renderer graph build ends at the invoke; allow slack for IPC transit either way.
|
||
const around = workloadLongTasks.filter((task) =>
|
||
publicationEpochMs.some(
|
||
(at) => at >= task.startEpochMs - 5 && at <= task.startEpochMs + task.durationMs + 50
|
||
)
|
||
)
|
||
|
||
return {
|
||
mainCounterInstalled: start.main === 'installed',
|
||
mainCounterReason: start.main,
|
||
rendererObserverInstalled: start.renderer === 'installed',
|
||
rendererObserverReason: start.renderer,
|
||
publications: mainResult?.count ?? 0,
|
||
mainHandler: summarize(mainResult?.handlerMs ?? []),
|
||
publicationIntervalMs: summarize(intervals),
|
||
longTasks: summarize(workloadLongTasks.map((task) => task.durationMs)),
|
||
selfTestLongTaskMs,
|
||
longTasksAroundPublication: summarize(around.map((task) => task.durationMs)),
|
||
longestLongTasks: [...workloadLongTasks]
|
||
.sort((a, b) => b.durationMs - a.durationMs)
|
||
.slice(0, 10)
|
||
.map((task) => ({
|
||
startEpochMs: task.startEpochMs,
|
||
durationMs: Number(task.durationMs.toFixed(1))
|
||
}))
|
||
}
|
||
}
|