Skip to content

Commit eb11979

Browse files
authored
feat(utils): Introduce getGlobalSingleton helper (#4860)
This helper abstracts away the logic of getting an variable from the global `__SENTRY__` object. It does this by introducing a new `getGlobalSingleton` utility function. For now, this is used by the event processors and hub logic. In an upcoming PR, we'll update the logger logic to also use this utility.
1 parent 225dd47 commit eb11979

File tree

3 files changed

+32
-14
lines changed

3 files changed

+32
-14
lines changed

packages/hub/src/hub.ts

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,15 @@ import {
2020
TransactionContext,
2121
User,
2222
} from '@sentry/types';
23-
import { consoleSandbox, dateTimestampInSeconds, getGlobalObject, isNodeEnv, logger, uuid4 } from '@sentry/utils';
23+
import {
24+
consoleSandbox,
25+
dateTimestampInSeconds,
26+
getGlobalObject,
27+
getGlobalSingleton,
28+
isNodeEnv,
29+
logger,
30+
uuid4,
31+
} from '@sentry/utils';
2432

2533
import { IS_DEBUG_BUILD } from './flags';
2634
import { Scope } from './scope';
@@ -617,10 +625,7 @@ function hasHubOnCarrier(carrier: Carrier): boolean {
617625
* @hidden
618626
*/
619627
export function getHubFromCarrier(carrier: Carrier): Hub {
620-
if (carrier && carrier.__SENTRY__ && carrier.__SENTRY__.hub) return carrier.__SENTRY__.hub;
621-
carrier.__SENTRY__ = carrier.__SENTRY__ || {};
622-
carrier.__SENTRY__.hub = new Hub();
623-
return carrier.__SENTRY__.hub;
628+
return getGlobalSingleton<Hub>('hub', () => new Hub(), carrier);
624629
}
625630

626631
/**
@@ -631,7 +636,7 @@ export function getHubFromCarrier(carrier: Carrier): Hub {
631636
*/
632637
export function setHubOnCarrier(carrier: Carrier, hub: Hub): boolean {
633638
if (!carrier) return false;
634-
carrier.__SENTRY__ = carrier.__SENTRY__ || {};
635-
carrier.__SENTRY__.hub = hub;
639+
const __SENTRY__ = (carrier.__SENTRY__ = carrier.__SENTRY__ || {});
640+
__SENTRY__.hub = hub;
636641
return true;
637642
}

packages/hub/src/scope.ts

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import {
1818
Transaction,
1919
User,
2020
} from '@sentry/types';
21-
import { dateTimestampInSeconds, getGlobalObject, isPlainObject, isThenable, SyncPromise } from '@sentry/utils';
21+
import { dateTimestampInSeconds, getGlobalSingleton, isPlainObject, isThenable, SyncPromise } from '@sentry/utils';
2222

2323
import { Session } from './session';
2424

@@ -522,12 +522,7 @@ export class Scope implements ScopeInterface {
522522
* Returns the global event processors.
523523
*/
524524
function getGlobalEventProcessors(): EventProcessor[] {
525-
/* eslint-disable @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access */
526-
const global = getGlobalObject<any>();
527-
global.__SENTRY__ = global.__SENTRY__ || {};
528-
global.__SENTRY__.globalEventProcessors = global.__SENTRY__.globalEventProcessors || [];
529-
return global.__SENTRY__.globalEventProcessors;
530-
/* eslint-enable @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access */
525+
return getGlobalSingleton<EventProcessor[]>('globalEventProcessors', () => []);
531526
}
532527

533528
/**

packages/utils/src/global.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,3 +44,21 @@ export function getGlobalObject<T>(): T & SentryGlobal {
4444
: fallbackGlobalObject
4545
) as T & SentryGlobal;
4646
}
47+
48+
/**
49+
* Returns a global singleton contained in the global `__SENTRY__` object.
50+
*
51+
* If the singleton doesn't already exist in `__SENTRY__`, it will be created using the given factory
52+
* function and added to the `__SENTRY__` object.
53+
*
54+
* @param name name of the global singleton on __SENTRY__
55+
* @param creator creator Factory function to create the singleton if it doesn't already exist on `__SENTRY__`
56+
* @param obj (Optional) The global object on which to look for `__SENTRY__`, if not `getGlobalObject`'s return value
57+
* @returns the singleton
58+
*/
59+
export function getGlobalSingleton<T>(name: keyof SentryGlobal['__SENTRY__'], creator: () => T, obj?: unknown): T {
60+
const global = (obj || getGlobalObject()) as SentryGlobal;
61+
const __SENTRY__ = (global.__SENTRY__ = global.__SENTRY__ || {});
62+
const singleton = __SENTRY__[name] || (__SENTRY__[name] = creator());
63+
return singleton;
64+
}

0 commit comments

Comments
 (0)