@dereekb/dbx-components-mcp 13.11.2 → 13.11.4

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.
@@ -5,6 +5,1215 @@
5
5
  "generatedAt": "1970-01-01T00:00:00.000Z",
6
6
  "generator": "@dereekb/dbx-components-mcp/scripts/generate-manifests.mjs",
7
7
  "entries": [
8
+ {
9
+ "slug": "date-cell-range-of-timing-factory",
10
+ "name": "dateCellRangeOfTimingFactory",
11
+ "kind": "function",
12
+ "category": "date",
13
+ "module": "@dereekb/date",
14
+ "subpath": "date/date.cell.factory",
15
+ "signature": "dateCellRangeOfTimingFactory(config: DateCallIndexRangeFromDatesFactoryConfig): DateCellRangeOfTimingFactory",
16
+ "description": "Creates a {@link DateCellRangeOfTimingFactory} that converts dates or indexes into a clamped\n{@link DateCellRangeWithRange} relative to the configured timing.\n\nWhen `fitToTimingRange` is true (default), the returned range is clamped to the timing's valid index bounds.\nWhen `limitToCompletedIndexes` is true, only indexes whose timing duration has fully elapsed are included,\nwith the max boundary lazily refreshed as time passes.",
17
+ "params": [
18
+ {
19
+ "name": "config",
20
+ "type": "DateCallIndexRangeFromDatesFactoryConfig",
21
+ "description": "- Configuration specifying the timing, range fit, and completion constraints.",
22
+ "optional": false
23
+ }
24
+ ],
25
+ "returns": "A factory function that produces a clamped {@link DateCellRangeWithRange } from optional start/end input.",
26
+ "tags": [
27
+ "date",
28
+ "cell",
29
+ "range",
30
+ "timing",
31
+ "factory",
32
+ "clamp",
33
+ "completed",
34
+ "index",
35
+ "of",
36
+ "datecellrangeoftimingfactory"
37
+ ],
38
+ "example": "const timing = dateCellTiming({ startsAt, duration: 60 }, 5);\nconst factory = dateCellRangeOfTimingFactory({ timing });\n\n// Clamp an arbitrary range to the timing's bounds (0..4)\nconst range = factory({ i: -10, to: 10 });\n// range.i === 0, range.to === 4\n\n// With no input, defaults to 0..now\nconst defaultRange = factory();",
39
+ "relatedSlugs": [
40
+ "date-cell-range-of-timing",
41
+ "date-cell-timing-completed-time-range",
42
+ "date-cell-index-range"
43
+ ]
44
+ },
45
+ {
46
+ "slug": "date-cell-range-of-timing",
47
+ "name": "dateCellRangeOfTiming",
48
+ "kind": "function",
49
+ "category": "date",
50
+ "module": "@dereekb/date",
51
+ "subpath": "date/date.cell.factory",
52
+ "signature": "dateCellRangeOfTiming(config: DateCellTiming | DateCallIndexRangeFromDatesFactoryConfig, input?: Maybe<DateCellRangeOfTimingInput>): DateCellRangeWithRange",
53
+ "description": "Computes a {@link DateCellRangeWithRange} from a timing and optional start/end input.\n\nShorthand for creating a {@link dateCellRangeOfTimingFactory} and immediately invoking it.",
54
+ "params": [
55
+ {
56
+ "name": "config",
57
+ "type": "DateCellTiming | DateCallIndexRangeFromDatesFactoryConfig",
58
+ "description": "- A {@link DateCellTiming } or full factory configuration.",
59
+ "optional": false
60
+ },
61
+ {
62
+ "name": "input",
63
+ "type": "Maybe<DateCellRangeOfTimingInput>",
64
+ "description": "- Optional start/end boundaries for the range.",
65
+ "optional": true
66
+ }
67
+ ],
68
+ "returns": "A clamped {@link DateCellRangeWithRange } derived from the timing and input.",
69
+ "tags": [
70
+ "date",
71
+ "cell",
72
+ "range",
73
+ "timing",
74
+ "clamp",
75
+ "shorthand",
76
+ "of",
77
+ "datecellrangeoftiming"
78
+ ],
79
+ "relatedSlugs": [
80
+ "date-cell-range-of-timing-factory",
81
+ "date-cell-timing-completed-time-range"
82
+ ]
83
+ },
84
+ {
85
+ "slug": "date-cell-timing-completed-time-range",
86
+ "name": "dateCellTimingCompletedTimeRange",
87
+ "kind": "function",
88
+ "category": "date",
89
+ "module": "@dereekb/date",
90
+ "subpath": "date/date.cell.factory",
91
+ "signature": "dateCellTimingCompletedTimeRange(timing: DateCellTiming, config?: DateCellTimingCompleteTimeRangeConfig): DateCellRangeWithRange",
92
+ "description": "Returns a {@link DateCellRangeWithRange} representing only the completed (fully elapsed) portion\nof the timing schedule. Useful for determining which days have already finished.\n\nBy default fitToTimingRange is true.",
93
+ "params": [
94
+ {
95
+ "name": "timing",
96
+ "type": "DateCellTiming",
97
+ "description": "- The timing schedule to evaluate.",
98
+ "optional": false
99
+ },
100
+ {
101
+ "name": "config",
102
+ "type": "DateCellTimingCompleteTimeRangeConfig",
103
+ "description": "- Optional configuration for the current time reference and range fitting.",
104
+ "optional": true
105
+ }
106
+ ],
107
+ "returns": "A {@link DateCellRangeWithRange } covering only the completed day indexes.",
108
+ "tags": [
109
+ "date",
110
+ "cell",
111
+ "timing",
112
+ "completed",
113
+ "range",
114
+ "elapsed",
115
+ "index",
116
+ "time",
117
+ "datecelltimingcompletedtimerange"
118
+ ],
119
+ "relatedSlugs": [
120
+ "date-cell-timing-latest-completed-index",
121
+ "date-cell-range-of-timing-factory"
122
+ ]
123
+ },
124
+ {
125
+ "slug": "date-cell-timing-latest-completed-index",
126
+ "name": "dateCellTimingLatestCompletedIndex",
127
+ "kind": "function",
128
+ "category": "date",
129
+ "module": "@dereekb/date",
130
+ "subpath": "date/date.cell.factory",
131
+ "signature": "dateCellTimingLatestCompletedIndex(timing: DateCellTiming, now?: Date): IndexNumber",
132
+ "description": "Returns the latest completed day index for a {@link DateCellTiming}.\n\nReturns -1 if no days have been completed yet.",
133
+ "params": [
134
+ {
135
+ "name": "timing",
136
+ "type": "DateCellTiming",
137
+ "description": "- The timing schedule to evaluate.",
138
+ "optional": false
139
+ },
140
+ {
141
+ "name": "now",
142
+ "type": "Date",
143
+ "description": "- Optional reference time; defaults to the current time.",
144
+ "optional": true
145
+ }
146
+ ],
147
+ "returns": "The zero-based index of the last fully completed day, or -1 if none.",
148
+ "tags": [
149
+ "date",
150
+ "cell",
151
+ "timing",
152
+ "latest",
153
+ "completed",
154
+ "index",
155
+ "elapsed",
156
+ "datecelltiminglatestcompletedindex"
157
+ ],
158
+ "relatedSlugs": [
159
+ "date-cell-timing-completed-time-range",
160
+ "date-cell-timing-end-index"
161
+ ]
162
+ },
163
+ {
164
+ "slug": "date-cell-range-to-date-cell-index-range",
165
+ "name": "dateCellRangeToDateCellIndexRange",
166
+ "kind": "function",
167
+ "category": "date",
168
+ "module": "@dereekb/date",
169
+ "subpath": "date/date.cell.factory",
170
+ "signature": "dateCellRangeToDateCellIndexRange(range: DateCellRange): DateCellIndexRange",
171
+ "description": "Converts a {@link DateCellRange} (inclusive `to`) to a {@link DateCellIndexRange} (exclusive `maxIndex`).",
172
+ "params": [
173
+ {
174
+ "name": "range",
175
+ "type": "DateCellRange",
176
+ "description": "- The inclusive date cell range to convert.",
177
+ "optional": false
178
+ }
179
+ ],
180
+ "returns": "A {@link DateCellIndexRange } with exclusive `maxIndex`.",
181
+ "tags": [
182
+ "date",
183
+ "cell",
184
+ "range",
185
+ "index-range",
186
+ "convert",
187
+ "inclusive",
188
+ "exclusive",
189
+ "to",
190
+ "index",
191
+ "datecellrangetodatecellindexrange"
192
+ ],
193
+ "relatedSlugs": [
194
+ "date-cell-index-range-to-date-cell-range",
195
+ "date-cell-index-range"
196
+ ]
197
+ },
198
+ {
199
+ "slug": "date-cell-index-range-to-date-cell-range",
200
+ "name": "dateCellIndexRangeToDateCellRange",
201
+ "kind": "function",
202
+ "category": "date",
203
+ "module": "@dereekb/date",
204
+ "subpath": "date/date.cell.factory",
205
+ "signature": "dateCellIndexRangeToDateCellRange(range: DateCellIndexRange): DateCellRangeWithRange",
206
+ "description": "Converts a {@link DateCellIndexRange} (exclusive `maxIndex`) back to a {@link DateCellRangeWithRange} (inclusive `to`).",
207
+ "params": [
208
+ {
209
+ "name": "range",
210
+ "type": "DateCellIndexRange",
211
+ "description": "- The exclusive date cell index range to convert.",
212
+ "optional": false
213
+ }
214
+ ],
215
+ "returns": "A {@link DateCellRangeWithRange } with inclusive `to`.",
216
+ "tags": [
217
+ "date",
218
+ "cell",
219
+ "range",
220
+ "index-range",
221
+ "convert",
222
+ "exclusive",
223
+ "inclusive",
224
+ "index",
225
+ "to",
226
+ "datecellindexrangetodatecellrange"
227
+ ],
228
+ "relatedSlugs": [
229
+ "date-cell-range-to-date-cell-index-range",
230
+ "date-cell-index-range"
231
+ ]
232
+ },
233
+ {
234
+ "slug": "date-cell-index-range",
235
+ "name": "dateCellIndexRange",
236
+ "kind": "function",
237
+ "category": "date",
238
+ "module": "@dereekb/date",
239
+ "subpath": "date/date.cell.factory",
240
+ "signature": "dateCellIndexRange(timing: DateCellTiming, limit?: DateCellTimingRangeInput, fitToTimingRange?: boolean): DateCellIndexRange",
241
+ "description": "Generates a {@link DateCellIndexRange} based on the input timing.\n\nAn arbitrary limit can also be applied. When `fitToTimingRange` is true (default),\nthe limit is intersected with the timing's own range; otherwise the limit is used as-is.",
242
+ "params": [
243
+ {
244
+ "name": "timing",
245
+ "type": "DateCellTiming",
246
+ "description": "- The timing schedule to derive the range from.",
247
+ "optional": false
248
+ },
249
+ {
250
+ "name": "limit",
251
+ "type": "DateCellTimingRangeInput",
252
+ "description": "- Optional range input to constrain the output.",
253
+ "optional": true
254
+ },
255
+ {
256
+ "name": "fitToTimingRange",
257
+ "type": "boolean",
258
+ "description": "- Whether to intersect the limit with the timing's own range. Defaults to true.",
259
+ "optional": true
260
+ }
261
+ ],
262
+ "returns": "A {@link DateCellIndexRange } representing the computed index bounds.",
263
+ "tags": [
264
+ "date",
265
+ "cell",
266
+ "index-range",
267
+ "timing",
268
+ "bounds",
269
+ "limit",
270
+ "intersect",
271
+ "index",
272
+ "range",
273
+ "datecellindexrange"
274
+ ],
275
+ "relatedSlugs": [
276
+ "date-cell-range-to-date-cell-index-range",
277
+ "date-cell-index-range-to-date-cell-range"
278
+ ]
279
+ },
280
+ {
281
+ "slug": "expand-date-cell-collection",
282
+ "name": "expandDateCellCollection",
283
+ "kind": "function",
284
+ "category": "date",
285
+ "module": "@dereekb/date",
286
+ "subpath": "date/date.cell.factory",
287
+ "signature": "expandDateCellCollection(collection: DateCellCollection<B>): DateCellDurationSpan<B>[]",
288
+ "description": "Expands a {@link DateCellCollection} into an array of {@link DateCellDurationSpan} values\nby combining its timing and blocks.\n\nShorthand for calling {@link expandDateCellTiming} with `collection.timing` and `collection.blocks`.",
289
+ "params": [
290
+ {
291
+ "name": "collection",
292
+ "type": "DateCellCollection<B>",
293
+ "description": "- The date cell collection containing timing and blocks to expand.",
294
+ "optional": false
295
+ }
296
+ ],
297
+ "returns": "An array of {@link DateCellDurationSpan } values with concrete start times and durations.",
298
+ "tags": [
299
+ "date",
300
+ "cell",
301
+ "collection",
302
+ "expand",
303
+ "duration-span",
304
+ "blocks",
305
+ "expanddatecellcollection"
306
+ ],
307
+ "relatedSlugs": [
308
+ "expand-date-cell-timing",
309
+ "date-cell-timing-expansion-factory"
310
+ ]
311
+ },
312
+ {
313
+ "slug": "expand-date-cell-timing",
314
+ "name": "expandDateCellTiming",
315
+ "kind": "function",
316
+ "category": "date",
317
+ "module": "@dereekb/date",
318
+ "subpath": "date/date.cell.factory",
319
+ "signature": "expandDateCellTiming(timing: DateCellTiming, blocks: B[]): DateCellDurationSpan<B>[]",
320
+ "description": "Expands the given blocks into {@link DateCellDurationSpan} values using the provided timing.\n\nShorthand for creating a {@link dateCellTimingExpansionFactory} and immediately invoking it.",
321
+ "params": [
322
+ {
323
+ "name": "timing",
324
+ "type": "DateCellTiming",
325
+ "description": "- The timing schedule providing start times and duration.",
326
+ "optional": false
327
+ },
328
+ {
329
+ "name": "blocks",
330
+ "type": "B[]",
331
+ "description": "- The date cell blocks to expand into duration spans.",
332
+ "optional": false
333
+ }
334
+ ],
335
+ "returns": "An array of {@link DateCellDurationSpan } values with concrete start times.",
336
+ "tags": [
337
+ "date",
338
+ "cell",
339
+ "timing",
340
+ "expand",
341
+ "duration-span",
342
+ "blocks",
343
+ "shorthand",
344
+ "expanddatecelltiming"
345
+ ],
346
+ "relatedSlugs": [
347
+ "expand-date-cell-collection",
348
+ "date-cell-timing-expansion-factory"
349
+ ]
350
+ },
351
+ {
352
+ "slug": "date-cell-timing-expansion-factory",
353
+ "name": "dateCellTimingExpansionFactory",
354
+ "kind": "function",
355
+ "category": "date",
356
+ "module": "@dereekb/date",
357
+ "subpath": "date/date.cell.factory",
358
+ "signature": "dateCellTimingExpansionFactory(config: DateCellTimingExpansionFactoryConfig): DateCellTimingExpansionFactory<B>",
359
+ "description": "Creates a {@link DateCellTimingExpansionFactory} that expands date cell blocks into\n{@link DateCellDurationSpan} values with concrete start times and durations.\n\nBlocks with a range (`i` to `to`) are expanded into individual single-index entries.\nFiltering is applied both at the block level and at the computed duration span level,\nand evaluation can be capped for performance with large datasets.",
360
+ "params": [
361
+ {
362
+ "name": "config",
363
+ "type": "DateCellTimingExpansionFactoryConfig",
364
+ "description": "- Configuration specifying the timing, range limits, filters, and output caps.",
365
+ "optional": false
366
+ }
367
+ ],
368
+ "returns": "A factory function that expands date cell blocks into {@link DateCellDurationSpan } arrays.",
369
+ "tags": [
370
+ "date",
371
+ "cell",
372
+ "timing",
373
+ "expansion",
374
+ "factory",
375
+ "blocks",
376
+ "duration-span",
377
+ "filter",
378
+ "datecelltimingexpansionfactory"
379
+ ],
380
+ "example": "const timing = dateCellTiming({ startsAt, duration: 60 }, 5);\nconst expand = dateCellTimingExpansionFactory({ timing });\n\nconst blocks: DateCell[] = [{ i: 0 }, { i: 1 }, { i: 2 }];\nconst spans = expand(blocks);\n// Each span has { i, startsAt, duration } with the concrete start time for that day\n\n// With range blocks:\nconst rangeBlocks = [{ i: 0, to: 2 }];\nconst expandedSpans = expand(rangeBlocks);\n// Produces 3 spans, one for each index 0, 1, 2",
381
+ "relatedSlugs": [
382
+ "expand-date-cell-collection",
383
+ "expand-date-cell-timing",
384
+ "date-cell-day-timing-info-factory"
385
+ ]
386
+ },
387
+ {
388
+ "slug": "date-cell-day-timing-info-factory",
389
+ "name": "dateCellDayTimingInfoFactory",
390
+ "kind": "function",
391
+ "category": "date",
392
+ "module": "@dereekb/date",
393
+ "subpath": "date/date.cell.factory",
394
+ "signature": "dateCellDayTimingInfoFactory(config: DateCellDayTimingInfoFactoryConfig): DateCellDayTimingInfoFactory",
395
+ "description": "Creates a {@link DateCellDayTimingInfoFactory} that computes detailed timing information\n(progress state, start/end times, range membership) for any given date or day index.\n\nThe factory handles timezone normalization internally and accounts for edge cases\nwhere a timing window spans midnight into the next day.",
396
+ "params": [
397
+ {
398
+ "name": "config",
399
+ "type": "DateCellDayTimingInfoFactoryConfig",
400
+ "description": "- Configuration providing the timing and optional range limit.",
401
+ "optional": false
402
+ }
403
+ ],
404
+ "returns": "A factory that computes {@link DateCellDayTimingInfo } for any date or day index.",
405
+ "tags": [
406
+ "date",
407
+ "cell",
408
+ "day",
409
+ "timing",
410
+ "info",
411
+ "factory",
412
+ "progress",
413
+ "in-progress",
414
+ "complete",
415
+ "datecelldaytiminginfofactory"
416
+ ],
417
+ "example": "const timing = dateCellTiming({ startsAt, duration: 60 }, 5);\nconst infoFactory = dateCellDayTimingInfoFactory({ timing });\n\n// Get info for day index 2\nconst info = infoFactory(2, new Date());\nconsole.log(info.isInProgress); // whether day 2's window is currently active\nconsole.log(info.startsAtOnDay); // concrete start time for day 2\nconsole.log(info.isInRange); // whether index 2 is within the timing's range\n\n// Get info for a specific date\nconst dateInfo = infoFactory(someDate);\nconsole.log(dateInfo.dayIndex); // which day index this date falls on",
418
+ "relatedSlugs": [
419
+ "date-cell-timing-relative-index-factory",
420
+ "date-cell-timing-expansion-factory",
421
+ "date-cell-timing-completed-time-range"
422
+ ]
423
+ },
424
+ {
425
+ "slug": "is-date-cell-timing-relative-index-factory",
426
+ "name": "isDateCellTimingRelativeIndexFactory",
427
+ "kind": "function",
428
+ "category": "date",
429
+ "module": "@dereekb/date",
430
+ "subpath": "date/date.cell.factory",
431
+ "signature": "isDateCellTimingRelativeIndexFactory(input: unknown): input is DateCellTimingRelativeIndexFactory<T>",
432
+ "description": "Type guard that returns true if the input is a {@link DateCellTimingRelativeIndexFactory}.\n\nChecks for the presence of `_timing` and `_normalInstance` properties on a function.",
433
+ "params": [
434
+ {
435
+ "name": "input",
436
+ "type": "unknown",
437
+ "description": "- The value to check.",
438
+ "optional": false
439
+ }
440
+ ],
441
+ "returns": "True if the input is a {@link DateCellTimingRelativeIndexFactory }.",
442
+ "tags": [
443
+ "date",
444
+ "cell",
445
+ "timing",
446
+ "relative-index",
447
+ "factory",
448
+ "type-guard",
449
+ "check",
450
+ "is",
451
+ "relative",
452
+ "index",
453
+ "isdatecelltimingrelativeindexfactory"
454
+ ],
455
+ "relatedSlugs": [
456
+ "date-cell-timing-relative-index-factory"
457
+ ]
458
+ },
459
+ {
460
+ "slug": "date-cell-timing-relative-index-factory",
461
+ "name": "dateCellTimingRelativeIndexFactory",
462
+ "kind": "function",
463
+ "category": "date",
464
+ "module": "@dereekb/date",
465
+ "subpath": "date/date.cell.factory",
466
+ "signature": "dateCellTimingRelativeIndexFactory(input: T | DateCellTimingRelativeIndexFactory<T>): DateCellTimingRelativeIndexFactory<T>",
467
+ "description": "Creates a {@link DateCellTimingRelativeIndexFactory} that converts dates, ISO8601 day strings,\nor indexes into a zero-based day index relative to the timing's start date.\n\nIf an existing factory is passed, it is returned as-is (idempotent). The factory normalizes\nall date inputs through UTC to handle timezone offsets correctly, computing the floor\nof the hour difference divided by 24 to determine the day offset.",
468
+ "params": [
469
+ {
470
+ "name": "input",
471
+ "type": "T | DateCellTimingRelativeIndexFactory<T>",
472
+ "description": "- A timing configuration or an existing factory (returned as-is).",
473
+ "optional": false
474
+ }
475
+ ],
476
+ "returns": "A factory that converts dates, ISO8601 day strings, or indexes to zero-based day offsets.",
477
+ "tags": [
478
+ "date",
479
+ "cell",
480
+ "timing",
481
+ "relative-index",
482
+ "factory",
483
+ "day-offset",
484
+ "iso8601",
485
+ "timezone",
486
+ "relative",
487
+ "index",
488
+ "datecelltimingrelativeindexfactory"
489
+ ],
490
+ "example": "const timing = dateCellTiming({ startsAt, duration: 60 }, 5);\nconst indexFactory = dateCellTimingRelativeIndexFactory(timing);\n\n// Numeric indexes pass through unchanged\nindexFactory(3); // 3\n\n// Dates are converted to their day offset from timing start\nindexFactory(addDays(startsAt, 2)); // 2\n\n// ISO8601 day strings are also supported\nindexFactory('2024-01-15'); // day offset from timing start\n\n// Access the underlying timing and normalizer\nindexFactory._timing; // the original timing\nindexFactory._normalInstance; // timezone normalizer",
491
+ "relatedSlugs": [
492
+ "is-date-cell-timing-relative-index-factory",
493
+ "get-relative-index-for-date-cell-timing",
494
+ "date-cell-timing-relative-index-array-factory"
495
+ ]
496
+ },
497
+ {
498
+ "slug": "date-cell-timing-relative-index-array-factory",
499
+ "name": "dateCellTimingRelativeIndexArrayFactory",
500
+ "kind": "function",
501
+ "category": "date",
502
+ "module": "@dereekb/date",
503
+ "subpath": "date/date.cell.factory",
504
+ "signature": "dateCellTimingRelativeIndexArrayFactory(indexFactory: DateCellTimingRelativeIndexFactory<T>): DateCellTimingRelativeIndexArrayFactory<T>",
505
+ "description": "Creates a {@link DateCellTimingRelativeIndexArrayFactory} that converts mixed arrays of\ndates, date ranges, and cell ranges into a flat array of day indexes.\n\nDate ranges and cell ranges are expanded to include every index within the range.",
506
+ "params": [
507
+ {
508
+ "name": "indexFactory",
509
+ "type": "DateCellTimingRelativeIndexFactory<T>",
510
+ "description": "- The relative index factory used for date-to-index conversion.",
511
+ "optional": false
512
+ }
513
+ ],
514
+ "returns": "A factory that flattens mixed date/range arrays into day index arrays.",
515
+ "tags": [
516
+ "date",
517
+ "cell",
518
+ "timing",
519
+ "relative-index",
520
+ "array",
521
+ "factory",
522
+ "expand",
523
+ "range",
524
+ "relative",
525
+ "index",
526
+ "datecelltimingrelativeindexarrayfactory"
527
+ ],
528
+ "relatedSlugs": [
529
+ "date-cell-timing-relative-index-factory",
530
+ "date-cell-index-range"
531
+ ]
532
+ },
533
+ {
534
+ "slug": "get-relative-index-for-date-cell-timing",
535
+ "name": "getRelativeIndexForDateCellTiming",
536
+ "kind": "function",
537
+ "category": "date",
538
+ "module": "@dereekb/date",
539
+ "subpath": "date/date.cell.factory",
540
+ "signature": "getRelativeIndexForDateCellTiming(timing: DateCellTimingStartsAt, date?: DateOrDateCellIndex): DateCellIndex",
541
+ "description": "Convenience function that returns the zero-based day index for a date (or index)\nrelative to the given timing's start.\n\nDefaults to the current date/time if no date is provided.",
542
+ "params": [
543
+ {
544
+ "name": "timing",
545
+ "type": "DateCellTimingStartsAt",
546
+ "description": "- The timing providing the start date and timezone context.",
547
+ "optional": false
548
+ },
549
+ {
550
+ "name": "date",
551
+ "type": "DateOrDateCellIndex",
552
+ "description": "- A date or index to convert; defaults to the current date/time.",
553
+ "optional": true
554
+ }
555
+ ],
556
+ "returns": "The zero-based day index relative to the timing's start.",
557
+ "tags": [
558
+ "date",
559
+ "cell",
560
+ "timing",
561
+ "relative-index",
562
+ "day-offset",
563
+ "shorthand",
564
+ "get",
565
+ "relative",
566
+ "index",
567
+ "for",
568
+ "getrelativeindexfordatecelltiming"
569
+ ],
570
+ "example": "const timing: DateCellTimingStartsAt = { startsAt, timezone: 'America/Denver' };\n\n// Get today's index relative to the timing\nconst todayIndex = getRelativeIndexForDateCellTiming(timing);\n\n// Get the index for a specific date\nconst index = getRelativeIndexForDateCellTiming(timing, someDate);",
571
+ "relatedSlugs": [
572
+ "date-cell-timing-relative-index-factory",
573
+ "get-relative-date-for-date-cell-timing"
574
+ ]
575
+ },
576
+ {
577
+ "slug": "date-cell-timing-date-factory",
578
+ "name": "dateCellTimingDateFactory",
579
+ "kind": "function",
580
+ "category": "date",
581
+ "module": "@dereekb/date",
582
+ "subpath": "date/date.cell.factory",
583
+ "signature": "dateCellTimingDateFactory(timing: T): DateCellTimingDateFactory<T>",
584
+ "description": "Creates a {@link DateCellTimingDateFactory} that maps day indexes to calendar dates\nwhile preserving the current time-of-day.\n\nThis is useful when you need the actual Date for a given index (e.g., for display or\ndate arithmetic) but want to retain the hours/minutes of \"now\" rather than using\nthe timing's startsAt time.",
585
+ "params": [
586
+ {
587
+ "name": "timing",
588
+ "type": "T",
589
+ "description": "- The timing providing the start date and timezone context.",
590
+ "optional": false
591
+ }
592
+ ],
593
+ "returns": "A factory that maps day indexes to calendar dates preserving the current time-of-day.",
594
+ "tags": [
595
+ "date",
596
+ "cell",
597
+ "timing",
598
+ "factory",
599
+ "day-index",
600
+ "calendar",
601
+ "time-of-day",
602
+ "datecelltimingdatefactory"
603
+ ],
604
+ "example": "const timing = dateCellTiming({ startsAt, duration: 60 }, 5);\nconst dateFactory = dateCellTimingDateFactory(timing);\n\n// Pass through dates unchanged\ndateFactory(someDate); // returns someDate\n\n// Convert index 3 to a date with current time-of-day\nconst dateForDay3 = dateFactory(3);\n\n// Convert index 3 to a date with a specific reference time\nconst dateForDay3AtNoon = dateFactory(3, noonDate);",
605
+ "relatedSlugs": [
606
+ "date-cell-timing-start-date-factory",
607
+ "date-cell-timing-starts-at-date-factory",
608
+ "get-relative-date-for-date-cell-timing"
609
+ ]
610
+ },
611
+ {
612
+ "slug": "date-cell-timing-end-index",
613
+ "name": "dateCellTimingEndIndex",
614
+ "kind": "function",
615
+ "category": "date",
616
+ "module": "@dereekb/date",
617
+ "subpath": "date/date.cell.factory",
618
+ "signature": "dateCellTimingEndIndex(input: DateCellTiming | DateCellTimingRelativeIndexFactory<DateCellTiming>): IndexNumber",
619
+ "description": "Returns the last (maximum) day index for a {@link DateCellTiming} schedule.\n\nThis is the index corresponding to the timing's `end` date, representing the final\nday in the schedule.",
620
+ "params": [
621
+ {
622
+ "name": "input",
623
+ "type": "DateCellTiming | DateCellTimingRelativeIndexFactory<DateCellTiming>",
624
+ "description": "- A timing or an existing relative index factory.",
625
+ "optional": false
626
+ }
627
+ ],
628
+ "returns": "The zero-based index of the last day in the schedule.",
629
+ "tags": [
630
+ "date",
631
+ "cell",
632
+ "timing",
633
+ "end",
634
+ "index",
635
+ "last",
636
+ "datecelltimingendindex"
637
+ ],
638
+ "example": "const timing = dateCellTiming({ startsAt, duration: 60 }, 5);\nconst lastIndex = dateCellTimingEndIndex(timing); // 4 (zero-based, 5 days)",
639
+ "relatedSlugs": [
640
+ "date-cell-timing-relative-index-factory",
641
+ "date-cell-timing-end-date-factory",
642
+ "date-cell-timing-latest-completed-index"
643
+ ]
644
+ },
645
+ {
646
+ "slug": "date-cell-timing-start-date-factory",
647
+ "name": "dateCellTimingStartDateFactory",
648
+ "kind": "function",
649
+ "category": "date",
650
+ "module": "@dereekb/date",
651
+ "subpath": "date/date.cell.factory",
652
+ "signature": "dateCellTimingStartDateFactory(input: T | DateCellTimingRelativeIndexFactory<T>): DateCellTimingStartDateFactory<T>",
653
+ "description": "Creates a {@link DateCellTimingStartDateFactory} that computes the calendar start-of-day date\nfor any day index relative to the timing's start.\n\nThe returned date represents the beginning of the day in the timing's timezone context.",
654
+ "params": [
655
+ {
656
+ "name": "input",
657
+ "type": "T | DateCellTimingRelativeIndexFactory<T>",
658
+ "description": "- A timing or an existing relative index factory.",
659
+ "optional": false
660
+ }
661
+ ],
662
+ "returns": "A factory that maps day indexes to the start-of-day date in the timing's timezone.",
663
+ "tags": [
664
+ "date",
665
+ "cell",
666
+ "timing",
667
+ "start-of-day",
668
+ "factory",
669
+ "day-index",
670
+ "calendar",
671
+ "timezone",
672
+ "start",
673
+ "datecelltimingstartdatefactory"
674
+ ],
675
+ "relatedSlugs": [
676
+ "date-cell-timing-starts-at-date-factory",
677
+ "date-cell-timing-end-date-factory",
678
+ "date-cell-timing-date-factory"
679
+ ]
680
+ },
681
+ {
682
+ "slug": "date-cell-timing-starts-at-date-factory",
683
+ "name": "dateCellTimingStartsAtDateFactory",
684
+ "kind": "function",
685
+ "category": "date",
686
+ "module": "@dereekb/date",
687
+ "subpath": "date/date.cell.factory",
688
+ "signature": "dateCellTimingStartsAtDateFactory(input: T | DateCellTimingRelativeIndexFactory<T>): DateCellTimingStartsAtDateFactory<T>",
689
+ "description": "Creates a {@link DateCellTimingStartsAtDateFactory} that computes the concrete event start time\nfor any day index relative to the timing's schedule.\n\nThe returned date reflects the actual `startsAt` time-of-day offset to the correct calendar date\nfor the requested index, with proper timezone normalization.",
690
+ "params": [
691
+ {
692
+ "name": "input",
693
+ "type": "T | DateCellTimingRelativeIndexFactory<T>",
694
+ "description": "- A timing or an existing relative index factory.",
695
+ "optional": false
696
+ }
697
+ ],
698
+ "returns": "A factory that computes the concrete event start time for any day index.",
699
+ "tags": [
700
+ "date",
701
+ "cell",
702
+ "timing",
703
+ "starts-at",
704
+ "factory",
705
+ "day-index",
706
+ "event-time",
707
+ "calendar",
708
+ "starts",
709
+ "at",
710
+ "datecelltimingstartsatdatefactory"
711
+ ],
712
+ "example": "const timing = dateCellTiming({ startsAt, duration: 60 }, 5);\nconst startsAtFactory = dateCellTimingStartsAtDateFactory(timing);\n\n// Get the exact start time for day 3\nconst day3Start = startsAtFactory(3);\n// Returns a Date with the same time-of-day as startsAt but on day 3's calendar date\n\n// Also works with dates\nconst startForDate = startsAtFactory(someDate);",
713
+ "relatedSlugs": [
714
+ "date-cell-timing-start-date-factory",
715
+ "date-cell-timing-end-date-factory",
716
+ "date-cell-timing-date-factory"
717
+ ]
718
+ },
719
+ {
720
+ "slug": "date-cell-timing-end-date-factory",
721
+ "name": "dateCellTimingEndDateFactory",
722
+ "kind": "function",
723
+ "category": "date",
724
+ "module": "@dereekb/date",
725
+ "subpath": "date/date.cell.factory",
726
+ "signature": "dateCellTimingEndDateFactory(input: T | DateCellTimingRelativeIndexFactory<T>): DateCellTimingEndDateFactory<T>",
727
+ "description": "Creates a {@link DateCellTimingEndDateFactory} that computes the end time\n(startsAt + duration) for any day index relative to the timing's schedule.",
728
+ "params": [
729
+ {
730
+ "name": "input",
731
+ "type": "T | DateCellTimingRelativeIndexFactory<T>",
732
+ "description": "- A timing or an existing relative index factory.",
733
+ "optional": false
734
+ }
735
+ ],
736
+ "returns": "A factory that computes the end time (startsAt + duration) for any day index.",
737
+ "tags": [
738
+ "date",
739
+ "cell",
740
+ "timing",
741
+ "end",
742
+ "factory",
743
+ "day-index",
744
+ "duration",
745
+ "event-time",
746
+ "datecelltimingenddatefactory"
747
+ ],
748
+ "example": "const timing = dateCellTiming({ startsAt, duration: 60 }, 5);\nconst endFactory = dateCellTimingEndDateFactory(timing);\n\n// Get the end time for day 2 (startsAt time + 60 minutes on day 2)\nconst day2End = endFactory(2);",
749
+ "relatedSlugs": [
750
+ "date-cell-timing-starts-at-date-factory",
751
+ "date-cell-timing-start-date-factory"
752
+ ]
753
+ },
754
+ {
755
+ "slug": "get-relative-date-for-date-cell-timing",
756
+ "name": "getRelativeDateForDateCellTiming",
757
+ "kind": "function",
758
+ "category": "date",
759
+ "module": "@dereekb/date",
760
+ "subpath": "date/date.cell.factory",
761
+ "signature": "getRelativeDateForDateCellTiming(timing: DateCellTimingStartsAt, input: DateOrDateCellIndex): Date",
762
+ "description": "Convenience function that returns the calendar date for a given day index or date\nrelative to the timing. Shorthand for creating a {@link dateCellTimingDateFactory} and invoking it.",
763
+ "params": [
764
+ {
765
+ "name": "timing",
766
+ "type": "DateCellTimingStartsAt",
767
+ "description": "- The timing providing the start date and timezone context.",
768
+ "optional": false
769
+ },
770
+ {
771
+ "name": "input",
772
+ "type": "DateOrDateCellIndex",
773
+ "description": "- A date or day index to convert.",
774
+ "optional": false
775
+ }
776
+ ],
777
+ "returns": "The calendar date corresponding to the input, preserving current time-of-day.",
778
+ "tags": [
779
+ "date",
780
+ "cell",
781
+ "timing",
782
+ "relative-date",
783
+ "day-index",
784
+ "calendar",
785
+ "shorthand",
786
+ "get",
787
+ "relative",
788
+ "for",
789
+ "getrelativedatefordatecelltiming"
790
+ ],
791
+ "relatedSlugs": [
792
+ "date-cell-timing-date-factory",
793
+ "get-relative-index-for-date-cell-timing"
794
+ ]
795
+ },
796
+ {
797
+ "slug": "update-date-cell-timing-with-date-cell-timing-event",
798
+ "name": "updateDateCellTimingWithDateCellTimingEvent",
799
+ "kind": "function",
800
+ "category": "date",
801
+ "module": "@dereekb/date",
802
+ "subpath": "date/date.cell.factory",
803
+ "signature": "updateDateCellTimingWithDateCellTimingEvent(input: UpdateDateCellTimingWithDateCellTimingEventInput): FullDateCellTiming",
804
+ "description": "Produces a new {@link FullDateCellTiming} by selectively replacing parts of an existing timing\nwith values from a {@link DateCellTimingEvent}.\n\nThis is the primary mechanism for updating a timing schedule in response to user edits.\nThe `replaceStartDay`, `replaceStartsAt`, `endOnEvent`, and `replaceDuration` flags\nindependently control which aspects of the timing are modified, and can be combined.\n\nWhen both `replaceStartDay` and `replaceStartsAt` are true, the event's startsAt is used directly.\nWhen only `replaceStartDay` is true, the day changes but the time-of-day is preserved.\nWhen only `replaceStartsAt` is true, the time-of-day changes but the calendar date is preserved.",
805
+ "params": [
806
+ {
807
+ "name": "input",
808
+ "type": "UpdateDateCellTimingWithDateCellTimingEventInput",
809
+ "description": "- Configuration specifying the timing to update, the event source, and which aspects to replace.",
810
+ "optional": false
811
+ }
812
+ ],
813
+ "returns": "A new {@link FullDateCellTiming } with the requested aspects replaced.",
814
+ "tags": [
815
+ "date",
816
+ "cell",
817
+ "timing",
818
+ "event",
819
+ "update",
820
+ "replace",
821
+ "modify",
822
+ "edit",
823
+ "with",
824
+ "updatedatecelltimingwithdatecelltimingevent"
825
+ ],
826
+ "example": "const result = updateDateCellTimingWithDateCellTimingEvent({\n timing: existingTiming,\n event: { startsAt: newStartTime, duration: 90 },\n replaceStartsAt: true,\n replaceDuration: true\n});\n// result has the same start day and end day, but new time-of-day and 90-minute duration",
827
+ "relatedSlugs": [
828
+ "date-cell-timing-starts-at-date-factory",
829
+ "date-cell-timing-start-date-factory"
830
+ ]
831
+ },
832
+ {
833
+ "slug": "is-date-within-date-cell-range-function",
834
+ "name": "isDateWithinDateCellRangeFunction",
835
+ "kind": "function",
836
+ "category": "date",
837
+ "module": "@dereekb/date",
838
+ "subpath": "date/date.cell.factory",
839
+ "signature": "isDateWithinDateCellRangeFunction(config: IsDateWithinDateCellRangeConfig): IsDateWithinDateCellRangeFunction",
840
+ "description": "Creates a predicate that checks whether a date, index, or range falls within\nthe configured reference range.\n\nConverts all date-based inputs to cell indexes using the configured (or inferred) timezone\nbefore performing the containment check.",
841
+ "params": [
842
+ {
843
+ "name": "config",
844
+ "type": "IsDateWithinDateCellRangeConfig",
845
+ "description": "- Configuration specifying the reference range and optional timezone context.",
846
+ "optional": false
847
+ }
848
+ ],
849
+ "returns": "A predicate function that checks containment within the configured range.",
850
+ "tags": [
851
+ "date",
852
+ "cell",
853
+ "range",
854
+ "contains",
855
+ "within",
856
+ "predicate",
857
+ "factory",
858
+ "check",
859
+ "is",
860
+ "function",
861
+ "isdatewithindatecellrangefunction"
862
+ ],
863
+ "example": "const isInRange = isDateWithinDateCellRangeFunction({\n startsAt: timing,\n range: { i: 2, to: 5 }\n});\n\nisInRange(3); // true - index 3 is within [2, 5]\nisInRange(6); // false - index 6 is outside [2, 5]\nisInRange(someDate); // converts date to index, then checks containment",
864
+ "relatedSlugs": [
865
+ "date-cell-timing-relative-index-factory",
866
+ "date-cell-index-range"
867
+ ]
868
+ },
869
+ {
870
+ "slug": "time-duration-data-is-empty",
871
+ "name": "timeDurationDataIsEmpty",
872
+ "kind": "function",
873
+ "category": "date",
874
+ "module": "@dereekb/date",
875
+ "subpath": "date/date.duration.data",
876
+ "signature": "timeDurationDataIsEmpty(data: TimeDurationData): boolean",
877
+ "description": "Returns true if the input TimeDurationData has no meaningful values (all zero or undefined).",
878
+ "params": [
879
+ {
880
+ "name": "data",
881
+ "type": "TimeDurationData",
882
+ "description": "- The duration data to check",
883
+ "optional": false
884
+ }
885
+ ],
886
+ "returns": "True if empty",
887
+ "tags": [
888
+ "date",
889
+ "duration",
890
+ "empty",
891
+ "check",
892
+ "time",
893
+ "zero",
894
+ "data",
895
+ "is",
896
+ "timedurationdataisempty"
897
+ ],
898
+ "example": "timeDurationDataIsEmpty({}); // true\ntimeDurationDataIsEmpty({ hours: 0, minutes: 0 }); // true\ntimeDurationDataIsEmpty({ hours: 1 }); // false",
899
+ "relatedSlugs": [
900
+ "duration-data-to-milliseconds",
901
+ "milliseconds-to-duration-data"
902
+ ]
903
+ },
904
+ {
905
+ "slug": "duration-data-to-milliseconds",
906
+ "name": "durationDataToMilliseconds",
907
+ "kind": "function",
908
+ "category": "date",
909
+ "module": "@dereekb/date",
910
+ "subpath": "date/date.duration.data",
911
+ "signature": "durationDataToMilliseconds(data: TimeDurationData): Milliseconds",
912
+ "description": "Converts a TimeDurationData to total milliseconds by summing all fields.",
913
+ "params": [
914
+ {
915
+ "name": "data",
916
+ "type": "TimeDurationData",
917
+ "description": "- The duration data to convert",
918
+ "optional": false
919
+ }
920
+ ],
921
+ "returns": "Total milliseconds",
922
+ "tags": [
923
+ "date",
924
+ "duration",
925
+ "milliseconds",
926
+ "convert",
927
+ "sum",
928
+ "time",
929
+ "total",
930
+ "data",
931
+ "to",
932
+ "durationdatatomilliseconds"
933
+ ],
934
+ "example": "durationDataToMilliseconds({ hours: 1, minutes: 30 }); // 5400000\ndurationDataToMilliseconds({ days: 1, hours: 2 }); // 93600000",
935
+ "relatedSlugs": [
936
+ "milliseconds-to-duration-data",
937
+ "parse-duration-string-to-milliseconds",
938
+ "time-duration-data-is-empty"
939
+ ]
940
+ },
941
+ {
942
+ "slug": "milliseconds-to-duration-data",
943
+ "name": "millisecondsToDurationData",
944
+ "kind": "function",
945
+ "category": "date",
946
+ "module": "@dereekb/date",
947
+ "subpath": "date/date.duration.data",
948
+ "signature": "millisecondsToDurationData(ms: Milliseconds, units?: readonly TimeUnit[]): TimeDurationData",
949
+ "description": "Decomposes milliseconds into a TimeDurationData object using the specified units.\n\nBreaks down from largest to smallest unit, only using units in the provided list.",
950
+ "params": [
951
+ {
952
+ "name": "ms",
953
+ "type": "Milliseconds",
954
+ "description": "- The total milliseconds to decompose",
955
+ "optional": false
956
+ },
957
+ {
958
+ "name": "units",
959
+ "type": "readonly TimeUnit[]",
960
+ "description": "- Which units to decompose into (defaults to days, hours, minutes, seconds)",
961
+ "optional": true
962
+ }
963
+ ],
964
+ "returns": "A TimeDurationData with the decomposed values",
965
+ "tags": [
966
+ "date",
967
+ "duration",
968
+ "milliseconds",
969
+ "decompose",
970
+ "convert",
971
+ "breakdown",
972
+ "units",
973
+ "time",
974
+ "to",
975
+ "data",
976
+ "millisecondstodurationdata"
977
+ ],
978
+ "example": "millisecondsToDurationData(5400000); // { days: 0, hours: 1, minutes: 30, seconds: 0 }\nmillisecondsToDurationData(90000, ['min', 's']); // { minutes: 1, seconds: 30 }",
979
+ "relatedSlugs": [
980
+ "duration-data-to-milliseconds",
981
+ "parse-duration-string",
982
+ "format-duration-string"
983
+ ]
984
+ },
985
+ {
986
+ "slug": "get-duration-data-value",
987
+ "name": "getDurationDataValue",
988
+ "kind": "function",
989
+ "category": "date",
990
+ "module": "@dereekb/date",
991
+ "subpath": "date/date.duration.data",
992
+ "signature": "getDurationDataValue(data: TimeDurationData, unit: TimeUnit): number",
993
+ "description": "Reads a specific time unit value from a TimeDurationData object.",
994
+ "params": [
995
+ {
996
+ "name": "data",
997
+ "type": "TimeDurationData",
998
+ "description": "- The duration data",
999
+ "optional": false
1000
+ },
1001
+ {
1002
+ "name": "unit",
1003
+ "type": "TimeUnit",
1004
+ "description": "- The time unit to read",
1005
+ "optional": false
1006
+ }
1007
+ ],
1008
+ "returns": "The value for that unit, or 0 if not set",
1009
+ "tags": [
1010
+ "date",
1011
+ "duration",
1012
+ "get",
1013
+ "read",
1014
+ "value",
1015
+ "unit",
1016
+ "time",
1017
+ "field",
1018
+ "data",
1019
+ "getdurationdatavalue"
1020
+ ],
1021
+ "relatedSlugs": [
1022
+ "set-duration-data-value",
1023
+ "duration-data-to-milliseconds"
1024
+ ]
1025
+ },
1026
+ {
1027
+ "slug": "set-duration-data-value",
1028
+ "name": "setDurationDataValue",
1029
+ "kind": "function",
1030
+ "category": "date",
1031
+ "module": "@dereekb/date",
1032
+ "subpath": "date/date.duration.data",
1033
+ "signature": "setDurationDataValue(data: TimeDurationData, unit: TimeUnit, value: number): TimeDurationData",
1034
+ "description": "Returns a new TimeDurationData with the specified unit set to the given value.",
1035
+ "params": [
1036
+ {
1037
+ "name": "data",
1038
+ "type": "TimeDurationData",
1039
+ "description": "- The original duration data",
1040
+ "optional": false
1041
+ },
1042
+ {
1043
+ "name": "unit",
1044
+ "type": "TimeUnit",
1045
+ "description": "- The time unit to set",
1046
+ "optional": false
1047
+ },
1048
+ {
1049
+ "name": "value",
1050
+ "type": "number",
1051
+ "description": "- The new value",
1052
+ "optional": false
1053
+ }
1054
+ ],
1055
+ "returns": "A new TimeDurationData with the updated value",
1056
+ "tags": [
1057
+ "date",
1058
+ "duration",
1059
+ "set",
1060
+ "update",
1061
+ "value",
1062
+ "unit",
1063
+ "time",
1064
+ "field",
1065
+ "immutable",
1066
+ "data",
1067
+ "setdurationdatavalue"
1068
+ ],
1069
+ "relatedSlugs": [
1070
+ "get-duration-data-value",
1071
+ "duration-data-to-milliseconds"
1072
+ ]
1073
+ },
1074
+ {
1075
+ "slug": "parse-duration-string",
1076
+ "name": "parseDurationString",
1077
+ "kind": "function",
1078
+ "category": "date",
1079
+ "module": "@dereekb/date",
1080
+ "subpath": "date/date.duration.data",
1081
+ "signature": "parseDurationString(input: string): TimeDurationData",
1082
+ "description": "Parses a human-readable duration string into a TimeDurationData object.\n\nSupports compact formats (\"3d10h5m8s\"), spaced formats (\"3d 10h 5m 8s\"),\nand long formats (\"3 days 10 hours 5 minutes 8 seconds\"). Mixed formats\nare also supported. If the same unit appears multiple times, values are summed.\n\nIf the string contains only a number with no unit, it is treated as the\nsmallest unit that would make sense (milliseconds by default).",
1083
+ "params": [
1084
+ {
1085
+ "name": "input",
1086
+ "type": "string",
1087
+ "description": "- The duration string to parse",
1088
+ "optional": false
1089
+ }
1090
+ ],
1091
+ "returns": "A TimeDurationData object with the parsed values",
1092
+ "tags": [
1093
+ "date",
1094
+ "duration",
1095
+ "parse",
1096
+ "string",
1097
+ "time",
1098
+ "human-readable",
1099
+ "decode",
1100
+ "parsedurationstring"
1101
+ ],
1102
+ "example": "parseDurationString('3d10h5m8s'); // { days: 3, hours: 10, minutes: 5, seconds: 8 }\nparseDurationString('2 hours 30 minutes'); // { hours: 2, minutes: 30 }\nparseDurationString('1w 2d'); // { weeks: 1, days: 2 }\nparseDurationString('500ms'); // { milliseconds: 500 }",
1103
+ "relatedSlugs": [
1104
+ "parse-duration-string-to-milliseconds",
1105
+ "format-duration-string",
1106
+ "format-duration-string-long",
1107
+ "milliseconds-to-duration-data"
1108
+ ]
1109
+ },
1110
+ {
1111
+ "slug": "parse-duration-string-to-milliseconds",
1112
+ "name": "parseDurationStringToMilliseconds",
1113
+ "kind": "function",
1114
+ "category": "date",
1115
+ "module": "@dereekb/date",
1116
+ "subpath": "date/date.duration.data",
1117
+ "signature": "parseDurationStringToMilliseconds(input: string): Milliseconds",
1118
+ "description": "Parses a duration string directly to milliseconds.",
1119
+ "params": [
1120
+ {
1121
+ "name": "input",
1122
+ "type": "string",
1123
+ "description": "- The duration string to parse",
1124
+ "optional": false
1125
+ }
1126
+ ],
1127
+ "returns": "Total milliseconds",
1128
+ "tags": [
1129
+ "date",
1130
+ "duration",
1131
+ "parse",
1132
+ "string",
1133
+ "milliseconds",
1134
+ "convert",
1135
+ "decode",
1136
+ "to",
1137
+ "parsedurationstringtomilliseconds"
1138
+ ],
1139
+ "example": "parseDurationStringToMilliseconds('1h30m'); // 5400000",
1140
+ "relatedSlugs": [
1141
+ "parse-duration-string",
1142
+ "duration-data-to-milliseconds",
1143
+ "format-duration-string"
1144
+ ]
1145
+ },
1146
+ {
1147
+ "slug": "format-duration-string",
1148
+ "name": "formatDurationString",
1149
+ "kind": "function",
1150
+ "category": "date",
1151
+ "module": "@dereekb/date",
1152
+ "subpath": "date/date.duration.data",
1153
+ "signature": "formatDurationString(data: TimeDurationData): string",
1154
+ "description": "Formats a TimeDurationData to a compact string like \"3d10h5m8s\".\n\nOmits zero-value units. Returns \"0s\" if all fields are zero or empty.",
1155
+ "params": [
1156
+ {
1157
+ "name": "data",
1158
+ "type": "TimeDurationData",
1159
+ "description": "- The duration data to format",
1160
+ "optional": false
1161
+ }
1162
+ ],
1163
+ "returns": "A compact duration string",
1164
+ "tags": [
1165
+ "date",
1166
+ "duration",
1167
+ "format",
1168
+ "string",
1169
+ "compact",
1170
+ "encode",
1171
+ "time",
1172
+ "formatdurationstring"
1173
+ ],
1174
+ "example": "formatDurationString({ days: 3, hours: 10, minutes: 5, seconds: 8 }); // \"3d10h5m8s\"\nformatDurationString({ hours: 2, minutes: 30 }); // \"2h30m\"\nformatDurationString({}); // \"0s\"",
1175
+ "relatedSlugs": [
1176
+ "format-duration-string-long",
1177
+ "parse-duration-string",
1178
+ "duration-data-to-milliseconds"
1179
+ ]
1180
+ },
1181
+ {
1182
+ "slug": "format-duration-string-long",
1183
+ "name": "formatDurationStringLong",
1184
+ "kind": "function",
1185
+ "category": "date",
1186
+ "module": "@dereekb/date",
1187
+ "subpath": "date/date.duration.data",
1188
+ "signature": "formatDurationStringLong(data: TimeDurationData): string",
1189
+ "description": "Formats a TimeDurationData to a long human-readable string.\n\nOmits zero-value units. Returns \"0 seconds\" if all fields are zero or empty.",
1190
+ "params": [
1191
+ {
1192
+ "name": "data",
1193
+ "type": "TimeDurationData",
1194
+ "description": "- The duration data to format",
1195
+ "optional": false
1196
+ }
1197
+ ],
1198
+ "returns": "A human-readable duration string",
1199
+ "tags": [
1200
+ "date",
1201
+ "duration",
1202
+ "format",
1203
+ "string",
1204
+ "long",
1205
+ "human-readable",
1206
+ "encode",
1207
+ "time",
1208
+ "formatdurationstringlong"
1209
+ ],
1210
+ "example": "formatDurationStringLong({ days: 3, hours: 10 }); // \"3 days 10 hours\"\nformatDurationStringLong({ hours: 1, minutes: 1 }); // \"1 hour 1 minute\"",
1211
+ "relatedSlugs": [
1212
+ "format-duration-string",
1213
+ "parse-duration-string",
1214
+ "duration-data-to-milliseconds"
1215
+ ]
1216
+ },
8
1217
  {
9
1218
  "slug": "date-duration-span-end-date",
10
1219
  "name": "dateDurationSpanEndDate",
@@ -221,6 +1430,52 @@
221
1430
  "format-date-distance"
222
1431
  ]
223
1432
  },
1433
+ {
1434
+ "slug": "format-to-time-range-string",
1435
+ "name": "formatToTimeRangeString",
1436
+ "kind": "function",
1437
+ "category": "date",
1438
+ "module": "@dereekb/date",
1439
+ "subpath": "date/date.format",
1440
+ "signature": "formatToTimeRangeString(startOrDateRange: DateRange | Date, end?: Maybe<Date>, onlyTimeRange?: boolean): string",
1441
+ "description": "Formats a date range as a time-only range string when both dates are on the same day,\nor falls back to a full date+time range when they span multiple days.\n\nSame day: `\"12:00 AM - 4:00 PM\"`\nDifferent days: `\"01/01/2001 12:00 AM - 01/02/2001 4:00 PM\"`",
1442
+ "params": [
1443
+ {
1444
+ "name": "startOrDateRange",
1445
+ "type": "DateRange | Date",
1446
+ "description": "- date range object or start date",
1447
+ "optional": false
1448
+ },
1449
+ {
1450
+ "name": "end",
1451
+ "type": "Maybe<Date>",
1452
+ "description": "- optional end date when a start date is provided",
1453
+ "optional": true
1454
+ },
1455
+ {
1456
+ "name": "onlyTimeRange",
1457
+ "type": "boolean",
1458
+ "description": "- whether to force time-only formatting regardless of date span",
1459
+ "optional": true
1460
+ }
1461
+ ],
1462
+ "returns": "the formatted time or date+time range string",
1463
+ "tags": [
1464
+ "date",
1465
+ "format",
1466
+ "time",
1467
+ "range",
1468
+ "string",
1469
+ "day-aware",
1470
+ "to",
1471
+ "formattotimerangestring"
1472
+ ],
1473
+ "example": "import { formatToTimeRangeString } from '@dereekb/date';\n\n// Same day - time only\nformatToTimeRangeString({ start: new Date('2024-01-15T09:00:00'), end: new Date('2024-01-15T17:00:00') });\n// \"9:00 AM - 5:00 PM\"\n\n// Different days - includes date\nformatToTimeRangeString({ start: new Date('2024-01-15T09:00:00'), end: new Date('2024-01-16T17:00:00') });\n// \"01/15/2024 9:00 AM - 01/16/2024 5:00 PM\"",
1474
+ "relatedSlugs": [
1475
+ "format-to-day-time-range-string",
1476
+ "format-date-range"
1477
+ ]
1478
+ },
224
1479
  {
225
1480
  "slug": "date-range-days-count",
226
1481
  "name": "dateRangeDaysCount",
@@ -788,6 +2043,276 @@
788
2043
  "safe-to-js-date"
789
2044
  ]
790
2045
  },
2046
+ {
2047
+ "slug": "earliest-date",
2048
+ "name": "earliestDate",
2049
+ "kind": "function",
2050
+ "category": "date",
2051
+ "module": "@dereekb/date",
2052
+ "subpath": "date/date",
2053
+ "signature": "earliestDate(dates: Maybe<Date>[], defaultDate?: Maybe<Date>): Maybe<Date>",
2054
+ "description": "Returns the earliest (minimum) date from the input array, ignoring null/undefined entries.",
2055
+ "params": [
2056
+ {
2057
+ "name": "dates",
2058
+ "type": "Maybe<Date>[]",
2059
+ "description": "- array of dates that may contain null/undefined",
2060
+ "optional": false
2061
+ },
2062
+ {
2063
+ "name": "defaultDate",
2064
+ "type": "Maybe<Date>",
2065
+ "description": "- fallback if no valid dates exist",
2066
+ "optional": true
2067
+ }
2068
+ ],
2069
+ "returns": "the earliest date, or the default if the array has no valid dates",
2070
+ "tags": [
2071
+ "date",
2072
+ "min",
2073
+ "earliest",
2074
+ "oldest",
2075
+ "before",
2076
+ "compare",
2077
+ "sort",
2078
+ "earliestdate"
2079
+ ],
2080
+ "example": "const a = new Date('2024-01-01');\nconst b = new Date('2024-06-01');\nearliestDate([a, b]); // a\nearliestDate([null, undefined], new Date()); // falls back to default",
2081
+ "relatedSlugs": [
2082
+ "latest-date",
2083
+ "is-before"
2084
+ ]
2085
+ },
2086
+ {
2087
+ "slug": "latest-date",
2088
+ "name": "latestDate",
2089
+ "kind": "function",
2090
+ "category": "date",
2091
+ "module": "@dereekb/date",
2092
+ "subpath": "date/date",
2093
+ "signature": "latestDate(dates: Maybe<Date>[], defaultDate?: Maybe<Date>): Maybe<Date>",
2094
+ "description": "Returns the latest (maximum) date from the input array, ignoring null/undefined entries.",
2095
+ "params": [
2096
+ {
2097
+ "name": "dates",
2098
+ "type": "Maybe<Date>[]",
2099
+ "description": "- array of dates that may contain null/undefined",
2100
+ "optional": false
2101
+ },
2102
+ {
2103
+ "name": "defaultDate",
2104
+ "type": "Maybe<Date>",
2105
+ "description": "- fallback if no valid dates exist",
2106
+ "optional": true
2107
+ }
2108
+ ],
2109
+ "returns": "the latest date, or the default if the array has no valid dates",
2110
+ "tags": [
2111
+ "date",
2112
+ "max",
2113
+ "latest",
2114
+ "newest",
2115
+ "after",
2116
+ "compare",
2117
+ "sort",
2118
+ "latestdate"
2119
+ ],
2120
+ "example": "const a = new Date('2024-01-01');\nconst b = new Date('2024-06-01');\nlatestDate([a, b]); // b\nlatestDate([null], new Date()); // falls back to default",
2121
+ "relatedSlugs": [
2122
+ "earliest-date",
2123
+ "is-after"
2124
+ ]
2125
+ },
2126
+ {
2127
+ "slug": "is-after",
2128
+ "name": "isAfter",
2129
+ "kind": "function",
2130
+ "category": "date",
2131
+ "module": "@dereekb/date",
2132
+ "subpath": "date/date",
2133
+ "signature": "isAfter(a: Maybe<Date>, b: Maybe<Date>, defaultValue?: Maybe<boolean>): Maybe<boolean>",
2134
+ "description": "Null-safe date comparison that returns true when `a` is chronologically after `b`.\n\nIf either date is null/undefined, returns the default value instead.",
2135
+ "params": [
2136
+ {
2137
+ "name": "a",
2138
+ "type": "Maybe<Date>",
2139
+ "description": "- first date",
2140
+ "optional": false
2141
+ },
2142
+ {
2143
+ "name": "b",
2144
+ "type": "Maybe<Date>",
2145
+ "description": "- second date to compare against",
2146
+ "optional": false
2147
+ },
2148
+ {
2149
+ "name": "defaultValue",
2150
+ "type": "Maybe<boolean>",
2151
+ "description": "- returned when either date is nullish",
2152
+ "optional": true
2153
+ }
2154
+ ],
2155
+ "returns": "whether `a` is after `b`, or the default",
2156
+ "tags": [
2157
+ "date",
2158
+ "after",
2159
+ "compare",
2160
+ "gt",
2161
+ "greater",
2162
+ "maybe",
2163
+ "safe",
2164
+ "is",
2165
+ "isafter"
2166
+ ],
2167
+ "example": "const jan = new Date('2024-01-01');\nconst feb = new Date('2024-02-01');\nisAfter(feb, jan); // true\nisAfter(null, jan); // undefined\nisAfter(null, jan, false); // false",
2168
+ "relatedSlugs": [
2169
+ "is-before",
2170
+ "is-same-date",
2171
+ "latest-date"
2172
+ ]
2173
+ },
2174
+ {
2175
+ "slug": "is-before",
2176
+ "name": "isBefore",
2177
+ "kind": "function",
2178
+ "category": "date",
2179
+ "module": "@dereekb/date",
2180
+ "subpath": "date/date",
2181
+ "signature": "isBefore(a: Maybe<Date>, b: Maybe<Date>, defaultValue?: Maybe<boolean>): Maybe<boolean>",
2182
+ "description": "Null-safe date comparison that returns true when `a` is chronologically before `b`.\n\nIf either date is null/undefined, returns the default value instead.",
2183
+ "params": [
2184
+ {
2185
+ "name": "a",
2186
+ "type": "Maybe<Date>",
2187
+ "description": "- first date",
2188
+ "optional": false
2189
+ },
2190
+ {
2191
+ "name": "b",
2192
+ "type": "Maybe<Date>",
2193
+ "description": "- second date to compare against",
2194
+ "optional": false
2195
+ },
2196
+ {
2197
+ "name": "defaultValue",
2198
+ "type": "Maybe<boolean>",
2199
+ "description": "- returned when either date is nullish",
2200
+ "optional": true
2201
+ }
2202
+ ],
2203
+ "returns": "whether `a` is before `b`, or the default",
2204
+ "tags": [
2205
+ "date",
2206
+ "before",
2207
+ "compare",
2208
+ "lt",
2209
+ "less",
2210
+ "maybe",
2211
+ "safe",
2212
+ "is",
2213
+ "isbefore"
2214
+ ],
2215
+ "example": "const jan = new Date('2024-01-01');\nconst feb = new Date('2024-02-01');\nisBefore(jan, feb); // true\nisBefore(null, feb); // undefined\nisBefore(null, feb, false); // false",
2216
+ "relatedSlugs": [
2217
+ "is-after",
2218
+ "is-same-date",
2219
+ "earliest-date"
2220
+ ]
2221
+ },
2222
+ {
2223
+ "slug": "is-same-date",
2224
+ "name": "isSameDate",
2225
+ "kind": "function",
2226
+ "category": "date",
2227
+ "module": "@dereekb/date",
2228
+ "subpath": "date/date",
2229
+ "signature": "isSameDate(a: Maybe<Date>, b: Maybe<Date>, defaultValue?: Maybe<boolean>): Maybe<boolean>",
2230
+ "description": "Null-safe exact date equality check (millisecond precision).\n\nWhen both dates are null/undefined and no default is provided, returns true (treating two absent values as equal).",
2231
+ "params": [
2232
+ {
2233
+ "name": "a",
2234
+ "type": "Maybe<Date>",
2235
+ "description": "- first date",
2236
+ "optional": false
2237
+ },
2238
+ {
2239
+ "name": "b",
2240
+ "type": "Maybe<Date>",
2241
+ "description": "- second date",
2242
+ "optional": false
2243
+ },
2244
+ {
2245
+ "name": "defaultValue",
2246
+ "type": "Maybe<boolean>",
2247
+ "description": "- returned when either date is nullish (defaults to `a == b` if not provided)",
2248
+ "optional": true
2249
+ }
2250
+ ],
2251
+ "returns": "whether the dates are exactly equal",
2252
+ "tags": [
2253
+ "date",
2254
+ "equal",
2255
+ "equality",
2256
+ "same",
2257
+ "compare",
2258
+ "exact",
2259
+ "is",
2260
+ "issamedate"
2261
+ ],
2262
+ "example": "const d = new Date('2024-01-01T00:00:00.000Z');\nisSameDate(d, new Date(d.getTime())); // true\nisSameDate(null, null); // true\nisSameDate(null, d); // false",
2263
+ "relatedSlugs": [
2264
+ "is-same-day",
2265
+ "is-same-date-hours-and-minutes",
2266
+ "is-after",
2267
+ "is-before"
2268
+ ]
2269
+ },
2270
+ {
2271
+ "slug": "is-same-date-day",
2272
+ "name": "isSameDateDay",
2273
+ "kind": "function",
2274
+ "category": "date",
2275
+ "module": "@dereekb/date",
2276
+ "subpath": "date/date",
2277
+ "signature": "isSameDateDay(a: Maybe<Date>, b: Maybe<Date>, defaultValue?: Maybe<boolean>): Maybe<boolean>",
2278
+ "description": "Null-safe day-level date equality check (same year, month, and day, ignoring time).\n\nWhen both dates are null/undefined and no default is provided, returns true (treating two absent values as equal).",
2279
+ "params": [
2280
+ {
2281
+ "name": "a",
2282
+ "type": "Maybe<Date>",
2283
+ "description": "- first date",
2284
+ "optional": false
2285
+ },
2286
+ {
2287
+ "name": "b",
2288
+ "type": "Maybe<Date>",
2289
+ "description": "- second date",
2290
+ "optional": false
2291
+ },
2292
+ {
2293
+ "name": "defaultValue",
2294
+ "type": "Maybe<boolean>",
2295
+ "description": "- returned when either date is nullish",
2296
+ "optional": true
2297
+ }
2298
+ ],
2299
+ "returns": "whether both dates fall on the same calendar day",
2300
+ "tags": [
2301
+ "date",
2302
+ "day",
2303
+ "same",
2304
+ "equal",
2305
+ "calendar",
2306
+ "compare",
2307
+ "is",
2308
+ "issamedateday"
2309
+ ],
2310
+ "example": "const morning = new Date('2024-01-01T08:00:00.000Z');\nconst evening = new Date('2024-01-01T20:00:00.000Z');\nisSameDateDay(morning, evening); // true\nisSameDateDay(null, null); // true",
2311
+ "relatedSlugs": [
2312
+ "is-same-date",
2313
+ "is-same-date-hours-and-minutes"
2314
+ ]
2315
+ },
791
2316
  {
792
2317
  "slug": "round-down-to-minute",
793
2318
  "name": "roundDownToMinute",
@@ -859,6 +2384,55 @@
859
2384
  "round-date-down-to",
860
2385
  "round-date-to"
861
2386
  ]
2387
+ },
2388
+ {
2389
+ "slug": "round-date-to",
2390
+ "name": "roundDateTo",
2391
+ "kind": "function",
2392
+ "category": "date",
2393
+ "module": "@dereekb/date",
2394
+ "subpath": "date/date",
2395
+ "signature": "roundDateTo(date: DateOrUnixDateTimeMillisecondsNumber, roundToUnit: DateHourMinuteOrSecond, roundType?: FloorOrCeilRounding): DateOrUnixDateTimeMillisecondsNumber",
2396
+ "description": "Rounds a date or unix timestamp to the nearest unit boundary using the specified rounding direction.\n\nPreserves the input type: Date inputs return Date, number inputs return number.",
2397
+ "params": [
2398
+ {
2399
+ "name": "date",
2400
+ "type": "DateOrUnixDateTimeMillisecondsNumber",
2401
+ "description": "- date or unix millisecond timestamp to round",
2402
+ "optional": false
2403
+ },
2404
+ {
2405
+ "name": "roundToUnit",
2406
+ "type": "DateHourMinuteOrSecond",
2407
+ "description": "- time unit to round to ('hour', 'minute', or 'second')",
2408
+ "optional": false
2409
+ },
2410
+ {
2411
+ "name": "roundType",
2412
+ "type": "FloorOrCeilRounding",
2413
+ "description": "- rounding direction ('floor' or 'ceil', defaults to 'floor')",
2414
+ "optional": true
2415
+ }
2416
+ ],
2417
+ "returns": "the rounded value in the same type as the input",
2418
+ "tags": [
2419
+ "date",
2420
+ "round",
2421
+ "floor",
2422
+ "ceil",
2423
+ "unit",
2424
+ "hour",
2425
+ "minute",
2426
+ "second",
2427
+ "truncate",
2428
+ "to",
2429
+ "rounddateto"
2430
+ ],
2431
+ "relatedSlugs": [
2432
+ "round-date-down-to",
2433
+ "round-down-to-minute",
2434
+ "round-down-to-hour"
2435
+ ]
862
2436
  }
863
2437
  ]
864
2438
  }