@chipmobilesdk/rn-i18n 0.1.2 → 0.2.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/CHANGELOG.md CHANGED
@@ -1,57 +1,168 @@
1
- # Changelog
2
-
3
- All notable changes to `@chipmobilesdk/rn-i18n` are documented here. This project
4
- follows [Semantic Versioning](https://semver.org/).
5
-
6
- ## 0.1.2 — 2026-11-01
7
-
8
- ### Fixed
9
-
10
- - **A throwing locale listener no longer breaks a locale switch.** Listeners
11
- were notified without isolation, so one that threw skipped every listener
12
- after it (React subscribers included) and made `setLocale` reject after the
13
- switch but before the choice was persisted: the app showed one locale and
14
- stored another. Each listener is now isolated and reported with
15
- `console.warn`, and a listener unsubscribed by an earlier one during the
16
- same change is no longer called. No code change is required.
17
-
18
- ## 0.1.0 — 2026-06-13
19
-
20
- Initial release of the reusable mobile i18n and locale library.
21
-
22
- ### Added
23
-
24
- - `createI18n(config)` with eager configuration validation: duplicate locales,
25
- unknown/duplicate/cyclic fallback chains, missing fallback resources, and
26
- missing storage adapter are rejected before any localized content is served.
27
- - Translation lookup with namespaced nested keys, ordered fallback-chain
28
- resolution, `{{name}}` interpolation, package-owned pluralization, and a
29
- deterministic missing-key policy (one console warning per failed lookup path).
30
- - Runtime locale switching without restart, persisted through an app-injected
31
- `LocaleStorageAdapter`, with recovery from unsupported persisted values.
32
- - Device-locale initialization via an injectable provider (default backed by
33
- Hermes `Intl`), with exact-match and single-language-match selection.
34
- - Locale-aware formatting: `formatNumber`, `formatDate`, `formatCurrency` (via
35
- Hermes `Intl`), and package-owned `formatUnit`/`convertUnit` across length,
36
- mass, volume, and temperature dimensions.
37
- - Declared runtime-only translation entries that resolve through the same
38
- pipeline and are protected during synchronization.
39
- - React bindings: `I18nProvider`, `useTranslation`, `useLocale`.
40
- - Node-only extraction/synchronization CLI (`@chipmobilesdk/rn-i18n/tooling`):
41
- regex-pattern source scanning, locale JSON create/add/preserve/remove,
42
- ambiguous-usage and conflict reporting, malformed-file isolation, typed key
43
- contract generation, and deterministic output.
44
-
45
- ### Adoption notes
46
-
47
- - App-owned translations live in the consuming app (commonly
48
- `src/i18n/locales/<locale>.json`), never inside this package.
49
- - Host frameworks (`react`, `react-native`) are peer dependencies; this package
50
- has zero runtime dependencies.
51
- - No native modules, permissions, network calls, analytics, or tracking are
52
- introduced; the locale preference stays on-device via the injected adapter.
53
-
54
- ### Compatibility
55
-
56
- React `19.x`, React Native `0.85+` (Hermes), TypeScript `5.8+`, Node `>=22.11.0`
57
- for tooling. Android and iOS, with no native code.
1
+ # @chipmobilesdk/rn-i18n
2
+
3
+ ## 0.2.0
4
+
5
+ ### Minor Changes
6
+
7
+ - One diagnostic stream: install a sink with `installSdkSink` from
8
+ `@chipmobilesdk/rn-core` and it receives what every package observes (events,
9
+ failures, warnings) as `SdkDiagnostic`s, redacted. Listeners are notified through
10
+ rn-core, so a listener that throws no longer stops the others nor fails the call that
11
+ notified, and its error is reported rather than swallowed. ([#17](https://github.com/operationd8979/chip-mobile-sdk/pull/17))
12
+
13
+ - rn-ads: a banner's auto-refresh is a new cycle, so its `loaded` and `impression`
14
+ events are no longer deduplicated away; the dedupe memory is bounded. A throwing
15
+ status, consent or placement listener is reported as an `internal_error` event.
16
+ - rn-i18n: new `onDiagnostic` config receives every diagnostic (`I18nDiagnostic`,
17
+ with a stable `code`); without it, warnings go to `console.warn` in development
18
+ builds only. The warn-once memory is bounded.
19
+ - rn-chart: now depends on rn-core for its diagnostics.
20
+ - rn-payment: status, entitlement and pending listeners report a throw to the logger
21
+ instead of swallowing it.
22
+
23
+ - The package's errors extend `SdkError` from the new `@chipmobilesdk/rn-core`
24
+ dependency: `isSdkError` recognises them alongside every other package's, and each
25
+ carries `pkg`, `code` and `retryable`. Names and codes are unchanged. ([#17](https://github.com/operationd8979/chip-mobile-sdk/pull/17))
26
+
27
+ - rn-ai and rn-camera: `retryable` is the new name of `recoverable`, which stays as a
28
+ deprecated alias.
29
+ - rn-auth: `retryable` is true for `network-unavailable`. `redact` also removes URLs,
30
+ e-mail addresses and UUIDs.
31
+ - rn-ads: `redact` also removes JWTs and e-mail addresses, and reduces an `AdsError`
32
+ to its code.
33
+ - rn-ai: an error message quoted from the gateway is pattern-redacted.
34
+ - rn-camera: `redact` also removes JWTs, e-mail addresses and UUIDs.
35
+ - rn-theme: `ThemeConfigError` has `code: 'invalid_config'` and `ThemeContrastError`
36
+ `code: 'contrast'` (new `ThemeErrorCode` type).
37
+ - rn-i18n: `I18nConfigError` has `code: 'invalid_config'` and `UnitConversionError`
38
+ `code: 'unit_conversion'` (new `I18nErrorCode` type).
39
+
40
+ - Hooks read through `useSyncExternalStore` (rn-core's `useExternalStore`) and
41
+ re-render only when what they return changes. ([#17](https://github.com/operationd8979/chip-mobile-sdk/pull/17))
42
+
43
+ - rn-auth: `useProfile` and `useAccessTier` no longer re-render for a status change,
44
+ and the provider's context no longer changes on every transition. New
45
+ `useAuthSelector`. `auth.getState()` returns the same frozen object until the state
46
+ changes, instead of a copy per call.
47
+ - rn-payment: `useEntitlement` re-renders only when its own entitlement changes; the
48
+ engine keeps unchanged entitlement objects across syncs and does not notify for a
49
+ sync that changed nothing.
50
+ - rn-ads: `usePlacementState` and `useAdsStatus` read tear-free; `useAdsEvents` keeps
51
+ one subscription when given an inline listener.
52
+ - rn-i18n: `useTranslation` returns the same `t` until the locale changes, and
53
+ `useLocale`'s `setLocale` is stable.
54
+ - rn-ai: new `useAiBehaviorState`, with `client.subscribe` and a stable
55
+ `client.getBehaviorState()`.
56
+
57
+ - Every package's own copy is an rn-core message catalog that an app can translate. ([#17](https://github.com/operationd8979/chip-mobile-sdk/pull/17))
58
+
59
+ - rn-i18n: new `runtimeEntriesFromCatalog(catalog)` registers any SDK catalog in one
60
+ line, converting `{name}` variables to `{{name}}`.
61
+ - rn-ai: new `messageKeyForError(error)` gives the copy for every error code, and
62
+ `aiMessageSet`. The input placeholder default is neutral ("Type a message…"), and
63
+ two keys were added for errors that had none (`ai.error.signIn`, `ai.error.generic`).
64
+ - rn-auth: new `authMessages`, the catalog split into user and developer copy.
65
+ - rn-payment: new `paymentMessages`.
66
+ - rn-chart: summaries, announcements, adjustable-action labels, built-in state text
67
+ and legend hints come from `chartStrings`; pass `strings` to translate them. The
68
+ `accessibility.summaryFormatter` prop, declared before, now replaces the summary.
69
+
70
+ - Formatters come from rn-core's cache instead of being built per call. ([#17](https://github.com/operationd8979/chip-mobile-sdk/pull/17))
71
+
72
+ - rn-notification: resolving a time zone builds one `Intl.DateTimeFormat` per zone
73
+ instead of one per occurrence; expanding 32 series of 32 occurrences went from
74
+ about 230 ms to under 30 ms on Node. Zone validity is memoized.
75
+ - rn-i18n: number, currency and date formatters are cached. A bad option (an unknown
76
+ currency such as `usd1`) goes through the invalid-format policy instead of
77
+ throwing out of a render, and a locale's `defaultCurrency` must be a three-letter
78
+ ISO 4217 code at startup.
79
+
80
+ - One app-lifecycle source, and a startup that needs no extra frame. ([#17](https://github.com/operationd8979/chip-mobile-sdk/pull/17))
81
+
82
+ - rn-core: `appLifecycle()`, a shared, reference-counted `AppState` subscription that
83
+ reports changes only (`active`, `inactive`, `background`), with `onForeground` for a
84
+ return from the background and `createManualLifecycle` in `./testing`.
85
+ - rn-camera, rn-ads and rn-notification hear the lifecycle through it instead of
86
+ subscribing to `AppState` each, so an app holds one native listener. The camera
87
+ controller's core layer no longer imports `react-native`.
88
+ - rn-payment: `syncOnForeground(engine)` and `<PaymentProvider syncOnForeground>` call
89
+ `handleForeground()` on each return from the background. Off by default; calling
90
+ `handleForeground()` yourself works as before.
91
+ - rn-i18n: `i18n.initSync()` resolves the locale before the first render when the
92
+ storage adapter has the new optional `getItemSync`, and returns false otherwise.
93
+ `localeStorageFromKeyValue(port)` builds such an adapter from rn-core's
94
+ `KeyValuePort` (MMKV).
95
+
96
+ ### Patch Changes
97
+
98
+ - Updated dependencies ([#17](https://github.com/operationd8979/chip-mobile-sdk/pull/17), [#17](https://github.com/operationd8979/chip-mobile-sdk/pull/17), [#17](https://github.com/operationd8979/chip-mobile-sdk/pull/17)):
99
+ - @chipmobilesdk/rn-core@0.1.0
100
+
101
+ ## 0.1.3
102
+
103
+ ### Patch Changes
104
+
105
+ - Packaging only; no code change. The package no longer declares `engines.node`: a
106
+ React Native package does not run on Node, so the field only produced install
107
+ warnings in apps on another Node version. rn-i18n's command-line tooling does run
108
+ on Node; its README's compatibility table states the version it needs. ([#14](https://github.com/operationd8979/chip-mobile-sdk/pull/14))
109
+
110
+ ## 0.1.2 — 2026-11-01
111
+
112
+ ### Fixed
113
+
114
+ - **A throwing locale listener no longer breaks a locale switch.** Listeners
115
+ were notified without isolation, so one that threw skipped every listener
116
+ after it (React subscribers included) and made `setLocale` reject after the
117
+ switch but before the choice was persisted: the app showed one locale and
118
+ stored another. Each listener is now isolated and reported with
119
+ `console.warn`, and a listener unsubscribed by an earlier one during the
120
+ same change is no longer called. No code change is required.
121
+
122
+ ## 0.1.1 — 2026-08-01
123
+
124
+ ### Changed
125
+
126
+ - The package now ships its agent skill (`skills/`), which consuming apps
127
+ copy in with `scripts/sync-sdk-skills.mjs`. No code change.
128
+
129
+ ## 0.1.0 — 2026-06-13
130
+
131
+ Initial release of the reusable mobile i18n and locale library.
132
+
133
+ ### Added
134
+
135
+ - `createI18n(config)` with eager configuration validation: duplicate locales,
136
+ unknown/duplicate/cyclic fallback chains, missing fallback resources, and
137
+ missing storage adapter are rejected before any localized content is served.
138
+ - Translation lookup with namespaced nested keys, ordered fallback-chain
139
+ resolution, `{{name}}` interpolation, package-owned pluralization, and a
140
+ deterministic missing-key policy (one console warning per failed lookup path).
141
+ - Runtime locale switching without restart, persisted through an app-injected
142
+ `LocaleStorageAdapter`, with recovery from unsupported persisted values.
143
+ - Device-locale initialization via an injectable provider (default backed by
144
+ Hermes `Intl`), with exact-match and single-language-match selection.
145
+ - Locale-aware formatting: `formatNumber`, `formatDate`, `formatCurrency` (via
146
+ Hermes `Intl`), and package-owned `formatUnit`/`convertUnit` across length,
147
+ mass, volume, and temperature dimensions.
148
+ - Declared runtime-only translation entries that resolve through the same
149
+ pipeline and are protected during synchronization.
150
+ - React bindings: `I18nProvider`, `useTranslation`, `useLocale`.
151
+ - Node-only extraction/synchronization CLI (`@chipmobilesdk/rn-i18n/tooling`):
152
+ regex-pattern source scanning, locale JSON create/add/preserve/remove,
153
+ ambiguous-usage and conflict reporting, malformed-file isolation, typed key
154
+ contract generation, and deterministic output.
155
+
156
+ ### Adoption notes
157
+
158
+ - App-owned translations live in the consuming app (commonly
159
+ `src/i18n/locales/<locale>.json`), never inside this package.
160
+ - Host frameworks (`react`, `react-native`) are peer dependencies; this package
161
+ has zero runtime dependencies.
162
+ - No native modules, permissions, network calls, analytics, or tracking are
163
+ introduced; the locale preference stays on-device via the injected adapter.
164
+
165
+ ### Compatibility
166
+
167
+ React `19.x`, React Native `0.85+` (Hermes), TypeScript `5.8+`, Node `>=22.11.0`
168
+ for tooling. Android and iOS, with no native code.