@neo-reckoning/core 0.1.0-alpha.1
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/dist/displayType.d.ts +9 -0
- package/dist/displayType.d.ts.map +1 -0
- package/dist/displayType.js +23 -0
- package/dist/displayType.js.map +1 -0
- package/dist/evaluator.d.ts +86 -0
- package/dist/evaluator.d.ts.map +1 -0
- package/dist/evaluator.js +608 -0
- package/dist/evaluator.js.map +1 -0
- package/dist/events.d.ts +10 -0
- package/dist/events.d.ts.map +1 -0
- package/dist/events.js +28 -0
- package/dist/events.js.map +1 -0
- package/dist/grid.d.ts +36 -0
- package/dist/grid.d.ts.map +1 -0
- package/dist/grid.js +177 -0
- package/dist/grid.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -0
- package/dist/scoring.d.ts +14 -0
- package/dist/scoring.d.ts.map +1 -0
- package/dist/scoring.js +152 -0
- package/dist/scoring.js.map +1 -0
- package/dist/time.d.ts +58 -0
- package/dist/time.d.ts.map +1 -0
- package/dist/time.js +169 -0
- package/dist/time.js.map +1 -0
- package/dist/timeline.d.ts +24 -0
- package/dist/timeline.d.ts.map +1 -0
- package/dist/timeline.js +158 -0
- package/dist/timeline.js.map +1 -0
- package/dist/types.d.ts +349 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/yearGrid.d.ts +16 -0
- package/dist/yearGrid.d.ts.map +1 -0
- package/dist/yearGrid.js +61 -0
- package/dist/yearGrid.js.map +1 -0
- package/package.json +29 -0
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,349 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* View fidelity level — controls how much detail CalendarGrid computes per day.
|
|
3
|
+
* - 'year': only hasActivity boolean (skip ranges[], timeSlots[])
|
|
4
|
+
* - 'month': ranges[] populated (skip timeSlots[])
|
|
5
|
+
* - 'week' / 'day': both ranges[] and timeSlots[] populated
|
|
6
|
+
*/
|
|
7
|
+
export type ViewFidelity = 'year' | 'month' | 'week' | 'day';
|
|
8
|
+
/**
|
|
9
|
+
* Display type hint — passed through from the API for the SPA to interpret.
|
|
10
|
+
*/
|
|
11
|
+
export type DisplayType = 'auto' | 'span' | 'dot' | 'fill' | 'chip' | 'block';
|
|
12
|
+
/**
|
|
13
|
+
* A DateRange defines a set of dates and/or times using either explicit values
|
|
14
|
+
* or recurrence patterns. This is the core data model of neo-reckoning,
|
|
15
|
+
* carried forward from the original Reckoning library and extended with
|
|
16
|
+
* sub-day time support.
|
|
17
|
+
*/
|
|
18
|
+
export interface DateRange {
|
|
19
|
+
id: string;
|
|
20
|
+
label: string;
|
|
21
|
+
title?: string;
|
|
22
|
+
/** Explicit date list, e.g. ["2026-03-21", "2026-03-25"] */
|
|
23
|
+
dates?: string[];
|
|
24
|
+
/** Range start date (YYYY-MM-DD) */
|
|
25
|
+
fromDate?: string;
|
|
26
|
+
/** Range end date (YYYY-MM-DD) */
|
|
27
|
+
toDate?: string;
|
|
28
|
+
/** If true, recurrence is constrained to the fromDate/toDate window */
|
|
29
|
+
fixedBetween?: boolean;
|
|
30
|
+
/** Days of month this range recurs on, e.g. [1, 15] */
|
|
31
|
+
everyDate?: number[];
|
|
32
|
+
/** Days of week (0=Sunday, 6=Saturday), e.g. [1, 3, 5] for Mon/Wed/Fri */
|
|
33
|
+
everyWeekday?: number[];
|
|
34
|
+
/** Months (1-12), e.g. [6, 12] for June and December */
|
|
35
|
+
everyMonth?: number[];
|
|
36
|
+
/** Specific hours (0-23), e.g. [6, 14, 22]. Mutually exclusive with startTime/repeatEvery. */
|
|
37
|
+
everyHour?: number[];
|
|
38
|
+
/** Start time in HH:mm format. Mutually exclusive with everyHour. */
|
|
39
|
+
startTime?: string;
|
|
40
|
+
/** End time in HH:mm format. Requires startTime. */
|
|
41
|
+
endTime?: string;
|
|
42
|
+
/** Repeat interval in minutes from startTime. Requires startTime. */
|
|
43
|
+
repeatEvery?: number;
|
|
44
|
+
/** Duration in minutes per occurrence. */
|
|
45
|
+
duration?: number;
|
|
46
|
+
/**
|
|
47
|
+
* IANA timezone identifier.
|
|
48
|
+
* - "UTC": times are in UTC, will be converted to userTimezone for display (default for API ranges)
|
|
49
|
+
* - Other IANA tz: times are in that timezone, converted to userTimezone
|
|
50
|
+
* - null/undefined: floating time — no conversion, times are as-is
|
|
51
|
+
*/
|
|
52
|
+
timezone?: string | null;
|
|
53
|
+
/** Display hint from the API. Neo-reckoning passes this through, SPA interprets it. */
|
|
54
|
+
displayType?: DisplayType;
|
|
55
|
+
/**
|
|
56
|
+
* Flexibility score (0-5). 0=locked, 1-5=increasingly flexible.
|
|
57
|
+
* Neo-reckoning passes this through — agent-facing code interprets it.
|
|
58
|
+
*/
|
|
59
|
+
flexibility?: number;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* A concrete occurrence of a DateRange — one specific date/time that the range
|
|
63
|
+
* evaluates to within a given window.
|
|
64
|
+
*/
|
|
65
|
+
export interface Occurrence {
|
|
66
|
+
/** Date in YYYY-MM-DD format */
|
|
67
|
+
date: string;
|
|
68
|
+
/** Start time in HH:mm format, null for all-day */
|
|
69
|
+
startTime: string | null;
|
|
70
|
+
/** End time in HH:mm format, null for all-day or when no end is defined */
|
|
71
|
+
endTime: string | null;
|
|
72
|
+
/** ID of the source DateRange */
|
|
73
|
+
rangeId: string;
|
|
74
|
+
/** Label from the source DateRange */
|
|
75
|
+
label: string;
|
|
76
|
+
/** Whether this is an all-day occurrence (no time fields) */
|
|
77
|
+
allDay: boolean;
|
|
78
|
+
/** Display type hint passed through from the source DateRange */
|
|
79
|
+
displayType?: string;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* A free (unoccupied) time slot within a single day.
|
|
83
|
+
* Produced by RangeEvaluator.findFreeSlots().
|
|
84
|
+
*/
|
|
85
|
+
export interface FreeSlot {
|
|
86
|
+
/** Date in YYYY-MM-DD format */
|
|
87
|
+
date: string;
|
|
88
|
+
/** Start time in HH:mm format */
|
|
89
|
+
startTime: string;
|
|
90
|
+
/** End time in HH:mm format */
|
|
91
|
+
endTime: string;
|
|
92
|
+
/** Duration in minutes */
|
|
93
|
+
duration: number;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* A time slot within a single day — used for day/week detail views.
|
|
97
|
+
*/
|
|
98
|
+
export interface TimeSlot {
|
|
99
|
+
/** Start time in HH:mm format */
|
|
100
|
+
startTime: string;
|
|
101
|
+
/** End time in HH:mm format, null if open-ended */
|
|
102
|
+
endTime: string | null;
|
|
103
|
+
/** Duration in minutes, null if not computable */
|
|
104
|
+
duration: number | null;
|
|
105
|
+
/** ID of the source DateRange */
|
|
106
|
+
rangeId: string;
|
|
107
|
+
/** Label from the source DateRange */
|
|
108
|
+
label: string;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Information about a DateRange's presence on a specific day — used for
|
|
112
|
+
* month-grid rendering to show contiguous spans.
|
|
113
|
+
*/
|
|
114
|
+
export interface DayRangeInfo {
|
|
115
|
+
/** ID of the source DateRange */
|
|
116
|
+
rangeId: string;
|
|
117
|
+
/** Label from the source DateRange */
|
|
118
|
+
label: string;
|
|
119
|
+
/** True if this is the first day of a contiguous span */
|
|
120
|
+
isStart: boolean;
|
|
121
|
+
/** True if this is the last day of a contiguous span */
|
|
122
|
+
isEnd: boolean;
|
|
123
|
+
/** True if this day is in the middle of a contiguous span */
|
|
124
|
+
isContinuation: boolean;
|
|
125
|
+
/** Display type hint passed through from the source DateRange */
|
|
126
|
+
displayType?: string;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Information about a contiguous span of days for a DateRange within a window.
|
|
130
|
+
* Used for overlap detection and lane-based rendering in month/timeline views.
|
|
131
|
+
*/
|
|
132
|
+
export interface SpanInfo {
|
|
133
|
+
/** ID of the source DateRange */
|
|
134
|
+
rangeId: string;
|
|
135
|
+
/** Label from the source DateRange */
|
|
136
|
+
label: string;
|
|
137
|
+
/** Display type hint passed through from the DateRange */
|
|
138
|
+
displayType?: string;
|
|
139
|
+
/** First day of this contiguous span (YYYY-MM-DD) */
|
|
140
|
+
startDate: string;
|
|
141
|
+
/** Last day of this contiguous span (YYYY-MM-DD) */
|
|
142
|
+
endDate: string;
|
|
143
|
+
/** Total days in this span */
|
|
144
|
+
length: number;
|
|
145
|
+
/** Maximum number of overlapping ranges at any point in this span */
|
|
146
|
+
maxOverlap: number;
|
|
147
|
+
/** Consistent lane assignment for rendering (0-based) */
|
|
148
|
+
lane: number;
|
|
149
|
+
/** Total number of lanes needed across all spans sharing any overlap day with this span */
|
|
150
|
+
totalLanes: number;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* A single day in a calendar grid.
|
|
154
|
+
*/
|
|
155
|
+
export interface Day {
|
|
156
|
+
/** Date in YYYY-MM-DD format */
|
|
157
|
+
date: string;
|
|
158
|
+
/** Day of month (1-31) */
|
|
159
|
+
dayOfMonth: number;
|
|
160
|
+
/** Whether this day belongs to the month being displayed */
|
|
161
|
+
isCurrentMonth: boolean;
|
|
162
|
+
/** Whether this is today */
|
|
163
|
+
isToday: boolean;
|
|
164
|
+
/** Which ranges this day belongs to */
|
|
165
|
+
ranges: DayRangeInfo[];
|
|
166
|
+
/** Sub-day occurrences, populated for day/week views */
|
|
167
|
+
timeSlots: TimeSlot[];
|
|
168
|
+
/** True if any range matches this day. Only computed for 'year' fidelity to save work. */
|
|
169
|
+
hasActivity?: boolean;
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* A week in a calendar grid — always 7 days.
|
|
173
|
+
*/
|
|
174
|
+
export interface Week {
|
|
175
|
+
days: Day[];
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* A month in a calendar grid.
|
|
179
|
+
*/
|
|
180
|
+
export interface Month {
|
|
181
|
+
year: number;
|
|
182
|
+
/** Month number (0-11, matching JS Date convention) */
|
|
183
|
+
month: number;
|
|
184
|
+
/** Formatted label, e.g. "March 2026" */
|
|
185
|
+
label: string;
|
|
186
|
+
weeks: Week[];
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Normalized event model — the single shape consumed by the rendering layer.
|
|
190
|
+
* Both native DateRanges and imported .ics events converge into this.
|
|
191
|
+
*/
|
|
192
|
+
export interface CalendarEvent {
|
|
193
|
+
id: string;
|
|
194
|
+
title: string;
|
|
195
|
+
start: Date;
|
|
196
|
+
end: Date | null;
|
|
197
|
+
allDay: boolean;
|
|
198
|
+
source: 'native' | 'imported';
|
|
199
|
+
/** Range ID (native) or subscription ID (imported) — SPA maps this to colors */
|
|
200
|
+
sourceId: string;
|
|
201
|
+
editable: boolean;
|
|
202
|
+
/** Source-specific extras (location, description, etc.) */
|
|
203
|
+
metadata?: Record<string, unknown>;
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* A positioned event in a timeline view — includes layout data for rendering.
|
|
207
|
+
*/
|
|
208
|
+
export interface PositionedEvent {
|
|
209
|
+
event: CalendarEvent;
|
|
210
|
+
/** Percentage offset from the timeline start (0-100) */
|
|
211
|
+
top: number;
|
|
212
|
+
/** Percentage height based on duration (0-100) */
|
|
213
|
+
height: number;
|
|
214
|
+
/** Column index for side-by-side overlapping events (0-based) */
|
|
215
|
+
column: number;
|
|
216
|
+
/** Total number of columns at this overlap point */
|
|
217
|
+
totalColumns: number;
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* A slot in a timeline view.
|
|
221
|
+
*/
|
|
222
|
+
export interface TimelineSlot {
|
|
223
|
+
/** Time label, e.g. "06:00" */
|
|
224
|
+
time: string;
|
|
225
|
+
hour: number;
|
|
226
|
+
minute: number;
|
|
227
|
+
/** Events that overlap this slot */
|
|
228
|
+
events: PositionedEvent[];
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Configuration for CalendarGrid.
|
|
232
|
+
*/
|
|
233
|
+
export interface CalendarGridConfig {
|
|
234
|
+
/** Center the grid on this date (YYYY-MM-DD) */
|
|
235
|
+
focusDate: string;
|
|
236
|
+
/** How many months to generate */
|
|
237
|
+
numberOfMonths: number;
|
|
238
|
+
/** DateRanges to evaluate against the grid */
|
|
239
|
+
ranges: DateRange[];
|
|
240
|
+
/** Week start day: 0=Sunday, 1=Monday. Default: 0 */
|
|
241
|
+
weekStartsOn?: number;
|
|
242
|
+
/** BCP 47 locale tag for Intl formatting. Default: browser/runtime default */
|
|
243
|
+
locale?: string;
|
|
244
|
+
/** IANA timezone for the user viewing the calendar */
|
|
245
|
+
userTimezone?: string;
|
|
246
|
+
/** View fidelity level — controls how much detail is computed per day. Default: 'month' */
|
|
247
|
+
fidelity?: ViewFidelity;
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Configuration for TimelineGrid.
|
|
251
|
+
*/
|
|
252
|
+
export interface TimelineGridConfig {
|
|
253
|
+
/** Which day to render (YYYY-MM-DD) */
|
|
254
|
+
date: string;
|
|
255
|
+
/** Start hour of the timeline (0-23). Default: 0 */
|
|
256
|
+
startHour?: number;
|
|
257
|
+
/** End hour of the timeline (1-24). Default: 24 */
|
|
258
|
+
endHour?: number;
|
|
259
|
+
/** Slot granularity in minutes: 15, 30, or 60. Default: 60 */
|
|
260
|
+
intervalMinutes?: number;
|
|
261
|
+
/** Normalized events for this day */
|
|
262
|
+
events: CalendarEvent[];
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* Pluggable cache adapter for @neo-reckoning/ical.
|
|
266
|
+
* Supports both sync (web localStorage) and async (React Native AsyncStorage) implementations.
|
|
267
|
+
*/
|
|
268
|
+
export interface CacheAdapter {
|
|
269
|
+
get(key: string): Promise<string | null> | string | null;
|
|
270
|
+
set(key: string, value: string): Promise<void> | void;
|
|
271
|
+
remove(key: string): Promise<void> | void;
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* Configuration for YearGrid.
|
|
275
|
+
*/
|
|
276
|
+
export interface YearGridConfig {
|
|
277
|
+
/** The year to generate (e.g. 2026) */
|
|
278
|
+
year: number;
|
|
279
|
+
/** DateRanges to evaluate against the grid */
|
|
280
|
+
ranges: DateRange[];
|
|
281
|
+
/** IANA timezone for the user viewing the calendar */
|
|
282
|
+
userTimezone?: string;
|
|
283
|
+
}
|
|
284
|
+
/**
|
|
285
|
+
* A month within a year grid — lightweight, no weeks/time slots.
|
|
286
|
+
*/
|
|
287
|
+
export interface YearMonth {
|
|
288
|
+
/** Month number (0-11) */
|
|
289
|
+
month: number;
|
|
290
|
+
/** Month label, e.g. "January" */
|
|
291
|
+
label: string;
|
|
292
|
+
/** Count of days that have at least one range match */
|
|
293
|
+
activeDays: number;
|
|
294
|
+
/** Total days in the month */
|
|
295
|
+
totalDays: number;
|
|
296
|
+
/** Per-day activity data for heatmap-style rendering */
|
|
297
|
+
days: YearDay[];
|
|
298
|
+
}
|
|
299
|
+
/**
|
|
300
|
+
* A single day in a year grid.
|
|
301
|
+
*/
|
|
302
|
+
export interface YearDay {
|
|
303
|
+
/** Date in YYYY-MM-DD format */
|
|
304
|
+
date: string;
|
|
305
|
+
/** Day of month (1-31) */
|
|
306
|
+
dayOfMonth: number;
|
|
307
|
+
/** How many ranges match this day */
|
|
308
|
+
rangeCount: number;
|
|
309
|
+
/** IDs of matching ranges (SPA maps these to colors) */
|
|
310
|
+
rangeIds: string[];
|
|
311
|
+
}
|
|
312
|
+
/**
|
|
313
|
+
* Score summarising the quality of a schedule across a date window.
|
|
314
|
+
*/
|
|
315
|
+
export interface ScheduleScore {
|
|
316
|
+
/** Total conflicts across the window */
|
|
317
|
+
conflicts: number;
|
|
318
|
+
/** Total minutes of free time within working hours across the window */
|
|
319
|
+
freeMinutes: number;
|
|
320
|
+
/** Number of uninterrupted focus blocks >= focusBlockMinutes */
|
|
321
|
+
focusBlocks: number;
|
|
322
|
+
/** Number of context switches (transitions between different ranges) per day, averaged */
|
|
323
|
+
avgContextSwitches: number;
|
|
324
|
+
/** Total days with at least one conflict */
|
|
325
|
+
conflictDays: number;
|
|
326
|
+
}
|
|
327
|
+
/**
|
|
328
|
+
* A time-level conflict between two ranges on a specific date.
|
|
329
|
+
* Only timed ranges can conflict — two all-day ranges stack, they don't conflict.
|
|
330
|
+
*/
|
|
331
|
+
export interface Conflict {
|
|
332
|
+
/** First conflicting range */
|
|
333
|
+
rangeA: {
|
|
334
|
+
id: string;
|
|
335
|
+
label: string;
|
|
336
|
+
};
|
|
337
|
+
/** Second conflicting range */
|
|
338
|
+
rangeB: {
|
|
339
|
+
id: string;
|
|
340
|
+
label: string;
|
|
341
|
+
};
|
|
342
|
+
/** Date of the conflict (YYYY-MM-DD) */
|
|
343
|
+
date: string;
|
|
344
|
+
/** Start of the overlap window (HH:mm), null for all-day */
|
|
345
|
+
overlapStart: string | null;
|
|
346
|
+
/** End of the overlap window (HH:mm), null for all-day */
|
|
347
|
+
overlapEnd: string | null;
|
|
348
|
+
}
|
|
349
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { YearGridConfig, YearMonth } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* YearGrid — lightweight year-level grid for heatmap-style rendering.
|
|
4
|
+
* No weeks, no time slots, no span tracking — just per-day activity data.
|
|
5
|
+
*/
|
|
6
|
+
export declare class YearGrid {
|
|
7
|
+
months: YearMonth[];
|
|
8
|
+
private year;
|
|
9
|
+
private ranges;
|
|
10
|
+
private evaluator;
|
|
11
|
+
constructor(config: YearGridConfig);
|
|
12
|
+
private generate;
|
|
13
|
+
private generateMonth;
|
|
14
|
+
private formatMonthLabel;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=yearGrid.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"yearGrid.d.ts","sourceRoot":"","sources":["../src/yearGrid.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,cAAc,EACd,SAAS,EAEV,MAAM,YAAY,CAAC;AAIpB;;;GAGG;AACH,qBAAa,QAAQ;IACnB,MAAM,EAAE,SAAS,EAAE,CAAC;IAEpB,OAAO,CAAC,IAAI,CAAS;IACrB,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,SAAS,CAAiB;gBAEtB,MAAM,EAAE,cAAc;IAOlC,OAAO,CAAC,QAAQ;IAUhB,OAAO,CAAC,aAAa;IAqCrB,OAAO,CAAC,gBAAgB;CAIzB"}
|
package/dist/yearGrid.js
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { RangeEvaluator } from './evaluator.js';
|
|
2
|
+
import { formatDate, daysInMonth } from './time.js';
|
|
3
|
+
/**
|
|
4
|
+
* YearGrid — lightweight year-level grid for heatmap-style rendering.
|
|
5
|
+
* No weeks, no time slots, no span tracking — just per-day activity data.
|
|
6
|
+
*/
|
|
7
|
+
export class YearGrid {
|
|
8
|
+
months;
|
|
9
|
+
year;
|
|
10
|
+
ranges;
|
|
11
|
+
evaluator;
|
|
12
|
+
constructor(config) {
|
|
13
|
+
this.year = config.year;
|
|
14
|
+
this.ranges = config.ranges;
|
|
15
|
+
this.evaluator = new RangeEvaluator(config.userTimezone);
|
|
16
|
+
this.months = this.generate();
|
|
17
|
+
}
|
|
18
|
+
generate() {
|
|
19
|
+
const months = [];
|
|
20
|
+
for (let month = 0; month < 12; month++) {
|
|
21
|
+
months.push(this.generateMonth(month));
|
|
22
|
+
}
|
|
23
|
+
return months;
|
|
24
|
+
}
|
|
25
|
+
generateMonth(month) {
|
|
26
|
+
const label = this.formatMonthLabel(month);
|
|
27
|
+
const totalDays = daysInMonth(this.year, month);
|
|
28
|
+
const days = [];
|
|
29
|
+
let activeDays = 0;
|
|
30
|
+
for (let day = 1; day <= totalDays; day++) {
|
|
31
|
+
const dateStr = formatDate(new Date(this.year, month, day));
|
|
32
|
+
const matchingRangeIds = [];
|
|
33
|
+
for (const range of this.ranges) {
|
|
34
|
+
if (this.evaluator.isDateInRange(dateStr, range)) {
|
|
35
|
+
matchingRangeIds.push(range.id);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
if (matchingRangeIds.length > 0) {
|
|
39
|
+
activeDays++;
|
|
40
|
+
}
|
|
41
|
+
days.push({
|
|
42
|
+
date: dateStr,
|
|
43
|
+
dayOfMonth: day,
|
|
44
|
+
rangeCount: matchingRangeIds.length,
|
|
45
|
+
rangeIds: matchingRangeIds,
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
return {
|
|
49
|
+
month,
|
|
50
|
+
label,
|
|
51
|
+
activeDays,
|
|
52
|
+
totalDays,
|
|
53
|
+
days,
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
formatMonthLabel(month) {
|
|
57
|
+
const date = new Date(this.year, month, 1);
|
|
58
|
+
return new Intl.DateTimeFormat('en-US', { month: 'long' }).format(date);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=yearGrid.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"yearGrid.js","sourceRoot":"","sources":["../src/yearGrid.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAEpD;;;GAGG;AACH,MAAM,OAAO,QAAQ;IACnB,MAAM,CAAc;IAEZ,IAAI,CAAS;IACb,MAAM,CAAc;IACpB,SAAS,CAAiB;IAElC,YAAY,MAAsB;QAChC,IAAI,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;QACxB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;QAC5B,IAAI,CAAC,SAAS,GAAG,IAAI,cAAc,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;QACzD,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;IAChC,CAAC;IAEO,QAAQ;QACd,MAAM,MAAM,GAAgB,EAAE,CAAC;QAE/B,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,EAAE,EAAE,KAAK,EAAE,EAAE,CAAC;YACxC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC;QACzC,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;IAEO,aAAa,CAAC,KAAa;QACjC,MAAM,KAAK,GAAG,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC;QAC3C,MAAM,SAAS,GAAG,WAAW,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAChD,MAAM,IAAI,GAAc,EAAE,CAAC;QAC3B,IAAI,UAAU,GAAG,CAAC,CAAC;QAEnB,KAAK,IAAI,GAAG,GAAG,CAAC,EAAE,GAAG,IAAI,SAAS,EAAE,GAAG,EAAE,EAAE,CAAC;YAC1C,MAAM,OAAO,GAAG,UAAU,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC;YAC5D,MAAM,gBAAgB,GAAa,EAAE,CAAC;YAEtC,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;gBAChC,IAAI,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,OAAO,EAAE,KAAK,CAAC,EAAE,CAAC;oBACjD,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;gBAClC,CAAC;YACH,CAAC;YAED,IAAI,gBAAgB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAChC,UAAU,EAAE,CAAC;YACf,CAAC;YAED,IAAI,CAAC,IAAI,CAAC;gBACR,IAAI,EAAE,OAAO;gBACb,UAAU,EAAE,GAAG;gBACf,UAAU,EAAE,gBAAgB,CAAC,MAAM;gBACnC,QAAQ,EAAE,gBAAgB;aAC3B,CAAC,CAAC;QACL,CAAC;QAED,OAAO;YACL,KAAK;YACL,KAAK;YACL,UAAU;YACV,SAAS;YACT,IAAI;SACL,CAAC;IACJ,CAAC;IAEO,gBAAgB,CAAC,KAAa;QACpC,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;QAC3C,OAAO,IAAI,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAC1E,CAAC;CACF"}
|
package/package.json
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@neo-reckoning/core",
|
|
3
|
+
"version": "0.1.0-alpha.1",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"types": "./dist/index.d.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"import": "./dist/index.js"
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
"scripts": {
|
|
14
|
+
"build": "tsc",
|
|
15
|
+
"test": "NODE_OPTIONS='--experimental-vm-modules' jest",
|
|
16
|
+
"typecheck": "tsc --noEmit"
|
|
17
|
+
},
|
|
18
|
+
"files": [
|
|
19
|
+
"dist"
|
|
20
|
+
],
|
|
21
|
+
"repository": {
|
|
22
|
+
"type": "git",
|
|
23
|
+
"url": "https://github.com/sdougbrown/neo-reckoning.git",
|
|
24
|
+
"directory": "packages/core"
|
|
25
|
+
},
|
|
26
|
+
"publishConfig": {
|
|
27
|
+
"access": "public"
|
|
28
|
+
}
|
|
29
|
+
}
|