Skip to content
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
106 changes: 0 additions & 106 deletions src/js/scope.ts

This file was deleted.

78 changes: 78 additions & 0 deletions src/js/scopeSync.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import type { Breadcrumb, Scope } from '@sentry/types';

import { DEFAULT_BREADCRUMB_LEVEL } from './breadcrumb';
import { fillTyped } from './utils/fill';
import { convertToNormalizedObject } from './utils/normalize';
import { NATIVE } from './wrapper';

/**
* This WeakMap is used to keep track of which scopes have been synced to the native SDKs.
* This ensures that we don't double sync the same scope.
*/
const syncedToNativeMap = new WeakMap<Scope, true>();

/**
* Hooks into the scope set methods and sync new data added to the given scope with the native SDKs.
*/
export function enableSyncToNative(scope: Scope): void {
if (syncedToNativeMap.has(scope)) {
return;
}
syncedToNativeMap.set(scope, true);

fillTyped(scope, 'setUser', original => (user): Scope => {
NATIVE.setUser(user);
return original.call(scope, user);
});

fillTyped(scope, 'setTag', original => (key, value): Scope => {
NATIVE.setTag(key, value as string);
return original.call(scope, key, value);
});

fillTyped(scope, 'setTags', original => (tags): Scope => {
// As native only has setTag, we just loop through each tag key.
Object.keys(tags).forEach(key => {
NATIVE.setTag(key, tags[key] as string);
});
return original.call(scope, tags);
});

fillTyped(scope, 'setExtras', original => (extras): Scope => {
Object.keys(extras).forEach(key => {
NATIVE.setExtra(key, extras[key]);
});
return original.call(scope, extras);
});

fillTyped(scope, 'setExtra', original => (key, value): Scope => {
NATIVE.setExtra(key, value);
return original.call(scope, key, value);
});

fillTyped(scope, 'addBreadcrumb', original => (breadcrumb, maxBreadcrumbs): Scope => {
const mergedBreadcrumb: Breadcrumb = {
...breadcrumb,
level: breadcrumb.level || DEFAULT_BREADCRUMB_LEVEL,
data: breadcrumb.data ? convertToNormalizedObject(breadcrumb.data) : undefined,
};

original.call(scope, mergedBreadcrumb, maxBreadcrumbs);

const finalBreadcrumb = scope.getLastBreadcrumb();
NATIVE.addBreadcrumb(finalBreadcrumb);

return scope;
});

fillTyped(scope, 'clearBreadcrumbs', original => (): Scope => {
NATIVE.clearBreadcrumbs();
return original.call(scope);
});

// eslint-disable-next-line @typescript-eslint/no-explicit-any
fillTyped(scope, 'setContext', original => (key: string, context: { [key: string]: any } | null): Scope => {
NATIVE.setContext(key, context);
return original.call(scope, key, context);
});
}
14 changes: 10 additions & 4 deletions src/js/sdk.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
/* eslint-disable complexity */
import { getClient, getIntegrationsToSetup, initAndBind, withScope as coreWithScope } from '@sentry/core';
import { getClient, getGlobalScope,getIntegrationsToSetup, getIsolationScope,initAndBind, withScope as coreWithScope } from '@sentry/core';
import {
defaultStackParser,
makeFetchTransport,
} from '@sentry/react';
import type { Integration, Scope, UserFeedback } from '@sentry/types';
import type { Integration, Scope,UserFeedback } from '@sentry/types';
import { logger, stackParserFromStackParserOptions } from '@sentry/utils';
import * as React from 'react';

import { ReactNativeClient } from './client';
import { getDefaultIntegrations } from './integrations/default';
import type { ReactNativeClientOptions, ReactNativeOptions, ReactNativeWrapperOptions } from './options';
import { shouldEnableNativeNagger } from './options';
import { enableSyncToNative } from './scopeSync';
import { TouchEventBoundary } from './touchevents';
import type { ReactNativeTracing } from './tracing';
import { ReactNativeProfiler } from './tracing';
Expand Down Expand Up @@ -43,8 +44,6 @@ export function init(passedOptions: ReactNativeOptions): void {
return;
}

useEncodePolyfill();

const maxQueueSize = passedOptions.maxQueueSize
// eslint-disable-next-line deprecation/deprecation
?? passedOptions.transportOptions?.bufferSize
Expand All @@ -53,6 +52,13 @@ export function init(passedOptions: ReactNativeOptions): void {
const enableNative = passedOptions.enableNative === undefined || passedOptions.enableNative
? NATIVE.isNativeAvailable()
: false;

useEncodePolyfill();
if (enableNative) {
enableSyncToNative(getGlobalScope());
enableSyncToNative(getIsolationScope());
}

const options: ReactNativeClientOptions = {
...DEFAULT_OPTIONS,
...passedOptions,
Expand Down
13 changes: 13 additions & 0 deletions src/js/utils/fill.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { fill } from '@sentry/utils';

/**
* The same as `import { fill } from '@sentry/utils';` but with explicit types.
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export function fillTyped<Source extends { [key: string]: any }, Name extends keyof Source & string>(
source: Source,
name: Name,
replacement: (original: Source[Name]) => Source[Name],
): void {
fill(source, name, replacement);
}
102 changes: 0 additions & 102 deletions test/scope.test.ts

This file was deleted.

Loading