@shortkitsdk/react-native 0.2.22 → 0.2.24

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 (30) hide show
  1. package/android/libs/shortkit-release.aar +0 -0
  2. package/android/src/main/java/com/shortkit/reactnative/ShortKitBridge.kt +10 -7
  3. package/ios/ShortKitBridge.swift +97 -2
  4. package/ios/ShortKitModule.mm +25 -2
  5. package/ios/ShortKitSDK.xcframework/Info.plist +5 -5
  6. package/ios/ShortKitSDK.xcframework/ios-arm64/ShortKitSDK.framework/Info.plist +2 -2
  7. package/ios/ShortKitSDK.xcframework/ios-arm64/ShortKitSDK.framework/Modules/ShortKitSDK.swiftmodule/arm64-apple-ios.abi.json +4998 -2499
  8. package/ios/ShortKitSDK.xcframework/ios-arm64/ShortKitSDK.framework/Modules/ShortKitSDK.swiftmodule/arm64-apple-ios.private.swiftinterface +64 -1
  9. package/ios/ShortKitSDK.xcframework/ios-arm64/ShortKitSDK.framework/Modules/ShortKitSDK.swiftmodule/arm64-apple-ios.swiftdoc +0 -0
  10. package/ios/ShortKitSDK.xcframework/ios-arm64/ShortKitSDK.framework/Modules/ShortKitSDK.swiftmodule/arm64-apple-ios.swiftinterface +64 -1
  11. package/ios/ShortKitSDK.xcframework/ios-arm64/ShortKitSDK.framework/ShortKitSDK +0 -0
  12. package/ios/ShortKitSDK.xcframework/ios-arm64/ShortKitSDK.framework/_CodeSignature/CodeResources +9 -9
  13. package/ios/ShortKitSDK.xcframework/ios-arm64_x86_64-simulator/ShortKitSDK.framework/Info.plist +2 -2
  14. package/ios/ShortKitSDK.xcframework/ios-arm64_x86_64-simulator/ShortKitSDK.framework/Modules/ShortKitSDK.swiftmodule/arm64-apple-ios-simulator.abi.json +4998 -2499
  15. package/ios/ShortKitSDK.xcframework/ios-arm64_x86_64-simulator/ShortKitSDK.framework/Modules/ShortKitSDK.swiftmodule/arm64-apple-ios-simulator.private.swiftinterface +64 -1
  16. package/ios/ShortKitSDK.xcframework/ios-arm64_x86_64-simulator/ShortKitSDK.framework/Modules/ShortKitSDK.swiftmodule/arm64-apple-ios-simulator.swiftdoc +0 -0
  17. package/ios/ShortKitSDK.xcframework/ios-arm64_x86_64-simulator/ShortKitSDK.framework/Modules/ShortKitSDK.swiftmodule/arm64-apple-ios-simulator.swiftinterface +64 -1
  18. package/ios/ShortKitSDK.xcframework/ios-arm64_x86_64-simulator/ShortKitSDK.framework/Modules/ShortKitSDK.swiftmodule/x86_64-apple-ios-simulator.abi.json +4998 -2499
  19. package/ios/ShortKitSDK.xcframework/ios-arm64_x86_64-simulator/ShortKitSDK.framework/Modules/ShortKitSDK.swiftmodule/x86_64-apple-ios-simulator.private.swiftinterface +64 -1
  20. package/ios/ShortKitSDK.xcframework/ios-arm64_x86_64-simulator/ShortKitSDK.framework/Modules/ShortKitSDK.swiftmodule/x86_64-apple-ios-simulator.swiftdoc +0 -0
  21. package/ios/ShortKitSDK.xcframework/ios-arm64_x86_64-simulator/ShortKitSDK.framework/Modules/ShortKitSDK.swiftmodule/x86_64-apple-ios-simulator.swiftinterface +64 -1
  22. package/ios/ShortKitSDK.xcframework/ios-arm64_x86_64-simulator/ShortKitSDK.framework/ShortKitSDK +0 -0
  23. package/ios/ShortKitSDK.xcframework/ios-arm64_x86_64-simulator/ShortKitSDK.framework/_CodeSignature/CodeResources +17 -17
  24. package/package.json +1 -1
  25. package/src/ShortKitCommands.ts +3 -0
  26. package/src/ShortKitContext.ts +6 -0
  27. package/src/ShortKitProvider.tsx +45 -1
  28. package/src/index.ts +2 -0
  29. package/src/specs/NativeShortKitModule.ts +29 -0
  30. package/src/types.ts +44 -1
@@ -337,6 +337,34 @@ extension ShortKitSDK.ShortKitDelegate {
337
337
  public func shortKit(_ shortKit: ShortKitSDK.ShortKit, didTapContent contentId: Swift.String, at index: Swift.Int)
338
338
  public func shortKit(_ shortKit: ShortKitSDK.ShortKit, didFetchContentItems items: [ShortKitSDK.ContentItem])
339
339
  }
340
+ public protocol ShortKitDownloadDelegate : AnyObject {
341
+ func shortKit(_ shortKit: ShortKitSDK.ShortKit, didStartDownload item: ShortKitSDK.ContentItem)
342
+ func shortKit(_ shortKit: ShortKitSDK.ShortKit, didUpdateDownloadProgress item: ShortKitSDK.ContentItem, progress: Swift.Double)
343
+ func shortKit(_ shortKit: ShortKitSDK.ShortKit, didCompleteDownload item: ShortKitSDK.ContentItem, fileURL: Foundation.URL)
344
+ func shortKit(_ shortKit: ShortKitSDK.ShortKit, didFailDownload item: ShortKitSDK.ContentItem, error: ShortKitSDK.ShortKitDownloadError)
345
+ }
346
+ extension ShortKitSDK.ShortKitDownloadDelegate {
347
+ public func shortKit(_ shortKit: ShortKitSDK.ShortKit, didStartDownload item: ShortKitSDK.ContentItem)
348
+ public func shortKit(_ shortKit: ShortKitSDK.ShortKit, didUpdateDownloadProgress item: ShortKitSDK.ContentItem, progress: Swift.Double)
349
+ public func shortKit(_ shortKit: ShortKitSDK.ShortKit, didCompleteDownload item: ShortKitSDK.ContentItem, fileURL: Foundation.URL)
350
+ public func shortKit(_ shortKit: ShortKitSDK.ShortKit, didFailDownload item: ShortKitSDK.ContentItem, error: ShortKitSDK.ShortKitDownloadError)
351
+ }
352
+ public enum DownloadMode {
353
+ case nonInterruptive
354
+ case interruptive
355
+ public static func == (a: ShortKitSDK.DownloadMode, b: ShortKitSDK.DownloadMode) -> Swift.Bool
356
+ public func hash(into hasher: inout Swift.Hasher)
357
+ public var hashValue: Swift.Int {
358
+ get
359
+ }
360
+ }
361
+ public enum ShortKitDownloadError : Swift.Error {
362
+ case downloadNotAvailable
363
+ case downloadInProgress
364
+ case networkError(any Swift.Error)
365
+ case httpError(statusCode: Swift.Int)
366
+ case cancelled
367
+ }
340
368
  @_hasMissingDesignatedInitializers final public class FeedPreload : @unchecked Swift.Sendable {
341
369
  @objc deinit
342
370
  }
@@ -479,14 +507,21 @@ public struct ContentItem : Swift.Codable, Swift.Equatable, @unchecked Swift.Sen
479
507
  public let articleUrl: Swift.String?
480
508
  public let commentCount: Swift.Int?
481
509
  public var fallbackUrl: Swift.String?
510
+ public var downloadUrl: Swift.String?
511
+ public init(id: Swift.String, playbackId: Swift.String? = nil, title: Swift.String, description: Swift.String? = nil, duration: Swift.Double, streamingUrl: Swift.String, thumbnailUrl: Swift.String, captionTracks: [ShortKitSDK.CaptionTrack] = [], customMetadata: [Swift.String : ShortKitSDK.JSONValue]? = nil, author: Swift.String? = nil, articleUrl: Swift.String? = nil, commentCount: Swift.Int? = nil, fallbackUrl: Swift.String? = nil, downloadUrl: Swift.String? = nil)
482
512
  public static func == (a: ShortKitSDK.ContentItem, b: ShortKitSDK.ContentItem) -> Swift.Bool
483
513
  public func encode(to encoder: any Swift.Encoder) throws
484
514
  public init(from decoder: any Swift.Decoder) throws
485
515
  }
516
+ extension ShortKitSDK.ContentItem {
517
+ public var isDownloadable: Swift.Bool {
518
+ get
519
+ }
520
+ }
486
521
  public enum FeedInput : Swift.Sendable {
487
522
  case video(playbackId: Swift.String, fallbackUrl: Swift.String? = nil)
488
523
  case imageCarousel(ShortKitSDK.ImageCarouselItem)
489
- case videoCarousel(ShortKitSDK.VideoCarouselItem)
524
+ case videoCarousel(ShortKitSDK.VideoCarouselInput)
490
525
  }
491
526
  public enum FeedItem : Swift.Sendable {
492
527
  case content(ShortKitSDK.ContentItem)
@@ -630,6 +665,19 @@ public struct VTTCue : Swift.Equatable, Swift.Sendable {
630
665
  public init(startTime: Swift.Double, endTime: Swift.Double, text: Swift.String)
631
666
  public static func == (a: ShortKitSDK.VTTCue, b: ShortKitSDK.VTTCue) -> Swift.Bool
632
667
  }
668
+ public struct VideoCarouselInput : Swift.Codable, Swift.Equatable, Swift.Sendable {
669
+ public let id: Swift.String
670
+ public let videos: [ShortKitSDK.VideoCarouselVideoInput]
671
+ public let title: Swift.String?
672
+ public let description: Swift.String?
673
+ public let author: Swift.String?
674
+ public let section: Swift.String?
675
+ public let articleUrl: Swift.String?
676
+ public init(id: Swift.String, videos: [ShortKitSDK.VideoCarouselVideoInput], title: Swift.String? = nil, description: Swift.String? = nil, author: Swift.String? = nil, section: Swift.String? = nil, articleUrl: Swift.String? = nil)
677
+ public static func == (a: ShortKitSDK.VideoCarouselInput, b: ShortKitSDK.VideoCarouselInput) -> Swift.Bool
678
+ public func encode(to encoder: any Swift.Encoder) throws
679
+ public init(from decoder: any Swift.Decoder) throws
680
+ }
633
681
  public struct VideoCarouselItem : Swift.Codable, Swift.Equatable, Swift.Sendable {
634
682
  public let id: Swift.String
635
683
  public let videos: [ShortKitSDK.ContentItem]
@@ -643,6 +691,14 @@ public struct VideoCarouselItem : Swift.Codable, Swift.Equatable, Swift.Sendable
643
691
  public func encode(to encoder: any Swift.Encoder) throws
644
692
  public init(from decoder: any Swift.Decoder) throws
645
693
  }
694
+ public struct VideoCarouselVideoInput : Swift.Codable, Swift.Equatable, Swift.Sendable {
695
+ public let playbackId: Swift.String
696
+ public let fallbackUrl: Swift.String?
697
+ public init(playbackId: Swift.String, fallbackUrl: Swift.String? = nil)
698
+ public static func == (a: ShortKitSDK.VideoCarouselVideoInput, b: ShortKitSDK.VideoCarouselVideoInput) -> Swift.Bool
699
+ public func encode(to encoder: any Swift.Encoder) throws
700
+ public init(from decoder: any Swift.Decoder) throws
701
+ }
646
702
  public protocol AdOverlay : AnyObject {
647
703
  func configure(with content: ShortKitSDK.NativeAdContent)
648
704
  func resetState()
@@ -654,6 +710,7 @@ public protocol CarouselOverlay : AnyObject {
654
710
  var wantsNativeImagePrefetch: Swift.Bool { get }
655
711
  func activatePlayback()
656
712
  func updateActiveImage(index: Swift.Int)
713
+ func resetToFirstImage()
657
714
  }
658
715
  extension ShortKitSDK.CarouselOverlay {
659
716
  public var cachedImage: ((Swift.String) -> UIKit.UIImage?)? {
@@ -665,6 +722,7 @@ extension ShortKitSDK.CarouselOverlay {
665
722
  }
666
723
  public func activatePlayback()
667
724
  public func updateActiveImage(index: Swift.Int)
725
+ public func resetToFirstImage()
668
726
  }
669
727
  final public class CellContent : Combine.ObservableObject {
670
728
  @Combine.Published<ShortKitSDK.ContentItem?> @_projectedValueProperty($item) final public var item: ShortKitSDK.ContentItem? {
@@ -884,6 +942,7 @@ final public class ShortKit {
884
942
  final public let player: ShortKitSDK.ShortKitPlayer
885
943
  final public let debugPanelEnabled: Swift.Bool
886
944
  weak final public var delegate: (any ShortKitSDK.ShortKitDelegate)?
945
+ weak final public var downloadDelegate: (any ShortKitSDK.ShortKitDownloadDelegate)?
887
946
  final public var loadingViewProvider: (() -> UIKit.UIView)?
888
947
  public init(apiKey: Swift.String, userId: Swift.String? = nil, adProvider: (any ShortKitSDK.ShortKitAdProvider)? = nil, clientAppName: Swift.String? = nil, clientAppVersion: Swift.String? = nil, customDimensions: [Swift.String : Swift.String]? = nil, loadingViewProvider: (() -> UIKit.UIView)? = nil, debugPanelEnabled: Swift.Bool = false)
889
948
  final public func preloadFeed(filter: ShortKitSDK.FeedFilter? = nil, limit: Swift.Int = 10) -> ShortKitSDK.FeedPreload
@@ -893,6 +952,8 @@ final public class ShortKit {
893
952
  final public func clearUserId()
894
953
  @_Concurrency.MainActor final public func setColdStartQueue(_ items: [ShortKitSDK.FeedInput])
895
954
  final public func clearColdStartCache()
955
+ final public func downloadVideo(_ item: ShortKitSDK.ContentItem, mode: ShortKitSDK.DownloadMode = .nonInterruptive) async throws -> Foundation.URL
956
+ final public func cancelDownload()
896
957
  @objc deinit
897
958
  }
898
959
  public enum PlayerClickAction : Swift.Sendable {
@@ -984,6 +1045,8 @@ extension ShortKitSDK.FeedSource : Swift.RawRepresentable {}
984
1045
  extension ShortKitSDK.SwipeCurve : Swift.Equatable {}
985
1046
  extension ShortKitSDK.SwipeCurve : Swift.Hashable {}
986
1047
  extension ShortKitSDK.SwipeCurve : Swift.RawRepresentable {}
1048
+ extension ShortKitSDK.DownloadMode : Swift.Equatable {}
1049
+ extension ShortKitSDK.DownloadMode : Swift.Hashable {}
987
1050
  extension ShortKitSDK.ShortKitFeedView : Swift.Sendable {}
988
1051
  extension ShortKitSDK.CaptionSource : Swift.Equatable {}
989
1052
  extension ShortKitSDK.CaptionSource : Swift.Hashable {}
@@ -337,6 +337,34 @@ extension ShortKitSDK.ShortKitDelegate {
337
337
  public func shortKit(_ shortKit: ShortKitSDK.ShortKit, didTapContent contentId: Swift.String, at index: Swift.Int)
338
338
  public func shortKit(_ shortKit: ShortKitSDK.ShortKit, didFetchContentItems items: [ShortKitSDK.ContentItem])
339
339
  }
340
+ public protocol ShortKitDownloadDelegate : AnyObject {
341
+ func shortKit(_ shortKit: ShortKitSDK.ShortKit, didStartDownload item: ShortKitSDK.ContentItem)
342
+ func shortKit(_ shortKit: ShortKitSDK.ShortKit, didUpdateDownloadProgress item: ShortKitSDK.ContentItem, progress: Swift.Double)
343
+ func shortKit(_ shortKit: ShortKitSDK.ShortKit, didCompleteDownload item: ShortKitSDK.ContentItem, fileURL: Foundation.URL)
344
+ func shortKit(_ shortKit: ShortKitSDK.ShortKit, didFailDownload item: ShortKitSDK.ContentItem, error: ShortKitSDK.ShortKitDownloadError)
345
+ }
346
+ extension ShortKitSDK.ShortKitDownloadDelegate {
347
+ public func shortKit(_ shortKit: ShortKitSDK.ShortKit, didStartDownload item: ShortKitSDK.ContentItem)
348
+ public func shortKit(_ shortKit: ShortKitSDK.ShortKit, didUpdateDownloadProgress item: ShortKitSDK.ContentItem, progress: Swift.Double)
349
+ public func shortKit(_ shortKit: ShortKitSDK.ShortKit, didCompleteDownload item: ShortKitSDK.ContentItem, fileURL: Foundation.URL)
350
+ public func shortKit(_ shortKit: ShortKitSDK.ShortKit, didFailDownload item: ShortKitSDK.ContentItem, error: ShortKitSDK.ShortKitDownloadError)
351
+ }
352
+ public enum DownloadMode {
353
+ case nonInterruptive
354
+ case interruptive
355
+ public static func == (a: ShortKitSDK.DownloadMode, b: ShortKitSDK.DownloadMode) -> Swift.Bool
356
+ public func hash(into hasher: inout Swift.Hasher)
357
+ public var hashValue: Swift.Int {
358
+ get
359
+ }
360
+ }
361
+ public enum ShortKitDownloadError : Swift.Error {
362
+ case downloadNotAvailable
363
+ case downloadInProgress
364
+ case networkError(any Swift.Error)
365
+ case httpError(statusCode: Swift.Int)
366
+ case cancelled
367
+ }
340
368
  @_hasMissingDesignatedInitializers final public class FeedPreload : @unchecked Swift.Sendable {
341
369
  @objc deinit
342
370
  }
@@ -479,14 +507,21 @@ public struct ContentItem : Swift.Codable, Swift.Equatable, @unchecked Swift.Sen
479
507
  public let articleUrl: Swift.String?
480
508
  public let commentCount: Swift.Int?
481
509
  public var fallbackUrl: Swift.String?
510
+ public var downloadUrl: Swift.String?
511
+ public init(id: Swift.String, playbackId: Swift.String? = nil, title: Swift.String, description: Swift.String? = nil, duration: Swift.Double, streamingUrl: Swift.String, thumbnailUrl: Swift.String, captionTracks: [ShortKitSDK.CaptionTrack] = [], customMetadata: [Swift.String : ShortKitSDK.JSONValue]? = nil, author: Swift.String? = nil, articleUrl: Swift.String? = nil, commentCount: Swift.Int? = nil, fallbackUrl: Swift.String? = nil, downloadUrl: Swift.String? = nil)
482
512
  public static func == (a: ShortKitSDK.ContentItem, b: ShortKitSDK.ContentItem) -> Swift.Bool
483
513
  public func encode(to encoder: any Swift.Encoder) throws
484
514
  public init(from decoder: any Swift.Decoder) throws
485
515
  }
516
+ extension ShortKitSDK.ContentItem {
517
+ public var isDownloadable: Swift.Bool {
518
+ get
519
+ }
520
+ }
486
521
  public enum FeedInput : Swift.Sendable {
487
522
  case video(playbackId: Swift.String, fallbackUrl: Swift.String? = nil)
488
523
  case imageCarousel(ShortKitSDK.ImageCarouselItem)
489
- case videoCarousel(ShortKitSDK.VideoCarouselItem)
524
+ case videoCarousel(ShortKitSDK.VideoCarouselInput)
490
525
  }
491
526
  public enum FeedItem : Swift.Sendable {
492
527
  case content(ShortKitSDK.ContentItem)
@@ -630,6 +665,19 @@ public struct VTTCue : Swift.Equatable, Swift.Sendable {
630
665
  public init(startTime: Swift.Double, endTime: Swift.Double, text: Swift.String)
631
666
  public static func == (a: ShortKitSDK.VTTCue, b: ShortKitSDK.VTTCue) -> Swift.Bool
632
667
  }
668
+ public struct VideoCarouselInput : Swift.Codable, Swift.Equatable, Swift.Sendable {
669
+ public let id: Swift.String
670
+ public let videos: [ShortKitSDK.VideoCarouselVideoInput]
671
+ public let title: Swift.String?
672
+ public let description: Swift.String?
673
+ public let author: Swift.String?
674
+ public let section: Swift.String?
675
+ public let articleUrl: Swift.String?
676
+ public init(id: Swift.String, videos: [ShortKitSDK.VideoCarouselVideoInput], title: Swift.String? = nil, description: Swift.String? = nil, author: Swift.String? = nil, section: Swift.String? = nil, articleUrl: Swift.String? = nil)
677
+ public static func == (a: ShortKitSDK.VideoCarouselInput, b: ShortKitSDK.VideoCarouselInput) -> Swift.Bool
678
+ public func encode(to encoder: any Swift.Encoder) throws
679
+ public init(from decoder: any Swift.Decoder) throws
680
+ }
633
681
  public struct VideoCarouselItem : Swift.Codable, Swift.Equatable, Swift.Sendable {
634
682
  public let id: Swift.String
635
683
  public let videos: [ShortKitSDK.ContentItem]
@@ -643,6 +691,14 @@ public struct VideoCarouselItem : Swift.Codable, Swift.Equatable, Swift.Sendable
643
691
  public func encode(to encoder: any Swift.Encoder) throws
644
692
  public init(from decoder: any Swift.Decoder) throws
645
693
  }
694
+ public struct VideoCarouselVideoInput : Swift.Codable, Swift.Equatable, Swift.Sendable {
695
+ public let playbackId: Swift.String
696
+ public let fallbackUrl: Swift.String?
697
+ public init(playbackId: Swift.String, fallbackUrl: Swift.String? = nil)
698
+ public static func == (a: ShortKitSDK.VideoCarouselVideoInput, b: ShortKitSDK.VideoCarouselVideoInput) -> Swift.Bool
699
+ public func encode(to encoder: any Swift.Encoder) throws
700
+ public init(from decoder: any Swift.Decoder) throws
701
+ }
646
702
  public protocol AdOverlay : AnyObject {
647
703
  func configure(with content: ShortKitSDK.NativeAdContent)
648
704
  func resetState()
@@ -654,6 +710,7 @@ public protocol CarouselOverlay : AnyObject {
654
710
  var wantsNativeImagePrefetch: Swift.Bool { get }
655
711
  func activatePlayback()
656
712
  func updateActiveImage(index: Swift.Int)
713
+ func resetToFirstImage()
657
714
  }
658
715
  extension ShortKitSDK.CarouselOverlay {
659
716
  public var cachedImage: ((Swift.String) -> UIKit.UIImage?)? {
@@ -665,6 +722,7 @@ extension ShortKitSDK.CarouselOverlay {
665
722
  }
666
723
  public func activatePlayback()
667
724
  public func updateActiveImage(index: Swift.Int)
725
+ public func resetToFirstImage()
668
726
  }
669
727
  final public class CellContent : Combine.ObservableObject {
670
728
  @Combine.Published<ShortKitSDK.ContentItem?> @_projectedValueProperty($item) final public var item: ShortKitSDK.ContentItem? {
@@ -884,6 +942,7 @@ final public class ShortKit {
884
942
  final public let player: ShortKitSDK.ShortKitPlayer
885
943
  final public let debugPanelEnabled: Swift.Bool
886
944
  weak final public var delegate: (any ShortKitSDK.ShortKitDelegate)?
945
+ weak final public var downloadDelegate: (any ShortKitSDK.ShortKitDownloadDelegate)?
887
946
  final public var loadingViewProvider: (() -> UIKit.UIView)?
888
947
  public init(apiKey: Swift.String, userId: Swift.String? = nil, adProvider: (any ShortKitSDK.ShortKitAdProvider)? = nil, clientAppName: Swift.String? = nil, clientAppVersion: Swift.String? = nil, customDimensions: [Swift.String : Swift.String]? = nil, loadingViewProvider: (() -> UIKit.UIView)? = nil, debugPanelEnabled: Swift.Bool = false)
889
948
  final public func preloadFeed(filter: ShortKitSDK.FeedFilter? = nil, limit: Swift.Int = 10) -> ShortKitSDK.FeedPreload
@@ -893,6 +952,8 @@ final public class ShortKit {
893
952
  final public func clearUserId()
894
953
  @_Concurrency.MainActor final public func setColdStartQueue(_ items: [ShortKitSDK.FeedInput])
895
954
  final public func clearColdStartCache()
955
+ final public func downloadVideo(_ item: ShortKitSDK.ContentItem, mode: ShortKitSDK.DownloadMode = .nonInterruptive) async throws -> Foundation.URL
956
+ final public func cancelDownload()
896
957
  @objc deinit
897
958
  }
898
959
  public enum PlayerClickAction : Swift.Sendable {
@@ -984,6 +1045,8 @@ extension ShortKitSDK.FeedSource : Swift.RawRepresentable {}
984
1045
  extension ShortKitSDK.SwipeCurve : Swift.Equatable {}
985
1046
  extension ShortKitSDK.SwipeCurve : Swift.Hashable {}
986
1047
  extension ShortKitSDK.SwipeCurve : Swift.RawRepresentable {}
1048
+ extension ShortKitSDK.DownloadMode : Swift.Equatable {}
1049
+ extension ShortKitSDK.DownloadMode : Swift.Hashable {}
987
1050
  extension ShortKitSDK.ShortKitFeedView : Swift.Sendable {}
988
1051
  extension ShortKitSDK.CaptionSource : Swift.Equatable {}
989
1052
  extension ShortKitSDK.CaptionSource : Swift.Hashable {}
@@ -10,39 +10,39 @@
10
10
  </data>
11
11
  <key>Info.plist</key>
12
12
  <data>
13
- N6BIyiZTG7NybeUMWtT8+6ppr/A=
13
+ aVOP/OHkEUzNyBoUHTT2iiGJbu4=
14
14
  </data>
15
15
  <key>Modules/ShortKitSDK.swiftmodule/arm64-apple-ios-simulator.abi.json</key>
16
16
  <data>
17
- XzFCNXT0oFqi22OvTJxQ8agFCQ0=
17
+ mxcDambiFIzUbFTPfCTaKwjGz/8=
18
18
  </data>
19
19
  <key>Modules/ShortKitSDK.swiftmodule/arm64-apple-ios-simulator.private.swiftinterface</key>
20
20
  <data>
21
- j1YuWonnCZA/HaM1cP3EOX85eY4=
21
+ wayE2tftrhjvaEAekKB20ZGO36g=
22
22
  </data>
23
23
  <key>Modules/ShortKitSDK.swiftmodule/arm64-apple-ios-simulator.swiftdoc</key>
24
24
  <data>
25
- lRwA+tdWhsfEF7MzPS63sMMFHVQ=
25
+ OXtQVstuyP3hqDsSczrvdpR/BZY=
26
26
  </data>
27
27
  <key>Modules/ShortKitSDK.swiftmodule/arm64-apple-ios-simulator.swiftinterface</key>
28
28
  <data>
29
- j1YuWonnCZA/HaM1cP3EOX85eY4=
29
+ wayE2tftrhjvaEAekKB20ZGO36g=
30
30
  </data>
31
31
  <key>Modules/ShortKitSDK.swiftmodule/x86_64-apple-ios-simulator.abi.json</key>
32
32
  <data>
33
- XzFCNXT0oFqi22OvTJxQ8agFCQ0=
33
+ mxcDambiFIzUbFTPfCTaKwjGz/8=
34
34
  </data>
35
35
  <key>Modules/ShortKitSDK.swiftmodule/x86_64-apple-ios-simulator.private.swiftinterface</key>
36
36
  <data>
37
- rs16WOdN1D8vIEvmH5Wtylpuqzs=
37
+ c5HZCcsGjJPhu5ppN3Wq4SsCx2A=
38
38
  </data>
39
39
  <key>Modules/ShortKitSDK.swiftmodule/x86_64-apple-ios-simulator.swiftdoc</key>
40
40
  <data>
41
- 9PRodo2h/+R4oGQMpMvB5dhaEVU=
41
+ IjquwfiAxSFG2n0IR/+e9HvnZCM=
42
42
  </data>
43
43
  <key>Modules/ShortKitSDK.swiftmodule/x86_64-apple-ios-simulator.swiftinterface</key>
44
44
  <data>
45
- rs16WOdN1D8vIEvmH5Wtylpuqzs=
45
+ c5HZCcsGjJPhu5ppN3Wq4SsCx2A=
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
- P/PhTd4eHyjgqdxeeC7V0MMZR0OL6Ob1vGdNyE+7SgU=
69
+ s3LSfH8aLgl3mic08rsi958gHLv6ImNC8MsZtFoy8u0=
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
- Ci2BwA0M1RNvymgreB44XItKdH3uLeswCR5suw6bTbA=
76
+ cYm595F0j0GSGb/GBTR7QHYSuFeUw9ZTPc8F87PKzvA=
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
- is5BMNiEvgHulXtIgjVIzD+UJnS2nkvI2LrkZvDOXIo=
83
+ 9FsW2XMD0E0AiZ7mHDBgLg/OeCcSwB2BmWG3PuPqPwM=
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
- Ci2BwA0M1RNvymgreB44XItKdH3uLeswCR5suw6bTbA=
90
+ cYm595F0j0GSGb/GBTR7QHYSuFeUw9ZTPc8F87PKzvA=
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
- P/PhTd4eHyjgqdxeeC7V0MMZR0OL6Ob1vGdNyE+7SgU=
97
+ s3LSfH8aLgl3mic08rsi958gHLv6ImNC8MsZtFoy8u0=
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
- n9cGqlcajvgi24HhUuEaWnzqdS25+zyyqGCkngfkpaw=
104
+ QRoqxRRNskUOSMbf+RlD6fMBj0mmhgmOres7jwvebiQ=
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
- PgFD4kP2WDXeolbcHxmC5r+pkgJLjtYxhZDRUWhAIcA=
111
+ R1p/WNYI3bnLOrWsIezOXSJRZEwJ/t8FuoDZCBZQhHg=
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
- n9cGqlcajvgi24HhUuEaWnzqdS25+zyyqGCkngfkpaw=
118
+ QRoqxRRNskUOSMbf+RlD6fMBj0mmhgmOres7jwvebiQ=
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.22",
3
+ "version": "0.2.24",
4
4
  "description": "ShortKit React Native SDK — short-form video feed",
5
5
  "react-native": "src/index",
6
6
  "source": "src/index",
@@ -28,4 +28,7 @@ export const ShortKitCommands = {
28
28
  NativeShortKitModule?.prefetchStoryboard(playbackId),
29
29
  getStoryboardData: (playbackId: string): Promise<string | null> =>
30
30
  NativeShortKitModule?.getStoryboardData(playbackId) ?? Promise.resolve(null),
31
+ downloadVideo: (itemId: string, mode: 'nonInterruptive' | 'interruptive' = 'nonInterruptive'): Promise<string> =>
32
+ NativeShortKitModule?.downloadVideo(itemId, mode) ?? Promise.reject(new Error('ShortKit not initialized')),
33
+ cancelDownload: () => NativeShortKitModule?.cancelDownload(),
31
34
  } as const;
@@ -1,6 +1,7 @@
1
1
  import { createContext } from 'react';
2
2
  import type {
3
3
  ContentItem,
4
+ DownloadState,
4
5
  FeedConfig,
5
6
  FeedFilter,
6
7
  FeedInput,
@@ -51,6 +52,11 @@ export interface ShortKitContextValue {
51
52
  // Storyboard / seek thumbnails
52
53
  prefetchStoryboard: (playbackId: string) => void;
53
54
  getStoryboardData: (playbackId: string) => Promise<StoryboardData | null>;
55
+
56
+ // Download
57
+ downloadState: DownloadState;
58
+ downloadVideo: (itemId: string, mode?: 'nonInterruptive' | 'interruptive') => Promise<string>;
59
+ cancelDownload: () => void;
54
60
  }
55
61
 
56
62
  export const ShortKitContext = createContext<ShortKitContextValue | null>(null);
@@ -6,6 +6,7 @@ import type { ShortKitContextValue } from './ShortKitContext';
6
6
  import type {
7
7
  ShortKitProviderProps,
8
8
  ContentItem,
9
+ DownloadState,
9
10
  FeedConfig,
10
11
  FeedFilter,
11
12
  FeedInput,
@@ -23,6 +24,7 @@ import {
23
24
  deserializePlayerTime,
24
25
  } from './serialization';
25
26
  import NativeShortKitModule from './specs/NativeShortKitModule';
27
+ import { ShortKitCommands } from './ShortKitCommands';
26
28
  import { registerLoadingComponent } from './ShortKitLoadingSurface';
27
29
 
28
30
  // ---------------------------------------------------------------------------
@@ -41,6 +43,7 @@ interface State {
41
43
  prefetchedAheadCount: number;
42
44
  isActive: boolean;
43
45
  feedScrollPhase: FeedScrollPhase | null;
46
+ downloadState: DownloadState;
44
47
  }
45
48
 
46
49
  const initialState: State = {
@@ -55,6 +58,7 @@ const initialState: State = {
55
58
  prefetchedAheadCount: 0,
56
59
  isActive: false,
57
60
  feedScrollPhase: null,
61
+ downloadState: { status: 'idle', progress: 0 },
58
62
  };
59
63
 
60
64
  type Action =
@@ -67,7 +71,11 @@ type Action =
67
71
  | { type: 'CAPTION_TRACK'; payload: CaptionTrack | null }
68
72
  | { type: 'CUE'; payload: { text: string; startTime: number; endTime: number } | null }
69
73
  | { type: 'PREFETCH_COUNT'; payload: number }
70
- | { type: 'FEED_SCROLL_PHASE'; payload: FeedScrollPhase };
74
+ | { type: 'FEED_SCROLL_PHASE'; payload: FeedScrollPhase }
75
+ | { type: 'DOWNLOAD_STARTED'; itemId: string }
76
+ | { type: 'DOWNLOAD_PROGRESS'; itemId: string; progress: number }
77
+ | { type: 'DOWNLOAD_COMPLETED'; itemId: string; fileUrl: string }
78
+ | { type: 'DOWNLOAD_FAILED'; itemId: string; error: string };
71
79
 
72
80
  function reducer(state: State, action: Action): State {
73
81
  switch (action.type) {
@@ -101,6 +109,14 @@ function reducer(state: State, action: Action): State {
101
109
  return { ...state, prefetchedAheadCount: action.payload };
102
110
  case 'FEED_SCROLL_PHASE':
103
111
  return { ...state, feedScrollPhase: action.payload };
112
+ case 'DOWNLOAD_STARTED':
113
+ return { ...state, downloadState: { status: 'downloading', itemId: action.itemId, progress: 0 } };
114
+ case 'DOWNLOAD_PROGRESS':
115
+ return { ...state, downloadState: { ...state.downloadState, progress: action.progress } };
116
+ case 'DOWNLOAD_COMPLETED':
117
+ return { ...state, downloadState: { status: 'completed', itemId: action.itemId, progress: 1, fileUrl: action.fileUrl } };
118
+ case 'DOWNLOAD_FAILED':
119
+ return { ...state, downloadState: { status: 'failed', itemId: action.itemId, progress: 0, error: action.error } };
104
120
  default:
105
121
  return state;
106
122
  }
@@ -327,6 +343,26 @@ export function ShortKitProvider({
327
343
  }),
328
344
  );
329
345
 
346
+ // Download started
347
+ const downloadStartedSub = NativeShortKitModule.onDownloadStarted((event) => {
348
+ dispatch({ type: 'DOWNLOAD_STARTED', itemId: event.itemId });
349
+ });
350
+
351
+ // Download progress
352
+ const downloadProgressSub = NativeShortKitModule.onDownloadProgress((event) => {
353
+ dispatch({ type: 'DOWNLOAD_PROGRESS', itemId: event.itemId, progress: event.progress });
354
+ });
355
+
356
+ // Download completed
357
+ const downloadCompletedSub = NativeShortKitModule.onDownloadCompleted((event) => {
358
+ dispatch({ type: 'DOWNLOAD_COMPLETED', itemId: event.itemId, fileUrl: event.fileUrl });
359
+ });
360
+
361
+ // Download failed
362
+ const downloadFailedSub = NativeShortKitModule.onDownloadFailed((event) => {
363
+ dispatch({ type: 'DOWNLOAD_FAILED', itemId: event.itemId, error: event.error });
364
+ });
365
+
330
366
  // Note: Feed-level callback events (onDidLoop, onFeedTransition,
331
367
  // onDismiss, etc.) are subscribed by the ShortKitFeed component
332
368
  // not here. The provider only manages state-driving events.
@@ -335,6 +371,10 @@ export function ShortKitProvider({
335
371
  for (const sub of subscriptions) {
336
372
  sub.remove();
337
373
  }
374
+ downloadStartedSub.remove();
375
+ downloadProgressSub.remove();
376
+ downloadCompletedSub.remove();
377
+ downloadFailedSub.remove();
338
378
  };
339
379
  }, []);
340
380
 
@@ -447,6 +487,7 @@ export function ShortKitProvider({
447
487
  prefetchedAheadCount: state.prefetchedAheadCount,
448
488
  isActive: state.isActive,
449
489
  feedScrollPhase: state.feedScrollPhase,
490
+ downloadState: state.downloadState,
450
491
 
451
492
  // Commands
452
493
  play,
@@ -467,6 +508,8 @@ export function ShortKitProvider({
467
508
  preloadFeed: preloadFeedCmd,
468
509
  prefetchStoryboard: prefetchStoryboardCmd,
469
510
  getStoryboardData: getStoryboardDataCmd,
511
+ downloadVideo: ShortKitCommands.downloadVideo,
512
+ cancelDownload: ShortKitCommands.cancelDownload,
470
513
  }),
471
514
  [
472
515
  state.playerState,
@@ -480,6 +523,7 @@ export function ShortKitProvider({
480
523
  state.prefetchedAheadCount,
481
524
  state.isActive,
482
525
  state.feedScrollPhase,
526
+ state.downloadState,
483
527
  play,
484
528
  pause,
485
529
  seek,
package/src/index.ts CHANGED
@@ -20,6 +20,8 @@ export type {
20
20
  CarouselImage,
21
21
  ImageCarouselItem,
22
22
  VideoCarouselItem,
23
+ VideoCarouselVideoInput,
24
+ VideoCarouselInput,
23
25
  FeedInput,
24
26
  JSONValue,
25
27
  CaptionTrack,
@@ -109,6 +109,25 @@ type FeedReadyEvent = Readonly<{
109
109
  feedId: string;
110
110
  }>;
111
111
 
112
+ type DownloadStartedEvent = Readonly<{
113
+ itemId: string;
114
+ }>;
115
+
116
+ type DownloadProgressEvent = Readonly<{
117
+ itemId: string;
118
+ progress: number;
119
+ }>;
120
+
121
+ type DownloadCompletedEvent = Readonly<{
122
+ itemId: string;
123
+ fileUrl: string;
124
+ }>;
125
+
126
+ type DownloadFailedEvent = Readonly<{
127
+ itemId: string;
128
+ error: string;
129
+ }>;
130
+
112
131
  // --- Overlay per-surface event payload types ---
113
132
 
114
133
  type OverlayActiveEvent = Readonly<{
@@ -216,6 +235,10 @@ export interface Spec extends TurboModule {
216
235
  prefetchStoryboard(playbackId: string): void;
217
236
  getStoryboardData(playbackId: string): Promise<string>;
218
237
 
238
+ // --- Download ---
239
+ downloadVideo(itemId: string, mode: string): Promise<string>;
240
+ cancelDownload(): void;
241
+
219
242
  // --- Event emitters ---
220
243
  readonly onPlayerStateChanged: EventEmitter<PlayerStateEvent>;
221
244
  readonly onCurrentItemChanged: EventEmitter<CurrentItemEvent>;
@@ -249,6 +272,12 @@ export interface Spec extends TurboModule {
249
272
  readonly onOverlayFullState: EventEmitter<OverlayFullStateEvent>;
250
273
  readonly onCarouselActiveImageChanged: EventEmitter<CarouselActiveImageEvent>;
251
274
  readonly onVideoCarouselActiveVideoChanged: EventEmitter<VideoCarouselActiveVideoEvent>;
275
+
276
+ // --- Download events ---
277
+ readonly onDownloadStarted: EventEmitter<DownloadStartedEvent>;
278
+ readonly onDownloadProgress: EventEmitter<DownloadProgressEvent>;
279
+ readonly onDownloadCompleted: EventEmitter<DownloadCompletedEvent>;
280
+ readonly onDownloadFailed: EventEmitter<DownloadFailedEvent>;
252
281
  }
253
282
 
254
283
  export default TurboModuleRegistry.getEnforcing<Spec>('ShortKitModule');
package/src/types.ts CHANGED
@@ -68,6 +68,21 @@ export interface ContentItem {
68
68
  articleUrl?: string;
69
69
  commentCount?: number;
70
70
  fallbackUrl?: string;
71
+ downloadUrl?: string;
72
+ }
73
+
74
+ export type DownloadStatus = 'idle' | 'downloading' | 'completed' | 'failed';
75
+
76
+ export interface DownloadState {
77
+ status: DownloadStatus;
78
+ /** ID of the content item being downloaded, if any. */
79
+ itemId?: string;
80
+ /** 0.0 to 1.0 progress fraction. */
81
+ progress: number;
82
+ /** Local file URL after successful download. */
83
+ fileUrl?: string;
84
+ /** Error message if download failed. */
85
+ error?: string;
71
86
  }
72
87
 
73
88
  // --- Custom Feed Types ---
@@ -98,10 +113,38 @@ export interface VideoCarouselItem {
98
113
  articleUrl?: string;
99
114
  }
100
115
 
116
+ /**
117
+ * Per-slide input for a VideoCarouselInput. Mirrors the `{ type: 'video' }`
118
+ * FeedInput variant — host apps pass a playback ID and the SDK constructs
119
+ * the streaming and thumbnail URLs internally.
120
+ */
121
+ export interface VideoCarouselVideoInput {
122
+ playbackId: string;
123
+ fallbackUrl?: string;
124
+ }
125
+
126
+ /**
127
+ * Compact input type for video carousels passed to
128
+ * `{ type: 'videoCarousel', item: VideoCarouselInput }`.
129
+ *
130
+ * The SDK hydrates each playback ID into a full ContentItem internally
131
+ * before rendering. Overlays continue to receive the fully-hydrated
132
+ * VideoCarouselItem shape via VideoCarouselOverlayProps.carouselItem.
133
+ */
134
+ export interface VideoCarouselInput {
135
+ id: string;
136
+ videos: VideoCarouselVideoInput[];
137
+ title?: string;
138
+ description?: string;
139
+ author?: string;
140
+ section?: string;
141
+ articleUrl?: string;
142
+ }
143
+
101
144
  export type FeedInput =
102
145
  | { type: 'video'; playbackId: string; fallbackUrl?: string }
103
146
  | { type: 'imageCarousel'; item: ImageCarouselItem }
104
- | { type: 'videoCarousel'; item: VideoCarouselItem };
147
+ | { type: 'videoCarousel'; item: VideoCarouselInput };
105
148
 
106
149
  export type JSONValue =
107
150
  | string