Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@nanostores/i18n

Package Overview
Dependencies
Maintainers
3
Versions
17
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@nanostores/i18n - npm Package Compare versions

Comparing version 0.2.1 to 0.3.0

68

count/index.d.ts

@@ -1,2 +0,6 @@

import { TranslationJSON, TranslationFunction } from '../create-i18n/index.js'
import {
TranslationJSON,
TranslationFunction,
TranslationFunctionAlternatives
} from '../create-i18n/index.js'

@@ -9,30 +13,34 @@ export type CountInput = {

/**
* Add pluralization variants to translation.
*
* ```ts
* import { count } from '@nanostores/i18n'
* import { i18n } from '../stores/i18n'
*
* export const messages = i18n('pagination', {
* pages: count({
* one: 'One page',
* many: '{count} pages'
* })
* })
* ```
*
* ```js
* t.count(5)
* ```
*
* @param input Pluralization variants.
* @return Transform for translation.
*/
export function count<Input extends CountInput>(
input: Input
): TranslationFunction<
[number],
// @ts-ignore
Input[keyof Input]
>
interface Count {
/**
* Add pluralization variants to translation.
*
* ```ts
* import { count } from '@nanostores/i18n'
* import { i18n } from '../stores/i18n'
*
* export const messages = i18n('pagination', {
* pages: count({
* one: 'One page',
* many: '{count} pages'
* })
* })
* ```
*
* ```js
* t.count(5)
* ```
*
* @param input Pluralization variants.
* @return Transform for translation.
*/
<Parameters extends Record<string, string | number>>(
input: TranslationFunction<[Parameters], string>
): TranslationFunctionAlternatives<Parameters>
<Input extends CountInput>(input: Input): TranslationFunction<
[number],
Input[keyof Input]
>
}
export const count: Count

@@ -18,3 +18,3 @@ import { ReadableAtom } from 'nanostores'

Arguments extends any[] = any[],
Output extends TranslationJSON = TranslationJSON
Output = TranslationJSON | Translation
> {

@@ -24,2 +24,9 @@ (...args: Arguments): Output

export type TranslationFunctionAlternatives<
Parameters extends Record<string, unknown>
> = {
(input: number): TranslationFunction<[Parameters], string>
(input: Parameters): TranslationFunction<[number], string>
}
export type Translation = string | TranslationFunction

@@ -48,4 +55,9 @@

export interface TranslationLoader<Locale extends string = string> {
(code: Locale): Promise<ComponentsJSON>
export interface TranslationLoader<
Locale extends string = string,
ComponentsNames extends string[] = string[]
> {
(code: Locale, components: ComponentsNames):
| Promise<ComponentsJSON[]>
| Promise<ComponentsJSON>
}

@@ -52,0 +64,0 @@

@@ -7,2 +7,4 @@ import { atom, onMount } from 'nanostores'

let loading = atom(true)
let mounted = new Set()
let fetched = new Set()

@@ -36,3 +38,2 @@ let define = (componentName, base) => {

let waiting = false
function setTranslation(code) {

@@ -49,3 +50,2 @@ let translations = {

t.set(translations)
waiting = false
}

@@ -55,27 +55,33 @@ setTranslation(baseLocale)

onMount(t, () => {
let unbindLocale = locale.subscribe(code => {
if (define.cache[code]) {
setTranslation(code)
waiting = false
} else {
waiting = true
mounted.add(t.component)
let code = locale.get()
let isCached =
code === baseLocale ||
(define.cache[code] && define.cache[code][t.component])
if (isCached) {
setTranslation(code)
} else {
let prefix = t.component.split('/')[0]
if (!fetched.has(prefix)) {
fetched.add(prefix)
getTranslation(code, [t.component]).then(() => {
fetched.delete(prefix)
})
}
})
let unbindLoading = loading.subscribe(isLoading => {
if (waiting && !isLoading) {
setTranslation(locale.get())
waiting = false
}
})
}
for (let i in processors) {
processors[i].from.listen(() => {
setTranslation(locale.get())
setTranslation(code)
})
}
let unbindLoading = loading.listen(isLoading => {
if (!isLoading) {
setTranslation(locale.get())
}
})
return () => {
unbindLocale()
mounted.delete(t.component)
unbindLoading()
}
})
return t

@@ -89,15 +95,27 @@ }

locale.subscribe(code => {
if (define.cache[code]) {
async function getTranslation(code, components) {
loading.set(true)
let translations = await opts.get(code, components)
if (Array.isArray(translations)) {
translations = translations.reduce((obj, item) =>
Object.assign(obj, item)
)
}
define.cache[code] = { ...define.cache[code], ...translations }
if (code === locale.get()) loading.set(false)
}
locale.listen(code => {
let nonCached = Array.from(mounted).filter(
component => !(define.cache[code] && define.cache[code][component])
)
if (nonCached.length) {
getTranslation(code, nonCached)
} else {
loading.set(false)
} else {
loading.set(true)
opts.get(code).then(translation => {
define.cache[code] = translation
if (code === locale.get()) loading.set(false)
})
}
})
loading.set(false)
return define
}
{
"name": "@nanostores/i18n",
"version": "0.2.1",
"description": "A tiny (≈500 bytes) i18n library for React/Preact/Vue/Svelte",
"version": "0.3.0",
"description": "A tiny (≈600 bytes) i18n library for React/Preact/Vue/Svelte",
"keywords": [

@@ -6,0 +6,0 @@ "nano",

@@ -1,3 +0,5 @@

import { TranslationFunction } from '../create-i18n/index.js'
import { CountInput } from '../count/index.js'
import {
TranslationFunctionAlternatives,
TranslationFunction
} from '../create-i18n/index.js'

@@ -18,2 +20,3 @@ interface Params {

* ```js
* const t = useStore(messages);
* t.page({ page: 1, all: 10 })

@@ -29,4 +32,4 @@ * ```

<Parameters extends Record<string, string | number>>(
input: CountInput
): TranslationFunction<[Parameters], CountInput>
input: TranslationFunction<[number], string>
): TranslationFunctionAlternatives<Parameters>
<Parameters extends Record<string, string | number>>(

@@ -33,0 +36,0 @@ input: any

@@ -7,7 +7,5 @@ import { ReadableAtom } from 'nanostores'

from: ReadableAtom<Key>
(input: Record<Key, TranslationJSON>): TranslationFunction<
[],
// @ts-ignore
Input[keyof Input]
>
<Input extends Record<Key, TranslationJSON>>(
input: Input
): TranslationFunction<[], Input[keyof Input]>
}

@@ -14,0 +12,0 @@

@@ -9,3 +9,3 @@ # Nano Stores I18n

* **Small.** Between 448 and 844 bytes (minified and gzipped).
* **Small.** Between 673 and 1106 bytes (minified and gzipped).
Zero dependencies.

@@ -12,0 +12,0 @@ * Works with **React**, **Preact**, **Vue**, **Svelte**, and plain JS.

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc