methanol 0.0.0 → 0.0.1
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/.editorconfig +19 -0
- package/.prettierrc +10 -0
- package/LICENSE +203 -0
- package/banner.txt +6 -0
- package/bin/methanol.js +24 -0
- package/index.js +22 -0
- package/package.json +42 -9
- package/src/assets.js +30 -0
- package/src/build-system.js +200 -0
- package/src/components.js +145 -0
- package/src/config.js +355 -0
- package/src/dev-server.js +559 -0
- package/src/main.js +87 -0
- package/src/mdx.js +254 -0
- package/src/node-loader.js +88 -0
- package/src/pagefind.js +99 -0
- package/src/pages.js +638 -0
- package/src/preview-server.js +58 -0
- package/src/public-assets.js +73 -0
- package/src/register-loader.js +29 -0
- package/src/rehype-plugins/link-resolve.js +89 -0
- package/src/rehype-plugins/methanol-ctx.js +89 -0
- package/src/renderer.js +25 -0
- package/src/rewind.js +117 -0
- package/src/stage-logger.js +59 -0
- package/src/state.js +159 -0
- package/src/virtual-module/inject.js +30 -0
- package/src/virtual-module/loader.js +116 -0
- package/src/virtual-module/pagefind.js +108 -0
- package/src/vite-plugins.js +173 -0
- package/themes/default/components/ThemeColorSwitch.client.jsx +95 -0
- package/themes/default/components/ThemeColorSwitch.static.jsx +23 -0
- package/themes/default/components/ThemeSearchBox.client.jsx +287 -0
- package/themes/default/components/ThemeSearchBox.static.jsx +41 -0
- package/themes/default/components/ThemeToCContainer.client.jsx +154 -0
- package/themes/default/components/ThemeToCContainer.static.jsx +61 -0
- package/themes/default/components/pre.client.jsx +84 -0
- package/themes/default/components/pre.jsx +27 -0
- package/themes/default/heading.jsx +35 -0
- package/themes/default/index.js +50 -0
- package/themes/default/page.jsx +249 -0
- package/themes/default/pages/404.mdx +8 -0
- package/themes/default/pages/index.mdx +9 -0
- package/themes/default/public/logo.png +0 -0
- package/themes/default/resources/style.css +1089 -0
|
@@ -0,0 +1,73 @@
|
|
|
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 { readdir, stat, copyFile, mkdir } from 'fs/promises'
|
|
22
|
+
import { existsSync } from 'fs'
|
|
23
|
+
import { resolve, dirname, relative } from 'path'
|
|
24
|
+
|
|
25
|
+
const ensureDir = async (dir) => {
|
|
26
|
+
await mkdir(dir, { recursive: true })
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const copyDir = async (sourceDir, targetDir, onFile) => {
|
|
30
|
+
await ensureDir(targetDir)
|
|
31
|
+
const entries = await readdir(sourceDir)
|
|
32
|
+
for (const entry of entries) {
|
|
33
|
+
if (entry.startsWith('.')) {
|
|
34
|
+
continue
|
|
35
|
+
}
|
|
36
|
+
const sourcePath = resolve(sourceDir, entry)
|
|
37
|
+
const targetPath = resolve(targetDir, entry)
|
|
38
|
+
const stats = await stat(sourcePath)
|
|
39
|
+
if (stats.isDirectory()) {
|
|
40
|
+
await copyDir(sourcePath, targetPath, onFile)
|
|
41
|
+
} else {
|
|
42
|
+
if (existsSync(targetPath)) {
|
|
43
|
+
if (onFile) {
|
|
44
|
+
onFile(sourcePath, targetPath, { skipped: true })
|
|
45
|
+
}
|
|
46
|
+
continue
|
|
47
|
+
}
|
|
48
|
+
await ensureDir(dirname(targetPath))
|
|
49
|
+
await copyFile(sourcePath, targetPath)
|
|
50
|
+
if (onFile) {
|
|
51
|
+
onFile(sourcePath, targetPath, { skipped: false })
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export const copyPublicDir = async ({ sourceDir, targetDir, label = 'public' }) => {
|
|
58
|
+
if (!sourceDir || !targetDir) return
|
|
59
|
+
if (!existsSync(sourceDir)) return
|
|
60
|
+
const resolvedSource = resolve(sourceDir)
|
|
61
|
+
const resolvedTarget = resolve(targetDir)
|
|
62
|
+
if (resolvedSource === resolvedTarget) return
|
|
63
|
+
const created = !existsSync(resolvedTarget)
|
|
64
|
+
await ensureDir(resolvedTarget)
|
|
65
|
+
if (created) {
|
|
66
|
+
console.log(`Methanol: created ${label} directory`)
|
|
67
|
+
}
|
|
68
|
+
await copyDir(resolvedSource, resolvedTarget, (sourcePath, targetPath, info) => {
|
|
69
|
+
const rel = relative(resolvedSource, sourcePath).replace(/\\/g, '/')
|
|
70
|
+
if (info?.skipped) return
|
|
71
|
+
console.log(`Methanol: copied ${label}/${rel}`)
|
|
72
|
+
})
|
|
73
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
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 { fileURLToPath } from 'node:url'
|
|
22
|
+
import { dirname, resolve } from 'node:path'
|
|
23
|
+
import { register } from 'node:module'
|
|
24
|
+
|
|
25
|
+
const __filename = fileURLToPath(import.meta.url)
|
|
26
|
+
const __dirname = dirname(__filename)
|
|
27
|
+
const loaderPath = resolve(__dirname, '../src/node-loader.js')
|
|
28
|
+
|
|
29
|
+
register(loaderPath, import.meta.url)
|
|
@@ -0,0 +1,89 @@
|
|
|
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 { existsSync } from 'fs'
|
|
22
|
+
import { dirname, resolve } from 'path'
|
|
23
|
+
import { isElement } from 'hast-util-is-element'
|
|
24
|
+
import { visit } from 'unist-util-visit'
|
|
25
|
+
|
|
26
|
+
const extensionRegex = /\.(mdx?|html)$/i
|
|
27
|
+
|
|
28
|
+
const isRelativeHref = (href) => {
|
|
29
|
+
if (typeof href !== 'string') return false
|
|
30
|
+
if (!href) return false
|
|
31
|
+
if (href.startsWith('#') || href.startsWith('?') || href.startsWith('/')) return false
|
|
32
|
+
if (href.startsWith('//')) return false
|
|
33
|
+
if (/^[a-zA-Z][a-zA-Z\d+\-.]*:/.test(href)) return false
|
|
34
|
+
return true
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const splitHref = (href) => {
|
|
38
|
+
const cutIndex = href.search(/[?#]/)
|
|
39
|
+
if (cutIndex === -1) {
|
|
40
|
+
return { path: href, suffix: '' }
|
|
41
|
+
}
|
|
42
|
+
return { path: href.slice(0, cutIndex), suffix: href.slice(cutIndex) }
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const resolveCandidate = (baseDir, targetPath) => resolve(baseDir, targetPath)
|
|
46
|
+
|
|
47
|
+
const hasExistingSource = (baseDir, pathWithoutSuffix, extension) => {
|
|
48
|
+
const targetPath = `${pathWithoutSuffix}${extension}`
|
|
49
|
+
return existsSync(resolveCandidate(baseDir, targetPath))
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export const linkResolve = () => {
|
|
53
|
+
return (tree, file) => {
|
|
54
|
+
const baseDir = file?.path ? dirname(file.path) : file?.cwd || process.cwd()
|
|
55
|
+
visit(tree, (node) => {
|
|
56
|
+
if (!isElement(node) || node.tagName !== 'a') {
|
|
57
|
+
return
|
|
58
|
+
}
|
|
59
|
+
const href = node.properties?.href
|
|
60
|
+
if (!isRelativeHref(href)) {
|
|
61
|
+
return
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const { path, suffix } = splitHref(href)
|
|
65
|
+
const match = path.match(extensionRegex)
|
|
66
|
+
if (!match) {
|
|
67
|
+
return
|
|
68
|
+
}
|
|
69
|
+
const extension = match[0]
|
|
70
|
+
const withoutExtension = path.replace(extensionRegex, '')
|
|
71
|
+
|
|
72
|
+
let shouldStrip = false
|
|
73
|
+
if (/\.mdx?$/i.test(extension)) {
|
|
74
|
+
shouldStrip = hasExistingSource(baseDir, withoutExtension, extension)
|
|
75
|
+
} else if (/\.html$/i.test(extension)) {
|
|
76
|
+
shouldStrip =
|
|
77
|
+
hasExistingSource(baseDir, withoutExtension, extension) ||
|
|
78
|
+
hasExistingSource(baseDir, withoutExtension, '.md') ||
|
|
79
|
+
hasExistingSource(baseDir, withoutExtension, '.mdx')
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (!shouldStrip) {
|
|
83
|
+
return
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
node.properties.href = withoutExtension + suffix
|
|
87
|
+
})
|
|
88
|
+
}
|
|
89
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
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 { extname } from 'path'
|
|
22
|
+
|
|
23
|
+
function createConst(name, init) {
|
|
24
|
+
return {
|
|
25
|
+
type: 'VariableDeclaration',
|
|
26
|
+
kind: 'const',
|
|
27
|
+
declarations: [
|
|
28
|
+
{
|
|
29
|
+
type: 'VariableDeclarator',
|
|
30
|
+
id: { type: 'Identifier', name },
|
|
31
|
+
init
|
|
32
|
+
}
|
|
33
|
+
]
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function argumentMember(name) {
|
|
38
|
+
return {
|
|
39
|
+
type: 'MemberExpression',
|
|
40
|
+
object: {
|
|
41
|
+
type: 'MemberExpression',
|
|
42
|
+
object: { type: 'Identifier', name: 'arguments' },
|
|
43
|
+
property: { type: 'Literal', value: 0 },
|
|
44
|
+
computed: true,
|
|
45
|
+
optional: false
|
|
46
|
+
},
|
|
47
|
+
property: { type: 'Identifier', name },
|
|
48
|
+
computed: false,
|
|
49
|
+
optional: false
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const ctxFrontmatter = {
|
|
54
|
+
type: 'ChainExpression',
|
|
55
|
+
expression: {
|
|
56
|
+
type: 'MemberExpression',
|
|
57
|
+
object: {
|
|
58
|
+
type: 'MemberExpression',
|
|
59
|
+
object: { type: 'Identifier', name: 'ctx' },
|
|
60
|
+
property: { type: 'Identifier', name: 'page' },
|
|
61
|
+
computed: false,
|
|
62
|
+
optional: false
|
|
63
|
+
},
|
|
64
|
+
property: { type: 'Identifier', name: 'frontmatter' },
|
|
65
|
+
computed: false,
|
|
66
|
+
optional: true
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export function methanolCtx() {
|
|
71
|
+
return (tree, file) => {
|
|
72
|
+
// const filePath = file?.path || ''
|
|
73
|
+
|
|
74
|
+
tree.children.unshift({
|
|
75
|
+
type: 'mdxjsEsm',
|
|
76
|
+
data: {
|
|
77
|
+
estree: {
|
|
78
|
+
type: 'Program',
|
|
79
|
+
sourceType: 'module',
|
|
80
|
+
body: [
|
|
81
|
+
createConst('rawHTML', argumentMember('rawHTML')),
|
|
82
|
+
createConst('ctx', argumentMember('ctx')),
|
|
83
|
+
createConst('frontmatter', ctxFrontmatter)
|
|
84
|
+
]
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
})
|
|
88
|
+
}
|
|
89
|
+
}
|
package/src/renderer.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
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 { createHTMLRenderer } from 'refui/html'
|
|
22
|
+
|
|
23
|
+
const HTMLRenderer = createHTMLRenderer()
|
|
24
|
+
|
|
25
|
+
export { HTMLRenderer }
|
package/src/rewind.js
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
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 fnv1a from '@sindresorhus/fnv1a'
|
|
22
|
+
import JSON5 from 'json5'
|
|
23
|
+
|
|
24
|
+
const utf8Buffer = new Uint8Array(128)
|
|
25
|
+
|
|
26
|
+
const alphabet = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!?*:+-=._/[]{}()<>%#$^|~`'"
|
|
27
|
+
const base = alphabet.length
|
|
28
|
+
function compress(num) {
|
|
29
|
+
let result = ''
|
|
30
|
+
while (num > 0) {
|
|
31
|
+
result = alphabet[num % base] + result
|
|
32
|
+
num = Math.floor(num / base)
|
|
33
|
+
}
|
|
34
|
+
return result
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function hash(str, size = 32) {
|
|
38
|
+
return compress(Number(fnv1a(str, { size, utf8Buffer })))
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export function env(parentEnv) {
|
|
42
|
+
const registry = {}
|
|
43
|
+
const keyPathRegistry = {}
|
|
44
|
+
let parent = parentEnv || null
|
|
45
|
+
|
|
46
|
+
let renderCount = 0
|
|
47
|
+
|
|
48
|
+
function client(info) {
|
|
49
|
+
const { clientPath, staticComponent, exportName } = info
|
|
50
|
+
|
|
51
|
+
let key = null
|
|
52
|
+
let _clientPath = clientPath
|
|
53
|
+
do {
|
|
54
|
+
_clientPath += '\0'
|
|
55
|
+
key = hash(_clientPath)
|
|
56
|
+
} while (keyPathRegistry[key] && keyPathRegistry[key] !== clientPath)
|
|
57
|
+
|
|
58
|
+
const component = ({ children: childrenProp, ...props }, ...children) => {
|
|
59
|
+
const id = renderCount++
|
|
60
|
+
const idStr = id.toString(16)
|
|
61
|
+
const script = `$$rwnd(${JSON.stringify(key)},${id},${Object.keys(props).length ? JSON5.stringify(props) : '{}'})`
|
|
62
|
+
|
|
63
|
+
return (R) => {
|
|
64
|
+
return [
|
|
65
|
+
R.createAnchor(`{${idStr}}`, true),
|
|
66
|
+
R.c(
|
|
67
|
+
staticComponent,
|
|
68
|
+
props,
|
|
69
|
+
R.createAnchor(`[${idStr}[`, true),
|
|
70
|
+
...children,
|
|
71
|
+
R.createAnchor(`]${idStr}]`, true)
|
|
72
|
+
),
|
|
73
|
+
R.c('script', null, R.rawHTML(script))
|
|
74
|
+
]
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
registry[exportName] = [key, info.clientPath]
|
|
79
|
+
keyPathRegistry[key] = info.clientPath
|
|
80
|
+
|
|
81
|
+
return component
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function invalidate(exportName) {
|
|
85
|
+
if (!registry[exportName]) {
|
|
86
|
+
return
|
|
87
|
+
}
|
|
88
|
+
const [key] = registry[exportName]
|
|
89
|
+
delete registry[exportName]
|
|
90
|
+
delete keyPathRegistry[key]
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function setParent(nextParent) {
|
|
94
|
+
parent = nextParent || null
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function getMergedRegistry() {
|
|
98
|
+
return Object.assign({}, parent?.registry, registry)
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function genRegistryScript() {
|
|
102
|
+
return `({
|
|
103
|
+
${Object.values(getMergedRegistry()).map(([key, path]) => `${JSON.stringify(key)}: () => import(${JSON.stringify(path)})`).join(`,
|
|
104
|
+
`)}
|
|
105
|
+
})`
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
return {
|
|
109
|
+
client,
|
|
110
|
+
invalidate,
|
|
111
|
+
genRegistryScript,
|
|
112
|
+
setParent,
|
|
113
|
+
get registry() {
|
|
114
|
+
return getMergedRegistry()
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
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
|
+
const now = () => (typeof performance !== 'undefined' ? performance.now() : Date.now())
|
|
22
|
+
|
|
23
|
+
export const createStageLogger = (enabled) => {
|
|
24
|
+
let lastLength = 0
|
|
25
|
+
const isTty = Boolean(process.stdout && process.stdout.isTTY)
|
|
26
|
+
const writeLine = (text, newline) => {
|
|
27
|
+
if (!process.stdout || !process.stdout.write) {
|
|
28
|
+
if (newline) {
|
|
29
|
+
console.log(text)
|
|
30
|
+
}
|
|
31
|
+
return
|
|
32
|
+
}
|
|
33
|
+
if (!isTty) {
|
|
34
|
+
if (newline) {
|
|
35
|
+
console.log(text)
|
|
36
|
+
}
|
|
37
|
+
return
|
|
38
|
+
}
|
|
39
|
+
const padding = lastLength > text.length ? ' '.repeat(lastLength - text.length) : ''
|
|
40
|
+
const clearLine = '\u001b[2K'
|
|
41
|
+
process.stdout.write(`${clearLine}\r${text}${padding}${newline ? '\n' : ''}`)
|
|
42
|
+
lastLength = text.length
|
|
43
|
+
}
|
|
44
|
+
const start = (label) => {
|
|
45
|
+
if (!enabled) return null
|
|
46
|
+
writeLine(`${label}...`, false)
|
|
47
|
+
return { label, start: now() }
|
|
48
|
+
}
|
|
49
|
+
const update = (token, message) => {
|
|
50
|
+
if (!enabled || !token || !message) return
|
|
51
|
+
writeLine(message, false)
|
|
52
|
+
}
|
|
53
|
+
const end = (token) => {
|
|
54
|
+
if (!enabled || !token) return
|
|
55
|
+
const duration = Math.round(now() - token.start)
|
|
56
|
+
writeLine(`${token.label}...\t${duration}ms`, true)
|
|
57
|
+
}
|
|
58
|
+
return { start, update, end }
|
|
59
|
+
}
|
package/src/state.js
ADDED
|
@@ -0,0 +1,159 @@
|
|
|
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 { resolve } from 'path'
|
|
22
|
+
import yargs from 'yargs/yargs'
|
|
23
|
+
import { hideBin } from 'yargs/helpers'
|
|
24
|
+
|
|
25
|
+
const PROJECT_ROOT = resolve('.')
|
|
26
|
+
|
|
27
|
+
const withCommonOptions = (y) =>
|
|
28
|
+
y
|
|
29
|
+
.positional('input', {
|
|
30
|
+
describe: 'Pages directory',
|
|
31
|
+
type: 'string',
|
|
32
|
+
nargs: 1
|
|
33
|
+
})
|
|
34
|
+
.positional('output', {
|
|
35
|
+
describe: 'Output directory',
|
|
36
|
+
type: 'string',
|
|
37
|
+
nargs: 1
|
|
38
|
+
})
|
|
39
|
+
.option('input', {
|
|
40
|
+
alias: 'i',
|
|
41
|
+
describe: 'Pages directory',
|
|
42
|
+
type: 'string',
|
|
43
|
+
requiresArg: true,
|
|
44
|
+
nargs: 1
|
|
45
|
+
})
|
|
46
|
+
.option('components', {
|
|
47
|
+
describe: 'Components directory',
|
|
48
|
+
type: 'string',
|
|
49
|
+
requiresArg: true,
|
|
50
|
+
nargs: 1
|
|
51
|
+
})
|
|
52
|
+
.option('assets', {
|
|
53
|
+
describe: 'Assets/public directory',
|
|
54
|
+
type: 'string',
|
|
55
|
+
requiresArg: true,
|
|
56
|
+
nargs: 1
|
|
57
|
+
})
|
|
58
|
+
.option('output', {
|
|
59
|
+
alias: 'o',
|
|
60
|
+
describe: 'Output directory',
|
|
61
|
+
type: 'string',
|
|
62
|
+
requiresArg: true,
|
|
63
|
+
nargs: 1
|
|
64
|
+
})
|
|
65
|
+
.option('config', {
|
|
66
|
+
alias: 'c',
|
|
67
|
+
describe: 'Config file path',
|
|
68
|
+
type: 'string',
|
|
69
|
+
requiresArg: true,
|
|
70
|
+
nargs: 1
|
|
71
|
+
})
|
|
72
|
+
.option('site-name', {
|
|
73
|
+
describe: 'Site name override',
|
|
74
|
+
type: 'string',
|
|
75
|
+
requiresArg: true,
|
|
76
|
+
nargs: 1
|
|
77
|
+
})
|
|
78
|
+
.option('port', {
|
|
79
|
+
describe: 'Port for dev/preview',
|
|
80
|
+
type: 'number',
|
|
81
|
+
requiresArg: true,
|
|
82
|
+
nargs: 1
|
|
83
|
+
})
|
|
84
|
+
.option('host', {
|
|
85
|
+
describe: 'Host for dev/preview',
|
|
86
|
+
type: 'string',
|
|
87
|
+
coerce: (value) => {
|
|
88
|
+
if (value == null) return null
|
|
89
|
+
if (value === true || value === '' || value === 'true') return true
|
|
90
|
+
return value
|
|
91
|
+
}
|
|
92
|
+
})
|
|
93
|
+
.option('intermediate-dir', {
|
|
94
|
+
describe: 'Write intermediate HTML output to a directory',
|
|
95
|
+
type: 'string',
|
|
96
|
+
requiresArg: true,
|
|
97
|
+
nargs: 1
|
|
98
|
+
})
|
|
99
|
+
.option('emit-intermediate', {
|
|
100
|
+
describe: 'Emit intermediate HTML output to the default build dir',
|
|
101
|
+
type: 'boolean',
|
|
102
|
+
default: false
|
|
103
|
+
})
|
|
104
|
+
|
|
105
|
+
const parser = yargs(hideBin(process.argv))
|
|
106
|
+
.scriptName('methanol')
|
|
107
|
+
.usage('Usage: $0 <command> [options]')
|
|
108
|
+
.command('dev [input]', 'Start the Methanol dev server', withCommonOptions)
|
|
109
|
+
.command('build [input] [output]', 'Build the static site', withCommonOptions)
|
|
110
|
+
.command('serve [input] [output]', 'Serve the production build', withCommonOptions)
|
|
111
|
+
.command('preview [input] [output]', false, withCommonOptions)
|
|
112
|
+
.help()
|
|
113
|
+
.wrap(null)
|
|
114
|
+
|
|
115
|
+
const argv = parser.parseSync()
|
|
116
|
+
|
|
117
|
+
export const cli = {
|
|
118
|
+
argv,
|
|
119
|
+
command: argv._[0] ? String(argv._[0]) : null,
|
|
120
|
+
showHelp: () => parser.showHelp(),
|
|
121
|
+
CLI_INTERMEDIATE_DIR: argv['intermediate-dir'] || null,
|
|
122
|
+
CLI_EMIT_INTERMEDIATE: Boolean(argv['emit-intermediate']),
|
|
123
|
+
CLI_HOST: argv.host ?? null,
|
|
124
|
+
CLI_PORT: typeof argv.port === 'number' ? argv.port : null,
|
|
125
|
+
CLI_PAGES_DIR: argv.input || null,
|
|
126
|
+
CLI_COMPONENTS_DIR: argv.components || null,
|
|
127
|
+
CLI_ASSETS_DIR: argv.assets || null,
|
|
128
|
+
CLI_OUTPUT_DIR: argv.output || null,
|
|
129
|
+
CLI_CONFIG_PATH: argv.config || null,
|
|
130
|
+
CLI_SITE_NAME: argv['site-name'] || null
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
export const state = {
|
|
134
|
+
PROJECT_ROOT,
|
|
135
|
+
ROOT_DIR: PROJECT_ROOT,
|
|
136
|
+
SITE_NAME: 'Methanol Site',
|
|
137
|
+
PAGES_DIR: resolve(PROJECT_ROOT, 'pages'),
|
|
138
|
+
COMPONENTS_DIR: resolve(PROJECT_ROOT, 'components'),
|
|
139
|
+
STATIC_DIR: resolve(PROJECT_ROOT, 'public'),
|
|
140
|
+
BUILD_DIR: resolve(PROJECT_ROOT, 'build'),
|
|
141
|
+
DIST_DIR: resolve(PROJECT_ROOT, 'dist'),
|
|
142
|
+
VIRTUAL_HTML_OUTPUT_ROOT: PROJECT_ROOT,
|
|
143
|
+
INTERMEDIATE_DIR: null,
|
|
144
|
+
THEME_COMPONENTS_DIR: null,
|
|
145
|
+
THEME_PAGES_DIR: null,
|
|
146
|
+
THEME_PUBLIC_DIR: null,
|
|
147
|
+
THEME_ENV: null,
|
|
148
|
+
USER_THEME: null,
|
|
149
|
+
USER_VITE_CONFIG: null,
|
|
150
|
+
USER_MDX_CONFIG: null,
|
|
151
|
+
USER_PUBLIC_OVERRIDE: false,
|
|
152
|
+
RESOURCES: [],
|
|
153
|
+
PAGEFIND_ENABLED: false,
|
|
154
|
+
PAGEFIND_OPTIONS: null,
|
|
155
|
+
PAGEFIND_BUILD_OPTIONS: null,
|
|
156
|
+
CURRENT_MODE: 'production',
|
|
157
|
+
RESOLVED_MDX_CONFIG: undefined,
|
|
158
|
+
RESOLVED_VITE_CONFIG: undefined
|
|
159
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
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 { createDOMRenderer } from 'refui/dom'
|
|
22
|
+
import { defaults } from 'refui/browser'
|
|
23
|
+
import { lazy } from 'refui'
|
|
24
|
+
import { init } from '/.methanol_virtual_module/loader.js'
|
|
25
|
+
|
|
26
|
+
const reg = import('/.methanol_virtual_module/registry.js')
|
|
27
|
+
|
|
28
|
+
const R = createDOMRenderer(defaults)
|
|
29
|
+
|
|
30
|
+
reg.then((m) => init(m.registry, R))
|