Is EventEmitter for communication between tabs.
- Cross-domain communication
- SharedWorker or fallback to localStorage
- IE 8+, Chrome 10+, FireFox 10+, Opera 10+, Safari 6+
- Test coverage (run)
// All tabs
wormhole().on("coords", function (x, y) {
console.log(x, y);
});
// Some tab
wormhole().emit("coords", [5, 10]);
- 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");
// 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);
});
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) {
// ..
})
;
// 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]
})
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]
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);
});
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(key, data);
});
wormhole.store.on("change:prop", function (key, value) {
console.log(key, value);
});
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.
Not enabled by default, but:
<script>window.wormhole = {workers: true};</script>
<script src="/vendor/wormhole.js"></script>