broadcast-channel
Advanced tools
Comparing version 1.0.2 to 1.1.0
@@ -12,2 +12,15 @@ import { isPromise } from './util.js'; | ||
this._isListening = false; | ||
/** | ||
* setting onmessage twice, | ||
* will overwrite the first listener | ||
*/ | ||
this._onMessageListener = null; | ||
this._addEventListeners = { | ||
message: [], | ||
internal: [] | ||
}; | ||
this._preparePromise = null; | ||
@@ -23,2 +36,3 @@ _prepareChannel(this); | ||
time: new Date().getTime(), | ||
type: 'message', | ||
data: msg | ||
@@ -38,20 +52,41 @@ }; | ||
set onmessage(fn) { | ||
var _this2 = this; | ||
var time = new Date().getTime() - 5; | ||
if (this._preparePromise) { | ||
this._preparePromise.then(function () { | ||
_this2.method.onMessage(_this2._state, messageHandler(fn, time), time); | ||
}); | ||
var listenObj = { | ||
time: time, | ||
fn: fn | ||
}; | ||
_removeListenerObject(this, 'message', this._onMessageListener); | ||
if (fn && typeof fn === 'function') { | ||
this._onMessageListener = listenObj; | ||
_addListenerObject(this, 'message', listenObj); | ||
} else { | ||
this.method.onMessage(this._state, messageHandler(fn, time), time); | ||
this._onMessageListener = null; | ||
} | ||
}, | ||
addEventListener: function addEventListener(type, fn) { | ||
var time = new Date().getTime() - 5; | ||
var listenObj = { | ||
time: time, | ||
fn: fn | ||
}; | ||
_addListenerObject(this, type, listenObj); | ||
}, | ||
removeEventListener: function removeEventListener(type, fn) { | ||
var obj = this._addEventListeners[type].find(function (obj) { | ||
return obj.fn === fn; | ||
}); | ||
_removeListenerObject(this, type, obj); | ||
}, | ||
close: function close() { | ||
var _this3 = this; | ||
var _this2 = this; | ||
this.closed = true; | ||
var awaitPrepare = this._preparePromise ? this._preparePromise : Promise.resolve(); | ||
this._onMessageListener = null; | ||
this._addEventListeners.message = []; | ||
return awaitPrepare.then(function () { | ||
return _this3.method.close(_this3._state); | ||
return _this2.method.close(_this2._state); | ||
}); | ||
@@ -81,10 +116,53 @@ }, | ||
function messageHandler(fn, minTime) { | ||
return function (msgObj) { | ||
if (msgObj.time >= minTime) { | ||
fn(msgObj.data); | ||
function _hasMessageListeners(channel) { | ||
if (channel._addEventListeners.message.length > 0) return true; | ||
if (channel._addEventListeners.internal.length > 0) return true; | ||
return false; | ||
} | ||
function _addListenerObject(channel, type, obj) { | ||
channel._addEventListeners[type].push(obj); | ||
_startListening(channel); | ||
} | ||
function _removeListenerObject(channel, type, obj) { | ||
channel._addEventListeners[type] = channel._addEventListeners[type].filter(function (o) { | ||
return o !== obj; | ||
}); | ||
_stopListening(channel); | ||
} | ||
function _startListening(channel) { | ||
if (!channel._isListening && _hasMessageListeners(channel)) { | ||
// someone is listening, start subscribing | ||
var listenerFn = function listenerFn(msgObj) { | ||
channel._addEventListeners[msgObj.type].forEach(function (obj) { | ||
if (msgObj.time >= obj.time) { | ||
obj.fn(msgObj.data); | ||
}; | ||
}); | ||
}; | ||
var time = new Date().getTime() - 5; | ||
if (channel._preparePromise) { | ||
channel._preparePromise.then(function () { | ||
channel._isListening = true; | ||
channel.method.onMessage(channel._state, listenerFn, time); | ||
}); | ||
} else { | ||
channel._isListening = true; | ||
channel.method.onMessage(channel._state, listenerFn, time); | ||
} | ||
}; | ||
}; | ||
} | ||
} | ||
function _stopListening(channel) { | ||
if (channel._isListening && !_hasMessageListeners(channel)) { | ||
// noone is listening, stop subscribing | ||
channel._isListening = false; | ||
var time = new Date().getTime() - 5; | ||
channel.method.onMessage(channel._state, null, time); | ||
} | ||
} | ||
export default BroadcastChannel; |
@@ -18,2 +18,15 @@ 'use strict'; | ||
this._isListening = false; | ||
/** | ||
* setting onmessage twice, | ||
* will overwrite the first listener | ||
*/ | ||
this._onMessageListener = null; | ||
this._addEventListeners = { | ||
message: [], | ||
internal: [] | ||
}; | ||
this._preparePromise = null; | ||
@@ -29,2 +42,3 @@ _prepareChannel(this); | ||
time: new Date().getTime(), | ||
type: 'message', | ||
data: msg | ||
@@ -44,20 +58,41 @@ }; | ||
set onmessage(fn) { | ||
var _this2 = this; | ||
var time = new Date().getTime() - 5; | ||
if (this._preparePromise) { | ||
this._preparePromise.then(function () { | ||
_this2.method.onMessage(_this2._state, messageHandler(fn, time), time); | ||
}); | ||
var listenObj = { | ||
time: time, | ||
fn: fn | ||
}; | ||
_removeListenerObject(this, 'message', this._onMessageListener); | ||
if (fn && typeof fn === 'function') { | ||
this._onMessageListener = listenObj; | ||
_addListenerObject(this, 'message', listenObj); | ||
} else { | ||
this.method.onMessage(this._state, messageHandler(fn, time), time); | ||
this._onMessageListener = null; | ||
} | ||
}, | ||
addEventListener: function addEventListener(type, fn) { | ||
var time = new Date().getTime() - 5; | ||
var listenObj = { | ||
time: time, | ||
fn: fn | ||
}; | ||
_addListenerObject(this, type, listenObj); | ||
}, | ||
removeEventListener: function removeEventListener(type, fn) { | ||
var obj = this._addEventListeners[type].find(function (obj) { | ||
return obj.fn === fn; | ||
}); | ||
_removeListenerObject(this, type, obj); | ||
}, | ||
close: function close() { | ||
var _this3 = this; | ||
var _this2 = this; | ||
this.closed = true; | ||
var awaitPrepare = this._preparePromise ? this._preparePromise : Promise.resolve(); | ||
this._onMessageListener = null; | ||
this._addEventListeners.message = []; | ||
return awaitPrepare.then(function () { | ||
return _this3.method.close(_this3._state); | ||
return _this2.method.close(_this2._state); | ||
}); | ||
@@ -87,10 +122,53 @@ }, | ||
function messageHandler(fn, minTime) { | ||
return function (msgObj) { | ||
if (msgObj.time >= minTime) { | ||
fn(msgObj.data); | ||
function _hasMessageListeners(channel) { | ||
if (channel._addEventListeners.message.length > 0) return true; | ||
if (channel._addEventListeners.internal.length > 0) return true; | ||
return false; | ||
} | ||
function _addListenerObject(channel, type, obj) { | ||
channel._addEventListeners[type].push(obj); | ||
_startListening(channel); | ||
} | ||
function _removeListenerObject(channel, type, obj) { | ||
channel._addEventListeners[type] = channel._addEventListeners[type].filter(function (o) { | ||
return o !== obj; | ||
}); | ||
_stopListening(channel); | ||
} | ||
function _startListening(channel) { | ||
if (!channel._isListening && _hasMessageListeners(channel)) { | ||
// someone is listening, start subscribing | ||
var listenerFn = function listenerFn(msgObj) { | ||
channel._addEventListeners[msgObj.type].forEach(function (obj) { | ||
if (msgObj.time >= obj.time) { | ||
obj.fn(msgObj.data); | ||
}; | ||
}); | ||
}; | ||
var time = new Date().getTime() - 5; | ||
if (channel._preparePromise) { | ||
channel._preparePromise.then(function () { | ||
channel._isListening = true; | ||
channel.method.onMessage(channel._state, listenerFn, time); | ||
}); | ||
} else { | ||
channel._isListening = true; | ||
channel.method.onMessage(channel._state, listenerFn, time); | ||
} | ||
}; | ||
}; | ||
} | ||
} | ||
function _stopListening(channel) { | ||
if (channel._isListening && !_hasMessageListeners(channel)) { | ||
// noone is listening, stop subscribing | ||
channel._isListening = false; | ||
var time = new Date().getTime() - 5; | ||
channel.method.onMessage(channel._state, null, time); | ||
} | ||
} | ||
exports['default'] = BroadcastChannel; |
declare type MethodType = 'node' | 'idb' | 'native' | 'localstorage'; | ||
interface BroadcastChannelEventMap { | ||
"message": MessageEvent; | ||
"messageerror": MessageEvent; | ||
} | ||
export type BroadcastChannelOptions = { | ||
@@ -16,5 +23,10 @@ type?: MethodType, | ||
declare type EventType = 'message' | 'error' | 'internal'; | ||
declare type OnMessageHandler<T> = ((this: BroadcastChannel, ev: T) => any) | null; | ||
/** | ||
* api as defined in | ||
* @link https://html.spec.whatwg.org/multipage/web-messaging.html#broadcasting-to-other-browsing-contexts | ||
* @link https://github.com/Microsoft/TypeScript/blob/master/src/lib/webworker.generated.d.ts#L325 | ||
*/ | ||
@@ -30,5 +42,9 @@ declare class BroadcastChannel<T = any> { | ||
onmessage: ((this: BroadcastChannel, ev: T) => any) | null; | ||
onmessage: OnMessageHandler<T>; | ||
// not defined in the offical standard | ||
addEventListener(type: EventType, OnMessageHandler): void; | ||
removeEventListener(type: EventType, OnMessageHandler): void; | ||
} | ||
export default BroadcastChannel; |
{ | ||
"name": "broadcast-channel", | ||
"version": "1.0.2", | ||
"version": "1.1.0", | ||
"description": "A BroadcastChannel implementation that works with new browsers, older browsers and Node.js", | ||
@@ -5,0 +5,0 @@ "homepage": "https://github.com/pubkey/broadcast-channel#readme", |
@@ -31,13 +31,2 @@ | ||
## Methods: | ||
Depending in which environment this is used, a proper method is automatically selected to ensure it always works. | ||
| Method | Used in | Description | | ||
| ---------------- | --------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- | | ||
| **Native** | [Modern Browsers](https://caniuse.com/broadcastchannel) | If the browser supports the BroadcastChannel-API, this method will be used because it is the fastest | | ||
| **IndexedDB** | [Browsers with WebWorkers](https://caniuse.com/#feat=indexeddb) | If there is no native BroadcastChannel support, the IndexedDB method is used because it supports messaging between browser-tabs, iframes and WebWorkers | | ||
| **LocalStorage** | [Older Browsers](https://caniuse.com/#feat=namevalue-storage) | In older browsers that do not support IndexedDb, a localstorage-method is used | | ||
| **Sockets** | NodeJs | In NodeJs the communication is handled by sockets that send each other messages | | ||
## Usage | ||
@@ -68,2 +57,16 @@ | ||
Add and remove multiple eventlisteners | ||
```js | ||
const BroadcastChannel = require('broadcast-channel'); | ||
const channel = new BroadcastChannel('foobar'); | ||
const handler = msg => console.log(msg); | ||
channel.addEventListener('message', handler); | ||
// remove it | ||
channel.removeEventListener('message', handler); | ||
``` | ||
Close the channel if you do not need it anymore. | ||
@@ -98,2 +101,14 @@ | ||
## Methods: | ||
Depending in which environment this is used, a proper method is automatically selected to ensure it always works. | ||
| Method | Used in | Description | | ||
| ---------------- | --------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- | | ||
| **Native** | [Modern Browsers](https://caniuse.com/broadcastchannel) | If the browser supports the BroadcastChannel-API, this method will be used because it is the fastest | | ||
| **IndexedDB** | [Browsers with WebWorkers](https://caniuse.com/#feat=indexeddb) | If there is no native BroadcastChannel support, the IndexedDB method is used because it supports messaging between browser-tabs, iframes and WebWorkers | | ||
| **LocalStorage** | [Older Browsers](https://caniuse.com/#feat=namevalue-storage) | In older browsers that do not support IndexedDb, a localstorage-method is used | | ||
| **Sockets** | NodeJs | In NodeJs the communication is handled by sockets that send each other messages | | ||
## What this is | ||
@@ -100,0 +115,0 @@ |
119
src/index.js
@@ -20,2 +20,15 @@ import { | ||
this._isListening = false; | ||
/** | ||
* setting onmessage twice, | ||
* will overwrite the first listener | ||
*/ | ||
this._onMessageListener = null; | ||
this._addEventListeners = { | ||
message: [], | ||
internal: [] | ||
}; | ||
this._preparePromise = null; | ||
@@ -29,2 +42,3 @@ _prepareChannel(this); | ||
time: new Date().getTime(), | ||
type: 'message', | ||
data: msg | ||
@@ -50,21 +64,35 @@ }; | ||
const time = new Date().getTime() - 5; | ||
if (this._preparePromise) { | ||
this._preparePromise.then(() => { | ||
this.method.onMessage( | ||
this._state, | ||
messageHandler(fn, time), | ||
time | ||
); | ||
}); | ||
const listenObj = { | ||
time, | ||
fn | ||
}; | ||
_removeListenerObject(this, 'message', this._onMessageListener); | ||
if (fn && typeof fn === 'function') { | ||
this._onMessageListener = listenObj; | ||
_addListenerObject(this, 'message', listenObj); | ||
} else { | ||
this.method.onMessage( | ||
this._state, | ||
messageHandler(fn, time), | ||
time | ||
); | ||
this._onMessageListener = null; | ||
} | ||
}, | ||
addEventListener(type, fn) { | ||
const time = new Date().getTime() - 5; | ||
const listenObj = { | ||
time, | ||
fn | ||
}; | ||
_addListenerObject(this, type, listenObj); | ||
}, | ||
removeEventListener(type, fn) { | ||
const obj = this._addEventListeners[type].find(obj => obj.fn === fn); | ||
_removeListenerObject(this, type, obj); | ||
}, | ||
close() { | ||
this.closed = true; | ||
const awaitPrepare = this._preparePromise ? this._preparePromise : Promise.resolve(); | ||
this._onMessageListener = null; | ||
this._addEventListeners.message = []; | ||
return awaitPrepare.then(() => { | ||
@@ -97,11 +125,64 @@ return this.method.close( | ||
function messageHandler(fn, minTime) { | ||
return msgObj => { | ||
if (msgObj.time >= minTime) { | ||
fn(msgObj.data); | ||
function _hasMessageListeners(channel) { | ||
if (channel._addEventListeners.message.length > 0) return true; | ||
if (channel._addEventListeners.internal.length > 0) return true; | ||
return false; | ||
} | ||
function _addListenerObject(channel, type, obj) { | ||
channel._addEventListeners[type].push(obj); | ||
_startListening(channel); | ||
} | ||
function _removeListenerObject(channel, type, obj) { | ||
channel._addEventListeners[type] = channel._addEventListeners[type].filter(o => o !== obj); | ||
_stopListening(channel); | ||
} | ||
function _startListening(channel) { | ||
if (!channel._isListening && _hasMessageListeners(channel)) { | ||
// someone is listening, start subscribing | ||
const listenerFn = msgObj => { | ||
channel._addEventListeners[msgObj.type].forEach(obj => { | ||
if (msgObj.time >= obj.time) { | ||
obj.fn(msgObj.data); | ||
}; | ||
}); | ||
}; | ||
const time = new Date().getTime() - 5; | ||
if (channel._preparePromise) { | ||
channel._preparePromise.then(() => { | ||
channel._isListening = true; | ||
channel.method.onMessage( | ||
channel._state, | ||
listenerFn, | ||
time | ||
); | ||
}); | ||
} else { | ||
channel._isListening = true; | ||
channel.method.onMessage( | ||
channel._state, | ||
listenerFn, | ||
time | ||
); | ||
} | ||
}; | ||
}; | ||
} | ||
} | ||
function _stopListening(channel) { | ||
if (channel._isListening && !_hasMessageListeners(channel)) { | ||
// noone is listening, stop subscribing | ||
channel._isListening = false; | ||
const time = new Date().getTime() - 5; | ||
channel.method.onMessage( | ||
channel._state, | ||
null, | ||
time | ||
); | ||
} | ||
} | ||
export default BroadcastChannel; |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
175197
3991
132