UNPKG

@zendesk/react-measure-timing-hooks

Version:

react hooks for measuring time to interactive and time to render of components

444 lines 17 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); const vitest_1 = require("vitest"); const hooks_1 = require("./hooks"); const match = __importStar(require("./matchSpan")); const TraceManager_1 = require("./TraceManager"); const mockSpanWithoutRelation = { name: 'some-span', duration: 0, type: 'mark', attributes: {}, startTime: { now: 0, epoch: 0 }, }; (0, vitest_1.describe)('type tests', () => { const traceManager = new TraceManager_1.TraceManager({ relationSchemas: { global: {}, ticket: { ticketId: String }, user: { userId: String }, tickedField: { ticketId: String, customFieldId: String }, custom: { customId: String, customOtherId: String }, ticketEvent: { ticketId: String, eventId: String }, }, generateId: () => 'id', reportFn: (trace) => { if (!trace.relatedTo) return; if ('ticketId' in trace.relatedTo) { // valid (0, vitest_1.expect)(trace.relatedTo.ticketId).toBeDefined(); // @ts-expect-error invalid relatedTo (0, vitest_1.expect)(trace.relatedTo.userId).toBeDefined(); } if ('eventId' in trace.relatedTo) { // valid (0, vitest_1.expect)(trace.relatedTo.eventId).toBeDefined(); (0, vitest_1.expect)(trace.relatedTo.ticketId).toBeDefined(); // @ts-expect-error invalid relatedTo (0, vitest_1.expect)(trace.relatedTo.userId).toBeDefined(); } if ('userId' in trace.relatedTo) { // valid (0, vitest_1.expect)(trace.relatedTo.userId).toBeDefined(); // @ts-expect-error invalid relatedTo (0, vitest_1.expect)(trace.relatedTo.ticketId).toBeDefined(); } // valid if ('customFieldId' in trace.relatedTo) { (0, vitest_1.expect)(trace.relatedTo.customFieldId).toBeDefined(); } }, reportErrorFn: (error) => { console.error(error); }, }); const useBeacon = (0, hooks_1.generateUseBeacon)(traceManager); const useBeaconWithRequiredAttributes = (0, hooks_1.generateUseBeacon)(traceManager); (0, vitest_1.it)('works', () => { // invalid: const invalidTraceManager = new TraceManager_1.TraceManager({ generateId: () => 'id', reportFn: () => { }, reportErrorFn: () => { }, relationSchemas: { // @ts-expect-error because in the matcher functions, we cannot compare objects (due to object equality comparison) something: { blah: { test: String } }, }, }); // valid beacon useBeacon({ name: 'OmniLog', renderedOutput: 'content', relatedTo: { ticketId: '123', customFieldId: '123' }, }); // valid beacon useBeacon({ name: 'UserPage', renderedOutput: 'content', relatedTo: { userId: '123' }, }); // invalid useBeacon({ name: 'UserPage', renderedOutput: 'content', // @ts-expect-error invalid relatedTo relatedTo: { invalid: '123' }, }); // valid beacon useBeacon({ name: 'OmniLog', renderedOutput: 'content', // @ts-expect-error invalid: missing ticketId relatedTo: { customFieldId: '123' }, }); // valid beacon with only required attributes useBeaconWithRequiredAttributes({ name: 'UserPage', renderedOutput: 'content', relatedTo: { userId: '123' }, attributes: { team: 'test' }, }); // valid beacon required attributes and additional attributes useBeaconWithRequiredAttributes({ name: 'UserPage', renderedOutput: 'content', relatedTo: { userId: '123' }, attributes: { randoKey: 'test', team: 'test' }, }); // invalid beacon missing required attributes useBeaconWithRequiredAttributes({ name: 'UserPage', renderedOutput: 'content', relatedTo: { userId: '123' }, // @ts-expect-error attributes require a team key attributes: { randoKey: 'test' }, }); // valid definition const ticketActivationTracer = traceManager.createTracer({ name: 'ticket.activated', relationSchemaName: 'ticket', variants: { origin: { timeout: 5_000 }, another_origin: { timeout: 10_000 }, }, requiredSpans: [{ matchingRelations: ['ticketId'] }], }); const ticketActivationTracer2 = traceManager.createTracer({ name: 'ticket.activated', relationSchemaName: 'custom', variants: { origin: { timeout: 5_000 }, }, requiredSpans: [ match.withAllConditions(match.withName((name, relations) => name === `${relations?.customId}.end`), match.withName('end'), match.withMatchingRelations(['customId'])), match.withName((name, relatedTo) => name === `${relatedTo?.customId}.end`), match.withName('customFieldId'), match.withMatchingRelations(['customId']), // @ts-expect-error invalid relatedTo match.withMatchingRelations(['typoId']), ], }); // valid definition const userPageTracer = traceManager.createTracer({ name: 'user.activation', relationSchemaName: 'user', variants: { origin: { timeout: 5_000 }, }, requiredSpans: [{ matchingRelations: ['userId'] }], }); // valid definition const customFieldDropdownTracer = traceManager.createTracer({ name: 'ticket.custom_field', relationSchemaName: 'tickedField', variants: { origin: { timeout: 5_000 }, }, requiredSpans: [{ matchingRelations: ['ticketId'] }], }); // invalid definition. relatedTo match but not included in AllPossibleScopes const invalidTracer = traceManager.createTracer({ name: 'ticket.activated', variants: { origin: { timeout: 5_000 }, }, // @ts-expect-error invalid relatedTo relationSchemaName: ['invalid'], requiredSpans: [ { // @ts-expect-error invalid relatedTo matchingRelations: ['invalid'], }, ], }); // invalid definition. userId given in requiredSpans isn't one of the relatedTo the tracer says it can have const shouldErrorTrace = traceManager.createTracer({ name: 'ticket.should_error', relationSchemaName: 'tickedField', variants: { origin: { timeout: 5_000 }, }, requiredSpans: [ { // @ts-expect-error invalid relatedTo matchingRelations: ['userId'], }, ], }); // valid definition const ticketActivationWithFnTracer = traceManager.createTracer({ name: 'ticket.activated', relationSchemaName: 'ticket', variants: { origin: { timeout: 5_000 }, }, requiredSpans: [ { matchingRelations: ['ticketId'] }, ({ span }) => span.relatedTo?.ticketId === '123', ], }); // valid start ticketActivationTracer.start({ relatedTo: { ticketId: '123' }, variant: 'origin', }); // valid start ticketActivationTracer.start({ relatedTo: { ticketId: '999' }, variant: 'another_origin', }); // invalid start - wrong variant ticketActivationTracer.start({ relatedTo: { ticketId: '123' }, // @ts-expect-error invalid variant variant: 'origin_wrong', }); // invalid start (errors) ticketActivationTracer.start({ // @ts-expect-error invalid relatedTo relatedTo: { whatever: '123' }, }); // invalid start (errors) ticketActivationTracer.start({ // @ts-expect-error invalid relatedTo relatedTo: { userId: '123' }, variant: 'origin', }); // valid - excess relatedTo traceManager.processSpan({ ...mockSpanWithoutRelation, relatedTo: { ticketId: '123', customFieldId: '123', userId: '123' }, }); // valid traceManager.processSpan({ ...mockSpanWithoutRelation, relatedTo: { ticketId: '123' }, }); // valid - multiple relatedTo simultaneously traceManager.processSpan({ ...mockSpanWithoutRelation, relatedTo: { ticketId: '123', customFieldId: '123', }, }); // invalid traceManager.processSpan({ ...mockSpanWithoutRelation, relatedTo: { // @ts-expect-error bad relatedTo bad: '123', }, }); // invalid traceManager.processSpan({ ...mockSpanWithoutRelation, relatedTo: { // @ts-expect-error bad relatedTo ticketId: 123, }, }); ticketActivationTracer.addRequirementsToCurrentTraceOnly({ additionalRequiredSpans: [ { name: 'end', matchingRelations: ['ticketId'] }, ], }); }); (0, vitest_1.it)('does not allow to include invalid relatedTo value', () => { const tracer = traceManager.createTracer({ name: 'ticket.relatedTo-operation', type: 'operation', relationSchemaName: 'ticket', variants: { origin: { timeout: 5_000 }, }, requiredSpans: [{ name: 'end', matchingRelations: true }], }); const traceId = tracer.start({ relatedTo: { // @ts-expect-error number should not be assignable to string ticketId: 4, }, variant: 'origin', }); (0, vitest_1.assertType)(traceId); }); (0, vitest_1.it)('mixed relatedTo', () => { const tracer = traceManager.createTracer({ name: 'ticket.relatedTo-operation', type: 'operation', relationSchemaName: 'tickedField', requiredSpans: [{ name: 'end', matchingRelations: true }], variants: { default: { timeout: 5_000 } }, }); const traceId = tracer.start({ variant: 'default', relatedTo: { customFieldId: '3', ticketId: '4', }, }); }); (0, vitest_1.it)('redaction example', () => { const tracer = traceManager.createTracer({ name: 'ticket.event.redacted', type: 'operation', relationSchemaName: 'ticketEvent', variants: { origin: { timeout: 5_000 }, }, requiredSpans: [{ name: 'OmniLogEvent', matchingRelations: true }], debounceOnSpans: [{ name: 'OmniLog', matchingRelations: ['ticketId'] }], }); const traceId = tracer.start({ relatedTo: { ticketId: '4', eventId: '3', }, variant: 'origin', }); (0, vitest_1.assertType)(traceId); }); (0, vitest_1.it)('redaction invalid example', () => { const tracer = traceManager.createTracer({ name: 'ticket.event.redacted', type: 'operation', // @ts-expect-error enforce a complete set of keys of a given relatedTo relationSchemaName: ['eventId'], timeout: 5_000, requiredSpans: [{ name: 'OmniLogEvent', matchingRelations: true }], }); const correctTracer = traceManager.createTracer({ name: 'ticket.event.redacted', type: 'operation', relationSchemaName: 'ticketEvent', variants: { origin: { timeout: 5_000 }, }, requiredSpans: [{ name: 'OmniLogEvent', matchingRelations: true }], }); const traceId = correctTracer.start({ relatedTo: { ticketId: '4', // @ts-expect-error trying to start trace with invalid relatedTo combination customFieldId: 'werwer', }, variant: 'origin', }); }); (0, vitest_1.it)('does not allow to include invalid relatedTo key', () => { const tracer = traceManager.createTracer({ name: 'ticket.relatedTo-operation', type: 'operation', relationSchemaName: 'ticket', variants: { origin: { timeout: 5_000 }, }, requiredSpans: [{ name: 'end', matchingRelations: true }], }); const traceId = tracer.start({ variant: 'origin', relatedTo: { // @ts-expect-error invalid relatedTo key userId: '3', }, }); (0, vitest_1.assertType)(traceId); }); (0, vitest_1.it)('maps schema to types', () => { const testSchema = { a: String, b: Number, c: Boolean, d: ['union', 'of', 'things', 2], }; (0, vitest_1.assertType)({}); }); (0, vitest_1.it)('maps computedValueDefinitions', () => { const tracer = traceManager.createTracer({ name: 'ticket.multiple-computed-values', type: 'operation', relationSchemaName: 'global', requiredSpans: [{ name: 'end' }], variants: { cold_boot: { timeout: 10_000 }, }, computedValueDefinitions: { 'valid-feature-count': { matches: [{ name: 'feature' }, { name: 'feature-2' }], computeValueFromMatches: (feature, feature2) => feature.length + feature2.length, }, 'invalid-feature-count': { matches: [{ name: 'feature' }, { name: 'feature-2' }], // @ts-expect-error invalid number of arguments computeValueFromMatches: (feature, feature2, invalid) => 0, }, 'error-count': { matches: [{ name: (name) => name.startsWith('error') }], computeValueFromMatches: (errors) => errors.length, }, another: { matches: [(name) => name.span.name.startsWith('error')], computeValueFromMatches: (errors) => errors.length, }, // TODO: adding a function breaks the type for some odd reason // https://github.com/microsoft/TypeScript/issues/61228 }, }); }); }); //# sourceMappingURL=types.test-d.js.map