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

@playruo/embed

v1.8.2

Published

React SDK to embed Playruo with postMessage API.

Readme

@playruo/embed

React SDK to embed Playruo via iframe + postMessage.

Documentation

  • Integrator overview and React/vanilla guides: docs/
  • Protocol reference for webapp ↔ SDK changes: DOCUMENTATION.md
  • Customer Notion pages are generated from docs/ via npm run docs:notion:dry-run / npm run docs:notion:publish

Windowed launch

PlayruoEmbed requests browser fullscreen on the iframe when the user starts a demo. This remains the default behavior.

Set enableWindowedLaunch to true to skip the parent fullscreen request and start the experience inside the current iframe bounds:

<PlayruoEmbed
  operation="iframe"
  enableWindowedLaunch
/>

Campaigns with several operations

operation is the campaign path. When the campaign holds more than one operation, name the one to open with operationKey, sent as ?op=:

<PlayruoEmbed
  operation="crypticalpath"
  operationKey="crypticalpath-fr"
/>

Passing it inside operation ("crypticalpath?op=...") still works and warns: it was the only way before this prop existed. operationKey wins over it. Other query parameters in operation are kept as they are.

Host-owned visitor identity

By default the SDK stores a UUID in localStorage["playruo_uuid"] and answers playruo_uuid_request with it. Pass clientFingerprint when the host already has a stable visitor id (account id, CRM id, …): that value is answered as uuid instead, and localStorage is left alone. Playruo derives the session fingerprint from it.

<PlayruoEmbed
  operation="crypticalpath"
  clientFingerprint={visitorId}
/>

A vanilla host answers the same way, with no React:

iframe.contentWindow.postMessage(
  {
    type: "playruo_uuid_response",
    requestId,
    uuid: visitorId,
  },
  "https://playruo.live",
);

resolveVisitorUuid(visitorId) from this package is the shared helper both paths use. A blank or whitespace-only value is ignored and the SDK-managed UUID is used.

Password protected operations

A protected operation renders no form of its own: it announces the gate and the host collects the password. Read the gate from renderState and answer with the actions:

<PlayruoEmbed
  operation="crypticalpath"
  onPasswordRequired={() => setAsking(true)}
  onPasswordResult={({ success }) => setAsking(!success)}
  renderState={({ password, actions }) =>
    password.required && !password.unlocked ? (
      <PasswordForm error={password.error} onSubmit={actions.submitPassword} />
    ) : null
  }
/>

The announce is emitted once, when the operation's configuration is loaded, so a host that mounts later misses it: call actions.requestPassword() to have it sent again. password.checked tells the two silences apart — an operation that has not answered yet, and one that answered it is not protected.

password.required stays true after a successful unlock, so read password.unlocked for the gate itself. A refusal carries a code in password.error, typed as PlayruoPasswordErrorCode.

Message origin

Messages are only accepted from the iframe's own window and from the origin operation/baseUrl point at, and every message sent to the iframe is addressed to that same origin rather than to "*". A playable served from an origin other than the one the embed URL was built with is therefore ignored.

Events forwarded one level up, to the host page's own parent, still go to "*": that origin is not something this package can know.

Event forwarding

When the embedded Playruo iframe sends { type: "playruo_event", data }, the React package forwards the payload through onEvent(data).

If the package host is itself inside another iframe, the same message is also forwarded one level up with window.parent.postMessage({ type: "playruo_event", data }, "*").