@blinkk/root 1.0.0-beta.9 → 1.0.0-rc.0

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/bin/root.js CHANGED
@@ -21,18 +21,22 @@ async function main() {
21
21
  .description('generates a static build')
22
22
  .option('--ssr-only', 'produce a ssr-only build')
23
23
  .option('--mode <mode>', 'see: https://vitejs.dev/guide/env-and-mode.html#modes', 'production')
24
+ .option('-c, --concurrency <num>', 'number of files to build concurrently', 10)
24
25
  .action(build);
25
26
  program
26
27
  .command('dev [path]')
27
28
  .description('starts the server in development mode')
29
+ .option('--host <host>', 'network address the server should listen on, e.g. 127.0.0.1')
28
30
  .action(dev);
29
31
  program
30
32
  .command('preview [path]')
31
33
  .description('starts the server in preview mode')
34
+ .option('--host <host>', 'network address the server should listen on, e.g. 127.0.0.1')
32
35
  .action(preview);
33
36
  program
34
37
  .command('start [path]')
35
38
  .description('starts the server in production mode')
39
+ .option('--host <host>', 'network address the server should listen on, e.g. 127.0.0.1')
36
40
  .action(start);
37
41
  await program.parseAsync(process.argv);
38
42
  }
@@ -1,3 +1,19 @@
1
+ // src/utils/elements.ts
2
+ var ELEMENT_RE = /^[a-z][\w-]*-[\w-]*$/;
3
+ var HTML_ELEMENTS_REGEX = /<([a-z][\w-]*-[\w-]*)/g;
4
+ function isValidTagName(tagName) {
5
+ return ELEMENT_RE.test(tagName);
6
+ }
7
+ function parseTagNames(src) {
8
+ const tagNames = /* @__PURE__ */ new Set();
9
+ const matches = Array.from(src.matchAll(HTML_ELEMENTS_REGEX));
10
+ for (const match of matches) {
11
+ const tagName = match[1];
12
+ tagNames.add(tagName);
13
+ }
14
+ return Array.from(tagNames);
15
+ }
16
+
1
17
  // src/render/html-minify.ts
2
18
  import { createRequire } from "module";
3
19
  var require2 = createRequire(import.meta.url);
@@ -17,22 +33,6 @@ async function htmlMinify(html, options) {
17
33
  }
18
34
  }
19
35
 
20
- // src/utils/elements.ts
21
- var ELEMENT_RE = /^[a-z][\w-]*-[\w-]*$/;
22
- var HTML_ELEMENTS_REGEX = /<([a-z][\w-]*-[\w-]*)/g;
23
- function isValidTagName(tagName) {
24
- return ELEMENT_RE.test(tagName);
25
- }
26
- function parseTagNames(src) {
27
- const tagNames = /* @__PURE__ */ new Set();
28
- const matches = Array.from(src.matchAll(HTML_ELEMENTS_REGEX));
29
- for (const match of matches) {
30
- const tagName = match[1];
31
- tagNames.add(tagName);
32
- }
33
- return Array.from(tagNames);
34
- }
35
-
36
36
  // src/render/html-pretty.ts
37
37
  import { createRequire as createRequire2 } from "module";
38
38
  var require3 = createRequire2(import.meta.url);
@@ -53,9 +53,9 @@ async function htmlPretty(html, options) {
53
53
  }
54
54
 
55
55
  export {
56
- htmlMinify,
57
56
  isValidTagName,
58
57
  parseTagNames,
58
+ htmlMinify,
59
59
  htmlPretty
60
60
  };
61
- //# sourceMappingURL=chunk-WVRC46JG.js.map
61
+ //# sourceMappingURL=chunk-DFBTOMQF.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/utils/elements.ts","../src/render/html-minify.ts","../src/render/html-pretty.ts"],"sourcesContent":["export const ELEMENT_RE = /^[a-z][\\w-]*-[\\w-]*$/;\nexport const HTML_ELEMENTS_REGEX = /<([a-z][\\w-]*-[\\w-]*)/g;\n\n/**\n * Returns true if the tagName is a valid custom element tag.\n */\nexport function isValidTagName(tagName: string) {\n return ELEMENT_RE.test(tagName);\n}\n\n/**\n * Returns a list of custom elements used in a src string (e.g. HTML, jsx, lit).\n * NOTE: the impl uses a simple regex, so tagNames used in comments and attr\n * values may be included.\n */\nexport function parseTagNames(src: string): string[] {\n const tagNames = new Set<string>();\n const matches = Array.from(src.matchAll(HTML_ELEMENTS_REGEX));\n for (const match of matches) {\n const tagName = match[1];\n tagNames.add(tagName);\n }\n return Array.from(tagNames);\n}\n","import {createRequire} from 'module';\n\nconst require = createRequire(import.meta.url);\nimport type {Options} from 'html-minifier-terser';\n\nconst {minify} = require('html-minifier-terser');\n\nexport type HtmlMinifyOptions = Options;\n\nexport async function htmlMinify(\n html: string,\n options?: HtmlMinifyOptions\n): Promise<string> {\n const minifyOptions = options || {\n collapseWhitespace: true,\n removeComments: true,\n preserveLineBreaks: true,\n };\n try {\n const min = await minify(html, minifyOptions);\n return min.trimStart();\n } catch (e) {\n console.error('failed to minify html:', e);\n return html;\n }\n}\n","import {createRequire} from 'module';\n\nconst require = createRequire(import.meta.url);\nimport type {HTMLBeautifyOptions} from 'js-beautify';\n\nconst beautify = require('js-beautify');\n\nexport type HtmlPrettyOptions = HTMLBeautifyOptions;\n\nexport async function htmlPretty(\n html: string,\n options?: HtmlPrettyOptions\n): Promise<string> {\n const prettyOptions = options || {\n indent_size: 0,\n end_with_newline: true,\n extra_liners: [],\n };\n try {\n const output = beautify.html(html, prettyOptions);\n return output.trimStart();\n } catch (e) {\n console.error('failed to pretty html:', e);\n return html;\n }\n}\n"],"mappings":";AAAO,IAAM,aAAa;AACnB,IAAM,sBAAsB;AAK5B,SAAS,eAAe,SAAiB;AAC9C,SAAO,WAAW,KAAK,OAAO;AAChC;AAOO,SAAS,cAAc,KAAuB;AACnD,QAAM,WAAW,oBAAI,IAAY;AACjC,QAAM,UAAU,MAAM,KAAK,IAAI,SAAS,mBAAmB,CAAC;AAC5D,aAAW,SAAS,SAAS;AAC3B,UAAM,UAAU,MAAM,CAAC;AACvB,aAAS,IAAI,OAAO;AAAA,EACtB;AACA,SAAO,MAAM,KAAK,QAAQ;AAC5B;;;ACvBA,SAAQ,qBAAoB;AAE5B,IAAMA,WAAU,cAAc,YAAY,GAAG;AAG7C,IAAM,EAAC,OAAM,IAAIA,SAAQ,sBAAsB;AAI/C,eAAsB,WACpB,MACA,SACiB;AACjB,QAAM,gBAAgB,WAAW;AAAA,IAC/B,oBAAoB;AAAA,IACpB,gBAAgB;AAAA,IAChB,oBAAoB;AAAA,EACtB;AACA,MAAI;AACF,UAAM,MAAM,MAAM,OAAO,MAAM,aAAa;AAC5C,WAAO,IAAI,UAAU;AAAA,EACvB,SAAS,GAAG;AACV,YAAQ,MAAM,0BAA0B,CAAC;AACzC,WAAO;AAAA,EACT;AACF;;;ACzBA,SAAQ,iBAAAC,sBAAoB;AAE5B,IAAMC,WAAUD,eAAc,YAAY,GAAG;AAG7C,IAAM,WAAWC,SAAQ,aAAa;AAItC,eAAsB,WACpB,MACA,SACiB;AACjB,QAAM,gBAAgB,WAAW;AAAA,IAC/B,aAAa;AAAA,IACb,kBAAkB;AAAA,IAClB,cAAc,CAAC;AAAA,EACjB;AACA,MAAI;AACF,UAAM,SAAS,SAAS,KAAK,MAAM,aAAa;AAChD,WAAO,OAAO,UAAU;AAAA,EAC1B,SAAS,GAAG;AACV,YAAQ,MAAM,0BAA0B,CAAC;AACzC,WAAO;AAAA,EACT;AACF;","names":["require","createRequire","require"]}
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  getVitePlugins
3
- } from "./chunk-DTEQ2AIW.js";
3
+ } from "./chunk-QKBMWK5B.js";
4
4
 
5
5
  // src/node/load-config.ts
6
6
  import path2 from "node:path";
@@ -55,6 +55,17 @@ async function isDirectory(dirpath) {
55
55
  function fileExists(filepath) {
56
56
  return fs.access(filepath).then(() => true).catch(() => false);
57
57
  }
58
+ async function dirExists(dirpath) {
59
+ try {
60
+ const stat = await fs.stat(dirpath);
61
+ return stat.isDirectory();
62
+ } catch (error) {
63
+ if (error.code === "ENOENT") {
64
+ return false;
65
+ }
66
+ throw error;
67
+ }
68
+ }
58
69
  async function directoryContains(dirpath, subpath) {
59
70
  const outer = await fs.realpath(dirpath);
60
71
  const inner = await fs.realpath(subpath);
@@ -80,10 +91,9 @@ async function loadRootConfig(rootDir, options) {
80
91
  }
81
92
 
82
93
  // src/node/vite.ts
83
- import path3 from "node:path";
84
94
  import { createServer } from "vite";
85
95
  async function createViteServer(rootConfig, options) {
86
- var _a, _b;
96
+ var _a, _b, _c;
87
97
  const rootDir = rootConfig.rootDir;
88
98
  const viteConfig = rootConfig.vite || {};
89
99
  let hmrOptions = (_a = viteConfig.server) == null ? void 0 : _a.hmr;
@@ -96,7 +106,10 @@ async function createViteServer(rootConfig, options) {
96
106
  ...viteConfig,
97
107
  mode: "development",
98
108
  root: rootDir,
99
- publicDir: path3.join(rootDir, "public"),
109
+ // publicDir is disabled from the vite dev server since it's handled by the
110
+ // root dev server directly, which allows user middlewares to override
111
+ // files in the public dir.
112
+ publicDir: false,
100
113
  server: {
101
114
  ...viteConfig.server || {},
102
115
  middlewareMode: true,
@@ -108,7 +121,8 @@ async function createViteServer(rootConfig, options) {
108
121
  include: [
109
122
  ...(options == null ? void 0 : options.optimizeDeps) || [],
110
123
  ...((_b = viteConfig.optimizeDeps) == null ? void 0 : _b.include) || []
111
- ]
124
+ ],
125
+ extensions: [...((_c = viteConfig.optimizeDeps) == null ? void 0 : _c.extensions) || [], ".tsx"]
112
126
  },
113
127
  ssr: {
114
128
  ...viteConfig.ssr || {},
@@ -142,9 +156,10 @@ export {
142
156
  loadJson,
143
157
  isDirectory,
144
158
  fileExists,
159
+ dirExists,
145
160
  directoryContains,
146
161
  loadRootConfig,
147
162
  createViteServer,
148
163
  viteSsrLoadModule
149
164
  };
150
- //# sourceMappingURL=chunk-LTSJAEBG.js.map
165
+ //# sourceMappingURL=chunk-J2ANSYAE.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/node/load-config.ts","../src/utils/fsutils.ts","../src/node/vite.ts"],"sourcesContent":["import path from 'node:path';\nimport {bundleRequire} from 'bundle-require';\nimport {RootConfig} from '../core/config';\nimport {fileExists} from '../utils/fsutils';\n\nexport interface ConfigOptions {\n command: string;\n}\n\nexport async function loadRootConfig(\n rootDir: string,\n options: ConfigOptions\n): Promise<RootConfig> {\n const configPath = path.resolve(rootDir, 'root.config.ts');\n const exists = await fileExists(configPath);\n if (!exists) {\n throw new Error(`${configPath} does not exist`);\n }\n const configBundle = await bundleRequire({\n filepath: configPath,\n });\n let config = configBundle.mod.default || {};\n if (typeof config === 'function') {\n config = (await config(options)) || {};\n }\n return Object.assign({}, config, {rootDir});\n}\n","import {promises as fs} from 'node:fs';\nimport path from 'node:path';\n\nimport fsExtra from 'fs-extra';\nimport glob from 'tiny-glob';\n\nexport function isJsFile(filename: string) {\n return !!filename.match(/\\.(j|t)sx?$/);\n}\n\nexport async function writeFile(filepath: string, content: string) {\n const dirPath = path.dirname(filepath);\n await makeDir(dirPath);\n await fs.writeFile(filepath, content);\n}\n\nexport async function makeDir(dirpath: string) {\n try {\n await fs.access(dirpath);\n } catch (e) {\n await fs.mkdir(dirpath, {recursive: true});\n }\n}\n\nexport async function copyDir(srcdir: string, dstdir: string) {\n if (!fsExtra.existsSync(srcdir)) {\n return;\n }\n fsExtra.copySync(srcdir, dstdir, {recursive: true, overwrite: true});\n}\n\n/**\n * Copies a glob of files from one directory to another.\n *\n * Example:\n *\n * ```\n * await copyGlob('*.css', 'src/styles', 'dist/html/styles');\n * ```\n */\nexport async function copyGlob(\n pattern: string,\n srcdir: string,\n dstdir: string\n) {\n const files = await glob(pattern, {cwd: srcdir});\n if (files.length > 0) {\n await makeDir(dstdir);\n }\n files.forEach((file) => {\n fsExtra.copySync(path.resolve(srcdir, file), path.resolve(dstdir, file));\n });\n}\n\nexport async function rmDir(dirpath: string) {\n await fs.rm(dirpath, {recursive: true, force: true});\n}\n\nexport async function loadJson<T = unknown>(filepath: string): Promise<T> {\n const content = await fs.readFile(filepath, 'utf-8');\n return JSON.parse(content);\n}\n\nexport async function isDirectory(dirpath: string) {\n return fs\n .stat(dirpath)\n .then((fsStat) => {\n return fsStat.isDirectory();\n })\n .catch((err) => {\n if (err.code === 'ENOENT') {\n return false;\n }\n throw err;\n });\n}\n\nexport function fileExists(filepath: string): Promise<boolean> {\n return fs\n .access(filepath)\n .then(() => true)\n .catch(() => false);\n}\n\nexport async function dirExists(dirpath: string): Promise<boolean> {\n try {\n const stat = await fs.stat(dirpath);\n return stat.isDirectory();\n } catch (error) {\n if (error.code === 'ENOENT') {\n return false;\n }\n throw error;\n }\n}\n\nexport async function directoryContains(\n dirpath: string,\n subpath: string\n): Promise<boolean> {\n const outer = await fs.realpath(dirpath);\n const inner = await fs.realpath(subpath);\n const rel = path.relative(outer, inner);\n return !rel.startsWith('..');\n}\n\nexport async function listFilesRecursive(dirPath: string): Promise<string[]> {\n const files: string[] = [];\n const entries = await fs.readdir(dirPath, {withFileTypes: true});\n for (const entry of entries) {\n const fullPath = path.join(dirPath, entry.name);\n if (entry.isDirectory()) {\n const subFiles = await listFilesRecursive(fullPath);\n files.push(...subFiles);\n } else {\n files.push(fullPath);\n }\n }\n return files;\n}\n","import path from 'node:path';\n\nimport {createServer, ViteDevServer} from 'vite';\n\nimport {RootConfig} from '../core/config.js';\nimport {getVitePlugins} from '../core/plugin.js';\n\nexport interface CreateViteServerOptions {\n /** Override HMR settings. */\n hmr?: boolean;\n /** The port the server will run on. */\n port?: number;\n /** List of files to include in the optimizeDeps.include config. */\n optimizeDeps?: string[];\n}\n\n/**\n * Returns a vite dev server.\n */\nexport async function createViteServer(\n rootConfig: RootConfig,\n options?: CreateViteServerOptions\n): Promise<ViteDevServer> {\n const rootDir = rootConfig.rootDir;\n const viteConfig = rootConfig.vite || {};\n\n let hmrOptions = viteConfig.server?.hmr;\n if (options?.hmr === false) {\n hmrOptions = false;\n } else if (typeof hmrOptions === 'undefined' && options?.port) {\n // Automatically set the HMR port to `port + 10`. This allows multiple\n // root.js dev servers to run without conflicts.\n hmrOptions = {port: options.port + 10};\n }\n\n const viteServer = await createServer({\n ...viteConfig,\n mode: 'development',\n root: rootDir,\n // publicDir is disabled from the vite dev server since it's handled by the\n // root dev server directly, which allows user middlewares to override\n // files in the public dir.\n publicDir: false,\n server: {\n ...(viteConfig.server || {}),\n middlewareMode: true,\n hmr: hmrOptions,\n },\n appType: 'custom',\n optimizeDeps: {\n ...(viteConfig.optimizeDeps || {}),\n include: [\n ...(options?.optimizeDeps || []),\n ...(viteConfig.optimizeDeps?.include || []),\n ],\n extensions: [...(viteConfig.optimizeDeps?.extensions || []), '.tsx'],\n },\n ssr: {\n ...(viteConfig.ssr || {}),\n noExternal: ['@blinkk/root'],\n },\n esbuild: {\n ...(viteConfig.esbuild || {}),\n jsx: 'automatic',\n jsxImportSource: 'preact',\n },\n plugins: [\n ...(viteConfig.plugins || []),\n ...getVitePlugins(rootConfig.plugins || []),\n ],\n });\n return viteServer;\n}\n\n/**\n * Shortcut `viteServer.ssrLoadModule()` without starting an actual dev server.\n */\nexport async function viteSsrLoadModule(\n rootConfig: RootConfig,\n file: string\n): Promise<Record<string, any>> {\n const viteServer = await createViteServer(rootConfig, {hmr: false});\n const module = await viteServer.ssrLoadModule(file);\n await viteServer.close();\n return module;\n}\n"],"mappings":"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","names":["path","path"]}