@cosmicdrift/kumiko-renderer-web 0.154.2 → 0.155.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/package.json +4 -4
- package/src/app/browser-locale.ts +1 -1
- package/src/sse/live-events.ts +6 -1
- package/src/tokens.ts +4 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cosmicdrift/kumiko-renderer-web",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.155.1",
|
|
4
4
|
"description": "Web-platform bindings for @cosmicdrift/kumiko-renderer. HTML default-primitives, browser history-based navigation, EventSource-backed live events, and a one-call createKumikoApp that mounts the whole stack via react-dom.",
|
|
5
5
|
"license": "BUSL-1.1",
|
|
6
6
|
"author": "Marc Frost <marc@cosmicdriftgamestudio.com>",
|
|
@@ -16,9 +16,9 @@
|
|
|
16
16
|
"./styles.css": "./src/styles.css"
|
|
17
17
|
},
|
|
18
18
|
"dependencies": {
|
|
19
|
-
"@cosmicdrift/kumiko-dispatcher-live": "0.
|
|
20
|
-
"@cosmicdrift/kumiko-headless": "0.
|
|
21
|
-
"@cosmicdrift/kumiko-renderer": "0.
|
|
19
|
+
"@cosmicdrift/kumiko-dispatcher-live": "0.155.1",
|
|
20
|
+
"@cosmicdrift/kumiko-headless": "0.155.1",
|
|
21
|
+
"@cosmicdrift/kumiko-renderer": "0.155.1",
|
|
22
22
|
"@radix-ui/react-dialog": "^1.1.15",
|
|
23
23
|
"@radix-ui/react-dropdown-menu": "^2.1.16",
|
|
24
24
|
"@radix-ui/react-label": "^2.1.8",
|
|
@@ -67,7 +67,7 @@ export function createBrowserLocaleResolver(
|
|
|
67
67
|
timeZone: () => timeZone,
|
|
68
68
|
subscribe: store.subscribe,
|
|
69
69
|
setLocale: (next) => {
|
|
70
|
-
//
|
|
70
|
+
// skip: locale unchanged, avoid redundant localStorage write
|
|
71
71
|
// own Object.is-Gate would already block listener notification,
|
|
72
72
|
// but the persistence side-effect lives outside the store.
|
|
73
73
|
if (next === store.getSnapshot()) return;
|
package/src/sse/live-events.ts
CHANGED
|
@@ -41,7 +41,7 @@ export function createEventSourceLiveEvents(
|
|
|
41
41
|
try {
|
|
42
42
|
parsed = JSON.parse(raw) as LiveEvent["data"];
|
|
43
43
|
} catch {
|
|
44
|
-
//
|
|
44
|
+
// skip: malformed SSE payload, drop it rather than crash all subscribers
|
|
45
45
|
// zu crashen und alle anderen subscribers mitzureißen.
|
|
46
46
|
return;
|
|
47
47
|
}
|
|
@@ -52,12 +52,15 @@ export function createEventSourceLiveEvents(
|
|
|
52
52
|
};
|
|
53
53
|
|
|
54
54
|
const ensureConnected = (): void => {
|
|
55
|
+
// skip: EventSource already connected
|
|
55
56
|
if (source !== undefined) return;
|
|
57
|
+
// skip: no window/EventSource available (SSR/non-browser), nothing to connect
|
|
56
58
|
if (typeof window === "undefined" || typeof EventSource === "undefined") return;
|
|
57
59
|
source = new EventSource(url);
|
|
58
60
|
};
|
|
59
61
|
|
|
60
62
|
const ensureListenersForEntity = (entityName: string): void => {
|
|
63
|
+
// skip: not connected yet, listeners get wired once ensureConnected runs
|
|
61
64
|
if (source === undefined) return;
|
|
62
65
|
for (const verb of VERBS) {
|
|
63
66
|
const type = `${entityName}.${verb}`;
|
|
@@ -70,7 +73,9 @@ export function createEventSourceLiveEvents(
|
|
|
70
73
|
};
|
|
71
74
|
|
|
72
75
|
const closeIfEmpty = (): void => {
|
|
76
|
+
// skip: subscribers remain, connection still needed
|
|
73
77
|
if (subscribers.size > 0) return;
|
|
78
|
+
// skip: already closed, nothing to close
|
|
74
79
|
if (source === undefined) return;
|
|
75
80
|
source.close();
|
|
76
81
|
source = undefined;
|
package/src/tokens.ts
CHANGED
|
@@ -55,6 +55,7 @@ function persistMode(mode: ThemeMode): void {
|
|
|
55
55
|
* in der Host-HTML (siehe Header-Kommentar) macht dasselbe synchron
|
|
56
56
|
* vor dem ersten Paint. */
|
|
57
57
|
export function applyStoredThemeMode(): void {
|
|
58
|
+
// skip: no document (SSR/non-DOM context), nothing to apply
|
|
58
59
|
if (typeof document === "undefined") return;
|
|
59
60
|
let stored: string | null = null;
|
|
60
61
|
try {
|
|
@@ -63,6 +64,7 @@ export function applyStoredThemeMode(): void {
|
|
|
63
64
|
// skip: localStorage kann werfen (Private-Mode) — ohne gespeicherte
|
|
64
65
|
// Wahl bleibt der Server-/HTML-Default stehen.
|
|
65
66
|
}
|
|
67
|
+
// skip: no valid persisted mode stored, keep server/HTML default
|
|
66
68
|
if (stored !== "dark" && stored !== "light") return;
|
|
67
69
|
document.documentElement.classList.toggle("dark", stored === "dark");
|
|
68
70
|
notifyThemeChange();
|
|
@@ -99,12 +101,14 @@ export function useBrowserTokensApi(): TokensApi {
|
|
|
99
101
|
tokens: cssVarTokens,
|
|
100
102
|
mode,
|
|
101
103
|
setMode: (next) => {
|
|
104
|
+
// skip: no document (SSR/non-DOM context), nothing to toggle
|
|
102
105
|
if (typeof document === "undefined") return;
|
|
103
106
|
document.documentElement.classList.toggle("dark", next === "dark");
|
|
104
107
|
persistMode(next);
|
|
105
108
|
notifyThemeChange();
|
|
106
109
|
},
|
|
107
110
|
toggleMode: () => {
|
|
111
|
+
// skip: no document (SSR/non-DOM context), nothing to toggle
|
|
108
112
|
if (typeof document === "undefined") return;
|
|
109
113
|
const nowDark = document.documentElement.classList.toggle("dark");
|
|
110
114
|
persistMode(nowDark ? "dark" : "light");
|