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/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..dc79eaf9f 100644 --- a/core/nodeFilesystemShared/src/node/buffer.kt +++ b/core/nodeFilesystemShared/src/node/buffer.kt @@ -22,4 +22,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) +} + +internal expect fun bufferInitializer(): BufferModule? diff --git a/core/nodeFilesystemShared/src/node/fs.kt b/core/nodeFilesystemShared/src/node/fs.kt index 84c9ba989..6ca09c872 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) +} + +internal expect fun fsInitializer(): 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..38b60dff4 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) +} + +internal expect fun osInitializer(): Os? diff --git a/core/nodeFilesystemShared/src/node/path.kt b/core/nodeFilesystemShared/src/node/path.kt index 25bc90612..3babaeb66 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) +} + +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')") 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 -}