sparkling-navigation 2.1.0-rc.3 → 2.1.0-rc.31

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 (35) hide show
  1. package/android/build.gradle.kts +41 -21
  2. package/android/src/androidTest/java/com/tiktok/sparkling/method/router/ExampleInstrumentedTest.kt +1 -1
  3. package/android/src/main/java/com/tiktok/sparkling/method/router/close/AbsRouterCloseMethodIDL.kt +2 -12
  4. package/android/src/main/java/com/tiktok/sparkling/method/router/close/RouterCloseMethod.kt +16 -17
  5. package/android/src/main/java/com/tiktok/sparkling/method/router/open/AbsRouterOpenMethodIDL.kt +4 -11
  6. package/android/src/main/java/com/tiktok/sparkling/method/router/open/RouterOpenMethod.kt +58 -53
  7. package/android/src/main/java/com/tiktok/sparkling/method/router/utils/AbsRouteOpenHandler.kt +7 -2
  8. package/android/src/main/java/com/tiktok/sparkling/method/router/utils/IHostRouterDepend.kt +19 -4
  9. package/android/src/main/java/com/tiktok/sparkling/method/router/utils/RouterProvider.kt +1 -2
  10. package/android/src/test/java/com/tiktok/sparkling/method/router/RouterCoverageTest.kt +593 -0
  11. package/android/src/test/java/com/tiktok/sparkling/method/router/RouterMethodUnitTest.kt +189 -13
  12. package/dist/src/devServer.d.ts +10 -0
  13. package/dist/src/devServer.d.ts.map +1 -0
  14. package/dist/src/devServer.js +40 -0
  15. package/dist/src/devServer.js.map +1 -0
  16. package/dist/src/navigate/navigate.d.ts.map +1 -1
  17. package/dist/src/navigate/navigate.js +4 -12
  18. package/dist/src/navigate/navigate.js.map +1 -1
  19. package/dist/src/open/open.d.ts.map +1 -1
  20. package/dist/src/open/open.js +20 -1
  21. package/dist/src/open/open.js.map +1 -1
  22. package/dist/tsconfig.tsbuildinfo +1 -1
  23. package/ios/Sources/Core/Methods/Close/CloseMethod+impl.swift +2 -3
  24. package/ios/Sources/Core/Methods/Close/CloseMethod.swift +7 -8
  25. package/ios/Sources/Core/Methods/Open/OpenMethod+impl.swift +2 -3
  26. package/ios/Sources/Core/Methods/Open/OpenMethod.swift +4 -5
  27. package/ios/Sources/Core/Protocols/RouterService.swift +1 -1
  28. package/ios/Sparkling-Router.podspec +14 -11
  29. package/ios/SparklingMethodTests/SPKRouterTest.swift +26 -31
  30. package/module.config.json +2 -2
  31. package/package.json +2 -2
  32. package/src/__tests__/navigate/navigate.test.ts +70 -1
  33. package/src/devServer.ts +44 -0
  34. package/src/navigate/navigate.ts +4 -15
  35. package/src/open/open.ts +20 -1
@@ -21,7 +21,7 @@ android {
21
21
  isMinifyEnabled = false
22
22
  proguardFiles(
23
23
  getDefaultProguardFile("proguard-android-optimize.txt"),
24
- "proguard-rules.pro"
24
+ "proguard-rules.pro",
25
25
  )
26
26
  }
27
27
  }
@@ -32,6 +32,15 @@ android {
32
32
  kotlinOptions {
33
33
  jvmTarget = "11"
34
34
  }
35
+
36
+ testOptions {
37
+ unitTests.all {
38
+ it.extensions.configure(org.gradle.testing.jacoco.plugins.JacocoTaskExtension::class.java) {
39
+ isIncludeNoLocationClasses = true
40
+ excludes = listOf("jdk.internal.*")
41
+ }
42
+ }
43
+ }
35
44
  }
36
45
 
37
46
  dependencies {
@@ -39,12 +48,20 @@ dependencies {
39
48
  implementation(libs.androidx.core.ktx)
40
49
  implementation(libs.androidx.appcompat)
41
50
  testImplementation(libs.junit)
51
+ testImplementation("io.mockk:mockk:1.13.8")
52
+ testImplementation("org.robolectric:robolectric:4.11.1")
53
+ testImplementation("androidx.test:core:1.5.0")
42
54
  androidTestImplementation(libs.androidx.junit)
43
55
  androidTestImplementation(libs.androidx.espresso.core)
44
- val sparklingVersion = (findProperty("SPARKLING_ANDROID_SDK_VERSION") as? String)
45
- ?: System.getenv("SPARKLING_ANDROID_SDK_VERSION")
46
- ?: "2.0.0-rc.5"
47
- api("com.tiktok.sparkling:sparkling-method:$sparklingVersion")
56
+ val sparklingVersion =
57
+ (findProperty("SPARKLING_ANDROID_SDK_VERSION") as? String)
58
+ ?: System.getenv("SPARKLING_ANDROID_SDK_VERSION")
59
+ ?: "2.1.0-rc.31"
60
+ if (rootProject.findProject(":sparkling-method") != null) {
61
+ api(project(":sparkling-method"))
62
+ } else {
63
+ api("com.tiktok.sparkling:sparkling-method:$sparklingVersion")
64
+ }
48
65
  }
49
66
 
50
67
  tasks.register<JacocoReport>("jacocoTestReport") {
@@ -55,28 +72,31 @@ tasks.register<JacocoReport>("jacocoTestReport") {
55
72
  html.required.set(true)
56
73
  }
57
74
 
58
- val fileFilter = listOf(
59
- "**/R.class",
60
- "**/R$*.class",
61
- "**/BuildConfig.*",
62
- "**/Manifest*.*",
63
- "**/*Test*.*",
64
- "android/**/*.*"
65
- )
75
+ val fileFilter =
76
+ listOf(
77
+ "**/R.class",
78
+ "**/R$*.class",
79
+ "**/BuildConfig.*",
80
+ "**/Manifest*.*",
81
+ "**/*Test*.*",
82
+ "android/**/*.*",
83
+ )
66
84
 
67
85
  val mainSrc = "${project.projectDir}/src/main/java"
68
86
  sourceDirectories.setFrom(files(mainSrc))
69
87
 
70
- val debugJavaTree = layout.buildDirectory.dir("intermediates/javac/debug").map { dir ->
71
- dir.asFileTree.matching {
72
- exclude(fileFilter)
88
+ val debugJavaTree =
89
+ layout.buildDirectory.dir("intermediates/javac/debug").map { dir ->
90
+ dir.asFileTree.matching {
91
+ exclude(fileFilter)
92
+ }
73
93
  }
74
- }
75
- val debugKotlinTree = layout.buildDirectory.dir("tmp/kotlin-classes/debug").map { dir ->
76
- dir.asFileTree.matching {
77
- exclude(fileFilter)
94
+ val debugKotlinTree =
95
+ layout.buildDirectory.dir("tmp/kotlin-classes/debug").map { dir ->
96
+ dir.asFileTree.matching {
97
+ exclude(fileFilter)
98
+ }
78
99
  }
79
- }
80
100
  classDirectories.setFrom(debugJavaTree, debugKotlinTree)
81
101
 
82
102
  val unitTestCoverageExec = layout.buildDirectory.file("outputs/unit_test_code_coverage/debugUnitTest/testDebugUnitTest.exec")
@@ -24,4 +24,4 @@ class ExampleInstrumentedTest {
24
24
  val appContext = InstrumentationRegistry.getInstrumentation().targetContext
25
25
  assertEquals("com.tiktok.sparkling.methods.route.test", appContext.packageName)
26
26
  }
27
- }
27
+ }
@@ -11,29 +11,19 @@ import com.tiktok.sparkling.method.registry.core.base.AbsSparklingIDLMethod
11
11
  import com.tiktok.sparkling.method.registry.core.model.idl.IDLMethodBaseParamModel
12
12
  import com.tiktok.sparkling.method.registry.core.model.idl.IDLMethodBaseResultModel
13
13
 
14
-
15
14
  abstract class AbsRouterCloseMethodIDL : AbsSparklingIDLMethod<AbsRouterCloseMethodIDL.IDLMethodCloseParamModel, AbsRouterCloseMethodIDL.IDLMethodCloseResultModel>() {
16
-
17
15
  @IDLMethodName(name = "router.close", params = ["containerID", "animated"])
18
16
  final override val name: String = "router.close"
19
17
 
20
-
21
18
  @IDLMethodParamModel
22
19
  interface IDLMethodCloseParamModel : IDLMethodBaseParamModel {
23
-
24
20
  @get:IDLMethodParamField(required = false, isGetter = true, keyPath = "containerID")
25
21
  val containerID: String
26
22
 
27
-
28
23
  @get:IDLMethodParamField(required = false, isGetter = true, keyPath = "animated")
29
24
  val animated: Boolean?
30
-
31
-
32
25
  }
33
26
 
34
27
  @IDLMethodResultModel
35
- interface IDLMethodCloseResultModel: IDLMethodBaseResultModel {
36
- }
37
-
38
-
39
- }
28
+ interface IDLMethodCloseResultModel : IDLMethodBaseResultModel
29
+ }
@@ -16,19 +16,16 @@ import com.tiktok.sparkling.method.router.utils.RouterProvider
16
16
  * Handles closing pages/containers.
17
17
  */
18
18
  class RouterCloseMethod : AbsRouterCloseMethodIDL() {
19
-
20
19
  companion object {
21
20
  private const val TAG = "RouterCloseMethod"
22
21
  }
23
22
 
24
- private fun getRouterDependInstance(): IHostRouterDepend? {
25
- return RouterProvider.hostRouterDepend
26
- }
23
+ private fun getRouterDependInstance(): IHostRouterDepend? = RouterProvider.hostRouterDepend
27
24
 
28
25
  override fun handle(
29
26
  params: IDLMethodCloseParamModel,
30
27
  callback: CompletionBlock<IDLMethodCloseResultModel>,
31
- type: BridgePlatformType
28
+ type: BridgePlatformType,
32
29
  ) {
33
30
  // Check if router dependency is available
34
31
  val routerDepend = getRouterDependInstance()
@@ -41,22 +38,24 @@ class RouterCloseMethod : AbsRouterCloseMethodIDL() {
41
38
  val containerID = params.containerID
42
39
  val animated = params.animated ?: true // Default to animated close
43
40
 
44
- val success = try {
45
- routerDepend.closeView(getSDKContext(), type, containerID, animated)
46
- } catch (e: Exception) {
47
- Log.e(TAG, "Exception while closing container: ${e.message}")
48
- false
49
- }
41
+ val success =
42
+ try {
43
+ routerDepend.closeView(getSDKContext(), type, containerID, animated)
44
+ } catch (e: Exception) {
45
+ Log.e(TAG, "Exception while closing container: ${e.message}")
46
+ false
47
+ }
50
48
 
51
49
  if (success) {
52
50
  callback.onSuccess(IDLMethodCloseResultModel::class.java.createXModel())
53
51
  } else {
54
- val errorMsg = if (containerID.isNullOrBlank()) {
55
- "Failed to close current container"
56
- } else {
57
- "Failed to close container: $containerID"
58
- }
52
+ val errorMsg =
53
+ if (containerID.isNullOrBlank()) {
54
+ "Failed to close current container"
55
+ } else {
56
+ "Failed to close container: $containerID"
57
+ }
59
58
  callback.onFailure(IDLBridgeMethod.FAIL, errorMsg, null)
60
59
  }
61
60
  }
62
- }
61
+ }
@@ -2,7 +2,7 @@
2
2
  // Licensed under the Apache License Version 2.0 that can be found in the
3
3
  // LICENSE file in the root directory of this source tree.
4
4
 
5
- /** anycode-lint-ignore */
5
+ // anycode-lint-ignore
6
6
  package com.tiktok.sparkling.method.router.open
7
7
 
8
8
  import com.tiktok.sparkling.method.registry.core.annotation.IDLMethodName
@@ -14,21 +14,16 @@ import com.tiktok.sparkling.method.registry.core.model.idl.IDLMethodBaseModel
14
14
  import com.tiktok.sparkling.method.registry.core.model.idl.IDLMethodBaseParamModel
15
15
  import com.tiktok.sparkling.method.registry.core.model.idl.IDLMethodBaseResultModel
16
16
 
17
- /** anycode-lint-ignore */
18
-
19
17
  /**
20
18
  * GENERATED BY ANYCODE.
21
19
  * DO NOT MODIFY!!!
22
20
  */
23
21
  abstract class AbsRouterOpenMethodIDL : AbsSparklingIDLMethod<AbsRouterOpenMethodIDL.IDLMethodOpenParamModel, AbsRouterOpenMethodIDL.IDLMethodOpenResultModel>() {
24
-
25
22
  @IDLMethodName(name = "router.open", params = ["scheme", "replace", "replaceType", "useSysBrowser", "animated", "interceptor", "extra"])
26
23
  final override val name: String = "router.open"
27
24
 
28
-
29
25
  @IDLMethodParamModel
30
26
  interface IDLMethodOpenParamModel : IDLMethodBaseParamModel {
31
-
32
27
  @get:IDLMethodParamField(required = true, isGetter = true, keyPath = "scheme")
33
28
  val scheme: String
34
29
 
@@ -52,9 +47,7 @@ abstract class AbsRouterOpenMethodIDL : AbsSparklingIDLMethod<AbsRouterOpenMetho
52
47
  }
53
48
 
54
49
  @IDLMethodResultModel
55
- interface IDLMethodOpenResultModel: IDLMethodBaseResultModel {
56
- }
50
+ interface IDLMethodOpenResultModel : IDLMethodBaseResultModel
57
51
 
58
- interface IDLMethodOpenExtra : IDLMethodBaseModel {
59
- }
60
- }
52
+ interface IDLMethodOpenExtra : IDLMethodBaseModel
53
+ }
@@ -2,10 +2,8 @@
2
2
  // Licensed under the Apache License Version 2.0 that can be found in the
3
3
  // LICENSE file in the root directory of this source tree.
4
4
 
5
-
6
5
  package com.tiktok.sparkling.method.router.open
7
6
 
8
-
9
7
  import android.util.Log
10
8
  import com.tiktok.sparkling.method.registry.core.IDLBridgeMethod
11
9
  import com.tiktok.sparkling.method.registry.core.BridgePlatformType
@@ -14,25 +12,21 @@ import com.tiktok.sparkling.method.registry.core.utils.createXModel
14
12
  import com.tiktok.sparkling.method.router.utils.IHostRouterDepend
15
13
  import com.tiktok.sparkling.method.router.utils.RouterProvider
16
14
 
17
-
18
15
  /**
19
16
  * Router open method implementation.
20
17
  * Handles opening new pages/routes with various configuration options.
21
18
  */
22
19
  class RouterOpenMethod : AbsRouterOpenMethodIDL() {
23
-
24
20
  companion object {
25
21
  private const val TAG = "RouterOpenMethod"
26
22
  }
27
23
 
28
- private fun getRouterDependInstance(): IHostRouterDepend? {
29
- return RouterProvider.hostRouterDepend
30
- }
24
+ private fun getRouterDependInstance(): IHostRouterDepend? = RouterProvider.hostRouterDepend
31
25
 
32
26
  override fun handle(
33
27
  params: IDLMethodOpenParamModel,
34
28
  callback: CompletionBlock<IDLMethodOpenResultModel>,
35
- type: BridgePlatformType
29
+ type: BridgePlatformType,
36
30
  ) {
37
31
  // Validate scheme is not null or empty
38
32
  val scheme = params.scheme
@@ -43,21 +37,22 @@ class RouterOpenMethod : AbsRouterOpenMethodIDL() {
43
37
  }
44
38
 
45
39
  // Validate replaceType if provided
46
- val replaceType: ReplaceType? = if (!params.replaceType.isNullOrBlank()) {
47
- try {
48
- ReplaceType.valueOf(params.replaceType!!)
49
- } catch (e: IllegalArgumentException) {
50
- Log.w(TAG, "Invalid replaceType: ${params.replaceType}")
51
- callback.onFailure(
52
- IDLBridgeMethod.INVALID_PARAM,
53
- "Invalid replaceType: ${params.replaceType}. Valid values are: ${ReplaceType.values().joinToString()}",
54
- null
55
- )
56
- return
40
+ val replaceType: ReplaceType? =
41
+ if (!params.replaceType.isNullOrBlank()) {
42
+ try {
43
+ ReplaceType.valueOf(params.replaceType!!)
44
+ } catch (e: IllegalArgumentException) {
45
+ Log.w(TAG, "Invalid replaceType: ${params.replaceType}")
46
+ callback.onFailure(
47
+ IDLBridgeMethod.INVALID_PARAM,
48
+ "Invalid replaceType: ${params.replaceType}. Valid values are: ${ReplaceType.values().joinToString()}",
49
+ null,
50
+ )
51
+ return
52
+ }
53
+ } else {
54
+ ReplaceType.onlyCloseAfterOpenSucceed
57
55
  }
58
- } else {
59
- ReplaceType.onlyCloseAfterOpenSucceed
60
- }
61
56
 
62
57
  // Get and validate context
63
58
  val context = getSDKContext()?.context
@@ -79,19 +74,21 @@ class RouterOpenMethod : AbsRouterOpenMethodIDL() {
79
74
  val useSysBrowser = params.useSysBrowser ?: false
80
75
  val extra = params.extra
81
76
 
82
- val extraInfo = mutableMapOf<String, Any>(
83
- "useSysBrowser" to useSysBrowser,
84
- "extra" to (extra ?: emptyMap<Any, Any>())
85
- )
77
+ val extraInfo =
78
+ mutableMapOf<String, Any>(
79
+ "useSysBrowser" to useSysBrowser,
80
+ "extra" to (extra ?: emptyMap<Any, Any>()),
81
+ )
86
82
 
87
83
  // Handle non-replace open
88
84
  if (!replace) {
89
- val success = try {
90
- routerDepend.openScheme(getSDKContext(), scheme, extraInfo, type, context = context)
91
- } catch (e: Exception) {
92
- Log.e(TAG, "Exception while opening scheme: ${e.message}")
93
- false
94
- }
85
+ val success =
86
+ try {
87
+ routerDepend.openScheme(getSDKContext(), scheme, extraInfo, type, context = context)
88
+ } catch (e: Exception) {
89
+ Log.e(TAG, "Exception while opening scheme: ${e.message}")
90
+ false
91
+ }
95
92
 
96
93
  if (success) {
97
94
  callback.onSuccess(IDLMethodOpenResultModel::class.java.createXModel())
@@ -102,30 +99,36 @@ class RouterOpenMethod : AbsRouterOpenMethodIDL() {
102
99
  }
103
100
 
104
101
  // Handle replace open with different replace types
105
- val success: Boolean = try {
106
- when (replaceType) {
107
- ReplaceType.alwaysCloseBeforeOpen -> {
108
- routerDepend.closeView(getSDKContext(), type)
109
- routerDepend.openScheme(getSDKContext(), scheme, extraInfo, type, context = context)
110
- }
111
- ReplaceType.alwaysCloseAfterOpen -> {
112
- val opened = routerDepend.openScheme(getSDKContext(), scheme, extraInfo, type, context = context)
113
- routerDepend.closeView(getSDKContext(), type)
114
- opened
115
- }
116
- ReplaceType.onlyCloseAfterOpenSucceed -> {
117
- val opened = routerDepend.openScheme(getSDKContext(), scheme, extraInfo, type, context = context)
118
- if (opened) {
102
+ val success: Boolean =
103
+ try {
104
+ when (replaceType) {
105
+ ReplaceType.alwaysCloseBeforeOpen -> {
119
106
  routerDepend.closeView(getSDKContext(), type)
107
+ routerDepend.openScheme(getSDKContext(), scheme, extraInfo, type, context = context)
108
+ }
109
+
110
+ ReplaceType.alwaysCloseAfterOpen -> {
111
+ val opened = routerDepend.openScheme(getSDKContext(), scheme, extraInfo, type, context = context)
112
+ routerDepend.closeView(getSDKContext(), type)
113
+ opened
114
+ }
115
+
116
+ ReplaceType.onlyCloseAfterOpenSucceed -> {
117
+ val opened = routerDepend.openScheme(getSDKContext(), scheme, extraInfo, type, context = context)
118
+ if (opened) {
119
+ routerDepend.closeView(getSDKContext(), type)
120
+ }
121
+ opened
122
+ }
123
+
124
+ null -> {
125
+ false
120
126
  }
121
- opened
122
127
  }
123
- null -> false
128
+ } catch (e: Exception) {
129
+ Log.e(TAG, "Exception during replace open: ${e.message}")
130
+ false
124
131
  }
125
- } catch (e: Exception) {
126
- Log.e(TAG, "Exception during replace open: ${e.message}")
127
- false
128
- }
129
132
 
130
133
  if (success) {
131
134
  callback.onSuccess(IDLMethodOpenResultModel::class.java.createXModel())
@@ -134,8 +137,10 @@ class RouterOpenMethod : AbsRouterOpenMethodIDL() {
134
137
  }
135
138
  }
136
139
  }
140
+
141
+ @Suppress("ktlint:standard:enum-entry-name-case")
137
142
  enum class ReplaceType {
138
143
  alwaysCloseAfterOpen,
139
144
  alwaysCloseBeforeOpen,
140
- onlyCloseAfterOpenSucceed
145
+ onlyCloseAfterOpenSucceed,
141
146
  }
@@ -23,6 +23,11 @@ abstract class AbsRouteOpenHandler {
23
23
  this.exceptionHandler = handler
24
24
  }
25
25
 
26
- abstract fun openScheme(scheme: String, extraInfo: Map<String, Any>, context: Context?): Boolean
26
+ abstract fun openScheme(
27
+ scheme: String,
28
+ extraInfo: Map<String, Any>,
29
+ context: Context?,
30
+ ): Boolean
31
+
27
32
  abstract fun getSupportPlatformTypeList(): List<BridgePlatformType>
28
- }
33
+ }
@@ -9,7 +9,13 @@ import com.tiktok.sparkling.method.registry.core.BridgePlatformType
9
9
  import com.tiktok.sparkling.method.registry.core.model.context.ContextProviderFactory
10
10
 
11
11
  interface IHostRouterDepend {
12
- fun openScheme(bridgeContext: IBridgeContext?, scheme: String, extraParams: Map<String, Any>, platformType: BridgePlatformType, context: Context?): Boolean {
12
+ fun openScheme(
13
+ bridgeContext: IBridgeContext?,
14
+ scheme: String,
15
+ extraParams: Map<String, Any>,
16
+ platformType: BridgePlatformType,
17
+ context: Context?,
18
+ ): Boolean {
13
19
  var handled = false
14
20
  val contextProviderFactory = ContextProviderFactory()
15
21
  val headHandlerNode = assembleHandlerChain(contextProviderFactory) ?: return false
@@ -30,11 +36,20 @@ interface IHostRouterDepend {
30
36
  }
31
37
  }
32
38
 
33
- return handled
39
+ return handled
34
40
  }
35
- fun closeView(bridgeContext: IBridgeContext?, type: BridgePlatformType, containerID: String? = null, animated: Boolean? = false): Boolean
41
+
42
+ fun closeView(
43
+ bridgeContext: IBridgeContext?,
44
+ type: BridgePlatformType,
45
+ containerID: String? = null,
46
+ animated: Boolean? = false,
47
+ ): Boolean
48
+
36
49
  fun provideRouteOpenHandlerList(contextProviderFactory: ContextProviderFactory?): List<AbsRouteOpenHandler> = listOf()
50
+
37
51
  fun provideRouteOpenExceptionHandler(contextProviderFactory: ContextProviderFactory?): AbsRouteOpenHandler? = null
52
+
38
53
  private fun assembleHandlerChain(contextProviderFactory: ContextProviderFactory?): AbsRouteOpenHandler? {
39
54
  val chainHandlerList = provideRouteOpenHandlerList(contextProviderFactory)
40
55
  val exceptionHandlerNode = provideRouteOpenExceptionHandler(contextProviderFactory)
@@ -51,4 +66,4 @@ interface IHostRouterDepend {
51
66
  }
52
67
  return headChainNode
53
68
  }
54
- }
69
+ }
@@ -3,7 +3,6 @@
3
3
  // LICENSE file in the root directory of this source tree.
4
4
  package com.tiktok.sparkling.method.router.utils
5
5
 
6
-
7
6
  object RouterProvider {
8
7
  var hostRouterDepend: IHostRouterDepend? = null
9
- }
8
+ }