methanol 0.0.15 → 0.0.17

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "methanol",
3
- "version": "0.0.15",
3
+ "version": "0.0.17",
4
4
  "description": "Static site generator powered by rEFui and MDX",
5
5
  "main": "./index.js",
6
6
  "type": "module",
@@ -21,14 +21,15 @@
21
21
  import { readFileSync } from 'fs'
22
22
  import { fileURLToPath } from 'url'
23
23
  import { dirname, resolve } from 'path'
24
- import { cached } from '../../utils.js'
24
+ import { cached, cachedStr } from '../../utils.js'
25
25
 
26
26
  const __filename = fileURLToPath(import.meta.url)
27
27
  const __dirname = dirname(__filename)
28
28
 
29
- const readStatic = (filePath) => cached(() => readFileSync(resolve(__dirname, filePath), 'utf-8'))
29
+ export const virtualModuleDir = __dirname
30
+ export const createStaticResource = (filePath) => cached(() => readFileSync(resolve(__dirname, filePath), 'utf-8'))
30
31
 
31
- export const INJECT_SCRIPT = readStatic('./inject.js')
32
- export const LOADER_SCRIPT = readStatic('./loader.js')
33
- export const PAGEFIND_LOADER_SCRIPT = readStatic('./pagefind-loader.js')
34
- export const PWA_INJECT_SCRIPT = readStatic('./pwa-inject.js')
32
+ export const INJECT_SCRIPT = createStaticResource('./inject.js')
33
+ export const LOADER_SCRIPT = createStaticResource('./loader.js')
34
+ export const PAGEFIND_LOADER_SCRIPT = createStaticResource('./pagefind-loader.js')
35
+ export const PWA_INJECT_SCRIPT = createStaticResource('./pwa-inject.js')
package/src/dev-server.js CHANGED
@@ -38,13 +38,16 @@ import {
38
38
  } from './components.js'
39
39
  import { buildPagesContext, buildPageEntry, routePathFromFile } from './pages.js'
40
40
  import { compilePageMdx, renderHtml } from './mdx.js'
41
+ import { DevErrorPage } from './error-page.jsx'
42
+ import { HTMLRenderer } from './renderer.js'
41
43
  import { methanolResolverPlugin } from './vite-plugins.js'
42
44
  import { preparePublicAssets, updateAsset } from './public-assets.js'
43
45
  import { createBuildWorkers, runWorkerStage, terminateWorkers } from './workers/build-pool.js'
46
+ import { virtualModuleDir } from './client/virtual-module/assets.js'
44
47
  import { style } from './logger.js'
45
48
 
46
49
  export const runViteDev = async () => {
47
- const baseFsAllow = [state.ROOT_DIR, state.USER_THEME.root].filter(Boolean)
50
+ const baseFsAllow = [virtualModuleDir, state.ROOT_DIR, state.USER_THEME.root].filter(Boolean)
48
51
  if (state.MERGED_ASSETS_DIR) {
49
52
  baseFsAllow.push(state.MERGED_ASSETS_DIR)
50
53
  }
@@ -160,6 +163,29 @@ export const runViteDev = async () => {
160
163
  console.error(style.red(`\n[methanol] ${phase} error in ${target}`))
161
164
  console.error(error?.stack || error)
162
165
  }
166
+ const formatDevError = (error) => {
167
+ if (!error) return 'Unknown error'
168
+ if (typeof error === 'string') return error
169
+ if (error?.stack) return error.stack
170
+ if (error?.message) return error.message
171
+ return String(error)
172
+ }
173
+ const sendDevError = async (res, error, url = '/') => {
174
+ const message = formatDevError(error)
175
+ const basePrefix = devBasePrefix || ''
176
+ const rawHtml = HTMLRenderer.serialize(
177
+ DevErrorPage({ message, basePrefix })(HTMLRenderer)
178
+ )
179
+ let html = rawHtml
180
+ try {
181
+ html = await server.transformIndexHtml(url, rawHtml)
182
+ } catch (err) {
183
+ console.error(err)
184
+ }
185
+ res.statusCode = 500
186
+ res.setHeader('Content-Type', 'text/html')
187
+ res.end(html)
188
+ }
163
189
 
164
190
  const _invalidate = (id) => {
165
191
  const _module = server.moduleGraph.getModuleById(id)
@@ -167,20 +193,24 @@ export const runViteDev = async () => {
167
193
  server.moduleGraph.invalidateModule(_module)
168
194
  }
169
195
  }
170
- const invalidateRewindInject = () => {
171
- _invalidate('\0/.methanol_virtual_module/registry.js')
196
+ const invalidateReframeInject = () => {
172
197
  _invalidate('\0methanol:registry')
173
- _invalidate('\0/.methanol_virtual_module/inject.js')
174
198
  _invalidate('\0methanol:inject')
199
+ _invalidate(resolve(virtualModuleDir, 'inject.js'))
175
200
  }
176
201
  const invalidatePagesIndex = () => {
177
- _invalidate('\0/.methanol_virtual_module/pages.js')
178
202
  _invalidate('\0methanol:pages')
179
203
  }
180
204
 
181
205
  const refreshPagesContext = async () => {
182
206
  setPagesContext(await buildPagesContext({ compileAll: false }))
183
207
  }
208
+ const resolveStaticCandidate = (baseDir, pathname) => {
209
+ if (!baseDir) return null
210
+ const target = resolve(baseDir, pathname.replace(/^\//, ''))
211
+ if (!target.startsWith(baseDir)) return null
212
+ return target
213
+ }
184
214
 
185
215
  const prebuildHtmlCache = async (token) => {
186
216
  if (!pagesContext || token !== pagesContextToken) return
@@ -402,7 +432,14 @@ export const runViteDev = async () => {
402
432
  const requestedPath = routePath
403
433
  if (pathname.includes('.') && !pathname.endsWith('.html')) {
404
434
  if (!pagesContext?.pagesByRoute?.has(requestedPath)) {
405
- return next()
435
+ const pageCandidate = resolveStaticCandidate(state.PAGES_DIR, pathname)
436
+ if (pageCandidate && existsSync(pageCandidate)) {
437
+ return next()
438
+ }
439
+ const staticCandidate = resolveStaticCandidate(state.STATIC_DIR, pathname)
440
+ if (staticCandidate && existsSync(staticCandidate)) {
441
+ return next()
442
+ }
406
443
  }
407
444
  }
408
445
  const isExcludedPath = () => {
@@ -448,8 +485,7 @@ export const runViteDev = async () => {
448
485
  return
449
486
  } catch (err) {
450
487
  console.error(err)
451
- res.statusCode = 500
452
- res.end('Internal Server Error')
488
+ await sendDevError(res, err, req.url)
453
489
  return
454
490
  }
455
491
  }
@@ -506,8 +542,7 @@ export const runViteDev = async () => {
506
542
  })
507
543
  } catch (err) {
508
544
  logMdxError('MDX render', err, pageMeta || { path, routePath: renderRoutePath })
509
- res.statusCode = 500
510
- res.end('Internal Server Error')
545
+ await sendDevError(res, err, req.url)
511
546
  return
512
547
  }
513
548
  if (renderEpoch === htmlCacheEpoch) {
@@ -523,8 +558,7 @@ export const runViteDev = async () => {
523
558
  res.end(html)
524
559
  } catch (err) {
525
560
  logMdxError('MDX render', err, pageMeta || { path, routePath: renderRoutePath })
526
- res.statusCode = 500
527
- res.end('Internal Server Error')
561
+ await sendDevError(res, err, req.url)
528
562
  }
529
563
  }
530
564
 
@@ -748,7 +782,7 @@ export const runViteDev = async () => {
748
782
  enqueue(async () => {
749
783
  const { hasClient } = await updateComponentEntry(path)
750
784
  if (hasClient) {
751
- invalidateRewindInject()
785
+ invalidateReframeInject()
752
786
  }
753
787
  invalidateHtmlCache()
754
788
  reload()
@@ -759,7 +793,7 @@ export const runViteDev = async () => {
759
793
  const { hasClient } = await updateComponentEntry(path)
760
794
  invalidateHtmlCache()
761
795
  if (hasClient) {
762
- invalidateRewindInject()
796
+ invalidateReframeInject()
763
797
  }
764
798
  reload()
765
799
  })
@@ -780,7 +814,7 @@ export const runViteDev = async () => {
780
814
  const { hasClient } = await updateComponentEntry(path)
781
815
  invalidateHtmlCache()
782
816
  if (hasClient) {
783
- invalidateRewindInject()
817
+ invalidateReframeInject()
784
818
  }
785
819
  reload()
786
820
  })
@@ -791,7 +825,7 @@ export const runViteDev = async () => {
791
825
  if (isClientComponent(path)) {
792
826
  enqueue(async () => {
793
827
  await updateComponentEntry(path, { fallback: true })
794
- invalidateRewindInject()
828
+ invalidateReframeInject()
795
829
  invalidateHtmlCache()
796
830
  reload()
797
831
  })
@@ -808,7 +842,7 @@ export const runViteDev = async () => {
808
842
  })
809
843
  invalidateHtmlCache()
810
844
  if (hasClient) {
811
- invalidateRewindInject()
845
+ invalidateReframeInject()
812
846
  }
813
847
  reload()
814
848
  })
@@ -0,0 +1,49 @@
1
+ /* Copyright Yukino Song, SudoMaker Ltd.
2
+ *
3
+ * Licensed to the Apache Software Foundation (ASF) under one
4
+ * or more contributor license agreements. See the NOTICE file
5
+ * distributed with this work for additional information
6
+ * regarding copyright ownership. The ASF licenses this file
7
+ * to you under the Apache License, Version 2.0 (the
8
+ * "License"); you may not use this file except in compliance
9
+ * with the License. You may obtain a copy of the License at
10
+ *
11
+ * http://www.apache.org/licenses/LICENSE-2.0
12
+ *
13
+ * Unless required by applicable law or agreed to in writing,
14
+ * software distributed under the License is distributed on an
15
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16
+ * KIND, either express or implied. See the License for the
17
+ * specific language governing permissions and limitations
18
+ * under the License.
19
+ */
20
+
21
+ import { HTMLRenderer as R } from './renderer.js'
22
+
23
+ export const DevErrorPage = ({ message = '', basePrefix = ''} = {}) => (
24
+ <>
25
+ {R.rawHTML`<!doctype html>`}
26
+ <html lang="en">
27
+ <head>
28
+ <meta charset="UTF-8" />
29
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
30
+ <title>Methanol dev error</title>
31
+ <style>{`
32
+ body { margin: 0; font-family: ui-sans-serif, system-ui, sans-serif; background: #0f1115; color: #e9edf1; }
33
+ .main { padding: 24px; max-width: 960px; }
34
+ h1 { margin: 0 0 12px; font-size: 20px; }
35
+ pre { white-space: pre-wrap; background: #151922; padding: 16px; border-radius: 8px; border: 1px solid #2a2f3a; }
36
+ .note { color: #9aa3ad; font-size: 12px; margin-top: 12px; }
37
+ `}</style>
38
+ </head>
39
+ <body>
40
+ <div class="main">
41
+ <h1>Dev server error</h1>
42
+ <pre>{message}</pre>
43
+ <div class="note">Fix the error and save to reload.</div>
44
+ </div>
45
+ </body>
46
+ </html>
47
+ </>
48
+ )
49
+
package/src/mdx.js CHANGED
@@ -25,6 +25,7 @@ import rehypeSlug from 'rehype-slug'
25
25
  import extractToc from '@stefanprobst/rehype-extract-toc'
26
26
  import withTocExport from '@stefanprobst/rehype-extract-toc/mdx'
27
27
  import rehypeStarryNight from 'rehype-starry-night'
28
+ import { createStarryNight } from '@wooorm/starry-night'
28
29
  import remarkGfm from 'remark-gfm'
29
30
  import { HTMLRenderer } from './renderer.js'
30
31
  import { signal, computed, read, Suspense, nextTick } from 'refui'
@@ -36,10 +37,12 @@ import { state } from './state.js'
36
37
  import { resolveUserMdxConfig, withBase } from './config.js'
37
38
  import { methanolCtx } from './rehype-plugins/methanol-ctx.js'
38
39
  import { linkResolve } from './rehype-plugins/link-resolve.js'
40
+ import { cached } from './utils.js'
39
41
 
40
42
  // Workaround for Vite: it doesn't support resolving module/virtual modules in script src in dev mode
41
- const resolveRewindInject = () =>
43
+ const resolveRewindInject = cached(() =>
42
44
  HTMLRenderer.rawHTML(`<script type="module" src="${withBase('/.methanol_virtual_module/inject.js')}"></script>`)
45
+ )
43
46
  const RWND_FALLBACK = HTMLRenderer.rawHTML(
44
47
  '<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
48
  )
@@ -219,16 +222,228 @@ const normalizeStarryNightConfig = (value) => {
219
222
  const resolveStarryNightForPage = (frontmatter) => {
220
223
  const base = {
221
224
  enabled: state.STARRY_NIGHT_ENABLED === true,
222
- options: state.STARRY_NIGHT_OPTIONS || null
225
+ options: state.STARRY_NIGHT_OPTIONS || null,
226
+ explicit: false
223
227
  }
224
228
  if (!frontmatter || !Object.prototype.hasOwnProperty.call(frontmatter, 'starryNight')) {
225
229
  return base
226
230
  }
227
- const override = normalizeStarryNightConfig(frontmatter.starryNight)
231
+ const overrideValue = frontmatter.starryNight
232
+ if (typeof overrideValue === 'boolean') {
233
+ if (overrideValue === false) {
234
+ return { enabled: false, options: null, explicit: true }
235
+ }
236
+ return { enabled: true, options: base.options, explicit: false }
237
+ }
238
+ if (!overrideValue || typeof overrideValue !== 'object') {
239
+ return base
240
+ }
241
+ const override = normalizeStarryNightConfig(overrideValue)
228
242
  if (!override) return base
229
- if (override.enabled === false) return { enabled: false, options: null }
243
+ if (override.enabled === false) return { enabled: false, options: null, explicit: true }
230
244
  const options = override.options != null ? override.options : base.options
231
- return { enabled: true, options }
245
+ return { enabled: true, options, explicit: true }
246
+ }
247
+
248
+ const CODE_FENCE_LANG_PATTERN = /(^|\n)\s*(```|~~~)\s*([^\s{]+)/g
249
+ const extractCodeFenceLanguages = (value) => {
250
+ const text = String(value || '')
251
+ const languages = new Set()
252
+ CODE_FENCE_LANG_PATTERN.lastIndex = 0
253
+ let match
254
+ while ((match = CODE_FENCE_LANG_PATTERN.exec(text))) {
255
+ let lang = match[3] ? String(match[3]).trim() : ''
256
+ if (!lang) continue
257
+ const braceIndex = lang.indexOf('{')
258
+ if (braceIndex >= 0) {
259
+ lang = lang.slice(0, braceIndex).trim()
260
+ }
261
+ if (!lang || !/[A-Za-z]/.test(lang)) continue
262
+ languages.add(lang.toLowerCase())
263
+ }
264
+ return languages
265
+ }
266
+ const cleanStarryOptions = (options) => {
267
+ if (!options || typeof options !== 'object') return undefined
268
+ const next = { ...options }
269
+ delete next.grammars
270
+ return next
271
+ }
272
+ let starryNightFuture = null
273
+ const resolvedGrammarCache = new Map()
274
+ const resolvedCustomGrammarCache = new Map()
275
+ const failedLanguageCache = new Set()
276
+ const failedCustomLanguageCache = new Map()
277
+ const loadStarryNight = async (options) => {
278
+ if (!starryNightFuture) {
279
+ starryNightFuture = import('@wooorm/starry-night').then(async (mod) => {
280
+ const grammars = Array.isArray(mod?.all) ? mod.all : []
281
+ const starryNight = await createStarryNight(grammars, cleanStarryOptions(options))
282
+ return {
283
+ starryNight,
284
+ grammars,
285
+ scopeMap: buildScopeGrammarMap(grammars)
286
+ }
287
+ })
288
+ }
289
+ return starryNightFuture
290
+ }
291
+ const buildScopeGrammarMap = (grammars) => {
292
+ const scopeMap = new Map()
293
+ for (const grammar of grammars || []) {
294
+ const scopeName = grammar?.scopeName
295
+ if (typeof scopeName === 'string' && scopeName) {
296
+ scopeMap.set(scopeName, grammar)
297
+ }
298
+ }
299
+ return scopeMap
300
+ }
301
+ const collectExternalScopes = (grammar) => {
302
+ const scopes = new Set()
303
+ const addScope = (value) => {
304
+ if (typeof value !== 'string') return
305
+ if (!value || value.startsWith('#')) return
306
+ scopes.add(value)
307
+ }
308
+ const visit = (node) => {
309
+ if (!node) return
310
+ if (Array.isArray(node)) {
311
+ for (const item of node) {
312
+ visit(item)
313
+ }
314
+ return
315
+ }
316
+ if (typeof node !== 'object') return
317
+ if (typeof node.include === 'string') {
318
+ addScope(node.include)
319
+ }
320
+ for (const value of Object.values(node)) {
321
+ visit(value)
322
+ }
323
+ }
324
+ if (Array.isArray(grammar?.dependencies)) {
325
+ for (const dep of grammar.dependencies) {
326
+ addScope(dep)
327
+ }
328
+ }
329
+ visit(grammar?.patterns)
330
+ visit(grammar?.repository)
331
+ return scopes
332
+ }
333
+ const resolveStarryNightGrammars = async (languages, options) => {
334
+ const hasCustomGrammars = Array.isArray(options?.grammars)
335
+ const baseGrammars = hasCustomGrammars ? options.grammars : null
336
+ if (hasCustomGrammars && (!baseGrammars || !baseGrammars.length)) return null
337
+ const getCustomKey = (grammars) =>
338
+ (grammars || [])
339
+ .map((grammar) => grammar?.scopeName)
340
+ .filter(Boolean)
341
+ .sort()
342
+ .join('|')
343
+ const failedSet = hasCustomGrammars
344
+ ? (() => {
345
+ const customKey = getCustomKey(baseGrammars)
346
+ let set = failedCustomLanguageCache.get(customKey)
347
+ if (!set) {
348
+ set = new Set()
349
+ failedCustomLanguageCache.set(customKey, set)
350
+ }
351
+ return set
352
+ })()
353
+ : failedLanguageCache
354
+ const filteredLanguages = Array.from(languages || [])
355
+ .map((lang) => String(lang).toLowerCase())
356
+ .filter((lang) => lang && !failedSet.has(lang))
357
+ const languageKey = filteredLanguages.slice().sort().join('|')
358
+ if (!languageKey) return []
359
+ if (hasCustomGrammars) {
360
+ const customKey = getCustomKey(baseGrammars)
361
+ const customCache = resolvedCustomGrammarCache.get(customKey)
362
+ if (customCache?.has(languageKey)) {
363
+ return customCache.get(languageKey)
364
+ }
365
+ } else if (resolvedGrammarCache.has(languageKey)) {
366
+ return resolvedGrammarCache.get(languageKey)
367
+ }
368
+ const selected = new Set()
369
+ const selectedScopes = new Set()
370
+ let scopeMap = baseGrammars ? buildScopeGrammarMap(baseGrammars) : null
371
+ let loadedStarryNight = null
372
+ const ensureAll = async () => {
373
+ if (!loadedStarryNight && !hasCustomGrammars) {
374
+ loadedStarryNight = await loadStarryNight(options)
375
+ if (!scopeMap) {
376
+ scopeMap = loadedStarryNight?.scopeMap || null
377
+ }
378
+ }
379
+ }
380
+ let flagToScope = null
381
+ if (hasCustomGrammars) {
382
+ const customStarryNight = await createStarryNight(baseGrammars, cleanStarryOptions(options))
383
+ flagToScope = (lang) => customStarryNight.flagToScope(String(lang))
384
+ } else {
385
+ try {
386
+ await ensureAll()
387
+ } catch {
388
+ for (const lang of filteredLanguages) {
389
+ failedSet.add(lang)
390
+ }
391
+ return []
392
+ }
393
+ flagToScope = (lang) => loadedStarryNight?.starryNight.flagToScope(String(lang))
394
+ }
395
+ if (!scopeMap) return null
396
+ const addGrammar = (grammar) => {
397
+ if (!grammar) return false
398
+ const scopeName = grammar.scopeName
399
+ if (!scopeName || selectedScopes.has(scopeName)) return false
400
+ selectedScopes.add(scopeName)
401
+ selected.add(grammar)
402
+ return true
403
+ }
404
+ for (const lang of filteredLanguages) {
405
+ let scope
406
+ try {
407
+ scope = flagToScope ? flagToScope(String(lang)) : undefined
408
+ } catch {
409
+ scope = undefined
410
+ }
411
+ const grammar = scope && scopeMap ? scopeMap.get(scope) : null
412
+ if (!grammar) {
413
+ failedSet.add(lang)
414
+ }
415
+ addGrammar(grammar)
416
+ }
417
+ if (!selected.size) return []
418
+ const queue = Array.from(selected)
419
+ while (queue.length) {
420
+ const grammar = queue.pop()
421
+ const scopes = collectExternalScopes(grammar)
422
+ for (const scope of scopes) {
423
+ if (selectedScopes.has(scope)) continue
424
+ let depGrammar = scopeMap ? scopeMap.get(scope) : null
425
+ if (!depGrammar && !hasCustomGrammars) {
426
+ await ensureAll()
427
+ depGrammar = scopeMap ? scopeMap.get(scope) : null
428
+ }
429
+ if (addGrammar(depGrammar)) {
430
+ queue.push(depGrammar)
431
+ }
432
+ }
433
+ }
434
+ const result = selected.size ? Array.from(selected) : []
435
+ if (hasCustomGrammars) {
436
+ const customKey = getCustomKey(baseGrammars)
437
+ let customCache = resolvedCustomGrammarCache.get(customKey)
438
+ if (!customCache) {
439
+ customCache = new Map()
440
+ resolvedCustomGrammarCache.set(customKey, customCache)
441
+ }
442
+ customCache.set(languageKey, result)
443
+ } else {
444
+ resolvedGrammarCache.set(languageKey, result)
445
+ }
446
+ return result
232
447
  }
233
448
 
234
449
  const resolveBaseMdxConfig = async () => {
@@ -262,7 +477,7 @@ const resolveBaseMdxConfig = async () => {
262
477
  return (cachedMdxConfig = mdxConfig)
263
478
  }
264
479
 
265
- const resolveMdxConfigForPage = async (frontmatter) => {
480
+ const resolveMdxConfigForPage = async (frontmatter, content = '') => {
266
481
  const baseConfig = await resolveBaseMdxConfig()
267
482
  const mdxConfig = {
268
483
  ...baseConfig,
@@ -270,7 +485,19 @@ const resolveMdxConfigForPage = async (frontmatter) => {
270
485
  }
271
486
  const starryNightConfig = resolveStarryNightForPage(frontmatter)
272
487
  if (!starryNightConfig.enabled) return mdxConfig
273
- const plugin = starryNightConfig.options ? [rehypeStarryNight, starryNightConfig.options] : [rehypeStarryNight]
488
+ let options = starryNightConfig.options
489
+ if (!starryNightConfig.explicit) {
490
+ const languages = extractCodeFenceLanguages(content)
491
+ if (!languages.size) {
492
+ return mdxConfig
493
+ }
494
+ const grammars = await resolveStarryNightGrammars(languages, options)
495
+ if (!grammars || !grammars.length) {
496
+ return mdxConfig
497
+ }
498
+ options = { ...(options || {}), grammars }
499
+ }
500
+ const plugin = options ? [rehypeStarryNight, options] : [rehypeStarryNight]
274
501
  const insertIndex = mdxConfig.rehypePlugins.indexOf(linkResolve)
275
502
  if (insertIndex >= 0) {
276
503
  mdxConfig.rehypePlugins.splice(insertIndex, 0, plugin)
@@ -281,7 +508,7 @@ const resolveMdxConfigForPage = async (frontmatter) => {
281
508
  }
282
509
 
283
510
  export const compileMdxSource = async ({ content, path, frontmatter }) => {
284
- const mdxConfig = await resolveMdxConfigForPage(frontmatter)
511
+ const mdxConfig = await resolveMdxConfigForPage(frontmatter, content)
285
512
  const compiled = await compile({ value: content, path: path }, mdxConfig)
286
513
  const code = String(compiled.value ?? compiled)
287
514
  return { code, development: Boolean(mdxConfig.development) }
@@ -27,7 +27,7 @@ import { state } from './state.js'
27
27
  import { resolveBasePrefix } from './config.js'
28
28
  import { genRegistryScript } from './components.js'
29
29
  import { serializePagesIndex } from './pages-index.js'
30
- import { INJECT_SCRIPT, LOADER_SCRIPT, PAGEFIND_LOADER_SCRIPT, PWA_INJECT_SCRIPT } from './client/virtual-module/assets.js'
30
+ import { virtualModuleDir, INJECT_SCRIPT, LOADER_SCRIPT, PAGEFIND_LOADER_SCRIPT, PWA_INJECT_SCRIPT } from './client/virtual-module/assets.js'
31
31
  import { projectRequire } from './node-loader.js'
32
32
 
33
33
  const require = createRequire(import.meta.url)
@@ -127,13 +127,10 @@ const virtualModuleMap = {
127
127
  get registry() {
128
128
  return `export const registry = ${genRegistryScript()}`
129
129
  },
130
- get 'registry.js'() {
131
- return `export const registry = ${genRegistryScript()}`
132
- },
133
130
  get loader() {
134
131
  return LOADER_SCRIPT()
135
132
  },
136
- get 'inject.js'() {
133
+ get 'inject'() {
137
134
  return INJECT_SCRIPT()
138
135
  },
139
136
  get 'pagefind-loader'() {
@@ -149,10 +146,6 @@ const virtualModuleMap = {
149
146
  get pages() {
150
147
  const pages = state.PAGES_CONTEXT?.pages || []
151
148
  return `export const pages = ${serializePagesIndex(pages)}\nexport default pages`
152
- },
153
- get 'pages.js'() {
154
- const pages = state.PAGES_CONTEXT?.pages || []
155
- return `export const pages = ${serializePagesIndex(pages)}\nexport default pages`
156
149
  }
157
150
  }
158
151
 
@@ -165,20 +158,6 @@ const getSchemeModuleKey = (id) => {
165
158
  return id.slice(virtualModuleScheme.length)
166
159
  }
167
160
 
168
- const resolveVirtualModuleId = (id) => {
169
- if (id.startsWith(virtualModulePrefix)) {
170
- return id
171
- }
172
- const basePrefix = resolveBasePrefix()
173
- if (basePrefix) {
174
- const prefixed = `${basePrefix}${virtualModulePrefix}`
175
- if (id.startsWith(prefixed)) {
176
- return id.slice(basePrefix.length)
177
- }
178
- }
179
- return null
180
- }
181
-
182
161
  export const methanolResolverPlugin = () => {
183
162
  return {
184
163
  name: 'methanol-resolver',
@@ -195,19 +174,16 @@ export const methanolResolverPlugin = () => {
195
174
  return require.resolve(id)
196
175
  }
197
176
 
177
+ // Very weird workaround for Vite
178
+ if (id.startsWith(virtualModulePrefix)) {
179
+ return resolve(virtualModuleDir, id.slice(virtualModulePrefix.length))
180
+ }
181
+
198
182
  const schemeKey = getSchemeModuleKey(id)
199
183
  if (schemeKey && Object.prototype.hasOwnProperty.call(virtualModuleMap, schemeKey)) {
200
184
  return '\0' + id
201
185
  }
202
186
 
203
- const virtualId = resolveVirtualModuleId(id)
204
- if (virtualId) {
205
- const _moduleId = getModuleIdSegment(virtualId, virtualModulePrefix.length)
206
- if (Object.prototype.hasOwnProperty.call(virtualModuleMap, _moduleId)) {
207
- return '\0' + virtualId
208
- }
209
- }
210
-
211
187
  if (state.SOURCES.length) {
212
188
  const { pathname, search } = new URL(id, 'http://methanol')
213
189
  for (const entry of state.SOURCES) {
@@ -18,7 +18,6 @@
18
18
  * under the License.
19
19
  */
20
20
 
21
- import { HTMLRenderer as R } from 'methanol'
22
21
  import { filterBlogPosts, mapStaticPosts, collectCategories } from './post-utils.js'
23
22
  import { formatDate } from '../src/date-utils.js'
24
23
 
@@ -18,7 +18,6 @@
18
18
  * under the License.
19
19
  */
20
20
 
21
- import { HTMLRenderer as R } from 'methanol'
22
21
  import { filterBlogPosts, mapStaticPosts, collectCollectionTitles } from './post-utils.js'
23
22
  import { formatDate } from '../src/date-utils.js'
24
23
 
@@ -18,7 +18,6 @@
18
18
  * under the License.
19
19
  */
20
20
 
21
- import { HTMLRenderer as R } from 'methanol'
22
21
  import { filterBlogPosts, mapStaticPosts } from './post-utils.js'
23
22
  import { formatDate } from '../src/date-utils.js'
24
23
 
@@ -18,8 +18,6 @@
18
18
  * under the License.
19
19
  */
20
20
 
21
- import { HTMLRenderer as R } from 'methanol'
22
-
23
21
  export const LayoutPost = ({ PageContent, title, page }) => {
24
22
  return (
25
23
  <article class="post-content">
@@ -18,7 +18,7 @@
18
18
  * under the License.
19
19
  */
20
20
 
21
- import { HTMLRenderer as R, DOCTYPE_HTML } from 'methanol'
21
+ import { DOCTYPE_HTML } from 'methanol'
22
22
  import { LayoutHome } from './layout-home.jsx'
23
23
  import { LayoutCategories } from './layout-categories.jsx'
24
24
  import { LayoutCollections } from './layout-collections.jsx'
@@ -29,7 +29,7 @@
29
29
  if (savedAccent && savedAccent !== 'default') {
30
30
  document.documentElement.classList.add('accent-' + savedAccent)
31
31
  }
32
- })
32
+ })()
33
33
  ;(function initPrefetch() {
34
34
  const prefetched = new Set()
35
35
  const canPrefetch = (anchor) => {
@@ -58,4 +58,4 @@
58
58
  document.head.appendChild(link)
59
59
  }
60
60
  document.addEventListener('pointerover', onHover, { capture: true, passive: true })
61
- })
61
+ })()
@@ -18,7 +18,7 @@
18
18
  * under the License.
19
19
  */
20
20
 
21
- import { HTMLRenderer as R, DOCTYPE_HTML } from 'methanol'
21
+ import { DOCTYPE_HTML } from 'methanol'
22
22
  import { renderToc } from '../components/ThemeToCContainer.static.jsx'
23
23
  import { renderNavTree } from './nav-tree.jsx'
24
24