@lukso/transaction-view-headless 0.4.9 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +20 -20
- package/.turbo/turbo-typecheck.log +1 -1
- package/CHANGELOG.md +19 -0
- package/dist/composables/index.cjs +4 -1
- package/dist/composables/index.cjs.map +1 -1
- package/dist/composables/index.js +4 -1
- package/dist/composables/index.js.map +1 -1
- package/dist/index.cjs +4 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -1
- package/dist/registry/index.cjs +4 -1
- package/dist/registry/index.cjs.map +1 -1
- package/dist/registry/index.js +4 -1
- package/dist/registry/index.js.map +1 -1
- package/package.json +5 -2
- package/src/registry/view-loader.ts +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/registry/index.ts","../../src/registry/view-loader.ts","../../src/utils/view-matcher.ts","../../src/registry/view-registry.ts"],"sourcesContent":["export {\n getGlobalLoader,\n LoaderHelpers,\n setGlobalLoader,\n UniversalViewLoader,\n ViewLoadingError,\n} from './view-loader'\nexport {\n DefaultViewRegistry,\n getGlobalRegistry,\n resetGlobalRegistry,\n setGlobalRegistry,\n} from './view-registry'\n","import type {\n FrameworkViewConfig,\n ViewLoader,\n ViewMatch,\n} from '../types/view-matching'\n\n/**\n * Error thrown when view loading fails\n */\nexport class ViewLoadingError extends Error {\n public readonly loader: ViewLoader\n public readonly config: FrameworkViewConfig\n public override readonly cause?: Error\n\n constructor(\n message: string,\n loader: ViewLoader,\n config: FrameworkViewConfig,\n cause?: Error\n ) {\n super(message)\n this.name = 'ViewLoadingError'\n this.loader = loader\n this.config = config\n this.cause = cause\n }\n}\n\n/**\n * Framework-agnostic view loader that handles different loading strategies\n */\nexport class UniversalViewLoader {\n private cache = new Map<string, any>()\n\n /**\n * Load a component based on the framework configuration\n */\n async loadComponent(config: FrameworkViewConfig): Promise<any> {\n const cacheKey = this.getCacheKey(config)\n\n // Return cached component if available\n if (this.cache.has(cacheKey)) {\n return this.cache.get(cacheKey)\n }\n\n try {\n const component = await this.loadByStrategy(config.loader)\n this.cache.set(cacheKey, component)\n return component\n } catch (error) {\n throw new ViewLoadingError(\n `Failed to load component \"${config.component}\"`,\n config.loader,\n config,\n error instanceof Error ? error : new Error(String(error))\n )\n }\n }\n\n /**\n * Load a component from a view match\n */\n async loadFromMatch(match: ViewMatch): Promise<any> {\n if (!match.frameworkConfig) {\n throw new ViewLoadingError(\n `No framework config available for view \"${match.view.id}\"`,\n { type: 'dynamic-import', path: '' },\n {} as FrameworkViewConfig\n )\n }\n\n return this.loadComponent(match.frameworkConfig)\n }\n\n /**\n * Load component using the specific strategy\n */\n private async loadByStrategy(loader: ViewLoader): Promise<any> {\n switch (loader.type) {\n case 'dynamic-import':\n return this.loadDynamicImport(loader.path)\n\n case 'static-import':\n return this.loadStaticImport(loader.path)\n\n case 'custom-element':\n return this.loadCustomElement(loader.tagName)\n\n case 'registry-lookup':\n return this.loadFromRegistry(loader.registryKey)\n\n case 'custom':\n return loader.loader({} as FrameworkViewConfig) // Will be passed proper config in real usage\n\n default:\n throw new Error(`Unknown loader type: ${(loader as any).type}`)\n }\n }\n\n /**\n * Dynamic import strategy (most common)\n * Supports both static strings and lazy-loaded callbacks\n */\n private async loadDynamicImport(\n path: string | (() => Promise<any>)\n ): Promise<any> {\n // Handle callback-based lazy loading\n if (typeof path === 'function') {\n const module = await path()\n\n // Handle different export patterns\n if (module.default) {\n return module.default\n }\n\n return module\n }\n\n // Handle string-based path (static)\n const module = await import(path)\n\n // Handle different export patterns\n if (module.default) {\n return module.default\n }\n\n // If no default export, return the entire module\n return module\n }\n\n /**\n * Static import strategy (requires bundler support)\n * Supports both static strings and lazy-loaded callbacks\n */\n private async loadStaticImport(\n path: string | (() => Promise<any>)\n ): Promise<any> {\n // Handle callback-based lazy loading\n if (typeof path === 'function') {\n const module = await path()\n\n if (module.default) {\n return module.default\n }\n\n return module\n }\n\n // This would typically be handled by bundler transformation\n // For now, fall back to dynamic import\n console.warn(\n 'Static import not implemented, falling back to dynamic import'\n )\n return this.loadDynamicImport(path)\n }\n\n /**\n * Custom element strategy (for Lit components)\n */\n private async loadCustomElement(tagName: string): Promise<any> {\n // Wait for custom element to be defined\n if (typeof window !== 'undefined' && window.customElements) {\n await window.customElements.whenDefined(tagName)\n return { tagName, type: 'custom-element' }\n }\n\n throw new Error('Custom elements not available in this environment')\n }\n\n /**\n * Registry lookup strategy (for pre-registered components)\n */\n private async loadFromRegistry(registryKey: string): Promise<any> {\n // This would look up in a component registry\n // Implementation depends on framework\n throw new Error(`Registry lookup not implemented for key: ${registryKey}`)\n }\n\n /**\n * Generate cache key for component config\n */\n private getCacheKey(config: FrameworkViewConfig): string {\n const { loader, component, package: pkg } = config\n return JSON.stringify({ loader, component, package: pkg })\n }\n\n /**\n * Clear the component cache\n */\n clearCache(): void {\n this.cache.clear()\n }\n\n /**\n * Get cache statistics\n */\n getCacheStats(): { size: number; keys: string[] } {\n return {\n size: this.cache.size,\n keys: Array.from(this.cache.keys()),\n }\n }\n}\n\n/**\n * Singleton loader instance\n */\nlet globalLoader: UniversalViewLoader | null = null\n\n/**\n * Get the global view loader\n */\nexport function getGlobalLoader(): UniversalViewLoader {\n if (!globalLoader) {\n globalLoader = new UniversalViewLoader()\n }\n return globalLoader\n}\n\n/**\n * Set a custom global loader (useful for testing)\n */\nexport function setGlobalLoader(loader: UniversalViewLoader): void {\n globalLoader = loader\n}\n\n/**\n * Framework-specific helpers for strategically optimized loading patterns\n *\n * Following our Suffering Economics optimization, we support:\n * - Lit Web Components (universal web compatibility) - REQUIRED\n * - Vue (native Vue optimization) - OPTIONAL\n * - React Native (mobile-native optimization) - OPTIONAL (WebView fallback available)\n *\n * All loaders support lazy loading via callbacks:\n * ```typescript\n * // Static (bundled)\n * vueComponent('./Component.vue')\n *\n * // Lazy (loaded on demand)\n * vueComponent(() => import('./Component.vue'))\n * ```\n */\nexport const LoaderHelpers = {\n /**\n * Create a Lit custom element loader (universal web compatibility)\n */\n litComponent(tagName: string): ViewLoader {\n return { type: 'custom-element', tagName }\n },\n\n /**\n * Create a Vue component loader (native Vue, optional)\n * Supports both static paths and lazy-loaded callbacks\n */\n vueComponent(path: string | (() => Promise<any>)): ViewLoader {\n return { type: 'dynamic-import', path }\n },\n\n /**\n * Create a React Native JSX dynamic import loader (mobile-native, optional)\n * Supports both static paths and lazy-loaded callbacks\n */\n rnComponent(path: string | (() => Promise<any>)): ViewLoader {\n return { type: 'dynamic-import', path }\n },\n\n /**\n * Create a custom loader function for advanced use cases\n */\n custom(loader: (config: FrameworkViewConfig) => Promise<any>): ViewLoader {\n return { type: 'custom', loader }\n },\n\n // Legacy helpers for compilation pipelines (Vue/React → Lit)\n /**\n * @deprecated Use litComponent() instead. This exists for compilation pipeline compatibility.\n */\n vueToLitCompiled(tagName: string): ViewLoader {\n console.warn(\n 'vueToLitCompiled is deprecated. Use litComponent() - the output is the same.'\n )\n return { type: 'custom-element', tagName }\n },\n\n /**\n * @deprecated Use litComponent() instead. This exists for compilation pipeline compatibility.\n */\n reactToLitCompiled(tagName: string): ViewLoader {\n console.warn(\n 'reactToLitCompiled is deprecated. Use litComponent() - the output is the same.'\n )\n return { type: 'custom-element', tagName }\n },\n\n /**\n * @deprecated Use rnComponent() instead. Updated for better TypeScript support.\n */\n reactNativeComponent(path: string): ViewLoader {\n console.warn(\n 'reactNativeComponent is deprecated. Use rnComponent() instead.'\n )\n return { type: 'dynamic-import', path }\n },\n}\n","import type { DecoderResult } from '@lukso/transaction-decoder'\nimport type {\n DecoderRecordForSelection,\n ViewDefinition,\n ViewMatch,\n ViewMatchCriteria,\n ViewMatchOptions,\n} from '../types/view-matching'\n\n/**\n * Weights for different matching criteria (higher = more important)\n * Context is optional - only weighted when both view and request specify context\n */\nexport const CRITERIA_WEIGHTS = {\n recordType: 0.25, // Most specific to transaction type\n functionName: 0.2, // Function-level specificity\n context: 0.2, // Context specificity (when opt-in)\n standard: 0.15, // LSP standard specificity\n contractAddress: 0.1, // Contract-specific logic\n contextRequirements: 0.05, // Context requirement matching\n chainId: 0.03, // Network-specific behavior\n customMatcher: 0.02, // Custom logic (lowest weight due to unpredictability)\n} as const\n\n/**\n * Calculate how well a view matches a transaction and context\n *\n * Context matching is opt-in:\n * - If view specifies context criteria, request MUST provide matching context\n * - If view has no context criteria, it matches any context (universal view)\n * - If request has no context, context-specific views are deprioritized\n *\n * Note: For batch operations (executeBatch, setDataBatch, etc.), this matches\n * against the parent transaction. Future enhancement could include matching\n * against child transactions for more granular view selection.\n */\nexport function calculateMatchScore(\n transaction: DecoderResult,\n view: ViewDefinition,\n options?: Pick<ViewMatchOptions, 'context' | 'contextRequirements'>\n): { score: number; matchedCriteria: (keyof ViewMatchCriteria)[] } {\n const { criteria } = view\n const matchedCriteria: (keyof ViewMatchCriteria)[] = []\n let totalWeight = 0\n let matchedWeight = 0\n\n // Check each criterion and accumulate scores\n for (const [criterion, weight] of Object.entries(CRITERIA_WEIGHTS)) {\n const criterionKey = criterion as keyof ViewMatchCriteria\n const criterionValue = criteria[criterionKey]\n\n if (criterionValue === undefined) continue\n\n totalWeight += weight\n\n // Special handling for customMatcher - use match count\n if (\n criterionKey === 'customMatcher' &&\n typeof criterionValue === 'function'\n ) {\n try {\n const matchCount = criterionValue(transaction)\n if (matchCount > 0) {\n matchedCriteria.push(criterionKey)\n // Normalize match count to 0-1 range (cap at 10 conditions)\n const normalizedScore = Math.min(matchCount / 10, 1)\n matchedWeight += weight * normalizedScore\n }\n } catch (error) {\n console.warn('Custom matcher threw error:', error)\n }\n continue\n }\n\n if (\n doesCriterionMatch(transaction, criterionKey, criterionValue, options)\n ) {\n matchedCriteria.push(criterionKey)\n matchedWeight += weight\n }\n }\n\n // Handle context opt-in logic\n const viewHasContext = criteria.context !== undefined\n const requestHasContext = options?.context !== undefined\n\n if (viewHasContext && !requestHasContext) {\n // View requires specific context, but none provided - penalize heavily\n matchedWeight *= 0.1 // Reduce score by 90%\n } else if (!viewHasContext && requestHasContext) {\n // Universal view matching specific context - slight penalty to prefer context-specific views\n matchedWeight *= 0.9 // Reduce score by 10%\n }\n\n // If no criteria are defined, this view doesn't match\n if (totalWeight === 0) return { score: 0, matchedCriteria: [] }\n\n // Calculate final score (0-1)\n const score = matchedWeight / totalWeight\n\n return { score, matchedCriteria }\n}\n\n/**\n * Check if a specific criterion matches the transaction\n */\nfunction doesCriterionMatch(\n transaction: DecoderResult,\n criterion: keyof ViewMatchCriteria,\n criterionValue: any,\n options?: Pick<ViewMatchOptions, 'context' | 'contextRequirements'>\n): boolean {\n switch (criterion) {\n case 'recordType':\n return matchesStringOrArray(\n (transaction as DecoderRecordForSelection).recordType,\n criterionValue\n )\n\n case 'functionName':\n return matchesStringOrArray(\n (transaction as DecoderRecordForSelection).functionName,\n criterionValue\n )\n\n case 'standard':\n return matchesStringOrArray(\n (transaction as DecoderRecordForSelection).standard,\n criterionValue\n )\n\n case 'contractAddress':\n return matchesStringOrArray(\n (transaction as DecoderRecordForSelection).contractAddress,\n criterionValue\n )\n\n case 'chainId':\n return matchesNumberOrArray(transaction.chainId, criterionValue)\n\n case 'context':\n if (!options?.context) return false // No context provided, can't match\n return matchesStringOrArray(options.context, criterionValue)\n\n case 'contextRequirements':\n if (!options?.contextRequirements || !criterionValue) return false\n return areContextRequirementsCompatible(\n options.contextRequirements,\n criterionValue\n )\n\n case 'customMatcher':\n if (typeof criterionValue === 'function') {\n try {\n const matchCount = criterionValue(transaction)\n // Match if any conditions matched (> 0)\n // The actual count contributes to the score in calculateMatchScore\n return matchCount > 0\n } catch (error) {\n console.warn('Custom matcher threw error:', error)\n return false\n }\n }\n return false\n\n default:\n return false\n }\n}\n\n/**\n * Helper to match string values against string or array criteria\n */\nfunction matchesStringOrArray(\n value: string | undefined,\n criteria: string | string[]\n): boolean {\n if (!value || !criteria) return false\n\n if (Array.isArray(criteria)) {\n return criteria.includes(value)\n }\n\n return value === criteria\n}\n\n/**\n * Helper to match number values against number or array criteria\n */\nfunction matchesNumberOrArray(\n value: number | undefined,\n criteria: number | number[]\n): boolean {\n if (value === undefined || criteria === undefined) return false\n\n if (Array.isArray(criteria)) {\n return criteria.includes(value)\n }\n\n return value === criteria\n}\n\n/**\n * Check if context requirements are compatible\n */\nfunction areContextRequirementsCompatible(\n requested: any,\n viewRequirements: any\n): boolean {\n // Simple compatibility check - can be extended\n if (requested.detailLevel && viewRequirements.detailLevel) {\n const detailOrder = ['minimal', 'summary', 'full', 'debug']\n const requestedLevel = detailOrder.indexOf(requested.detailLevel)\n const viewLevel = detailOrder.indexOf(viewRequirements.detailLevel)\n if (viewLevel < requestedLevel) return false\n }\n\n if (requested.maxHeight && viewRequirements.maxHeight) {\n if (viewRequirements.maxHeight > requested.maxHeight) return false\n }\n\n return true\n}\n\n/**\n * Calculate native framework priority bonus\n *\n * Native framework implementations (Vue, React Native) get priority over Lit fallbacks:\n * - Vue: +0.15 bonus when view has Vue implementation\n * - React Native (rn): +0.15 bonus when view has RN implementation\n * - Lit: NO bonus (Lit is the universal fallback)\n *\n * This ensures that when both native and Lit views exist for the same transaction:\n * - Vue app prefers Vue view (Vue score + 0.15 > Lit score)\n * - React Native app prefers RN view (RN score + 0.15 > Lit score)\n * - Other frameworks use Lit view (universal compatibility)\n */\nfunction calculateNativeFrameworkBonus(\n view: ViewDefinition,\n requestedFramework: 'lit' | 'vue' | 'rn'\n): number {\n // Lit gets no bonus - it's the universal fallback\n if (requestedFramework === 'lit') {\n return 0\n }\n\n // Vue gets bonus if view has Vue implementation\n if (requestedFramework === 'vue' && view.frameworks.vue) {\n return 0.15\n }\n\n // React Native gets bonus if view has RN implementation\n if (requestedFramework === 'rn' && view.frameworks.rn) {\n return 0.15\n }\n\n return 0\n}\n\n/**\n * Find and score all matching views for a transaction\n *\n * Views are matched and sorted by:\n * 1. Match score (how well criteria match the transaction)\n * 2. Native framework bonus (Vue/RN get +0.15, Lit gets 0)\n * 3. View priority (manually set priority)\n *\n * This ensures that native framework views are preferred when available,\n * while Lit serves as a universal fallback.\n */\nexport function findMatchingViews(\n transaction: DecoderResult,\n views: ViewDefinition[],\n options: ViewMatchOptions\n): ViewMatch[] {\n const matches: ViewMatch[] = []\n const minScore = options.minScore ?? 0\n\n for (const view of views) {\n // Skip if framework is not supported\n if (!view.frameworks[options.framework]) {\n continue\n }\n\n const { score, matchedCriteria } = calculateMatchScore(transaction, view, {\n context: options.context,\n contextRequirements: options.contextRequirements,\n })\n\n // Skip if score is below threshold\n if (score < minScore) {\n continue\n }\n\n // Apply native framework bonus (Vue/RN only, NOT Lit)\n const frameworkBonus = calculateNativeFrameworkBonus(\n view,\n options.framework\n )\n const finalScore = Math.min(1, score + frameworkBonus)\n\n const match: ViewMatch = {\n view,\n score: finalScore,\n matchedCriteria,\n frameworkConfig: options.includeFrameworkConfig\n ? view.frameworks[options.framework]\n : undefined,\n }\n\n matches.push(match)\n }\n\n // Sort by score (descending), then by priority (descending)\n matches.sort((a, b) => {\n if (a.score !== b.score) {\n return b.score - a.score\n }\n return b.view.priority - a.view.priority\n })\n\n // Limit results if requested\n if (options.maxMatches) {\n return matches.slice(0, options.maxMatches)\n }\n\n return matches\n}\n\n/**\n * TODO: Future enhancement for batch operations\n *\n * For batch operations like executeBatch, setDataBatch, we might want to:\n * 1. Match against the batch container (current behavior)\n * 2. Also match against child transactions for more specific views\n * 3. Allow views to specify whether they handle batches vs individual items\n * 4. Support composite views that render both batch info + child items\n */\n","import type { DecoderResult } from '@lukso/transaction-decoder'\nimport type {\n ViewDefinition,\n ViewMatch,\n ViewMatchOptions,\n ViewRegistry,\n} from '../types/view-matching'\nimport { findMatchingViews } from '../utils/view-matcher'\n\n/**\n * Default view registry implementation\n */\nexport class DefaultViewRegistry implements ViewRegistry {\n private views = new Map<string, ViewDefinition>()\n\n register(view: ViewDefinition): void {\n if (this.views.has(view.id)) {\n console.warn(\n `View with id \"${view.id}\" is already registered. Overwriting.`\n )\n }\n\n this.views.set(view.id, view)\n }\n\n unregister(viewId: string): void {\n this.views.delete(viewId)\n }\n\n getAllViews(): ViewDefinition[] {\n return Array.from(this.views.values())\n }\n\n findMatches(\n transaction: DecoderResult,\n options: ViewMatchOptions\n ): ViewMatch[] {\n const allViews = this.getAllViews()\n return findMatchingViews(transaction, allViews, options)\n }\n\n getView(viewId: string): ViewDefinition | undefined {\n return this.views.get(viewId)\n }\n\n clear(): void {\n this.views.clear()\n }\n\n /**\n * Get the best matching view (highest score) for a transaction\n */\n getBestMatch(\n transaction: DecoderResult,\n options: ViewMatchOptions\n ): ViewMatch | null {\n const matches = this.findMatches(transaction, { ...options, maxMatches: 1 })\n return matches[0] || null\n }\n\n /**\n * Bulk register multiple views\n */\n registerMany(views: ViewDefinition[]): void {\n for (const view of views) {\n this.register(view)\n }\n }\n\n /**\n * Get stats about registered views\n */\n getStats(): {\n totalViews: number\n viewsByFramework: Record<string, number>\n viewsByRecordType: Record<string, number>\n } {\n const allViews = this.getAllViews()\n const totalViews = allViews.length\n\n const viewsByFramework: Record<string, number> = {}\n const viewsByRecordType: Record<string, number> = {}\n\n for (const view of allViews) {\n // Count framework support\n for (const framework of Object.keys(view.frameworks)) {\n viewsByFramework[framework] = (viewsByFramework[framework] || 0) + 1\n }\n\n // Count by record type\n const recordType = view.criteria.recordType\n if (recordType) {\n const types = Array.isArray(recordType) ? recordType : [recordType]\n for (const type of types) {\n viewsByRecordType[type] = (viewsByRecordType[type] || 0) + 1\n }\n }\n }\n\n return {\n totalViews,\n viewsByFramework,\n viewsByRecordType,\n }\n }\n}\n\n/**\n * Global registry instance\n */\nlet globalRegistry: ViewRegistry | null = null\n\n/**\n * Get or create the global view registry\n */\nexport function getGlobalRegistry(): ViewRegistry {\n if (!globalRegistry) {\n globalRegistry = new DefaultViewRegistry()\n }\n return globalRegistry\n}\n\n/**\n * Set a custom global registry (useful for testing or custom implementations)\n */\nexport function setGlobalRegistry(registry: ViewRegistry): void {\n globalRegistry = registry\n}\n\n/**\n * Reset the global registry (mainly for testing)\n */\nexport function resetGlobalRegistry(): void {\n globalRegistry = null\n}\n"],"mappings":"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","names":["module"]}
|
|
1
|
+
{"version":3,"sources":["../../src/registry/index.ts","../../src/registry/view-loader.ts","../../src/utils/view-matcher.ts","../../src/registry/view-registry.ts"],"sourcesContent":["export {\n getGlobalLoader,\n LoaderHelpers,\n setGlobalLoader,\n UniversalViewLoader,\n ViewLoadingError,\n} from './view-loader'\nexport {\n DefaultViewRegistry,\n getGlobalRegistry,\n resetGlobalRegistry,\n setGlobalRegistry,\n} from './view-registry'\n","import type {\n FrameworkViewConfig,\n ViewLoader,\n ViewMatch,\n} from '../types/view-matching'\n\n/**\n * Error thrown when view loading fails\n */\nexport class ViewLoadingError extends Error {\n public readonly loader: ViewLoader\n public readonly config: FrameworkViewConfig\n public override readonly cause?: Error\n\n constructor(\n message: string,\n loader: ViewLoader,\n config: FrameworkViewConfig,\n cause?: Error\n ) {\n super(message)\n this.name = 'ViewLoadingError'\n this.loader = loader\n this.config = config\n this.cause = cause\n }\n}\n\n/**\n * Framework-agnostic view loader that handles different loading strategies\n */\nexport class UniversalViewLoader {\n private cache = new Map<string, any>()\n\n /**\n * Load a component based on the framework configuration\n */\n async loadComponent(config: FrameworkViewConfig): Promise<any> {\n const cacheKey = this.getCacheKey(config)\n\n // Return cached component if available\n if (this.cache.has(cacheKey)) {\n return this.cache.get(cacheKey)\n }\n\n try {\n const component = await this.loadByStrategy(config.loader)\n this.cache.set(cacheKey, component)\n return component\n } catch (error) {\n throw new ViewLoadingError(\n `Failed to load component \"${config.component}\"`,\n config.loader,\n config,\n error instanceof Error ? error : new Error(String(error))\n )\n }\n }\n\n /**\n * Load a component from a view match\n */\n async loadFromMatch(match: ViewMatch): Promise<any> {\n if (!match.frameworkConfig) {\n throw new ViewLoadingError(\n `No framework config available for view \"${match.view.id}\"`,\n { type: 'dynamic-import', path: '' },\n {} as FrameworkViewConfig\n )\n }\n\n return this.loadComponent(match.frameworkConfig)\n }\n\n /**\n * Load component using the specific strategy\n */\n private async loadByStrategy(loader: ViewLoader): Promise<any> {\n switch (loader.type) {\n case 'dynamic-import':\n return this.loadDynamicImport(loader.path)\n\n case 'static-import':\n return this.loadStaticImport(loader.path)\n\n case 'custom-element':\n return this.loadCustomElement(loader.tagName)\n\n case 'registry-lookup':\n return this.loadFromRegistry(loader.registryKey)\n\n case 'custom':\n return loader.loader({} as FrameworkViewConfig) // Will be passed proper config in real usage\n\n default:\n throw new Error(`Unknown loader type: ${(loader as any).type}`)\n }\n }\n\n /**\n * Dynamic import strategy (most common)\n * Supports both static strings and lazy-loaded callbacks\n */\n private async loadDynamicImport(\n path: string | (() => Promise<any>)\n ): Promise<any> {\n // Handle callback-based lazy loading\n if (typeof path === 'function') {\n const module = await path()\n\n // Handle different export patterns\n if (module.default) {\n return module.default\n }\n\n return module\n }\n\n // Handle string-based path (static)\n const module = await import(/* @vite-ignore */ path)\n\n // Handle different export patterns\n if (module.default) {\n return module.default\n }\n\n // If no default export, return the entire module\n return module\n }\n\n /**\n * Static import strategy (requires bundler support)\n * Supports both static strings and lazy-loaded callbacks\n */\n private async loadStaticImport(\n path: string | (() => Promise<any>)\n ): Promise<any> {\n // Handle callback-based lazy loading\n if (typeof path === 'function') {\n const module = await path()\n\n if (module.default) {\n return module.default\n }\n\n return module\n }\n\n // This would typically be handled by bundler transformation\n // For now, fall back to dynamic import\n console.warn(\n 'Static import not implemented, falling back to dynamic import'\n )\n return this.loadDynamicImport(path)\n }\n\n /**\n * Custom element strategy (for Lit components)\n */\n private async loadCustomElement(tagName: string): Promise<any> {\n // Wait for custom element to be defined\n if (typeof window !== 'undefined' && window.customElements) {\n await window.customElements.whenDefined(tagName)\n return { tagName, type: 'custom-element' }\n }\n\n throw new Error('Custom elements not available in this environment')\n }\n\n /**\n * Registry lookup strategy (for pre-registered components)\n */\n private async loadFromRegistry(registryKey: string): Promise<any> {\n // This would look up in a component registry\n // Implementation depends on framework\n throw new Error(`Registry lookup not implemented for key: ${registryKey}`)\n }\n\n /**\n * Generate cache key for component config\n */\n private getCacheKey(config: FrameworkViewConfig): string {\n const { loader, component, package: pkg } = config\n return JSON.stringify({ loader, component, package: pkg })\n }\n\n /**\n * Clear the component cache\n */\n clearCache(): void {\n this.cache.clear()\n }\n\n /**\n * Get cache statistics\n */\n getCacheStats(): { size: number; keys: string[] } {\n return {\n size: this.cache.size,\n keys: Array.from(this.cache.keys()),\n }\n }\n}\n\n/**\n * Singleton loader instance\n */\nlet globalLoader: UniversalViewLoader | null = null\n\n/**\n * Get the global view loader\n */\nexport function getGlobalLoader(): UniversalViewLoader {\n if (!globalLoader) {\n globalLoader = new UniversalViewLoader()\n }\n return globalLoader\n}\n\n/**\n * Set a custom global loader (useful for testing)\n */\nexport function setGlobalLoader(loader: UniversalViewLoader): void {\n globalLoader = loader\n}\n\n/**\n * Framework-specific helpers for strategically optimized loading patterns\n *\n * Following our Suffering Economics optimization, we support:\n * - Lit Web Components (universal web compatibility) - REQUIRED\n * - Vue (native Vue optimization) - OPTIONAL\n * - React Native (mobile-native optimization) - OPTIONAL (WebView fallback available)\n *\n * All loaders support lazy loading via callbacks:\n * ```typescript\n * // Static (bundled)\n * vueComponent('./Component.vue')\n *\n * // Lazy (loaded on demand)\n * vueComponent(() => import('./Component.vue'))\n * ```\n */\nexport const LoaderHelpers = {\n /**\n * Create a Lit custom element loader (universal web compatibility)\n */\n litComponent(tagName: string): ViewLoader {\n return { type: 'custom-element', tagName }\n },\n\n /**\n * Create a Vue component loader (native Vue, optional)\n * Supports both static paths and lazy-loaded callbacks\n */\n vueComponent(path: string | (() => Promise<any>)): ViewLoader {\n return { type: 'dynamic-import', path }\n },\n\n /**\n * Create a React Native JSX dynamic import loader (mobile-native, optional)\n * Supports both static paths and lazy-loaded callbacks\n */\n rnComponent(path: string | (() => Promise<any>)): ViewLoader {\n return { type: 'dynamic-import', path }\n },\n\n /**\n * Create a custom loader function for advanced use cases\n */\n custom(loader: (config: FrameworkViewConfig) => Promise<any>): ViewLoader {\n return { type: 'custom', loader }\n },\n\n // Legacy helpers for compilation pipelines (Vue/React → Lit)\n /**\n * @deprecated Use litComponent() instead. This exists for compilation pipeline compatibility.\n */\n vueToLitCompiled(tagName: string): ViewLoader {\n console.warn(\n 'vueToLitCompiled is deprecated. Use litComponent() - the output is the same.'\n )\n return { type: 'custom-element', tagName }\n },\n\n /**\n * @deprecated Use litComponent() instead. This exists for compilation pipeline compatibility.\n */\n reactToLitCompiled(tagName: string): ViewLoader {\n console.warn(\n 'reactToLitCompiled is deprecated. Use litComponent() - the output is the same.'\n )\n return { type: 'custom-element', tagName }\n },\n\n /**\n * @deprecated Use rnComponent() instead. Updated for better TypeScript support.\n */\n reactNativeComponent(path: string): ViewLoader {\n console.warn(\n 'reactNativeComponent is deprecated. Use rnComponent() instead.'\n )\n return { type: 'dynamic-import', path }\n },\n}\n","import type { DecoderResult } from '@lukso/transaction-decoder'\nimport type {\n DecoderRecordForSelection,\n ViewDefinition,\n ViewMatch,\n ViewMatchCriteria,\n ViewMatchOptions,\n} from '../types/view-matching'\n\n/**\n * Weights for different matching criteria (higher = more important)\n * Context is optional - only weighted when both view and request specify context\n */\nexport const CRITERIA_WEIGHTS = {\n recordType: 0.25, // Most specific to transaction type\n functionName: 0.2, // Function-level specificity\n context: 0.2, // Context specificity (when opt-in)\n standard: 0.15, // LSP standard specificity\n contractAddress: 0.1, // Contract-specific logic\n contextRequirements: 0.05, // Context requirement matching\n chainId: 0.03, // Network-specific behavior\n customMatcher: 0.02, // Custom logic (lowest weight due to unpredictability)\n} as const\n\n/**\n * Calculate how well a view matches a transaction and context\n *\n * Context matching is opt-in:\n * - If view specifies context criteria, request MUST provide matching context\n * - If view has no context criteria, it matches any context (universal view)\n * - If request has no context, context-specific views are deprioritized\n *\n * Note: For batch operations (executeBatch, setDataBatch, etc.), this matches\n * against the parent transaction. Future enhancement could include matching\n * against child transactions for more granular view selection.\n */\nexport function calculateMatchScore(\n transaction: DecoderResult,\n view: ViewDefinition,\n options?: Pick<ViewMatchOptions, 'context' | 'contextRequirements'>\n): { score: number; matchedCriteria: (keyof ViewMatchCriteria)[] } {\n const { criteria } = view\n const matchedCriteria: (keyof ViewMatchCriteria)[] = []\n let totalWeight = 0\n let matchedWeight = 0\n\n // Check each criterion and accumulate scores\n for (const [criterion, weight] of Object.entries(CRITERIA_WEIGHTS)) {\n const criterionKey = criterion as keyof ViewMatchCriteria\n const criterionValue = criteria[criterionKey]\n\n if (criterionValue === undefined) continue\n\n totalWeight += weight\n\n // Special handling for customMatcher - use match count\n if (\n criterionKey === 'customMatcher' &&\n typeof criterionValue === 'function'\n ) {\n try {\n const matchCount = criterionValue(transaction)\n if (matchCount > 0) {\n matchedCriteria.push(criterionKey)\n // Normalize match count to 0-1 range (cap at 10 conditions)\n const normalizedScore = Math.min(matchCount / 10, 1)\n matchedWeight += weight * normalizedScore\n }\n } catch (error) {\n console.warn('Custom matcher threw error:', error)\n }\n continue\n }\n\n if (\n doesCriterionMatch(transaction, criterionKey, criterionValue, options)\n ) {\n matchedCriteria.push(criterionKey)\n matchedWeight += weight\n }\n }\n\n // Handle context opt-in logic\n const viewHasContext = criteria.context !== undefined\n const requestHasContext = options?.context !== undefined\n\n if (viewHasContext && !requestHasContext) {\n // View requires specific context, but none provided - penalize heavily\n matchedWeight *= 0.1 // Reduce score by 90%\n } else if (!viewHasContext && requestHasContext) {\n // Universal view matching specific context - slight penalty to prefer context-specific views\n matchedWeight *= 0.9 // Reduce score by 10%\n }\n\n // If no criteria are defined, this view doesn't match\n if (totalWeight === 0) return { score: 0, matchedCriteria: [] }\n\n // Calculate final score (0-1)\n const score = matchedWeight / totalWeight\n\n return { score, matchedCriteria }\n}\n\n/**\n * Check if a specific criterion matches the transaction\n */\nfunction doesCriterionMatch(\n transaction: DecoderResult,\n criterion: keyof ViewMatchCriteria,\n criterionValue: any,\n options?: Pick<ViewMatchOptions, 'context' | 'contextRequirements'>\n): boolean {\n switch (criterion) {\n case 'recordType':\n return matchesStringOrArray(\n (transaction as DecoderRecordForSelection).recordType,\n criterionValue\n )\n\n case 'functionName':\n return matchesStringOrArray(\n (transaction as DecoderRecordForSelection).functionName,\n criterionValue\n )\n\n case 'standard':\n return matchesStringOrArray(\n (transaction as DecoderRecordForSelection).standard,\n criterionValue\n )\n\n case 'contractAddress':\n return matchesStringOrArray(\n (transaction as DecoderRecordForSelection).contractAddress,\n criterionValue\n )\n\n case 'chainId':\n return matchesNumberOrArray(transaction.chainId, criterionValue)\n\n case 'context':\n if (!options?.context) return false // No context provided, can't match\n return matchesStringOrArray(options.context, criterionValue)\n\n case 'contextRequirements':\n if (!options?.contextRequirements || !criterionValue) return false\n return areContextRequirementsCompatible(\n options.contextRequirements,\n criterionValue\n )\n\n case 'customMatcher':\n if (typeof criterionValue === 'function') {\n try {\n const matchCount = criterionValue(transaction)\n // Match if any conditions matched (> 0)\n // The actual count contributes to the score in calculateMatchScore\n return matchCount > 0\n } catch (error) {\n console.warn('Custom matcher threw error:', error)\n return false\n }\n }\n return false\n\n default:\n return false\n }\n}\n\n/**\n * Helper to match string values against string or array criteria\n */\nfunction matchesStringOrArray(\n value: string | undefined,\n criteria: string | string[]\n): boolean {\n if (!value || !criteria) return false\n\n if (Array.isArray(criteria)) {\n return criteria.includes(value)\n }\n\n return value === criteria\n}\n\n/**\n * Helper to match number values against number or array criteria\n */\nfunction matchesNumberOrArray(\n value: number | undefined,\n criteria: number | number[]\n): boolean {\n if (value === undefined || criteria === undefined) return false\n\n if (Array.isArray(criteria)) {\n return criteria.includes(value)\n }\n\n return value === criteria\n}\n\n/**\n * Check if context requirements are compatible\n */\nfunction areContextRequirementsCompatible(\n requested: any,\n viewRequirements: any\n): boolean {\n // Simple compatibility check - can be extended\n if (requested.detailLevel && viewRequirements.detailLevel) {\n const detailOrder = ['minimal', 'summary', 'full', 'debug']\n const requestedLevel = detailOrder.indexOf(requested.detailLevel)\n const viewLevel = detailOrder.indexOf(viewRequirements.detailLevel)\n if (viewLevel < requestedLevel) return false\n }\n\n if (requested.maxHeight && viewRequirements.maxHeight) {\n if (viewRequirements.maxHeight > requested.maxHeight) return false\n }\n\n return true\n}\n\n/**\n * Calculate native framework priority bonus\n *\n * Native framework implementations (Vue, React Native) get priority over Lit fallbacks:\n * - Vue: +0.15 bonus when view has Vue implementation\n * - React Native (rn): +0.15 bonus when view has RN implementation\n * - Lit: NO bonus (Lit is the universal fallback)\n *\n * This ensures that when both native and Lit views exist for the same transaction:\n * - Vue app prefers Vue view (Vue score + 0.15 > Lit score)\n * - React Native app prefers RN view (RN score + 0.15 > Lit score)\n * - Other frameworks use Lit view (universal compatibility)\n */\nfunction calculateNativeFrameworkBonus(\n view: ViewDefinition,\n requestedFramework: 'lit' | 'vue' | 'rn'\n): number {\n // Lit gets no bonus - it's the universal fallback\n if (requestedFramework === 'lit') {\n return 0\n }\n\n // Vue gets bonus if view has Vue implementation\n if (requestedFramework === 'vue' && view.frameworks.vue) {\n return 0.15\n }\n\n // React Native gets bonus if view has RN implementation\n if (requestedFramework === 'rn' && view.frameworks.rn) {\n return 0.15\n }\n\n return 0\n}\n\n/**\n * Find and score all matching views for a transaction\n *\n * Views are matched and sorted by:\n * 1. Match score (how well criteria match the transaction)\n * 2. Native framework bonus (Vue/RN get +0.15, Lit gets 0)\n * 3. View priority (manually set priority)\n *\n * This ensures that native framework views are preferred when available,\n * while Lit serves as a universal fallback.\n */\nexport function findMatchingViews(\n transaction: DecoderResult,\n views: ViewDefinition[],\n options: ViewMatchOptions\n): ViewMatch[] {\n const matches: ViewMatch[] = []\n const minScore = options.minScore ?? 0\n\n for (const view of views) {\n // Skip if framework is not supported\n if (!view.frameworks[options.framework]) {\n continue\n }\n\n const { score, matchedCriteria } = calculateMatchScore(transaction, view, {\n context: options.context,\n contextRequirements: options.contextRequirements,\n })\n\n // Skip if score is below threshold\n if (score < minScore) {\n continue\n }\n\n // Apply native framework bonus (Vue/RN only, NOT Lit)\n const frameworkBonus = calculateNativeFrameworkBonus(\n view,\n options.framework\n )\n const finalScore = Math.min(1, score + frameworkBonus)\n\n const match: ViewMatch = {\n view,\n score: finalScore,\n matchedCriteria,\n frameworkConfig: options.includeFrameworkConfig\n ? view.frameworks[options.framework]\n : undefined,\n }\n\n matches.push(match)\n }\n\n // Sort by score (descending), then by priority (descending)\n matches.sort((a, b) => {\n if (a.score !== b.score) {\n return b.score - a.score\n }\n return b.view.priority - a.view.priority\n })\n\n // Limit results if requested\n if (options.maxMatches) {\n return matches.slice(0, options.maxMatches)\n }\n\n return matches\n}\n\n/**\n * TODO: Future enhancement for batch operations\n *\n * For batch operations like executeBatch, setDataBatch, we might want to:\n * 1. Match against the batch container (current behavior)\n * 2. Also match against child transactions for more specific views\n * 3. Allow views to specify whether they handle batches vs individual items\n * 4. Support composite views that render both batch info + child items\n */\n","import type { DecoderResult } from '@lukso/transaction-decoder'\nimport type {\n ViewDefinition,\n ViewMatch,\n ViewMatchOptions,\n ViewRegistry,\n} from '../types/view-matching'\nimport { findMatchingViews } from '../utils/view-matcher'\n\n/**\n * Default view registry implementation\n */\nexport class DefaultViewRegistry implements ViewRegistry {\n private views = new Map<string, ViewDefinition>()\n\n register(view: ViewDefinition): void {\n if (this.views.has(view.id)) {\n console.warn(\n `View with id \"${view.id}\" is already registered. Overwriting.`\n )\n }\n\n this.views.set(view.id, view)\n }\n\n unregister(viewId: string): void {\n this.views.delete(viewId)\n }\n\n getAllViews(): ViewDefinition[] {\n return Array.from(this.views.values())\n }\n\n findMatches(\n transaction: DecoderResult,\n options: ViewMatchOptions\n ): ViewMatch[] {\n const allViews = this.getAllViews()\n return findMatchingViews(transaction, allViews, options)\n }\n\n getView(viewId: string): ViewDefinition | undefined {\n return this.views.get(viewId)\n }\n\n clear(): void {\n this.views.clear()\n }\n\n /**\n * Get the best matching view (highest score) for a transaction\n */\n getBestMatch(\n transaction: DecoderResult,\n options: ViewMatchOptions\n ): ViewMatch | null {\n const matches = this.findMatches(transaction, { ...options, maxMatches: 1 })\n return matches[0] || null\n }\n\n /**\n * Bulk register multiple views\n */\n registerMany(views: ViewDefinition[]): void {\n for (const view of views) {\n this.register(view)\n }\n }\n\n /**\n * Get stats about registered views\n */\n getStats(): {\n totalViews: number\n viewsByFramework: Record<string, number>\n viewsByRecordType: Record<string, number>\n } {\n const allViews = this.getAllViews()\n const totalViews = allViews.length\n\n const viewsByFramework: Record<string, number> = {}\n const viewsByRecordType: Record<string, number> = {}\n\n for (const view of allViews) {\n // Count framework support\n for (const framework of Object.keys(view.frameworks)) {\n viewsByFramework[framework] = (viewsByFramework[framework] || 0) + 1\n }\n\n // Count by record type\n const recordType = view.criteria.recordType\n if (recordType) {\n const types = Array.isArray(recordType) ? recordType : [recordType]\n for (const type of types) {\n viewsByRecordType[type] = (viewsByRecordType[type] || 0) + 1\n }\n }\n }\n\n return {\n totalViews,\n viewsByFramework,\n viewsByRecordType,\n }\n }\n}\n\n/**\n * Global registry instance\n */\nlet globalRegistry: ViewRegistry | null = null\n\n/**\n * Get or create the global view registry\n */\nexport function getGlobalRegistry(): ViewRegistry {\n if (!globalRegistry) {\n globalRegistry = new DefaultViewRegistry()\n }\n return globalRegistry\n}\n\n/**\n * Set a custom global registry (useful for testing or custom implementations)\n */\nexport function setGlobalRegistry(registry: ViewRegistry): void {\n globalRegistry = registry\n}\n\n/**\n * Reset the global registry (mainly for testing)\n */\nexport function resetGlobalRegistry(): void {\n globalRegistry = null\n}\n"],"mappings":"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","names":["module"]}
|
package/dist/registry/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/registry/view-loader.ts","../../src/utils/view-matcher.ts","../../src/registry/view-registry.ts"],"sourcesContent":["import type {\n FrameworkViewConfig,\n ViewLoader,\n ViewMatch,\n} from '../types/view-matching'\n\n/**\n * Error thrown when view loading fails\n */\nexport class ViewLoadingError extends Error {\n public readonly loader: ViewLoader\n public readonly config: FrameworkViewConfig\n public override readonly cause?: Error\n\n constructor(\n message: string,\n loader: ViewLoader,\n config: FrameworkViewConfig,\n cause?: Error\n ) {\n super(message)\n this.name = 'ViewLoadingError'\n this.loader = loader\n this.config = config\n this.cause = cause\n }\n}\n\n/**\n * Framework-agnostic view loader that handles different loading strategies\n */\nexport class UniversalViewLoader {\n private cache = new Map<string, any>()\n\n /**\n * Load a component based on the framework configuration\n */\n async loadComponent(config: FrameworkViewConfig): Promise<any> {\n const cacheKey = this.getCacheKey(config)\n\n // Return cached component if available\n if (this.cache.has(cacheKey)) {\n return this.cache.get(cacheKey)\n }\n\n try {\n const component = await this.loadByStrategy(config.loader)\n this.cache.set(cacheKey, component)\n return component\n } catch (error) {\n throw new ViewLoadingError(\n `Failed to load component \"${config.component}\"`,\n config.loader,\n config,\n error instanceof Error ? error : new Error(String(error))\n )\n }\n }\n\n /**\n * Load a component from a view match\n */\n async loadFromMatch(match: ViewMatch): Promise<any> {\n if (!match.frameworkConfig) {\n throw new ViewLoadingError(\n `No framework config available for view \"${match.view.id}\"`,\n { type: 'dynamic-import', path: '' },\n {} as FrameworkViewConfig\n )\n }\n\n return this.loadComponent(match.frameworkConfig)\n }\n\n /**\n * Load component using the specific strategy\n */\n private async loadByStrategy(loader: ViewLoader): Promise<any> {\n switch (loader.type) {\n case 'dynamic-import':\n return this.loadDynamicImport(loader.path)\n\n case 'static-import':\n return this.loadStaticImport(loader.path)\n\n case 'custom-element':\n return this.loadCustomElement(loader.tagName)\n\n case 'registry-lookup':\n return this.loadFromRegistry(loader.registryKey)\n\n case 'custom':\n return loader.loader({} as FrameworkViewConfig) // Will be passed proper config in real usage\n\n default:\n throw new Error(`Unknown loader type: ${(loader as any).type}`)\n }\n }\n\n /**\n * Dynamic import strategy (most common)\n * Supports both static strings and lazy-loaded callbacks\n */\n private async loadDynamicImport(\n path: string | (() => Promise<any>)\n ): Promise<any> {\n // Handle callback-based lazy loading\n if (typeof path === 'function') {\n const module = await path()\n\n // Handle different export patterns\n if (module.default) {\n return module.default\n }\n\n return module\n }\n\n // Handle string-based path (static)\n const module = await import(path)\n\n // Handle different export patterns\n if (module.default) {\n return module.default\n }\n\n // If no default export, return the entire module\n return module\n }\n\n /**\n * Static import strategy (requires bundler support)\n * Supports both static strings and lazy-loaded callbacks\n */\n private async loadStaticImport(\n path: string | (() => Promise<any>)\n ): Promise<any> {\n // Handle callback-based lazy loading\n if (typeof path === 'function') {\n const module = await path()\n\n if (module.default) {\n return module.default\n }\n\n return module\n }\n\n // This would typically be handled by bundler transformation\n // For now, fall back to dynamic import\n console.warn(\n 'Static import not implemented, falling back to dynamic import'\n )\n return this.loadDynamicImport(path)\n }\n\n /**\n * Custom element strategy (for Lit components)\n */\n private async loadCustomElement(tagName: string): Promise<any> {\n // Wait for custom element to be defined\n if (typeof window !== 'undefined' && window.customElements) {\n await window.customElements.whenDefined(tagName)\n return { tagName, type: 'custom-element' }\n }\n\n throw new Error('Custom elements not available in this environment')\n }\n\n /**\n * Registry lookup strategy (for pre-registered components)\n */\n private async loadFromRegistry(registryKey: string): Promise<any> {\n // This would look up in a component registry\n // Implementation depends on framework\n throw new Error(`Registry lookup not implemented for key: ${registryKey}`)\n }\n\n /**\n * Generate cache key for component config\n */\n private getCacheKey(config: FrameworkViewConfig): string {\n const { loader, component, package: pkg } = config\n return JSON.stringify({ loader, component, package: pkg })\n }\n\n /**\n * Clear the component cache\n */\n clearCache(): void {\n this.cache.clear()\n }\n\n /**\n * Get cache statistics\n */\n getCacheStats(): { size: number; keys: string[] } {\n return {\n size: this.cache.size,\n keys: Array.from(this.cache.keys()),\n }\n }\n}\n\n/**\n * Singleton loader instance\n */\nlet globalLoader: UniversalViewLoader | null = null\n\n/**\n * Get the global view loader\n */\nexport function getGlobalLoader(): UniversalViewLoader {\n if (!globalLoader) {\n globalLoader = new UniversalViewLoader()\n }\n return globalLoader\n}\n\n/**\n * Set a custom global loader (useful for testing)\n */\nexport function setGlobalLoader(loader: UniversalViewLoader): void {\n globalLoader = loader\n}\n\n/**\n * Framework-specific helpers for strategically optimized loading patterns\n *\n * Following our Suffering Economics optimization, we support:\n * - Lit Web Components (universal web compatibility) - REQUIRED\n * - Vue (native Vue optimization) - OPTIONAL\n * - React Native (mobile-native optimization) - OPTIONAL (WebView fallback available)\n *\n * All loaders support lazy loading via callbacks:\n * ```typescript\n * // Static (bundled)\n * vueComponent('./Component.vue')\n *\n * // Lazy (loaded on demand)\n * vueComponent(() => import('./Component.vue'))\n * ```\n */\nexport const LoaderHelpers = {\n /**\n * Create a Lit custom element loader (universal web compatibility)\n */\n litComponent(tagName: string): ViewLoader {\n return { type: 'custom-element', tagName }\n },\n\n /**\n * Create a Vue component loader (native Vue, optional)\n * Supports both static paths and lazy-loaded callbacks\n */\n vueComponent(path: string | (() => Promise<any>)): ViewLoader {\n return { type: 'dynamic-import', path }\n },\n\n /**\n * Create a React Native JSX dynamic import loader (mobile-native, optional)\n * Supports both static paths and lazy-loaded callbacks\n */\n rnComponent(path: string | (() => Promise<any>)): ViewLoader {\n return { type: 'dynamic-import', path }\n },\n\n /**\n * Create a custom loader function for advanced use cases\n */\n custom(loader: (config: FrameworkViewConfig) => Promise<any>): ViewLoader {\n return { type: 'custom', loader }\n },\n\n // Legacy helpers for compilation pipelines (Vue/React → Lit)\n /**\n * @deprecated Use litComponent() instead. This exists for compilation pipeline compatibility.\n */\n vueToLitCompiled(tagName: string): ViewLoader {\n console.warn(\n 'vueToLitCompiled is deprecated. Use litComponent() - the output is the same.'\n )\n return { type: 'custom-element', tagName }\n },\n\n /**\n * @deprecated Use litComponent() instead. This exists for compilation pipeline compatibility.\n */\n reactToLitCompiled(tagName: string): ViewLoader {\n console.warn(\n 'reactToLitCompiled is deprecated. Use litComponent() - the output is the same.'\n )\n return { type: 'custom-element', tagName }\n },\n\n /**\n * @deprecated Use rnComponent() instead. Updated for better TypeScript support.\n */\n reactNativeComponent(path: string): ViewLoader {\n console.warn(\n 'reactNativeComponent is deprecated. Use rnComponent() instead.'\n )\n return { type: 'dynamic-import', path }\n },\n}\n","import type { DecoderResult } from '@lukso/transaction-decoder'\nimport type {\n DecoderRecordForSelection,\n ViewDefinition,\n ViewMatch,\n ViewMatchCriteria,\n ViewMatchOptions,\n} from '../types/view-matching'\n\n/**\n * Weights for different matching criteria (higher = more important)\n * Context is optional - only weighted when both view and request specify context\n */\nexport const CRITERIA_WEIGHTS = {\n recordType: 0.25, // Most specific to transaction type\n functionName: 0.2, // Function-level specificity\n context: 0.2, // Context specificity (when opt-in)\n standard: 0.15, // LSP standard specificity\n contractAddress: 0.1, // Contract-specific logic\n contextRequirements: 0.05, // Context requirement matching\n chainId: 0.03, // Network-specific behavior\n customMatcher: 0.02, // Custom logic (lowest weight due to unpredictability)\n} as const\n\n/**\n * Calculate how well a view matches a transaction and context\n *\n * Context matching is opt-in:\n * - If view specifies context criteria, request MUST provide matching context\n * - If view has no context criteria, it matches any context (universal view)\n * - If request has no context, context-specific views are deprioritized\n *\n * Note: For batch operations (executeBatch, setDataBatch, etc.), this matches\n * against the parent transaction. Future enhancement could include matching\n * against child transactions for more granular view selection.\n */\nexport function calculateMatchScore(\n transaction: DecoderResult,\n view: ViewDefinition,\n options?: Pick<ViewMatchOptions, 'context' | 'contextRequirements'>\n): { score: number; matchedCriteria: (keyof ViewMatchCriteria)[] } {\n const { criteria } = view\n const matchedCriteria: (keyof ViewMatchCriteria)[] = []\n let totalWeight = 0\n let matchedWeight = 0\n\n // Check each criterion and accumulate scores\n for (const [criterion, weight] of Object.entries(CRITERIA_WEIGHTS)) {\n const criterionKey = criterion as keyof ViewMatchCriteria\n const criterionValue = criteria[criterionKey]\n\n if (criterionValue === undefined) continue\n\n totalWeight += weight\n\n // Special handling for customMatcher - use match count\n if (\n criterionKey === 'customMatcher' &&\n typeof criterionValue === 'function'\n ) {\n try {\n const matchCount = criterionValue(transaction)\n if (matchCount > 0) {\n matchedCriteria.push(criterionKey)\n // Normalize match count to 0-1 range (cap at 10 conditions)\n const normalizedScore = Math.min(matchCount / 10, 1)\n matchedWeight += weight * normalizedScore\n }\n } catch (error) {\n console.warn('Custom matcher threw error:', error)\n }\n continue\n }\n\n if (\n doesCriterionMatch(transaction, criterionKey, criterionValue, options)\n ) {\n matchedCriteria.push(criterionKey)\n matchedWeight += weight\n }\n }\n\n // Handle context opt-in logic\n const viewHasContext = criteria.context !== undefined\n const requestHasContext = options?.context !== undefined\n\n if (viewHasContext && !requestHasContext) {\n // View requires specific context, but none provided - penalize heavily\n matchedWeight *= 0.1 // Reduce score by 90%\n } else if (!viewHasContext && requestHasContext) {\n // Universal view matching specific context - slight penalty to prefer context-specific views\n matchedWeight *= 0.9 // Reduce score by 10%\n }\n\n // If no criteria are defined, this view doesn't match\n if (totalWeight === 0) return { score: 0, matchedCriteria: [] }\n\n // Calculate final score (0-1)\n const score = matchedWeight / totalWeight\n\n return { score, matchedCriteria }\n}\n\n/**\n * Check if a specific criterion matches the transaction\n */\nfunction doesCriterionMatch(\n transaction: DecoderResult,\n criterion: keyof ViewMatchCriteria,\n criterionValue: any,\n options?: Pick<ViewMatchOptions, 'context' | 'contextRequirements'>\n): boolean {\n switch (criterion) {\n case 'recordType':\n return matchesStringOrArray(\n (transaction as DecoderRecordForSelection).recordType,\n criterionValue\n )\n\n case 'functionName':\n return matchesStringOrArray(\n (transaction as DecoderRecordForSelection).functionName,\n criterionValue\n )\n\n case 'standard':\n return matchesStringOrArray(\n (transaction as DecoderRecordForSelection).standard,\n criterionValue\n )\n\n case 'contractAddress':\n return matchesStringOrArray(\n (transaction as DecoderRecordForSelection).contractAddress,\n criterionValue\n )\n\n case 'chainId':\n return matchesNumberOrArray(transaction.chainId, criterionValue)\n\n case 'context':\n if (!options?.context) return false // No context provided, can't match\n return matchesStringOrArray(options.context, criterionValue)\n\n case 'contextRequirements':\n if (!options?.contextRequirements || !criterionValue) return false\n return areContextRequirementsCompatible(\n options.contextRequirements,\n criterionValue\n )\n\n case 'customMatcher':\n if (typeof criterionValue === 'function') {\n try {\n const matchCount = criterionValue(transaction)\n // Match if any conditions matched (> 0)\n // The actual count contributes to the score in calculateMatchScore\n return matchCount > 0\n } catch (error) {\n console.warn('Custom matcher threw error:', error)\n return false\n }\n }\n return false\n\n default:\n return false\n }\n}\n\n/**\n * Helper to match string values against string or array criteria\n */\nfunction matchesStringOrArray(\n value: string | undefined,\n criteria: string | string[]\n): boolean {\n if (!value || !criteria) return false\n\n if (Array.isArray(criteria)) {\n return criteria.includes(value)\n }\n\n return value === criteria\n}\n\n/**\n * Helper to match number values against number or array criteria\n */\nfunction matchesNumberOrArray(\n value: number | undefined,\n criteria: number | number[]\n): boolean {\n if (value === undefined || criteria === undefined) return false\n\n if (Array.isArray(criteria)) {\n return criteria.includes(value)\n }\n\n return value === criteria\n}\n\n/**\n * Check if context requirements are compatible\n */\nfunction areContextRequirementsCompatible(\n requested: any,\n viewRequirements: any\n): boolean {\n // Simple compatibility check - can be extended\n if (requested.detailLevel && viewRequirements.detailLevel) {\n const detailOrder = ['minimal', 'summary', 'full', 'debug']\n const requestedLevel = detailOrder.indexOf(requested.detailLevel)\n const viewLevel = detailOrder.indexOf(viewRequirements.detailLevel)\n if (viewLevel < requestedLevel) return false\n }\n\n if (requested.maxHeight && viewRequirements.maxHeight) {\n if (viewRequirements.maxHeight > requested.maxHeight) return false\n }\n\n return true\n}\n\n/**\n * Calculate native framework priority bonus\n *\n * Native framework implementations (Vue, React Native) get priority over Lit fallbacks:\n * - Vue: +0.15 bonus when view has Vue implementation\n * - React Native (rn): +0.15 bonus when view has RN implementation\n * - Lit: NO bonus (Lit is the universal fallback)\n *\n * This ensures that when both native and Lit views exist for the same transaction:\n * - Vue app prefers Vue view (Vue score + 0.15 > Lit score)\n * - React Native app prefers RN view (RN score + 0.15 > Lit score)\n * - Other frameworks use Lit view (universal compatibility)\n */\nfunction calculateNativeFrameworkBonus(\n view: ViewDefinition,\n requestedFramework: 'lit' | 'vue' | 'rn'\n): number {\n // Lit gets no bonus - it's the universal fallback\n if (requestedFramework === 'lit') {\n return 0\n }\n\n // Vue gets bonus if view has Vue implementation\n if (requestedFramework === 'vue' && view.frameworks.vue) {\n return 0.15\n }\n\n // React Native gets bonus if view has RN implementation\n if (requestedFramework === 'rn' && view.frameworks.rn) {\n return 0.15\n }\n\n return 0\n}\n\n/**\n * Find and score all matching views for a transaction\n *\n * Views are matched and sorted by:\n * 1. Match score (how well criteria match the transaction)\n * 2. Native framework bonus (Vue/RN get +0.15, Lit gets 0)\n * 3. View priority (manually set priority)\n *\n * This ensures that native framework views are preferred when available,\n * while Lit serves as a universal fallback.\n */\nexport function findMatchingViews(\n transaction: DecoderResult,\n views: ViewDefinition[],\n options: ViewMatchOptions\n): ViewMatch[] {\n const matches: ViewMatch[] = []\n const minScore = options.minScore ?? 0\n\n for (const view of views) {\n // Skip if framework is not supported\n if (!view.frameworks[options.framework]) {\n continue\n }\n\n const { score, matchedCriteria } = calculateMatchScore(transaction, view, {\n context: options.context,\n contextRequirements: options.contextRequirements,\n })\n\n // Skip if score is below threshold\n if (score < minScore) {\n continue\n }\n\n // Apply native framework bonus (Vue/RN only, NOT Lit)\n const frameworkBonus = calculateNativeFrameworkBonus(\n view,\n options.framework\n )\n const finalScore = Math.min(1, score + frameworkBonus)\n\n const match: ViewMatch = {\n view,\n score: finalScore,\n matchedCriteria,\n frameworkConfig: options.includeFrameworkConfig\n ? view.frameworks[options.framework]\n : undefined,\n }\n\n matches.push(match)\n }\n\n // Sort by score (descending), then by priority (descending)\n matches.sort((a, b) => {\n if (a.score !== b.score) {\n return b.score - a.score\n }\n return b.view.priority - a.view.priority\n })\n\n // Limit results if requested\n if (options.maxMatches) {\n return matches.slice(0, options.maxMatches)\n }\n\n return matches\n}\n\n/**\n * TODO: Future enhancement for batch operations\n *\n * For batch operations like executeBatch, setDataBatch, we might want to:\n * 1. Match against the batch container (current behavior)\n * 2. Also match against child transactions for more specific views\n * 3. Allow views to specify whether they handle batches vs individual items\n * 4. Support composite views that render both batch info + child items\n */\n","import type { DecoderResult } from '@lukso/transaction-decoder'\nimport type {\n ViewDefinition,\n ViewMatch,\n ViewMatchOptions,\n ViewRegistry,\n} from '../types/view-matching'\nimport { findMatchingViews } from '../utils/view-matcher'\n\n/**\n * Default view registry implementation\n */\nexport class DefaultViewRegistry implements ViewRegistry {\n private views = new Map<string, ViewDefinition>()\n\n register(view: ViewDefinition): void {\n if (this.views.has(view.id)) {\n console.warn(\n `View with id \"${view.id}\" is already registered. Overwriting.`\n )\n }\n\n this.views.set(view.id, view)\n }\n\n unregister(viewId: string): void {\n this.views.delete(viewId)\n }\n\n getAllViews(): ViewDefinition[] {\n return Array.from(this.views.values())\n }\n\n findMatches(\n transaction: DecoderResult,\n options: ViewMatchOptions\n ): ViewMatch[] {\n const allViews = this.getAllViews()\n return findMatchingViews(transaction, allViews, options)\n }\n\n getView(viewId: string): ViewDefinition | undefined {\n return this.views.get(viewId)\n }\n\n clear(): void {\n this.views.clear()\n }\n\n /**\n * Get the best matching view (highest score) for a transaction\n */\n getBestMatch(\n transaction: DecoderResult,\n options: ViewMatchOptions\n ): ViewMatch | null {\n const matches = this.findMatches(transaction, { ...options, maxMatches: 1 })\n return matches[0] || null\n }\n\n /**\n * Bulk register multiple views\n */\n registerMany(views: ViewDefinition[]): void {\n for (const view of views) {\n this.register(view)\n }\n }\n\n /**\n * Get stats about registered views\n */\n getStats(): {\n totalViews: number\n viewsByFramework: Record<string, number>\n viewsByRecordType: Record<string, number>\n } {\n const allViews = this.getAllViews()\n const totalViews = allViews.length\n\n const viewsByFramework: Record<string, number> = {}\n const viewsByRecordType: Record<string, number> = {}\n\n for (const view of allViews) {\n // Count framework support\n for (const framework of Object.keys(view.frameworks)) {\n viewsByFramework[framework] = (viewsByFramework[framework] || 0) + 1\n }\n\n // Count by record type\n const recordType = view.criteria.recordType\n if (recordType) {\n const types = Array.isArray(recordType) ? recordType : [recordType]\n for (const type of types) {\n viewsByRecordType[type] = (viewsByRecordType[type] || 0) + 1\n }\n }\n }\n\n return {\n totalViews,\n viewsByFramework,\n viewsByRecordType,\n }\n }\n}\n\n/**\n * Global registry instance\n */\nlet globalRegistry: ViewRegistry | null = null\n\n/**\n * Get or create the global view registry\n */\nexport function getGlobalRegistry(): ViewRegistry {\n if (!globalRegistry) {\n globalRegistry = new DefaultViewRegistry()\n }\n return globalRegistry\n}\n\n/**\n * Set a custom global registry (useful for testing or custom implementations)\n */\nexport function setGlobalRegistry(registry: ViewRegistry): void {\n globalRegistry = registry\n}\n\n/**\n * Reset the global registry (mainly for testing)\n */\nexport function resetGlobalRegistry(): void {\n globalRegistry = null\n}\n"],"mappings":"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","names":["module"]}
|
|
1
|
+
{"version":3,"sources":["../../src/registry/view-loader.ts","../../src/utils/view-matcher.ts","../../src/registry/view-registry.ts"],"sourcesContent":["import type {\n FrameworkViewConfig,\n ViewLoader,\n ViewMatch,\n} from '../types/view-matching'\n\n/**\n * Error thrown when view loading fails\n */\nexport class ViewLoadingError extends Error {\n public readonly loader: ViewLoader\n public readonly config: FrameworkViewConfig\n public override readonly cause?: Error\n\n constructor(\n message: string,\n loader: ViewLoader,\n config: FrameworkViewConfig,\n cause?: Error\n ) {\n super(message)\n this.name = 'ViewLoadingError'\n this.loader = loader\n this.config = config\n this.cause = cause\n }\n}\n\n/**\n * Framework-agnostic view loader that handles different loading strategies\n */\nexport class UniversalViewLoader {\n private cache = new Map<string, any>()\n\n /**\n * Load a component based on the framework configuration\n */\n async loadComponent(config: FrameworkViewConfig): Promise<any> {\n const cacheKey = this.getCacheKey(config)\n\n // Return cached component if available\n if (this.cache.has(cacheKey)) {\n return this.cache.get(cacheKey)\n }\n\n try {\n const component = await this.loadByStrategy(config.loader)\n this.cache.set(cacheKey, component)\n return component\n } catch (error) {\n throw new ViewLoadingError(\n `Failed to load component \"${config.component}\"`,\n config.loader,\n config,\n error instanceof Error ? error : new Error(String(error))\n )\n }\n }\n\n /**\n * Load a component from a view match\n */\n async loadFromMatch(match: ViewMatch): Promise<any> {\n if (!match.frameworkConfig) {\n throw new ViewLoadingError(\n `No framework config available for view \"${match.view.id}\"`,\n { type: 'dynamic-import', path: '' },\n {} as FrameworkViewConfig\n )\n }\n\n return this.loadComponent(match.frameworkConfig)\n }\n\n /**\n * Load component using the specific strategy\n */\n private async loadByStrategy(loader: ViewLoader): Promise<any> {\n switch (loader.type) {\n case 'dynamic-import':\n return this.loadDynamicImport(loader.path)\n\n case 'static-import':\n return this.loadStaticImport(loader.path)\n\n case 'custom-element':\n return this.loadCustomElement(loader.tagName)\n\n case 'registry-lookup':\n return this.loadFromRegistry(loader.registryKey)\n\n case 'custom':\n return loader.loader({} as FrameworkViewConfig) // Will be passed proper config in real usage\n\n default:\n throw new Error(`Unknown loader type: ${(loader as any).type}`)\n }\n }\n\n /**\n * Dynamic import strategy (most common)\n * Supports both static strings and lazy-loaded callbacks\n */\n private async loadDynamicImport(\n path: string | (() => Promise<any>)\n ): Promise<any> {\n // Handle callback-based lazy loading\n if (typeof path === 'function') {\n const module = await path()\n\n // Handle different export patterns\n if (module.default) {\n return module.default\n }\n\n return module\n }\n\n // Handle string-based path (static)\n const module = await import(/* @vite-ignore */ path)\n\n // Handle different export patterns\n if (module.default) {\n return module.default\n }\n\n // If no default export, return the entire module\n return module\n }\n\n /**\n * Static import strategy (requires bundler support)\n * Supports both static strings and lazy-loaded callbacks\n */\n private async loadStaticImport(\n path: string | (() => Promise<any>)\n ): Promise<any> {\n // Handle callback-based lazy loading\n if (typeof path === 'function') {\n const module = await path()\n\n if (module.default) {\n return module.default\n }\n\n return module\n }\n\n // This would typically be handled by bundler transformation\n // For now, fall back to dynamic import\n console.warn(\n 'Static import not implemented, falling back to dynamic import'\n )\n return this.loadDynamicImport(path)\n }\n\n /**\n * Custom element strategy (for Lit components)\n */\n private async loadCustomElement(tagName: string): Promise<any> {\n // Wait for custom element to be defined\n if (typeof window !== 'undefined' && window.customElements) {\n await window.customElements.whenDefined(tagName)\n return { tagName, type: 'custom-element' }\n }\n\n throw new Error('Custom elements not available in this environment')\n }\n\n /**\n * Registry lookup strategy (for pre-registered components)\n */\n private async loadFromRegistry(registryKey: string): Promise<any> {\n // This would look up in a component registry\n // Implementation depends on framework\n throw new Error(`Registry lookup not implemented for key: ${registryKey}`)\n }\n\n /**\n * Generate cache key for component config\n */\n private getCacheKey(config: FrameworkViewConfig): string {\n const { loader, component, package: pkg } = config\n return JSON.stringify({ loader, component, package: pkg })\n }\n\n /**\n * Clear the component cache\n */\n clearCache(): void {\n this.cache.clear()\n }\n\n /**\n * Get cache statistics\n */\n getCacheStats(): { size: number; keys: string[] } {\n return {\n size: this.cache.size,\n keys: Array.from(this.cache.keys()),\n }\n }\n}\n\n/**\n * Singleton loader instance\n */\nlet globalLoader: UniversalViewLoader | null = null\n\n/**\n * Get the global view loader\n */\nexport function getGlobalLoader(): UniversalViewLoader {\n if (!globalLoader) {\n globalLoader = new UniversalViewLoader()\n }\n return globalLoader\n}\n\n/**\n * Set a custom global loader (useful for testing)\n */\nexport function setGlobalLoader(loader: UniversalViewLoader): void {\n globalLoader = loader\n}\n\n/**\n * Framework-specific helpers for strategically optimized loading patterns\n *\n * Following our Suffering Economics optimization, we support:\n * - Lit Web Components (universal web compatibility) - REQUIRED\n * - Vue (native Vue optimization) - OPTIONAL\n * - React Native (mobile-native optimization) - OPTIONAL (WebView fallback available)\n *\n * All loaders support lazy loading via callbacks:\n * ```typescript\n * // Static (bundled)\n * vueComponent('./Component.vue')\n *\n * // Lazy (loaded on demand)\n * vueComponent(() => import('./Component.vue'))\n * ```\n */\nexport const LoaderHelpers = {\n /**\n * Create a Lit custom element loader (universal web compatibility)\n */\n litComponent(tagName: string): ViewLoader {\n return { type: 'custom-element', tagName }\n },\n\n /**\n * Create a Vue component loader (native Vue, optional)\n * Supports both static paths and lazy-loaded callbacks\n */\n vueComponent(path: string | (() => Promise<any>)): ViewLoader {\n return { type: 'dynamic-import', path }\n },\n\n /**\n * Create a React Native JSX dynamic import loader (mobile-native, optional)\n * Supports both static paths and lazy-loaded callbacks\n */\n rnComponent(path: string | (() => Promise<any>)): ViewLoader {\n return { type: 'dynamic-import', path }\n },\n\n /**\n * Create a custom loader function for advanced use cases\n */\n custom(loader: (config: FrameworkViewConfig) => Promise<any>): ViewLoader {\n return { type: 'custom', loader }\n },\n\n // Legacy helpers for compilation pipelines (Vue/React → Lit)\n /**\n * @deprecated Use litComponent() instead. This exists for compilation pipeline compatibility.\n */\n vueToLitCompiled(tagName: string): ViewLoader {\n console.warn(\n 'vueToLitCompiled is deprecated. Use litComponent() - the output is the same.'\n )\n return { type: 'custom-element', tagName }\n },\n\n /**\n * @deprecated Use litComponent() instead. This exists for compilation pipeline compatibility.\n */\n reactToLitCompiled(tagName: string): ViewLoader {\n console.warn(\n 'reactToLitCompiled is deprecated. Use litComponent() - the output is the same.'\n )\n return { type: 'custom-element', tagName }\n },\n\n /**\n * @deprecated Use rnComponent() instead. Updated for better TypeScript support.\n */\n reactNativeComponent(path: string): ViewLoader {\n console.warn(\n 'reactNativeComponent is deprecated. Use rnComponent() instead.'\n )\n return { type: 'dynamic-import', path }\n },\n}\n","import type { DecoderResult } from '@lukso/transaction-decoder'\nimport type {\n DecoderRecordForSelection,\n ViewDefinition,\n ViewMatch,\n ViewMatchCriteria,\n ViewMatchOptions,\n} from '../types/view-matching'\n\n/**\n * Weights for different matching criteria (higher = more important)\n * Context is optional - only weighted when both view and request specify context\n */\nexport const CRITERIA_WEIGHTS = {\n recordType: 0.25, // Most specific to transaction type\n functionName: 0.2, // Function-level specificity\n context: 0.2, // Context specificity (when opt-in)\n standard: 0.15, // LSP standard specificity\n contractAddress: 0.1, // Contract-specific logic\n contextRequirements: 0.05, // Context requirement matching\n chainId: 0.03, // Network-specific behavior\n customMatcher: 0.02, // Custom logic (lowest weight due to unpredictability)\n} as const\n\n/**\n * Calculate how well a view matches a transaction and context\n *\n * Context matching is opt-in:\n * - If view specifies context criteria, request MUST provide matching context\n * - If view has no context criteria, it matches any context (universal view)\n * - If request has no context, context-specific views are deprioritized\n *\n * Note: For batch operations (executeBatch, setDataBatch, etc.), this matches\n * against the parent transaction. Future enhancement could include matching\n * against child transactions for more granular view selection.\n */\nexport function calculateMatchScore(\n transaction: DecoderResult,\n view: ViewDefinition,\n options?: Pick<ViewMatchOptions, 'context' | 'contextRequirements'>\n): { score: number; matchedCriteria: (keyof ViewMatchCriteria)[] } {\n const { criteria } = view\n const matchedCriteria: (keyof ViewMatchCriteria)[] = []\n let totalWeight = 0\n let matchedWeight = 0\n\n // Check each criterion and accumulate scores\n for (const [criterion, weight] of Object.entries(CRITERIA_WEIGHTS)) {\n const criterionKey = criterion as keyof ViewMatchCriteria\n const criterionValue = criteria[criterionKey]\n\n if (criterionValue === undefined) continue\n\n totalWeight += weight\n\n // Special handling for customMatcher - use match count\n if (\n criterionKey === 'customMatcher' &&\n typeof criterionValue === 'function'\n ) {\n try {\n const matchCount = criterionValue(transaction)\n if (matchCount > 0) {\n matchedCriteria.push(criterionKey)\n // Normalize match count to 0-1 range (cap at 10 conditions)\n const normalizedScore = Math.min(matchCount / 10, 1)\n matchedWeight += weight * normalizedScore\n }\n } catch (error) {\n console.warn('Custom matcher threw error:', error)\n }\n continue\n }\n\n if (\n doesCriterionMatch(transaction, criterionKey, criterionValue, options)\n ) {\n matchedCriteria.push(criterionKey)\n matchedWeight += weight\n }\n }\n\n // Handle context opt-in logic\n const viewHasContext = criteria.context !== undefined\n const requestHasContext = options?.context !== undefined\n\n if (viewHasContext && !requestHasContext) {\n // View requires specific context, but none provided - penalize heavily\n matchedWeight *= 0.1 // Reduce score by 90%\n } else if (!viewHasContext && requestHasContext) {\n // Universal view matching specific context - slight penalty to prefer context-specific views\n matchedWeight *= 0.9 // Reduce score by 10%\n }\n\n // If no criteria are defined, this view doesn't match\n if (totalWeight === 0) return { score: 0, matchedCriteria: [] }\n\n // Calculate final score (0-1)\n const score = matchedWeight / totalWeight\n\n return { score, matchedCriteria }\n}\n\n/**\n * Check if a specific criterion matches the transaction\n */\nfunction doesCriterionMatch(\n transaction: DecoderResult,\n criterion: keyof ViewMatchCriteria,\n criterionValue: any,\n options?: Pick<ViewMatchOptions, 'context' | 'contextRequirements'>\n): boolean {\n switch (criterion) {\n case 'recordType':\n return matchesStringOrArray(\n (transaction as DecoderRecordForSelection).recordType,\n criterionValue\n )\n\n case 'functionName':\n return matchesStringOrArray(\n (transaction as DecoderRecordForSelection).functionName,\n criterionValue\n )\n\n case 'standard':\n return matchesStringOrArray(\n (transaction as DecoderRecordForSelection).standard,\n criterionValue\n )\n\n case 'contractAddress':\n return matchesStringOrArray(\n (transaction as DecoderRecordForSelection).contractAddress,\n criterionValue\n )\n\n case 'chainId':\n return matchesNumberOrArray(transaction.chainId, criterionValue)\n\n case 'context':\n if (!options?.context) return false // No context provided, can't match\n return matchesStringOrArray(options.context, criterionValue)\n\n case 'contextRequirements':\n if (!options?.contextRequirements || !criterionValue) return false\n return areContextRequirementsCompatible(\n options.contextRequirements,\n criterionValue\n )\n\n case 'customMatcher':\n if (typeof criterionValue === 'function') {\n try {\n const matchCount = criterionValue(transaction)\n // Match if any conditions matched (> 0)\n // The actual count contributes to the score in calculateMatchScore\n return matchCount > 0\n } catch (error) {\n console.warn('Custom matcher threw error:', error)\n return false\n }\n }\n return false\n\n default:\n return false\n }\n}\n\n/**\n * Helper to match string values against string or array criteria\n */\nfunction matchesStringOrArray(\n value: string | undefined,\n criteria: string | string[]\n): boolean {\n if (!value || !criteria) return false\n\n if (Array.isArray(criteria)) {\n return criteria.includes(value)\n }\n\n return value === criteria\n}\n\n/**\n * Helper to match number values against number or array criteria\n */\nfunction matchesNumberOrArray(\n value: number | undefined,\n criteria: number | number[]\n): boolean {\n if (value === undefined || criteria === undefined) return false\n\n if (Array.isArray(criteria)) {\n return criteria.includes(value)\n }\n\n return value === criteria\n}\n\n/**\n * Check if context requirements are compatible\n */\nfunction areContextRequirementsCompatible(\n requested: any,\n viewRequirements: any\n): boolean {\n // Simple compatibility check - can be extended\n if (requested.detailLevel && viewRequirements.detailLevel) {\n const detailOrder = ['minimal', 'summary', 'full', 'debug']\n const requestedLevel = detailOrder.indexOf(requested.detailLevel)\n const viewLevel = detailOrder.indexOf(viewRequirements.detailLevel)\n if (viewLevel < requestedLevel) return false\n }\n\n if (requested.maxHeight && viewRequirements.maxHeight) {\n if (viewRequirements.maxHeight > requested.maxHeight) return false\n }\n\n return true\n}\n\n/**\n * Calculate native framework priority bonus\n *\n * Native framework implementations (Vue, React Native) get priority over Lit fallbacks:\n * - Vue: +0.15 bonus when view has Vue implementation\n * - React Native (rn): +0.15 bonus when view has RN implementation\n * - Lit: NO bonus (Lit is the universal fallback)\n *\n * This ensures that when both native and Lit views exist for the same transaction:\n * - Vue app prefers Vue view (Vue score + 0.15 > Lit score)\n * - React Native app prefers RN view (RN score + 0.15 > Lit score)\n * - Other frameworks use Lit view (universal compatibility)\n */\nfunction calculateNativeFrameworkBonus(\n view: ViewDefinition,\n requestedFramework: 'lit' | 'vue' | 'rn'\n): number {\n // Lit gets no bonus - it's the universal fallback\n if (requestedFramework === 'lit') {\n return 0\n }\n\n // Vue gets bonus if view has Vue implementation\n if (requestedFramework === 'vue' && view.frameworks.vue) {\n return 0.15\n }\n\n // React Native gets bonus if view has RN implementation\n if (requestedFramework === 'rn' && view.frameworks.rn) {\n return 0.15\n }\n\n return 0\n}\n\n/**\n * Find and score all matching views for a transaction\n *\n * Views are matched and sorted by:\n * 1. Match score (how well criteria match the transaction)\n * 2. Native framework bonus (Vue/RN get +0.15, Lit gets 0)\n * 3. View priority (manually set priority)\n *\n * This ensures that native framework views are preferred when available,\n * while Lit serves as a universal fallback.\n */\nexport function findMatchingViews(\n transaction: DecoderResult,\n views: ViewDefinition[],\n options: ViewMatchOptions\n): ViewMatch[] {\n const matches: ViewMatch[] = []\n const minScore = options.minScore ?? 0\n\n for (const view of views) {\n // Skip if framework is not supported\n if (!view.frameworks[options.framework]) {\n continue\n }\n\n const { score, matchedCriteria } = calculateMatchScore(transaction, view, {\n context: options.context,\n contextRequirements: options.contextRequirements,\n })\n\n // Skip if score is below threshold\n if (score < minScore) {\n continue\n }\n\n // Apply native framework bonus (Vue/RN only, NOT Lit)\n const frameworkBonus = calculateNativeFrameworkBonus(\n view,\n options.framework\n )\n const finalScore = Math.min(1, score + frameworkBonus)\n\n const match: ViewMatch = {\n view,\n score: finalScore,\n matchedCriteria,\n frameworkConfig: options.includeFrameworkConfig\n ? view.frameworks[options.framework]\n : undefined,\n }\n\n matches.push(match)\n }\n\n // Sort by score (descending), then by priority (descending)\n matches.sort((a, b) => {\n if (a.score !== b.score) {\n return b.score - a.score\n }\n return b.view.priority - a.view.priority\n })\n\n // Limit results if requested\n if (options.maxMatches) {\n return matches.slice(0, options.maxMatches)\n }\n\n return matches\n}\n\n/**\n * TODO: Future enhancement for batch operations\n *\n * For batch operations like executeBatch, setDataBatch, we might want to:\n * 1. Match against the batch container (current behavior)\n * 2. Also match against child transactions for more specific views\n * 3. Allow views to specify whether they handle batches vs individual items\n * 4. Support composite views that render both batch info + child items\n */\n","import type { DecoderResult } from '@lukso/transaction-decoder'\nimport type {\n ViewDefinition,\n ViewMatch,\n ViewMatchOptions,\n ViewRegistry,\n} from '../types/view-matching'\nimport { findMatchingViews } from '../utils/view-matcher'\n\n/**\n * Default view registry implementation\n */\nexport class DefaultViewRegistry implements ViewRegistry {\n private views = new Map<string, ViewDefinition>()\n\n register(view: ViewDefinition): void {\n if (this.views.has(view.id)) {\n console.warn(\n `View with id \"${view.id}\" is already registered. Overwriting.`\n )\n }\n\n this.views.set(view.id, view)\n }\n\n unregister(viewId: string): void {\n this.views.delete(viewId)\n }\n\n getAllViews(): ViewDefinition[] {\n return Array.from(this.views.values())\n }\n\n findMatches(\n transaction: DecoderResult,\n options: ViewMatchOptions\n ): ViewMatch[] {\n const allViews = this.getAllViews()\n return findMatchingViews(transaction, allViews, options)\n }\n\n getView(viewId: string): ViewDefinition | undefined {\n return this.views.get(viewId)\n }\n\n clear(): void {\n this.views.clear()\n }\n\n /**\n * Get the best matching view (highest score) for a transaction\n */\n getBestMatch(\n transaction: DecoderResult,\n options: ViewMatchOptions\n ): ViewMatch | null {\n const matches = this.findMatches(transaction, { ...options, maxMatches: 1 })\n return matches[0] || null\n }\n\n /**\n * Bulk register multiple views\n */\n registerMany(views: ViewDefinition[]): void {\n for (const view of views) {\n this.register(view)\n }\n }\n\n /**\n * Get stats about registered views\n */\n getStats(): {\n totalViews: number\n viewsByFramework: Record<string, number>\n viewsByRecordType: Record<string, number>\n } {\n const allViews = this.getAllViews()\n const totalViews = allViews.length\n\n const viewsByFramework: Record<string, number> = {}\n const viewsByRecordType: Record<string, number> = {}\n\n for (const view of allViews) {\n // Count framework support\n for (const framework of Object.keys(view.frameworks)) {\n viewsByFramework[framework] = (viewsByFramework[framework] || 0) + 1\n }\n\n // Count by record type\n const recordType = view.criteria.recordType\n if (recordType) {\n const types = Array.isArray(recordType) ? recordType : [recordType]\n for (const type of types) {\n viewsByRecordType[type] = (viewsByRecordType[type] || 0) + 1\n }\n }\n }\n\n return {\n totalViews,\n viewsByFramework,\n viewsByRecordType,\n }\n }\n}\n\n/**\n * Global registry instance\n */\nlet globalRegistry: ViewRegistry | null = null\n\n/**\n * Get or create the global view registry\n */\nexport function getGlobalRegistry(): ViewRegistry {\n if (!globalRegistry) {\n globalRegistry = new DefaultViewRegistry()\n }\n return globalRegistry\n}\n\n/**\n * Set a custom global registry (useful for testing or custom implementations)\n */\nexport function setGlobalRegistry(registry: ViewRegistry): void {\n globalRegistry = registry\n}\n\n/**\n * Reset the global registry (mainly for testing)\n */\nexport function resetGlobalRegistry(): void {\n globalRegistry = null\n}\n"],"mappings":"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","names":["module"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lukso/transaction-view-headless",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "Framework-agnostic transaction decoder and view selection system",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -32,11 +32,14 @@
|
|
|
32
32
|
"require": "./dist/utils/index.cjs"
|
|
33
33
|
}
|
|
34
34
|
},
|
|
35
|
+
"publishConfig": {
|
|
36
|
+
"access": "public"
|
|
37
|
+
},
|
|
35
38
|
"dependencies": {
|
|
36
39
|
"@preact/signals-core": "^1.13.0",
|
|
37
40
|
"@tanstack/query-core": "^5.90.20",
|
|
38
41
|
"viem": "^2.46.1",
|
|
39
|
-
"@lukso/transaction-decoder": "1.
|
|
42
|
+
"@lukso/transaction-decoder": "1.4.0"
|
|
40
43
|
},
|
|
41
44
|
"devDependencies": {
|
|
42
45
|
"@types/node": "^25.2.3",
|