UNPKG

rrule-rust

Version:

RRule implementation for browsers and Node.js written in Rust

428 lines (427 loc) 15 kB
import { RRule, type RRuleLike } from './rrule'; import { type Time, DateTime, type DateTimeLike, type DateLike } from './datetime'; import { DtStart, type DtStartLike } from './dtstart'; import { ExDate, type ExDateLike } from './exdate'; import { RDate, type RDateLike } from './rdate'; /** * Interface for controlling caching behavior of RRuleSet operations. * * Caching is enabled by default and significantly improves performance when repeatedly * calling methods like `all()`, `between()`, or iterating over the same RRuleSet instance. * However, it may consume additional memory for large recurrence sets. * * @example * ```typescript * const rruleSet = new RRuleSet({ * dtstart: new DtStart(DateTime.local(2024, 1, 1, 9, 0, 0)), * rrules: [new RRule({ frequency: Frequency.Daily, count: 100 })] * }); * * // Disable caching if memory is a concern * rruleSet.cache.disable(); * * // Enable caching for better performance * rruleSet.cache.enable(); * * // Clear cached results * rruleSet.cache.clear(); * ``` */ export interface RRuleSetCache { /** * Indicates whether caching is currently disabled. * When `true`, all operations compute results fresh without storing them. */ disabled: boolean; /** * Clears all cached results. * Use this method when you want to free memory while keeping caching enabled. */ clear(): void; /** * Disables caching for all subsequent operations. * Existing cached results are preserved but not used. New operations will not cache results. */ disable(): void; /** * Enables caching for all subsequent operations. * Operations will store and reuse results to improve performance. */ enable(): void; } /** * Options for creating an RRuleSet instance. */ export interface RRuleSetOptions<DT extends DateTime<Time> | DateTime<undefined>, RRDT extends DT | undefined = DT | undefined, ERDT extends DT | undefined = DT | undefined> { /** The start date/time for the recurrence set */ readonly dtstart: DtStart<DT>; /** Array of recurrence rules to include */ readonly rrules?: readonly RRule<RRDT>[]; /** Array of recurrence rules to exclude */ readonly exrules?: readonly RRule<ERDT>[]; /** Array of exception dates to exclude */ readonly exdates?: readonly ExDate<DT>[]; /** Array of recurrence dates to include */ readonly rdates?: readonly RDate<DT>[]; } /** * Plain object representation of RRuleSet. */ export interface RRuleSetLike<DT extends DateTimeLike | DateLike> { /** The start date/time for the recurrence set */ readonly dtstart: DtStartLike<DT>; /** Array of recurrence rules to include */ readonly rrules: readonly RRuleLike<DT>[]; /** Array of recurrence rules to exclude */ readonly exrules: readonly RRuleLike<DT>[]; /** Array of exception dates to exclude */ readonly exdates: readonly ExDateLike<DT>[]; /** Array of recurrence dates to include */ readonly rdates: readonly RDateLike<DT>[]; } /** * Represents a set of recurrence rules (RRuleSet) according to RFC 5545. * * RRuleSet combines multiple recurrence components: * - DTSTART: The start date/time * - RRULE: Rules for generating occurrences * - EXRULE: Rules for excluding occurrences * - RDATE: Additional dates to include * - EXDATE: Specific dates to exclude * * @example * ```typescript * // Weekly meeting on Mondays, excluding holidays * const rruleSet = new RRuleSet({ * dtstart: new DtStart(DateTime.local(2024, 1, 15, 9, 0, 0)), * rrules: [ * new RRule({ * frequency: Frequency.Weekly, * byWeekday: [Weekday.Monday] * }) * ], * exdates: [ * new ExDate([ * DateTime.date(2024, 1, 1), // New Year * DateTime.date(2024, 12, 25) // Christmas * ]) * ] * }); * * // Get first 10 occurrences * const occurrences = rruleSet.all(10); * ``` */ export declare class RRuleSet<DT extends DateTime<Time> | DateTime<undefined>, RRDT extends DT | undefined = DT | undefined, ERDT extends DT | undefined = DT | undefined> implements Iterable<DateTime<Time> | DateTime<undefined>> { /** The start date/time for the recurrence set */ readonly dtstart: DtStart<DT>; /** Array of recurrence rules to include */ readonly rrules: readonly RRule<RRDT>[]; /** Array of recurrence rules to exclude */ readonly exrules: readonly RRule<ERDT>[]; /** Array of exception dates to exclude */ readonly exdates: readonly ExDate<DT>[]; /** Array of recurrence dates to include */ readonly rdates: readonly RDate<DT>[]; private _cache; constructor(dtstart: DtStart<DT>); constructor(options: RRuleSetOptions<DT, RRDT, ERDT>); /** * Provides access to cache control for this RRuleSet instance. * * By default, caching is enabled to optimize repeated calls to methods like `all()`, * `between()`, and iteration. Use this property to control caching behavior based on * your performance and memory requirements. * * @example * ```typescript * const rruleSet = new RRuleSet({ * dtstart: new DtStart(DateTime.local(2024, 1, 1, 9, 0, 0)), * rrules: [new RRule({ frequency: Frequency.Daily })] * }); * * // Check if caching is disabled * console.log(rruleSet.cache.disabled); // false * * // Disable caching for memory-constrained environments * rruleSet.cache.disable(); * * // Clear cached data to free memory * rruleSet.cache.clear(); * ``` */ get cache(): RRuleSetCache; /** * Parses an RFC 5545 formatted string into an RRuleSet. * * @param str - RFC 5545 formatted string containing DTSTART, RRULE, etc. * @returns A new RRuleSet instance * * @example * ```typescript * const str = `DTSTART:20240115T090000 * RRULE:FREQ=WEEKLY;BYDAY=MO * EXDATE:20240101,20241225`; * const rruleSet = RRuleSet.fromString(str); * ``` */ static fromString<DT extends DateTime<Time> | DateTime<undefined>>(str: string): RRuleSet<DT>; /** * Creates an RRuleSet from a plain object representation. * * @param plain - Plain object with recurrence set properties * @returns A new RRuleSet instance * * @example * ```typescript * const plain = { * dtstart: { value: { year: 2024, month: 1, day: 15, hour: 9, minute: 0, second: 0, utc: false } }, * rrules: [{ frequency: Frequency.Weekly, byWeekday: [Weekday.Monday], ... }], * exrules: [], * exdates: [], * rdates: [] * }; * const rruleSet = RRuleSet.fromPlain(plain); * ``` */ static fromPlain(plain: RRuleSetLike<DateTimeLike>): RRuleSet<DateTime<Time>>; static fromPlain(plain: RRuleSetLike<DateLike>): RRuleSet<DateTime<undefined>>; /** * Creates a new RRuleSet with a different start date/time. * * @param dtstart - The new start date/time * @returns A new RRuleSet instance * * @example * ```typescript * const rruleSet = new RRuleSet(new DtStart(DateTime.date(2024, 1, 15))); * const updated = rruleSet.setDtStart(new DtStart(DateTime.date(2024, 2, 1))); * ``` */ setDtStart(dtstart: DtStart<DT>): RRuleSet<DT>; /** * Creates a new RRuleSet with an additional recurrence rule. * * @param rrule - The recurrence rule to add * @returns A new RRuleSet instance * * @example * ```typescript * const rruleSet = new RRuleSet(new DtStart(DateTime.date(2024, 1, 15))); * const withRule = rruleSet.addRRule(new RRule(Frequency.Weekly)); * ``` */ addRRule<NRRDT extends DT | undefined>(rrule: RRule<NRRDT>): RRuleSet<DT, RRDT | NRRDT, ERDT>; /** * Creates a new RRuleSet with a different set of recurrence rules. * * @param rrules - The new array of recurrence rules * @returns A new RRuleSet instance */ setRRules<NRDT extends DT | undefined>(rrules: readonly RRule<NRDT>[]): RRuleSet<DT, NRDT>; /** * Creates a new RRuleSet with an additional exclusion rule. * * @param rrule - The exclusion rule to add * @returns A new RRuleSet instance * * @example * ```typescript * const rruleSet = new RRuleSet({ * dtstart: new DtStart(DateTime.date(2024, 1, 15)), * rrules: [new RRule(Frequency.Daily)] * }); * // Exclude weekends * const noWeekends = rruleSet.addExRule(new RRule({ * frequency: Frequency.Weekly, * byWeekday: [Weekday.Saturday, Weekday.Sunday] * })); * ``` */ addExRule<NERDT extends DT | undefined>(rrule: RRule<NERDT>): RRuleSet<DT, RRDT, ERDT | NERDT>; /** * Creates a new RRuleSet with a different set of exclusion rules. * * @param rrules - The new array of exclusion rules * @returns A new RRuleSet instance */ setExRules<ERDT extends DT | undefined>(rrules: readonly RRule<ERDT>[]): RRuleSet<DT, RRDT, ERDT>; /** * Creates a new RRuleSet with an additional exception date. * * @param exdate - The exception date(s) to add * @returns A new RRuleSet instance * * @example * ```typescript * const rruleSet = new RRuleSet({ * dtstart: new DtStart(DateTime.date(2024, 1, 15)), * rrules: [new RRule(Frequency.Daily)] * }); * // Exclude specific holidays * const withExceptions = rruleSet.addExDate(new ExDate([ * DateTime.date(2024, 1, 1), * DateTime.date(2024, 12, 25) * ])); * ``` */ addExDate(exdate: ExDate<DT>): RRuleSet<DT>; /** * Creates a new RRuleSet with a different set of exception dates. * * @param exdates - The new array of exception dates * @returns A new RRuleSet instance */ setExDates(exdates: readonly ExDate<DT>[]): RRuleSet<DT>; /** * Creates a new RRuleSet with an additional recurrence date. * * @param datetime - The recurrence date(s) to add * @returns A new RRuleSet instance * * @example * ```typescript * const rruleSet = new RRuleSet({ * dtstart: new DtStart(DateTime.date(2024, 1, 15)), * rrules: [new RRule(Frequency.Weekly)] * }); * // Add extra dates not covered by the rule * const withExtras = rruleSet.addRDate(new RDate([ * DateTime.date(2024, 2, 14), // Valentine's Day special * DateTime.date(2024, 3, 17) // St. Patrick's Day special * ])); * ``` */ addRDate(datetime: RDate<DT>): RRuleSet<DT>; /** * Creates a new RRuleSet with a different set of recurrence dates. * * @param datetimes - The new array of recurrence dates * @returns A new RRuleSet instance */ setRDates(datetimes: readonly RDate<DT>[]): RRuleSet<DT>; /** * Returns all the occurrences of the recurrence set. * * @param limit - Optional maximum number of occurrences to return * @returns Array of date/time occurrences * * @example * ```typescript * const rruleSet = new RRuleSet({ * dtstart: new DtStart(DateTime.date(2024, 1, 15)), * rrules: [new RRule({ frequency: Frequency.Daily, count: 5 })] * }); * * // Get all occurrences (limited by count in rule) * const all = rruleSet.all(); * * // Get first 10 occurrences * const first10 = rruleSet.all(10); * ``` */ all(limit?: number): readonly DT[]; /** * Returns all occurrences between two dates. * * @param after - The lower bound date (exclusive by default) * @param before - The upper bound date (exclusive by default) * @param inclusive - Whether to include the boundary dates in results * @returns Array of date/time occurrences in the range * * @example * ```typescript * const rruleSet = new RRuleSet({ * dtstart: new DtStart(DateTime.date(2024, 1, 1)), * rrules: [new RRule(Frequency.Daily)] * }); * * // Get occurrences in January 2024 (exclusive) * const january = rruleSet.between( * DateTime.date(2024, 1, 1), * DateTime.date(2024, 2, 1) * ); * * // Get occurrences in January 2024 (inclusive) * const januaryInclusive = rruleSet.between( * DateTime.date(2024, 1, 1), * DateTime.date(2024, 1, 31), * true * ); * ``` */ between(after: DT, before: DT, inclusive?: boolean): readonly DT[]; /** * Parses an RFC 5545 string and updates the RRuleSet. * * @param str - RFC 5545 formatted string * @returns A new RRuleSet instance parsed from the string * * @example * ```typescript * const rruleSet = new RRuleSet(new DtStart(DateTime.date(2024, 1, 15))); * const updated = rruleSet.setFromString(`DTSTART:20240201T090000 * RRULE:FREQ=WEEKLY;BYDAY=MO,WE,FR`); * ``` */ setFromString<NDT extends DateTime<Time> | DateTime<undefined> = DT>(str: string): RRuleSet<NDT>; /** * Converts the RRuleSet to an RFC 5545 formatted string. * * @returns RFC 5545 formatted string representation * * @example * ```typescript * const rruleSet = new RRuleSet({ * dtstart: new DtStart(DateTime.date(2024, 1, 15)), * rrules: [new RRule({ frequency: Frequency.Weekly, byWeekday: [Weekday.Monday] })] * }); * console.log(rruleSet.toString()); * // DTSTART:20240115 * // RRULE:FREQ=WEEKLY;BYDAY=MO * ``` */ toString(): string; /** * Converts the RRuleSet to a plain object representation. * * @returns A plain object with all RRuleSet properties * * @example * ```typescript * const rruleSet = new RRuleSet({ * dtstart: new DtStart(DateTime.date(2024, 1, 15)), * rrules: [new RRule(Frequency.Weekly)] * }); * const plain = rruleSet.toPlain(); * // Useful for serialization to JSON * const json = JSON.stringify(plain); * ``` */ toPlain(): RRuleSetLike<DT extends DateTime<Time> ? DateTimeLike : DateLike>; /** * Returns an iterator for the recurrence set. * * This allows using RRuleSet with for-of loops and other iteration constructs. * * @returns An iterator over the occurrences * * @example * ```typescript * const rruleSet = new RRuleSet({ * dtstart: new DtStart(DateTime.date(2024, 1, 15)), * rrules: [new RRule({ frequency: Frequency.Daily, count: 5 })] * }); * * // Iterate over occurrences * for (const occurrence of rruleSet) { * console.log(occurrence.toString()); * } * * // Use with spread operator * const allOccurrences = [...rruleSet]; * ``` */ [Symbol.iterator](): Iterator<DT, any, any>; private toOptions; }