@fuzdev/fuz_ui 0.206.7 → 0.206.9
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/README.md +3 -3
- package/dist/Alert.svelte +21 -25
- package/dist/Alert.svelte.d.ts.map +1 -1
- package/dist/ApiDeclarationList.svelte +2 -2
- package/dist/ApiDeclarationList.svelte.d.ts.map +1 -1
- package/dist/ApiIndex.svelte +4 -4
- package/dist/ApiIndex.svelte.d.ts.map +1 -1
- package/dist/ApiModule.svelte +13 -10
- package/dist/ApiModule.svelte.d.ts.map +1 -1
- package/dist/ApiModulesList.svelte +2 -2
- package/dist/ApiModulesList.svelte.d.ts.map +1 -1
- package/dist/Breadcrumb.svelte +31 -19
- package/dist/Breadcrumb.svelte.d.ts.map +1 -1
- package/dist/Card.svelte +17 -17
- package/dist/Card.svelte.d.ts.map +1 -1
- package/dist/ColorSchemeInput.svelte +6 -6
- package/dist/ColorSchemeInput.svelte.d.ts.map +1 -1
- package/dist/Contextmenu.svelte +6 -4
- package/dist/Contextmenu.svelte.d.ts.map +1 -1
- package/dist/ContextmenuEntry.svelte +8 -8
- package/dist/ContextmenuEntry.svelte.d.ts.map +1 -1
- package/dist/ContextmenuIcon.svelte +3 -3
- package/dist/ContextmenuIcon.svelte.d.ts.map +1 -1
- package/dist/ContextmenuLinkEntry.svelte +14 -14
- package/dist/ContextmenuLinkEntry.svelte.d.ts.map +1 -1
- package/dist/ContextmenuMenu.svelte +10 -10
- package/dist/ContextmenuMenu.svelte.d.ts.map +1 -1
- package/dist/ContextmenuRoot.svelte +7 -7
- package/dist/ContextmenuRootForSafariCompatibility.svelte +15 -15
- package/dist/ContextmenuSeparator.svelte +2 -2
- package/dist/ContextmenuSubmenu.svelte +15 -12
- package/dist/ContextmenuSubmenu.svelte.d.ts.map +1 -1
- package/dist/ContextmenuTextEntry.svelte +4 -4
- package/dist/ContextmenuTextEntry.svelte.d.ts.map +1 -1
- package/dist/CopyToClipboard.svelte +7 -7
- package/dist/CopyToClipboard.svelte.d.ts.map +1 -1
- package/dist/DeclarationDetail.svelte +35 -28
- package/dist/DeclarationDetail.svelte.d.ts.map +1 -1
- package/dist/DeclarationLink.svelte +7 -7
- package/dist/DeclarationLink.svelte.d.ts.map +1 -1
- package/dist/Details.svelte +3 -3
- package/dist/Details.svelte.d.ts.map +1 -1
- package/dist/Dialog.svelte +7 -7
- package/dist/Dialog.svelte.d.ts.map +1 -1
- package/dist/DialogContent.svelte +6 -6
- package/dist/DialogContent.svelte.d.ts.map +1 -1
- package/dist/Docs.svelte +14 -12
- package/dist/Docs.svelte.d.ts.map +1 -1
- package/dist/DocsContent.svelte +4 -4
- package/dist/DocsContent.svelte.d.ts.map +1 -1
- package/dist/DocsFooter.svelte +7 -8
- package/dist/DocsFooter.svelte.d.ts.map +1 -1
- package/dist/DocsLink.svelte +24 -21
- package/dist/DocsLink.svelte.d.ts.map +1 -1
- package/dist/DocsList.svelte +3 -3
- package/dist/DocsList.svelte.d.ts.map +1 -1
- package/dist/DocsMenu.svelte +13 -10
- package/dist/DocsMenu.svelte.d.ts.map +1 -1
- package/dist/DocsMenuHeader.svelte +2 -2
- package/dist/DocsMenuHeader.svelte.d.ts.map +1 -1
- package/dist/DocsPageLinks.svelte +9 -7
- package/dist/DocsPageLinks.svelte.d.ts.map +1 -1
- package/dist/DocsPrimaryNav.svelte +5 -5
- package/dist/DocsPrimaryNav.svelte.d.ts.map +1 -1
- package/dist/DocsSearch.svelte +3 -3
- package/dist/DocsSearch.svelte.d.ts.map +1 -1
- package/dist/DocsSecondaryNav.svelte +3 -3
- package/dist/DocsSecondaryNav.svelte.d.ts.map +1 -1
- package/dist/DocsTertiaryNav.svelte +8 -8
- package/dist/DocsTertiaryNav.svelte.d.ts.map +1 -1
- package/dist/EcosystemLinks.svelte +3 -3
- package/dist/EcosystemLinks.svelte.d.ts.map +1 -1
- package/dist/EcosystemLinksPanel.svelte +2 -2
- package/dist/EcosystemLinksPanel.svelte.d.ts.map +1 -1
- package/dist/GithubLink.svelte +10 -10
- package/dist/GithubLink.svelte.d.ts.map +1 -1
- package/dist/Glyph.svelte +4 -2
- package/dist/Glyph.svelte.d.ts.map +1 -1
- package/dist/Hashlink.svelte +5 -5
- package/dist/Hashlink.svelte.d.ts.map +1 -1
- package/dist/HueInput.svelte +5 -5
- package/dist/HueInput.svelte.d.ts.map +1 -1
- package/dist/ImgOrSvg.svelte +20 -20
- package/dist/ImgOrSvg.svelte.d.ts.map +1 -1
- package/dist/LibraryDetail.svelte +16 -16
- package/dist/LibraryDetail.svelte.d.ts.map +1 -1
- package/dist/LibrarySummary.svelte +10 -8
- package/dist/LibrarySummary.svelte.d.ts.map +1 -1
- package/dist/MdnLink.svelte +8 -8
- package/dist/MdnLink.svelte.d.ts.map +1 -1
- package/dist/ModuleLink.svelte +5 -5
- package/dist/ModuleLink.svelte.d.ts.map +1 -1
- package/dist/PasteFromClipboard.svelte +1 -1
- package/dist/PasteFromClipboard.svelte.d.ts.map +1 -1
- package/dist/PendingAnimation.svelte +12 -11
- package/dist/PendingAnimation.svelte.d.ts.map +1 -1
- package/dist/PendingButton.svelte +3 -3
- package/dist/PendingButton.svelte.d.ts.map +1 -1
- package/dist/ProjectActivityChart.svelte +137 -0
- package/dist/ProjectActivityChart.svelte.d.ts +30 -0
- package/dist/ProjectActivityChart.svelte.d.ts.map +1 -0
- package/dist/ProjectLinks.svelte +29 -48
- package/dist/ProjectLinks.svelte.d.ts.map +1 -1
- package/dist/Redirect.svelte +12 -8
- package/dist/Redirect.svelte.d.ts.map +1 -1
- package/dist/Sparkline.svelte +131 -0
- package/dist/Sparkline.svelte.d.ts +42 -0
- package/dist/Sparkline.svelte.d.ts.map +1 -0
- package/dist/Spiders.svelte +5 -5
- package/dist/Spiders.svelte.d.ts.map +1 -1
- package/dist/StyleVariableButton.svelte +6 -6
- package/dist/StyleVariableButton.svelte.d.ts.map +1 -1
- package/dist/Svg.svelte +5 -5
- package/dist/Svg.svelte.d.ts.map +1 -1
- package/dist/Teleport.svelte +2 -2
- package/dist/Teleport.svelte.d.ts.map +1 -1
- package/dist/ThemeInput.svelte +10 -8
- package/dist/ThemeInput.svelte.d.ts.map +1 -1
- package/dist/ThemeRoot.svelte +10 -11
- package/dist/ThemeRoot.svelte.d.ts.map +1 -1
- package/dist/TomeContent.svelte +11 -11
- package/dist/TomeContent.svelte.d.ts.map +1 -1
- package/dist/TomeHeader.svelte +6 -6
- package/dist/TomeLink.svelte +7 -7
- package/dist/TomeLink.svelte.d.ts.map +1 -1
- package/dist/TomeSection.svelte +8 -8
- package/dist/TomeSection.svelte.d.ts.map +1 -1
- package/dist/TomeSectionHeader.svelte +12 -12
- package/dist/TomeSectionHeader.svelte.d.ts.map +1 -1
- package/dist/TypeLink.svelte +11 -11
- package/dist/TypeLink.svelte.d.ts.map +1 -1
- package/dist/alert.js +1 -1
- package/dist/api_search.svelte.d.ts.map +1 -1
- package/dist/api_search.svelte.js +5 -7
- package/dist/autofocus.svelte.d.ts.map +1 -1
- package/dist/context_helpers.js +1 -1
- package/dist/contextmenu_helpers.d.ts.map +1 -1
- package/dist/contextmenu_helpers.js +3 -3
- package/dist/contextmenu_state.svelte.d.ts.map +1 -1
- package/dist/contextmenu_state.svelte.js +4 -4
- package/dist/csp.d.ts.map +1 -1
- package/dist/csp.js +27 -27
- package/dist/csp_of_fuzdev.d.ts.map +1 -1
- package/dist/csp_of_fuzdev.js +1 -1
- package/dist/declaration.svelte.d.ts +44 -256
- package/dist/declaration.svelte.d.ts.map +1 -1
- package/dist/declaration.svelte.js +132 -52
- package/dist/declaration_contextmenu.d.ts.map +1 -1
- package/dist/declaration_contextmenu.js +2 -2
- package/dist/docs_helpers.svelte.d.ts.map +1 -1
- package/dist/icons.js +200 -200
- package/dist/intersect.svelte.d.ts.map +1 -1
- package/dist/library.svelte.d.ts +31 -18
- package/dist/library.svelte.d.ts.map +1 -1
- package/dist/library.svelte.js +76 -21
- package/dist/logos.js +42 -42
- package/dist/module.svelte.d.ts +30 -37
- package/dist/module.svelte.d.ts.map +1 -1
- package/dist/module.svelte.js +88 -35
- package/dist/module_contextmenu.d.ts.map +1 -1
- package/dist/module_contextmenu.js +2 -2
- package/dist/project_stats.d.ts +121 -0
- package/dist/project_stats.d.ts.map +1 -0
- package/dist/project_stats.js +153 -0
- package/dist/project_stats_data.d.ts +3 -0
- package/dist/project_stats_data.d.ts.map +1 -0
- package/dist/project_stats_data.js +469 -0
- package/dist/project_stats_update.task.d.ts +4 -0
- package/dist/project_stats_update.task.d.ts.map +1 -0
- package/dist/project_stats_update.task.js +50 -0
- package/dist/projects.d.ts +17 -0
- package/dist/projects.d.ts.map +1 -0
- package/dist/projects.js +20 -0
- package/dist/publish.task.d.ts +3 -0
- package/dist/publish.task.d.ts.map +1 -0
- package/dist/publish.task.js +23 -0
- package/dist/site.svelte.d.ts.map +1 -1
- package/dist/sparkline.d.ts +102 -0
- package/dist/sparkline.d.ts.map +1 -0
- package/dist/sparkline.js +63 -0
- package/dist/style_variable_helpers.svelte.d.ts.map +1 -1
- package/dist/svg.d.ts.map +1 -1
- package/dist/theme_state.svelte.d.ts.map +1 -1
- package/dist/theme_state.svelte.js +1 -1
- package/dist/tome.d.ts.map +1 -1
- package/dist/tome.js +1 -1
- package/dist/vite_plugin_pkg_json.d.ts.map +1 -1
- package/dist/vite_plugin_pkg_json.js +1 -1
- package/package.json +3 -22
- package/src/lib/alert.ts +3 -3
- package/src/lib/api_search.svelte.ts +9 -11
- package/src/lib/autofocus.svelte.ts +2 -2
- package/src/lib/context_helpers.ts +2 -2
- package/src/lib/contextmenu_helpers.ts +21 -21
- package/src/lib/contextmenu_state.svelte.ts +32 -34
- package/src/lib/csp.ts +42 -54
- package/src/lib/csp_of_fuzdev.ts +2 -2
- package/src/lib/declaration.svelte.ts +157 -62
- package/src/lib/declaration_contextmenu.ts +5 -5
- package/src/lib/dialog.ts +1 -1
- package/src/lib/docs_helpers.svelte.ts +9 -9
- package/src/lib/icons.ts +205 -205
- package/src/lib/intersect.svelte.ts +5 -5
- package/src/lib/library.svelte.ts +103 -36
- package/src/lib/library_helpers.ts +2 -2
- package/src/lib/logos.ts +43 -43
- package/src/lib/module.svelte.ts +98 -49
- package/src/lib/module_contextmenu.ts +4 -4
- package/src/lib/project_stats.ts +220 -0
- package/src/lib/project_stats_data.ts +472 -0
- package/src/lib/project_stats_update.task.ts +53 -0
- package/src/lib/projects.ts +49 -0
- package/src/lib/publish.task.ts +22 -0
- package/src/lib/site.svelte.ts +5 -5
- package/src/lib/sparkline.ts +173 -0
- package/src/lib/storage.ts +2 -2
- package/src/lib/style_variable_helpers.svelte.ts +2 -2
- package/src/lib/svg.ts +2 -2
- package/src/lib/theme_state.svelte.ts +8 -8
- package/src/lib/tome.ts +8 -8
- package/src/lib/vite_plugin_pkg_json.ts +8 -8
package/dist/module.svelte.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { EMPTY_ARRAY } from '@fuzdev/fuz_util/array.ts';
|
|
1
2
|
import { Declaration } from './declaration.svelte.js';
|
|
2
3
|
import { url_github_file } from '@fuzdev/fuz_util/package_helpers.ts';
|
|
3
4
|
/**
|
|
@@ -20,8 +21,11 @@ const group_sorted = (entries, get_key) => {
|
|
|
20
21
|
/**
|
|
21
22
|
* Rich runtime representation of a module with computed properties.
|
|
22
23
|
*
|
|
23
|
-
* Wraps svelte-docinfo's `ModuleJson` with
|
|
24
|
-
*
|
|
24
|
+
* Wraps svelte-docinfo's `ModuleJson` with computed properties, URL
|
|
25
|
+
* generation, and `Declaration` instances.
|
|
26
|
+
*
|
|
27
|
+
* Computed properties are plain getters rather than `$derived` — see
|
|
28
|
+
* `Library` for why.
|
|
25
29
|
*
|
|
26
30
|
* @see {@link https://github.com/ryanatkn/svelte-docinfo svelte-docinfo} for the analysis library
|
|
27
31
|
* @see `declaration.svelte.ts` for the `Declaration` wrapper class
|
|
@@ -44,102 +48,151 @@ export class Module {
|
|
|
44
48
|
* A leading `./` or a `.js` runtime extension will not match. Top-level
|
|
45
49
|
* files match by bare filename; nested files require the full sub-path.
|
|
46
50
|
*/
|
|
47
|
-
path
|
|
51
|
+
get path() {
|
|
52
|
+
return this.module_json.path;
|
|
53
|
+
}
|
|
48
54
|
/**
|
|
49
55
|
* Import-style path with ./ prefix.
|
|
50
56
|
*/
|
|
51
|
-
path_import
|
|
52
|
-
|
|
57
|
+
get path_import() {
|
|
58
|
+
return './' + this.path;
|
|
59
|
+
}
|
|
60
|
+
get module_comment() {
|
|
61
|
+
return this.module_json.moduleComment;
|
|
62
|
+
}
|
|
63
|
+
#declarations;
|
|
53
64
|
/**
|
|
54
65
|
* Array of `Declaration` instances. Filters out default exports.
|
|
55
66
|
*/
|
|
56
|
-
declarations
|
|
57
|
-
|
|
58
|
-
|
|
67
|
+
get declarations() {
|
|
68
|
+
return (this.#declarations ??= (this.module_json.declarations ?? [])
|
|
69
|
+
.filter((declaration_json) => declaration_json.name !== 'default')
|
|
70
|
+
.map((declaration_json) => new Declaration(this, declaration_json)));
|
|
71
|
+
}
|
|
59
72
|
/**
|
|
60
73
|
* API documentation URL for this module.
|
|
61
74
|
*/
|
|
62
|
-
url_api
|
|
75
|
+
get url_api() {
|
|
76
|
+
return `/docs/api${this.library.url_prefix}/${this.path}`;
|
|
77
|
+
}
|
|
63
78
|
/**
|
|
64
79
|
* Public documentation link (if `homepage_url` is available).
|
|
65
80
|
*
|
|
66
81
|
* Absolute URL into the library's own deployed docs, for rendering a
|
|
67
82
|
* foreign library's modules on a different site (e.g. an aggregator).
|
|
68
83
|
*/
|
|
69
|
-
url_api_full
|
|
70
|
-
|
|
71
|
-
: undefined
|
|
84
|
+
get url_api_full() {
|
|
85
|
+
const { homepage_url } = this.library;
|
|
86
|
+
return homepage_url ? `${homepage_url.replace(/\/$/, '')}/docs/api/${this.path}` : undefined;
|
|
87
|
+
}
|
|
72
88
|
/**
|
|
73
89
|
* GitHub source URL.
|
|
74
90
|
*/
|
|
75
|
-
url_github
|
|
76
|
-
|
|
77
|
-
: undefined
|
|
91
|
+
get url_github() {
|
|
92
|
+
const { repo_url } = this.library;
|
|
93
|
+
return repo_url ? url_github_file(repo_url, `src/lib/${this.path}`) : undefined;
|
|
94
|
+
}
|
|
78
95
|
/**
|
|
79
96
|
* Whether the module has renderable declarations (after the default-export
|
|
80
97
|
* filter in `declarations`).
|
|
81
98
|
*/
|
|
82
|
-
has_declarations
|
|
83
|
-
|
|
99
|
+
get has_declarations() {
|
|
100
|
+
return this.declarations.length > 0;
|
|
101
|
+
}
|
|
102
|
+
get has_module_comment() {
|
|
103
|
+
return !!this.module_comment;
|
|
104
|
+
}
|
|
84
105
|
/**
|
|
85
106
|
* Modules this imports (paths relative to src/lib).
|
|
86
107
|
*/
|
|
87
|
-
dependencies
|
|
108
|
+
get dependencies() {
|
|
109
|
+
return this.module_json.dependencies ?? EMPTY_ARRAY;
|
|
110
|
+
}
|
|
88
111
|
/**
|
|
89
112
|
* Modules that import this (paths relative to src/lib).
|
|
90
113
|
*/
|
|
91
|
-
dependents
|
|
92
|
-
|
|
93
|
-
|
|
114
|
+
get dependents() {
|
|
115
|
+
return this.module_json.dependents ?? EMPTY_ARRAY;
|
|
116
|
+
}
|
|
117
|
+
get has_dependencies() {
|
|
118
|
+
return this.dependencies.length > 0;
|
|
119
|
+
}
|
|
120
|
+
get has_dependents() {
|
|
121
|
+
return this.dependents.length > 0;
|
|
122
|
+
}
|
|
94
123
|
/**
|
|
95
124
|
* Same-name re-export edges in this module's source (`ModuleJson.reExports`)
|
|
96
125
|
* — the forward view of declarations' `alsoExportedFrom`, sorted by name
|
|
97
126
|
* then module. Renamed re-exports appear as declarations with `aliasOf`
|
|
98
127
|
* instead, and star exports in `star_exports`.
|
|
99
128
|
*/
|
|
100
|
-
re_exports
|
|
101
|
-
|
|
129
|
+
get re_exports() {
|
|
130
|
+
return this.module_json.reExports ?? EMPTY_ARRAY;
|
|
131
|
+
}
|
|
132
|
+
get has_re_exports() {
|
|
133
|
+
return this.re_exports.length > 0;
|
|
134
|
+
}
|
|
102
135
|
/**
|
|
103
136
|
* Modules fully re-exported via `export * from './module'`
|
|
104
137
|
* (`ModuleJson.starExports`), in source order. Star-projected symbols are
|
|
105
138
|
* not materialized as declarations or `re_exports` edges — this is their
|
|
106
139
|
* sole encoding.
|
|
107
140
|
*/
|
|
108
|
-
star_exports
|
|
109
|
-
|
|
141
|
+
get star_exports() {
|
|
142
|
+
return this.module_json.starExports ?? EMPTY_ARRAY;
|
|
143
|
+
}
|
|
144
|
+
get has_star_exports() {
|
|
145
|
+
return this.star_exports.length > 0;
|
|
146
|
+
}
|
|
147
|
+
#re_exports_by_module;
|
|
110
148
|
/**
|
|
111
149
|
* Re-export edges grouped by canonical module path, groups sorted by path.
|
|
112
150
|
* Entries within each group keep their name-sorted serialized order.
|
|
113
151
|
*/
|
|
114
|
-
re_exports_by_module
|
|
152
|
+
get re_exports_by_module() {
|
|
153
|
+
return (this.#re_exports_by_module ??= group_sorted(this.re_exports, (entry) => entry.module));
|
|
154
|
+
}
|
|
115
155
|
/**
|
|
116
156
|
* Re-exports whose immediate target is an external package
|
|
117
157
|
* (`ModuleJson.externalReExports`) — `export {x} from 'pkg'` and
|
|
118
158
|
* `export * as ns from 'pkg'` forms, sorted by name then specifier.
|
|
119
159
|
*/
|
|
120
|
-
external_re_exports
|
|
121
|
-
|
|
160
|
+
get external_re_exports() {
|
|
161
|
+
return this.module_json.externalReExports ?? EMPTY_ARRAY;
|
|
162
|
+
}
|
|
163
|
+
get has_external_re_exports() {
|
|
164
|
+
return this.external_re_exports.length > 0;
|
|
165
|
+
}
|
|
166
|
+
#external_re_exports_by_specifier;
|
|
122
167
|
/**
|
|
123
168
|
* External re-exports grouped by package specifier, groups sorted by
|
|
124
169
|
* specifier. Entries within each group keep their name-sorted serialized
|
|
125
170
|
* order.
|
|
126
171
|
*/
|
|
127
|
-
external_re_exports_by_specifier
|
|
172
|
+
get external_re_exports_by_specifier() {
|
|
173
|
+
return (this.#external_re_exports_by_specifier ??= group_sorted(this.external_re_exports, (entry) => entry.specifier));
|
|
174
|
+
}
|
|
128
175
|
/**
|
|
129
176
|
* External packages fully re-exported via `export * from 'pkg'`
|
|
130
177
|
* (`ModuleJson.externalStarExports`), in source order. The projected
|
|
131
178
|
* names are unknown — the package isn't analyzed.
|
|
132
179
|
*/
|
|
133
|
-
external_star_exports
|
|
134
|
-
|
|
180
|
+
get external_star_exports() {
|
|
181
|
+
return this.module_json.externalStarExports ?? EMPTY_ARRAY;
|
|
182
|
+
}
|
|
183
|
+
get has_external_star_exports() {
|
|
184
|
+
return this.external_star_exports.length > 0;
|
|
185
|
+
}
|
|
135
186
|
/**
|
|
136
187
|
* Whether the module re-exports anything in any form — same-name edges,
|
|
137
188
|
* star exports, or the external variants of both.
|
|
138
189
|
*/
|
|
139
|
-
has_any_re_exports
|
|
140
|
-
this.
|
|
141
|
-
|
|
142
|
-
|
|
190
|
+
get has_any_re_exports() {
|
|
191
|
+
return (this.has_re_exports ||
|
|
192
|
+
this.has_star_exports ||
|
|
193
|
+
this.has_external_re_exports ||
|
|
194
|
+
this.has_external_star_exports);
|
|
195
|
+
}
|
|
143
196
|
constructor(library, module_json) {
|
|
144
197
|
this.library = library;
|
|
145
198
|
this.module_json = module_json;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"module_contextmenu.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/module_contextmenu.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"module_contextmenu.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/module_contextmenu.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAIvE,eAAO,MAAM,yBAAyB,GAAI,QAAQ,MAAM,KAAG,KAAK,CAAC,iBAAiB,CAcjF,CAAC"}
|
|
@@ -0,0 +1,121 @@
|
|
|
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
|
+
/**
|
|
14
|
+
* Daily commit counts for one project.
|
|
15
|
+
*/
|
|
16
|
+
export interface ProjectCommitStats {
|
|
17
|
+
/**
|
|
18
|
+
* Project name, matching `project_items`.
|
|
19
|
+
*/
|
|
20
|
+
name: string;
|
|
21
|
+
/**
|
|
22
|
+
* UTC date (`YYYY-MM-DD`) of the first day bucket, the day of the first commit.
|
|
23
|
+
*/
|
|
24
|
+
start_date: string;
|
|
25
|
+
/**
|
|
26
|
+
* Commits per UTC day from `start_date` through the snapshot's `end_date`, inclusive.
|
|
27
|
+
*/
|
|
28
|
+
daily_counts: Array<number>;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* A snapshot of commit stats across projects, sharing a single `end_date`.
|
|
32
|
+
*/
|
|
33
|
+
export interface ProjectStatsSnapshot {
|
|
34
|
+
/**
|
|
35
|
+
* ISO datetime when the snapshot was collected.
|
|
36
|
+
*/
|
|
37
|
+
generated_at: string;
|
|
38
|
+
/**
|
|
39
|
+
* UTC date (`YYYY-MM-DD`) of the final day bucket, shared by every project.
|
|
40
|
+
*/
|
|
41
|
+
end_date: string;
|
|
42
|
+
projects: Array<ProjectCommitStats>;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* A derived series of bucketed counts for one project.
|
|
46
|
+
*/
|
|
47
|
+
export interface ProjectStatsSeries {
|
|
48
|
+
name: string;
|
|
49
|
+
counts: Array<number>;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Converts a UTC `YYYY-MM-DD` date to days since the Unix epoch.
|
|
53
|
+
*/
|
|
54
|
+
export declare const epoch_day_from_date: (date: string) => number;
|
|
55
|
+
/**
|
|
56
|
+
* Converts days since the Unix epoch to a UTC `YYYY-MM-DD` date.
|
|
57
|
+
*/
|
|
58
|
+
export declare const date_from_epoch_day: (epoch_day: number) => string;
|
|
59
|
+
/**
|
|
60
|
+
* Buckets commit timestamps into daily counts from the earliest commit's UTC
|
|
61
|
+
* day through `end_date`, inclusive.
|
|
62
|
+
*
|
|
63
|
+
* @param timestamps - commit times as Unix epoch seconds
|
|
64
|
+
* @param end_date - UTC date (`YYYY-MM-DD`) of the final bucket; later timestamps clamp into it
|
|
65
|
+
* @returns the start date and daily counts, or `null` if `timestamps` is empty
|
|
66
|
+
*/
|
|
67
|
+
export declare const daily_counts_from_timestamps: (timestamps: Array<number>, end_date: string) => {
|
|
68
|
+
start_date: string;
|
|
69
|
+
daily_counts: Array<number>;
|
|
70
|
+
} | null;
|
|
71
|
+
/**
|
|
72
|
+
* Pads `daily_counts` with leading zeros so the series starts at
|
|
73
|
+
* `padded_start_date` instead of `start_date`.
|
|
74
|
+
*
|
|
75
|
+
* Returns the input array unchanged when `padded_start_date` is not earlier
|
|
76
|
+
* than `start_date`.
|
|
77
|
+
*/
|
|
78
|
+
export declare const daily_counts_pad_start: (daily_counts: Array<number>, start_date: string, padded_start_date: string) => Array<number>;
|
|
79
|
+
/**
|
|
80
|
+
* Rebuckets daily counts into calendar-month (UTC) counts.
|
|
81
|
+
*
|
|
82
|
+
* The first and last buckets may cover partial months.
|
|
83
|
+
*/
|
|
84
|
+
export declare const monthly_counts_from_daily: (daily_counts: Array<number>, start_date: string) => Array<number>;
|
|
85
|
+
/**
|
|
86
|
+
* Rebuckets daily counts into 7-day counts, anchored at the end of the series
|
|
87
|
+
* so the newest bucket always covers a full 7 days.
|
|
88
|
+
*
|
|
89
|
+
* The first bucket may cover fewer days when the length isn't a multiple of 7.
|
|
90
|
+
*/
|
|
91
|
+
export declare const weekly_counts_from_daily: (daily_counts: Array<number>) => Array<number>;
|
|
92
|
+
/**
|
|
93
|
+
* Derives aligned monthly series for every project in `snapshot`, sharing one
|
|
94
|
+
* time window and one scale.
|
|
95
|
+
*
|
|
96
|
+
* Each series spans from the earliest project's `start_date` through the
|
|
97
|
+
* snapshot's `end_date` (younger projects are zero-padded at the front), so
|
|
98
|
+
* all series have the same length and bucket boundaries. `max` is the largest
|
|
99
|
+
* monthly count across all projects, for rendering every series at the same
|
|
100
|
+
* vertical scale.
|
|
101
|
+
*/
|
|
102
|
+
export declare const project_stats_to_monthly_series: (snapshot: ProjectStatsSnapshot) => {
|
|
103
|
+
series: Array<ProjectStatsSeries>;
|
|
104
|
+
max: number;
|
|
105
|
+
};
|
|
106
|
+
/**
|
|
107
|
+
* Derives aligned weekly series for every project in `snapshot`, sharing one
|
|
108
|
+
* time window and one scale — the weekly sibling of
|
|
109
|
+
* `project_stats_to_monthly_series`.
|
|
110
|
+
*/
|
|
111
|
+
export declare const project_stats_to_weekly_series: (snapshot: ProjectStatsSnapshot) => {
|
|
112
|
+
series: Array<ProjectStatsSeries>;
|
|
113
|
+
max: number;
|
|
114
|
+
};
|
|
115
|
+
/**
|
|
116
|
+
* Formats a one-line human-readable summary of a project's commit stats,
|
|
117
|
+
* e.g. `"gro — 2,386 commits since August 7, 2019"`. Used for accessible
|
|
118
|
+
* labels and tooltips.
|
|
119
|
+
*/
|
|
120
|
+
export declare const project_stats_label: (project: ProjectCommitStats) => string;
|
|
121
|
+
//# sourceMappingURL=project_stats.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project_stats.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/project_stats.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH;;GAEG;AACH,MAAM,WAAW,kBAAkB;IAClC;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IACb;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC;IACnB;;OAEG;IACH,YAAY,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;CAC5B;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACpC;;OAEG;IACH,YAAY,EAAE,MAAM,CAAC;IACrB;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,KAAK,CAAC,kBAAkB,CAAC,CAAC;CACpC;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;CACtB;AAED;;GAEG;AACH,eAAO,MAAM,mBAAmB,GAAI,MAAM,MAAM,KAAG,MAGlD,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,mBAAmB,GAAI,WAAW,MAAM,KAAG,MACA,CAAC;AAEzD;;;;;;;GAOG;AACH,eAAO,MAAM,4BAA4B,GACxC,YAAY,KAAK,CAAC,MAAM,CAAC,EACzB,UAAU,MAAM,KACd;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,KAAK,CAAC,MAAM,CAAC,CAAA;CAAE,GAAG,IAaxD,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,sBAAsB,GAClC,cAAc,KAAK,CAAC,MAAM,CAAC,EAC3B,YAAY,MAAM,EAClB,mBAAmB,MAAM,KACvB,KAAK,CAAC,MAAM,CAId,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,yBAAyB,GACrC,cAAc,KAAK,CAAC,MAAM,CAAC,EAC3B,YAAY,MAAM,KAChB,KAAK,CAAC,MAAM,CAcd,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,wBAAwB,GAAI,cAAc,KAAK,CAAC,MAAM,CAAC,KAAG,KAAK,CAAC,MAAM,CAUlF,CAAC;AAuBF;;;;;;;;;GASG;AACH,eAAO,MAAM,+BAA+B,GAC3C,UAAU,oBAAoB,KAC5B;IAAE,MAAM,EAAE,KAAK,CAAC,kBAAkB,CAAC,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CACI,CAAC;AAExD;;;;GAIG;AACH,eAAO,MAAM,8BAA8B,GAC1C,UAAU,oBAAoB,KAC5B;IAAE,MAAM,EAAE,KAAK,CAAC,kBAAkB,CAAC,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CACG,CAAC;AASvD;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,GAAI,SAAS,kBAAkB,KAAG,MAMjE,CAAC"}
|
|
@@ -0,0 +1,153 @@
|
|
|
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
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
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,oBAmdhC,CAAC"}
|