npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

tiny-trans

v2.0.1

Published

simple localisation manager

Downloads

7

Readme

tiny-trans - lib for localisation

Simple translate manager with supporting of dynamic imports, variables and plural. You can use a lib for react applications react-tiny-trans

Install

npm i tiny-trans
// or
yarn add tiny-trans 

Usage

You can use different files for translates. Below I use follow example files

lang_ru.json

{
  "screens": {
    "Home": {
      "title": "Заголовок",
      "description": "Описание ${desc} ${name}",
      "plural": {
        "zero": "${COUNT} бананов",
        "one": "${COUNT} банан",
        "two": "${COUNT} банана",
        "few": "${COUNT} банана",
        "many": "${COUNT} бананов",
        "other": "${COUNT} бананов"
      }
    }
  }
  "extrapoint": {
    "anything": "Что-нибудь"
  }
}

lang_en.json

{
  "screens": {
    "Home": {
      "title": "Title",
      "description": "Description ${desc} ${name}",
      "plural": {
        "zero": "${COUNT} bananas",
        "one": "${COUNT} banane",
        "two": "${COUNT} bananas",
        "few": "${COUNT} bananas",
        "many": "${COUNT} bananas",
        "other": "${COUNT} bananas"
      }
    }
  }
  "extrapoint": {
    "anything": "Anything"
  }
}

Creating

You should pass the translations and the starting locale to the init method. You can also explicitly specify possible locales by passing Locale type when creating a Trans instance

import ru from './lang_ru.json';
import en from './lang_en.json';

enum Locale {
  ru = 'ru',
  en = 'en',
}

const trans = new Trans<Locale>({
  translations: { ru, en },
  locale: Locale.en,
});
await trans.init();

Creating with dynamic imports

Files of translates will dynamic download. See webpack code-splitting

enum Locale {
  ru = 'ru',
  en = 'en',
}

const trans = new Trans<Locale>({
  translations: { 
    ru: () => new Promise((resolve) => import('./lang_ru.json').then((res) => resolve(res.default))), 
    en: () => new Promise((resolve) => import('./lang_en.json').then((res) => resolve(res.default))), 
  },
  locale: Locale.en,
});
await trans.init();

or you can use fetch for dynamic download

enum Locale {
  ru = 'ru',
  en = 'en',
}

const trans = new Trans<Locale>({
  translations: { 
    ru: async () => await fetch('url_of_my_translate_ru.json'), 
    en: async () => await fetch('url_of_my_translate_en.json'), 
  },
  locale: Locale.en,
});
await trans.init();

Creating with custom pluralization

You can pass the custom plural functions.

Note: under hood it uses Intl.PluralRules(locale).select(count) , but it does not support in IE. You can pass in the init method own plural functions object.

import ru from './lang_ru.json';
import en from './lang_en.json';

enum Locale {
  ru = 'ru',
  en = 'en',
}

const trans = new Trans<Locale>({
  translations: { ru, en },
  locale: Locale.en,
  pluralRecord: { ru: (count: number, locale: string) => "zero" | "one" | "two" | "few" | "many" | "other", en: (count: number, locale: string) => "zero" | "one" | "two" | "few" | "many" | "other" }
});
await trans.init();

Translate

You can write in different ways:

// case 1
const translate = trans.createTranslate`screens`;
translate`Home.title`; // en -> Title; ru -> Заголовок  

// case 2
const translate = trans.createTranslate`screens.Home`;
translate`title`; // en -> Title; ru -> Заголовок  

// case 3
const translate = trans.createTranslate`screens.Home.title`;
translate``; // en -> Title; ru -> Заголовок  

// case 4
const translate = trans.createTranslate``;
translate`screens.Home.title`; // en -> Title; ru -> Заголовок  

Note: createTranslate and translate take a TemplateStringsArray or a string as first param.

createTranslate`some` // it works
createTranslate('some') // it works too
createTranslate'some' // it does not work!

translate`some` // it works
translate('some') // it works too
translate'some' // it does not work!

Translate with variables

const translate = trans.createTranslate`screens.Home`;
translate('description', { variables: { desc: "Any", name: "Name" } }); // en -> Description Any Name; ru -> Описание Any Name  

Translate with plural

const translate = trans.createTranslate`screens.Home`;
translate('plural', { count: 3 }); // en -> 3 bananas; ru -> 3 банана 

Note: COUNT is reserved name. Don't name your variables so.

translate('description', { variables: { COUNT: "you data" } }) // bad

Translate with few points

In any translation function, you can write the full path, and this works even if a different root path is passed to createTranslate

const translate = trans.createTranslate`screens`;
translate`Home.title` // en -> Title; ru -> Заголовок  
translate`extrapoint.anything` // en -> Anything; ru -> Что-нибудь  

Error handing

Sometimes we mistake in translate files, and we need see it

const translate = trans.createTranslate`screens.Home`;
translate`plural`
// throw "invalid translate! result: "[object Object]"; result as a json: {"zero":"zero bananas","one":"one banane","two":"two bananas","few":"${COUNT} bananas","many":"${COUNT} bananas","other":"${COUNT} bananas"}; rootResult: "undefined"; rootResult as a json: undefined. full path: "screens.Home.plural"; translate path: "plural";"

Also you can ignore error:

const translate = trans.createTranslate`screens.Home`;
translate(`plural`, { errorsMode: 'ignore' }) // returns ''

Or you can handle error:

const translate = trans.createTranslate`screens.Home`;
translate(`plural`, { errorsMode: (error: TransError) => 'handle error' }) // returns 'handle error'

API

Methods

constructor

type PluralFn = (count: number, locale: string) => "zero" | "one" | "two" | "few" | "many" | "other";

constructor(params: {
  /**
  * for example: { ru: { test: 'тест' }, en: { test: 'test' } } 
  */
  translations: Record<Locale, unknown>;
  /**
  * string
  */
  locale: Locale;
  /**
  * If you want you can pass custom plural hanlders
  */
  pluralRecord?: Record<Locale, PluralFn>;
})

init

Download dynamic files

init(): Promise<void> 

changeLocale

changeLocale(locale: Locale): Promise<void>

createTranslate

createTranslate<T extends Variables = Variables>(module: string | TemplateStringsArray): Translate<T>

translate

type Variables = Record<string, string>;
type ErrorsMode = 'ignore' | 'throw' | 'console' | ((error: TransError) => string);

type TranslateOptions<T extends Variables = Variables> = {
  /**
   * ignore the error, handle error, show in the console or throw error (throw by default)
   * */
  errorsMode?: ErrorsMode;
  /**
   * it uses for the plural if it exists
   * */
  count?: number;
  /**
   * for replaced the variable patters - ${variable}
   * */
  variables?: T;
};

type Translate<T extends Variables = Variables> = (
  path: string | TemplateStringsArray,
  options?: TranslateOptions<T>
) => string;

Events

You can listen trans events. They will be helpful for creating a lib for any frameworks

  • loadstart Triggered before only dynamic importing
  • loadend Triggered after only dynamic importing
  • change-locale Triggered every time by changeLocale method but after loadend. It takes a locale as a first argument
  • init Triggered single time in the end by init method. It takes a locale as a first argument
// To add
trans.addEventListener('loadstart', () => void);
trans.addEventListener('loadend', () => void);
trans.addEventListener('change-locale', (locale: string) => void);
trans.addEventListener('init', (locale: string) => void);

// To remove
trans.removeEventListener('loadstart', () => void);
trans.removeEventListener('loadend', () => void);
trans.removeEventListener('change-locale', (locale: string) => void);
trans.removeEventListener('init', (locale: string) => void);