@omercnet/paseo-pr-radar 0.4.1-next.133.1 → 0.4.1-next.144.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.
@@ -0,0 +1,55 @@
1
+ import type { PaseoApi } from "./radar";
2
+
3
+ export function observeDirectoryInvalidation(
4
+ paseo: PaseoApi,
5
+ invalidate: () => void,
6
+ debounceMs: number,
7
+ ): () => void {
8
+ const lifetime = new AbortController();
9
+ const subscriptions: Array<{ release(): Promise<void> }> = [];
10
+ const unsubscribes: Array<() => void> = [];
11
+ let stopped = false;
12
+ let timer: NodeJS.Timeout | undefined;
13
+ const scheduleInvalidation = () => {
14
+ if (stopped || timer !== undefined) return;
15
+ timer = setTimeout(() => {
16
+ timer = undefined;
17
+ if (!stopped) invalidate();
18
+ }, debounceMs);
19
+ };
20
+ const attach = (subscription: {
21
+ subscribe(observer: { snapshot(): void; update(message: unknown): void }): () => void;
22
+ release(): Promise<void>;
23
+ }) => {
24
+ subscriptions.push(subscription);
25
+ if (stopped) {
26
+ void subscription.release().catch(() => undefined);
27
+ return;
28
+ }
29
+ unsubscribes.push(
30
+ subscription.subscribe({
31
+ snapshot: scheduleInvalidation,
32
+ update: scheduleInvalidation,
33
+ }),
34
+ );
35
+ };
36
+
37
+ void paseo.agents
38
+ .list({ subscribe: {}, signal: lifetime.signal })
39
+ .then(({ subscription }) => attach(subscription))
40
+ .catch(() => undefined);
41
+ void paseo.workspaces
42
+ .list({ subscribe: {} })
43
+ .then(({ subscription }) => attach(subscription))
44
+ .catch(() => undefined);
45
+
46
+ return () => {
47
+ stopped = true;
48
+ lifetime.abort();
49
+ if (timer !== undefined) clearTimeout(timer);
50
+ for (const unsubscribe of unsubscribes) unsubscribe();
51
+ void Promise.all(subscriptions.map((subscription) => subscription.release())).catch(
52
+ () => undefined,
53
+ );
54
+ };
55
+ }
@@ -12,6 +12,7 @@ import {
12
12
  View,
13
13
  } from "react-native";
14
14
  import { acknowledgeViewerScope, viewerScope } from "../shared/viewer-scope";
15
+ import { observeDirectoryInvalidation } from "./directory-observation";
15
16
  import {
16
17
  type AgentEntry,
17
18
  agentActionFor,
@@ -136,23 +137,15 @@ export function PrRadar({ theme, layout, host, navigation }: PluginSurfaceProps)
136
137
  return () => clearInterval(clock);
137
138
  }, []);
138
139
 
139
- useEffect(() => {
140
- let timer: ReturnType<typeof setTimeout> | undefined;
141
- const invalidate = () => {
142
- if (timer) return;
143
- timer = setTimeout(() => {
144
- timer = undefined;
145
- void queryClient.invalidateQueries({ queryKey });
146
- }, EVENT_DEBOUNCE_MS);
147
- };
148
- const unsubscribeAgents = paseo.agents.subscribe(invalidate);
149
- const unsubscribeWorkspaces = paseo.workspaces.subscribe(invalidate);
150
- return () => {
151
- clearTimeout(timer);
152
- unsubscribeAgents();
153
- unsubscribeWorkspaces();
154
- };
155
- }, [paseo, queryClient, queryKey]);
140
+ useEffect(
141
+ () =>
142
+ observeDirectoryInvalidation(
143
+ paseo,
144
+ () => void queryClient.invalidateQueries({ queryKey }),
145
+ EVENT_DEBOUNCE_MS,
146
+ ),
147
+ [paseo, queryClient, queryKey],
148
+ );
156
149
 
157
150
  const rawRows = data?.rows ?? [];
158
151
  const scopeUrls = useMemo(() => rawRows.map((row) => row.url), [rawRows]);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@omercnet/paseo-pr-radar",
3
- "version": "0.4.1-next.133.1",
3
+ "version": "0.4.1-next.144.1",
4
4
  "type": "module",
5
5
  "description": "A viewer-aware delivery queue for pull requests linked to Paseo workspaces.",
6
6
  "license": "MIT",
package/paseo-plugin.json CHANGED
@@ -1,4 +1,4 @@
1
1
  {
2
2
  "id": "pr-radar",
3
- "requirements": { "paseo": ">=0.8.0 <0.10.0" }
3
+ "requirements": { "paseo": ">=0.9.0 <0.10.0" }
4
4
  }