feature: execute load()
/unload()
methods found in _pre.ts
files
This commit is contained in:
parent
df8291bfc7
commit
046617bc4f
7 changed files with 116 additions and 62 deletions
|
@ -34,8 +34,7 @@ type ROUTE_HANDLER_RECORD = {
|
|||
module?: ROUTE_HANDLER;
|
||||
};
|
||||
const routes: ROUTE_HANDLER_RECORD[] = [];
|
||||
let loading: boolean = false;
|
||||
let all_routes_loaded: boolean = false;
|
||||
const unloaders: (() => Promise<void> | void)[] = [];
|
||||
|
||||
/**
|
||||
* Handles requests for which there are typescript files in the root tree.
|
||||
|
@ -48,57 +47,6 @@ let all_routes_loaded: boolean = false;
|
|||
* @returns Either a response (a handler for the request path and method was found) or undefined if unhandled.
|
||||
*/
|
||||
export default async function handle_typescript(request: Request): Promise<Response | undefined> {
|
||||
if (!all_routes_loaded) {
|
||||
if (!loading) {
|
||||
loading = true;
|
||||
|
||||
const root_directory = path.resolve(Deno.cwd());
|
||||
|
||||
const imports: ROUTE_HANDLER_RECORD[] = [];
|
||||
for await (
|
||||
const entry of walk(root_directory, {
|
||||
exts: ['.ts'],
|
||||
skip: [/\.test\.ts$/]
|
||||
})
|
||||
) {
|
||||
if (entry.isFile) {
|
||||
const relative_path = entry.path.substring(root_directory.length);
|
||||
const route_path = relative_path
|
||||
.replace(/\.ts$/, '')
|
||||
//.replace(/\[(\w+)\]/g, ':$1')
|
||||
.replace(/\/index$/, '')
|
||||
.replace(/___/g, ':') || // required for windows, uncivilized OS that it is
|
||||
'/';
|
||||
|
||||
const route_pattern = new URLPattern({ pathname: route_path });
|
||||
|
||||
const import_path = new URL('file://' + entry.path, import.meta.url).toString();
|
||||
|
||||
imports.push({
|
||||
route_path,
|
||||
route_pattern,
|
||||
import_path
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// try to sort imports such that they're registered like:
|
||||
// /permissions/test
|
||||
// /api/echo/hi
|
||||
// /api/echo/:input
|
||||
//
|
||||
// we want paths with parameters to sort later than paths without
|
||||
routes.push(...imports.sort((lhs, rhs) => rhs.route_path.localeCompare(lhs.route_path)));
|
||||
|
||||
all_routes_loaded = true;
|
||||
loading = false;
|
||||
}
|
||||
|
||||
do {
|
||||
await delay(10);
|
||||
} while (!all_routes_loaded);
|
||||
}
|
||||
|
||||
for (const route_record of routes) {
|
||||
const match = route_record.route_pattern.exec(request.url.replace(/\/$/, ''));
|
||||
if (match) {
|
||||
|
@ -142,8 +90,64 @@ export default async function handle_typescript(request: Request): Promise<Respo
|
|||
}
|
||||
}
|
||||
|
||||
export function unload(): void {
|
||||
loading = false;
|
||||
routes.splice(0, routes.length);
|
||||
all_routes_loaded = false;
|
||||
export async function load(): Promise<void> {
|
||||
const root_directory = path.resolve(Deno.cwd());
|
||||
|
||||
const imports: ROUTE_HANDLER_RECORD[] = [];
|
||||
for await (
|
||||
const entry of walk(root_directory, {
|
||||
exts: ['.ts'],
|
||||
skip: [/\.test\.ts$/]
|
||||
})
|
||||
) {
|
||||
if (entry.isFile) {
|
||||
const import_path = new URL('file://' + entry.path, import.meta.url).toString();
|
||||
|
||||
const filename = path.basename(entry.path);
|
||||
if (filename === '_pre.ts') {
|
||||
const preloader = await import(import_path);
|
||||
if (typeof preloader.load === 'function') {
|
||||
await preloader.load();
|
||||
}
|
||||
|
||||
if (typeof preloader.unload === 'function') {
|
||||
unloaders.push(preloader.unload);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
const relative_path = entry.path.substring(root_directory.length);
|
||||
const route_path = relative_path
|
||||
.replace(/\.ts$/, '')
|
||||
//.replace(/\[(\w+)\]/g, ':$1')
|
||||
.replace(/\/index$/, '')
|
||||
.replace(/___/g, ':') || // required for windows, uncivilized OS that it is
|
||||
'/';
|
||||
|
||||
const route_pattern = new URLPattern({ pathname: route_path });
|
||||
|
||||
imports.push({
|
||||
route_path,
|
||||
route_pattern,
|
||||
import_path
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// try to sort imports such that they're registered like:
|
||||
// /permissions/test
|
||||
// /api/echo/hi
|
||||
// /api/echo/:input
|
||||
//
|
||||
// we want paths with parameters to sort later than paths without
|
||||
routes.push(...imports.sort((lhs, rhs) => rhs.route_path.localeCompare(lhs.route_path)));
|
||||
}
|
||||
|
||||
export async function unload(): Promise<void> {
|
||||
for (const unloader of unloaders) {
|
||||
await unloader();
|
||||
}
|
||||
|
||||
routes.splice(0, routes.length);
|
||||
unloaders.splice(0, unloaders.length);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue