@fuzdev/fuz_ui 0.206.8 → 0.207.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.
- package/dist/DeclarationDetail.svelte +55 -20
- package/dist/DeclarationDetail.svelte.d.ts +1 -1
- package/dist/DeclarationDetail.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 +31 -46
- package/dist/ProjectLinks.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/TypeJsonView.svelte +90 -0
- package/dist/TypeJsonView.svelte.d.ts +26 -0
- package/dist/TypeJsonView.svelte.d.ts.map +1 -0
- package/dist/TypeLink.svelte +17 -1
- package/dist/TypeLink.svelte.d.ts +10 -0
- package/dist/TypeLink.svelte.d.ts.map +1 -1
- package/dist/declaration.svelte.d.ts +25 -5
- package/dist/declaration.svelte.d.ts.map +1 -1
- package/dist/declaration.svelte.js +31 -5
- 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/sparkline.d.ts +102 -0
- package/dist/sparkline.d.ts.map +1 -0
- package/dist/sparkline.js +63 -0
- package/package.json +2 -2
- package/src/lib/declaration.svelte.ts +37 -7
- 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/sparkline.ts +173 -0
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
@component
|
|
3
|
+
|
|
4
|
+
Renders svelte-docinfo's structured `TypeJson` tree as inline code: `reference`
|
|
5
|
+
nodes (and alias-carrying unions/intersections) link to API docs via
|
|
6
|
+
`DeclarationLink` when the name resolves in the library — scoped to the token's
|
|
7
|
+
declaring module when the analysis names one — terminal type text is
|
|
8
|
+
syntax-highlighted via fuz_code's `Code`, and structural punctuation comes
|
|
9
|
+
from svelte-docinfo's `typeJsonToTokens`, which owns spacing and
|
|
10
|
+
parenthesization so rendering is whitespace-exact.
|
|
11
|
+
|
|
12
|
+
The structured sibling of `TypeLink`, which renders flat type strings —
|
|
13
|
+
`TypeLink` delegates here when given `type_info`, and svelte-docinfo omits the
|
|
14
|
+
tree wherever the flat string is the whole story, so the two compose as
|
|
15
|
+
"structured when it says something, flat otherwise". Pass `title` (typically
|
|
16
|
+
the flat sibling string) to keep the expansion reachable on hover where the
|
|
17
|
+
tree replaced it with a recovered name.
|
|
18
|
+
-->
|
|
19
|
+
<script lang="ts">
|
|
20
|
+
import Code from '@fuzdev/fuz_code/Code.svelte';
|
|
21
|
+
import type { TypeJson } from 'svelte-docinfo/types.js';
|
|
22
|
+
import { typeJsonToTokens } from 'svelte-docinfo/declaration-helpers.js';
|
|
23
|
+
|
|
24
|
+
import DeclarationLink from './DeclarationLink.svelte';
|
|
25
|
+
import { library_context } from './library.svelte.js';
|
|
26
|
+
|
|
27
|
+
const {
|
|
28
|
+
type_info,
|
|
29
|
+
title
|
|
30
|
+
}: {
|
|
31
|
+
type_info: TypeJson;
|
|
32
|
+
/** Hover text for the root element — pass the flat type string so the checker's expansion stays reachable. */
|
|
33
|
+
title?: string;
|
|
34
|
+
} = $props();
|
|
35
|
+
|
|
36
|
+
const get_library = library_context.get();
|
|
37
|
+
const library = $derived(get_library());
|
|
38
|
+
|
|
39
|
+
const tokens = $derived(typeJsonToTokens(type_info));
|
|
40
|
+
|
|
41
|
+
// a bare name renders without the code wrapper, matching the plain chip
|
|
42
|
+
// link `TypeLink` produces for whole-string matches
|
|
43
|
+
const bare_name_token = $derived(
|
|
44
|
+
tokens.length === 1 && tokens[0]!.kind === 'name' ? tokens[0]! : undefined
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
// the gate mirrors `DeclarationLink`'s resolution exactly — a moduled token
|
|
48
|
+
// (registry-recovered reference) is scoped to its declaring module with no
|
|
49
|
+
// by-name fallback, so the gate can't admit a name the link then fails on
|
|
50
|
+
const resolves = (name: string, module?: string): boolean =>
|
|
51
|
+
module === undefined
|
|
52
|
+
? library.declaration_by_name.has(name)
|
|
53
|
+
: library.module_by_path.get(module)?.get_declaration_by_name(name) !== undefined;
|
|
54
|
+
</script>
|
|
55
|
+
|
|
56
|
+
{#snippet name_view(name: string, module: string | undefined, root_title?: string)}
|
|
57
|
+
{#if resolves(name, module)}
|
|
58
|
+
<DeclarationLink {name} module_path={module} title={root_title} />
|
|
59
|
+
{:else}
|
|
60
|
+
<Code lang="ts" content={name} inline title={root_title} />
|
|
61
|
+
{/if}
|
|
62
|
+
{/snippet}
|
|
63
|
+
|
|
64
|
+
{#if bare_name_token}
|
|
65
|
+
{@render name_view(bare_name_token.name, bare_name_token.module, title)}
|
|
66
|
+
{:else}
|
|
67
|
+
<!-- token adjacency survives the multi-line template: Svelte trims
|
|
68
|
+
block-boundary whitespace here, locked by the `TypeJsonView` render tests
|
|
69
|
+
(`textContent` equality would catch stray spaces) -->
|
|
70
|
+
<code class="type-json-view" {title}>
|
|
71
|
+
{#each tokens as token, i (i)}
|
|
72
|
+
{#if token.kind === 'text'}
|
|
73
|
+
{token.text}
|
|
74
|
+
{:else if token.kind === 'name'}
|
|
75
|
+
{@render name_view(token.name, token.module)}
|
|
76
|
+
{:else}
|
|
77
|
+
<Code lang="ts" content={token.text} inline />
|
|
78
|
+
{/if}
|
|
79
|
+
{/each}
|
|
80
|
+
</code>
|
|
81
|
+
{/if}
|
|
82
|
+
|
|
83
|
+
<style>
|
|
84
|
+
/* the outer element is the one code pill; inner `Code` fragments contribute
|
|
85
|
+
syntax coloring only */
|
|
86
|
+
.type-json-view :global(code) {
|
|
87
|
+
background: transparent;
|
|
88
|
+
padding: 0;
|
|
89
|
+
}
|
|
90
|
+
</style>
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { TypeJson } from 'svelte-docinfo/types.js';
|
|
2
|
+
type $$ComponentProps = {
|
|
3
|
+
type_info: TypeJson;
|
|
4
|
+
/** Hover text for the root element — pass the flat type string so the checker's expansion stays reachable. */
|
|
5
|
+
title?: string;
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* Renders svelte-docinfo's structured `TypeJson` tree as inline code: `reference`
|
|
9
|
+
* nodes (and alias-carrying unions/intersections) link to API docs via
|
|
10
|
+
* `DeclarationLink` when the name resolves in the library — scoped to the token's
|
|
11
|
+
* declaring module when the analysis names one — terminal type text is
|
|
12
|
+
* syntax-highlighted via fuz_code's `Code`, and structural punctuation comes
|
|
13
|
+
* from svelte-docinfo's `typeJsonToTokens`, which owns spacing and
|
|
14
|
+
* parenthesization so rendering is whitespace-exact.
|
|
15
|
+
*
|
|
16
|
+
* The structured sibling of `TypeLink`, which renders flat type strings —
|
|
17
|
+
* `TypeLink` delegates here when given `type_info`, and svelte-docinfo omits the
|
|
18
|
+
* tree wherever the flat string is the whole story, so the two compose as
|
|
19
|
+
* "structured when it says something, flat otherwise". Pass `title` (typically
|
|
20
|
+
* the flat sibling string) to keep the expansion reachable on hover where the
|
|
21
|
+
* tree replaced it with a recovered name.
|
|
22
|
+
*/
|
|
23
|
+
declare const TypeJsonView: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
24
|
+
type TypeJsonView = ReturnType<typeof TypeJsonView>;
|
|
25
|
+
export default TypeJsonView;
|
|
26
|
+
//# sourceMappingURL=TypeJsonView.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TypeJsonView.svelte.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/TypeJsonView.svelte"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAMvD,KAAK,gBAAgB,GAAI;IACxB,SAAS,EAAE,QAAQ,CAAC;IACpB,8GAA8G;IAC9G,KAAK,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AAgEH;;;;;;;;;;;;;;;GAeG;AACH,QAAA,MAAM,YAAY,sDAAwC,CAAC;AAC3D,KAAK,YAAY,GAAG,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC;AACpD,eAAe,YAAY,CAAC"}
|
package/dist/TypeLink.svelte
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import Code from '@fuzdev/fuz_code/Code.svelte';
|
|
3
3
|
import type { HTMLAttributes, SvelteHTMLElements } from 'svelte/elements';
|
|
4
|
+
import type { TypeJson } from 'svelte-docinfo/types.js';
|
|
4
5
|
|
|
5
6
|
import DeclarationLink from './DeclarationLink.svelte';
|
|
7
|
+
import TypeJsonView from './TypeJsonView.svelte';
|
|
6
8
|
import { library_context } from './library.svelte.js';
|
|
7
9
|
|
|
8
10
|
const {
|
|
9
11
|
type,
|
|
12
|
+
type_info,
|
|
10
13
|
hash,
|
|
11
14
|
a_attrs,
|
|
12
15
|
code_attrs,
|
|
@@ -14,6 +17,15 @@
|
|
|
14
17
|
}: // generic element attrs, the common denominator of the rendered roots - // assignable to the anchor rest of `DeclarationLink` and the code rest of `Code`
|
|
15
18
|
HTMLAttributes<HTMLElement> & {
|
|
16
19
|
type: string;
|
|
20
|
+
/**
|
|
21
|
+
* Structured type tree, when svelte-docinfo emitted one beside the flat
|
|
22
|
+
* string — rendered via `TypeJsonView` (per-node linkification, with
|
|
23
|
+
* `type` as hover text) instead of the whole-string match below. An
|
|
24
|
+
* absent tree falls through to `type`, so call sites pass both fields
|
|
25
|
+
* unconditionally. `hash` and the rest/`a_attrs`/`code_attrs`
|
|
26
|
+
* attributes apply only to the flat branches, not the delegated tree.
|
|
27
|
+
*/
|
|
28
|
+
type_info?: TypeJson;
|
|
17
29
|
/** URL fragment to append, with or without the `#`. */
|
|
18
30
|
hash?: string;
|
|
19
31
|
/** Anchor attributes, applied only when the type resolves to a declaration link. */
|
|
@@ -28,7 +40,11 @@
|
|
|
28
40
|
// TODO maybe better name?
|
|
29
41
|
</script>
|
|
30
42
|
|
|
31
|
-
{#if
|
|
43
|
+
{#if type_info}
|
|
44
|
+
<!-- the flat string rides along as hover text so the checker's expansion
|
|
45
|
+
stays reachable where the tree replaced it with a recovered name -->
|
|
46
|
+
<TypeJsonView {type_info} title={type} />
|
|
47
|
+
{:else if library.declaration_by_name.has(type)}
|
|
32
48
|
<DeclarationLink {...rest} {...a_attrs} name={type} {hash} />
|
|
33
49
|
{:else}
|
|
34
50
|
<Code {...rest} {...code_attrs} lang="ts" content={type} inline />
|
|
@@ -1,7 +1,17 @@
|
|
|
1
1
|
import type { HTMLAttributes, SvelteHTMLElements } from 'svelte/elements';
|
|
2
|
+
import type { TypeJson } from 'svelte-docinfo/types.js';
|
|
2
3
|
type $$ComponentProps = // generic element attrs, the common denominator of the rendered roots - // assignable to the anchor rest of `DeclarationLink` and the code rest of `Code`
|
|
3
4
|
HTMLAttributes<HTMLElement> & {
|
|
4
5
|
type: string;
|
|
6
|
+
/**
|
|
7
|
+
* Structured type tree, when svelte-docinfo emitted one beside the flat
|
|
8
|
+
* string — rendered via `TypeJsonView` (per-node linkification, with
|
|
9
|
+
* `type` as hover text) instead of the whole-string match below. An
|
|
10
|
+
* absent tree falls through to `type`, so call sites pass both fields
|
|
11
|
+
* unconditionally. `hash` and the rest/`a_attrs`/`code_attrs`
|
|
12
|
+
* attributes apply only to the flat branches, not the delegated tree.
|
|
13
|
+
*/
|
|
14
|
+
type_info?: TypeJson;
|
|
5
15
|
/** URL fragment to append, with or without the `#`. */
|
|
6
16
|
hash?: string;
|
|
7
17
|
/** Anchor attributes, applied only when the type resolves to a declaration link. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TypeLink.svelte.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/TypeLink.svelte"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"TypeLink.svelte.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/TypeLink.svelte"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAC1E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAMvD,KAAK,gBAAgB,GACpB,AADwB,0JAA0J;AAClL,cAAc,CAAC,WAAW,CAAC,GAAG;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb;;;;;;;OAOG;IACH,SAAS,CAAC,EAAE,QAAQ,CAAC;IACrB,uDAAuD;IACvD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,oFAAoF;IACpF,OAAO,CAAC,EAAE,kBAAkB,CAAC,GAAG,CAAC,CAAC;IAClC,0FAA0F;IAC1F,UAAU,CAAC,EAAE,kBAAkB,CAAC,MAAM,CAAC,CAAC;CACxC,CAAC;AAoCJ,QAAA,MAAM,QAAQ,sDAAwC,CAAC;AACvD,KAAK,QAAQ,GAAG,UAAU,CAAC,OAAO,QAAQ,CAAC,CAAC;AAC5C,eAAe,QAAQ,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { DeclarationJsonInput, MemberJsonInput, ParameterJsonInput, ComponentPropJsonInput, OverloadJsonInput, Reactivity } from 'svelte-docinfo/types.js';
|
|
1
|
+
import type { DeclarationJsonInput, MemberJsonInput, ParameterJsonInput, ComponentPropJsonInput, OverloadJsonInput, Reactivity, TypeJson } from 'svelte-docinfo/types.js';
|
|
2
2
|
import type { Module } from './module.svelte.js';
|
|
3
3
|
/**
|
|
4
4
|
* Rich runtime representation of an exported declaration.
|
|
@@ -45,14 +45,30 @@ export declare class Declaration {
|
|
|
45
45
|
*/
|
|
46
46
|
get display_name(): string;
|
|
47
47
|
get type_signature(): string | undefined;
|
|
48
|
+
/**
|
|
49
|
+
* Structured type tree beside `type_signature`, absent when the flat string
|
|
50
|
+
* is the whole story. Present on `variable` and `type` kinds only.
|
|
51
|
+
*/
|
|
52
|
+
get type_info(): TypeJson | undefined;
|
|
53
|
+
/**
|
|
54
|
+
* Default value documented via `@default`; the authoritative initializer
|
|
55
|
+
* (when human-readable) is in `type_signature`. Present on `variable` kind
|
|
56
|
+
* only — parameters, props, and members carry their own.
|
|
57
|
+
*/
|
|
58
|
+
get default_value(): string | undefined;
|
|
48
59
|
get doc_comment(): string | undefined;
|
|
49
60
|
get deprecated_message(): string | undefined;
|
|
50
61
|
get parameters(): Array<ParameterJsonInput> | undefined;
|
|
51
62
|
get props(): Array<ComponentPropJsonInput> | undefined;
|
|
52
63
|
get return_type(): string | undefined;
|
|
64
|
+
/**
|
|
65
|
+
* Structured return type beside `return_type`, absent when the flat string
|
|
66
|
+
* is the whole story. Present on `function` kind only.
|
|
67
|
+
*/
|
|
68
|
+
get return_type_info(): TypeJson | undefined;
|
|
53
69
|
get return_description(): string | undefined;
|
|
54
70
|
get generic_params(): NonNullable<DeclarationJsonInput['genericParams']>;
|
|
55
|
-
get
|
|
71
|
+
get extends_types(): Array<string> | undefined;
|
|
56
72
|
get implements_types(): Array<string> | undefined;
|
|
57
73
|
get throws(): NonNullable<DeclarationJsonInput['throws']>;
|
|
58
74
|
get since(): string | undefined;
|
|
@@ -63,10 +79,14 @@ export declare class Declaration {
|
|
|
63
79
|
*/
|
|
64
80
|
get members(): Array<MemberJsonInput> | undefined;
|
|
65
81
|
/**
|
|
66
|
-
*
|
|
67
|
-
*
|
|
82
|
+
* External types whose contributions are filtered out of props/members —
|
|
83
|
+
* the attribute bags a component forwards, however the author composed
|
|
84
|
+
* them (intersection, heritage clause, bare or indexed-access reference).
|
|
85
|
+
* On `interface`/`class` kinds it records the external reach of the
|
|
86
|
+
* heritage chain, whose contributions members (own-only) never enumerate.
|
|
87
|
+
* Present on `component`, `type`, `interface`, and `class` kinds.
|
|
68
88
|
*/
|
|
69
|
-
get
|
|
89
|
+
get external_types(): Array<string> | undefined;
|
|
70
90
|
/**
|
|
71
91
|
* Whether a component accepts children via props or template usage.
|
|
72
92
|
* Present on `component` kind only.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"declaration.svelte.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/declaration.svelte.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEX,oBAAoB,EACpB,eAAe,EACf,kBAAkB,EAClB,sBAAsB,EACtB,iBAAiB,EACjB,UAAU,EACV,MAAM,yBAAyB,CAAC;AAIjC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAcjD;;;;;;;;;;;;GAYG;AACH,qBAAa,WAAW;;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAiB;IACxC,QAAQ,CAAC,gBAAgB,EAAE,oBAAoB,CAAiB;IAEhE,IAAI,OAAO,IAAI,MAAM,CAAC,SAAS,CAAC,CAE/B;IAED;;OAEG;IACH,IAAI,WAAW,IAAI,MAAM,CAExB;IAED,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,IAAI,IAAI,IAAI,oBAAoB,CAAC,MAAM,CAAC,CAEvC;IAED;;OAEG;IACH,IAAI,UAAU,IAAI,MAAM,GAAG,SAAS,CAQnC;IAED;;OAEG;IACH,IAAI,OAAO,IAAI,MAAM,CAEpB;IAID;;OAEG;IACH,IAAI,gBAAgB,IAAI,MAAM,CAQ7B;IAED;;OAEG;IACH,IAAI,YAAY,IAAI,MAAM,GAAG,SAAS,CAIrC;IAID;;OAEG;IACH,IAAI,YAAY,IAAI,MAAM,CAOzB;IAED,IAAI,cAAc,IAAI,MAAM,GAAG,SAAS,CAEvC;IAED,IAAI,WAAW,IAAI,MAAM,GAAG,SAAS,CAEpC;IAED,IAAI,kBAAkB,IAAI,MAAM,GAAG,SAAS,CAE3C;IAED,IAAI,UAAU,IAAI,KAAK,CAAC,kBAAkB,CAAC,GAAG,SAAS,CAEtD;IAED,IAAI,KAAK,IAAI,KAAK,CAAC,sBAAsB,CAAC,GAAG,SAAS,CAErD;IAED,IAAI,WAAW,IAAI,MAAM,GAAG,SAAS,CAEpC;IAED,IAAI,kBAAkB,IAAI,MAAM,GAAG,SAAS,CAE3C;IAED,IAAI,cAAc,IAAI,WAAW,CAAC,oBAAoB,CAAC,eAAe,CAAC,CAAC,CAEvE;IAED,IAAI,
|
|
1
|
+
{"version":3,"file":"declaration.svelte.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/declaration.svelte.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEX,oBAAoB,EACpB,eAAe,EACf,kBAAkB,EAClB,sBAAsB,EACtB,iBAAiB,EACjB,UAAU,EACV,QAAQ,EACR,MAAM,yBAAyB,CAAC;AAIjC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAcjD;;;;;;;;;;;;GAYG;AACH,qBAAa,WAAW;;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAiB;IACxC,QAAQ,CAAC,gBAAgB,EAAE,oBAAoB,CAAiB;IAEhE,IAAI,OAAO,IAAI,MAAM,CAAC,SAAS,CAAC,CAE/B;IAED;;OAEG;IACH,IAAI,WAAW,IAAI,MAAM,CAExB;IAED,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,IAAI,IAAI,IAAI,oBAAoB,CAAC,MAAM,CAAC,CAEvC;IAED;;OAEG;IACH,IAAI,UAAU,IAAI,MAAM,GAAG,SAAS,CAQnC;IAED;;OAEG;IACH,IAAI,OAAO,IAAI,MAAM,CAEpB;IAID;;OAEG;IACH,IAAI,gBAAgB,IAAI,MAAM,CAQ7B;IAED;;OAEG;IACH,IAAI,YAAY,IAAI,MAAM,GAAG,SAAS,CAIrC;IAID;;OAEG;IACH,IAAI,YAAY,IAAI,MAAM,CAOzB;IAED,IAAI,cAAc,IAAI,MAAM,GAAG,SAAS,CAEvC;IAED;;;OAGG;IACH,IAAI,SAAS,IAAI,QAAQ,GAAG,SAAS,CAEpC;IAED;;;;OAIG;IACH,IAAI,aAAa,IAAI,MAAM,GAAG,SAAS,CAEtC;IAED,IAAI,WAAW,IAAI,MAAM,GAAG,SAAS,CAEpC;IAED,IAAI,kBAAkB,IAAI,MAAM,GAAG,SAAS,CAE3C;IAED,IAAI,UAAU,IAAI,KAAK,CAAC,kBAAkB,CAAC,GAAG,SAAS,CAEtD;IAED,IAAI,KAAK,IAAI,KAAK,CAAC,sBAAsB,CAAC,GAAG,SAAS,CAErD;IAED,IAAI,WAAW,IAAI,MAAM,GAAG,SAAS,CAEpC;IAED;;;OAGG;IACH,IAAI,gBAAgB,IAAI,QAAQ,GAAG,SAAS,CAE3C;IAED,IAAI,kBAAkB,IAAI,MAAM,GAAG,SAAS,CAE3C;IAED,IAAI,cAAc,IAAI,WAAW,CAAC,oBAAoB,CAAC,eAAe,CAAC,CAAC,CAEvE;IAED,IAAI,aAAa,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,SAAS,CAE7C;IAED,IAAI,gBAAgB,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,SAAS,CAEhD;IAED,IAAI,MAAM,IAAI,WAAW,CAAC,oBAAoB,CAAC,QAAQ,CAAC,CAAC,CAExD;IAED,IAAI,KAAK,IAAI,MAAM,GAAG,SAAS,CAE9B;IAED,IAAI,QAAQ,IAAI,WAAW,CAAC,oBAAoB,CAAC,UAAU,CAAC,CAAC,CAE5D;IAED,IAAI,QAAQ,IAAI,WAAW,CAAC,oBAAoB,CAAC,SAAS,CAAC,CAAC,CAE3D;IAED;;OAEG;IACH,IAAI,OAAO,IAAI,KAAK,CAAC,eAAe,CAAC,GAAG,SAAS,CAEhD;IAED;;;;;;;OAOG;IACH,IAAI,cAAc,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,SAAS,CAE9C;IAED;;;OAGG;IACH,IAAI,gBAAgB,IAAI,OAAO,GAAG,SAAS,CAE1C;IAED;;;OAGG;IACH,IAAI,SAAS,IAAI,KAAK,CAAC,iBAAiB,CAAC,GAAG,SAAS,CAEpD;IAED;;OAEG;IACH,IAAI,QAAQ,IAAI,oBAAoB,CAAC,SAAS,CAAC,CAE9C;IAED;;;;OAIG;IACH,IAAI,kBAAkB,IAAI,oBAAoB,CAAC,kBAAkB,CAAC,CAEjE;IAED;;OAEG;IACH,IAAI,OAAO,IAAI,oBAAoB,CAAC,SAAS,CAAC,CAE7C;IAED;;;;OAIG;IACH,IAAI,UAAU,IAAI,UAAU,GAAG,SAAS,CAEvC;IAED,IAAI,YAAY,IAAI,OAAO,CAE1B;IAGD,IAAI,aAAa,IAAI,OAAO,CAE3B;IAED,IAAI,iBAAiB,IAAI,OAAO,CAE/B;IAED,IAAI,cAAc,IAAI,OAAO,CAG5B;IAED,IAAI,SAAS,IAAI,OAAO,CAGvB;IAED,IAAI,YAAY,IAAI,OAAO,CAE1B;gBAEW,MAAM,EAAE,MAAM,EAAE,gBAAgB,EAAE,oBAAoB;CAIlE"}
|
|
@@ -87,6 +87,21 @@ export class Declaration {
|
|
|
87
87
|
get type_signature() {
|
|
88
88
|
return this.declaration_json.typeSignature;
|
|
89
89
|
}
|
|
90
|
+
/**
|
|
91
|
+
* Structured type tree beside `type_signature`, absent when the flat string
|
|
92
|
+
* is the whole story. Present on `variable` and `type` kinds only.
|
|
93
|
+
*/
|
|
94
|
+
get type_info() {
|
|
95
|
+
return field(this.declaration_json, 'typeInfo');
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Default value documented via `@default`; the authoritative initializer
|
|
99
|
+
* (when human-readable) is in `type_signature`. Present on `variable` kind
|
|
100
|
+
* only — parameters, props, and members carry their own.
|
|
101
|
+
*/
|
|
102
|
+
get default_value() {
|
|
103
|
+
return field(this.declaration_json, 'defaultValue');
|
|
104
|
+
}
|
|
90
105
|
get doc_comment() {
|
|
91
106
|
return this.declaration_json.docComment;
|
|
92
107
|
}
|
|
@@ -102,13 +117,20 @@ export class Declaration {
|
|
|
102
117
|
get return_type() {
|
|
103
118
|
return field(this.declaration_json, 'returnType');
|
|
104
119
|
}
|
|
120
|
+
/**
|
|
121
|
+
* Structured return type beside `return_type`, absent when the flat string
|
|
122
|
+
* is the whole story. Present on `function` kind only.
|
|
123
|
+
*/
|
|
124
|
+
get return_type_info() {
|
|
125
|
+
return field(this.declaration_json, 'returnTypeInfo');
|
|
126
|
+
}
|
|
105
127
|
get return_description() {
|
|
106
128
|
return field(this.declaration_json, 'returnDescription');
|
|
107
129
|
}
|
|
108
130
|
get generic_params() {
|
|
109
131
|
return this.declaration_json.genericParams ?? EMPTY_ARRAY;
|
|
110
132
|
}
|
|
111
|
-
get
|
|
133
|
+
get extends_types() {
|
|
112
134
|
return field(this.declaration_json, 'extends');
|
|
113
135
|
}
|
|
114
136
|
get implements_types() {
|
|
@@ -133,11 +155,15 @@ export class Declaration {
|
|
|
133
155
|
return field(this.declaration_json, 'members');
|
|
134
156
|
}
|
|
135
157
|
/**
|
|
136
|
-
*
|
|
137
|
-
*
|
|
158
|
+
* External types whose contributions are filtered out of props/members —
|
|
159
|
+
* the attribute bags a component forwards, however the author composed
|
|
160
|
+
* them (intersection, heritage clause, bare or indexed-access reference).
|
|
161
|
+
* On `interface`/`class` kinds it records the external reach of the
|
|
162
|
+
* heritage chain, whose contributions members (own-only) never enumerate.
|
|
163
|
+
* Present on `component`, `type`, `interface`, and `class` kinds.
|
|
138
164
|
*/
|
|
139
|
-
get
|
|
140
|
-
return field(this.declaration_json, '
|
|
165
|
+
get external_types() {
|
|
166
|
+
return field(this.declaration_json, 'externalTypes');
|
|
141
167
|
}
|
|
142
168
|
/**
|
|
143
169
|
* Whether a component accepts children via props or template usage.
|
|
@@ -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"}
|