Skip to content

Commit f10452c

Browse files
committed
fix: Use sidecar when it is available for local JS
1 parent f3d71f2 commit f10452c

File tree

8 files changed

+102
-69
lines changed

8 files changed

+102
-69
lines changed

.vscode/settings.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@
1919
"notarytool",
2020
"outro",
2121
"pageload",
22+
"platformicons",
2223
"postject",
24+
"raleway",
2325
"rcodesign",
2426
"spotlightjs",
2527
"svgr",

packages/overlay/package.json

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,10 @@
2929
"devDependencies": {
3030
"@fontsource/raleway": "^5.1.0",
3131
"@microlink/react-json-view": "^1.23.4",
32-
"@sentry/react": "^8.43.0",
33-
"@sentry/types": "^8.33.1",
34-
"@sentry/utils": "^8.33.1",
32+
"@sentry/browser": "^8.51.0",
33+
"@sentry/react": "^8.51.0",
34+
"@sentry/types": "^8.51.0",
35+
"@sentry/core": "^8.51.0",
3536
"@spotlightjs/sidecar": "workspace:*",
3637
"@spotlightjs/tsconfig": "workspace:*",
3738
"@types/beautify": "^0.0.3",

packages/overlay/src/App.tsx

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import Debugger from './components/Debugger';
44
import Trigger from './components/Trigger';
55
import type { Integration, IntegrationData } from './integrations/integration';
66
import * as db from './lib/db';
7-
import { getSpotlightEventTarget } from './lib/eventTarget';
7+
import { getSpotlightEventTarget, trigger } from './lib/eventTarget';
88
import { log } from './lib/logger';
99
import useKeyPress from './lib/useKeyPress';
1010
import { connectToSidecar } from './sidecar';
@@ -62,6 +62,10 @@ export default function App({
6262
return result;
6363
});
6464
const [isOnline, setOnline] = useState(false);
65+
const notifyOnlineStatus = useCallback((onlineStatus: boolean) => {
66+
trigger('sidecar:connectivity', { connected: onlineStatus });
67+
setOnline(onlineStatus);
68+
}, []);
6569
const [triggerButtonCount, setTriggerButtonCount] = useState<NotificationCount>({ count: 0, severe: false });
6670
const [isOpen, setOpen] = useState(openOnInit);
6771
log('App rerender', integrationData, isOnline, triggerButtonCount, isOpen);
@@ -111,8 +115,8 @@ export default function App({
111115
}, [integrations]);
112116

113117
useEffect(
114-
() => connectToSidecar(sidecarUrl, contentTypeListeners, setOnline) as () => undefined,
115-
[sidecarUrl, contentTypeListeners],
118+
() => connectToSidecar(sidecarUrl, contentTypeListeners, notifyOnlineStatus) as () => undefined,
119+
[sidecarUrl, contentTypeListeners, notifyOnlineStatus],
116120
);
117121

118122
const spotlightEventTarget = useMemo(() => getSpotlightEventTarget(), []);

packages/overlay/src/integrations/sentry/data/sentryDataCache.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
import { Envelope } from '@sentry/types';
1+
import type { Envelope } from '@sentry/types';
22
import { CONTEXT_LINES_ENDPOINT } from '@spotlightjs/sidecar/constants';
33
import { DEFAULT_SIDECAR_URL } from '~/constants';
4-
import { RawEventContext } from '~/integrations/integration';
4+
import type { RawEventContext } from '~/integrations/integration';
55
import { log } from '../../../lib/logger';
66
import { generateUuidv4 } from '../../../lib/uuid';
7-
import { Sdk, SentryErrorEvent, SentryEvent, SentryTransactionEvent, Span, Trace } from '../types';
7+
import type { Sdk, SentryErrorEvent, SentryEvent, SentryTransactionEvent, Span, Trace } from '../types';
88
import { getNativeFetchImplementation } from '../utils/fetch';
99
import { sdkToPlatform } from '../utils/sdkToPlatform';
1010
import { groupSpans } from '../utils/traces';

packages/overlay/src/integrations/sentry/index.ts

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ import InsightsTab from './tabs/InsightsTab';
1111
import PerformanceTab from './tabs/PerformanceTab';
1212
import type { SentryErrorEvent, SentryEvent } from './types';
1313

14+
import { spotlightBrowserIntegration } from '@sentry/browser';
15+
1416
const HEADER = 'application/x-sentry-envelope';
1517

1618
type SentryIntegrationOptions = {
@@ -28,10 +30,13 @@ export default function sentryIntegration(options: SentryIntegrationOptions = {}
2830
if (options.retries == null) {
2931
options.retries = 10;
3032
}
33+
let baseSidecarUrl: string | undefined = undefined;
3134
if (sidecarUrl) {
32-
sentryDataCache.setSidecarUrl(removeURLSuffix(sidecarUrl, '/stream'));
35+
baseSidecarUrl = removeURLSuffix(sidecarUrl, '/stream');
36+
sentryDataCache.setSidecarUrl(baseSidecarUrl);
3337
}
34-
addSpotlightIntegrationToSentry(options);
38+
log('Setting up Sentry integration for Spotlight');
39+
addSpotlightIntegrationToSentry(options, baseSidecarUrl && new URL('/stream', baseSidecarUrl).href);
3540

3641
if (options.openLastError) {
3742
sentryDataCache.subscribe('event', (e: SentryEvent) => {
@@ -181,6 +186,11 @@ type WindowWithSentry = Window & {
181186
__SENTRY__?: LegacyCarrier & VersionedCarrier;
182187
};
183188

189+
let sidecarConnected = false;
190+
on('sidecar:connectivity', evt => {
191+
sidecarConnected = (evt as CustomEvent).detail.connected;
192+
});
193+
184194
/**
185195
* Takes care of injecting spotlight-specific behavior into the Sentry SDK by
186196
* accessing the global __SENTRY__ carrier object.
@@ -197,7 +207,7 @@ type WindowWithSentry = Window & {
197207
*
198208
* @param options options of the Sentry integration for Spotlight
199209
*/
200-
function addSpotlightIntegrationToSentry(options: SentryIntegrationOptions) {
210+
function addSpotlightIntegrationToSentry(options: SentryIntegrationOptions, sidecarUrl?: string) {
201211
if (options.injectIntoSDK === false) {
202212
return;
203213
}
@@ -211,7 +221,7 @@ function addSpotlightIntegrationToSentry(options: SentryIntegrationOptions) {
211221
log(`Will retry ${options.retries} more time(s) at 100ms intervals...`);
212222
options.retries--;
213223
setTimeout(() => {
214-
addSpotlightIntegrationToSentry(options);
224+
addSpotlightIntegrationToSentry(options, sidecarUrl);
215225
}, 500);
216226
}
217227
return;
@@ -247,8 +257,8 @@ function addSpotlightIntegrationToSentry(options: SentryIntegrationOptions) {
247257
);
248258
return;
249259
}
250-
const integration = spotlightIntegration();
251-
sentryClient.addIntegration(integration);
260+
sentryClient.addIntegration(spotlightIntegration(sidecarConnected));
261+
sentryClient.addIntegration(spotlightBrowserIntegration({ sidecarUrl }));
252262
} catch (e) {
253263
warn('Failed to add Spotlight integration to Sentry', e);
254264
log('Please open an issue with the error at: https://github.com/getsentry/spotlight/issues/new/choose');

packages/overlay/src/integrations/sentry/sentry-integration.ts

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import type { Client, Envelope, Event, Integration } from '@sentry/types';
2-
import { serializeEnvelope } from '@sentry/utils';
3-
import { trigger } from '../../lib/eventTarget';
2+
import { serializeEnvelope } from '@sentry/core';
3+
import { trigger, on } from '../../lib/eventTarget';
44
import { log } from '../../lib/logger';
55
import sentryDataCache from './data/sentryDataCache';
66

@@ -14,20 +14,24 @@ import sentryDataCache from './data/sentryDataCache';
1414
*
1515
* @returns Sentry integration for Spotlight.
1616
*/
17-
export const spotlightIntegration = () => {
17+
export const spotlightIntegration = (sidecarConnected = false) => {
18+
let enabled = !sidecarConnected;
19+
on('sidecar:connectivity', evt => {
20+
enabled = !(evt as CustomEvent).detail.connected;
21+
});
22+
1823
return {
1924
name: 'SpotlightBrowserDirect',
2025
setupOnce: () => {
2126
/* Empty function to ensure compatibility w/ JS SDK v7 >= 7.99.0 */
2227
},
23-
setup: () => {
24-
log('Setting up the *direct* Sentry SDK integration for Spotlight');
25-
},
28+
setup: () => {},
2629
processEvent: (event: Event) => {
2730
// We don't want to send interaction transactions/root spans created from
2831
// clicks within Spotlight to Sentry. Neither do we want them to be sent to
2932
// spotlight.
3033
if (isSpotlightInteraction(event)) {
34+
log('Dropping transaction created from Spotlight interaction');
3135
return null;
3236
}
3337

@@ -39,9 +43,11 @@ export const spotlightIntegration = () => {
3943
return event;
4044
},
4145
afterAllSetup: (client: Client) =>
42-
client.on('beforeEnvelope', (envelope: Envelope) =>
43-
trigger('event', { contentType: 'application/x-sentry-envelope', data: serializeEnvelope(envelope) }),
44-
),
46+
client.on('beforeEnvelope', (envelope: Envelope) => {
47+
if (enabled) {
48+
trigger('event', { contentType: 'application/x-sentry-envelope', data: serializeEnvelope(envelope) });
49+
}
50+
}),
4551
} satisfies Integration;
4652
};
4753

packages/overlay/src/sidecar.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
1-
import type React from 'react';
21
import { log } from './lib/logger';
32

43
export function connectToSidecar(
54
sidecarUrl: string,
65
// Content Type to listener
76
contentTypeListeners: Record<string, (event: { data: string | Uint8Array }) => void>,
8-
setOnline: React.Dispatch<React.SetStateAction<boolean>>,
7+
setOnline: (online: boolean) => void,
98
): () => void {
109
log('Connecting to sidecar at', sidecarUrl);
1110
const sidecarStreamUrl = new URL('/stream', sidecarUrl);
@@ -18,12 +17,12 @@ export function connectToSidecar(
1817

1918
source.addEventListener('open', () => {
2019
setOnline(true);
21-
log('Open');
20+
log('Sidecar connected.');
2221
});
2322

2423
source.addEventListener('error', err => {
2524
setOnline(false);
26-
console.error('EventSource failed:', err);
25+
console.error('Sidecar connection error:', err);
2726
});
2827

2928
return () => {

0 commit comments

Comments
 (0)