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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@matrix500mg-plugins/angular

v1.0.4

Published

Framework-agnostic OpenTelemetry frontend SDK — Grafana Tempo + Loki

Readme

@matrix500mg-plugins/angular

Frontend observability SDK for DMI apps — OpenTelemetry traces to Grafana Tempo, logs to Loki, Web Vitals, and cross-project journey linking.

Framework-agnostic core; used from Angular via the standard 4-file kit (matrix500-config.ts, -init.ts, -tracking.service.ts, -http.interceptor.ts).


⚠️ Upgrading to 1.0.4 — read this first

1.0.4 removes raw mobile numbers from all telemetry. If you upgrade without setting piiSalt, nothing crashes — but cross-project journey linking silently breaks, which is the worst kind of failure. Two things to do:

1. Set piiSalt, identically in every project

export const OBS_CONFIG = {
  // ...
  piiSalt: (window as any).__OBS_PII_SALT__ ?? 'dmi-matrix500-2026',
};

Every app that takes part in a handoff (gpay → kyc, phonepe → kyc) must use the same salt. A different salt means a different user.hash, which means the two halves of the journey never join up. Inject it at build time; don't commit the production value.

The backend needs the same value as APM_PII_SALT in .env.

2. Update anything that queried user.mobile

user.mobile and user.email are no longer emitted on spans or log lines. user.hash replaces them:

# before
{ span.user.mobile = "9876543210" }

# after
{ span.user.hash = "b151eb9af95ccacbc72657b06c66322f" }

To go from a mobile number to its hash, call the backend SDK's POST /V1/apm/user-hash (admin-token protected). Don't compute it by hand.

Why: the trace id used to be the mobile number hex-encoded, which is reversible in two lines of JavaScript. Every span also carried the number in plaintext. For an NBFC that is not acceptable at rest in Tempo or Loki.

Also changed in 1.0.4

  • Trace ids rotate daily. Previously one mobile mapped to one trace id forever, so a returning user's trace grew without bound until Tempo dropped it. Ids are still deterministic (handoffs still land in one trace) but are now bucketed per day. Follow a user across days via user.hash.
  • Spans survive a failed export. They used to be discarded when the endpoint was down or the circuit breaker was open. They are now re-queued.
  • maxExportBatchSize is honoured. It was declared but never read; the whole pending queue went out in one request.
  • Error storms are rate-limited. An error inside a render loop used to emit a span and a Loki line per occurrence.
  • INP is collected. interaction_to_next_paint_ms on page-load spans.
  • traceparent carries a real span id. The id it sent before was never exported, so backend spans pointed at a parent Tempo had never seen and rendered as detached, badly ordered roots.

Install

npm install @matrix500mg-plugins/angular

Quick start

// main.ts — before bootstrap, so early spans and bootstrap errors are captured
import { initializeObservability } from '@matrix500mg-plugins/angular';

initializeObservability({
  serviceName: 'dmi-frontend',
  environment: 'production',
  otlpEndpoint: 'https://apmuat.dmifinance.in/v1/traces',
  lokiEndpoint: 'https://apmuat.dmifinance.in/loki/api/v1/push',
  piiSalt: '...',                                  // same in every project
  corsUrls: ['https://dmikyc.dmifinance.in'],      // traceparent goes only here
  customAttributes: { 'project.name': 'dmi-kyc-FE' },
});

Post-login, attach the user:

import { startUserSession } from '@matrix500mg-plugins/angular';

startUserSession({ mobile: '9876543210' });   // hashed immediately, never stored raw

Config

| Key | Default | Notes | |---|---|---| | serviceName | — | Constant across DMI apps | | environment | — | production / development | | otlpEndpoint | — | Tempo (or the OTel Collector) | | lokiEndpoint | — | Full push URL, /loki/api/v1/push | | piiSalt | matrix500-default-salt | Set this. Must match across projects | | corsUrls | [] | Origins that receive traceparent | | customAttributes | {} | Must include project.name | | maxExportBatchSize | 50 | Spans per export request | | scheduledDelayMillis | 5000 | Batch flush interval | | propagateTraceHeaders | true | Needs corsUrls to do anything | | enableTTFI / enablePageTracking / enableApiTracking / enableRouterTracking / enableGlobalErrors / enablePerformanceMetrics | true | Feature flags |

What lands in Tempo

page_load, js_error, journey_step, cta_click, cta_response, form_complete, field_input, field_error, screen_buffering, plus one span per API call from the interceptor.

Common attributes on every span: user.hash, session.id, page.route, service.name, deployment.environment, browser metadata, and whatever you put in customAttributes.

Notes

piiSalt makes the hash one-way, but a 10-digit mobile has only 10^10 possible values — anyone holding the salt can brute-force it. The salt ships in a browser bundle, so treat this as removing plaintext PII at rest, not as protection against a determined attacker. Server-side pseudonymisation is the stronger answer if that threat matters.

Build

npm install
npm run build     # rollup -> dist/

prepublishOnly runs the build, so npm publish always ships a fresh dist/.