@forcecalendar/core 2.1.70 → 2.2.0

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.
@@ -12,7 +12,7 @@ import { TimezoneManager } from '../timezone/TimezoneManager.js';
12
12
  export class Calendar {
13
13
  /**
14
14
  * Create a new Calendar instance
15
- * @param {import('../../types.js').CalendarConfig} [config={}] - Configuration options
15
+ * @param {import('../types.js').CalendarConfig} [config={}] - Configuration options
16
16
  */
17
17
  constructor(config = {}) {
18
18
  // Initialize timezone manager first (use singleton to share cache)
@@ -69,7 +69,7 @@ export class Calendar {
69
69
 
70
70
  /**
71
71
  * Set the calendar view
72
- * @param {import('../../types.js').ViewType} viewType - The view type ('month', 'week', 'day', 'list')
72
+ * @param {import('../types.js').ViewType} viewType - The view type ('month', 'week', 'day', 'list')
73
73
  * @param {Date} [date=null] - Optional date to navigate to
74
74
  */
75
75
  setView(viewType, date = null) {
@@ -87,7 +87,7 @@ export class Calendar {
87
87
 
88
88
  /**
89
89
  * Get the current view type
90
- * @returns {import('../../types.js').ViewType} The current view type
90
+ * @returns {import('../types.js').ViewType} The current view type
91
91
  */
92
92
  getView() {
93
93
  return this.state.get('view');
@@ -160,7 +160,7 @@ export class Calendar {
160
160
 
161
161
  /**
162
162
  * Add an event
163
- * @param {import('../events/Event.js').Event|import('../../types.js').EventData} eventData - Event data or Event instance
163
+ * @param {import('../events/Event.js').Event|import('../types.js').EventData} eventData - Event data or Event instance
164
164
  * @returns {import('../events/Event.js').Event} The added event
165
165
  */
166
166
  addEvent(eventData) {
@@ -389,7 +389,7 @@ export class Calendar {
389
389
 
390
390
  /**
391
391
  * Get the current view's data
392
- * @returns {import('../../types.js').MonthViewData|import('../../types.js').WeekViewData|import('../../types.js').DayViewData|import('../../types.js').ListViewData|null} View-specific data
392
+ * @returns {import('../types.js').MonthViewData|import('../types.js').WeekViewData|import('../types.js').DayViewData|import('../types.js').ListViewData|null} View-specific data
393
393
  */
394
394
  getViewData() {
395
395
  const view = this.state.get('view');
@@ -14,9 +14,9 @@ export class ConflictDetector {
14
14
 
15
15
  /**
16
16
  * Check for conflicts for a specific event
17
- * @param {import('../events/Event.js').Event|import('../../types.js').EventData} event - Event to check
18
- * @param {import('../../types.js').ConflictCheckOptions} [options={}] - Check options
19
- * @returns {import('../../types.js').ConflictSummary} Conflict summary
17
+ * @param {import('../events/Event.js').Event|import('../types.js').EventData} event - Event to check
18
+ * @param {import('../types.js').ConflictCheckOptions} [options={}] - Check options
19
+ * @returns {import('../types.js').ConflictSummary} Conflict summary
20
20
  */
21
21
  checkConflicts(event, options = {}) {
22
22
  // Default options
@@ -87,8 +87,8 @@ export class ConflictDetector {
87
87
  * Check for conflicts between two specific events
88
88
  * @param {import('../events/Event.js').Event} event1 - First event
89
89
  * @param {import('../events/Event.js').Event} event2 - Second event
90
- * @param {import('../../types.js').ConflictCheckOptions} [options={}] - Check options
91
- * @returns {import('../../types.js').ConflictDetails[]} Array of conflicts
90
+ * @param {import('../types.js').ConflictCheckOptions} [options={}] - Check options
91
+ * @returns {import('../types.js').ConflictDetails[]} Array of conflicts
92
92
  */
93
93
  checkEventPairConflicts(event1, event2, options = {}) {
94
94
  const opts = {
@@ -18,8 +18,8 @@ export class Event {
18
18
 
19
19
  /**
20
20
  * Normalize event data
21
- * @param {import('../../types.js').EventData} data - Raw event data
22
- * @returns {import('../../types.js').EventData} Normalized event data
21
+ * @param {import('../types.js').EventData} data - Raw event data
22
+ * @returns {import('../types.js').EventData} Normalized event data
23
23
  */
24
24
  static normalize(data) {
25
25
  const normalized = { ...data };
@@ -109,7 +109,7 @@ export class Event {
109
109
 
110
110
  /**
111
111
  * Validate event data
112
- * @param {import('../../types.js').EventData} data - Normalized event data
112
+ * @param {import('../types.js').EventData} data - Normalized event data
113
113
  * @throws {Error} If validation fails
114
114
  */
115
115
  static validate(data) {
@@ -173,7 +173,7 @@ export class Event {
173
173
  try {
174
174
  new Intl.DateTimeFormat('en-US', { timeZone: data.timeZone });
175
175
  } catch (e) {
176
- throw new Error(`Invalid timezone: ${data.timeZone}`);
176
+ throw new Error(`Invalid timezone: ${data.timeZone}`, { cause: e });
177
177
  }
178
178
  }
179
179
 
@@ -182,14 +182,14 @@ export class Event {
182
182
  try {
183
183
  new Intl.DateTimeFormat('en-US', { timeZone: data.endTimeZone });
184
184
  } catch (e) {
185
- throw new Error(`Invalid end timezone: ${data.endTimeZone}`);
185
+ throw new Error(`Invalid end timezone: ${data.endTimeZone}`, { cause: e });
186
186
  }
187
187
  }
188
188
  }
189
189
 
190
190
  /**
191
191
  * Create a new Event instance
192
- * @param {import('../../types.js').EventData} eventData - Event data object
192
+ * @param {import('../types.js').EventData} eventData - Event data object
193
193
  * @throws {Error} If required fields are missing or invalid
194
194
  */
195
195
  constructor({
@@ -426,7 +426,7 @@ export class Event {
426
426
 
427
427
  /**
428
428
  * Backward-compatible alias for recurrenceRule
429
- * @returns {import('../../types.js').RecurrenceRule|string|null}
429
+ * @returns {import('../types.js').RecurrenceRule|string|null}
430
430
  */
431
431
  get recurrence() {
432
432
  return this.recurrenceRule;
@@ -513,7 +513,7 @@ export class Event {
513
513
 
514
514
  /**
515
515
  * Clone the event with optional updates
516
- * @param {Partial<import('../../types.js').EventData>} [updates={}] - Properties to update in the clone
516
+ * @param {Partial<import('../types.js').EventData>} [updates={}] - Properties to update in the clone
517
517
  * @returns {Event} New Event instance with updated properties
518
518
  */
519
519
  clone(updates = {}) {
@@ -548,7 +548,7 @@ export class Event {
548
548
 
549
549
  /**
550
550
  * Convert event to plain object
551
- * @returns {import('../../types.js').EventData} Plain object representation of the event
551
+ * @returns {import('../types.js').EventData} Plain object representation of the event
552
552
  */
553
553
  toObject() {
554
554
  return {
@@ -580,7 +580,7 @@ export class Event {
580
580
 
581
581
  /**
582
582
  * Create Event from plain object
583
- * @param {import('../../types.js').EventData} obj - Plain object with event properties
583
+ * @param {import('../types.js').EventData} obj - Plain object with event properties
584
584
  * @returns {Event} New Event instance
585
585
  */
586
586
  static fromObject(obj) {
@@ -613,7 +613,7 @@ export class Event {
613
613
 
614
614
  /**
615
615
  * Add an attendee to the event
616
- * @param {import('../../types.js').Attendee} attendee - Attendee to add
616
+ * @param {import('../types.js').Attendee} attendee - Attendee to add
617
617
  * @returns {boolean} True if attendee was added, false if already exists
618
618
  */
619
619
  addAttendee(attendee) {
@@ -662,7 +662,7 @@ export class Event {
662
662
  /**
663
663
  * Update an attendee's response status
664
664
  * @param {string} email - Attendee's email
665
- * @param {import('../../types.js').AttendeeResponseStatus} responseStatus - New response status
665
+ * @param {import('../types.js').AttendeeResponseStatus} responseStatus - New response status
666
666
  * @returns {boolean} True if attendee was updated
667
667
  */
668
668
  updateAttendeeResponse(email, responseStatus) {
@@ -678,7 +678,7 @@ export class Event {
678
678
  /**
679
679
  * Get an attendee by email
680
680
  * @param {string} email - Attendee's email
681
- * @returns {import('../../types.js').Attendee|null} The attendee or null
681
+ * @returns {import('../types.js').Attendee|null} The attendee or null
682
682
  */
683
683
  getAttendee(email) {
684
684
  return this.attendees.find(a => a.email === email) || null;
@@ -695,8 +695,8 @@ export class Event {
695
695
 
696
696
  /**
697
697
  * Get attendees by response status
698
- * @param {import('../../types.js').AttendeeResponseStatus} status - Response status to filter by
699
- * @returns {import('../../types.js').Attendee[]} Filtered attendees
698
+ * @param {import('../types.js').AttendeeResponseStatus} status - Response status to filter by
699
+ * @returns {import('../types.js').Attendee[]} Filtered attendees
700
700
  */
701
701
  getAttendeesByStatus(status) {
702
702
  return this.attendees.filter(a => a.responseStatus === status);
@@ -718,7 +718,7 @@ export class Event {
718
718
 
719
719
  /**
720
720
  * Add a reminder to the event
721
- * @param {import('../../types.js').Reminder} reminder - Reminder to add
721
+ * @param {import('../types.js').Reminder} reminder - Reminder to add
722
722
  * @returns {boolean} True if reminder was added
723
723
  */
724
724
  addReminder(reminder) {
@@ -764,7 +764,7 @@ export class Event {
764
764
 
765
765
  /**
766
766
  * Get active reminders
767
- * @returns {import('../../types.js').Reminder[]} Active reminders
767
+ * @returns {import('../types.js').Reminder[]} Active reminders
768
768
  */
769
769
  getActiveReminders() {
770
770
  return this.reminders.filter(r => r.enabled !== false);
@@ -56,13 +56,13 @@ export class EventStore {
56
56
  // Change tracking
57
57
  /** @type {number} */
58
58
  this.version = 0;
59
- /** @type {Set<import('../../types.js').EventListener>} */
59
+ /** @type {Set<import('../types.js').EventListener>} */
60
60
  this.listeners = new Set();
61
61
  }
62
62
 
63
63
  /**
64
64
  * Add an event to the store
65
- * @param {Event|import('../../types.js').EventData} event - The event to add
65
+ * @param {Event|import('../types.js').EventData} event - The event to add
66
66
  * @returns {Event} The added event
67
67
  * @throws {Error} If event with same ID already exists
68
68
  */
@@ -107,7 +107,7 @@ export class EventStore {
107
107
  /**
108
108
  * Update an existing event
109
109
  * @param {string} eventId - The event ID
110
- * @param {Partial<import('../../types.js').EventData>} updates - Properties to update
110
+ * @param {Partial<import('../types.js').EventData>} updates - Properties to update
111
111
  * @returns {Event} The updated event
112
112
  * @throws {Error} If event not found
113
113
  */
@@ -212,7 +212,7 @@ export class EventStore {
212
212
 
213
213
  /**
214
214
  * Query events with filters
215
- * @param {import('../../types.js').QueryFilters} [filters={}] - Query filters
215
+ * @param {import('../types.js').QueryFilters} [filters={}] - Query filters
216
216
  * @returns {Event[]} Filtered events
217
217
  */
218
218
  queryEvents(filters = {}) {
@@ -566,7 +566,7 @@ export class EventStore {
566
566
  * @returns {Event[]}
567
567
  */
568
568
  getEventsInRange(start, end, expandRecurringOrOptions = true, timezone = null) {
569
- let expandRecurring = true;
569
+ let expandRecurring;
570
570
 
571
571
  if (typeof expandRecurringOrOptions === 'object' && expandRecurringOrOptions !== null) {
572
572
  // Options object form: getEventsInRange(start, end, { expandRecurring, timezone })
@@ -1117,7 +1117,7 @@ export class EventStore {
1117
1117
 
1118
1118
  /**
1119
1119
  * Add multiple events in batch
1120
- * @param {Array<Event|import('../../types.js').EventData>} events - Events to add
1120
+ * @param {Array<Event|import('../types.js').EventData>} events - Events to add
1121
1121
  * @returns {Event[]} Added events
1122
1122
  */
1123
1123
  addEvents(events) {
@@ -1277,9 +1277,9 @@ export class EventStore {
1277
1277
 
1278
1278
  /**
1279
1279
  * Check for conflicts for an event
1280
- * @param {Event|import('../../types.js').EventData} event - Event to check
1281
- * @param {import('../../types.js').ConflictCheckOptions} [options={}] - Check options
1282
- * @returns {import('../../types.js').ConflictSummary} Conflict summary
1280
+ * @param {Event|import('../types.js').EventData} event - Event to check
1281
+ * @param {import('../types.js').ConflictCheckOptions} [options={}] - Check options
1282
+ * @returns {import('../types.js').ConflictSummary} Conflict summary
1283
1283
  */
1284
1284
  checkConflicts(event, options = {}) {
1285
1285
  return this.conflictDetector.checkConflicts(event, options);
@@ -1289,8 +1289,8 @@ export class EventStore {
1289
1289
  * Check conflicts between two events
1290
1290
  * @param {string} eventId1 - First event ID
1291
1291
  * @param {string} eventId2 - Second event ID
1292
- * @param {import('../../types.js').ConflictCheckOptions} [options={}] - Check options
1293
- * @returns {import('../../types.js').ConflictDetails[]} Conflicts between events
1292
+ * @param {import('../types.js').ConflictCheckOptions} [options={}] - Check options
1293
+ * @returns {import('../types.js').ConflictDetails[]} Conflicts between events
1294
1294
  */
1295
1295
  checkEventPairConflicts(eventId1, eventId2, options = {}) {
1296
1296
  const event1 = this.getEvent(eventId1);
@@ -1307,8 +1307,8 @@ export class EventStore {
1307
1307
  * Get all conflicts in a date range
1308
1308
  * @param {Date} start - Start date
1309
1309
  * @param {Date} end - End date
1310
- * @param {import('../../types.js').ConflictCheckOptions} [options={}] - Check options
1311
- * @returns {import('../../types.js').ConflictSummary} All conflicts in range
1310
+ * @param {import('../types.js').ConflictCheckOptions} [options={}] - Check options
1311
+ * @returns {import('../types.js').ConflictSummary} All conflicts in range
1312
1312
  */
1313
1313
  getAllConflicts(start, end, options = {}) {
1314
1314
  const events = this.getEventsInRange(start, end, false);
@@ -1363,9 +1363,9 @@ export class EventStore {
1363
1363
 
1364
1364
  /**
1365
1365
  * Add event with conflict checking
1366
- * @param {Event|import('../../types.js').EventData} event - Event to add
1366
+ * @param {Event|import('../types.js').EventData} event - Event to add
1367
1367
  * @param {boolean} [allowConflicts=true] - Whether to allow adding with conflicts
1368
- * @returns {{event: Event, conflicts: import('../../types.js').ConflictSummary}} Result
1368
+ * @returns {{event: Event, conflicts: import('../types.js').ConflictSummary}} Result
1369
1369
  */
1370
1370
  addEventWithConflictCheck(event, allowConflicts = true) {
1371
1371
  // Check conflicts before adding
@@ -1387,7 +1387,7 @@ export class EventStore {
1387
1387
  /**
1388
1388
  * Find events with conflicts
1389
1389
  * @param {Object} [options={}] - Options
1390
- * @returns {Array<{event: Event, conflicts: import('../../types.js').ConflictDetails[]}>} Events with conflicts
1390
+ * @returns {Array<{event: Event, conflicts: import('../types.js').ConflictDetails[]}>} Events with conflicts
1391
1391
  */
1392
1392
  findEventsWithConflicts(options = {}) {
1393
1393
  const eventsWithConflicts = [];
@@ -24,7 +24,7 @@ export class RecurrenceEngine {
24
24
  * @param {Date} rangeEnd - End of the expansion range
25
25
  * @param {number} [maxOccurrences=365] - Maximum number of occurrences to generate
26
26
  * @param {string} [timezone] - Timezone for expansion (important for DST)
27
- * @returns {import('../../types.js').EventOccurrence[]} Array of occurrence objects with start/end dates
27
+ * @returns {import('../types.js').EventOccurrence[]} Array of occurrence objects with start/end dates
28
28
  */
29
29
  static expandEvent(event, rangeStart, rangeEnd, maxOccurrences = 365, timezone = null) {
30
30
  // Enforce hard limit regardless of caller-provided value
@@ -165,8 +165,8 @@ export class RecurrenceEngine {
165
165
 
166
166
  /**
167
167
  * Parse an RRULE string into a rule object
168
- * @param {string|import('../../types.js').RecurrenceRule} ruleString - RRULE string (e.g., "FREQ=DAILY;INTERVAL=1;COUNT=10") or rule object
169
- * @returns {import('../../types.js').RecurrenceRule} Parsed rule object
168
+ * @param {string|import('../types.js').RecurrenceRule} ruleString - RRULE string (e.g., "FREQ=DAILY;INTERVAL=1;COUNT=10") or rule object
169
+ * @returns {import('../types.js').RecurrenceRule} Parsed rule object
170
170
  */
171
171
  static parseRule(ruleString) {
172
172
  // Use the new comprehensive parser
@@ -177,7 +177,7 @@ export class RecurrenceEngine {
177
177
  * Parse a rule with caching for string rules (internal use by expandEvent).
178
178
  * Cached rule objects are shared across calls and must not be mutated.
179
179
  * @param {string|Object} recurrenceRule - RRULE string or rule object
180
- * @returns {import('../../types.js').RecurrenceRule} Parsed rule object
180
+ * @returns {import('../types.js').RecurrenceRule} Parsed rule object
181
181
  * @private
182
182
  */
183
183
  static _getParsedRule(recurrenceRule) {
@@ -106,7 +106,7 @@ export class ICSHandler {
106
106
 
107
107
  return results;
108
108
  } catch (error) {
109
- throw new Error(`ICS import failed: ${error.message}`);
109
+ throw new Error(`ICS import failed: ${error.message}`, { cause: error });
110
110
  }
111
111
  }
112
112
 
@@ -221,9 +221,11 @@ export class ICSHandler {
221
221
  }
222
222
  } catch (error) {
223
223
  if (error.name === 'AbortError') {
224
- throw new Error(`Failed to import from URL: request timed out after ${requestTimeout}ms`);
224
+ throw new Error(`Failed to import from URL: request timed out after ${requestTimeout}ms`, {
225
+ cause: error
226
+ });
225
227
  }
226
- throw new Error(`Failed to import from URL: ${error.message}`);
228
+ throw new Error(`Failed to import from URL: ${error.message}`, { cause: error });
227
229
  }
228
230
  }
229
231
 
package/core/index.js CHANGED
@@ -24,11 +24,15 @@ export { RecurrenceEngine } from './events/RecurrenceEngine.js';
24
24
  export { RecurrenceEngineV2 } from './events/RecurrenceEngineV2.js';
25
25
  export { RRuleParser } from './events/RRuleParser.js';
26
26
 
27
+ // Timezone and Conflicts
28
+ export { TimezoneManager } from './timezone/TimezoneManager.js';
29
+ export { ConflictDetector } from './conflicts/ConflictDetector.js';
30
+
27
31
  // Enhanced Integration
28
32
  export { EnhancedCalendar } from './integration/EnhancedCalendar.js';
29
33
 
30
34
  // Version — keep in sync with package.json
31
- export const VERSION = '2.1.70';
35
+ export const VERSION = '2.2.0';
32
36
 
33
37
  // Default export
34
38
  export { Calendar as default } from './calendar/Calendar.js';
@@ -5,7 +5,7 @@
5
5
  export class StateManager {
6
6
  /**
7
7
  * Create a new StateManager instance
8
- * @param {Partial<import('../../types.js').CalendarState>} [initialState={}] - Initial state values
8
+ * @param {Partial<import('../types.js').CalendarState>} [initialState={}] - Initial state values
9
9
  */
10
10
  constructor(initialState = {}) {
11
11
  this.state = {
@@ -75,7 +75,7 @@ export class StateManager {
75
75
 
76
76
  /**
77
77
  * Get the current state
78
- * @returns {import('../../types.js').CalendarState} Current state (frozen)
78
+ * @returns {import('../types.js').CalendarState} Current state (frozen)
79
79
  */
80
80
  getState() {
81
81
  return Object.freeze({ ...this.state });
@@ -83,7 +83,7 @@ export class StateManager {
83
83
 
84
84
  /**
85
85
  * Get a specific state value
86
- * @param {keyof import('../../types.js').CalendarState} key - The state key
86
+ * @param {keyof import('../types.js').CalendarState} key - The state key
87
87
  * @returns {any} The state value
88
88
  */
89
89
  get(key) {
package/core/types.js CHANGED
@@ -19,6 +19,9 @@
19
19
  * @property {boolean} [recurring=false] - Whether this is a recurring event
20
20
  * @property {RecurrenceRule|string} [recurrenceRule=null] - Recurrence rule (RRULE string or object)
21
21
  * @property {string} [timeZone=null] - IANA timezone for the event
22
+ * @property {string} [endTimeZone=null] - IANA timezone for the event end (cross-timezone events)
23
+ * @property {RecurrenceRule|string} [recurrence=null] - Backward-compatible alias for recurrenceRule
24
+ * @property {string} [category=null] - Single category (alias for a one-element categories array)
22
25
  * @property {EventStatus} [status='confirmed'] - Event status
23
26
  * @property {EventVisibility} [visibility='public'] - Event visibility
24
27
  * @property {Organizer} [organizer=null] - Event organizer
@@ -172,7 +175,7 @@
172
175
  * @property {boolean} isCurrentMonth - Whether this day is in the current month
173
176
  * @property {boolean} isToday - Whether this is today
174
177
  * @property {boolean} isWeekend - Whether this is a weekend day
175
- * @property {import('./core/events/Event.js').Event[]} events - Events for this day
178
+ * @property {import('./events/Event.js').Event[]} events - Events for this day
176
179
  */
177
180
 
178
181
  /**
@@ -191,9 +194,9 @@
191
194
  * @property {string} dayName - Localized day name
192
195
  * @property {boolean} isToday - Whether this is today
193
196
  * @property {boolean} isWeekend - Whether this is a weekend day
194
- * @property {import('./core/events/Event.js').Event[]} events - All events for this day
195
- * @property {Array<import('./core/events/Event.js').Event[]>} overlapGroups - Groups of overlapping events
196
- * @property {function(import('./core/events/Event.js').Event[]): Map<string, EventPosition>} getEventPositions - Function to calculate positions
197
+ * @property {import('./events/Event.js').Event[]} events - All events for this day
198
+ * @property {Array<import('./events/Event.js').Event[]>} overlapGroups - Groups of overlapping events
199
+ * @property {(events: import('./events/Event.js').Event[]) => Map<string, EventPosition>} getEventPositions - Function to calculate positions
197
200
  */
198
201
 
199
202
  /**
@@ -208,7 +211,7 @@
208
211
  * @property {Date} date - Date being displayed
209
212
  * @property {string} dayName - Localized day name
210
213
  * @property {boolean} isToday - Whether this is today
211
- * @property {import('./core/events/Event.js').Event[]} allDayEvents - All-day events
214
+ * @property {import('./events/Event.js').Event[]} allDayEvents - All-day events
212
215
  * @property {HourSlot[]} hours - Hourly time slots
213
216
  */
214
217
 
@@ -216,7 +219,7 @@
216
219
  * @typedef {Object} HourSlot
217
220
  * @property {number} hour - Hour (0-23)
218
221
  * @property {string} time - Formatted time string
219
- * @property {import('./core/events/Event.js').Event[]} events - Events in this hour
222
+ * @property {import('./events/Event.js').Event[]} events - Events in this hour
220
223
  */
221
224
 
222
225
  /**
@@ -233,7 +236,7 @@
233
236
  * @property {Date} date - Date object
234
237
  * @property {string} dayName - Localized day name
235
238
  * @property {boolean} isToday - Whether this is today
236
- * @property {import('./core/events/Event.js').Event[]} events - Events for this day
239
+ * @property {import('./events/Event.js').Event[]} events - Events for this day
237
240
  */
238
241
 
239
242
  /**
@@ -273,9 +276,9 @@
273
276
  /**
274
277
  * @typedef {Object} EventStoreChange
275
278
  * @property {('add'|'update'|'remove'|'clear')} type - Type of change
276
- * @property {import('./core/events/Event.js').Event} [event] - Affected event
277
- * @property {import('./core/events/Event.js').Event} [oldEvent] - Previous event state (for updates)
278
- * @property {import('./core/events/Event.js').Event[]} [oldEvents] - Previous events (for clear)
279
+ * @property {import('./events/Event.js').Event} [event] - Affected event
280
+ * @property {import('./events/Event.js').Event} [oldEvent] - Previous event state (for updates)
281
+ * @property {import('./events/Event.js').Event[]} [oldEvents] - Previous events (for clear)
279
282
  * @property {number} version - Store version number
280
283
  */
281
284
 
@@ -305,16 +308,16 @@
305
308
 
306
309
  /**
307
310
  * @typedef {Object} CalendarPlugin
308
- * @property {function(import('./core/calendar/Calendar.js').Calendar): void} install - Installation function
309
- * @property {function(import('./core/calendar/Calendar.js').Calendar): void} [uninstall] - Cleanup function
311
+ * @property {(calendar: import('./calendar/Calendar.js').Calendar) => void} install - Installation function
312
+ * @property {(calendar: import('./calendar/Calendar.js').Calendar) => void} [uninstall] - Cleanup function
310
313
  */
311
314
 
312
315
  /**
313
- * @typedef {function(any): void} EventListener
316
+ * @typedef {(payload: any) => void} EventListener
314
317
  */
315
318
 
316
319
  /**
317
- * @typedef {function(): void} UnsubscribeFn
320
+ * @typedef {() => void} UnsubscribeFn
318
321
  */
319
322
 
320
323
  /**
package/package.json CHANGED
@@ -1,32 +1,55 @@
1
1
  {
2
2
  "name": "@forcecalendar/core",
3
- "version": "2.1.70",
3
+ "version": "2.2.0",
4
4
  "type": "module",
5
5
  "private": false,
6
6
  "description": "A modern, lightweight, framework-agnostic calendar engine optimized for Salesforce",
7
7
  "main": "core/index.js",
8
8
  "module": "core/index.js",
9
- "types": "core/types.js",
9
+ "types": "./types/index.d.ts",
10
10
  "sideEffects": false,
11
11
  "scripts": {
12
12
  "test": "node tests/run-all.js",
13
13
  "test:ics": "node tests/integration/test-ics.js",
14
14
  "test:search": "node tests/integration/test-search.js",
15
- "lint": "eslint core/ --ext .js",
16
- "lint:fix": "eslint core/ --ext .js --fix",
15
+ "lint": "eslint core/",
16
+ "lint:fix": "eslint core/ --fix",
17
17
  "format": "prettier --write \"core/**/*.js\"",
18
18
  "format:check": "prettier --check \"core/**/*.js\"",
19
19
  "quality": "npm run lint && npm run format:check",
20
- "sync:version": "node scripts/sync-version.js"
20
+ "sync:version": "node scripts/sync-version.js",
21
+ "build:types": "tsc -p tsconfig.types.json",
22
+ "prepublishOnly": "npm run build:types"
21
23
  },
22
24
  "exports": {
23
- ".": "./core/index.js",
24
- "./calendar": "./core/calendar/Calendar.js",
25
- "./events": "./core/events/Event.js",
26
- "./state": "./core/state/StateManager.js",
27
- "./search": "./core/search/EventSearch.js",
28
- "./ics": "./core/ics/ICSHandler.js",
29
- "./types": "./core/types.js"
25
+ ".": {
26
+ "types": "./types/index.d.ts",
27
+ "default": "./core/index.js"
28
+ },
29
+ "./calendar": {
30
+ "types": "./types/calendar/Calendar.d.ts",
31
+ "default": "./core/calendar/Calendar.js"
32
+ },
33
+ "./events": {
34
+ "types": "./types/events/Event.d.ts",
35
+ "default": "./core/events/Event.js"
36
+ },
37
+ "./state": {
38
+ "types": "./types/state/StateManager.d.ts",
39
+ "default": "./core/state/StateManager.js"
40
+ },
41
+ "./search": {
42
+ "types": "./types/search/EventSearch.d.ts",
43
+ "default": "./core/search/EventSearch.js"
44
+ },
45
+ "./ics": {
46
+ "types": "./types/ics/ICSHandler.d.ts",
47
+ "default": "./core/ics/ICSHandler.js"
48
+ },
49
+ "./types": {
50
+ "types": "./types/types.d.ts",
51
+ "default": "./core/types.js"
52
+ }
30
53
  },
31
54
  "repository": {
32
55
  "type": "git",
@@ -50,20 +73,17 @@
50
73
  },
51
74
  "homepage": "https://github.com/forceCalendar/core#readme",
52
75
  "devDependencies": {
53
- "@babel/core": "^7.29.6",
54
- "@babel/preset-env": "^7.29.7",
55
- "@rollup/plugin-babel": "^7.0.0",
56
- "@rollup/plugin-node-resolve": "^16.0.3",
57
- "@rollup/plugin-terser": "^1.0.0",
58
- "eslint": "^8.50.0",
76
+ "@eslint/js": "^10.0.1",
77
+ "eslint": "^10.6.0",
78
+ "globals": "^17.7.0",
59
79
  "prettier": "^3.0.3",
60
- "rollup": "^4.61.1",
61
- "vite": "^6.4.3"
80
+ "typescript": "^7.0.2"
62
81
  },
63
82
  "files": [
64
83
  "core/**/*.js",
65
84
  "!core/**/*.test.js",
66
85
  "!core/**/*.spec.js",
86
+ "types/**/*.d.ts",
67
87
  "README.md",
68
88
  "LICENSE"
69
89
  ]