@oh-my-pi/omp-stats 18.15.0 → 18.16.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/CHANGELOG.md +6 -0
- package/dist/client/index.js +64 -64
- package/package.json +4 -4
- package/src/client/data/query.ts +12 -4
- package/src/client/traces/SpanDrawer.tsx +2 -1
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@oh-my-pi/omp-stats",
|
|
4
|
-
"version": "18.
|
|
4
|
+
"version": "18.16.0",
|
|
5
5
|
"description": "Local observability dashboard for omp AI usage statistics",
|
|
6
6
|
"homepage": "https://omp.sh",
|
|
7
7
|
"author": {
|
|
@@ -42,9 +42,9 @@
|
|
|
42
42
|
"fmt": "oxfmt --no-error-on-unmatched-pattern 'src/**/*.{ts,tsx}' '{test,bench,examples,scripts}/**/*.ts' '*.ts'"
|
|
43
43
|
},
|
|
44
44
|
"dependencies": {
|
|
45
|
-
"@oh-my-pi/pi-ai": "18.
|
|
46
|
-
"@oh-my-pi/pi-catalog": "18.
|
|
47
|
-
"@oh-my-pi/pi-utils": "18.
|
|
45
|
+
"@oh-my-pi/pi-ai": "18.16.0",
|
|
46
|
+
"@oh-my-pi/pi-catalog": "18.16.0",
|
|
47
|
+
"@oh-my-pi/pi-utils": "18.16.0",
|
|
48
48
|
"lucide-react": "^1.24.0",
|
|
49
49
|
"react": "19.2.7",
|
|
50
50
|
"react-dom": "19.2.7"
|
package/src/client/data/query.ts
CHANGED
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
* can resolve to that same object; an unchanged reference does not re-render.
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
|
+
import { toError } from "@oh-my-pi/pi-utils/type-guards";
|
|
18
19
|
import { startTransition, useCallback, useEffect, useReducer, useRef, useState } from "react";
|
|
19
20
|
import { currentLiveVersion, useLiveVersion } from "./live";
|
|
20
21
|
import { cachedEntry, type Inflight, inflightRequest, loadQuery, type QueryFetcher, releaseQuery } from "./query-store";
|
|
@@ -60,6 +61,7 @@ export function useQuery<T>(key: readonly unknown[], fetcher: QueryFetcher<T>, o
|
|
|
60
61
|
const version = useLiveVersion(enabled);
|
|
61
62
|
|
|
62
63
|
const [, rerender] = useReducer((n: number) => n + 1, 0);
|
|
64
|
+
const [settled, recheck] = useReducer((n: number) => n + 1, 0);
|
|
63
65
|
const [error, setError] = useState<{ key: string; error: Error } | null>(null);
|
|
64
66
|
const [refreshing, setRefreshing] = useState(false);
|
|
65
67
|
|
|
@@ -82,8 +84,10 @@ export function useQuery<T>(key: readonly unknown[], fetcher: QueryFetcher<T>, o
|
|
|
82
84
|
waiting.current = { key: targetKey, request };
|
|
83
85
|
// Join the new request before leaving the old one, so a shared request isn't aborted in between.
|
|
84
86
|
if (current) releaseQuery(current.key, current.request);
|
|
87
|
+
let succeeded = false;
|
|
85
88
|
request.promise
|
|
86
89
|
.then(data => {
|
|
90
|
+
succeeded = true;
|
|
87
91
|
if (keyRef.current !== targetKey) return;
|
|
88
92
|
// Revalidated to the very same object: nothing on screen changes.
|
|
89
93
|
if (data === shownBefore) {
|
|
@@ -97,11 +101,15 @@ export function useQuery<T>(key: readonly unknown[], fetcher: QueryFetcher<T>, o
|
|
|
97
101
|
})
|
|
98
102
|
.catch((err: unknown) => {
|
|
99
103
|
if (keyRef.current !== targetKey || request.controller.signal.aborted) return;
|
|
100
|
-
setError({ key: targetKey, error:
|
|
104
|
+
setError({ key: targetKey, error: toError(err) });
|
|
101
105
|
})
|
|
102
106
|
.finally(() => {
|
|
103
|
-
if (waiting.current?.request
|
|
104
|
-
|
|
107
|
+
if (waiting.current?.request !== request) return;
|
|
108
|
+
waiting.current = null;
|
|
109
|
+
if (keyRef.current !== targetKey) return;
|
|
110
|
+
setRefreshing(false);
|
|
111
|
+
// A newer live version may have arrived while this older request was in flight.
|
|
112
|
+
if (succeeded && (cachedEntry(targetKey)?.version ?? -1) < currentLiveVersion()) recheck();
|
|
105
113
|
});
|
|
106
114
|
}, []);
|
|
107
115
|
|
|
@@ -128,7 +136,7 @@ export function useQuery<T>(key: readonly unknown[], fetcher: QueryFetcher<T>, o
|
|
|
128
136
|
}
|
|
129
137
|
const timer = setTimeout(() => run(keyString), wait);
|
|
130
138
|
return () => clearTimeout(timer);
|
|
131
|
-
}, [keyString, enabled, version, run, leave]);
|
|
139
|
+
}, [keyString, enabled, version, settled, run, leave]);
|
|
132
140
|
|
|
133
141
|
useEffect(() => {
|
|
134
142
|
if (!enabled || !pollMs) return;
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* + text blocks, tool args/result, user text, subagent task text.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
+
import { toError } from "@oh-my-pi/pi-utils/type-guards";
|
|
7
8
|
import { Check, Copy, X } from "lucide-react";
|
|
8
9
|
import { type ReactNode, useEffect, useRef, useState } from "react";
|
|
9
10
|
import { getSessionEntryDetail } from "../api";
|
|
@@ -112,7 +113,7 @@ export function SpanDrawer({
|
|
|
112
113
|
})
|
|
113
114
|
.catch(err => {
|
|
114
115
|
if (controller.signal.aborted) return;
|
|
115
|
-
setError(
|
|
116
|
+
setError(toError(err));
|
|
116
117
|
})
|
|
117
118
|
.finally(() => {
|
|
118
119
|
if (!controller.signal.aborted) setLoading(false);
|