busroot-sdk 0.0.8-dev.2920350130 → 0.0.8-dev.2922257515

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.
Files changed (2) hide show
  1. package/build/index.js +125 -45
  2. 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
  }
@@ -359,7 +369,7 @@ var require_error_key = __commonJS({
359
369
  Object.defineProperty(exports2, "__esModule", { value: true });
360
370
  exports2.TARGET_STATION_NOT_FOUND = exports2.INVALID_PARTS_PER_CYCLE = exports2.PARTS_PER_CYCLE_NOT_ALLOWED_FOR_STATION = exports2.SCHEDULE_CANNOT_STOP_FUTURE = exports2.SCHEDULE_NON_PROD_OR_ENDED = exports2.SCHEDULE_CANNOT_CUT_SHORT = exports2.SCHEDULE_AUTO_ENDED_BY_QUANTITY = exports2.SCHEDULE_NOT_STARTED_OR_ENDED = exports2.ACTUAL_START_IN_PAST = exports2.PLANNED_START_IN_PAST = exports2.SCHEDULE_CANNOT_CHANGE_PROD_TO_NON_PROD = exports2.SCHEDULE_CANNOT_CHANGE_NON_PROD_TO_PROD = exports2.SCHEDULE_CANNOT_SET_PRIORITY_AFTER_START = exports2.SCHEDULE_ALREADY_STARTED_CANNOT_EDIT_START = exports2.SCHEDULE_ALREADY_ENDED = exports2.UNSUPPORTED_SCHEDULE_OPERATION = exports2.INVALID_RESOLUTION_MODE = exports2.EXISTED_EVENT = exports2.INVALID_SEARCH_TEXT = exports2.INVALID_SKIP = exports2.INVALID_LIMIT = exports2.INVALID_WINDOW_TIME = exports2.INVALID_NOTIFICATION_PREFERENCE = exports2.OVERLAPPED_SHIFT = exports2.INVALID_SHIFT_NAME = exports2.INVALID_WEEK_DAY = exports2.INVALID_FILE_TYPE = exports2.INVALID_HEADER_FIELDS = exports2.DELETE_LAST_SHIFT_PATTERN = exports2.INVALID_ACTUAL_START_AT_STATE = exports2.INVALID_DOMAIN = exports2.SKU_NOT_FOUND = exports2.STATION_GROUP_NOT_FOUND = exports2.WORK_ORDER_ENDED = exports2.SCHEDULE_NOT_FOUND = exports2.INVALID_SKU = exports2.INVALID_SCHEDULE = exports2.EXPIRED_TOKEN = exports2.UNAUTHORIZED_USER = exports2.UNAUTHENTICATED_USER = exports2.SHIFT_PATTERN_NOT_FOUND = exports2.INVALID_SHIFT_PATTERN_TITLE = exports2.INVALID_SHIFT_PATTERN_ID = exports2.INVALID_DELETE_SHIFTS = exports2.UNSUPPORTED_SHIFT_OVER_MID_NIGHT = exports2.INVALID_SHIFTS = exports2.INVALID_PLANTCODE = exports2.INVALID_RANGECODE = exports2.INTERNAL_SERVER_ERROR = exports2.CACHE_NOT_COMPLETE = void 0;
361
371
  exports2.INVALID_USER_ACCOUNT = exports2.NO_ACCOUNT_AVAILABLE = exports2.EXPIRED_USER = exports2.USER_IS_BLOCKED = exports2.INVALID_USER = exports2.USER_ALREADY_EXISTS = exports2.USER_NOT_FOUND = exports2.MULTIPLE_ACCOUNT_ASSOCIATED = exports2.UNSUPPORTED_USER_OPERATION = exports2.EMAIL_TYPE_NOT_FOUND = exports2.INVALID_STATION_CODE = exports2.DUPLICATED_STATION_CODE = exports2.DUPLICATED_STATION_GROUP_CODE = exports2.INVALID_INPUT = exports2.DUPLICATED_SKU_CODE = exports2.INVALID_SKU_CODE = exports2.TOO_LARGE = exports2.BUSINESS_CONFLICT = exports2.FORBIDDEN = exports2.INVALID_ACCESS_CODE = exports2.EXPIRED_API_KEY = exports2.UNSUPPORTED_ARCHIVE_LAST_PLANT = exports2.PLANT_NOT_EXISTS = exports2.NOT_EMPTY_STATION_GROUP = exports2.INVALID_AGGREGATE_WINDOW = exports2.DUPLICATED_SCHEDULE = exports2.INVALID_SCHEDULE_ORDER_TYPE = exports2.INVALID_SKU_GROUP_NAME = exports2.SKU_GROUP_NOT_FOUND = exports2.INVALID_SKU_GROUP = exports2.INVALID_DOWNTIMNE_DURATION_THRESHOLD_MULTIPLIER = exports2.REASON_NOT_DOWNTIME_TYPE = exports2.MANUAL_DOWNTIME_NO_ACTIVE_SCHEDULE = exports2.MANUAL_DOWNTIME_ALREADY_ONGOING = exports2.CACHE_WARMING_DISABLED = exports2.MANUAL_DOWNTIME_DISABLED = exports2.DOWNTIME_NOT_MANUAL = exports2.DOWNTIME_NOT_FOUND = exports2.STATION_NOT_FOUND = exports2.TASK_COMPLETION_MISSED = exports2.TASK_COMPLETION_ALREADY_COMPLETED = exports2.TASK_COMPLETION_NOT_FOUND = exports2.TASK_LIST_NOT_FOUND = exports2.TASK_NOT_FOUND = exports2.REPORTED_BY_REQUIRED = exports2.REASON_NOTE_REQUIRED = exports2.REASON_NOT_ALLOWED_FOR_STATION = exports2.REASON_NOT_FOUND = exports2.SKU_REQUIRED = exports2.STATION_REASSIGN_CROSS_GROUP = void 0;
362
- exports2.TOO_MANY_ACCESS_CODE_ATTEMPTS = exports2.TOO_MANY_REQUESTS = exports2.HISTORICAL_CORRECTION_LIMIT_REACHED = exports2.HISTORICAL_CORRECTION_CURSOR_RESET_FAILED = exports2.HISTORICAL_CORRECTION_WINDOW_EXPIRED = exports2.SCHEDULE_NOT_CORRECTABLE = exports2.HISTORICAL_CORRECTION_NOT_ALLOWED = exports2.PRODUCTION_EXCEEDS_MAX_COUNT = exports2.PRODUCTION_BLOCKED_BY_MANUAL_DOWNTIME = exports2.PRODUCTION_CORRECTION_NOT_ALLOWED = exports2.PRODUCTION_QUANTITY_BELOW_ZERO = exports2.INVALID_PRODUCTION_ID = exports2.RESET_EXCEED_30_DAYS = exports2.INVALID_REASON_CODE = exports2.SELF_REFERENCING_CODE = exports2.PARENT_CODE_IN_USE = exports2.DUPLICATED_REASON_CODE = exports2.DATABASE_ERROR_MESSAGE = exports2.INVALID_API_KEY = exports2.UNSUPPORTED_API_KEY_OPERATION = exports2.ACCOUNT_ARCHIVED = exports2.ACCOUNT_DENIED = exports2.ACCOUNT_NOT_FOUND = exports2.ACCOUNT_MISMATCH = exports2.USER_ACCOUNT_IS_BLOCKED = exports2.ACCOUNT_NOT_SELECTED = void 0;
372
+ exports2.TOO_MANY_ACCESS_CODE_ATTEMPTS = exports2.TOO_MANY_REQUESTS = exports2.HISTORICAL_CORRECTION_LIMIT_REACHED = exports2.HISTORICAL_CORRECTION_CURSOR_RESET_FAILED = exports2.HISTORICAL_CORRECTION_WINDOW_EXPIRED = exports2.SCHEDULE_NOT_CORRECTABLE = exports2.HISTORICAL_CORRECTION_NOT_ALLOWED = exports2.PRODUCTION_EXCEEDS_MAX_COUNT = exports2.PRODUCTION_BLOCKED_BY_MANUAL_DOWNTIME = exports2.PRODUCTION_CORRECTION_NOT_ALLOWED = exports2.PRODUCTION_QUANTITY_BELOW_ZERO = exports2.INVALID_PRODUCTION_ID = exports2.RESET_EXCEED_30_DAYS = exports2.INVALID_REASON_CODE = exports2.SELF_REFERENCING_CODE = exports2.PARENT_CODE_IN_USE = exports2.DUPLICATED_REASON_CODE = exports2.DATABASE_ERROR_MESSAGE = exports2.INVALID_API_KEY = exports2.UNSUPPORTED_API_KEY_OPERATION = exports2.ACCOUNT_ARCHIVED = exports2.ACCOUNT_DENIED = exports2.ACCOUNT_NOT_FOUND = exports2.MANIFEST_REVISION_MISMATCH = exports2.MANIFEST_REVISION_REQUIRED = exports2.PRECONDITION_REQUIRED = exports2.ACCOUNT_MISMATCH = exports2.USER_ACCOUNT_IS_BLOCKED = exports2.ACCOUNT_NOT_SELECTED = void 0;
363
373
  exports2.CACHE_NOT_COMPLETE = "cacheNotComplete";
364
374
  exports2.INTERNAL_SERVER_ERROR = "internalServerError";
365
375
  exports2.INVALID_RANGECODE = "invalidRangeCode";
@@ -463,6 +473,9 @@ var require_error_key = __commonJS({
463
473
  exports2.ACCOUNT_NOT_SELECTED = "accountNotSelected";
464
474
  exports2.USER_ACCOUNT_IS_BLOCKED = "userAccountIsBlocked";
465
475
  exports2.ACCOUNT_MISMATCH = "accountMismatch";
476
+ exports2.PRECONDITION_REQUIRED = "preconditionRequired";
477
+ exports2.MANIFEST_REVISION_REQUIRED = "manifestRevisionRequired";
478
+ exports2.MANIFEST_REVISION_MISMATCH = "manifestRevisionMismatch";
466
479
  exports2.ACCOUNT_NOT_FOUND = "accountNotFound";
467
480
  exports2.ACCOUNT_DENIED = "accountDenied";
468
481
  exports2.ACCOUNT_ARCHIVED = "accountArchived";
@@ -554,6 +567,7 @@ var require_times = __commonJS({
554
567
  exports2.fromSpecificHourString = fromSpecificHourString;
555
568
  exports2.plantWeekNumber = plantWeekNumber;
556
569
  exports2.plantWeekStart = plantWeekStart;
570
+ exports2.addPlantDays = addPlantDays;
557
571
  exports2.getTimeRangeFromRangeCode = getTimeRangeFromRangeCode;
558
572
  exports2.getCoverage = getCoverage;
559
573
  exports2.getWindowAtTime = getWindowAtTime;
@@ -568,6 +582,7 @@ var require_times = __commonJS({
568
582
  exports2.getDayRangeCode = getDayRangeCode;
569
583
  exports2.getCurrentWeekRangeCode = getCurrentWeekRangeCode;
570
584
  exports2.generateTimeWindows = generateTimeWindows;
585
+ exports2.generatePlantDayWindows = generatePlantDayWindows;
571
586
  exports2.BusrootDateTimeParse = BusrootDateTimeParse;
572
587
  exports2.decimalHoursToTime = decimalHoursToTime;
573
588
  var moment_timezone_1 = __importStar(require("moment-timezone"));
@@ -744,7 +759,8 @@ var require_times = __commonJS({
744
759
  }
745
760
  ];
746
761
  function getAllowedAggregationWindowsForDuration(durationMs) {
747
- const allowedAggregationWindows = AllowedAggregationWindows.find((a) => durationMs <= a.durationMs)?.allowedAggregationWindows;
762
+ const nominalMs = (0, time_1.nominalDurationMs)(durationMs);
763
+ const allowedAggregationWindows = AllowedAggregationWindows.find((a) => nominalMs <= a.durationMs)?.allowedAggregationWindows;
748
764
  return allowedAggregationWindows;
749
765
  }
750
766
  function getTimestampFromString(timeString) {
@@ -978,6 +994,15 @@ var require_times = __commonJS({
978
994
  }
979
995
  return start;
980
996
  }
997
+ var DAYS_PER_WEEK = 7;
998
+ function plantDayRange(date, days, dayStartHour) {
999
+ const from = date.clone().add(dayStartHour, "hour").valueOf();
1000
+ const to = date.clone().add(days, "days").add(dayStartHour, "hour").valueOf();
1001
+ return timestampsToTimeRange({ from, to });
1002
+ }
1003
+ function addPlantDays(instant, days, timezone) {
1004
+ return (0, moment_timezone_1.default)(instant).tz(timezone).add(days, "days").valueOf();
1005
+ }
981
1006
  function floorToPlantWeekStart(instant, plant) {
982
1007
  const weekStartDay = plant.weekStartDay ?? 0;
983
1008
  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 +1062,33 @@ var require_times = __commonJS({
1037
1062
  day.utc();
1038
1063
  return timestampsToTimeRange({ from: day.valueOf(), to: day.add(1, "hours").valueOf() });
1039
1064
  },
1065
+ // Every range below ends where the next one of its kind starts, built on the plant's local calendar
1066
+ // (add whole days/months, then dayStartHour) and only then read as UTC. Adding a fixed n×24h instead
1067
+ // would make a range that contains a daylight-saving change an hour too long or short, leaving gaps
1068
+ // and overlaps between consecutive ranges.
1069
+ //
1040
1070
  // TODAY/YESTERDAY: subtract dayStartHour before startOf("day") to find the
1041
1071
  // correct production day boundary, then re-add it. This handles the case where
1042
1072
  // e.g. it's 02:00 but the production day started at 06:00 the previous calendar day.
1043
1073
  today: () => {
1044
- const day = (0, moment_timezone_1.default)(now).tz(plant.timezone).add(-plant.dayStartHour, "hour").startOf("day").add(plant.dayStartHour, "hour");
1045
- day.utc();
1046
- return timestampsToTimeRange({ from: day.valueOf(), to: day.add(24, "hours").valueOf() });
1074
+ const date = (0, moment_timezone_1.default)(now).tz(plant.timezone).add(-plant.dayStartHour, "hour").startOf("day");
1075
+ return plantDayRange(date, 1, plant.dayStartHour);
1047
1076
  },
1048
1077
  yesterday: () => {
1049
- const day = (0, moment_timezone_1.default)(now).tz(plant.timezone).add(-plant.dayStartHour, "hour").startOf("day").add(-1, "day").add(plant.dayStartHour, "hour");
1050
- day.utc();
1051
- return timestampsToTimeRange({ from: day.valueOf(), to: day.add(24, "hours").valueOf() });
1078
+ const date = (0, moment_timezone_1.default)(now).tz(plant.timezone).add(-plant.dayStartHour, "hour").startOf("day").add(-1, "day");
1079
+ return plantDayRange(date, 1, plant.dayStartHour);
1052
1080
  },
1053
1081
  day: () => {
1054
- const day = moment_timezone_1.default.tz(`${parseInt(parts[1])}_${parseInt(parts[2])}_${parseInt(parts[3])}`, "YYYY_MM_DD", plant.timezone);
1055
- day.add(plant.dayStartHour, "hour");
1056
- day.utc();
1057
- return timestampsToTimeRange({ from: day.valueOf(), to: day.add(24, "hours").valueOf() });
1082
+ const date = moment_timezone_1.default.tz(`${parseInt(parts[1])}_${parseInt(parts[2])}_${parseInt(parts[3])}`, "YYYY_MM_DD", plant.timezone);
1083
+ return plantDayRange(date, 1, plant.dayStartHour);
1058
1084
  },
1059
1085
  week: () => {
1060
1086
  const week = plantWeekStart(parseInt(parts[1]), parseInt(parts[2]), plant.weekStartDay ?? 0, plant.timezone);
1061
- week.add(plant.dayStartHour, "hour");
1062
- week.utc();
1063
- return timestampsToTimeRange({ from: week.valueOf(), to: week.add(24 * 7, "hours").valueOf() });
1087
+ return plantDayRange(week, DAYS_PER_WEEK, plant.dayStartHour);
1064
1088
  },
1065
1089
  month: () => {
1066
1090
  const month = moment_timezone_1.default.tz(`${parseInt(parts[1])}_${parseInt(parts[2])}}`, "YYYY_MM", plant.timezone).startOf("month");
1067
- month.add(plant.dayStartHour, "hour");
1068
- month.utc();
1069
- return timestampsToTimeRange({ from: month.valueOf(), to: month.add(month.daysInMonth() * 24, "hours").valueOf() });
1091
+ return plantDayRange(month, month.daysInMonth(), plant.dayStartHour);
1070
1092
  },
1071
1093
  // QUARTER: 13 ISO weeks (14 for Q4 in 53-week years). Start at the first ISO week of the quarter,
1072
1094
  // then apply the plant's weekStartDay and dayStartHour offsets exactly like the week handler.
@@ -1076,18 +1098,14 @@ var require_times = __commonJS({
1076
1098
  const weeks = getWeeksInQuarter(year, quarter);
1077
1099
  const firstWeek = weeks[0];
1078
1100
  const start = plantWeekStart(year, firstWeek, plant.weekStartDay ?? 0, plant.timezone);
1079
- start.add(plant.dayStartHour, "hour");
1080
- start.utc();
1081
- return timestampsToTimeRange({ from: start.valueOf(), to: start.add(weeks.length * 7 * 24, "hours").valueOf() });
1101
+ return plantDayRange(start, weeks.length * DAYS_PER_WEEK, plant.dayStartHour);
1082
1102
  },
1083
1103
  // YEAR: full ISO week year (52 or 53 weeks). Start at ISO week 1, apply plant offsets like the week handler.
1084
1104
  year: () => {
1085
1105
  const year = parseInt(parts[1]);
1086
1106
  const weeksInYear = isoWeeksInIsoWeekYear(year);
1087
1107
  const start = plantWeekStart(year, 1, plant.weekStartDay ?? 0, plant.timezone);
1088
- start.add(plant.dayStartHour, "hour");
1089
- start.utc();
1090
- return timestampsToTimeRange({ from: start.valueOf(), to: start.add(weeksInYear * 7 * 24, "hours").valueOf() });
1108
+ return plantDayRange(start, weeksInYear * DAYS_PER_WEEK, plant.dayStartHour);
1091
1109
  },
1092
1110
  custom: () => timestampsToTimeRange({ from: 0, to: 0 }),
1093
1111
  // Already handled above
@@ -1383,6 +1401,25 @@ var require_times = __commonJS({
1383
1401
  endAt: (0, moment_timezone_1.default)(endAtTimestamp).toISOString()
1384
1402
  };
1385
1403
  }
1404
+ function generatePlantDayWindows(startAt, days, until, timezone) {
1405
+ const windows = [];
1406
+ let endAtTimestamp = 0;
1407
+ for (let i = 0; ; i++) {
1408
+ const windowStartAtTimestamp = addPlantDays(startAt, days * i, timezone);
1409
+ const windowEndAtTimestamp = addPlantDays(startAt, days * (i + 1), timezone);
1410
+ if (windowEndAtTimestamp > until) {
1411
+ break;
1412
+ }
1413
+ endAtTimestamp = windowEndAtTimestamp;
1414
+ windows.push({
1415
+ windowStartAtTimestamp,
1416
+ windowEndAtTimestamp,
1417
+ windowStartAt: (0, moment_timezone_1.default)(windowStartAtTimestamp).toISOString(),
1418
+ windowEndAt: (0, moment_timezone_1.default)(windowEndAtTimestamp).toISOString()
1419
+ });
1420
+ }
1421
+ return { windows, endAtTimestamp };
1422
+ }
1386
1423
  function BusrootDateTimeParse(obj, now = moment_timezone_1.default.utc().valueOf()) {
1387
1424
  const fields = ["plannedStartAt", "plannedEndAt", "actualStartAt", "actualEndAt"];
1388
1425
  for (const field of fields) {
@@ -1652,9 +1689,11 @@ var require_account = __commonJS({
1652
1689
  "../../packages/common/build/schemas/account.js"(exports2) {
1653
1690
  "use strict";
1654
1691
  Object.defineProperty(exports2, "__esModule", { value: true });
1655
- exports2.MANIFEST_HISTORY_MODEL = exports2.ACCOUNT_MODEL = void 0;
1692
+ exports2.MANIFEST_SOURCE_UNKNOWN = exports2.MANIFEST_SOURCE_REPO = exports2.MANIFEST_HISTORY_MODEL = exports2.ACCOUNT_MODEL = void 0;
1656
1693
  exports2.ACCOUNT_MODEL = "account";
1657
1694
  exports2.MANIFEST_HISTORY_MODEL = "manifest_history";
1695
+ exports2.MANIFEST_SOURCE_REPO = "repo";
1696
+ exports2.MANIFEST_SOURCE_UNKNOWN = "unknown";
1658
1697
  }
1659
1698
  });
1660
1699
 
@@ -9907,11 +9946,11 @@ var require_station_windows = __commonJS({
9907
9946
  if (windows.length === 0) {
9908
9947
  throw new Error("Must be at least 1 window.");
9909
9948
  }
9910
- const windowDuration = windows[0].totalMs;
9949
+ const windowDuration = (0, time_1.nominalDurationMs)(windows[0].totalMs);
9911
9950
  const window2 = windows.reduce((a, b, i) => {
9912
9951
  const isFirstWindow = i === 0;
9913
9952
  const isConsecutive = a.windowEndAt === b.windowStartAt;
9914
- const isSameDuration = b.totalMs === windowDuration;
9953
+ const isSameDuration = (0, time_1.nominalDurationMs)(b.totalMs) === windowDuration;
9915
9954
  if (!isFirstWindow && !skipConsecutiveCheck) {
9916
9955
  if (!isConsecutive) {
9917
9956
  throw new Error("Windows are not consecutive.");
@@ -10190,7 +10229,7 @@ var require_station_windows = __commonJS({
10190
10229
  const batch = [];
10191
10230
  for (let i = 0; i < windows.length; i++) {
10192
10231
  const thisWindow = windows[i];
10193
- const thisWindowDuration = thisWindow.windowEndAtTimestamp - thisWindow.windowStartAtTimestamp;
10232
+ const thisWindowDuration = (0, time_1.nominalDurationMs)(thisWindow.windowEndAtTimestamp - thisWindow.windowStartAtTimestamp);
10194
10233
  if (thisWindowDuration > aggregateWindowInMs) {
10195
10234
  throw new Error("Windows being aggregated must be less than or equal to the aggregate window. " + windows[i].totalMs + " " + aggregateWindowInMinutes);
10196
10235
  }
@@ -10202,7 +10241,7 @@ var require_station_windows = __commonJS({
10202
10241
  }
10203
10242
  }
10204
10243
  batch.push(windows[i]);
10205
- const durationOfBatch = batch.reduce((a, b) => a + b.totalMs, 0);
10244
+ const durationOfBatch = batch.reduce((a, b) => a + (0, time_1.nominalDurationMs)(b.totalMs), 0);
10206
10245
  if (durationOfBatch >= aggregateWindowInMs) {
10207
10246
  aggregatedWindows.push(combineStationWindows(batch, inShiftAverages));
10208
10247
  batch.length = 0;
@@ -10213,8 +10252,8 @@ var require_station_windows = __commonJS({
10213
10252
  const lastAggregatedWindowEndAtTimestamp = aggregatedWindows[aggregatedWindows.length - 1]?.windowEndAtTimestamp;
10214
10253
  const lastWindowEndAtTimestamp = lastAggregatedWindowEndAtTimestamp ?? windows[windows.length - 1].windowEndAtTimestamp;
10215
10254
  const futureWindowsStartAt = lastAggregatedWindowEndAtTimestamp == null && aggregateWindowInMinutes < time_1.TimeIntervals["1h"].min ? lastWindowEndAtTimestamp - lastWindowEndAtTimestamp % windowDurationMs : lastWindowEndAtTimestamp;
10216
- const requiredFutureWindowsCount = Math.floor((includeFutureWindowsUntil - futureWindowsStartAt) / windowDurationMs);
10217
- const { windows: futureTimeWindows, endAtTimestamp } = (0, times_1.generateTimeWindows)(futureWindowsStartAt, windowDurationMs, requiredFutureWindowsCount, void 0, false);
10255
+ const windowDays = windowDurationMs / time_1.TimeIntervals["1d"].ms;
10256
+ 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
10257
  const futureWindows = futureTimeWindows.map((x) => {
10219
10258
  const isInShift = shiftUtils.isTimeInShifts({
10220
10259
  time: x.windowStartAtTimestamp,
@@ -10864,6 +10903,35 @@ var require_plant3 = __commonJS({
10864
10903
  }
10865
10904
  });
10866
10905
 
10906
+ // ../../packages/common/build/utils/manifest-revision.js
10907
+ var require_manifest_revision = __commonJS({
10908
+ "../../packages/common/build/utils/manifest-revision.js"(exports2) {
10909
+ "use strict";
10910
+ Object.defineProperty(exports2, "__esModule", { value: true });
10911
+ exports2.ManifestRevisionMismatchError = void 0;
10912
+ exports2.manifestRevision = manifestRevision;
10913
+ exports2.isManifestRevisionMismatch = isManifestRevisionMismatch;
10914
+ var crypto_1 = require("crypto");
10915
+ function manifestRevision(manifestJson) {
10916
+ return (0, crypto_1.createHash)("sha256").update(manifestJson ?? "").digest("hex");
10917
+ }
10918
+ var MANIFEST_REVISION_MISMATCH_ERROR = "ManifestRevisionMismatchError";
10919
+ var ManifestRevisionMismatchError = class extends Error {
10920
+ constructor(accountId, expectedRevision, currentRevision) {
10921
+ super(`Manifest of ${accountId} is at revision ${currentRevision}, expected ${expectedRevision}`);
10922
+ this.accountId = accountId;
10923
+ this.expectedRevision = expectedRevision;
10924
+ this.currentRevision = currentRevision;
10925
+ this.name = MANIFEST_REVISION_MISMATCH_ERROR;
10926
+ }
10927
+ };
10928
+ exports2.ManifestRevisionMismatchError = ManifestRevisionMismatchError;
10929
+ function isManifestRevisionMismatch(error) {
10930
+ return error instanceof Error && error.name === MANIFEST_REVISION_MISMATCH_ERROR;
10931
+ }
10932
+ }
10933
+ });
10934
+
10867
10935
  // ../../packages/common/build/utils/manifest-helpers.js
10868
10936
  var require_manifest_helpers = __commonJS({
10869
10937
  "../../packages/common/build/utils/manifest-helpers.js"(exports2) {
@@ -10882,6 +10950,7 @@ var require_manifest_helpers = __commonJS({
10882
10950
  var base_account_1 = require_base_account();
10883
10951
  var manifest_1 = require_manifest();
10884
10952
  var feature_flags_1 = require_feature_flags();
10953
+ var manifest_revision_1 = require_manifest_revision();
10885
10954
  var LEGACY_FLAG_RENAMES = {
10886
10955
  allowCycleTimeAnalysis: "enableCycleTimeAnalysis",
10887
10956
  allowProductionCorrection: "enableProductionCorrection",
@@ -11034,21 +11103,32 @@ var require_manifest_helpers = __commonJS({
11034
11103
  }
11035
11104
  return { ...manifest, account };
11036
11105
  }
11106
+ var UPDATE_MANIFEST_MAX_ATTEMPTS = 3;
11037
11107
  async function updateManifest(accountRepository, accountId, mutate) {
11038
- const account = await accountRepository.raw(accountId);
11039
- if (!account) {
11040
- throw new Error(`Account not found: ${accountId}`);
11041
- }
11042
- if (!account.manifestJson) {
11043
- const empty = { ...exports2.EMPTY_MANIFEST, account: { ...exports2.EMPTY_MANIFEST.account, id: accountId } };
11044
- account.manifestJson = JSON.stringify(empty);
11045
- await accountRepository.save([account]);
11046
- }
11047
- const manifest = manifest_1.ManifestSchema.parse(normalizeManifest(JSON.parse(account.manifestJson)));
11048
- mutate(manifest);
11049
- manifest_1.ManifestSchema.parse(manifest);
11050
- await accountRepository.save([{ ...account, manifestJson: JSON.stringify(manifest) }]);
11051
- return manifest;
11108
+ for (let attempt = 1; ; attempt++) {
11109
+ const account = await accountRepository.raw(accountId);
11110
+ if (!account) {
11111
+ throw new Error(`Account not found: ${accountId}`);
11112
+ }
11113
+ if (!account.manifestJson) {
11114
+ const empty = { ...exports2.EMPTY_MANIFEST, account: { ...exports2.EMPTY_MANIFEST.account, id: accountId } };
11115
+ account.manifestJson = JSON.stringify(empty);
11116
+ await accountRepository.save([account]);
11117
+ }
11118
+ const manifest = manifest_1.ManifestSchema.parse(normalizeManifest(JSON.parse(account.manifestJson)));
11119
+ mutate(manifest);
11120
+ manifest_1.ManifestSchema.parse(manifest);
11121
+ try {
11122
+ await accountRepository.save([{ ...account, manifestJson: JSON.stringify(manifest) }], {
11123
+ expectedRevision: (0, manifest_revision_1.manifestRevision)(account.manifestJson)
11124
+ });
11125
+ return manifest;
11126
+ } catch (e) {
11127
+ if (!(0, manifest_revision_1.isManifestRevisionMismatch)(e) || attempt >= UPDATE_MANIFEST_MAX_ATTEMPTS) {
11128
+ throw e;
11129
+ }
11130
+ }
11131
+ }
11052
11132
  }
11053
11133
  }
11054
11134
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "busroot-sdk",
3
- "version": "0.0.8-dev.2920350130",
3
+ "version": "0.0.8-dev.2922257515",
4
4
  "description": "An SDK for accessing Busroot from output.industries",
5
5
  "homepage": "https://www.output.industries",
6
6
  "main": "./build/index.js",