Skip to content

Commit f22a7e3

Browse files
niieanibbrzoska
authored andcommitted
refactor: extract common functionality
1 parent 6c62f57 commit f22a7e3

File tree

4 files changed

+211
-188
lines changed

4 files changed

+211
-188
lines changed

src/v3/ConsoleTraceLogger.ts

Lines changed: 17 additions & 132 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
1-
import {
2-
DEFAULT_DEBOUNCE_DURATION,
3-
DEFAULT_INTERACTIVE_TIMEOUT_DURATION,
4-
} from './constants'
51
import type {
62
AllPossibleRequiredSpanSeenEvents,
73
AllPossibleStateTransitionEvents,
84
AllPossibleTraceStartEvents,
95
} from './debugTypes'
10-
import { isSuppressedError } from './debugUtils'
6+
import {
7+
extractTimingOffsets,
8+
formatMatcher,
9+
getComputedResults,
10+
getConfigSummary,
11+
isSuppressedError,
12+
} from './debugUtils'
1113
import type { SpanMatcherFn } from './matchSpan'
12-
import { createTraceRecording } from './recordingComputeUtils'
1314
import type { FinalTransition, OnEnterStatePayload } from './Trace'
1415
import { isTerminalState } from './Trace'
1516
import type { TraceManager } from './TraceManager'
@@ -34,73 +35,6 @@ interface ConsoleLike {
3435
// Add other console methods if needed (warn, error, etc.)
3536
}
3637

37-
/**
38-
* Formats a SpanMatcherFn into a more readable string representation.
39-
* This is a basic implementation and can be significantly improved
40-
* based on the actual structure of `matcher.fromDefinition`.
41-
*
42-
* @param matcher The matcher function to format.
43-
* @param index Optional index for generic naming.
44-
* @returns A string representation of the matcher.
45-
*/
46-
export function formatMatcher<
47-
SelectedRelationNameT extends keyof RelationSchemasT,
48-
RelationSchemasT extends RelationSchemasBase<RelationSchemasT>,
49-
VariantsT extends string,
50-
>(
51-
matcher: SpanMatcherFn<SelectedRelationNameT, RelationSchemasT, VariantsT>,
52-
index?: number,
53-
): string {
54-
// Check if the matcher has attached definition info
55-
if (matcher.fromDefinition) {
56-
// Attempt to create a more descriptive name from the definition
57-
// This part needs customization based on how 'fromDefinition' is structured.
58-
// Example: Check for specific properties like 'name', 'type', 'label' etc.
59-
const def = matcher.fromDefinition
60-
const parts: string[] = []
61-
62-
if (typeof def === 'object' && def !== null) {
63-
// Example: Prioritize 'label' if it exists
64-
if ('label' in def && typeof def.label === 'string') {
65-
return `Label: "${def.label}"`
66-
}
67-
// Example: Use 'name' if it exists
68-
if ('name' in def) {
69-
if (typeof def.name === 'string') {
70-
parts.push(`Name: "${def.name}"`)
71-
} else if (def.name instanceof RegExp) {
72-
parts.push(`Name: /${def.name.source}/${def.name.flags}`)
73-
}
74-
}
75-
// Example: Add type if present
76-
if ('type' in def && typeof def.type === 'string') {
77-
parts.push(`Type: ${def.type}`)
78-
}
79-
// Add other relevant properties from your definition structure
80-
}
81-
82-
if (parts.length > 0) {
83-
return parts.join(', ')
84-
}
85-
86-
// Fallback: Stringify the definition (can be verbose)
87-
try {
88-
const defString = JSON.stringify(def)
89-
// Limit length to avoid overly long strings
90-
return defString.length > 100
91-
? // eslint-disable-next-line no-magic-numbers
92-
`${defString.slice(0, 97)}...`
93-
: defString
94-
} catch {
95-
// Fallback if stringify fails
96-
return `Matcher Definition #${index ?? '?'}`
97-
}
98-
}
99-
100-
// Fallback if no definition info is available
101-
return `Matcher #${index ?? '?'}`
102-
}
103-
10438
/**
10539
* Options for configuring the ConsoleTraceLogger
10640
*/
@@ -156,45 +90,6 @@ interface TraceInfo<RelationSchemasT> {
15690
requiredSpans: { name: string; isMatched: boolean; matcher: Function }[]
15791
}
15892

159-
/**
160-
* Extract timing offsets from a transition object
161-
*/
162-
const extractTimingOffsets = <RelationSchemasT>(
163-
transition: OnEnterStatePayload<RelationSchemasT>,
164-
) => {
165-
// ... (implementation unchanged) ...
166-
let lastRequiredSpanOffset: number | undefined
167-
let completeSpanOffset: number | undefined
168-
let cpuIdleSpanOffset: number | undefined
169-
170-
if (
171-
'lastRequiredSpanAndAnnotation' in transition &&
172-
transition.lastRequiredSpanAndAnnotation
173-
) {
174-
lastRequiredSpanOffset =
175-
transition.lastRequiredSpanAndAnnotation.annotation
176-
.operationRelativeEndTime
177-
}
178-
179-
if (
180-
'completeSpanAndAnnotation' in transition &&
181-
transition.completeSpanAndAnnotation
182-
) {
183-
completeSpanOffset =
184-
transition.completeSpanAndAnnotation.annotation.operationRelativeEndTime
185-
}
186-
187-
if (
188-
'cpuIdleSpanAndAnnotation' in transition &&
189-
transition.cpuIdleSpanAndAnnotation
190-
) {
191-
cpuIdleSpanOffset =
192-
transition.cpuIdleSpanAndAnnotation.annotation.operationRelativeEndTime
193-
}
194-
195-
return { lastRequiredSpanOffset, completeSpanOffset, cpuIdleSpanOffset }
196-
}
197-
19893
/**
19994
* Format timestamp to readable time
20095
*/
@@ -474,16 +369,7 @@ export function createConsoleTraceLogger<
474369
}
475370
log(` Required spans: ${requiredSpans.length}`)
476371
// Log config summary
477-
const variantConfig = trace.definition.variants[trace.input.variant]
478-
const timeout = variantConfig?.timeout
479-
const debounce =
480-
trace.definition.debounceWindow ?? DEFAULT_DEBOUNCE_DURATION
481-
const interactive =
482-
typeof trace.definition.captureInteractive === 'object'
483-
? trace.definition.captureInteractive.timeout
484-
: trace.definition.captureInteractive
485-
? DEFAULT_INTERACTIVE_TIMEOUT_DURATION
486-
: undefined
372+
const { timeout, debounce, interactive } = getConfigSummary(trace)
487373
log(
488374
` Config: Timeout=${timeout}ms, Debounce=${debounce}ms${
489375
interactive ? `, Interactive=${interactive}ms` : ''
@@ -550,12 +436,13 @@ export function createConsoleTraceLogger<
550436
logTimingInfo(transition)
551437
// Log computed values and spans
552438
try {
553-
const rec = createTraceRecording(trace, transition)
554-
const computedVals = rec.computedValues
555-
const { computedSpans } = rec
556-
if (computedVals && Object.keys(computedVals).length > 0) {
439+
const { computedValues, computedSpans } = getComputedResults(
440+
trace,
441+
transition,
442+
)
443+
if (computedValues && Object.keys(computedValues).length > 0) {
557444
log(
558-
` Computed Values: ${Object.entries(computedVals)
445+
` Computed Values: ${Object.entries(computedValues)
559446
.map(([k, v]) => `${k}=${v}`)
560447
.join(', ')}`,
561448
)
@@ -587,15 +474,13 @@ export function createConsoleTraceLogger<
587474
logTimingInfo(transition)
588475
// Log computed values and spans
589476
try {
590-
const rec = createTraceRecording(
477+
const { computedValues, computedSpans } = getComputedResults(
591478
trace,
592479
transition as FinalTransition<RelationSchemasT>,
593480
)
594-
const computedVals = rec.computedValues
595-
const { computedSpans } = rec
596-
if (computedVals && Object.keys(computedVals).length > 0) {
481+
if (computedValues && Object.keys(computedValues).length > 0) {
597482
log(
598-
` Computed Values: ${Object.entries(computedVals)
483+
` Computed Values: ${Object.entries(computedValues)
599484
.map(([k, v]) => `${k}=${v}`)
600485
.join(', ')}`,
601486
)

src/v3/TraceManagerDebugger.tsx

Lines changed: 24 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
import React, { useEffect, useRef, useState } from 'react'
22
import {
3-
DEFAULT_DEBOUNCE_DURATION,
4-
DEFAULT_INTERACTIVE_TIMEOUT_DURATION,
5-
} from './constants'
6-
import { isSuppressedError } from './debugUtils'
3+
formatMatcher,
4+
formatMs,
5+
getComputedResults,
6+
getConfigSummary,
7+
isSuppressedError,
8+
} from './debugUtils'
79
import { createTraceRecording } from './recordingComputeUtils'
810
import type { SpanAndAnnotation } from './spanAnnotationTypes'
911
import {
@@ -557,53 +559,6 @@ function getStateStyle(state: string) {
557559

558560
const TRACE_HISTORY_LIMIT = 15
559561

560-
// Add a helper to format ms
561-
function formatMs(ms?: number) {
562-
if (ms == null) return ''
563-
if (ms < 1_000) return `${ms}ms`
564-
return `${(ms / 1_000).toFixed(2)}s`
565-
}
566-
567-
// Add a helper to get config summary from traceContext
568-
function getConfigSummary<RelationSchemasT>(
569-
trace: TraceInfo<RelationSchemasT>,
570-
) {
571-
if (!trace.traceContext) return {}
572-
const def = trace.traceContext.definition
573-
const variant = def.variants[trace.variant]
574-
const timeout = variant?.timeout
575-
const debounce =
576-
(def.debounceOnSpans ?? []).length > 0
577-
? def.debounceWindow ?? DEFAULT_DEBOUNCE_DURATION
578-
: undefined
579-
const interactive =
580-
typeof def.captureInteractive === 'object'
581-
? def.captureInteractive.timeout
582-
: def.captureInteractive
583-
? DEFAULT_INTERACTIVE_TIMEOUT_DURATION
584-
: undefined
585-
return { timeout, debounce, interactive }
586-
}
587-
588-
// Add a helper to get computed values/spans for completed/interrupted traces
589-
function getComputedResults<RelationSchemasT>(
590-
trace: TraceInfo<RelationSchemasT>,
591-
) {
592-
if (!trace.traceContext || !trace.finalTransition) return {}
593-
try {
594-
const recording = createTraceRecording(
595-
trace.traceContext,
596-
trace.finalTransition,
597-
)
598-
return {
599-
computedValues: recording.computedValues,
600-
computedSpans: recording.computedSpans,
601-
}
602-
} catch {
603-
return {}
604-
}
605-
}
606-
607562
// TraceAttributes component to display attributes as chips
608563
function TraceAttributes({
609564
attributes,
@@ -994,7 +949,9 @@ function TraceItem<
994949
<div style={styles.configInfoRow}>
995950
{/* Config summary chips */}
996951
{(() => {
997-
const { timeout, debounce, interactive } = getConfigSummary(trace)
952+
const { timeout, debounce, interactive } = trace.traceContext
953+
? getConfigSummary(trace.traceContext)
954+
: {}
998955
return (
999956
<>
1000957
{timeout != null && (
@@ -1038,7 +995,13 @@ function TraceItem<
1038995
{name}
1039996
{trace.state === 'complete' || trace.state === 'interrupted'
1040997
? (() => {
1041-
const { computedSpans } = getComputedResults(trace)
998+
const { computedSpans } =
999+
trace.traceContext && trace.finalTransition
1000+
? getComputedResults(
1001+
trace.traceContext,
1002+
trace.finalTransition,
1003+
)
1004+
: {}
10421005
if (computedSpans?.[name]) {
10431006
return (
10441007
<span style={{ marginLeft: 8, color: '#1976d2' }}>
@@ -1061,7 +1024,13 @@ function TraceItem<
10611024
{name}
10621025
{trace.state === 'complete' || trace.state === 'interrupted'
10631026
? (() => {
1064-
const { computedValues } = getComputedResults(trace)
1027+
const { computedValues } =
1028+
trace.traceContext && trace.finalTransition
1029+
? getComputedResults(
1030+
trace.traceContext,
1031+
trace.finalTransition,
1032+
)
1033+
: {}
10651034
if (computedValues?.[name] !== undefined) {
10661035
return (
10671036
<span style={{ marginLeft: 8, color: '#1976d2' }}>
@@ -1210,7 +1179,7 @@ export default function TraceManagerDebugger<
12101179
? { ...trace.input.relatedTo }
12111180
: undefined,
12121181
requiredSpans: trace.definition.requiredSpans.map((matcher, index) => {
1213-
const name = `Matcher #${index}`
1182+
const name = formatMatcher(matcher, index)
12141183

12151184
return {
12161185
name,

src/v3/debugTypes.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,3 +129,5 @@ export type DebugEventType =
129129
| 'trace-start'
130130
| 'state-transition'
131131
| 'required-span-seen'
132+
| 'add-span-to-recording'
133+
| 'definition-modified'

0 commit comments

Comments
 (0)