@mapl/web 0.4.1 → 0.5.0

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 (64) hide show
  1. package/README.md +30 -12
  2. package/bun/index.d.ts +3 -10
  3. package/bun/index.js +1 -1
  4. package/compiler/call.d.ts +10 -0
  5. package/compiler/call.js +1 -0
  6. package/compiler/globals.d.ts +34 -0
  7. package/compiler/globals.js +1 -0
  8. package/compiler/router.d.ts +37 -0
  9. package/compiler/router.js +1 -0
  10. package/compiler/state.d.ts +32 -0
  11. package/compiler/state.js +1 -0
  12. package/constants.d.ts +17 -5
  13. package/constants.js +1 -1
  14. package/generic/compiler.d.ts +32 -0
  15. package/generic/compiler.js +1 -0
  16. package/generic/handlers.d.ts +23 -0
  17. package/generic/handlers.js +1 -0
  18. package/generic/index.d.ts +3 -0
  19. package/generic/index.js +1 -0
  20. package/generic/layers.d.ts +6 -0
  21. package/generic/layers.js +1 -0
  22. package/generic/parsers.d.ts +21 -0
  23. package/generic/parsers.js +1 -0
  24. package/generic/route.d.ts +11 -0
  25. package/generic/route.js +1 -0
  26. package/{core/context.d.ts → generic/types.d.ts} +2 -2
  27. package/index.d.ts +7 -23
  28. package/index.js +1 -1
  29. package/package.json +16 -23
  30. package/build/rolldown.d.ts +0 -36
  31. package/build/rolldown.js +0 -15
  32. package/build/utils.d.ts +0 -2
  33. package/build/utils.js +0 -1
  34. package/bun/compiler/aot.d.ts +0 -2
  35. package/bun/compiler/aot.js +0 -1
  36. package/bun/compiler/jit.d.ts +0 -8
  37. package/bun/compiler/jit.js +0 -1
  38. package/bun/compiler/router.d.ts +0 -3
  39. package/bun/compiler/router.js +0 -1
  40. package/compiler/aot.d.ts +0 -6
  41. package/compiler/aot.js +0 -1
  42. package/compiler/jit.d.ts +0 -10
  43. package/compiler/jit.js +0 -1
  44. package/core/handler.d.ts +0 -94
  45. package/core/handler.js +0 -1
  46. package/core/index.d.ts +0 -22
  47. package/core/index.js +0 -1
  48. package/core/middleware.d.ts +0 -38
  49. package/core/middleware.js +0 -1
  50. package/core/utils.d.ts +0 -5
  51. package/core/utils.js +0 -1
  52. package/utils/basic-auth.d.ts +0 -7
  53. package/utils/basic-auth.js +0 -1
  54. package/utils/bearer-auth.d.ts +0 -4
  55. package/utils/bearer-auth.js +0 -1
  56. package/utils/body-limit.d.ts +0 -7
  57. package/utils/body-limit.js +0 -1
  58. package/utils/cors.d.ts +0 -18
  59. package/utils/cors.js +0 -1
  60. package/utils/redirect.d.ts +0 -3
  61. package/utils/redirect.js +0 -1
  62. package/utils/static-headers.d.ts +0 -5
  63. package/utils/static-headers.js +0 -1
  64. /package/{core/context.js → generic/types.js} +0 -0
package/README.md CHANGED
@@ -1,13 +1,31 @@
1
- A compiled web framework for all runtimes.
2
-
3
- ## AOT compilation (experimental)
4
- Build `@mapl/web` to improve startup time.
5
-
6
- ### Rolldown
7
- Try it out using:
8
- ```sh
9
- npm install -g degit
10
- degit github:mapljs/web/examples/generic
11
- # or with Bun
12
- degit github:mapljs/web/examples/bun
1
+ # `@mapl/web`
2
+ A low level, fast and type-safe framework.
3
+
4
+ ```ts
5
+ import { inject, route, router, send } from '@mapl/web';
6
+ import { compiler, request } from '@mapl/web/generic';
7
+
8
+ const app = router(
9
+ [],
10
+ [
11
+ route.get(
12
+ '/',
13
+ send.raw((c) => {
14
+ c.status = 418;
15
+ return 'Hi';
16
+ }),
17
+ ),
18
+ route.post(
19
+ '/body',
20
+ send.json(
21
+ inject([request], async (req) => req.json())
22
+ ),
23
+ ),
24
+ ],
25
+ );
26
+
27
+ export default {
28
+ fetch: compiler.buildSync(app)(),
29
+ };
30
+
13
31
  ```
package/bun/index.d.ts CHANGED
@@ -1,11 +1,4 @@
1
1
  import type { BunRequest, Server } from "bun";
2
- import { type ChildRouters, type InferHandlers, type InferRouter } from "../core/index.js";
3
- import type { MiddlewareTypes } from "../core/middleware.js";
4
- export interface BunContext {
5
- readonly req: BunRequest;
6
- readonly server: Server<any>;
7
- }
8
- export declare const router: <
9
- const T extends MiddlewareTypes<BunContext, any, any>[],
10
- const S extends ChildRouters<BunContext> = {}
11
- >(middlewares: T, handlers: InferHandlers<BunContext, T>, children?: S) => InferRouter<BunContext, T, S>;
2
+ import type { LocalDependency } from "runtime-compiler";
3
+ export declare const request: LocalDependency<BunRequest>;
4
+ export declare const server: LocalDependency<Server<any>>;
package/bun/index.js CHANGED
@@ -1 +1 @@
1
- import{routerImpl}from"../core/index.js";export let router=routerImpl;
1
+ export let request=`mr`;export let server=`mi`;
@@ -0,0 +1,10 @@
1
+ import type { State } from "./state.ts";
2
+ /**
3
+ * Compile a function to call statement.
4
+ * Use in `default` and `build` mode.
5
+ */
6
+ export declare const buildCall: (state: State, fn: (...args: any[]) => any, paramCount: number, params: string) => string;
7
+ /**
8
+ * Hydrate a call.
9
+ */
10
+ export declare const hydrateCall: (state: State, fn: (...args: any[]) => any, paramCount: number) => void;
@@ -0,0 +1 @@
1
+ import{getDeps}from"runtime-compiler/call";import{injectExternalDependency}from"runtime-compiler";import{AsyncFunction}from"runtime-compiler/utils";export let buildCall=(state,fn,paramCount,params)=>{let fnId=injectExternalDependency(fn);if(fn instanceof AsyncFunction){state[0]=true;fnId=`await `+fnId}let deps=getDeps(fn);return deps==null?fn.length>paramCount?(state[1]=true,`${fnId}(${params}mc)`):`${fnId}(${params})`:fn.length>paramCount+deps.length?(state[1]=true,`${fnId}(${deps.join()},${params}mc)`):`${fnId}(${deps.join()},${params})`};export let hydrateCall=(state,fn,paramCount)=>{injectExternalDependency(fn);state[0]||=fn instanceof AsyncFunction;let deps=getDeps(fn);state[1]||=fn.length>(deps==null?paramCount:deps.length+paramCount)};
@@ -0,0 +1,34 @@
1
+ /**
2
+ * @module Global compiler hooks
3
+ */
4
+ import type { Route } from "./router.ts";
5
+ import type { State } from "./state.ts";
6
+ export declare let registerRoute: (route: Route, state: State, prefix: string, content: string) => any;
7
+ /**
8
+ * Set a callback that register routes to a router.
9
+ * Use in `default` and `build` mode.
10
+ */
11
+ export declare const setRegisterRoute: (f: typeof registerRoute) => void;
12
+ export declare let routeParamMap: string[];
13
+ /**
14
+ * Set route param map.
15
+ * Use in `default` and `build` mode.
16
+ *
17
+ * @example
18
+ * setRouteParamMap([
19
+ * '', 'err'
20
+ * ]);
21
+ *
22
+ * routeParamMap[paramCount << 1]; // No context
23
+ * routeParamMap[paramCount << 1 | 1]; // With context
24
+ */
25
+ export declare const setRouteParamMap: (m: string[]) => void;
26
+ export declare let handlerArgs: string;
27
+ /**
28
+ * Set request handler args.
29
+ * Use in `default` and `build` mode.
30
+ *
31
+ * @example
32
+ * setHandlerArgs('(req, env, ctx)');
33
+ */
34
+ export declare const setHandlerArgs: (a: string) => void;
@@ -0,0 +1 @@
1
+ export let registerRoute;export let setRegisterRoute=f=>{registerRoute=f};export let routeParamMap=[];export let setRouteParamMap=m=>{routeParamMap=m};export let handlerArgs;export let setHandlerArgs=a=>{handlerArgs=a};
@@ -0,0 +1,37 @@
1
+ import type { State } from "./state.ts";
2
+ /*
3
+ * From what i've tested closures use 5x more
4
+ * memory than [fn, ...data] and runs slower too
5
+ */
6
+ export type Layer<Data extends any[] = any[]> = [build: (data: any[], state: State) => string, ...Data];
7
+ export type InferPath<Path extends string> = Path extends `${string}*${infer Rest}` ? Rest extends "*" ? [string] : [string, ...InferPath<Rest>] : [];
8
+ export type RouteLayer<Params extends any[]> = [build: (data: any[], state: State, paramCount: number, paramString: string) => string, ...any[]] & {
9
+ _?: Params;
10
+ };
11
+ export type Route = [method: string, path: string, ...layers: RouteLayer<any[]>[]];
12
+ export type RegisterRouteFn = <const Path extends string>(path: Path, ...layers: RouteLayer<InferPath<Path>>[]) => Route;
13
+ export type RegisterRouteWithMethodFn = <const Path extends string>(method: string, path: Path, ...layers: RouteLayer<InferPath<Path>>[]) => Route;
14
+ export type Router = [layers: Layer[], routes: Route[]] | [layers: Layer[], routes: Route[], children: Record<string, Router>];
15
+ /**
16
+ * Run a layer
17
+ */
18
+ export declare const evaluateLayer: (layer: Layer, state: State) => string;
19
+ /**
20
+ * Run a route layer
21
+ */
22
+ export declare const evaluateRouteLayer: (layer: RouteLayer<any[]>, state: State, paramCount: number, params: string) => string;
23
+ // Build implementations
24
+ /**
25
+ * Use in `default` and `build` mode.
26
+ *
27
+ * @example
28
+ * build(router, [false, false] as any, '', '');
29
+ */
30
+ export declare const build: (router: Router, state: State, prefix: string, content: string) => void;
31
+ /**
32
+ * Use in `hydrate` mode.
33
+ *
34
+ * @example
35
+ * build(router, [false, false] as any);
36
+ */
37
+ export declare const hydrate: (router: Router, state: State) => void;
@@ -0,0 +1 @@
1
+ import{countParams}from"@mapl/router/utils";import{registerRoute,routeParamMap}from"./globals.js";export let evaluateLayer=(layer,state)=>layer[0](layer,state);export let evaluateRouteLayer=(layer,state,paramCount,params)=>layer[0](layer,state,paramCount,params);export let build=(router,state,prefix,content)=>{for(let i=0,layers=router[0];i<layers.length;i++)content+=evaluateLayer(layers[i],state);for(let i=0,routes=router[1];i<routes.length;i++){let route=routes[i];let routeState=state.slice();let routeContent=content;for(let j=2,paramCount=countParams(route[1]),params=routeParamMap[paramCount];j<route.length;j++)routeContent+=evaluateRouteLayer(route[j],routeState,paramCount,params);registerRoute(route,routeState,prefix,routeContent)}if(router.length>2){let children=router[2];for(let key in children)build(children[key],state.slice(),key===`/`?prefix:prefix+key,content)}};export let hydrate=(router,state)=>{for(let i=0,layers=router[0];i<layers.length;i++)evaluateLayer(layers[i],state);for(let i=0,routes=router[1];i<routes.length;i++){let route=routes[i];let routeState=state.slice();for(let j=2,paramCount=countParams(route[1]);j<route.length;j++)evaluateRouteLayer(route[j],routeState,paramCount,``)}if(router.length>2){let children=router[2];for(const key in children)hydrate(children[key],state.slice())}};
@@ -0,0 +1,32 @@
1
+ export interface State extends Array<any> {
2
+ /**
3
+ * Whether scope should be async
4
+ */
5
+ 0: boolean;
6
+ /**
7
+ * Whether the scope needs a context object
8
+ */
9
+ 1: boolean;
10
+ /**
11
+ * Fork the current state
12
+ */
13
+ slice: () => this;
14
+ }
15
+ /**
16
+ * Create initial state
17
+ */
18
+ export declare const initState: () => State;
19
+ /**
20
+ * Use in `default` and `build` mode.
21
+ *
22
+ * @example
23
+ * finalizeReturn([true, true], 'return await fn(c);');
24
+ */
25
+ export declare const finalizeReturn: (state: State, content: string) => string;
26
+ /**
27
+ * Use in `default` and `build` mode.
28
+ *
29
+ * @example
30
+ * finalizeFn([true, true], 'return await fn(c);');
31
+ */
32
+ export declare const finalizeFn: (state: State, content: string) => string;
@@ -0,0 +1 @@
1
+ import{injectDependency}from"runtime-compiler";import{handlerArgs}from"./globals.js";export let initState=()=>[false,false];export let finalizeReturn=(state,content)=>state[0]?`return `+injectDependency(`async${handlerArgs}=>{${state[1]?`let mh=[],mc={status:200,headers:mh};`+content:content}}`)+handlerArgs:state[1]?`let mh=[],mc={status:200,headers:mh};`+content:content;export let finalizeFn=(state,content)=>injectDependency(`${state[0]?`async`+handlerArgs:handlerArgs}=>{${state[1]?`let mh=[],mc={status:200,headers:mh};`+content:content}}`);
package/constants.d.ts CHANGED
@@ -1,6 +1,18 @@
1
1
  export * from "@mapl/framework/constants";
2
- export declare const HEADERS: string;
3
- export declare const SERVER_INFO: string;
4
- export declare const BUN_FN_ARGS: string;
5
- export declare const BUN_FN_START: string;
6
- export declare const PARSE_PATH: string;
2
+ export * from "@mapl/router/constants";
3
+ // Additional args
4
+ export declare const CTX = "mc";
5
+ export declare const HEADERS = "mh";
6
+ export declare const PARSED_RESULT = "mt";
7
+ export declare const CREATE_CTX: string;
8
+ // Mapl locals
9
+ export declare const REQ = "mr";
10
+ export declare const INFO = "mi";
11
+ export declare const FULL_URL = "mu";
12
+ export declare const RES_404 = "mnf";
13
+ export declare const JSON_HEADER = "mjh";
14
+ export declare const JSON_OPTION = "mjo";
15
+ export declare const HTML_HEADER = "mhh";
16
+ export declare const HTML_OPTION = "mho";
17
+ // Fast path for injecting mapl symbols
18
+ export declare const DECL_GLOBALS: string;
package/constants.js CHANGED
@@ -1 +1 @@
1
- import{PATH,REQ,URL,PATH_START,PATH_END}from"@mapl/framework/constants";export*from"@mapl/framework/constants";export let HEADERS=`h`;export let SERVER_INFO=`s`;export let BUN_FN_ARGS=`(`+REQ+`,s)`;export let BUN_FN_START=BUN_FN_ARGS+`=>`;export let PARSE_PATH=`let `+URL+`=`+REQ+`.url,`+PATH_START+`=`+URL+`.indexOf("/",12)+1,`+PATH_END+`=`+URL+`.indexOf("?",`+PATH_START+`),`+PATH+`=`+PATH_END+`===-1?`+URL+`.slice(`+PATH_START+`):`+URL+`.slice(`+PATH_START+`,`+PATH_END+`);`;
1
+ export*from"@mapl/framework/constants";export*from"@mapl/router/constants";export let CTX=`mc`;export let HEADERS=`mh`;export let PARSED_RESULT=`mt`;export let CREATE_CTX=`let ${HEADERS}=[],${CTX}={status:200,headers:${HEADERS}};`;export let REQ=`mr`;export let INFO=`mi`;export let FULL_URL=`mu`;export let RES_404=`mnf`;export let JSON_HEADER=`mjh`;export let JSON_OPTION=`mjo`;export let HTML_HEADER=`mhh`;export let HTML_OPTION=`mho`;export let DECL_GLOBALS=`var ${JSON_HEADER}=['content-type','application/json'],${JSON_OPTION}={headers:${JSON_HEADER}},${HTML_HEADER}=['content-type','text/html'],${HTML_OPTION}={headers:${HTML_HEADER}},${RES_404}=new Response(null,{status:404});`;
@@ -0,0 +1,32 @@
1
+ import { type LocalDependency } from "runtime-compiler";
2
+ import { type Router } from "../compiler/router.ts";
3
+ import { type registerRoute } from "../compiler/globals.ts";
4
+ export type BuiltFn = () => (req: Request) => any;
5
+ export declare const registerRouteCb: typeof registerRoute;
6
+ /**
7
+ * Build to a local dependency.
8
+ * Use in `default` and `build` mode.
9
+ */
10
+ export declare const buildToDependency: (router: Router) => LocalDependency<BuiltFn>;
11
+ /**
12
+ * Hydrate to a local dependency.
13
+ * Use in `hydrate` mode.
14
+ */
15
+ export declare const hydrateToDependency: (router: Router) => void;
16
+ /**
17
+ * Build the router into evaluatable string.
18
+ * Use in `build` mode.
19
+ *
20
+ * @example
21
+ * `(${buildToString(app)})(hydrate(app));`
22
+ */
23
+ export declare const buildToString: (router: Router) => string;
24
+ /**
25
+ * Build the router to a lazy function.
26
+ * Use in `default` mode.
27
+ */
28
+ export declare const build: (router: Router) => BuiltFn;
29
+ /**
30
+ * Return the arguments needed in `hydrate` mode.
31
+ */
32
+ export declare const hydrate: (router: Router) => any[];
@@ -0,0 +1 @@
1
+ import{createRouter,insertItem}from"@mapl/router/method";import compileMethodRouter from"@mapl/router/method/compiler";import{addExtraCode,evaluate,evaluateToString,hydrate as finishHydration,injectDependency}from"runtime-compiler";import{build as buildRouter,hydrate as hydrateRouter}from"../compiler/router.js";import{finalizeReturn}from"../compiler/state.js";import{setHandlerArgs,setRegisterRoute,setRouteParamMap}from"../compiler/globals.js";let methodRouter;export let registerRouteCb=(route,state,prefix,content)=>{insertItem(methodRouter,route[0],prefix+route[1],finalizeReturn(state,content))};let buildWrapper=router=>{setHandlerArgs(`(mr)`);methodRouter=createRouter();setRegisterRoute(registerRouteCb);let paramMap=[``,`q0,`];for(let i=1;i<=8;i++)paramMap.push(`${paramMap[i]}q${i},`);setRouteParamMap(paramMap);buildRouter(router,[false,false],``,``);return`()=>{var mjh=['content-type','application/json'],mjo={headers:mjh},mhh=['content-type','text/html'],mho={headers:mhh},mnf=new Response(null,{status:404});return(mr)=>{${compileMethodRouter(methodRouter,`mr.method`,`let mu=mr.url,s=mu.indexOf('/',10)+1,e=mu.indexOf('?',s),p=e===-1?mu.slice(s):mu.slice(s,e);`,1)}return mnf}}`};export let buildToDependency=router=>injectDependency(buildWrapper(router));export let hydrateToDependency=router=>{hydrateRouter(router,[false,false])};export let buildToString=router=>(addExtraCode(`return`+buildWrapper(router)),evaluateToString());export let build=router=>(addExtraCode(`return`+buildWrapper(router)),evaluate());export let hydrate=router=>(hydrateToDependency(router),finishHydration());
@@ -0,0 +1,23 @@
1
+ import type { Context, MaybePromise } from "./types.ts";
2
+ import type { RouteLayer } from "../compiler/router.ts";
3
+ // Send text and streams
4
+ type SendFn<Params extends any[]> = (...args: [...Params, c: Context]) => MaybePromise<BodyInit | null>;
5
+ export declare const sendFn: RouteLayer<any[]>[0];
6
+ /**
7
+ * Send raw content
8
+ */
9
+ export declare const raw: <Params extends any[]>(fn: SendFn<Params>) => RouteLayer<Params>;
10
+ // Send JSON
11
+ type SendJSONFn<Params extends any[]> = (...args: [...Params, c: Context]) => any;
12
+ export declare const sendJSONFn: RouteLayer<any[]>[0];
13
+ /**
14
+ * Send JSON
15
+ */
16
+ export declare const json: <Params extends any[]>(fn: SendJSONFn<Params>) => RouteLayer<Params>;
17
+ // Send HTML
18
+ export declare const sendHTMLFn: RouteLayer<any[]>[0];
19
+ /**
20
+ * Send HTML
21
+ */
22
+ export declare const html: <Params extends any[]>(fn: SendFn<Params>) => RouteLayer<Params>;
23
+ export {};
@@ -0,0 +1 @@
1
+ import{isHydrating}from"runtime-compiler/config";import{buildCall,hydrateCall}from"../compiler/call.js";let onlyHydrateCall=(data,state,paramCount)=>(hydrateCall(state,data[1],paramCount),``);export let sendFn=isHydrating?onlyHydrateCall:(data,state,paramCount,params)=>{let call=buildCall(state,data[1],paramCount,params);return state[1]?`return new Response(${call},mc)`:`return new Response(${call})`};export let raw=fn=>[sendFn,fn];export let sendJSONFn=isHydrating?onlyHydrateCall:(data,state,paramCount,params)=>{let call=buildCall(state,data[1],paramCount,params);return state[1]?`mh.push(mjh);return new Response(${call},mc)`:`return new Response(${call},mjo)`};export let json=fn=>[sendJSONFn,fn];export let sendHTMLFn=isHydrating?onlyHydrateCall:(data,state,paramCount,params)=>{let call=buildCall(state,data[1],paramCount,params);return state[1]?`mh.push(mhh);return new Response(${call},mc)`:`return new Response(${call},mho)`};export let html=fn=>[sendHTMLFn,fn];
@@ -0,0 +1,3 @@
1
+ import type { LocalDependency } from "runtime-compiler";
2
+ export declare const request: LocalDependency<Request>;
3
+ export * as compiler from "./compiler.ts";
@@ -0,0 +1 @@
1
+ export let request=`mr`;export*as compiler from"./compiler.js";
@@ -0,0 +1,6 @@
1
+ import type { Layer } from "../compiler/router.ts";
2
+ import type { Context } from "./types.ts";
3
+ /**
4
+ * Run a function on every request
5
+ */
6
+ export declare const tap: <const Fn extends (c: Context) => any>(fn: Fn) => Layer<[Fn]>;
@@ -0,0 +1 @@
1
+ import{isHydrating}from"runtime-compiler/config";import{buildCall,hydrateCall}from"../compiler/call.js";let buildTap=isHydrating?(data,state)=>(hydrateCall(state,data[1],0),``):(data,state)=>buildCall(state,data[1],0,``)+`;`;export let tap=fn=>[buildTap,fn];
@@ -0,0 +1,21 @@
1
+ import { type InferErr, type InferResult, isErr } from "@safe-std/error";
2
+ import { type LocalDependency } from "runtime-compiler";
3
+ import type { Context } from "./types.ts";
4
+ import { type Layer, type RouteLayer } from "../compiler/router.ts";
5
+ interface ParseLayerFn {
6
+ <const T>(fn: (c: Context) => T, handleError: RouteLayer<[InferErr<Awaited<T>>]>): Layer<[LocalDependency<InferResult<Awaited<T>>>, typeof fn, typeof handleError]>;
7
+ <const T>(fn: (c: Context) => T): Layer<[LocalDependency<Awaited<T>>, typeof fn]>;
8
+ }
9
+ /**
10
+ * Check whether value is an error
11
+ */
12
+ export declare const IS_ERR: LocalDependency<typeof isErr>;
13
+ /**
14
+ * Parse and assign the value to a local variable on every request
15
+ */
16
+ export declare const init: ParseLayerFn;
17
+ /**
18
+ * Get the parsed result of a parser
19
+ */
20
+ export declare const result: <T extends LocalDependency<any>>(parser: Layer<[T, ...any[]]>) => T;
21
+ export {};
@@ -0,0 +1 @@
1
+ import{isErr}from"@safe-std/error";import{injectExternalDependency}from"runtime-compiler";import{isHydrating}from"runtime-compiler/config";import{evaluateRouteLayer}from"../compiler/router.js";import{buildCall,hydrateCall}from"../compiler/call.js";export let IS_ERR=injectExternalDependency(isErr);let buildParse=isHydrating?(data,state)=>(hydrateCall(state,data[2],0),data.length>3?evaluateRouteLayer(data[3],state,1,data[1]):``):(data,state)=>{let id=data[1];return`let ${id}=${buildCall(state,data[2],0,``)};`+(data.length>3?`if(${IS_ERR}(${id})){${evaluateRouteLayer(data[3],state,1,id+`,`)}}`:``)};let tmpId=0;export let init=(fn,handleError)=>handleError==null?[buildParse,`mt`+ tmpId++,fn]:[buildParse,`mt`+ tmpId++,fn,handleError];export let result=parser=>parser[1];
@@ -0,0 +1,11 @@
1
+ import type { RegisterRouteFn, RegisterRouteWithMethodFn } from "../compiler/router.ts";
2
+ export declare const get: RegisterRouteFn;
3
+ export declare const post: RegisterRouteFn;
4
+ export declare const put: RegisterRouteFn;
5
+ export declare const del: RegisterRouteFn;
6
+ export declare const patch: RegisterRouteFn;
7
+ export declare const options: RegisterRouteFn;
8
+ export declare const trace: RegisterRouteFn;
9
+ export declare const query: RegisterRouteFn;
10
+ export declare const any: RegisterRouteFn;
11
+ export declare const def: RegisterRouteWithMethodFn;
@@ -0,0 +1 @@
1
+ let GET=[`GET`];export let get=(...args)=>GET.concat(args);let POST=[`POST`];export let post=(...args)=>POST.concat(args);let PUT=[`PUT`];export let put=(...args)=>PUT.concat(args);let DEL=[`DELETE`];export let del=(...args)=>DEL.concat(args);let PATCH=[`PATCH`];export let patch=(...args)=>PATCH.concat(args);let OPTIONS=[`OPTIONS`];export let options=(...args)=>OPTIONS.concat(args);let TRACE=[`TRACE`];export let trace=(...args)=>TRACE.concat(args);let QUERY=[`QUERY`];export let query=(...args)=>QUERY.concat(args);let ANY=[``];export let any=(...args)=>ANY.concat(args);export let def=(...args)=>args;
@@ -1,6 +1,6 @@
1
1
  export type Header = [string, string] | readonly [string, string];
2
2
  export interface Context {
3
- headers: Header[];
4
3
  status: number;
5
- statusText?: string;
4
+ headers: Header[];
6
5
  }
6
+ export type MaybePromise<T> = T | Promise<T>;
package/index.d.ts CHANGED
@@ -1,23 +1,7 @@
1
- import { type ChildRouters, type InferHandlers, type InferRouter } from "./core/index.js";
2
- import type { MiddlewareTypes } from "./core/middleware.js";
3
- /**
4
- * Generic context
5
- */
6
- export interface GenericContext {
7
- readonly req: Request;
8
- }
9
- /**
10
- * Generic router
11
- */
12
- export declare const router: <
13
- const T extends MiddlewareTypes<GenericContext, any, any>[],
14
- const S extends ChildRouters<GenericContext> = {}
15
- >(middlewares: T, handlers: InferHandlers<GenericContext, T>, children?: S) => InferRouter<GenericContext, T, S>;
16
- export * as layer from "./core/middleware.js";
17
- export * as handle from "./core/handler.js";
18
- export * as cors from "./utils/cors.js";
19
- export * as bearerAuth from "./utils/bearer-auth.js";
20
- export * as basicAuth from "./utils/basic-auth.js";
21
- export * as bodyLimit from "./utils/body-limit.js";
22
- export { default as redirect } from "./utils/redirect.js";
23
- export { default as staticHeaders } from "./utils/static-headers.js";
1
+ import type { Router } from "./compiler/router.ts";
2
+ export * as send from "./generic/handlers.ts";
3
+ export * as route from "./generic/route.ts";
4
+ export * as layer from "./generic/layers.ts";
5
+ export * as parser from "./generic/parsers.ts";
6
+ export { inject } from "runtime-compiler/call";
7
+ export declare const router: (layers: Router[0], routes: Router[1], children?: Router[2]) => Router;
package/index.js CHANGED
@@ -1 +1 @@
1
- import{routerImpl}from"./core/index.js";export let router=routerImpl;export*as layer from"./core/middleware.js";export*as handle from"./core/handler.js";export*as cors from"./utils/cors.js";export*as bearerAuth from"./utils/bearer-auth.js";export*as basicAuth from"./utils/basic-auth.js";export*as bodyLimit from"./utils/body-limit.js";export{default as redirect}from"./utils/redirect.js";export{default as staticHeaders}from"./utils/static-headers.js";
1
+ export*as send from"./generic/handlers.js";export*as route from"./generic/route.js";export*as layer from"./generic/layers.js";export*as parser from"./generic/parsers.js";export{inject}from"runtime-compiler/call";export let router=(layers,routes,children)=>children==null?[layers,routes]:[layers,routes,children];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mapl/web",
3
- "version": "0.4.1",
3
+ "version": "0.5.0",
4
4
  "description": "A compiled web framework for all runtimes",
5
5
  "keywords": ["fast", "lightweight", "cross-runtime", "framework", "web", "backend"],
6
6
  "repository": {
@@ -12,32 +12,25 @@
12
12
  "main": "./index.js",
13
13
  "types": "./index.d.ts",
14
14
  "dependencies": {
15
- "@mapl/framework": "^0.6.3",
16
- "@mapl/router": "^0.6.4",
15
+ "@biomejs/biome": "^2.3.2",
16
+ "@mapl/router": "^0.7.7",
17
17
  "@safe-std/error": "^2.0.4",
18
- "runtime-compiler": "^1.2.7"
18
+ "runtime-compiler": "^2.1.2"
19
19
  },
20
20
  "exports": {
21
- ".": "./index.js",
22
21
  "./constants": "./constants.js",
23
- "./core/utils": "./core/utils.js",
24
- "./core/middleware": "./core/middleware.js",
25
- "./core/context": "./core/context.js",
26
- "./utils/cors": "./utils/cors.js",
27
- "./core/handler": "./core/handler.js",
28
- "./utils/redirect": "./utils/redirect.js",
29
- "./utils/body-limit": "./utils/body-limit.js",
30
- "./utils/bearer-auth": "./utils/bearer-auth.js",
31
- "./utils/static-headers": "./utils/static-headers.js",
32
- "./utils/basic-auth": "./utils/basic-auth.js",
33
- "./bun/compiler/router": "./bun/compiler/router.js",
34
- "./compiler/aot": "./compiler/aot.js",
35
- "./bun/compiler/aot": "./bun/compiler/aot.js",
36
- "./compiler/jit": "./compiler/jit.js",
22
+ "./compiler/call": "./compiler/call.js",
23
+ "./generic": "./generic/index.js",
24
+ "./generic/compiler": "./generic/compiler.js",
25
+ "./generic/handlers": "./generic/handlers.js",
26
+ "./generic/route": "./generic/route.js",
27
+ "./generic/parsers": "./generic/parsers.js",
28
+ "./generic/layers": "./generic/layers.js",
29
+ "./compiler/router": "./compiler/router.js",
30
+ "./compiler/globals": "./compiler/globals.js",
37
31
  "./bun": "./bun/index.js",
38
- "./bun/compiler/jit": "./bun/compiler/jit.js",
39
- "./build/rolldown": "./build/rolldown.js",
40
- "./core": "./core/index.js",
41
- "./build/utils": "./build/utils.js"
32
+ "./compiler/state": "./compiler/state.js",
33
+ ".": "./index.js",
34
+ "./generic/types": "./generic/types.js"
42
35
  }
43
36
  }
@@ -1,36 +0,0 @@
1
- import { type BuildOptions, type OutputOptions, type RolldownWatcher, type RolldownPluginOption } from "rolldown";
2
- export interface MaplBuildOptions extends Omit<BuildOptions, "input" | "output"> {
3
- output?: Omit<OutputOptions, "file" | "dir">;
4
- }
5
- export interface MaplOptions {
6
- /**
7
- * App entry point
8
- */
9
- main: string;
10
- /**
11
- * Output directory
12
- */
13
- outputDir: string;
14
- /**
15
- * Build options
16
- */
17
- build?: MaplBuildOptions;
18
- /**
19
- * Whether to emit asynchronous output
20
- */
21
- asynchronous?: boolean;
22
- /**
23
- * Compiler module to use
24
- */
25
- target?: "bun";
26
- /**
27
- * Hydrate specific options
28
- */
29
- hydrate?: MaplBuildOptions;
30
- }
31
- // Plugins to manipulate imports
32
- export declare const hydrateImportsPlugin: RolldownPluginOption;
33
- export declare const SERVER_ENTRY = "index.js";
34
- export declare const hydrate: (options: MaplOptions) => Promise<void>;
35
- export declare const onceBundled: (watcher: RolldownWatcher) => Promise<void>;
36
- export declare const dev: (options: MaplOptions) => RolldownWatcher | void;
package/build/rolldown.js DELETED
@@ -1,15 +0,0 @@
1
- import{mkdirSync,writeFileSync}from"node:fs";import{build,watch}from"rolldown";import{evaluateToString}from"runtime-compiler/jit";import{resolve}from"node:path";import{EXTERNALS}from"./utils.js";export let hydrateImportsPlugin={name:`mapl-web-hydrate-config-replacer`,resolveId(source){return this.resolve(source===`runtime-compiler/config`?`runtime-compiler/hydrate-config`:source)}};export let SERVER_ENTRY=`index.js`;let mkdirSafe=dir=>{try{mkdirSync(dir,{recursive:true})}catch{}};let getTargetCompilerMod=targetOption=>targetOption==null?`@mapl/web/compiler/`:`@mapl/web/`+targetOption+`/compiler/`;export let hydrate=async options=>{let buildOptions=options.build;let hydrateOptions=options.hydrate;let asyncOption=options.asynchronous;let inputFile=resolve(options.main);let compilerPrefix=getTargetCompilerMod(options.target);let tmpFile;if(buildOptions==null){tmpFile=inputFile;mkdirSafe(options.outputDir)}else{tmpFile=resolve(options.outputDir,`tmp.js`);let outputOptions=buildOptions?.output;let currentExternals=buildOptions?.external;await build({...buildOptions,input:inputFile,output:{...outputOptions,file:tmpFile},external:currentExternals==null?EXTERNALS:typeof currentExternals===`function`?(id,...args)=>EXTERNALS.includes(id)||currentExternals(id,...args):EXTERNALS.concat(currentExternals)})}let appMod=await import(tmpFile);let{compileToExportedDependency}=await import(compilerPrefix+`jit`);let HANDLER=compileToExportedDependency(appMod.default);let outputFile=resolve(options.outputDir,SERVER_ENTRY);writeFileSync(outputFile,`
2
- import app from ${JSON.stringify(tmpFile)};
3
- import hydrateRouter from '${compilerPrefix}aot';
4
- hydrateRouter(app);
5
-
6
- import { hydrate } from 'runtime-compiler/hydrate';
7
- import { getDependency } from 'runtime-compiler';
8
-
9
- ${asyncOption?`await(async`:`(`}${evaluateToString()})(...hydrate());
10
- export default getDependency(${HANDLER});
11
- `);let currentPlugins=hydrateOptions?.plugins;await build({...hydrateOptions,input:outputFile,output:{...hydrateOptions?.output,file:outputFile},plugins:!currentPlugins?hydrateImportsPlugin:Array.isArray(currentPlugins)?[hydrateImportsPlugin].concat(currentPlugins):[hydrateImportsPlugin,currentPlugins]})};let jitContent=(inputFile,options)=>{let asyncOption=options.asynchronous===true;return`
12
- import app from ${JSON.stringify(inputFile)};
13
- import { ${asyncOption?`compileToHandler`:`compileToHandlerSync`} } from '${getTargetCompilerMod(options.target)}jit';
14
- export default ${asyncOption?`await compileToHandler`:`compileToHandlerSync`}(app);
15
- `};export let onceBundled=watcher=>new Promise((res,rej)=>watcher.on(`event`,function f(e){if(e.code===`ERROR`)rej(e.error);else if(e.code===`BUNDLE_END`)res();watcher.off(`event`,f)}));export let dev=options=>{let outputFile=resolve(options.outputDir,SERVER_ENTRY);mkdirSafe(options.outputDir);let content=jitContent(resolve(options.main),options);if(options.build!=null){let buildOptions=options.build;let outputOptions=buildOptions?.output;let tmpFile=resolve(options.outputDir,`tmp.js`);mkdirSafe(options.outputDir);writeFileSync(tmpFile,content);return watch({...buildOptions,input:tmpFile,output:{...outputOptions,file:outputFile}})}writeFileSync(outputFile,content)};
package/build/utils.d.ts DELETED
@@ -1,2 +0,0 @@
1
- // Packages that can be affected by compiling app first
2
- export declare const EXTERNALS: string[];
package/build/utils.js DELETED
@@ -1 +0,0 @@
1
- export let EXTERNALS=[`runtime-compiler`,`runtime-compiler/config`,`@mapl/framework`,`@mapl/web`];
@@ -1,2 +0,0 @@
1
- import aot from "../../compiler/aot.js";
2
- export default aot;
@@ -1 +0,0 @@
1
- import aot from"../../compiler/aot.js";export default aot;
@@ -1,8 +0,0 @@
1
- import type { RouterTag } from "../../core/index.js";
2
- import { type CompiledDependency } from "runtime-compiler";
3
- import type { BunContext } from "../index.js";
4
- import type { Serve } from "bun";
5
- export declare const compileToString: (router: RouterTag<BunContext>) => string;
6
- export declare const compileToExportedDependency: (router: RouterTag<BunContext>) => CompiledDependency<Serve.Routes<any, any>>;
7
- export declare const compileToHandler: (router: RouterTag<BunContext>) => Promise<Serve.Routes<any, any>>;
8
- export declare const compileToHandlerSync: (router: RouterTag<BunContext>) => Serve.Routes<any, any>;
@@ -1 +0,0 @@
1
- import{compileGroup,contextInit,setContextInit,hooks,getParamArgs}from"@mapl/framework";import{countParams}from"@mapl/router/path";import{AsyncFunction,exportDependency,getDependency,injectDependency,injectExternalDependency}from"runtime-compiler";import{evaluate,evaluateSync}from"runtime-compiler/jit";import{compileErrorHandler,compileReturn,RES400}from"../../compiler/jit.js";import{insertRoute,resetRouter,routerToString}from"./router.js";let compileToState=router=>{resetRouter();hooks.compileHandler=(handler,prevContent,path,scope)=>{let fn=handler[2];let paramCount=countParams(handler[1]);let call=injectExternalDependency(fn)+`(`+getParamArgs(paramCount);if(fn.length>paramCount){call+=`c`;if(!scope[1]){insertRoute(handler[0],path,prevContent+contextInit+compileReturn(handler[3],fn instanceof AsyncFunction,scope[0],true,call+`)`)+(scope[0]?`})()`:``));return}}insertRoute(handler[0],path,prevContent+compileReturn(handler[3],fn instanceof AsyncFunction,scope[0],scope[1],call+`)`)+(scope[0]?`})()`:``))};hooks.compileErrorHandler=compileErrorHandler;setContextInit(`let h=[],c={status:200,req:r,headers:h,server:s};`);compileGroup(router,[false,false,,`return `+RES400(),false],``,``)};export let compileToString=router=>{compileToState(router);return routerToString()};export let compileToExportedDependency=router=>exportDependency(injectDependency(compileToString(router)));export let compileToHandler=async router=>{let id=compileToExportedDependency(router);await evaluate();return getDependency(id)};export let compileToHandlerSync=router=>{let id=compileToExportedDependency(router);evaluateSync();return getDependency(id)};
@@ -1,3 +0,0 @@
1
- export declare const resetRouter: () => void;
2
- export declare const insertRoute: (method: string, path: string, content: string) => void;
3
- export declare const routerToString: () => string;
@@ -1 +0,0 @@
1
- import{injectDependency}from"runtime-compiler";import{RES404}from"../../compiler/jit.js";let ROUTES;export let resetRouter=()=>{ROUTES={}};export let insertRoute=(method,path,content)=>{let isWildcard=path.endsWith(`**`);let i=0;let bunPattern=isWildcard?path.slice(-2).replace(/\*/g,()=>`:q`+ i++)+`*`:path.replace(/\*/g,()=>`:q`+ i++);let str=`(r,s)=>{`;if(i>0){str+=`let {q0`;for(let j=1,l=i-(isWildcard?1:0);j<l;j++)str+=`q,`+j;str+=`}=r.params`+(isWildcard?`,q`+i+`=r.params["*"];`:`;`)}(ROUTES[bunPattern]??={})[method]=str+content+`}`;if(method!==``&&method!==`GET`&&method!==`HEAD`&&method!==`OPTIONS`&&method!==`DELETE`&&method!==`PATCH`&&method!==`POST`&&method!==`PUT`)ROUTES[bunPattern][``]??=RES404();if(isWildcard)(ROUTES[bunPattern===`/*`?`/`:bunPattern.slice(0,-3)]??={})[method]??=RES404()};export let routerToString=()=>{let str=`{`;for(let pattern in ROUTES){str+=`"`+pattern+`":`;let methods=ROUTES[pattern];let allMethods=methods[``];if(allMethods==null){str+=`{`;for(let method in methods)str+=method+`:`+methods[method]+`,`;str+=`},`}else if(Object.keys(methods).length===1)str+=methods[``]+`,`;else{str+=`(r,s)=>`;for(let method in methods)if(method!==``){let fn=methods[method];str+=`r.method==="`+method+`"?`+(fn.startsWith(`(r,s)=>`)?injectDependency(fn)+`(r,s)`:fn)+`:`}str+=(allMethods.startsWith(`(r,s)=>`)?injectDependency(allMethods)+`(r,s)`:allMethods)+`,`}}return str+`}`};
package/compiler/aot.d.ts DELETED
@@ -1,6 +0,0 @@
1
- import type { RouterTag } from "../core/index.js";
2
- import "../core/context.js";
3
- import type { GenericContext } from "../index.js";
4
- export declare const hydrateRouter: (router: RouterTag<GenericContext>) => void;
5
- declare const _default: (router: RouterTag<GenericContext>) => void;
6
- export default _default;
package/compiler/aot.js DELETED
@@ -1 +0,0 @@
1
- import{hydrateDependency,hooks}from"@mapl/framework";import{countParams}from"@mapl/router/path";import{injectExternalDependency,markExported}from"runtime-compiler";import"../core/context.js";export let hydrateRouter=router=>{hooks.compileHandler=(handler,_,_1,scope)=>{let fn=handler[2];injectExternalDependency(fn);handler[3]?.handler?.(``,scope[1]||fn.length>countParams(handler[1]))};hooks.compileErrorHandler=(_,fn,dat,scope)=>{injectExternalDependency(fn);dat?.handler?.(``,scope[1]||fn.length>1);return``};hydrateDependency(router,[false,false,,``,false],``)};export default router=>{hydrateRouter(router);markExported()};
package/compiler/jit.d.ts DELETED
@@ -1,10 +0,0 @@
1
- import type { RouterTag } from "../core/index.js";
2
- import { type CompiledDependency } from "runtime-compiler";
3
- import type { FetchFn } from "../core/utils.js";
4
- import type { GenericContext } from "../index.js";
5
- export declare const RES404: () => string;
6
- export declare const RES400: () => string;
7
- export declare const compileToString: (router: RouterTag<GenericContext>) => string;
8
- export declare const compileToExportedDependency: (router: RouterTag<GenericContext>) => CompiledDependency<FetchFn>;
9
- export declare const compileToHandler: (router: RouterTag<GenericContext>) => Promise<FetchFn>;
10
- export declare const compileToHandlerSync: (router: RouterTag<GenericContext>) => FetchFn;
package/compiler/jit.js DELETED
@@ -1 +0,0 @@
1
- import{compileGroup,contextInit,setContextInit,hooks,getParamArgs}from"@mapl/framework";import compile from"@mapl/router/method/compiler";import{countParams}from"@mapl/router/path";import{insertItem}from"@mapl/router/method";import{AsyncFunction,exportDependency,getDependency,injectDependency,injectExternalDependency,lazyDependency,noOp}from"runtime-compiler";import{evaluate,evaluateSync}from"runtime-compiler/jit";import{isHydrating}from"runtime-compiler/config";let URL_ROUTER;export let RES404=isHydrating?noOp:lazyDependency(injectDependency,`new Response(null,{status:404})`);export let RES400=isHydrating?noOp:lazyDependency(injectDependency,`new Response(null,{status:400})`);export let compileReturn=(dat,fnAsync,scopeAsync,contextCreated,result)=>{let res=dat?.handler;if(res==null)return`return `+result;let str=res(fnAsync?`await `+result:result,contextCreated);return fnAsync&&!scopeAsync?`return (async()=>{`+str+`})()`:str};export let compileErrorHandler=(input,fn,dat,scope)=>{let call=injectExternalDependency(fn)+`(`+input;if(fn.length>1){call+=`,c`;if(!scope[1])return contextInit+compileReturn(dat,fn instanceof AsyncFunction,scope[0],true,call+`)`)}return compileReturn(dat,fn instanceof AsyncFunction,scope[0],scope[1],call+`)`)};let compileToState=router=>{URL_ROUTER={};hooks.compileHandler=(handler,prevContent,path,scope)=>{let fn=handler[2];let paramCount=countParams(handler[1]);let call=injectExternalDependency(fn)+`(`+getParamArgs(paramCount);if(fn.length>paramCount){call+=`c`;if(!scope[1]){insertItem(URL_ROUTER,handler[0],path,prevContent+contextInit+compileReturn(handler[3],fn instanceof AsyncFunction,scope[0],true,call+`)`)+(scope[0]?`})()`:``));return}}insertItem(URL_ROUTER,handler[0],path,prevContent+compileReturn(handler[3],fn instanceof AsyncFunction,scope[0],scope[1],call+`)`)+(scope[0]?`})()`:``))};hooks.compileErrorHandler=compileErrorHandler;setContextInit(`let h=[],c={status:200,req:r,headers:h};`);compileGroup(router,[false,false,,`return `+RES400(),false],``,``)};export let compileToString=router=>{compileToState(router);return`(r)=>{`+compile(URL_ROUTER,`r.method`,`let u=r.url,s=u.indexOf("/",12)+1,e=u.indexOf("?",s),p=e===-1?u.slice(s):u.slice(s,e);`,1)+`return `+RES404()+`}`};export let compileToExportedDependency=router=>exportDependency(injectDependency(compileToString(router)));export let compileToHandler=async router=>{let id=compileToExportedDependency(router);await evaluate();return getDependency(id)};export let compileToHandlerSync=router=>{let id=compileToExportedDependency(router);evaluateSync();return getDependency(id)};
package/core/handler.d.ts DELETED
@@ -1,94 +0,0 @@
1
- import type { AnyErr } from "@safe-std/error";
2
- import type { Context } from "./context.js";
3
- import type { RouterTag } from "./index.js";
4
- import type { MaybePromise, RequestMethod } from "./utils.js";
5
- export interface HandlerResponse<I = any> {
6
- (response: string, hasContext: boolean): string;
7
- (response: string, hasContext: boolean, _: I): string;
8
- }
9
- export interface HandlerData extends Record<symbol, any> {
10
- handler?: HandlerResponse;
11
- }
12
- export type Handler<
13
- Params extends string[] = string[],
14
- T extends {} = Record<string, any>,
15
- R = any
16
- > = (...args: [...params: Params, c: Context & T]) => R;
17
- export type InferPath<T extends string> = T extends `${string}*${infer Next}` ? Next extends "*" ? [string] : [string, ...InferPath<Next>] : [];
18
- // toResponse macro
19
- export type InferReturn<D extends HandlerData | undefined> = MaybePromise<D extends HandlerData ? D["handler"] extends HandlerResponse<infer I> ? I : Response : Response>;
20
- export type InferHandler<
21
- P extends string,
22
- D extends HandlerData | undefined,
23
- C
24
- > = Handler<InferPath<P>, Required<C>, InferReturn<D>>;
25
- export interface DefineHandler {
26
- <
27
- P extends string,
28
- const D extends HandlerData,
29
- C
30
- >(path: P, handler: NoInfer<InferHandler<P, D, C>>, dat: D): HandlerTag<C>;
31
- <
32
- P extends string,
33
- C
34
- >(path: P, handler: NoInfer<InferHandler<P, undefined, C>>): HandlerTag<C>;
35
- }
36
- // Unique tags
37
- declare const handlerTag: unique symbol;
38
- export interface HandlerTag<out T> {
39
- [handlerTag]: T;
40
- }
41
- export declare const JSON_HEADER: () => string;
42
- export declare const JSON_OPTIONS: () => string;
43
- /**
44
- * Return JSON
45
- */
46
- export declare const json: HandlerResponse;
47
- export declare const HTML_HEADER: () => string;
48
- export declare const HTML_OPTIONS: () => string;
49
- /**
50
- * Return HTML
51
- */
52
- export declare const html: HandlerResponse<BodyInit>;
53
- /**
54
- * Return a body init
55
- */
56
- export declare const text: HandlerResponse<BodyInit>;
57
- /**
58
- * Handle errors of a router
59
- * @param f
60
- */
61
- export declare const error: <
62
- C,
63
- const E extends AnyErr,
64
- const D extends HandlerData | undefined = undefined
65
- >(r: RouterTag<C, E>, f: NoInfer<(err: E, c: Context & C) => InferReturn<D>>, dat?: D) => RouterTag<C, never>;
66
- /**
67
- * Handle requests to a path with a specific method
68
- * @param method
69
- * @param path
70
- * @param handler
71
- * @param dat
72
- */
73
- export declare const route: <
74
- P extends string,
75
- const D extends HandlerData | undefined = undefined,
76
- C = {}
77
- >(method: RequestMethod, path: P, handler: NoInfer<InferHandler<P, D, C>>, dat?: D) => HandlerTag<C>;
78
- // @ts-ignore
79
- export declare const any: DefineHandler;
80
- // @ts-ignore
81
- export declare const get: DefineHandler;
82
- // @ts-ignore
83
- export declare const post: DefineHandler;
84
- // @ts-ignore
85
- export declare const put: DefineHandler;
86
- // @ts-ignore
87
- export declare const del: DefineHandler;
88
- // @ts-ignore
89
- export declare const patch: DefineHandler;
90
- // @ts-ignore
91
- export declare const options: DefineHandler;
92
- // @ts-ignore
93
- export declare const trace: DefineHandler;
94
- export {};
package/core/handler.js DELETED
@@ -1 +0,0 @@
1
- import{isHydrating}from"runtime-compiler/config";import{injectDependency,lazyDependency,noOp}from"runtime-compiler";export let JSON_HEADER=isHydrating?noOp:lazyDependency(injectDependency,`["content-type","application/json"]`);export let JSON_OPTIONS=isHydrating?noOp:lazyDependency(injectDependency,`{headers:[`+JSON_HEADER()+`]}`);export let json=isHydrating?noOp:(res,hasContext)=>hasContext?`h.push(`+JSON_HEADER()+`);return new Response(JSON.stringify(`+res+`),c)`:`return new Response(JSON.stringify(`+res+`),`+JSON_OPTIONS()+`)`;export let HTML_HEADER=isHydrating?noOp:lazyDependency(injectDependency,`["content-type","application/json"]`);export let HTML_OPTIONS=isHydrating?noOp:lazyDependency(injectDependency,`{headers:[`+JSON_HEADER()+`]}`);export let html=isHydrating?noOp:(res,hasContext)=>hasContext?`h.push(`+HTML_HEADER()+`);return new Response(`+res+`,c)`:`return new Response(`+res+`,`+HTML_OPTIONS()+`)`;export let text=isHydrating?noOp:(res,hasContext)=>`return new Response(`+res+(hasContext?`,c)`:`)`);export let error=(r,f,dat)=>{r[2]=[f,dat];return r};export let route=(method,path,handler,dat)=>[method,path,handler,dat];export let any=(path,handler,dat)=>[``,path,handler,dat];export let get=(path,handler,dat)=>[`GET`,path,handler,dat];export let post=(path,handler,dat)=>[`POST`,path,handler,dat];export let put=(path,handler,dat)=>[`PUT`,path,handler,dat];export let del=(path,handler,dat)=>[`DELETE`,path,handler,dat];export let patch=(path,handler,dat)=>[`PATCH`,path,handler,dat];export let options=(path,handler,dat)=>[`OPTIONS`,path,handler,dat];export let trace=(path,handler,dat)=>[`TRACE`,path,handler,dat];
package/core/index.d.ts DELETED
@@ -1,22 +0,0 @@
1
- import type { HandlerTag } from "./handler.js";
2
- import type { AnyMiddlewareTypes, InferMiddlewareState, InferMiddlewareErr } from "./middleware.js";
3
- import type { UnionToIntersection } from "./utils.js";
4
- declare const _: unique symbol;
5
- export interface RouterTag<
6
- out C,
7
- out E = any
8
- > {
9
- [_]: [E, C];
10
- }
11
- export type ChildRouters<C> = Record<string, RouterTag<C, any>>;
12
- export type InferHandlers<
13
- C,
14
- T extends AnyMiddlewareTypes[]
15
- > = HandlerTag<T extends [] ? C : C & UnionToIntersection<InferMiddlewareState<T[number]>>>[];
16
- export type InferRouterErr<T extends RouterTag<any>> = T[typeof _][0];
17
- export type InferRouter<
18
- C,
19
- T extends AnyMiddlewareTypes[],
20
- S extends ChildRouters<C>
21
- > = RouterTag<C, InferRouterErr<S[keyof S]> | InferMiddlewareErr<T[number]>>;
22
- export {};
package/core/index.js DELETED
@@ -1 +0,0 @@
1
- export let routerImpl=(middlewares,handlers,children)=>[middlewares,handlers,,children];
@@ -1,38 +0,0 @@
1
- import type { ScopeState } from "@mapl/framework";
2
- import type { AwaitedReturn } from "./utils.js";
3
- import type { Context } from "./context.js";
4
- import type { InferErr, InferResult } from "@safe-std/error";
5
- declare const _: unique symbol;
6
- export interface MiddlewareTypes<
7
- out Context,
8
- out Err,
9
- in out State
10
- > {
11
- [_]: [Context, Err, State];
12
- }
13
- export type AnyMiddlewareTypes = MiddlewareTypes<any, any, any>;
14
- export type InferMiddlewareState<T extends AnyMiddlewareTypes> = T[typeof _][2];
15
- export type InferMiddlewareErr<T extends AnyMiddlewareTypes> = T[typeof _][1];
16
- export type MiddlewareHandler<C> = (c: Context & C) => any;
17
- export declare const macro: <
18
- C,
19
- E = never,
20
- S = {}
21
- >(f: (scope: ScopeState) => string) => MiddlewareTypes<C, E, S>;
22
- export declare const noOpMacro: MiddlewareTypes<any, never, {}>;
23
- export declare const tap: <C>(f: MiddlewareHandler<C>) => MiddlewareTypes<C, never, {}>;
24
- export declare const attach: <
25
- C,
26
- Prop extends string,
27
- const T extends MiddlewareHandler<C>
28
- >(prop: Prop, f: T) => MiddlewareTypes<C, never, Record<Prop, AwaitedReturn<T>>>;
29
- export declare const validate: <
30
- C,
31
- const T extends MiddlewareHandler<C>
32
- >(f: T) => MiddlewareTypes<C, InferErr<AwaitedReturn<T>>, {}>;
33
- export declare const parse: <
34
- C,
35
- Prop extends string,
36
- const T extends MiddlewareHandler<C>
37
- >(prop: Prop, f: T) => MiddlewareTypes<C, InferErr<AwaitedReturn<T>>, Record<Prop, InferResult<AwaitedReturn<T>>>>;
38
- export {};
@@ -1 +0,0 @@
1
- import{noOp}from"runtime-compiler";export let macro=f=>[-1,f];export let noOpMacro=macro(noOp);export let tap=f=>[0,f];export let attach=(prop,f)=>[1,f,prop];export let validate=f=>[2,f];export let parse=(prop,f)=>[3,f,prop];
package/core/utils.d.ts DELETED
@@ -1,5 +0,0 @@
1
- export type UnionToIntersection<U> = (U extends any ? (x: U) => void : never) extends (x: infer I) => void ? I : never;
2
- export type AwaitedReturn<U extends (...a: any[]) => any> = Awaited<ReturnType<U>>;
3
- export type MaybePromise<T> = Promise<T> | T;
4
- export type RequestMethod = "GET" | "POST" | "PUT" | "DELETE" | "PATCH" | "OPTIONS" | "TRACE" | (string & {});
5
- export type FetchFn = (req: Request) => any;
package/core/utils.js DELETED
@@ -1 +0,0 @@
1
- export{};
@@ -1,7 +0,0 @@
1
- import type { Header } from "../core/context.js";
2
- export declare const extract: (req: Request) => {
3
- name: string;
4
- pwd: string;
5
- } | undefined;
6
- export declare const realm: (val: string) => Header;
7
- export declare const error: (val: string) => Header;
@@ -1 +0,0 @@
1
- export let extract=req=>{let header=req.headers.get(`authorization`);if(header?.startsWith(`Basic `))try{let sliced=atob(header.slice(6));let sep=sliced.indexOf(`:`);if(sep>-1)return{name:sliced.slice(0,sep),pwd:sliced.slice(sep+1)}}catch{}};export let realm=val=>[`www-authenticate`,`Basic realm=`+JSON.stringify(val)];export let error=val=>[`www-authenticate`,`Basic error=`+JSON.stringify(val)];
@@ -1,4 +0,0 @@
1
- import type { Header } from "../core/context.js";
2
- export declare const extract: (req: Request) => string | undefined;
3
- export declare const realm: (val: string) => Header;
4
- export declare const error: (val: string) => Header;
@@ -1 +0,0 @@
1
- export let extract=req=>{let header=req.headers.get(`authorization`);if(header?.startsWith(`Bearer `))return header.slice(7)};export let realm=val=>[`www-authenticate`,`Basic realm=`+JSON.stringify(val)];export let error=val=>[`www-authenticate`,`Basic error=`+JSON.stringify(val)];
@@ -1,7 +0,0 @@
1
- import { type MiddlewareTypes } from "../core/middleware.js";
2
- export declare const RES413: () => string;
3
- /**
4
- * Set size limit for body.
5
- * If you use Bun, use their `maxRequestBodySize` option instead.
6
- */
7
- export declare const size: (bytes: number) => MiddlewareTypes<any, never, {}>;
@@ -1 +0,0 @@
1
- import{macro}from"../core/middleware.js";import{injectDependency,lazyDependency,noOp}from"runtime-compiler";import{isHydrating}from"runtime-compiler/config";import{createAsyncScope}from"@mapl/framework";export let RES413=isHydrating?noOp:lazyDependency(injectDependency,`new Response(null,{status:413})`);export let size=isHydrating?()=>macro(createAsyncScope):bytes=>macro(scope=>createAsyncScope(scope)+`if(await `+injectDependency(`async(r)=>{if(r.body!==null){let l=r.headers.get("content-length");if(l===null||r.headers.has("transfer-encoding")){let g=r.clone().body.getReader(),i=await g.read(),s=0;while(!i.done){s+=i.value.byteLength;if(s>`+bytes+`)return true;i=await g.read()}}else if(+l>`+bytes+`)return true}return false}`)+`(r))return `+RES413()+`;`);
package/utils/cors.d.ts DELETED
@@ -1,18 +0,0 @@
1
- import { type MiddlewareTypes } from "../core/middleware.js";
2
- import type { RequestMethod } from "../core/utils.js";
3
- import type { Header } from "../core/context.js";
4
- // Ensure people don't make mistake categorizing headers
5
- declare const _: unique symbol;
6
- export type CORSHeader = Header & {
7
- [_]: 0;
8
- };
9
- export type CORSPreflightHeader = Header & {
10
- [_]: 1;
11
- };
12
- export declare const allowMethods: (v: [RequestMethod, RequestMethod, ...RequestMethod[]] | RequestMethod | "*") => CORSPreflightHeader;
13
- export declare const allowHeaders: (v: string[] | string) => CORSPreflightHeader;
14
- export declare const maxAge: (v: number) => CORSPreflightHeader;
15
- export declare const allowCredentials: CORSHeader;
16
- export declare const exposeHeaders: (v: "*" | (string & {}) | [string, string, ...string[]]) => CORSHeader;
17
- export declare const init: (origins: "*" | (string & {}) | [string, string, ...string[]], preflightHeaders?: CORSPreflightHeader[], headers?: Header[]) => MiddlewareTypes<any, never, {}>;
18
- export {};
package/utils/cors.js DELETED
@@ -1 +0,0 @@
1
- import{injectDependency}from"runtime-compiler";import{isHydrating}from"runtime-compiler/config";import{createContext}from"@mapl/framework";import{macro}from"../core/middleware.js";import{injectList}from"./static-headers.js";export let allowMethods=v=>[`access-control-allow-methods`,``+v];export let allowHeaders=v=>[`access-control-allow-headers`,``+v];export let maxAge=v=>[`access-control-max-age`,``+v];export let allowCredentials=[`access-control-allow-credentials`,`true`];export let exposeHeaders=v=>[`access-control-expose-headers`,``+v];let createContextMacro=macro(createContext);export let init=isHydrating?()=>createContextMacro:(origins,preflightHeaders=[],headers=[])=>{if(origins!==`*`){headers.push([`vary`,`origin`]);if(Array.isArray(origins))return macro(scope=>{let str=`(r,h)=>{let o=r.headers.get("origin");h.push(["access-control-allow-origin",typeof o==="string"&&o===`+JSON.stringify(origins[1]);for(let i=2;i<origins.length;i++)str+=`||o===`+JSON.stringify(origins[i]);return createContext(scope)+(injectDependency(str+`?o:`+JSON.stringify(origins[0])+`]);`+(headers.length>0?`h.push(`+injectList(headers)+`);`:``)+(preflightHeaders.length>0?`r.method==="OPTIONS"&&h.push(`+injectList(preflightHeaders)+`)}`:`}`))+`(r,h);`)})}headers.push([`access-control-allow-origin`,origins]);return macro(scope=>{let pushHeaders=headers.length>0?`h.push(`+injectList(headers)+`);`:``;return createContext(scope)+(preflightHeaders.length>0?injectDependency(`(r,h)=>{`+pushHeaders+`r.method==="OPTIONS"&&h.push(`+injectList(preflightHeaders)+`)}`)+`(r,h);`:pushHeaders)})};
@@ -1,3 +0,0 @@
1
- import type { Context } from "../core/context.js";
2
- declare const _default: (c: Context, location: string, status: 301 | 302 | 307 | 308) => void;
3
- export default _default;
package/utils/redirect.js DELETED
@@ -1 +0,0 @@
1
- export default (c,location,status)=>{c.status=status;c.headers.push([`location`,location])};
@@ -1,5 +0,0 @@
1
- import type { Header } from "../core/context.js";
2
- import { type MiddlewareTypes } from "../core/middleware.js";
3
- export declare const injectList: (list: any[]) => string;
4
- declare const _default: (headers: Headers | Header[] | Record<string, any>) => MiddlewareTypes<any, never, {}>;
5
- export default _default;
@@ -1 +0,0 @@
1
- import{isHydrating}from"runtime-compiler/config";import{injectDependency}from"runtime-compiler";import{macro,noOpMacro}from"../core/middleware.js";export let injectList=list=>list.length!==1?`...`+injectDependency(JSON.stringify(list)):injectDependency(JSON.stringify(list[0]));export default isHydrating?()=>noOpMacro:headers=>macro(()=>`h.push(`+injectList(Array.isArray(headers)?headers:headers instanceof Headers?headers.entries().toArray():Object.entries(headers))+`);`);
File without changes