@gracile/engine 0.9.0-next.7 → 0.9.1-next.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/dist/plugin.d.ts.map +1 -1
  2. package/dist/plugin.js +25 -16
  3. package/dist/render/route-template.d.ts.map +1 -1
  4. package/dist/render/route-template.js +27 -6
  5. package/dist/routes/load-module.d.ts.map +1 -1
  6. package/dist/routes/load-module.js +5 -2
  7. package/dist/routes/render.d.ts.map +1 -1
  8. package/dist/routes/render.js +9 -8
  9. package/dist/vite/build-routes.d.ts +1 -2
  10. package/dist/vite/build-routes.d.ts.map +1 -1
  11. package/dist/vite/build-routes.js +0 -98
  12. package/dist/vite/plugin-build-environment.d.ts +21 -0
  13. package/dist/vite/plugin-build-environment.d.ts.map +1 -0
  14. package/dist/vite/plugin-build-environment.js +83 -0
  15. package/dist/vite/plugin-client-build.d.ts +7 -3
  16. package/dist/vite/plugin-client-build.d.ts.map +1 -1
  17. package/dist/vite/plugin-client-build.js +10 -14
  18. package/dist/vite/plugin-html-routes-build.d.ts +22 -0
  19. package/dist/vite/plugin-html-routes-build.d.ts.map +1 -0
  20. package/dist/vite/plugin-html-routes-build.js +140 -0
  21. package/dist/vite/plugin-serve.d.ts.map +1 -1
  22. package/dist/vite/plugin-serve.js +1 -2
  23. package/dist/vite/plugin-server-build.d.ts +22 -12
  24. package/dist/vite/plugin-server-build.d.ts.map +1 -1
  25. package/dist/vite/plugin-server-build.js +22 -71
  26. package/dist/vite/plugin-shared-state.d.ts +2 -0
  27. package/dist/vite/plugin-shared-state.d.ts.map +1 -1
  28. package/dist/vite/plugin-shared-state.js +1 -0
  29. package/dist/vite/virtual-routes.d.ts +8 -5
  30. package/dist/vite/virtual-routes.d.ts.map +1 -1
  31. package/dist/vite/virtual-routes.js +32 -31
  32. package/package.json +5 -5
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAetD;;;;;;;;;;;;;;;;GAgBG;AAIH,eAAO,MAAM,OAAO,GAAI,SAAS,aAAa,KAAG,GAAG,EAoEnD,CAAC;AAEF,YAAY,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC"}
1
+ {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAsBtD;;;;;;;;;;;;;;;;GAgBG;AAIH,eAAO,MAAM,OAAO,GAAI,SAAS,aAAa,KAAG,GAAG,EA2EnD,CAAC;AAEF,YAAY,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC"}
package/dist/plugin.js CHANGED
@@ -2,12 +2,18 @@ import { createLogger } from '@gracile/internal-utils/logger/helpers';
2
2
  import { getPluginContext, } from '@gracile/internal-utils/plugin-context';
3
3
  import { htmlRoutesLoader } from './vite/html-routes.js';
4
4
  import { hmrSsrReload } from './vite/hmr.js';
5
- import { virtualRoutesClient } from './vite/virtual-routes.js';
5
+ import { virtualRoutesClient, virtualRoutes } from './vite/virtual-routes.js';
6
6
  import { createPluginSharedState } from './vite/plugin-shared-state.js';
7
7
  import { gracileServePlugin } from './vite/plugin-serve.js';
8
8
  import { gracileClientBuildPlugin } from './vite/plugin-client-build.js';
9
- import { gracileCollectClientAssetsPlugin, gracileServerBuildPlugin, } from './vite/plugin-server-build.js';
9
+ import { gracileBuildEnvironmentPlugin } from './vite/plugin-build-environment.js';
10
+ import { gracileCollectClientAssetsPlugin, gracileEntrypointPlugin, gracileMoveServerAssetsPlugin, } from './vite/plugin-server-build.js';
10
11
  import { gracileCETrackerPlugin } from './vite/plugin-ce-tracker.js';
12
+ import { gracileHtmlRoutesBuildPlugins } from './vite/plugin-html-routes-build.js';
13
+ // When plugin-client-build creates a temporary dev server via createServer(),
14
+ // the user's vite.config is re-evaluated, calling gracile() again.
15
+ // This guard prevents that re-entrant call from initializing the full plugin set.
16
+ // Reset in configureServer so dev-mode config hot-reloads still work.
11
17
  let isClientBuilt = false;
12
18
  /**
13
19
  * The main Vite plugin for loading the Gracile framework.
@@ -32,8 +38,6 @@ let isClientBuilt = false;
32
38
  export const gracile = (config) => {
33
39
  const logger = createLogger();
34
40
  const state = createPluginSharedState(config);
35
- // HACK: Prevent duplicate client build for the SSR build step in server mode.
36
- // TODO: Move to the new, clean, environments builders API.
37
41
  if (isClientBuilt)
38
42
  return [];
39
43
  isClientBuilt = true;
@@ -54,11 +58,11 @@ export const gracile = (config) => {
54
58
  sharedPluginContext.litSsrRenderInfo;
55
59
  },
56
60
  },
57
- // MARK: 1.5. CE registry tracker (dev HMR cleanup)
61
+ // MARK: 2. CE registry tracker (dev HMR cleanup)
58
62
  gracileCETrackerPlugin(),
59
- // MARK: 2. HMR SSR reload
63
+ // MARK: 3. HMR SSR reload
60
64
  hmrSsrReload(),
61
- // MARK: 3. Dev serve middleware
65
+ // MARK: 4. Dev serve middleware
62
66
  gracileServePlugin({
63
67
  state,
64
68
  config,
@@ -67,21 +71,26 @@ export const gracile = (config) => {
67
71
  isClientBuilt = false;
68
72
  },
69
73
  }),
70
- // MARK: 4. Client virtual routes
74
+ // MARK: 5. Client virtual routes
71
75
  virtualRoutesForClient,
72
- // MARK: 5. HTML routes loader
76
+ // MARK: 6. HTML routes loader
73
77
  htmlRoutesLoader(),
74
- // MARK: 6. Client build
78
+ // MARK: 7. Client build (route rendering → populates shared state)
75
79
  gracileClientBuildPlugin({
76
80
  state,
77
81
  virtualRoutesForClient,
78
82
  }),
79
- // MARK: 7. Collect client assets for server
83
+ // MARK: 8. HTML route resolution + asset collection (client build only)
84
+ ...gracileHtmlRoutesBuildPlugins({ state }),
85
+ // MARK: 9. Build environment configuration (consumes shared state)
86
+ gracileBuildEnvironmentPlugin({ state }),
87
+ // MARK: 9. Collect client assets for server
80
88
  gracileCollectClientAssetsPlugin({ state }),
81
- // MARK: 8. Server build (nested)
82
- gracileServerBuildPlugin({
83
- state,
84
- virtualRoutesForClient,
85
- }),
89
+ // MARK: 10. Server virtual routes (SSR environment only)
90
+ ...virtualRoutes({ state }),
91
+ // MARK: 11. Server entrypoint (SSR environment only)
92
+ gracileEntrypointPlugin({ state }),
93
+ // MARK: 12. Move server assets (SSR environment only)
94
+ gracileMoveServerAssetsPlugin({ state }),
86
95
  ];
87
96
  };
@@ -1 +1 @@
1
- {"version":3,"file":"route-template.d.ts","sourceRoot":"","sources":["../../src/render/route-template.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAIvC,OAAO,EAA0B,KAAK,UAAU,EAAE,MAAM,eAAe,CAAC;AAOxE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,MAAM,CAAC;AAO1C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,KAAK,KAAK,CAAC,MAAM,oBAAoB,CAAC;AAa7C,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAEhF,wBAAsB,mBAAmB,CAAC,EACzC,GAAG,EACH,IAAI,EACJ,IAAI,EACJ,UAAU,EACV,WAAW,EACX,UAAU,EACV,OAAO,EACP,UAAU,GACV,EAAE;IACF,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,aAAa,GAAG,SAAS,CAAC;IACjC,IAAI,EAAE,KAAK,GAAG,OAAO,CAAC;IACtB,UAAU,EAAE,UAAU,CAAC;IACvB,WAAW,CAAC,EAAE,CAAC,CAAC,YAAY,GAAG,SAAS,CAAC;IACzC,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACjC,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC9B,UAAU,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,GAAG,SAAS,CAAC;CAC7C,GAAG,OAAO,CAAC;IAAE,MAAM,EAAE,IAAI,GAAG,QAAQ,CAAC;IAAC,QAAQ,EAAE,IAAI,GAAG,MAAM,CAAA;CAAE,CAAC,CA4JhE"}
1
+ {"version":3,"file":"route-template.d.ts","sourceRoot":"","sources":["../../src/render/route-template.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAIvC,OAAO,EAA0B,KAAK,UAAU,EAAE,MAAM,eAAe,CAAC;AAOxE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,MAAM,CAAC;AAO1C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,KAAK,KAAK,CAAC,MAAM,oBAAoB,CAAC;AAa7C,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AA0BhF,wBAAsB,mBAAmB,CAAC,EACzC,GAAG,EACH,IAAI,EACJ,IAAI,EACJ,UAAU,EACV,WAAW,EACX,UAAU,EACV,OAAO,EACP,UAAU,GACV,EAAE;IACF,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,aAAa,GAAG,SAAS,CAAC;IACjC,IAAI,EAAE,KAAK,GAAG,OAAO,CAAC;IACtB,UAAU,EAAE,UAAU,CAAC;IACvB,WAAW,CAAC,EAAE,CAAC,CAAC,YAAY,GAAG,SAAS,CAAC;IACzC,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACjC,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC9B,UAAU,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,GAAG,SAAS,CAAC;CAC7C,GAAG,OAAO,CAAC;IAAE,MAAM,EAAE,IAAI,GAAG,QAAQ,CAAC;IAAC,QAAQ,EAAE,IAAI,GAAG,MAAM,CAAA;CAAE,CAAC,CAwJhE"}
@@ -2,11 +2,36 @@ import { Readable } from 'node:stream';
2
2
  import * as assert from '@gracile/internal-utils/assertions';
3
3
  import { render as renderLitSsr } from '@lit-labs/ssr';
4
4
  import { collectResult } from '@lit-labs/ssr/lib/render-result.js';
5
+ // Lit's purpose-built Readable subclass for RenderResult. Handles nested
6
+ // iterables, thunks, and Promises from sub-templates with proper back-pressure,
7
+ // whereas generic `Readable.from()` only sees the top-level iterable.
8
+ // Inherits from the same Node `Readable` we already depend on.
9
+ import { RenderResultReadable } from '@lit-labs/ssr/lib/render-result-readable.js';
5
10
  import { GracileError, GracileErrorData, TemplateError, } from '../errors/errors.js';
6
11
  import { SSR_OUTLET_MARKER } from './markers.js';
7
12
  import { concatStreams, mergeRenderInfo, injectSiblingAssets, ensureDoctype, injectDevelopmentOverlay, injectServerAssets, } from './route-template-pipeline.js';
8
13
  // Re-export for consumers that import these regexes from this module.
9
14
  export { REGEX_TAG_SCRIPT, REGEX_TAG_LINK } from './route-template-pipeline.js';
15
+ /**
16
+ * Lit SSR's `RenderResultReadable._read()` is `async`, but Node.js
17
+ * calls `_read()` without awaiting its return value. If a thunk inside
18
+ * the render result throws (e.g. template expressions in invalid
19
+ * locations), the rejected Promise escapes and becomes an
20
+ * `unhandledRejection`.
21
+ *
22
+ * This subclass overrides `_read()` to catch that rejection and convert
23
+ * it into a stream `'error'` event via `this.destroy(err)`, which is
24
+ * the standard Node Readable contract.
25
+ */
26
+ class SafeRenderResultReadable extends RenderResultReadable {
27
+ _read(size) {
28
+ const maybePromise = super._read(size);
29
+ void maybePromise?.catch?.((error) => {
30
+ this.destroy(error);
31
+ });
32
+ return maybePromise;
33
+ }
34
+ }
10
35
  export async function renderRouteTemplate({ url, vite, mode, routeInfos, routeAssets, serverMode, docOnly, renderInfo, }) {
11
36
  const location = {
12
37
  file: routeInfos.foundRoute.filePath,
@@ -31,10 +56,7 @@ export async function renderRouteTemplate({ url, vite, mode, routeInfos, routeAs
31
56
  // location,
32
57
  });
33
58
  const fragmentRender = renderLitSsr(fragmentOutput, mergedRenderInfo);
34
- const output = Readable.from(fragmentRender);
35
- // TODO: Disabled for now. Causes issue in static renders.
36
- // Needs investigations.
37
- // const output = new RenderResultReadable(fragmentRender);
59
+ const output = new SafeRenderResultReadable(fragmentRender);
38
60
  return { output, document: null };
39
61
  }
40
62
  // MARK: Document
@@ -90,8 +112,7 @@ export async function renderRouteTemplate({ url, vite, mode, routeInfos, routeAs
90
112
  const routeOutput = await Promise.resolve(routeInfos.routeModule.template(context));
91
113
  if (assert.isLitTemplate(routeOutput) === false)
92
114
  throw new Error(`Wrong template result for page template ${routeInfos.foundRoute.filePath}.`);
93
- const renderStream =
94
- /* TODO: Use `new RenderResultReadable` */ Readable.from(renderLitSsr(routeOutput, mergedRenderInfo));
115
+ const renderStream = new SafeRenderResultReadable(renderLitSsr(routeOutput, mergedRenderInfo));
95
116
  const output = Readable.from(concatStreams(baseDocumentRenderStreamPre, renderStream, baseDocumentRenderStreamPost));
96
117
  return { output, document: baseDocumentHtml };
97
118
  }
@@ -1 +1 @@
1
- {"version":3,"file":"load-module.d.ts","sourceRoot":"","sources":["../../src/routes/load-module.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,MAAM,CAAC;AAI1C,OAAO,KAAK,CAAC,MAAM,YAAY,CAAC;AAGhC,eAAO,MAAM,OAAO;;;;;;CASnB,CAAC;AAQF,wBAAsB,sBAAsB,CAAC,EAC5C,IAAI,EACJ,KAAK,EACL,YAAY,GACZ,EAAE;IACF,IAAI,CAAC,EAAE,aAAa,GAAG,SAAS,CAAC;IACjC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC;IACf,YAAY,CAAC,EAAE,CAAC,CAAC,aAAa,GAAG,SAAS,CAAC;CAC3C,0BA2CA"}
1
+ {"version":3,"file":"load-module.d.ts","sourceRoot":"","sources":["../../src/routes/load-module.ts"],"names":[],"mappings":"AAKA,OAAO,EAA4B,KAAK,aAAa,EAAE,MAAM,MAAM,CAAC;AAIpE,OAAO,KAAK,CAAC,MAAM,YAAY,CAAC;AAGhC,eAAO,MAAM,OAAO;;;;;;CASnB,CAAC;AAQF,wBAAsB,sBAAsB,CAAC,EAC5C,IAAI,EACJ,KAAK,EACL,YAAY,GACZ,EAAE;IACF,IAAI,CAAC,EAAE,aAAa,GAAG,SAAS,CAAC;IACjC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC;IACf,YAAY,CAAC,EAAE,CAAC,CAAC,aAAa,GAAG,SAAS,CAAC;CAC3C,0BAgDA"}
@@ -2,7 +2,7 @@ import { join } from 'node:path';
2
2
  import { pathToFileURL } from 'node:url';
3
3
  import { collectErrorMetadata } from '@gracile-labs/better-errors/dev/utils';
4
4
  import { enhanceViteSSRError } from '@gracile-labs/better-errors/dev/vite';
5
- import {} from 'vite';
5
+ import { isRunnableDevEnvironment } from 'vite';
6
6
  import { GracileError, GracileErrorData } from '../errors/errors.js';
7
7
  import * as R from './route.js';
8
8
  // const ROUTE_SPREAD = /^\.{3}.+$/;
@@ -24,7 +24,10 @@ export async function loadForeignRouteObject({ vite, route, routeImports, }) {
24
24
  let unknownRouteModule;
25
25
  if (vite) {
26
26
  try {
27
- unknownRouteModule = await vite.ssrLoadModule(route.filePath, {});
27
+ const ssrEnvironment = vite.environments.ssr;
28
+ if (!isRunnableDevEnvironment(ssrEnvironment))
29
+ throw new Error('Not in a SSR path');
30
+ unknownRouteModule = await ssrEnvironment.runner.import(route.filePath);
28
31
  }
29
32
  catch (error) {
30
33
  const error_ = error;
@@ -1 +1 @@
1
- {"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../src/routes/render.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,MAAM,CAAC;AAG1C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAIvD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,MAAM,WAAW,uBAAuB;IACvC,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAEpB,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB,MAAM,EAAE;QACP,KAAK,EAAE,OAAO,CAAC;QACf,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;KACxB,CAAC;IAEF,aAAa,EAAE,OAAO,GAAG,IAAI,CAAC;CAC9B;AAwBD,wBAAsB,YAAY,CAAC,EAClC,MAAM,EACN,IAAI,EACJ,UAAU,EACV,IAAoB,EACpB,aAAa,GACb,EAAE;IACF,MAAM,EAAE,cAAc,CAAC;IACvB,IAAI,EAAE,aAAa,CAAC;IACpB,UAAU,EAAE,OAAO,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,aAAa,CAAC;CAC7B;;;GAwKA"}
1
+ {"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../src/routes/render.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,MAAM,CAAC;AAG1C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAIvD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,MAAM,WAAW,uBAAuB;IACvC,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAEpB,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB,MAAM,EAAE;QACP,KAAK,EAAE,OAAO,CAAC;QACf,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;KACxB,CAAC;IAEF,aAAa,EAAE,OAAO,GAAG,IAAI,CAAC;CAC9B;AAsBD,wBAAsB,YAAY,CAAC,EAClC,MAAM,EACN,IAAI,EACJ,UAAU,EACV,IAAoB,EACpB,aAAa,GACb,EAAE;IACF,MAAM,EAAE,cAAc,CAAC;IACvB,IAAI,EAAE,aAAa,CAAC;IACpB,UAAU,EAAE,OAAO,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,aAAa,CAAC;CAC7B;;;GAwKA"}
@@ -8,18 +8,19 @@ import { loadForeignRouteObject } from './load-module.js';
8
8
  async function streamToString(stream) {
9
9
  const chunks = [];
10
10
  for await (const chunk of stream) {
11
- // NOTE: Since using Lit's `RenderResultReadable` instead of pure
12
- // Node Readable, the chunk can be a string or a Buffer.
13
- // If it's a string, convert it to Buffer first.
11
+ // `RenderResultReadable` always pushes strings (it resolves promises,
12
+ // thunks, and nested iterables internally). `Readable.from(string)`
13
+ // used for the document-only path also yields strings.
14
+ // Accept Buffer too for safety (plain `Readable` streams may emit them).
14
15
  if (typeof chunk === 'string') {
15
16
  chunks.push(Buffer.from(chunk));
16
17
  }
17
- else
18
- throw new TypeError('Wrong buffer type from stream. Should be a `string` only.');
19
- // NOTE: Disabled for now. Causes issues with `RenderResultReadable`.
20
- /* else {
18
+ else if (Buffer.isBuffer(chunk)) {
21
19
  chunks.push(chunk);
22
- } */
20
+ }
21
+ else {
22
+ throw new TypeError(`Unexpected chunk type in stream: ${typeof chunk}`);
23
+ }
23
24
  }
24
25
  return Buffer.concat(chunks).toString('utf8');
25
26
  }
@@ -1,4 +1,4 @@
1
- import { type Plugin, type ViteDevServer } from 'vite';
1
+ import { type ViteDevServer } from 'vite';
2
2
  import { type RenderedRouteDefinition } from '../routes/render.js';
3
3
  import type { RoutesManifest } from '../routes/route.js';
4
4
  import type { GracileConfig } from '../user-config.js';
@@ -12,6 +12,5 @@ export declare const buildRoutes: ({ routes, viteServerForBuild, root, gracileCo
12
12
  routes: RoutesManifest;
13
13
  renderedRoutes: RenderedRouteDefinition[];
14
14
  inputList: string[];
15
- plugin: Plugin[];
16
15
  }>;
17
16
  //# sourceMappingURL=build-routes.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"build-routes.d.ts","sourceRoot":"","sources":["../../src/vite/build-routes.ts"],"names":[],"mappings":"AAEA,OAAO,EAAgB,KAAK,MAAM,EAAE,KAAK,aAAa,EAAE,MAAM,MAAM,CAAC;AAErE,OAAO,EAEN,KAAK,uBAAuB,EAC5B,MAAM,qBAAqB,CAAC;AAE7B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AASvD,eAAO,MAAM,WAAW,GAAU,kEAM/B;IACF,MAAM,EAAE,cAAc,CAAC;IACvB,kBAAkB,EAAE,aAAa,CAAC;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,aAAa,CAAC;IAC7B,UAAU,CAAC,EAAE,OAAO,CAAC;CACrB,KAAG,OAAO,CAAC;IACX,MAAM,EAAE,cAAc,CAAC;IACvB,cAAc,EAAE,uBAAuB,EAAE,CAAC;IAC1C,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,MAAM,EAAE,MAAM,EAAE,CAAC;CACjB,CA6JA,CAAC"}
1
+ {"version":3,"file":"build-routes.d.ts","sourceRoot":"","sources":["../../src/vite/build-routes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,KAAK,aAAa,EAAE,MAAM,MAAM,CAAC;AAExD,OAAO,EAEN,KAAK,uBAAuB,EAC5B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AASvD,eAAO,MAAM,WAAW,GAAU,kEAM/B;IACF,MAAM,EAAE,cAAc,CAAC;IACvB,kBAAkB,EAAE,aAAa,CAAC;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,aAAa,CAAC;IAC7B,UAAU,CAAC,EAAE,OAAO,CAAC;CACrB,KAAG,OAAO,CAAC;IACX,MAAM,EAAE,cAAc,CAAC;IACvB,cAAc,EAAE,uBAAuB,EAAE,CAAC;IAC1C,SAAS,EAAE,MAAM,EAAE,CAAC;CACpB,CAkCA,CAAC"}
@@ -1,7 +1,5 @@
1
- import { basename, extname, join } from 'node:path';
2
1
  import { createFilter } from 'vite';
3
2
  import { renderRoutes, } from '../routes/render.js';
4
- import { REGEX_TAG_LINK, REGEX_TAG_SCRIPT } from '../render/route-template.js';
5
3
  function stripPremises(input) {
6
4
  return input
7
5
  .replace(/index\.html$/, '__index.doc.html')
@@ -9,7 +7,6 @@ function stripPremises(input) {
9
7
  .replace(/500\.html$/, '__500.doc.html');
10
8
  }
11
9
  export const buildRoutes = async ({ routes, viteServerForBuild, root, gracileConfig, serverMode = false, }) => {
12
- // TODO: extract upstream, return just the plugins
13
10
  const { renderedRoutes } = await renderRoutes({
14
11
  vite: viteServerForBuild,
15
12
  serverMode,
@@ -35,100 +32,5 @@ export const buildRoutes = async ({ routes, viteServerForBuild, root, gracileCon
35
32
  routes,
36
33
  renderedRoutes,
37
34
  inputList,
38
- plugin: [
39
- {
40
- name: 'gracile-html-routes',
41
- apply: 'build',
42
- enforce: 'pre',
43
- resolveId(id) {
44
- if (extname(id) === '.html' && inputList.includes(id))
45
- return join(root, id);
46
- return null;
47
- },
48
- load(id) {
49
- if (extname(id) === '.html') {
50
- if (['index.html', '404.html', '500.html'].includes(basename(id))) {
51
- const content = renderedRoutes.find((index) => index.absoluteId === id)?.html;
52
- if (content)
53
- return content;
54
- }
55
- if (gracileConfig.pages?.premises?.expose) {
56
- if (basename(id).endsWith('doc.html')) {
57
- const content = renderedRoutes.find((index) => stripPremises(index.absoluteId) === id)?.static.document;
58
- if (content)
59
- return content;
60
- }
61
- const content = renderedRoutes.find((index) => index.name === basename(id))?.html;
62
- if (content)
63
- return content;
64
- // return '';}
65
- }
66
- }
67
- return null;
68
- },
69
- },
70
- {
71
- name: 'gracile-collect-handler-assets',
72
- enforce: 'post',
73
- buildStart() {
74
- if (!gracileConfig.pages?.premises?.expose || !premisesFilter)
75
- return;
76
- for (const route of renderedRoutes) {
77
- if (premisesFilter(route.name) === false)
78
- continue;
79
- if (serverMode && route.savePrerender !== true)
80
- continue;
81
- const fileNameParts = route.name.split('/');
82
- const last = fileNameParts.pop();
83
- const properties = last?.replace(/(.*)\.html$/, (_, r) => `__${r}.props.json`);
84
- if (!properties)
85
- throw new Error('No props.');
86
- fileNameParts.push(properties);
87
- const fileName = fileNameParts.join('/');
88
- this.emitFile({
89
- fileName,
90
- type: 'asset',
91
- source: JSON.stringify(route.static.props ?? {}),
92
- });
93
- }
94
- },
95
- generateBundle(_, bundle) {
96
- if (serverMode === false)
97
- return;
98
- for (const fileKey in bundle) {
99
- const file = bundle[fileKey];
100
- if (fileKey.endsWith('.html') && file && 'source' in file) {
101
- const source = file.source.toString();
102
- const collectedAssets = [
103
- ...[...source.matchAll(REGEX_TAG_SCRIPT)]
104
- .map((v) => v[0])
105
- // NOTE: Too brittle
106
- .filter((v) => v.includes(`type="module"`)),
107
- ...[...source.matchAll(REGEX_TAG_LINK)]
108
- .map((v) => v[0])
109
- // NOTE: Too brittle
110
- .filter((v) => /rel="(stylesheet|modulepreload)"/.test(v)),
111
- ].join('\n');
112
- // NOTE: Not used (for now?)
113
- // file.source = alteredContent;
114
- const route = renderedRoutes.find((r) => {
115
- if (gracileConfig.pages?.premises?.expose)
116
- return (`/${r.name}` ===
117
- `/${fileKey}`.replace(/(.*?)\/__(.*?)\.doc\.html$/, (a, b, c) => `${b}/${c}.html`));
118
- return r.name === fileKey;
119
- });
120
- if (route)
121
- route.handlerAssets = collectedAssets;
122
- if (route?.savePrerender !== true) {
123
- delete bundle[fileKey];
124
- // NOTE: Not sure if it's useful
125
- if (route?.html)
126
- route.html = null;
127
- }
128
- }
129
- }
130
- },
131
- },
132
- ],
133
35
  };
134
36
  };
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Vite plugin: build environment configuration.
3
+ *
4
+ * Owns all Environment API concerns for builds:
5
+ * - Top-level config: `builder.sharedConfigBuild`, `ssr.external` (server mode)
6
+ * - `configEnvironment('client')`: rollupOptions.input, outDir
7
+ * - `configEnvironment('ssr')`: outDir, SSR-specific build options, rollupOptions
8
+ * - `buildApp()`: orchestrates build order (client-only or client → SSR)
9
+ *
10
+ * `rollupOptions.input` must be set via `configEnvironment` (not the
11
+ * top-level `config` hook) because `builder.build(env)` uses
12
+ * environment-resolved config, not the top-level config.
13
+ *
14
+ * @internal
15
+ */
16
+ import type { PluginOption } from 'vite';
17
+ import type { PluginSharedState } from './plugin-shared-state.js';
18
+ export declare function gracileBuildEnvironmentPlugin({ state, }: {
19
+ state: PluginSharedState;
20
+ }): PluginOption;
21
+ //# sourceMappingURL=plugin-build-environment.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin-build-environment.d.ts","sourceRoot":"","sources":["../../src/vite/plugin-build-environment.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAIH,OAAO,KAAK,EAAE,YAAY,EAAe,MAAM,MAAM,CAAC;AAEtD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAElE,wBAAgB,6BAA6B,CAAC,EAC7C,KAAK,GACL,EAAE;IACF,KAAK,EAAE,iBAAiB,CAAC;CACzB,GAAG,YAAY,CA4Ef"}
@@ -0,0 +1,83 @@
1
+ /**
2
+ * Vite plugin: build environment configuration.
3
+ *
4
+ * Owns all Environment API concerns for builds:
5
+ * - Top-level config: `builder.sharedConfigBuild`, `ssr.external` (server mode)
6
+ * - `configEnvironment('client')`: rollupOptions.input, outDir
7
+ * - `configEnvironment('ssr')`: outDir, SSR-specific build options, rollupOptions
8
+ * - `buildApp()`: orchestrates build order (client-only or client → SSR)
9
+ *
10
+ * `rollupOptions.input` must be set via `configEnvironment` (not the
11
+ * top-level `config` hook) because `builder.build(env)` uses
12
+ * environment-resolved config, not the top-level config.
13
+ *
14
+ * @internal
15
+ */
16
+ import { join } from 'node:path';
17
+ export function gracileBuildEnvironmentPlugin({ state, }) {
18
+ const isServerMode = state.outputMode === 'server';
19
+ return {
20
+ name: 'vite-plugin-gracile-build-env',
21
+ apply: 'build',
22
+ config() {
23
+ return {
24
+ ...(isServerMode ? { ssr: { external: ['@gracile/gracile'] } } : {}),
25
+ builder: { sharedConfigBuild: true },
26
+ };
27
+ },
28
+ configEnvironment(name, config) {
29
+ if (name === 'client') {
30
+ if (!state.clientBuildInputList)
31
+ return null;
32
+ return {
33
+ build: {
34
+ rollupOptions: {
35
+ input: state.clientBuildInputList,
36
+ },
37
+ outDir: join(config.build?.outDir || 'dist', isServerMode ? 'client' : ''),
38
+ },
39
+ };
40
+ }
41
+ if (name === 'ssr' && isServerMode) {
42
+ return {
43
+ build: {
44
+ outDir: 'dist/server',
45
+ copyPublicDir: false,
46
+ ssrEmitAssets: true,
47
+ cssMinify: true,
48
+ cssCodeSplit: true,
49
+ rollupOptions: {
50
+ input: 'entrypoint.js',
51
+ output: {
52
+ entryFileNames: '[name].js',
53
+ assetFileNames: (chunkInfo) => {
54
+ if (chunkInfo.name) {
55
+ const fileName = state.clientAssets[chunkInfo.name];
56
+ if (fileName)
57
+ return fileName;
58
+ return `assets/${chunkInfo.name.replace(/\.(.*)$/, '')}-[hash].[ext]`;
59
+ }
60
+ return 'assets/[name]-[hash].[ext]';
61
+ },
62
+ chunkFileNames: 'chunk/[name].js',
63
+ },
64
+ },
65
+ },
66
+ };
67
+ }
68
+ return null;
69
+ },
70
+ async buildApp(builder) {
71
+ const client = builder.environments['client'];
72
+ if (!client)
73
+ throw new Error('Missing client build environment.');
74
+ await builder.build(client);
75
+ if (isServerMode) {
76
+ const ssr = builder.environments['ssr'];
77
+ if (!ssr)
78
+ throw new Error('Missing ssr build environment.');
79
+ await builder.build(ssr);
80
+ }
81
+ },
82
+ };
83
+ }
@@ -1,9 +1,13 @@
1
1
  /**
2
- * Vite plugin: client-side build configuration.
2
+ * Vite plugin: client-side build route rendering.
3
3
  *
4
4
  * During `vite build`, this spins up a temporary dev server to render
5
- * all routes into static HTML, then configures Rollup with the
6
- * generated HTML pages as inputs.
5
+ * all routes into static HTML, then populates shared state with the
6
+ * rendered routes and input list.
7
+ *
8
+ * The actual HTML route resolution and asset collection are handled by
9
+ * separate Vite plugins (see `plugin-html-routes-build.ts`) that read
10
+ * from shared state and use `applyToEnvironment` to scope to the client.
7
11
  *
8
12
  * @internal
9
13
  */
@@ -1 +1 @@
1
- {"version":3,"file":"plugin-client-build.d.ts","sourceRoot":"","sources":["../../src/vite/plugin-client-build.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAKH,OAAO,EAAgB,KAAK,YAAY,EAAE,MAAM,MAAM,CAAC;AAGvD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAElE,wBAAgB,wBAAwB,CAAC,EACxC,KAAK,EACL,sBAAsB,GACtB,EAAE;IACF,KAAK,EAAE,iBAAiB,CAAC;IACzB,sBAAsB,EAAE,YAAY,CAAC;CACrC,GAAG,YAAY,CA+Df"}
1
+ {"version":3,"file":"plugin-client-build.d.ts","sourceRoot":"","sources":["../../src/vite/plugin-client-build.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,EAAgB,KAAK,YAAY,EAAE,MAAM,MAAM,CAAC;AAGvD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAElE,wBAAgB,wBAAwB,CAAC,EACxC,KAAK,EACL,sBAAsB,GACtB,EAAE;IACF,KAAK,EAAE,iBAAiB,CAAC;IACzB,sBAAsB,EAAE,YAAY,CAAC;CACrC,GAAG,YAAY,CAoDf"}
@@ -1,13 +1,16 @@
1
1
  /**
2
- * Vite plugin: client-side build configuration.
2
+ * Vite plugin: client-side build route rendering.
3
3
  *
4
4
  * During `vite build`, this spins up a temporary dev server to render
5
- * all routes into static HTML, then configures Rollup with the
6
- * generated HTML pages as inputs.
5
+ * all routes into static HTML, then populates shared state with the
6
+ * rendered routes and input list.
7
+ *
8
+ * The actual HTML route resolution and asset collection are handled by
9
+ * separate Vite plugins (see `plugin-html-routes-build.ts`) that read
10
+ * from shared state and use `applyToEnvironment` to scope to the client.
7
11
  *
8
12
  * @internal
9
13
  */
10
- import { join } from 'node:path';
11
14
  import { getPluginContext } from '@gracile/internal-utils/plugin-context';
12
15
  import { createServer } from 'vite';
13
16
  import { buildRoutes } from './build-routes.js';
@@ -16,8 +19,9 @@ export function gracileClientBuildPlugin({ state, virtualRoutesForClient, }) {
16
19
  name: 'vite-plugin-gracile-build',
17
20
  apply: 'build',
18
21
  async config(viteConfig) {
22
+ state.root = viteConfig.root || process.cwd();
19
23
  const viteServerForClientHtmlBuild = await createServer({
20
- root: viteConfig.root || process.cwd(),
24
+ root: state.root,
21
25
  server: { middlewareMode: true },
22
26
  // NOTE: Stub. KEEP IT!
23
27
  optimizeDeps: { include: [] },
@@ -34,6 +38,7 @@ export function gracileClientBuildPlugin({ state, virtualRoutesForClient, }) {
34
38
  routes: state.routes,
35
39
  });
36
40
  state.renderedRoutes = htmlPages.renderedRoutes;
41
+ state.clientBuildInputList = htmlPages.inputList;
37
42
  // NOTE: Vite's dev server does not invoke Rollup's `closeWatcher`
38
43
  // hook when shutting down. Plugins like @rollup/plugin-typescript
39
44
  // use `ts.createWatchProgram()` which sets up hundreds of FS
@@ -45,15 +50,6 @@ export function gracileClientBuildPlugin({ state, virtualRoutesForClient, }) {
45
50
  }
46
51
  }
47
52
  await viteServerForClientHtmlBuild.close();
48
- return {
49
- build: {
50
- rollupOptions: {
51
- input: htmlPages.inputList,
52
- plugins: [htmlPages.plugin],
53
- },
54
- outDir: join(viteConfig.build?.outDir || 'dist', state.outputMode === 'server' ? 'client' : ''),
55
- },
56
- };
57
53
  },
58
54
  };
59
55
  }
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Vite plugins: HTML route resolution and asset collection for builds.
3
+ *
4
+ * These are registered as Vite plugins (not Rollup plugins via
5
+ * `rollupOptions.plugins`) so they work correctly with the Environment
6
+ * API's `builder.build(env)`, which does not inherit top-level
7
+ * `rollupOptions` into environment builds.
8
+ *
9
+ * They use `applyToEnvironment` to scope to the client build only,
10
+ * preventing the SSR build from trying to resolve HTML entries.
11
+ *
12
+ * Data is read lazily from shared state, which is populated by the
13
+ * client build plugin's `config` hook before these hooks run.
14
+ *
15
+ * @internal
16
+ */
17
+ import { type PluginOption } from 'vite';
18
+ import type { PluginSharedState } from './plugin-shared-state.js';
19
+ export declare function gracileHtmlRoutesBuildPlugins({ state, }: {
20
+ state: PluginSharedState;
21
+ }): PluginOption[];
22
+ //# sourceMappingURL=plugin-html-routes-build.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin-html-routes-build.d.ts","sourceRoot":"","sources":["../../src/vite/plugin-html-routes-build.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAIH,OAAO,EAAgB,KAAK,YAAY,EAAE,MAAM,MAAM,CAAC;AAIvD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AASlE,wBAAgB,6BAA6B,CAAC,EAC7C,KAAK,GACL,EAAE;IACF,KAAK,EAAE,iBAAiB,CAAC;CACzB,GAAG,YAAY,EAAE,CAiJjB"}
@@ -0,0 +1,140 @@
1
+ /**
2
+ * Vite plugins: HTML route resolution and asset collection for builds.
3
+ *
4
+ * These are registered as Vite plugins (not Rollup plugins via
5
+ * `rollupOptions.plugins`) so they work correctly with the Environment
6
+ * API's `builder.build(env)`, which does not inherit top-level
7
+ * `rollupOptions` into environment builds.
8
+ *
9
+ * They use `applyToEnvironment` to scope to the client build only,
10
+ * preventing the SSR build from trying to resolve HTML entries.
11
+ *
12
+ * Data is read lazily from shared state, which is populated by the
13
+ * client build plugin's `config` hook before these hooks run.
14
+ *
15
+ * @internal
16
+ */
17
+ import { basename, extname, join } from 'node:path';
18
+ import { createFilter } from 'vite';
19
+ import { REGEX_TAG_LINK, REGEX_TAG_SCRIPT } from '../render/route-template.js';
20
+ function stripPremises(input) {
21
+ return input
22
+ .replace(/index\.html$/, '__index.doc.html')
23
+ .replace(/404\.html$/, '__404.doc.html')
24
+ .replace(/500\.html$/, '__500.doc.html');
25
+ }
26
+ export function gracileHtmlRoutesBuildPlugins({ state, }) {
27
+ return [
28
+ {
29
+ name: 'gracile-html-routes',
30
+ apply: 'build',
31
+ enforce: 'pre',
32
+ applyToEnvironment(environment) {
33
+ return environment.name !== 'ssr';
34
+ },
35
+ resolveId(id) {
36
+ const inputList = state.clientBuildInputList;
37
+ const root = state.root;
38
+ if (!inputList || !root)
39
+ return null;
40
+ if (extname(id) === '.html' && inputList.includes(id))
41
+ return join(root, id);
42
+ return null;
43
+ },
44
+ load(id) {
45
+ const renderedRoutes = state.renderedRoutes;
46
+ if (!renderedRoutes)
47
+ return null;
48
+ if (extname(id) === '.html') {
49
+ if (['index.html', '404.html', '500.html'].includes(basename(id))) {
50
+ const content = renderedRoutes.find((index) => index.absoluteId === id)?.html;
51
+ if (content)
52
+ return content;
53
+ }
54
+ if (state.gracileConfig.pages?.premises?.expose) {
55
+ if (basename(id).endsWith('doc.html')) {
56
+ const content = renderedRoutes.find((index) => stripPremises(index.absoluteId) === id)?.static.document;
57
+ if (content)
58
+ return content;
59
+ }
60
+ const content = renderedRoutes.find((index) => index.name === basename(id))?.html;
61
+ if (content)
62
+ return content;
63
+ }
64
+ }
65
+ return null;
66
+ },
67
+ },
68
+ {
69
+ name: 'gracile-collect-handler-assets',
70
+ apply: 'build',
71
+ enforce: 'post',
72
+ applyToEnvironment(environment) {
73
+ return environment.name !== 'ssr';
74
+ },
75
+ buildStart() {
76
+ const renderedRoutes = state.renderedRoutes;
77
+ if (!renderedRoutes)
78
+ return;
79
+ if (!state.gracileConfig.pages?.premises?.expose)
80
+ return;
81
+ const premisesFilter = createFilter(state.gracileConfig.pages.premises.include, state.gracileConfig.pages.premises.exclude);
82
+ for (const route of renderedRoutes) {
83
+ if (premisesFilter(route.name) === false)
84
+ continue;
85
+ if (state.outputMode === 'server' && route.savePrerender !== true)
86
+ continue;
87
+ const fileNameParts = route.name.split('/');
88
+ const last = fileNameParts.pop();
89
+ const properties = last?.replace(/(.*)\.html$/, (_, r) => `__${r}.props.json`);
90
+ if (!properties)
91
+ throw new Error('No props.');
92
+ fileNameParts.push(properties);
93
+ const fileName = fileNameParts.join('/');
94
+ this.emitFile({
95
+ fileName,
96
+ type: 'asset',
97
+ source: JSON.stringify(route.static.props ?? {}),
98
+ });
99
+ }
100
+ },
101
+ generateBundle(_, bundle) {
102
+ const renderedRoutes = state.renderedRoutes;
103
+ if (!renderedRoutes)
104
+ return;
105
+ if (state.outputMode !== 'server')
106
+ return;
107
+ for (const fileKey in bundle) {
108
+ const file = bundle[fileKey];
109
+ if (fileKey.endsWith('.html') && file && 'source' in file) {
110
+ const source = file.source.toString();
111
+ const collectedAssets = [
112
+ ...[...source.matchAll(REGEX_TAG_SCRIPT)]
113
+ .map((v) => v[0])
114
+ // NOTE: Too brittle
115
+ .filter((v) => v.includes(`type="module"`)),
116
+ ...[...source.matchAll(REGEX_TAG_LINK)]
117
+ .map((v) => v[0])
118
+ // NOTE: Too brittle
119
+ .filter((v) => /rel="(stylesheet|modulepreload)"/.test(v)),
120
+ ].join('\n');
121
+ const route = renderedRoutes.find((r) => {
122
+ if (state.gracileConfig.pages?.premises?.expose)
123
+ return (`/${r.name}` ===
124
+ `/${fileKey}`.replace(/(.*?)\/__(.*?)\.doc\.html$/, (a, b, c) => `${b}/${c}.html`));
125
+ return r.name === fileKey;
126
+ });
127
+ if (route)
128
+ route.handlerAssets = collectedAssets;
129
+ if (route?.savePrerender !== true) {
130
+ delete bundle[fileKey];
131
+ // NOTE: Not sure if it's useful
132
+ if (route?.html)
133
+ route.html = null;
134
+ }
135
+ }
136
+ }
137
+ },
138
+ },
139
+ ];
140
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"plugin-serve.d.ts","sourceRoot":"","sources":["../../src/vite/plugin-serve.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,MAAM,CAAC;AAIjD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAEvD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAElE,wBAAgB,kBAAkB,CAAC,EAClC,KAAK,EACL,MAAM,EACN,MAAM,EACN,oBAAoB,GACpB,EAAE;IACF,KAAK,EAAE,iBAAiB,CAAC;IACzB,MAAM,EAAE,aAAa,GAAG,SAAS,CAAC;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,oBAAoB,EAAE,MAAM,IAAI,CAAC;CACjC,GAAG,YAAY,CA6Df"}
1
+ {"version":3,"file":"plugin-serve.d.ts","sourceRoot":"","sources":["../../src/vite/plugin-serve.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,MAAM,CAAC;AAIjD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAEvD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAElE,wBAAgB,kBAAkB,CAAC,EAClC,KAAK,EACL,MAAM,EACN,MAAM,EACN,oBAAoB,GACpB,EAAE;IACF,KAAK,EAAE,iBAAiB,CAAC;IACzB,MAAM,EAAE,aAAa,GAAG,SAAS,CAAC;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,oBAAoB,EAAE,MAAM,IAAI,CAAC;CACjC,GAAG,YAAY,CA4Df"}
@@ -27,8 +27,7 @@ export function gracileServePlugin({ state, config, logger, resetClientBuiltFlag
27
27
  };
28
28
  },
29
29
  async configureServer(server) {
30
- // HACK: We know we are in dev here, this will prevent incorrect
31
- // vite.config hot reloading. Will be removed when adopting env. API.
30
+ // Reset so dev-mode config hot-reloads don't hit the guard.
32
31
  resetClientBuiltFlag();
33
32
  const version = getVersion();
34
33
  logger.info(`${c.cyan(c.italic(c.underline('🧚 Gracile')))}` +
@@ -1,18 +1,17 @@
1
1
  /**
2
2
  * Vite plugins: server-side build pipeline.
3
3
  *
4
- * After the client build completes, these plugins run a nested
5
- * `vite build` in SSR mode to produce the server entrypoint.
4
+ * Uses the Vite Environment API (`builder.buildApp()`) to coordinate
5
+ * client and SSR builds instead of a nested `build()` call.
6
6
  *
7
7
  * Includes:
8
- * - Client asset filename collector (from the client writeBundle)
9
- * - Server build trigger (closeBundle)
10
- * - Virtual entrypoint codegen
11
- * - Server-to-client asset mover
8
+ * - Client asset filename collector (client env writeBundle)
9
+ * - Virtual entrypoint codegen (SSR env only)
10
+ * - Server-to-client asset mover (SSR env only)
12
11
  *
13
12
  * @internal
14
13
  */
15
- import { type PluginOption } from 'vite';
14
+ import type { PluginOption } from 'vite';
16
15
  import type { PluginSharedState } from './plugin-shared-state.js';
17
16
  /**
18
17
  * Tracks client bundle assets so the server build can reference them
@@ -22,12 +21,23 @@ export declare function gracileCollectClientAssetsPlugin({ state, }: {
22
21
  state: PluginSharedState;
23
22
  }): PluginOption;
24
23
  /**
25
- * After the client build finishes (`closeBundle`), run a nested SSR
26
- * build that produces the server entrypoint and moves assets back into
27
- * the client output directory.
24
+ * Generates the virtual `entrypoint.js` module for the server build.
25
+ * This is the server's main entry: it imports routes and creates the
26
+ * Gracile handler.
27
+ *
28
+ * Scoped to the SSR environment via `applyToEnvironment`.
29
+ */
30
+ export declare function gracileEntrypointPlugin({ state, }: {
31
+ state: PluginSharedState;
32
+ }): PluginOption;
33
+ /**
34
+ * After the server build writes its bundle, move any assets from
35
+ * `dist/server/assets/` into `dist/client/assets/` so the client
36
+ * can serve them.
37
+ *
38
+ * Scoped to the SSR environment via `applyToEnvironment`.
28
39
  */
29
- export declare function gracileServerBuildPlugin({ state, virtualRoutesForClient, }: {
40
+ export declare function gracileMoveServerAssetsPlugin({ state, }: {
30
41
  state: PluginSharedState;
31
- virtualRoutesForClient: PluginOption;
32
42
  }): PluginOption;
33
43
  //# sourceMappingURL=plugin-server-build.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"plugin-server-build.d.ts","sourceRoot":"","sources":["../../src/vite/plugin-server-build.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAKH,OAAO,EAAS,KAAK,YAAY,EAAE,MAAM,MAAM,CAAC;AAGhD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAIlE;;;GAGG;AACH,wBAAgB,gCAAgC,CAAC,EAChD,KAAK,GACL,EAAE;IACF,KAAK,EAAE,iBAAiB,CAAC;CACzB,GAAG,YAAY,CAYf;AAID;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,EACxC,KAAK,EACL,sBAAsB,GACtB,EAAE;IACF,KAAK,EAAE,iBAAiB,CAAC;IACzB,sBAAsB,EAAE,YAAY,CAAC;CACrC,GAAG,YAAY,CAqEf"}
1
+ {"version":3,"file":"plugin-server-build.d.ts","sourceRoot":"","sources":["../../src/vite/plugin-server-build.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAKH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,MAAM,CAAC;AAEzC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAIlE;;;GAGG;AACH,wBAAgB,gCAAgC,CAAC,EAChD,KAAK,GACL,EAAE;IACF,KAAK,EAAE,iBAAiB,CAAC;CACzB,GAAG,YAAY,CAgBf;AAID;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CAAC,EACvC,KAAK,GACL,EAAE;IACF,KAAK,EAAE,iBAAiB,CAAC;CACzB,GAAG,YAAY,CAsCf;AAID;;;;;;GAMG;AACH,wBAAgB,6BAA6B,CAAC,EAC7C,KAAK,GACL,EAAE;IACF,KAAK,EAAE,iBAAiB,CAAC;CACzB,GAAG,YAAY,CA2Bf"}
@@ -1,21 +1,18 @@
1
1
  /**
2
2
  * Vite plugins: server-side build pipeline.
3
3
  *
4
- * After the client build completes, these plugins run a nested
5
- * `vite build` in SSR mode to produce the server entrypoint.
4
+ * Uses the Vite Environment API (`builder.buildApp()`) to coordinate
5
+ * client and SSR builds instead of a nested `build()` call.
6
6
  *
7
7
  * Includes:
8
- * - Client asset filename collector (from the client writeBundle)
9
- * - Server build trigger (closeBundle)
10
- * - Virtual entrypoint codegen
11
- * - Server-to-client asset mover
8
+ * - Client asset filename collector (client env writeBundle)
9
+ * - Virtual entrypoint codegen (SSR env only)
10
+ * - Server-to-client asset mover (SSR env only)
12
11
  *
13
12
  * @internal
14
13
  */
15
14
  import { join } from 'node:path';
16
15
  import { rename, rm } from 'node:fs/promises';
17
- import { build } from 'vite';
18
- import { virtualRoutes } from './virtual-routes.js';
19
16
  // ── Client asset collector ───────────────────────────────────────────
20
17
  /**
21
18
  * Tracks client bundle assets so the server build can reference them
@@ -24,6 +21,9 @@ import { virtualRoutes } from './virtual-routes.js';
24
21
  export function gracileCollectClientAssetsPlugin({ state, }) {
25
22
  return {
26
23
  name: 'vite-plugin-gracile-collect-client-assets-for-server',
24
+ applyToEnvironment(environment) {
25
+ return environment.name !== 'ssr';
26
+ },
27
27
  writeBundle(_, bundle) {
28
28
  if (state.outputMode === 'static')
29
29
  return;
@@ -33,76 +33,21 @@ export function gracileCollectClientAssetsPlugin({ state, }) {
33
33
  },
34
34
  };
35
35
  }
36
- // ── Server build trigger ─────────────────────────────────────────────
37
- /**
38
- * After the client build finishes (`closeBundle`), run a nested SSR
39
- * build that produces the server entrypoint and moves assets back into
40
- * the client output directory.
41
- */
42
- export function gracileServerBuildPlugin({ state, virtualRoutesForClient, }) {
43
- return {
44
- name: 'vite-plugin-gracile-server-build',
45
- apply: 'build',
46
- config(viteConfig) {
47
- state.root = viteConfig.root || null;
48
- },
49
- async closeBundle() {
50
- if (state.outputMode === 'static' ||
51
- !state.routes ||
52
- !state.renderedRoutes)
53
- return;
54
- const root = state.root || process.cwd();
55
- await build({
56
- root,
57
- ssr: { external: ['@gracile/gracile'] },
58
- build: {
59
- target: 'esnext',
60
- ssr: true,
61
- copyPublicDir: false,
62
- outDir: 'dist/server',
63
- ssrEmitAssets: true,
64
- cssMinify: true,
65
- cssCodeSplit: true,
66
- rollupOptions: {
67
- input: 'entrypoint.js',
68
- output: {
69
- entryFileNames: '[name].js',
70
- assetFileNames: (chunkInfo) => {
71
- if (chunkInfo.name) {
72
- const fileName = state.clientAssets[chunkInfo.name];
73
- if (fileName)
74
- return fileName;
75
- // NOTE: When not imported at all from client
76
- return `assets/${chunkInfo.name.replace(/\.(.*)$/, '')}-[hash].[ext]`;
77
- }
78
- return 'assets/[name]-[hash].[ext]';
79
- },
80
- chunkFileNames: 'chunk/[name].js',
81
- },
82
- },
83
- },
84
- plugins: [
85
- virtualRoutesForClient,
86
- virtualRoutes({
87
- routes: state.routes,
88
- renderedRoutes: state.renderedRoutes,
89
- }),
90
- gracileEntrypointPlugin(state),
91
- gracileMoveServerAssetsPlugin(state),
92
- ],
93
- });
94
- },
95
- };
96
- }
97
36
  // ── Virtual entrypoint ───────────────────────────────────────────────
98
37
  /**
99
38
  * Generates the virtual `entrypoint.js` module for the server build.
100
39
  * This is the server's main entry: it imports routes and creates the
101
40
  * Gracile handler.
41
+ *
42
+ * Scoped to the SSR environment via `applyToEnvironment`.
102
43
  */
103
- function gracileEntrypointPlugin(state) {
44
+ export function gracileEntrypointPlugin({ state, }) {
104
45
  return {
105
46
  name: 'vite-plugin-gracile-entry',
47
+ apply: 'build',
48
+ applyToEnvironment(environment) {
49
+ return environment.name === 'ssr';
50
+ },
106
51
  resolveId(id) {
107
52
  if (id === 'entrypoint.js') {
108
53
  return id;
@@ -137,10 +82,16 @@ export const handler = createGracileHandler({
137
82
  * After the server build writes its bundle, move any assets from
138
83
  * `dist/server/assets/` into `dist/client/assets/` so the client
139
84
  * can serve them.
85
+ *
86
+ * Scoped to the SSR environment via `applyToEnvironment`.
140
87
  */
141
- function gracileMoveServerAssetsPlugin(state) {
88
+ export function gracileMoveServerAssetsPlugin({ state, }) {
142
89
  return {
143
90
  name: 'gracile-move-server-assets',
91
+ apply: 'build',
92
+ applyToEnvironment(environment) {
93
+ return environment.name === 'ssr';
94
+ },
144
95
  async writeBundle(_, bundle) {
145
96
  const cwd = state.root || process.cwd();
146
97
  await Promise.all(Object.entries(bundle).map(async ([file]) => {
@@ -15,6 +15,8 @@ export interface PluginSharedState {
15
15
  routes: RoutesManifest;
16
16
  /** Rendered route definitions from the client build phase. */
17
17
  renderedRoutes: RenderedRouteDefinition[] | null;
18
+ /** Rollup input list for the client build (populated by route renderer). */
19
+ clientBuildInputList: string[] | null;
18
20
  /** Maps original asset names → hashed filenames from the client bundle. */
19
21
  clientAssets: Record<string, string>;
20
22
  /** Vite `root` captured during build config. */
@@ -1 +1 @@
1
- {"version":3,"file":"plugin-shared-state.d.ts","sourceRoot":"","sources":["../../src/vite/plugin-shared-state.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AACnE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAEvD,MAAM,WAAW,iBAAiB;IACjC,qEAAqE;IACrE,MAAM,EAAE,cAAc,CAAC;IAEvB,8DAA8D;IAC9D,cAAc,EAAE,uBAAuB,EAAE,GAAG,IAAI,CAAC;IAEjD,2EAA2E;IAC3E,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAErC,gDAAgD;IAChD,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAEpB,0CAA0C;IAC1C,aAAa,EAAE,aAAa,CAAC;IAE7B,6CAA6C;IAC7C,UAAU,EAAE,QAAQ,GAAG,QAAQ,CAAC;CAChC;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CACtC,MAAM,EAAE,aAAa,GAAG,SAAS,GAC/B,iBAAiB,CASnB"}
1
+ {"version":3,"file":"plugin-shared-state.d.ts","sourceRoot":"","sources":["../../src/vite/plugin-shared-state.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AACnE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAEvD,MAAM,WAAW,iBAAiB;IACjC,qEAAqE;IACrE,MAAM,EAAE,cAAc,CAAC;IAEvB,8DAA8D;IAC9D,cAAc,EAAE,uBAAuB,EAAE,GAAG,IAAI,CAAC;IAEjD,4EAA4E;IAC5E,oBAAoB,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IAEtC,2EAA2E;IAC3E,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAErC,gDAAgD;IAChD,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAEpB,0CAA0C;IAC1C,aAAa,EAAE,aAAa,CAAC;IAE7B,6CAA6C;IAC7C,UAAU,EAAE,QAAQ,GAAG,QAAQ,CAAC;CAChC;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CACtC,MAAM,EAAE,aAAa,GAAG,SAAS,GAC/B,iBAAiB,CAUnB"}
@@ -14,6 +14,7 @@ export function createPluginSharedState(config) {
14
14
  return {
15
15
  routes: new Map(),
16
16
  renderedRoutes: null,
17
+ clientBuildInputList: null,
17
18
  clientAssets: {},
18
19
  root: null,
19
20
  gracileConfig: config || {},
@@ -1,13 +1,16 @@
1
1
  import { type Plugin } from 'vite';
2
- import type { RenderedRouteDefinition } from '../routes/render.js';
3
2
  import type { RoutesManifest } from '../routes/route.js';
4
3
  import type { GracileConfig } from '../user-config.js';
4
+ import type { PluginSharedState } from './plugin-shared-state.js';
5
5
  /**
6
- * @todo Client-side testing, docs.
6
+ * Server-side routes virtual module (`gracile:routes`).
7
+ *
8
+ * Scoped to the SSR build environment via `applyToEnvironment`.
9
+ * Reads from shared state lazily so `renderedRoutes` is available
10
+ * (populated during the client build).
7
11
  */
8
- export declare function virtualRoutes({ routes, renderedRoutes, }: {
9
- routes: RoutesManifest;
10
- renderedRoutes: RenderedRouteDefinition[];
12
+ export declare function virtualRoutes({ state, }: {
13
+ state: PluginSharedState;
11
14
  }): Plugin[];
12
15
  export declare function virtualRoutesClient({ routes: routesMap, mode, gracileConfig, }: {
13
16
  routes: RoutesManifest;
@@ -1 +1 @@
1
- {"version":3,"file":"virtual-routes.d.ts","sourceRoot":"","sources":["../../src/vite/virtual-routes.ts"],"names":[],"mappings":"AACA,OAAO,EAAgB,KAAK,MAAM,EAAE,MAAM,MAAM,CAAC;AAEjD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AACnE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAEvD;;GAEG;AACH,wBAAgB,aAAa,CAAC,EAE7B,MAAM,EACN,cAAc,GACd,EAAE;IAEF,MAAM,EAAE,cAAc,CAAC;IACvB,cAAc,EAAE,uBAAuB,EAAE,CAAC;CAC1C,GAAG,MAAM,EAAE,CAyEX;AAKD,wBAAgB,mBAAmB,CAAC,EACnC,MAAM,EAAE,SAAS,EACjB,IAAe,EACf,aAAa,GACb,EAAE;IACF,MAAM,EAAE,cAAc,CAAC;IACvB,IAAI,EAAE,QAAQ,GAAG,QAAQ,CAAC;IAC1B,aAAa,EAAE,aAAa,CAAC;CAC7B,GAAG,MAAM,EAAE,CA4DX"}
1
+ {"version":3,"file":"virtual-routes.d.ts","sourceRoot":"","sources":["../../src/vite/virtual-routes.ts"],"names":[],"mappings":"AACA,OAAO,EAAgB,KAAK,MAAM,EAAE,MAAM,MAAM,CAAC;AAEjD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAEvD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAElE;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,EAC7B,KAAK,GACL,EAAE;IACF,KAAK,EAAE,iBAAiB,CAAC;CACzB,GAAG,MAAM,EAAE,CAwEX;AAKD,wBAAgB,mBAAmB,CAAC,EACnC,MAAM,EAAE,SAAS,EACjB,IAAe,EACf,aAAa,GACb,EAAE;IACF,MAAM,EAAE,cAAc,CAAC;IACvB,IAAI,EAAE,QAAQ,GAAG,QAAQ,CAAC;IAC1B,aAAa,EAAE,aAAa,CAAC;CAC7B,GAAG,MAAM,EAAE,CA4DX"}
@@ -1,25 +1,22 @@
1
1
  import { normalizeToPosix } from '@gracile/internal-utils/paths';
2
2
  import { createFilter } from 'vite';
3
3
  /**
4
- * @todo Client-side testing, docs.
4
+ * Server-side routes virtual module (`gracile:routes`).
5
+ *
6
+ * Scoped to the SSR build environment via `applyToEnvironment`.
7
+ * Reads from shared state lazily so `renderedRoutes` is available
8
+ * (populated during the client build).
5
9
  */
6
- export function virtualRoutes({
7
- // root,
8
- routes, renderedRoutes, }) {
10
+ export function virtualRoutes({ state, }) {
9
11
  const virtualModuleId = 'gracile:routes';
10
12
  const resolvedVirtualModuleId = `\0${virtualModuleId}`;
11
- // TODO: Remove handler when prerendering route
12
- const routesWithoutPrerender = [...routes];
13
- const renderedRoutesWithoutPrerender = renderedRoutes;
14
- // const routesWithoutPrerender = [...routes].filter(
15
- // ([, r]) => r.prerender !== true,
16
- // );
17
- // const renderedRoutesWithoutPrerender = renderedRoutes.filter(
18
- // (r) => r.savePrerender !== true,
19
- // );
20
13
  return [
21
14
  {
22
15
  name: 'gracile-server-routes',
16
+ apply: 'build',
17
+ applyToEnvironment(environment) {
18
+ return environment.name === 'ssr';
19
+ },
23
20
  resolveId(id) {
24
21
  if (id === virtualModuleId) {
25
22
  return resolvedVirtualModuleId;
@@ -27,39 +24,43 @@ routes, renderedRoutes, }) {
27
24
  return null;
28
25
  },
29
26
  load(id) {
30
- if (id === resolvedVirtualModuleId) {
31
- return `
27
+ if (id !== resolvedVirtualModuleId)
28
+ return null;
29
+ const routes = state.routes;
30
+ const renderedRoutes = state.renderedRoutes;
31
+ if (!routes || routes.size === 0 || !renderedRoutes)
32
+ return null;
33
+ const routesArray = [...routes];
34
+ return `
32
35
  import { URLPattern } from '@gracile/gracile/url-pattern';
33
36
 
34
37
  const routes = new Map(${
35
- //
36
- JSON.stringify(routesWithoutPrerender, null, 2).replaceAll(
37
- // NOTE: Not strictly necessary, but just in case.
38
- '"pattern": {}', '"pattern": null')})
38
+ //
39
+ JSON.stringify(routesArray, null, 2).replaceAll(
40
+ // NOTE: Not strictly necessary, but just in case.
41
+ '"pattern": {}', '"pattern": null')})
39
42
  routes.forEach((route, pattern) => {
40
43
  route.pattern = new URLPattern(pattern, 'http://gracile');
41
44
  });
42
45
 
43
46
  const routeImports = new Map(
44
47
  [
45
- ${routesWithoutPrerender
46
- .map(([pattern, route]) => `['${pattern}', () => import('/${normalizeToPosix(route.filePath)}')],`)
47
- .join('\n ')}
48
+ ${routesArray
49
+ .map(([pattern, route]) => `['${pattern}', () => import('/${normalizeToPosix(route.filePath)}')],`)
50
+ .join('\n ')}
48
51
  ]
49
52
  );
50
53
 
51
- const routeAssets = new Map(${JSON.stringify(renderedRoutesWithoutPrerender.map((r) => [
52
- `/${r.name
53
- //
54
- .replace(/index\.html$/, '')
55
- .replace(/* Error pages */ /\.html$/, '/')}`,
56
- r.handlerAssets,
57
- ]), null, 2)});
54
+ const routeAssets = new Map(${JSON.stringify(renderedRoutes.map((r) => [
55
+ `/${r.name
56
+ //
57
+ .replace(/index\.html$/, '')
58
+ .replace(/* Error pages */ /\.html$/, '/')}`,
59
+ r.handlerAssets,
60
+ ]), null, 2)});
58
61
 
59
62
  export { routes, routeImports, routeAssets };
60
63
  `;
61
- }
62
- return null;
63
64
  },
64
65
  },
65
66
  ];
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@gracile/engine",
3
- "version": "0.9.0-next.7",
4
- "description": "A thin, full-stack, web framework",
3
+ "version": "0.9.1-next.0",
4
+ "description": "Vite-powered build and dev server engine for the Gracile framework",
5
5
  "keywords": [
6
6
  "custom-elements",
7
7
  "full-stack",
@@ -43,8 +43,8 @@
43
43
  "!/dist/typedoc-entrypoint.*"
44
44
  ],
45
45
  "dependencies": {
46
- "@gracile-labs/better-errors": "^0.2.1-next.0",
47
- "@gracile/internal-utils": "^0.6.1-next.0",
46
+ "@gracile-labs/better-errors": "^0.3.1-next.0",
47
+ "@gracile/internal-utils": "^0.6.2-next.0",
48
48
  "@whatwg-node/server": "^0.10.18",
49
49
  "fdir": "^6.5.0",
50
50
  "picocolors": "^1.1.1",
@@ -60,5 +60,5 @@
60
60
  "access": "public",
61
61
  "provenance": true
62
62
  },
63
- "gitHead": "9abb3f9de0217a6284a88b114194b4d254d0a104"
63
+ "gitHead": "d9d9fc5711f843aaa0356d0f5a781aa68f264af2"
64
64
  }