@emkodev/emroute 1.7.3 → 1.8.0-beta.2

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 (238) hide show
  1. package/README.md +1 -1
  2. package/core/component/abstract.component.ts +74 -0
  3. package/{src → core}/component/page.component.ts +3 -61
  4. package/core/component/widget.component.ts +54 -0
  5. package/core/pipeline/pipeline.ts +224 -0
  6. package/{src/renderer/ssr → core/renderer}/html.renderer.ts +26 -47
  7. package/{src/renderer/ssr → core/renderer}/md.renderer.ts +22 -41
  8. package/{src/renderer/ssr → core/renderer}/ssr.renderer.ts +44 -58
  9. package/{src/route → core/router}/route.resolver.ts +1 -10
  10. package/core/router/route.trie.ts +175 -0
  11. package/core/runtime/abstract.runtime.ts +47 -0
  12. package/core/server/emroute.server.ts +324 -0
  13. package/core/type/component.type.ts +39 -0
  14. package/core/type/element.type.ts +10 -0
  15. package/core/type/logger.type.ts +20 -0
  16. package/core/type/markdown.type.ts +8 -0
  17. package/core/type/route-tree.type.ts +28 -0
  18. package/core/type/route.type.ts +75 -0
  19. package/core/type/widget.type.ts +27 -0
  20. package/core/util/html.util.ts +50 -0
  21. package/{src → core}/util/md.util.ts +3 -5
  22. package/{src/route → core/util}/route-tree.util.ts +0 -2
  23. package/{src → core}/util/widget-resolve.util.ts +15 -46
  24. package/{src → core}/widget/widget.parser.ts +2 -23
  25. package/core/widget/widget.registry.ts +36 -0
  26. package/dist/core/component/abstract.component.d.ts +48 -0
  27. package/dist/core/component/abstract.component.js +42 -0
  28. package/dist/core/component/abstract.component.js.map +1 -0
  29. package/dist/core/component/page.component.d.ts +23 -0
  30. package/dist/core/component/page.component.js +49 -0
  31. package/dist/core/component/page.component.js.map +1 -0
  32. package/dist/core/component/widget.component.d.ts +17 -0
  33. package/dist/core/component/widget.component.js +37 -0
  34. package/dist/core/component/widget.component.js.map +1 -0
  35. package/dist/core/pipeline/pipeline.d.ts +61 -0
  36. package/dist/core/pipeline/pipeline.js +189 -0
  37. package/dist/core/pipeline/pipeline.js.map +1 -0
  38. package/dist/{src/renderer/ssr → core/renderer}/html.renderer.d.ts +8 -24
  39. package/dist/{src/renderer/ssr → core/renderer}/html.renderer.js +20 -35
  40. package/dist/core/renderer/html.renderer.js.map +1 -0
  41. package/dist/{src/renderer/ssr → core/renderer}/md.renderer.d.ts +6 -21
  42. package/dist/{src/renderer/ssr → core/renderer}/md.renderer.js +16 -32
  43. package/dist/core/renderer/md.renderer.js.map +1 -0
  44. package/dist/{src/renderer/ssr → core/renderer}/ssr.renderer.d.ts +11 -27
  45. package/dist/{src/renderer/ssr → core/renderer}/ssr.renderer.js +33 -37
  46. package/dist/core/renderer/ssr.renderer.js.map +1 -0
  47. package/dist/{src/route → core/router}/route.resolver.d.ts +1 -8
  48. package/dist/{src/route → core/router}/route.resolver.js +0 -1
  49. package/dist/core/router/route.resolver.js.map +1 -0
  50. package/dist/core/router/route.trie.d.ts +32 -0
  51. package/dist/core/router/route.trie.js +152 -0
  52. package/dist/core/router/route.trie.js.map +1 -0
  53. package/dist/core/runtime/abstract.runtime.d.ts +32 -0
  54. package/dist/core/runtime/abstract.runtime.js +26 -0
  55. package/dist/core/runtime/abstract.runtime.js.map +1 -0
  56. package/dist/core/server/emroute.server.d.ts +48 -0
  57. package/dist/core/server/emroute.server.js +239 -0
  58. package/dist/core/server/emroute.server.js.map +1 -0
  59. package/dist/core/server/server.type.d.ts +45 -0
  60. package/dist/core/server/server.type.js +11 -0
  61. package/dist/core/server/server.type.js.map +1 -0
  62. package/dist/core/type/component.type.d.ts +37 -0
  63. package/dist/core/type/component.type.js +7 -0
  64. package/dist/core/type/component.type.js.map +1 -0
  65. package/dist/core/type/element.type.d.ts +9 -0
  66. package/dist/core/type/element.type.js +5 -0
  67. package/dist/core/type/element.type.js.map +1 -0
  68. package/dist/core/type/logger.type.d.ts +14 -0
  69. package/dist/core/type/logger.type.js +8 -0
  70. package/dist/core/type/logger.type.js.map +1 -0
  71. package/dist/core/type/markdown.type.d.ts +7 -0
  72. package/dist/core/type/markdown.type.js +5 -0
  73. package/dist/core/type/markdown.type.js.map +1 -0
  74. package/dist/{src → core}/type/route-tree.type.d.ts +0 -12
  75. package/dist/{src → core}/type/route-tree.type.js +0 -1
  76. package/dist/core/type/route-tree.type.js.map +1 -0
  77. package/dist/core/type/route.type.d.ts +62 -0
  78. package/dist/core/type/route.type.js +7 -0
  79. package/dist/core/type/route.type.js.map +1 -0
  80. package/dist/core/type/widget.type.d.ts +27 -0
  81. package/dist/core/type/widget.type.js +5 -0
  82. package/dist/core/type/widget.type.js.map +1 -0
  83. package/dist/core/util/html.util.d.ts +14 -0
  84. package/dist/core/util/html.util.js +43 -0
  85. package/dist/core/util/html.util.js.map +1 -0
  86. package/dist/{src → core}/util/md.util.d.ts +0 -1
  87. package/dist/{src → core}/util/md.util.js +0 -2
  88. package/dist/core/util/md.util.js.map +1 -0
  89. package/dist/{src/route → core/util}/route-tree.util.js +0 -2
  90. package/dist/core/util/route-tree.util.js.map +1 -0
  91. package/dist/core/util/widget-resolve.util.d.ts +28 -0
  92. package/dist/{src → core}/util/widget-resolve.util.js +12 -42
  93. package/dist/core/util/widget-resolve.util.js.map +1 -0
  94. package/dist/{src → core}/widget/widget.parser.d.ts +0 -13
  95. package/dist/{src → core}/widget/widget.parser.js +1 -22
  96. package/dist/core/widget/widget.parser.js.map +1 -0
  97. package/dist/core/widget/widget.registry.d.ts +14 -0
  98. package/dist/core/widget/widget.registry.js +26 -0
  99. package/dist/core/widget/widget.registry.js.map +1 -0
  100. package/dist/emroute.js +1092 -1220
  101. package/dist/emroute.js.map +36 -5
  102. package/dist/runtime/abstract.runtime.d.ts +41 -7
  103. package/dist/runtime/abstract.runtime.js +404 -9
  104. package/dist/runtime/abstract.runtime.js.map +1 -1
  105. package/dist/runtime/bun/fs/bun-fs.runtime.d.ts +1 -0
  106. package/dist/runtime/bun/fs/bun-fs.runtime.js +15 -1
  107. package/dist/runtime/bun/fs/bun-fs.runtime.js.map +1 -1
  108. package/dist/runtime/bun/sqlite/bun-sqlite.runtime.d.ts +2 -0
  109. package/dist/runtime/bun/sqlite/bun-sqlite.runtime.js +8 -0
  110. package/dist/runtime/bun/sqlite/bun-sqlite.runtime.js.map +1 -1
  111. package/dist/runtime/fetch.runtime.d.ts +3 -3
  112. package/dist/runtime/fetch.runtime.js +3 -3
  113. package/dist/runtime/sitemap.generator.d.ts +1 -1
  114. package/dist/runtime/sitemap.generator.js +1 -1
  115. package/dist/runtime/sitemap.generator.js.map +1 -1
  116. package/dist/runtime/universal/fs/universal-fs.runtime.d.ts +1 -0
  117. package/dist/runtime/universal/fs/universal-fs.runtime.js +15 -1
  118. package/dist/runtime/universal/fs/universal-fs.runtime.js.map +1 -1
  119. package/dist/server/build.util.d.ts +9 -10
  120. package/dist/server/build.util.js +11 -31
  121. package/dist/server/build.util.js.map +1 -1
  122. package/dist/server/codegen.util.d.ts +1 -1
  123. package/dist/server/emroute.server.d.ts +8 -35
  124. package/dist/server/emroute.server.js +7 -351
  125. package/dist/server/emroute.server.js.map +1 -1
  126. package/dist/server/esbuild-manifest.plugin.js +1 -1
  127. package/dist/server/esbuild-manifest.plugin.js.map +1 -1
  128. package/dist/server/server-api.type.d.ts +3 -71
  129. package/dist/server/server-api.type.js +1 -8
  130. package/dist/server/server-api.type.js.map +1 -1
  131. package/dist/src/element/component.element.d.ts +6 -14
  132. package/dist/src/element/component.element.js +13 -40
  133. package/dist/src/element/component.element.js.map +1 -1
  134. package/dist/src/element/markdown.element.d.ts +2 -2
  135. package/dist/src/element/markdown.element.js +3 -2
  136. package/dist/src/element/markdown.element.js.map +1 -1
  137. package/dist/src/index.d.ts +15 -14
  138. package/dist/src/index.js +8 -8
  139. package/dist/src/index.js.map +1 -1
  140. package/dist/src/renderer/spa/emroute.app.d.ts +50 -0
  141. package/dist/src/renderer/spa/emroute.app.js +246 -0
  142. package/dist/src/renderer/spa/emroute.app.js.map +1 -0
  143. package/dist/src/renderer/spa/mod.d.ts +17 -16
  144. package/dist/src/renderer/spa/mod.js +9 -9
  145. package/dist/src/renderer/spa/mod.js.map +1 -1
  146. package/dist/src/renderer/spa/thin-client.d.ts +3 -3
  147. package/dist/src/renderer/spa/thin-client.js +7 -7
  148. package/dist/src/renderer/spa/thin-client.js.map +1 -1
  149. package/dist/src/route/route.core.d.ts +3 -3
  150. package/dist/src/util/html.util.d.ts +5 -22
  151. package/dist/src/util/html.util.js +8 -56
  152. package/dist/src/util/html.util.js.map +1 -1
  153. package/dist/src/widget/breadcrumb.widget.d.ts +2 -2
  154. package/dist/src/widget/breadcrumb.widget.js +2 -2
  155. package/dist/src/widget/breadcrumb.widget.js.map +1 -1
  156. package/dist/src/widget/page-title.widget.d.ts +1 -1
  157. package/dist/src/widget/page-title.widget.js +1 -1
  158. package/dist/src/widget/page-title.widget.js.map +1 -1
  159. package/package.json +8 -8
  160. package/runtime/abstract.runtime.ts +433 -17
  161. package/runtime/bun/fs/bun-fs.runtime.ts +15 -1
  162. package/runtime/bun/sqlite/bun-sqlite.runtime.ts +9 -0
  163. package/runtime/fetch.runtime.ts +3 -3
  164. package/runtime/sitemap.generator.ts +2 -2
  165. package/runtime/universal/fs/universal-fs.runtime.ts +15 -1
  166. package/server/build.util.ts +17 -43
  167. package/server/codegen.util.ts +1 -1
  168. package/server/emroute.server.ts +12 -426
  169. package/src/element/component.element.ts +14 -54
  170. package/src/element/markdown.element.ts +4 -3
  171. package/src/index.ts +22 -19
  172. package/src/renderer/spa/{thin-client.ts → emroute.app.ts} +19 -20
  173. package/src/renderer/spa/mod.ts +22 -22
  174. package/src/util/html.util.ts +16 -61
  175. package/src/widget/breadcrumb.widget.ts +3 -3
  176. package/src/widget/page-title.widget.ts +1 -1
  177. package/dist/src/component/abstract.component.d.ts +0 -199
  178. package/dist/src/component/abstract.component.js +0 -84
  179. package/dist/src/component/abstract.component.js.map +0 -1
  180. package/dist/src/component/page.component.d.ts +0 -74
  181. package/dist/src/component/page.component.js +0 -107
  182. package/dist/src/component/page.component.js.map +0 -1
  183. package/dist/src/component/widget.component.d.ts +0 -47
  184. package/dist/src/component/widget.component.js +0 -69
  185. package/dist/src/component/widget.component.js.map +0 -1
  186. package/dist/src/renderer/ssr/html.renderer.js.map +0 -1
  187. package/dist/src/renderer/ssr/md.renderer.js.map +0 -1
  188. package/dist/src/renderer/ssr/ssr.renderer.js.map +0 -1
  189. package/dist/src/route/route-tree.util.js.map +0 -1
  190. package/dist/src/route/route.matcher.d.ts +0 -86
  191. package/dist/src/route/route.matcher.js +0 -214
  192. package/dist/src/route/route.matcher.js.map +0 -1
  193. package/dist/src/route/route.resolver.js.map +0 -1
  194. package/dist/src/route/route.trie.d.ts +0 -38
  195. package/dist/src/route/route.trie.js +0 -206
  196. package/dist/src/route/route.trie.js.map +0 -1
  197. package/dist/src/type/element.type.d.ts +0 -19
  198. package/dist/src/type/element.type.js +0 -9
  199. package/dist/src/type/element.type.js.map +0 -1
  200. package/dist/src/type/logger.type.d.ts +0 -17
  201. package/dist/src/type/logger.type.js +0 -9
  202. package/dist/src/type/logger.type.js.map +0 -1
  203. package/dist/src/type/markdown.type.d.ts +0 -20
  204. package/dist/src/type/markdown.type.js +0 -2
  205. package/dist/src/type/markdown.type.js.map +0 -1
  206. package/dist/src/type/route-tree.type.js.map +0 -1
  207. package/dist/src/type/route.type.d.ts +0 -94
  208. package/dist/src/type/route.type.js +0 -8
  209. package/dist/src/type/route.type.js.map +0 -1
  210. package/dist/src/type/widget.type.d.ts +0 -55
  211. package/dist/src/type/widget.type.js +0 -10
  212. package/dist/src/type/widget.type.js.map +0 -1
  213. package/dist/src/util/logger.util.d.ts +0 -26
  214. package/dist/src/util/logger.util.js +0 -80
  215. package/dist/src/util/logger.util.js.map +0 -1
  216. package/dist/src/util/md.util.js.map +0 -1
  217. package/dist/src/util/widget-resolve.util.d.ts +0 -52
  218. package/dist/src/util/widget-resolve.util.js.map +0 -1
  219. package/dist/src/widget/widget.parser.js.map +0 -1
  220. package/dist/src/widget/widget.registry.d.ts +0 -23
  221. package/dist/src/widget/widget.registry.js +0 -42
  222. package/dist/src/widget/widget.registry.js.map +0 -1
  223. package/runtime/bun/esbuild-runtime-loader.plugin.ts +0 -112
  224. package/server/esbuild-manifest.plugin.ts +0 -209
  225. package/server/server-api.type.ts +0 -101
  226. package/src/component/abstract.component.ts +0 -231
  227. package/src/component/widget.component.ts +0 -85
  228. package/src/route/route.core.ts +0 -371
  229. package/src/route/route.trie.ts +0 -265
  230. package/src/type/element.type.ts +0 -22
  231. package/src/type/logger.type.ts +0 -24
  232. package/src/type/markdown.type.ts +0 -21
  233. package/src/type/route-tree.type.ts +0 -51
  234. package/src/type/route.type.ts +0 -124
  235. package/src/type/widget.type.ts +0 -65
  236. package/src/util/logger.util.ts +0 -83
  237. package/src/widget/widget.registry.ts +0 -51
  238. /package/dist/{src/route → core/util}/route-tree.util.d.ts +0 -0
@@ -0,0 +1,239 @@
1
+ /**
2
+ * Emroute
3
+ *
4
+ * Framework entry point. Reads manifests from Runtime,
5
+ * builds Pipeline + Renderers, handles Request → Response.
6
+ */
7
+ import { Pipeline } from "../pipeline/pipeline.js";
8
+ import { SsrHtmlRenderer } from "../renderer/html.renderer.js";
9
+ import { SsrMdRenderer } from "../renderer/md.renderer.js";
10
+ import { WidgetRegistry } from "../widget/widget.registry.js";
11
+ import { escapeHtml } from "../util/html.util.js";
12
+ import { rewriteMdLinks } from "../util/md.util.js";
13
+ import { ROUTES_MANIFEST_PATH, WIDGETS_MANIFEST_PATH, } from "../runtime/abstract.runtime.js";
14
+ export const DEFAULT_BASE_PATH = { html: '/html', md: '/md', app: '/app' };
15
+ export class Emroute {
16
+ runtime;
17
+ htmlBase;
18
+ mdBase;
19
+ appBase;
20
+ spa;
21
+ title;
22
+ htmlRenderer;
23
+ mdRenderer;
24
+ shell;
25
+ constructor(htmlRenderer, mdRenderer, shell, runtime, htmlBase, mdBase, appBase, spa, title) {
26
+ this.runtime = runtime;
27
+ this.htmlBase = htmlBase;
28
+ this.mdBase = mdBase;
29
+ this.appBase = appBase;
30
+ this.spa = spa;
31
+ this.title = title;
32
+ this.htmlRenderer = htmlRenderer;
33
+ this.mdRenderer = mdRenderer;
34
+ this.shell = shell;
35
+ }
36
+ static async create(config, runtime) {
37
+ const { spa = 'root' } = config;
38
+ const { html: htmlBase, md: mdBase, app: appBase } = config.basePath ?? DEFAULT_BASE_PATH;
39
+ // ── Verify route manifest exists ──────────────────────────────────
40
+ const manifestResponse = await runtime.query(ROUTES_MANIFEST_PATH);
41
+ if (manifestResponse.status === 404 && !config.routeTree) {
42
+ throw new Error(`[emroute] ${ROUTES_MANIFEST_PATH} not found in runtime. ` +
43
+ 'Provide routeTree in config or ensure the runtime produces it.');
44
+ }
45
+ if (config.routeTree && manifestResponse.status === 404) {
46
+ await runtime.command(ROUTES_MANIFEST_PATH, {
47
+ body: JSON.stringify(config.routeTree),
48
+ });
49
+ }
50
+ // ── Pipeline ──────────────────────────────────────────────────────
51
+ const pipeline = new Pipeline({
52
+ runtime,
53
+ ...(config.extendContext ? { contextProvider: config.extendContext } : {}),
54
+ ...(config.moduleLoaders ? { moduleLoaders: config.moduleLoaders } : {}),
55
+ });
56
+ // ── Widgets ───────────────────────────────────────────────────────
57
+ let widgets = config.widgets;
58
+ const widgetsResponse = await runtime.query(WIDGETS_MANIFEST_PATH);
59
+ if (widgetsResponse.status !== 404) {
60
+ const entries = await widgetsResponse.json();
61
+ if (!config.widgets) {
62
+ widgets = await Emroute.importWidgets(entries, runtime);
63
+ }
64
+ }
65
+ // ── Renderers ─────────────────────────────────────────────────────
66
+ let ssrHtmlRenderer = null;
67
+ let ssrMdRenderer = null;
68
+ if (spa !== 'only') {
69
+ ssrHtmlRenderer = new SsrHtmlRenderer(pipeline, {
70
+ ...(config.markdownRenderer ? { markdownRenderer: config.markdownRenderer } : {}),
71
+ ...(widgets ? { widgets } : {}),
72
+ });
73
+ ssrMdRenderer = new SsrMdRenderer(pipeline, {
74
+ ...(widgets ? { widgets } : {}),
75
+ });
76
+ }
77
+ // ── HTML shell ────────────────────────────────────────────────────
78
+ const title = config.title ?? 'emroute';
79
+ const shellBase = (spa === 'root' || spa === 'only') ? appBase : htmlBase;
80
+ let shell = await Emroute.resolveShell(runtime, title, shellBase);
81
+ if ((await runtime.query('/main.css')).status !== 404) {
82
+ shell = shell.replace('</head>', ' <link rel="stylesheet" href="/main.css">\n</head>');
83
+ }
84
+ return new Emroute(ssrHtmlRenderer, ssrMdRenderer, shell, runtime, htmlBase, mdBase, appBase, spa, title);
85
+ }
86
+ // ── handleRequest ─────────────────────────────────────────────────
87
+ async handleRequest(req) {
88
+ const url = new URL(req.url);
89
+ const pathname = url.pathname;
90
+ const mdPrefix = this.mdBase + '/';
91
+ const htmlPrefix = this.htmlBase + '/';
92
+ const appPrefix = this.appBase + '/';
93
+ // SSR Markdown: /md/*
94
+ if (this.mdRenderer &&
95
+ (pathname.startsWith(mdPrefix) || pathname === this.mdBase)) {
96
+ const routePath = pathname === this.mdBase ? '/' : pathname.slice(this.mdBase.length);
97
+ if (routePath.length > 1 && routePath.endsWith('/')) {
98
+ const canonical = this.mdBase + routePath.slice(0, -1) + (url.search || '');
99
+ return Response.redirect(new URL(canonical, url.origin), 301);
100
+ }
101
+ try {
102
+ const routeUrl = new URL(routePath + url.search, url.origin);
103
+ const { content, status, redirect } = await this.mdRenderer.render(routeUrl, req.signal);
104
+ if (redirect) {
105
+ const target = redirect.startsWith('/') ? this.mdBase + redirect : redirect;
106
+ return Response.redirect(new URL(target, url.origin), status);
107
+ }
108
+ return new Response(rewriteMdLinks(content, this.mdBase, [this.mdBase, this.htmlBase]), {
109
+ status,
110
+ headers: { 'Content-Type': 'text/markdown; charset=utf-8; variant=CommonMark' },
111
+ });
112
+ }
113
+ catch (e) {
114
+ console.error(`[emroute] Error rendering ${pathname}:`, e);
115
+ return new Response('Internal Server Error', { status: 500 });
116
+ }
117
+ }
118
+ // SSR HTML: /html/*
119
+ if (this.htmlRenderer &&
120
+ (pathname.startsWith(htmlPrefix) || pathname === this.htmlBase)) {
121
+ const routePath = pathname === this.htmlBase ? '/' : pathname.slice(this.htmlBase.length);
122
+ if (routePath.length > 1 && routePath.endsWith('/')) {
123
+ const canonical = this.htmlBase + routePath.slice(0, -1) + (url.search || '');
124
+ return Response.redirect(new URL(canonical, url.origin), 301);
125
+ }
126
+ try {
127
+ const routeUrl = new URL(routePath + url.search, url.origin);
128
+ const result = await this.htmlRenderer.render(routeUrl, req.signal);
129
+ if (result.redirect) {
130
+ const target = result.redirect.startsWith('/') ? this.htmlBase + result.redirect : result.redirect;
131
+ return Response.redirect(new URL(target, url.origin), result.status);
132
+ }
133
+ const ssrTitle = result.title ?? this.title;
134
+ const html = Emroute.injectSsrContent(this.shell, result.content, ssrTitle, pathname);
135
+ return new Response(html, {
136
+ status: result.status,
137
+ headers: { 'Content-Type': 'text/html; charset=utf-8' },
138
+ });
139
+ }
140
+ catch (e) {
141
+ console.error(`[emroute] Error rendering ${pathname}:`, e);
142
+ return new Response('Internal Server Error', { status: 500 });
143
+ }
144
+ }
145
+ // /app/*
146
+ if (pathname.startsWith(appPrefix) || pathname === this.appBase) {
147
+ return new Response(this.shell, {
148
+ status: 200,
149
+ headers: { 'Content-Type': 'text/html; charset=utf-8' },
150
+ });
151
+ }
152
+ // Unhandled SSR paths in 'only' mode — serve shell
153
+ if (pathname.startsWith(htmlPrefix) || pathname === this.htmlBase ||
154
+ pathname.startsWith(mdPrefix) || pathname === this.mdBase) {
155
+ return new Response(this.shell, {
156
+ status: 200,
157
+ headers: { 'Content-Type': 'text/html; charset=utf-8' },
158
+ });
159
+ }
160
+ // Static files
161
+ const lastSegment = pathname.split('/').pop() ?? '';
162
+ if (lastSegment.includes('.')) {
163
+ const fileResponse = await this.runtime.handle(pathname);
164
+ if (fileResponse.status === 200)
165
+ return fileResponse;
166
+ return null;
167
+ }
168
+ // Bare paths → redirect
169
+ const base = (this.spa === 'root' || this.spa === 'only') ? this.appBase : this.htmlBase;
170
+ const bare = pathname === '/' ? '' : pathname.slice(1).replace(/\/$/, '');
171
+ return Response.redirect(new URL(`${base}/${bare}`, url.origin), 302);
172
+ }
173
+ // ── Private static helpers ────────────────────────────────────────
174
+ static extractWidgetExport(mod) {
175
+ for (const value of Object.values(mod)) {
176
+ if (!value)
177
+ continue;
178
+ if (typeof value === 'object' && 'getData' in value) {
179
+ return value;
180
+ }
181
+ if (typeof value === 'function' && value.prototype?.getData) {
182
+ return new value();
183
+ }
184
+ }
185
+ return null;
186
+ }
187
+ static async importWidgets(entries, runtime) {
188
+ const registry = new WidgetRegistry();
189
+ for (const entry of entries) {
190
+ try {
191
+ const runtimePath = entry.modulePath.startsWith('/')
192
+ ? entry.modulePath
193
+ : `/${entry.modulePath}`;
194
+ const mod = await runtime.loadModule(runtimePath);
195
+ const instance = Emroute.extractWidgetExport(mod);
196
+ if (!instance)
197
+ continue;
198
+ registry.add(instance, runtimePath);
199
+ }
200
+ catch (e) {
201
+ console.error(`[emroute] Failed to load widget ${entry.modulePath}:`, e);
202
+ }
203
+ }
204
+ return registry;
205
+ }
206
+ static buildHtmlShell(title, htmlBase) {
207
+ const baseTag = htmlBase ? `\n <base href="${escapeHtml(htmlBase)}/">` : '';
208
+ return `<!DOCTYPE html>
209
+ <html>
210
+ <head>${baseTag}
211
+ <meta charset="utf-8">
212
+ <meta name="viewport" content="width=device-width, initial-scale=1">
213
+ <title>${escapeHtml(title)}</title>
214
+ <style>@view-transition { navigation: auto; } router-slot { display: contents; }</style>
215
+ </head>
216
+ <body>
217
+ <router-slot></router-slot>
218
+ </body>
219
+ </html>`;
220
+ }
221
+ static injectSsrContent(html, content, title, ssrRoute) {
222
+ const slotPattern = /<router-slot\b[^>]*>.*?<\/router-slot>/s;
223
+ if (!slotPattern.test(html))
224
+ return html;
225
+ const ssrAttr = ssrRoute ? ` data-ssr-route="${ssrRoute}"` : '';
226
+ html = html.replace(slotPattern, `<router-slot${ssrAttr}>${content}</router-slot>`);
227
+ if (title) {
228
+ html = html.replace(/<title>[^<]*<\/title>/, `<title>${escapeHtml(title)}</title>`);
229
+ }
230
+ return html;
231
+ }
232
+ static async resolveShell(runtime, title, htmlBase) {
233
+ const response = await runtime.query('/index.html');
234
+ if (response.status !== 404)
235
+ return await response.text();
236
+ return Emroute.buildHtmlShell(title, htmlBase);
237
+ }
238
+ }
239
+ //# sourceMappingURL=emroute.server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emroute.server.js","sourceRoot":"","sources":["../../../core/server/emroute.server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Server Types
3
+ *
4
+ * Types and conventions for the emroute server layer.
5
+ */
6
+ import type { RouteNode } from '../type/route-tree.type.ts';
7
+ import type { MarkdownRenderer } from '../type/markdown.type.ts';
8
+ import type { SpaMode, WidgetManifestEntry } from '../type/widget.type.ts';
9
+ import type { ElementManifestEntry } from '../type/element.type.ts';
10
+ import type { ContextProvider } from '../type/component.type.ts';
11
+ import type { WidgetRegistry } from '../widget/widget.registry.ts';
12
+ import type { SsrHtmlRenderer } from '../renderer/html.renderer.ts';
13
+ import type { SsrMdRenderer } from '../renderer/md.renderer.ts';
14
+ /** Base paths for the three rendering endpoints. */
15
+ export interface BasePath {
16
+ html: string;
17
+ md: string;
18
+ app: string;
19
+ }
20
+ export declare const DEFAULT_BASE_PATH: BasePath;
21
+ /** Well-known manifest paths (convention between Runtime and Server). */
22
+ export declare const ROUTES_MANIFEST_PATH = "/routes.manifest.json";
23
+ export declare const WIDGETS_MANIFEST_PATH = "/widgets.manifest.json";
24
+ export declare const ELEMENTS_MANIFEST_PATH = "/elements.manifest.json";
25
+ /** Config for `createEmrouteServer()`. */
26
+ export interface EmrouteServerConfig {
27
+ routeTree?: RouteNode;
28
+ widgets?: WidgetRegistry;
29
+ spa?: SpaMode;
30
+ basePath?: BasePath;
31
+ title?: string;
32
+ markdownRenderer?: MarkdownRenderer;
33
+ extendContext?: ContextProvider;
34
+ moduleLoaders?: Record<string, () => Promise<unknown>>;
35
+ }
36
+ /** An emroute server instance. */
37
+ export interface EmrouteServer {
38
+ handleRequest(req: Request): Promise<Response | null>;
39
+ readonly htmlRenderer: SsrHtmlRenderer | null;
40
+ readonly mdRenderer: SsrMdRenderer | null;
41
+ readonly routeTree: RouteNode;
42
+ readonly widgetEntries: WidgetManifestEntry[];
43
+ readonly elementEntries: ElementManifestEntry[];
44
+ readonly shell: string;
45
+ }
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Server Types
3
+ *
4
+ * Types and conventions for the emroute server layer.
5
+ */
6
+ export const DEFAULT_BASE_PATH = { html: '/html', md: '/md', app: '/app' };
7
+ /** Well-known manifest paths (convention between Runtime and Server). */
8
+ export const ROUTES_MANIFEST_PATH = '/routes.manifest.json';
9
+ export const WIDGETS_MANIFEST_PATH = '/widgets.manifest.json';
10
+ export const ELEMENTS_MANIFEST_PATH = '/elements.manifest.json';
11
+ //# sourceMappingURL=server.type.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.type.js","sourceRoot":"","sources":["../../../core/server/server.type.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAkBH,MAAM,CAAC,MAAM,iBAAiB,GAAa,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC;AAErF,yEAAyE;AACzE,MAAM,CAAC,MAAM,oBAAoB,GAAG,uBAAuB,CAAC;AAC5D,MAAM,CAAC,MAAM,qBAAqB,GAAG,wBAAwB,CAAC;AAC9D,MAAM,CAAC,MAAM,sBAAsB,GAAG,yBAAyB,CAAC"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Component Types
3
+ *
4
+ * Types for the component system. Separate from route types.
5
+ */
6
+ import type { RouteInfo } from './route.type.ts';
7
+ /** Shape of companion file contents (html, md, css). */
8
+ export type FileContents = {
9
+ html?: string;
10
+ md?: string;
11
+ css?: string;
12
+ };
13
+ /** Context passed to components during rendering. */
14
+ export interface ComponentContext extends RouteInfo {
15
+ /** @deprecated Use context.url.pathname */
16
+ readonly pathname: string;
17
+ /** @deprecated Use context.url.searchParams */
18
+ readonly searchParams: URLSearchParams;
19
+ readonly files?: Readonly<FileContents>;
20
+ readonly signal?: AbortSignal;
21
+ readonly isLeaf?: boolean;
22
+ }
23
+ /**
24
+ * Enriches the base ComponentContext with app-level services.
25
+ * Registered once at server creation; called for every context construction.
26
+ */
27
+ export type ContextProvider = (base: ComponentContext) => ComponentContext;
28
+ /** Render context determines how components are rendered. */
29
+ export type RenderContext = 'markdown' | 'html' | 'spa';
30
+ /** Component manifest entry for code generation. */
31
+ export interface ComponentManifestEntry {
32
+ name: string;
33
+ modulePath: string;
34
+ tagName: string;
35
+ type: 'page' | 'widget';
36
+ pattern?: string;
37
+ }
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Component Types
3
+ *
4
+ * Types for the component system. Separate from route types.
5
+ */
6
+ export {};
7
+ //# sourceMappingURL=component.type.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"component.type.js","sourceRoot":"","sources":["../../../core/type/component.type.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Element Types
3
+ */
4
+ /** Custom element manifest entry for discovery and registration. */
5
+ export interface ElementManifestEntry {
6
+ name: string;
7
+ modulePath: string;
8
+ tagName: string;
9
+ }
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Element Types
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=element.type.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"element.type.js","sourceRoot":"","sources":["../../../core/type/element.type.ts"],"names":[],"mappings":"AAAA;;GAEG"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Logger Interface
3
+ *
4
+ * Minimal pluggable logger. Default: no-op (silent degradation).
5
+ * Pass via PipelineOptions to wire in.
6
+ */
7
+ export interface Logger {
8
+ error(msg: string, error?: Error): void;
9
+ warn(msg: string): void;
10
+ }
11
+ /** Default no-op logger. */
12
+ export declare const defaultLogger: Logger;
13
+ /** @deprecated Pass `logger` in Emroute.create() config instead. This function is a no-op. */
14
+ export declare function setLogger(_logger: Logger): void;
@@ -0,0 +1,8 @@
1
+ const noop = () => { };
2
+ /** Default no-op logger. */
3
+ export const defaultLogger = { error: noop, warn: noop };
4
+ /** @deprecated Pass `logger` in Emroute.create() config instead. This function is a no-op. */
5
+ export function setLogger(_logger) {
6
+ console.warn('[emroute] setLogger() is deprecated. Pass `logger` in Emroute.create() config instead.');
7
+ }
8
+ //# sourceMappingURL=logger.type.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.type.js","sourceRoot":"","sources":["../../../core/type/logger.type.ts"],"names":[],"mappings":"AAWA,MAAM,IAAI,GAAG,GAAG,EAAE,GAAE,CAAC,CAAC;AAEtB,4BAA4B;AAC5B,MAAM,CAAC,MAAM,aAAa,GAAW,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;AAEjE,8FAA8F;AAC9F,MAAM,UAAU,SAAS,CAAC,OAAe;IACvC,OAAO,CAAC,IAAI,CAAC,wFAAwF,CAAC,CAAC;AACzG,CAAC"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Markdown Renderer Interface
3
+ */
4
+ export interface MarkdownRenderer {
5
+ render(markdown: string): string;
6
+ init?(): Promise<void>;
7
+ }
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Markdown Renderer Interface
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=markdown.type.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdown.type.js","sourceRoot":"","sources":["../../../core/type/markdown.type.ts"],"names":[],"mappings":"AAAA;;GAEG"}
@@ -2,7 +2,6 @@
2
2
  * Route Tree
3
3
  *
4
4
  * Serializable tree structure that mirrors the filesystem layout.
5
- * Replaces the flat array manifest as the canonical route format.
6
5
  *
7
6
  * Each node corresponds to a URL segment. The tree is JSON-serializable
8
7
  * (no Maps, no classes) so it can be written to disk, sent over the wire,
@@ -10,33 +9,22 @@
10
9
  */
11
10
  /** Files associated with a route (companion files discovered alongside the page). */
12
11
  export interface RouteFiles {
13
- /** TypeScript module (e.g. "routes/about.page.ts") */
14
12
  ts?: string;
15
- /** JavaScript module — merged module with inlined companions (e.g. "routes/about.page.js") */
16
13
  js?: string;
17
- /** HTML template (e.g. "routes/about.page.html") */
18
14
  html?: string;
19
- /** Markdown content (e.g. "routes/about.page.md") */
20
15
  md?: string;
21
- /** Scoped stylesheet (e.g. "routes/about.page.css") */
22
16
  css?: string;
23
17
  }
24
18
  /** A single node in the route tree. */
25
19
  export interface RouteNode {
26
- /** Route files when this node is a terminal route. */
27
20
  files?: RouteFiles;
28
- /** Error boundary module path scoped to this prefix (from .error.ts). */
29
21
  errorBoundary?: string;
30
- /** Redirect module path (from .redirect.ts). Mutually exclusive with files. */
31
22
  redirect?: string;
32
- /** Static children keyed by URL segment (e.g. "about", "projects"). */
33
23
  children?: Record<string, RouteNode>;
34
- /** Single-segment dynamic param (from [param] directories/files). */
35
24
  dynamic?: {
36
25
  param: string;
37
26
  child: RouteNode;
38
27
  };
39
- /** Catch-all wildcard (from directory index.page.* files). */
40
28
  wildcard?: {
41
29
  param: string;
42
30
  child: RouteNode;
@@ -2,7 +2,6 @@
2
2
  * Route Tree
3
3
  *
4
4
  * Serializable tree structure that mirrors the filesystem layout.
5
- * Replaces the flat array manifest as the canonical route format.
6
5
  *
7
6
  * Each node corresponds to a URL segment. The tree is JSON-serializable
8
7
  * (no Maps, no classes) so it can be written to disk, sent over the wire,
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route-tree.type.js","sourceRoot":"","sources":["../../../core/type/route-tree.type.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG"}
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Route Types
3
+ *
4
+ * Pure routing types. No rendering, no navigation, no browser concerns.
5
+ */
6
+ export type { RouteNode, RouteFiles } from './route-tree.type.ts';
7
+ /** Parameters extracted from URL patterns. */
8
+ export type RouteParams = Readonly<Record<string, string>>;
9
+ /** Immutable route context built once per navigation, shared across the render pipeline. */
10
+ export interface RouteInfo {
11
+ readonly url: URL;
12
+ readonly params: RouteParams;
13
+ }
14
+ /** Supported file patterns in file-based routing. */
15
+ export type RouteFileType = 'page' | 'error' | 'redirect';
16
+ /** Redirect configuration. */
17
+ export interface RedirectConfig {
18
+ to: string;
19
+ status: 301 | 302;
20
+ }
21
+ /** Route configuration for a single matched route. */
22
+ export interface RouteConfig {
23
+ pattern: string;
24
+ type: RouteFileType;
25
+ modulePath: string;
26
+ files?: import('./route-tree.type.ts').RouteFiles;
27
+ parent?: string;
28
+ statusCode?: number;
29
+ }
30
+ /** Result of matching a URL against routes. */
31
+ export interface MatchedRoute {
32
+ readonly route: RouteConfig;
33
+ readonly params: RouteParams;
34
+ }
35
+ /** Error boundary configuration. */
36
+ export interface ErrorBoundary {
37
+ pattern: string;
38
+ modulePath: string;
39
+ }
40
+ /** Router state for history management. */
41
+ export interface RouterState {
42
+ pathname: string;
43
+ params: RouteParams;
44
+ scrollY?: number;
45
+ }
46
+ /** Navigation options. */
47
+ export interface NavigateOptions {
48
+ replace?: boolean;
49
+ state?: RouterState;
50
+ hash?: string;
51
+ }
52
+ /** Router event types. */
53
+ export type RouterEventType = 'navigate' | 'error' | 'load';
54
+ /** Router event payload. */
55
+ export interface RouterEvent {
56
+ type: RouterEventType;
57
+ pathname: string;
58
+ params: RouteParams;
59
+ error?: Error;
60
+ }
61
+ /** Router event listener. */
62
+ export type RouterEventListener = (event: RouterEvent) => void;
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Route Types
3
+ *
4
+ * Pure routing types. No rendering, no navigation, no browser concerns.
5
+ */
6
+ export {};
7
+ //# sourceMappingURL=route.type.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route.type.js","sourceRoot":"","sources":["../../../core/type/route.type.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Widget Types
3
+ */
4
+ /** SPA rendering mode. */
5
+ export type SpaMode = 'none' | 'leaf' | 'root' | 'only';
6
+ /** Widget manifest entry for discovery and registration. */
7
+ export interface WidgetManifestEntry {
8
+ name: string;
9
+ modulePath: string;
10
+ tagName: string;
11
+ files?: {
12
+ html?: string;
13
+ md?: string;
14
+ css?: string;
15
+ };
16
+ }
17
+ /** Full widgets manifest (array, sorted by name). */
18
+ export type WidgetsManifest = WidgetManifestEntry[];
19
+ /** Parsed widget block from markdown fenced code. */
20
+ export interface ParsedWidgetBlock {
21
+ fullMatch: string;
22
+ widgetName: string;
23
+ params: Record<string, unknown> | null;
24
+ parseError?: string;
25
+ startIndex: number;
26
+ endIndex: number;
27
+ }
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Widget Types
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=widget.type.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"widget.type.js","sourceRoot":"","sources":["../../../core/type/widget.type.ts"],"names":[],"mappings":"AAAA;;GAEG"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Pure HTML utilities. No DOM, no browser APIs.
3
+ */
4
+ /** HTML attribute name marking a widget as server-rendered. */
5
+ export declare const SSR_ATTR = "ssr";
6
+ /** HTML attribute name for lazy-loading widgets. */
7
+ export declare const LAZY_ATTR = "lazy";
8
+ /** Throw if a redirect URL uses a dangerous protocol. */
9
+ export declare function assertSafeRedirect(url: string): void;
10
+ export declare function escapeHtml(text: string): string;
11
+ export declare function unescapeHtml(text: string): string;
12
+ export declare function scopeWidgetCss(css: string, widgetName: string): string;
13
+ /** Status code to message mapping. */
14
+ export declare const STATUS_MESSAGES: Record<number, string>;