@sx3/ultra 0.0.2 → 0.0.4

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/dist/auth.d.mts CHANGED
@@ -1,9 +1,9 @@
1
- import { n as DefaultSocketData, t as BaseContext } from "./context-ChCsZh7S.mjs";
1
+ import { t as BaseContext } from "./context-BZAzgugo.mjs";
2
2
  import { o as Promisable } from "./types-Cn69QrjS.mjs";
3
- import "./http-BqWCMASL.mjs";
4
- import { t as Middleware } from "./middleware-COKreBGP.mjs";
5
- import { ProceduresMap, Ultra } from "./ultra.mjs";
6
- import { Session } from "./session.mjs";
3
+ import "./http-NhhQxMv8.mjs";
4
+ import { t as Middleware } from "./middleware-DB4PWjb4.mjs";
5
+ import "./ultra-Dawe5ndl.mjs";
6
+ import { Session, SessionContext } from "./session.mjs";
7
7
 
8
8
  //#region src/auth.d.ts
9
9
  interface AuthProvider<User> {
@@ -13,7 +13,7 @@ interface AuthProvider<User> {
13
13
  logout: () => Promisable<void>;
14
14
  setUser: (user: User) => Promisable<void>;
15
15
  }
16
- type AuthProviderFactory<User = any> = (context: AuthContext<User>) => AuthProvider<User>;
16
+ type AuthProviderFactory<User = any> = (context: SessionContext) => AuthProvider<User>;
17
17
  interface AuthConfig<P extends Record<string, AuthProviderFactory> = Record<string, AuthProviderFactory>> {
18
18
  provider: keyof P;
19
19
  providers: P;
@@ -23,17 +23,14 @@ type AuthContext<User> = BaseContext & {
23
23
  auth: Auth<User>;
24
24
  };
25
25
  declare function defineConfig<User, P extends Record<string, AuthProviderFactory<User>> = Record<string, AuthProviderFactory<User>>>(config: AuthConfig<P>): AuthConfig<P>;
26
- declare function createAuthModule<User, P extends Record<string, AuthProviderFactory<User>> = Record<string, AuthProviderFactory<User>>>(config: AuthConfig<P>): Ultra<ProceduresMap, BaseContext & {
27
- auth: Auth<User, P>;
28
- }, DefaultSocketData>;
29
26
  declare const isAuthenticated: Middleware<any, any, AuthContext<any>>;
30
27
  declare const isGuest: Middleware<any, any, AuthContext<any>>;
31
28
  declare class Auth<User, Providers extends Record<string, AuthProviderFactory<User>> = Record<string, AuthProviderFactory<User>>> {
32
29
  protected readonly config: AuthConfig<Providers>;
33
- protected readonly context: AuthContext<User>;
30
+ protected readonly context: SessionContext;
34
31
  protected readonly usingProvider: keyof Providers;
35
32
  protected readonly providerCache: Map<keyof Providers, AuthProvider<User>>;
36
- constructor(config: AuthConfig<Providers>, context: AuthContext<User>, provider?: keyof Providers, providerCache?: Map<keyof Providers, AuthProvider<User>>);
33
+ constructor(config: AuthConfig<Providers>, context: SessionContext, provider?: keyof Providers, providerCache?: Map<keyof Providers, AuthProvider<User>>);
37
34
  use(provider: keyof Providers): Auth<User, Providers>;
38
35
  get user(): User | null;
39
36
  check(): Promisable<boolean>;
@@ -43,9 +40,9 @@ declare class Auth<User, Providers extends Record<string, AuthProviderFactory<Us
43
40
  protected get provider(): AuthProvider<User>;
44
41
  }
45
42
  declare class SessionAuthProvider<User> implements AuthProvider<User> {
46
- protected readonly context: AuthContext<User>;
43
+ protected readonly context: SessionContext;
47
44
  protected readonly sessionKey: string;
48
- constructor(context: AuthContext<User>, sessionKey?: string);
45
+ constructor(context: SessionContext, sessionKey?: string);
49
46
  get user(): NonNullable<User> | null;
50
47
  check(): boolean;
51
48
  login(user: User): void;
@@ -53,4 +50,4 @@ declare class SessionAuthProvider<User> implements AuthProvider<User> {
53
50
  setUser(user: User): void;
54
51
  }
55
52
  //#endregion
56
- export { Auth, AuthContext, AuthProvider, SessionAuthProvider, createAuthModule, defineConfig, isAuthenticated, isGuest };
53
+ export { Auth, AuthContext, AuthProvider, SessionAuthProvider, defineConfig, isAuthenticated, isGuest };
package/dist/auth.mjs CHANGED
@@ -1 +1 @@
1
- import{r as e}from"./error-Dq1biCC8.mjs";import{Ultra as t}from"./ultra.mjs";function n(e){return e}function r(e){return new t().derive(t=>({auth:new o(e,t)}))}const i=async t=>await t.context.auth.check()?t.next():new e,a=async t=>await t.context.auth.check()?new e:t.next();var o=class e{config;context;usingProvider;providerCache;constructor(e,t,n=e.provider,r=new Map){this.config=e,this.context=t,this.usingProvider=n,this.providerCache=r}use(t){return new e(this.config,this.context,t,this.providerCache)}get user(){return this.provider.user}check(){return this.provider.check()}login(e){return this.provider.login(e)}logout(){return this.provider.logout()}setUser(e){return this.provider.setUser(e)}get provider(){let e=this.providerCache.get(this.usingProvider);if(e)return e;let t=this.config.providers[this.usingProvider];if(!t)throw Error(`Auth provider "${String(this.usingProvider)}" is not configured.`);let n=t(this.context);return this.providerCache.set(this.usingProvider,n),n}},s=class{context;sessionKey;constructor(e,t=`user`){this.context=e,this.sessionKey=t}get user(){return this.context.session.get(this.sessionKey)||null}check(){return this.user!==null}login(e){this.setUser(e),this.context.session.regenerate()}logout(){this.context.session.delete(this.sessionKey)}setUser(e){this.context.session.set(this.sessionKey,e)}};export{o as Auth,s as SessionAuthProvider,r as createAuthModule,n as defineConfig,i as isAuthenticated,a as isGuest};
1
+ import{r as e}from"./error-Dq1biCC8.mjs";function t(e){return e}const n=async t=>await t.context.auth.check()?t.next():new e,r=async t=>await t.context.auth.check()?new e:t.next();var i=class e{config;context;usingProvider;providerCache;constructor(e,t,n=e.provider,r=new Map){this.config=e,this.context=t,this.usingProvider=n,this.providerCache=r}use(t){return new e(this.config,this.context,t,this.providerCache)}get user(){return this.provider.user}check(){return this.provider.check()}login(e){return this.provider.login(e)}logout(){return this.provider.logout()}setUser(e){return this.provider.setUser(e)}get provider(){let e=this.providerCache.get(this.usingProvider);if(e)return e;let t=this.config.providers[this.usingProvider];if(!t)throw Error(`Auth provider "${String(this.usingProvider)}" is not configured.`);let n=t(this.context);return this.providerCache.set(this.usingProvider,n),n}},a=class{context;sessionKey;constructor(e,t=`user`){this.context=e,this.sessionKey=t}get user(){return this.context.session.get(this.sessionKey)||null}check(){return this.user!==null}login(e){this.setUser(e),this.context.session.regenerate()}logout(){this.context.session.delete(this.sessionKey)}setUser(e){this.context.session.set(this.sessionKey,e)}};export{i as Auth,a as SessionAuthProvider,t as defineConfig,n as isAuthenticated,r as isGuest};
package/dist/client.d.mts CHANGED
@@ -1,10 +1,10 @@
1
- import "./context-ChCsZh7S.mjs";
2
- import "./http-BqWCMASL.mjs";
3
- import { i as Procedure } from "./middleware-COKreBGP.mjs";
4
- import { ProceduresMap, Ultra } from "./ultra.mjs";
1
+ import "./context-BZAzgugo.mjs";
2
+ import "./http-NhhQxMv8.mjs";
3
+ import { i as Procedure } from "./middleware-DB4PWjb4.mjs";
4
+ import { n as Ultra, t as ProceduresMap } from "./ultra-Dawe5ndl.mjs";
5
5
 
6
6
  //#region src/client.d.ts
7
- type GetProcedures<T> = T extends Ultra<infer P> ? P : never;
7
+ type GetProcedures<T> = T extends Ultra<infer P, any, any> ? P : never;
8
8
  type BuildProcedure<P, CO> = P extends Procedure<infer I, infer O, any> ? (undefined extends I ? (input?: I, callOptions?: CO) => Promise<O> : (input: I, callOptions?: CO) => Promise<O>) : never;
9
9
  type BuildClient<P extends ProceduresMap, CO> = { [K in keyof P]: P[K] extends Procedure<any, any, any> ? BuildProcedure<P[K], CO> : P[K] extends ProceduresMap ? BuildClient<P[K], CO> : never };
10
10
  type Invoke<CO> = (method: string, params: unknown, callOptions?: CO) => Promise<unknown>;
@@ -12,16 +12,16 @@ interface HTTPClientOptions extends Omit<RequestInit, 'body'> {
12
12
  baseUrl: string;
13
13
  timeout?: number;
14
14
  }
15
- declare function createHTTPClient<B extends Ultra>(clientOptions: HTTPClientOptions): BuildClient<GetProcedures<B>, Partial<HTTPClientOptions>>;
15
+ declare function createHTTPClient<U extends Ultra<any, any, any>>(clientOptions: HTTPClientOptions): BuildClient<GetProcedures<U>, Partial<HTTPClientOptions>>;
16
16
  interface WebSocketClientOptions {
17
- socket: () => WebSocket;
17
+ socket: () => WebSocket | null;
18
18
  timeout?: number;
19
19
  }
20
- declare function createWebSocketClient<B extends Ultra>(options: WebSocketClientOptions): BuildClient<GetProcedures<B>, Partial<WebSocketClientOptions>>;
20
+ declare function createWebSocketClient<U extends Ultra<any, any, any>>(options: WebSocketClientOptions): BuildClient<GetProcedures<U>, Partial<WebSocketClientOptions>>;
21
21
  type ClientsCallsParams = Partial<WebSocketClientOptions> | Partial<HTTPClientOptions>;
22
- interface SuperClientOptions<B extends Ultra> {
22
+ interface SuperClientOptions<B extends Ultra<any, any, any>> {
23
23
  pick: (...args: Parameters<Invoke<ClientsCallsParams>>) => BuildClient<GetProcedures<B>, ClientsCallsParams>;
24
24
  }
25
- declare function createSuperClient<B extends Ultra>(options: SuperClientOptions<B>): BuildClient<GetProcedures<B>, ClientsCallsParams>;
25
+ declare function createSuperClient<B extends Ultra<any, any, any>>(options: SuperClientOptions<B>): BuildClient<GetProcedures<B>, ClientsCallsParams>;
26
26
  //#endregion
27
27
  export { createHTTPClient, createSuperClient, createWebSocketClient };
package/dist/client.mjs CHANGED
@@ -1 +1 @@
1
- function e(t,n=[]){return new Proxy(()=>{},{get(r,i){if(typeof i==`string`)return e(t,[...n,i])},apply(e,r,i){if(!n.length)throw Error(`Cannot call client root; select a procedure first`);let a=n.join(`/`),o=i[0],s=i[1];return t(a,o,s)}})}function t(...e){let t=new Headers;for(let n of e)n&&new Headers(n).forEach((e,n)=>t.set(n,e));return t}function n(n){return e(async(e,r,i)=>{let a={...n,...i},o=a?.timeout||1e4,s=new AbortController,c=a?.method||`POST`,l=`${a.baseUrl}/${e}`,u=t(n?.headers,a?.headers,i?.headers),d=null,f=setTimeout(()=>s.abort(`Timeout: ${o}`),o);switch(!0){case c===`GET`:{if(d=null,!r)break;if(typeof r!=`object`)throw Error(`GET requests params to be an object for query string generation`);let e=Object.entries(r).filter(([,e])=>e!=null).map(([e,t])=>[e,String(t)]),t=new URLSearchParams(e).toString();t&&(l+=`?${t}`);break}case r instanceof FormData:d=r;break;case typeof r==`string`:u.set(`Content-Type`,`text/plain`),d=r;break;default:u.set(`Content-Type`,`application/json`),d=JSON.stringify(r)}try{let e=await fetch(l,{method:c,...d&&{body:d},...a,signal:s.signal,headers:u});if(!e.ok)throw Error(`HTTP error: ${e.statusText} ${e.status} `);let t=e.headers.get(`Content-Type`)||``;switch(!0){case t.includes(`application/json`):return await e.json();case t.includes(`text/`):return await e.text();default:return await e.blob()}}catch(e){throw e.name===`AbortError`?Error(`Request aborted: ${e.message}`):e}finally{clearTimeout(f)}})}function r(t){let{timeout:n=1e4}=t,r=()=>Math.random().toString(36);return e((e,i,a)=>{let o=t.socket(),s=o.readyState;if(typeof s==`number`&&s!==WebSocket.OPEN)return Promise.reject(Error(`WebSocket is not open`));let{promise:c,resolve:l,reject:u}=Promise.withResolvers(),d=a?.timeout??n,f,p=r(),m=e=>{try{let t=JSON.parse(e.data);return t.id===p?(clearTimeout(f),o.removeEventListener(`message`,m),`error`in t?u(t.error):l(t.result)):void 0}catch(e){u(e)}};return o.addEventListener(`message`,m),f=setTimeout(()=>{o.removeEventListener(`message`,m),u(`Timeout: ${d}`)},d),o.send(JSON.stringify({id:p,method:e,params:i})),c})}function i(t){return e((e,n,r)=>{let i=t.pick(e,n,r),a=e.split(`/`).filter(Boolean),o=i;for(let e of a)o[e]&&(o=o[e]);return o(n,r)})}export{n as createHTTPClient,i as createSuperClient,r as createWebSocketClient};
1
+ function e(t,n=[]){return new Proxy(()=>{},{get(r,i){if(typeof i==`string`)return e(t,[...n,i])},apply(e,r,i){if(!n.length)throw Error(`Cannot call client root; select a procedure first`);let a=n.join(`/`),o=i[0],s=i[1];return t(a,o,s)}})}function t(...e){let t=new Headers;for(let n of e)n&&new Headers(n).forEach((e,n)=>t.set(n,e));return t}function n(n){return e(async(e,r,i)=>{let a={...n,...i},o=a?.timeout||1e4,s=new AbortController,c=a?.method||`POST`,l=`${a.baseUrl}/${e}`,u=t(n?.headers,a?.headers,i?.headers),d=null,f=setTimeout(()=>s.abort(`Timeout: ${o}`),o);switch(!0){case c===`GET`:{if(d=null,!r)break;if(typeof r!=`object`)throw Error(`GET requests params to be an object for query string generation`);let e=Object.entries(r).filter(([,e])=>e!=null).map(([e,t])=>[e,String(t)]),t=new URLSearchParams(e).toString();t&&(l+=`?${t}`);break}case r instanceof FormData:d=r;break;case typeof r==`string`:u.set(`Content-Type`,`text/plain`),d=r;break;default:u.set(`Content-Type`,`application/json`),d=JSON.stringify(r)}try{let e=await fetch(l,{method:c,...d&&{body:d},...a,signal:s.signal,headers:u});if(!e.ok)throw Error(`HTTP error: ${e.statusText} ${e.status} `);let t=e.headers.get(`Content-Type`)||``;switch(!0){case t.includes(`application/json`):return await e.json();case t.includes(`text/`):return await e.text();default:return await e.blob()}}catch(e){throw e.name===`AbortError`?Error(`Request aborted: ${e.message}`):e}finally{clearTimeout(f)}})}function r(t){let{timeout:n=1e4}=t,r=()=>Math.random().toString(36);return e((e,i,a)=>{let o=t.socket();if(!o||o.readyState!==WebSocket.OPEN)return Promise.reject(Error(`WebSocket is not open`));let{promise:s,resolve:c,reject:l}=Promise.withResolvers(),u=a?.timeout??n,d,f=r(),p=e=>{try{let t=JSON.parse(e.data);return t.id===f?(clearTimeout(d),o.removeEventListener(`message`,p),`error`in t?l(t.error):c(t.result)):void 0}catch(e){l(e)}};return o.addEventListener(`message`,p),d=setTimeout(()=>{o.removeEventListener(`message`,p),l(`Timeout: ${u}`)},u),o.send(JSON.stringify({id:f,method:e,params:i})),s})}function i(t){return e((e,n,r)=>{let i=t.pick(e,n,r),a=e.split(`/`).filter(Boolean),o=i;for(let e of a)o[e]&&(o=o[e]);return o(n,r)})}export{n as createHTTPClient,i as createSuperClient,r as createWebSocketClient};
@@ -10,7 +10,7 @@ interface WSContext<SocketData> {
10
10
  server: Server<SocketData>;
11
11
  ws: ServerWebSocket<SocketData>;
12
12
  }
13
- type BaseContext<SocketData extends DefaultSocketData = DefaultSocketData> = HTTPContext | WSContext<SocketData>;
13
+ type BaseContext<SocketData extends DefaultSocketData = any> = HTTPContext | WSContext<SocketData>;
14
14
  declare function isHTTP(context: BaseContext): context is HTTPContext;
15
15
  declare function isWS<SocketData extends DefaultSocketData = DefaultSocketData>(context: BaseContext): context is WSContext<SocketData>;
16
16
  //#endregion
@@ -1,2 +1,2 @@
1
- import { a as isHTTP, i as WSContext, n as DefaultSocketData, o as isWS, r as HTTPContext, t as BaseContext } from "./context-ChCsZh7S.mjs";
1
+ import { a as isHTTP, i as WSContext, n as DefaultSocketData, o as isWS, r as HTTPContext, t as BaseContext } from "./context-BZAzgugo.mjs";
2
2
  export { BaseContext, DefaultSocketData, HTTPContext, WSContext, isHTTP, isWS };
package/dist/cors.d.mts CHANGED
@@ -1,6 +1,6 @@
1
- import { t as BaseContext } from "./context-ChCsZh7S.mjs";
2
- import "./http-BqWCMASL.mjs";
3
- import { t as Middleware } from "./middleware-COKreBGP.mjs";
1
+ import { t as BaseContext } from "./context-BZAzgugo.mjs";
2
+ import "./http-NhhQxMv8.mjs";
3
+ import { t as Middleware } from "./middleware-DB4PWjb4.mjs";
4
4
 
5
5
  //#region src/cors.d.ts
6
6
  interface CorsConfig {
package/dist/cors.mjs CHANGED
@@ -1 +1 @@
1
- import{t as e}from"./response-CnnOFeUL.mjs";const t={"Access-Control-Allow-Methods":[`GET`,`POST`,`PUT`,`PATCH`,`DELETE`,`OPTIONS`].join(`, `),"Access-Control-Allow-Headers":[`Accept-Language`,`Accept`,`Content-Type`,`Content-Language`,`Range`].join(`, `),"Access-Control-Expose-Headers":[`Cache-Control`,`Content-Language`,`Content-Type`,`Expires`,`Last-Modified`,`Pragma`].join(`, `),"Access-Control-Max-Age":`3600`};function n(n){let r={...t,...n.methods?.length&&{"Access-Control-Allow-Methods":n.methods.join(`, `)},...n.allowedHeaders?.length&&{"Access-Control-Allow-Headers":n.allowedHeaders.join(`, `)},...n.exposedHeaders?.length&&{"Access-Control-Expose-Headers":n.exposedHeaders.join(`, `)},...n.credentials&&!n.origin.includes(`*`)&&{"Access-Control-Allow-Credentials":`true`},...n.maxAge&&{"Access-Control-Max-Age":n.maxAge.toString()}};return async t=>{if(!(`request`in t.context))return t.next();let i=t.context.request.headers.get(`Origin`);if(!i||!n.origin.includes(i))return t.next();if(t.context.request.method===`OPTIONS`)return new Response(null,{status:204,headers:{"Access-Control-Allow-Origin":i,...r}});let a=e(await t.next());for(let e in a.headers.set(`Access-Control-Allow-Origin`,i),r)a.headers.set(e,r[e]);return a}}export{n as createCORSMiddleware};
1
+ import{t as e}from"./response-D935Hx3o.mjs";const t={"Access-Control-Allow-Methods":[`GET`,`POST`,`PUT`,`PATCH`,`DELETE`,`OPTIONS`].join(`, `),"Access-Control-Allow-Headers":[`Accept-Language`,`Accept`,`Content-Type`,`Content-Language`,`Range`].join(`, `),"Access-Control-Expose-Headers":[`Cache-Control`,`Content-Language`,`Content-Type`,`Expires`,`Last-Modified`,`Pragma`].join(`, `),"Access-Control-Max-Age":`3600`};function n(n){let r={...t,...n.methods?.length&&{"Access-Control-Allow-Methods":n.methods.join(`, `)},...n.allowedHeaders?.length&&{"Access-Control-Allow-Headers":n.allowedHeaders.join(`, `)},...n.exposedHeaders?.length&&{"Access-Control-Expose-Headers":n.exposedHeaders.join(`, `)},...n.credentials&&!n.origin.includes(`*`)&&{"Access-Control-Allow-Credentials":`true`},...n.maxAge&&{"Access-Control-Max-Age":n.maxAge.toString()}};return async t=>{if(!(`request`in t.context))return t.next();let i=t.context.request.headers.get(`Origin`);if(!i||!n.origin.includes(i))return t.next();if(t.context.request.method===`OPTIONS`)return new Response(null,{status:204,headers:{"Access-Control-Allow-Origin":i,...r}});let a=e(await t.next());for(let e in a.headers.set(`Access-Control-Allow-Origin`,i),r)a.headers.set(e,r[e]);return a}}export{n as createCORSMiddleware};
@@ -1,4 +1,4 @@
1
- import { n as DefaultSocketData } from "./context-ChCsZh7S.mjs";
1
+ import { n as DefaultSocketData } from "./context-BZAzgugo.mjs";
2
2
  import { o as Promisable } from "./types-Cn69QrjS.mjs";
3
3
  import { BunRequest, Server } from "bun";
4
4
 
package/dist/http.d.mts CHANGED
@@ -1,3 +1,3 @@
1
- import "./context-ChCsZh7S.mjs";
2
- import { n as BunRoutes, r as HTTPMethod, t as BunRouteHandler } from "./http-BqWCMASL.mjs";
1
+ import "./context-BZAzgugo.mjs";
2
+ import { n as BunRoutes, r as HTTPMethod, t as BunRouteHandler } from "./http-NhhQxMv8.mjs";
3
3
  export { BunRouteHandler, BunRoutes, HTTPMethod };
@@ -1,6 +1,6 @@
1
- import { t as BaseContext } from "./context-ChCsZh7S.mjs";
1
+ import { t as BaseContext } from "./context-BZAzgugo.mjs";
2
2
  import { o as Promisable } from "./types-Cn69QrjS.mjs";
3
- import { r as HTTPMethod } from "./http-BqWCMASL.mjs";
3
+ import { r as HTTPMethod } from "./http-NhhQxMv8.mjs";
4
4
  import { c as StandardSchemaV1 } from "./validation-CkRfxQJ_.mjs";
5
5
 
6
6
  //#region src/procedure.d.ts
@@ -1,4 +1,4 @@
1
- import "./context-ChCsZh7S.mjs";
2
- import "./http-BqWCMASL.mjs";
3
- import { n as MiddlewareOptions, t as Middleware } from "./middleware-COKreBGP.mjs";
1
+ import "./context-BZAzgugo.mjs";
2
+ import "./http-NhhQxMv8.mjs";
3
+ import { n as MiddlewareOptions, t as Middleware } from "./middleware-DB4PWjb4.mjs";
4
4
  export { Middleware, MiddlewareOptions };
@@ -1 +1 @@
1
- import{t as e}from"./validation-BY5LC99k.mjs";var t=class{inputSchema;outputSchema;handlerFunction;middleware=new Set;httpOptions;input(e){return e&&(this.inputSchema=e),this}output(e){return e&&(this.outputSchema=e),this}handler(e){return this.handlerFunction=e,this}http(e){return this.httpOptions={...e,enabled:!0},this}use(e){return this.middleware.add(e),this}wrap(){if(!this.handlerFunction)throw Error(`Procedure handler is not defined`);if(!this.inputSchema&&!this.outputSchema&&!this.middleware.size)return this.handlerFunction;let t=this.handlerFunction;switch(!0){case!this.inputSchema&&!this.outputSchema:break;case!this.inputSchema:{let n=t;t=async t=>e(this.outputSchema,await n(t));break}case!this.outputSchema:{let n=t;t=async t=>n({...t,input:await e(this.inputSchema,t.input)});break}default:{let n=t;t=async t=>{let r=await n({...t,input:await e(this.inputSchema,t.input)});return e(this.outputSchema,r)}}}if(this.middleware.size){let e=Array.from(this.middleware);for(let n=e.length-1;n>=0;n--){let r=e[n],i=t;t=e=>r({...e,next:()=>i(e)})}}return t}getInfo(){return{http:this.httpOptions,hasInput:!!this.inputSchema,hasOutput:!!this.outputSchema}}};export{t};
1
+ import{t as e}from"./validation-dJpfcBud.mjs";var t=class{inputSchema;outputSchema;handlerFunction;middleware=new Set;httpOptions;input(e){return e&&(this.inputSchema=e),this}output(e){return e&&(this.outputSchema=e),this}handler(e){return this.handlerFunction=e,this}http(e){return this.httpOptions={...e,enabled:!0},this}use(e){return this.middleware.add(e),this}wrap(){if(!this.handlerFunction)throw Error(`Procedure handler is not defined`);if(!this.inputSchema&&!this.outputSchema&&!this.middleware.size)return this.handlerFunction;let t=this.handlerFunction;switch(!0){case!this.inputSchema&&!this.outputSchema:break;case!this.inputSchema:{let n=t;t=async t=>e(this.outputSchema,await n(t));break}case!this.outputSchema:{let n=t;t=async t=>n({...t,input:await e(this.inputSchema,t.input)});break}default:{let n=t;t=async t=>{let r=await n({...t,input:await e(this.inputSchema,t.input)});return e(this.outputSchema,r)}}}if(this.middleware.size){let e=Array.from(this.middleware);for(let n=e.length-1;n>=0;n--){let r=e[n],i=t;t=e=>r({...e,next:()=>i(e)})}}return t}getInfo(){return{http:this.httpOptions,hasInput:!!this.inputSchema,hasOutput:!!this.outputSchema}}};export{t};
@@ -1,4 +1,4 @@
1
- import "./context-ChCsZh7S.mjs";
2
- import "./http-BqWCMASL.mjs";
3
- import { a as ProcedureHandler, i as Procedure, o as ProcedureOptions, r as HTTPOptions } from "./middleware-COKreBGP.mjs";
1
+ import "./context-BZAzgugo.mjs";
2
+ import "./http-NhhQxMv8.mjs";
3
+ import { a as ProcedureHandler, i as Procedure, o as ProcedureOptions, r as HTTPOptions } from "./middleware-DB4PWjb4.mjs";
4
4
  export { HTTPOptions, Procedure, ProcedureHandler, ProcedureOptions };
@@ -1 +1 @@
1
- import{t as e}from"./procedure-DRzVmxaT.mjs";export{e as Procedure};
1
+ import{t as e}from"./procedure-AntXykJT.mjs";export{e as Procedure};
package/dist/response.mjs CHANGED
@@ -1 +1 @@
1
- import{n as e,t}from"./response-CnnOFeUL.mjs";export{t as toHTTPResponse,e as toRPCResponse};
1
+ import{n as e,t}from"./response-D935Hx3o.mjs";export{t as toHTTPResponse,e as toRPCResponse};
@@ -1,8 +1,8 @@
1
- import { n as DefaultSocketData, r as HTTPContext, t as BaseContext } from "./context-ChCsZh7S.mjs";
1
+ import { n as DefaultSocketData, t as BaseContext } from "./context-BZAzgugo.mjs";
2
2
  import { a as JSONValue, o as Promisable, r as JSONObject, t as DeepReadonly } from "./types-Cn69QrjS.mjs";
3
- import "./http-BqWCMASL.mjs";
4
- import "./middleware-COKreBGP.mjs";
5
- import { ProceduresMap, Ultra } from "./ultra.mjs";
3
+ import "./http-NhhQxMv8.mjs";
4
+ import "./middleware-DB4PWjb4.mjs";
5
+ import { n as Ultra, t as ProceduresMap } from "./ultra-Dawe5ndl.mjs";
6
6
  import { BunRequest, CookieSameSite, RedisClient } from "bun";
7
7
 
8
8
  //#region src/session.d.ts
@@ -47,13 +47,18 @@ interface SessionConfig<S extends Record<string, SessionStoreFactory> = Record<s
47
47
  interface SessionSocketData {
48
48
  sessionId: string;
49
49
  }
50
+ type SessionContext = BaseContext<{
51
+ sessionId: string;
52
+ }> & {
53
+ session: Session<any>;
54
+ };
50
55
  declare function defineConfig<S extends Record<string, SessionStoreFactory>>(config: SessionConfig<S>): SessionConfig<S>;
51
56
  /** Extends context and socket data, initiate session instance every request */
52
57
  declare function createSessionModule<S extends Record<string, SessionStoreFactory>>(config: SessionConfig<S>): Ultra<ProceduresMap, (BaseContext & {
53
58
  session: Session<S>;
54
- }) & BaseContext, DefaultSocketData & ((context: HTTPContext) => {
59
+ }) & BaseContext, DefaultSocketData & {
55
60
  sessionId: string;
56
- })>;
61
+ }>;
57
62
  /** Stores the ID in a cookie, then moves it to the socket and uses it for requests */
58
63
  declare class Session<Stores extends Record<string, SessionStoreFactory> = Record<string, SessionStoreFactory>> {
59
64
  /** Make random session id */
@@ -112,4 +117,4 @@ declare class MemorySessionStore implements SessionStore {
112
117
  protected maybeSweep(now?: number): void;
113
118
  }
114
119
  //#endregion
115
- export { MemorySessionStore, RedisSessionStore, Session, SessionConfig, SessionData, SessionSocketData, SessionStore, SessionStoreFactory, createSessionModule, defineConfig };
120
+ export { MemorySessionStore, RedisSessionStore, Session, SessionConfig, SessionContext, SessionData, SessionSocketData, SessionStore, SessionStoreFactory, createSessionModule, defineConfig };
package/dist/session.mjs CHANGED
@@ -1 +1 @@
1
- import{i as e}from"./error-Dq1biCC8.mjs";import{Ultra as t}from"./ultra.mjs";import{isHTTP as n,isWS as r}from"./context.mjs";import{sign as i,unsign as a}from"./crypto.mjs";import{randomBytes as o}from"node:crypto";function s(e){return{...e,cookie:{path:`/`,httpOnly:!0,secure:!0,sameSite:`lax`,maxAge:e.ttlSec,...e?.cookie}}}function c(e){return new t().deriveWS(t=>({sessionId:l.getOrCreateId(t.request,e)})).derive(t=>({session:new l(e,t)})).use(async({context:e,next:t})=>{await e.session.initiate();let n=await t();return await e.session.commit(),n})}var l=class t{static makeId(){return o(16).toString(`base64url`)}static getOrCreateId(e,n){let r=e.cookies.get(n.name);return r&&a(r,n.secret)||t.makeId()}config;context;store;sessionIdFromClient=null;sessionId;sessionState=null;modified=!1;constructor(i,o){switch(this.config=i,this.context=o,this.store=i.stores[i.store](i,o),!0){case n(o):{let e=o.request.cookies.get(i.name);e&&(this.sessionIdFromClient=a(e,i.secret));break}case r(o):this.sessionIdFromClient=o.ws.data.sessionId||null;break;default:throw new e(`Session management is only supported for HTTP and WebSocket protocols.`)}this.sessionId=this.sessionIdFromClient||t.makeId()}get id(){return this.sessionId}async initiate(){this.sessionState||=await this.store.read(this.sessionId)||{}}async commit(){if(this.touch(),this.isEmpty&&this.sessionIdFromClient)return this.store.destroy(this.sessionIdFromClient);this.sessionIdFromClient&&this.sessionIdFromClient!==this.sessionId?(await this.store.destroy(this.sessionIdFromClient),await this.store.write(this.sessionId,this.state)):this.modified?await this.store.write(this.sessionId,this.state):await this.store.touch(this.sessionId)}regenerate(){this.sessionId=t.makeId()}get(e,t){return this.state[e]??t??null}set(e,t){this.state[e]=t,this.modified=!0}has(e){return Object.hasOwn(this.state,e)}all(){return this.state}delete(e){delete this.state[e],this.modified=!0}clear(){this.sessionState={},this.modified=!0}get state(){if(!this.sessionState)throw Error(`Session is not initiated yet.`);return this.sessionState}get isEmpty(){return Object.keys(this.state).length===0}touch(){`request`in this.context&&this.context.request.cookies.set(this.config.name,i(this.sessionId,this.config.secret),this.config.cookie)}},u=class{config;connection;constructor(e,t){this.config=e,this.connection=t}async read(e){let t=await this.connection.get(`${this.config.name}:${e}`);return t?JSON.parse(t):null}async write(e,t){await this.connection.set(`${this.config.name}:${e}`,JSON.stringify(t),`EX`,this.config.ttlSec)}async destroy(e){await this.connection.del(`${this.config.name}:${e}`)}async touch(e){await this.connection.expire(`${this.config.name}:${e}`,this.config.ttlSec)}},d=class{config;sessions=new Map;sweepIntervalMs;ttlMs;lastSweepAt=Date.now();constructor(e,t=e.ttlSec){this.config=e,this.sweepIntervalMs=t*1e3,this.ttlMs=e.ttlSec*1e3}read(e){return this.maybeSweep(),this.sessions.get(e)?.data||null}write(e,t){this.maybeSweep(),this.sessions.set(e,{data:t,touched:Date.now()})}destroy(e){this.maybeSweep(),this.sessions.delete(e)}touch(e){this.maybeSweep();let t=this.sessions.get(e);t&&(t.touched=Date.now())}maybeSweep(e=Date.now()){if(!(e-this.lastSweepAt<this.sweepIntervalMs)){this.lastSweepAt=e;for(let[t,n]of this.sessions)e-n.touched>this.ttlMs&&this.sessions.delete(t)}}};export{d as MemorySessionStore,u as RedisSessionStore,l as Session,c as createSessionModule,s as defineConfig};
1
+ import{i as e}from"./error-Dq1biCC8.mjs";import{isHTTP as t,isWS as n}from"./context.mjs";import{sign as r,unsign as i}from"./crypto.mjs";import{Ultra as a}from"./ultra.mjs";import{randomBytes as o}from"node:crypto";function s(e){return{...e,cookie:{path:`/`,httpOnly:!0,secure:!0,sameSite:`lax`,maxAge:e.ttlSec,...e?.cookie}}}function c(e){return new a().deriveWS(t=>({sessionId:l.getOrCreateId(t.request,e)})).derive(t=>({session:new l(e,t)})).use(async({context:e,next:t})=>{await e.session.initiate();let n=await t();return await e.session.commit(),n})}var l=class a{static makeId(){return o(16).toString(`base64url`)}static getOrCreateId(e,t){let n=e.cookies.get(t.name);return n&&i(n,t.secret)||a.makeId()}config;context;store;sessionIdFromClient=null;sessionId;sessionState=null;modified=!1;constructor(r,o){switch(this.config=r,this.context=o,this.store=r.stores[r.store](r,o),!0){case t(o):{let e=o.request.cookies.get(r.name);e&&(this.sessionIdFromClient=i(e,r.secret));break}case n(o):this.sessionIdFromClient=o.ws.data.sessionId||null;break;default:throw new e(`Session management is only supported for HTTP and WebSocket protocols.`)}this.sessionId=this.sessionIdFromClient||a.makeId()}get id(){return this.sessionId}async initiate(){this.sessionState||=await this.store.read(this.sessionId)||{}}async commit(){if(this.touch(),this.isEmpty&&this.sessionIdFromClient)return this.store.destroy(this.sessionIdFromClient);this.sessionIdFromClient&&this.sessionIdFromClient!==this.sessionId?(await this.store.destroy(this.sessionIdFromClient),await this.store.write(this.sessionId,this.state)):this.modified?await this.store.write(this.sessionId,this.state):await this.store.touch(this.sessionId)}regenerate(){this.sessionId=a.makeId()}get(e,t){return this.state[e]??t??null}set(e,t){this.state[e]=t,this.modified=!0}has(e){return Object.hasOwn(this.state,e)}all(){return this.state}delete(e){delete this.state[e],this.modified=!0}clear(){this.sessionState={},this.modified=!0}get state(){if(!this.sessionState)throw Error(`Session is not initiated yet.`);return this.sessionState}get isEmpty(){return Object.keys(this.state).length===0}touch(){`request`in this.context&&this.context.request.cookies.set(this.config.name,r(this.sessionId,this.config.secret),this.config.cookie)}},u=class{config;connection;constructor(e,t){this.config=e,this.connection=t}async read(e){let t=await this.connection.get(`${this.config.name}:${e}`);return t?JSON.parse(t):null}async write(e,t){await this.connection.set(`${this.config.name}:${e}`,JSON.stringify(t),`EX`,this.config.ttlSec)}async destroy(e){await this.connection.del(`${this.config.name}:${e}`)}async touch(e){await this.connection.expire(`${this.config.name}:${e}`,this.config.ttlSec)}},d=class{config;sessions=new Map;sweepIntervalMs;ttlMs;lastSweepAt=Date.now();constructor(e,t=e.ttlSec){this.config=e,this.sweepIntervalMs=t*1e3,this.ttlMs=e.ttlSec*1e3}read(e){return this.maybeSweep(),this.sessions.get(e)?.data||null}write(e,t){this.maybeSweep(),this.sessions.set(e,{data:t,touched:Date.now()})}destroy(e){this.maybeSweep(),this.sessions.delete(e)}touch(e){this.maybeSweep();let t=this.sessions.get(e);t&&(t.touched=Date.now())}maybeSweep(e=Date.now()){if(!(e-this.lastSweepAt<this.sweepIntervalMs)){this.lastSweepAt=e;for(let[t,n]of this.sessions)e-n.touched>this.ttlMs&&this.sessions.delete(t)}}};export{d as MemorySessionStore,u as RedisSessionStore,l as Session,c as createSessionModule,s as defineConfig};
@@ -0,0 +1,69 @@
1
+ import { n as DefaultSocketData, t as BaseContext } from "./context-BZAzgugo.mjs";
2
+ import { o as Promisable } from "./types-Cn69QrjS.mjs";
3
+ import { n as BunRoutes } from "./http-NhhQxMv8.mjs";
4
+ import { c as StandardSchemaV1 } from "./validation-CkRfxQJ_.mjs";
5
+ import { a as ProcedureHandler, i as Procedure, t as Middleware } from "./middleware-DB4PWjb4.mjs";
6
+ import { n as Payload } from "./rpc-Ch2UXReT.mjs";
7
+ import { BunRequest, ErrorLike, Server, ServerWebSocket } from "bun";
8
+
9
+ //#region src/ultra.d.ts
10
+ interface ProceduresMap {
11
+ [key: string]: Procedure<any, any, any> | ProceduresMap;
12
+ }
13
+ interface ServerEventMap<SocketData extends DefaultSocketData = DefaultSocketData> {
14
+ 'error': [ErrorLike];
15
+ 'unhandled:error': [ErrorLike];
16
+ 'http:request': [BunRequest, Server<SocketData>];
17
+ 'ws:open': [ServerWebSocket<SocketData>];
18
+ 'ws:message': [ServerWebSocket<SocketData>, string | Buffer<ArrayBuffer>];
19
+ 'ws:close': [ServerWebSocket<SocketData>, number, string];
20
+ 'server:started': [Server<SocketData>];
21
+ 'server:stopped': [Server<SocketData>, closeActiveConnections: boolean];
22
+ }
23
+ type ServerEventListener<K extends keyof ServerEventMap> = (...args: ServerEventMap[K]) => any;
24
+ type DeriveFunction<C extends BaseContext> = (context: C) => Promisable<Record<PropertyKey, any>>;
25
+ type DeriveValue<C extends BaseContext> = DeriveFunction<C> | Record<PropertyKey, any>;
26
+ type ExtractDerive<C extends BaseContext, T extends DeriveValue<C>> = T extends DeriveFunction<C> ? Awaited<ReturnType<T>> : T;
27
+ type StartOptions<SocketData extends DefaultSocketData> = Omit<Partial<Bun.Serve.Options<SocketData>>, 'websocket' | 'error' | 'routes'>;
28
+ interface UltraOptions {
29
+ http: boolean;
30
+ }
31
+ type InputFactory<C extends BaseContext> = <I>(schema?: StandardSchemaV1<I>) => Procedure<I, unknown, C>;
32
+ type ProcedureMapInitializer<R extends ProceduresMap, C extends BaseContext = BaseContext> = (input: InputFactory<C>) => R;
33
+ declare class Ultra<Procedures extends ProceduresMap = ProceduresMap, Context extends BaseContext = BaseContext, SocketData extends DefaultSocketData = DefaultSocketData> {
34
+ protected readonly initializers: Set<ProcedureMapInitializer<any, Context>>;
35
+ protected readonly handlers: Map<string, ProcedureHandler<any, any, Context>>;
36
+ protected readonly events: Map<keyof ServerEventMap<SocketData>, Set<ServerEventListener<any>>>;
37
+ protected readonly middlewares: Set<Middleware<any, any, Context>>;
38
+ protected readonly derived: Set<DeriveValue<Context>>;
39
+ protected readonly derivedWS: Set<DeriveValue<Context>>;
40
+ protected readonly options: UltraOptions;
41
+ protected server?: Server<SocketData>;
42
+ constructor(options?: Partial<UltraOptions>);
43
+ /** Register procedures */
44
+ routes<const P extends ProceduresMap>(initializer: ProcedureMapInitializer<P, Context>): Ultra<Procedures & P, Context, SocketData>;
45
+ /** Register middleware or another Ultra instance */
46
+ use<const PluginProcedures extends ProceduresMap, const PluginContext extends BaseContext, const PluginSocketData extends DefaultSocketData>(entity: Middleware<any, any, Context> | Ultra<PluginProcedures, PluginContext, PluginSocketData>): Ultra<Procedures & PluginProcedures, Context & PluginContext, SocketData & PluginSocketData>;
47
+ /** Extends context values for every request with provided values */
48
+ derive<const D extends DeriveValue<Context>>(derive: D): Ultra<Procedures, Context & ExtractDerive<Context, D>, SocketData>;
49
+ /** Extends WS data for every ws connection */
50
+ deriveWS<const D extends DeriveValue<Context>>(derive: D): Ultra<Procedures, Context, SocketData & ExtractDerive<Context, D>>;
51
+ start(options?: StartOptions<SocketData>): Server<SocketData>;
52
+ stop(closeActiveConnections?: boolean): Promise<void>;
53
+ on<E extends keyof ServerEventMap>(event: E, listener: ServerEventListener<E>): this;
54
+ off<E extends keyof ServerEventMap>(event: E, listener: ServerEventListener<E>): this;
55
+ emit<E extends keyof ServerEventMap>(event: E, ...args: ServerEventMap[E]): this;
56
+ protected handleRPC(ws: ServerWebSocket<SocketData>, payload: Payload): Promise<void>;
57
+ /** Enrich context with derived values */
58
+ protected enrichContext(context: BaseContext): Promise<Context>;
59
+ /** Merge other Ultra instance with deduplication */
60
+ protected merge(module: Ultra<any, any, any>): void;
61
+ /** Wrap procedure handler with global middlewares */
62
+ protected wrapHandler(handler: ProcedureHandler<any, any, any>): ProcedureHandler<any, any, any>;
63
+ /** Build flat map from procedures tree and write handles map */
64
+ protected buildProcedures(): Map<string, Procedure<any, any, Context>>;
65
+ /** Build Bun native HTTP routes */
66
+ protected buildRoutes(procedures: Map<string, Procedure<any, any, Context>>): BunRoutes;
67
+ }
68
+ //#endregion
69
+ export { Ultra as n, ProceduresMap as t };
package/dist/ultra.d.mts CHANGED
@@ -1,69 +1,5 @@
1
- import { n as DefaultSocketData, t as BaseContext } from "./context-ChCsZh7S.mjs";
2
- import { o as Promisable } from "./types-Cn69QrjS.mjs";
3
- import { n as BunRoutes } from "./http-BqWCMASL.mjs";
4
- import { c as StandardSchemaV1 } from "./validation-CkRfxQJ_.mjs";
5
- import { a as ProcedureHandler, i as Procedure, t as Middleware } from "./middleware-COKreBGP.mjs";
6
- import { n as Payload } from "./rpc-Ch2UXReT.mjs";
7
- import { BunRequest, ErrorLike, Server, ServerWebSocket } from "bun";
8
-
9
- //#region src/ultra.d.ts
10
- interface ProceduresMap {
11
- [key: string]: Procedure<any, any, any> | ProceduresMap;
12
- }
13
- interface ServerEventMap<SocketData extends DefaultSocketData = DefaultSocketData> {
14
- 'error': [ErrorLike];
15
- 'unhandled:error': [ErrorLike];
16
- 'http:request': [BunRequest, Server<SocketData>];
17
- 'ws:open': [ServerWebSocket<SocketData>];
18
- 'ws:message': [ServerWebSocket<SocketData>, string | Buffer<ArrayBuffer>];
19
- 'ws:close': [ServerWebSocket<SocketData>, number, string];
20
- 'server:started': [Server<SocketData>];
21
- 'server:stopped': [Server<SocketData>, closeActiveConnections: boolean];
22
- }
23
- type ServerEventListener<K extends keyof ServerEventMap> = (...args: ServerEventMap[K]) => any;
24
- type DeriveFunction<C extends BaseContext> = (context: C) => Promisable<Record<PropertyKey, any>>;
25
- type DeriveValue<C extends BaseContext> = DeriveFunction<C> | Record<PropertyKey, any>;
26
- type ExtractDerive<C extends BaseContext, T extends DeriveValue<C>> = T extends DeriveFunction<C> ? Awaited<ReturnType<T>> : T;
27
- type StartOptions<SocketData extends DefaultSocketData> = Omit<Partial<Bun.Serve.Options<SocketData>>, 'websocket' | 'error' | 'routes'>;
28
- interface UltraOptions {
29
- http: boolean;
30
- }
31
- type InputFactory<C extends BaseContext> = <I>(schema?: StandardSchemaV1<I>) => Procedure<I, unknown, C>;
32
- type ProcedureMapInitializer<R extends ProceduresMap, C extends BaseContext = BaseContext> = (input: InputFactory<C>) => R;
33
- declare class Ultra<Procedures extends ProceduresMap = ProceduresMap, Context extends BaseContext = BaseContext, SocketData extends DefaultSocketData = DefaultSocketData> {
34
- protected readonly initializers: Set<ProcedureMapInitializer<any, Context>>;
35
- protected readonly handlers: Map<string, ProcedureHandler<any, any, Context>>;
36
- protected readonly events: Map<keyof ServerEventMap<SocketData>, Set<ServerEventListener<any>>>;
37
- protected readonly middlewares: Set<Middleware<any, any, Context>>;
38
- protected readonly derived: Set<DeriveValue<Context>>;
39
- protected readonly derivedWS: Set<DeriveValue<Context>>;
40
- protected readonly options: UltraOptions;
41
- protected server?: Server<SocketData>;
42
- constructor(options?: Partial<UltraOptions>);
43
- /** Register procedures */
44
- routes<const P extends ProceduresMap>(initializer: ProcedureMapInitializer<P, Context>): Ultra<Procedures & P, Context, SocketData>;
45
- /** Register middleware or another Ultra instance */
46
- use<const PluginProcedures extends ProceduresMap, const PluginContext extends BaseContext, const PluginSocketData extends DefaultSocketData>(entity: Middleware<any, any, Context> | Ultra<PluginProcedures, PluginContext, PluginSocketData>): Ultra<Procedures & PluginProcedures, Context & PluginContext, SocketData & PluginSocketData>;
47
- /** Extends context values for every request with provided values */
48
- derive<const D extends DeriveValue<Context>>(derive: D): Ultra<Procedures, Context & ExtractDerive<Context, D>, SocketData>;
49
- /** Extends WS data for every ws connection */
50
- deriveWS<const D extends DeriveValue<Context>>(derive: D): Ultra<Procedures, Context, SocketData & ExtractDerive<Context, D>>;
51
- start(options?: StartOptions<SocketData>): Server<SocketData>;
52
- stop(closeActiveConnections?: boolean): Promise<void>;
53
- on<E extends keyof ServerEventMap>(event: E, listener: ServerEventListener<E>): this;
54
- off<E extends keyof ServerEventMap>(event: E, listener: ServerEventListener<E>): this;
55
- emit<E extends keyof ServerEventMap>(event: E, ...args: ServerEventMap[E]): this;
56
- protected handleRPC(ws: ServerWebSocket<SocketData>, payload: Payload): Promise<void>;
57
- /** Enrich context with derived values */
58
- protected enrichContext(context: BaseContext): Promise<Context>;
59
- /** Merge other Ultra instance with deduplication */
60
- protected merge(module: Ultra<any, any, any>): void;
61
- /** Wrap procedure handler with global middlewares */
62
- protected wrapHandler(handler: ProcedureHandler<any, any, any>): ProcedureHandler<any, any, any>;
63
- /** Build flat map from procedures tree and write handles map */
64
- protected buildProcedures(): Map<string, Procedure<any, any, Context>>;
65
- /** Build Bun native HTTP routes */
66
- protected buildRoutes(procedures: Map<string, Procedure<any, any, Context>>): BunRoutes;
67
- }
68
- //#endregion
1
+ import "./context-BZAzgugo.mjs";
2
+ import "./http-NhhQxMv8.mjs";
3
+ import "./middleware-DB4PWjb4.mjs";
4
+ import { n as Ultra, t as ProceduresMap } from "./ultra-Dawe5ndl.mjs";
69
5
  export { ProceduresMap, Ultra };
package/dist/ultra.mjs CHANGED
@@ -1 +1 @@
1
- import{t as e}from"./procedure-DRzVmxaT.mjs";import{n as t,t as n}from"./response-CnnOFeUL.mjs";import{t as r}from"./rpc-CAwkzxZe.mjs";import{serve as i}from"bun";var a=class{initializers=new Set;handlers=new Map;events=new Map;middlewares=new Set;derived=new Set;derivedWS=new Set;options={http:!0};server;constructor(e){Object.assign(this.options,e)}routes(e){return this.initializers.add(e),this}use(e){return typeof e==`function`?(this.middlewares.add(e),this):(this.merge(e),this)}derive(e){return this.derived.add(e),this}deriveWS(e){return this.derivedWS.add(e),this}start(e){if(this.server)return console.warn(`Server is already running`),this.server;let t=this.buildProcedures(),n=this.wrapHandler(()=>new Response(`Not Found`,{status:404}));return this.server=i({...e??{},routes:{...this.options.http&&{...this.buildRoutes(t),"/*":async(e,t)=>(this.emit(`http:request`,e,t),n({input:null,context:this.derived.size?await this.enrichContext({server:t,request:e}):{server:t,request:e}}))},"/ws":async(e,t)=>{if(this.derivedWS.size){let n={},r=this.derived.size?await this.enrichContext({server:t,request:e}):{server:t,request:e};for(let e of this.derivedWS)Object.assign(n,typeof e==`function`?await e(r):e);t.upgrade(e,{data:n});return}t.upgrade(e)}},websocket:{open:e=>{this.emit(`ws:open`,e)},close:(e,t,n)=>{this.emit(`ws:close`,e,t,n)},message:(e,t)=>{if(this.emit(`ws:message`,e,t),typeof t!=`string`)return;let n=JSON.parse(t);r(n)&&this.handleRPC(e,n)}},error:e=>(this.emit(`unhandled:error`,e),console.error(`Unhandled server error:`,e),new Response(`Internal Server Error`,{status:500}))}),this.emit(`server:started`,this.server),this.server}async stop(e=!1){if(!this.server)return console.error(`Server is not running`);await this.server.stop(e),this.emit(`server:stopped`,this.server,e)}on(e,t){return this.events.has(e)||this.events.set(e,new Set),this.events.get(e).add(t),this}off(e,t){return this.events.get(e)?.delete(t),this}emit(e,...t){return this.events.get(e)?.forEach(e=>e(...t)),this}async handleRPC(e,n){let r=this.handlers.get(n.method);if(!r){e.send(`{"id": "${n.id}", "error": {"code": 404, "message": "Not found"}}`);return}try{e.send(t(n.id,await r({input:n.params,context:await this.enrichContext({server:this.server,ws:e})})))}catch(r){this.emit(`error`,r),e.send(t(n.id,r))}}async enrichContext(e){for(let t of this.derived)Object.assign(e,typeof t==`function`?await t(e):t);return e}merge(e){e.initializers.forEach(e=>this.initializers.add(e)),e.derived.forEach(e=>this.derived.add(e)),e.derivedWS.forEach(e=>this.derivedWS.add(e)),e.middlewares.forEach(e=>this.middlewares.add(e)),e.events.forEach((e,t)=>{this.events.has(t)||this.events.set(t,new Set);let n=this.events.get(t);e.forEach(e=>n.add(e))})}wrapHandler(e){if(!this.middlewares.size)return e;let t=Array.from(this.middlewares);return async n=>{let r=0,i=()=>r===t.length?e(n):t[r++]({...n,next:i});return i()}}buildProcedures(){let t=new Map,n=t=>{let n=new e;return t?n.input(t):n};for(let r of this.initializers){let i=r(n),a=[];for(let[e,t]of Object.entries(i))a.push({path:e,value:t});for(;a.length;){let{path:n,value:r}=a.pop();if(r instanceof e){if(t.has(n))throw Error(`Procedure conflict at path "${n}"`);t.set(n,r),this.handlers.set(n,this.wrapHandler(r.wrap()));continue}for(let[e,t]of Object.entries(r)){let r=n?`${n}/${e}`:e;a.push({path:r,value:t})}}}return t}buildRoutes(e){let t={};for(let[r,i]of e){let e=i.getInfo();if(!e.http?.enabled)continue;let a=`/${r}`,o=this.handlers.get(r);if(!o)throw Error(`Handler for procedure at path "${r}" is not defined`);let s=async(t,i)=>{this.emit(`http:request`,t,i);let a=t.body,s={server:i,request:t},c=this.derived.size?await this.enrichContext(s):s;if(a&&e.hasInput){if(t.method===`GET`){let e=t.url.indexOf(`?`);e!==-1&&e<t.url.length-1&&(a=Object.fromEntries(new URLSearchParams(t.url.slice(e+1)).entries()))}else if(t.headers.get(`Content-Length`)!==`0`){let e=t.headers.get(`Content-Type`);if(e)switch(!0){case e.startsWith(`application/json`):a=await t.json();break;case e.startsWith(`text`):a=await t.text();break;case e.startsWith(`multipart/form-data`):a=await t.formData();break;default:console.error(`Unsupported Content-Type for procedure ${r}: ${e}`);break}}}try{return n(await o({input:a,context:c}))}catch(e){return this.emit(`error`,e),n(e)}};if(!e.http.method){t[a]=s;continue}t[a]||(t[a]={}),t[a][e.http.method]=s}return t}};export{a as Ultra};
1
+ import{n as e,t}from"./response-D935Hx3o.mjs";import{t as n}from"./procedure-AntXykJT.mjs";import{t as r}from"./rpc-CAwkzxZe.mjs";import{serve as i}from"bun";var a=class{initializers=new Set;handlers=new Map;events=new Map;middlewares=new Set;derived=new Set;derivedWS=new Set;options={http:!0};server;constructor(e){Object.assign(this.options,e)}routes(e){return this.initializers.add(e),this}use(e){return typeof e==`function`?(this.middlewares.add(e),this):(this.merge(e),this)}derive(e){return this.derived.add(e),this}deriveWS(e){return this.derivedWS.add(e),this}start(e){if(this.server)return console.warn(`Server is already running`),this.server;let t=this.buildProcedures(),n=this.wrapHandler(()=>new Response(`Not Found`,{status:404}));return this.server=i({...e??{},routes:{...this.options.http&&{...this.buildRoutes(t),"/*":async(e,t)=>(this.emit(`http:request`,e,t),n({input:null,context:this.derived.size?await this.enrichContext({server:t,request:e}):{server:t,request:e}}))},"/ws":async(e,t)=>{if(this.derivedWS.size){let n={},r=this.derived.size?await this.enrichContext({server:t,request:e}):{server:t,request:e};for(let e of this.derivedWS)Object.assign(n,typeof e==`function`?await e(r):e);t.upgrade(e,{data:n});return}t.upgrade(e)}},websocket:{open:e=>{this.emit(`ws:open`,e)},close:(e,t,n)=>{this.emit(`ws:close`,e,t,n)},message:(e,t)=>{if(this.emit(`ws:message`,e,t),typeof t!=`string`)return;let n=JSON.parse(t);r(n)&&this.handleRPC(e,n)}},error:e=>(this.emit(`unhandled:error`,e),console.error(`Unhandled server error:`,e),new Response(`Internal Server Error`,{status:500}))}),this.emit(`server:started`,this.server),this.server}async stop(e=!1){if(!this.server)return console.error(`Server is not running`);await this.server.stop(e),this.emit(`server:stopped`,this.server,e)}on(e,t){return this.events.has(e)||this.events.set(e,new Set),this.events.get(e).add(t),this}off(e,t){return this.events.get(e)?.delete(t),this}emit(e,...t){return this.events.get(e)?.forEach(e=>e(...t)),this}async handleRPC(t,n){let r=this.handlers.get(n.method);if(!r){t.send(`{"id": "${n.id}", "error": {"code": 404, "message": "Not found"}}`);return}try{t.send(e(n.id,await r({input:n.params,context:await this.enrichContext({server:this.server,ws:t})})))}catch(r){this.emit(`error`,r),t.send(e(n.id,r))}}async enrichContext(e){for(let t of this.derived)Object.assign(e,typeof t==`function`?await t(e):t);return e}merge(e){e.initializers.forEach(e=>this.initializers.add(e)),e.derived.forEach(e=>this.derived.add(e)),e.derivedWS.forEach(e=>this.derivedWS.add(e)),e.middlewares.forEach(e=>this.middlewares.add(e)),e.events.forEach((e,t)=>{this.events.has(t)||this.events.set(t,new Set);let n=this.events.get(t);e.forEach(e=>n.add(e))})}wrapHandler(e){if(!this.middlewares.size)return e;let t=Array.from(this.middlewares);return async n=>{let r=0,i=()=>r===t.length?e(n):t[r++]({...n,next:i});return i()}}buildProcedures(){let e=new Map,t=e=>{let t=new n;return e?t.input(e):t};for(let r of this.initializers){let i=r(t),a=[];for(let[e,t]of Object.entries(i))a.push({path:e,value:t});for(;a.length;){let{path:t,value:r}=a.pop();if(r instanceof n){if(e.has(t))throw Error(`Procedure conflict at path "${t}"`);e.set(t,r),this.handlers.set(t,this.wrapHandler(r.wrap()));continue}for(let[e,n]of Object.entries(r)){let r=t?`${t}/${e}`:e;a.push({path:r,value:n})}}}return e}buildRoutes(e){let n={};for(let[r,i]of e){let e=i.getInfo();if(!e.http?.enabled)continue;let a=`/${r}`,o=this.handlers.get(r);if(!o)throw Error(`Handler for procedure at path "${r}" is not defined`);let s=async(n,i)=>{this.emit(`http:request`,n,i);let a=n.body,s={server:i,request:n},c=this.derived.size?await this.enrichContext(s):s;if(a&&e.hasInput){if(n.method===`GET`){let e=n.url.indexOf(`?`);e!==-1&&e<n.url.length-1&&(a=Object.fromEntries(new URLSearchParams(n.url.slice(e+1)).entries()))}else if(n.headers.get(`Content-Length`)!==`0`){let e=n.headers.get(`Content-Type`);if(e)switch(!0){case e.startsWith(`application/json`):a=await n.json();break;case e.startsWith(`text`):a=await n.text();break;case e.startsWith(`multipart/form-data`):a=await n.formData();break;default:console.error(`Unsupported Content-Type for procedure ${r}: ${e}`);break}}}try{return t(await o({input:a,context:c}))}catch(e){return this.emit(`error`,e),t(e)}};if(!e.http.method){n[a]=s;continue}n[a]||(n[a]={}),n[a][e.http.method]=s}return n}};export{a as Ultra};
@@ -1 +1 @@
1
- import{t as e}from"./validation-BY5LC99k.mjs";export{e as validate};
1
+ import{t as e}from"./validation-dJpfcBud.mjs";export{e as validate};
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@sx3/ultra",
3
3
  "type": "module",
4
- "version": "0.0.2",
4
+ "version": "0.0.4",
5
5
  "private": false,
6
6
  "description": "Type-safe RPC over HTTP/WebSocket for Bun",
7
7
  "author": "SX3",