@gracile/engine 0.9.0-next.3 → 0.9.0-next.5

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 (43) hide show
  1. package/dist/plugin.d.ts.map +1 -1
  2. package/dist/plugin.js +42 -254
  3. package/dist/render/light-dom.d.ts +2 -0
  4. package/dist/render/light-dom.d.ts.map +1 -0
  5. package/dist/render/light-dom.js +31 -0
  6. package/dist/render/route-template-pipeline.d.ts +64 -0
  7. package/dist/render/route-template-pipeline.d.ts.map +1 -0
  8. package/dist/render/route-template-pipeline.js +144 -0
  9. package/dist/render/route-template.d.ts +4 -3
  10. package/dist/render/route-template.d.ts.map +1 -1
  11. package/dist/render/route-template.js +17 -88
  12. package/dist/routes/collect.d.ts +4 -0
  13. package/dist/routes/collect.d.ts.map +1 -1
  14. package/dist/routes/collect.js +2 -1
  15. package/dist/routes/match.d.ts +26 -0
  16. package/dist/routes/match.d.ts.map +1 -1
  17. package/dist/routes/match.js +4 -2
  18. package/dist/routes/render.d.ts.map +1 -1
  19. package/dist/routes/render.js +1 -0
  20. package/dist/server/request-pipeline.d.ts +109 -0
  21. package/dist/server/request-pipeline.d.ts.map +1 -0
  22. package/dist/server/request-pipeline.js +198 -0
  23. package/dist/server/request.d.ts +3 -16
  24. package/dist/server/request.d.ts.map +1 -1
  25. package/dist/server/request.js +56 -169
  26. package/dist/test/init.d.ts +2 -0
  27. package/dist/test/init.d.ts.map +1 -0
  28. package/dist/test/init.js +7 -0
  29. package/dist/user-config.d.ts +35 -0
  30. package/dist/user-config.d.ts.map +1 -1
  31. package/dist/vite/plugin-client-build.d.ts +16 -0
  32. package/dist/vite/plugin-client-build.d.ts.map +1 -0
  33. package/dist/vite/plugin-client-build.js +49 -0
  34. package/dist/vite/plugin-serve.d.ts +18 -0
  35. package/dist/vite/plugin-serve.d.ts.map +1 -0
  36. package/dist/vite/plugin-serve.js +62 -0
  37. package/dist/vite/plugin-server-build.d.ts +33 -0
  38. package/dist/vite/plugin-server-build.d.ts.map +1 -0
  39. package/dist/vite/plugin-server-build.js +157 -0
  40. package/dist/vite/plugin-shared-state.d.ts +31 -0
  41. package/dist/vite/plugin-shared-state.d.ts.map +1 -0
  42. package/dist/vite/plugin-shared-state.js +22 -0
  43. package/package.json +4 -4
@@ -1,24 +1,11 @@
1
1
  import { Readable } from 'node:stream';
2
- import * as assert from '@gracile/internal-utils/assertions';
3
2
  import { getLogger } from '@gracile/internal-utils/logger/helpers';
4
3
  import c from 'picocolors';
5
- // import { GracileError } from '../errors/errors.js';
6
4
  import { builtIn404Page, builtInErrorPage } from '../errors/pages.js';
7
5
  import { renderRouteTemplate } from '../render/route-template.js';
8
6
  import { renderLitTemplate } from '../render/lit-ssr.js';
9
7
  import { getRoute } from '../routes/match.js';
10
- const CONTENT_TYPE_HTML = { 'Content-Type': 'text/html' };
11
- const PREMISE_REGEXES = {
12
- properties: /\/__(.*?)\.props\.json$/,
13
- document: /\/__(.*?)\.doc\.html$/,
14
- };
15
- export function isRedirect(response) {
16
- const location = response.headers.get('location');
17
- if (response.status >= 300 && response.status <= 303 && location) {
18
- return { location };
19
- }
20
- return null;
21
- }
8
+ import { CONTENT_TYPE_HTML, rewriteHiddenRoutes, resolvePremises, executeHandler, renderWithoutHandler, buildResponse, } from './request-pipeline.js';
22
9
  export function createGracileHandler({ vite, routes, routeImports, routeAssets, root, serverMode, gracileConfig, }) {
23
10
  const logger = getLogger();
24
11
  const middleware = async (request, locals) => {
@@ -28,16 +15,11 @@ export function createGracileHandler({ vite, routes, routeImports, routeAssets,
28
15
  emitViteBetterError =
29
16
  await import('../errors/create-vite-better-error.js').then(({ emitViteBetterError: error }) => error);
30
17
  try {
31
- // MARK: Rewrite hidden route siblings
32
- const fullUrl = requestedUrl.replace(/\/__(.*)$/, '/');
33
- // MARK: Setup premises
34
- const propertiesOnly = PREMISE_REGEXES.properties.test(requestedUrl);
35
- const documentOnly = PREMISE_REGEXES.document.test(requestedUrl);
36
- const allowPremises = Boolean(gracileConfig.pages?.premises?.expose);
37
- if (allowPremises === false && (propertiesOnly || documentOnly))
38
- throw new Error('Accessed a page premise but they are not activated. You must enable `pages.premises.expose`.');
39
- const premises = allowPremises ? { propertiesOnly, documentOnly } : null;
40
- // MARK: Get route infos
18
+ // MARK: 1. Rewrite hidden route siblings
19
+ const fullUrl = rewriteHiddenRoutes(requestedUrl);
20
+ // MARK: 2. Setup premises
21
+ const premises = resolvePremises(requestedUrl, gracileConfig);
22
+ // MARK: 3. Route resolution + 404 fallback
41
23
  const routeOptions = {
42
24
  url: fullUrl,
43
25
  vite,
@@ -46,15 +28,12 @@ export function createGracileHandler({ vite, routes, routeImports, routeAssets,
46
28
  };
47
29
  const responseInit = {};
48
30
  let routeInfos = await getRoute(routeOptions);
49
- // MARK: 404
50
31
  if (routeInfos === null) {
51
32
  responseInit.status = 404;
52
33
  const url = new URL('/404/', fullUrl).href;
53
34
  const options = { ...routeOptions, url };
54
- const notFound = await getRoute(options);
55
- routeInfos = notFound;
35
+ routeInfos = await getRoute(options);
56
36
  }
57
- // MARK: fallback 404
58
37
  if (routeInfos === null) {
59
38
  const page = builtIn404Page(new URL(fullUrl).pathname, Boolean(vite));
60
39
  return {
@@ -66,163 +45,49 @@ export function createGracileHandler({ vite, routes, routeImports, routeAssets,
66
45
  const routeTemplateOptions = {
67
46
  url: fullUrl,
68
47
  vite,
69
- mode: 'dev', // vite && vite.config.mode === 'dev' ? 'dev' : 'build',
48
+ mode: 'dev',
70
49
  routeAssets,
71
50
  root,
72
51
  serverMode,
73
52
  routeInfos,
74
53
  docOnly: premises?.documentOnly,
54
+ renderInfo: gracileConfig.litSsr?.renderInfo,
75
55
  };
76
56
  logger.info(`[${c.yellow(method)}] ${c.yellow(fullUrl)}`, {
77
57
  timestamp: true,
78
58
  });
59
+ // MARK: 4. Handler dispatch
79
60
  let output;
80
- let providedLocals = {};
81
- if (locals && assert.isUnknownObject(locals))
82
- providedLocals = locals;
83
- // MARK: Server handler
84
- const handler = routeInfos.routeModule.handler;
85
- if (('handler' in routeInfos.routeModule && handler !== undefined) ||
86
- // TODO: Explain this condition
87
- (handler && 'GET' in handler === false && method !== 'GET')) {
88
- const routeContext = Object.freeze({
89
- request,
90
- url: new URL(fullUrl),
91
- responseInit,
92
- params: routeInfos.params,
93
- locals: providedLocals,
94
- });
95
- // MARK: Run user middleware
96
- // NOTE: Experimental
97
- /// eslint-disable-next-line no-inner-declarations
98
- // async function useHandler() {}
99
- // if (vite) {
100
- // const middleware = await vite
101
- // .ssrLoadModule('/src/middleware.ts')
102
- // .catch(() => null)
103
- // .then((m) => m.default);
104
- // if (middleware)
105
- // await middleware(
106
- // routeContext,
107
- // async () => {
108
- // await useHandler();
109
- // },
110
- // );
111
- // else await useHandler();
112
- // } else {
113
- // await useHandler();
114
- // }
115
- //
116
- // MARK: Handler(s)
117
- const hasTopLevelHandler = typeof handler === 'function';
118
- if (hasTopLevelHandler || method in handler) {
119
- const handlerWithMethod = hasTopLevelHandler
120
- ? handler
121
- : handler[method];
122
- if (typeof handlerWithMethod !== 'function')
123
- throw new TypeError('Handler must be a function.');
124
- const handlerOutput = await Promise.resolve(handlerWithMethod(routeContext));
125
- if (assert.isResponseOrPatchedResponse(handlerOutput))
126
- output = handlerOutput;
127
- else {
128
- routeTemplateOptions.routeInfos.props = hasTopLevelHandler
129
- ? handlerOutput
130
- : { [method]: handlerOutput };
131
- if (premises?.documentOnly) {
132
- const { document } = await renderRouteTemplate(routeTemplateOptions);
133
- return {
134
- response: new Response(document, {
135
- headers: { ...CONTENT_TYPE_HTML },
136
- }),
137
- };
138
- }
139
- if (premises?.propertiesOnly)
140
- return {
141
- response: Response.json(routeTemplateOptions.routeInfos.props),
142
- };
143
- output = await renderRouteTemplate(routeTemplateOptions).then((r) => r.output);
144
- }
145
- // MARK: No GET, render page
146
- }
147
- else {
148
- const statusText = `This route doesn't handle the \`${method}\` method!`;
149
- return {
150
- response: new Response(statusText, { status: 405, statusText }),
151
- };
152
- }
61
+ const handlerResult = await executeHandler({
62
+ routeInfos,
63
+ method,
64
+ request,
65
+ fullUrl,
66
+ locals,
67
+ responseInit,
68
+ premises,
69
+ routeTemplateOptions,
70
+ });
71
+ if (handlerResult.type === 'response')
72
+ return handlerResult.value;
73
+ if (handlerResult.type === 'output') {
74
+ output = handlerResult.value;
153
75
  }
154
76
  else {
155
- if (premises?.documentOnly) {
156
- const { document } = await renderRouteTemplate(routeTemplateOptions);
157
- return {
158
- response: new Response(document, {
159
- headers: { ...CONTENT_TYPE_HTML },
160
- }),
161
- };
162
- }
163
- if (premises?.propertiesOnly)
164
- return {
165
- response: Response.json(routeTemplateOptions.routeInfos.props || {}),
166
- };
167
- output = await renderRouteTemplate(routeTemplateOptions).then((r) => r.output);
168
- }
169
- // MARK: Return response
170
- // NOTE: try directly with the requestPonyfill. This might not be necessary
171
- if (assert.isResponseOrPatchedResponse(output)) {
172
- const redirect = isRedirect(output);
173
- if (redirect?.location)
174
- return {
175
- response: Response.redirect(redirect.location, output.status),
176
- };
177
- return { response: output };
178
- // MARK: Stream page render
179
- }
180
- // MARK: Page stream error
181
- if (output instanceof Readable) {
182
- responseInit.headers = {
183
- ...responseInit.headers,
184
- ...CONTENT_TYPE_HTML,
185
- };
186
- return {
187
- body: output.on('error', (error) => {
188
- const errorMessage = `[SSR Error] There was an error while rendering a template chunk on server-side.\n` +
189
- `It was omitted from the resulting HTML.\n`;
190
- if (vite) {
191
- logger.error(errorMessage + error.stack);
192
- // emitViteBetterError(new GracileError(GracileErrorData.FailedToGlobalLogger), vite);
193
- const payload = {
194
- type: 'error',
195
- // FIXME: Use the emitViteBetterError instead (but flaky for now with streaming)
196
- // err: new GracileError({}),
197
- err: {
198
- name: 'StreamingError',
199
- message: errorMessage,
200
- stack: error.stack,
201
- hint: 'This is often caused by a wrong template location dynamic interpolation.',
202
- cause: error,
203
- // highlightedCode: error.message,
204
- },
205
- };
206
- //
207
- setTimeout(() => {
208
- // @ts-expect-error ...........
209
- vite.hot.send(payload);
210
- // NOTE: Arbitrary value. Lower seems to be too fast, higher is not guaranteed to work.
211
- }, 200);
212
- }
213
- else {
214
- logger.error(errorMessage);
215
- }
216
- }),
217
- init: responseInit,
218
- };
77
+ // MARK: 5. Template-only render (no handler)
78
+ const renderResult = await renderWithoutHandler({
79
+ premises,
80
+ routeTemplateOptions,
81
+ });
82
+ if (renderResult && 'response' in renderResult)
83
+ return renderResult;
84
+ output = renderResult;
219
85
  }
220
- return null;
86
+ // MARK: 6. Build final response
87
+ return buildResponse({ output, responseInit, vite, logger });
221
88
  // MARK: Errors
222
89
  }
223
90
  catch (error) {
224
- // const safeError = createSafeError(error);
225
- // TODO: User defined dev/runtime 500 error
226
91
  const ultimateErrorPage = vite && emitViteBetterError
227
92
  ? await emitViteBetterError({ vite, error: error })
228
93
  : await renderLitTemplate(builtInErrorPage(error.name));
@@ -237,3 +102,25 @@ export function createGracileHandler({ vite, routes, routeImports, routeAssets,
237
102
  };
238
103
  return middleware;
239
104
  }
105
+ // MARK: Run user middleware
106
+ // NOTE: Experimental
107
+ /// eslint-disable-next-line no-inner-declarations
108
+ // async function useHandler() {}
109
+ // if (vite) {
110
+ // const middleware = await vite
111
+ // .ssrLoadModule('/src/middleware.ts')
112
+ // .catch(() => null)
113
+ // .then((m) => m.default);
114
+ // if (middleware)
115
+ // await middleware(
116
+ // routeContext,
117
+ // async () => {
118
+ // await useHandler();
119
+ // },
120
+ // );
121
+ // else await useHandler();
122
+ // } else {
123
+ // await useHandler();
124
+ // }
125
+ //
126
+ export { isRedirect, } from './request-pipeline.js';
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=init.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/test/init.ts"],"names":[],"mappings":""}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Side-effect import: initializes the Gracile logger globally.
3
+ * Import this at the top of any engine unit test that touches modules
4
+ * which call `getLogger()` at module scope.
5
+ */
6
+ import { createLogger } from '@gracile/internal-utils/logger/helpers';
7
+ createLogger();
@@ -1,3 +1,4 @@
1
+ import type { RenderInfo } from '@lit-labs/ssr';
1
2
  import type { Connect } from 'vite';
2
3
  /**
3
4
  * @example
@@ -93,6 +94,40 @@ export interface GracileConfig {
93
94
  exclude?: string[];
94
95
  };
95
96
  };
97
+ litSsr?: {
98
+ /**
99
+ * Lets you extend Gracile's SSR pipeline with
100
+ * custom Lit SSR `ElementRenderer` subclasses. This is the foundation for
101
+ * features like [Islands](/docs/add-ons/islands/), which register a renderer
102
+ * for the `<is-land>` custom element to server-render components from other
103
+ * UI frameworks.
104
+ *
105
+ * In most cases, you do **not** set this option manually — add-on plugins
106
+ * (like `gracileIslands()`) register their renderers automatically via the
107
+ * plugin context communication channel. However,
108
+ * you can use it directly for advanced use cases:
109
+ *
110
+ * ```ts
111
+ * import { gracile } from '@gracile/gracile/plugin';
112
+ * import { defineConfig } from 'vite';
113
+ *
114
+ * export default defineConfig({
115
+ * plugins: [
116
+ * gracile({
117
+ * litSsr: {
118
+ * renderInfo: {
119
+ * elementRenderers: [
120
+ * // Your custom ElementRenderer subclass
121
+ * ],
122
+ * },
123
+ * },
124
+ * }),
125
+ * ],
126
+ * });
127
+ * ```
128
+ */
129
+ renderInfo?: Partial<RenderInfo>;
130
+ };
96
131
  /**
97
132
  * Future, unstable features flags.
98
133
  */
@@ -1 +1 @@
1
- {"version":3,"file":"user-config.d.ts","sourceRoot":"","sources":["../src/user-config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAEpC;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,MAAM,WAAW,aAAa;IAC7B;;;;;;OAMG;IACH,MAAM,CAAC,EAAE,QAAQ,GAAG,QAAQ,CAAC;IAE7B;;OAEG;IACH,GAAG,CAAC,EAAE;QACL;;;;;WAKG;QACH,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE;YAAE,WAAW,EAAE,OAAO,CAAC,eAAe,CAAA;SAAE,KAAK,OAAO,CAAC;KACxE,CAAC;IAEF;;OAEG;IACH,MAAM,CAAC,EAAE;QACR;;WAEG;QACH,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;KACnB,CAAC;IAEF;;OAEG;IACH,KAAK,CAAC,EAAE;QACP;;;;;;;;;;;;;WAaG;QACH,QAAQ,CAAC,EAAE;YACV;;eAEG;YACH,MAAM,CAAC,EAAE,OAAO,CAAC;YAGjB;;eAEG;YACH,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;YAEnB;;eAEG;YACH,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;SACnB,CAAC;KACF,CAAC;IAEF;;OAEG;IACH,YAAY,CAAC,EAAE;QACd;;;WAGG;QACH,qBAAqB,CAAC,EAAE,OAAO,CAAC;KAOhC,CAAC;CACF"}
1
+ {"version":3,"file":"user-config.d.ts","sourceRoot":"","sources":["../src/user-config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAEpC;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,MAAM,WAAW,aAAa;IAC7B;;;;;;OAMG;IACH,MAAM,CAAC,EAAE,QAAQ,GAAG,QAAQ,CAAC;IAE7B;;OAEG;IACH,GAAG,CAAC,EAAE;QACL;;;;;WAKG;QACH,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE;YAAE,WAAW,EAAE,OAAO,CAAC,eAAe,CAAA;SAAE,KAAK,OAAO,CAAC;KACxE,CAAC;IAEF;;OAEG;IACH,MAAM,CAAC,EAAE;QACR;;WAEG;QACH,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;KACnB,CAAC;IAEF;;OAEG;IACH,KAAK,CAAC,EAAE;QACP;;;;;;;;;;;;;WAaG;QACH,QAAQ,CAAC,EAAE;YACV;;eAEG;YACH,MAAM,CAAC,EAAE,OAAO,CAAC;YAGjB;;eAEG;YACH,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;YAEnB;;eAEG;YACH,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;SACnB,CAAC;KACF,CAAC;IACF,MAAM,CAAC,EAAE;QACR;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;WA8BG;QACH,UAAU,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC;KACjC,CAAC;IAEF;;OAEG;IACH,YAAY,CAAC,EAAE;QACd;;;WAGG;QACH,qBAAqB,CAAC,EAAE,OAAO,CAAC;KAOhC,CAAC;CACF"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Vite plugin: client-side build configuration.
3
+ *
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.
7
+ *
8
+ * @internal
9
+ */
10
+ import { type PluginOption } from 'vite';
11
+ import type { PluginSharedState } from './plugin-shared-state.js';
12
+ export declare function gracileClientBuildPlugin({ state, virtualRoutesForClient, }: {
13
+ state: PluginSharedState;
14
+ virtualRoutesForClient: PluginOption;
15
+ }): PluginOption;
16
+ //# sourceMappingURL=plugin-client-build.d.ts.map
@@ -0,0 +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,CAkDf"}
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Vite plugin: client-side build configuration.
3
+ *
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.
7
+ *
8
+ * @internal
9
+ */
10
+ import { join } from 'node:path';
11
+ import { getPluginContext } from '@gracile/internal-utils/plugin-context';
12
+ import { createServer } from 'vite';
13
+ import { buildRoutes } from './build-routes.js';
14
+ export function gracileClientBuildPlugin({ state, virtualRoutesForClient, }) {
15
+ return {
16
+ name: 'vite-plugin-gracile-build',
17
+ apply: 'build',
18
+ async config(viteConfig) {
19
+ const viteServerForClientHtmlBuild = await createServer({
20
+ root: viteConfig.root || process.cwd(),
21
+ server: { middlewareMode: true },
22
+ // NOTE: Stub. KEEP IT!
23
+ optimizeDeps: { include: [] },
24
+ plugins: [virtualRoutesForClient],
25
+ });
26
+ // NOTE: Important. Get the dev. server elements renderers.
27
+ state.gracileConfig.litSsr ??= {};
28
+ state.gracileConfig.litSsr.renderInfo = getPluginContext(viteServerForClientHtmlBuild.config)?.litSsrRenderInfo;
29
+ const htmlPages = await buildRoutes({
30
+ viteServerForBuild: viteServerForClientHtmlBuild,
31
+ root: viteConfig.root || process.cwd(),
32
+ gracileConfig: state.gracileConfig,
33
+ serverMode: state.outputMode === 'server',
34
+ routes: state.routes,
35
+ });
36
+ state.renderedRoutes = htmlPages.renderedRoutes;
37
+ await viteServerForClientHtmlBuild.close();
38
+ return {
39
+ build: {
40
+ rollupOptions: {
41
+ input: htmlPages.inputList,
42
+ plugins: [htmlPages.plugin],
43
+ },
44
+ outDir: join(viteConfig.build?.outDir || 'dist', state.outputMode === 'server' ? 'client' : ''),
45
+ },
46
+ };
47
+ },
48
+ };
49
+ }
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Vite plugin: development server middleware.
3
+ *
4
+ * Sets up the Gracile request handler, route watcher, and dev-time
5
+ * logging for `vite dev`.
6
+ *
7
+ * @internal
8
+ */
9
+ import type { Logger, PluginOption } from 'vite';
10
+ import type { GracileConfig } from '../user-config.js';
11
+ import type { PluginSharedState } from './plugin-shared-state.js';
12
+ export declare function gracileServePlugin({ state, config, logger, resetClientBuiltFlag, }: {
13
+ state: PluginSharedState;
14
+ config: GracileConfig | undefined;
15
+ logger: Logger;
16
+ resetClientBuiltFlag: () => void;
17
+ }): PluginOption;
18
+ //# sourceMappingURL=plugin-serve.d.ts.map
@@ -0,0 +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"}
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Vite plugin: development server middleware.
3
+ *
4
+ * Sets up the Gracile request handler, route watcher, and dev-time
5
+ * logging for `vite dev`.
6
+ *
7
+ * @internal
8
+ */
9
+ import { getVersion } from '@gracile/internal-utils/version';
10
+ import c from 'picocolors';
11
+ import { createDevelopmentHandler } from '../dev/development.js';
12
+ import { nodeAdapter } from '../server/adapters/node.js';
13
+ export function gracileServePlugin({ state, config, logger, resetClientBuiltFlag, }) {
14
+ return {
15
+ name: 'vite-plugin-gracile-serve-middleware',
16
+ apply: 'serve',
17
+ config(_, environment) {
18
+ if (environment.isPreview)
19
+ return null;
20
+ return {
21
+ // NOTE: Supresses message: `Could not auto-determine entry point from rollupOptions or html files…`
22
+ // FIXME: It's not working when reloading the Vite config.
23
+ // Is user config, putting `optimizeDeps: { include: [] }` solve this.
24
+ optimizeDeps: { include: [] },
25
+ // NOTE: Useful? It breaks preview (expected)
26
+ appType: 'custom',
27
+ };
28
+ },
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.
32
+ resetClientBuiltFlag();
33
+ const version = getVersion();
34
+ logger.info(`${c.cyan(c.italic(c.underline('🧚 Gracile')))}` +
35
+ ` ${c.dim(`~`)} ${c.green(`v${version ?? 'X'}`)}`);
36
+ const { handler } = await createDevelopmentHandler({
37
+ routes: state.routes,
38
+ vite: server,
39
+ gracileConfig: state.gracileConfig,
40
+ });
41
+ logger.info(c.dim('Vite development server is starting…'), {
42
+ timestamp: true,
43
+ });
44
+ server.watcher.on('ready', () => {
45
+ setTimeout(() => {
46
+ logger.info('');
47
+ logger.info(c.green('Watching for file changes…'), {
48
+ timestamp: true,
49
+ });
50
+ logger.info('');
51
+ // NOTE: We want it to show after the Vite intro stuff
52
+ }, 100);
53
+ });
54
+ return () => {
55
+ server.middlewares.use((request, response, next) => {
56
+ const locals = config?.dev?.locals?.({ nodeRequest: request });
57
+ Promise.resolve(nodeAdapter(handler, { logger })(request, response, locals)).catch((error) => next(error));
58
+ });
59
+ };
60
+ },
61
+ };
62
+ }
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Vite plugins: server-side build pipeline.
3
+ *
4
+ * After the client build completes, these plugins run a nested
5
+ * `vite build` in SSR mode to produce the server entrypoint.
6
+ *
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
12
+ *
13
+ * @internal
14
+ */
15
+ import { type PluginOption } from 'vite';
16
+ import type { PluginSharedState } from './plugin-shared-state.js';
17
+ /**
18
+ * Tracks client bundle assets so the server build can reference them
19
+ * with their hashed filenames.
20
+ */
21
+ export declare function gracileCollectClientAssetsPlugin({ state, }: {
22
+ state: PluginSharedState;
23
+ }): PluginOption;
24
+ /**
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.
28
+ */
29
+ export declare function gracileServerBuildPlugin({ state, virtualRoutesForClient, }: {
30
+ state: PluginSharedState;
31
+ virtualRoutesForClient: PluginOption;
32
+ }): PluginOption;
33
+ //# sourceMappingURL=plugin-server-build.d.ts.map
@@ -0,0 +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"}