Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

13 — State Management (i18n Module)

Client state for catalog delivery (mobile) and the (planned) console. Framework conventions per 00-shared/06_State_Management.md.


1. State domain

StateLives whereSource
Localeserver request context (ctx.locale)tenant-context.service.ts:58-60
Catalog (flat map)app-side cache (per locale)getMessages response, i18n.service.ts:47-49
Catalog version/hash (planned)app cache + response header
Editor state (keys, dirty, parity)console Cubits06_Screen_Specifications.md
Coverage/drift reportconsole Cubit, fetched on demandGET /api/v1/i18n/drift (planned)

2. Cubit breakdown (console, (planned))

CubitStateEvents
CatalogCubit{ locale, catalog: Map<String,String>, version, status: loading/ready/error }fetch(locale), localeChanged, refresh
KeyListCubit{ keys, filters: {namespace, missingIn: String?, hasParams}, page, hasMore, status }search(q), toggleFilter(f), loadMore(), bulkDelete(ids)
KeyEditorCubit{ key, params, values: Map<locale,String>, dirty: Set<locale>, parity: Map<locale,ParityStatus>, version, saving }load(key), editValue(locale,v), save(), delete(), reload()
LocaleCubit{ locales: Map<tag,{coverage,direction,status}>, promoting }load(), add(tag), promote(tag), demote(tag)
SyncCubit{ report, lastRunAt, exporting }run(), export()

Parity computation (pure function, unit-testable): parity(locale) = diff(valueParams(value), sourceParams(en)) using /\{(\w+)\}/g (i18n.service.ts:42-44).

3. State flow — catalog delivery (mobile)

flowchart LR
    A[App start] --> B[Resolve locale<br/>Accept-Language]
    B --> C{Catalog cached?}
    C -->|yes| D[Render cached]
    C -->|no| E[GET /i18n/messages?locale]
    E --> F{200?}
    F -->|yes| G[Store map keyed by locale]
    F -->|no| H[Retry backoff x3]
    H --> I{ok?}
    I -->|no| J[Offline state + banner]
    G --> D
    J --> K[Retry on connectivity]
    K --> E

4. State flow — key editor save (console, (planned))

flowchart LR
    A[editValue] --> B[Mark dirty]
    B --> C[Debounce 300ms parity check]
    C --> D{Parity ok?}
    D -->|no| E[Amber warn / red block]
    D -->|yes| F[Enable Save]
    F --> G[PUT /i18n/keys/:key]
    G --> H{201?}
    H -->|yes| I[Clear dirty + snackbar]
    H -->|409| J[Conflict dialog<br/>reload/overwrite]
    H -->|network| K[Banner + keep draft]

5. Rules

  • Catalog map is immutable after fetch; updates replace the whole map (locale keyed) — no partial mutation.
  • Editor keeps in-memory drafts; leaving with dirty non-empty triggers the unsaved-changes guard (10 §3).
  • One locale per catalog fetch; locale switch swaps the map, never merges.
  • Console state is local-only today (no server push); WebSocket refresh of coverage (forward-looking).