Docs: Update benchmark results

This commit is contained in:
github-actions[bot]
2025-11-18 23:31:52 +00:00
parent 341252fec1
commit 5855cf8a6f
77 changed files with 972 additions and 1051 deletions

View File

@@ -1,71 +1,69 @@
const findAvailableSlots = async (cal1, cal2, constraints) => {
const { default: dayjs } = await import('https://cdn.jsdelivr.net/npm/dayjs@1.11.10/+esm');
const { default: isBetween } = await import('https://cdn.jsdelivr.net/npm/dayjs@1.11.10/plugin/isBetween.js/+esm');
const { default: customParseFormat } = await import('https://cdn.jsdelivr.net/npm/dayjs@1.11.10/plugin/customParseFormat.js/+esm');
const findAvailableSlots = async (calendar1, calendar2, constraints) => {
const { startOfDay, addMinutes, parseISO, formatISO } = await import('https://cdn.jsdelivr.net/npm/date-fns@3.0.0/+esm');
dayjs.extend(isBetween);
dayjs.extend(customParseFormat);
const { durationMinutes, searchRange, workHours } = constraints;
const searchStart = dayjs(searchRange.start);
const searchEnd = dayjs(searchRange.end);
const allBusy = [...cal1, ...cal2]
.map(({ start, end }) => ({ start: dayjs(start), end: dayjs(end) }))
.sort((a, b) => a.start.valueOf() - b.start.valueOf());
const searchStart = parseISO(searchRange.start);
const searchEnd = parseISO(searchRange.end);
const [workStartHour, workStartMin] = workHours.start.split(':').map(Number);
const [workEndHour, workEndMin] = workHours.end.split(':').map(Number);
const workStartMs = (workStartHour * 60 + workStartMin) * 60000;
const workEndMs = (workEndHour * 60 + workEndMin) * 60000;
const allBusy = [...calendar1, ...calendar2]
.map(({ start, end }) => ({ start: parseISO(start), end: parseISO(end) }))
.sort((a, b) => a.start - b.start);
const merged = [];
for (const slot of allBusy) {
if (!merged.length || merged[merged.length - 1].end.isBefore(slot.start)) {
merged.push({ start: slot.start, end: slot.end });
if (merged.length && slot.start <= merged[merged.length - 1].end) {
merged[merged.length - 1].end = new Date(Math.max(merged[merged.length - 1].end, slot.end));
} else {
merged[merged.length - 1].end = dayjs.max(merged[merged.length - 1].end, slot.end);
merged.push({ start: slot.start, end: slot.end });
}
}
const freePeriods = [];
const free = [];
let current = searchStart;
for (const busy of merged) {
if (current.isBefore(busy.start)) {
freePeriods.push({ start: current, end: busy.start });
if (current < busy.start) {
free.push({ start: current, end: busy.start });
}
current = dayjs.max(current, busy.end);
current = new Date(Math.max(current, busy.end));
}
if (current < searchEnd) {
free.push({ start: current, end: searchEnd });
}
if (current.isBefore(searchEnd)) {
freePeriods.push({ start: current, end: searchEnd });
}
const isWithinWorkHours = (slotStart, slotEnd) => {
const date = slotStart.format('YYYY-MM-DD');
const workStart = dayjs(`${date} ${workHours.start}`, 'YYYY-MM-DD HH:mm');
const workEnd = dayjs(`${date} ${workHours.end}`, 'YYYY-MM-DD HH:mm');
return !slotStart.isBefore(workStart) && !slotEnd.isAfter(workEnd);
};
const slots = [];
for (const period of freePeriods) {
for (const period of free) {
let slotStart = period.start;
while (slotStart.add(durationMinutes, 'minute').isSameOrBefore(period.end)) {
const slotEnd = slotStart.add(durationMinutes, 'minute');
while (slotStart < period.end) {
const dayStart = startOfDay(slotStart);
const slotStartMs = slotStart - dayStart;
const slotEnd = addMinutes(slotStart, durationMinutes);
const slotEndMs = slotEnd - dayStart;
if (isWithinWorkHours(slotStart, slotEnd) &&
!slotStart.isBefore(searchStart) &&
!slotEnd.isAfter(searchEnd)) {
if (slotEnd > period.end) break;
const endsNextDay = slotEnd - startOfDay(slotEnd) < slotEndMs % 86400000;
if (!endsNextDay &&
slotStartMs >= workStartMs &&
slotEndMs <= workEndMs &&
slotStart >= searchStart &&
slotEnd <= searchEnd) {
slots.push({
start: slotStart.toISOString(),
end: slotEnd.toISOString()
start: formatISO(slotStart),
end: formatISO(slotEnd)
});
}
slotStart = slotEnd;
}
}
return slots;
};
export default findAvailableSlots;