From 30679250a3c68fe5cd34bb8b1a48681a62e1e308 Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Wed, 8 Mar 2023 16:10:42 +0100 Subject: [PATCH 01/11] add hooks types and base implementation --- packages/core/src/baseclient.ts | 29 +++++++++++++++++++++++++++++ packages/types/src/client.ts | 25 +++++++++++++++++++++++++ packages/types/src/hooks.ts | 19 +++++++++++++++++++ packages/types/src/index.ts | 1 + 4 files changed, 74 insertions(+) create mode 100644 packages/types/src/hooks.ts diff --git a/packages/core/src/baseclient.ts b/packages/core/src/baseclient.ts index b551cfafb8e8..d1534940ae5a 100644 --- a/packages/core/src/baseclient.ts +++ b/packages/core/src/baseclient.ts @@ -9,6 +9,9 @@ import type { Event, EventDropReason, EventHint, + HookCallback, + HookName, + HookStore, Integration, IntegrationClass, Outcome, @@ -97,6 +100,8 @@ export abstract class BaseClient implements Client { /** Holds flushable */ private _outcomes: { [key: string]: number } = {}; + private _hooks: HookStore = {}; + /** * Initializes this client instance. * @@ -351,6 +356,30 @@ export abstract class BaseClient implements Client { } } + /** + * @inheritDoc + */ + public on(hook: HookName, callback: HookCallback): void { + if (this._hooks[hook]) { + // @ts-ignore we cannot enforce the callback to match the hook + // while saving bundle size + this._hooks[hook].push(callback); + } else { + this._hooks[hook] = []; + } + } + + /** + * @inheritDoc + */ + public emit(hook: HookName, ...args: Parameters): void { + if (this._hooks[hook]) { + // @ts-ignore we cannot enforce the callback to match the hook + // while saving bundle size + this._hooks[hook].forEach((callback: HookCallback) => callback(...args)); + } + } + /** Updates existing session based on the provided event */ protected _updateSessionFromEvent(session: Session, event: Event): void { let crashed = false; diff --git a/packages/types/src/client.ts b/packages/types/src/client.ts index 28d23025ce84..c68d8417c611 100644 --- a/packages/types/src/client.ts +++ b/packages/types/src/client.ts @@ -2,6 +2,7 @@ import type { EventDropReason } from './clientreport'; import type { DataCategory } from './datacategory'; import type { DsnComponents } from './dsn'; import type { Event, EventHint } from './event'; +import type { EnvelopeHookCallback, EnvelopeHookName, TransactionHookCallback, TransactionHookName } from './hooks'; import type { Integration, IntegrationClass } from './integration'; import type { ClientOptions } from './options'; import type { Scope } from './scope'; @@ -147,4 +148,28 @@ export interface Client { * @param event The dropped event. */ recordDroppedEvent(reason: EventDropReason, dataCategory: DataCategory, event?: Event): void; + + // HOOKS + + /** + * Register a callback for transaction start and finish. + */ + on(hook: TransactionHookName, callback: TransactionHookCallback): void; + + /** + * Register a callback for envelope creation and sending. + */ + on(hook: EnvelopeHookName, callback: EnvelopeHookCallback): void; + + /** + * Fire a hook event for transaction start and finish. Expects to be given a transaction as the + * second argument. + */ + emit(hook: TransactionHookName, ...params: Parameters): void; + + /* + * Fire a hook event for envelope creation and sending. Expects to be given an envelope as the + * second argument. + */ + emit(hook: EnvelopeHookName, ...params: Parameters): void; } diff --git a/packages/types/src/hooks.ts b/packages/types/src/hooks.ts new file mode 100644 index 000000000000..e478d9cc9b49 --- /dev/null +++ b/packages/types/src/hooks.ts @@ -0,0 +1,19 @@ +import type { Envelope } from './envelope'; +import type { Transaction } from './transaction'; + +export type TransactionHookName = 'startTransaction' | 'transactionFinish'; +export type TransactionHookCallback = (transaction: Transaction) => void; + +export type EnvelopeHookName = 'beforeEnvelope'; +export type EnvelopeHookCallback = (envelope: Envelope) => void; + +export type HookName = TransactionHookName | EnvelopeHookName; +export type HookCallback = TransactionHookCallback | EnvelopeHookCallback; + +export type HookStoreItem = Partial<{ [key in N]: C[] }>; + +export type HookStore = + // Hooks related to transaction start/finish + HookStoreItem & + // Hooks related to envelope create and send + HookStoreItem; diff --git a/packages/types/src/index.ts b/packages/types/src/index.ts index 7f7ed86cfc9a..db9bf0adef78 100644 --- a/packages/types/src/index.ts +++ b/packages/types/src/index.ts @@ -96,3 +96,4 @@ export type { WrappedFunction } from './wrappedfunction'; export type { Instrumenter } from './instrumenter'; export type { BrowserClientReplayOptions } from './browseroptions'; +export type { HookStore, HookName, HookCallback } from './hooks'; From 712feb2ee6e93cdd755f285cec5bb7cdb6713159 Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Wed, 8 Mar 2023 16:22:58 +0100 Subject: [PATCH 02/11] add tests --- packages/core/src/baseclient.ts | 10 +++++----- packages/core/test/lib/base.test.ts | 21 ++++++++++++++++++++- 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/packages/core/src/baseclient.ts b/packages/core/src/baseclient.ts index d1534940ae5a..186f453dd963 100644 --- a/packages/core/src/baseclient.ts +++ b/packages/core/src/baseclient.ts @@ -360,13 +360,13 @@ export abstract class BaseClient implements Client { * @inheritDoc */ public on(hook: HookName, callback: HookCallback): void { - if (this._hooks[hook]) { - // @ts-ignore we cannot enforce the callback to match the hook - // while saving bundle size - this._hooks[hook].push(callback); - } else { + if (!this._hooks[hook]) { this._hooks[hook] = []; } + + // @ts-ignore we cannot enforce the callback to match the hook + // while saving bundle size + this._hooks[hook].push(callback); } /** diff --git a/packages/core/test/lib/base.test.ts b/packages/core/test/lib/base.test.ts index d7382ceeeacb..b857f913d51b 100644 --- a/packages/core/test/lib/base.test.ts +++ b/packages/core/test/lib/base.test.ts @@ -1,4 +1,4 @@ -import type { Event, Span } from '@sentry/types'; +import type { Event, Span, Transaction } from '@sentry/types'; import { dsnToString, logger, SentryError, SyncPromise } from '@sentry/utils'; import { Hub, makeSession, Scope } from '../../src'; @@ -1730,4 +1730,23 @@ describe('BaseClient', () => { expect(clearedOutcomes4.length).toEqual(0); }); }); + + describe('hooks', () => { + it('should call a startTransaction hook', () => { + expect.assertions(1); + + const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN }); + const client = new TestClient(options); + + let mockTransaction = { + traceId: '86f39e84263a4de99c326acab3bfe3bd', + } as Transaction; + + client.on('startTransaction', (transaction: Transaction) => { + expect(transaction).toEqual(mockTransaction); + }); + + client.emit('startTransaction', mockTransaction); + }); + }); }); From 2350bdb3cbd933090878ce363a9be905dceef7d8 Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Wed, 8 Mar 2023 16:30:42 +0100 Subject: [PATCH 03/11] make hook methods optional --- packages/core/test/lib/base.test.ts | 4 ++-- packages/types/src/client.ts | 9 +++++---- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/packages/core/test/lib/base.test.ts b/packages/core/test/lib/base.test.ts index b857f913d51b..d50c6d02eaf2 100644 --- a/packages/core/test/lib/base.test.ts +++ b/packages/core/test/lib/base.test.ts @@ -1742,11 +1742,11 @@ describe('BaseClient', () => { traceId: '86f39e84263a4de99c326acab3bfe3bd', } as Transaction; - client.on('startTransaction', (transaction: Transaction) => { + client?.on('startTransaction', (transaction: Transaction) => { expect(transaction).toEqual(mockTransaction); }); - client.emit('startTransaction', mockTransaction); + client?.emit('startTransaction', mockTransaction); }); }); }); diff --git a/packages/types/src/client.ts b/packages/types/src/client.ts index c68d8417c611..fd0b58d89f3e 100644 --- a/packages/types/src/client.ts +++ b/packages/types/src/client.ts @@ -150,26 +150,27 @@ export interface Client { recordDroppedEvent(reason: EventDropReason, dataCategory: DataCategory, event?: Event): void; // HOOKS + // TODO(v8): Make the hooks non-optional. /** * Register a callback for transaction start and finish. */ - on(hook: TransactionHookName, callback: TransactionHookCallback): void; + on?(hook: TransactionHookName, callback: TransactionHookCallback): void; /** * Register a callback for envelope creation and sending. */ - on(hook: EnvelopeHookName, callback: EnvelopeHookCallback): void; + on?(hook: EnvelopeHookName, callback: EnvelopeHookCallback): void; /** * Fire a hook event for transaction start and finish. Expects to be given a transaction as the * second argument. */ - emit(hook: TransactionHookName, ...params: Parameters): void; + emit?(hook: TransactionHookName, ...params: Parameters): void; /* * Fire a hook event for envelope creation and sending. Expects to be given an envelope as the * second argument. */ - emit(hook: EnvelopeHookName, ...params: Parameters): void; + emit?(hook: EnvelopeHookName, ...params: Parameters): void; } From 0e337f65198839dcd4a8a00b234b0b98dd86c32f Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Wed, 8 Mar 2023 16:42:33 +0100 Subject: [PATCH 04/11] fix lint --- packages/core/test/lib/base.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/test/lib/base.test.ts b/packages/core/test/lib/base.test.ts index d50c6d02eaf2..6dec03e1b918 100644 --- a/packages/core/test/lib/base.test.ts +++ b/packages/core/test/lib/base.test.ts @@ -1738,7 +1738,7 @@ describe('BaseClient', () => { const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN }); const client = new TestClient(options); - let mockTransaction = { + const mockTransaction = { traceId: '86f39e84263a4de99c326acab3bfe3bd', } as Transaction; From 79e1f592bf60d3a2b5ed5b058ccf0155d41cff2b Mon Sep 17 00:00:00 2001 From: Francesco Novy Date: Wed, 8 Mar 2023 17:14:31 +0100 Subject: [PATCH 05/11] ref: Make baseclient hooks typesafe when using generics --- packages/core/src/baseclient.ts | 16 ++++++---------- packages/types/src/client.ts | 10 +++++----- packages/types/src/hooks.ts | 25 +++++++++++++------------ packages/types/src/index.ts | 2 +- 4 files changed, 25 insertions(+), 28 deletions(-) diff --git a/packages/core/src/baseclient.ts b/packages/core/src/baseclient.ts index 186f453dd963..b0c638d9ea32 100644 --- a/packages/core/src/baseclient.ts +++ b/packages/core/src/baseclient.ts @@ -9,8 +9,7 @@ import type { Event, EventDropReason, EventHint, - HookCallback, - HookName, + Hook, HookStore, Integration, IntegrationClass, @@ -359,24 +358,21 @@ export abstract class BaseClient implements Client { /** * @inheritDoc */ - public on(hook: HookName, callback: HookCallback): void { + public on(hook: HookType['name'], callback: HookType['callback']): void { if (!this._hooks[hook]) { this._hooks[hook] = []; } - // @ts-ignore we cannot enforce the callback to match the hook - // while saving bundle size - this._hooks[hook].push(callback); + (this._hooks[hook] as HookType['callback'][]).push(callback); } /** * @inheritDoc */ - public emit(hook: HookName, ...args: Parameters): void { + public emit(hook: HookType['name'], ...args: Parameters): void { if (this._hooks[hook]) { - // @ts-ignore we cannot enforce the callback to match the hook - // while saving bundle size - this._hooks[hook].forEach((callback: HookCallback) => callback(...args)); + // @ts-ignore it does not like ...args, but we know this is correct + (this._hooks[hook] as HookType['callback'][]).forEach(callback => callback(...args)); } } diff --git a/packages/types/src/client.ts b/packages/types/src/client.ts index fd0b58d89f3e..1d5eff7584e6 100644 --- a/packages/types/src/client.ts +++ b/packages/types/src/client.ts @@ -2,7 +2,7 @@ import type { EventDropReason } from './clientreport'; import type { DataCategory } from './datacategory'; import type { DsnComponents } from './dsn'; import type { Event, EventHint } from './event'; -import type { EnvelopeHookCallback, EnvelopeHookName, TransactionHookCallback, TransactionHookName } from './hooks'; +import type { EnvelopeHook, TransactionHook } from './hooks'; import type { Integration, IntegrationClass } from './integration'; import type { ClientOptions } from './options'; import type { Scope } from './scope'; @@ -155,22 +155,22 @@ export interface Client { /** * Register a callback for transaction start and finish. */ - on?(hook: TransactionHookName, callback: TransactionHookCallback): void; + on?(hook: TransactionHook['name'], callback: TransactionHook['callback']): void; /** * Register a callback for envelope creation and sending. */ - on?(hook: EnvelopeHookName, callback: EnvelopeHookCallback): void; + on?(hook: EnvelopeHook['name'], callback: EnvelopeHook['callback']): void; /** * Fire a hook event for transaction start and finish. Expects to be given a transaction as the * second argument. */ - emit?(hook: TransactionHookName, ...params: Parameters): void; + emit?(hook: TransactionHook['name'], ...params: Parameters): void; /* * Fire a hook event for envelope creation and sending. Expects to be given an envelope as the * second argument. */ - emit?(hook: EnvelopeHookName, ...params: Parameters): void; + emit?(hook: EnvelopeHook['name'], ...params: Parameters): void; } diff --git a/packages/types/src/hooks.ts b/packages/types/src/hooks.ts index e478d9cc9b49..6f4988d92811 100644 --- a/packages/types/src/hooks.ts +++ b/packages/types/src/hooks.ts @@ -1,19 +1,20 @@ import type { Envelope } from './envelope'; import type { Transaction } from './transaction'; -export type TransactionHookName = 'startTransaction' | 'transactionFinish'; -export type TransactionHookCallback = (transaction: Transaction) => void; +// Hooks related to transaction start/finish +export type TransactionHook = { + name: 'startTransaction' | 'transactionFinish'; + callback: (transaction: Transaction) => void; +}; -export type EnvelopeHookName = 'beforeEnvelope'; -export type EnvelopeHookCallback = (envelope: Envelope) => void; +// Hooks related to envelope create and send +export type EnvelopeHook = { + name: 'beforeEnvelope'; + callback: (envelope: Envelope) => void; +}; -export type HookName = TransactionHookName | EnvelopeHookName; -export type HookCallback = TransactionHookCallback | EnvelopeHookCallback; +export type Hook = TransactionHook | EnvelopeHook; -export type HookStoreItem = Partial<{ [key in N]: C[] }>; +export type HookStoreItem = Partial>; -export type HookStore = - // Hooks related to transaction start/finish - HookStoreItem & - // Hooks related to envelope create and send - HookStoreItem; +export type HookStore = HookStoreItem & HookStoreItem; diff --git a/packages/types/src/index.ts b/packages/types/src/index.ts index db9bf0adef78..961d910adf47 100644 --- a/packages/types/src/index.ts +++ b/packages/types/src/index.ts @@ -96,4 +96,4 @@ export type { WrappedFunction } from './wrappedfunction'; export type { Instrumenter } from './instrumenter'; export type { BrowserClientReplayOptions } from './browseroptions'; -export type { HookStore, HookName, HookCallback } from './hooks'; +export type { HookStore, Hook, TransactionHook, EnvelopeHook } from './hooks'; From 99f67e23b2bdc0a806838aa3a5c633ef7947211b Mon Sep 17 00:00:00 2001 From: Francesco Novy Date: Wed, 8 Mar 2023 17:17:26 +0100 Subject: [PATCH 06/11] use generic for hook --- packages/core/test/lib/base.test.ts | 26 +++++++++++++++++++++++--- packages/types/src/client.ts | 17 +++-------------- 2 files changed, 26 insertions(+), 17 deletions(-) diff --git a/packages/core/test/lib/base.test.ts b/packages/core/test/lib/base.test.ts index 6dec03e1b918..85f12e3f3353 100644 --- a/packages/core/test/lib/base.test.ts +++ b/packages/core/test/lib/base.test.ts @@ -1,4 +1,4 @@ -import type { Event, Span, Transaction } from '@sentry/types'; +import { Event, Span, Transaction, TransactionHook, EnvelopeHook, Envelope } from '@sentry/types'; import { dsnToString, logger, SentryError, SyncPromise } from '@sentry/utils'; import { Hub, makeSession, Scope } from '../../src'; @@ -1742,11 +1742,31 @@ describe('BaseClient', () => { traceId: '86f39e84263a4de99c326acab3bfe3bd', } as Transaction; - client?.on('startTransaction', (transaction: Transaction) => { + client?.on('startTransaction', (transaction: Transaction) => { expect(transaction).toEqual(mockTransaction); }); - client?.emit('startTransaction', mockTransaction); + client?.emit('startTransaction', mockTransaction); + }); + + it('should call a beforeEnvelope hook', () => { + expect.assertions(1); + + const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN }); + const client = new TestClient(options); + + const mockEnvelope = [ + { + event_id: '12345', + }, + {}, + ] as Envelope; + + client?.on('beforeEnvelope', (envelope: Envelope) => { + expect(envelope).toEqual(mockEnvelope); + }); + + client?.emit('beforeEnvelope', mockEnvelope); }); }); }); diff --git a/packages/types/src/client.ts b/packages/types/src/client.ts index 1d5eff7584e6..4481b7ddfea5 100644 --- a/packages/types/src/client.ts +++ b/packages/types/src/client.ts @@ -2,7 +2,7 @@ import type { EventDropReason } from './clientreport'; import type { DataCategory } from './datacategory'; import type { DsnComponents } from './dsn'; import type { Event, EventHint } from './event'; -import type { EnvelopeHook, TransactionHook } from './hooks'; +import type { Hook } from './hooks'; import type { Integration, IntegrationClass } from './integration'; import type { ClientOptions } from './options'; import type { Scope } from './scope'; @@ -155,22 +155,11 @@ export interface Client { /** * Register a callback for transaction start and finish. */ - on?(hook: TransactionHook['name'], callback: TransactionHook['callback']): void; - - /** - * Register a callback for envelope creation and sending. - */ - on?(hook: EnvelopeHook['name'], callback: EnvelopeHook['callback']): void; - - /** - * Fire a hook event for transaction start and finish. Expects to be given a transaction as the - * second argument. - */ - emit?(hook: TransactionHook['name'], ...params: Parameters): void; + on?(hook: HookType['name'], callback: HookType['callback']): void; /* * Fire a hook event for envelope creation and sending. Expects to be given an envelope as the * second argument. */ - emit?(hook: EnvelopeHook['name'], ...params: Parameters): void; + emit?(hook: HookType['name'], ...args: Parameters): void; } From 729dedb98dda8f8e66ae1c04eb6d1960e5ce6690 Mon Sep 17 00:00:00 2001 From: Francesco Novy Date: Wed, 8 Mar 2023 17:28:21 +0100 Subject: [PATCH 07/11] un-export HookStoreItem --- packages/types/src/hooks.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/types/src/hooks.ts b/packages/types/src/hooks.ts index 6f4988d92811..f3e4ca389bed 100644 --- a/packages/types/src/hooks.ts +++ b/packages/types/src/hooks.ts @@ -15,6 +15,6 @@ export type EnvelopeHook = { export type Hook = TransactionHook | EnvelopeHook; -export type HookStoreItem = Partial>; +type HookStoreItem = Partial>; export type HookStore = HookStoreItem & HookStoreItem; From 52cd479264c91e02552c5b3b40fecfac2c0eeff3 Mon Sep 17 00:00:00 2001 From: Francesco Novy Date: Wed, 8 Mar 2023 18:16:45 +0100 Subject: [PATCH 08/11] ref: Make types explicit --- packages/core/src/baseclient.ts | 39 ++++++++++++------- packages/core/test/lib/base.test.ts | 58 +++++++++++++++-------------- packages/types/src/client.ts | 18 +++++++-- packages/types/src/hooks.ts | 20 ---------- packages/types/src/index.ts | 1 - 5 files changed, 71 insertions(+), 65 deletions(-) delete mode 100644 packages/types/src/hooks.ts diff --git a/packages/core/src/baseclient.ts b/packages/core/src/baseclient.ts index b0c638d9ea32..bf1ae616c4d6 100644 --- a/packages/core/src/baseclient.ts +++ b/packages/core/src/baseclient.ts @@ -9,8 +9,6 @@ import type { Event, EventDropReason, EventHint, - Hook, - HookStore, Integration, IntegrationClass, Outcome, @@ -19,6 +17,7 @@ import type { SessionAggregates, Severity, SeverityLevel, + Transaction, TransactionEvent, Transport, } from '@sentry/types'; @@ -99,7 +98,8 @@ export abstract class BaseClient implements Client { /** Holds flushable */ private _outcomes: { [key: string]: number } = {}; - private _hooks: HookStore = {}; + // eslint-disable-next-line @typescript-eslint/ban-types + private _hooks: Record = {}; /** * Initializes this client instance. @@ -355,24 +355,35 @@ export abstract class BaseClient implements Client { } } - /** - * @inheritDoc - */ - public on(hook: HookType['name'], callback: HookType['callback']): void { + // Keep on() & emit() signatures in sync with types' client.ts interface + + /** @inheritdoc */ + public on(hook: 'startTransaction' | 'finishTransaction', callback: (transaction: Transaction) => void): void; + + /** @inheritdoc */ + public on(hook: 'beforeEnvelope', callback: (envelope: Envelope) => void): void; + + /** @inheritdoc */ + public on(hook: string, callback: unknown): void { if (!this._hooks[hook]) { this._hooks[hook] = []; } - (this._hooks[hook] as HookType['callback'][]).push(callback); + // @ts-ignore We assue the types are correct + this._hooks[hook].push(callback); } - /** - * @inheritDoc - */ - public emit(hook: HookType['name'], ...args: Parameters): void { + /** @inheritdoc */ + public emit(hook: 'startTransaction' | 'finishTransaction', transaction: Transaction): void; + + /** @inheritdoc */ + public emit(hook: 'beforeEnvelope', envelope: Envelope): void; + + /** @inheritdoc */ + public emit(hook: string, ...rest: unknown[]): void { if (this._hooks[hook]) { - // @ts-ignore it does not like ...args, but we know this is correct - (this._hooks[hook] as HookType['callback'][]).forEach(callback => callback(...args)); + // @ts-ignore we cannot enforce the callback to match the hook + this._hooks[hook].forEach(callback => callback(...rest)); } } diff --git a/packages/core/test/lib/base.test.ts b/packages/core/test/lib/base.test.ts index 85f12e3f3353..d09928566f40 100644 --- a/packages/core/test/lib/base.test.ts +++ b/packages/core/test/lib/base.test.ts @@ -1,4 +1,4 @@ -import { Event, Span, Transaction, TransactionHook, EnvelopeHook, Envelope } from '@sentry/types'; +import type { Envelope, Event, Span, Transaction, Client } from '@sentry/types'; import { dsnToString, logger, SentryError, SyncPromise } from '@sentry/utils'; import { Hub, makeSession, Scope } from '../../src'; @@ -1732,41 +1732,45 @@ describe('BaseClient', () => { }); describe('hooks', () => { - it('should call a startTransaction hook', () => { - expect.assertions(1); + const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN }); - const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN }); - const client = new TestClient(options); + // Make sure types work for both Client & BaseClient + const scenarios = [ + ['BaseClient', new TestClient(options)], + ['Client', new TestClient(options) as Client], + ] as const; - const mockTransaction = { - traceId: '86f39e84263a4de99c326acab3bfe3bd', - } as Transaction; + describe.each(scenarios)('with client %s', (_, client) => { + it('should call a startTransaction hook', () => { + expect.assertions(1); - client?.on('startTransaction', (transaction: Transaction) => { - expect(transaction).toEqual(mockTransaction); - }); + const mockTransaction = { + traceId: '86f39e84263a4de99c326acab3bfe3bd', + } as Transaction; - client?.emit('startTransaction', mockTransaction); - }); + client.on?.('startTransaction', transaction => { + expect(transaction).toEqual(mockTransaction); + }); - it('should call a beforeEnvelope hook', () => { - expect.assertions(1); + client.emit?.('startTransaction', mockTransaction); + }); - const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN }); - const client = new TestClient(options); + it('should call a beforeEnvelope hook', () => { + expect.assertions(1); - const mockEnvelope = [ - { - event_id: '12345', - }, - {}, - ] as Envelope; + const mockEnvelope = [ + { + event_id: '12345', + }, + {}, + ] as Envelope; - client?.on('beforeEnvelope', (envelope: Envelope) => { - expect(envelope).toEqual(mockEnvelope); - }); + client.on?.('beforeEnvelope', envelope => { + expect(envelope).toEqual(mockEnvelope); + }); - client?.emit('beforeEnvelope', mockEnvelope); + client.emit?.('beforeEnvelope', mockEnvelope); + }); }); }); }); diff --git a/packages/types/src/client.ts b/packages/types/src/client.ts index 4481b7ddfea5..3839f794b8e1 100644 --- a/packages/types/src/client.ts +++ b/packages/types/src/client.ts @@ -2,7 +2,6 @@ import type { EventDropReason } from './clientreport'; import type { DataCategory } from './datacategory'; import type { DsnComponents } from './dsn'; import type { Event, EventHint } from './event'; -import type { Hook } from './hooks'; import type { Integration, IntegrationClass } from './integration'; import type { ClientOptions } from './options'; import type { Scope } from './scope'; @@ -10,6 +9,8 @@ import type { SdkMetadata } from './sdkmetadata'; import type { Session, SessionAggregates } from './session'; import type { Severity, SeverityLevel } from './severity'; import type { Transport } from './transport'; +import { Transaction } from './transaction'; +import { Envelope } from './envelope'; /** * User-Facing Sentry SDK Client. @@ -155,11 +156,22 @@ export interface Client { /** * Register a callback for transaction start and finish. */ - on?(hook: HookType['name'], callback: HookType['callback']): void; + on?(hook: 'startTransaction' | 'finishTransaction', callback: (transaction: Transaction) => void): void; + + /** + * Register a callback for transaction start and finish. + */ + on?(hook: 'beforeEnvelope', callback: (envelope: Envelope) => void): void; + + /** + * Fire a hook event for transaction start and finish. Expects to be given a transaction as the + * second argument. + */ + emit?(hook: 'startTransaction' | 'finishTransaction', transaction: Transaction): void; /* * Fire a hook event for envelope creation and sending. Expects to be given an envelope as the * second argument. */ - emit?(hook: HookType['name'], ...args: Parameters): void; + emit?(hook: 'beforeEnvelope', envelope: Envelope): void; } diff --git a/packages/types/src/hooks.ts b/packages/types/src/hooks.ts deleted file mode 100644 index f3e4ca389bed..000000000000 --- a/packages/types/src/hooks.ts +++ /dev/null @@ -1,20 +0,0 @@ -import type { Envelope } from './envelope'; -import type { Transaction } from './transaction'; - -// Hooks related to transaction start/finish -export type TransactionHook = { - name: 'startTransaction' | 'transactionFinish'; - callback: (transaction: Transaction) => void; -}; - -// Hooks related to envelope create and send -export type EnvelopeHook = { - name: 'beforeEnvelope'; - callback: (envelope: Envelope) => void; -}; - -export type Hook = TransactionHook | EnvelopeHook; - -type HookStoreItem = Partial>; - -export type HookStore = HookStoreItem & HookStoreItem; diff --git a/packages/types/src/index.ts b/packages/types/src/index.ts index 961d910adf47..7f7ed86cfc9a 100644 --- a/packages/types/src/index.ts +++ b/packages/types/src/index.ts @@ -96,4 +96,3 @@ export type { WrappedFunction } from './wrappedfunction'; export type { Instrumenter } from './instrumenter'; export type { BrowserClientReplayOptions } from './browseroptions'; -export type { HookStore, Hook, TransactionHook, EnvelopeHook } from './hooks'; From f68eb4e0d60f7373679d46b43007ec2ef2ab33f1 Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Wed, 8 Mar 2023 18:31:32 +0100 Subject: [PATCH 09/11] fix lint --- packages/core/test/lib/base.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/test/lib/base.test.ts b/packages/core/test/lib/base.test.ts index d09928566f40..7b0cd1dadc95 100644 --- a/packages/core/test/lib/base.test.ts +++ b/packages/core/test/lib/base.test.ts @@ -1,4 +1,4 @@ -import type { Envelope, Event, Span, Transaction, Client } from '@sentry/types'; +import type { Client,Envelope, Event, Span, Transaction } from '@sentry/types'; import { dsnToString, logger, SentryError, SyncPromise } from '@sentry/utils'; import { Hub, makeSession, Scope } from '../../src'; From 32182f7262e4a68395ee6beb2f9009360f4833b5 Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Wed, 8 Mar 2023 19:07:29 +0100 Subject: [PATCH 10/11] fix types lint --- packages/types/src/client.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/types/src/client.ts b/packages/types/src/client.ts index 3839f794b8e1..71e2ac5a96d6 100644 --- a/packages/types/src/client.ts +++ b/packages/types/src/client.ts @@ -1,6 +1,7 @@ import type { EventDropReason } from './clientreport'; import type { DataCategory } from './datacategory'; import type { DsnComponents } from './dsn'; +import type { Envelope } from './envelope'; import type { Event, EventHint } from './event'; import type { Integration, IntegrationClass } from './integration'; import type { ClientOptions } from './options'; @@ -8,9 +9,8 @@ import type { Scope } from './scope'; import type { SdkMetadata } from './sdkmetadata'; import type { Session, SessionAggregates } from './session'; import type { Severity, SeverityLevel } from './severity'; +import type { Transaction } from './transaction'; import type { Transport } from './transport'; -import { Transaction } from './transaction'; -import { Envelope } from './envelope'; /** * User-Facing Sentry SDK Client. From 51570b580da9d7838a85b57110030fd9bd35a050 Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Wed, 8 Mar 2023 19:27:34 +0100 Subject: [PATCH 11/11] prettier --- packages/core/test/lib/base.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/test/lib/base.test.ts b/packages/core/test/lib/base.test.ts index 7b0cd1dadc95..4ee65114fe79 100644 --- a/packages/core/test/lib/base.test.ts +++ b/packages/core/test/lib/base.test.ts @@ -1,4 +1,4 @@ -import type { Client,Envelope, Event, Span, Transaction } from '@sentry/types'; +import type { Client, Envelope, Event, Span, Transaction } from '@sentry/types'; import { dsnToString, logger, SentryError, SyncPromise } from '@sentry/utils'; import { Hub, makeSession, Scope } from '../../src';