Skip to content

Instantly share code, notes, and snippets.

@maolion
Last active May 18, 2017 09:59
Show Gist options
  • Save maolion/85ce4d8718ad22e58ee7ff9dd23b9cd9 to your computer and use it in GitHub Desktop.
Save maolion/85ce4d8718ad22e58ee7ff9dd23b9cd9 to your computer and use it in GitHub Desktop.
(function() {
let MF = window.MF = window.MF || {};
let defaultMessageChannel = null;
let pendingWorks = [];
let uid = Date.now();
class Message extends MF.Event {
constructor(channelId, id) {
super();
this._id = id;
this._channelId = channelId || Date.now();
this._ns = `${channelId}@${id}`;
this._polling();
}
get ns() {
return this._ns;
}
get channelName() {
return this._channelId;
}
to(id, type, data) {
let timestamp = Date.now();
if (arguments.length == 2 && type && typeof type === 'object') {
data = type;
type = undefined;
}
let messageKey = this._generateMessageKey(id, type, timestamp);
localStorage[messageKey] = JSON.stringify(data == undefined ? null : data);
console.log(`[Post message | channel: ${this._channelId}]`, this._resolveMessage(messageKey));
}
_polling() {
clearInterval(this._pollingTimerHandle)
this._pollingTimerHandle = setInterval(this._query.bind(this), 600);
}
_query() {
let keys = Object.keys(localStorage).filter(key => key.startsWith(this._ns));
if (!keys.length) {
return;
}
for (let key of keys) {
let message = this._resolveMessage(key);
console.log(`[Get message | channel: ${this._channelId}]`, message);
this.emit('message', [message]);
if (message.type) {
this.emit(message.type, [message.data, message]);
}
localStorage.removeItem(key);
}
}
_generateMessageKey(id, type, timestamp) {
return `${this._channelId}@${id}[@${this._id} - ${timestamp}]${type ? '('+ type +')' : ''}#${uid++}`;
}
_resolveMessage(key) {
let group = key.match(/^[^@]+@([^\]]+)\[@(.+) - (\d+)\](?:\((.+)\))?#(.*)$/) || [];
let data = localStorage[key];
return {
channelId: this._channelId,
to: group[1],
from: group[2],
timestamp: parseInt(group[3]),
type: group[4],
uid: parseInt(group[5]),
data: data ? JSON.parse(data) : null,
};
}
// statics
static initDefaultMessageChannel(userId) {
if (defaultMessageChannel) {
return;
}
defaultMessageChannel = new Message('mf.default', userId);
while(pendingWorks.length) pendingWorks.shift()();
}
static on(type, handler) {
if (!defaultMessageChannel) {
pendingWorks.push(() => {
Message.on(type, handler);
});
return;
}
defaultMessageChannel.on(type, handler);
}
static un(type, handler) {
if (!defaultMessageChannel) {
pendingWorks.push(() => {
Message.un(type, handler);
});
return;
}
defaultMessageChannel.un(type, handler);
}
static once(type, handler) {
if (!defaultMessageChannel) {
pendingWorks.push(() => {
Message.once(type, handler);
});
return;
}
defaultMessageChannel.once(type, handler);
}
static to(userId, type, data) {
if (!defaultMessageChannel) {
pendingWorks.push(() => {
Message.to(userId, type, data);
});
return;
}
defaultMessageChannel.to(userId, type, data);
}
}
MF.Message = Message;
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment