Files
operations/src/env.ts
glm-5.1 29f0dd7af0 Initial package implementation: operations registry, call protocol, and adapters
Extracted from alkhub_ts packages/core/operations/ and packages/core/mcp/.
- Runtime-agnostic (injected fs/env deps, no Deno globals)
- Direct @logtape/logtape import instead of logger wrapper
- PendingRequestMap with pubsub-wired call protocol
- Peer-dep isolation for MCP adapter (sub-path export)
- Schema const naming convention (XSchema + X type alias)
- 68 tests passing, build + lint + test all green
2026-04-30 12:34:26 +00:00

56 lines
1.7 KiB
TypeScript

import { OperationType } from "./types.js";
import type { OperationContext, OperationEnv } from "./types.js";
import type { OperationRegistry } from "./registry.js";
import { getLogger } from "@logtape/logtape";
const logger = getLogger("operations:env");
export interface PendingRequestMap {
call(operationId: string, input: unknown, options?: { parentRequestId?: string; identity?: unknown }): Promise<unknown>;
}
export interface EnvOptions {
registry: OperationRegistry;
context: OperationContext;
allowedNamespaces?: string[];
callMap?: PendingRequestMap;
}
export function buildEnv(options: EnvOptions): OperationEnv {
const { registry, context, allowedNamespaces, callMap } = options;
const operations = registry.list();
const namespaces: OperationEnv = {};
for (const operation of operations) {
if (allowedNamespaces && !allowedNamespaces.includes(operation.namespace)) {
continue;
}
if (operation.type === OperationType.SUBSCRIPTION) {
continue;
}
if (!namespaces[operation.namespace]) {
namespaces[operation.namespace] = {};
}
const operationId = `${operation.namespace}.${operation.name}`;
if (callMap) {
namespaces[operation.namespace][operation.name] = async (input: unknown) => {
logger.debug(`Call protocol: ${operationId}`);
return await callMap.call(operationId, input, {
parentRequestId: context.requestId,
});
};
} else {
namespaces[operation.namespace][operation.name] = async (input: unknown) => {
logger.debug(`Executing: ${operationId}`);
return await registry.execute(operationId, input, context);
};
}
}
return namespaces;
}