@blinkk/root 2.5.16 → 3.0.1-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/dist/chunk-3OVMCKPA.js +416 -0
  2. package/dist/chunk-3OVMCKPA.js.map +1 -0
  3. package/dist/chunk-CY5IQ4AQ.js +73 -0
  4. package/dist/chunk-CY5IQ4AQ.js.map +1 -0
  5. package/dist/chunk-PVBPP5LN.js +854 -0
  6. package/dist/chunk-PVBPP5LN.js.map +1 -0
  7. package/dist/{chunk-ZOU2UDXE.js → chunk-RRJ3JKJD.js} +56 -33
  8. package/dist/chunk-RRJ3JKJD.js.map +1 -0
  9. package/dist/{chunk-6FDF3DXT.js → chunk-XSNCF7WU.js} +1 -1
  10. package/dist/chunk-XSNCF7WU.js.map +1 -0
  11. package/dist/cli.d.ts +3 -1
  12. package/dist/cli.js +4 -4
  13. package/dist/core.d.ts +4 -2
  14. package/dist/core.js +10 -4
  15. package/dist/core.js.map +1 -1
  16. package/dist/functions.js +4 -4
  17. package/dist/jsx/jsx-dev-runtime.d.ts +1 -0
  18. package/dist/jsx/jsx-dev-runtime.js +11 -0
  19. package/dist/jsx/jsx-dev-runtime.js.map +1 -0
  20. package/dist/jsx/jsx-runtime.d.ts +1 -0
  21. package/dist/jsx/jsx-runtime.js +19 -0
  22. package/dist/jsx/jsx-runtime.js.map +1 -0
  23. package/dist/jsx-C8BaDh-4.d.ts +14 -0
  24. package/dist/jsx-dev-runtime-DUJrvx5P.d.ts +677 -0
  25. package/dist/jsx.d.ts +2 -0
  26. package/dist/jsx.js +23 -0
  27. package/dist/jsx.js.map +1 -0
  28. package/dist/middleware.d.ts +4 -2
  29. package/dist/node.d.ts +36 -2
  30. package/dist/node.js +6 -2
  31. package/dist/render.d.ts +3 -1
  32. package/dist/render.js +86 -16
  33. package/dist/render.js.map +1 -1
  34. package/dist/{types-BXpvdaTX.d.ts → types-Cksf99CK.d.ts} +100 -1
  35. package/package.json +21 -8
  36. package/dist/chunk-6FDF3DXT.js.map +0 -1
  37. package/dist/chunk-ISNB54FM.js +0 -406
  38. package/dist/chunk-ISNB54FM.js.map +0 -1
  39. package/dist/chunk-ZOU2UDXE.js.map +0 -1
@@ -1,6 +1,7 @@
1
1
  import { Express, Request as Request$1, Response as Response$1, NextFunction as NextFunction$1 } from 'express';
2
2
  import { ComponentType } from 'preact';
3
3
  import { PluginOption, UserConfig, ViteDevServer } from 'vite';
4
+ import { J as JsxRenderOptions } from './jsx-C8BaDh-4.js';
4
5
  import { Options } from 'html-minifier-terser';
5
6
  import { HTMLBeautifyOptions } from 'js-beautify';
6
7
 
@@ -38,6 +39,59 @@ type HtmlMinifyOptions = Options;
38
39
 
39
40
  type HtmlPrettyOptions = HTMLBeautifyOptions;
40
41
 
42
+ interface Pod {
43
+ /** Unique pod name, e.g. '@blinkk/root-docs-pod'. */
44
+ name: string;
45
+ /**
46
+ * URL prefix for pod routes. Routes within the pod are served under this
47
+ * mount path. Defaults to '/'.
48
+ */
49
+ mount?: string;
50
+ /**
51
+ * Priority for route conflict resolution. Higher values win when multiple
52
+ * pods register the same URL path. User-site routes always take precedence
53
+ * regardless of priority. Defaults to 0.
54
+ */
55
+ priority?: number;
56
+ /** Absolute path to the pod's routes/ directory. */
57
+ routesDir?: string;
58
+ /** Absolute path(s) to the pod's elements/ directory(s). */
59
+ elementsDirs?: string[];
60
+ /** Absolute path to the pod's bundles/ directory. */
61
+ bundlesDir?: string;
62
+ /** Absolute path to the pod's collections/ directory (root-cms only). */
63
+ collectionsDir?: string;
64
+ /** Absolute path to the pod's translations/ directory. */
65
+ translationsDir?: string;
66
+ /** Extra Vite plugins contributed by the pod. */
67
+ vitePlugins?: PluginOption[];
68
+ }
69
+ type PodFactory = (ctx: {
70
+ rootConfig: RootConfig;
71
+ }) => Pod | Promise<Pod>;
72
+ interface PodConfig {
73
+ /** Whether the pod is enabled. Defaults to true. */
74
+ enabled?: boolean;
75
+ /** Override the pod's mount path. */
76
+ mount?: string;
77
+ /** Override the pod's priority. */
78
+ priority?: number;
79
+ /** Filter pod routes. */
80
+ routes?: {
81
+ exclude?: (string | RegExp)[];
82
+ };
83
+ /** Configure pod collections. */
84
+ collections?: {
85
+ exclude?: string[];
86
+ /** Rename collection ids, e.g. {Posts: 'DocsPosts'}. */
87
+ rename?: Record<string, string>;
88
+ };
89
+ }
90
+ /**
91
+ * Helper to define a pod with type-checking.
92
+ */
93
+ declare function definePod(pod: Pod): Pod;
94
+
41
95
  type MaybePromise<T> = T | Promise<T>;
42
96
  type PreBuildHook = (rootConfig: RootConfig) => MaybePromise<void>;
43
97
  interface PostBuildOptions {
@@ -99,6 +153,12 @@ interface Plugin {
99
153
  hooks?: PluginHooks;
100
154
  /** Custom 404 handler. */
101
155
  handle404?: (req: Request, res: Response, next: NextFunction) => void | Promise<void>;
156
+ /**
157
+ * Registers a pod (a mini root.js site) that gets merged into the parent
158
+ * site at dev/build time. A plugin may return a single pod, an array of
159
+ * pods, or a factory that receives the rootConfig.
160
+ */
161
+ pod?: Pod | Pod[] | PodFactory;
102
162
  }
103
163
  /**
104
164
  * Runs the pre-hook configureServer method of every plugin, calls a callback
@@ -168,6 +228,27 @@ interface RootUserConfig {
168
228
  * @see {@link https://vitejs.dev/config/} for more information.
169
229
  */
170
230
  vite?: UserConfig;
231
+ /**
232
+ * Config for the built-in JSX-to-HTML renderer.
233
+ *
234
+ * - `mode: 'pretty'` (default) — block-level elements render on their own
235
+ * line with no indentation.
236
+ * - `mode: 'minimal'` — compact output with no extra whitespace.
237
+ *
238
+ * Use `blockElements` to specify additional custom element tag names that
239
+ * should be treated as block-level in pretty mode.
240
+ *
241
+ * @example
242
+ * ```ts
243
+ * export default defineConfig({
244
+ * jsxRenderer: {
245
+ * mode: 'pretty',
246
+ * blockElements: ['my-card', 'my-section'],
247
+ * },
248
+ * });
249
+ * ```
250
+ */
251
+ jsxRenderer?: JsxRenderOptions;
171
252
  /**
172
253
  * Whether to automatically minify HTML output. This is enabled by default,
173
254
  * in order to disable, pass `minifyHtml: false` to root.config.ts.
@@ -193,6 +274,11 @@ interface RootUserConfig {
193
274
  * Plugins.
194
275
  */
195
276
  plugins?: Plugin[];
277
+ /**
278
+ * Per-pod user-level overrides. The key is the pod name as declared in
279
+ * Pod.name.
280
+ */
281
+ pods?: Record<string, PodConfig>;
196
282
  /**
197
283
  * Experimental config options. Note: these are subject to change at any time.
198
284
  */
@@ -470,8 +556,16 @@ declare class Renderer {
470
556
  * - construct alternates for localized URL paths
471
557
  */
472
558
  getSitemap(): Promise<Sitemap>;
559
+ private getJsxRenderOptions;
560
+ /**
561
+ * Renders JSX via either the `@blinkk/root/jsx` package or
562
+ * `preact-render-to-string` depending if the `jsxRenderer` config is set up
563
+ * in `root.config.ts`.
564
+ */
565
+ private renderJsx;
473
566
  private getConfiguredStyleEntries;
474
567
  private renderHtml;
568
+ private ensureNewline;
475
569
  render404(options?: {
476
570
  currentPath?: string;
477
571
  }): Promise<{
@@ -688,6 +782,11 @@ interface Route {
688
782
  * Per the example above, this value contains placeholder params.
689
783
  */
690
784
  localeRoutePath: string;
785
+ /**
786
+ * The name of the pod that contributed this route, or undefined if the
787
+ * route is from the user's project.
788
+ */
789
+ podName?: string;
691
790
  }
692
791
  interface HandlerRenderOptions {
693
792
  /** HTTP status code to return. Defaults to 200. */
@@ -725,4 +824,4 @@ interface SitemapItem {
725
824
  }>;
726
825
  }
727
826
 
728
- export { type Sitemap as A, type SitemapItem as B, type ContentSecurityPolicyConfig as C, SESSION_COOKIE as D, type SessionMiddlewareOptions as E, type SaveSessionOptions as F, type GetStaticProps as G, type HandlerContext as H, sessionMiddleware as I, Session as J, Renderer as K, type LocaleGroup as L, type MultipartFile as M, type NextFunction as N, type PostBuildOptions as P, type Route as R, type Server as S, type XFrameOptionsConfig as X, type RootUserConfig as a, type RootConfig as b, type RootI18nConfig as c, type RootBuildConfig as d, type RootRedirectConfig as e, type RootHeaderConfig as f, type RootSecurityConfig as g, type RootServerConfig as h, defineConfig as i, type ConfigureServerHook as j, type ConfigureServerOptions as k, type PluginHooks as l, type Plugin as m, configureServerPlugins as n, getVitePlugins as o, type RouteParams as p, type GetStaticPaths as q, type RequestMiddleware as r, type Request as s, type Response as t, type Handler as u, type StaticContentResult as v, type GetStaticContent as w, type RouteModule as x, type HandlerRenderOptions as y, type HandlerRenderFn as z };
827
+ export { type RouteParams as A, type GetStaticPaths as B, type ContentSecurityPolicyConfig as C, type RequestMiddleware as D, type Handler as E, type StaticContentResult as F, type GetStaticProps as G, type HandlerContext as H, type GetStaticContent as I, type RouteModule as J, type HandlerRenderOptions as K, type LocaleGroup as L, type MultipartFile as M, type NextFunction as N, type HandlerRenderFn as O, type PodConfig as P, type Sitemap as Q, type RootConfig as R, SESSION_COOKIE as S, type SitemapItem as T, Renderer as U, type XFrameOptionsConfig as X, type Request as a, type Response as b, type SessionMiddlewareOptions as c, type SaveSessionOptions as d, Session as e, type Server as f, type Route as g, type RootUserConfig as h, type RootI18nConfig as i, type RootBuildConfig as j, type RootRedirectConfig as k, type RootHeaderConfig as l, type RootSecurityConfig as m, type RootServerConfig as n, defineConfig as o, type Pod as p, type PodFactory as q, definePod as r, sessionMiddleware as s, type PostBuildOptions as t, type ConfigureServerHook as u, type ConfigureServerOptions as v, type PluginHooks as w, type Plugin as x, configureServerPlugins as y, getVitePlugins as z };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blinkk/root",
3
- "version": "2.5.16",
3
+ "version": "3.0.1-alpha.1",
4
4
  "author": "s@blinkk.com",
5
5
  "license": "MIT",
6
6
  "engines": {
@@ -11,9 +11,6 @@
11
11
  "url": "git+https://github.com/blinkk/rootjs.git",
12
12
  "directory": "packages/root"
13
13
  },
14
- "publishConfig": {
15
- "provenance": true
16
- },
17
14
  "files": [
18
15
  "bin/*",
19
16
  "dist/**/*",
@@ -43,6 +40,18 @@
43
40
  "types": "./dist/functions.d.ts",
44
41
  "import": "./dist/functions.js"
45
42
  },
43
+ "./jsx": {
44
+ "types": "./dist/jsx.d.ts",
45
+ "import": "./dist/jsx.js"
46
+ },
47
+ "./jsx/jsx-runtime": {
48
+ "types": "./dist/jsx/jsx-runtime.d.ts",
49
+ "import": "./dist/jsx/jsx-runtime.js"
50
+ },
51
+ "./jsx/jsx-dev-runtime": {
52
+ "types": "./dist/jsx/jsx-dev-runtime.d.ts",
53
+ "import": "./dist/jsx/jsx-dev-runtime.js"
54
+ },
46
55
  "./middleware": {
47
56
  "types": "./dist/middleware.d.ts",
48
57
  "import": "./dist/middleware.js"
@@ -77,7 +86,7 @@
77
86
  "sirv": "2.0.3",
78
87
  "source-map-support": "0.5.21",
79
88
  "tiny-glob": "0.2.9",
80
- "vite": "7.1.4",
89
+ "vite": "8.0.3",
81
90
  "workspace-tools": "0.37.0"
82
91
  },
83
92
  "peerDependencies": {
@@ -92,6 +101,12 @@
92
101
  },
93
102
  "firebase-admin": {
94
103
  "optional": true
104
+ },
105
+ "preact": {
106
+ "optional": true
107
+ },
108
+ "preact-render-to-string": {
109
+ "optional": true
95
110
  }
96
111
  },
97
112
  "devDependencies": {
@@ -103,16 +118,14 @@
103
118
  "@types/html-minifier-terser": "7.0.0",
104
119
  "@types/js-beautify": "1.14.1",
105
120
  "@types/node": "24.3.1",
106
- "@types/preact-custom-element": "4.0.2",
107
121
  "firebase-admin": "11.11.0",
108
122
  "firebase-functions": "4.8.0",
109
123
  "nodemon": "3.0.1",
110
124
  "preact": "10.27.1",
111
- "preact-custom-element": "4.5.0",
112
125
  "preact-render-to-string": "6.6.1",
113
126
  "tsup": "8.5.0",
114
127
  "typescript": "5.9.2",
115
- "vitest": "3.2.4"
128
+ "vitest": "4.1.2"
116
129
  },
117
130
  "scripts": {
118
131
  "build": "rm -rf dist && tsup-node",
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/core/plugin.ts"],"sourcesContent":["import {ViteDevServer, PluginOption as VitePlugin} from 'vite';\nimport {RootConfig} from './config.js';\nimport {NextFunction, Request, Response, Server} from './types.js';\n\ntype MaybePromise<T> = T | Promise<T>;\n\ntype PreBuildHook = (rootConfig: RootConfig) => MaybePromise<void>;\n\nexport interface PostBuildOptions {\n /** Whether the build was SSR-only (no SSG pre-rendering). */\n ssrOnly?: boolean;\n}\n\ntype PostBuildHook = (\n rootConfig: RootConfig,\n options?: PostBuildOptions\n) => MaybePromise<void>;\n\nexport type ConfigureServerHook = (\n server: Server,\n options: ConfigureServerOptions\n) => MaybePromise<void> | MaybePromise<() => void>;\n\nexport interface ConfigureServerOptions {\n type: 'dev' | 'preview' | 'prod';\n rootConfig: RootConfig;\n}\n\nexport interface PluginHooks {\n /**\n * Hook that runs before the build starts.\n */\n preBuild?: PreBuildHook;\n\n /**\n * Hook that runs after the build completes.\n */\n postBuild?: PostBuildHook;\n\n /**\n * Post-render hook that's called before the HTML is rendered to the response\n * object. If a string is returned from this hook, it will replace the\n * rendered HTML.\n */\n preRender?: (html: string) => void | MaybePromise<string>;\n}\n\nexport interface Plugin {\n [key: string]: any;\n /** The name of the plugin. */\n name?: string;\n /**\n * Configures the root.js express server. Any middleware defined by the plugin\n * will be added to the server first. If a callback fn is returned, it will\n * be called after the root.js middlewares are added.\n */\n configureServer?: ConfigureServerHook;\n /**\n * Hook for file changes.\n */\n onFileChange?: (\n eventName: 'add' | 'addDir' | 'change' | 'unlink' | 'unlinkDir',\n path: string\n ) => void;\n /**\n * Returns a list of deps to bundle for ssr. The files will be bundled and\n * output to `dist/server/`. The return value should be a map of\n * `{output filename => input filepath}`.\n *\n * E.g. a value of `{foo: 'path/to/bar.js'}` will output `dist/server/foo.js`.\n *\n * @experimental This config is subject to change to be incorporated into a\n * broader config option called \"ssr\" or \"ssrOptions\".\n */\n ssrInput?: () => {[entryAlias: string]: string};\n /** Adds vite plugins. */\n vitePlugins?: VitePlugin[];\n /** Plugin lifecycle callback hooks. */\n hooks?: PluginHooks;\n /** Custom 404 handler. */\n handle404?: (\n req: Request,\n res: Response,\n next: NextFunction\n ) => void | Promise<void>;\n}\n\n/**\n * Runs the pre-hook configureServer method of every plugin, calls a callback\n * function, and then runs the configureServer's post-hook if provided. Plugins\n * provide a post-hook by returning a callback function from configureServer.\n */\nexport async function configureServerPlugins(\n server: Server,\n callback: () => Promise<void>,\n plugins: Plugin[],\n options: ConfigureServerOptions\n) {\n const postHooks: Array<() => void> = [];\n const viteServer = server.get('viteServer') as ViteDevServer;\n\n // Call the `configureServer()` method for each plugin.\n for (const plugin of plugins) {\n if (plugin.configureServer) {\n const postHook = await plugin.configureServer(server, options);\n if (postHook) {\n postHooks.push(postHook);\n }\n }\n\n if (viteServer && plugin.onFileChange) {\n viteServer.watcher.on('all', plugin.onFileChange);\n }\n }\n\n // Register any built-in middleware.\n callback();\n\n // Run any post hooks returned by `plugin.configureServer()`.\n for (const postHook of postHooks) {\n await postHook();\n }\n}\n\nexport function getVitePlugins(plugins: Plugin[]): VitePlugin[] {\n const vitePlugins: VitePlugin[] = [];\n for (const plugin of plugins) {\n if (plugin.vitePlugins) {\n vitePlugins.push(...plugin.vitePlugins);\n }\n }\n return vitePlugins;\n}\n"],"mappings":";AA4FA,eAAsB,uBACpB,QACA,UACA,SACA,SACA;AACA,QAAM,YAA+B,CAAC;AACtC,QAAM,aAAa,OAAO,IAAI,YAAY;AAG1C,aAAW,UAAU,SAAS;AAC5B,QAAI,OAAO,iBAAiB;AAC1B,YAAM,WAAW,MAAM,OAAO,gBAAgB,QAAQ,OAAO;AAC7D,UAAI,UAAU;AACZ,kBAAU,KAAK,QAAQ;AAAA,MACzB;AAAA,IACF;AAEA,QAAI,cAAc,OAAO,cAAc;AACrC,iBAAW,QAAQ,GAAG,OAAO,OAAO,YAAY;AAAA,IAClD;AAAA,EACF;AAGA,WAAS;AAGT,aAAW,YAAY,WAAW;AAChC,UAAM,SAAS;AAAA,EACjB;AACF;AAEO,SAAS,eAAe,SAAiC;AAC9D,QAAM,cAA4B,CAAC;AACnC,aAAW,UAAU,SAAS;AAC5B,QAAI,OAAO,aAAa;AACtB,kBAAY,KAAK,GAAG,OAAO,WAAW;AAAA,IACxC;AAAA,EACF;AACA,SAAO;AACT;","names":[]}
@@ -1,406 +0,0 @@
1
- import {
2
- getVitePlugins
3
- } from "./chunk-6FDF3DXT.js";
4
-
5
- // src/node/monorepo.ts
6
- import path2 from "path";
7
- import { getWorkspaces, getWorkspaceRoot } from "workspace-tools";
8
-
9
- // src/utils/fsutils.ts
10
- import fs from "fs";
11
- import path from "path";
12
- import fsExtra from "fs-extra";
13
- import glob from "tiny-glob";
14
- function isJsFile(filename) {
15
- return !!filename.match(/\.(j|t)sx?$/);
16
- }
17
- async function writeFile(filepath, content) {
18
- const dirPath = path.dirname(filepath);
19
- await makeDir(dirPath);
20
- await fs.promises.writeFile(filepath, content);
21
- }
22
- async function makeDir(dirpath) {
23
- try {
24
- await fs.promises.access(dirpath);
25
- } catch (e) {
26
- await fs.promises.mkdir(dirpath, { recursive: true });
27
- }
28
- }
29
- async function copyDir(srcdir, dstdir) {
30
- if (!fsExtra.existsSync(srcdir)) {
31
- return;
32
- }
33
- fsExtra.copySync(srcdir, dstdir, { overwrite: true });
34
- }
35
- async function copyGlob(pattern, srcdir, dstdir) {
36
- const files = await glob(pattern, { cwd: srcdir });
37
- if (files.length > 0) {
38
- await makeDir(dstdir);
39
- }
40
- files.forEach((file) => {
41
- fsExtra.copySync(path.resolve(srcdir, file), path.resolve(dstdir, file));
42
- });
43
- }
44
- async function rmDir(dirpath) {
45
- await fs.promises.rm(dirpath, { recursive: true, force: true });
46
- }
47
- async function loadJson(filepath) {
48
- const content = await fs.promises.readFile(filepath, "utf-8");
49
- return JSON.parse(content);
50
- }
51
- function loadJsonSync(filepath) {
52
- const content = fs.readFileSync(filepath, "utf-8");
53
- return JSON.parse(content);
54
- }
55
- async function writeJson(filepath, data) {
56
- const content = JSON.stringify(data, null, 2);
57
- await writeFile(filepath, content);
58
- }
59
- async function isDirectory(dirpath) {
60
- return fs.promises.stat(dirpath).then((fsStat) => {
61
- return fsStat.isDirectory();
62
- }).catch((err) => {
63
- if (err.code === "ENOENT") {
64
- return false;
65
- }
66
- throw err;
67
- });
68
- }
69
- function fileExists(filepath) {
70
- return fs.promises.access(filepath).then(() => true).catch(() => false);
71
- }
72
- function fileExistsSync(filepath) {
73
- try {
74
- fs.accessSync(filepath);
75
- return true;
76
- } catch {
77
- return false;
78
- }
79
- }
80
- async function dirExists(dirpath) {
81
- try {
82
- const stat = await fs.promises.stat(dirpath);
83
- return stat.isDirectory();
84
- } catch (error) {
85
- if (error.code === "ENOENT") {
86
- return false;
87
- }
88
- throw error;
89
- }
90
- }
91
- async function directoryContains(dirpath, subpath) {
92
- const outer = await fs.promises.realpath(dirpath);
93
- const inner = await fs.promises.realpath(subpath);
94
- const rel = path.relative(outer, inner);
95
- return !rel.startsWith("..");
96
- }
97
-
98
- // src/node/monorepo.ts
99
- function loadPackageJson(filepath) {
100
- if (!fileExistsSync(filepath)) {
101
- return null;
102
- }
103
- return loadJsonSync(filepath);
104
- }
105
- function getMonorepoPackages(rootDir) {
106
- const monorepoRoot = getWorkspaceRoot(rootDir);
107
- if (!monorepoRoot) {
108
- return {};
109
- }
110
- const workspaces = getWorkspaces(monorepoRoot);
111
- const packages = {};
112
- workspaces.forEach((workspaceInfo) => {
113
- packages[workspaceInfo.name] = workspaceInfo;
114
- });
115
- return packages;
116
- }
117
- function getMonorepoPackageDeps(rootDir) {
118
- const monorepoRoot = getWorkspaceRoot(rootDir);
119
- if (!monorepoRoot) {
120
- return {};
121
- }
122
- const packageJsonPath = path2.join(monorepoRoot, "package.json");
123
- const packageJson = loadPackageJson(packageJsonPath);
124
- return packageJson?.dependencies || {};
125
- }
126
- function flattenPackageDepsFromMonorepo(rootDir, options) {
127
- const packageJsonPath = path2.resolve(rootDir, "package.json");
128
- const packageJson = loadPackageJson(packageJsonPath);
129
- const monorepoDeps = getMonorepoPackageDeps(rootDir);
130
- const projectDeps = {
131
- ...packageJson?.peerDependencies,
132
- ...packageJson?.dependencies
133
- };
134
- const allDeps = {};
135
- const workspacePackages = getMonorepoPackages(rootDir);
136
- const ignore = options?.ignore || /* @__PURE__ */ new Set();
137
- Object.entries(projectDeps).forEach(([depName, depVersion]) => {
138
- if (depName.startsWith("@blinkk/root") && depVersion.startsWith("workspace:")) {
139
- const packageInfo = workspacePackages[depName];
140
- if (packageInfo) {
141
- allDeps[depName] = packageInfo.packageJson.version;
142
- }
143
- } else if (depVersion.startsWith("workspace:")) {
144
- if (ignore.has(depName)) {
145
- return;
146
- }
147
- ignore.add(depName);
148
- const packageInfo = workspacePackages[depName];
149
- if (packageInfo) {
150
- const workspacePackageDir = packageInfo.path;
151
- const deps = flattenPackageDepsFromMonorepo(workspacePackageDir, {
152
- ignore
153
- });
154
- for (const key in deps) {
155
- const currentValue = allDeps[key];
156
- if (deps[key] && deps[key] !== "*" && (!currentValue || currentValue === "*")) {
157
- allDeps[key] = deps[key];
158
- }
159
- }
160
- }
161
- } else if (depVersion === "*" && monorepoDeps[depName]) {
162
- allDeps[depName] = monorepoDeps[depName];
163
- } else {
164
- allDeps[depName] = depVersion;
165
- }
166
- });
167
- return sortDeps(allDeps);
168
- }
169
- function sortDeps(deps) {
170
- const keys = Object.keys(deps).sort();
171
- const sortedDeps = {};
172
- for (const key of keys) {
173
- sortedDeps[key] = deps[key];
174
- }
175
- return sortedDeps;
176
- }
177
-
178
- // src/node/load-config.ts
179
- import path3 from "path";
180
- import { bundleRequire } from "bundle-require";
181
- import { build } from "esbuild";
182
- async function loadRootConfig(rootDir, options) {
183
- const { rootConfig } = await loadRootConfigWithDeps(rootDir, options);
184
- return rootConfig;
185
- }
186
- async function loadRootConfigWithDeps(rootDir, options) {
187
- const configPath = path3.resolve(rootDir, "root.config.ts");
188
- const exists = await fileExists(configPath);
189
- if (!exists) {
190
- throw new Error(`${configPath} does not exist`);
191
- }
192
- const configBundle = await bundleRequire({
193
- filepath: configPath,
194
- esbuildOptions: { plugins: [esbuildExternalsPlugin({ rootDir })] }
195
- });
196
- let config = configBundle.mod.default || {};
197
- if (typeof config === "function") {
198
- config = await config(options) || {};
199
- }
200
- const rootConfig = Object.assign({}, config, { rootDir });
201
- validateRootconfig(rootConfig);
202
- return { rootConfig, dependencies: configBundle.dependencies };
203
- }
204
- function validateRootconfig(rootConfig) {
205
- const scss = rootConfig.vite?.css?.preprocessorOptions?.scss;
206
- if (scss?.includePaths) {
207
- console.warn(
208
- '[deprecation warning] root.config.ts: vite.css.preprocessorOptions.scss.includePaths is deprecated. rename "includePaths" -> "loadPaths"'
209
- );
210
- scss.loadPaths = scss.includePaths;
211
- }
212
- }
213
- async function bundleRootConfig(rootDir, outPath) {
214
- const configPath = path3.resolve(rootDir, "root.config.ts");
215
- const configExists = await fileExists(configPath);
216
- if (!configExists) {
217
- throw new Error(`${configPath} does not exist`);
218
- }
219
- await build({
220
- entryPoints: [configPath],
221
- bundle: true,
222
- minify: true,
223
- platform: "node",
224
- outfile: outPath,
225
- sourcemap: "inline",
226
- metafile: true,
227
- format: "esm",
228
- plugins: [esbuildExternalsPlugin({ rootDir })]
229
- });
230
- }
231
- async function loadBundledConfig(rootDir, options) {
232
- const configPath = path3.resolve(rootDir, "dist/root.config.js");
233
- const exists = await fileExists(configPath);
234
- if (!exists) {
235
- throw new Error(`${configPath} does not exist`);
236
- }
237
- const module = await import(configPath);
238
- let config = module.default || {};
239
- if (typeof config === "function") {
240
- config = await config(options) || {};
241
- }
242
- return Object.assign({}, config, { rootDir });
243
- }
244
- function esbuildExternalsPlugin(options) {
245
- const rootDir = options.rootDir;
246
- const allDeps = flattenPackageDepsFromMonorepo(rootDir);
247
- function getPackageName(id) {
248
- const segments = id.split("/");
249
- if (segments.length > 1) {
250
- if (segments[0].startsWith("@") && segments[0].length > 1) {
251
- return `${segments[0]}/${segments[1]}`;
252
- }
253
- return segments[0];
254
- }
255
- return id;
256
- }
257
- return {
258
- name: "root-externals-plugin",
259
- setup(build2) {
260
- build2.onResolve({ filter: /.*/ }, (args) => {
261
- const id = args.path;
262
- if (id[0] !== "." && !id.startsWith("@/")) {
263
- const packageName = getPackageName(id);
264
- if (packageName in allDeps) {
265
- return {
266
- external: true
267
- };
268
- }
269
- }
270
- return null;
271
- });
272
- }
273
- };
274
- }
275
-
276
- // src/node/vite.ts
277
- import { createServer } from "vite";
278
- async function createViteServer(rootConfig, options) {
279
- const rootDir = rootConfig.rootDir;
280
- const viteConfig = rootConfig.vite || {};
281
- let hmrOptions = viteConfig.server?.hmr;
282
- if (options?.hmr === false) {
283
- hmrOptions = false;
284
- } else if (typeof hmrOptions === "undefined" && options?.port) {
285
- hmrOptions = { port: options.port + 10 };
286
- }
287
- const viteServer = await createServer({
288
- ...viteConfig,
289
- mode: "development",
290
- root: rootDir,
291
- // publicDir is disabled from the vite dev server since it's handled by the
292
- // root dev server directly, which allows user middlewares to override
293
- // files in the public dir.
294
- publicDir: false,
295
- server: {
296
- ...viteConfig.server || {},
297
- middlewareMode: true,
298
- hmr: hmrOptions
299
- },
300
- appType: "custom",
301
- optimizeDeps: {
302
- // As of vite v5 / esbuild v19, experimentalDecorators need to be
303
- // explicitly set, and for some reason this option isn't read from the
304
- // project's tsconfig.json file by default.
305
- // See: https://vitejs.dev/blog/announcing-vite5
306
- esbuildOptions: {
307
- tsconfigRaw: {
308
- compilerOptions: {
309
- target: "esnext",
310
- experimentalDecorators: true,
311
- useDefineForClassFields: false
312
- }
313
- }
314
- },
315
- ...viteConfig.optimizeDeps || {},
316
- include: [
317
- ...options?.optimizeDeps || [],
318
- ...viteConfig.optimizeDeps?.include || []
319
- ],
320
- extensions: [...viteConfig.optimizeDeps?.extensions || [], ".tsx"]
321
- },
322
- ssr: {
323
- ...viteConfig.ssr || {},
324
- noExternal: ["@blinkk/root", "@blinkk/root-cms/richtext"]
325
- },
326
- esbuild: {
327
- ...viteConfig.esbuild || {},
328
- jsx: "automatic",
329
- jsxImportSource: "preact"
330
- },
331
- plugins: [
332
- hmrSSRReload(),
333
- ...viteConfig.plugins || [],
334
- ...getVitePlugins(rootConfig.plugins || [])
335
- ]
336
- });
337
- return viteServer;
338
- }
339
- async function viteSsrLoadModule(rootConfig, file) {
340
- const viteServer = await createViteServer(rootConfig, { hmr: false });
341
- const module = await viteServer.ssrLoadModule(file);
342
- await viteServer.close();
343
- return module;
344
- }
345
- function hmrSSRReload() {
346
- return {
347
- name: "hmr-ssr-reload",
348
- enforce: "post",
349
- hotUpdate: {
350
- order: "post",
351
- handler({ modules, server, timestamp }) {
352
- if (this.environment.name !== "ssr") {
353
- return;
354
- }
355
- let hasSsrOnlyModules = false;
356
- const invalidatedModules = /* @__PURE__ */ new Set();
357
- for (const mod of modules) {
358
- if (mod.id === null) {
359
- continue;
360
- }
361
- const clientModule = server.environments.client.moduleGraph.getModuleById(mod.id);
362
- if (clientModule) {
363
- continue;
364
- }
365
- hasSsrOnlyModules = true;
366
- this.environment.moduleGraph.invalidateModule(
367
- mod,
368
- invalidatedModules,
369
- timestamp,
370
- true
371
- );
372
- }
373
- if (hasSsrOnlyModules) {
374
- server.ws.send({ type: "full-reload" });
375
- return [];
376
- }
377
- return;
378
- }
379
- }
380
- };
381
- }
382
-
383
- export {
384
- isJsFile,
385
- writeFile,
386
- makeDir,
387
- copyDir,
388
- copyGlob,
389
- rmDir,
390
- loadJson,
391
- writeJson,
392
- isDirectory,
393
- fileExists,
394
- dirExists,
395
- directoryContains,
396
- loadPackageJson,
397
- getMonorepoPackageDeps,
398
- flattenPackageDepsFromMonorepo,
399
- loadRootConfig,
400
- loadRootConfigWithDeps,
401
- bundleRootConfig,
402
- loadBundledConfig,
403
- createViteServer,
404
- viteSsrLoadModule
405
- };
406
- //# sourceMappingURL=chunk-ISNB54FM.js.map