@amityco/ts-sdk 7.32.0 → 7.32.1-0c6bf84.0

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.
Files changed (58) hide show
  1. package/dist/@types/domains/comment.d.ts +2 -2
  2. package/dist/@types/domains/comment.d.ts.map +1 -1
  3. package/dist/@types/domains/content.d.ts +23 -3
  4. package/dist/@types/domains/content.d.ts.map +1 -1
  5. package/dist/@types/domains/feed.d.ts +4 -1
  6. package/dist/@types/domains/feed.d.ts.map +1 -1
  7. package/dist/@types/domains/post.d.ts +11 -0
  8. package/dist/@types/domains/post.d.ts.map +1 -1
  9. package/dist/cache/api/dropFromCache.d.ts.map +1 -1
  10. package/dist/cache/api/pushToCache.d.ts.map +1 -1
  11. package/dist/cache/api/queryCache.d.ts.map +1 -1
  12. package/dist/cache/api/queryCacheByProperty.d.ts +3 -0
  13. package/dist/cache/api/queryCacheByProperty.d.ts.map +1 -0
  14. package/dist/cache/api/tests/queryCache.test.d.ts +2 -0
  15. package/dist/cache/api/tests/queryCache.test.d.ts.map +1 -0
  16. package/dist/cache/utils/cacheIndex.d.ts +15 -0
  17. package/dist/cache/utils/cacheIndex.d.ts.map +1 -0
  18. package/dist/commentRepository/api/createComment.d.ts +1 -1
  19. package/dist/commentRepository/api/createComment.d.ts.map +1 -1
  20. package/dist/commentRepository/api/tests/createComment.gif.test.d.ts +2 -0
  21. package/dist/commentRepository/api/tests/createComment.gif.test.d.ts.map +1 -0
  22. package/dist/commentRepository/api/tests/deleteComment.gif.test.d.ts +2 -0
  23. package/dist/commentRepository/api/tests/deleteComment.gif.test.d.ts.map +1 -0
  24. package/dist/commentRepository/api/tests/updateComment.gif.test.d.ts +2 -0
  25. package/dist/commentRepository/api/tests/updateComment.gif.test.d.ts.map +1 -0
  26. package/dist/commentRepository/api/updateComment.d.ts +9 -2
  27. package/dist/commentRepository/api/updateComment.d.ts.map +1 -1
  28. package/dist/commentRepository/observers/tests/getComments.gif.test.d.ts +2 -0
  29. package/dist/commentRepository/observers/tests/getComments.gif.test.d.ts.map +1 -0
  30. package/dist/commentRepository/utils/dataTypes.d.ts +2 -0
  31. package/dist/commentRepository/utils/dataTypes.d.ts.map +1 -0
  32. package/dist/index.cjs.js +210 -56
  33. package/dist/index.esm.js +210 -56
  34. package/dist/index.umd.js +2 -2
  35. package/dist/messagePreview/utils/getSubChannelMessagePreviewWithUser.d.ts +1 -1
  36. package/dist/messageRepository/utils/getMessageFromMainDB.d.ts.map +1 -1
  37. package/dist/messageRepository/utils/prepareMessagePayload.d.ts.map +1 -1
  38. package/dist/postRepository/api/createMixedMediaPost.d.ts +6 -6
  39. package/dist/postRepository/api/createMixedMediaPost.d.ts.map +1 -1
  40. package/dist/postRepository/api/createPost.d.ts +1 -4
  41. package/dist/postRepository/api/createPost.d.ts.map +1 -1
  42. package/dist/postRepository/api/editPost.d.ts +4 -5
  43. package/dist/postRepository/api/editPost.d.ts.map +1 -1
  44. package/dist/postRepository/api/tests/gifPost.test.d.ts +2 -0
  45. package/dist/postRepository/api/tests/gifPost.test.d.ts.map +1 -0
  46. package/dist/postRepository/observers/getPosts.d.ts +4 -0
  47. package/dist/postRepository/observers/getPosts.d.ts.map +1 -1
  48. package/dist/postRepository/utils/attachments.d.ts +8 -0
  49. package/dist/postRepository/utils/attachments.d.ts.map +1 -0
  50. package/dist/utils/gifAttachment.d.ts +5 -0
  51. package/dist/utils/gifAttachment.d.ts.map +1 -0
  52. package/dist/utils/linkedObject/channelLinkedObject.d.ts.map +1 -1
  53. package/dist/utils/linkedObject/tests/channelCachePerformance.test.d.ts +2 -0
  54. package/dist/utils/linkedObject/tests/channelCachePerformance.test.d.ts.map +1 -0
  55. package/dist/utils/postTypePredicate.d.ts +1 -0
  56. package/dist/utils/postTypePredicate.d.ts.map +1 -1
  57. package/dist/utils/tests/dummy/comment.d.ts +1 -1
  58. package/package.json +1 -1
package/dist/index.esm.js CHANGED
@@ -177,6 +177,7 @@ const PostContentType = Object.freeze({
177
177
  AUDIO: 'audio',
178
178
  ROOM: 'room',
179
179
  EVENT: 'event',
180
+ GIF: 'gif',
180
181
  });
181
182
  const PostStructureType = Object.freeze({
182
183
  TEXT: 'text',
@@ -186,6 +187,8 @@ const PostStructureType = Object.freeze({
186
187
  AUDIO: 'audio',
187
188
  MIXED: 'mixed',
188
189
  EVENT: 'event',
190
+ /** A post that holds only GIFs. GIFs beside other media make the post `mixed`. */
191
+ GIF: 'gif',
189
192
  });
190
193
 
191
194
  var InvitationTypeEnum;
@@ -1168,6 +1171,116 @@ const wipeCache = async (storageKey = 'amitySdk') => {
1168
1171
  return true;
1169
1172
  };
1170
1173
 
1174
+ // Indexes never enter persisted cache data. Replacing data (restore/wipe/enable) starts a new index.
1175
+ const indexes = new WeakMap();
1176
+ const prefixesFor = (key) => {
1177
+ if (typeof key[0] !== 'string')
1178
+ return [];
1179
+ const prefixes = [JSON.stringify([key[0]])];
1180
+ if (typeof key[1] === 'string')
1181
+ prefixes.push(JSON.stringify([key[0], key[1]]));
1182
+ return prefixes;
1183
+ };
1184
+ const removePropertyValue = (property, indexed) => {
1185
+ const previous = property.previousValues.get(indexed.encodedKey);
1186
+ if (previous === undefined)
1187
+ return;
1188
+ const matches = property.values.get(previous);
1189
+ matches.delete(indexed);
1190
+ if (!matches.size)
1191
+ property.values.delete(previous);
1192
+ property.previousValues.delete(indexed.encodedKey);
1193
+ };
1194
+ const addPropertyValue = (data, property, indexed) => {
1195
+ var _a;
1196
+ if (!partialMatch(property.prefix, indexed.key))
1197
+ return;
1198
+ const value = (_a = data[indexed.encodedKey].data) === null || _a === void 0 ? void 0 : _a[property.property];
1199
+ if (typeof value !== 'string')
1200
+ return;
1201
+ let matches = property.values.get(value);
1202
+ if (!matches) {
1203
+ matches = new Set();
1204
+ property.values.set(value, matches);
1205
+ }
1206
+ matches.add(indexed);
1207
+ property.previousValues.set(indexed.encodedKey, value);
1208
+ };
1209
+ const addKey = (index, encodedKey) => {
1210
+ const indexed = { encodedKey, key: decodeKey(encodedKey), order: index.nextOrder };
1211
+ index.nextOrder += 1; // eslint-disable-line no-param-reassign
1212
+ index.keys.set(encodedKey, indexed);
1213
+ prefixesFor(indexed.key).forEach(prefix => {
1214
+ let keys = index.prefixes.get(prefix);
1215
+ if (!keys) {
1216
+ keys = new Map();
1217
+ index.prefixes.set(prefix, keys);
1218
+ }
1219
+ keys.set(encodedKey, indexed);
1220
+ });
1221
+ return indexed;
1222
+ };
1223
+ const getIndex = (data) => {
1224
+ let index = indexes.get(data);
1225
+ if (!index) {
1226
+ index = { keys: new Map(), prefixes: new Map(), properties: new Map(), nextOrder: 0 };
1227
+ Object.keys(data).forEach(encodedKey => addKey(index, encodedKey));
1228
+ indexes.set(data, index);
1229
+ }
1230
+ return index;
1231
+ };
1232
+ const candidatesFor = (index, key) => {
1233
+ var _a, _b;
1234
+ const prefixes = prefixesFor(key);
1235
+ if (!prefixes.length)
1236
+ return index.keys.values();
1237
+ return (_b = (_a = index.prefixes.get(prefixes[prefixes.length - 1])) === null || _a === void 0 ? void 0 : _a.values()) !== null && _b !== void 0 ? _b : [];
1238
+ };
1239
+ /** @hidden */
1240
+ const getMatchingCacheKeys = (data, key) => Array.from(candidatesFor(getIndex(data), key)).filter(indexed => partialMatch(key, indexed.key));
1241
+ /** Update only an index that has already been used; writes alone need no index build. @hidden */
1242
+ const updateCacheIndex = (data, encodedKey) => {
1243
+ var _a;
1244
+ const index = indexes.get(data);
1245
+ if (!index)
1246
+ return;
1247
+ const indexed = (_a = index.keys.get(encodedKey)) !== null && _a !== void 0 ? _a : addKey(index, encodedKey);
1248
+ index.properties.forEach(property => {
1249
+ removePropertyValue(property, indexed);
1250
+ addPropertyValue(data, property, indexed);
1251
+ });
1252
+ };
1253
+ /** @hidden */
1254
+ const removeFromCacheIndex = (data, encodedKey) => {
1255
+ const index = indexes.get(data);
1256
+ const indexed = index === null || index === void 0 ? void 0 : index.keys.get(encodedKey);
1257
+ if (!index || !indexed)
1258
+ return;
1259
+ index.properties.forEach(property => removePropertyValue(property, indexed));
1260
+ prefixesFor(indexed.key).forEach(prefix => {
1261
+ const keys = index.prefixes.get(prefix);
1262
+ keys.delete(encodedKey);
1263
+ if (!keys.size)
1264
+ index.prefixes.delete(prefix);
1265
+ });
1266
+ index.keys.delete(encodedKey);
1267
+ };
1268
+ /** Index a string model property within one domain/operation, retaining cache insertion order. @hidden */
1269
+ const getCacheEntriesByProperty = (data, prefix, property, value) => {
1270
+ var _a;
1271
+ const index = getIndex(data);
1272
+ const identity = JSON.stringify([prefix, property]);
1273
+ let propertyIndex = index.properties.get(identity);
1274
+ if (!propertyIndex) {
1275
+ propertyIndex = { prefix, property, values: new Map(), previousValues: new Map() };
1276
+ index.properties.set(identity, propertyIndex);
1277
+ Array.from(candidatesFor(index, prefix)).forEach(indexed => addPropertyValue(data, propertyIndex, indexed));
1278
+ }
1279
+ return Array.from((_a = propertyIndex.values.get(value)) !== null && _a !== void 0 ? _a : [])
1280
+ .sort((a, b) => a.order - b.order)
1281
+ .map(({ encodedKey }) => data[encodedKey]);
1282
+ };
1283
+
1171
1284
  /**
1172
1285
  * ```js
1173
1286
  * import { queryCache } from '@amityco/ts-sdk'
@@ -1188,12 +1301,7 @@ const queryCache = (key) => {
1188
1301
  if (!cache)
1189
1302
  return;
1190
1303
  log('cache/api/queryCache', { key });
1191
- return Object.keys(cache.data)
1192
- .filter(stringKey => {
1193
- const decodedKey = decodeKey(stringKey);
1194
- return partialMatch(key, decodedKey);
1195
- })
1196
- .map(stringKey => cache.data[stringKey]);
1304
+ return getMatchingCacheKeys(cache.data, key).map(({ encodedKey }) => cache.data[encodedKey]);
1197
1305
  };
1198
1306
 
1199
1307
  /**
@@ -1249,6 +1357,7 @@ const pushToCache = (key, data, options = { cachedAt: Date.now() }) => {
1249
1357
  }
1250
1358
  const encodedKey = encodeKey(key);
1251
1359
  cache.data[encodedKey] = Object.assign({ key, data }, options);
1360
+ updateCacheIndex(cache.data, encodedKey);
1252
1361
  return true;
1253
1362
  };
1254
1363
 
@@ -1333,15 +1442,14 @@ const dropFromCache = (key, exact = false) => {
1333
1442
  return false;
1334
1443
  log('cache/api/dropFromCache', { key, exact });
1335
1444
  if (!exact) {
1336
- return Object.keys(cache.data)
1337
- .map(stringKey => decodeKey(stringKey))
1338
- .filter(candidate => partialMatch(key, candidate))
1339
- .map(filteredKey => dropFromCache(filteredKey, true))
1445
+ return getMatchingCacheKeys(cache.data, key)
1446
+ .map(({ key: filteredKey }) => dropFromCache(filteredKey, true))
1340
1447
  .every(returned => returned);
1341
1448
  }
1342
1449
  const encodedKey = encodeKey(key);
1343
1450
  if (encodedKey in cache.data) {
1344
1451
  delete cache.data[encodedKey];
1452
+ removeFromCacheIndex(cache.data, encodedKey);
1345
1453
  return true;
1346
1454
  }
1347
1455
  return false;
@@ -3746,13 +3854,20 @@ const getUserMarker = async () => {
3746
3854
  return { data: latestUserMarker, cachedAt };
3747
3855
  };
3748
3856
 
3857
+ /** Internal model lookup; deliberately excluded from the public Cache API. @hidden */
3858
+ const queryCacheByProperty = (prefix, property, value) => {
3859
+ const { cache } = getActiveClient();
3860
+ if (!cache)
3861
+ return;
3862
+ return getCacheEntriesByProperty(cache.data, prefix, property, value);
3863
+ };
3864
+
3749
3865
  const getMessageFromMainDB = (messageId) => {
3750
- var _a, _b;
3866
+ var _a, _b, _c;
3751
3867
  const message = (_a = pullFromCache(['message', 'get', messageId])) === null || _a === void 0 ? void 0 : _a.data;
3752
3868
  if (message)
3753
3869
  return message;
3754
- const messages = queryCache(['message', 'get']);
3755
- return (_b = messages === null || messages === void 0 ? void 0 : messages.find(({ data }) => data.messageId === messageId)) === null || _b === void 0 ? void 0 : _b.data;
3870
+ return (_c = (_b = queryCacheByProperty(['message', 'get'], 'messageId', messageId)) === null || _b === void 0 ? void 0 : _b[0]) === null || _c === void 0 ? void 0 : _c.data;
3756
3871
  };
3757
3872
 
3758
3873
  /** @hidden */
@@ -3894,7 +4009,8 @@ function convertFromRaw$2(_a) {
3894
4009
 
3895
4010
  const mergePayloadWithLocal = (payload) => {
3896
4011
  var _a, _b, _c;
3897
- const localMessage = (_b = (_a = queryCache(['message', 'get'])) === null || _a === void 0 ? void 0 : _a.find(({ data }) => data.messageId === payload.messageId)) === null || _b === void 0 ? void 0 : _b.data;
4012
+ // Cache keys may be local referenceIds even after a server messageId is assigned.
4013
+ const localMessage = (_b = (_a = queryCacheByProperty(['message', 'get'], 'messageId', payload.messageId)) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.data;
3898
4014
  if (localMessage) {
3899
4015
  return Object.assign(Object.assign(Object.assign({}, localMessage), payload), {
3900
4016
  // NOTE: referenceId is missing in the some payload event. If we have local message data with referenceId, use it instead.
@@ -5461,9 +5577,9 @@ const channelLinkedObject = (channel) => {
5461
5577
  var _a;
5462
5578
  let previewMembers = [];
5463
5579
  if (['conversation', 'community'].includes(channel.type)) {
5464
- const channelUsers = queryCache(['channelUsers', 'get']);
5580
+ const channelUsers = queryCacheByProperty(['channelUsers', 'get'], 'channelId', channel.channelId);
5465
5581
  if (channelUsers && (channelUsers === null || channelUsers === void 0 ? void 0 : channelUsers.length) > 0) {
5466
- previewMembers = ((_a = channelUsers === null || channelUsers === void 0 ? void 0 : channelUsers.filter(({ data }) => data.channelId === channel.channelId && data.membership !== 'none')) !== null && _a !== void 0 ? _a : [])
5582
+ previewMembers = ((_a = channelUsers === null || channelUsers === void 0 ? void 0 : channelUsers.filter(({ data }) => data.membership !== 'none')) !== null && _a !== void 0 ? _a : [])
5467
5583
  // sort in ascending order by userInternalId
5468
5584
  .sort((a, b) => a.data.userInternalId.localeCompare(b.data.userInternalId))
5469
5585
  // Select only first 4 members
@@ -14026,7 +14142,7 @@ const getWatchSessionStorage = () => {
14026
14142
  return storageInstance;
14027
14143
  };
14028
14144
 
14029
- const privateKey = "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDHo80SecH7FuF2\nhFYnb+l26/VN8UMLXAQFLnxciNTEwkGVFMpdezlH8rU2HtUJL4RETogbAOLVY0XM\njs6sPn8G1nALmh9qeDpUtVqFOVtBHxEZ910TLOtQiunjqJKO5nWdqZ71EC3OFluR\niGQkO84BiIFbv37ub7xl3S8XarbtKoLcyVpkDHi+1wx1pgCAn6gtBUgckPL5NR8j\nLseabl3HAXQfhTCKo4tmOFM2Dxwl1IUMmIJrJg/aIU/U0tj/1Eoo7mG0JcNWX19l\nW3EecCbi0ncCJOrkUdwlBrcjaMayaX/ubEwyUeTGiLdyc4L3GRLHjyK8xgVNXRMH\nbZWJ2a5NAgMBAAECggEASxuE+35zTFO/XydKgmvIGcWL9FbgMlXb7Vcf0nBoG945\nbiz0NVc2paraIhJXc608xbYF3qLmtAE1MVBI0ORyRdBHNxY024l/6H6SH60Ed+uI\nM4ysp5ourY6Vj+DLwpdRiI9YDjqYAQDIUmhNxJP7XPhOMoZI6st+xZQBM34ic/bv\nAMSJm9OZphSp3+qXVkFZztr2mxD2EZSJJLYxi8BCdgM2qhazalbcJ6zDKHCZWVWm\n8RRxDGldyMb/237JxETzP40tAlzOZDmBAbUgEnurDJ93RVDIE3rbZUshwgeQd18a\nem096mWgvB1AIKYgsTAR3pw+V19YWAjq/glP6fz8wQKBgQD/oQq+ukKF0PRgBeM5\ngeTjSwsdGppQLmf5ndujvoiz/TpdjDEPu6R8kigQr1rG2t4K/yfdZoI8RdmJD1al\n3Q7N9hofooSy4rj6E3txzWZCHJjHad2cnCp/O26HiReGAl7wTcfTmNdiFHhZQzm5\nJBkvWAiwuvQMNfEbnXxw6/vIDwKBgQDH7fX8gsc77JLvAWgp1MaQN/sbqVb6JeT1\nFQfR8E/WFCSmzQBtNzd5KgYuCeelwr/8DyYytvN2BzCYZXp73gI1jF3YlW5jVn74\nOY6TwQ095digwo6Z0yuxopdIOApKgAkL9PRKgNrqAf3NAyMua6lOGifzjDojC3KU\nfylQmxMn4wKBgHp2B9O/H0dEBw5JQ8W0+JX6yWQz7mEjGiR2/1W+XXb8hQ1zr709\nw1r6Gb+EghRpnZ3fBpYGGbYOMFx8wKHM+N6qW3F0ReX8v2juFGE8aRSa5oYBrWzt\nU16Idjbv8hj84cZ1PJmdyvDtpYn9rpWHOZl4rxEbPvbqkIsOMyNVqdT5AoGAOSge\nmwIIU2le2FVeohbibXiToWTYKMuMmURZ5/r72AgKMmWJKbAPe+Q3wBG01/7FRBpQ\noU8Ma0HC8s6QJbliiEyIx9JwrJWd1vkdecBHONrtA4ibm/5zD2WcOllLF+FitLhi\n3qnX6+6F0IaFGFBPJrTzlv0P4dTz/OAdv52V7GECgYEA2TttOKBAqWllgOaZOkql\nLVMJVmgR7s6tLi1+cEP8ZcapV9aRbRzTAKXm4f8AEhtlG9F9kCOvHYCYGi6JaiWJ\nZkHjeex3T+eE6Di6y5Bm/Ift5jtVhJ4jCVwHOKTMej79NPUFTJfv8hCo29haBDv6\nRXFrv+T21KCcw8k3sJeJWWQ=\n-----END PRIVATE KEY-----";
14145
+ const privateKey = "MIIEpQIBAAKCAQEAwAEc/oZgYIvKSUG/C3mONYLR4ZPgAjMEX4bJ+xqqakUDRtqlNO+eZs2blQ1Ko0DBkqPExyQezvjibH5W2UZBV5RaBTlTcNVKTToMBEGesAfaEcM3qUyQHxdbFYZv6P4sb14dcwxTQ8usmaV8ooiR1Fcaso5ZWYcZ8Hb46FbQ7OoVumsBtPWwfZ4f003o5VCl6AIM6lcLv9UDLlFVYhE+PeXpRHtfWlGqxMvqC9oinlwhL6nWv6VjQXW4nhcib72dPBzfHT7k/PMKto2SxALYdb68ENiAGuJLWi3AUHSyYCJK2w7wIlWfJUAI0v26ub10IpExr6D5QuW2577jjP93iwIDAQABAoIBAFWfqXhwIIatkFY+9Z1+ZcbDQimgsmMIsUiQaX6Lk7e0cxOj6czDlxYtVtaPiNtow2pLkjNkjkCqiP7tEHnwdK9DvylZOTa2R15NJpK3WLcTqVIGhsn/FL5owfvFah6zSsmXZParZm5zY9NZE03ALZhOB9/cz0e3kf/EbpfeL2mW7MApyiUt5i09ycchroOpcWp73ipIxvgigtZyUGFmsQicWhUs28F0D7w4Qfk76yG3nqXeb+BAMhCaIaa/k/aAxhiZG/ygEQWQrcC8gfe+jyicMAQPDEVS9YuUMGsLjIjKuVLZzp2xirQnhc2i2zVNEIvG6soprPOBEMQugzrtX5ECgYEA3b7KAbBIbDl1e4ZSCWhHdHkiWVZHaopsR/LhqDDNhXjWjq3AesgV6k0j9EdziMn/HmmOso0bz99GTV3JZf4A9ztTLumJlkHbdVtlgOqSjrFLj12rH9KXTheyIhWSpUmm8+WB1xasFbqpvJaGo7F3pd2Fqj1XR4mp5BO7c/t7LJ0CgYEA3aouEzXQ9THRKYocdfY69EI1Il1t/d/RSqqd9BxEjxBgxkM13ZiYIn/R4WW/nCUrlmhxG44Aa2Gob4Ahfsui2xKTg/g/3Zk/rAxAEGkfOLGoenaJMD41fH4wUq3FRYwkvnaMb9Hd6f/TlBHslIRa2NN58bSBGJCyBP2b59+2+EcCgYEAixDVRXvV37GlYUOa/XVdosk5Zoe6oDGRuQm0xbNdoUBoZvDHDvme7ONWEiQha/8qtVsD+CyQ7awcPfb8kK9c0bBt+bTS6d4BkTcxkEkMgtrkBVR8Nqfu5jXsLH4VCv4G61zbMhZw8+ut+az5YX2yCN7Frj9sFlxapMRPQmzMEe0CgYEAumsAzM8ZqNv4mAK65Mnr0rhLj1cbxcKRdUYACOgtEFQpzxN/HZnTeFAe5nx3pI3uFlRHq3DFEYnT6dHMWaJQmAULYpVIwMi9L6gtyJ9fzoI6uqMtxRDMUqKdaSsTGOY/kJ6KhQ/unXi1K3XXjR+yd1+C0q+HUm1+CYxvrZYLfskCgYEArsEy+IQOiqniJ0NE2vVUF+UK/IRZaic9YKcpov5Ot7Vvzm/MnnW4N1ljVskocETBWMmPUvNSExVjPebi+rxd8fa5kY8BJScPTzMFbunZn/wjtGdcM10qdlVQ9doG61A/9P3ezFKCfS4AvF/H/59LcSx2Bh28fp3/efiVIOpVd4Y=";
14030
14146
  /*
14031
14147
  * The crypto algorithm used for importing key and signing string
14032
14148
  */
@@ -27743,8 +27859,40 @@ getCommentByIds.locally = (commentIds) => {
27743
27859
  };
27744
27860
  };
27745
27861
 
27862
+ const GIF_OPTIONAL_KEYS = ['width', 'height'];
27863
+ /*
27864
+ * The server refuses a GIF attachment that carries `null` or any key it does not know, so the
27865
+ * request keeps `type`, `url` and only the optional fields that have a value. The SDK does not
27866
+ * check the values themselves: the server answers 400 for a bad one.
27867
+ */
27868
+ const toGifAttachmentPayload = (gif) => {
27869
+ const payload = { type: 'gif', url: gif.url };
27870
+ GIF_OPTIONAL_KEYS.forEach(key => {
27871
+ const value = gif[key];
27872
+ if (value !== undefined && value !== null)
27873
+ Object.assign(payload, { [key]: value });
27874
+ });
27875
+ return payload;
27876
+ };
27877
+ /* Builds each GIF from its known keys; every other attachment is sent as the caller gave it. */
27878
+ const toAttachmentsPayload = (attachments) => attachments.map(attachment => attachment.type === 'gif'
27879
+ ? toGifAttachmentPayload(attachment)
27880
+ : attachment);
27881
+
27882
+ /*
27883
+ * The data types the server lists for a comment, known before it answers: one per attachment
27884
+ * type, plus `text` when there is text. Sorted, as the server sorts them.
27885
+ */
27886
+ const commentDataTypesOf = (text, attachments) => {
27887
+ const types = new Set((attachments !== null && attachments !== void 0 ? attachments : []).map(attachment => attachment.type));
27888
+ if (text)
27889
+ types.add('text');
27890
+ return [...types].sort();
27891
+ };
27892
+
27746
27893
  const getLocalCommentId = () => uuid();
27747
27894
  const createCommentOptimistic = (bundle) => {
27895
+ var _a;
27748
27896
  const client = getActiveClient();
27749
27897
  if (!client.cache)
27750
27898
  return;
@@ -27779,6 +27927,7 @@ const createCommentOptimistic = (bundle) => {
27779
27927
  targetId: '',
27780
27928
  targetType: 'community',
27781
27929
  dataType: 'text',
27930
+ dataTypes: commentDataTypesOf((_a = bundle.data) === null || _a === void 0 ? void 0 : _a.text, bundle.attachments),
27782
27931
  syncState: "syncing" /* Amity.SyncState.Syncing */,
27783
27932
  // In a gated community the optimistic object stays out of public collections until the
27784
27933
  // response settles the status; the author's own view still updates through the local event
@@ -27825,12 +27974,15 @@ const createCommentOptimistic = (bundle) => {
27825
27974
  const createComment = async (bundle, isOptimistic = true) => {
27826
27975
  const client = getActiveClient();
27827
27976
  client.log('comment/createComment', Object.assign(Object.assign({}, bundle), { isOptimistic }));
27977
+ // A GIF is sent with its known keys only; the server refuses `null` and unknown keys.
27978
+ const request = bundle.attachments
27979
+ ? Object.assign(Object.assign({}, bundle), { attachments: toAttachmentsPayload(bundle.attachments) }) : bundle;
27828
27980
  // Without a local comment the server assigns the id; with one, the same id travels through the
27829
27981
  // optimistic object, the response and every realtime event so each step recognises it.
27830
- const optimisticData = isOptimistic ? createCommentOptimistic(bundle) : undefined;
27982
+ const optimisticData = isOptimistic ? createCommentOptimistic(request) : undefined;
27831
27983
  const commentId = optimisticData === null || optimisticData === void 0 ? void 0 : optimisticData.commentId;
27832
27984
  try {
27833
- const { data: payload } = await client.http.post('/api/v3/comments', Object.assign(Object.assign({}, bundle), { commentId }));
27985
+ const { data: payload } = await client.http.post('/api/v3/comments', Object.assign(Object.assign({}, request), { commentId }));
27834
27986
  // BE always returns an array of comments If it got record 0 from BE it might have a problem on creation logic
27835
27987
  if (payload.comments.length === 0)
27836
27988
  throw new Error('Comment not created');
@@ -27923,9 +28075,16 @@ const createComment = async (bundle, isOptimistic = true) => {
27923
28075
  * const updated = await CommentRepository.updateComment(commentId, {
27924
28076
  * data: { text: 'hello world' }
27925
28077
  * })
28078
+ *
28079
+ * // Replace the GIF, or remove it and keep the text
28080
+ * await CommentRepository.updateComment(commentId, {
28081
+ * attachments: [{ type: 'gif', url: 'https://media.giphy.com/media/l0MYt5jPR6QX5pnqM/giphy.gif' }],
28082
+ * })
28083
+ * await CommentRepository.updateComment(commentId, { attachments: [] })
27926
28084
  * ```
27927
28085
  *
27928
- * Updates an {@link Amity.Comment}
28086
+ * Updates an {@link Amity.Comment}. `attachments` replaces the current ones, `[]` removes them,
28087
+ * and leaving `attachments` out keeps them as they are.
27929
28088
  *
27930
28089
  * @param commentId The ID of the {@link Amity.Comment} to edit
27931
28090
  * @param patch The patch data to apply
@@ -27939,7 +28098,10 @@ const updateComment = async (commentId, patch) => {
27939
28098
  const client = getActiveClient();
27940
28099
  client.log('user/updateComment', patch);
27941
28100
  const previous = (_a = pullFromCache(['comment', 'get', commentId])) === null || _a === void 0 ? void 0 : _a.data;
27942
- const { data: payload } = await client.http.put(`/api/v3/comments/${encodeURIComponent(commentId)}`, patch);
28101
+ // A GIF is sent with its known keys only; the server refuses `null` and unknown keys.
28102
+ const body = patch.attachments
28103
+ ? Object.assign(Object.assign({}, patch), { attachments: toAttachmentsPayload(patch.attachments) }) : patch;
28104
+ const { data: payload } = await client.http.put(`/api/v3/comments/${encodeURIComponent(commentId)}`, body);
27943
28105
  const data = prepareCommentPayload(payload);
27944
28106
  const updated = data.comments.find(comment => comment.commentId === commentId);
27945
28107
  const cachedAt = client.cache && Date.now();
@@ -30406,6 +30568,19 @@ getPostByIds.locally = (postIds) => {
30406
30568
  };
30407
30569
  };
30408
30570
 
30571
+ /*
30572
+ * The `attachments` a post create or edit sends. A GIF goes with its known keys only and never
30573
+ * with product tags (both a 400). A file takes its product tags from the map, as before.
30574
+ */
30575
+ const preparePostAttachments = (attachments, attachmentProductTags) => attachments === null || attachments === void 0 ? void 0 : attachments.map(attachment => {
30576
+ if (attachment.type === 'gif') {
30577
+ return toGifAttachmentPayload(attachment);
30578
+ }
30579
+ if (!attachmentProductTags || !attachment.fileId)
30580
+ return attachment;
30581
+ return Object.assign(Object.assign({}, attachment), { productTags: attachmentProductTags.get(attachment.fileId) });
30582
+ });
30583
+
30409
30584
  /* begin_public_function
30410
30585
  id: post.create.text_post, post.create.image_post, post.create.file_post, post.create.video_post, post.create.poll_post, post.create.livestream_post, post.create.custom_post
30411
30586
  */
@@ -30435,17 +30610,7 @@ const createPost = async (bundle) => {
30435
30610
  delete bundle.dataType;
30436
30611
  }
30437
30612
  const { attachments, attachmentProductTags } = bundle, rest = __rest(bundle, ["attachments", "attachmentProductTags"]);
30438
- const processedAttachments = attachments && attachments.length > 0 && bundle.attachmentProductTags
30439
- ? attachments.map(attachment => {
30440
- var _a;
30441
- /* c8 ignore next */
30442
- const productTags = (_a = bundle.attachmentProductTags) === null || _a === void 0 ? void 0 : _a.get(attachment.fileId);
30443
- if (productTags)
30444
- return Object.assign(Object.assign({}, attachment), { productTags });
30445
- /* c8 ignore next */
30446
- return attachment;
30447
- })
30448
- : attachments;
30613
+ const processedAttachments = preparePostAttachments(attachments, attachmentProductTags);
30449
30614
  const { data: payload } = await client.http.post('/api/v4/posts', Object.assign(Object.assign({}, rest), { attachments: processedAttachments }));
30450
30615
  fireEvent('post.created', payload);
30451
30616
  const data = preparePostPayload(payload);
@@ -30471,7 +30636,9 @@ const createPost = async (bundle) => {
30471
30636
  * })
30472
30637
  * ```
30473
30638
  *
30474
- * Updates an {@link Amity.Post}
30639
+ * Updates an {@link Amity.Post}. `attachments` is the full list to keep: a GIF is matched by its
30640
+ * `url`, so send each kept GIF back with its link and size as read from `childrenPosts`; an
30641
+ * attachment left out is deleted, `[]` removes them all, and leaving `attachments` out keeps them.
30475
30642
  *
30476
30643
  * @param postId The ID of the {@link Amity.Post} to edit
30477
30644
  * @param patch The patch data to apply
@@ -30484,17 +30651,7 @@ const editPost = async (postId, patch) => {
30484
30651
  const client = getActiveClient();
30485
30652
  client.log('user/editPost', patch);
30486
30653
  const { attachments } = patch;
30487
- const processedAttachments = attachments && attachments.length > 0 && patch.attachmentProductTags
30488
- ? attachments.map(attachment => {
30489
- var _a;
30490
- /* c8 ignore next */
30491
- const productTags = (_a = patch.attachmentProductTags) === null || _a === void 0 ? void 0 : _a.get(attachment.fileId);
30492
- if (productTags)
30493
- return Object.assign(Object.assign({}, attachment), { productTags });
30494
- /* c8 ignore next */
30495
- return attachment;
30496
- })
30497
- : attachments;
30654
+ const processedAttachments = preparePostAttachments(attachments, patch.attachmentProductTags);
30498
30655
  const { data: payload } = await client.http.put(`/api/v4/posts/${encodeURIComponent(postId)}`, Object.assign(Object.assign({}, patch), { attachments: processedAttachments }));
30499
30656
  const data = prepareMembershipPayload(payload, 'communityUsers');
30500
30657
  const cachedAt = client.cache && Date.now();
@@ -30978,11 +31135,14 @@ const createAudioPost = async (bundle) => {
30978
31135
  * { fileId: "file1", type: "image" },
30979
31136
  * { fileId: "file2", type: "video" },
30980
31137
  * { fileId: "file3", type: "audio" },
30981
- * { fileId: "file4", type: "file" }
31138
+ * { fileId: "file4", type: "file" },
31139
+ * { type: "gif", url: "https://media.giphy.com/media/l0MYt5jPR6QX5pnqM/giphy.gif", width: 480, height: 270 }
30982
31140
  * ],
30983
31141
  * })
30984
31142
  * ```
30985
31143
  *
31144
+ * A post holds 1 to 10 attachments. A GIF is a link, not a file, and takes no product tags.
31145
+ *
30986
31146
  * Creates an {@link Amity.Post}
30987
31147
  *
30988
31148
  * @param bundle The data necessary to create a new {@link Amity.Post}
@@ -30996,17 +31156,7 @@ const createMixedMediaPost = async (bundle) => {
30996
31156
  const client = getActiveClient();
30997
31157
  client.log('post/createMixedMediaPost', bundle);
30998
31158
  const { attachments, attachmentProductTags } = bundle, rest = __rest(bundle, ["attachments", "attachmentProductTags"]);
30999
- const processedAttachments = attachments && attachments.length > 0 && bundle.attachmentProductTags
31000
- ? attachments.map(attachment => {
31001
- var _a;
31002
- /* c8 ignore next */
31003
- const productTags = (_a = bundle.attachmentProductTags) === null || _a === void 0 ? void 0 : _a.get(attachment.fileId);
31004
- if (productTags)
31005
- return Object.assign(Object.assign({}, attachment), { productTags });
31006
- /* c8 ignore next */
31007
- return attachment;
31008
- })
31009
- : /* c8 ignore next */ attachments;
31159
+ const processedAttachments = preparePostAttachments(attachments, attachmentProductTags);
31010
31160
  const { data: payload } = await client.http.post('/api/v4/posts', Object.assign(Object.assign({}, rest), { attachments: processedAttachments }));
31011
31161
  fireEvent('post.created', payload);
31012
31162
  const data = preparePostPayload(payload);
@@ -31523,6 +31673,10 @@ class PostLiveCollectionController extends LiveCollectionController {
31523
31673
  *
31524
31674
  * Observe all mutations on a list of {@link Amity.Post} for a given target object
31525
31675
  *
31676
+ * GIF posts come back on every API version. This query is on v5, so `dataTypes: ['gif']` filters
31677
+ * them; a post with GIFs beside other media is `mixed` and is hidden unless
31678
+ * `includeMixedStructure` is `true`.
31679
+ *
31526
31680
  * @param params.targetType the type of the target
31527
31681
  * @param params.targetId the ID of the target
31528
31682
  * @param callback the function to call when new data are available