@mionjs/client 0.13.0 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.dist/esm/src/batch.js +1 -1
- package/.dist/esm/src/batch.js.map +1 -1
- package/.dist/esm/src/client.js +1 -0
- package/.dist/esm/src/client.js.map +1 -1
- package/.dist/esm/src/lib/clientMethodsMetadata.js +1 -1
- package/.dist/esm/src/lib/clientMethodsMetadata.js.map +1 -1
- package/package.json +10 -12
- package/.dist/cjs/index.cjs +0 -1
- package/.dist/cjs/index.d.ts +0 -16
- package/.dist/cjs/middlewares.cjs +0 -1
- package/.dist/cjs/middlewares.d.ts +0 -3
- package/.dist/cjs/package.json +0 -1
- package/.dist/cjs/src/batch.cjs +0 -3
- package/.dist/cjs/src/batch.cjs.map +0 -1
- package/.dist/cjs/src/batch.d.ts +0 -7
- package/.dist/cjs/src/callContext.cjs +0 -3
- package/.dist/cjs/src/callContext.cjs.map +0 -1
- package/.dist/cjs/src/callContext.d.ts +0 -6
- package/.dist/cjs/src/client.cjs +0 -3
- package/.dist/cjs/src/client.cjs.map +0 -1
- package/.dist/cjs/src/client.d.ts +0 -26
- package/.dist/cjs/src/constants.cjs +0 -3
- package/.dist/cjs/src/constants.cjs.map +0 -1
- package/.dist/cjs/src/constants.d.ts +0 -11
- package/.dist/cjs/src/dispatch.cjs +0 -3
- package/.dist/cjs/src/dispatch.cjs.map +0 -1
- package/.dist/cjs/src/dispatch.d.ts +0 -8
- package/.dist/cjs/src/lib/apiBuildVersion.cjs +0 -3
- package/.dist/cjs/src/lib/apiBuildVersion.cjs.map +0 -1
- package/.dist/cjs/src/lib/apiBuildVersion.d.ts +0 -10
- package/.dist/cjs/src/lib/apiVersionRecovery.cjs +0 -3
- package/.dist/cjs/src/lib/apiVersionRecovery.cjs.map +0 -1
- package/.dist/cjs/src/lib/apiVersionRecovery.d.ts +0 -7
- package/.dist/cjs/src/lib/bundledApi.cjs +0 -3
- package/.dist/cjs/src/lib/bundledApi.cjs.map +0 -1
- package/.dist/cjs/src/lib/bundledApi.d.ts +0 -12
- package/.dist/cjs/src/lib/clientMethodsMetadata.cjs +0 -3
- package/.dist/cjs/src/lib/clientMethodsMetadata.cjs.map +0 -1
- package/.dist/cjs/src/lib/clientMethodsMetadata.d.ts +0 -11
- package/.dist/cjs/src/lib/clientResponse.cjs +0 -3
- package/.dist/cjs/src/lib/clientResponse.cjs.map +0 -1
- package/.dist/cjs/src/lib/clientResponse.d.ts +0 -9
- package/.dist/cjs/src/lib/fetchRemoteMethodsMetadata.cjs +0 -3
- package/.dist/cjs/src/lib/fetchRemoteMethodsMetadata.cjs.map +0 -1
- package/.dist/cjs/src/lib/fetchRemoteMethodsMetadata.d.ts +0 -3
- package/.dist/cjs/src/lib/handlersRegistry.cjs +0 -3
- package/.dist/cjs/src/lib/handlersRegistry.cjs.map +0 -1
- package/.dist/cjs/src/lib/handlersRegistry.d.ts +0 -28
- package/.dist/cjs/src/lib/headers.cjs +0 -3
- package/.dist/cjs/src/lib/headers.cjs.map +0 -1
- package/.dist/cjs/src/lib/headers.d.ts +0 -7
- package/.dist/cjs/src/lib/metadataEviction.cjs +0 -3
- package/.dist/cjs/src/lib/metadataEviction.cjs.map +0 -1
- package/.dist/cjs/src/lib/metadataEviction.d.ts +0 -9
- package/.dist/cjs/src/lib/metadataFetcher.cjs +0 -3
- package/.dist/cjs/src/lib/metadataFetcher.cjs.map +0 -1
- package/.dist/cjs/src/lib/metadataFetcher.d.ts +0 -29
- package/.dist/cjs/src/lib/metadataFromServer.cjs +0 -1
- package/.dist/cjs/src/lib/metadataFromServer.d.ts +0 -4
- package/.dist/cjs/src/lib/metadataFromServerLoader.cjs +0 -3
- package/.dist/cjs/src/lib/metadataFromServerLoader.cjs.map +0 -1
- package/.dist/cjs/src/lib/metadataFromServerLoader.d.ts +0 -6
- package/.dist/cjs/src/lib/metadataStore.cjs +0 -3
- package/.dist/cjs/src/lib/metadataStore.cjs.map +0 -1
- package/.dist/cjs/src/lib/metadataStore.d.ts +0 -23
- package/.dist/cjs/src/lib/methods.cjs +0 -3
- package/.dist/cjs/src/lib/methods.cjs.map +0 -1
- package/.dist/cjs/src/lib/methods.d.ts +0 -15
- package/.dist/cjs/src/lib/persistentStorage.cjs +0 -3
- package/.dist/cjs/src/lib/persistentStorage.cjs.map +0 -1
- package/.dist/cjs/src/lib/persistentStorage.d.ts +0 -3
- package/.dist/cjs/src/lib/sanitize.cjs +0 -3
- package/.dist/cjs/src/lib/sanitize.cjs.map +0 -1
- package/.dist/cjs/src/lib/sanitize.d.ts +0 -3
- package/.dist/cjs/src/lib/serializer.cjs +0 -3
- package/.dist/cjs/src/lib/serializer.cjs.map +0 -1
- package/.dist/cjs/src/lib/serializer.d.ts +0 -14
- package/.dist/cjs/src/lib/storage.cjs +0 -0
- package/.dist/cjs/src/lib/storage.d.ts +0 -19
- package/.dist/cjs/src/lib/typedEvent.cjs +0 -3
- package/.dist/cjs/src/lib/typedEvent.cjs.map +0 -1
- package/.dist/cjs/src/lib/typedEvent.d.ts +0 -20
- package/.dist/cjs/src/lib/validation.cjs +0 -3
- package/.dist/cjs/src/lib/validation.cjs.map +0 -1
- package/.dist/cjs/src/lib/validation.d.ts +0 -6
- package/.dist/cjs/src/middlewares/fetchMetadata.cjs +0 -3
- package/.dist/cjs/src/middlewares/fetchMetadata.cjs.map +0 -1
- package/.dist/cjs/src/middlewares/fetchMetadata.d.ts +0 -4
- package/.dist/cjs/src/middlewares/syncRoutes.cjs +0 -3
- package/.dist/cjs/src/middlewares/syncRoutes.cjs.map +0 -1
- package/.dist/cjs/src/middlewares/syncRoutes.d.ts +0 -4
- package/.dist/cjs/src/subRequest.cjs +0 -3
- package/.dist/cjs/src/subRequest.cjs.map +0 -1
- package/.dist/cjs/src/subRequest.d.ts +0 -19
- package/.dist/cjs/src/types.cjs +0 -0
- package/.dist/cjs/src/types.d.ts +0 -155
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"dispatch.cjs","names":[],"sources":["../../../src/dispatch.ts"],"sourcesContent":["/* ########\n * 2023 mion\n * Author: Ma-jerez\n * License: MIT\n * The software is provided \"as is\", without warranty of any kind.\n * ######## */\n\nimport type {ResponseBody} from '@mionjs/router';\nimport type {\n BatchResult,\n ClientCallContext,\n ClientOptions,\n MiddlewareContext,\n MiddlewareSubRequest,\n RequestErrors,\n Result,\n RouteSubRequest,\n SubRequest,\n} from './types.ts';\nimport type {HandlersRegistry, RequestHandlerEntry} from './lib/handlersRegistry.ts';\nimport type {RunTypeError} from '@mionjs/core';\nimport {RpcError, isRpcError, MION_ROUTES, toBase64Url, BUILD_VERSION_HEADER, ROUTER_ITEM_SEPARATOR_CHAR} from '@mionjs/core';\nimport {addSubRequest, createCallContext, getRouteIds, getRoutePointers} from './callContext.ts';\nimport {noteServerApiVersion, reportApiVersionMismatch, takeApiVersionError} from './lib/apiBuildVersion.ts';\nimport {getMethod, hasMethod} from './lib/methods.ts';\nimport {getMetadataFetcher, type MetadataCall} from './lib/metadataFetcher.ts';\nimport {getResponseError, validateSubRequests} from './lib/validation.ts';\nimport {sanitizeSubRequests} from './lib/sanitize.ts';\nimport {serializeRequestBody, deserializeResponseBody} from './lib/serializer.ts';\nimport {MAX_GET_URL_LENGTH, CLIENT_REQUEST_ERROR_ID} from './constants.ts';\nimport {extractRequestHeaders, headersToRecord, reconstructHeadersSubsetFromResponse} from './lib/headers.ts';\nimport {addThrownError, deleteResponseValue, getResponseValue, hasResponseValue, setResponseValue} from './lib/clientResponse.ts';\nimport {takeBundledApiError} from '#bundled-api';\n\n/** One call's retry state: it belongs to the dispatch, never to the context onRequest hooks see */\ninterface DispatchState {\n readonly context: ClientCallContext;\n readonly handlersRegistry: HandlersRegistry;\n /** set only when the client set up `useFetchMetadata` */\n readonly metadata: MetadataCall | undefined;\n /** middlewares whose onRequest already ran, so a retry never asks twice */\n readonly askedRequestHandlers: Set<string>;\n /** the current attempt reached fetch, so the server may have run its routes */\n sent: boolean;\n}\n\n// ############# DISPATCH #############\n\nexport async function dispatchCall(\n context: ClientCallContext,\n handlersRegistry: HandlersRegistry\n): Promise<BatchResult<any> | Result<any, any>> {\n const metadata = getMetadataFetcher(handlersRegistry)?.startCall(context);\n const state: DispatchState = {\n context,\n handlersRegistry,\n metadata,\n askedRequestHandlers: new Set<string>(),\n sent: false,\n };\n // a middleware whose hook asked for a retry never gets another one in this call\n const retriedBy = new Set<string>();\n for (;;) {\n let errors: RequestErrors | undefined;\n try {\n await runCall(state);\n } catch (requestErrors: any) {\n errors = requestErrors;\n }\n // before any hook sees the failed attempt: a resend with fresh rows is the metadata's own, not a hook's\n if (metadata && (await resendsForMetadata(state, metadata, errors, retriedBy))) {\n retriedBy.add(metadata.id);\n // keeps what onRequest hooks sent: the params did not change, only how they are written\n resetAttempt(state);\n continue;\n }\n const hooks = await runMiddlewareResponses(state, getMiddlewareSubRequests(context), errors, retriedBy);\n if (!hooks.retryIds.length) return buildResult(state, hooks.errors);\n hooks.retryIds.forEach((id) => retriedBy.add(id));\n resetForMiddlewareRetry(state);\n }\n}\n\n/** Validates params locally without sending anything */\nexport async function dispatchTypeErrors(\n options: ClientOptions,\n subRequests: SubRequest<any>[],\n handlersRegistry?: HandlersRegistry\n): Promise<RunTypeError[]> {\n const context = createCallContext(options);\n subRequests.forEach((subRequest) => addSubRequest(context, subRequest));\n const errors: RequestErrors = new Map();\n try {\n const subRequestIds = Object.keys(context.subRequestList);\n await loadMethodsMetadata(getMetadataFetcher(handlersRegistry)?.startCall(context), subRequestIds);\n sanitizeSubRequests(subRequestIds, context);\n validateSubRequests(subRequestIds, context, errors, false);\n return Object.values(context.subRequestList)\n .map((subRequest) => subRequest.error?.errorData?.typeErrors || [])\n .flat();\n } catch (error: any) {\n onError(context, error, 'Error preparing request', errors);\n return Promise.reject(errors);\n }\n}\n\nasync function runCall(state: DispatchState): Promise<ResponseBody> {\n const {signal} = state.context;\n if (signal?.aborted) {\n const errors: RequestErrors = new Map();\n onError(\n state.context,\n signal.reason ?? new DOMException('This operation was aborted', 'AbortError'),\n 'Request aborted',\n errors\n );\n return Promise.reject(errors);\n }\n return makeCall(state);\n}\n\nasync function makeCall(state: DispatchState, skipOptimistic?: boolean): Promise<ResponseBody> {\n const {context, metadata} = state;\n const {options, signal} = context;\n const errors: RequestErrors = new Map();\n let isOptimistic = false;\n\n try {\n const prepared = await metadata?.prepare(!!skipOptimistic);\n const subRequestIds = prepared?.ids ?? Object.keys(context.subRequestList);\n isOptimistic = !!prepared?.optimistic;\n if (signal?.aborted) {\n onError(context, signal.reason ?? new DOMException('This operation was aborted', 'AbortError'), 'Request aborted', errors);\n return Promise.reject(errors);\n }\n if (isOptimistic) {\n // No chain before metadata, so scope picks the middlewares; a missed one costs the resend, an extra is ignored.\n const running = runRequestHandlers(state, getScopedRequestHandlerIds(state));\n if (running) await running;\n if (signal?.aborted) {\n onError(context, signal.reason, 'Request aborted', errors);\n return Promise.reject(errors);\n }\n metadata?.askRows();\n } else {\n await loadMethodsMetadata(metadata, subRequestIds, signal);\n const chainIds = getChainMiddlewareIds(context, errors);\n if (errors.size) return Promise.reject(errors);\n const beforeHandlers = new Set(Object.keys(context.subRequestList));\n const running = runRequestHandlers(state, chainIds);\n if (running) await running;\n if (signal?.aborted) {\n onError(context, signal.reason, 'Request aborted', errors);\n return Promise.reject(errors);\n }\n const addedIds = Object.keys(context.subRequestList).filter((id) => !beforeHandlers.has(id));\n const allIds = [...subRequestIds, ...addedIds];\n await loadMethodsMetadata(metadata, allIds, signal);\n sanitizeSubRequests(allIds, context);\n validateSubRequests(allIds, context, errors);\n // a validation error is typed, so it sits at its own path like a returned one\n errors.forEach((error, id) => setResponseValue(context.response, id, error));\n if (errors.size) return Promise.reject(errors);\n }\n } catch (error: any) {\n onError(context, error, 'Error preparing request', errors);\n return Promise.reject(errors);\n }\n\n let response: Response;\n try {\n let serialized: ReturnType<typeof serializeRequestBody>;\n try {\n serialized = serializeRequestBody(context, isOptimistic);\n } catch (serializeError) {\n // plain JSON.stringify failed and nothing was sent: fetch the rows first, then send the real encoders\n if (isOptimistic) return makeCall(state, true);\n throw serializeError;\n }\n\n const headersFromParams = extractRequestHeaders(context);\n const url = new URL(context.path, options.baseURL);\n const fetchOptions = buildFetchOptions(\n url,\n serialized,\n headersFromParams,\n options,\n isOptimistic,\n isQueryRoute(context),\n signal\n );\n state.sent = true;\n response = await fetch(url, fetchOptions);\n context.httpResponse = response;\n } catch (error: any) {\n onError(context, error, 'Error executing request', errors);\n return Promise.reject(errors);\n }\n\n try {\n // A body read after an in-flight abort may be truncated, so report the abort instead.\n if (signal?.aborted) {\n onError(context, signal.reason, 'Request aborted', errors);\n return Promise.reject(errors);\n }\n const deserialized = await deserializeResponseBody(response, options, metadata && ((body) => metadata.readRows(body)));\n if (handlePlatformError(context, deserialized, errors)) return Promise.reject(errors);\n // without the metadata middleware the client cannot check routes one by one, so the whole API is reported\n if (noteServerApiVersion(options.baseURL, response.headers.get(BUILD_VERSION_HEADER)) && !metadata)\n reportApiVersionMismatch(options.baseURL);\n addParamlessMiddlewares(context);\n resolveSubRequests(context, deserialized, errors);\n if (errors.size) return Promise.reject(errors);\n return deserialized;\n } catch (error) {\n onError(context, error, 'Error parsing response', errors);\n return Promise.reject(errors);\n }\n}\n\n/** Rows missing for any id: fetched when the client set up metadata fetching, a clear error otherwise. */\nasync function loadMethodsMetadata(metadata: MetadataCall | undefined, methodIds: string[], signal?: AbortSignal): Promise<void> {\n const missing = methodIds.filter((id) => !hasMethod(id));\n if (!missing.length) return;\n if (metadata) return metadata.fetchRows(missing, signal);\n throw new RpcError({\n type: 'route-metadata-not-found',\n publicMessage:\n `No metadata for ${missing.map((id) => `'${id}'`).join(', ')}: the build did not bundle it and the client does not fetch it. ` +\n `Call the route where the build can see it, or set up useFetchMetadata from '@mionjs/client/middlewares'.`,\n });\n}\n\n/** A metadata resend fixes an attempt that failed on the wire, once per call, never re-running a success. */\nasync function resendsForMetadata(\n state: DispatchState,\n metadata: MetadataCall,\n errors: RequestErrors | undefined,\n retriedBy: ReadonlySet<string>\n): Promise<boolean> {\n if (!errors || !state.sent || retriedBy.has(metadata.id)) return false;\n // a storage engine the app supplied can throw, and a call never rejects\n const resend = await metadata.shouldResend(errors).catch(() => false);\n return resend && isRetrySafe(state, errors);\n}\n\n/** A platform error is request-scoped: one entry, not one per subrequest */\nfunction handlePlatformError(context: ClientCallContext, deserialized: ResponseBody, errors: RequestErrors): boolean {\n if (!(MION_ROUTES.platformError in deserialized)) return false;\n const platformError = deserialized[MION_ROUTES.platformError];\n Object.values(context.subRequestList).forEach((methodMeta) => (methodMeta.isResolved = true));\n setThrownError(context, CLIENT_REQUEST_ERROR_ID, platformError as RpcError<string>, errors);\n return true;\n}\n\n/** An untyped error: only `@thrownErrors`, never a typed slot or a listener */\nfunction setThrownError(context: ClientCallContext, id: string, error: RpcError<string>, errors: RequestErrors): void {\n errors.set(id, error);\n context.thrownErrorIds.add(id);\n addThrownError(context.response, error);\n}\n\n/** A middleware with no params gets no onRequest call, yet its answer and declared errors are the caller's */\nfunction addParamlessMiddlewares(context: ClientCallContext): void {\n for (const id of getChainMiddlewareIds(context)) {\n const method = getMethod(id);\n if (context.subRequestList[id] || !method || method.paramsCount || method.headersParam || !method.hasReturnData) continue;\n addSubRequest(context, {pointer: method.pointer, id, isResolved: false, params: []});\n }\n}\n\n/** A thrown validation error is typed, so it moves to its path */\nfunction resolveSubRequests(context: ClientCallContext, deserialized: ResponseBody, errors: RequestErrors): void {\n const {response, subRequestList} = context;\n for (const [id, value] of Object.entries(deserialized)) {\n if (id !== MION_ROUTES.thrownErrors) setResponseValue(response, id, value);\n }\n for (const [id, thrownError] of Object.entries(deserialized[MION_ROUTES.thrownErrors] ?? {})) {\n // a response key is untrusted: only an own entry is one of this request's subrequests\n const subRequest = Object.hasOwn(subRequestList, id) ? subRequestList[id] : undefined;\n if (subRequest) {\n subRequest.isResolved = true;\n subRequest.error = thrownError;\n }\n if (thrownError.type === 'validation-error' && setResponseValue(response, id, thrownError)) errors.set(id, thrownError);\n else setThrownError(context, id, thrownError, errors);\n }\n\n const checkAnswers = context.options.validateServerResponses;\n // the halting brand never travels, so after any error an absent member may never have run\n const mayHaveStopped = checkAnswers && (errors.size > 0 || Object.values(deserialized).some((value) => isRpcError(value)));\n Object.entries(subRequestList).forEach(([id, methodMeta]) => {\n if (errors.has(id)) return;\n // a headers answer proves the member ran, so it is checked like a body one\n const headersSubset = reconstructHeadersSubsetFromResponse(id, (context.httpResponse as Response).headers);\n if (headersSubset) setResponseValue(response, id, headersSubset);\n const resp = headersSubset ?? getResponseValue(response, id);\n methodMeta.isResolved = true;\n if (isRpcError(resp)) {\n methodMeta.error = resp;\n errors.set(id, resp);\n return;\n }\n const responseError =\n checkAnswers && (hasResponseValue(response, id) || !mayHaveStopped) ? getResponseError(id, resp) : undefined;\n if (responseError) {\n methodMeta.error = responseError;\n deleteResponseValue(response, id);\n setThrownError(context, id, responseError, errors);\n } else {\n methodMeta.resolvedValue = resp;\n }\n });\n\n // an error for an id this request never asked for stays at its path; the map only feeds the retry rules\n Object.entries(deserialized).forEach(([id, value]) => {\n if (id === MION_ROUTES.thrownErrors || Object.hasOwn(subRequestList, id)) return;\n if (isRpcError(value)) errors.set(id, value);\n });\n}\n\nfunction onError(context: ClientCallContext, error: any, stageMessage: string, errors: RequestErrors): void {\n // Check signal.reason before the isRpcError return: a later stage may have wrapped the abort as an RpcError.\n const reason = context.signal?.aborted ? context.signal.reason : undefined;\n if (reason instanceof DOMException) {\n if (reason.name === 'TimeoutError') {\n setThrownError(\n context,\n CLIENT_REQUEST_ERROR_ID,\n new RpcError({\n type: 'request-timeout',\n publicMessage: 'Request timed out',\n originalError: error instanceof Error ? error : undefined,\n }),\n errors\n );\n return;\n }\n if (reason.name === 'AbortError') {\n setThrownError(\n context,\n CLIENT_REQUEST_ERROR_ID,\n new RpcError({\n type: 'request-aborted',\n publicMessage: 'Request was aborted',\n originalError: error instanceof Error ? error : undefined,\n }),\n errors\n );\n return;\n }\n }\n if (isRpcError(error)) {\n setThrownError(context, CLIENT_REQUEST_ERROR_ID, error, errors);\n return;\n }\n const message = error?.message ? `${stageMessage}: ${error.message}` : `${stageMessage}: Unknown Error`;\n setThrownError(\n context,\n CLIENT_REQUEST_ERROR_ID,\n new RpcError({\n type: error?.name || 'unknown-error',\n publicMessage: message,\n originalError: error instanceof Error ? error : undefined,\n }),\n errors\n );\n}\n\nfunction isQueryRoute(context: ClientCallContext): boolean {\n if (context.batchSubRequests) return false;\n const meta = getMethod(context.requestId);\n // strict false value required for queries\n return meta?.options?.isMutation === false;\n}\n\n// ############# ON REQUEST HOOKS #############\n\n/** The middlewares the cached metadata lists in the route's chain (standard flow) */\nfunction getChainMiddlewareIds(context: ClientCallContext, errors?: RequestErrors): string[] {\n const routeIds = new Set(getRouteIds(context));\n const chainIds = new Set<string>();\n for (const routeId of routeIds) {\n const methodMeta = getMethod(routeId);\n if (!methodMeta) {\n // without errors (after the answer) a missing row only means no chain to read\n if (errors) {\n setThrownError(\n context,\n routeId,\n new RpcError({\n type: 'route-metadata-not-found',\n publicMessage: `Metadata for Route '${routeId}' not found.`,\n }),\n errors\n );\n }\n continue;\n }\n methodMeta.middlewareIds?.forEach((id) => !!id && !routeIds.has(id) && chainIds.add(id));\n }\n return [...chainIds];\n}\n\n/** Optimistic flow: the chain is not cached yet, but a middleware's group is part of its pointer */\nfunction getScopedRequestHandlerIds(state: DispatchState): string[] {\n const routeIds = new Set(getRouteIds(state.context));\n const routePointers = getRoutePointers(state.context);\n return state.handlersRegistry.getRequestHandlerIds().filter((id) => {\n if (routeIds.has(id)) return false;\n const middlewarePointer = id.split(ROUTER_ITEM_SEPARATOR_CHAR);\n return routePointers.some((routePointer) => isMiddlewareInScope(middlewarePointer, routePointer));\n });\n}\n\n/** Runs each middleware's onRequest once per call, in chain order; awaits only when one returns a promise */\nfunction runRequestHandlers(state: DispatchState, ids: string[]): Promise<void> | void {\n const pending: Promise<void>[] = [];\n for (const id of ids) {\n if (state.context.subRequestList[id] || state.askedRequestHandlers.has(id)) continue;\n const entry = state.handlersRegistry.getRequestHandler(id);\n if (!entry) continue;\n state.askedRequestHandlers.add(id);\n const running = runRequestHandler(state.context, id, entry);\n if (running) pending.push(running);\n }\n if (pending.length) return Promise.all(pending).then(() => undefined);\n}\n\nfunction runRequestHandler(context: ClientCallContext, id: string, entry: RequestHandlerEntry): Promise<void> | void {\n let subRequest: SubRequest<any> | undefined;\n let isOpen = true;\n // the last call wins; a call after the handler finished belongs to no request\n const call = (...params: any[]) => {\n if (isOpen) subRequest = entry.createSubRequest(params);\n };\n const finish = () => {\n isOpen = false;\n if (subRequest) addSubRequest(context, subRequest);\n };\n const fail = (error: unknown): never => {\n isOpen = false;\n throw requestHandlerError(id, error);\n };\n let returned: void | Promise<void>;\n try {\n returned = entry.handler(call, context);\n } catch (error) {\n return fail(error);\n }\n if (!isPromiseLike(returned)) return finish();\n return Promise.resolve(returned).then(finish, fail);\n}\n\nfunction isPromiseLike(value: unknown): value is PromiseLike<unknown> {\n return !!value && typeof (value as PromiseLike<unknown>).then === 'function';\n}\n\n/** The result lands in @thrownErrors */\nfunction requestHandlerError(id: string, error: unknown): RpcError<string> {\n if (isRpcError(error)) return error;\n const message = error instanceof Error ? error.message : String(error);\n return new RpcError({\n type: 'middleware-on-request-failed',\n publicMessage: `onRequest for middleware '${id}' failed: ${message}`,\n originalError: error instanceof Error ? error : undefined,\n });\n}\n\n/** A middleware's scope is its pointer minus the last segment; a route is in scope when its pointer starts with it */\nexport function isMiddlewareInScope(middlewarePointer: string[], routePointer: string[]): boolean {\n const groupDepth = middlewarePointer.length - 1;\n if (groupDepth >= routePointer.length) return false;\n for (let i = 0; i < groupDepth; i++) if (middlewarePointer[i] !== routePointer[i]) return false;\n return true;\n}\n\n// ############# FETCH #############\n\n/** GET only for a JSON query whose URL fits MAX_GET_URL_LENGTH; mutations, optimistic calls and batches POST */\nfunction buildFetchOptions(\n url: URL,\n serialized: ReturnType<typeof serializeRequestBody>,\n headersFromParams: Record<string, string>,\n options: ClientOptions,\n isOptimistic: boolean,\n isQuery: boolean,\n signal?: AbortSignal\n): RequestInit {\n if (!isOptimistic && isQuery && serialized.contentType.includes('json')) {\n const encoded = toBase64Url(serialized.body as string);\n const testUrl = new URL(url.pathname + url.search, url.origin);\n testUrl.searchParams.set('data', encoded);\n\n if (testUrl.toString().length <= MAX_GET_URL_LENGTH) {\n url.searchParams.set('data', encoded);\n return {\n ...options.fetchOptions,\n method: 'GET',\n headers: {...headersToRecord(options.fetchOptions.headers), ...headersFromParams},\n body: undefined,\n signal,\n };\n }\n }\n\n return {\n ...options.fetchOptions,\n method: 'POST',\n headers: {...headersToRecord(options.fetchOptions.headers), ...headersFromParams, 'Content-Type': serialized.contentType},\n body: serialized.body as BodyInit,\n signal,\n };\n}\n\n// ############# RESULT #############\n\nfunction getMiddlewareSubRequests(context: ClientCallContext): MiddlewareSubRequest<any>[] {\n const routeIds = new Set<string>();\n if (context.route) routeIds.add(context.route.id);\n if (context.batchSubRequests) context.batchSubRequests.forEach((sr) => routeIds.add(sr.id));\n return Object.entries(context.subRequestList)\n .filter(([id]) => !routeIds.has(id))\n .map(([, subRequest]) => subRequest as MiddlewareSubRequest<any>);\n}\n\ninterface MiddlewareResponsesOutcome {\n errors: RequestErrors | undefined;\n /** middlewares whose hook asked for a retry that was allowed */\n retryIds: string[];\n}\n\n/** onError fires only for declared (returned) errors; thrown ones reach @thrownErrors only */\nasync function runMiddlewareResponses(\n state: DispatchState,\n middlewareSubRequests: MiddlewareSubRequest<any>[],\n errors: RequestErrors | undefined,\n retriedBy: ReadonlySet<string>\n): Promise<MiddlewareResponsesOutcome> {\n const {context, handlersRegistry} = state;\n const retryIds: string[] = [];\n const pending: Promise<void>[] = [];\n let retrySafe: boolean | undefined;\n /** Records the retry and says whether it will happen; the rule is worked out once per attempt */\n const requestRetry = (id: string): boolean => {\n if (retriedBy.has(id)) return false;\n retrySafe ??= isRetrySafe(state, errors);\n if (!retrySafe) return false;\n if (!retryIds.includes(id)) retryIds.push(id);\n return true;\n };\n // every middleware gets this context, with its own retry\n const baseContext: MiddlewareContext = {\n route: context.route,\n batchSubRequests: context.batchSubRequests,\n subRequestList: context.subRequestList,\n options: context.options,\n signal: context.signal,\n retry: () => false,\n };\n for (const middleware of middlewareSubRequests) {\n const id = middleware.id;\n const middlewareError = errors?.get(id);\n const isErrorHandler = !!middlewareError;\n if (isErrorHandler && context.thrownErrorIds.has(id)) continue;\n if (!isErrorHandler && middleware.resolvedValue === undefined) continue;\n const handlerName = isErrorHandler ? 'onError' : 'onResponse';\n const handlers = isErrorHandler\n ? handlersRegistry.getErrorHandlers(id, middlewareError.type)\n : handlersRegistry.getResponseHandlers(id);\n // a failing handler does not stop the rest\n for (const handler of handlers) {\n // a retry asked after the handler finished belongs to no attempt\n let isOpen = true;\n const middlewareContext: MiddlewareContext = {...baseContext, retry: () => isOpen && requestRetry(id)};\n const fail = (error: unknown) => {\n isOpen = false;\n errors ??= new Map();\n setThrownError(context, CLIENT_REQUEST_ERROR_ID, middlewareHandlerError(handlerName, id, error), errors);\n };\n let returned: unknown;\n try {\n returned = isErrorHandler\n ? handler(middlewareError, middlewareContext)\n : handler(middleware.resolvedValue, middlewareContext);\n } catch (error) {\n fail(error);\n continue;\n }\n if (!isPromiseLike(returned)) {\n isOpen = false;\n continue;\n }\n pending.push(\n Promise.resolve(returned).then(\n () => {\n isOpen = false;\n },\n (error) => fail(error)\n )\n );\n }\n }\n if (pending.length) await Promise.all(pending);\n // a failed handler ends the call: its error is the answer, not a resend\n if (errors?.has(CLIENT_REQUEST_ERROR_ID) && retryIds.length) retryIds.length = 0;\n return {errors, retryIds};\n}\n\n/** Safe when nothing was sent, or when every route is a query or did not succeed */\nfunction isRetrySafe(state: DispatchState, errors: RequestErrors | undefined): boolean {\n if (!state.sent) return true;\n return getRouteIds(state.context).every(\n (id) => getMethod(id)?.options?.isMutation === false || !routeSucceeded(state.context, id, errors)\n );\n}\n\n/** A void route answers nothing, so any error in the response counts it as failed */\nexport function routeSucceeded(context: ClientCallContext, routeId: string, errors: RequestErrors | undefined): boolean {\n const errorType = errors?.get(routeId)?.type;\n // the handler ran: its answer was refused, or the headers it built failed their check\n if (errorType === 'response-validation-error' || errorType === 'headers-validation-error') return true;\n if (errors?.has(routeId)) return false;\n if (context.subRequestList[routeId]?.resolvedValue !== undefined) return true;\n return !errors?.size;\n}\n\n/** Hook-driven retries ask every onRequest again: a hook usually retries because what it sends changed */\nfunction resetForMiddlewareRetry(state: DispatchState): void {\n const {context} = state;\n const routeIds = new Set(getRouteIds(context));\n for (const id of Object.keys(context.subRequestList)) {\n if (!routeIds.has(id)) delete context.subRequestList[id];\n }\n state.askedRequestHandlers.clear();\n resetAttempt(state);\n}\n\nfunction resetAttempt(state: DispatchState): void {\n const {context} = state;\n Object.values(context.subRequestList).forEach((subRequest) => {\n subRequest.isResolved = false;\n subRequest.resolvedValue = undefined;\n subRequest.error = undefined;\n });\n context.thrownErrorIds.clear();\n context.httpResponse = undefined;\n context.response = {};\n state.sent = false;\n}\n\n/** The result lands in @thrownErrors */\nfunction middlewareHandlerError(handlerName: 'onResponse' | 'onError', id: string, error: unknown): RpcError<string> {\n if (isRpcError(error)) return error;\n const message = error instanceof Error ? error.message : String(error);\n return new RpcError({\n type: handlerName === 'onError' ? 'middleware-on-error-failed' : 'middleware-on-response-failed',\n publicMessage: `${handlerName} for middleware '${id}' failed: ${message}`,\n originalError: error instanceof Error ? error : undefined,\n });\n}\n\n/** Slot rules are pinned in test/errorDispatch.spec.ts */\nfunction buildResult(\n state: DispatchState,\n errors: RequestErrors | undefined\n): BatchResult<RouteSubRequest<any>[]> | Result<any, any> {\n const {route: routeSubRequest, batchSubRequests, thrownErrorIds, response} = state.context;\n const declaredErrorFor = (id: string): RpcError<string> | undefined => {\n const error = errors?.get(id);\n return error && !thrownErrorIds.has(id) ? error : undefined;\n };\n\n // framework errors the router never saw: the call ran, so they are reported here rather than rejecting\n const frameworkErrors = [takeBundledApiError(), takeApiVersionError(), state.metadata?.takeError()];\n frameworkErrors.forEach((error) => error && addThrownError(response, error));\n\n // every batch entry is a call() Result sharing the same response\n if (batchSubRequests)\n return batchSubRequests.map(\n (batchRoute): Result<any, any> => [batchRoute.resolvedValue, declaredErrorFor(batchRoute.id), response]\n );\n return [routeSubRequest?.resolvedValue, routeSubRequest && declaredErrorFor(routeSubRequest.id), response];\n}\n"],"mappings":"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"}
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { BatchResult, ClientCallContext, ClientOptions, RequestErrors, Result, SubRequest } from './types.ts';
|
|
2
|
-
import { HandlersRegistry } from './lib/handlersRegistry.ts';
|
|
3
|
-
import { RunTypeError } from '@mionjs/core';
|
|
4
|
-
export declare function dispatchCall(context: ClientCallContext, handlersRegistry: HandlersRegistry): Promise<BatchResult<any> | Result<any, any>>;
|
|
5
|
-
export declare function dispatchTypeErrors(options: ClientOptions, subRequests: SubRequest<any>[], handlersRegistry?: HandlersRegistry): Promise<RunTypeError[]>;
|
|
6
|
-
export declare function isMiddlewareInScope(middlewarePointer: string[], routePointer: string[]): boolean;
|
|
7
|
-
export declare function routeSucceeded(context: ClientCallContext, routeId: string, errors: RequestErrors | undefined): boolean;
|
|
8
|
-
//# sourceMappingURL=dispatch.d.ts.map
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});let _mionjs_core=require("@mionjs/core");var apiBuildVersion,mismatchedServers=new Set,mismatchError;function setApiBuildVersion(version){apiBuildVersion=version||void 0}function getApiBuildVersion(){return apiBuildVersion}function noteServerApiVersion(baseURL,serverVersion){return!serverVersion||!apiBuildVersion||serverVersion===apiBuildVersion?!1:(mismatchedServers.add(baseURL),!0)}function hasApiVersionMismatch(baseURL){return mismatchedServers.has(baseURL)}var reportedServers=new Set;function reportApiVersionMismatch(baseURL){reportedServers.has(baseURL)||(reportedServers.add(baseURL),mismatchError=new _mionjs_core.RpcError({type:"api-version-mismatch",publicMessage:`The server at ${baseURL||"this origin"} runs a different build of the API than this client was built against. Reload the app or rebuild the client against the current API.`}))}function stashApiVersionError(error){mismatchError=error}function takeApiVersionError(){const error=mismatchError;return mismatchError=void 0,error}function resetApiBuildVersion(){apiBuildVersion=void 0,mismatchedServers.clear(),reportedServers.clear(),mismatchError=void 0}exports.getApiBuildVersion=getApiBuildVersion;exports.hasApiVersionMismatch=hasApiVersionMismatch;exports.noteServerApiVersion=noteServerApiVersion;exports.reportApiVersionMismatch=reportApiVersionMismatch;exports.resetApiBuildVersion=resetApiBuildVersion;exports.setApiBuildVersion=setApiBuildVersion;exports.stashApiVersionError=stashApiVersionError;exports.takeApiVersionError=takeApiVersionError;
|
|
2
|
-
|
|
3
|
-
//# sourceMappingURL=apiBuildVersion.cjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"apiBuildVersion.cjs","names":[],"sources":["../../../../src/lib/apiBuildVersion.ts"],"sourcesContent":["/* ########\n * 2026 mion\n * Author: Ma-jerez\n * License: MIT\n * The software is provided \"as is\", without warranty of any kind.\n * ######## */\n\n// The version check rides every response, so it cannot be lazily loaded; what a mismatch then does lives in\n// apiVersionRecovery.ts, behind `#metadata-from-server`. Split from client.ts: request.ts\n// must not pull the client in. One build version per program, one mismatch per server.\n\nimport {RpcError} from '@mionjs/core';\n\n/** The API version this client was built against, injected at `initClient` by the build. */\nlet apiBuildVersion: string | undefined;\n/** baseURLs that answered with a version other than this build's. */\nconst mismatchedServers = new Set<string>();\nlet mismatchError: RpcError<'api-version-mismatch'> | undefined;\n\n/** Called by generated code, never by hand: the value comes from the API's types. */\nexport function setApiBuildVersion(version: string | undefined): void {\n apiBuildVersion = version || undefined;\n}\n\nexport function getApiBuildVersion(): string | undefined {\n return apiBuildVersion;\n}\n\n/** A missing version on either side answers false: an end with no version knows too little to call it a mismatch. */\nexport function noteServerApiVersion(baseURL: string, serverVersion: string | undefined | null): boolean {\n if (!serverVersion || !apiBuildVersion || serverVersion === apiBuildVersion) return false;\n mismatchedServers.add(baseURL);\n return true;\n}\n\n/** Whether the recovery module is worth loading: nothing else in this file reaches it. */\nexport function hasApiVersionMismatch(baseURL: string): boolean {\n return mismatchedServers.has(baseURL);\n}\n\n/** baseURLs whose mismatch was already reported for the whole API. */\nconst reportedServers = new Set<string>();\n\n/** Without the metadata middleware no route can be checked alone, so the whole API is reported, once per server. */\nexport function reportApiVersionMismatch(baseURL: string): void {\n if (reportedServers.has(baseURL)) return;\n reportedServers.add(baseURL);\n mismatchError = new RpcError({\n type: 'api-version-mismatch',\n publicMessage:\n `The server at ${baseURL || 'this origin'} runs a different build of the API than this client was built against. ` +\n `Reload the app or rebuild the client against the current API.`,\n });\n}\n\n/** Held for the next call's @thrownErrors, beside the bundled-API error: the call itself ran. */\nexport function stashApiVersionError(error: RpcError<'api-version-mismatch'>): void {\n mismatchError = error;\n}\n\n/** The mismatch error, reported once. */\nexport function takeApiVersionError(): RpcError<'api-version-mismatch'> | undefined {\n const error = mismatchError;\n mismatchError = undefined;\n return error;\n}\n\n/** Tests only: forgets the injected version and the mismatch. */\nexport function resetApiBuildVersion(): void {\n apiBuildVersion = undefined;\n mismatchedServers.clear();\n reportedServers.clear();\n mismatchError = undefined;\n}\n"],"mappings":"4GAcA,IAAI,gBAEE,kBAAoB,IAAI,IAC1B,cAGJ,SAAgB,mBAAmB,QAAmC,CACpE,gBAAkB,SAAW,MAC/B,CAEA,SAAgB,oBAAyC,CACvD,OAAO,eACT,CAGA,SAAgB,qBAAqB,QAAiB,cAAmD,CACvG,MAAI,CAAC,eAAiB,CAAC,iBAAmB,gBAAkB,gBAAwB,IACpF,kBAAkB,IAAI,OAAO,EACtB,GACT,CAGA,SAAgB,sBAAsB,QAA0B,CAC9D,OAAO,kBAAkB,IAAI,OAAO,CACtC,CAGA,IAAM,gBAAkB,IAAI,IAG5B,SAAgB,yBAAyB,QAAuB,CAC1D,gBAAgB,IAAI,OAAO,IAC/B,gBAAgB,IAAI,OAAO,EAC3B,cAAgB,IAAI,aAAA,SAAS,CAC3B,KAAM,uBACN,cACE,iBAAiB,SAAW,aAAA,sIAEhC,CAAC,EACH,CAGA,SAAgB,qBAAqB,MAA+C,CAClF,cAAgB,KAClB,CAGA,SAAgB,qBAAoE,CAClF,MAAM,MAAQ,cACd,qBAAgB,OACT,KACT,CAGA,SAAgB,sBAA6B,CAC3C,gBAAkB,OAClB,kBAAkB,MAAM,EACxB,gBAAgB,MAAM,EACtB,cAAgB,MAClB"}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { RpcError } from '@mionjs/core';
|
|
2
|
-
export declare function setApiBuildVersion(version: string | undefined): void;
|
|
3
|
-
export declare function getApiBuildVersion(): string | undefined;
|
|
4
|
-
export declare function noteServerApiVersion(baseURL: string, serverVersion: string | undefined | null): boolean;
|
|
5
|
-
export declare function hasApiVersionMismatch(baseURL: string): boolean;
|
|
6
|
-
export declare function reportApiVersionMismatch(baseURL: string): void;
|
|
7
|
-
export declare function stashApiVersionError(error: RpcError<'api-version-mismatch'>): void;
|
|
8
|
-
export declare function takeApiVersionError(): RpcError<'api-version-mismatch'> | undefined;
|
|
9
|
-
export declare function resetApiBuildVersion(): void;
|
|
10
|
-
//# sourceMappingURL=apiBuildVersion.d.ts.map
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const require_src_lib_methods=require("./methods.cjs"),require_src_lib_clientMethodsMetadata=require("./clientMethodsMetadata.cjs"),require_src_lib_apiBuildVersion=require("./apiBuildVersion.cjs");let _mionjs_core=require("@mionjs/core");var verifiedIds=new Map;function verifiedBy(baseURL){let ids=verifiedIds.get(baseURL);return ids||verifiedIds.set(baseURL,ids=new Set),ids}function unverifiedIds(baseURL,ids){const verified=verifiedBy(baseURL);return ids.filter(id=>!verified.has(id))}function resetApiVersionRecovery(){verifiedIds.clear()}function verifyMethodRows(options,asked,data){const verified=verifiedBy(options.baseURL);for(const id of asked)verified.add(id);const stale=asked.filter(id=>!rowsAgree(require_src_lib_methods.getMethod(id),data.methods[id]));if(!stale.length)return;const fetched=stale.filter(id=>!require_src_lib_methods.isBundledMethod(id));fetched.length&&require_src_lib_clientMethodsMetadata.installMethodRows(data,options,fetched);const bundled=stale.filter(id=>require_src_lib_methods.isBundledMethod(id));bundled.length&&require_src_lib_apiBuildVersion.stashApiVersionError(staleRoutesError(bundled))}function rowsAgree(held,served){return!!held?.syncId&&held.syncId===served?.syncId}function staleRoutesError(stale){return new _mionjs_core.RpcError({type:"api-version-mismatch",publicMessage:`This mion client carries routes compiled against an older version of the API: the server answers with a different build version, and ${stale.map(id=>`"${id}"`).join(", ")} no longer matches what it declares. Reload the app or rebuild the client against the current API.`})}exports.resetApiVersionRecovery=resetApiVersionRecovery;exports.rowsAgree=rowsAgree;exports.unverifiedIds=unverifiedIds;exports.verifyMethodRows=verifyMethodRows;
|
|
2
|
-
|
|
3
|
-
//# sourceMappingURL=apiVersionRecovery.cjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"apiVersionRecovery.cjs","names":[],"sources":["../../../../src/lib/apiVersionRecovery.ts"],"sourcesContent":["/* ########\n * 2026 mion\n * Author: Ma-jerez\n * License: MIT\n * The software is provided \"as is\", without warranty of any kind.\n * ######## */\n\n// Rides the `#metadata-from-server` chunk: like the fetch, it runs only when the bundle comes up short.\n\nimport {RpcError} from '@mionjs/core';\nimport type {MethodWithOptions, SerializableMethodsData} from '@mionjs/core';\nimport type {ClientOptions} from '../types.ts';\nimport {stashApiVersionError} from './apiBuildVersion.ts';\nimport {getMethod, isBundledMethod} from './methods.ts';\nimport {installMethodRows} from './clientMethodsMetadata.ts';\n\n/** Ids each baseURL confirmed: a route is checked once per server, on its first use after the mismatch. */\nconst verifiedIds = new Map<string, Set<string>>();\n\nfunction verifiedBy(baseURL: string): Set<string> {\n let ids = verifiedIds.get(baseURL);\n if (!ids) verifiedIds.set(baseURL, (ids = new Set()));\n return ids;\n}\n\n/** The ids to ask the server to confirm, out of the ones this request calls. */\nexport function unverifiedIds(baseURL: string, ids: string[]): string[] {\n const verified = verifiedBy(baseURL);\n return ids.filter((id) => !verified.has(id));\n}\n\n/** Tests only: forgets which routes were confirmed. */\nexport function resetApiVersionRecovery(): void {\n verifiedIds.clear();\n}\n\n/** A fetched row is a cache: replaced and saved. A bundled one is what the calling code was built against: reported. */\nexport function verifyMethodRows(options: ClientOptions, asked: string[], data: SerializableMethodsData): void {\n const verified = verifiedBy(options.baseURL);\n for (const id of asked) verified.add(id);\n // Only the asked ids: comparing the middleware riding along would report a route this call never uses.\n const stale = asked.filter((id) => !rowsAgree(getMethod(id), data.methods[id] as MethodWithOptions | undefined));\n if (!stale.length) return;\n const fetched = stale.filter((id) => !isBundledMethod(id));\n if (fetched.length) installMethodRows(data, options, fetched);\n const bundled = stale.filter((id) => isBundledMethod(id));\n if (bundled.length) stashApiVersionError(staleRoutesError(bundled));\n}\n\n/** Sync id only: it covers the types and wire formats; a row or id missing on either end never agrees. */\nexport function rowsAgree(held: MethodWithOptions | undefined, served: MethodWithOptions | undefined): boolean {\n return !!held?.syncId && held.syncId === served?.syncId;\n}\n\nfunction staleRoutesError(stale: string[]): RpcError<'api-version-mismatch'> {\n return new RpcError({\n type: 'api-version-mismatch',\n publicMessage:\n `This mion client carries routes compiled against an older version of the API: the server answers with a ` +\n `different build version, and ${stale.map((id) => `\"${id}\"`).join(', ')} no longer matches what it declares. ` +\n `Reload the app or rebuild the client against the current API.`,\n });\n}\n"],"mappings":"iTAiBA,IAAM,YAAc,IAAI,IAExB,SAAS,WAAW,QAA8B,CAChD,IAAI,IAAM,YAAY,IAAI,OAAO,EACjC,OAAK,KAAK,YAAY,IAAI,QAAU,IAAM,IAAI,GAAM,EAC7C,GACT,CAGA,SAAgB,cAAc,QAAiB,IAAyB,CACtE,MAAM,SAAW,WAAW,OAAO,EACnC,OAAO,IAAI,OAAQ,IAAO,CAAC,SAAS,IAAI,EAAE,CAAC,CAC7C,CAGA,SAAgB,yBAAgC,CAC9C,YAAY,MAAM,CACpB,CAGA,SAAgB,iBAAiB,QAAwB,MAAiB,KAAqC,CAC7G,MAAM,SAAW,WAAW,QAAQ,OAAO,EAC3C,UAAW,MAAM,MAAO,SAAS,IAAI,EAAE,EAEvC,MAAM,MAAQ,MAAM,OAAQ,IAAO,CAAC,UAAU,wBAAA,UAAU,EAAE,EAAG,KAAK,QAAQ,EAAA,CAAoC,CAAC,EAC/G,GAAI,CAAC,MAAM,OAAQ,OACnB,MAAM,QAAU,MAAM,OAAQ,IAAO,CAAC,wBAAA,gBAAgB,EAAE,CAAC,EACrD,QAAQ,QAAQ,sCAAA,kBAAkB,KAAM,QAAS,OAAO,EAC5D,MAAM,QAAU,MAAM,OAAQ,IAAO,wBAAA,gBAAgB,EAAE,CAAC,EACpD,QAAQ,QAAQ,gCAAA,qBAAqB,iBAAiB,OAAO,CAAC,CACpE,CAGA,SAAgB,UAAU,KAAqC,OAAgD,CAC7G,MAAO,CAAC,CAAC,MAAM,QAAU,KAAK,SAAW,QAAQ,MACnD,CAEA,SAAS,iBAAiB,MAAmD,CAC3E,OAAO,IAAI,aAAA,SAAS,CAClB,KAAM,uBACN,cACE,wIACgC,MAAM,IAAK,IAAO,IAAI,EAAA,GAAK,EAAE,KAAK,IAAI,CAAA,oGAE1E,CAAC,CACH"}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import { MethodWithOptions, SerializableMethodsData } from '@mionjs/core';
|
|
2
|
-
import { ClientOptions } from '../types.ts';
|
|
3
|
-
export declare function unverifiedIds(baseURL: string, ids: string[]): string[];
|
|
4
|
-
export declare function resetApiVersionRecovery(): void;
|
|
5
|
-
export declare function verifyMethodRows(options: ClientOptions, asked: string[], data: SerializableMethodsData): void;
|
|
6
|
-
export declare function rowsAgree(held: MethodWithOptions | undefined, served: MethodWithOptions | undefined): boolean;
|
|
7
|
-
//# sourceMappingURL=apiVersionRecovery.d.ts.map
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const require_src_lib_methods=require("./methods.cjs");let _mionjs_core=require("@mionjs/core");var pendingPayloadError;function registerBundledApi(payload){if(!isBundledApiPayload(payload)){pendingPayloadError=new _mionjs_core.RpcError({type:"bundle-api-invalid-payload",publicMessage:"The bundled API metadata injected at this call is not what the build writes; rebuild with a matching @mionjs/devtools."}),console.error("[mion] bundled API payload rejected at a dispatch point; rebuild with a matching @mionjs/devtools");return}for(const method of payload.methods)require_src_lib_methods.isBundledMethod(method.id)||require_src_lib_methods.setBundledMethod(method.id,bundledMethodToCacheEntry(method))}function takeBundledApiError(){const error=pendingPayloadError;return pendingPayloadError=void 0,error}function resetBundledApi(){require_src_lib_methods.resetBundledMethods(),pendingPayloadError=void 0}function isBundledApiPayload(value){if(typeof value!="object"||value===null)return!1;const methods=value.methods;return Array.isArray(methods)&&methods.every(isBundledMethodRow)}function isBundledMethodRow(value){if(typeof value!="object"||value===null)return!1;const method=value;return typeof method.id=="string"&&typeof method.type=="number"&&typeof method.nestLevel=="number"&&typeof method.isAsync=="boolean"&&Array.isArray(method.pointer)&&typeof method.options=="object"&&method.options!==null&&typeof method.rtFns=="object"&&method.rtFns!==null}var noHandler=()=>{};function bundledMethodToCacheEntry(method){const entry={...method.type===_mionjs_core.HandlerType.headersMiddleware?(0,_mionjs_core.getHeadersReflectionFromMarkers)(method.rtFns,noHandler,method.id):(0,_mionjs_core.getReflectionFromMarkers)(method.rtFns,noHandler,method.id),type:method.type,id:method.id,pointer:method.pointer,nestLevel:method.nestLevel,isAsync:method.isAsync,options:method.options};return delete entry.paramsJsonMaxBytes,method.middlewareIds&&method.middlewareIds.length&&(entry.middlewareIds=method.middlewareIds),entry}exports.registerBundledApi=registerBundledApi;exports.resetBundledApi=resetBundledApi;exports.takeBundledApiError=takeBundledApiError;
|
|
2
|
-
|
|
3
|
-
//# sourceMappingURL=bundledApi.cjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"bundledApi.cjs","names":[],"sources":["../../../../src/lib/bundledApi.ts"],"sourcesContent":["/* ########\n * 2026 mion\n * Author: Ma-jerez\n * License: MIT\n * The software is provided \"as is\", without warranty of any kind.\n * ######## */\n\nimport {\n HandlerType,\n RpcError,\n getHeadersReflectionFromMarkers,\n getReflectionFromMarkers,\n type MethodWithOptions,\n type MethodWithOptsAndJitFns,\n type RtMarkerPayload,\n} from '@mionjs/core';\nimport type {InjectedApiMetadata} from '../types.ts';\nimport {isBundledMethod, resetBundledMethods, setBundledMethod} from './methods.ts';\n\n// With bundled routes the build injects, at each dispatch point, the route and its middlewares with the server's\n// compiled functions. Registering one runs the router's initRoutes reflection, so it looks exactly like a fetched one.\n\n/** One method of a bundled payload: the `MethodWithOptions` members the build can answer from the API type,\n * plus the marker payload. The rest (jit hashes, arity, header names) comes from the reflection instead. */\nexport interface BundledMethod extends Pick<\n MethodWithOptions,\n 'id' | 'pointer' | 'nestLevel' | 'type' | 'isAsync' | 'options' | 'middlewareIds'\n> {\n rtFns: RtMarkerPayload;\n}\n\n/** What the build injects at a dispatch point: the method called plus every middleware in its chain. */\nexport interface BundledApiPayload {\n methods: BundledMethod[];\n}\n\n/** A payload the build did not write, held until a call can report it once. */\nlet pendingPayloadError: RpcError<string> | undefined;\n\n/** Registers a bundled payload, once per method id; a dispatch point passes the same module on every call.\n * The guard runs despite the declared type because a `<genDir>/api/` tree from another @mionjs/devtools\n * version can disagree; a payload it did not write is recorded, never thrown, since `call()` never throws. */\nexport function registerBundledApi(payload: InjectedApiMetadata): void {\n if (!isBundledApiPayload(payload)) {\n pendingPayloadError = new RpcError({\n type: 'bundle-api-invalid-payload',\n publicMessage:\n 'The bundled API metadata injected at this call is not what the build writes; rebuild with a matching @mionjs/devtools.',\n });\n console.error('[mion] bundled API payload rejected at a dispatch point; rebuild with a matching @mionjs/devtools');\n return;\n }\n for (const method of payload.methods) {\n if (isBundledMethod(method.id)) continue;\n setBundledMethod(method.id, bundledMethodToCacheEntry(method));\n }\n}\n\n/** Takes the last rejected payload, if any, so a call can report it once. */\nexport function takeBundledApiError(): RpcError<string> | undefined {\n const error = pendingPayloadError;\n pendingPayloadError = undefined;\n return error;\n}\n\n/** Forgets which ids came from a bundle. Tests only. */\nexport function resetBundledApi(): void {\n resetBundledMethods();\n pendingPayloadError = undefined;\n // the bundled flag stays: the build's module sets it once at import, and a cache reset cannot change the build\n}\n\nfunction isBundledApiPayload(value: unknown): value is BundledApiPayload {\n if (typeof value !== 'object' || value === null) return false;\n const methods = (value as BundledApiPayload).methods;\n return Array.isArray(methods) && methods.every(isBundledMethodRow);\n}\n\n/** Every member the cache entry reads, so a stale module fails the guard instead of a later access. */\nfunction isBundledMethodRow(value: unknown): value is BundledMethod {\n if (typeof value !== 'object' || value === null) return false;\n const method = value as BundledMethod;\n return (\n typeof method.id === 'string' &&\n typeof method.type === 'number' &&\n typeof method.nestLevel === 'number' &&\n typeof method.isAsync === 'boolean' &&\n Array.isArray(method.pointer) &&\n typeof method.options === 'object' &&\n method.options !== null &&\n typeof method.rtFns === 'object' &&\n method.rtFns !== null\n );\n}\n\n/** A bundled method never carries a handler; the reflection reads everything off the marker payload\n * and the row, so the placeholder is never called. */\nconst noHandler = () => undefined;\n\nfunction bundledMethodToCacheEntry(method: BundledMethod): MethodWithOptsAndJitFns {\n const reflection =\n method.type === HandlerType.headersMiddleware\n ? getHeadersReflectionFromMarkers(method.rtFns, noHandler, method.id)\n : getReflectionFromMarkers(method.rtFns, noHandler, method.id);\n // spread, like `registerRoutes` does on the server, so a member added to the reflection reaches\n // a bundled method too; only the row's own answers are written over it\n const entry: MethodWithOptsAndJitFns = {\n ...reflection,\n type: method.type,\n id: method.id,\n pointer: method.pointer,\n nestLevel: method.nestLevel,\n // the build answered this off the server handler's declared return; the placeholder above cannot\n isAsync: method.isAsync,\n // `options.maxBodySize` is the route's own declared limit or nothing: the number the server\n // settles for a chain that declares none (its types times the router factor, else the platform\n // adapter's) is only known at the server's registration, and the client never enforces it\n options: method.options,\n };\n // the params byte ceiling is the SERVER's: it settles a chain's request limit once at\n // registration. The client enforces no limit, and the fetched lane is never sent it either\n delete entry.paramsJsonMaxBytes;\n if (method.middlewareIds && method.middlewareIds.length) entry.middlewareIds = method.middlewareIds;\n return entry;\n}\n"],"mappings":"mKAqCA,IAAI,oBAKJ,SAAgB,mBAAmB,QAAoC,CACrE,GAAI,CAAC,oBAAoB,OAAO,EAAG,CACjC,oBAAsB,IAAI,aAAA,SAAS,CACjC,KAAM,6BACN,cACE,wHACJ,CAAC,EACD,QAAQ,MAAM,mGAAmG,EACjH,MACF,CACA,UAAW,UAAU,QAAQ,QACvB,wBAAA,gBAAgB,OAAO,EAAE,GAC7B,wBAAA,iBAAiB,OAAO,GAAI,0BAA0B,MAAM,CAAC,CAEjE,CAGA,SAAgB,qBAAoD,CAClE,MAAM,MAAQ,oBACd,2BAAsB,OACf,KACT,CAGA,SAAgB,iBAAwB,CACtC,wBAAA,oBAAoB,EACpB,oBAAsB,MAExB,CAEA,SAAS,oBAAoB,MAA4C,CACvE,GAAI,OAAO,OAAU,UAAY,QAAU,KAAM,MAAO,GACxD,MAAM,QAAW,MAA4B,QAC7C,OAAO,MAAM,QAAQ,OAAO,GAAK,QAAQ,MAAM,kBAAkB,CACnE,CAGA,SAAS,mBAAmB,MAAwC,CAClE,GAAI,OAAO,OAAU,UAAY,QAAU,KAAM,MAAO,GACxD,MAAM,OAAS,MACf,OACE,OAAO,OAAO,IAAO,UACrB,OAAO,OAAO,MAAS,UACvB,OAAO,OAAO,WAAc,UAC5B,OAAO,OAAO,SAAY,WAC1B,MAAM,QAAQ,OAAO,OAAO,GAC5B,OAAO,OAAO,SAAY,UAC1B,OAAO,UAAY,MACnB,OAAO,OAAO,OAAU,UACxB,OAAO,QAAU,IAErB,CAIA,IAAM,UAAA,IAAA,GAEN,SAAS,0BAA0B,OAAgD,CAOjF,MAAM,MAAiC,CACrC,GANA,OAAO,OAAS,aAAA,YAAY,qBAAA,aAAA,iCACQ,OAAO,MAAO,UAAW,OAAO,EAAE,KAAA,aAAA,0BACzC,OAAO,MAAO,UAAW,OAAO,EAAE,EAK/D,KAAM,OAAO,KACb,GAAI,OAAO,GACX,QAAS,OAAO,QAChB,UAAW,OAAO,UAElB,QAAS,OAAO,QAIhB,QAAS,OAAO,OAClB,EAGA,cAAO,MAAM,mBACT,OAAO,eAAiB,OAAO,cAAc,SAAQ,MAAM,cAAgB,OAAO,eAC/E,KACT"}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { RpcError, MethodWithOptions, RtMarkerPayload } from '@mionjs/core';
|
|
2
|
-
import { InjectedApiMetadata } from '../types.ts';
|
|
3
|
-
export interface BundledMethod extends Pick<MethodWithOptions, 'id' | 'pointer' | 'nestLevel' | 'type' | 'isAsync' | 'options' | 'middlewareIds'> {
|
|
4
|
-
rtFns: RtMarkerPayload;
|
|
5
|
-
}
|
|
6
|
-
export interface BundledApiPayload {
|
|
7
|
-
methods: BundledMethod[];
|
|
8
|
-
}
|
|
9
|
-
export declare function registerBundledApi(payload: InjectedApiMetadata): void;
|
|
10
|
-
export declare function takeBundledApiError(): RpcError<string> | undefined;
|
|
11
|
-
export declare function resetBundledApi(): void;
|
|
12
|
-
//# sourceMappingURL=bundledApi.d.ts.map
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const require_src_constants=require("../constants.cjs"),require_src_lib_metadataStore=require("./metadataStore.cjs"),require_src_lib_persistentStorage=require("./persistentStorage.cjs"),require_src_lib_methods=require("./methods.cjs"),require_src_lib_metadataEviction=require("./metadataEviction.cjs");let _mionjs_core=require("@mionjs/core");var states=new Map,writeQueue=[],flushHandle,flushChain=Promise.resolve(),persistenceAsked=!1,pendingCacheError;function getState(options){const baseURL=options.baseURL;let state=states.get(baseURL);return state||(state={baseURL,storageEngine:options.storageEngine,hydratedIds:new Set,stored:new Map,bytes:0,graph:{methods:Object.create(null),deps:Object.create(null),pureFns:Object.create(null)},sweepScheduled:!1},states.set(baseURL,state)),state}function storedKey(kind,id){return`${kind} ${id}`}function processMethodsMetadata(serializableMethodsData,options){addToCaches(serializableMethodsData),queuePersist(serializableMethodsData,options)}function isStorableName(name){return!(0,_mionjs_core.isUnsafePropertyName)(name)&&!name.includes(":")}function queuePersist(data,options){writeQueue.push({data,options}),scheduleFlush()}function scheduleFlush(){if(flushHandle!==void 0)return;const run=()=>{flushHandle=void 0,flushChain=flushChain.then(flushQueue)},idle=globalThis.requestIdleCallback;flushHandle=typeof idle=="function"?idle(run,{timeout:200}):setTimeout(run,0)}function flushMetadataCache(){if(flushHandle!==void 0){const cancelIdle=globalThis.cancelIdleCallback;typeof cancelIdle=="function"?cancelIdle(flushHandle):clearTimeout(flushHandle),flushHandle=void 0}return flushChain=flushChain.then(flushQueue),flushChain}async function flushQueue(){if(!writeQueue.length)return;const batch=writeQueue;writeQueue=[];const byBaseURL=new Map;for(const item of batch){const group=byBaseURL.get(item.options.baseURL);group?group.payloads.push(item.data):byBaseURL.set(item.options.baseURL,{options:item.options,payloads:[item.data]})}for(const group of byBaseURL.values())await persistPayloads(group.options,group.payloads)}async function persistPayloads(options,payloads){const baseURL=options.baseURL,state=getState(options),ts=Date.now(),records=new Map,add=(kind,id,value)=>{const key=storedKey(kind,id);if(!(kind!=="m"&&state.stored.has(key)))try{records.set(key,{baseURL,kind,id,json:JSON.stringify(value),ts})}catch(error){console.warn(`Failed to serialize metadata cache entry ${id}:`,error)}};for(const payload of payloads){for(const[hash,jitFnData]of Object.entries(payload.deps??{})){if(!isStorableName(hash)){console.warn(`Refused to store JIT function dependency under '${hash}'`);continue}add("j",hash,jitFnData)}for(const[id,pureFnData]of Object.entries(payload.purFnDeps??{})){if(!isStorableName(id)){console.warn(`Refused to store pure function '${id}'`);continue}add("p",id,pureFnData)}for(const[methodId,methodData]of Object.entries(payload.methods??{})){if(!isStorableName(methodId)){console.warn(`Refused to store metadata for method '${methodId}'`);continue}require_src_lib_methods.isBundledMethod(methodId)||add("m",methodId,methodData)}}records.size&&await writeRecords(state,[...records.values()])}function recordBytes(record){return record.json.length+record.id.length}async function writeRecords(state,records){const store=await require_src_lib_metadataStore.getMetadataStore(state.storageEngine),incoming=records.reduce((total,record)=>total+recordBytes(record),0);await evictOldest(state,store,state.bytes+incoming-require_src_constants.METADATA_CACHE_MAX_BYTES);for(let round=0;;round++)try{await store.write(records);for(const record of records){const key=storedKey(record.kind,record.id),previous=state.stored.get(key);previous&&(state.bytes-=previous.bytes);const bytes=recordBytes(record);state.stored.set(key,{kind:record.kind,id:record.id,ts:record.ts,bytes}),state.bytes+=bytes}askForPersistenceOnce();return}catch(error){if(round>=5||!await evictOldest(state,store,Math.max(state.bytes/4,incoming)))return reportCacheError(error)}}async function evictOldest(state,store,targetBytes){if(targetBytes<=0||!state.stored.size)return 0;const oldestFirst=[...state.stored.values()].sort((a,b)=>a.ts-b.ts),keys=[];let freed=0;for(const entry of oldestFirst)if(keys.push([entry.kind,entry.id]),freed+=entry.bytes,freed>=targetBytes)break;try{await store.remove(state.baseURL,keys)}catch{return 0}for(const[kind,id]of keys){const key=storedKey(kind,id);state.bytes-=state.stored.get(key)?.bytes??0,state.stored.delete(key),kind==="j"?delete state.graph.deps[id]:kind==="p"?delete state.graph.pureFns[id]:delete state.graph.methods[id]}return freed}function reportCacheError(error){const rpcError=new _mionjs_core.RpcError({type:"metadata-cache-error",publicMessage:"Could not store the remote method metadata cache",originalError:error instanceof Error?error:void 0});console.error("[mion] metadata cache write failed:",error),pendingCacheError=rpcError}function takeMetadataCacheError(){const error=pendingCacheError;return pendingCacheError=void 0,error}function askForPersistenceOnce(){persistenceAsked||(persistenceAsked=!0,require_src_lib_persistentStorage.requestPersistenceWhenSilent())}function hydrateMetadataCache(options){const state=getState(options);return state.hydration||(state.hydration=hydrate(state).catch(error=>{console.warn("Failed to restore the remote method metadata cache:",error)})),state.hydration}async function hydrate(state){const records=await(await require_src_lib_metadataStore.getMetadataStore(state.storageEngine)).readAll(state.baseURL);if(!records.length)return;const deps=Object.create(null),pureFnDeps=Object.create(null),methods=Object.create(null);for(const record of records){if(!isStorableName(record.id))continue;let parsed;try{parsed=JSON.parse(record.json)}catch(error){console.warn(`Failed to restore metadata cache entry ${record.id}:`,error);continue}const key=storedKey(record.kind,record.id);if(state.stored.set(key,{kind:record.kind,id:record.id,ts:record.ts,bytes:recordBytes(record)}),state.bytes+=recordBytes(record),record.kind==="j")deps[record.id]=parsed,state.graph.deps[record.id]=parsed;else if(record.kind==="p"){if(typeof parsed?.code!="string"){console.warn(`Ignoring cached pure function ${record.id}: it carries no code`);continue}pureFnDeps[record.id]=parsed,state.graph.pureFns[record.id]=parsed}else methods[record.id]=parsed,state.graph.methods[record.id]=parsed}(0,_mionjs_core.addSerializedJitCaches)(deps,pureFnDeps);const restorable={},unusable=[];for(const[id,metadata]of Object.entries(methods))(0,_mionjs_core.hasJitFnsForMethod)(metadata)?(restorable[id]=metadata,state.hydratedIds.add(id)):(unusable.push(["m",id]),delete state.graph.methods[id]);(0,_mionjs_core.addRoutesToCache)(restorable),scheduleSweep(state,unusable)}function wasHydratedFromCache(id,options){return states.get(options.baseURL)?.hydratedIds.has(id)===!0}async function purgeHydratedMetadata(ids,options){const state=states.get(options.baseURL);if(!state)return;const hydrated=ids.filter(id=>state.hydratedIds.has(id));for(const id of hydrated)_mionjs_core.routesCache.removeMetadata(id);await dropStoredMethods(state,hydrated)}async function forgetFetchedMetadata(ids,options){const fetchedIds=ids.filter(id=>!require_src_lib_methods.isBundledMethod(id));for(const id of fetchedIds)_mionjs_core.routesCache.removeMetadata(id);for(const queued of writeQueue)if(queued.options.baseURL===options.baseURL)for(const id of fetchedIds)delete queued.data.methods[id];const state=states.get(options.baseURL);state&&await dropStoredMethods(state,fetchedIds)}async function dropStoredMethods(state,ids){const keys=[];for(const id of ids)state.hydratedIds.delete(id),delete state.graph.methods[id],keys.push(["m",id]);if(keys.length){await(await require_src_lib_metadataStore.getMetadataStore(state.storageEngine)).remove(state.baseURL,keys).catch(()=>{});for(const[kind,id]of keys){const key=storedKey(kind,id);state.bytes-=state.stored.get(key)?.bytes??0,state.stored.delete(key)}await sweepOrphans(state)}}function scheduleSweep(state,alsoDelete){if(state.sweepScheduled)return;state.sweepScheduled=!0;const run=()=>{sweepOrphans(state,alsoDelete)},idle=globalThis.requestIdleCallback;typeof idle=="function"?idle(run,{timeout:2e3}):setTimeout(run,0)}async function sweepOrphans(state,alsoDelete=[]){const keys=[...alsoDelete,...require_src_lib_metadataEviction.findOrphans(state.graph)];if(keys.length){await(await require_src_lib_metadataStore.getMetadataStore(state.storageEngine)).remove(state.baseURL,keys).catch(()=>{});for(const[kind,id]of keys){const key=storedKey(kind,id);state.bytes-=state.stored.get(key)?.bytes??0,state.stored.delete(key),kind==="j"?delete state.graph.deps[id]:kind==="p"?delete state.graph.pureFns[id]:delete state.graph.methods[id]}}}function resetMetadataCacheState(){states.clear(),writeQueue=[],persistenceAsked=!1,pendingCacheError=void 0}function installMethodRows(serializableMethodsData,options,replaceIds=[]){for(const id of replaceIds)_mionjs_core.routesCache.removeMetadata(id);processMethodsMetadata(serializableMethodsData,options)}function addToCaches(serializableMethodsData){(0,_mionjs_core.addSerializedJitCaches)(serializableMethodsData.deps,serializableMethodsData.purFnDeps),(0,_mionjs_core.addRoutesToCache)(serializableMethodsData.methods)}require_src_lib_methods.setFetchedMethods(_mionjs_core.routesCache);exports.flushMetadataCache=flushMetadataCache;exports.forgetFetchedMetadata=forgetFetchedMetadata;exports.hydrateMetadataCache=hydrateMetadataCache;exports.installMethodRows=installMethodRows;exports.purgeHydratedMetadata=purgeHydratedMetadata;exports.resetMetadataCacheState=resetMetadataCacheState;exports.takeMetadataCacheError=takeMetadataCacheError;exports.wasHydratedFromCache=wasHydratedFromCache;
|
|
2
|
-
|
|
3
|
-
//# sourceMappingURL=clientMethodsMetadata.cjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"clientMethodsMetadata.cjs","names":[],"sources":["../../../../src/lib/clientMethodsMetadata.ts"],"sourcesContent":["/* ########\n * 2023 mion\n * Author: Ma-jerez\n * License: MIT\n * The software is provided \"as is\", without warranty of any kind.\n * ######## */\n\nimport {addRoutesToCache, isUnsafePropertyName, hasJitFnsForMethod, RpcError} from '@mionjs/core';\nimport {ClientOptions} from '../types.ts';\nimport type {\n CompiledFnData,\n MethodsCache,\n MethodWithOptions,\n PureFunctionData,\n SerializablePureFunction,\n SerializableMethodsData,\n PureFnsDataCache,\n} from '@mionjs/core';\nimport {addSerializedJitCaches, routesCache} from '@mionjs/core';\nimport {METADATA_CACHE_EVICTION_ROUNDS, METADATA_CACHE_MAX_BYTES} from '../constants.ts';\nimport {getMetadataStore} from './metadataStore.ts';\nimport type {MetadataKind, MetadataRecord, MetadataRecordKey, MetadataStore, StorageEngine} from './storage.ts';\nimport {findOrphans, type CacheGraph} from './metadataEviction.ts';\nimport {requestPersistenceWhenSilent} from './persistentStorage.ts';\nimport {isBundledMethod, setFetchedMethods} from './methods.ts';\n\n/** What the cache knows about one stored record, without holding its text. Enough to pick the\n * oldest rows when room is needed, and to skip re-writing an entry that is already down. */\ninterface StoredEntry {\n kind: MetadataKind;\n id: string;\n ts: number;\n bytes: number;\n}\n\n/** Everything the cache tracks for one server. One instance per baseURL, for the page's lifetime. */\ninterface CacheState {\n baseURL: string;\n /** the engine this server's cache lives on, so every read and write goes to the same store */\n storageEngine: StorageEngine | undefined;\n hydration?: Promise<void>;\n /** method ids this page restored from the store rather than from the server */\n hydratedIds: Set<string>;\n /** what is on disk, keyed `${kind} ${id}` */\n stored: Map<string, StoredEntry>;\n bytes: number;\n graph: CacheGraph;\n sweepScheduled: boolean;\n}\n\nconst states = new Map<string, CacheState>();\n/** Payloads waiting to be written; the response path only pushes here and returns */\nlet writeQueue: {data: SerializableMethodsData; options: ClientOptions}[] = [];\nlet flushHandle: ReturnType<typeof setTimeout> | number | undefined;\nlet flushChain: Promise<void> = Promise.resolve();\nlet persistenceAsked = false;\nlet pendingCacheError: RpcError<string> | undefined;\n\nfunction getState(options: ClientOptions): CacheState {\n const baseURL = options.baseURL;\n let state = states.get(baseURL);\n if (!state) {\n state = {\n baseURL,\n storageEngine: options.storageEngine,\n hydratedIds: new Set(),\n stored: new Map(),\n bytes: 0,\n // Null-prototype maps: every key comes off the store, which any script on the page can write,\n // so a plain object would let a `__proto__` key reach Object.prototype.\n graph: {methods: Object.create(null), deps: Object.create(null), pureFns: Object.create(null)},\n sweepScheduled: false,\n };\n states.set(baseURL, state);\n }\n return state;\n}\n\nfunction storedKey(kind: MetadataKind, id: string): string {\n return `${kind} ${id}`;\n}\n\n/** Fills the in-memory caches now and leaves the store for later: the caller is a sync deserializer on the\n * response path, where every throw becomes a parse error. */\nfunction processMethodsMetadata(serializableMethodsData: SerializableMethodsData, options: ClientOptions): void {\n addToCaches(serializableMethodsData);\n queuePersist(serializableMethodsData, options);\n}\n\n/** A name that reaches an object key on restore is checked even though the server is trusted: `__proto__` as\n * a namespace would land the next write on Object.prototype, page-wide. A refused entry is only warned about. */\nfunction isStorableName(name: string): boolean {\n return !isUnsafePropertyName(name) && !name.includes(':');\n}\n\n// ############# WRITE PATH #############\n\nfunction queuePersist(data: SerializableMethodsData, options: ClientOptions): void {\n writeQueue.push({data, options});\n scheduleFlush();\n}\n\nfunction scheduleFlush(): void {\n if (flushHandle !== undefined) return;\n const run = () => {\n flushHandle = undefined;\n flushChain = flushChain.then(flushQueue);\n };\n // idle time is exactly right for this: nothing waits on the write, and a big metadata payload\n // costs a real JSON.stringify per entry\n const idle = (globalThis as any).requestIdleCallback;\n flushHandle = typeof idle === 'function' ? idle(run, {timeout: 200}) : setTimeout(run, 0);\n}\n\n/** Resolves once every queued write has reached the store. The write path is deferred on purpose,\n * so a test that wants to read back what a response cached must await this first. */\nexport function flushMetadataCache(): Promise<void> {\n if (flushHandle !== undefined) {\n const cancelIdle = (globalThis as any).cancelIdleCallback;\n if (typeof cancelIdle === 'function') cancelIdle(flushHandle);\n else clearTimeout(flushHandle as ReturnType<typeof setTimeout>);\n flushHandle = undefined;\n }\n flushChain = flushChain.then(flushQueue);\n return flushChain;\n}\n\nasync function flushQueue(): Promise<void> {\n if (!writeQueue.length) return;\n const batch = writeQueue;\n writeQueue = [];\n const byBaseURL = new Map<string, {options: ClientOptions; payloads: SerializableMethodsData[]}>();\n for (const item of batch) {\n const group = byBaseURL.get(item.options.baseURL);\n if (group) group.payloads.push(item.data);\n else byBaseURL.set(item.options.baseURL, {options: item.options, payloads: [item.data]});\n }\n for (const group of byBaseURL.values()) await persistPayloads(group.options, group.payloads);\n}\n\n/** Turns the payloads into records, dropping anything already down, then writes them as one unit. */\nasync function persistPayloads(options: ClientOptions, payloads: SerializableMethodsData[]): Promise<void> {\n const baseURL = options.baseURL;\n const state = getState(options);\n const ts = Date.now();\n const records = new Map<string, MetadataRecord>();\n const add = (kind: MetadataKind, id: string, value: unknown) => {\n const key = storedKey(kind, id);\n // hashes are content addresses, so a compiled function already down is byte for byte this one.\n // A method row is keyed by its id instead, so it is always rewritten.\n if (kind !== 'm' && state.stored.has(key)) return;\n try {\n records.set(key, {baseURL, kind, id, json: JSON.stringify(value), ts});\n } catch (error) {\n console.warn(`Failed to serialize metadata cache entry ${id}:`, error);\n }\n };\n\n for (const payload of payloads) {\n for (const [hash, jitFnData] of Object.entries<CompiledFnData>(payload.deps ?? {})) {\n if (!isStorableName(hash)) {\n console.warn(`Refused to store JIT function dependency under '${hash}'`);\n continue;\n }\n add('j', hash, jitFnData);\n }\n for (const [id, pureFnData] of Object.entries<PureFunctionData>(payload.purFnDeps ?? {})) {\n if (!isStorableName(id)) {\n console.warn(`Refused to store pure function '${id}'`);\n continue;\n }\n add('p', id, pureFnData);\n }\n for (const [methodId, methodData] of Object.entries<MethodWithOptions>(payload.methods ?? {})) {\n if (!isStorableName(methodId)) {\n console.warn(`Refused to store metadata for method '${methodId}'`);\n continue;\n }\n // The server answers for a route's whole chain, so a bundled middleware rides a fetched route's\n // answer; its row would only be read back to be ignored. Orphaned compiled functions are swept.\n if (isBundledMethod(methodId)) continue;\n add('m', methodId, methodData);\n }\n }\n\n if (!records.size) return;\n await writeRecords(state, [...records.values()]);\n}\n\nfunction recordBytes(record: MetadataRecord): number {\n return record.json.length + record.id.length;\n}\n\n/** Writes the records, making room as many times as it takes: the new data always wins. The size cap trims\n * first, and a browser that refuses anyway gets more old rows dropped and the write retried. Only an empty\n * store that still cannot take the write is reported. */\nasync function writeRecords(state: CacheState, records: MetadataRecord[]): Promise<void> {\n const store = await getMetadataStore(state.storageEngine);\n const incoming = records.reduce((total, record) => total + recordBytes(record), 0);\n await evictOldest(state, store, state.bytes + incoming - METADATA_CACHE_MAX_BYTES);\n\n for (let round = 0; ; round++) {\n try {\n await store.write(records);\n for (const record of records) {\n const key = storedKey(record.kind, record.id);\n const previous = state.stored.get(key);\n if (previous) state.bytes -= previous.bytes;\n const bytes = recordBytes(record);\n state.stored.set(key, {kind: record.kind, id: record.id, ts: record.ts, bytes});\n state.bytes += bytes;\n }\n askForPersistenceOnce();\n return;\n } catch (error) {\n if (round >= METADATA_CACHE_EVICTION_ROUNDS) return reportCacheError(error);\n // nothing freed means nothing is left to give up, so the store cannot take this write: tell the app\n const freed = await evictOldest(state, store, Math.max(state.bytes / 4, incoming));\n if (!freed) return reportCacheError(error);\n }\n }\n}\n\n/** Drops the oldest rows until at least `targetBytes` have been freed. Returns the bytes freed.\n * Safe at any granularity: a method whose compiled functions went with it is refused on the next\n * hydration and simply refetched. */\nasync function evictOldest(state: CacheState, store: MetadataStore, targetBytes: number): Promise<number> {\n if (targetBytes <= 0 || !state.stored.size) return 0;\n const oldestFirst = [...state.stored.values()].sort((a, b) => a.ts - b.ts);\n const keys: MetadataRecordKey[] = [];\n let freed = 0;\n for (const entry of oldestFirst) {\n keys.push([entry.kind, entry.id]);\n freed += entry.bytes;\n if (freed >= targetBytes) break;\n }\n try {\n await store.remove(state.baseURL, keys);\n } catch {\n // a store that cannot delete cannot be trimmed; the caller reports the write failure instead\n return 0;\n }\n for (const [kind, id] of keys) {\n const key = storedKey(kind, id);\n state.bytes -= state.stored.get(key)?.bytes ?? 0;\n state.stored.delete(key);\n if (kind === 'j') delete state.graph.deps[id];\n else if (kind === 'p') delete state.graph.pureFns[id];\n else delete state.graph.methods[id];\n }\n return freed;\n}\n\nfunction reportCacheError(error: unknown): void {\n const rpcError = new RpcError({\n type: 'metadata-cache-error',\n publicMessage: 'Could not store the remote method metadata cache',\n originalError: error instanceof Error ? error : undefined,\n });\n // loud now for whoever is watching the console, and again on the next call for the app itself\n console.error('[mion] metadata cache write failed:', error);\n pendingCacheError = rpcError;\n}\n\n/** Takes the last unrecoverable cache error, if any, so a call can report it once. */\nexport function takeMetadataCacheError(): RpcError<string> | undefined {\n const error = pendingCacheError;\n pendingCacheError = undefined;\n return error;\n}\n\nfunction askForPersistenceOnce(): void {\n if (persistenceAsked) return;\n persistenceAsked = true;\n // never awaited, and never in a browser where it could prompt (see persistentStorage.ts)\n void requestPersistenceWhenSilent();\n}\n\n// ############# READ PATH #############\n\n/** Restores everything this server cached, once per page. One indexed read, never a scan.\n * Never rejects: a missing or blocked store is a cache miss, not an error. */\nexport function hydrateMetadataCache(options: ClientOptions): Promise<void> {\n const state = getState(options);\n if (!state.hydration) {\n state.hydration = hydrate(state).catch((error) => {\n console.warn('Failed to restore the remote method metadata cache:', error);\n });\n }\n return state.hydration;\n}\n\nasync function hydrate(state: CacheState): Promise<void> {\n const store = await getMetadataStore(state.storageEngine);\n const records = await store.readAll(state.baseURL);\n if (!records.length) return;\n\n const deps: Record<string, CompiledFnData> = Object.create(null);\n const pureFnDeps: PureFnsDataCache = Object.create(null);\n const methods: MethodsCache = Object.create(null);\n\n for (const record of records) {\n // the entry is keyed by the id in ITS OWN record, never by what the payload claims\n if (!isStorableName(record.id)) continue;\n let parsed: any;\n try {\n parsed = JSON.parse(record.json);\n } catch (error) {\n console.warn(`Failed to restore metadata cache entry ${record.id}:`, error);\n continue;\n }\n const key = storedKey(record.kind, record.id);\n state.stored.set(key, {kind: record.kind, id: record.id, ts: record.ts, bytes: recordBytes(record)});\n state.bytes += recordBytes(record);\n if (record.kind === 'j') {\n deps[record.id] = parsed;\n state.graph.deps[record.id] = parsed;\n } else if (record.kind === 'p') {\n // the factory is rebuilt from `code`, so an entry without one restores to nothing callable\n if (typeof parsed?.code !== 'string') {\n console.warn(`Ignoring cached pure function ${record.id}: it carries no code`);\n continue;\n }\n pureFnDeps[record.id] = parsed as SerializablePureFunction;\n state.graph.pureFns[record.id] = parsed;\n } else {\n methods[record.id] = parsed as MethodWithOptions;\n state.graph.methods[record.id] = parsed;\n }\n }\n\n addSerializedJitCaches(deps, pureFnDeps);\n\n // A method whose compiled functions are gone (eviction, an aborted write, a newer server build) would\n // throw at call time, not here: refuse it and let the server be asked again.\n const restorable: MethodsCache = {};\n const unusable: MetadataRecordKey[] = [];\n for (const [id, metadata] of Object.entries(methods)) {\n if (hasJitFnsForMethod(metadata)) {\n restorable[id] = metadata;\n state.hydratedIds.add(id);\n } else {\n unusable.push(['m', id]);\n delete state.graph.methods[id];\n }\n }\n addRoutesToCache(restorable);\n scheduleSweep(state, unusable);\n}\n\n/** True when this page took the method's metadata off the store rather than from the server. */\nexport function wasHydratedFromCache(id: string, options: ClientOptions): boolean {\n return states.get(options.baseURL)?.hydratedIds.has(id) === true;\n}\n\n/** Drops restored rows the server no longer matches from memory and the store, so the next call relearns them. */\nexport async function purgeHydratedMetadata(ids: string[], options: ClientOptions): Promise<void> {\n const state = states.get(options.baseURL);\n if (!state) return;\n const hydrated = ids.filter((id) => state.hydratedIds.has(id));\n for (const id of hydrated) routesCache.removeMetadata(id);\n await dropStoredMethods(state, hydrated);\n}\n\n/** Forgets fetched rows from memory, the store and any queued write, so the next call relearns them.\n * A bundled row stays: the calling code was built against it. */\nexport async function forgetFetchedMetadata(ids: string[], options: ClientOptions): Promise<void> {\n const fetchedIds = ids.filter((id) => !isBundledMethod(id));\n for (const id of fetchedIds) routesCache.removeMetadata(id);\n // a queued write would put the forgotten row back after the delete below\n for (const queued of writeQueue) {\n if (queued.options.baseURL !== options.baseURL) continue;\n for (const id of fetchedIds) delete queued.data.methods[id];\n }\n const state = states.get(options.baseURL);\n if (state) await dropStoredMethods(state, fetchedIds);\n}\n\nasync function dropStoredMethods(state: CacheState, ids: string[]): Promise<void> {\n const keys: MetadataRecordKey[] = [];\n for (const id of ids) {\n state.hydratedIds.delete(id);\n delete state.graph.methods[id];\n keys.push(['m', id]);\n }\n if (!keys.length) return;\n const store = await getMetadataStore(state.storageEngine);\n await store.remove(state.baseURL, keys).catch(() => undefined);\n for (const [kind, id] of keys) {\n const key = storedKey(kind, id);\n state.bytes -= state.stored.get(key)?.bytes ?? 0;\n state.stored.delete(key);\n }\n // the compiled functions those methods pointed at have nothing left pointing at them\n await sweepOrphans(state);\n}\n\n/** Deletes rows nothing can reach any more. Costs no extra reads: it walks the records hydration\n * already parsed. Once per server per page, on idle. */\nfunction scheduleSweep(state: CacheState, alsoDelete: MetadataRecordKey[]): void {\n if (state.sweepScheduled) return;\n state.sweepScheduled = true;\n const run = () => void sweepOrphans(state, alsoDelete);\n const idle = (globalThis as any).requestIdleCallback;\n if (typeof idle === 'function') idle(run, {timeout: 2000});\n else setTimeout(run, 0);\n}\n\nasync function sweepOrphans(state: CacheState, alsoDelete: MetadataRecordKey[] = []): Promise<void> {\n const keys = [...alsoDelete, ...findOrphans(state.graph)];\n if (!keys.length) return;\n const store = await getMetadataStore(state.storageEngine);\n await store.remove(state.baseURL, keys).catch(() => undefined);\n for (const [kind, id] of keys) {\n const key = storedKey(kind, id);\n state.bytes -= state.stored.get(key)?.bytes ?? 0;\n state.stored.delete(key);\n if (kind === 'j') delete state.graph.deps[id];\n else if (kind === 'p') delete state.graph.pureFns[id];\n else delete state.graph.methods[id];\n }\n}\n\n/** Forgets everything this page learned about the store. Only for testing — simulates a new page. */\nexport function resetMetadataCacheState(): void {\n states.clear();\n writeQueue = [];\n persistenceAsked = false;\n pendingCacheError = undefined;\n}\n\n/** Saves rows answered outside the metadata route: a stored row that later disagrees with its server is relearned.\n * `replaceIds` go first: the fetched shelf never overwrites a row. */\nexport function installMethodRows(\n serializableMethodsData: SerializableMethodsData,\n options: ClientOptions,\n replaceIds: string[] = []\n): void {\n for (const id of replaceIds) routesCache.removeMetadata(id);\n processMethodsMetadata(serializableMethodsData, options);\n}\n\nfunction addToCaches(serializableMethodsData: SerializableMethodsData) {\n addSerializedJitCaches(serializableMethodsData.deps, serializableMethodsData.purFnDeps);\n addRoutesToCache(serializableMethodsData.methods);\n}\n\n// Registered here rather than in metadataFromServer.ts: its pieces are public API and a consumer\n// can import one directly, so this module evaluating IS the moment the fetched lane exists.\nsetFetchedMethods(routesCache);\n"],"mappings":"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"}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { RpcError, SerializableMethodsData } from '@mionjs/core';
|
|
2
|
-
import { ClientOptions } from '../types.ts';
|
|
3
|
-
export declare function flushMetadataCache(): Promise<void>;
|
|
4
|
-
export declare function takeMetadataCacheError(): RpcError<string> | undefined;
|
|
5
|
-
export declare function hydrateMetadataCache(options: ClientOptions): Promise<void>;
|
|
6
|
-
export declare function wasHydratedFromCache(id: string, options: ClientOptions): boolean;
|
|
7
|
-
export declare function purgeHydratedMetadata(ids: string[], options: ClientOptions): Promise<void>;
|
|
8
|
-
export declare function forgetFetchedMetadata(ids: string[], options: ClientOptions): Promise<void>;
|
|
9
|
-
export declare function resetMetadataCacheState(): void;
|
|
10
|
-
export declare function installMethodRows(serializableMethodsData: SerializableMethodsData, options: ClientOptions, replaceIds?: string[]): void;
|
|
11
|
-
//# sourceMappingURL=clientMethodsMetadata.d.ts.map
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});let _mionjs_core=require("@mionjs/core");function addThrownError(response,error){const thrownErrors=response[_mionjs_core.MION_ROUTES.thrownErrors];Array.isArray(thrownErrors)?thrownErrors.push(error):response[_mionjs_core.MION_ROUTES.thrownErrors]=[error]}function hasResponseValue(response,id){const{parent,key}=findParent(response,id);return!!parent&&Object.hasOwn(parent,key)}function getResponseValue(response,id){const{parent,key}=findParent(response,id);return parent&&Object.hasOwn(parent,key)?parent[key]:void 0}function setResponseValue(response,id,value){const{parent,key}=findParent(response,id,!0);return parent&&(parent[key]=value),!!parent}function deleteResponseValue(response,id){const pointer=id.split(_mionjs_core.ROUTER_ITEM_SEPARATOR_CHAR);for(let depth=pointer.length;depth>0;depth--){const{parent,key}=findParent(response,pointer.slice(0,depth).join(_mionjs_core.ROUTER_ITEM_SEPARATOR_CHAR));if(!parent||!Object.hasOwn(parent,key))return;const child=parent[key];if(depth<pointer.length&&!(isNode(child)&&!Object.keys(child).length))return;delete parent[key]}}function findParent(response,id,create=!1){const pointer=id.split(_mionjs_core.ROUTER_ITEM_SEPARATOR_CHAR),key=pointer[pointer.length-1];if(pointer.includes("__proto__")||pointer[0]===_mionjs_core.MION_ROUTES.thrownErrors)return{key};let node=response;for(let i=0;i<pointer.length-1;i++){let next=Object.hasOwn(node,pointer[i])?node[pointer[i]]:void 0;if(next===void 0&&create&&(next=node[pointer[i]]={}),!isNode(next))return{key};node=next}return{parent:node,key}}function isNode(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)}exports.addThrownError=addThrownError;exports.deleteResponseValue=deleteResponseValue;exports.getResponseValue=getResponseValue;exports.hasResponseValue=hasResponseValue;exports.setResponseValue=setResponseValue;
|
|
2
|
-
|
|
3
|
-
//# sourceMappingURL=clientResponse.cjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"clientResponse.cjs","names":[],"sources":["../../../../src/lib/clientResponse.ts"],"sourcesContent":["/* ########\n * 2026 mion\n * Author: Ma-jerez\n * License: MIT\n * The software is provided \"as is\", without warranty of any kind.\n * ######## */\n\nimport {MION_ROUTES, ROUTER_ITEM_SEPARATOR_CHAR} from '@mionjs/core';\nimport type {RpcError} from '@mionjs/core';\nimport type {RemoteApi} from '@mionjs/router';\nimport type {ClientResponse} from '../types.ts';\n\ntype ResponseNode = Record<string, unknown>;\n\nexport function addThrownError(response: ClientResponse<RemoteApi>, error: RpcError<string>): void {\n const thrownErrors = response[MION_ROUTES.thrownErrors];\n if (Array.isArray(thrownErrors)) thrownErrors.push(error);\n else response[MION_ROUTES.thrownErrors] = [error];\n}\n\nexport function hasResponseValue(response: ClientResponse<RemoteApi>, id: string): boolean {\n const {parent, key} = findParent(response, id);\n return !!parent && Object.hasOwn(parent, key);\n}\n\nexport function getResponseValue(response: ClientResponse<RemoteApi>, id: string): unknown {\n const {parent, key} = findParent(response, id);\n return parent && Object.hasOwn(parent, key) ? parent[key] : undefined;\n}\n\n/** False when the id has no safe path, so the caller keeps the value somewhere else */\nexport function setResponseValue(response: ClientResponse<RemoteApi>, id: string, value: unknown): boolean {\n const {parent, key} = findParent(response, id, true);\n if (parent) parent[key] = value;\n return !!parent;\n}\n\n/** Also drops every group it leaves empty: the response never holds what the body did not */\nexport function deleteResponseValue(response: ClientResponse<RemoteApi>, id: string): void {\n const pointer = id.split(ROUTER_ITEM_SEPARATOR_CHAR);\n for (let depth = pointer.length; depth > 0; depth--) {\n const {parent, key} = findParent(response, pointer.slice(0, depth).join(ROUTER_ITEM_SEPARATOR_CHAR));\n if (!parent || !Object.hasOwn(parent, key)) return;\n const child = parent[key];\n if (depth < pointer.length && !(isNode(child) && !Object.keys(child).length)) return;\n delete parent[key];\n }\n}\n\nfunction findParent(response: ClientResponse<RemoteApi>, id: string, create = false): {parent?: ResponseNode; key: string} {\n const pointer = id.split(ROUTER_ITEM_SEPARATOR_CHAR);\n const key = pointer[pointer.length - 1];\n // a response key is untrusted: `__proto__` would write the prototype, and the top-level thrown list is not a group\n if (pointer.includes('__proto__') || pointer[0] === MION_ROUTES.thrownErrors) return {key};\n let node: ResponseNode = response;\n for (let i = 0; i < pointer.length - 1; i++) {\n let next = Object.hasOwn(node, pointer[i]) ? node[pointer[i]] : undefined;\n if (next === undefined && create) next = node[pointer[i]] = {};\n if (!isNode(next)) return {key};\n node = next;\n }\n return {parent: node, key};\n}\n\nfunction isNode(value: unknown): value is ResponseNode {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n"],"mappings":"4GAcA,SAAgB,eAAe,SAAqC,MAA+B,CACjG,MAAM,aAAe,SAAS,aAAA,YAAY,YAAA,EACtC,MAAM,QAAQ,YAAY,EAAG,aAAa,KAAK,KAAK,EACnD,SAAS,aAAA,YAAY,YAAA,EAAgB,CAAC,KAAK,CAClD,CAEA,SAAgB,iBAAiB,SAAqC,GAAqB,CACzF,KAAM,CAAC,OAAQ,GAAA,EAAO,WAAW,SAAU,EAAE,EAC7C,MAAO,CAAC,CAAC,QAAU,OAAO,OAAO,OAAQ,GAAG,CAC9C,CAEA,SAAgB,iBAAiB,SAAqC,GAAqB,CACzF,KAAM,CAAC,OAAQ,GAAA,EAAO,WAAW,SAAU,EAAE,EAC7C,OAAO,QAAU,OAAO,OAAO,OAAQ,GAAG,EAAI,OAAO,GAAA,EAAO,MAC9D,CAGA,SAAgB,iBAAiB,SAAqC,GAAY,MAAyB,CACzG,KAAM,CAAC,OAAQ,GAAA,EAAO,WAAW,SAAU,GAAI,EAAI,EACnD,OAAI,SAAQ,OAAO,GAAA,EAAO,OACnB,CAAC,CAAC,MACX,CAGA,SAAgB,oBAAoB,SAAqC,GAAkB,CACzF,MAAM,QAAU,GAAG,MAAM,aAAA,0BAA0B,EACnD,QAAS,MAAQ,QAAQ,OAAQ,MAAQ,EAAG,QAAS,CACnD,KAAM,CAAC,OAAQ,GAAA,EAAO,WAAW,SAAU,QAAQ,MAAM,EAAG,KAAK,EAAE,KAAK,aAAA,0BAA0B,CAAC,EACnG,GAAI,CAAC,QAAU,CAAC,OAAO,OAAO,OAAQ,GAAG,EAAG,OAC5C,MAAM,MAAQ,OAAO,GAAA,EACrB,GAAI,MAAQ,QAAQ,QAAU,EAAE,OAAO,KAAK,GAAK,CAAC,OAAO,KAAK,KAAK,EAAE,QAAS,OAC9E,OAAO,OAAO,GAAA,CAChB,CACF,CAEA,SAAS,WAAW,SAAqC,GAAY,OAAS,GAA6C,CACzH,MAAM,QAAU,GAAG,MAAM,aAAA,0BAA0B,EAC7C,IAAM,QAAQ,QAAQ,OAAS,CAAA,EAErC,GAAI,QAAQ,SAAS,WAAW,GAAK,QAAQ,CAAA,IAAO,aAAA,YAAY,aAAc,MAAO,CAAC,GAAG,EACzF,IAAI,KAAqB,SACzB,QAAS,EAAI,EAAG,EAAI,QAAQ,OAAS,EAAG,IAAK,CAC3C,IAAI,KAAO,OAAO,OAAO,KAAM,QAAQ,CAAA,CAAE,EAAI,KAAK,QAAQ,CAAA,CAAA,EAAM,OAEhE,GADI,OAAS,QAAa,SAAQ,KAAO,KAAK,QAAQ,CAAA,CAAA,EAAM,CAAC,GACzD,CAAC,OAAO,IAAI,EAAG,MAAO,CAAC,GAAG,EAC9B,KAAO,IACT,CACA,MAAO,CAAC,OAAQ,KAAM,GAAG,CAC3B,CAEA,SAAS,OAAO,MAAuC,CACrD,OAAO,OAAO,OAAU,UAAY,QAAU,MAAQ,CAAC,MAAM,QAAQ,KAAK,CAC5E"}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { RpcError } from '@mionjs/core';
|
|
2
|
-
import { RemoteApi } from '@mionjs/router';
|
|
3
|
-
import { ClientResponse } from '../types.ts';
|
|
4
|
-
export declare function addThrownError(response: ClientResponse<RemoteApi>, error: RpcError<string>): void;
|
|
5
|
-
export declare function hasResponseValue(response: ClientResponse<RemoteApi>, id: string): boolean;
|
|
6
|
-
export declare function getResponseValue(response: ClientResponse<RemoteApi>, id: string): unknown;
|
|
7
|
-
export declare function setResponseValue(response: ClientResponse<RemoteApi>, id: string, value: unknown): boolean;
|
|
8
|
-
export declare function deleteResponseValue(response: ClientResponse<RemoteApi>, id: string): void;
|
|
9
|
-
//# sourceMappingURL=clientResponse.d.ts.map
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const require_src_lib_methods=require("./methods.cjs"),require_src_lib_clientMethodsMetadata=require("./clientMethodsMetadata.cjs");let _mionjs_core=require("@mionjs/core");var FETCH_METADATA_ID="mionFetchMetadata";async function fetchRemoteMethodsMetadata(methodIds,routePointer,options,signal,middlewareId=FETCH_METADATA_ID){await require_src_lib_clientMethodsMetadata.hydrateMetadataCache(options);const missingAfterLocal=methodIds.filter(path=>!require_src_lib_methods.hasMethod(path));if(!missingAfterLocal.length)return;const body={[middlewareId]:[missingAfterLocal,"only"],[(0,_mionjs_core.getRouterItemId)(routePointer)]:"metadata-only"};try{const url=new URL((0,_mionjs_core.getRoutePath)(routePointer,options),options.baseURL),parsedBody=await(await fetch(url,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(body),signal})).json(),platformError=parsedBody?.[_mionjs_core.MION_ROUTES.thrownErrors]?.[_mionjs_core.MION_ROUTES.platformError];if((0,_mionjs_core.isRpcError)(platformError))throw new _mionjs_core.RpcError(platformError);const slot=parsedBody?.[middlewareId],answer=Array.isArray(slot)?slot[1]:slot;if(!(0,_mionjs_core.isRpcError)(answer)||answer.type!=="metadata-only"||!answer.errorData?.metadata)throw new Error(`the server answered no metadata; place ${middlewareId} first in its routes`);require_src_lib_clientMethodsMetadata.installMethodRows(answer.errorData.metadata,options);const stillMissing=missingAfterLocal.filter(id=>!require_src_lib_methods.hasMethod(id));if(stillMissing.length)throw new Error(`Failed to fetch metadata for: ${stillMissing.join(", ")}`)}catch(error){throw signal?.aborted?error:new Error(`Error fetching validation and serialization metadata: ${error?.message}`)}}exports.fetchRemoteMethodsMetadata=fetchRemoteMethodsMetadata;
|
|
2
|
-
|
|
3
|
-
//# sourceMappingURL=fetchRemoteMethodsMetadata.cjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"fetchRemoteMethodsMetadata.cjs","names":[],"sources":["../../../../src/lib/fetchRemoteMethodsMetadata.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 {isRpcError, MION_ROUTES, getRoutePath, RpcError, getRouterItemId} from '@mionjs/core';\nimport type {FetchMetadataOnlyData} from '@mionjs/core/middlewares';\nimport {ClientOptions} from '../types.ts';\nimport {hydrateMetadataCache, installMethodRows} from './clientMethodsMetadata.ts';\nimport {hasMethod} from './methods.ts';\n\n/** The key `mionFetchMetadata` sits under when placed by its own name. */\nconst FETCH_METADATA_ID = 'mionFetchMetadata';\n\n/** Sent to a route's path: the metadata middleware answers and stops the call before the route runs. */\nexport async function fetchRemoteMethodsMetadata(\n methodIds: string[],\n routePointer: string[],\n options: ClientOptions,\n signal?: AbortSignal,\n middlewareId: string = FETCH_METADATA_ID\n): Promise<void> {\n await hydrateMetadataCache(options);\n const missingAfterLocal = methodIds.filter((path) => !hasMethod(path));\n if (!missingAfterLocal.length) return;\n const body: Record<string, unknown> = {\n [middlewareId]: [missingAfterLocal, 'only'],\n // not params: a server without the middleware refuses this slot instead of running the route\n [getRouterItemId(routePointer)]: 'metadata-only',\n };\n try {\n const url = new URL(getRoutePath(routePointer, options), options.baseURL);\n const response = await fetch(url, {\n method: 'POST',\n headers: {'Content-Type': 'application/json'},\n body: JSON.stringify(body),\n signal,\n });\n // the middleware pins the built-in parser on both wires, so its answer is plain JSON\n const parsedBody = await response.json();\n const platformError = parsedBody?.[MION_ROUTES.thrownErrors]?.[MION_ROUTES.platformError];\n if (isRpcError(platformError)) throw new RpcError(platformError);\n const slot = parsedBody?.[middlewareId];\n // a union answer rides the `[index, value]` envelope\n const answer = (Array.isArray(slot) ? slot[1] : slot) as RpcError<string, FetchMetadataOnlyData> | undefined;\n if (!isRpcError(answer) || answer.type !== 'metadata-only' || !answer.errorData?.metadata)\n throw new Error(`the server answered no metadata; place ${middlewareId} first in its routes`);\n installMethodRows(answer.errorData.metadata, options);\n const stillMissing = missingAfterLocal.filter((id) => !hasMethod(id));\n if (stillMissing.length) throw new Error(`Failed to fetch metadata for: ${stillMissing.join(', ')}`);\n } catch (error: any) {\n // Preserve the abort/timeout DOMException so the caller's onError can classify it\n if (signal?.aborted) throw error;\n throw new Error(`Error fetching validation and serialization metadata: ${error?.message}`);\n }\n}\n"],"mappings":"gPAcA,IAAM,kBAAoB,oBAG1B,eAAsB,2BACpB,UACA,aACA,QACA,OACA,aAAuB,kBACR,CACf,MAAM,sCAAA,qBAAqB,OAAO,EAClC,MAAM,kBAAoB,UAAU,OAAQ,MAAS,CAAC,wBAAA,UAAU,IAAI,CAAC,EACrE,GAAI,CAAC,kBAAkB,OAAQ,OAC/B,MAAM,KAAgC,EACnC,YAAA,EAAe,CAAC,kBAAmB,MAAM,oCAEzB,YAAY,CAAA,EAAI,eACnC,EACA,GAAI,CACF,MAAM,IAAM,IAAI,OAAA,aAAA,cAAiB,aAAc,OAAO,EAAG,QAAQ,OAAO,EAQlE,WAAa,MAAM,MAPF,MAAM,IAAK,CAChC,OAAQ,OACR,QAAS,CAAC,eAAgB,kBAAkB,EAC5C,KAAM,KAAK,UAAU,IAAI,EACzB,MACF,CAAC,GAEiC,KAAK,EACjC,cAAgB,aAAa,aAAA,YAAY,YAAA,IAAgB,aAAA,YAAY,aAAA,EAC3E,MAAA,aAAA,YAAe,aAAa,EAAG,MAAM,IAAI,aAAA,SAAS,aAAa,EAC/D,MAAM,KAAO,aAAa,YAAA,EAEpB,OAAU,MAAM,QAAQ,IAAI,EAAI,KAAK,CAAA,EAAK,KAChD,GAAI,IAAA,aAAA,YAAY,MAAM,GAAK,OAAO,OAAS,iBAAmB,CAAC,OAAO,WAAW,SAC/E,MAAM,IAAI,MAAM,0CAA0C,YAAA,sBAAkC,EAC9F,sCAAA,kBAAkB,OAAO,UAAU,SAAU,OAAO,EACpD,MAAM,aAAe,kBAAkB,OAAQ,IAAO,CAAC,wBAAA,UAAU,EAAE,CAAC,EACpE,GAAI,aAAa,OAAQ,MAAM,IAAI,MAAM,iCAAiC,aAAa,KAAK,IAAI,CAAA,EAAG,CACrG,OAAS,MAAY,CAEnB,MAAI,QAAQ,QAAe,MACrB,IAAI,MAAM,yDAAyD,OAAO,OAAA,EAAS,CAC3F,CACF"}
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
import { ClientOptions } from '../types.ts';
|
|
2
|
-
export declare function fetchRemoteMethodsMetadata(methodIds: string[], routePointer: string[], options: ClientOptions, signal?: AbortSignal, middlewareId?: string): Promise<void>;
|
|
3
|
-
//# sourceMappingURL=fetchRemoteMethodsMetadata.d.ts.map
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});var HandlersRegistry=class{errorHandlers=new Map;responseHandlers=new Map;requestHandlers=new Map;register(handlerId,errorType,handler){let handlerMap=this.errorHandlers.get(handlerId);handlerMap||(handlerMap=new Map,this.errorHandlers.set(handlerId,handlerMap));const handlers=handlerMap.get(errorType);handlers?handlers.push(handler):handlerMap.set(errorType,[handler])}unregister(handlerId,errorType,handler){const handlerMap=this.errorHandlers.get(handlerId),handlers=handlerMap?.get(errorType);!handlerMap||!handlers||(removeFrom(handlers,handler),handlers.length||handlerMap.delete(errorType),handlerMap.size===0&&this.errorHandlers.delete(handlerId))}hasHandler(handlerId,errorType){return this.errorHandlers.get(handlerId)?.has(errorType)??!1}getErrorHandlers(handlerId,errorType){return[...this.errorHandlers.get(handlerId)?.get(errorType)??[]]}registerResponse(handlerId,handler){const handlers=this.responseHandlers.get(handlerId);handlers?handlers.push(handler):this.responseHandlers.set(handlerId,[handler])}unregisterResponse(handlerId,handler){const handlers=this.responseHandlers.get(handlerId);handlers&&(removeFrom(handlers,handler),handlers.length||this.responseHandlers.delete(handlerId))}hasResponseHandler(handlerId){return this.responseHandlers.has(handlerId)}getResponseHandlers(handlerId){return[...this.responseHandlers.get(handlerId)??[]]}registerRequest(handlerId,handler,createSubRequest){this.requestHandlers.set(handlerId,{handler,createSubRequest})}unregisterRequest(handlerId){this.requestHandlers.delete(handlerId)}hasRequestHandler(handlerId){return this.requestHandlers.has(handlerId)}getRequestHandler(handlerId){return this.requestHandlers.get(handlerId)}getRequestHandlerIds(){return Array.from(this.requestHandlers.keys())}clearHandlers(handlerId){this.errorHandlers.delete(handlerId),this.responseHandlers.delete(handlerId),this.requestHandlers.delete(handlerId)}clearAll(){this.errorHandlers.clear(),this.responseHandlers.clear(),this.requestHandlers.clear()}getHandlerIds(){const errorIds=Array.from(this.errorHandlers.keys()),responseIds=Array.from(this.responseHandlers.keys()),requestIds=Array.from(this.requestHandlers.keys());return[...new Set([...errorIds,...responseIds,...requestIds])]}getErrorTypes(handlerId){const handlerMap=this.errorHandlers.get(handlerId);return handlerMap?Array.from(handlerMap.keys()):[]}};function removeFrom(handlers,handler){const index=handlers.indexOf(handler);index!==-1&&handlers.splice(index,1)}exports.HandlersRegistry=HandlersRegistry;
|
|
2
|
-
|
|
3
|
-
//# sourceMappingURL=handlersRegistry.cjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"handlersRegistry.cjs","names":[],"sources":["../../../../src/lib/handlersRegistry.ts"],"sourcesContent":["/* ########\n * 2025 mion\n * Author: Ma-jerez\n * License: MIT\n * The software is provided \"as is\", without warranty of any kind.\n * ######## */\n\nimport type {ErrorHandler, RequestHandler, ResponseHandler, SubRequest} from '../types.ts';\n\n/** A request handler plus the middleware function that turns its params into a sub request */\nexport interface RequestHandlerEntry {\n handler: RequestHandler<any>;\n createSubRequest: (params: any[]) => SubRequest<any>;\n}\n\n/** Central registry for persistent middleware handlers: request, response and error */\nexport class HandlersRegistry {\n private errorHandlers: Map<string, Map<string, ErrorHandler<any>[]>> = new Map();\n private responseHandlers: Map<string, ResponseHandler<any>[]> = new Map();\n private requestHandlers: Map<string, RequestHandlerEntry> = new Map();\n\n register(handlerId: string, errorType: string, handler: ErrorHandler<any>): void {\n let handlerMap = this.errorHandlers.get(handlerId);\n if (!handlerMap) {\n handlerMap = new Map();\n this.errorHandlers.set(handlerId, handlerMap);\n }\n const handlers = handlerMap.get(errorType);\n if (handlers) handlers.push(handler);\n else handlerMap.set(errorType, [handler]);\n }\n\n unregister(handlerId: string, errorType: string, handler: ErrorHandler<any>): void {\n const handlerMap = this.errorHandlers.get(handlerId);\n const handlers = handlerMap?.get(errorType);\n if (!handlerMap || !handlers) return;\n removeFrom(handlers, handler);\n if (!handlers.length) handlerMap.delete(errorType);\n if (handlerMap.size === 0) this.errorHandlers.delete(handlerId);\n }\n\n hasHandler(handlerId: string, errorType: string): boolean {\n const handlerMap = this.errorHandlers.get(handlerId);\n return handlerMap?.has(errorType) ?? false;\n }\n\n /** A copy, so a handler that adds or removes one leaves this run unchanged */\n getErrorHandlers(handlerId: string, errorType: string): ErrorHandler<any>[] {\n return [...(this.errorHandlers.get(handlerId)?.get(errorType) ?? [])];\n }\n\n registerResponse(handlerId: string, handler: ResponseHandler<any>): void {\n const handlers = this.responseHandlers.get(handlerId);\n if (handlers) handlers.push(handler);\n else this.responseHandlers.set(handlerId, [handler]);\n }\n\n unregisterResponse(handlerId: string, handler: ResponseHandler<any>): void {\n const handlers = this.responseHandlers.get(handlerId);\n if (!handlers) return;\n removeFrom(handlers, handler);\n if (!handlers.length) this.responseHandlers.delete(handlerId);\n }\n\n hasResponseHandler(handlerId: string): boolean {\n return this.responseHandlers.has(handlerId);\n }\n\n /** A copy, so a handler that adds or removes one leaves this run unchanged */\n getResponseHandlers(handlerId: string): ResponseHandler<any>[] {\n return [...(this.responseHandlers.get(handlerId) ?? [])];\n }\n\n registerRequest(\n handlerId: string,\n handler: RequestHandler<any>,\n createSubRequest: RequestHandlerEntry['createSubRequest']\n ): void {\n this.requestHandlers.set(handlerId, {handler, createSubRequest});\n }\n\n unregisterRequest(handlerId: string): void {\n this.requestHandlers.delete(handlerId);\n }\n\n hasRequestHandler(handlerId: string): boolean {\n return this.requestHandlers.has(handlerId);\n }\n\n getRequestHandler(handlerId: string): RequestHandlerEntry | undefined {\n return this.requestHandlers.get(handlerId);\n }\n\n getRequestHandlerIds(): string[] {\n return Array.from(this.requestHandlers.keys());\n }\n\n clearHandlers(handlerId: string): void {\n this.errorHandlers.delete(handlerId);\n this.responseHandlers.delete(handlerId);\n this.requestHandlers.delete(handlerId);\n }\n\n clearAll(): void {\n this.errorHandlers.clear();\n this.responseHandlers.clear();\n this.requestHandlers.clear();\n }\n\n getHandlerIds(): string[] {\n const errorIds = Array.from(this.errorHandlers.keys());\n const responseIds = Array.from(this.responseHandlers.keys());\n const requestIds = Array.from(this.requestHandlers.keys());\n return [...new Set([...errorIds, ...responseIds, ...requestIds])];\n }\n\n getErrorTypes(handlerId: string): string[] {\n const handlerMap = this.errorHandlers.get(handlerId);\n return handlerMap ? Array.from(handlerMap.keys()) : [];\n }\n}\n\n/** A handler registered twice needs two removals */\nfunction removeFrom<H>(handlers: H[], handler: H): void {\n const index = handlers.indexOf(handler);\n if (index !== -1) handlers.splice(index, 1);\n}\n"],"mappings":"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"}
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { ErrorHandler, RequestHandler, ResponseHandler, SubRequest } from '../types.ts';
|
|
2
|
-
export interface RequestHandlerEntry {
|
|
3
|
-
handler: RequestHandler<any>;
|
|
4
|
-
createSubRequest: (params: any[]) => SubRequest<any>;
|
|
5
|
-
}
|
|
6
|
-
export declare class HandlersRegistry {
|
|
7
|
-
private errorHandlers;
|
|
8
|
-
private responseHandlers;
|
|
9
|
-
private requestHandlers;
|
|
10
|
-
register(handlerId: string, errorType: string, handler: ErrorHandler<any>): void;
|
|
11
|
-
unregister(handlerId: string, errorType: string, handler: ErrorHandler<any>): void;
|
|
12
|
-
hasHandler(handlerId: string, errorType: string): boolean;
|
|
13
|
-
getErrorHandlers(handlerId: string, errorType: string): ErrorHandler<any>[];
|
|
14
|
-
registerResponse(handlerId: string, handler: ResponseHandler<any>): void;
|
|
15
|
-
unregisterResponse(handlerId: string, handler: ResponseHandler<any>): void;
|
|
16
|
-
hasResponseHandler(handlerId: string): boolean;
|
|
17
|
-
getResponseHandlers(handlerId: string): ResponseHandler<any>[];
|
|
18
|
-
registerRequest(handlerId: string, handler: RequestHandler<any>, createSubRequest: RequestHandlerEntry['createSubRequest']): void;
|
|
19
|
-
unregisterRequest(handlerId: string): void;
|
|
20
|
-
hasRequestHandler(handlerId: string): boolean;
|
|
21
|
-
getRequestHandler(handlerId: string): RequestHandlerEntry | undefined;
|
|
22
|
-
getRequestHandlerIds(): string[];
|
|
23
|
-
clearHandlers(handlerId: string): void;
|
|
24
|
-
clearAll(): void;
|
|
25
|
-
getHandlerIds(): string[];
|
|
26
|
-
getErrorTypes(handlerId: string): string[];
|
|
27
|
-
}
|
|
28
|
-
//# sourceMappingURL=handlersRegistry.d.ts.map
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const require_src_lib_methods=require("./methods.cjs");let _mionjs_core=require("@mionjs/core");function hasHeadersSubsetParam(id,params){const method=require_src_lib_methods.getMethod(id);return method?method.type===_mionjs_core.HandlerType.headersMiddleware&&!!method.headersParam:params?.[0]instanceof _mionjs_core.HeadersSubset}function headersToRecord(headers){return headers?typeof Headers<"u"&&headers instanceof Headers?Object.fromEntries(headers.entries()):typeof headers[Symbol.iterator]=="function"?Object.fromEntries(headers):{...headers}:{}}function extractRequestHeaders(context){const headers={},subRequestIds=Object.keys(context.subRequestList);for(let i=0;i<subRequestIds.length;i++){const id=subRequestIds[i],subRequest=context.subRequestList[id];!subRequest||!hasHeadersSubsetParam(id,subRequest.params)||Object.assign(headers,extractHeadersFromParams(subRequest.params))}return headers}function extractHeadersFromParams(params){if(!params||params.length===0)throw new _mionjs_core.RpcError({type:"missing-headers-param",publicMessage:"HeadersMiddleware requires a HeadersSubset parameter."});const firstParam=params[0];if(firstParam instanceof _mionjs_core.HeadersSubset||firstParam&&typeof firstParam=="object"&&"headers"in firstParam&&typeof firstParam.headers=="object")return firstParam.headers;throw new _mionjs_core.RpcError({type:"invalid-headers-param",publicMessage:"HeadersMiddleware first parameter must be a HeadersSubset instance or object with headers property."})}function reconstructHeadersSubsetFromResponse(methodId,responseHeaders){const method=require_src_lib_methods.getMethod(methodId);if(!method?.headersReturn?.headerNames||method.headersReturn.headerNames.length===0)return;const headerNames=method.headersReturn.headerNames,headersMap={};for(const name of headerNames){const value=responseHeaders.get(name);value!=null&&(headersMap[name]=value)}if(Object.keys(headersMap).length>0)return(0,_mionjs_core.trustedHeadersSubset)(headersMap)}exports.extractRequestHeaders=extractRequestHeaders;exports.hasHeadersSubsetParam=hasHeadersSubsetParam;exports.headersToRecord=headersToRecord;exports.reconstructHeadersSubsetFromResponse=reconstructHeadersSubsetFromResponse;
|
|
2
|
-
|
|
3
|
-
//# sourceMappingURL=headers.cjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"headers.cjs","names":[],"sources":["../../../../src/lib/headers.ts"],"sourcesContent":["/* ########\n * 2026 mion\n * Author: Ma-jerez\n * License: MIT\n * The software is provided \"as is\", without warranty of any kind.\n * ######## */\n\nimport {HandlerType, HeadersSubset, RpcError, trustedHeadersSubset} from '@mionjs/core';\nimport {getMethod} from './methods.ts';\nimport type {CallContext} from '../types.ts';\n\n/** True when a subrequest's first param travels as HTTP headers rather than in the body; with no\n * cached metadata yet (a route's FIRST optimistic call) the value itself answers. */\nexport function hasHeadersSubsetParam(id: string, params: any[] | undefined): boolean {\n const method = getMethod(id);\n if (method) return method.type === HandlerType.headersMiddleware && !!method.headersParam;\n return params?.[0] instanceof HeadersSubset;\n}\n\n/** Spreading a `HeadersInit` only works for the plain-object form: a `Headers` instance has no own\n * enumerable properties and the `[name, value][]` form spreads as numeric indices. Internal, never exported. */\nexport function headersToRecord(headers: HeadersInit | undefined): Record<string, string> {\n if (!headers) return {};\n if (typeof Headers !== 'undefined' && headers instanceof Headers) return Object.fromEntries(headers.entries());\n // Any iterable of pairs (the `[name, value][]` form, a Map): spreading gives numeric indices, not headers.\n if (typeof (headers as Iterable<readonly [string, string]>)[Symbol.iterator] === 'function') {\n return Object.fromEntries(headers as Iterable<readonly [string, string]>);\n }\n return {...(headers as Record<string, string>)};\n}\n\nexport function extractRequestHeaders(context: CallContext): Record<string, string> {\n const headers: Record<string, string> = {};\n const subRequestIds = Object.keys(context.subRequestList);\n\n for (let i = 0; i < subRequestIds.length; i++) {\n const id = subRequestIds[i];\n const subRequest = context.subRequestList[id];\n if (!subRequest || !hasHeadersSubsetParam(id, subRequest.params)) continue;\n Object.assign(headers, extractHeadersFromParams(subRequest.params));\n }\n\n return headers;\n}\n\nfunction extractHeadersFromParams(params: any[]): Record<string, string> {\n if (!params || params.length === 0) {\n throw new RpcError({\n type: 'missing-headers-param',\n publicMessage: 'HeadersMiddleware requires a HeadersSubset parameter.',\n });\n }\n\n const firstParam = params[0];\n\n if (firstParam instanceof HeadersSubset) {\n return firstParam.headers as Record<string, string>;\n }\n\n if (firstParam && typeof firstParam === 'object' && 'headers' in firstParam && typeof firstParam.headers === 'object') {\n return firstParam.headers as Record<string, string>;\n }\n\n throw new RpcError({\n type: 'invalid-headers-param',\n publicMessage: 'HeadersMiddleware first parameter must be a HeadersSubset instance or object with headers property.',\n });\n}\n\nexport function reconstructHeadersSubsetFromResponse(\n methodId: string,\n responseHeaders: Headers\n): HeadersSubset<string, string> | undefined {\n const method = getMethod(methodId);\n\n if (!method?.headersReturn?.headerNames || method.headersReturn.headerNames.length === 0) {\n return undefined;\n }\n\n const headerNames = method.headersReturn.headerNames;\n const headersMap: Record<string, string> = {};\n\n for (const name of headerNames) {\n const value = responseHeaders.get(name);\n if (value !== undefined && value !== null) {\n headersMap[name] = value;\n }\n }\n\n if (Object.keys(headersMap).length > 0) {\n return trustedHeadersSubset(headersMap);\n }\n\n return undefined;\n}\n"],"mappings":"mKAaA,SAAgB,sBAAsB,GAAY,OAAoC,CACpF,MAAM,OAAS,wBAAA,UAAU,EAAE,EAC3B,OAAI,OAAe,OAAO,OAAS,aAAA,YAAY,mBAAqB,CAAC,CAAC,OAAO,aACtE,SAAS,CAAA,YAAc,aAAA,aAChC,CAIA,SAAgB,gBAAgB,QAA0D,CACxF,OAAK,QACD,OAAO,QAAY,KAAe,mBAAmB,QAAgB,OAAO,YAAY,QAAQ,QAAQ,CAAC,EAEzG,OAAQ,QAAgD,OAAO,QAAA,GAAc,WACxE,OAAO,YAAY,OAA8C,EAEnE,CAAC,GAAI,OAAkC,EANzB,CAAC,CAOxB,CAEA,SAAgB,sBAAsB,QAA8C,CAClF,MAAM,QAAkC,CAAC,EACnC,cAAgB,OAAO,KAAK,QAAQ,cAAc,EAExD,QAAS,EAAI,EAAG,EAAI,cAAc,OAAQ,IAAK,CAC7C,MAAM,GAAK,cAAc,CAAA,EACnB,WAAa,QAAQ,eAAe,EAAA,EACtC,CAAC,YAAc,CAAC,sBAAsB,GAAI,WAAW,MAAM,GAC/D,OAAO,OAAO,QAAS,yBAAyB,WAAW,MAAM,CAAC,CACpE,CAEA,OAAO,OACT,CAEA,SAAS,yBAAyB,OAAuC,CACvE,GAAI,CAAC,QAAU,OAAO,SAAW,EAC/B,MAAM,IAAI,aAAA,SAAS,CACjB,KAAM,wBACN,cAAe,uDACjB,CAAC,EAGH,MAAM,WAAa,OAAO,CAAA,EAM1B,GAJI,sBAAsB,aAAA,eAItB,YAAc,OAAO,YAAe,UAAY,YAAa,YAAc,OAAO,WAAW,SAAY,SAC3G,OAAO,WAAW,QAGpB,MAAM,IAAI,aAAA,SAAS,CACjB,KAAM,wBACN,cAAe,qGACjB,CAAC,CACH,CAEA,SAAgB,qCACd,SACA,gBAC2C,CAC3C,MAAM,OAAS,wBAAA,UAAU,QAAQ,EAEjC,GAAI,CAAC,QAAQ,eAAe,aAAe,OAAO,cAAc,YAAY,SAAW,EACrF,OAGF,MAAM,YAAc,OAAO,cAAc,YACnC,WAAqC,CAAC,EAE5C,UAAW,QAAQ,YAAa,CAC9B,MAAM,MAAQ,gBAAgB,IAAI,IAAI,EACX,OAAU,OACnC,WAAW,IAAA,EAAQ,MAEvB,CAEA,GAAI,OAAO,KAAK,UAAU,EAAE,OAAS,EACnC,SAAA,aAAA,sBAA4B,UAAU,CAI1C"}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import { HeadersSubset } from '@mionjs/core';
|
|
2
|
-
import { CallContext } from '../types.ts';
|
|
3
|
-
export declare function hasHeadersSubsetParam(id: string, params: any[] | undefined): boolean;
|
|
4
|
-
export declare function headersToRecord(headers: HeadersInit | undefined): Record<string, string>;
|
|
5
|
-
export declare function extractRequestHeaders(context: CallContext): Record<string, string>;
|
|
6
|
-
export declare function reconstructHeadersSubsetFromResponse(methodId: string, responseHeaders: Headers): HeadersSubset<string, string> | undefined;
|
|
7
|
-
//# sourceMappingURL=headers.d.ts.map
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});let _mionjs_core=require("@mionjs/core");function methodRootHashes(metadata){const parser=metadata.options?.parser??_mionjs_core.DEFAULT_PARSER,roots=[],addSet=(jitHash,strategy)=>{if(!(!jitHash||jitHash===_mionjs_core.EMPTY_HASH))for(const hash of Object.values((0,_mionjs_core.getJitFnHashes)(jitHash,strategy)))typeof hash=="string"&&roots.push(hash)};return addSet(metadata.paramsJitHash,parser.params),addSet(metadata.returnJitHash,parser.return),metadata.headersParam&&addSet(metadata.headersParam.jitHash,"mutate"),metadata.headersReturn&&addSet(metadata.headersReturn.jitHash,"mutate"),roots}function findOrphans(graph){const reachedDeps=new Set,reachedPureFns=new Set,pending=[];for(const metadata of Object.values(graph.methods))for(const hash of methodRootHashes(metadata))graph.deps[hash]&&!reachedDeps.has(hash)&&(reachedDeps.add(hash),pending.push(hash));const reachPureFn=key=>{if(!reachedPureFns.has(key)){reachedPureFns.add(key);for(const nested of graph.pureFns[key]?.pureFnDependencies??[])reachPureFn(nested)}};for(;pending.length;){const entry=graph.deps[pending.pop()];for(const hash of entry?.rtDependencies??[])!graph.deps[hash]||reachedDeps.has(hash)||(reachedDeps.add(hash),pending.push(hash));for(const key of entry?.pureFnDependencies??[])reachPureFn(key)}const orphans=[];for(const hash of Object.keys(graph.deps))reachedDeps.has(hash)||orphans.push(["j",hash]);for(const key of Object.keys(graph.pureFns))reachedPureFns.has(key)||orphans.push(["p",key]);return orphans}exports.findOrphans=findOrphans;
|
|
2
|
-
|
|
3
|
-
//# sourceMappingURL=metadataEviction.cjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"metadataEviction.cjs","names":[],"sources":["../../../../src/lib/metadataEviction.ts"],"sourcesContent":["/* ########\n * 2026 mion\n * Author: Ma-jerez\n * License: MIT\n * The software is provided \"as is\", without warranty of any kind.\n * ######## */\n\nimport {DEFAULT_PARSER, EMPTY_HASH, getJitFnHashes} from '@mionjs/core';\nimport type {CompiledFnData, MethodWithOptions, PureFunctionData} from '@mionjs/core';\nimport type {MetadataRecordKey} from './storage.ts';\n\n/** The stored cache as one graph: methods point at compiled functions by hash, and those point at\n * each other. Everything already parsed by the hydrator, so the sweep costs no extra reads. */\nexport interface CacheGraph {\n /** by methodId */\n methods: Record<string, MethodWithOptions>;\n /** by compiled function hash */\n deps: Record<string, CompiledFnData>;\n /** by `${namespace}::${fnName}` */\n pureFns: Record<string, PureFunctionData>;\n}\n\n/** Every compiled function hash the method itself names, across both wires and both header sets. */\nfunction methodRootHashes(metadata: MethodWithOptions): string[] {\n const parser = metadata.options?.parser ?? DEFAULT_PARSER;\n const roots: string[] = [];\n // a root is anything the method COULD reach; a hash it never uses is simply absent from the store\n const addSet = (jitHash: string, strategy: Parameters<typeof getJitFnHashes>[1]) => {\n if (!jitHash || jitHash === EMPTY_HASH) return;\n // the optional hashes are absent on the returned shape, so only the real strings become roots\n for (const hash of Object.values(getJitFnHashes(jitHash, strategy)) as (string | undefined)[]) {\n if (typeof hash === 'string') roots.push(hash);\n }\n };\n addSet(metadata.paramsJitHash, parser.params);\n addSet(metadata.returnJitHash, parser.return);\n if (metadata.headersParam) addSet(metadata.headersParam.jitHash, 'mutate');\n if (metadata.headersReturn) addSet(metadata.headersReturn.jitHash, 'mutate');\n return roots;\n}\n\n/** The compiled functions no stored method can reach any more. Hashes are content addresses, so an entry is\n * never stale, only unreachable: a deploy rewrites a method's row and leaves the old hashes behind. */\nexport function findOrphans(graph: CacheGraph): MetadataRecordKey[] {\n const reachedDeps = new Set<string>();\n const reachedPureFns = new Set<string>();\n const pending: string[] = [];\n\n for (const metadata of Object.values(graph.methods)) {\n for (const hash of methodRootHashes(metadata)) {\n if (graph.deps[hash] && !reachedDeps.has(hash)) {\n reachedDeps.add(hash);\n pending.push(hash);\n }\n }\n }\n\n const reachPureFn = (key: string) => {\n if (reachedPureFns.has(key)) return;\n reachedPureFns.add(key);\n for (const nested of graph.pureFns[key]?.pureFnDependencies ?? []) reachPureFn(nested);\n };\n\n while (pending.length) {\n const entry = graph.deps[pending.pop() as string];\n for (const hash of entry?.rtDependencies ?? []) {\n if (!graph.deps[hash] || reachedDeps.has(hash)) continue;\n reachedDeps.add(hash);\n pending.push(hash);\n }\n for (const key of entry?.pureFnDependencies ?? []) reachPureFn(key);\n }\n\n const orphans: MetadataRecordKey[] = [];\n for (const hash of Object.keys(graph.deps)) if (!reachedDeps.has(hash)) orphans.push(['j', hash]);\n for (const key of Object.keys(graph.pureFns)) if (!reachedPureFns.has(key)) orphans.push(['p', key]);\n return orphans;\n}\n"],"mappings":"4GAuBA,SAAS,iBAAiB,SAAuC,CAC/D,MAAM,OAAS,SAAS,SAAS,QAAU,aAAA,eACrC,MAAkB,CAAC,EAEnB,OAAA,CAAU,QAAiB,WAAmD,CAClF,GAAI,GAAC,SAAW,UAAY,aAAA,YAE5B,UAAW,QAAQ,OAAO,UAAA,aAAA,gBAAsB,QAAS,QAAQ,CAAC,EAC5D,OAAO,MAAS,UAAU,MAAM,KAAK,IAAI,CAEjD,EACA,cAAO,SAAS,cAAe,OAAO,MAAM,EAC5C,OAAO,SAAS,cAAe,OAAO,MAAM,EACxC,SAAS,cAAc,OAAO,SAAS,aAAa,QAAS,QAAQ,EACrE,SAAS,eAAe,OAAO,SAAS,cAAc,QAAS,QAAQ,EACpE,KACT,CAIA,SAAgB,YAAY,MAAwC,CAClE,MAAM,YAAc,IAAI,IAClB,eAAiB,IAAI,IACrB,QAAoB,CAAC,EAE3B,UAAW,YAAY,OAAO,OAAO,MAAM,OAAO,EAChD,UAAW,QAAQ,iBAAiB,QAAQ,EACtC,MAAM,KAAK,IAAA,GAAS,CAAC,YAAY,IAAI,IAAI,IAC3C,YAAY,IAAI,IAAI,EACpB,QAAQ,KAAK,IAAI,GAKvB,MAAM,YAAe,KAAgB,CACnC,GAAI,gBAAe,IAAI,GAAG,EAC1B,gBAAe,IAAI,GAAG,EACtB,UAAW,UAAU,MAAM,QAAQ,GAAA,GAAM,oBAAsB,CAAC,EAAG,YAAY,MAAM,EACvF,EAEA,KAAO,QAAQ,QAAQ,CACrB,MAAM,MAAQ,MAAM,KAAK,QAAQ,IAAI,CAAA,EACrC,UAAW,QAAQ,OAAO,gBAAkB,CAAC,EACvC,CAAC,MAAM,KAAK,IAAA,GAAS,YAAY,IAAI,IAAI,IAC7C,YAAY,IAAI,IAAI,EACpB,QAAQ,KAAK,IAAI,GAEnB,UAAW,OAAO,OAAO,oBAAsB,CAAC,EAAG,YAAY,GAAG,CACpE,CAEA,MAAM,QAA+B,CAAC,EACtC,UAAW,QAAQ,OAAO,KAAK,MAAM,IAAI,EAAQ,YAAY,IAAI,IAAI,GAAG,QAAQ,KAAK,CAAC,IAAK,IAAI,CAAC,EAChG,UAAW,OAAO,OAAO,KAAK,MAAM,OAAO,EAAQ,eAAe,IAAI,GAAG,GAAG,QAAQ,KAAK,CAAC,IAAK,GAAG,CAAC,EACnG,OAAO,OACT"}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { CompiledFnData, MethodWithOptions, PureFunctionData } from '@mionjs/core';
|
|
2
|
-
import { MetadataRecordKey } from './storage.ts';
|
|
3
|
-
export interface CacheGraph {
|
|
4
|
-
methods: Record<string, MethodWithOptions>;
|
|
5
|
-
deps: Record<string, CompiledFnData>;
|
|
6
|
-
pureFns: Record<string, PureFunctionData>;
|
|
7
|
-
}
|
|
8
|
-
export declare function findOrphans(graph: CacheGraph): MetadataRecordKey[];
|
|
9
|
-
//# sourceMappingURL=metadataEviction.d.ts.map
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});var MIDDLEWARE_TARGET=Symbol("mion.middlewareTarget"),fetchers=new WeakMap,readTarget=middleware=>middleware[MIDDLEWARE_TARGET];function middlewareTargetOf(middleware){const target=readTarget(middleware);if(!target)throw new Error("Expected a middleware from the client, like middlewares.mionFetchMetadata");return target}function setMetadataFetcher(registry,fetcher){fetchers.set(registry,fetcher)}function getMetadataFetcher(registry){return registry&&fetchers.get(registry)}function metadataFetcherOf(middleware){return getMetadataFetcher(readTarget(middleware)?.registry)}exports.MIDDLEWARE_TARGET=MIDDLEWARE_TARGET;exports.getMetadataFetcher=getMetadataFetcher;exports.metadataFetcherOf=metadataFetcherOf;exports.middlewareTargetOf=middlewareTargetOf;exports.setMetadataFetcher=setMetadataFetcher;
|
|
2
|
-
|
|
3
|
-
//# sourceMappingURL=metadataFetcher.cjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"metadataFetcher.cjs","names":[],"sources":["../../../../src/lib/metadataFetcher.ts"],"sourcesContent":["/* ########\n * 2026 mion\n * Author: Ma-jerez\n * License: MIT\n * The software is provided \"as is\", without warranty of any kind.\n * ######## */\n\n// Internal hooks between the dispatch and `useFetchMetadata`. Never exported from the package: the public\n// middleware type stays hooks only, and a client that never sets metadata fetching up ships none of it.\n\nimport type {RpcError} from '@mionjs/core';\nimport type {ClientCallContext, ClientOptions, RequestErrors} from '../types.ts';\nimport type {HandlersRegistry} from './handlersRegistry.ts';\n\n/** What `useFetchMetadata` hands the dispatch, once per client. */\nexport interface MetadataFetcher {\n /** Rows for the given ids without running any route; route sync refetches through it. */\n fetchRows(ids: string[], routePointer: string[], options: ClientOptions, signal?: AbortSignal): Promise<void>;\n startCall(context: ClientCallContext): MetadataCall;\n}\n\n/** One call's metadata state, driven by the dispatch attempt by attempt. */\nexport interface MetadataCall {\n /** the metadata middleware's id: the rows a call asks for ride the request under it */\n readonly id: string;\n /** Before the chain is read. `ids` omits its own entry; `optimistic`: sent before rows are known, in plain wire forms. */\n prepare(skipOptimistic: boolean): Promise<{ids: string[]; optimistic: boolean}>;\n /** Optimistic attempt: asks the server for the rows of every id in the call. */\n askRows(): void;\n /** Rows for the given ids without running any route: `typeErrors()`, a body that cannot go out plain. */\n fetchRows(ids: string[], signal?: AbortSignal): Promise<void>;\n /** Takes this call's rows out of the raw body before anything is decoded; returns a refusal to put back. */\n readRows(parsedBody: Record<string, unknown>): Record<string, RpcError<string>> | undefined;\n /** After a failed attempt: true when a resend with fresh rows can fix it. Called at most once per call. */\n shouldResend(errors: RequestErrors): Promise<boolean>;\n /** a store write the browser refused, reported once in a later call's @thrownErrors */\n takeError(): RpcError<string> | undefined;\n}\n\n/** A middleware's client and id, read off `middlewares.<name>` through a key no public type names. */\nexport const MIDDLEWARE_TARGET = Symbol('mion.middlewareTarget');\n\nexport interface MiddlewareTarget {\n id: string;\n registry: HandlersRegistry;\n}\n\nconst fetchers = new WeakMap<HandlersRegistry, MetadataFetcher>();\n\nconst readTarget = (middleware: object) => (middleware as {[MIDDLEWARE_TARGET]?: MiddlewareTarget})[MIDDLEWARE_TARGET];\n\nexport function middlewareTargetOf(middleware: object): MiddlewareTarget {\n const target = readTarget(middleware);\n if (!target) throw new Error('Expected a middleware from the client, like middlewares.mionFetchMetadata');\n return target;\n}\n\nexport function setMetadataFetcher(registry: HandlersRegistry, fetcher: MetadataFetcher): void {\n fetchers.set(registry, fetcher);\n}\n\nexport function getMetadataFetcher(registry: HandlersRegistry | undefined): MetadataFetcher | undefined {\n return registry && fetchers.get(registry);\n}\n\n/** The fetcher of the client a middleware belongs to, if it set one up; route sync refetches through it. */\nexport function metadataFetcherOf(middleware: object): MetadataFetcher | undefined {\n return getMetadataFetcher(readTarget(middleware)?.registry);\n}\n"],"mappings":"mEAwCA,IAAa,kBAAoB,OAAO,uBAAuB,EAOzD,SAAW,IAAI,QAEf,WAAc,YAAwB,WAAwD,iBAAA,EAEpG,SAAgB,mBAAmB,WAAsC,CACvE,MAAM,OAAS,WAAW,UAAU,EACpC,GAAI,CAAC,OAAQ,MAAM,IAAI,MAAM,2EAA2E,EACxG,OAAO,MACT,CAEA,SAAgB,mBAAmB,SAA4B,QAAgC,CAC7F,SAAS,IAAI,SAAU,OAAO,CAChC,CAEA,SAAgB,mBAAmB,SAAqE,CACtG,OAAO,UAAY,SAAS,IAAI,QAAQ,CAC1C,CAGA,SAAgB,kBAAkB,WAAiD,CACjF,OAAO,mBAAmB,WAAW,UAAU,GAAG,QAAQ,CAC5D"}
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import { RpcError } from '@mionjs/core';
|
|
2
|
-
import { ClientCallContext, ClientOptions, RequestErrors } from '../types.ts';
|
|
3
|
-
import { HandlersRegistry } from './handlersRegistry.ts';
|
|
4
|
-
export interface MetadataFetcher {
|
|
5
|
-
fetchRows(ids: string[], routePointer: string[], options: ClientOptions, signal?: AbortSignal): Promise<void>;
|
|
6
|
-
startCall(context: ClientCallContext): MetadataCall;
|
|
7
|
-
}
|
|
8
|
-
export interface MetadataCall {
|
|
9
|
-
readonly id: string;
|
|
10
|
-
prepare(skipOptimistic: boolean): Promise<{
|
|
11
|
-
ids: string[];
|
|
12
|
-
optimistic: boolean;
|
|
13
|
-
}>;
|
|
14
|
-
askRows(): void;
|
|
15
|
-
fetchRows(ids: string[], signal?: AbortSignal): Promise<void>;
|
|
16
|
-
readRows(parsedBody: Record<string, unknown>): Record<string, RpcError<string>> | undefined;
|
|
17
|
-
shouldResend(errors: RequestErrors): Promise<boolean>;
|
|
18
|
-
takeError(): RpcError<string> | undefined;
|
|
19
|
-
}
|
|
20
|
-
export declare const MIDDLEWARE_TARGET: unique symbol;
|
|
21
|
-
export interface MiddlewareTarget {
|
|
22
|
-
id: string;
|
|
23
|
-
registry: HandlersRegistry;
|
|
24
|
-
}
|
|
25
|
-
export declare function middlewareTargetOf(middleware: object): MiddlewareTarget;
|
|
26
|
-
export declare function setMetadataFetcher(registry: HandlersRegistry, fetcher: MetadataFetcher): void;
|
|
27
|
-
export declare function getMetadataFetcher(registry: HandlersRegistry | undefined): MetadataFetcher | undefined;
|
|
28
|
-
export declare function metadataFetcherOf(middleware: object): MetadataFetcher | undefined;
|
|
29
|
-
//# sourceMappingURL=metadataFetcher.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const require_src_lib_clientMethodsMetadata=require("./clientMethodsMetadata.cjs"),require_src_lib_fetchRemoteMethodsMetadata=require("./fetchRemoteMethodsMetadata.cjs"),require_src_lib_apiVersionRecovery=require("./apiVersionRecovery.cjs");require("@mionjs/run-types/formats");exports.fetchRemoteMethodsMetadata=require_src_lib_fetchRemoteMethodsMetadata.fetchRemoteMethodsMetadata;exports.forgetFetchedMetadata=require_src_lib_clientMethodsMetadata.forgetFetchedMetadata;exports.hydrateMetadataCache=require_src_lib_clientMethodsMetadata.hydrateMetadataCache;exports.installMethodRows=require_src_lib_clientMethodsMetadata.installMethodRows;exports.purgeHydratedMetadata=require_src_lib_clientMethodsMetadata.purgeHydratedMetadata;exports.takeMetadataCacheError=require_src_lib_clientMethodsMetadata.takeMetadataCacheError;exports.unverifiedIds=require_src_lib_apiVersionRecovery.unverifiedIds;exports.verifyMethodRows=require_src_lib_apiVersionRecovery.verifyMethodRows;exports.wasHydratedFromCache=require_src_lib_clientMethodsMetadata.wasHydratedFromCache;
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
export { forgetFetchedMetadata, hydrateMetadataCache, installMethodRows, purgeHydratedMetadata, takeMetadataCacheError, wasHydratedFromCache, } from './clientMethodsMetadata.ts';
|
|
2
|
-
export { fetchRemoteMethodsMetadata } from './fetchRemoteMethodsMetadata.ts';
|
|
3
|
-
export { unverifiedIds, verifyMethodRows } from './apiVersionRecovery.ts';
|
|
4
|
-
//# sourceMappingURL=metadataFromServer.d.ts.map
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
var __create=Object.create;var __defProp=Object.defineProperty;var __getOwnPropDesc=Object.getOwnPropertyDescriptor;var __getOwnPropNames=Object.getOwnPropertyNames;var __getProtoOf=Object.getPrototypeOf,__hasOwnProp=Object.prototype.hasOwnProperty;var __copyProps=(to,from,except,desc)=>{if(from&&typeof from=="object"||typeof from=="function")for(let key of __getOwnPropNames(from))!__hasOwnProp.call(to,key)&&key!==except&&__defProp(to,key,{get:()=>from[key],enumerable:!(desc=__getOwnPropDesc(from,key))||desc.enumerable});return to};var __toESM=(mod,isNodeMode,target)=>(target=mod!=null?__create(__getProtoOf(mod)):{},__copyProps(isNodeMode||!mod||!mod.__esModule?__defProp(target,"default",{value:mod,enumerable:!0}):target,mod));Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});let _mionjs_core=require("@mionjs/core");var laneModule,loading;function loadMetadataFromServer(){return laneModule?Promise.resolve(laneModule):(loading??=import("#metadata-from-server").then(loaded=>(laneModule=loaded,loaded)).catch(error=>{throw loading=void 0,laneLoadError(error)}),loading)}function loadedMetadataFromServer(){return laneModule}function resetMetadataFromServer(){laneModule=void 0,loading=void 0}function laneLoadError(error){return new _mionjs_core.RpcError({type:"metadata-load-error",publicMessage:"Could not load the code that asks the server how a route works. Build with client routes bundled to ship every route the client calls, or check that the app can load its own chunks.",originalError:error instanceof Error?error:void 0})}exports.loadMetadataFromServer=loadMetadataFromServer;exports.loadedMetadataFromServer=loadedMetadataFromServer;exports.resetMetadataFromServer=resetMetadataFromServer;
|
|
2
|
-
|
|
3
|
-
//# sourceMappingURL=metadataFromServerLoader.cjs.map
|