@burdenoff/microfe-conversations 2026.924.1 → 2026.928.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.
@@ -1,9 +1,10 @@
1
1
  import { useConversations as e } from "../providers/ConversationsProvider.js";
2
- import { useArchiveConversationMutation as t, useCreateConversationMutation as n, useGetConversationQuery as r, useGetConversationsQuery as i, useGetWorkspaceDirectoryQuery as a, useLeaveConversationMutation as o, useMuteConversationMutation as s, usePinConversationMutation as c, useSearchConversationsQuery as l, useUnarchiveConversationMutation as u, useUnmuteConversationMutation as d, useUnpinConversationMutation as f, useUpdateConversationByHookMutation as p } from "../../generated/wspace-operations.js";
3
- import { mapConversation as m } from "../utils/mappers.js";
4
- import { useCallback as h, useEffect as g, useMemo as _, useState as v } from "react";
2
+ import { useArchiveConversationMutation as t, useCreateConversationMutation as n, useGetConversationQuery as r, useGetConversationsQuery as i, useGetWorkspaceDirectoryQuery as a, useLeaveConversationMutation as o, useMarkConversationAsReadMutation as s, useMuteConversationMutation as c, usePinConversationMutation as l, useSearchConversationsQuery as u, useUnarchiveConversationMutation as d, useUnmuteConversationMutation as f, useUnpinConversationMutation as p, useUpdateConversationByHookMutation as m } from "../../generated/wspace-operations.js";
3
+ import { mapConversation as h } from "../utils/mappers.js";
4
+ import { applyMarkConversationAsReadToCache as g } from "../utils/readReceiptCache.js";
5
+ import { useCallback as _, useEffect as v, useMemo as y, useState as b } from "react";
5
6
  //#region src/conversations/hooks/useConversationQueries.ts
6
- function y(t) {
7
+ function x(t) {
7
8
  let { workspaceId: n } = e(), r = i({
8
9
  variables: {
9
10
  first: t?.first ?? 25,
@@ -16,7 +17,7 @@ function y(t) {
16
17
  }
17
18
  },
18
19
  skip: !n
19
- }), a = _(() => r.data?.conversations.edges.map((e) => m(e.node)) ?? [], [r.data]), o = r.data?.conversations.pageInfo.hasNextPage ?? !1;
20
+ }), a = y(() => r.data?.conversations.edges.map((e) => h(e.node)) ?? [], [r.data]), o = r.data?.conversations.pageInfo.hasNextPage ?? !1;
20
21
  return {
21
22
  conversations: a,
22
23
  loading: r.loading,
@@ -40,13 +41,13 @@ function y(t) {
40
41
  }
41
42
  };
42
43
  }
43
- function b(t) {
44
+ function S(t) {
44
45
  let { workspaceId: n } = e(), i = r({
45
46
  variables: { id: t },
46
47
  skip: !n || !t
47
48
  });
48
49
  return {
49
- conversation: i.data?.conversation ? m(i.data.conversation) : null,
50
+ conversation: i.data?.conversation ? h(i.data.conversation) : null,
50
51
  members: i.data?.conversation?.members.edges.map((e) => e.node).filter((e) => !!e) ?? [],
51
52
  membersTotalCount: i.data?.conversation?.members.totalCount ?? 0,
52
53
  loading: i.loading,
@@ -56,8 +57,8 @@ function b(t) {
56
57
  }
57
58
  };
58
59
  }
59
- function x(t) {
60
- let { workspaceId: n } = e(), r = t.trim(), i = l({
60
+ function C(t) {
61
+ let { workspaceId: n } = e(), r = t.trim(), i = u({
61
62
  variables: {
62
63
  query: r,
63
64
  first: 25
@@ -65,25 +66,25 @@ function x(t) {
65
66
  skip: !n || r.length < 2
66
67
  });
67
68
  return {
68
- conversations: i.data?.searchConversations.edges.map((e) => m(e.node)) ?? [],
69
+ conversations: i.data?.searchConversations.edges.map((e) => h(e.node)) ?? [],
69
70
  loading: i.loading,
70
71
  error: i.error ?? null
71
72
  };
72
73
  }
73
- var S = 25, C = 250;
74
- function w(t) {
75
- let { workspaceId: n } = e(), [r, i] = v(t.trim());
76
- g(() => {
74
+ var w = 25, T = 250;
75
+ function E(t) {
76
+ let { workspaceId: n } = e(), [r, i] = b(t.trim());
77
+ v(() => {
77
78
  let e = t.trim(), n = setTimeout(() => {
78
79
  i(e);
79
- }, C);
80
+ }, T);
80
81
  return () => clearTimeout(n);
81
82
  }, [t]);
82
83
  let o = a({
83
84
  variables: {
84
85
  filter: r ? { search: r } : void 0,
85
86
  pagination: {
86
- limit: S,
87
+ limit: w,
87
88
  offset: 0
88
89
  }
89
90
  },
@@ -91,16 +92,16 @@ function w(t) {
91
92
  fetchPolicy: "cache-and-network"
92
93
  });
93
94
  return {
94
- members: _(() => o.data?.workspaceDirectory.edges ?? [], [o.data]),
95
+ members: y(() => o.data?.workspaceDirectory.edges ?? [], [o.data]),
95
96
  totalCount: o.data?.workspaceDirectory.totalCount ?? 0,
96
97
  loading: o.loading,
97
98
  error: o.error ?? null
98
99
  };
99
100
  }
100
- function T() {
101
+ function D() {
101
102
  let { workspaceId: t } = e(), [r, i] = n();
102
103
  return {
103
- createConversation: h(async (e) => {
104
+ createConversation: _(async (e) => {
104
105
  if (!t) throw Error("Workspace context is required to create a conversation");
105
106
  try {
106
107
  let { data: n, error: i } = await r({ variables: { input: {
@@ -112,7 +113,7 @@ function T() {
112
113
  } } });
113
114
  if (i) throw i;
114
115
  let a = n?.createConversation.conversation;
115
- return a ? m(a) : null;
116
+ return a ? h(a) : null;
116
117
  } catch (e) {
117
118
  throw e instanceof Error ? e : /* @__PURE__ */ Error("Failed to create conversation");
118
119
  }
@@ -121,10 +122,35 @@ function T() {
121
122
  error: i.error ?? null
122
123
  };
123
124
  }
124
- function E() {
125
- let [e, n] = t(), [r, i] = u(), [a, l] = c(), [p, m] = f(), [g, _] = s(), [v, y] = d(), [b, x] = o();
125
+ function O() {
126
+ let [e, t] = s();
126
127
  return {
127
- archiveConversation: h(async (t) => {
128
+ markConversationAsRead: _(async (t) => {
129
+ try {
130
+ let { data: n, error: r } = await e({
131
+ variables: {
132
+ conversationId: t.conversationId,
133
+ messageId: t.messageId
134
+ },
135
+ update: (e, t) => {
136
+ let n = t.data?.markConversationAsRead;
137
+ n && g(e, n);
138
+ }
139
+ });
140
+ if (r) throw r;
141
+ return !!n?.markConversationAsRead;
142
+ } catch (e) {
143
+ throw e instanceof Error ? e : /* @__PURE__ */ Error("Failed to mark conversation as read");
144
+ }
145
+ }, [e]),
146
+ loading: t.loading,
147
+ error: t.error ?? null
148
+ };
149
+ }
150
+ function k() {
151
+ let [e, n] = t(), [r, i] = d(), [a, s] = l(), [u, m] = p(), [h, g] = c(), [v, y] = f(), [b, x] = o();
152
+ return {
153
+ archiveConversation: _(async (t) => {
128
154
  let { data: n } = await e({
129
155
  variables: { id: t },
130
156
  refetchQueries: ["GetConversations"],
@@ -132,7 +158,7 @@ function E() {
132
158
  });
133
159
  return n?.archiveConversation.id === t;
134
160
  }, [e]),
135
- unarchiveConversation: h(async (e) => {
161
+ unarchiveConversation: _(async (e) => {
136
162
  let { data: t } = await r({
137
163
  variables: { id: e },
138
164
  refetchQueries: ["GetConversations"],
@@ -140,23 +166,23 @@ function E() {
140
166
  });
141
167
  return t?.unarchiveConversation.id === e;
142
168
  }, [r]),
143
- pinConversation: h(async (e) => {
169
+ pinConversation: _(async (e) => {
144
170
  let { data: t } = await a({ variables: { conversationId: e } });
145
171
  return !!t?.pinConversation?.id;
146
172
  }, [a]),
147
- unpinConversation: h(async (e) => {
148
- let { data: t } = await p({ variables: { conversationId: e } });
173
+ unpinConversation: _(async (e) => {
174
+ let { data: t } = await u({ variables: { conversationId: e } });
149
175
  return !!t?.unpinConversation?.id;
150
- }, [p]),
151
- muteConversation: h(async (e) => {
152
- let { data: t } = await g({ variables: { conversationId: e } });
176
+ }, [u]),
177
+ muteConversation: _(async (e) => {
178
+ let { data: t } = await h({ variables: { conversationId: e } });
153
179
  return !!t?.muteConversation?.id;
154
- }, [g]),
155
- unmuteConversation: h(async (e) => {
180
+ }, [h]),
181
+ unmuteConversation: _(async (e) => {
156
182
  let { data: t } = await v({ variables: { conversationId: e } });
157
183
  return !!t?.unmuteConversation?.id;
158
184
  }, [v]),
159
- leaveConversation: h(async (e) => {
185
+ leaveConversation: _(async (e) => {
160
186
  let { data: t } = await b({
161
187
  variables: { conversationId: e },
162
188
  refetchQueries: ["GetConversations"],
@@ -164,17 +190,17 @@ function E() {
164
190
  });
165
191
  return t?.leaveConversation.success ?? !1;
166
192
  }, [b]),
167
- loading: n.loading || i.loading || l.loading || m.loading || _.loading || y.loading || x.loading,
168
- error: n.error ?? i.error ?? l.error ?? m.error ?? _.error ?? y.error ?? x.error ?? null
193
+ loading: n.loading || i.loading || s.loading || m.loading || g.loading || y.loading || x.loading,
194
+ error: n.error ?? i.error ?? s.error ?? m.error ?? g.error ?? y.error ?? x.error ?? null
169
195
  };
170
196
  }
171
- function D() {
172
- let [e, t] = p();
197
+ function A() {
198
+ let [e, t] = m();
173
199
  return {
174
- updateConversation: h(async (t) => {
200
+ updateConversation: _(async (t) => {
175
201
  try {
176
202
  let { data: n } = await e({ variables: { input: t } }), r = n?.updateConversation?.conversation;
177
- return r ? m(r) : null;
203
+ return r ? h(r) : null;
178
204
  } catch (e) {
179
205
  throw e instanceof Error ? e : /* @__PURE__ */ Error("Failed to update conversation");
180
206
  }
@@ -184,6 +210,6 @@ function D() {
184
210
  };
185
211
  }
186
212
  //#endregion
187
- export { E as useConversationActions, T as useCreateConversation, b as useGetConversation, y as useGetConversations, x as useSearchConversations, D as useUpdateConversation, w as useWorkspaceDirectory };
213
+ export { k as useConversationActions, D as useCreateConversation, S as useGetConversation, x as useGetConversations, O as useMarkConversationAsRead, C as useSearchConversations, A as useUpdateConversation, E as useWorkspaceDirectory };
188
214
 
189
215
  //# sourceMappingURL=useConversationQueries.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"useConversationQueries.js","names":[],"sources":["../../../src/conversations/hooks/useConversationQueries.ts"],"sourcesContent":["import { useCallback, useEffect, useMemo, useState } from \"react\";\nimport {\n type GetConversationQuery,\n type GetWorkspaceDirectoryQuery,\n useArchiveConversationMutation,\n useCreateConversationMutation,\n useGetConversationQuery,\n useGetConversationsQuery,\n useGetWorkspaceDirectoryQuery,\n useMuteConversationMutation,\n useLeaveConversationMutation,\n usePinConversationMutation,\n useSearchConversationsQuery,\n useUnarchiveConversationMutation,\n useUnmuteConversationMutation,\n useUnpinConversationMutation,\n useUpdateConversationByHookMutation,\n} from \"../../generated/wspace-operations\";\nimport type * as WspaceTypes from \"../../generated/wspace-types\";\nimport type {\n Conversation,\n ConversationState,\n ConversationType,\n ConversationVisibility,\n} from \"../types\";\nimport { useConversations } from \"../providers/ConversationsProvider\";\nimport { mapConversation } from \"../utils/mappers\";\n\ninterface UseGetConversationsOptions {\n first?: number;\n after?: string;\n types?: ConversationType[];\n /**\n * Conversation lifecycle states to include. When omitted the backend\n * returns ACTIVE conversations by default (filtering is union, not\n * exclusion, so `[\"ACTIVE\"]` and `undefined` are interchangeable for the\n * default inbox). Pass `[\"ARCHIVED\"]` to drive the archived tab.\n */\n states?: ConversationState[];\n hasUnread?: boolean;\n isPinned?: boolean;\n}\n\ninterface UseGetConversationsResult {\n conversations: Conversation[];\n loading: boolean;\n error: Error | null;\n hasNextPage: boolean;\n fetchMore: () => void;\n refetch: () => void;\n}\n\n/**\n * Hook: Fetch a paginated list of conversations.\n */\nexport function useGetConversations(\n options?: UseGetConversationsOptions,\n): UseGetConversationsResult {\n const { workspaceId } = useConversations();\n const queryResult = useGetConversationsQuery({\n variables: {\n first: options?.first ?? 25,\n after: options?.after,\n filter: {\n types: options?.types as WspaceTypes.InputMaybe<\n WspaceTypes.ConversationType[]\n >,\n states: options?.states as WspaceTypes.InputMaybe<\n WspaceTypes.ConversationState[]\n >,\n hasUnread: options?.hasUnread,\n isPinned: options?.isPinned,\n },\n },\n skip: !workspaceId,\n });\n\n const conversations = useMemo(\n () =>\n queryResult.data?.conversations.edges.map(\n (edge: { node: Record<string, unknown> }) => mapConversation(edge.node),\n ) ?? [],\n [queryResult.data],\n );\n\n const hasNextPage =\n queryResult.data?.conversations.pageInfo.hasNextPage ?? false;\n\n return {\n conversations,\n loading: queryResult.loading,\n error: queryResult.error ?? null,\n hasNextPage,\n fetchMore: () => {\n const endCursor = queryResult.data?.conversations.pageInfo.endCursor;\n if (!endCursor || !hasNextPage) return;\n void queryResult.fetchMore({\n variables: {\n first: options?.first ?? 25,\n after: endCursor,\n filter: {\n types: options?.types as WspaceTypes.InputMaybe<\n WspaceTypes.ConversationType[]\n >,\n states: options?.states as WspaceTypes.InputMaybe<\n WspaceTypes.ConversationState[]\n >,\n hasUnread: options?.hasUnread,\n isPinned: options?.isPinned,\n },\n },\n });\n },\n refetch: () => {\n void queryResult.refetch();\n },\n };\n}\n\ninterface UseGetConversationResult {\n conversation: Conversation | null;\n members: ConversationMember[];\n membersTotalCount: number;\n loading: boolean;\n error: Error | null;\n refetch: () => void;\n}\n\nexport type ConversationMember = NonNullable<\n GetConversationQuery[\"conversation\"]\n>[\"members\"][\"edges\"][number][\"node\"];\ntype ConversationMemberEdge = NonNullable<\n GetConversationQuery[\"conversation\"]\n>[\"members\"][\"edges\"][number];\n\n/**\n * Hook: Fetch a single conversation by ID.\n */\nexport function useGetConversation(\n conversationId: string,\n): UseGetConversationResult {\n const { workspaceId } = useConversations();\n const queryResult = useGetConversationQuery({\n variables: { id: conversationId },\n skip: !workspaceId || !conversationId,\n });\n\n return {\n conversation: queryResult.data?.conversation\n ? mapConversation(queryResult.data.conversation)\n : null,\n members:\n queryResult.data?.conversation?.members.edges\n .map((edge: ConversationMemberEdge) => edge.node)\n .filter(\n (member: ConversationMember | null): member is ConversationMember =>\n Boolean(member),\n ) ?? [],\n membersTotalCount: queryResult.data?.conversation?.members.totalCount ?? 0,\n loading: queryResult.loading,\n error: queryResult.error ?? null,\n refetch: () => {\n void queryResult.refetch();\n },\n };\n}\n\ninterface UseSearchConversationsResult {\n conversations: Conversation[];\n loading: boolean;\n error: Error | null;\n}\n\n/**\n * Hook: Search conversations by query string.\n */\nexport function useSearchConversations(\n query: string,\n): UseSearchConversationsResult {\n const { workspaceId } = useConversations();\n const trimmedQuery = query.trim();\n const queryResult = useSearchConversationsQuery({\n variables: { query: trimmedQuery, first: 25 },\n skip: !workspaceId || trimmedQuery.length < 2,\n });\n\n return {\n conversations:\n queryResult.data?.searchConversations.edges.map(\n (edge: { node: Record<string, unknown> }) => mapConversation(edge.node),\n ) ?? [],\n loading: queryResult.loading,\n error: queryResult.error ?? null,\n };\n}\n\n/**\n * A workspace member surfaced by the directory, resolved to a friendly\n * identity. `id` is the member's user id (used for `participantIds`).\n */\nexport type WorkspaceDirectoryMember =\n GetWorkspaceDirectoryQuery[\"workspaceDirectory\"][\"edges\"][number];\n\ninterface UseWorkspaceDirectoryResult {\n members: WorkspaceDirectoryMember[];\n totalCount: number;\n loading: boolean;\n error: Error | null;\n}\n\nconst DIRECTORY_PAGE_SIZE = 25;\nconst DIRECTORY_SEARCH_DEBOUNCE_MS = 250;\n\n/**\n * Hook: Search the current workspace's member directory (server-side,\n * debounced). Backed by the conversations `workspaceDirectory` query, which is\n * a thin, identity-resolved wrapper over wspace-workspace-svc. An empty search\n * lists the first page of members so the picker shows suggestions before the\n * user types.\n */\nexport function useWorkspaceDirectory(\n search: string,\n): UseWorkspaceDirectoryResult {\n const { workspaceId } = useConversations();\n const [debouncedSearch, setDebouncedSearch] = useState(search.trim());\n\n useEffect(() => {\n const trimmed = search.trim();\n const handle = setTimeout(() => {\n setDebouncedSearch(trimmed);\n }, DIRECTORY_SEARCH_DEBOUNCE_MS);\n return () => clearTimeout(handle);\n }, [search]);\n\n const queryResult = useGetWorkspaceDirectoryQuery({\n variables: {\n filter: debouncedSearch ? { search: debouncedSearch } : undefined,\n pagination: { limit: DIRECTORY_PAGE_SIZE, offset: 0 },\n },\n skip: !workspaceId,\n fetchPolicy: \"cache-and-network\",\n });\n\n const members = useMemo(\n () => queryResult.data?.workspaceDirectory.edges ?? [],\n [queryResult.data],\n );\n\n return {\n members,\n totalCount: queryResult.data?.workspaceDirectory.totalCount ?? 0,\n loading: queryResult.loading,\n error: queryResult.error ?? null,\n };\n}\n\ninterface CreateConversationInput {\n type: ConversationType;\n title?: string;\n description?: string;\n participantIds: string[];\n visibility?: ConversationVisibility;\n}\n\ninterface UseCreateConversationResult {\n createConversation: (\n input: CreateConversationInput,\n ) => Promise<Conversation | null>;\n loading: boolean;\n error: Error | null;\n}\n\n/**\n * Hook: Create a new conversation.\n */\nexport function useCreateConversation(): UseCreateConversationResult {\n const { workspaceId } = useConversations();\n const [createConversationMutation, mutationState] =\n useCreateConversationMutation();\n\n const createConversation = useCallback(\n async (input: CreateConversationInput): Promise<Conversation | null> => {\n if (!workspaceId) {\n throw new Error(\n \"Workspace context is required to create a conversation\",\n );\n }\n\n try {\n const { data, error } = await createConversationMutation({\n variables: {\n input: {\n workspaceId,\n type: input.type as WspaceTypes.ConversationType,\n title: input.title,\n description: input.description,\n participantIds: input.participantIds,\n },\n },\n });\n if (error) throw error;\n\n const conversation = data?.createConversation.conversation;\n return conversation ? mapConversation(conversation) : null;\n } catch (err) {\n throw err instanceof Error\n ? err\n : new Error(\"Failed to create conversation\");\n }\n },\n [createConversationMutation, workspaceId],\n );\n\n return {\n createConversation,\n loading: mutationState.loading,\n error: mutationState.error ?? null,\n };\n}\n\ninterface UseUpdateConversationResult {\n archiveConversation: (id: string) => Promise<boolean>;\n unarchiveConversation: (id: string) => Promise<boolean>;\n pinConversation: (id: string) => Promise<boolean>;\n unpinConversation: (id: string) => Promise<boolean>;\n muteConversation: (id: string) => Promise<boolean>;\n unmuteConversation: (id: string) => Promise<boolean>;\n leaveConversation: (id: string) => Promise<boolean>;\n loading: boolean;\n error: Error | null;\n}\n\n/**\n * Hook: Conversation mutation operations.\n */\nexport function useConversationActions(): UseUpdateConversationResult {\n const [archiveConversationMutation, archiveState] =\n useArchiveConversationMutation();\n const [unarchiveConversationMutation, unarchiveState] =\n useUnarchiveConversationMutation();\n const [pinConversationMutation, pinState] = usePinConversationMutation();\n const [unpinConversationMutation, unpinState] =\n useUnpinConversationMutation();\n const [muteConversationMutation, muteState] = useMuteConversationMutation();\n const [unmuteConversationMutation, unmuteState] =\n useUnmuteConversationMutation();\n const [leaveConversationMutation, leaveState] =\n useLeaveConversationMutation();\n\n const archiveConversation = useCallback(\n async (id: string): Promise<boolean> => {\n // refetch GetConversations so the row drops out of the inbox (and the\n // Archived tab gains it) without waiting for a manual refresh.\n const { data } = await archiveConversationMutation({\n variables: { id },\n refetchQueries: [\"GetConversations\"],\n awaitRefetchQueries: true,\n });\n return data?.archiveConversation.id === id;\n },\n [archiveConversationMutation],\n );\n\n const unarchiveConversation = useCallback(\n async (id: string): Promise<boolean> => {\n const { data } = await unarchiveConversationMutation({\n variables: { id },\n refetchQueries: [\"GetConversations\"],\n awaitRefetchQueries: true,\n });\n return data?.unarchiveConversation.id === id;\n },\n [unarchiveConversationMutation],\n );\n\n const pinConversation = useCallback(\n async (id: string): Promise<boolean> => {\n const { data } = await pinConversationMutation({\n variables: { conversationId: id },\n });\n return Boolean(data?.pinConversation?.id);\n },\n [pinConversationMutation],\n );\n\n const unpinConversation = useCallback(\n async (id: string): Promise<boolean> => {\n const { data } = await unpinConversationMutation({\n variables: { conversationId: id },\n });\n return Boolean(data?.unpinConversation?.id);\n },\n [unpinConversationMutation],\n );\n\n const muteConversation = useCallback(\n async (id: string): Promise<boolean> => {\n const { data } = await muteConversationMutation({\n variables: { conversationId: id },\n });\n return Boolean(data?.muteConversation?.id);\n },\n [muteConversationMutation],\n );\n\n const unmuteConversation = useCallback(\n async (id: string): Promise<boolean> => {\n const { data } = await unmuteConversationMutation({\n variables: { conversationId: id },\n });\n return Boolean(data?.unmuteConversation?.id);\n },\n [unmuteConversationMutation],\n );\n\n const leaveConversation = useCallback(\n async (id: string): Promise<boolean> => {\n const { data } = await leaveConversationMutation({\n variables: { conversationId: id },\n refetchQueries: [\"GetConversations\"],\n awaitRefetchQueries: true,\n });\n return data?.leaveConversation.success ?? false;\n },\n [leaveConversationMutation],\n );\n\n return {\n archiveConversation,\n unarchiveConversation,\n pinConversation,\n unpinConversation,\n muteConversation,\n unmuteConversation,\n leaveConversation,\n loading:\n archiveState.loading ||\n unarchiveState.loading ||\n pinState.loading ||\n unpinState.loading ||\n muteState.loading ||\n unmuteState.loading ||\n leaveState.loading,\n error:\n (archiveState.error as Error | undefined) ??\n (unarchiveState.error as Error | undefined) ??\n (pinState.error as Error | undefined) ??\n (unpinState.error as Error | undefined) ??\n (muteState.error as Error | undefined) ??\n (unmuteState.error as Error | undefined) ??\n (leaveState.error as Error | undefined) ??\n null,\n };\n}\n\ninterface UseUpdateConversationOptions {\n updateConversation: (input: {\n id: string;\n title?: string;\n description?: string;\n avatarUrl?: string;\n settings?: Record<string, unknown>;\n }) => Promise<Conversation | null>;\n loading: boolean;\n error: Error | null;\n}\n\nexport function useUpdateConversation(): UseUpdateConversationOptions {\n const [updateConversationMutation, mutationState] =\n useUpdateConversationByHookMutation();\n\n const updateConversation = useCallback(\n async (input: {\n id: string;\n title?: string;\n description?: string;\n avatarUrl?: string;\n settings?: Record<string, unknown>;\n }): Promise<Conversation | null> => {\n try {\n const { data } = await updateConversationMutation({\n variables: { input },\n });\n const typedData = data as\n | {\n updateConversation?: {\n conversation?: Record<string, unknown> | null;\n };\n }\n | undefined;\n const conversation = typedData?.updateConversation?.conversation;\n return conversation\n ? mapConversation(conversation as Record<string, unknown>)\n : null;\n } catch (err) {\n throw err instanceof Error\n ? err\n : new Error(\"Failed to update conversation\");\n }\n },\n [updateConversationMutation],\n );\n\n return {\n updateConversation,\n loading: mutationState.loading,\n error: mutationState.error ?? null,\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"useConversationQueries.js","names":[],"sources":["../../../src/conversations/hooks/useConversationQueries.ts"],"sourcesContent":["import { useCallback, useEffect, useMemo, useState } from \"react\";\nimport { type ApolloCache, type FetchResult } from \"@apollo/client\";\nimport {\n type GetConversationQuery,\n type GetWorkspaceDirectoryQuery,\n type MarkConversationAsReadMutation,\n useArchiveConversationMutation,\n useCreateConversationMutation,\n useGetConversationQuery,\n useGetConversationsQuery,\n useGetWorkspaceDirectoryQuery,\n useMarkConversationAsReadMutation,\n useMuteConversationMutation,\n useLeaveConversationMutation,\n usePinConversationMutation,\n useSearchConversationsQuery,\n useUnarchiveConversationMutation,\n useUnmuteConversationMutation,\n useUnpinConversationMutation,\n useUpdateConversationByHookMutation,\n} from \"../../generated/wspace-operations\";\nimport type * as WspaceTypes from \"../../generated/wspace-types\";\nimport type {\n Conversation,\n ConversationState,\n ConversationType,\n ConversationVisibility,\n} from \"../types\";\nimport { useConversations } from \"../providers/ConversationsProvider\";\nimport { mapConversation } from \"../utils/mappers\";\nimport { applyMarkConversationAsReadToCache } from \"../utils/readReceiptCache\";\n\ninterface UseGetConversationsOptions {\n first?: number;\n after?: string;\n types?: ConversationType[];\n /**\n * Conversation lifecycle states to include. When omitted the backend\n * returns ACTIVE conversations by default (filtering is union, not\n * exclusion, so `[\"ACTIVE\"]` and `undefined` are interchangeable for the\n * default inbox). Pass `[\"ARCHIVED\"]` to drive the archived tab.\n */\n states?: ConversationState[];\n hasUnread?: boolean;\n isPinned?: boolean;\n}\n\ninterface UseGetConversationsResult {\n conversations: Conversation[];\n loading: boolean;\n error: Error | null;\n hasNextPage: boolean;\n fetchMore: () => void;\n refetch: () => void;\n}\n\n/**\n * Hook: Fetch a paginated list of conversations.\n */\nexport function useGetConversations(\n options?: UseGetConversationsOptions,\n): UseGetConversationsResult {\n const { workspaceId } = useConversations();\n const queryResult = useGetConversationsQuery({\n variables: {\n first: options?.first ?? 25,\n after: options?.after,\n filter: {\n types: options?.types as WspaceTypes.InputMaybe<\n WspaceTypes.ConversationType[]\n >,\n states: options?.states as WspaceTypes.InputMaybe<\n WspaceTypes.ConversationState[]\n >,\n hasUnread: options?.hasUnread,\n isPinned: options?.isPinned,\n },\n },\n skip: !workspaceId,\n });\n\n const conversations = useMemo(\n () =>\n queryResult.data?.conversations.edges.map(\n (edge: { node: Record<string, unknown> }) => mapConversation(edge.node),\n ) ?? [],\n [queryResult.data],\n );\n\n const hasNextPage =\n queryResult.data?.conversations.pageInfo.hasNextPage ?? false;\n\n return {\n conversations,\n loading: queryResult.loading,\n error: queryResult.error ?? null,\n hasNextPage,\n fetchMore: () => {\n const endCursor = queryResult.data?.conversations.pageInfo.endCursor;\n if (!endCursor || !hasNextPage) return;\n void queryResult.fetchMore({\n variables: {\n first: options?.first ?? 25,\n after: endCursor,\n filter: {\n types: options?.types as WspaceTypes.InputMaybe<\n WspaceTypes.ConversationType[]\n >,\n states: options?.states as WspaceTypes.InputMaybe<\n WspaceTypes.ConversationState[]\n >,\n hasUnread: options?.hasUnread,\n isPinned: options?.isPinned,\n },\n },\n });\n },\n refetch: () => {\n void queryResult.refetch();\n },\n };\n}\n\ninterface UseGetConversationResult {\n conversation: Conversation | null;\n members: ConversationMember[];\n membersTotalCount: number;\n loading: boolean;\n error: Error | null;\n refetch: () => void;\n}\n\nexport type ConversationMember = NonNullable<\n GetConversationQuery[\"conversation\"]\n>[\"members\"][\"edges\"][number][\"node\"];\ntype ConversationMemberEdge = NonNullable<\n GetConversationQuery[\"conversation\"]\n>[\"members\"][\"edges\"][number];\n\n/**\n * Hook: Fetch a single conversation by ID.\n */\nexport function useGetConversation(\n conversationId: string,\n): UseGetConversationResult {\n const { workspaceId } = useConversations();\n const queryResult = useGetConversationQuery({\n variables: { id: conversationId },\n skip: !workspaceId || !conversationId,\n });\n\n return {\n conversation: queryResult.data?.conversation\n ? mapConversation(queryResult.data.conversation)\n : null,\n members:\n queryResult.data?.conversation?.members.edges\n .map((edge: ConversationMemberEdge) => edge.node)\n .filter(\n (member: ConversationMember | null): member is ConversationMember =>\n Boolean(member),\n ) ?? [],\n membersTotalCount: queryResult.data?.conversation?.members.totalCount ?? 0,\n loading: queryResult.loading,\n error: queryResult.error ?? null,\n refetch: () => {\n void queryResult.refetch();\n },\n };\n}\n\ninterface UseSearchConversationsResult {\n conversations: Conversation[];\n loading: boolean;\n error: Error | null;\n}\n\n/**\n * Hook: Search conversations by query string.\n */\nexport function useSearchConversations(\n query: string,\n): UseSearchConversationsResult {\n const { workspaceId } = useConversations();\n const trimmedQuery = query.trim();\n const queryResult = useSearchConversationsQuery({\n variables: { query: trimmedQuery, first: 25 },\n skip: !workspaceId || trimmedQuery.length < 2,\n });\n\n return {\n conversations:\n queryResult.data?.searchConversations.edges.map(\n (edge: { node: Record<string, unknown> }) => mapConversation(edge.node),\n ) ?? [],\n loading: queryResult.loading,\n error: queryResult.error ?? null,\n };\n}\n\n/**\n * A workspace member surfaced by the directory, resolved to a friendly\n * identity. `id` is the member's user id (used for `participantIds`).\n */\nexport type WorkspaceDirectoryMember =\n GetWorkspaceDirectoryQuery[\"workspaceDirectory\"][\"edges\"][number];\n\ninterface UseWorkspaceDirectoryResult {\n members: WorkspaceDirectoryMember[];\n totalCount: number;\n loading: boolean;\n error: Error | null;\n}\n\nconst DIRECTORY_PAGE_SIZE = 25;\nconst DIRECTORY_SEARCH_DEBOUNCE_MS = 250;\n\n/**\n * Hook: Search the current workspace's member directory (server-side,\n * debounced). Backed by the conversations `workspaceDirectory` query, which is\n * a thin, identity-resolved wrapper over wspace-workspace-svc. An empty search\n * lists the first page of members so the picker shows suggestions before the\n * user types.\n */\nexport function useWorkspaceDirectory(\n search: string,\n): UseWorkspaceDirectoryResult {\n const { workspaceId } = useConversations();\n const [debouncedSearch, setDebouncedSearch] = useState(search.trim());\n\n useEffect(() => {\n const trimmed = search.trim();\n const handle = setTimeout(() => {\n setDebouncedSearch(trimmed);\n }, DIRECTORY_SEARCH_DEBOUNCE_MS);\n return () => clearTimeout(handle);\n }, [search]);\n\n const queryResult = useGetWorkspaceDirectoryQuery({\n variables: {\n filter: debouncedSearch ? { search: debouncedSearch } : undefined,\n pagination: { limit: DIRECTORY_PAGE_SIZE, offset: 0 },\n },\n skip: !workspaceId,\n fetchPolicy: \"cache-and-network\",\n });\n\n const members = useMemo(\n () => queryResult.data?.workspaceDirectory.edges ?? [],\n [queryResult.data],\n );\n\n return {\n members,\n totalCount: queryResult.data?.workspaceDirectory.totalCount ?? 0,\n loading: queryResult.loading,\n error: queryResult.error ?? null,\n };\n}\n\ninterface CreateConversationInput {\n type: ConversationType;\n title?: string;\n description?: string;\n participantIds: string[];\n visibility?: ConversationVisibility;\n}\n\ninterface UseCreateConversationResult {\n createConversation: (\n input: CreateConversationInput,\n ) => Promise<Conversation | null>;\n loading: boolean;\n error: Error | null;\n}\n\n/**\n * Hook: Create a new conversation.\n */\nexport function useCreateConversation(): UseCreateConversationResult {\n const { workspaceId } = useConversations();\n const [createConversationMutation, mutationState] =\n useCreateConversationMutation();\n\n const createConversation = useCallback(\n async (input: CreateConversationInput): Promise<Conversation | null> => {\n if (!workspaceId) {\n throw new Error(\n \"Workspace context is required to create a conversation\",\n );\n }\n\n try {\n const { data, error } = await createConversationMutation({\n variables: {\n input: {\n workspaceId,\n type: input.type as WspaceTypes.ConversationType,\n title: input.title,\n description: input.description,\n participantIds: input.participantIds,\n },\n },\n });\n if (error) throw error;\n\n const conversation = data?.createConversation.conversation;\n return conversation ? mapConversation(conversation) : null;\n } catch (err) {\n throw err instanceof Error\n ? err\n : new Error(\"Failed to create conversation\");\n }\n },\n [createConversationMutation, workspaceId],\n );\n\n return {\n createConversation,\n loading: mutationState.loading,\n error: mutationState.error ?? null,\n };\n}\n\ninterface UseMarkConversationAsReadResult {\n markConversationAsRead: (input: {\n conversationId: string;\n messageId?: string;\n }) => Promise<boolean>;\n loading: boolean;\n error: Error | null;\n}\n\n/**\n * Hook: Mark a conversation as read for the current viewer.\n *\n * Pass the newest message the viewer has seen as `messageId`; when omitted\n * the backend marks the whole conversation read. On success the cache update\n * zeroes the viewer-scoped `unreadCount`/`mentionCount` fields on the cached\n * Conversation entity — the list badge reads those top-level fields, which\n * membership normalization alone would leave stale — and drops the\n * conversation from any cached `hasUnread: true` list (see\n * `applyMarkConversationAsReadToCache`).\n */\nexport function useMarkConversationAsRead(): UseMarkConversationAsReadResult {\n const [markConversationAsReadMutation, mutationState] =\n useMarkConversationAsReadMutation();\n\n const markConversationAsRead = useCallback(\n async (input: {\n conversationId: string;\n messageId?: string;\n }): Promise<boolean> => {\n try {\n const { data, error } = await markConversationAsReadMutation({\n variables: {\n conversationId: input.conversationId,\n messageId: input.messageId,\n },\n update: (\n cache: ApolloCache,\n result: FetchResult<MarkConversationAsReadMutation>,\n ) => {\n const membership = result.data?.markConversationAsRead;\n if (!membership) return;\n applyMarkConversationAsReadToCache(cache, membership);\n },\n });\n if (error) throw error;\n return Boolean(data?.markConversationAsRead);\n } catch (err) {\n throw err instanceof Error\n ? err\n : new Error(\"Failed to mark conversation as read\");\n }\n },\n [markConversationAsReadMutation],\n );\n\n return {\n markConversationAsRead,\n loading: mutationState.loading,\n error: mutationState.error ?? null,\n };\n}\n\ninterface UseUpdateConversationResult {\n archiveConversation: (id: string) => Promise<boolean>;\n unarchiveConversation: (id: string) => Promise<boolean>;\n pinConversation: (id: string) => Promise<boolean>;\n unpinConversation: (id: string) => Promise<boolean>;\n muteConversation: (id: string) => Promise<boolean>;\n unmuteConversation: (id: string) => Promise<boolean>;\n leaveConversation: (id: string) => Promise<boolean>;\n loading: boolean;\n error: Error | null;\n}\n\n/**\n * Hook: Conversation mutation operations.\n */\nexport function useConversationActions(): UseUpdateConversationResult {\n const [archiveConversationMutation, archiveState] =\n useArchiveConversationMutation();\n const [unarchiveConversationMutation, unarchiveState] =\n useUnarchiveConversationMutation();\n const [pinConversationMutation, pinState] = usePinConversationMutation();\n const [unpinConversationMutation, unpinState] =\n useUnpinConversationMutation();\n const [muteConversationMutation, muteState] = useMuteConversationMutation();\n const [unmuteConversationMutation, unmuteState] =\n useUnmuteConversationMutation();\n const [leaveConversationMutation, leaveState] =\n useLeaveConversationMutation();\n\n const archiveConversation = useCallback(\n async (id: string): Promise<boolean> => {\n // refetch GetConversations so the row drops out of the inbox (and the\n // Archived tab gains it) without waiting for a manual refresh.\n const { data } = await archiveConversationMutation({\n variables: { id },\n refetchQueries: [\"GetConversations\"],\n awaitRefetchQueries: true,\n });\n return data?.archiveConversation.id === id;\n },\n [archiveConversationMutation],\n );\n\n const unarchiveConversation = useCallback(\n async (id: string): Promise<boolean> => {\n const { data } = await unarchiveConversationMutation({\n variables: { id },\n refetchQueries: [\"GetConversations\"],\n awaitRefetchQueries: true,\n });\n return data?.unarchiveConversation.id === id;\n },\n [unarchiveConversationMutation],\n );\n\n const pinConversation = useCallback(\n async (id: string): Promise<boolean> => {\n const { data } = await pinConversationMutation({\n variables: { conversationId: id },\n });\n return Boolean(data?.pinConversation?.id);\n },\n [pinConversationMutation],\n );\n\n const unpinConversation = useCallback(\n async (id: string): Promise<boolean> => {\n const { data } = await unpinConversationMutation({\n variables: { conversationId: id },\n });\n return Boolean(data?.unpinConversation?.id);\n },\n [unpinConversationMutation],\n );\n\n const muteConversation = useCallback(\n async (id: string): Promise<boolean> => {\n const { data } = await muteConversationMutation({\n variables: { conversationId: id },\n });\n return Boolean(data?.muteConversation?.id);\n },\n [muteConversationMutation],\n );\n\n const unmuteConversation = useCallback(\n async (id: string): Promise<boolean> => {\n const { data } = await unmuteConversationMutation({\n variables: { conversationId: id },\n });\n return Boolean(data?.unmuteConversation?.id);\n },\n [unmuteConversationMutation],\n );\n\n const leaveConversation = useCallback(\n async (id: string): Promise<boolean> => {\n const { data } = await leaveConversationMutation({\n variables: { conversationId: id },\n refetchQueries: [\"GetConversations\"],\n awaitRefetchQueries: true,\n });\n return data?.leaveConversation.success ?? false;\n },\n [leaveConversationMutation],\n );\n\n return {\n archiveConversation,\n unarchiveConversation,\n pinConversation,\n unpinConversation,\n muteConversation,\n unmuteConversation,\n leaveConversation,\n loading:\n archiveState.loading ||\n unarchiveState.loading ||\n pinState.loading ||\n unpinState.loading ||\n muteState.loading ||\n unmuteState.loading ||\n leaveState.loading,\n error:\n (archiveState.error as Error | undefined) ??\n (unarchiveState.error as Error | undefined) ??\n (pinState.error as Error | undefined) ??\n (unpinState.error as Error | undefined) ??\n (muteState.error as Error | undefined) ??\n (unmuteState.error as Error | undefined) ??\n (leaveState.error as Error | undefined) ??\n null,\n };\n}\n\ninterface UseUpdateConversationOptions {\n updateConversation: (input: {\n id: string;\n title?: string;\n description?: string;\n avatarUrl?: string;\n settings?: Record<string, unknown>;\n }) => Promise<Conversation | null>;\n loading: boolean;\n error: Error | null;\n}\n\nexport function useUpdateConversation(): UseUpdateConversationOptions {\n const [updateConversationMutation, mutationState] =\n useUpdateConversationByHookMutation();\n\n const updateConversation = useCallback(\n async (input: {\n id: string;\n title?: string;\n description?: string;\n avatarUrl?: string;\n settings?: Record<string, unknown>;\n }): Promise<Conversation | null> => {\n try {\n const { data } = await updateConversationMutation({\n variables: { input },\n });\n const typedData = data as\n | {\n updateConversation?: {\n conversation?: Record<string, unknown> | null;\n };\n }\n | undefined;\n const conversation = typedData?.updateConversation?.conversation;\n return conversation\n ? mapConversation(conversation as Record<string, unknown>)\n : null;\n } catch (err) {\n throw err instanceof Error\n ? err\n : new Error(\"Failed to update conversation\");\n }\n },\n [updateConversationMutation],\n );\n\n return {\n updateConversation,\n loading: mutationState.loading,\n error: mutationState.error ?? null,\n };\n}\n"],"mappings":"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"}