@forcecalendar/interface 1.0.15 → 1.0.16
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/package.json
CHANGED
package/src/core/StateManager.js
CHANGED
|
@@ -39,6 +39,32 @@ class StateManager {
|
|
|
39
39
|
this.subscribe = this.subscribe.bind(this);
|
|
40
40
|
this.unsubscribe = this.unsubscribe.bind(this);
|
|
41
41
|
this.setState = this.setState.bind(this);
|
|
42
|
+
|
|
43
|
+
// Initial sync of events from Core (in case events were pre-loaded)
|
|
44
|
+
this._syncEventsFromCore({ silent: true });
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Sync state.events from Core calendar (single source of truth)
|
|
49
|
+
* This ensures state.events always matches Core's event store
|
|
50
|
+
*/
|
|
51
|
+
_syncEventsFromCore(options = {}) {
|
|
52
|
+
const coreEvents = this.calendar.getEvents() || [];
|
|
53
|
+
// Only update if different to avoid unnecessary re-renders
|
|
54
|
+
if (this.state.events.length !== coreEvents.length ||
|
|
55
|
+
!this._eventsMatch(this.state.events, coreEvents)) {
|
|
56
|
+
this.setState({ events: [...coreEvents] }, options);
|
|
57
|
+
}
|
|
58
|
+
return coreEvents;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Check if two event arrays have the same events (by id)
|
|
63
|
+
*/
|
|
64
|
+
_eventsMatch(arr1, arr2) {
|
|
65
|
+
if (arr1.length !== arr2.length) return false;
|
|
66
|
+
const ids1 = new Set(arr1.map(e => e.id));
|
|
67
|
+
return arr2.every(e => ids1.has(e.id));
|
|
42
68
|
}
|
|
43
69
|
|
|
44
70
|
// State management
|
|
@@ -150,14 +176,16 @@ class StateManager {
|
|
|
150
176
|
eventBus.emit('event:error', { action: 'add', event, error: 'Failed to add event' });
|
|
151
177
|
return null;
|
|
152
178
|
}
|
|
153
|
-
//
|
|
154
|
-
|
|
155
|
-
this.setState({ events: newEvents });
|
|
179
|
+
// Sync from Core to ensure consistency (single source of truth)
|
|
180
|
+
this._syncEventsFromCore();
|
|
156
181
|
eventBus.emit('event:added', { event: addedEvent });
|
|
157
182
|
return addedEvent;
|
|
158
183
|
}
|
|
159
184
|
|
|
160
185
|
updateEvent(eventId, updates) {
|
|
186
|
+
// First, ensure state is in sync with Core (recover from any prior desync)
|
|
187
|
+
this._syncEventsFromCore({ silent: true });
|
|
188
|
+
|
|
161
189
|
const event = this.calendar.updateEvent(eventId, updates);
|
|
162
190
|
if (!event) {
|
|
163
191
|
console.error(`Failed to update event: ${eventId}`);
|
|
@@ -165,37 +193,39 @@ class StateManager {
|
|
|
165
193
|
return null;
|
|
166
194
|
}
|
|
167
195
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
console.error(`Event ${eventId} not found in state`);
|
|
171
|
-
eventBus.emit('event:error', { action: 'update', eventId, error: 'Event not found in state' });
|
|
172
|
-
return null;
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
// Create new array to avoid mutation before setState
|
|
176
|
-
const newEvents = [...this.state.events];
|
|
177
|
-
newEvents[index] = event;
|
|
178
|
-
this.setState({ events: newEvents });
|
|
196
|
+
// Sync from Core to ensure consistency (single source of truth)
|
|
197
|
+
this._syncEventsFromCore();
|
|
179
198
|
eventBus.emit('event:updated', { event });
|
|
180
199
|
return event;
|
|
181
200
|
}
|
|
182
201
|
|
|
183
202
|
deleteEvent(eventId) {
|
|
203
|
+
// First, ensure state is in sync with Core (recover from any prior desync)
|
|
204
|
+
this._syncEventsFromCore({ silent: true });
|
|
205
|
+
|
|
184
206
|
const deleted = this.calendar.removeEvent(eventId);
|
|
185
207
|
if (!deleted) {
|
|
186
208
|
console.error(`Failed to delete event: ${eventId}`);
|
|
187
209
|
eventBus.emit('event:error', { action: 'delete', eventId, error: 'Event not found' });
|
|
188
210
|
return false;
|
|
189
211
|
}
|
|
190
|
-
//
|
|
191
|
-
|
|
192
|
-
this.setState({ events: newEvents });
|
|
212
|
+
// Sync from Core to ensure consistency (single source of truth)
|
|
213
|
+
this._syncEventsFromCore();
|
|
193
214
|
eventBus.emit('event:deleted', { eventId });
|
|
194
215
|
return true;
|
|
195
216
|
}
|
|
196
217
|
|
|
197
218
|
getEvents() {
|
|
198
|
-
|
|
219
|
+
// Return from Core (source of truth)
|
|
220
|
+
return this.calendar.getEvents() || [];
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Force sync state.events from Core calendar
|
|
225
|
+
* Use this if you've modified events directly on the Core calendar
|
|
226
|
+
*/
|
|
227
|
+
syncEvents() {
|
|
228
|
+
return this._syncEventsFromCore();
|
|
199
229
|
}
|
|
200
230
|
|
|
201
231
|
getEventsForDate(date) {
|