From 6d2fa913ac97743e423bb9870479fa5bf3dc498c Mon Sep 17 00:00:00 2001 From: kirillgroshkov Date: Sat, 21 Oct 2023 18:39:17 +0200 Subject: [PATCH] fix: separate localDateRange for better tree-shakeability --- scripts/dateParseBench.ts | 4 +- src/datetime/dateInterval.ts | 6 +- src/datetime/localDate.test.ts | 12 ++-- src/datetime/localDate.ts | 102 ++++++++++++++++----------------- 4 files changed, 63 insertions(+), 61 deletions(-) diff --git a/scripts/dateParseBench.ts b/scripts/dateParseBench.ts index 58cac43b..81f323b2 100644 --- a/scripts/dateParseBench.ts +++ b/scripts/dateParseBench.ts @@ -8,9 +8,9 @@ yarn tsn dateParseBench import { runBenchScript } from '@naturalcycles/bench-lib' import { dayjs } from '@naturalcycles/time-lib' -import { localDate, LocalDate } from '../src' +import { localDate, localDateRange } from '../src' -const strings = LocalDate.range('2022-01-03', '2023-01-05').map(String) +const strings = localDateRange('2022-01-03', '2023-01-05').map(String) const DATE = /^(\d\d\d\d)-(\d\d)-(\d\d)$/ // dayjs x 4,733 ops/sec ±0.31% (90 runs sampled) diff --git a/src/datetime/dateInterval.ts b/src/datetime/dateInterval.ts index 85066368..02456d1b 100644 --- a/src/datetime/dateInterval.ts +++ b/src/datetime/dateInterval.ts @@ -1,5 +1,5 @@ import type { Inclusiveness, LocalDateInput, LocalDateUnit } from './localDate' -import { LocalDate } from './localDate' +import { LocalDate, localDateRange } from './localDate' export type DateIntervalConfig = DateInterval | DateIntervalString export type DateIntervalString = string @@ -81,14 +81,14 @@ export class DateInterval { } getDays(incl: Inclusiveness = '[]'): LocalDate[] { - return LocalDate.range(this.start, this.end, incl, 1, 'day') + return localDateRange(this.start, this.end, incl, 1, 'day') } /** * Returns an array of LocalDates that are included in the interval. */ range(incl: Inclusiveness = '[]', step = 1, stepUnit: LocalDateUnit = 'day'): LocalDate[] { - return LocalDate.range(this.start, this.end, incl, step, stepUnit) + return localDateRange(this.start, this.end, incl, step, stepUnit) } toString(): DateIntervalString { diff --git a/src/datetime/localDate.test.ts b/src/datetime/localDate.test.ts index be276788..f2dfcdb8 100644 --- a/src/datetime/localDate.test.ts +++ b/src/datetime/localDate.test.ts @@ -7,6 +7,8 @@ import { LocalDate, localDateOrToday, localDateOrUndefined, + localDateRange, + localDateRangeIt, localDateToday, } from './localDate' @@ -212,14 +214,14 @@ test('toDate', () => { }) test('range', () => { - expect(LocalDate.range('2021-12-24', '2021-12-26')).toMatchInlineSnapshot(` + expect(localDateRange('2021-12-24', '2021-12-26')).toMatchInlineSnapshot(` [ "2021-12-24", "2021-12-25", ] `) - expect(LocalDate.range('2021-12-24', '2021-12-26', '[]')).toMatchInlineSnapshot(` + expect(localDateRange('2021-12-24', '2021-12-26', '[]')).toMatchInlineSnapshot(` [ "2021-12-24", "2021-12-25", @@ -227,7 +229,7 @@ test('range', () => { ] `) - expect(LocalDate.range('2021-12-24', '2021-12-30', '[)', 2)).toMatchInlineSnapshot(` + expect(localDateRange('2021-12-24', '2021-12-30', '[)', 2)).toMatchInlineSnapshot(` [ "2021-12-24", "2021-12-26", @@ -235,7 +237,7 @@ test('range', () => { ] `) - expect(LocalDate.range('2021-12-24', '2021-12-30', '[]', 2)).toMatchInlineSnapshot(` + expect(localDateRange('2021-12-24', '2021-12-30', '[]', 2)).toMatchInlineSnapshot(` [ "2021-12-24", "2021-12-26", @@ -246,7 +248,7 @@ test('range', () => { }) test('rangeIterable', () => { - expect([...LocalDate.rangeIt('2021-12-24', '2021-12-26')]).toMatchInlineSnapshot(` + expect([...localDateRangeIt('2021-12-24', '2021-12-26')]).toMatchInlineSnapshot(` [ "2021-12-24", "2021-12-25", diff --git a/src/datetime/localDate.ts b/src/datetime/localDate.ts index 645a0c49..913617a1 100644 --- a/src/datetime/localDate.ts +++ b/src/datetime/localDate.ts @@ -143,57 +143,6 @@ export class LocalDate { .reduce((max, item) => (max.isSameOrAfter(item) ? max : item)) } - static range( - min: LocalDateInput, - max: LocalDateInput, - incl: Inclusiveness = '[)', - step = 1, - stepUnit: LocalDateUnit = 'day', - ): LocalDate[] { - return this.rangeIt(min, max, incl, step, stepUnit).toArray() - } - - /** - * Experimental, returns the range as Iterable2. - */ - static rangeIt( - min: LocalDateInput, - max: LocalDateInput, - incl: Inclusiveness = '[)', - step = 1, - stepUnit: LocalDateUnit = 'day', - ): Iterable2 { - if (stepUnit === 'week') { - step *= 7 - stepUnit = 'day' - } - - const $min = LocalDate.of(min).startOf(stepUnit) - const $max = LocalDate.of(max).startOf(stepUnit) - - let value = $min - // eslint-disable-next-line @typescript-eslint/prefer-string-starts-ends-with - if (value.isAfter($min, incl[0] === '[')) { - // ok - } else { - value.plus(1, stepUnit, true) - } - - const rightInclusive = incl[1] === ']' - - return Iterable2.of({ - *[Symbol.iterator]() { - while (value.isBefore($max, rightInclusive)) { - yield value - - // We don't mutate, because we already returned `current` - // in the previous iteration - value = value.plus(step, stepUnit) - } - }, - }) - } - get(unit: LocalDateUnitStrict): number { return unit === 'year' ? this.$year : unit === 'month' ? this.$month : this.$day } @@ -583,6 +532,57 @@ export class LocalDate { } } +export function localDateRange( + min: LocalDateInput, + max: LocalDateInput, + incl: Inclusiveness = '[)', + step = 1, + stepUnit: LocalDateUnit = 'day', +): LocalDate[] { + return localDateRangeIt(min, max, incl, step, stepUnit).toArray() +} + +/** + * Experimental, returns the range as Iterable2. + */ +export function localDateRangeIt( + min: LocalDateInput, + max: LocalDateInput, + incl: Inclusiveness = '[)', + step = 1, + stepUnit: LocalDateUnit = 'day', +): Iterable2 { + if (stepUnit === 'week') { + step *= 7 + stepUnit = 'day' + } + + const $min = LocalDate.of(min).startOf(stepUnit) + const $max = LocalDate.of(max).startOf(stepUnit) + + let value = $min + // eslint-disable-next-line @typescript-eslint/prefer-string-starts-ends-with + if (value.isAfter($min, incl[0] === '[')) { + // ok + } else { + value.plus(1, stepUnit, true) + } + + const rightInclusive = incl[1] === ']' + + return Iterable2.of({ + *[Symbol.iterator]() { + while (value.isBefore($max, rightInclusive)) { + yield value + + // We don't mutate, because we already returned `current` + // in the previous iteration + value = value.plus(step, stepUnit) + } + }, + }) +} + /** * Convenience wrapper around `LocalDate.of` */