Skip to content

feat(core): Add addIntegration method to client #6651

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jan 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion packages/core/src/baseclient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ import {

import { getEnvelopeEndpointWithUrlEncodedAuth } from './api';
import { createEventEnvelope, createSessionEnvelope } from './envelope';
import { IntegrationIndex, setupIntegrations } from './integration';
import { IntegrationIndex, setupIntegration, setupIntegrations } from './integration';
import { Scope } from './scope';
import { updateSession } from './session';
import { prepareEvent } from './utils/prepareEvent';
Expand Down Expand Up @@ -291,6 +291,13 @@ export abstract class BaseClient<O extends ClientOptions> implements Client<O> {
}
}

/**
* @inheritDoc
*/
public addIntegration(integration: Integration): void {
setupIntegration(integration, this._integrations);
}

/**
* @inheritDoc
*/
Expand Down
19 changes: 12 additions & 7 deletions packages/core/src/integration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,14 +88,19 @@ export function setupIntegrations(integrations: Integration[]): IntegrationIndex
const integrationIndex: IntegrationIndex = {};

integrations.forEach(integration => {
integrationIndex[integration.name] = integration;

if (installedIntegrations.indexOf(integration.name) === -1) {
integration.setupOnce(addGlobalEventProcessor, getCurrentHub);
installedIntegrations.push(integration.name);
__DEBUG_BUILD__ && logger.log(`Integration installed: ${integration.name}`);
}
setupIntegration(integration, integrationIndex);
});

return integrationIndex;
}

/** Setup a single integration. */
export function setupIntegration(integration: Integration, integrationIndex: IntegrationIndex): void {
integrationIndex[integration.name] = integration;

if (installedIntegrations.indexOf(integration.name) === -1) {
integration.setupOnce(addGlobalEventProcessor, getCurrentHub);
installedIntegrations.push(integration.name);
__DEBUG_BUILD__ && logger.log(`Integration installed: ${integration.name}`);
}
}
10 changes: 10 additions & 0 deletions packages/types/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,16 @@ export interface Client<O extends ClientOptions = ClientOptions> {
/** Returns the client's instance of the given integration class, it any. */
getIntegration<T extends Integration>(integration: IntegrationClass<T>): T | null;

/**
* Add an integration to the client.
* This can be used to e.g. lazy load integrations.
* In most cases, this should not be necessary, and you're better off just passing the integrations via `integrations: []` at initialization time.
* However, if you find the need to conditionally load & add an integration, you can use `addIntegration` to do so.
*
* TODO (v8): Make this a required method.
* */
addIntegration?(integration: Integration): void;

/** This is an internal function to setup all integrations that should run on the client */
setupIntegrations(): void;

Expand Down
4 changes: 2 additions & 2 deletions packages/types/src/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ export interface ClientOptions<TO extends BaseTransportOptions = BaseTransportOp
*/
tracesSampler?: (samplingContext: SamplingContext) => number | boolean;

// TODO v8: Narrow the response type to `ErrorEvent` - this is technically a breaking change.
// TODO (v8): Narrow the response type to `ErrorEvent` - this is technically a breaking change.
/**
* An event-processing callback for error and message events, guaranteed to be invoked after all other event
* processors, which allows an event to be modified or dropped.
Expand All @@ -236,7 +236,7 @@ export interface ClientOptions<TO extends BaseTransportOptions = BaseTransportOp
*/
beforeSend?: (event: ErrorEvent, hint: EventHint) => PromiseLike<Event | null> | Event | null;

// TODO v8: Narrow the response type to `TransactionEvent` - this is technically a breaking change.
// TODO (v8): Narrow the response type to `TransactionEvent` - this is technically a breaking change.
/**
* An event-processing callback for transaction events, guaranteed to be invoked after all other event
* processors. This allows an event to be modified or dropped before it's sent.
Expand Down