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

@viadialog/viaflow-sdk

v0.0.9

Published

Browser SDK to embed the Viaflow webphone in any host page via an iframe and a typed postMessage bridge. Voice, SMS, agent status, CTI screen pop.

Readme

@viadialog/viaflow-sdk

Browser SDK that embeds the Viaflow web app into any host page via an iframe and exposes a typed JavaScript API for click-to-call, SMS, navigation and call lifecycle events.

Status: scaffold. The Viaflow web app does not yet implement the matching postMessage protocol — until that lands, only the iframe lifecycle (mount / show / hide / destroy) is functional. Action calls and event subscriptions will be silently no-ops on the app side.

Install

The SDK is currently distributed via the internal Viadialog MinIO CDN. npm publish is wired but disabled — see docs/release.md §8 for how to re-enable it.

<script
  src="http://minio-viaflow-prod.in.viadialog.com:8001/cdnstorage/viaflow-sdk/0.0.8/index.global.min.js"
  integrity="sha384-REPLACE_WITH_RELEASE_NOTES_HASH"
  crossorigin="anonymous"></script>
<script>
  // appUrl defaults to https://viaflow-app.viadialog.com/embedded-banner
  const sdk = new ViaflowSDK.ViaflowSDK();
  sdk.generate();
</script>

The CDN serves two flavours of the IIFE bundle at every versioned URL:

| File | Size | Use for | |---|---|---| | index.global.min.js | ~12 KB | Production. Default. | | index.global.js | ~22 KB | Debugging — readable identifiers and stack traces. |

Each release publishes both SRI hashes in the CHANGELOG entry and in the GitLab CI release log. URLs are immutable: 0.0.8/index.global.min.js always serves the same bytes.

The current endpoint is HTTP and reachable only from the Viadialog network. SRI requires HTTPS for browsers to accept the integrity= attribute on cross-origin scripts loaded from the public internet — fine internally, not yet usable for external integrators.

Usage

import { ViaflowSDK } from "@viadialog/viaflow-sdk";

const sdk = new ViaflowSDK({
  // appUrl defaults to https://viaflow-app.viadialog.com/embedded-banner
  size: "medium",
  position: { bottom: "0", right: "64px" },
  trayicon: true,
});

sdk.generate();

sdk.on("ringingCall", (call) => {
  console.log("incoming call from", call.number);
});

document.querySelector("#call-btn")?.addEventListener("click", () => {
  sdk.dial("+33612345678");
});

Constructor options

| Option | Type | Default | | |--------|------|---------|---| | appUrl | string | https://viaflow-app.viadialog.com/embedded-banner | URL of the Viaflow banner to embed. Override only for staging/dev environments. | | container | string | document.body | DOM id of the parent element. | | type | "fixed" \| "relative" \| "absolute" | "fixed" (or "relative" if container is set) | CSS positioning of the iframe wrapper. | | size | "small" \| "medium" \| "big" \| "auto" | "medium" | Preset width/height. | | position | { top?, bottom?, left?, right? } | { right: "64px", bottom: "0" } | Manual position. | | border | boolean | true | Drop shadow around the iframe. | | animation | boolean | true | Fade-in/out on show/hide. | | backgroundColor | string | — | Background of the iframe wrapper. | | trayicon | boolean | true | Render a tray bubble when the iframe is hidden. | | trayposition | { top?, bottom?, left?, right? } | { bottom: "10px", right: "10px" } | Tray bubble position. | | trayIconUrl | string | placeholder | Override the tray bubble image. |

Methods

Lifecycle

  • sdk.generate() — mount the iframe in the DOM and show it. Returns the HTMLIFrameElement on success.
  • sdk.destroy() — unmount and tear down event listeners.
  • sdk.show() / sdk.hide() / sdk.toggle(force?) — visibility.
  • sdk.isDisplayed() — current visibility.

Actions (host → app)

These all auto-show the iframe except changePage / reload / logout.

  • sdk.dial(number, fromNumber?)
  • sdk.sendSMS(toNumber, message, fromNumber?)
  • sdk.openCallLog(callId)
  • sdk.changePage(page)
  • sdk.reload()
  • sdk.logout()
  • sdk.getCurrentPage()

CTI screen pop

When a call event fires, automatically navigate the host page to a relevant record (case detail, contact lookup, etc.).

sdk.screenPop({
  url: "/cases/{{case_id}}",
  required: ["case_id"],
  on: ["ringingCall"],
});

sdk.screenPop({
  url: "/contacts/lookup?phone={{number}}",
  on: ["ringingCall"],
});

Multiple registrations are evaluated in order — the first one that produces a non-null URL pops, the rest are skipped for that call_id. Useful to express "if there's a case, open it; otherwise fall back to phone lookup".

Template syntax: {{var}} with fallback chain {{var_a|var_b|"literal default"}}. Substitutions are URI-encoded.

Filters:

  • required: ["case_id"] — skip unless the call carries all listed keys
  • whenInbound (default true), whenOutbound (default false), whenTransferred (default false)

SPA hosts: provide a navigate callback to drive your router instead of window.location:

sdk.screenPop({
  url: "/cases/{{case_id}}",
  navigate: (url, call) => router.push(url),
});

Custom logic: use resolve for async CRM lookups, and beforePop to cancel:

sdk.screenPop({
  on: ["ringingCall"],
  resolve: async (call) => {
    const match = await crm.searchByPhone(call.number);
    return match ? `/contacts/${match.id}` : null;
  },
  beforePop: (call) => !document.body.classList.contains("editing"),
});

See examples/screenpop.html for a working mini-CRM with hash routing.

Events (app → host)

const unsubscribe = sdk.on("ringingCall", (call) => { /* ... */ });
unsubscribe();

// or
sdk.off("ringingCall", listener);   // remove one
sdk.off("ringingCall");              // remove all listeners for this event
sdk.offAll();                        // remove every listener

Available events: dialerReady, login, logout, changePage, ringingCall, answeredCall, hangupCall, smsSent, smsReceived. See PROTOCOL.md for payload shapes.

Development

npm install
npm run build         # produces dist/index.{js,cjs,global.js} + .d.ts
npm run typecheck
npm run dev           # build:watch + host server (:3000) + mock server (:3002)

Releasing

See docs/release.md for the full release guide — one-time setup (npm scope, GitLab variables, MinIO bucket, CDN/DNS), the standard release workflow, pre-release (alpha/beta/rc), versioning policy, and pipeline troubleshooting.

Local end-to-end test with the mock app

Until the real Viaflow web app ships the matching postMessage protocol (see PROTOCOL.md), mock/index.html simulates it. It speaks the full protocol: handshake, every event, and auto-responds to dial / sendSMS / changePage with realistic event sequences.

npm run dev

Then open:

  • Host page (loads the SDK): http://localhost:3000/examples/vanilla.html
  • Mock app (rendered inside the iframe): http://localhost:3002/

The host's appUrl defaults to http://localhost:3001 but can be overridden via ?appUrl=… in the URL. Click dial on the host → the mock auto-emits ringingCallansweredCallhangupCall over 5 seconds.