-
Notifications
You must be signed in to change notification settings - Fork 0
/
localmessage.js
108 lines (98 loc) · 3.66 KB
/
localmessage.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
var localMessage = new Class({
/**
*
* @author Rob Pickering [email protected]
* @name localMessage
* @constructor
* @param {string} [prefix] unique namespace prefix for this
* instance of the message class in localStorage.
* @requires ipcortex/MasquradeJS
*/
construct: function(prefix) {
// Stuff we are waiting to post or receive
this.queue = [];
this.prefix = (prefix) ? prefix : "localMessage$";
window.addEventListener('storage', (function(event) {
this._queueRunner(event);
}).bind(this));
},
/**
* @function localMessage.postMessage
* @param {string} name - message name, used by receiving page to listen
* @param {Object} value - opaque object to pass to receiver
* @returns {Promise} a promise which resolves when the message is
* received by the consumer
*/
postMessage: function(name, value) {
return (new Promise((function(resolve, reject) {
this.queue.push({
pop: false,
name: name,
value: value,
ret: {
resolve: resolve,
reject: reject
}
});
this._queueRunner({
key: this.prefix + name
});
}).bind(this)));
},
/**
* @function localMessage.receiveMessage
* @param {string} name - message name we want to listen for
* @returns {Promise} a promise which resolves to the sent message object
*
*/
receiveMessage: function(name) {
return (new Promise((function(resolve, reject) {
this.queue.push({
pop: true,
name: name,
ret: {
resolve: resolve,
reject: reject
}
});
this._queueRunner({
key: this.prefix + name
});
}).bind(this)));
},
_queueRunner: function(ev) {
var item = "";
// Iterate over queue looking for messages that are pending send or receive
this.queue.forEach(function(request) {
var item = localStorage.getItem(this.prefix + request.name);
var itemExists = (item != null && item.length);
if ((!ev || ev.key == this.prefix + request.name) && !request.resolved) {
// This is a pop request and a matching localStorage item has just been posted
if (request.pop && itemExists) {
request.resolved = true;
localStorage.removeItem(this.prefix + request.name);
request.ret.resolve(JSON.parse(item));
}
// This is a push request and matching previous message has just been consumed
else if (!request.pop && !itemExists) {
// Previous post has been received, inform sender and destroy it
if (request.sent && !request.resolved) {
request.resolved = true;
request.ret.resolve(request);
}
// Put next message off queue into localStorage
else {
localStorage.setItem(this.prefix + request.name, JSON.stringify(request.value));
request.sent = true;
}
}
}
}, this);
// Clean up resolved requests
this.queue.slice().reverse().forEach(function(r, i, o) {
if (r.resolved) {
this.queue.splice(o.length - 1 - i, 1);
}
}, this);
}
});