@emkodev/emroute 1.6.2 → 1.6.3

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 (128) hide show
  1. package/README.md +6 -6
  2. package/dist/runtime/abstract.runtime.d.ts +94 -0
  3. package/dist/runtime/abstract.runtime.js +339 -0
  4. package/dist/runtime/abstract.runtime.js.map +1 -0
  5. package/dist/runtime/bun/esbuild-runtime-loader.plugin.d.ts +25 -0
  6. package/dist/runtime/bun/esbuild-runtime-loader.plugin.js +72 -0
  7. package/dist/runtime/bun/esbuild-runtime-loader.plugin.js.map +1 -0
  8. package/dist/runtime/bun/fs/bun-fs.runtime.d.ts +21 -0
  9. package/dist/runtime/bun/fs/bun-fs.runtime.js +205 -0
  10. package/dist/runtime/bun/fs/bun-fs.runtime.js.map +1 -0
  11. package/dist/runtime/bun/sqlite/bun-sqlite.runtime.d.ts +27 -0
  12. package/dist/runtime/bun/sqlite/bun-sqlite.runtime.js +234 -0
  13. package/dist/runtime/bun/sqlite/bun-sqlite.runtime.js.map +1 -0
  14. package/dist/runtime/sitemap.generator.d.ts +58 -0
  15. package/dist/runtime/sitemap.generator.js +107 -0
  16. package/dist/runtime/sitemap.generator.js.map +1 -0
  17. package/dist/runtime/universal/fs/universal-fs.runtime.d.ts +29 -0
  18. package/dist/runtime/universal/fs/universal-fs.runtime.js +213 -0
  19. package/dist/runtime/universal/fs/universal-fs.runtime.js.map +1 -0
  20. package/dist/server/codegen.util.d.ts +16 -0
  21. package/dist/server/codegen.util.js +46 -0
  22. package/dist/server/codegen.util.js.map +1 -0
  23. package/dist/server/emroute.server.d.ts +37 -0
  24. package/dist/server/emroute.server.js +314 -0
  25. package/dist/server/emroute.server.js.map +1 -0
  26. package/dist/server/esbuild-manifest.plugin.d.ts +26 -0
  27. package/dist/server/esbuild-manifest.plugin.js +187 -0
  28. package/dist/server/esbuild-manifest.plugin.js.map +1 -0
  29. package/dist/server/scanner.util.d.ts +22 -0
  30. package/dist/server/scanner.util.js +194 -0
  31. package/dist/server/scanner.util.js.map +1 -0
  32. package/dist/server/server-api.type.d.ts +71 -0
  33. package/dist/server/server-api.type.js +9 -0
  34. package/dist/server/server-api.type.js.map +1 -0
  35. package/dist/src/component/abstract.component.d.ts +197 -0
  36. package/dist/src/component/abstract.component.js +84 -0
  37. package/dist/src/component/abstract.component.js.map +1 -0
  38. package/dist/src/component/page.component.d.ts +74 -0
  39. package/dist/src/component/page.component.js +107 -0
  40. package/dist/src/component/page.component.js.map +1 -0
  41. package/dist/src/component/widget.component.d.ts +47 -0
  42. package/dist/src/component/widget.component.js +69 -0
  43. package/dist/src/component/widget.component.js.map +1 -0
  44. package/dist/src/element/component.element.d.ts +79 -0
  45. package/dist/src/element/component.element.js +293 -0
  46. package/dist/src/element/component.element.js.map +1 -0
  47. package/dist/src/element/markdown.element.d.ts +36 -0
  48. package/dist/src/element/markdown.element.js +93 -0
  49. package/dist/src/element/markdown.element.js.map +1 -0
  50. package/dist/src/element/slot.element.d.ts +30 -0
  51. package/dist/src/element/slot.element.js +31 -0
  52. package/dist/src/element/slot.element.js.map +1 -0
  53. package/dist/src/index.d.ts +23 -0
  54. package/dist/src/index.js +24 -0
  55. package/dist/src/index.js.map +1 -0
  56. package/dist/src/overlay/mod.d.ts +9 -0
  57. package/dist/src/overlay/mod.js +9 -0
  58. package/dist/src/overlay/mod.js.map +1 -0
  59. package/dist/src/overlay/overlay.css.d.ts +8 -0
  60. package/dist/src/overlay/overlay.css.js +170 -0
  61. package/dist/src/overlay/overlay.css.js.map +1 -0
  62. package/dist/src/overlay/overlay.service.d.ts +14 -0
  63. package/dist/src/overlay/overlay.service.js +307 -0
  64. package/dist/src/overlay/overlay.service.js.map +1 -0
  65. package/dist/src/overlay/overlay.type.d.ts +33 -0
  66. package/dist/src/overlay/overlay.type.js +11 -0
  67. package/dist/src/overlay/overlay.type.js.map +1 -0
  68. package/dist/src/renderer/spa/base.renderer.d.ts +39 -0
  69. package/dist/src/renderer/spa/base.renderer.js +149 -0
  70. package/dist/src/renderer/spa/base.renderer.js.map +1 -0
  71. package/dist/src/renderer/spa/hash.renderer.d.ts +78 -0
  72. package/dist/src/renderer/spa/hash.renderer.js +162 -0
  73. package/dist/src/renderer/spa/hash.renderer.js.map +1 -0
  74. package/dist/src/renderer/spa/html.renderer.d.ts +81 -0
  75. package/dist/src/renderer/spa/html.renderer.js +304 -0
  76. package/dist/src/renderer/spa/html.renderer.js.map +1 -0
  77. package/dist/src/renderer/spa/mod.d.ts +30 -0
  78. package/dist/src/renderer/spa/mod.js +35 -0
  79. package/dist/src/renderer/spa/mod.js.map +1 -0
  80. package/dist/src/renderer/ssr/html.renderer.d.ts +49 -0
  81. package/dist/src/renderer/ssr/html.renderer.js +108 -0
  82. package/dist/src/renderer/ssr/html.renderer.js.map +1 -0
  83. package/dist/src/renderer/ssr/md.renderer.d.ts +40 -0
  84. package/dist/src/renderer/ssr/md.renderer.js +100 -0
  85. package/dist/src/renderer/ssr/md.renderer.js.map +1 -0
  86. package/dist/src/renderer/ssr/ssr.renderer.d.ts +74 -0
  87. package/dist/src/renderer/ssr/ssr.renderer.js +185 -0
  88. package/dist/src/renderer/ssr/ssr.renderer.js.map +1 -0
  89. package/dist/src/route/route.core.d.ts +129 -0
  90. package/dist/src/route/route.core.js +255 -0
  91. package/dist/src/route/route.core.js.map +1 -0
  92. package/dist/src/route/route.matcher.d.ts +86 -0
  93. package/dist/src/route/route.matcher.js +214 -0
  94. package/dist/src/route/route.matcher.js.map +1 -0
  95. package/dist/src/type/logger.type.d.ts +17 -0
  96. package/dist/src/type/logger.type.js +9 -0
  97. package/dist/src/type/logger.type.js.map +1 -0
  98. package/dist/src/type/markdown.type.d.ts +20 -0
  99. package/dist/src/type/markdown.type.js +2 -0
  100. package/dist/src/type/markdown.type.js.map +1 -0
  101. package/dist/src/type/route.type.d.ts +112 -0
  102. package/dist/src/type/route.type.js +8 -0
  103. package/dist/src/type/route.type.js.map +1 -0
  104. package/dist/src/type/widget.type.d.ts +55 -0
  105. package/dist/src/type/widget.type.js +10 -0
  106. package/dist/src/type/widget.type.js.map +1 -0
  107. package/dist/src/util/html.util.d.ts +29 -0
  108. package/dist/src/util/html.util.js +158 -0
  109. package/dist/src/util/html.util.js.map +1 -0
  110. package/dist/src/util/logger.util.d.ts +26 -0
  111. package/dist/src/util/logger.util.js +80 -0
  112. package/dist/src/util/logger.util.js.map +1 -0
  113. package/dist/src/util/widget-resolve.util.d.ts +52 -0
  114. package/dist/src/util/widget-resolve.util.js +149 -0
  115. package/dist/src/util/widget-resolve.util.js.map +1 -0
  116. package/dist/src/widget/breadcrumb.widget.d.ts +48 -0
  117. package/dist/src/widget/breadcrumb.widget.js +72 -0
  118. package/dist/src/widget/breadcrumb.widget.js.map +1 -0
  119. package/dist/src/widget/page-title.widget.d.ts +33 -0
  120. package/dist/src/widget/page-title.widget.js +33 -0
  121. package/dist/src/widget/page-title.widget.js.map +1 -0
  122. package/dist/src/widget/widget.parser.d.ts +26 -0
  123. package/dist/src/widget/widget.parser.js +76 -0
  124. package/dist/src/widget/widget.parser.js.map +1 -0
  125. package/dist/src/widget/widget.registry.d.ts +23 -0
  126. package/dist/src/widget/widget.registry.js +42 -0
  127. package/dist/src/widget/widget.registry.js.map +1 -0
  128. package/package.json +72 -13
@@ -0,0 +1,205 @@
1
+ var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) {
2
+ if (typeof path === "string" && /^\.\.?\//.test(path)) {
3
+ return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {
4
+ return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js");
5
+ });
6
+ }
7
+ return path;
8
+ };
9
+ import { stat, readdir, mkdir } from 'node:fs/promises';
10
+ import { createRequire } from 'node:module';
11
+ import { resolve } from 'node:path';
12
+ import { CONTENT_TYPES, DEFAULT_ROUTES_DIR, DEFAULT_WIDGETS_DIR, EMROUTE_EXTERNALS, ROUTES_MANIFEST_PATH, Runtime, WIDGETS_MANIFEST_PATH, } from "../../abstract.runtime.js";
13
+ import { createManifestPlugin } from "../../../server/esbuild-manifest.plugin.js";
14
+ import { createRuntimeLoaderPlugin } from "../esbuild-runtime-loader.plugin.js";
15
+ import { generateMainTs } from "../../../server/codegen.util.js";
16
+ export class BunFsRuntime extends Runtime {
17
+ root;
18
+ constructor(root, config = {}) {
19
+ if (config.entryPoint && !config.bundlePaths) {
20
+ config.bundlePaths = { emroute: '/emroute.js', app: '/app.js' };
21
+ }
22
+ super(config);
23
+ const abs = resolve(root);
24
+ this.root = abs.endsWith('/') ? abs.slice(0, -1) : abs;
25
+ }
26
+ handle(resource, init) {
27
+ const [pathname, method, body] = this.parse(resource, init);
28
+ const path = `${this.root}${pathname}`;
29
+ switch (method) {
30
+ case 'PUT':
31
+ return this.write(path, body);
32
+ default:
33
+ return this.read(path);
34
+ }
35
+ }
36
+ query(resource, options) {
37
+ if (options?.as === 'text') {
38
+ const pathname = this.parsePath(resource);
39
+ return Bun.file(`${this.root}${pathname}`).text();
40
+ }
41
+ return this.handle(resource, options);
42
+ }
43
+ parsePath(resource) {
44
+ if (typeof resource === 'string')
45
+ return decodeURIComponent(resource);
46
+ if (resource instanceof URL)
47
+ return decodeURIComponent(resource.pathname);
48
+ return decodeURIComponent(new URL(resource.url).pathname);
49
+ }
50
+ parse(resource, init) {
51
+ const pathname = this.parsePath(resource);
52
+ if (typeof resource === 'string' || resource instanceof URL) {
53
+ return [pathname, init?.method ?? 'GET', init?.body ?? null];
54
+ }
55
+ return [
56
+ pathname,
57
+ init?.method ?? resource.method,
58
+ init?.body ?? resource.body,
59
+ ];
60
+ }
61
+ async read(path) {
62
+ try {
63
+ const info = await stat(path);
64
+ if (info.isDirectory()) {
65
+ return this.list(path);
66
+ }
67
+ const content = new Uint8Array(await Bun.file(path).arrayBuffer());
68
+ const ext = path.slice(path.lastIndexOf('.')).toLowerCase();
69
+ const headers = {
70
+ 'Content-Type': CONTENT_TYPES.get(ext) ?? 'application/octet-stream',
71
+ 'Content-Length': content.byteLength.toString(),
72
+ };
73
+ if (info.mtime) {
74
+ headers['Last-Modified'] = info.mtime.toUTCString();
75
+ }
76
+ return new Response(content, { status: 200, headers });
77
+ }
78
+ catch (error) {
79
+ if (error.code === 'ENOENT') {
80
+ const pathname = path.slice(this.root.length);
81
+ if (pathname === ROUTES_MANIFEST_PATH)
82
+ return this.resolveRoutesManifest();
83
+ if (pathname === WIDGETS_MANIFEST_PATH)
84
+ return this.resolveWidgetsManifest();
85
+ return new Response('Not Found', { status: 404 });
86
+ }
87
+ return new Response(`Internal Error: ${error}`, { status: 500 });
88
+ }
89
+ }
90
+ async list(path) {
91
+ const entries = [];
92
+ const dirents = await readdir(path, { withFileTypes: true });
93
+ for (const entry of dirents) {
94
+ entries.push(entry.name + (entry.isDirectory() ? '/' : ''));
95
+ }
96
+ return Response.json(entries);
97
+ }
98
+ async write(path, body) {
99
+ try {
100
+ const content = body
101
+ ? new Uint8Array(await new Response(body).arrayBuffer())
102
+ : new Uint8Array();
103
+ const dir = path.slice(0, path.lastIndexOf('/'));
104
+ if (dir)
105
+ await mkdir(dir, { recursive: true });
106
+ await Bun.write(path, content);
107
+ return new Response(null, { status: 204 });
108
+ }
109
+ catch (error) {
110
+ return new Response(`Write failed: ${error}`, { status: 500 });
111
+ }
112
+ }
113
+ loadModule(path) {
114
+ return import(__rewriteRelativeImportExtension(this.root + path));
115
+ }
116
+ // ── Bundling ─────────────────────────────────────────────────────────
117
+ async bundle() {
118
+ if (this.config.spa === 'none')
119
+ return;
120
+ const paths = this.config.bundlePaths;
121
+ if (!paths)
122
+ return;
123
+ const esbuild = await BunFsRuntime.esbuild();
124
+ const builds = [];
125
+ const shared = { bundle: true, write: false, format: 'esm', platform: 'browser' };
126
+ const runtimeLoader = createRuntimeLoaderPlugin({ runtime: this, root: this.root });
127
+ // Emroute SPA bundle — resolve from consumer's node_modules (no runtime loader needed)
128
+ const consumerRequire = createRequire(this.root + '/');
129
+ const spaEntry = consumerRequire.resolve('@emkodev/emroute/spa');
130
+ builds.push(esbuild.build({
131
+ ...shared,
132
+ entryPoints: [spaEntry],
133
+ outfile: `${this.root}${paths.emroute}`,
134
+ }));
135
+ // App bundle — generate main.ts if absent, virtual plugin resolves manifests
136
+ if (this.config.entryPoint) {
137
+ if ((await this.query(this.config.entryPoint)).status === 404) {
138
+ const hasRoutes = (await this.query((this.config.routesDir ?? DEFAULT_ROUTES_DIR) + '/')).status !== 404;
139
+ const hasWidgets = (await this.query((this.config.widgetsDir ?? DEFAULT_WIDGETS_DIR) + '/')).status !== 404;
140
+ const code = generateMainTs('root', hasRoutes, hasWidgets, '@emkodev/emroute');
141
+ await this.command(this.config.entryPoint, { body: code });
142
+ }
143
+ const manifestPlugin = createManifestPlugin({
144
+ runtime: this,
145
+ basePath: '/html',
146
+ resolveDir: this.root,
147
+ });
148
+ builds.push(esbuild.build({
149
+ ...shared,
150
+ entryPoints: [`${this.root}${this.config.entryPoint}`],
151
+ outfile: `${this.root}${paths.app}`,
152
+ external: [...EMROUTE_EXTERNALS],
153
+ plugins: [manifestPlugin, runtimeLoader],
154
+ }));
155
+ }
156
+ // Widgets bundle
157
+ if (paths.widgets) {
158
+ const widgetsTsPath = paths.widgets.replace('.js', '.ts');
159
+ if ((await this.query(widgetsTsPath)).status !== 404) {
160
+ builds.push(esbuild.build({
161
+ ...shared,
162
+ entryPoints: [`${this.root}${widgetsTsPath}`],
163
+ outfile: `${this.root}${paths.widgets}`,
164
+ external: [...EMROUTE_EXTERNALS],
165
+ plugins: [runtimeLoader],
166
+ }));
167
+ }
168
+ }
169
+ const results = await Promise.all(builds);
170
+ // Write all output files through the runtime
171
+ for (const result of results) {
172
+ for (const file of result.outputFiles) {
173
+ const runtimePath = file.path.startsWith(this.root)
174
+ ? file.path.slice(this.root.length)
175
+ : '/' + file.path;
176
+ await this.command(runtimePath, { body: file.contents });
177
+ }
178
+ }
179
+ await this.writeShell(paths);
180
+ await esbuild.stop();
181
+ BunFsRuntime._esbuild = null;
182
+ }
183
+ // ── Transpile / esbuild ───────────────────────────────────────────────
184
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
185
+ static _esbuild = null;
186
+ static async esbuild() {
187
+ if (!BunFsRuntime._esbuild) {
188
+ // Resolve esbuild from the consumer's node_modules, not the package's
189
+ const consumerRequire = createRequire(process.cwd() + '/');
190
+ BunFsRuntime._esbuild = consumerRequire('esbuild');
191
+ }
192
+ return BunFsRuntime._esbuild;
193
+ }
194
+ static transpile(source) {
195
+ const transpiler = new Bun.Transpiler({ loader: 'ts' });
196
+ return Promise.resolve(transpiler.transformSync(source));
197
+ }
198
+ static async stopBundler() {
199
+ if (BunFsRuntime._esbuild) {
200
+ await BunFsRuntime._esbuild.stop();
201
+ BunFsRuntime._esbuild = null;
202
+ }
203
+ }
204
+ }
205
+ //# sourceMappingURL=bun-fs.runtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bun-fs.runtime.js","sourceRoot":"","sources":["../../../../runtime/bun/fs/bun-fs.runtime.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ import { type FetchParams, type FetchReturn, Runtime, type RuntimeConfig } from '../../abstract.runtime.ts';
2
+ export declare class BunSqliteRuntime extends Runtime {
3
+ private readonly db;
4
+ private readonly stmtGet;
5
+ private readonly stmtSet;
6
+ private readonly stmtList;
7
+ private readonly stmtHas;
8
+ constructor(path?: string, config?: RuntimeConfig);
9
+ handle(resource: FetchParams[0], init?: FetchParams[1]): FetchReturn;
10
+ query(resource: FetchParams[0], options: FetchParams[1] & {
11
+ as: 'text';
12
+ }): Promise<string>;
13
+ query(resource: FetchParams[0], options?: FetchParams[1]): FetchReturn;
14
+ loadModule(path: string): Promise<unknown>;
15
+ close(): void;
16
+ bundle(): Promise<void>;
17
+ private read;
18
+ private write;
19
+ private listChildren;
20
+ private hasChildren;
21
+ private static _esbuild;
22
+ private static esbuild;
23
+ static transpile(source: string): Promise<string>;
24
+ static stopBundler(): Promise<void>;
25
+ private parsePath;
26
+ private parse;
27
+ }
@@ -0,0 +1,234 @@
1
+ var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) {
2
+ if (typeof path === "string" && /^\.\.?\//.test(path)) {
3
+ return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {
4
+ return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js");
5
+ });
6
+ }
7
+ return path;
8
+ };
9
+ import { createRequire } from 'node:module';
10
+ import { Database } from 'bun:sqlite';
11
+ import { CONTENT_TYPES, DEFAULT_ROUTES_DIR, DEFAULT_WIDGETS_DIR, EMROUTE_EXTERNALS, ROUTES_MANIFEST_PATH, Runtime, WIDGETS_MANIFEST_PATH, } from "../../abstract.runtime.js";
12
+ import { createManifestPlugin } from "../../../server/esbuild-manifest.plugin.js";
13
+ import { createRuntimeLoaderPlugin } from "../esbuild-runtime-loader.plugin.js";
14
+ import { generateMainTs } from "../../../server/codegen.util.js";
15
+ export class BunSqliteRuntime extends Runtime {
16
+ db;
17
+ stmtGet;
18
+ stmtSet;
19
+ stmtList;
20
+ stmtHas;
21
+ constructor(path = ':memory:', config = {}) {
22
+ if (config.entryPoint && !config.bundlePaths) {
23
+ config.bundlePaths = { emroute: '/emroute.js', app: '/app.js' };
24
+ }
25
+ super(config);
26
+ this.db = new Database(path);
27
+ this.db.run(`
28
+ CREATE TABLE IF NOT EXISTS files (
29
+ path TEXT PRIMARY KEY,
30
+ data BLOB NOT NULL,
31
+ mtime TEXT NOT NULL
32
+ )
33
+ `);
34
+ this.stmtGet = this.db.prepare('SELECT data, mtime FROM files WHERE path = ?');
35
+ this.stmtSet = this.db.prepare('INSERT OR REPLACE INTO files (path, data, mtime) VALUES (?, ?, ?)');
36
+ this.stmtList = this.db.prepare("SELECT DISTINCT path FROM files WHERE path LIKE ? || '%'");
37
+ this.stmtHas = this.db.prepare("SELECT 1 FROM files WHERE path LIKE ? || '%' LIMIT 1");
38
+ }
39
+ handle(resource, init) {
40
+ const [pathname, method, body] = this.parse(resource, init);
41
+ switch (method) {
42
+ case 'PUT':
43
+ return this.write(pathname, body);
44
+ default:
45
+ return this.read(pathname);
46
+ }
47
+ }
48
+ query(resource, options) {
49
+ if (options?.as === 'text') {
50
+ const pathname = this.parsePath(resource);
51
+ const row = this.stmtGet.get(pathname);
52
+ if (!row) {
53
+ return Promise.reject(new Error(`Not found: ${pathname}`));
54
+ }
55
+ return Promise.resolve(new TextDecoder().decode(row.data));
56
+ }
57
+ return this.handle(resource, options);
58
+ }
59
+ async loadModule(path) {
60
+ const source = await this.query(path, { as: 'text' });
61
+ const code = path.endsWith('.ts')
62
+ ? await BunSqliteRuntime.transpile(source)
63
+ : source;
64
+ const blob = new Blob([code], { type: 'text/javascript' });
65
+ const url = URL.createObjectURL(blob);
66
+ try {
67
+ return await import(__rewriteRelativeImportExtension(url));
68
+ }
69
+ finally {
70
+ URL.revokeObjectURL(url);
71
+ }
72
+ }
73
+ close() {
74
+ this.db.close();
75
+ }
76
+ // ── Bundling ─────────────────────────────────────────────────────────
77
+ async bundle() {
78
+ if (this.config.spa === 'none')
79
+ return;
80
+ const paths = this.config.bundlePaths;
81
+ if (!paths)
82
+ return;
83
+ const esbuild = await BunSqliteRuntime.esbuild();
84
+ const builds = [];
85
+ const shared = { bundle: true, write: false, format: 'esm', platform: 'browser' };
86
+ const runtimeLoader = createRuntimeLoaderPlugin({ runtime: this, root: '' });
87
+ // Emroute SPA bundle — resolve from consumer's node_modules (no runtime loader needed)
88
+ const consumerRequire = createRequire(process.cwd() + '/');
89
+ const spaEntry = consumerRequire.resolve('@emkodev/emroute/spa');
90
+ builds.push(esbuild.build({
91
+ ...shared,
92
+ entryPoints: [spaEntry],
93
+ outfile: paths.emroute,
94
+ }));
95
+ // App bundle — generate main.ts if absent, virtual plugin resolves manifests
96
+ if (this.config.entryPoint) {
97
+ if ((await this.query(this.config.entryPoint)).status === 404) {
98
+ const hasRoutes = (await this.query((this.config.routesDir ?? DEFAULT_ROUTES_DIR) + '/')).status !== 404;
99
+ const hasWidgets = (await this.query((this.config.widgetsDir ?? DEFAULT_WIDGETS_DIR) + '/')).status !== 404;
100
+ const code = generateMainTs('root', hasRoutes, hasWidgets, '@emkodev/emroute');
101
+ await this.command(this.config.entryPoint, { body: code });
102
+ }
103
+ const manifestPlugin = createManifestPlugin({
104
+ runtime: this,
105
+ basePath: '/html',
106
+ resolveDir: process.cwd(),
107
+ });
108
+ builds.push(esbuild.build({
109
+ ...shared,
110
+ entryPoints: [this.config.entryPoint],
111
+ outfile: paths.app,
112
+ external: [...EMROUTE_EXTERNALS],
113
+ plugins: [manifestPlugin, runtimeLoader],
114
+ }));
115
+ }
116
+ // Widgets bundle
117
+ if (paths.widgets) {
118
+ const widgetsTsPath = paths.widgets.replace('.js', '.ts');
119
+ if ((await this.query(widgetsTsPath)).status !== 404) {
120
+ builds.push(esbuild.build({
121
+ ...shared,
122
+ entryPoints: [widgetsTsPath],
123
+ outfile: paths.widgets,
124
+ external: [...EMROUTE_EXTERNALS],
125
+ plugins: [runtimeLoader],
126
+ }));
127
+ }
128
+ }
129
+ const results = await Promise.all(builds);
130
+ // Write all output files through the runtime
131
+ for (const result of results) {
132
+ for (const file of result.outputFiles) {
133
+ // outfile paths are relative — ensure leading /
134
+ const runtimePath = file.path.startsWith('/') ? file.path : '/' + file.path;
135
+ await this.command(runtimePath, { body: file.contents });
136
+ }
137
+ }
138
+ await this.writeShell(paths);
139
+ await esbuild.stop();
140
+ BunSqliteRuntime._esbuild = null;
141
+ }
142
+ // ── Private ─────────────────────────────────────────────────────────
143
+ async read(path) {
144
+ if (path.endsWith('/')) {
145
+ const children = this.listChildren(path);
146
+ if (children.length === 0) {
147
+ return new Response('Not Found', { status: 404 });
148
+ }
149
+ return Response.json(children);
150
+ }
151
+ if (!this.stmtGet.get(path) && this.hasChildren(path + '/')) {
152
+ return Response.json(this.listChildren(path + '/'));
153
+ }
154
+ const row = this.stmtGet.get(path);
155
+ if (!row) {
156
+ if (path === ROUTES_MANIFEST_PATH)
157
+ return this.resolveRoutesManifest();
158
+ if (path === WIDGETS_MANIFEST_PATH)
159
+ return this.resolveWidgetsManifest();
160
+ return new Response('Not Found', { status: 404 });
161
+ }
162
+ const data = new Uint8Array(row.data);
163
+ const ext = path.slice(path.lastIndexOf('.')).toLowerCase();
164
+ const headers = {
165
+ 'Content-Type': CONTENT_TYPES.get(ext) ?? 'application/octet-stream',
166
+ 'Content-Length': data.byteLength.toString(),
167
+ 'Last-Modified': new Date(row.mtime).toUTCString(),
168
+ };
169
+ return new Response(data, { status: 200, headers });
170
+ }
171
+ async write(path, body) {
172
+ const data = body
173
+ ? new Uint8Array(await new Response(body).arrayBuffer())
174
+ : new Uint8Array();
175
+ this.stmtSet.run(path, data, new Date().toISOString());
176
+ return new Response(null, { status: 204 });
177
+ }
178
+ listChildren(prefix) {
179
+ const rows = this.stmtList.all(prefix);
180
+ const entries = new Set();
181
+ for (const row of rows) {
182
+ const rest = row.path.slice(prefix.length);
183
+ const slashIdx = rest.indexOf('/');
184
+ if (slashIdx === -1) {
185
+ entries.add(rest);
186
+ }
187
+ else {
188
+ entries.add(rest.slice(0, slashIdx + 1));
189
+ }
190
+ }
191
+ return [...entries];
192
+ }
193
+ hasChildren(prefix) {
194
+ return this.stmtHas.get(prefix) !== null;
195
+ }
196
+ // ── Transpile / esbuild ───────────────────────────────────────────────
197
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
198
+ static _esbuild = null;
199
+ static async esbuild() {
200
+ if (!BunSqliteRuntime._esbuild) {
201
+ BunSqliteRuntime._esbuild = await import('esbuild');
202
+ }
203
+ return BunSqliteRuntime._esbuild;
204
+ }
205
+ static transpile(source) {
206
+ const transpiler = new Bun.Transpiler({ loader: 'ts' });
207
+ return Promise.resolve(transpiler.transformSync(source));
208
+ }
209
+ static async stopBundler() {
210
+ if (BunSqliteRuntime._esbuild) {
211
+ await BunSqliteRuntime._esbuild.stop();
212
+ BunSqliteRuntime._esbuild = null;
213
+ }
214
+ }
215
+ parsePath(resource) {
216
+ if (typeof resource === 'string')
217
+ return decodeURIComponent(resource);
218
+ if (resource instanceof URL)
219
+ return decodeURIComponent(resource.pathname);
220
+ return decodeURIComponent(new URL(resource.url).pathname);
221
+ }
222
+ parse(resource, init) {
223
+ const pathname = this.parsePath(resource);
224
+ if (typeof resource === 'string' || resource instanceof URL) {
225
+ return [pathname, init?.method ?? 'GET', init?.body ?? null];
226
+ }
227
+ return [
228
+ pathname,
229
+ init?.method ?? resource.method,
230
+ init?.body ?? resource.body,
231
+ ];
232
+ }
233
+ }
234
+ //# sourceMappingURL=bun-sqlite.runtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bun-sqlite.runtime.js","sourceRoot":"","sources":["../../../../runtime/bun/sqlite/bun-sqlite.runtime.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Sitemap Generator — Opt-in Submodule
3
+ *
4
+ * Generates sitemap.xml from a RoutesManifest. Pure function over manifest data,
5
+ * no filesystem access needed.
6
+ *
7
+ * Usage:
8
+ * import { generateSitemap } from '@emkodev/emroute/runtime/sitemap';
9
+ * const xml = await generateSitemap(manifest, { baseUrl: 'https://example.com' });
10
+ *
11
+ * Per sitemaps.org protocol:
12
+ * - <loc> is required (full absolute URL)
13
+ * - <lastmod>, <changefreq>, <priority> are optional
14
+ * - URLs use route patterns as-is (patterns include basePath when present)
15
+ * - Max 50,000 URLs per sitemap file
16
+ *
17
+ * @see https://www.sitemaps.org/protocol.html
18
+ */
19
+ import type { RoutesManifest } from '../src/type/route.type.ts';
20
+ /** Valid changefreq values per sitemaps.org protocol. */
21
+ export type Changefreq = 'always' | 'hourly' | 'daily' | 'weekly' | 'monthly' | 'yearly' | 'never';
22
+ /** Per-route sitemap overrides. */
23
+ export interface SitemapRouteOptions {
24
+ /** W3C Datetime, e.g. '2025-06-15' or '2025-06-15T10:30:00+00:00' */
25
+ lastmod?: string;
26
+ changefreq?: Changefreq;
27
+ /** 0.0–1.0, default 0.5 per protocol */
28
+ priority?: number;
29
+ }
30
+ /** Options for sitemap generation. */
31
+ export interface SitemapOptions {
32
+ /** Site origin with protocol, e.g. 'https://example.com'. No trailing slash. */
33
+ baseUrl: string;
34
+ /** Per-route overrides keyed by route pattern (including basePath if present). */
35
+ routes?: Record<string, SitemapRouteOptions>;
36
+ /** Defaults applied when a route has no specific override. */
37
+ defaults?: SitemapRouteOptions;
38
+ /**
39
+ * Enumerators for dynamic routes. Keyed by route pattern (e.g. '/html/projects/:id').
40
+ * Each function returns concrete path segments to substitute for the parameter.
41
+ * Dynamic routes without an enumerator are excluded from the sitemap.
42
+ */
43
+ enumerators?: Record<string, () => Promise<string[]>>;
44
+ /**
45
+ * Base path to prepend to patterns when manifest contains bare patterns.
46
+ * When the manifest already has prefixed patterns (e.g. from generateManifestCode),
47
+ * leave this unset.
48
+ */
49
+ basePath?: string;
50
+ }
51
+ /**
52
+ * Generate sitemap.xml content from a routes manifest.
53
+ *
54
+ * Static routes (no :param) are included directly.
55
+ * Dynamic routes are included only if an enumerator is provided.
56
+ * All URLs point to /html/ prefixed paths for SSR HTML rendering.
57
+ */
58
+ export declare function generateSitemap(manifest: RoutesManifest, options: SitemapOptions): Promise<string>;
@@ -0,0 +1,107 @@
1
+ /**
2
+ * Sitemap Generator — Opt-in Submodule
3
+ *
4
+ * Generates sitemap.xml from a RoutesManifest. Pure function over manifest data,
5
+ * no filesystem access needed.
6
+ *
7
+ * Usage:
8
+ * import { generateSitemap } from '@emkodev/emroute/runtime/sitemap';
9
+ * const xml = await generateSitemap(manifest, { baseUrl: 'https://example.com' });
10
+ *
11
+ * Per sitemaps.org protocol:
12
+ * - <loc> is required (full absolute URL)
13
+ * - <lastmod>, <changefreq>, <priority> are optional
14
+ * - URLs use route patterns as-is (patterns include basePath when present)
15
+ * - Max 50,000 URLs per sitemap file
16
+ *
17
+ * @see https://www.sitemaps.org/protocol.html
18
+ */
19
+ import { escapeHtml } from "../src/util/html.util.js";
20
+ const XML_HEADER = '<?xml version="1.0" encoding="UTF-8"?>';
21
+ const URLSET_OPEN = '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">';
22
+ const URLSET_CLOSE = '</urlset>';
23
+ const MAX_URLS = 50_000;
24
+ /** Check if a route pattern contains dynamic segments. */
25
+ function isDynamic(pattern) {
26
+ return pattern.includes(':');
27
+ }
28
+ /** Build the absolute URL for a route path. */
29
+ function buildLoc(baseUrl, path, basePath = '') {
30
+ const base = baseUrl.replace(/\/+$/, '');
31
+ if (path === '/' && basePath)
32
+ return `${base}${basePath}/`;
33
+ return `${base}${basePath}${path}`;
34
+ }
35
+ /**
36
+ * Expand a dynamic pattern using an enumerator's param values.
37
+ * Supports single-param patterns like '/projects/:id'.
38
+ * Multi-param patterns are expanded per value (first param replaced).
39
+ */
40
+ function expandDynamic(pattern, values) {
41
+ // Find the first :param segment
42
+ const paramMatch = pattern.match(/:([^/]+)/);
43
+ if (!paramMatch)
44
+ return [];
45
+ return values.map((value) => pattern.replace(paramMatch[0], encodeURIComponent(value)));
46
+ }
47
+ /** Resolve route options: per-route override > defaults > empty. */
48
+ function resolveOptions(pattern, options) {
49
+ return { ...options.defaults, ...options.routes?.[pattern] };
50
+ }
51
+ /** Serialize a single <url> entry. */
52
+ function serializeEntry(entry) {
53
+ const lines = [` <url>`, ` <loc>${escapeHtml(entry.loc)}</loc>`];
54
+ if (entry.lastmod !== undefined) {
55
+ lines.push(` <lastmod>${escapeHtml(entry.lastmod)}</lastmod>`);
56
+ }
57
+ if (entry.changefreq !== undefined) {
58
+ lines.push(` <changefreq>${entry.changefreq}</changefreq>`);
59
+ }
60
+ if (entry.priority !== undefined) {
61
+ lines.push(` <priority>${entry.priority.toFixed(1)}</priority>`);
62
+ }
63
+ lines.push(` </url>`);
64
+ return lines.join('\n');
65
+ }
66
+ /**
67
+ * Generate sitemap.xml content from a routes manifest.
68
+ *
69
+ * Static routes (no :param) are included directly.
70
+ * Dynamic routes are included only if an enumerator is provided.
71
+ * All URLs point to /html/ prefixed paths for SSR HTML rendering.
72
+ */
73
+ export async function generateSitemap(manifest, options) {
74
+ const entries = [];
75
+ const bp = options.basePath ?? '';
76
+ // Filter to page routes only (exclude error, redirect)
77
+ const pages = manifest.routes.filter((r) => r.type === 'page');
78
+ for (const route of pages) {
79
+ const routeOpts = resolveOptions(route.pattern, options);
80
+ if (isDynamic(route.pattern)) {
81
+ // Dynamic route — use enumerator if provided, skip otherwise
82
+ const enumerator = options.enumerators?.[route.pattern];
83
+ if (!enumerator)
84
+ continue;
85
+ const values = await enumerator();
86
+ const paths = expandDynamic(route.pattern, values);
87
+ for (const path of paths) {
88
+ entries.push({
89
+ loc: buildLoc(options.baseUrl, path, bp),
90
+ ...routeOpts,
91
+ });
92
+ }
93
+ }
94
+ else {
95
+ // Static route — include directly
96
+ entries.push({
97
+ loc: buildLoc(options.baseUrl, route.pattern, bp),
98
+ ...routeOpts,
99
+ });
100
+ }
101
+ if (entries.length >= MAX_URLS)
102
+ break;
103
+ }
104
+ const urlEntries = entries.slice(0, MAX_URLS).map(serializeEntry).join('\n');
105
+ return `${XML_HEADER}\n${URLSET_OPEN}\n${urlEntries}\n${URLSET_CLOSE}\n`;
106
+ }
107
+ //# sourceMappingURL=sitemap.generator.js.map