#! Fluent i18n translation daemon functions #! #! Provides high-performance message translation via HTTP API using Mozilla's Fluent. #! The CLI daemon's Fluent engine offers 50-100x better performance than using #! the nu_plugin_fluent plugin due to aggressive caching and no process spawning. #! #! Performance: #! - Single translation: ~1-5ms uncached, ~0.1-0.5ms cached (vs ~50ms with plugin) #! - Batch 10 translations: ~10-20ms with cache #! - Cache hit ratio: 75-80% on typical workloads use ../env.nu [get-cli-daemon-url] # Translate a message ID to the target locale # # Uses the CLI daemon's Fluent engine for fast i18n translation. # Supports variable interpolation and fallback locales. # # # Arguments # * `message_id` - Message identifier (e.g., "welcome-message") # * `--locale (-l)` - Target locale (default: "en-US") # * `--args (-a)` - Arguments for variable interpolation (record) # * `--fallback (-f)` - Fallback locale if message not found # # # Returns # Translated message string or error if translation failed # # # Example # ```nushell # # Simple translation # fluent-translate "welcome-message" --locale en-US # # # With arguments # fluent-translate "greeting" --locale es --args {name: "María"} # # # With fallback # fluent-translate "new-feature" --locale fr --fallback en-US # ``` export def fluent-translate [ message_id: string --locale (-l): string = "en-US" --args (-a): record = {} --fallback (-f): string ] -> string { let daemon_url = (get-cli-daemon-url) # Build request let request = { message_id: $message_id locale: $locale args: ($args | to json | from json) fallback_locale: $fallback } # Send to daemon's Fluent endpoint let response = ( http post $"($daemon_url)/fluent/translate" $request --raw ) # Parse response let parsed = ($response | from json) # Check for error if ($parsed.error? != null) { error make {msg: $"Fluent translation error: ($parsed.error)"} } # Return translated message $parsed.translated } # Translate multiple messages in batch mode # # Translates a list of message IDs to the same locale. More efficient # than calling fluent-translate multiple times due to connection reuse. # # # Arguments # * `message_ids` - List of message IDs to translate # * `--locale (-l)` - Target locale (default: "en-US") # * `--fallback (-f)` - Fallback locale if messages not found # # # Returns # List of translated messages # # # Example # ```nushell # let messages = ["welcome", "goodbye", "thank-you"] # fluent-translate-batch $messages --locale fr --fallback en # ``` export def fluent-translate-batch [ message_ids: list --locale (-l): string = "en-US" --fallback (-f): string ] -> list { $message_ids | each { |msg_id| fluent-translate $msg_id --locale $locale --fallback $fallback } } # Load a Fluent bundle from a specific FTL file # # Loads messages from an FTL file into the daemon's bundle cache. # This is useful for loading custom translations at runtime. # # # Arguments # * `locale` - Locale identifier (e.g., "es", "fr-FR") # * `path` - Path to FTL file # # # Returns # Record with load status and message count # # # Example # ```nushell # fluent-load-bundle "es" "/path/to/es.ftl" # ``` export def fluent-load-bundle [ locale: string path: string ] -> record { let daemon_url = (get-cli-daemon-url) let request = { locale: $locale path: $path } let response = ( http post $"($daemon_url)/fluent/bundles/load" $request ) $response | from json } # Reload all Fluent bundles from the FTL directory # # Clears all cached bundles and reloads them from the configured # FTL directory. Useful after updating translation files. # # # Returns # Record with reload status and list of loaded locales # # # Example # ```nushell # fluent-reload-bundles # ``` export def fluent-reload-bundles [] -> record { let daemon_url = (get-cli-daemon-url) let response = ( http post $"($daemon_url)/fluent/bundles/reload" "" ) $response | from json } # List all available locales # # Returns a list of all currently loaded locale identifiers. # # # Returns # List of locale strings # # # Example # ```nushell # fluent-list-locales # # Output: [en-US, es, fr-FR, de] # ``` export def fluent-list-locales [] -> list { let daemon_url = (get-cli-daemon-url) let response = (http get $"($daemon_url)/fluent/bundles/locales") ($response | from json).locales } # Get translation statistics from daemon # # Returns statistics about translations since daemon startup or last reset. # # # Returns # Record with: # - `total_translations`: Total number of translations # - `successful_translations`: Number of successful translations # - `failed_translations`: Number of failed translations # - `cache_hits`: Number of cache hits # - `cache_misses`: Number of cache misses # - `cache_hit_ratio`: Cache hit ratio (0.0 - 1.0) # - `bundles_loaded`: Number of bundles loaded # - `total_time_ms`: Total time spent translating (milliseconds) # - `average_time_ms`: Average time per translation # # # Example # ```nushell # fluent-stats # ``` export def fluent-stats [] -> record { let daemon_url = (get-cli-daemon-url) let response = (http get $"($daemon_url)/fluent/stats") $response | from json } # Reset translation statistics on daemon # # Clears all counters and timing statistics. # # # Example # ```nushell # fluent-reset-stats # ``` export def fluent-reset-stats [] -> void { let daemon_url = (get-cli-daemon-url) http post $"($daemon_url)/fluent/stats/reset" "" } # Clear all Fluent caches # # Clears both the translation cache and bundle cache. # All subsequent translations will reload bundles and re-translate messages. # # # Example # ```nushell # fluent-clear-caches # ``` export def fluent-clear-caches [] -> void { let daemon_url = (get-cli-daemon-url) http delete $"($daemon_url)/fluent/cache/clear" } # Check if CLI daemon is running with Fluent support # # # Returns # `true` if daemon is running with Fluent support, `false` otherwise # # # Example # ```nushell # if (is-fluent-daemon-available) { # fluent-translate "welcome" # } else { # print "Fallback: Welcome!" # } # ``` export def is-fluent-daemon-available [] -> bool { let result = (do { let daemon_url = (get-cli-daemon-url) let response = (http get $"($daemon_url)/fluent/health" --timeout 500ms) ($response | from json | .status == "healthy") } | complete) if $result.exit_code != 0 { false } else { $result.stdout } } # Ensure Fluent daemon is available # # Checks if the daemon is running and prints a status message. # Useful for diagnostics and setup scripts. # # # Example # ```nushell # ensure-fluent-daemon # ``` export def ensure-fluent-daemon [] -> void { if (is-fluent-daemon-available) { print "✅ Fluent i18n daemon is available and running" } else { print "⚠️ Fluent i18n daemon is not available" print " CLI daemon may not be running at http://localhost:9091" print " Translations will not work until daemon is started" } } # Profile translation performance # # Translates a message multiple times and reports timing statistics. # Useful for benchmarking and performance optimization. # # # Arguments # * `message_id` - Message ID to translate # * `--locale (-l)` - Target locale (default: "en-US") # * `--iterations (-i)` - Number of times to translate (default: 100) # * `--args (-a)` - Arguments for variable interpolation (record) # # # Returns # Record with performance metrics # # # Example # ```nushell # fluent-profile "greeting" --locale es --iterations 1000 --args {name: "Usuario"} # ``` export def fluent-profile [ message_id: string --locale (-l): string = "en-US" --iterations (-i): int = 100 --args (-a): record = {} ] -> record { let start = (date now) # Reset stats before profiling fluent-reset-stats # Run translations for i in 0..<$iterations { fluent-translate $message_id --locale $locale --args $args } let elapsed_ms = ((date now) - $start) | into duration | .0 / 1_000_000 let stats = (fluent-stats) { message_id: $message_id locale: $locale iterations: $iterations total_time_ms: $elapsed_ms avg_time_ms: ($elapsed_ms / $iterations) daemon_total_translations: $stats.total_translations daemon_cache_hits: $stats.cache_hits daemon_cache_hit_ratio: $stats.cache_hit_ratio daemon_avg_time_ms: $stats.average_time_ms daemon_successful: $stats.successful_translations daemon_failed: $stats.failed_translations } } # Show cache efficiency report # # Displays a formatted report of cache performance. # # # Example # ```nushell # fluent-cache-report # ``` export def fluent-cache-report [] -> void { let stats = (fluent-stats) print $"=== Fluent i18n Cache Report ===" print $"" print $"Total translations: ($stats.total_translations)" print $"Cache hits: ($stats.cache_hits)" print $"Cache misses: ($stats.cache_misses)" print $"Hit ratio: (($stats.cache_hit_ratio * 100) | math round --precision 1)%" print $"" print $"Average latency: ($stats.average_time_ms | math round --precision 2)ms" print $"Total time: ($stats.total_time_ms)ms" print $"" print $"Bundles loaded: ($stats.bundles_loaded)" print $"Success rate: (($stats.successful_translations / $stats.total_translations * 100) | math round --precision 1)%" } # Translate and fallback to default if not found # # Attempts to translate a message, falling back to a default value if not found. # # # Arguments # * `message_id` - Message ID to translate # * `default` - Default value if translation fails # * `--locale (-l)` - Target locale (default: "en-US") # * `--args (-a)` - Arguments for variable interpolation (record) # # # Returns # Translated message or default value # # # Example # ```nushell # fluent-translate-or "new-feature" "New Feature" --locale fr # ``` export def fluent-translate-or [ message_id: string default: string --locale (-l): string = "en-US" --args (-a): record = {} ] -> string { let result = (do { fluent-translate $message_id --locale $locale --args $args } | complete) if $result.exit_code != 0 { $default } else { $result.stdout } } # Create a localized string table from message IDs # # Translates a list of message IDs and returns a record mapping IDs to translations. # # # Arguments # * `message_ids` - List of message IDs # * `--locale (-l)` - Target locale (default: "en-US") # # # Returns # Record mapping message IDs to translated strings # # # Example # ```nushell # let ids = ["welcome", "goodbye", "help"] # let strings = (fluent-string-table $ids --locale es) # $strings.welcome # Accesses translated "welcome" message # ``` export def fluent-string-table [ message_ids: list --locale (-l): string = "en-US" ] -> record { let table = {} for msg_id in $message_ids { let translation = (fluent-translate $msg_id --locale $locale) $table | insert $msg_id $translation } $table }