npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@wix/monitoring-browser-sentry

v0.21.0

Published

A Sentry adapter for monitoring in external apps.

Downloads

8,381

Readme

@wix/monitoring-browser-sentry

A Sentry adapter for monitoring in external apps.

[!NOTE] We support a lazy Sentry instance, but from the user perspective all methods in the adapter always run synchronously

Semi-custom implementation of spans

Why is a custom implementation required?

The lazy Sentry instance doesn't include any spans functionality, meaning that we need to implement parts of it while we wait for the full SDK to load.

startSpan()

We execute all code synchronosuly if we received the full SDK upfront and when the full SDK was already loaded.

If the full SDK was not loaded yet, we do the following:

  • Start preloading the full SDK
  • Run the user callback synchronously (the callback itself can be sync or async, we handle both cases)
    • Record the duration of the callback execution
    • Catch any unhandled errors thrown from the callback and save the reference to the error
      • Rethrow the error so that the user code fails
    • Return the return value of the callback
  • When the full SDK is ready call Sentry.startSpan() with a simulated callback:
    • The callback runs the same amount of time as the original one
    • The callback throws the same error as the original one
      • We wrap the Sentry.startSpan() call with try/catch because Sentry will rethrow the error
        • We will rethrow the error if it is thrown from within Sentry.startSpan() unexpectedly

startSpanManual()

A custom implementation of a manual span, which doesn't involve a callback and instead returns a ManualSpan instance that allows to end the span successfully or fail it with a provided Error or error message.

Under the hood we still call Sentry.startSpan() but provide a callback that returns a Promise, which gives us the ability to resolve or reject it on demand, at which Sentry will report it.

  • We save the ManualSpan instance using the span name in a map
    • Consecutive calls to startSpanManual() with the same span name will override the mapped value, it is up to the user to end the span before starting a new one
    • If the full SDK was not loaded yet we trigger and subscribe to the fullSDK and save a promise of type ManualSpan
  • We return a ManualSpan instance to the user to allow ending or failing the span manually
  • If the full SDK was not loaded yet we handle the end() and fail() calls asynchronously (but hide this fact from the user)
  • When end() is called we resolve the callback promise (and then Sentry reports the span)
    • The span is then removed from the map
  • When fail() is called we reject the callback promise (and then Sentry marks the span as failed and reports it)
    • The span is then removed from the map
    • We catch the rejection because Sentry will rethrow the error
      • We will rethrow the error if it is thrown from within Sentry.startSpan() unexpectedly
  • We report the span only once even if multiple end() or fail() calls were made

endSpanManual()

Allows to end a span that was created via startSpanManual() by name, rather than via the returned ManualSpan object.

This methods allows to end only the last span that was created. It is up to the user to make sure there is no ambiguity (i.e. multiple started spans) when they call this method.

  • We get the pending ManualSpan instance using the span name from our map and then call end() if the span exists
    • The span is then removed from the map
  • We report the span only once even if multiple endSpanManual() calls were made

A note about isolation of manual spans

  • In the browser we report manual spans with the forceTransaction: true flag because spans are reported globally and we want to avoid grouping spans under the same transaction, and more importantly avoid grouping if they were reported from different apps
  • We create the map of the pending manual spans pepr the provided dsn to avoid conflict between apps that report spans with the same name