From 26bcda9f28b66bd369efdcfd9d664b904204c830 Mon Sep 17 00:00:00 2001 From: hfhbd <22521688+hfhbd@users.noreply.github.com> Date: Sun, 27 Oct 2024 12:27:45 +0100 Subject: [PATCH 1/2] Draft --- api/routing-compose.api | 2 +- api/routing-compose.klib.api | 26 ++++++++++++++++--- .../softwork/routingcompose/DelegateRouter.kt | 2 +- .../app/softwork/routingcompose/Router.kt | 3 ++- .../app/softwork/routingcompose/MockRouter.kt | 4 --- .../softwork/routingcompose/BrowserRouter.kt | 10 +------ .../app/softwork/routingcompose/HashRouter.kt | 10 +------ .../app/softwork/routingcompose/RouterTest.kt | 2 +- .../softwork/routingcompose/DesktopRouter.kt | 14 ++++++++-- .../routingcompose/RoutingNodeTest.kt | 4 +-- 10 files changed, 44 insertions(+), 33 deletions(-) diff --git a/api/routing-compose.api b/api/routing-compose.api index 2d7b76c..2390bdb 100644 --- a/api/routing-compose.api +++ b/api/routing-compose.api @@ -77,13 +77,13 @@ public final class app/softwork/routingcompose/Router$DefaultImpls { } public final class app/softwork/routingcompose/RouterKt { + public static final fun invoke (Lapp/softwork/routingcompose/Router;Ljava/lang/String;Lkotlin/jvm/functions/Function3;Landroidx/compose/runtime/Composer;I)V public static final fun navigate (Lapp/softwork/routingcompose/Router;Ljava/lang/String;Lapp/softwork/routingcompose/Parameters;Z)V public static final fun navigate (Lapp/softwork/routingcompose/Router;Ljava/lang/String;Ljava/util/Map;Z)V public static synthetic fun navigate$default (Lapp/softwork/routingcompose/Router;Ljava/lang/String;Lapp/softwork/routingcompose/Parameters;ZILjava/lang/Object;)V public static synthetic fun navigate$default (Lapp/softwork/routingcompose/Router;Ljava/lang/String;Ljava/util/Map;ZILjava/lang/Object;)V public static final fun navigateParameterList (Lapp/softwork/routingcompose/Router;Ljava/lang/String;Ljava/util/Map;Z)V public static synthetic fun navigateParameterList$default (Lapp/softwork/routingcompose/Router;Ljava/lang/String;Ljava/util/Map;ZILjava/lang/Object;)V - public static final fun route (Lapp/softwork/routingcompose/Router;Ljava/lang/String;Lkotlin/jvm/functions/Function3;Landroidx/compose/runtime/Composer;I)V } public abstract interface annotation class app/softwork/routingcompose/Routing : java/lang/annotation/Annotation { diff --git a/api/routing-compose.klib.api b/api/routing-compose.klib.api index 3f03bdd..687376a 100644 --- a/api/routing-compose.klib.api +++ b/api/routing-compose.klib.api @@ -87,6 +87,28 @@ final class app.softwork.routingcompose/RouteBuilder { // app.softwork.routingco } } +final object app.softwork.routingcompose/BrowserRouter : app.softwork.routingcompose/Router { // app.softwork.routingcompose/BrowserRouter|null[0] + final val currentPath // app.softwork.routingcompose/BrowserRouter.currentPath|{}currentPath[0] + final fun (): app.softwork.routingcompose/Path // app.softwork.routingcompose/BrowserRouter.currentPath.|(){}[0] + + final fun equals(kotlin/Any?): kotlin/Boolean // app.softwork.routingcompose/BrowserRouter.equals|equals(kotlin.Any?){}[0] + final fun getPath(kotlin/String, androidx.compose.runtime/Composer?, kotlin/Int): androidx.compose.runtime/State // app.softwork.routingcompose/BrowserRouter.getPath|getPath(kotlin.String;androidx.compose.runtime.Composer?;kotlin.Int){}[0] + final fun hashCode(): kotlin/Int // app.softwork.routingcompose/BrowserRouter.hashCode|hashCode(){}[0] + final fun navigate(kotlin/String, kotlin/Boolean) // app.softwork.routingcompose/BrowserRouter.navigate|navigate(kotlin.String;kotlin.Boolean){}[0] + final fun toString(): kotlin/String // app.softwork.routingcompose/BrowserRouter.toString|toString(){}[0] +} + +final object app.softwork.routingcompose/HashRouter : app.softwork.routingcompose/Router { // app.softwork.routingcompose/HashRouter|null[0] + final val currentPath // app.softwork.routingcompose/HashRouter.currentPath|{}currentPath[0] + final fun (): app.softwork.routingcompose/Path // app.softwork.routingcompose/HashRouter.currentPath.|(){}[0] + + final fun equals(kotlin/Any?): kotlin/Boolean // app.softwork.routingcompose/HashRouter.equals|equals(kotlin.Any?){}[0] + final fun getPath(kotlin/String, androidx.compose.runtime/Composer?, kotlin/Int): androidx.compose.runtime/State // app.softwork.routingcompose/HashRouter.getPath|getPath(kotlin.String;androidx.compose.runtime.Composer?;kotlin.Int){}[0] + final fun hashCode(): kotlin/Int // app.softwork.routingcompose/HashRouter.hashCode|hashCode(){}[0] + final fun navigate(kotlin/String, kotlin/Boolean) // app.softwork.routingcompose/HashRouter.navigate|navigate(kotlin.String;kotlin.Boolean){}[0] + final fun toString(): kotlin/String // app.softwork.routingcompose/HashRouter.toString|toString(){}[0] +} + final val app.softwork.routingcompose/app_softwork_routingcompose_BrowserRouter$stableprop // app.softwork.routingcompose/app_softwork_routingcompose_BrowserRouter$stableprop|#static{}app_softwork_routingcompose_BrowserRouter$stableprop[0] final val app.softwork.routingcompose/app_softwork_routingcompose_DelegateRouter$stableprop // app.softwork.routingcompose/app_softwork_routingcompose_DelegateRouter$stableprop|#static{}app_softwork_routingcompose_DelegateRouter$stableprop[0] final val app.softwork.routingcompose/app_softwork_routingcompose_HashRouter$stableprop // app.softwork.routingcompose/app_softwork_routingcompose_HashRouter$stableprop|#static{}app_softwork_routingcompose_HashRouter$stableprop[0] @@ -95,12 +117,10 @@ final val app.softwork.routingcompose/app_softwork_routingcompose_Path$stablepro final val app.softwork.routingcompose/app_softwork_routingcompose_RouteBuilder$stableprop // app.softwork.routingcompose/app_softwork_routingcompose_RouteBuilder$stableprop|#static{}app_softwork_routingcompose_RouteBuilder$stableprop[0] final val app.softwork.routingcompose/app_softwork_routingcompose_RouteBuilder_NoMatch$stableprop // app.softwork.routingcompose/app_softwork_routingcompose_RouteBuilder_NoMatch$stableprop|#static{}app_softwork_routingcompose_RouteBuilder_NoMatch$stableprop[0] +final fun (app.softwork.routingcompose/Router).app.softwork.routingcompose/invoke(kotlin/String, kotlin/Function3, androidx.compose.runtime/Composer?, kotlin/Int) // app.softwork.routingcompose/invoke|invoke@app.softwork.routingcompose.Router(kotlin.String;kotlin.Function3;androidx.compose.runtime.Composer?;kotlin.Int){}[0] final fun (app.softwork.routingcompose/Router).app.softwork.routingcompose/navigate(kotlin/String, app.softwork.routingcompose/Parameters, kotlin/Boolean = ...) // app.softwork.routingcompose/navigate|navigate@app.softwork.routingcompose.Router(kotlin.String;app.softwork.routingcompose.Parameters;kotlin.Boolean){}[0] final fun (app.softwork.routingcompose/Router).app.softwork.routingcompose/navigate(kotlin/String, kotlin.collections/Map>, kotlin/Boolean = ...) // app.softwork.routingcompose/navigate|navigate@app.softwork.routingcompose.Router(kotlin.String;kotlin.collections.Map>;kotlin.Boolean){}[0] final fun (app.softwork.routingcompose/Router).app.softwork.routingcompose/navigate(kotlin/String, kotlin.collections/Map, kotlin/Boolean = ...) // app.softwork.routingcompose/navigate|navigate@app.softwork.routingcompose.Router(kotlin.String;kotlin.collections.Map;kotlin.Boolean){}[0] -final fun (app.softwork.routingcompose/Router).app.softwork.routingcompose/route(kotlin/String, kotlin/Function3, androidx.compose.runtime/Composer?, kotlin/Int) // app.softwork.routingcompose/route|route@app.softwork.routingcompose.Router(kotlin.String;kotlin.Function3;androidx.compose.runtime.Composer?;kotlin.Int){}[0] -final fun app.softwork.routingcompose/BrowserRouter(kotlin/String, kotlin/Function3, androidx.compose.runtime/Composer?, kotlin/Int) // app.softwork.routingcompose/BrowserRouter|BrowserRouter(kotlin.String;kotlin.Function3;androidx.compose.runtime.Composer?;kotlin.Int){}[0] -final fun app.softwork.routingcompose/HashRouter(kotlin/String, kotlin/Function3, androidx.compose.runtime/Composer?, kotlin/Int) // app.softwork.routingcompose/HashRouter|HashRouter(kotlin.String;kotlin.Function3;androidx.compose.runtime.Composer?;kotlin.Int){}[0] final fun app.softwork.routingcompose/app_softwork_routingcompose_BrowserRouter$stableprop_getter(): kotlin/Int // app.softwork.routingcompose/app_softwork_routingcompose_BrowserRouter$stableprop_getter|app_softwork_routingcompose_BrowserRouter$stableprop_getter(){}[0] final fun app.softwork.routingcompose/app_softwork_routingcompose_DelegateRouter$stableprop_getter(): kotlin/Int // app.softwork.routingcompose/app_softwork_routingcompose_DelegateRouter$stableprop_getter|app_softwork_routingcompose_DelegateRouter$stableprop_getter(){}[0] final fun app.softwork.routingcompose/app_softwork_routingcompose_HashRouter$stableprop_getter(): kotlin/Int // app.softwork.routingcompose/app_softwork_routingcompose_HashRouter$stableprop_getter|app_softwork_routingcompose_HashRouter$stableprop_getter(){}[0] diff --git a/src/commonMain/kotlin/app/softwork/routingcompose/DelegateRouter.kt b/src/commonMain/kotlin/app/softwork/routingcompose/DelegateRouter.kt index b85a18c..92b0be5 100644 --- a/src/commonMain/kotlin/app/softwork/routingcompose/DelegateRouter.kt +++ b/src/commonMain/kotlin/app/softwork/routingcompose/DelegateRouter.kt @@ -1,6 +1,6 @@ package app.softwork.routingcompose -internal class DelegateRouter(val basePath: String, val router: Router) : Router by router { +internal data class DelegateRouter(val basePath: String, val router: Router) : Router by router { override fun navigate(to: String, hide: Boolean) { when { to.startsWith("/") -> { diff --git a/src/commonMain/kotlin/app/softwork/routingcompose/Router.kt b/src/commonMain/kotlin/app/softwork/routingcompose/Router.kt index 09c8a41..b16f542 100644 --- a/src/commonMain/kotlin/app/softwork/routingcompose/Router.kt +++ b/src/commonMain/kotlin/app/softwork/routingcompose/Router.kt @@ -33,8 +33,9 @@ public interface Router { internal val RouterCompositionLocal: ProvidableCompositionLocal = compositionLocalOf { error("Router not defined, cannot provide through RouterCompositionLocal.") } +@Routing @Composable -public fun Router.route( +public operator fun Router.invoke( initRoute: String, routing: @Composable RouteBuilder.() -> Unit ) { diff --git a/src/commonTest/kotlin/app/softwork/routingcompose/MockRouter.kt b/src/commonTest/kotlin/app/softwork/routingcompose/MockRouter.kt index 24e07e1..e574bb1 100644 --- a/src/commonTest/kotlin/app/softwork/routingcompose/MockRouter.kt +++ b/src/commonTest/kotlin/app/softwork/routingcompose/MockRouter.kt @@ -16,7 +16,3 @@ class MockRouter : Router { currentState.value = to } } - -@Composable -operator fun MockRouter.invoke(initPath: String, routeBuilder: @Composable RouteBuilder.() -> Unit) = - route(initPath, routeBuilder) diff --git a/src/jsSharedMain/kotlin/app/softwork/routingcompose/BrowserRouter.kt b/src/jsSharedMain/kotlin/app/softwork/routingcompose/BrowserRouter.kt index 46349b0..2b5542b 100644 --- a/src/jsSharedMain/kotlin/app/softwork/routingcompose/BrowserRouter.kt +++ b/src/jsSharedMain/kotlin/app/softwork/routingcompose/BrowserRouter.kt @@ -19,15 +19,7 @@ import androidx.compose.runtime.* * For development environments, see the RoutingCompose Readme * for full instructions. */ -@Composable -public fun BrowserRouter( - initPath: String, - routeBuilder: @Composable RouteBuilder.() -> Unit -) { - BrowserRouter().route(initPath, routeBuilder) -} - -internal class BrowserRouter : Router { +public data object BrowserRouter : Router { override val currentPath: Path get() = Path.from(currentLocation.value) diff --git a/src/jsSharedMain/kotlin/app/softwork/routingcompose/HashRouter.kt b/src/jsSharedMain/kotlin/app/softwork/routingcompose/HashRouter.kt index 6893955..9edd905 100644 --- a/src/jsSharedMain/kotlin/app/softwork/routingcompose/HashRouter.kt +++ b/src/jsSharedMain/kotlin/app/softwork/routingcompose/HashRouter.kt @@ -8,15 +8,7 @@ import androidx.compose.runtime.* * Every request will always request `GET /`, so your server needs only to listen and serve this endpoint, * or using a SaaS `/index.html`. */ -@Composable -public fun HashRouter( - initPath: String, - routeBuilder: @Composable RouteBuilder.() -> Unit -) { - HashRouter().route(initPath, routeBuilder) -} - -internal class HashRouter : Router { +public data object HashRouter : Router { override val currentPath: Path get() = Path.from(currentHash.value) diff --git a/src/jsTest/kotlin/app/softwork/routingcompose/RouterTest.kt b/src/jsTest/kotlin/app/softwork/routingcompose/RouterTest.kt index 72b2b5e..9c3eb39 100644 --- a/src/jsTest/kotlin/app/softwork/routingcompose/RouterTest.kt +++ b/src/jsTest/kotlin/app/softwork/routingcompose/RouterTest.kt @@ -339,7 +339,7 @@ internal class RouterTest { fun relativeRoutingTest() = runTest { var router: Router = MockRouter() composition { - router.route("/") { + router("/") { route("foo") { int { uuid { diff --git a/src/jvmMain/kotlin/app/softwork/routingcompose/DesktopRouter.kt b/src/jvmMain/kotlin/app/softwork/routingcompose/DesktopRouter.kt index 7a0134d..849a4ad 100644 --- a/src/jvmMain/kotlin/app/softwork/routingcompose/DesktopRouter.kt +++ b/src/jvmMain/kotlin/app/softwork/routingcompose/DesktopRouter.kt @@ -7,10 +7,9 @@ import androidx.compose.runtime.* * * To get the current [Router] inside the [navBuilder] `@Composable` tree call [Router.current]. */ -@Routing @Composable public fun DesktopRouter(initRoute: String, navBuilder: @Composable RouteBuilder.() -> Unit) { - DesktopRouter().route(initRoute, navBuilder) + DesktopRouter().invoke(initRoute, navBuilder) } internal class DesktopRouter : Router { @@ -37,6 +36,17 @@ internal class DesktopRouter : Router { internal fun navigateBack() { stack.removeAt(stack.lastIndex) } + + override fun equals(other: Any?): Boolean { + if (other !is DesktopRouter) { + return false + } + return stack == other.stack + } + + override fun hashCode(): Int { + return stack.hashCode() + } } public fun Router.navigateBack() { diff --git a/src/jvmTest/kotlin/app/softwork/routingcompose/RoutingNodeTest.kt b/src/jvmTest/kotlin/app/softwork/routingcompose/RoutingNodeTest.kt index 1d70a4a..f1e0391 100644 --- a/src/jvmTest/kotlin/app/softwork/routingcompose/RoutingNodeTest.kt +++ b/src/jvmTest/kotlin/app/softwork/routingcompose/RoutingNodeTest.kt @@ -15,7 +15,7 @@ class RoutingNodeTest { val router: Router = DesktopRouter() var result: String? = null rule.setContent { - router.route("/") { + router("/") { int { i -> result = "$i" } @@ -41,7 +41,7 @@ class RoutingNodeTest { val router: Router = DesktopRouter() var result: String? = null rule.setContent { - router.route("/") { + router("/") { int { user -> result = "$user" int { i -> From 85bafa8158e6fac2297e43bc9a47203f0415098b Mon Sep 17 00:00:00 2001 From: hfhbd <22521688+hfhbd@users.noreply.github.com> Date: Sun, 27 Oct 2024 16:02:40 +0100 Subject: [PATCH 2/2] Add Stable and Immutable annotations --- api/routing-compose.api | 3 +-- api/routing-compose.klib.api | 14 +++----------- .../app/softwork/routingcompose/DelegateRouter.kt | 4 ++-- .../app/softwork/routingcompose/Parameters.kt | 2 ++ .../kotlin/app/softwork/routingcompose/Path.kt | 3 +++ .../app/softwork/routingcompose/RouteBuilder.kt | 4 +++- .../kotlin/app/softwork/routingcompose/Router.kt | 3 ++- .../app/softwork/routingcompose/MockRouter.kt | 3 +-- .../kotlin/app/softwork/routingcompose/NavLink.kt | 2 +- .../app/softwork/routingcompose/BrowserRouter.kt | 3 +-- .../app/softwork/routingcompose/HashRouter.kt | 3 +-- .../app/softwork/routingcompose/DesktopRouter.kt | 3 +-- 12 files changed, 21 insertions(+), 26 deletions(-) diff --git a/api/routing-compose.api b/api/routing-compose.api index 2390bdb..cba4b75 100644 --- a/api/routing-compose.api +++ b/api/routing-compose.api @@ -55,7 +55,6 @@ public final class app/softwork/routingcompose/RouteBuilder { public final class app/softwork/routingcompose/RouteBuilder$NoMatch { public static final field $stable I - public fun (Ljava/lang/String;Lapp/softwork/routingcompose/Parameters;)V public final fun getParameters ()Lapp/softwork/routingcompose/Parameters; public final fun getRemainingPath ()Ljava/lang/String; public final fun redirect (Ljava/lang/String;ZLandroidx/compose/runtime/Composer;II)V @@ -63,7 +62,7 @@ public final class app/softwork/routingcompose/RouteBuilder$NoMatch { public abstract interface class app/softwork/routingcompose/Router { public static final field Companion Lapp/softwork/routingcompose/Router$Companion; - public abstract fun getCurrentPath ()Lapp/softwork/routingcompose/Path; + public abstract fun currentPath ()Lapp/softwork/routingcompose/Path; public abstract fun getPath (Ljava/lang/String;Landroidx/compose/runtime/Composer;I)Landroidx/compose/runtime/State; public abstract fun navigate (Ljava/lang/String;Z)V } diff --git a/api/routing-compose.klib.api b/api/routing-compose.klib.api index 687376a..12d7087 100644 --- a/api/routing-compose.klib.api +++ b/api/routing-compose.klib.api @@ -11,9 +11,7 @@ open annotation class app.softwork.routingcompose/Routing : kotlin/Annotation { } abstract interface app.softwork.routingcompose/Router { // app.softwork.routingcompose/Router|null[0] - abstract val currentPath // app.softwork.routingcompose/Router.currentPath|{}currentPath[0] - abstract fun (): app.softwork.routingcompose/Path // app.softwork.routingcompose/Router.currentPath.|(){}[0] - + abstract fun currentPath(): app.softwork.routingcompose/Path // app.softwork.routingcompose/Router.currentPath|currentPath(){}[0] abstract fun getPath(kotlin/String, androidx.compose.runtime/Composer?, kotlin/Int): androidx.compose.runtime/State // app.softwork.routingcompose/Router.getPath|getPath(kotlin.String;androidx.compose.runtime.Composer?;kotlin.Int){}[0] abstract fun navigate(kotlin/String, kotlin/Boolean = ...) // app.softwork.routingcompose/Router.navigate|navigate(kotlin.String;kotlin.Boolean){}[0] @@ -76,8 +74,6 @@ final class app.softwork.routingcompose/RouteBuilder { // app.softwork.routingco final fun uuid(kotlin/Function4, androidx.compose.runtime/Composer?, kotlin/Int) // app.softwork.routingcompose/RouteBuilder.uuid|uuid(kotlin.Function4;androidx.compose.runtime.Composer?;kotlin.Int){}[0] final class NoMatch { // app.softwork.routingcompose/RouteBuilder.NoMatch|null[0] - constructor (kotlin/String, app.softwork.routingcompose/Parameters?) // app.softwork.routingcompose/RouteBuilder.NoMatch.|(kotlin.String;app.softwork.routingcompose.Parameters?){}[0] - final val parameters // app.softwork.routingcompose/RouteBuilder.NoMatch.parameters|{}parameters[0] final fun (): app.softwork.routingcompose/Parameters? // app.softwork.routingcompose/RouteBuilder.NoMatch.parameters.|(){}[0] final val remainingPath // app.softwork.routingcompose/RouteBuilder.NoMatch.remainingPath|{}remainingPath[0] @@ -88,9 +84,7 @@ final class app.softwork.routingcompose/RouteBuilder { // app.softwork.routingco } final object app.softwork.routingcompose/BrowserRouter : app.softwork.routingcompose/Router { // app.softwork.routingcompose/BrowserRouter|null[0] - final val currentPath // app.softwork.routingcompose/BrowserRouter.currentPath|{}currentPath[0] - final fun (): app.softwork.routingcompose/Path // app.softwork.routingcompose/BrowserRouter.currentPath.|(){}[0] - + final fun currentPath(): app.softwork.routingcompose/Path // app.softwork.routingcompose/BrowserRouter.currentPath|currentPath(){}[0] final fun equals(kotlin/Any?): kotlin/Boolean // app.softwork.routingcompose/BrowserRouter.equals|equals(kotlin.Any?){}[0] final fun getPath(kotlin/String, androidx.compose.runtime/Composer?, kotlin/Int): androidx.compose.runtime/State // app.softwork.routingcompose/BrowserRouter.getPath|getPath(kotlin.String;androidx.compose.runtime.Composer?;kotlin.Int){}[0] final fun hashCode(): kotlin/Int // app.softwork.routingcompose/BrowserRouter.hashCode|hashCode(){}[0] @@ -99,9 +93,7 @@ final object app.softwork.routingcompose/BrowserRouter : app.softwork.routingcom } final object app.softwork.routingcompose/HashRouter : app.softwork.routingcompose/Router { // app.softwork.routingcompose/HashRouter|null[0] - final val currentPath // app.softwork.routingcompose/HashRouter.currentPath|{}currentPath[0] - final fun (): app.softwork.routingcompose/Path // app.softwork.routingcompose/HashRouter.currentPath.|(){}[0] - + final fun currentPath(): app.softwork.routingcompose/Path // app.softwork.routingcompose/HashRouter.currentPath|currentPath(){}[0] final fun equals(kotlin/Any?): kotlin/Boolean // app.softwork.routingcompose/HashRouter.equals|equals(kotlin.Any?){}[0] final fun getPath(kotlin/String, androidx.compose.runtime/Composer?, kotlin/Int): androidx.compose.runtime/State // app.softwork.routingcompose/HashRouter.getPath|getPath(kotlin.String;androidx.compose.runtime.Composer?;kotlin.Int){}[0] final fun hashCode(): kotlin/Int // app.softwork.routingcompose/HashRouter.hashCode|hashCode(){}[0] diff --git a/src/commonMain/kotlin/app/softwork/routingcompose/DelegateRouter.kt b/src/commonMain/kotlin/app/softwork/routingcompose/DelegateRouter.kt index 92b0be5..590618d 100644 --- a/src/commonMain/kotlin/app/softwork/routingcompose/DelegateRouter.kt +++ b/src/commonMain/kotlin/app/softwork/routingcompose/DelegateRouter.kt @@ -11,8 +11,8 @@ internal data class DelegateRouter(val basePath: String, val router: Router) : R router.navigate("/$to", hide) } - to.startsWith(".") -> { - val newPath = router.currentPath.relative(to) + to.startsWith("./") -> { + val newPath = router.currentPath().relative(to) router.navigate(newPath.path) } diff --git a/src/commonMain/kotlin/app/softwork/routingcompose/Parameters.kt b/src/commonMain/kotlin/app/softwork/routingcompose/Parameters.kt index 898fbde..7e3ce2e 100644 --- a/src/commonMain/kotlin/app/softwork/routingcompose/Parameters.kt +++ b/src/commonMain/kotlin/app/softwork/routingcompose/Parameters.kt @@ -1,7 +1,9 @@ package app.softwork.routingcompose +import androidx.compose.runtime.Immutable import kotlin.jvm.* +@Immutable public class Parameters private constructor(public val raw: String, public val map: Map>) { public companion object { private val reservedCharacters = mapOf( diff --git a/src/commonMain/kotlin/app/softwork/routingcompose/Path.kt b/src/commonMain/kotlin/app/softwork/routingcompose/Path.kt index 247340c..9ee3f94 100644 --- a/src/commonMain/kotlin/app/softwork/routingcompose/Path.kt +++ b/src/commonMain/kotlin/app/softwork/routingcompose/Path.kt @@ -1,5 +1,8 @@ package app.softwork.routingcompose +import androidx.compose.runtime.Immutable + +@Immutable public data class Path(val path: String, val parameters: Parameters?) { internal fun newPath(currentPath: String) = Path(path = path.removePrefix("/$currentPath"), parameters) diff --git a/src/commonMain/kotlin/app/softwork/routingcompose/RouteBuilder.kt b/src/commonMain/kotlin/app/softwork/routingcompose/RouteBuilder.kt index dc98a4e..1375695 100644 --- a/src/commonMain/kotlin/app/softwork/routingcompose/RouteBuilder.kt +++ b/src/commonMain/kotlin/app/softwork/routingcompose/RouteBuilder.kt @@ -34,6 +34,7 @@ import kotlin.uuid.* * ``` */ @Routing +@Stable public class RouteBuilder internal constructor(private val basePath: String, private val remainingPath: Path) { public val path: String = remainingPath.path public val parameters: Parameters? = remainingPath.parameters @@ -156,8 +157,9 @@ public class RouteBuilder internal constructor(private val basePath: String, pri } } + @Immutable @Routing - public class NoMatch(public val remainingPath: String, public val parameters: Parameters?) { + public class NoMatch internal constructor(public val remainingPath: String, public val parameters: Parameters?) { @Routing @Composable public fun redirect(target: String, hide: Boolean = false) { diff --git a/src/commonMain/kotlin/app/softwork/routingcompose/Router.kt b/src/commonMain/kotlin/app/softwork/routingcompose/Router.kt index b16f542..ab3a783 100644 --- a/src/commonMain/kotlin/app/softwork/routingcompose/Router.kt +++ b/src/commonMain/kotlin/app/softwork/routingcompose/Router.kt @@ -3,11 +3,12 @@ package app.softwork.routingcompose import androidx.compose.runtime.* import kotlin.jvm.* +@Stable public interface Router { /** * The current path */ - public val currentPath: Path + public fun currentPath(): Path public fun navigate(to: String, hide: Boolean = false) diff --git a/src/commonTest/kotlin/app/softwork/routingcompose/MockRouter.kt b/src/commonTest/kotlin/app/softwork/routingcompose/MockRouter.kt index e574bb1..c8d1a09 100644 --- a/src/commonTest/kotlin/app/softwork/routingcompose/MockRouter.kt +++ b/src/commonTest/kotlin/app/softwork/routingcompose/MockRouter.kt @@ -3,8 +3,7 @@ package app.softwork.routingcompose import androidx.compose.runtime.* class MockRouter : Router { - override val currentPath: Path - get() = Path.from(currentState.value!!) + override fun currentPath() = Path.from(currentState.value!!) private val currentState = mutableStateOf(null) diff --git a/src/jsMain/kotlin/app/softwork/routingcompose/NavLink.kt b/src/jsMain/kotlin/app/softwork/routingcompose/NavLink.kt index 284ca2d..ed199bb 100644 --- a/src/jsMain/kotlin/app/softwork/routingcompose/NavLink.kt +++ b/src/jsMain/kotlin/app/softwork/routingcompose/NavLink.kt @@ -20,7 +20,7 @@ public fun NavLink( A( href = to, attrs = { - val currentPath = router.currentPath.path + val currentPath = router.currentPath().path val selected = if (to == "/") { currentPath == to } else { diff --git a/src/jsSharedMain/kotlin/app/softwork/routingcompose/BrowserRouter.kt b/src/jsSharedMain/kotlin/app/softwork/routingcompose/BrowserRouter.kt index 2b5542b..24006f5 100644 --- a/src/jsSharedMain/kotlin/app/softwork/routingcompose/BrowserRouter.kt +++ b/src/jsSharedMain/kotlin/app/softwork/routingcompose/BrowserRouter.kt @@ -20,8 +20,7 @@ import androidx.compose.runtime.* * for full instructions. */ public data object BrowserRouter : Router { - override val currentPath: Path - get() = Path.from(currentLocation.value) + override fun currentPath(): Path = Path.from(currentLocation.value) private val currentLocation: MutableState = mutableStateOf(window.location.newPath()) diff --git a/src/jsSharedMain/kotlin/app/softwork/routingcompose/HashRouter.kt b/src/jsSharedMain/kotlin/app/softwork/routingcompose/HashRouter.kt index 9edd905..c985bf8 100644 --- a/src/jsSharedMain/kotlin/app/softwork/routingcompose/HashRouter.kt +++ b/src/jsSharedMain/kotlin/app/softwork/routingcompose/HashRouter.kt @@ -9,8 +9,7 @@ import androidx.compose.runtime.* * or using a SaaS `/index.html`. */ public data object HashRouter : Router { - override val currentPath: Path - get() = Path.from(currentHash.value) + override fun currentPath(): Path = Path.from(currentHash.value) private val currentHash: MutableState = mutableStateOf(window.location.hash.currentURL() ?: "") diff --git a/src/jvmMain/kotlin/app/softwork/routingcompose/DesktopRouter.kt b/src/jvmMain/kotlin/app/softwork/routingcompose/DesktopRouter.kt index 849a4ad..1b93631 100644 --- a/src/jvmMain/kotlin/app/softwork/routingcompose/DesktopRouter.kt +++ b/src/jvmMain/kotlin/app/softwork/routingcompose/DesktopRouter.kt @@ -13,8 +13,7 @@ public fun DesktopRouter(initRoute: String, navBuilder: @Composable RouteBuilder } internal class DesktopRouter : Router { - override val currentPath: Path - get() = Path.from(stack.last().path) + override fun currentPath() = Path.from(stack.last().path) private data class Entry(val path: String, val hide: Boolean)