fix(cli): store annonces inter-agent borné par projectId avec reset et réhydratation busy au changement de projet — #236
This commit is contained in:
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* `AnnouncementsProvider` — the live, app-wide store for inter-agent announcements
|
||||
* `AnnouncementsProvider` — the live, project-scoped store for inter-agent announcements
|
||||
* (ticket #4, F1 wiring). Subscribes **once** to the domain-event stream via the
|
||||
* {@link SystemGateway} and folds two orthogonal signals:
|
||||
*
|
||||
@ -22,8 +22,9 @@
|
||||
* busy is the sole lifecycle authority, which is exactly what we want.)
|
||||
*
|
||||
* Consumers read via {@link useTargetAnnouncements} (F3) and
|
||||
* {@link useRequesterAnnouncements} (F2). The store is never persisted — it is
|
||||
* rebuilt live from the event stream and the read-model snapshot.
|
||||
* {@link useRequesterAnnouncements} (F2). The store is never persisted and is
|
||||
* reset whenever the provider's project changes; it is rebuilt live from the
|
||||
* event stream and the read-model snapshot for that project.
|
||||
*/
|
||||
|
||||
import {
|
||||
@ -76,7 +77,13 @@ const DEFAULT_STORE: AnnouncementsStore = {
|
||||
|
||||
const AnnouncementsContext = createContext<AnnouncementsStore | null>(null);
|
||||
|
||||
export function AnnouncementsProvider({ children }: { children: ReactNode }) {
|
||||
export function AnnouncementsProvider({
|
||||
projectId,
|
||||
children,
|
||||
}: {
|
||||
projectId: string | null;
|
||||
children: ReactNode;
|
||||
}) {
|
||||
const { system } = useGateways();
|
||||
const [index, setIndex] = useState<AnnouncementIndex>(emptyAnnouncementIndex);
|
||||
const [busy, setBusy] = useState<BusyMap>({});
|
||||
@ -87,15 +94,21 @@ export function AnnouncementsProvider({ children }: { children: ReactNode }) {
|
||||
setBusy((prev) => (agentId in prev ? prev : { ...prev, [agentId]: value }));
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
setIndex(emptyAnnouncementIndex());
|
||||
setBusy({});
|
||||
}, [projectId]);
|
||||
|
||||
useEffect(() => {
|
||||
// `system` may be absent in unit tests injecting a partial gateway set.
|
||||
if (!system) return;
|
||||
if (!system || !projectId) return;
|
||||
let unsubscribe: (() => void) | undefined;
|
||||
let cancelled = false;
|
||||
|
||||
void system
|
||||
.onDomainEvent((event) => {
|
||||
if (event.type === "agentAnnouncement") {
|
||||
if (event.projectId !== projectId) return;
|
||||
// Content of the overlay/preview.
|
||||
setIndex((prev) =>
|
||||
appendAnnouncement(prev, {
|
||||
@ -127,7 +140,7 @@ export function AnnouncementsProvider({ children }: { children: ReactNode }) {
|
||||
cancelled = true;
|
||||
unsubscribe?.();
|
||||
};
|
||||
}, [system]);
|
||||
}, [system, projectId]);
|
||||
|
||||
const store = useMemo<AnnouncementsStore>(
|
||||
() => ({ index, busy, seedBusy }),
|
||||
|
||||
Reference in New Issue
Block a user