@mionjs/router 0.8.4-alpha.0 → 0.8.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -27,6 +27,7 @@ const defaultStartMiddleFns = {
27
27
  mionDeserializeRequest: src_routes_serializer_routes.serializerMiddleFns.mionDeserializeRequest
28
28
  };
29
29
  const defaultEndMiddleFns = {
30
+ ...src_routes_client_routes.mionClientMiddleFns,
30
31
  mionSerializeResponse: src_routes_serializer_routes.serializerMiddleFns.mionSerializeResponse
31
32
  };
32
33
  let startMiddleFnsDef = { ...defaultStartMiddleFns };
@@ -99,7 +100,9 @@ async function registerRoutes(routes) {
99
100
  if (!isRouterInitialized) throw new Error("initRouter should be called first");
100
101
  exports.startMiddleFns = await getExecutablesFromMiddleFnsCollection(startMiddleFnsDef);
101
102
  exports.endMiddleFns = await getExecutablesFromMiddleFnsCollection(endMiddleFnsDef);
102
- await recursiveFlatRoutes(routes);
103
+ const binaryMiddlewares = /* @__PURE__ */ new Set();
104
+ await recursiveFlatRoutes(routes, [], [], [], binaryMiddlewares, 0);
105
+ if (binaryMiddlewares.size > 0) await compileBinaryForMiddleware(binaryMiddlewares);
103
106
  if (shouldFullGenerateSpec()) {
104
107
  return src_lib_remoteMethods.getPublicApi(routes);
105
108
  }
@@ -167,7 +170,7 @@ async function emitAOTCaches() {
167
170
  const aotEmitter = await Promise.resolve().then(() => require("./lib/aotEmitter.cjs"));
168
171
  return aotEmitter.emitAOTCaches();
169
172
  }
170
- async function recursiveFlatRoutes(routes, currentPointer = [], preMiddleFns = [], postMiddleFns = [], nestLevel = 0) {
173
+ async function recursiveFlatRoutes(routes, currentPointer = [], preMiddleFns = [], postMiddleFns = [], binaryMiddlewares = /* @__PURE__ */ new Set(), nestLevel = 0) {
171
174
  if (nestLevel > src_constants.MAX_ROUTE_NESTING)
172
175
  throw new Error("Too many nested routes, you can only nest routes ${MAX_ROUTE_NESTING} levels");
173
176
  const entries = Object.entries(routes);
@@ -206,11 +209,12 @@ async function recursiveFlatRoutes(routes, currentPointer = [], preMiddleFns = [
206
209
  const itemType = typeof item;
207
210
  throw new Error(`Invalid route: ${joinPath(...newPointer)}. Type <${itemType}> is not a valid route.`);
208
211
  }
209
- minus1Props = await recursiveCreateExecutionChainAsync(
212
+ minus1Props = await recursiveCreateExecutionChain(
210
213
  routeEntry,
211
214
  newPointer,
212
215
  preMiddleFns,
213
216
  postMiddleFns,
217
+ binaryMiddlewares,
214
218
  nestLevel,
215
219
  index,
216
220
  entries,
@@ -219,7 +223,7 @@ async function recursiveFlatRoutes(routes, currentPointer = [], preMiddleFns = [
219
223
  complexity++;
220
224
  }
221
225
  }
222
- async function recursiveCreateExecutionChainAsync(routeEntry, currentPointer, preMiddleFns, postMiddleFns, nestLevel, index, routeKeyedEntries, minus1Props) {
226
+ async function recursiveCreateExecutionChain(routeEntry, currentPointer, preMiddleFns, postMiddleFns, binaryMiddlewares, nestLevel, index, routeKeyedEntries, minus1Props) {
223
227
  const minus1 = getEntry(index - 1, routeKeyedEntries);
224
228
  const plus1 = getEntry(index + 1, routeKeyedEntries);
225
229
  const props = getRouteEntryProperties(minus1, routeEntry, plus1);
@@ -257,12 +261,20 @@ async function recursiveCreateExecutionChainAsync(routeEntry, currentPointer, pr
257
261
  const middleFnIds = getPublicMiddleFnIds(methods);
258
262
  if (middleFnIds.length) routeMethod.middleFnIds = middleFnIds;
259
263
  flatRouter.set(path, executionChain);
264
+ if (routeMethod.options.serializer === "binary") {
265
+ for (const method of methods) {
266
+ if (method.type === core.HandlerType.middleFn || method.type === core.HandlerType.headersMiddleFn) {
267
+ binaryMiddlewares.add(method.id);
268
+ }
269
+ }
270
+ }
260
271
  } else if (!isExec) {
261
272
  await recursiveFlatRoutes(
262
273
  routeEntry.routes,
263
274
  routeEntry.pathPointer,
264
275
  [...preMiddleFns, ...props.preLevelMiddleFns],
265
276
  [...props.postLevelMiddleFns, ...postMiddleFns],
277
+ binaryMiddlewares,
266
278
  nestLevel + 1
267
279
  );
268
280
  }
@@ -286,6 +298,7 @@ async function getExecutableFromMiddleFn(middleFn, middleFnPointer, nestLevel) {
286
298
  middleFn.handler,
287
299
  middleFnId,
288
300
  routerOptions,
301
+ middleFn.options ?? {},
289
302
  isHeader,
290
303
  middleFn.options?.strictTypes
291
304
  );
@@ -333,6 +346,12 @@ async function getExecutableFromRawMiddleFn(middleFn, middleFnPointer, nestLevel
333
346
  core.routesCache.setMethodJitFns(middleFnId, executable);
334
347
  return executable;
335
348
  }
349
+ async function compileBinaryForMiddleware(binaryMiddlewareIds) {
350
+ for (const id of binaryMiddlewareIds) {
351
+ const method = middleFnsById.get(id);
352
+ if (method) await src_lib_reflection.ensureBinaryJitFns(method);
353
+ }
354
+ }
336
355
  async function getExecutableFromRoute(route, routePointer, nestLevel) {
337
356
  const routeId = core.getRouterItemId(routePointer);
338
357
  const existing = routesById.get(routeId);
@@ -342,10 +361,12 @@ async function getExecutableFromRoute(route, routePointer, nestLevel) {
342
361
  if (compiledMethod) {
343
362
  executable = compiledMethod;
344
363
  } else {
364
+ const resolvedRouteOptions = { ...route.options, serializer: route.options?.serializer ?? routerOptions.serializer };
345
365
  const reflectionData = await src_lib_reflection.getHandlerReflection(
346
366
  route.handler,
347
367
  routeId,
348
368
  routerOptions,
369
+ resolvedRouteOptions,
349
370
  false,
350
371
  route.options?.strictTypes
351
372
  );
@@ -422,6 +443,8 @@ function getSerializerCodeFromMode(mode) {
422
443
  return core.SerializerModes.binary;
423
444
  case "stringifyJson":
424
445
  return core.SerializerModes.stringifyJson;
446
+ case "optimistic":
447
+ return core.SerializerModes.stringifyJson;
425
448
  case "json":
426
449
  default:
427
450
  return core.SerializerModes.json;
@@ -1 +1 @@
1
- {"version":3,"file":"router.cjs","sources":["../../../src/router.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\n/** Lightweight path join for error messages (avoids Node's 'path' module for edge compatibility) */\nimport type {Route, RouterOptions, Routes, RouterEntry} from './types/general.ts';\nimport type {\n RemoteMethod,\n MethodsExecutionChain,\n RawMethod,\n HeadersMethod,\n MiddleFnMethod,\n RouteMethod,\n} from './types/remoteMethods.ts';\nimport type {PublicApi, PrivateDef, MiddleFnsCollection} from './types/publicMethods.ts';\nimport type {HeadersMiddleFnDef, MiddleFnDef, RawMiddleFnDef} from './types/definitions.ts';\nimport {DEFAULT_ROUTE_OPTIONS, MAX_ROUTE_NESTING, WORKFLOW_KEY} from './constants.ts';\nimport {\n isRawMiddleFnDef,\n isHeadersMiddleFnDef,\n isExecutable,\n isMiddleFnDef,\n isRoute,\n isRoutes,\n isAnyMiddleFnDef,\n isPublicExecutable,\n} from './types/guards.ts';\nimport {\n HandlerType,\n SerializerModes,\n SerializerCode,\n SerializerMode,\n isTestEnv,\n isMionCompileMode,\n isMionAOTEmitMode,\n resetRoutesCache,\n} from '@mionjs/core';\nimport {getRawMethodReflection, getHandlerReflection} from './lib/reflection.ts';\nimport {serializerMiddleFns} from './routes/serializer.routes.ts';\nimport {getRouterItemId, getRoutePath, getENV, MION_ROUTES, routesCache} from '@mionjs/core';\nimport {setErrorOptions} from '@mionjs/core';\nimport {getPublicApi, resetRemoteMethodsMetadata} from './lib/remoteMethods.ts';\nimport {addToPersistedMethods, getPersistedMethod, resetPersistedMethods} from './lib/methodsCache.ts';\nimport {mionClientRoutes} from './routes/client.routes.ts';\nimport {mionErrorsRoutes} from './routes/errors.routes.ts';\nimport {clearRoutesFlowCache} from './routesFlow.ts';\nimport {clearContextPool} from './callContext.ts';\n\ntype RouterKeyEntryList = [string, RouterEntry][];\ntype RoutesWithId = {\n pathPointer: string[];\n routes: Routes;\n};\n\n// ############# PRIVATE STATE #############\n\nconst mionInternalRoutes = Object.values(MION_ROUTES) as string[];\nconst flatRouter: Map<string, MethodsExecutionChain> = new Map(); // Main Router\nconst middleFnsById: Map<string, MiddleFnMethod | HeadersMethod | RawMethod> = new Map();\nconst routesById: Map<string, RouteMethod> = new Map();\nconst rawMiddleFnsById: Map<string, RawMethod> = new Map();\nconst middleFnNames: Set<string> = new Set();\nconst routeNames: Set<string> = new Set();\nlet complexity = 0;\nlet routerOptions: RouterOptions = {...DEFAULT_ROUTE_OPTIONS};\nlet isRouterInitialized = false;\nlet allExecutablesIds: string[] | undefined;\nlet platformConfig: Record<string, unknown> | undefined;\n\n/** Global middleFns to be run before and after any other middleFns or routes set using `registerRoutes` */\nconst defaultStartMiddleFns = {\n mionDeserializeRequest: serializerMiddleFns.mionDeserializeRequest,\n};\nconst defaultEndMiddleFns = {\n mionSerializeResponse: serializerMiddleFns.mionSerializeResponse,\n};\nlet startMiddleFnsDef: MiddleFnsCollection = {...defaultStartMiddleFns};\nlet endMiddleFnsDef: MiddleFnsCollection = {...defaultEndMiddleFns};\nexport let startMiddleFns: RemoteMethod[] = [];\nexport let endMiddleFns: RemoteMethod[] = [];\n\n// ############# PUBLIC METHODS #############\n\nexport const getRouteExecutionChain = (path: string) => flatRouter.get(path);\nexport const getRouteEntries = () => flatRouter.entries();\nexport const geRoutesSize = () => flatRouter.size;\nexport const getRouteExecutable = (id: string) => routesById.get(id);\nexport const getMiddleFnExecutable = (id: string) => middleFnsById.get(id);\nexport const geMiddleFnsSize = () => middleFnsById.size;\nexport const getComplexity = () => complexity;\nexport const getRouterOptions = <Opts extends RouterOptions>(): Readonly<Opts> => routerOptions as Opts;\nexport const getAnyExecutable = (id: string) => routesById.get(id) || middleFnsById.get(id) || rawMiddleFnsById.get(id);\n\n/** Sets platform adapter config and notifies the parent process (Vite plugin) that the server is ready.\n * Called automatically by platform adapters. Sends an IPC message containing both the\n * serializable router config and the platform adapter config. */\nexport function setPlatformConfig(config: Record<string, unknown>): void {\n platformConfig = config;\n if (isMionAOTEmitMode() && typeof process.send === 'function') {\n const routerConfig = Object.fromEntries(Object.entries(routerOptions).filter(([, v]) => typeof v !== 'function'));\n try {\n process.send({type: 'mion-platform-ready', routerConfig, platformConfig: config});\n } catch (err) {\n console.error('[mion] Failed to send platform-ready IPC:', err);\n }\n }\n}\n\n/** Returns the platform adapter config set by setPlatformConfig(). */\nexport const getPlatformConfig = (): Readonly<Record<string, unknown>> | undefined => platformConfig;\n\nexport const resetRouter = () => {\n flatRouter.clear();\n middleFnsById.clear();\n routesById.clear();\n rawMiddleFnsById.clear();\n middleFnNames.clear();\n routeNames.clear();\n complexity = 0;\n routerOptions = {...DEFAULT_ROUTE_OPTIONS};\n startMiddleFnsDef = {...defaultStartMiddleFns};\n endMiddleFnsDef = {...defaultEndMiddleFns};\n startMiddleFns = [];\n endMiddleFns = [];\n isRouterInitialized = false;\n allExecutablesIds = undefined;\n platformConfig = undefined;\n resetRemoteMethodsMetadata();\n resetPersistedMethods();\n resetRoutesCache();\n clearContextPool();\n clearRoutesFlowCache();\n // Note: We intentionally do NOT call resetJitFnCaches() here because:\n // 1. JIT function caches are global and should persist across router resets\n // 2. The serializableClassRegistry (cleared by resetJitFnCaches) is needed for\n // serialization/deserialization of classes like RpcError\n // resetJitFnCaches() should only be called in specific test scenarios that need\n // to test AOT cache loading behavior\n};\n\n// simpler router initialization\nexport async function initMionRouter<R extends Routes>(routes: R, opts?: Partial<RouterOptions>): Promise<PublicApi<R>> {\n await initRouter(opts);\n const publicApi = await registerRoutes(routes);\n // Emit AOT caches once after ALL routes (error, client, user) are registered\n await emitAOTCaches();\n return publicApi;\n}\n\n/**\n * Initializes the Router.\n * @param application\n * @param contextDataFactory a factory function that returns an object to be shared in the `callContext.shared`\n * @param routerOptions\n * @returns\n */\nexport async function initRouter(opts?: Partial<RouterOptions>): Promise<Readonly<RouterOptions>> {\n if (isRouterInitialized) throw new Error('Router has already been initialized');\n routerOptions = {...routerOptions, ...opts};\n validateSharedDataFactory(routerOptions);\n Object.freeze(routerOptions);\n setErrorOptions(routerOptions);\n if (routerOptions.aot) await loadAOTCaches();\n isRouterInitialized = true;\n await registerRoutes({...mionErrorsRoutes});\n if (!routerOptions.skipClientRoutes) await registerRoutes({...mionClientRoutes});\n if (!isTestEnv()) console.log('mion router initialized', {routerOptions});\n return routerOptions;\n}\n\nexport async function registerRoutes<R extends Routes>(routes: R): Promise<PublicApi<R>> {\n if (!isRouterInitialized) throw new Error('initRouter should be called first');\n startMiddleFns = await getExecutablesFromMiddleFnsCollection(startMiddleFnsDef);\n endMiddleFns = await getExecutablesFromMiddleFnsCollection(endMiddleFnsDef);\n await recursiveFlatRoutes(routes);\n if (shouldFullGenerateSpec()) {\n return getPublicApi(routes);\n }\n return {} as PublicApi<R>;\n}\n\n/** Add middleFns at the start af the ExecutionChain, adds them before any other existing start middleFns by default */\nexport function addStartMiddleFns(middleFnsDef: MiddleFnsCollection, appendBeforeExisting = true) {\n if (isRouterInitialized) throw new Error('Can not add start middleFns after the router has been initialized');\n if (appendBeforeExisting) {\n startMiddleFnsDef = {...middleFnsDef, ...startMiddleFnsDef};\n return;\n }\n startMiddleFnsDef = {...startMiddleFnsDef, ...middleFnsDef};\n}\n\n/** Add middleFns at the end af the ExecutionChain, adds them after any other existing end middleFns by default */\nexport function addEndMiddleFns(middleFnsDef: MiddleFnsCollection, prependAfterExisting = true) {\n if (isRouterInitialized) throw new Error('Can not add end middleFns after the router has been initialized');\n if (prependAfterExisting) {\n endMiddleFnsDef = {...endMiddleFnsDef, ...middleFnsDef};\n return;\n }\n endMiddleFnsDef = {...middleFnsDef, ...endMiddleFnsDef};\n}\n\nexport function isPrivateDefinition(entry: RouterEntry, id: string): entry is PrivateDef {\n if (isRoute(entry)) return false;\n if (isRawMiddleFnDef(entry)) return true;\n try {\n const executable = getMiddleFnExecutable(id) || getRouteExecutable(id);\n if (!executable)\n throw new Error(`Route or MiddleFn ${id} not found. Please check you have called router.registerRoutes first.`);\n return isPrivateExecutable(executable);\n } catch {\n // error thrown because entry is a Routes object and does not have any handler\n return false;\n }\n}\n\nexport function isPrivateExecutable(executable: RemoteMethod): boolean {\n if (executable.type === HandlerType.rawMiddleFn) return true;\n if (executable.type === HandlerType.route) return false;\n const hasPublicParams = !!executable.paramNames?.length;\n const hasHeaderParams = !!(executable as HeadersMethod).headersParam?.headerNames?.length;\n return !hasPublicParams && !hasHeaderParams && !executable.hasReturnData;\n}\n\nexport function getTotalExecutables(): number {\n return routesById.size + middleFnsById.size + rawMiddleFnsById.size;\n}\n\nexport function getAllExecutablesIds(): string[] {\n if (allExecutablesIds) return allExecutablesIds;\n allExecutablesIds = [...routesById.keys(), ...middleFnsById.keys(), ...rawMiddleFnsById.keys()];\n return allExecutablesIds;\n}\n\n// used by codegen\nexport function shouldFullGenerateSpec(): boolean {\n return routerOptions.getPublicRoutesData || getENV('GENERATE_ROUTER_SPEC') === 'true' || isMionCompileMode();\n}\n\nexport function getRouteExecutableFromPath(path: string): RouteMethod {\n const executionChain = flatRouter.get(path);\n if (!executionChain) {\n // Return the not-found route executable\n return getAnyExecutable(MION_ROUTES.notFound) as RouteMethod;\n }\n return executionChain.methods[executionChain.routeIndex] as RouteMethod;\n}\n\n// ############# PRIVATE METHODS #############\n\nasync function loadAOTCaches() {\n const loader = await import('./aot/aotCacheLoader.ts');\n return loader.loadRouterAOTCaches();\n}\n\nasync function emitAOTCaches() {\n if (!isMionAOTEmitMode()) return;\n // Dynamic import resolves relative to this source file.\n // This only runs via vite-node (MION_COMPILE=buildOnly|childProcess), which always resolves from source.\n const aotEmitter = await import('./lib/aotEmitter.ts');\n return aotEmitter.emitAOTCaches();\n}\n\n/**\n * Optimized algorithm to flatten the routes object into a list of Executable objects.\n * @param routes\n * @param currentPointer current pointer in the routes object i.e. ['users', 'get']\n * @param preMiddleFns middleFns one level up preceding current pointer\n * @param postMiddleFns middleFns one level up following the current pointer\n * @param nestLevel\n */\nasync function recursiveFlatRoutes(\n routes: Routes,\n currentPointer: string[] = [],\n preMiddleFns: RemoteMethod[] = [],\n postMiddleFns: RemoteMethod[] = [],\n nestLevel = 0\n) {\n if (nestLevel > MAX_ROUTE_NESTING)\n throw new Error('Too many nested routes, you can only nest routes ${MAX_ROUTE_NESTING} levels');\n\n const entries = Object.entries(routes);\n if (entries.length === 0)\n throw new Error(\n `Invalid route: ${currentPointer.length ? joinPath(...currentPointer) : '*'}. Can Not define empty routes`\n );\n\n let minus1Props: ReturnType<typeof getRouteEntryProperties> | null = null;\n for (let index = 0; index < entries.length; index++) {\n const [key, item] = entries[index];\n // create the executable items\n const newPointer = [...currentPointer, key];\n let routeEntry: RemoteMethod | RoutesWithId;\n if (typeof key !== 'string' || !isNaN(key as any))\n throw new Error(`Invalid route: ${joinPath(...newPointer)}. Numeric route names are not allowed`);\n if (key.includes(',')) throw new Error(`Invalid route: ${joinPath(...newPointer)}. Route names cannot contain commas.`);\n if (key === WORKFLOW_KEY)\n throw new Error(`Invalid route: ${joinPath(...newPointer)}. '${WORKFLOW_KEY}' is a reserved mion route name.`);\n\n // generates a middleFn\n if (isAnyMiddleFnDef(item)) {\n routeEntry = await getExecutableFromAnyMiddleFn(item, newPointer, nestLevel);\n if (middleFnNames.has(routeEntry.id))\n throw new Error(\n `Invalid middleFn: ${joinPath(...newPointer)}. Naming collision, Naming collision, duplicated middleFn.`\n );\n middleFnNames.add(routeEntry.id);\n }\n\n // generates a route\n else if (isRoute(item)) {\n routeEntry = await getExecutableFromRoute(item, newPointer, nestLevel);\n if (routeNames.has(routeEntry.id))\n throw new Error(`Invalid route: ${joinPath(...newPointer)}. Naming collision, duplicated route`);\n routeNames.add(routeEntry.id);\n }\n\n // generates structure required to go one level down\n else if (isRoutes(item)) {\n routeEntry = {\n pathPointer: newPointer,\n routes: item,\n };\n }\n\n // throws an error if the route is invalid\n else {\n const itemType = typeof item;\n throw new Error(`Invalid route: ${joinPath(...newPointer)}. Type <${itemType}> is not a valid route.`);\n }\n\n // recurse into sublevels\n minus1Props = await recursiveCreateExecutionChainAsync(\n routeEntry,\n newPointer,\n preMiddleFns,\n postMiddleFns,\n nestLevel,\n index,\n entries,\n minus1Props\n );\n\n complexity++;\n }\n}\n\nasync function recursiveCreateExecutionChainAsync(\n routeEntry: RemoteMethod | RoutesWithId,\n currentPointer: string[],\n preMiddleFns: RemoteMethod[],\n postMiddleFns: RemoteMethod[],\n nestLevel: number,\n index: number,\n routeKeyedEntries: RouterKeyEntryList,\n minus1Props: ReturnType<typeof getRouteEntryProperties> | null\n) {\n const minus1 = getEntry(index - 1, routeKeyedEntries);\n const plus1 = getEntry(index + 1, routeKeyedEntries);\n const props = getRouteEntryProperties(minus1, routeEntry, plus1);\n\n if (props.isBetweenRoutes && minus1Props) {\n props.preLevelMiddleFns = minus1Props.preLevelMiddleFns;\n props.postLevelMiddleFns = minus1Props.postLevelMiddleFns;\n } else {\n for (let i = 0; i < routeKeyedEntries.length; i++) {\n const [k, entry] = routeKeyedEntries[i];\n complexity++;\n if (!isAnyMiddleFnDef(entry)) continue;\n const newPointer = [...currentPointer.slice(0, -1), k];\n const executable = await getExecutableFromAnyMiddleFn(entry, newPointer, nestLevel);\n if (i < index) props.preLevelMiddleFns.push(executable);\n if (i > index) props.postLevelMiddleFns.push(executable);\n }\n }\n const isExec = isExecutable(routeEntry);\n\n if (isExec && props.isRoute) {\n const path = getRoutePath(routeEntry.pointer, routerOptions);\n const routeMethod = routeEntry as RouteMethod;\n const levelMethods = [\n ...preMiddleFns,\n ...props.preLevelMiddleFns,\n routeEntry,\n ...props.postLevelMiddleFns,\n ...postMiddleFns,\n ];\n const methods = [...startMiddleFns, ...levelMethods, ...endMiddleFns];\n const executionChain: MethodsExecutionChain = {\n routeIndex: startMiddleFns.length + preMiddleFns.length + props.preLevelMiddleFns.length,\n methods,\n serializer: getSerializerCodeFromMode(routeMethod.options.serializer),\n };\n const middleFnIds = getPublicMiddleFnIds(methods);\n // add middleware functions deps, so can be serialized with the router\n if (middleFnIds.length) routeMethod.middleFnIds = middleFnIds;\n flatRouter.set(path, executionChain);\n } else if (!isExec) {\n await recursiveFlatRoutes(\n routeEntry.routes,\n routeEntry.pathPointer,\n [...preMiddleFns, ...props.preLevelMiddleFns],\n [...props.postLevelMiddleFns, ...postMiddleFns],\n nestLevel + 1\n );\n }\n\n return props;\n}\n\nasync function getExecutableFromAnyMiddleFn(\n middleFn: MiddleFnDef | HeadersMiddleFnDef | RawMiddleFnDef,\n middleFnPointer: string[],\n nestLevel: number\n) {\n if (isRawMiddleFnDef(middleFn)) return getExecutableFromRawMiddleFn(middleFn, middleFnPointer, nestLevel);\n return getExecutableFromMiddleFn(middleFn, middleFnPointer, nestLevel);\n}\n\nexport async function getExecutableFromMiddleFn(\n middleFn: MiddleFnDef | HeadersMiddleFnDef,\n middleFnPointer: string[],\n nestLevel: number\n): Promise<MiddleFnMethod | HeadersMethod> {\n const isHeader = isHeadersMiddleFnDef(middleFn);\n // todo fix header id should be same as any other one and then maybe map from id to header name\n const middleFnId = getRouterItemId(middleFnPointer);\n const existing = middleFnsById.get(middleFnId);\n if (existing) return existing as MiddleFnMethod;\n\n type MixedMiddleFn = (Omit<MiddleFnMethod, 'type'> | Omit<HeadersMethod, 'type'>) & {\n type: typeof HandlerType.middleFn | typeof HandlerType.headersMiddleFn;\n };\n\n const compiledMethod = getPersistedMethod(middleFnId, middleFn.handler);\n let executable: MixedMiddleFn;\n if (compiledMethod) {\n executable = compiledMethod as MixedMiddleFn;\n } else {\n const reflectionData = await getHandlerReflection(\n middleFn.handler,\n middleFnId,\n routerOptions,\n isHeader,\n middleFn.options?.strictTypes\n );\n executable = {\n id: middleFnId,\n type: isHeader ? HandlerType.headersMiddleFn : HandlerType.middleFn,\n nestLevel,\n handler: middleFn.handler,\n pointer: middleFnPointer,\n ...reflectionData,\n options: {\n runOnError: !!middleFn.options?.runOnError,\n validateParams: middleFn.options?.validateParams ?? true,\n validateReturn: middleFn.options?.validateReturn ?? false,\n description: middleFn.options?.description,\n strictTypes: middleFn.options?.strictTypes ?? routerOptions.strictTypes,\n },\n };\n addToPersistedMethods(middleFnId, executable);\n }\n\n middleFnsById.set(middleFnId, executable as any);\n routesCache.setMethodJitFns(middleFnId, executable as any);\n return executable as any;\n}\n\nexport async function getExecutableFromRawMiddleFn(\n middleFn: RawMiddleFnDef,\n middleFnPointer: string[],\n nestLevel: number\n): Promise<RawMethod> {\n const middleFnId = getRouterItemId(middleFnPointer);\n const existing = rawMiddleFnsById.get(middleFnId);\n if (existing) return existing as RawMethod;\n const reflectionData = await getRawMethodReflection(middleFn.handler, middleFnId, routerOptions);\n const executable: RawMethod = {\n id: middleFnId,\n type: HandlerType.rawMiddleFn,\n nestLevel,\n handler: middleFn.handler,\n pointer: middleFnPointer,\n ...reflectionData,\n options: {\n runOnError: !!middleFn.options?.runOnError,\n validateParams: false,\n validateReturn: false,\n description: middleFn.options?.description,\n },\n };\n rawMiddleFnsById.set(middleFnId, executable);\n routesCache.setMethodJitFns(middleFnId, executable as any);\n return executable;\n}\n\nexport async function getExecutableFromRoute(route: Route, routePointer: string[], nestLevel: number): Promise<RouteMethod> {\n const routeId = getRouterItemId(routePointer);\n const existing = routesById.get(routeId);\n if (existing) return existing as RouteMethod;\n\n const compiledMethod = getPersistedMethod(routeId, route.handler);\n let executable: RouteMethod;\n if (compiledMethod) {\n executable = compiledMethod as RouteMethod;\n } else {\n const reflectionData = await getHandlerReflection(\n route.handler,\n routeId,\n routerOptions,\n false,\n route.options?.strictTypes\n );\n executable = {\n id: routeId,\n type: HandlerType.route,\n nestLevel,\n handler: route.handler,\n pointer: routePointer,\n ...reflectionData,\n options: {\n runOnError: false,\n validateParams: route.options?.validateParams ?? true,\n validateReturn: route.options?.validateReturn ?? false,\n description: route.options?.description,\n serializer: route.options?.serializer ?? routerOptions.serializer,\n isMutation: route.options?.isMutation,\n strictTypes: route.options?.strictTypes ?? routerOptions.strictTypes,\n },\n };\n addToPersistedMethods(routeId, executable);\n }\n routesById.set(routeId, executable);\n routesCache.setMethodJitFns(routeId, executable as any);\n return executable;\n}\n\n/** Returns IDs of public middleware methods from the execution chain, excluding internal mion routes. */\nfunction getPublicMiddleFnIds(methods: RemoteMethod[]): string[] {\n const ids = methods\n .filter((exec) => isPublicExecutable(exec))\n .map((exec) => getRouterItemId(exec.pointer))\n .filter((mfId) => {\n if (mionInternalRoutes.includes(mfId)) return false;\n const exec = getMiddleFnExecutable(mfId);\n return exec && isPublicExecutable(exec);\n });\n return ids;\n}\n\nfunction getEntry(index: number, keyEntryList: RouterKeyEntryList) {\n return keyEntryList[index]?.[1];\n}\n\nfunction getRouteEntryProperties(\n minus1: RouterEntry | undefined,\n zero: RemoteMethod | RoutesWithId,\n plus1: RouterEntry | undefined\n) {\n const minus1IsRoute = minus1 && isRoute(minus1);\n const zeroIsRoute = (zero as RemoteMethod).type === HandlerType.route;\n const plus1IsRoute = plus1 && isRoute(plus1);\n\n const isExec = !!(zero as RemoteMethod).handler;\n\n return {\n isBetweenRoutes: minus1IsRoute && zeroIsRoute && plus1IsRoute,\n isExecutable: isExec,\n isRoute: zeroIsRoute,\n preLevelMiddleFns: [] as RemoteMethod[],\n postLevelMiddleFns: [] as RemoteMethod[],\n };\n}\n\nasync function getExecutablesFromMiddleFnsCollection(\n middleFnsDef: MiddleFnsCollection\n): Promise<(RawMethod | MiddleFnMethod | HeadersMethod)[]> {\n const results: (RawMethod | MiddleFnMethod | HeadersMethod)[] = [];\n for (const [key, middleFn] of Object.entries(middleFnsDef)) {\n if (isRawMiddleFnDef(middleFn)) {\n results.push(await getExecutableFromRawMiddleFn(middleFn, [key], 0));\n } else if (isHeadersMiddleFnDef(middleFn) || isMiddleFnDef(middleFn)) {\n results.push(await getExecutableFromMiddleFn(middleFn, [key], 0));\n } else {\n throw new Error(`Invalid middleFn: ${key}. Invalid middleFn definition`);\n }\n }\n return results;\n}\n\n/**\n * Validates that a contextDataFactory returns a valid context data object.\n * @param contextDataFactory The factory function to validate\n * @throws Error if the factory doesn't return a plain object with at least one property\n */\nfunction validateSharedDataFactory(opts?: Partial<RouterOptions>): void {\n if (!opts?.contextDataFactory) return;\n const testSharedData = opts.contextDataFactory();\n if (\n typeof testSharedData !== 'object' ||\n Array.isArray(testSharedData) ||\n testSharedData === null ||\n Object.keys(testSharedData).length === 0\n ) {\n throw new Error('contextDataFactory must return a plain object with at least one property');\n }\n}\n\n/** Maps serializer mode string to response body type code */\nfunction getSerializerCodeFromMode(mode: SerializerMode | undefined): SerializerCode {\n switch (mode) {\n case 'binary':\n return SerializerModes.binary;\n case 'stringifyJson':\n return SerializerModes.stringifyJson;\n case 'json':\n default:\n return SerializerModes.json;\n }\n}\n\n/** Path replacement as is not available in edge runtime */\nfunction joinPath(...parts: string[]): string {\n return parts.filter(Boolean).join('/');\n}\n"],"names":["MION_ROUTES","DEFAULT_ROUTE_OPTIONS","serializerMiddleFns","startMiddleFns","endMiddleFns","isMionAOTEmitMode","resetRemoteMethodsMetadata","resetPersistedMethods","resetRoutesCache","clearContextPool","clearRoutesFlowCache","setErrorOptions","mionErrorsRoutes","mionClientRoutes","isTestEnv","getPublicApi","isRoute","isRawMiddleFnDef","HandlerType","getENV","isMionCompileMode","MAX_ROUTE_NESTING","WORKFLOW_KEY","isAnyMiddleFnDef","isRoutes","isExecutable","getRoutePath","isHeadersMiddleFnDef","getRouterItemId","getPersistedMethod","getHandlerReflection","addToPersistedMethods","routesCache","getRawMethodReflection","isPublicExecutable","isMiddleFnDef","SerializerModes"],"mappings":"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"}
1
+ {"version":3,"file":"router.cjs","sources":["../../../src/router.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\n/** Lightweight path join for error messages (avoids Node's 'path' module for edge compatibility) */\nimport type {Route, RouterOptions, Routes, RouterEntry} from './types/general.ts';\nimport type {\n RemoteMethod,\n MethodsExecutionChain,\n RawMethod,\n HeadersMethod,\n MiddleFnMethod,\n RouteMethod,\n} from './types/remoteMethods.ts';\nimport type {PublicApi, PrivateDef, MiddleFnsCollection} from './types/publicMethods.ts';\nimport type {HeadersMiddleFnDef, MiddleFnDef, RawMiddleFnDef} from './types/definitions.ts';\nimport {DEFAULT_ROUTE_OPTIONS, MAX_ROUTE_NESTING, WORKFLOW_KEY} from './constants.ts';\nimport {\n isRawMiddleFnDef,\n isHeadersMiddleFnDef,\n isExecutable,\n isMiddleFnDef,\n isRoute,\n isRoutes,\n isAnyMiddleFnDef,\n isPublicExecutable,\n} from './types/guards.ts';\nimport {\n HandlerType,\n SerializerModes,\n SerializerCode,\n SerializerMode,\n isTestEnv,\n isMionCompileMode,\n isMionAOTEmitMode,\n resetRoutesCache,\n} from '@mionjs/core';\nimport {getRawMethodReflection, getHandlerReflection, ensureBinaryJitFns} from './lib/reflection.ts';\nimport {serializerMiddleFns} from './routes/serializer.routes.ts';\nimport {getRouterItemId, getRoutePath, getENV, MION_ROUTES, routesCache} from '@mionjs/core';\nimport {setErrorOptions} from '@mionjs/core';\nimport {getPublicApi, resetRemoteMethodsMetadata} from './lib/remoteMethods.ts';\nimport {addToPersistedMethods, getPersistedMethod, resetPersistedMethods} from './lib/methodsCache.ts';\nimport {mionClientRoutes, mionClientMiddleFns} from './routes/client.routes.ts';\nimport {mionErrorsRoutes} from './routes/errors.routes.ts';\nimport {clearRoutesFlowCache} from './routesFlow.ts';\nimport {clearContextPool} from './callContext.ts';\n\ntype RouterKeyEntryList = [string, RouterEntry][];\ntype RoutesWithId = {\n pathPointer: string[];\n routes: Routes;\n};\n\n// ############# PRIVATE STATE #############\n\nconst mionInternalRoutes = Object.values(MION_ROUTES) as string[];\nconst flatRouter: Map<string, MethodsExecutionChain> = new Map(); // Main Router\nconst middleFnsById: Map<string, MiddleFnMethod | HeadersMethod | RawMethod> = new Map();\nconst routesById: Map<string, RouteMethod> = new Map();\nconst rawMiddleFnsById: Map<string, RawMethod> = new Map();\nconst middleFnNames: Set<string> = new Set();\nconst routeNames: Set<string> = new Set();\nlet complexity = 0;\nlet routerOptions: RouterOptions = {...DEFAULT_ROUTE_OPTIONS};\nlet isRouterInitialized = false;\nlet allExecutablesIds: string[] | undefined;\nlet platformConfig: Record<string, unknown> | undefined;\n\n/** Global middleFns to be run before and after any other middleFns or routes set using `registerRoutes` */\nconst defaultStartMiddleFns = {\n mionDeserializeRequest: serializerMiddleFns.mionDeserializeRequest,\n};\nconst defaultEndMiddleFns = {\n ...mionClientMiddleFns,\n mionSerializeResponse: serializerMiddleFns.mionSerializeResponse,\n};\nlet startMiddleFnsDef: MiddleFnsCollection = {...defaultStartMiddleFns};\nlet endMiddleFnsDef: MiddleFnsCollection = {...defaultEndMiddleFns};\nexport let startMiddleFns: RemoteMethod[] = [];\nexport let endMiddleFns: RemoteMethod[] = [];\n\n// ############# PUBLIC METHODS #############\n\nexport const getRouteExecutionChain = (path: string) => flatRouter.get(path);\nexport const getRouteEntries = () => flatRouter.entries();\nexport const geRoutesSize = () => flatRouter.size;\nexport const getRouteExecutable = (id: string) => routesById.get(id);\nexport const getMiddleFnExecutable = (id: string) => middleFnsById.get(id);\nexport const geMiddleFnsSize = () => middleFnsById.size;\nexport const getComplexity = () => complexity;\nexport const getRouterOptions = <Opts extends RouterOptions>(): Readonly<Opts> => routerOptions as Opts;\nexport const getAnyExecutable = (id: string) => routesById.get(id) || middleFnsById.get(id) || rawMiddleFnsById.get(id);\n\n/** Sets platform adapter config and notifies the parent process (Vite plugin) that the server is ready.\n * Called automatically by platform adapters. Sends an IPC message containing both the\n * serializable router config and the platform adapter config. */\nexport function setPlatformConfig(config: Record<string, unknown>): void {\n platformConfig = config;\n if (isMionAOTEmitMode() && typeof process.send === 'function') {\n const routerConfig = Object.fromEntries(Object.entries(routerOptions).filter(([, v]) => typeof v !== 'function'));\n try {\n process.send({type: 'mion-platform-ready', routerConfig, platformConfig: config});\n } catch (err) {\n console.error('[mion] Failed to send platform-ready IPC:', err);\n }\n }\n}\n\n/** Returns the platform adapter config set by setPlatformConfig(). */\nexport const getPlatformConfig = (): Readonly<Record<string, unknown>> | undefined => platformConfig;\n\nexport const resetRouter = () => {\n flatRouter.clear();\n middleFnsById.clear();\n routesById.clear();\n rawMiddleFnsById.clear();\n middleFnNames.clear();\n routeNames.clear();\n complexity = 0;\n routerOptions = {...DEFAULT_ROUTE_OPTIONS};\n startMiddleFnsDef = {...defaultStartMiddleFns};\n endMiddleFnsDef = {...defaultEndMiddleFns};\n startMiddleFns = [];\n endMiddleFns = [];\n isRouterInitialized = false;\n allExecutablesIds = undefined;\n platformConfig = undefined;\n resetRemoteMethodsMetadata();\n resetPersistedMethods();\n resetRoutesCache();\n clearContextPool();\n clearRoutesFlowCache();\n // Note: We intentionally do NOT call resetJitFnCaches() here because:\n // 1. JIT function caches are global and should persist across router resets\n // 2. The serializableClassRegistry (cleared by resetJitFnCaches) is needed for\n // serialization/deserialization of classes like RpcError\n // resetJitFnCaches() should only be called in specific test scenarios that need\n // to test AOT cache loading behavior\n};\n\n// simpler router initialization\nexport async function initMionRouter<R extends Routes>(routes: R, opts?: Partial<RouterOptions>): Promise<PublicApi<R>> {\n await initRouter(opts);\n const publicApi = await registerRoutes(routes);\n // Emit AOT caches once after ALL routes (error, client, user) are registered\n await emitAOTCaches();\n return publicApi;\n}\n\n/**\n * Initializes the Router.\n * @param application\n * @param contextDataFactory a factory function that returns an object to be shared in the `callContext.shared`\n * @param routerOptions\n * @returns\n */\nexport async function initRouter(opts?: Partial<RouterOptions>): Promise<Readonly<RouterOptions>> {\n if (isRouterInitialized) throw new Error('Router has already been initialized');\n routerOptions = {...routerOptions, ...opts};\n validateSharedDataFactory(routerOptions);\n Object.freeze(routerOptions);\n setErrorOptions(routerOptions);\n if (routerOptions.aot) await loadAOTCaches();\n isRouterInitialized = true;\n await registerRoutes({...mionErrorsRoutes});\n if (!routerOptions.skipClientRoutes) await registerRoutes({...mionClientRoutes});\n if (!isTestEnv()) console.log('mion router initialized', {routerOptions});\n return routerOptions;\n}\n\nexport async function registerRoutes<R extends Routes>(routes: R): Promise<PublicApi<R>> {\n if (!isRouterInitialized) throw new Error('initRouter should be called first');\n startMiddleFns = await getExecutablesFromMiddleFnsCollection(startMiddleFnsDef);\n endMiddleFns = await getExecutablesFromMiddleFnsCollection(endMiddleFnsDef);\n const binaryMiddlewares = new Set<string>();\n await recursiveFlatRoutes(routes, [], [], [], binaryMiddlewares, 0);\n if (binaryMiddlewares.size > 0) await compileBinaryForMiddleware(binaryMiddlewares);\n if (shouldFullGenerateSpec()) {\n return getPublicApi(routes);\n }\n return {} as PublicApi<R>;\n}\n\n/** Add middleFns at the start af the ExecutionChain, adds them before any other existing start middleFns by default */\nexport function addStartMiddleFns(middleFnsDef: MiddleFnsCollection, appendBeforeExisting = true) {\n if (isRouterInitialized) throw new Error('Can not add start middleFns after the router has been initialized');\n if (appendBeforeExisting) {\n startMiddleFnsDef = {...middleFnsDef, ...startMiddleFnsDef};\n return;\n }\n startMiddleFnsDef = {...startMiddleFnsDef, ...middleFnsDef};\n}\n\n/** Add middleFns at the end af the ExecutionChain, adds them after any other existing end middleFns by default */\nexport function addEndMiddleFns(middleFnsDef: MiddleFnsCollection, prependAfterExisting = true) {\n if (isRouterInitialized) throw new Error('Can not add end middleFns after the router has been initialized');\n if (prependAfterExisting) {\n endMiddleFnsDef = {...endMiddleFnsDef, ...middleFnsDef};\n return;\n }\n endMiddleFnsDef = {...middleFnsDef, ...endMiddleFnsDef};\n}\n\nexport function isPrivateDefinition(entry: RouterEntry, id: string): entry is PrivateDef {\n if (isRoute(entry)) return false;\n if (isRawMiddleFnDef(entry)) return true;\n try {\n const executable = getMiddleFnExecutable(id) || getRouteExecutable(id);\n if (!executable)\n throw new Error(`Route or MiddleFn ${id} not found. Please check you have called router.registerRoutes first.`);\n return isPrivateExecutable(executable);\n } catch {\n // error thrown because entry is a Routes object and does not have any handler\n return false;\n }\n}\n\nexport function isPrivateExecutable(executable: RemoteMethod): boolean {\n if (executable.type === HandlerType.rawMiddleFn) return true;\n if (executable.type === HandlerType.route) return false;\n const hasPublicParams = !!executable.paramNames?.length;\n const hasHeaderParams = !!(executable as HeadersMethod).headersParam?.headerNames?.length;\n return !hasPublicParams && !hasHeaderParams && !executable.hasReturnData;\n}\n\nexport function getTotalExecutables(): number {\n return routesById.size + middleFnsById.size + rawMiddleFnsById.size;\n}\n\nexport function getAllExecutablesIds(): string[] {\n if (allExecutablesIds) return allExecutablesIds;\n allExecutablesIds = [...routesById.keys(), ...middleFnsById.keys(), ...rawMiddleFnsById.keys()];\n return allExecutablesIds;\n}\n\n// used by codegen\nexport function shouldFullGenerateSpec(): boolean {\n return routerOptions.getPublicRoutesData || getENV('GENERATE_ROUTER_SPEC') === 'true' || isMionCompileMode();\n}\n\nexport function getRouteExecutableFromPath(path: string): RouteMethod {\n const executionChain = flatRouter.get(path);\n if (!executionChain) {\n // Return the not-found route executable\n return getAnyExecutable(MION_ROUTES.notFound) as RouteMethod;\n }\n return executionChain.methods[executionChain.routeIndex] as RouteMethod;\n}\n\n// ############# PRIVATE METHODS #############\n\nasync function loadAOTCaches() {\n const loader = await import('./aot/aotCacheLoader.ts');\n return loader.loadRouterAOTCaches();\n}\n\nasync function emitAOTCaches() {\n if (!isMionAOTEmitMode()) return;\n // Dynamic import resolves relative to this source file.\n // This only runs via vite-node (MION_COMPILE=buildOnly|childProcess), which always resolves from source.\n const aotEmitter = await import('./lib/aotEmitter.ts');\n return aotEmitter.emitAOTCaches();\n}\n\n/**\n * Optimized algorithm to flatten the routes object into a list of Executable objects.\n * @param routes\n * @param currentPointer current pointer in the routes object i.e. ['users', 'get']\n * @param preMiddleFns middleFns one level up preceding current pointer\n * @param postMiddleFns middleFns one level up following the current pointer\n * @param nestLevel\n */\nasync function recursiveFlatRoutes(\n routes: Routes,\n currentPointer: string[] = [],\n preMiddleFns: RemoteMethod[] = [],\n postMiddleFns: RemoteMethod[] = [],\n binaryMiddlewares: Set<string> = new Set(),\n nestLevel = 0\n) {\n if (nestLevel > MAX_ROUTE_NESTING)\n throw new Error('Too many nested routes, you can only nest routes ${MAX_ROUTE_NESTING} levels');\n\n const entries = Object.entries(routes);\n if (entries.length === 0)\n throw new Error(\n `Invalid route: ${currentPointer.length ? joinPath(...currentPointer) : '*'}. Can Not define empty routes`\n );\n\n let minus1Props: ReturnType<typeof getRouteEntryProperties> | null = null;\n for (let index = 0; index < entries.length; index++) {\n const [key, item] = entries[index];\n // create the executable items\n const newPointer = [...currentPointer, key];\n let routeEntry: RemoteMethod | RoutesWithId;\n if (typeof key !== 'string' || !isNaN(key as any))\n throw new Error(`Invalid route: ${joinPath(...newPointer)}. Numeric route names are not allowed`);\n if (key.includes(',')) throw new Error(`Invalid route: ${joinPath(...newPointer)}. Route names cannot contain commas.`);\n if (key === WORKFLOW_KEY)\n throw new Error(`Invalid route: ${joinPath(...newPointer)}. '${WORKFLOW_KEY}' is a reserved mion route name.`);\n\n // generates a middleFn\n if (isAnyMiddleFnDef(item)) {\n routeEntry = await getExecutableFromAnyMiddleFn(item, newPointer, nestLevel);\n if (middleFnNames.has(routeEntry.id))\n throw new Error(\n `Invalid middleFn: ${joinPath(...newPointer)}. Naming collision, Naming collision, duplicated middleFn.`\n );\n middleFnNames.add(routeEntry.id);\n }\n\n // generates a route\n else if (isRoute(item)) {\n routeEntry = await getExecutableFromRoute(item, newPointer, nestLevel);\n if (routeNames.has(routeEntry.id))\n throw new Error(`Invalid route: ${joinPath(...newPointer)}. Naming collision, duplicated route`);\n routeNames.add(routeEntry.id);\n }\n\n // generates structure required to go one level down\n else if (isRoutes(item)) {\n routeEntry = {\n pathPointer: newPointer,\n routes: item,\n };\n }\n\n // throws an error if the route is invalid\n else {\n const itemType = typeof item;\n throw new Error(`Invalid route: ${joinPath(...newPointer)}. Type <${itemType}> is not a valid route.`);\n }\n\n // recurse into sublevels\n minus1Props = await recursiveCreateExecutionChain(\n routeEntry,\n newPointer,\n preMiddleFns,\n postMiddleFns,\n binaryMiddlewares,\n nestLevel,\n index,\n entries,\n minus1Props\n );\n\n complexity++;\n }\n}\n\nasync function recursiveCreateExecutionChain(\n routeEntry: RemoteMethod | RoutesWithId,\n currentPointer: string[],\n preMiddleFns: RemoteMethod[],\n postMiddleFns: RemoteMethod[],\n binaryMiddlewares: Set<string>,\n nestLevel: number,\n index: number,\n routeKeyedEntries: RouterKeyEntryList,\n minus1Props: ReturnType<typeof getRouteEntryProperties> | null\n) {\n const minus1 = getEntry(index - 1, routeKeyedEntries);\n const plus1 = getEntry(index + 1, routeKeyedEntries);\n const props = getRouteEntryProperties(minus1, routeEntry, plus1);\n\n if (props.isBetweenRoutes && minus1Props) {\n props.preLevelMiddleFns = minus1Props.preLevelMiddleFns;\n props.postLevelMiddleFns = minus1Props.postLevelMiddleFns;\n } else {\n for (let i = 0; i < routeKeyedEntries.length; i++) {\n const [k, entry] = routeKeyedEntries[i];\n complexity++;\n if (!isAnyMiddleFnDef(entry)) continue;\n const newPointer = [...currentPointer.slice(0, -1), k];\n const executable = await getExecutableFromAnyMiddleFn(entry, newPointer, nestLevel);\n if (i < index) props.preLevelMiddleFns.push(executable);\n if (i > index) props.postLevelMiddleFns.push(executable);\n }\n }\n const isExec = isExecutable(routeEntry);\n\n if (isExec && props.isRoute) {\n const path = getRoutePath(routeEntry.pointer, routerOptions);\n const routeMethod = routeEntry as RouteMethod;\n const levelMethods = [\n ...preMiddleFns,\n ...props.preLevelMiddleFns,\n routeEntry,\n ...props.postLevelMiddleFns,\n ...postMiddleFns,\n ];\n const methods = [...startMiddleFns, ...levelMethods, ...endMiddleFns];\n const executionChain: MethodsExecutionChain = {\n routeIndex: startMiddleFns.length + preMiddleFns.length + props.preLevelMiddleFns.length,\n methods,\n serializer: getSerializerCodeFromMode(routeMethod.options.serializer),\n };\n const middleFnIds = getPublicMiddleFnIds(methods);\n // add middleware functions deps, so can be serialized with the router\n if (middleFnIds.length) routeMethod.middleFnIds = middleFnIds;\n flatRouter.set(path, executionChain);\n // Collect middleware that needs binary JIT functions for retroactive compilation\n if (routeMethod.options.serializer === 'binary') {\n for (const method of methods) {\n if (method.type === HandlerType.middleFn || method.type === HandlerType.headersMiddleFn) {\n binaryMiddlewares.add(method.id);\n }\n }\n }\n } else if (!isExec) {\n await recursiveFlatRoutes(\n routeEntry.routes,\n routeEntry.pathPointer,\n [...preMiddleFns, ...props.preLevelMiddleFns],\n [...props.postLevelMiddleFns, ...postMiddleFns],\n binaryMiddlewares,\n nestLevel + 1\n );\n }\n\n return props;\n}\n\nasync function getExecutableFromAnyMiddleFn(\n middleFn: MiddleFnDef | HeadersMiddleFnDef | RawMiddleFnDef,\n middleFnPointer: string[],\n nestLevel: number\n) {\n if (isRawMiddleFnDef(middleFn)) return getExecutableFromRawMiddleFn(middleFn, middleFnPointer, nestLevel);\n return getExecutableFromMiddleFn(middleFn, middleFnPointer, nestLevel);\n}\n\nexport async function getExecutableFromMiddleFn(\n middleFn: MiddleFnDef | HeadersMiddleFnDef,\n middleFnPointer: string[],\n nestLevel: number\n): Promise<MiddleFnMethod | HeadersMethod> {\n const isHeader = isHeadersMiddleFnDef(middleFn);\n // todo fix header id should be same as any other one and then maybe map from id to header name\n const middleFnId = getRouterItemId(middleFnPointer);\n const existing = middleFnsById.get(middleFnId);\n if (existing) return existing as MiddleFnMethod;\n\n type MixedMiddleFn = (Omit<MiddleFnMethod, 'type'> | Omit<HeadersMethod, 'type'>) & {\n type: typeof HandlerType.middleFn | typeof HandlerType.headersMiddleFn;\n };\n\n const compiledMethod = getPersistedMethod(middleFnId, middleFn.handler);\n let executable: MixedMiddleFn;\n if (compiledMethod) {\n executable = compiledMethod as MixedMiddleFn;\n } else {\n const reflectionData = await getHandlerReflection(\n middleFn.handler,\n middleFnId,\n routerOptions,\n middleFn.options ?? {},\n isHeader,\n middleFn.options?.strictTypes\n );\n executable = {\n id: middleFnId,\n type: isHeader ? HandlerType.headersMiddleFn : HandlerType.middleFn,\n nestLevel,\n handler: middleFn.handler,\n pointer: middleFnPointer,\n ...reflectionData,\n options: {\n runOnError: !!middleFn.options?.runOnError,\n validateParams: middleFn.options?.validateParams ?? true,\n validateReturn: middleFn.options?.validateReturn ?? false,\n description: middleFn.options?.description,\n strictTypes: middleFn.options?.strictTypes ?? routerOptions.strictTypes,\n },\n };\n addToPersistedMethods(middleFnId, executable);\n }\n\n middleFnsById.set(middleFnId, executable as any);\n routesCache.setMethodJitFns(middleFnId, executable as any);\n return executable as any;\n}\n\nexport async function getExecutableFromRawMiddleFn(\n middleFn: RawMiddleFnDef,\n middleFnPointer: string[],\n nestLevel: number\n): Promise<RawMethod> {\n const middleFnId = getRouterItemId(middleFnPointer);\n const existing = rawMiddleFnsById.get(middleFnId);\n if (existing) return existing as RawMethod;\n const reflectionData = await getRawMethodReflection(middleFn.handler, middleFnId, routerOptions);\n const executable: RawMethod = {\n id: middleFnId,\n type: HandlerType.rawMiddleFn,\n nestLevel,\n handler: middleFn.handler,\n pointer: middleFnPointer,\n ...reflectionData,\n options: {\n runOnError: !!middleFn.options?.runOnError,\n validateParams: false,\n validateReturn: false,\n description: middleFn.options?.description,\n },\n };\n rawMiddleFnsById.set(middleFnId, executable);\n routesCache.setMethodJitFns(middleFnId, executable as any);\n return executable;\n}\n\n/** Retroactively compiles binary JIT functions for middleware in the path of binary routes */\nasync function compileBinaryForMiddleware(binaryMiddlewareIds: Set<string>): Promise<void> {\n for (const id of binaryMiddlewareIds) {\n const method = middleFnsById.get(id);\n if (method) await ensureBinaryJitFns(method as MiddleFnMethod);\n }\n}\n\nexport async function getExecutableFromRoute(route: Route, routePointer: string[], nestLevel: number): Promise<RouteMethod> {\n const routeId = getRouterItemId(routePointer);\n const existing = routesById.get(routeId);\n if (existing) return existing as RouteMethod;\n\n const compiledMethod = getPersistedMethod(routeId, route.handler);\n let executable: RouteMethod;\n if (compiledMethod) {\n executable = compiledMethod as RouteMethod;\n } else {\n const resolvedRouteOptions = {...route.options, serializer: route.options?.serializer ?? routerOptions.serializer};\n const reflectionData = await getHandlerReflection(\n route.handler,\n routeId,\n routerOptions,\n resolvedRouteOptions,\n false,\n route.options?.strictTypes\n );\n executable = {\n id: routeId,\n type: HandlerType.route,\n nestLevel,\n handler: route.handler,\n pointer: routePointer,\n ...reflectionData,\n options: {\n runOnError: false,\n validateParams: route.options?.validateParams ?? true,\n validateReturn: route.options?.validateReturn ?? false,\n description: route.options?.description,\n serializer: route.options?.serializer ?? routerOptions.serializer,\n isMutation: route.options?.isMutation,\n strictTypes: route.options?.strictTypes ?? routerOptions.strictTypes,\n },\n };\n addToPersistedMethods(routeId, executable);\n }\n routesById.set(routeId, executable);\n routesCache.setMethodJitFns(routeId, executable as any);\n return executable;\n}\n\n/** Returns IDs of public middleware methods from the execution chain, excluding internal mion routes. */\nfunction getPublicMiddleFnIds(methods: RemoteMethod[]): string[] {\n const ids = methods\n .filter((exec) => isPublicExecutable(exec))\n .map((exec) => getRouterItemId(exec.pointer))\n .filter((mfId) => {\n if (mionInternalRoutes.includes(mfId)) return false;\n const exec = getMiddleFnExecutable(mfId);\n return exec && isPublicExecutable(exec);\n });\n return ids;\n}\n\nfunction getEntry(index: number, keyEntryList: RouterKeyEntryList) {\n return keyEntryList[index]?.[1];\n}\n\nfunction getRouteEntryProperties(\n minus1: RouterEntry | undefined,\n zero: RemoteMethod | RoutesWithId,\n plus1: RouterEntry | undefined\n) {\n const minus1IsRoute = minus1 && isRoute(minus1);\n const zeroIsRoute = (zero as RemoteMethod).type === HandlerType.route;\n const plus1IsRoute = plus1 && isRoute(plus1);\n\n const isExec = !!(zero as RemoteMethod).handler;\n\n return {\n isBetweenRoutes: minus1IsRoute && zeroIsRoute && plus1IsRoute,\n isExecutable: isExec,\n isRoute: zeroIsRoute,\n preLevelMiddleFns: [] as RemoteMethod[],\n postLevelMiddleFns: [] as RemoteMethod[],\n };\n}\n\nasync function getExecutablesFromMiddleFnsCollection(\n middleFnsDef: MiddleFnsCollection\n): Promise<(RawMethod | MiddleFnMethod | HeadersMethod)[]> {\n const results: (RawMethod | MiddleFnMethod | HeadersMethod)[] = [];\n for (const [key, middleFn] of Object.entries(middleFnsDef)) {\n if (isRawMiddleFnDef(middleFn)) {\n results.push(await getExecutableFromRawMiddleFn(middleFn, [key], 0));\n } else if (isHeadersMiddleFnDef(middleFn) || isMiddleFnDef(middleFn)) {\n results.push(await getExecutableFromMiddleFn(middleFn, [key], 0));\n } else {\n throw new Error(`Invalid middleFn: ${key}. Invalid middleFn definition`);\n }\n }\n return results;\n}\n\n/**\n * Validates that a contextDataFactory returns a valid context data object.\n * @param contextDataFactory The factory function to validate\n * @throws Error if the factory doesn't return a plain object with at least one property\n */\nfunction validateSharedDataFactory(opts?: Partial<RouterOptions>): void {\n if (!opts?.contextDataFactory) return;\n const testSharedData = opts.contextDataFactory();\n if (\n typeof testSharedData !== 'object' ||\n Array.isArray(testSharedData) ||\n testSharedData === null ||\n Object.keys(testSharedData).length === 0\n ) {\n throw new Error('contextDataFactory must return a plain object with at least one property');\n }\n}\n\n/** Maps serializer mode string to response body type code */\nfunction getSerializerCodeFromMode(mode: SerializerMode | undefined): SerializerCode {\n switch (mode) {\n case 'binary':\n return SerializerModes.binary;\n case 'stringifyJson':\n return SerializerModes.stringifyJson;\n case 'optimistic':\n return SerializerModes.stringifyJson;\n case 'json':\n default:\n return SerializerModes.json;\n }\n}\n\n/** Path replacement as is not available in edge runtime */\nfunction joinPath(...parts: string[]): string {\n return parts.filter(Boolean).join('/');\n}\n"],"names":["MION_ROUTES","DEFAULT_ROUTE_OPTIONS","serializerMiddleFns","mionClientMiddleFns","startMiddleFns","endMiddleFns","isMionAOTEmitMode","resetRemoteMethodsMetadata","resetPersistedMethods","resetRoutesCache","clearContextPool","clearRoutesFlowCache","setErrorOptions","mionErrorsRoutes","mionClientRoutes","isTestEnv","getPublicApi","isRoute","isRawMiddleFnDef","HandlerType","getENV","isMionCompileMode","MAX_ROUTE_NESTING","WORKFLOW_KEY","isAnyMiddleFnDef","isRoutes","isExecutable","getRoutePath","isHeadersMiddleFnDef","getRouterItemId","getPersistedMethod","getHandlerReflection","addToPersistedMethods","routesCache","getRawMethodReflection","ensureBinaryJitFns","isPublicExecutable","isMiddleFnDef","SerializerModes"],"mappings":"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"}
@@ -5,6 +5,7 @@ const src_router = require("../router.cjs");
5
5
  const src_lib_handlers = require("../lib/handlers.cjs");
6
6
  const src_types_general = require("../types/general.cjs");
7
7
  const src_lib_remoteMethods = require("../lib/remoteMethods.cjs");
8
+ const src_types_context = require("../types/context.cjs");
8
9
  function __assignType(fn, args) {
9
10
  fn.__type = args;
10
11
  return fn;
@@ -34,17 +35,13 @@ function mionGetRemoteMethodsDataById(ctx, methodsIds, getAllRemoteMethods) {
34
35
  return resp;
35
36
  }
36
37
  mionGetRemoteMethodsDataById.__type = ["ctx", "methodsIds", "getAllRemoteMethods", () => core.__ΩSerializableMethodsData, "rpc-metadata-not-found", () => core.RpcError, "mionGetRemoteMethodsDataById", `P"2!&F2")2#8Pn$P.%7&J/'`];
37
- function mionGetRemoteMethodsDataByPath(ctx, path, getAllRemoteMethods) {
38
- const executables = src_router.getRouteExecutionChain(path);
39
- if (!executables)
40
- return new core.RpcError({
41
- type: "rpc-metadata-not-found",
42
- publicMessage: `Route ${path} not found`
43
- });
44
- const privateExecutables = executables.methods.filter(__assignType((e) => !src_router.isPrivateExecutable(e), ["e", "", 'P"2!"/"']));
45
- return mionGetRemoteMethodsDataById(ctx, privateExecutables.map(__assignType((e) => e.id, ["e", "", 'P"2!"/"'])), getAllRemoteMethods);
38
+ function mionMethodsMetadata(ctx, methodsIds, getAllRemoteMethods) {
39
+ if (!methodsIds || methodsIds.length === 0)
40
+ return;
41
+ ctx.response.serializer = core.SerializerModes.stringifyJson;
42
+ return mionGetRemoteMethodsDataById(ctx, methodsIds, getAllRemoteMethods);
46
43
  }
47
- mionGetRemoteMethodsDataByPath.__type = ["ctx", "path", "getAllRemoteMethods", () => core.__ΩSerializableMethodsData, "rpc-metadata-not-found", () => core.RpcError, "mionGetRemoteMethodsDataByPath", `P"2!&2")2#8Pn$P.%7&J/'`];
44
+ mionMethodsMetadata.__type = [() => src_types_context.__ΩCallContext, "ctx", "methodsIds", "getAllRemoteMethods", () => core.__ΩSerializableMethodsData, "rpc-metadata-not-found", () => core.RpcError, "mionMethodsMetadata", `Pn!2"&F2#8)2$8Pn%P.&7'$J/(`];
48
45
  function addRequiredRemoteMethodsToResponse(id, resp, errorData) {
49
46
  const { methods, deps, purFnDeps } = resp;
50
47
  if (methods[id])
@@ -64,13 +61,16 @@ function addRequiredRemoteMethodsToResponse(id, resp, errorData) {
64
61
  src_lib_remoteMethods.serializeMethodDeps(method, deps, purFnDeps);
65
62
  }
66
63
  addRequiredRemoteMethodsToResponse.__type = ["id", () => core.__ΩSerializableMethodsData, "resp", () => core.__ΩAnyObject, "errorData", "addRequiredRemoteMethodsToResponse", 'P&2!n"2#n$2%$/&'];
64
+ const mionClientMiddleFns = {
65
+ [core.MION_ROUTES.methodsMetadata]: src_lib_handlers.middleFn(mionMethodsMetadata, { runOnError: true })
66
+ };
67
67
  const mionClientRoutes = {
68
68
  // Client routes always use stringifyJson serialization to avoid mutating data as is cached
69
69
  // These routes are used by the client to fetch metadata and must work regardless of router's default serialization
70
- [core.MION_ROUTES.methodsMetadataById]: src_lib_handlers.route(mionGetRemoteMethodsDataById, { serializer: "stringifyJson" }),
71
- [core.MION_ROUTES.methodsMetadataByPath]: src_lib_handlers.route(mionGetRemoteMethodsDataByPath, { serializer: "stringifyJson" })
70
+ [core.MION_ROUTES.methodsMetadataById]: src_lib_handlers.route(mionGetRemoteMethodsDataById, { serializer: "stringifyJson" })
72
71
  };
73
72
  exports.__ΩClientRouteOptions = __ΩClientRouteOptions;
74
73
  exports.defaultClientRouteOptions = defaultClientRouteOptions;
74
+ exports.mionClientMiddleFns = mionClientMiddleFns;
75
75
  exports.mionClientRoutes = mionClientRoutes;
76
76
  //# sourceMappingURL=client.routes.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"client.routes.cjs","sources":["../../../../src/routes/client.routes.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 {AnyObject, RpcError, MION_ROUTES, SerializableMethodsData} from '@mionjs/core';\nimport {\n getMiddleFnExecutable,\n getRouteExecutable,\n isPrivateExecutable,\n getRouteExecutionChain,\n getRouterOptions,\n getTotalExecutables,\n getAllExecutablesIds,\n getAnyExecutable,\n} from '../router.ts';\nimport {route} from '../lib/handlers.ts';\nimport {RouterOptions, Routes} from '../types/general.ts';\nimport {getSerializableMethod, serializeMethodDeps} from '../lib/remoteMethods.ts';\nimport {RemoteMethod} from '../types/remoteMethods.ts';\n\nexport interface ClientRouteOptions extends RouterOptions {\n getAllRemoteMethodsMaxNumber?: number;\n}\n\nexport const defaultClientRouteOptions = {\n getAllRemoteMethodsMaxNumber: 100,\n};\n\n// Internal mion routes that should not be exposed to clients\nconst mionInternalRoutes = Object.values(MION_ROUTES) as string[];\n\n/**\n * Returns the metadata for the given method ids.\n * If getAllRemoteMethods is true, all public methods and middleFns are returned.\n * @mion:route\n */\nfunction mionGetRemoteMethodsDataById(\n ctx,\n methodsIds: string[],\n getAllRemoteMethods?: boolean\n): SerializableMethodsData | RpcError<'rpc-metadata-not-found'> {\n const resp: SerializableMethodsData = {\n methods: {},\n deps: {},\n purFnDeps: {},\n };\n const errorData = {};\n const maxMethods =\n getRouterOptions<ClientRouteOptions>().getAllRemoteMethodsMaxNumber ||\n defaultClientRouteOptions.getAllRemoteMethodsMaxNumber;\n const shouldReturnAll = getAllRemoteMethods && getTotalExecutables() <= maxMethods;\n const idsToReturn = shouldReturnAll\n ? getAllExecutablesIds().filter(\n (id) => !mionInternalRoutes.includes(id) && !isPrivateExecutable(getAnyExecutable(id) as RemoteMethod)\n )\n : methodsIds;\n idsToReturn.forEach((id) => addRequiredRemoteMethodsToResponse(id, resp, errorData));\n\n if (Object.keys(errorData).length)\n return new RpcError({\n type: 'rpc-metadata-not-found',\n publicMessage: 'Errors getting Remote Methods Metadata',\n errorData,\n });\n return resp;\n}\n\n/**\n * Returns the metadata for the given route path.\n * This include all middleFns in the ExecutionChain of the route.\n * If getAllRemoteMethods is true, all public methods and middleFns are returned.\n * @mion:route\n */\nfunction mionGetRemoteMethodsDataByPath(\n ctx,\n path: string,\n getAllRemoteMethods?: boolean\n): SerializableMethodsData | RpcError<'rpc-metadata-not-found'> {\n const executables = getRouteExecutionChain(path);\n if (!executables)\n return new RpcError({\n type: 'rpc-metadata-not-found',\n publicMessage: `Route ${path} not found`,\n });\n const privateExecutables = executables.methods.filter((e) => !isPrivateExecutable(e));\n return mionGetRemoteMethodsDataById(\n ctx,\n privateExecutables.map((e) => e.id),\n getAllRemoteMethods\n );\n}\n\nfunction addRequiredRemoteMethodsToResponse(id: string, resp: SerializableMethodsData, errorData: AnyObject): void {\n const {methods, deps, purFnDeps} = resp;\n if (methods[id]) return;\n if (mionInternalRoutes.includes(id)) return;\n const executable = getMiddleFnExecutable(id) || getRouteExecutable(id);\n if (!executable) {\n errorData[id] = `Remote Method ${id} not found`;\n return;\n }\n if (isPrivateExecutable(executable)) return;\n const method = getSerializableMethod(executable as RemoteMethod);\n methods[id] = method;\n method.middleFnIds?.forEach((middleFnId) => addRequiredRemoteMethodsToResponse(middleFnId, resp, errorData));\n serializeMethodDeps(method, deps, purFnDeps);\n}\n\nexport const mionClientRoutes = {\n // Client routes always use stringifyJson serialization to avoid mutating data as is cached\n // These routes are used by the client to fetch metadata and must work regardless of router's default serialization\n [MION_ROUTES.methodsMetadataById]: route(mionGetRemoteMethodsDataById, {serializer: 'stringifyJson'}),\n [MION_ROUTES.methodsMetadataByPath]: route(mionGetRemoteMethodsDataByPath, {serializer: 'stringifyJson'}),\n} as const satisfies Routes;\n"],"names":["MION_ROUTES","getRouterOptions","getTotalExecutables","getAllExecutablesIds","isPrivateExecutable","getAnyExecutable","RpcError","getRouteExecutionChain","getMiddleFnExecutable","getRouteExecutable","getSerializableMethod","serializeMethodDeps","route"],"mappings":";;;;;;;;;;;;AA2BO,MAAM,4BAA4B;AAAA,EACrC,8BAA8B;;AAIlC,MAAM,qBAAqB,OAAO,OAAOA,gBAAW;AAOpD,SAAS,6BACL,KACA,YACA,qBAA6B;AAE7B,QAAM,OAAgC;AAAA,IAClC,SAAS,CAAA;AAAA,IACT,MAAM,CAAA;AAAA,IACN,WAAW,CAAA;AAAA,EAAA;AAEf,QAAM,YAAY,CAAA;AAClB,QAAM,cACFC,WAAAA,4DAAAA,WAAAA,iBAAA,GAAuC,gCACvC,0BAA0B;AAC9B,QAAM,kBAAkB,uBAAuBC,WAAAA,oBAAA,KAAyB;AACxE,QAAM,cAAc,kBACdC,WAAAA,uBAAuB,OAAM,aACzB,CAAC,OAAO,CAAC,mBAAmB,SAAS,EAAE,KAAK,CAACC,WAAAA,oBAAoBC,4BAAiB,EAAE,CAAiB,GAAC,CAAA,MAAA,IAAA,SAAA,CAAA,CAAA,IAE1G;AACN,cAAY,QAAO,aAAC,CAAC,OAAO,mCAAmC,IAAI,MAAM,SAAS;AAElF,MAAI,OAAO,KAAK,SAAS,EAAE;AACvB,WAAO,IAAIC,KAAAA,SAAS;AAAA,MAChB,MAAM;AAAA,MACN,eAAe;AAAA,MACf;AAAA,IAAA,CACH;AACL,SAAO;AACX;;AAQA,SAAS,+BACL,KACA,MACA,qBAA6B;AAE7B,QAAM,cAAcC,WAAAA,uBAAuB,IAAI;AAC/C,MAAI,CAAC;AACD,WAAO,IAAID,KAAAA,SAAS;AAAA,MAChB,MAAM;AAAA,MACN,eAAe,SAAS,IAAI;AAAA,IAAA,CAC/B;AACL,QAAM,qBAAqB,YAAY,QAAQ,OAAM,aAAC,CAAC,MAAM,CAACF,WAAAA,oBAAoB,CAAC;AACnF,SAAO,6BACH,KACA,mBAAmB,iBAAI,CAAC,MAAM,EAAE,4BAChC,mBAAmB;AAE3B;;AAEA,SAAS,mCAAmC,IAAY,MAA+B,WAAoB;AACvG,QAAM,EAAC,SAAS,MAAM,UAAA,IAAa;AACnC,MAAI,QAAQ,EAAE;AAAG;AACjB,MAAI,mBAAmB,SAAS,EAAE;AAAG;AACrC,QAAM,aAAaI,WAAAA,sBAAsB,EAAE,KAAKC,WAAAA,mBAAmB,EAAE;AACrE,MAAI,CAAC,YAAY;AACb,cAAU,EAAE,IAAI,iBAAiB,EAAE;AACnC;AAAA,EACJ;AACA,MAAIL,WAAAA,oBAAoB,UAAU;AAAG;AACrC,QAAM,SAASM,sBAAAA,sBAAsB,UAA0B;AAC/D,UAAQ,EAAE,IAAI;AACd,SAAO,aAAa,QAAO,aAAC,CAAC,eAAe,mCAAmC,YAAY,MAAM,SAAS;AAC1GC,4CAAoB,QAAQ,MAAM,SAAS;AAC/C;;AAEO,MAAM,mBAAmB;AAAA;AAAA;AAAA,EAG5B,CAACX,KAAAA,YAAY,mBAAmB,GAAGY,iBAAAA,MAAM,8BAA8B,EAAC,YAAY,iBAAgB;AAAA,EACpG,CAACZ,KAAAA,YAAY,qBAAqB,GAAGY,iBAAAA,MAAM,gCAAgC,EAAC,YAAY,gBAAA,CAAgB;;;;;"}
1
+ {"version":3,"file":"client.routes.cjs","sources":["../../../../src/routes/client.routes.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 {AnyObject, Mutable, RpcError, MION_ROUTES, SerializableMethodsData, SerializerModes} from '@mionjs/core';\nimport {\n getMiddleFnExecutable,\n getRouteExecutable,\n isPrivateExecutable,\n getRouterOptions,\n getTotalExecutables,\n getAllExecutablesIds,\n getAnyExecutable,\n} from '../router.ts';\nimport {middleFn, route} from '../lib/handlers.ts';\nimport {RouterOptions, Routes} from '../types/general.ts';\nimport {MiddleFnsCollection} from '../types/publicMethods.ts';\nimport {getSerializableMethod, serializeMethodDeps} from '../lib/remoteMethods.ts';\nimport {RemoteMethod} from '../types/remoteMethods.ts';\nimport {CallContext, MionResponse} from '../types/context.ts';\n\nexport interface ClientRouteOptions extends RouterOptions {\n getAllRemoteMethodsMaxNumber?: number;\n}\n\nexport const defaultClientRouteOptions = {\n getAllRemoteMethodsMaxNumber: 100,\n};\n\n// Internal mion routes that should not be exposed to clients\nconst mionInternalRoutes = Object.values(MION_ROUTES) as string[];\n\n/**\n * Returns the metadata for the given method ids.\n * If getAllRemoteMethods is true, all public methods and middleFns are returned.\n * @mion:route\n */\nfunction mionGetRemoteMethodsDataById(\n ctx,\n methodsIds: string[],\n getAllRemoteMethods?: boolean\n): SerializableMethodsData | RpcError<'rpc-metadata-not-found'> {\n const resp: SerializableMethodsData = {\n methods: {},\n deps: {},\n purFnDeps: {},\n };\n const errorData = {};\n const maxMethods =\n getRouterOptions<ClientRouteOptions>().getAllRemoteMethodsMaxNumber ||\n defaultClientRouteOptions.getAllRemoteMethodsMaxNumber;\n const shouldReturnAll = getAllRemoteMethods && getTotalExecutables() <= maxMethods;\n const idsToReturn = shouldReturnAll\n ? getAllExecutablesIds().filter(\n (id) => !mionInternalRoutes.includes(id) && !isPrivateExecutable(getAnyExecutable(id) as RemoteMethod)\n )\n : methodsIds;\n idsToReturn.forEach((id) => addRequiredRemoteMethodsToResponse(id, resp, errorData));\n\n if (Object.keys(errorData).length)\n return new RpcError({\n type: 'rpc-metadata-not-found',\n publicMessage: 'Errors getting Remote Methods Metadata',\n errorData,\n });\n return resp;\n}\n\n/** Middleware wrapper: delegates to mionGetRemoteMethodsDataById when params are provided */\nfunction mionMethodsMetadata(\n ctx: CallContext,\n methodsIds?: string[],\n getAllRemoteMethods?: boolean\n): SerializableMethodsData | RpcError<'rpc-metadata-not-found'> | void {\n if (!methodsIds || methodsIds.length === 0) return;\n // Force JSON serialization so optimistic client can parse the response\n (ctx.response as Mutable<MionResponse>).serializer = SerializerModes.stringifyJson;\n return mionGetRemoteMethodsDataById(ctx, methodsIds, getAllRemoteMethods);\n}\n\nfunction addRequiredRemoteMethodsToResponse(id: string, resp: SerializableMethodsData, errorData: AnyObject): void {\n const {methods, deps, purFnDeps} = resp;\n if (methods[id]) return;\n if (mionInternalRoutes.includes(id)) return;\n const executable = getMiddleFnExecutable(id) || getRouteExecutable(id);\n if (!executable) {\n errorData[id] = `Remote Method ${id} not found`;\n return;\n }\n if (isPrivateExecutable(executable)) return;\n const method = getSerializableMethod(executable as RemoteMethod);\n methods[id] = method;\n method.middleFnIds?.forEach((middleFnId) => addRequiredRemoteMethodsToResponse(middleFnId, resp, errorData));\n serializeMethodDeps(method, deps, purFnDeps);\n}\n\nexport const mionClientMiddleFns = {\n [MION_ROUTES.methodsMetadata]: middleFn(mionMethodsMetadata, {runOnError: true}),\n} as const satisfies MiddleFnsCollection;\n\nexport const mionClientRoutes = {\n // Client routes always use stringifyJson serialization to avoid mutating data as is cached\n // These routes are used by the client to fetch metadata and must work regardless of router's default serialization\n [MION_ROUTES.methodsMetadataById]: route(mionGetRemoteMethodsDataById, {serializer: 'stringifyJson'}),\n} as const satisfies Routes;\n"],"names":["MION_ROUTES","getRouterOptions","getTotalExecutables","getAllExecutablesIds","isPrivateExecutable","getAnyExecutable","RpcError","SerializerModes","getMiddleFnExecutable","getRouteExecutable","getSerializableMethod","serializeMethodDeps","middleFn","route"],"mappings":";;;;;;;;;;;;;AA4BO,MAAM,4BAA4B;AAAA,EACrC,8BAA8B;;AAIlC,MAAM,qBAAqB,OAAO,OAAOA,gBAAW;AAOpD,SAAS,6BACL,KACA,YACA,qBAA6B;AAE7B,QAAM,OAAgC;AAAA,IAClC,SAAS,CAAA;AAAA,IACT,MAAM,CAAA;AAAA,IACN,WAAW,CAAA;AAAA,EAAA;AAEf,QAAM,YAAY,CAAA;AAClB,QAAM,cACFC,WAAAA,4DAAAA,WAAAA,iBAAA,GAAuC,gCACvC,0BAA0B;AAC9B,QAAM,kBAAkB,uBAAuBC,WAAAA,oBAAA,KAAyB;AACxE,QAAM,cAAc,kBACdC,WAAAA,uBAAuB,OAAM,aACzB,CAAC,OAAO,CAAC,mBAAmB,SAAS,EAAE,KAAK,CAACC,WAAAA,oBAAoBC,4BAAiB,EAAE,CAAiB,GAAC,CAAA,MAAA,IAAA,SAAA,CAAA,CAAA,IAE1G;AACN,cAAY,QAAO,aAAC,CAAC,OAAO,mCAAmC,IAAI,MAAM,SAAS;AAElF,MAAI,OAAO,KAAK,SAAS,EAAE;AACvB,WAAO,IAAIC,KAAAA,SAAS;AAAA,MAChB,MAAM;AAAA,MACN,eAAe;AAAA,MACf;AAAA,IAAA,CACH;AACL,SAAO;AACX;;AAGA,SAAS,oBACL,KACA,YACA,qBAA6B;AAE7B,MAAI,CAAC,cAAc,WAAW,WAAW;AAAG;AAE3C,MAAI,SAAmC,aAAaC,KAAAA,gBAAgB;AACrE,SAAO,6BAA6B,KAAK,YAAY,mBAAmB;AAC5E;;AAEA,SAAS,mCAAmC,IAAY,MAA+B,WAAoB;AACvG,QAAM,EAAC,SAAS,MAAM,UAAA,IAAa;AACnC,MAAI,QAAQ,EAAE;AAAG;AACjB,MAAI,mBAAmB,SAAS,EAAE;AAAG;AACrC,QAAM,aAAaC,WAAAA,sBAAsB,EAAE,KAAKC,WAAAA,mBAAmB,EAAE;AACrE,MAAI,CAAC,YAAY;AACb,cAAU,EAAE,IAAI,iBAAiB,EAAE;AACnC;AAAA,EACJ;AACA,MAAIL,WAAAA,oBAAoB,UAAU;AAAG;AACrC,QAAM,SAASM,sBAAAA,sBAAsB,UAA0B;AAC/D,UAAQ,EAAE,IAAI;AACd,SAAO,aAAa,QAAO,aAAC,CAAC,eAAe,mCAAmC,YAAY,MAAM,SAAS;AAC1GC,4CAAoB,QAAQ,MAAM,SAAS;AAC/C;;AAEO,MAAM,sBAAsB;AAAA,EAC/B,CAACX,KAAAA,YAAY,eAAe,GAAGY,iBAAAA,SAAS,qBAAqB,EAAC,YAAY,KAAA,CAAK;;AAG5E,MAAM,mBAAmB;AAAA;AAAA;AAAA,EAG5B,CAACZ,KAAAA,YAAY,mBAAmB,GAAGa,iBAAAA,MAAM,8BAA8B,EAAC,YAAY,gBAAA,CAAgB;;;;;;"}
@@ -1,5 +1,6 @@
1
1
  import { RpcError, SerializableMethodsData } from '@mionjs/core';
2
2
  import { RouterOptions } from '../types/general.ts';
3
+ import { CallContext } from '../types/context.ts';
3
4
  export interface ClientRouteOptions extends RouterOptions {
4
5
  getAllRemoteMethodsMaxNumber?: number;
5
6
  }
@@ -7,10 +8,12 @@ export declare const defaultClientRouteOptions: {
7
8
  getAllRemoteMethodsMaxNumber: number;
8
9
  };
9
10
  declare function mionGetRemoteMethodsDataById(ctx: any, methodsIds: string[], getAllRemoteMethods?: boolean): SerializableMethodsData | RpcError<'rpc-metadata-not-found'>;
10
- declare function mionGetRemoteMethodsDataByPath(ctx: any, path: string, getAllRemoteMethods?: boolean): SerializableMethodsData | RpcError<'rpc-metadata-not-found'>;
11
+ declare function mionMethodsMetadata(ctx: CallContext, methodsIds?: string[], getAllRemoteMethods?: boolean): SerializableMethodsData | RpcError<'rpc-metadata-not-found'> | void;
12
+ export declare const mionClientMiddleFns: {
13
+ readonly "mion@methodsMetadata": import('../types/definitions.ts').MiddleFnDef<typeof mionMethodsMetadata>;
14
+ };
11
15
  export declare const mionClientRoutes: {
12
16
  readonly "mion@methodsMetadataById": import('../types/definitions.ts').RouteDef<typeof mionGetRemoteMethodsDataById>;
13
- readonly "mion@methodsMetadataByPath": import('../types/definitions.ts').RouteDef<typeof mionGetRemoteMethodsDataByPath>;
14
17
  };
15
18
  export {};
16
19
  export declare type __ΩClientRouteOptions = any[];
@@ -4,7 +4,6 @@ export declare const mionRoutes: {
4
4
  readonly "mion@notFound": import('../types/definitions.ts').RouteDef<(ctx: import('../types/context.ts').CallContext) => import('@mionjs/core/.dist/esm/index.js').RpcError<"route-not-found">>;
5
5
  readonly "mion@platformError": import('../types/definitions.ts').RouteDef<(_ctx: import('../types/context.ts').CallContext) => import('@mionjs/core/.dist/esm/index.js').RpcError<string>>;
6
6
  readonly "mion@methodsMetadataById": import('../types/definitions.ts').RouteDef<(ctx: any, methodsIds: string[], getAllRemoteMethods?: boolean) => import('@mionjs/core/.dist/esm/index.js').SerializableMethodsData | import('@mionjs/core/.dist/esm/index.js').RpcError<"rpc-metadata-not-found">>;
7
- readonly "mion@methodsMetadataByPath": import('../types/definitions.ts').RouteDef<(ctx: any, path: string, getAllRemoteMethods?: boolean) => import('@mionjs/core/.dist/esm/index.js').SerializableMethodsData | import('@mionjs/core/.dist/esm/index.js').RpcError<"rpc-metadata-not-found">>;
8
7
  };
9
8
  export type MionRoutes = PublicApi<typeof mionRoutes>;
10
9
  export declare type __ΩMionRoutes = any[];
@@ -1 +1 @@
1
- {"version":3,"file":"defaultRoutes.js","sources":["../../../src/defaultRoutes.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\n/**\n * Default routes script for AOT cache generation.\n *\n * This script initializes the mion router with only the built-in internal routes\n * (error routes, metadata routes, etc.). It is used by the Vite plugin as a fallback\n * when no user-provided startScript is configured.\n *\n * When run with MION_COMPILE=buildOnly, the router's emitAOTCaches() will automatically\n * collect and send the serialized caches for these internal routes via IPC.\n *\n * Internal routes included:\n * - @thrownErrors: Error serialization route\n * - mion@notFound: Not-found handler\n * - mion@platformError: Platform error handler\n * - mion@methodsMetadataById: Remote methods metadata by ID\n * - mion@methodsMetadataByPath: Remote methods metadata by path\n */\n\nimport {middleFn, initMionRouter} from '@mionjs/router';\nimport type {Routes} from '@mionjs/router';\n\nconst routes = {\n // Only required as initMionRouter needs at least one route/middleFn\n 'mion@mionEmptyMiddleFn': middleFn((): void => undefined),\n} satisfies Routes;\n\n// Initialize the router — this registers all internal routes and emits AOT caches\n// skipClientRoutes must be false to ensure metadata routes are included in AOT caches\nexport const defaultApi = initMionRouter(routes, {skipClientRoutes: false});\nexport type DefaultApi = typeof defaultApi;\n"],"names":[],"mappings":";;;;;AA4BA,MAAM,SAAS;AAAA;AAAA,EAEX,0BAA0B,SAAQ,aAAC,MAAY,QAAS,CAAA,IAAA,MAAA,CAAA,CAAA;;AAKrD,MAAM,aAAa,eAAe,QAAQ,EAAC,kBAAkB,OAAM;;"}
1
+ {"version":3,"file":"defaultRoutes.js","sources":["../../../src/defaultRoutes.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\n/**\n * Default routes script for AOT cache generation.\n *\n * This script initializes the mion router with only the built-in internal routes\n * (error routes, metadata routes, etc.). It is used by the Vite plugin as a fallback\n * when no user-provided startScript is configured.\n *\n * When run with MION_COMPILE=buildOnly, the router's emitAOTCaches() will automatically\n * collect and send the serialized caches for these internal routes via IPC.\n *\n * Internal routes included:\n * - @thrownErrors: Error serialization route\n * - mion@notFound: Not-found handler\n * - mion@platformError: Platform error handler\n * - mion@methodsMetadataById: Remote methods metadata by ID\n * - mion@methodsMetadata: Methods metadata middleware (returns metadata alongside any route response)\n */\n\nimport {middleFn, initMionRouter} from '@mionjs/router';\nimport type {Routes} from '@mionjs/router';\n\nconst routes = {\n // Only required as initMionRouter needs at least one route/middleFn\n 'mion@mionEmptyMiddleFn': middleFn((): void => undefined),\n} satisfies Routes;\n\n// Initialize the router — this registers all internal routes and emits AOT caches\n// skipClientRoutes must be false to ensure metadata routes are included in AOT caches\nexport const defaultApi = initMionRouter(routes, {skipClientRoutes: false});\nexport type DefaultApi = typeof defaultApi;\n"],"names":[],"mappings":";;;;;AA4BA,MAAM,SAAS;AAAA;AAAA,EAEX,0BAA0B,SAAQ,aAAC,MAAY,QAAS,CAAA,IAAA,MAAA,CAAA,CAAA;;AAKrD,MAAM,aAAa,eAAe,QAAQ,EAAC,kBAAkB,OAAM;;"}
@@ -1,4 +1,4 @@
1
- import { JIT_FUNCTION_IDS, isMionAOTEmitMode, getENV, getJitFnCaches, __ΩSrcCodeJITCompiledFnsCache as ___SrcCodeJITCompiledFnsCache, __ΩSrcCodePureFunctionsCache as ___SrcCodePureFunctionsCache, __ΩMethodsCache as ___MethodsCache, __ΩJitFunctionsCache as ___JitFunctionsCache, __ΩPureFunctionsCache as ___PureFunctionsCache } from "@mionjs/core";
1
+ import { JIT_FUNCTION_IDS, isMionAOTEmitMode, getENV, getJitFnCaches, __ΩClientSrcCodeJITCompiledFnsCache as ___ClientSrcCodeJITCompiledFnsCache, __ΩSrcCodeJITCompiledFnsCache as ___SrcCodeJITCompiledFnsCache, __ΩClientSrcCodePureFunctionsCache as ___ClientSrcCodePureFunctionsCache, __ΩSrcCodePureFunctionsCache as ___SrcCodePureFunctionsCache, __ΩMethodsCache as ___MethodsCache, __ΩJitFunctionsCache as ___JitFunctionsCache, __ΩPureFunctionsCache as ___PureFunctionsCache } from "@mionjs/core";
2
2
  import { getPersistedMethods } from "./methodsCache.js";
3
3
  import { createToJavascriptFn } from "@mionjs/run-types";
4
4
  const __ΩRecord = ["K", "T", "Record", `l'e#"Rb!b"Pde"!N#!w#y`];
@@ -35,8 +35,9 @@ async function emitAOTCaches() {
35
35
  }
36
36
  emitAOTCaches.__type = ["emitAOTCaches", "P$`/!"];
37
37
  async function serializeCachesToCode(jitFnsCache, pureFnsCache, routerCache) {
38
- const jitToJSCode = (createToJavascriptFn.Ω = [[() => ___SrcCodeJITCompiledFnsCache, "n!"]], createToJavascriptFn());
39
- const pureToJSCode = (createToJavascriptFn.Ω = [[() => ___SrcCodePureFunctionsCache, "n!"]], createToJavascriptFn());
38
+ const isClient = getENV("MION_AOT_IS_CLIENT") === "true";
39
+ const jitToJSCode = isClient ? (createToJavascriptFn.Ω = [[() => ___ClientSrcCodeJITCompiledFnsCache, "n!"]], createToJavascriptFn()) : (createToJavascriptFn.Ω = [[() => ___SrcCodeJITCompiledFnsCache, "n!"]], createToJavascriptFn());
40
+ const pureToJSCode = isClient ? (createToJavascriptFn.Ω = [[() => ___ClientSrcCodePureFunctionsCache, "n!"]], createToJavascriptFn()) : (createToJavascriptFn.Ω = [[() => ___SrcCodePureFunctionsCache, "n!"]], createToJavascriptFn());
40
41
  const routerToJSCode = (createToJavascriptFn.Ω = [[() => ___MethodsCache, "n!"]], createToJavascriptFn());
41
42
  const finalJitFns = filterExcludedJitFns(jitFnsCache, EXCLUDED_JIT_FN_IDS);
42
43
  const finalPureFns = filterExcludedPureFns(pureFnsCache, EXCLUDED_PURE_FN_NAMES);
@@ -1 +1 @@
1
- {"version":3,"file":"aotEmitter.js","sources":["../../../../src/lib/aotEmitter.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 {\n getJitFnCaches,\n getENV,\n isMionAOTEmitMode,\n JitFunctionsCache,\n PureFunctionsCache,\n MethodsCache,\n SrcCodeJITCompiledFnsCache,\n SrcCodePureFunctionsCache,\n JIT_FUNCTION_IDS,\n} from '@mionjs/core';\nimport {getPersistedMethods} from './methodsCache.ts';\nimport {createToJavascriptFn} from '@mionjs/run-types';\n\n/** IPC message type for AOT cache emission */\nexport interface AOTCacheMessage {\n type: 'mion-aot-caches';\n jitFnsCode: string;\n pureFnsCode: string;\n routerCacheCode: string;\n}\n\n/** IPC message sent by setPlatformConfig() to signal server readiness */\nexport interface PlatformReadyMessage {\n type: 'mion-platform-ready';\n routerConfig: Record<string, unknown>;\n platformConfig: Record<string, unknown>;\n}\n\n/** Serialized cache data before converting to JS code */\nexport interface SerializedCaches {\n jitFnsCode: string;\n pureFnsCode: string;\n routerCacheCode: string;\n}\n\n/** JIT function IDs to exclude from AOT caches (toJSCode is only needed at compile time) */\nconst EXCLUDED_JIT_FN_IDS = [JIT_FUNCTION_IDS.toJSCode];\n\n/** Pure function names to exclude from AOT caches */\nconst EXCLUDED_PURE_FN_NAMES = ['sanitizeCompiledFn'];\n\n/** Returns serialized caches for in-process AOT generation (no IPC needed). Call after initMionRouter(). */\nexport async function getSerializedCaches(): Promise<SerializedCaches> {\n const {jitFnsCache, pureFnsCache} = getJitFnCaches();\n const routerCache = getPersistedMethods();\n return serializeCachesToCode(jitFnsCache, pureFnsCache, routerCache);\n}\n\n/**\n * Emits AOT caches to the parent process via IPC when running in MION_COMPILE mode.\n * This function is called automatically at the end of initMionRouter() and can also\n * be called manually for multi-step route registration patterns.\n */\nexport async function emitAOTCaches(): Promise<void> {\n // Only emit in AOT generation mode (compile, SSR, or serve)\n if (!isMionAOTEmitMode()) return;\n // middleware mode: caches remain in global state, read directly via getSerializedCaches()\n if (getENV('MION_COMPILE') === 'middleware') return;\n\n // IPC mode: send to parent process\n if (typeof process.send !== 'function') return;\n\n // Get the caches\n const {jitFnsCache, pureFnsCache} = getJitFnCaches();\n const routerCache = getPersistedMethods();\n\n // Serialize caches to JS code (filtering happens inside, after createToJavascriptFn)\n const serialized = await serializeCachesToCode(jitFnsCache, pureFnsCache, routerCache);\n\n // Send to parent process\n const message: AOTCacheMessage = {\n type: 'mion-aot-caches',\n ...serialized,\n };\n\n process.send(message);\n}\n\n/**\n * Serializes the caches to JavaScript code strings using run-types toJSCode.\n * Filtering is done AFTER createToJavascriptFn because it adds compile-time-only JIT functions\n * to the global caches that should be excluded from the serialized output.\n */\nexport async function serializeCachesToCode(\n jitFnsCache: JitFunctionsCache,\n pureFnsCache: PureFunctionsCache,\n routerCache: MethodsCache\n): Promise<SerializedCaches> {\n const jitToJSCode = createToJavascriptFn<SrcCodeJITCompiledFnsCache>();\n const pureToJSCode = createToJavascriptFn<SrcCodePureFunctionsCache>();\n const routerToJSCode = createToJavascriptFn<MethodsCache>();\n // Filter AFTER createToJavascriptFn to exclude compile-time-only items (including those just added)\n const finalJitFns = filterExcludedJitFns(jitFnsCache, EXCLUDED_JIT_FN_IDS);\n const finalPureFns = filterExcludedPureFns(pureFnsCache, EXCLUDED_PURE_FN_NAMES);\n return {\n jitFnsCode: jitToJSCode(finalJitFns as unknown as SrcCodeJITCompiledFnsCache),\n pureFnsCode: pureToJSCode(finalPureFns as unknown as SrcCodePureFunctionsCache),\n routerCacheCode: routerToJSCode(routerCache),\n };\n}\n\n/**\n * Filters out excluded JIT functions by their function ID.\n * toJSCode is excluded because it's only needed at compile time.\n */\nfunction filterExcludedJitFns(jitFnsCache: JitFunctionsCache, excludedFnIds: string[]): JitFunctionsCache {\n if (!excludedFnIds.length) return jitFnsCache;\n return Object.fromEntries(\n Object.entries(jitFnsCache).filter(([, value]) => !excludedFnIds.includes(value.fnID as string))\n ) as JitFunctionsCache;\n}\n\n/**\n * Filters out excluded pure functions by their function name.\n * sanitizeCompiledFn is excluded because it's only needed at compile time.\n */\nfunction filterExcludedPureFns(pureFnsCache: PureFunctionsCache, excludedFnNames: string[]): PureFunctionsCache {\n if (!excludedFnNames.length) return pureFnsCache;\n return Object.fromEntries(\n Object.entries(pureFnsCache).map(([namespace, nsCache]) => [\n namespace,\n Object.fromEntries(Object.entries(nsCache).filter(([, value]) => !excludedFnNames.includes(value.fnName))),\n ])\n ) as PureFunctionsCache;\n}\n"],"names":[],"mappings":";;;;;;;;;;;AA4CA,MAAM,sBAAsB,CAAC,iBAAiB,QAAQ;AAGtD,MAAM,yBAAyB,CAAC,oBAAoB;AAGpD,eAAsB,sBAAmB;AACrC,QAAM,EAAC,aAAa,aAAA,IAAgB,eAAA;AACpC,QAAM,cAAc,oBAAA;AACpB,SAAO,sBAAsB,aAAa,cAAc,WAAW;AACvE;;AAOA,eAAsB,gBAAa;AAE/B,MAAI,CAAC,kBAAA;AAAqB;AAE1B,MAAI,OAAO,cAAc,MAAM;AAAc;AAG7C,MAAI,OAAO,QAAQ,SAAS;AAAY;AAGxC,QAAM,EAAC,aAAa,aAAA,IAAgB,eAAA;AACpC,QAAM,cAAc,oBAAA;AAGpB,QAAM,aAAa,MAAM,sBAAsB,aAAa,cAAc,WAAW;AAGrF,QAAM,UAA2B;AAAA,IAC7B,MAAM;AAAA,IACN,GAAG;AAAA,EAAA;AAGP,UAAQ,KAAK,OAAO;AACxB;;AAOA,eAAsB,sBAClB,aACA,cACA,aAAyB;AAEzB,QAAM,eAAc,wEAAA;AACpB,QAAM,gBAAe,uEAAA;AACrB,QAAM,kBAAiB,0DAAA;AAEvB,QAAM,cAAc,qBAAqB,aAAa,mBAAmB;AACzE,QAAM,eAAe,sBAAsB,cAAc,sBAAsB;AAC/E,SAAO;AAAA,IACH,YAAY,YAAY,WAAoD;AAAA,IAC5E,aAAa,aAAa,YAAoD;AAAA,IAC9E,iBAAiB,eAAe,WAAW;AAAA,EAAA;AAEnD;;AAMA,SAAS,qBAAqB,aAAgC,eAAuB;AACjF,MAAI,CAAC,cAAc;AAAQ,WAAO;AAClC,SAAO,OAAO,YACV,OAAO,QAAQ,WAAW,EAAE,OAAM,aAAC,CAAC,GAAG,KAAK,MAAM,CAAC,cAAc,SAAS,MAAM,IAAc,GAAC,CAAA,UAAA,IAAA,SAAA,CAAA,CAAA,CAAC;AAExG;;AAMA,SAAS,sBAAsB,cAAkC,iBAAyB;AACtF,MAAI,CAAC,gBAAgB;AAAQ,WAAO;AACpC,SAAO,OAAO,YACV,OAAO,QAAQ,YAAY,EAAE,IAAG,aAAC,CAAC,CAAC,WAAW,OAAO,MAAM;AAAA,IACvD;AAAA,IACA,OAAO,YAAY,OAAO,QAAQ,OAAO,EAAE,OAAM,aAAC,CAAC,GAAG,KAAK,MAAM,CAAC,gBAAgB,SAAS,MAAM,MAAM,8BAAE;AAAA,EAAA,GAC5G,CAAA,UAAA,IAAA,SAAA,CAAA,CAAA,CAAC;AAEV;;"}
1
+ {"version":3,"file":"aotEmitter.js","sources":["../../../../src/lib/aotEmitter.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 {\n getJitFnCaches,\n getENV,\n isMionAOTEmitMode,\n JitFunctionsCache,\n PureFunctionsCache,\n MethodsCache,\n SrcCodeJITCompiledFnsCache,\n SrcCodePureFunctionsCache,\n ClientSrcCodeJITCompiledFnsCache,\n ClientSrcCodePureFunctionsCache,\n JIT_FUNCTION_IDS,\n} from '@mionjs/core';\nimport {getPersistedMethods} from './methodsCache.ts';\nimport {createToJavascriptFn} from '@mionjs/run-types';\n\n/** IPC message type for AOT cache emission */\nexport interface AOTCacheMessage {\n type: 'mion-aot-caches';\n jitFnsCode: string;\n pureFnsCode: string;\n routerCacheCode: string;\n}\n\n/** IPC message sent by setPlatformConfig() to signal server readiness */\nexport interface PlatformReadyMessage {\n type: 'mion-platform-ready';\n routerConfig: Record<string, unknown>;\n platformConfig: Record<string, unknown>;\n}\n\n/** Serialized cache data before converting to JS code */\nexport interface SerializedCaches {\n jitFnsCode: string;\n pureFnsCode: string;\n routerCacheCode: string;\n}\n\n/** JIT function IDs to exclude from AOT caches (toJSCode is only needed at compile time) */\nconst EXCLUDED_JIT_FN_IDS = [JIT_FUNCTION_IDS.toJSCode];\n\n/** Pure function names to exclude from AOT caches */\nconst EXCLUDED_PURE_FN_NAMES = ['sanitizeCompiledFn'];\n\n/** Returns serialized caches for in-process AOT generation (no IPC needed). Call after initMionRouter(). */\nexport async function getSerializedCaches(): Promise<SerializedCaches> {\n const {jitFnsCache, pureFnsCache} = getJitFnCaches();\n const routerCache = getPersistedMethods();\n return serializeCachesToCode(jitFnsCache, pureFnsCache, routerCache);\n}\n\n/**\n * Emits AOT caches to the parent process via IPC when running in MION_COMPILE mode.\n * This function is called automatically at the end of initMionRouter() and can also\n * be called manually for multi-step route registration patterns.\n */\nexport async function emitAOTCaches(): Promise<void> {\n // Only emit in AOT generation mode (compile, SSR, or serve)\n if (!isMionAOTEmitMode()) return;\n // middleware mode: caches remain in global state, read directly via getSerializedCaches()\n if (getENV('MION_COMPILE') === 'middleware') return;\n\n // IPC mode: send to parent process\n if (typeof process.send !== 'function') return;\n\n // Get the caches\n const {jitFnsCache, pureFnsCache} = getJitFnCaches();\n const routerCache = getPersistedMethods();\n\n // Serialize caches to JS code (filtering happens inside, after createToJavascriptFn)\n const serialized = await serializeCachesToCode(jitFnsCache, pureFnsCache, routerCache);\n\n // Send to parent process\n const message: AOTCacheMessage = {\n type: 'mion-aot-caches',\n ...serialized,\n };\n\n process.send(message);\n}\n\n/**\n * Serializes the caches to JavaScript code strings using run-types toJSCode.\n * Filtering is done AFTER createToJavascriptFn because it adds compile-time-only JIT functions\n * to the global caches that should be excluded from the serialized output.\n */\nexport async function serializeCachesToCode(\n jitFnsCache: JitFunctionsCache,\n pureFnsCache: PureFunctionsCache,\n routerCache: MethodsCache\n): Promise<SerializedCaches> {\n const isClient = getENV('MION_AOT_IS_CLIENT') === 'true';\n const jitToJSCode = isClient\n ? createToJavascriptFn<ClientSrcCodeJITCompiledFnsCache>()\n : createToJavascriptFn<SrcCodeJITCompiledFnsCache>();\n const pureToJSCode = isClient\n ? createToJavascriptFn<ClientSrcCodePureFunctionsCache>()\n : createToJavascriptFn<SrcCodePureFunctionsCache>();\n const routerToJSCode = createToJavascriptFn<MethodsCache>();\n // Filter AFTER createToJavascriptFn to exclude compile-time-only items (including those just added)\n const finalJitFns = filterExcludedJitFns(jitFnsCache, EXCLUDED_JIT_FN_IDS);\n const finalPureFns = filterExcludedPureFns(pureFnsCache, EXCLUDED_PURE_FN_NAMES);\n return {\n jitFnsCode: jitToJSCode(finalJitFns as unknown as SrcCodeJITCompiledFnsCache),\n pureFnsCode: pureToJSCode(finalPureFns as unknown as SrcCodePureFunctionsCache),\n routerCacheCode: routerToJSCode(routerCache),\n };\n}\n\n/**\n * Filters out excluded JIT functions by their function ID.\n * toJSCode is excluded because it's only needed at compile time.\n */\nfunction filterExcludedJitFns(jitFnsCache: JitFunctionsCache, excludedFnIds: string[]): JitFunctionsCache {\n if (!excludedFnIds.length) return jitFnsCache;\n return Object.fromEntries(\n Object.entries(jitFnsCache).filter(([, value]) => !excludedFnIds.includes(value.fnID as string))\n ) as JitFunctionsCache;\n}\n\n/**\n * Filters out excluded pure functions by their function name.\n * sanitizeCompiledFn is excluded because it's only needed at compile time.\n */\nfunction filterExcludedPureFns(pureFnsCache: PureFunctionsCache, excludedFnNames: string[]): PureFunctionsCache {\n if (!excludedFnNames.length) return pureFnsCache;\n return Object.fromEntries(\n Object.entries(pureFnsCache).map(([namespace, nsCache]) => [\n namespace,\n Object.fromEntries(Object.entries(nsCache).filter(([, value]) => !excludedFnNames.includes(value.fnName))),\n ])\n ) as PureFunctionsCache;\n}\n"],"names":["__ΩClientSrcCodeJITCompiledFnsCache","__ΩSrcCodeJITCompiledFnsCache","__ΩClientSrcCodePureFunctionsCache","__ΩSrcCodePureFunctionsCache"],"mappings":";;;;;;;;;;;AA8CA,MAAM,sBAAsB,CAAC,iBAAiB,QAAQ;AAGtD,MAAM,yBAAyB,CAAC,oBAAoB;AAGpD,eAAsB,sBAAmB;AACrC,QAAM,EAAC,aAAa,aAAA,IAAgB,eAAA;AACpC,QAAM,cAAc,oBAAA;AACpB,SAAO,sBAAsB,aAAa,cAAc,WAAW;AACvE;;AAOA,eAAsB,gBAAa;AAE/B,MAAI,CAAC,kBAAA;AAAqB;AAE1B,MAAI,OAAO,cAAc,MAAM;AAAc;AAG7C,MAAI,OAAO,QAAQ,SAAS;AAAY;AAGxC,QAAM,EAAC,aAAa,aAAA,IAAgB,eAAA;AACpC,QAAM,cAAc,oBAAA;AAGpB,QAAM,aAAa,MAAM,sBAAsB,aAAa,cAAc,WAAW;AAGrF,QAAM,UAA2B;AAAA,IAC7B,MAAM;AAAA,IACN,GAAG;AAAA,EAAA;AAGP,UAAQ,KAAK,OAAO;AACxB;;AAOA,eAAsB,sBAClB,aACA,cACA,aAAyB;AAEzB,QAAM,WAAW,OAAO,oBAAoB,MAAM;AAClD,QAAM,cAAc,YACd,qBAAoB,IAAA,CAAA,CAAA,MAAAA,qCAAA,IAAA,CAAA,GAApB,2BACA,qBAAoB,IAAA,CAAA,CAAA,MAAAC,+BAAA,IAAA,CAAA,GAApB;AACN,QAAM,eAAe,YACf,qBAAoB,IAAA,CAAA,CAAA,MAAAC,oCAAA,IAAA,CAAA,GAApB,2BACA,qBAAoB,IAAA,CAAA,CAAA,MAAAC,8BAAA,IAAA,CAAA,GAApB;AACN,QAAM,kBAAiB,0DAAA;AAEvB,QAAM,cAAc,qBAAqB,aAAa,mBAAmB;AACzE,QAAM,eAAe,sBAAsB,cAAc,sBAAsB;AAC/E,SAAO;AAAA,IACH,YAAY,YAAY,WAAoD;AAAA,IAC5E,aAAa,aAAa,YAAoD;AAAA,IAC9E,iBAAiB,eAAe,WAAW;AAAA,EAAA;AAEnD;;AAMA,SAAS,qBAAqB,aAAgC,eAAuB;AACjF,MAAI,CAAC,cAAc;AAAQ,WAAO;AAClC,SAAO,OAAO,YACV,OAAO,QAAQ,WAAW,EAAE,OAAM,aAAC,CAAC,GAAG,KAAK,MAAM,CAAC,cAAc,SAAS,MAAM,IAAc,GAAC,CAAA,UAAA,IAAA,SAAA,CAAA,CAAA,CAAC;AAExG;;AAMA,SAAS,sBAAsB,cAAkC,iBAAyB;AACtF,MAAI,CAAC,gBAAgB;AAAQ,WAAO;AACpC,SAAO,OAAO,YACV,OAAO,QAAQ,YAAY,EAAE,IAAG,aAAC,CAAC,CAAC,WAAW,OAAO,MAAM;AAAA,IACvD;AAAA,IACA,OAAO,YAAY,OAAO,QAAQ,OAAO,EAAE,OAAM,aAAC,CAAC,GAAG,KAAK,MAAM,CAAC,gBAAgB,SAAS,MAAM,MAAM,8BAAE;AAAA,EAAA,GAC5G,CAAA,UAAA,IAAA,SAAA,CAAA,CAAA,CAAC;AAEV;;"}
@@ -1,12 +1,14 @@
1
1
  import { MethodWithJitFns } from '@mionjs/core';
2
2
  import { Handler } from '../types/handlers.ts';
3
3
  import { RouterOptions } from '../types/general.ts';
4
+ import { RouteOptions, MiddleFnOptions, HeadersMiddleFnOptions, MiddleFnMethod, HeadersMethod } from '../types/remoteMethods.ts';
4
5
  type MethodReflect = Omit<MethodWithJitFns, 'id' | 'type' | 'nestLevel' | 'pointer' | 'options'>;
5
6
  export declare class AOTCacheError extends Error {
6
7
  constructor(routeId: string, type?: 'route' | 'middleFn' | 'rawMiddleFn');
7
8
  }
8
9
  export declare function resetRunTypesCache(): void;
9
10
  export declare function resetReflectionCaches(): void;
10
- export declare function getHandlerReflection(handler: Handler, routeId: string, routerOptions: RouterOptions, isHeadersMiddleFn?: boolean, methodStrictTypes?: boolean): Promise<MethodReflect>;
11
+ export declare function getHandlerReflection(handler: Handler, routeId: string, routerOptions: RouterOptions, handlerOptions?: RouteOptions | MiddleFnOptions | HeadersMiddleFnOptions, isHeadersMiddleFn?: boolean, methodStrictTypes?: boolean): Promise<MethodReflect>;
11
12
  export declare function getRawMethodReflection(handler: Handler, routeId: string, routerOptions: RouterOptions): Promise<MethodReflect>;
13
+ export declare function ensureBinaryJitFns(method: MiddleFnMethod | HeadersMethod): Promise<void>;
12
14
  export {};