UNPKG

visiting-hours

Version:

An advanced, feature rich, optimised and tiny visiting-hours library.

266 lines (210 loc) 11.6 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.VisitingHours = void 0; var _Timezone = require("./Timezone"); var _Utils = require("./Utils"); var _VisitingHour = require("./VisitingHour"); var _HoursIndex = require("./HoursIndex"); var _HoursQuery = require("./HoursQuery"); function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); } function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } function _iterableToArrayLimit(arr, i) { if (typeof Symbol === "undefined" || !(Symbol.iterator in Object(arr))) return; var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } var VisitingHours = /*#__PURE__*/function () { function VisitingHours(_ref) { var regular = _ref.regular, special = _ref.special, zone = _ref.zone, live = _ref.live; _classCallCheck(this, VisitingHours); _defineProperty(this, "zone", void 0); _defineProperty(this, "live", void 0); _defineProperty(this, "lastTimeStamp", null); _defineProperty(this, "lastMatch", null); _defineProperty(this, "validUntil", 0); _defineProperty(this, "hoursIndex", void 0); this.hoursIndex = new _HoursIndex.HoursIndex({ regularIndex: regular ? _Utils.Utils.buildIndex(regular) : undefined, specialIndex: special ? _Utils.Utils.buildSpecialIndex(special) : undefined }); if (zone) this.zone = zone; this.live = !!live; } _createClass(VisitingHours, [{ key: "isOpen", value: function isOpen(inputDate) { var date = this.getDateInput(inputDate); var cacheResult = this.checkCache(date); if (cacheResult) return cacheResult; var hour = date.hour, minute = date.minute, month = date.month, day = date.day, zoneName = date.zoneName, ts = date.ts; var zone = zoneName || this.zone; var key = +"".concat(hour).concat(minute.toString().padStart(2, '0')); var _this$hoursIndex$date = this.hoursIndex.dateKeys(date), regularDate = _this$hoursIndex$date.regularDate, specialDate = _this$hoursIndex$date.specialDate, leapYearDate = _this$hoursIndex$date.leapYearDate, postLeapYearDate = _this$hoursIndex$date.postLeapYearDate; if (postLeapYearDate && month === 2 && day === 1 && date.isInLeapYear) { var result = this.hoursIndex.checkSpecialDay(new _HoursQuery.HoursQuery(key, postLeapYearDate, !this.live, zone, ts)); if (typeof result !== 'undefined') return this.writeCache(result, date); } if (leapYearDate && (month === 1 && day === 29 || month === 2 && day === 1 && !date.isInLeapYear)) { var _result = this.hoursIndex.checkSpecialDay(new _HoursQuery.HoursQuery(key, leapYearDate, !this.live, zone, ts)); if (typeof _result !== 'undefined') return this.writeCache(_result, date); } if (specialDate) { var _result2 = this.hoursIndex.checkSpecialDay(new _HoursQuery.HoursQuery(key, specialDate, !this.live, zone, ts)); if (typeof _result2 !== 'undefined') return this.writeCache(_result2, date); } return this.writeCache(this.hoursIndex.checkDay(new _HoursQuery.HoursQuery(key, regularDate, !this.live, zone, ts)), date); } /** * Returns all the remaining hour ranges for the provided date, included left-overs past midnight. */ }, { key: "getRemainingHours", value: function getRemainingHours(inputDate) { var _ref2, _specialDate$raw; var date = this.getDateInput(inputDate); var hour = date.hour, minute = date.minute, month = date.month, day = date.day, zoneName = date.zoneName, ts = date.ts; var zone = zoneName || this.zone; var key = +"".concat(hour).concat(minute.toString().padStart(2, '0')); var _this$hoursIndex$date2 = this.hoursIndex.dateKeys(date), regularDate = _this$hoursIndex$date2.regularDate, specialDate = _this$hoursIndex$date2.specialDate, leapYearDate = _this$hoursIndex$date2.leapYearDate, postLeapYearDate = _this$hoursIndex$date2.postLeapYearDate; var allHours = []; function addBase(forHours) { var lowest = 2400; forHours.forEach(function (h) { var _Utils$timeValues = _Utils.Utils.timeValues(h), _Utils$timeValues2 = _slicedToArray(_Utils$timeValues, 2), o = _Utils$timeValues2[0], c = _Utils$timeValues2[1]; // We only want future times here. if ((c < o ? c + 2400 : c) < key) return; allHours.push({ open: new _VisitingHour.VisitingHour({ timeValue: o > key ? o : key, relativeToTimestamp: ts, zone: zone }), close: new _VisitingHour.VisitingHour({ timeValue: c, relativeToTimestamp: ts, zone: zone }) }); if (o < lowest) lowest = o; }); return lowest; } var lowest = addBase((_ref2 = (_specialDate$raw = specialDate === null || specialDate === void 0 ? void 0 : specialDate.raw) !== null && _specialDate$raw !== void 0 ? _specialDate$raw : regularDate === null || regularDate === void 0 ? void 0 : regularDate.raw) !== null && _ref2 !== void 0 ? _ref2 : []); // Lowest is already at midnight, so it really doesn't matter what else there is. if (lowest === 0) { return allHours; } function collect(hours) { var hour = hours === null || hours === void 0 ? void 0 : hours.find(function (_ref3) { var _ref4 = _slicedToArray(_ref3, 2), o = _ref4[0], c = _ref4[1]; return o === 0 && c > key && c < lowest; }); if (hour) allHours.push({ open: new _VisitingHour.VisitingHour({ timeValue: key, relativeToTimestamp: ts, zone: zone }), close: new _VisitingHour.VisitingHour({ timeValue: hour[1], relativeToTimestamp: ts, zone: zone }) }); } // Now let's collect a range past midnight. It can only be one of these. if ((postLeapYearDate === null || postLeapYearDate === void 0 ? void 0 : postLeapYearDate.pastMidnight) && month === 2 && day === 1 && date.isInLeapYear) { collect(postLeapYearDate.hours); } else if ((leapYearDate === null || leapYearDate === void 0 ? void 0 : leapYearDate.pastMidnight) && (month === 1 && day === 29 || month === 2 && day === 1 && !date.isInLeapYear)) { collect(leapYearDate.hours); } else if (specialDate === null || specialDate === void 0 ? void 0 : specialDate.pastMidnight) { collect(specialDate.hours); } else if (regularDate === null || regularDate === void 0 ? void 0 : regularDate.pastMidnight) { collect(regularDate.hours); } return allHours.sort(function (a, b) { return a.open.timeValue - b.open.timeValue; }); } }, { key: "getDateInput", value: function getDateInput(inputDate) { var asLuxon = inputDate; return inputDate instanceof Date ? _Utils.Utils.fromDate(inputDate, this.zone) : asLuxon.isLuxonDateTime ? _Utils.Utils.fromLuxon(asLuxon) : inputDate; } }, { key: "checkCache", value: function checkCache(input) { var _this$lastTimeStamp; if (!this.live || !this.lastMatch || input.ts >= this.validUntil || ((_this$lastTimeStamp = this === null || this === void 0 ? void 0 : this.lastTimeStamp) !== null && _this$lastTimeStamp !== void 0 ? _this$lastTimeStamp : 0) > input.ts) return; return this.lastMatch; } }, { key: "sourceDate", value: function sourceDate(source, zoneName) { if (!zoneName || Intl.DateTimeFormat().resolvedOptions().timeZone === zoneName) { return { source: source, offset: 0 }; } var inTZ = _Timezone.Timezone.utcToZonedTime(source, zoneName); return { source: inTZ, offset: source.getTime() - inTZ.getTime() }; } // @todo see if we can use Timezone.fromTimeValues here }, { key: "writeCache", value: function writeCache(hoursMatch, input) { var _cache$hours, _cache$minutes; if (!this.live) return hoursMatch; var open = hoursMatch.open, match = hoursMatch.match, soonest = hoursMatch.soonest; var _this$sourceDate = this.sourceDate(new Date(input.ts), input.zoneName), source = _this$sourceDate.source, offset = _this$sourceDate.offset; var cache = open && match ? match.close : soonest instanceof _VisitingHour.VisitingHour ? soonest : null; source.setHours((_cache$hours = cache === null || cache === void 0 ? void 0 : cache.hours) !== null && _cache$hours !== void 0 ? _cache$hours : 0); source.setMinutes((_cache$minutes = cache === null || cache === void 0 ? void 0 : cache.minutes) !== null && _cache$minutes !== void 0 ? _cache$minutes : 0); source.setSeconds(0); source.setMilliseconds(offset); if (!cache) source.setDate(source.getDate() + 1); this.lastTimeStamp = input.ts; this.validUntil = source.getTime(); this.lastMatch = hoursMatch; return hoursMatch; } }]); return VisitingHours; }(); exports.VisitingHours = VisitingHours;