Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

sysend

Package Overview
Dependencies
Maintainers
1
Versions
41
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

sysend - npm Package Compare versions

Comparing version 1.15.0 to 1.16.0

2

package.json
{
"name": "sysend",
"version": "1.15.0",
"version": "1.16.0",
"description": "Web application synchronization between different tabs",

@@ -5,0 +5,0 @@ "main": "sysend.js",

@@ -5,4 +5,4 @@ <p align="center">

[![npm](https://img.shields.io/badge/npm-1.15.0-blue.svg)](https://www.npmjs.com/package/sysend)
![bower](https://img.shields.io/badge/bower-1.15.0-yellow.svg)
[![npm](https://img.shields.io/badge/npm-1.16.0-blue.svg)](https://www.npmjs.com/package/sysend)
![bower](https://img.shields.io/badge/bower-1.16.0-yellow.svg)
![downloads](https://img.shields.io/npm/dt/sysend.svg)

@@ -109,2 +109,51 @@ [![jsdelivr](https://img.shields.io/jsdelivr/npm/hm/sysend)](https://www.jsdelivr.com/package/npm/sysend)

```javascript
let list = [];
sysend.track('open', data => {
if (data.id !== sysend.id) {
list.push(data);
populate_list(list);
}
});
sysend.track('close', data => {
list = list.filter(tab => data.id !== tab.id);
populate_list(list);
});
sysend.track('ready', () => {
sysend.list().then(tabs => {
list = tabs;
populate_list(list);
});
});
function populate_list() {
select.innerHTML = '';
list.forEach(tab => {
const option = document.createElement('option');
option.value = tab.id;
option.innerText = tab.id;
select.appendChild(option);
});
}
```
In version 1.16.0 this code was abstracted into:
```javascript
sysend.track('update', (list) => {
populate_list(list);
});
```
This can be simplified with point free style:
```javascript
sysend.track('update', populate_list);
```
### RPC mechanism
In version 1.15.0 new API was added called `rpc()` (build on top of tracking mechanism) that allow to use RPC (Remote Procedure Call) between open windows/tabs.

@@ -140,8 +189,2 @@

### Security protection
Since version 1.10.0 as a security mesure Cross-Domain communication has been limited to only those domains that are allowed.
To allow domain to listen to sysend communication you need to specify channel inside iframe. You need add your origins to the
`sysend.channel()` function (origin is combination of protocol domain and optional port).
### Serialization

@@ -172,2 +215,9 @@

### Security protection
Since version 1.10.0 as a security mesure Cross-Domain communication has been limited to only those domains that are allowed.
To allow domain to listen to sysend communication you need to specify channel inside iframe. You need add your origins to the
`sysend.channel()` function (origin is combination of protocol domain and optional port).
## Demos

@@ -196,4 +246,4 @@

| `list()` | returns a Promise of objects `{id:<UUID>, primary}` for other windows, you can use those to send a message with `post()` | NA | 1.6.0 |
| `track(event, callback)` | track inter window communication events | event - any of the strings: `"open"`, `"close"`, `"primary"`, <br>`"secondary"`, `"message"`<br>callback - different function depend on the event:<br>* `"message"` - `{data, origin}` - where data is anything the `post()` sends, and origin is `id` of the sender.<br>* `"open"` - `{count, primary, id}` when new window/tab is opened<br>* `"close"` - `{count, primary, id, self}` when window/tab is closed<br>* `"primary"` and `"secondary"` function has no arguments and is called when window/tab become secondary or primary.<br>* `"ready"` - event when tracking is ready. | 1.6.0 except `ready` - 1.10.0 |
| `untrack(event [,callback])` | remove single event listener all listeners for a given event | event - any of the strings `'open'`, `'close'`, `'primary'`, `'secondary'`, or `'message'`. | 1.6.0 |
| `track(event, callback)` | track inter window communication events | event - any of the strings: `"open"`, `"close"`, `"primary"`, <br>`"secondary"`, `"message"`, `"update"`<br>callback - different function depend on the event:<br>* `"message"` - `{data, origin}` - where data is anything the `post()` sends, and origin is `id` of the sender.<br>* `"open"` - `{count, primary, id}` when new window/tab is opened<br>* `"close"` - `{count, primary, id, self}` when window/tab is closed<br>* `"primary"` and `"secondary"` function has no arguments and is called when window/tab become secondary or primary.<br>* `"ready"` - event when tracking is ready. | 1.6.0 except `ready` - 1.10.0 and `update` - 1.16.0 |
| `untrack(event [,callback])` | remove single event listener all listeners for a given event | event - any of the strings `'open'`, `'close'`, `'primary'`, `'secondary'`, `'message'`, or `'update'`. | 1.6.0 |
| `isPrimary()` | function returns true if window is primary (first open or last that remain) | NA | 1.6.0 |

@@ -200,0 +250,0 @@ | `channel()` | function restrict cross domain communication to only allowed domains. You need to call this function on proxy iframe to limit number of domains (origins) that can listen and send events. | any number of origins (e.g. 'http://localhost:8080' or 'https://jcubic.github.io') you can also use valid URL. | 1.10.0 |

/**@license
* sysend.js - send messages between browser windows/tabs version 1.15.0
* sysend.js - send messages between browser windows/tabs version 1.16.0
*

@@ -8,20 +8,21 @@ * Copyright (C) 2014-2023 Jakub T. Jankiewicz <https://jcubic.pl/me>

*/
type callback = (message: any, event: string) => void;
type callback = (message: unknown, event: string) => void;
interface Sysend {
id: string;
broadcast(event: string, data?: any): void;
emit(event: string, data?: any): void;
broadcast(event: string, data?: unknown): void;
emit(event: string, data?: unknown): void;
on(event: string, callback: callback): void;
off(event: string, callback?: callback): void;
proxy(...args: string[]): void;
serializer(to: (data: any) => string, from: (data: string) => any): void;
serializer(to: (data: unknown) => string, from: (data: string) => unknown): void;
track(event: 'open', callback: (data: {id: string, count: number, primary: boolean}) => void): void;
track(event: 'close', callback: (data: {id: string, count: number, primary: boolean, self: boolean}) => void): void;
track(event: 'primary', callback: () => void): void;
track(event: 'message', callback: (payload: {data: any, origin: string}) => void): void;
track(event: 'message', callback: (payload: {data: unknown, origin: string}) => void): void;
track(event: 'secondary', callback: () => void): void;
untrack(event: 'open' | 'close' | 'primary' | 'secondary' | 'message', fn?: (input?: any) => void): void;
track(event: 'update', callback: (payload: Array<{ id: string, primary: boolean }>) => void): void;
untrack(event: 'open' | 'close' | 'primary' | 'secondary' | 'message' | 'update', fn?: (input?: unknown) => void): void;
list(): Promise<Array<{ id: string, primary: boolean }>>;
post(target: string, data?: any): void;
post(target: string, data?: unknown): void;
channel(...domains: string[]): void;

@@ -28,0 +29,0 @@ isPrimary(): boolean;

/**@license
* sysend.js - send messages between browser windows/tabs version 1.15.0
* sysend.js - send messages between browser windows/tabs version 1.16.0
*

@@ -24,3 +24,3 @@ * Copyright (C) 2014-2023 Jakub T. Jankiewicz <https://jcubic.pl/me>

var uniq_prefix = '___sysend___';
var prefix_re = new RegExp(uniq_prefix);
var prefix_re = new RegExp('^' + uniq_prefix);
var random_value = Math.random();

@@ -57,3 +57,4 @@ var serializer = {};

visbility: [],
ready: []
ready: [],
update: []
};

@@ -143,3 +144,3 @@ var events = Object.keys(handlers);

},
off: function(event, fn) {
off: function(event, fn, internal = false) {
if (callbacks[event]) {

@@ -152,3 +153,3 @@ if (fn) {

}
} else {
} else if (internal && is_internal(event) || !internal) {
callbacks[event] = [];

@@ -159,3 +160,6 @@ }

},
track: function(event, fn) {
track: function(event, fn, internal = false) {
if (internal) {
fn[Symbol.for(uniq_prefix)] = true;
}
if (events.includes(event)) {

@@ -166,6 +170,12 @@ handlers[event].push(fn);

},
untrack: function(event, fn) {
untrack: function(event, fn, internal = false) {
if (events.includes(event) && handlers[event].length) {
if (fn === undefined) {
handlers[event] = [];
if (internal) {
handlers[event] = [];
} else {
handlers[event] = handlers[event].filter(fn => {
return !fn[Symbol.for(uniq_prefix)];
});
}
} else {

@@ -180,3 +190,3 @@ handlers[event] = handlers[event].filter(function(handler) {

post: function(target, data) {
return sysend.broadcast('__message__', {
return sysend.broadcast(make_internal('__message__'), {
target: target,

@@ -193,3 +203,3 @@ data: data,

const ids = [];
sysend.on('__window_ack__', function(data) {
sysend.on(make_internal('__window_ack__'), function(data) {
if (data.origin.target === target_id && data.origin.id === id) {

@@ -202,3 +212,3 @@ ids.push({

});
sysend.broadcast('__window__', { id: marker });
sysend.broadcast(make_internal('__window__'), { id: marker });
timer().then(function() {

@@ -245,3 +255,3 @@ resolve(ids);

}
});
}, true);
sysend.post(id, { method, id: req_id, type: req, args });

@@ -273,3 +283,3 @@ const timer = setTimeout(() => {

}
});
}, true);
const error_msg = 'You need to specify the target window/tab';

@@ -397,6 +407,14 @@ return Object.fromEntries(Object.keys(object).map(name => {

// -------------------------------------------------------------------------
function make_internal(name) {
return uniq_prefix + name;
}
// -------------------------------------------------------------------------
function is_internal(name) {
return name.match(prefix_re);
}
// -------------------------------------------------------------------------
// :: valid sysend message
// -------------------------------------------------------------------------
function is_sysend_post_message(e) {
return typeof e.data === 'string' && e.data.match(prefix_re);
return typeof e.data === 'string' && is_internal(e.data);
}

@@ -446,3 +464,3 @@ // -------------------------------------------------------------------------

function get(key) {
return localStorage.getItem(uniq_prefix + key);
return localStorage.getItem(make_internal(key));
}

@@ -453,3 +471,3 @@ // -------------------------------------------------------------------------

if (id == 0) {
localStorage.setItem(uniq_prefix + key, random_value);
localStorage.setItem(make_internal(key), random_value);
}

@@ -572,3 +590,3 @@ localStorage.setItem(uniq_prefix + key, value);

trigger(handlers.primary);
sysend.emit('__primary__');
sysend.emit(make_internal('__primary__'));
}

@@ -587,2 +605,5 @@ // -------------------------------------------------------------------------

}
// -------------------------------------------------------------------------
setup_update_tracking();
// -------------------------------------------------------------------------
function setup_ls() {

@@ -615,2 +636,29 @@ // we need to clean up localStorage if broadcast called on unload

// -------------------------------------------------------------------------
function setup_update_tracking() {
let list = [];
function update() {
trigger(handlers.update, list);
}
sysend.track('open', data => {
if (data.id !== sysend.id) {
list.push(data);
update();
}
}, true);
sysend.track('close', data => {
list = list.filter(tab => data.id !== tab.id);
update();
}, true);
sysend.track('ready', () => {
sysend.list().then(tabs => {
list = tabs;
update();
});
}, true);
}
// -------------------------------------------------------------------------
function init() {

@@ -669,13 +717,13 @@ if (typeof window.BroadcastChannel === 'function') {

}
});
}, true);
sysend.on('__primary__', function() {
sysend.on(make_internal('__primary__'), function() {
has_primary = true;
});
sysend.on('__open__', function(data) {
sysend.on(make_internal('__open__'), function(data) {
var id = data.id;
target_count++;
if (primary) {
sysend.broadcast('__ack__');
sysend.broadcast(make_internal('__ack__'));
}

@@ -692,3 +740,3 @@ trigger(handlers.open, {

sysend.on('__ack__', function() {
sysend.on(make_internal('__ack__'), function() {
if (!primary) {

@@ -699,3 +747,3 @@ trigger(handlers.secondary);

sysend.on('__close__', function(data) {
sysend.on(make_internal('__close__'), function(data) {
--target_count;

@@ -720,4 +768,4 @@ var last = target_count === 1;

sysend.on('__window__', function(data) {
sysend.broadcast('__window_ack__', {
sysend.on(make_internal('__window__'), function(data) {
sysend.broadcast(make_internal('__window_ack__'), {
id: target_id,

@@ -729,3 +777,3 @@ origin: data.id,

sysend.on('__message__', function(data) {
sysend.on(make_internal('__message__'), function(data) {
if (data.target === 'primary' && primary) {

@@ -739,3 +787,3 @@ trigger(handlers.message, data);

addEventListener('beforeunload', function() {
sysend.emit('__close__', { id: target_id, wasPrimary: primary });
sysend.emit(make_internal('__close__'), { id: target_id, wasPrimary: primary });
}, { capture: true });

@@ -753,3 +801,3 @@

}
sysend.emit('__open__', {
sysend.emit(make_internal('__open__'), {
id: target_id,

@@ -756,0 +804,0 @@ primary: primary

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc