From 8ee005939634a66a9a93f6b49c64f42e695b05ad Mon Sep 17 00:00:00 2001 From: Philip Wedemann <22521688+hfhbd@users.noreply.github.com> Date: Mon, 9 Sep 2024 13:03:30 +0200 Subject: [PATCH] Add wasm support (#404) --- build.gradle.kts | 30 +- detekt-baseline.xml | 3 + .../browserRouterTest/build.gradle.kts | 2 +- integrationTest/build.gradle.kts | 26 +- .../hashRouterTest/build.gradle.kts | 2 +- integrationTest/src/jvmMain/kotlin/main.kt | 71 +- .../src/jvmWasmSharedMain/kotlin/demo.kt | 78 ++ integrationTest/src/wasmJsMain/kotlin/main.kt | 13 + .../src/wasmJsMain/resources/index.html | 11 + kotlin-js-store/package-lock.json | 1009 ++++++++--------- settings.gradle.kts | 23 + .../softwork/routingcompose/browserApi.js.kt | 22 + .../softwork/routingcompose/BrowserRouter.kt | 2 - .../app/softwork/routingcompose/HashRouter.kt | 1 - .../app/softwork/routingcompose/browserApi.kt | 21 + .../routingcompose/browserApi.wasm.kt | 23 + 16 files changed, 708 insertions(+), 629 deletions(-) create mode 100644 integrationTest/src/jvmWasmSharedMain/kotlin/demo.kt create mode 100644 integrationTest/src/wasmJsMain/kotlin/main.kt create mode 100644 integrationTest/src/wasmJsMain/resources/index.html create mode 100644 src/jsMain/kotlin/app/softwork/routingcompose/browserApi.js.kt rename src/{jsMain => jsSharedMain}/kotlin/app/softwork/routingcompose/BrowserRouter.kt (97%) rename src/{jsMain => jsSharedMain}/kotlin/app/softwork/routingcompose/HashRouter.kt (98%) create mode 100644 src/jsSharedMain/kotlin/app/softwork/routingcompose/browserApi.kt create mode 100644 src/wasmJsMain/kotlin/app/softwork/routingcompose/browserApi.wasm.kt diff --git a/build.gradle.kts b/build.gradle.kts index 87b5e0c..1c90fa2 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -16,14 +16,25 @@ kotlin { jvmToolchain(11) jvm() - js(IR) { + js { browser() } + wasmJs { + browser() + } + applyDefaultHierarchyTemplate { + common { + group("jsShared") { + withJs() + withWasmJs() + } + } + } explicitApi() compilerOptions { - allWarningsAsErrors.set(true) progressiveMode.set(true) + freeCompilerArgs.add("-Xexpect-actual-classes") } sourceSets { @@ -39,18 +50,19 @@ kotlin { implementation(libs.kotlinx.coroutines.core) } } - named("jsMain") { + + jsMain { dependencies { api(compose.html.core) } } - named("jsTest") { + jsTest { dependencies { implementation(compose.html.testUtils) } } - named("jvmTest") { + jvmTest { dependencies { implementation(compose.desktop.uiTestJUnit4) // there is no non-ui testing implementation(compose.desktop.currentOs) // ui-testings needs skiko @@ -159,3 +171,11 @@ tasks { } } } + +plugins.withType { + the().downloadBaseUrl = null +} + +the().apply { + downloadBaseUrl = null +} diff --git a/detekt-baseline.xml b/detekt-baseline.xml index c921613..8cb1d6c 100644 --- a/detekt-baseline.xml +++ b/detekt-baseline.xml @@ -2,6 +2,9 @@ + Filename:browserApi.js.kt$app.softwork.routingcompose.browserApi.js.kt + Filename:browserApi.kt$app.softwork.routingcompose.browserApi.kt + Filename:browserApi.wasm.kt$app.softwork.routingcompose.browserApi.wasm.kt Filename:demo.kt$.demo.kt Filename:main.kt$.main.kt diff --git a/integrationTest/browserRouterTest/build.gradle.kts b/integrationTest/browserRouterTest/build.gradle.kts index 9198613..4c071e5 100644 --- a/integrationTest/browserRouterTest/build.gradle.kts +++ b/integrationTest/browserRouterTest/build.gradle.kts @@ -5,7 +5,7 @@ plugins { } kotlin { - js(IR) { + js { browser { binaries.executable() } diff --git a/integrationTest/build.gradle.kts b/integrationTest/build.gradle.kts index 7881969..2c51884 100644 --- a/integrationTest/build.gradle.kts +++ b/integrationTest/build.gradle.kts @@ -1,3 +1,7 @@ +import org.gradle.kotlin.dsl.support.KotlinCompilerOptions +import org.jetbrains.kotlin.gradle.dsl.KotlinCommonCompilerOptions +import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrCompilation + plugins { kotlin("multiplatform") kotlin("plugin.compose") @@ -8,8 +12,21 @@ kotlin { jvmToolchain(11) jvm() - js(IR) { + js { + browser() + } + wasmJs { browser() + binaries.executable() + } + + applyDefaultHierarchyTemplate { + common { + group("jvmWasmShared") { + withJvm() + withWasmJs() + } + } } sourceSets { @@ -19,7 +36,12 @@ kotlin { api(libs.kotlinx.coroutines.core) } } - named("jvmMain") { + named("jvmWasmSharedMain") { + dependencies { + implementation(compose.material) + } + } + jvmMain { dependencies { implementation(compose.desktop.currentOs) } diff --git a/integrationTest/hashRouterTest/build.gradle.kts b/integrationTest/hashRouterTest/build.gradle.kts index 9198613..4c071e5 100644 --- a/integrationTest/hashRouterTest/build.gradle.kts +++ b/integrationTest/hashRouterTest/build.gradle.kts @@ -5,7 +5,7 @@ plugins { } kotlin { - js(IR) { + js { browser { binaries.executable() } diff --git a/integrationTest/src/jvmMain/kotlin/main.kt b/integrationTest/src/jvmMain/kotlin/main.kt index 022265e..b07dd14 100644 --- a/integrationTest/src/jvmMain/kotlin/main.kt +++ b/integrationTest/src/jvmMain/kotlin/main.kt @@ -1,18 +1,14 @@ -import androidx.compose.foundation.layout.* -import androidx.compose.material.* import androidx.compose.runtime.* import androidx.compose.ui.window.* import app.softwork.routingcompose.* fun main() = application { - Demo(1) - Demo(2) + DemoWindow(1) + DemoWindow(2) } -private const val Answer = 42 - @Composable -private fun Demo(it: Int) { +fun DemoWindow(it: Int) { var isOpen by remember { mutableStateOf(true) } var wasMagic42 by remember { mutableStateOf(false) } if (isOpen) { @@ -20,66 +16,7 @@ private fun Demo(it: Int) { isOpen = false }, title = "$it") { DesktopRouter("/$it") { - Column { - val params = parameters?.map - if (params != null) { - Text("Parameters: $params") - } - if (wasMagic42) { - route("/answer") { - val router = Router.current - Text("The Answer to the Ultimate Question of Life, the Universe, and Everything is 42.") - Button(onClick = { router.navigateBack() }) { - Text("Back") - } - } - } - int { - Content(it, wasMagic42) - if (it == Answer) { - LaunchedEffect(it) { - wasMagic42 = true - } - } - } - string { - Column { - val router = Router.current - Text("Hello $it") - Button(onClick = { router.navigateBack() }) { - Text("Back") - } - } - } - } - } - } - } -} - -@Composable -fun Content(int: Int, wasMagic42: Boolean) { - var name by remember { mutableStateOf("") } - val router = Router.current - Column { - Text("Hello World $int") - TextField(value = name, { - name = it - }) - - if (name.isNotBlank()) { - Button({ - router.navigate("/$name") - }) { - Text("Update name") - } - } - - if (wasMagic42) { - Button({ - router.navigate("/answer") - }) { - Text("Unlocked answer") + Demo(it, wasMagic42, { wasMagic42 = it }) } } } diff --git a/integrationTest/src/jvmWasmSharedMain/kotlin/demo.kt b/integrationTest/src/jvmWasmSharedMain/kotlin/demo.kt new file mode 100644 index 0000000..4e2ad8c --- /dev/null +++ b/integrationTest/src/jvmWasmSharedMain/kotlin/demo.kt @@ -0,0 +1,78 @@ +import androidx.compose.foundation.layout.* +import androidx.compose.material.* +import androidx.compose.runtime.* +import app.softwork.routingcompose.* + +private const val Answer = 42 + +@Composable +fun RouteBuilder.Demo( + root: Int, + wasMagic42: Boolean, + changeMagic42: (Boolean) -> Unit, +) { + Column { + val params = parameters?.map + if (params != null) { + Text("Parameters: $params") + } + if (wasMagic42) { + route("/answer") { + val router = Router.current + Text("The Answer to the Ultimate Question of Life, the Universe, and Everything is 42.") + Button(onClick = { + router.navigate("/$root") + }) { + Text("Back") + } + } + } + int { + Content(it, wasMagic42) + if (it == Answer) { + LaunchedEffect(it) { + changeMagic42(true) + } + } + } + string { + Column { + val router = Router.current + Text("Hello $it") + Button(onClick = { + router.navigate("/$root") + }) { + Text("Back") + } + } + } + } +} + +@Composable +fun Content(int: Int, wasMagic42: Boolean) { + var name by remember { mutableStateOf("") } + val router = Router.current + Column { + Text("Hello World $int") + TextField(value = name, { + name = it + }) + + if (name.isNotBlank()) { + Button({ + router.navigate("/$name") + }) { + Text("Update name") + } + } + + if (wasMagic42) { + Button({ + router.navigate("/answer") + }) { + Text("Unlocked answer") + } + } + } +} diff --git a/integrationTest/src/wasmJsMain/kotlin/main.kt b/integrationTest/src/wasmJsMain/kotlin/main.kt new file mode 100644 index 0000000..426f3e2 --- /dev/null +++ b/integrationTest/src/wasmJsMain/kotlin/main.kt @@ -0,0 +1,13 @@ + +import androidx.compose.runtime.* +import androidx.compose.ui.* +import androidx.compose.ui.window.* +import app.softwork.routingcompose.* + +@ExperimentalComposeUiApi +fun main() = CanvasBasedWindow("WASM Test") { + var wasMagic42 by remember { mutableStateOf(false) } + HashRouter("/1") { + Demo(1, wasMagic42, { wasMagic42 = it }) + } +} diff --git a/integrationTest/src/wasmJsMain/resources/index.html b/integrationTest/src/wasmJsMain/resources/index.html new file mode 100644 index 0000000..642a411 --- /dev/null +++ b/integrationTest/src/wasmJsMain/resources/index.html @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/kotlin-js-store/package-lock.json b/kotlin-js-store/package-lock.json index 58457eb..43e2e7a 100644 --- a/kotlin-js-store/package-lock.json +++ b/kotlin-js-store/package-lock.json @@ -10,14 +10,20 @@ "workspaces": [ "packages/routing-compose", "packages/routing-compose-test", + "packages/routing-compose-wasm-js", + "packages/routing-compose-wasm-js-test", "packages/routing-compose-integrationTest", "packages/routing-compose-integrationTest-test", + "packages/routing-compose-integrationTest-wasm-js", + "packages/routing-compose-integrationTest-wasm-js-test", "packages/routing-compose-integrationTest-browserRouterTest", "packages/routing-compose-integrationTest-browserRouterTest-test", "packages/routing-compose-integrationTest-hashRouterTest", "packages/routing-compose-integrationTest-hashRouterTest-test", "packages_imported/html-core-js/1.6.11", - "packages_imported/kotlin-test-js-runner/0.0.2" + "packages_imported/kotlin-test-js-runner/0.0.2", + "packages_imported/skiko-wasm-js/0.8.4", + "packages_imported/skiko-js-wasm-runtime/0.8.4" ], "devDependencies": {} }, @@ -263,6 +269,12 @@ "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==", "dev": true }, + "node_modules/@types/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==", + "dev": true + }, "node_modules/@types/send": { "version": "0.17.4", "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", @@ -581,15 +593,15 @@ } }, "node_modules/ajv-formats/node_modules/ajv": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", - "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "dev": true, "dependencies": { - "fast-deep-equal": "^3.1.1", + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" + "require-from-string": "^2.0.2" }, "funding": { "type": "github", @@ -1191,6 +1203,15 @@ "node": ">= 10" } }, + "node_modules/define-lazy-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", + "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", @@ -2153,6 +2174,21 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "dev": true, + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -2240,6 +2276,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dev": true, + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", @@ -2543,6 +2591,18 @@ "node": ">= 0.6" } }, + "node_modules/memfs": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz", + "integrity": "sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==", + "dev": true, + "dependencies": { + "fs-monkey": "^1.0.4" + }, + "engines": { + "node": ">= 4.0.0" + } + }, "node_modules/merge-descriptors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", @@ -2899,6 +2959,23 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/open": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", + "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", + "dev": true, + "dependencies": { + "define-lazy-prop": "^2.0.0", + "is-docker": "^2.1.1", + "is-wsl": "^2.2.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -2929,6 +3006,19 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/p-retry": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz", + "integrity": "sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==", + "dev": true, + "dependencies": { + "@types/retry": "0.12.0", + "retry": "^0.13.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", @@ -3321,10 +3411,26 @@ "resolved": "packages/routing-compose-integrationTest-test", "link": true }, + "node_modules/routing-compose-integrationTest-wasm-js": { + "resolved": "packages/routing-compose-integrationTest-wasm-js", + "link": true + }, + "node_modules/routing-compose-integrationTest-wasm-js-test": { + "resolved": "packages/routing-compose-integrationTest-wasm-js-test", + "link": true + }, "node_modules/routing-compose-test": { "resolved": "packages/routing-compose-test", "link": true }, + "node_modules/routing-compose-wasm-js": { + "resolved": "packages/routing-compose-wasm-js", + "link": true + }, + "node_modules/routing-compose-wasm-js-test": { + "resolved": "packages/routing-compose-wasm-js-test", + "link": true + }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -3585,6 +3691,14 @@ "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", "dev": true }, + "node_modules/skiko-js-wasm-runtime": { + "resolved": "packages_imported/skiko-js-wasm-runtime/0.8.4", + "link": true + }, + "node_modules/skiko-wasm-js": { + "resolved": "packages_imported/skiko-wasm-js/0.8.4", + "link": true + }, "node_modules/socket.io": { "version": "4.7.5", "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.7.5.tgz", @@ -4351,104 +4465,313 @@ "node": ">=10.0.0" } }, - "node_modules/webpack-merge": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-4.2.2.tgz", - "integrity": "sha512-TUE1UGoTX2Cd42j3krGYqObZbOD+xF7u28WB7tfUordytSjbWTIjK/8V0amkBfTYN4/pB/GIDlJZZ657BGG19g==", + "node_modules/webpack-dev-middleware": { + "version": "5.3.4", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.4.tgz", + "integrity": "sha512-BVdTqhhs+0IfoeAf7EoH5WE+exCmqGerHfDM0IL096Px60Tq2Mn9MAbnaGUe6HiMa41KMCYF19gyzZmBcq/o4Q==", "dev": true, "dependencies": { - "lodash": "^4.17.15" - } - }, - "node_modules/webpack-sources": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", - "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", - "dev": true, + "colorette": "^2.0.10", + "memfs": "^3.4.3", + "mime-types": "^2.1.31", + "range-parser": "^1.2.1", + "schema-utils": "^4.0.0" + }, "engines": { - "node": ">=10.13.0" + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^4.0.0 || ^5.0.0" } }, - "node_modules/websocket-driver": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", - "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", + "node_modules/webpack-dev-middleware/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "dev": true, "dependencies": { - "http-parser-js": ">=0.5.1", - "safe-buffer": ">=5.1.0", - "websocket-extensions": ">=0.1.1" + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/websocket-extensions": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", - "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", - "dev": true, - "engines": { - "node": ">=0.8.0" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "node_modules/webpack-dev-middleware/node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", "dev": true, "dependencies": { - "isexe": "^2.0.0" + "fast-deep-equal": "^3.1.3" }, - "bin": { - "which": "bin/which" + "peerDependencies": { + "ajv": "^8.8.2" } }, - "node_modules/wildcard": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.0.tgz", - "integrity": "sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==", - "dev": true - }, - "node_modules/workerpool": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.5.1.tgz", - "integrity": "sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==", + "node_modules/webpack-dev-middleware/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "dev": true }, - "node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "node_modules/webpack-dev-middleware/node_modules/schema-utils": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", + "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", "dev": true, "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" }, "engines": { - "node": ">=10" + "node": ">= 12.13.0" }, "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + "type": "opencollective", + "url": "https://opencollective.com/webpack" } }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true - }, - "node_modules/ws": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz", - "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==", + "node_modules/webpack-dev-server": { + "version": "4.15.2", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.15.2.tgz", + "integrity": "sha512-0XavAZbNJ5sDrCbkpWL8mia0o5WPOd2YGtxrEiZkBK9FjLppIUK2TgxK6qGD2P3hUXTJNNPVibrerKcx5WkR1g==", "dev": true, + "dependencies": { + "@types/bonjour": "^3.5.9", + "@types/connect-history-api-fallback": "^1.3.5", + "@types/express": "^4.17.13", + "@types/serve-index": "^1.9.1", + "@types/serve-static": "^1.13.10", + "@types/sockjs": "^0.3.33", + "@types/ws": "^8.5.5", + "ansi-html-community": "^0.0.8", + "bonjour-service": "^1.0.11", + "chokidar": "^3.5.3", + "colorette": "^2.0.10", + "compression": "^1.7.4", + "connect-history-api-fallback": "^2.0.0", + "default-gateway": "^6.0.3", + "express": "^4.17.3", + "graceful-fs": "^4.2.6", + "html-entities": "^2.3.2", + "http-proxy-middleware": "^2.0.3", + "ipaddr.js": "^2.0.1", + "launch-editor": "^2.6.0", + "open": "^8.0.9", + "p-retry": "^4.5.0", + "rimraf": "^3.0.2", + "schema-utils": "^4.0.0", + "selfsigned": "^2.1.1", + "serve-index": "^1.9.1", + "sockjs": "^0.3.24", + "spdy": "^4.0.2", + "webpack-dev-middleware": "^5.3.4", + "ws": "^8.13.0" + }, + "bin": { + "webpack-dev-server": "bin/webpack-dev-server.js" + }, "engines": { - "node": ">=10.0.0" + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" }, "peerDependencies": { - "bufferutil": "^4.0.1", + "webpack": "^4.37.0 || ^5.0.0" + }, + "peerDependenciesMeta": { + "webpack": { + "optional": true + }, + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-dev-server/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/webpack-dev-server/node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/webpack-dev-server/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "node_modules/webpack-dev-server/node_modules/schema-utils": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", + "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/webpack-dev-server/node_modules/ws": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", + "dev": true, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/webpack-merge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-4.2.2.tgz", + "integrity": "sha512-TUE1UGoTX2Cd42j3krGYqObZbOD+xF7u28WB7tfUordytSjbWTIjK/8V0amkBfTYN4/pB/GIDlJZZ657BGG19g==", + "dev": true, + "dependencies": { + "lodash": "^4.17.15" + } + }, + "node_modules/webpack-sources": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", + "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", + "dev": true, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/websocket-driver": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", + "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", + "dev": true, + "dependencies": { + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/websocket-extensions": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/wildcard": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.0.tgz", + "integrity": "sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==", + "dev": true + }, + "node_modules/workerpool": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.5.1.tgz", + "integrity": "sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==", + "dev": true + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "node_modules/ws": { + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz", + "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==", + "dev": true, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", "utf-8-validate": "^5.0.2" }, "peerDependenciesMeta": { @@ -4554,6 +4877,16 @@ }, "devDependencies": {} }, + "packages_imported/skiko-js-wasm-runtime/0.8.4": { + "name": "skiko-js-wasm-runtime", + "version": "0.8.4", + "devDependencies": {} + }, + "packages_imported/skiko-wasm-js/0.8.4": { + "name": "skiko-wasm-js", + "version": "0.8.4", + "devDependencies": {} + }, "packages/routing-compose": { "version": "0.0.0-unspecified", "dependencies": { @@ -4599,247 +4932,56 @@ "webpack-cli": "5.1.4" } }, - "packages/routing-compose-integrationTest-browserRouterTest/node_modules/@types/retry": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", - "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==", - "dev": true - }, - "packages/routing-compose-integrationTest-browserRouterTest/node_modules/ajv": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", - "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", - "dev": true, + "packages/routing-compose-integrationTest-hashRouterTest": { + "version": "0.0.0-unspecified", "dependencies": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" + "format-util": "^1.0.5" }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" + "devDependencies": { + "source-map-loader": "5.0.0", + "typescript": "5.5.4", + "webpack": "5.93.0", + "webpack-cli": "5.1.4", + "webpack-dev-server": "4.15.2" } }, - "packages/routing-compose-integrationTest-browserRouterTest/node_modules/ajv-keywords": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", - "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", - "dev": true, + "packages/routing-compose-integrationTest-hashRouterTest-test": { + "version": "0.0.0-unspecified", "dependencies": { - "fast-deep-equal": "^3.1.3" + "format-util": "^1.0.5" }, - "peerDependencies": { - "ajv": "^8.8.2" + "devDependencies": { + "karma": "6.4.3", + "karma-chrome-launcher": "3.2.0", + "karma-mocha": "2.0.1", + "karma-sourcemap-loader": "0.4.0", + "karma-webpack": "5.0.1", + "mocha": "10.7.0", + "source-map-loader": "5.0.0", + "typescript": "5.5.4", + "webpack": "5.93.0", + "webpack-cli": "5.1.4" } }, - "packages/routing-compose-integrationTest-browserRouterTest/node_modules/define-lazy-prop": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", - "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", - "dev": true, - "engines": { - "node": ">=8" + "packages/routing-compose-integrationTest-test": { + "version": "0.0.0-unspecified", + "dependencies": { + "format-util": "^1.0.5" + }, + "devDependencies": { + "karma": "6.4.3", + "karma-chrome-launcher": "3.2.0", + "karma-mocha": "2.0.1", + "karma-sourcemap-loader": "0.4.0", + "karma-webpack": "5.0.1", + "mocha": "10.7.0", + "source-map-loader": "5.0.0", + "typescript": "5.5.4", + "webpack": "5.93.0", + "webpack-cli": "5.1.4" } }, - "packages/routing-compose-integrationTest-browserRouterTest/node_modules/is-docker": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", - "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", - "dev": true, - "bin": { - "is-docker": "cli.js" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/routing-compose-integrationTest-browserRouterTest/node_modules/is-wsl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", - "dev": true, - "dependencies": { - "is-docker": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "packages/routing-compose-integrationTest-browserRouterTest/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - }, - "packages/routing-compose-integrationTest-browserRouterTest/node_modules/memfs": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz", - "integrity": "sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==", - "dev": true, - "dependencies": { - "fs-monkey": "^1.0.4" - }, - "engines": { - "node": ">= 4.0.0" - } - }, - "packages/routing-compose-integrationTest-browserRouterTest/node_modules/open": { - "version": "8.4.2", - "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", - "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", - "dev": true, - "dependencies": { - "define-lazy-prop": "^2.0.0", - "is-docker": "^2.1.1", - "is-wsl": "^2.2.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/routing-compose-integrationTest-browserRouterTest/node_modules/p-retry": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz", - "integrity": "sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==", - "dev": true, - "dependencies": { - "@types/retry": "0.12.0", - "retry": "^0.13.1" - }, - "engines": { - "node": ">=8" - } - }, - "packages/routing-compose-integrationTest-browserRouterTest/node_modules/schema-utils": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", - "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", - "dev": true, - "dependencies": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.9.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.1.0" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "packages/routing-compose-integrationTest-browserRouterTest/node_modules/webpack-dev-middleware": { - "version": "5.3.4", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.4.tgz", - "integrity": "sha512-BVdTqhhs+0IfoeAf7EoH5WE+exCmqGerHfDM0IL096Px60Tq2Mn9MAbnaGUe6HiMa41KMCYF19gyzZmBcq/o4Q==", - "dev": true, - "dependencies": { - "colorette": "^2.0.10", - "memfs": "^3.4.3", - "mime-types": "^2.1.31", - "range-parser": "^1.2.1", - "schema-utils": "^4.0.0" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^4.0.0 || ^5.0.0" - } - }, - "packages/routing-compose-integrationTest-browserRouterTest/node_modules/webpack-dev-server": { - "version": "4.15.2", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.15.2.tgz", - "integrity": "sha512-0XavAZbNJ5sDrCbkpWL8mia0o5WPOd2YGtxrEiZkBK9FjLppIUK2TgxK6qGD2P3hUXTJNNPVibrerKcx5WkR1g==", - "dev": true, - "dependencies": { - "@types/bonjour": "^3.5.9", - "@types/connect-history-api-fallback": "^1.3.5", - "@types/express": "^4.17.13", - "@types/serve-index": "^1.9.1", - "@types/serve-static": "^1.13.10", - "@types/sockjs": "^0.3.33", - "@types/ws": "^8.5.5", - "ansi-html-community": "^0.0.8", - "bonjour-service": "^1.0.11", - "chokidar": "^3.5.3", - "colorette": "^2.0.10", - "compression": "^1.7.4", - "connect-history-api-fallback": "^2.0.0", - "default-gateway": "^6.0.3", - "express": "^4.17.3", - "graceful-fs": "^4.2.6", - "html-entities": "^2.3.2", - "http-proxy-middleware": "^2.0.3", - "ipaddr.js": "^2.0.1", - "launch-editor": "^2.6.0", - "open": "^8.0.9", - "p-retry": "^4.5.0", - "rimraf": "^3.0.2", - "schema-utils": "^4.0.0", - "selfsigned": "^2.1.1", - "serve-index": "^1.9.1", - "sockjs": "^0.3.24", - "spdy": "^4.0.2", - "webpack-dev-middleware": "^5.3.4", - "ws": "^8.13.0" - }, - "bin": { - "webpack-dev-server": "bin/webpack-dev-server.js" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^4.37.0 || ^5.0.0" - }, - "peerDependenciesMeta": { - "webpack": { - "optional": true - }, - "webpack-cli": { - "optional": true - } - } - }, - "packages/routing-compose-integrationTest-browserRouterTest/node_modules/ws": { - "version": "8.18.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", - "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", - "dev": true, - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "packages/routing-compose-integrationTest-hashRouterTest": { + "packages/routing-compose-integrationTest-wasm-js": { "version": "0.0.0-unspecified", "dependencies": { "format-util": "^1.0.5" @@ -4852,7 +4994,7 @@ "webpack-dev-server": "4.15.2" } }, - "packages/routing-compose-integrationTest-hashRouterTest-test": { + "packages/routing-compose-integrationTest-wasm-js-test": { "version": "0.0.0-unspecified", "dependencies": { "format-util": "^1.0.5" @@ -4870,247 +5012,7 @@ "webpack-cli": "5.1.4" } }, - "packages/routing-compose-integrationTest-hashRouterTest/node_modules/@types/retry": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", - "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==", - "dev": true - }, - "packages/routing-compose-integrationTest-hashRouterTest/node_modules/ajv": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", - "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "packages/routing-compose-integrationTest-hashRouterTest/node_modules/ajv-keywords": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", - "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.3" - }, - "peerDependencies": { - "ajv": "^8.8.2" - } - }, - "packages/routing-compose-integrationTest-hashRouterTest/node_modules/define-lazy-prop": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", - "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "packages/routing-compose-integrationTest-hashRouterTest/node_modules/is-docker": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", - "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", - "dev": true, - "bin": { - "is-docker": "cli.js" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/routing-compose-integrationTest-hashRouterTest/node_modules/is-wsl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", - "dev": true, - "dependencies": { - "is-docker": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "packages/routing-compose-integrationTest-hashRouterTest/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - }, - "packages/routing-compose-integrationTest-hashRouterTest/node_modules/memfs": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz", - "integrity": "sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==", - "dev": true, - "dependencies": { - "fs-monkey": "^1.0.4" - }, - "engines": { - "node": ">= 4.0.0" - } - }, - "packages/routing-compose-integrationTest-hashRouterTest/node_modules/open": { - "version": "8.4.2", - "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", - "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", - "dev": true, - "dependencies": { - "define-lazy-prop": "^2.0.0", - "is-docker": "^2.1.1", - "is-wsl": "^2.2.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/routing-compose-integrationTest-hashRouterTest/node_modules/p-retry": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz", - "integrity": "sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==", - "dev": true, - "dependencies": { - "@types/retry": "0.12.0", - "retry": "^0.13.1" - }, - "engines": { - "node": ">=8" - } - }, - "packages/routing-compose-integrationTest-hashRouterTest/node_modules/schema-utils": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", - "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", - "dev": true, - "dependencies": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.9.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.1.0" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "packages/routing-compose-integrationTest-hashRouterTest/node_modules/webpack-dev-middleware": { - "version": "5.3.4", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.4.tgz", - "integrity": "sha512-BVdTqhhs+0IfoeAf7EoH5WE+exCmqGerHfDM0IL096Px60Tq2Mn9MAbnaGUe6HiMa41KMCYF19gyzZmBcq/o4Q==", - "dev": true, - "dependencies": { - "colorette": "^2.0.10", - "memfs": "^3.4.3", - "mime-types": "^2.1.31", - "range-parser": "^1.2.1", - "schema-utils": "^4.0.0" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^4.0.0 || ^5.0.0" - } - }, - "packages/routing-compose-integrationTest-hashRouterTest/node_modules/webpack-dev-server": { - "version": "4.15.2", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.15.2.tgz", - "integrity": "sha512-0XavAZbNJ5sDrCbkpWL8mia0o5WPOd2YGtxrEiZkBK9FjLppIUK2TgxK6qGD2P3hUXTJNNPVibrerKcx5WkR1g==", - "dev": true, - "dependencies": { - "@types/bonjour": "^3.5.9", - "@types/connect-history-api-fallback": "^1.3.5", - "@types/express": "^4.17.13", - "@types/serve-index": "^1.9.1", - "@types/serve-static": "^1.13.10", - "@types/sockjs": "^0.3.33", - "@types/ws": "^8.5.5", - "ansi-html-community": "^0.0.8", - "bonjour-service": "^1.0.11", - "chokidar": "^3.5.3", - "colorette": "^2.0.10", - "compression": "^1.7.4", - "connect-history-api-fallback": "^2.0.0", - "default-gateway": "^6.0.3", - "express": "^4.17.3", - "graceful-fs": "^4.2.6", - "html-entities": "^2.3.2", - "http-proxy-middleware": "^2.0.3", - "ipaddr.js": "^2.0.1", - "launch-editor": "^2.6.0", - "open": "^8.0.9", - "p-retry": "^4.5.0", - "rimraf": "^3.0.2", - "schema-utils": "^4.0.0", - "selfsigned": "^2.1.1", - "serve-index": "^1.9.1", - "sockjs": "^0.3.24", - "spdy": "^4.0.2", - "webpack-dev-middleware": "^5.3.4", - "ws": "^8.13.0" - }, - "bin": { - "webpack-dev-server": "bin/webpack-dev-server.js" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^4.37.0 || ^5.0.0" - }, - "peerDependenciesMeta": { - "webpack": { - "optional": true - }, - "webpack-cli": { - "optional": true - } - } - }, - "packages/routing-compose-integrationTest-hashRouterTest/node_modules/ws": { - "version": "8.18.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", - "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", - "dev": true, - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "packages/routing-compose-integrationTest-test": { + "packages/routing-compose-test": { "version": "0.0.0-unspecified", "dependencies": { "format-util": "^1.0.5" @@ -5128,7 +5030,14 @@ "webpack-cli": "5.1.4" } }, - "packages/routing-compose-test": { + "packages/routing-compose-wasm-js": { + "version": "0.0.0-unspecified", + "dependencies": { + "format-util": "^1.0.5" + }, + "devDependencies": {} + }, + "packages/routing-compose-wasm-js-test": { "version": "0.0.0-unspecified", "dependencies": { "format-util": "^1.0.5" diff --git a/settings.gradle.kts b/settings.gradle.kts index 7b0128b..d273cde 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -22,9 +22,32 @@ develocity { } dependencyResolutionManagement { + repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { mavenCentral() google() + exclusiveContent { + forRepository { + ivy("https://nodejs.org/dist/") { + name = "Node Distributions at $url" + patternLayout { artifact("v[revision]/[artifact](-v[revision]-[classifier]).[ext]") } + metadataSources { artifact() } + content { includeModule("org.nodejs", "node") } + } + } + filter { includeGroup("org.nodejs") } + } + exclusiveContent { + forRepository { + ivy("https://github.com/WebAssembly/binaryen/releases/download") { + name = "Binaryen Distributions at $url" + patternLayout { artifact("version_[revision]/[module]-version_[revision]-[classifier].[ext]") } + metadataSources { artifact() } + content { includeModule("com.github.webassembly", "binaryen") } + } + } + filter { includeGroup("com.github.webassembly") } + } } } diff --git a/src/jsMain/kotlin/app/softwork/routingcompose/browserApi.js.kt b/src/jsMain/kotlin/app/softwork/routingcompose/browserApi.js.kt new file mode 100644 index 0000000..6b91f4e --- /dev/null +++ b/src/jsMain/kotlin/app/softwork/routingcompose/browserApi.js.kt @@ -0,0 +1,22 @@ +package app.softwork.routingcompose + +internal actual typealias Window = org.w3c.dom.Window + +internal actual typealias History = org.w3c.dom.History +internal actual fun History.pushState(data: Any?, title: String, url: String?) { + this.pushState(data, title, url) +} + +internal actual typealias Location = org.w3c.dom.Location + +internal actual val window: Window get() = kotlinx.browser.window +internal actual var Window.onpopstate: () -> Unit + get() = { onpopstate() } + set(value) { + onpopstate = { value() } + } +internal actual var Window.onhashchange: () -> Unit + get() = { onhashchange() } + set(value) { + onhashchange = { value() } + } diff --git a/src/jsMain/kotlin/app/softwork/routingcompose/BrowserRouter.kt b/src/jsSharedMain/kotlin/app/softwork/routingcompose/BrowserRouter.kt similarity index 97% rename from src/jsMain/kotlin/app/softwork/routingcompose/BrowserRouter.kt rename to src/jsSharedMain/kotlin/app/softwork/routingcompose/BrowserRouter.kt index d930c5f..8d16ed3 100644 --- a/src/jsMain/kotlin/app/softwork/routingcompose/BrowserRouter.kt +++ b/src/jsSharedMain/kotlin/app/softwork/routingcompose/BrowserRouter.kt @@ -1,8 +1,6 @@ package app.softwork.routingcompose import androidx.compose.runtime.* -import kotlinx.browser.* -import org.w3c.dom.* /** * A router leveraging the History API (https://developer.mozilla.org/en-US/docs/Web/API/History). diff --git a/src/jsMain/kotlin/app/softwork/routingcompose/HashRouter.kt b/src/jsSharedMain/kotlin/app/softwork/routingcompose/HashRouter.kt similarity index 98% rename from src/jsMain/kotlin/app/softwork/routingcompose/HashRouter.kt rename to src/jsSharedMain/kotlin/app/softwork/routingcompose/HashRouter.kt index 95390d8..fe303fa 100644 --- a/src/jsMain/kotlin/app/softwork/routingcompose/HashRouter.kt +++ b/src/jsSharedMain/kotlin/app/softwork/routingcompose/HashRouter.kt @@ -1,7 +1,6 @@ package app.softwork.routingcompose import androidx.compose.runtime.* -import kotlinx.browser.* /** * This [Router] implementation uses `/#/path` to persistent the current route in [window.location.hash]. diff --git a/src/jsSharedMain/kotlin/app/softwork/routingcompose/browserApi.kt b/src/jsSharedMain/kotlin/app/softwork/routingcompose/browserApi.kt new file mode 100644 index 0000000..25ed124 --- /dev/null +++ b/src/jsSharedMain/kotlin/app/softwork/routingcompose/browserApi.kt @@ -0,0 +1,21 @@ +package app.softwork.routingcompose + +internal expect abstract class Window { + val history: History + val location: Location +} + +internal expect var Window.onpopstate: () -> Unit + +internal expect var Window.onhashchange: () -> Unit + +internal expect abstract class History +internal expect fun History.pushState(data: Any?, title: String, url: String?) + +internal expect abstract class Location { + var pathname: String + var search: String + var hash: String +} + +internal expect val window: Window diff --git a/src/wasmJsMain/kotlin/app/softwork/routingcompose/browserApi.wasm.kt b/src/wasmJsMain/kotlin/app/softwork/routingcompose/browserApi.wasm.kt new file mode 100644 index 0000000..711776c --- /dev/null +++ b/src/wasmJsMain/kotlin/app/softwork/routingcompose/browserApi.wasm.kt @@ -0,0 +1,23 @@ +package app.softwork.routingcompose + +internal actual typealias Window = org.w3c.dom.Window + +internal actual typealias History = org.w3c.dom.History + +internal actual fun History.pushState(data: Any?, title: String, url: String?) { + this.pushState(data, title, url) +} + +internal actual typealias Location = org.w3c.dom.Location + +internal actual val window: Window get() = kotlinx.browser.window +internal actual var Window.onpopstate: () -> Unit + get() = { onpopstate() } + set(value) { + onpopstate = { value() } + } +internal actual var Window.onhashchange: () -> Unit + get() = { onhashchange() } + set(value) { + onhashchange = { value() } + }