README
Wormhole
Is EventEmitter for communication between tabs.
npm i --save-dev wormhole.js
Features
- One connection on WebSocket for all tabs.
- Support Master/Slave
- Cross-domain communication
- SharedWorker or fallback to localStorage
- IE 8+, Chrome 10+, FireFox 10+, Opera 10+, Safari 6+
- Test coverage (run)
Basic example
// All tabs
wormhole().on('coords', function (x, y) {
console.log(x, y);
});
// Some tab
wormhole().emit('coords', [5, 10]);
// Master tab
if (wormhole().master) {
// ..
}
wormhole().on('master', function () {
console.log('Wow!');
});
One connection on WebSocket for all tabs
Module wormhole.js/ws
implements WebSocket-like interface:
https://rubaxa.github.io/wormhole/?ws=y
import WS from 'wormhole.js/ws';
// Create WebScoket (wormhole-socket)
const socket = new WS('ws://echo.websocket.org'); // OR new WS('...', null, hole);
socket.onopen = () => console.log('Connected');
socket.onmessage = ({data}) => console.log('Received:', data);
// Unique event
socket.onmaster = () => {
console.log('Yes, I\'m master!');
};
// Some tab
socket.send({foo: 'bar'})
// All tabs:
// "Received:" {foo: 'bar'}
CORS example
- Create a subdomain, ex.:
http://wormhole.youdomain.com/
; - Copy-paste universal.html into root;
- Check access
http://wormhole.youdomain.com/universal.html
; - Profit.
// http://foo.youdomain.com/
var hole = new wormhole.Universal('http://wormhole.youdomain.com/universal.html');
hole.on('data', function (data) {
console.log(data);
});
// http://bar.youdomain.com/
var hole = new wormhole.Universal('http://wormhole.youdomain.com/universal.html');
hole.emit('data', 'any data');
Master/slave example
// All tabs
(function ($) {
var _cache = {},
_getCacheKey = function (req) {
return req.url + JSON.stringify(req.data);
}
;
// Define remote command (master)
wormhole()['get-data'] = function (req, callback) {
var key = _getCacheKey(req),
promise = _cache[key];
if (!promise) {
_cache[key] = promise = $.get(req.url, req.data);
}
return promise
.done(function (result) {
callback(null, result);
})
.fail(function (err) {
delete _cache[key];
callback(err);
})
;
};
// Get remote data
$.getData = function (url, data) {
var dfd = $.Deferred();
// Calling command on master (from slave... or the master, is not important)
wormhole().call('get-data', { url: url, data: data }, function (err, data) {
if (err) {
dfd.reject(err);
} else {
dfd.resolve(data);
}
});
return dfd.promise();
};
// I'm master!
wormhole().on('master', function () {
// some code
});
})(jQuery);
// Tab #X
$.getData('/path/to/api').then(function (result) {
// Send ajax request
console.log(result);
});
// Tab #Y
$.getData('/path/to/api').then(function (result) {
// From master cache
console.log(result);
});
Peers
wormhole()
.on('peers', function (peers) {
console.log('ids:', peers); // ['tab-id-1', 'tab-id-2', ..]
})
.on('peers:add', function (id) {
// ..
})
.on('peers:remove', function (id) {
// ..
})
;
Executing the command on master
// Register command (all tabs)
wormhole()['foo'] = function (data, next) {
// bla-bla-bla
next(null, data.reverse()); // or `next('error')`
};
// Calling the command (some tab)
wormhole().call('foo', [1, 2, 3], function (err, results) {
console.log(results); // [3, 2, 1]
})
Modules
wormhole.Emitter
Micro event emitter.
- on(type:
String
, fn:Function
):this
- off(type:
String
, fn:Function
):this
- emit(type:
String
[, args:*|Array
]):this
var obj = wormhole.Emitter.apply({}); // or new wormhole.Emitter();
obj.on('foo', function () {
console.log(arguments);
});
obj.emit('foo'); // []
obj.emit('foo', 1); // [1]
obj.emit('foo', [1, 2, 3]); // [1, 2, 3]
wormhole.cors
Wrapper for postMessage
.
// Main-frame
wormhole.cors.on('data', function (data) {
// ...
});
wormhole.cors['some:command'] = function (value) {
return value * 2;
};
// IFrame
wormhole.cors(parent).send({foo: 'bar'});
wormhole.cors(parent).call('some:command', 3, function (err, result) {
console.log(result);
});
wormhole.store
Interface for localStorage
.
- get(key:
String
):*
- set(key:
String
, value:*
) - remove(key:
String
):*
- on(type:
String
, fn:Function
) - off(type:
String
, fn:Function
)
wormhole.store.on('change', function (key, data) {
console.log('change -> ', key, data);
});
wormhole.store.on('change:prop', function (key, value) {
console.log('change:prop -> ', key, value);
});
wormhole.store.set('foo', {bar: 'baz'});
// change -> foo {bar: 'baz'}
wormhole.store.set('prop', {qux: 'ok'});
// change -> prop {qux: 'ok'}
// change:prop -> prop {qux: 'ok'}
Utils
String
wormhole.uuid():A universally unique identifier (UUID) is an identifier standard used in software construction, standardized by the Open Software Foundation (OSF) as part of the Distributed Computing Environment (DCE) (c) wiki.
Function
, delay:Number
[, immediate:Boolean
]):Function
wormhole.debounce(fn:Development
npm test
npm run dev
— run dev watchernpm run build