ezmedicationinput 0.1.35 → 0.1.36
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/schedule.js +145 -79
- package/dist/types.d.ts +1 -1
- package/package.json +1 -1
package/dist/schedule.js
CHANGED
|
@@ -433,6 +433,25 @@ function mergeFrequencyDefaults(base, override) {
|
|
|
433
433
|
}
|
|
434
434
|
return merged;
|
|
435
435
|
}
|
|
436
|
+
function inferDailyFrequencyClocks(frequency) {
|
|
437
|
+
if (!Number.isFinite(frequency) || frequency <= 0) {
|
|
438
|
+
return [];
|
|
439
|
+
}
|
|
440
|
+
if (frequency === 1) {
|
|
441
|
+
return ["09:00:00"];
|
|
442
|
+
}
|
|
443
|
+
const startMinutes = 8 * 60;
|
|
444
|
+
const endMinutes = 20 * 60;
|
|
445
|
+
const spanMinutes = endMinutes - startMinutes;
|
|
446
|
+
const clocks = new Set();
|
|
447
|
+
for (let index = 0; index < frequency; index += 1) {
|
|
448
|
+
const minutes = startMinutes + Math.round((spanMinutes * index) / (frequency - 1));
|
|
449
|
+
const hour = Math.floor(minutes / SECONDS_PER_MINUTE);
|
|
450
|
+
const minute = minutes % SECONDS_PER_MINUTE;
|
|
451
|
+
clocks.add(`${pad(hour)}:${pad(minute)}:00`);
|
|
452
|
+
}
|
|
453
|
+
return Array.from(clocks).sort();
|
|
454
|
+
}
|
|
436
455
|
/** Resolves fallback clock arrays for frequency-only schedules. */
|
|
437
456
|
function resolveFrequencyClocks(timing, config) {
|
|
438
457
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
|
@@ -462,6 +481,11 @@ function resolveFrequencyClocks(timing, config) {
|
|
|
462
481
|
collected.add(normalizeClock(clock));
|
|
463
482
|
}
|
|
464
483
|
}
|
|
484
|
+
if (collected.size === 0 && repeat.period === 1 && repeat.periodUnit === "d") {
|
|
485
|
+
for (const clock of inferDailyFrequencyClocks(repeat.frequency)) {
|
|
486
|
+
collected.add(clock);
|
|
487
|
+
}
|
|
488
|
+
}
|
|
465
489
|
}
|
|
466
490
|
return Array.from(collected).sort();
|
|
467
491
|
}
|
|
@@ -561,46 +585,53 @@ function nextDueDoses(dosage, options) {
|
|
|
561
585
|
if (results.length >= effectiveLimit) {
|
|
562
586
|
return results.slice(0, effectiveLimit);
|
|
563
587
|
}
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
588
|
+
const canFallbackToFrequency = expanded.length === 0 &&
|
|
589
|
+
timeOfDayEntries.length === 0 &&
|
|
590
|
+
!!repeat.frequency &&
|
|
591
|
+
!!repeat.period &&
|
|
592
|
+
!!repeat.periodUnit;
|
|
593
|
+
if (!canFallbackToFrequency) {
|
|
594
|
+
if (expanded.length === 0) {
|
|
595
|
+
return results.slice(0, effectiveLimit);
|
|
596
|
+
}
|
|
597
|
+
let currentDay = startOfLocalDay(from, timeZone);
|
|
598
|
+
let iterations = 0;
|
|
599
|
+
const maxIterations = effectiveLimit * 31;
|
|
600
|
+
while (results.length < effectiveLimit && iterations < maxIterations) {
|
|
601
|
+
const weekday = getLocalWeekday(currentDay, timeZone);
|
|
602
|
+
if (!enforceDayFilter || dayFilter.has(weekday)) {
|
|
603
|
+
for (const entry of expanded) {
|
|
604
|
+
const targetDay = entry.dayShift === 0
|
|
605
|
+
? currentDay
|
|
606
|
+
: addLocalDays(currentDay, entry.dayShift, timeZone);
|
|
607
|
+
const zoned = makeZonedDateFromDay(targetDay, timeZone, entry.time);
|
|
608
|
+
if (!zoned) {
|
|
609
|
+
continue;
|
|
610
|
+
}
|
|
611
|
+
if (zoned < from) {
|
|
612
|
+
continue;
|
|
613
|
+
}
|
|
614
|
+
if (orderedAt && zoned < orderedAt) {
|
|
615
|
+
continue;
|
|
616
|
+
}
|
|
617
|
+
const iso = formatZonedIso(zoned, timeZone);
|
|
618
|
+
if (!seen.has(iso)) {
|
|
619
|
+
seen.add(iso);
|
|
620
|
+
results.push(iso);
|
|
621
|
+
if (results.length === effectiveLimit) {
|
|
622
|
+
break;
|
|
623
|
+
}
|
|
593
624
|
}
|
|
594
625
|
}
|
|
595
626
|
}
|
|
627
|
+
if (results.length >= effectiveLimit) {
|
|
628
|
+
break;
|
|
629
|
+
}
|
|
630
|
+
currentDay = addLocalDays(currentDay, 1, timeZone);
|
|
631
|
+
iterations += 1;
|
|
596
632
|
}
|
|
597
|
-
|
|
598
|
-
break;
|
|
599
|
-
}
|
|
600
|
-
currentDay = addLocalDays(currentDay, 1, timeZone);
|
|
601
|
-
iterations += 1;
|
|
633
|
+
return results.slice(0, effectiveLimit);
|
|
602
634
|
}
|
|
603
|
-
return results.slice(0, effectiveLimit);
|
|
604
635
|
}
|
|
605
636
|
const treatAsInterval = !!repeat.period &&
|
|
606
637
|
!!repeat.periodUnit &&
|
|
@@ -705,35 +736,42 @@ function derivePriorCountFromHistory(timing, repeat, config, orderedAt, from, ti
|
|
|
705
736
|
return count;
|
|
706
737
|
}
|
|
707
738
|
}
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
739
|
+
const canFallbackToFrequency = expanded.length === 0 &&
|
|
740
|
+
timeOfDayEntries.length === 0 &&
|
|
741
|
+
!!repeat.frequency &&
|
|
742
|
+
!!repeat.period &&
|
|
743
|
+
!!repeat.periodUnit;
|
|
744
|
+
if (!canFallbackToFrequency) {
|
|
745
|
+
if (expanded.length === 0) {
|
|
746
|
+
return count;
|
|
747
|
+
}
|
|
748
|
+
let currentDay = startOfLocalDay(orderedAt, timeZone);
|
|
749
|
+
let iterations = 0;
|
|
750
|
+
const maxIterations = normalizedCount !== undefined ? normalizedCount * 31 : 31 * 365;
|
|
751
|
+
while (currentDay < from && iterations < maxIterations) {
|
|
752
|
+
const weekday = getLocalWeekday(currentDay, timeZone);
|
|
753
|
+
if (!enforceDayFilter || dayFilter.has(weekday)) {
|
|
754
|
+
for (const entry of expanded) {
|
|
755
|
+
const targetDay = entry.dayShift === 0
|
|
756
|
+
? currentDay
|
|
757
|
+
: addLocalDays(currentDay, entry.dayShift, timeZone);
|
|
758
|
+
const zoned = makeZonedDateFromDay(targetDay, timeZone, entry.time);
|
|
759
|
+
if (!zoned) {
|
|
760
|
+
continue;
|
|
761
|
+
}
|
|
762
|
+
if (zoned < orderedAt || zoned >= from) {
|
|
763
|
+
continue;
|
|
764
|
+
}
|
|
765
|
+
if (recordCandidate(zoned) && normalizedCount !== undefined && seen.size >= normalizedCount) {
|
|
766
|
+
return count;
|
|
767
|
+
}
|
|
730
768
|
}
|
|
731
769
|
}
|
|
770
|
+
currentDay = addLocalDays(currentDay, 1, timeZone);
|
|
771
|
+
iterations += 1;
|
|
732
772
|
}
|
|
733
|
-
|
|
734
|
-
iterations += 1;
|
|
773
|
+
return count;
|
|
735
774
|
}
|
|
736
|
-
return count;
|
|
737
775
|
}
|
|
738
776
|
const treatAsInterval = !!repeat.period &&
|
|
739
777
|
!!repeat.periodUnit &&
|
|
@@ -949,27 +987,34 @@ function countScheduleEvents(dosage, from, to, config, baseTime, orderedAt, limi
|
|
|
949
987
|
recordCandidate(immediateSource);
|
|
950
988
|
}
|
|
951
989
|
}
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
990
|
+
const canFallbackToFrequency = expanded.length === 0 &&
|
|
991
|
+
timeOfDayEntries.length === 0 &&
|
|
992
|
+
!!repeat.frequency &&
|
|
993
|
+
!!repeat.period &&
|
|
994
|
+
!!repeat.periodUnit;
|
|
995
|
+
if (!canFallbackToFrequency) {
|
|
996
|
+
if (expanded.length === 0)
|
|
997
|
+
return count;
|
|
998
|
+
let currentDay = startOfLocalDay(from, timeZone);
|
|
999
|
+
let iterations = 0;
|
|
1000
|
+
const maxIterations = limit !== undefined ? limit * 31 : 365 * 31;
|
|
1001
|
+
while (count < (limit !== null && limit !== void 0 ? limit : Infinity) && currentDay < to && iterations < maxIterations) {
|
|
1002
|
+
const weekday = getLocalWeekday(currentDay, timeZone);
|
|
1003
|
+
if (!enforceDayFilter || dayFilter.has(weekday)) {
|
|
1004
|
+
for (const entry of expanded) {
|
|
1005
|
+
const targetDay = entry.dayShift === 0
|
|
1006
|
+
? currentDay
|
|
1007
|
+
: addLocalDays(currentDay, entry.dayShift, timeZone);
|
|
1008
|
+
const zoned = makeZonedDateFromDay(targetDay, timeZone, entry.time);
|
|
1009
|
+
if (zoned)
|
|
1010
|
+
recordCandidate(zoned);
|
|
1011
|
+
}
|
|
967
1012
|
}
|
|
1013
|
+
currentDay = addLocalDays(currentDay, 1, timeZone);
|
|
1014
|
+
iterations += 1;
|
|
968
1015
|
}
|
|
969
|
-
|
|
970
|
-
iterations += 1;
|
|
1016
|
+
return count;
|
|
971
1017
|
}
|
|
972
|
-
return count;
|
|
973
1018
|
}
|
|
974
1019
|
const treatAsInterval = !!repeat.period &&
|
|
975
1020
|
!!repeat.periodUnit &&
|
|
@@ -1047,7 +1092,7 @@ function countScheduleEvents(dosage, from, to, config, baseTime, orderedAt, limi
|
|
|
1047
1092
|
}
|
|
1048
1093
|
return count;
|
|
1049
1094
|
}
|
|
1050
|
-
function
|
|
1095
|
+
function calculateTotalUnitsSingle(options) {
|
|
1051
1096
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
|
|
1052
1097
|
const { dosage, durationValue, durationUnit, roundToMultiple, context } = options;
|
|
1053
1098
|
const from = coerceDate(options.from, "from");
|
|
@@ -1102,3 +1147,24 @@ function calculateTotalUnits(options) {
|
|
|
1102
1147
|
}
|
|
1103
1148
|
return result;
|
|
1104
1149
|
}
|
|
1150
|
+
function calculateTotalUnits(options) {
|
|
1151
|
+
if (Array.isArray(options.dosage)) {
|
|
1152
|
+
const hasAnyDosage = options.dosage.length > 0;
|
|
1153
|
+
if (!hasAnyDosage) {
|
|
1154
|
+
return { totalUnits: 0 };
|
|
1155
|
+
}
|
|
1156
|
+
let totalUnits = 0;
|
|
1157
|
+
let totalContainers = 0;
|
|
1158
|
+
let sawContainers = false;
|
|
1159
|
+
for (const dosage of options.dosage) {
|
|
1160
|
+
const result = calculateTotalUnitsSingle(Object.assign(Object.assign({}, options), { dosage }));
|
|
1161
|
+
totalUnits += result.totalUnits;
|
|
1162
|
+
if (result.totalContainers !== undefined) {
|
|
1163
|
+
totalContainers += result.totalContainers;
|
|
1164
|
+
sawContainers = true;
|
|
1165
|
+
}
|
|
1166
|
+
}
|
|
1167
|
+
return sawContainers ? { totalUnits, totalContainers } : { totalUnits };
|
|
1168
|
+
}
|
|
1169
|
+
return calculateTotalUnitsSingle(options);
|
|
1170
|
+
}
|
package/dist/types.d.ts
CHANGED
|
@@ -673,7 +673,7 @@ export interface TotalUnitsResult {
|
|
|
673
673
|
totalContainers?: number;
|
|
674
674
|
}
|
|
675
675
|
export interface TotalUnitsOptions extends NextDueDoseOptions {
|
|
676
|
-
dosage: FhirDosage;
|
|
676
|
+
dosage: FhirDosage | FhirDosage[];
|
|
677
677
|
durationValue: number;
|
|
678
678
|
durationUnit: FhirPeriodUnit;
|
|
679
679
|
roundToMultiple?: number;
|