import { AttrPatterns, AttrConfig, ParserFunction, ParserContext, SpawnContext } from './types/assign-gingerly/types'; import { globalParserRegistry, getParserRegistry } from './parserRegistry.js'; import { resolveTemplate } from './resolveTemplate.js'; // Module-level cache for parsed attribute values // Structure: Map> const parseCache = new Map>(); /** * Resolves a parser specification to an actual parser function * Supports: * - Inline functions (direct use) * - Named parsers from scoped registry (if synthesizerElement provided) * - Named parsers from global registry (fallback) * * @param parserSpec - Parser function or string reference * @param synthesizerElement - Optional synthesizer element for scoped parser lookup * @returns The resolved parser function * @throws Error if parser cannot be resolved */ function resolveParser( parserSpec: ParserFunction | string | undefined, synthesizerElement?: Element ): ParserFunction | undefined { // Undefined - no parser specified if (parserSpec === undefined) { return undefined; } // Inline function - use directly if (typeof parserSpec === 'function') { return parserSpec; } // String reference - resolve from scoped or global registry if (typeof parserSpec === 'string') { // Check scoped registry first (if synthesizerElement provided) if (synthesizerElement) { const scopedRegistry = getParserRegistry(synthesizerElement); const scopedParser = scopedRegistry.get(parserSpec); if (scopedParser) { return scopedParser; } } // Fallback to global registry const globalParser = globalParserRegistry.get(parserSpec); if (globalParser) { return globalParser; } // Not found in either registry throw new Error( `Parser "${parserSpec}" not found. ` + `Checked ${synthesizerElement ? 'scoped registry and ' : ''}global registry.\n` + `Ensure the parser is registered via:\n` + `-