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 🙏

© 2024 – Pkg Stats / Ryan Hefner

post-robot

v10.0.46

Published

Simple postMessage based server.

Downloads

184,387

Readme

post-robot [:]-\-<

npm version

Cross domain post-messaging on the client side, using a simple listener/client pattern.

Send a message to another window, and:

Serialization

post-robot will serialize and deserialize the following data types in messages:

  • Objects, arrays, strings, numbers, booleans, null
    • Note: this includes any JSON-serializable types
  • Functions
  • Promises
    • Note: deserialized promises will be instances of ZalgoPromise
  • Error objects
    • e.g. new Error("This error will self-destruct in 10, 9, 8...")
  • Regex objects
    • e.g. /[a-zA-Z0-9]*/

Simple listener and sender

// Set up a listener

postRobot.on('getUser', function(event) {

    // Have it return some data to the calling window

    return {
        id:   1234,
        name: 'Zippy the Pinhead',

        // Yep, we're even returning a function to the other window!

        logout: function() {
            return $currentUser.logout();
        }
    };
});
// Call the listener, on a different window, on a different domain

postRobot.send(someWindow, 'getUser', { id: 1337 }).then(function(event) {
    var user = event.data;

    console.log(event.source, event.origin, 'Got user:', user);

    // Call the user.logout function from the other window!

    user.logout();

}).catch(function(err) {

    // Handle any errors that stopped our call from going through

    console.error(err);
});

Listener with promise response

postRobot.on('getUser', function(event) {

    return getUser(event.data.id).then(function(user) {
        return {
            name: user.name
        };
    });
});

One-off listener

postRobot.once('getUser', function(event) {

    return {
        name: 'Noggin the Nog'
    };
});

Cancelling a listener

var listener = postRobot.on('getUser', function(event) {
    return {
        id:   event.data.id,
        name: 'Zippy the Pinhead'
    };
});

listener.cancel();

Listen for messages from a specific window

postRobot.on('getUser', { window: window.parent }, function(event) {

    return {
        name: 'Guybrush Threepwood'
    };
});

Listen for messages from a specific domain

postRobot.on('getUser', { domain: 'http://zombo.com' }, function(event) {

    return {
        name: 'Manny Calavera'
    };
});

Set a timeout for a response

postRobot.send(someWindow, 'getUser', { id: 1337 }, { timeout: 5000 }).then(function(event) {
    console.log(event.source, event.origin, 'Got user:', event.data.name);

}).catch(function(err) {
    console.error(err);
});

Send a message to a specific domain

postRobot.send(someWindow, 'getUser', { id: 1337 }, { domain: 'http://zombo.com' }).then(function(event) {
    console.log(event.source, event.origin, 'Got user:', event.data.name);
});

Async / Await

postRobot.on('getUser', async ({ source, origin, data }) => {

    let user = await getUser(data.id);

    return {
        id:   data.id,
        name: user.name
    };
});
try {
    let { source, origin, data } = await postRobot.send(someWindow, `getUser`, { id: 1337 });
    console.log(source, origin, 'Got user:', data.name);

} catch (err) {
    console.error(err);
}

Secure Message Channel

For security reasons, it is recommended that you always explicitly specify the window and domain you want to listen to and send messages to. This creates a secure message channel that only works between two windows on the specified domain:

postRobot.on('getUser', { window: childWindow, domain: 'http://zombo.com' }, function(event) {
    return {
        id:   event.data.id,
        name: 'Frodo'
    };
});
postRobot.send(someWindow, 'getUser', { id: 1337 }, { domain: 'http://zombo.com' }).then(function(event) {
    console.log(event.source, event.origin, 'Got user:', event.data.name);

}).catch(function(err) {
    console.error(err);
});

Functions

Post robot lets you send across functions in your data payload, fairly seamlessly.

For example:

postRobot.on('getUser', function(event) {
    return {
        id:     event.data.id,
        name:   'Nogbad the Bad',

        logout: function() {
            currentUser.logout();
        }
    };
});
postRobot.send(myWindow, 'getUser', { id: 1337 }).then(function(event) {
    var user = event.data;

    user.logout().then(function() {
        console.log('User was logged out');
    });
});

The function user.logout() will be called on the original window. Post Robot transparently messages back to the original window, calls the function that was passed, then messages back with the result of the function.

Because this uses post-messaging behind the scenes and is therefore always async, user.logout() will always return a promise, and must be .then'd or awaited.

Parent to popup messaging

Unfortunately, IE blocks direct post messaging between a parent window and a popup, on different domains.

In order to use post-robot in IE9+ with popup windows, you will need to set up an invisible 'bridge' iframe on your parent page:

   [ Parent page ]

+---------------------+          [ Popup ]
|        xx.com       |
|                     |      +--------------+
|  +---------------+  |      |    yy.com    |
|  |    [iframe]   |  |      |              |
|  |               |  |      |              |
|  | yy.com/bridge |  |      |              |
|  |               |  |      |              |
|  |               |  |      |              |
|  |               |  |      |              |
|  |               |  |      +--------------+
|  +---------------+  |
|                     |
+---------------------+

a. Use the special ie build of post-robot: dist/post-robot.ie.js.

b. Create a bridge path on the domain of your popup, for example http://yy.com/bridge.html, and include post-robot:

<script src="http://yy.com/js/post-robot.ie.js"></script>

c. In the parent page on xx.com which opens the popup, include the following javascript:

<script>
    postRobot.bridge.openBridge('http://yy.com/bridge.html');
</script>

Now xx.com and yy.com can communicate freely using post-robot, in IE.