@farmslot/recipe-runner 0.25.0 → 0.27.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -6,6 +6,16 @@ All notable changes to `@farmslot/recipe-runner` (published as `@farmslot/recipe
6
6
 
7
7
  - Active-development baseline; add user-facing changes here before release or package publication.
8
8
 
9
+ ## 0.27.0 - 2026-10-08
10
+
11
+ - Add a `lenient` option to `resolveRecipeValue(value, params, outputs, { lenient })`: only an exact reference to a parameter that exists resolves, anything else stays as written, and nothing throws. Static validation in `@farmslot/recipe-cli` resolves parameters this way.
12
+ - Publish with protocol 0.34.0.
13
+
14
+ ## 0.26.0 - 2026-10-06
15
+
16
+ - Add `@farmslot/recipe-runner/runtime/cdp-trace`, the CDP performance trace engine moved from mm-harness: `createCdpTraceCollector(client, { kind, platform, marker, markerPrefix })` runs one `Tracing` capture at a time and aligns it to the host clock through a marker the host writes into the trace; `parseTraceCapture(capture, kind)` turns a capture into JavaScript-task and native-frame samples with summaries. A `TraceKind` names what a trace captures (categories, renderer scoping, scope label, native source, JavaScript-task flag, `draw` or `cadence` frame timing), so the host keeps its own platform names. The marker prefix defaults to `farmslot-clock-`. `summarizeFrames` (from `@farmslot/adapter-rn`) and `summarizeJavaScriptTasks` move here too, unchanged.
17
+ - Publish with protocol 0.34.0.
18
+
9
19
  ## 0.25.0 - 2026-10-06
10
20
 
11
21
  - The library digest (`digestRecipeLibrary`) covers every file under each declared adapter module's directory, not only the module file, so a plugin's helper files move it. A module at the library root contributes itself and the library's `actions/`, not the whole root. Add `libraryAdapterFiles(root, declaration)` (the module's directory plus the library's `actions/`, the files a host lets the plugin import) and `digestLibraryAdapter(root, declaration)` for one plugin. The module's directory is listed strictly (`listLibraryFiles(root, directory, { strict: true })`): dot-files are digested, and a `node_modules`, a symlinked directory, or more than `MAX_LIBRARY_ADAPTER_FILES` (1,000) files fails with `RECIPE_SOURCE_INVALID`.
package/README.md CHANGED
@@ -229,6 +229,7 @@ surface and capture ids; `feedbackDraftFromDocument` is the same restore for cod
229
229
  - `/runtime/cdp`, `/runtime/react-native-bridge`, `/runtime/browser-extension`
230
230
  - `/runtime/deps-readiness`, `/runtime/log-analysis`, `/runtime/metro-probe`
231
231
  - `/runtime/decision-types`, `/runtime/orchestrate-up`
232
+ - `/runtime/cdp-trace` (CDP performance traces, frame and JavaScript-task summaries)
232
233
  - `/cli`, `/cli/support`
233
234
  - `/visual-review`
234
235
 
@@ -1,5 +1,13 @@
1
1
  export declare function resolveRecipeParams(ref: string, recipe: Record<string, unknown>, input: Record<string, unknown>, options?: {
2
2
  allowTemplates?: boolean;
3
3
  }): Record<string, unknown>;
4
- export declare function resolveRecipeValue(value: unknown, params: Record<string, unknown>, outputs?: ReadonlyMap<string, unknown>): unknown;
4
+ /**
5
+ * `value` with its `{{params.*}}`/`{{outputs.*}}` references resolved. Strict
6
+ * (the default) interpolates every reference and throws on a missing one.
7
+ * `lenient` is the static view before a run: only an exact reference to a
8
+ * parameter that exists resolves; anything else stays as written.
9
+ */
10
+ export declare function resolveRecipeValue(value: unknown, params: Record<string, unknown>, outputs?: ReadonlyMap<string, unknown>, options?: {
11
+ lenient?: boolean;
12
+ }): unknown;
5
13
  //# sourceMappingURL=parameters.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"parameters.d.ts","sourceRoot":"","sources":["../../src/core/parameters.ts"],"names":[],"mappings":"AAKA,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,OAAO,CAAC,EAAE;IAAE,cAAc,CAAC,EAAE,OAAO,CAAA;CAAE,GACrC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAazB;AAED,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,OAAO,EACd,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,OAAO,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,GACrC,OAAO,CAoBT"}
1
+ {"version":3,"file":"parameters.d.ts","sourceRoot":"","sources":["../../src/core/parameters.ts"],"names":[],"mappings":"AAKA,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,OAAO,CAAC,EAAE;IAAE,cAAc,CAAC,EAAE,OAAO,CAAA;CAAE,GACrC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAazB;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,OAAO,EACd,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,OAAO,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,EACtC,OAAO,GAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAA;CAAO,GAClC,OAAO,CA6BT"}
@@ -11,9 +11,19 @@ export function resolveRecipeParams(ref, recipe, input, options) {
11
11
  }
12
12
  return params;
13
13
  }
14
- export function resolveRecipeValue(value, params, outputs) {
14
+ /**
15
+ * `value` with its `{{params.*}}`/`{{outputs.*}}` references resolved. Strict
16
+ * (the default) interpolates every reference and throws on a missing one.
17
+ * `lenient` is the static view before a run: only an exact reference to a
18
+ * parameter that exists resolves; anything else stays as written.
19
+ */
20
+ export function resolveRecipeValue(value, params, outputs, options = {}) {
15
21
  if (typeof value === 'string') {
16
22
  const exact = /^\{\{(params|outputs)\.([A-Za-z0-9_.-]+)\}\}$/u.exec(value);
23
+ if (options.lenient) {
24
+ const found = exact?.[1] === 'params' ? nestedValue(params, exact[2]) : undefined;
25
+ return found ? found.value : value;
26
+ }
17
27
  if (exact) {
18
28
  if (exact[1] === 'outputs' && !outputs)
19
29
  return value;
@@ -23,11 +33,15 @@ export function resolveRecipeValue(value, params, outputs) {
23
33
  ? _match
24
34
  : String(getRecipeReference(source, key, params, outputs)));
25
35
  }
26
- if (Array.isArray(value))
27
- return value.map((entry) => resolveRecipeValue(entry, params, outputs));
36
+ if (Array.isArray(value)) {
37
+ return value.map((entry) => resolveRecipeValue(entry, params, outputs, options));
38
+ }
28
39
  if (!isRecord(value))
29
40
  return value;
30
- return Object.fromEntries(Object.entries(value).map(([key, entry]) => [key, resolveRecipeValue(entry, params, outputs)]));
41
+ return Object.fromEntries(Object.entries(value).map(([key, entry]) => [
42
+ key,
43
+ resolveRecipeValue(entry, params, outputs, options),
44
+ ]));
31
45
  }
32
46
  function getRecipeReference(source, path, params, outputs) {
33
47
  if (source === 'params')
@@ -41,17 +55,24 @@ function getRecipeReference(source, path, params, outputs) {
41
55
  return getNestedValue(outputs.get(nodeId), segments.join('.'), 'output');
42
56
  }
43
57
  function getNestedValue(value, path, kind) {
44
- if (!path)
45
- return value;
58
+ const found = nestedValue(value, path);
59
+ if (!found) {
60
+ throw new RecipeResolutionError('RECIPE_PARAMS_INVALID', `Recipe ${kind} ${path} is not defined.`, kind === 'parameter'
61
+ ? `declare ${path} in paramsSchema or provide it before running the recipe`
62
+ : `inspect the producing node output before referencing ${path}`);
63
+ }
64
+ return found.value;
65
+ }
66
+ // The value at a dotted path, or undefined when a segment is missing.
67
+ function nestedValue(value, path) {
46
68
  let current = value;
69
+ if (!path)
70
+ return { value: current };
47
71
  for (const segment of path.split('.')) {
48
- if (!isRecord(current) || !Object.hasOwn(current, segment)) {
49
- throw new RecipeResolutionError('RECIPE_PARAMS_INVALID', `Recipe ${kind} ${path} is not defined.`, kind === 'parameter'
50
- ? `declare ${path} in paramsSchema or provide it before running the recipe`
51
- : `inspect the producing node output before referencing ${path}`);
52
- }
72
+ if (!isRecord(current) || !Object.hasOwn(current, segment))
73
+ return undefined;
53
74
  current = current[segment];
54
75
  }
55
- return current;
76
+ return { value: current };
56
77
  }
57
78
  //# sourceMappingURL=parameters.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"parameters.js","sourceRoot":"","sources":["../../src/core/parameters.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"parameters.js","sourceRoot":"","sources":["../../src/core/parameters.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  export declare function isPathWithin(root: string, candidate: string): boolean;
2
2
  export declare function readFileWithinRoot(root: string, relativePath: string): Promise<Buffer>;
3
3
  export declare function digestFileWithinRoot(root: string, relativePath: string): Promise<string>;
4
- export declare function statFileWithinRoot(root: string, relativePath: string): Promise<import("fs").Stats>;
4
+ export declare function statFileWithinRoot(root: string, relativePath: string): Promise<import("node:fs").Stats>;
5
5
  export declare function writeFileWithinRoot(root: string, relativePath: string, data: string | Uint8Array): Promise<string>;
6
6
  export declare function copyFileWithinRoots(sourceRoot: string, sourceRelativePath: string, destinationRoot: string, destinationRelativePath: string): Promise<string>;
7
7
  //# sourceMappingURL=path.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"path.d.ts","sourceRoot":"","sources":["../../src/core/path.ts"],"names":[],"mappings":"AAQA,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAMrE;AAED,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAO5F;AAED,wBAAsB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAS9F;AAED,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,+BAO1E;AAED,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,MAAM,EACZ,YAAY,EAAE,MAAM,EACpB,IAAI,EAAE,MAAM,GAAG,UAAU,GACxB,OAAO,CAAC,MAAM,CAAC,CAQjB;AAED,wBAAsB,mBAAmB,CACvC,UAAU,EAAE,MAAM,EAClB,kBAAkB,EAAE,MAAM,EAC1B,eAAe,EAAE,MAAM,EACvB,uBAAuB,EAAE,MAAM,GAC9B,OAAO,CAAC,MAAM,CAAC,CAwBjB"}
1
+ {"version":3,"file":"path.d.ts","sourceRoot":"","sources":["../../src/core/path.ts"],"names":[],"mappings":"AAQA,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAMrE;AAED,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAO5F;AAED,wBAAsB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAS9F;AAED,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,oCAO1E;AAED,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,MAAM,EACZ,YAAY,EAAE,MAAM,EACpB,IAAI,EAAE,MAAM,GAAG,UAAU,GACxB,OAAO,CAAC,MAAM,CAAC,CAQjB;AAED,wBAAsB,mBAAmB,CACvC,UAAU,EAAE,MAAM,EAClB,kBAAkB,EAAE,MAAM,EAC1B,eAAe,EAAE,MAAM,EACvB,uBAAuB,EAAE,MAAM,GAC9B,OAAO,CAAC,MAAM,CAAC,CAwBjB"}
@@ -0,0 +1,92 @@
1
+ import { type FrameMetricSummary, type FrameSample, summarizeFrames } from './frame-metrics.js';
2
+ import { type JavaScriptTaskMetricSummary, type JavaScriptTaskSample, summarizeJavaScriptTasks } from './js-task-metrics.js';
3
+ export { type FrameMetricSummary, type FrameSample, type JavaScriptTaskMetricSummary, type JavaScriptTaskSample, summarizeFrames, summarizeJavaScriptTasks, };
4
+ export interface TraceKind {
5
+ categories: readonly string[];
6
+ rendererScoped: boolean;
7
+ scope: string;
8
+ nativeSource: string;
9
+ javascriptTasks: boolean;
10
+ frameTiming: 'draw' | 'cadence';
11
+ }
12
+ export type PerformanceSourceStatus = 'complete' | 'partial' | 'unavailable';
13
+ interface PerformanceSourceResult<TSample, TSummary> {
14
+ status: PerformanceSourceStatus;
15
+ kind: string;
16
+ unavailableReasons: string[];
17
+ coverageGapReasons: string[];
18
+ samples: TSample[];
19
+ summary: TSummary;
20
+ clockSyncUncertaintyMs?: number;
21
+ }
22
+ type JavaScriptPerformanceSourceBase = Omit<PerformanceSourceResult<JavaScriptTaskSample, JavaScriptTaskMetricSummary>, 'summary'>;
23
+ export type JavaScriptPerformanceSourceResult = (JavaScriptPerformanceSourceBase & {
24
+ applicability: 'applicable';
25
+ summary: JavaScriptTaskMetricSummary;
26
+ }) | (JavaScriptPerformanceSourceBase & {
27
+ applicability: 'not_applicable';
28
+ summary: Record<string, never>;
29
+ });
30
+ export type NativeUiPerformanceSourceResult = PerformanceSourceResult<FrameSample, FrameMetricSummary>;
31
+ export interface PerformanceCaptureResult<P extends string = string> {
32
+ platform: P;
33
+ javascript: JavaScriptPerformanceSourceResult;
34
+ nativeUi: NativeUiPerformanceSourceResult;
35
+ trace: TraceEvidence;
36
+ rawTraceEvents?: TraceEvent[];
37
+ }
38
+ export interface TraceEvidence {
39
+ beginFrameCount: number;
40
+ dataLossOccurred: boolean;
41
+ drawFrameCount: number;
42
+ overflow: boolean;
43
+ profileChunkCount: number;
44
+ rendererProcessId?: number;
45
+ runTaskCount: number;
46
+ scope: string;
47
+ totalEventCount: number;
48
+ }
49
+ export interface PerformanceBackend<P extends string = string> {
50
+ start(id: string): Promise<void>;
51
+ end(id: string): Promise<PerformanceCaptureResult<P>>;
52
+ close(): Promise<void>;
53
+ }
54
+ export interface CdpClient {
55
+ send(method: string, params?: Record<string, unknown>, timeoutMs?: number): Promise<unknown>;
56
+ on(method: string, handler: (params: Record<string, unknown>) => void): () => void;
57
+ close(): void;
58
+ }
59
+ export interface TraceEvent {
60
+ name?: string;
61
+ cat?: string;
62
+ ph?: string;
63
+ ts?: number;
64
+ dur?: number;
65
+ pid?: number;
66
+ tid?: number;
67
+ args?: Record<string, unknown>;
68
+ }
69
+ export interface TraceCapture<P extends string = string> {
70
+ platform: P;
71
+ events: TraceEvent[];
72
+ markerName?: string;
73
+ markerHostEpochMs?: number;
74
+ markerUncertaintyMs?: number;
75
+ dataLossOccurred: boolean;
76
+ overflow: boolean;
77
+ unavailableReasons: string[];
78
+ coverageGapReasons: string[];
79
+ }
80
+ export interface TraceClockSync {
81
+ hostEpochMs: number;
82
+ uncertaintyMs: number;
83
+ }
84
+ export interface CdpTraceCollectorOptions<P extends string = string> {
85
+ kind: TraceKind;
86
+ platform: P;
87
+ marker(name: string): Promise<TraceClockSync>;
88
+ markerPrefix?: string;
89
+ }
90
+ export declare function createCdpTraceCollector<P extends string = string>(client: CdpClient, { kind, platform, marker, markerPrefix }: CdpTraceCollectorOptions<P>): PerformanceBackend<P>;
91
+ export declare function parseTraceCapture<P extends string = string>(capture: TraceCapture<P>, kind: TraceKind): PerformanceCaptureResult<P>;
92
+ //# sourceMappingURL=cdp-trace.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cdp-trace.d.ts","sourceRoot":"","sources":["../../src/runtime/cdp-trace.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,385 @@
1
+ // CDP performance traces: start and end a `Tracing` capture over a CDP
2
+ // client, align it to the host clock through a marker written into the trace,
3
+ // and turn it into JavaScript-task and native-frame samples with summaries.
4
+ // The host names what a trace captures with a `TraceKind`.
5
+ import { summarizeFrames } from './frame-metrics.js';
6
+ import { summarizeJavaScriptTasks, } from './js-task-metrics.js';
7
+ export { summarizeFrames, summarizeJavaScriptTasks, };
8
+ const MAX_TRACE_BYTES = 16 * 1024 * 1024;
9
+ const MAX_TRACE_EVENTS = 250_000;
10
+ const DEFAULT_MARKER_PREFIX = 'farmslot-clock-';
11
+ export function createCdpTraceCollector(client, { kind, platform, marker, markerPrefix = DEFAULT_MARKER_PREFIX }) {
12
+ let active;
13
+ const offData = client.on('Tracing.dataCollected', (params) => {
14
+ if (!active || !Array.isArray(params.value))
15
+ return;
16
+ for (const value of params.value) {
17
+ if (!value || typeof value !== 'object' || Array.isArray(value))
18
+ continue;
19
+ const event = value;
20
+ const bytes = Buffer.byteLength(JSON.stringify(event));
21
+ if (active.events.length >= MAX_TRACE_EVENTS || active.bytes + bytes > MAX_TRACE_BYTES) {
22
+ active.overflow = true;
23
+ continue;
24
+ }
25
+ active.events.push(event);
26
+ active.bytes += bytes;
27
+ }
28
+ });
29
+ const offComplete = client.on('Tracing.tracingComplete', (params) => {
30
+ if (!active)
31
+ return;
32
+ active.dataLossOccurred = params.dataLossOccurred === true;
33
+ active.complete?.();
34
+ });
35
+ return {
36
+ async start(id) {
37
+ if (active)
38
+ throw new Error('Only one CDP performance trace may be active.');
39
+ let complete;
40
+ const completePromise = new Promise((resolve) => {
41
+ complete = resolve;
42
+ });
43
+ active = {
44
+ id,
45
+ events: [],
46
+ bytes: 0,
47
+ overflow: false,
48
+ dataLossOccurred: false,
49
+ complete,
50
+ completePromise,
51
+ };
52
+ let tracingStarted = false;
53
+ try {
54
+ await client.send('Tracing.start', {
55
+ categories: kind.categories.join(','),
56
+ transferMode: 'ReportEvents',
57
+ }, 15_000);
58
+ tracingStarted = true;
59
+ const markerName = `${markerPrefix}${id}-${Date.now()}`;
60
+ const sync = await marker(markerName);
61
+ active.markerName = markerName;
62
+ active.markerHostEpochMs = sync.hostEpochMs;
63
+ active.markerUncertaintyMs = sync.uncertaintyMs;
64
+ }
65
+ catch (error) {
66
+ if (tracingStarted) {
67
+ await client.send('Tracing.end', {}, 5_000).catch(() => undefined);
68
+ await withTimeout(active.completePromise, 1_000, 'CDP tracing cleanup did not report tracingComplete.').catch(() => undefined);
69
+ }
70
+ active = undefined;
71
+ throw error;
72
+ }
73
+ },
74
+ async end(id) {
75
+ const capture = active;
76
+ if (!capture || capture.id !== id) {
77
+ throw new Error(`Performance capture is not active: ${id}`);
78
+ }
79
+ try {
80
+ await client.send('Tracing.end', {}, 15_000);
81
+ await withTimeout(capture.completePromise, 30_000, 'CDP tracing did not report tracingComplete.');
82
+ }
83
+ finally {
84
+ active = undefined;
85
+ }
86
+ return parseTraceCapture({
87
+ platform,
88
+ events: capture.events,
89
+ markerName: capture.markerName,
90
+ markerHostEpochMs: capture.markerHostEpochMs,
91
+ markerUncertaintyMs: capture.markerUncertaintyMs,
92
+ dataLossOccurred: capture.dataLossOccurred,
93
+ overflow: capture.overflow,
94
+ unavailableReasons: [],
95
+ coverageGapReasons: [],
96
+ }, kind);
97
+ },
98
+ async close() {
99
+ if (active) {
100
+ await client.send('Tracing.end', {}, 5_000).catch(() => undefined);
101
+ await withTimeout(active.completePromise, 1_000, 'CDP tracing cleanup did not report tracingComplete.').catch(() => undefined);
102
+ active = undefined;
103
+ }
104
+ offData();
105
+ offComplete();
106
+ client.close();
107
+ },
108
+ };
109
+ }
110
+ export function parseTraceCapture(capture, kind) {
111
+ const marker = findClockMarker(capture.events, capture.markerName);
112
+ if (kind.rendererScoped && !finite(marker?.pid)) {
113
+ const reason = 'Extension trace marker did not identify a renderer process.';
114
+ return {
115
+ platform: capture.platform,
116
+ javascript: unavailableJavaScriptSource('cdp-js-runtime-tasks', reason),
117
+ nativeUi: unavailableNativeUiSource('cdp-native-frame-timings', reason),
118
+ trace: traceEvidence(capture, 'unresolved'),
119
+ };
120
+ }
121
+ const rendererProcessId = kind.rendererScoped ? marker?.pid : undefined;
122
+ const scopedEvents = rendererProcessId === undefined
123
+ ? capture.events
124
+ : capture.events.filter((event) => event.pid === rendererProcessId);
125
+ const trace = traceEvidence({ ...capture, events: scopedEvents }, kind.scope, rendererProcessId);
126
+ if (!marker ||
127
+ !finite(marker.ts) ||
128
+ capture.markerHostEpochMs === undefined ||
129
+ capture.markerUncertaintyMs === undefined) {
130
+ const reason = 'CDP trace clock marker was unavailable.';
131
+ return {
132
+ platform: capture.platform,
133
+ javascript: unavailableJavaScriptSource('cdp-js-runtime-tasks', reason),
134
+ nativeUi: unavailableNativeUiSource('cdp-native-frame-timings', reason),
135
+ trace,
136
+ };
137
+ }
138
+ const markerTs = marker.ts;
139
+ const markerHostEpochMs = capture.markerHostEpochMs;
140
+ const traceToEpochMs = (timestampUs) => markerHostEpochMs + (timestampUs - markerTs) / 1000;
141
+ const gapReasons = [
142
+ ...capture.coverageGapReasons,
143
+ ...(capture.overflow ? ['CDP trace retention limit was reached.'] : []),
144
+ ...(capture.dataLossOccurred ? ['CDP reported trace data loss.'] : []),
145
+ ];
146
+ const nativeSamples = nativeFrameSamples(scopedEvents, kind.frameTiming, traceToEpochMs);
147
+ const javascriptSamples = javascriptTaskSamples(scopedEvents, traceToEpochMs);
148
+ const status = capture.overflow || capture.dataLossOccurred ? 'partial' : 'complete';
149
+ return {
150
+ platform: capture.platform,
151
+ javascript: javascriptSourceResult('cdp-js-runtime-tasks', javascriptSamples, status, gapReasons, traceEventNames(scopedEvents), capture.markerUncertaintyMs),
152
+ nativeUi: nativeUiSourceResult(kind.nativeSource, nativeSamples, status, gapReasons, traceEventNames(scopedEvents), capture.markerUncertaintyMs),
153
+ trace,
154
+ rawTraceEvents: normalizeTraceTimestamps(scopedEvents, traceToEpochMs),
155
+ };
156
+ }
157
+ function normalizeTraceTimestamps(events, traceToEpochMs) {
158
+ return events.map((event) => finite(event.ts) ? { ...event, ts: traceToEpochMs(event.ts) * 1000 } : { ...event });
159
+ }
160
+ function traceEvidence(capture, scope, rendererProcessId) {
161
+ const counts = new Map();
162
+ for (const event of capture.events) {
163
+ const name = String(event.name ?? '');
164
+ counts.set(name, (counts.get(name) ?? 0) + 1);
165
+ }
166
+ return {
167
+ beginFrameCount: counts.get('BeginFrame') ?? 0,
168
+ dataLossOccurred: capture.dataLossOccurred,
169
+ drawFrameCount: counts.get('DrawFrame') ?? 0,
170
+ overflow: capture.overflow,
171
+ profileChunkCount: counts.get('ProfileChunk') ?? 0,
172
+ ...(rendererProcessId === undefined ? {} : { rendererProcessId }),
173
+ runTaskCount: counts.get('RunTask') ?? 0,
174
+ scope,
175
+ totalEventCount: capture.events.length,
176
+ };
177
+ }
178
+ function nativeFrameSamples(events, frameTiming, traceToEpochMs) {
179
+ const begins = new Map();
180
+ const frames = [];
181
+ for (const event of events) {
182
+ if (event.name !== 'BeginFrame' && event.name !== 'DrawFrame')
183
+ continue;
184
+ const sequence = frameSequence(event);
185
+ if (!sequence || !finite(event.ts))
186
+ continue;
187
+ if (event.name === 'BeginFrame') {
188
+ begins.set(sequence, event);
189
+ continue;
190
+ }
191
+ const begin = begins.get(sequence);
192
+ if (!begin || !finite(begin.ts))
193
+ continue;
194
+ frames.push({ beginUs: begin.ts, endUs: event.ts });
195
+ }
196
+ frames.sort((first, second) => first.beginUs - second.beginUs);
197
+ const frameBudgetMs = estimateFrameBudgetMs(frames);
198
+ if (frameTiming === 'cadence') {
199
+ const samples = [];
200
+ for (let index = 1; index < frames.length; index += 1) {
201
+ const previous = frames[index - 1];
202
+ const current = frames[index];
203
+ if (!previous || !current)
204
+ continue;
205
+ const durationMs = (current.beginUs - previous.beginUs) / 1000;
206
+ if (durationMs <= 0)
207
+ continue;
208
+ samples.push({
209
+ cadenceInterval: true,
210
+ completedAtEpochMs: traceToEpochMs(current.beginUs),
211
+ durationMs,
212
+ ...(frameBudgetMs
213
+ ? {
214
+ frameBudgetMs,
215
+ overBudget: durationMs > frameBudgetMs * 1.01,
216
+ }
217
+ : {}),
218
+ startedAtEpochMs: traceToEpochMs(previous.beginUs),
219
+ });
220
+ }
221
+ return samples;
222
+ }
223
+ return frames
224
+ .map((frame) => {
225
+ const durationMs = (frame.endUs - frame.beginUs) / 1000;
226
+ return {
227
+ completedAtEpochMs: traceToEpochMs(frame.endUs),
228
+ durationMs,
229
+ ...(frameBudgetMs
230
+ ? {
231
+ frameBudgetMs,
232
+ overBudget: durationMs > frameBudgetMs * 1.01,
233
+ }
234
+ : {}),
235
+ startedAtEpochMs: traceToEpochMs(frame.beginUs),
236
+ };
237
+ })
238
+ .filter((sample) => sample.durationMs > 0);
239
+ }
240
+ function estimateFrameBudgetMs(frames) {
241
+ const cadenceMs = [];
242
+ for (let index = 1; index < frames.length; index += 1) {
243
+ const previous = frames[index - 1];
244
+ const current = frames[index];
245
+ if (!previous || !current)
246
+ continue;
247
+ const intervalMs = (current.beginUs - previous.beginUs) / 1000;
248
+ if (intervalMs >= 3.5 && intervalMs <= 40)
249
+ cadenceMs.push(intervalMs);
250
+ }
251
+ if (cadenceMs.length < 5)
252
+ return undefined;
253
+ cadenceMs.sort((first, second) => first - second);
254
+ const observedBudgetMs = percentile(cadenceMs, 0.1);
255
+ const refreshRateHz = Math.round(1000 / observedBudgetMs);
256
+ return refreshRateHz >= 24 && refreshRateHz <= 240 ? 1000 / refreshRateHz : undefined;
257
+ }
258
+ function percentile(sorted, quantile) {
259
+ if (sorted.length === 1)
260
+ return sorted[0] ?? 0;
261
+ const position = (sorted.length - 1) * quantile;
262
+ const lower = Math.floor(position);
263
+ const upper = Math.ceil(position);
264
+ const lowerValue = sorted[lower] ?? 0;
265
+ const upperValue = sorted[upper] ?? lowerValue;
266
+ return lowerValue + (upperValue - lowerValue) * (position - lower);
267
+ }
268
+ function javascriptTaskSamples(events, traceToEpochMs) {
269
+ const samples = [];
270
+ for (const event of events) {
271
+ if (event.name !== 'RunTask' || event.ph !== 'X')
272
+ continue;
273
+ if (!finite(event.ts) || !finite(event.dur) || event.dur <= 0)
274
+ continue;
275
+ samples.push({
276
+ completedAtEpochMs: traceToEpochMs(event.ts + event.dur),
277
+ durationMs: event.dur / 1000,
278
+ });
279
+ }
280
+ return samples;
281
+ }
282
+ function findClockMarker(events, markerName) {
283
+ if (!markerName)
284
+ return undefined;
285
+ return events.find((candidate) => candidate.name === markerName ||
286
+ asRecord(candidate.args).sync_id === markerName ||
287
+ asRecord(asRecord(candidate.args).data).sync_id === markerName);
288
+ }
289
+ function frameSequence(event) {
290
+ const args = asRecord(event.args);
291
+ const value = args.frameSeqId ?? asRecord(args.data).frameSeqId;
292
+ return value === undefined ? undefined : String(value);
293
+ }
294
+ function javascriptSourceResult(kind, samples, status, coverageGapReasons, observedEventNames, clockSyncUncertaintyMs) {
295
+ return {
296
+ applicability: 'applicable',
297
+ status: samples.length > 0 ? status : 'partial',
298
+ kind,
299
+ unavailableReasons: [],
300
+ coverageGapReasons: [
301
+ ...coverageGapReasons,
302
+ ...(samples.length > 0
303
+ ? []
304
+ : [
305
+ `No ${kind} samples were recorded. Observed trace events: ${observedEventNames.join(', ') || 'none'}.`,
306
+ ]),
307
+ ],
308
+ samples,
309
+ summary: summarizeJavaScriptTasks(samples),
310
+ clockSyncUncertaintyMs,
311
+ };
312
+ }
313
+ function nativeUiSourceResult(kind, samples, status, coverageGapReasons, observedEventNames, clockSyncUncertaintyMs) {
314
+ const summary = summarizeFrames(samples);
315
+ const hasUnclassifiedCadenceGap = (summary.cadenceGapCount ?? 0) > 0;
316
+ return {
317
+ status: samples.length === 0 ? 'partial' : hasUnclassifiedCadenceGap ? 'partial' : status,
318
+ kind,
319
+ unavailableReasons: [],
320
+ coverageGapReasons: [
321
+ ...coverageGapReasons,
322
+ ...(samples.length > 0
323
+ ? []
324
+ : [
325
+ `No ${kind} samples were recorded. Observed trace events: ${observedEventNames.join(', ') || 'none'}.`,
326
+ ]),
327
+ ...(hasUnclassifiedCadenceGap
328
+ ? ['Unclassified native cadence gap prevents a complete FPS result.']
329
+ : []),
330
+ ],
331
+ samples,
332
+ summary,
333
+ clockSyncUncertaintyMs,
334
+ };
335
+ }
336
+ function traceEventNames(events) {
337
+ const counts = new Map();
338
+ for (const event of events) {
339
+ const name = String(event.name ?? 'unknown');
340
+ counts.set(name, (counts.get(name) ?? 0) + 1);
341
+ }
342
+ return [...counts.entries()]
343
+ .sort((first, second) => second[1] - first[1])
344
+ .slice(0, 20)
345
+ .map(([name, count]) => `${name}(${count})`);
346
+ }
347
+ function unavailableJavaScriptSource(kind, reason) {
348
+ return {
349
+ applicability: 'applicable',
350
+ status: 'unavailable',
351
+ kind,
352
+ unavailableReasons: [reason],
353
+ coverageGapReasons: [],
354
+ samples: [],
355
+ summary: { taskCount: 0 },
356
+ };
357
+ }
358
+ function unavailableNativeUiSource(kind, reason) {
359
+ return {
360
+ status: 'unavailable',
361
+ kind,
362
+ unavailableReasons: [reason],
363
+ coverageGapReasons: [],
364
+ samples: [],
365
+ summary: { frameCount: 0 },
366
+ };
367
+ }
368
+ function withTimeout(promise, timeoutMs, message) {
369
+ let timer;
370
+ return Promise.race([
371
+ promise,
372
+ new Promise((_resolve, reject) => {
373
+ timer = setTimeout(() => reject(new Error(message)), timeoutMs);
374
+ }),
375
+ ]).finally(() => clearTimeout(timer));
376
+ }
377
+ function finite(value) {
378
+ return typeof value === 'number' && Number.isFinite(value);
379
+ }
380
+ function asRecord(value) {
381
+ return value && typeof value === 'object' && !Array.isArray(value)
382
+ ? value
383
+ : {};
384
+ }
385
+ //# sourceMappingURL=cdp-trace.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cdp-trace.js","sourceRoot":"","sources":["../../src/runtime/cdp-trace.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,8EAA8E;AAC9E,4EAA4E;AAC5E,2DAA2D;AAC3D,OAAO,EAA6C,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAChG,OAAO,EAGL,wBAAwB,GACzB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAKL,eAAe,EACf,wBAAwB,GACzB,CAAC;AAEF,MAAM,eAAe,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC;AACzC,MAAM,gBAAgB,GAAG,OAAO,CAAC;AACjC,MAAM,qBAAqB,GAAG,iBAAiB,CAAC;AA2HhD,MAAM,UAAU,uBAAuB,CACrC,MAAiB,EACjB,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,YAAY,GAAG,qBAAqB,EAA+B;IAE7F,IAAI,MAaS,CAAC;IAEd,MAAM,OAAO,GAAG,MAAM,CAAC,EAAE,CAAC,uBAAuB,EAAE,CAAC,MAAM,EAAE,EAAE;QAC5D,IAAI,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC;YAAE,OAAO;QACpD,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;YACjC,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;gBAAE,SAAS;YAC1E,MAAM,KAAK,GAAG,KAAmB,CAAC;YAClC,MAAM,KAAK,GAAG,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;YACvD,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,IAAI,gBAAgB,IAAI,MAAM,CAAC,KAAK,GAAG,KAAK,GAAG,eAAe,EAAE,CAAC;gBACvF,MAAM,CAAC,QAAQ,GAAG,IAAI,CAAC;gBACvB,SAAS;YACX,CAAC;YACD,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC1B,MAAM,CAAC,KAAK,IAAI,KAAK,CAAC;QACxB,CAAC;IACH,CAAC,CAAC,CAAC;IACH,MAAM,WAAW,GAAG,MAAM,CAAC,EAAE,CAAC,yBAAyB,EAAE,CAAC,MAAM,EAAE,EAAE;QAClE,IAAI,CAAC,MAAM;YAAE,OAAO;QACpB,MAAM,CAAC,gBAAgB,GAAG,MAAM,CAAC,gBAAgB,KAAK,IAAI,CAAC;QAC3D,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAC;IACtB,CAAC,CAAC,CAAC;IAEH,OAAO;QACL,KAAK,CAAC,KAAK,CAAC,EAAE;YACZ,IAAI,MAAM;gBAAE,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;YAC7E,IAAI,QAAkC,CAAC;YACvC,MAAM,eAAe,GAAG,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;gBACpD,QAAQ,GAAG,OAAO,CAAC;YACrB,CAAC,CAAC,CAAC;YACH,MAAM,GAAG;gBACP,EAAE;gBACF,MAAM,EAAE,EAAE;gBACV,KAAK,EAAE,CAAC;gBACR,QAAQ,EAAE,KAAK;gBACf,gBAAgB,EAAE,KAAK;gBACvB,QAAQ;gBACR,eAAe;aAChB,CAAC;YACF,IAAI,cAAc,GAAG,KAAK,CAAC;YAC3B,IAAI,CAAC;gBACH,MAAM,MAAM,CAAC,IAAI,CACf,eAAe,EACf;oBACE,UAAU,EAAE,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC;oBACrC,YAAY,EAAE,cAAc;iBAC7B,EACD,MAAM,CACP,CAAC;gBACF,cAAc,GAAG,IAAI,CAAC;gBACtB,MAAM,UAAU,GAAG,GAAG,YAAY,GAAG,EAAE,IAAI,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;gBACxD,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC,CAAC;gBACtC,MAAM,CAAC,UAAU,GAAG,UAAU,CAAC;gBAC/B,MAAM,CAAC,iBAAiB,GAAG,IAAI,CAAC,WAAW,CAAC;gBAC5C,MAAM,CAAC,mBAAmB,GAAG,IAAI,CAAC,aAAa,CAAC;YAClD,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,IAAI,cAAc,EAAE,CAAC;oBACnB,MAAM,MAAM,CAAC,IAAI,CAAC,aAAa,EAAE,EAAE,EAAE,KAAK,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;oBACnE,MAAM,WAAW,CACf,MAAM,CAAC,eAAe,EACtB,KAAK,EACL,qDAAqD,CACtD,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;gBAC3B,CAAC;gBACD,MAAM,GAAG,SAAS,CAAC;gBACnB,MAAM,KAAK,CAAC;YACd,CAAC;QACH,CAAC;QACD,KAAK,CAAC,GAAG,CAAC,EAAE;YACV,MAAM,OAAO,GAAG,MAAM,CAAC;YACvB,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC;gBAClC,MAAM,IAAI,KAAK,CAAC,sCAAsC,EAAE,EAAE,CAAC,CAAC;YAC9D,CAAC;YACD,IAAI,CAAC;gBACH,MAAM,MAAM,CAAC,IAAI,CAAC,aAAa,EAAE,EAAE,EAAE,MAAM,CAAC,CAAC;gBAC7C,MAAM,WAAW,CACf,OAAO,CAAC,eAAe,EACvB,MAAM,EACN,6CAA6C,CAC9C,CAAC;YACJ,CAAC;oBAAS,CAAC;gBACT,MAAM,GAAG,SAAS,CAAC;YACrB,CAAC;YACD,OAAO,iBAAiB,CACtB;gBACE,QAAQ;gBACR,MAAM,EAAE,OAAO,CAAC,MAAM;gBACtB,UAAU,EAAE,OAAO,CAAC,UAAU;gBAC9B,iBAAiB,EAAE,OAAO,CAAC,iBAAiB;gBAC5C,mBAAmB,EAAE,OAAO,CAAC,mBAAmB;gBAChD,gBAAgB,EAAE,OAAO,CAAC,gBAAgB;gBAC1C,QAAQ,EAAE,OAAO,CAAC,QAAQ;gBAC1B,kBAAkB,EAAE,EAAE;gBACtB,kBAAkB,EAAE,EAAE;aACvB,EACD,IAAI,CACL,CAAC;QACJ,CAAC;QACD,KAAK,CAAC,KAAK;YACT,IAAI,MAAM,EAAE,CAAC;gBACX,MAAM,MAAM,CAAC,IAAI,CAAC,aAAa,EAAE,EAAE,EAAE,KAAK,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;gBACnE,MAAM,WAAW,CACf,MAAM,CAAC,eAAe,EACtB,KAAK,EACL,qDAAqD,CACtD,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;gBACzB,MAAM,GAAG,SAAS,CAAC;YACrB,CAAC;YACD,OAAO,EAAE,CAAC;YACV,WAAW,EAAE,CAAC;YACd,MAAM,CAAC,KAAK,EAAE,CAAC;QACjB,CAAC;KACF,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,iBAAiB,CAC/B,OAAwB,EACxB,IAAe;IAEf,MAAM,MAAM,GAAG,eAAe,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC;IACnE,IAAI,IAAI,CAAC,cAAc,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,CAAC;QAChD,MAAM,MAAM,GAAG,6DAA6D,CAAC;QAC7E,OAAO;YACL,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,UAAU,EAAE,2BAA2B,CAAC,sBAAsB,EAAE,MAAM,CAAC;YACvE,QAAQ,EAAE,yBAAyB,CAAC,0BAA0B,EAAE,MAAM,CAAC;YACvE,KAAK,EAAE,aAAa,CAAC,OAAO,EAAE,YAAY,CAAC;SAC5C,CAAC;IACJ,CAAC;IACD,MAAM,iBAAiB,GAAG,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC;IACxE,MAAM,YAAY,GAChB,iBAAiB,KAAK,SAAS;QAC7B,CAAC,CAAC,OAAO,CAAC,MAAM;QAChB,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,KAAK,iBAAiB,CAAC,CAAC;IACxE,MAAM,KAAK,GAAG,aAAa,CAAC,EAAE,GAAG,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,EAAE,IAAI,CAAC,KAAK,EAAE,iBAAiB,CAAC,CAAC;IACjG,IACE,CAAC,MAAM;QACP,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;QAClB,OAAO,CAAC,iBAAiB,KAAK,SAAS;QACvC,OAAO,CAAC,mBAAmB,KAAK,SAAS,EACzC,CAAC;QACD,MAAM,MAAM,GAAG,yCAAyC,CAAC;QACzD,OAAO;YACL,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,UAAU,EAAE,2BAA2B,CAAC,sBAAsB,EAAE,MAAM,CAAC;YACvE,QAAQ,EAAE,yBAAyB,CAAC,0BAA0B,EAAE,MAAM,CAAC;YACvE,KAAK;SACN,CAAC;IACJ,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,CAAC,EAAE,CAAC;IAC3B,MAAM,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAC;IACpD,MAAM,cAAc,GAAG,CAAC,WAAmB,EAAE,EAAE,CAC7C,iBAAiB,GAAG,CAAC,WAAW,GAAG,QAAQ,CAAC,GAAG,IAAI,CAAC;IACtD,MAAM,UAAU,GAAG;QACjB,GAAG,OAAO,CAAC,kBAAkB;QAC7B,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,wCAAwC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACvE,GAAG,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,+BAA+B,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;KACvE,CAAC;IACF,MAAM,aAAa,GAAG,kBAAkB,CAAC,YAAY,EAAE,IAAI,CAAC,WAAW,EAAE,cAAc,CAAC,CAAC;IACzF,MAAM,iBAAiB,GAAG,qBAAqB,CAAC,YAAY,EAAE,cAAc,CAAC,CAAC;IAC9E,MAAM,MAAM,GACV,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,gBAAgB,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC;IAExE,OAAO;QACL,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,UAAU,EAAE,sBAAsB,CAChC,sBAAsB,EACtB,iBAAiB,EACjB,MAAM,EACN,UAAU,EACV,eAAe,CAAC,YAAY,CAAC,EAC7B,OAAO,CAAC,mBAAmB,CAC5B;QACD,QAAQ,EAAE,oBAAoB,CAC5B,IAAI,CAAC,YAAY,EACjB,aAAa,EACb,MAAM,EACN,UAAU,EACV,eAAe,CAAC,YAAY,CAAC,EAC7B,OAAO,CAAC,mBAAmB,CAC5B;QACD,KAAK;QACL,cAAc,EAAE,wBAAwB,CAAC,YAAY,EAAE,cAAc,CAAC;KACvE,CAAC;AACJ,CAAC;AAED,SAAS,wBAAwB,CAC/B,MAA6B,EAC7B,cAA+C;IAE/C,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAC1B,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,KAAK,EAAE,EAAE,EAAE,cAAc,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,KAAK,EAAE,CACpF,CAAC;AACJ,CAAC;AAED,SAAS,aAAa,CACpB,OAAqB,EACrB,KAAa,EACb,iBAA0B;IAE1B,MAAM,MAAM,GAAG,IAAI,GAAG,EAAkB,CAAC;IACzC,KAAK,MAAM,KAAK,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QACnC,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;QACtC,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAChD,CAAC;IACD,OAAO;QACL,eAAe,EAAE,MAAM,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,CAAC;QAC9C,gBAAgB,EAAE,OAAO,CAAC,gBAAgB;QAC1C,cAAc,EAAE,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC;QAC5C,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,iBAAiB,EAAE,MAAM,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,CAAC;QAClD,GAAG,CAAC,iBAAiB,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,iBAAiB,EAAE,CAAC;QACjE,YAAY,EAAE,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC;QACxC,KAAK;QACL,eAAe,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM;KACvC,CAAC;AACJ,CAAC;AAED,SAAS,kBAAkB,CACzB,MAA6B,EAC7B,WAAqC,EACrC,cAA+C;IAE/C,MAAM,MAAM,GAAG,IAAI,GAAG,EAAsB,CAAC;IAC7C,MAAM,MAAM,GAAyC,EAAE,CAAC;IACxD,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY,IAAI,KAAK,CAAC,IAAI,KAAK,WAAW;YAAE,SAAS;QACxE,MAAM,QAAQ,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;QACtC,IAAI,CAAC,QAAQ,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;YAAE,SAAS;QAC7C,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;YAChC,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;YAC5B,SAAS;QACX,CAAC;QACD,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACnC,IAAI,CAAC,KAAK,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;YAAE,SAAS;QAC1C,MAAM,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC;IACtD,CAAC;IACD,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;IAC/D,MAAM,aAAa,GAAG,qBAAqB,CAAC,MAAM,CAAC,CAAC;IAEpD,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;QAC9B,MAAM,OAAO,GAAkB,EAAE,CAAC;QAClC,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;YACtD,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;YACnC,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;YAC9B,IAAI,CAAC,QAAQ,IAAI,CAAC,OAAO;gBAAE,SAAS;YACpC,MAAM,UAAU,GAAG,CAAC,OAAO,CAAC,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC;YAC/D,IAAI,UAAU,IAAI,CAAC;gBAAE,SAAS;YAC9B,OAAO,CAAC,IAAI,CAAC;gBACX,eAAe,EAAE,IAAI;gBACrB,kBAAkB,EAAE,cAAc,CAAC,OAAO,CAAC,OAAO,CAAC;gBACnD,UAAU;gBACV,GAAG,CAAC,aAAa;oBACf,CAAC,CAAC;wBACE,aAAa;wBACb,UAAU,EAAE,UAAU,GAAG,aAAa,GAAG,IAAI;qBAC9C;oBACH,CAAC,CAAC,EAAE,CAAC;gBACP,gBAAgB,EAAE,cAAc,CAAC,QAAQ,CAAC,OAAO,CAAC;aACnD,CAAC,CAAC;QACL,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,OAAO,MAAM;SACV,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;QACb,MAAM,UAAU,GAAG,CAAC,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC;QACxD,OAAO;YACL,kBAAkB,EAAE,cAAc,CAAC,KAAK,CAAC,KAAK,CAAC;YAC/C,UAAU;YACV,GAAG,CAAC,aAAa;gBACf,CAAC,CAAC;oBACE,aAAa;oBACb,UAAU,EAAE,UAAU,GAAG,aAAa,GAAG,IAAI;iBAC9C;gBACH,CAAC,CAAC,EAAE,CAAC;YACP,gBAAgB,EAAE,cAAc,CAAC,KAAK,CAAC,OAAO,CAAC;SAChD,CAAC;IACJ,CAAC,CAAC;SACD,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC;AAC/C,CAAC;AAED,SAAS,qBAAqB,CAAC,MAAsC;IACnE,MAAM,SAAS,GAAa,EAAE,CAAC;IAC/B,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;QACtD,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;QACnC,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;QAC9B,IAAI,CAAC,QAAQ,IAAI,CAAC,OAAO;YAAE,SAAS;QACpC,MAAM,UAAU,GAAG,CAAC,OAAO,CAAC,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC;QAC/D,IAAI,UAAU,IAAI,GAAG,IAAI,UAAU,IAAI,EAAE;YAAE,SAAS,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACxE,CAAC;IACD,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,SAAS,CAAC;IAC3C,SAAS,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,CAAC,KAAK,GAAG,MAAM,CAAC,CAAC;IAClD,MAAM,gBAAgB,GAAG,UAAU,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;IACpD,MAAM,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,gBAAgB,CAAC,CAAC;IAC1D,OAAO,aAAa,IAAI,EAAE,IAAI,aAAa,IAAI,GAAG,CAAC,CAAC,CAAC,IAAI,GAAG,aAAa,CAAC,CAAC,CAAC,SAAS,CAAC;AACxF,CAAC;AAED,SAAS,UAAU,CAAC,MAAyB,EAAE,QAAgB;IAC7D,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IAC/C,MAAM,QAAQ,GAAG,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,QAAQ,CAAC;IAChD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IACnC,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAClC,MAAM,UAAU,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACtC,MAAM,UAAU,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,UAAU,CAAC;IAC/C,OAAO,UAAU,GAAG,CAAC,UAAU,GAAG,UAAU,CAAC,GAAG,CAAC,QAAQ,GAAG,KAAK,CAAC,CAAC;AACrE,CAAC;AAED,SAAS,qBAAqB,CAC5B,MAA6B,EAC7B,cAA+C;IAE/C,MAAM,OAAO,GAA2B,EAAE,CAAC;IAC3C,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,IAAI,KAAK,CAAC,EAAE,KAAK,GAAG;YAAE,SAAS;QAC3D,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,GAAG,IAAI,CAAC;YAAE,SAAS;QACxE,OAAO,CAAC,IAAI,CAAC;YACX,kBAAkB,EAAE,cAAc,CAAC,KAAK,CAAC,EAAE,GAAG,KAAK,CAAC,GAAG,CAAC;YACxD,UAAU,EAAE,KAAK,CAAC,GAAG,GAAG,IAAI;SAC7B,CAAC,CAAC;IACL,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,SAAS,eAAe,CACtB,MAA6B,EAC7B,UAAmB;IAEnB,IAAI,CAAC,UAAU;QAAE,OAAO,SAAS,CAAC;IAClC,OAAO,MAAM,CAAC,IAAI,CAChB,CAAC,SAAS,EAAE,EAAE,CACZ,SAAS,CAAC,IAAI,KAAK,UAAU;QAC7B,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,OAAO,KAAK,UAAU;QAC/C,QAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,KAAK,UAAU,CACjE,CAAC;AACJ,CAAC;AAED,SAAS,aAAa,CAAC,KAAiB;IACtC,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAClC,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,IAAI,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,UAAU,CAAC;IAChE,OAAO,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AACzD,CAAC;AAED,SAAS,sBAAsB,CAC7B,IAAY,EACZ,OAA+B,EAC/B,MAA+B,EAC/B,kBAA4B,EAC5B,kBAA4B,EAC5B,sBAA8B;IAE9B,OAAO;QACL,aAAa,EAAE,YAAY;QAC3B,MAAM,EAAE,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS;QAC/C,IAAI;QACJ,kBAAkB,EAAE,EAAE;QACtB,kBAAkB,EAAE;YAClB,GAAG,kBAAkB;YACrB,GAAG,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC;gBACpB,CAAC,CAAC,EAAE;gBACJ,CAAC,CAAC;oBACE,MAAM,IAAI,kDAAkD,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,MAAM,GAAG;iBACvG,CAAC;SACP;QACD,OAAO;QACP,OAAO,EAAE,wBAAwB,CAAC,OAAO,CAAC;QAC1C,sBAAsB;KACvB,CAAC;AACJ,CAAC;AAED,SAAS,oBAAoB,CAC3B,IAAY,EACZ,OAAsB,EACtB,MAA+B,EAC/B,kBAA4B,EAC5B,kBAA4B,EAC5B,sBAA8B;IAE9B,MAAM,OAAO,GAAG,eAAe,CAAC,OAAO,CAAC,CAAC;IACzC,MAAM,yBAAyB,GAAG,CAAC,OAAO,CAAC,eAAe,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;IACrE,OAAO;QACL,MAAM,EAAE,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,yBAAyB,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM;QACzF,IAAI;QACJ,kBAAkB,EAAE,EAAE;QACtB,kBAAkB,EAAE;YAClB,GAAG,kBAAkB;YACrB,GAAG,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC;gBACpB,CAAC,CAAC,EAAE;gBACJ,CAAC,CAAC;oBACE,MAAM,IAAI,kDAAkD,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,MAAM,GAAG;iBACvG,CAAC;YACN,GAAG,CAAC,yBAAyB;gBAC3B,CAAC,CAAC,CAAC,iEAAiE,CAAC;gBACrE,CAAC,CAAC,EAAE,CAAC;SACR;QACD,OAAO;QACP,OAAO;QACP,sBAAsB;KACvB,CAAC;AACJ,CAAC;AAED,SAAS,eAAe,CAAC,MAA6B;IACpD,MAAM,MAAM,GAAG,IAAI,GAAG,EAAkB,CAAC;IACzC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,IAAI,SAAS,CAAC,CAAC;QAC7C,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAChD,CAAC;IACD,OAAO,CAAC,GAAG,MAAM,CAAC,OAAO,EAAE,CAAC;SACzB,IAAI,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;SAC7C,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC;SACZ,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,GAAG,IAAI,IAAI,KAAK,GAAG,CAAC,CAAC;AACjD,CAAC;AAED,SAAS,2BAA2B,CAClC,IAAY,EACZ,MAAc;IAEd,OAAO;QACL,aAAa,EAAE,YAAY;QAC3B,MAAM,EAAE,aAAa;QACrB,IAAI;QACJ,kBAAkB,EAAE,CAAC,MAAM,CAAC;QAC5B,kBAAkB,EAAE,EAAE;QACtB,OAAO,EAAE,EAAE;QACX,OAAO,EAAE,EAAE,SAAS,EAAE,CAAC,EAAE;KAC1B,CAAC;AACJ,CAAC;AAED,SAAS,yBAAyB,CAAC,IAAY,EAAE,MAAc;IAC7D,OAAO;QACL,MAAM,EAAE,aAAa;QACrB,IAAI;QACJ,kBAAkB,EAAE,CAAC,MAAM,CAAC;QAC5B,kBAAkB,EAAE,EAAE;QACtB,OAAO,EAAE,EAAE;QACX,OAAO,EAAE,EAAE,UAAU,EAAE,CAAC,EAAE;KAC3B,CAAC;AACJ,CAAC;AAED,SAAS,WAAW,CAAI,OAAmB,EAAE,SAAiB,EAAE,OAAe;IAC7E,IAAI,KAAiC,CAAC;IACtC,OAAO,OAAO,CAAC,IAAI,CAAC;QAClB,OAAO;QACP,IAAI,OAAO,CAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE;YACtC,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;QAClE,CAAC,CAAC;KACH,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC;AACxC,CAAC;AAED,SAAS,MAAM,CAAC,KAAc;IAC5B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;AAC7D,CAAC;AAED,SAAS,QAAQ,CAAC,KAAc;IAC9B,OAAO,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAChE,CAAC,CAAE,KAAiC;QACpC,CAAC,CAAC,EAAE,CAAC;AACT,CAAC"}
@@ -0,0 +1,26 @@
1
+ export interface FrameSample {
2
+ cadenceInterval?: boolean;
3
+ completedAtEpochMs: number;
4
+ durationMs: number;
5
+ frameBudgetMs?: number;
6
+ overBudget?: boolean;
7
+ startedAtEpochMs?: number;
8
+ }
9
+ export interface FrameMetricSummary {
10
+ activeFps?: number;
11
+ cadenceGapCount?: number;
12
+ fpsIntervalCount?: number;
13
+ fpsUnavailableReason?: 'insufficient_active_frames' | 'refresh_rate_unavailable' | 'unclassified_cadence_gap';
14
+ frameBudgetMs?: number;
15
+ frameCount: number;
16
+ longestCadenceGapMs?: number;
17
+ longestFrameMs?: number;
18
+ overBudgetFrameCount?: number;
19
+ overBudgetFramePercent?: number;
20
+ p50FrameMs?: number;
21
+ p95FrameMs?: number;
22
+ p99FrameMs?: number;
23
+ refreshRateHz?: number;
24
+ }
25
+ export declare function summarizeFrames(samples: readonly FrameSample[]): FrameMetricSummary;
26
+ //# sourceMappingURL=frame-metrics.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frame-metrics.d.ts","sourceRoot":"","sources":["../../src/runtime/frame-metrics.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,WAAW;IAC1B,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,kBAAkB;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,oBAAoB,CAAC,EACjB,4BAA4B,GAC5B,0BAA0B,GAC1B,0BAA0B,CAAC;IAC/B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAID,wBAAgB,eAAe,CAAC,OAAO,EAAE,SAAS,WAAW,EAAE,GAAG,kBAAkB,CAgGnF"}
@@ -0,0 +1,134 @@
1
+ const MIN_ACTIVE_INTERVALS = 5;
2
+ export function summarizeFrames(samples) {
3
+ const allValidSamples = samples.filter((sample) => Number.isFinite(sample.durationMs) && sample.durationMs > 0);
4
+ const frameBudgetMs = commonFrameBudget(allValidSamples);
5
+ const cadenceSamples = allValidSamples.length > 0 &&
6
+ allValidSamples.every((sample) => sample.cadenceInterval === true);
7
+ const cadenceGaps = cadenceSamples && frameBudgetMs
8
+ ? allValidSamples.filter((sample) => sample.durationMs > frameBudgetMs * 3.01)
9
+ : [];
10
+ const validSamples = cadenceGaps.length > 0
11
+ ? allValidSamples.filter((sample) => sample.durationMs <= (frameBudgetMs ?? 0) * 3.01)
12
+ : allValidSamples;
13
+ const durations = validSamples
14
+ .map((sample) => sample.durationMs)
15
+ .sort((first, second) => first - second);
16
+ if (durations.length === 0) {
17
+ return {
18
+ fpsUnavailableReason: frameBudgetMs
19
+ ? 'insufficient_active_frames'
20
+ : 'refresh_rate_unavailable',
21
+ ...(cadenceGaps.length > 0
22
+ ? {
23
+ cadenceGapCount: cadenceGaps.length,
24
+ longestCadenceGapMs: round(Math.max(...cadenceGaps.map((sample) => sample.durationMs))),
25
+ }
26
+ : {}),
27
+ ...(frameBudgetMs
28
+ ? {
29
+ frameBudgetMs: round(frameBudgetMs),
30
+ refreshRateHz: round(1000 / frameBudgetMs),
31
+ }
32
+ : {}),
33
+ frameCount: 0,
34
+ };
35
+ }
36
+ const frameBudgetOutcomes = validSamples
37
+ .map((sample) => sample.overBudget)
38
+ .filter((value) => value !== undefined);
39
+ const missedFrameBudgetCount = frameBudgetOutcomes.filter(Boolean).length;
40
+ const activeIntervals = frameBudgetMs
41
+ ? activeRenderingIntervals(validSamples, frameBudgetMs)
42
+ : [];
43
+ const activeElapsedMs = activeIntervals.reduce((total, interval) => total + interval, 0);
44
+ const hasActiveFps = cadenceGaps.length === 0 &&
45
+ activeIntervals.length >= MIN_ACTIVE_INTERVALS &&
46
+ activeElapsedMs > 0;
47
+ const refreshRateHz = frameBudgetMs ? 1000 / frameBudgetMs : undefined;
48
+ return {
49
+ ...(hasActiveFps
50
+ ? {
51
+ activeFps: round(Math.min(refreshRateHz ?? Number.POSITIVE_INFINITY, (activeIntervals.length * 1000) / activeElapsedMs)),
52
+ fpsIntervalCount: activeIntervals.length,
53
+ }
54
+ : {
55
+ fpsUnavailableReason: frameBudgetMs
56
+ ? cadenceGaps.length > 0
57
+ ? 'unclassified_cadence_gap'
58
+ : 'insufficient_active_frames'
59
+ : 'refresh_rate_unavailable',
60
+ }),
61
+ ...(cadenceGaps.length > 0
62
+ ? {
63
+ cadenceGapCount: cadenceGaps.length,
64
+ longestCadenceGapMs: round(Math.max(...cadenceGaps.map((sample) => sample.durationMs))),
65
+ }
66
+ : {}),
67
+ ...(frameBudgetMs
68
+ ? {
69
+ frameBudgetMs: round(frameBudgetMs),
70
+ refreshRateHz: round(1000 / frameBudgetMs),
71
+ }
72
+ : {}),
73
+ frameCount: durations.length,
74
+ ...(frameBudgetOutcomes.length === validSamples.length
75
+ ? {
76
+ overBudgetFrameCount: missedFrameBudgetCount,
77
+ overBudgetFramePercent: round((missedFrameBudgetCount / validSamples.length) * 100),
78
+ }
79
+ : {}),
80
+ longestFrameMs: round(durations.at(-1) ?? 0),
81
+ p50FrameMs: round(percentile(durations, 0.5)),
82
+ p95FrameMs: round(percentile(durations, 0.95)),
83
+ p99FrameMs: round(percentile(durations, 0.99)),
84
+ };
85
+ }
86
+ function commonFrameBudget(samples) {
87
+ const budgets = samples
88
+ .map((sample) => sample.frameBudgetMs)
89
+ .filter((value) => value !== undefined && Number.isFinite(value) && value > 0)
90
+ .sort((first, second) => first - second);
91
+ return budgets.length > 0 ? percentile(budgets, 0.5) : undefined;
92
+ }
93
+ function activeRenderingIntervals(samples, frameBudgetMs) {
94
+ if (samples.every((sample) => sample.cadenceInterval === true)) {
95
+ return samples
96
+ .map((sample) => sample.durationMs)
97
+ .filter((durationMs) => Number.isFinite(durationMs) && durationMs > 0 && durationMs <= frameBudgetMs * 3.01);
98
+ }
99
+ const ordered = [...samples]
100
+ .map((sample) => ({
101
+ ...sample,
102
+ startedAtEpochMs: sample.startedAtEpochMs ?? sample.completedAtEpochMs - sample.durationMs,
103
+ }))
104
+ .sort((first, second) => first.startedAtEpochMs - second.startedAtEpochMs);
105
+ const intervals = [];
106
+ for (let index = 1; index < ordered.length; index += 1) {
107
+ const previous = ordered[index - 1];
108
+ const current = ordered[index];
109
+ if (!previous || !current)
110
+ continue;
111
+ const interval = current.startedAtEpochMs - previous.startedAtEpochMs;
112
+ if (!Number.isFinite(interval) || interval <= 0)
113
+ continue;
114
+ const continuous = interval <= frameBudgetMs * 3.01;
115
+ const explainedBySlowFrame = Math.max(previous.durationMs, current.durationMs) >= interval - frameBudgetMs * 1.01;
116
+ if (continuous || explainedBySlowFrame)
117
+ intervals.push(interval);
118
+ }
119
+ return intervals;
120
+ }
121
+ function percentile(sorted, quantile) {
122
+ if (sorted.length === 1)
123
+ return sorted[0] ?? 0;
124
+ const position = (sorted.length - 1) * quantile;
125
+ const lower = Math.floor(position);
126
+ const upper = Math.ceil(position);
127
+ const lowerValue = sorted[lower] ?? 0;
128
+ const upperValue = sorted[upper] ?? lowerValue;
129
+ return lowerValue + (upperValue - lowerValue) * (position - lower);
130
+ }
131
+ function round(value) {
132
+ return Math.round(value * 1000) / 1000;
133
+ }
134
+ //# sourceMappingURL=frame-metrics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frame-metrics.js","sourceRoot":"","sources":["../../src/runtime/frame-metrics.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ export interface JavaScriptTaskSample {
2
+ completedAtEpochMs: number;
3
+ durationMs: number;
4
+ }
5
+ export interface JavaScriptTaskMetricSummary {
6
+ longestTaskMs?: number;
7
+ longTaskCount?: number;
8
+ longTaskPercent?: number;
9
+ p50TaskMs?: number;
10
+ p95TaskMs?: number;
11
+ p99TaskMs?: number;
12
+ taskCount: number;
13
+ totalTaskTimeMs?: number;
14
+ }
15
+ export declare function summarizeJavaScriptTasks(samples: readonly JavaScriptTaskSample[]): JavaScriptTaskMetricSummary;
16
+ //# sourceMappingURL=js-task-metrics.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"js-task-metrics.d.ts","sourceRoot":"","sources":["../../src/runtime/js-task-metrics.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,oBAAoB;IACnC,kBAAkB,EAAE,MAAM,CAAC;IAC3B,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,2BAA2B;IAC1C,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,SAAS,oBAAoB,EAAE,GACvC,2BAA2B,CAkB7B"}
@@ -0,0 +1,34 @@
1
+ const LONG_TASK_MS = 50;
2
+ export function summarizeJavaScriptTasks(samples) {
3
+ const durations = samples
4
+ .map((sample) => sample.durationMs)
5
+ .filter((duration) => Number.isFinite(duration) && duration > 0)
6
+ .sort((first, second) => first - second);
7
+ if (durations.length === 0)
8
+ return { taskCount: 0 };
9
+ const longTaskCount = durations.filter((duration) => duration >= LONG_TASK_MS).length;
10
+ return {
11
+ longestTaskMs: round(durations.at(-1) ?? 0),
12
+ longTaskCount,
13
+ longTaskPercent: round((longTaskCount / durations.length) * 100),
14
+ p50TaskMs: round(percentile(durations, 0.5)),
15
+ p95TaskMs: round(percentile(durations, 0.95)),
16
+ p99TaskMs: round(percentile(durations, 0.99)),
17
+ taskCount: durations.length,
18
+ totalTaskTimeMs: round(durations.reduce((total, duration) => total + duration, 0)),
19
+ };
20
+ }
21
+ function percentile(sorted, quantile) {
22
+ if (sorted.length === 1)
23
+ return sorted[0] ?? 0;
24
+ const position = (sorted.length - 1) * quantile;
25
+ const lower = Math.floor(position);
26
+ const upper = Math.ceil(position);
27
+ const lowerValue = sorted[lower] ?? 0;
28
+ const upperValue = sorted[upper] ?? lowerValue;
29
+ return lowerValue + (upperValue - lowerValue) * (position - lower);
30
+ }
31
+ function round(value) {
32
+ return Math.round(value * 1000) / 1000;
33
+ }
34
+ //# sourceMappingURL=js-task-metrics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"js-task-metrics.js","sourceRoot":"","sources":["../../src/runtime/js-task-metrics.ts"],"names":[],"mappings":"AAAA,MAAM,YAAY,GAAG,EAAE,CAAC;AAkBxB,MAAM,UAAU,wBAAwB,CACtC,OAAwC;IAExC,MAAM,SAAS,GAAG,OAAO;SACtB,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC;SAClC,MAAM,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,QAAQ,GAAG,CAAC,CAAC;SAC/D,IAAI,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,CAAC,KAAK,GAAG,MAAM,CAAC,CAAC;IAC3C,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC;IAEpD,MAAM,aAAa,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,IAAI,YAAY,CAAC,CAAC,MAAM,CAAC;IACtF,OAAO;QACL,aAAa,EAAE,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAC3C,aAAa;QACb,eAAe,EAAE,KAAK,CAAC,CAAC,aAAa,GAAG,SAAS,CAAC,MAAM,CAAC,GAAG,GAAG,CAAC;QAChE,SAAS,EAAE,KAAK,CAAC,UAAU,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;QAC5C,SAAS,EAAE,KAAK,CAAC,UAAU,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;QAC7C,SAAS,EAAE,KAAK,CAAC,UAAU,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;QAC7C,SAAS,EAAE,SAAS,CAAC,MAAM;QAC3B,eAAe,EAAE,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE,CAAC,KAAK,GAAG,QAAQ,EAAE,CAAC,CAAC,CAAC;KACnF,CAAC;AACJ,CAAC;AAED,SAAS,UAAU,CAAC,MAAyB,EAAE,QAAgB;IAC7D,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IAC/C,MAAM,QAAQ,GAAG,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,QAAQ,CAAC;IAChD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IACnC,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAClC,MAAM,UAAU,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACtC,MAAM,UAAU,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,UAAU,CAAC;IAC/C,OAAO,UAAU,GAAG,CAAC,UAAU,GAAG,UAAU,CAAC,GAAG,CAAC,QAAQ,GAAG,KAAK,CAAC,CAAC;AACrE,CAAC;AAED,SAAS,KAAK,CAAC,KAAa;IAC1B,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC;AACzC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@farmslot/recipe-runner",
3
- "version": "0.25.0",
3
+ "version": "0.27.0",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -63,6 +63,11 @@
63
63
  "import": "./dist/runtime/cdp.js",
64
64
  "default": "./dist/runtime/cdp.js"
65
65
  },
66
+ "./runtime/cdp-trace": {
67
+ "types": "./dist/runtime/cdp-trace.d.ts",
68
+ "import": "./dist/runtime/cdp-trace.js",
69
+ "default": "./dist/runtime/cdp-trace.js"
70
+ },
66
71
  "./runtime/react-native-bridge": {
67
72
  "types": "./dist/runtime/react-native-bridge.d.ts",
68
73
  "import": "./dist/runtime/react-native-bridge.js",