Skip to content

Commit 07a35f7

Browse files
committed
feat: allow MatchDefinitions
1 parent bc16203 commit 07a35f7

10 files changed

+211
-231
lines changed

src/v3/ActiveTrace.ts

Lines changed: 16 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
/* eslint-disable @typescript-eslint/consistent-indexed-object-style */
22
/* eslint-disable max-classes-per-file */
3-
import { doesEntryMatchDefinition } from './doesEntryMatchDefinition'
43
import { ensureTimestamp } from './ensureTimestamp'
54
import {
65
type CPUIdleLongTaskProcessor,
@@ -14,8 +13,11 @@ import type {
1413
SpanAnnotationRecord,
1514
} from './spanAnnotationTypes'
1615
import type { ActiveTraceConfig, Span } from './spanTypes'
17-
import type { CompleteTraceDefinition } from './traceRecordingTypes'
18-
import type { ScopeBase, TraceInterruptionReason } from './types'
16+
import type {
17+
CompleteTraceDefinition,
18+
ScopeBase,
19+
TraceInterruptionReason,
20+
} from './types'
1921
import type {
2022
DistributiveOmit,
2123
MergedStateHandlerMethods,
@@ -146,14 +148,8 @@ export class TraceStateMachine<ScopeT extends ScopeBase> {
146148

147149
// does span satisfy any of the "interruptOn" definitions
148150
if (this.context.definition.interruptOn) {
149-
for (const definition of this.context.definition.interruptOn) {
150-
if (
151-
doesEntryMatchDefinition(
152-
spanAndAnnotation,
153-
definition,
154-
this.context.input.scope,
155-
)
156-
) {
151+
for (const match of this.context.definition.interruptOn) {
152+
if (match(spanAndAnnotation, this.context.input.scope)) {
157153
return {
158154
transitionToState: 'interrupted',
159155
interruptionReason: 'matched-on-interrupt',
@@ -169,20 +165,14 @@ export class TraceStateMachine<ScopeT extends ScopeBase> {
169165
continue
170166
}
171167

172-
const definition = this.context.definition.requiredToEnd[i]!
173-
if (
174-
doesEntryMatchDefinition(
175-
spanAndAnnotation,
176-
definition,
177-
this.context.input.scope,
178-
)
179-
) {
168+
const matcher = this.context.definition.requiredToEnd[i]!
169+
if (matcher(spanAndAnnotation, this.context.input.scope)) {
180170
console.log(
181171
'# got a match!',
182172
'span',
183173
spanAndAnnotation,
184174
'matches',
185-
definition,
175+
matcher,
186176
'remaining items',
187177
this.context.requiredToEndIndexChecklist,
188178
)
@@ -266,11 +256,7 @@ export class TraceStateMachine<ScopeT extends ScopeBase> {
266256
for (const matcher of this.context.definition.requiredToEnd) {
267257
const { span } = spanAndAnnotation
268258
if (
269-
doesEntryMatchDefinition(
270-
spanAndAnnotation,
271-
matcher,
272-
this.context.input.scope,
273-
) &&
259+
matcher(spanAndAnnotation, this.context.input.scope) &&
274260
matcher.isIdle &&
275261
'isIdle' in span &&
276262
span.isIdle
@@ -286,13 +272,7 @@ export class TraceStateMachine<ScopeT extends ScopeBase> {
286272
// does span satisfy any of the "debouncedOn" and if so, restart our debounce timer
287273
if (this.context.definition.debounceOn) {
288274
for (const matcher of this.context.definition.debounceOn) {
289-
if (
290-
doesEntryMatchDefinition(
291-
spanAndAnnotation,
292-
matcher,
293-
this.context.input.scope,
294-
)
295-
) {
275+
if (matcher(spanAndAnnotation, this.context.input.scope)) {
296276
// Sometimes spans are processed out of order, we update the lastRelevant if this span ends later
297277
if (
298278
spanAndAnnotation.annotation.operationRelativeEndTime >
@@ -431,13 +411,7 @@ export class TraceStateMachine<ScopeT extends ScopeBase> {
431411
// transition to complete state with the 'matched-on-interrupt' interruptionReason
432412
if (this.context.definition.interruptOn) {
433413
for (const matcher of this.context.definition.interruptOn) {
434-
if (
435-
doesEntryMatchDefinition(
436-
spanAndAnnotation,
437-
matcher,
438-
this.context.input.scope,
439-
)
440-
) {
414+
if (matcher(spanAndAnnotation, this.context.input.scope)) {
441415
return {
442416
transitionToState: 'complete',
443417
interruptionReason: 'matched-on-interrupt',
@@ -557,15 +531,16 @@ export class ActiveTrace<ScopeT extends ScopeBase> {
557531
// this is public API only and should not be called internally
558532
interrupt(reason: TraceInterruptionReason) {
559533
const transition = this.stateMachine.emit('onInterrupt', reason)
534+
if (!transition) return
560535

561536
const traceRecording = createTraceRecording(
562537
{
563538
definition: this.definition,
564-
// only keep items captured until the endOfOperationSpan
539+
// TODO: only keep items captured until the endOfOperationSpan
565540
recordedItems: this.recordedItems,
566541
input: this.input,
567542
},
568-
transition
543+
transition,
569544
)
570545

571546
this.input.onEnd(traceRecording)

src/v3/doesEntryMatchDefinition.test.ts renamed to src/v3/matchSpan.test.ts

Lines changed: 23 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
import * as matchSpan from './doesEntryMatchDefinition'
2-
import { doesEntryMatchDefinition } from './doesEntryMatchDefinition'
1+
import * as matchSpan from './matchSpan'
32
import type { SpanAnnotation } from './spanAnnotationTypes'
43
import type { ComponentRenderSpan, SpanBase } from './spanTypes'
54
import type { ScopeBase } from './types'
@@ -66,9 +65,7 @@ describe('doesEntryMatchDefinition', () => {
6665
span: mockEntryBase,
6766
annotation: mockAnnotation,
6867
}
69-
expect(
70-
doesEntryMatchDefinition(mockSpanAndAnnotation, matcher, mockScope),
71-
).toBe(true)
68+
expect(matcher(mockSpanAndAnnotation, mockScope)).toBe(true)
7269
})
7370

7471
it('should return true for function matchers for name', () => {
@@ -77,9 +74,7 @@ describe('doesEntryMatchDefinition', () => {
7774
span: mockEntryBase,
7875
annotation: mockAnnotation,
7976
}
80-
expect(
81-
doesEntryMatchDefinition(mockSpanAndAnnotation, matcher, mockScope),
82-
).toBe(true)
77+
expect(matcher(mockSpanAndAnnotation, mockScope)).toBe(true)
8378
})
8479

8580
it('should return true for regex matchers for name', () => {
@@ -88,9 +83,7 @@ describe('doesEntryMatchDefinition', () => {
8883
span: mockEntryBase,
8984
annotation: mockAnnotation,
9085
}
91-
expect(
92-
doesEntryMatchDefinition(mockSpanAndAnnotation, matcher, mockScope),
93-
).toBe(true)
86+
expect(matcher(mockSpanAndAnnotation, mockScope)).toBe(true)
9487
})
9588

9689
it('should return false for a non-matching span based on name', () => {
@@ -99,9 +92,7 @@ describe('doesEntryMatchDefinition', () => {
9992
span: mockEntryBase,
10093
annotation: mockAnnotation,
10194
}
102-
expect(
103-
doesEntryMatchDefinition(mockSpanAndAnnotation, matcher, mockScope),
104-
).toBe(false)
95+
expect(matcher(mockSpanAndAnnotation, mockScope)).toBe(false)
10596
})
10697
})
10798

@@ -112,9 +103,7 @@ describe('doesEntryMatchDefinition', () => {
112103
span: mockPerformanceEntry,
113104
annotation: mockAnnotation,
114105
}
115-
expect(
116-
doesEntryMatchDefinition(mockSpanAndAnnotation, matcher, mockScope),
117-
).toBe(true)
106+
expect(matcher(mockSpanAndAnnotation, mockScope)).toBe(true)
118107
})
119108

120109
it('should return false for a non-matching performanceEntryName', () => {
@@ -123,9 +112,7 @@ describe('doesEntryMatchDefinition', () => {
123112
span: mockPerformanceEntry,
124113
annotation: mockAnnotation,
125114
}
126-
expect(
127-
doesEntryMatchDefinition(mockSpanAndAnnotation, matcher, mockScope),
128-
).toBe(false)
115+
expect(matcher(mockSpanAndAnnotation, mockScope)).toBe(false)
129116
})
130117
})
131118

@@ -137,9 +124,7 @@ describe('doesEntryMatchDefinition', () => {
137124
span: mockEntryBase,
138125
annotation: mockAnnotation,
139126
}
140-
expect(
141-
doesEntryMatchDefinition(mockSpanAndAnnotation, matcher, mockScope),
142-
).toBe(true)
127+
expect(matcher(mockSpanAndAnnotation, mockScope)).toBe(true)
143128
})
144129

145130
it('should return false for non-matching attributes', () => {
@@ -148,9 +133,7 @@ describe('doesEntryMatchDefinition', () => {
148133
span: mockEntryBase,
149134
annotation: mockAnnotation,
150135
}
151-
expect(
152-
doesEntryMatchDefinition(mockSpanAndAnnotation, matcher, mockScope),
153-
).toBe(false)
136+
expect(matcher(mockSpanAndAnnotation, mockScope)).toBe(false)
154137
})
155138
})
156139

@@ -164,9 +147,7 @@ describe('doesEntryMatchDefinition', () => {
164147
span: mockComponentEntry,
165148
annotation: mockAnnotation,
166149
}
167-
expect(
168-
doesEntryMatchDefinition(mockSpanAndAnnotation, matcher, mockScope),
169-
).toBe(true)
150+
expect(matcher(mockSpanAndAnnotation, mockScope)).toBe(true)
170151
})
171152

172153
it('should return false for a non-matching ComponentRenderTraceEntry', () => {
@@ -178,9 +159,7 @@ describe('doesEntryMatchDefinition', () => {
178159
span: mockComponentEntry,
179160
annotation: mockAnnotation,
180161
}
181-
expect(
182-
doesEntryMatchDefinition(mockSpanAndAnnotation, matcher, mockScope),
183-
).toBe(false)
162+
expect(matcher(mockSpanAndAnnotation, mockScope)).toBe(false)
184163
})
185164
})
186165
})
@@ -192,9 +171,7 @@ describe('doesEntryMatchDefinition', () => {
192171
span: mockEntryBase,
193172
annotation: mockAnnotation,
194173
}
195-
expect(
196-
doesEntryMatchDefinition(mockSpanAndAnnotation, matcher, mockScope),
197-
).toBe(true)
174+
expect(matcher(mockSpanAndAnnotation, mockScope)).toBe(true)
198175
})
199176

200177
it('should return false when status does not match', () => {
@@ -203,9 +180,7 @@ describe('doesEntryMatchDefinition', () => {
203180
span: mockEntryBase,
204181
annotation: mockAnnotation,
205182
}
206-
expect(
207-
doesEntryMatchDefinition(mockSpanAndAnnotation, matcher, mockScope),
208-
).toBe(false)
183+
expect(matcher(mockSpanAndAnnotation, mockScope)).toBe(false)
209184
})
210185
})
211186

@@ -219,10 +194,7 @@ describe('doesEntryMatchDefinition', () => {
219194
span: mockEntryBase,
220195
annotation: mockAnnotation,
221196
}
222-
// Assuming occurrence logic is implemented in the function
223-
expect(
224-
doesEntryMatchDefinition(mockSpanAndAnnotation, matcher, mockScope),
225-
).toBe(true)
197+
expect(matcher(mockSpanAndAnnotation, mockScope)).toBe(true)
226198
})
227199

228200
it('should return false for non-matching occurrence', () => {
@@ -234,10 +206,7 @@ describe('doesEntryMatchDefinition', () => {
234206
span: mockEntryBase,
235207
annotation: mockAnnotation,
236208
}
237-
// Assuming occurrence logic is implemented in the function
238-
expect(
239-
doesEntryMatchDefinition(mockSpanAndAnnotation, matcher, mockScope),
240-
).toBe(false)
209+
expect(matcher(mockSpanAndAnnotation, mockScope)).toBe(false)
241210
})
242211
})
243212

@@ -248,9 +217,7 @@ describe('doesEntryMatchDefinition', () => {
248217
span: mockEntryBase,
249218
annotation: mockAnnotation,
250219
}
251-
expect(
252-
doesEntryMatchDefinition(mockSpanAndAnnotation, matcher, mockScope),
253-
).toBe(true)
220+
expect(matcher(mockSpanAndAnnotation, mockScope)).toBe(true)
254221
})
255222

256223
it('should return false for non-matching attributes', () => {
@@ -259,9 +226,7 @@ describe('doesEntryMatchDefinition', () => {
259226
span: mockEntryBase,
260227
annotation: mockAnnotation,
261228
}
262-
expect(
263-
doesEntryMatchDefinition(mockSpanAndAnnotation, matcher, mockScope),
264-
).toBe(false)
229+
expect(matcher(mockSpanAndAnnotation, mockScope)).toBe(false)
265230
})
266231
})
267232

@@ -275,9 +240,7 @@ describe('doesEntryMatchDefinition', () => {
275240
span: mockEntryBase,
276241
annotation: mockAnnotation,
277242
}
278-
expect(
279-
doesEntryMatchDefinition(mockSpanAndAnnotation, matcher, mockScope),
280-
).toBe(true)
243+
expect(matcher(mockSpanAndAnnotation, mockScope)).toBe(true)
281244
})
282245

283246
it('should return false when scope does not match', () => {
@@ -293,9 +256,7 @@ describe('doesEntryMatchDefinition', () => {
293256
span: mockEntryBase,
294257
annotation: mockAnnotation,
295258
}
296-
expect(
297-
doesEntryMatchDefinition(mockSpanAndAnnotation, matcher, scope),
298-
).toBe(false)
259+
expect(matcher(mockSpanAndAnnotation, scope)).toBe(false)
299260
})
300261
})
301262

@@ -310,9 +271,7 @@ describe('doesEntryMatchDefinition', () => {
310271
span: mockComponentEntry,
311272
annotation: mockAnnotation,
312273
}
313-
expect(
314-
doesEntryMatchDefinition(mockSpanAndAnnotation, mockMatcher, mockScope),
315-
).toBe(true)
274+
expect(mockMatcher(mockSpanAndAnnotation, mockScope)).toBe(true)
316275
})
317276

318277
it('should return false for non-matching isIdle', () => {
@@ -321,9 +280,7 @@ describe('doesEntryMatchDefinition', () => {
321280
span: mockEntry,
322281
annotation: mockAnnotation,
323282
}
324-
expect(
325-
doesEntryMatchDefinition(mockSpanAndAnnotation, mockMatcher, mockScope),
326-
).toBe(false)
283+
expect(mockMatcher(mockSpanAndAnnotation, mockScope)).toBe(false)
327284
})
328285
})
329286

@@ -341,9 +298,7 @@ describe('doesEntryMatchDefinition', () => {
341298
span: mockPerformanceEntry,
342299
annotation: mockAnnotation,
343300
}
344-
expect(
345-
doesEntryMatchDefinition(mockSpanAndAnnotation, matcher, mockScope),
346-
).toBe(true)
301+
expect(matcher(mockSpanAndAnnotation, mockScope)).toBe(true)
347302
})
348303

349304
it('should return false when all conditions match but name', () => {
@@ -359,9 +314,7 @@ describe('doesEntryMatchDefinition', () => {
359314
span: mockPerformanceEntry,
360315
annotation: mockAnnotation,
361316
}
362-
expect(
363-
doesEntryMatchDefinition(mockSpanAndAnnotation, matcher, mockScope),
364-
).toBe(false)
317+
expect(matcher(mockSpanAndAnnotation, mockScope)).toBe(false)
365318
})
366319
})
367320
})

0 commit comments

Comments
 (0)