@forcecalendar/interface 1.0.26 → 1.0.27
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.
|
@@ -738,7 +738,7 @@ class C {
|
|
|
738
738
|
*/
|
|
739
739
|
getTimezoneOffset(e, t) {
|
|
740
740
|
t = this.database.resolveAlias(t);
|
|
741
|
-
const s = `${t}_${e.getFullYear()}_${e.getMonth()}_${e.getDate()}`;
|
|
741
|
+
const s = `${t}_${e.getFullYear()}_${e.getMonth()}_${e.getDate()}_${e.getHours()}`;
|
|
742
742
|
if (this.offsetCache.has(s))
|
|
743
743
|
return this.cacheHits++, this._manageCacheSize(), this.offsetCache.get(s);
|
|
744
744
|
if (this.cacheMisses++, typeof Intl < "u" && Intl.DateTimeFormat)
|
|
@@ -1022,6 +1022,12 @@ class w {
|
|
|
1022
1022
|
} catch {
|
|
1023
1023
|
throw new Error(`Invalid timezone: ${e.timeZone}`);
|
|
1024
1024
|
}
|
|
1025
|
+
if (e.endTimeZone)
|
|
1026
|
+
try {
|
|
1027
|
+
new Intl.DateTimeFormat("en-US", { timeZone: e.endTimeZone });
|
|
1028
|
+
} catch {
|
|
1029
|
+
throw new Error(`Invalid end timezone: ${e.endTimeZone}`);
|
|
1030
|
+
}
|
|
1025
1031
|
}
|
|
1026
1032
|
/**
|
|
1027
1033
|
* Create a new Event instance
|
|
@@ -1056,8 +1062,8 @@ class w {
|
|
|
1056
1062
|
categories: U,
|
|
1057
1063
|
// Support plural categories (no default)
|
|
1058
1064
|
attachments: Y = [],
|
|
1059
|
-
conferenceData:
|
|
1060
|
-
metadata:
|
|
1065
|
+
conferenceData: P = null,
|
|
1066
|
+
metadata: N = {},
|
|
1061
1067
|
...V
|
|
1062
1068
|
// Capture any extra properties
|
|
1063
1069
|
}) {
|
|
@@ -1088,8 +1094,8 @@ class w {
|
|
|
1088
1094
|
categories: U,
|
|
1089
1095
|
// Pass categories to normalize
|
|
1090
1096
|
attachments: Y,
|
|
1091
|
-
conferenceData:
|
|
1092
|
-
metadata:
|
|
1097
|
+
conferenceData: P,
|
|
1098
|
+
metadata: N,
|
|
1093
1099
|
...V
|
|
1094
1100
|
// Pass any extra properties
|
|
1095
1101
|
});
|
|
@@ -1768,8 +1774,10 @@ let f = class y {
|
|
|
1768
1774
|
* @returns {number}
|
|
1769
1775
|
*/
|
|
1770
1776
|
static getWeekNumber(e) {
|
|
1771
|
-
const t = new Date(e
|
|
1772
|
-
|
|
1777
|
+
const t = new Date(e);
|
|
1778
|
+
t.setHours(0, 0, 0, 0), t.setDate(t.getDate() + 4 - (t.getDay() || 7));
|
|
1779
|
+
const s = new Date(t.getFullYear(), 0, 1);
|
|
1780
|
+
return Math.ceil(((t - s) / 864e5 + 1) / 7);
|
|
1773
1781
|
}
|
|
1774
1782
|
/**
|
|
1775
1783
|
* Get the day of week for a date
|
|
@@ -2261,7 +2269,39 @@ class K {
|
|
|
2261
2269
|
if (n.count && d >= n.count)
|
|
2262
2270
|
break;
|
|
2263
2271
|
}
|
|
2264
|
-
return a;
|
|
2272
|
+
return n.bySetPos && n.bySetPos.length > 0 && n.freq !== "MONTHLY" ? this._applyBySetPos(a, n) : a;
|
|
2273
|
+
}
|
|
2274
|
+
/**
|
|
2275
|
+
* Apply BYSETPOS to filter occurrences within each frequency period
|
|
2276
|
+
* @param {Array} occurrences - Generated occurrences
|
|
2277
|
+
* @param {Object} rule - Recurrence rule
|
|
2278
|
+
* @returns {Array} Filtered occurrences
|
|
2279
|
+
* @private
|
|
2280
|
+
*/
|
|
2281
|
+
static _applyBySetPos(e, t) {
|
|
2282
|
+
if (e.length === 0) return e;
|
|
2283
|
+
const s = /* @__PURE__ */ new Map();
|
|
2284
|
+
for (const r of e) {
|
|
2285
|
+
let n;
|
|
2286
|
+
switch (t.freq) {
|
|
2287
|
+
case "YEARLY":
|
|
2288
|
+
n = r.start.getFullYear();
|
|
2289
|
+
break;
|
|
2290
|
+
case "WEEKLY":
|
|
2291
|
+
n = `${r.start.getFullYear()}-W${f.getWeekNumber(r.start)}`;
|
|
2292
|
+
break;
|
|
2293
|
+
default:
|
|
2294
|
+
n = `${r.start.getFullYear()}-${r.start.getMonth()}`;
|
|
2295
|
+
}
|
|
2296
|
+
s.has(n) || s.set(n, []), s.get(n).push(r);
|
|
2297
|
+
}
|
|
2298
|
+
const i = [];
|
|
2299
|
+
for (const r of s.values())
|
|
2300
|
+
for (const n of t.bySetPos) {
|
|
2301
|
+
const a = n > 0 ? n - 1 : r.length + n;
|
|
2302
|
+
a >= 0 && a < r.length && i.push(r[a]);
|
|
2303
|
+
}
|
|
2304
|
+
return i.sort((r, n) => r.start - n.start);
|
|
2265
2305
|
}
|
|
2266
2306
|
/**
|
|
2267
2307
|
* Parse an RRULE string into a rule object
|
|
@@ -2281,6 +2321,15 @@ class K {
|
|
|
2281
2321
|
static getNextOccurrence(e, t, s = "UTC") {
|
|
2282
2322
|
const i = new Date(e);
|
|
2283
2323
|
switch (t.freq) {
|
|
2324
|
+
case "SECONDLY":
|
|
2325
|
+
i.setSeconds(i.getSeconds() + t.interval);
|
|
2326
|
+
break;
|
|
2327
|
+
case "MINUTELY":
|
|
2328
|
+
i.setMinutes(i.getMinutes() + t.interval);
|
|
2329
|
+
break;
|
|
2330
|
+
case "HOURLY":
|
|
2331
|
+
i.setHours(i.getHours() + t.interval);
|
|
2332
|
+
break;
|
|
2284
2333
|
case "DAILY":
|
|
2285
2334
|
i.setDate(i.getDate() + t.interval);
|
|
2286
2335
|
break;
|
|
@@ -2297,8 +2346,15 @@ class K {
|
|
|
2297
2346
|
case "MONTHLY":
|
|
2298
2347
|
if (t.byMonthDay && t.byMonthDay.length > 0) {
|
|
2299
2348
|
const r = i.getMonth();
|
|
2300
|
-
i.setMonth(r + t.interval)
|
|
2301
|
-
|
|
2349
|
+
i.setMonth(r + t.interval);
|
|
2350
|
+
const n = new Date(i.getFullYear(), i.getMonth() + 1, 0).getDate();
|
|
2351
|
+
i.setDate(Math.min(t.byMonthDay[0], n));
|
|
2352
|
+
} else if (t.byDay && t.byDay.length > 0) {
|
|
2353
|
+
i.setMonth(i.getMonth() + t.interval);
|
|
2354
|
+
const n = t.byDay[0].match(/^(-?\d+)?([A-Z]{2})$/), o = (n && n[1] ? parseInt(n[1], 10) : null) || t.bySetPos && t.bySetPos[0] || 1;
|
|
2355
|
+
this.setToWeekdayOfMonth(i, t.byDay[0], o);
|
|
2356
|
+
} else
|
|
2357
|
+
i.setMonth(i.getMonth() + t.interval);
|
|
2302
2358
|
break;
|
|
2303
2359
|
case "YEARLY":
|
|
2304
2360
|
t.byMonth && t.byMonth.length > 0 ? (i.setFullYear(i.getFullYear() + t.interval), i.setMonth(t.byMonth[0] - 1)) : i.setFullYear(i.getFullYear() + t.interval);
|
|
@@ -2373,10 +2429,11 @@ class K {
|
|
|
2373
2429
|
const i = e.toDateString(), r = e.getTime();
|
|
2374
2430
|
return t.exceptions.some((n) => {
|
|
2375
2431
|
if (typeof n == "object" && n.date) {
|
|
2376
|
-
const
|
|
2377
|
-
return n.matchTime ? Math.abs(
|
|
2432
|
+
const c = n.date instanceof Date ? n.date : new Date(n.date);
|
|
2433
|
+
return n.matchTime ? Math.abs(c.getTime() - r) < 1e3 : c.toDateString() === i;
|
|
2378
2434
|
}
|
|
2379
|
-
|
|
2435
|
+
const a = n instanceof Date ? n : new Date(n);
|
|
2436
|
+
return a.getHours() !== 0 || a.getMinutes() !== 0 || a.getSeconds() !== 0 ? Math.abs(a.getTime() - r) < 1e3 : a.toDateString() === i;
|
|
2380
2437
|
});
|
|
2381
2438
|
}
|
|
2382
2439
|
/**
|
|
@@ -3403,7 +3460,7 @@ class X {
|
|
|
3403
3460
|
throw new Error(`Event with id ${e} not found`);
|
|
3404
3461
|
this._unindexEvent(s);
|
|
3405
3462
|
const i = s.clone(t);
|
|
3406
|
-
return this.events.set(e, i), this._indexEvent(i), this._notifyChange({
|
|
3463
|
+
return this.events.set(e, i), this.optimizer.cache(e, i, "event"), this.optimizer.queryCache.clear(), this.optimizer.dateRangeCache.clear(), this._indexEvent(i), this._notifyChange({
|
|
3407
3464
|
type: "update",
|
|
3408
3465
|
event: i,
|
|
3409
3466
|
oldEvent: s,
|
|
@@ -3417,7 +3474,7 @@ class X {
|
|
|
3417
3474
|
*/
|
|
3418
3475
|
removeEvent(e) {
|
|
3419
3476
|
const t = this.events.get(e);
|
|
3420
|
-
return t ? (this.events.delete(e), this._unindexEvent(t), this._notifyChange({
|
|
3477
|
+
return t ? (this.events.delete(e), this.optimizer.eventCache.delete(e), this.optimizer.queryCache.clear(), this.optimizer.dateRangeCache.clear(), this._unindexEvent(t), this._notifyChange({
|
|
3421
3478
|
type: "remove",
|
|
3422
3479
|
event: t,
|
|
3423
3480
|
version: ++this.version
|
|
@@ -3554,21 +3611,15 @@ class X {
|
|
|
3554
3611
|
*/
|
|
3555
3612
|
getOverlapGroups(e, t = !0) {
|
|
3556
3613
|
let s = this.getEventsForDate(e);
|
|
3557
|
-
t && (s = s.filter((
|
|
3558
|
-
|
|
3559
|
-
|
|
3560
|
-
|
|
3561
|
-
|
|
3562
|
-
|
|
3563
|
-
|
|
3564
|
-
|
|
3565
|
-
|
|
3566
|
-
s.forEach((l) => {
|
|
3567
|
-
!r.has(l.id) && c.overlaps(l) && (a.push(l), r.add(l.id));
|
|
3568
|
-
}), o++;
|
|
3569
|
-
}
|
|
3570
|
-
i.push(a);
|
|
3571
|
-
}), i;
|
|
3614
|
+
if (t && (s = s.filter((a) => !a.allDay)), s.length === 0) return [];
|
|
3615
|
+
s.sort((a, o) => a.start - o.start || o.end - a.end);
|
|
3616
|
+
const i = [];
|
|
3617
|
+
let r = [s[0]], n = s[0].end;
|
|
3618
|
+
for (let a = 1; a < s.length; a++) {
|
|
3619
|
+
const o = s[a];
|
|
3620
|
+
o.start < n ? (r.push(o), o.end > n && (n = o.end)) : (i.push(r), r = [o], n = o.end);
|
|
3621
|
+
}
|
|
3622
|
+
return i.push(r), i;
|
|
3572
3623
|
}
|
|
3573
3624
|
/**
|
|
3574
3625
|
* Calculate positions for overlapping events (for rendering)
|
|
@@ -3602,29 +3653,31 @@ class X {
|
|
|
3602
3653
|
* Get events for a date range
|
|
3603
3654
|
* @param {Date} start - Start date
|
|
3604
3655
|
* @param {Date} end - End date
|
|
3605
|
-
* @param {boolean|
|
|
3606
|
-
*
|
|
3656
|
+
* @param {boolean|Object} [expandRecurringOrOptions=true] - Boolean to expand recurring events,
|
|
3657
|
+
* or options object: { expandRecurring?: boolean, timezone?: string }
|
|
3658
|
+
* @param {string} [timezone] - Timezone for the query
|
|
3607
3659
|
* @returns {Event[]}
|
|
3608
3660
|
*/
|
|
3609
3661
|
getEventsInRange(e, t, s = !0, i = null) {
|
|
3610
|
-
|
|
3611
|
-
|
|
3612
|
-
|
|
3613
|
-
|
|
3662
|
+
let r = !0;
|
|
3663
|
+
typeof s == "object" && s !== null ? (r = s.expandRecurring !== !1, i = s.timezone || i) : typeof s == "string" ? (i = s, r = !0) : r = s, i = i || this.defaultTimezone;
|
|
3664
|
+
const n = this.timezoneManager.toUTC(e, i), a = this.timezoneManager.toUTC(t, i), o = this.queryEvents({
|
|
3665
|
+
start: n,
|
|
3666
|
+
end: a,
|
|
3614
3667
|
sort: "start"
|
|
3615
3668
|
});
|
|
3616
|
-
if (!
|
|
3617
|
-
return
|
|
3618
|
-
const
|
|
3619
|
-
return
|
|
3620
|
-
if (
|
|
3621
|
-
const
|
|
3622
|
-
|
|
3669
|
+
if (!r)
|
|
3670
|
+
return o;
|
|
3671
|
+
const c = [];
|
|
3672
|
+
return o.forEach((l) => {
|
|
3673
|
+
if (l.recurring && l.recurrenceRule) {
|
|
3674
|
+
const h = this.expandRecurringEvent(l, e, t, i);
|
|
3675
|
+
c.push(...h);
|
|
3623
3676
|
} else
|
|
3624
|
-
|
|
3625
|
-
}),
|
|
3626
|
-
const
|
|
3627
|
-
return
|
|
3677
|
+
c.push(l);
|
|
3678
|
+
}), c.sort((l, h) => {
|
|
3679
|
+
const d = l.getStartInTimezone(i), p = h.getStartInTimezone(i);
|
|
3680
|
+
return d - p;
|
|
3628
3681
|
});
|
|
3629
3682
|
}
|
|
3630
3683
|
/**
|
|
@@ -3860,7 +3913,7 @@ class X {
|
|
|
3860
3913
|
*/
|
|
3861
3914
|
addEvents(e) {
|
|
3862
3915
|
return this.optimizer.measure("addEvents", () => {
|
|
3863
|
-
this.startBatch();
|
|
3916
|
+
this.startBatch(!0);
|
|
3864
3917
|
const t = [], s = [];
|
|
3865
3918
|
for (const i of e)
|
|
3866
3919
|
try {
|
|
@@ -3868,7 +3921,7 @@ class X {
|
|
|
3868
3921
|
} catch (r) {
|
|
3869
3922
|
s.push({ event: i, error: r.message });
|
|
3870
3923
|
}
|
|
3871
|
-
return this.commitBatch(), s.length > 0 && console.warn(`Failed to add ${s.length} events:`, s), t;
|
|
3924
|
+
return s.length > 0 && t.length === 0 ? this.rollbackBatch() : this.commitBatch(), s.length > 0 && console.warn(`Failed to add ${s.length} events:`, s), t;
|
|
3872
3925
|
});
|
|
3873
3926
|
}
|
|
3874
3927
|
/**
|
|
@@ -3878,7 +3931,7 @@ class X {
|
|
|
3878
3931
|
*/
|
|
3879
3932
|
updateEvents(e) {
|
|
3880
3933
|
return this.optimizer.measure("updateEvents", () => {
|
|
3881
|
-
this.startBatch();
|
|
3934
|
+
this.startBatch(!0);
|
|
3882
3935
|
const t = [], s = [];
|
|
3883
3936
|
for (const { id: i, updates: r } of e)
|
|
3884
3937
|
try {
|
|
@@ -3886,7 +3939,7 @@ class X {
|
|
|
3886
3939
|
} catch (n) {
|
|
3887
3940
|
s.push({ id: i, error: n.message });
|
|
3888
3941
|
}
|
|
3889
|
-
return this.commitBatch(), s.length > 0 && console.warn(`Failed to update ${s.length} events:`, s), t;
|
|
3942
|
+
return s.length > 0 && t.length === 0 ? this.rollbackBatch() : this.commitBatch(), s.length > 0 && console.warn(`Failed to update ${s.length} events:`, s), t;
|
|
3890
3943
|
});
|
|
3891
3944
|
}
|
|
3892
3945
|
/**
|
|
@@ -3896,11 +3949,11 @@ class X {
|
|
|
3896
3949
|
*/
|
|
3897
3950
|
removeEvents(e) {
|
|
3898
3951
|
return this.optimizer.measure("removeEvents", () => {
|
|
3899
|
-
this.startBatch();
|
|
3952
|
+
this.startBatch(!0);
|
|
3900
3953
|
let t = 0;
|
|
3901
3954
|
for (const s of e)
|
|
3902
3955
|
this.removeEvent(s) && t++;
|
|
3903
|
-
return this.commitBatch(), t;
|
|
3956
|
+
return t === 0 && e.length > 0 ? this.rollbackBatch() : this.commitBatch(), t;
|
|
3904
3957
|
});
|
|
3905
3958
|
}
|
|
3906
3959
|
// ============ Performance Methods ============
|
|
@@ -4125,7 +4178,7 @@ let ee = class {
|
|
|
4125
4178
|
*/
|
|
4126
4179
|
setState(e) {
|
|
4127
4180
|
const t = this.state;
|
|
4128
|
-
typeof e == "function" && (e = e(t));
|
|
4181
|
+
typeof e == "function" && (e = e(t)), e && typeof e == "object" && (delete e.__proto__, delete e.constructor, delete e.prototype);
|
|
4129
4182
|
const s = {
|
|
4130
4183
|
...t,
|
|
4131
4184
|
...e,
|
|
@@ -4946,9 +4999,14 @@ class te {
|
|
|
4946
4999
|
* Destroy the calendar and clean up
|
|
4947
5000
|
*/
|
|
4948
5001
|
destroy() {
|
|
4949
|
-
this.listeners.clear(), this.eventStore.destroy(), this.plugins.forEach((e) => {
|
|
4950
|
-
typeof e.uninstall == "function"
|
|
4951
|
-
|
|
5002
|
+
this._emit("destroy"), this.listeners.clear(), this.eventStore.destroy(), this.plugins.forEach((e) => {
|
|
5003
|
+
if (typeof e.uninstall == "function")
|
|
5004
|
+
try {
|
|
5005
|
+
e.uninstall(this);
|
|
5006
|
+
} catch (t) {
|
|
5007
|
+
console.error("Error uninstalling plugin:", t);
|
|
5008
|
+
}
|
|
5009
|
+
}), this.plugins.clear(), this.views.clear();
|
|
4952
5010
|
}
|
|
4953
5011
|
}
|
|
4954
5012
|
class se {
|