@janus-scheduler/core 1.0.2 → 2.0.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.
Files changed (41) hide show
  1. package/LICENSE +15 -0
  2. package/README.md +94 -0
  3. package/dist/api/EventBus.d.ts +20 -0
  4. package/dist/api/EventBus.d.ts.map +1 -0
  5. package/dist/api/api.init.d.ts +3 -0
  6. package/dist/api/api.init.d.ts.map +1 -0
  7. package/dist/api/api.types.d.ts +309 -0
  8. package/dist/api/api.types.d.ts.map +1 -0
  9. package/dist/index.d.ts +16 -464
  10. package/dist/index.d.ts.map +1 -0
  11. package/dist/interactions/interactions.init.d.ts +1 -0
  12. package/dist/interactions/interactions.init.d.ts.map +1 -0
  13. package/dist/janus-scheduler.cjs +8 -0
  14. package/dist/janus-scheduler.cjs.map +1 -0
  15. package/dist/janus-scheduler.es.js +2426 -208
  16. package/dist/janus-scheduler.es.js.map +1 -1
  17. package/dist/models/assignments/assignments.d.ts +15 -0
  18. package/dist/models/assignments/assignments.d.ts.map +1 -0
  19. package/dist/models/events/event.d.ts +19 -0
  20. package/dist/models/events/event.d.ts.map +1 -0
  21. package/dist/models/resources/resources.d.ts +19 -0
  22. package/dist/models/resources/resources.d.ts.map +1 -0
  23. package/dist/rendering/rendering.init.d.ts +1 -0
  24. package/dist/rendering/rendering.init.d.ts.map +1 -0
  25. package/dist/services/SchedulerManager.service.d.ts +284 -0
  26. package/dist/services/SchedulerManager.service.d.ts.map +1 -0
  27. package/dist/store/index.d.ts +2 -0
  28. package/dist/store/index.d.ts.map +1 -0
  29. package/dist/store/scheduler.store.d.ts +45 -0
  30. package/dist/store/scheduler.store.d.ts.map +1 -0
  31. package/dist/types/event.types.d.ts +15 -0
  32. package/dist/types/event.types.d.ts.map +1 -0
  33. package/dist/utils/conflict.d.ts +54 -0
  34. package/dist/utils/conflict.d.ts.map +1 -0
  35. package/dist/utils/recurrence.d.ts +9 -0
  36. package/dist/utils/recurrence.d.ts.map +1 -0
  37. package/dist/utils/time.d.ts +42 -0
  38. package/dist/utils/time.d.ts.map +1 -0
  39. package/package.json +45 -14
  40. package/dist/janus-scheduler.cjs.js +0 -2
  41. package/dist/janus-scheduler.cjs.js.map +0 -1
@@ -0,0 +1,15 @@
1
+ export interface AssignmentData {
2
+ id: string;
3
+ eventId: string;
4
+ resourceId: string;
5
+ role?: "organizer" | "attendee";
6
+ }
7
+ export declare class Assignment {
8
+ id: string;
9
+ eventId: string;
10
+ resourceId: string;
11
+ role: "organizer" | "attendee";
12
+ constructor(data: AssignmentData);
13
+ isValid(): boolean;
14
+ }
15
+ //# sourceMappingURL=assignments.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assignments.d.ts","sourceRoot":"","sources":["../../../src/models/assignments/assignments.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,WAAW,GAAG,UAAU,CAAC;CACjC;AAED,qBAAa,UAAU;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,WAAW,GAAG,UAAU,CAAC;gBAEnB,IAAI,EAAE,cAAc;IAQhC,OAAO,IAAI,OAAO;CAGnB"}
@@ -0,0 +1,19 @@
1
+ import { EventData } from '../../types/event.types';
2
+ export declare class Event {
3
+ id: string;
4
+ title: string;
5
+ startTime: string;
6
+ endTime: string;
7
+ resourceId: string;
8
+ resourceIds: string[];
9
+ status: "draft" | "confirmed" | "cancelled";
10
+ description: string;
11
+ color?: string;
12
+ allDay?: boolean;
13
+ recurrenceRule?: string;
14
+ timezone?: string;
15
+ constructor(data: EventData);
16
+ isValid(): boolean;
17
+ getDuration(): number;
18
+ }
19
+ //# sourceMappingURL=event.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event.d.ts","sourceRoot":"","sources":["../../../src/models/events/event.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAEpD,qBAAa,KAAK;IAChB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,MAAM,EAAE,OAAO,GAAG,WAAW,GAAG,WAAW,CAAC;IAC5C,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;gBAEN,IAAI,EAAE,SAAS;IAqB3B,OAAO,IAAI,OAAO;IASlB,WAAW,IAAI,MAAM;CAKtB"}
@@ -0,0 +1,19 @@
1
+ export interface ResourceData {
2
+ id: string;
3
+ name: string;
4
+ type?: "person" | "room" | "equipment" | (string & {});
5
+ email?: string;
6
+ avatar?: string;
7
+ subtitle?: string;
8
+ }
9
+ export declare class Resource {
10
+ id: string;
11
+ name: string;
12
+ type: "person" | "room" | "equipment" | (string & {});
13
+ email: string;
14
+ avatar: string;
15
+ subtitle: string;
16
+ constructor(data: ResourceData);
17
+ isValid(): boolean;
18
+ }
19
+ //# sourceMappingURL=resources.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resources.d.ts","sourceRoot":"","sources":["../../../src/models/resources/resources.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,QAAQ,GAAG,MAAM,GAAG,WAAW,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;IACvD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,qBAAa,QAAQ;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,QAAQ,GAAG,MAAM,GAAG,WAAW,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;IACtD,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;gBAEL,IAAI,EAAE,YAAY;IAU9B,OAAO,IAAI,OAAO;CAKnB"}
@@ -0,0 +1 @@
1
+ //# sourceMappingURL=rendering.init.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rendering.init.d.ts","sourceRoot":"","sources":["../../src/rendering/rendering.init.ts"],"names":[],"mappings":""}
@@ -0,0 +1,284 @@
1
+ import { Event } from '../models/events/event';
2
+ import { Resource, ResourceData } from '../models/resources/resources';
3
+ import { Assignment, AssignmentData } from '../models/assignments/assignments';
4
+ import { EventData } from '../types/event.types';
5
+ export interface SchedulerHooks {
6
+ onEventAdd?: (event: Event) => void | Promise<void>;
7
+ onEventUpdate?: (event: Event) => void | Promise<void>;
8
+ onEventDelete?: (id: string) => void | Promise<void>;
9
+ /**
10
+ * Called once after a batch of events is added via `batchAddEvents()`.
11
+ * If omitted, individual `onEventAdd` hooks are fired for each event instead.
12
+ */
13
+ onBulkEventAdd?: (events: Event[]) => void | Promise<void>;
14
+ onResourceAdd?: (resource: Resource) => void | Promise<void>;
15
+ onResourceUpdate?: (resource: Resource) => void | Promise<void>;
16
+ onResourceDelete?: (id: string) => void | Promise<void>;
17
+ onAssignmentAdd?: (assignment: Assignment) => void | Promise<void>;
18
+ onAssignmentDelete?: (id: string) => void | Promise<void>;
19
+ /**
20
+ * Called whenever any hook fails — either throws synchronously or returns a
21
+ * rejected Promise (e.g. a failed fetch()). The store change that triggered
22
+ * the hook has already been rolled back by the time this fires, so the UI
23
+ * has reverted to the previous state.
24
+ *
25
+ * Use this hook to show an error notification to your user, e.g.:
26
+ * onError: ({ operation, error }) => toast.error(`${operation} failed: ${error.message}`)
27
+ *
28
+ * @param ctx.operation - Name of the method that failed, e.g. "addEvent"
29
+ * @param ctx.error - The raw thrown/rejected value from your hook
30
+ * @param ctx.reverted - Always true — the store was rolled back automatically
31
+ */
32
+ onError?: (ctx: {
33
+ operation: string;
34
+ error: unknown;
35
+ reverted: boolean;
36
+ }) => void;
37
+ /**
38
+ * Called whenever the undo stack's availability changes.
39
+ */
40
+ onUndoStateChange?: (canUndo: boolean) => void;
41
+ }
42
+ export interface SchedulerConfig {
43
+ /**
44
+ * Maximum number of undo actions retained in the stack.
45
+ * Older actions are discarded when this limit is exceeded.
46
+ * @default 20
47
+ */
48
+ maxUndoStackSize?: number;
49
+ }
50
+ export type UndoAction = {
51
+ type: "addEvent";
52
+ id: string;
53
+ } | {
54
+ type: "updateEvent";
55
+ id: string;
56
+ previous: Partial<EventData>;
57
+ } | {
58
+ type: "deleteEvent";
59
+ previous: EventData;
60
+ } | {
61
+ type: "batchAddEvents";
62
+ ids: string[];
63
+ };
64
+ /**
65
+ * SchedulerManager
66
+ *
67
+ * The single public API surface for reading and writing scheduler data.
68
+ * Internally it writes to the Zustand vanilla store (which drives UI reactivity)
69
+ * and then fires the matching lifecycle hook so the host application can persist
70
+ * the change to its own backend.
71
+ *
72
+ * If the async hook rejects (e.g. a network error), the store is automatically
73
+ * rolled back and `onError` is called — the host only needs to display a message.
74
+ *
75
+ * @example
76
+ * ```ts
77
+ * const manager = new SchedulerManager(
78
+ * {
79
+ * onEventAdd: async (event) => {
80
+ * await fetch('/api/events', { method: 'POST', body: JSON.stringify(event) });
81
+ * },
82
+ * onEventUpdate: async (event) => {
83
+ * await fetch(`/api/events/${event.id}`, { method: 'PATCH', body: JSON.stringify(event) });
84
+ * },
85
+ * onEventDelete: async (id) => {
86
+ * await fetch(`/api/events/${id}`, { method: 'DELETE' });
87
+ * },
88
+ * onError: ({ operation, error }) => {
89
+ * // The UI has already reverted — just show a notification
90
+ * toast.error(`"${operation}" failed. Your change has been undone.`);
91
+ * console.error(error);
92
+ * },
93
+ * },
94
+ * { maxUndoStackSize: 50 },
95
+ * );
96
+ * ```
97
+ */
98
+ export declare class SchedulerManager {
99
+ private readonly _hooks;
100
+ private readonly _config;
101
+ private _undoStack;
102
+ private _isUndoing;
103
+ private _isBatchOperation;
104
+ private readonly _undoListeners;
105
+ constructor(hooks?: SchedulerHooks, config?: SchedulerConfig);
106
+ canUndo(): boolean;
107
+ peekUndo(): UndoAction | undefined;
108
+ /**
109
+ * Subscribe to undo-stack changes. The listener fires whenever the stack
110
+ * grows or shrinks, letting UI frameworks derive `canUndo()` reactively
111
+ * (e.g. via React's `useSyncExternalStore`) instead of wiring a manual
112
+ * `onUndoStateChange` callback.
113
+ *
114
+ * @returns An unsubscribe function.
115
+ */
116
+ subscribeUndo(listener: () => void): () => void;
117
+ private _notifyUndoChanged;
118
+ undo(): void;
119
+ private _pushUndo;
120
+ /**
121
+ * Invokes an optional lifecycle hook inside a try/catch and, if it fails
122
+ * (synchronous throw OR async rejection), runs the rollback then calls onError.
123
+ *
124
+ * The hook is passed as a **thunk** (`() => hook?.()`) so that invocation
125
+ * happens inside the try block. Without this, a synchronous throw would
126
+ * escape at the call site before _fireHook was entered, bypassing rollback.
127
+ *
128
+ * @param operation - Method name shown in the error context, e.g. "addEvent"
129
+ * @param invokeHook - Zero-arg function that calls the hook and returns its result
130
+ * @param rollback - Undoes the optimistic store write
131
+ */
132
+ private _fireHook;
133
+ /**
134
+ * Optimistically adds an event to the store, then fires `onEventAdd`.
135
+ * If the hook rejects, the event is removed from the store and `onError` fires.
136
+ *
137
+ * @param data - Raw event data
138
+ * @returns The created Event instance (already visible in the UI)
139
+ */
140
+ addEvent(data: EventData): Event;
141
+ /**
142
+ * Optimistically adds multiple events to the store in a single batch.
143
+ * Fires a single `onBulkEventAdd` hook (or falls back to individual
144
+ * `onEventAdd` hooks) and pushes a single compound undo action.
145
+ *
146
+ * This avoids the N-request / N-undo-push problem when importing
147
+ * external data.
148
+ *
149
+ * @param dataArray - Array of raw event data to add
150
+ * @returns Array of created Event instances
151
+ */
152
+ batchAddEvents(dataArray: EventData[]): Event[];
153
+ /**
154
+ * Get a single event by ID.
155
+ * @param id - Event ID
156
+ * @returns Event if found, undefined otherwise
157
+ */
158
+ getEvent(id: string): Event | undefined;
159
+ /**
160
+ * Get all events currently in the store.
161
+ * @returns Array of all Event instances
162
+ */
163
+ getAllEvents(): Event[];
164
+ /**
165
+ * The IANA timezone the scheduler is currently displaying in.
166
+ * Defaults to the browser's local timezone unless changed via the store's
167
+ * `setTimezone`. Use this (not `Intl.DateTimeFormat()`) when formatting
168
+ * event times outside the scheduler components, so external UI (dialogs,
169
+ * toasts) matches the calendar display.
170
+ */
171
+ getTimezone(): string;
172
+ private _shiftParentEventTimes;
173
+ private _computeEventDelta;
174
+ /**
175
+ * Optimistically updates an event in the store, then fires `onEventUpdate`.
176
+ * If the hook rejects, the event is restored to its previous state and `onError` fires.
177
+ *
178
+ * @param id - Event ID
179
+ * @param updates - Partial event fields to update
180
+ * @returns The updated Event instance (already visible in the UI)
181
+ */
182
+ updateEvent(id: string, updates: Partial<EventData>): Event;
183
+ /**
184
+ * Optimistically deletes an event from the store, then fires `onEventDelete`.
185
+ * If the hook rejects, the event is re-added to the store and `onError` fires.
186
+ *
187
+ * @param id - Event ID
188
+ * @returns true if the event was found and deleted, false otherwise
189
+ */
190
+ deleteEvent(id: string): boolean;
191
+ /**
192
+ * Get all events assigned to a specific resource.
193
+ * @param resourceId - Resource ID
194
+ * @returns Filtered array of Event instances
195
+ */
196
+ getEventsByResource(resourceId: string): Event[];
197
+ /**
198
+ * Get all events that start on a specific calendar date.
199
+ * @param date - Date string in YYYY-MM-DD format
200
+ * @returns Filtered array of Event instances
201
+ */
202
+ getEventsByDate(date: string): Event[];
203
+ /**
204
+ * Optimistically adds a resource to the store, then fires `onResourceAdd`.
205
+ * If the hook rejects, the resource is removed from the store and `onError` fires.
206
+ *
207
+ * @param data - Raw resource data
208
+ * @returns The created Resource instance (already visible in the UI)
209
+ */
210
+ addResource(data: ResourceData): Resource;
211
+ /**
212
+ * Get a single resource by ID.
213
+ * @param id - Resource ID
214
+ * @returns Resource if found, undefined otherwise
215
+ */
216
+ getResource(id: string): Resource | undefined;
217
+ /**
218
+ * Get all resources currently in the store.
219
+ * @returns Array of all Resource instances
220
+ */
221
+ getAllResources(): Resource[];
222
+ /**
223
+ * Optimistically updates a resource in the store, then fires `onResourceUpdate`.
224
+ * If the hook rejects, the resource is restored to its previous state and `onError` fires.
225
+ *
226
+ * @param id - Resource ID
227
+ * @param updates - Partial resource fields to update
228
+ * @returns The updated Resource instance (already visible in the UI)
229
+ */
230
+ updateResource(id: string, updates: Partial<ResourceData>): Resource;
231
+ /**
232
+ * Optimistically deletes a resource from the store, then fires `onResourceDelete`.
233
+ * If the hook rejects, the resource is re-added to the store and `onError` fires.
234
+ * Will throw synchronously if the resource has assigned events (store-level guard).
235
+ *
236
+ * @param id - Resource ID
237
+ * @returns true if the resource was found and deleted
238
+ */
239
+ deleteResource(id: string): boolean;
240
+ /**
241
+ * Optimistically creates an assignment, then fires `onAssignmentAdd`.
242
+ * If the hook rejects, the assignment is deleted from the store and `onError` fires.
243
+ *
244
+ * @param data - Assignment data
245
+ * @returns The created Assignment instance (already visible in the UI)
246
+ */
247
+ addAssignment(data: AssignmentData): Assignment;
248
+ /**
249
+ * Get all assignments for a specific event.
250
+ * @param eventId - Event ID
251
+ * @returns Array of Assignment instances
252
+ */
253
+ getAssignmentsByEvent(eventId: string): Assignment[];
254
+ /**
255
+ * Get all assignments for a specific resource.
256
+ * @param resourceId - Resource ID
257
+ * @returns Array of Assignment instances
258
+ */
259
+ getAssignmentsByResource(resourceId: string): Assignment[];
260
+ /**
261
+ * Optimistically deletes an assignment, then fires `onAssignmentDelete`.
262
+ * If the hook rejects, the assignment is re-added to the store and `onError` fires.
263
+ *
264
+ * @param id - Assignment ID
265
+ * @returns true if deleted, false if not found
266
+ */
267
+ deleteAssignment(id: string): boolean;
268
+ /**
269
+ * Total number of events currently in the store.
270
+ */
271
+ getEventCount(): number;
272
+ /**
273
+ * Total number of resources currently in the store.
274
+ */
275
+ getResourceCount(): number;
276
+ /**
277
+ * Remove all events, resources, and assignments from the store.
278
+ * Does NOT fire individual delete hooks — use this only for full resets
279
+ * (e.g. on logout or when switching tenants).
280
+ */
281
+ clearAll(): void;
282
+ }
283
+ export default SchedulerManager;
284
+ //# sourceMappingURL=SchedulerManager.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SchedulerManager.service.d.ts","sourceRoot":"","sources":["../../src/services/SchedulerManager.service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export * from './scheduler.store';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/store/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC"}
@@ -0,0 +1,45 @@
1
+ import { Event } from '../models/events/event';
2
+ import { Resource, ResourceData } from '../models/resources/resources';
3
+ import { Assignment, AssignmentData } from '../models/assignments/assignments';
4
+ import { EventData } from '../types/event.types';
5
+ export interface EventDraft {
6
+ id: string | null;
7
+ title: string;
8
+ startDate: string;
9
+ startTime: string;
10
+ endDate: string;
11
+ endTime: string;
12
+ participants: string[];
13
+ description: string;
14
+ activeColor: string;
15
+ timezone: string;
16
+ allDay?: boolean;
17
+ recurrenceRule?: string;
18
+ }
19
+ export interface SchedulerState {
20
+ events: Record<string, Event>;
21
+ resources: Record<string, Resource>;
22
+ assignments: Record<string, Assignment>;
23
+ /** IANA timezone string used for all display conversions. Defaults to the browser's local timezone. */
24
+ timezone: string;
25
+ eventDraft: EventDraft | null;
26
+ }
27
+ export interface SchedulerActions {
28
+ addEvent: (data: EventData) => Event;
29
+ updateEvent: (id: string, updates: Partial<EventData>) => Event;
30
+ deleteEvent: (id: string) => boolean;
31
+ addResource: (data: ResourceData) => Resource;
32
+ updateResource: (id: string, updates: Partial<ResourceData>) => Resource;
33
+ deleteResource: (id: string) => boolean;
34
+ addAssignment: (data: AssignmentData) => Assignment;
35
+ deleteAssignment: (id: string) => boolean;
36
+ clearAll: () => void;
37
+ /** Change the display timezone for all scheduler components. */
38
+ setTimezone: (timezone: string) => void;
39
+ startDraft: (id: string | null, defaults: Partial<EventDraft>) => void;
40
+ updateDraft: (updates: Partial<EventDraft>) => void;
41
+ clearDraft: (clearLocalStorage?: boolean) => void;
42
+ }
43
+ export type SchedulerStore = SchedulerState & SchedulerActions;
44
+ export declare const schedulerStore: import('zustand/vanilla').StoreApi<SchedulerStore>;
45
+ //# sourceMappingURL=scheduler.store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scheduler.store.d.ts","sourceRoot":"","sources":["../../src/store/scheduler.store.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAC;AAC/C,OAAO,EAAE,QAAQ,EAAE,KAAK,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAC5E,OAAO,EACL,UAAU,EACV,KAAK,cAAc,EACpB,MAAM,mCAAmC,CAAC;AAC3C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAGtD,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IAC9B,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IACpC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACxC,uGAAuG;IACvG,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,UAAU,GAAG,IAAI,CAAC;CAC/B;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,KAAK,CAAC;IACrC,WAAW,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,SAAS,CAAC,KAAK,KAAK,CAAC;IAChE,WAAW,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC;IACrC,WAAW,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,QAAQ,CAAC;IAC9C,cAAc,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,YAAY,CAAC,KAAK,QAAQ,CAAC;IACzE,cAAc,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC;IACxC,aAAa,EAAE,CAAC,IAAI,EAAE,cAAc,KAAK,UAAU,CAAC;IACpD,gBAAgB,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC;IAC1C,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,gEAAgE;IAChE,WAAW,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,UAAU,EAAE,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,EAAE,QAAQ,EAAE,OAAO,CAAC,UAAU,CAAC,KAAK,IAAI,CAAC;IACvE,WAAW,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,UAAU,CAAC,KAAK,IAAI,CAAC;IACpD,UAAU,EAAE,CAAC,iBAAiB,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;CACnD;AAED,MAAM,MAAM,cAAc,GAAG,cAAc,GAAG,gBAAgB,CAAC;AAoC/D,eAAO,MAAM,cAAc,oDA+NxB,CAAC"}
@@ -0,0 +1,15 @@
1
+ export interface EventData {
2
+ id: string;
3
+ title: string;
4
+ startTime: string;
5
+ endTime: string;
6
+ resourceId?: string;
7
+ resourceIds?: string[];
8
+ status?: "draft" | "confirmed" | "cancelled";
9
+ description?: string;
10
+ color?: string;
11
+ allDay?: boolean;
12
+ recurrenceRule?: string;
13
+ timezone?: string;
14
+ }
15
+ //# sourceMappingURL=event.types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event.types.d.ts","sourceRoot":"","sources":["../../src/types/event.types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,MAAM,CAAC,EAAE,OAAO,GAAG,WAAW,GAAG,WAAW,CAAC;IAC7C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB"}
@@ -0,0 +1,54 @@
1
+ import { Event } from '../models/events/event';
2
+ export interface ConflictEvent {
3
+ id: string;
4
+ title: string;
5
+ startMs: number;
6
+ endMs: number;
7
+ startTime: string;
8
+ endTime: string;
9
+ }
10
+ export interface ConflictResource {
11
+ id: string;
12
+ name: string;
13
+ events: ConflictEvent[];
14
+ }
15
+ /**
16
+ * Perform a sorting sweep to find all overlapping events on a single resource.
17
+ * Returns timezone-aware overlap warning messages and the set of conflicting event IDs for this resource.
18
+ */
19
+ export declare function computeSingleResourceConflicts(resource: ConflictResource, timezone: string, maxMessages?: number): {
20
+ conflictingEventIds: Set<string>;
21
+ messages: string[];
22
+ };
23
+ /**
24
+ * Perform an O(N log N) sorting sweep to find all overlapping events on each resource.
25
+ * Returns timezone-aware overlap warning messages and the set of conflicting event IDs.
26
+ */
27
+ export declare function computeTimelineConflicts(resources: ConflictResource[], timezone: string): {
28
+ hasConflict: boolean;
29
+ messages: string[];
30
+ conflictingEventIds: Set<string>;
31
+ };
32
+ /**
33
+ * Checks if a single start/end time range overlaps with existing events on a resource.
34
+ */
35
+ export declare function checkSlotConflict(events: ConflictEvent[], startMs: number, endMs: number, ignoreEventId?: string): boolean;
36
+ /**
37
+ * Validate conflicts for a recurring/single event draft.
38
+ */
39
+ export declare function checkDraftConflict(draft: {
40
+ id: string | null;
41
+ title: string;
42
+ startDate: string;
43
+ startTime: string;
44
+ endDate: string;
45
+ endTime: string;
46
+ participants: string[];
47
+ allDay?: boolean;
48
+ recurrenceRule?: string;
49
+ }, existingEvents: Event[], timezone: string): {
50
+ hasConflict: boolean;
51
+ message: string;
52
+ resourceIds: string[];
53
+ };
54
+ //# sourceMappingURL=conflict.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"conflict.d.ts","sourceRoot":"","sources":["../../src/utils/conflict.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAC;AAK/C,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,aAAa,EAAE,CAAC;CACzB;AAED;;;GAGG;AACH,wBAAgB,8BAA8B,CAC5C,QAAQ,EAAE,gBAAgB,EAC1B,QAAQ,EAAE,MAAM,EAChB,WAAW,SAAK,GACf;IACD,mBAAmB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACjC,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB,CA6CA;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CACtC,SAAS,EAAE,gBAAgB,EAAE,EAC7B,QAAQ,EAAE,MAAM,GACf;IACD,WAAW,EAAE,OAAO,CAAC;IACrB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,mBAAmB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CAClC,CAgCA;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,aAAa,EAAE,EACvB,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,EACb,aAAa,CAAC,EAAE,MAAM,GACrB,OAAO,CAYT;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE;IACL,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,EACD,cAAc,EAAE,KAAK,EAAE,EACvB,QAAQ,EAAE,MAAM,GACf;IAAE,WAAW,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,EAAE,CAAA;CAAE,CAkGlE"}
@@ -0,0 +1,9 @@
1
+ import { Event } from '../models/events/event';
2
+ import { EventData } from '../types/event.types';
3
+ /**
4
+ * Expands a list of events, producing virtual occurrence event records for any recurring event.
5
+ * Non-recurring events are passed through unmodified.
6
+ * For recurring events, the base event is omitted and replaced by occurrences within the specified range.
7
+ */
8
+ export declare function expandEvents(events: Event[], startMs: number, endMs: number): EventData[];
9
+ //# sourceMappingURL=recurrence.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recurrence.d.ts","sourceRoot":"","sources":["../../src/utils/recurrence.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAC;AAC/C,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAEjD;;;;GAIG;AACH,wBAAgB,YAAY,CAC1B,MAAM,EAAE,KAAK,EAAE,EACf,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,GACZ,SAAS,EAAE,CA4Eb"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * time.ts
3
+ *
4
+ * Timezone-aware date/time utilities for the Janus Scheduler.
5
+ * All functions use the native Intl API — no external dependencies.
6
+ */
7
+ /** Get the browser's IANA timezone string (e.g. "Asia/Kolkata"). */
8
+ export declare function getBrowserTimezone(): string;
9
+ /**
10
+ * Convert a UTC ISO string → { date, time } displayed in the given IANA timezone.
11
+ * date: "YYYY-MM-DD" | time: "HH:MM" (24-hour)
12
+ */
13
+ export declare function isoToZonedDisplay(iso: string, timezone: string): {
14
+ date: string;
15
+ time: string;
16
+ };
17
+ /**
18
+ * Get the UTC milliseconds for a date+time string interpreted in the given IANA timezone.
19
+ * date: "YYYY-MM-DD" | time: "HH:MM"
20
+ */
21
+ export declare function getUtcMsForZonedDatetime(date: string, time: string, timezone: string): number;
22
+ /**
23
+ * Convert a user-entered date+time (in the given timezone) → UTC ISO string.
24
+ * date: "YYYY-MM-DD" | time: "HH:MM"
25
+ */
26
+ export declare function zonedInputToISO(date: string, time: string, timezone: string): string;
27
+ /**
28
+ * Return a "fake" local Date whose local-time getters reflect the given timezone.
29
+ * Used to pass to existing formatter functions that call getHours(), getDay(), etc.
30
+ */
31
+ export declare function toFakeLocalDate(tsMs: number, timezone: string): Date;
32
+ /**
33
+ * Human-readable label for a timezone including its UTC offset.
34
+ * e.g. "Asia/Kolkata (UTC+5:30)"
35
+ */
36
+ export declare function formatTimezoneLabel(tz: string): string;
37
+ /**
38
+ * All IANA timezone strings supported by the browser.
39
+ * Falls back to a curated list when Intl.supportedValuesOf is unavailable.
40
+ */
41
+ export declare function getAllTimezones(): string[];
42
+ //# sourceMappingURL=time.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"time.d.ts","sourceRoot":"","sources":["../../src/utils/time.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,oEAAoE;AACpE,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C;AAmDD;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,MAAM,GACf;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAoChC;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,GACf,MAAM,CA8CR;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,GACf,MAAM,CAER;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CA2BpE;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAkBtD;AAED;;;GAGG;AACH,wBAAgB,eAAe,IAAI,MAAM,EAAE,CAO1C"}
package/package.json CHANGED
@@ -1,34 +1,65 @@
1
1
  {
2
2
  "name": "@janus-scheduler/core",
3
- "version": "1.0.2",
3
+ "version": "2.0.0",
4
+ "description": "Framework-agnostic scheduling engine for Janus Scheduler — Zustand state store, domain models, conflict detection, recurrence expansion and timezone utilities.",
5
+ "keywords": [
6
+ "scheduler",
7
+ "calendar",
8
+ "timeline",
9
+ "events",
10
+ "scheduling",
11
+ "zustand",
12
+ "state-management",
13
+ "conflict-detection",
14
+ "recurrence",
15
+ "rrule"
16
+ ],
17
+ "license": "ISC",
18
+ "author": "janus-scheduler-app",
19
+ "homepage": "https://github.com/Janus-scheduler/main-program#readme",
20
+ "repository": {
21
+ "type": "git",
22
+ "url": "git+https://github.com/Janus-scheduler/main-program.git",
23
+ "directory": "packages/core"
24
+ },
25
+ "bugs": {
26
+ "url": "https://github.com/Janus-scheduler/main-program/issues"
27
+ },
4
28
  "type": "module",
5
- "main": "./dist/janus-scheduler.cjs.js",
29
+ "sideEffects": false,
30
+ "main": "./dist/janus-scheduler.cjs",
6
31
  "module": "./dist/janus-scheduler.es.js",
7
32
  "types": "./dist/index.d.ts",
8
33
  "exports": {
9
34
  ".": {
10
35
  "types": "./dist/index.d.ts",
11
36
  "import": "./dist/janus-scheduler.es.js",
12
- "require": "./dist/janus-scheduler.cjs.js"
37
+ "require": "./dist/janus-scheduler.cjs"
13
38
  }
14
39
  },
15
40
  "files": [
16
- "dist"
41
+ "dist",
42
+ "LICENSE",
43
+ "README.md"
17
44
  ],
18
45
  "directories": {
19
46
  "test": "tests"
20
47
  },
48
+ "engines": {
49
+ "node": ">=18"
50
+ },
21
51
  "scripts": {
22
- "test": "jest --coverage",
23
- "build": "vite build"
52
+ "test": "npm run typecheck && jest --coverage",
53
+ "build": "vite build",
54
+ "typecheck": "tsc -p tsconfig.tests.json",
55
+ "prepublishOnly": "npm run build"
56
+ },
57
+ "dependencies": {
58
+ "rrule": "^2.8.1",
59
+ "zustand": "^5.0.12"
24
60
  },
25
- "keywords": [
26
- "schedule-core"
27
- ],
28
- "author": "janus-scheduler-app",
29
- "license": "ISC",
30
- "description": "",
31
61
  "devDependencies": {
62
+ "@janus-scheduler/nlp": "^2.0.0",
32
63
  "@types/jest": "^30.0.0",
33
64
  "@types/node": "^25.2.3",
34
65
  "jest": "^30.2.0",
@@ -36,7 +67,7 @@
36
67
  "vite": "^7.3.1",
37
68
  "vite-plugin-dts": "^4.5.4"
38
69
  },
39
- "dependencies": {
40
- "zustand": "^5.0.12"
70
+ "publishConfig": {
71
+ "access": "public"
41
72
  }
42
73
  }