opfs-worker 0.2.1 → 0.2.2
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/README.md +260 -27
- package/dist/assets/worker-CMvl9yOu.js.map +1 -0
- package/dist/index.cjs +189 -135
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +6 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1184 -11
- package/dist/index.js.map +1 -1
- package/dist/raw.cjs +1 -1
- package/dist/raw.cjs.map +1 -1
- package/dist/raw.js +154 -100
- package/dist/raw.js.map +1 -1
- package/dist/worker.d.ts +36 -8
- package/dist/worker.d.ts.map +1 -1
- package/package.json +1 -1
- package/dist/assets/worker-ChfzBM-o.js.map +0 -1
- package/dist/types.js +0 -1
- package/dist/utils/encoder.js +0 -83
- package/dist/utils/errors.js +0 -77
- package/dist/utils/helpers.js +0 -246
- package/dist/worker.js +0 -818
package/README.md
CHANGED
|
@@ -57,22 +57,34 @@ async function example() {
|
|
|
57
57
|
// Create a file system instance
|
|
58
58
|
const fs = await createWorker();
|
|
59
59
|
|
|
60
|
-
// Mount
|
|
61
|
-
await fs.mount('/my-app');
|
|
60
|
+
// Mount is optional - OPFS root is used by default
|
|
61
|
+
// await fs.mount('/my-app'); // Uses custom subdirectory
|
|
62
62
|
|
|
63
|
-
// Write a file
|
|
63
|
+
// Write a file (auto-mounts if not mounted)
|
|
64
64
|
await fs.writeFile('/config.json', JSON.stringify({ theme: 'dark' }));
|
|
65
65
|
|
|
66
66
|
// Read the file back
|
|
67
67
|
const config = await fs.readFile('/config.json');
|
|
68
68
|
console.log(JSON.parse(config));
|
|
69
|
+
|
|
70
|
+
// Handle binary files
|
|
71
|
+
const imageData = new Uint8Array([/* binary data */]);
|
|
72
|
+
await fs.writeFile('/image.png', imageData);
|
|
73
|
+
const binaryData = await fs.readFile('/image.png', 'binary');
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// With watch callbacks
|
|
77
|
+
async function exampleWithWatch() {
|
|
78
|
+
const fs = await createWorker(
|
|
79
|
+
(event) => console.log('File changed:', event),
|
|
80
|
+
{ watchInterval: 500 }
|
|
81
|
+
);
|
|
82
|
+
|
|
83
|
+
await fs.watch('/docs');
|
|
69
84
|
}
|
|
70
85
|
```
|
|
71
86
|
|
|
72
|
-
> **Note:** The `mount` call
|
|
73
|
-
> file system. This call is mandatory before any file operations. For example,
|
|
74
|
-
> after `fs.mount('/dir')`, calling `fs.readFile('/text.txt')` accesses the file
|
|
75
|
-
> located at `/dir/text.txt` inside OPFS.
|
|
87
|
+
> **Note:** The `mount` call is now optional. If not called, the OPFS root directory is used automatically. For custom subdirectories, call `fs.mount('/my-app')` to create a subdirectory in OPFS. All file operations will auto-mount if needed.
|
|
76
88
|
|
|
77
89
|
### Manual Worker Setup
|
|
78
90
|
|
|
@@ -86,18 +98,32 @@ async function example() {
|
|
|
86
98
|
// Create and wrap the worker
|
|
87
99
|
const worker = wrap(new OPFSWorker());
|
|
88
100
|
|
|
89
|
-
// Mount
|
|
90
|
-
await worker.mount(
|
|
101
|
+
// Mount is optional - OPFS root is used by default
|
|
102
|
+
// await worker.mount(); // Uses OPFS root directory
|
|
103
|
+
// await worker.mount('/my-app'); // Uses custom subdirectory
|
|
91
104
|
|
|
92
|
-
// Use the file system
|
|
105
|
+
// Use the file system (auto-mounts if not mounted)
|
|
93
106
|
await worker.writeFile('/config.json', JSON.stringify({ theme: 'dark' }));
|
|
94
107
|
const config = await worker.readFile('/config.json');
|
|
95
108
|
console.log(JSON.parse(config));
|
|
96
109
|
}
|
|
110
|
+
|
|
111
|
+
// With watch callbacks
|
|
112
|
+
async function exampleWithWatch() {
|
|
113
|
+
const worker = wrap(new OPFSWorker(
|
|
114
|
+
(event) => console.log('File changed:', event),
|
|
115
|
+
{ watchInterval: 500 }
|
|
116
|
+
));
|
|
117
|
+
|
|
118
|
+
await worker.mount('/my-app');
|
|
119
|
+
await worker.watch('/docs');
|
|
120
|
+
}
|
|
97
121
|
```
|
|
98
122
|
|
|
99
123
|
**Note:** Manual worker setup requires a bundler that supports Web Workers (like Vite, Webpack, or Rollup) and the `comlink` package for communication between the main thread and worker.
|
|
100
124
|
|
|
125
|
+
**Watch Callbacks:** File watching with callbacks is available with both `createWorker()` and raw worker usage. The `createWorker()` function uses Comlink.proxy to handle function serialization across worker boundaries.
|
|
126
|
+
|
|
101
127
|
### Advanced Usage
|
|
102
128
|
|
|
103
129
|
```typescript
|
|
@@ -105,7 +131,8 @@ import { createWorker } from 'opfs-worker';
|
|
|
105
131
|
|
|
106
132
|
async function advancedExample() {
|
|
107
133
|
const fs = await createWorker();
|
|
108
|
-
|
|
134
|
+
// Mount is optional - auto-mounts to OPFS root if not called
|
|
135
|
+
// await fs.mount('/my-app'); // For custom subdirectory
|
|
109
136
|
|
|
110
137
|
// Create directories
|
|
111
138
|
await fs.mkdir('/data/logs', { recursive: true });
|
|
@@ -114,6 +141,11 @@ async function advancedExample() {
|
|
|
114
141
|
await fs.writeFile('/data/config.json', JSON.stringify({ version: '1.0' }));
|
|
115
142
|
await fs.writeFile('/data/logs/app.log', 'Application started\n');
|
|
116
143
|
|
|
144
|
+
// Handle binary files
|
|
145
|
+
const imageData = new Uint8Array([/* binary data */]);
|
|
146
|
+
await fs.writeFile('/data/image.png', imageData);
|
|
147
|
+
const binaryData = await fs.readFile('/data/image.png', 'binary');
|
|
148
|
+
|
|
117
149
|
// Append to a file
|
|
118
150
|
await fs.appendFile('/data/logs/app.log', `${new Date().toISOString()}: User logged in\n`);
|
|
119
151
|
|
|
@@ -129,6 +161,8 @@ async function advancedExample() {
|
|
|
129
161
|
files.forEach(item => {
|
|
130
162
|
console.log(`${item.name} - ${item.isFile ? 'file' : 'directory'}`);
|
|
131
163
|
});
|
|
164
|
+
|
|
165
|
+
|
|
132
166
|
}
|
|
133
167
|
```
|
|
134
168
|
|
|
@@ -160,6 +194,8 @@ Check out the live demo powered by Vite and hosted on GitHub Pages.
|
|
|
160
194
|
- [Watch](#watchpath-string-promisevoid)
|
|
161
195
|
- [Unwatch](#unwatchpath-string-void)
|
|
162
196
|
- [Real Path](#realpathpath-string-promisestring)
|
|
197
|
+
- [Binary File Handling](#binary-file-handling)
|
|
198
|
+
- [Utility Functions](#utility-functions)
|
|
163
199
|
|
|
164
200
|
### Entry Points
|
|
165
201
|
|
|
@@ -196,11 +232,9 @@ const worker = wrap(new OPFSWorker());
|
|
|
196
232
|
|
|
197
233
|
### Mount
|
|
198
234
|
|
|
199
|
-
#### `mount(root?: string
|
|
235
|
+
#### `mount(root?: string): Promise<boolean>`
|
|
200
236
|
|
|
201
|
-
Initialize the file system within a given directory
|
|
202
|
-
watch callback. Calling `mount` is required before performing any file
|
|
203
|
-
operations, even if you're using the root directory (`'/'`).
|
|
237
|
+
Initialize the file system within a given directory. **Mount is now optional** - if not called, the OPFS root directory is used automatically.
|
|
204
238
|
|
|
205
239
|
The `root` parameter defines where in OPFS the file system's root will be
|
|
206
240
|
created. All file paths passed to the API are relative to this mount point. For
|
|
@@ -208,26 +242,30 @@ example, after `fs.mount('/dir')`, calling `fs.readFile('/text.txt')` accesses
|
|
|
208
242
|
`/dir/text.txt` in OPFS.
|
|
209
243
|
|
|
210
244
|
```typescript
|
|
211
|
-
|
|
245
|
+
// Use OPFS root (default behavior)
|
|
246
|
+
await fs.mount();
|
|
247
|
+
|
|
248
|
+
// Use custom subdirectory
|
|
249
|
+
await fs.mount('/my-app');
|
|
212
250
|
```
|
|
213
251
|
|
|
214
252
|
**Parameters:**
|
|
215
253
|
|
|
216
254
|
- `root` (optional): The root path for the file system (default: '/')
|
|
217
|
-
- `watch` (optional): Callback invoked with `WatchEvent` objects when watched
|
|
218
|
-
paths change
|
|
219
|
-
- `options.watchInterval` (optional): Polling interval in milliseconds
|
|
220
|
-
(default: `1000`)
|
|
221
255
|
|
|
222
256
|
**Returns:** `Promise<boolean>` - True if initialization was successful
|
|
223
257
|
|
|
224
258
|
**Throws:** `OPFSError` if initialization fails
|
|
225
259
|
|
|
260
|
+
**Note:** All file operations will automatically mount the OPFS root if no explicit mount has been performed.
|
|
261
|
+
|
|
262
|
+
**Watch Callbacks:** File watching with callbacks is only available when using the raw worker directly. The `createWorker()` function does not support watch callbacks due to Comlink limitations with function serialization.
|
|
263
|
+
|
|
226
264
|
### Read File
|
|
227
265
|
|
|
228
266
|
#### `readFile(path: string, encoding?: BufferEncoding | 'binary'): Promise<string | Uint8Array>`
|
|
229
267
|
|
|
230
|
-
Read a file from the file system.
|
|
268
|
+
Read a file from the file system. Supports both text and binary files.
|
|
231
269
|
|
|
232
270
|
```typescript
|
|
233
271
|
// Read as text (default)
|
|
@@ -238,22 +276,32 @@ const binaryData = await fs.readFile('/images/logo.png', 'binary');
|
|
|
238
276
|
|
|
239
277
|
// Read with specific encoding
|
|
240
278
|
const utf8Content = await fs.readFile('/data/utf8.txt', 'utf-8');
|
|
279
|
+
|
|
280
|
+
// Handle binary data
|
|
281
|
+
const imageBuffer = await fs.readFile('/image.png', 'binary');
|
|
282
|
+
const blob = new Blob([imageBuffer], { type: 'image/png' });
|
|
283
|
+
const url = URL.createObjectURL(blob);
|
|
241
284
|
```
|
|
242
285
|
|
|
243
286
|
**Parameters:**
|
|
244
287
|
|
|
245
288
|
- `path`: The path to the file to read
|
|
246
|
-
- `encoding` (optional): The encoding to use ('utf-8', 'binary',
|
|
289
|
+
- `encoding` (optional): The encoding to use ('utf-8', 'binary', 'utf-16le', 'ascii', 'latin1', 'base64', 'hex')
|
|
247
290
|
|
|
248
|
-
**Returns:** `Promise<string | Uint8Array>` - File contents
|
|
291
|
+
**Returns:** `Promise<string | Uint8Array>` - File contents as string or binary data
|
|
249
292
|
|
|
250
293
|
**Throws:** `FileNotFoundError` if the file doesn't exist
|
|
251
294
|
|
|
295
|
+
**Binary File Handling:**
|
|
296
|
+
- Use `'binary'` encoding to read files as `Uint8Array`
|
|
297
|
+
- Binary data can be converted to `Blob` for use with `URL.createObjectURL()`
|
|
298
|
+
- Supports various encodings for text files
|
|
299
|
+
|
|
252
300
|
### Write File
|
|
253
301
|
|
|
254
302
|
#### `writeFile(path: string, data: string | Uint8Array | ArrayBuffer, encoding?: BufferEncoding): Promise<void>`
|
|
255
303
|
|
|
256
|
-
Write data to a file, creating or overwriting it.
|
|
304
|
+
Write data to a file, creating or overwriting it. Supports both text and binary data.
|
|
257
305
|
|
|
258
306
|
```typescript
|
|
259
307
|
// Write text data
|
|
@@ -265,13 +313,31 @@ await fs.writeFile('/data/binary.dat', binaryData);
|
|
|
265
313
|
|
|
266
314
|
// Write with specific encoding
|
|
267
315
|
await fs.writeFile('/data/utf16.txt', 'Hello World', 'utf-16le');
|
|
316
|
+
|
|
317
|
+
// Write binary data from file input
|
|
318
|
+
const fileInput = document.getElementById('file') as HTMLInputElement;
|
|
319
|
+
const file = fileInput.files?.[0];
|
|
320
|
+
if (file) {
|
|
321
|
+
const arrayBuffer = await file.arrayBuffer();
|
|
322
|
+
await fs.writeFile('/uploaded-file', new Uint8Array(arrayBuffer));
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
// Write binary data from fetch
|
|
326
|
+
const response = await fetch('/api/image.png');
|
|
327
|
+
const arrayBuffer = await response.arrayBuffer();
|
|
328
|
+
await fs.writeFile('/downloaded-image.png', new Uint8Array(arrayBuffer));
|
|
268
329
|
```
|
|
269
330
|
|
|
270
331
|
**Parameters:**
|
|
271
332
|
|
|
272
333
|
- `path`: The path to the file to write
|
|
273
334
|
- `data`: The data to write (string, Uint8Array, or ArrayBuffer)
|
|
274
|
-
- `encoding` (optional): The encoding to use when writing string data
|
|
335
|
+
- `encoding` (optional): The encoding to use when writing string data ('utf-8', 'utf-16le', 'ascii', 'latin1', 'base64', 'hex')
|
|
336
|
+
|
|
337
|
+
**Binary File Handling:**
|
|
338
|
+
- Pass `Uint8Array` or `ArrayBuffer` directly for binary data
|
|
339
|
+
- Use with file uploads, image processing, or any binary content
|
|
340
|
+
- Supports various text encodings for string data
|
|
275
341
|
|
|
276
342
|
### Append File
|
|
277
343
|
|
|
@@ -520,8 +586,8 @@ await fs.sync(entries, { cleanBefore: true });
|
|
|
520
586
|
#### `watch(path: string): Promise<void>`
|
|
521
587
|
|
|
522
588
|
Start watching a file or directory for changes. Detected changes are sent to the
|
|
523
|
-
callback provided to
|
|
524
|
-
|
|
589
|
+
callback provided to the constructor. The polling interval is configured globally when
|
|
590
|
+
creating the worker instance.
|
|
525
591
|
|
|
526
592
|
```typescript
|
|
527
593
|
await fs.watch('/docs');
|
|
@@ -531,6 +597,8 @@ await fs.watch('/docs');
|
|
|
531
597
|
|
|
532
598
|
- `path`: File or directory to watch
|
|
533
599
|
|
|
600
|
+
**Note:** Watch callbacks are available with both `createWorker()` and raw worker usage. The `createWorker()` function uses Comlink.proxy to handle function serialization across worker boundaries.
|
|
601
|
+
|
|
534
602
|
### Unwatch
|
|
535
603
|
|
|
536
604
|
#### `unwatch(path: string): void`
|
|
@@ -557,6 +625,171 @@ console.log(absolute); // '/data/file.txt'
|
|
|
557
625
|
|
|
558
626
|
**Throws:** `FileNotFoundError` if the path doesn't exist
|
|
559
627
|
|
|
628
|
+
## Binary File Handling
|
|
629
|
+
|
|
630
|
+
This library provides comprehensive support for binary files, making it easy to work with images, documents, and other binary data.
|
|
631
|
+
|
|
632
|
+
### Reading Binary Files
|
|
633
|
+
|
|
634
|
+
```typescript
|
|
635
|
+
// Read as binary data
|
|
636
|
+
const imageData = await fs.readFile('/image.png', 'binary');
|
|
637
|
+
const documentData = await fs.readFile('/document.pdf', 'binary');
|
|
638
|
+
|
|
639
|
+
// Convert to Blob for use with URLs
|
|
640
|
+
const imageBuffer = await fs.readFile('/image.png', 'binary');
|
|
641
|
+
const blob = new Blob([imageBuffer], { type: 'image/png' });
|
|
642
|
+
const url = URL.createObjectURL(blob);
|
|
643
|
+
|
|
644
|
+
// Display image
|
|
645
|
+
const img = document.createElement('img');
|
|
646
|
+
img.src = url;
|
|
647
|
+
document.body.appendChild(img);
|
|
648
|
+
```
|
|
649
|
+
|
|
650
|
+
### Writing Binary Files
|
|
651
|
+
|
|
652
|
+
```typescript
|
|
653
|
+
// Write binary data directly
|
|
654
|
+
const binaryData = new Uint8Array([1, 2, 3, 4, 5]);
|
|
655
|
+
await fs.writeFile('/data.bin', binaryData);
|
|
656
|
+
|
|
657
|
+
// From file input
|
|
658
|
+
const fileInput = document.getElementById('file') as HTMLInputElement;
|
|
659
|
+
const file = fileInput.files?.[0];
|
|
660
|
+
if (file) {
|
|
661
|
+
const arrayBuffer = await file.arrayBuffer();
|
|
662
|
+
await fs.writeFile('/uploaded-file', new Uint8Array(arrayBuffer));
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
// From fetch response
|
|
666
|
+
const response = await fetch('/api/download/file.pdf');
|
|
667
|
+
const arrayBuffer = await response.arrayBuffer();
|
|
668
|
+
await fs.writeFile('/downloaded-file.pdf', new Uint8Array(arrayBuffer));
|
|
669
|
+
|
|
670
|
+
// From canvas
|
|
671
|
+
const canvas = document.createElement('canvas');
|
|
672
|
+
const ctx = canvas.getContext('2d');
|
|
673
|
+
// ... draw something ...
|
|
674
|
+
canvas.toBlob(async (blob) => {
|
|
675
|
+
if (blob) {
|
|
676
|
+
const arrayBuffer = await blob.arrayBuffer();
|
|
677
|
+
await fs.writeFile('/canvas-image.png', new Uint8Array(arrayBuffer));
|
|
678
|
+
}
|
|
679
|
+
});
|
|
680
|
+
```
|
|
681
|
+
|
|
682
|
+
### Working with Different Data Types
|
|
683
|
+
|
|
684
|
+
```typescript
|
|
685
|
+
// Convert between different binary formats
|
|
686
|
+
const uint8Array = new Uint8Array([1, 2, 3, 4, 5]);
|
|
687
|
+
const arrayBuffer = uint8Array.buffer;
|
|
688
|
+
|
|
689
|
+
// All of these work the same way
|
|
690
|
+
await fs.writeFile('/data1.bin', uint8Array);
|
|
691
|
+
await fs.writeFile('/data2.bin', arrayBuffer);
|
|
692
|
+
await fs.writeFile('/data3.bin', new Uint8Array(arrayBuffer));
|
|
693
|
+
|
|
694
|
+
// Read back as binary
|
|
695
|
+
const data = await fs.readFile('/data1.bin', 'binary');
|
|
696
|
+
console.log(data); // Uint8Array
|
|
697
|
+
```
|
|
698
|
+
|
|
699
|
+
### File Upload and Download
|
|
700
|
+
|
|
701
|
+
```typescript
|
|
702
|
+
// Handle file uploads
|
|
703
|
+
const handleFileUpload = async (file: File) => {
|
|
704
|
+
const arrayBuffer = await file.arrayBuffer();
|
|
705
|
+
await fs.writeFile(`/uploads/${file.name}`, new Uint8Array(arrayBuffer));
|
|
706
|
+
};
|
|
707
|
+
|
|
708
|
+
// Create downloadable files
|
|
709
|
+
const createDownloadLink = async (filePath: string, fileName: string) => {
|
|
710
|
+
const data = await fs.readFile(filePath, 'binary');
|
|
711
|
+
const blob = new Blob([data]);
|
|
712
|
+
const url = URL.createObjectURL(blob);
|
|
713
|
+
|
|
714
|
+
const a = document.createElement('a');
|
|
715
|
+
a.href = url;
|
|
716
|
+
a.download = fileName;
|
|
717
|
+
a.click();
|
|
718
|
+
|
|
719
|
+
URL.revokeObjectURL(url);
|
|
720
|
+
};
|
|
721
|
+
```
|
|
722
|
+
|
|
723
|
+
### Supported Encodings
|
|
724
|
+
|
|
725
|
+
The library supports various encodings for text files:
|
|
726
|
+
|
|
727
|
+
- `'utf-8'` (default) - UTF-8 encoding
|
|
728
|
+
- `'utf-16le'` - UTF-16 little-endian
|
|
729
|
+
- `'ascii'` - ASCII encoding
|
|
730
|
+
- `'latin1'` - Latin-1 encoding
|
|
731
|
+
- `'base64'` - Base64 encoding
|
|
732
|
+
- `'hex'` - Hexadecimal encoding
|
|
733
|
+
- `'binary'` - Raw binary data (returns Uint8Array)
|
|
734
|
+
|
|
735
|
+
## Utility Functions
|
|
736
|
+
|
|
737
|
+
The library exports several utility functions that can be used independently:
|
|
738
|
+
|
|
739
|
+
### Path Utilities
|
|
740
|
+
|
|
741
|
+
```typescript
|
|
742
|
+
import { basename, dirname, normalizePath, resolvePath, extname } from 'opfs-worker';
|
|
743
|
+
|
|
744
|
+
// Extract filename from path
|
|
745
|
+
basename('/path/to/file.txt'); // 'file.txt'
|
|
746
|
+
basename('/path/to/directory/'); // ''
|
|
747
|
+
|
|
748
|
+
// Extract directory path
|
|
749
|
+
dirname('/path/to/file.txt'); // '/path/to'
|
|
750
|
+
dirname('file.txt'); // '/'
|
|
751
|
+
|
|
752
|
+
// Normalize path to start with '/'
|
|
753
|
+
normalizePath('path/to/file'); // '/path/to/file'
|
|
754
|
+
normalizePath('/path/to/file'); // '/path/to/file'
|
|
755
|
+
|
|
756
|
+
// Resolve relative paths
|
|
757
|
+
resolvePath('./config/../data/file.txt'); // '/data/file.txt'
|
|
758
|
+
resolvePath('/path/to/../file.txt'); // '/path/file.txt'
|
|
759
|
+
|
|
760
|
+
// Get file extension
|
|
761
|
+
extname('/path/to/file.txt'); // '.txt'
|
|
762
|
+
extname('/path/to/file'); // ''
|
|
763
|
+
extname('/path/to/file.name.ext'); // '.ext'
|
|
764
|
+
```
|
|
765
|
+
|
|
766
|
+
### Data Conversion
|
|
767
|
+
|
|
768
|
+
```typescript
|
|
769
|
+
import { convertBlobToUint8Array } from 'opfs-worker';
|
|
770
|
+
|
|
771
|
+
// Convert Blob to Uint8Array
|
|
772
|
+
const fileInput = document.getElementById('file') as HTMLInputElement;
|
|
773
|
+
const file = fileInput.files?.[0];
|
|
774
|
+
if (file) {
|
|
775
|
+
const data = await convertBlobToUint8Array(file);
|
|
776
|
+
await fs.writeFile('/uploaded-file', data);
|
|
777
|
+
}
|
|
778
|
+
```
|
|
779
|
+
|
|
780
|
+
### File System Utilities
|
|
781
|
+
|
|
782
|
+
```typescript
|
|
783
|
+
import { checkOPFSSupport, splitPath, joinPath } from 'opfs-worker';
|
|
784
|
+
|
|
785
|
+
// Check if browser supports OPFS
|
|
786
|
+
checkOPFSSupport(); // Throws error if not supported
|
|
787
|
+
|
|
788
|
+
// Path manipulation
|
|
789
|
+
splitPath('/path/to/file'); // ['path', 'to', 'file']
|
|
790
|
+
joinPath(['path', 'to', 'file']); // '/path/to/file'
|
|
791
|
+
```
|
|
792
|
+
|
|
560
793
|
## Types
|
|
561
794
|
|
|
562
795
|
### `FileStat`
|