@cosmicdrift/kumiko-dispatcher-live 0.211.0 → 0.213.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/package.json +2 -2
- package/src/dispatcher-live.ts +5 -0
- package/src/index.ts +1 -0
- package/src/locale.ts +22 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cosmicdrift/kumiko-dispatcher-live",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.213.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.
|
|
27
|
+
"@cosmicdrift/kumiko-headless": "0.213.0"
|
|
28
28
|
},
|
|
29
29
|
"publishConfig": {
|
|
30
30
|
"registry": "https://registry.npmjs.org",
|
package/src/dispatcher-live.ts
CHANGED
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
} from "@cosmicdrift/kumiko-headless";
|
|
16
16
|
import { CSRF_HEADER_NAME, readCsrfToken } from "./csrf";
|
|
17
17
|
import { buildAbortError, buildNetworkError, mapServerError } from "./error-mapping";
|
|
18
|
+
import { LOCALE_HEADER_NAME, readActiveLocale } from "./locale";
|
|
18
19
|
import { iterateSseChunks } from "./sse-stream";
|
|
19
20
|
|
|
20
21
|
// HTTP-only dispatcher. Maps Kumiko's client-side Dispatcher contract to
|
|
@@ -103,6 +104,8 @@ export function createLiveDispatcher(options: LiveDispatcherOptions = {}): Dispa
|
|
|
103
104
|
};
|
|
104
105
|
const csrf = readCsrf();
|
|
105
106
|
if (csrf !== undefined) headers[CSRF_HEADER_NAME] = csrf;
|
|
107
|
+
const locale = readActiveLocale();
|
|
108
|
+
if (locale !== undefined) headers[LOCALE_HEADER_NAME] = locale;
|
|
106
109
|
// If no CSRF token, still send the request — public / pre-login
|
|
107
110
|
// routes like /auth/login don't require CSRF, and POST /write/query/
|
|
108
111
|
// batch against a logged-out client returns 401 via auth-middleware
|
|
@@ -204,6 +207,8 @@ export function createLiveDispatcher(options: LiveDispatcherOptions = {}): Dispa
|
|
|
204
207
|
};
|
|
205
208
|
const csrf = readCsrf();
|
|
206
209
|
if (csrf !== undefined) headers[CSRF_HEADER_NAME] = csrf;
|
|
210
|
+
const locale = readActiveLocale();
|
|
211
|
+
if (locale !== undefined) headers[LOCALE_HEADER_NAME] = locale;
|
|
207
212
|
|
|
208
213
|
let response: Response;
|
|
209
214
|
try {
|
package/src/index.ts
CHANGED
|
@@ -2,5 +2,6 @@ export { CSRF_COOKIE_NAME, CSRF_HEADER_NAME, readCsrfToken } from "./csrf";
|
|
|
2
2
|
export type { LiveDispatcherOptions } from "./dispatcher-live";
|
|
3
3
|
export { createLiveDispatcher } from "./dispatcher-live";
|
|
4
4
|
export { buildAbortError, buildNetworkError, mapServerError } from "./error-mapping";
|
|
5
|
+
export { LOCALE_HEADER_NAME, readActiveLocale } from "./locale";
|
|
5
6
|
export type { SseFrame } from "./sse-stream";
|
|
6
7
|
export { iterateSseChunks, parseSseBlock, parseSseFrames } from "./sse-stream";
|
package/src/locale.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// Active-locale header transport for the live dispatcher.
|
|
2
|
+
//
|
|
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.
|
|
8
|
+
|
|
9
|
+
// Kept in sync with LOCALE_HEADER_NAME in api-constants.ts by hand rather
|
|
10
|
+
// than imported from @cosmicdrift/kumiko-framework — this package must
|
|
11
|
+
// remain server-dep-free (runs in browsers and React Native).
|
|
12
|
+
export const LOCALE_HEADER_NAME = "X-Locale";
|
|
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.
|
|
18
|
+
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
|
+
}
|