UNPKG

@ruanitto/react-native-ntp-sync

Version:
163 lines (162 loc) 6.75 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.NtpClientError = void 0; const error_1 = require("./internals/error"); Object.defineProperty(exports, "NtpClientError", { enumerable: true, get: function () { return error_1.NtpClientError; } }); const client_1 = require("./internals/client"); const default_config_1 = __importDefault(require("./internals/default-config")); class NTPSync { constructor(config) { this.currentIndex = 0; this.tickId = null; this.listeners = new Set(); this.computeAndUpdate = (ntpDate) => { const tempServerTime = ntpDate.getTime(); const tempLocalTime = Date.now(); const dt = tempServerTime - tempLocalTime; if (this.historyDetails.deltas.length === this.limit) { this.historyDetails.deltas.shift(); } this.historyDetails.deltas.push({ dt: dt, ntp: tempServerTime, }); this.historyDetails.lastSyncTime = tempLocalTime; this.historyDetails.lastNtpTime = tempServerTime; return dt; }; this.getDelta = () => __awaiter(this, void 0, void 0, function* () { if (this.isOnline) { const fetchingServer = Object.assign({}, this.historyDetails.currentServer); try { const ntpDate = yield client_1.getNetworkTime(this.historyDetails.currentServer.server, this.historyDetails.currentServer.port, this.syncTimeout); const delta = this.computeAndUpdate(ntpDate); return { delta, fetchingServer, }; } catch (err) { this.shiftServer(); throw new error_1.NtpClientError(err, fetchingServer); } } else { return { delta: 0 }; } }); this.getHistory = () => { return JSON.parse(JSON.stringify(this.historyDetails)); }; this.getTime = () => { const sum = this.historyDetails.deltas.reduce((a, b) => { return a + b.dt; }, 0); const avg = Math.round(sum / this.historyDetails.deltas.length) || 0; return Date.now() + avg; }; this.shiftServer = () => { if (this.ntpServers.length > 1) { this.currentIndex++; this.currentIndex %= this.ntpServers.length; } this.historyDetails.currentServer = this.ntpServers[this.currentIndex]; }; this.startAutoSync = () => { if (!this.tickId) { this.tickId = setInterval(() => this.syncTime(), this.tickRate); } }; this.stopAutoSync = () => { if (this.tickId) { clearInterval(this.tickId); this.tickId = null; } }; this.syncTime = () => __awaiter(this, void 0, void 0, function* () { if (this.isOnline) { try { const delta = yield this.getDelta(); this.historyDetails.currentConsecutiveErrorCount = 0; this.historyDetails.isInErrorState = false; this.listeners.forEach((handler) => handler(this.getHistory())); return true; } catch (err) { const ed = { name: err.name, message: err.message, server: err.server, stack: err.stack, time: Date.now(), }; this.historyDetails.currentConsecutiveErrorCount++; if (this.historyDetails.errors.length === this.limit) { this.historyDetails.errors.shift(); } this.historyDetails.errors.push(ed); this.historyDetails.isInErrorState = true; this.historyDetails.lastError = ed; this.historyDetails.lifetimeErrorCount++; this.historyDetails.maxConsecutiveErrorCount = Math.max(this.historyDetails.maxConsecutiveErrorCount, this.historyDetails.currentConsecutiveErrorCount); } return false; } return false; }); this.config = Object.assign(default_config_1.default, config); this.ntpServers = this.config.servers; this.limit = this.config.history; this.tickRate = this.config.syncInterval; this.syncTimeout = this.config.syncTimeout; this.historyDetails = { currentConsecutiveErrorCount: 0, currentServer: this.ntpServers[this.currentIndex], deltas: [], errors: [], isInErrorState: false, lastSyncTime: null, lastNtpTime: null, lastError: null, lifetimeErrorCount: 0, maxConsecutiveErrorCount: 0, }; this.isOnline = this.config.startOnline; if (this.config.syncOnCreation && this.config.startOnline) { this.syncTime(); } if (this.config.autoSync) { this.startAutoSync(); } } setIsOnline(isOnline) { if (isOnline && !this.isOnline) { this.isOnline = true; this.syncTime(); this.startAutoSync(); } else if (!isOnline && this.isOnline) { this.stopAutoSync(); this.isOnline = false; } } getIsOnline() { return this.isOnline; } addListener(listener) { this.listeners.add(listener); } } exports.default = NTPSync;