/** * Folds the Timeline list's spans into update ticks, as pure functions. * * One component update is four spans (`performUpdate`, `willUpdate`, * `update`, `updated`) plus whatever else happened inside it. Read flat, that * is four rows per tick and the reader loses the thread; this module turns the * filtered span list into the rows the list shows — one `performUpdate` row * per tick, with the rest folded under it while the tick is expanded. * * What folds is decided by `groupId`: the lifecycle layer stamps every phase of * a tick with `${elementId}:${tick}`, and the lifecycle layer's point events * (`update skipped`, Lit warnings, late async errors) and the Custom events * layer's rows (when dispatched during the element's own update) carry the same * id. Folding is one level deep and never crosses ticks. * * A `@lit/task` run's `task` span has a groupId of its own (`task:…`), so it * stays a top-level row, from the update that started it to when it settled. * * Why a tick ran (`TimelineSpan.cause`) is not nested here: rows stay in time * order and `cause-rails.ts` draws the chain as rails. {@link causeParentKey} * only looks the cause's target up. * * Framework-free and memoisation-free on purpose: the list recomputes it when * its spans, filter or expanded set change, and the cost is linear. */ import { type TimelineSpan } from './derive.js'; /** What a collapsed tick row flags about the rows it hides. */ export type TickAttention = 'error' | 'warning' | 'skipped'; /** One row of the list: a span at a depth, with its fold's state if it has one. */ export interface ListRow { span: TimelineSpan; /** 0 for top-level rows, 1 for a row folded under a tick. */ depth: number; /** Set on a tick row that has shown children. */ tick?: { expanded: boolean; /** Children that pass the filters (what expanding would show). */ count: number; /** The most severe thing among the shown children, or the tick itself. */ attention?: TickAttention; /** * The reactive properties the update changed, from its phases in the * order they first appear. The lifecycle layer records them on * `willUpdate` and `update`; `performUpdate` carries none, so the row * that stands for the tick would otherwise say nothing about them. */ changed?: string[]; }; } /** A `@lit/task` run's span, which can cause, and be caused, like a tick. */ export declare const isTaskRun: (span: TimelineSpan) => boolean; /** * Every folded span's key mapped to the key of its tick, computed once for all * of `spans`; what "expand all" opens. */ export declare const foldParentKeys: (spans: readonly TimelineSpan[]) => Map; /** The key of the `performUpdate` row `span` folds under, if it folds. */ export declare const foldParentKey: (span: TimelineSpan, spans: readonly TimelineSpan[]) => string | undefined; /** * The key of the span that caused the tick or task run `span`, if it has a * recorded cause whose target is among `spans`: the tick root the `update` * cause names, the `task` span the `task` cause names, or the point span (no * `groupId`) at the `event` cause's layer and time. A `devtools` cause names * no row. */ export declare const causeParentKey: (span: TimelineSpan, spans: readonly TimelineSpan[]) => string | undefined; /** * Builds the list's rows. * * `candidates` are the spans of the enabled layers, in start order; `matched` * is the subset the element, regex and range filters keep. Rules: * * - A tick that matches is shown with all of its candidate children. A tick * that does not match is shown anyway when a child matches (so the match * keeps its context), with just the matching children under it. * - A span whose tick is not among the candidates stays a top-level row, and a * tick is always top level, whatever caused it. * - Children are listed only while their tick's key is in `expanded`. * - A tick with shown children carries `tick`; one without is a plain row. */ export declare const buildListRows: (candidates: readonly TimelineSpan[], matched: readonly TimelineSpan[], expanded: ReadonlySet) => ListRow[]; //# sourceMappingURL=tick-rows.d.ts.map