UNPKG

askeroo

Version:

A modern CLI prompt library with flow control, history navigation, and conditional prompts

138 lines 4.74 kB
/** * FieldDiscoveryService - Handles field discovery for static groups * * Static groups need to pre-scan their fields before rendering to know what * fields will be shown. This service manages the discovery process, tracks * discovered fields, and provides re-discovery capabilities. */ import { debugLogger } from "../utils/logging.js"; export class FieldDiscoveryService { state; isScanning = false; discoveredFieldsByGroup = new Map(); groupBodyFunctions = new Map(); constructor(state) { this.state = state; } // ========== SCANNING STATE ========== isCurrentlyScanning() { return this.isScanning; } // ========== FIELD RETRIEVAL ========== getDiscoveredFields(groupId) { return this.discoveredFieldsByGroup.get(groupId); } // ========== FIELD REGISTRATION ========== registerDiscoveredField(groupId, field) { const fields = this.discoveredFieldsByGroup.get(groupId) || []; // Only add if not already present if (!fields.some((f) => f.id === field.id)) { fields.push(field); this.discoveredFieldsByGroup.set(groupId, fields); debugLogger.log("DISCOVERY_FIELD_ADDED", { groupId, fieldId: field.id, fieldCount: fields.length, }); } } // ========== GROUP BODY STORAGE ========== storeGroupBodyFunction(groupId, body) { this.groupBodyFunctions.set(groupId, body); } hasStoredBodyFunction(groupId) { return this.groupBodyFunctions.has(groupId); } // ========== FIELD SCANNING ========== /** * Scan a static group to discover all its fields * Executes the group body in scanning mode to find all fields */ async scanGroupFields(groupId, body) { this.isScanning = true; debugLogger.log("DISCOVERY_START", { groupId, groupStack: this.state.getGroupHierarchy(), }); // Push group to stack temporarily for discovery this.state.enterGroup(groupId); try { // Run discovery once to find all fields await body(); } catch (e) { debugLogger.log("DISCOVERY_ERROR", { groupId, error: e, }); // Ignore errors in discovery mode } finally { // Remove from stack after discovery this.state.exitGroup(); } this.isScanning = false; const discoveredFields = this.discoveredFieldsByGroup.get(groupId); debugLogger.log("DISCOVERY_END", { groupId, fields: discoveredFields, }); return discoveredFields || []; } /** * Re-scan a static group's fields * Used when a group needs to be re-rendered with updated fields */ async rescanGroupFields(groupId) { if (this.isScanning) { // Already scanning, skip return this.discoveredFieldsByGroup.get(groupId); } if (!this.groupBodyFunctions.has(groupId)) { // No stored body function, return existing fields return this.discoveredFieldsByGroup.get(groupId); } debugLogger.log("REDISCOVERY_START", { groupId }); const body = this.groupBodyFunctions.get(groupId); // Clear existing discovered fields for this group this.discoveredFieldsByGroup.delete(groupId); this.isScanning = true; this.state.enterGroup(groupId); try { await body(); } catch (e) { debugLogger.log("REDISCOVERY_ERROR", { groupId, error: e }); } finally { this.state.exitGroup(); this.isScanning = false; } const rescannedFields = this.discoveredFieldsByGroup.get(groupId); debugLogger.log("REDISCOVERY_END", { groupId, fields: rescannedFields, }); return rescannedFields; } // ========== CLEANUP ========== /** * Clear all discovered fields and stored body functions * Typically used when resetting the runtime */ clearAll() { this.discoveredFieldsByGroup.clear(); this.groupBodyFunctions.clear(); this.isScanning = false; } // ========== DEBUG/INSPECTION ========== getDebugInfo() { return { isScanning: this.isScanning, discoveredGroupsCount: this.discoveredFieldsByGroup.size, storedBodiesCount: this.groupBodyFunctions.size, groups: Array.from(this.discoveredFieldsByGroup.keys()), }; } } //# sourceMappingURL=discovery-service.js.map