UNPKG

@sentry/browser

Version:
136 lines (129 loc) 4.42 kB
import { defineIntegration, debug, isPlainObject } from '@sentry/core'; import { DEBUG_BUILD } from '../debug-build.js'; import { WINDOW } from '../helpers.js'; const INTEGRATION_NAME = 'WebWorker'; /** * Use this integration to set up Sentry with web workers. * * IMPORTANT: This integration must be added **before** you start listening to * any messages from the worker. Otherwise, your message handlers will receive * messages from the Sentry SDK which you need to ignore. * * This integration only has an effect, if you call `Sentry.registerWorker(self)` * from within the worker(s) you're adding to the integration. * * Given that you want to initialize the SDK as early as possible, you most likely * want to add this integration **after** initializing the SDK: * * @example: * ```ts filename={main.js} * import * as Sentry from '@sentry/<your-sdk>'; * * // some time earlier: * Sentry.init(...) * * // 1. Initialize the worker * const worker = new Worker(new URL('./worker.ts', import.meta.url)); * * // 2. Add the integration * const webWorkerIntegration = Sentry.webWorkerIntegration({ worker }); * Sentry.addIntegration(webWorkerIntegration); * * // 3. Register message listeners on the worker * worker.addEventListener('message', event => { * // ... * }); * ``` * * If you initialize multiple workers at the same time, you can also pass an array of workers * to the integration: * * ```ts filename={main.js} * const webWorkerIntegration = Sentry.webWorkerIntegration({ worker: [worker1, worker2] }); * Sentry.addIntegration(webWorkerIntegration); * ``` * * If you have any additional workers that you initialize at a later point, * you can add them to the integration as follows: * * ```ts filename={main.js} * const webWorkerIntegration = Sentry.webWorkerIntegration({ worker: worker1 }); * Sentry.addIntegration(webWorkerIntegration); * * // sometime later: * webWorkerIntegration.addWorker(worker2); * ``` * * Of course, you can also directly add the integration in Sentry.init: * ```ts filename={main.js} * import * as Sentry from '@sentry/<your-sdk>'; * * // 1. Initialize the worker * const worker = new Worker(new URL('./worker.ts', import.meta.url)); * * // 2. Initialize the SDK * Sentry.init({ * integrations: [Sentry.webWorkerIntegration({ worker })] * }); * * // 3. Register message listeners on the worker * worker.addEventListener('message', event => { * // ... * }); * ``` * * @param options {WebWorkerIntegrationOptions} Integration options: * - `worker`: The worker instance. */ const webWorkerIntegration = defineIntegration(({ worker }) => ({ name: INTEGRATION_NAME, setupOnce: () => { (Array.isArray(worker) ? worker : [worker]).forEach(w => listenForSentryDebugIdMessages(w)); }, addWorker: (worker) => listenForSentryDebugIdMessages(worker), })) ; function listenForSentryDebugIdMessages(worker) { worker.addEventListener('message', event => { if (isSentryDebugIdMessage(event.data)) { event.stopImmediatePropagation(); // other listeners should not receive this message DEBUG_BUILD && debug.log('Sentry debugId web worker message received', event.data); WINDOW._sentryDebugIds = { ...event.data._sentryDebugIds, // debugIds of the main thread have precedence over the worker's in case of a collision. ...WINDOW._sentryDebugIds, }; } }); } /** * Use this function to register the worker with the Sentry SDK. * * @example * ```ts filename={worker.js} * import * as Sentry from '@sentry/<your-sdk>'; * * // Do this as early as possible in your worker. * Sentry.registerWorker({ self }); * * // continue setting up your worker * self.postMessage(...) * ``` * @param options {RegisterWebWorkerOptions} Integration options: * - `self`: The worker instance you're calling this function from (self). */ function registerWebWorker({ self }) { self.postMessage({ _sentryMessage: true, _sentryDebugIds: self._sentryDebugIds ?? undefined, }); } function isSentryDebugIdMessage(eventData) { return ( isPlainObject(eventData) && eventData._sentryMessage === true && '_sentryDebugIds' in eventData && (isPlainObject(eventData._sentryDebugIds) || eventData._sentryDebugIds === undefined) ); } export { INTEGRATION_NAME, registerWebWorker, webWorkerIntegration }; //# sourceMappingURL=webWorker.js.map