@mionjs/client 0.8.0-alpha.0 → 0.8.4-alpha.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/.dist/cjs/_virtual/jit-fns.cjs +57 -53
- package/.dist/cjs/_virtual/jit-fns.cjs.map +1 -1
- package/.dist/cjs/_virtual/router-cache.cjs +1 -1
- package/.dist/cjs/index.cjs +1 -1
- package/.dist/cjs/index.d.ts +7 -6
- package/.dist/cjs/src/aot/aotCaches.cjs +2 -0
- package/.dist/cjs/src/aot/aotCaches.cjs.map +1 -0
- package/.dist/cjs/src/aot/aotCaches.d.ts +5 -0
- package/.dist/cjs/src/client.cjs +1 -1
- package/.dist/cjs/src/client.cjs.map +1 -1
- package/.dist/cjs/src/client.d.ts +1 -1
- package/.dist/cjs/src/constants.cjs.map +1 -1
- package/.dist/cjs/src/lib/clientMethodsMetadata.cjs +2 -0
- package/.dist/cjs/src/lib/clientMethodsMetadata.cjs.map +1 -0
- package/.dist/cjs/src/{clientMethodsMetadata.d.ts → lib/clientMethodsMetadata.d.ts} +1 -5
- package/.dist/cjs/src/{handlersRegistry.cjs → lib/handlersRegistry.cjs} +1 -1
- package/.dist/cjs/src/lib/handlersRegistry.cjs.map +1 -0
- package/.dist/cjs/src/{handlersRegistry.d.ts → lib/handlersRegistry.d.ts} +1 -1
- package/.dist/cjs/src/lib/serializer.cjs +2 -0
- package/.dist/cjs/src/lib/serializer.cjs.map +1 -0
- package/.dist/{esm/src → cjs/src/lib}/serializer.d.ts +1 -4
- package/.dist/cjs/src/lib/storage.cjs +2 -0
- package/.dist/cjs/src/lib/storage.cjs.map +1 -0
- package/.dist/cjs/src/lib/testUtils.cjs +2 -0
- package/.dist/cjs/src/lib/testUtils.cjs.map +1 -0
- package/.dist/cjs/src/lib/typedEvent.cjs +2 -0
- package/.dist/cjs/src/lib/typedEvent.cjs.map +1 -0
- package/.dist/{esm/src → cjs/src/lib}/typedEvent.d.ts +1 -1
- package/.dist/cjs/src/lib/validation.cjs +2 -0
- package/.dist/cjs/src/lib/validation.cjs.map +1 -0
- package/.dist/cjs/src/{validation.d.ts → lib/validation.d.ts} +2 -2
- package/.dist/cjs/src/request.cjs +1 -1
- package/.dist/cjs/src/request.cjs.map +1 -1
- package/.dist/cjs/src/routesFlow.cjs +1 -1
- package/.dist/cjs/src/routesFlow.cjs.map +1 -1
- package/.dist/cjs/src/subRequest.cjs +1 -1
- package/.dist/cjs/src/subRequest.cjs.map +1 -1
- package/.dist/cjs/src/subRequest.d.ts +1 -1
- package/.dist/cjs/src/types.cjs +1 -1
- package/.dist/cjs/src/types.d.ts +1 -38
- package/.dist/esm/_virtual/jit-fns.js +138 -134
- package/.dist/esm/_virtual/jit-fns.js.map +1 -1
- package/.dist/esm/_virtual/router-cache.js +1 -1
- package/.dist/esm/index.d.ts +7 -6
- package/.dist/esm/index.js +8 -47
- package/.dist/esm/src/aot/aotCaches.d.ts +5 -0
- package/.dist/esm/src/aot/aotCaches.js +16 -0
- package/.dist/esm/src/aot/aotCaches.js.map +1 -0
- package/.dist/esm/src/client.d.ts +1 -1
- package/.dist/esm/src/client.js +13 -44
- package/.dist/esm/src/client.js.map +1 -1
- package/.dist/esm/src/constants.js.map +1 -1
- package/.dist/esm/src/{clientMethodsMetadata.d.ts → lib/clientMethodsMetadata.d.ts} +1 -5
- package/.dist/esm/src/{clientMethodsMetadata.js → lib/clientMethodsMetadata.js} +16 -36
- package/.dist/esm/src/lib/clientMethodsMetadata.js.map +1 -0
- package/.dist/esm/src/{handlersRegistry.d.ts → lib/handlersRegistry.d.ts} +1 -1
- package/.dist/esm/src/{handlersRegistry.js → lib/handlersRegistry.js} +0 -5
- package/.dist/esm/src/lib/handlersRegistry.js.map +1 -0
- package/.dist/{cjs/src → esm/src/lib}/serializer.d.ts +1 -4
- package/.dist/esm/src/{serializer.js → lib/serializer.js} +5 -22
- package/.dist/esm/src/lib/serializer.js.map +1 -0
- package/.dist/esm/src/{storage.js → lib/storage.js} +1 -6
- package/.dist/esm/src/lib/storage.js.map +1 -0
- package/.dist/esm/src/{testUtils.js → lib/testUtils.js} +2 -5
- package/.dist/esm/src/lib/testUtils.js.map +1 -0
- package/.dist/{cjs/src → esm/src/lib}/typedEvent.d.ts +1 -1
- package/.dist/esm/src/{typedEvent.js → lib/typedEvent.js} +0 -2
- package/.dist/esm/src/lib/typedEvent.js.map +1 -0
- package/.dist/esm/src/{validation.d.ts → lib/validation.d.ts} +2 -2
- package/.dist/esm/src/{validation.js → lib/validation.js} +3 -10
- package/.dist/esm/src/lib/validation.js.map +1 -0
- package/.dist/esm/src/request.js +24 -36
- package/.dist/esm/src/request.js.map +1 -1
- package/.dist/esm/src/routesFlow.js +4 -9
- package/.dist/esm/src/routesFlow.js.map +1 -1
- package/.dist/esm/src/subRequest.d.ts +1 -1
- package/.dist/esm/src/subRequest.js +6 -15
- package/.dist/esm/src/subRequest.js.map +1 -1
- package/.dist/esm/src/types.d.ts +1 -38
- package/.dist/esm/src/types.js +1 -41
- package/.dist/esm/src/types.js.map +1 -1
- package/package.json +7 -13
- package/.dist/cjs/src/aot/loadClientAOTCaches.cjs +0 -2
- package/.dist/cjs/src/aot/loadClientAOTCaches.cjs.map +0 -1
- package/.dist/cjs/src/aot/loadClientAOTCaches.d.ts +0 -8
- package/.dist/cjs/src/clientMethodsMetadata.cjs +0 -2
- package/.dist/cjs/src/clientMethodsMetadata.cjs.map +0 -1
- package/.dist/cjs/src/handlersRegistry.cjs.map +0 -1
- package/.dist/cjs/src/serializer.cjs +0 -2
- package/.dist/cjs/src/serializer.cjs.map +0 -1
- package/.dist/cjs/src/storage.cjs +0 -2
- package/.dist/cjs/src/storage.cjs.map +0 -1
- package/.dist/cjs/src/testUtils.cjs +0 -2
- package/.dist/cjs/src/testUtils.cjs.map +0 -1
- package/.dist/cjs/src/typedEvent.cjs +0 -2
- package/.dist/cjs/src/typedEvent.cjs.map +0 -1
- package/.dist/cjs/src/validation.cjs +0 -2
- package/.dist/cjs/src/validation.cjs.map +0 -1
- package/.dist/esm/src/aot/loadClientAOTCaches.d.ts +0 -8
- package/.dist/esm/src/aot/loadClientAOTCaches.js +0 -19
- package/.dist/esm/src/aot/loadClientAOTCaches.js.map +0 -1
- package/.dist/esm/src/clientMethodsMetadata.js.map +0 -1
- package/.dist/esm/src/handlersRegistry.js.map +0 -1
- package/.dist/esm/src/serializer.js.map +0 -1
- package/.dist/esm/src/storage.js.map +0 -1
- package/.dist/esm/src/testUtils.js.map +0 -1
- package/.dist/esm/src/typedEvent.js.map +0 -1
- package/.dist/esm/src/validation.js.map +0 -1
- /package/.dist/cjs/src/{storage.d.ts → lib/storage.d.ts} +0 -0
- /package/.dist/cjs/src/{testUtils.d.ts → lib/testUtils.d.ts} +0 -0
- /package/.dist/esm/src/{storage.d.ts → lib/storage.d.ts} +0 -0
- /package/.dist/esm/src/{testUtils.d.ts → lib/testUtils.d.ts} +0 -0
package/.dist/cjs/src/client.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const src_constants=require("./constants.cjs"),
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const src_constants=require("./constants.cjs"),core=require("@mionjs/core"),src_request=require("./request.cjs"),src_lib_handlersRegistry=require("./lib/handlersRegistry.cjs"),src_subRequest=require("./subRequest.cjs"),src_aot_aotCaches=require("./aot/aotCaches.cjs");function initClient(options){src_aot_aotCaches.loadAOTCaches(),core.registerErrorDeserializers();const clientOptions={...src_constants.DEFAULT_PREFILL_OPTIONS,...options},client=new MionClient(clientOptions),rootProxy=new MethodProxy([],client,clientOptions);return{client,routes:rootProxy.proxy,middleFns:rootProxy.proxy}}class MionClient{clientOptions;handlersRegistry=new src_lib_handlersRegistry.HandlersRegistry;prefilledMiddleFnsCache=new Map;pendingPrefills=[];constructor(clientOptions){this.clientOptions=clientOptions}executeCall(routeSubRequest){return this.executeRequest(routeSubRequest,void 0,void 0)}executeCallWithMiddleFns(routeSubRequest,middleFnsRecord){return this.executeRequest(routeSubRequest,void 0,middleFnsRecord)}executeCallWithWorkflow(workflowSubRequests,middleFnsRecord){return this.executeRequest(void 0,workflowSubRequests,middleFnsRecord)}async executeRequest(routeSubRequest,workflowSubRequests,middleFnsRecord){this.pendingPrefills.length>0&&await Promise.allSettled([...this.pendingPrefills]);const middleFnSubRequests=middleFnsRecord?Object.values(middleFnsRecord):[],request=new src_request.MionClientRequest(this.clientOptions,this.prefilledMiddleFnsCache,routeSubRequest,middleFnSubRequests,workflowSubRequests);try{await request.call();const routeIds=this.getRouteIds(routeSubRequest,workflowSubRequests),allMiddleFns=this.getAllMiddleFnsFromRequest(request,routeIds);return this.processMiddleFnsResponses(allMiddleFns,void 0),this.buildResult(routeSubRequest,workflowSubRequests,middleFnsRecord||allMiddleFns,void 0)}catch(errors){const routeIds=this.getRouteIds(routeSubRequest,workflowSubRequests),allMiddleFns=this.getAllMiddleFnsFromRequest(request,routeIds);return this.processMiddleFnsResponses(allMiddleFns,errors),this.buildResult(routeSubRequest,workflowSubRequests,middleFnsRecord||allMiddleFns,errors)}}getRouteIds(routeSubRequest,workflowSubRequests){const routeIds=new Set;return routeSubRequest&&routeIds.add(routeSubRequest.id),workflowSubRequests&&workflowSubRequests.forEach(sr=>routeIds.add(sr.id)),routeIds}getAllMiddleFnsFromRequest(request,excludedIds){return Object.entries(request.subRequestList).filter(([id])=>!excludedIds.has(id)).map(([,subRequest])=>subRequest)}processMiddleFnsResponses(middleFnSubRequests,errors){for(const middleFn of middleFnSubRequests){const middleFnError=errors?.get(middleFn.id);middleFnError?this.handlersRegistry.executeHandler(middleFn.id,middleFnError):middleFn.resolvedValue!==void 0&&this.handlersRegistry.executeSuccessHandler(middleFn.id,middleFn.resolvedValue)}}buildResult(routeSubRequest,workflowSubRequests,middleFns,errors){const middleFnsResults={},middleFnsErrors={},processedIds=new Set;let routeResultPart,routeErrorPart;if(routeSubRequest){processedIds.add(routeSubRequest.id);const routeError=errors?.get(routeSubRequest.id)||(errors?src_subRequest.findSubRequestError(routeSubRequest,errors):void 0);routeResultPart=routeError?void 0:routeSubRequest.resolvedValue,routeErrorPart=routeError}else if(workflowSubRequests){const routeResults=[],routeErrors=[];for(const routeSubRequest2 of workflowSubRequests){processedIds.add(routeSubRequest2.id);const routeError=errors?.get(routeSubRequest2.id);routeError?(routeResults.push(void 0),routeErrors.push(routeError)):(routeResults.push(routeSubRequest2.resolvedValue),routeErrors.push(void 0))}const hasAnyResult=routeResults.some(r=>r!==void 0),hasAnyError=routeErrors.some(e=>e!==void 0);routeResultPart=hasAnyResult?routeResults:void 0,routeErrorPart=hasAnyError?routeErrors:void 0}if(Array.isArray(middleFns))for(const middleFn of middleFns){processedIds.add(middleFn.id);const middleFnError=errors?.get(middleFn.id);middleFnError?middleFnsErrors[middleFn.id]=middleFnError:middleFn.resolvedValue!==void 0&&(middleFnsResults[middleFn.id]=middleFn.resolvedValue)}else for(const[name,middleFn]of Object.entries(middleFns)){processedIds.add(middleFn.id);const middleFnError=errors?.get(middleFn.id);middleFnError?middleFnsErrors[name]=middleFnError:middleFn.resolvedValue!==void 0&&(middleFnsResults[name]=middleFn.resolvedValue)}if(errors)for(const[id,error]of errors)processedIds.has(id)||(middleFnsErrors[id]=error);return[routeResultPart,routeErrorPart,middleFnsResults,middleFnsErrors]}typeErrors(...subRequest){return new src_request.MionClientRequest(this.clientOptions,this.prefilledMiddleFnsCache).validateParams(subRequest)}prefill(...subRequest){const promise=new src_request.MionClientRequest(this.clientOptions,this.prefilledMiddleFnsCache).prefill(subRequest);return this.pendingPrefills.push(promise),promise.finally(()=>{const index=this.pendingPrefills.indexOf(promise);index>=0&&this.pendingPrefills.splice(index,1)}),promise}removePrefill(...subRequest){return new src_request.MionClientRequest(this.clientOptions,this.prefilledMiddleFnsCache).removePrefill(subRequest)}destroy(){this.handlersRegistry.clearAll()}}class MethodProxy{parentProps;client;clientOptions;propsProxies={};handler={apply:(_target,_thisArg,argArray)=>{const handlerId=core.getRouterItemId(this.parentProps);return new src_subRequest.MionSubRequest(this.parentProps,handlerId,argArray,this.client)},get:(_target,prop)=>{const existing=this.propsProxies[prop];if(existing)return existing.proxy;const newMethodProxy=new MethodProxy([...this.parentProps,prop],this.client,this.clientOptions);return this.propsProxies[prop]=newMethodProxy,newMethodProxy.proxy}};proxy;constructor(parentProps,client,clientOptions){this.parentProps=parentProps,this.client=client,this.clientOptions=clientOptions;const target=()=>null;this.proxy=new Proxy(target,this.handler)}}exports.MionClient=MionClient;exports.initClient=initClient;
|
|
2
2
|
//# sourceMappingURL=client.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
|
1
|
+
{"version":3,"file":"client.cjs","sources":["../../../src/client.ts"],"sourcesContent":["/* ########\n * 2023 mion\n * Author: Ma-jerez\n * License: MIT\n * The software is provided \"as is\", without warranty of any kind.\n * ######## */\n\nimport {DEFAULT_PREFILL_OPTIONS} from './constants.ts';\nimport {\n CallWithMiddleFnsResult,\n ClientOptions,\n HSubRequest,\n InitClientOptions,\n RSubRequest,\n SubRequest,\n RequestErrors,\n ClientRoutes,\n ClientMiddleFns,\n Result,\n WorkflowResult,\n} from './types.ts';\nimport type {RemoteApi} from '@mionjs/router';\nimport {registerErrorDeserializers} from '@mionjs/core';\nimport {getRouterItemId} from '@mionjs/core';\nimport {MionClientRequest} from './request.ts';\nimport type {RunTypeError} from '@mionjs/core';\nimport {HandlersRegistry} from './lib/handlersRegistry.ts';\nimport {MionSubRequest, findSubRequestError} from './subRequest.ts';\nimport {loadAOTCaches} from './aot/aotCaches.ts';\n\nexport function initClient<RM extends RemoteApi>(\n options: InitClientOptions\n): {client: MionClient; routes: ClientRoutes<RM>; middleFns: ClientMiddleFns<RM>} {\n loadAOTCaches();\n registerErrorDeserializers();\n const clientOptions = {\n ...DEFAULT_PREFILL_OPTIONS,\n ...options,\n };\n const client = new MionClient(clientOptions);\n const rootProxy = new MethodProxy([], client, clientOptions);\n return {\n client,\n routes: rootProxy.proxy as ClientRoutes<RM>,\n middleFns: rootProxy.proxy as ClientMiddleFns<RM>,\n };\n}\n\nexport class MionClient {\n /** Shared registry for persistent middleFn error handlers */\n readonly handlersRegistry = new HandlersRegistry();\n\n /** In-memory cache for prefilled middleFn subrequests (keyed by baseURL:middleFnId) */\n readonly prefilledMiddleFnsCache = new Map<string, SubRequest<any>>();\n\n /** Tracks in-flight prefill operations to avoid race conditions */\n private pendingPrefills: Promise<void>[] = [];\n\n constructor(private clientOptions: ClientOptions) {}\n\n /** Executes a route call and returns a Result 4-tuple */\n executeCall<RR extends RSubRequest<any>>(routeSubRequest: RR): Promise<Result<any, any>> {\n return this.executeRequest(routeSubRequest, undefined, undefined);\n }\n\n /** Executes a route call with middleFns and returns a typed result object */\n executeCallWithMiddleFns<H extends Record<string, HSubRequest<any>>>(\n routeSubRequest: RSubRequest<any>,\n middleFnsRecord: H\n ): Promise<CallWithMiddleFnsResult<any, any, H>> {\n return this.executeRequest(routeSubRequest, undefined, middleFnsRecord);\n }\n\n /** Executes a routesFlow call with multiple routes and optional middleFns */\n executeCallWithWorkflow<Routes extends RSubRequest<any>[], H extends Record<string, HSubRequest<any>>>(\n workflowSubRequests: Routes,\n middleFnsRecord: H\n ): Promise<WorkflowResult<Routes, H>> {\n return this.executeRequest(undefined, workflowSubRequests, middleFnsRecord);\n }\n\n private async executeRequest<Routes extends RSubRequest<any>[], H extends Record<string, HSubRequest<any>>>(\n routeSubRequest: RSubRequest<any> | undefined,\n workflowSubRequests: Routes | undefined,\n middleFnsRecord: H | undefined\n ): Promise<any> {\n // Wait for any in-flight prefill operations to complete before executing the request\n if (this.pendingPrefills.length > 0) await Promise.allSettled([...this.pendingPrefills]);\n\n const middleFnSubRequests = middleFnsRecord ? Object.values(middleFnsRecord) : [];\n const request = new MionClientRequest(\n this.clientOptions,\n this.prefilledMiddleFnsCache,\n routeSubRequest,\n middleFnSubRequests,\n workflowSubRequests\n );\n\n try {\n await request.call();\n const routeIds = this.getRouteIds(routeSubRequest, workflowSubRequests);\n const allMiddleFns = this.getAllMiddleFnsFromRequest(request, routeIds);\n this.processMiddleFnsResponses(allMiddleFns, undefined);\n return this.buildResult(routeSubRequest, workflowSubRequests, middleFnsRecord || allMiddleFns, undefined);\n } catch (errors: any) {\n const routeIds = this.getRouteIds(routeSubRequest, workflowSubRequests);\n const allMiddleFns = this.getAllMiddleFnsFromRequest(request, routeIds);\n this.processMiddleFnsResponses(allMiddleFns, errors);\n return this.buildResult(routeSubRequest, workflowSubRequests, middleFnsRecord || allMiddleFns, errors);\n }\n }\n\n /** Get route IDs from single route or routesFlow routes */\n private getRouteIds(\n routeSubRequest: RSubRequest<any> | undefined,\n workflowSubRequests: RSubRequest<any>[] | undefined\n ): Set<string> {\n const routeIds = new Set<string>();\n if (routeSubRequest) routeIds.add(routeSubRequest.id);\n if (workflowSubRequests) workflowSubRequests.forEach((sr) => routeIds.add(sr.id));\n return routeIds;\n }\n\n /** Get all middleFns from the request's subRequestList, excluding the route(s) */\n private getAllMiddleFnsFromRequest(request: MionClientRequest<any, any>, excludedIds: Set<string>): HSubRequest<any>[] {\n return Object.entries(request.subRequestList)\n .filter(([id]) => !excludedIds.has(id))\n .map(([, subRequest]) => subRequest as HSubRequest<any>);\n }\n\n /** Process all middleFn responses - call success or error handlers for each middleFn individually */\n private processMiddleFnsResponses(middleFnSubRequests: HSubRequest<any>[], errors: RequestErrors | undefined): void {\n for (const middleFn of middleFnSubRequests) {\n const middleFnError = errors?.get(middleFn.id);\n if (middleFnError) {\n this.handlersRegistry.executeHandler(middleFn.id, middleFnError);\n } else if (middleFn.resolvedValue !== undefined) {\n this.handlersRegistry.executeSuccessHandler(middleFn.id, middleFn.resolvedValue);\n }\n }\n }\n\n /** Build the result 4-tuple from the request results. middleFns can be a named record or an array of subrequests */\n private buildResult<Routes extends RSubRequest<any>[], H extends Record<string, HSubRequest<any>>>(\n routeSubRequest: RSubRequest<any> | undefined,\n workflowSubRequests: Routes | undefined,\n middleFns: H | HSubRequest<any>[],\n errors: RequestErrors | undefined\n ): CallWithMiddleFnsResult<any, any, H> | WorkflowResult<Routes, H> | Result<any, any> {\n const middleFnsResults = {} as Record<string, any>;\n const middleFnsErrors = {} as Record<string, any>;\n const processedIds = new Set<string>();\n\n let routeResultPart: any;\n let routeErrorPart: any;\n\n if (routeSubRequest) {\n processedIds.add(routeSubRequest.id);\n const routeError =\n errors?.get(routeSubRequest.id) || (errors ? findSubRequestError(routeSubRequest, errors) : undefined);\n routeResultPart = routeError ? undefined : routeSubRequest.resolvedValue;\n routeErrorPart = routeError;\n } else if (workflowSubRequests) {\n const routeResults: (any | undefined)[] = [];\n const routeErrors: (any | undefined)[] = [];\n for (const routeSubRequest of workflowSubRequests) {\n processedIds.add(routeSubRequest.id);\n const routeError = errors?.get(routeSubRequest.id);\n if (routeError) {\n routeResults.push(undefined);\n routeErrors.push(routeError);\n } else {\n routeResults.push(routeSubRequest.resolvedValue);\n routeErrors.push(undefined);\n }\n }\n const hasAnyResult = routeResults.some((r) => r !== undefined);\n const hasAnyError = routeErrors.some((e) => e !== undefined);\n routeResultPart = hasAnyResult ? routeResults : undefined;\n routeErrorPart = hasAnyError ? routeErrors : undefined;\n }\n\n // middleFns can be a named record (from callWithMiddleFns/routesFlow) or an array (from executeCall)\n if (Array.isArray(middleFns)) {\n // Array of subrequests - use IDs as keys\n for (const middleFn of middleFns) {\n processedIds.add(middleFn.id);\n const middleFnError = errors?.get(middleFn.id);\n if (middleFnError) {\n middleFnsErrors[middleFn.id] = middleFnError;\n } else if (middleFn.resolvedValue !== undefined) {\n middleFnsResults[middleFn.id] = middleFn.resolvedValue;\n }\n }\n } else {\n // Named record - use names as keys\n for (const [name, middleFn] of Object.entries(middleFns)) {\n processedIds.add(middleFn.id);\n const middleFnError = errors?.get(middleFn.id);\n if (middleFnError) {\n middleFnsErrors[name] = middleFnError;\n } else if (middleFn.resolvedValue !== undefined) {\n middleFnsResults[name] = middleFn.resolvedValue;\n }\n }\n }\n\n if (errors) {\n for (const [id, error] of errors) {\n if (!processedIds.has(id)) {\n middleFnsErrors[id] = error;\n }\n }\n }\n\n return [routeResultPart, routeErrorPart, middleFnsResults, middleFnsErrors] as any;\n }\n\n typeErrors<List extends SubRequest<any>[]>(...subRequest: List): Promise<RunTypeError[]> {\n const request = new MionClientRequest(this.clientOptions, this.prefilledMiddleFnsCache);\n return request.validateParams(subRequest);\n }\n\n prefill<List extends HSubRequest<any>[]>(...subRequest: List): Promise<void> {\n const request = new MionClientRequest(this.clientOptions, this.prefilledMiddleFnsCache);\n const promise = request.prefill(subRequest);\n this.pendingPrefills.push(promise);\n promise.finally(() => {\n const index = this.pendingPrefills.indexOf(promise);\n if (index >= 0) this.pendingPrefills.splice(index, 1);\n });\n return promise;\n }\n\n removePrefill<List extends HSubRequest<any>[]>(...subRequest: List): Promise<void> {\n const request = new MionClientRequest(this.clientOptions, this.prefilledMiddleFnsCache);\n return request.removePrefill(subRequest);\n }\n\n /** Clear all error handlers from the registry */\n destroy(): void {\n this.handlersRegistry.clearAll();\n }\n}\n\nclass MethodProxy {\n propsProxies: Record<string, MethodProxy> = {};\n handler = {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n apply: (_target: any, _thisArg: any, argArray?: any): RSubRequest<any> & HSubRequest<any> => {\n const handlerId = getRouterItemId(this.parentProps);\n return new MionSubRequest(this.parentProps, handlerId, argArray, this.client);\n },\n\n get: (_target: any, prop: string): typeof Proxy => {\n const existing = this.propsProxies[prop];\n if (existing) return existing.proxy;\n const newMethodProxy = new MethodProxy([...this.parentProps, prop], this.client, this.clientOptions);\n this.propsProxies[prop] = newMethodProxy;\n return newMethodProxy.proxy;\n },\n };\n\n proxy: typeof Proxy;\n\n constructor(\n public parentProps: string[],\n private client: MionClient,\n private clientOptions: ClientOptions\n ) {\n const target = () => null;\n this.proxy = new Proxy(target, this.handler);\n }\n}\n"],"names":["loadAOTCaches","registerErrorDeserializers","DEFAULT_PREFILL_OPTIONS","HandlersRegistry","MionClientRequest","findSubRequestError","routeSubRequest","getRouterItemId","MionSubRequest"],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { CallWithMiddleFnsResult, ClientOptions, HSubRequest, InitClientOptions, RSubRequest, SubRequest, ClientRoutes, ClientMiddleFns, Result, WorkflowResult } from './types.ts';
|
|
2
2
|
import { RemoteApi } from '@mionjs/router';
|
|
3
3
|
import { RunTypeError } from '@mionjs/core';
|
|
4
|
-
import { HandlersRegistry } from './handlersRegistry.ts';
|
|
4
|
+
import { HandlersRegistry } from './lib/handlersRegistry.ts';
|
|
5
5
|
export declare function initClient<RM extends RemoteApi>(options: InitClientOptions): {
|
|
6
6
|
client: MionClient;
|
|
7
7
|
routes: ClientRoutes<RM>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
|
1
|
+
{"version":3,"file":"constants.cjs","sources":["../../../src/constants.ts"],"sourcesContent":["/* ########\n * 2022 mion\n * Author: Ma-jerez\n * License: MIT\n * The software is provided \"as is\", without warranty of any kind.\n * ######## */\n\nimport {ClientOptions} from './types.ts';\n\nexport const DEFAULT_PREFILL_OPTIONS: ClientOptions = {\n baseURL: '',\n fetchOptions: {\n method: 'PUT',\n headers: {'Content-Type': 'application/json'},\n },\n /** Prefix for all routes, i.e: api/v1 */\n basePath: '',\n /** Suffix for all routes, i.e: .json */\n suffix: '',\n /** Enables automatic parameter validation */\n validateParams: true,\n /** Set true to automatically generate and id for every error */\n autoGenerateErrorId: false,\n /** Default serializer mode - stringifyJson as default native serializer */\n serializer: 'stringifyJson',\n};\n\n/** Maximum safe URL length for GET requests with ?data= query param */\nexport const MAX_GET_URL_LENGTH = 4096;\n\nexport const STORAGE_KEY = 'mionkit:client';\n\n/** RoutesFlow route key - matches router constant */\nexport const ROUTES_FLOW_KEY = 'mion-routes-flow';\n\n/** RoutesFlow route path - matches router constant */\nexport const ROUTES_FLOW_PATH = `/${ROUTES_FLOW_KEY}`;\n"],"names":[],"mappings":"gFASO,MAAM,wBAAyC,CAClD,QAAS,GACT,aAAc,CACV,OAAQ,MACR,QAAS,CAAC,eAAgB,kBAAA,CAAkB,EAGhD,SAAU,GAEV,OAAQ,GAER,eAAgB,GAEhB,oBAAqB,GAErB,WAAY,iBAIH,mBAAqB,KAErB,YAAc,iBAGd,gBAAkB,mBAGlB,iBAAmB,IAAI,eAAe"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const core=require("@mionjs/core"),src_aot_aotCaches=require("../aot/aotCaches.cjs"),src_constants=require("../constants.cjs"),src_lib_serializer=require("./serializer.cjs"),src_lib_storage=require("./storage.cjs");async function fetchRemoteMethodsMetadata(methodIds,options){src_aot_aotCaches.loadAOTCaches(),validateClientCaches(),restoreFromLocalStorage(methodIds,options);const missingAfterLocal=methodIds.filter(path=>!core.routesCache.hasMetadata(path));if(!missingAfterLocal.length)return;const shouldReturnAllMethods=!0,body={[core.MION_ROUTES.methodsMetadataById]:[missingAfterLocal,shouldReturnAllMethods]};try{const path=core.getRoutePath([core.MION_ROUTES.methodsMetadataById],options),url=new URL(path,options.baseURL),response=await fetch(url,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(body)}),deserialized=await src_lib_serializer.deserializeResponseBody(response),platformError=deserialized[core.MION_ROUTES.platformError],serializableMethodsData=deserialized[core.MION_ROUTES.methodsMetadataById];if(core.isRpcError(platformError))throw platformError;if(core.isRpcError(serializableMethodsData))throw serializableMethodsData;if(!serializableMethodsData)throw new core.RpcError({type:"cant-fetch-remote-methods-metadata",publicMessage:"Failed to fetch remote methods metadata",errorData:{response}});storeDependencies(serializableMethodsData.deps,serializableMethodsData.purFnDeps,options),storeMethodsMetadata(serializableMethodsData.methods,options),addToCaches(serializableMethodsData)}catch(error){throw new Error(`Error fetching validation and serialization metadata: ${error?.message}`)}}function getSerializedMethodDataKey(methodId,options){return`${src_constants.STORAGE_KEY}:serialized-method-data:${options.baseURL}:${methodId}`}function getJitCompiledFnKey(jitFnHash,options){return`${src_constants.STORAGE_KEY}:jit-compiled-fn:${options.baseURL}:${jitFnHash}`}function getJitPureFnKey(namespace,pureFnHash,options){return`${src_constants.STORAGE_KEY}:jit-pure-fn:${options.baseURL}:${namespace}:${pureFnHash}`}function storeDependencies(deps,pureFnDeps,options){Object.entries(deps).forEach(([hash,jitFnData])=>{const key=getJitCompiledFnKey(hash,options);try{src_lib_storage.getStorage().setItem(key,JSON.stringify(jitFnData))}catch(error){console.warn(`Failed to store JIT function dependency ${hash}:`,error)}}),Object.entries(pureFnDeps).forEach(([namespace,nsPureFns])=>{Object.entries(nsPureFns).forEach(([fnHash,pureFnData])=>{const key=getJitPureFnKey(namespace,fnHash,options);try{src_lib_storage.getStorage().setItem(key,JSON.stringify(pureFnData))}catch(error){console.warn(`Failed to store pure function dependency ${namespace}::${fnHash}:`,error)}})})}function storeMethodsMetadata(methods,options){Object.entries(methods).forEach(([methodId,methodData])=>{const key=getSerializedMethodDataKey(methodId,options);try{src_lib_storage.getStorage().setItem(key,JSON.stringify(methodData))}catch(error){console.warn(`Failed to store method metadata ${methodId}:`,error)}})}function restoreAllDependencies(options){const deps={},pureFnDeps={},pureFnKeyPrefix=`${src_constants.STORAGE_KEY}:jit-pure-fn:${options.baseURL}:`;for(let i=0;i<src_lib_storage.getStorage().length;i++){const key=src_lib_storage.getStorage().key(i);if(key?.startsWith(`${src_constants.STORAGE_KEY}:jit-compiled-fn:${options.baseURL}:`))try{const data=src_lib_storage.getStorage().getItem(key);if(data){const parsedData=JSON.parse(data);deps[parsedData.jitFnHash]=parsedData}}catch(error){console.warn(`Failed to restore JIT function from key ${key}:`,error)}}for(let i=0;i<src_lib_storage.getStorage().length;i++){const key=src_lib_storage.getStorage().key(i);if(key?.startsWith(pureFnKeyPrefix))try{const data=src_lib_storage.getStorage().getItem(key);if(data){const parsedData=JSON.parse(data),namespace=key.slice(pureFnKeyPrefix.length).split(":")[0]||parsedData.namespace;pureFnDeps[namespace]||(pureFnDeps[namespace]={}),pureFnDeps[namespace][parsedData.fnName]=parsedData}}catch(error){console.warn(`Failed to restore pure function from key ${key}:`,error)}}(Object.keys(deps).length>0||Object.keys(pureFnDeps).length>0)&&core.addSerializedJitCaches(deps,pureFnDeps)}function restoreFromLocalStorage(methodIds,options){restoreAllDependencies(options);const methods={};let anyMethodsRestored=!1;methodIds.forEach(id=>{if(core.routesCache.hasMetadata(id))return;const methodKey=getSerializedMethodDataKey(id,options),methodMetaJson=src_lib_storage.getStorage().getItem(methodKey);if(methodMetaJson)try{const methodMeta=JSON.parse(methodMetaJson);methods[id]=methodMeta,anyMethodsRestored=!0}catch(error){console.warn(`Failed to restore method metadata for ${id}:`,error),src_lib_storage.getStorage().removeItem(methodKey)}}),anyMethodsRestored&&addToCaches({methods,deps:{},purFnDeps:{}})}function addToCaches(serializableMethodsData){core.addSerializedJitCaches(serializableMethodsData.deps,serializableMethodsData.purFnDeps),core.addRoutesToCache(serializableMethodsData.methods)}let clientCachesValidated=!1;function validateClientCaches(){if(clientCachesValidated||core.isTestEnv())return;clientCachesValidated=!0;const missingRoutes=Object.values(core.MION_ROUTES).filter(routeId=>!core.routesCache.hasMetadata(routeId));if(missingRoutes.length>0)throw new Error(`AOT cache not loaded: Required MION_ROUTES not found in router cache: ${missingRoutes.join(", ")}. Make sure the AOT caches are generated and bundled correctly.`)}exports.fetchRemoteMethodsMetadata=fetchRemoteMethodsMetadata;exports.restoreAllDependencies=restoreAllDependencies;exports.storeDependencies=storeDependencies;exports.storeMethodsMetadata=storeMethodsMetadata;
|
|
2
|
+
//# sourceMappingURL=clientMethodsMetadata.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clientMethodsMetadata.cjs","sources":["../../../../src/lib/clientMethodsMetadata.ts"],"sourcesContent":["/* ########\n * 2023 mion\n * Author: Ma-jerez\n * License: MIT\n * The software is provided \"as is\", without warranty of any kind.\n * ######## */\n\nimport {RpcError, isRpcError, addRoutesToCache, isTestEnv} from '@mionjs/core';\nimport {MION_ROUTES, getRoutePath} from '@mionjs/core';\nimport {loadAOTCaches} from '../aot/aotCaches.ts';\nimport {ClientOptions, RequestBody} from '../types.ts';\nimport type {\n JitCompiledFnData,\n MethodsCache,\n MethodWithOptions,\n PureFunctionData,\n SerializableMethodsData,\n PureFnsDataCache,\n} from '@mionjs/core';\nimport {routesCache, addSerializedJitCaches} from '@mionjs/core';\nimport {STORAGE_KEY} from '../constants.ts';\n\nimport {deserializeResponseBody} from './serializer.ts';\nimport {getStorage} from './storage.ts';\nimport type {MionRoutes} from '@mionjs/router';\n\ntype GetRemoteMethodsMetadataById = MionRoutes[typeof MION_ROUTES.methodsMetadataById]['handler'];\ntype MethodsMetadataResponse = Awaited<ReturnType<GetRemoteMethodsMetadataById>>;\ntype GlobalErrorRoute = MionRoutes[typeof MION_ROUTES.platformError]['handler'];\ntype GlobalErrorResponse = Awaited<ReturnType<GlobalErrorRoute>>;\n\n/** Manually calls mionGetRemoteMethodsInfoById to get Remote Api Metadata */\nexport async function fetchRemoteMethodsMetadata(methodIds: string[], options: ClientOptions) {\n loadAOTCaches();\n validateClientCaches();\n restoreFromLocalStorage(methodIds, options);\n const missingAfterLocal = methodIds.filter((path) => !routesCache.hasMetadata(path));\n if (!missingAfterLocal.length) return;\n const shouldReturnAllMethods = true;\n const body: RequestBody = {\n [MION_ROUTES.methodsMetadataById]: [missingAfterLocal, shouldReturnAllMethods],\n };\n try {\n const path = getRoutePath([MION_ROUTES.methodsMetadataById], options);\n const url = new URL(path, options.baseURL);\n const response = await fetch(url, {\n method: 'POST',\n headers: {'Content-Type': 'application/json'},\n body: JSON.stringify(body),\n });\n\n const deserialized = await deserializeResponseBody(response);\n const platformError = deserialized[MION_ROUTES.platformError] as GlobalErrorResponse | undefined;\n const serializableMethodsData = deserialized[MION_ROUTES.methodsMetadataById] as MethodsMetadataResponse;\n\n if (isRpcError(platformError)) throw platformError;\n if (isRpcError(serializableMethodsData)) throw serializableMethodsData;\n if (!serializableMethodsData)\n throw new RpcError({\n type: 'cant-fetch-remote-methods-metadata',\n publicMessage: 'Failed to fetch remote methods metadata',\n errorData: {response},\n });\n\n storeDependencies(serializableMethodsData.deps, serializableMethodsData.purFnDeps, options);\n storeMethodsMetadata(serializableMethodsData.methods, options);\n addToCaches(serializableMethodsData);\n } catch (error: any) {\n throw new Error(`Error fetching validation and serialization metadata: ${error?.message}`);\n }\n}\n\nfunction getSerializedMethodDataKey(methodId: string, options: ClientOptions) {\n return `${STORAGE_KEY}:serialized-method-data:${options.baseURL}:${methodId}`;\n}\n\nfunction getJitCompiledFnKey(jitFnHash: string, options: ClientOptions) {\n return `${STORAGE_KEY}:jit-compiled-fn:${options.baseURL}:${jitFnHash}`;\n}\n\nfunction getJitPureFnKey(namespace: string, pureFnHash: string, options: ClientOptions) {\n return `${STORAGE_KEY}:jit-pure-fn:${options.baseURL}:${namespace}:${pureFnHash}`;\n}\n\n/** Stores JIT compiled functions and pure functions globally in localStorage */\nexport function storeDependencies(deps: Record<string, JitCompiledFnData>, pureFnDeps: PureFnsDataCache, options: ClientOptions) {\n Object.entries(deps).forEach(([hash, jitFnData]: [string, JitCompiledFnData]) => {\n const key = getJitCompiledFnKey(hash, options);\n try {\n getStorage().setItem(key, JSON.stringify(jitFnData));\n } catch (error) {\n console.warn(`Failed to store JIT function dependency ${hash}:`, error);\n }\n });\n\n // Store namespaced pure functions\n Object.entries(pureFnDeps).forEach(([namespace, nsPureFns]) => {\n Object.entries(nsPureFns).forEach(([fnHash, pureFnData]: [string, PureFunctionData]) => {\n const key = getJitPureFnKey(namespace, fnHash, options);\n try {\n getStorage().setItem(key, JSON.stringify(pureFnData));\n } catch (error) {\n console.warn(`Failed to store pure function dependency ${namespace}::${fnHash}:`, error);\n }\n });\n });\n}\n\n/** Stores method metadata in localStorage using the new storage format */\nexport function storeMethodsMetadata(methods: MethodsCache, options: ClientOptions) {\n Object.entries(methods).forEach(([methodId, methodData]) => {\n const key = getSerializedMethodDataKey(methodId, options);\n try {\n getStorage().setItem(key, JSON.stringify(methodData));\n } catch (error) {\n console.warn(`Failed to store method metadata ${methodId}:`, error);\n }\n });\n}\n\n/** Restores all JIT compiled functions and pure functions from localStorage and deserializes them */\nexport function restoreAllDependencies(options: ClientOptions) {\n const deps: Record<string, JitCompiledFnData> = {};\n const pureFnDeps: PureFnsDataCache = {};\n const pureFnKeyPrefix = `${STORAGE_KEY}:jit-pure-fn:${options.baseURL}:`;\n\n for (let i = 0; i < getStorage().length; i++) {\n const key = getStorage().key(i);\n if (key?.startsWith(`${STORAGE_KEY}:jit-compiled-fn:${options.baseURL}:`)) {\n try {\n const data = getStorage().getItem(key);\n if (data) {\n const parsedData = JSON.parse(data);\n deps[parsedData.jitFnHash] = parsedData;\n }\n } catch (error) {\n console.warn(`Failed to restore JIT function from key ${key}:`, error);\n }\n }\n }\n\n for (let i = 0; i < getStorage().length; i++) {\n const key = getStorage().key(i);\n if (key?.startsWith(pureFnKeyPrefix)) {\n try {\n const data = getStorage().getItem(key);\n if (data) {\n const parsedData = JSON.parse(data);\n // Extract namespace from key: \"mion:jit-pure-fn:baseURL:namespace:fnHash\"\n const keyParts = key.slice(pureFnKeyPrefix.length).split(':');\n const namespace = keyParts[0] || parsedData.namespace;\n if (!pureFnDeps[namespace]) pureFnDeps[namespace] = {};\n pureFnDeps[namespace][parsedData.fnName] = parsedData;\n }\n } catch (error) {\n console.warn(`Failed to restore pure function from key ${key}:`, error);\n }\n }\n }\n\n if (Object.keys(deps).length > 0 || Object.keys(pureFnDeps).length > 0) {\n addSerializedJitCaches(deps, pureFnDeps);\n }\n}\n\n/** Restores method metadata from localStorage using the new storage format */\nfunction restoreFromLocalStorage(methodIds: string[], options: ClientOptions) {\n restoreAllDependencies(options);\n\n const methods: MethodsCache = {};\n let anyMethodsRestored = false;\n\n methodIds.forEach((id) => {\n if (routesCache.hasMetadata(id)) return;\n const methodKey = getSerializedMethodDataKey(id, options);\n const methodMetaJson = getStorage().getItem(methodKey);\n if (methodMetaJson) {\n try {\n const methodMeta: MethodWithOptions = JSON.parse(methodMetaJson);\n methods[id] = methodMeta;\n anyMethodsRestored = true;\n } catch (error) {\n console.warn(`Failed to restore method metadata for ${id}:`, error);\n getStorage().removeItem(methodKey);\n }\n }\n });\n\n if (anyMethodsRestored) {\n const serializableMethodsData: SerializableMethodsData = {\n methods,\n deps: {},\n purFnDeps: {},\n };\n addToCaches(serializableMethodsData);\n }\n}\n\nfunction addToCaches(serializableMethodsData: SerializableMethodsData) {\n addSerializedJitCaches(serializableMethodsData.deps, serializableMethodsData.purFnDeps);\n addRoutesToCache(serializableMethodsData.methods);\n}\n\n/** Validates that required MION_ROUTES are loaded in the cache. Skipped in test environments. */\nlet clientCachesValidated = false;\nfunction validateClientCaches() {\n if (clientCachesValidated || isTestEnv()) return;\n clientCachesValidated = true;\n\n const requiredRoutes = Object.values(MION_ROUTES);\n const missingRoutes = requiredRoutes.filter((routeId) => !routesCache.hasMetadata(routeId));\n if (missingRoutes.length > 0) {\n throw new Error(\n `AOT cache not loaded: Required MION_ROUTES not found in router cache: ${missingRoutes.join(', ')}. ` +\n `Make sure the AOT caches are generated and bundled correctly.`\n );\n }\n}\n"],"names":["loadAOTCaches","routesCache","MION_ROUTES","getRoutePath","deserializeResponseBody","isRpcError","RpcError","STORAGE_KEY","getStorage","addSerializedJitCaches","addRoutesToCache","isTestEnv"],"mappings":"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"}
|
|
@@ -1,10 +1,6 @@
|
|
|
1
|
-
import { ClientOptions } from '
|
|
1
|
+
import { ClientOptions } from '../types.ts';
|
|
2
2
|
import { JitCompiledFnData, MethodsCache, PureFnsDataCache } from '@mionjs/core';
|
|
3
3
|
export declare function fetchRemoteMethodsMetadata(methodIds: string[], options: ClientOptions): Promise<void>;
|
|
4
4
|
export declare function storeDependencies(deps: Record<string, JitCompiledFnData>, pureFnDeps: PureFnsDataCache, options: ClientOptions): void;
|
|
5
5
|
export declare function storeMethodsMetadata(methods: MethodsCache, options: ClientOptions): void;
|
|
6
6
|
export declare function restoreAllDependencies(options: ClientOptions): void;
|
|
7
|
-
export declare function getAOTCaches(): {
|
|
8
|
-
jitFnsCache: Record<string, any>;
|
|
9
|
-
pureFnsCache: Record<string, Record<string, any>>;
|
|
10
|
-
};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});class HandlersRegistry{errorHandlers=new Map;successHandlers=new Map;register(handlerId,errorType,handler){let handlerMap=this.errorHandlers.get(handlerId);handlerMap||(handlerMap=new Map,this.errorHandlers.set(handlerId,handlerMap)),handlerMap.set(errorType,handler)}unregister(handlerId,errorType){const handlerMap=this.errorHandlers.get(handlerId);handlerMap&&(handlerMap.delete(errorType),handlerMap.size===0&&this.errorHandlers.delete(handlerId))}hasHandler(handlerId,errorType){return this.errorHandlers.get(handlerId)?.has(errorType)??!1}executeHandler(handlerId,error){const handlerMap=this.errorHandlers.get(handlerId);if(!handlerMap)return!1;const handler=handlerMap.get(error.type);return handler?(handler(error),!0):!1}registerSuccess(handlerId,handler){this.successHandlers.set(handlerId,handler)}unregisterSuccess(handlerId){this.successHandlers.delete(handlerId)}hasSuccessHandler(handlerId){return this.successHandlers.has(handlerId)}executeSuccessHandler(handlerId,result){const handler=this.successHandlers.get(handlerId);return handler?(handler(result),!0):!1}clearHandlers(handlerId){this.errorHandlers.delete(handlerId),this.successHandlers.delete(handlerId)}clearAll(){this.errorHandlers.clear(),this.successHandlers.clear()}getHandlerIds(){const errorIds=Array.from(this.errorHandlers.keys()),successIds=Array.from(this.successHandlers.keys());return[...new Set([...errorIds,...successIds])]}getErrorTypes(handlerId){const handlerMap=this.errorHandlers.get(handlerId);return handlerMap?Array.from(handlerMap.keys()):[]}
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});class HandlersRegistry{errorHandlers=new Map;successHandlers=new Map;register(handlerId,errorType,handler){let handlerMap=this.errorHandlers.get(handlerId);handlerMap||(handlerMap=new Map,this.errorHandlers.set(handlerId,handlerMap)),handlerMap.set(errorType,handler)}unregister(handlerId,errorType){const handlerMap=this.errorHandlers.get(handlerId);handlerMap&&(handlerMap.delete(errorType),handlerMap.size===0&&this.errorHandlers.delete(handlerId))}hasHandler(handlerId,errorType){return this.errorHandlers.get(handlerId)?.has(errorType)??!1}executeHandler(handlerId,error){const handlerMap=this.errorHandlers.get(handlerId);if(!handlerMap)return!1;const handler=handlerMap.get(error.type);return handler?(handler(error),!0):!1}registerSuccess(handlerId,handler){this.successHandlers.set(handlerId,handler)}unregisterSuccess(handlerId){this.successHandlers.delete(handlerId)}hasSuccessHandler(handlerId){return this.successHandlers.has(handlerId)}executeSuccessHandler(handlerId,result){const handler=this.successHandlers.get(handlerId);return handler?(handler(result),!0):!1}clearHandlers(handlerId){this.errorHandlers.delete(handlerId),this.successHandlers.delete(handlerId)}clearAll(){this.errorHandlers.clear(),this.successHandlers.clear()}getHandlerIds(){const errorIds=Array.from(this.errorHandlers.keys()),successIds=Array.from(this.successHandlers.keys());return[...new Set([...errorIds,...successIds])]}getErrorTypes(handlerId){const handlerMap=this.errorHandlers.get(handlerId);return handlerMap?Array.from(handlerMap.keys()):[]}}exports.HandlersRegistry=HandlersRegistry;
|
|
2
2
|
//# sourceMappingURL=handlersRegistry.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handlersRegistry.cjs","sources":["../../../../src/lib/handlersRegistry.ts"],"sourcesContent":["/* ########\n * 2025 mion\n * Author: Ma-jerez\n * License: MIT\n * The software is provided \"as is\", without warranty of any kind.\n * ######## */\n\nimport type {RpcError} from '@mionjs/core';\nimport type {ErrorHandler, SuccessHandler} from '../types.ts';\n\n/** Central registry for persistent middleFn handlers (both success and error) */\nexport class HandlersRegistry {\n private errorHandlers: Map<string, Map<string, ErrorHandler<any>>> = new Map();\n private successHandlers: Map<string, SuccessHandler<any>> = new Map();\n\n /** Register an error handler for a specific handler (middleFn) and error type */\n register(handlerId: string, errorType: string, handler: ErrorHandler<any>): void {\n let handlerMap = this.errorHandlers.get(handlerId);\n if (!handlerMap) {\n handlerMap = new Map();\n this.errorHandlers.set(handlerId, handlerMap);\n }\n handlerMap.set(errorType, handler);\n }\n\n /** Unregister an error handler for a specific handler and error type */\n unregister(handlerId: string, errorType: string): void {\n const handlerMap = this.errorHandlers.get(handlerId);\n if (handlerMap) {\n handlerMap.delete(errorType);\n if (handlerMap.size === 0) this.errorHandlers.delete(handlerId);\n }\n }\n\n /** Check if an error handler exists for a specific handler ID and error type */\n hasHandler(handlerId: string, errorType: string): boolean {\n const handlerMap = this.errorHandlers.get(handlerId);\n return handlerMap?.has(errorType) ?? false;\n }\n\n /** Get and execute the handler for an error, if it exists */\n executeHandler(handlerId: string, error: RpcError<string>): boolean {\n const handlerMap = this.errorHandlers.get(handlerId);\n if (!handlerMap) return false;\n\n const handler = handlerMap.get(error.type);\n if (!handler) return false;\n\n handler(error);\n return true;\n }\n\n /** Register a success handler for a specific middleFn */\n registerSuccess(handlerId: string, handler: SuccessHandler<any>): void {\n this.successHandlers.set(handlerId, handler);\n }\n\n /** Unregister a success handler for a specific middleFn */\n unregisterSuccess(handlerId: string): void {\n this.successHandlers.delete(handlerId);\n }\n\n /** Check if a success handler exists for a specific handler ID */\n hasSuccessHandler(handlerId: string): boolean {\n return this.successHandlers.has(handlerId);\n }\n\n /** Get and execute the success handler for a middleFn result, if it exists */\n executeSuccessHandler(handlerId: string, result: any): boolean {\n const handler = this.successHandlers.get(handlerId);\n if (!handler) return false;\n\n handler(result);\n return true;\n }\n\n /** Clear all handlers (both error and success) for a specific handler ID */\n clearHandlers(handlerId: string): void {\n this.errorHandlers.delete(handlerId);\n this.successHandlers.delete(handlerId);\n }\n\n /** Clear all registered handlers (both error and success) */\n clearAll(): void {\n this.errorHandlers.clear();\n this.successHandlers.clear();\n }\n\n /** Get all registered handler IDs */\n getHandlerIds(): string[] {\n const errorIds = Array.from(this.errorHandlers.keys());\n const successIds = Array.from(this.successHandlers.keys());\n return [...new Set([...errorIds, ...successIds])];\n }\n\n /** Get all error types registered for a handler ID */\n getErrorTypes(handlerId: string): string[] {\n const handlerMap = this.errorHandlers.get(handlerId);\n return handlerMap ? Array.from(handlerMap.keys()) : [];\n }\n}\n"],"names":[],"mappings":"sFAWa,gBAAgB,CACjB,kBAAiE,IACjE,oBAAwD,IAGhE,SAAS,UAAmB,UAAmB,QAA0B,CACrE,IAAI,WAAa,KAAK,cAAc,IAAI,SAAS,EAC5C,aACD,eAAiB,IACjB,KAAK,cAAc,IAAI,UAAW,UAAU,GAEhD,WAAW,IAAI,UAAW,OAAO,CACrC,CAGA,WAAW,UAAmB,UAAiB,CAC3C,MAAM,WAAa,KAAK,cAAc,IAAI,SAAS,EAC/C,aACA,WAAW,OAAO,SAAS,EACvB,WAAW,OAAS,GAAG,KAAK,cAAc,OAAO,SAAS,EAEtE,CAGA,WAAW,UAAmB,UAAiB,CAE3C,OADmB,KAAK,cAAc,IAAI,SAAS,GAChC,IAAI,SAAS,GAAK,EACzC,CAGA,eAAe,UAAmB,MAAuB,CACrD,MAAM,WAAa,KAAK,cAAc,IAAI,SAAS,EACnD,GAAI,CAAC,WAAY,MAAO,GAExB,MAAM,QAAU,WAAW,IAAI,MAAM,IAAI,EACzC,OAAK,SAEL,QAAQ,KAAK,EACN,IAHc,EAIzB,CAGA,gBAAgB,UAAmB,QAA4B,CAC3D,KAAK,gBAAgB,IAAI,UAAW,OAAO,CAC/C,CAGA,kBAAkB,UAAiB,CAC/B,KAAK,gBAAgB,OAAO,SAAS,CACzC,CAGA,kBAAkB,UAAiB,CAC/B,OAAO,KAAK,gBAAgB,IAAI,SAAS,CAC7C,CAGA,sBAAsB,UAAmB,OAAW,CAChD,MAAM,QAAU,KAAK,gBAAgB,IAAI,SAAS,EAClD,OAAK,SAEL,QAAQ,MAAM,EACP,IAHc,EAIzB,CAGA,cAAc,UAAiB,CAC3B,KAAK,cAAc,OAAO,SAAS,EACnC,KAAK,gBAAgB,OAAO,SAAS,CACzC,CAGA,UAAQ,CACJ,KAAK,cAAc,MAAA,EACnB,KAAK,gBAAgB,MAAA,CACzB,CAGA,eAAa,CACT,MAAM,SAAW,MAAM,KAAK,KAAK,cAAc,MAAM,EAC/C,WAAa,MAAM,KAAK,KAAK,gBAAgB,MAAM,EACzD,MAAO,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,SAAU,GAAG,UAAU,CAAC,CAAC,CACpD,CAGA,cAAc,UAAiB,CAC3B,MAAM,WAAa,KAAK,cAAc,IAAI,SAAS,EACnD,OAAO,WAAa,MAAM,KAAK,WAAW,KAAA,CAAM,EAAI,CAAA,CACxD,CACH"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const core=require("@mionjs/core"),src_constants=require("../constants.cjs");function getSerializerMode(req){const methodId=req.route?.id??req.workflowSubRequests?.[0]?.id,serializerMode=core.routesCache.getMethodJitFns(methodId)?.options.serializer||src_constants.DEFAULT_PREFILL_OPTIONS.serializer;return serializerMode==="json"?src_constants.DEFAULT_PREFILL_OPTIONS.serializer:serializerMode}function serializeRequestBody(req){const serializerMode=getSerializerMode(req);switch(serializerMode){case"json":case"stringifyJson":return{body:stringifyBody(req),contentType:"application/json; charset=utf-8"};case"binary":return{body:serializeBinaryBody(req),contentType:"application/octet-stream"};default:throw new Error(`Invalid serializer mode ${serializerMode}`)}}function serializeBinaryBody(req){const subRequestIds=Object.keys(req.subRequestList),body={},executionChain=[];for(const id of subRequestIds){let params=req.subRequestList[id].params;const method=core.routesCache.useMethodJitFns(id);method.type===core.HandlerType.headersMiddleFn&&method.headersParam&&(params=getParamsWithoutHeadersSubset(params)),body[id]=params,executionChain.push(method)}const workflowRouteIds=req.workflowSubRequests?.map(sr=>sr.id),{buffer}=core.serializeBinaryBody(req.path,executionChain,body,!1,workflowRouteIds);return new Uint8Array(buffer)}async function deserializeResponseBody(response){const contentType=response.headers.get("content-type"),isJson=contentType?.includes("application/json"),isBinary=contentType?.includes("application/octet-stream");let parsedBody;if(isJson?parsedBody=await deserializeJsonResponseBody(response):isBinary?parsedBody=await deserializeBinaryResponseBody(response):parsedBody=await deserializeJsonResponseBody(response),core.MION_ROUTES.thrownErrors in parsedBody){const unexpectedErrors=parsedBody[core.MION_ROUTES.thrownErrors];if(core.MION_ROUTES.platformError in unexpectedErrors){const globalErrorValue=unexpectedErrors[core.MION_ROUTES.platformError],platformError=core.isRpcError(globalErrorValue)?new core.RpcError(globalErrorValue):globalErrorValue;return{[core.MION_ROUTES.platformError]:platformError}}Object.assign(parsedBody,unexpectedErrors),delete parsedBody[core.MION_ROUTES.thrownErrors]}if(isJson||!isJson&&!isBinary){const deserializedBody={};return Object.entries(parsedBody).forEach(([methodId,returnValue])=>{const method=core.routesCache.useMethodJitFns(methodId),deserialized=parseHandlerReturnValue(method,returnValue);deserializedBody[methodId]=deserialized}),deserializedBody}return parsedBody}async function deserializeJsonResponseBody(response){try{return await response.json()}catch(err){throw new core.RpcError({type:"parsing-json-response-error",publicMessage:`Invalid json response body: ${err?.message||"unknown parsing error."}`})}}async function deserializeBinaryResponseBody(response){const arrayBuffer=await response.arrayBuffer(),{body}=core.deserializeBinaryBody("client-response",arrayBuffer,!0);return body}function stringifyBody(req){const props=[],subRequestIds=Object.keys(req.subRequestList);for(let i=0;i<subRequestIds.length;i++){const id=subRequestIds[i],subRequest=req.subRequestList[id];if(!subRequest)continue;let params=subRequest.params;const method=core.routesCache.useMethodJitFns(id);method.type===core.HandlerType.headersMiddleFn&&method.headersParam&&(params=getParamsWithoutHeadersSubset(params));try{const jsonValue=stringifyHandlerParams(method,params);if(!jsonValue)continue;props.push(`${JSON.stringify(id)}:${jsonValue}`)}catch(e){throw new core.RpcError({type:"json-stringify-request-error",publicMessage:`Failed to stringify params for handler ${id}`,originalError:e})}}return`{${props.join(",")}}`}function getParamsWithoutHeadersSubset(params){return!params||params.length===0?[]:params.slice(1)}function stringifyHandlerParams(method,params){if(!method.paramNames||method.paramNames.length===0)return"";const paramsJit=method.paramsJitFns;return paramsJit.prepareForJson.isNoop?JSON.stringify(params):paramsJit.stringifyJson.fn(params)}function parseHandlerReturnValue(method,returnValue){if(!method.hasReturnData)return returnValue;const returnJit=method.returnJitFns;if(returnJit.restoreFromJson.isNoop||!returnValue)return returnValue;try{return returnValue instanceof core.RpcError?returnValue:core.isRpcError(returnValue)?new core.RpcError(returnValue):returnJit.restoreFromJson.fn(returnValue)}catch(e){return new core.RpcError({type:"deserialization-error",publicMessage:`Invalid response from Route or MiddleFn '${method.id}', can not deserialize return value: ${e.message}`,errorData:e?.errors})}}exports.deserializeResponseBody=deserializeResponseBody;exports.serializeRequestBody=serializeRequestBody;
|
|
2
|
+
//# sourceMappingURL=serializer.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serializer.cjs","sources":["../../../../src/lib/serializer.ts"],"sourcesContent":["/* ########\n * 2023 mion\n * Author: Ma-jerez\n * License: MIT\n * The software is provided \"as is\", without warranty of any kind.\n * ######## */\n\nimport type {ResponseBody} from '@mionjs/router';\nimport {\n type MethodWithJitFns,\n RpcError,\n isRpcError,\n routesCache,\n MION_ROUTES,\n HandlerType,\n type SerializerMode,\n serializeBinaryBody as coreSerializeBinaryBody,\n deserializeBinaryBody as coreDeserializeBinaryBody,\n} from '@mionjs/core';\nimport type {MionClientRequest} from '../request.ts';\nimport {DEFAULT_PREFILL_OPTIONS} from '../constants.ts';\n\n/** Result of serializing a request body - can be string (JSON) or Uint8Array (binary) */\nexport type SerializedBody = string | Uint8Array;\n\n/** Content-type header value for the serialized body */\nexport type ContentType = 'application/json; charset=utf-8' | 'application/octet-stream';\n\n/** Result of serializing a request body with its content type */\nexport interface SerializedRequest {\n body: SerializedBody;\n contentType: ContentType;\n}\n\n/** Determines the serializer mode to use for a request */\nfunction getSerializerMode(req: MionClientRequest<any, any>): SerializerMode {\n const methodId = req.route?.id ?? req.workflowSubRequests?.[0]?.id;\n const method = routesCache.getMethodJitFns(methodId);\n const serializerMode = method?.options.serializer || DEFAULT_PREFILL_OPTIONS.serializer;\n if (serializerMode === 'json') return DEFAULT_PREFILL_OPTIONS.serializer;\n return serializerMode;\n}\n\n/** Serializes the request body and returns it with the appropriate content type */\nexport function serializeRequestBody(req: MionClientRequest<any, any>): SerializedRequest {\n const serializerMode = getSerializerMode(req);\n\n switch (serializerMode) {\n case 'json':\n case 'stringifyJson':\n return {\n body: stringifyBody(req),\n contentType: 'application/json; charset=utf-8',\n };\n case 'binary':\n return {\n body: serializeBinaryBody(req),\n contentType: 'application/octet-stream',\n };\n default:\n throw new Error(`Invalid serializer mode ${serializerMode}`);\n }\n}\n\n/** Serializes request body to binary format */\nfunction serializeBinaryBody(req: MionClientRequest<any, any>): Uint8Array {\n const subRequestIds = Object.keys(req.subRequestList);\n const body: Record<string, any> = {};\n const executionChain: MethodWithJitFns[] = [];\n\n for (const id of subRequestIds) {\n const subRequest = req.subRequestList[id];\n let params = subRequest.params;\n const method = routesCache.useMethodJitFns(id);\n\n if (method.type === HandlerType.headersMiddleFn && method.headersParam) {\n params = getParamsWithoutHeadersSubset(params);\n }\n\n body[id] = params;\n executionChain.push(method);\n }\n\n const workflowRouteIds = req.workflowSubRequests?.map((sr) => sr.id);\n const {buffer} = coreSerializeBinaryBody(req.path, executionChain, body, false, workflowRouteIds);\n return new Uint8Array(buffer);\n}\n\n/** Deserializes the response body from a fetch Response object */\nexport async function deserializeResponseBody(response: Response): Promise<ResponseBody> {\n const contentType = response.headers.get('content-type');\n const isJson = contentType?.includes('application/json');\n const isBinary = contentType?.includes('application/octet-stream');\n\n let parsedBody: any;\n\n if (isJson) {\n parsedBody = await deserializeJsonResponseBody(response);\n } else if (isBinary) {\n parsedBody = await deserializeBinaryResponseBody(response);\n } else {\n parsedBody = await deserializeJsonResponseBody(response);\n }\n\n if (MION_ROUTES.thrownErrors in parsedBody) {\n const unexpectedErrors = parsedBody[MION_ROUTES.thrownErrors];\n\n if (MION_ROUTES.platformError in unexpectedErrors) {\n const globalErrorValue = unexpectedErrors[MION_ROUTES.platformError];\n const platformError = isRpcError(globalErrorValue) ? new RpcError(globalErrorValue) : globalErrorValue;\n return {[MION_ROUTES.platformError]: platformError};\n }\n\n Object.assign(parsedBody, unexpectedErrors);\n delete parsedBody[MION_ROUTES.thrownErrors];\n }\n\n if (isJson || (!isJson && !isBinary)) {\n const deserializedBody: ResponseBody = {};\n Object.entries(parsedBody).forEach(([methodId, returnValue]) => {\n const method = routesCache.useMethodJitFns(methodId);\n const deserialized = parseHandlerReturnValue(method, returnValue);\n deserializedBody[methodId] = deserialized;\n });\n return deserializedBody;\n }\n\n return parsedBody;\n}\n\n/** Deserializes JSON response body */\nasync function deserializeJsonResponseBody(response: Response): Promise<any> {\n try {\n return await response.json();\n } catch (err: any) {\n throw new RpcError({\n type: 'parsing-json-response-error',\n publicMessage: `Invalid json response body: ${err?.message || 'unknown parsing error.'}`,\n });\n }\n}\n\n/** Deserializes binary response body */\nasync function deserializeBinaryResponseBody(response: Response): Promise<ResponseBody> {\n const arrayBuffer = await response.arrayBuffer();\n const {body} = coreDeserializeBinaryBody('client-response', arrayBuffer, true);\n return body;\n}\n\nfunction stringifyBody(req: MionClientRequest<any, any>): string {\n const props: string[] = [];\n const subRequestIds = Object.keys(req.subRequestList);\n\n for (let i = 0; i < subRequestIds.length; i++) {\n const id = subRequestIds[i];\n const subRequest = req.subRequestList[id];\n if (!subRequest) continue;\n let params = subRequest.params;\n const method = routesCache.useMethodJitFns(id);\n\n if (method.type === HandlerType.headersMiddleFn && method.headersParam) {\n params = getParamsWithoutHeadersSubset(params);\n }\n\n try {\n const jsonValue = stringifyHandlerParams(method, params);\n if (!jsonValue) continue;\n props.push(`${JSON.stringify(id)}:${jsonValue}`);\n } catch (e: any) {\n const err = new RpcError({\n type: 'json-stringify-request-error',\n publicMessage: `Failed to stringify params for handler ${id}`,\n originalError: e,\n });\n throw err;\n }\n }\n\n return `{${props.join(',')}}`;\n}\n\n/** Returns params array without the HeadersSubset (first param) */\nfunction getParamsWithoutHeadersSubset(params: any[]): any[] {\n if (!params || params.length === 0) return [];\n return params.slice(1);\n}\n\nfunction stringifyHandlerParams(method: MethodWithJitFns, params: any[]): string {\n if (!method.paramNames || method.paramNames.length === 0) return '';\n const paramsJit = method.paramsJitFns;\n if (paramsJit.prepareForJson.isNoop) return JSON.stringify(params);\n return paramsJit.stringifyJson.fn(params);\n}\n\nfunction parseHandlerReturnValue(method: MethodWithJitFns, returnValue: any): any {\n if (!method.hasReturnData) return returnValue;\n const returnJit = method.returnJitFns;\n if (returnJit.restoreFromJson.isNoop || !returnValue) return returnValue;\n\n try {\n if (returnValue instanceof RpcError) return returnValue;\n if (isRpcError(returnValue)) return new RpcError(returnValue);\n return returnJit.restoreFromJson.fn(returnValue);\n } catch (e: any) {\n return new RpcError({\n type: 'deserialization-error',\n publicMessage: `Invalid response from Route or MiddleFn '${method.id}', can not deserialize return value: ${e.message}`,\n errorData: e?.errors,\n });\n }\n}\n"],"names":["routesCache","DEFAULT_PREFILL_OPTIONS","HandlerType","coreSerializeBinaryBody","MION_ROUTES","isRpcError","RpcError","coreDeserializeBinaryBody"],"mappings":"6JAmCA,SAAS,kBAAkB,IAAgC,CACvD,MAAM,SAAW,IAAI,OAAO,IAAM,IAAI,sBAAsB,CAAC,GAAG,GAE1D,eADSA,KAAAA,YAAY,gBAAgB,QAAQ,GACpB,QAAQ,YAAcC,cAAAA,wBAAwB,WAC7E,OAAI,iBAAmB,OAAeA,cAAAA,wBAAwB,WACvD,cACX,CAGM,SAAU,qBAAqB,IAAgC,CACjE,MAAM,eAAiB,kBAAkB,GAAG,EAE5C,OAAQ,eAAA,CACJ,IAAK,OACL,IAAK,gBACD,MAAO,CACH,KAAM,cAAc,GAAG,EACvB,YAAa,iCAAA,EAErB,IAAK,SACD,MAAO,CACH,KAAM,oBAAoB,GAAG,EAC7B,YAAa,0BAAA,EAErB,QACI,MAAM,IAAI,MAAM,2BAA2B,cAAc,EAAE,CAAA,CAEvE,CAGA,SAAS,oBAAoB,IAAgC,CACzD,MAAM,cAAgB,OAAO,KAAK,IAAI,cAAc,EAC9C,KAA4B,CAAA,EAC5B,eAAqC,CAAA,EAE3C,UAAW,MAAM,cAAe,CAE5B,IAAI,OADe,IAAI,eAAe,EAAE,EAChB,OACxB,MAAM,OAASD,KAAAA,YAAY,gBAAgB,EAAE,EAEzC,OAAO,OAASE,KAAAA,YAAY,iBAAmB,OAAO,eACtD,OAAS,8BAA8B,MAAM,GAGjD,KAAK,EAAE,EAAI,OACX,eAAe,KAAK,MAAM,CAC9B,CAEA,MAAM,iBAAmB,IAAI,qBAAqB,IAAK,IAAO,GAAG,EAAE,EAC7D,CAAC,QAAUC,KAAAA,oBAAwB,IAAI,KAAM,eAAgB,KAAM,GAAO,gBAAgB,EAChG,OAAO,IAAI,WAAW,MAAM,CAChC,CAGA,eAAsB,wBAAwB,SAAkB,CAC5D,MAAM,YAAc,SAAS,QAAQ,IAAI,cAAc,EACjD,OAAS,aAAa,SAAS,kBAAkB,EACjD,SAAW,aAAa,SAAS,0BAA0B,EAEjE,IAAI,WAUJ,GARI,OACA,WAAa,MAAM,4BAA4B,QAAQ,EAChD,SACP,WAAa,MAAM,8BAA8B,QAAQ,EAEzD,WAAa,MAAM,4BAA4B,QAAQ,EAGvDC,KAAAA,YAAY,gBAAgB,WAAY,CACxC,MAAM,iBAAmB,WAAWA,KAAAA,YAAY,YAAY,EAE5D,GAAIA,KAAAA,YAAY,iBAAiB,iBAAkB,CAC/C,MAAM,iBAAmB,iBAAiBA,KAAAA,YAAY,aAAa,EAC7D,cAAgBC,KAAAA,WAAW,gBAAgB,EAAI,IAAIC,KAAAA,SAAS,gBAAgB,EAAI,iBACtF,MAAO,CAAC,CAACF,KAAAA,YAAY,aAAa,EAAG,aAAA,CACzC,CAEA,OAAO,OAAO,WAAY,gBAAgB,EAC1C,OAAO,WAAWA,KAAAA,YAAY,YAAY,CAC9C,CAEA,GAAI,QAAW,CAAC,QAAU,CAAC,SAAW,CAClC,MAAM,iBAAiC,CAAA,EACvC,cAAO,QAAQ,UAAU,EAAE,QAAQ,CAAC,CAAC,SAAU,WAAW,IAAK,CAC3D,MAAM,OAASJ,KAAAA,YAAY,gBAAgB,QAAQ,EAC7C,aAAe,wBAAwB,OAAQ,WAAW,EAChE,iBAAiB,QAAQ,EAAI,YACjC,CAAC,EACM,gBACX,CAEA,OAAO,UACX,CAGA,eAAe,4BAA4B,SAAkB,CACzD,GAAI,CACA,OAAO,MAAM,SAAS,KAAA,CAC1B,OAAS,IAAU,CACf,MAAM,IAAIM,KAAAA,SAAS,CACf,KAAM,8BACN,cAAe,+BAA+B,KAAK,SAAW,wBAAwB,EAAA,CACzF,CACL,CACJ,CAGA,eAAe,8BAA8B,SAAkB,CAC3D,MAAM,YAAc,MAAM,SAAS,YAAA,EAC7B,CAAC,IAAA,EAAQC,KAAAA,sBAA0B,kBAAmB,YAAa,EAAI,EAC7E,OAAO,IACX,CAEA,SAAS,cAAc,IAAgC,CACnD,MAAM,MAAkB,CAAA,EAClB,cAAgB,OAAO,KAAK,IAAI,cAAc,EAEpD,QAAS,EAAI,EAAG,EAAI,cAAc,OAAQ,IAAK,CAC3C,MAAM,GAAK,cAAc,CAAC,EACpB,WAAa,IAAI,eAAe,EAAE,EACxC,GAAI,CAAC,WAAY,SACjB,IAAI,OAAS,WAAW,OACxB,MAAM,OAASP,KAAAA,YAAY,gBAAgB,EAAE,EAEzC,OAAO,OAASE,KAAAA,YAAY,iBAAmB,OAAO,eACtD,OAAS,8BAA8B,MAAM,GAGjD,GAAI,CACA,MAAM,UAAY,uBAAuB,OAAQ,MAAM,EACvD,GAAI,CAAC,UAAW,SAChB,MAAM,KAAK,GAAG,KAAK,UAAU,EAAE,CAAC,IAAI,SAAS,EAAE,CACnD,OAAS,EAAQ,CAMb,MALY,IAAII,cAAS,CACrB,KAAM,+BACN,cAAe,0CAA0C,EAAE,GAC3D,cAAe,CAAA,CAClB,CAEL,CACJ,CAEA,MAAO,IAAI,MAAM,KAAK,GAAG,CAAC,GAC9B,CAGA,SAAS,8BAA8B,OAAa,CAChD,MAAI,CAAC,QAAU,OAAO,SAAW,EAAU,CAAA,EACpC,OAAO,MAAM,CAAC,CACzB,CAEA,SAAS,uBAAuB,OAA0B,OAAa,CACnE,GAAI,CAAC,OAAO,YAAc,OAAO,WAAW,SAAW,EAAG,MAAO,GACjE,MAAM,UAAY,OAAO,aACzB,OAAI,UAAU,eAAe,OAAe,KAAK,UAAU,MAAM,EAC1D,UAAU,cAAc,GAAG,MAAM,CAC5C,CAEA,SAAS,wBAAwB,OAA0B,YAAgB,CACvE,GAAI,CAAC,OAAO,cAAe,OAAO,YAClC,MAAM,UAAY,OAAO,aACzB,GAAI,UAAU,gBAAgB,QAAU,CAAC,YAAa,OAAO,YAE7D,GAAI,CACA,OAAI,uBAAuBA,KAAAA,SAAiB,YACxCD,KAAAA,WAAW,WAAW,EAAU,IAAIC,KAAAA,SAAS,WAAW,EACrD,UAAU,gBAAgB,GAAG,WAAW,CACnD,OAAS,EAAQ,CACb,OAAO,IAAIA,KAAAA,SAAS,CAChB,KAAM,wBACN,cAAe,4CAA4C,OAAO,EAAE,wCAAwC,EAAE,OAAO,GACrH,UAAW,GAAG,MAAA,CACjB,CACL,CACJ"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ResponseBody } from '@mionjs/router';
|
|
2
|
-
import { MionClientRequest } from '
|
|
2
|
+
import { MionClientRequest } from '../request.ts';
|
|
3
3
|
export type SerializedBody = string | Uint8Array;
|
|
4
4
|
export type ContentType = 'application/json; charset=utf-8' | 'application/octet-stream';
|
|
5
5
|
export interface SerializedRequest {
|
|
@@ -8,6 +8,3 @@ export interface SerializedRequest {
|
|
|
8
8
|
}
|
|
9
9
|
export declare function serializeRequestBody(req: MionClientRequest<any, any>): SerializedRequest;
|
|
10
10
|
export declare function deserializeResponseBody(response: Response): Promise<ResponseBody>;
|
|
11
|
-
export declare type __ΩSerializedBody = any[];
|
|
12
|
-
export declare type __ΩContentType = any[];
|
|
13
|
-
export declare type __ΩSerializedRequest = any[];
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const STORAGE_GLOBAL_KEY="__mion_storage__";class MemoryStorage{data=new Map;get length(){return this.data.size}getItem(key){return this.data.get(key)??null}setItem(key,value){this.data.set(key,value)}removeItem(key){this.data.delete(key)}clear(){this.data.clear()}key(index){return[...this.data.keys()][index]??null}}function getStorage(){const existing=globalThis[STORAGE_GLOBAL_KEY];if(existing)return existing;let storage;try{typeof localStorage<"u"?(localStorage.setItem("__mion_test__","1"),localStorage.removeItem("__mion_test__"),storage=localStorage):storage=new MemoryStorage}catch{storage=new MemoryStorage}return globalThis[STORAGE_GLOBAL_KEY]=storage,storage}function resetStorageInstance(){delete globalThis[STORAGE_GLOBAL_KEY]}exports.MemoryStorage=MemoryStorage;exports.getStorage=getStorage;exports.resetStorageInstance=resetStorageInstance;
|
|
2
|
+
//# sourceMappingURL=storage.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage.cjs","sources":["../../../../src/lib/storage.ts"],"sourcesContent":["/* ########\n * 2024 mion\n * Author: Ma-jerez\n * License: MIT\n * The software is provided \"as is\", without warranty of any kind.\n * ######## */\n\nconst STORAGE_GLOBAL_KEY = '__mion_storage__';\n\n/** In-memory Storage implementation for SSR/Node environments where localStorage is not available */\nexport class MemoryStorage {\n private data = new Map<string, string>();\n get length() {\n return this.data.size;\n }\n getItem(key: string): string | null {\n return this.data.get(key) ?? null;\n }\n setItem(key: string, value: string) {\n this.data.set(key, value);\n }\n removeItem(key: string) {\n this.data.delete(key);\n }\n clear() {\n this.data.clear();\n }\n key(index: number): string | null {\n return [...this.data.keys()][index] ?? null;\n }\n}\n\n/** Returns localStorage if available, otherwise a MemoryStorage instance.\n * Uses globalThis to ensure the same instance is shared across module boundaries. */\nexport function getStorage(): Storage | MemoryStorage {\n const existing = (globalThis as any)[STORAGE_GLOBAL_KEY];\n if (existing) return existing;\n let storage: Storage | MemoryStorage;\n try {\n if (typeof localStorage !== 'undefined') {\n localStorage.setItem('__mion_test__', '1');\n localStorage.removeItem('__mion_test__');\n storage = localStorage;\n } else {\n storage = new MemoryStorage();\n }\n } catch {\n storage = new MemoryStorage();\n }\n (globalThis as any)[STORAGE_GLOBAL_KEY] = storage;\n return storage;\n}\n\n/** Reset storage instance, useful for testing */\nexport function resetStorageInstance() {\n delete (globalThis as any)[STORAGE_GLOBAL_KEY];\n}\n"],"names":[],"mappings":"gFAOA,MAAM,mBAAqB,yBAGd,aAAa,CACd,SAAW,IACnB,IAAI,QAAM,CACN,OAAO,KAAK,KAAK,IACrB,CACA,QAAQ,IAAW,CACf,OAAO,KAAK,KAAK,IAAI,GAAG,GAAK,IACjC,CACA,QAAQ,IAAa,MAAa,CAC9B,KAAK,KAAK,IAAI,IAAK,KAAK,CAC5B,CACA,WAAW,IAAW,CAClB,KAAK,KAAK,OAAO,GAAG,CACxB,CACA,OAAK,CACD,KAAK,KAAK,MAAA,CACd,CACA,IAAI,MAAa,CACb,MAAO,CAAC,GAAG,KAAK,KAAK,MAAM,EAAE,KAAK,GAAK,IAC3C,CACH,UAIe,YAAU,CACtB,MAAM,SAAY,WAAmB,kBAAkB,EACvD,GAAI,SAAU,OAAO,SACrB,IAAI,QACJ,GAAI,CACI,OAAO,aAAiB,KACxB,aAAa,QAAQ,gBAAiB,GAAG,EACzC,aAAa,WAAW,eAAe,EACvC,QAAU,cAEV,QAAU,IAAI,aAEtB,MAAQ,CACJ,QAAU,IAAI,aAClB,CACC,kBAAmB,kBAAkB,EAAI,QACnC,OACX,UAGgB,sBAAoB,CAChC,OAAQ,WAAmB,kBAAkB,CACjD"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const core=require("@mionjs/core"),src_aot_aotCaches=require("../aot/aotCaches.cjs");function resetClientCaches(){const{jitFnsCache,pureFnsCache}=src_aot_aotCaches.getAOTCaches(),mionRouteIds=new Set(Object.values(core.MION_ROUTES)),cache=core.routesCache.getCache();for(const key in cache)mionRouteIds.has(key)||delete cache[key];core.resetJitFnCaches(),core.resetJitFunctionsCache();const neededJitHashes=new Set,neededPureFnKeys=new Set;for(const routeId of mionRouteIds){const meta=core.routesCache.getMetadata(routeId);meta&&(collectJitDepsFromParentHash(meta.paramsJitHash,neededJitHashes,neededPureFnKeys,jitFnsCache),collectJitDepsFromParentHash(meta.returnJitHash,neededJitHashes,neededPureFnKeys,jitFnsCache),meta.headersParam&&collectJitDepsFromParentHash(meta.headersParam.jitHash,neededJitHashes,neededPureFnKeys,jitFnsCache),meta.headersReturn&&collectJitDepsFromParentHash(meta.headersReturn.jitHash,neededJitHashes,neededPureFnKeys,jitFnsCache))}const filteredJitFns={};for(const hash of neededJitHashes)hash in jitFnsCache&&(filteredJitFns[hash]=jitFnsCache[hash]);const filteredPureFns={};for(const key of neededPureFnKeys){const[ns,fnHash]=key.split("::");pureFnsCache[ns]?.[fnHash]&&(filteredPureFns[ns]||(filteredPureFns[ns]={}),filteredPureFns[ns][fnHash]=pureFnsCache[ns][fnHash])}(Object.keys(filteredJitFns).length>0||Object.keys(filteredPureFns).length>0)&&core.addAOTCaches(filteredJitFns,filteredPureFns)}function collectJitDepsFromParentHash(parentHash,jitHashes,pureFnKeys,jitFnsCache){if(!parentHash)return;const hashes=core.getJitFnHashes(parentHash);for(const individualHash of Object.values(hashes))collectJitDeps(individualHash,jitHashes,pureFnKeys,jitFnsCache)}function collectJitDeps(hash,jitHashes,pureFnKeys,jitFnsCache){if(!hash||jitHashes.has(hash))return;jitHashes.add(hash);const entry=jitFnsCache[hash];if(entry){for(const dep of entry.jitDependencies)collectJitDeps(dep,jitHashes,pureFnKeys,jitFnsCache);for(const pureDep of entry.pureFnDependencies)pureFnKeys.add(pureDep)}}exports.resetClientCaches=resetClientCaches;
|
|
2
|
+
//# sourceMappingURL=testUtils.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"testUtils.cjs","sources":["../../../../src/lib/testUtils.ts"],"sourcesContent":["/* ########\n * 2024 mion\n * Author: Ma-jerez\n * License: MIT\n * The software is provided \"as is\", without warranty of any kind.\n * ######## */\n\nimport {addAOTCaches, resetJitFnCaches, resetJitFunctionsCache, MION_ROUTES, getJitFnHashes, routesCache} from '@mionjs/core';\nimport type {PersistedJitFunctionsCache} from '@mionjs/core';\nimport {getAOTCaches} from '../aot/aotCaches.ts';\n\n/**\n * Resets client caches preserving MION internal routes and their JIT dependencies.\n * Only for testing — simulates app restart without losing MION infrastructure.\n */\nexport function resetClientCaches() {\n const {jitFnsCache, pureFnsCache} = getAOTCaches();\n // Clear only user routes, keep internal MION_ROUTES (needed for fetch calls)\n const mionRouteIds = new Set(Object.values(MION_ROUTES) as string[]);\n const cache = routesCache.getCache();\n for (const key in cache) {\n if (!mionRouteIds.has(key)) delete cache[key];\n }\n // Full JIT reset is safe — only MION internal route JIT caches will be re-registered below\n resetJitFnCaches();\n resetJitFunctionsCache();\n // Collect individual JIT hashes needed by MION internal routes and their transitive dependencies\n const neededJitHashes = new Set<string>();\n const neededPureFnKeys = new Set<string>();\n for (const routeId of mionRouteIds) {\n const meta = routesCache.getMetadata(routeId);\n if (!meta) continue;\n collectJitDepsFromParentHash(meta.paramsJitHash, neededJitHashes, neededPureFnKeys, jitFnsCache);\n collectJitDepsFromParentHash(meta.returnJitHash, neededJitHashes, neededPureFnKeys, jitFnsCache);\n if (meta.headersParam)\n collectJitDepsFromParentHash(meta.headersParam.jitHash, neededJitHashes, neededPureFnKeys, jitFnsCache);\n if (meta.headersReturn)\n collectJitDepsFromParentHash(meta.headersReturn.jitHash, neededJitHashes, neededPureFnKeys, jitFnsCache);\n }\n // Re-register only the filtered AOT caches for MION internal routes\n const filteredJitFns: Record<string, any> = {};\n for (const hash of neededJitHashes) {\n if (hash in jitFnsCache) filteredJitFns[hash] = jitFnsCache[hash];\n }\n const filteredPureFns: Record<string, Record<string, any>> = {};\n for (const key of neededPureFnKeys) {\n const [ns, fnHash] = key.split('::');\n if (pureFnsCache[ns]?.[fnHash]) {\n if (!filteredPureFns[ns]) filteredPureFns[ns] = {};\n filteredPureFns[ns][fnHash] = pureFnsCache[ns][fnHash];\n }\n }\n if (Object.keys(filteredJitFns).length > 0 || Object.keys(filteredPureFns).length > 0) {\n addAOTCaches(filteredJitFns, filteredPureFns);\n }\n}\n\n/** Expands a parent JIT hash into individual function hashes and collects their transitive dependencies */\nfunction collectJitDepsFromParentHash(\n parentHash: string,\n jitHashes: Set<string>,\n pureFnKeys: Set<string>,\n jitFnsCache: PersistedJitFunctionsCache\n) {\n if (!parentHash) return;\n const hashes = getJitFnHashes(parentHash);\n for (const individualHash of Object.values(hashes) as string[]) {\n collectJitDeps(individualHash, jitHashes, pureFnKeys, jitFnsCache);\n }\n}\n\n/** Transitively collects JIT and pure function dependency hashes from the AOT cache */\nfunction collectJitDeps(hash: string, jitHashes: Set<string>, pureFnKeys: Set<string>, jitFnsCache: PersistedJitFunctionsCache) {\n if (!hash || jitHashes.has(hash)) return;\n jitHashes.add(hash);\n const entry = jitFnsCache[hash];\n if (!entry) return;\n for (const dep of entry.jitDependencies) collectJitDeps(dep, jitHashes, pureFnKeys, jitFnsCache);\n for (const pureDep of entry.pureFnDependencies) pureFnKeys.add(pureDep);\n}\n"],"names":["getAOTCaches","MION_ROUTES","routesCache","resetJitFnCaches","resetJitFunctionsCache","addAOTCaches","getJitFnHashes"],"mappings":"8KAegB,mBAAiB,CAC7B,KAAM,CAAC,YAAa,YAAA,EAAgBA,+BAAA,EAE9B,aAAe,IAAI,IAAI,OAAO,OAAOC,KAAAA,WAAW,CAAa,EAC7D,MAAQC,KAAAA,YAAY,SAAA,EAC1B,UAAW,OAAO,MACT,aAAa,IAAI,GAAG,GAAG,OAAO,MAAM,GAAG,EAGhDC,sBAAA,EACAC,4BAAA,EAEA,MAAM,oBAAsB,IACtB,qBAAuB,IAC7B,UAAW,WAAW,aAAc,CAChC,MAAM,KAAOF,KAAAA,YAAY,YAAY,OAAO,EACvC,OACL,6BAA6B,KAAK,cAAe,gBAAiB,iBAAkB,WAAW,EAC/F,6BAA6B,KAAK,cAAe,gBAAiB,iBAAkB,WAAW,EAC3F,KAAK,cACL,6BAA6B,KAAK,aAAa,QAAS,gBAAiB,iBAAkB,WAAW,EACtG,KAAK,eACL,6BAA6B,KAAK,cAAc,QAAS,gBAAiB,iBAAkB,WAAW,EAC/G,CAEA,MAAM,eAAsC,CAAA,EAC5C,UAAW,QAAQ,gBACX,QAAQ,cAAa,eAAe,IAAI,EAAI,YAAY,IAAI,GAEpE,MAAM,gBAAuD,CAAA,EAC7D,UAAW,OAAO,iBAAkB,CAChC,KAAM,CAAC,GAAI,MAAM,EAAI,IAAI,MAAM,IAAI,EAC/B,aAAa,EAAE,IAAI,MAAM,IACpB,gBAAgB,EAAE,IAAG,gBAAgB,EAAE,EAAI,CAAA,GAChD,gBAAgB,EAAE,EAAE,MAAM,EAAI,aAAa,EAAE,EAAE,MAAM,EAE7D,EACI,OAAO,KAAK,cAAc,EAAE,OAAS,GAAK,OAAO,KAAK,eAAe,EAAE,OAAS,IAChFG,KAAAA,aAAa,eAAgB,eAAe,CAEpD,CAGA,SAAS,6BACL,WACA,UACA,WACA,YAAuC,CAEvC,GAAI,CAAC,WAAY,OACjB,MAAM,OAASC,KAAAA,eAAe,UAAU,EACxC,UAAW,kBAAkB,OAAO,OAAO,MAAM,EAC7C,eAAe,eAAgB,UAAW,WAAY,WAAW,CAEzE,CAGA,SAAS,eAAe,KAAc,UAAwB,WAAyB,YAAuC,CAC1H,GAAI,CAAC,MAAQ,UAAU,IAAI,IAAI,EAAG,OAClC,UAAU,IAAI,IAAI,EAClB,MAAM,MAAQ,YAAY,IAAI,EAC9B,GAAK,MACL,WAAW,OAAO,MAAM,gBAAiB,eAAe,IAAK,UAAW,WAAY,WAAW,EAC/F,UAAW,WAAW,MAAM,mBAAoB,WAAW,IAAI,OAAO,EAC1E"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});class TypedEvent{handlerId;registry;constructor(handlerId,registry){this.handlerId=handlerId,this.registry=registry}onSuccess(handler){return this.registry.registerSuccess(this.handlerId,handler),this}offSuccess(){return this.registry.unregisterSuccess(this.handlerId),this}onError(errorType,handler){return this.registry.register(this.handlerId,errorType,handler),this}offError(errorType){return this.registry.unregister(this.handlerId,errorType),this}getHandlerId(){return this.handlerId}hasErrorHandler(errorType){return this.registry.hasHandler(this.handlerId,errorType)}hasSuccessHandler(){return this.registry.hasSuccessHandler(this.handlerId)}}exports.TypedEvent=TypedEvent;
|
|
2
|
+
//# sourceMappingURL=typedEvent.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"typedEvent.cjs","sources":["../../../../src/lib/typedEvent.ts"],"sourcesContent":["/* ########\n * 2025 mion\n * Author: Ma-jerez\n * License: MIT\n * The software is provided \"as is\", without warranty of any kind.\n * ######## */\n\nimport type {RpcError} from '@mionjs/core';\nimport type {HandlersRegistry} from './handlersRegistry.ts';\nimport type {ErrorHandler, SuccessHandler} from '../types.ts';\n\n/** Persistent event emitter for middleFn success and error handling */\nexport class TypedEvent<S = void, E extends RpcError<string, any> = never> {\n constructor(\n private readonly handlerId: string,\n private readonly registry: HandlersRegistry\n ) {}\n\n /** Register a persistent success handler for this middleFn */\n onSuccess(handler: SuccessHandler<S>): TypedEvent<S, E> {\n this.registry.registerSuccess(this.handlerId, handler);\n return this;\n }\n\n /** Remove a previously registered success handler from HandlersRegistry */\n offSuccess(): TypedEvent<S, E> {\n this.registry.unregisterSuccess(this.handlerId);\n return this;\n }\n\n /** Register a persistent error handler for this middleFn */\n onError<T extends E['type']>(errorType: T, handler: (error: Extract<E, {type: T}>) => void): TypedEvent<S, E> {\n this.registry.register(this.handlerId, errorType, handler as ErrorHandler<any>);\n return this;\n }\n\n /** Remove a previously registered error handler from HandlersRegistry */\n offError<T extends E['type']>(errorType: T): TypedEvent<S, E> {\n this.registry.unregister(this.handlerId, errorType);\n return this;\n }\n\n /** Get the handler ID this event is associated with */\n getHandlerId(): string {\n return this.handlerId;\n }\n\n /** Check if an error handler is registered for a specific error type */\n hasErrorHandler(errorType: string): boolean {\n return this.registry.hasHandler(this.handlerId, errorType);\n }\n\n /** Check if a success handler is registered */\n hasSuccessHandler(): boolean {\n return this.registry.hasSuccessHandler(this.handlerId);\n }\n}\n"],"names":[],"mappings":"sFAYa,UAAU,CAEE,UACA,SAFrB,YACqB,UACA,SAA0B,CAD1B,KAAA,UAAA,UACA,KAAA,SAAA,QAClB,CAGH,UAAU,QAA0B,CAChC,YAAK,SAAS,gBAAgB,KAAK,UAAW,OAAO,EAC9C,IACX,CAGA,YAAU,CACN,YAAK,SAAS,kBAAkB,KAAK,SAAS,EACvC,IACX,CAGA,QAA6B,UAAc,QAA+C,CACtF,YAAK,SAAS,SAAS,KAAK,UAAW,UAAW,OAA4B,EACvE,IACX,CAGA,SAA8B,UAAY,CACtC,YAAK,SAAS,WAAW,KAAK,UAAW,SAAS,EAC3C,IACX,CAGA,cAAY,CACR,OAAO,KAAK,SAChB,CAGA,gBAAgB,UAAiB,CAC7B,OAAO,KAAK,SAAS,WAAW,KAAK,UAAW,SAAS,CAC7D,CAGA,mBAAiB,CACb,OAAO,KAAK,SAAS,kBAAkB,KAAK,SAAS,CACzD,CACH"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { RpcError } from '@mionjs/core';
|
|
2
2
|
import { HandlersRegistry } from './handlersRegistry.ts';
|
|
3
|
-
import { SuccessHandler } from '
|
|
3
|
+
import { SuccessHandler } from '../types.ts';
|
|
4
4
|
export declare class TypedEvent<S = void, E extends RpcError<string, any> = never> {
|
|
5
5
|
private readonly handlerId;
|
|
6
6
|
private readonly registry;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const core=require("@mionjs/core");function validateSubRequests(subRequestIds,req,errors,validateRouteMiddleFns=!0){req.options.validateParams&&subRequestIds.forEach(id=>{const subRequest=req.subRequestList[id];validateSubRequest(id,subRequest,errors);const methodMeta=core.routesCache.getMetadata(id);if(validateRouteMiddleFns&&methodMeta?.middleFnIds?.length){const validMiddleFnIds=methodMeta.middleFnIds.filter(middleFnId=>middleFnId!=null);validateSubRequests(validMiddleFnIds,req,errors,validateRouteMiddleFns)}})}function validateSubRequest(id,subRequest,errors){if(subRequest?.error||subRequest?.isResolved)return;const mappings=subRequest?.mappings;if(Array.isArray(mappings)&&mappings.length>0)return;const params=subRequest?.params||[],validationResponse=getTypeErrors(id,params);if(!validationResponse)return;const error=validationResponse;errors.set(id,error),subRequest&&(subRequest.error=error,subRequest.isResolved=!0)}function getTypeErrors(id,params){const method=core.routesCache.useMethodJitFns(id);if(!method.paramNames||method.paramNames.length===0)return;const paramsJit=method.paramsJitFns;if(!paramsJit.typeErrors.isNoop)try{const validationsResponse=paramsJit.isType.fn(params)||paramsJit.typeErrors.fn(params);if(validationsResponse?.length)return new core.RpcError({type:"validation-error",publicMessage:`Invalid params for Route or MiddleFn '${method.id}', validation failed.`,errorData:validationsResponse})}catch(e){return new core.RpcError({type:"unexpected-validation-error",publicMessage:`Could not validate params for Route or MiddleFn '${method.id}': ${e.message} `})}}exports.validateSubRequest=validateSubRequest;exports.validateSubRequests=validateSubRequests;
|
|
2
|
+
//# sourceMappingURL=validation.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation.cjs","sources":["../../../../src/lib/validation.ts"],"sourcesContent":["/* ########\n * 2023 mion\n * Author: Ma-jerez\n * License: MIT\n * The software is provided \"as is\", without warranty of any kind.\n * ######## */\n\nimport {RpcError, routesCache} from '@mionjs/core';\nimport {RequestErrors, SubRequest} from '../types.ts';\nimport type {MionClientRequest} from '../request.ts';\n\n/** Validate subRequests locally using existing RemoteApi metadata */\nexport function validateSubRequests(\n subRequestIds: string[],\n req: MionClientRequest<any, any>,\n errors: RequestErrors,\n validateRouteMiddleFns = true\n): void {\n if (!req.options.validateParams) return;\n subRequestIds.forEach((id) => {\n const subRequest = req.subRequestList[id];\n validateSubRequest(id, subRequest, errors);\n const methodMeta = routesCache.getMetadata(id);\n if (validateRouteMiddleFns && methodMeta?.middleFnIds?.length) {\n const validMiddleFnIds = methodMeta.middleFnIds.filter((middleFnId) => middleFnId != null);\n validateSubRequests(validMiddleFnIds, req, errors, validateRouteMiddleFns);\n }\n });\n return;\n}\n\n/** Validate subRequest locally using existing RemoteApi metadata */\nexport function validateSubRequest(id: string, subRequest: SubRequest<any>, errors: RequestErrors): void {\n if (subRequest?.error || subRequest?.isResolved) return;\n // Skip validation for subrequests with mapFrom mappings — params contain null placeholders\n // that will be filled by the server's mapping step after the source route executes\n const mappings = (subRequest as any)?.mappings;\n if (Array.isArray(mappings) && mappings.length > 0) return;\n\n const params = subRequest?.params || [];\n const validationResponse = getTypeErrors(id, params);\n if (!validationResponse) return;\n const error = validationResponse;\n errors.set(id, error);\n if (subRequest) {\n subRequest.error = error;\n subRequest.isResolved = true;\n }\n return;\n}\n\nfunction getTypeErrors(id: string, params: any[]): void | RpcError<'validation-error' | 'unexpected-validation-error'> {\n const method = routesCache.useMethodJitFns(id);\n if (!method.paramNames || method.paramNames.length === 0) return;\n const paramsJit = method.paramsJitFns;\n if (paramsJit.typeErrors.isNoop) return;\n try {\n const validationsResponse = paramsJit.isType.fn(params) || paramsJit.typeErrors.fn(params);\n if ((validationsResponse as [])?.length) {\n return new RpcError({\n type: 'validation-error',\n publicMessage: `Invalid params for Route or MiddleFn '${method.id}', validation failed.`,\n errorData: validationsResponse,\n });\n }\n } catch (e: any | Error) {\n return new RpcError({\n type: 'unexpected-validation-error',\n publicMessage: `Could not validate params for Route or MiddleFn '${method.id}': ${e.message} `,\n });\n }\n}\n"],"names":["routesCache","RpcError"],"mappings":"mHAYM,SAAU,oBACZ,cACA,IACA,OACA,uBAAyB,GAAI,CAExB,IAAI,QAAQ,gBACjB,cAAc,QAAS,IAAM,CACzB,MAAM,WAAa,IAAI,eAAe,EAAE,EACxC,mBAAmB,GAAI,WAAY,MAAM,EACzC,MAAM,WAAaA,KAAAA,YAAY,YAAY,EAAE,EAC7C,GAAI,wBAA0B,YAAY,aAAa,OAAQ,CAC3D,MAAM,iBAAmB,WAAW,YAAY,OAAQ,YAAe,YAAc,IAAI,EACzF,oBAAoB,iBAAkB,IAAK,OAAQ,sBAAsB,CAC7E,CACJ,CAAC,CAEL,UAGgB,mBAAmB,GAAY,WAA6B,OAAqB,CAC7F,GAAI,YAAY,OAAS,YAAY,WAAY,OAGjD,MAAM,SAAY,YAAoB,SACtC,GAAI,MAAM,QAAQ,QAAQ,GAAK,SAAS,OAAS,EAAG,OAEpD,MAAM,OAAS,YAAY,QAAU,CAAA,EAC/B,mBAAqB,cAAc,GAAI,MAAM,EACnD,GAAI,CAAC,mBAAoB,OACzB,MAAM,MAAQ,mBACd,OAAO,IAAI,GAAI,KAAK,EAChB,aACA,WAAW,MAAQ,MACnB,WAAW,WAAa,GAGhC,CAEA,SAAS,cAAc,GAAY,OAAa,CAC5C,MAAM,OAASA,KAAAA,YAAY,gBAAgB,EAAE,EAC7C,GAAI,CAAC,OAAO,YAAc,OAAO,WAAW,SAAW,EAAG,OAC1D,MAAM,UAAY,OAAO,aACzB,GAAI,WAAU,WAAW,OACzB,GAAI,CACA,MAAM,oBAAsB,UAAU,OAAO,GAAG,MAAM,GAAK,UAAU,WAAW,GAAG,MAAM,EACzF,GAAK,qBAA4B,OAC7B,OAAO,IAAIC,KAAAA,SAAS,CAChB,KAAM,mBACN,cAAe,yCAAyC,OAAO,EAAE,wBACjE,UAAW,mBAAA,CACd,CAET,OAAS,EAAgB,CACrB,OAAO,IAAIA,KAAAA,SAAS,CAChB,KAAM,8BACN,cAAe,oDAAoD,OAAO,EAAE,MAAM,EAAE,OAAO,GAAA,CAC9F,CACL,CACJ"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { RequestErrors, SubRequest } from '
|
|
2
|
-
import { MionClientRequest } from '
|
|
1
|
+
import { RequestErrors, SubRequest } from '../types.ts';
|
|
2
|
+
import { MionClientRequest } from '../request.ts';
|
|
3
3
|
export declare function validateSubRequests(subRequestIds: string[], req: MionClientRequest<any, any>, errors: RequestErrors, validateRouteMiddleFns?: boolean): void;
|
|
4
4
|
export declare function validateSubRequest(id: string, subRequest: SubRequest<any>, errors: RequestErrors): void;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const src_types=require("./types.cjs"),core=require("@mionjs/core"),src_clientMethodsMetadata=require("./clientMethodsMetadata.cjs"),src_validation=require("./validation.cjs"),src_serializer=require("./serializer.cjs"),src_constants=require("./constants.cjs"),__ΩRecord=["K","T","Record",`l'e#"Rb!b"Pde"!N#!w#y`];function __assignType(fn,args){return fn.__type=args,fn}class MionClientRequest{options;prefilledMiddleFnsCache;route;middleFns;workflowSubRequests;path;requestId;subRequestList={};response;constructor(options,prefilledMiddleFnsCache,route,middleFns,workflowSubRequests){if(this.options=options,this.prefilledMiddleFnsCache=prefilledMiddleFnsCache,this.route=route,this.middleFns=middleFns,this.workflowSubRequests=workflowSubRequests,workflowSubRequests&&workflowSubRequests.length>0){const routePaths=workflowSubRequests.map(__assignType(sr=>core.getRoutePath(sr.pointer,this.options),["sr","",'P"2!"/"'])),query=buildRoutesFlowQuery(routePaths,workflowSubRequests),flowPath=core.getRoutePath([src_constants.ROUTES_FLOW_KEY],this.options);this.path=`${flowPath}?data=${core.toBase64Url(JSON.stringify(query))}`,this.requestId="mion-routes-flow",workflowSubRequests.forEach(__assignType(sr=>this.addSubRequest(sr),["sr","",'P"2!"/"']))}else this.path=route?core.getRoutePath(route.pointer,this.options):"no-route",this.requestId=route?route.id:"no-route",route&&this.addSubRequest(route);middleFns&&middleFns.forEach(__assignType(middleFn=>this.addSubRequest(middleFn),["middleFn","",'P"2!"/"']))}async call(){const errors=new Map;try{const subRequestIds=Object.keys(this.subRequestList);if(await src_clientMethodsMetadata.fetchRemoteMethodsMetadata(subRequestIds,this.options),this.restorePrefilledMiddleFns(errors),errors.size||(src_validation.validateSubRequests(subRequestIds,this,errors),errors.size))return Promise.reject(errors)}catch(error){return this.onError(error,"Error preparing request",errors),Promise.reject(errors)}try{const serialized=src_serializer.serializeRequestBody(this),headersFromParams=extractRequestHeaders(this),url=new URL(this.path,this.options.baseURL);let fetchOptions;if(this.isQueryRoute()&&serialized.contentType.includes("json")){const encoded=core.toBase64Url(serialized.body),testUrl=new URL(this.path,this.options.baseURL);testUrl.searchParams.set("data",encoded),testUrl.toString().length<=src_constants.MAX_GET_URL_LENGTH?(url.searchParams.set("data",encoded),fetchOptions={...this.options.fetchOptions,method:"GET",headers:{...this.options.fetchOptions.headers,...headersFromParams},body:void 0}):fetchOptions={...this.options.fetchOptions,method:"POST",headers:{...this.options.fetchOptions.headers,...headersFromParams,"Content-Type":serialized.contentType},body:serialized.body}}else fetchOptions={...this.options.fetchOptions,method:"POST",headers:{...this.options.fetchOptions.headers,...headersFromParams,"Content-Type":serialized.contentType},body:serialized.body};this.response=await fetch(url,fetchOptions)}catch(error){return this.onError(error,"Error executing request",errors),Promise.reject(errors)}try{const deserialized=await src_serializer.deserializeResponseBody(this.response);if(core.MION_ROUTES.platformError in deserialized){const platformError=deserialized[core.MION_ROUTES.platformError];return Object.entries(this.subRequestList).forEach(__assignType(([id,methodMeta])=>{methodMeta.isResolved=!0,methodMeta.error=platformError,errors.set(id,platformError)},["param0","",'P"2!"/"'])),Promise.reject(errors)}return Object.entries(this.subRequestList).forEach(__assignType(([id,methodMeta])=>{const resp=this.getResponseValueFromBodyOrHeader(id,deserialized,this.response.headers);methodMeta.isResolved=!0,core.isRpcError(resp)?(methodMeta.error=resp,errors.set(id,resp)):methodMeta.resolvedValue=resp},["param0","",'P"2!"/"'])),Object.entries(deserialized).forEach(__assignType(([id,value])=>{!(id in this.subRequestList)&&core.isRpcError(value)&&errors.set(id,value)},["param0","",'P"2!"/"'])),errors.size?Promise.reject(errors):deserialized}catch(error){return this.onError(error,"Error parsing response",errors),Promise.reject(errors)}}async validateParams(subReqList){subReqList&&subReqList.forEach(__assignType(subRequest=>this.addSubRequest(subRequest),["subRequest","",'P"2!"/"']));const errors=new Map;try{const subRequestIds=Object.keys(this.subRequestList);return await src_clientMethodsMetadata.fetchRemoteMethodsMetadata(subRequestIds,this.options),src_validation.validateSubRequests(subRequestIds,this,errors,!1),Object.values(this.subRequestList).map(__assignType(subRequest=>subRequest.error?.errorData||[],["subRequest","",'P"2!"/"'])).flat()}catch(error){return this.onError(error,"Error preparing request",errors),Promise.reject(errors)}}async prefill(subReqList){subReqList&&subReqList.forEach(__assignType(subRequest=>this.addSubRequest(subRequest),["subRequest","",'P"2!"/"']));const errors=new Map;try{const subRequestIds=Object.keys(this.subRequestList);return await src_clientMethodsMetadata.fetchRemoteMethodsMetadata(subRequestIds,this.options),src_validation.validateSubRequests(subRequestIds,this,errors,!1),errors.size||(src_serializer.serializeRequestBody(this),this.storePrefilledMiddleFns(errors),errors.size)?Promise.reject(errors):void 0}catch(error){return this.onError(error,"Error preparing request",errors),Promise.reject(errors)}}async removePrefill(subRequests){subRequests&&subRequests.forEach(__assignType(subRequest=>this.addSubRequest(subRequest),["subRequest","",'P"2!"/"'])),this.removePrefilledMiddleFns()}addSubRequest(subRequest){if(subRequest.isResolved)throw new Error(`SubRequest ${subRequest.id} is already resolved`);this.subRequestList[subRequest.id]=subRequest}onError(error,stageMessage,errors){if(core.isRpcError(error)){errors.set(this.requestId,error);return}const message=error?.message?`${stageMessage}: ${error.message}`:`${stageMessage}: Unknown Error`;errors.set(this.requestId,new core.RpcError({type:error?.name||"unknown-error",publicMessage:message,originalError:error instanceof Error?error:void 0}))}getResponseValueFromBodyOrHeader(id,respBody,headers){const headersSubset=reconstructHeadersSubsetFromResponse(id,headers);return headersSubset||respBody[id]}restorePrefilledMiddleFns(errors){if(this.workflowSubRequests&&this.workflowSubRequests.length>0){this.restorePrefilledMiddleFnsForWorkflow(errors);return}const methodMeta=core.routesCache.getMetadata(this.requestId);if(!methodMeta){errors.set(this.requestId,new core.RpcError({type:"route-metadata-not-found",publicMessage:`Metadata for Route '${this.requestId} not found.'.`}));return}(methodMeta.middleFnIds?.filter(__assignType(id=>!!id&&this.requestId!==id,["id","",'P"2!"/"']))||[]).forEach(__assignType(id=>{if(this.subRequestList[id])return;const cacheKey=this.getPrefilledMiddleFnCacheKey(id),cachedSubRequest=this.prefilledMiddleFnsCache.get(cacheKey);if(cachedSubRequest){const clonedSubRequest={...cachedSubRequest,isResolved:!1,resolvedValue:void 0,error:void 0};this.addSubRequest(clonedSubRequest)}},["id","",'P"2!"/"']))}restorePrefilledMiddleFnsForWorkflow(errors){const workflowRouteIds=new Set(this.workflowSubRequests.map(__assignType(sr=>sr.id,["sr","",'P"2!"/"'])));for(const routeSubRequest of this.workflowSubRequests){const methodMeta=core.routesCache.getMetadata(routeSubRequest.id);if(!methodMeta){errors.set(routeSubRequest.id,new core.RpcError({type:"route-metadata-not-found",publicMessage:`Metadata for Route '${routeSubRequest.id}' not found.`}));continue}(methodMeta.middleFnIds?.filter(__assignType(id=>!!id&&!workflowRouteIds.has(id),["id","",'P"2!"/"']))||[]).forEach(__assignType(id=>{if(this.subRequestList[id])return;const cacheKey=this.getPrefilledMiddleFnCacheKey(id),cachedSubRequest=this.prefilledMiddleFnsCache.get(cacheKey);if(cachedSubRequest){const clonedSubRequest={...cachedSubRequest,isResolved:!1,resolvedValue:void 0,error:void 0};this.addSubRequest(clonedSubRequest)}},["id","",'P"2!"/"']))}}storePrefilledMiddleFns(errors){Object.keys(this.subRequestList).forEach(__assignType(id=>{const subRequest=this.subRequestList[id],methodMeta=core.routesCache.getMetadata(id);if(!methodMeta)throw new Error(`Remote method ${id} not found.`);if(methodMeta.type===core.HandlerType.route){errors.set(id,new core.RpcError({type:"routes-cant-be-prefilled",publicMessage:`Remote method ${id} is a route and can't be prefilled.`}));return}const cacheKey=this.getPrefilledMiddleFnCacheKey(id);this.prefilledMiddleFnsCache.set(cacheKey,subRequest)},["id","",'P"2!"/"']))}removePrefilledMiddleFns(){Object.keys(this.subRequestList).forEach(__assignType(id=>{const cacheKey=this.getPrefilledMiddleFnCacheKey(id);this.prefilledMiddleFnsCache.delete(cacheKey)},["id","",'P"2!"/"']))}isQueryRoute(){return this.workflowSubRequests?!1:core.routesCache.getMetadata(this.requestId)?.options?.isMutation===!1}getPrefilledMiddleFnCacheKey(id){return`${this.options.baseURL}:${id}`}static __type=["RR","MiddleFnRequestsList","path","requestId",()=>src_types.__ΩSubRequest,"subRequestList",function(){return{}},"response",()=>src_types.__ΩClientOptions,"options",()=>src_types.__ΩPrefilledMiddleFnsCache,"prefilledMiddleFnsCache","route","middleFns",()=>src_types.__ΩRSubRequest,"workflowSubRequests","constructor","ResponseBody","call",()=>src_types.__ΩSubRequest,"subReqList","RunTypeError","validateParams",()=>src_types.__ΩSubRequest,"prefill",()=>src_types.__ΩSubRequest,"subRequests","removePrefill",()=>src_types.__ΩSubRequest,"subRequest","addSubRequest","error","stageMessage",()=>src_types.__ΩRequestErrors,"errors","onError","id","respBody","headers","getResponseValueFromBodyOrHeader",()=>src_types.__ΩRequestErrors,"restorePrefilledMiddleFns",()=>src_types.__ΩRequestErrors,"restorePrefilledMiddleFnsForWorkflow",()=>src_types.__ΩRequestErrors,"storePrefilledMiddleFns","removePrefilledMiddleFns","isQueryRoute","getPrefilledMiddleFnCacheKey","MionClientRequest",'b!b"&3#9&3$9P&"o%"LM3&9>\'P!-J3(Pn)2*:9n+2,;9e"!2-8:9e""2.8:9"o/"F208:9"01P"w2`03P"o4"F258"w6F`07P"o8"F258$`09P"o:"F2;8$`0<P"o="2>"0?P"2@&2AnB2C$0D;P&2E"w22F!2G"0H;PnI2C$0J;PnK2C$0L;PnM2C$0N;P$0O;P)0P;P&2E&0Q;5wR']}function extractRequestHeaders(req){const headers={},subRequestIds=Object.keys(req.subRequestList);for(let i=0;i<subRequestIds.length;i++){const id=subRequestIds[i],subRequest=req.subRequestList[id];if(!subRequest)continue;const method=core.routesCache.getMetadata(id);if(!method||method.type!==core.HandlerType.headersMiddleFn||!method.headersParam)continue;const params=subRequest.params,extracted=extractHeadersFromParams(params);Object.assign(headers,extracted)}return headers}extractRequestHeaders.__type=[()=>MionClientRequest,"req",()=>__ΩRecord,"extractRequestHeaders",'PP""7!2"&&o##/$'];function extractHeadersFromParams(params){if(!params||params.length===0)throw new core.RpcError({type:"missing-headers-param",publicMessage:"HeadersFn requires a HeadersSubset parameter."});const firstParam=params[0];if(firstParam instanceof core.HeadersSubset||firstParam&&typeof firstParam=="object"&&"headers"in firstParam&&typeof firstParam.headers=="object")return firstParam.headers;throw new core.RpcError({type:"invalid-headers-param",publicMessage:"HeadersFn first parameter must be a HeadersSubset instance or object with headers property."})}extractHeadersFromParams.__type=["params",()=>__ΩRecord,"extractHeadersFromParams",'P"F2!&&o"#/#'];function reconstructHeadersSubsetFromResponse(methodId,responseHeaders){const method=core.routesCache.getMetadata(methodId);if(!method?.headersReturn?.headerNames||method.headersReturn.headerNames.length===0)return;const headerNames=method.headersReturn.headerNames,headersMap={};for(const name of headerNames){const value=responseHeaders.get(name);value!=null&&(headersMap[name]=value)}if(Object.keys(headersMap).length>0)return new core.HeadersSubset(headersMap)}reconstructHeadersSubsetFromResponse.__type=["methodId","responseHeaders",()=>core.HeadersSubset,"reconstructHeadersSubsetFromResponse",'P&2!!2"PP&&7#-J/$'];function buildRoutesFlowQuery(routePaths,workflowSubRequests){const allMappings=[];for(const sr of workflowSubRequests){const mappings=sr.mappings;if(Array.isArray(mappings)&&mappings.length>0)for(const ref of mappings)allMappings.push({fromId:ref.fromRequestId,toId:ref.toRequestId,bodyHash:ref.bodyHash,paramIndex:ref.paramIndex})}return{routes:routePaths,mappings:allMappings.length>0?allMappings:void 0}}buildRoutesFlowQuery.__type=["routePaths",()=>src_types.__ΩRSubRequest,"workflowSubRequests","RoutesFlowQuery","buildRoutesFlowQuery",'P&F2!"o""F2#"w$/%'];exports.MionClientRequest=MionClientRequest;
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const core=require("@mionjs/core"),src_lib_clientMethodsMetadata=require("./lib/clientMethodsMetadata.cjs"),src_lib_validation=require("./lib/validation.cjs"),src_lib_serializer=require("./lib/serializer.cjs"),src_constants=require("./constants.cjs");class MionClientRequest{options;prefilledMiddleFnsCache;route;middleFns;workflowSubRequests;path;requestId;subRequestList={};response;constructor(options,prefilledMiddleFnsCache,route,middleFns,workflowSubRequests){if(this.options=options,this.prefilledMiddleFnsCache=prefilledMiddleFnsCache,this.route=route,this.middleFns=middleFns,this.workflowSubRequests=workflowSubRequests,workflowSubRequests&&workflowSubRequests.length>0){const routePaths=workflowSubRequests.map(sr=>core.getRoutePath(sr.pointer,this.options)),query=buildRoutesFlowQuery(routePaths,workflowSubRequests),flowPath=core.getRoutePath([src_constants.ROUTES_FLOW_KEY],this.options);this.path=`${flowPath}?data=${core.toBase64Url(JSON.stringify(query))}`,this.requestId="mion-routes-flow",workflowSubRequests.forEach(sr=>this.addSubRequest(sr))}else this.path=route?core.getRoutePath(route.pointer,this.options):"no-route",this.requestId=route?route.id:"no-route",route&&this.addSubRequest(route);middleFns&&middleFns.forEach(middleFn=>this.addSubRequest(middleFn))}async call(){const errors=new Map;try{const subRequestIds=Object.keys(this.subRequestList);if(await src_lib_clientMethodsMetadata.fetchRemoteMethodsMetadata(subRequestIds,this.options),this.restorePrefilledMiddleFns(errors),errors.size||(src_lib_validation.validateSubRequests(subRequestIds,this,errors),errors.size))return Promise.reject(errors)}catch(error){return this.onError(error,"Error preparing request",errors),Promise.reject(errors)}try{const serialized=src_lib_serializer.serializeRequestBody(this),headersFromParams=extractRequestHeaders(this),url=new URL(this.path,this.options.baseURL);let fetchOptions;if(this.isQueryRoute()&&serialized.contentType.includes("json")){const encoded=core.toBase64Url(serialized.body),testUrl=new URL(this.path,this.options.baseURL);testUrl.searchParams.set("data",encoded),testUrl.toString().length<=src_constants.MAX_GET_URL_LENGTH?(url.searchParams.set("data",encoded),fetchOptions={...this.options.fetchOptions,method:"GET",headers:{...this.options.fetchOptions.headers,...headersFromParams},body:void 0}):fetchOptions={...this.options.fetchOptions,method:"POST",headers:{...this.options.fetchOptions.headers,...headersFromParams,"Content-Type":serialized.contentType},body:serialized.body}}else fetchOptions={...this.options.fetchOptions,method:"POST",headers:{...this.options.fetchOptions.headers,...headersFromParams,"Content-Type":serialized.contentType},body:serialized.body};this.response=await fetch(url,fetchOptions)}catch(error){return this.onError(error,"Error executing request",errors),Promise.reject(errors)}try{const deserialized=await src_lib_serializer.deserializeResponseBody(this.response);if(core.MION_ROUTES.platformError in deserialized){const platformError=deserialized[core.MION_ROUTES.platformError];return Object.entries(this.subRequestList).forEach(([id,methodMeta])=>{methodMeta.isResolved=!0,methodMeta.error=platformError,errors.set(id,platformError)}),Promise.reject(errors)}return Object.entries(this.subRequestList).forEach(([id,methodMeta])=>{const resp=this.getResponseValueFromBodyOrHeader(id,deserialized,this.response.headers);methodMeta.isResolved=!0,core.isRpcError(resp)?(methodMeta.error=resp,errors.set(id,resp)):methodMeta.resolvedValue=resp}),Object.entries(deserialized).forEach(([id,value])=>{!(id in this.subRequestList)&&core.isRpcError(value)&&errors.set(id,value)}),errors.size?Promise.reject(errors):deserialized}catch(error){return this.onError(error,"Error parsing response",errors),Promise.reject(errors)}}async validateParams(subReqList){subReqList&&subReqList.forEach(subRequest=>this.addSubRequest(subRequest));const errors=new Map;try{const subRequestIds=Object.keys(this.subRequestList);return await src_lib_clientMethodsMetadata.fetchRemoteMethodsMetadata(subRequestIds,this.options),src_lib_validation.validateSubRequests(subRequestIds,this,errors,!1),Object.values(this.subRequestList).map(subRequest=>subRequest.error?.errorData||[]).flat()}catch(error){return this.onError(error,"Error preparing request",errors),Promise.reject(errors)}}async prefill(subReqList){subReqList&&subReqList.forEach(subRequest=>this.addSubRequest(subRequest));const errors=new Map;try{const subRequestIds=Object.keys(this.subRequestList);return await src_lib_clientMethodsMetadata.fetchRemoteMethodsMetadata(subRequestIds,this.options),src_lib_validation.validateSubRequests(subRequestIds,this,errors,!1),errors.size||(src_lib_serializer.serializeRequestBody(this),this.storePrefilledMiddleFns(errors),errors.size)?Promise.reject(errors):void 0}catch(error){return this.onError(error,"Error preparing request",errors),Promise.reject(errors)}}async removePrefill(subRequests){subRequests&&subRequests.forEach(subRequest=>this.addSubRequest(subRequest)),this.removePrefilledMiddleFns()}addSubRequest(subRequest){if(subRequest.isResolved)throw new Error(`SubRequest ${subRequest.id} is already resolved`);this.subRequestList[subRequest.id]=subRequest}onError(error,stageMessage,errors){if(core.isRpcError(error)){errors.set(this.requestId,error);return}const message=error?.message?`${stageMessage}: ${error.message}`:`${stageMessage}: Unknown Error`;errors.set(this.requestId,new core.RpcError({type:error?.name||"unknown-error",publicMessage:message,originalError:error instanceof Error?error:void 0}))}getResponseValueFromBodyOrHeader(id,respBody,headers){const headersSubset=reconstructHeadersSubsetFromResponse(id,headers);return headersSubset||respBody[id]}restorePrefilledMiddleFns(errors){if(this.workflowSubRequests&&this.workflowSubRequests.length>0){this.restorePrefilledMiddleFnsForWorkflow(errors);return}const methodMeta=core.routesCache.getMetadata(this.requestId);if(!methodMeta){errors.set(this.requestId,new core.RpcError({type:"route-metadata-not-found",publicMessage:`Metadata for Route '${this.requestId} not found.'.`}));return}(methodMeta.middleFnIds?.filter(id=>!!id&&this.requestId!==id)||[]).forEach(id=>{if(this.subRequestList[id])return;const cacheKey=this.getPrefilledMiddleFnCacheKey(id),cachedSubRequest=this.prefilledMiddleFnsCache.get(cacheKey);if(cachedSubRequest){const clonedSubRequest={...cachedSubRequest,isResolved:!1,resolvedValue:void 0,error:void 0};this.addSubRequest(clonedSubRequest)}})}restorePrefilledMiddleFnsForWorkflow(errors){const workflowRouteIds=new Set(this.workflowSubRequests.map(sr=>sr.id));for(const routeSubRequest of this.workflowSubRequests){const methodMeta=core.routesCache.getMetadata(routeSubRequest.id);if(!methodMeta){errors.set(routeSubRequest.id,new core.RpcError({type:"route-metadata-not-found",publicMessage:`Metadata for Route '${routeSubRequest.id}' not found.`}));continue}(methodMeta.middleFnIds?.filter(id=>!!id&&!workflowRouteIds.has(id))||[]).forEach(id=>{if(this.subRequestList[id])return;const cacheKey=this.getPrefilledMiddleFnCacheKey(id),cachedSubRequest=this.prefilledMiddleFnsCache.get(cacheKey);if(cachedSubRequest){const clonedSubRequest={...cachedSubRequest,isResolved:!1,resolvedValue:void 0,error:void 0};this.addSubRequest(clonedSubRequest)}})}}storePrefilledMiddleFns(errors){Object.keys(this.subRequestList).forEach(id=>{const subRequest=this.subRequestList[id],methodMeta=core.routesCache.getMetadata(id);if(!methodMeta)throw new Error(`Remote method ${id} not found.`);if(methodMeta.type===core.HandlerType.route){errors.set(id,new core.RpcError({type:"routes-cant-be-prefilled",publicMessage:`Remote method ${id} is a route and can't be prefilled.`}));return}const cacheKey=this.getPrefilledMiddleFnCacheKey(id);this.prefilledMiddleFnsCache.set(cacheKey,subRequest)})}removePrefilledMiddleFns(){Object.keys(this.subRequestList).forEach(id=>{const cacheKey=this.getPrefilledMiddleFnCacheKey(id);this.prefilledMiddleFnsCache.delete(cacheKey)})}isQueryRoute(){return this.workflowSubRequests?!1:core.routesCache.getMetadata(this.requestId)?.options?.isMutation===!1}getPrefilledMiddleFnCacheKey(id){return`${this.options.baseURL}:${id}`}}function extractRequestHeaders(req){const headers={},subRequestIds=Object.keys(req.subRequestList);for(let i=0;i<subRequestIds.length;i++){const id=subRequestIds[i],subRequest=req.subRequestList[id];if(!subRequest)continue;const method=core.routesCache.getMetadata(id);if(!method||method.type!==core.HandlerType.headersMiddleFn||!method.headersParam)continue;const params=subRequest.params,extracted=extractHeadersFromParams(params);Object.assign(headers,extracted)}return headers}function extractHeadersFromParams(params){if(!params||params.length===0)throw new core.RpcError({type:"missing-headers-param",publicMessage:"HeadersFn requires a HeadersSubset parameter."});const firstParam=params[0];if(firstParam instanceof core.HeadersSubset||firstParam&&typeof firstParam=="object"&&"headers"in firstParam&&typeof firstParam.headers=="object")return firstParam.headers;throw new core.RpcError({type:"invalid-headers-param",publicMessage:"HeadersFn first parameter must be a HeadersSubset instance or object with headers property."})}function reconstructHeadersSubsetFromResponse(methodId,responseHeaders){const method=core.routesCache.getMetadata(methodId);if(!method?.headersReturn?.headerNames||method.headersReturn.headerNames.length===0)return;const headerNames=method.headersReturn.headerNames,headersMap={};for(const name of headerNames){const value=responseHeaders.get(name);value!=null&&(headersMap[name]=value)}if(Object.keys(headersMap).length>0)return new core.HeadersSubset(headersMap)}function buildRoutesFlowQuery(routePaths,workflowSubRequests){const allMappings=[];for(const sr of workflowSubRequests){const mappings=sr.mappings;if(Array.isArray(mappings)&&mappings.length>0)for(const ref of mappings)allMappings.push({fromId:ref.fromRequestId,toId:ref.toRequestId,bodyHash:ref.bodyHash,paramIndex:ref.paramIndex})}return{routes:routePaths,mappings:allMappings.length>0?allMappings:void 0}}exports.MionClientRequest=MionClientRequest;
|
|
2
2
|
//# sourceMappingURL=request.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"request.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
|
1
|
+
{"version":3,"file":"request.cjs","sources":["../../../src/request.ts"],"sourcesContent":["/* ########\n * 2023 mion\n * Author: Ma-jerez\n * License: MIT\n * The software is provided \"as is\", without warranty of any kind.\n * ######## */\n\nimport type {ResponseBody} from '@mionjs/router';\nimport {ClientOptions, HSubRequest, SubRequest, RSubRequest, RequestErrors, PrefilledMiddleFnsCache} from './types.ts';\nimport type {RunTypeError, RoutesFlowQuery, RoutesFlowMapping} from '@mionjs/core';\nimport {RpcError, isRpcError, routesCache, MION_ROUTES, HandlerType, HeadersSubset, toBase64Url} from '@mionjs/core';\nimport {getRoutePath} from '@mionjs/core';\nimport {fetchRemoteMethodsMetadata} from './lib/clientMethodsMetadata.ts';\nimport {validateSubRequests} from './lib/validation.ts';\nimport {serializeRequestBody, deserializeResponseBody} from './lib/serializer.ts';\nimport {ROUTES_FLOW_KEY, MAX_GET_URL_LENGTH} from './constants.ts';\n\nexport class MionClientRequest<RR extends RSubRequest<any>, MiddleFnRequestsList extends HSubRequest<any>[]> {\n readonly path: string;\n readonly requestId: string;\n readonly subRequestList: {[key: string]: SubRequest<any>} = {};\n response: Response | undefined;\n\n constructor(\n public readonly options: ClientOptions,\n private readonly prefilledMiddleFnsCache: PrefilledMiddleFnsCache,\n public readonly route?: RR,\n public readonly middleFns?: MiddleFnRequestsList,\n /** Array of routesFlow subrequests when executing a routesFlow */\n public readonly workflowSubRequests?: RSubRequest<any>[]\n ) {\n if (workflowSubRequests && workflowSubRequests.length > 0) {\n const routePaths = workflowSubRequests.map((sr) => getRoutePath(sr.pointer, this.options));\n const query = buildRoutesFlowQuery(routePaths, workflowSubRequests);\n const flowPath = getRoutePath([ROUTES_FLOW_KEY], this.options);\n this.path = `${flowPath}?data=${toBase64Url(JSON.stringify(query))}`;\n this.requestId = 'mion-routes-flow';\n workflowSubRequests.forEach((sr) => this.addSubRequest(sr));\n } else {\n this.path = route ? getRoutePath(route.pointer, this.options) : 'no-route';\n this.requestId = route ? route.id : 'no-route';\n if (route) this.addSubRequest(route);\n }\n if (middleFns) middleFns.forEach((middleFn) => this.addSubRequest(middleFn));\n }\n\n /** Calls a remote route */\n async call(): Promise<ResponseBody> {\n const errors: RequestErrors = new Map();\n\n try {\n const subRequestIds = Object.keys(this.subRequestList);\n await fetchRemoteMethodsMetadata(subRequestIds, this.options);\n\n this.restorePrefilledMiddleFns(errors);\n if (errors.size) return Promise.reject(errors);\n\n validateSubRequests(subRequestIds, this, errors);\n if (errors.size) return Promise.reject(errors);\n } catch (error: any) {\n this.onError(error, 'Error preparing request', errors);\n return Promise.reject(errors);\n }\n\n try {\n const serialized = serializeRequestBody(this);\n const headersFromParams = extractRequestHeaders(this);\n\n const url = new URL(this.path, this.options.baseURL);\n let fetchOptions: RequestInit;\n\n if (this.isQueryRoute() && serialized.contentType.includes('json')) {\n const encoded = toBase64Url(serialized.body as string);\n const testUrl = new URL(this.path, this.options.baseURL);\n testUrl.searchParams.set('data', encoded);\n\n if (testUrl.toString().length <= MAX_GET_URL_LENGTH) {\n url.searchParams.set('data', encoded);\n fetchOptions = {\n ...this.options.fetchOptions,\n method: 'GET',\n headers: {...this.options.fetchOptions.headers, ...headersFromParams},\n body: undefined,\n };\n } else {\n fetchOptions = {\n ...this.options.fetchOptions,\n method: 'POST',\n headers: {\n ...this.options.fetchOptions.headers,\n ...headersFromParams,\n 'Content-Type': serialized.contentType,\n },\n body: serialized.body as BodyInit,\n };\n }\n } else {\n fetchOptions = {\n ...this.options.fetchOptions,\n method: 'POST',\n headers: {...this.options.fetchOptions.headers, ...headersFromParams, 'Content-Type': serialized.contentType},\n body: serialized.body as BodyInit,\n };\n }\n this.response = await fetch(url, fetchOptions);\n } catch (error: any) {\n this.onError(error, 'Error executing request', errors);\n return Promise.reject(errors);\n }\n\n try {\n const deserialized = await deserializeResponseBody(this.response);\n\n if (MION_ROUTES.platformError in deserialized) {\n const platformError = deserialized[MION_ROUTES.platformError];\n Object.entries(this.subRequestList).forEach(([id, methodMeta]) => {\n methodMeta.isResolved = true;\n methodMeta.error = platformError as RpcError<string>;\n errors.set(id, platformError as RpcError<string>);\n });\n return Promise.reject(errors);\n }\n\n Object.entries(this.subRequestList).forEach(([id, methodMeta]) => {\n const resp = this.getResponseValueFromBodyOrHeader(id, deserialized, (this.response as Response).headers);\n methodMeta.isResolved = true;\n if (isRpcError(resp)) {\n methodMeta.error = resp;\n errors.set(id, resp);\n } else {\n methodMeta.resolvedValue = resp;\n }\n });\n\n Object.entries(deserialized).forEach(([id, value]) => {\n if (!(id in this.subRequestList) && isRpcError(value)) {\n errors.set(id, value);\n }\n });\n\n if (errors.size) return Promise.reject(errors);\n return deserialized;\n } catch (error) {\n this.onError(error, 'Error parsing response', errors);\n return Promise.reject(errors);\n }\n }\n\n /** Validate params */\n async validateParams(subReqList?: SubRequest<any>[]): Promise<RunTypeError[]> {\n if (subReqList) subReqList.forEach((subRequest) => this.addSubRequest(subRequest));\n const errors: RequestErrors = new Map();\n try {\n const subRequestIds = Object.keys(this.subRequestList);\n await fetchRemoteMethodsMetadata(subRequestIds, this.options);\n validateSubRequests(subRequestIds, this, errors, false);\n return Object.values(this.subRequestList)\n .map((subRequest) => subRequest.error?.errorData || [])\n .flat();\n } catch (error: any) {\n this.onError(error, 'Error preparing request', errors);\n return Promise.reject(errors);\n }\n }\n\n /** Prefills and stores SubRequest */\n async prefill(subReqList?: SubRequest<any>[]): Promise<void> {\n if (subReqList) subReqList.forEach((subRequest) => this.addSubRequest(subRequest));\n const errors: RequestErrors = new Map();\n try {\n const subRequestIds = Object.keys(this.subRequestList);\n await fetchRemoteMethodsMetadata(subRequestIds, this.options);\n\n validateSubRequests(subRequestIds, this, errors, false);\n if (errors.size) return Promise.reject(errors);\n\n serializeRequestBody(this);\n\n this.storePrefilledMiddleFns(errors);\n if (errors.size) return Promise.reject(errors);\n\n return;\n } catch (error: any) {\n this.onError(error, 'Error preparing request', errors);\n return Promise.reject(errors);\n }\n }\n\n /** Removes Prefills and stores SubRequest */\n async removePrefill(subRequests?: SubRequest<any>[]): Promise<void> {\n if (subRequests) subRequests.forEach((subRequest) => this.addSubRequest(subRequest));\n this.removePrefilledMiddleFns();\n }\n\n addSubRequest(subRequest: SubRequest<any>) {\n if (subRequest.isResolved) throw new Error(`SubRequest ${subRequest.id} is already resolved`);\n this.subRequestList[subRequest.id] = subRequest;\n }\n\n private onError(error: any, stageMessage: string, errors: RequestErrors): void {\n if (isRpcError(error)) {\n errors.set(this.requestId, error);\n return;\n }\n const message = error?.message ? `${stageMessage}: ${error.message}` : `${stageMessage}: Unknown Error`;\n errors.set(\n this.requestId,\n new RpcError({\n type: error?.name || 'unknown-error',\n publicMessage: message,\n originalError: error instanceof Error ? error : undefined,\n })\n );\n }\n\n private getResponseValueFromBodyOrHeader(id: string, respBody: ResponseBody, headers: Headers): any {\n const headersSubset = reconstructHeadersSubsetFromResponse(id, headers);\n if (headersSubset) return headersSubset;\n return respBody[id];\n }\n\n private restorePrefilledMiddleFns(errors: RequestErrors): void {\n if (this.workflowSubRequests && this.workflowSubRequests.length > 0) {\n this.restorePrefilledMiddleFnsForWorkflow(errors);\n return;\n }\n\n const methodMeta = routesCache.getMetadata(this.requestId);\n if (!methodMeta) {\n errors.set(\n this.requestId,\n new RpcError({\n type: 'route-metadata-not-found',\n publicMessage: `Metadata for Route '${this.requestId} not found.'.`,\n })\n );\n return;\n }\n const missingIds = methodMeta.middleFnIds?.filter((id) => !!id && this.requestId !== id) || [];\n missingIds.forEach((id) => {\n const subRequest = this.subRequestList[id];\n if (subRequest) return;\n const cacheKey = this.getPrefilledMiddleFnCacheKey(id);\n const cachedSubRequest = this.prefilledMiddleFnsCache.get(cacheKey);\n if (cachedSubRequest) {\n const clonedSubRequest: SubRequest<any> = {\n ...cachedSubRequest,\n isResolved: false,\n resolvedValue: undefined,\n error: undefined,\n };\n this.addSubRequest(clonedSubRequest);\n }\n });\n }\n\n /** Restore prefilled middleFns for all routes in a routesFlow, deduplicating by ID */\n private restorePrefilledMiddleFnsForWorkflow(errors: RequestErrors): void {\n const workflowRouteIds = new Set(this.workflowSubRequests!.map((sr) => sr.id));\n\n for (const routeSubRequest of this.workflowSubRequests!) {\n const methodMeta = routesCache.getMetadata(routeSubRequest.id);\n if (!methodMeta) {\n errors.set(\n routeSubRequest.id,\n new RpcError({\n type: 'route-metadata-not-found',\n publicMessage: `Metadata for Route '${routeSubRequest.id}' not found.`,\n })\n );\n continue;\n }\n const missingIds = methodMeta.middleFnIds?.filter((id) => !!id && !workflowRouteIds.has(id)) || [];\n missingIds.forEach((id) => {\n const subRequest = this.subRequestList[id];\n if (subRequest) return;\n const cacheKey = this.getPrefilledMiddleFnCacheKey(id);\n const cachedSubRequest = this.prefilledMiddleFnsCache.get(cacheKey);\n if (cachedSubRequest) {\n const clonedSubRequest: SubRequest<any> = {\n ...cachedSubRequest,\n isResolved: false,\n resolvedValue: undefined,\n error: undefined,\n };\n this.addSubRequest(clonedSubRequest);\n }\n });\n }\n }\n\n private storePrefilledMiddleFns(errors: RequestErrors): void {\n Object.keys(this.subRequestList).forEach((id) => {\n const subRequest = this.subRequestList[id];\n const methodMeta = routesCache.getMetadata(id);\n if (!methodMeta) throw new Error(`Remote method ${id} not found.`);\n if (methodMeta.type === HandlerType.route) {\n errors.set(\n id,\n new RpcError({\n type: 'routes-cant-be-prefilled',\n publicMessage: `Remote method ${id} is a route and can't be prefilled.`,\n })\n );\n return;\n }\n const cacheKey = this.getPrefilledMiddleFnCacheKey(id);\n this.prefilledMiddleFnsCache.set(cacheKey, subRequest);\n });\n }\n\n private removePrefilledMiddleFns(): void {\n Object.keys(this.subRequestList).forEach((id) => {\n const cacheKey = this.getPrefilledMiddleFnCacheKey(id);\n this.prefilledMiddleFnsCache.delete(cacheKey);\n });\n }\n\n /** Returns true if the route is a query (isMutation === false) and not a routesFlow */\n private isQueryRoute(): boolean {\n if (this.workflowSubRequests) return false;\n const meta = routesCache.getMetadata(this.requestId);\n // strict false value required for queries\n return meta?.options?.isMutation === false;\n }\n\n private getPrefilledMiddleFnCacheKey(id: string): string {\n return `${this.options.baseURL}:${id}`;\n }\n}\n\n/** Extracts headers from HeadersSubset params in headersFn methods */\nfunction extractRequestHeaders(req: MionClientRequest<any, any>): Record<string, string> {\n const headers: Record<string, string> = {};\n const subRequestIds = Object.keys(req.subRequestList);\n\n for (let i = 0; i < subRequestIds.length; i++) {\n const id = subRequestIds[i];\n const subRequest = req.subRequestList[id];\n if (!subRequest) continue;\n\n const method = routesCache.getMetadata(id);\n if (!method || method.type !== HandlerType.headersMiddleFn || !method.headersParam) continue;\n\n const params = subRequest.params;\n const extracted = extractHeadersFromParams(params);\n Object.assign(headers, extracted);\n }\n\n return headers;\n}\n\n/** Extracts headers from a HeadersSubset parameter */\nfunction extractHeadersFromParams(params: any[]): Record<string, string> {\n if (!params || params.length === 0) {\n throw new RpcError({\n type: 'missing-headers-param',\n publicMessage: 'HeadersFn requires a HeadersSubset parameter.',\n });\n }\n\n const firstParam = params[0];\n\n if (firstParam instanceof HeadersSubset) {\n return firstParam.headers as Record<string, string>;\n }\n\n if (firstParam && typeof firstParam === 'object' && 'headers' in firstParam && typeof firstParam.headers === 'object') {\n return firstParam.headers as Record<string, string>;\n }\n\n throw new RpcError({\n type: 'invalid-headers-param',\n publicMessage: 'HeadersFn first parameter must be a HeadersSubset instance or object with headers property.',\n });\n}\n\n/** Reconstructs a HeadersSubset from HTTP response headers for methods that return HeadersSubset */\nfunction reconstructHeadersSubsetFromResponse(\n methodId: string,\n responseHeaders: Headers\n): HeadersSubset<string, string> | undefined {\n const method = routesCache.getMetadata(methodId);\n\n if (!method?.headersReturn?.headerNames || method.headersReturn.headerNames.length === 0) {\n return undefined;\n }\n\n const headerNames = method.headersReturn.headerNames;\n const headersMap: Record<string, string> = {};\n\n for (const name of headerNames) {\n const value = responseHeaders.get(name);\n if (value !== undefined && value !== null) {\n headersMap[name] = value;\n }\n }\n\n if (Object.keys(headersMap).length > 0) {\n return new HeadersSubset(headersMap);\n }\n\n return undefined;\n}\n\n/** Builds a RoutesFlowQuery from route paths and subrequests, collecting any mapFrom mappings */\nfunction buildRoutesFlowQuery(routePaths: string[], workflowSubRequests: RSubRequest<any>[]): RoutesFlowQuery {\n const allMappings: RoutesFlowMapping[] = [];\n for (const sr of workflowSubRequests) {\n // Duck-type check for mappings array (avoids circular import of MionSubRequest)\n const mappings = (sr as any).mappings;\n if (Array.isArray(mappings) && mappings.length > 0) {\n for (const ref of mappings) {\n allMappings.push({\n fromId: ref.fromRequestId,\n toId: ref.toRequestId,\n bodyHash: ref.bodyHash,\n paramIndex: ref.paramIndex,\n });\n }\n }\n }\n return {\n routes: routePaths,\n mappings: allMappings.length > 0 ? allMappings : undefined,\n };\n}\n"],"names":["getRoutePath","ROUTES_FLOW_KEY","toBase64Url","fetchRemoteMethodsMetadata","validateSubRequests","serializeRequestBody","MAX_GET_URL_LENGTH","deserializeResponseBody","MION_ROUTES","isRpcError","RpcError","routesCache","HandlerType","HeadersSubset"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const core=require("@mionjs/core");
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const core=require("@mionjs/core");async function routesFlow(routeSubRequests,middleFns){if(!routeSubRequests||routeSubRequests.length===0)throw new core.RpcError({type:"routesFlow-empty-routes",publicMessage:"RoutesFlow requires at least one route subrequest."});const firstSubRequest=routeSubRequests[0];if(!firstSubRequest.client)throw new core.RpcError({type:"routesFlow-missing-client",publicMessage:"Could not extract MionClient from subrequest. Ensure subrequests are created via routes proxy."});const client=firstSubRequest.client;for(let i=1;i<routeSubRequests.length;i++)if(routeSubRequests[i].client!==client)throw new core.RpcError({type:"routesFlow-client-mismatch",publicMessage:`All subrequests in a routesFlow must use the same client instance. Subrequest at index ${i} has a different client.`});const[results,errors,middleFnResults,middleFnErrors]=await client.executeCallWithWorkflow(routeSubRequests,middleFns??{}),emptyResults=routeSubRequests.map(()=>{}),emptyErrors=routeSubRequests.map(()=>{});return[results??emptyResults,errors??emptyErrors,middleFnResults,middleFnErrors]}const mapFromSymbol=Symbol("MapFromServerFnRef");function mapFrom(source,mapper,bodyHash){if(!bodyHash)throw new Error("mapFrom() requires mion vite plugin transform to inject bodyHash");const ref={mapFromSymbol,namespace:core.PURE_SERVER_FN_NAMESPACE,fnName:bodyHash,bodyHash,pureFn:mapper,isFactory:!1,fromRequestId:source.id,toRequestId:"",paramIndex:-1,type(){return ref}};return ref}function isMapFromRef(ref){return ref&&ref.mapFromSymbol===mapFromSymbol}exports.isMapFromRef=isMapFromRef;exports.mapFrom=mapFrom;exports.mapFromSymbol=mapFromSymbol;exports.routesFlow=routesFlow;
|
|
2
2
|
//# sourceMappingURL=routesFlow.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"routesFlow.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
|
1
|
+
{"version":3,"file":"routesFlow.cjs","sources":["../../../src/routesFlow.ts"],"sourcesContent":["/* ########\n * 2025 mion\n * Author: Ma-jerez\n * License: MIT\n * The software is provided \"as is\", without warranty of any kind.\n * ######## */\n\nimport {PURE_SERVER_FN_NAMESPACE, RpcError} from '@mionjs/core';\nimport type {HSubRequest, RSubRequest, SubRequest, WorkflowResult} from './types.ts';\nimport type {MionSubRequest} from './subRequest.ts';\nimport {MapFromServerFnRef} from '@mionjs/core';\n\n/** Creates and executes a routesFlow request with multiple routes */\nexport async function routesFlow<\n Routes extends RSubRequest<any>[],\n MiddleFns extends Record<string, HSubRequest<any>> = Record<string, never>,\n>(routeSubRequests: [...Routes], middleFns?: MiddleFns): Promise<WorkflowResult<Routes, MiddleFns>> {\n if (!routeSubRequests || routeSubRequests.length === 0) {\n throw new RpcError({\n type: 'routesFlow-empty-routes',\n publicMessage: 'RoutesFlow requires at least one route subrequest.',\n });\n }\n\n const firstSubRequest = routeSubRequests[0] as MionSubRequest;\n if (!firstSubRequest.client) {\n throw new RpcError({\n type: 'routesFlow-missing-client',\n publicMessage: 'Could not extract MionClient from subrequest. Ensure subrequests are created via routes proxy.',\n });\n }\n\n const client = firstSubRequest.client;\n\n // Validate all subrequests use the same client instance\n for (let i = 1; i < routeSubRequests.length; i++) {\n const subRequest = routeSubRequests[i] as MionSubRequest;\n if (subRequest.client !== client) {\n throw new RpcError({\n type: 'routesFlow-client-mismatch',\n publicMessage: `All subrequests in a routesFlow must use the same client instance. Subrequest at index ${i} has a different client.`,\n });\n }\n }\n\n const [results, errors, middleFnResults, middleFnErrors] = await client.executeCallWithWorkflow(\n routeSubRequests as any,\n (middleFns ?? {}) as any\n );\n const emptyResults = routeSubRequests.map(() => undefined);\n const emptyErrors = routeSubRequests.map(() => undefined);\n return [results ?? emptyResults, errors ?? emptyErrors, middleFnResults, middleFnErrors] as WorkflowResult<Routes, MiddleFns>;\n}\n\nexport const mapFromSymbol = Symbol('MapFromServerFnRef');\n\n// ╔══════════════════════════════════════════════════════════════════════════════╗\n// ║ WARNING: This function's call signature is parsed by the mion vite plugin ║\n// ║ at build time (see devtools/src/vite-plugin/extractPureFn.ts). ║\n// ║ Do NOT rename, change the parameter order, or modify the function ║\n// ║ signature without updating the corresponding AST extraction and ║\n// ║ transformer logic in @mionjs/devtools. ║\n// ╚══════════════════════════════════════════════════════════════════════════════╝\n/**\n * Maps the output of one route SubRequest to the input of another within a routesFlow.\n * The mapper function must be pure (same rules as pureServerFn).\n * The bodyHash is injected at build time by the mion vite plugin.\n */\n\nexport function mapFrom<FromSR extends SubRequest<any>, MappedInput>(\n source: FromSR,\n mapper: (value: FromSR['resolvedValue']) => MappedInput,\n bodyHash?: string // injected by mion vite plugin\n): MapFromServerFnRef<(value: FromSR['resolvedValue']) => MappedInput> {\n // Important: bodyHash is injected at build time by mion vite plugin\n if (!bodyHash) throw new Error('mapFrom() requires mion vite plugin transform to inject bodyHash');\n const ref: MapFromServerFnRef<(value: FromSR['resolvedValue']) => MappedInput> = {\n mapFromSymbol,\n namespace: PURE_SERVER_FN_NAMESPACE,\n fnName: bodyHash,\n bodyHash,\n pureFn: mapper,\n isFactory: false,\n fromRequestId: source.id,\n toRequestId: '',\n paramIndex: -1, // set by MionSubRequest constructor when passed as a parameter\n type() {\n return ref as unknown as MappedInput;\n },\n };\n return ref;\n}\n\nexport function isMapFromRef(ref: any): ref is MapFromServerFnRef<any> {\n return ref && ref.mapFromSymbol === mapFromSymbol;\n}\n"],"names":["RpcError","PURE_SERVER_FN_NAMESPACE"],"mappings":"mHAaA,eAAsB,WAGpB,iBAA+B,UAAqB,CAClD,GAAI,CAAC,kBAAoB,iBAAiB,SAAW,EACjD,MAAM,IAAIA,KAAAA,SAAS,CACf,KAAM,0BACN,cAAe,oDAAA,CAClB,EAGL,MAAM,gBAAkB,iBAAiB,CAAC,EAC1C,GAAI,CAAC,gBAAgB,OACjB,MAAM,IAAIA,KAAAA,SAAS,CACf,KAAM,4BACN,cAAe,gGAAA,CAClB,EAGL,MAAM,OAAS,gBAAgB,OAG/B,QAAS,EAAI,EAAG,EAAI,iBAAiB,OAAQ,IAEzC,GADmB,iBAAiB,CAAC,EACtB,SAAW,OACtB,MAAM,IAAIA,KAAAA,SAAS,CACf,KAAM,6BACN,cAAe,0FAA0F,CAAC,0BAAA,CAC7G,EAIT,KAAM,CAAC,QAAS,OAAQ,gBAAiB,cAAc,EAAI,MAAM,OAAO,wBACpE,iBACC,WAAa,CAAA,CAAU,EAEtB,aAAe,iBAAiB,IAAI,IAAA,EAAe,EACnD,YAAc,iBAAiB,IAAI,IAAA,EAAe,EACxD,MAAO,CAAC,SAAW,aAAc,QAAU,YAAa,gBAAiB,cAAc,CAC3F,CAEO,MAAM,qBAAuB,oBAAoB,EAelD,SAAU,QACZ,OACA,OACA,UAGA,GAAI,CAAC,SAAU,MAAM,IAAI,MAAM,kEAAkE,EACjG,MAAM,IAA2E,CAC7E,cACA,UAAWC,KAAAA,yBACX,OAAQ,SACR,SACA,OAAQ,OACR,UAAW,GACX,cAAe,OAAO,GACtB,YAAa,GACb,WAAY,GACZ,MAAI,CACA,OAAO,GACX,CAAA,EAEJ,OAAO,GACX,CAEM,SAAU,aAAa,IAAQ,CACjC,OAAO,KAAO,IAAI,gBAAkB,aACxC"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const core=require("@mionjs/core"),
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const core=require("@mionjs/core"),src_lib_typedEvent=require("./lib/typedEvent.cjs"),src_routesFlow=require("./routesFlow.cjs");class MionSubRequest{client;pointer;id;isResolved=!1;params;resolvedValue;error;serializedParams;mappings=[];constructor(parentProps,handlerId,argArray,client){this.client=client,this.pointer=[...parentProps],this.id=handlerId,this.params=argArray.map((arg,index)=>src_routesFlow.isMapFromRef(arg)?(arg.toRequestId=this.id,arg.paramIndex=index,this.mappings.push(arg),null):arg)}prefill(){const typedEvent=new src_lib_typedEvent.TypedEvent(this.id,this.client.handlersRegistry);return this.client.prefill(this).catch(errors=>{console.error("Prefill error:",findSubRequestError(this,errors))}),typedEvent}removePrefill(){return this.client.handlersRegistry.clearHandlers(this.id),this.client.removePrefill(this)}call(){return this.client.executeCall(this)}callWithMiddleFns(middleFns){if(Object.keys(middleFns).length===0)throw new Error("callWithMiddleFns requires at least one middleFn. Use call() instead for requests without middleFns.");return this.client.executeCallWithMiddleFns(this,middleFns)}async callWithWorkflow(otherRoutes,middleFns){const allRoutes=[this,...otherRoutes],[results,errors,middleFnResults,middleFnErrors]=await this.client.executeCallWithWorkflow(allRoutes,middleFns??{}),emptyResults=allRoutes.map(()=>{}),emptyErrors=allRoutes.map(()=>{});return[results??emptyResults,errors??emptyErrors,middleFnResults,middleFnErrors]}typeErrors(){return this.client.typeErrors(this).catch(errors=>Promise.reject(findSubRequestError(this,errors)))}}function findSubRequestError(subRequest,errors){const specificError=errors.get(subRequest.id);if(specificError)return specificError;const firstError=errors.values().next().value;return firstError||new core.RpcError({type:"unknown-error",publicMessage:"An unknown error occurred"})}exports.MionSubRequest=MionSubRequest;exports.findSubRequestError=findSubRequestError;
|
|
2
2
|
//# sourceMappingURL=subRequest.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"subRequest.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
|
1
|
+
{"version":3,"file":"subRequest.cjs","sources":["../../../src/subRequest.ts"],"sourcesContent":["/* ########\n * 2025 mion\n * Author: Ma-jerez\n * License: MIT\n * The software is provided \"as is\", without warranty of any kind.\n * ######## */\n\nimport {RpcError} from '@mionjs/core';\nimport type {RunTypeError} from '@mionjs/core';\nimport type {\n CallWithMiddleFnsResult,\n HSubRequest,\n RequestErrors,\n Result,\n RSubRequest,\n SubRequest,\n WorkflowResult,\n} from './types.ts';\nimport type {MapFromServerFnRef} from '@mionjs/core';\nimport type {MionClient} from './client.ts';\nimport {TypedEvent} from './lib/typedEvent.ts';\nimport {isMapFromRef} from './routesFlow.ts';\n\n/** Implementation of both RouteSubRequest and MiddleFnSubRequest interfaces */\nexport class MionSubRequest<S = any, E extends RpcError<string, any> = any> implements RSubRequest<any>, HSubRequest<any> {\n pointer: string[];\n id: string;\n isResolved: boolean = false;\n params: any[];\n resolvedValue?: S;\n error?: E;\n serializedParams?: any[];\n mappings: MapFromServerFnRef[] = [];\n\n constructor(\n parentProps: string[],\n handlerId: string,\n argArray: any[],\n readonly client: MionClient\n ) {\n this.pointer = [...parentProps];\n this.id = handlerId;\n this.params = argArray.map((arg, index) => {\n if (isMapFromRef(arg)) {\n arg.toRequestId = this.id;\n arg.paramIndex = index;\n this.mappings.push(arg);\n return null;\n }\n return arg;\n });\n }\n\n /** Prefills MiddleFn's parameters and returns TypedEvent for event handler registration */\n prefill(): TypedEvent<S, E> {\n const typedEvent = new TypedEvent<S, E>(this.id, this.client.handlersRegistry);\n\n this.client.prefill(this as HSubRequest<any>).catch((errors: RequestErrors) => {\n console.error('Prefill error:', findSubRequestError(this, errors));\n });\n\n return typedEvent;\n }\n\n /** Removes prefilled value and clears any registered error handlers for this middleFn */\n removePrefill(): Promise<void> {\n this.client.handlersRegistry.clearHandlers(this.id);\n return this.client.removePrefill(this as HSubRequest<any>);\n }\n\n /** Calls a remote route and returns a Result 4-tuple with full typing preserved */\n call(): Promise<Result<S, E>> {\n return this.client.executeCall(this as unknown as RSubRequest<any>);\n }\n\n /** Calls a remote route with middleFns and returns a fully-typed 4-tuple result */\n callWithMiddleFns<H extends Record<string, HSubRequest<any>>>(middleFns: H): Promise<CallWithMiddleFnsResult<S, E, H>> {\n if (Object.keys(middleFns).length === 0) {\n throw new Error(\n 'callWithMiddleFns requires at least one middleFn. Use call() instead for requests without middleFns.'\n );\n }\n return this.client.executeCallWithMiddleFns(this as RSubRequest<any>, middleFns) as Promise<\n CallWithMiddleFnsResult<S, E, H>\n >;\n }\n\n /** Calls this route as part of a routesFlow with other routes in a single HTTP request */\n async callWithWorkflow<OtherRoutes extends RSubRequest<any>[], H extends Record<string, HSubRequest<any>>>(\n otherRoutes: [...OtherRoutes],\n middleFns?: H\n ): Promise<WorkflowResult<[RSubRequest<any>, ...OtherRoutes], H>> {\n const allRoutes = [this as unknown as RSubRequest<any>, ...otherRoutes];\n const [results, errors, middleFnResults, middleFnErrors] = await this.client.executeCallWithWorkflow(\n allRoutes,\n middleFns ?? ({} as H)\n );\n const emptyResults = allRoutes.map(() => undefined);\n const emptyErrors = allRoutes.map(() => undefined);\n return [results ?? emptyResults, errors ?? emptyErrors, middleFnResults, middleFnErrors] as WorkflowResult<\n [RSubRequest<any>, ...OtherRoutes],\n H\n >;\n }\n\n /** Validates parameters and returns type errors */\n typeErrors(): Promise<RunTypeError[]> {\n return this.client\n .typeErrors(this as SubRequest<any>)\n .catch((errors: RequestErrors) => Promise.reject(findSubRequestError(this, errors)));\n }\n}\n\n/** Finds the most relevant error from the errors map for a given sub-request */\nexport function findSubRequestError(subRequest: SubRequest<any>, errors: RequestErrors): RpcError<string> {\n const specificError = errors.get(subRequest.id);\n if (specificError) return specificError;\n\n const firstError = errors.values().next().value;\n if (firstError) return firstError;\n\n return new RpcError({\n type: 'unknown-error',\n publicMessage: 'An unknown error occurred',\n });\n}\n"],"names":["isMapFromRef","TypedEvent","RpcError"],"mappings":"uNAwBa,cAAc,CAcV,OAbb,QACA,GACA,WAAsB,GACtB,OACA,cACA,MACA,iBACA,SAAiC,CAAA,EAEjC,YACI,YACA,UACA,SACS,OAAkB,CAAlB,KAAA,OAAA,OAET,KAAK,QAAU,CAAC,GAAG,WAAW,EAC9B,KAAK,GAAK,UACV,KAAK,OAAS,SAAS,IAAI,CAAC,IAAK,QACzBA,eAAAA,aAAa,GAAG,GAChB,IAAI,YAAc,KAAK,GACvB,IAAI,WAAa,MACjB,KAAK,SAAS,KAAK,GAAG,EACf,MAEJ,GACV,CACL,CAGA,SAAO,CACH,MAAM,WAAa,IAAIC,8BAAiB,KAAK,GAAI,KAAK,OAAO,gBAAgB,EAE7E,YAAK,OAAO,QAAQ,IAAwB,EAAE,MAAO,QAAyB,CAC1E,QAAQ,MAAM,iBAAkB,oBAAoB,KAAM,MAAM,CAAC,CACrE,CAAC,EAEM,UACX,CAGA,eAAa,CACT,YAAK,OAAO,iBAAiB,cAAc,KAAK,EAAE,EAC3C,KAAK,OAAO,cAAc,IAAwB,CAC7D,CAGA,MAAI,CACA,OAAO,KAAK,OAAO,YAAY,IAAmC,CACtE,CAGA,kBAA8D,UAAY,CACtE,GAAI,OAAO,KAAK,SAAS,EAAE,SAAW,EAClC,MAAM,IAAI,MACN,sGAAsG,EAG9G,OAAO,KAAK,OAAO,yBAAyB,KAA0B,SAAS,CAGnF,CAGA,MAAM,iBACF,YACA,UAAa,CAEb,MAAM,UAAY,CAAC,KAAqC,GAAG,WAAW,EAChE,CAAC,QAAS,OAAQ,gBAAiB,cAAc,EAAI,MAAM,KAAK,OAAO,wBACzE,UACA,WAAc,CAAA,CAAQ,EAEpB,aAAe,UAAU,IAAI,IAAA,EAAe,EAC5C,YAAc,UAAU,IAAI,IAAA,EAAe,EACjD,MAAO,CAAC,SAAW,aAAc,QAAU,YAAa,gBAAiB,cAAc,CAI3F,CAGA,YAAU,CACN,OAAO,KAAK,OACP,WAAW,IAAuB,EAClC,MAAO,QAA0B,QAAQ,OAAO,oBAAoB,KAAM,MAAM,CAAC,CAAC,CAC3F,CACH,CAGK,SAAU,oBAAoB,WAA6B,OAAqB,CAClF,MAAM,cAAgB,OAAO,IAAI,WAAW,EAAE,EAC9C,GAAI,cAAe,OAAO,cAE1B,MAAM,WAAa,OAAO,OAAA,EAAS,OAAO,MAC1C,OAAI,YAEG,IAAIC,KAAAA,SAAS,CAChB,KAAM,gBACN,cAAe,2BAAA,CAClB,CACL"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { RpcError, RunTypeError, MapFromServerFnRef } from '@mionjs/core';
|
|
2
2
|
import { CallWithMiddleFnsResult, HSubRequest, RequestErrors, Result, RSubRequest, SubRequest, WorkflowResult } from './types.ts';
|
|
3
3
|
import { MionClient } from './client.ts';
|
|
4
|
-
import { TypedEvent } from './typedEvent.ts';
|
|
4
|
+
import { TypedEvent } from './lib/typedEvent.ts';
|
|
5
5
|
export declare class MionSubRequest<S = any, E extends RpcError<string, any> = any> implements RSubRequest<any>, HSubRequest<any> {
|
|
6
6
|
readonly client: MionClient;
|
|
7
7
|
pointer: string[];
|