11import * as Path from "path" ;
22import { RendererComponent } from "../components.js" ;
3- import { PageEvent , RendererEvent } from "../events.js" ;
4- import { JSX , writeFile } from "../../utils/index.js" ;
3+ import { RendererEvent } from "../events.js" ;
4+ import { writeFile } from "../../utils/index.js" ;
55import { DefaultTheme } from "../themes/default/DefaultTheme.js" ;
66import { gzip } from "zlib" ;
77import { promisify } from "util" ;
8- import {
9- DeclarationReflection ,
10- ReferenceType ,
11- ReflectionKind ,
12- } from "../../models/index.js" ;
8+
139import type { Renderer } from "../index.js" ;
10+ import {
11+ getHierarchyRoots ,
12+ getKindClass ,
13+ getUniquePath ,
14+ } from "../themes/lib.js" ;
15+ import type { DeclarationReflection } from "../../models/index.js" ;
1416
1517const gzipP = promisify ( gzip ) ;
1618
17- export interface HierarchyElement {
18- html : string ;
19- text : string ;
20- path : string ;
21- parents ?: ( { path : string } | { html : string ; text : string } ) [ ] ;
22- children ?: ( { path : string } | { html : string ; text : string } ) [ ] ;
19+ interface JsonHierarchyElement {
20+ name : string ;
21+ kind : number ;
22+ url : string ;
23+ children ?: number [ ] ;
24+ uniqueNameParents ?: number [ ] ;
25+ class : string ;
26+ }
27+
28+ interface JsonHierarchy {
29+ // ids of root instances
30+ roots : number [ ] ;
31+ reflections : Record < number , JsonHierarchyElement > ;
2332}
2433
2534export class HierarchyPlugin extends RendererComponent {
@@ -39,60 +48,53 @@ export class HierarchyPlugin extends RendererComponent {
3948 }
4049
4150 private async buildHierarchy ( event : RendererEvent ) {
42- const theme = this . owner . theme as DefaultTheme ;
43-
44- const context = theme . getRenderContext ( new PageEvent ( event . project ) ) ;
45-
46- const hierarchy = (
47- event . project . getReflectionsByKind (
48- ReflectionKind . ClassOrInterface ,
49- ) as DeclarationReflection [ ]
50- )
51- . filter (
52- ( reflection ) =>
53- reflection . extendedTypes ?. length ||
54- reflection . extendedBy ?. length ,
55- )
56- . map ( ( reflection ) => ( {
57- html : JSX . renderElement (
58- context . type (
59- ReferenceType . createResolvedReference (
60- reflection . name ,
61- reflection ,
62- reflection . project ,
63- ) ,
64- ) ,
65- ) ,
66- // Full name should be safe here, since this list only includes classes/interfaces.
67- text : reflection . getFullName ( ) ,
68- path : reflection . url ! ,
69- parents : reflection . extendedTypes ?. map ( ( type ) =>
70- ! ( type instanceof ReferenceType ) ||
71- ! ( type . reflection instanceof DeclarationReflection )
72- ? {
73- html : JSX . renderElement ( context . type ( type ) ) ,
74- text : type . toString ( ) ,
75- }
76- : { path : type . reflection . url ! } ,
77- ) ,
78- children : reflection . extendedBy ?. map ( ( type ) =>
79- ! ( type instanceof ReferenceType ) ||
80- ! ( type . reflection instanceof DeclarationReflection )
81- ? {
82- html : JSX . renderElement ( context . type ( type ) ) ,
83- text : type . toString ( ) ,
84- }
85- : { path : type . reflection . url ! } ,
86- ) ,
87- } ) ) ;
88-
89- if ( ! hierarchy . length ) return ;
90-
91- hierarchy . forEach ( ( element ) => {
92- if ( ! element . parents ?. length ) delete element . parents ;
93-
94- if ( ! element . children ?. length ) delete element . children ;
95- } ) ;
51+ const project = event . project ;
52+
53+ const hierarchy : JsonHierarchy = {
54+ roots : getHierarchyRoots ( project ) . map ( ( refl ) => refl . id ) ,
55+ reflections : { } ,
56+ } ;
57+
58+ const queue = [ ...hierarchy . roots ] ;
59+
60+ while ( queue . length ) {
61+ const id = queue . pop ( ) ! ;
62+ const refl = project . getReflectionById ( id ) as DeclarationReflection ;
63+ if ( id in hierarchy . reflections ) continue ;
64+ if ( ! refl . url ) continue ;
65+
66+ const jsonRecord : JsonHierarchyElement = {
67+ name : refl . name ,
68+ kind : refl . kind ,
69+ url : refl . url ,
70+ class : getKindClass ( refl ) ,
71+ } ;
72+
73+ const path = getUniquePath ( refl ) ;
74+ if ( path . length > 1 ) {
75+ jsonRecord . uniqueNameParents = path
76+ . slice ( 0 , - 1 )
77+ . map ( ( r ) => r . id ) ;
78+ queue . push ( ...jsonRecord . uniqueNameParents ) ;
79+ }
80+
81+ const children = [
82+ ...( refl . implementedBy || [ ] ) ,
83+ ...( refl . extendedBy || [ ] ) ,
84+ ] ;
85+
86+ for ( const child of children ) {
87+ if ( child . reflection ) {
88+ jsonRecord . children ||= [ ] ;
89+ jsonRecord . children . push ( child . reflection . id ) ;
90+ }
91+ }
92+ if ( jsonRecord . children ) {
93+ queue . push ( ...jsonRecord . children ) ;
94+ }
95+
96+ hierarchy . reflections [ id ] = jsonRecord ;
97+ }
9698
9799 const hierarchyJs = Path . join (
98100 event . outputDirectory ,
0 commit comments