@messenger-box/platform-client 10.0.3-alpha.165 → 10.0.3-alpha.171
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/lib/graphql/mutations/messages-mutation.gql +0 -26
- package/package.json +3 -3
- package/CHANGELOG.md +0 -373
- package/jest.config.js +0 -25
- package/lib/graphql/subscription/sandboxError.gql +0 -17
- package/rollup.config.mjs +0 -36
- package/src/graphql/fragments/configuration.gql +0 -12
- package/src/graphql/fragments/extended-user-account.gql +0 -10
- package/src/graphql/fragments/file-info.gql +0 -12
- package/src/graphql/fragments/messenger-user.gql +0 -15
- package/src/graphql/fragments/minimal-user.gql +0 -9
- package/src/graphql/fragments/post-message.gql +0 -152
- package/src/graphql/fragments/post-thread-message.gql +0 -77
- package/src/graphql/fragments/user.gql +0 -11
- package/src/graphql/id-generation.ts +0 -8
- package/src/graphql/index.ts +0 -24
- package/src/graphql/mutations/channel-mutation.gql +0 -77
- package/src/graphql/mutations/expo-notification-token.gql +0 -13
- package/src/graphql/mutations/message-threads-mutation.gql +0 -44
- package/src/graphql/mutations/messages-mutation.gql +0 -113
- package/src/graphql/mutations/messages-mutation.gql.bk +0 -66
- package/src/graphql/mutations/organization-mutation.gql.bk +0 -14
- package/src/graphql/mutations/teams-mutation.gql.bk +0 -8
- package/src/graphql/policies/channel-policies.ts +0 -153
- package/src/graphql/policies/index.ts +0 -7
- package/src/graphql/policies/messages-policies.ts +0 -321
- package/src/graphql/policies/post-thread-policies.ts +0 -179
- package/src/graphql/policies/posts-policies.ts +0 -110
- package/src/graphql/policies/teams-policies.ts +0 -19
- package/src/graphql/policies/user-account-policies.ts +0 -15
- package/src/graphql/policies/user-policies.ts +0 -32
- package/src/graphql/queries/channel.gql +0 -57
- package/src/graphql/queries/channels-by-user.gql +0 -86
- package/src/graphql/queries/check-for-new-messages.gql +0 -5
- package/src/graphql/queries/file-url.gql +0 -5
- package/src/graphql/queries/get-device-token.gql +0 -8
- package/src/graphql/queries/messages.gql +0 -28
- package/src/graphql/queries/organization-query.gql +0 -125
- package/src/graphql/queries/post-message.gql +0 -8
- package/src/graphql/queries/post-thread-message.gql +0 -24
- package/src/graphql/queries/support-service-channels.gql +0 -18
- package/src/graphql/queries/teams-query.gql +0 -32
- package/src/graphql/queries/user-account.gql +0 -5
- package/src/graphql/queries/users.gql +0 -48
- package/src/graphql/schema/index.ts +0 -6
- package/src/graphql/schema/messages.graphql +0 -5
- package/src/graphql/schema/post.graphql +0 -44
- package/src/graphql/schema/services.graphql +0 -6
- package/src/graphql/schema/user-account.graphql +0 -3
- package/src/graphql/subscription/chat-message-added.gql +0 -6
- package/src/graphql/subscription/fileUpdated.gql +0 -11
- package/src/graphql/subscription/public-post-added.gql +0 -5
- package/src/graphql/subscription/thread-chat-message-added.gql +0 -5
- package/src/graphql/subscription/thread-created-updated.gql +0 -12
- package/src/hooks/index.ts +0 -4
- package/src/hooks/use-base-file-upload.hook.ts +0 -148
- package/src/hooks/use-upload-file.hook.native.ts +0 -22
- package/src/hooks/use-upload-file.hook.ts +0 -22
- package/src/hooks/use-upload-files.hook.native.ts +0 -22
- package/src/hooks/use-upload-files.hook.ts +0 -22
- package/src/index.ts +0 -3
- package/src/inversify-containers/index.ts +0 -1
- package/src/inversify-containers/module.ts +0 -4
- package/src/packages/constants/constants.ts +0 -1831
- package/src/packages/types/channels.ts +0 -194
- package/src/packages/types/emojis.ts +0 -41
- package/src/packages/types/files.ts +0 -43
- package/src/packages/types/posts.ts +0 -155
- package/src/packages/types/reactions.ts +0 -8
- package/src/packages/types/teams.ts +0 -109
- package/src/packages/types/utilities.ts +0 -30
- package/src/services/index.ts +0 -0
- package/src/tests/mutation/__snapshots__/set-device-token.test.ts.snap +0 -18
- package/src/tests/mutation/set-device-token.test.ts +0 -85
- package/src/utils/constants.tsx +0 -1120
- package/src/utils/i18n.tsx +0 -15
- package/src/utils/index.ts +0 -34
- package/src/utils/post_list.ts +0 -54
- package/src/utils/post_utils.ts +0 -33
- package/src/utils/user_agent.tsx +0 -153
- package/src/utils/utils.tsx +0 -54
- package/tsconfig.json +0 -14
- package/webpack.config.js +0 -58
|
@@ -1,153 +0,0 @@
|
|
|
1
|
-
import { TypePolicies, gql } from '@apollo/client';
|
|
2
|
-
|
|
3
|
-
export const channelPolicies: TypePolicies = {
|
|
4
|
-
Query: {
|
|
5
|
-
fields: {
|
|
6
|
-
channelsByUser: {
|
|
7
|
-
keyArgs: ['role', 'criteria', 'limit', 'skip', 'sort'],
|
|
8
|
-
merge(existing = [], incoming = [], { readField }) {
|
|
9
|
-
// If no existing data, just return incoming
|
|
10
|
-
if (!existing || existing.length === 0) {
|
|
11
|
-
return incoming;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
// If no incoming data, keep existing
|
|
15
|
-
if (!incoming || incoming.length === 0) {
|
|
16
|
-
return existing;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
// Create a map for efficient lookup
|
|
20
|
-
const channelMap = new Map();
|
|
21
|
-
|
|
22
|
-
// Add existing channels to map
|
|
23
|
-
for (let i = 0; i < existing.length; i++) {
|
|
24
|
-
const channel = existing[i];
|
|
25
|
-
if (channel) {
|
|
26
|
-
const id = readField('id', channel);
|
|
27
|
-
if (id) {
|
|
28
|
-
channelMap.set(id, channel);
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
// Merge in incoming channels, overwriting existing ones
|
|
34
|
-
for (let i = 0; i < incoming.length; i++) {
|
|
35
|
-
const channel = incoming[i];
|
|
36
|
-
if (channel) {
|
|
37
|
-
const id = readField('id', channel);
|
|
38
|
-
if (id) {
|
|
39
|
-
channelMap.set(id, channel);
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
// Convert map values back to array
|
|
45
|
-
return Array.from(channelMap.values());
|
|
46
|
-
},
|
|
47
|
-
// Add a read function for more control over cache reads
|
|
48
|
-
read(existing, { args }) {
|
|
49
|
-
// Return undefined to force a network request if data doesn't exist
|
|
50
|
-
if (!existing) return undefined;
|
|
51
|
-
return existing;
|
|
52
|
-
},
|
|
53
|
-
},
|
|
54
|
-
},
|
|
55
|
-
},
|
|
56
|
-
Channel: {
|
|
57
|
-
keyFields: ['id'],
|
|
58
|
-
fields: {
|
|
59
|
-
members: {
|
|
60
|
-
merge(existing = [], incoming) {
|
|
61
|
-
return incoming;
|
|
62
|
-
},
|
|
63
|
-
},
|
|
64
|
-
// Add field policies for other Channel fields if needed
|
|
65
|
-
title: {
|
|
66
|
-
read(title) {
|
|
67
|
-
return title || '';
|
|
68
|
-
},
|
|
69
|
-
},
|
|
70
|
-
displayName: {
|
|
71
|
-
read(displayName) {
|
|
72
|
-
return displayName || '';
|
|
73
|
-
},
|
|
74
|
-
},
|
|
75
|
-
// Add computed fields if needed
|
|
76
|
-
memberCount: {
|
|
77
|
-
read(_, { readField }) {
|
|
78
|
-
const members = readField('members') as any[];
|
|
79
|
-
return members && Array.isArray(members) ? members.length : 0;
|
|
80
|
-
},
|
|
81
|
-
},
|
|
82
|
-
lastMessage: {
|
|
83
|
-
merge(existing, incoming, { readField }) {
|
|
84
|
-
// If no incoming message, keep existing
|
|
85
|
-
if (!incoming) return existing;
|
|
86
|
-
|
|
87
|
-
// If no existing message, use incoming
|
|
88
|
-
if (!existing) return incoming;
|
|
89
|
-
|
|
90
|
-
// Compare timestamps to determine which is newer
|
|
91
|
-
const existingCreatedAt = readField('createdAt', existing) as string | number | Date;
|
|
92
|
-
const incomingCreatedAt = readField('createdAt', incoming) as string | number | Date;
|
|
93
|
-
|
|
94
|
-
if (existingCreatedAt && incomingCreatedAt) {
|
|
95
|
-
// Use the more recent message
|
|
96
|
-
return new Date(incomingCreatedAt) > new Date(existingCreatedAt) ? incoming : existing;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
// If timestamps are not available, prefer incoming
|
|
100
|
-
return incoming;
|
|
101
|
-
},
|
|
102
|
-
read(lastMessage, { readField, cache, args }) {
|
|
103
|
-
// If lastMessage is already available, return it
|
|
104
|
-
if (lastMessage) return lastMessage;
|
|
105
|
-
|
|
106
|
-
// Try to get the channel ID to reference messages cache
|
|
107
|
-
const channelId = readField('id');
|
|
108
|
-
if (!channelId) return null;
|
|
109
|
-
|
|
110
|
-
try {
|
|
111
|
-
// Read messages from cache for this channel
|
|
112
|
-
const messagesQuery = cache.readQuery({
|
|
113
|
-
query: gql`
|
|
114
|
-
query GetChannelMessages($channelId: String!) {
|
|
115
|
-
messages(channelId: $channelId, skip: 0, limit: 1) {
|
|
116
|
-
data {
|
|
117
|
-
id
|
|
118
|
-
content
|
|
119
|
-
createdAt
|
|
120
|
-
updatedAt
|
|
121
|
-
user {
|
|
122
|
-
id
|
|
123
|
-
username
|
|
124
|
-
displayName
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
`,
|
|
130
|
-
variables: { channelId },
|
|
131
|
-
}) as any;
|
|
132
|
-
|
|
133
|
-
// Return the first (latest) message if available
|
|
134
|
-
return messagesQuery?.messages?.data?.[0] || null;
|
|
135
|
-
} catch (error) {
|
|
136
|
-
// If messages query fails, return null
|
|
137
|
-
return null;
|
|
138
|
-
}
|
|
139
|
-
},
|
|
140
|
-
},
|
|
141
|
-
},
|
|
142
|
-
},
|
|
143
|
-
// Add policies for ChannelMember type
|
|
144
|
-
ChannelMember: {
|
|
145
|
-
keyFields: ['id'],
|
|
146
|
-
fields: {
|
|
147
|
-
user: {
|
|
148
|
-
// Ensure user references are properly merged
|
|
149
|
-
merge: true,
|
|
150
|
-
},
|
|
151
|
-
},
|
|
152
|
-
},
|
|
153
|
-
};
|
|
@@ -1,321 +0,0 @@
|
|
|
1
|
-
import { TypePolicies } from '@apollo/client';
|
|
2
|
-
|
|
3
|
-
export const messagesPolicies: TypePolicies = {
|
|
4
|
-
Messages: {
|
|
5
|
-
// keyFields: ['messagesRefId'],
|
|
6
|
-
//keyFields: [],
|
|
7
|
-
// keyFields: ['data', ['channel', ['id']]],
|
|
8
|
-
fields: {
|
|
9
|
-
id: {
|
|
10
|
-
read(existing, { variables }) {
|
|
11
|
-
const { channelId, parentId }: any = variables;
|
|
12
|
-
return parentId ? `${channelId}-${parentId}` : `${channelId}`;
|
|
13
|
-
},
|
|
14
|
-
},
|
|
15
|
-
messagesRefId: {
|
|
16
|
-
read(existing, { variables }) {
|
|
17
|
-
const { channelId, parentId }: any = variables;
|
|
18
|
-
return parentId ? `${channelId}-${parentId}` : `${channelId}`;
|
|
19
|
-
},
|
|
20
|
-
},
|
|
21
|
-
data: {
|
|
22
|
-
keyArgs: ['channelId', 'parentId'],
|
|
23
|
-
merge: (existing = [], incoming = [], { readField }) => {
|
|
24
|
-
// Use a Map for O(1) lookups instead of array iterations
|
|
25
|
-
const existingMap = new Map();
|
|
26
|
-
|
|
27
|
-
// Populate map with existing messages
|
|
28
|
-
if (existing && existing.length > 0) {
|
|
29
|
-
for (let i = 0; i < existing.length; i++) {
|
|
30
|
-
const id = readField('id', existing[i]);
|
|
31
|
-
if (id) {
|
|
32
|
-
existingMap.set(id, existing[i]);
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
// Create result array with same capacity as total items
|
|
38
|
-
const result = [];
|
|
39
|
-
|
|
40
|
-
// Add incoming items, overwriting existing ones
|
|
41
|
-
if (incoming && incoming.length > 0) {
|
|
42
|
-
for (let i = 0; i < incoming.length; i++) {
|
|
43
|
-
const item = incoming[i];
|
|
44
|
-
const id = readField('id', item);
|
|
45
|
-
if (id) {
|
|
46
|
-
existingMap.set(id, item);
|
|
47
|
-
}
|
|
48
|
-
result.push(item);
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
// Add remaining existing items not in incoming
|
|
53
|
-
if (existing && existing.length > 0) {
|
|
54
|
-
for (let i = 0; i < existing.length; i++) {
|
|
55
|
-
const id = readField('id', existing[i]);
|
|
56
|
-
if (id && !result.some((item) => readField('id', item) === id)) {
|
|
57
|
-
result.push(existing[i]);
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
return result;
|
|
63
|
-
},
|
|
64
|
-
},
|
|
65
|
-
totalCount: {
|
|
66
|
-
keyArgs: ['channelId', 'parentId'],
|
|
67
|
-
merge(existing, incoming) {
|
|
68
|
-
return incoming !== undefined ? incoming : existing;
|
|
69
|
-
},
|
|
70
|
-
},
|
|
71
|
-
// data: {
|
|
72
|
-
// merge(existing: any[], incoming: any[], { args }) {
|
|
73
|
-
// console.log('existing', JSON.stringify(existing), 'incoming', JSON.stringify(incoming));
|
|
74
|
-
// const merged = existing ? existing.slice(0) : [];
|
|
75
|
-
// // Insert the incoming elements in the right places, according to args.
|
|
76
|
-
// const end = args?.skip + Math.min(args?.limit, incoming.length);
|
|
77
|
-
// for (let i = args?.skip; i < end; ++i) {
|
|
78
|
-
// merged[i] = incoming[i - args?.skip];
|
|
79
|
-
// }
|
|
80
|
-
// return merged;
|
|
81
|
-
// },
|
|
82
|
-
// },
|
|
83
|
-
},
|
|
84
|
-
},
|
|
85
|
-
PostThreadMessages: {
|
|
86
|
-
// keyFields: ['threadmessagesRefId'],
|
|
87
|
-
fields: {
|
|
88
|
-
threadmessagesRefId: {
|
|
89
|
-
read(existing, { variables }) {
|
|
90
|
-
const { channelId, parentId }: any = variables;
|
|
91
|
-
return parentId ? `${channelId}-${parentId}` : `${channelId}`;
|
|
92
|
-
},
|
|
93
|
-
},
|
|
94
|
-
id: {
|
|
95
|
-
read(existing, { variables }) {
|
|
96
|
-
const { channelId, parentId }: any = variables;
|
|
97
|
-
return parentId ? `${channelId}-${parentId}` : `${channelId}`;
|
|
98
|
-
},
|
|
99
|
-
},
|
|
100
|
-
},
|
|
101
|
-
},
|
|
102
|
-
Query: {
|
|
103
|
-
fields: {
|
|
104
|
-
messages: {
|
|
105
|
-
keyArgs: ['channelId', 'parentId'],
|
|
106
|
-
merge(existing, incoming, { args, readField }) {
|
|
107
|
-
if (!incoming) return existing;
|
|
108
|
-
if (!existing) return incoming;
|
|
109
|
-
|
|
110
|
-
// Fast return if incoming has no data
|
|
111
|
-
if (!incoming.data || incoming.data.length === 0) {
|
|
112
|
-
return {
|
|
113
|
-
...existing,
|
|
114
|
-
totalCount: incoming.totalCount ?? existing.totalCount,
|
|
115
|
-
};
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
// Fast return if existing has no data
|
|
119
|
-
if (!existing.data || existing.data.length === 0) {
|
|
120
|
-
return incoming;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
// Determine if this is likely a new message or pagination
|
|
124
|
-
const isNewMessage = args && args.skip === 0;
|
|
125
|
-
|
|
126
|
-
// Create a map for existing messages for fast lookups
|
|
127
|
-
const idSet = new Set();
|
|
128
|
-
const mergedData = [...existing.data];
|
|
129
|
-
|
|
130
|
-
// Mark all existing IDs
|
|
131
|
-
for (let i = 0; i < mergedData.length; i++) {
|
|
132
|
-
const id = readField('id', mergedData[i]);
|
|
133
|
-
if (id) idSet.add(id);
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
// Process incoming messages
|
|
137
|
-
for (let i = 0; i < incoming.data.length; i++) {
|
|
138
|
-
const incomingMsg = incoming.data[i];
|
|
139
|
-
const id = readField('id', incomingMsg);
|
|
140
|
-
|
|
141
|
-
if (!id) continue;
|
|
142
|
-
|
|
143
|
-
if (idSet.has(id)) {
|
|
144
|
-
// Replace existing message with same ID
|
|
145
|
-
const existingIndex = mergedData.findIndex((msg) => readField('id', msg) === id);
|
|
146
|
-
if (existingIndex >= 0) {
|
|
147
|
-
mergedData[existingIndex] = incomingMsg;
|
|
148
|
-
}
|
|
149
|
-
} else {
|
|
150
|
-
// Add new message
|
|
151
|
-
if (isNewMessage) {
|
|
152
|
-
// Add to beginning for new messages
|
|
153
|
-
mergedData.unshift(incomingMsg);
|
|
154
|
-
} else {
|
|
155
|
-
// Add to end for pagination
|
|
156
|
-
mergedData.push(incomingMsg);
|
|
157
|
-
}
|
|
158
|
-
idSet.add(id);
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
return {
|
|
163
|
-
...existing,
|
|
164
|
-
totalCount: incoming.totalCount ?? existing.totalCount,
|
|
165
|
-
data: mergedData,
|
|
166
|
-
};
|
|
167
|
-
},
|
|
168
|
-
},
|
|
169
|
-
},
|
|
170
|
-
},
|
|
171
|
-
FilesInfo: {
|
|
172
|
-
merge: true, // Use default merging behavior for FilesInfo
|
|
173
|
-
fields: {
|
|
174
|
-
data: {
|
|
175
|
-
merge(existing = [], incoming = [], { readField }) {
|
|
176
|
-
// If no existing data, just return incoming
|
|
177
|
-
if (!existing || existing.length === 0) {
|
|
178
|
-
return incoming;
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
// If no incoming data, keep existing
|
|
182
|
-
if (!incoming || incoming.length === 0) {
|
|
183
|
-
return existing;
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
// Create a map for efficient lookup
|
|
187
|
-
const fileMap = new Map();
|
|
188
|
-
|
|
189
|
-
// Add existing files to map
|
|
190
|
-
for (let i = 0; i < existing.length; i++) {
|
|
191
|
-
const file = existing[i];
|
|
192
|
-
if (file) {
|
|
193
|
-
const id = readField('id', file);
|
|
194
|
-
if (id) {
|
|
195
|
-
fileMap.set(id, file);
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
// Merge in incoming files, overwriting existing ones
|
|
201
|
-
for (let i = 0; i < incoming.length; i++) {
|
|
202
|
-
const file = incoming[i];
|
|
203
|
-
if (file) {
|
|
204
|
-
const id = readField('id', file);
|
|
205
|
-
if (id) {
|
|
206
|
-
fileMap.set(id, file);
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
// Convert map values back to array
|
|
212
|
-
return Array.from(fileMap.values());
|
|
213
|
-
},
|
|
214
|
-
},
|
|
215
|
-
},
|
|
216
|
-
},
|
|
217
|
-
FileInfo: {
|
|
218
|
-
// Use ID as key field
|
|
219
|
-
keyFields: ['id'],
|
|
220
|
-
fields: {
|
|
221
|
-
url: {
|
|
222
|
-
// Ensure URL is always preserved and not normalized
|
|
223
|
-
merge(existing, incoming) {
|
|
224
|
-
return incoming ?? existing;
|
|
225
|
-
},
|
|
226
|
-
},
|
|
227
|
-
},
|
|
228
|
-
},
|
|
229
|
-
Post: {
|
|
230
|
-
fields: {
|
|
231
|
-
replies: {
|
|
232
|
-
merge(existing, incoming) {
|
|
233
|
-
if (!incoming) return existing;
|
|
234
|
-
if (!existing) return incoming;
|
|
235
|
-
|
|
236
|
-
// Use a Set for fast duplicate checking
|
|
237
|
-
const uniqueIds = new Set();
|
|
238
|
-
const mergedData = [];
|
|
239
|
-
|
|
240
|
-
// Add all existing items to the result and track IDs
|
|
241
|
-
if (existing.data && existing.data.length > 0) {
|
|
242
|
-
for (let i = 0; i < existing.data.length; i++) {
|
|
243
|
-
const item = existing.data[i];
|
|
244
|
-
if (item && item.id && !uniqueIds.has(item.id)) {
|
|
245
|
-
uniqueIds.add(item.id);
|
|
246
|
-
mergedData.push(item);
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
// Add incoming items that don't exist yet
|
|
252
|
-
if (incoming.data && incoming.data.length > 0) {
|
|
253
|
-
for (let i = 0; i < incoming.data.length; i++) {
|
|
254
|
-
const item = incoming.data[i];
|
|
255
|
-
if (item && item.id && !uniqueIds.has(item.id)) {
|
|
256
|
-
uniqueIds.add(item.id);
|
|
257
|
-
mergedData.push(item);
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
return {
|
|
263
|
-
...incoming,
|
|
264
|
-
data: mergedData,
|
|
265
|
-
};
|
|
266
|
-
},
|
|
267
|
-
},
|
|
268
|
-
files: {
|
|
269
|
-
merge(existing, incoming, { readField }) {
|
|
270
|
-
if (!incoming) return existing;
|
|
271
|
-
if (!existing) return incoming;
|
|
272
|
-
|
|
273
|
-
// If either has no data or totalCount is 0, prefer the one with data
|
|
274
|
-
if (!existing.data || existing.data.length === 0) {
|
|
275
|
-
return incoming;
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
if (!incoming.data || incoming.data.length === 0) {
|
|
279
|
-
return existing;
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
// Create a map for efficient lookup
|
|
283
|
-
const fileMap = new Map();
|
|
284
|
-
|
|
285
|
-
// Add existing files to map
|
|
286
|
-
if (existing.data) {
|
|
287
|
-
for (let i = 0; i < existing.data.length; i++) {
|
|
288
|
-
const file = existing.data[i];
|
|
289
|
-
if (file) {
|
|
290
|
-
const id = readField('id', file);
|
|
291
|
-
if (id) {
|
|
292
|
-
fileMap.set(id, file);
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
// Merge in incoming files, overwriting existing ones
|
|
299
|
-
if (incoming.data) {
|
|
300
|
-
for (let i = 0; i < incoming.data.length; i++) {
|
|
301
|
-
const file = incoming.data[i];
|
|
302
|
-
if (file) {
|
|
303
|
-
const id = readField('id', file);
|
|
304
|
-
if (id) {
|
|
305
|
-
fileMap.set(id, file);
|
|
306
|
-
}
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
// Create merged result
|
|
312
|
-
return {
|
|
313
|
-
__typename: 'FilesInfo',
|
|
314
|
-
totalCount: Math.max(existing.totalCount || 0, incoming.totalCount || 0, fileMap.size),
|
|
315
|
-
data: Array.from(fileMap.values()),
|
|
316
|
-
};
|
|
317
|
-
},
|
|
318
|
-
},
|
|
319
|
-
},
|
|
320
|
-
},
|
|
321
|
-
};
|
|
@@ -1,179 +0,0 @@
|
|
|
1
|
-
import { TypePolicies } from '@apollo/client';
|
|
2
|
-
import { gql } from '@apollo/client';
|
|
3
|
-
|
|
4
|
-
// Define the fragment we'll use for cache operations
|
|
5
|
-
const POST_THREAD_FRAGMENT = gql`
|
|
6
|
-
fragment PostThreadInfo on PostThread {
|
|
7
|
-
replies
|
|
8
|
-
replyCount
|
|
9
|
-
lastReplyAt
|
|
10
|
-
updatedAt
|
|
11
|
-
}
|
|
12
|
-
`;
|
|
13
|
-
|
|
14
|
-
export const postThreadPolicies: TypePolicies = {
|
|
15
|
-
ThreadMessages: {
|
|
16
|
-
keyFields: ['data', ['channel', ['id']]],
|
|
17
|
-
fields: {
|
|
18
|
-
data: {
|
|
19
|
-
merge: (existing = [], incoming = [], { readField }) => {
|
|
20
|
-
// Create a map for efficient lookups
|
|
21
|
-
const threadMap = new Map();
|
|
22
|
-
|
|
23
|
-
// Store existing threads
|
|
24
|
-
if (existing && existing.length > 0) {
|
|
25
|
-
for (const item of existing) {
|
|
26
|
-
const id = readField('id', item);
|
|
27
|
-
if (id) threadMap.set(id, item);
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
// Add or update with incoming threads
|
|
32
|
-
if (incoming && incoming.length > 0) {
|
|
33
|
-
for (const item of incoming) {
|
|
34
|
-
const id = readField('id', item);
|
|
35
|
-
if (id) threadMap.set(id, item);
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
// Convert back to array
|
|
40
|
-
return Array.from(threadMap.values());
|
|
41
|
-
},
|
|
42
|
-
},
|
|
43
|
-
totalCount: {
|
|
44
|
-
merge(existing, incoming) {
|
|
45
|
-
// Take the higher of the two counts
|
|
46
|
-
return incoming !== undefined ? Math.max(existing || 0, incoming) : existing;
|
|
47
|
-
},
|
|
48
|
-
},
|
|
49
|
-
},
|
|
50
|
-
},
|
|
51
|
-
Query: {
|
|
52
|
-
fields: {
|
|
53
|
-
threadMessages: {
|
|
54
|
-
keyArgs: ['channelId'],
|
|
55
|
-
merge(existing, incoming, { readField }) {
|
|
56
|
-
if (!existing) return incoming;
|
|
57
|
-
if (!incoming) return existing;
|
|
58
|
-
|
|
59
|
-
return {
|
|
60
|
-
...incoming,
|
|
61
|
-
data: [...(existing?.data || []), ...(incoming.data || [])].filter(
|
|
62
|
-
(item, index, self) =>
|
|
63
|
-
// Filter out duplicates
|
|
64
|
-
index === self.findIndex((t) => readField('id', t) === readField('id', item)),
|
|
65
|
-
),
|
|
66
|
-
};
|
|
67
|
-
},
|
|
68
|
-
},
|
|
69
|
-
getPostThread: {
|
|
70
|
-
keyArgs: ['channelId', 'postParentId', 'role'],
|
|
71
|
-
merge(existing, incoming, { mergeObjects }) {
|
|
72
|
-
if (!existing) return incoming;
|
|
73
|
-
if (!incoming) return existing;
|
|
74
|
-
|
|
75
|
-
// Carefully merge the two objects
|
|
76
|
-
const result = mergeObjects(existing, incoming);
|
|
77
|
-
|
|
78
|
-
// Special handling for replies to avoid duplicates
|
|
79
|
-
if (existing.replies && incoming.replies) {
|
|
80
|
-
const uniqueReplies = new Map();
|
|
81
|
-
|
|
82
|
-
// Add existing replies
|
|
83
|
-
for (const reply of existing.replies) {
|
|
84
|
-
uniqueReplies.set(reply.id, reply);
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
// Add incoming replies, overwriting existing ones
|
|
88
|
-
for (const reply of incoming.replies) {
|
|
89
|
-
uniqueReplies.set(reply.id, reply);
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
// Replace replies with deduplicated list
|
|
93
|
-
result.replies = Array.from(uniqueReplies.values());
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
return result;
|
|
97
|
-
},
|
|
98
|
-
},
|
|
99
|
-
},
|
|
100
|
-
},
|
|
101
|
-
// Mutation: {
|
|
102
|
-
// fields: {
|
|
103
|
-
// createPostThread: {
|
|
104
|
-
// merge(existing, incoming, { cache, args, readField }) {
|
|
105
|
-
// // Early return if not enough data
|
|
106
|
-
// if (!incoming?.lastMessage || !incoming?.data || !args?.channelId || !args?.postParentId) {
|
|
107
|
-
// return incoming;
|
|
108
|
-
// }
|
|
109
|
-
|
|
110
|
-
// try {
|
|
111
|
-
// // Use type policies to handle the cache update instead of direct manipulation
|
|
112
|
-
// const queryRef = cache.identify({
|
|
113
|
-
// __typename: 'Query',
|
|
114
|
-
// getPostThread: {
|
|
115
|
-
// channelId: args.channelId,
|
|
116
|
-
// postParentId: args.postParentId,
|
|
117
|
-
// role: args.threadMessageInput?.role
|
|
118
|
-
// }
|
|
119
|
-
// });
|
|
120
|
-
|
|
121
|
-
// // Use cache.modify which doesn't require fragments
|
|
122
|
-
// if (queryRef) {
|
|
123
|
-
// cache.modify({
|
|
124
|
-
// id: queryRef,
|
|
125
|
-
// fields: {
|
|
126
|
-
// getPostThread(existingThread = {}) {
|
|
127
|
-
// if (!existingThread) return existingThread;
|
|
128
|
-
|
|
129
|
-
// // Create a new object with the updated properties
|
|
130
|
-
// return {
|
|
131
|
-
// ...existingThread,
|
|
132
|
-
// replies: [incoming.lastMessage, ...(existingThread.replies || [])],
|
|
133
|
-
// replyCount: (existingThread.replyCount || 0) + 1,
|
|
134
|
-
// lastReplyAt: incoming.lastMessage.createdAt,
|
|
135
|
-
// updatedAt: incoming.lastMessage.createdAt
|
|
136
|
-
// };
|
|
137
|
-
// }
|
|
138
|
-
// }
|
|
139
|
-
// });
|
|
140
|
-
// }
|
|
141
|
-
// } catch (error) {
|
|
142
|
-
// console.error('Error updating cache in createPostThread policy:', error);
|
|
143
|
-
// }
|
|
144
|
-
|
|
145
|
-
// return incoming;
|
|
146
|
-
// },
|
|
147
|
-
// },
|
|
148
|
-
// },
|
|
149
|
-
// },
|
|
150
|
-
PostThread: {
|
|
151
|
-
fields: {
|
|
152
|
-
replies: {
|
|
153
|
-
merge(existing = [], incoming = [], { readField }) {
|
|
154
|
-
// Use a map for fast deduplication
|
|
155
|
-
const replyMap = new Map();
|
|
156
|
-
|
|
157
|
-
// Add existing replies
|
|
158
|
-
if (existing && existing.length > 0) {
|
|
159
|
-
for (const reply of existing) {
|
|
160
|
-
const id = readField('id', reply);
|
|
161
|
-
if (id) replyMap.set(id, reply);
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
// Add or update with incoming replies
|
|
166
|
-
if (incoming && incoming.length > 0) {
|
|
167
|
-
for (const reply of incoming) {
|
|
168
|
-
const id = readField('id', reply);
|
|
169
|
-
if (id) replyMap.set(id, reply);
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
// Convert back to array
|
|
174
|
-
return Array.from(replyMap.values());
|
|
175
|
-
},
|
|
176
|
-
},
|
|
177
|
-
},
|
|
178
|
-
},
|
|
179
|
-
};
|