@gjsify/fs 0.3.13 → 0.3.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/esm/_virtual/_rolldown/runtime.js +18 -0
- package/lib/esm/callback.js +301 -302
- package/lib/esm/cp.js +207 -227
- package/lib/esm/dir.js +140 -148
- package/lib/esm/dirent.js +137 -128
- package/lib/esm/encoding.js +30 -27
- package/lib/esm/errors.js +15 -11
- package/lib/esm/fd-ops.js +105 -122
- package/lib/esm/file-handle.js +648 -653
- package/lib/esm/fs-watcher.js +153 -161
- package/lib/esm/glob.js +148 -149
- package/lib/esm/index.js +158 -351
- package/lib/esm/promises.js +413 -386
- package/lib/esm/read-stream.js +104 -108
- package/lib/esm/stat-watcher.js +113 -114
- package/lib/esm/statfs.js +56 -43
- package/lib/esm/stats.js +166 -159
- package/lib/esm/sync.js +366 -341
- package/lib/esm/types/index.js +6 -6
- package/lib/esm/utils.js +15 -17
- package/lib/esm/utimes.js +26 -37
- package/lib/esm/write-stream.js +96 -108
- package/package.json +10 -10
package/lib/esm/read-stream.js
CHANGED
|
@@ -1,113 +1,109 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { normalizePath } from "./utils.js";
|
|
2
2
|
import GLib from "@girs/glib-2.0";
|
|
3
|
+
import Gio from "@girs/gio-2.0";
|
|
3
4
|
import { Buffer } from "node:buffer";
|
|
4
5
|
import { Readable } from "node:stream";
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
}
|
|
104
|
-
callback(error);
|
|
105
|
-
}
|
|
106
|
-
}
|
|
6
|
+
|
|
7
|
+
//#region src/read-stream.ts
|
|
8
|
+
var ReadStream = class extends Readable {
|
|
9
|
+
bytesRead = 0;
|
|
10
|
+
path;
|
|
11
|
+
pending = true;
|
|
12
|
+
fd = null;
|
|
13
|
+
_gioFile;
|
|
14
|
+
_inputStream = null;
|
|
15
|
+
_cancellable = new Gio.Cancellable();
|
|
16
|
+
_start;
|
|
17
|
+
_end;
|
|
18
|
+
_pos;
|
|
19
|
+
close(callback) {
|
|
20
|
+
this._cancellable.cancel();
|
|
21
|
+
if (this._inputStream) {
|
|
22
|
+
this._inputStream.close_async(GLib.PRIORITY_DEFAULT, null, () => {});
|
|
23
|
+
this._inputStream = null;
|
|
24
|
+
}
|
|
25
|
+
this.destroy();
|
|
26
|
+
if (callback) callback(null);
|
|
27
|
+
}
|
|
28
|
+
constructor(path, opts) {
|
|
29
|
+
const pathStr = normalizePath(path);
|
|
30
|
+
super({
|
|
31
|
+
highWaterMark: opts?.highWaterMark ?? 64 * 1024,
|
|
32
|
+
encoding: opts?.encoding,
|
|
33
|
+
objectMode: false
|
|
34
|
+
});
|
|
35
|
+
this.path = pathStr;
|
|
36
|
+
this._gioFile = Gio.File.new_for_path(pathStr);
|
|
37
|
+
this._start = opts?.start ?? 0;
|
|
38
|
+
this._end = opts?.end ?? Infinity;
|
|
39
|
+
this._pos = this._start;
|
|
40
|
+
}
|
|
41
|
+
_construct(callback) {
|
|
42
|
+
this._gioFile.read_async(GLib.PRIORITY_DEFAULT, this._cancellable, (_source, asyncResult) => {
|
|
43
|
+
if (this.destroyed) {
|
|
44
|
+
callback();
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
try {
|
|
48
|
+
this._inputStream = this._gioFile.read_finish(asyncResult);
|
|
49
|
+
this.pending = false;
|
|
50
|
+
this.emit("open", 0);
|
|
51
|
+
this.emit("ready");
|
|
52
|
+
if (this._start > 0 && this._inputStream.can_seek()) {
|
|
53
|
+
this._inputStream.seek(this._start, GLib.SeekType.SET, null);
|
|
54
|
+
}
|
|
55
|
+
callback();
|
|
56
|
+
} catch (err) {
|
|
57
|
+
if (!this._cancellable.is_cancelled()) {
|
|
58
|
+
callback(err);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
_read(size) {
|
|
64
|
+
this._doRead(size);
|
|
65
|
+
}
|
|
66
|
+
_doRead(size) {
|
|
67
|
+
let toRead = size;
|
|
68
|
+
if (this._end !== Infinity) {
|
|
69
|
+
const remaining = this._end - this._pos + 1;
|
|
70
|
+
if (remaining <= 0) {
|
|
71
|
+
this.push(null);
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
toRead = Math.min(size, remaining);
|
|
75
|
+
}
|
|
76
|
+
const stream = this._inputStream;
|
|
77
|
+
stream.read_bytes_async(toRead, GLib.PRIORITY_DEFAULT, this._cancellable, (_source, asyncResult) => {
|
|
78
|
+
try {
|
|
79
|
+
const gbytes = stream.read_bytes_finish(asyncResult);
|
|
80
|
+
const data = gbytes.get_data();
|
|
81
|
+
if (!data || data.length === 0) {
|
|
82
|
+
this.push(null);
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
this.bytesRead += data.length;
|
|
86
|
+
this._pos += data.length;
|
|
87
|
+
this.push(Buffer.from(data));
|
|
88
|
+
} catch (err) {
|
|
89
|
+
if (!this._cancellable.is_cancelled()) {
|
|
90
|
+
this.destroy(err);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
_destroy(error, callback) {
|
|
96
|
+
this._cancellable.cancel();
|
|
97
|
+
if (this._inputStream) {
|
|
98
|
+
this._inputStream.close_async(GLib.PRIORITY_DEFAULT, null, () => {});
|
|
99
|
+
this._inputStream = null;
|
|
100
|
+
}
|
|
101
|
+
callback(error);
|
|
102
|
+
}
|
|
103
|
+
};
|
|
107
104
|
function createReadStream(path, options) {
|
|
108
|
-
|
|
105
|
+
return new ReadStream(path, options);
|
|
109
106
|
}
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
};
|
|
107
|
+
|
|
108
|
+
//#endregion
|
|
109
|
+
export { ReadStream, createReadStream };
|
package/lib/esm/stat-watcher.js
CHANGED
|
@@ -1,121 +1,120 @@
|
|
|
1
|
-
import { EventEmitter } from "node:events";
|
|
2
1
|
import { statSync } from "./sync.js";
|
|
2
|
+
import { EventEmitter } from "node:events";
|
|
3
|
+
|
|
4
|
+
//#region src/stat-watcher.ts
|
|
3
5
|
function zeroedStat() {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
}
|
|
32
|
-
class StatWatcher extends EventEmitter {
|
|
33
|
-
_path;
|
|
34
|
-
_interval;
|
|
35
|
-
_timerId = null;
|
|
36
|
-
_prev;
|
|
37
|
-
_changeCount = 0;
|
|
38
|
-
constructor(path, interval) {
|
|
39
|
-
super();
|
|
40
|
-
this._path = path;
|
|
41
|
-
this._interval = interval;
|
|
42
|
-
this._prev = zeroedStat();
|
|
43
|
-
}
|
|
44
|
-
start() {
|
|
45
|
-
try {
|
|
46
|
-
this._prev = statSync(this._path);
|
|
47
|
-
} catch {
|
|
48
|
-
}
|
|
49
|
-
this._timerId = setInterval(() => {
|
|
50
|
-
let curr;
|
|
51
|
-
try {
|
|
52
|
-
curr = statSync(this._path);
|
|
53
|
-
} catch {
|
|
54
|
-
curr = zeroedStat();
|
|
55
|
-
}
|
|
56
|
-
const prev = this._prev;
|
|
57
|
-
if (curr.mtimeMs !== prev.mtimeMs || curr.size !== prev.size || curr.ino !== prev.ino) {
|
|
58
|
-
this._prev = curr;
|
|
59
|
-
this.emit("change", curr, prev);
|
|
60
|
-
}
|
|
61
|
-
}, this._interval);
|
|
62
|
-
}
|
|
63
|
-
stop() {
|
|
64
|
-
if (this._timerId !== null) {
|
|
65
|
-
clearInterval(this._timerId);
|
|
66
|
-
this._timerId = null;
|
|
67
|
-
}
|
|
68
|
-
this.emit("stop");
|
|
69
|
-
}
|
|
70
|
-
addChangeListener(listener) {
|
|
71
|
-
this._changeCount++;
|
|
72
|
-
this.on("change", listener);
|
|
73
|
-
}
|
|
74
|
-
removeChangeListener(listener) {
|
|
75
|
-
this._changeCount--;
|
|
76
|
-
this.removeListener("change", listener);
|
|
77
|
-
}
|
|
78
|
-
removeAllChangeListeners() {
|
|
79
|
-
this._changeCount = 0;
|
|
80
|
-
this.removeAllListeners("change");
|
|
81
|
-
}
|
|
82
|
-
get changeListenerCount() {
|
|
83
|
-
return this._changeCount;
|
|
84
|
-
}
|
|
6
|
+
return {
|
|
7
|
+
dev: 0,
|
|
8
|
+
ino: 0,
|
|
9
|
+
mode: 0,
|
|
10
|
+
nlink: 0,
|
|
11
|
+
uid: 0,
|
|
12
|
+
gid: 0,
|
|
13
|
+
rdev: 0,
|
|
14
|
+
size: 0,
|
|
15
|
+
blksize: 0,
|
|
16
|
+
blocks: 0,
|
|
17
|
+
atimeMs: 0,
|
|
18
|
+
mtimeMs: 0,
|
|
19
|
+
ctimeMs: 0,
|
|
20
|
+
birthtimeMs: 0,
|
|
21
|
+
atime: new Date(0),
|
|
22
|
+
mtime: new Date(0),
|
|
23
|
+
ctime: new Date(0),
|
|
24
|
+
birthtime: new Date(0),
|
|
25
|
+
isFile: () => false,
|
|
26
|
+
isDirectory: () => false,
|
|
27
|
+
isBlockDevice: () => false,
|
|
28
|
+
isCharacterDevice: () => false,
|
|
29
|
+
isSymbolicLink: () => false,
|
|
30
|
+
isFIFO: () => false,
|
|
31
|
+
isSocket: () => false
|
|
32
|
+
};
|
|
85
33
|
}
|
|
86
|
-
|
|
34
|
+
var StatWatcher = class extends EventEmitter {
|
|
35
|
+
_path;
|
|
36
|
+
_interval;
|
|
37
|
+
_timerId = null;
|
|
38
|
+
_prev;
|
|
39
|
+
_changeCount = 0;
|
|
40
|
+
constructor(path, interval) {
|
|
41
|
+
super();
|
|
42
|
+
this._path = path;
|
|
43
|
+
this._interval = interval;
|
|
44
|
+
this._prev = zeroedStat();
|
|
45
|
+
}
|
|
46
|
+
start() {
|
|
47
|
+
try {
|
|
48
|
+
this._prev = statSync(this._path);
|
|
49
|
+
} catch {}
|
|
50
|
+
this._timerId = setInterval(() => {
|
|
51
|
+
let curr;
|
|
52
|
+
try {
|
|
53
|
+
curr = statSync(this._path);
|
|
54
|
+
} catch {
|
|
55
|
+
curr = zeroedStat();
|
|
56
|
+
}
|
|
57
|
+
const prev = this._prev;
|
|
58
|
+
if (curr.mtimeMs !== prev.mtimeMs || curr.size !== prev.size || curr.ino !== prev.ino) {
|
|
59
|
+
this._prev = curr;
|
|
60
|
+
this.emit("change", curr, prev);
|
|
61
|
+
}
|
|
62
|
+
}, this._interval);
|
|
63
|
+
}
|
|
64
|
+
stop() {
|
|
65
|
+
if (this._timerId !== null) {
|
|
66
|
+
clearInterval(this._timerId);
|
|
67
|
+
this._timerId = null;
|
|
68
|
+
}
|
|
69
|
+
this.emit("stop");
|
|
70
|
+
}
|
|
71
|
+
addChangeListener(listener) {
|
|
72
|
+
this._changeCount++;
|
|
73
|
+
this.on("change", listener);
|
|
74
|
+
}
|
|
75
|
+
removeChangeListener(listener) {
|
|
76
|
+
this._changeCount--;
|
|
77
|
+
this.removeListener("change", listener);
|
|
78
|
+
}
|
|
79
|
+
removeAllChangeListeners() {
|
|
80
|
+
this._changeCount = 0;
|
|
81
|
+
this.removeAllListeners("change");
|
|
82
|
+
}
|
|
83
|
+
get changeListenerCount() {
|
|
84
|
+
return this._changeCount;
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
const statWatchers = new Map();
|
|
87
88
|
function watchFile(filename, options, listener) {
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
89
|
+
if (typeof options === "function") {
|
|
90
|
+
listener = options;
|
|
91
|
+
options = {};
|
|
92
|
+
}
|
|
93
|
+
const interval = options.interval ?? 5007;
|
|
94
|
+
const resolved = filename.toString();
|
|
95
|
+
let watcher = statWatchers.get(resolved);
|
|
96
|
+
if (!watcher) {
|
|
97
|
+
watcher = new StatWatcher(resolved, interval);
|
|
98
|
+
watcher.start();
|
|
99
|
+
statWatchers.set(resolved, watcher);
|
|
100
|
+
}
|
|
101
|
+
if (listener) watcher.addChangeListener(listener);
|
|
102
|
+
return watcher;
|
|
102
103
|
}
|
|
103
104
|
function unwatchFile(filename, listener) {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
105
|
+
const resolved = filename.toString();
|
|
106
|
+
const watcher = statWatchers.get(resolved);
|
|
107
|
+
if (!watcher) return;
|
|
108
|
+
if (listener) {
|
|
109
|
+
watcher.removeChangeListener(listener);
|
|
110
|
+
} else {
|
|
111
|
+
watcher.removeAllChangeListeners();
|
|
112
|
+
}
|
|
113
|
+
if (watcher.changeListenerCount === 0) {
|
|
114
|
+
watcher.stop();
|
|
115
|
+
statWatchers.delete(resolved);
|
|
116
|
+
}
|
|
116
117
|
}
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
watchFile
|
|
121
|
-
};
|
|
118
|
+
|
|
119
|
+
//#endregion
|
|
120
|
+
export { StatWatcher, unwatchFile, watchFile };
|
package/lib/esm/statfs.js
CHANGED
|
@@ -1,57 +1,70 @@
|
|
|
1
|
-
import Gio from "@girs/gio-2.0";
|
|
2
|
-
import GLib from "@girs/glib-2.0";
|
|
3
1
|
import { normalizePath } from "./utils.js";
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
2
|
+
import GLib from "@girs/glib-2.0";
|
|
3
|
+
import Gio from "@girs/gio-2.0";
|
|
4
|
+
|
|
5
|
+
//#region src/statfs.ts
|
|
6
|
+
const FS_INFO_ATTRS = ["filesystem::size", "filesystem::free"].join(",");
|
|
8
7
|
const BSIZE = 4096;
|
|
9
8
|
function buildStatFs(info) {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
9
|
+
const totalBytes = Number(info.get_attribute_uint64("filesystem::size") ?? 0);
|
|
10
|
+
const freeBytes = Number(info.get_attribute_uint64("filesystem::free") ?? 0);
|
|
11
|
+
const blocks = Math.floor(totalBytes / BSIZE);
|
|
12
|
+
const bfree = Math.floor(freeBytes / BSIZE);
|
|
13
|
+
return {
|
|
14
|
+
type: 0,
|
|
15
|
+
bsize: BSIZE,
|
|
16
|
+
blocks,
|
|
17
|
+
bfree,
|
|
18
|
+
bavail: bfree,
|
|
19
|
+
files: 0,
|
|
20
|
+
ffree: 0
|
|
21
|
+
};
|
|
15
22
|
}
|
|
16
23
|
function buildBigIntStatFs(info) {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
24
|
+
const totalBytes = BigInt(info.get_attribute_uint64("filesystem::size") ?? 0);
|
|
25
|
+
const freeBytes = BigInt(info.get_attribute_uint64("filesystem::free") ?? 0);
|
|
26
|
+
const bsize = BigInt(BSIZE);
|
|
27
|
+
const blocks = totalBytes / bsize;
|
|
28
|
+
const bfree = freeBytes / bsize;
|
|
29
|
+
return {
|
|
30
|
+
type: 0n,
|
|
31
|
+
bsize,
|
|
32
|
+
blocks,
|
|
33
|
+
bfree,
|
|
34
|
+
bavail: bfree,
|
|
35
|
+
files: 0n,
|
|
36
|
+
ffree: 0n
|
|
37
|
+
};
|
|
23
38
|
}
|
|
24
39
|
function statfsSync(path, options) {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
40
|
+
const file = Gio.File.new_for_path(normalizePath(path));
|
|
41
|
+
const info = file.query_filesystem_info(FS_INFO_ATTRS, null);
|
|
42
|
+
return options?.bigint === true ? buildBigIntStatFs(info) : buildStatFs(info);
|
|
28
43
|
}
|
|
29
44
|
function queryFsInfoAsync(path, useBigInt) {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
45
|
+
return new Promise((resolve, reject) => {
|
|
46
|
+
const file = Gio.File.new_for_path(normalizePath(path));
|
|
47
|
+
file.query_filesystem_info_async(FS_INFO_ATTRS, GLib.PRIORITY_DEFAULT, null, (_s, res) => {
|
|
48
|
+
try {
|
|
49
|
+
const info = file.query_filesystem_info_finish(res);
|
|
50
|
+
resolve(useBigInt ? buildBigIntStatFs(info) : buildStatFs(info));
|
|
51
|
+
} catch (err) {
|
|
52
|
+
reject(err);
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
});
|
|
41
56
|
}
|
|
42
57
|
function statfs(path, optionsOrCb, callback) {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
58
|
+
if (typeof optionsOrCb === "function") {
|
|
59
|
+
callback = optionsOrCb;
|
|
60
|
+
optionsOrCb = {};
|
|
61
|
+
}
|
|
62
|
+
const useBigInt = optionsOrCb?.bigint === true;
|
|
63
|
+
queryFsInfoAsync(path, useBigInt).then((result) => callback(null, result), (err) => callback(err, null));
|
|
49
64
|
}
|
|
50
65
|
async function statfsAsync(path, options) {
|
|
51
|
-
|
|
66
|
+
return queryFsInfoAsync(path, options?.bigint === true);
|
|
52
67
|
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
statfsSync
|
|
57
|
-
};
|
|
68
|
+
|
|
69
|
+
//#endregion
|
|
70
|
+
export { statfs, statfsAsync, statfsSync };
|