Skip to content

feat(utils): Introduce getGlobalSingleton helper #4860

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
Apr 6, 2022
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
19 changes: 12 additions & 7 deletions packages/hub/src/hub.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,15 @@ import {
TransactionContext,
User,
} from '@sentry/types';
import { consoleSandbox, dateTimestampInSeconds, getGlobalObject, isNodeEnv, logger, uuid4 } from '@sentry/utils';
import {
consoleSandbox,
dateTimestampInSeconds,
getGlobalObject,
getGlobalSingleton,
isNodeEnv,
logger,
uuid4,
} from '@sentry/utils';

import { IS_DEBUG_BUILD } from './flags';
import { Scope } from './scope';
Expand Down Expand Up @@ -617,10 +625,7 @@ function hasHubOnCarrier(carrier: Carrier): boolean {
* @hidden
*/
export function getHubFromCarrier(carrier: Carrier): Hub {
if (carrier && carrier.__SENTRY__ && carrier.__SENTRY__.hub) return carrier.__SENTRY__.hub;
carrier.__SENTRY__ = carrier.__SENTRY__ || {};
carrier.__SENTRY__.hub = new Hub();
return carrier.__SENTRY__.hub;
return getGlobalSingleton<Hub>('hub', () => new Hub(), carrier);
}

/**
Expand All @@ -631,7 +636,7 @@ export function getHubFromCarrier(carrier: Carrier): Hub {
*/
export function setHubOnCarrier(carrier: Carrier, hub: Hub): boolean {
if (!carrier) return false;
carrier.__SENTRY__ = carrier.__SENTRY__ || {};
carrier.__SENTRY__.hub = hub;
const __SENTRY__ = (carrier.__SENTRY__ = carrier.__SENTRY__ || {});
__SENTRY__.hub = hub;
return true;
}
9 changes: 2 additions & 7 deletions packages/hub/src/scope.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import {
Transaction,
User,
} from '@sentry/types';
import { dateTimestampInSeconds, getGlobalObject, isPlainObject, isThenable, SyncPromise } from '@sentry/utils';
import { dateTimestampInSeconds, getGlobalSingleton, isPlainObject, isThenable, SyncPromise } from '@sentry/utils';

import { Session } from './session';

Expand Down Expand Up @@ -522,12 +522,7 @@ export class Scope implements ScopeInterface {
* Returns the global event processors.
*/
function getGlobalEventProcessors(): EventProcessor[] {
/* eslint-disable @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access */
const global = getGlobalObject<any>();
global.__SENTRY__ = global.__SENTRY__ || {};
global.__SENTRY__.globalEventProcessors = global.__SENTRY__.globalEventProcessors || [];
return global.__SENTRY__.globalEventProcessors;
/* eslint-enable @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access */
return getGlobalSingleton<EventProcessor[]>('globalEventProcessors', () => []);
}

/**
Expand Down
18 changes: 18 additions & 0 deletions packages/utils/src/global.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,21 @@ export function getGlobalObject<T>(): T & SentryGlobal {
: fallbackGlobalObject
) as T & SentryGlobal;
}

/**
* Returns a global singleton contained in the global `__SENTRY__` object.
*
* If the singleton doesn't already exist in `__SENTRY__`, it will be created using the given factory
* function and added to the `__SENTRY__` object.
*
* @param name name of the global singleton on __SENTRY__
* @param creator creator Factory function to create the singleton if it doesn't already exist on `__SENTRY__`
* @param obj (Optional) The global object on which to look for `__SENTRY__`, if not `getGlobalObject`'s return value
* @returns the singleton
*/
export function getGlobalSingleton<T>(name: keyof SentryGlobal['__SENTRY__'], creator: () => T, obj?: unknown): T {
const global = (obj || getGlobalObject()) as SentryGlobal;
const __SENTRY__ = (global.__SENTRY__ = global.__SENTRY__ || {});
const singleton = __SENTRY__[name] || (__SENTRY__[name] = creator());
return singleton;
}