@cosmicdrift/kumiko-renderer 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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cosmicdrift/kumiko-renderer",
3
- "version": "0.154.2",
3
+ "version": "0.155.1",
4
4
  "description": "Platform-agnostic React renderer for Kumiko screens. Contains the shared logic — primitives-contract, hooks, KumikoScreen, navigation & SSE abstractions — that any platform-specific renderer (web, native) composes. No DOM, no EventSource, no react-dom.",
5
5
  "license": "BUSL-1.1",
6
6
  "author": "Marc Frost <marc@cosmicdriftgamestudio.com>",
@@ -15,9 +15,10 @@
15
15
  }
16
16
  },
17
17
  "dependencies": {
18
- "@cosmicdrift/kumiko-framework": "0.154.2",
19
- "@cosmicdrift/kumiko-headless": "0.154.2",
20
- "react": "^19.2.6"
18
+ "@cosmicdrift/kumiko-framework": "0.155.1",
19
+ "@cosmicdrift/kumiko-headless": "0.155.1",
20
+ "react": "^19.2.6",
21
+ "temporal-polyfill": "^0.3.2"
21
22
  },
22
23
  "devDependencies": {
23
24
  "@testing-library/react": "^16.3.2",
@@ -1,6 +1,11 @@
1
+ import { Temporal } from "temporal-polyfill";
2
+
1
3
  // Shared timestamp formatter for operator screens (audit log, job runs) —
2
4
  // falls back to the raw ISO string on an unparseable value instead of "Invalid Date".
3
5
  export function formatWhen(value: string): string {
4
- const d = new Date(value);
5
- return Number.isNaN(d.getTime()) ? value : d.toLocaleString();
6
+ try {
7
+ return Temporal.Instant.from(value).toLocaleString();
8
+ } catch {
9
+ return value;
10
+ }
6
11
  }
@@ -149,6 +149,7 @@ export function useCompletion(debounceMs: number = DEFAULT_DEBOUNCE_MS): UseComp
149
149
  clearTimer();
150
150
  if (text.length === 0) {
151
151
  reset();
152
+ // skip: empty text, state already reset above
152
153
  return;
153
154
  }
154
155
  timerRef.current = setTimeout(() => {
@@ -87,14 +87,14 @@ export function useQuery<TData = unknown>(
87
87
 
88
88
  setLoading(true);
89
89
  const result = await dispatcher.query<TData>(type, payload, { signal: ctrl.signal });
90
- // Don't update state if a newer fetch has already taken over.
90
+ // skip: a newer fetch already superseded this one, don't clobber its state
91
91
  if (ctrl.signal.aborted) return;
92
92
  if (result.isSuccess) {
93
93
  setData(result.data);
94
94
  setError(null);
95
95
  } else {
96
96
  // A cancelled request comes back with code "aborted" from the
97
- // dispatcher — skip the state update, another run replaces it.
97
+ // skip: aborted request, a newer run already replaces this result
98
98
  if (result.error.code === "aborted") return;
99
99
  setError(result.error);
100
100
  }
@@ -104,6 +104,7 @@ export function useQuery<TData = unknown>(
104
104
  useEffect(() => {
105
105
  if (!enabled) {
106
106
  setLoading(false);
107
+ // skip: query disabled, loading state already cleared above
107
108
  return;
108
109
  }
109
110
  void run();
@@ -117,8 +118,10 @@ export function useQuery<TData = unknown>(
117
118
  // Subscription-Lifecycle genau einmal durchwalzt.
118
119
  const subscribeLive = useLiveEvents();
119
120
  useEffect(() => {
121
+ // skip: live mode or query disabled, no SSE subscription needed
120
122
  if (!live || !enabled) return;
121
123
  const entity = entityFromQueryType(type);
124
+ // skip: query type has no mapped entity, nothing to subscribe to
122
125
  if (entity === undefined) return;
123
126
  return subscribeLive(entity, () => {
124
127
  void run();