@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.
- package/README.md +6 -6
- package/dist/runtime/abstract.runtime.d.ts +94 -0
- package/dist/runtime/abstract.runtime.js +339 -0
- package/dist/runtime/abstract.runtime.js.map +1 -0
- package/dist/runtime/bun/esbuild-runtime-loader.plugin.d.ts +25 -0
- package/dist/runtime/bun/esbuild-runtime-loader.plugin.js +72 -0
- package/dist/runtime/bun/esbuild-runtime-loader.plugin.js.map +1 -0
- package/dist/runtime/bun/fs/bun-fs.runtime.d.ts +21 -0
- package/dist/runtime/bun/fs/bun-fs.runtime.js +205 -0
- package/dist/runtime/bun/fs/bun-fs.runtime.js.map +1 -0
- package/dist/runtime/bun/sqlite/bun-sqlite.runtime.d.ts +27 -0
- package/dist/runtime/bun/sqlite/bun-sqlite.runtime.js +234 -0
- package/dist/runtime/bun/sqlite/bun-sqlite.runtime.js.map +1 -0
- package/dist/runtime/sitemap.generator.d.ts +58 -0
- package/dist/runtime/sitemap.generator.js +107 -0
- package/dist/runtime/sitemap.generator.js.map +1 -0
- package/dist/runtime/universal/fs/universal-fs.runtime.d.ts +29 -0
- package/dist/runtime/universal/fs/universal-fs.runtime.js +213 -0
- package/dist/runtime/universal/fs/universal-fs.runtime.js.map +1 -0
- package/dist/server/codegen.util.d.ts +16 -0
- package/dist/server/codegen.util.js +46 -0
- package/dist/server/codegen.util.js.map +1 -0
- package/dist/server/emroute.server.d.ts +37 -0
- package/dist/server/emroute.server.js +314 -0
- package/dist/server/emroute.server.js.map +1 -0
- package/dist/server/esbuild-manifest.plugin.d.ts +26 -0
- package/dist/server/esbuild-manifest.plugin.js +187 -0
- package/dist/server/esbuild-manifest.plugin.js.map +1 -0
- package/dist/server/scanner.util.d.ts +22 -0
- package/dist/server/scanner.util.js +194 -0
- package/dist/server/scanner.util.js.map +1 -0
- package/dist/server/server-api.type.d.ts +71 -0
- package/dist/server/server-api.type.js +9 -0
- package/dist/server/server-api.type.js.map +1 -0
- package/dist/src/component/abstract.component.d.ts +197 -0
- package/dist/src/component/abstract.component.js +84 -0
- package/dist/src/component/abstract.component.js.map +1 -0
- package/dist/src/component/page.component.d.ts +74 -0
- package/dist/src/component/page.component.js +107 -0
- package/dist/src/component/page.component.js.map +1 -0
- package/dist/src/component/widget.component.d.ts +47 -0
- package/dist/src/component/widget.component.js +69 -0
- package/dist/src/component/widget.component.js.map +1 -0
- package/dist/src/element/component.element.d.ts +79 -0
- package/dist/src/element/component.element.js +293 -0
- package/dist/src/element/component.element.js.map +1 -0
- package/dist/src/element/markdown.element.d.ts +36 -0
- package/dist/src/element/markdown.element.js +93 -0
- package/dist/src/element/markdown.element.js.map +1 -0
- package/dist/src/element/slot.element.d.ts +30 -0
- package/dist/src/element/slot.element.js +31 -0
- package/dist/src/element/slot.element.js.map +1 -0
- package/dist/src/index.d.ts +23 -0
- package/dist/src/index.js +24 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/overlay/mod.d.ts +9 -0
- package/dist/src/overlay/mod.js +9 -0
- package/dist/src/overlay/mod.js.map +1 -0
- package/dist/src/overlay/overlay.css.d.ts +8 -0
- package/dist/src/overlay/overlay.css.js +170 -0
- package/dist/src/overlay/overlay.css.js.map +1 -0
- package/dist/src/overlay/overlay.service.d.ts +14 -0
- package/dist/src/overlay/overlay.service.js +307 -0
- package/dist/src/overlay/overlay.service.js.map +1 -0
- package/dist/src/overlay/overlay.type.d.ts +33 -0
- package/dist/src/overlay/overlay.type.js +11 -0
- package/dist/src/overlay/overlay.type.js.map +1 -0
- package/dist/src/renderer/spa/base.renderer.d.ts +39 -0
- package/dist/src/renderer/spa/base.renderer.js +149 -0
- package/dist/src/renderer/spa/base.renderer.js.map +1 -0
- package/dist/src/renderer/spa/hash.renderer.d.ts +78 -0
- package/dist/src/renderer/spa/hash.renderer.js +162 -0
- package/dist/src/renderer/spa/hash.renderer.js.map +1 -0
- package/dist/src/renderer/spa/html.renderer.d.ts +81 -0
- package/dist/src/renderer/spa/html.renderer.js +304 -0
- package/dist/src/renderer/spa/html.renderer.js.map +1 -0
- package/dist/src/renderer/spa/mod.d.ts +30 -0
- package/dist/src/renderer/spa/mod.js +35 -0
- package/dist/src/renderer/spa/mod.js.map +1 -0
- package/dist/src/renderer/ssr/html.renderer.d.ts +49 -0
- package/dist/src/renderer/ssr/html.renderer.js +108 -0
- package/dist/src/renderer/ssr/html.renderer.js.map +1 -0
- package/dist/src/renderer/ssr/md.renderer.d.ts +40 -0
- package/dist/src/renderer/ssr/md.renderer.js +100 -0
- package/dist/src/renderer/ssr/md.renderer.js.map +1 -0
- package/dist/src/renderer/ssr/ssr.renderer.d.ts +74 -0
- package/dist/src/renderer/ssr/ssr.renderer.js +185 -0
- package/dist/src/renderer/ssr/ssr.renderer.js.map +1 -0
- package/dist/src/route/route.core.d.ts +129 -0
- package/dist/src/route/route.core.js +255 -0
- package/dist/src/route/route.core.js.map +1 -0
- package/dist/src/route/route.matcher.d.ts +86 -0
- package/dist/src/route/route.matcher.js +214 -0
- package/dist/src/route/route.matcher.js.map +1 -0
- package/dist/src/type/logger.type.d.ts +17 -0
- package/dist/src/type/logger.type.js +9 -0
- package/dist/src/type/logger.type.js.map +1 -0
- package/dist/src/type/markdown.type.d.ts +20 -0
- package/dist/src/type/markdown.type.js +2 -0
- package/dist/src/type/markdown.type.js.map +1 -0
- package/dist/src/type/route.type.d.ts +112 -0
- package/dist/src/type/route.type.js +8 -0
- package/dist/src/type/route.type.js.map +1 -0
- package/dist/src/type/widget.type.d.ts +55 -0
- package/dist/src/type/widget.type.js +10 -0
- package/dist/src/type/widget.type.js.map +1 -0
- package/dist/src/util/html.util.d.ts +29 -0
- package/dist/src/util/html.util.js +158 -0
- package/dist/src/util/html.util.js.map +1 -0
- package/dist/src/util/logger.util.d.ts +26 -0
- package/dist/src/util/logger.util.js +80 -0
- package/dist/src/util/logger.util.js.map +1 -0
- package/dist/src/util/widget-resolve.util.d.ts +52 -0
- package/dist/src/util/widget-resolve.util.js +149 -0
- package/dist/src/util/widget-resolve.util.js.map +1 -0
- package/dist/src/widget/breadcrumb.widget.d.ts +48 -0
- package/dist/src/widget/breadcrumb.widget.js +72 -0
- package/dist/src/widget/breadcrumb.widget.js.map +1 -0
- package/dist/src/widget/page-title.widget.d.ts +33 -0
- package/dist/src/widget/page-title.widget.js +33 -0
- package/dist/src/widget/page-title.widget.js.map +1 -0
- package/dist/src/widget/widget.parser.d.ts +26 -0
- package/dist/src/widget/widget.parser.js +76 -0
- package/dist/src/widget/widget.parser.js.map +1 -0
- package/dist/src/widget/widget.registry.d.ts +23 -0
- package/dist/src/widget/widget.registry.js +42 -0
- package/dist/src/widget/widget.registry.js.map +1 -0
- 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
|