Skip to content

Commit b63f04a

Browse files
authored
feat: SDK unified API (#1402)
* feat: Add/change functions on hub/minimal to conform unified api * fix: Domain tests * feat: Add event processor * fix: Scope init * ref: Rename main to default hub
1 parent aa72795 commit b63f04a

File tree

22 files changed

+308
-301
lines changed

22 files changed

+308
-301
lines changed

packages/browser/src/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,11 @@ export {
1919
configureScope,
2020
} from '@sentry/minimal';
2121

22-
export { getGlobalHub, Hub, Scope } from '@sentry/hub';
22+
export { getDefaultHub, Hub, Scope } from '@sentry/hub';
2323

2424
export { BrowserBackend, BrowserOptions } from './backend';
2525
export { BrowserClient } from './client';
26-
export { init, getCurrentClient } from './sdk';
26+
export { init } from './sdk';
2727

2828
import * as Integrations from './integrations';
2929
export { Integrations };

packages/browser/src/sdk.ts

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { initAndBind } from '@sentry/core';
2-
import { getCurrentClient as shimGetCurrentClient } from '@sentry/minimal';
32
import { BrowserOptions } from './backend';
43
import { BrowserClient } from './client';
54
import {
@@ -62,8 +61,3 @@ export function init(options: BrowserOptions): void {
6261
new Breadcrumbs(),
6362
]);
6463
}
65-
66-
/** Returns the current BrowserClient, if any. */
67-
export function getCurrentClient(): BrowserClient {
68-
return shimGetCurrentClient() as BrowserClient;
69-
}

packages/browser/test/index.test.ts

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import {
99
captureException,
1010
captureMessage,
1111
configureScope,
12-
getGlobalHub,
12+
getDefaultHub,
1313
init,
1414
Scope,
1515
SentryEvent,
@@ -25,11 +25,11 @@ describe('SentryBrowser', () => {
2525
});
2626

2727
beforeEach(() => {
28-
getGlobalHub().pushScope();
28+
getDefaultHub().pushScope();
2929
});
3030

3131
afterEach(() => {
32-
getGlobalHub().popScope();
32+
getDefaultHub().popScope();
3333
});
3434

3535
describe('getContext() / setContext()', () => {
@@ -75,7 +75,8 @@ describe('SentryBrowser', () => {
7575
});
7676

7777
it('should record auto breadcrumbs', done => {
78-
getGlobalHub().pushScope(
78+
getDefaultHub().pushScope();
79+
getDefaultHub().bindClient(
7980
new BrowserClient({
8081
afterSend: (event: SentryEvent) => {
8182
expect(event.breadcrumbs!).to.have.lengthOf(3);
@@ -97,7 +98,7 @@ describe('SentryBrowser', () => {
9798
addBreadcrumb({ message: 'test2' });
9899

99100
captureMessage('event');
100-
getGlobalHub().popScope();
101+
getDefaultHub().popScope();
101102
});
102103
});
103104

@@ -115,7 +116,8 @@ describe('SentryBrowser', () => {
115116
});
116117

117118
it('should capture an exception', done => {
118-
getGlobalHub().pushScope(
119+
getDefaultHub().pushScope();
120+
getDefaultHub().bindClient(
119121
new BrowserClient({
120122
afterSend: (event: SentryEvent) => {
121123
expect(event.exception).to.not.be.undefined;
@@ -133,11 +135,12 @@ describe('SentryBrowser', () => {
133135
} catch (e) {
134136
captureException(e);
135137
}
136-
getGlobalHub().popScope();
138+
getDefaultHub().popScope();
137139
});
138140

139141
it('should capture a message', done => {
140-
getGlobalHub().pushScope(
142+
getDefaultHub().pushScope();
143+
getDefaultHub().bindClient(
141144
new BrowserClient({
142145
afterSend: (event: SentryEvent) => {
143146
expect(event.message).to.equal('test');
@@ -148,11 +151,12 @@ describe('SentryBrowser', () => {
148151
}),
149152
);
150153
captureMessage('test');
151-
getGlobalHub().popScope();
154+
getDefaultHub().popScope();
152155
});
153156

154157
it('should capture an event', done => {
155-
getGlobalHub().pushScope(
158+
getDefaultHub().pushScope();
159+
getDefaultHub().bindClient(
156160
new BrowserClient({
157161
afterSend: (event: SentryEvent) => {
158162
expect(event.message).to.equal('test');
@@ -163,7 +167,7 @@ describe('SentryBrowser', () => {
163167
}),
164168
);
165169
captureEvent({ message: 'test' });
166-
getGlobalHub().popScope();
170+
getDefaultHub().popScope();
167171
});
168172
});
169173
});

packages/core/src/sdk.ts

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
1-
import {
2-
bindClient as shimBindClient,
3-
getCurrentClient as shimGetCurrentClient,
4-
} from '@sentry/minimal';
1+
import { getDefaultHub } from '@sentry/hub';
52
import { Integration } from '@sentry/types';
63
import { Client, Options } from './interfaces';
74

@@ -23,7 +20,7 @@ export function initAndBind<F extends Client, O extends Options>(
2320
options: O,
2421
defaultIntegrations: Integration[] = [],
2522
): void {
26-
if (shimGetCurrentClient()) {
23+
if (getDefaultHub().getClient()) {
2724
return;
2825
}
2926

@@ -44,5 +41,5 @@ export function initAndBind<F extends Client, O extends Options>(
4441
});
4542
}
4643

47-
shimBindClient(client);
44+
getDefaultHub().bindClient(client);
4845
}

packages/hub/src/global.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,19 +21,19 @@ global.__SENTRY__ = global.__SENTRY__ || {
2121
};
2222

2323
/** Returns the global shim registry. */
24-
export function getGlobalCarrier(): Carrier {
24+
export function getMainCarrier(): Carrier {
2525
return global.__SENTRY__;
2626
}
2727

2828
/**
29-
* Returns the latest global hum instance.
29+
* Returns the default hub instance.
3030
*
3131
* If a hub is already registered in the global carrier but this module
3232
* contains a more recent version, it replaces the registered version.
3333
* Otherwise, the currently registered hub will be returned.
3434
*/
35-
export function getGlobalHub(): Hub {
36-
const registry = getGlobalCarrier();
35+
export function getDefaultHub(): Hub {
36+
const registry = getMainCarrier();
3737

3838
if (!registry.hub || registry.hub.isOlderThan(API_VERSION)) {
3939
registry.hub = new Hub();

packages/hub/src/hub.ts

Lines changed: 54 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,23 @@ import { Scope } from './scope';
88
* working in case we have a version conflict.
99
*/
1010
export class Hub {
11+
/** Is a {@link Layer}[] containing the client and scope */
12+
private readonly stack: Layer[] = [];
13+
1114
/**
12-
* Creates a new instance of the hub
13-
* @param stack Is a {@link Layer}[] containing the client and scope
15+
* Creates a new instance of the hub, will push one {@link Layer} into the
16+
* internal stack on creation.
17+
*
18+
* @param client bound to the hub.
19+
* @param scope bound to the hub.
1420
* @param version number, higher number means higher priority.
1521
*/
1622
public constructor(
17-
private readonly stack: Layer[] = [],
23+
client?: any,
24+
scope: Scope = new Scope(),
1825
private readonly version: number = API_VERSION,
1926
) {
20-
if (stack.length === 0) {
21-
this.stack.push({ scope: this.createScope(), type: 'process' });
22-
}
27+
this.stack.push({ client, scope });
2328
}
2429

2530
/**
@@ -28,7 +33,7 @@ export class Hub {
2833
* @param method The method to call on the client/client.
2934
* @param args Arguments to pass to the client/fontend.
3035
*/
31-
public _invokeClient(method: string, ...args: any[]): void {
36+
private invokeClient(method: string, ...args: any[]): void {
3237
const top = this.getStackTop();
3338
if (top && top.client && top.client[method]) {
3439
top.client[method](...args, top.scope);
@@ -61,25 +66,42 @@ export class Hub {
6166
return this.version < version;
6267
}
6368

69+
/**
70+
* This binds the given client to the current scope.
71+
* @param client An SDK client (client) instance.
72+
*/
73+
public bindClient(client?: any): void {
74+
const top = this.getStackTop();
75+
top.client = client;
76+
if (top && top.scope && client) {
77+
top.scope.addScopeListener((s: Scope) => {
78+
if (client.getBackend) {
79+
try {
80+
client.getBackend().storeScope(s);
81+
} catch {
82+
// Do nothing
83+
}
84+
}
85+
});
86+
}
87+
}
88+
6489
/**
6590
* Create a new scope to store context information.
6691
*
6792
* The scope will be layered on top of the current one. It is isolated, i.e. all
6893
* breadcrumbs and context information added to this scope will be removed once
6994
* the scope ends. Be sure to always remove this scope with {@link this.popScope}
7095
* when the operation finishes or throws.
71-
* @param client Optional client, defaults to the current client.
7296
*/
73-
public pushScope(client?: any): void {
74-
const usedClient = client || this.getCurrentClient();
97+
public pushScope(): void {
7598
// We want to clone the content of prev scope
7699
const stack = this.getStack();
77100
const parentScope =
78101
stack.length > 0 ? stack[stack.length - 1].scope : undefined;
79102
this.getStack().push({
80-
client: usedClient,
81-
scope: this.createScope(parentScope),
82-
type: 'local',
103+
client: this.getClient(),
104+
scope: Scope.clone(parentScope),
83105
});
84106
}
85107

@@ -95,34 +117,20 @@ export class Hub {
95117
}
96118

97119
/**
98-
* Creates a new scope with a custom client instance and executes the given
99-
* operation within. The scope is automatically removed once the operation
120+
* Creates a new scope with and executes the given operation within.
121+
* The scope is automatically removed once the operation
100122
* finishes or throws.
101123
*
102-
* The client can be configured with different options than the enclosing scope,
103-
* such as a different DSN or other callbacks.
104-
*
105124
* This is essentially a convenience function for:
106125
*
107-
* pushScope(client);
126+
* pushScope();
108127
* callback();
109128
* popScope();
110129
*
111-
* @param arg1 Either the client or callback.
112-
* @param arg2 Either the client or callback.
130+
* @param callback that will be enclosed into push/popScope.
113131
*/
114-
public withScope(arg1: (() => void) | any, arg2?: (() => void) | any): void {
115-
let callback: () => void = arg1;
116-
let client: any = arg2;
117-
if (!!(arg1 && arg1.constructor && arg1.call && arg1.apply)) {
118-
callback = arg1;
119-
client = arg2;
120-
}
121-
if (!!(arg2 && arg2.constructor && arg2.call && arg2.apply)) {
122-
callback = arg2;
123-
client = arg1;
124-
}
125-
this.pushScope(client);
132+
public withScope(callback: (() => void)): void {
133+
this.pushScope();
126134
try {
127135
callback();
128136
} finally {
@@ -131,7 +139,7 @@ export class Hub {
131139
}
132140

133141
/** Returns the client of the currently active scope. */
134-
public getCurrentClient(): any | undefined {
142+
public getClient(): any | undefined {
135143
return this.getStackTop().client;
136144
}
137145

@@ -145,18 +153,6 @@ export class Hub {
145153
return this.stack[this.stack.length - 1];
146154
}
147155

148-
/**
149-
* Obtains a new scope instance from the client.
150-
*
151-
* @param parentScope Optional parent scope to inherit from.
152-
* @returns The scope instance or an empty object on error.
153-
*/
154-
public createScope(parentScope?: Scope): Scope {
155-
const newScope = new Scope();
156-
newScope.setParentScope(parentScope);
157-
return newScope;
158-
}
159-
160156
/**
161157
* Captures an exception event and sends it to Sentry.
162158
*
@@ -193,7 +189,7 @@ export class Hub {
193189
* @param breadcrumb The breadcrumb to record.
194190
*/
195191
public addBreadcrumb(breadcrumb: Breadcrumb): void {
196-
this._invokeClient('addBreadcrumb', breadcrumb);
192+
this.invokeClient('addBreadcrumb', breadcrumb);
197193
}
198194

199195
/**
@@ -208,4 +204,15 @@ export class Hub {
208204
callback(top.scope);
209205
}
210206
}
207+
208+
/**
209+
* This will be called to receive the event
210+
* @param callback
211+
*/
212+
public addEventProcessor(callback: () => (event: SentryEvent) => void): void {
213+
const top = this.getStackTop();
214+
if (top.scope && top.client) {
215+
top.scope.addEventProcessor(callback());
216+
}
217+
}
211218
}

packages/hub/src/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
export { Carrier, Layer, LayerType } from './interfaces';
1+
export { Carrier, Layer } from './interfaces';
22
export { Scope } from './scope';
33
export { Hub } from './hub';
4-
export { getGlobalHub, getHubFromCarrier } from './global';
4+
export { getDefaultHub, getHubFromCarrier } from './global';

packages/hub/src/interfaces.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,10 @@
11
import { Hub } from './hub';
22
import { Scope } from './scope';
33

4-
/** The type of a process stack layer. */
5-
export type LayerType = 'process' | 'local';
6-
74
/** A layer in the process stack. */
85
export interface Layer {
96
client?: any;
107
scope?: Scope;
11-
type: LayerType;
128
}
139

1410
/** An object that contains a hub and maintains a scope stack. */

0 commit comments

Comments
 (0)