@zendesk/react-measure-timing-hooks
Version:
react hooks for measuring time to interactive and time to render of components
148 lines • 6.59 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.Tracer = void 0;
const ensureMatcherFn_1 = require("./ensureMatcherFn");
const ensureTimestamp_1 = require("./ensureTimestamp");
const Trace_1 = require("./Trace");
/**
* Tracer can create draft traces and start traces
*/
class Tracer {
definition;
traceUtilities;
constructor(definition, traceUtilities) {
this.definition = definition;
this.traceUtilities = traceUtilities;
}
/**
* @returns The ID of the trace.
*/
start = (input, definitionModifications) => {
const traceId = this.createDraft(input);
if (!traceId)
return undefined;
this.transitionDraftToActive({
relatedTo: input.relatedTo,
...definitionModifications,
});
return traceId;
};
createDraft = (input, definitionModifications) => {
const id = input.id ?? this.traceUtilities.generateId();
const trace = new Trace_1.Trace({
definition: this.definition,
input: {
...input,
// relatedTo will be overwritten later during initialization of the trace
relatedTo: undefined,
startTime: (0, ensureTimestamp_1.ensureTimestamp)(input.startTime),
id,
},
definitionModifications,
traceUtilities: this.traceUtilities,
});
this.traceUtilities.replaceCurrentTrace(trace, 'another-trace-started');
return id;
};
interrupt = ({ error } = {}) => {
const trace = this.traceUtilities.getCurrentTrace();
if (!trace) {
this.traceUtilities.reportWarningFn(new Error(`No currently active trace when canceling a draft. Call tracer.start(...) or tracer.createDraft(...) beforehand.`));
return;
}
// verify that trace is the same definition as the Tracer's definition
if (trace.sourceDefinition !== this.definition) {
this.traceUtilities.reportWarningFn(new Error(`You are trying to cancel a draft that is not the same definition as the Tracer's definition.`));
return;
}
if (error) {
trace.processSpan({
name: error.name,
startTime: (0, ensureTimestamp_1.ensureTimestamp)(),
// TODO: use a dedicated error type
type: 'mark',
attributes: {},
duration: 0,
error,
});
trace.interrupt('aborted');
return;
}
if (trace.isDraft) {
trace.interrupt('draft-cancelled');
return;
}
trace.interrupt('aborted');
};
/**
* Adds additional required spans or debounce spans to the current trace *only*.
* Note: This recreates the Trace instance with the modified definition and replays all the spans.
*/
addRequirementsToCurrentTraceOnly = (definitionModifications) => {
const trace = this.traceUtilities.getCurrentTrace();
if (!trace) {
this.traceUtilities.reportWarningFn(new Error(`No currently active trace when adding required spans. Call tracer.start(...) or tracer.createDraft(...) beforehand.`));
return;
}
// verify that trace is the same definition as the Tracer's definition
if (trace.sourceDefinition !== this.definition) {
this.traceUtilities.reportWarningFn(new Error(`You are trying to add required spans to a trace that is not the same definition as the Tracer's definition.`));
return;
}
// Create a new trace with the updated definition, importing state from the existing trace
const newTrace = new Trace_1.Trace({
importFrom: trace,
definitionModifications,
});
// Replace the current trace with the new one
this.traceUtilities.replaceCurrentTrace(newTrace, 'definition-changed');
};
// can have config changed until we move into active
// from input: relatedTo (required), attributes (optional, merge into)
// from definition, can add items to: requiredSpans (additionalRequiredSpans), debounceOnSpans (additionalDebounceOnSpans)
// documentation: interruption still works and all the other events are buffered
transitionDraftToActive = (inputAndDefinitionModifications) => {
const trace = this.traceUtilities.getCurrentTrace();
if (!trace) {
this.traceUtilities.reportErrorFn(new Error(`No currently active trace when initializing a trace. Call tracer.start(...) or tracer.createDraft(...) beforehand.`));
return;
}
// this is an already initialized active trace, do nothing:
if (!trace.isDraft) {
this.traceUtilities.reportWarningFn(new Error(`You are trying to initialize a trace that has already been initialized before (${trace.definition.name}).`));
return;
}
// verify that trace is the same definition as the Tracer's definition
if (trace.sourceDefinition !== this.definition) {
this.traceUtilities.reportWarningFn(new Error(`You are trying to initialize a trace that is not the same definition as the Tracer's definition is different.`));
return;
}
trace.transitionDraftToActive(inputAndDefinitionModifications);
};
getCurrentTrace = () => {
const trace = this.traceUtilities.getCurrentTrace();
if (!trace || trace.sourceDefinition !== this.definition) {
return undefined;
}
return trace;
};
defineComputedSpan = (definition) => {
this.definition.computedSpanDefinitions[definition.name] = {
startSpan: typeof definition.startSpan === 'string'
? definition.startSpan
: (0, ensureMatcherFn_1.ensureMatcherFn)(definition.startSpan),
endSpan: typeof definition.endSpan === 'string'
? definition.endSpan
: (0, ensureMatcherFn_1.ensureMatcherFn)(definition.endSpan),
};
};
defineComputedValue = (definition) => {
const convertedMatches = definition.matches.map((m) => (0, ensureMatcherFn_1.ensureMatcherFn)(m));
this.definition.computedValueDefinitions[definition.name] = {
matches: convertedMatches,
computeValueFromMatches: definition.computeValueFromMatches,
};
};
}
exports.Tracer = Tracer;
//# sourceMappingURL=Tracer.js.map
;