Skip to content

Commit 0c12d5e

Browse files
slusarzcmouse
authored andcommitted
utility.js: Make loadData() a sync function
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.
1 parent c910614 commit 0c12d5e

File tree

11 files changed

+73
-26
lines changed

11 files changed

+73
-26
lines changed

.vitepress/config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ export default defineConfig({
131131
},
132132

133133
markdown: {
134-
config: async (md) => await dovecotMdExtend(md),
134+
config: (md) => dovecotMdExtend(md),
135135
image: {
136136
lazyLoading: true,
137137
},

lib/data/doveadm.data.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ async function normalizeDoveadm(doveadm) {
150150
export default addWatchPaths({
151151
async load() {
152152
return await normalizeDoveadm(
153-
structuredClone((await loadData('doveadm')).doveadm)
153+
structuredClone(loadData('doveadm').doveadm)
154154
)
155155
}
156156
})

lib/data/event_categories.data.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ async function normalizeEventCategories(categories) {
1414
export default addWatchPaths({
1515
async load() {
1616
return await normalizeEventCategories(
17-
structuredClone((await loadData('event_categories')).categories)
17+
structuredClone(loadData('event_categories').categories)
1818
)
1919
}
2020
})

lib/data/event_reasons.data.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ async function normalizeEventReasons(reasons) {
1414
export default addWatchPaths({
1515
async load() {
1616
return await normalizeEventReasons(
17-
structuredClone((await loadData('event_reasons')).reasons)
17+
structuredClone(loadData('event_reasons').reasons)
1818
)
1919
}
2020
})

lib/data/events.data.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ async function normalizeEvents(events, global_inherits, inherits) {
126126

127127
export default addWatchPaths({
128128
async load() {
129-
const data = await loadData('events')
129+
const data = loadData('events')
130130
return await normalizeEvents(
131131
structuredClone(data.events),
132132
structuredClone(data.global_inherits),

lib/data/lua.data.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ async function normalizeLuaVariables(lua) {
6464

6565
export default addWatchPaths({
6666
async load() {
67-
const data = await(loadData('lua'))
67+
const data = loadData('lua')
6868

6969
return {
7070
constants: await normalizeLuaConstants(data.lua_constants),

lib/data/settings.data.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ async function normalizeSettings(settings) {
7272
export default addWatchPaths({
7373
async load() {
7474
return await normalizeSettings(
75-
structuredClone((await loadData('settings')).settings)
75+
structuredClone(loadData('settings').settings)
7676
)
7777
}
7878
})

lib/markdown.js

Lines changed: 43 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@ import path from 'path'
55
import { createMarkdownRenderer } from 'vitepress'
66
import { dovecotSetting, frontmatterIter, loadData } from './utility.js'
77

8-
let md_conf = null
9-
export async function dovecotMdExtend(md) {
8+
export function dovecotMdExtend(md) {
109
md.use(containerPlugin, 'todo', {
1110
render: function(tokens, idx) {
1211
if (tokens[idx].nesting === 1) {
@@ -17,18 +16,7 @@ export async function dovecotMdExtend(md) {
1716
}
1817
})
1918
md.use(deflistPlugin)
20-
21-
if (md_conf === null) {
22-
md_conf = {
23-
base: globalThis.VITEPRESS_CONFIG.site.base,
24-
doveadm: (await loadData('doveadm')).doveadm,
25-
events: (await loadData('events')).events,
26-
linkoverrides: (await loadData('links_overrides')).links_overrides,
27-
settings: (await loadData('settings')).settings,
28-
updates: (await loadData('updates')).updates
29-
}
30-
}
31-
md.use(dovecot_markdown, md_conf)
19+
md.use(dovecot_markdown)
3220

3321
return md
3422
}
@@ -38,7 +26,7 @@ export async function getVitepressMd() {
3826
if (vitepress_md === null) {
3927
const config = globalThis.VITEPRESS_CONFIG
4028

41-
vitepress_md = await dovecotMdExtend(await createMarkdownRenderer(
29+
vitepress_md = dovecotMdExtend(await createMarkdownRenderer(
4230
config.srcDir,
4331
config.markdown,
4432
config.site.base,
@@ -52,7 +40,7 @@ export async function getVitepressMd() {
5240
/* This is a dovecot markdown extension to support the "[[...]]" syntax.
5341
* Much of this is copied from existing markdown-it plugins. See, e.g.,
5442
* https://github.com/markdown-it/markdown-it-sub/blob/master/index.mjs */
55-
function dovecot_markdown(md, opts) {
43+
function dovecot_markdown(md) {
5644
function process_brackets(state, silent) {
5745
const max = state.posMax
5846
const start = state.pos
@@ -142,6 +130,8 @@ function dovecot_markdown(md, opts) {
142130
let page = mode
143131
switch (mode) {
144132
case 'doveadm':
133+
initDoveadm()
134+
145135
if (!opts.doveadm[env.inner]) {
146136
if (!Object.values(opts.doveadm).find((x) => (x.man == 'doveadm-' + env.inner))) {
147137
handle_error('doveadm link missing: ' + env.inner)
@@ -151,6 +141,8 @@ function dovecot_markdown(md, opts) {
151141
break
152142

153143
case 'event':
144+
initEvents()
145+
154146
if (!opts.events[env.inner]) {
155147
handle_error('event link missing: ' + env.inner)
156148
return '<code><a>'
@@ -160,6 +152,8 @@ function dovecot_markdown(md, opts) {
160152

161153
case 'setting':
162154
case 'setting_text':
155+
initSettings()
156+
163157
/* Settings names can have brackets, so we need to unescape
164158
* input for purposes of searching settings keys. */
165159
const search_str = env.inner.replaceAll('&gt;', '>')
@@ -293,6 +287,8 @@ function dovecot_markdown(md, opts) {
293287
case 'changed':
294288
case 'deprecated':
295289
case 'removed':
290+
initUpdates()
291+
296292
if (!opts.updates[env.args]) {
297293
handle_error('Missing updates entry for: ' + env.args)
298294
return env.args
@@ -373,6 +369,12 @@ function dovecot_markdown(md, opts) {
373369
console.error(msg)
374370
}
375371

372+
function initDoveadm() {
373+
if (!opts.doveadm) {
374+
opts.doveadm = loadData('doveadm').doveadm
375+
}
376+
}
377+
376378
function initDovecotLinks() {
377379
if (opts.dovecotlinks) {
378380
return
@@ -406,7 +408,15 @@ function dovecot_markdown(md, opts) {
406408
}
407409
})
408410

409-
opts.dovecotlinks = { ...links, ...opts.linkoverrides }
411+
opts.dovecotlinks = {
412+
...links, ...(loadData('links_overrides').links_overrides)
413+
}
414+
}
415+
416+
function initEvents() {
417+
if (!opts.events) {
418+
opts.events = loadData('events').events
419+
}
410420
}
411421

412422
function initManFiles() {
@@ -434,6 +444,18 @@ function dovecot_markdown(md, opts) {
434444
}
435445
}
436446

447+
function initSettings() {
448+
if (!opts.settings) {
449+
opts.settings = loadData('settings').settings
450+
}
451+
}
452+
453+
function initUpdates() {
454+
if (!opts.updates) {
455+
opts.updates = loadData('updates').updates
456+
}
457+
}
458+
437459
function resolveURL(url) {
438460
if (!('url_rewrite' in opts)) {
439461
opts.url_rewrite = dovecotSetting('url_rewrite')
@@ -445,6 +467,10 @@ function dovecot_markdown(md, opts) {
445467
return (opts.url_rewrite) ? opts.url_rewrite(new_url) : new_url
446468
}
447469

470+
const opts = {
471+
base: globalThis.VITEPRESS_CONFIG.site.base
472+
}
473+
448474
md.inline.ruler.after('emphasis', 'dovecot_brackets', process_brackets)
449475
md.renderer.rules.dovecot_open = dovecot_open
450476
md.renderer.rules.dovecot_body = dovecot_body

lib/utility.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import fg from 'fast-glob'
44
import fs from 'fs'
55
import matter from 'gray-matter'
6+
import importSync from 'import-sync'
67
import { dirname } from 'path'
78
import { fileURLToPath } from 'url'
89

@@ -26,12 +27,12 @@ export function normalizeArrayData(data, keys) {
2627
return data
2728
}
2829

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

3334
try {
34-
return await import(__dirname + '/' + path)
35+
return importSync(__dirname + '/' + path)
3536
} catch (e) {
3637
throw new Error('Unable to import module (' + __dirname + '/' +
3738
path + '):' + e)

package-lock.json

Lines changed: 19 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)