Code Monkey home page Code Monkey logo

really-simple-xdm's Introduction

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.

really-simple-xdm's People

Contributors

gsanta avatar katona avatar

Stargazers

 avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

Forkers

gsanta

really-simple-xdm's Issues

Timeout for function calls

At the moment the client waits forever for responses of function call messages sent to the server. There should be a timeout for it.

Provide a way of disconnecting clients

There is no way of 'stopping' the client at the moment, which means even if the reference to it is lost, it is still registered to the window for 'message' events.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.