Skip to content

Commit

Permalink
Merge pull request #4 from sveyret/performance
Browse files Browse the repository at this point in the history
Rewrite to improve performances
  • Loading branch information
sveyret committed Jun 17, 2018
2 parents 2dead87 + 33cb96c commit b49345c
Show file tree
Hide file tree
Showing 9 changed files with 328 additions and 111 deletions.
25 changes: 17 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@

intl-ts is an i18n (internationlization) library for TypeScript. The package is compiled in ES2015 and so can also be used by JavaScript applications, but may require a Babel translation to be used with browsers. Its main features are:

* Type safe: using a wrong message name or the wrong type for the parameters will be checked at compile time. If your IDE allow it, you may even have completion for message names.
* Immutable: except for JavaScript representation of the `LanguageMap` (because of lazy initialization) object states will never change. New object is created when calling `LanguageMap.merge` or `Intl.$withPreferences`. Good for most state-aware framework, like React/Redux.
* Agnostic: can be used both at server or browser side.
- Type safe: using a wrong message name or the wrong type for the parameters will be checked at compile time. If your IDE allow it, you may even have completion for message names.
- Mutable or immutable: the library can be used in an immutable way (good for most state-aware framework, like React/Redux), or in a mutable way (for better performance).
- Agnostic: can be used both at server or browser side.

# Installation

Expand All @@ -36,7 +36,7 @@ Anyway, because English is the language of programming, the code, including vari

# Usage

* Create your language strings (messages):
- Create your language strings (messages):

```typescript
// English version — default
Expand Down Expand Up @@ -94,7 +94,7 @@ const eo: Partial<langType> = {

Note that the message names _must not contain one of the keyword_ of the [Intl API](doc/api.md#intlt-extends-messages).

* Create the corresponding language map:
- Create the corresponding language map:

```typescript
// Direct creation
Expand All @@ -112,15 +112,24 @@ const languageMap = new LanguageMap(en, 'en').merge({ fr, fr_ca }).merge({ eo })

Note that you should only use lowercases, digits and underscores as keys in language maps, because language codes will be formatted this way by the `Intl` class.

* Create the internationalization object, and use it!
- Create the internationalization object, and use it!

```typescript
const lang = new Intl<langType>(languageMap, ['eo', 'fr-CA'])
lang.welcome() // 'Bonvenon!'
lang.showElementCount(0) // 'Il n’y a pas d’éléments' — Compilation check that 0 is of type number
```

# Mutability

Object states will never change except:

- JavaScript representation of the `LanguageMap` (because of lazy initialization),
- if you choose to update the language preferences with `Intl.$changePreferences`.

A new object is created when calling `LanguageMap.merge`, and language preferences can be updated cloning the international object with `new Intl`.

# Documentation

* [API documentation](doc/api.md)
* [Code snippets](doc/tips.md)
- [API documentation](doc/api.md)
- [Code snippets](doc/tips.md)
10 changes: 9 additions & 1 deletion doc/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,17 @@ Note that language codes are formatted to lowercase and digit separated with und

Note that the message names _must not contain one of the keyword_ of the API. In order to prevent name collision, API methods and data begin with a $ character.

## constructor(intl: Intl\<T>, preferences?: ReadonlyArray\<string>, createGenerics: boolean = true)

Clone the given internationalization object with new preferences. In other words, this will create a new internationalization object with the same language map as the given one but new preferences. Calling this constructor will be faster than creating a new object based on the language map, because message methods will be copied instead of being recreated.

## $changePreferences(preferences: ReadonlyArray\<string>, createGenerics: boolean = true): this

Change the language preferences of this internationalization object.

## $withPreferences(preferences: ReadonlyArray\<string>, createGenerics: boolean = true): Intl\<T>

Create a new internationalization object with the same language map as this one but new preferences.
Deprecated. Use `new Intl(intl, preferences, createGenerics)` instead.

## $preferences: ReadonlyArray\<string>

Expand Down
25 changes: 17 additions & 8 deletions doc/fr/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

intl-ts est une bibliothèque d'internationalisation (i18n) pour TypeScript. Le paquet est compilé en ES2015 et peut donc également être utilisé par des applications JavaScript, mais peut potentiellement requérir une transformation par Babel pour être utilisé par les navigateurs. Ses principales caractéristiques sont :

* Typage sûr : l'utilisation d'un mauvais nom de message ou du mauvais type de paramètre est détecté à la compilation. Si votre EDI le permet, vous pouvez même avoir la complétion pour les noms de message.
* Immuable : excepté pour la représentation d'une `LanguageMap` en JavaScript (à cause d'une initialisation paresseuse), l'état des objets ne changera jamais. Un nouvel objet est créé lors de l'appel à `LanguageMap.merge` ou `Intl.$withPreferences`. Idéal pour la plupart des cadres basés sur les états, tel que React/Redux.
* Agnostique : peut être utilisé à la fois côté serveur et côté navigateur.
- Typage sûr : l'utilisation d'un mauvais nom de message ou du mauvais type de paramètre est détecté à la compilation. Si votre EDI le permet, vous pouvez même avoir la complétion pour les noms de message.
- Mutable ou immuable : la bibliothèque peut être utilisée de façon immutable (idéal pour la plupart des cadres basés sur les états, tel que React/Redux) ou mutable (pour une meilleure performance).
- Agnostique : peut être utilisé à la fois côté serveur et côté navigateur.

# Installation

Expand All @@ -28,7 +28,7 @@ Cependant, l'anglais étant la langue de la programmation, le code, y compris le

# Utilisation

* Créez vos messages :
- Créez vos messages :

```typescript
// Version anglaise — défault
Expand Down Expand Up @@ -86,7 +86,7 @@ const eo: Partial<langType> = {

Notez que les noms des messages _ne doivent pas contenir l'un des mots-clés_ de l'[API Intl](api.md#intlt-extends-messages).

* Créez la table des langues correspondante :
- Créez la table des langues correspondante :

```typescript
// Création directe
Expand All @@ -104,15 +104,24 @@ const languageMap = new LanguageMap(en, 'en').merge({ fr, fr_ca }).merge({ eo })

Notez que vous devriez utiliser uniquement des minuscules, chiffres et souligné comme clés dans les tables de langues, car le code de la langue est formaté ainsi par la classe `Intl`.

* Créez l'objet d'internationalisation et utilisez-le !
- Créez l'objet d'internationalisation et utilisez-le !

```typescript
const lang = new Intl<langType>(languageMap, ['eo', 'fr-CA'])
lang.welcome() // 'Bonvenon!'
lang.showElementCount(0) // 'Il n’y a pas d’éléments' — La compilation vérifie que 0 est bien un nombre
```

# Mutabilité

L'état des objets ne changera jamais, sauf :

- la représentation d'une `LanguageMap` en JavaScript (à cause d'une initialisation paresseuse) ;
- si vous choisissez de modifier les préférences linguistiques avec `Intl.$changePreferences`.

Un nouvel objet est créé lors de l'appel à `LanguageMap.merge`, et les préférences peuvent être modifiées en clonant l'objet d'internationalisation avec `new Intl`.

# Documentation

* [Documentation de l'API](api.md)
* [Exemples de code](tips.md)
- [Documentation de l'API](api.md)
- [Exemples de code](tips.md)
10 changes: 9 additions & 1 deletion doc/fr/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,17 @@ Notez que les codes de langue sont formatés en minuscules et chiffres séparés

Notez que les noms des messages _ne doivent pas contenir l'un des mots-clés_ de l'API. Afin d'éviter les collision de noms, les méthodes et données de l'API commencent par le caractère $.

## constructor(intl: Intl\<T>, preferences?: ReadonlyArray\<string>, createGenerics: boolean = true)

Cloner l'objet d'internationalisation donné avec de nouvelles préférences. Autrement dit, cela va créer un nouvel objet d'internationalisation avec la même table de langues que celui fourni, mais de nouvelles préférences. L'utilisation de se constructeur sera plus rapide que de créer un nouvel objet basé sur la table de langues, car les méthodes des messages seront copiées plutôt que d'être re-créées.

## $changePreferences(preferences: ReadonlyArray\<string>, createGenerics: boolean = true): this

Modifier les préférences linguistique de cet objet d'internationalisation.

## $withPreferences(preferences: ReadonlyArray\<string>, createGenerics: boolean = true): Intl\<T>

Créer un nouvel objet d'internationalisation avec la même table de langues que celui-ci, mais de nouvelles préférences.
Dépréciée. Utiliser plutôt `new Intl(intl, preferences, createGenerics)`.

## $preferences: ReadonlyArray\<string>

Expand Down
2 changes: 1 addition & 1 deletion doc/fr/tips.md
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ app.use((req, res) => {
const preferredLanguages = calculatePreferredLanguages(
req.headers['accept-language']
)
const reqLang = lang.$withPreferences(preferredLanguages, false)
const reqLang = new Intl(lang, preferredLanguages, false)
const htmlContent = renderToString(<Layout />)
const preloaded = `window.__PRELOADED_STATE__=${JSON.stringify({
preferredLanguages,
Expand Down
2 changes: 1 addition & 1 deletion doc/tips.md
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ app.use((req, res) => {
const preferredLanguages = calculatePreferredLanguages(
req.headers['accept-language']
)
const reqLang = lang.$withPreferences(preferredLanguages, false)
const reqLang = new Intl(lang, preferredLanguages, false)
const htmlContent = renderToString(<Layout />)
const preloaded = `window.__PRELOADED_STATE__=${JSON.stringify({
preferredLanguages,
Expand Down
Loading

0 comments on commit b49345c

Please sign in to comment.