htmx-router 1.0.0-alpha.5 → 1.0.0-pre1

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 (58) hide show
  1. package/example/eventdim-react/package.json +67 -0
  2. package/example/eventdim-react/server.js +90 -0
  3. package/example/island-react/global.d.ts +8 -0
  4. package/example/island-react/package.json +38 -0
  5. package/example/island-react/server.js +58 -0
  6. package/global.d.ts +7 -0
  7. package/package.json +10 -8
  8. package/readme.md +17 -212
  9. package/bin/cli/config.d.ts +0 -10
  10. package/bin/cli/config.js +0 -4
  11. package/bin/cli/index.d.ts +0 -2
  12. package/bin/cli/index.js +0 -66
  13. package/bin/client/entry.d.ts +0 -1
  14. package/bin/client/entry.js +0 -12
  15. package/bin/client/index.d.ts +0 -7
  16. package/bin/client/index.js +0 -132
  17. package/bin/client/mount.d.ts +0 -2
  18. package/bin/client/mount.js +0 -116
  19. package/bin/client/watch.d.ts +0 -1
  20. package/bin/client/watch.js +0 -11
  21. package/bin/helper.d.ts +0 -2
  22. package/bin/helper.js +0 -34
  23. package/bin/index.d.ts +0 -11
  24. package/bin/index.js +0 -18
  25. package/bin/request/http.d.ts +0 -10
  26. package/bin/request/http.js +0 -41
  27. package/bin/request/index.d.ts +0 -16
  28. package/bin/request/index.js +0 -6
  29. package/bin/request/native.d.ts +0 -9
  30. package/bin/request/native.js +0 -46
  31. package/bin/response.d.ts +0 -9
  32. package/bin/response.js +0 -46
  33. package/bin/router.d.ts +0 -49
  34. package/bin/router.js +0 -217
  35. package/bin/types.d.ts +0 -10
  36. package/bin/types.js +0 -1
  37. package/bin/util/cookies.d.ts +0 -25
  38. package/bin/util/cookies.js +0 -60
  39. package/bin/util/css.d.ts +0 -13
  40. package/bin/util/css.js +0 -55
  41. package/bin/util/dynamic.d.ts +0 -8
  42. package/bin/util/dynamic.js +0 -40
  43. package/bin/util/endpoint.d.ts +0 -13
  44. package/bin/util/endpoint.js +0 -32
  45. package/bin/util/event-source.d.ts +0 -16
  46. package/bin/util/event-source.js +0 -85
  47. package/bin/util/hash.d.ts +0 -4
  48. package/bin/util/hash.js +0 -10
  49. package/bin/util/index.d.ts +0 -1
  50. package/bin/util/index.js +0 -7
  51. package/bin/util/parameters.d.ts +0 -10
  52. package/bin/util/parameters.js +0 -17
  53. package/bin/util/path-builder.d.ts +0 -1
  54. package/bin/util/path-builder.js +0 -43
  55. package/bin/util/response.d.ts +0 -11
  56. package/bin/util/response.js +0 -46
  57. package/bin/util/shell.d.ts +0 -120
  58. package/bin/util/shell.js +0 -251
@@ -1,132 +0,0 @@
1
- /**
2
- * Builds the SSR and client side mounter for client components
3
- */
4
- import { readFile, writeFile } from "fs/promises";
5
- import { init, parse } from "es-module-lexer";
6
- import { QuickHash } from "../util/hash.js";
7
- import { CutString } from "../helper.js";
8
- const pivot = `\n// DO NOT EDIT BELOW THIS LINE\n`;
9
- export async function GenerateClient(config, force = false) {
10
- const file = await readFile(config.source, "utf8");
11
- const [source, history] = CutString(file, pivot);
12
- const hash = QuickHash(source);
13
- if (!force && ExtractHash(history) === hash)
14
- return;
15
- await init;
16
- const imported = ParseImports(source);
17
- await Promise.all([
18
- writeFile(config.source, source
19
- + pivot
20
- + `// hash: ${hash}\n`
21
- + BuildClientServer(config.adapter, imported)),
22
- writeFile(CutString(config.source, ".", -1)[0] + ".manifest.tsx", BuildClientManifest(config.adapter, imported))
23
- ]);
24
- }
25
- function ParseImports(source) {
26
- const parsed = parse(source)[0];
27
- const out = [];
28
- for (const imported of parsed) {
29
- if (imported.a !== -1)
30
- continue;
31
- if (imported.t !== 1)
32
- continue;
33
- const href = source.slice(imported.s, imported.e);
34
- const front = source.slice(imported.ss, imported.s);
35
- const start = front.indexOf("{");
36
- if (start === -1) {
37
- const middle = CutString(CutString(front, "import")[1], "from", -1)[0];
38
- out.push({ mapping: ExtractName(middle), href });
39
- continue;
40
- }
41
- const end = front.lastIndexOf("}");
42
- const segments = front.slice(start + 1, end).split(",");
43
- out.push({ mapping: segments.map(ExtractName), href });
44
- }
45
- return out;
46
- }
47
- function SafeScript(type, script) {
48
- switch (type) {
49
- case "react": return `<script dangerouslySetInnerHTML={{__html: ${script}}}></script>`;
50
- default: return `<script>${script}</script>`;
51
- }
52
- }
53
- function BuildClientServer(type, imported) {
54
- const names = new Array();
55
- for (const imp of imported) {
56
- if (Array.isArray(imp.mapping))
57
- names.push(...imp.mapping.map(x => x.name));
58
- else
59
- names.push(imp.mapping.name);
60
- }
61
- let out = `import { StyleClass } from "htmx-router";\n`
62
- + `const island = new StyleClass("i", ".this{display:contents;}\\n").name;\n\n`
63
- + "type FirstArg<T> = T extends (arg: infer U, ...args: any[]) => any ? U : never;\n"
64
- + "function mount(name: string, data: string, ssr?: JSX.Element) {\n"
65
- + "\treturn (<>\n"
66
- + `\t\t<div className={island}>{ssr}</div>\n`
67
- + `\t\t${SafeScript(type, "`Router.mountAboveWith('${name}', ${data})`")}\n`
68
- + "\t</>);\n"
69
- + "}\n"
70
- + "\n"
71
- + "const Client = {\n";
72
- for (const name of names) {
73
- out += `\t${name}: function(props: FirstArg<typeof ${name}> & { children?: JSX.Element }) {\n`
74
- + `\t\tconst { children, ...rest } = props;\n`
75
- + `\t\treturn mount("${name}", JSON.stringify(rest), children);\n`
76
- + `\t},\n`;
77
- }
78
- out += "}\nexport default Client;\n\n"
79
- + `import { __RebuildClient__ } from "htmx-router/bin/client/watch.js";\n`
80
- + `__RebuildClient__();`;
81
- return out;
82
- }
83
- const renderer = {
84
- react: '\t\tconst r = await import("react-dom/client");\n'
85
- + "\t\tr.createRoot(element).render(<C {...props} />);\n"
86
- };
87
- function BuildClientManifest(type, imports) {
88
- let out = "/*------------------------------------------\n"
89
- + " * Generated by htmx-router *\n"
90
- + " * Warn: Any changes will be overwritten *\n"
91
- + "-------------------------------------------*/\n\n"
92
- + "/* eslint-disable @typescript-eslint/no-explicit-any */\n"
93
- + "const client = {\n";
94
- const render = renderer[type];
95
- if (!render) {
96
- console.error(`Unsupported client adapter ${type}`);
97
- process.exit(1);
98
- }
99
- for (const imported of imports) {
100
- if (Array.isArray(imported.mapping)) {
101
- for (const map of imported.mapping) {
102
- out += `\t${map.name}: async (element: HTMLElement, props: any) => {\n`
103
- + `\t\tconst C = (await import("${imported.href}")).${map.original};\n`
104
- + render
105
- + `\t},\n`;
106
- }
107
- }
108
- else {
109
- out += `\t${imported.mapping.name}: async (element: HTMLElement, props: any) => {\n`
110
- + `\t\tconst C = (await import("${imported.href}")).default;\n`
111
- + render
112
- + `\t},\n`;
113
- }
114
- }
115
- out += "}\nexport default client;\n"
116
- + "(window as any).CLIENT = client;";
117
- return out;
118
- }
119
- function ExtractName(str) {
120
- const parts = CutString(str, "as");
121
- if (parts[1].length !== 0)
122
- return { name: parts[1].trim(), original: parts[0].trim() };
123
- const name = parts[0].trim();
124
- return { name, original: name };
125
- }
126
- function ExtractHash(source) {
127
- const regex = /\/\/\s+hash\s*:\s*(\w+)/;
128
- const match = source.match(regex);
129
- if (match)
130
- return match[1] || "";
131
- return "";
132
- }
@@ -1,2 +0,0 @@
1
- export declare function _resolve(fragments: string[]): Response | null;
2
- export declare function GetMountUrl(): string;
@@ -1,116 +0,0 @@
1
- import { QuickHash } from "../util/hash.js";
2
- import { CutString } from "../helper.js";
3
- // this function simply exists so it can be stringified and written into the client js bundle
4
- function ClientMounter() {
5
- const theme = {
6
- get: () => {
7
- return (localStorage.getItem("theme") || theme.infer());
8
- },
9
- infer: () => {
10
- const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
11
- const current = prefersDark ? 'dark' : 'light';
12
- localStorage.setItem("theme", current);
13
- return current;
14
- },
15
- apply: () => {
16
- document.documentElement.setAttribute('data-theme', theme.get());
17
- },
18
- toggle: () => {
19
- if (theme.get() === "dark")
20
- localStorage.setItem("theme", "light");
21
- else
22
- localStorage.setItem("theme", "dark");
23
- theme.apply();
24
- return localStorage.getItem("theme");
25
- }
26
- };
27
- window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', () => {
28
- theme.infer();
29
- theme.apply();
30
- });
31
- theme.apply();
32
- const global = window;
33
- const mountRequests = new Array();
34
- function RequestMount(funcName, json) {
35
- mountRequests.push([funcName, document.currentScript.previousElementSibling, json]);
36
- }
37
- function Mount() {
38
- if (mountRequests.length < 1)
39
- return;
40
- if (!global.CLIENT)
41
- throw new Error("Client manifest missing");
42
- for (const [funcName, element, json] of mountRequests) {
43
- console.info("hydrating", funcName, "into", element);
44
- const func = global.CLIENT[funcName];
45
- if (!func)
46
- throw new Error(`Component ${funcName} is missing from client manifest`);
47
- func(element, json);
48
- }
49
- mountRequests.length = 0;
50
- }
51
- document.addEventListener("DOMContentLoaded", Mount);
52
- if (global.htmx)
53
- global.htmx.onLoad(Mount);
54
- // Track the number of active requests
55
- let activeRequests = 0;
56
- const updateLoadingAttribute = () => {
57
- if (activeRequests > 0)
58
- document.body.setAttribute('data-loading', 'true');
59
- else
60
- document.body.removeAttribute('data-loading');
61
- };
62
- const originalXHROpen = XMLHttpRequest.prototype.open;
63
- const originalXHRSend = XMLHttpRequest.prototype.send;
64
- // @ts-ignore
65
- XMLHttpRequest.prototype.open = function (...args) {
66
- this.addEventListener('loadstart', () => {
67
- activeRequests++;
68
- updateLoadingAttribute();
69
- });
70
- this.addEventListener('loadend', () => {
71
- activeRequests--;
72
- updateLoadingAttribute();
73
- });
74
- originalXHROpen.apply(this, args);
75
- };
76
- XMLHttpRequest.prototype.send = function (...args) {
77
- originalXHRSend.apply(this, args);
78
- };
79
- // Override fetch
80
- const originalFetch = window.fetch;
81
- window.fetch = async (...args) => {
82
- activeRequests++;
83
- updateLoadingAttribute();
84
- try {
85
- const response = await originalFetch(...args);
86
- return response;
87
- }
88
- finally {
89
- activeRequests--;
90
- updateLoadingAttribute();
91
- }
92
- };
93
- return {
94
- mountAboveWith: RequestMount,
95
- theme
96
- };
97
- }
98
- ;
99
- const script = "window.Router = (function () {"
100
- + CutString(ClientMounter.toString(), "{")[1]
101
- + ")();";
102
- const hash = QuickHash(script);
103
- export function _resolve(fragments) {
104
- if (!fragments[2])
105
- return null;
106
- // const build = GetSheet();
107
- if (!fragments[2].startsWith(hash))
108
- return null;
109
- const headers = new Headers();
110
- headers.set("Content-Type", "text/javascript");
111
- headers.set("Cache-Control", "public, max-age=604800");
112
- return new Response(script, { headers });
113
- }
114
- export function GetMountUrl() {
115
- return `/_/mount/${hash}.js`;
116
- }
@@ -1 +0,0 @@
1
- export declare function __RebuildClient__(): Promise<void>;
@@ -1,11 +0,0 @@
1
- import { GenerateClient } from "../client/index.js";
2
- import { ReadConfig } from "../cli/config.js";
3
- export async function __RebuildClient__() {
4
- if (process.env.NODE_ENV === "production")
5
- return;
6
- const config = await ReadConfig();
7
- const client = config.client;
8
- if (!client)
9
- return;
10
- GenerateClient(client, false).catch(console.error);
11
- }
package/bin/helper.d.ts DELETED
@@ -1,2 +0,0 @@
1
- export declare function CutString(str: string, pivot: string, offset?: number): [string, string];
2
- export declare function Singleton<T>(name: string, cb: () => T): T;
package/bin/helper.js DELETED
@@ -1,34 +0,0 @@
1
- export function CutString(str, pivot, offset = 1) {
2
- if (offset > 0) {
3
- let cursor = 0;
4
- while (offset !== 0) {
5
- const i = str.indexOf(pivot, cursor);
6
- if (i === -1)
7
- return [str, ""];
8
- cursor = i + 1;
9
- offset--;
10
- }
11
- cursor--;
12
- return [str.slice(0, cursor), str.slice(cursor + pivot.length)];
13
- }
14
- if (offset < 0) {
15
- let cursor = str.length;
16
- while (offset !== 0) {
17
- const i = str.lastIndexOf(pivot, cursor);
18
- if (i === -1)
19
- return [str, ""];
20
- cursor = i - 1;
21
- offset++;
22
- }
23
- cursor++;
24
- return [str.slice(0, cursor), str.slice(cursor + pivot.length)];
25
- }
26
- return [str, ""];
27
- }
28
- export function Singleton(name, cb) {
29
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
30
- const g = globalThis;
31
- g.__singletons ??= {};
32
- g.__singletons[name] ??= cb();
33
- return g.__singletons[name];
34
- }
package/bin/index.d.ts DELETED
@@ -1,11 +0,0 @@
1
- import { RouteModule, CatchFunction, RenderFunction } from './types.js';
2
- import { RouteContext, GenericContext } from "./router.js";
3
- import { createRequestHandler } from './request/index.js';
4
- import { MetaDescriptor, RenderMetaDescriptor, ShellOptions, ApplyMetaDescriptorDefaults, LdJsonObject, OpenGraph, OpenGraphImage, OpenGraphVideo, OpenGraphAudio, InferShellOptions } from './util/shell.js';
5
- import { redirect, refresh, revalidate, text, json } from './util/response.js';
6
- import { Cookies, CookieOptions } from "./util/cookies.js";
7
- import { EventSourceConnection } from "./util/event-source.js";
8
- import { DynamicReference } from './util/dynamic.js';
9
- import { StyleClass } from './util/css.js';
10
- import { Endpoint } from './util/endpoint.js';
11
- export { createRequestHandler, CatchFunction, RenderFunction, RouteContext, RouteModule, GenericContext, Cookies, CookieOptions, Endpoint, DynamicReference, StyleClass, EventSourceConnection, redirect, refresh, revalidate, text, json, MetaDescriptor, RenderMetaDescriptor, ShellOptions, ApplyMetaDescriptorDefaults, LdJsonObject, OpenGraph, OpenGraphImage, OpenGraphVideo, OpenGraphAudio, InferShellOptions };
package/bin/index.js DELETED
@@ -1,18 +0,0 @@
1
- import { RouteContext, GenericContext } from "./router.js";
2
- import { createRequestHandler } from './request/index.js';
3
- import { RenderMetaDescriptor, ApplyMetaDescriptorDefaults } from './util/shell.js';
4
- import { redirect, refresh, revalidate, text, json } from './util/response.js';
5
- import { Cookies } from "./util/cookies.js";
6
- import { EventSourceConnection } from "./util/event-source.js";
7
- import { DynamicReference } from './util/dynamic.js';
8
- import { StyleClass } from './util/css.js';
9
- import { Endpoint } from './util/endpoint.js';
10
- export { createRequestHandler, RouteContext, GenericContext,
11
- // Request helpers
12
- Cookies, Endpoint, DynamicReference,
13
- // CSS Helper
14
- StyleClass,
15
- // SSE helper
16
- EventSourceConnection,
17
- // Response helpers
18
- redirect, refresh, revalidate, text, json, RenderMetaDescriptor, ApplyMetaDescriptorDefaults };
@@ -1,10 +0,0 @@
1
- import type { IncomingMessage, ServerResponse } from "http";
2
- import type { ViteDevServer } from "vite";
3
- import { GenericContext } from "../router.js";
4
- type Config = {
5
- build: Promise<any> | (() => Promise<Record<string, any>>);
6
- viteDevServer: ViteDevServer | null;
7
- render: GenericContext["render"];
8
- };
9
- export declare function createRequestHandler(config: Config): (req: IncomingMessage, res: ServerResponse) => Promise<void>;
10
- export {};
@@ -1,41 +0,0 @@
1
- import { Resolve } from "../request/native.js";
2
- export function createRequestHandler(config) {
3
- return async (req, res) => {
4
- try {
5
- const mod = typeof config.build === "function" ? await config.build() : await config.build;
6
- const request = NativeRequest(req);
7
- let { response, headers } = await Resolve(request, mod.tree, config);
8
- res.writeHead(response.status, headers);
9
- let rendered = await response.text();
10
- res.end(rendered);
11
- }
12
- catch (e) {
13
- res.statusCode = 500;
14
- if (e instanceof Error) {
15
- console.error(e.stack);
16
- config.viteDevServer?.ssrFixStacktrace(e);
17
- res.end(e.stack);
18
- }
19
- else {
20
- console.error(e);
21
- res.end(String(e));
22
- }
23
- }
24
- };
25
- }
26
- function NativeRequest(req) {
27
- const ctrl = new AbortController();
28
- const headers = new Headers(req.headers);
29
- const url = new URL(`http://${headers.get('host')}${req.originalUrl || req.url}`);
30
- req.once('aborted', () => ctrl.abort());
31
- const bodied = req.method !== "GET" && req.method !== "HEAD";
32
- return new Request(url, {
33
- headers,
34
- method: req.method,
35
- body: bodied ? req : undefined,
36
- signal: ctrl.signal,
37
- referrer: headers.get("referrer") || undefined,
38
- // @ts-ignore
39
- duplex: bodied ? 'half' : undefined
40
- });
41
- }
@@ -1,16 +0,0 @@
1
- import type { ViteDevServer } from "vite";
2
- import * as native from "../request/native.js";
3
- import * as http from "../request/http.js";
4
- import { GenericContext, RouteTree } from '../router.js';
5
- export type Config = {
6
- build: Promise<any> | (() => Promise<Record<string, any>>);
7
- viteDevServer: ViteDevServer | null;
8
- render: GenericContext["render"];
9
- };
10
- export type RouterModule = {
11
- tree: RouteTree;
12
- };
13
- export declare const createRequestHandler: {
14
- http: typeof http.createRequestHandler;
15
- native: typeof native.createRequestHandler;
16
- };
@@ -1,6 +0,0 @@
1
- import * as native from "../request/native.js";
2
- import * as http from "../request/http.js";
3
- export const createRequestHandler = {
4
- http: http.createRequestHandler,
5
- native: native.createRequestHandler
6
- };
@@ -1,9 +0,0 @@
1
- import { RouteTree } from '../router.js';
2
- import { Config } from '../request/index.js';
3
- export declare function createRequestHandler(config: Config): (req: Request) => Promise<Response>;
4
- export declare function Resolve(request: Request, tree: RouteTree, config: Config): Promise<{
5
- response: Response;
6
- headers: {
7
- [key: string]: string | string[];
8
- };
9
- }>;
@@ -1,46 +0,0 @@
1
- import { GenericContext } from '../router.js';
2
- export function createRequestHandler(config) {
3
- return async (req) => {
4
- try {
5
- const mod = typeof config.build === "function" ? await config.build() : await config.build;
6
- let { response } = await Resolve(req, mod.tree, config);
7
- return response;
8
- }
9
- catch (e) {
10
- if (e instanceof Error) {
11
- console.error(e.stack);
12
- config.viteDevServer?.ssrFixStacktrace(e);
13
- return new Response(e.message + "\n" + e.stack, { status: 500, statusText: "Internal Server Error" });
14
- }
15
- else {
16
- console.error(e);
17
- return new Response(String(e), { status: 500, statusText: "Internal Server Error" });
18
- }
19
- }
20
- };
21
- }
22
- export async function Resolve(request, tree, config) {
23
- const url = new URL(request.url);
24
- const ctx = new GenericContext(request, url, config.render);
25
- const x = ctx.url.pathname.endsWith("/") ? ctx.url.pathname.slice(0, -1) : ctx.url.pathname;
26
- const fragments = x.split("/").slice(1);
27
- let response = await tree.resolve(fragments, ctx);
28
- if (response === null)
29
- response = new Response("No Route Found", { status: 404, statusText: "Not Found", headers: ctx.headers });
30
- // Override with context headers
31
- if (response.headers !== ctx.headers) {
32
- for (const [key, value] of ctx.headers) {
33
- if (ctx.headers.has(key))
34
- continue;
35
- response.headers.set(key, value);
36
- }
37
- }
38
- // Merge cookie changes
39
- const headers = Object.fromEntries(response.headers);
40
- const cookies = ctx.cookie.export();
41
- if (cookies.length > 0) {
42
- headers['set-cookie'] = cookies;
43
- response.headers.set("Set-Cookie", cookies[0]); // Response object doesn't support multi-header..[]
44
- }
45
- return { response, headers };
46
- }
package/bin/response.d.ts DELETED
@@ -1,9 +0,0 @@
1
- export declare function text(text: string, init?: ResponseInit): Response;
2
- export declare function json(data: unknown, init?: ResponseInit): Response;
3
- export declare function redirect(url: string, init?: ResponseInit & {
4
- client?: boolean;
5
- }): Response;
6
- export declare function revalidate(init?: ResponseInit): Response;
7
- export declare function refresh(init?: ResponseInit & {
8
- client?: boolean;
9
- }): Response;
package/bin/response.js DELETED
@@ -1,46 +0,0 @@
1
- export function text(text, init) {
2
- init ||= {};
3
- init.statusText ||= "ok";
4
- init.status = 200;
5
- const res = new Response(text, init);
6
- res.headers.set("Content-Type", "text/plain");
7
- res.headers.set("X-Caught", "true");
8
- return res;
9
- }
10
- export function json(data, init) {
11
- init ||= {};
12
- init.statusText ||= "ok";
13
- init.status = 200;
14
- const res = new Response(JSON.stringify(data), init);
15
- res.headers.set("Content-Type", "application/json");
16
- res.headers.set("X-Caught", "true");
17
- return res;
18
- }
19
- export function redirect(url, init) {
20
- init ||= {};
21
- init.statusText ||= "Temporary Redirect";
22
- init.status = 307;
23
- const res = new Response("", init);
24
- if (!init?.client)
25
- res.headers.set("Location", url);
26
- res.headers.set("HX-Location", url); // use hx-boost if applicable
27
- return res;
28
- }
29
- export function revalidate(init) {
30
- init ||= {};
31
- init.statusText ||= "ok";
32
- init.status = 200;
33
- const res = new Response("", init);
34
- res.headers.set("HX-Location", "");
35
- return res;
36
- }
37
- export function refresh(init) {
38
- init ||= {};
39
- init.statusText ||= "ok";
40
- init.status = 200;
41
- const res = new Response("", init);
42
- if (!init?.client)
43
- res.headers.set("Refresh", "0"); // fallback
44
- res.headers.set("HX-Refresh", "true");
45
- return res;
46
- }
package/bin/router.d.ts DELETED
@@ -1,49 +0,0 @@
1
- import { Parameterized, ParameterShaper } from './util/parameters.js';
2
- import { RouteModule } from "./types.js";
3
- import { Cookies } from './util/cookies.js';
4
- export declare class GenericContext {
5
- request: Request;
6
- headers: Headers;
7
- cookie: Cookies;
8
- params: {
9
- [key: string]: string;
10
- };
11
- url: URL;
12
- render: (res: JSX.Element) => Response;
13
- constructor(request: GenericContext["request"], url: GenericContext["url"], renderer: GenericContext["render"]);
14
- shape<T extends ParameterShaper>(shape: T): RouteContext<T>;
15
- }
16
- export declare class RouteContext<T extends ParameterShaper> {
17
- request: Request;
18
- headers: Headers;
19
- cookie: Cookies;
20
- params: Parameterized<T>;
21
- url: URL;
22
- render: (res: JSX.Element) => Response;
23
- constructor(base: GenericContext, shape: T);
24
- }
25
- export declare class RouteLeaf {
26
- module: RouteModule<any>;
27
- constructor(module: RouteModule<any>);
28
- resolve(ctx: GenericContext): Promise<Response | null>;
29
- error(ctx: GenericContext, e: unknown): Promise<Response>;
30
- private renderWrapper;
31
- }
32
- export declare class RouteTree {
33
- root: boolean;
34
- nested: Map<string, RouteTree>;
35
- index: RouteLeaf | null;
36
- slug: RouteLeaf | null;
37
- wild: RouteTree | null;
38
- wildCard: string;
39
- constructor(root?: boolean);
40
- ingest(path: string | string[], module: RouteModule<any>): void;
41
- resolve(fragments: string[], ctx: GenericContext): Promise<Response | null>;
42
- private _resolve;
43
- private resolveIndex;
44
- private resolveNext;
45
- private resolveWild;
46
- private resolveSlug;
47
- private resolveNative;
48
- private unwrap;
49
- }