@gjsify/fs 0.1.13 → 0.2.0

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.
Files changed (67) hide show
  1. package/lib/esm/callback.js +22 -13
  2. package/lib/esm/cp.js +253 -0
  3. package/lib/esm/dir.js +160 -0
  4. package/lib/esm/fd-ops.js +189 -0
  5. package/lib/esm/file-handle.js +263 -84
  6. package/lib/esm/fs-watcher.js +88 -4
  7. package/lib/esm/glob.js +164 -0
  8. package/lib/esm/index.js +128 -2
  9. package/lib/esm/promises.js +90 -27
  10. package/lib/esm/read-stream.js +53 -43
  11. package/lib/esm/stat-watcher.js +121 -0
  12. package/lib/esm/statfs.js +57 -0
  13. package/lib/esm/sync.js +70 -52
  14. package/lib/esm/utils.js +7 -0
  15. package/lib/esm/utimes.js +62 -0
  16. package/lib/esm/write-stream.js +2 -5
  17. package/lib/types/cp.d.ts +18 -0
  18. package/lib/types/cp.spec.d.ts +2 -0
  19. package/lib/types/dir.d.ts +29 -0
  20. package/lib/types/dir.spec.d.ts +2 -0
  21. package/lib/types/fd-ops.d.ts +57 -0
  22. package/lib/types/fd-ops.spec.d.ts +2 -0
  23. package/lib/types/file-handle.d.ts +34 -4
  24. package/lib/types/fs-watcher.d.ts +9 -2
  25. package/lib/types/glob.d.ts +8 -0
  26. package/lib/types/glob.spec.d.ts +2 -0
  27. package/lib/types/index.d.ts +51 -1
  28. package/lib/types/promises.d.ts +31 -4
  29. package/lib/types/read-stream.d.ts +3 -1
  30. package/lib/types/stat-watcher.d.ts +21 -0
  31. package/lib/types/statfs.d.ts +35 -0
  32. package/lib/types/statfs.spec.d.ts +2 -0
  33. package/lib/types/sync.d.ts +4 -7
  34. package/lib/types/utils.d.ts +2 -0
  35. package/lib/types/utimes.d.ts +13 -0
  36. package/lib/types/utimes.spec.d.ts +2 -0
  37. package/lib/types/watch.spec.d.ts +2 -0
  38. package/lib/types/watchfile.spec.d.ts +2 -0
  39. package/lib/types/write-stream.d.ts +1 -2
  40. package/package.json +12 -12
  41. package/src/callback.ts +22 -13
  42. package/src/cp.spec.ts +181 -0
  43. package/src/cp.ts +328 -0
  44. package/src/dir.spec.ts +204 -0
  45. package/src/dir.ts +199 -0
  46. package/src/fd-ops.spec.ts +234 -0
  47. package/src/fd-ops.ts +251 -0
  48. package/src/file-handle.ts +264 -94
  49. package/src/fs-watcher.ts +101 -6
  50. package/src/glob.spec.ts +201 -0
  51. package/src/glob.ts +205 -0
  52. package/src/index.ts +74 -0
  53. package/src/promises.ts +94 -29
  54. package/src/read-stream.ts +49 -43
  55. package/src/stat-watcher.ts +116 -0
  56. package/src/statfs.spec.ts +67 -0
  57. package/src/statfs.ts +92 -0
  58. package/src/streams.spec.ts +58 -0
  59. package/src/sync.ts +75 -57
  60. package/src/test.mts +13 -2
  61. package/src/utils.ts +10 -0
  62. package/src/utimes.spec.ts +113 -0
  63. package/src/utimes.ts +97 -0
  64. package/src/watch.spec.ts +171 -0
  65. package/src/watchfile.spec.ts +185 -0
  66. package/src/write-stream.ts +5 -8
  67. package/tsconfig.tsbuildinfo +1 -1
package/src/fd-ops.ts ADDED
@@ -0,0 +1,251 @@
1
+ // Reference: Node.js lib/fs.js (fd-based ops, readSync, writeSync, readv, writev, exists, openAsBlob)
2
+ // Reimplemented for GJS using FileHandle + Gio streams
3
+
4
+ import GLib from '@girs/glib-2.0';
5
+ import Gio from '@girs/gio-2.0';
6
+ import { FileHandle } from './file-handle.js';
7
+ import { Stats, BigIntStats } from './stats.js';
8
+ import { statSync, truncateSync, chmodSync, chownSync, readFileSync } from './sync.js';
9
+ import { utimesSync } from './utimes.js';
10
+ import { normalizePath } from './utils.js';
11
+
12
+ import type { PathLike, TimeLike, StatOptions } from 'node:fs';
13
+
14
+ function getFH(fd: number | FileHandle): FileHandle {
15
+ if (fd instanceof FileHandle) return FileHandle.getInstance(fd.fd);
16
+ return FileHandle.getInstance(fd as number);
17
+ }
18
+
19
+ // ─── fstat ────────────────────────────────────────────────────────────────────
20
+
21
+ export function fstatSync(fd: number, options?: { bigint?: false }): Stats;
22
+ export function fstatSync(fd: number, options: { bigint: true }): BigIntStats;
23
+ export function fstatSync(fd: number, options?: { bigint?: boolean }): Stats | BigIntStats {
24
+ return statSync(normalizePath(getFH(fd).options.path), options as any);
25
+ }
26
+
27
+ export function fstat(fd: number, callback: (err: NodeJS.ErrnoException | null, stats: Stats) => void): void;
28
+ export function fstat(fd: number, options: StatOptions, callback: (err: NodeJS.ErrnoException | null, stats: Stats | BigIntStats) => void): void;
29
+ export function fstat(fd: number, optionsOrCb: any, callback?: any): void {
30
+ if (typeof optionsOrCb === 'function') { callback = optionsOrCb; optionsOrCb = {}; }
31
+ Promise.resolve()
32
+ .then(() => fstatSync(fd, optionsOrCb))
33
+ .then(s => callback(null, s), callback);
34
+ }
35
+
36
+ export async function fstatAsync(fd: number, options?: StatOptions): Promise<Stats | BigIntStats> {
37
+ return fstatSync(fd, options as any);
38
+ }
39
+
40
+ // ─── ftruncate ────────────────────────────────────────────────────────────────
41
+
42
+ export function ftruncateSync(fd: number, len = 0): void {
43
+ truncateSync(normalizePath(getFH(fd).options.path), len);
44
+ }
45
+
46
+ export function ftruncate(fd: number, callback: (err: NodeJS.ErrnoException | null) => void): void;
47
+ export function ftruncate(fd: number, len: number, callback: (err: NodeJS.ErrnoException | null) => void): void;
48
+ export function ftruncate(fd: number, lenOrCb: any, callback?: any): void {
49
+ if (typeof lenOrCb === 'function') { callback = lenOrCb; lenOrCb = 0; }
50
+ Promise.resolve()
51
+ .then(() => ftruncateSync(fd, lenOrCb))
52
+ .then(() => callback(null), callback);
53
+ }
54
+
55
+ export async function ftruncateAsync(fd: number, len = 0): Promise<void> {
56
+ ftruncateSync(fd, len);
57
+ }
58
+
59
+ // ─── fdatasync / fsync ────────────────────────────────────────────────────────
60
+ // Best-effort: flush the IOChannel write buffer (equivalent to fdatasync on GJS).
61
+
62
+ export function fdatasyncSync(fd: number): void { getFH(fd)._flushSync(); }
63
+ export function fdatasync(fd: number, callback: (err: NodeJS.ErrnoException | null) => void): void {
64
+ Promise.resolve().then(() => fdatasyncSync(fd)).then(() => callback(null), callback);
65
+ }
66
+ export async function fdatasyncAsync(fd: number): Promise<void> { fdatasyncSync(fd); }
67
+
68
+ export function fsyncSync(fd: number): void { getFH(fd)._flushSync(); }
69
+ export function fsync(fd: number, callback: (err: NodeJS.ErrnoException | null) => void): void {
70
+ Promise.resolve().then(() => fsyncSync(fd)).then(() => callback(null), callback);
71
+ }
72
+ export async function fsyncAsync(fd: number): Promise<void> { fsyncSync(fd); }
73
+
74
+ // ─── fchmod / fchown / futimes ────────────────────────────────────────────────
75
+
76
+ export function fchmodSync(fd: number, mode: number | string): void {
77
+ chmodSync(normalizePath(getFH(fd).options.path), mode);
78
+ }
79
+ export function fchmod(fd: number, mode: number | string, callback: (err: NodeJS.ErrnoException | null) => void): void {
80
+ Promise.resolve().then(() => fchmodSync(fd, mode)).then(() => callback(null), callback);
81
+ }
82
+ export async function fchmodAsync(fd: number, mode: number | string): Promise<void> { fchmodSync(fd, mode); }
83
+
84
+ export function fchownSync(fd: number, uid: number, gid: number): void {
85
+ chownSync(normalizePath(getFH(fd).options.path), uid, gid);
86
+ }
87
+ export function fchown(fd: number, uid: number, gid: number, callback: (err: NodeJS.ErrnoException | null) => void): void {
88
+ Promise.resolve().then(() => fchownSync(fd, uid, gid)).then(() => callback(null), callback);
89
+ }
90
+ export async function fchownAsync(fd: number, uid: number, gid: number): Promise<void> { fchownSync(fd, uid, gid); }
91
+
92
+ export function futimesSync(fd: number, atime: TimeLike, mtime: TimeLike): void {
93
+ utimesSync(normalizePath(getFH(fd).options.path), atime, mtime);
94
+ }
95
+ export function futimes(fd: number, atime: TimeLike, mtime: TimeLike, callback: (err: NodeJS.ErrnoException | null) => void): void {
96
+ Promise.resolve().then(() => futimesSync(fd, atime, mtime)).then(() => callback(null), callback);
97
+ }
98
+ export async function futimesAsync(fd: number, atime: TimeLike, mtime: TimeLike): Promise<void> { futimesSync(fd, atime, mtime); }
99
+
100
+ // ─── closeSync ────────────────────────────────────────────────────────────────
101
+
102
+ export function closeSync(fd: number): void {
103
+ getFH(fd)._closeSync();
104
+ }
105
+
106
+ // ─── readSync ─────────────────────────────────────────────────────────────────
107
+
108
+ export function readSync(
109
+ fd: number,
110
+ buffer: NodeJS.ArrayBufferView,
111
+ offset?: number | null,
112
+ length?: number | null,
113
+ position?: number | null,
114
+ ): number;
115
+ export function readSync(
116
+ fd: number,
117
+ buffer: NodeJS.ArrayBufferView,
118
+ options: { offset?: number; length?: number; position?: number | null },
119
+ ): number;
120
+ export function readSync(
121
+ fd: number,
122
+ buffer: NodeJS.ArrayBufferView,
123
+ offsetOrOptions?: number | null | { offset?: number; length?: number; position?: number | null },
124
+ length?: number | null,
125
+ position?: number | null,
126
+ ): number {
127
+ let offset = 0;
128
+ if (offsetOrOptions !== null && typeof offsetOrOptions === 'object') {
129
+ offset = (offsetOrOptions as any).offset ?? 0;
130
+ length = (offsetOrOptions as any).length ?? buffer.byteLength;
131
+ position = (offsetOrOptions as any).position ?? null;
132
+ } else {
133
+ offset = (offsetOrOptions as number | null | undefined) ?? 0;
134
+ length = length ?? buffer.byteLength - offset;
135
+ }
136
+ return getFH(fd)._readSync(buffer, offset, length!, position ?? null);
137
+ }
138
+
139
+ // ─── writeSync ────────────────────────────────────────────────────────────────
140
+
141
+ export function writeSync(
142
+ fd: number,
143
+ buffer: NodeJS.ArrayBufferView,
144
+ offset?: number | null,
145
+ length?: number | null,
146
+ position?: number | null,
147
+ ): number;
148
+ export function writeSync(
149
+ fd: number,
150
+ string: string,
151
+ position?: number | null,
152
+ encoding?: BufferEncoding | null,
153
+ ): number;
154
+ export function writeSync(
155
+ fd: number,
156
+ bufferOrString: NodeJS.ArrayBufferView | string,
157
+ offsetOrPosition?: number | null,
158
+ lengthOrEncoding?: number | string | null,
159
+ position?: number | null,
160
+ ): number {
161
+ let data: Uint8Array;
162
+ if (typeof bufferOrString === 'string') {
163
+ data = new TextEncoder().encode(bufferOrString);
164
+ if (typeof offsetOrPosition === 'number') position = offsetOrPosition;
165
+ } else {
166
+ const offset = (typeof offsetOrPosition === 'number' ? offsetOrPosition : 0);
167
+ const len = (typeof lengthOrEncoding === 'number' ? lengthOrEncoding : bufferOrString.byteLength - offset);
168
+ data = new Uint8Array((bufferOrString as any).buffer, (bufferOrString as any).byteOffset + offset, len);
169
+ }
170
+ return getFH(fd)._writeSync(data, position ?? null);
171
+ }
172
+
173
+ // ─── readvSync / readv ────────────────────────────────────────────────────────
174
+
175
+ export function readvSync(fd: number, buffers: NodeJS.ArrayBufferView[], position?: number | null): number {
176
+ let bytesRead = 0;
177
+ for (const buf of buffers) {
178
+ const n = readSync(fd, buf, 0, buf.byteLength, position != null ? position + bytesRead : null);
179
+ bytesRead += n;
180
+ if (n < buf.byteLength) break;
181
+ }
182
+ return bytesRead;
183
+ }
184
+
185
+ export function readv(
186
+ fd: number,
187
+ buffers: NodeJS.ArrayBufferView[],
188
+ callback: (err: NodeJS.ErrnoException | null, bytesRead: number, buffers: NodeJS.ArrayBufferView[]) => void,
189
+ ): void;
190
+ export function readv(
191
+ fd: number,
192
+ buffers: NodeJS.ArrayBufferView[],
193
+ position: number | null,
194
+ callback: (err: NodeJS.ErrnoException | null, bytesRead: number, buffers: NodeJS.ArrayBufferView[]) => void,
195
+ ): void;
196
+ export function readv(fd: number, buffers: NodeJS.ArrayBufferView[], positionOrCb: any, callback?: any): void {
197
+ if (typeof positionOrCb === 'function') { callback = positionOrCb; positionOrCb = null; }
198
+ Promise.resolve()
199
+ .then(() => ({ bytesRead: readvSync(fd, buffers, positionOrCb), buffers }))
200
+ .then(r => callback(null, r.bytesRead, r.buffers), callback);
201
+ }
202
+
203
+ export async function readvAsync(fd: number, buffers: NodeJS.ArrayBufferView[], position?: number | null) {
204
+ return { bytesRead: readvSync(fd, buffers, position), buffers };
205
+ }
206
+
207
+ // ─── writevSync / writev ──────────────────────────────────────────────────────
208
+
209
+ export function writevSync(fd: number, buffers: NodeJS.ArrayBufferView[], position?: number | null): number {
210
+ let bytesWritten = 0;
211
+ for (const buf of buffers) {
212
+ const n = writeSync(fd, buf, 0, buf.byteLength, position != null ? position + bytesWritten : null);
213
+ bytesWritten += n;
214
+ }
215
+ return bytesWritten;
216
+ }
217
+
218
+ export function writev(
219
+ fd: number,
220
+ buffers: NodeJS.ArrayBufferView[],
221
+ callback: (err: NodeJS.ErrnoException | null, bytesWritten: number, buffers: NodeJS.ArrayBufferView[]) => void,
222
+ ): void;
223
+ export function writev(
224
+ fd: number,
225
+ buffers: NodeJS.ArrayBufferView[],
226
+ position: number | null,
227
+ callback: (err: NodeJS.ErrnoException | null, bytesWritten: number, buffers: NodeJS.ArrayBufferView[]) => void,
228
+ ): void;
229
+ export function writev(fd: number, buffers: NodeJS.ArrayBufferView[], positionOrCb: any, callback?: any): void {
230
+ if (typeof positionOrCb === 'function') { callback = positionOrCb; positionOrCb = null; }
231
+ Promise.resolve()
232
+ .then(() => ({ bytesWritten: writevSync(fd, buffers, positionOrCb), buffers }))
233
+ .then(r => callback(null, r.bytesWritten, r.buffers), callback);
234
+ }
235
+
236
+ export async function writevAsync(fd: number, buffers: NodeJS.ArrayBufferView[], position?: number | null) {
237
+ return { bytesWritten: writevSync(fd, buffers, position), buffers };
238
+ }
239
+
240
+ // ─── exists (deprecated) ──────────────────────────────────────────────────────
241
+
242
+ export function exists(path: PathLike, callback: (exists: boolean) => void): void {
243
+ try { statSync(normalizePath(path)); callback(true); } catch { callback(false); }
244
+ }
245
+
246
+ // ─── openAsBlob ───────────────────────────────────────────────────────────────
247
+
248
+ export async function openAsBlob(path: PathLike, options?: { type?: string }): Promise<Blob> {
249
+ const data = readFileSync(normalizePath(path)) as unknown as ArrayBuffer;
250
+ return new Blob([data], { type: options?.type ?? '' });
251
+ }