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

really-simple-xdm

v1.1.3

Published

Experimental Cross Domain Messaging library based on Javascript Proxies.

Downloads

12

Readme

really-simple-xdm

CircleCI

Experimental JavaScript Cross Domain Messaging library based on JavaScript proxies.

The goal of this library is to simplify cross domain messaging in browsers, that is, making the communication with a Javascript object in a iframe (almost) as simple as it were a local one.

Quick Start

Let's assume that we would like to call Math.abs(-2), if Math were a local object, then the call would look like this:

console.log(Math.abs(-2)); // Prints '2'

If Math is in an iframe, calling it with really-simple-xdm is demonstrated below.

Initialization in the iframe

The first step is to expose the service object (Math in our case) by creating a server:

import { createServer } from 'really-simple-xdm';

const server = createServer({ serviceObject: Math, targetOrigin: "*" });
server.serve();

createServer accepts a config object which contains the service object to be exposed (serviceObject) and the origin of the target frame (targetOrigin). Messages will be sent to and accepted only from the target origin (see the documentation of postMessage for more information).

Initialization in the host page

In the host page a client has to be made which connects to the server created above.

import { createClient } from 'really-simple-xdm';

const iframeElement = document.getElementById('testFrame'); // the id of the frame containing the `Math` object to be called
const mathProxyPromise = createClient({ targetWindow: iframeElement.contentWindow, targetOrigin: "*" }); // 'mathProxyPromise' is a promise which resolves with the proxy of 'Math'

createClient expects a config object which contains the window containing the server object (targetWindow) and the origin of the target (targetOrigin).

Using the object

Now, with everything is setup, the actual call would be the following:

mathProxyPromise.then(mathProxy => {
    mathProxy.abs(-2).then(result => console.log(result)); // Prints '2'
});

If we were to use async functions, then the client code would be as simple as:

const mathProxy = await createClient({ targetWindow: iframeElement.contentWindow, targetOrigin: "*" });
const result = await mathProxy.abs(-2);
console.log(result);

The createClient function returns a promise which is resolved with a proxy object when the connection is estabilished with the server object in the embedded frame. All the methods of the service object (Math in the example) can be called on the proxy almost the same as if it was the service object itself. The only difference is the calls return a Promise in every case. If the call is successful, then the promise is resolved with the return value if any, if the call fails then the promise is rejected.

Callback support

Functions can also be passed as arguments and when called in the frame, the call will be dispatched to the host page.

Event listeners

Event listeners here are treated as special callbacks: they can be registered and deregistered. For this to work, the server needs some auxiliary information to know the function pairs used to register and deregister the event listener.

import { createServer } from 'really-simple-xdm';

const config = {
    serviceObject: Math,
    targetOrigin: "*",
    events: [ { register: 'on', deregister: 'off' } ]
}
const server = createServer(config);
server.serve();

The events configuration property is an array which describe events provided by the proxied object. It's elements, the EventMetadatas, specify the functions used to register and deregister event listeners for the particular event. This information will be used for book keeping the event listener registrations.

After the server is configured properly, event listeners can be registered on the client:

import { createClient } from 'really-simple-xdm';

const config = {
    targetWindow: document.getElementById('testFrame').contentWindow,
    targetOrigin: "*"
}
const client = await createClient(config);
const clickListener = e => {
    console.log(e);
};
await client.on('click', clickListener); // registering the listener
await client.off('click', clickListener); // deregistration

Note that the register/deregister methods (on and off respectively) return a promise which resolves when the registration/deregistration is completed.

The only difference between normal callbacks and event listeners is callback registrations are not tracked so they can not be deregistered.

Exposing multiple service objects from one iframe

It is possible to expose multiple service objects from one iframe by giving them a name using the name configuration property:

import { createServer } from 'really-simple-xdm';

const mathServer = createServer({ serviceObject: Math, targetOrigin: "*", name: "Math" });
mathServer.serve();

const numberServer = createServer({ serviceObject: Number, targetOrigin: "*", name: "Number" });
numberServer.serve();

The names specified during server creation has to be passed to the clients via the serverName configuration property:

import { createClient } from 'really-simple-xdm';

const targetWindow = document.getElementById('testFrame').contentWindow;
const targetOrigin = "*";

const mathProxy = await createClient({ targetWindow, targetOrigin, serverName: "Math" });
const abs = await mathProxy.abs(-1);
console.log(abs);

const integerProxy = await createClient({ targetWindow, targetOrigin, serverName: "Number" });
const isInteger = await integerProxy.isInteger(1);
console.log(isInteger);

API documentation

See TypeScript type definitions for the API documentation.