Fix fetchData

The fetchData function suffer from a race condition. If the function is
called before the promise finishes, it will result in another pair of
HTTP request. This does not only make the function useless but
Actually, it makes it harmful as the data might be redownloaded twice.

Now fetchData is not a function but rather the promise by itself.
Previous callers are expected to await the variable instead, this
should be not concern as awaiting a promise multiple time in
JavaScript is completely safe.
This commit is contained in:
Claudio Yanes 2022-03-04 02:25:30 +00:00
parent 1313bd9779
commit 7e0f2e4449
7 changed files with 16 additions and 26 deletions

View file

@ -16,7 +16,7 @@ jobs:
with: with:
index: true index: true
input: content input: content
output: static output: assets/indices
root: . root: .
- name: Setup Hugo - name: Setup Hugo

4
.gitignore vendored
View file

@ -3,5 +3,5 @@ public
resources resources
.idea .idea
content/.obsidian content/.obsidian
static/linkIndex.json assets/indices/linkIndex.json
static/contentIndex.json assets/indices/contentIndex.json

View file

@ -1,5 +1,5 @@
async function drawGraph(url, baseUrl, pathColors, depth, enableDrag, enableLegend, enableZoom) { async function drawGraph(url, baseUrl, pathColors, depth, enableDrag, enableLegend, enableZoom) {
const { index, links, content } = await fetchData() const { index, links, content } = await fetchData
const curPage = url.replace(baseUrl, "") const curPage = url.replace(baseUrl, "")
const parseIdsFromLinks = (links) => [...(new Set(links.flatMap(link => ([link.source, link.target]))))] const parseIdsFromLinks = (links) => [...(new Set(links.flatMap(link => ([link.source, link.target]))))]

View file

@ -8,7 +8,7 @@ function htmlToElement(html) {
function initPopover(base) { function initPopover(base) {
const baseUrl = base.replace(window.location.origin, "") // is this useless? const baseUrl = base.replace(window.location.origin, "") // is this useless?
document.addEventListener("DOMContentLoaded", () => { document.addEventListener("DOMContentLoaded", () => {
fetchData().then(({content}) => { fetchData.then(({content}) => {
const links = [...document.getElementsByClassName("internal-link")] const links = [...document.getElementsByClassName("internal-link")]
links.forEach(li => { links.forEach(li => {
const linkDest = content[li.dataset.src.replace(baseUrl, "")] const linkDest = content[li.dataset.src.replace(baseUrl, "")]

View file

@ -81,7 +81,7 @@ const removeMarkdown = (
} }
}) })
const { content } = await fetchData() const { content } = await fetchData
for (const [key, value] of Object.entries(content)) { for (const [key, value] of Object.entries(content)) {
contentIndex.add({ contentIndex.add({
id: key, id: key,

View file

@ -3,9 +3,9 @@
{{$url := urls.Parse .Site.BaseURL }} {{$url := urls.Parse .Site.BaseURL }}
{{$host := strings.TrimRight "/" $url.Path }} {{$host := strings.TrimRight "/" $url.Path }}
{{$curPage := strings.TrimPrefix $host (strings.TrimRight "/" .Page.RelPermalink) }} {{$curPage := strings.TrimPrefix $host (strings.TrimRight "/" .Page.RelPermalink) }}
{{$linkIndex := getJSON "/static/linkIndex.json"}} {{$linkIndex := getJSON "/assets/indices/linkIndex.json"}}
{{$inbound := index $linkIndex.index.backlinks $curPage}} {{$inbound := index $linkIndex.index.backlinks $curPage}}
{{$contentTable := getJSON "/static/contentIndex.json"}} {{$contentTable := getJSON "/assets/indices/contentIndex.json"}}
{{if $inbound}} {{if $inbound}}
{{$cleanedInbound := apply (apply $inbound "index" "." "source") "replace" "." " " "-"}} {{$cleanedInbound := apply (apply $inbound "index" "." "source") "replace" "." " " "-"}}
{{- range $cleanedInbound | uniq -}} {{- range $cleanedInbound | uniq -}}

View file

@ -21,35 +21,25 @@
<script src="{{$darkMode.Permalink}}"></script> <script src="{{$darkMode.Permalink}}"></script>
<!-- Preload page vars --> <!-- Preload page vars -->
{{$linkIndex := resources.Get "indices/linkIndex.json" | resources.Fingerprint "md5" | resources.Minify | }}
{{$contentIndex := resources.Get "indices/contentIndex.json" | resources.Fingerprint "md5" | resources.Minify }}
<script> <script>
const BASE_URL = {{.Site.BaseURL}} const BASE_URL = {{.Site.BaseURL}}
let saved = false const fetchData = Promise.all([
const fetchData = async () => { fetch("{{ $linkIndex.Permalink }}")
if (saved) {
return saved
} else {
const promises = [
fetch("{{ .Site.BaseURL }}/linkIndex.json")
.then(data => data.json()) .then(data => data.json())
.then(data => ({ .then(data => ({
index: data.index, index: data.index,
links: data.links, links: data.links,
})), })),
fetch("{{ .Site.BaseURL }}/contentIndex.json") fetch("{{ $contentIndex.Permalink }}")
.then(data => data.json()), .then(data => data.json()),
] ])
const [{index, links}, content] = await Promise.all(promises) .then(([{index, links}, content]) => ({
const res = ({
index, index,
links, links,
content, content,
}) }))
saved = res
return res
}
}
fetchData()
</script> </script>
</head> </head>
{{ template "_internal/google_analytics.html" . }} {{ template "_internal/google_analytics.html" . }}