@cosmicdrift/kumiko-dispatcher-live 0.220.0 → 0.221.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.
Files changed (2) hide show
  1. package/package.json +2 -2
  2. package/src/locale.ts +17 -11
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cosmicdrift/kumiko-dispatcher-live",
3
- "version": "0.220.0",
3
+ "version": "0.221.0",
4
4
  "description": "HTTP-only Dispatcher for Kumiko UIs. Always-online; failures surface immediately. Default client for web admin/cockpit apps.",
5
5
  "license": "BUSL-1.1",
6
6
  "author": "Marc Frost <marc@cosmicdriftgamestudio.com>",
@@ -24,7 +24,7 @@
24
24
  }
25
25
  },
26
26
  "dependencies": {
27
- "@cosmicdrift/kumiko-headless": "0.220.0"
27
+ "@cosmicdrift/kumiko-headless": "0.221.0"
28
28
  },
29
29
  "publishConfig": {
30
30
  "registry": "https://registry.npmjs.org",
package/src/locale.ts CHANGED
@@ -1,22 +1,28 @@
1
1
  // Active-locale header transport for the live dispatcher.
2
2
  //
3
3
  // @cosmicdrift/kumiko-renderer-web's DocumentLangSync (mounted by
4
- // createKumikoApp/createPublicSurface) keeps document.documentElement.lang in
5
- // sync with the app's LocaleResolver. This module reads that value back so
6
- // every outgoing request carries the language the user is ACTUALLY using —
7
- // not the app's hardcoded boot language — with zero app-side wiring.
4
+ // createKumikoApp/createPublicSurface) sets dataset.kumikoLocale from the
5
+ // LocaleResolver. This module reads that marker back so every outgoing
6
+ // request carries the language the user is ACTUALLY using — not a static
7
+ // <html lang> — with zero app-side wiring.
8
8
 
9
9
  // Kept in sync with LOCALE_HEADER_NAME in api-constants.ts by hand rather
10
10
  // than imported from @cosmicdrift/kumiko-framework — this package must
11
11
  // remain server-dep-free (runs in browsers and React Native).
12
12
  export const LOCALE_HEADER_NAME = "X-Locale";
13
13
 
14
- // Reads document.documentElement.lang. Returns undefined for non-browser
15
- // environments (SSR, Web Worker, React Native) or before any provider has
16
- // set a lang yet — callers skip the header in that case and the server
17
- // falls back to Accept-Language, then its boot default.
14
+ // Loose BCP-47 tag check — reject newlines/junk that would break fetch headers.
15
+ const LOCALE_TAG = /^[A-Za-z]{2,3}(-[A-Za-z0-9]{2,8})*$/;
16
+
17
+ // Reads dataset.kumikoLocale. Returns undefined for non-browser environments
18
+ // (SSR, Web Worker, React Native), before DocumentLangSync has run, or when
19
+ // the value is not a safe language tag — callers skip the header and the
20
+ // server falls back to Accept-Language, then its boot default.
18
21
  export function readActiveLocale(): string | undefined {
19
- const g = globalThis as { document?: { documentElement?: { lang?: string } } };
20
- const lang = g.document?.documentElement?.lang;
21
- return lang !== undefined && lang.length > 0 ? lang : undefined;
22
+ const g = globalThis as {
23
+ document?: { documentElement?: { dataset?: { kumikoLocale?: string } } };
24
+ };
25
+ const lang = g.document?.documentElement?.dataset?.kumikoLocale;
26
+ if (lang === undefined || lang.length === 0) return undefined;
27
+ return LOCALE_TAG.test(lang) ? lang : undefined;
22
28
  }