visiting-hours
Version:
An advanced, feature rich, optimised and tiny visiting-hours library.
266 lines (210 loc) • 11.6 kB
JavaScript
"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;