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

@sendoracloud/sdk-web

v2.20.0

Published

Sendora Cloud Web SDK — analytics, feature flags, surveys, in-app messaging, chatbot, auth, deep links (Branch / Firebase parity). Zero dependencies, TypeScript, SSR-safe.

Downloads

2,788

Readme

@sendoracloud/sdk-web

Official SendoraCloud Web SDK — analytics, feature flags, surveys, in-app messaging, and a chatbot widget. Zero runtime dependencies, TypeScript-first, SSR-safe.

Full docs: sendoracloud.com/sdks

Install

npm install @sendoracloud/sdk-web

Quick start

import SendoraCloud from "@sendoracloud/sdk-web";

const sendora = SendoraCloud.init({
  apiKey: "pk_live_...", // publishable key — never a secret (sk_...) key
});

// Grant consent (GDPR/ePrivacy). Events are buffered until this is called.
sendora.consent.grant();

// Track an event
sendora.track("button.clicked", { buttonId: "signup" });

// Identify a signed-in user. `identityToken` is an HMAC of userId signed by
// your backend with your SendoraCloud secret key — this prevents spoofing.
sendora.identify(
  "user_123",
  { email: "[email protected]" },
  { identityToken: "<HMAC from your backend>" },
);

// Feature flags
const enabled = await sendora.flags.isEnabled("new-checkout");

// In-app messages (rendering is your responsibility — use the sanitizer)
sendora.messages.onDisplay((msg) => {
  const safe = SendoraCloud.sanitizeHtml(msg.content.body);
  // render `safe` with innerHTML
});
sendora.messages.startPolling();

// Cleanup
sendora.destroy();

Security model

The SDK is designed for hostile browser environments:

  • Secret-key refusal. init() throws if given a key starting with sk_.
  • HTTPS-only. apiUrl overrides must be https:// (except http://localhost).
  • No eval, no dynamic code. Zero runtime deps.
  • CSPRNG-backed IDs. Anonymous, session, and chat IDs use crypto.getRandomValues.
  • Identity tokens. identify() accepts an identityToken (HMAC of userId signed by your backend). When the SendoraCloud project is in strict-identity mode, unsigned claims are rejected server-side.
  • Input validation. Event names must be [A-Za-z0-9._:-]{1,128}; properties cap at 32 KB, depth 5; prototype-pollution keys (__proto__, constructor, prototype) are blocked.
  • Consent gating. Events buffer in memory until consent.grant() is called.
  • Exponential backoff + circuit breaker. Failed batches retry with min(60s, 2^n) delay and drop after 10 consecutive failures — the SDK will not DDoS your own API on outage.
  • HTML sanitizer. SendoraCloud.sanitizeHtml(html) allow-lists a small set of tags for rendering server-provided message/survey bodies. Always run server content through it before using innerHTML.
  • URL sanitizer. SendoraCloud.safeUrl(u) returns undefined for javascript:, data:, and other script-bearing schemes.
  • No PII in URLs by default. Tracked URLs drop query strings unless you set stripQueryParams: false.
  • No persisted userId by default. We don't write your authenticated userId to localStorage (opt-in via persistUserId: true).

Config

| Option | Type | Default | Notes | | - | - | - | - | | apiKey | string | — | Publishable key (pk_...). Required. | | apiUrl | string | https://api.sendoracloud.com | HTTPS enforced. | | projectId | string | — | Scope events to a project. | | defaultConsent | boolean | false | Set to true to opt in immediately. | | stripQueryParams | boolean | true | Drop ? from page URLs to avoid PII leaks. | | persistUserId | boolean | false | Store userId in localStorage. | | autoTrack | boolean | object | true | Auto-collected lifecycle events. true = enable all (page views on history.pushState + popstate, session.start on idle expiry, app.opened per page load, app.foregrounded/app.backgrounded on visibility flips). Pass { pageViews?, sessionStart?, appOpen?, appBackground? } for granular control, or false to disable. | | sessionIdleMs | number | 1800000 (30 min) | Idle threshold for session expiry. After this much inactivity the next event emits a fresh session.start. | | flushInterval | number | 5000 | Event flush interval in ms. | | maxQueueSize | number | 20 | Flush when queue reaches this size. | | debug | boolean | false | Log method/path/status (never keys or bodies). |

License

Apache-2.0 © SendoraCloud