@shortkitsdk/react-native 0.2.38 → 0.2.40

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 (31) hide show
  1. package/android/build.gradle.kts +2 -2
  2. package/android/libs/shortkit-release.aar +0 -0
  3. package/android/src/main/java/com/shortkit/reactnative/ReactCarouselOverlayHost.kt +19 -1
  4. package/android/src/main/java/com/shortkit/reactnative/ReactOverlayHost.kt +1 -0
  5. package/android/src/main/java/com/shortkit/reactnative/ReactVideoCarouselOverlayHost.kt +29 -25
  6. package/android/src/main/java/com/shortkit/reactnative/ShortKitBridge.kt +37 -0
  7. package/android/src/main/java/com/shortkit/reactnative/ShortKitFeedView.kt +1 -0
  8. package/android/src/main/java/com/shortkit/reactnative/ShortKitModule.kt +1 -1
  9. package/android/src/test/java/com/shortkit/reactnative/ReactCarouselOverlayHostLifecycleTest.kt +19 -0
  10. package/android/src/test/java/com/shortkit/reactnative/ReactVideoCarouselOverlayHostLifecycleTest.kt +22 -0
  11. package/android/src/test/java/com/shortkit/reactnative/ShortKitBridgeLongPressTest.kt +148 -0
  12. package/ios/ShortKitBridge.swift +2 -1
  13. package/ios/ShortKitSDK.xcframework/ios-arm64/ShortKitSDK.framework/Info.plist +2 -2
  14. package/ios/ShortKitSDK.xcframework/ios-arm64/ShortKitSDK.framework/Modules/ShortKitSDK.swiftmodule/arm64-apple-ios.abi.json +26 -12
  15. package/ios/ShortKitSDK.xcframework/ios-arm64/ShortKitSDK.framework/Modules/ShortKitSDK.swiftmodule/arm64-apple-ios.private.swiftinterface +2 -2
  16. package/ios/ShortKitSDK.xcframework/ios-arm64/ShortKitSDK.framework/Modules/ShortKitSDK.swiftmodule/arm64-apple-ios.swiftdoc +0 -0
  17. package/ios/ShortKitSDK.xcframework/ios-arm64/ShortKitSDK.framework/Modules/ShortKitSDK.swiftmodule/arm64-apple-ios.swiftinterface +2 -2
  18. package/ios/ShortKitSDK.xcframework/ios-arm64/ShortKitSDK.framework/ShortKitSDK +0 -0
  19. package/ios/ShortKitSDK.xcframework/ios-arm64/ShortKitSDK.framework/_CodeSignature/CodeResources +9 -9
  20. package/ios/ShortKitSDK.xcframework/ios-arm64_x86_64-simulator/ShortKitSDK.framework/Info.plist +2 -2
  21. package/ios/ShortKitSDK.xcframework/ios-arm64_x86_64-simulator/ShortKitSDK.framework/Modules/ShortKitSDK.swiftmodule/arm64-apple-ios-simulator.abi.json +26 -12
  22. package/ios/ShortKitSDK.xcframework/ios-arm64_x86_64-simulator/ShortKitSDK.framework/Modules/ShortKitSDK.swiftmodule/arm64-apple-ios-simulator.private.swiftinterface +2 -2
  23. package/ios/ShortKitSDK.xcframework/ios-arm64_x86_64-simulator/ShortKitSDK.framework/Modules/ShortKitSDK.swiftmodule/arm64-apple-ios-simulator.swiftdoc +0 -0
  24. package/ios/ShortKitSDK.xcframework/ios-arm64_x86_64-simulator/ShortKitSDK.framework/Modules/ShortKitSDK.swiftmodule/arm64-apple-ios-simulator.swiftinterface +2 -2
  25. package/ios/ShortKitSDK.xcframework/ios-arm64_x86_64-simulator/ShortKitSDK.framework/Modules/ShortKitSDK.swiftmodule/x86_64-apple-ios-simulator.abi.json +26 -12
  26. package/ios/ShortKitSDK.xcframework/ios-arm64_x86_64-simulator/ShortKitSDK.framework/Modules/ShortKitSDK.swiftmodule/x86_64-apple-ios-simulator.private.swiftinterface +2 -2
  27. package/ios/ShortKitSDK.xcframework/ios-arm64_x86_64-simulator/ShortKitSDK.framework/Modules/ShortKitSDK.swiftmodule/x86_64-apple-ios-simulator.swiftdoc +0 -0
  28. package/ios/ShortKitSDK.xcframework/ios-arm64_x86_64-simulator/ShortKitSDK.framework/Modules/ShortKitSDK.swiftmodule/x86_64-apple-ios-simulator.swiftinterface +2 -2
  29. package/ios/ShortKitSDK.xcframework/ios-arm64_x86_64-simulator/ShortKitSDK.framework/ShortKitSDK +0 -0
  30. package/ios/ShortKitSDK.xcframework/ios-arm64_x86_64-simulator/ShortKitSDK.framework/_CodeSignature/CodeResources +17 -17
  31. package/package.json +1 -1
@@ -37,8 +37,8 @@ dependencies {
37
37
  implementation("com.facebook.react:react-android")
38
38
  // Composite build in sample/android/settings.gradle substitutes this with
39
39
  // live android_sdk source automatically (dev.shortkit:shortkit → :shortkit project).
40
- implementation("dev.shortkit:shortkit:0.2.37")
41
- // implementation(files("libs/shortkit-release.aar"))
40
+ // implementation("dev.shortkit:shortkit:0.2.37")
41
+ implementation(files("libs/shortkit-release.aar"))
42
42
  // Transitive deps needed when using local AAR (Maven artifact bundles these automatically)
43
43
  implementation("androidx.media3:media3-exoplayer:1.5.1")
44
44
  implementation("androidx.media3:media3-exoplayer-hls:1.5.1")
Binary file
@@ -15,6 +15,8 @@ import kotlinx.coroutines.CoroutineScope
15
15
  import kotlinx.coroutines.Dispatchers
16
16
  import kotlinx.coroutines.Job
17
17
  import kotlinx.coroutines.SupervisorJob
18
+ import kotlinx.coroutines.cancel
19
+ import kotlinx.coroutines.isActive
18
20
  import kotlinx.coroutines.launch
19
21
  import kotlinx.coroutines.withContext
20
22
  import kotlinx.serialization.encodeToString
@@ -52,10 +54,20 @@ class ReactCarouselOverlayHost(context: Context) : FrameLayout(context), Carouse
52
54
  private var surface: ReactSurface? = null
53
55
  private var pendingProps: Bundle? = null
54
56
  private var isInLayoutPass: Boolean = false
55
- private val ioScope = CoroutineScope(Dispatchers.Main + SupervisorJob())
57
+ private var ioScope: CoroutineScope = CoroutineScope(Dispatchers.Main + SupervisorJob())
56
58
  private var pendingWriteJob: Job? = null
57
59
  private var configureGeneration: Int = 0
58
60
 
61
+ /** Test-only accessor for ioScope. */
62
+ @androidx.annotation.VisibleForTesting
63
+ internal val ioScopeForTest: CoroutineScope get() = ioScope
64
+
65
+ /** Test-only triggers for window lifecycle (protected in View). */
66
+ @androidx.annotation.VisibleForTesting
67
+ internal fun callOnDetachedFromWindow() = onDetachedFromWindow()
68
+ @androidx.annotation.VisibleForTesting
69
+ internal fun callOnAttachedToWindow() = onAttachedToWindow()
70
+
59
71
  /** Unique identifier for this overlay instance, used for event routing. */
60
72
  val surfaceId: String = java.util.UUID.randomUUID().toString()
61
73
 
@@ -405,6 +417,9 @@ class ReactCarouselOverlayHost(context: Context) : FrameLayout(context), Carouse
405
417
 
406
418
  override fun onAttachedToWindow() {
407
419
  super.onAttachedToWindow()
420
+ if (!ioScope.isActive) {
421
+ ioScope = CoroutineScope(Dispatchers.Main + SupervisorJob())
422
+ }
408
423
 
409
424
  val parentView = parent as? android.view.View
410
425
  if (parentView != null && parentView.width > 0 && parentView.height > 0 && (width == 0 || height == 0)) {
@@ -467,11 +482,14 @@ class ReactCarouselOverlayHost(context: Context) : FrameLayout(context), Carouse
467
482
 
468
483
  public override fun onDetachedFromWindow() {
469
484
  super.onDetachedFromWindow()
485
+ layoutHandler.removeCallbacks(layoutRunnable)
470
486
  pendingWriteJob?.cancel()
471
487
  pendingWriteJob = null
488
+ ioScope.cancel()
472
489
  // Non-destructive: surface survives cell recycle and view transitions.
473
490
  // iOS parity: ReactCarouselOverlayHost.swift has no willMove/didMoveToWindow
474
491
  // override — surface stops only in deinit. Mirrors the non-destructive
475
492
  // contract enforced on ReactVideoCarouselOverlayHost.
493
+ // ioScope is recreated in onAttachedToWindow if needed.
476
494
  }
477
495
  }
@@ -300,6 +300,7 @@ class ReactOverlayHost(context: Context) : FrameLayout(context), FeedOverlay {
300
300
 
301
301
  override fun onDetachedFromWindow() {
302
302
  super.onDetachedFromWindow()
303
+ layoutHandler.removeCallbacks(layoutRunnable)
303
304
  // Cancel flow subscriptions to avoid emitting events for off-screen cells.
304
305
  // Do NOT stop the surface — keep JS alive so subscriptions persist across
305
306
  // RecyclerView detach/reattach cycles. This matches iOS behavior where the
@@ -156,6 +156,17 @@ class ReactVideoCarouselOverlayHost(context: Context) : FrameLayout(context), Vi
156
156
 
157
157
  private var flowScope: CoroutineScope? = null
158
158
 
159
+ /** Test-only read-write accessor for flowScope. Write path lets tests inject a scope
160
+ * without needing a full ShortKitPlayer mock. */
161
+ @androidx.annotation.VisibleForTesting
162
+ internal var flowScopeForTest: CoroutineScope?
163
+ get() = flowScope
164
+ set(value) { flowScope = value }
165
+
166
+ /** Test-only trigger for onDetachedFromWindow (protected in View). */
167
+ @androidx.annotation.VisibleForTesting
168
+ internal fun callOnDetachedFromWindow() = onDetachedFromWindow()
169
+
159
170
  // ------------------------------------------------------------------
160
171
  // Fabric layout workaround
161
172
  // ------------------------------------------------------------------
@@ -277,9 +288,10 @@ class ReactVideoCarouselOverlayHost(context: Context) : FrameLayout(context), Vi
277
288
  putBoolean("isActive", false)
278
289
  putString("playerState", "idle")
279
290
  putBoolean("isMuted", cachedIsMuted)
280
- if (item.videos.isNotEmpty()) {
281
- putString("activeVideo", ShortKitBridge.serializeContentItemToJSON(item.videos.first()))
282
- putInt("activeVideoIndex", 0)
291
+ val initialIdx = item.clampedInitialPageIndex
292
+ if (item.videos.indices.contains(initialIdx)) {
293
+ putString("activeVideo", ShortKitBridge.serializeContentItemToJSON(item.videos[initialIdx]))
294
+ putInt("activeVideoIndex", initialIdx)
283
295
  }
284
296
  }
285
297
 
@@ -299,11 +311,12 @@ class ReactVideoCarouselOverlayHost(context: Context) : FrameLayout(context), Vi
299
311
  putBoolean("isActive", false)
300
312
  putString("playerState", "idle")
301
313
  putBoolean("isMuted", cachedIsMuted)
302
- putInt("activeVideoIndex", 0)
303
- if (item.videos.isNotEmpty()) {
314
+ val initialIdx = item.clampedInitialPageIndex
315
+ putInt("activeVideoIndex", initialIdx)
316
+ if (item.videos.indices.contains(initialIdx)) {
304
317
  putString(
305
318
  "activeVideo",
306
- ShortKitBridge.serializeContentItemToJSON(item.videos.first()),
319
+ ShortKitBridge.serializeContentItemToJSON(item.videos[initialIdx]),
307
320
  )
308
321
  } else {
309
322
  putNull("activeVideo")
@@ -633,26 +646,17 @@ class ReactVideoCarouselOverlayHost(context: Context) : FrameLayout(context), Vi
633
646
 
634
647
  public override fun onDetachedFromWindow() {
635
648
  super.onDetachedFromWindow()
636
- // iOS-parity: detach is fully non-destructive. The React surface,
637
- // currentCarouselItem, flowScope, isActive, AND the time-coalescing
638
- // runnable all survive visibility transitions. The cell's recycle
639
- // path keeps the overlay attached (mirror of iOS
640
- // VideoCarouselCell.prepareForReuse).
649
+ layoutHandler.removeCallbacks(layoutRunnable)
650
+ // Cancel flow subscriptions so StateFlow collectors don't retain this host
651
+ // after permanent cell eviction. onAttachedToWindow re-subscribes via the
652
+ // existing `if (flowScope == null)` guard; attach(player) calls
653
+ // resubscribeToPlayer unconditionally, which is the canonical re-entry point.
641
654
  //
642
- // isActive is owned exclusively by the feed's active-cell
643
- // propagation (activatePlayback / deactivatePlayback). Touching it
644
- // here would create a second writer and break the suspend/resume
645
- // case where the active cell never changes — activatePlayback
646
- // wouldn't re-fire on resume, leaving isActive stuck false and
647
- // gating out every updateActiveVideo emit.
648
- //
649
- // Player flow subscriptions are idempotently re-established by
650
- // attach() -> resubscribeToPlayer (which cancels the prior scope
651
- // on entry) when the cell rebinds its player on next visit.
652
- //
653
- // True teardown happens via release() (called by the cell on
654
- // permanent disposal) or implicitly when the host is GC'd along
655
- // with the cell.
655
+ // Do NOT call stopTimeCoalescing() here the time coalescer is owned
656
+ // exclusively by activatePlayback/deactivatePlayback. Stopping it on detach
657
+ // breaks the kept-attached-zone scenario where activatePlayback won't re-fire.
658
+ flowScope?.cancel()
659
+ flowScope = null
656
660
  }
657
661
 
658
662
  }
@@ -33,6 +33,7 @@ import com.shortkit.sdk.feed.ShortKitRefreshState
33
33
  import com.shortkit.sdk.config.VideoOverlayMode
34
34
  import com.shortkit.sdk.feed.FeedPreload
35
35
  import com.shortkit.sdk.feed.ShortKitFeedFragment
36
+ import com.shortkit.sdk.feed.VideoCarouselCellLongPressState
36
37
  import kotlinx.coroutines.CoroutineScope
37
38
  import kotlinx.coroutines.Dispatchers
38
39
  import kotlinx.coroutines.SupervisorJob
@@ -446,6 +447,7 @@ class ShortKitBridge(
446
447
  videos = videoInputs,
447
448
  title = itemObj.optString("title", null),
448
449
  description = itemObj.optString("description", null),
450
+ initialPageIndex = itemObj.optInt("initialPageIndex", -1).takeIf { it >= 0 },
449
451
  author = itemObj.optString("author", null),
450
452
  section = itemObj.optString("section", null),
451
453
  articleUrl = itemObj.optString("articleUrl", null),
@@ -551,6 +553,13 @@ class ShortKitBridge(
551
553
  private var shortKit: ShortKit? = null
552
554
  private var scope: CoroutineScope? = null
553
555
 
556
+ /**
557
+ * Factory for [WritableMap] instances. Overridden in unit tests with
558
+ * `{ JavaOnlyMap() }` to avoid the JNI initialisation that
559
+ * [Arguments.createMap] requires. Production code always uses the default.
560
+ */
561
+ internal var createMap: () -> WritableMap = { Arguments.createMap() }
562
+
554
563
  /** Preload handles keyed by UUID, consumed by feed views via preloadId prop. */
555
564
  var preloadHandles = mutableMapOf<String, FeedPreload>()
556
565
  private set
@@ -733,6 +742,11 @@ class ShortKitBridge(
733
742
  fragment.onVideoCarouselCellTap = { payload ->
734
743
  emitVideoCarouselCellTap(payload.id, payload.index, payload.pageIndex)
735
744
  }
745
+ fragment.onVideoCarouselCellLongPress = { payload ->
746
+ emitVideoCarouselCellLongPress(
747
+ payload.id, payload.index, payload.pageIndex, payload.state
748
+ )
749
+ }
736
750
  // Per-feed transition event. Fires once per transition, bound to this
737
751
  // fragment. Replaces the global player.feedTransition.collect pattern
738
752
  // (which fanned every feed's transitions out to every mounted
@@ -934,6 +948,29 @@ class ShortKitBridge(
934
948
  emitEventOnMain("onVideoCarouselCellTap", params)
935
949
  }
936
950
 
951
+ /**
952
+ * Emit `onVideoCarouselCellLongPress` with the active surface's feedId.
953
+ * Mirrors iOS ShortKitBridge.emitOnMain("onVideoCarouselCellLongPress").
954
+ * State enum is lowercased so JS receives "began" | "ended" | "cancelled"
955
+ * matching the iOS bridge output.
956
+ */
957
+ internal fun emitVideoCarouselCellLongPress(
958
+ itemId: String,
959
+ index: Int,
960
+ pageIndex: Int,
961
+ state: VideoCarouselCellLongPressState,
962
+ ) {
963
+ val feedId = activeSurfaceFeedId()
964
+ val params = createMap().apply {
965
+ putString("feedId", feedId)
966
+ putString("id", itemId)
967
+ putInt("index", index)
968
+ putInt("pageIndex", pageIndex)
969
+ putString("state", state.name.lowercase())
970
+ }
971
+ emitEventOnMain("onVideoCarouselCellLongPress", params)
972
+ }
973
+
937
974
  // ------------------------------------------------------------------
938
975
  // Player commands
939
976
  // ------------------------------------------------------------------
@@ -205,6 +205,7 @@ class ShortKitFeedView(context: Context) : FrameLayout(context) {
205
205
  synchronized(ShortKitBridge.staticPendingFeedViews) {
206
206
  ShortKitBridge.staticPendingFeedViews.remove(this)
207
207
  }
208
+ handler.removeCallbacks(constrainRunnable)
208
209
  // Mirror iOS willMove(toWindow:) at react_native_sdk/ios/ShortKitFeedView.swift:91-99 —
209
210
  // suspend only if leaving the window AND the prop says we should be active.
210
211
  // When active=false the host has already driven the fragment into deactivate
@@ -352,7 +352,7 @@ class ShortKitModule(reactContext: ReactApplicationContext) :
352
352
  "onVideoCarouselCellTap" -> emitOnVideoCarouselCellTap(params)
353
353
  "onVideoCarouselItemChanged" -> emitOnVideoCarouselItemChanged(params)
354
354
  "onCarouselActiveVideoCompleted" -> emitOnCarouselActiveVideoCompleted(params)
355
- "onVideoCarouselCellTap" -> emitOnVideoCarouselCellTap(params)
355
+ "onVideoCarouselCellLongPress" -> emitOnVideoCarouselCellLongPress(params)
356
356
  else -> {
357
357
  android.util.Log.w("SK:Module", "sendEvent: unknown event name '$name', using legacy emitter")
358
358
  reactApplicationContext
@@ -8,7 +8,9 @@ import com.facebook.react.interfaces.TaskInterface
8
8
  import com.facebook.react.interfaces.fabric.ReactSurface
9
9
  import com.shortkit.sdk.model.CarouselImage
10
10
  import com.shortkit.sdk.model.ImageCarouselItem
11
+ import kotlinx.coroutines.isActive
11
12
  import org.junit.Assert.assertEquals
13
+ import org.junit.Assert.assertFalse
12
14
  import org.junit.Assert.assertNotNull
13
15
  import org.junit.Assert.assertTrue
14
16
  import org.junit.Test
@@ -133,4 +135,21 @@ class ReactCarouselOverlayHostLifecycleTest {
133
135
  assertTrue("surface must remain running after resetState", surface.isRunning)
134
136
  assertEquals("resetState must not call surface.stop()", stopsBefore, surface.stopCount)
135
137
  }
138
+
139
+ @Test
140
+ fun `onDetachedFromWindow cancels ioScope and it is recreated on reattach`() {
141
+ val ctx = ApplicationProvider.getApplicationContext<Context>()
142
+ val host = ReactCarouselOverlayHost(ctx)
143
+
144
+ assertTrue("ioScope must be active initially", host.ioScopeForTest.isActive)
145
+
146
+ host.callOnDetachedFromWindow()
147
+
148
+ assertFalse("ioScope must be cancelled after detach", host.ioScopeForTest.isActive)
149
+
150
+ // Simulate reattach
151
+ host.callOnAttachedToWindow()
152
+
153
+ assertTrue("ioScope must be active again after reattach", host.ioScopeForTest.isActive)
154
+ }
136
155
  }
@@ -8,9 +8,14 @@ import com.facebook.react.interfaces.TaskInterface
8
8
  import com.facebook.react.interfaces.fabric.ReactSurface
9
9
  import com.shortkit.sdk.model.ContentItem
10
10
  import com.shortkit.sdk.model.VideoCarouselItem
11
+ import kotlinx.coroutines.CoroutineScope
12
+ import kotlinx.coroutines.Dispatchers
13
+ import kotlinx.coroutines.SupervisorJob
14
+ import kotlinx.coroutines.isActive
11
15
  import org.junit.Assert.assertEquals
12
16
  import org.junit.Assert.assertFalse
13
17
  import org.junit.Assert.assertNotNull
18
+ import org.junit.Assert.assertNull
14
19
  import org.junit.Assert.assertTrue
15
20
  import org.junit.Test
16
21
  import org.junit.runner.RunWith
@@ -175,4 +180,21 @@ class ReactVideoCarouselOverlayHostLifecycleTest {
175
180
  assertTrue("isActive untouched", host.isActive)
176
181
  assertNotNull("currentCarouselItem untouched", host.currentCarouselItem)
177
182
  }
183
+
184
+ @Test
185
+ fun `onDetachedFromWindow cancels flowScope`() {
186
+ val ctx = ApplicationProvider.getApplicationContext<Context>()
187
+ val host = ReactVideoCarouselOverlayHost(ctx)
188
+
189
+ // Inject a live scope directly via the writable test accessor.
190
+ val injected = CoroutineScope(Dispatchers.Main + SupervisorJob())
191
+ host.flowScopeForTest = injected
192
+
193
+ assertTrue("injected scope must be active before detach", injected.isActive)
194
+
195
+ host.callOnDetachedFromWindow()
196
+
197
+ assertNull("flowScope must be null after detach", host.flowScopeForTest)
198
+ assertFalse("injected scope must be cancelled after detach", injected.isActive)
199
+ }
178
200
  }
@@ -0,0 +1,148 @@
1
+ package com.shortkit.reactnative
2
+
3
+ import androidx.test.core.app.ApplicationProvider
4
+ import com.facebook.react.bridge.JavaOnlyMap
5
+ import com.facebook.react.bridge.WritableMap
6
+ import com.shortkit.sdk.feed.VideoCarouselCellLongPressState
7
+ import org.junit.Assert.assertEquals
8
+ import org.junit.Test
9
+ import org.junit.runner.RunWith
10
+ import org.robolectric.RobolectricTestRunner
11
+
12
+ /**
13
+ * JVM unit tests for [ShortKitBridge.emitVideoCarouselCellLongPress].
14
+ *
15
+ * Verifies the event name, state-string lowercasing for all three enum values,
16
+ * and the full payload shape (feedId, id, index, pageIndex).
17
+ *
18
+ * The [JavaOnlyMap] seam avoids the JNI initialisation that
19
+ * [com.facebook.react.bridge.Arguments.createMap] requires in host tests
20
+ * (same pattern used in ReactVideoCarouselOverlayHostEmitTest).
21
+ */
22
+ @RunWith(RobolectricTestRunner::class)
23
+ class ShortKitBridgeLongPressTest {
24
+
25
+ /**
26
+ * Construct a minimal [ShortKitBridge] with a captured [emitEvent] lambda.
27
+ * [JavaOnlyMap] is injected via the [ShortKitBridge.createMap] seam so
28
+ * [Arguments.createMap] (which requires JNI) is never called in tests.
29
+ */
30
+ private fun makeBridge(
31
+ onEmit: (String, WritableMap) -> Unit,
32
+ ): ShortKitBridge {
33
+ val bridge = ShortKitBridge(
34
+ apiKey = "pk_test_unit",
35
+ context = ApplicationProvider.getApplicationContext(),
36
+ hasLoadingView = false,
37
+ clientAppName = null,
38
+ clientAppVersion = null,
39
+ customDimensionsJSON = null,
40
+ debugPanel = false,
41
+ serverTracingEnabled = false,
42
+ consoleTracingEnabled = false,
43
+ emitEvent = onEmit,
44
+ )
45
+ // Override the map factory before any emit call so the bridge never
46
+ // reaches Arguments.createMap() in emitVideoCarouselCellLongPress.
47
+ bridge.createMap = { JavaOnlyMap() }
48
+ return bridge
49
+ }
50
+
51
+ // ------------------------------------------------------------------
52
+ // State-string lowercasing
53
+ // ------------------------------------------------------------------
54
+
55
+ @Test
56
+ fun emitsBegan() {
57
+ val emitted = mutableListOf<Pair<String, WritableMap>>()
58
+ val bridge = makeBridge { name, params -> emitted.add(name to params) }
59
+
60
+ bridge.emitVideoCarouselCellLongPress(
61
+ itemId = "item-1",
62
+ index = 0,
63
+ pageIndex = 0,
64
+ state = VideoCarouselCellLongPressState.BEGAN,
65
+ )
66
+
67
+ assertEquals(1, emitted.size)
68
+ assertEquals("onVideoCarouselCellLongPress", emitted[0].first)
69
+ assertEquals("began", emitted[0].second.getString("state"))
70
+ }
71
+
72
+ @Test
73
+ fun emitsEnded() {
74
+ val emitted = mutableListOf<Pair<String, WritableMap>>()
75
+ val bridge = makeBridge { name, params -> emitted.add(name to params) }
76
+
77
+ bridge.emitVideoCarouselCellLongPress(
78
+ itemId = "item-1",
79
+ index = 0,
80
+ pageIndex = 0,
81
+ state = VideoCarouselCellLongPressState.ENDED,
82
+ )
83
+
84
+ assertEquals(1, emitted.size)
85
+ assertEquals("onVideoCarouselCellLongPress", emitted[0].first)
86
+ assertEquals("ended", emitted[0].second.getString("state"))
87
+ }
88
+
89
+ @Test
90
+ fun emitsCancelled() {
91
+ val emitted = mutableListOf<Pair<String, WritableMap>>()
92
+ val bridge = makeBridge { name, params -> emitted.add(name to params) }
93
+
94
+ bridge.emitVideoCarouselCellLongPress(
95
+ itemId = "item-1",
96
+ index = 0,
97
+ pageIndex = 0,
98
+ state = VideoCarouselCellLongPressState.CANCELLED,
99
+ )
100
+
101
+ assertEquals(1, emitted.size)
102
+ assertEquals("onVideoCarouselCellLongPress", emitted[0].first)
103
+ assertEquals("cancelled", emitted[0].second.getString("state"))
104
+ }
105
+
106
+ // ------------------------------------------------------------------
107
+ // Payload shape
108
+ // ------------------------------------------------------------------
109
+
110
+ @Test
111
+ fun emitsCorrectPayloadFields() {
112
+ val emitted = mutableListOf<Pair<String, WritableMap>>()
113
+ val bridge = makeBridge { name, params -> emitted.add(name to params) }
114
+
115
+ bridge.emitVideoCarouselCellLongPress(
116
+ itemId = "car-1",
117
+ index = 3,
118
+ pageIndex = 2,
119
+ state = VideoCarouselCellLongPressState.BEGAN,
120
+ )
121
+
122
+ val params = emitted[0].second
123
+ assertEquals("car-1", params.getString("id"))
124
+ assertEquals(3, params.getInt("index"))
125
+ assertEquals(2, params.getInt("pageIndex"))
126
+ assertEquals("began", params.getString("state"))
127
+ }
128
+
129
+ @Test
130
+ fun emitsFeedId() {
131
+ val emitted = mutableListOf<Pair<String, WritableMap>>()
132
+ val bridge = makeBridge { name, params -> emitted.add(name to params) }
133
+
134
+ bridge.emitVideoCarouselCellLongPress(
135
+ itemId = "item-1",
136
+ index = 0,
137
+ pageIndex = 0,
138
+ state = VideoCarouselCellLongPressState.BEGAN,
139
+ )
140
+
141
+ // activeSurfaceFeedId() returns "" when no active surface is registered
142
+ // (no ShortKitFeedFragment has been attached in this unit-test environment).
143
+ // The important guarantee is that the "feedId" key is present in the map,
144
+ // matching the iOS bridge payload shape.
145
+ val params = emitted[0].second
146
+ assertEquals("", params.getString("feedId"))
147
+ }
148
+ }
@@ -208,7 +208,8 @@ import ShortKitSDK
208
208
  customDimensions: dimensions,
209
209
  debugPanelEnabled: debugPanel,
210
210
  serverTracingEnabled: serverTracingEnabled,
211
- consoleTracingEnabled: consoleTracingEnabled
211
+ consoleTracingEnabled: consoleTracingEnabled,
212
+ poolDebugEnabled: false
212
213
  )
213
214
  self.shortKit = sdk
214
215
 
@@ -11,9 +11,9 @@
11
11
  <key>CFBundlePackageType</key>
12
12
  <string>FMWK</string>
13
13
  <key>CFBundleVersion</key>
14
- <string>0.2.38</string>
14
+ <string>0.2.40</string>
15
15
  <key>CFBundleShortVersionString</key>
16
- <string>0.2.38</string>
16
+ <string>0.2.40</string>
17
17
  <key>MinimumOSVersion</key>
18
18
  <string>16.0</string>
19
19
  </dict>
@@ -22629,17 +22629,24 @@
22629
22629
  {
22630
22630
  "kind": "Function",
22631
22631
  "name": "activate",
22632
- "printedName": "activate()",
22632
+ "printedName": "activate(caller:)",
22633
22633
  "children": [
22634
22634
  {
22635
22635
  "kind": "TypeNominal",
22636
22636
  "name": "Void",
22637
22637
  "printedName": "()"
22638
+ },
22639
+ {
22640
+ "kind": "TypeNominal",
22641
+ "name": "String",
22642
+ "printedName": "Swift.String",
22643
+ "hasDefaultArg": true,
22644
+ "usr": "s:SS"
22638
22645
  }
22639
22646
  ],
22640
22647
  "declKind": "Func",
22641
- "usr": "s:11ShortKitSDK0aB18FeedViewControllerC8activateyyF",
22642
- "mangledName": "$s11ShortKitSDK0aB18FeedViewControllerC8activateyyF",
22648
+ "usr": "s:11ShortKitSDK0aB18FeedViewControllerC8activate6callerySS_tF",
22649
+ "mangledName": "$s11ShortKitSDK0aB18FeedViewControllerC8activate6callerySS_tF",
22643
22650
  "moduleName": "ShortKitSDK",
22644
22651
  "declAttributes": [
22645
22652
  "Preconcurrency",
@@ -22651,17 +22658,24 @@
22651
22658
  {
22652
22659
  "kind": "Function",
22653
22660
  "name": "deactivate",
22654
- "printedName": "deactivate()",
22661
+ "printedName": "deactivate(caller:)",
22655
22662
  "children": [
22656
22663
  {
22657
22664
  "kind": "TypeNominal",
22658
22665
  "name": "Void",
22659
22666
  "printedName": "()"
22667
+ },
22668
+ {
22669
+ "kind": "TypeNominal",
22670
+ "name": "String",
22671
+ "printedName": "Swift.String",
22672
+ "hasDefaultArg": true,
22673
+ "usr": "s:SS"
22660
22674
  }
22661
22675
  ],
22662
22676
  "declKind": "Func",
22663
- "usr": "s:11ShortKitSDK0aB18FeedViewControllerC10deactivateyyF",
22664
- "mangledName": "$s11ShortKitSDK0aB18FeedViewControllerC10deactivateyyF",
22677
+ "usr": "s:11ShortKitSDK0aB18FeedViewControllerC10deactivate6callerySS_tF",
22678
+ "mangledName": "$s11ShortKitSDK0aB18FeedViewControllerC10deactivate6callerySS_tF",
22665
22679
  "moduleName": "ShortKitSDK",
22666
22680
  "declAttributes": [
22667
22681
  "Preconcurrency",
@@ -52612,21 +52626,21 @@
52612
52626
  {
52613
52627
  "filePath": "\/Users\/michaelseleman\/shortkit\/swift_sdk\/Sources\/ShortKit\/Feed\/FeedViewController.swift",
52614
52628
  "kind": "BooleanLiteral",
52615
- "offset": 126604,
52629
+ "offset": 126724,
52616
52630
  "length": 5,
52617
52631
  "value": "false"
52618
52632
  },
52619
52633
  {
52620
52634
  "filePath": "\/Users\/michaelseleman\/shortkit\/swift_sdk\/Sources\/ShortKit\/Feed\/FeedViewController.swift",
52621
52635
  "kind": "BooleanLiteral",
52622
- "offset": 256537,
52636
+ "offset": 256197,
52623
52637
  "length": 5,
52624
52638
  "value": "false"
52625
52639
  },
52626
52640
  {
52627
52641
  "filePath": "\/Users\/michaelseleman\/shortkit\/swift_sdk\/Sources\/ShortKit\/Feed\/FeedViewController.swift",
52628
52642
  "kind": "BooleanLiteral",
52629
- "offset": 267242,
52643
+ "offset": 266902,
52630
52644
  "length": 5,
52631
52645
  "value": "false"
52632
52646
  },
@@ -52850,14 +52864,14 @@
52850
52864
  {
52851
52865
  "filePath": "\/Users\/michaelseleman\/shortkit\/swift_sdk\/Sources\/ShortKit\/Feed\/VideoCarouselCell.swift",
52852
52866
  "kind": "BooleanLiteral",
52853
- "offset": 31591,
52867
+ "offset": 45026,
52854
52868
  "length": 4,
52855
52869
  "value": "true"
52856
52870
  },
52857
52871
  {
52858
52872
  "filePath": "\/Users\/michaelseleman\/shortkit\/swift_sdk\/Sources\/ShortKit\/Feed\/VideoCarouselCell.swift",
52859
52873
  "kind": "IntegerLiteral",
52860
- "offset": 38856,
52874
+ "offset": 52291,
52861
52875
  "length": 1,
52862
52876
  "value": "0"
52863
52877
  },
@@ -53517,7 +53531,7 @@
53517
53531
  "kind": "StringLiteral",
53518
53532
  "offset": 154,
53519
53533
  "length": 8,
53520
- "value": "\"0.2.38\""
53534
+ "value": "\"0.2.40\""
53521
53535
  },
53522
53536
  {
53523
53537
  "filePath": "\/Users\/michaelseleman\/shortkit\/swift_sdk\/Sources\/ShortKit\/ShortKit.swift",
@@ -600,8 +600,8 @@ public enum VideoCarouselCellLongPressState : Swift.String {
600
600
  @_Concurrency.MainActor @preconcurrency @objc override dynamic public func viewWillDisappear(_ animated: Swift.Bool)
601
601
  @available(*, deprecated, message: "Pass lifecycle: .manual to ShortKitFeedViewController's initializer instead.")
602
602
  @_Concurrency.MainActor @preconcurrency public func setBridgeManaged()
603
- @_Concurrency.MainActor @preconcurrency public func activate()
604
- @_Concurrency.MainActor @preconcurrency public func deactivate()
603
+ @_Concurrency.MainActor @preconcurrency public func activate(caller: Swift.String = #function)
604
+ @_Concurrency.MainActor @preconcurrency public func deactivate(caller: Swift.String = #function)
605
605
  @_Concurrency.MainActor @preconcurrency @objc override dynamic public func viewDidDisappear(_ animated: Swift.Bool)
606
606
  @_Concurrency.MainActor @preconcurrency @objc override dynamic public var supportedInterfaceOrientations: UIKit.UIInterfaceOrientationMask {
607
607
  @objc get
@@ -600,8 +600,8 @@ public enum VideoCarouselCellLongPressState : Swift.String {
600
600
  @_Concurrency.MainActor @preconcurrency @objc override dynamic public func viewWillDisappear(_ animated: Swift.Bool)
601
601
  @available(*, deprecated, message: "Pass lifecycle: .manual to ShortKitFeedViewController's initializer instead.")
602
602
  @_Concurrency.MainActor @preconcurrency public func setBridgeManaged()
603
- @_Concurrency.MainActor @preconcurrency public func activate()
604
- @_Concurrency.MainActor @preconcurrency public func deactivate()
603
+ @_Concurrency.MainActor @preconcurrency public func activate(caller: Swift.String = #function)
604
+ @_Concurrency.MainActor @preconcurrency public func deactivate(caller: Swift.String = #function)
605
605
  @_Concurrency.MainActor @preconcurrency @objc override dynamic public func viewDidDisappear(_ animated: Swift.Bool)
606
606
  @_Concurrency.MainActor @preconcurrency @objc override dynamic public var supportedInterfaceOrientations: UIKit.UIInterfaceOrientationMask {
607
607
  @objc get
@@ -10,23 +10,23 @@
10
10
  </data>
11
11
  <key>Info.plist</key>
12
12
  <data>
13
- OPbiGQgVvhc9i76qqjEwO15NZ9U=
13
+ 23w227OWxjyMmGQaLZT1I5SzVXU=
14
14
  </data>
15
15
  <key>Modules/ShortKitSDK.swiftmodule/arm64-apple-ios.abi.json</key>
16
16
  <data>
17
- bmR7HZYLcS/c/oJglUFjXRw3kcs=
17
+ hGf1d05M6JqCtRSCa1YzvqrWqFw=
18
18
  </data>
19
19
  <key>Modules/ShortKitSDK.swiftmodule/arm64-apple-ios.private.swiftinterface</key>
20
20
  <data>
21
- mW6r7/iq/Jg6ZI9W1lRMm1aLB4U=
21
+ 9FqsjTg24DzaleUB7JnSq8UQqsY=
22
22
  </data>
23
23
  <key>Modules/ShortKitSDK.swiftmodule/arm64-apple-ios.swiftdoc</key>
24
24
  <data>
25
- l1kCcZKKkWNHXRUj315dwvKpWXM=
25
+ WDYFmyxlo+9gLMt6pL15d/2NK5w=
26
26
  </data>
27
27
  <key>Modules/ShortKitSDK.swiftmodule/arm64-apple-ios.swiftinterface</key>
28
28
  <data>
29
- mW6r7/iq/Jg6ZI9W1lRMm1aLB4U=
29
+ 9FqsjTg24DzaleUB7JnSq8UQqsY=
30
30
  </data>
31
31
  <key>Modules/module.modulemap</key>
32
32
  <data>
@@ -50,28 +50,28 @@
50
50
  <dict>
51
51
  <key>hash2</key>
52
52
  <data>
53
- k2NIGYptDbpRKu5vmsmuboSr7G2j4qb9eftlewub0LA=
53
+ 6ykDmHgBfxYifZSz+fro3Yvp/b++qes+KaY7NMNET70=
54
54
  </data>
55
55
  </dict>
56
56
  <key>Modules/ShortKitSDK.swiftmodule/arm64-apple-ios.private.swiftinterface</key>
57
57
  <dict>
58
58
  <key>hash2</key>
59
59
  <data>
60
- iY6z+DXd1iuZbhyTgR+zIsrqnFIyzYlJuBvur5T5jXY=
60
+ eZ8oFee1rUs7ne3rIUBvSKdlQGoaO+7wds7ouBenXQM=
61
61
  </data>
62
62
  </dict>
63
63
  <key>Modules/ShortKitSDK.swiftmodule/arm64-apple-ios.swiftdoc</key>
64
64
  <dict>
65
65
  <key>hash2</key>
66
66
  <data>
67
- 9ubaUPA066m+2mexrnZpAFVqLjQ7fJ3mmYL75KIJWZI=
67
+ Fbc2YsVV3eEvWzjX2AhdqAZOrrqNyD/dVZR0rjVgDxQ=
68
68
  </data>
69
69
  </dict>
70
70
  <key>Modules/ShortKitSDK.swiftmodule/arm64-apple-ios.swiftinterface</key>
71
71
  <dict>
72
72
  <key>hash2</key>
73
73
  <data>
74
- iY6z+DXd1iuZbhyTgR+zIsrqnFIyzYlJuBvur5T5jXY=
74
+ eZ8oFee1rUs7ne3rIUBvSKdlQGoaO+7wds7ouBenXQM=
75
75
  </data>
76
76
  </dict>
77
77
  <key>Modules/module.modulemap</key>
@@ -11,9 +11,9 @@
11
11
  <key>CFBundlePackageType</key>
12
12
  <string>FMWK</string>
13
13
  <key>CFBundleVersion</key>
14
- <string>0.2.38</string>
14
+ <string>0.2.40</string>
15
15
  <key>CFBundleShortVersionString</key>
16
- <string>0.2.38</string>
16
+ <string>0.2.40</string>
17
17
  <key>MinimumOSVersion</key>
18
18
  <string>16.0</string>
19
19
  </dict>
@@ -22629,17 +22629,24 @@
22629
22629
  {
22630
22630
  "kind": "Function",
22631
22631
  "name": "activate",
22632
- "printedName": "activate()",
22632
+ "printedName": "activate(caller:)",
22633
22633
  "children": [
22634
22634
  {
22635
22635
  "kind": "TypeNominal",
22636
22636
  "name": "Void",
22637
22637
  "printedName": "()"
22638
+ },
22639
+ {
22640
+ "kind": "TypeNominal",
22641
+ "name": "String",
22642
+ "printedName": "Swift.String",
22643
+ "hasDefaultArg": true,
22644
+ "usr": "s:SS"
22638
22645
  }
22639
22646
  ],
22640
22647
  "declKind": "Func",
22641
- "usr": "s:11ShortKitSDK0aB18FeedViewControllerC8activateyyF",
22642
- "mangledName": "$s11ShortKitSDK0aB18FeedViewControllerC8activateyyF",
22648
+ "usr": "s:11ShortKitSDK0aB18FeedViewControllerC8activate6callerySS_tF",
22649
+ "mangledName": "$s11ShortKitSDK0aB18FeedViewControllerC8activate6callerySS_tF",
22643
22650
  "moduleName": "ShortKitSDK",
22644
22651
  "declAttributes": [
22645
22652
  "Preconcurrency",
@@ -22651,17 +22658,24 @@
22651
22658
  {
22652
22659
  "kind": "Function",
22653
22660
  "name": "deactivate",
22654
- "printedName": "deactivate()",
22661
+ "printedName": "deactivate(caller:)",
22655
22662
  "children": [
22656
22663
  {
22657
22664
  "kind": "TypeNominal",
22658
22665
  "name": "Void",
22659
22666
  "printedName": "()"
22667
+ },
22668
+ {
22669
+ "kind": "TypeNominal",
22670
+ "name": "String",
22671
+ "printedName": "Swift.String",
22672
+ "hasDefaultArg": true,
22673
+ "usr": "s:SS"
22660
22674
  }
22661
22675
  ],
22662
22676
  "declKind": "Func",
22663
- "usr": "s:11ShortKitSDK0aB18FeedViewControllerC10deactivateyyF",
22664
- "mangledName": "$s11ShortKitSDK0aB18FeedViewControllerC10deactivateyyF",
22677
+ "usr": "s:11ShortKitSDK0aB18FeedViewControllerC10deactivate6callerySS_tF",
22678
+ "mangledName": "$s11ShortKitSDK0aB18FeedViewControllerC10deactivate6callerySS_tF",
22665
22679
  "moduleName": "ShortKitSDK",
22666
22680
  "declAttributes": [
22667
22681
  "Preconcurrency",
@@ -52612,21 +52626,21 @@
52612
52626
  {
52613
52627
  "filePath": "\/Users\/michaelseleman\/shortkit\/swift_sdk\/Sources\/ShortKit\/Feed\/FeedViewController.swift",
52614
52628
  "kind": "BooleanLiteral",
52615
- "offset": 126604,
52629
+ "offset": 126724,
52616
52630
  "length": 5,
52617
52631
  "value": "false"
52618
52632
  },
52619
52633
  {
52620
52634
  "filePath": "\/Users\/michaelseleman\/shortkit\/swift_sdk\/Sources\/ShortKit\/Feed\/FeedViewController.swift",
52621
52635
  "kind": "BooleanLiteral",
52622
- "offset": 256537,
52636
+ "offset": 256197,
52623
52637
  "length": 5,
52624
52638
  "value": "false"
52625
52639
  },
52626
52640
  {
52627
52641
  "filePath": "\/Users\/michaelseleman\/shortkit\/swift_sdk\/Sources\/ShortKit\/Feed\/FeedViewController.swift",
52628
52642
  "kind": "BooleanLiteral",
52629
- "offset": 267242,
52643
+ "offset": 266902,
52630
52644
  "length": 5,
52631
52645
  "value": "false"
52632
52646
  },
@@ -52850,14 +52864,14 @@
52850
52864
  {
52851
52865
  "filePath": "\/Users\/michaelseleman\/shortkit\/swift_sdk\/Sources\/ShortKit\/Feed\/VideoCarouselCell.swift",
52852
52866
  "kind": "BooleanLiteral",
52853
- "offset": 31591,
52867
+ "offset": 45026,
52854
52868
  "length": 4,
52855
52869
  "value": "true"
52856
52870
  },
52857
52871
  {
52858
52872
  "filePath": "\/Users\/michaelseleman\/shortkit\/swift_sdk\/Sources\/ShortKit\/Feed\/VideoCarouselCell.swift",
52859
52873
  "kind": "IntegerLiteral",
52860
- "offset": 38856,
52874
+ "offset": 52291,
52861
52875
  "length": 1,
52862
52876
  "value": "0"
52863
52877
  },
@@ -53517,7 +53531,7 @@
53517
53531
  "kind": "StringLiteral",
53518
53532
  "offset": 154,
53519
53533
  "length": 8,
53520
- "value": "\"0.2.38\""
53534
+ "value": "\"0.2.40\""
53521
53535
  },
53522
53536
  {
53523
53537
  "filePath": "\/Users\/michaelseleman\/shortkit\/swift_sdk\/Sources\/ShortKit\/ShortKit.swift",
@@ -600,8 +600,8 @@ public enum VideoCarouselCellLongPressState : Swift.String {
600
600
  @_Concurrency.MainActor @preconcurrency @objc override dynamic public func viewWillDisappear(_ animated: Swift.Bool)
601
601
  @available(*, deprecated, message: "Pass lifecycle: .manual to ShortKitFeedViewController's initializer instead.")
602
602
  @_Concurrency.MainActor @preconcurrency public func setBridgeManaged()
603
- @_Concurrency.MainActor @preconcurrency public func activate()
604
- @_Concurrency.MainActor @preconcurrency public func deactivate()
603
+ @_Concurrency.MainActor @preconcurrency public func activate(caller: Swift.String = #function)
604
+ @_Concurrency.MainActor @preconcurrency public func deactivate(caller: Swift.String = #function)
605
605
  @_Concurrency.MainActor @preconcurrency @objc override dynamic public func viewDidDisappear(_ animated: Swift.Bool)
606
606
  @_Concurrency.MainActor @preconcurrency @objc override dynamic public var supportedInterfaceOrientations: UIKit.UIInterfaceOrientationMask {
607
607
  @objc get
@@ -600,8 +600,8 @@ public enum VideoCarouselCellLongPressState : Swift.String {
600
600
  @_Concurrency.MainActor @preconcurrency @objc override dynamic public func viewWillDisappear(_ animated: Swift.Bool)
601
601
  @available(*, deprecated, message: "Pass lifecycle: .manual to ShortKitFeedViewController's initializer instead.")
602
602
  @_Concurrency.MainActor @preconcurrency public func setBridgeManaged()
603
- @_Concurrency.MainActor @preconcurrency public func activate()
604
- @_Concurrency.MainActor @preconcurrency public func deactivate()
603
+ @_Concurrency.MainActor @preconcurrency public func activate(caller: Swift.String = #function)
604
+ @_Concurrency.MainActor @preconcurrency public func deactivate(caller: Swift.String = #function)
605
605
  @_Concurrency.MainActor @preconcurrency @objc override dynamic public func viewDidDisappear(_ animated: Swift.Bool)
606
606
  @_Concurrency.MainActor @preconcurrency @objc override dynamic public var supportedInterfaceOrientations: UIKit.UIInterfaceOrientationMask {
607
607
  @objc get
@@ -22629,17 +22629,24 @@
22629
22629
  {
22630
22630
  "kind": "Function",
22631
22631
  "name": "activate",
22632
- "printedName": "activate()",
22632
+ "printedName": "activate(caller:)",
22633
22633
  "children": [
22634
22634
  {
22635
22635
  "kind": "TypeNominal",
22636
22636
  "name": "Void",
22637
22637
  "printedName": "()"
22638
+ },
22639
+ {
22640
+ "kind": "TypeNominal",
22641
+ "name": "String",
22642
+ "printedName": "Swift.String",
22643
+ "hasDefaultArg": true,
22644
+ "usr": "s:SS"
22638
22645
  }
22639
22646
  ],
22640
22647
  "declKind": "Func",
22641
- "usr": "s:11ShortKitSDK0aB18FeedViewControllerC8activateyyF",
22642
- "mangledName": "$s11ShortKitSDK0aB18FeedViewControllerC8activateyyF",
22648
+ "usr": "s:11ShortKitSDK0aB18FeedViewControllerC8activate6callerySS_tF",
22649
+ "mangledName": "$s11ShortKitSDK0aB18FeedViewControllerC8activate6callerySS_tF",
22643
22650
  "moduleName": "ShortKitSDK",
22644
22651
  "declAttributes": [
22645
22652
  "Preconcurrency",
@@ -22651,17 +22658,24 @@
22651
22658
  {
22652
22659
  "kind": "Function",
22653
22660
  "name": "deactivate",
22654
- "printedName": "deactivate()",
22661
+ "printedName": "deactivate(caller:)",
22655
22662
  "children": [
22656
22663
  {
22657
22664
  "kind": "TypeNominal",
22658
22665
  "name": "Void",
22659
22666
  "printedName": "()"
22667
+ },
22668
+ {
22669
+ "kind": "TypeNominal",
22670
+ "name": "String",
22671
+ "printedName": "Swift.String",
22672
+ "hasDefaultArg": true,
22673
+ "usr": "s:SS"
22660
22674
  }
22661
22675
  ],
22662
22676
  "declKind": "Func",
22663
- "usr": "s:11ShortKitSDK0aB18FeedViewControllerC10deactivateyyF",
22664
- "mangledName": "$s11ShortKitSDK0aB18FeedViewControllerC10deactivateyyF",
22677
+ "usr": "s:11ShortKitSDK0aB18FeedViewControllerC10deactivate6callerySS_tF",
22678
+ "mangledName": "$s11ShortKitSDK0aB18FeedViewControllerC10deactivate6callerySS_tF",
22665
22679
  "moduleName": "ShortKitSDK",
22666
22680
  "declAttributes": [
22667
22681
  "Preconcurrency",
@@ -52612,21 +52626,21 @@
52612
52626
  {
52613
52627
  "filePath": "\/Users\/michaelseleman\/shortkit\/swift_sdk\/Sources\/ShortKit\/Feed\/FeedViewController.swift",
52614
52628
  "kind": "BooleanLiteral",
52615
- "offset": 126604,
52629
+ "offset": 126724,
52616
52630
  "length": 5,
52617
52631
  "value": "false"
52618
52632
  },
52619
52633
  {
52620
52634
  "filePath": "\/Users\/michaelseleman\/shortkit\/swift_sdk\/Sources\/ShortKit\/Feed\/FeedViewController.swift",
52621
52635
  "kind": "BooleanLiteral",
52622
- "offset": 256537,
52636
+ "offset": 256197,
52623
52637
  "length": 5,
52624
52638
  "value": "false"
52625
52639
  },
52626
52640
  {
52627
52641
  "filePath": "\/Users\/michaelseleman\/shortkit\/swift_sdk\/Sources\/ShortKit\/Feed\/FeedViewController.swift",
52628
52642
  "kind": "BooleanLiteral",
52629
- "offset": 267242,
52643
+ "offset": 266902,
52630
52644
  "length": 5,
52631
52645
  "value": "false"
52632
52646
  },
@@ -52850,14 +52864,14 @@
52850
52864
  {
52851
52865
  "filePath": "\/Users\/michaelseleman\/shortkit\/swift_sdk\/Sources\/ShortKit\/Feed\/VideoCarouselCell.swift",
52852
52866
  "kind": "BooleanLiteral",
52853
- "offset": 31591,
52867
+ "offset": 45026,
52854
52868
  "length": 4,
52855
52869
  "value": "true"
52856
52870
  },
52857
52871
  {
52858
52872
  "filePath": "\/Users\/michaelseleman\/shortkit\/swift_sdk\/Sources\/ShortKit\/Feed\/VideoCarouselCell.swift",
52859
52873
  "kind": "IntegerLiteral",
52860
- "offset": 38856,
52874
+ "offset": 52291,
52861
52875
  "length": 1,
52862
52876
  "value": "0"
52863
52877
  },
@@ -53517,7 +53531,7 @@
53517
53531
  "kind": "StringLiteral",
53518
53532
  "offset": 154,
53519
53533
  "length": 8,
53520
- "value": "\"0.2.38\""
53534
+ "value": "\"0.2.40\""
53521
53535
  },
53522
53536
  {
53523
53537
  "filePath": "\/Users\/michaelseleman\/shortkit\/swift_sdk\/Sources\/ShortKit\/ShortKit.swift",
@@ -600,8 +600,8 @@ public enum VideoCarouselCellLongPressState : Swift.String {
600
600
  @_Concurrency.MainActor @preconcurrency @objc override dynamic public func viewWillDisappear(_ animated: Swift.Bool)
601
601
  @available(*, deprecated, message: "Pass lifecycle: .manual to ShortKitFeedViewController's initializer instead.")
602
602
  @_Concurrency.MainActor @preconcurrency public func setBridgeManaged()
603
- @_Concurrency.MainActor @preconcurrency public func activate()
604
- @_Concurrency.MainActor @preconcurrency public func deactivate()
603
+ @_Concurrency.MainActor @preconcurrency public func activate(caller: Swift.String = #function)
604
+ @_Concurrency.MainActor @preconcurrency public func deactivate(caller: Swift.String = #function)
605
605
  @_Concurrency.MainActor @preconcurrency @objc override dynamic public func viewDidDisappear(_ animated: Swift.Bool)
606
606
  @_Concurrency.MainActor @preconcurrency @objc override dynamic public var supportedInterfaceOrientations: UIKit.UIInterfaceOrientationMask {
607
607
  @objc get
@@ -600,8 +600,8 @@ public enum VideoCarouselCellLongPressState : Swift.String {
600
600
  @_Concurrency.MainActor @preconcurrency @objc override dynamic public func viewWillDisappear(_ animated: Swift.Bool)
601
601
  @available(*, deprecated, message: "Pass lifecycle: .manual to ShortKitFeedViewController's initializer instead.")
602
602
  @_Concurrency.MainActor @preconcurrency public func setBridgeManaged()
603
- @_Concurrency.MainActor @preconcurrency public func activate()
604
- @_Concurrency.MainActor @preconcurrency public func deactivate()
603
+ @_Concurrency.MainActor @preconcurrency public func activate(caller: Swift.String = #function)
604
+ @_Concurrency.MainActor @preconcurrency public func deactivate(caller: Swift.String = #function)
605
605
  @_Concurrency.MainActor @preconcurrency @objc override dynamic public func viewDidDisappear(_ animated: Swift.Bool)
606
606
  @_Concurrency.MainActor @preconcurrency @objc override dynamic public var supportedInterfaceOrientations: UIKit.UIInterfaceOrientationMask {
607
607
  @objc get
@@ -10,39 +10,39 @@
10
10
  </data>
11
11
  <key>Info.plist</key>
12
12
  <data>
13
- OPbiGQgVvhc9i76qqjEwO15NZ9U=
13
+ 23w227OWxjyMmGQaLZT1I5SzVXU=
14
14
  </data>
15
15
  <key>Modules/ShortKitSDK.swiftmodule/arm64-apple-ios-simulator.abi.json</key>
16
16
  <data>
17
- bmR7HZYLcS/c/oJglUFjXRw3kcs=
17
+ hGf1d05M6JqCtRSCa1YzvqrWqFw=
18
18
  </data>
19
19
  <key>Modules/ShortKitSDK.swiftmodule/arm64-apple-ios-simulator.private.swiftinterface</key>
20
20
  <data>
21
- VtQKD6iU2DxNLUgN8Nm9hVEd+LA=
21
+ kMD88dAC4/UAXQveBEVyu416rZk=
22
22
  </data>
23
23
  <key>Modules/ShortKitSDK.swiftmodule/arm64-apple-ios-simulator.swiftdoc</key>
24
24
  <data>
25
- RYBSyi3j5xH2WhtxZngr8vlpDDM=
25
+ VOTbFDsFlUk+zeSbdHV3CUJ4sbs=
26
26
  </data>
27
27
  <key>Modules/ShortKitSDK.swiftmodule/arm64-apple-ios-simulator.swiftinterface</key>
28
28
  <data>
29
- VtQKD6iU2DxNLUgN8Nm9hVEd+LA=
29
+ kMD88dAC4/UAXQveBEVyu416rZk=
30
30
  </data>
31
31
  <key>Modules/ShortKitSDK.swiftmodule/x86_64-apple-ios-simulator.abi.json</key>
32
32
  <data>
33
- bmR7HZYLcS/c/oJglUFjXRw3kcs=
33
+ hGf1d05M6JqCtRSCa1YzvqrWqFw=
34
34
  </data>
35
35
  <key>Modules/ShortKitSDK.swiftmodule/x86_64-apple-ios-simulator.private.swiftinterface</key>
36
36
  <data>
37
- l/8aNIdTZYrYfdGjeCunQev+z2s=
37
+ S7MSFMJ213kJdVpeQfSzi4JI0aY=
38
38
  </data>
39
39
  <key>Modules/ShortKitSDK.swiftmodule/x86_64-apple-ios-simulator.swiftdoc</key>
40
40
  <data>
41
- dK384fZQxXLFp6AahpyFqGJOfnY=
41
+ fULOA1HVzJwVPDNXTIp5uNMx9R8=
42
42
  </data>
43
43
  <key>Modules/ShortKitSDK.swiftmodule/x86_64-apple-ios-simulator.swiftinterface</key>
44
44
  <data>
45
- l/8aNIdTZYrYfdGjeCunQev+z2s=
45
+ S7MSFMJ213kJdVpeQfSzi4JI0aY=
46
46
  </data>
47
47
  <key>Modules/module.modulemap</key>
48
48
  <data>
@@ -66,56 +66,56 @@
66
66
  <dict>
67
67
  <key>hash2</key>
68
68
  <data>
69
- k2NIGYptDbpRKu5vmsmuboSr7G2j4qb9eftlewub0LA=
69
+ 6ykDmHgBfxYifZSz+fro3Yvp/b++qes+KaY7NMNET70=
70
70
  </data>
71
71
  </dict>
72
72
  <key>Modules/ShortKitSDK.swiftmodule/arm64-apple-ios-simulator.private.swiftinterface</key>
73
73
  <dict>
74
74
  <key>hash2</key>
75
75
  <data>
76
- rf7zOX3BNWSgC2Lvt4rs/pTvzoqY4r2easqa7IcD/BY=
76
+ 4q40ucTr1qUkFbVYoihDDoBnnICmQ/lO/7JH1WKQzcw=
77
77
  </data>
78
78
  </dict>
79
79
  <key>Modules/ShortKitSDK.swiftmodule/arm64-apple-ios-simulator.swiftdoc</key>
80
80
  <dict>
81
81
  <key>hash2</key>
82
82
  <data>
83
- U33t59L18Q9DqIsgOyi6pcHV+IuHxLRdntw2IQW1DLo=
83
+ dKQ8XFw0Is3GUAQat76xrMwYPR/5ZRiZoANThtyA56Q=
84
84
  </data>
85
85
  </dict>
86
86
  <key>Modules/ShortKitSDK.swiftmodule/arm64-apple-ios-simulator.swiftinterface</key>
87
87
  <dict>
88
88
  <key>hash2</key>
89
89
  <data>
90
- rf7zOX3BNWSgC2Lvt4rs/pTvzoqY4r2easqa7IcD/BY=
90
+ 4q40ucTr1qUkFbVYoihDDoBnnICmQ/lO/7JH1WKQzcw=
91
91
  </data>
92
92
  </dict>
93
93
  <key>Modules/ShortKitSDK.swiftmodule/x86_64-apple-ios-simulator.abi.json</key>
94
94
  <dict>
95
95
  <key>hash2</key>
96
96
  <data>
97
- k2NIGYptDbpRKu5vmsmuboSr7G2j4qb9eftlewub0LA=
97
+ 6ykDmHgBfxYifZSz+fro3Yvp/b++qes+KaY7NMNET70=
98
98
  </data>
99
99
  </dict>
100
100
  <key>Modules/ShortKitSDK.swiftmodule/x86_64-apple-ios-simulator.private.swiftinterface</key>
101
101
  <dict>
102
102
  <key>hash2</key>
103
103
  <data>
104
- c3dj4IBlPLhIqbUCIQDEpGHL5WE7f1b16++z2hPOOTU=
104
+ E1GiseiMFLYmROiZwBW1bJ9EOsVO+0XjhLoQF9rW+Gk=
105
105
  </data>
106
106
  </dict>
107
107
  <key>Modules/ShortKitSDK.swiftmodule/x86_64-apple-ios-simulator.swiftdoc</key>
108
108
  <dict>
109
109
  <key>hash2</key>
110
110
  <data>
111
- kFhyC63KxDPM8/iRTzRd5M1FO7ojEQzF0migxa4EIpU=
111
+ T8grir+EcdMC7s5ILrY4dZfCi++IEzyJW4sMxHJ6QYc=
112
112
  </data>
113
113
  </dict>
114
114
  <key>Modules/ShortKitSDK.swiftmodule/x86_64-apple-ios-simulator.swiftinterface</key>
115
115
  <dict>
116
116
  <key>hash2</key>
117
117
  <data>
118
- c3dj4IBlPLhIqbUCIQDEpGHL5WE7f1b16++z2hPOOTU=
118
+ E1GiseiMFLYmROiZwBW1bJ9EOsVO+0XjhLoQF9rW+Gk=
119
119
  </data>
120
120
  </dict>
121
121
  <key>Modules/module.modulemap</key>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shortkitsdk/react-native",
3
- "version": "0.2.38",
3
+ "version": "0.2.40",
4
4
  "description": "ShortKit React Native SDK — short-form video feed",
5
5
  "react-native": "src/index",
6
6
  "source": "src/index",