import { getDomainStack } from './domain';
import { getGlobalStack } from './global';
import { ScopeLayer } from './interfaces';
* API compatibility version of this shim.
*
* WARNING: This number should only be incresed when the global interface
* changes a and new methods are introduced.
*/
export const API_VERSION = 1;
* Internal class used to make sure we always have the latest internal functions
* working in case we have a version conflict.
*/
export class Shim {
public constructor(public readonly version: number = API_VERSION) {
const stack = getGlobalStack();
if (stack.length === 0) {
stack.push({ scope: {}, type: 'process' });
}
}
* Checks if this shim's version is older than the given version.
*
* @param version A version number to compare to.
* @return True if the given version is newer; otherwise false.
*/
public isOlderThan(version: number): boolean {
return this.version < version;
}
* Creates a new 'local' ScopeLayer with the given client.
* @param client Optional client, defaults to the current client.
*/
public pushScope(client?: any): void {
const usedClient = client || this.getCurrentClient();
this.getStack().push({
client: usedClient,
scope: this.getInitialScope(usedClient),
type: 'local',
});
}
public popScope(): boolean {
return this.getStack().pop() !== undefined;
}
* Convenience method for pushScope and popScope.
*
* @param arg1 Either the client or callback.
* @param arg2 Either the client or callback.
*/
public withScope(arg1: (() => void) | any, arg2?: (() => void) | any): void {
let callback: () => void = arg1;
let client: any = arg2;
if (!!(arg1 && arg1.constructor && arg1.call && arg1.apply)) {
callback = arg1;
client = arg2;
}
if (!!(arg2 && arg2.constructor && arg2.call && arg2.apply)) {
callback = arg2;
client = arg1;
}
this.pushScope(client);
try {
callback();
} finally {
this.popScope();
}
}
public clearScope(): void {
const top = this.getStackTop();
top.scope = this.getInitialScope(top.client);
}
public getCurrentClient(): any | undefined {
return this.getStackTop().client;
}
public getStack(): ScopeLayer[] {
return getDomainStack() || getGlobalStack();
}
public getStackTop(): ScopeLayer {
return this.getDomainStackTop() || this.getGlobalStackTop();
}
private getGlobalStackTop(): ScopeLayer {
const stack = getGlobalStack();
return stack[stack.length - 1];
}
private getDomainStackTop(): ScopeLayer | undefined {
const stack = getDomainStack();
if (!stack) {
return undefined;
}
if (stack.length === 0) {
const client = this.getCurrentClient();
stack.push({
client,
scope: this.getInitialScope(client),
type: 'domain',
});
}
return stack[stack.length - 1];
}
* Obtains a new scope instance from the client.
*
* @param client An SDK client that implements `getInitialScope`.
* @returns The scope instance or an empty object on error.
*/
public getInitialScope(client?: any): any {
try {
return client && client.getInitialScope();
} catch {
return {};
}
}
}