@pantho075/locale 0.1.0 → 0.1.1

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/README.md CHANGED
@@ -55,12 +55,10 @@ console.log(title, home.header, home.footer);
55
55
 
56
56
  ### Adding your own keys
57
57
 
58
- Edit `src/locales/en.ts` (and `bn.ts`, `ne.ts`) in this package, or fork it. Each file is just a `const data = { ... }` wrapped in `withNullTopLevel`:
58
+ Edit `src/locales/en.ts` (and `bn.ts`, `ne.ts`) in this package, or fork it. Each file is just a plain object exported as default:
59
59
 
60
60
  ```ts
61
61
  // src/locales/en.ts
62
- import { withNullTopLevel } from "../normalize";
63
-
64
62
  const data = {
65
63
  title: "Welcome",
66
64
  home: {
@@ -70,44 +68,14 @@ const data = {
70
68
  greeting: "Hi there",
71
69
  };
72
70
 
73
- export default withNullTopLevel(data);
71
+ export default data;
74
72
  ```
75
73
 
76
74
  ### Adding a new locale
77
75
 
78
- 1. Create `src/locales/<code>.ts` that exports `withNullTopLevel(...)`.
76
+ 1. Create `src/locales/<code>.ts` that exports the locale object as default.
79
77
  2. Import it in `src/getTranslation.ts` and add it to the `locales` map.
80
78
 
81
- ## Missing-value semantics
82
-
83
- This is important — read it.
84
-
85
- | Situation | Returned value |
86
- | ---------------------------------------- | ------------------------------------------- |
87
- | Top-level key is **absent** from source | `null` (Proxy returns null on miss) |
88
- | Nested key is **absent** from source | `undefined` (standard JS) |
89
- | Key is present with value `null` | `null` |
90
- | Key is present with a string/object/etc. | that value |
91
-
92
- So:
93
-
94
- - `useTranslation('en').totallyMissing` → `null`
95
- - `useTranslation('en').home.missing` → `undefined`
96
- - `useTranslation('en').home.footer` (where `home.footer` isn't in source) → `undefined`
97
-
98
- If you need `null` for a missing nested key, write it explicitly in the source:
99
-
100
- ```ts
101
- const data = {
102
- home: {
103
- header: "Hello",
104
- footer: null, // explicit null, not "missing"
105
- },
106
- };
107
- ```
108
-
109
- The Proxy only wraps the **top level**. Nested objects are returned by reference, so they keep standard JS behavior — missing nested keys read as `undefined` and you can iterate them with `Object.keys()` etc.
110
-
111
79
  ## API
112
80
 
113
81
  ### `getTranslation<T>(lang: string): T`
@@ -132,7 +100,7 @@ React hook wrapping `getTranslation`. Memoized on `lang` — same language retur
132
100
  ```ts
133
101
  import { useTranslation } from "@pantho075/locale";
134
102
 
135
- const { title } = useTranslation("en"); // string | null
103
+ const { title } = useTranslation("en"); // string | undefined
136
104
  const en = useTranslation<English>("en"); // typed
137
105
  ```
138
106
 
@@ -144,7 +112,7 @@ The default return type — `Record<string, unknown>`. Most consumers will const
144
112
 
145
113
  Because the package ships its own locale data, it doesn't need to scan the consumer's filesystem, doesn't need a bundler alias, and doesn't need `resolveJsonModule`. The data is just regular TypeScript that gets tree-shaken and bundled like any other code.
146
114
 
147
- If you want to override locales from your own app, you can fork the package or import the `normalize` helper directly and build your own locale map.
115
+ If you want to override locales from your own app, you can fork the package and build your own locale map.
148
116
 
149
117
  ## License
150
118
 
package/dist/index.cjs CHANGED
@@ -2,18 +2,6 @@
2
2
 
3
3
  var react = require('react');
4
4
 
5
- // src/normalize.ts
6
- function withNullTopLevel(data4) {
7
- return new Proxy(data4, {
8
- get(target, prop, receiver) {
9
- if (typeof prop === "string" && !(prop in target)) {
10
- return null;
11
- }
12
- return Reflect.get(target, prop, receiver);
13
- }
14
- });
15
- }
16
-
17
5
  // src/locales/bn.ts
18
6
  var data = {
19
7
  title: "\u09B6\u09BF\u09B0\u09CB\u09A8\u09BE\u09AE",
@@ -22,7 +10,7 @@ var data = {
22
10
  footer: "\u09AB\u09C1\u099F\u09BE\u09B0"
23
11
  }
24
12
  };
25
- var bn_default = withNullTopLevel(data);
13
+ var bn_default = data;
26
14
 
27
15
  // src/locales/en.ts
28
16
  var data2 = {
@@ -32,7 +20,7 @@ var data2 = {
32
20
  footer: "this is footer"
33
21
  }
34
22
  };
35
- var en_default = withNullTopLevel(data2);
23
+ var en_default = data2;
36
24
 
37
25
  // src/locales/ne.ts
38
26
  var data3 = {
@@ -42,7 +30,7 @@ var data3 = {
42
30
  footer: "this is footer"
43
31
  }
44
32
  };
45
- var ne_default = withNullTopLevel(data3);
33
+ var ne_default = data3;
46
34
 
47
35
  // src/getTranslation.ts
48
36
  var EMPTY = Object.freeze({});
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/normalize.ts","../src/locales/bn.ts","../src/locales/en.ts","../src/locales/ne.ts","../src/getTranslation.ts","../src/useTranslation.ts"],"names":["data","useMemo"],"mappings":";;;;;AAUO,SAAS,iBAA4CA,KAAAA,EAAY;AACtE,EAAA,OAAO,IAAI,MAAMA,KAAAA,EAAM;AAAA,IACrB,GAAA,CAAI,MAAA,EAAQ,IAAA,EAAM,QAAA,EAAU;AAC1B,MAAA,IAAI,OAAO,IAAA,KAAS,QAAA,IAAY,EAAE,QAAQ,MAAA,CAAA,EAAS;AACjD,QAAA,OAAO,IAAA;AAAA,MACT;AACA,MAAA,OAAO,OAAA,CAAQ,GAAA,CAAI,MAAA,EAAQ,IAAA,EAAM,QAAQ,CAAA;AAAA,IAC3C;AAAA,GACD,CAAA;AACH;;;ACjBA,IAAM,IAAA,GAAO;AAAA,EACX,KAAA,EAAO,4CAAA;AAAA,EACP,IAAA,EAAM;AAAA,IACJ,MAAA,EAAQ,gCAAA;AAAA,IACR,MAAA,EAAQ;AAAA;AAEZ,CAAA;AAEA,IAAO,UAAA,GAAQ,iBAAiB,IAAI,CAAA;;;ACRpC,IAAMA,KAAAA,GAAO;AAAA,EACX,KAAA,EAAO,WAAA;AAAA,EACP,IAAA,EAAM;AAAA,IACJ,MAAA,EAAQ,gBAAA;AAAA,IACR,MAAA,EAAQ;AAAA;AAEZ,CAAA;AAEA,IAAO,UAAA,GAAQ,iBAAiBA,KAAI,CAAA;;;ACRpC,IAAMA,KAAAA,GAAO;AAAA,EACX,KAAA,EAAO,WAAA;AAAA,EACP,IAAA,EAAM;AAAA,IACJ,MAAA,EAAQ,gBAAA;AAAA,IACR,MAAA,EAAQ;AAAA;AAEZ,CAAA;AAEA,IAAO,UAAA,GAAQ,iBAAiBA,KAAI,CAAA;;;ACJpC,IAAM,KAAA,GAAyB,MAAA,CAAO,MAAA,CAAO,EAAE,CAAA;AAQ/C,IAAM,OAAA,GAA2C;AAAA,EAC/C,EAAA,EAAA,UAAA;AAAA,EACA,EAAA,EAAA,UAAA;AAAA,EACA,EAAA,EAAA;AACF,CAAA;AASO,SAAS,eACd,IAAA,EACG;AACH,EAAA,OAAQ,OAAA,CAAQ,IAAI,CAAA,IAAK,KAAA;AAC3B;ACpBO,SAAS,eACd,IAAA,EACG;AACH,EAAA,OAAOC,cAAQ,MAAM,cAAA,CAAkB,IAAI,CAAA,EAAG,CAAC,IAAI,CAAC,CAAA;AACtD","file":"index.cjs","sourcesContent":["import type { TranslationData } from \"./types\";\n\n/**\n * Wrap a translation bundle in a Proxy that returns `null` for any\n * missing top-level key, while leaving nested objects untouched so\n * missing nested keys still resolve to `undefined` (standard JS\n * semantics).\n *\n * Explicit `null` values in the source are preserved.\n */\nexport function withNullTopLevel<T extends TranslationData>(data: T): T {\n return new Proxy(data, {\n get(target, prop, receiver) {\n if (typeof prop === \"string\" && !(prop in target)) {\n return null;\n }\n return Reflect.get(target, prop, receiver);\n },\n }) as T;\n}\n","import { withNullTopLevel } from \"../normalize\";\n\nconst data = {\n title: \"শিরোনাম\",\n home: {\n header: \"হেডার\",\n footer: \"ফুটার\",\n },\n};\n\nexport default withNullTopLevel(data);\n","import { withNullTopLevel } from \"../normalize\";\n\nconst data = {\n title: \"the title\",\n home: {\n header: \"this is header\",\n footer: \"this is footer\",\n },\n};\n\nexport default withNullTopLevel(data);\n","import { withNullTopLevel } from \"../normalize\";\n\nconst data = {\n title: \"the title\",\n home: {\n header: \"this is header\",\n footer: \"this is footer\",\n },\n};\n\nexport default withNullTopLevel(data);\n","import bn from \"./locales/bn\";\nimport en from \"./locales/en\";\nimport ne from \"./locales/ne\";\nimport type { TranslationData } from \"./types\";\n\n/** Shared empty fallback for unknown languages. Frozen so it can't be mutated. */\nconst EMPTY: TranslationData = Object.freeze({});\n\n/**\n * Locale registry. Adding a new language means:\n * 1. drop a `src/locales/<code>.ts` that exports `normalizeTopLevel(data)`\n * 2. import it here\n * 3. add it to this map\n */\nconst locales: Record<string, TranslationData> = {\n en,\n bn,\n ne,\n};\n\n/**\n * Returns the translation bundle for the given language code.\n * Unknown / undefined / empty values fall back to a stable empty object.\n *\n * Framework-agnostic: works in React, Next.js server components, Vue,\n * Svelte, or vanilla Node scripts.\n */\nexport function getTranslation<T extends object = TranslationData>(\n lang: string,\n): T {\n return (locales[lang] ?? EMPTY) as T;\n}\n","import { useMemo } from \"react\";\nimport { getTranslation } from \"./getTranslation\";\nimport type { TranslationData } from \"./types\";\n\n/**\n * React hook: returns the translation bundle for the given language.\n *\n * Memoized on `lang`, so the same language produces a stable object\n * reference across re-renders. Switching language swaps the reference\n * (and any consumers destructuring top-level keys will re-render).\n */\nexport function useTranslation<T extends object = TranslationData>(\n lang: string,\n): T {\n return useMemo(() => getTranslation<T>(lang), [lang]);\n}\n"]}
1
+ {"version":3,"sources":["../src/locales/bn.ts","../src/locales/en.ts","../src/locales/ne.ts","../src/getTranslation.ts","../src/useTranslation.ts"],"names":["data","useMemo"],"mappings":";;;;;AAAA,IAAM,IAAA,GAAO;AAAA,EACX,KAAA,EAAO,4CAAA;AAAA,EACP,IAAA,EAAM;AAAA,IACJ,MAAA,EAAQ,gCAAA;AAAA,IACR,MAAA,EAAQ;AAAA;AAEZ,CAAA;AAEA,IAAO,UAAA,GAAQ,IAAA;;;ACRf,IAAMA,KAAAA,GAAO;AAAA,EACX,KAAA,EAAO,WAAA;AAAA,EACP,IAAA,EAAM;AAAA,IACJ,MAAA,EAAQ,gBAAA;AAAA,IACR,MAAA,EAAQ;AAAA;AAEZ,CAAA;AAEA,IAAO,UAAA,GAAQA,KAAAA;;;ACRf,IAAMA,KAAAA,GAAO;AAAA,EACX,KAAA,EAAO,WAAA;AAAA,EACP,IAAA,EAAM;AAAA,IACJ,MAAA,EAAQ,gBAAA;AAAA,IACR,MAAA,EAAQ;AAAA;AAEZ,CAAA;AAEA,IAAO,UAAA,GAAQA,KAAAA;;;ACFf,IAAM,KAAA,GAAyB,MAAA,CAAO,MAAA,CAAO,EAAE,CAAA;AAQ/C,IAAM,OAAA,GAA2C;AAAA,EAC/C,EAAA,EAAA,UAAA;AAAA,EACA,EAAA,EAAA,UAAA;AAAA,EACA,EAAA,EAAA;AACF,CAAA;AASO,SAAS,eACd,IAAA,EACG;AACH,EAAA,OAAQ,OAAA,CAAQ,IAAI,CAAA,IAAK,KAAA;AAC3B;ACpBO,SAAS,eACd,IAAA,EACG;AACH,EAAA,OAAOC,cAAQ,MAAM,cAAA,CAAkB,IAAI,CAAA,EAAG,CAAC,IAAI,CAAC,CAAA;AACtD","file":"index.cjs","sourcesContent":["const data = {\n title: \"শিরোনাম\",\n home: {\n header: \"হেডার\",\n footer: \"ফুটার\",\n },\n};\n\nexport default data;\n","const data = {\n title: \"the title\",\n home: {\n header: \"this is header\",\n footer: \"this is footer\",\n },\n};\n\nexport default data;\n","const data = {\n title: \"the title\",\n home: {\n header: \"this is header\",\n footer: \"this is footer\",\n },\n};\n\nexport default data;\n","import bn from \"./locales/bn\";\nimport en from \"./locales/en\";\nimport ne from \"./locales/ne\";\nimport type { TranslationData } from \"./types\";\n\n/** Shared empty fallback for unknown languages. Frozen so it can't be mutated. */\nconst EMPTY: TranslationData = Object.freeze({});\n\n/**\n * Locale registry. Adding a new language means:\n * 1. drop a `src/locales/<code>.ts` that exports the locale object as default\n * 2. import it here\n * 3. add it to this map\n */\nconst locales: Record<string, TranslationData> = {\n en,\n bn,\n ne,\n};\n\n/**\n * Returns the translation bundle for the given language code.\n * Unknown / undefined / empty values fall back to a stable empty object.\n *\n * Framework-agnostic: works in React, Next.js server components, Vue,\n * Svelte, or vanilla Node scripts.\n */\nexport function getTranslation<T extends object = TranslationData>(\n lang: string,\n): T {\n return (locales[lang] ?? EMPTY) as T;\n}\n","import { useMemo } from \"react\";\nimport { getTranslation } from \"./getTranslation\";\nimport type { TranslationData } from \"./types\";\n\n/**\n * React hook: returns the translation bundle for the given language.\n *\n * Memoized on `lang`, so the same language produces a stable object\n * reference across re-renders. Switching language swaps the reference\n * (and any consumers destructuring top-level keys will re-render).\n */\nexport function useTranslation<T extends object = TranslationData>(\n lang: string,\n): T {\n return useMemo(() => getTranslation<T>(lang), [lang]);\n}\n"]}
package/dist/index.js CHANGED
@@ -1,17 +1,5 @@
1
1
  import { useMemo } from 'react';
2
2
 
3
- // src/normalize.ts
4
- function withNullTopLevel(data4) {
5
- return new Proxy(data4, {
6
- get(target, prop, receiver) {
7
- if (typeof prop === "string" && !(prop in target)) {
8
- return null;
9
- }
10
- return Reflect.get(target, prop, receiver);
11
- }
12
- });
13
- }
14
-
15
3
  // src/locales/bn.ts
16
4
  var data = {
17
5
  title: "\u09B6\u09BF\u09B0\u09CB\u09A8\u09BE\u09AE",
@@ -20,7 +8,7 @@ var data = {
20
8
  footer: "\u09AB\u09C1\u099F\u09BE\u09B0"
21
9
  }
22
10
  };
23
- var bn_default = withNullTopLevel(data);
11
+ var bn_default = data;
24
12
 
25
13
  // src/locales/en.ts
26
14
  var data2 = {
@@ -30,7 +18,7 @@ var data2 = {
30
18
  footer: "this is footer"
31
19
  }
32
20
  };
33
- var en_default = withNullTopLevel(data2);
21
+ var en_default = data2;
34
22
 
35
23
  // src/locales/ne.ts
36
24
  var data3 = {
@@ -40,7 +28,7 @@ var data3 = {
40
28
  footer: "this is footer"
41
29
  }
42
30
  };
43
- var ne_default = withNullTopLevel(data3);
31
+ var ne_default = data3;
44
32
 
45
33
  // src/getTranslation.ts
46
34
  var EMPTY = Object.freeze({});
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/normalize.ts","../src/locales/bn.ts","../src/locales/en.ts","../src/locales/ne.ts","../src/getTranslation.ts","../src/useTranslation.ts"],"names":["data"],"mappings":";;;AAUO,SAAS,iBAA4CA,KAAAA,EAAY;AACtE,EAAA,OAAO,IAAI,MAAMA,KAAAA,EAAM;AAAA,IACrB,GAAA,CAAI,MAAA,EAAQ,IAAA,EAAM,QAAA,EAAU;AAC1B,MAAA,IAAI,OAAO,IAAA,KAAS,QAAA,IAAY,EAAE,QAAQ,MAAA,CAAA,EAAS;AACjD,QAAA,OAAO,IAAA;AAAA,MACT;AACA,MAAA,OAAO,OAAA,CAAQ,GAAA,CAAI,MAAA,EAAQ,IAAA,EAAM,QAAQ,CAAA;AAAA,IAC3C;AAAA,GACD,CAAA;AACH;;;ACjBA,IAAM,IAAA,GAAO;AAAA,EACX,KAAA,EAAO,4CAAA;AAAA,EACP,IAAA,EAAM;AAAA,IACJ,MAAA,EAAQ,gCAAA;AAAA,IACR,MAAA,EAAQ;AAAA;AAEZ,CAAA;AAEA,IAAO,UAAA,GAAQ,iBAAiB,IAAI,CAAA;;;ACRpC,IAAMA,KAAAA,GAAO;AAAA,EACX,KAAA,EAAO,WAAA;AAAA,EACP,IAAA,EAAM;AAAA,IACJ,MAAA,EAAQ,gBAAA;AAAA,IACR,MAAA,EAAQ;AAAA;AAEZ,CAAA;AAEA,IAAO,UAAA,GAAQ,iBAAiBA,KAAI,CAAA;;;ACRpC,IAAMA,KAAAA,GAAO;AAAA,EACX,KAAA,EAAO,WAAA;AAAA,EACP,IAAA,EAAM;AAAA,IACJ,MAAA,EAAQ,gBAAA;AAAA,IACR,MAAA,EAAQ;AAAA;AAEZ,CAAA;AAEA,IAAO,UAAA,GAAQ,iBAAiBA,KAAI,CAAA;;;ACJpC,IAAM,KAAA,GAAyB,MAAA,CAAO,MAAA,CAAO,EAAE,CAAA;AAQ/C,IAAM,OAAA,GAA2C;AAAA,EAC/C,EAAA,EAAA,UAAA;AAAA,EACA,EAAA,EAAA,UAAA;AAAA,EACA,EAAA,EAAA;AACF,CAAA;AASO,SAAS,eACd,IAAA,EACG;AACH,EAAA,OAAQ,OAAA,CAAQ,IAAI,CAAA,IAAK,KAAA;AAC3B;ACpBO,SAAS,eACd,IAAA,EACG;AACH,EAAA,OAAO,QAAQ,MAAM,cAAA,CAAkB,IAAI,CAAA,EAAG,CAAC,IAAI,CAAC,CAAA;AACtD","file":"index.js","sourcesContent":["import type { TranslationData } from \"./types\";\n\n/**\n * Wrap a translation bundle in a Proxy that returns `null` for any\n * missing top-level key, while leaving nested objects untouched so\n * missing nested keys still resolve to `undefined` (standard JS\n * semantics).\n *\n * Explicit `null` values in the source are preserved.\n */\nexport function withNullTopLevel<T extends TranslationData>(data: T): T {\n return new Proxy(data, {\n get(target, prop, receiver) {\n if (typeof prop === \"string\" && !(prop in target)) {\n return null;\n }\n return Reflect.get(target, prop, receiver);\n },\n }) as T;\n}\n","import { withNullTopLevel } from \"../normalize\";\n\nconst data = {\n title: \"শিরোনাম\",\n home: {\n header: \"হেডার\",\n footer: \"ফুটার\",\n },\n};\n\nexport default withNullTopLevel(data);\n","import { withNullTopLevel } from \"../normalize\";\n\nconst data = {\n title: \"the title\",\n home: {\n header: \"this is header\",\n footer: \"this is footer\",\n },\n};\n\nexport default withNullTopLevel(data);\n","import { withNullTopLevel } from \"../normalize\";\n\nconst data = {\n title: \"the title\",\n home: {\n header: \"this is header\",\n footer: \"this is footer\",\n },\n};\n\nexport default withNullTopLevel(data);\n","import bn from \"./locales/bn\";\nimport en from \"./locales/en\";\nimport ne from \"./locales/ne\";\nimport type { TranslationData } from \"./types\";\n\n/** Shared empty fallback for unknown languages. Frozen so it can't be mutated. */\nconst EMPTY: TranslationData = Object.freeze({});\n\n/**\n * Locale registry. Adding a new language means:\n * 1. drop a `src/locales/<code>.ts` that exports `normalizeTopLevel(data)`\n * 2. import it here\n * 3. add it to this map\n */\nconst locales: Record<string, TranslationData> = {\n en,\n bn,\n ne,\n};\n\n/**\n * Returns the translation bundle for the given language code.\n * Unknown / undefined / empty values fall back to a stable empty object.\n *\n * Framework-agnostic: works in React, Next.js server components, Vue,\n * Svelte, or vanilla Node scripts.\n */\nexport function getTranslation<T extends object = TranslationData>(\n lang: string,\n): T {\n return (locales[lang] ?? EMPTY) as T;\n}\n","import { useMemo } from \"react\";\nimport { getTranslation } from \"./getTranslation\";\nimport type { TranslationData } from \"./types\";\n\n/**\n * React hook: returns the translation bundle for the given language.\n *\n * Memoized on `lang`, so the same language produces a stable object\n * reference across re-renders. Switching language swaps the reference\n * (and any consumers destructuring top-level keys will re-render).\n */\nexport function useTranslation<T extends object = TranslationData>(\n lang: string,\n): T {\n return useMemo(() => getTranslation<T>(lang), [lang]);\n}\n"]}
1
+ {"version":3,"sources":["../src/locales/bn.ts","../src/locales/en.ts","../src/locales/ne.ts","../src/getTranslation.ts","../src/useTranslation.ts"],"names":["data"],"mappings":";;;AAAA,IAAM,IAAA,GAAO;AAAA,EACX,KAAA,EAAO,4CAAA;AAAA,EACP,IAAA,EAAM;AAAA,IACJ,MAAA,EAAQ,gCAAA;AAAA,IACR,MAAA,EAAQ;AAAA;AAEZ,CAAA;AAEA,IAAO,UAAA,GAAQ,IAAA;;;ACRf,IAAMA,KAAAA,GAAO;AAAA,EACX,KAAA,EAAO,WAAA;AAAA,EACP,IAAA,EAAM;AAAA,IACJ,MAAA,EAAQ,gBAAA;AAAA,IACR,MAAA,EAAQ;AAAA;AAEZ,CAAA;AAEA,IAAO,UAAA,GAAQA,KAAAA;;;ACRf,IAAMA,KAAAA,GAAO;AAAA,EACX,KAAA,EAAO,WAAA;AAAA,EACP,IAAA,EAAM;AAAA,IACJ,MAAA,EAAQ,gBAAA;AAAA,IACR,MAAA,EAAQ;AAAA;AAEZ,CAAA;AAEA,IAAO,UAAA,GAAQA,KAAAA;;;ACFf,IAAM,KAAA,GAAyB,MAAA,CAAO,MAAA,CAAO,EAAE,CAAA;AAQ/C,IAAM,OAAA,GAA2C;AAAA,EAC/C,EAAA,EAAA,UAAA;AAAA,EACA,EAAA,EAAA,UAAA;AAAA,EACA,EAAA,EAAA;AACF,CAAA;AASO,SAAS,eACd,IAAA,EACG;AACH,EAAA,OAAQ,OAAA,CAAQ,IAAI,CAAA,IAAK,KAAA;AAC3B;ACpBO,SAAS,eACd,IAAA,EACG;AACH,EAAA,OAAO,QAAQ,MAAM,cAAA,CAAkB,IAAI,CAAA,EAAG,CAAC,IAAI,CAAC,CAAA;AACtD","file":"index.js","sourcesContent":["const data = {\n title: \"শিরোনাম\",\n home: {\n header: \"হেডার\",\n footer: \"ফুটার\",\n },\n};\n\nexport default data;\n","const data = {\n title: \"the title\",\n home: {\n header: \"this is header\",\n footer: \"this is footer\",\n },\n};\n\nexport default data;\n","const data = {\n title: \"the title\",\n home: {\n header: \"this is header\",\n footer: \"this is footer\",\n },\n};\n\nexport default data;\n","import bn from \"./locales/bn\";\nimport en from \"./locales/en\";\nimport ne from \"./locales/ne\";\nimport type { TranslationData } from \"./types\";\n\n/** Shared empty fallback for unknown languages. Frozen so it can't be mutated. */\nconst EMPTY: TranslationData = Object.freeze({});\n\n/**\n * Locale registry. Adding a new language means:\n * 1. drop a `src/locales/<code>.ts` that exports the locale object as default\n * 2. import it here\n * 3. add it to this map\n */\nconst locales: Record<string, TranslationData> = {\n en,\n bn,\n ne,\n};\n\n/**\n * Returns the translation bundle for the given language code.\n * Unknown / undefined / empty values fall back to a stable empty object.\n *\n * Framework-agnostic: works in React, Next.js server components, Vue,\n * Svelte, or vanilla Node scripts.\n */\nexport function getTranslation<T extends object = TranslationData>(\n lang: string,\n): T {\n return (locales[lang] ?? EMPTY) as T;\n}\n","import { useMemo } from \"react\";\nimport { getTranslation } from \"./getTranslation\";\nimport type { TranslationData } from \"./types\";\n\n/**\n * React hook: returns the translation bundle for the given language.\n *\n * Memoized on `lang`, so the same language produces a stable object\n * reference across re-renders. Switching language swaps the reference\n * (and any consumers destructuring top-level keys will re-render).\n */\nexport function useTranslation<T extends object = TranslationData>(\n lang: string,\n): T {\n return useMemo(() => getTranslation<T>(lang), [lang]);\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pantho075/locale",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Tiny framework-agnostic i18n core. Translation data lives in TS, no JSON files, no provider. Works in React, Next.js, Vue, Svelte, and Node.",
5
5
  "type": "module",
6
6
  "sideEffects": false,