@mastra/core
Version:
Mastra is a framework for building AI-powered applications and agents with a modern TypeScript stack.
185 lines (182 loc) • 5.4 kB
JavaScript
;
// src/mastra/types.ts
function mergeVersionOverrides(base, overrides) {
if (!base) return overrides;
if (!overrides) return base;
return {
...base,
...overrides,
agents: {
...base.agents,
...overrides.agents
}
};
}
// src/request-context/index.ts
var MASTRA_RESOURCE_ID_KEY = "mastra__resourceId";
var MASTRA_THREAD_ID_KEY = "mastra__threadId";
var MASTRA_VERSIONS_KEY = "mastra__versions";
var MASTRA_AUTH_TOKEN_KEY = "mastra__authToken";
var CyclicRequestContextToJSONError = class extends Error {
constructor(message) {
super(message);
this.name = "CyclicRequestContextToJSONError";
}
};
var _toJSONInProgress = /* @__PURE__ */ new WeakSet();
var _toJSONDepth = 0;
var RequestContext = class {
registry = /* @__PURE__ */ new Map();
constructor(iterable) {
if (iterable && typeof iterable === "object" && typeof iterable[Symbol.iterator] !== "function") {
this.registry = new Map(Object.entries(iterable));
} else {
this.registry = new Map(iterable);
}
}
/**
* set a value with strict typing if `Values` is a Record and the key exists in it.
*/
set(key, value) {
this.registry.set(key, value);
}
/**
* Get a value with its type
*/
get(key) {
return this.registry.get(key);
}
/**
* Check if a key exists in the container
*/
has(key) {
return this.registry.has(key);
}
/**
* Delete a value by key
*/
delete(key) {
return this.registry.delete(key);
}
/**
* Clear all values from the container
*/
clear() {
this.registry.clear();
}
/**
* Get all keys in the container
*/
keys() {
return this.registry.keys();
}
/**
* Get all values in the container
*/
values() {
return this.registry.values();
}
/**
* Get all entries in the container.
* Returns a discriminated union of tuples for proper type narrowing when iterating.
*/
entries() {
return this.registry.entries();
}
/**
* Get the size of the container
*/
size() {
return this.registry.size;
}
/**
* Execute a function for each entry in the container.
* The callback receives properly typed key-value pairs.
*/
forEach(callbackfn) {
this.registry.forEach(callbackfn);
}
/**
* Custom JSON serialization method.
* Converts the internal Map to a plain object for proper JSON serialization.
* Non-serializable values (functions, symbols, RPC proxies, in-value
* circular references, and values whose serialization re-enters this
* `toJSON` via cross-context back-references) are skipped to prevent
* serialization errors when storing to database.
*
* Reentry safety: if a stored value's `isSerializable` probe re-enters
* `toJSON()` on this same instance (through a chain of RequestContexts
* holding references to each other), we throw `CyclicRequestContextToJSONError`.
* Inner `isSerializable` calls re-throw the marker; the outermost
* `isSerializable` swallows it and filters the offending key, the same
* way it filters in-value circular references today.
*/
toJSON() {
if (_toJSONInProgress.has(this)) {
throw new CyclicRequestContextToJSONError(
"RequestContext.toJSON: detected cyclic re-entry (a stored value transitively references this context)"
);
}
_toJSONInProgress.add(this);
_toJSONDepth++;
try {
const result = {};
for (const [key, value] of this.registry.entries()) {
if (this.isSerializable(value)) {
result[key] = value;
}
}
return result;
} finally {
_toJSONInProgress.delete(this);
_toJSONDepth--;
}
}
/**
* Check if a value can be safely serialized to JSON.
*
* Re-throws `CyclicRequestContextToJSONError` when called from a nested
* `toJSON()` (`_toJSONDepth > 1`), so the marker propagates up to the
* outermost `toJSON()`'s `isSerializable`, which then swallows it and
* filters the offending key. This is what lets the outermost call return
* a clean JSON-safe dict for cross-context cycles.
*/
isSerializable(value) {
if (value === null || value === void 0) return true;
if (typeof value === "function") return false;
if (typeof value === "symbol") return false;
if (typeof value !== "object") return true;
try {
JSON.stringify(value);
return true;
} catch (e) {
if (e instanceof CyclicRequestContextToJSONError && _toJSONDepth > 1) {
throw e;
}
return false;
}
}
/**
* Get all values as a typed object for destructuring.
* Returns Record<string, any> when untyped, or the Values type when typed.
*
* @example
* ```typescript
* const ctx = new RequestContext<{ userId: string; apiKey: string }>();
* ctx.set('userId', 'user-123');
* ctx.set('apiKey', 'key-456');
* const { userId, apiKey } = ctx.all;
* ```
*/
get all() {
return Object.fromEntries(this.registry);
}
};
exports.MASTRA_AUTH_TOKEN_KEY = MASTRA_AUTH_TOKEN_KEY;
exports.MASTRA_RESOURCE_ID_KEY = MASTRA_RESOURCE_ID_KEY;
exports.MASTRA_THREAD_ID_KEY = MASTRA_THREAD_ID_KEY;
exports.MASTRA_VERSIONS_KEY = MASTRA_VERSIONS_KEY;
exports.RequestContext = RequestContext;
exports.mergeVersionOverrides = mergeVersionOverrides;
//# sourceMappingURL=chunk-CAVARKYS.cjs.map
//# sourceMappingURL=chunk-CAVARKYS.cjs.map