Skip to content

Commit 95f022f

Browse files
authored
Make nodejs module loading lazy again (#283)
Fixes: #265
1 parent a2047af commit 95f022f

File tree

12 files changed

+214
-168
lines changed

12 files changed

+214
-168
lines changed

core/js/src/-PlatformJs.kt

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,6 @@ public actual open class EOFException : IOException {
2525
public actual constructor(message: String?) : super(message)
2626
}
2727

28-
@Suppress("ACTUAL_WITHOUT_EXPECT")
29-
internal actual typealias CommonJsModule = JsModule
30-
31-
@Suppress("ACTUAL_WITHOUT_EXPECT")
32-
internal actual typealias CommonJsNonModule = JsNonModule
33-
3428
internal actual fun withCaughtException(block: () -> Unit): Throwable? {
3529
try {
3630
block()

core/js/src/node/nodeModulesJs.kt

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*
2+
* Copyright 2010-2024 JetBrains s.r.o. and Kotlin Programming Language contributors.
3+
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE.txt file.
4+
*/
5+
6+
package kotlinx.io.node
7+
8+
internal actual val path: Path by lazy {
9+
try {
10+
js("require(\"path\")")
11+
} catch (e: Throwable) {
12+
throw UnsupportedOperationException("Module 'path' could not be imported", e)
13+
}
14+
}
15+
16+
internal actual val fs: Fs by lazy {
17+
try {
18+
js("require(\"fs\")")
19+
} catch (e: Throwable) {
20+
throw UnsupportedOperationException("Module 'fs' could not be imported", e)
21+
}
22+
}
23+
24+
internal actual val os: Os by lazy {
25+
try {
26+
js("require(\"os\")")
27+
} catch (e: Throwable) {
28+
throw UnsupportedOperationException("Module 'os' could not be imported", e)
29+
}
30+
}
31+
32+
internal actual val buffer: BufferModule by lazy {
33+
try {
34+
js("require(\"buffer\")")
35+
} catch (e: Throwable) {
36+
throw UnsupportedOperationException("Module 'buffer' could not be imported", e)
37+
}
38+
}
39+

core/nodeFilesystemShared/src/annotations.kt

Lines changed: 0 additions & 22 deletions
This file was deleted.

core/nodeFilesystemShared/src/files/FileSystemNodeJs.kt

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,13 @@ package kotlinx.io.files
88
import kotlinx.io.IOException
99
import kotlinx.io.RawSink
1010
import kotlinx.io.RawSource
11-
import kotlinx.io.node.fs.*
12-
import kotlinx.io.node.os.platform
13-
import kotlinx.io.node.os.tmpdir
11+
import kotlinx.io.node.fs
12+
import kotlinx.io.node.os
1413
import kotlinx.io.withCaughtException
1514

1615
public actual val SystemFileSystem: FileSystem = object : SystemFileSystemImpl() {
1716
override fun exists(path: Path): Boolean {
18-
return existsSync(path.path)
17+
return fs.existsSync(path.path)
1918
}
2019

2120
override fun delete(path: Path, mustExist: Boolean) {
@@ -26,11 +25,11 @@ public actual val SystemFileSystem: FileSystem = object : SystemFileSystemImpl()
2625
return
2726
}
2827
withCaughtException {
29-
val stats = statSync(path.path) ?: throw FileNotFoundException("File does not exist: $path")
28+
val stats = fs.statSync(path.path) ?: throw FileNotFoundException("File does not exist: $path")
3029
if (stats.isDirectory()) {
31-
rmdirSync(path.path)
30+
fs.rmdirSync(path.path)
3231
} else {
33-
rmSync(path.path)
32+
fs.rmSync(path.path)
3433
}
3534
}?.also {
3635
throw IOException("Delete failed for $path", it)
@@ -56,7 +55,7 @@ public actual val SystemFileSystem: FileSystem = object : SystemFileSystemImpl()
5655
p = p.parent
5756
}
5857
parts.asReversed().forEach {
59-
mkdirSync(it)
58+
fs.mkdirSync(it)
6059
}
6160
}
6261

@@ -65,7 +64,7 @@ public actual val SystemFileSystem: FileSystem = object : SystemFileSystemImpl()
6564
throw FileNotFoundException("Source does not exist: ${source.path}")
6665
}
6766
withCaughtException {
68-
renameSync(source.path, destination.path)
67+
fs.renameSync(source.path, destination.path)
6968
}?.also {
7069
throw IOException("Move failed from $source to $destination", it)
7170
}
@@ -75,12 +74,12 @@ public actual val SystemFileSystem: FileSystem = object : SystemFileSystemImpl()
7574
if (!exists(path)) return null
7675
var metadata: FileMetadata? = null
7776
withCaughtException {
78-
val stat = statSync(path.path) ?: return@withCaughtException
77+
val stat = fs.statSync(path.path) ?: return@withCaughtException
7978
val mode = stat.mode
80-
val isFile = (mode and constants.S_IFMT) == constants.S_IFREG
79+
val isFile = (mode and fs.constants.S_IFMT) == fs.constants.S_IFREG
8180
metadata = FileMetadata(
8281
isRegularFile = isFile,
83-
isDirectory = (mode and constants.S_IFMT) == constants.S_IFDIR,
82+
isDirectory = (mode and fs.constants.S_IFMT) == fs.constants.S_IFDIR,
8483
if (isFile) stat.size.toLong() else -1L
8584
)
8685
}?.also {
@@ -99,17 +98,17 @@ public actual val SystemFileSystem: FileSystem = object : SystemFileSystemImpl()
9998

10099
override fun resolve(path: Path): Path {
101100
if (!exists(path)) throw FileNotFoundException(path.path)
102-
return Path(realpathSync.native(path.path))
101+
return Path(fs.realpathSync.native(path.path))
103102
}
104103
}
105104

106105
public actual val SystemTemporaryDirectory: Path
107106
get() {
108-
return Path(tmpdir() ?: "")
107+
return Path(os.tmpdir() ?: "")
109108
}
110109

111110
public actual open class FileNotFoundException actual constructor(
112111
message: String?,
113112
) : IOException(message)
114113

115-
internal actual val isWindows = platform() == "win32"
114+
internal actual val isWindows = os.platform() == "win32"

core/nodeFilesystemShared/src/files/PathsNodeJs.kt

Lines changed: 16 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,9 @@
66
package kotlinx.io.files
77

88
import kotlinx.io.*
9-
import kotlinx.io.node.fs.*
10-
import kotlinx.io.node.path.basename
11-
import kotlinx.io.node.path.dirname
12-
import kotlinx.io.node.path.isAbsolute
13-
import kotlinx.io.node.path.sep
9+
import kotlinx.io.node.buffer
10+
import kotlinx.io.node.fs
11+
import kotlinx.io.node.path as nodeJsPath
1412

1513
public actual class Path internal constructor(
1614
rawPath: String,
@@ -28,7 +26,7 @@ public actual class Path internal constructor(
2826
} else if (!path.contains(SystemPathSeparator)) {
2927
return null
3028
}
31-
val p = dirname(path)
29+
val p = nodeJsPath.dirname(path)
3230
return when {
3331
p.isEmpty() -> null
3432
p == path -> null
@@ -38,15 +36,15 @@ public actual class Path internal constructor(
3836

3937
public actual val isAbsolute: Boolean
4038
get() {
41-
return isAbsolute(path)
39+
return nodeJsPath.isAbsolute(path)
4240
}
4341

4442
public actual val name: String
4543
get() {
4644
when {
4745
path.isEmpty() -> return ""
4846
}
49-
val p = basename(path)
47+
val p = nodeJsPath.basename(path)
5048
return when {
5149
p.isEmpty() -> ""
5250
else -> p
@@ -68,7 +66,7 @@ public actual class Path internal constructor(
6866
}
6967

7068
public actual val SystemPathSeparator: Char by lazy {
71-
val sep = sep
69+
val sep = nodeJsPath.sep
7270
check(sep.length == 1)
7371
sep[0]
7472
}
@@ -78,18 +76,18 @@ public actual fun Path(path: String): Path {
7876
}
7977

8078
internal class FileSource(private val path: Path) : RawSource {
81-
private var buffer: kotlinx.io.node.buffer.Buffer? = null
79+
private var buffer: kotlinx.io.node.Buffer? = null
8280
private var closed = false
8381
private var offset = 0
8482
private val fd = open(path)
8583

8684
private fun open(path: Path): Int {
87-
if (!existsSync(path.path)) {
85+
if (!fs.existsSync(path.path)) {
8886
throw FileNotFoundException("File does not exist: ${path.path}")
8987
}
9088
var fd: Int = -1
9189
withCaughtException {
92-
fd = openSync(path.path, "r")
90+
fd = fs.openSync(path.path, "r")
9391
}?.also {
9492
throw IOException("Failed to open a file ${path.path}.", it)
9593
}
@@ -104,7 +102,7 @@ internal class FileSource(private val path: Path) : RawSource {
104102
}
105103
if (buffer === null) {
106104
withCaughtException {
107-
buffer = readFileSync(fd, null)
105+
buffer = fs.readFileSync(fd, null)
108106
}?.also {
109107
throw IOException("Failed to read data from ${path.path}", it)
110108
}
@@ -124,7 +122,7 @@ internal class FileSource(private val path: Path) : RawSource {
124122
override fun close() {
125123
if (!closed) {
126124
closed = true
127-
closeSync(fd)
125+
fs.closeSync(fd)
128126
}
129127
}
130128
}
@@ -137,7 +135,7 @@ internal class FileSink(path: Path, append: Boolean) : RawSink {
137135
val flags = if (append) "a" else "w"
138136
var fd = -1
139137
withCaughtException {
140-
fd = openSync(path.path, flags)
138+
fd = fs.openSync(path.path, flags)
141139
}?.also {
142140
throw IOException("Failed to open a file ${path.path}.", it)
143141
}
@@ -155,15 +153,14 @@ internal class FileSink(path: Path, append: Boolean) : RawSink {
155153
while (remainingBytes > 0) {
156154
val head = source.head!!
157155
val segmentBytes = head.limit - head.pos
158-
159-
val buf = kotlinx.io.node.buffer.Buffer.allocUnsafe(segmentBytes)
156+
val buf = buffer.Buffer.allocUnsafe(segmentBytes)
160157
val data = head.data
161158
val pos = head.pos
162159
for (offset in 0 until segmentBytes) {
163160
buf.writeInt8(data[pos + offset], offset)
164161
}
165162
withCaughtException {
166-
writeFileSync(fd, buf)
163+
fs.writeFileSync(fd, buf)
167164
}?.also {
168165
throw IOException("Write failed", it)
169166
}
@@ -177,7 +174,7 @@ internal class FileSink(path: Path, append: Boolean) : RawSink {
177174
override fun close() {
178175
if (!closed) {
179176
closed = true
180-
closeSync(fd)
177+
fs.closeSync(fd)
181178
}
182179
}
183180
}

core/nodeFilesystemShared/src/node/buffer.kt

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,23 @@
33
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE.txt file.
44
*/
55

6-
@file:CommonJsModule("buffer")
7-
@file:CommonJsNonModule
6+
package kotlinx.io.node
87

9-
package kotlinx.io.node.buffer
8+
internal external interface BufferModule {
9+
val Buffer: BufferObj
10+
}
1011

11-
import kotlinx.io.CommonJsModule
12-
import kotlinx.io.CommonJsNonModule
12+
internal external object BufferObj {
13+
fun allocUnsafe(bytes: Int): Buffer
14+
}
1315

1416
/**
1517
* Partial declaration of a class mirroring [node:buffer.Buffer](https://nodejs.org/api/buffer.html#buffer).
1618
*/
17-
internal open external class Buffer {
19+
internal external interface Buffer {
1820
val length: Int
1921
fun readInt8(offset: Int): Byte
2022
fun writeInt8(value: Byte, offset: Int)
21-
22-
companion object {
23-
fun allocUnsafe(bytes: Int): Buffer
24-
}
2523
}
24+
25+
internal expect val buffer: BufferModule

0 commit comments

Comments
 (0)