@statewalker/webrun-files 0.3.1 → 0.5.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.
- package/README.md +188 -6
- package/dist/cjs/index.cjs +599 -0
- package/dist/esm/index.js +584 -0
- package/dist/files-api.d.ts +44 -0
- package/dist/files-api.d.ts.map +1 -0
- package/dist/impl/index.d.ts +6 -0
- package/dist/impl/index.d.ts.map +1 -0
- package/dist/impl/mem-files-api.d.ts +13 -0
- package/dist/impl/mem-files-api.d.ts.map +1 -0
- package/dist/impl/node-files-api.d.ts +24 -0
- package/dist/impl/node-files-api.d.ts.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/types.d.ts +67 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/utils/collect-stream.d.ts +16 -0
- package/dist/utils/collect-stream.d.ts.map +1 -0
- package/dist/utils/file-info-utils.d.ts +10 -0
- package/dist/utils/file-info-utils.d.ts.map +1 -0
- package/dist/utils/index.d.ts +8 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/normalize-path.d.ts +21 -0
- package/dist/utils/normalize-path.d.ts.map +1 -0
- package/dist/utils/path-utils.d.ts +20 -0
- package/dist/utils/path-utils.d.ts.map +1 -0
- package/package.json +30 -31
- package/src/files-api.ts +168 -0
- package/src/impl/index.ts +6 -0
- package/src/impl/mem-files-api.ts +323 -0
- package/src/impl/node-files-api.ts +271 -0
- package/src/index.ts +36 -0
- package/src/types.ts +79 -0
- package/src/utils/collect-stream.ts +35 -0
- package/src/utils/file-info-utils.ts +15 -0
- package/src/utils/index.ts +8 -0
- package/src/utils/normalize-path.ts +34 -0
- package/src/utils/path-utils.ts +46 -0
- package/CHANGELOG.md +0 -2
- package/dist/index-umd.js +0 -1054
- package/dist/index-umd.min.js +0 -2
- package/dist/index.js +0 -1033
- package/dist/index.min.js +0 -2
- package/index.js +0 -1
- package/src/BrowserFilesApi.js +0 -335
- package/src/FilesApi.js +0 -133
- package/src/MemFilesApi.js +0 -129
- package/src/NodeFilesApi.js +0 -222
- package/src/addFilesApiLogger.js +0 -25
- package/src/getMimeType.js +0 -19
- package/src/index.js +0 -10
- package/src/mimeTypes.js +0 -96
- package/src/normalizePath.js +0 -8
- package/src/notImplemented.js +0 -3
- package/src/openBrowserFilesApi.js +0 -67
package/README.md
CHANGED
|
@@ -1,17 +1,199 @@
|
|
|
1
|
+
# @statewalker/webrun-files
|
|
1
2
|
|
|
2
|
-
|
|
3
|
+
The core filesystem API for cross-platform file operations. This package provides a clean, minimal interface for reading, writing, and managing files that works consistently whether you're running in Node.js or need an in-memory implementation for browsers and testing.
|
|
3
4
|
|
|
4
|
-
|
|
5
|
+
## Installation
|
|
5
6
|
|
|
6
|
-
|
|
7
|
+
```bash
|
|
8
|
+
npm install @statewalker/webrun-files
|
|
9
|
+
# or
|
|
10
|
+
pnpm add @statewalker/webrun-files
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Quick Start
|
|
14
|
+
|
|
15
|
+
The fastest way to get going is to create a `FilesApi` instance with one of the built-in backends. Here's an example using the in-memory implementation:
|
|
16
|
+
|
|
17
|
+
```typescript
|
|
18
|
+
import { FilesApi, MemFilesApi } from '@statewalker/webrun-files';
|
|
19
|
+
|
|
20
|
+
const files = new FilesApi(new MemFilesApi());
|
|
21
|
+
|
|
22
|
+
// Write a file
|
|
23
|
+
await files.write('/documents/notes.txt', [
|
|
24
|
+
new TextEncoder().encode('Remember to water the plants')
|
|
25
|
+
]);
|
|
26
|
+
|
|
27
|
+
// Read it back
|
|
28
|
+
const content = await files.readFile('/documents/notes.txt');
|
|
29
|
+
console.log(new TextDecoder().decode(content));
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
For Node.js applications that need to work with the actual filesystem, switch to `NodeFilesApi`:
|
|
33
|
+
|
|
34
|
+
```typescript
|
|
35
|
+
import { FilesApi, NodeFilesApi } from '@statewalker/webrun-files';
|
|
36
|
+
|
|
37
|
+
const files = new FilesApi(new NodeFilesApi('/path/to/root'));
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
The `NodeFilesApi` constructor accepts an optional root directory path. When provided, all file operations will be relative to this directory, effectively sandboxing the API.
|
|
41
|
+
|
|
42
|
+
## Working with Files
|
|
43
|
+
|
|
44
|
+
The `FilesApi` class provides everything you need for common file operations. Writing content is straightforward—just pass an array of `Uint8Array` chunks:
|
|
7
45
|
|
|
8
|
-
```
|
|
46
|
+
```typescript
|
|
47
|
+
const text = new TextEncoder().encode('Hello, World!');
|
|
48
|
+
await files.write('/greeting.txt', [text]);
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Reading comes in two flavors. Use `readFile` when you want the entire contents as a single buffer:
|
|
52
|
+
|
|
53
|
+
```typescript
|
|
54
|
+
const content = await files.readFile('/greeting.txt');
|
|
55
|
+
```
|
|
9
56
|
|
|
57
|
+
For large files, `read` returns an async generator that yields chunks as they come in, keeping memory usage under control:
|
|
10
58
|
|
|
59
|
+
```typescript
|
|
60
|
+
for await (const chunk of files.read('/large-file.bin')) {
|
|
61
|
+
process.stdout.write(chunk);
|
|
62
|
+
}
|
|
11
63
|
```
|
|
12
64
|
|
|
13
|
-
|
|
65
|
+
You can also read specific portions of a file by specifying start and end positions:
|
|
14
66
|
|
|
15
|
-
```
|
|
67
|
+
```typescript
|
|
68
|
+
for await (const chunk of files.read('/data.bin', { start: 100, end: 200 })) {
|
|
69
|
+
// Only bytes 100-199
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Managing Files and Directories
|
|
16
74
|
|
|
75
|
+
Checking whether a file or directory exists is simple:
|
|
76
|
+
|
|
77
|
+
```typescript
|
|
78
|
+
if (await files.exists('/config.json')) {
|
|
79
|
+
// Load configuration
|
|
80
|
+
}
|
|
17
81
|
```
|
|
82
|
+
|
|
83
|
+
To get detailed information about a file, use `stats`:
|
|
84
|
+
|
|
85
|
+
```typescript
|
|
86
|
+
const info = await files.stats('/photo.jpg');
|
|
87
|
+
if (info) {
|
|
88
|
+
console.log(`Size: ${info.size} bytes`);
|
|
89
|
+
console.log(`Modified: ${new Date(info.lastModified)}`);
|
|
90
|
+
console.log(`Type: ${info.kind}`); // "file" or "directory"
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Listing directory contents returns an async generator of file info objects:
|
|
95
|
+
|
|
96
|
+
```typescript
|
|
97
|
+
for await (const entry of files.list('/documents')) {
|
|
98
|
+
console.log(`${entry.name} (${entry.kind})`);
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Pass `{ recursive: true }` to traverse subdirectories:
|
|
103
|
+
|
|
104
|
+
```typescript
|
|
105
|
+
for await (const entry of files.list('/project', { recursive: true })) {
|
|
106
|
+
console.log(entry.path);
|
|
107
|
+
}
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
Creating directories, copying, moving, and deleting all work as you'd expect:
|
|
111
|
+
|
|
112
|
+
```typescript
|
|
113
|
+
await files.mkdir('/archive/2024');
|
|
114
|
+
await files.copy('/report.pdf', '/archive/2024/report.pdf');
|
|
115
|
+
await files.move('/temp/draft.txt', '/documents/final.txt');
|
|
116
|
+
await files.remove('/old-stuff'); // Recursively deletes directories
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## Low-Level File Handle Operations
|
|
120
|
+
|
|
121
|
+
When you need fine-grained control over file operations, work directly with file handles. Opening a file gives you a handle that supports reading, writing, and appending at specific positions:
|
|
122
|
+
|
|
123
|
+
```typescript
|
|
124
|
+
const handle = await files.open('/data.bin');
|
|
125
|
+
|
|
126
|
+
// Get the current file size
|
|
127
|
+
console.log(`File is ${handle.size} bytes`);
|
|
128
|
+
|
|
129
|
+
// Read a specific range
|
|
130
|
+
for await (const chunk of handle.createReadStream({ start: 0, end: 100 })) {
|
|
131
|
+
// First 100 bytes
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// Write at a specific position
|
|
135
|
+
await handle.createWriteStream([newData], { start: 50 });
|
|
136
|
+
|
|
137
|
+
// Append to the end
|
|
138
|
+
await handle.appendFile([moreData]);
|
|
139
|
+
|
|
140
|
+
// Always close when done
|
|
141
|
+
await handle.close();
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
## Building Your Own Backend
|
|
145
|
+
|
|
146
|
+
The `IFilesApi` interface defines the contract that all backends must implement. At minimum, you need four methods:
|
|
147
|
+
|
|
148
|
+
```typescript
|
|
149
|
+
interface IFilesApi {
|
|
150
|
+
list(file: FileRef, options?: ListOptions): AsyncGenerator<FileInfo>;
|
|
151
|
+
stats(file: FileRef): Promise<FileInfo | undefined>;
|
|
152
|
+
remove(file: FileRef): Promise<boolean>;
|
|
153
|
+
open(file: FileRef): Promise<FileHandle>;
|
|
154
|
+
}
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
The `FilesApi` wrapper class builds convenience methods like `read`, `write`, `copy`, and `move` on top of these primitives. Backends can optionally implement native versions of `move`, `copy`, and `mkdir` for better performance.
|
|
158
|
+
|
|
159
|
+
Take a look at `MemFilesApi` or `NodeFilesApi` in the source code for reference implementations.
|
|
160
|
+
|
|
161
|
+
## Type Reference
|
|
162
|
+
|
|
163
|
+
The package exports all the TypeScript types you'll need:
|
|
164
|
+
|
|
165
|
+
```typescript
|
|
166
|
+
import type {
|
|
167
|
+
IFilesApi, // Core interface for backends
|
|
168
|
+
FilesApi, // Wrapper class with convenience methods
|
|
169
|
+
FileInfo, // Metadata returned by stats() and list()
|
|
170
|
+
FileHandle, // Low-level file operations
|
|
171
|
+
FileRef, // string | { path: string }
|
|
172
|
+
FileKind, // "file" | "directory"
|
|
173
|
+
BinaryStream, // AsyncIterable<Uint8Array> | Iterable<Uint8Array>
|
|
174
|
+
ListOptions, // { recursive?: boolean }
|
|
175
|
+
CopyOptions, // { recursive?: boolean }
|
|
176
|
+
ReadStreamOptions, // { start?: number, end?: number, signal?: AbortSignal }
|
|
177
|
+
WriteStreamOptions, // { start?: number, signal?: AbortSignal }
|
|
178
|
+
} from '@statewalker/webrun-files';
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
## Utility Functions
|
|
182
|
+
|
|
183
|
+
The package includes helpful utilities for working with paths and streams:
|
|
184
|
+
|
|
185
|
+
```typescript
|
|
186
|
+
import {
|
|
187
|
+
normalizePath, // Clean up path strings
|
|
188
|
+
resolveFileRef, // Convert FileRef to normalized path
|
|
189
|
+
joinPath, // Join path segments
|
|
190
|
+
dirname, // Get directory portion of path
|
|
191
|
+
basename, // Get filename portion
|
|
192
|
+
extname, // Get file extension
|
|
193
|
+
collectGenerator, // Collect async iterable into array
|
|
194
|
+
} from '@statewalker/webrun-files';
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
## License
|
|
198
|
+
|
|
199
|
+
MIT
|