@forcecalendar/core 2.4.0 → 2.5.1
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/core/calendar/Calendar.js +191 -23
- package/core/events/Event.js +106 -14
- package/core/events/EventStore.js +482 -63
- package/core/events/RRuleParser.js +19 -3
- package/core/events/RecurrenceEngine.js +427 -31
- package/core/events/RecurrenceEngineV2.js +497 -88
- package/core/index.js +1 -1
- package/core/integration/EnhancedCalendar.js +126 -14
- package/core/timezone/TimezoneManager.js +45 -9
- package/core/types.js +61 -0
- package/package.json +1 -1
- package/types/calendar/Calendar.d.ts +123 -9
- package/types/events/Event.d.ts +50 -0
- package/types/events/EventStore.d.ts +235 -13
- package/types/events/RRuleParser.d.ts +10 -1
- package/types/events/RecurrenceEngine.d.ts +159 -1
- package/types/events/RecurrenceEngineV2.d.ts +178 -15
- package/types/index.d.ts +1 -1
- package/types/integration/EnhancedCalendar.d.ts +73 -1
- package/types/types.d.ts +201 -0
|
@@ -15,10 +15,15 @@ export declare class RecurrenceEngineV2 {
|
|
|
15
15
|
/**
|
|
16
16
|
* Expand recurring event with advanced handling
|
|
17
17
|
*
|
|
18
|
-
* Occurrences before rangeStart are skipped without being generated
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
* the same cost as one that
|
|
18
|
+
* Occurrences before rangeStart are skipped without being generated for
|
|
19
|
+
* the rules seekToRange can seek: DAILY (without BYHOUR), WEEKLY (with or
|
|
20
|
+
* without BYDAY), HOURLY and MINUTELY. Such a series that started years
|
|
21
|
+
* before the queried window is expanded at the same cost as one that
|
|
22
|
+
* started yesterday. MONTHLY and YEARLY rules, and DAILY with BYHOUR,
|
|
23
|
+
* are stepped from DTSTART; they take few enough steps per year that
|
|
24
|
+
* this is cheap, but an expansion that would need more than
|
|
25
|
+
* MAX_ITERATIONS_HARD_LIMIT steps is truncated (with one console.warn
|
|
26
|
+
* per process).
|
|
22
27
|
*
|
|
23
28
|
* @param {import('./Event.js').Event} event - Recurring event
|
|
24
29
|
* @param {Date} rangeStart - Start of expansion range
|
|
@@ -30,7 +35,7 @@ export declare class RecurrenceEngineV2 {
|
|
|
30
35
|
* @param {boolean} [options.includeCancelled=false] - Return exception dates as cancelled occurrences
|
|
31
36
|
* @param {string} [options.timezone] - Timezone for expansion (defaults to the event's)
|
|
32
37
|
* @param {boolean} [options.handleDST=true] - Adjust occurrences across DST transitions
|
|
33
|
-
* @returns {
|
|
38
|
+
* @returns {import('../types.js').ExpandedOccurrence[]} Expanded occurrences
|
|
34
39
|
*/
|
|
35
40
|
expandEvent(event: import('./Event.js').Event, rangeStart: Date, rangeEnd: Date, options?: {
|
|
36
41
|
maxOccurrences?: number;
|
|
@@ -38,14 +43,107 @@ export declare class RecurrenceEngineV2 {
|
|
|
38
43
|
includeCancelled?: boolean;
|
|
39
44
|
timezone?: string;
|
|
40
45
|
handleDST?: boolean;
|
|
41
|
-
}):
|
|
46
|
+
}): import('../types.js').ExpandedOccurrence[];
|
|
47
|
+
/**
|
|
48
|
+
* Lazily iterate the occurrences of an event in chronological order.
|
|
49
|
+
*
|
|
50
|
+
* Yields what expandEvent returns for the window, one occurrence at a
|
|
51
|
+
* time and without the expansion cache: stored instance modifications
|
|
52
|
+
* and exceptions are applied as each occurrence is produced, so changes
|
|
53
|
+
* made through addModifiedInstance or addException are visible on the
|
|
54
|
+
* next pull. Rules seekToRange can seek (daily, weekly, hourly,
|
|
55
|
+
* minutely) jump straight to `after`, and DST transitions are scanned
|
|
56
|
+
* lazily ahead of the cursor instead of for the whole window up front.
|
|
57
|
+
*
|
|
58
|
+
* Both bounds are exclusive unless `inclusive` is set: an occurrence that
|
|
59
|
+
* starts exactly at `after` or `before` is skipped by default, so
|
|
60
|
+
* iterating from a known occurrence's start continues the series without
|
|
61
|
+
* repeating it; with `inclusive: true` the window is closed on both ends
|
|
62
|
+
* like expandEvent's range. A non-recurring event yields its single
|
|
63
|
+
* occurrence when it falls inside the window. Iteration ends at COUNT or
|
|
64
|
+
* UNTIL, at `before`, or — as a guard for rules that produce no
|
|
65
|
+
* occurrences — after MAX_ITERATIONS_HARD_LIMIT consecutive steps
|
|
66
|
+
* without one. The generator is single-use; call again for a fresh one.
|
|
67
|
+
*
|
|
68
|
+
* @example
|
|
69
|
+
* const engine = new RecurrenceEngineV2();
|
|
70
|
+
* for (const occurrence of engine.iterateOccurrences(event, { after: new Date() })) {
|
|
71
|
+
* if (occurrence.start > deadline) break;
|
|
72
|
+
* schedule(occurrence);
|
|
73
|
+
* }
|
|
74
|
+
*
|
|
75
|
+
* @param {import('./Event.js').Event} event - The event to iterate
|
|
76
|
+
* @param {import('../types.js').ExpandedOccurrenceIteratorOptions} [options={}] - Window and expansion options
|
|
77
|
+
* @returns {Generator<import('../types.js').ExpandedOccurrence, void, undefined>} Occurrences in chronological order
|
|
78
|
+
* @throws {TypeError} If `after` or `before` is not a valid Date or timestamp
|
|
79
|
+
*/
|
|
80
|
+
iterateOccurrences(event: import('./Event.js').Event, options?: import('../types.js').ExpandedOccurrenceIteratorOptions): Generator<import('../types.js').ExpandedOccurrence, void, undefined>;
|
|
81
|
+
/**
|
|
82
|
+
* First occurrence of an event after an instant, or null when the series
|
|
83
|
+
* has no occurrence after it. `after` is exclusive unless
|
|
84
|
+
* `options.inclusive` is set, so passing the start of a known occurrence
|
|
85
|
+
* returns the one that follows it.
|
|
86
|
+
*
|
|
87
|
+
* @example
|
|
88
|
+
* const upcoming = engine.nextOccurrence(event, new Date());
|
|
89
|
+
*
|
|
90
|
+
* @param {import('./Event.js').Event} event - The event to query
|
|
91
|
+
* @param {Date|number} [after=null] - Instant to search from (defaults to the series start)
|
|
92
|
+
* @param {import('../types.js').ExpandedOccurrenceIteratorOptions} [options={}] - Further options
|
|
93
|
+
* @returns {import('../types.js').ExpandedOccurrence|null} The next occurrence, or null
|
|
94
|
+
*/
|
|
95
|
+
nextOccurrence(event: import('./Event.js').Event, after?: Date | number, options?: import('../types.js').ExpandedOccurrenceIteratorOptions): import('../types.js').ExpandedOccurrence | null;
|
|
96
|
+
/**
|
|
97
|
+
* The first `count` occurrences of an event inside a window, generated
|
|
98
|
+
* lazily so an open-ended series costs only the occurrences taken.
|
|
99
|
+
* `count` is capped at MAX_OCCURRENCES_HARD_LIMIT; fewer are returned
|
|
100
|
+
* when the series or the window ends first.
|
|
101
|
+
*
|
|
102
|
+
* @example
|
|
103
|
+
* const nextFive = engine.takeOccurrences(event, 5, { after: new Date() });
|
|
104
|
+
*
|
|
105
|
+
* @param {import('./Event.js').Event} event - The event to query
|
|
106
|
+
* @param {number} count - Maximum number of occurrences to return (fractions are floored)
|
|
107
|
+
* @param {import('../types.js').ExpandedOccurrenceIteratorOptions} [options={}] - Window and expansion options
|
|
108
|
+
* @returns {import('../types.js').ExpandedOccurrence[]} Up to `count` occurrences in chronological order
|
|
109
|
+
*/
|
|
110
|
+
takeOccurrences(event: import('./Event.js').Event, count: number, options?: import('../types.js').ExpandedOccurrenceIteratorOptions): import('../types.js').ExpandedOccurrence[];
|
|
111
|
+
/**
|
|
112
|
+
* Yield a non-recurring event's single occurrence if it starts inside
|
|
113
|
+
* the window
|
|
114
|
+
* @param {import('./Event.js').Event} event - The event
|
|
115
|
+
* @param {{ startMs: number, endMs: number }} window - Inclusive bounds
|
|
116
|
+
* @returns {Generator<import('../types.js').ExpandedOccurrence, void, undefined>}
|
|
117
|
+
* @private
|
|
118
|
+
*/
|
|
119
|
+
private _iterateSingle;
|
|
120
|
+
/**
|
|
121
|
+
* Lazy counterpart of the expandEvent loop: seeks to the window, then
|
|
122
|
+
* steps the cursor and yields each in-window occurrence with the same
|
|
123
|
+
* DST adjustment, exception handling and instance modifications.
|
|
124
|
+
* @private
|
|
125
|
+
*/
|
|
126
|
+
private _iterateRule;
|
|
127
|
+
/**
|
|
128
|
+
* Apply exceptions and stored instance modifications to a generated
|
|
129
|
+
* occurrence
|
|
130
|
+
* @param {import('./Event.js').Event} event - The recurring event
|
|
131
|
+
* @param {Object} occurrence - Occurrence from generateOccurrence
|
|
132
|
+
* @param {Object} rule - Parsed recurrence rule
|
|
133
|
+
* @param {boolean} includeCancelled - Return exception dates as cancelled occurrences
|
|
134
|
+
* @param {boolean} includeModified - Apply stored instance modifications
|
|
135
|
+
* @returns {Object|null} The occurrence, or null when it is excluded
|
|
136
|
+
* @private
|
|
137
|
+
*/
|
|
138
|
+
private _applyOverrides;
|
|
42
139
|
/**
|
|
43
140
|
* Move the expansion cursor to the last occurrence before the range
|
|
44
141
|
* without stepping through every occurrence in between.
|
|
45
142
|
*
|
|
46
143
|
* Applies to rules whose step is a fixed duration between system-timezone
|
|
47
|
-
* transitions (plain DAILY and WEEKLY, HOURLY, MINUTELY)
|
|
48
|
-
*
|
|
144
|
+
* transitions (plain DAILY and WEEKLY, HOURLY, MINUTELY) and to WEEKLY
|
|
145
|
+
* rules with BYDAY, whose steps repeat in a weekly cycle; the steps that
|
|
146
|
+
* cross a transition are taken with getNextDate so the result is exactly
|
|
49
147
|
* what stepping from DTSTART would produce. Never seeks past UNTIL, and
|
|
50
148
|
* counts skipped steps against COUNT.
|
|
51
149
|
*
|
|
@@ -56,6 +154,40 @@ export declare class RecurrenceEngineV2 {
|
|
|
56
154
|
* @param {string} timezone - Expansion timezone
|
|
57
155
|
*/
|
|
58
156
|
seekToRange(state: Object, rule: Object, rangeStart: Date, rangeEnd: Date, timezone: string): void;
|
|
157
|
+
/**
|
|
158
|
+
* Seek for WEEKLY rules with BYDAY. getNextWeekly picks the next weekday
|
|
159
|
+
* from the BYDAY list (in list order), so the step from each weekday is
|
|
160
|
+
* fixed and the walk from DTSTART settles into a cycle of weekdays that
|
|
161
|
+
* repeats every whole number of weeks. The cursor is stepped one
|
|
162
|
+
* occurrence at a time until it is on that cycle (at most six steps),
|
|
163
|
+
* then whole cycles are skipped arithmetically between system-timezone
|
|
164
|
+
* transitions, exactly as seekToRange does for fixed steps.
|
|
165
|
+
* @param {Object} state - Expansion state (currentDate and count are updated)
|
|
166
|
+
* @param {Object} rule - Parsed recurrence rule
|
|
167
|
+
* @param {Date} rangeStart - Start of expansion range
|
|
168
|
+
* @param {Date} rangeEnd - End of expansion range
|
|
169
|
+
* @param {string} timezone - Expansion timezone
|
|
170
|
+
* @private
|
|
171
|
+
*/
|
|
172
|
+
private _seekWeekCycle;
|
|
173
|
+
/**
|
|
174
|
+
* Days getNextWeekly adds from each weekday (index 0-6) for a WEEKLY
|
|
175
|
+
* rule with BYDAY, or null when the rule cannot be seeked (an invalid
|
|
176
|
+
* interval or day code, which the expansion loop handles as before)
|
|
177
|
+
* @param {Object} rule - Parsed recurrence rule
|
|
178
|
+
* @returns {number[]|null} Delta table indexed by Date#getDay()
|
|
179
|
+
* @private
|
|
180
|
+
*/
|
|
181
|
+
private _weekdayDeltas;
|
|
182
|
+
/**
|
|
183
|
+
* Weekday numbers (Date#getDay) of a rule's BYDAY entries in ascending
|
|
184
|
+
* order, computed once per parsed rule. Invalid day codes map to
|
|
185
|
+
* undefined and sort last.
|
|
186
|
+
* @param {Object} rule - Parsed recurrence rule with byDay
|
|
187
|
+
* @returns {number[]} Sorted weekday numbers
|
|
188
|
+
* @private
|
|
189
|
+
*/
|
|
190
|
+
private _weekdayTargets;
|
|
59
191
|
/**
|
|
60
192
|
* Milliseconds per step for rules getNextDate advances by a fixed
|
|
61
193
|
* duration while the system UTC offset is constant
|
|
@@ -111,12 +243,18 @@ export declare class RecurrenceEngineV2 {
|
|
|
111
243
|
/**
|
|
112
244
|
* Find DST transitions in date range
|
|
113
245
|
*/
|
|
114
|
-
findDSTTransitions(start: any, end: any, timezone: any):
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
246
|
+
findDSTTransitions(start: any, end: any, timezone: any): any[];
|
|
247
|
+
/**
|
|
248
|
+
* Walk the scan cursor one day at a time up to untilMs, appending each
|
|
249
|
+
* offset change. The cursor and last offset persist in `scan`, so the
|
|
250
|
+
* walk can be resumed later on the same day grid.
|
|
251
|
+
* @param {{ cursor: Date, lastOffset: number }} scan - Resumable scan position (mutated)
|
|
252
|
+
* @param {Array} transitions - Transition list to append to
|
|
253
|
+
* @param {number} untilMs - Scan through this timestamp (inclusive)
|
|
254
|
+
* @param {string} timezone - Timezone to probe
|
|
255
|
+
* @private
|
|
256
|
+
*/
|
|
257
|
+
private _scanDSTTransitions;
|
|
120
258
|
/**
|
|
121
259
|
* Adjust occurrence for DST transitions
|
|
122
260
|
*/
|
|
@@ -150,8 +288,27 @@ export declare class RecurrenceEngineV2 {
|
|
|
150
288
|
getDateKey(date: any): string;
|
|
151
289
|
/**
|
|
152
290
|
* Create cache key
|
|
291
|
+
*
|
|
292
|
+
* When given the event itself the key also covers everything the
|
|
293
|
+
* expansion depends on (DTSTART, end, recurrence rule), so a series that
|
|
294
|
+
* is updated, replaced or re-added under the same id can never be served
|
|
295
|
+
* a stale expansion. Keys always start with `<eventId>_`, which is what
|
|
296
|
+
* {@link RecurrenceEngineV2#clearEventCache} matches on.
|
|
297
|
+
* @param {import('./Event.js').Event|string} event - Recurring event, or just its id
|
|
298
|
+
* @param {Date} start - Start of expansion range
|
|
299
|
+
* @param {Date} end - End of expansion range
|
|
300
|
+
* @param {Object} options - Expansion options
|
|
301
|
+
* @returns {string} Cache key
|
|
302
|
+
*/
|
|
303
|
+
getCacheKey(event: import('./Event.js').Event | string, start: Date, end: Date, options: Object): string;
|
|
304
|
+
/**
|
|
305
|
+
* Stable text form of a recurrence rule for cache keys. A rule that
|
|
306
|
+
* cannot be serialised gets a unique fingerprint, i.e. is never cached.
|
|
307
|
+
* @param {string|Object} rule - RRULE string or rule object
|
|
308
|
+
* @returns {string} Fingerprint
|
|
309
|
+
* @private
|
|
153
310
|
*/
|
|
154
|
-
|
|
311
|
+
private _ruleFingerprint;
|
|
155
312
|
/**
|
|
156
313
|
* Cache occurrences
|
|
157
314
|
*/
|
|
@@ -160,6 +317,12 @@ export declare class RecurrenceEngineV2 {
|
|
|
160
317
|
* Clone occurrence results before returning or caching.
|
|
161
318
|
*/
|
|
162
319
|
cloneOccurrences(occurrences: any): any;
|
|
320
|
+
/**
|
|
321
|
+
* Clone a single occurrence, copying its Date and array fields.
|
|
322
|
+
* @param {import('../types.js').ExpandedOccurrence} occurrence - Occurrence to clone
|
|
323
|
+
* @returns {import('../types.js').ExpandedOccurrence} Independent copy
|
|
324
|
+
*/
|
|
325
|
+
cloneOccurrence(occurrence: import('../types.js').ExpandedOccurrence): import('../types.js').ExpandedOccurrence;
|
|
163
326
|
/**
|
|
164
327
|
* Clear cache for specific event
|
|
165
328
|
*/
|
package/types/index.d.ts
CHANGED
|
@@ -18,5 +18,5 @@ export { RRuleParser } from './events/RRuleParser.js';
|
|
|
18
18
|
export { TimezoneManager } from './timezone/TimezoneManager.js';
|
|
19
19
|
export { ConflictDetector } from './conflicts/ConflictDetector.js';
|
|
20
20
|
export { EnhancedCalendar } from './integration/EnhancedCalendar.js';
|
|
21
|
-
export declare const VERSION = "2.
|
|
21
|
+
export declare const VERSION = "2.5.1";
|
|
22
22
|
export { Calendar as default } from './calendar/Calendar.js';
|
|
@@ -13,16 +13,51 @@ export declare class EnhancedCalendar extends Calendar {
|
|
|
13
13
|
expansionTime: never[];
|
|
14
14
|
renderTime: never[];
|
|
15
15
|
};
|
|
16
|
+
_unsubscribeCacheInvalidation: Function;
|
|
16
17
|
_clearReindexTimeout: (() => void) | null | undefined;
|
|
17
18
|
constructor(config: any);
|
|
19
|
+
/**
|
|
20
|
+
* Invalidate the enhanced engine's cached expansions for a store change
|
|
21
|
+
* @param {import('../types.js').EventStoreChange} change - Store change
|
|
22
|
+
* @private
|
|
23
|
+
*/
|
|
24
|
+
private _invalidateOccurrenceCache;
|
|
18
25
|
/**
|
|
19
26
|
* Enhanced search with worker support
|
|
20
27
|
*/
|
|
21
28
|
search(query: any, options?: {}): Promise<any>;
|
|
22
29
|
/**
|
|
23
30
|
* Get events with enhanced recurrence expansion
|
|
31
|
+
*
|
|
32
|
+
* Regular events overlapping the range are returned as stored. Every
|
|
33
|
+
* recurring series in the store is expanded with this calendar's
|
|
34
|
+
* RecurrenceEngineV2 (so instance modifications and cancellations apply),
|
|
35
|
+
* including series that started before the range. Occurrences are the
|
|
36
|
+
* engine's plain occurrence objects, with the id `<masterId>_<startMs>`
|
|
37
|
+
* (see `Event.occurrenceId`), `recurringEventId`, `isOccurrence: true` and
|
|
38
|
+
* `occurrenceStart`.
|
|
24
39
|
*/
|
|
25
|
-
getEventsInRange(startDate: any, endDate: any, options?: {}):
|
|
40
|
+
getEventsInRange(startDate: any, endDate: any, options?: {}): (import("../index.js").Event | {
|
|
41
|
+
id: string;
|
|
42
|
+
recurringEventId?: string;
|
|
43
|
+
title: string;
|
|
44
|
+
start: Date;
|
|
45
|
+
end: Date;
|
|
46
|
+
startUTC?: Date;
|
|
47
|
+
endUTC?: Date;
|
|
48
|
+
timezone: string;
|
|
49
|
+
originalStart?: Date;
|
|
50
|
+
allDay: boolean;
|
|
51
|
+
description?: string;
|
|
52
|
+
location?: string;
|
|
53
|
+
categories?: string[];
|
|
54
|
+
status?: import("../types.js").EventStatus;
|
|
55
|
+
cancellationReason?: string;
|
|
56
|
+
isRecurring: boolean;
|
|
57
|
+
isModified?: boolean;
|
|
58
|
+
isOccurrence: boolean;
|
|
59
|
+
occurrenceStart: Date;
|
|
60
|
+
})[];
|
|
26
61
|
/**
|
|
27
62
|
* Modify a single occurrence of a recurring event
|
|
28
63
|
*/
|
|
@@ -31,6 +66,43 @@ export declare class EnhancedCalendar extends Calendar {
|
|
|
31
66
|
* Cancel a single occurrence of a recurring event
|
|
32
67
|
*/
|
|
33
68
|
cancelOccurrence(eventId: any, occurrenceDate: any, reason?: string): void;
|
|
69
|
+
/**
|
|
70
|
+
* Lazily iterate the occurrences of an event through the enhanced
|
|
71
|
+
* engine, so occurrences changed with modifyOccurrence or cancelled with
|
|
72
|
+
* cancelOccurrence are reflected. Same semantics as
|
|
73
|
+
* Calendar#iterateOccurrences.
|
|
74
|
+
* @param {string} eventId - The event ID
|
|
75
|
+
* @param {import('../types.js').ExpandedOccurrenceIteratorOptions} [options={}] - Window and expansion options
|
|
76
|
+
* @returns {Generator<import('../types.js').ExpandedOccurrence, void, undefined>} Occurrences in chronological order
|
|
77
|
+
* @throws {Error} If no event with the ID exists
|
|
78
|
+
*/
|
|
79
|
+
iterateOccurrences(eventId: string, options?: import('../types.js').ExpandedOccurrenceIteratorOptions): Generator<import('../types.js').ExpandedOccurrence, void, undefined>;
|
|
80
|
+
/**
|
|
81
|
+
* First occurrence of an event after an instant through the enhanced
|
|
82
|
+
* engine, or null. Same semantics as Calendar#getNextOccurrence.
|
|
83
|
+
* @param {string} eventId - The event ID
|
|
84
|
+
* @param {Date|number} [after=null] - Instant to search from (defaults to the series start)
|
|
85
|
+
* @param {import('../types.js').ExpandedOccurrenceIteratorOptions} [options={}] - Further options
|
|
86
|
+
* @returns {import('../types.js').ExpandedOccurrence|null} The next occurrence, or null
|
|
87
|
+
* @throws {Error} If no event with the ID exists
|
|
88
|
+
*/
|
|
89
|
+
getNextOccurrence(eventId: string, after?: Date | number, options?: import('../types.js').ExpandedOccurrenceIteratorOptions): import('../types.js').ExpandedOccurrence | null;
|
|
90
|
+
/**
|
|
91
|
+
* The first `count` occurrences of an event through the enhanced
|
|
92
|
+
* engine. Same semantics as Calendar#takeOccurrences.
|
|
93
|
+
* @param {string} eventId - The event ID
|
|
94
|
+
* @param {number} count - Maximum number of occurrences to return
|
|
95
|
+
* @param {import('../types.js').ExpandedOccurrenceIteratorOptions} [options={}] - Window and expansion options
|
|
96
|
+
* @returns {import('../types.js').ExpandedOccurrence[]} Up to `count` occurrences in chronological order
|
|
97
|
+
* @throws {Error} If no event with the ID exists
|
|
98
|
+
*/
|
|
99
|
+
takeOccurrences(eventId: string, count: number, options?: import('../types.js').ExpandedOccurrenceIteratorOptions): import('../types.js').ExpandedOccurrence[];
|
|
100
|
+
/**
|
|
101
|
+
* Resolve an occurrence query to the stored event and its options, with
|
|
102
|
+
* the timezone defaulted as getEventsInRange does
|
|
103
|
+
* @private
|
|
104
|
+
*/
|
|
105
|
+
private _occurrenceQuery;
|
|
34
106
|
/**
|
|
35
107
|
* Bulk operations for recurring events
|
|
36
108
|
*/
|
package/types/types.d.ts
CHANGED
|
@@ -789,6 +789,24 @@ export type EventsSetPayload = {
|
|
|
789
789
|
*/
|
|
790
790
|
unchanged: import('./events/Event.js').Event[];
|
|
791
791
|
};
|
|
792
|
+
export type EventSelectPayload = {
|
|
793
|
+
/**
|
|
794
|
+
* - The stored event (the master for an occurrence id)
|
|
795
|
+
*/
|
|
796
|
+
event: import('./events/Event.js').Event;
|
|
797
|
+
/**
|
|
798
|
+
* - Id of the stored event, as kept in the state's selectedEventId
|
|
799
|
+
*/
|
|
800
|
+
eventId: string;
|
|
801
|
+
/**
|
|
802
|
+
* - The occurrence id that was selected, or null for a stored event's id
|
|
803
|
+
*/
|
|
804
|
+
occurrenceId: string | null;
|
|
805
|
+
/**
|
|
806
|
+
* - The selected occurrence as in view data, or null
|
|
807
|
+
*/
|
|
808
|
+
occurrence: import('./events/Event.js').Event | null;
|
|
809
|
+
};
|
|
792
810
|
export type QueryFilters = {
|
|
793
811
|
/**
|
|
794
812
|
* - Start date for range query
|
|
@@ -856,6 +874,132 @@ export type EventOccurrence = {
|
|
|
856
874
|
* - ID of the parent recurring event
|
|
857
875
|
*/
|
|
858
876
|
recurringEventId: string;
|
|
877
|
+
/**
|
|
878
|
+
* - Timezone the occurrence was expanded in
|
|
879
|
+
*/
|
|
880
|
+
timezone?: string;
|
|
881
|
+
/**
|
|
882
|
+
* - Start of the series (DTSTART)
|
|
883
|
+
*/
|
|
884
|
+
originalStart?: Date;
|
|
885
|
+
};
|
|
886
|
+
export type OccurrenceIteratorOptions = {
|
|
887
|
+
/**
|
|
888
|
+
* - Only occurrences starting after this instant (Date or timestamp)
|
|
889
|
+
*/
|
|
890
|
+
after?: Date | number;
|
|
891
|
+
/**
|
|
892
|
+
* - Only occurrences starting before this instant (Date or timestamp)
|
|
893
|
+
*/
|
|
894
|
+
before?: Date | number;
|
|
895
|
+
/**
|
|
896
|
+
* - Treat `after` and `before` as closed bounds
|
|
897
|
+
*/
|
|
898
|
+
inclusive?: boolean;
|
|
899
|
+
/**
|
|
900
|
+
* - Timezone for expansion (defaults to the event's)
|
|
901
|
+
*/
|
|
902
|
+
timezone?: string;
|
|
903
|
+
};
|
|
904
|
+
export type ExpandedOccurrenceIteratorOptions = {
|
|
905
|
+
/**
|
|
906
|
+
* - Only occurrences starting after this instant (Date or timestamp)
|
|
907
|
+
*/
|
|
908
|
+
after?: Date | number;
|
|
909
|
+
/**
|
|
910
|
+
* - Only occurrences starting before this instant (Date or timestamp)
|
|
911
|
+
*/
|
|
912
|
+
before?: Date | number;
|
|
913
|
+
/**
|
|
914
|
+
* - Treat `after` and `before` as closed bounds
|
|
915
|
+
*/
|
|
916
|
+
inclusive?: boolean;
|
|
917
|
+
/**
|
|
918
|
+
* - Timezone for expansion (defaults to the event's)
|
|
919
|
+
*/
|
|
920
|
+
timezone?: string;
|
|
921
|
+
/**
|
|
922
|
+
* - Apply stored instance modifications
|
|
923
|
+
*/
|
|
924
|
+
includeModified?: boolean;
|
|
925
|
+
/**
|
|
926
|
+
* - Yield exception dates as cancelled occurrences
|
|
927
|
+
*/
|
|
928
|
+
includeCancelled?: boolean;
|
|
929
|
+
/**
|
|
930
|
+
* - Adjust occurrences across DST transitions
|
|
931
|
+
*/
|
|
932
|
+
handleDST?: boolean;
|
|
933
|
+
};
|
|
934
|
+
export type ExpandedOccurrence = {
|
|
935
|
+
/**
|
|
936
|
+
* - Occurrence ID (`<eventId>_<startTimestamp>` for recurring events)
|
|
937
|
+
*/
|
|
938
|
+
id: string;
|
|
939
|
+
/**
|
|
940
|
+
* - ID of the parent recurring event
|
|
941
|
+
*/
|
|
942
|
+
recurringEventId?: string;
|
|
943
|
+
/**
|
|
944
|
+
* - Event title
|
|
945
|
+
*/
|
|
946
|
+
title: string;
|
|
947
|
+
/**
|
|
948
|
+
* - Occurrence start date
|
|
949
|
+
*/
|
|
950
|
+
start: Date;
|
|
951
|
+
/**
|
|
952
|
+
* - Occurrence end date
|
|
953
|
+
*/
|
|
954
|
+
end: Date;
|
|
955
|
+
/**
|
|
956
|
+
* - Occurrence start in UTC
|
|
957
|
+
*/
|
|
958
|
+
startUTC?: Date;
|
|
959
|
+
/**
|
|
960
|
+
* - Occurrence end in UTC
|
|
961
|
+
*/
|
|
962
|
+
endUTC?: Date;
|
|
963
|
+
/**
|
|
964
|
+
* - Timezone the occurrence was expanded in
|
|
965
|
+
*/
|
|
966
|
+
timezone: string;
|
|
967
|
+
/**
|
|
968
|
+
* - Start of the series (DTSTART)
|
|
969
|
+
*/
|
|
970
|
+
originalStart?: Date;
|
|
971
|
+
/**
|
|
972
|
+
* - Whether the event is all-day
|
|
973
|
+
*/
|
|
974
|
+
allDay: boolean;
|
|
975
|
+
/**
|
|
976
|
+
* - Event description
|
|
977
|
+
*/
|
|
978
|
+
description?: string;
|
|
979
|
+
/**
|
|
980
|
+
* - Event location
|
|
981
|
+
*/
|
|
982
|
+
location?: string;
|
|
983
|
+
/**
|
|
984
|
+
* - Event categories
|
|
985
|
+
*/
|
|
986
|
+
categories?: string[];
|
|
987
|
+
/**
|
|
988
|
+
* - 'confirmed', or 'cancelled' for exception dates yielded with includeCancelled
|
|
989
|
+
*/
|
|
990
|
+
status?: EventStatus;
|
|
991
|
+
/**
|
|
992
|
+
* - Reason recorded for a cancelled occurrence
|
|
993
|
+
*/
|
|
994
|
+
cancellationReason?: string;
|
|
995
|
+
/**
|
|
996
|
+
* - Whether the occurrence belongs to a recurring series
|
|
997
|
+
*/
|
|
998
|
+
isRecurring: boolean;
|
|
999
|
+
/**
|
|
1000
|
+
* - Whether a stored instance modification was applied
|
|
1001
|
+
*/
|
|
1002
|
+
isModified?: boolean;
|
|
859
1003
|
};
|
|
860
1004
|
export type CalendarPlugin = {
|
|
861
1005
|
/**
|
|
@@ -1267,6 +1411,14 @@ export type ConflictSummary = {
|
|
|
1267
1411
|
* @property {import('./events/Event.js').Event[]} removed - Events removed by the operation
|
|
1268
1412
|
* @property {import('./events/Event.js').Event[]} unchanged - Events left untouched
|
|
1269
1413
|
*/
|
|
1414
|
+
/**
|
|
1415
|
+
* Payload of the Calendar `eventSelect` event
|
|
1416
|
+
* @typedef {Object} EventSelectPayload
|
|
1417
|
+
* @property {import('./events/Event.js').Event} event - The stored event (the master for an occurrence id)
|
|
1418
|
+
* @property {string} eventId - Id of the stored event, as kept in the state's selectedEventId
|
|
1419
|
+
* @property {string|null} occurrenceId - The occurrence id that was selected, or null for a stored event's id
|
|
1420
|
+
* @property {import('./events/Event.js').Event|null} occurrence - The selected occurrence as in view data, or null
|
|
1421
|
+
*/
|
|
1270
1422
|
/**
|
|
1271
1423
|
* @typedef {Object} QueryFilters
|
|
1272
1424
|
* @property {Date} [start] - Start date for range query
|
|
@@ -1288,6 +1440,55 @@ export type ConflictSummary = {
|
|
|
1288
1440
|
* @property {Date} start - Occurrence start date
|
|
1289
1441
|
* @property {Date} end - Occurrence end date
|
|
1290
1442
|
* @property {string} recurringEventId - ID of the parent recurring event
|
|
1443
|
+
* @property {string} [timezone] - Timezone the occurrence was expanded in
|
|
1444
|
+
* @property {Date} [originalStart] - Start of the series (DTSTART)
|
|
1445
|
+
*/
|
|
1446
|
+
/**
|
|
1447
|
+
* Window for lazy occurrence iteration. Both bounds are exclusive unless
|
|
1448
|
+
* `inclusive` is set: an occurrence starting exactly at `after` or `before`
|
|
1449
|
+
* is skipped by default, so iterating from a known occurrence's start
|
|
1450
|
+
* continues the series without repeating it. Omit a bound to leave that
|
|
1451
|
+
* end of the window open.
|
|
1452
|
+
* @typedef {Object} OccurrenceIteratorOptions
|
|
1453
|
+
* @property {Date|number} [after] - Only occurrences starting after this instant (Date or timestamp)
|
|
1454
|
+
* @property {Date|number} [before] - Only occurrences starting before this instant (Date or timestamp)
|
|
1455
|
+
* @property {boolean} [inclusive=false] - Treat `after` and `before` as closed bounds
|
|
1456
|
+
* @property {string} [timezone] - Timezone for expansion (defaults to the event's)
|
|
1457
|
+
*/
|
|
1458
|
+
/**
|
|
1459
|
+
* Options for lazy occurrence iteration through RecurrenceEngineV2,
|
|
1460
|
+
* EventStore and Calendar: the OccurrenceIteratorOptions window plus the
|
|
1461
|
+
* expansion switches RecurrenceEngineV2.expandEvent accepts.
|
|
1462
|
+
* @typedef {Object} ExpandedOccurrenceIteratorOptions
|
|
1463
|
+
* @property {Date|number} [after] - Only occurrences starting after this instant (Date or timestamp)
|
|
1464
|
+
* @property {Date|number} [before] - Only occurrences starting before this instant (Date or timestamp)
|
|
1465
|
+
* @property {boolean} [inclusive=false] - Treat `after` and `before` as closed bounds
|
|
1466
|
+
* @property {string} [timezone] - Timezone for expansion (defaults to the event's)
|
|
1467
|
+
* @property {boolean} [includeModified=true] - Apply stored instance modifications
|
|
1468
|
+
* @property {boolean} [includeCancelled=false] - Yield exception dates as cancelled occurrences
|
|
1469
|
+
* @property {boolean} [handleDST=true] - Adjust occurrences across DST transitions
|
|
1470
|
+
*/
|
|
1471
|
+
/**
|
|
1472
|
+
* Occurrence produced by RecurrenceEngineV2 (and therefore by EventStore
|
|
1473
|
+
* and Calendar occurrence queries)
|
|
1474
|
+
* @typedef {Object} ExpandedOccurrence
|
|
1475
|
+
* @property {string} id - Occurrence ID (`<eventId>_<startTimestamp>` for recurring events)
|
|
1476
|
+
* @property {string} [recurringEventId] - ID of the parent recurring event
|
|
1477
|
+
* @property {string} title - Event title
|
|
1478
|
+
* @property {Date} start - Occurrence start date
|
|
1479
|
+
* @property {Date} end - Occurrence end date
|
|
1480
|
+
* @property {Date} [startUTC] - Occurrence start in UTC
|
|
1481
|
+
* @property {Date} [endUTC] - Occurrence end in UTC
|
|
1482
|
+
* @property {string} timezone - Timezone the occurrence was expanded in
|
|
1483
|
+
* @property {Date} [originalStart] - Start of the series (DTSTART)
|
|
1484
|
+
* @property {boolean} allDay - Whether the event is all-day
|
|
1485
|
+
* @property {string} [description] - Event description
|
|
1486
|
+
* @property {string} [location] - Event location
|
|
1487
|
+
* @property {string[]} [categories] - Event categories
|
|
1488
|
+
* @property {EventStatus} [status] - 'confirmed', or 'cancelled' for exception dates yielded with includeCancelled
|
|
1489
|
+
* @property {string} [cancellationReason] - Reason recorded for a cancelled occurrence
|
|
1490
|
+
* @property {boolean} isRecurring - Whether the occurrence belongs to a recurring series
|
|
1491
|
+
* @property {boolean} [isModified] - Whether a stored instance modification was applied
|
|
1291
1492
|
*/
|
|
1292
1493
|
/**
|
|
1293
1494
|
* @typedef {Object} CalendarPlugin
|