@fuzdev/fuz_ui 0.208.0 → 0.209.0

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.
@@ -1,153 +0,0 @@
1
- /**
2
- * Types and pure helpers for project commit-activity stats.
3
- *
4
- * The committed dataset (`project_stats_data.ts`, written by the
5
- * `project_stats_update` task) stores daily commit counts per project as the
6
- * master granularity; coarser scopes like monthly are derived at runtime by
7
- * rebucketing. All date handling is UTC — `YYYY-MM-DD` strings and "epoch
8
- * days" (days since the Unix epoch) — so results are deterministic across
9
- * machines.
10
- *
11
- * @module
12
- */
13
- const DAY_MS = 86_400_000;
14
- /**
15
- * Converts a UTC `YYYY-MM-DD` date to days since the Unix epoch.
16
- */
17
- export const epoch_day_from_date = (date) => {
18
- const [year, month, day] = date.split('-').map(Number);
19
- return Date.UTC(year, month - 1, day) / DAY_MS;
20
- };
21
- /**
22
- * Converts days since the Unix epoch to a UTC `YYYY-MM-DD` date.
23
- */
24
- export const date_from_epoch_day = (epoch_day) => new Date(epoch_day * DAY_MS).toISOString().slice(0, 10);
25
- /**
26
- * Buckets commit timestamps into daily counts from the earliest commit's UTC
27
- * day through `end_date`, inclusive.
28
- *
29
- * @param timestamps - commit times as Unix epoch seconds
30
- * @param end_date - UTC date (`YYYY-MM-DD`) of the final bucket; later timestamps clamp into it
31
- * @returns the start date and daily counts, or `null` if `timestamps` is empty
32
- */
33
- export const daily_counts_from_timestamps = (timestamps, end_date) => {
34
- if (timestamps.length === 0)
35
- return null;
36
- const days = timestamps.map((t) => Math.floor((t * 1000) / DAY_MS));
37
- const end_day = epoch_day_from_date(end_date);
38
- let start_day = end_day;
39
- for (const day of days) {
40
- if (day < start_day)
41
- start_day = day;
42
- }
43
- const daily_counts = new Array(end_day - start_day + 1).fill(0);
44
- for (const day of days) {
45
- daily_counts[Math.min(day, end_day) - start_day] += 1;
46
- }
47
- return { start_date: date_from_epoch_day(start_day), daily_counts };
48
- };
49
- /**
50
- * Pads `daily_counts` with leading zeros so the series starts at
51
- * `padded_start_date` instead of `start_date`.
52
- *
53
- * Returns the input array unchanged when `padded_start_date` is not earlier
54
- * than `start_date`.
55
- */
56
- export const daily_counts_pad_start = (daily_counts, start_date, padded_start_date) => {
57
- const pad = epoch_day_from_date(start_date) - epoch_day_from_date(padded_start_date);
58
- if (pad <= 0)
59
- return daily_counts;
60
- return new Array(pad).fill(0).concat(daily_counts);
61
- };
62
- /**
63
- * Rebuckets daily counts into calendar-month (UTC) counts.
64
- *
65
- * The first and last buckets may cover partial months.
66
- */
67
- export const monthly_counts_from_daily = (daily_counts, start_date) => {
68
- const start_day = epoch_day_from_date(start_date);
69
- const counts = [];
70
- let current_month_key = null;
71
- for (let i = 0; i < daily_counts.length; i++) {
72
- const date = new Date((start_day + i) * DAY_MS);
73
- const month_key = date.getUTCFullYear() * 12 + date.getUTCMonth();
74
- if (month_key !== current_month_key) {
75
- current_month_key = month_key;
76
- counts.push(0);
77
- }
78
- counts[counts.length - 1] += daily_counts[i];
79
- }
80
- return counts;
81
- };
82
- /**
83
- * Rebuckets daily counts into 7-day counts, anchored at the end of the series
84
- * so the newest bucket always covers a full 7 days.
85
- *
86
- * The first bucket may cover fewer days when the length isn't a multiple of 7.
87
- */
88
- export const weekly_counts_from_daily = (daily_counts) => {
89
- const counts = [];
90
- for (let end = daily_counts.length; end > 0; end -= 7) {
91
- let sum = 0;
92
- for (let i = Math.max(0, end - 7); i < end; i++) {
93
- sum += daily_counts[i];
94
- }
95
- counts.push(sum);
96
- }
97
- return counts.reverse();
98
- };
99
- const to_aligned_series = (snapshot, rebucket) => {
100
- if (snapshot.projects.length === 0)
101
- return { series: [], max: 0 };
102
- let shared_start = snapshot.projects[0].start_date;
103
- for (const project of snapshot.projects) {
104
- if (project.start_date < shared_start)
105
- shared_start = project.start_date;
106
- }
107
- let max = 0;
108
- const series = snapshot.projects.map((project) => {
109
- const daily = daily_counts_pad_start(project.daily_counts, project.start_date, shared_start);
110
- const counts = rebucket(daily, shared_start);
111
- for (const count of counts) {
112
- if (count > max)
113
- max = count;
114
- }
115
- return { name: project.name, counts };
116
- });
117
- return { series, max };
118
- };
119
- /**
120
- * Derives aligned monthly series for every project in `snapshot`, sharing one
121
- * time window and one scale.
122
- *
123
- * Each series spans from the earliest project's `start_date` through the
124
- * snapshot's `end_date` (younger projects are zero-padded at the front), so
125
- * all series have the same length and bucket boundaries. `max` is the largest
126
- * monthly count across all projects, for rendering every series at the same
127
- * vertical scale.
128
- */
129
- export const project_stats_to_monthly_series = (snapshot) => to_aligned_series(snapshot, monthly_counts_from_daily);
130
- /**
131
- * Derives aligned weekly series for every project in `snapshot`, sharing one
132
- * time window and one scale — the weekly sibling of
133
- * `project_stats_to_monthly_series`.
134
- */
135
- export const project_stats_to_weekly_series = (snapshot) => to_aligned_series(snapshot, weekly_counts_from_daily);
136
- const start_date_formatter = new Intl.DateTimeFormat('en-US', {
137
- month: 'long',
138
- day: 'numeric',
139
- year: 'numeric',
140
- timeZone: 'UTC'
141
- });
142
- /**
143
- * Formats a one-line human-readable summary of a project's commit stats,
144
- * e.g. `"gro — 2,386 commits since August 7, 2019"`. Used for accessible
145
- * labels and tooltips.
146
- */
147
- export const project_stats_label = (project) => {
148
- let total = 0;
149
- for (const count of project.daily_counts) {
150
- total += count;
151
- }
152
- return `${project.name} — ${total.toLocaleString('en-US')} commits since ${start_date_formatter.format(new Date(project.start_date))}`;
153
- };
@@ -1,3 +0,0 @@
1
- import type { ProjectStatsSnapshot } from './project_stats.js';
2
- export declare const project_stats_data: ProjectStatsSnapshot;
3
- //# sourceMappingURL=project_stats_data.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"project_stats_data.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/project_stats_data.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAE/D,eAAO,MAAM,kBAAkB,EAAE,oBA0dhC,CAAC"}