@messenger-box/platform-client 10.0.3-alpha.36 → 10.0.3-alpha.37
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
CHANGED
|
@@ -3,6 +3,10 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## [10.0.3-alpha.37](https://github.com/CDEBase/messenger-box/compare/v10.0.3-alpha.36...v10.0.3-alpha.37) (2025-04-25)
|
|
7
|
+
|
|
8
|
+
**Note:** Version bump only for package @messenger-box/platform-client
|
|
9
|
+
|
|
6
10
|
## [10.0.3-alpha.36](https://github.com/CDEBase/messenger-box/compare/v10.0.3-alpha.35...v10.0.3-alpha.36) (2025-04-23)
|
|
7
11
|
|
|
8
12
|
**Note:** Version bump only for package @messenger-box/platform-client
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"messages-policies.d.ts","sourceRoot":"","sources":["../../../src/graphql/policies/messages-policies.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9C,eAAO,MAAM,gBAAgB,EAAE,
|
|
1
|
+
{"version":3,"file":"messages-policies.d.ts","sourceRoot":"","sources":["../../../src/graphql/policies/messages-policies.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9C,eAAO,MAAM,gBAAgB,EAAE,YA2L9B,CAAC"}
|
|
@@ -27,29 +27,40 @@ const messagesPolicies = {
|
|
|
27
27
|
}
|
|
28
28
|
},
|
|
29
29
|
data: {
|
|
30
|
-
keyArgs:
|
|
30
|
+
keyArgs: ['channelId', 'parentId'],
|
|
31
31
|
merge: (existing = [], incoming = [], {
|
|
32
32
|
readField,
|
|
33
33
|
mergeObjects
|
|
34
34
|
}) => {
|
|
35
|
-
//
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
35
|
+
// Create a map of existing messages by ID for efficient lookups
|
|
36
|
+
const existingMap = new Map();
|
|
37
|
+
existing.forEach(item => {
|
|
38
|
+
const id = readField('id', item);
|
|
39
|
+
if (id) existingMap.set(id, item);
|
|
40
|
+
});
|
|
41
|
+
// Create a new array by merging incoming with existing
|
|
42
|
+
const merged = incoming.map(incomingItem => {
|
|
43
|
+
const id = readField('id', incomingItem);
|
|
44
|
+
// If item already exists, merge them, otherwise use incoming
|
|
45
|
+
if (id && existingMap.has(id)) {
|
|
46
|
+
return mergeObjects(existingMap.get(id), incomingItem);
|
|
47
|
+
}
|
|
48
|
+
return incomingItem;
|
|
49
|
+
});
|
|
50
|
+
// Add any existing items that aren't in the incoming list
|
|
51
|
+
existing.forEach(existingItem => {
|
|
52
|
+
const id = readField('id', existingItem);
|
|
53
|
+
if (id && !merged.some(item => readField('id', item) === id)) {
|
|
54
|
+
merged.push(existingItem);
|
|
44
55
|
}
|
|
45
56
|
});
|
|
46
57
|
return merged;
|
|
47
58
|
}
|
|
48
59
|
},
|
|
49
60
|
totalCount: {
|
|
50
|
-
keyArgs:
|
|
61
|
+
keyArgs: ['channelId', 'parentId'],
|
|
51
62
|
merge(existing, incoming) {
|
|
52
|
-
return
|
|
63
|
+
return incoming !== undefined ? incoming : existing;
|
|
53
64
|
}
|
|
54
65
|
}
|
|
55
66
|
// data: {
|
|
@@ -96,32 +107,89 @@ const messagesPolicies = {
|
|
|
96
107
|
Query: {
|
|
97
108
|
fields: {
|
|
98
109
|
messages: {
|
|
99
|
-
|
|
100
|
-
|
|
110
|
+
keyArgs: ['channelId', 'parentId'],
|
|
111
|
+
merge(existing, incoming, {
|
|
112
|
+
args,
|
|
113
|
+
readField
|
|
114
|
+
}) {
|
|
115
|
+
if (!incoming) return existing;
|
|
116
|
+
if (!existing) return incoming;
|
|
117
|
+
// Create a deep copy of the existing data
|
|
118
|
+
const result = {
|
|
119
|
+
...existing,
|
|
120
|
+
totalCount: incoming.totalCount ?? existing.totalCount
|
|
121
|
+
};
|
|
122
|
+
// If there's no data in either, return the basic structure
|
|
123
|
+
if (!existing.data || !incoming.data) {
|
|
124
|
+
return result;
|
|
125
|
+
}
|
|
126
|
+
// Create a map of existing messages by ID
|
|
127
|
+
const existingMessages = new Map();
|
|
128
|
+
existing.data.forEach(message => {
|
|
129
|
+
const id = readField('id', message);
|
|
130
|
+
if (id) existingMessages.set(id, message);
|
|
131
|
+
});
|
|
132
|
+
// Create merged data array with deduplication
|
|
133
|
+
let mergedData = [...existing.data];
|
|
134
|
+
// Add new messages, replacing existing ones with same ID
|
|
135
|
+
incoming.data.forEach(incomingMessage => {
|
|
136
|
+
const id = readField('id', incomingMessage);
|
|
137
|
+
if (!id) return;
|
|
138
|
+
// If message already exists, update it at its current position
|
|
139
|
+
const existingIndex = mergedData.findIndex(msg => readField('id', msg) === id);
|
|
140
|
+
if (existingIndex >= 0) {
|
|
141
|
+
// Replace the existing message with the incoming one
|
|
142
|
+
mergedData[existingIndex] = incomingMessage;
|
|
143
|
+
} else {
|
|
144
|
+
// Add the new message
|
|
145
|
+
// For optimistic updates with sendMessage mutation, we want to add to the beginning
|
|
146
|
+
// For pagination/fetchMore, we should add according to the sort order
|
|
147
|
+
if (args && args.skip === 0) {
|
|
148
|
+
// This is likely a new message or an optimistic update
|
|
149
|
+
mergedData.unshift(incomingMessage);
|
|
150
|
+
} else {
|
|
151
|
+
// This is likely from pagination
|
|
152
|
+
mergedData.push(incomingMessage);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
});
|
|
156
|
+
// Ensure no duplicate messages
|
|
157
|
+
const uniqueIds = new Set();
|
|
158
|
+
mergedData = mergedData.filter(message => {
|
|
159
|
+
const id = readField('id', message);
|
|
160
|
+
if (!id || uniqueIds.has(id)) return false;
|
|
161
|
+
uniqueIds.add(id);
|
|
162
|
+
return true;
|
|
163
|
+
});
|
|
164
|
+
return {
|
|
165
|
+
...result,
|
|
166
|
+
data: mergedData
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
},
|
|
172
|
+
Post: {
|
|
173
|
+
fields: {
|
|
174
|
+
replies: {
|
|
175
|
+
merge(existing, incoming) {
|
|
176
|
+
if (!incoming) return existing;
|
|
177
|
+
if (!existing) return incoming;
|
|
178
|
+
return {
|
|
179
|
+
...incoming,
|
|
180
|
+
data: [...(existing?.data || []), ...(incoming?.data || [])].filter((message, index, self) => index === self.findIndex(m => m.id === message.id))
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
},
|
|
184
|
+
files: {
|
|
101
185
|
merge(existing, incoming) {
|
|
186
|
+
if (!incoming) return existing;
|
|
187
|
+
if (!existing) return incoming;
|
|
102
188
|
return {
|
|
103
189
|
...incoming,
|
|
104
|
-
data: [...(existing?.data
|
|
190
|
+
data: [...(existing?.data || []), ...(incoming?.data || [])].filter((file, index, self) => index === self.findIndex(f => f.id === file.id))
|
|
105
191
|
};
|
|
106
192
|
}
|
|
107
|
-
// merge(existing, incoming, { args, mergeObjects }) {
|
|
108
|
-
// console.log('existing length', existing?.data?.length);
|
|
109
|
-
// console.log('incoming length', incoming?.data?.length);
|
|
110
|
-
// // console.log('existing', JSON.stringify(existing), 'incoming', JSON.stringify(incoming));
|
|
111
|
-
// if (!incoming || incoming?.data?.length) return existing;
|
|
112
|
-
// if (!existing || existing?.data?.length) return incoming;
|
|
113
|
-
// //console.log('existing', JSON.stringify(existing), 'incoming', JSON.stringify(incoming));
|
|
114
|
-
// const mergedData = existing ? existing?.data?.slice(0) : [];
|
|
115
|
-
// // Insert the incoming elements in the right places, according to args.
|
|
116
|
-
// const end = args?.skip + Math.min(args?.limit, incoming?.data?.length);
|
|
117
|
-
// for (let i = args?.skip; i < end; ++i) {
|
|
118
|
-
// mergedData[i] = incoming?.data[i - args?.skip];
|
|
119
|
-
// }
|
|
120
|
-
// const merged = { ...incoming, data: mergedData };
|
|
121
|
-
// return merged;
|
|
122
|
-
// // return mergeObjects(existing, incoming);
|
|
123
|
-
// //return existing ? { ...existing, ...incoming } : incoming;
|
|
124
|
-
// },
|
|
125
193
|
}
|
|
126
194
|
}
|
|
127
195
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"messages-policies.js","sources":["../../../src/graphql/policies/messages-policies.ts"],"sourcesContent":[null],"names":[],"mappings":"AAEa,MAAA,gBAAgB,GAAiB;AAC1C,EAAA,QAAA,EAAQ;;;;AAIJ,IAAA,MAAA,EAAA;AACI,MAAA,EAAA,EAAA;AACI,QAAA,IAAA,CAAA,QAAK,EAAA;AACD,UAAA;AACA,SAAA,EAAA;gBACJ;AACH,YAAA,SAAA;AACD,YAAA;AACI,WAAA,GAAA,SAAK;AACD,UAAA,OAAA,QAAA,GAAQ,CAAS,EAAA,qBAAoB,iBAAU,CAAA,CAAA;AAC/C;;AAEP,MAAA,aAAA,EAAA;AACD,QAAA,IAAA,CAAA,QAAM,EAAA;AACF,UAAA;AACA,SAAA,EAAA;;
|
|
1
|
+
{"version":3,"file":"messages-policies.js","sources":["../../../src/graphql/policies/messages-policies.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@messenger-box/platform-client",
|
|
3
|
-
"version": "10.0.3-alpha.
|
|
3
|
+
"version": "10.0.3-alpha.37",
|
|
4
4
|
"description": "Sample core for higher packages to depend on",
|
|
5
5
|
"license": "ISC",
|
|
6
6
|
"author": "CDMBase LLC",
|
|
@@ -35,5 +35,5 @@
|
|
|
35
35
|
"typescript": {
|
|
36
36
|
"definition": "lib/index.d.ts"
|
|
37
37
|
},
|
|
38
|
-
"gitHead": "
|
|
38
|
+
"gitHead": "4a360a1be756050ed8c3c1cd61a037c6109f8866"
|
|
39
39
|
}
|
|
@@ -19,27 +19,40 @@ export const messagesPolicies: TypePolicies = {
|
|
|
19
19
|
},
|
|
20
20
|
},
|
|
21
21
|
data: {
|
|
22
|
-
keyArgs:
|
|
22
|
+
keyArgs: ['channelId', 'parentId'],
|
|
23
23
|
merge: (existing = [], incoming = [], { readField, mergeObjects }) => {
|
|
24
|
-
//
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
24
|
+
// Create a map of existing messages by ID for efficient lookups
|
|
25
|
+
const existingMap = new Map();
|
|
26
|
+
existing.forEach((item) => {
|
|
27
|
+
const id = readField<string>('id', item);
|
|
28
|
+
if (id) existingMap.set(id, item);
|
|
29
|
+
});
|
|
28
30
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
|
|
31
|
+
// Create a new array by merging incoming with existing
|
|
32
|
+
const merged = incoming.map((incomingItem) => {
|
|
33
|
+
const id = readField<string>('id', incomingItem);
|
|
34
|
+
// If item already exists, merge them, otherwise use incoming
|
|
35
|
+
if (id && existingMap.has(id)) {
|
|
36
|
+
return mergeObjects(existingMap.get(id), incomingItem);
|
|
34
37
|
}
|
|
38
|
+
return incomingItem;
|
|
35
39
|
});
|
|
40
|
+
|
|
41
|
+
// Add any existing items that aren't in the incoming list
|
|
42
|
+
existing.forEach((existingItem) => {
|
|
43
|
+
const id = readField<string>('id', existingItem);
|
|
44
|
+
if (id && !merged.some((item) => readField<string>('id', item) === id)) {
|
|
45
|
+
merged.push(existingItem);
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
|
|
36
49
|
return merged;
|
|
37
50
|
},
|
|
38
51
|
},
|
|
39
52
|
totalCount: {
|
|
40
|
-
keyArgs:
|
|
53
|
+
keyArgs: ['channelId', 'parentId'],
|
|
41
54
|
merge(existing, incoming) {
|
|
42
|
-
return
|
|
55
|
+
return incoming !== undefined ? incoming : existing;
|
|
43
56
|
},
|
|
44
57
|
},
|
|
45
58
|
// data: {
|
|
@@ -57,7 +70,7 @@ export const messagesPolicies: TypePolicies = {
|
|
|
57
70
|
},
|
|
58
71
|
},
|
|
59
72
|
PostThreadMessages: {
|
|
60
|
-
|
|
73
|
+
// keyFields: ['threadmessagesRefId'],
|
|
61
74
|
fields: {
|
|
62
75
|
threadmessagesRefId: {
|
|
63
76
|
read(existing, { variables }) {
|
|
@@ -76,33 +89,101 @@ export const messagesPolicies: TypePolicies = {
|
|
|
76
89
|
Query: {
|
|
77
90
|
fields: {
|
|
78
91
|
messages: {
|
|
79
|
-
|
|
80
|
-
|
|
92
|
+
keyArgs: ['channelId', 'parentId'],
|
|
93
|
+
merge(existing, incoming, { args, readField }) {
|
|
94
|
+
if (!incoming) return existing;
|
|
95
|
+
if (!existing) return incoming;
|
|
96
|
+
|
|
97
|
+
// Create a deep copy of the existing data
|
|
98
|
+
const result = {
|
|
99
|
+
...existing,
|
|
100
|
+
totalCount: incoming.totalCount ?? existing.totalCount,
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
// If there's no data in either, return the basic structure
|
|
104
|
+
if (!existing.data || !incoming.data) {
|
|
105
|
+
return result;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// Create a map of existing messages by ID
|
|
109
|
+
const existingMessages = new Map();
|
|
110
|
+
existing.data.forEach((message) => {
|
|
111
|
+
const id = readField<string>('id', message);
|
|
112
|
+
if (id) existingMessages.set(id, message);
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
// Create merged data array with deduplication
|
|
116
|
+
let mergedData = [...existing.data];
|
|
117
|
+
|
|
118
|
+
// Add new messages, replacing existing ones with same ID
|
|
119
|
+
incoming.data.forEach((incomingMessage) => {
|
|
120
|
+
const id = readField<string>('id', incomingMessage);
|
|
121
|
+
if (!id) return;
|
|
122
|
+
|
|
123
|
+
// If message already exists, update it at its current position
|
|
124
|
+
const existingIndex = mergedData.findIndex((msg) => readField<string>('id', msg) === id);
|
|
125
|
+
|
|
126
|
+
if (existingIndex >= 0) {
|
|
127
|
+
// Replace the existing message with the incoming one
|
|
128
|
+
mergedData[existingIndex] = incomingMessage;
|
|
129
|
+
} else {
|
|
130
|
+
// Add the new message
|
|
131
|
+
// For optimistic updates with sendMessage mutation, we want to add to the beginning
|
|
132
|
+
// For pagination/fetchMore, we should add according to the sort order
|
|
133
|
+
if (args && args.skip === 0) {
|
|
134
|
+
// This is likely a new message or an optimistic update
|
|
135
|
+
mergedData.unshift(incomingMessage);
|
|
136
|
+
} else {
|
|
137
|
+
// This is likely from pagination
|
|
138
|
+
mergedData.push(incomingMessage);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
// Ensure no duplicate messages
|
|
144
|
+
const uniqueIds = new Set();
|
|
145
|
+
mergedData = mergedData.filter((message) => {
|
|
146
|
+
const id = readField<string>('id', message);
|
|
147
|
+
if (!id || uniqueIds.has(id)) return false;
|
|
148
|
+
uniqueIds.add(id);
|
|
149
|
+
return true;
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
return {
|
|
153
|
+
...result,
|
|
154
|
+
data: mergedData,
|
|
155
|
+
};
|
|
156
|
+
},
|
|
157
|
+
},
|
|
158
|
+
},
|
|
159
|
+
},
|
|
160
|
+
Post: {
|
|
161
|
+
fields: {
|
|
162
|
+
replies: {
|
|
81
163
|
merge(existing, incoming) {
|
|
164
|
+
if (!incoming) return existing;
|
|
165
|
+
if (!existing) return incoming;
|
|
166
|
+
|
|
82
167
|
return {
|
|
83
168
|
...incoming,
|
|
84
|
-
data: [...(existing?.data
|
|
169
|
+
data: [...(existing?.data || []), ...(incoming?.data || [])].filter(
|
|
170
|
+
(message, index, self) => index === self.findIndex((m) => m.id === message.id),
|
|
171
|
+
),
|
|
85
172
|
};
|
|
86
173
|
},
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
// if (!existing || existing?.data?.length) return incoming;
|
|
93
|
-
// //console.log('existing', JSON.stringify(existing), 'incoming', JSON.stringify(incoming));
|
|
94
|
-
// const mergedData = existing ? existing?.data?.slice(0) : [];
|
|
95
|
-
// // Insert the incoming elements in the right places, according to args.
|
|
96
|
-
// const end = args?.skip + Math.min(args?.limit, incoming?.data?.length);
|
|
97
|
-
// for (let i = args?.skip; i < end; ++i) {
|
|
98
|
-
// mergedData[i] = incoming?.data[i - args?.skip];
|
|
99
|
-
// }
|
|
174
|
+
},
|
|
175
|
+
files: {
|
|
176
|
+
merge(existing, incoming) {
|
|
177
|
+
if (!incoming) return existing;
|
|
178
|
+
if (!existing) return incoming;
|
|
100
179
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
180
|
+
return {
|
|
181
|
+
...incoming,
|
|
182
|
+
data: [...(existing?.data || []), ...(incoming?.data || [])].filter(
|
|
183
|
+
(file, index, self) => index === self.findIndex((f) => f.id === file.id),
|
|
184
|
+
),
|
|
185
|
+
};
|
|
186
|
+
},
|
|
106
187
|
},
|
|
107
188
|
},
|
|
108
189
|
},
|