s3db.js 11.0.4 → 11.0.5
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/package.json
CHANGED
|
@@ -851,18 +851,18 @@ export async function getWeekByDay(resourceName, field, week, options, fieldHand
|
|
|
851
851
|
const year = parseInt(week.substring(0, 4));
|
|
852
852
|
const weekNum = parseInt(week.substring(6, 8));
|
|
853
853
|
|
|
854
|
-
// Calculate the first day of the week (Monday)
|
|
855
|
-
const jan4 = new Date(year, 0, 4);
|
|
856
|
-
const jan4Day = jan4.
|
|
857
|
-
const firstMonday = new Date(year, 0, 4 - jan4Day + 1);
|
|
854
|
+
// Calculate the first day of the week (Monday) using ISO 8601 - use UTC
|
|
855
|
+
const jan4 = new Date(Date.UTC(year, 0, 4));
|
|
856
|
+
const jan4Day = jan4.getUTCDay() || 7; // Sunday = 7
|
|
857
|
+
const firstMonday = new Date(Date.UTC(year, 0, 4 - jan4Day + 1));
|
|
858
858
|
const weekStart = new Date(firstMonday);
|
|
859
|
-
weekStart.
|
|
859
|
+
weekStart.setUTCDate(weekStart.getUTCDate() + (weekNum - 1) * 7);
|
|
860
860
|
|
|
861
861
|
// Get all 7 days of the week
|
|
862
862
|
const days = [];
|
|
863
863
|
for (let i = 0; i < 7; i++) {
|
|
864
864
|
const day = new Date(weekStart);
|
|
865
|
-
day.
|
|
865
|
+
day.setUTCDate(weekStart.getUTCDate() + i);
|
|
866
866
|
days.push(day.toISOString().substring(0, 10));
|
|
867
867
|
}
|
|
868
868
|
|
|
@@ -897,16 +897,16 @@ export async function getWeekByHour(resourceName, field, week, options, fieldHan
|
|
|
897
897
|
const year = parseInt(week.substring(0, 4));
|
|
898
898
|
const weekNum = parseInt(week.substring(6, 8));
|
|
899
899
|
|
|
900
|
-
// Calculate the first day of the week (Monday)
|
|
901
|
-
const jan4 = new Date(year, 0, 4);
|
|
902
|
-
const jan4Day = jan4.
|
|
903
|
-
const firstMonday = new Date(year, 0, 4 - jan4Day + 1);
|
|
900
|
+
// Calculate the first day of the week (Monday) using ISO 8601 - use UTC
|
|
901
|
+
const jan4 = new Date(Date.UTC(year, 0, 4));
|
|
902
|
+
const jan4Day = jan4.getUTCDay() || 7; // Sunday = 7
|
|
903
|
+
const firstMonday = new Date(Date.UTC(year, 0, 4 - jan4Day + 1));
|
|
904
904
|
const weekStart = new Date(firstMonday);
|
|
905
|
-
weekStart.
|
|
905
|
+
weekStart.setUTCDate(weekStart.getUTCDate() + (weekNum - 1) * 7);
|
|
906
906
|
|
|
907
907
|
// Get first and last day of week
|
|
908
908
|
const weekEnd = new Date(weekStart);
|
|
909
|
-
weekEnd.
|
|
909
|
+
weekEnd.setUTCDate(weekEnd.getUTCDate() + 6);
|
|
910
910
|
|
|
911
911
|
const startDate = weekStart.toISOString().substring(0, 10);
|
|
912
912
|
const endDate = weekEnd.toISOString().substring(0, 10);
|
|
@@ -937,21 +937,31 @@ export async function getWeekByHour(resourceName, field, week, options, fieldHan
|
|
|
937
937
|
export async function getLastNHours(resourceName, field, hours = 24, options, fieldHandlers) {
|
|
938
938
|
const now = new Date();
|
|
939
939
|
const hoursAgo = new Date(now);
|
|
940
|
-
hoursAgo.setHours(hoursAgo.getHours() - hours);
|
|
940
|
+
hoursAgo.setHours(hoursAgo.getHours() - hours + 1); // +1 to include current hour
|
|
941
941
|
|
|
942
|
-
const
|
|
943
|
-
const
|
|
942
|
+
const startHour = hoursAgo.toISOString().substring(0, 13); // YYYY-MM-DDTHH
|
|
943
|
+
const endHour = now.toISOString().substring(0, 13);
|
|
944
944
|
|
|
945
945
|
const data = await getAnalytics(resourceName, field, {
|
|
946
946
|
period: 'hour',
|
|
947
|
-
startDate,
|
|
948
|
-
endDate
|
|
947
|
+
startDate: startHour,
|
|
948
|
+
endDate: endHour
|
|
949
949
|
}, fieldHandlers);
|
|
950
950
|
|
|
951
951
|
if (options.fillGaps) {
|
|
952
|
-
|
|
953
|
-
const
|
|
954
|
-
|
|
952
|
+
// For hour-level gaps, we need to manually generate the exact hours requested
|
|
953
|
+
const result = [];
|
|
954
|
+
const emptyRecord = { count: 0, sum: 0, avg: 0, min: 0, max: 0, recordCount: 0 };
|
|
955
|
+
const dataMap = new Map(data.map(d => [d.cohort, d]));
|
|
956
|
+
|
|
957
|
+
const current = new Date(hoursAgo);
|
|
958
|
+
for (let i = 0; i < hours; i++) {
|
|
959
|
+
const cohort = current.toISOString().substring(0, 13);
|
|
960
|
+
result.push(dataMap.get(cohort) || { cohort, ...emptyRecord });
|
|
961
|
+
current.setHours(current.getHours() + 1);
|
|
962
|
+
}
|
|
963
|
+
|
|
964
|
+
return result;
|
|
955
965
|
}
|
|
956
966
|
|
|
957
967
|
return data;
|
|
@@ -1008,7 +1018,7 @@ export async function getLastNWeeks(resourceName, field, weeks = 4, options, fie
|
|
|
1008
1018
|
export async function getLastNMonths(resourceName, field, months = 12, options, fieldHandlers) {
|
|
1009
1019
|
const now = new Date();
|
|
1010
1020
|
const monthsAgo = new Date(now);
|
|
1011
|
-
monthsAgo.setMonth(monthsAgo.getMonth() - months);
|
|
1021
|
+
monthsAgo.setMonth(monthsAgo.getMonth() - months + 1); // +1 to include current month
|
|
1012
1022
|
|
|
1013
1023
|
const startDate = monthsAgo.toISOString().substring(0, 7); // YYYY-MM
|
|
1014
1024
|
const endDate = now.toISOString().substring(0, 7);
|
|
@@ -1020,7 +1030,19 @@ export async function getLastNMonths(resourceName, field, months = 12, options,
|
|
|
1020
1030
|
}, fieldHandlers);
|
|
1021
1031
|
|
|
1022
1032
|
if (options.fillGaps) {
|
|
1023
|
-
|
|
1033
|
+
// Generate exact months requested
|
|
1034
|
+
const result = [];
|
|
1035
|
+
const emptyRecord = { count: 0, sum: 0, avg: 0, min: 0, max: 0, recordCount: 0 };
|
|
1036
|
+
const dataMap = new Map(data.map(d => [d.cohort, d]));
|
|
1037
|
+
|
|
1038
|
+
const current = new Date(monthsAgo);
|
|
1039
|
+
for (let i = 0; i < months; i++) {
|
|
1040
|
+
const cohort = current.toISOString().substring(0, 7);
|
|
1041
|
+
result.push(dataMap.get(cohort) || { cohort, ...emptyRecord });
|
|
1042
|
+
current.setMonth(current.getMonth() + 1);
|
|
1043
|
+
}
|
|
1044
|
+
|
|
1045
|
+
return result;
|
|
1024
1046
|
}
|
|
1025
1047
|
|
|
1026
1048
|
return data;
|
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
runConsolidation
|
|
18
18
|
} from "./consolidation.js";
|
|
19
19
|
import { runGarbageCollection } from "./garbage-collection.js";
|
|
20
|
-
import { updateAnalytics, getAnalytics, getMonthByDay, getDayByHour, getLastNDays, getYearByMonth, getYearByWeek, getMonthByWeek, getMonthByHour, getTopRecords } from "./analytics.js";
|
|
20
|
+
import { updateAnalytics, getAnalytics, getMonthByDay, getDayByHour, getLastNDays, getYearByMonth, getYearByWeek, getMonthByWeek, getMonthByHour, getTopRecords, getYearByDay, getWeekByDay, getWeekByHour, getLastNHours, getLastNWeeks, getLastNMonths } from "./analytics.js";
|
|
21
21
|
import { onInstall, onStart, onStop, watchForResource, completeFieldSetup } from "./install.js";
|
|
22
22
|
|
|
23
23
|
export class EventualConsistencyPlugin extends Plugin {
|
|
@@ -459,6 +459,78 @@ export class EventualConsistencyPlugin extends Plugin {
|
|
|
459
459
|
async getTopRecords(resourceName, field, options = {}) {
|
|
460
460
|
return await getTopRecords(resourceName, field, options, this.fieldHandlers);
|
|
461
461
|
}
|
|
462
|
+
|
|
463
|
+
/**
|
|
464
|
+
* Get analytics for entire year, broken down by days
|
|
465
|
+
* @param {string} resourceName - Resource name
|
|
466
|
+
* @param {string} field - Field name
|
|
467
|
+
* @param {number} year - Year (e.g., 2025)
|
|
468
|
+
* @param {Object} options - Options
|
|
469
|
+
* @returns {Promise<Array>} Daily analytics for the year (up to 365/366 records)
|
|
470
|
+
*/
|
|
471
|
+
async getYearByDay(resourceName, field, year, options = {}) {
|
|
472
|
+
return await getYearByDay(resourceName, field, year, options, this.fieldHandlers);
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
/**
|
|
476
|
+
* Get analytics for entire week, broken down by days
|
|
477
|
+
* @param {string} resourceName - Resource name
|
|
478
|
+
* @param {string} field - Field name
|
|
479
|
+
* @param {string} week - Week in YYYY-Www format (e.g., '2025-W42')
|
|
480
|
+
* @param {Object} options - Options
|
|
481
|
+
* @returns {Promise<Array>} Daily analytics for the week (7 records)
|
|
482
|
+
*/
|
|
483
|
+
async getWeekByDay(resourceName, field, week, options = {}) {
|
|
484
|
+
return await getWeekByDay(resourceName, field, week, options, this.fieldHandlers);
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
/**
|
|
488
|
+
* Get analytics for entire week, broken down by hours
|
|
489
|
+
* @param {string} resourceName - Resource name
|
|
490
|
+
* @param {string} field - Field name
|
|
491
|
+
* @param {string} week - Week in YYYY-Www format (e.g., '2025-W42')
|
|
492
|
+
* @param {Object} options - Options
|
|
493
|
+
* @returns {Promise<Array>} Hourly analytics for the week (168 records)
|
|
494
|
+
*/
|
|
495
|
+
async getWeekByHour(resourceName, field, week, options = {}) {
|
|
496
|
+
return await getWeekByHour(resourceName, field, week, options, this.fieldHandlers);
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
/**
|
|
500
|
+
* Get analytics for last N hours
|
|
501
|
+
* @param {string} resourceName - Resource name
|
|
502
|
+
* @param {string} field - Field name
|
|
503
|
+
* @param {number} hours - Number of hours to look back (default: 24)
|
|
504
|
+
* @param {Object} options - Options
|
|
505
|
+
* @returns {Promise<Array>} Hourly analytics
|
|
506
|
+
*/
|
|
507
|
+
async getLastNHours(resourceName, field, hours = 24, options = {}) {
|
|
508
|
+
return await getLastNHours(resourceName, field, hours, options, this.fieldHandlers);
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
/**
|
|
512
|
+
* Get analytics for last N weeks
|
|
513
|
+
* @param {string} resourceName - Resource name
|
|
514
|
+
* @param {string} field - Field name
|
|
515
|
+
* @param {number} weeks - Number of weeks to look back (default: 4)
|
|
516
|
+
* @param {Object} options - Options
|
|
517
|
+
* @returns {Promise<Array>} Weekly analytics
|
|
518
|
+
*/
|
|
519
|
+
async getLastNWeeks(resourceName, field, weeks = 4, options = {}) {
|
|
520
|
+
return await getLastNWeeks(resourceName, field, weeks, options, this.fieldHandlers);
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
/**
|
|
524
|
+
* Get analytics for last N months
|
|
525
|
+
* @param {string} resourceName - Resource name
|
|
526
|
+
* @param {string} field - Field name
|
|
527
|
+
* @param {number} months - Number of months to look back (default: 12)
|
|
528
|
+
* @param {Object} options - Options
|
|
529
|
+
* @returns {Promise<Array>} Monthly analytics
|
|
530
|
+
*/
|
|
531
|
+
async getLastNMonths(resourceName, field, months = 12, options = {}) {
|
|
532
|
+
return await getLastNMonths(resourceName, field, months, options, this.fieldHandlers);
|
|
533
|
+
}
|
|
462
534
|
}
|
|
463
535
|
|
|
464
536
|
export default EventualConsistencyPlugin;
|