@folklore/clock
Advanced tools
Comparing version 0.1.9 to 0.1.11
369
es/Clock.js
@@ -1,199 +0,218 @@ | ||
import _classCallCheck from 'babel-runtime/helpers/classCallCheck'; | ||
import _possibleConstructorReturn from 'babel-runtime/helpers/possibleConstructorReturn'; | ||
import _createClass from 'babel-runtime/helpers/createClass'; | ||
import _inherits from 'babel-runtime/helpers/inherits'; | ||
import _objectSpread from "@babel/runtime/helpers/objectSpread"; | ||
import _classCallCheck from "@babel/runtime/helpers/classCallCheck"; | ||
import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn"; | ||
import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf"; | ||
import _assertThisInitialized from "@babel/runtime/helpers/assertThisInitialized"; | ||
import _createClass from "@babel/runtime/helpers/createClass"; | ||
import _inherits from "@babel/runtime/helpers/inherits"; | ||
import EventEmitter from 'wolfy87-eventemitter'; | ||
import createDebug from 'debug'; | ||
import getServerTime from './getServerTime'; | ||
var debug = createDebug('folklore:clock'); | ||
var Clock = function (_EventEmitter) { | ||
_inherits(Clock, _EventEmitter); | ||
var Clock = | ||
/*#__PURE__*/ | ||
function (_EventEmitter) { | ||
_inherits(Clock, _EventEmitter); | ||
_createClass(Clock, null, [{ | ||
key: 'getUTCTime', | ||
value: function getUTCTime(date) { | ||
var realDate = date || new Date(); | ||
return realDate.getTime(); | ||
} | ||
}]); | ||
_createClass(Clock, null, [{ | ||
key: "getUTCTime", | ||
value: function getUTCTime(date) { | ||
var realDate = date || new Date(); | ||
return realDate.getTime(); | ||
} | ||
}]); | ||
function Clock(opts) { | ||
_classCallCheck(this, Clock); | ||
function Clock(opts) { | ||
var _this; | ||
var _this = _possibleConstructorReturn(this, (Clock.__proto__ || Object.getPrototypeOf(Clock)).call(this)); | ||
_classCallCheck(this, Clock); | ||
_this.options = Object.assign({ | ||
time: null, | ||
updateInterval: 10, | ||
autoStart: true, | ||
server: null, | ||
serverUrlFormat: null, | ||
serverParseResponse: null, | ||
syncCount: 5 | ||
}, opts); | ||
_this = _possibleConstructorReturn(this, _getPrototypeOf(Clock).call(this)); | ||
_this.options = _objectSpread({ | ||
time: null, | ||
updateInterval: 10, | ||
autoStart: true, | ||
server: null, | ||
serverUrlFormat: null, | ||
serverParseResponse: null, | ||
syncCount: 5 | ||
}, opts); | ||
_this.onUpdate = _this.onUpdate.bind(_assertThisInitialized(_this)); | ||
_this.startTime = Clock.getUTCTime(); | ||
_this.currentTime = _this.startTime; | ||
_this.customStartTime = _this.options.time || _this.startTime; | ||
_this.time = _this.customStartTime; | ||
_this.serverOffset = 0; | ||
_this.started = false; | ||
_this.shouldStart = false; | ||
_this.server = null; | ||
_this.interval = null; | ||
_this.onUpdate = _this.onUpdate.bind(_this); | ||
if (_this.options.server !== null) { | ||
_this.ready = false; | ||
_this.startTime = Clock.getUTCTime(); | ||
_this.currentTime = _this.startTime; | ||
_this.customStartTime = _this.options.time || _this.startTime; | ||
_this.time = _this.customStartTime; | ||
_this.serverOffset = 0; | ||
_this.started = false; | ||
_this.shouldStart = false; | ||
_this.server = null; | ||
_this.interval = null; | ||
_this.setServer(_this.options.server); | ||
} else { | ||
_this.ready = true; | ||
if (_this.options.server !== null) { | ||
_this.ready = false; | ||
_this.setServer(_this.options.server); | ||
} else { | ||
_this.ready = true; | ||
_this.emit('ready'); | ||
} | ||
_this.emit('ready'); | ||
} | ||
if (_this.options.autoStart) { | ||
_this.start(); | ||
} | ||
return _this; | ||
if (_this.options.autoStart) { | ||
_this.start(); | ||
} | ||
_createClass(Clock, [{ | ||
key: 'setTime', | ||
value: function setTime(time) { | ||
this.startTime = Clock.getUTCTime(); | ||
this.customStartTime = time; | ||
} | ||
}, { | ||
key: 'setServer', | ||
value: function setServer(server) { | ||
var _this2 = this; | ||
return _this; | ||
} | ||
debug('Setting server to: ' + server); | ||
this.ready = false; | ||
this.server = server; | ||
var wasStarted = this.started; | ||
if (wasStarted) { | ||
debug('Stopping time whil syncing.'); | ||
this.stop(); | ||
} | ||
return this.sync().then(function () { | ||
_this2.ready = true; | ||
_this2.emit('ready'); | ||
if (wasStarted || _this2.shouldStart) { | ||
debug('Starting back...'); | ||
_this2.start(); | ||
} | ||
}); | ||
} | ||
}, { | ||
key: 'sync', | ||
value: function sync() { | ||
var _this3 = this; | ||
_createClass(Clock, [{ | ||
key: "setTime", | ||
value: function setTime(time) { | ||
this.startTime = Clock.getUTCTime(); | ||
this.customStartTime = time; | ||
} | ||
}, { | ||
key: "setServer", | ||
value: function setServer(server) { | ||
var _this2 = this; | ||
debug('Syncing with server: ' + this.server); | ||
var _options = this.options, | ||
syncCount = _options.syncCount, | ||
serverUrlFormat = _options.serverUrlFormat, | ||
serverParseResponse = _options.serverParseResponse; | ||
debug("Setting server to: ".concat(server)); | ||
this.ready = false; | ||
this.server = server; | ||
var wasStarted = this.started; | ||
var promises = []; | ||
for (var i = 0; i < syncCount; i += 1) { | ||
var promise = getServerTime(this.server, { | ||
urlFormat: serverUrlFormat, | ||
parseResponse: serverParseResponse | ||
}).then(function (time) { | ||
var clientTime = new Date().getTime(); | ||
return { | ||
server: time, | ||
client: clientTime | ||
}; | ||
}); | ||
promises.push(promise); | ||
} | ||
return Promise.all(promises).then(function (times) { | ||
var timesCount = times.length; | ||
var avgOffset = times.reduce(function (total, _ref) { | ||
var client = _ref.client, | ||
server = _ref.server; | ||
return total + (client - server); | ||
}, 0) / timesCount; | ||
var avgTime = times.reduce(function (total, _ref2) { | ||
var server = _ref2.server; | ||
return total + server; | ||
}, 0) / timesCount; | ||
_this3.serverOffset = avgOffset; | ||
_this3.setTime(avgTime); | ||
debug('Time synced with server. Offset: ' + _this3.serverOffset); | ||
_this3.emit('synced', avgTime); | ||
}); | ||
} | ||
}, { | ||
key: 'getOffset', | ||
value: function getOffset() { | ||
return this.serverOffset; | ||
} | ||
}, { | ||
key: 'start', | ||
value: function start() { | ||
if (this.started) { | ||
return; | ||
} | ||
if (!this.ready) { | ||
this.shouldStart = true; | ||
debug('Not ready, waiting to start...'); | ||
return; | ||
} | ||
debug('Starting...'); | ||
this.started = true; | ||
var updateInterval = this.options.updateInterval; | ||
if (wasStarted) { | ||
debug('Stopping time whil syncing.'); | ||
this.stop(); | ||
} | ||
if (updateInterval !== null && updateInterval > 0) { | ||
this.interval = setInterval(this.onUpdate, updateInterval); | ||
} | ||
return this.sync().then(function () { | ||
_this2.ready = true; | ||
_this2.emit('ready'); | ||
if (wasStarted || _this2.shouldStart) { | ||
debug('Starting back...'); | ||
_this2.start(); | ||
} | ||
}, { | ||
key: 'stop', | ||
value: function stop() { | ||
if (!this.started) { | ||
return; | ||
} | ||
this.shouldStart = false; | ||
this.started = false; | ||
if (this.interval) { | ||
clearInterval(this.interval); | ||
this.interval = null; | ||
} | ||
} | ||
}, { | ||
key: 'getTime', | ||
value: function getTime() { | ||
this.update(); | ||
return this.time; | ||
} | ||
}, { | ||
key: 'update', | ||
value: function update() { | ||
this.currentTime = Clock.getUTCTime(); | ||
var currentDelta = this.currentTime - this.startTime; | ||
var time = this.customStartTime + currentDelta; | ||
var changed = time !== this.time; | ||
this.time = time; | ||
if (changed) { | ||
this.emit('change', this.time); | ||
} | ||
} | ||
}, { | ||
key: 'onUpdate', | ||
value: function onUpdate() { | ||
this.update(); | ||
} | ||
}]); | ||
}); | ||
} | ||
}, { | ||
key: "sync", | ||
value: function sync() { | ||
var _this3 = this; | ||
return Clock; | ||
debug("Syncing with server: ".concat(this.server)); | ||
var _this$options = this.options, | ||
syncCount = _this$options.syncCount, | ||
serverUrlFormat = _this$options.serverUrlFormat, | ||
serverParseResponse = _this$options.serverParseResponse; | ||
var promises = []; | ||
for (var i = 0; i < syncCount; i += 1) { | ||
var promise = getServerTime(this.server, { | ||
urlFormat: serverUrlFormat, | ||
parseResponse: serverParseResponse | ||
}).then(function (time) { | ||
var clientTime = new Date().getTime(); | ||
return { | ||
server: time, | ||
client: clientTime | ||
}; | ||
}); | ||
promises.push(promise); | ||
} | ||
return Promise.all(promises).then(function (times) { | ||
var timesCount = times.length; | ||
var avgOffset = times.reduce(function (total, _ref) { | ||
var client = _ref.client, | ||
server = _ref.server; | ||
return total + (client - server); | ||
}, 0) / timesCount; | ||
var avgTime = times.reduce(function (total, _ref2) { | ||
var server = _ref2.server; | ||
return total + server; | ||
}, 0) / timesCount; | ||
_this3.serverOffset = avgOffset; | ||
_this3.setTime(avgTime); | ||
debug("Time synced with server. Offset: ".concat(_this3.serverOffset)); | ||
_this3.emit('synced', avgTime); | ||
}); | ||
} | ||
}, { | ||
key: "getOffset", | ||
value: function getOffset() { | ||
return this.serverOffset; | ||
} | ||
}, { | ||
key: "start", | ||
value: function start() { | ||
if (this.started) { | ||
return; | ||
} | ||
if (!this.ready) { | ||
this.shouldStart = true; | ||
debug('Not ready, waiting to start...'); | ||
return; | ||
} | ||
debug('Starting...'); | ||
this.started = true; | ||
var updateInterval = this.options.updateInterval; | ||
if (updateInterval !== null && updateInterval > 0) { | ||
this.interval = setInterval(this.onUpdate, updateInterval); | ||
} | ||
} | ||
}, { | ||
key: "stop", | ||
value: function stop() { | ||
if (!this.started) { | ||
return; | ||
} | ||
this.shouldStart = false; | ||
this.started = false; | ||
if (this.interval) { | ||
clearInterval(this.interval); | ||
this.interval = null; | ||
} | ||
} | ||
}, { | ||
key: "getTime", | ||
value: function getTime() { | ||
this.update(); | ||
return this.time; | ||
} | ||
}, { | ||
key: "update", | ||
value: function update() { | ||
this.currentTime = Clock.getUTCTime(); | ||
var currentDelta = this.currentTime - this.startTime; | ||
var time = this.customStartTime + currentDelta; | ||
var changed = time !== this.time; | ||
this.time = time; | ||
if (changed) { | ||
this.emit('change', this.time); | ||
} | ||
} | ||
}, { | ||
key: "onUpdate", | ||
value: function onUpdate() { | ||
this.update(); | ||
} | ||
}]); | ||
return Clock; | ||
}(EventEmitter); | ||
export default Clock; |
@@ -1,2 +0,3 @@ | ||
import _defineProperty from 'babel-runtime/helpers/defineProperty'; | ||
import _defineProperty from "@babel/runtime/helpers/defineProperty"; | ||
import _objectSpread from "@babel/runtime/helpers/objectSpread"; | ||
// Thanks http://stackoverflow.com/questions/1638337/the-best-way-to-synchronize-client-side-javascript-clock-with-server-date | ||
@@ -6,40 +7,42 @@ import 'whatwg-fetch'; | ||
var getTime = function getTime() { | ||
return new Date().getTime(); | ||
return new Date().getTime(); | ||
}; | ||
var getServerTime = function getServerTime(url, opts) { | ||
var options = Object.assign({ | ||
urlFormat: '{url}?time={timestamp}', | ||
parseResponse: function parseResponse(response) { | ||
var responseParts = response.split(','); | ||
return { | ||
serverTimestamp: parseInt(responseParts[0], 10), | ||
serverClientRequestDiffTime: parseInt(responseParts[1], 10) | ||
}; | ||
} | ||
}, Object.keys(opts || {}).reduce(function (finalOptions, key) { | ||
return typeof opts[key] !== 'undefined' && opts[key] !== null ? Object.assign({}, finalOptions, _defineProperty({}, key, opts[key])) : finalOptions; | ||
}, {})); | ||
var clientTimestamp = getTime(); | ||
var clockUrl = options.urlFormat.replace(/\{\s*url\s*\}/, url).replace(/\{\s*timestamp\s*\}/, clientTimestamp); | ||
return fetch(clockUrl, { | ||
method: 'GET' | ||
}).then(function (response) { | ||
return response.text(); | ||
}).then(function (response) { | ||
var nowTimeStamp = getTime(); | ||
var options = _objectSpread({ | ||
urlFormat: '{url}?time={timestamp}', | ||
parseResponse: function parseResponse(response) { | ||
var responseParts = response.split(','); | ||
return { | ||
serverTimestamp: parseInt(responseParts[0], 10), | ||
serverClientRequestDiffTime: parseInt(responseParts[1], 10) | ||
}; | ||
} | ||
}, Object.keys(opts || {}).reduce(function (finalOptions, key) { | ||
return typeof opts[key] !== 'undefined' && opts[key] !== null ? _objectSpread({}, finalOptions, _defineProperty({}, key, opts[key])) : finalOptions; | ||
}, {})); | ||
var _options$parseRespons = options.parseResponse(response), | ||
serverTimestamp = _options$parseRespons.serverTimestamp, | ||
serverClientRequestDiffTime = _options$parseRespons.serverClientRequestDiffTime; | ||
var clientTimestamp = getTime(); | ||
var clockUrl = options.urlFormat.replace(/\{\s*url\s*\}/, url).replace(/\{\s*timestamp\s*\}/, clientTimestamp); | ||
return fetch(clockUrl, { | ||
method: 'GET' | ||
}).then(function (response) { | ||
return response.text(); | ||
}).then(function (response) { | ||
var nowTimeStamp = getTime(); | ||
if (typeof serverTimestamp === 'undefined' || typeof serverClientRequestDiffTime === 'undefined' || Number.isNaN(serverTimestamp) || Number.isNaN(serverClientRequestDiffTime)) { | ||
throw new Error('Bad response'); | ||
} | ||
var serverClientResponseDiffTime = nowTimeStamp - serverTimestamp; | ||
var responseTime = (serverClientRequestDiffTime - nowTimeStamp + (clientTimestamp - serverClientResponseDiffTime)) / 2; | ||
return nowTimeStamp + responseTime; | ||
}); | ||
var _options$parseRespons = options.parseResponse(response), | ||
serverTimestamp = _options$parseRespons.serverTimestamp, | ||
serverClientRequestDiffTime = _options$parseRespons.serverClientRequestDiffTime; | ||
if (typeof serverTimestamp === 'undefined' || typeof serverClientRequestDiffTime === 'undefined' || Number.isNaN(serverTimestamp) || Number.isNaN(serverClientRequestDiffTime)) { | ||
throw new Error('Bad response'); | ||
} | ||
var serverClientResponseDiffTime = nowTimeStamp - serverTimestamp; | ||
var responseTime = (serverClientRequestDiffTime - nowTimeStamp + (clientTimestamp - serverClientResponseDiffTime)) / 2; | ||
return nowTimeStamp + responseTime; | ||
}); | ||
}; | ||
export default getServerTime; |
import Clock from './Clock'; | ||
import getServerTime from './getServerTime'; | ||
export { Clock, getServerTime }; | ||
export default Clock; |
389
lib/Clock.js
@@ -1,224 +0,235 @@ | ||
'use strict'; | ||
"use strict"; | ||
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); | ||
Object.defineProperty(exports, "__esModule", { | ||
value: true | ||
value: true | ||
}); | ||
exports["default"] = void 0; | ||
var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck'); | ||
var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread")); | ||
var _classCallCheck3 = _interopRequireDefault(_classCallCheck2); | ||
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); | ||
var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn'); | ||
var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn")); | ||
var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2); | ||
var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf")); | ||
var _createClass2 = require('babel-runtime/helpers/createClass'); | ||
var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized")); | ||
var _createClass3 = _interopRequireDefault(_createClass2); | ||
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); | ||
var _inherits2 = require('babel-runtime/helpers/inherits'); | ||
var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits")); | ||
var _inherits3 = _interopRequireDefault(_inherits2); | ||
var _wolfy87Eventemitter = _interopRequireDefault(require("wolfy87-eventemitter")); | ||
var _wolfy87Eventemitter = require('wolfy87-eventemitter'); | ||
var _debug = _interopRequireDefault(require("debug")); | ||
var _wolfy87Eventemitter2 = _interopRequireDefault(_wolfy87Eventemitter); | ||
var _getServerTime = _interopRequireDefault(require("./getServerTime")); | ||
var _debug = require('debug'); | ||
var debug = (0, _debug["default"])('folklore:clock'); | ||
var _debug2 = _interopRequireDefault(_debug); | ||
var Clock = | ||
/*#__PURE__*/ | ||
function (_EventEmitter) { | ||
(0, _inherits2["default"])(Clock, _EventEmitter); | ||
(0, _createClass2["default"])(Clock, null, [{ | ||
key: "getUTCTime", | ||
value: function getUTCTime(date) { | ||
var realDate = date || new Date(); | ||
return realDate.getTime(); | ||
} | ||
}]); | ||
var _getServerTime = require('./getServerTime'); | ||
function Clock(opts) { | ||
var _this; | ||
var _getServerTime2 = _interopRequireDefault(_getServerTime); | ||
(0, _classCallCheck2["default"])(this, Clock); | ||
_this = (0, _possibleConstructorReturn2["default"])(this, (0, _getPrototypeOf2["default"])(Clock).call(this)); | ||
_this.options = (0, _objectSpread2["default"])({ | ||
time: null, | ||
updateInterval: 10, | ||
autoStart: true, | ||
server: null, | ||
serverUrlFormat: null, | ||
serverParseResponse: null, | ||
syncCount: 5 | ||
}, opts); | ||
_this.onUpdate = _this.onUpdate.bind((0, _assertThisInitialized2["default"])(_this)); | ||
_this.startTime = Clock.getUTCTime(); | ||
_this.currentTime = _this.startTime; | ||
_this.customStartTime = _this.options.time || _this.startTime; | ||
_this.time = _this.customStartTime; | ||
_this.serverOffset = 0; | ||
_this.started = false; | ||
_this.shouldStart = false; | ||
_this.server = null; | ||
_this.interval = null; | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
if (_this.options.server !== null) { | ||
_this.ready = false; | ||
var debug = (0, _debug2.default)('folklore:clock'); | ||
_this.setServer(_this.options.server); | ||
} else { | ||
_this.ready = true; | ||
var Clock = function (_EventEmitter) { | ||
(0, _inherits3.default)(Clock, _EventEmitter); | ||
(0, _createClass3.default)(Clock, null, [{ | ||
key: 'getUTCTime', | ||
value: function getUTCTime(date) { | ||
var realDate = date || new Date(); | ||
return realDate.getTime(); | ||
} | ||
}]); | ||
_this.emit('ready'); | ||
} | ||
function Clock(opts) { | ||
(0, _classCallCheck3.default)(this, Clock); | ||
if (_this.options.autoStart) { | ||
_this.start(); | ||
} | ||
var _this = (0, _possibleConstructorReturn3.default)(this, (Clock.__proto__ || Object.getPrototypeOf(Clock)).call(this)); | ||
return _this; | ||
} | ||
_this.options = Object.assign({ | ||
time: null, | ||
updateInterval: 10, | ||
autoStart: true, | ||
server: null, | ||
serverUrlFormat: null, | ||
serverParseResponse: null, | ||
syncCount: 5 | ||
}, opts); | ||
(0, _createClass2["default"])(Clock, [{ | ||
key: "setTime", | ||
value: function setTime(time) { | ||
this.startTime = Clock.getUTCTime(); | ||
this.customStartTime = time; | ||
} | ||
}, { | ||
key: "setServer", | ||
value: function setServer(server) { | ||
var _this2 = this; | ||
_this.onUpdate = _this.onUpdate.bind(_this); | ||
debug("Setting server to: ".concat(server)); | ||
this.ready = false; | ||
this.server = server; | ||
var wasStarted = this.started; | ||
_this.startTime = Clock.getUTCTime(); | ||
_this.currentTime = _this.startTime; | ||
_this.customStartTime = _this.options.time || _this.startTime; | ||
_this.time = _this.customStartTime; | ||
_this.serverOffset = 0; | ||
_this.started = false; | ||
_this.shouldStart = false; | ||
_this.server = null; | ||
_this.interval = null; | ||
if (wasStarted) { | ||
debug('Stopping time whil syncing.'); | ||
this.stop(); | ||
} | ||
if (_this.options.server !== null) { | ||
_this.ready = false; | ||
_this.setServer(_this.options.server); | ||
} else { | ||
_this.ready = true; | ||
_this.emit('ready'); | ||
} | ||
return this.sync().then(function () { | ||
_this2.ready = true; | ||
if (_this.options.autoStart) { | ||
_this.start(); | ||
_this2.emit('ready'); | ||
if (wasStarted || _this2.shouldStart) { | ||
debug('Starting back...'); | ||
_this2.start(); | ||
} | ||
return _this; | ||
}); | ||
} | ||
}, { | ||
key: "sync", | ||
value: function sync() { | ||
var _this3 = this; | ||
(0, _createClass3.default)(Clock, [{ | ||
key: 'setTime', | ||
value: function setTime(time) { | ||
this.startTime = Clock.getUTCTime(); | ||
this.customStartTime = time; | ||
} | ||
}, { | ||
key: 'setServer', | ||
value: function setServer(server) { | ||
var _this2 = this; | ||
debug("Syncing with server: ".concat(this.server)); | ||
var _this$options = this.options, | ||
syncCount = _this$options.syncCount, | ||
serverUrlFormat = _this$options.serverUrlFormat, | ||
serverParseResponse = _this$options.serverParseResponse; | ||
var promises = []; | ||
debug('Setting server to: ' + server); | ||
this.ready = false; | ||
this.server = server; | ||
var wasStarted = this.started; | ||
if (wasStarted) { | ||
debug('Stopping time whil syncing.'); | ||
this.stop(); | ||
} | ||
return this.sync().then(function () { | ||
_this2.ready = true; | ||
_this2.emit('ready'); | ||
if (wasStarted || _this2.shouldStart) { | ||
debug('Starting back...'); | ||
_this2.start(); | ||
} | ||
}); | ||
} | ||
}, { | ||
key: 'sync', | ||
value: function sync() { | ||
var _this3 = this; | ||
for (var i = 0; i < syncCount; i += 1) { | ||
var promise = (0, _getServerTime["default"])(this.server, { | ||
urlFormat: serverUrlFormat, | ||
parseResponse: serverParseResponse | ||
}).then(function (time) { | ||
var clientTime = new Date().getTime(); | ||
return { | ||
server: time, | ||
client: clientTime | ||
}; | ||
}); | ||
promises.push(promise); | ||
} | ||
debug('Syncing with server: ' + this.server); | ||
var _options = this.options, | ||
syncCount = _options.syncCount, | ||
serverUrlFormat = _options.serverUrlFormat, | ||
serverParseResponse = _options.serverParseResponse; | ||
return Promise.all(promises).then(function (times) { | ||
var timesCount = times.length; | ||
var avgOffset = times.reduce(function (total, _ref) { | ||
var client = _ref.client, | ||
server = _ref.server; | ||
return total + (client - server); | ||
}, 0) / timesCount; | ||
var avgTime = times.reduce(function (total, _ref2) { | ||
var server = _ref2.server; | ||
return total + server; | ||
}, 0) / timesCount; | ||
_this3.serverOffset = avgOffset; | ||
var promises = []; | ||
for (var i = 0; i < syncCount; i += 1) { | ||
var promise = (0, _getServerTime2.default)(this.server, { | ||
urlFormat: serverUrlFormat, | ||
parseResponse: serverParseResponse | ||
}).then(function (time) { | ||
var clientTime = new Date().getTime(); | ||
return { | ||
server: time, | ||
client: clientTime | ||
}; | ||
}); | ||
promises.push(promise); | ||
} | ||
return Promise.all(promises).then(function (times) { | ||
var timesCount = times.length; | ||
var avgOffset = times.reduce(function (total, _ref) { | ||
var client = _ref.client, | ||
server = _ref.server; | ||
return total + (client - server); | ||
}, 0) / timesCount; | ||
var avgTime = times.reduce(function (total, _ref2) { | ||
var server = _ref2.server; | ||
return total + server; | ||
}, 0) / timesCount; | ||
_this3.serverOffset = avgOffset; | ||
_this3.setTime(avgTime); | ||
debug('Time synced with server. Offset: ' + _this3.serverOffset); | ||
_this3.emit('synced', avgTime); | ||
}); | ||
} | ||
}, { | ||
key: 'getOffset', | ||
value: function getOffset() { | ||
return this.serverOffset; | ||
} | ||
}, { | ||
key: 'start', | ||
value: function start() { | ||
if (this.started) { | ||
return; | ||
} | ||
if (!this.ready) { | ||
this.shouldStart = true; | ||
debug('Not ready, waiting to start...'); | ||
return; | ||
} | ||
debug('Starting...'); | ||
this.started = true; | ||
var updateInterval = this.options.updateInterval; | ||
_this3.setTime(avgTime); | ||
if (updateInterval !== null && updateInterval > 0) { | ||
this.interval = setInterval(this.onUpdate, updateInterval); | ||
} | ||
} | ||
}, { | ||
key: 'stop', | ||
value: function stop() { | ||
if (!this.started) { | ||
return; | ||
} | ||
this.shouldStart = false; | ||
this.started = false; | ||
if (this.interval) { | ||
clearInterval(this.interval); | ||
this.interval = null; | ||
} | ||
} | ||
}, { | ||
key: 'getTime', | ||
value: function getTime() { | ||
this.update(); | ||
return this.time; | ||
} | ||
}, { | ||
key: 'update', | ||
value: function update() { | ||
this.currentTime = Clock.getUTCTime(); | ||
var currentDelta = this.currentTime - this.startTime; | ||
var time = this.customStartTime + currentDelta; | ||
var changed = time !== this.time; | ||
this.time = time; | ||
if (changed) { | ||
this.emit('change', this.time); | ||
} | ||
} | ||
}, { | ||
key: 'onUpdate', | ||
value: function onUpdate() { | ||
this.update(); | ||
} | ||
}]); | ||
return Clock; | ||
}(_wolfy87Eventemitter2.default); | ||
debug("Time synced with server. Offset: ".concat(_this3.serverOffset)); | ||
exports.default = Clock; | ||
_this3.emit('synced', avgTime); | ||
}); | ||
} | ||
}, { | ||
key: "getOffset", | ||
value: function getOffset() { | ||
return this.serverOffset; | ||
} | ||
}, { | ||
key: "start", | ||
value: function start() { | ||
if (this.started) { | ||
return; | ||
} | ||
if (!this.ready) { | ||
this.shouldStart = true; | ||
debug('Not ready, waiting to start...'); | ||
return; | ||
} | ||
debug('Starting...'); | ||
this.started = true; | ||
var updateInterval = this.options.updateInterval; | ||
if (updateInterval !== null && updateInterval > 0) { | ||
this.interval = setInterval(this.onUpdate, updateInterval); | ||
} | ||
} | ||
}, { | ||
key: "stop", | ||
value: function stop() { | ||
if (!this.started) { | ||
return; | ||
} | ||
this.shouldStart = false; | ||
this.started = false; | ||
if (this.interval) { | ||
clearInterval(this.interval); | ||
this.interval = null; | ||
} | ||
} | ||
}, { | ||
key: "getTime", | ||
value: function getTime() { | ||
this.update(); | ||
return this.time; | ||
} | ||
}, { | ||
key: "update", | ||
value: function update() { | ||
this.currentTime = Clock.getUTCTime(); | ||
var currentDelta = this.currentTime - this.startTime; | ||
var time = this.customStartTime + currentDelta; | ||
var changed = time !== this.time; | ||
this.time = time; | ||
if (changed) { | ||
this.emit('change', this.time); | ||
} | ||
} | ||
}, { | ||
key: "onUpdate", | ||
value: function onUpdate() { | ||
this.update(); | ||
} | ||
}]); | ||
return Clock; | ||
}(_wolfy87Eventemitter["default"]); | ||
var _default = Clock; | ||
exports["default"] = _default; |
@@ -1,55 +0,58 @@ | ||
'use strict'; | ||
"use strict"; | ||
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); | ||
Object.defineProperty(exports, "__esModule", { | ||
value: true | ||
value: true | ||
}); | ||
exports["default"] = void 0; | ||
var _defineProperty2 = require('babel-runtime/helpers/defineProperty'); | ||
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); | ||
var _defineProperty3 = _interopRequireDefault(_defineProperty2); | ||
var _objectSpread3 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread")); | ||
require('whatwg-fetch'); | ||
require("whatwg-fetch"); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
// Thanks http://stackoverflow.com/questions/1638337/the-best-way-to-synchronize-client-side-javascript-clock-with-server-date | ||
var getTime = function getTime() { | ||
return new Date().getTime(); | ||
}; // Thanks http://stackoverflow.com/questions/1638337/the-best-way-to-synchronize-client-side-javascript-clock-with-server-date | ||
return new Date().getTime(); | ||
}; | ||
var getServerTime = function getServerTime(url, opts) { | ||
var options = Object.assign({ | ||
urlFormat: '{url}?time={timestamp}', | ||
parseResponse: function parseResponse(response) { | ||
var responseParts = response.split(','); | ||
return { | ||
serverTimestamp: parseInt(responseParts[0], 10), | ||
serverClientRequestDiffTime: parseInt(responseParts[1], 10) | ||
}; | ||
} | ||
}, Object.keys(opts || {}).reduce(function (finalOptions, key) { | ||
return typeof opts[key] !== 'undefined' && opts[key] !== null ? Object.assign({}, finalOptions, (0, _defineProperty3.default)({}, key, opts[key])) : finalOptions; | ||
}, {})); | ||
var clientTimestamp = getTime(); | ||
var clockUrl = options.urlFormat.replace(/\{\s*url\s*\}/, url).replace(/\{\s*timestamp\s*\}/, clientTimestamp); | ||
return fetch(clockUrl, { | ||
method: 'GET' | ||
}).then(function (response) { | ||
return response.text(); | ||
}).then(function (response) { | ||
var nowTimeStamp = getTime(); | ||
var options = (0, _objectSpread3["default"])({ | ||
urlFormat: '{url}?time={timestamp}', | ||
parseResponse: function parseResponse(response) { | ||
var responseParts = response.split(','); | ||
return { | ||
serverTimestamp: parseInt(responseParts[0], 10), | ||
serverClientRequestDiffTime: parseInt(responseParts[1], 10) | ||
}; | ||
} | ||
}, Object.keys(opts || {}).reduce(function (finalOptions, key) { | ||
return typeof opts[key] !== 'undefined' && opts[key] !== null ? (0, _objectSpread3["default"])({}, finalOptions, (0, _defineProperty2["default"])({}, key, opts[key])) : finalOptions; | ||
}, {})); | ||
var clientTimestamp = getTime(); | ||
var clockUrl = options.urlFormat.replace(/\{\s*url\s*\}/, url).replace(/\{\s*timestamp\s*\}/, clientTimestamp); | ||
return fetch(clockUrl, { | ||
method: 'GET' | ||
}).then(function (response) { | ||
return response.text(); | ||
}).then(function (response) { | ||
var nowTimeStamp = getTime(); | ||
var _options$parseRespons = options.parseResponse(response), | ||
serverTimestamp = _options$parseRespons.serverTimestamp, | ||
serverClientRequestDiffTime = _options$parseRespons.serverClientRequestDiffTime; | ||
var _options$parseRespons = options.parseResponse(response), | ||
serverTimestamp = _options$parseRespons.serverTimestamp, | ||
serverClientRequestDiffTime = _options$parseRespons.serverClientRequestDiffTime; | ||
if (typeof serverTimestamp === 'undefined' || typeof serverClientRequestDiffTime === 'undefined' || Number.isNaN(serverTimestamp) || Number.isNaN(serverClientRequestDiffTime)) { | ||
throw new Error('Bad response'); | ||
} | ||
var serverClientResponseDiffTime = nowTimeStamp - serverTimestamp; | ||
var responseTime = (serverClientRequestDiffTime - nowTimeStamp + (clientTimestamp - serverClientResponseDiffTime)) / 2; | ||
return nowTimeStamp + responseTime; | ||
}); | ||
if (typeof serverTimestamp === 'undefined' || typeof serverClientRequestDiffTime === 'undefined' || Number.isNaN(serverTimestamp) || Number.isNaN(serverClientRequestDiffTime)) { | ||
throw new Error('Bad response'); | ||
} | ||
var serverClientResponseDiffTime = nowTimeStamp - serverTimestamp; | ||
var responseTime = (serverClientRequestDiffTime - nowTimeStamp + (clientTimestamp - serverClientResponseDiffTime)) / 2; | ||
return nowTimeStamp + responseTime; | ||
}); | ||
}; | ||
exports.default = getServerTime; | ||
var _default = getServerTime; | ||
exports["default"] = _default; |
@@ -1,20 +0,27 @@ | ||
'use strict'; | ||
"use strict"; | ||
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); | ||
Object.defineProperty(exports, "__esModule", { | ||
value: true | ||
value: true | ||
}); | ||
exports.getServerTime = exports.Clock = undefined; | ||
Object.defineProperty(exports, "Clock", { | ||
enumerable: true, | ||
get: function get() { | ||
return _Clock["default"]; | ||
} | ||
}); | ||
Object.defineProperty(exports, "getServerTime", { | ||
enumerable: true, | ||
get: function get() { | ||
return _getServerTime["default"]; | ||
} | ||
}); | ||
exports["default"] = void 0; | ||
var _Clock = require('./Clock'); | ||
var _Clock = _interopRequireDefault(require("./Clock")); | ||
var _Clock2 = _interopRequireDefault(_Clock); | ||
var _getServerTime = _interopRequireDefault(require("./getServerTime")); | ||
var _getServerTime = require('./getServerTime'); | ||
var _getServerTime2 = _interopRequireDefault(_getServerTime); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
exports.Clock = _Clock2.default; | ||
exports.getServerTime = _getServerTime2.default; | ||
exports.default = _Clock2.default; | ||
var _default = _Clock["default"]; | ||
exports["default"] = _default; |
{ | ||
"name": "@folklore/clock", | ||
"version": "0.1.9", | ||
"version": "0.1.11", | ||
"description": "Clock synced with server", | ||
@@ -40,3 +40,3 @@ "keywords": [ | ||
"clean": "rm -rf dist && rm -rf lib && rm -rf es", | ||
"webpack:dist": "node -r babel-register ../../node_modules/.bin/webpack --config ./webpack.config.js --progress --colors", | ||
"webpack:dist": "../../node_modules/.bin/webpack --config ./webpack.config.js --progress --colors", | ||
"webpack": "npm run webpack:dist", | ||
@@ -51,3 +51,3 @@ "babel:es": "BABEL_ENV=es ../../node_modules/.bin/babel src --out-dir es --ignore story.js,test.js", | ||
"dependencies": { | ||
"babel-runtime": "^6.26.0", | ||
"@babel/runtime": "^7.4.3", | ||
"debug": "^3.1.0", | ||
@@ -57,3 +57,3 @@ "whatwg-fetch": "^2.0.3", | ||
}, | ||
"gitHead": "5bae5c551be82e7681abc29e004329caf3041666" | ||
"gitHead": "74592843a9e8b982a8584ae80b2f6cdd3d5db2f4" | ||
} |
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
Found 1 instance in 1 package
66578
488
1
+ Added@babel/runtime@^7.4.3
+ Added@babel/runtime@7.25.9(transitive)
+ Addedregenerator-runtime@0.14.1(transitive)
- Removedbabel-runtime@^6.26.0
- Removedbabel-runtime@6.26.0(transitive)
- Removedcore-js@2.6.12(transitive)
- Removedregenerator-runtime@0.11.1(transitive)