@blinkk/root 1.0.0-alpha.3 → 1.0.0-alpha.4

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/dist/cli.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  declare function dev(rootDir?: string): void;
2
2
 
3
- declare function build(rootDir?: string): Promise<void>;
3
+ declare function build(rootProjectDir?: string): Promise<void>;
4
4
 
5
5
  declare function start(): Promise<void>;
6
6
 
package/dist/cli.js CHANGED
@@ -55,18 +55,38 @@ async function isDirectory(dirpath) {
55
55
  var JSX_ELEMENTS_REGEX = /jsxs?\("(\w[\w-]+\w)"/g;
56
56
  var HTML_ELEMENTS_REGEX = /<(\w[\w-]+\w)/g;
57
57
  function pluginRoot(options) {
58
+ var _a;
59
+ const elementsVirtualId = "virtual:root-elements";
60
+ const resolvedElementsVirtualId = "\0" + elementsVirtualId;
58
61
  const rootDir = (options == null ? void 0 : options.rootDir) || process.cwd();
62
+ const rootConfig = (options == null ? void 0 : options.rootConfig) || {};
63
+ const elementsDirs = [path2.join(rootDir, "elements")];
64
+ const includeDirs = ((_a = rootConfig.elements) == null ? void 0 : _a.include) || [];
65
+ includeDirs.forEach((dirPath) => {
66
+ const elementsDir = path2.resolve(rootDir, dirPath);
67
+ if (!elementsDir.startsWith(rootDir)) {
68
+ throw new Error(`the elements dir (${dirPath}) should be relative to the project's root dir (${rootDir})`);
69
+ }
70
+ elementsDirs.push(elementsDir);
71
+ });
59
72
  let elementMap;
60
73
  async function updateElementMap() {
61
74
  elementMap = {};
62
- const files = await glob("./elements/**/*", { cwd: rootDir });
63
- files.forEach((file) => {
64
- const parts = path2.parse(file);
65
- if (isJsFile(parts.base)) {
66
- elementMap[parts.name] = `/${file}`;
75
+ await Promise.all(elementsDirs.map(async (dirPath) => {
76
+ const dirExists = await isDirectory(dirPath);
77
+ if (!dirExists) {
78
+ return;
67
79
  }
68
- });
69
- console.log(JSON.stringify(elementMap));
80
+ const files = await glob("**/*", { cwd: dirPath });
81
+ files.forEach((file) => {
82
+ const parts = path2.parse(file);
83
+ if (isJsFile(parts.base)) {
84
+ const fullPath = path2.join(dirPath, file);
85
+ const moduleId = fullPath.slice(rootDir.length);
86
+ elementMap[parts.name] = moduleId;
87
+ }
88
+ });
89
+ }));
70
90
  }
71
91
  async function getElementImport(tagname) {
72
92
  if (!elementMap) {
@@ -77,14 +97,31 @@ function pluginRoot(options) {
77
97
  }
78
98
  return null;
79
99
  }
100
+ function isCustomElement(id) {
101
+ if (!isJsFile(id)) {
102
+ return false;
103
+ }
104
+ return elementsDirs.some((elementsDir) => {
105
+ return id.startsWith(elementsDir);
106
+ });
107
+ }
80
108
  return {
81
109
  name: "vite-plugin-root",
82
- async transform(src, id) {
83
- if (!id.startsWith(rootDir)) {
84
- return null;
110
+ resolveId(id) {
111
+ if (id === elementsVirtualId) {
112
+ return resolvedElementsVirtualId;
85
113
  }
86
- const moduleId = id.slice(rootDir.length);
87
- if (moduleId.startsWith("/elements/") && isJsFile(id)) {
114
+ return null;
115
+ },
116
+ async load(id) {
117
+ if (id === resolvedElementsVirtualId) {
118
+ await updateElementMap();
119
+ return `export const elementsMap = ${JSON.stringify(elementMap)}`;
120
+ }
121
+ return null;
122
+ },
123
+ async transform(src, id) {
124
+ if (isCustomElement(id)) {
88
125
  const idParts = path2.parse(id);
89
126
  const deps = /* @__PURE__ */ new Set();
90
127
  const tagnames = [
@@ -115,11 +152,11 @@ function pluginRoot(options) {
115
152
  // autogenerated by root:
116
153
  ${importLines}
117
154
  `;
118
- console.log(code);
119
155
  return { code };
120
156
  }
121
157
  return null;
122
158
  }
159
+ return null;
123
160
  }
124
161
  };
125
162
  }
@@ -341,8 +378,9 @@ import { build as viteBuild } from "vite";
341
378
  // src/render/asset-map/build-asset-map.ts
342
379
  import path5 from "path";
343
380
  var BuildAssetMap = class {
344
- constructor(manifest) {
381
+ constructor(manifest, options) {
345
382
  this.manifest = manifest;
383
+ this.elementMap = options.elementMap;
346
384
  this.moduleIdToAsset = /* @__PURE__ */ new Map();
347
385
  Object.keys(this.manifest).forEach((manifestKey) => {
348
386
  const moduleId = `/${manifestKey}`;
@@ -352,6 +390,9 @@ var BuildAssetMap = class {
352
390
  async get(moduleId) {
353
391
  return this.moduleIdToAsset.get(moduleId) || null;
354
392
  }
393
+ isElement(moduleId) {
394
+ return Object.values(this.elementMap).includes(moduleId);
395
+ }
355
396
  toJson() {
356
397
  const result = {};
357
398
  for (const moduleId of this.moduleIdToAsset.keys()) {
@@ -393,7 +434,7 @@ var BuildAsset = class {
393
434
  }
394
435
  visited.add(asset.moduleId);
395
436
  const parts = path5.parse(asset.assetUrl);
396
- if ([".js", ".jsx", ".ts", ".tsx"].includes(parts.ext) && asset.moduleId.includes("/elements/")) {
437
+ if ([".js", ".jsx", ".ts", ".tsx"].includes(parts.ext) && this.assetMap.isElement(asset.moduleId)) {
397
438
  urls.add(asset.assetUrl);
398
439
  }
399
440
  await Promise.all(asset.importedModules.map(async (moduleId) => {
@@ -432,11 +473,10 @@ var BuildAsset = class {
432
473
 
433
474
  // src/cli/commands/build.ts
434
475
  var __dirname3 = path6.dirname(fileURLToPath2(import.meta.url));
435
- async function build(rootDir) {
476
+ async function build(rootProjectDir) {
477
+ var _a;
436
478
  console.log("\u{1F333} Root.js");
437
- if (!rootDir) {
438
- rootDir = process.cwd();
439
- }
479
+ const rootDir = rootProjectDir || process.cwd();
440
480
  const rootConfig = await loadRootConfig(rootDir);
441
481
  const distDir = path6.join(rootDir, "dist");
442
482
  await rmDir(distDir);
@@ -451,15 +491,30 @@ async function build(rootDir) {
451
491
  }
452
492
  });
453
493
  }
494
+ const elementsDirs = [path6.join(rootDir, "elements")];
495
+ const elementsInclude = ((_a = rootConfig.elements) == null ? void 0 : _a.include) || [];
496
+ for (const dirPath of elementsInclude) {
497
+ const elementsDir = path6.resolve(rootDir, dirPath);
498
+ if (!elementsDir.startsWith(rootDir)) {
499
+ throw new Error(`the elements dir (${dirPath}) should be relative to the project's root dir (${rootDir})`);
500
+ }
501
+ elementsDirs.push(elementsDir);
502
+ }
454
503
  const elements = [];
455
- if (await isDirectory(path6.join(rootDir, "elements"))) {
456
- const elementFiles = await glob3(path6.join(rootDir, "elements/**/*"));
457
- elementFiles.forEach((file) => {
458
- const parts = path6.parse(file);
459
- if (isJsFile(parts.base)) {
460
- elements.push(file);
461
- }
462
- });
504
+ const elementMap = {};
505
+ for (const dirPath of elementsDirs) {
506
+ if (await isDirectory(dirPath)) {
507
+ const elementFiles = await glob3("**/*", { cwd: dirPath });
508
+ elementFiles.forEach((file) => {
509
+ const parts = path6.parse(file);
510
+ if (isJsFile(parts.base)) {
511
+ const fullPath = path6.join(dirPath, file);
512
+ const moduleId = fullPath.slice(rootDir.length);
513
+ elements.push(fullPath);
514
+ elementMap[parts.name] = moduleId;
515
+ }
516
+ });
517
+ }
463
518
  }
464
519
  const bundleScripts = [];
465
520
  if (await isDirectory(path6.join(rootDir, "bundles"))) {
@@ -533,7 +588,7 @@ async function build(rootDir) {
533
588
  }
534
589
  });
535
590
  const manifest = await loadJson(path6.join(distDir, "client/manifest.json"));
536
- const assetMap = new BuildAssetMap(manifest);
591
+ const assetMap = new BuildAssetMap(manifest, { elementMap });
537
592
  writeFile(path6.join(distDir, "client/root-manifest.json"), JSON.stringify(assetMap.toJson(), null, 2));
538
593
  const buildDir = path6.join(distDir, "html");
539
594
  const publicDir = path6.join(rootDir, "public");
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli/commands/dev.ts","../src/render/vite-plugin-root.ts","../src/core/fsutils.ts","../src/render/asset-map/dev-asset-map.ts","../src/cli/load-config.ts","../src/render/html-minify.ts","../src/cli/commands/build.ts","../src/render/asset-map/build-asset-map.ts","../src/cli/commands/start.ts"],"sourcesContent":["import path from 'node:path';\nimport {fileURLToPath} from 'node:url';\nimport {default as express, Request, Response, NextFunction} from 'express';\nimport {createServer as createViteServer} from 'vite';\nimport {pluginRoot} from '../../render/vite-plugin-root.js';\nimport {DevServerAssetMap} from '../../render/asset-map/dev-asset-map.js';\nimport {loadRootConfig} from '../load-config.js';\nimport {htmlMinify} from '../../render/html-minify.js';\nimport {Renderer} from '../../render/render.js';\nimport {isDirectory, isJsFile} from '../../core/fsutils.js';\nimport glob from 'tiny-glob';\n\nconst __dirname = path.dirname(fileURLToPath(import.meta.url));\n\nexport async function createServer(options?: {rootDir?: string}) {\n const app = express();\n\n app.use(express.static('public'));\n const middlewares = await getMiddlewares({rootDir: options?.rootDir});\n middlewares.forEach((middleware) => app.use(middleware));\n\n const port = parseInt(process.env.PORT || '4007');\n console.log('🌳 Root.js');\n console.log();\n console.log(`Started server: http://localhost:${port}`);\n app.listen(port);\n}\n\nexport async function getMiddlewares(options?: {rootDir?: string}) {\n const rootDir = options?.rootDir || process.cwd();\n const rootConfig = await loadRootConfig(rootDir);\n const viteConfig = rootConfig.vite || {};\n const renderModulePath = path.resolve(__dirname, './render.js');\n\n const pages: string[] = [];\n if (await isDirectory(path.join(rootDir, 'routes'))) {\n const pageFiles = await glob(path.join(rootDir, 'routes/**/*'));\n pageFiles.forEach((file) => {\n const parts = path.parse(file);\n if (!parts.name.startsWith('_') && isJsFile(parts.base)) {\n pages.push(file);\n }\n });\n }\n\n const elements: string[] = [];\n if (await isDirectory(path.join(rootDir, 'elements'))) {\n const elementFiles = await glob(path.join(rootDir, 'elements/**/*'));\n elementFiles.forEach((file) => {\n const parts = path.parse(file);\n if (isJsFile(parts.base)) {\n elements.push(file);\n }\n });\n }\n\n const bundleScripts: string[] = [];\n if (await isDirectory(path.join(rootDir, 'bundles'))) {\n const bundleFiles = await glob(path.join(rootDir, 'bundles/*'));\n bundleFiles.forEach((file) => {\n const parts = path.parse(file);\n if (isJsFile(parts.base)) {\n bundleScripts.push(file);\n }\n });\n }\n\n const viteServer = await createViteServer({\n ...viteConfig,\n server: {middlewareMode: true},\n appType: 'custom',\n optimizeDeps: {\n include: [...pages, ...elements, ...bundleScripts],\n },\n ssr: {\n noExternal: ['@blinkk/root'],\n },\n esbuild: {\n jsx: 'automatic',\n jsxImportSource: 'preact',\n },\n plugins: [...(viteConfig.plugins || []), pluginRoot({rootDir, rootConfig})],\n });\n\n const rootMiddleware = async (\n req: Request,\n res: Response,\n next: NextFunction\n ) => {\n const url = req.originalUrl;\n const render = await viteServer.ssrLoadModule(renderModulePath);\n const renderer = new render.Renderer(rootConfig) as Renderer;\n try {\n // Create a dev asset map using Vite dev server's module graph.\n const assetMap = new DevServerAssetMap(viteServer.moduleGraph);\n const data = await renderer.render(url, {\n assetMap: assetMap,\n });\n // Inject the Vite HMR client.\n const html = await htmlMinify(\n await viteServer.transformIndexHtml(url, data.html || '')\n );\n\n res.status(200).set({'Content-Type': 'text/html'}).end(html);\n } catch (e) {\n // If an error is caught, let Vite fix the stack trace so it maps back to\n // your actual source code.\n viteServer.ssrFixStacktrace(e);\n try {\n const {html} = await renderer.renderError(e);\n res.status(500).set({'Content-Type': 'text/html'}).end(html);\n } catch (e2) {\n console.error('failed to render custom error');\n console.error(e2);\n next(e);\n }\n }\n };\n\n return [viteServer.middlewares, rootMiddleware];\n}\n\nexport function dev(rootDir?: string) {\n createServer({rootDir});\n}\n","import path from 'path';\nimport glob from 'tiny-glob';\nimport {RootConfig} from '../core/config';\nimport {isJsFile} from '../core/fsutils';\n\nconst JSX_ELEMENTS_REGEX = /jsxs?\\(\"(\\w[\\w-]+\\w)\"/g;\nconst HTML_ELEMENTS_REGEX = /<(\\w[\\w-]+\\w)/g;\n\nexport interface RootPluginOptions {\n rootDir: string;\n rootConfig: RootConfig;\n}\n\nexport function pluginRoot(options?: RootPluginOptions) {\n const rootDir = options?.rootDir || process.cwd();\n let elementMap: Record<string, string>;\n\n async function updateElementMap() {\n elementMap = {};\n const files = await glob('./elements/**/*', {cwd: rootDir});\n files.forEach((file) => {\n const parts = path.parse(file);\n if (isJsFile(parts.base)) {\n elementMap[parts.name] = `/${file}`;\n }\n });\n console.log(JSON.stringify(elementMap));\n }\n\n async function getElementImport(tagname: string): Promise<string | null> {\n if (!elementMap) {\n await updateElementMap();\n }\n if (tagname in elementMap) {\n return elementMap[tagname];\n }\n return null;\n }\n\n return {\n name: 'vite-plugin-root',\n\n async transform(src: string, id: string): Promise<any> {\n if (!id.startsWith(rootDir)) {\n return null;\n }\n const moduleId = id.slice(rootDir.length);\n if (moduleId.startsWith('/elements/') && isJsFile(id)) {\n const idParts = path.parse(id);\n const deps = new Set<string>();\n const tagnames = [\n ...src.matchAll(JSX_ELEMENTS_REGEX),\n ...src.matchAll(HTML_ELEMENTS_REGEX),\n ];\n for (const match of tagnames) {\n const tagname = match[1];\n // All custom elements should contain a dash.\n if (!tagname.includes('-')) {\n continue;\n }\n // Avoid circular deps.\n if (tagname === idParts.name) {\n continue;\n }\n deps.add(tagname);\n }\n const importUrls: string[] = [];\n await Promise.all(\n Array.from(deps).map(async (tagname) => {\n const importUrl = await getElementImport(tagname);\n if (importUrl) {\n importUrls.push(importUrl);\n }\n })\n );\n if (importUrls.length > 0) {\n const importLines = importUrls\n .map((url) => `import '${url}';`)\n .join('\\n');\n const code = `${src}\n\n// autogenerated by root:\n${importLines}\n`;\n console.log(code);\n return {code};\n }\n return null;\n }\n },\n };\n}\n","import {promises as fs} from 'node:fs';\nimport path from 'node:path';\nimport fsExtra from 'fs-extra';\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\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","import path from 'node:path';\nimport {ModuleGraph, ModuleNode} from 'vite';\nimport {Asset, AssetMap} from './asset-map';\n\nexport class DevServerAssetMap implements AssetMap {\n private moduleGraph: ModuleGraph;\n\n constructor(moduleGraph: ModuleGraph) {\n this.moduleGraph = moduleGraph;\n }\n\n async get(moduleId: string): Promise<Asset | null> {\n const viteModule = await this.moduleGraph.getModuleByUrl(moduleId);\n if (!viteModule || !viteModule.id) {\n return null;\n }\n return new DevServerAsset(this, viteModule);\n }\n}\n\nexport class DevServerAsset implements Asset {\n moduleId: string;\n assetUrl: string;\n private assetMap: AssetMap;\n private viteModule: ModuleNode;\n\n constructor(assetMap: AssetMap, viteModule: ModuleNode) {\n this.assetMap = assetMap;\n this.viteModule = viteModule;\n this.moduleId = this.viteModule.id!;\n this.assetUrl = this.viteModule.url;\n }\n\n async getCssDeps(): Promise<string[]> {\n const visited = new Set<string>();\n const deps = new Set<string>();\n this.collectCss(this, deps, visited);\n return Array.from(deps);\n }\n\n async getJsDeps(): Promise<string[]> {\n const visited = new Set<string>();\n const deps = new Set<string>();\n this.collectJs(this, deps, visited);\n return Array.from(deps);\n }\n\n getImportedModules() {\n return this.viteModule.importedModules;\n }\n\n private collectJs(\n asset: DevServerAsset | null,\n urls: Set<string>,\n visited: Set<string>\n ) {\n if (!asset) {\n return;\n }\n if (!asset.moduleId) {\n return;\n }\n if (visited.has(asset.moduleId)) {\n return;\n }\n visited.add(asset.moduleId);\n const parts = path.parse(asset.assetUrl);\n if (\n ['.js', '.jsx', '.ts', '.tsx'].includes(parts.ext) &&\n asset.moduleId.includes('/elements/')\n ) {\n urls.add(asset.assetUrl);\n }\n asset.getImportedModules().forEach((viteModule) => {\n if (viteModule.id) {\n const importedAsset = new DevServerAsset(this.assetMap, viteModule);\n this.collectJs(importedAsset, urls, visited);\n }\n });\n }\n\n private collectCss(\n asset: DevServerAsset | null,\n urls: Set<string>,\n visited: Set<string>\n ) {\n if (!asset) {\n return;\n }\n if (!asset.assetUrl) {\n return;\n }\n if (visited.has(asset.assetUrl)) {\n return;\n }\n visited.add(asset.assetUrl);\n if (asset.moduleId.endsWith('.scss')) {\n const parts = path.parse(asset.assetUrl);\n if (!parts.name.startsWith('_')) {\n urls.add(asset.assetUrl);\n }\n }\n asset.getImportedModules().forEach((viteModule) => {\n if (viteModule.id) {\n const importedAsset = new DevServerAsset(this.assetMap, viteModule);\n this.collectCss(importedAsset, urls, visited);\n }\n });\n }\n}\n","import {bundleRequire} from 'bundle-require';\nimport JoyCon from 'joycon';\nimport {RootConfig} from '../core/config';\n\nexport async function loadRootConfig(rootDir: string): Promise<RootConfig> {\n const joycon = new JoyCon();\n const configPath = await joycon.resolve({\n cwd: rootDir,\n files: ['root.config.ts'],\n });\n if (configPath) {\n const configBundle = await bundleRequire({\n filepath: configPath,\n });\n return configBundle.mod.default || {};\n }\n return {};\n}\n","import {minify} from 'html-minifier-terser';\n\nexport async function htmlMinify(html: string): Promise<string> {\n const min = await minify(html, {\n collapseWhitespace: true,\n removeComments: true,\n preserveLineBreaks: true,\n });\n return min.trimStart();\n}\n","import path from 'node:path';\nimport {fileURLToPath} from 'node:url';\nimport fsExtra from 'fs-extra';\nimport glob from 'tiny-glob';\nimport {build as viteBuild, Manifest, UserConfig} from 'vite';\nimport {pluginRoot} from '../../render/vite-plugin-root.js';\nimport {BuildAssetMap} from '../../render/asset-map/build-asset-map.js';\nimport {loadRootConfig} from '../load-config.js';\nimport {\n copyDir,\n isDirectory,\n isJsFile,\n loadJson,\n makeDir,\n rmDir,\n writeFile,\n} from '../../core/fsutils.js';\nimport {Renderer} from '../../render/render.js';\nimport {htmlMinify} from '../../render/html-minify.js';\n\nconst __dirname = path.dirname(fileURLToPath(import.meta.url));\n\nexport async function build(rootDir?: string) {\n console.log('🌳 Root.js');\n\n if (!rootDir) {\n rootDir = process.cwd();\n }\n const rootConfig = await loadRootConfig(rootDir);\n const distDir = path.join(rootDir, 'dist');\n await rmDir(distDir);\n await makeDir(distDir);\n\n const pages: string[] = [];\n if (await isDirectory(path.join(rootDir, 'routes'))) {\n const pageFiles = await glob(path.join(rootDir, 'routes/**/*'));\n pageFiles.forEach((file) => {\n const parts = path.parse(file);\n if (!parts.name.startsWith('_') && isJsFile(parts.base)) {\n pages.push(file);\n }\n });\n }\n\n const elements: string[] = [];\n if (await isDirectory(path.join(rootDir, 'elements'))) {\n const elementFiles = await glob(path.join(rootDir, 'elements/**/*'));\n elementFiles.forEach((file) => {\n const parts = path.parse(file);\n if (isJsFile(parts.base)) {\n elements.push(file);\n }\n });\n }\n\n const bundleScripts: string[] = [];\n if (await isDirectory(path.join(rootDir, 'bundles'))) {\n const bundleFiles = await glob(path.join(rootDir, 'bundles/*'));\n bundleFiles.forEach((file) => {\n const parts = path.parse(file);\n if (isJsFile(parts.base)) {\n bundleScripts.push(file);\n }\n });\n }\n\n const viteConfig = rootConfig.vite || {};\n const baseConfig: UserConfig = {\n ...viteConfig,\n root: rootDir,\n esbuild: {\n jsx: 'automatic',\n jsxImportSource: 'preact',\n treeShaking: true,\n },\n plugins: [...(viteConfig.plugins || []), pluginRoot({rootDir, rootConfig})],\n };\n\n // Bundle the render.js file with vite, which is pre-optimized for rendering\n // HTML routes.\n await viteBuild({\n ...baseConfig,\n mode: 'production',\n publicDir: false,\n build: {\n rollupOptions: {\n input: [path.resolve(__dirname, './render.js')],\n output: {\n format: 'esm',\n chunkFileNames: 'chunks/[name].[hash].js',\n assetFileNames: 'assets/[name].[hash][extname]',\n },\n },\n outDir: path.join(distDir, 'server'),\n ssr: true,\n ssrManifest: false,\n cssCodeSplit: true,\n target: 'esnext',\n minify: false,\n polyfillModulePreload: false,\n reportCompressedSize: false,\n },\n ssr: {\n noExternal: ['@blinkk/root'],\n },\n });\n\n // Pre-render any client scripts and CSS deps.\n await viteBuild({\n ...baseConfig,\n mode: 'production',\n publicDir: false,\n build: {\n rollupOptions: {\n input: [...pages, ...elements, ...bundleScripts],\n output: {\n format: 'esm',\n chunkFileNames: 'chunks/[name].[hash].js',\n assetFileNames: 'assets/[name].[hash][extname]',\n },\n },\n outDir: path.join(distDir, 'client'),\n ssr: false,\n ssrManifest: false,\n manifest: true,\n cssCodeSplit: true,\n target: 'esnext',\n minify: true,\n polyfillModulePreload: false,\n reportCompressedSize: false,\n },\n });\n\n const manifest = await loadJson<Manifest>(\n path.join(distDir, 'client/manifest.json')\n );\n\n // Use the output of the client build to generate an asset map, which is used\n // by the renderer for automatically injecting dependencies for a page.\n const assetMap = new BuildAssetMap(manifest);\n\n // Save the asset map to `dist/client` for use by the prod SSR server.\n writeFile(\n path.join(distDir, 'client/root-manifest.json'),\n JSON.stringify(assetMap.toJson(), null, 2)\n );\n\n // Write SSG output to `dist/html`.\n const buildDir = path.join(distDir, 'html');\n\n // Recursively copy files from `public` to `dist/html`.\n const publicDir = path.join(rootDir, 'public');\n if (fsExtra.existsSync(path.join(rootDir, 'public'))) {\n fsExtra.copySync(publicDir, buildDir);\n } else {\n makeDir(buildDir);\n }\n\n // Copy files from `dist/client/{assets,chunks}` to `dist/html`.\n copyDir(path.join(distDir, 'client/assets'), path.join(buildDir, 'assets'));\n copyDir(path.join(distDir, 'client/chunks'), path.join(buildDir, 'chunks'));\n\n // Render HTML pages.\n const render = await import(path.join(distDir, 'server/render.js'));\n const renderer = new render.Renderer(rootConfig) as Renderer;\n const sitemap = await renderer.getSitemap();\n\n await Promise.all(\n Object.keys(sitemap).map(async (urlPath) => {\n const {route, params} = sitemap[urlPath];\n const data = await renderer.renderRoute(route, {\n assetMap,\n routeParams: params,\n });\n\n // The renderer currently assumes that all paths serve HTML.\n // TODO(stevenle): support non-HTML routes using `routes/[name].[ext].ts`.\n let outPath = path.join(distDir, `html${urlPath}`, 'index.html');\n\n if (outPath.endsWith('404/index.html')) {\n outPath = outPath.replace('404/index.html', '404.html');\n }\n\n const html = await htmlMinify(data.html || '');\n await writeFile(outPath, html);\n\n const relPath = outPath.slice(path.dirname(distDir).length + 1);\n console.log(`saved ${relPath}`);\n })\n );\n}\n","import path from 'path';\nimport {Manifest, ManifestChunk} from 'vite';\nimport {Asset, AssetMap} from './asset-map';\n\ntype BuildAssetManifest = Record<\n string,\n {\n moduleId: string;\n assetUrl: string;\n importedModules: string[];\n importedCss: string[];\n }\n>;\n\nexport class BuildAssetMap implements AssetMap {\n private manifest: Manifest;\n private moduleIdToAsset: Map<string, BuildAsset>;\n\n constructor(manifest: Manifest) {\n this.manifest = manifest;\n this.moduleIdToAsset = new Map();\n Object.keys(this.manifest).forEach((manifestKey) => {\n const moduleId = `/${manifestKey}`;\n this.moduleIdToAsset.set(\n moduleId,\n new BuildAsset(this, moduleId, this.manifest[manifestKey])\n );\n });\n }\n\n async get(moduleId: string): Promise<Asset | null> {\n return this.moduleIdToAsset.get(moduleId) || null;\n }\n\n toJson(): BuildAssetManifest {\n const result: BuildAssetManifest = {};\n for (const moduleId of this.moduleIdToAsset.keys()) {\n result[moduleId] = this.moduleIdToAsset.get(moduleId)!.toJson();\n }\n return result;\n }\n}\n\nexport class BuildAsset {\n moduleId: string;\n assetUrl: string;\n private assetMap: BuildAssetMap;\n private manifestData: ManifestChunk;\n private importedModules: string[];\n private importedCss: string[];\n\n constructor(\n assetMap: BuildAssetMap,\n moduleId: string,\n manifestData: ManifestChunk\n ) {\n this.assetMap = assetMap;\n this.moduleId = moduleId;\n this.manifestData = manifestData;\n this.assetUrl = `/${manifestData.file}`;\n this.importedModules = (this.manifestData.imports || []).map(\n (relPath) => `/${relPath}`\n );\n this.importedCss = (this.manifestData.css || []).map(\n (relPath) => `/${relPath}`\n );\n }\n\n async getCssDeps(): Promise<string[]> {\n const visited = new Set<string>();\n const deps = new Set<string>();\n await this.collectCss(this, deps, visited);\n return Array.from(deps);\n }\n\n async getJsDeps(): Promise<string[]> {\n const visited = new Set<string>();\n const deps = new Set<string>();\n await this.collectJs(this, deps, visited);\n return Array.from(deps);\n }\n\n private async collectJs(\n asset: BuildAsset | null,\n urls: Set<string>,\n visited: Set<string>\n ) {\n if (!asset) {\n return;\n }\n if (!asset.moduleId) {\n return;\n }\n if (visited.has(asset.moduleId)) {\n return;\n }\n visited.add(asset.moduleId);\n const parts = path.parse(asset.assetUrl);\n if (\n ['.js', '.jsx', '.ts', '.tsx'].includes(parts.ext) &&\n asset.moduleId.includes('/elements/')\n ) {\n urls.add(asset.assetUrl);\n }\n await Promise.all(\n asset.importedModules.map(async (moduleId) => {\n const importedAsset = (await this.assetMap.get(moduleId)) as BuildAsset;\n this.collectJs(importedAsset, urls, visited);\n })\n );\n }\n\n private async collectCss(\n asset: BuildAsset | null,\n urls: Set<string>,\n visited: Set<string>\n ) {\n if (!asset) {\n return;\n }\n if (!asset.assetUrl) {\n return;\n }\n if (visited.has(asset.moduleId)) {\n return;\n }\n visited.add(asset.moduleId);\n if (asset.importedCss) {\n asset.importedCss.forEach((cssUrl) => urls.add(cssUrl));\n }\n await Promise.all(\n asset.importedModules.map(async (moduleId) => {\n const importedAsset = (await this.assetMap.get(moduleId)) as BuildAsset;\n this.collectCss(importedAsset, urls, visited);\n })\n );\n }\n\n toJson() {\n return {\n moduleId: this.moduleId,\n assetUrl: this.assetUrl,\n importedModules: this.importedModules,\n importedCss: this.importedCss,\n };\n }\n}\n","export async function start() {\n console.log('SSR production server is coming soon');\n}\n"],"mappings":";AAAA;AACA;AACA;AACA;;;ACHA;AACA;;;ACDA;AACA;AACA;AAEO,kBAAkB,UAAkB;AACzC,SAAO,CAAC,CAAC,SAAS,MAAM,aAAa;AACvC;AAEA,yBAAgC,UAAkB,SAAiB;AACjE,QAAM,UAAU,KAAK,QAAQ,QAAQ;AACrC,QAAM,QAAQ,OAAO;AACrB,QAAM,GAAG,UAAU,UAAU,OAAO;AACtC;AAEA,uBAA8B,SAAiB;AAC7C,MAAI;AACF,UAAM,GAAG,OAAO,OAAO;AAAA,EACzB,SAAS,GAAP;AACA,UAAM,GAAG,MAAM,SAAS,EAAC,WAAW,KAAI,CAAC;AAAA,EAC3C;AACF;AAEA,uBAA8B,QAAgB,QAAgB;AAC5D,MAAI,CAAC,QAAQ,WAAW,MAAM,GAAG;AAC/B;AAAA,EACF;AACA,UAAQ,SAAS,QAAQ,QAAQ,EAAC,WAAW,MAAM,WAAW,KAAI,CAAC;AACrE;AAEA,qBAA4B,SAAiB;AAC3C,QAAM,GAAG,GAAG,SAAS,EAAC,WAAW,MAAM,OAAO,KAAI,CAAC;AACrD;AAEA,wBAA4C,UAA8B;AACxE,QAAM,UAAU,MAAM,GAAG,SAAS,UAAU,OAAO;AACnD,SAAO,KAAK,MAAM,OAAO;AAC3B;AAEA,2BAAkC,SAAiB;AACjD,SAAO,GACJ,KAAK,OAAO,EACZ,KAAK,CAAC,WAAW;AAChB,WAAO,OAAO,YAAY;AAAA,EAC5B,CAAC,EACA,MAAM,CAAC,QAAQ;AACd,QAAI,IAAI,SAAS,UAAU;AACzB,aAAO;AAAA,IACT;AACA,UAAM;AAAA,EACR,CAAC;AACL;;;AD7CA,IAAM,qBAAqB;AAC3B,IAAM,sBAAsB;AAOrB,oBAAoB,SAA6B;AACtD,QAAM,UAAU,oCAAS,YAAW,QAAQ,IAAI;AAChD,MAAI;AAEJ,oCAAkC;AAChC,iBAAa,CAAC;AACd,UAAM,QAAQ,MAAM,KAAK,mBAAmB,EAAC,KAAK,QAAO,CAAC;AAC1D,UAAM,QAAQ,CAAC,SAAS;AACtB,YAAM,QAAQ,MAAK,MAAM,IAAI;AAC7B,UAAI,SAAS,MAAM,IAAI,GAAG;AACxB,mBAAW,MAAM,QAAQ,IAAI;AAAA,MAC/B;AAAA,IACF,CAAC;AACD,YAAQ,IAAI,KAAK,UAAU,UAAU,CAAC;AAAA,EACxC;AAEA,kCAAgC,SAAyC;AACvE,QAAI,CAAC,YAAY;AACf,YAAM,iBAAiB;AAAA,IACzB;AACA,QAAI,WAAW,YAAY;AACzB,aAAO,WAAW;AAAA,IACpB;AACA,WAAO;AAAA,EACT;AAEA,SAAO;AAAA,IACL,MAAM;AAAA,IAEN,MAAM,UAAU,KAAa,IAA0B;AACrD,UAAI,CAAC,GAAG,WAAW,OAAO,GAAG;AAC3B,eAAO;AAAA,MACT;AACA,YAAM,WAAW,GAAG,MAAM,QAAQ,MAAM;AACxC,UAAI,SAAS,WAAW,YAAY,KAAK,SAAS,EAAE,GAAG;AACrD,cAAM,UAAU,MAAK,MAAM,EAAE;AAC7B,cAAM,OAAO,oBAAI,IAAY;AAC7B,cAAM,WAAW;AAAA,UACf,GAAG,IAAI,SAAS,kBAAkB;AAAA,UAClC,GAAG,IAAI,SAAS,mBAAmB;AAAA,QACrC;AACA,mBAAW,SAAS,UAAU;AAC5B,gBAAM,UAAU,MAAM;AAEtB,cAAI,CAAC,QAAQ,SAAS,GAAG,GAAG;AAC1B;AAAA,UACF;AAEA,cAAI,YAAY,QAAQ,MAAM;AAC5B;AAAA,UACF;AACA,eAAK,IAAI,OAAO;AAAA,QAClB;AACA,cAAM,aAAuB,CAAC;AAC9B,cAAM,QAAQ,IACZ,MAAM,KAAK,IAAI,EAAE,IAAI,OAAO,YAAY;AACtC,gBAAM,YAAY,MAAM,iBAAiB,OAAO;AAChD,cAAI,WAAW;AACb,uBAAW,KAAK,SAAS;AAAA,UAC3B;AAAA,QACF,CAAC,CACH;AACA,YAAI,WAAW,SAAS,GAAG;AACzB,gBAAM,cAAc,WACjB,IAAI,CAAC,QAAQ,WAAW,OAAO,EAC/B,KAAK,IAAI;AACZ,gBAAM,OAAO,GAAG;AAAA;AAAA;AAAA,EAGxB;AAAA;AAEQ,kBAAQ,IAAI,IAAI;AAChB,iBAAO,EAAC,KAAI;AAAA,QACd;AACA,eAAO;AAAA,MACT;AAAA,IACF;AAAA,EACF;AACF;;;AE3FA;AAIO,IAAM,oBAAN,MAA4C;AAAA,EAGjD,YAAY,aAA0B;AACpC,SAAK,cAAc;AAAA,EACrB;AAAA,EAEA,MAAM,IAAI,UAAyC;AACjD,UAAM,aAAa,MAAM,KAAK,YAAY,eAAe,QAAQ;AACjE,QAAI,CAAC,cAAc,CAAC,WAAW,IAAI;AACjC,aAAO;AAAA,IACT;AACA,WAAO,IAAI,eAAe,MAAM,UAAU;AAAA,EAC5C;AACF;AAEO,IAAM,iBAAN,MAAsC;AAAA,EAM3C,YAAY,UAAoB,YAAwB;AACtD,SAAK,WAAW;AAChB,SAAK,aAAa;AAClB,SAAK,WAAW,KAAK,WAAW;AAChC,SAAK,WAAW,KAAK,WAAW;AAAA,EAClC;AAAA,EAEA,MAAM,aAAgC;AACpC,UAAM,UAAU,oBAAI,IAAY;AAChC,UAAM,OAAO,oBAAI,IAAY;AAC7B,SAAK,WAAW,MAAM,MAAM,OAAO;AACnC,WAAO,MAAM,KAAK,IAAI;AAAA,EACxB;AAAA,EAEA,MAAM,YAA+B;AACnC,UAAM,UAAU,oBAAI,IAAY;AAChC,UAAM,OAAO,oBAAI,IAAY;AAC7B,SAAK,UAAU,MAAM,MAAM,OAAO;AAClC,WAAO,MAAM,KAAK,IAAI;AAAA,EACxB;AAAA,EAEA,qBAAqB;AACnB,WAAO,KAAK,WAAW;AAAA,EACzB;AAAA,EAEA,AAAQ,UACN,OACA,MACA,SACA;AACA,QAAI,CAAC,OAAO;AACV;AAAA,IACF;AACA,QAAI,CAAC,MAAM,UAAU;AACnB;AAAA,IACF;AACA,QAAI,QAAQ,IAAI,MAAM,QAAQ,GAAG;AAC/B;AAAA,IACF;AACA,YAAQ,IAAI,MAAM,QAAQ;AAC1B,UAAM,QAAQ,MAAK,MAAM,MAAM,QAAQ;AACvC,QACE,CAAC,OAAO,QAAQ,OAAO,MAAM,EAAE,SAAS,MAAM,GAAG,KACjD,MAAM,SAAS,SAAS,YAAY,GACpC;AACA,WAAK,IAAI,MAAM,QAAQ;AAAA,IACzB;AACA,UAAM,mBAAmB,EAAE,QAAQ,CAAC,eAAe;AACjD,UAAI,WAAW,IAAI;AACjB,cAAM,gBAAgB,IAAI,eAAe,KAAK,UAAU,UAAU;AAClE,aAAK,UAAU,eAAe,MAAM,OAAO;AAAA,MAC7C;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,AAAQ,WACN,OACA,MACA,SACA;AACA,QAAI,CAAC,OAAO;AACV;AAAA,IACF;AACA,QAAI,CAAC,MAAM,UAAU;AACnB;AAAA,IACF;AACA,QAAI,QAAQ,IAAI,MAAM,QAAQ,GAAG;AAC/B;AAAA,IACF;AACA,YAAQ,IAAI,MAAM,QAAQ;AAC1B,QAAI,MAAM,SAAS,SAAS,OAAO,GAAG;AACpC,YAAM,QAAQ,MAAK,MAAM,MAAM,QAAQ;AACvC,UAAI,CAAC,MAAM,KAAK,WAAW,GAAG,GAAG;AAC/B,aAAK,IAAI,MAAM,QAAQ;AAAA,MACzB;AAAA,IACF;AACA,UAAM,mBAAmB,EAAE,QAAQ,CAAC,eAAe;AACjD,UAAI,WAAW,IAAI;AACjB,cAAM,gBAAgB,IAAI,eAAe,KAAK,UAAU,UAAU;AAClE,aAAK,WAAW,eAAe,MAAM,OAAO;AAAA,MAC9C;AAAA,IACF,CAAC;AAAA,EACH;AACF;;;AC7GA;AACA;AAGA,8BAAqC,SAAsC;AACzE,QAAM,SAAS,IAAI,OAAO;AAC1B,QAAM,aAAa,MAAM,OAAO,QAAQ;AAAA,IACtC,KAAK;AAAA,IACL,OAAO,CAAC,gBAAgB;AAAA,EAC1B,CAAC;AACD,MAAI,YAAY;AACd,UAAM,eAAe,MAAM,cAAc;AAAA,MACvC,UAAU;AAAA,IACZ,CAAC;AACD,WAAO,aAAa,IAAI,WAAW,CAAC;AAAA,EACtC;AACA,SAAO,CAAC;AACV;;;ACjBA;AAEA,0BAAiC,MAA+B;AAC9D,QAAM,MAAM,MAAM,OAAO,MAAM;AAAA,IAC7B,oBAAoB;AAAA,IACpB,gBAAgB;AAAA,IAChB,oBAAoB;AAAA,EACtB,CAAC;AACD,SAAO,IAAI,UAAU;AACvB;;;ALCA;AAEA,IAAM,aAAY,MAAK,QAAQ,cAAc,YAAY,GAAG,CAAC;AAE7D,4BAAmC,SAA8B;AAC/D,QAAM,MAAM,QAAQ;AAEpB,MAAI,IAAI,QAAQ,OAAO,QAAQ,CAAC;AAChC,QAAM,cAAc,MAAM,eAAe,EAAC,SAAS,mCAAS,QAAO,CAAC;AACpE,cAAY,QAAQ,CAAC,eAAe,IAAI,IAAI,UAAU,CAAC;AAEvD,QAAM,OAAO,SAAS,QAAQ,IAAI,QAAQ,MAAM;AAChD,UAAQ,IAAI,mBAAY;AACxB,UAAQ,IAAI;AACZ,UAAQ,IAAI,oCAAoC,MAAM;AACtD,MAAI,OAAO,IAAI;AACjB;AAEA,8BAAqC,SAA8B;AACjE,QAAM,UAAU,oCAAS,YAAW,QAAQ,IAAI;AAChD,QAAM,aAAa,MAAM,eAAe,OAAO;AAC/C,QAAM,aAAa,WAAW,QAAQ,CAAC;AACvC,QAAM,mBAAmB,MAAK,QAAQ,YAAW,aAAa;AAE9D,QAAM,QAAkB,CAAC;AACzB,MAAI,MAAM,YAAY,MAAK,KAAK,SAAS,QAAQ,CAAC,GAAG;AACnD,UAAM,YAAY,MAAM,MAAK,MAAK,KAAK,SAAS,aAAa,CAAC;AAC9D,cAAU,QAAQ,CAAC,SAAS;AAC1B,YAAM,QAAQ,MAAK,MAAM,IAAI;AAC7B,UAAI,CAAC,MAAM,KAAK,WAAW,GAAG,KAAK,SAAS,MAAM,IAAI,GAAG;AACvD,cAAM,KAAK,IAAI;AAAA,MACjB;AAAA,IACF,CAAC;AAAA,EACH;AAEA,QAAM,WAAqB,CAAC;AAC5B,MAAI,MAAM,YAAY,MAAK,KAAK,SAAS,UAAU,CAAC,GAAG;AACrD,UAAM,eAAe,MAAM,MAAK,MAAK,KAAK,SAAS,eAAe,CAAC;AACnE,iBAAa,QAAQ,CAAC,SAAS;AAC7B,YAAM,QAAQ,MAAK,MAAM,IAAI;AAC7B,UAAI,SAAS,MAAM,IAAI,GAAG;AACxB,iBAAS,KAAK,IAAI;AAAA,MACpB;AAAA,IACF,CAAC;AAAA,EACH;AAEA,QAAM,gBAA0B,CAAC;AACjC,MAAI,MAAM,YAAY,MAAK,KAAK,SAAS,SAAS,CAAC,GAAG;AACpD,UAAM,cAAc,MAAM,MAAK,MAAK,KAAK,SAAS,WAAW,CAAC;AAC9D,gBAAY,QAAQ,CAAC,SAAS;AAC5B,YAAM,QAAQ,MAAK,MAAM,IAAI;AAC7B,UAAI,SAAS,MAAM,IAAI,GAAG;AACxB,sBAAc,KAAK,IAAI;AAAA,MACzB;AAAA,IACF,CAAC;AAAA,EACH;AAEA,QAAM,aAAa,MAAM,iBAAiB;AAAA,IACxC,GAAG;AAAA,IACH,QAAQ,EAAC,gBAAgB,KAAI;AAAA,IAC7B,SAAS;AAAA,IACT,cAAc;AAAA,MACZ,SAAS,CAAC,GAAG,OAAO,GAAG,UAAU,GAAG,aAAa;AAAA,IACnD;AAAA,IACA,KAAK;AAAA,MACH,YAAY,CAAC,cAAc;AAAA,IAC7B;AAAA,IACA,SAAS;AAAA,MACP,KAAK;AAAA,MACL,iBAAiB;AAAA,IACnB;AAAA,IACA,SAAS,CAAC,GAAI,WAAW,WAAW,CAAC,GAAI,WAAW,EAAC,SAAS,WAAU,CAAC,CAAC;AAAA,EAC5E,CAAC;AAED,QAAM,iBAAiB,OACrB,KACA,KACA,SACG;AACH,UAAM,MAAM,IAAI;AAChB,UAAM,SAAS,MAAM,WAAW,cAAc,gBAAgB;AAC9D,UAAM,WAAW,IAAI,OAAO,SAAS,UAAU;AAC/C,QAAI;AAEF,YAAM,WAAW,IAAI,kBAAkB,WAAW,WAAW;AAC7D,YAAM,OAAO,MAAM,SAAS,OAAO,KAAK;AAAA,QACtC;AAAA,MACF,CAAC;AAED,YAAM,OAAO,MAAM,WACjB,MAAM,WAAW,mBAAmB,KAAK,KAAK,QAAQ,EAAE,CAC1D;AAEA,UAAI,OAAO,GAAG,EAAE,IAAI,EAAC,gBAAgB,YAAW,CAAC,EAAE,IAAI,IAAI;AAAA,IAC7D,SAAS,GAAP;AAGA,iBAAW,iBAAiB,CAAC;AAC7B,UAAI;AACF,cAAM,EAAC,SAAQ,MAAM,SAAS,YAAY,CAAC;AAC3C,YAAI,OAAO,GAAG,EAAE,IAAI,EAAC,gBAAgB,YAAW,CAAC,EAAE,IAAI,IAAI;AAAA,MAC7D,SAAS,IAAP;AACA,gBAAQ,MAAM,+BAA+B;AAC7C,gBAAQ,MAAM,EAAE;AAChB,aAAK,CAAC;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,SAAO,CAAC,WAAW,aAAa,cAAc;AAChD;AAEO,aAAa,SAAkB;AACpC,eAAa,EAAC,QAAO,CAAC;AACxB;;;AM5HA;AACA;AACA;AACA;AACA;;;ACJA;AAcO,IAAM,gBAAN,MAAwC;AAAA,EAI7C,YAAY,UAAoB;AAC9B,SAAK,WAAW;AAChB,SAAK,kBAAkB,oBAAI,IAAI;AAC/B,WAAO,KAAK,KAAK,QAAQ,EAAE,QAAQ,CAAC,gBAAgB;AAClD,YAAM,WAAW,IAAI;AACrB,WAAK,gBAAgB,IACnB,UACA,IAAI,WAAW,MAAM,UAAU,KAAK,SAAS,YAAY,CAC3D;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,IAAI,UAAyC;AACjD,WAAO,KAAK,gBAAgB,IAAI,QAAQ,KAAK;AAAA,EAC/C;AAAA,EAEA,SAA6B;AAC3B,UAAM,SAA6B,CAAC;AACpC,eAAW,YAAY,KAAK,gBAAgB,KAAK,GAAG;AAClD,aAAO,YAAY,KAAK,gBAAgB,IAAI,QAAQ,EAAG,OAAO;AAAA,IAChE;AACA,WAAO;AAAA,EACT;AACF;AAEO,IAAM,aAAN,MAAiB;AAAA,EAQtB,YACE,UACA,UACA,cACA;AACA,SAAK,WAAW;AAChB,SAAK,WAAW;AAChB,SAAK,eAAe;AACpB,SAAK,WAAW,IAAI,aAAa;AACjC,SAAK,kBAAmB,MAAK,aAAa,WAAW,CAAC,GAAG,IACvD,CAAC,YAAY,IAAI,SACnB;AACA,SAAK,cAAe,MAAK,aAAa,OAAO,CAAC,GAAG,IAC/C,CAAC,YAAY,IAAI,SACnB;AAAA,EACF;AAAA,EAEA,MAAM,aAAgC;AACpC,UAAM,UAAU,oBAAI,IAAY;AAChC,UAAM,OAAO,oBAAI,IAAY;AAC7B,UAAM,KAAK,WAAW,MAAM,MAAM,OAAO;AACzC,WAAO,MAAM,KAAK,IAAI;AAAA,EACxB;AAAA,EAEA,MAAM,YAA+B;AACnC,UAAM,UAAU,oBAAI,IAAY;AAChC,UAAM,OAAO,oBAAI,IAAY;AAC7B,UAAM,KAAK,UAAU,MAAM,MAAM,OAAO;AACxC,WAAO,MAAM,KAAK,IAAI;AAAA,EACxB;AAAA,EAEA,MAAc,UACZ,OACA,MACA,SACA;AACA,QAAI,CAAC,OAAO;AACV;AAAA,IACF;AACA,QAAI,CAAC,MAAM,UAAU;AACnB;AAAA,IACF;AACA,QAAI,QAAQ,IAAI,MAAM,QAAQ,GAAG;AAC/B;AAAA,IACF;AACA,YAAQ,IAAI,MAAM,QAAQ;AAC1B,UAAM,QAAQ,MAAK,MAAM,MAAM,QAAQ;AACvC,QACE,CAAC,OAAO,QAAQ,OAAO,MAAM,EAAE,SAAS,MAAM,GAAG,KACjD,MAAM,SAAS,SAAS,YAAY,GACpC;AACA,WAAK,IAAI,MAAM,QAAQ;AAAA,IACzB;AACA,UAAM,QAAQ,IACZ,MAAM,gBAAgB,IAAI,OAAO,aAAa;AAC5C,YAAM,gBAAiB,MAAM,KAAK,SAAS,IAAI,QAAQ;AACvD,WAAK,UAAU,eAAe,MAAM,OAAO;AAAA,IAC7C,CAAC,CACH;AAAA,EACF;AAAA,EAEA,MAAc,WACZ,OACA,MACA,SACA;AACA,QAAI,CAAC,OAAO;AACV;AAAA,IACF;AACA,QAAI,CAAC,MAAM,UAAU;AACnB;AAAA,IACF;AACA,QAAI,QAAQ,IAAI,MAAM,QAAQ,GAAG;AAC/B;AAAA,IACF;AACA,YAAQ,IAAI,MAAM,QAAQ;AAC1B,QAAI,MAAM,aAAa;AACrB,YAAM,YAAY,QAAQ,CAAC,WAAW,KAAK,IAAI,MAAM,CAAC;AAAA,IACxD;AACA,UAAM,QAAQ,IACZ,MAAM,gBAAgB,IAAI,OAAO,aAAa;AAC5C,YAAM,gBAAiB,MAAM,KAAK,SAAS,IAAI,QAAQ;AACvD,WAAK,WAAW,eAAe,MAAM,OAAO;AAAA,IAC9C,CAAC,CACH;AAAA,EACF;AAAA,EAEA,SAAS;AACP,WAAO;AAAA,MACL,UAAU,KAAK;AAAA,MACf,UAAU,KAAK;AAAA,MACf,iBAAiB,KAAK;AAAA,MACtB,aAAa,KAAK;AAAA,IACpB;AAAA,EACF;AACF;;;AD9HA,IAAM,aAAY,MAAK,QAAQ,eAAc,YAAY,GAAG,CAAC;AAE7D,qBAA4B,SAAkB;AAC5C,UAAQ,IAAI,mBAAY;AAExB,MAAI,CAAC,SAAS;AACZ,cAAU,QAAQ,IAAI;AAAA,EACxB;AACA,QAAM,aAAa,MAAM,eAAe,OAAO;AAC/C,QAAM,UAAU,MAAK,KAAK,SAAS,MAAM;AACzC,QAAM,MAAM,OAAO;AACnB,QAAM,QAAQ,OAAO;AAErB,QAAM,QAAkB,CAAC;AACzB,MAAI,MAAM,YAAY,MAAK,KAAK,SAAS,QAAQ,CAAC,GAAG;AACnD,UAAM,YAAY,MAAM,MAAK,MAAK,KAAK,SAAS,aAAa,CAAC;AAC9D,cAAU,QAAQ,CAAC,SAAS;AAC1B,YAAM,QAAQ,MAAK,MAAM,IAAI;AAC7B,UAAI,CAAC,MAAM,KAAK,WAAW,GAAG,KAAK,SAAS,MAAM,IAAI,GAAG;AACvD,cAAM,KAAK,IAAI;AAAA,MACjB;AAAA,IACF,CAAC;AAAA,EACH;AAEA,QAAM,WAAqB,CAAC;AAC5B,MAAI,MAAM,YAAY,MAAK,KAAK,SAAS,UAAU,CAAC,GAAG;AACrD,UAAM,eAAe,MAAM,MAAK,MAAK,KAAK,SAAS,eAAe,CAAC;AACnE,iBAAa,QAAQ,CAAC,SAAS;AAC7B,YAAM,QAAQ,MAAK,MAAM,IAAI;AAC7B,UAAI,SAAS,MAAM,IAAI,GAAG;AACxB,iBAAS,KAAK,IAAI;AAAA,MACpB;AAAA,IACF,CAAC;AAAA,EACH;AAEA,QAAM,gBAA0B,CAAC;AACjC,MAAI,MAAM,YAAY,MAAK,KAAK,SAAS,SAAS,CAAC,GAAG;AACpD,UAAM,cAAc,MAAM,MAAK,MAAK,KAAK,SAAS,WAAW,CAAC;AAC9D,gBAAY,QAAQ,CAAC,SAAS;AAC5B,YAAM,QAAQ,MAAK,MAAM,IAAI;AAC7B,UAAI,SAAS,MAAM,IAAI,GAAG;AACxB,sBAAc,KAAK,IAAI;AAAA,MACzB;AAAA,IACF,CAAC;AAAA,EACH;AAEA,QAAM,aAAa,WAAW,QAAQ,CAAC;AACvC,QAAM,aAAyB;AAAA,IAC7B,GAAG;AAAA,IACH,MAAM;AAAA,IACN,SAAS;AAAA,MACP,KAAK;AAAA,MACL,iBAAiB;AAAA,MACjB,aAAa;AAAA,IACf;AAAA,IACA,SAAS,CAAC,GAAI,WAAW,WAAW,CAAC,GAAI,WAAW,EAAC,SAAS,WAAU,CAAC,CAAC;AAAA,EAC5E;AAIA,QAAM,UAAU;AAAA,IACd,GAAG;AAAA,IACH,MAAM;AAAA,IACN,WAAW;AAAA,IACX,OAAO;AAAA,MACL,eAAe;AAAA,QACb,OAAO,CAAC,MAAK,QAAQ,YAAW,aAAa,CAAC;AAAA,QAC9C,QAAQ;AAAA,UACN,QAAQ;AAAA,UACR,gBAAgB;AAAA,UAChB,gBAAgB;AAAA,QAClB;AAAA,MACF;AAAA,MACA,QAAQ,MAAK,KAAK,SAAS,QAAQ;AAAA,MACnC,KAAK;AAAA,MACL,aAAa;AAAA,MACb,cAAc;AAAA,MACd,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,uBAAuB;AAAA,MACvB,sBAAsB;AAAA,IACxB;AAAA,IACA,KAAK;AAAA,MACH,YAAY,CAAC,cAAc;AAAA,IAC7B;AAAA,EACF,CAAC;AAGD,QAAM,UAAU;AAAA,IACd,GAAG;AAAA,IACH,MAAM;AAAA,IACN,WAAW;AAAA,IACX,OAAO;AAAA,MACL,eAAe;AAAA,QACb,OAAO,CAAC,GAAG,OAAO,GAAG,UAAU,GAAG,aAAa;AAAA,QAC/C,QAAQ;AAAA,UACN,QAAQ;AAAA,UACR,gBAAgB;AAAA,UAChB,gBAAgB;AAAA,QAClB;AAAA,MACF;AAAA,MACA,QAAQ,MAAK,KAAK,SAAS,QAAQ;AAAA,MACnC,KAAK;AAAA,MACL,aAAa;AAAA,MACb,UAAU;AAAA,MACV,cAAc;AAAA,MACd,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,uBAAuB;AAAA,MACvB,sBAAsB;AAAA,IACxB;AAAA,EACF,CAAC;AAED,QAAM,WAAW,MAAM,SACrB,MAAK,KAAK,SAAS,sBAAsB,CAC3C;AAIA,QAAM,WAAW,IAAI,cAAc,QAAQ;AAG3C,YACE,MAAK,KAAK,SAAS,2BAA2B,GAC9C,KAAK,UAAU,SAAS,OAAO,GAAG,MAAM,CAAC,CAC3C;AAGA,QAAM,WAAW,MAAK,KAAK,SAAS,MAAM;AAG1C,QAAM,YAAY,MAAK,KAAK,SAAS,QAAQ;AAC7C,MAAI,SAAQ,WAAW,MAAK,KAAK,SAAS,QAAQ,CAAC,GAAG;AACpD,aAAQ,SAAS,WAAW,QAAQ;AAAA,EACtC,OAAO;AACL,YAAQ,QAAQ;AAAA,EAClB;AAGA,UAAQ,MAAK,KAAK,SAAS,eAAe,GAAG,MAAK,KAAK,UAAU,QAAQ,CAAC;AAC1E,UAAQ,MAAK,KAAK,SAAS,eAAe,GAAG,MAAK,KAAK,UAAU,QAAQ,CAAC;AAG1E,QAAM,SAAS,MAAM,OAAO,MAAK,KAAK,SAAS,kBAAkB;AACjE,QAAM,WAAW,IAAI,OAAO,SAAS,UAAU;AAC/C,QAAM,UAAU,MAAM,SAAS,WAAW;AAE1C,QAAM,QAAQ,IACZ,OAAO,KAAK,OAAO,EAAE,IAAI,OAAO,YAAY;AAC1C,UAAM,EAAC,OAAO,WAAU,QAAQ;AAChC,UAAM,OAAO,MAAM,SAAS,YAAY,OAAO;AAAA,MAC7C;AAAA,MACA,aAAa;AAAA,IACf,CAAC;AAID,QAAI,UAAU,MAAK,KAAK,SAAS,OAAO,WAAW,YAAY;AAE/D,QAAI,QAAQ,SAAS,gBAAgB,GAAG;AACtC,gBAAU,QAAQ,QAAQ,kBAAkB,UAAU;AAAA,IACxD;AAEA,UAAM,OAAO,MAAM,WAAW,KAAK,QAAQ,EAAE;AAC7C,UAAM,UAAU,SAAS,IAAI;AAE7B,UAAM,UAAU,QAAQ,MAAM,MAAK,QAAQ,OAAO,EAAE,SAAS,CAAC;AAC9D,YAAQ,IAAI,SAAS,SAAS;AAAA,EAChC,CAAC,CACH;AACF;;;AE9LA,uBAA8B;AAC5B,UAAQ,IAAI,sCAAsC;AACpD;","names":[]}
1
+ {"version":3,"sources":["../src/cli/commands/dev.ts","../src/render/vite-plugin-root.ts","../src/core/fsutils.ts","../src/render/asset-map/dev-asset-map.ts","../src/cli/load-config.ts","../src/render/html-minify.ts","../src/cli/commands/build.ts","../src/render/asset-map/build-asset-map.ts","../src/cli/commands/start.ts"],"sourcesContent":["import path from 'node:path';\nimport {fileURLToPath} from 'node:url';\nimport {default as express, Request, Response, NextFunction} from 'express';\nimport {createServer as createViteServer} from 'vite';\nimport {pluginRoot} from '../../render/vite-plugin-root.js';\nimport {DevServerAssetMap} from '../../render/asset-map/dev-asset-map.js';\nimport {loadRootConfig} from '../load-config.js';\nimport {htmlMinify} from '../../render/html-minify.js';\nimport {Renderer} from '../../render/render.js';\nimport {isDirectory, isJsFile} from '../../core/fsutils.js';\nimport glob from 'tiny-glob';\n\nconst __dirname = path.dirname(fileURLToPath(import.meta.url));\n\nexport async function createServer(options?: {rootDir?: string}) {\n const app = express();\n\n app.use(express.static('public'));\n const middlewares = await getMiddlewares({rootDir: options?.rootDir});\n middlewares.forEach((middleware) => app.use(middleware));\n\n const port = parseInt(process.env.PORT || '4007');\n console.log('🌳 Root.js');\n console.log();\n console.log(`Started server: http://localhost:${port}`);\n app.listen(port);\n}\n\nexport async function getMiddlewares(options?: {rootDir?: string}) {\n const rootDir = options?.rootDir || process.cwd();\n const rootConfig = await loadRootConfig(rootDir);\n const viteConfig = rootConfig.vite || {};\n const renderModulePath = path.resolve(__dirname, './render.js');\n\n const pages: string[] = [];\n if (await isDirectory(path.join(rootDir, 'routes'))) {\n const pageFiles = await glob(path.join(rootDir, 'routes/**/*'));\n pageFiles.forEach((file) => {\n const parts = path.parse(file);\n if (!parts.name.startsWith('_') && isJsFile(parts.base)) {\n pages.push(file);\n }\n });\n }\n\n const elements: string[] = [];\n if (await isDirectory(path.join(rootDir, 'elements'))) {\n const elementFiles = await glob(path.join(rootDir, 'elements/**/*'));\n elementFiles.forEach((file) => {\n const parts = path.parse(file);\n if (isJsFile(parts.base)) {\n elements.push(file);\n }\n });\n }\n\n const bundleScripts: string[] = [];\n if (await isDirectory(path.join(rootDir, 'bundles'))) {\n const bundleFiles = await glob(path.join(rootDir, 'bundles/*'));\n bundleFiles.forEach((file) => {\n const parts = path.parse(file);\n if (isJsFile(parts.base)) {\n bundleScripts.push(file);\n }\n });\n }\n\n const viteServer = await createViteServer({\n ...viteConfig,\n server: {middlewareMode: true},\n appType: 'custom',\n optimizeDeps: {\n include: [...pages, ...elements, ...bundleScripts],\n },\n ssr: {\n noExternal: ['@blinkk/root'],\n },\n esbuild: {\n jsx: 'automatic',\n jsxImportSource: 'preact',\n },\n plugins: [...(viteConfig.plugins || []), pluginRoot({rootDir, rootConfig})],\n });\n\n const rootMiddleware = async (\n req: Request,\n res: Response,\n next: NextFunction\n ) => {\n const url = req.originalUrl;\n const render = await viteServer.ssrLoadModule(renderModulePath);\n const renderer = new render.Renderer(rootConfig) as Renderer;\n try {\n // Create a dev asset map using Vite dev server's module graph.\n const assetMap = new DevServerAssetMap(viteServer.moduleGraph);\n const data = await renderer.render(url, {\n assetMap: assetMap,\n });\n // Inject the Vite HMR client.\n const html = await htmlMinify(\n await viteServer.transformIndexHtml(url, data.html || '')\n );\n\n res.status(200).set({'Content-Type': 'text/html'}).end(html);\n } catch (e) {\n // If an error is caught, let Vite fix the stack trace so it maps back to\n // your actual source code.\n viteServer.ssrFixStacktrace(e);\n try {\n const {html} = await renderer.renderError(e);\n res.status(500).set({'Content-Type': 'text/html'}).end(html);\n } catch (e2) {\n console.error('failed to render custom error');\n console.error(e2);\n next(e);\n }\n }\n };\n\n return [viteServer.middlewares, rootMiddleware];\n}\n\nexport function dev(rootDir?: string) {\n createServer({rootDir});\n}\n","import path from 'path';\nimport glob from 'tiny-glob';\nimport {RootConfig} from '../core/config';\nimport {isDirectory, isJsFile} from '../core/fsutils';\n\nconst JSX_ELEMENTS_REGEX = /jsxs?\\(\"(\\w[\\w-]+\\w)\"/g;\nconst HTML_ELEMENTS_REGEX = /<(\\w[\\w-]+\\w)/g;\n\nexport interface RootPluginOptions {\n rootDir: string;\n rootConfig: RootConfig;\n}\n\nexport function pluginRoot(options?: RootPluginOptions) {\n const elementsVirtualId = 'virtual:root-elements';\n const resolvedElementsVirtualId = '\\0' + elementsVirtualId;\n\n const rootDir = options?.rootDir || process.cwd();\n const rootConfig = options?.rootConfig || {};\n const elementsDirs = [path.join(rootDir, 'elements')];\n const includeDirs = rootConfig.elements?.include || [];\n includeDirs.forEach((dirPath) => {\n const elementsDir = path.resolve(rootDir, dirPath);\n if (!elementsDir.startsWith(rootDir)) {\n throw new Error(\n `the elements dir (${dirPath}) should be relative to the project's root dir (${rootDir})`\n );\n }\n elementsDirs.push(elementsDir);\n });\n\n let elementMap: Record<string, string>;\n async function updateElementMap() {\n elementMap = {};\n await Promise.all(\n elementsDirs.map(async (dirPath: string) => {\n const dirExists = await isDirectory(dirPath);\n if (!dirExists) {\n return;\n }\n const files = await glob('**/*', {cwd: dirPath});\n files.forEach((file) => {\n const parts = path.parse(file);\n if (isJsFile(parts.base)) {\n const fullPath = path.join(dirPath, file);\n const moduleId = fullPath.slice(rootDir.length);\n elementMap[parts.name] = moduleId;\n }\n });\n })\n );\n }\n\n async function getElementImport(tagname: string): Promise<string | null> {\n if (!elementMap) {\n await updateElementMap();\n }\n if (tagname in elementMap) {\n return elementMap[tagname];\n }\n return null;\n }\n\n function isCustomElement(id: string) {\n if (!isJsFile(id)) {\n return false;\n }\n return elementsDirs.some((elementsDir) => {\n return id.startsWith(elementsDir);\n });\n }\n\n return {\n name: 'vite-plugin-root',\n\n resolveId(id: string) {\n if (id === elementsVirtualId) {\n return resolvedElementsVirtualId;\n }\n return null;\n },\n\n async load(id: string) {\n if (id === resolvedElementsVirtualId) {\n await updateElementMap();\n return `export const elementsMap = ${JSON.stringify(elementMap)}`;\n }\n return null;\n },\n\n async transform(src: string, id: string): Promise<any> {\n if (isCustomElement(id)) {\n const idParts = path.parse(id);\n const deps = new Set<string>();\n const tagnames = [\n ...src.matchAll(JSX_ELEMENTS_REGEX),\n ...src.matchAll(HTML_ELEMENTS_REGEX),\n ];\n for (const match of tagnames) {\n const tagname = match[1];\n // All custom elements should contain a dash.\n if (!tagname.includes('-')) {\n continue;\n }\n // Avoid circular deps.\n if (tagname === idParts.name) {\n continue;\n }\n deps.add(tagname);\n }\n const importUrls: string[] = [];\n await Promise.all(\n Array.from(deps).map(async (tagname) => {\n const importUrl = await getElementImport(tagname);\n if (importUrl) {\n importUrls.push(importUrl);\n }\n })\n );\n if (importUrls.length > 0) {\n const importLines = importUrls\n .map((url) => `import '${url}';`)\n .join('\\n');\n const code = `${src}\n\n// autogenerated by root:\n${importLines}\n`;\n return {code};\n }\n return null;\n }\n return null;\n },\n };\n}\n","import {promises as fs} from 'node:fs';\nimport path from 'node:path';\nimport fsExtra from 'fs-extra';\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\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","import path from 'node:path';\nimport {ModuleGraph, ModuleNode} from 'vite';\nimport {Asset, AssetMap} from './asset-map';\n\nexport class DevServerAssetMap implements AssetMap {\n private moduleGraph: ModuleGraph;\n\n constructor(moduleGraph: ModuleGraph) {\n this.moduleGraph = moduleGraph;\n }\n\n async get(moduleId: string): Promise<Asset | null> {\n const viteModule = await this.moduleGraph.getModuleByUrl(moduleId);\n if (!viteModule || !viteModule.id) {\n return null;\n }\n return new DevServerAsset(this, viteModule);\n }\n}\n\nexport class DevServerAsset implements Asset {\n moduleId: string;\n assetUrl: string;\n private assetMap: AssetMap;\n private viteModule: ModuleNode;\n\n constructor(assetMap: AssetMap, viteModule: ModuleNode) {\n this.assetMap = assetMap;\n this.viteModule = viteModule;\n this.moduleId = this.viteModule.id!;\n this.assetUrl = this.viteModule.url;\n }\n\n async getCssDeps(): Promise<string[]> {\n const visited = new Set<string>();\n const deps = new Set<string>();\n this.collectCss(this, deps, visited);\n return Array.from(deps);\n }\n\n async getJsDeps(): Promise<string[]> {\n const visited = new Set<string>();\n const deps = new Set<string>();\n this.collectJs(this, deps, visited);\n return Array.from(deps);\n }\n\n getImportedModules() {\n return this.viteModule.importedModules;\n }\n\n private collectJs(\n asset: DevServerAsset | null,\n urls: Set<string>,\n visited: Set<string>\n ) {\n if (!asset) {\n return;\n }\n if (!asset.moduleId) {\n return;\n }\n if (visited.has(asset.moduleId)) {\n return;\n }\n visited.add(asset.moduleId);\n const parts = path.parse(asset.assetUrl);\n if (\n ['.js', '.jsx', '.ts', '.tsx'].includes(parts.ext) &&\n asset.moduleId.includes('/elements/')\n ) {\n urls.add(asset.assetUrl);\n }\n asset.getImportedModules().forEach((viteModule) => {\n if (viteModule.id) {\n const importedAsset = new DevServerAsset(this.assetMap, viteModule);\n this.collectJs(importedAsset, urls, visited);\n }\n });\n }\n\n private collectCss(\n asset: DevServerAsset | null,\n urls: Set<string>,\n visited: Set<string>\n ) {\n if (!asset) {\n return;\n }\n if (!asset.assetUrl) {\n return;\n }\n if (visited.has(asset.assetUrl)) {\n return;\n }\n visited.add(asset.assetUrl);\n if (asset.moduleId.endsWith('.scss')) {\n const parts = path.parse(asset.assetUrl);\n if (!parts.name.startsWith('_')) {\n urls.add(asset.assetUrl);\n }\n }\n asset.getImportedModules().forEach((viteModule) => {\n if (viteModule.id) {\n const importedAsset = new DevServerAsset(this.assetMap, viteModule);\n this.collectCss(importedAsset, urls, visited);\n }\n });\n }\n}\n","import {bundleRequire} from 'bundle-require';\nimport JoyCon from 'joycon';\nimport {RootConfig} from '../core/config';\n\nexport async function loadRootConfig(rootDir: string): Promise<RootConfig> {\n const joycon = new JoyCon();\n const configPath = await joycon.resolve({\n cwd: rootDir,\n files: ['root.config.ts'],\n });\n if (configPath) {\n const configBundle = await bundleRequire({\n filepath: configPath,\n });\n return configBundle.mod.default || {};\n }\n return {};\n}\n","import {minify} from 'html-minifier-terser';\n\nexport async function htmlMinify(html: string): Promise<string> {\n const min = await minify(html, {\n collapseWhitespace: true,\n removeComments: true,\n preserveLineBreaks: true,\n });\n return min.trimStart();\n}\n","import path from 'node:path';\nimport {fileURLToPath} from 'node:url';\nimport fsExtra from 'fs-extra';\nimport glob from 'tiny-glob';\nimport {build as viteBuild, Manifest, UserConfig} from 'vite';\nimport {pluginRoot} from '../../render/vite-plugin-root.js';\nimport {BuildAssetMap} from '../../render/asset-map/build-asset-map.js';\nimport {loadRootConfig} from '../load-config.js';\nimport {\n copyDir,\n isDirectory,\n isJsFile,\n loadJson,\n makeDir,\n rmDir,\n writeFile,\n} from '../../core/fsutils.js';\nimport {Renderer} from '../../render/render.js';\nimport {htmlMinify} from '../../render/html-minify.js';\n\nconst __dirname = path.dirname(fileURLToPath(import.meta.url));\n\nexport async function build(rootProjectDir?: string) {\n console.log('🌳 Root.js');\n\n const rootDir = rootProjectDir || process.cwd();\n const rootConfig = await loadRootConfig(rootDir);\n const distDir = path.join(rootDir, 'dist');\n await rmDir(distDir);\n await makeDir(distDir);\n\n const pages: string[] = [];\n if (await isDirectory(path.join(rootDir, 'routes'))) {\n const pageFiles = await glob(path.join(rootDir, 'routes/**/*'));\n pageFiles.forEach((file) => {\n const parts = path.parse(file);\n if (!parts.name.startsWith('_') && isJsFile(parts.base)) {\n pages.push(file);\n }\n });\n }\n\n const elementsDirs = [path.join(rootDir, 'elements')];\n const elementsInclude = rootConfig.elements?.include || [];\n for (const dirPath of elementsInclude) {\n const elementsDir = path.resolve(rootDir, dirPath);\n if (!elementsDir.startsWith(rootDir)) {\n throw new Error(\n `the elements dir (${dirPath}) should be relative to the project's root dir (${rootDir})`\n );\n }\n elementsDirs.push(elementsDir);\n }\n const elements: string[] = [];\n const elementMap: Record<string, string> = {};\n for (const dirPath of elementsDirs) {\n if (await isDirectory(dirPath)) {\n const elementFiles = await glob('**/*', {cwd: dirPath});\n elementFiles.forEach((file) => {\n const parts = path.parse(file);\n if (isJsFile(parts.base)) {\n const fullPath = path.join(dirPath, file);\n const moduleId = fullPath.slice(rootDir.length);\n elements.push(fullPath);\n elementMap[parts.name] = moduleId;\n }\n });\n }\n }\n\n const bundleScripts: string[] = [];\n if (await isDirectory(path.join(rootDir, 'bundles'))) {\n const bundleFiles = await glob(path.join(rootDir, 'bundles/*'));\n bundleFiles.forEach((file) => {\n const parts = path.parse(file);\n if (isJsFile(parts.base)) {\n bundleScripts.push(file);\n }\n });\n }\n\n const viteConfig = rootConfig.vite || {};\n const baseConfig: UserConfig = {\n ...viteConfig,\n root: rootDir,\n esbuild: {\n jsx: 'automatic',\n jsxImportSource: 'preact',\n treeShaking: true,\n },\n plugins: [...(viteConfig.plugins || []), pluginRoot({rootDir, rootConfig})],\n };\n\n // Bundle the render.js file with vite, which is pre-optimized for rendering\n // HTML routes.\n await viteBuild({\n ...baseConfig,\n mode: 'production',\n publicDir: false,\n build: {\n rollupOptions: {\n input: [path.resolve(__dirname, './render.js')],\n output: {\n format: 'esm',\n chunkFileNames: 'chunks/[name].[hash].js',\n assetFileNames: 'assets/[name].[hash][extname]',\n },\n },\n outDir: path.join(distDir, 'server'),\n ssr: true,\n ssrManifest: false,\n cssCodeSplit: true,\n target: 'esnext',\n minify: false,\n polyfillModulePreload: false,\n reportCompressedSize: false,\n },\n ssr: {\n noExternal: ['@blinkk/root'],\n },\n });\n\n // Pre-render any client scripts and CSS deps.\n await viteBuild({\n ...baseConfig,\n mode: 'production',\n publicDir: false,\n build: {\n rollupOptions: {\n input: [...pages, ...elements, ...bundleScripts],\n output: {\n format: 'esm',\n chunkFileNames: 'chunks/[name].[hash].js',\n assetFileNames: 'assets/[name].[hash][extname]',\n },\n },\n outDir: path.join(distDir, 'client'),\n ssr: false,\n ssrManifest: false,\n manifest: true,\n cssCodeSplit: true,\n target: 'esnext',\n minify: true,\n polyfillModulePreload: false,\n reportCompressedSize: false,\n },\n });\n\n const manifest = await loadJson<Manifest>(\n path.join(distDir, 'client/manifest.json')\n );\n\n // Use the output of the client build to generate an asset map, which is used\n // by the renderer for automatically injecting dependencies for a page.\n const assetMap = new BuildAssetMap(manifest, {elementMap});\n\n // Save the asset map to `dist/client` for use by the prod SSR server.\n writeFile(\n path.join(distDir, 'client/root-manifest.json'),\n JSON.stringify(assetMap.toJson(), null, 2)\n );\n\n // Write SSG output to `dist/html`.\n const buildDir = path.join(distDir, 'html');\n\n // Recursively copy files from `public` to `dist/html`.\n const publicDir = path.join(rootDir, 'public');\n if (fsExtra.existsSync(path.join(rootDir, 'public'))) {\n fsExtra.copySync(publicDir, buildDir);\n } else {\n makeDir(buildDir);\n }\n\n // Copy files from `dist/client/{assets,chunks}` to `dist/html`.\n copyDir(path.join(distDir, 'client/assets'), path.join(buildDir, 'assets'));\n copyDir(path.join(distDir, 'client/chunks'), path.join(buildDir, 'chunks'));\n\n // Render HTML pages.\n const render = await import(path.join(distDir, 'server/render.js'));\n const renderer = new render.Renderer(rootConfig) as Renderer;\n const sitemap = await renderer.getSitemap();\n\n await Promise.all(\n Object.keys(sitemap).map(async (urlPath) => {\n const {route, params} = sitemap[urlPath];\n const data = await renderer.renderRoute(route, {\n assetMap,\n routeParams: params,\n });\n\n // The renderer currently assumes that all paths serve HTML.\n // TODO(stevenle): support non-HTML routes using `routes/[name].[ext].ts`.\n let outPath = path.join(distDir, `html${urlPath}`, 'index.html');\n\n if (outPath.endsWith('404/index.html')) {\n outPath = outPath.replace('404/index.html', '404.html');\n }\n\n const html = await htmlMinify(data.html || '');\n await writeFile(outPath, html);\n\n const relPath = outPath.slice(path.dirname(distDir).length + 1);\n console.log(`saved ${relPath}`);\n })\n );\n}\n","import path from 'path';\nimport {Manifest, ManifestChunk} from 'vite';\nimport {Asset, AssetMap} from './asset-map';\n\ntype BuildAssetManifest = Record<\n string,\n {\n moduleId: string;\n assetUrl: string;\n importedModules: string[];\n importedCss: string[];\n }\n>;\n\nexport class BuildAssetMap implements AssetMap {\n private manifest: Manifest;\n private moduleIdToAsset: Map<string, BuildAsset>;\n private elementMap: Record<string, string>;\n\n constructor(\n manifest: Manifest,\n options: {elementMap: Record<string, string>}\n ) {\n this.manifest = manifest;\n this.elementMap = options.elementMap;\n this.moduleIdToAsset = new Map();\n Object.keys(this.manifest).forEach((manifestKey) => {\n const moduleId = `/${manifestKey}`;\n this.moduleIdToAsset.set(\n moduleId,\n new BuildAsset(this, moduleId, this.manifest[manifestKey])\n );\n });\n }\n\n async get(moduleId: string): Promise<Asset | null> {\n return this.moduleIdToAsset.get(moduleId) || null;\n }\n\n isElement(moduleId: string): boolean {\n return Object.values(this.elementMap).includes(moduleId);\n }\n\n toJson(): BuildAssetManifest {\n const result: BuildAssetManifest = {};\n for (const moduleId of this.moduleIdToAsset.keys()) {\n result[moduleId] = this.moduleIdToAsset.get(moduleId)!.toJson();\n }\n return result;\n }\n}\n\nexport class BuildAsset {\n moduleId: string;\n assetUrl: string;\n private assetMap: BuildAssetMap;\n private manifestData: ManifestChunk;\n private importedModules: string[];\n private importedCss: string[];\n\n constructor(\n assetMap: BuildAssetMap,\n moduleId: string,\n manifestData: ManifestChunk\n ) {\n this.assetMap = assetMap;\n this.moduleId = moduleId;\n this.manifestData = manifestData;\n this.assetUrl = `/${manifestData.file}`;\n this.importedModules = (this.manifestData.imports || []).map(\n (relPath) => `/${relPath}`\n );\n this.importedCss = (this.manifestData.css || []).map(\n (relPath) => `/${relPath}`\n );\n }\n\n async getCssDeps(): Promise<string[]> {\n const visited = new Set<string>();\n const deps = new Set<string>();\n await this.collectCss(this, deps, visited);\n return Array.from(deps);\n }\n\n async getJsDeps(): Promise<string[]> {\n const visited = new Set<string>();\n const deps = new Set<string>();\n await this.collectJs(this, deps, visited);\n return Array.from(deps);\n }\n\n private async collectJs(\n asset: BuildAsset | null,\n urls: Set<string>,\n visited: Set<string>\n ) {\n if (!asset) {\n return;\n }\n if (!asset.moduleId) {\n return;\n }\n if (visited.has(asset.moduleId)) {\n return;\n }\n visited.add(asset.moduleId);\n const parts = path.parse(asset.assetUrl);\n if (\n ['.js', '.jsx', '.ts', '.tsx'].includes(parts.ext) &&\n this.assetMap.isElement(asset.moduleId)\n ) {\n urls.add(asset.assetUrl);\n }\n await Promise.all(\n asset.importedModules.map(async (moduleId) => {\n const importedAsset = (await this.assetMap.get(moduleId)) as BuildAsset;\n this.collectJs(importedAsset, urls, visited);\n })\n );\n }\n\n private async collectCss(\n asset: BuildAsset | null,\n urls: Set<string>,\n visited: Set<string>\n ) {\n if (!asset) {\n return;\n }\n if (!asset.assetUrl) {\n return;\n }\n if (visited.has(asset.moduleId)) {\n return;\n }\n visited.add(asset.moduleId);\n if (asset.importedCss) {\n asset.importedCss.forEach((cssUrl) => urls.add(cssUrl));\n }\n await Promise.all(\n asset.importedModules.map(async (moduleId) => {\n const importedAsset = (await this.assetMap.get(moduleId)) as BuildAsset;\n this.collectCss(importedAsset, urls, visited);\n })\n );\n }\n\n toJson() {\n return {\n moduleId: this.moduleId,\n assetUrl: this.assetUrl,\n importedModules: this.importedModules,\n importedCss: this.importedCss,\n };\n }\n}\n","export async function start() {\n console.log('SSR production server is coming soon');\n}\n"],"mappings":"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","names":[]}
package/dist/core.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as preact from 'preact';
2
2
  import { h, ComponentChildren } from 'preact';
3
- export { b as GetStaticPaths, G as GetStaticProps, R as RootConfig, a as RootI18nConfig, d as defineConfig } from './types-d6c0705e.js';
3
+ export { b as GetStaticPaths, G as GetStaticProps, R as RootConfig, a as RootI18nConfig, d as defineConfig } from './types-07f4e3d2.js';
4
4
  import 'vite';
5
5
 
6
6
  interface ErrorPageProps {
package/dist/core.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/core/config.ts"],"sourcesContent":["import {UserConfig as ViteUserConfig} from 'vite';\n\nexport interface RootConfig {\n i18n?: RootI18nConfig;\n vite?: ViteUserConfig;\n sitemap?: boolean;\n}\n\nexport interface RootI18nConfig {\n locales?: string[];\n defaultLocale?: string;\n urlFormat?: string;\n}\n\nexport function defineConfig(config: RootConfig): RootConfig {\n return config;\n}\n"],"mappings":";;;;;;;;;;;;AAcO,sBAAsB,QAAgC;AAC3D,SAAO;AACT;","names":[]}
1
+ {"version":3,"sources":["../src/core/config.ts"],"sourcesContent":["import {UserConfig as ViteUserConfig} from 'vite';\n\nexport interface RootConfig {\n /**\n * Configuration for auto-injecting custom element dependencies.\n */\n elements?: {\n /**\n * A list of directories to use to look for custom elements. The dir path\n * should be relative to the project dir, e.g. \"path/to/elements\" or\n * \"node_modules/my-package\".\n */\n include?: string[];\n };\n\n /**\n * Configuration options for localization and internationalization.\n */\n i18n?: RootI18nConfig;\n\n /**\n * Vite configuration.\n * @see {@link https://vitejs.dev/config/} for more information.\n */\n vite?: ViteUserConfig;\n\n /**\n * Whether to include a sitemap.xml file to the build output.\n */\n sitemap?: boolean;\n}\n\nexport interface RootI18nConfig {\n /**\n * Locales enabled for the site.\n */\n locales?: string[];\n\n /**\n * The default locale to use. Defaults is `en`.\n */\n defaultLocale?: string;\n\n /**\n * URL format for localized content. Default is `/{locale}/{path}`.\n */\n urlFormat?: string;\n}\n\nexport function defineConfig(config: RootConfig): RootConfig {\n return config;\n}\n"],"mappings":";;;;;;;;;;;;AAiDO,sBAAsB,QAAgC;AAC3D,SAAO;AACT;","names":[]}
package/dist/render.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { ComponentType } from 'preact';
2
- import { b as GetStaticPaths, G as GetStaticProps, R as RootConfig } from './types-d6c0705e.js';
2
+ import { b as GetStaticPaths, G as GetStaticProps, R as RootConfig } from './types-07f4e3d2.js';
3
3
  import 'vite';
4
4
 
5
5
  interface RouteModule {
package/dist/render.js CHANGED
@@ -7,7 +7,6 @@ import {
7
7
  } from "./chunk-CDPH3RKE.js";
8
8
 
9
9
  // src/render/render.tsx
10
- import path2 from "node:path";
11
10
  import { h } from "preact";
12
11
  import renderToString from "preact-render-to-string";
13
12
 
@@ -19,13 +18,13 @@ var RouteTrie = class {
19
18
  constructor() {
20
19
  this.children = {};
21
20
  }
22
- add(path3, route) {
23
- path3 = this.normalizePath(path3);
24
- if (path3 === "") {
21
+ add(path2, route) {
22
+ path2 = this.normalizePath(path2);
23
+ if (path2 === "") {
25
24
  this.route = route;
26
25
  return;
27
26
  }
28
- const [head, tail] = this.splitPath(path3);
27
+ const [head, tail] = this.splitPath(path2);
29
28
  if (head.startsWith("[...") && head.endsWith("]")) {
30
29
  const paramName = head.slice(4, -1);
31
30
  this.wildcardChild = new WildcardChild(paramName, route);
@@ -47,9 +46,9 @@ var RouteTrie = class {
47
46
  }
48
47
  nextNode.add(tail, route);
49
48
  }
50
- get(path3) {
49
+ get(path2) {
51
50
  const params = {};
52
- const route = this.getRoute(path3, params);
51
+ const route = this.getRoute(path2, params);
53
52
  return [route, params];
54
53
  }
55
54
  walk(cb) {
@@ -114,15 +113,15 @@ var RouteTrie = class {
114
113
  }
115
114
  return void 0;
116
115
  }
117
- normalizePath(path3) {
118
- return path3.replace(/^\/+/g, "");
116
+ normalizePath(path2) {
117
+ return path2.replace(/^\/+/g, "");
119
118
  }
120
- splitPath(path3) {
121
- const i = path3.indexOf("/");
119
+ splitPath(path2) {
120
+ const i = path2.indexOf("/");
122
121
  if (i === -1) {
123
- return [path3, ""];
122
+ return [path2, ""];
124
123
  }
125
- return [path3.slice(0, i), path3.slice(i + 1)];
124
+ return [path2.slice(0, i), path2.slice(i + 1)];
126
125
  }
127
126
  };
128
127
  var ParamChild = class {
@@ -205,15 +204,7 @@ function replaceParams(urlPathFormat, params) {
205
204
  }
206
205
 
207
206
  // src/render/render.tsx
208
- var ELEMENTS_MAP = {};
209
- var ELEMENTS_MODULES = import.meta.glob([
210
- "/elements/**/*.ts",
211
- "/elements/**/*.tsx"
212
- ]);
213
- Object.keys(ELEMENTS_MODULES).forEach((elementPath) => {
214
- const parts = path2.parse(elementPath);
215
- ELEMENTS_MAP[parts.name] = elementPath;
216
- });
207
+ import { elementsMap } from "virtual:root-elements";
217
208
  var Renderer = class {
218
209
  constructor(config) {
219
210
  this.routes = getRoutes(config);
@@ -336,14 +327,16 @@ ${renderToString(page, {}, { pretty: true })}
336
327
  const matches = Array.from(html.matchAll(re));
337
328
  await Promise.all(matches.map(async (match) => {
338
329
  const tagName = match[1];
339
- if (tagName && tagName.includes("-") && tagName in ELEMENTS_MAP) {
340
- const modulePath = ELEMENTS_MAP[tagName];
330
+ if (tagName && tagName.includes("-") && tagName in elementsMap) {
331
+ const modulePath = elementsMap[tagName];
341
332
  const asset = await assetMap.get(modulePath);
342
333
  if (!asset) {
343
334
  return;
344
335
  }
345
336
  const assetJsDeps = await asset.getJsDeps();
346
337
  assetJsDeps.forEach((dep) => deps.add(dep));
338
+ } else {
339
+ console.log(`could not find tag name: ${tagName}`);
347
340
  }
348
341
  }));
349
342
  return Array.from(deps);
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/render/render.tsx","../src/render/router.ts","../src/render/route-trie.ts"],"sourcesContent":["import path from 'node:path';\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nimport {h, ComponentChildren} from 'preact';\nimport renderToString from 'preact-render-to-string';\nimport {getRoutes, RouteModule, Route, getAllPathsForRoute} from './router';\nimport {HEAD_CONTEXT} from '../core/components/head';\nimport {ErrorPage} from '../core/components/error-page';\nimport {getTranslations, I18N_CONTEXT} from '../core/i18n';\nimport {ScriptProps, SCRIPT_CONTEXT} from '../core/components/script';\nimport {AssetMap} from './asset-map/asset-map';\nimport {RootConfig} from '../core/config';\nimport {RouteTrie} from './route-trie';\n\n// TODO(stevenle): this should be added via config.\nconst ELEMENTS_MAP: Record<string, string> = {};\nconst ELEMENTS_MODULES = import.meta.glob([\n '/elements/**/*.ts',\n '/elements/**/*.tsx',\n]) as Record<string, () => Promise<RouteModule>>;\nObject.keys(ELEMENTS_MODULES).forEach((elementPath) => {\n const parts = path.parse(elementPath);\n ELEMENTS_MAP[parts.name] = elementPath;\n});\n\ninterface RenderOptions {\n assetMap: AssetMap;\n}\n\ninterface RenderHtmlOptions {\n mainHtml: string;\n locale: string;\n headComponents?: ComponentChildren[];\n}\n\nexport class Renderer {\n private routes: RouteTrie<Route>;\n\n constructor(config: RootConfig) {\n this.routes = getRoutes(config);\n }\n\n async render(\n url: string,\n options: RenderOptions\n ): Promise<{html: string; notFound?: boolean}> {\n const assetMap = options.assetMap;\n const [route, routeParams] = this.routes.get(url);\n if (route && route.module && route.module.default) {\n return await this.renderRoute(route, {routeParams, assetMap});\n }\n return this.render404();\n }\n\n async renderRoute(\n route: Route,\n options: {routeParams: Record<string, string>; assetMap: AssetMap}\n ): Promise<{html: string; notFound?: boolean}> {\n const routeParams = options.routeParams;\n const assetMap = options.assetMap;\n const Component = route.module.default;\n if (!Component) {\n throw new Error(\n 'unable to render route. the route should have a default export that renders a jsx component.'\n );\n }\n let props = {};\n if (route.module.getStaticProps) {\n const propsData = await route.module.getStaticProps({\n params: routeParams,\n });\n if (propsData.notFound) {\n return this.render404();\n }\n if (propsData.props) {\n props = propsData.props;\n }\n }\n\n const locale = route.locale;\n const translations = getTranslations(locale);\n\n const headComponents: ComponentChildren[] = [];\n const userScripts: ScriptProps[] = [];\n const vdom = (\n <I18N_CONTEXT.Provider value={{locale, translations}}>\n <SCRIPT_CONTEXT.Provider value={userScripts}>\n <HEAD_CONTEXT.Provider value={headComponents}>\n <Component {...props} />\n </HEAD_CONTEXT.Provider>\n </SCRIPT_CONTEXT.Provider>\n </I18N_CONTEXT.Provider>\n );\n const mainHtml = renderToString(vdom, {}, {pretty: true});\n\n // Walk the page's dependency tree for CSS dependencies that are added via\n // `import 'foo.scss'` or `import 'foo.module.scss'`.\n const pageAsset = await assetMap.get(route.modulePath);\n const cssDeps = await pageAsset?.getCssDeps();\n if (cssDeps) {\n cssDeps.forEach((cssUrl) => {\n headComponents.push(<link rel=\"stylesheet\" href={cssUrl} />);\n });\n }\n\n // Parse the HTML for custom elements that are found within the project\n // and automatically inject the script deps for them.\n const scriptDeps = await this.getScriptDeps(mainHtml, {assetMap});\n scriptDeps.forEach((jsUrls) => {\n headComponents.push(<script type=\"module\" src={jsUrls} />);\n });\n\n // Add user defined scripts added via the `<Script>` component.\n await Promise.all(\n userScripts.map(async (scriptDep) => {\n const scriptAsset = await assetMap.get(scriptDep.src);\n if (!scriptAsset && import.meta.env.PROD) {\n console.log(`could not find precompiled asset: ${scriptDep.src}`);\n }\n const scriptUrl = scriptAsset ? scriptAsset.assetUrl : scriptDep.src;\n headComponents.push(<script type=\"module\" src={scriptUrl} />);\n })\n );\n\n const html = await this.renderHtml({mainHtml, locale, headComponents});\n return {html};\n }\n\n async getSitemap(): Promise<\n Record<string, {route: Route; params: Record<string, string>}>\n > {\n const sitemap: Record<\n string,\n {route: Route; params: Record<string, string>}\n > = {};\n await this.routes.walk(async (urlPath: string, route: Route) => {\n const routePaths = await getAllPathsForRoute(urlPath, route);\n routePaths.forEach((routePath) => {\n sitemap[routePath.urlPath] = {\n route,\n params: routePath.params,\n };\n });\n });\n return sitemap;\n }\n\n private async renderHtml(options: RenderHtmlOptions) {\n const page = (\n <html lang={options.locale}>\n <head>\n <meta charSet=\"utf-8\" />\n {options.headComponents}\n </head>\n <body dangerouslySetInnerHTML={{__html: options.mainHtml}} />\n </html>\n );\n const html = `<!doctype html>\\n${renderToString(\n page,\n {},\n {pretty: true}\n )}\\n`;\n return html;\n }\n\n async render404() {\n return {\n html: '<!doctype html><html><title>404 Not Found</title><h1>404 Not Found</h1>',\n notFound: true,\n };\n }\n\n async renderError(error: unknown) {\n const mainHtml = renderToString(<ErrorPage error={error} />);\n const html = await this.renderHtml({mainHtml, locale: 'en'});\n return {html};\n }\n\n private async getScriptDeps(\n html: string,\n options: {assetMap: AssetMap}\n ): Promise<string[]> {\n const assetMap = options.assetMap as AssetMap;\n const deps = new Set<string>();\n\n const re = /<(\\w[\\w-]+\\w)/g;\n const matches = Array.from(html.matchAll(re));\n await Promise.all(\n matches.map(async (match) => {\n const tagName = match[1];\n // Custom elements require a dash.\n if (tagName && tagName.includes('-') && tagName in ELEMENTS_MAP) {\n const modulePath = ELEMENTS_MAP[tagName];\n const asset = await assetMap.get(modulePath);\n if (!asset) {\n return;\n }\n const assetJsDeps = await asset.getJsDeps();\n assetJsDeps.forEach((dep) => deps.add(dep));\n }\n })\n );\n\n return Array.from(deps);\n }\n}\n","import path from 'node:path';\nimport {ComponentType} from 'preact';\nimport {RootConfig} from '../core/config';\nimport {GetStaticPaths, GetStaticProps} from '../core/types';\nimport {RouteTrie} from './route-trie';\n\nexport interface RouteModule {\n default?: ComponentType<unknown>;\n getStaticPaths?: GetStaticPaths;\n getStaticProps?: GetStaticProps;\n}\n\nexport interface Route {\n modulePath: string;\n module: RouteModule;\n locale: string;\n}\n\nexport function getRoutes(config: RootConfig) {\n const locales = config.i18n?.locales || [];\n const i18nUrlFormat = config.i18n?.urlFormat || '/{locale}/{path}';\n const defaultLocale = config.i18n?.defaultLocale || 'en';\n\n const routes = import.meta.glob(\n ['/routes/*.ts', '/routes/**/*.ts', '/routes/*.tsx', '/routes/**/*.tsx'],\n {\n eager: true,\n }\n );\n const trie = new RouteTrie<Route>();\n Object.keys(routes).forEach((filePath) => {\n let routePath = filePath.replace(/^\\/routes/, '');\n const parts = path.parse(routePath);\n if (parts.name.startsWith('_')) {\n return;\n }\n if (parts.name === 'index') {\n routePath = parts.dir;\n } else {\n routePath = path.join(parts.dir, parts.name);\n }\n trie.add(routePath, {\n modulePath: filePath,\n module: routes[filePath] as RouteModule,\n locale: defaultLocale,\n });\n\n // At the moment, all routes are assumed to use the site-wide i18n config.\n // TODO(stevenle): provide routes with a way to override the default\n // i18n serving behavior.\n locales.forEach((locale) => {\n const localeRoutePath = i18nUrlFormat\n .replace('{locale}', locale)\n .replace('{path}', routePath.replace(/^\\/*/, ''));\n if (localeRoutePath !== routePath) {\n trie.add(localeRoutePath, {\n modulePath: filePath,\n module: routes[filePath] as RouteModule,\n locale: locale,\n });\n }\n });\n });\n return trie;\n}\n\nexport async function getAllPathsForRoute(\n urlPathFormat: string,\n route: Route\n): Promise<Array<{urlPath: string; params: Record<string, string>}>> {\n const urlPaths: Array<{urlPath: string; params: Record<string, string>}> = [];\n const routeModule = route.module;\n if (routeModule.getStaticPaths) {\n const staticPaths = await routeModule.getStaticPaths();\n staticPaths.paths.forEach(\n (pathParams: {params: Record<string, string>}) => {\n urlPaths.push({\n urlPath: replaceParams(urlPathFormat, pathParams.params),\n params: pathParams.params || {},\n });\n }\n );\n } else {\n urlPaths.push({urlPath: urlPathFormat, params: {}});\n }\n return urlPaths;\n}\n\nexport function replaceParams(\n urlPathFormat: string,\n params: Record<string, string>\n) {\n const urlPath = urlPathFormat.replaceAll(\n /\\[(\\.\\.\\.)?([\\w\\-_]*)\\]/g,\n (match: string, _wildcard: string, key: string) => {\n const val = params[key];\n if (!val) {\n throw new Error(`unreplaced param ${match} in url: ${urlPathFormat}`);\n }\n return val;\n }\n );\n return urlPath;\n}\n","/**\n * A trie data structure that stores routes. The trie supports `:param` and\n * `*wildcard` values.\n */\nexport class RouteTrie<T> {\n private children: Record<string, RouteTrie<T>> = {};\n private paramChild?: ParamChild<T>;\n private wildcardChild?: WildcardChild<T>;\n private route?: T;\n\n /**\n * Adds a route to the trie.\n */\n add(path: string, route: T) {\n path = this.normalizePath(path);\n\n // If the end was reached, save the value to the node.\n if (path === '') {\n this.route = route;\n return;\n }\n\n const [head, tail] = this.splitPath(path);\n if (head.startsWith('[...') && head.endsWith(']')) {\n const paramName = head.slice(4, -1);\n this.wildcardChild = new WildcardChild(paramName, route);\n return;\n }\n\n let nextNode: RouteTrie<T>;\n if (head.startsWith('[') && head.endsWith(']')) {\n if (!this.paramChild) {\n const paramName = head.slice(1, -1);\n this.paramChild = new ParamChild(paramName);\n }\n nextNode = this.paramChild.trie;\n } else {\n nextNode = this.children[head];\n if (!nextNode) {\n nextNode = new RouteTrie();\n this.children[head] = nextNode;\n }\n }\n nextNode.add(tail, route);\n }\n\n /**\n * Returns a route mapped to the given path and any parameter values from the\n * URL.\n */\n get(path: string): [T | undefined, Record<string, string>] {\n const params = {};\n const route = this.getRoute(path, params);\n return [route, params];\n }\n\n /**\n * Walks the route trie and calls a callback function for each route.\n */\n walk(cb: (urlPath: string, route: T) => Promise<void> | void): Promise<void> {\n const promises: Array<Promise<void>> = [];\n const addPromise = (promise: Promise<void> | void) => {\n if (promise) {\n promises.push(promise);\n }\n };\n if (this.route) {\n addPromise(cb('/', this.route));\n }\n if (this.paramChild) {\n const param = `[${this.paramChild.name}]`;\n this.paramChild.trie.walk((childPath: string, route: T) => {\n const paramUrlPath = `/${param}${childPath}`;\n addPromise(cb(paramUrlPath, route));\n });\n }\n if (this.wildcardChild) {\n const wildcardUrlPath = `/[...${this.wildcardChild.name}]`;\n addPromise(cb(wildcardUrlPath, this.wildcardChild.route));\n }\n for (const subpath of Object.keys(this.children)) {\n const childTrie = this.children[subpath];\n childTrie.walk((childPath: string, childRoute: T) => {\n addPromise(cb(`/${subpath}${childPath}`, childRoute));\n });\n }\n return Promise.all(promises).then(() => {});\n }\n\n /**\n * Removes all routes from the trie.\n */\n clear() {\n this.children = {};\n this.paramChild = undefined;\n this.wildcardChild = undefined;\n this.route = undefined;\n }\n\n private getRoute(\n urlPath: string,\n params: Record<string, string>\n ): T | undefined {\n urlPath = this.normalizePath(urlPath);\n if (urlPath === '') {\n return this.route;\n }\n\n const [head, tail] = this.splitPath(urlPath);\n\n const child = this.children[head];\n if (child) {\n const route = child.getRoute(tail, params);\n if (route) {\n return route;\n }\n }\n\n if (this.paramChild) {\n const route = this.paramChild.trie.getRoute(tail, params);\n if (route) {\n params[this.paramChild.name] = head;\n return route;\n }\n }\n\n if (this.wildcardChild) {\n params[this.wildcardChild.name] = urlPath;\n return this.wildcardChild.route;\n }\n\n return undefined;\n }\n\n /**\n * Normalizes a path for inclusion into the route trie.\n */\n private normalizePath(path: string) {\n // Remove leading slashes.\n return path.replace(/^\\/+/g, '');\n }\n\n /**\n * Splits the parent directory from its children, e.g.:\n *\n * splitPath(\"foo/bar/baz\") -> [\"foo\", \"bar/baz\"]\n */\n private splitPath(path: string): [string, string] {\n const i = path.indexOf('/');\n if (i === -1) {\n return [path, ''];\n }\n return [path.slice(0, i), path.slice(i + 1)];\n }\n}\n\n/**\n * A node in the RouteTrie for a :param child.\n */\nclass ParamChild<T> {\n readonly name: string;\n readonly trie: RouteTrie<T> = new RouteTrie();\n\n constructor(name: string) {\n this.name = name;\n }\n}\n\n/**\n * A node in the RouteTrie for a *wildcard child.\n */\nclass WildcardChild<T> {\n readonly name: string;\n readonly route: T;\n\n constructor(name: string, route: T) {\n this.name = name;\n this.route = route;\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/render/render.tsx","../src/render/router.ts","../src/render/route-trie.ts"],"sourcesContent":["// eslint-disable-next-line @typescript-eslint/no-unused-vars\nimport {h, ComponentChildren} from 'preact';\nimport renderToString from 'preact-render-to-string';\nimport {getRoutes, Route, getAllPathsForRoute} from './router';\nimport {HEAD_CONTEXT} from '../core/components/head';\nimport {ErrorPage} from '../core/components/error-page';\nimport {getTranslations, I18N_CONTEXT} from '../core/i18n';\nimport {ScriptProps, SCRIPT_CONTEXT} from '../core/components/script';\nimport {AssetMap} from './asset-map/asset-map';\nimport {RootConfig} from '../core/config';\nimport {RouteTrie} from './route-trie';\nimport {elementsMap} from 'virtual:root-elements';\n\ninterface RenderOptions {\n assetMap: AssetMap;\n}\n\ninterface RenderHtmlOptions {\n mainHtml: string;\n locale: string;\n headComponents?: ComponentChildren[];\n}\n\nexport class Renderer {\n private routes: RouteTrie<Route>;\n\n constructor(config: RootConfig) {\n this.routes = getRoutes(config);\n }\n\n async render(\n url: string,\n options: RenderOptions\n ): Promise<{html: string; notFound?: boolean}> {\n const assetMap = options.assetMap;\n const [route, routeParams] = this.routes.get(url);\n if (route && route.module && route.module.default) {\n return await this.renderRoute(route, {routeParams, assetMap});\n }\n return this.render404();\n }\n\n async renderRoute(\n route: Route,\n options: {routeParams: Record<string, string>; assetMap: AssetMap}\n ): Promise<{html: string; notFound?: boolean}> {\n const routeParams = options.routeParams;\n const assetMap = options.assetMap;\n const Component = route.module.default;\n if (!Component) {\n throw new Error(\n 'unable to render route. the route should have a default export that renders a jsx component.'\n );\n }\n let props = {};\n if (route.module.getStaticProps) {\n const propsData = await route.module.getStaticProps({\n params: routeParams,\n });\n if (propsData.notFound) {\n return this.render404();\n }\n if (propsData.props) {\n props = propsData.props;\n }\n }\n\n const locale = route.locale;\n const translations = getTranslations(locale);\n\n const headComponents: ComponentChildren[] = [];\n const userScripts: ScriptProps[] = [];\n const vdom = (\n <I18N_CONTEXT.Provider value={{locale, translations}}>\n <SCRIPT_CONTEXT.Provider value={userScripts}>\n <HEAD_CONTEXT.Provider value={headComponents}>\n <Component {...props} />\n </HEAD_CONTEXT.Provider>\n </SCRIPT_CONTEXT.Provider>\n </I18N_CONTEXT.Provider>\n );\n const mainHtml = renderToString(vdom, {}, {pretty: true});\n\n // Walk the page's dependency tree for CSS dependencies that are added via\n // `import 'foo.scss'` or `import 'foo.module.scss'`.\n const pageAsset = await assetMap.get(route.modulePath);\n const cssDeps = await pageAsset?.getCssDeps();\n if (cssDeps) {\n cssDeps.forEach((cssUrl) => {\n headComponents.push(<link rel=\"stylesheet\" href={cssUrl} />);\n });\n }\n\n // Parse the HTML for custom elements that are found within the project\n // and automatically inject the script deps for them.\n const scriptDeps = await this.getScriptDeps(mainHtml, {assetMap});\n scriptDeps.forEach((jsUrls) => {\n headComponents.push(<script type=\"module\" src={jsUrls} />);\n });\n\n // Add user defined scripts added via the `<Script>` component.\n await Promise.all(\n userScripts.map(async (scriptDep) => {\n const scriptAsset = await assetMap.get(scriptDep.src);\n if (!scriptAsset && import.meta.env.PROD) {\n console.log(`could not find precompiled asset: ${scriptDep.src}`);\n }\n const scriptUrl = scriptAsset ? scriptAsset.assetUrl : scriptDep.src;\n headComponents.push(<script type=\"module\" src={scriptUrl} />);\n })\n );\n\n const html = await this.renderHtml({mainHtml, locale, headComponents});\n return {html};\n }\n\n async getSitemap(): Promise<\n Record<string, {route: Route; params: Record<string, string>}>\n > {\n const sitemap: Record<\n string,\n {route: Route; params: Record<string, string>}\n > = {};\n await this.routes.walk(async (urlPath: string, route: Route) => {\n const routePaths = await getAllPathsForRoute(urlPath, route);\n routePaths.forEach((routePath) => {\n sitemap[routePath.urlPath] = {\n route,\n params: routePath.params,\n };\n });\n });\n return sitemap;\n }\n\n private async renderHtml(options: RenderHtmlOptions) {\n const page = (\n <html lang={options.locale}>\n <head>\n <meta charSet=\"utf-8\" />\n {options.headComponents}\n </head>\n <body dangerouslySetInnerHTML={{__html: options.mainHtml}} />\n </html>\n );\n const html = `<!doctype html>\\n${renderToString(\n page,\n {},\n {pretty: true}\n )}\\n`;\n return html;\n }\n\n async render404() {\n return {\n html: '<!doctype html><html><title>404 Not Found</title><h1>404 Not Found</h1>',\n notFound: true,\n };\n }\n\n async renderError(error: unknown) {\n const mainHtml = renderToString(<ErrorPage error={error} />);\n const html = await this.renderHtml({mainHtml, locale: 'en'});\n return {html};\n }\n\n private async getScriptDeps(\n html: string,\n options: {assetMap: AssetMap}\n ): Promise<string[]> {\n const assetMap = options.assetMap as AssetMap;\n const deps = new Set<string>();\n\n const re = /<(\\w[\\w-]+\\w)/g;\n const matches = Array.from(html.matchAll(re));\n await Promise.all(\n matches.map(async (match) => {\n const tagName = match[1];\n // Custom elements require a dash.\n if (tagName && tagName.includes('-') && tagName in elementsMap) {\n const modulePath = elementsMap[tagName];\n const asset = await assetMap.get(modulePath);\n if (!asset) {\n return;\n }\n const assetJsDeps = await asset.getJsDeps();\n assetJsDeps.forEach((dep) => deps.add(dep));\n } else {\n console.log(`could not find tag name: ${tagName}`);\n }\n })\n );\n\n return Array.from(deps);\n }\n}\n","import path from 'node:path';\nimport {ComponentType} from 'preact';\nimport {RootConfig} from '../core/config';\nimport {GetStaticPaths, GetStaticProps} from '../core/types';\nimport {RouteTrie} from './route-trie';\n\nexport interface RouteModule {\n default?: ComponentType<unknown>;\n getStaticPaths?: GetStaticPaths;\n getStaticProps?: GetStaticProps;\n}\n\nexport interface Route {\n modulePath: string;\n module: RouteModule;\n locale: string;\n}\n\nexport function getRoutes(config: RootConfig) {\n const locales = config.i18n?.locales || [];\n const i18nUrlFormat = config.i18n?.urlFormat || '/{locale}/{path}';\n const defaultLocale = config.i18n?.defaultLocale || 'en';\n\n const routes = import.meta.glob(\n ['/routes/*.ts', '/routes/**/*.ts', '/routes/*.tsx', '/routes/**/*.tsx'],\n {\n eager: true,\n }\n );\n const trie = new RouteTrie<Route>();\n Object.keys(routes).forEach((filePath) => {\n let routePath = filePath.replace(/^\\/routes/, '');\n const parts = path.parse(routePath);\n if (parts.name.startsWith('_')) {\n return;\n }\n if (parts.name === 'index') {\n routePath = parts.dir;\n } else {\n routePath = path.join(parts.dir, parts.name);\n }\n trie.add(routePath, {\n modulePath: filePath,\n module: routes[filePath] as RouteModule,\n locale: defaultLocale,\n });\n\n // At the moment, all routes are assumed to use the site-wide i18n config.\n // TODO(stevenle): provide routes with a way to override the default\n // i18n serving behavior.\n locales.forEach((locale) => {\n const localeRoutePath = i18nUrlFormat\n .replace('{locale}', locale)\n .replace('{path}', routePath.replace(/^\\/*/, ''));\n if (localeRoutePath !== routePath) {\n trie.add(localeRoutePath, {\n modulePath: filePath,\n module: routes[filePath] as RouteModule,\n locale: locale,\n });\n }\n });\n });\n return trie;\n}\n\nexport async function getAllPathsForRoute(\n urlPathFormat: string,\n route: Route\n): Promise<Array<{urlPath: string; params: Record<string, string>}>> {\n const urlPaths: Array<{urlPath: string; params: Record<string, string>}> = [];\n const routeModule = route.module;\n if (routeModule.getStaticPaths) {\n const staticPaths = await routeModule.getStaticPaths();\n staticPaths.paths.forEach(\n (pathParams: {params: Record<string, string>}) => {\n urlPaths.push({\n urlPath: replaceParams(urlPathFormat, pathParams.params),\n params: pathParams.params || {},\n });\n }\n );\n } else {\n urlPaths.push({urlPath: urlPathFormat, params: {}});\n }\n return urlPaths;\n}\n\nexport function replaceParams(\n urlPathFormat: string,\n params: Record<string, string>\n) {\n const urlPath = urlPathFormat.replaceAll(\n /\\[(\\.\\.\\.)?([\\w\\-_]*)\\]/g,\n (match: string, _wildcard: string, key: string) => {\n const val = params[key];\n if (!val) {\n throw new Error(`unreplaced param ${match} in url: ${urlPathFormat}`);\n }\n return val;\n }\n );\n return urlPath;\n}\n","/**\n * A trie data structure that stores routes. The trie supports `:param` and\n * `*wildcard` values.\n */\nexport class RouteTrie<T> {\n private children: Record<string, RouteTrie<T>> = {};\n private paramChild?: ParamChild<T>;\n private wildcardChild?: WildcardChild<T>;\n private route?: T;\n\n /**\n * Adds a route to the trie.\n */\n add(path: string, route: T) {\n path = this.normalizePath(path);\n\n // If the end was reached, save the value to the node.\n if (path === '') {\n this.route = route;\n return;\n }\n\n const [head, tail] = this.splitPath(path);\n if (head.startsWith('[...') && head.endsWith(']')) {\n const paramName = head.slice(4, -1);\n this.wildcardChild = new WildcardChild(paramName, route);\n return;\n }\n\n let nextNode: RouteTrie<T>;\n if (head.startsWith('[') && head.endsWith(']')) {\n if (!this.paramChild) {\n const paramName = head.slice(1, -1);\n this.paramChild = new ParamChild(paramName);\n }\n nextNode = this.paramChild.trie;\n } else {\n nextNode = this.children[head];\n if (!nextNode) {\n nextNode = new RouteTrie();\n this.children[head] = nextNode;\n }\n }\n nextNode.add(tail, route);\n }\n\n /**\n * Returns a route mapped to the given path and any parameter values from the\n * URL.\n */\n get(path: string): [T | undefined, Record<string, string>] {\n const params = {};\n const route = this.getRoute(path, params);\n return [route, params];\n }\n\n /**\n * Walks the route trie and calls a callback function for each route.\n */\n walk(cb: (urlPath: string, route: T) => Promise<void> | void): Promise<void> {\n const promises: Array<Promise<void>> = [];\n const addPromise = (promise: Promise<void> | void) => {\n if (promise) {\n promises.push(promise);\n }\n };\n if (this.route) {\n addPromise(cb('/', this.route));\n }\n if (this.paramChild) {\n const param = `[${this.paramChild.name}]`;\n this.paramChild.trie.walk((childPath: string, route: T) => {\n const paramUrlPath = `/${param}${childPath}`;\n addPromise(cb(paramUrlPath, route));\n });\n }\n if (this.wildcardChild) {\n const wildcardUrlPath = `/[...${this.wildcardChild.name}]`;\n addPromise(cb(wildcardUrlPath, this.wildcardChild.route));\n }\n for (const subpath of Object.keys(this.children)) {\n const childTrie = this.children[subpath];\n childTrie.walk((childPath: string, childRoute: T) => {\n addPromise(cb(`/${subpath}${childPath}`, childRoute));\n });\n }\n return Promise.all(promises).then(() => {});\n }\n\n /**\n * Removes all routes from the trie.\n */\n clear() {\n this.children = {};\n this.paramChild = undefined;\n this.wildcardChild = undefined;\n this.route = undefined;\n }\n\n private getRoute(\n urlPath: string,\n params: Record<string, string>\n ): T | undefined {\n urlPath = this.normalizePath(urlPath);\n if (urlPath === '') {\n return this.route;\n }\n\n const [head, tail] = this.splitPath(urlPath);\n\n const child = this.children[head];\n if (child) {\n const route = child.getRoute(tail, params);\n if (route) {\n return route;\n }\n }\n\n if (this.paramChild) {\n const route = this.paramChild.trie.getRoute(tail, params);\n if (route) {\n params[this.paramChild.name] = head;\n return route;\n }\n }\n\n if (this.wildcardChild) {\n params[this.wildcardChild.name] = urlPath;\n return this.wildcardChild.route;\n }\n\n return undefined;\n }\n\n /**\n * Normalizes a path for inclusion into the route trie.\n */\n private normalizePath(path: string) {\n // Remove leading slashes.\n return path.replace(/^\\/+/g, '');\n }\n\n /**\n * Splits the parent directory from its children, e.g.:\n *\n * splitPath(\"foo/bar/baz\") -> [\"foo\", \"bar/baz\"]\n */\n private splitPath(path: string): [string, string] {\n const i = path.indexOf('/');\n if (i === -1) {\n return [path, ''];\n }\n return [path.slice(0, i), path.slice(i + 1)];\n }\n}\n\n/**\n * A node in the RouteTrie for a :param child.\n */\nclass ParamChild<T> {\n readonly name: string;\n readonly trie: RouteTrie<T> = new RouteTrie();\n\n constructor(name: string) {\n this.name = name;\n }\n}\n\n/**\n * A node in the RouteTrie for a *wildcard child.\n */\nclass WildcardChild<T> {\n readonly name: string;\n readonly route: T;\n\n constructor(name: string, route: T) {\n this.name = name;\n this.route = route;\n }\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,57 @@
1
+ import { UserConfig } from 'vite';
2
+
3
+ interface RootConfig {
4
+ /**
5
+ * Configuration for auto-injecting custom element dependencies.
6
+ */
7
+ elements?: {
8
+ /**
9
+ * A list of directories to use to look for custom elements. The dir path
10
+ * should be relative to the project dir, e.g. "path/to/elements" or
11
+ * "node_modules/my-package".
12
+ */
13
+ include?: string[];
14
+ };
15
+ /**
16
+ * Configuration options for localization and internationalization.
17
+ */
18
+ i18n?: RootI18nConfig;
19
+ /**
20
+ * Vite configuration.
21
+ * @see {@link https://vitejs.dev/config/} for more information.
22
+ */
23
+ vite?: UserConfig;
24
+ /**
25
+ * Whether to include a sitemap.xml file to the build output.
26
+ */
27
+ sitemap?: boolean;
28
+ }
29
+ interface RootI18nConfig {
30
+ /**
31
+ * Locales enabled for the site.
32
+ */
33
+ locales?: string[];
34
+ /**
35
+ * The default locale to use. Defaults is `en`.
36
+ */
37
+ defaultLocale?: string;
38
+ /**
39
+ * URL format for localized content. Default is `/{locale}/{path}`.
40
+ */
41
+ urlFormat?: string;
42
+ }
43
+ declare function defineConfig(config: RootConfig): RootConfig;
44
+
45
+ declare type GetStaticProps<T = unknown> = (ctx: {
46
+ params: Record<string, string>;
47
+ }) => Promise<{
48
+ props: T;
49
+ notFound?: boolean;
50
+ }>;
51
+ declare type GetStaticPaths<T = Record<string, string>> = () => Promise<{
52
+ paths: Array<{
53
+ params: T;
54
+ }>;
55
+ }>;
56
+
57
+ export { GetStaticProps as G, RootConfig as R, RootI18nConfig as a, GetStaticPaths as b, defineConfig as d };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blinkk/root",
3
- "version": "1.0.0-alpha.3",
3
+ "version": "1.0.0-alpha.4",
4
4
  "author": "s@blinkk.com",
5
5
  "license": "MIT",
6
6
  "bin": {
@@ -1,27 +0,0 @@
1
- import { UserConfig } from 'vite';
2
-
3
- interface RootConfig {
4
- i18n?: RootI18nConfig;
5
- vite?: UserConfig;
6
- sitemap?: boolean;
7
- }
8
- interface RootI18nConfig {
9
- locales?: string[];
10
- defaultLocale?: string;
11
- urlFormat?: string;
12
- }
13
- declare function defineConfig(config: RootConfig): RootConfig;
14
-
15
- declare type GetStaticProps<T = unknown> = (ctx: {
16
- params: Record<string, string>;
17
- }) => Promise<{
18
- props: T;
19
- notFound?: boolean;
20
- }>;
21
- declare type GetStaticPaths<T = Record<string, string>> = () => Promise<{
22
- paths: Array<{
23
- params: T;
24
- }>;
25
- }>;
26
-
27
- export { GetStaticProps as G, RootConfig as R, RootI18nConfig as a, GetStaticPaths as b, defineConfig as d };