@dereekb/date 10.0.12 → 10.0.13

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/index.cjs.js CHANGED
@@ -5126,20 +5126,59 @@ function expandUniqueDateCellsFunction(config) {
5126
5126
  function dateCellRangeOfTimingFactory(config) {
5127
5127
  const {
5128
5128
  timing,
5129
- fitToTimingRange = true
5129
+ fitToTimingRange = true,
5130
+ limitToCompletedIndexes: onlyIncludeIfComplete = false,
5131
+ now: inputNowGetter
5130
5132
  } = config;
5133
+ const nowGetter = util.asGetter(inputNowGetter !== null && inputNowGetter !== void 0 ? inputNowGetter : () => new Date());
5131
5134
  const indexFactory = dateCellTimingRelativeIndexFactory(timing);
5132
5135
  const minIndex = fitToTimingRange ? 0 : Number.MIN_SAFE_INTEGER;
5133
5136
  const maxIndex = fitToTimingRange ? indexFactory(indexFactory._timing.end) : Number.MAX_SAFE_INTEGER;
5137
+ let getCurrentMaxIndex;
5138
+ if (onlyIncludeIfComplete) {
5139
+ const timingInfoFactory = dateCellDayTimingInfoFactory({
5140
+ timing
5141
+ });
5142
+ const endAtFactory = dateCellTimingEndDateFactory(timing);
5143
+ let nextExpectedIndexChangeAt;
5144
+ let currentMaxDay;
5145
+ function refreshCurrentInfo() {
5146
+ const now = nowGetter();
5147
+ const currentInfo = timingInfoFactory(now, now);
5148
+ if (fitToTimingRange && currentInfo.isComplete) {
5149
+ // if the timing is complete relative to now, then update to prevent any further updates since the max will not change anymore
5150
+ currentMaxDay = indexFactory(indexFactory._timing.end);
5151
+ getCurrentMaxIndex = () => currentMaxDay;
5152
+ } else {
5153
+ const latestCompletedIndex = currentInfo.isInProgress ? currentInfo.currentIndex - 1 : currentInfo.currentIndex;
5154
+ // calculate the next max change. It occurs whenever the current index ends
5155
+ nextExpectedIndexChangeAt = endAtFactory(latestCompletedIndex + 1);
5156
+ currentMaxDay = fitToTimingRange ? Math.max(latestCompletedIndex, -1) : latestCompletedIndex; // the currentIndex day is not yet complete.
5157
+ }
5158
+ }
5159
+
5160
+ refreshCurrentInfo();
5161
+ getCurrentMaxIndex = () => {
5162
+ const now = nowGetter();
5163
+ if (!dateFns.isBefore(now, nextExpectedIndexChangeAt)) {
5164
+ // refresh since we're expecting the index change
5165
+ refreshCurrentInfo();
5166
+ }
5167
+ return currentMaxDay;
5168
+ };
5169
+ } else {
5170
+ getCurrentMaxIndex = () => maxIndex;
5171
+ }
5134
5172
  return input => {
5135
5173
  const {
5136
5174
  i: start,
5137
5175
  to: end
5138
5176
  } = input;
5139
5177
  const startIndex = indexFactory(start !== null && start !== void 0 ? start : 0);
5140
- const endIndex = indexFactory(end !== null && end !== void 0 ? end : new Date());
5141
- const i = Math.max(minIndex, startIndex);
5142
- const to = Math.min(maxIndex, endIndex);
5178
+ const endIndex = indexFactory(end !== null && end !== void 0 ? end : nowGetter());
5179
+ const maxIndex = getCurrentMaxIndex();
5180
+ const to = Math.min(maxIndex, endIndex); // calculate to first to get the max value
5181
+ const i = Math.min(Math.max(minIndex, startIndex), to); // i should never be greater than to
5143
5182
  return {
5144
5183
  i,
5145
5184
  to
@@ -5319,12 +5358,12 @@ function dateCellDayTimingInfoFactory(config) {
5319
5358
  indexRange,
5320
5359
  inclusiveMaxIndex: false
5321
5360
  });
5322
- const dayIndexFactory = dateCellTimingRelativeIndexFactory(timing);
5361
+ const indexFactory = dateCellTimingRelativeIndexFactory(timing);
5323
5362
  const dayFactory = dateCellTimingDateFactory(timing);
5324
- const startsAtFactory = dateCellTimingStartsAtDateFactory(dayIndexFactory);
5325
- return (input, inputNow) => {
5363
+ const startsAtFactory = dateCellTimingStartsAtDateFactory(indexFactory);
5364
+ const fn = (input, inputNow) => {
5326
5365
  const date = typeof input === 'number' ? dayFactory(input) : input;
5327
- const dayIndex = dayIndexFactory(input);
5366
+ const dayIndex = indexFactory(input);
5328
5367
  const isInRange = checkIsInRange(dayIndex);
5329
5368
  const now = inputNow !== null && inputNow !== void 0 ? inputNow : date;
5330
5369
  const startsAtOnDay = startsAtFactory(dayIndex); // convert back to the proper date
@@ -5348,9 +5387,13 @@ function dateCellDayTimingInfoFactory(config) {
5348
5387
  startsAtOnDay,
5349
5388
  endsAtOnDay,
5350
5389
  nextIndexInRange,
5351
- isComplete
5390
+ isComplete,
5391
+ _indexRange: indexRange
5352
5392
  };
5353
5393
  };
5394
+ fn._indexFactory = indexFactory;
5395
+ fn._startsAtFactory = startsAtFactory;
5396
+ return fn;
5354
5397
  }
5355
5398
  /**
5356
5399
  * Returns true if the input is a DateCellTimingRelativeIndexFactory.
package/index.esm.js CHANGED
@@ -1,4 +1,4 @@
1
- import { MS_IN_HOUR, MS_IN_MINUTE, MINUTES_IN_DAY, isISO8601DateString, filterMaybeValues, asArray, dayOfWeek, sortNumbersAscendingFunction, SORT_VALUE_LESS_THAN, SORT_VALUE_GREATER_THAN, SORT_VALUE_EQUAL, copyArray, compareFnOrder, groupValues, daysOfWeekArray, MS_IN_DAY, minutesToFractionalHours, UTC_TIMEZONE_STRING, isSameNonNullValue, isConsideredUtcTimezoneString, parseISO8601DayStringToUTCDate, cachedGetter, replaceStringsFunction, sortAscendingIndexNumberRefFunction, range, addToSet, sumOfIntegersBetween, makeValuesGroupMap, lastValue, pushArrayItemsIntoArray, indexRangeCheckFunction, mergeFilterFunctions, isDate as isDate$2, HOURS_IN_DAY, getNextDay, enabledDaysFromDaysOfWeek, daysOfWeekFromEnabledDays, firstValueFromIterable, forEachInIterable, iterablesAreSetEquivalent, invertFilter, mapIdentityFunction, repeatString, HashSet, DATE_NOW_VALUE, roundNumberUpToStep, protectedFactory, MS_IN_SECOND, TimeAM, isLogicalDateStringCode as isLogicalDateStringCode$1, dateFromLogicalDate as dateFromLogicalDate$1, flattenArray, splitJoinRemainder } from '@dereekb/util';
1
+ import { MS_IN_HOUR, MS_IN_MINUTE, MINUTES_IN_DAY, isISO8601DateString, filterMaybeValues, asArray, dayOfWeek, sortNumbersAscendingFunction, SORT_VALUE_LESS_THAN, SORT_VALUE_GREATER_THAN, SORT_VALUE_EQUAL, copyArray, compareFnOrder, groupValues, daysOfWeekArray, MS_IN_DAY, minutesToFractionalHours, UTC_TIMEZONE_STRING, isSameNonNullValue, isConsideredUtcTimezoneString, parseISO8601DayStringToUTCDate, cachedGetter, replaceStringsFunction, sortAscendingIndexNumberRefFunction, range, addToSet, sumOfIntegersBetween, makeValuesGroupMap, lastValue, pushArrayItemsIntoArray, asGetter, indexRangeCheckFunction, mergeFilterFunctions, isDate as isDate$2, HOURS_IN_DAY, getNextDay, enabledDaysFromDaysOfWeek, daysOfWeekFromEnabledDays, firstValueFromIterable, forEachInIterable, iterablesAreSetEquivalent, invertFilter, mapIdentityFunction, repeatString, HashSet, DATE_NOW_VALUE, roundNumberUpToStep, protectedFactory, MS_IN_SECOND, TimeAM, isLogicalDateStringCode as isLogicalDateStringCode$1, dateFromLogicalDate as dateFromLogicalDate$1, flattenArray, splitJoinRemainder } from '@dereekb/util';
2
2
  import { isDate as isDate$1, startOfMinute, isValid, parseISO, min as min$5, max as max$2, isAfter as isAfter$1, isEqual, isSameDay, isPast, addDays, set as set$1, differenceInDays, startOfMonth, endOfWeek, startOfWeek, endOfMonth, addHours, addMinutes, isBefore, addMilliseconds, startOfDay, addMonths, addWeeks, endOfDay, endOfHour, startOfHour, endOfMinute, minutesToHours, getMinutes, getSeconds, getMilliseconds, differenceInMilliseconds, differenceInHours, getWeek, getYear, setWeek, getDay, formatDistanceStrict, formatDistance, format, differenceInMinutes, formatDistanceToNow, parse, addSeconds } from 'date-fns';
3
3
  import { Expose, Type, Exclude } from 'class-transformer';
4
4
  import { IsDate, IsEnum, IsOptional, IsNumber, Min, registerDecorator, IsString, Matches, IsArray, IsBoolean } from 'class-validator';
@@ -5636,20 +5636,61 @@ function expandUniqueDateCellsFunction(config) {
5636
5636
  function dateCellRangeOfTimingFactory(config) {
5637
5637
  const {
5638
5638
  timing,
5639
- fitToTimingRange = true
5639
+ fitToTimingRange = true,
5640
+ limitToCompletedIndexes: onlyIncludeIfComplete = false,
5641
+ now: inputNowGetter
5640
5642
  } = config;
5643
+ const nowGetter = asGetter(inputNowGetter != null ? inputNowGetter : () => new Date());
5641
5644
  const indexFactory = dateCellTimingRelativeIndexFactory(timing);
5642
5645
  const minIndex = fitToTimingRange ? 0 : Number.MIN_SAFE_INTEGER;
5643
5646
  const maxIndex = fitToTimingRange ? indexFactory(indexFactory._timing.end) : Number.MAX_SAFE_INTEGER;
5647
+ let getCurrentMaxIndex;
5648
+ if (onlyIncludeIfComplete) {
5649
+ const timingInfoFactory = dateCellDayTimingInfoFactory({
5650
+ timing
5651
+ });
5652
+ const endAtFactory = dateCellTimingEndDateFactory(timing);
5653
+ let nextExpectedIndexChangeAt;
5654
+ let currentMaxDay;
5655
+ function refreshCurrentInfo() {
5656
+ const now = nowGetter();
5657
+ const currentInfo = timingInfoFactory(now, now);
5658
+ if (fitToTimingRange && currentInfo.isComplete) {
5659
+ // if the timing is complete relative to now, then update to prevent any further updates since the max will not change anymore
5660
+ currentMaxDay = indexFactory(indexFactory._timing.end);
5661
+ getCurrentMaxIndex = () => currentMaxDay;
5662
+ } else {
5663
+ const latestCompletedIndex = currentInfo.isInProgress ? currentInfo.currentIndex - 1 : currentInfo.currentIndex;
5664
+
5665
+ // calculate the next max change. It occurs whenever the current index ends
5666
+ nextExpectedIndexChangeAt = endAtFactory(latestCompletedIndex + 1);
5667
+ currentMaxDay = fitToTimingRange ? Math.max(latestCompletedIndex, -1) : latestCompletedIndex; // the currentIndex day is not yet complete.
5668
+ }
5669
+ }
5670
+
5671
+ refreshCurrentInfo();
5672
+ getCurrentMaxIndex = () => {
5673
+ const now = nowGetter();
5674
+ if (!isBefore(now, nextExpectedIndexChangeAt)) {
5675
+ // refresh since we're expecting the index change
5676
+ refreshCurrentInfo();
5677
+ }
5678
+ return currentMaxDay;
5679
+ };
5680
+ } else {
5681
+ getCurrentMaxIndex = () => maxIndex;
5682
+ }
5644
5683
  return input => {
5645
5684
  const {
5646
5685
  i: start,
5647
5686
  to: end
5648
5687
  } = input;
5649
5688
  const startIndex = indexFactory(start != null ? start : 0);
5650
- const endIndex = indexFactory(end != null ? end : new Date());
5651
- const i = Math.max(minIndex, startIndex);
5652
- const to = Math.min(maxIndex, endIndex);
5689
+ const endIndex = indexFactory(end != null ? end : nowGetter());
5690
+ const maxIndex = getCurrentMaxIndex();
5691
+ const to = Math.min(maxIndex, endIndex); // calculate to first to get the max value
5692
+ const i = Math.min(Math.max(minIndex, startIndex), to); // i should never be greater than to
5693
+
5653
5694
  return {
5654
5695
  i,
5655
5696
  to
@@ -5858,12 +5899,12 @@ function dateCellDayTimingInfoFactory(config) {
5858
5899
  indexRange,
5859
5900
  inclusiveMaxIndex: false
5860
5901
  });
5861
- const dayIndexFactory = dateCellTimingRelativeIndexFactory(timing);
5902
+ const indexFactory = dateCellTimingRelativeIndexFactory(timing);
5862
5903
  const dayFactory = dateCellTimingDateFactory(timing);
5863
- const startsAtFactory = dateCellTimingStartsAtDateFactory(dayIndexFactory);
5864
- return (input, inputNow) => {
5904
+ const startsAtFactory = dateCellTimingStartsAtDateFactory(indexFactory);
5905
+ const fn = (input, inputNow) => {
5865
5906
  const date = typeof input === 'number' ? dayFactory(input) : input;
5866
- const dayIndex = dayIndexFactory(input);
5907
+ const dayIndex = indexFactory(input);
5867
5908
  const isInRange = checkIsInRange(dayIndex);
5868
5909
  const now = inputNow != null ? inputNow : date;
5869
5910
  const startsAtOnDay = startsAtFactory(dayIndex); // convert back to the proper date
@@ -5888,9 +5929,13 @@ function dateCellDayTimingInfoFactory(config) {
5888
5929
  startsAtOnDay,
5889
5930
  endsAtOnDay,
5890
5931
  nextIndexInRange,
5891
- isComplete
5932
+ isComplete,
5933
+ _indexRange: indexRange
5892
5934
  };
5893
5935
  };
5936
+ fn._indexFactory = indexFactory;
5937
+ fn._startsAtFactory = startsAtFactory;
5938
+ return fn;
5894
5939
  }
5895
5940
 
5896
5941
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dereekb/date",
3
- "version": "10.0.12",
3
+ "version": "10.0.13",
4
4
  "exports": {
5
5
  ".": {
6
6
  "types": "./src/index.d.ts",
@@ -1,4 +1,4 @@
1
- import { type Maybe, type ArrayOrValue, type FilterFunction, type IndexRange, type ISO8601DayString, type IndexNumber } from '@dereekb/util';
1
+ import { type Maybe, type ArrayOrValue, type FilterFunction, type IndexRange, type ISO8601DayString, type IndexNumber, type GetterOrValue } from '@dereekb/util';
2
2
  import { type DateCell, type DateCellIndex, type DateOrDateCellIndex, type DateCellTiming, type DateCellArrayRef, type DateCellArray, type DateCellTimingRangeInput, type DateCellCollection, type DateCellDurationSpan, type DateCellTimingStartsAt, type DateCellTimingEvent, type DateCellTimingStartsAtEndRange, type FullDateCellTiming } from './date.cell';
3
3
  import { type DateCellRange, type DateCellRangeWithRange, type DateOrDateRangeOrDateCellIndexOrDateCellRange } from './date.cell.index';
4
4
  import { type DateRange, type DateRangeStart } from './date.range';
@@ -17,6 +17,18 @@ export interface DateCallIndexRangeFromDatesFactoryConfig {
17
17
  * Defaults to true.
18
18
  */
19
19
  readonly fitToTimingRange?: boolean;
20
+ /**
21
+ * Only include the index if the timing is marked as complete for that index.
22
+ *
23
+ * If no indexes have been completed, the returned value range will be -1 to -1.
24
+ *
25
+ * Defaults to false.
26
+ */
27
+ readonly limitToCompletedIndexes?: boolean;
28
+ /**
29
+ * (Optional) now date/getter used to influence the limitToCompletedIndexes calculations.
30
+ */
31
+ readonly now?: GetterOrValue<Date>;
20
32
  }
21
33
  /**
22
34
  * DateCellRangeOfTimingFactory input
@@ -25,11 +37,11 @@ export interface DateCellRangeOfTimingInput {
25
37
  /**
26
38
  * Start date or index
27
39
  */
28
- readonly i?: DateOrDateCellIndex;
40
+ readonly i?: Maybe<DateOrDateCellIndex>;
29
41
  /**
30
42
  * End date or index
31
43
  */
32
- readonly to?: DateOrDateCellIndex;
44
+ readonly to?: Maybe<DateOrDateCellIndex>;
33
45
  }
34
46
  /**
35
47
  * Creates a DateCellRange from the input.
@@ -192,7 +204,10 @@ export interface DateCellDayTimingInfo {
192
204
  *
193
205
  * Can optionally specify a now that is used for checking the inProgress functionality.
194
206
  */
195
- export type DateCellDayTimingInfoFactory = (date: DateOrDateCellIndex, now?: Date) => DateCellDayTimingInfo;
207
+ export type DateCellDayTimingInfoFactory = ((date: DateOrDateCellIndex, now?: Date) => DateCellDayTimingInfo) & {
208
+ readonly _indexFactory: DateCellTimingRelativeIndexFactory;
209
+ readonly _startsAtFactory: DateCellTimingStartsAtDateFactory;
210
+ };
196
211
  export declare function dateCellDayTimingInfoFactory(config: DateCellDayTimingInfoFactoryConfig): DateCellDayTimingInfoFactory;
197
212
  /**
198
213
  * DateCellTimingRelativeIndexFactory input. Can be a Date, DateCellIndex, or ISO8601DayString