@shortkitsdk/react-native 0.2.42 → 0.2.43

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.
Binary file
@@ -14,6 +14,7 @@ import com.shortkit.sdk.model.ContentSignal
14
14
  import com.shortkit.sdk.model.FeedDirection
15
15
  import com.shortkit.sdk.model.FeedFilter
16
16
  import com.shortkit.sdk.model.FeedInput
17
+ import com.shortkit.sdk.model.FeedItem
17
18
  import com.shortkit.sdk.model.FeedScrollPhase
18
19
  import com.shortkit.sdk.model.FeedTransitionPhase
19
20
  import com.shortkit.sdk.model.ImageCarouselItem
@@ -427,7 +428,10 @@ class ShortKitBridge(
427
428
  "video" -> {
428
429
  val playbackId = obj.optString("playbackId", null) ?: continue
429
430
  val fallbackUrl = obj.optString("fallbackUrl", null)
430
- result.add(FeedInput.Video(playbackId, fallbackUrl))
431
+ val itemId = obj.optString("id", null)
432
+ val nativePlaybackId =
433
+ if (!itemId.isNullOrBlank() && !fallbackUrl.isNullOrBlank()) itemId else playbackId
434
+ result.add(FeedInput.Video(nativePlaybackId, fallbackUrl))
431
435
  }
432
436
  "imageCarousel" -> {
433
437
  val itemObj = obj.optJSONObject("item") ?: continue
@@ -442,7 +446,10 @@ class ShortKitBridge(
442
446
  val videoObj = videosArr.getJSONObject(i)
443
447
  val playbackId = videoObj.optString("playbackId", null) ?: continue
444
448
  val fallbackUrl = videoObj.optString("fallbackUrl", null)
445
- videoInputs.add(VideoCarouselVideoInput(playbackId, fallbackUrl))
449
+ val videoId = videoObj.optString("id", null)
450
+ val nativePlaybackId =
451
+ if (!videoId.isNullOrBlank() && !fallbackUrl.isNullOrBlank()) videoId else playbackId
452
+ videoInputs.add(VideoCarouselVideoInput(nativePlaybackId, fallbackUrl))
446
453
  }
447
454
  if (videoInputs.isEmpty()) continue
448
455
  val carouselInput = VideoCarouselInput(
@@ -1098,22 +1105,220 @@ class ShortKitBridge(
1098
1105
  // Custom feed operations
1099
1106
  // ------------------------------------------------------------------
1100
1107
 
1108
+ private fun legacyFallbackIdsByFallbackUrl(itemsJSON: String): Map<String, String> {
1109
+ return try {
1110
+ val arr = JSONArray(itemsJSON)
1111
+ val ids = mutableMapOf<String, String>()
1112
+
1113
+ for (i in 0 until arr.length()) {
1114
+ val obj = arr.getJSONObject(i)
1115
+ when (obj.optString("type")) {
1116
+ "video" -> {
1117
+ val id = obj.optString("id", null)
1118
+ val fallbackUrl = obj.optString("fallbackUrl", null)
1119
+ if (!id.isNullOrBlank() && !fallbackUrl.isNullOrBlank()) {
1120
+ ids[fallbackUrl] = id
1121
+ }
1122
+ }
1123
+ "videoCarousel" -> {
1124
+ val videos = obj.optJSONObject("item")?.optJSONArray("videos")
1125
+ if (videos != null) {
1126
+ for (videoIndex in 0 until videos.length()) {
1127
+ val video = videos.getJSONObject(videoIndex)
1128
+ val id = video.optString("id", null)
1129
+ val fallbackUrl = video.optString("fallbackUrl", null)
1130
+ if (!id.isNullOrBlank() && !fallbackUrl.isNullOrBlank()) {
1131
+ ids[fallbackUrl] = id
1132
+ }
1133
+ }
1134
+ }
1135
+ }
1136
+ }
1137
+ }
1138
+
1139
+ ids
1140
+ } catch (_: Throwable) {
1141
+ emptyMap()
1142
+ }
1143
+ }
1144
+
1145
+ private fun fallbackThumbnailUrl(fallbackUrl: String): String {
1146
+ val uploadMarker = "/video/upload/"
1147
+ val uploadIndex = fallbackUrl.indexOf(uploadMarker)
1148
+
1149
+ if (uploadIndex >= 0) {
1150
+ val prefix = fallbackUrl.substring(0, uploadIndex)
1151
+ val path = fallbackUrl.substring(uploadIndex + uploadMarker.length)
1152
+ val withoutExtension = path.substringBeforeLast('.', path)
1153
+ return "$prefix/video/upload/so_0/$withoutExtension.jpg"
1154
+ }
1155
+
1156
+ return fallbackUrl
1157
+ }
1158
+
1159
+ private fun legacyFallbackContentItem(contentId: String, fallbackUrl: String): ContentItem {
1160
+ return ContentItem(
1161
+ id = contentId,
1162
+ playbackId = contentId,
1163
+ title = "",
1164
+ description = null,
1165
+ duration = 0.0,
1166
+ streamingUrl = fallbackUrl,
1167
+ thumbnailUrl = fallbackThumbnailUrl(fallbackUrl),
1168
+ captionTracks = emptyList(),
1169
+ customMetadata = null,
1170
+ author = null,
1171
+ articleUrl = null,
1172
+ commentCount = null,
1173
+ fallbackUrl = fallbackUrl,
1174
+ )
1175
+ }
1176
+
1177
+ private fun patchLegacyFallbackFeedItems(
1178
+ fragment: ShortKitFeedFragment,
1179
+ legacyIdsByFallbackUrl: Map<String, String>,
1180
+ ): Boolean {
1181
+ if (legacyIdsByFallbackUrl.isEmpty()) return false
1182
+
1183
+ try {
1184
+ val feedDataSourceField = fragment.javaClass.getDeclaredField("feedDataSource").apply {
1185
+ isAccessible = true
1186
+ }
1187
+ val feedDataSource = feedDataSourceField.get(fragment) ?: return false
1188
+ @Suppress("UNCHECKED_CAST")
1189
+ val feedItems = feedDataSource.javaClass.getMethod("getItems").invoke(feedDataSource) as? MutableList<FeedItem>
1190
+ ?: return false
1191
+ var patchedCount = 0
1192
+
1193
+ feedItems.forEachIndexed { index, feedItem ->
1194
+ when (feedItem) {
1195
+ is FeedItem.Content -> {
1196
+ val item = feedItem.item
1197
+ val fallbackUrl = item.fallbackUrl
1198
+ val legacyId = fallbackUrl?.takeIf { it.isNotBlank() }?.let {
1199
+ legacyIdsByFallbackUrl[it]
1200
+ }
1201
+ if (!legacyId.isNullOrBlank() && !fallbackUrl.isNullOrBlank()) {
1202
+ feedItems[index] = FeedItem.Content(legacyFallbackContentItem(legacyId, fallbackUrl))
1203
+ patchedCount += 1
1204
+ }
1205
+ }
1206
+ is FeedItem.VideoCarousel -> {
1207
+ val carouselItem = feedItem.item
1208
+ var didPatchCarousel = false
1209
+ val patchedVideos = carouselItem.videos.map { video ->
1210
+ val fallbackUrl = video.fallbackUrl
1211
+ val legacyId = fallbackUrl?.takeIf { it.isNotBlank() }?.let {
1212
+ legacyIdsByFallbackUrl[it]
1213
+ }
1214
+ if (legacyId.isNullOrBlank() || fallbackUrl.isNullOrBlank()) {
1215
+ video
1216
+ } else {
1217
+ didPatchCarousel = true
1218
+ legacyFallbackContentItem(legacyId, fallbackUrl)
1219
+ }
1220
+ }
1221
+
1222
+ if (didPatchCarousel) {
1223
+ feedItems[index] = FeedItem.VideoCarousel(carouselItem.copy(videos = patchedVideos))
1224
+ patchedCount += 1
1225
+ }
1226
+ }
1227
+ else -> Unit
1228
+ }
1229
+ }
1230
+
1231
+ if (patchedCount > 0) {
1232
+ android.util.Log.d("SK:Bridge", "patched legacy fallback feed items count=$patchedCount")
1233
+ }
1234
+ return patchedCount > 0
1235
+ } catch (error: Throwable) {
1236
+ android.util.Log.w("SK:Bridge", "failed to patch legacy fallback feed items", error)
1237
+ }
1238
+
1239
+ return false
1240
+ }
1241
+
1242
+ private fun resubmitPatchedFeedItems(fragment: ShortKitFeedFragment, startAtId: String?) {
1243
+ try {
1244
+ val feedDataSourceField = fragment.javaClass.getDeclaredField("feedDataSource").apply {
1245
+ isAccessible = true
1246
+ }
1247
+ val feedDataSource = feedDataSourceField.get(fragment) ?: return
1248
+ @Suppress("UNCHECKED_CAST")
1249
+ val feedItems = feedDataSource.javaClass.getMethod("getItems").invoke(feedDataSource) as? List<FeedItem>
1250
+ ?: return
1251
+
1252
+ val feedAdapterField = fragment.javaClass.getDeclaredField("feedAdapter").apply {
1253
+ isAccessible = true
1254
+ }
1255
+ val feedAdapter = feedAdapterField.get(fragment) ?: return
1256
+ val submitList = feedAdapter.javaClass.methods.firstOrNull { method ->
1257
+ method.name == "submitList" &&
1258
+ method.parameterTypes.size == 2 &&
1259
+ Runnable::class.java.isAssignableFrom(method.parameterTypes[1])
1260
+ } ?: return
1261
+ val callback = Runnable {
1262
+ if (!startAtId.isNullOrBlank()) {
1263
+ fragment.scrollToItem(startAtId, false)
1264
+ }
1265
+ }
1266
+
1267
+ submitList.invoke(feedAdapter, feedItems.toList(), callback)
1268
+ } catch (error: Throwable) {
1269
+ android.util.Log.w("SK:Bridge", "failed to resubmit patched legacy fallback feed items", error)
1270
+ }
1271
+ }
1272
+
1273
+ internal fun hasLegacyFallbackFeedItems(itemsJSON: String): Boolean {
1274
+ return legacyFallbackIdsByFallbackUrl(itemsJSON).isNotEmpty()
1275
+ }
1276
+
1277
+ internal fun setFeedItemsResolvingLegacyFallback(
1278
+ fragment: ShortKitFeedFragment,
1279
+ parsed: List<FeedInput>,
1280
+ itemsJSON: String,
1281
+ startAtId: String?,
1282
+ ) {
1283
+ val legacyIdsByFallbackUrl = legacyFallbackIdsByFallbackUrl(itemsJSON)
1284
+ val nativeStartAtId =
1285
+ if (!startAtId.isNullOrBlank() && legacyIdsByFallbackUrl.containsValue(startAtId)) null else startAtId
1286
+
1287
+ fragment.setFeedItems(parsed, nativeStartAtId)
1288
+ if (patchLegacyFallbackFeedItems(fragment, legacyIdsByFallbackUrl)) {
1289
+ resubmitPatchedFeedItems(fragment, startAtId)
1290
+ }
1291
+ }
1292
+
1293
+ internal fun appendFeedItemsResolvingLegacyFallback(
1294
+ fragment: ShortKitFeedFragment,
1295
+ parsed: List<FeedInput>,
1296
+ itemsJSON: String,
1297
+ ) {
1298
+ val legacyIdsByFallbackUrl = legacyFallbackIdsByFallbackUrl(itemsJSON)
1299
+
1300
+ fragment.appendFeedItems(parsed)
1301
+ if (patchLegacyFallbackFeedItems(fragment, legacyIdsByFallbackUrl)) {
1302
+ resubmitPatchedFeedItems(fragment, null)
1303
+ }
1304
+ }
1305
+
1101
1306
  fun setFeedItems(feedId: String, itemsJSON: String, startAtId: String?) {
1102
1307
  val fragment = feedFragment(feedId)
1103
1308
  if (fragment != null) {
1104
1309
  val parsed = parseFeedInputs(itemsJSON) ?: return
1105
1310
  Handler(Looper.getMainLooper()).post {
1106
- fragment.setFeedItems(parsed, startAtId)
1311
+ setFeedItemsResolvingLegacyFallback(fragment, parsed, itemsJSON, startAtId)
1107
1312
  }
1108
1313
  } else {
1109
1314
  synchronized(pendingOpsLock) {
1110
1315
  pendingOps.getOrPut(feedId) { mutableListOf() }.add { frag ->
1111
1316
  val parsed = parseFeedInputs(itemsJSON) ?: return@add
1112
1317
  if (Looper.myLooper() == Looper.getMainLooper()) {
1113
- frag.setFeedItems(parsed, startAtId)
1318
+ setFeedItemsResolvingLegacyFallback(frag, parsed, itemsJSON, startAtId)
1114
1319
  } else {
1115
1320
  Handler(Looper.getMainLooper()).post {
1116
- frag.setFeedItems(parsed, startAtId)
1321
+ setFeedItemsResolvingLegacyFallback(frag, parsed, itemsJSON, startAtId)
1117
1322
  }
1118
1323
  }
1119
1324
  }
@@ -1143,14 +1348,14 @@ class ShortKitBridge(
1143
1348
  if (fragment != null) {
1144
1349
  val parsed = parseFeedInputs(itemsJSON) ?: return
1145
1350
  Handler(Looper.getMainLooper()).post {
1146
- fragment.appendFeedItems(parsed)
1351
+ appendFeedItemsResolvingLegacyFallback(fragment, parsed, itemsJSON)
1147
1352
  }
1148
1353
  } else {
1149
1354
  synchronized(pendingOpsLock) {
1150
1355
  pendingOps.getOrPut(feedId) { mutableListOf() }.add { frag ->
1151
1356
  val parsed = parseFeedInputs(itemsJSON) ?: return@add
1152
1357
  Handler(Looper.getMainLooper()).post {
1153
- frag.appendFeedItems(parsed)
1358
+ appendFeedItemsResolvingLegacyFallback(frag, parsed, itemsJSON)
1154
1359
  }
1155
1360
  }
1156
1361
  }
@@ -1222,6 +1427,11 @@ class ShortKitBridge(
1222
1427
  callback("")
1223
1428
  return
1224
1429
  }
1430
+ if (hasLegacyFallbackFeedItems(itemsJSON)) {
1431
+ android.util.Log.d("SK:Bridge", "skipping custom preload for legacy fallback feed items")
1432
+ callback("")
1433
+ return
1434
+ }
1225
1435
  val items = parseFeedInputs(itemsJSON)
1226
1436
  if (items == null) {
1227
1437
  callback("")
@@ -10,6 +10,7 @@ import android.view.ViewGroup
10
10
  import android.widget.FrameLayout
11
11
  import androidx.fragment.app.FragmentActivity
12
12
  import com.shortkit.sdk.feed.ShortKitFeedFragment
13
+ import com.shortkit.sdk.model.FeedInput
13
14
 
14
15
  /**
15
16
  * Fabric native view that embeds [ShortKitFeedFragment] using Android
@@ -292,12 +293,10 @@ class ShortKitFeedView(context: Context) : FrameLayout(context) {
292
293
 
293
294
  val explicitPreloadId = preloadId
294
295
  val explicitFeedItemsJSON = feedItemsJSON
295
- if (explicitPreloadId != null) {
296
- val preload = ShortKitBridge.shared?.consumePreload(explicitPreloadId)
297
- if (preload != null) {
298
- feedConfig = feedConfig.copy(preload = preload)
299
- }
300
- } else if (explicitFeedItemsJSON != null) {
296
+ var deferredFeedItemsJSON: String? = null
297
+ var deferredFeedItems: List<FeedInput>? = null
298
+ fun configureExplicitFeedItems() {
299
+ val sourceItemsJSON = explicitFeedItemsJSON ?: return
301
300
  // Mount-time custom-feed fast-path (SHO-29 / iOS PR #150).
302
301
  // Parse JSON → FeedInput[] → sdk.preloadFeed(items=) which
303
302
  // internally calls FeedPreload.forCustomItems with the SDK's
@@ -310,15 +309,31 @@ class ShortKitFeedView(context: Context) : FrameLayout(context) {
310
309
  // ShortKit.kt:232) instead of FeedPreload.forCustomItems
311
310
  // directly — avoids needing to promote internal SDK helpers
312
311
  // for cross-module access from the bridge.
313
- val parsed = ShortKitBridge.parseFeedInputs(explicitFeedItemsJSON)
312
+ val parsed = ShortKitBridge.parseFeedInputs(sourceItemsJSON)
314
313
  if (parsed != null && parsed.isNotEmpty()) {
315
- val preload = sdk.preloadFeed(items = parsed)
316
- feedConfig = feedConfig.copy(preload = preload)
314
+ if (ShortKitBridge.shared?.hasLegacyFallbackFeedItems(sourceItemsJSON) == true) {
315
+ deferredFeedItemsJSON = sourceItemsJSON
316
+ deferredFeedItems = parsed
317
+ } else {
318
+ val preload = sdk.preloadFeed(items = parsed)
319
+ feedConfig = feedConfig.copy(preload = preload)
320
+ }
317
321
  } else {
318
322
  Log.w(TAG, "feedItemsJSON parsed to null/empty — ignoring (config feedSource will drive the fetch path)")
319
323
  }
320
324
  }
321
325
 
326
+ if (explicitPreloadId != null) {
327
+ val preload = ShortKitBridge.shared?.consumePreload(explicitPreloadId)
328
+ if (preload != null) {
329
+ feedConfig = feedConfig.copy(preload = preload)
330
+ } else {
331
+ configureExplicitFeedItems()
332
+ }
333
+ } else if (explicitFeedItemsJSON != null) {
334
+ configureExplicitFeedItems()
335
+ }
336
+
322
337
  val fragment = ShortKitFeedFragment.newInstance(sdk, feedConfig, startAtItemId)
323
338
 
324
339
  val debugPanelEnabled = if (debugPanelPropSet) debugPanel else sdk.debugPanelEnabled
@@ -348,6 +363,16 @@ class ShortKitFeedView(context: Context) : FrameLayout(context) {
348
363
  .replace(fragmentContainerId, fragment)
349
364
  .commitNowAllowingStateLoss()
350
365
  this.feedFragment = fragment
366
+ val mountFeedItemsJSON = deferredFeedItemsJSON
367
+ val mountFeedItems = deferredFeedItems
368
+ if (mountFeedItemsJSON != null && mountFeedItems != null) {
369
+ ShortKitBridge.shared?.setFeedItemsResolvingLegacyFallback(
370
+ fragment,
371
+ mountFeedItems,
372
+ mountFeedItemsJSON,
373
+ startAtItemId,
374
+ )
375
+ }
351
376
 
352
377
  // Android-specific first-mount race: Fabric may have set active=false
353
378
  // BEFORE we got to embed the fragment. The fragment self-claims the
@@ -11,9 +11,9 @@
11
11
  <key>CFBundlePackageType</key>
12
12
  <string>FMWK</string>
13
13
  <key>CFBundleVersion</key>
14
- <string>0.2.42</string>
14
+ <string>0.2.43</string>
15
15
  <key>CFBundleShortVersionString</key>
16
- <string>0.2.42</string>
16
+ <string>0.2.43</string>
17
17
  <key>MinimumOSVersion</key>
18
18
  <string>16.0</string>
19
19
  </dict>
@@ -53531,7 +53531,7 @@
53531
53531
  "kind": "StringLiteral",
53532
53532
  "offset": 154,
53533
53533
  "length": 8,
53534
- "value": "\"0.2.42\""
53534
+ "value": "\"0.2.43\""
53535
53535
  },
53536
53536
  {
53537
53537
  "filePath": "\/Users\/michaelseleman\/shortkit\/swift_sdk\/Sources\/ShortKit\/ShortKit.swift",
@@ -10,11 +10,11 @@
10
10
  </data>
11
11
  <key>Info.plist</key>
12
12
  <data>
13
- WYwIj+FGMh7YF5ujxHC/klHgUnc=
13
+ TG3LP5ZMM8V3dELjK3Olw15ohCg=
14
14
  </data>
15
15
  <key>Modules/ShortKitSDK.swiftmodule/arm64-apple-ios.abi.json</key>
16
16
  <data>
17
- tozRG9zh+x9rx3eAHry35nYt4pM=
17
+ 3lW3HwkTYBJ3P/8BAI6tSSqybzM=
18
18
  </data>
19
19
  <key>Modules/ShortKitSDK.swiftmodule/arm64-apple-ios.private.swiftinterface</key>
20
20
  <data>
@@ -50,7 +50,7 @@
50
50
  <dict>
51
51
  <key>hash2</key>
52
52
  <data>
53
- SzEj0TFMLukykfaw3Vh0cjVfyWUnkYbtJO3MrTBkLeQ=
53
+ xcfBvVw56QMYGrmvXutsz9+UxOyQoHa33Hgy7h5/lto=
54
54
  </data>
55
55
  </dict>
56
56
  <key>Modules/ShortKitSDK.swiftmodule/arm64-apple-ios.private.swiftinterface</key>
@@ -11,9 +11,9 @@
11
11
  <key>CFBundlePackageType</key>
12
12
  <string>FMWK</string>
13
13
  <key>CFBundleVersion</key>
14
- <string>0.2.42</string>
14
+ <string>0.2.43</string>
15
15
  <key>CFBundleShortVersionString</key>
16
- <string>0.2.42</string>
16
+ <string>0.2.43</string>
17
17
  <key>MinimumOSVersion</key>
18
18
  <string>16.0</string>
19
19
  </dict>
@@ -53531,7 +53531,7 @@
53531
53531
  "kind": "StringLiteral",
53532
53532
  "offset": 154,
53533
53533
  "length": 8,
53534
- "value": "\"0.2.42\""
53534
+ "value": "\"0.2.43\""
53535
53535
  },
53536
53536
  {
53537
53537
  "filePath": "\/Users\/michaelseleman\/shortkit\/swift_sdk\/Sources\/ShortKit\/ShortKit.swift",
@@ -53531,7 +53531,7 @@
53531
53531
  "kind": "StringLiteral",
53532
53532
  "offset": 154,
53533
53533
  "length": 8,
53534
- "value": "\"0.2.42\""
53534
+ "value": "\"0.2.43\""
53535
53535
  },
53536
53536
  {
53537
53537
  "filePath": "\/Users\/michaelseleman\/shortkit\/swift_sdk\/Sources\/ShortKit\/ShortKit.swift",
@@ -10,11 +10,11 @@
10
10
  </data>
11
11
  <key>Info.plist</key>
12
12
  <data>
13
- WYwIj+FGMh7YF5ujxHC/klHgUnc=
13
+ TG3LP5ZMM8V3dELjK3Olw15ohCg=
14
14
  </data>
15
15
  <key>Modules/ShortKitSDK.swiftmodule/arm64-apple-ios-simulator.abi.json</key>
16
16
  <data>
17
- tozRG9zh+x9rx3eAHry35nYt4pM=
17
+ 3lW3HwkTYBJ3P/8BAI6tSSqybzM=
18
18
  </data>
19
19
  <key>Modules/ShortKitSDK.swiftmodule/arm64-apple-ios-simulator.private.swiftinterface</key>
20
20
  <data>
@@ -30,7 +30,7 @@
30
30
  </data>
31
31
  <key>Modules/ShortKitSDK.swiftmodule/x86_64-apple-ios-simulator.abi.json</key>
32
32
  <data>
33
- tozRG9zh+x9rx3eAHry35nYt4pM=
33
+ 3lW3HwkTYBJ3P/8BAI6tSSqybzM=
34
34
  </data>
35
35
  <key>Modules/ShortKitSDK.swiftmodule/x86_64-apple-ios-simulator.private.swiftinterface</key>
36
36
  <data>
@@ -66,7 +66,7 @@
66
66
  <dict>
67
67
  <key>hash2</key>
68
68
  <data>
69
- SzEj0TFMLukykfaw3Vh0cjVfyWUnkYbtJO3MrTBkLeQ=
69
+ xcfBvVw56QMYGrmvXutsz9+UxOyQoHa33Hgy7h5/lto=
70
70
  </data>
71
71
  </dict>
72
72
  <key>Modules/ShortKitSDK.swiftmodule/arm64-apple-ios-simulator.private.swiftinterface</key>
@@ -94,7 +94,7 @@
94
94
  <dict>
95
95
  <key>hash2</key>
96
96
  <data>
97
- SzEj0TFMLukykfaw3Vh0cjVfyWUnkYbtJO3MrTBkLeQ=
97
+ xcfBvVw56QMYGrmvXutsz9+UxOyQoHa33Hgy7h5/lto=
98
98
  </data>
99
99
  </dict>
100
100
  <key>Modules/ShortKitSDK.swiftmodule/x86_64-apple-ios-simulator.private.swiftinterface</key>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shortkitsdk/react-native",
3
- "version": "0.2.42",
3
+ "version": "0.2.43",
4
4
  "description": "ShortKit React Native SDK — short-form video feed",
5
5
  "react-native": "src/index",
6
6
  "source": "src/index",
@@ -100,7 +100,10 @@ export function deserializePlayerTime(event: {
100
100
  function serializeVideoCarouselSlide(
101
101
  slide: VideoCarouselVideoInput,
102
102
  ): Record<string, unknown> {
103
+ const legacyId = (slide as VideoCarouselVideoInput & { id?: string }).id;
104
+
103
105
  return {
106
+ ...(legacyId != null ? { id: String(legacyId) } : {}),
104
107
  playbackId: slide.playbackId,
105
108
  origin: slide.origin ?? 'other',
106
109
  ...(slide.fallbackUrl != null ? { fallbackUrl: slide.fallbackUrl } : {}),
@@ -114,8 +117,11 @@ function serializeVideoCarouselSlide(
114
117
  export function serializeFeedInputs(items: FeedInput[]): string {
115
118
  const serialized = items.map((input) => {
116
119
  if (input.type === 'video') {
120
+ const legacyId = (input as FeedInput & { id?: string }).id;
121
+
117
122
  return {
118
123
  type: 'video',
124
+ ...(legacyId != null ? { id: String(legacyId) } : {}),
119
125
  playbackId: input.playbackId,
120
126
  origin: input.origin ?? 'other',
121
127
  ...(input.fallbackUrl != null ? { fallbackUrl: input.fallbackUrl } : {}),