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

@dysonic/web-replay-chrome-extensions

v0.1.0

Published

Chrome extension runtime and prototype assets for web replay capture

Readme

@dysonic/web-replay-chrome-extensions

Chrome Extension runtime and prototype assets for web session recording and replay. Provides the message bridge, controller, background/content script helpers, and popup utilities needed to build a Chrome Extension on top of the web-replay stack.

Installation

npm install @dysonic/web-replay-chrome-extensions

Architecture

The extension is split into three runtime contexts that communicate via Chrome's message-passing API:

Popup (UI)
  │  ExtensionCommand (RECORDER_START, PAUSE, RESUME, EXPORT, STATUS)
  ▼
Background Script
  │  sendCommandToActiveTab()
  ▼
Content Script (injected into the page)
  │  attachChromeMessageBridge()
  ▼
ExtensionRuntime → ExtensionController → RecorderCore

API

Content Script — attachChromeMessageBridge(runtime?, chromeApi?)

The main entry point for a content script. Listens for ExtensionCommand messages via chrome.runtime.onMessage and dispatches them to the given runtime.

import { attachChromeMessageBridge } from '@dysonic/web-replay-chrome-extensions';

// Uses createLiveExtensionRuntime() + window.chrome by default
attachChromeMessageBridge();

Provide your own runtime or chrome API for testing:

import {
  attachChromeMessageBridge,
  createExtensionRuntime,
  createLiveRrwebAdapter,
} from '@dysonic/web-replay-chrome-extensions';

const adapter = createLiveRrwebAdapter({ maskAllInputs: true });
const runtime = createExtensionRuntime(adapter);
attachChromeMessageBridge(runtime, chrome);

Background Script — sendCommandToActiveTab(chromeApi, command)

Sends an ExtensionCommand to the currently active tab's content script and returns the ExtensionEvent response.

import { sendCommandToActiveTab } from '@dysonic/web-replay-chrome-extensions';

const response = await sendCommandToActiveTab(chrome, { type: 'RECORDER_EXPORT' });
if (response.type === 'EXPORT_READY') {
  console.log(response.payload); // ReplayEnvelope
}

Runtime — createExtensionRuntime(adapter)

Creates an ExtensionRuntime that maps ExtensionCommand objects to controller actions.

import { createExtensionRuntime } from '@dysonic/web-replay-chrome-extensions';

const runtime = createExtensionRuntime(adapter);
runtime.dispatch({ type: 'RECORDER_START' });  // → { type: 'STATUS', payload: { active: true, paused: false } }
runtime.dispatch({ type: 'RECORDER_EXPORT' }); // → { type: 'EXPORT_READY', payload: ReplayEnvelope }

Supported commands:

| Command | Response type | |---|---| | RECORDER_STATUS | STATUS | | RECORDER_START | STATUS | | RECORDER_PAUSE | STATUS | | RECORDER_RESUME | STATUS | | RECORDER_EXPORT | EXPORT_READY |


Controller — createExtensionController(config?)

Lower-level controller that wraps RecorderCore and adds extension-specific lifecycle markers to the customEvents stream.

import { createExtensionController } from '@dysonic/web-replay-chrome-extensions';

const controller = createExtensionController({ maxMinutes: 5 });
controller.start(adapter);
controller.pause();
controller.resume();
const envelope = controller.exportReplay(); // ReplayEnvelope
controller.getStatus();                     // { active, paused }

Popup utilities

import {
  dispatchPopupCommand,
  renderPopupResponse,
  downloadReplayFromResponse,
} from '@dysonic/web-replay-chrome-extensions';

const response = await dispatchPopupCommand(transport, { type: 'RECORDER_EXPORT' });
renderPopupResponse(outputElement, response);
downloadReplayFromResponse(response, (filename, content) => {
  // trigger a file download in the popup
});

Building the extension assets

The extension assets (background, content, and popup scripts) are bundled separately using esbuild via the package's own build script:

cd packages/web-replay-chrome-extensions
pnpm build:extensions

License

MIT