From e54ce29a29d178b0ddbe4a74ff794ede7c03a31d Mon Sep 17 00:00:00 2001 From: Jack Westbrook Date: Tue, 3 Dec 2024 17:23:04 +0100 Subject: [PATCH] refactor(crash): clean up cors sharedworker --- public/app/core/crash/index.ts | 5 ++- public/app/core/utils/CorsSharedWorker.ts | 38 ++++++----------------- public/app/core/utils/CorsWorker.ts | 2 +- 3 files changed, 13 insertions(+), 32 deletions(-) diff --git a/public/app/core/crash/index.ts b/public/app/core/crash/index.ts index 929ff7ef7e4..79e64e2b2fb 100644 --- a/public/app/core/crash/index.ts +++ b/public/app/core/crash/index.ts @@ -6,7 +6,7 @@ import { config, createMonitoringLogger } from '@grafana/runtime'; import { corsWorker } from 'app/core/utils/CorsWorker'; import { contextSrv } from '../services/context_srv'; -import { CorsSharedWorker as SharedWorker, sharedWorkersSupported } from '../utils/CorsSharedWorker'; +import { corsSharedWorker, sharedWorkersSupported } from '../utils/CorsSharedWorker'; import { isChromePerformance, prepareContext } from './crash.utils'; @@ -61,8 +61,7 @@ export function initializeCrashDetection() { * We guarantee the type assertion is correct by returning a SharedWorker in CorsSharedWorker constructor. */ createDetectorWorker() { - // eslint-disable-next-line @typescript-eslint/consistent-type-assertions - return new SharedWorker(new URL('./detector.worker', import.meta.url)) as globalThis.SharedWorker; + return corsSharedWorker('./detector.worker', { name: 'crashDetector' }); }, reportCrash: async (report) => { diff --git a/public/app/core/utils/CorsSharedWorker.ts b/public/app/core/utils/CorsSharedWorker.ts index 6edee786867..c9a6c549b65 100644 --- a/public/app/core/utils/CorsSharedWorker.ts +++ b/public/app/core/utils/CorsSharedWorker.ts @@ -1,33 +1,15 @@ -// Almost identical to CorsWorker.ts. Main difference being it allows loading a SharedWorker if browser supports it - export function sharedWorkersSupported() { return typeof window.SharedWorker !== 'undefined'; } -/** - * Creating CorsSharedWorker should be called only if sharedWorkersSupported() is truthy - */ -export class CorsSharedWorker { - constructor(url: URL, options?: WorkerOptions) { - if (!sharedWorkersSupported()) { - throw new Error('SharedWorker is not supported'); - } - // by default, worker inherits HTML document's location and pathname which leads to wrong public path value - // the CorsWorkerPlugin will override it with the value based on the initial worker chunk, ie. - // initial worker chunk: http://host.com/cdn/scripts/worker-123.js - // resulting public path: http://host.com/cdn/scripts - - const scriptUrl = url.toString(); - const scriptsBasePathUrl = new URL('.', url).toString(); - - const importScripts = `importScripts('${scriptUrl}');`; - const objectURL = URL.createObjectURL( - new Blob([`__webpack_worker_public_path__ = '${scriptsBasePathUrl}'; ${importScripts}`], { - type: 'application/javascript', - }) - ); - const worker = new SharedWorker(objectURL, options); - URL.revokeObjectURL(objectURL); - return worker; - } +// This function is used to create a sharedworker that can load across domains. +export function corsSharedWorker(workerUrl: string, options: WorkerOptions) { + const js = `import ${JSON.stringify(new URL(workerUrl, import.meta.url))}`; + const blob = new Blob([js], { type: 'application/javascript' }); + const objURL = URL.createObjectURL(blob); + const worker = new SharedWorker(objURL, { type: 'module', name: options?.name }); + worker.addEventListener('error', (e) => { + URL.revokeObjectURL(objURL); + }); + return worker; } diff --git a/public/app/core/utils/CorsWorker.ts b/public/app/core/utils/CorsWorker.ts index ef71e918cb5..b9bfa56cdc7 100644 --- a/public/app/core/utils/CorsWorker.ts +++ b/public/app/core/utils/CorsWorker.ts @@ -1,4 +1,4 @@ -// This function is used to create a worker that can be used to fetch data from a different domain (e.g. CDN). +// This function is used to create a worker that can load across domains. export function corsWorker(workerUrl: string, options: WorkerOptions) { const js = `import ${JSON.stringify(new URL(workerUrl, import.meta.url))}`; const blob = new Blob([js], { type: 'application/javascript' });