cookiesync
Advanced tools
Comparing version 1.4.0 to 2.0.1
171
lib/index.js
@@ -1,166 +0,5 @@ | ||
'use strict'; | ||
Object.defineProperty(exports, "__esModule", { | ||
value: true | ||
}); | ||
exports.default = cookiesync; | ||
var _invariant = require('invariant'); | ||
var _invariant2 = _interopRequireDefault(_invariant); | ||
var _reactCookie = require('react-cookie'); | ||
var _reactCookie2 = _interopRequireDefault(_reactCookie); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
var mechanism = 'cookiesync'; | ||
/** | ||
* Creates a synchronizer which uses cookie polling to transmit objects to other tabs. | ||
* @param {string} key The key to synchronize on. | ||
* @param {function} action The action to run when trigger is executed. Should return the payload to be transmitted to the handlers on other tabs. | ||
* @param {function} handler The handler which is executed on other tabs when a synchronization is triggered. Argument is the return value of the action. | ||
* @param {boolean} [options.tracing=false] Option to turn on tracing for debugging. | ||
* @param {Object} [options.logger=console] The logger to debug to. | ||
* @param {string} [options.logLevel=info] The log level to trace at. | ||
* @param {number} [options.idLength=8] The number of characters to use for unique instance ID. | ||
* @param {number} [options.pollFrequency=3000] The frequency (in milliseconds) to poll at. | ||
* @param {string} [options.path='/'] The path to store the cookie at. | ||
* @param {boolean} [options.secure=false] Flag to set the cookies secure flag. | ||
* @param {boolean} [options.httpOnly=false] Flag to set the cookies httpOnly flag. | ||
* @return {Object} cookiesync instance with start, stop, trigger, isRunning, isFallback, and instanceID properties. | ||
*/ | ||
function cookiesync(key, action, handler) { | ||
var _ref = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {}, | ||
_ref$tracing = _ref.tracing, | ||
tracing = _ref$tracing === undefined ? false : _ref$tracing, | ||
_ref$logger = _ref.logger, | ||
logger = _ref$logger === undefined ? console : _ref$logger, | ||
_ref$logLevel = _ref.logLevel, | ||
logLevel = _ref$logLevel === undefined ? 'info' : _ref$logLevel, | ||
_ref$idLength = _ref.idLength, | ||
idLength = _ref$idLength === undefined ? 8 : _ref$idLength, | ||
_ref$pollFrequency = _ref.pollFrequency, | ||
pollFrequency = _ref$pollFrequency === undefined ? 3000 : _ref$pollFrequency, | ||
_ref$path = _ref.path, | ||
path = _ref$path === undefined ? '/' : _ref$path, | ||
_ref$secure = _ref.secure, | ||
secure = _ref$secure === undefined ? false : _ref$secure, | ||
_ref$httpOnly = _ref.httpOnly, | ||
httpOnly = _ref$httpOnly === undefined ? false : _ref$httpOnly; | ||
(0, _invariant2.default)(key, 'key is required'); | ||
(0, _invariant2.default)(action, 'action is required'); | ||
(0, _invariant2.default)(handler, 'handler is required'); | ||
var log = function log() { | ||
return tracing ? logger[logLevel].apply(logger, arguments) : function () {}; | ||
}; | ||
var cookieOpts = { path: path, secure: secure, httpOnly: httpOnly }; | ||
var cookieKey = 'cookiesync_fallback_' + key; | ||
var instanceID = function (N) { | ||
return (Math.random().toString(36) + '00000000000000000').slice(2, N + 2); | ||
}(idLength); | ||
var loadCookie = function loadCookie() { | ||
try { | ||
var value = _reactCookie2.default.load(cookieKey, false); | ||
if (typeof value !== 'undefined') { | ||
var _instanceID = value.instanceID, | ||
payload = value.payload; | ||
(0, _invariant2.default)(_instanceID, 'cookiesync cookies must have an instanceID associated => ' + JSON.stringify(value)); | ||
(0, _invariant2.default)(typeof _instanceID === 'string' && _instanceID.length === idLength, 'instanceID must be a string'); | ||
(0, _invariant2.default)(payload, 'cookiesync cookies must have a payload associated => ' + JSON.stringify(value)); | ||
} | ||
log('cookiesync#loadCookie', value); | ||
return value; | ||
} catch (err) { | ||
logger.error(err, 'cookiesync#loadCookie => error occurred in cookiesync, wiping cookie with key ' + cookieKey); | ||
_reactCookie2.default.remove(cookieKey); | ||
} | ||
}; | ||
var saveCookie = function saveCookie() { | ||
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { | ||
args[_key] = arguments[_key]; | ||
} | ||
(0, _invariant2.default)(args.length === 1, 'should only have one argument'); | ||
var payload = args[0]; | ||
var value = { instanceID: instanceID, payload: payload }; | ||
log('cookisync#saveCookie', instanceID, payload); | ||
_reactCookie2.default.save(cookieKey, value, cookieOpts); | ||
}; | ||
var isRunning = false; | ||
var trigger = function trigger() { | ||
for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { | ||
args[_key2] = arguments[_key2]; | ||
} | ||
log.apply(undefined, ['cookiesync#trigger', instanceID].concat(args)); | ||
var payload = action.apply(undefined, args); | ||
log('cookiesync#trigger => payload', payload); | ||
saveCookie(payload); | ||
}; | ||
var intervalID = null; | ||
var start = function start() { | ||
var sync = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; | ||
log('cookiesync#start', instanceID); | ||
var last = loadCookie(); | ||
if (!last) { | ||
log('cookiesync#start: nolast', instanceID); | ||
last = { instanceID: instanceID }; | ||
saveCookie(last); | ||
} | ||
intervalID = setInterval(function () { | ||
log('cookiesync#poll', instanceID); | ||
var current = loadCookie(); | ||
if (!current) { | ||
log('cookiesync#poll: nocurrent', instanceID); | ||
current = last; | ||
saveCookie(current); | ||
} | ||
/** DONT NOTIFY IF SAME TAB */ | ||
if (current.instanceID === instanceID) { | ||
log('cookiesync#poll: sameinstance', instanceID); | ||
return; | ||
} | ||
if (JSON.stringify(last.payload) != JSON.stringify(current.payload)) { | ||
log('cookiesync#poll: INVOKE|instanceID =', instanceID, '|current.instanceID =', current.instanceID, '|last.instanceID =', last.instanceID, '|last.payload =', JSON.stringify(last.payload), '|current.payload =', JSON.stringify(current.payload)); | ||
handler(current.payload, last ? last.payload : {}, last ? last.url || '' : ''); | ||
last = current; | ||
} else { | ||
log('cookiesync#poll: noinvoke|instanceID =', instanceID, '|current.instanceID =', current.instanceID, '|last.instanceID =', last.instanceID, '|last.payload =', JSON.stringify(last.payload), '|current.payload =', JSON.stringify(current.payload)); | ||
} | ||
}, pollFrequency); | ||
if (sync) { | ||
var current = loadCookie(); | ||
handler(current.payload, last ? last.payload : {}, last ? last.url || '' : ''); | ||
last = current; | ||
} | ||
isRunning = true; | ||
}; | ||
var stop = function stop() { | ||
log('cookiesync#stop', instanceID); | ||
clearInterval(intervalID); | ||
isRunning = false; | ||
}; | ||
return { start: start, | ||
stop: stop, | ||
trigger: trigger, | ||
get isRunning() { | ||
return isRunning; | ||
}, | ||
mechanism: mechanism, | ||
isFallback: true, | ||
isServer: false, | ||
instanceID: instanceID | ||
}; | ||
} | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var cookiesync_1 = require("./cookiesync"); | ||
exports.cookiesync = cookiesync_1.cookiesync; | ||
//# sourceMappingURL=index.js.map |
{ | ||
"name": "cookiesync", | ||
"version": "1.4.0", | ||
"version": "2.0.1", | ||
"description": "a lightweight module to sync JS objects in realtime across tabs / windows of a browser.", | ||
@@ -21,50 +21,19 @@ "main": "lib/index.js", | ||
"scripts": { | ||
"start": "run-p build-watch test-watch", | ||
"clean": "run-p clean-lib clean-doc clean-test", | ||
"clean-lib": "rimraf lib", | ||
"clean-doc": "rimraf doc", | ||
"clean-test": "rimraf coverage.lcov", | ||
"prebuild": "npm run clean", | ||
"build": "babel src/lib -d lib", | ||
"build-watch": "npm run build -- --watch", | ||
"pretest-mocha": "npm run build", | ||
"test-mocha": "mocha --harmony --es_staging --require test/require", | ||
"test": "nyc npm run test-mocha", | ||
"coverage": "nyc report --reporter=text-lcov > coverage.lcov && codecov", | ||
"test-watch": "npm run test-mocha -- --watch", | ||
"prerelease": "npm run test", | ||
"release": "npm version patch && npm publish", | ||
"postrelease": "npm run release-gh-pages", | ||
"prerelease-gh-pages": "npm run doc", | ||
"release-gh-pages": "run-s gh-pages-subtree gh-pages-push gh-pages-delete", | ||
"postrelease-gh-pages": "npm run clean-doc && npm run git-save -- clean && git push -u origin master --follow-tags", | ||
"predoc": "rimraf doc", | ||
"doc": "esdoc -c ./esdoc.json && ncp CNAME doc/CNAME", | ||
"postdoc": "npm run git-save -- doc", | ||
"gh-pages-subtree": "git subtree split --prefix doc -b gh-pages", | ||
"gh-pages-push": "git push -f origin gh-pages:gh-pages", | ||
"gh-pages-delete": "git branch -D gh-pages", | ||
"git-save": "git add -A && git commit -am ", | ||
"upgrade": "ncu -a && npm update" | ||
"start": "yarn build --watch", | ||
"clean": "rm -rf lib tsconfig.tsbuildinfo", | ||
"prebuild": "yarn clean", | ||
"build": "tsc --build", | ||
"prerelease": "yarn build", | ||
"release": "yarn publish --patch --non-interactive --access public" | ||
}, | ||
"dependencies": { | ||
"invariant": "^2.2.2", | ||
"react-cookie": "1.0.4" | ||
"browser-cookies": "^1.2.0", | ||
"localsync-core": "^2.0.0", | ||
"tslib": "^1.10.0" | ||
}, | ||
"devDependencies": { | ||
"babel-cli": "^6.7.7", | ||
"babel-preset-es2015": "^6.6.0", | ||
"babel-preset-stage-0": "^6.5.0", | ||
"babel-register": "latest", | ||
"codecov": "^1.0.1", | ||
"esdoc": "^0.4.6", | ||
"esdoc-es7-plugin": "0.0.3", | ||
"mocha": "latest", | ||
"ncp": "^2.0.0", | ||
"npm-run-all": "^2.1.1", | ||
"nyc": "^6.4.4", | ||
"rewire": "^2.5.1", | ||
"rimraf": "^2.5.2" | ||
"@types/node": "^12.6.9", | ||
"typescript": "^3.5.3" | ||
}, | ||
"author": "Cole Chamberlain <cole.chamberlain@gmail.com> (https://github.com/cchamberlain)", | ||
"author": "Cole Chamberlain <colewc@google.com> (https://github.com/cchamberlain)", | ||
"bugs": { | ||
@@ -71,0 +40,0 @@ "url": "https://github.com/noderaider/localsync/issues" |
@@ -1,88 +0,7 @@ | ||
[![NPM](https://raw.githubusercontent.com/noderaider/localsync/master/public/images/localsync.gif)](https://npmjs.com/packages/localsync) | ||
# cookiesync | ||
### serversync | ||
This package is a part of the [`localsync`](https://npmjs.com/package/localsync) monorepo. | ||
**a lightweight module to sync JS objects in realtime across tabs / windows of a browser *COOKIE FALLBACK VERSION*.** | ||
- Synchronizes state using cookies. | ||
#### Features | ||
* Uses local storage event emitters to sync objects in realtime across tabs. | ||
* Never calls the tab that the event occurred on. | ||
* Falls back to cookie polling internally if using an unsupported browser (IE 9+ / Edge). | ||
* Isomorphic. | ||
* Tested with mocha. | ||
[![Build Status](https://travis-ci.org/noderaider/localsync.svg?branch=master)](https://travis-ci.org/noderaider/localsync) | ||
[![codecov](https://codecov.io/gh/noderaider/localsync/branch/master/graph/badge.svg)](https://codecov.io/gh/noderaider/localsync) | ||
[![NPM](https://nodei.co/npm/localsync.png?stars=true&downloads=true)](https://nodei.co/npm/localsync/) | ||
## Install | ||
`npm i -S cookiesync` | ||
## How to use | ||
```js | ||
import cookiesync from 'cookiesync' | ||
/** Create an action that will trigger a sync to other tabs. */ | ||
const action = (userID, first, last) => ({ userID, first, last }) | ||
/** Create a handler that will run on all tabs that did not trigger the sync. */ | ||
const handler = (value, old, url) => { | ||
console.info(`Another tab at url ${url} switched user from "${old.first} ${old.last}" to "${value.first} ${value.last}".`) | ||
// do something with value.userID | ||
} | ||
/** Create a synchronizer. cookiesync supports N number of synchronizers for different things across your app. */ | ||
const usersync = cookiesync('user', action, handler) | ||
/** Start synchronizing. */ | ||
usersync.start() | ||
/** IE / Edge do not support local storage across multiple tabs. cookiesync will automatically fallback to a cookie polling mechanism here. You don't need to do anything else. */ | ||
if(usersync.isFallback) | ||
console.warn('browser doesnt support local storage synchronization, falling back to cookie synchronization.') | ||
/** Trigger an action that will get handled on other tabs. */ | ||
usersync.trigger(1, 'jimmy', 'john') | ||
setTimeout(() => { | ||
/** Trigger another action in 5 seconds. */ | ||
usersync.trigger(2, 'jane', 'wonka') | ||
}, 5000) | ||
setTimeout(() => { | ||
/** If its still running, stop syncing in 10 seconds. */ | ||
if(usersync.isRunning) | ||
usersync.stop() | ||
}, 10000) | ||
``` | ||
## Documentation | ||
```js | ||
cookiesync(key: string, action: (...args) => payload, handler: payload => {}, [opts: Object]): { start, stop, trigger, isRunning, isFallback } | ||
``` | ||
**opts** | ||
**name** | **type** | **default** | **description** | ||
-------- | -------- | ----------- | --------------- | ||
`tracing` | `boolean` | `false` | toggles tracing for debugging purposes | ||
`logger` | `Object` | `console` | the logger object to trace to | ||
`loglevel` | `string` | `'info'` | the log level to use when tracing (`error`, `warn`, `info`, `trace`) | ||
**IE / Edge fallback props for `cookiesync`** | ||
**name** | **type** | **default** | **description** | ||
-------- | -------- | ----------- | --------------- | ||
`pollFrequency` | `number` | `3000` | the number in milliseconds that should be used for cookie polling | ||
`idLength` | `number` | `8` | the number of characters to use for tracking the current instance (tab) | ||
`path` | `string` | `'/'` | The path to use for cookies | ||
`secure` | `boolean` | `false` | Whether to set the secure flag on cookies or not (not recommended) | ||
`httpOnly` | `boolean` | `false` | Whether to set the http only flag on cookies or not | ||
See [https://github.com/noderaider/localsync] for usage information. |
Sorry, the diff of this file is not supported yet
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
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
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
2
13
17971
3
274
8
1
+ Addedbrowser-cookies@^1.2.0
+ Addedlocalsync-core@^2.0.0
+ Addedtslib@^1.10.0
+ Addedbrowser-cookies@1.2.0(transitive)
+ Addedlocalsync-core@2.0.8(transitive)
+ Addedtslib@1.14.1(transitive)
- Removedinvariant@^2.2.2
- Removedreact-cookie@1.0.4
- Removedcookie@0.3.1(transitive)
- Removedinvariant@2.2.4(transitive)
- Removedjs-tokens@4.0.0(transitive)
- Removedloose-envify@1.4.0(transitive)
- Removedobject-assign@4.1.1(transitive)
- Removedreact-cookie@1.0.4(transitive)