@gracile/engine 0.6.0 → 0.7.0-next.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) 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 +38 -8
  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 +32 -19
  7. package/dist/dev/vite-logger.d.ts +2 -0
  8. package/dist/dev/vite-logger.d.ts.map +1 -0
  9. package/dist/dev/vite-logger.js +2 -0
  10. package/dist/errors/create-vite-better-error.d.ts +6 -0
  11. package/dist/errors/create-vite-better-error.d.ts.map +1 -0
  12. package/dist/errors/create-vite-better-error.js +27 -0
  13. package/dist/errors/errors-data.d.ts +81 -0
  14. package/dist/errors/errors-data.d.ts.map +1 -0
  15. package/dist/errors/errors-data.js +98 -0
  16. package/dist/errors/errors.d.ts +22 -0
  17. package/dist/errors/errors.d.ts.map +1 -0
  18. package/dist/errors/errors.js +122 -0
  19. package/dist/errors/pages.d.ts +4 -0
  20. package/dist/errors/pages.d.ts.map +1 -0
  21. package/dist/errors/pages.js +135 -0
  22. package/dist/logging/messages.d.ts +2 -0
  23. package/dist/logging/messages.d.ts.map +1 -0
  24. package/dist/logging/messages.js +6 -0
  25. package/dist/plugin.d.ts.map +1 -1
  26. package/dist/plugin.js +82 -43
  27. package/dist/render/markers.d.ts +3 -0
  28. package/dist/render/markers.d.ts.map +1 -0
  29. package/dist/render/markers.js +4 -0
  30. package/dist/render/route-template.d.ts +5 -10
  31. package/dist/render/route-template.d.ts.map +1 -1
  32. package/dist/render/route-template.js +68 -48
  33. package/dist/render/utils.d.ts +24 -1
  34. package/dist/render/utils.d.ts.map +1 -1
  35. package/dist/render/utils.js +23 -1
  36. package/dist/routes/collect.d.ts +2 -1
  37. package/dist/routes/collect.d.ts.map +1 -1
  38. package/dist/routes/collect.js +15 -11
  39. package/dist/routes/load-module.d.ts +1 -1
  40. package/dist/routes/load-module.d.ts.map +1 -1
  41. package/dist/routes/load-module.js +31 -5
  42. package/dist/routes/match.d.ts +1 -1
  43. package/dist/routes/match.d.ts.map +1 -1
  44. package/dist/routes/match.js +26 -12
  45. package/dist/routes/route.d.ts +2 -2
  46. package/dist/routes/route.d.ts.map +1 -1
  47. package/dist/routes/route.js +14 -12
  48. package/dist/server/adapters/hono.d.ts +5 -2
  49. package/dist/server/adapters/hono.d.ts.map +1 -1
  50. package/dist/server/adapters/hono.js +12 -6
  51. package/dist/server/adapters/node.d.ts +4 -2
  52. package/dist/server/adapters/node.d.ts.map +1 -1
  53. package/dist/server/adapters/node.js +27 -12
  54. package/dist/server/constants.d.ts +1 -1
  55. package/dist/server/constants.d.ts.map +1 -1
  56. package/dist/server/constants.js +1 -1
  57. package/dist/server/request.d.ts +7 -2
  58. package/dist/server/request.d.ts.map +1 -1
  59. package/dist/server/request.js +95 -69
  60. package/dist/server/utils.d.ts.map +1 -1
  61. package/dist/server/utils.js +5 -4
  62. package/dist/tsconfig.tsbuildinfo +1 -1
  63. package/dist/user-config.d.ts +35 -1
  64. package/dist/user-config.d.ts.map +1 -1
  65. package/dist/vite/plugins/build-routes.d.ts +6 -2
  66. package/dist/vite/plugins/build-routes.d.ts.map +1 -1
  67. package/dist/vite/plugins/build-routes.js +69 -35
  68. package/dist/vite/plugins/virtual-routes.d.ts +10 -0
  69. package/dist/vite/plugins/virtual-routes.d.ts.map +1 -1
  70. package/dist/vite/plugins/virtual-routes.js +56 -4
  71. package/package.json +10 -11
  72. package/dist/assertions.d.ts +0 -13
  73. package/dist/assertions.d.ts.map +0 -1
  74. package/dist/assertions.js +0 -45
  75. package/dist/errors/templates.d.ts +0 -3
  76. package/dist/errors/templates.d.ts.map +0 -1
  77. package/dist/errors/templates.js +0 -69
@@ -0,0 +1,135 @@
1
+ import { html } from '@lit-labs/ssr';
2
+ export function errorInline(error) {
3
+ return html `<!-- --></a>
4
+ <div data-ssr-error>
5
+ <strong style="color: red">SSR Template error!</strong>
6
+ <details>
7
+ <summary style="user-select: none; cursor: pointer">Stack trace</summary>
8
+ <pre style="overflow: auto">${error.stack}</pre>
9
+ </details>
10
+ </div>`;
11
+ }
12
+ const minimalStyles = () => html `<style>
13
+ html {
14
+ color-scheme: light dark;
15
+ font-size: 16px;
16
+ line-height: 1.23rem;
17
+ font-family: system-ui;
18
+ }
19
+ </style>`;
20
+ const logo = () =>
21
+ /* prettier-ignore */
22
+ html `<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2" viewBox="0 0 630 630"><g transform="matrix(.877 .23499 -.25635 .95673 119.498 -60.39)"><circle cx="315" cy="315" r="315" style="fill:url(#a)"/><path d="M315 0c173.853 0 315 141.147 315 315S488.853 630 315 630 0 488.853 0 315 141.147 0 315 0Zm0 13.125c166.309 0 300.682 135.566 300.682 301.875S481.309 616.875 315 616.875C148.691 616.875 14.318 481.309 14.318 315S148.691 13.125 315 13.125Z" style="fill:#1a1a1e"/></g><path d="M.238.087A.195.195 0 0 1 .135.058.215.215 0 0 1 .06-.029a.293.293 0 0 1-.028-.135c0-.051.008-.103.024-.156a.699.699 0 0 1 .162-.278.475.475 0 0 1 .115-.089.258.258 0 0 1 .121-.032.14.14 0 0 1 .07.016c.017.011.03.026.038.044a.158.158 0 0 1 .011.058.215.215 0 0 1-.012.07.181.181 0 0 1-.034.058C.512-.458.496-.45.479-.45a.036.036 0 0 1-.022-.007.073.073 0 0 1-.02-.026.162.162 0 0 0 .034-.035.303.303 0 0 0 .032-.056.135.135 0 0 0 .014-.054.05.05 0 0 0-.012-.034C.496-.671.482-.675.463-.675a.16.16 0 0 0-.092.033.447.447 0 0 0-.091.089.764.764 0 0 0-.152.4c0 .061.013.108.04.141.026.034.057.051.094.051A.127.127 0 0 0 .338.013a.243.243 0 0 0 .061-.069.454.454 0 0 0 .062-.19.9.9 0 0 0-.051-.008 1.011 1.011 0 0 0-.056-.002H.322l-.034.002a.1.1 0 0 1 .029-.052.076.076 0 0 1 .051-.016c.02 0 .04.003.061.009a4.452 4.452 0 0 0 .123.039l-.01.031-.029.091a.854.854 0 0 0-.026.108l-.002.043.001.042.002.052C.468.09.453.085.444.076A.063.063 0 0 1 .425.044.148.148 0 0 1 .42.009v-.01l.001-.01a.317.317 0 0 1-.08.071.2.2 0 0 1-.103.027Z" style="fill-rule:nonzero" transform="translate(115.745 497.368) scale(589.0308)"/><path d="M6516.9 5139.28c-23.64 24.86-49.83 45.96-78.54 63.32-38.12 23.04-81.04 34.61-128.8 34.61-46.96 0-90.14-12.37-129.56-37.11-39.27-24.65-70.68-60.51-94.08-107.72-23.09-46.59-34.76-102.43-34.76-167.57 0-62.67 9.75-126.16 29.28-190.46 19.46-64.05 46.21-125.05 80.26-183.02 34.06-57.99 73-109.68 116.79-155.1 44.07-45.7 90.8-81.78 140.17-108.29 50.15-26.95 100.53-40.34 151.1-40.34 37.75 0 67.7 7.39 90.01 21.55 22.8 14.47 39.21 33.58 49.3 57.27 9.78 22.96 14.7 47.62 14.7 73.99 0 29.25-5.21 58.51-15.66 87.77-10.56 29.57-24.99 54.04-43.16 73.48-19.63 20.99-41.46 31.15-65.19 31.15-11.93 0-22.88-3.46-32.82-10.42-9.08-6.35-18.42-17.93-27.5-35.16-2.67-5.08-1.07-11.36 3.71-14.55 11.2-7.47 23.58-20.66 37.4-39.34 14.36-19.4 26.96-40.94 37.83-64.61 10.4-22.67 15.78-42.88 15.78-60.72 0-12.95-3.93-23.85-12.02-32.59-8.3-8.96-22.33-12.61-41.58-12.61-33.94 0-68.72 12.89-104.54 38.15-37.17 26.22-72.55 61.08-106.2 104.51-33.98 43.85-64.59 92.85-91.85 146.98-27.27 54.14-48.81 109.46-64.62 165.98-15.7 56.14-23.58 109.33-23.58 159.58 0 69.79 14.72 124.16 45.02 162.89 29.19 37.32 63.93 56.3 104.57 56.3 30.37 0 58.3-9.68 83.86-28.94 26.57-20.03 50.02-46.45 70.43-79.18 20.72-33.23 37.33-69.39 49.84-108.49 11.42-35.68 18.94-70.7 22.56-105.08-16.51-3-33.42-5.31-50.74-6.95-20.87-1.97-42.72-2.95-65.55-2.95-12.68 0-25.37.2-38.05.6-12.71.39-26.22.99-40.53 1.78a11.194 11.194 0 0 1-11.47-13.97c7.89-30.7 20.71-53.1 37.81-67.57 17.46-14.76 40.4-22.45 69.04-22.45 25.1 0 50.41 3.96 75.93 11.91 24.52 7.64 49.44 15.88 74.77 24.72 24.8 8.66 49.02 15.75 72.65 21.27 3.05.71 5.66 2.66 7.2 5.39 1.55 2.73 1.88 5.98.92 8.96 0 0-12 37.2-12.02 37.24-14.39 43.95-26.17 80.52-35.36 109.68-9.1 28.89-16.03 53.42-20.78 73.6-4.67 19.86-7.8 37.76-9.36 53.72-1.56 16.06-2.34 32.69-2.34 49.92 0 15.83.39 32.26 1.18 49.28.81 17.24 1.61 38.29 2.41 63.16.11 3.29-1.24 6.46-3.68 8.67a11.2 11.2 0 0 1-9 2.79c-26.84-3.58-46.58-11.82-59.55-23.9-13.28-12.36-21.92-26.81-26.04-43.29-3.23-12.91-5.09-25.52-5.59-37.84Zm-207.34 86.73c-44.8 0-86-11.8-123.6-35.4-37.6-23.6-67.6-58-90-103.2-22.4-45.2-33.6-99.4-33.6-162.6 0-61.6 9.6-124 28.8-187.2 19.2-63.2 45.6-123.4 79.2-180.6 33.6-57.2 72-108.2 115.2-153s89-80.2 137.4-106.2c48.4-26 97-39 145.8-39 35.2 0 63.2 6.6 84 19.8 20.8 13.2 35.8 30.6 45 52.2 9.2 21.6 13.8 44.8 13.8 69.6 0 28-5 56-15 84s-23.6 51.2-40.8 69.6c-17.2 18.4-36.2 27.6-57 27.6-9.6 0-18.4-2.8-26.4-8.4-8-5.6-16-16-24-31.2 12-8 25.4-22 40.2-42 14.8-20 27.8-42.2 39-66.6 11.2-24.4 16.8-46.2 16.8-65.4 0-16-5-29.4-15-40.2-10-10.8-26.6-16.2-49.8-16.2-36 0-73 13.4-111 40.2-38 26.8-74.2 62.4-108.6 106.8-34.4 44.4-65.4 94-93 148.8-27.6 54.8-49.4 110.8-65.4 168-16 57.2-24 111.4-24 162.6 0 72.8 15.8 129.4 47.4 169.8 31.6 40.4 69.4 60.6 113.4 60.6 32.8 0 63-10.4 90.6-31.2 27.6-20.8 52-48.2 73.2-82.2 21.2-34 38.2-71 51-111 12.8-40 20.8-79.2 24-117.6-20-4-40.6-7-61.8-9-21.2-2-43.4-3-66.6-3-12.8 0-25.6.2-38.4.6-12.8.4-26.4 1-40.8 1.8 7.2-28 18.6-48.6 34.2-61.8 15.6-13.2 36.2-19.8 61.8-19.8 24 0 48.2 3.8 72.6 11.4 24.4 7.6 49.2 15.8 74.4 24.6 25.2 8.8 49.8 16 73.8 21.6l-12 37.2c-14.4 44-26.2 80.6-35.4 109.8-9.2 29.2-16.2 54-21 74.4-4.8 20.4-8 38.8-9.6 55.2-1.6 16.4-2.4 33.4-2.4 51 0 16 .4 32.6 1.2 49.8.8 17.2 1.6 38.2 2.4 63-24-3.2-41.8-10.2-53.4-21-11.6-10.8-19.2-23.4-22.8-37.8-3.6-14.4-5.4-28.4-5.4-42v-12c0-4 .4-8 1.2-12-28 34.4-60.2 62.6-96.6 84.6-36.4 22-77.4 33-123 33Z" style="fill:#fff" transform="matrix(.49086 0 0 .49086 -2841.17 -2016.62)"/><defs><radialGradient id="a" cx="0" cy="0" r="1" gradientTransform="matrix(315 0 0 315 315 315)" gradientUnits="userSpaceOnUse"><stop offset="0" style="stop-color:white;stop-opacity:1"/><stop offset="1" style="stop-color:#57d5a3;stop-opacity:1"/></radialGradient></defs></svg>`;
23
+ export function builtIn404Page(path, dev = false) {
24
+ return html `
25
+ <!doctype html>
26
+ <html lang="en">
27
+ <head>
28
+ <meta charset="UTF-8" />
29
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
30
+ <meta name="generator" content="Gracile" />
31
+ <title>404: Not found</title>
32
+
33
+ ${minimalStyles()}
34
+ <style>
35
+ body {
36
+ padding: 1rem;
37
+ }
38
+
39
+ pre {
40
+ padding: 0.5rem 0.75rem;
41
+
42
+ overflow-y: auto;
43
+ }
44
+
45
+ button {
46
+ font-size: 2rem;
47
+ }
48
+
49
+ h1 {
50
+ color: tomato;
51
+ }
52
+
53
+ pre {
54
+ border: 1px solid grey;
55
+ border-radius: 0.15rem;
56
+ padding: 1rem;
57
+ }
58
+
59
+ .middle {
60
+ width: 100%;
61
+ height: 100dvh;
62
+ display: flex;
63
+ align-items: center;
64
+ justify-content: center;
65
+ flex-direction: column;
66
+ position: relative;
67
+ top: -5dvh;
68
+ }
69
+
70
+ .gracile-logo {
71
+ height: 8rem;
72
+ width: 8rem;
73
+ margin: 4rem;
74
+ }
75
+
76
+ section {
77
+ text-align: center;
78
+ }
79
+ </style>
80
+ </head>
81
+ <body>
82
+ <main class="middle">
83
+ <div class="gracile-logo">${logo()}</div>
84
+
85
+ <h1>404: Not found</h1>
86
+
87
+ <section>
88
+ <div>Path:</div>
89
+ <pre>${path}</pre>
90
+ </section>
91
+
92
+ ${dev
93
+ ? html ` <section>
94
+ <p>The page or route may be not configured properly.</p>
95
+
96
+ <p>
97
+ See
98
+ <a
99
+ target="_blank"
100
+ href="https://gracile.js.org/docs/learn/usage/defining-routes/"
101
+ >Defining routes</a
102
+ >
103
+ in the documentation.
104
+ </p>
105
+ </section>`
106
+ : null}
107
+ </main>
108
+ </body>
109
+ </html>
110
+ `;
111
+ }
112
+ // TODO: Extract
113
+ // const ESCAPE_SEQUENCE_CHARACTER =
114
+ // // eslint-disable-next-line no-control-regex
115
+ // /[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g;
116
+ export function builtInErrorPage(name = 'Error', dev = false) {
117
+ const title = `500: ${name ? `${name} | ` : ''}Internal Server Error`;
118
+ return html `
119
+ <!doctype html>
120
+ <html lang="en">
121
+ <head>
122
+ <meta charset="UTF-8" />
123
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
124
+ <title>${title}</title>
125
+ ${minimalStyles()}
126
+ ${dev
127
+ ? html `<script type="module" src="/@vite/client"></script>`
128
+ : null}
129
+ </head>
130
+ <body>
131
+ <h1>${title}</h1>
132
+ </body>
133
+ </html>
134
+ `;
135
+ }
@@ -0,0 +1,2 @@
1
+ export declare function emptyRoutes(): string;
2
+ //# sourceMappingURL=messages.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../src/logging/messages.ts"],"names":[],"mappings":"AAEA,wBAAgB,WAAW,WAO1B"}
@@ -0,0 +1,6 @@
1
+ import c from 'picocolors';
2
+ export function emptyRoutes() {
3
+ const message = c.yellow(`No route were found in the \`src/routes/\` folder.\n\n`) +
4
+ c.magenta(`▶ See https://gracile.js.org/docs/learn/usage/defining-routes/.`);
5
+ return `${message}\n`;
6
+ }
@@ -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":"AAeA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAOtD,YAAY,EAAE,aAAa,EAAE,CAAC;AAI9B;;;;;;;;;;;;;;;;;GAiBG;AAIH,eAAO,MAAM,OAAO,YAAa,aAAa,KAAG,GAAG,EAyTnD,CAAC"}
package/dist/plugin.js CHANGED
@@ -1,5 +1,7 @@
1
1
  import { join } from 'node:path';
2
- import { logger } from '@gracile/internal-utils/logger';
2
+ import { createLogger } from '@gracile/internal-utils/logger/helpers';
3
+ import { getVersion } from '@gracile/internal-utils/version';
4
+ import { betterErrors } from '@gracile-labs/better-errors/plugin';
3
5
  import { rename, rm } from 'fs/promises';
4
6
  import c from 'picocolors';
5
7
  import { build, createServer } from 'vite';
@@ -7,7 +9,7 @@ import {} from './build/static.js';
7
9
  import { createDevHandler } from './dev/dev.js';
8
10
  import { nodeAdapter } from './server/adapters/node.js';
9
11
  import { buildRoutes } from './vite/plugins/build-routes.js';
10
- import { virtualRoutes } from './vite/plugins/virtual-routes.js';
12
+ import { virtualRoutes, virtualRoutesClient, } from './vite/plugins/virtual-routes.js';
11
13
  let isClientBuilt = false;
12
14
  /**
13
15
  * The main Vite plugin for loading the Gracile framework.
@@ -27,51 +29,73 @@ let isClientBuilt = false;
27
29
  * });
28
30
  * ```
29
31
  */
30
- // Return as `any` to avoid Plugin type mismatches when there are multiple Vite versions installed
32
+ // NOTE: for Vite versions mismatches with `exactOptionalPropertyTypes`?
33
+ // This `any[]` AND with a plugin -array- makes ESLint and TS shut up.
31
34
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
32
35
  export const gracile = (config) => {
36
+ const logger = createLogger();
33
37
  const outputMode = config?.output || 'static';
34
38
  const clientAssets = {};
35
- let routes = null;
39
+ const routes = new Map();
36
40
  let renderedRoutes = null;
37
41
  let root = null;
38
42
  const gracileConfig = config || {};
39
43
  if (isClientBuilt)
40
44
  return [];
41
45
  isClientBuilt = true;
46
+ const virtualRoutesForClient = virtualRoutesClient({
47
+ mode: outputMode,
48
+ routes,
49
+ // NOTE: This will be a dedicated setting when it will not be experimental
50
+ // anymore.
51
+ gracileConfig,
52
+ // enabled: gracileConfig?.pages?.premises?.expose || false,
53
+ });
42
54
  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
- },
55
+ betterErrors({
56
+ overlayImportPath: '@gracile/gracile/_internals/vite-custom-overlay',
57
+ }),
58
+ // {
59
+ // name: 'gracile-routes-codegen',
60
+ // // watchChange(change) {
61
+ // // console.log({ change });
62
+ // // },
63
+ // resolveId(id) {
64
+ // const virtualModuleId = 'gracile:route';
65
+ // const resolvedVirtualModuleId = `\0${virtualModuleId}`;
66
+ // if (id === virtualModuleId) {
67
+ // return resolvedVirtualModuleId;
68
+ // }
69
+ // return null;
70
+ // },
71
+ // load(id) {
72
+ // const virtualModuleId = 'gracile:route';
73
+ // const resolvedVirtualModuleId = `\0${virtualModuleId}`;
74
+ // if (id === resolvedVirtualModuleId) {
75
+ // return `
76
+ // export function route(input){
77
+ // return input;
78
+ // }`;
79
+ // }
80
+ // return null;
81
+ // },
82
+ // },
68
83
  {
69
84
  name: 'vite-plugin-gracile-serve-middleware',
70
85
  apply: 'serve',
71
- config() {
86
+ config(_, env) {
87
+ if (env.isPreview)
88
+ return null;
72
89
  return {
73
90
  // NOTE: Supresses message: `Could not auto-determine entry point from rollupOptions or html files…`
91
+ // FIXME: It's not working when reloading the Vite config.
92
+ // Is user config, putting `optimizeDeps: { include: [] }` solve this.
74
93
  optimizeDeps: { include: [] },
94
+ // NOTE: Useful? It breaks preview (expected)
95
+ appType: 'custom',
96
+ // resolve: {
97
+ // conditions: ['development'],
98
+ // },
75
99
  };
76
100
  },
77
101
  async configureServer(server) {
@@ -89,22 +113,37 @@ return input;
89
113
  // ) as {
90
114
  // version: number;
91
115
  // };
92
- const version = process.env['__GRACILE_VERSION__'];
93
- logger.info(`${c.cyan(c.italic(c.underline('🧚 Gracile ')))}` +
94
- ` ${c.green(` v${version ?? 'X'}`)}`);
116
+ const version = getVersion();
117
+ logger.info(`${c.cyan(c.italic(c.underline('🧚 Gracile')))}` +
118
+ ` ${c.dim(`~`)} ${c.green(`v${version ?? 'X'}`)}`);
95
119
  // ---
96
120
  const { handler } = await createDevHandler({
121
+ routes,
97
122
  vite: server,
98
123
  gracileConfig,
99
124
  });
125
+ logger.info(c.dim('Vite development server is starting…'), {
126
+ timestamp: true,
127
+ });
128
+ server.watcher.on('ready', () => {
129
+ setTimeout(() => {
130
+ logger.info('');
131
+ logger.info(c.green('Watching for file changes…'), {
132
+ timestamp: true,
133
+ });
134
+ logger.info('');
135
+ }, 100);
136
+ // s
137
+ });
100
138
  return () => {
101
139
  server.middlewares.use((req, res, next) => {
102
140
  const locals = config?.dev?.locals?.({ nodeRequest: req });
103
- Promise.resolve(nodeAdapter(handler)(req, res, locals)).catch((error) => next(error));
141
+ Promise.resolve(nodeAdapter(handler, { logger })(req, res, locals)).catch((error) => next(error));
104
142
  });
105
143
  };
106
144
  },
107
145
  },
146
+ virtualRoutesForClient,
108
147
  {
109
148
  name: 'vite-plugin-gracile-build',
110
149
  apply: 'build',
@@ -115,14 +154,15 @@ return input;
115
154
  server: { middlewareMode: true },
116
155
  // NOTE: Stub. KEEP IT!
117
156
  optimizeDeps: { include: [] },
157
+ plugins: [virtualRoutesForClient],
118
158
  });
119
159
  const htmlPages = await buildRoutes({
120
160
  viteServerForBuild: viteServerForClientHtmlBuild,
121
161
  root: viteConfig.root || process.cwd(),
122
162
  gracileConfig,
123
163
  serverMode: outputMode === 'server',
164
+ routes,
124
165
  });
125
- routes = htmlPages.routes;
126
166
  renderedRoutes = htmlPages.renderedRoutes;
127
167
  await viteServerForClientHtmlBuild.close();
128
168
  return {
@@ -180,7 +220,6 @@ return input;
180
220
  // NOTE: Useful for, e.g., link tag with `?url`
181
221
  assetFileNames: (chunkInfo) => {
182
222
  if (chunkInfo.name) {
183
- // (chunkInfo);
184
223
  const fileName = clientAssets[chunkInfo.name];
185
224
  if (fileName)
186
225
  return fileName;
@@ -195,10 +234,8 @@ return input;
195
234
  },
196
235
  },
197
236
  plugins: [
198
- virtualRoutes({
199
- routes,
200
- renderedRoutes,
201
- }),
237
+ virtualRoutesForClient,
238
+ virtualRoutes({ routes, renderedRoutes }),
202
239
  {
203
240
  name: 'vite-plugin-gracile-entry',
204
241
  resolveId(id) {
@@ -211,16 +248,18 @@ return input;
211
248
  if (id === 'entrypoint.js' && routes && renderedRoutes) {
212
249
  return `
213
250
  import { routeAssets, routeImports, routes } from 'gracile:routes';
214
- import { createGracileMiddleware } from '@gracile/gracile/_internals/server-runtime';
251
+ import { createGracileHandler } from '@gracile/gracile/_internals/server-runtime';
252
+ import { createLogger } from '@gracile/gracile/_internals/logger';
215
253
 
216
- // ({ routeAssets, routeImports, routes })
254
+ createLogger();
217
255
 
218
- export const handler = createGracileMiddleware({
256
+ export const handler = createGracileHandler({
219
257
  root: process.cwd(),
220
258
  routes,
221
259
  routeImports,
222
260
  routeAssets,
223
261
  serverMode: true,
262
+ gracileConfig: ${JSON.stringify(gracileConfig, null, 2)}
224
263
  });
225
264
  `;
226
265
  }
@@ -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;AAOvC,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,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,CAqNhE"}
@@ -1,8 +1,10 @@
1
+ import { Readable } from 'node:stream';
2
+ import * as assert from '@gracile/internal-utils/assertions';
1
3
  import { html } from '@gracile/internal-utils/dummy-literals';
2
4
  import { render as renderLitSsr } from '@lit-labs/ssr';
3
5
  import { collectResult } from '@lit-labs/ssr/lib/render-result.js';
4
- import { Readable } from 'stream';
5
- import { isLitServerTemplate, isLitTemplate } from '../assertions.js';
6
+ import { GracileError, GracileErrorData, TemplateError, } from '../errors/errors.js';
7
+ import { PAGE_ASSETS_MARKER, SSR_OUTLET_MARKER } from './markers.js';
6
8
  async function* concatStreams(...readables) {
7
9
  // eslint-disable-next-line no-restricted-syntax
8
10
  for (const readable of readables) {
@@ -12,71 +14,87 @@ async function* concatStreams(...readables) {
12
14
  }
13
15
  }
14
16
  }
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
17
  export const REGEX_TAG_SCRIPT = /\s?<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script\s*>\s?/gi;
20
18
  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, }) {
19
+ export async function renderRouteTemplate({ url, vite, mode, routeInfos, routeAssets, serverMode, docOnly, }) {
20
+ const location = {
21
+ file: routeInfos.foundRoute.filePath,
22
+ };
24
23
  if (!routeInfos.routeModule.document && !routeInfos.routeModule.template)
25
- return { output: null };
24
+ return { output: null, document: null };
26
25
  // MARK: Context
27
26
  const context = {
28
- url: new URL(request.url),
27
+ url: new URL(url),
29
28
  params: routeInfos.params,
30
- props: handlerInfos?.data
31
- ? {
32
- [handlerInfos.method]: handlerInfos.data,
33
- }
34
- : routeInfos.props,
29
+ props: routeInfos.props,
35
30
  };
36
31
  // MARK: Fragment
37
32
  if (!routeInfos.routeModule.document && routeInfos.routeModule.template) {
38
33
  const fragmentOutput = await Promise.resolve(routeInfos.routeModule.template?.(context));
39
- if (isLitTemplate(fragmentOutput) === false)
40
- throw Error(`Wrong template result for fragment template ${routeInfos.foundRoute.filePath}.`);
34
+ if (assert.isLitTemplate(fragmentOutput) === false)
35
+ throw new GracileError({
36
+ ...GracileErrorData.InvalidRouteDocument,
37
+ message: GracileErrorData.InvalidRouteDocument.message(location.file),
38
+ // location,
39
+ });
41
40
  const fragmentRender = renderLitSsr(fragmentOutput);
42
41
  const output = Readable.from(fragmentRender);
43
- return { output };
42
+ return { output, document: null };
44
43
  }
45
44
  // MARK: Document
46
45
  if (!routeInfos.routeModule.document ||
47
46
  typeof routeInfos.routeModule.document !== 'function')
48
- throw new TypeError(`Route document must be a function ${routeInfos.foundRoute.filePath}.`);
47
+ throw new GracileError({
48
+ ...GracileErrorData.InvalidRouteDocument,
49
+ message: GracileErrorData.InvalidRouteDocument.message(location.file),
50
+ location,
51
+ });
49
52
  const baseDocTemplateResult = await Promise.resolve(routeInfos.routeModule.document?.(context));
50
- if (isLitServerTemplate(baseDocTemplateResult) === false)
51
- throw new TypeError(`Incorrect document template result for ${routeInfos.foundRoute.filePath}.`);
52
- const baseDocRendered = await collectResult(renderLitSsr(baseDocTemplateResult));
53
+ if (assert.isLitServerTemplate(baseDocTemplateResult) === false)
54
+ throw new GracileError({
55
+ ...GracileErrorData.InvalidRouteDocumentResult,
56
+ message: GracileErrorData.InvalidRouteDocumentResult.message(location.file),
57
+ location,
58
+ });
59
+ let baseDocRendered;
60
+ // console.log({ ddd: baseDocTemplateResult });
61
+ try {
62
+ baseDocRendered = await collectResult(renderLitSsr(baseDocTemplateResult));
63
+ }
64
+ catch (e) {
65
+ throw new TemplateError({
66
+ ...GracileErrorData.CouldNotRenderRouteDocument,
67
+ message: GracileErrorData.CouldNotRenderRouteDocument.message(location.file),
68
+ location,
69
+ }, { cause: String(e) });
70
+ }
53
71
  // MARK: Sibling assets
54
72
  let baseDocRenderedWithAssets = baseDocRendered;
55
73
  // If the user doesnt use `pageAssetCustomLocation`, we put this as a fallback
56
74
  baseDocRenderedWithAssets = baseDocRenderedWithAssets
57
- .replace('</head>', `${PAGE_ASSETS_MARKER}</head>`)
75
+ .replace('</head>', `\n${PAGE_ASSETS_MARKER}</head>`)
58
76
  .replace(PAGE_ASSETS_MARKER,
59
77
  // 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
- `);
78
+ routeInfos.foundRoute.pageAssets.length
79
+ ? // eslint-disable-next-line prefer-template
80
+ html `<!-- PAGE ASSETS -->` +
81
+ `${routeInfos.foundRoute.pageAssets
82
+ .map((path) => {
83
+ //
84
+ if (/\.(js|ts)$/.test(path)) {
85
+ // prettier-ignore
86
+ return html ` <script type="module" src="/${path}"></script>`;
87
+ }
88
+ if (/\.(css|scss|sass|less|styl|stylus)$/.test(path)) {
89
+ // prettier-ignore
90
+ return html ` <link rel="stylesheet" href="/${path}" />`;
91
+ }
92
+ // NOTE: Never called (filtered upstream in `collectRoutes`)
93
+ return null;
94
+ })
95
+ .join('\n')}` +
96
+ `<!-- /PAGE ASSETS -->\n `
97
+ : '');
80
98
  // MARK: Dev. overlay
81
99
  // TODO: Need more testing and refinement (refreshes kills its usefulness)
82
100
  const overlay = () => html `
@@ -118,6 +136,8 @@ serverMode, }) {
118
136
  // `${routeInfos.pathname}?r=${Math.random()}`,
119
137
  routeInfos.pathname, baseDocRenderedWithAssets)
120
138
  : baseDocRenderedWithAssets;
139
+ if (docOnly)
140
+ return { document: baseDocHtml, output: null };
121
141
  const index = baseDocHtml.indexOf(SSR_OUTLET_MARKER);
122
142
  const baseDocRenderStreamPre = Readable.from(baseDocHtml.substring(0, index));
123
143
  const baseDocRenderStreamPost = Readable.from(baseDocHtml.substring(index + SSR_OUTLET_MARKER.length + 1));
@@ -134,15 +154,15 @@ serverMode, }) {
134
154
  // const output = Readable.from(
135
155
  // concatStreams(baseDocRenderStreamPre, baseDocRenderStreamPost),
136
156
  // );
137
- // return { output };
157
+ // return { output, document: null };
138
158
  // }
139
- if (isLitTemplate(routeOutput) === false)
159
+ if (assert.isLitTemplate(routeOutput) === false)
140
160
  throw Error(`Wrong template result for page template ${routeInfos.foundRoute.filePath}.`);
141
161
  const renderStream = Readable.from(renderLitSsr(routeOutput));
142
162
  const output = Readable.from(concatStreams(baseDocRenderStreamPre, renderStream, baseDocRenderStreamPost));
143
- return { output };
163
+ return { output, document: baseDocHtml };
144
164
  }
145
165
  // MARK: Just the document
146
166
  const output = Readable.from(baseDocHtml);
147
- return { output };
167
+ return { output, document: baseDocHtml };
148
168
  }
@@ -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"}