methanol 0.0.11 → 0.0.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -2
- package/package.json +2 -2
- package/src/build-system.js +116 -44
- package/src/components.js +16 -18
- package/src/config.js +13 -2
- package/src/dev-server.js +156 -25
- package/src/logger.js +15 -3
- package/src/mdx.js +58 -38
- package/src/pages.js +216 -56
- package/src/reframe.js +13 -6
- package/src/stage-logger.js +2 -1
- package/src/state.js +18 -14
- package/src/workers/build-pool.js +156 -0
- package/src/workers/build-worker.js +231 -0
- package/src/workers/mdx-compile-worker.js +60 -0
- package/themes/default/components/ThemeAccentSwitch.static.jsx +3 -3
- package/themes/default/components/ThemeColorSwitch.static.jsx +3 -3
- package/themes/default/components/pre.client.jsx +2 -2
- package/themes/default/{public → sources}/theme-prepare.js +3 -2
- package/themes/default/src/nav-tree.jsx +6 -5
- package/themes/default/src/page.jsx +3 -3
package/src/mdx.js
CHANGED
|
@@ -40,16 +40,9 @@ import { linkResolve } from './rehype-plugins/link-resolve.js'
|
|
|
40
40
|
// Workaround for Vite: it doesn't support resolving module/virtual modules in script src in dev mode
|
|
41
41
|
const resolveRewindInject = () =>
|
|
42
42
|
HTMLRenderer.rawHTML(`<script type="module" src="${withBase('/.methanol_virtual_module/inject.js')}"></script>`)
|
|
43
|
-
const RWND_FALLBACK = HTMLRenderer.rawHTML
|
|
44
|
-
if
|
|
45
|
-
|
|
46
|
-
const r = function(k,i,p) {
|
|
47
|
-
l.push([k,i,p,document.currentScript])
|
|
48
|
-
}
|
|
49
|
-
r.$$loaded = l
|
|
50
|
-
window.$$rfrm = r
|
|
51
|
-
}
|
|
52
|
-
</script>`
|
|
43
|
+
const RWND_FALLBACK = HTMLRenderer.rawHTML(
|
|
44
|
+
'<script>if(!window.$$rfrm){var l=[];var r=function(k,i,p){l.push([k,i,p,document.currentScript])};r.$$loaded=l;window.$$rfrm=r}</script>'
|
|
45
|
+
)
|
|
53
46
|
|
|
54
47
|
let cachedHeadAssets = null
|
|
55
48
|
|
|
@@ -131,9 +124,7 @@ const resolvePageHeadAssets = (page) => {
|
|
|
131
124
|
export const buildPageContext = ({ routePath, path, pageMeta, pagesContext, lazyPagesTree = false }) => {
|
|
132
125
|
const page = pageMeta
|
|
133
126
|
const language = pagesContext.getLanguageForRoute ? pagesContext.getLanguageForRoute(routePath) : null
|
|
134
|
-
const getSiblings = pagesContext.getSiblings
|
|
135
|
-
? () => pagesContext.getSiblings(routePath, page.path || path)
|
|
136
|
-
: null
|
|
127
|
+
const getSiblings = pagesContext.getSiblings ? () => pagesContext.getSiblings(routePath, page.path || path) : null
|
|
137
128
|
if (page && getSiblings && page.getSiblings !== getSiblings) {
|
|
138
129
|
page.getSiblings = getSiblings
|
|
139
130
|
}
|
|
@@ -215,7 +206,7 @@ const normalizeStarryNightConfig = (value) => {
|
|
|
215
206
|
}
|
|
216
207
|
if (typeof value !== 'object') return null
|
|
217
208
|
const { enabled, options, ...rest } = value
|
|
218
|
-
if (enabled === false) return { enabled: false, options
|
|
209
|
+
if (enabled === false) return { enabled: false, options }
|
|
219
210
|
if (options && typeof options === 'object') {
|
|
220
211
|
return { enabled: true, options: { ...options } }
|
|
221
212
|
}
|
|
@@ -289,12 +280,17 @@ const resolveMdxConfigForPage = async (frontmatter) => {
|
|
|
289
280
|
return mdxConfig
|
|
290
281
|
}
|
|
291
282
|
|
|
292
|
-
export const
|
|
293
|
-
const mdxConfig = await resolveMdxConfigForPage(
|
|
294
|
-
const runtimeFactory = mdxConfig.development ? JSXDevFactory : JSXFactory
|
|
283
|
+
export const compileMdxSource = async ({ content, path, frontmatter }) => {
|
|
284
|
+
const mdxConfig = await resolveMdxConfigForPage(frontmatter)
|
|
295
285
|
const compiled = await compile({ value: content, path: path }, mdxConfig)
|
|
286
|
+
const code = String(compiled.value ?? compiled)
|
|
287
|
+
return { code, development: Boolean(mdxConfig.development) }
|
|
288
|
+
}
|
|
296
289
|
|
|
297
|
-
|
|
290
|
+
export const runMdxSource = async ({ code, path, ctx, development = null }) => {
|
|
291
|
+
const isDev = development == null ? state.CURRENT_MODE !== 'production' : development
|
|
292
|
+
const runtimeFactory = isDev ? JSXDevFactory : JSXFactory
|
|
293
|
+
return await run(code, {
|
|
298
294
|
...runtimeFactory,
|
|
299
295
|
baseUrl: pathToFileURL(path).href,
|
|
300
296
|
ctx,
|
|
@@ -302,9 +298,23 @@ export const compileMdx = async ({ content, path, ctx }) => {
|
|
|
302
298
|
})
|
|
303
299
|
}
|
|
304
300
|
|
|
301
|
+
export const compileMdx = async ({ content, path, ctx }) => {
|
|
302
|
+
const result = await compileMdxSource({
|
|
303
|
+
content,
|
|
304
|
+
path,
|
|
305
|
+
frontmatter: ctx?.page?.frontmatter || null
|
|
306
|
+
})
|
|
307
|
+
return await runMdxSource({
|
|
308
|
+
code: result.code,
|
|
309
|
+
path,
|
|
310
|
+
ctx,
|
|
311
|
+
development: result.development
|
|
312
|
+
})
|
|
313
|
+
}
|
|
314
|
+
|
|
305
315
|
export const compilePageMdx = async (page, pagesContext, options = {}) => {
|
|
306
316
|
if (!page || page.content == null || page.mdxComponent) return
|
|
307
|
-
const { ctx = null, lazyPagesTree = false, refreshPagesTree = true } = options || {}
|
|
317
|
+
const { ctx = null, lazyPagesTree = false, refreshPagesTree = true, compiled = null } = options || {}
|
|
308
318
|
const activeCtx =
|
|
309
319
|
ctx ||
|
|
310
320
|
buildPageContext({
|
|
@@ -314,11 +324,19 @@ export const compilePageMdx = async (page, pagesContext, options = {}) => {
|
|
|
314
324
|
pagesContext,
|
|
315
325
|
lazyPagesTree
|
|
316
326
|
})
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
327
|
+
page.mdxCtx = activeCtx
|
|
328
|
+
const mdxModule = compiled?.code
|
|
329
|
+
? await runMdxSource({
|
|
330
|
+
code: compiled.code,
|
|
331
|
+
path: page.path,
|
|
332
|
+
ctx: activeCtx,
|
|
333
|
+
development: compiled.development
|
|
334
|
+
})
|
|
335
|
+
: await compileMdx({
|
|
336
|
+
content: page.content,
|
|
337
|
+
path: page.path,
|
|
338
|
+
ctx: activeCtx
|
|
339
|
+
})
|
|
322
340
|
page.mdxComponent = mdxModule.default
|
|
323
341
|
page.toc = mdxModule.toc
|
|
324
342
|
const shouldUseTocTitle = page.frontmatter?.title == null
|
|
@@ -346,6 +364,7 @@ export const renderHtml = async ({ routePath, path, components, pagesContext, pa
|
|
|
346
364
|
pageMeta,
|
|
347
365
|
pagesContext
|
|
348
366
|
})
|
|
367
|
+
|
|
349
368
|
await compilePageMdx(pageMeta, pagesContext, { ctx })
|
|
350
369
|
|
|
351
370
|
const [Head, Outlet] = createPortal()
|
|
@@ -359,8 +378,6 @@ export const renderHtml = async ({ routePath, path, components, pagesContext, pa
|
|
|
359
378
|
]
|
|
360
379
|
}
|
|
361
380
|
|
|
362
|
-
const mdxComponent = pageMeta.mdxComponent
|
|
363
|
-
|
|
364
381
|
const PageContent = ({ components: extraComponents, ...props }, ...children) =>
|
|
365
382
|
mdxComponent({
|
|
366
383
|
children,
|
|
@@ -374,25 +391,28 @@ export const renderHtml = async ({ routePath, path, components, pagesContext, pa
|
|
|
374
391
|
})
|
|
375
392
|
|
|
376
393
|
const template = state.USER_THEME.template
|
|
394
|
+
const mdxComponent = pageMeta.mdxComponent
|
|
377
395
|
|
|
378
|
-
const renderResult = await new Promise((
|
|
396
|
+
const renderResult = await new Promise((resolve, reject) => {
|
|
379
397
|
const result = HTMLRenderer.c(
|
|
380
398
|
Suspense,
|
|
381
399
|
{
|
|
382
400
|
onLoad() {
|
|
383
|
-
nextTick(() =>
|
|
401
|
+
nextTick(() => resolve(result))
|
|
402
|
+
},
|
|
403
|
+
catch({ error }) {
|
|
404
|
+
reject(error)
|
|
384
405
|
}
|
|
385
406
|
},
|
|
386
|
-
(
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
})
|
|
407
|
+
template({
|
|
408
|
+
ctx,
|
|
409
|
+
page: ctx.page,
|
|
410
|
+
withBase,
|
|
411
|
+
PageContent,
|
|
412
|
+
ExtraHead,
|
|
413
|
+
HTMLRenderer,
|
|
414
|
+
components
|
|
415
|
+
})
|
|
396
416
|
)
|
|
397
417
|
})
|
|
398
418
|
|
package/src/pages.js
CHANGED
|
@@ -22,9 +22,11 @@ import matter from 'gray-matter'
|
|
|
22
22
|
import { readdir, readFile, stat } from 'fs/promises'
|
|
23
23
|
import { existsSync } from 'fs'
|
|
24
24
|
import { resolve, join, relative } from 'path'
|
|
25
|
+
import { cpus } from 'os'
|
|
26
|
+
import { Worker } from 'worker_threads'
|
|
25
27
|
import { state, cli } from './state.js'
|
|
26
28
|
import { withBase } from './config.js'
|
|
27
|
-
import { compilePageMdx } from './mdx.js'
|
|
29
|
+
import { compileMdxSource, compilePageMdx } from './mdx.js'
|
|
28
30
|
import { createStageLogger } from './stage-logger.js'
|
|
29
31
|
|
|
30
32
|
const isPageFile = (name) => name.endsWith('.mdx') || name.endsWith('.md')
|
|
@@ -32,6 +34,137 @@ const isIgnoredEntry = (name) => name.startsWith('.') || name.startsWith('_')
|
|
|
32
34
|
|
|
33
35
|
const pageMetadataCache = new Map()
|
|
34
36
|
const pageDerivedCache = new Map()
|
|
37
|
+
const MDX_WORKER_URL = new URL('./workers/mdx-compile-worker.js', import.meta.url)
|
|
38
|
+
const cliOverrides = {
|
|
39
|
+
CLI_INTERMEDIATE_DIR: cli.CLI_INTERMEDIATE_DIR,
|
|
40
|
+
CLI_EMIT_INTERMEDIATE: cli.CLI_EMIT_INTERMEDIATE,
|
|
41
|
+
CLI_HOST: cli.CLI_HOST,
|
|
42
|
+
CLI_PORT: cli.CLI_PORT,
|
|
43
|
+
CLI_PAGES_DIR: cli.CLI_PAGES_DIR,
|
|
44
|
+
CLI_COMPONENTS_DIR: cli.CLI_COMPONENTS_DIR,
|
|
45
|
+
CLI_ASSETS_DIR: cli.CLI_ASSETS_DIR,
|
|
46
|
+
CLI_OUTPUT_DIR: cli.CLI_OUTPUT_DIR,
|
|
47
|
+
CLI_CONFIG_PATH: cli.CLI_CONFIG_PATH,
|
|
48
|
+
CLI_SITE_NAME: cli.CLI_SITE_NAME,
|
|
49
|
+
CLI_CODE_HIGHLIGHTING: cli.CLI_CODE_HIGHLIGHTING,
|
|
50
|
+
CLI_JOBS: cli.CLI_JOBS,
|
|
51
|
+
CLI_VERBOSE: cli.CLI_VERBOSE,
|
|
52
|
+
CLI_BASE: cli.CLI_BASE,
|
|
53
|
+
CLI_SEARCH: cli.CLI_SEARCH,
|
|
54
|
+
CLI_PWA: cli.CLI_PWA
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const resolveWorkerCount = (total) => {
|
|
58
|
+
const cpuCount = Math.max(1, cpus()?.length || 1)
|
|
59
|
+
const requested = state.WORKER_JOBS
|
|
60
|
+
if (requested == null || requested <= 0) {
|
|
61
|
+
const items = Math.max(1, Number.isFinite(total) ? total : 1)
|
|
62
|
+
const autoCount = Math.round(Math.log(items))
|
|
63
|
+
return Math.max(1, Math.min(cpuCount, autoCount))
|
|
64
|
+
}
|
|
65
|
+
return Math.max(1, Math.min(cpuCount, Math.floor(requested)))
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const compileMdxSources = async (pages, options = {}) => {
|
|
69
|
+
const targets = pages.filter((page) => page && page.content != null && !page.mdxComponent)
|
|
70
|
+
const results = new Map()
|
|
71
|
+
if (!targets.length) return results
|
|
72
|
+
const { onProgress } = options || {}
|
|
73
|
+
const reportProgress = (page) => {
|
|
74
|
+
if (typeof onProgress === 'function') {
|
|
75
|
+
onProgress(page)
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
const workerCount = Math.min(resolveWorkerCount(targets.length), targets.length)
|
|
79
|
+
if (workerCount <= 1) {
|
|
80
|
+
for (const page of targets) {
|
|
81
|
+
const result = await compileMdxSource({
|
|
82
|
+
content: page.content,
|
|
83
|
+
path: page.path,
|
|
84
|
+
frontmatter: page.frontmatter
|
|
85
|
+
})
|
|
86
|
+
results.set(page, result)
|
|
87
|
+
reportProgress(page)
|
|
88
|
+
}
|
|
89
|
+
return results
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
return await new Promise((resolve, reject) => {
|
|
93
|
+
const workers = []
|
|
94
|
+
const pending = new Map()
|
|
95
|
+
let cursor = 0
|
|
96
|
+
let nextId = 0
|
|
97
|
+
let finished = false
|
|
98
|
+
|
|
99
|
+
const finalize = async (error) => {
|
|
100
|
+
if (finished) return
|
|
101
|
+
finished = true
|
|
102
|
+
await Promise.all(workers.map((worker) => worker.terminate().catch(() => null)))
|
|
103
|
+
if (error) {
|
|
104
|
+
reject(error)
|
|
105
|
+
return
|
|
106
|
+
}
|
|
107
|
+
resolve(results)
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
const assign = (worker) => {
|
|
111
|
+
if (cursor >= targets.length) return false
|
|
112
|
+
const page = targets[cursor++]
|
|
113
|
+
const id = nextId++
|
|
114
|
+
pending.set(id, page)
|
|
115
|
+
worker.postMessage({
|
|
116
|
+
id,
|
|
117
|
+
path: page.path,
|
|
118
|
+
content: page.content,
|
|
119
|
+
frontmatter: page.frontmatter
|
|
120
|
+
})
|
|
121
|
+
return true
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const handleMessage = (worker, message) => {
|
|
125
|
+
if (finished) return
|
|
126
|
+
const { id, result, error } = message || {}
|
|
127
|
+
const page = pending.get(id)
|
|
128
|
+
pending.delete(id)
|
|
129
|
+
if (!page) return
|
|
130
|
+
if (error) {
|
|
131
|
+
void finalize(new Error(error))
|
|
132
|
+
return
|
|
133
|
+
}
|
|
134
|
+
results.set(page, result)
|
|
135
|
+
reportProgress(page)
|
|
136
|
+
assign(worker)
|
|
137
|
+
if (results.size === targets.length && pending.size === 0) {
|
|
138
|
+
void finalize()
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
const handleError = (error) => {
|
|
143
|
+
if (finished) return
|
|
144
|
+
void finalize(error instanceof Error ? error : new Error(String(error)))
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
for (let i = 0; i < workerCount; i += 1) {
|
|
148
|
+
const worker = new Worker(MDX_WORKER_URL, {
|
|
149
|
+
type: 'module',
|
|
150
|
+
workerData: {
|
|
151
|
+
mode: state.CURRENT_MODE,
|
|
152
|
+
configPath: cli.CLI_CONFIG_PATH,
|
|
153
|
+
cli: cliOverrides
|
|
154
|
+
}
|
|
155
|
+
})
|
|
156
|
+
workers.push(worker)
|
|
157
|
+
worker.on('message', (message) => handleMessage(worker, message))
|
|
158
|
+
worker.on('error', handleError)
|
|
159
|
+
worker.on('exit', (code) => {
|
|
160
|
+
if (code !== 0) {
|
|
161
|
+
handleError(new Error(`MDX worker exited with code ${code}`))
|
|
162
|
+
}
|
|
163
|
+
})
|
|
164
|
+
assign(worker)
|
|
165
|
+
}
|
|
166
|
+
})
|
|
167
|
+
}
|
|
35
168
|
|
|
36
169
|
const collectLanguagesFromPages = (pages = []) => {
|
|
37
170
|
const languages = new Map()
|
|
@@ -616,47 +749,12 @@ const buildNavSequence = (nodes, pagesByRoute) => {
|
|
|
616
749
|
return result
|
|
617
750
|
}
|
|
618
751
|
|
|
619
|
-
export const
|
|
620
|
-
const
|
|
621
|
-
const
|
|
622
|
-
const
|
|
623
|
-
const collected = await collectPages()
|
|
624
|
-
stageLogger.end(collectToken)
|
|
625
|
-
let pages = collected.pages
|
|
626
|
-
const excludedRoutes = collected.excludedRoutes
|
|
627
|
-
const excludedDirs = collected.excludedDirs
|
|
628
|
-
const hasIndex = pages.some((page) => page.routePath === '/')
|
|
629
|
-
if (!hasIndex) {
|
|
630
|
-
const content = buildIndexFallback(pages, state.SITE_NAME)
|
|
631
|
-
pages.unshift({
|
|
632
|
-
routePath: '/',
|
|
633
|
-
routeHref: withBase('/'),
|
|
634
|
-
path: resolve(state.PAGES_DIR, 'index.md'),
|
|
635
|
-
relativePath: 'index.md',
|
|
636
|
-
name: 'index',
|
|
637
|
-
dir: '',
|
|
638
|
-
segments: [],
|
|
639
|
-
depth: 0,
|
|
640
|
-
isIndex: true,
|
|
641
|
-
title: state.SITE_NAME || 'Methanol Site',
|
|
642
|
-
weight: null,
|
|
643
|
-
date: null,
|
|
644
|
-
isRoot: false,
|
|
645
|
-
hidden: false,
|
|
646
|
-
content,
|
|
647
|
-
frontmatter: {},
|
|
648
|
-
matter: null,
|
|
649
|
-
stats: { size: content.length, createdAt: null, updatedAt: null },
|
|
650
|
-
createdAt: null,
|
|
651
|
-
updatedAt: null
|
|
652
|
-
})
|
|
653
|
-
if (excludedRoutes?.has('/')) {
|
|
654
|
-
excludedRoutes.delete('/')
|
|
655
|
-
}
|
|
656
|
-
}
|
|
657
|
-
|
|
752
|
+
export const createPagesContextFromPages = ({ pages, excludedRoutes, excludedDirs } = {}) => {
|
|
753
|
+
const pageList = Array.isArray(pages) ? pages : []
|
|
754
|
+
const routeExcludes = excludedRoutes || new Set()
|
|
755
|
+
const dirExcludes = excludedDirs || new Set()
|
|
658
756
|
const pagesByRoute = new Map()
|
|
659
|
-
for (const page of
|
|
757
|
+
for (const page of pageList) {
|
|
660
758
|
if (!pagesByRoute.has(page.routePath)) {
|
|
661
759
|
pagesByRoute.set(page.routePath, page)
|
|
662
760
|
}
|
|
@@ -703,7 +801,7 @@ export const buildPagesContext = async ({ compileAll = true } = {}) => {
|
|
|
703
801
|
}
|
|
704
802
|
let pagesTree = getPagesTree('/')
|
|
705
803
|
const notFound = pagesByRoute.get('/404') || null
|
|
706
|
-
const languages = collectLanguagesFromPages(
|
|
804
|
+
const languages = collectLanguagesFromPages(pageList)
|
|
707
805
|
const userSite = state.USER_SITE || {}
|
|
708
806
|
const siteBase = state.VITE_BASE ?? userSite.base ?? null
|
|
709
807
|
const site = {
|
|
@@ -723,9 +821,9 @@ export const buildPagesContext = async ({ compileAll = true } = {}) => {
|
|
|
723
821
|
},
|
|
724
822
|
generatedAt: new Date().toISOString()
|
|
725
823
|
}
|
|
726
|
-
const excludedDirPaths = new Set(Array.from(
|
|
824
|
+
const excludedDirPaths = new Set(Array.from(dirExcludes).map((dir) => `/${dir}`))
|
|
727
825
|
const pagesContext = {
|
|
728
|
-
pages,
|
|
826
|
+
pages: pageList,
|
|
729
827
|
pagesByRoute,
|
|
730
828
|
getPageByRoute,
|
|
731
829
|
pagesTree,
|
|
@@ -775,34 +873,96 @@ export const buildPagesContext = async ({ compileAll = true } = {}) => {
|
|
|
775
873
|
pagesContext.getLanguageForRoute = (routePath) =>
|
|
776
874
|
resolveLanguageForRoute(pagesContext.languages, routePath)
|
|
777
875
|
},
|
|
778
|
-
excludedRoutes,
|
|
779
|
-
excludedDirs,
|
|
876
|
+
excludedRoutes: routeExcludes,
|
|
877
|
+
excludedDirs: dirExcludes,
|
|
780
878
|
excludedDirPaths,
|
|
781
879
|
notFound,
|
|
782
880
|
languages,
|
|
783
881
|
getLanguageForRoute: (routePath) => resolveLanguageForRoute(languages, routePath),
|
|
784
882
|
site
|
|
785
883
|
}
|
|
884
|
+
return pagesContext
|
|
885
|
+
}
|
|
886
|
+
|
|
887
|
+
export const buildPagesContext = async ({ compileAll = true } = {}) => {
|
|
888
|
+
const logEnabled = state.CURRENT_MODE === 'production' && cli.command === 'build'
|
|
889
|
+
const stageLogger = createStageLogger(logEnabled)
|
|
890
|
+
const collectToken = stageLogger.start('Collecting pages')
|
|
891
|
+
const collected = await collectPages()
|
|
892
|
+
stageLogger.end(collectToken)
|
|
893
|
+
let pages = collected.pages
|
|
894
|
+
const excludedRoutes = collected.excludedRoutes
|
|
895
|
+
const excludedDirs = collected.excludedDirs
|
|
896
|
+
const hasIndex = pages.some((page) => page.routePath === '/')
|
|
897
|
+
if (!hasIndex) {
|
|
898
|
+
const content = buildIndexFallback(pages, state.SITE_NAME)
|
|
899
|
+
pages.unshift({
|
|
900
|
+
routePath: '/',
|
|
901
|
+
routeHref: withBase('/'),
|
|
902
|
+
path: resolve(state.PAGES_DIR, 'index.md'),
|
|
903
|
+
relativePath: 'index.md',
|
|
904
|
+
name: 'index',
|
|
905
|
+
dir: '',
|
|
906
|
+
segments: [],
|
|
907
|
+
depth: 0,
|
|
908
|
+
isIndex: true,
|
|
909
|
+
title: state.SITE_NAME || 'Methanol Site',
|
|
910
|
+
weight: null,
|
|
911
|
+
date: null,
|
|
912
|
+
isRoot: false,
|
|
913
|
+
hidden: false,
|
|
914
|
+
content,
|
|
915
|
+
frontmatter: {},
|
|
916
|
+
matter: null,
|
|
917
|
+
stats: { size: content.length, createdAt: null, updatedAt: null },
|
|
918
|
+
createdAt: null,
|
|
919
|
+
updatedAt: null
|
|
920
|
+
})
|
|
921
|
+
if (excludedRoutes?.has('/')) {
|
|
922
|
+
excludedRoutes.delete('/')
|
|
923
|
+
}
|
|
924
|
+
}
|
|
925
|
+
|
|
926
|
+
const pagesContext = createPagesContextFromPages({
|
|
927
|
+
pages,
|
|
928
|
+
excludedRoutes,
|
|
929
|
+
excludedDirs
|
|
930
|
+
})
|
|
786
931
|
if (compileAll) {
|
|
787
932
|
const compileToken = stageLogger.start('Compiling MDX')
|
|
788
|
-
const
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
933
|
+
const compileTargets = pages.filter((page) => page && page.content != null && !page.mdxComponent)
|
|
934
|
+
const totalPages = compileTargets.length
|
|
935
|
+
let completed = 0
|
|
936
|
+
const compiledSources = await compileMdxSources(compileTargets, {
|
|
937
|
+
onProgress: (page) => {
|
|
938
|
+
if (!logEnabled) return
|
|
939
|
+
completed += 1
|
|
792
940
|
stageLogger.update(
|
|
793
941
|
compileToken,
|
|
794
|
-
`Compiling MDX [${
|
|
942
|
+
`Compiling MDX [${completed}/${totalPages}] ${page.routePath || page.path}`
|
|
795
943
|
)
|
|
796
944
|
}
|
|
945
|
+
})
|
|
946
|
+
stageLogger.end(compileToken)
|
|
947
|
+
const executeToken = stageLogger.start('Running MDX')
|
|
948
|
+
completed = 0
|
|
949
|
+
for (const page of compileTargets) {
|
|
950
|
+
const compiled = compiledSources.get(page) || null
|
|
797
951
|
await compilePageMdx(page, pagesContext, {
|
|
798
952
|
lazyPagesTree: true,
|
|
799
|
-
refreshPagesTree: false
|
|
953
|
+
refreshPagesTree: false,
|
|
954
|
+
compiled
|
|
800
955
|
})
|
|
956
|
+
if (logEnabled) {
|
|
957
|
+
completed += 1
|
|
958
|
+
stageLogger.update(
|
|
959
|
+
executeToken,
|
|
960
|
+
`Running MDX [${completed}/${totalPages}] ${page.routePath || page.path}`
|
|
961
|
+
)
|
|
962
|
+
}
|
|
801
963
|
}
|
|
802
|
-
stageLogger.end(
|
|
803
|
-
|
|
804
|
-
pagesTree = getPagesTree('/')
|
|
805
|
-
pagesContext.pagesTree = pagesTree
|
|
964
|
+
stageLogger.end(executeToken)
|
|
965
|
+
pagesContext.refreshPagesTree?.()
|
|
806
966
|
}
|
|
807
967
|
return pagesContext
|
|
808
968
|
}
|
package/src/reframe.js
CHANGED
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
* under the License.
|
|
19
19
|
*/
|
|
20
20
|
|
|
21
|
+
import { lazy } from 'refui'
|
|
21
22
|
import fnv1a from '@sindresorhus/fnv1a'
|
|
22
23
|
import JSON5 from 'json5'
|
|
23
24
|
|
|
@@ -45,8 +46,12 @@ export function env(parentEnv) {
|
|
|
45
46
|
|
|
46
47
|
let renderCount = 0
|
|
47
48
|
|
|
48
|
-
function
|
|
49
|
-
const { clientPath,
|
|
49
|
+
function register(info) {
|
|
50
|
+
const { clientPath, staticPath, staticImportURL, exportName } = info
|
|
51
|
+
|
|
52
|
+
if (!clientPath) {
|
|
53
|
+
return lazy(() => import(staticImportURL))
|
|
54
|
+
}
|
|
50
55
|
|
|
51
56
|
let key = null
|
|
52
57
|
let _clientPath = clientPath
|
|
@@ -55,7 +60,9 @@ export function env(parentEnv) {
|
|
|
55
60
|
key = hash(_clientPath)
|
|
56
61
|
} while (keyPathRegistry[key] && keyPathRegistry[key] !== clientPath)
|
|
57
62
|
|
|
58
|
-
const component = ({ children: childrenProp, ...props }, ...children) => {
|
|
63
|
+
const component = async ({ children: childrenProp, ...props }, ...children) => {
|
|
64
|
+
const staticComponent = (await import(staticImportURL)).default
|
|
65
|
+
|
|
59
66
|
const id = renderCount++
|
|
60
67
|
const idStr = id.toString(16)
|
|
61
68
|
const script = `$$rfrm(${JSON.stringify(key)},${id},${Object.keys(props).length ? JSON5.stringify(props) : '{}'})`
|
|
@@ -63,13 +70,13 @@ export function env(parentEnv) {
|
|
|
63
70
|
return (R) => {
|
|
64
71
|
return [
|
|
65
72
|
R.createAnchor(`{${idStr}}`, true),
|
|
66
|
-
R.c(
|
|
73
|
+
staticComponent ? R.c(
|
|
67
74
|
staticComponent,
|
|
68
75
|
props,
|
|
69
76
|
R.createAnchor(`[${idStr}[`, true),
|
|
70
77
|
...children,
|
|
71
78
|
R.createAnchor(`]${idStr}]`, true)
|
|
72
|
-
),
|
|
79
|
+
): null,
|
|
73
80
|
R.c('script', null, R.rawHTML(script))
|
|
74
81
|
]
|
|
75
82
|
}
|
|
@@ -106,7 +113,7 @@ export function env(parentEnv) {
|
|
|
106
113
|
}
|
|
107
114
|
|
|
108
115
|
return {
|
|
109
|
-
|
|
116
|
+
register,
|
|
110
117
|
invalidate,
|
|
111
118
|
genRegistryScript,
|
|
112
119
|
setParent,
|
package/src/stage-logger.js
CHANGED
|
@@ -41,7 +41,8 @@ export const createStageLogger = (enabled) => {
|
|
|
41
41
|
}
|
|
42
42
|
const padding = lastLength > text.length ? ' '.repeat(lastLength - text.length) : ''
|
|
43
43
|
const clearLine = '\u001b[2K'
|
|
44
|
-
|
|
44
|
+
const reset = '\x1b[0m'
|
|
45
|
+
process.stdout.write(`${clearLine}\r${reset}${text}${reset}${padding}${newline ? '\n' : ''}`)
|
|
45
46
|
lastLength = text.length
|
|
46
47
|
}
|
|
47
48
|
const start = (label) => {
|
package/src/state.js
CHANGED
|
@@ -104,14 +104,14 @@ const withCommonOptions = (y) =>
|
|
|
104
104
|
.option('highlight', {
|
|
105
105
|
describe: 'Enable or disable code highlighting',
|
|
106
106
|
type: 'boolean',
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
107
|
+
default: undefined
|
|
108
|
+
})
|
|
109
|
+
.option('jobs', {
|
|
110
|
+
alias: 'j',
|
|
111
|
+
describe: 'Worker thread count (0 for auto)',
|
|
112
|
+
type: 'number',
|
|
113
|
+
requiresArg: true,
|
|
114
|
+
nargs: 1
|
|
115
115
|
})
|
|
116
116
|
.option('verbose', {
|
|
117
117
|
alias: 'v',
|
|
@@ -126,12 +126,14 @@ const withCommonOptions = (y) =>
|
|
|
126
126
|
nargs: 1
|
|
127
127
|
})
|
|
128
128
|
.option('search', {
|
|
129
|
-
describe: 'Enable search indexing (pagefind)',
|
|
130
|
-
type: 'boolean'
|
|
129
|
+
describe: 'Enable or disable search indexing (pagefind)',
|
|
130
|
+
type: 'boolean',
|
|
131
|
+
default: undefined
|
|
131
132
|
})
|
|
132
133
|
.option('pwa', {
|
|
133
|
-
describe: 'Enable PWA support',
|
|
134
|
-
type: 'boolean'
|
|
134
|
+
describe: 'Enable or disable PWA support',
|
|
135
|
+
type: 'boolean',
|
|
136
|
+
default: undefined
|
|
135
137
|
})
|
|
136
138
|
|
|
137
139
|
const parser = yargs(hideBin(process.argv))
|
|
@@ -161,10 +163,11 @@ export const cli = {
|
|
|
161
163
|
CLI_CONFIG_PATH: argv.config || null,
|
|
162
164
|
CLI_SITE_NAME: argv['site-name'] || null,
|
|
163
165
|
CLI_CODE_HIGHLIGHTING: typeof argv.highlight === 'boolean' ? argv.highlight : null,
|
|
166
|
+
CLI_JOBS: typeof argv.jobs === 'number' && Number.isFinite(argv.jobs) ? argv.jobs : null,
|
|
164
167
|
CLI_VERBOSE: Boolean(argv.verbose),
|
|
165
168
|
CLI_BASE: argv.base || null,
|
|
166
|
-
CLI_SEARCH: argv.search,
|
|
167
|
-
CLI_PWA: argv.pwa
|
|
169
|
+
CLI_SEARCH: typeof argv.search === 'boolean' ? argv.search : undefined,
|
|
170
|
+
CLI_PWA: typeof argv.pwa === 'boolean' ? argv.pwa : undefined
|
|
168
171
|
}
|
|
169
172
|
|
|
170
173
|
export const state = {
|
|
@@ -204,6 +207,7 @@ export const state = {
|
|
|
204
207
|
THEME_POST_BUNDLE_HOOKS: [],
|
|
205
208
|
STARRY_NIGHT_ENABLED: false,
|
|
206
209
|
STARRY_NIGHT_OPTIONS: null,
|
|
210
|
+
WORKER_JOBS: 0,
|
|
207
211
|
GFM_ENABLED: true,
|
|
208
212
|
PWA_ENABLED: false,
|
|
209
213
|
PWA_OPTIONS: null,
|