From 3b07a49839b7e148997df16b71031058351d90a5 Mon Sep 17 00:00:00 2001 From: Filipp Zhinkin Date: Tue, 19 Mar 2024 17:59:35 +0100 Subject: [PATCH 1/2] Unify module loading for js and wasmJs --- core/js/src/node/nodeModulesJs.kt | 39 --------------- core/nodeFilesystemShared/src/node/buffer.kt | 8 +++- core/nodeFilesystemShared/src/node/fs.kt | 6 ++- .../src/node/modLoader.kt | 19 ++++++++ core/nodeFilesystemShared/src/node/os.kt | 6 ++- core/nodeFilesystemShared/src/node/path.kt | 6 ++- core/wasmJs/src/node/nodeModulesWasmJs.kt | 47 ------------------- 7 files changed, 41 insertions(+), 90 deletions(-) delete mode 100644 core/js/src/node/nodeModulesJs.kt create mode 100644 core/nodeFilesystemShared/src/node/modLoader.kt delete mode 100644 core/wasmJs/src/node/nodeModulesWasmJs.kt diff --git a/core/js/src/node/nodeModulesJs.kt b/core/js/src/node/nodeModulesJs.kt deleted file mode 100644 index 83fe3f2f4..000000000 --- a/core/js/src/node/nodeModulesJs.kt +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2010-2024 JetBrains s.r.o. and Kotlin Programming Language contributors. - * Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE.txt file. - */ - -package kotlinx.io.node - -internal actual val path: Path by lazy { - try { - js("eval('require')('path')") - } catch (e: Throwable) { - throw UnsupportedOperationException("Module 'path' could not be imported", e) - } -} - -internal actual val fs: Fs by lazy { - try { - js("eval('require')('fs')") - } catch (e: Throwable) { - throw UnsupportedOperationException("Module 'fs' could not be imported", e) - } -} - -internal actual val os: Os by lazy { - try { - js("eval('require')('os')") - } catch (e: Throwable) { - throw UnsupportedOperationException("Module 'os' could not be imported", e) - } -} - -internal actual val buffer: BufferModule by lazy { - try { - js("eval('require')('buffer')") - } catch (e: Throwable) { - throw UnsupportedOperationException("Module 'buffer' could not be imported", e) - } -} - diff --git a/core/nodeFilesystemShared/src/node/buffer.kt b/core/nodeFilesystemShared/src/node/buffer.kt index a457094e4..a9e9029f5 100644 --- a/core/nodeFilesystemShared/src/node/buffer.kt +++ b/core/nodeFilesystemShared/src/node/buffer.kt @@ -5,6 +5,8 @@ package kotlinx.io.node +import kotlinx.io.withCaughtException + internal external interface BufferModule { val Buffer: BufferObj } @@ -22,4 +24,8 @@ internal external interface Buffer { fun writeInt8(value: Byte, offset: Int) } -internal expect val buffer: BufferModule +internal val buffer: BufferModule by lazy { + loadModule("buffer", ::bufferInitializer) +} + +private fun bufferInitializer(): BufferModule? = js("eval('require')('buffer')") diff --git a/core/nodeFilesystemShared/src/node/fs.kt b/core/nodeFilesystemShared/src/node/fs.kt index 84c9ba989..8a9718f0b 100644 --- a/core/nodeFilesystemShared/src/node/fs.kt +++ b/core/nodeFilesystemShared/src/node/fs.kt @@ -86,4 +86,8 @@ internal external interface realpathSync { fun native(path: String): String } -internal expect val fs: Fs +internal val fs: Fs by lazy { + loadModule("fs", ::fsInitializer) +} + +private fun fsInitializer(): Fs? = js("eval('require')('fs')") diff --git a/core/nodeFilesystemShared/src/node/modLoader.kt b/core/nodeFilesystemShared/src/node/modLoader.kt new file mode 100644 index 000000000..a0f14fc2c --- /dev/null +++ b/core/nodeFilesystemShared/src/node/modLoader.kt @@ -0,0 +1,19 @@ +/* + * Copyright 2010-2024 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE.txt file. + */ + +package kotlinx.io.node + +import kotlinx.io.withCaughtException + +internal fun loadModule(name: String, initializer: () -> T?): T { + var mod: T? = null + val ex = withCaughtException { + mod = initializer() + } + if (mod == null) { + throw UnsupportedOperationException("Module '$name' could not be loaded", ex) + } + return mod!! +} diff --git a/core/nodeFilesystemShared/src/node/os.kt b/core/nodeFilesystemShared/src/node/os.kt index 431d60a8f..d197da091 100644 --- a/core/nodeFilesystemShared/src/node/os.kt +++ b/core/nodeFilesystemShared/src/node/os.kt @@ -18,4 +18,8 @@ internal external interface Os { fun platform(): String } -internal expect val os: Os +internal val os: Os by lazy { + loadModule("os", ::osInitializer) +} + +private fun osInitializer(): Os? = js("eval('require')('os')") diff --git a/core/nodeFilesystemShared/src/node/path.kt b/core/nodeFilesystemShared/src/node/path.kt index 25bc90612..918b7afbf 100644 --- a/core/nodeFilesystemShared/src/node/path.kt +++ b/core/nodeFilesystemShared/src/node/path.kt @@ -14,4 +14,8 @@ internal external interface Path { val sep: String } -internal expect val path: Path +internal val path: Path by lazy { + loadModule("path", ::pathInitializer) +} + +private fun pathInitializer(): Path? = js("eval('require')('path')") diff --git a/core/wasmJs/src/node/nodeModulesWasmJs.kt b/core/wasmJs/src/node/nodeModulesWasmJs.kt deleted file mode 100644 index 9bb913ce3..000000000 --- a/core/wasmJs/src/node/nodeModulesWasmJs.kt +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2010-2024 JetBrains s.r.o. and Kotlin Programming Language contributors. - * Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE.txt file. - */ - -package kotlinx.io.node - - -internal fun requireExists(): Boolean = js("typeof require === 'function'") - -internal fun requireModule(mod: String): JsAny? = js("""{ - try { - let m = require(mod); - if (m) return m; - return null; - } catch (e) { - return null; - } - }""") - -internal fun loadModule(name: String): JsAny { - if (!requireExists()) { - throw UnsupportedOperationException("Module $name could not be loaded") - } - val mod = requireModule(name) ?: throw UnsupportedOperationException("Module '$name' could not be imported") - return mod -} - -internal actual val buffer: BufferModule by lazy { - @Suppress("UNCHECKED_CAST_TO_EXTERNAL_INTERFACE") - loadModule("buffer") as BufferModule -} - -internal actual val os: Os by lazy { - @Suppress("UNCHECKED_CAST_TO_EXTERNAL_INTERFACE") - loadModule("os") as Os -} - -internal actual val path: Path by lazy { - @Suppress("UNCHECKED_CAST_TO_EXTERNAL_INTERFACE") - loadModule("path") as Path -} - -internal actual val fs: Fs by lazy { - @Suppress("UNCHECKED_CAST_TO_EXTERNAL_INTERFACE") - loadModule("fs") as Fs -} From b0a830c102da9358953d1fe96e2cb175f4714c70 Mon Sep 17 00:00:00 2001 From: Filipp Zhinkin Date: Wed, 20 Mar 2024 14:03:05 +0100 Subject: [PATCH 2/2] Fixed metadata compilation failure --- core/js/src/node/initializers.kt | 11 +++++++++++ core/nodeFilesystemShared/src/node/buffer.kt | 4 +--- core/nodeFilesystemShared/src/node/fs.kt | 2 +- core/nodeFilesystemShared/src/node/os.kt | 2 +- core/nodeFilesystemShared/src/node/path.kt | 2 +- core/wasmJs/src/node/initializers.kt | 11 +++++++++++ 6 files changed, 26 insertions(+), 6 deletions(-) create mode 100644 core/js/src/node/initializers.kt create mode 100644 core/wasmJs/src/node/initializers.kt diff --git a/core/js/src/node/initializers.kt b/core/js/src/node/initializers.kt new file mode 100644 index 000000000..40e5ff070 --- /dev/null +++ b/core/js/src/node/initializers.kt @@ -0,0 +1,11 @@ +/* + * Copyright 2010-2024 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE.txt file. + */ + +package kotlinx.io.node + +internal actual fun bufferInitializer(): BufferModule? = js("eval('require')('buffer')") +internal actual fun osInitializer(): Os? = js("eval('require')('os')") +internal actual fun fsInitializer(): Fs? = js("eval('require')('fs')") +internal actual fun pathInitializer(): Path? = js("eval('require')('path')") diff --git a/core/nodeFilesystemShared/src/node/buffer.kt b/core/nodeFilesystemShared/src/node/buffer.kt index a9e9029f5..dc79eaf9f 100644 --- a/core/nodeFilesystemShared/src/node/buffer.kt +++ b/core/nodeFilesystemShared/src/node/buffer.kt @@ -5,8 +5,6 @@ package kotlinx.io.node -import kotlinx.io.withCaughtException - internal external interface BufferModule { val Buffer: BufferObj } @@ -28,4 +26,4 @@ internal val buffer: BufferModule by lazy { loadModule("buffer", ::bufferInitializer) } -private fun bufferInitializer(): BufferModule? = js("eval('require')('buffer')") +internal expect fun bufferInitializer(): BufferModule? diff --git a/core/nodeFilesystemShared/src/node/fs.kt b/core/nodeFilesystemShared/src/node/fs.kt index 8a9718f0b..6ca09c872 100644 --- a/core/nodeFilesystemShared/src/node/fs.kt +++ b/core/nodeFilesystemShared/src/node/fs.kt @@ -90,4 +90,4 @@ internal val fs: Fs by lazy { loadModule("fs", ::fsInitializer) } -private fun fsInitializer(): Fs? = js("eval('require')('fs')") +internal expect fun fsInitializer(): Fs? diff --git a/core/nodeFilesystemShared/src/node/os.kt b/core/nodeFilesystemShared/src/node/os.kt index d197da091..38b60dff4 100644 --- a/core/nodeFilesystemShared/src/node/os.kt +++ b/core/nodeFilesystemShared/src/node/os.kt @@ -22,4 +22,4 @@ internal val os: Os by lazy { loadModule("os", ::osInitializer) } -private fun osInitializer(): Os? = js("eval('require')('os')") +internal expect fun osInitializer(): Os? diff --git a/core/nodeFilesystemShared/src/node/path.kt b/core/nodeFilesystemShared/src/node/path.kt index 918b7afbf..3babaeb66 100644 --- a/core/nodeFilesystemShared/src/node/path.kt +++ b/core/nodeFilesystemShared/src/node/path.kt @@ -18,4 +18,4 @@ internal val path: Path by lazy { loadModule("path", ::pathInitializer) } -private fun pathInitializer(): Path? = js("eval('require')('path')") +internal expect fun pathInitializer(): Path? diff --git a/core/wasmJs/src/node/initializers.kt b/core/wasmJs/src/node/initializers.kt new file mode 100644 index 000000000..40e5ff070 --- /dev/null +++ b/core/wasmJs/src/node/initializers.kt @@ -0,0 +1,11 @@ +/* + * Copyright 2010-2024 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE.txt file. + */ + +package kotlinx.io.node + +internal actual fun bufferInitializer(): BufferModule? = js("eval('require')('buffer')") +internal actual fun osInitializer(): Os? = js("eval('require')('os')") +internal actual fun fsInitializer(): Fs? = js("eval('require')('fs')") +internal actual fun pathInitializer(): Path? = js("eval('require')('path')")