koto-react 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Koto Contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,152 @@
1
+ # Koto React
2
+
3
+ > **Koto** (言) — Japanese for "word." Every translation starts with a single word. Koto bridges languages one word at a time.
4
+
5
+ A React translation library with IndexedDB caching for optimal performance.
6
+
7
+ ## Installation
8
+
9
+ ```bash
10
+ npm install koto-react
11
+ # or
12
+ yarn add koto-react
13
+ ```
14
+
15
+ ## Usage
16
+
17
+ ### Basic Setup with Provider
18
+
19
+ ```tsx
20
+ import React from 'react';
21
+ import { HermesProvider } from 'koto-react';
22
+
23
+ function App() {
24
+ return (
25
+ <HermesProvider
26
+ apiKey="your-api-key"
27
+ defaultLocale="en"
28
+ apiUrl="https://your-api-endpoint.com/translations" // optional
29
+ >
30
+ <YourApp />
31
+ </HermesProvider>
32
+ );
33
+ }
34
+ ```
35
+
36
+ ### Using the Translation Hook
37
+
38
+ ```tsx
39
+ import React from 'react';
40
+ import { useTranslation } from 'koto-react';
41
+
42
+ function MyComponent() {
43
+ const { t, locale, loading } = useTranslation();
44
+
45
+ if (loading) {
46
+ return <div>Loading translations...</div>;
47
+ }
48
+
49
+ return (
50
+ <div>
51
+ <h1>{t('checkout.payment.title')}</h1>
52
+ <p>{t('checkout.payment.description', 'Default fallback text')}</p>
53
+ <p>Current locale: {locale}</p>
54
+ </div>
55
+ );
56
+ }
57
+ ```
58
+
59
+ ### Using the Standalone Translation Function
60
+
61
+ For non-React contexts or utility functions:
62
+
63
+ ```typescript
64
+ import { t, initTranslations } from 'koto-react';
65
+
66
+ // Initialize once in your app
67
+ await initTranslations('en');
68
+
69
+ // Use anywhere
70
+ const title = t('checkout.payment.title');
71
+ const notFound = t('some.missing.key'); // Returns 'some.missing.key'
72
+ const withFallback = t('some.missing.key', 'Fallback text'); // Returns 'Fallback text'
73
+ ```
74
+
75
+ ### Translation with Interpolation
76
+
77
+ ```typescript
78
+ import { ti } from 'koto-react';
79
+
80
+ // If translation is: "Hello, {{name}}! You have {{count}} items."
81
+ const message = ti('greeting.message', {
82
+ name: 'John',
83
+ count: 5
84
+ });
85
+ // Returns: "Hello, John! You have 5 items."
86
+ ```
87
+
88
+ ### Pluralization
89
+
90
+ ```typescript
91
+ import { tp } from 'koto-react';
92
+
93
+ // Translations:
94
+ // "items.zero": "No items"
95
+ // "items.one": "One item"
96
+ // "items.other": "{{count}} items"
97
+
98
+ tp('items', 0); // "No items"
99
+ tp('items', 1); // "One item"
100
+ tp('items', 5); // "5 items"
101
+ ```
102
+
103
+ ## Features
104
+
105
+ - 🚀 **Automatic Caching**: Translations are cached in IndexedDB for offline access and faster loads
106
+ - 🔄 **Background Updates**: Cached translations are served immediately while fresh data is fetched in the background
107
+ - 📦 **Nested Keys**: Support for nested translation keys using dot notation
108
+ - 🎯 **TypeScript Support**: Full TypeScript support with type definitions
109
+ - 💾 **Offline Support**: Works offline using cached translations
110
+ - 🔧 **Flexible API**: Use with React hooks or standalone functions
111
+
112
+ ## API Reference
113
+
114
+ ### HermesProvider
115
+
116
+ The main provider component that manages translations.
117
+
118
+ **Props:**
119
+ - `apiKey` (string, required): Your API key for fetching translations
120
+ - `defaultLocale` (string, required): The default locale to use
121
+ - `apiUrl` (string, optional): Custom API endpoint URL
122
+ - `children` (ReactNode, required): Your app components
123
+
124
+ ### useTranslation()
125
+
126
+ Hook that returns translation utilities.
127
+
128
+ **Returns:**
129
+ - `t(key: string, fallback?: string): string` - Translation function
130
+ - `locale: string` - Current locale
131
+ - `loading: boolean` - Loading state
132
+
133
+ ### t(key: string, fallback?: string): string
134
+
135
+ Standalone translation function.
136
+
137
+ **Parameters:**
138
+ - `key`: The translation key (supports dot notation)
139
+ - `fallback`: Optional fallback value if translation not found
140
+
141
+ **Returns:** The translated string or the key if not found
142
+
143
+ ### Storage
144
+
145
+ Translations are automatically cached in IndexedDB with:
146
+ - 1-hour cache duration (configurable)
147
+ - Automatic cleanup of expired entries
148
+ - Per-locale storage
149
+
150
+ ## License
151
+
152
+ MIT
@@ -0,0 +1,16 @@
1
+ import React from 'react';
2
+ import { KotoConfig, KotoContextValue, LocaleInfo } from './types';
3
+ export interface KotoProviderProps extends KotoConfig {
4
+ children: React.ReactNode;
5
+ }
6
+ export declare function KotoProvider({ children, apiKey, projectId, defaultLocale, apiUrl }: KotoProviderProps): React.JSX.Element;
7
+ export declare function useKoto(): KotoContextValue;
8
+ export declare function useTranslation(): {
9
+ t: (key: string, fallback?: string) => string;
10
+ locale: string;
11
+ loading: boolean;
12
+ setLocale: (locale: string) => void;
13
+ availableLocales: LocaleInfo[];
14
+ getAvailableLocales: () => LocaleInfo[];
15
+ };
16
+ //# sourceMappingURL=Provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Provider.d.ts","sourceRoot":"","sources":["../src/Provider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA+E,MAAM,OAAO,CAAC;AACpG,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAmB,UAAU,EAAE,MAAM,SAAS,CAAC;AAOpF,MAAM,WAAW,iBAAkB,SAAQ,UAAU;IACnD,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B;AAID,wBAAgB,YAAY,CAAC,EAC3B,QAAQ,EACR,MAAM,EACN,SAAS,EACT,aAAa,EACb,MAA+C,EAChD,EAAE,iBAAiB,qBAqHnB;AAGD,wBAAgB,OAAO,IAAI,gBAAgB,CAM1C;AAGD,wBAAgB,cAAc;;;;;;;EAG7B"}
@@ -0,0 +1,20 @@
1
+ export declare const SUPPORTED_LOCALES: {
2
+ readonly EN: "en";
3
+ readonly ES: "es";
4
+ readonly FR: "fr";
5
+ readonly DE: "de";
6
+ readonly IT: "it";
7
+ readonly PT: "pt";
8
+ readonly RU: "ru";
9
+ readonly ZH: "zh";
10
+ readonly JA: "ja";
11
+ readonly KO: "ko";
12
+ readonly AR: "ar";
13
+ readonly HI: "hi";
14
+ };
15
+ export type SupportedLocale = typeof SUPPORTED_LOCALES[keyof typeof SUPPORTED_LOCALES];
16
+ export declare const DEFAULT_LOCALE: SupportedLocale;
17
+ export declare const LOCALE_NAMES: Record<SupportedLocale, string>;
18
+ export declare function isValidLocale(locale: string): locale is SupportedLocale;
19
+ export declare function getLocaleName(locale: SupportedLocale): string;
20
+ //# sourceMappingURL=locales.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"locales.d.ts","sourceRoot":"","sources":["../../src/constants/locales.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;CAapB,CAAC;AAEX,MAAM,MAAM,eAAe,GAAG,OAAO,iBAAiB,CAAC,MAAM,OAAO,iBAAiB,CAAC,CAAC;AAEvF,eAAO,MAAM,cAAc,EAAE,eAAsC,CAAC;AAEpE,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,eAAe,EAAE,MAAM,CAaxD,CAAC;AAEF,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,IAAI,eAAe,CAEvE;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,eAAe,GAAG,MAAM,CAE7D"}
package/dist/hoc.d.ts ADDED
@@ -0,0 +1,33 @@
1
+ import React, { ComponentType } from 'react';
2
+ import { KotoContextValue } from './types';
3
+ /**
4
+ * Higher-Order Component for class components
5
+ * Wraps a component and injects translation props
6
+ */
7
+ export declare function withTranslation<P extends object>(Component: ComponentType<P & WithTranslationProps>): ComponentType<Omit<P, keyof WithTranslationProps>>;
8
+ /**
9
+ * Props injected by withTranslation HOC
10
+ */
11
+ export interface WithTranslationProps {
12
+ t: KotoContextValue['t'];
13
+ locale: KotoContextValue['locale'];
14
+ loading: KotoContextValue['loading'];
15
+ setLocale: KotoContextValue['setLocale'];
16
+ translations?: KotoContextValue['translations'];
17
+ error?: KotoContextValue['error'];
18
+ }
19
+ /**
20
+ * Render prop component for more flexible usage
21
+ */
22
+ export interface TranslationProps {
23
+ children: (props: KotoContextValue) => React.ReactNode;
24
+ }
25
+ export declare function Translation({ children }: TranslationProps): React.JSX.Element;
26
+ /**
27
+ * Consumer component for direct context access
28
+ * Useful for class components that need conditional rendering
29
+ */
30
+ export declare class KotoConsumer extends React.Component<TranslationProps> {
31
+ render(): React.JSX.Element;
32
+ }
33
+ //# sourceMappingURL=hoc.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hoc.d.ts","sourceRoot":"","sources":["../src/hoc.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAE7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAE3C;;;GAGG;AACH,wBAAgB,eAAe,CAAC,CAAC,SAAS,MAAM,EAC9C,SAAS,EAAE,aAAa,CAAC,CAAC,GAAG,oBAAoB,CAAC,GACjD,aAAa,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,oBAAoB,CAAC,CAAC,CAoBpD;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,CAAC,EAAE,gBAAgB,CAAC,GAAG,CAAC,CAAC;IACzB,MAAM,EAAE,gBAAgB,CAAC,QAAQ,CAAC,CAAC;IACnC,OAAO,EAAE,gBAAgB,CAAC,SAAS,CAAC,CAAC;IACrC,SAAS,EAAE,gBAAgB,CAAC,WAAW,CAAC,CAAC;IACzC,YAAY,CAAC,EAAE,gBAAgB,CAAC,cAAc,CAAC,CAAC;IAChD,KAAK,CAAC,EAAE,gBAAgB,CAAC,OAAO,CAAC,CAAC;CACnC;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,CAAC,KAAK,EAAE,gBAAgB,KAAK,KAAK,CAAC,SAAS,CAAC;CACxD;AAED,wBAAgB,WAAW,CAAC,EAAE,QAAQ,EAAE,EAAE,gBAAgB,qBAGzD;AAED;;;GAGG;AACH,qBAAa,YAAa,SAAQ,KAAK,CAAC,SAAS,CAAC,gBAAgB,CAAC;IACjE,MAAM;CAGP"}
@@ -0,0 +1,14 @@
1
+ export { KotoProvider, useKoto, useTranslation } from './Provider';
2
+ export type { KotoProviderProps } from './Provider';
3
+ export { withTranslation, Translation, KotoConsumer } from './hoc';
4
+ export type { WithTranslationProps, TranslationProps } from './hoc';
5
+ export { t, ti, tp, initTranslations, setTranslations, getLocale } from './t';
6
+ export { storage } from './storage';
7
+ export type { TranslationData, KotoConfig, KotoContextValue, StoredTranslations, LocaleInfo, } from './types';
8
+ export { AVAILABLE_LOCALES, getLocaleInfo, isLocaleSupported, getFallbackLocale, resolveLocale } from './locales';
9
+ export { getNestedTranslation, flattenTranslations, unflattenTranslations } from './utils';
10
+ export { KotoProvider as HermesProvider, useKoto as useHermes } from './Provider';
11
+ export { KotoConsumer as HermesConsumer } from './hoc';
12
+ import { t } from './t';
13
+ export default t;
14
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AACnE,YAAY,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAGpD,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AACnE,YAAY,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,OAAO,CAAC;AAGpE,OAAO,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,gBAAgB,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,KAAK,CAAC;AAG9E,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,YAAY,EACV,eAAe,EACf,UAAU,EACV,gBAAgB,EAChB,kBAAkB,EAClB,UAAU,GACX,MAAM,SAAS,CAAC;AAGjB,OAAO,EACL,iBAAiB,EACjB,aAAa,EACb,iBAAiB,EACjB,iBAAiB,EACjB,aAAa,EACd,MAAM,WAAW,CAAC;AAGnB,OAAO,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAG3F,OAAO,EAAE,YAAY,IAAI,cAAc,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,YAAY,CAAC;AAClF,OAAO,EAAE,YAAY,IAAI,cAAc,EAAE,MAAM,OAAO,CAAC;AAGvD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,eAAe,CAAC,CAAC"}