@mapl/web 0.0.8 → 0.1.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.
package/README.md CHANGED
@@ -1 +1,16 @@
1
- A fast Web Standard framework.
1
+ # `@mapl/web`
2
+ A compiled web framework for all runtimes.
3
+
4
+ ```ts
5
+ import { router, layer, compile } from '@mapl/web';
6
+
7
+ const app = router.init([
8
+ layer.attach('id', () => performance.now())
9
+ ], [
10
+ router.on('GET', '/path', (c) => c.id)
11
+ ]);
12
+
13
+ export default {
14
+ fetch: compile(app)
15
+ };
16
+ ```
package/constants.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export * from '@mapl/framework/constants';
1
+ export * from "@mapl/framework/constants.js";
2
2
  export declare const WEB: string;
3
3
  export declare const CTX_FN: string;
4
4
  export declare const CTX_INIT: string;
package/constants.js CHANGED
@@ -1 +1 @@
1
- import{MAPL,HEADERS,CTX,PATH,REQ,URL,PATH_START,PATH_END}from"@mapl/framework/constants";export*from"@mapl/framework/constants";export let WEB=MAPL+"w";export let CTX_FN=WEB+"c";export let CTX_INIT="let "+HEADERS+"=[],"+CTX+"="+CTX_FN+"("+REQ+","+HEADERS+");";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+".substring("+PATH_START+","+PATH_END+");";export let CHTML=WEB+"h";export let CJSON=WEB+"j";export let R404=WEB+"n";export let R400=WEB+"b";export let GLOBALS="let ["+CHTML+","+CJSON+']=["text/html","application/json"].map(c=>["content-type",c]),['+R404+","+R400+"]=[404,400].map(s=>new Response(null,{status:s}));";
1
+ import{MAPL,HEADERS,CTX,PATH,REQ,URL,PATH_START,PATH_END}from"@mapl/framework/constants.js";export*from"@mapl/framework/constants.js";export let WEB=MAPL+`w`;export let CTX_FN=WEB+`c`;export let CTX_INIT=`let `+HEADERS+`=[],`+CTX+`=`+CTX_FN+`(`+REQ+`,`+HEADERS+`);`;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+`.substring(`+PATH_START+`,`+PATH_END+`);`;export let CHTML=WEB+`h`;export let CJSON=WEB+`j`;export let R404=WEB+`n`;export let R400=WEB+`b`;export let GLOBALS=`let [`+CHTML+`,`+CJSON+`]=["text/html","application/json"].map(c=>["content-type",c]),[`+R404+`,`+R400+`]=[404,400].map(s=>new Response(null,{status:s}));`;
@@ -0,0 +1,3 @@
1
+ import type { AnyRouter } from "./index.js";
2
+ declare const _default: (router: AnyRouter) => ((req: Request) => any);
3
+ export default _default;
@@ -0,0 +1 @@
1
+ import{compileGroup,createArgSet,isFuncAsync}from"@mapl/framework";import{o2}from"@mapl/router/tree/compiler.js";import compile from"@mapl/router/method/compiler.js";import{countParams}from"@mapl/router/path/index.js";import{isErr}from"safe-throw";import createContext from"./context.js";let paramArgs=createArgSet(new Array(16).fill(0).map((_1,i)=>`q`+i));let compileReturn=(state,dat,fnAsync,scopeAsync,contextCreated,result)=>{let typ=dat.type;if(typ===`raw`)return`return `+result;if(fnAsync)result=`await `+result;let str=typ==null?`return new Response(`+result+(contextCreated?`,c)`:`)`):(contextCreated?``:state[2])+`mh.push(`+(typ===`json`?`mwj`:`mwh`)+`);return new Response(`+(typ===`json`?`JSON.stringify(`+result+`)`:result)+`,c)`;return fnAsync&&!scopeAsync?`return (async()=>{`+str+`})()`:scopeAsync?str+`})()`:str};export default router=>{let baseRouter={};let dependencies=[];compileGroup(router,[baseRouter,dependencies,`let mh=[],c=mwc(r,mh);`,(fn,dat,path,state,scope)=>{let call=`f`+state[1].push(fn)+`(`;let paramCount=countParams(path);if(paramCount>0)call+=paramArgs[paramCount];if(fn.length>paramCount){call+=paramCount===0?`c`:`,c`;if(!scope[1])return state[2]+compileReturn(state,dat,isFuncAsync(fn),scope[0],true,call+`)`)}return compileReturn(state,dat,isFuncAsync(fn),scope[0],scope[1],call+`)`)},(fn,dat,state,scope)=>{let call=`f`+state[1].push(fn)+`(t`;if(fn.length>1){call+=`,c`;if(!scope[1])return state[2]+compileReturn(state,dat,isFuncAsync(fn),scope[0],true,call+`)`)}return compileReturn(state,dat,isFuncAsync(fn),scope[0],scope[1],call+`)`)}],[false,false,null,`return mwb`],``,``);return Function(`me`,`mwc`,...dependencies.map((_,i)=>`f`+(i+1)),`let [mwh,mwj]=["text/html","application/json"].map(c=>["content-type",c]),[mwn,mwb]=[404,400].map(s=>new Response(null,{status:s}));return(r)=>{`+compile(baseRouter,o2,`r.method`,`let u=r.url,s=u.indexOf("/",12)+1,e=u.indexOf("?",s),p=e===-1?u.slice(s):u.substring(s,e);`,1)+`return mwn}`)(isErr,createContext,...dependencies)};
@@ -0,0 +1,10 @@
1
+ export type Header = [string, string] | readonly [string, string];
2
+ export type Headers = Header[];
3
+ export interface Context {
4
+ req: Request;
5
+ headers: Headers;
6
+ status?: number;
7
+ statusText?: string;
8
+ }
9
+ declare const _default: (req: Request) => Context;
10
+ export default _default;
@@ -0,0 +1 @@
1
+ import{proto}from"./utils.js";let ctxProto=proto({req:void 0,headers:void 0,status:200});export default req=>{let obj=Object.create(ctxProto);obj.headers=[];obj.req=req;return obj};
@@ -0,0 +1,22 @@
1
+ import type { Err } from "safe-throw";
2
+ import type { Context } from "./context.js";
3
+ export type ErrorHandler<
4
+ E extends Err = Err,
5
+ T extends {} = Record<string, any>
6
+ > = (err: E, c: Context & T) => any;
7
+ export type Handler<
8
+ Params extends string[] = string[],
9
+ T extends {} = Record<string, any>
10
+ > = (...args: [...params: Params, c: Context & T]) => any;
11
+ export type MiddlewareHandler = (c: Context) => any;
12
+ export type MiddlewareTypes<
13
+ E = never,
14
+ S = {}
15
+ > = [err: E, state: S];
16
+ export type AnyMiddlewareTypes = MiddlewareTypes<any, any>;
17
+ export type MergeMiddlewareTypes<T extends AnyMiddlewareTypes[]> = T extends [infer First extends AnyMiddlewareTypes, ...infer Rest extends AnyMiddlewareTypes[]] ? [First[0] | MergeMiddlewareTypes<Rest>[0], First[1] & MergeMiddlewareTypes<Rest>[1]] : [never, {}];
18
+ export interface HandlerData extends Record<symbol, any> {
19
+ type?: "json" | "html" | "raw";
20
+ }
21
+ export type InferPath<T extends string> = T extends `${string}*${infer Next}` ? Next extends "*" ? [string] : [string, ...InferPath<Next>] : [];
22
+ export type RequestMethod = "GET" | "POST" | "PUT" | "DELETE" | "PATCH" | "OPTIONS" | "TRACE";
@@ -0,0 +1 @@
1
+ export{};
@@ -0,0 +1,46 @@
1
+ import type { Err } from "safe-throw";
2
+ import type { MiddlewareTypes, AnyMiddlewareTypes, MergeMiddlewareTypes, ErrorHandler, Handler, HandlerData, InferPath, RequestMethod } from "./handler.js";
3
+ declare const tag: unique symbol;
4
+ export interface RouteHandler<S> {
5
+ readonly [tag]: S;
6
+ }
7
+ export type RouterTag = RouteHandler<typeof tag>;
8
+ export type AnyRouter = AnyMiddlewareTypes & RouterTag;
9
+ /**
10
+ * Create a router
11
+ * @param middlewares
12
+ * @param handlers
13
+ * @param children
14
+ */
15
+ export declare const init: <const T extends AnyMiddlewareTypes[]>(middlewares: T, handlers: RouteHandler<MergeMiddlewareTypes<T>[1]>[], children?: Record<string, AnyRouter>) => MergeMiddlewareTypes<T> & RouterTag;
16
+ /**
17
+ * Handle requests to a path with a specific method
18
+ * @param method
19
+ * @param path
20
+ * @param handler
21
+ * @param dat
22
+ */
23
+ export declare const on: <
24
+ S,
25
+ P extends string
26
+ >(method: RequestMethod | (string & {}), path: P, handler: Handler<InferPath<P>, S & {}>, ...dat: HandlerData[]) => RouteHandler<S>;
27
+ /**
28
+ * Handle any request method
29
+ * @param path
30
+ * @param handler
31
+ * @param dat
32
+ */
33
+ export declare const any: <
34
+ S,
35
+ P extends string
36
+ >(path: P, handler: Handler<InferPath<P>, S & {}>, ...dat: HandlerData[]) => RouteHandler<S>;
37
+ /**
38
+ * Handle router error
39
+ * @param router
40
+ * @param f
41
+ */
42
+ export declare const onErr: <
43
+ E extends Err,
44
+ S extends {}
45
+ >(router: MiddlewareTypes<E, S> & RouterTag, f: ErrorHandler<E, S>) => void;
46
+ export {};
package/core/index.js ADDED
@@ -0,0 +1 @@
1
+ import{proto}from"./utils.js";import{ALL}from"@mapl/router/method/index.js";export let init=(middlewares,handlers,children={})=>[middlewares,handlers,null,Object.entries(children)];export let on=(method,path,handler,...dat)=>[method,path,handler,proto(...dat)];export let any=(path,handler,...dat)=>[ALL,path,handler,proto(...dat)];export let onErr=(router,f)=>{router[2]=f};
@@ -0,0 +1,13 @@
1
+ import type { MiddlewareHandler, MiddlewareTypes } from "./handler.js";
2
+ import type { InferErr } from "safe-throw";
3
+ import type { AwaitedReturn } from "./utils.js";
4
+ export declare const run: (f: MiddlewareHandler) => MiddlewareTypes;
5
+ export declare const attach: <
6
+ Prop extends string,
7
+ const T extends MiddlewareHandler
8
+ >(prop: Prop, f: T) => MiddlewareTypes<never, Record<Prop, AwaitedReturn<T>>>;
9
+ export declare const validate: <const T extends MiddlewareHandler>(f: T) => MiddlewareTypes<InferErr<AwaitedReturn<T>>>;
10
+ export declare const parse: <
11
+ Prop extends string,
12
+ const T extends MiddlewareHandler
13
+ >(prop: Prop, f: T) => MiddlewareTypes<InferErr<AwaitedReturn<T>>, Record<Prop, AwaitedReturn<T>>>;
@@ -0,0 +1 @@
1
+ export let run=f=>[0,f];export let attach=(prop,f)=>[1,f,prop];export let validate=f=>[2,f];export let parse=(prop,f)=>[3,f];
@@ -1,3 +1,3 @@
1
- export type UnionToIntersection<U> = (U extends any ? (x: U) => void : never) extends ((x: infer I) => void) ? I : never;
1
+ export type UnionToIntersection<U> = (U extends any ? (x: U) => void : never) extends (x: infer I) => void ? I : never;
2
2
  export type AwaitedReturn<U extends (...a: any[]) => any> = Awaited<ReturnType<U>>;
3
3
  export declare const proto: <T extends any[]>(...f: T) => UnionToIntersection<T[number]>;
package/index.d.ts CHANGED
@@ -1,3 +1,3 @@
1
- export { default as router } from './router';
2
- import type { AnyRouter } from './router';
3
- export declare const compile: (app: AnyRouter) => (req: Request) => any;
1
+ export * as router from "./core/index.js";
2
+ export * as layer from "./core/middleware.js";
3
+ export { default as compile } from "./core/compile.js";
package/index.js CHANGED
@@ -1 +1 @@
1
- export{default as router}from"./router";import genericCompile from"./router/compiler";export let compile=(app)=>genericCompile(app,[]);
1
+ export*as router from"./core/index.js";export*as layer from"./core/middleware.js";export{default as compile}from"./core/compile.js";
package/package.json CHANGED
@@ -1,41 +1,25 @@
1
1
  {
2
- "name": "@mapl/web",
3
- "version": "0.0.8",
4
- "description": "A compiled web standard framework",
5
- "keywords": [
6
- "fast",
7
- "compiled",
8
- "cross-runtime",
9
- "framework",
10
- "web",
11
- "backend"
12
- ],
13
- "license": "MIT",
14
- "type": "module",
15
- "main": "./index.js",
16
- "types": "./index.d.ts",
17
- "scripts": {
18
- "task": "bun scripts/task.ts",
19
- "build:test": "bun task build && bun test",
20
- "build:publish": "bun task build && bun task report-size && bun task publish",
21
- "lint": "eslint ./src",
22
- "lint:fix": "eslint ./src --fix"
23
- },
24
- "devDependencies": {
25
- "@stylistic/eslint-plugin": "latest",
26
- "@types/bun": "latest",
27
- "@types/uglify-js": "latest",
28
- "eslint": "latest",
29
- "eslint-plugin-jsdoc": "latest",
30
- "mitata": "latest",
31
- "terser": "^5.39.0",
32
- "tsx": "latest",
33
- "typescript": "latest",
34
- "typescript-eslint": "latest"
35
- },
36
- "dependencies": {
37
- "@mapl/framework": "^0.1.0",
38
- "@mapl/router": "^0.4.13",
39
- "safe-throw": "^0.0.9"
40
- }
2
+ "name": "@mapl/web",
3
+ "version": "0.1.0",
4
+ "description": "A compiled web framework for all runtimes",
5
+ "keywords": [],
6
+ "license": "MIT",
7
+ "type": "module",
8
+ "main": "./index.js",
9
+ "types": "./index.d.ts",
10
+ "dependencies": {
11
+ "@mapl/framework": "^0.1.3",
12
+ "@mapl/router": "^0.4.15",
13
+ "safe-throw": "^0.5.1"
14
+ },
15
+ "exports": {
16
+ "./constants": "./constants.js",
17
+ "./core/compile": "./core/compile.js",
18
+ "./core/utils": "./core/utils.js",
19
+ "./core/context": "./core/context.js",
20
+ "./core/middleware": "./core/middleware.js",
21
+ ".": "./index.js",
22
+ "./core/handler": "./core/handler.js",
23
+ "./core": "./core/index.js"
41
24
  }
25
+ }
@@ -1,6 +0,0 @@
1
- import { type Err } from 'safe-throw';
2
- import type { Context } from '../router/context';
3
- export type TokenParser = (token: string, c: Context) => Promise<any>;
4
- export type MalformedErr = Err<'Malformed bearer token'>;
5
- declare const _default: <const T extends TokenParser>(verifier: T) => (c: Parameters<T>[1]) => ReturnType<T> | Promise<MalformedErr>;
6
- export default _default;
package/modules/bearer.js DELETED
@@ -1 +0,0 @@
1
- export default (verifier)=>async(c)=>{let tok=c.req.headers.get("Authorization");return typeof tok==="string"&&tok.startsWith("Bearer ")&&tok.length>7?verifier(tok,c):malformedErr};import{err}from"safe-throw";let malformedErr=Promise.resolve(err("Malformed bearer token"));
@@ -1,3 +0,0 @@
1
- import type { AnyRouter } from '.';
2
- declare const _default: (router: AnyRouter) => (req: Request) => any;
3
- export default _default;
@@ -1 +0,0 @@
1
- export default (router)=>{let baseRouter={};let dependencies=[];compileGroup(router._,[baseRouter,dependencies,"let mh=[],c=mwc(r,mh);",(fn,dat,path,state,scope)=>{let call="f"+state[1].push(fn)+"(";let paramCount=path[0].length;if(paramCount>0)call+=paramArgs[paramCount];if(fn.length>paramCount){call+=paramCount===0?"c":",c";if(!scope[1])return state[2]+compileReturn(state,dat,isFuncAsync(fn),scope[0],true,call+")")}return compileReturn(state,dat,isFuncAsync(fn),scope[0],scope[1],call+")")},(fn,dat,state,scope)=>{let call="f"+state[1].push(fn)+"(t";if(fn.length>1){call+=",c";if(!scope[1])return state[2]+compileReturn(state,dat,isFuncAsync(fn),scope[0],true,call+")")}return compileReturn(state,dat,isFuncAsync(fn),scope[0],scope[1],call+")")},transformRoute],[false,false,null,"return mwb"],"","");return Function("me","mwc",...dependencies.map((_,i)=>"f"+(i+1)),'let [mwh,mwj]=["text/html","application/json"].map(c=>["content-type",c]),[mwn,mwb]=[404,400].map(s=>new Response(null,{status:s}));return(r)=>{'+compile(baseRouter,o2,"r.method",'let u=r.url,s=u.indexOf("/",12)+1,e=u.indexOf("?",s),p=e===-1?u.slice(s):u.substring(s,e);',1)+"return mwn}")(isErr,createContext,...dependencies)};import{compileGroup,createArgSet,isFuncAsync}from"@mapl/framework";import{o2}from"@mapl/router/tree/compiler";import compile from"@mapl/router/method/compiler";import{transformRoute}from"@mapl/router/transform";import{isErr}from"safe-throw";import{createContext}from"./context";let paramArgs=createArgSet(new Array(16).fill(0).map((_1,i)=>"q"+i));let compileReturn=(state,dat,fnAsync,scopeAsync,contextCreated,result)=>{let typ=dat.type;if(typ==="raw")return"return "+result;if(fnAsync)result="await "+result;let str=typ==null?"return new Response("+result+(contextCreated?",c)":")"):(contextCreated?"":state[2])+"mh.push("+(typ==="json"?"mwj":"mwh")+");return new Response("+(typ==="json"?"JSON.stringify("+result+")":result)+",c)";return fnAsync&&!scopeAsync?"return (async()=>{"+str+"})()":scopeAsync?str+"})()":str};
@@ -1,9 +0,0 @@
1
- export type Header = [string, string] | readonly [string, string];
2
- export type Headers = Header[];
3
- export interface Context {
4
- req: Request;
5
- headers: Headers;
6
- status?: number;
7
- statusText?: string;
8
- }
9
- export declare const createContext: (req: Request, headers: Headers) => Context;
package/router/context.js DELETED
@@ -1 +0,0 @@
1
- import{proto}from"./utils";let ctxProto=proto({req:null,headers:null,status:200});export let createContext=(req,headers)=>{let obj=Object.create(ctxProto);obj.headers=headers;obj.req=req;return obj};
@@ -1,14 +0,0 @@
1
- import type { Group } from '@mapl/framework';
2
- import type { Err } from 'safe-throw';
3
- import type { Context } from './context';
4
- export type ErrorFunc<E extends Err = Err, T extends {} = Record<string, any>, Args extends any[] = any[]> = (err: E, c: Context & T, ...args: Args) => any;
5
- export type HandlerFunc<Params extends string[] = string[], T extends {} = Record<string, any>> = (...args: [...params: Params, c: Context & T]) => any;
6
- export type MiddlewareFunc<T extends {} = Record<string, any>> = (c: Context & T) => any;
7
- /**
8
- * Basic information to compile
9
- */
10
- export interface Data {
11
- type?: 'json' | 'html' | 'raw';
12
- }
13
- export type HandlerData = Data & Record<symbol, any>;
14
- export type HandlerGroup = Group<ErrorFunc, HandlerFunc, HandlerData>;
package/router/index.d.ts DELETED
@@ -1,22 +0,0 @@
1
- import type { Err, InferErr, InferResult } from 'safe-throw';
2
- import type { InferRoute } from '@mapl/router/transform';
3
- import { type AwaitedReturn } from './utils';
4
- import type { ErrorFunc, HandlerData, HandlerFunc, HandlerGroup, MiddlewareFunc } from './handler';
5
- import { type Methods } from './method';
6
- export type RouteRegister<in out State extends {}, in out E extends Err> = {
7
- [K in Methods | 'any']: <Path extends string>(path: Path, handler: HandlerFunc<InferRoute<Path>, State>, ...data: HandlerData[]) => Router<State, E>;
8
- };
9
- export interface Router<in out State extends {} = {}, in out E extends Err = never> extends RouteRegister<State, E> {
10
- _state: State;
11
- _err: E;
12
- _: HandlerGroup;
13
- apply: (fn: MiddlewareFunc<State>) => this;
14
- check: <const T extends MiddlewareFunc<State>>(fn: T) => Router<State, E | InferErr<AwaitedReturn<T>>>;
15
- set: <Prop extends string, const T extends MiddlewareFunc<State>>(prop: Prop, fn: T) => Router<State & Record<Prop, AwaitedReturn<T>>, E>;
16
- parse: <Prop extends string, const T extends MiddlewareFunc<State>>(prop: Prop, fn: T) => Router<State & Record<Prop, InferResult<AwaitedReturn<T>>>, E | InferErr<AwaitedReturn<T>>>;
17
- route: <Prefix extends string, const App extends Router<any, any>>(prefix: Prefix, app: App) => this;
18
- err: (fn: ErrorFunc<E, State>, ...data: HandlerData[]) => this;
19
- }
20
- export type AnyRouter = Router<any, any>;
21
- declare const _default: () => Router<[]>;
22
- export default _default;
package/router/index.js DELETED
@@ -1 +0,0 @@
1
- export default ()=>{let obj=Object.create(routerProto);obj._=[[],[],null,[]];return obj};import{proto}from"./utils";import{ALL,METHODS}from"./method";let createMethodRegister=(method)=>function(path,handler,...data){this._[1].push([method,path,handler,proto(...data)]);return this};let routerProto=proto({_:null,apply(f){this._[0].push([0,f]);return this},check(f){this._[0].push([2,f]);return this},set(prop,f){this._[0].push([1,f,prop]);return this},parse(prop,f){this._[0].push([3,f,prop]);return this},route(prefix,app){this._[3].push([prefix,app._]);return this},any:createMethodRegister(ALL),err(f,...data){this._[2]=[f,proto(...data)];return this}},Object.fromEntries(METHODS.map((method)=>[method,createMethodRegister(method.toUpperCase())])));
@@ -1,5 +0,0 @@
1
- import { ALL } from '@mapl/router/method';
2
- export declare const METHODS: readonly ["get", "post", "put", "delete", "patch", "options", "trace"];
3
- export type Methods = typeof METHODS[number];
4
- export type RequestMethod = Uppercase<Methods> | ALL | (string & {});
5
- export { ALL };
package/router/method.js DELETED
@@ -1 +0,0 @@
1
- import{ALL}from"@mapl/router/method";export let METHODS=["get","post","put","delete","patch","options","trace"];export{ALL};
File without changes