busroot-sdk 0.0.8-dev.2920350130 → 0.0.8-dev.2920950808
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/index.js +63 -29
- package/package.json +1 -1
package/build/index.js
CHANGED
|
@@ -38,6 +38,7 @@ var require_time = __commonJS({
|
|
|
38
38
|
exports2.Crons = exports2.TimeIntervals = exports2.TimeRange = void 0;
|
|
39
39
|
exports2.getTimeIntervalFromString = getTimeIntervalFromString;
|
|
40
40
|
exports2.getTimeIntervalKeyFromMs = getTimeIntervalKeyFromMs;
|
|
41
|
+
exports2.nominalDurationMs = nominalDurationMs;
|
|
41
42
|
exports2.millisToSec = millisToSec;
|
|
42
43
|
var zod_1 = require("zod");
|
|
43
44
|
exports2.TimeRange = zod_1.z.object({
|
|
@@ -95,6 +96,15 @@ var require_time = __commonJS({
|
|
|
95
96
|
}
|
|
96
97
|
return void 0;
|
|
97
98
|
}
|
|
99
|
+
var MAX_CLOCK_CHANGE_MS = exports2.TimeIntervals["1h"].ms;
|
|
100
|
+
function nominalDurationMs(durationMs) {
|
|
101
|
+
const dayMs = exports2.TimeIntervals["1d"].ms;
|
|
102
|
+
const wholeDays = Math.round(durationMs / dayMs);
|
|
103
|
+
if (wholeDays >= 1 && Math.abs(durationMs - wholeDays * dayMs) <= MAX_CLOCK_CHANGE_MS) {
|
|
104
|
+
return wholeDays * dayMs;
|
|
105
|
+
}
|
|
106
|
+
return durationMs;
|
|
107
|
+
}
|
|
98
108
|
function millisToSec(millis) {
|
|
99
109
|
return millis / 1e3;
|
|
100
110
|
}
|
|
@@ -554,6 +564,7 @@ var require_times = __commonJS({
|
|
|
554
564
|
exports2.fromSpecificHourString = fromSpecificHourString;
|
|
555
565
|
exports2.plantWeekNumber = plantWeekNumber;
|
|
556
566
|
exports2.plantWeekStart = plantWeekStart;
|
|
567
|
+
exports2.addPlantDays = addPlantDays;
|
|
557
568
|
exports2.getTimeRangeFromRangeCode = getTimeRangeFromRangeCode;
|
|
558
569
|
exports2.getCoverage = getCoverage;
|
|
559
570
|
exports2.getWindowAtTime = getWindowAtTime;
|
|
@@ -568,6 +579,7 @@ var require_times = __commonJS({
|
|
|
568
579
|
exports2.getDayRangeCode = getDayRangeCode;
|
|
569
580
|
exports2.getCurrentWeekRangeCode = getCurrentWeekRangeCode;
|
|
570
581
|
exports2.generateTimeWindows = generateTimeWindows;
|
|
582
|
+
exports2.generatePlantDayWindows = generatePlantDayWindows;
|
|
571
583
|
exports2.BusrootDateTimeParse = BusrootDateTimeParse;
|
|
572
584
|
exports2.decimalHoursToTime = decimalHoursToTime;
|
|
573
585
|
var moment_timezone_1 = __importStar(require("moment-timezone"));
|
|
@@ -744,7 +756,8 @@ var require_times = __commonJS({
|
|
|
744
756
|
}
|
|
745
757
|
];
|
|
746
758
|
function getAllowedAggregationWindowsForDuration(durationMs) {
|
|
747
|
-
const
|
|
759
|
+
const nominalMs = (0, time_1.nominalDurationMs)(durationMs);
|
|
760
|
+
const allowedAggregationWindows = AllowedAggregationWindows.find((a) => nominalMs <= a.durationMs)?.allowedAggregationWindows;
|
|
748
761
|
return allowedAggregationWindows;
|
|
749
762
|
}
|
|
750
763
|
function getTimestampFromString(timeString) {
|
|
@@ -978,6 +991,15 @@ var require_times = __commonJS({
|
|
|
978
991
|
}
|
|
979
992
|
return start;
|
|
980
993
|
}
|
|
994
|
+
var DAYS_PER_WEEK = 7;
|
|
995
|
+
function plantDayRange(date, days, dayStartHour) {
|
|
996
|
+
const from = date.clone().add(dayStartHour, "hour").valueOf();
|
|
997
|
+
const to = date.clone().add(days, "days").add(dayStartHour, "hour").valueOf();
|
|
998
|
+
return timestampsToTimeRange({ from, to });
|
|
999
|
+
}
|
|
1000
|
+
function addPlantDays(instant, days, timezone) {
|
|
1001
|
+
return (0, moment_timezone_1.default)(instant).tz(timezone).add(days, "days").valueOf();
|
|
1002
|
+
}
|
|
981
1003
|
function floorToPlantWeekStart(instant, plant) {
|
|
982
1004
|
const weekStartDay = plant.weekStartDay ?? 0;
|
|
983
1005
|
return (0, moment_timezone_1.default)(instant).tz(plant.timezone).subtract(weekStartDay, "days").subtract(plant.dayStartHour, "hours").startOf("isoWeek").add(weekStartDay, "days").add(plant.dayStartHour, "hours").valueOf();
|
|
@@ -1037,36 +1059,33 @@ var require_times = __commonJS({
|
|
|
1037
1059
|
day.utc();
|
|
1038
1060
|
return timestampsToTimeRange({ from: day.valueOf(), to: day.add(1, "hours").valueOf() });
|
|
1039
1061
|
},
|
|
1062
|
+
// Every range below ends where the next one of its kind starts, built on the plant's local calendar
|
|
1063
|
+
// (add whole days/months, then dayStartHour) and only then read as UTC. Adding a fixed n×24h instead
|
|
1064
|
+
// would make a range that contains a daylight-saving change an hour too long or short, leaving gaps
|
|
1065
|
+
// and overlaps between consecutive ranges.
|
|
1066
|
+
//
|
|
1040
1067
|
// TODAY/YESTERDAY: subtract dayStartHour before startOf("day") to find the
|
|
1041
1068
|
// correct production day boundary, then re-add it. This handles the case where
|
|
1042
1069
|
// e.g. it's 02:00 but the production day started at 06:00 the previous calendar day.
|
|
1043
1070
|
today: () => {
|
|
1044
|
-
const
|
|
1045
|
-
|
|
1046
|
-
return timestampsToTimeRange({ from: day.valueOf(), to: day.add(24, "hours").valueOf() });
|
|
1071
|
+
const date = (0, moment_timezone_1.default)(now).tz(plant.timezone).add(-plant.dayStartHour, "hour").startOf("day");
|
|
1072
|
+
return plantDayRange(date, 1, plant.dayStartHour);
|
|
1047
1073
|
},
|
|
1048
1074
|
yesterday: () => {
|
|
1049
|
-
const
|
|
1050
|
-
|
|
1051
|
-
return timestampsToTimeRange({ from: day.valueOf(), to: day.add(24, "hours").valueOf() });
|
|
1075
|
+
const date = (0, moment_timezone_1.default)(now).tz(plant.timezone).add(-plant.dayStartHour, "hour").startOf("day").add(-1, "day");
|
|
1076
|
+
return plantDayRange(date, 1, plant.dayStartHour);
|
|
1052
1077
|
},
|
|
1053
1078
|
day: () => {
|
|
1054
|
-
const
|
|
1055
|
-
|
|
1056
|
-
day.utc();
|
|
1057
|
-
return timestampsToTimeRange({ from: day.valueOf(), to: day.add(24, "hours").valueOf() });
|
|
1079
|
+
const date = moment_timezone_1.default.tz(`${parseInt(parts[1])}_${parseInt(parts[2])}_${parseInt(parts[3])}`, "YYYY_MM_DD", plant.timezone);
|
|
1080
|
+
return plantDayRange(date, 1, plant.dayStartHour);
|
|
1058
1081
|
},
|
|
1059
1082
|
week: () => {
|
|
1060
1083
|
const week = plantWeekStart(parseInt(parts[1]), parseInt(parts[2]), plant.weekStartDay ?? 0, plant.timezone);
|
|
1061
|
-
week
|
|
1062
|
-
week.utc();
|
|
1063
|
-
return timestampsToTimeRange({ from: week.valueOf(), to: week.add(24 * 7, "hours").valueOf() });
|
|
1084
|
+
return plantDayRange(week, DAYS_PER_WEEK, plant.dayStartHour);
|
|
1064
1085
|
},
|
|
1065
1086
|
month: () => {
|
|
1066
1087
|
const month = moment_timezone_1.default.tz(`${parseInt(parts[1])}_${parseInt(parts[2])}}`, "YYYY_MM", plant.timezone).startOf("month");
|
|
1067
|
-
month.
|
|
1068
|
-
month.utc();
|
|
1069
|
-
return timestampsToTimeRange({ from: month.valueOf(), to: month.add(month.daysInMonth() * 24, "hours").valueOf() });
|
|
1088
|
+
return plantDayRange(month, month.daysInMonth(), plant.dayStartHour);
|
|
1070
1089
|
},
|
|
1071
1090
|
// QUARTER: 13 ISO weeks (14 for Q4 in 53-week years). Start at the first ISO week of the quarter,
|
|
1072
1091
|
// then apply the plant's weekStartDay and dayStartHour offsets exactly like the week handler.
|
|
@@ -1076,18 +1095,14 @@ var require_times = __commonJS({
|
|
|
1076
1095
|
const weeks = getWeeksInQuarter(year, quarter);
|
|
1077
1096
|
const firstWeek = weeks[0];
|
|
1078
1097
|
const start = plantWeekStart(year, firstWeek, plant.weekStartDay ?? 0, plant.timezone);
|
|
1079
|
-
start.
|
|
1080
|
-
start.utc();
|
|
1081
|
-
return timestampsToTimeRange({ from: start.valueOf(), to: start.add(weeks.length * 7 * 24, "hours").valueOf() });
|
|
1098
|
+
return plantDayRange(start, weeks.length * DAYS_PER_WEEK, plant.dayStartHour);
|
|
1082
1099
|
},
|
|
1083
1100
|
// YEAR: full ISO week year (52 or 53 weeks). Start at ISO week 1, apply plant offsets like the week handler.
|
|
1084
1101
|
year: () => {
|
|
1085
1102
|
const year = parseInt(parts[1]);
|
|
1086
1103
|
const weeksInYear = isoWeeksInIsoWeekYear(year);
|
|
1087
1104
|
const start = plantWeekStart(year, 1, plant.weekStartDay ?? 0, plant.timezone);
|
|
1088
|
-
start
|
|
1089
|
-
start.utc();
|
|
1090
|
-
return timestampsToTimeRange({ from: start.valueOf(), to: start.add(weeksInYear * 7 * 24, "hours").valueOf() });
|
|
1105
|
+
return plantDayRange(start, weeksInYear * DAYS_PER_WEEK, plant.dayStartHour);
|
|
1091
1106
|
},
|
|
1092
1107
|
custom: () => timestampsToTimeRange({ from: 0, to: 0 }),
|
|
1093
1108
|
// Already handled above
|
|
@@ -1383,6 +1398,25 @@ var require_times = __commonJS({
|
|
|
1383
1398
|
endAt: (0, moment_timezone_1.default)(endAtTimestamp).toISOString()
|
|
1384
1399
|
};
|
|
1385
1400
|
}
|
|
1401
|
+
function generatePlantDayWindows(startAt, days, until, timezone) {
|
|
1402
|
+
const windows = [];
|
|
1403
|
+
let endAtTimestamp = 0;
|
|
1404
|
+
for (let i = 0; ; i++) {
|
|
1405
|
+
const windowStartAtTimestamp = addPlantDays(startAt, days * i, timezone);
|
|
1406
|
+
const windowEndAtTimestamp = addPlantDays(startAt, days * (i + 1), timezone);
|
|
1407
|
+
if (windowEndAtTimestamp > until) {
|
|
1408
|
+
break;
|
|
1409
|
+
}
|
|
1410
|
+
endAtTimestamp = windowEndAtTimestamp;
|
|
1411
|
+
windows.push({
|
|
1412
|
+
windowStartAtTimestamp,
|
|
1413
|
+
windowEndAtTimestamp,
|
|
1414
|
+
windowStartAt: (0, moment_timezone_1.default)(windowStartAtTimestamp).toISOString(),
|
|
1415
|
+
windowEndAt: (0, moment_timezone_1.default)(windowEndAtTimestamp).toISOString()
|
|
1416
|
+
});
|
|
1417
|
+
}
|
|
1418
|
+
return { windows, endAtTimestamp };
|
|
1419
|
+
}
|
|
1386
1420
|
function BusrootDateTimeParse(obj, now = moment_timezone_1.default.utc().valueOf()) {
|
|
1387
1421
|
const fields = ["plannedStartAt", "plannedEndAt", "actualStartAt", "actualEndAt"];
|
|
1388
1422
|
for (const field of fields) {
|
|
@@ -9907,11 +9941,11 @@ var require_station_windows = __commonJS({
|
|
|
9907
9941
|
if (windows.length === 0) {
|
|
9908
9942
|
throw new Error("Must be at least 1 window.");
|
|
9909
9943
|
}
|
|
9910
|
-
const windowDuration = windows[0].totalMs;
|
|
9944
|
+
const windowDuration = (0, time_1.nominalDurationMs)(windows[0].totalMs);
|
|
9911
9945
|
const window2 = windows.reduce((a, b, i) => {
|
|
9912
9946
|
const isFirstWindow = i === 0;
|
|
9913
9947
|
const isConsecutive = a.windowEndAt === b.windowStartAt;
|
|
9914
|
-
const isSameDuration = b.totalMs === windowDuration;
|
|
9948
|
+
const isSameDuration = (0, time_1.nominalDurationMs)(b.totalMs) === windowDuration;
|
|
9915
9949
|
if (!isFirstWindow && !skipConsecutiveCheck) {
|
|
9916
9950
|
if (!isConsecutive) {
|
|
9917
9951
|
throw new Error("Windows are not consecutive.");
|
|
@@ -10190,7 +10224,7 @@ var require_station_windows = __commonJS({
|
|
|
10190
10224
|
const batch = [];
|
|
10191
10225
|
for (let i = 0; i < windows.length; i++) {
|
|
10192
10226
|
const thisWindow = windows[i];
|
|
10193
|
-
const thisWindowDuration = thisWindow.windowEndAtTimestamp - thisWindow.windowStartAtTimestamp;
|
|
10227
|
+
const thisWindowDuration = (0, time_1.nominalDurationMs)(thisWindow.windowEndAtTimestamp - thisWindow.windowStartAtTimestamp);
|
|
10194
10228
|
if (thisWindowDuration > aggregateWindowInMs) {
|
|
10195
10229
|
throw new Error("Windows being aggregated must be less than or equal to the aggregate window. " + windows[i].totalMs + " " + aggregateWindowInMinutes);
|
|
10196
10230
|
}
|
|
@@ -10202,7 +10236,7 @@ var require_station_windows = __commonJS({
|
|
|
10202
10236
|
}
|
|
10203
10237
|
}
|
|
10204
10238
|
batch.push(windows[i]);
|
|
10205
|
-
const durationOfBatch = batch.reduce((a, b) => a + b.totalMs, 0);
|
|
10239
|
+
const durationOfBatch = batch.reduce((a, b) => a + (0, time_1.nominalDurationMs)(b.totalMs), 0);
|
|
10206
10240
|
if (durationOfBatch >= aggregateWindowInMs) {
|
|
10207
10241
|
aggregatedWindows.push(combineStationWindows(batch, inShiftAverages));
|
|
10208
10242
|
batch.length = 0;
|
|
@@ -10213,8 +10247,8 @@ var require_station_windows = __commonJS({
|
|
|
10213
10247
|
const lastAggregatedWindowEndAtTimestamp = aggregatedWindows[aggregatedWindows.length - 1]?.windowEndAtTimestamp;
|
|
10214
10248
|
const lastWindowEndAtTimestamp = lastAggregatedWindowEndAtTimestamp ?? windows[windows.length - 1].windowEndAtTimestamp;
|
|
10215
10249
|
const futureWindowsStartAt = lastAggregatedWindowEndAtTimestamp == null && aggregateWindowInMinutes < time_1.TimeIntervals["1h"].min ? lastWindowEndAtTimestamp - lastWindowEndAtTimestamp % windowDurationMs : lastWindowEndAtTimestamp;
|
|
10216
|
-
const
|
|
10217
|
-
const { windows: futureTimeWindows, endAtTimestamp } = (0, times_1.generateTimeWindows)(futureWindowsStartAt, windowDurationMs,
|
|
10250
|
+
const windowDays = windowDurationMs / time_1.TimeIntervals["1d"].ms;
|
|
10251
|
+
const { windows: futureTimeWindows, endAtTimestamp } = Number.isInteger(windowDays) ? (0, times_1.generatePlantDayWindows)(futureWindowsStartAt, windowDays, includeFutureWindowsUntil, station.timezone) : (0, times_1.generateTimeWindows)(futureWindowsStartAt, windowDurationMs, Math.floor((includeFutureWindowsUntil - futureWindowsStartAt) / windowDurationMs), void 0, false);
|
|
10218
10252
|
const futureWindows = futureTimeWindows.map((x) => {
|
|
10219
10253
|
const isInShift = shiftUtils.isTimeInShifts({
|
|
10220
10254
|
time: x.windowStartAtTimestamp,
|
package/package.json
CHANGED