-
-
Notifications
You must be signed in to change notification settings - Fork 31
NEW: Custom message formatter #198
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
Changed the structure so that alternative formatters can be added. Improved performance
|
I will try to integrate this in my app first to get experience in running this in a production app. In Literary Universe we use ICU message format so that is why I want this feature as migrating to the current custom default would be more trouble than it is worth. |
jankapunkt
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added comments for discussion but generally approved. Feel free to update the changes on your behalf. From my end they are not serious but nitpickings.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR adds a pluggable message formatter system to universe:i18n, allowing developers to use custom message formats (e.g., ICU MessageFormat) while maintaining backward compatibility with the default format. The implementation also includes multiple performance optimizations using modern JavaScript APIs.
- Introduces
MessageFormatterinterface andDefaultMessageFormatterclass for customizable message formatting - Adds comprehensive test coverage for the new formatter functionality (8 new tests)
- Implements significant performance improvements by replacing
forEachloops withfor...of, usingreplaceAll()instead ofsplit().join(), and other optimizations
Reviewed Changes
Copilot reviewed 11 out of 18 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/common.ts | Adds comprehensive test suite for custom message formatters with 8 new test cases |
| source/utils.ts | Performance optimization: replaces shift() with index-based iteration |
| source/formatters/default.ts | New default message formatter implementing the original universe:i18n format |
| source/formatters/base.ts | Defines MessageFormatter interface and FormatterOptions for the formatter system |
| source/common.ts | Integrates formatter system, adds performance optimizations, and refactors translation logic |
| source/code-generators.ts | Performance optimization: uses Set for O(1) lookups instead of Array.includes() |
| source/client.ts | Performance optimization: replaces forEach and map with for...of loops |
| package.js | Updates package version to 3.1.0 and adds new formatter source files |
| README.md | Updates feature list to mention pluggable message formatters |
| CUSTOM_FORMATTERS.md | Comprehensive documentation for the new formatter system with examples |
| CHANGELOG.md | Documents all changes and performance improvements in version 3.1.0 |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
…tion Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
Added the option to add custom message formatters.
Also added more tests and improved performance using new JS API and other known performance boosts like using for of loops instead of forEach.
Custom Message Formatters
Overview
The formatter system allows you to:
Default Formatter
The package ships with a
DefaultMessageFormatterthat implements the original universe:i18n format:Interpolation:
Pluralization:
Creating a Custom Formatter
To create a custom formatter, implement the
MessageFormatterinterface:MessageFormatter Interface
FormatterOptions
The
optionsparameter provides access to configuration:Using a Custom Formatter
Set your custom formatter using
setOptions():Important: Set the formatter before loading any translations or calling translation functions.
ICU Message Format Example
Here's an example of implementing an ICU MessageFormat formatter using the
intl-messageformatlibrary:1. Install the dependency
2. Create the ICU formatter
3. Use the ICU formatter
4. Write ICU-formatted translations
5. Use the translations
API Reference
Exported Types
Setting a Formatter
Accessing the Current Formatter
Best Practices
Cache Compiled Messages: If your formatter compiles messages (like ICU), cache the compiled results for better performance.
Error Handling: Always handle errors gracefully and return the original message if formatting fails.
Memory Management: For long-running applications, consider implementing cache size limits or LRU eviction.
Type Safety: Use TypeScript to ensure your formatter implements the interface correctly.
Testing: Write comprehensive tests for your custom formatter with various message patterns.
Documentation: Document the message format syntax your formatter supports for other developers.
Migration from Default to Custom Format
If you're migrating from the default format to a custom format (e.g., ICU):
Gradual Migration: You can use different formatters for different locales if needed by creating a wrapper formatter that delegates based on locale.
Conversion Script: Write a script to convert your existing translation files to the new format.
Testing: Thoroughly test all translations after migration to ensure nothing breaks.
Fallback: Consider implementing a fallback mechanism that tries the new format first, then falls back to the old format if parsing fails.
Example: Hybrid Formatter
Here's an example of a formatter that supports both default and ICU formats: