UNPKG

bc-webclient-mcp

Version:

Model Context Protocol (MCP) server for Microsoft Dynamics 365 Business Central via WebUI protocol. Enables AI assistants to interact with BC through the web client protocol, supporting Card, List, and Document pages with full line item support and server

130 lines 4.01 kB
/** * BC Handler Event Emitter * * Provides pub/sub for BC handler events and predicate-based waiting. * Used by both WebSocketManager/ProtocolAdapter (emit) and consumers (wait). * * This is a stateless service (except for listener subscriptions). * It does NOT own any session or protocol state. */ import type { IBCHandlerEventEmitter, HandlerEvent } from '../interfaces.js'; /** * Event emitter for BC handler arrays. * * Extracted from BCRawWebSocketClient (lines 56-57, 782-874). * * Key features: * - Type-safe event emission (HandlerEvent union type) * - Predicate-based waiting with timeout/abort support * - Error isolation (listener errors don't break other listeners) * * Usage: * ```ts * const emitter = new BCHandlerEventEmitter(); * * // Subscribe * const unsubscribe = emitter.onHandlers((event) => { * if (event.kind === 'FormToShow') { * console.log('Form appeared:', event.formId); * } * }); * * // Wait for specific event * const formId = await emitter.waitForHandlers( * (event) => event.kind === 'FormToShow' * ? { matched: true, data: event.formId } * : { matched: false }, * { timeoutMs: 5000 } * ); * * // Emit * emitter.emit({ * kind: 'FormToShow', * formId: 'form123', * raw: { handlerType: 'DN.LogicalClientEventRaisingHandler', parameters: [] } * }); * ``` */ export declare class BCHandlerEventEmitter implements IBCHandlerEventEmitter { private handlerListeners; /** * Subscribe to handler events. * * Returns an unsubscribe function for cleanup. * * @param listener Callback for each event * @returns Unsubscribe function * * @example * ```ts * const unsubscribe = emitter.onHandlers((event) => { * console.log('Event:', event.kind); * }); * * // Later: cleanup * unsubscribe(); * ``` */ onHandlers(listener: (event: HandlerEvent) => void): () => void; /** * Wait for a handler event that matches the predicate. * * Promise-based waiting with timeout and abort signal support. * Uses the same composeWithTimeout pattern as RPC requests. * * @param predicate Function that returns {matched: true, data: T} when event matches * @param options Optional timeout and abort signal * @returns Promise resolving to matched data * @throws {TimeoutError} If no matching event arrives within timeout * @throws {AbortedError} If externally aborted via signal * * @example * ```ts * // Wait for Tell Me dialog to appear * const formId = await emitter.waitForHandlers( * (event) => { * if (event.kind === 'FormToShow') { * return { matched: true, data: event.formId }; * } * return { matched: false }; * }, * { timeoutMs: 2500 } * ); * ``` */ waitForHandlers<T>(predicate: (event: HandlerEvent) => { matched: boolean; data?: T; }, options?: { signal?: AbortSignal; timeoutMs?: number; }): Promise<T>; /** * Emit a handler event to all subscribers. * * Called by BCProtocolAdapter after parsing WebSocket messages. * * Error isolation: If a listener throws, the error is logged but * other listeners are still called. This prevents one bad listener * from breaking the entire event pipeline. * * IMPORTANT: Iterates over a copy of the listeners array to prevent * issues when listeners unsubscribe during emission (e.g., waitForHandlers * cleanup after match). * * @param event The handler event to emit * * @example * ```ts * // From BCProtocolAdapter * emitter.emit({ * kind: 'RawHandlers', * handlers: [ * { handlerType: 'DN.LogicalClientEventRaisingHandler', parameters: [...] } * ] * }); * ``` */ emit(event: HandlerEvent): void; } //# sourceMappingURL=BCHandlerEventEmitter.d.ts.map