@forcecalendar/interface 1.0.15 → 1.0.17

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.
@@ -1,6 +1,6 @@
1
1
  var V = Object.defineProperty;
2
2
  var P = (p, e, t) => e in p ? V(p, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : p[e] = t;
3
- var _ = (p, e, t) => P(p, typeof e != "symbol" ? e + "" : e, t);
3
+ var I = (p, e, t) => P(p, typeof e != "symbol" ? e + "" : e, t);
4
4
  class $ extends HTMLElement {
5
5
  constructor() {
6
6
  super(), this.attachShadow({ mode: "open" }), this._listeners = [], this._state = null, this._props = /* @__PURE__ */ new Map(), this._initialized = !1;
@@ -1048,14 +1048,14 @@ class M {
1048
1048
  visibility: b = "public",
1049
1049
  organizer: T = null,
1050
1050
  attendees: A = [],
1051
- reminders: I = [],
1051
+ reminders: _ = [],
1052
1052
  category: L,
1053
1053
  // Support singular category (no default)
1054
- categories: O,
1054
+ categories: F,
1055
1055
  // Support plural categories (no default)
1056
- attachments: F = [],
1057
- conferenceData: R = null,
1058
- metadata: H = {},
1056
+ attachments: O = [],
1057
+ conferenceData: H = null,
1058
+ metadata: R = {},
1059
1059
  ...B
1060
1060
  // Capture any extra properties
1061
1061
  }) {
@@ -1079,14 +1079,14 @@ class M {
1079
1079
  visibility: b,
1080
1080
  organizer: T,
1081
1081
  attendees: A,
1082
- reminders: I,
1082
+ reminders: _,
1083
1083
  category: L,
1084
1084
  // Pass category to normalize
1085
- categories: O,
1085
+ categories: F,
1086
1086
  // Pass categories to normalize
1087
- attachments: F,
1088
- conferenceData: R,
1089
- metadata: H,
1087
+ attachments: O,
1088
+ conferenceData: H,
1089
+ metadata: R,
1090
1090
  ...B
1091
1091
  // Pass any extra properties
1092
1092
  });
@@ -2228,8 +2228,8 @@ class N {
2228
2228
  if (d >= t) {
2229
2229
  const b = new Date(d), T = new Date(d.getTime() + o), A = l.getTimezoneOffset(b, c);
2230
2230
  if (A !== g) {
2231
- const I = g - A;
2232
- b.setMinutes(b.getMinutes() + I), T.setMinutes(T.getMinutes() + I);
2231
+ const _ = g - A;
2232
+ b.setMinutes(b.getMinutes() + _), T.setMinutes(T.getMinutes() + _);
2233
2233
  }
2234
2234
  g = A, this.isException(b, n, e.id) || a.push({
2235
2235
  start: b,
@@ -4959,10 +4959,39 @@ class Q {
4959
4959
  * Unsubscribe from an event
4960
4960
  */
4961
4961
  off(e, t) {
4962
+ if (e.includes("*")) {
4963
+ for (const r of this.wildcardHandlers)
4964
+ if (r.pattern === e && r.handler === t) {
4965
+ this.wildcardHandlers.delete(r);
4966
+ return;
4967
+ }
4968
+ return;
4969
+ }
4962
4970
  if (!this.events.has(e)) return;
4963
4971
  const s = this.events.get(e), i = s.findIndex((r) => r.handler === t);
4964
4972
  i > -1 && s.splice(i, 1), s.length === 0 && this.events.delete(e);
4965
4973
  }
4974
+ /**
4975
+ * Remove all wildcard handlers matching a pattern
4976
+ * @param {string} pattern - Pattern to match (e.g., 'event:*')
4977
+ */
4978
+ offWildcard(e) {
4979
+ for (const t of [...this.wildcardHandlers])
4980
+ t.pattern === e && this.wildcardHandlers.delete(t);
4981
+ }
4982
+ /**
4983
+ * Remove all handlers (regular and wildcard) for a specific handler function
4984
+ * Useful for cleanup when a component is destroyed
4985
+ * @param {Function} handler - Handler function to remove
4986
+ */
4987
+ offAll(e) {
4988
+ for (const [t, s] of this.events) {
4989
+ const i = s.findIndex((r) => r.handler === e);
4990
+ i > -1 && s.splice(i, 1), s.length === 0 && this.events.delete(t);
4991
+ }
4992
+ for (const t of [...this.wildcardHandlers])
4993
+ t.handler === e && this.wildcardHandlers.delete(t);
4994
+ }
4966
4995
  /**
4967
4996
  * Emit an event
4968
4997
  * @param {string} eventName - Event name
@@ -5022,6 +5051,21 @@ class Q {
5022
5051
  getHandlerCount(e) {
5023
5052
  return this.events.has(e) ? this.events.get(e).length : 0;
5024
5053
  }
5054
+ /**
5055
+ * Get wildcard handler count
5056
+ */
5057
+ getWildcardHandlerCount() {
5058
+ return this.wildcardHandlers.size;
5059
+ }
5060
+ /**
5061
+ * Get total handler count (for debugging/monitoring)
5062
+ */
5063
+ getTotalHandlerCount() {
5064
+ let e = this.wildcardHandlers.size;
5065
+ for (const t of this.events.values())
5066
+ e += t.length;
5067
+ return e;
5068
+ }
5025
5069
  }
5026
5070
  const y = new Q();
5027
5071
  class J {
@@ -5042,7 +5086,23 @@ class J {
5042
5086
  loading: !1,
5043
5087
  error: null,
5044
5088
  config: { ...e }
5045
- }, this.subscribers = /* @__PURE__ */ new Set(), this.subscribe = this.subscribe.bind(this), this.unsubscribe = this.unsubscribe.bind(this), this.setState = this.setState.bind(this);
5089
+ }, this.subscribers = /* @__PURE__ */ new Set(), this.subscribe = this.subscribe.bind(this), this.unsubscribe = this.unsubscribe.bind(this), this.setState = this.setState.bind(this), this._syncEventsFromCore({ silent: !0 });
5090
+ }
5091
+ /**
5092
+ * Sync state.events from Core calendar (single source of truth)
5093
+ * This ensures state.events always matches Core's event store
5094
+ */
5095
+ _syncEventsFromCore(e = {}) {
5096
+ const t = this.calendar.getEvents() || [];
5097
+ return (this.state.events.length !== t.length || !this._eventsMatch(this.state.events, t)) && this.setState({ events: [...t] }, e), t;
5098
+ }
5099
+ /**
5100
+ * Check if two event arrays have the same events (by id)
5101
+ */
5102
+ _eventsMatch(e, t) {
5103
+ if (e.length !== t.length) return !1;
5104
+ const s = new Set(e.map((i) => i.id));
5105
+ return t.every((i) => s.has(i.id));
5046
5106
  }
5047
5107
  // State management
5048
5108
  getState() {
@@ -5052,11 +5112,26 @@ class J {
5052
5112
  const { silent: s = !1 } = t, i = { ...this.state };
5053
5113
  return this.state = { ...this.state, ...e }, s || (this.notifySubscribers(i, this.state), this.emitStateChange(i, this.state)), this.state;
5054
5114
  }
5055
- subscribe(e) {
5056
- return this.subscribers.add(e), () => this.unsubscribe(e);
5115
+ subscribe(e, t = null) {
5116
+ return this.subscribers.add(e), t && (this._subscriberIds || (this._subscriberIds = /* @__PURE__ */ new Map()), this._subscriberIds.set(t, e)), () => this.unsubscribe(e, t);
5117
+ }
5118
+ unsubscribe(e, t = null) {
5119
+ this.subscribers.delete(e), t && this._subscriberIds && this._subscriberIds.delete(t);
5057
5120
  }
5058
- unsubscribe(e) {
5059
- this.subscribers.delete(e);
5121
+ /**
5122
+ * Unsubscribe by subscriber ID
5123
+ * @param {string} subscriberId - ID used when subscribing
5124
+ */
5125
+ unsubscribeById(e) {
5126
+ if (!this._subscriberIds) return !1;
5127
+ const t = this._subscriberIds.get(e);
5128
+ return t ? (this.subscribers.delete(t), this._subscriberIds.delete(e), !0) : !1;
5129
+ }
5130
+ /**
5131
+ * Get subscriber count (for debugging/monitoring)
5132
+ */
5133
+ getSubscriberCount() {
5134
+ return this.subscribers.size;
5060
5135
  }
5061
5136
  notifySubscribers(e, t) {
5062
5137
  this.subscribers.forEach((s) => {
@@ -5108,29 +5183,25 @@ class J {
5108
5183
  // Event management
5109
5184
  addEvent(e) {
5110
5185
  const t = this.calendar.addEvent(e);
5111
- if (!t)
5112
- return console.error("Failed to add event to calendar"), y.emit("event:error", { action: "add", event: e, error: "Failed to add event" }), null;
5113
- const s = [...this.state.events, t];
5114
- return this.setState({ events: s }), y.emit("event:added", { event: t }), t;
5186
+ return t ? (this._syncEventsFromCore(), y.emit("event:added", { event: t }), t) : (console.error("Failed to add event to calendar"), y.emit("event:error", { action: "add", event: e, error: "Failed to add event" }), null);
5115
5187
  }
5116
5188
  updateEvent(e, t) {
5189
+ this._syncEventsFromCore({ silent: !0 });
5117
5190
  const s = this.calendar.updateEvent(e, t);
5118
- if (!s)
5119
- return console.error(`Failed to update event: ${e}`), y.emit("event:error", { action: "update", eventId: e, updates: t, error: "Event not found in calendar" }), null;
5120
- const i = this.state.events.findIndex((n) => n.id === e);
5121
- if (i === -1)
5122
- return console.error(`Event ${e} not found in state`), y.emit("event:error", { action: "update", eventId: e, error: "Event not found in state" }), null;
5123
- const r = [...this.state.events];
5124
- return r[i] = s, this.setState({ events: r }), y.emit("event:updated", { event: s }), s;
5191
+ return s ? (this._syncEventsFromCore(), y.emit("event:updated", { event: s }), s) : (console.error(`Failed to update event: ${e}`), y.emit("event:error", { action: "update", eventId: e, updates: t, error: "Event not found in calendar" }), null);
5125
5192
  }
5126
5193
  deleteEvent(e) {
5127
- if (!this.calendar.removeEvent(e))
5128
- return console.error(`Failed to delete event: ${e}`), y.emit("event:error", { action: "delete", eventId: e, error: "Event not found" }), !1;
5129
- const s = this.state.events.filter((i) => i.id !== e);
5130
- return this.setState({ events: s }), y.emit("event:deleted", { eventId: e }), !0;
5194
+ return this._syncEventsFromCore({ silent: !0 }), this.calendar.removeEvent(e) ? (this._syncEventsFromCore(), y.emit("event:deleted", { eventId: e }), !0) : (console.error(`Failed to delete event: ${e}`), y.emit("event:error", { action: "delete", eventId: e, error: "Event not found" }), !1);
5131
5195
  }
5132
5196
  getEvents() {
5133
- return this.calendar.getEvents();
5197
+ return this.calendar.getEvents() || [];
5198
+ }
5199
+ /**
5200
+ * Force sync state.events from Core calendar
5201
+ * Use this if you've modified events directly on the Core calendar
5202
+ */
5203
+ syncEvents() {
5204
+ return this._syncEventsFromCore();
5134
5205
  }
5135
5206
  getEventsForDate(e) {
5136
5207
  return this.calendar.getEventsForDate(e);
@@ -5215,7 +5286,7 @@ class J {
5215
5286
  }
5216
5287
  // Destroy
5217
5288
  destroy() {
5218
- this.subscribers.clear(), this.state = null, this.calendar = null;
5289
+ this.subscribers.clear(), this._subscriberIds && (this._subscriberIds.clear(), this._subscriberIds = null), this.state = null, this.calendar = null;
5219
5290
  }
5220
5291
  }
5221
5292
  class x extends u {
@@ -5864,7 +5935,7 @@ class v {
5864
5935
  /**
5865
5936
  * Default theme colors
5866
5937
  */
5867
- _(v, "colors", {
5938
+ I(v, "colors", {
5868
5939
  primary: "#3B82F6",
5869
5940
  // Modern Blue
5870
5941
  secondary: "#64748B",
@@ -5897,7 +5968,7 @@ _(v, "colors", {
5897
5968
  }), /**
5898
5969
  * Common CSS variables
5899
5970
  */
5900
- _(v, "cssVariables", {
5971
+ I(v, "cssVariables", {
5901
5972
  // "Pro" Palette - Functional & Sharp
5902
5973
  "--fc-primary-color": "#2563EB",
5903
5974
  // International Blue (Focus)
@@ -5965,7 +6036,7 @@ _(v, "cssVariables", {
5965
6036
  }), /**
5966
6037
  * Get responsive breakpoints
5967
6038
  */
5968
- _(v, "breakpoints", {
6039
+ I(v, "breakpoints", {
5969
6040
  xs: "320px",
5970
6041
  sm: "576px",
5971
6042
  md: "768px",
@@ -7354,9 +7425,9 @@ class se extends $ {
7354
7425
  });
7355
7426
  }), this.addListener(this, "click", (e) => {
7356
7427
  e.target === this && this.close();
7357
- }), this._handleKeyDown && window.removeEventListener("keydown", this._handleKeyDown), this._handleKeyDown = (e) => {
7428
+ }), this._keydownListenerAdded || (this._handleKeyDown = (e) => {
7358
7429
  e.key === "Escape" && this.hasAttribute("open") && this.close();
7359
- }, window.addEventListener("keydown", this._handleKeyDown);
7430
+ }, window.addEventListener("keydown", this._handleKeyDown), this._keydownListenerAdded = !0);
7360
7431
  }
7361
7432
  updateColorSelection() {
7362
7433
  this.colorContainer.querySelectorAll(".color-btn").forEach((t) => {
@@ -7391,7 +7462,7 @@ class se extends $ {
7391
7462
  return `${s}-${i}-${r}T${n}:${a}`;
7392
7463
  }
7393
7464
  unmount() {
7394
- this._cleanupFocusTrap && this._cleanupFocusTrap(), window.removeEventListener("keydown", this._handleKeyDown);
7465
+ this._cleanupFocusTrap && this._cleanupFocusTrap(), this._handleKeyDown && (window.removeEventListener("keydown", this._handleKeyDown), this._handleKeyDown = null, this._keydownListenerAdded = !1);
7395
7466
  }
7396
7467
  }
7397
7468
  customElements.get("forcecal-event-form") || customElements.define("forcecal-event-form", se);