lduck 0.0.5 → 0.0.6

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/index.js CHANGED
@@ -631,8 +631,12 @@ class LogDatabase {
631
631
  const rangeStartMs = Math.min(startTime.getTime(), endTime.getTime());
632
632
  const rangeEndMs = Math.max(startTime.getTime(), endTime.getTime());
633
633
  const spanMs = Math.max(1e3, rangeEndMs - rangeStartMs);
634
- const intervalMs = Math.max(1e3, Math.floor(spanMs / buckets));
635
- const interval = intervalMsToIntervalString(intervalMs);
634
+ const rawIntervalMs = Math.max(1e3, Math.floor(spanMs / buckets));
635
+ const interval = intervalMsToIntervalString(rawIntervalMs);
636
+ const normalizedMs = normalizeIntervalMs(rawIntervalMs);
637
+ const actualBuckets = Math.ceil(spanMs / normalizedMs);
638
+ const alignedStart = Math.floor(rangeStartMs / normalizedMs) * normalizedMs;
639
+ const origin = new Date(alignedStart).toISOString();
636
640
  const conditions = buildFilterConditions({
637
641
  ...params,
638
642
  startTime: new Date(rangeStartMs),
@@ -643,7 +647,7 @@ class LogDatabase {
643
647
  const whereClause = `WHERE ${conditions.join(" AND ")}`;
644
648
  const reader = await conn.runAndReadAll(
645
649
  `SELECT
646
- time_bucket(INTERVAL '${interval}', timestamp) AS bucket,
650
+ time_bucket(INTERVAL '${interval}', timestamp, TIMESTAMP '${origin}') AS bucket,
647
651
  UPPER(level) AS lvl,
648
652
  COUNT(*) AS cnt
649
653
  FROM logs
@@ -660,9 +664,8 @@ class LogDatabase {
660
664
  current[level] = count;
661
665
  countsByBucket.set(bucketIso, current);
662
666
  }
663
- const alignedStart = Math.floor(rangeStartMs / intervalMs) * intervalMs;
664
- const histogramBuckets = Array.from({ length: buckets }, (_, i) => {
665
- const timestamp = new Date(alignedStart + i * intervalMs).toISOString();
667
+ const histogramBuckets = Array.from({ length: actualBuckets }, (_, i) => {
668
+ const timestamp = new Date(alignedStart + i * normalizedMs).toISOString();
666
669
  return {
667
670
  timestamp,
668
671
  counts: countsByBucket.get(timestamp) ?? {}
@@ -795,6 +798,27 @@ function intervalMsToIntervalString(intervalMs) {
795
798
  const seconds = Math.max(1, Math.floor(intervalMs / secondMs));
796
799
  return `${seconds} ${seconds === 1 ? "second" : "seconds"}`;
797
800
  }
801
+ function normalizeIntervalMs(intervalMs) {
802
+ const interval = intervalMsToIntervalString(intervalMs);
803
+ const match = interval.match(/^(\d+)\s+(\w+)$/);
804
+ if (!match) return intervalMs;
805
+ const value = parseInt(match[1], 10);
806
+ const unit = match[2].replace(/s$/, "");
807
+ switch (unit) {
808
+ case "day":
809
+ return value * 24 * 60 * 60 * 1e3;
810
+ case "hour":
811
+ return value * 60 * 60 * 1e3;
812
+ case "minute":
813
+ return value * 60 * 1e3;
814
+ case "second":
815
+ return value * 1e3;
816
+ case "millisecond":
817
+ return value;
818
+ default:
819
+ return intervalMs;
820
+ }
821
+ }
798
822
  function appendNullableVarchar(appender, value) {
799
823
  if (value !== null) {
800
824
  appender.appendVarchar(value);