@mastra/core
Version:
Mastra is a framework for building AI-powered applications and agents with a modern TypeScript stack.
1 lines • 14.4 kB
Source Map (JSON)
{"version":3,"sources":["../src/mastra/types.ts","../src/request-context/index.ts"],"names":[],"mappings":"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","file":"chunk-CAVARKYS.cjs","sourcesContent":["/**\n * Selects a specific version of a primitive by ID or by publication status.\n */\nexport type VersionSelector = { versionId: string } | { status: 'draft' | 'published' };\n\n/**\n * Per-primitive version overrides.\n * Keys are primitive IDs, values select which version to resolve.\n */\nexport type VersionOverrides = {\n agents?: Record<string, VersionSelector>;\n // Future: tools, workflows, etc.\n};\n\n/**\n * Shallow-merge two VersionOverrides objects.\n * Per-category, entries in `overrides` win over entries in `base`.\n */\nexport function mergeVersionOverrides(\n base: VersionOverrides | undefined,\n overrides: VersionOverrides | undefined,\n): VersionOverrides | undefined {\n if (!base) return overrides;\n if (!overrides) return base;\n\n return {\n ...base,\n ...overrides,\n agents: {\n ...base.agents,\n ...overrides.agents,\n },\n };\n}\n","type RecordToTuple<T> = {\n [K in keyof T]: [K, T[K]];\n}[keyof T][];\n\n/**\n * Reserved key for setting resourceId from middleware.\n * When set in RequestContext, this takes precedence over client-provided values\n * for security (prevents attackers from hijacking another user's memory).\n *\n * @example\n * ```typescript\n * // In your auth middleware:\n * const requestContext = c.get('requestContext');\n * requestContext.set(MASTRA_RESOURCE_ID_KEY, authenticatedUser.id);\n * ```\n */\nexport const MASTRA_RESOURCE_ID_KEY = 'mastra__resourceId';\n\n/**\n * Reserved key for setting threadId from middleware.\n * When set in RequestContext, this takes precedence over client-provided values\n * for security (prevents attackers from hijacking another user's memory).\n *\n * @example\n * ```typescript\n * // In your auth middleware:\n * const requestContext = c.get('requestContext');\n * requestContext.set(MASTRA_THREAD_ID_KEY, threadId);\n * ```\n */\nexport const MASTRA_THREAD_ID_KEY = 'mastra__threadId';\n\n/**\n * Reserved key for storing version overrides on RequestContext.\n * When set, sub-agent delegation resolves versioned agents from these overrides.\n *\n * @example\n * ```typescript\n * requestContext.set(MASTRA_VERSIONS_KEY, {\n * agents: { 'researcher-agent': { versionId: '123' } },\n * });\n * ```\n */\nexport const MASTRA_VERSIONS_KEY = 'mastra__versions';\n\n/**\n * Reserved key for storing the raw auth token from the incoming request.\n * Used by the editor to forward authentication when connecting to MCP servers\n * that require the same auth as the Mastra server itself.\n */\nexport const MASTRA_AUTH_TOKEN_KEY = 'mastra__authToken';\n\nexport type { VersionOverrides, VersionSelector } from '../mastra/types';\nexport { mergeVersionOverrides } from '../mastra/types';\n\n/**\n * Marker thrown by `RequestContext.toJSON()` when it detects cyclic re-entry.\n *\n * Cyclic re-entry happens when a stored value transitively references another\n * `RequestContext` whose `toJSON()` is already on the call stack. `JSON.stringify`\n * inside `isSerializable` then walks into that context, V8 invokes its\n * `toJSON()`, which iterates its registry and calls `JSON.stringify` on values\n * that may walk back through the first context — and so on. Each step is a\n * fresh `JSON.stringify` call with a fresh internal cycle stack, so V8's\n * built-in cycle detection never trips and the recursion would pin one CPU\n * core at 100% indefinitely.\n *\n * The fix: throw this marker on reentry. The marker propagates upward through\n * `isSerializable`'s nested catches (which re-throw it) until it reaches the\n * outermost `toJSON()`'s `isSerializable` — there it is swallowed and the\n * offending key is filtered, the same way in-value circular references are\n * filtered today.\n */\nclass CyclicRequestContextToJSONError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'CyclicRequestContextToJSONError';\n }\n}\n\n/**\n * Tracks `RequestContext` instances whose `toJSON()` is currently on the call\n * stack. Used to detect cyclic re-entry. Stored as a `WeakSet` so entries are\n * garbage-collected with their owning context.\n */\nconst _toJSONInProgress = new WeakSet<RequestContext<any>>();\n\n/**\n * Nesting depth of active `toJSON()` calls. The outermost call (depth === 1\n * after entry) catches the cyclic marker error and filters the offending\n * value; inner calls re-throw so the marker propagates to the outermost.\n */\nlet _toJSONDepth = 0;\n\nexport class RequestContext<Values extends Record<string, any> | unknown = unknown> {\n private registry = new Map<string, unknown>();\n\n constructor(\n iterable?: Values extends Record<string, any>\n ? RecordToTuple<Partial<Values>>\n : Iterable<readonly [string, unknown]>,\n ) {\n if (iterable && typeof iterable === 'object' && typeof (iterable as any)[Symbol.iterator] !== 'function') {\n this.registry = new Map(Object.entries(iterable));\n } else {\n this.registry = new Map(iterable);\n }\n }\n\n /**\n * set a value with strict typing if `Values` is a Record and the key exists in it.\n */\n public set<K extends Values extends Record<string, any> ? keyof Values : string>(\n key: K,\n value: Values extends Record<string, any> ? (K extends keyof Values ? Values[K] : never) : unknown,\n ): void {\n // The type assertion `key as string` is safe because K always extends string ultimately.\n this.registry.set(key as string, value);\n }\n\n /**\n * Get a value with its type\n */\n public get<\n K extends Values extends Record<string, any> ? keyof Values : string,\n R = Values extends Record<string, any> ? (K extends keyof Values ? Values[K] : never) : unknown,\n >(key: K): R {\n return this.registry.get(key as string) as R;\n }\n\n /**\n * Check if a key exists in the container\n */\n public has<K extends Values extends Record<string, any> ? keyof Values : string>(key: K): boolean {\n return this.registry.has(key);\n }\n\n /**\n * Delete a value by key\n */\n public delete<K extends Values extends Record<string, any> ? keyof Values : string>(key: K): boolean {\n return this.registry.delete(key);\n }\n\n /**\n * Clear all values from the container\n */\n public clear(): void {\n this.registry.clear();\n }\n\n /**\n * Get all keys in the container\n */\n public keys(): IterableIterator<Values extends Record<string, any> ? keyof Values : string> {\n return this.registry.keys() as IterableIterator<Values extends Record<string, any> ? keyof Values : string>;\n }\n\n /**\n * Get all values in the container\n */\n public values(): IterableIterator<Values extends Record<string, any> ? Values[keyof Values] : unknown> {\n return this.registry.values() as IterableIterator<\n Values extends Record<string, any> ? Values[keyof Values] : unknown\n >;\n }\n\n /**\n * Get all entries in the container.\n * Returns a discriminated union of tuples for proper type narrowing when iterating.\n */\n public entries(): IterableIterator<\n Values extends Record<string, any> ? { [K in keyof Values]: [K, Values[K]] }[keyof Values] : [string, unknown]\n > {\n return this.registry.entries() as IterableIterator<\n Values extends Record<string, any> ? { [K in keyof Values]: [K, Values[K]] }[keyof Values] : [string, unknown]\n >;\n }\n\n /**\n * Get the size of the container\n */\n public size(): number {\n return this.registry.size;\n }\n\n /**\n * Execute a function for each entry in the container.\n * The callback receives properly typed key-value pairs.\n */\n public forEach<K extends Values extends Record<string, any> ? keyof Values : string>(\n callbackfn: (\n value: Values extends Record<string, any> ? (K extends keyof Values ? Values[K] : unknown) : unknown,\n key: K,\n map: Map<string, unknown>,\n ) => void,\n ): void {\n this.registry.forEach(callbackfn as (value: unknown, key: string, map: Map<string, unknown>) => void);\n }\n\n /**\n * Custom JSON serialization method.\n * Converts the internal Map to a plain object for proper JSON serialization.\n * Non-serializable values (functions, symbols, RPC proxies, in-value\n * circular references, and values whose serialization re-enters this\n * `toJSON` via cross-context back-references) are skipped to prevent\n * serialization errors when storing to database.\n *\n * Reentry safety: if a stored value's `isSerializable` probe re-enters\n * `toJSON()` on this same instance (through a chain of RequestContexts\n * holding references to each other), we throw `CyclicRequestContextToJSONError`.\n * Inner `isSerializable` calls re-throw the marker; the outermost\n * `isSerializable` swallows it and filters the offending key, the same\n * way it filters in-value circular references today.\n */\n public toJSON(): Record<string, any> {\n if (_toJSONInProgress.has(this)) {\n throw new CyclicRequestContextToJSONError(\n 'RequestContext.toJSON: detected cyclic re-entry (a stored value transitively references this context)',\n );\n }\n _toJSONInProgress.add(this);\n _toJSONDepth++;\n try {\n const result: Record<string, any> = {};\n for (const [key, value] of this.registry.entries()) {\n if (this.isSerializable(value)) {\n result[key] = value;\n }\n }\n return result;\n } finally {\n _toJSONInProgress.delete(this);\n _toJSONDepth--;\n }\n }\n\n /**\n * Check if a value can be safely serialized to JSON.\n *\n * Re-throws `CyclicRequestContextToJSONError` when called from a nested\n * `toJSON()` (`_toJSONDepth > 1`), so the marker propagates up to the\n * outermost `toJSON()`'s `isSerializable`, which then swallows it and\n * filters the offending key. This is what lets the outermost call return\n * a clean JSON-safe dict for cross-context cycles.\n */\n private isSerializable(value: unknown): boolean {\n if (value === null || value === undefined) return true;\n if (typeof value === 'function') return false;\n if (typeof value === 'symbol') return false;\n if (typeof value !== 'object') return true;\n\n try {\n JSON.stringify(value);\n return true;\n } catch (e) {\n if (e instanceof CyclicRequestContextToJSONError && _toJSONDepth > 1) {\n throw e;\n }\n return false;\n }\n }\n\n /**\n * Get all values as a typed object for destructuring.\n * Returns Record<string, any> when untyped, or the Values type when typed.\n *\n * @example\n * ```typescript\n * const ctx = new RequestContext<{ userId: string; apiKey: string }>();\n * ctx.set('userId', 'user-123');\n * ctx.set('apiKey', 'key-456');\n * const { userId, apiKey } = ctx.all;\n * ```\n */\n public get all(): Values extends Record<string, any> ? Values : Record<string, any> {\n return Object.fromEntries(this.registry) as Values extends Record<string, any> ? Values : Record<string, any>;\n }\n}\n"]}