Skip to content

Commit

Permalink
Merge pull request #2289 from bugsnag/plat-13218
Browse files Browse the repository at this point in the history
web worker: TypeScript and rollup
  • Loading branch information
djskinner authored Jan 29, 2025
2 parents afb9447 + aebef9c commit 4a7dfca
Show file tree
Hide file tree
Showing 24 changed files with 860 additions and 913 deletions.
1,249 changes: 572 additions & 677 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion packages/browser/rollup.config.npm.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ const plugins = [
preventAssignment: true,
values: {
'process.env.NODE_ENV': JSON.stringify('production'),
values: { __VERSION__: packageJson.version },
__BUGSNAG_NOTIFIER_VERSION__: JSON.stringify(packageJson.version),
},
}),
]
Expand Down
3 changes: 2 additions & 1 deletion packages/browser/src/bugsnag.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ import dXDomainRequest from '@bugsnag/delivery-x-domain-request'
import dXMLHttpRequest from '@bugsnag/delivery-xml-http-request'

const name = 'Bugsnag JavaScript'
const version = '__VERSION__'
// @ts-ignore
const version = __BUGSNAG_NOTIFIER_VERSION__
const url = 'https://github.com/bugsnag/bugsnag-js'

const schema = assign({}, baseConfig, browserConfig)
Expand Down
1 change: 1 addition & 0 deletions packages/browser/test/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ function mockFetch () {

describe('browser notifier', () => {
beforeAll(() => {
(global as any).__BUGSNAG_NOTIFIER_VERSION__ = ''
jest.spyOn(console, 'debug').mockImplementation(() => {})
jest.spyOn(console, 'warn').mockImplementation(() => {})
})
Expand Down
2 changes: 2 additions & 0 deletions packages/core/client.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,4 +82,6 @@ export default class ClientWithInternals<T extends Config = Config> extends Clie
_loadPlugin(plugin: Plugin): void

_isBreadcrumbTypeEnabled(type: string): boolean

public addOnError(fn: OnErrorCallback, moveToFront?: boolean): void;
}
4 changes: 2 additions & 2 deletions packages/plugin-browser-device/src/device.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ declare global {
/*
* Automatically detects browser device details
*/
export default (nav = navigator, win = window): Plugin => ({
export default (nav = navigator, win: Window | null = window): Plugin => ({
name: 'device',
load: (client) => {
const device: Device = {
Expand All @@ -33,7 +33,7 @@ export default (nav = navigator, win = window): Plugin => ({
}

// @ts-expect-error _config is private API
if (client._config.generateAnonymousId) {
if (client._config.generateAnonymousId && win) {
device.id = getDeviceId(win)
}

Expand Down
3 changes: 3 additions & 0 deletions packages/web-worker/babel.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
const babelConfig = require('../../babel.config.js')

module.exports = babelConfig
34 changes: 0 additions & 34 deletions packages/web-worker/esm.config.js

This file was deleted.

37 changes: 23 additions & 14 deletions packages/web-worker/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,16 @@
"version": "8.1.1",
"description": "BugSnag error reporter for JavaScript web workers and service workers",
"homepage": "https://www.bugsnag.com/",
"main": "dist/bugsnag.web-worker.js",
"module": "dist/bugsnag.web-worker.js",
"types": "types/notifier.ts",
"main": "dist/index.js",
"module": "dist/index.js",
"types": "dist/types/index.d.ts",
"exports": {
".": {
"types": "./dist/types/index.d.ts",
"import": "./dist/index.js",
"default": "./dist/index.js"
}
},
"repository": {
"type": "git",
"url": "[email protected]:bugsnag/bugsnag-js.git"
Expand All @@ -14,8 +21,7 @@
"access": "public"
},
"files": [
"dist",
"types"
"dist"
],
"keywords": [
"worker",
Expand All @@ -28,11 +34,8 @@
],
"scripts": {
"clean": "rm -fr dist && mkdir dist",
"build": "npm run clean && npm run build:dist && npm run build:dist:min",
"build:dist": "webpack",
"build:dist:min": "webpack --optimization-minimize --output-filename=bugsnag.web-worker.min.js",
"build:dist:esm": "webpack --config esm.config.js",
"build:dist:esm.min": "webpack --config esm.config.js --optimization-minimize --output-filename=bugsnag.web-worker.min.mjs",
"build": "npm run clean && npm run build:npm",
"build:npm": "rollup --config rollup.config.npm.mjs",
"size": "../../bin/size dist/bugsnag.web-worker.min.js",
"cdn-upload": "../../bin/cdn-upload dist/*"
},
Expand All @@ -46,9 +49,15 @@
"@bugsnag/plugin-client-ip": "^8.1.1",
"@bugsnag/plugin-window-onerror": "^8.1.1",
"@bugsnag/plugin-window-unhandled-rejection": "^8.1.1",
"ts-loader": "^9.4.1",
"typescript": "^4.9.3",
"webpack": "^5.75.0",
"webpack-cli": "^5.0.0"
"@rollup/plugin-babel": "^6.0.4",
"@rollup/plugin-commonjs": "^28.0.2",
"@rollup/plugin-node-resolve": "^16.0.0",
"@rollup/plugin-replace": "^6.0.2",
"@rollup/plugin-terser": "^0.4.4",
"rollup": "^4.31.0",
"typescript": "^4.9.3"
},
"dependencies": {
"@bugsnag/core": "^8.1.1"
}
}
69 changes: 69 additions & 0 deletions packages/web-worker/rollup.config.npm.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import babel from '@rollup/plugin-babel'
import commonjs from '@rollup/plugin-commonjs'
import nodeResolve from '@rollup/plugin-node-resolve'
import replace from '@rollup/plugin-replace'
import terser from '@rollup/plugin-terser'
import typescript from '@rollup/plugin-typescript'
import fs from 'fs'

import createRollupConfig, { sharedOutput } from '../../.rollup/index.mjs'

const packageJson = JSON.parse(fs.readFileSync('./package.json'))

const plugins = [
nodeResolve({
browser: true
}),
commonjs(),
typescript({
removeComments: true,
// don't output anything if there's a TS error
noEmitOnError: true,
compilerOptions: {
target: 'es2015'
}
}),
babel({ babelHelpers: 'bundled' }),
replace({
preventAssignment: true,
values: {
'process.env.NODE_ENV': JSON.stringify('production'),
__BUGSNAG_NOTIFIER_VERSION__: JSON.stringify(packageJson.version),
}
})
]

export default [
createRollupConfig({
input: 'src/index.ts',
output: [
{
...sharedOutput,
preserveModules: false,
entryFileNames: '[name].js',
format: 'esm'
}
],
plugins
}),
createRollupConfig({
input: 'src/index-umd.ts',
output: [
{
...sharedOutput,
entryFileNames: 'bugsnag.web-worker.js',
format: 'umd',
name: 'Bugsnag'
},
{
...sharedOutput,
entryFileNames: 'bugsnag.web-worker.min.js',
format: 'umd',
compact: true,
name: 'Bugsnag',
plugins: [terser()]
}
],
plugins
})
]
101 changes: 101 additions & 0 deletions packages/web-worker/src/bugsnag.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
/* eslint-env worker, serviceworker */

import delivery from '@bugsnag/delivery-fetch'
import pluginClientIp from '@bugsnag/plugin-client-ip'
import pluginWindowOnError from '@bugsnag/plugin-window-onerror'
import pluginWindowUnhandledRejection from '@bugsnag/plugin-window-unhandled-rejection'

// extend the base config schema with some browser-specific options
import { schema as baseConfig } from '@bugsnag/core/config'
import workerConfig from './config'
import pluginBrowserDevice from '@bugsnag/plugin-browser-device'
import pluginBrowserSession from '@bugsnag/plugin-browser-session'
import pluginPreventDiscard from './prevent-discard'
import ClientWithInternals from '@bugsnag/core/client'
import type { Client, Config, BugsnagStatic } from '@bugsnag/core'
import assign from '@bugsnag/core/lib/es-utils/assign'

export interface WorkerConfig extends Config {
collectUserIp?: boolean
generateAnonymousId?: boolean
}

export interface WorkerBugsnagStatic extends BugsnagStatic {
start(apiKeyOrOpts: string | WorkerConfig): Client
createClient(apiKeyOrOpts: string | WorkerConfig): Client
}

const name = 'Bugsnag Web Worker'
const url = 'https://github.com/bugsnag/bugsnag-js'
// @ts-ignore
const version = __BUGSNAG_NOTIFIER_VERSION__

// extend the base config schema with some worker-specific options
const schema = assign({}, baseConfig, workerConfig)

type WorkerClient = Partial<ClientWithInternals> & {
_client: ClientWithInternals | null
createClient: (opts?: Config) => ClientWithInternals
start: (opts?: Config) => ClientWithInternals
isStarted: () => boolean
}

const notifier: WorkerClient = {
_client: null,
createClient: (opts) => {
// handle very simple use case where user supplies just the api key as a string
if (typeof opts === 'string') opts = { apiKey: opts }
if (!opts) opts = {} as unknown as Config

const internalPlugins = [
pluginBrowserDevice(navigator, null),
pluginBrowserSession,
pluginClientIp,
pluginPreventDiscard,
pluginWindowOnError(self, 'worker onerror'),
pluginWindowUnhandledRejection(self)
]

// configure a client with user supplied options
const bugsnag = new ClientWithInternals(opts, schema, internalPlugins, { name, version, url })

bugsnag._setDelivery(client => delivery(client, self.fetch))

bugsnag._logger.debug('Loaded!')

return bugsnag._config.autoTrackSessions
? bugsnag.startSession()
: bugsnag
},
start: (opts) => {
if (notifier._client) {
notifier._client._logger.warn('Bugsnag.start() was called more than once. Ignoring.')
return notifier._client
}
notifier._client = notifier.createClient(opts)
return notifier._client
},
isStarted: () => {
return notifier._client != null
}
}

type Method = keyof typeof ClientWithInternals.prototype

// Add client functions to notifier
(Object.getOwnPropertyNames(ClientWithInternals.prototype) as Method[]).forEach(method => {
// skip private methods
// @ts-ignore
if (/^_/.test(method) || method === 'constructor') return
notifier[method] = function () {
if (!notifier._client) return console.log(`Bugsnag.${method}() was called before Bugsnag.start()`)
notifier._client._depth += 1
const ret = notifier._client[method].apply(notifier._client, arguments)
notifier._client._depth -= 1
return ret
}
})

const Bugsnag = notifier as WorkerBugsnagStatic

export default Bugsnag
38 changes: 0 additions & 38 deletions packages/web-worker/src/config.js

This file was deleted.

26 changes: 26 additions & 0 deletions packages/web-worker/src/config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/* eslint-env worker, serviceworker */

import { schema } from '@bugsnag/core/config'
import assign from '@bugsnag/core/lib/es-utils/assign'
import getPrefixedConsole from './get-prefixed-console'

export default {
appType: {
...schema.appType,
defaultValue: () => 'workerjs'
},
logger: assign({}, schema.logger, {
defaultValue: () =>
(typeof console !== 'undefined' && typeof console.debug === 'function')
? getPrefixedConsole()
: undefined
}),
autoTrackSessions: {
...schema.autoTrackSessions,
defaultValue: () => false
},
autoDetectErrors: {
...schema.autoTrackSessions,
defaultValue: () => false
}
}
Loading

0 comments on commit 4a7dfca

Please sign in to comment.