Split up allKnownLayouts, make parsing it lazy for faster loading

This commit is contained in:
Pieter Vander Vennet 2023-03-02 05:20:53 +01:00
parent 6dc0fa0851
commit 6ee85b12f8
14 changed files with 311 additions and 323 deletions

View file

@ -24,6 +24,11 @@ import { DefaultGuiState } from "../UI/DefaultGuiState"
import fakedom from "fake-dom"
import Hotkeys from "../UI/Base/Hotkeys"
import { QueryParameters } from "../Logic/Web/QueryParameters"
import Link from "../UI/Base/Link"
import Constants from "../Models/Constants"
import LayerConfig from "../Models/ThemeConfig/LayerConfig"
import DependencyCalculator from "../Models/ThemeConfig/DependencyCalculator"
import { AllSharedLayers } from "../Customizations/AllSharedLayers"
function WriteFile(
filename,
html: BaseUIElement,
@ -74,6 +79,179 @@ function WriteFile(
writeFileSync(filename, warnAutomated + md)
}
function GenerateDocumentationForTheme(theme: LayoutConfig): BaseUIElement {
return new Combine([
new Title(
new Combine([
theme.title,
"(",
new Link(theme.id, "https://mapcomplete.osm.be/" + theme.id),
")",
]),
2
),
theme.description,
"This theme contains the following layers:",
new List(
theme.layers
.filter((l) => !l.id.startsWith("note_import_"))
.map((l) => new Link(l.id, "../Layers/" + l.id + ".md"))
),
"Available languages:",
new List(theme.language.filter((ln) => ln !== "_context")),
]).SetClass("flex flex-col")
}
/**
* Generates the documentation for the layers overview page
* @constructor
*/
function GenLayerOverviewText(): BaseUIElement {
for (const id of Constants.priviliged_layers) {
if (!AllSharedLayers.sharedLayers.has(id)) {
throw "Priviliged layer definition not found: " + id
}
}
const allLayers: LayerConfig[] = Array.from(AllSharedLayers.sharedLayers.values()).filter(
(layer) => Constants.priviliged_layers.indexOf(layer.id) < 0
)
const builtinLayerIds: Set<string> = new Set<string>()
allLayers.forEach((l) => builtinLayerIds.add(l.id))
const themesPerLayer = new Map<string, string[]>()
for (const layout of Array.from(AllKnownLayouts.allKnownLayouts.values())) {
for (const layer of layout.layers) {
if (!builtinLayerIds.has(layer.id)) {
continue
}
if (!themesPerLayer.has(layer.id)) {
themesPerLayer.set(layer.id, [])
}
themesPerLayer.get(layer.id).push(layout.id)
}
}
// Determine the cross-dependencies
const layerIsNeededBy: Map<string, string[]> = new Map<string, string[]>()
for (const layer of allLayers) {
for (const dep of DependencyCalculator.getLayerDependencies(layer)) {
const dependency = dep.neededLayer
if (!layerIsNeededBy.has(dependency)) {
layerIsNeededBy.set(dependency, [])
}
layerIsNeededBy.get(dependency).push(layer.id)
}
}
return new Combine([
new Title("Special and other useful layers", 1),
"MapComplete has a few data layers available in the theme which have special properties through builtin-hooks. Furthermore, there are some normal layers (which are built from normal Theme-config files) but are so general that they get a mention here.",
new Title("Priviliged layers", 1),
new List(Constants.priviliged_layers.map((id) => "[" + id + "](#" + id + ")")),
...Constants.priviliged_layers
.map((id) => AllSharedLayers.sharedLayers.get(id))
.map((l) =>
l.GenerateDocumentation(
themesPerLayer.get(l.id),
layerIsNeededBy,
DependencyCalculator.getLayerDependencies(l),
Constants.added_by_default.indexOf(l.id) >= 0,
Constants.no_include.indexOf(l.id) < 0
)
),
new Title("Normal layers", 1),
"The following layers are included in MapComplete:",
new List(
Array.from(AllSharedLayers.sharedLayers.keys()).map(
(id) => new Link(id, "./Layers/" + id + ".md")
)
),
])
}
/**
* Generates documentation for the layers.
* Inline layers are included (if the theme is public)
* @param callback
* @constructor
*/
function GenOverviewsForSingleLayer(
callback: (layer: LayerConfig, element: BaseUIElement, inlineSource: string) => void
): void {
const allLayers: LayerConfig[] = Array.from(AllSharedLayers.sharedLayers.values()).filter(
(layer) => Constants.priviliged_layers.indexOf(layer.id) < 0
)
const builtinLayerIds: Set<string> = new Set<string>()
allLayers.forEach((l) => builtinLayerIds.add(l.id))
const inlineLayers = new Map<string, string>()
for (const layout of Array.from(AllKnownLayouts.allKnownLayouts.values())) {
if (layout.hideFromOverview) {
continue
}
for (const layer of layout.layers) {
if (Constants.priviliged_layers.indexOf(layer.id) >= 0) {
continue
}
if (builtinLayerIds.has(layer.id)) {
continue
}
if (layer.source.geojsonSource !== undefined) {
// Not an OSM-source
continue
}
allLayers.push(layer)
builtinLayerIds.add(layer.id)
inlineLayers.set(layer.id, layout.id)
}
}
const themesPerLayer = new Map<string, string[]>()
for (const layout of Array.from(AllKnownLayouts.allKnownLayouts.values())) {
if (layout.hideFromOverview) {
continue
}
for (const layer of layout.layers) {
if (!builtinLayerIds.has(layer.id)) {
// This is an inline layer
continue
}
if (!themesPerLayer.has(layer.id)) {
themesPerLayer.set(layer.id, [])
}
themesPerLayer.get(layer.id).push(layout.id)
}
}
// Determine the cross-dependencies
const layerIsNeededBy: Map<string, string[]> = new Map<string, string[]>()
for (const layer of allLayers) {
for (const dep of DependencyCalculator.getLayerDependencies(layer)) {
const dependency = dep.neededLayer
if (!layerIsNeededBy.has(dependency)) {
layerIsNeededBy.set(dependency, [])
}
layerIsNeededBy.get(dependency).push(layer.id)
}
}
allLayers.forEach((layer) => {
const element = layer.GenerateDocumentation(
themesPerLayer.get(layer.id),
layerIsNeededBy,
DependencyCalculator.getLayerDependencies(layer)
)
callback(layer, element, inlineLayers.get(layer.id))
})
}
/**
* The wikitable is updated as some tools show an overview of apps based on the wiki.
*/
@ -131,7 +309,7 @@ console.log("Starting documentation generation...")
ScriptUtils.fixUtils()
generateWikipage()
AllKnownLayouts.GenOverviewsForSingleLayer((layer, element, inlineSource) => {
GenOverviewsForSingleLayer((layer, element, inlineSource) => {
console.log("Exporting ", layer.id)
if (!existsSync("./Docs/Layers")) {
mkdirSync("./Docs/Layers")
@ -144,7 +322,7 @@ AllKnownLayouts.GenOverviewsForSingleLayer((layer, element, inlineSource) => {
})
Array.from(AllKnownLayouts.allKnownLayouts.values()).map((theme) => {
const docs = AllKnownLayouts.GenerateDocumentationForTheme(theme)
const docs = GenerateDocumentationForTheme(theme)
WriteFile(
"./Docs/Themes/" + theme.id + ".md",
docs,
@ -167,9 +345,7 @@ WriteFile(
WriteFile("./Docs/SpecialInputElements.md", ValidatedTextField.HelpText(), [
"UI/Input/ValidatedTextField.ts",
])
WriteFile("./Docs/BuiltinLayers.md", AllKnownLayouts.GenLayerOverviewText(), [
"Customizations/AllKnownLayouts.ts",
])
WriteFile("./Docs/BuiltinLayers.md", GenLayerOverviewText(), ["Customizations/AllKnownLayouts.ts"])
WriteFile("./Docs/BuiltinQuestions.md", SharedTagRenderings.HelpText(), [
"Customizations/SharedTagRenderings.ts",
"assets/tagRenderings/questions.json",