@amityco/ts-sdk-react-native 7.26.1-6101ded.0 → 7.26.1-9f3ac9f9.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.
package/dist/index.esm.js CHANGED
@@ -355,6 +355,12 @@ const CACHE_LIFESPAN_TOMBSTONE = 3 * MINUTE; // 3 minutes
355
355
  const normalize = (source) => Object.keys(source)
356
356
  .sort()
357
357
  .reduce((acc, key) => (Object.assign(Object.assign({}, acc), { [key]: source[key] })), {});
358
+ /**
359
+ * Keys already reported by encodeKey, so one recurring bad payload does not
360
+ * flood the console — a null segment usually arrives on a realtime event that
361
+ * repeats.
362
+ */
363
+ const reportedNullKeys = new Set();
358
364
  /**
359
365
  * Encodes a given {@link Amity.CacheKey} to a plain string
360
366
  *
@@ -364,7 +370,26 @@ const normalize = (source) => Object.keys(source)
364
370
  * @category Cache
365
371
  * @hidden
366
372
  */
367
- const encodeKey = (key) => JSON.stringify(key, (_, val) => (typeof val === 'object' ? normalize(val) : val));
373
+ const encodeKey = (key) => JSON.stringify(key, (_, val) => {
374
+ // `typeof null` is `'object'`, so a nullish segment would reach normalize()
375
+ // and throw on Object.keys(null) — taking down whichever cache read built
376
+ // the key. Amity.Serializable does not admit null in the first place, so a
377
+ // null here is a payload that broke its own contract: encode it as null and
378
+ // let the miss be a miss.
379
+ if (val === null) {
380
+ // Diagnostic: the guard makes the key harmless, but it hides which
381
+ // caller built it. Printing the whole key names the domain and the shape
382
+ // ('post'/'get'/null vs something else), which is the one thing needed
383
+ // to find the producer.
384
+ const printed = JSON.stringify(key);
385
+ if (!reportedNullKeys.has(printed)) {
386
+ reportedNullKeys.add(printed);
387
+ console.warn('[AmitySDK] null segment in cache key', printed);
388
+ }
389
+ return val;
390
+ }
391
+ return typeof val === 'object' ? normalize(val) : val;
392
+ });
368
393
  /**
369
394
  * Decodes a string back into a {@link Amity.CacheKey}
370
395
 
@@ -13054,6 +13079,21 @@ const productTagLinkedObject = (productTag) => {
13054
13079
  return Object.assign(Object.assign({}, productTag), { product: internalProduct ? productLinkedObject(internalProduct) : undefined });
13055
13080
  };
13056
13081
 
13082
+ const fileLinkedObject = (file) => {
13083
+ var _a, _b, _c;
13084
+ if (!file)
13085
+ return file;
13086
+ if (file.type === 'video') {
13087
+ const video = (_b = (_a = file.attributes) === null || _a === void 0 ? void 0 : _a.metadata) === null || _b === void 0 ? void 0 : _b.video;
13088
+ return Object.assign(Object.assign({}, file), { getWidth: () => { var _a; return (_a = video === null || video === void 0 ? void 0 : video.width) !== null && _a !== void 0 ? _a : 0; }, getHeight: () => { var _a; return (_a = video === null || video === void 0 ? void 0 : video.height) !== null && _a !== void 0 ? _a : 0; }, getRotation: () => { var _a; return (_a = video === null || video === void 0 ? void 0 : video.rotation) !== null && _a !== void 0 ? _a : 0; } });
13089
+ }
13090
+ if (file.type === 'image') {
13091
+ const metadata = (_c = file.attributes) === null || _c === void 0 ? void 0 : _c.metadata;
13092
+ return Object.assign(Object.assign({}, file), { getWidth: () => { var _a; return (_a = metadata === null || metadata === void 0 ? void 0 : metadata.width) !== null && _a !== void 0 ? _a : 0; }, getHeight: () => { var _a; return (_a = metadata === null || metadata === void 0 ? void 0 : metadata.height) !== null && _a !== void 0 ? _a : 0; } });
13093
+ }
13094
+ return file;
13095
+ };
13096
+
13057
13097
  const postLinkedObject = (post) => {
13058
13098
  return shallowClone(post, {
13059
13099
  childrenPosts: post.children
@@ -13092,6 +13132,11 @@ const postLinkedObject = (post) => {
13092
13132
  .filter(Boolean) || []);
13093
13133
  },
13094
13134
  get creator() {
13135
+ // The id is checked for a value, not just for presence: a payload can
13136
+ // carry the field as null, and a null segment in a cache key throws
13137
+ // while encoding it rather than simply missing the cache.
13138
+ if (!post.postedUserId)
13139
+ return;
13095
13140
  const cacheData = pullFromCache(['user', 'get', post.postedUserId]);
13096
13141
  if (!(cacheData === null || cacheData === void 0 ? void 0 : cacheData.data))
13097
13142
  return;
@@ -13099,6 +13144,8 @@ const postLinkedObject = (post) => {
13099
13144
  },
13100
13145
  get targetCommunity() {
13101
13146
  var _a;
13147
+ if (!post.targetId)
13148
+ return;
13102
13149
  const communityCache = (_a = pullFromCache([
13103
13150
  'community',
13104
13151
  'get',
@@ -13110,36 +13157,43 @@ const postLinkedObject = (post) => {
13110
13157
  },
13111
13158
  getImageInfo() {
13112
13159
  var _a, _b;
13113
- return isAmityImagePost(post)
13114
- ? (_b = pullFromCache(['file', 'get', (_a = post === null || post === void 0 ? void 0 : post.data) === null || _a === void 0 ? void 0 : _a.fileId])) === null || _b === void 0 ? void 0 : _b.data
13115
- : undefined;
13160
+ if (!isAmityImagePost(post) || !((_a = post.data) === null || _a === void 0 ? void 0 : _a.fileId))
13161
+ return undefined;
13162
+ return fileLinkedObject((_b = pullFromCache(['file', 'get', post.data.fileId])) === null || _b === void 0 ? void 0 : _b.data);
13116
13163
  },
13117
13164
  getVideoInfo() {
13118
13165
  var _a, _b, _c;
13119
- return isAmityVideoPost(post)
13120
- ? (_c = pullFromCache(['file', 'get', (_b = (_a = post === null || post === void 0 ? void 0 : post.data) === null || _a === void 0 ? void 0 : _a.videoFileId) === null || _b === void 0 ? void 0 : _b.original])) === null || _c === void 0 ? void 0 : _c.data
13121
- : undefined;
13166
+ const originalFileId = isAmityVideoPost(post) ? (_b = (_a = post.data) === null || _a === void 0 ? void 0 : _a.videoFileId) === null || _b === void 0 ? void 0 : _b.original : undefined;
13167
+ if (!originalFileId)
13168
+ return undefined;
13169
+ return fileLinkedObject((_c = pullFromCache(['file', 'get', originalFileId])) === null || _c === void 0 ? void 0 : _c.data);
13122
13170
  },
13123
13171
  getVideoThumbnailInfo() {
13124
13172
  var _a, _b;
13125
- return isAmityVideoPost(post)
13126
- ? (_b = pullFromCache(['file', 'get', (_a = post === null || post === void 0 ? void 0 : post.data) === null || _a === void 0 ? void 0 : _a.thumbnailFileId])) === null || _b === void 0 ? void 0 : _b.data
13127
- : undefined;
13173
+ // `isAmityVideoPost` proves the field is *present* — it tests
13174
+ // `'thumbnailFileId' in post.data` — and presence is not a value. The
13175
+ // server sends the field as null until it has finished transcoding the
13176
+ // video, so a just-published post reaches here with a null id and used
13177
+ // to build the cache key ['file', 'get', null].
13178
+ const thumbnailFileId = isAmityVideoPost(post) ? (_a = post.data) === null || _a === void 0 ? void 0 : _a.thumbnailFileId : undefined;
13179
+ if (!thumbnailFileId)
13180
+ return undefined;
13181
+ return fileLinkedObject((_b = pullFromCache(['file', 'get', thumbnailFileId])) === null || _b === void 0 ? void 0 : _b.data);
13128
13182
  },
13129
13183
  getFileInfo() {
13130
13184
  var _a, _b;
13131
- return isAmityFilePost(post)
13132
- ? (_b = pullFromCache(['file', 'get', (_a = post === null || post === void 0 ? void 0 : post.data) === null || _a === void 0 ? void 0 : _a.fileId])) === null || _b === void 0 ? void 0 : _b.data
13133
- : undefined;
13185
+ if (!isAmityFilePost(post) || !((_a = post.data) === null || _a === void 0 ? void 0 : _a.fileId))
13186
+ return undefined;
13187
+ return (_b = pullFromCache(['file', 'get', post.data.fileId])) === null || _b === void 0 ? void 0 : _b.data;
13134
13188
  },
13135
13189
  getLivestreamInfo() {
13136
13190
  var _a, _b;
13137
- if (!isAmityLivestreamPost(post))
13191
+ if (!isAmityLivestreamPost(post) || !((_a = post.data) === null || _a === void 0 ? void 0 : _a.streamId))
13138
13192
  return;
13139
13193
  const cache = (_b = pullFromCache([
13140
13194
  'stream',
13141
13195
  'get',
13142
- (_a = post === null || post === void 0 ? void 0 : post.data) === null || _a === void 0 ? void 0 : _a.streamId,
13196
+ post.data.streamId,
13143
13197
  ])) === null || _b === void 0 ? void 0 : _b.data;
13144
13198
  if (!cache)
13145
13199
  return;
@@ -13147,30 +13201,30 @@ const postLinkedObject = (post) => {
13147
13201
  },
13148
13202
  getPollInfo() {
13149
13203
  var _a, _b;
13150
- if (!isAmityPollPost(post))
13204
+ if (!isAmityPollPost(post) || !((_a = post.data) === null || _a === void 0 ? void 0 : _a.pollId))
13151
13205
  return;
13152
- const cache = (_b = pullFromCache(['poll', 'get', (_a = post === null || post === void 0 ? void 0 : post.data) === null || _a === void 0 ? void 0 : _a.pollId])) === null || _b === void 0 ? void 0 : _b.data;
13206
+ const cache = (_b = pullFromCache(['poll', 'get', post.data.pollId])) === null || _b === void 0 ? void 0 : _b.data;
13153
13207
  if (!cache)
13154
13208
  return;
13155
13209
  return pollLinkedObject(cache);
13156
13210
  },
13157
13211
  getClipInfo() {
13158
13212
  var _a, _b;
13159
- return isAmityClipPost(post)
13160
- ? (_b = pullFromCache(['file', 'get', (_a = post === null || post === void 0 ? void 0 : post.data) === null || _a === void 0 ? void 0 : _a.fileId])) === null || _b === void 0 ? void 0 : _b.data
13161
- : undefined;
13213
+ if (!isAmityClipPost(post) || !((_a = post.data) === null || _a === void 0 ? void 0 : _a.fileId))
13214
+ return undefined;
13215
+ return (_b = pullFromCache(['file', 'get', post.data.fileId])) === null || _b === void 0 ? void 0 : _b.data;
13162
13216
  },
13163
13217
  getAudioInfo() {
13164
13218
  var _a, _b;
13165
- return isAmityAudioPost(post)
13166
- ? (_b = pullFromCache(['file', 'get', (_a = post === null || post === void 0 ? void 0 : post.data) === null || _a === void 0 ? void 0 : _a.fileId])) === null || _b === void 0 ? void 0 : _b.data
13167
- : undefined;
13219
+ if (!isAmityAudioPost(post) || !((_a = post.data) === null || _a === void 0 ? void 0 : _a.fileId))
13220
+ return undefined;
13221
+ return (_b = pullFromCache(['file', 'get', post.data.fileId])) === null || _b === void 0 ? void 0 : _b.data;
13168
13222
  },
13169
13223
  getRoomInfo() {
13170
13224
  var _a, _b;
13171
- if (!isAmityRoomPost(post))
13225
+ if (!isAmityRoomPost(post) || !((_a = post.data) === null || _a === void 0 ? void 0 : _a.roomId))
13172
13226
  return;
13173
- const room = (_b = pullFromCache(['room', 'get', (_a = post === null || post === void 0 ? void 0 : post.data) === null || _a === void 0 ? void 0 : _a.roomId])) === null || _b === void 0 ? void 0 : _b.data;
13227
+ const room = (_b = pullFromCache(['room', 'get', post.data.roomId])) === null || _b === void 0 ? void 0 : _b.data;
13174
13228
  return room ? roomLinkedObject(room) : undefined;
13175
13229
  },
13176
13230
  getEventInfo() {
@@ -13199,6 +13253,8 @@ const postLinkedObject = (post) => {
13199
13253
  // full linked-object surface — including RSVP methods and `event.post` —
13200
13254
  // is available via EventRepository.getEvent(eventId).
13201
13255
  return Object.assign(Object.assign({}, event), { get creator() {
13256
+ if (!event.userId)
13257
+ return undefined;
13202
13258
  const cacheData = pullFromCache(['user', 'get', event.userId]);
13203
13259
  if (!(cacheData === null || cacheData === void 0 ? void 0 : cacheData.data))
13204
13260
  return undefined;
@@ -14114,6 +14170,7 @@ const eventLinkedObject = (event) => {
14114
14170
  };
14115
14171
 
14116
14172
  const LinkedObject = {
14173
+ file: fileLinkedObject,
14117
14174
  ad: adLinkedObject,
14118
14175
  comment: commentLinkedObject,
14119
14176
  post: postLinkedObject,
@@ -15461,7 +15518,7 @@ const getFile = async (fileId) => {
15461
15518
  if (client.cache)
15462
15519
  ingestInCache({ files: [data] }, { cachedAt });
15463
15520
  return {
15464
- data,
15521
+ data: fileLinkedObject(data),
15465
15522
  cachedAt,
15466
15523
  };
15467
15524
  };
@@ -15488,7 +15545,7 @@ getFile.locally = (fileId) => {
15488
15545
  if (!cached)
15489
15546
  return;
15490
15547
  return {
15491
- data: cached.data,
15548
+ data: fileLinkedObject(cached.data),
15492
15549
  cachedAt: cached.cachedAt,
15493
15550
  };
15494
15551
  };
@@ -15625,7 +15682,7 @@ const uploadVideo = async (formData, feedType, onProgress) => {
15625
15682
  if (client.cache)
15626
15683
  ingestInCache({ files: data }, { cachedAt });
15627
15684
  return {
15628
- data,
15685
+ data: data.map(file => fileLinkedObject(file)),
15629
15686
  cachedAt,
15630
15687
  };
15631
15688
  };
@@ -15686,7 +15743,7 @@ const uploadImage = async (formData, onProgress, altText) => {
15686
15743
  if (client.cache)
15687
15744
  ingestInCache({ files: data }, { cachedAt });
15688
15745
  return {
15689
- data,
15746
+ data: data.map(file => fileLinkedObject(file)),
15690
15747
  cachedAt,
15691
15748
  };
15692
15749
  };
@@ -16649,6 +16706,39 @@ removeReaction.optimistically = (referenceType, referenceId, reactionName) => {
16649
16706
  return !((_d = reaction === null || reaction === void 0 ? void 0 : reaction.myReactions) === null || _d === void 0 ? void 0 : _d.includes(reactionName));
16650
16707
  };
16651
16708
 
16709
+ /**
16710
+ * Resolves the id of the parent post that a child-post payload belongs to.
16711
+ *
16712
+ * `parentId` and `parentPostId` name the same post, but a payload does not
16713
+ * always carry both — and the delete/create child handlers decide *whether* a
16714
+ * post is a child from `parentId` while reading the cache with `parentPostId`.
16715
+ * When only the former is set that read builds `['post', 'get', undefined]`,
16716
+ * which cannot match anything and, when the value is null, breaks key encoding
16717
+ * outright. Reading whichever id is present keeps the decision and the lookup
16718
+ * on the same post.
16719
+ *
16720
+ * @param post the child post payload
16721
+ * @returns the parent post id, or undefined when the payload carries neither
16722
+ *
16723
+ * @category Post Events
16724
+ * @hidden
16725
+ */
16726
+ const resolveParentPostId = (post) => {
16727
+ if (post.parentPostId)
16728
+ return post.parentPostId;
16729
+ if (post.parentId) {
16730
+ // Diagnostic: we do not know yet whether the server actually emits this
16731
+ // shape. If this warning is never seen in practice the fallback can go.
16732
+ console.warn('[AmitySDK] post payload carries `parentId` without `parentPostId` — falling back to `parentId`', {
16733
+ postId: post.postId,
16734
+ parentId: post.parentId,
16735
+ parentPostId: post.parentPostId,
16736
+ });
16737
+ return post.parentId;
16738
+ }
16739
+ return undefined;
16740
+ };
16741
+
16652
16742
  const processDeleteChildPost = (payload) => {
16653
16743
  var _a;
16654
16744
  const post = payload.posts[0];
@@ -16660,7 +16750,10 @@ const processDeleteChildPost = (payload) => {
16660
16750
  }
16661
16751
  else {
16662
16752
  // child post in a parent post
16663
- const parentPost = (_a = pullFromCache(['post', 'get', post.parentPostId])) === null || _a === void 0 ? void 0 : _a.data;
16753
+ const parentPostId = resolveParentPostId(post);
16754
+ if (!parentPostId)
16755
+ return;
16756
+ const parentPost = (_a = pullFromCache(['post', 'get', parentPostId])) === null || _a === void 0 ? void 0 : _a.data;
16664
16757
  if (!parentPost)
16665
16758
  return;
16666
16759
  pushToCache(['post', 'get', parentPost.postId], Object.assign(Object.assign({}, parentPost), { children: parentPost.children.filter(childId => childId !== post.postId) }));
@@ -16671,7 +16764,10 @@ const processCreateChildPost = (payload) => {
16671
16764
  const post = payload.posts[0];
16672
16765
  if (!post.parentId)
16673
16766
  return;
16674
- const parentPost = (_a = pullFromCache(['post', 'get', post.parentPostId])) === null || _a === void 0 ? void 0 : _a.data;
16767
+ const parentPostId = resolveParentPostId(post);
16768
+ if (!parentPostId)
16769
+ return;
16770
+ const parentPost = (_a = pullFromCache(['post', 'get', parentPostId])) === null || _a === void 0 ? void 0 : _a.data;
16675
16771
  if (!parentPost)
16676
16772
  return;
16677
16773
  pushToCache(['post', 'get', parentPost.postId], Object.assign(Object.assign({}, parentPost), { children: [...new Set([post.postId, ...parentPost.children])] }));