@gracile/engine 0.6.0-next.1 → 0.7.0-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 (43) hide show
  1. package/dist/build/static.d.ts +8 -2
  2. package/dist/build/static.d.ts.map +1 -1
  3. package/dist/build/static.js +32 -7
  4. package/dist/dev/dev.d.ts +4 -1
  5. package/dist/dev/dev.d.ts.map +1 -1
  6. package/dist/dev/dev.js +12 -6
  7. package/dist/plugin.d.ts.map +1 -1
  8. package/dist/plugin.js +51 -40
  9. package/dist/render/markers.d.ts +3 -0
  10. package/dist/render/markers.d.ts.map +1 -0
  11. package/dist/render/markers.js +4 -0
  12. package/dist/render/route-template.d.ts +5 -10
  13. package/dist/render/route-template.d.ts.map +1 -1
  14. package/dist/render/route-template.js +32 -40
  15. package/dist/render/utils.d.ts +24 -1
  16. package/dist/render/utils.d.ts.map +1 -1
  17. package/dist/render/utils.js +23 -1
  18. package/dist/routes/collect.d.ts +1 -1
  19. package/dist/routes/collect.d.ts.map +1 -1
  20. package/dist/routes/collect.js +2 -2
  21. package/dist/routes/match.js +3 -3
  22. package/dist/routes/route.d.ts +1 -1
  23. package/dist/routes/route.d.ts.map +1 -1
  24. package/dist/server/adapters/hono.js +3 -3
  25. package/dist/server/adapters/node.d.ts.map +1 -1
  26. package/dist/server/adapters/node.js +3 -3
  27. package/dist/server/constants.d.ts +1 -1
  28. package/dist/server/constants.d.ts.map +1 -1
  29. package/dist/server/constants.js +1 -1
  30. package/dist/server/request.d.ts +3 -1
  31. package/dist/server/request.d.ts.map +1 -1
  32. package/dist/server/request.js +55 -31
  33. package/dist/server/utils.js +3 -3
  34. package/dist/tsconfig.tsbuildinfo +1 -1
  35. package/dist/user-config.d.ts +35 -1
  36. package/dist/user-config.d.ts.map +1 -1
  37. package/dist/vite/plugins/build-routes.d.ts +6 -2
  38. package/dist/vite/plugins/build-routes.d.ts.map +1 -1
  39. package/dist/vite/plugins/build-routes.js +67 -35
  40. package/dist/vite/plugins/virtual-routes.d.ts +10 -0
  41. package/dist/vite/plugins/virtual-routes.d.ts.map +1 -1
  42. package/dist/vite/plugins/virtual-routes.js +54 -3
  43. package/package.json +9 -11
@@ -1,19 +1,25 @@
1
1
  import type { ViteDevServer } from 'vite';
2
+ import type { RoutesManifest } from '../routes/route.js';
2
3
  import type { GracileConfig } from '../user-config.js';
3
4
  export interface RenderedRouteDefinition {
4
5
  absoluteId: string;
5
6
  name: string;
6
7
  html: string | null;
7
8
  handlerAssets?: string;
9
+ static: {
10
+ props: unknown;
11
+ document: string | null;
12
+ };
8
13
  savePrerender: boolean | null;
9
14
  }
10
- export declare function renderRoutes({ vite, serverMode, root, gracileConfig, }: {
15
+ export declare function renderRoutes({ routes, vite, serverMode, root, gracileConfig, }: {
16
+ routes: RoutesManifest;
11
17
  vite: ViteDevServer;
12
18
  serverMode: boolean;
13
19
  root?: string;
14
20
  gracileConfig: GracileConfig;
15
21
  }): Promise<{
16
- routes: import("../routes/route.js").RoutesManifest;
22
+ routes: RoutesManifest;
17
23
  renderedRoutes: RenderedRouteDefinition[];
18
24
  }>;
19
25
  //# sourceMappingURL=static.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"static.d.ts","sourceRoot":"","sources":["../../src/build/static.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,MAAM,CAAC;AAK1C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAEvD,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,aAAa,EAAE,OAAO,GAAG,IAAI,CAAC;CAC9B;AAeD,wBAAsB,YAAY,CAAC,EAClC,IAAI,EACJ,UAAU,EACV,IAAoB,EACpB,aAAa,GACb,EAAE;IACF,IAAI,EAAE,aAAa,CAAC;IACpB,UAAU,EAAE,OAAO,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,aAAa,CAAC;CAC7B;;;GAyHA"}
1
+ {"version":3,"file":"static.d.ts","sourceRoot":"","sources":["../../src/build/static.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,MAAM,CAAC;AAK1C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAEvD,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;AAeD,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;;;GAmJA"}
@@ -17,10 +17,10 @@ async function streamToString(stream) {
17
17
  }
18
18
  return Buffer.concat(chunks).toString('utf-8');
19
19
  }
20
- export async function renderRoutes({ vite, serverMode, root = process.cwd(), gracileConfig, }) {
20
+ export async function renderRoutes({ routes, vite, serverMode, root = process.cwd(), gracileConfig, }) {
21
21
  logger.info(c.green('Rendering routes…'), { timestamp: true });
22
22
  // MARK: Collect
23
- const routes = await collectRoutes(root, gracileConfig.routes?.exclude);
23
+ await collectRoutes(routes, root, gracileConfig.routes?.exclude);
24
24
  const renderedRoutes = [];
25
25
  // MARK: Iterate modules
26
26
  await Promise.all([...routes].map(async ([patternString, route]) => {
@@ -31,15 +31,38 @@ export async function renderRoutes({ vite, serverMode, root = process.cwd(), gra
31
31
  // NOTE: Skip rendering base document for server
32
32
  if (serverMode && typeof routeModule.document !== 'function')
33
33
  return;
34
- const routeStaticPaths = routeModule.staticPaths?.();
34
+ const routeStaticPaths = await Promise.resolve(routeModule.staticPaths?.());
35
35
  // MARK: Extract data
36
- await Promise.all((routeStaticPaths ?? [patternString]).map(async (staticPathOptions) => {
36
+ await Promise.all(
37
+ /* Single route */
38
+ (routeStaticPaths ?? [patternString]).map(async (staticPathOptions) => {
37
39
  let pathnameWithParams = patternString;
38
40
  let params = {};
39
41
  let props;
42
+ // MARK: Handler data (for single route only, NOT dynamic)
43
+ if (routeModule.handler) {
44
+ const url = new URL(pathnameWithParams, 'http://gracile-static');
45
+ const context = {
46
+ url,
47
+ params: {},
48
+ // NOTE: STUB, maybe it should be better to remove them from typings?
49
+ // But that will make more mismatches between static and server.
50
+ request: new Request(url),
51
+ locals: {},
52
+ responseInit: {},
53
+ };
54
+ if (typeof routeModule.handler === 'function') {
55
+ props = await Promise.resolve(routeModule.handler(context));
56
+ }
57
+ else if ('GET' in routeModule.handler) {
58
+ props = {
59
+ GET: await Promise.resolve(routeModule.handler.GET(context)),
60
+ };
61
+ }
62
+ }
40
63
  // MARK: Convert pattern
41
64
  // to real route with static parameters + get props. for after
42
- if (typeof staticPathOptions === 'object') {
65
+ else if (typeof staticPathOptions === 'object') {
43
66
  params = staticPathOptions.params;
44
67
  props = staticPathOptions.props;
45
68
  Object.entries(staticPathOptions.params).forEach(([paramName, value]) => {
@@ -62,9 +85,10 @@ export async function renderRoutes({ vite, serverMode, root = process.cwd(), gra
62
85
  name = '404.html';
63
86
  const url = new URL(pathnameWithParams, 'http://gracile-static');
64
87
  // MARK: Render
65
- const { output } = await renderRouteTemplate({
88
+ const { output, document } = await renderRouteTemplate({
66
89
  //
67
- request: { url: url.href },
90
+ // request: { url: url.href },
91
+ url: url.href,
68
92
  vite,
69
93
  mode: 'build',
70
94
  routeInfos: {
@@ -90,6 +114,7 @@ export async function renderRoutes({ vite, serverMode, root = process.cwd(), gra
90
114
  name,
91
115
  html: htmlString,
92
116
  savePrerender,
117
+ static: { props, document },
93
118
  };
94
119
  renderedRoutes.push(rendered);
95
120
  }));
package/dist/dev/dev.d.ts CHANGED
@@ -1,10 +1,13 @@
1
1
  import { type ViteDevServer } from 'vite';
2
+ import type { RoutesManifest } from '../routes/route.js';
2
3
  import { type GracileHandler } from '../server/request.js';
3
4
  import type { GracileConfig } from '../user-config.js';
4
- export declare function createDevHandler({ vite, gracileConfig, }: {
5
+ export declare function createDevHandler({ routes, vite, gracileConfig, }: {
6
+ routes: RoutesManifest;
5
7
  vite: ViteDevServer;
6
8
  gracileConfig: GracileConfig;
7
9
  }): Promise<{
8
10
  handler: GracileHandler;
11
+ routes: RoutesManifest;
9
12
  }>;
10
13
  //# sourceMappingURL=dev.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"dev.d.ts","sourceRoot":"","sources":["../../src/dev/dev.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,MAAM,CAAC;AAG1C,OAAO,EAEN,KAAK,cAAc,EACnB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAGvD,wBAAsB,gBAAgB,CAAC,EACtC,IAAI,EACJ,aAAa,GACb,EAAE;IACF,IAAI,EAAE,aAAa,CAAC;IACpB,aAAa,EAAE,aAAa,CAAC;CAC7B,GAAG,OAAO,CAAC;IACX,OAAO,EAAE,cAAc,CAAC;CACxB,CAAC,CAoCD"}
1
+ {"version":3,"file":"dev.d.ts","sourceRoot":"","sources":["../../src/dev/dev.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,MAAM,CAAC;AAG1C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAEN,KAAK,cAAc,EACnB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAGvD,wBAAsB,gBAAgB,CAAC,EACtC,MAAM,EACN,IAAI,EACJ,aAAa,GACb,EAAE;IACF,MAAM,EAAE,cAAc,CAAC;IACvB,IAAI,EAAE,aAAa,CAAC;IACpB,aAAa,EAAE,aAAa,CAAC;CAC7B,GAAG,OAAO,CAAC;IACX,OAAO,EAAE,cAAc,CAAC;IACxB,MAAM,EAAE,cAAc,CAAC;CACvB,CAAC,CA4CD"}
package/dist/dev/dev.js CHANGED
@@ -4,17 +4,17 @@ import {} from 'vite';
4
4
  import { collectRoutes } from '../routes/collect.js';
5
5
  import { createGracileHandler, } from '../server/request.js';
6
6
  import { generateRoutesTypings } from './route-typings.js';
7
- export async function createDevHandler({ vite, gracileConfig, }) {
7
+ export async function createDevHandler({ routes, vite, gracileConfig, }) {
8
8
  const root = vite.config.root;
9
9
  logger.info(c.dim('\nCreating handler…'), { timestamp: true });
10
- const routes = await collectRoutes(root, gracileConfig.routes?.exclude);
10
+ await collectRoutes(routes, root, gracileConfig.routes?.exclude);
11
11
  if (gracileConfig.experimental?.generateRoutesTypings)
12
12
  generateRoutesTypings(root, routes).catch((error) => logger.error(String(error)));
13
13
  vite.watcher.on('all', (event, file) => {
14
14
  // console.log({ event });
15
- if (file.match(/\/src\/routes\/(.*)\.(ts|js)$/) &&
15
+ if (file.match(/\/src\/routes\/(.*)\.(ts|js|css|scss|sass|less|styl|stylus)$/) &&
16
16
  ['add', 'unlink'].includes(event))
17
- collectRoutes(root, gracileConfig.routes?.exclude)
17
+ collectRoutes(routes, root, gracileConfig.routes?.exclude)
18
18
  .then(() => {
19
19
  vite.hot.send('vite:invalidate');
20
20
  if (gracileConfig.experimental?.generateRoutesTypings)
@@ -25,6 +25,12 @@ export async function createDevHandler({ vite, gracileConfig, }) {
25
25
  //
26
26
  // NOTE: Wrong place?
27
27
  const serverMode = false;
28
- const gracile = createGracileHandler({ vite, root, serverMode, routes });
29
- return { handler: gracile };
28
+ const gracile = createGracileHandler({
29
+ vite,
30
+ root,
31
+ serverMode,
32
+ routes,
33
+ gracileConfig,
34
+ });
35
+ return { handler: gracile, routes };
30
36
  }
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAItD,YAAY,EAAE,aAAa,EAAE,CAAC;AAI9B;;;;;;;;;;;;;;;;;GAiBG;AAGH,eAAO,MAAM,OAAO,YAAa,aAAa,KAAG,GAAG,EA4QnD,CAAC"}
1
+ {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAOtD,YAAY,EAAE,aAAa,EAAE,CAAC;AAI9B;;;;;;;;;;;;;;;;;GAiBG;AAIH,eAAO,MAAM,OAAO,YAAa,aAAa,KAAG,GAAG,EA4RnD,CAAC"}
package/dist/plugin.js CHANGED
@@ -7,7 +7,7 @@ import {} from './build/static.js';
7
7
  import { createDevHandler } from './dev/dev.js';
8
8
  import { nodeAdapter } from './server/adapters/node.js';
9
9
  import { buildRoutes } from './vite/plugins/build-routes.js';
10
- import { virtualRoutes } from './vite/plugins/virtual-routes.js';
10
+ import { virtualRoutes, virtualRoutesClient, } from './vite/plugins/virtual-routes.js';
11
11
  let isClientBuilt = false;
12
12
  /**
13
13
  * The main Vite plugin for loading the Gracile framework.
@@ -27,44 +27,54 @@ let isClientBuilt = false;
27
27
  * });
28
28
  * ```
29
29
  */
30
- // Return as `any` to avoid Plugin type mismatches when there are multiple Vite versions installed
30
+ // NOTE: for Vite versions mismatches with `exactOptionalPropertyTypes`?
31
+ // This `any[]` AND with a plugin -array- makes ESLint and TS shut up.
31
32
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
32
33
  export const gracile = (config) => {
33
34
  const outputMode = config?.output || 'static';
34
35
  const clientAssets = {};
35
- let routes = null;
36
+ const routes = new Map();
36
37
  let renderedRoutes = null;
37
38
  let root = null;
38
39
  const gracileConfig = config || {};
39
40
  if (isClientBuilt)
40
41
  return [];
41
42
  isClientBuilt = true;
43
+ const virtualRoutesForClient = virtualRoutesClient({
44
+ mode: outputMode,
45
+ routes,
46
+ // NOTE: This will be a dedicated setting when it will not be experimental
47
+ // anymore.
48
+ gracileConfig,
49
+ // enabled: gracileConfig?.pages?.premises?.expose || false,
50
+ });
42
51
  return [
43
- {
44
- name: 'gracile-routes-codegen',
45
- // watchChange(change) {
46
- // console.log({ change });
47
- // },
48
- resolveId(id) {
49
- const virtualModuleId = 'gracile:route';
50
- const resolvedVirtualModuleId = `\0${virtualModuleId}`;
51
- if (id === virtualModuleId) {
52
- return resolvedVirtualModuleId;
53
- }
54
- return null;
55
- },
56
- load(id) {
57
- const virtualModuleId = 'gracile:route';
58
- const resolvedVirtualModuleId = `\0${virtualModuleId}`;
59
- if (id === resolvedVirtualModuleId) {
60
- return `
61
- export function route(input){
62
- return input;
63
- }`;
64
- }
65
- return null;
66
- },
67
- },
52
+ // {
53
+ // name: 'gracile-routes-codegen',
54
+ // // watchChange(change) {
55
+ // // console.log({ change });
56
+ // // },
57
+ // resolveId(id) {
58
+ // const virtualModuleId = 'gracile:route';
59
+ // const resolvedVirtualModuleId = `\0${virtualModuleId}`;
60
+ // if (id === virtualModuleId) {
61
+ // return resolvedVirtualModuleId;
62
+ // }
63
+ // return null;
64
+ // },
65
+ // load(id) {
66
+ // const virtualModuleId = 'gracile:route';
67
+ // const resolvedVirtualModuleId = `\0${virtualModuleId}`;
68
+ // if (id === resolvedVirtualModuleId) {
69
+ // return `
70
+ // export function route(input){
71
+ // return input;
72
+ // }`;
73
+ // }
74
+ // return null;
75
+ // },
76
+ // },
77
+ virtualRoutesForClient,
68
78
  {
69
79
  name: 'vite-plugin-gracile-serve-middleware',
70
80
  apply: 'serve',
@@ -72,6 +82,9 @@ return input;
72
82
  return {
73
83
  // NOTE: Supresses message: `Could not auto-determine entry point from rollupOptions or html files…`
74
84
  optimizeDeps: { include: [] },
85
+ // resolve: {
86
+ // conditions: ['development'],
87
+ // },
75
88
  };
76
89
  },
77
90
  async configureServer(server) {
@@ -90,10 +103,11 @@ return input;
90
103
  // version: number;
91
104
  // };
92
105
  const version = process.env['__GRACILE_VERSION__'];
93
- logger.info(`${c.cyan(c.italic(c.underline('🧚 Gracile ')))}` +
94
- ` ${c.green(` v${version ?? 'X'}`)}`);
106
+ logger.info(`${c.cyan(c.italic(c.underline('🧚 Gracile')))}` +
107
+ ` ${c.dim(`~`)} ${c.green(`v${version ?? 'X'}`)}`);
95
108
  // ---
96
109
  const { handler } = await createDevHandler({
110
+ routes,
97
111
  vite: server,
98
112
  gracileConfig,
99
113
  });
@@ -115,14 +129,15 @@ return input;
115
129
  server: { middlewareMode: true },
116
130
  // NOTE: Stub. KEEP IT!
117
131
  optimizeDeps: { include: [] },
132
+ plugins: [virtualRoutesForClient],
118
133
  });
119
134
  const htmlPages = await buildRoutes({
120
135
  viteServerForBuild: viteServerForClientHtmlBuild,
121
136
  root: viteConfig.root || process.cwd(),
122
137
  gracileConfig,
123
138
  serverMode: outputMode === 'server',
139
+ routes,
124
140
  });
125
- routes = htmlPages.routes;
126
141
  renderedRoutes = htmlPages.renderedRoutes;
127
142
  await viteServerForClientHtmlBuild.close();
128
143
  return {
@@ -180,7 +195,6 @@ return input;
180
195
  // NOTE: Useful for, e.g., link tag with `?url`
181
196
  assetFileNames: (chunkInfo) => {
182
197
  if (chunkInfo.name) {
183
- // (chunkInfo);
184
198
  const fileName = clientAssets[chunkInfo.name];
185
199
  if (fileName)
186
200
  return fileName;
@@ -195,10 +209,8 @@ return input;
195
209
  },
196
210
  },
197
211
  plugins: [
198
- virtualRoutes({
199
- routes,
200
- renderedRoutes,
201
- }),
212
+ virtualRoutesForClient,
213
+ virtualRoutes({ routes, renderedRoutes }),
202
214
  {
203
215
  name: 'vite-plugin-gracile-entry',
204
216
  resolveId(id) {
@@ -211,16 +223,15 @@ return input;
211
223
  if (id === 'entrypoint.js' && routes && renderedRoutes) {
212
224
  return `
213
225
  import { routeAssets, routeImports, routes } from 'gracile:routes';
214
- import { createGracileMiddleware } from '@gracile/gracile/_internals/server-runtime';
215
-
216
- // ({ routeAssets, routeImports, routes })
226
+ import { createGracileHandler } from '@gracile/gracile/_internals/server-runtime';
217
227
 
218
- export const handler = createGracileMiddleware({
228
+ export const handler = createGracileHandler({
219
229
  root: process.cwd(),
220
230
  routes,
221
231
  routeImports,
222
232
  routeAssets,
223
233
  serverMode: true,
234
+ gracileConfig: ${JSON.stringify(gracileConfig, null, 2)}
224
235
  });
225
236
  `;
226
237
  }
@@ -0,0 +1,3 @@
1
+ export declare const SSR_OUTLET_MARKER = "<route-template-outlet></route-template-outlet>";
2
+ export declare const PAGE_ASSETS_MARKER = "<!--__GRACILE_PAGE_ASSETS__-->";
3
+ //# sourceMappingURL=markers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markers.d.ts","sourceRoot":"","sources":["../../src/render/markers.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,iBAAiB,oDACoB,CAAC;AAGnD,eAAO,MAAM,kBAAkB,mCAAmC,CAAC"}
@@ -0,0 +1,4 @@
1
+ // export const SSR_OUTLET_MARKER = '________SSR_OUTLET________';
2
+ export const SSR_OUTLET_MARKER = '<route-template-outlet></route-template-outlet>';
3
+ // const SSR_OUTLET = unsafeHTML(SSR_OUTLET_MARKER);
4
+ export const PAGE_ASSETS_MARKER = '<!--__GRACILE_PAGE_ASSETS__-->';
@@ -1,25 +1,20 @@
1
- import { Readable } from 'stream';
1
+ import { Readable } from 'node:stream';
2
2
  import type { ViteDevServer } from 'vite';
3
3
  import type { RouteInfos } from '../routes/match.js';
4
4
  import type * as R from '../routes/route.js';
5
- export declare const SSR_OUTLET_MARKER = "<route-template-outlet></route-template-outlet>";
6
- export declare const PAGE_ASSETS_MARKER = "<!--__GRACILE_PAGE_ASSETS__-->";
7
5
  export declare const REGEX_TAG_SCRIPT: RegExp;
8
6
  export declare const REGEX_TAG_LINK: RegExp;
9
- export type HandlerInfos = {
10
- data: unknown;
11
- method: string;
12
- };
13
- export declare function renderRouteTemplate({ request, vite, mode, routeInfos, handlerInfos, routeAssets, serverMode, }: {
14
- request: Request | R.StaticRequest;
7
+ export declare function renderRouteTemplate({ url, vite, mode, routeInfos, routeAssets, serverMode, docOnly, }: {
8
+ url: string;
15
9
  vite?: ViteDevServer | undefined;
16
10
  mode: 'dev' | 'build';
17
11
  routeInfos: RouteInfos;
18
- handlerInfos?: HandlerInfos | undefined;
19
12
  routeAssets?: R.RoutesAssets | undefined;
20
13
  root: string;
21
14
  serverMode?: boolean | undefined;
15
+ docOnly?: boolean | undefined;
22
16
  }): Promise<{
23
17
  output: null | Readable;
18
+ document: null | string;
24
19
  }>;
25
20
  //# sourceMappingURL=route-template.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"route-template.d.ts","sourceRoot":"","sources":["../../src/render/route-template.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAClC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,MAAM,CAAC;AAG1C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,KAAK,KAAK,CAAC,MAAM,oBAAoB,CAAC;AAa7C,eAAO,MAAM,iBAAiB,oDACoB,CAAC;AAGnD,eAAO,MAAM,kBAAkB,mCAAmC,CAAC;AAEnE,eAAO,MAAM,gBAAgB,QACkC,CAAC;AAEhE,eAAO,MAAM,cAAc,QAA2B,CAAC;AAEvD,MAAM,MAAM,YAAY,GAAG;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAE7D,wBAAsB,mBAAmB,CAAC,EACzC,OAAO,EACP,IAAI,EACJ,IAAI,EACJ,UAAU,EACV,YAAY,EACZ,WAAW,EAEX,UAAU,GACV,EAAE;IACF,OAAO,EAAE,OAAO,GAAG,CAAC,CAAC,aAAa,CAAC;IACnC,IAAI,CAAC,EAAE,aAAa,GAAG,SAAS,CAAC;IACjC,IAAI,EAAE,KAAK,GAAG,OAAO,CAAC;IACtB,UAAU,EAAE,UAAU,CAAC;IACvB,YAAY,CAAC,EAAE,YAAY,GAAG,SAAS,CAAC;IACxC,WAAW,CAAC,EAAE,CAAC,CAAC,YAAY,GAAG,SAAS,CAAC;IACzC,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CACjC,GAAG,OAAO,CAAC;IAAE,MAAM,EAAE,IAAI,GAAG,QAAQ,CAAA;CAAE,CAAC,CA0LvC"}
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;AAKvC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,MAAM,CAAC;AAG1C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,KAAK,KAAK,CAAC,MAAM,oBAAoB,CAAC;AAa7C,eAAO,MAAM,gBAAgB,QACkC,CAAC;AAEhE,eAAO,MAAM,cAAc,QAA2B,CAAC;AAEvD,wBAAsB,mBAAmB,CAAC,EACzC,GAAG,EACH,IAAI,EACJ,IAAI,EACJ,UAAU,EACV,WAAW,EACX,UAAU,EACV,OAAO,GACP,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;CAC9B,GAAG,OAAO,CAAC;IAAE,MAAM,EAAE,IAAI,GAAG,QAAQ,CAAC;IAAC,QAAQ,EAAE,IAAI,GAAG,MAAM,CAAA;CAAE,CAAC,CAwLhE"}
@@ -1,8 +1,9 @@
1
+ import { Readable } from 'node:stream';
1
2
  import { html } from '@gracile/internal-utils/dummy-literals';
2
3
  import { render as renderLitSsr } from '@lit-labs/ssr';
3
4
  import { collectResult } from '@lit-labs/ssr/lib/render-result.js';
4
- import { Readable } from 'stream';
5
5
  import { isLitServerTemplate, isLitTemplate } from '../assertions.js';
6
+ import { PAGE_ASSETS_MARKER, SSR_OUTLET_MARKER } from './markers.js';
6
7
  async function* concatStreams(...readables) {
7
8
  // eslint-disable-next-line no-restricted-syntax
8
9
  for (const readable of readables) {
@@ -12,26 +13,16 @@ async function* concatStreams(...readables) {
12
13
  }
13
14
  }
14
15
  }
15
- // export const SSR_OUTLET_MARKER = '________SSR_OUTLET________';
16
- export const SSR_OUTLET_MARKER = '<route-template-outlet></route-template-outlet>';
17
- // const SSR_OUTLET = unsafeHTML(SSR_OUTLET_MARKER);
18
- export const PAGE_ASSETS_MARKER = '<!--__GRACILE_PAGE_ASSETS__-->';
19
16
  export const REGEX_TAG_SCRIPT = /\s?<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script\s*>\s?/gi;
20
17
  export const REGEX_TAG_LINK = /\s?<link\b[^>]*?>\s?/gi;
21
- export async function renderRouteTemplate({ request, vite, mode, routeInfos, handlerInfos, routeAssets,
22
- // root,
23
- serverMode, }) {
18
+ export async function renderRouteTemplate({ url, vite, mode, routeInfos, routeAssets, serverMode, docOnly, }) {
24
19
  if (!routeInfos.routeModule.document && !routeInfos.routeModule.template)
25
- return { output: null };
20
+ return { output: null, document: null };
26
21
  // MARK: Context
27
22
  const context = {
28
- url: new URL(request.url),
23
+ url: new URL(url),
29
24
  params: routeInfos.params,
30
- props: handlerInfos?.data
31
- ? {
32
- [handlerInfos.method]: handlerInfos.data,
33
- }
34
- : routeInfos.props,
25
+ props: routeInfos.props,
35
26
  };
36
27
  // MARK: Fragment
37
28
  if (!routeInfos.routeModule.document && routeInfos.routeModule.template) {
@@ -40,7 +31,7 @@ serverMode, }) {
40
31
  throw Error(`Wrong template result for fragment template ${routeInfos.foundRoute.filePath}.`);
41
32
  const fragmentRender = renderLitSsr(fragmentOutput);
42
33
  const output = Readable.from(fragmentRender);
43
- return { output };
34
+ return { output, document: null };
44
35
  }
45
36
  // MARK: Document
46
37
  if (!routeInfos.routeModule.document ||
@@ -54,29 +45,28 @@ serverMode, }) {
54
45
  let baseDocRenderedWithAssets = baseDocRendered;
55
46
  // If the user doesnt use `pageAssetCustomLocation`, we put this as a fallback
56
47
  baseDocRenderedWithAssets = baseDocRenderedWithAssets
57
- .replace('</head>', `${PAGE_ASSETS_MARKER}</head>`)
48
+ .replace('</head>', `\n${PAGE_ASSETS_MARKER}</head>`)
58
49
  .replace(PAGE_ASSETS_MARKER,
59
50
  // eslint-disable-next-line prefer-template
60
- html `
61
- <!-- PAGE ASSETS -->
62
- ${routeInfos.foundRoute.pageAssets.map((path) => {
63
- //
64
- if (/\.(js|ts)$/.test(path)) {
65
- return html `
66
- <script type="module" src="/${path}"></script>
67
- <!-- -->
68
- `;
69
- }
70
- if (/\.(css|scss|sass|less|styl|stylus)$/.test(path)) {
71
- return html `
72
- <link rel="stylesheet" href="/${path}" />
73
- <!-- -->
74
- `;
75
- }
76
- throw new Error('Unknown asset.');
77
- })}
78
- <!-- /PAGE ASSETS -->
79
- `);
51
+ routeInfos.foundRoute.pageAssets.length
52
+ ? // eslint-disable-next-line prefer-template
53
+ html `<!-- PAGE ASSETS -->` +
54
+ `${routeInfos.foundRoute.pageAssets
55
+ .map((path) => {
56
+ //
57
+ if (/\.(js|ts)$/.test(path)) {
58
+ // prettier-ignore
59
+ return html ` <script type="module" src="/${path}"></script>`;
60
+ }
61
+ if (/\.(css|scss|sass|less|styl|stylus)$/.test(path)) {
62
+ // prettier-ignore
63
+ return html ` <link rel="stylesheet" href="/${path}" />`;
64
+ }
65
+ throw new Error('Unknown asset.');
66
+ })
67
+ .join('\n')}` +
68
+ `<!-- /PAGE ASSETS -->\n `
69
+ : '');
80
70
  // MARK: Dev. overlay
81
71
  // TODO: Need more testing and refinement (refreshes kills its usefulness)
82
72
  const overlay = () => html `
@@ -118,6 +108,8 @@ serverMode, }) {
118
108
  // `${routeInfos.pathname}?r=${Math.random()}`,
119
109
  routeInfos.pathname, baseDocRenderedWithAssets)
120
110
  : baseDocRenderedWithAssets;
111
+ if (docOnly)
112
+ return { document: baseDocHtml, output: null };
121
113
  const index = baseDocHtml.indexOf(SSR_OUTLET_MARKER);
122
114
  const baseDocRenderStreamPre = Readable.from(baseDocHtml.substring(0, index));
123
115
  const baseDocRenderStreamPost = Readable.from(baseDocHtml.substring(index + SSR_OUTLET_MARKER.length + 1));
@@ -134,15 +126,15 @@ serverMode, }) {
134
126
  // const output = Readable.from(
135
127
  // concatStreams(baseDocRenderStreamPre, baseDocRenderStreamPost),
136
128
  // );
137
- // return { output };
129
+ // return { output, document: null };
138
130
  // }
139
131
  if (isLitTemplate(routeOutput) === false)
140
132
  throw Error(`Wrong template result for page template ${routeInfos.foundRoute.filePath}.`);
141
133
  const renderStream = Readable.from(renderLitSsr(routeOutput));
142
134
  const output = Readable.from(concatStreams(baseDocRenderStreamPre, renderStream, baseDocRenderStreamPost));
143
- return { output };
135
+ return { output, document: baseDocHtml };
144
136
  }
145
137
  // MARK: Just the document
146
138
  const output = Readable.from(baseDocHtml);
147
- return { output };
139
+ return { output, document: baseDocHtml };
148
140
  }
@@ -1,3 +1,26 @@
1
1
  import { type ServerRenderedTemplate } from '@lit-labs/ssr';
2
- export declare function renderSsrTemplate(template: ServerRenderedTemplate): Promise<string>;
2
+ import type { TemplateResult } from 'lit';
3
+ /**
4
+ * Just a tiny wrapper for `render` and `collectResult` from `@lit-labs/ssr`.
5
+ *
6
+ * Useful for testing server only partials.
7
+ *
8
+ * @example
9
+ * ```js
10
+ * import assert from 'node:assert';
11
+ * import {
12
+ * html,
13
+ * type ServerRenderedTemplate,
14
+ * } from '@gracile/gracile/server-html';
15
+ *
16
+ * const myServerTemplate1 = (): ServerRenderedTemplate => html`
17
+ * <div>Hello</div>
18
+ * `;
19
+ *
20
+ * const result = await renderLitTemplate(myServerTemplate1());
21
+ *
22
+ * assert.match(result, /Hello/);
23
+ * ```
24
+ */
25
+ export declare function renderLitTemplate(template: ServerRenderedTemplate | TemplateResult<1>): Promise<string>;
3
26
  //# sourceMappingURL=utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/render/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAEN,KAAK,sBAAsB,EAC3B,MAAM,eAAe,CAAC;AAGvB,wBAAsB,iBAAiB,CAAC,QAAQ,EAAE,sBAAsB,mBAEvE"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/render/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAEN,KAAK,sBAAsB,EAC3B,MAAM,eAAe,CAAC;AAEvB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,KAAK,CAAC;AAE1C;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAsB,iBAAiB,CACtC,QAAQ,EAAE,sBAAsB,GAAG,cAAc,CAAC,CAAC,CAAC,GAClD,OAAO,CAAC,MAAM,CAAC,CAEjB"}
@@ -1,5 +1,27 @@
1
1
  import { render as renderLitSsr, } from '@lit-labs/ssr';
2
2
  import { collectResult } from '@lit-labs/ssr/lib/render-result.js';
3
- export async function renderSsrTemplate(template) {
3
+ /**
4
+ * Just a tiny wrapper for `render` and `collectResult` from `@lit-labs/ssr`.
5
+ *
6
+ * Useful for testing server only partials.
7
+ *
8
+ * @example
9
+ * ```js
10
+ * import assert from 'node:assert';
11
+ * import {
12
+ * html,
13
+ * type ServerRenderedTemplate,
14
+ * } from '@gracile/gracile/server-html';
15
+ *
16
+ * const myServerTemplate1 = (): ServerRenderedTemplate => html`
17
+ * <div>Hello</div>
18
+ * `;
19
+ *
20
+ * const result = await renderLitTemplate(myServerTemplate1());
21
+ *
22
+ * assert.match(result, /Hello/);
23
+ * ```
24
+ */
25
+ export async function renderLitTemplate(template) {
4
26
  return collectResult(renderLitSsr(template));
5
27
  }
@@ -1,3 +1,3 @@
1
1
  import type * as R from './route.js';
2
- export declare function collectRoutes(root: string, excludePatterns?: string[]): Promise<R.RoutesManifest>;
2
+ export declare function collectRoutes(routes: R.RoutesManifest, root: string, excludePatterns?: string[]): Promise<R.RoutesManifest>;
3
3
  //# sourceMappingURL=collect.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"collect.d.ts","sourceRoot":"","sources":["../../src/routes/collect.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,KAAK,CAAC,MAAM,YAAY,CAAC;AA4DrC,wBAAsB,aAAa,CAClC,IAAI,EAAE,MAAM,EACZ,eAAe,GAAE,MAAM,EAAO,GAE5B,OAAO,CAAC,CAAC,CAAC,cAAc,CAAC,CA+F3B"}
1
+ {"version":3,"file":"collect.d.ts","sourceRoot":"","sources":["../../src/routes/collect.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,KAAK,CAAC,MAAM,YAAY,CAAC;AA4DrC,wBAAsB,aAAa,CAClC,MAAM,EAAE,CAAC,CAAC,cAAc,EACxB,IAAI,EAAE,MAAM,EACZ,eAAe,GAAE,MAAM,EAAO,GAE5B,OAAO,CAAC,CAAC,CAAC,cAAc,CAAC,CA+F3B"}
@@ -48,8 +48,8 @@ function extractRoutePatterns(routeFilePath) {
48
48
  hasParams,
49
49
  };
50
50
  }
51
- const routes = new Map();
52
- export async function collectRoutes(root /* vite: ViteDevServer */, excludePatterns = []) {
51
+ // const routes: R.RoutesManifest = new Map<string, R.Route>();
52
+ export async function collectRoutes(routes, root /* vite: ViteDevServer */, excludePatterns = []) {
53
53
  routes.clear();
54
54
  const routesFolder = 'src/routes';
55
55
  const routesFolderAbsolute = join(root, routesFolder);
@@ -19,14 +19,14 @@ function matchRouteFromUrl(url, routes) {
19
19
  const params = Object.freeze({ ...match.pathname.groups });
20
20
  return { match, foundRoute, params, pathname };
21
21
  }
22
- function extractStaticPaths(options) {
22
+ async function extractStaticPaths(options) {
23
23
  if (!options.foundRoute.hasParams)
24
24
  return null;
25
25
  if (!options.routeModule.staticPaths)
26
26
  return null;
27
27
  const routeStaticPaths = options.routeModule.staticPaths;
28
28
  let props;
29
- const staticPaths = routeStaticPaths();
29
+ const staticPaths = await Promise.resolve(routeStaticPaths());
30
30
  let hasCorrectParams = false;
31
31
  staticPaths.forEach((providedRouteOptions) => {
32
32
  const routeOptions = providedRouteOptions;
@@ -50,7 +50,7 @@ export async function getRoute(options) {
50
50
  route: foundRoute,
51
51
  routeImports: options.routeImports,
52
52
  });
53
- const staticPaths = extractStaticPaths({
53
+ const staticPaths = await extractStaticPaths({
54
54
  routeModule,
55
55
  foundRoute,
56
56
  pathname,