@@ -6,44 +6,41 @@ const nonEnterpriseDefaultVersion = require('./non-enterprise-default-version')
66const englishPath = path . join ( __dirname , '..' , 'content' )
77
88/**
9- * This function creates three representions of pages we need for different purposes:
10- *
11- * 1. siteTree: A nested object with pages for every language and version, useful for nav because it
12- * contains parent, child, and sibling relationships:
13- * siteTree[languageCode][version].childPages[<array of pages>].childPages[<array of pages>] (etc...)
14- *
15- * 2. pageMap: A map of all pages with permalinks as keys for fast lookup.
16- *
17- * 3. pageList: A simple array of all page objects for fast iterating.
9+ * We only need to initialize pages _once per language_ since pages don't change per version. So we do that
10+ * first since it's the most expensive work. This gets us a nested object with pages attached that we can use
11+ * as the basis for the siteTree after we do some versioning. We can also use it to derive the pageList.
1812*/
19- module . exports = async function loadPageData ( ) {
20- /**
21- * We only need to initialize pages _once per language_ since pages don't change per version. So we do that
22- * first since it's the most expensive work. This gets us a nested object with pages attached that we can use
23- * as the basis for the siteTree after we do some versioning.
24- */
25- const rawTree = { }
13+ async function loadUnversionedTree ( ) {
14+ const unversionedTree = { }
2615
2716 await Promise . all ( Object . values ( languages )
2817 . map ( async ( langObj ) => {
29- rawTree [ langObj . code ] = await createTree ( englishPath , langObj )
18+ unversionedTree [ langObj . code ] = await createTree ( englishPath , langObj )
3019 } ) )
3120
32- /**
33- * Now that we have the object of all pages per language, we can walk it for each version and do a couple operations:
34- * 1. Add a versioned href to every item, where the href is the relevant permalink for the current version.
35- * A) Add an entry for the permalink in the pageMap.
36- * 2. Drop any child pages that are not available in the current version.
37- * Note that order of languages and versions doesn't matter, but order of child page arrays DOES matter (for navigation).
38- */
21+ return unversionedTree
22+ }
23+
24+ /**
25+ * The siteTree is a nested object with pages for every language and version, useful for nav because it
26+ * contains parent, child, and sibling relationships:
27+ *
28+ * siteTree[languageCode][version].childPages[<array of pages>].childPages[<array of pages>] (etc...)
29+
30+ * Given an unversioned tree of all pages per language, we can walk it for each version and do a couple operations:
31+ * 1. Add a versioned href to every item, where the href is the relevant permalink for the current version.
32+ * 2. Drop any child pages that are not available in the current version.
33+ *
34+ * Order of languages and versions doesn't matter, but order of child page arrays DOES matter (for navigation).
35+ */
36+ async function loadSiteTree ( unversionedTree ) {
37+ const rawTree = Object . assign ( { } , ( unversionedTree || await loadUnversionedTree ( ) ) )
3938 const siteTree = { }
40- const pageMap = { }
4139
4240 await Promise . all ( Object . keys ( languages ) . map ( async ( langCode ) => {
4341 const treePerVersion = { }
4442
4543 await Promise . all ( versions . map ( async ( version ) => {
46- // Yes, we are mutating the rawTree object here...
4744 versionPages ( rawTree [ langCode ] )
4845
4946 // This step can't be asynchronous because the order of child pages matters.
@@ -53,9 +50,6 @@ module.exports = async function loadPageData () {
5350 . find ( pl => pl . pageVersion === version || ( pl . pageVersion === 'homepage' && version === nonEnterpriseDefaultVersion ) )
5451 . href
5552
56- // Add permalinks to the pageMap.
57- pageMap [ item . href ] = item . page
58-
5953 if ( ! item . childPages ) return item
6054
6155 // Drop child pages that do not apply to the current version.
@@ -71,8 +65,53 @@ module.exports = async function loadPageData () {
7165 siteTree [ langCode ] = treePerVersion
7266 } ) )
7367
74- // Get a simple array of pages.
75- const pageList = [ ...new Set ( Object . values ( pageMap ) ) ]
68+ return siteTree
69+ }
70+
71+ // Derive a flat array of Page objects in all languages.
72+ async function loadPageList ( unversionedTree ) {
73+ const rawTree = unversionedTree || await loadUnversionedTree ( )
74+ const pageList = [ ]
75+
76+ await Promise . all ( Object . keys ( languages ) . map ( async ( langCode ) => {
77+ await addToCollection ( rawTree [ langCode ] , pageList )
78+ } ) )
79+
80+ async function addToCollection ( item , collection ) {
81+ if ( ! item . page ) return
82+ collection . push ( item . page )
83+
84+ if ( ! item . childPages ) return
85+ await Promise . all ( item . childPages . map ( async ( childPage ) => await addToCollection ( childPage , collection ) ) )
86+ }
87+
88+ return pageList
89+ }
90+
91+ // Create an object from the list of all pages with permalinks as keys for fast lookup.
92+ function createMapFromArray ( pageList ) {
93+ const pageMap =
94+ pageList . reduce (
95+ ( pageMap , page ) => {
96+ for ( const permalink of page . permalinks ) {
97+ pageMap [ permalink . href ] = page
98+ }
99+ return pageMap
100+ } ,
101+ { }
102+ )
103+
104+ return pageMap
105+ }
106+
107+ async function loadPageMap ( pageList ) {
108+ const pages = pageList || await loadPageList ( )
109+ return createMapFromArray ( pages )
110+ }
76111
77- return { siteTree, pageList, pageMap }
112+ module . exports = {
113+ loadUnversionedTree,
114+ loadSiteTree,
115+ loadPages : loadPageList ,
116+ loadPageMap
78117}
0 commit comments