Skip to content

Commit

Permalink
utility.js: Make loadData() a sync function
Browse files Browse the repository at this point in the history
We always want loadData() to be a blocking call, as we use that code to
read the data JS files so that we can do further processing.

However, since data JS paths are dynamic, we must use import() which is
required to be an async call.

For bootstrapping purposes, this means there is no way to block markdown
processing to begin before the Dovecot markdown plugin is ready. This is
because markdown-it code MUST NOT use async code, so we need to load all the
data (via loadData()) before it can be initialized. Dovecot markdown code
also requires VitePress paths to be available in global config object, so the
only place we can realistically add the Dovecot markdown processing is via the
"config" markdown option. Unfortunately, the internal VitePress code does not
call this function with await, so there is simply no way to block processing
via this mechanism.

Solution- the import-sync nodejs package allows import behavior to be done
synchronously.

This allows us to no longer need to pre-configure the dovecot markdown plugin,
as the loadData() calls can now be called on-demand inside of the plugin. Thus,
we can guarantee that the Dovecot markdown plugin is initialized at the time
the first page is processed by VitePress now.
  • Loading branch information
slusarz authored and cmouse committed Nov 6, 2024
1 parent c910614 commit 0c12d5e
Show file tree
Hide file tree
Showing 11 changed files with 73 additions and 26 deletions.
2 changes: 1 addition & 1 deletion .vitepress/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ export default defineConfig({
},

markdown: {
config: async (md) => await dovecotMdExtend(md),
config: (md) => dovecotMdExtend(md),
image: {
lazyLoading: true,
},
Expand Down
2 changes: 1 addition & 1 deletion lib/data/doveadm.data.js
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ async function normalizeDoveadm(doveadm) {
export default addWatchPaths({
async load() {
return await normalizeDoveadm(
structuredClone((await loadData('doveadm')).doveadm)
structuredClone(loadData('doveadm').doveadm)
)
}
})
2 changes: 1 addition & 1 deletion lib/data/event_categories.data.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ async function normalizeEventCategories(categories) {
export default addWatchPaths({
async load() {
return await normalizeEventCategories(
structuredClone((await loadData('event_categories')).categories)
structuredClone(loadData('event_categories').categories)
)
}
})
2 changes: 1 addition & 1 deletion lib/data/event_reasons.data.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ async function normalizeEventReasons(reasons) {
export default addWatchPaths({
async load() {
return await normalizeEventReasons(
structuredClone((await loadData('event_reasons')).reasons)
structuredClone(loadData('event_reasons').reasons)
)
}
})
2 changes: 1 addition & 1 deletion lib/data/events.data.js
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ async function normalizeEvents(events, global_inherits, inherits) {

export default addWatchPaths({
async load() {
const data = await loadData('events')
const data = loadData('events')
return await normalizeEvents(
structuredClone(data.events),
structuredClone(data.global_inherits),
Expand Down
2 changes: 1 addition & 1 deletion lib/data/lua.data.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ async function normalizeLuaVariables(lua) {

export default addWatchPaths({
async load() {
const data = await(loadData('lua'))
const data = loadData('lua')

return {
constants: await normalizeLuaConstants(data.lua_constants),
Expand Down
2 changes: 1 addition & 1 deletion lib/data/settings.data.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ async function normalizeSettings(settings) {
export default addWatchPaths({
async load() {
return await normalizeSettings(
structuredClone((await loadData('settings')).settings)
structuredClone(loadData('settings').settings)
)
}
})
60 changes: 43 additions & 17 deletions lib/markdown.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@ import path from 'path'
import { createMarkdownRenderer } from 'vitepress'
import { dovecotSetting, frontmatterIter, loadData } from './utility.js'

let md_conf = null
export async function dovecotMdExtend(md) {
export function dovecotMdExtend(md) {
md.use(containerPlugin, 'todo', {
render: function(tokens, idx) {
if (tokens[idx].nesting === 1) {
Expand All @@ -17,18 +16,7 @@ export async function dovecotMdExtend(md) {
}
})
md.use(deflistPlugin)

if (md_conf === null) {
md_conf = {
base: globalThis.VITEPRESS_CONFIG.site.base,
doveadm: (await loadData('doveadm')).doveadm,
events: (await loadData('events')).events,
linkoverrides: (await loadData('links_overrides')).links_overrides,
settings: (await loadData('settings')).settings,
updates: (await loadData('updates')).updates
}
}
md.use(dovecot_markdown, md_conf)
md.use(dovecot_markdown)

return md
}
Expand All @@ -38,7 +26,7 @@ export async function getVitepressMd() {
if (vitepress_md === null) {
const config = globalThis.VITEPRESS_CONFIG

vitepress_md = await dovecotMdExtend(await createMarkdownRenderer(
vitepress_md = dovecotMdExtend(await createMarkdownRenderer(
config.srcDir,
config.markdown,
config.site.base,
Expand All @@ -52,7 +40,7 @@ export async function getVitepressMd() {
/* This is a dovecot markdown extension to support the "[[...]]" syntax.
* Much of this is copied from existing markdown-it plugins. See, e.g.,
* https://github.com/markdown-it/markdown-it-sub/blob/master/index.mjs */
function dovecot_markdown(md, opts) {
function dovecot_markdown(md) {
function process_brackets(state, silent) {
const max = state.posMax
const start = state.pos
Expand Down Expand Up @@ -142,6 +130,8 @@ function dovecot_markdown(md, opts) {
let page = mode
switch (mode) {
case 'doveadm':
initDoveadm()

if (!opts.doveadm[env.inner]) {
if (!Object.values(opts.doveadm).find((x) => (x.man == 'doveadm-' + env.inner))) {
handle_error('doveadm link missing: ' + env.inner)
Expand All @@ -151,6 +141,8 @@ function dovecot_markdown(md, opts) {
break

case 'event':
initEvents()

if (!opts.events[env.inner]) {
handle_error('event link missing: ' + env.inner)
return '<code><a>'
Expand All @@ -160,6 +152,8 @@ function dovecot_markdown(md, opts) {

case 'setting':
case 'setting_text':
initSettings()

/* Settings names can have brackets, so we need to unescape
* input for purposes of searching settings keys. */
const search_str = env.inner.replaceAll('&gt;', '>')
Expand Down Expand Up @@ -293,6 +287,8 @@ function dovecot_markdown(md, opts) {
case 'changed':
case 'deprecated':
case 'removed':
initUpdates()

if (!opts.updates[env.args]) {
handle_error('Missing updates entry for: ' + env.args)
return env.args
Expand Down Expand Up @@ -373,6 +369,12 @@ function dovecot_markdown(md, opts) {
console.error(msg)
}

function initDoveadm() {
if (!opts.doveadm) {
opts.doveadm = loadData('doveadm').doveadm
}
}

function initDovecotLinks() {
if (opts.dovecotlinks) {
return
Expand Down Expand Up @@ -406,7 +408,15 @@ function dovecot_markdown(md, opts) {
}
})

opts.dovecotlinks = { ...links, ...opts.linkoverrides }
opts.dovecotlinks = {
...links, ...(loadData('links_overrides').links_overrides)
}
}

function initEvents() {
if (!opts.events) {
opts.events = loadData('events').events
}
}

function initManFiles() {
Expand Down Expand Up @@ -434,6 +444,18 @@ function dovecot_markdown(md, opts) {
}
}

function initSettings() {
if (!opts.settings) {
opts.settings = loadData('settings').settings
}
}

function initUpdates() {
if (!opts.updates) {
opts.updates = loadData('updates').updates
}
}

function resolveURL(url) {
if (!('url_rewrite' in opts)) {
opts.url_rewrite = dovecotSetting('url_rewrite')
Expand All @@ -445,6 +467,10 @@ function dovecot_markdown(md, opts) {
return (opts.url_rewrite) ? opts.url_rewrite(new_url) : new_url
}

const opts = {
base: globalThis.VITEPRESS_CONFIG.site.base
}

md.inline.ruler.after('emphasis', 'dovecot_brackets', process_brackets)
md.renderer.rules.dovecot_open = dovecot_open
md.renderer.rules.dovecot_body = dovecot_body
Expand Down
5 changes: 3 additions & 2 deletions lib/utility.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import fg from 'fast-glob'
import fs from 'fs'
import matter from 'gray-matter'
import importSync from 'import-sync'
import { dirname } from 'path'
import { fileURLToPath } from 'url'

Expand All @@ -26,12 +27,12 @@ export function normalizeArrayData(data, keys) {
return data
}

export async function loadData(id) {
export function loadData(id) {
const path = globalThis.VITEPRESS_CONFIG.userConfig.themeConfig.dovecot?.data_paths?.[id]
?? ('../data/' + id + '.js')

try {
return await import(__dirname + '/' + path)
return importSync(__dirname + '/' + path)
} catch (e) {
throw new Error('Unable to import module (' + __dirname + '/' +
path + '):' + e)
Expand Down
19 changes: 19 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"dayjs": "^1.11.13",
"fast-glob": "^3.3.2",
"git-commit-info": "^2.0.2",
"import-sync": "^2.2.2",
"markdown-it-container": "^4.0.0",
"markdown-it-deflist": "^3.0.0",
"markdown-it-mathjax3": "^4.3.2",
Expand Down

0 comments on commit 0c12d5e

Please sign in to comment.