opfs-worker 2.0.0 → 2.1.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 +62 -439
- package/dist/BaseOPFS-BPw9AIQ-.cjs +4 -0
- package/dist/BaseOPFS-BPw9AIQ-.cjs.map +1 -0
- package/dist/BaseOPFS-Cylz6ijk.js +2036 -0
- package/dist/BaseOPFS-Cylz6ijk.js.map +1 -0
- package/dist/OPFSAsync-BKSAJJeh.js +124 -0
- package/dist/OPFSAsync-BKSAJJeh.js.map +1 -0
- package/dist/OPFSAsync-s2P7y3sw.cjs +2 -0
- package/dist/OPFSAsync-s2P7y3sw.cjs.map +1 -0
- package/dist/OPFSFacade-DePnNRgt.cjs +2 -0
- package/dist/OPFSFacade-DePnNRgt.cjs.map +1 -0
- package/dist/OPFSFacade-XohWlHuu.js +281 -0
- package/dist/OPFSFacade-XohWlHuu.js.map +1 -0
- package/dist/OPFSSync-C7KBepe_.cjs +2 -0
- package/dist/OPFSSync-C7KBepe_.cjs.map +1 -0
- package/dist/OPFSSync-CsSQkpk5.js +208 -0
- package/dist/OPFSSync-CsSQkpk5.js.map +1 -0
- package/dist/assets/dedicated.worker-nY3tK4zi.js.map +1 -0
- package/dist/{OPFSWorker.d.ts → core/BaseOPFS.d.ts} +34 -304
- package/dist/core/BaseOPFS.d.ts.map +1 -0
- package/dist/core/OPFSAsync.d.ts +55 -0
- package/dist/core/OPFSAsync.d.ts.map +1 -0
- package/dist/core/OPFSSync.d.ts +54 -0
- package/dist/core/OPFSSync.d.ts.map +1 -0
- package/dist/createOPFSAsync-BwKDmHsy.cjs +2 -0
- package/dist/createOPFSAsync-BwKDmHsy.cjs.map +1 -0
- package/dist/createOPFSAsync-Y4Mg6qte.js +10 -0
- package/dist/createOPFSAsync-Y4Mg6qte.js.map +1 -0
- package/dist/createOPFSDedicated-CsnV6MLP.js +2333 -0
- package/dist/createOPFSDedicated-CsnV6MLP.js.map +1 -0
- package/dist/createOPFSDedicated-pKTRWLdz.cjs +2283 -0
- package/dist/createOPFSDedicated-pKTRWLdz.cjs.map +1 -0
- package/dist/createOPFSShared-CGdd__PH.js +23 -0
- package/dist/createOPFSShared-CGdd__PH.js.map +1 -0
- package/dist/createOPFSShared-CskROt7U.cjs +2 -0
- package/dist/createOPFSShared-CskROt7U.cjs.map +1 -0
- package/dist/dedicated.worker.js +2281 -0
- package/dist/dedicated.worker.js.map +1 -0
- package/dist/{OPFSFacade.d.ts → facade/OPFSFacade.d.ts} +31 -23
- package/dist/facade/OPFSFacade.d.ts.map +1 -0
- package/dist/facade/createOPFSAsync.d.ts +16 -0
- package/dist/facade/createOPFSAsync.d.ts.map +1 -0
- package/dist/facade/createOPFSDedicated.d.ts +17 -0
- package/dist/facade/createOPFSDedicated.d.ts.map +1 -0
- package/dist/facade/createOPFSShared.d.ts +24 -0
- package/dist/facade/createOPFSShared.d.ts.map +1 -0
- package/dist/index.async.cjs +2 -0
- package/dist/index.async.cjs.map +1 -0
- package/dist/index.async.d.ts +10 -0
- package/dist/index.async.d.ts.map +1 -0
- package/dist/index.async.js +55 -0
- package/dist/index.async.js.map +1 -0
- package/dist/index.cjs +1 -2477
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +17 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +61 -2828
- package/dist/index.js.map +1 -1
- package/dist/index.pure.cjs +1 -1
- package/dist/index.pure.cjs.map +1 -1
- package/dist/index.pure.d.ts +3 -1
- package/dist/index.pure.d.ts.map +1 -1
- package/dist/index.pure.js +50 -1053
- package/dist/index.pure.js.map +1 -1
- package/dist/index.sharedworker.cjs +2 -0
- package/dist/index.sharedworker.cjs.map +1 -0
- package/dist/index.sharedworker.d.ts +11 -0
- package/dist/index.sharedworker.d.ts.map +1 -0
- package/dist/index.sharedworker.js +55 -0
- package/dist/index.sharedworker.js.map +1 -0
- package/dist/index.sync.cjs +2 -0
- package/dist/index.sync.cjs.map +1 -0
- package/dist/index.sync.d.ts +11 -0
- package/dist/index.sync.d.ts.map +1 -0
- package/dist/index.sync.js +55 -0
- package/dist/index.sync.js.map +1 -0
- package/dist/shared.worker.js +2166 -0
- package/dist/shared.worker.js.map +1 -0
- package/dist/types.d.ts +9 -4
- package/dist/types.d.ts.map +1 -1
- package/dist/worker/createDedicatedWorker.d.ts +30 -0
- package/dist/worker/createDedicatedWorker.d.ts.map +1 -0
- package/dist/worker/createSharedWorker.d.ts +37 -0
- package/dist/worker/createSharedWorker.d.ts.map +1 -0
- package/dist/worker/dedicated.worker.d.ts +2 -0
- package/dist/worker/dedicated.worker.d.ts.map +1 -0
- package/dist/worker/shared.worker.d.ts +2 -0
- package/dist/worker/shared.worker.d.ts.map +1 -0
- package/docs/README.md +30 -0
- package/docs/api/backend.md +36 -0
- package/docs/api/create.md +82 -0
- package/docs/api/facade.md +52 -0
- package/docs/choosing-a-mode.md +41 -0
- package/docs/file-descriptors.md +8 -9
- package/docs/guides/async.md +36 -0
- package/docs/guides/dedicated.md +76 -0
- package/docs/guides/hashing.md +34 -0
- package/docs/guides/pure.md +46 -0
- package/docs/guides/sharedworker.md +57 -0
- package/docs/guides/streaming.md +51 -0
- package/docs/guides/watching.md +35 -0
- package/docs/migration.md +41 -0
- package/docs/types.md +20 -6
- package/package.json +42 -3
- package/src/{OPFSWorker.ts → core/BaseOPFS.ts} +54 -647
- package/src/core/OPFSAsync.ts +248 -0
- package/src/core/OPFSSync.ts +460 -0
- package/src/{OPFSFacade.ts → facade/OPFSFacade.ts} +83 -54
- package/src/facade/createOPFSAsync.ts +22 -0
- package/src/facade/createOPFSDedicated.ts +23 -0
- package/src/facade/createOPFSShared.ts +30 -0
- package/src/index.async.ts +11 -0
- package/src/index.pure.ts +3 -2
- package/src/index.sharedworker.ts +12 -0
- package/src/index.sync.ts +12 -0
- package/src/index.ts +37 -8
- package/src/types.ts +8 -4
- package/src/worker/createDedicatedWorker.ts +74 -0
- package/src/worker/createSharedWorker.ts +67 -0
- package/src/worker/dedicated.worker.ts +13 -0
- package/src/worker/shared.worker.ts +17 -0
- package/dist/OPFSFacade.d.ts.map +0 -1
- package/dist/OPFSWorker.d.ts.map +0 -1
- package/dist/assets/worker.entry-DUlEoroc.js.map +0 -1
- package/dist/createOPFSWorker.d.ts +0 -17
- package/dist/createOPFSWorker.d.ts.map +0 -1
- package/dist/helpers-DNj8ZoMu.cjs +0 -4
- package/dist/helpers-DNj8ZoMu.cjs.map +0 -1
- package/dist/helpers-WY2jfbOT.js +0 -1427
- package/dist/helpers-WY2jfbOT.js.map +0 -1
- package/dist/worker.entry.d.ts +0 -2
- package/dist/worker.entry.d.ts.map +0 -1
- package/docs/api-reference.md +0 -815
- package/src/createOPFSWorker.ts +0 -57
- package/src/worker.entry.ts +0 -6
package/docs/api-reference.md
DELETED
|
@@ -1,815 +0,0 @@
|
|
|
1
|
-
# API Reference
|
|
2
|
-
|
|
3
|
-
This document contains the complete API reference for OPFS Worker.
|
|
4
|
-
|
|
5
|
-
## Table of Contents
|
|
6
|
-
|
|
7
|
-
- [API Reference](#api-reference)
|
|
8
|
-
- [Table of Contents](#table-of-contents)
|
|
9
|
-
- [Entry Points](#entry-points)
|
|
10
|
-
- [Mode 1: Node-like facade](#mode-1-node-like-facade)
|
|
11
|
-
- [`createOPFS(options?: OPFSOptions)`](#createopfsoptions-opfsoptions)
|
|
12
|
-
- [Mode 2: Raw worker API from the main thread](#mode-2-raw-worker-api-from-the-main-thread)
|
|
13
|
-
- [`createOPFSWorker(options?: OPFSOptions)`](#createopfsworkeroptions-opfsoptions)
|
|
14
|
-
- [Mode 3: `OPFSWorker` inside your own worker](#mode-3-opfsworker-inside-your-own-worker)
|
|
15
|
-
- [`OPFSWorker` from `opfs-worker/pure`](#opfsworker-from-opfs-workerpure)
|
|
16
|
-
- [Core Methods](#core-methods)
|
|
17
|
-
- [Read File](#read-file)
|
|
18
|
-
- [`readFile(path: string, encoding?: Encoding | 'binary'): Promise<string | Uint8Array>`](#readfilepath-string-encoding-encoding--binary-promisestring--uint8array)
|
|
19
|
-
- [Write File](#write-file)
|
|
20
|
-
- [`writeFile(path: string, data: string | Uint8Array | ArrayBuffer, encoding?: Encoding): Promise<void>`](#writefilepath-string-data-string--uint8array--arraybuffer-encoding-encoding-promisevoid)
|
|
21
|
-
- [Append File](#append-file)
|
|
22
|
-
- [`appendFile(path: string, data: string | Uint8Array | ArrayBuffer, encoding?: Encoding): Promise<void>`](#appendfilepath-string-data-string--uint8array--arraybuffer-encoding-encoding-promisevoid)
|
|
23
|
-
- [Create Directory](#create-directory)
|
|
24
|
-
- [`mkdir(path: string, options?: { recursive?: boolean }): Promise<void>`](#mkdirpath-string-options--recursive-boolean--promisevoid)
|
|
25
|
-
- [Read Directory](#read-directory)
|
|
26
|
-
- [`readDir(path: string): Promise<DirentData[]>`](#readdirpath-string-promisedirentdata)
|
|
27
|
-
- [Get Stats](#get-stats)
|
|
28
|
-
- [`stat(path: string): Promise<FileStat>`](#statpath-string-promisefilestat)
|
|
29
|
-
- [Check Existence](#check-existence)
|
|
30
|
-
- [`exists(path: string): Promise<boolean>`](#existspath-string-promiseboolean)
|
|
31
|
-
- [Remove Path](#remove-path)
|
|
32
|
-
- [`remove(path: string, options?: { recursive?: boolean; force?: boolean }): Promise<void>`](#removepath-string-options--recursive-boolean-force-boolean--promisevoid)
|
|
33
|
-
- [Copy Path](#copy-path)
|
|
34
|
-
- [`copy(source: string, destination: string, options?: { recursive?: boolean; force?: boolean }): Promise<void>`](#copysource-string-destination-string-options--recursive-boolean-force-boolean--promisevoid)
|
|
35
|
-
- [Rename Path](#rename-path)
|
|
36
|
-
- [`rename(oldPath: string, newPath: string): Promise<void>`](#renameoldpath-string-newpath-string-promisevoid)
|
|
37
|
-
- [Clear Directory](#clear-directory)
|
|
38
|
-
- [`clear(path?: string): Promise<void>`](#clearpath-string-promisevoid)
|
|
39
|
-
- [Index File System](#index-file-system)
|
|
40
|
-
- [`index(): Promise<Map<string, FileStat>>`](#index-promisemapstring-filestat)
|
|
41
|
-
- [Sync File System](#sync-file-system)
|
|
42
|
-
- [`sync(entries: [string, string | Uint8Array | Blob][], options?: { cleanBefore?: boolean }): Promise<void>`](#syncentries-string-string--uint8array--blob-options--cleanbefore-boolean--promisevoid)
|
|
43
|
-
- [Watch](#watch)
|
|
44
|
-
- [`watch(path: string, options?: WatchOptions): Promise<void>`](#watchpath-string-options-watchoptions-promisevoid)
|
|
45
|
-
- [Watch Behavior](#watch-behavior)
|
|
46
|
-
- [Unwatch](#unwatch)
|
|
47
|
-
- [`unwatch(path: string): void`](#unwatchpath-string-void)
|
|
48
|
-
- [Dispose](#dispose)
|
|
49
|
-
- [`dispose(): void`](#dispose-void)
|
|
50
|
-
- [Configuration](#configuration)
|
|
51
|
-
- [`setOptions(options: { root?: string; hashAlgorithm?: null | false | 'etag' | 'SHA-1' | 'SHA-256' | 'SHA-384' | 'SHA-512'; maxFileSize?: number }): Promise<void>`](#setoptionsoptions--root-string-hashalgorithm-null--false--etag--sha-1--sha-256--sha-384--sha-512-maxfilesize-number--promisevoid)
|
|
52
|
-
- [Resolve Path](#resolve-path)
|
|
53
|
-
- [`realpath(path: string): Promise<string>`](#realpathpath-string-promisestring)
|
|
54
|
-
- [File Descriptors](#file-descriptors)
|
|
55
|
-
- [File Descriptors Overview](#file-descriptors-overview)
|
|
56
|
-
- [File Descriptor Methods](#file-descriptor-methods)
|
|
57
|
-
- [Binary File Handling](#binary-file-handling)
|
|
58
|
-
- [Reading Binary Files](#reading-binary-files)
|
|
59
|
-
- [Writing Binary Files](#writing-binary-files)
|
|
60
|
-
- [Working with Different Data Types](#working-with-different-data-types)
|
|
61
|
-
- [File Upload and Download](#file-upload-and-download)
|
|
62
|
-
- [Supported Encodings](#supported-encodings)
|
|
63
|
-
- [Utility Functions](#utility-functions)
|
|
64
|
-
- [Path Utilities](#path-utilities)
|
|
65
|
-
- [Data Conversion](#data-conversion)
|
|
66
|
-
- [File System Utilities](#file-system-utilities)
|
|
67
|
-
|
|
68
|
-
## Entry Points
|
|
69
|
-
|
|
70
|
-
### Mode 1: Node-like facade
|
|
71
|
-
|
|
72
|
-
#### `createOPFS(options?: OPFSOptions)`
|
|
73
|
-
|
|
74
|
-
Starts an inlined worker and returns a facade with a Node-like API (strings, encodings, auto-detection). Comlink is used under the hood.
|
|
75
|
-
|
|
76
|
-
```typescript
|
|
77
|
-
import { createOPFS } from 'opfs-worker';
|
|
78
|
-
|
|
79
|
-
const fs = createOPFS();
|
|
80
|
-
|
|
81
|
-
const fsCustom = createOPFS({
|
|
82
|
-
root: '/my-app',
|
|
83
|
-
hashAlgorithm: 'SHA-256',
|
|
84
|
-
broadcastChannel: 'my-app-events'
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
const channel = new BroadcastChannel('my-app-events');
|
|
88
|
-
channel.onmessage = (event) => {
|
|
89
|
-
console.log('File changed:', event.data);
|
|
90
|
-
};
|
|
91
|
-
```
|
|
92
|
-
|
|
93
|
-
**Parameters:**
|
|
94
|
-
|
|
95
|
-
- `options` (optional): Configuration options
|
|
96
|
-
- `root` (optional): Root path for the file system (default: '/')
|
|
97
|
-
- `namespace` (optional): Namespace for the file system (default: 'opfs-worker:${root}'), will be sent to the BroadcastChannel with each event
|
|
98
|
-
- `hashAlgorithm` (optional): Hash algorithm for file hashing
|
|
99
|
-
- `broadcastChannel` (optional): Custom name for the broadcast channel (default: 'opfs-worker')
|
|
100
|
-
|
|
101
|
-
**Returns:** `OPFSFacade`
|
|
102
|
-
|
|
103
|
-
### Mode 2: Raw worker API from the main thread
|
|
104
|
-
|
|
105
|
-
#### `createOPFSWorker(options?: OPFSOptions)`
|
|
106
|
-
|
|
107
|
-
Same entry as Mode 1, but without the facade. Returns a Comlink proxy to `OPFSWorker` (bytes in / bytes out). Useful if you want to wrap it yourself or prefer the lower-level API. The built-in `OPFSFacade` is itself built on this function, so it doubles as a reference implementation for your own wrapper.
|
|
108
|
-
|
|
109
|
-
```typescript
|
|
110
|
-
import { createOPFSWorker } from 'opfs-worker';
|
|
111
|
-
|
|
112
|
-
const { fs, worker, dispose } = createOPFSWorker({
|
|
113
|
-
root: '/my-app',
|
|
114
|
-
broadcastChannel: 'my-app-events',
|
|
115
|
-
});
|
|
116
|
-
|
|
117
|
-
await fs.writeFile('/config.json', new TextEncoder().encode('{}'));
|
|
118
|
-
dispose();
|
|
119
|
-
```
|
|
120
|
-
|
|
121
|
-
**Returns:** `{ fs, worker, dispose }` — `fs` is `RemoteOPFSWorker`, `worker` is the browser `Worker`, `dispose()` cleans up both.
|
|
122
|
-
|
|
123
|
-
**Deprecated aliases (1.x compatibility):** `createWorker` → `createOPFS`, `OPFSFileSystem` → `OPFSFacade`. `opfs-worker/raw` is removed — use `opfs-worker/pure`.
|
|
124
|
-
|
|
125
|
-
### Mode 3: `OPFSWorker` inside your own worker
|
|
126
|
-
|
|
127
|
-
#### `OPFSWorker` from `opfs-worker/pure`
|
|
128
|
-
|
|
129
|
-
Use the class directly inside a worker you control. No nested worker, no Comlink. How you bundle that worker and talk to the main thread is up to you.
|
|
130
|
-
|
|
131
|
-
```typescript
|
|
132
|
-
import { OPFSWorker } from 'opfs-worker/pure';
|
|
133
|
-
|
|
134
|
-
const fs = new OPFSWorker({
|
|
135
|
-
root: '/my-app',
|
|
136
|
-
broadcastChannel: 'my-app-events', // name only
|
|
137
|
-
});
|
|
138
|
-
|
|
139
|
-
await fs.writeFile('/config.json', new TextEncoder().encode('{}'));
|
|
140
|
-
```
|
|
141
|
-
|
|
142
|
-
`opfs-worker/pure` does not call Comlink `expose()`, so it will not take over your worker's message port.
|
|
143
|
-
|
|
144
|
-
## Core Methods
|
|
145
|
-
|
|
146
|
-
### Read File
|
|
147
|
-
|
|
148
|
-
#### `readFile(path: string, encoding?: Encoding | 'binary'): Promise<string | Uint8Array>`
|
|
149
|
-
|
|
150
|
-
Read a file from the file system. Supports both text and binary files.
|
|
151
|
-
|
|
152
|
-
```typescript
|
|
153
|
-
// Read as text (default)
|
|
154
|
-
const content = await fs.readFile('/config/settings.json');
|
|
155
|
-
|
|
156
|
-
// Read as binary
|
|
157
|
-
const binaryData = await fs.readFile('/images/logo.png', 'binary');
|
|
158
|
-
|
|
159
|
-
// Read with specific encoding
|
|
160
|
-
const utf8Content = await fs.readFile('/data/utf8.txt', 'utf-8');
|
|
161
|
-
|
|
162
|
-
// Handle binary data
|
|
163
|
-
const imageBuffer = await fs.readFile('/image.png', 'binary');
|
|
164
|
-
const blob = new Blob([imageBuffer], { type: 'image/png' });
|
|
165
|
-
const url = URL.createObjectURL(blob);
|
|
166
|
-
```
|
|
167
|
-
|
|
168
|
-
**Parameters:**
|
|
169
|
-
|
|
170
|
-
- `path`: The path to the file to read
|
|
171
|
-
- `encoding` (optional): The encoding to use ('utf-8', 'binary', 'utf-16le', 'ascii', 'latin1', 'base64', 'hex')
|
|
172
|
-
|
|
173
|
-
**Returns:** `Promise<string | Uint8Array>` - File contents as string or binary data
|
|
174
|
-
|
|
175
|
-
**Throws:** `ExistenceError` if the file doesn't exist
|
|
176
|
-
|
|
177
|
-
**Binary File Handling:**
|
|
178
|
-
|
|
179
|
-
- Use `'binary'` encoding to read files as `Uint8Array`
|
|
180
|
-
- Binary data can be converted to `Blob` for use with `URL.createObjectURL()`
|
|
181
|
-
- Supports various encodings for text files
|
|
182
|
-
|
|
183
|
-
### Write File
|
|
184
|
-
|
|
185
|
-
#### `writeFile(path: string, data: string | Uint8Array | ArrayBuffer, encoding?: Encoding): Promise<void>`
|
|
186
|
-
|
|
187
|
-
Write data to a file, creating or overwriting it. Supports both text and binary data.
|
|
188
|
-
|
|
189
|
-
```typescript
|
|
190
|
-
// Write text data
|
|
191
|
-
await fs.writeFile('/config/settings.json', JSON.stringify({ theme: 'dark' }));
|
|
192
|
-
|
|
193
|
-
// Write binary data
|
|
194
|
-
const binaryData = new Uint8Array([1, 2, 3, 4, 5]);
|
|
195
|
-
await fs.writeFile('/data/binary.dat', binaryData);
|
|
196
|
-
|
|
197
|
-
// Write with specific encoding
|
|
198
|
-
await fs.writeFile('/data/utf16.txt', 'Hello World', 'utf-16le');
|
|
199
|
-
|
|
200
|
-
// Write binary data from file input
|
|
201
|
-
const fileInput = document.getElementById('file') as HTMLInputElement;
|
|
202
|
-
const file = fileInput.files?.[0];
|
|
203
|
-
if (file) {
|
|
204
|
-
const arrayBuffer = await file.arrayBuffer();
|
|
205
|
-
await fs.writeFile('/uploaded-file', new Uint8Array(arrayBuffer));
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
// Write binary data from fetch
|
|
209
|
-
const response = await fetch('/api/image.png');
|
|
210
|
-
const arrayBuffer = await response.arrayBuffer();
|
|
211
|
-
await fs.writeFile('/downloaded-image.png', new Uint8Array(arrayBuffer));
|
|
212
|
-
```
|
|
213
|
-
|
|
214
|
-
**Parameters:**
|
|
215
|
-
|
|
216
|
-
- `path`: The path to the file to write
|
|
217
|
-
- `data`: The data to write (string, Uint8Array, or ArrayBuffer)
|
|
218
|
-
- `encoding` (optional): The encoding to use when writing string data ('utf-8', 'utf-16le', 'ascii', 'latin1', 'base64', 'hex')
|
|
219
|
-
|
|
220
|
-
**Binary File Handling:**
|
|
221
|
-
|
|
222
|
-
- Pass `Uint8Array` or `ArrayBuffer` directly for binary data
|
|
223
|
-
- Use with file uploads, image processing, or any binary content
|
|
224
|
-
- Supports various text encodings for string data
|
|
225
|
-
|
|
226
|
-
### Append File
|
|
227
|
-
|
|
228
|
-
#### `appendFile(path: string, data: string | Uint8Array | ArrayBuffer, encoding?: Encoding): Promise<void>`
|
|
229
|
-
|
|
230
|
-
Append data to the end of a file.
|
|
231
|
-
|
|
232
|
-
```typescript
|
|
233
|
-
// Append text to a log file
|
|
234
|
-
await fs.appendFile('/logs/app.log', `[${new Date().toISOString()}] User logged in\n`);
|
|
235
|
-
|
|
236
|
-
// Append binary data
|
|
237
|
-
const additionalData = new Uint8Array([6, 7, 8]);
|
|
238
|
-
await fs.appendFile('/data/binary.dat', additionalData);
|
|
239
|
-
```
|
|
240
|
-
|
|
241
|
-
### Create Directory
|
|
242
|
-
|
|
243
|
-
#### `mkdir(path: string, options?: { recursive?: boolean }): Promise<void>`
|
|
244
|
-
|
|
245
|
-
Create a directory.
|
|
246
|
-
|
|
247
|
-
```typescript
|
|
248
|
-
// Create a single directory
|
|
249
|
-
await fs.mkdir('/users/john');
|
|
250
|
-
|
|
251
|
-
// Create nested directories
|
|
252
|
-
await fs.mkdir('/users/john/documents/projects', { recursive: true });
|
|
253
|
-
```
|
|
254
|
-
|
|
255
|
-
**Parameters:**
|
|
256
|
-
|
|
257
|
-
- `path`: The path where the directory should be created
|
|
258
|
-
- `options.recursive` (optional): Whether to create parent directories if they don't exist
|
|
259
|
-
|
|
260
|
-
### Read Directory
|
|
261
|
-
|
|
262
|
-
#### `readDir(path: string): Promise<DirentData[]>`
|
|
263
|
-
|
|
264
|
-
Read a directory's contents.
|
|
265
|
-
|
|
266
|
-
```typescript
|
|
267
|
-
// Get simple list of names
|
|
268
|
-
const files = await fs.readDir('/users/john/documents');
|
|
269
|
-
console.log('Files:', files); // ['readme.txt', 'config.json', 'images']
|
|
270
|
-
|
|
271
|
-
// Get detailed information
|
|
272
|
-
const detailed = await fs.readDir('/users/john/documents');
|
|
273
|
-
detailed.forEach(item => {
|
|
274
|
-
console.log(`${item.name} - ${item.isFile ? 'file' : 'directory'}`);
|
|
275
|
-
});
|
|
276
|
-
```
|
|
277
|
-
|
|
278
|
-
**Returns:**
|
|
279
|
-
|
|
280
|
-
- `Promise<DirentData[]>` - Always returns detailed file/directory information
|
|
281
|
-
|
|
282
|
-
### Get Stats
|
|
283
|
-
|
|
284
|
-
#### `stat(path: string): Promise<FileStat>`
|
|
285
|
-
|
|
286
|
-
Get file or directory statistics. If hashing is enabled globally, file hashes will be included automatically.
|
|
287
|
-
|
|
288
|
-
```typescript
|
|
289
|
-
// Basic stats
|
|
290
|
-
const stats = await fs.stat('/config/settings.json');
|
|
291
|
-
console.log(`File size: ${stats.size} bytes`);
|
|
292
|
-
console.log(`Is file: ${stats.isFile}`);
|
|
293
|
-
console.log(`Modified: ${stats.mtime}`);
|
|
294
|
-
|
|
295
|
-
// If hashing is enabled globally, hash will be included
|
|
296
|
-
if (stats.hash) {
|
|
297
|
-
console.log(`Hash: ${stats.hash}`);
|
|
298
|
-
}
|
|
299
|
-
```
|
|
300
|
-
|
|
301
|
-
**Parameters:**
|
|
302
|
-
|
|
303
|
-
- `path`: The path to the file or directory
|
|
304
|
-
|
|
305
|
-
**Returns:** `Promise<FileStat>` - File/directory statistics
|
|
306
|
-
|
|
307
|
-
**Note:** File hashing is controlled globally via the constructor options or `setOptions()` method. When enabled, all file stats will automatically include hash information.
|
|
308
|
-
|
|
309
|
-
### Check Existence
|
|
310
|
-
|
|
311
|
-
#### `exists(path: string): Promise<boolean>`
|
|
312
|
-
|
|
313
|
-
Check if a file or directory exists.
|
|
314
|
-
|
|
315
|
-
```typescript
|
|
316
|
-
const exists = await fs.exists('/config/settings.json');
|
|
317
|
-
console.log(`File exists: ${exists}`);
|
|
318
|
-
```
|
|
319
|
-
|
|
320
|
-
**Returns:** `Promise<boolean>` - True if the file or directory exists
|
|
321
|
-
|
|
322
|
-
### Remove Path
|
|
323
|
-
|
|
324
|
-
#### `remove(path: string, options?: { recursive?: boolean; force?: boolean }): Promise<void>`
|
|
325
|
-
|
|
326
|
-
Remove files and directories.
|
|
327
|
-
|
|
328
|
-
```typescript
|
|
329
|
-
// Remove a file
|
|
330
|
-
await fs.remove('/path/to/file.txt');
|
|
331
|
-
|
|
332
|
-
// Remove a directory and all its contents
|
|
333
|
-
await fs.remove('/path/to/directory', { recursive: true });
|
|
334
|
-
|
|
335
|
-
// Remove with force (ignore if doesn't exist)
|
|
336
|
-
await fs.remove('/maybe/exists', { force: true });
|
|
337
|
-
```
|
|
338
|
-
|
|
339
|
-
**Parameters:**
|
|
340
|
-
|
|
341
|
-
- `path`: The path to remove
|
|
342
|
-
- `options.recursive` (optional): Whether to remove directories recursively (default: false)
|
|
343
|
-
- `options.force` (optional): Whether to ignore errors if the path doesn't exist (default: false)
|
|
344
|
-
|
|
345
|
-
### Copy Path
|
|
346
|
-
|
|
347
|
-
#### `copy(source: string, destination: string, options?: { recursive?: boolean; force?: boolean }): Promise<void>`
|
|
348
|
-
|
|
349
|
-
Copy files and directories.
|
|
350
|
-
|
|
351
|
-
```typescript
|
|
352
|
-
// Copy a file
|
|
353
|
-
await fs.copy('/source/file.txt', '/dest/file.txt');
|
|
354
|
-
|
|
355
|
-
// Copy a directory and all its contents
|
|
356
|
-
await fs.copy('/source/dir', '/dest/dir', { recursive: true });
|
|
357
|
-
|
|
358
|
-
// Copy without overwriting existing files
|
|
359
|
-
await fs.copy('/source', '/dest', { recursive: true, force: false });
|
|
360
|
-
```
|
|
361
|
-
|
|
362
|
-
**Parameters:**
|
|
363
|
-
|
|
364
|
-
- `source`: The source path to copy from
|
|
365
|
-
- `destination`: The destination path to copy to
|
|
366
|
-
- `options.recursive` (optional): Whether to copy directories recursively (default: false)
|
|
367
|
-
- `options.force` (optional): Whether to overwrite existing files (default: true)
|
|
368
|
-
|
|
369
|
-
### Rename Path
|
|
370
|
-
|
|
371
|
-
#### `rename(oldPath: string, newPath: string): Promise<void>`
|
|
372
|
-
|
|
373
|
-
Rename a file or directory.
|
|
374
|
-
|
|
375
|
-
```typescript
|
|
376
|
-
await fs.rename('/old/path/file.txt', '/new/path/renamed.txt');
|
|
377
|
-
```
|
|
378
|
-
|
|
379
|
-
**Parameters:**
|
|
380
|
-
|
|
381
|
-
- `oldPath`: The current path of the file or directory
|
|
382
|
-
- `newPath`: The new path for the file or directory
|
|
383
|
-
|
|
384
|
-
### Clear Directory
|
|
385
|
-
|
|
386
|
-
#### `clear(path?: string): Promise<void>`
|
|
387
|
-
|
|
388
|
-
Clear all contents of a directory without removing the directory itself.
|
|
389
|
-
|
|
390
|
-
```typescript
|
|
391
|
-
// Clear root directory contents
|
|
392
|
-
await fs.clear('/');
|
|
393
|
-
|
|
394
|
-
// Clear specific directory contents
|
|
395
|
-
await fs.clear('/data');
|
|
396
|
-
```
|
|
397
|
-
|
|
398
|
-
**Parameters:**
|
|
399
|
-
|
|
400
|
-
- `path` (optional): The path to the directory to clear (default: '/')
|
|
401
|
-
|
|
402
|
-
### Index File System
|
|
403
|
-
|
|
404
|
-
#### `index(): Promise<Map<string, FileStat>>`
|
|
405
|
-
|
|
406
|
-
Recursively list all files and directories with their stats. If hashing is enabled globally, file hashes will be included automatically.
|
|
407
|
-
|
|
408
|
-
```typescript
|
|
409
|
-
// Get complete file system index
|
|
410
|
-
const index = await fs.index();
|
|
411
|
-
|
|
412
|
-
// Iterate through all files and directories
|
|
413
|
-
for (const [path, stat] of index) {
|
|
414
|
-
console.log(`${path}: ${stat.isFile ? 'file' : 'directory'} (${stat.size} bytes)`);
|
|
415
|
-
if (stat.hash) console.log(` Hash: ${stat.hash}`);
|
|
416
|
-
}
|
|
417
|
-
|
|
418
|
-
// Get specific file stats
|
|
419
|
-
const fileStats = index.get('/data/config.json');
|
|
420
|
-
if (fileStats) {
|
|
421
|
-
console.log(`File size: ${fileStats.size} bytes`);
|
|
422
|
-
if (fileStats.hash) console.log(`Hash: ${fileStats.hash}`);
|
|
423
|
-
}
|
|
424
|
-
```
|
|
425
|
-
|
|
426
|
-
**Returns:** `Promise<Map<string, FileStat>>` - Map of path => FileStat
|
|
427
|
-
|
|
428
|
-
**Note:** File hashing is controlled globally via the constructor options or `setOptions()` method. When enabled, all file stats in the index will automatically include hash information.
|
|
429
|
-
|
|
430
|
-
### Sync File System
|
|
431
|
-
|
|
432
|
-
#### `sync(entries: [string, string | Uint8Array | Blob][], options?: { cleanBefore?: boolean }): Promise<void>`
|
|
433
|
-
|
|
434
|
-
Synchronize the file system with external data.
|
|
435
|
-
|
|
436
|
-
```typescript
|
|
437
|
-
// Sync with external data
|
|
438
|
-
const entries: [string, string | Uint8Array | Blob][] = [
|
|
439
|
-
['/config.json', JSON.stringify({ theme: 'dark' })],
|
|
440
|
-
['/data/binary.dat', new Uint8Array([1, 2, 3, 4])],
|
|
441
|
-
['/upload.txt', new Blob(['file content'], { type: 'text/plain' })]
|
|
442
|
-
];
|
|
443
|
-
|
|
444
|
-
// Sync without clearing existing files
|
|
445
|
-
await fs.sync(entries);
|
|
446
|
-
|
|
447
|
-
// Clean file system and then sync
|
|
448
|
-
await fs.sync(entries, { cleanBefore: true });
|
|
449
|
-
```
|
|
450
|
-
|
|
451
|
-
**Parameters:**
|
|
452
|
-
|
|
453
|
-
- `entries`: Array of [path, data] tuples to sync
|
|
454
|
-
- `options.cleanBefore` (optional): Whether to clear the file system before syncing (default: false)
|
|
455
|
-
|
|
456
|
-
### Watch
|
|
457
|
-
|
|
458
|
-
#### `watch(path: string, options?: WatchOptions): Promise<void>`
|
|
459
|
-
|
|
460
|
-
Start watching a file or directory for changes. Detected changes are sent via BroadcastChannel
|
|
461
|
-
using the channel name specified in the `broadcastChannel` option.
|
|
462
|
-
|
|
463
|
-
```typescript
|
|
464
|
-
// Start watching a directory recursively (default behavior)
|
|
465
|
-
await fs.watch('/docs');
|
|
466
|
-
|
|
467
|
-
// Start watching a directory shallow (only immediate children)
|
|
468
|
-
await fs.watch('/docs', { recursive: false });
|
|
469
|
-
|
|
470
|
-
// Watch a single file (non-recursive)
|
|
471
|
-
await fs.watch('/config.json', { recursive: false });
|
|
472
|
-
|
|
473
|
-
// Watch with minimatch patterns and include/exclude options
|
|
474
|
-
await fs.watch('/**/*.js', {
|
|
475
|
-
recursive: true,
|
|
476
|
-
include: ['**/*.js', '**/*.ts'],
|
|
477
|
-
exclude: ['**/dist/**', '**/node_modules/**']
|
|
478
|
-
});
|
|
479
|
-
|
|
480
|
-
// Listen for changes via BroadcastChannel
|
|
481
|
-
const channel = new BroadcastChannel('opfs-worker'); // or your custom channel name
|
|
482
|
-
channel.onmessage = (event) => {
|
|
483
|
-
const { path, type, isDirectory, timestamp, hash } = event.data;
|
|
484
|
-
console.log(`File ${path} was ${type} at ${timestamp}`);
|
|
485
|
-
if (hash) console.log(`Hash: ${hash}`);
|
|
486
|
-
};
|
|
487
|
-
```
|
|
488
|
-
|
|
489
|
-
**Parameters:**
|
|
490
|
-
|
|
491
|
-
- `path`: File or directory to watch (supports minimatch glob patterns)
|
|
492
|
-
- `options` (optional): Watch options
|
|
493
|
-
- `options.recursive` (optional): Whether to watch recursively (default: `true`)
|
|
494
|
-
- `true`: Watch the entire directory tree
|
|
495
|
-
- `false`: Only watch the specified path and its immediate children (shallow watching)
|
|
496
|
-
- `options.include` (optional): Glob patterns to include in watching (minimatch syntax, default: `['**']`)
|
|
497
|
-
- `options.exclude` (optional): Glob patterns to exclude from watching (minimatch syntax, default: `[]`)
|
|
498
|
-
|
|
499
|
-
**Note:** File change events are sent via BroadcastChannel. Set the `broadcastChannel` option to customize the channel name, or use the default 'opfs-worker' channel. The `createOPFS()` function automatically handles the BroadcastChannel setup.
|
|
500
|
-
|
|
501
|
-
#### Watch Behavior
|
|
502
|
-
|
|
503
|
-
The watch system provides real-time change detection with the following characteristics:
|
|
504
|
-
|
|
505
|
-
- **Immediate Events**: Events are sent immediately when file system operations occur
|
|
506
|
-
- **Watched Paths Only**: Events are only sent for paths that are actively being watched
|
|
507
|
-
- **Minimatch Support**: Watch paths support glob patterns like `/**/*.js`, `*.txt`, etc.
|
|
508
|
-
- **Include/Exclude Filters**: Fine-grained control over which files trigger events
|
|
509
|
-
- **Internal Changes Only**: The worker detects changes made through its own operations
|
|
510
|
-
- **Efficient**: Only watched paths generate events, reducing unnecessary broadcasts
|
|
511
|
-
|
|
512
|
-
**Example Watch Patterns:**
|
|
513
|
-
|
|
514
|
-
```typescript
|
|
515
|
-
// Watch all JavaScript files recursively
|
|
516
|
-
await fs.watch('/**/*.js');
|
|
517
|
-
|
|
518
|
-
// Watch source files but exclude build artifacts
|
|
519
|
-
await fs.watch('/', {
|
|
520
|
-
recursive: true,
|
|
521
|
-
include: ['**/*.ts', '**/*.js', '**/*.tsx', '**/*.jsx'],
|
|
522
|
-
exclude: ['**/node_modules/**', '**/dist/**', '**/*.d.ts']
|
|
523
|
-
});
|
|
524
|
-
|
|
525
|
-
// Watch immediate children only (shallow)
|
|
526
|
-
await fs.watch('/data/*', { recursive: false });
|
|
527
|
-
|
|
528
|
-
// Watch specific file types in multiple directories
|
|
529
|
-
await fs.watch('/**/*.{json,yaml,yml}');
|
|
530
|
-
```
|
|
531
|
-
|
|
532
|
-
### Unwatch
|
|
533
|
-
|
|
534
|
-
#### `unwatch(path: string): void`
|
|
535
|
-
|
|
536
|
-
Stop watching a watched path.
|
|
537
|
-
|
|
538
|
-
```typescript
|
|
539
|
-
fs.unwatch('/docs');
|
|
540
|
-
```
|
|
541
|
-
|
|
542
|
-
### Dispose
|
|
543
|
-
|
|
544
|
-
#### `dispose(): void`
|
|
545
|
-
|
|
546
|
-
Dispose of resources and clean up the file system instance. This method should be called when the file system instance is no longer needed to properly clean up resources like the broadcast channel and watch timers.
|
|
547
|
-
|
|
548
|
-
```typescript
|
|
549
|
-
// Clean up resources when done
|
|
550
|
-
fs.dispose();
|
|
551
|
-
```
|
|
552
|
-
|
|
553
|
-
**Note:** This method closes the broadcast channel, clears watch timers, and cleans up all watched paths. Call this when you're done with the file system instance to prevent memory leaks.
|
|
554
|
-
|
|
555
|
-
### Configuration
|
|
556
|
-
|
|
557
|
-
#### `setOptions(options: { root?: string; hashAlgorithm?: null | false | 'etag' | 'SHA-1' | 'SHA-256' | 'SHA-384' | 'SHA-512'; maxFileSize?: number }): Promise<void>`
|
|
558
|
-
|
|
559
|
-
Update configuration options for the file system, including root path, hash algorithm, and maximum file size for hashing.
|
|
560
|
-
|
|
561
|
-
```typescript
|
|
562
|
-
// Change root path (automatically remounts)
|
|
563
|
-
await fs.setOptions({ root: '/new-app' });
|
|
564
|
-
|
|
565
|
-
// Default is 'etag' (mtime + size, no content read). Opt into SHA when needed:
|
|
566
|
-
await fs.setOptions({ hashAlgorithm: 'SHA-256' });
|
|
567
|
-
|
|
568
|
-
// Set custom maximum file size for SHA-* hashing (100MB)
|
|
569
|
-
await fs.setOptions({ maxFileSize: 100 * 1024 * 1024 });
|
|
570
|
-
|
|
571
|
-
// Disable hashing
|
|
572
|
-
await fs.setOptions({ hashAlgorithm: null });
|
|
573
|
-
|
|
574
|
-
// Update multiple options at once
|
|
575
|
-
await fs.setOptions({
|
|
576
|
-
root: '/my-app',
|
|
577
|
-
hashAlgorithm: 'etag',
|
|
578
|
-
maxFileSize: 50 * 1024 * 1024 // 50MB (only used by SHA-*)
|
|
579
|
-
});
|
|
580
|
-
```
|
|
581
|
-
|
|
582
|
-
**Parameters:**
|
|
583
|
-
|
|
584
|
-
- `options.root` (optional): Root path for the file system
|
|
585
|
-
- `options.hashAlgorithm` (optional): `'etag'` (default), `'SHA-*'`, or `null`/`false` to disable
|
|
586
|
-
- `options.maxFileSize` (optional): Maximum file size in bytes for SHA-\* hashing (default: 50MB); ignored by `'etag'`
|
|
587
|
-
|
|
588
|
-
**Note:** When the `root` option is changed, the file system automatically remounts to the new location. All other options are updated immediately.
|
|
589
|
-
|
|
590
|
-
### Resolve Path
|
|
591
|
-
|
|
592
|
-
#### `realpath(path: string): Promise<string>`
|
|
593
|
-
|
|
594
|
-
Resolve a path to an absolute path.
|
|
595
|
-
|
|
596
|
-
```typescript
|
|
597
|
-
// Resolve relative path
|
|
598
|
-
const absolute = await fs.realpath('./config/../data/file.txt');
|
|
599
|
-
console.log(absolute); // '/data/file.txt'
|
|
600
|
-
```
|
|
601
|
-
|
|
602
|
-
**Returns:** `Promise<string>` - The absolute normalized path
|
|
603
|
-
|
|
604
|
-
**Throws:** `ExistenceError` if the path doesn't exist
|
|
605
|
-
|
|
606
|
-
## File Descriptors
|
|
607
|
-
|
|
608
|
-
OPFS Worker provides low-level file I/O operations through file descriptors, similar to POSIX file descriptors. File descriptors are useful for:
|
|
609
|
-
|
|
610
|
-
- **Large file operations**: Reading/writing files in chunks without loading entire content into memory
|
|
611
|
-
- **Streaming operations**: Processing files sequentially or in specific positions
|
|
612
|
-
- **Performance-critical applications**: Direct file access without the overhead of high-level methods
|
|
613
|
-
- **Binary data manipulation**: Working with raw bytes at specific file positions
|
|
614
|
-
|
|
615
|
-
For comprehensive documentation on file descriptors, see [File Descriptors Guide](file-descriptors.md).
|
|
616
|
-
|
|
617
|
-
### File Descriptors Overview
|
|
618
|
-
|
|
619
|
-
File descriptors provide efficient, low-level access to files for reading, writing, and manipulating file data. They maintain a current position that advances with read/write operations and support both sequential and random access patterns.
|
|
620
|
-
|
|
621
|
-
**Key Benefits:**
|
|
622
|
-
|
|
623
|
-
- **Efficient I/O**: Direct access to file data without intermediate buffers
|
|
624
|
-
- **Position control**: Read/write at specific file positions or advance automatically
|
|
625
|
-
- **Resource management**: Automatic cleanup when closed
|
|
626
|
-
- **Performance**: Better for large files and streaming operations
|
|
627
|
-
|
|
628
|
-
### File Descriptor Methods
|
|
629
|
-
|
|
630
|
-
The following methods are available for working with file descriptors:
|
|
631
|
-
|
|
632
|
-
- **`open(path, options?)`** - Open a file and return a file descriptor
|
|
633
|
-
- **`read(fd, buffer, offset, length, position?)`** - Read data from a file descriptor
|
|
634
|
-
- **`write(fd, buffer, offset?, length?, position?)`** - Write data to a file descriptor
|
|
635
|
-
- **`fstat(fd)`** - Get file status information by file descriptor
|
|
636
|
-
- **`ftruncate(fd, size?)`** - Truncate file to specified size
|
|
637
|
-
- **`fsync(fd)`** - Synchronize file data to storage
|
|
638
|
-
- **`close(fd)`** - Close a file descriptor
|
|
639
|
-
|
|
640
|
-
**Quick Example:**
|
|
641
|
-
|
|
642
|
-
```typescript
|
|
643
|
-
const fd = await fs.open('/data/file.txt');
|
|
644
|
-
const buffer = new Uint8Array(1024);
|
|
645
|
-
const bytesRead = await fs.read(fd, buffer, 0, 1024, null);
|
|
646
|
-
console.log(`Read ${bytesRead} bytes`);
|
|
647
|
-
await fs.close(fd);
|
|
648
|
-
```
|
|
649
|
-
|
|
650
|
-
**Important:** Always close file descriptors when you're done with them to prevent resource leaks.
|
|
651
|
-
|
|
652
|
-
## Binary File Handling
|
|
653
|
-
|
|
654
|
-
This library provides comprehensive support for binary files, making it easy to work with images, documents, and other binary data.
|
|
655
|
-
|
|
656
|
-
### Reading Binary Files
|
|
657
|
-
|
|
658
|
-
```typescript
|
|
659
|
-
// Read as binary data
|
|
660
|
-
const imageData = await fs.readFile('/image.png', 'binary');
|
|
661
|
-
const documentData = await fs.readFile('/document.pdf', 'binary');
|
|
662
|
-
|
|
663
|
-
// Convert to Blob for use with URLs
|
|
664
|
-
const imageBuffer = await fs.readFile('/image.png', 'binary');
|
|
665
|
-
const blob = new Blob([imageBuffer], { type: 'image/png' });
|
|
666
|
-
const url = URL.createObjectURL(blob);
|
|
667
|
-
|
|
668
|
-
// Display image
|
|
669
|
-
const img = document.createElement('img');
|
|
670
|
-
img.src = url;
|
|
671
|
-
document.body.appendChild(img);
|
|
672
|
-
```
|
|
673
|
-
|
|
674
|
-
### Writing Binary Files
|
|
675
|
-
|
|
676
|
-
```typescript
|
|
677
|
-
// Write binary data directly
|
|
678
|
-
const binaryData = new Uint8Array([1, 2, 3, 4, 5]);
|
|
679
|
-
await fs.writeFile('/data.bin', binaryData);
|
|
680
|
-
|
|
681
|
-
// From file input
|
|
682
|
-
const fileInput = document.getElementById('file') as HTMLInputElement;
|
|
683
|
-
const file = fileInput.files?.[0];
|
|
684
|
-
if (file) {
|
|
685
|
-
const arrayBuffer = await file.arrayBuffer();
|
|
686
|
-
await fs.writeFile('/uploaded-file', new Uint8Array(arrayBuffer));
|
|
687
|
-
}
|
|
688
|
-
|
|
689
|
-
// From fetch response
|
|
690
|
-
const response = await fetch('/api/download/file.pdf');
|
|
691
|
-
const arrayBuffer = await response.arrayBuffer();
|
|
692
|
-
await fs.writeFile('/downloaded-file.pdf', new Uint8Array(arrayBuffer));
|
|
693
|
-
|
|
694
|
-
// From canvas
|
|
695
|
-
const canvas = document.createElement('canvas');
|
|
696
|
-
const ctx = canvas.getContext('2d');
|
|
697
|
-
// ... draw something ...
|
|
698
|
-
canvas.toBlob(async (blob) => {
|
|
699
|
-
if (blob) {
|
|
700
|
-
const arrayBuffer = await blob.arrayBuffer();
|
|
701
|
-
await fs.writeFile('/canvas-image.png', new Uint8Array(arrayBuffer));
|
|
702
|
-
}
|
|
703
|
-
});
|
|
704
|
-
```
|
|
705
|
-
|
|
706
|
-
### Working with Different Data Types
|
|
707
|
-
|
|
708
|
-
```typescript
|
|
709
|
-
// Convert between different binary formats
|
|
710
|
-
const uint8Array = new Uint8Array([1, 2, 3, 4, 5]);
|
|
711
|
-
const arrayBuffer = uint8Array.buffer;
|
|
712
|
-
|
|
713
|
-
// All of these work the same way
|
|
714
|
-
await fs.writeFile('/data1.bin', uint8Array);
|
|
715
|
-
await fs.writeFile('/data2.bin', arrayBuffer);
|
|
716
|
-
await fs.writeFile('/data3.bin', new Uint8Array(arrayBuffer));
|
|
717
|
-
|
|
718
|
-
// Read back as binary
|
|
719
|
-
const data = await fs.readFile('/data1.bin', 'binary');
|
|
720
|
-
console.log(data); // Uint8Array
|
|
721
|
-
```
|
|
722
|
-
|
|
723
|
-
### File Upload and Download
|
|
724
|
-
|
|
725
|
-
```typescript
|
|
726
|
-
// Handle file uploads
|
|
727
|
-
const handleFileUpload = async (file: File) => {
|
|
728
|
-
const arrayBuffer = await file.arrayBuffer();
|
|
729
|
-
await fs.writeFile(`/uploads/${file.name}`, new Uint8Array(arrayBuffer));
|
|
730
|
-
};
|
|
731
|
-
|
|
732
|
-
// Create downloadable files
|
|
733
|
-
const createDownloadLink = async (filePath: string, fileName: string) => {
|
|
734
|
-
const data = await fs.readFile(filePath, 'binary');
|
|
735
|
-
const blob = new Blob([data]);
|
|
736
|
-
const url = URL.createObjectURL(blob);
|
|
737
|
-
|
|
738
|
-
const a = document.createElement('a');
|
|
739
|
-
a.href = url;
|
|
740
|
-
a.download = fileName;
|
|
741
|
-
a.click();
|
|
742
|
-
|
|
743
|
-
URL.revokeObjectURL(url);
|
|
744
|
-
};
|
|
745
|
-
```
|
|
746
|
-
|
|
747
|
-
### Supported Encodings
|
|
748
|
-
|
|
749
|
-
The library supports various encodings for text files:
|
|
750
|
-
|
|
751
|
-
- `'utf-8'` (default) - UTF-8 encoding
|
|
752
|
-
- `'utf-16le'` - UTF-16 little-endian
|
|
753
|
-
- `'ascii'` - ASCII encoding
|
|
754
|
-
- `'latin1'` - Latin-1 encoding
|
|
755
|
-
- `'base64'` - Base64 encoding
|
|
756
|
-
- `'hex'` - Hexadecimal encoding
|
|
757
|
-
- `'binary'` - Raw binary data (returns Uint8Array)
|
|
758
|
-
|
|
759
|
-
## Utility Functions
|
|
760
|
-
|
|
761
|
-
The library exports several utility functions that can be used independently:
|
|
762
|
-
|
|
763
|
-
### Path Utilities
|
|
764
|
-
|
|
765
|
-
```typescript
|
|
766
|
-
import { basename, dirname, normalizePath, resolvePath, extname } from 'opfs-worker';
|
|
767
|
-
|
|
768
|
-
// Extract filename from path
|
|
769
|
-
basename('/path/to/file.txt'); // 'file.txt'
|
|
770
|
-
basename('/path/to/directory/'); // ''
|
|
771
|
-
|
|
772
|
-
// Extract directory path
|
|
773
|
-
dirname('/path/to/file.txt'); // '/path/to'
|
|
774
|
-
dirname('file.txt'); // '/'
|
|
775
|
-
|
|
776
|
-
// Normalize path to start with '/'
|
|
777
|
-
normalizePath('path/to/file'); // '/path/to/file'
|
|
778
|
-
normalizePath('/path/to/file'); // '/path/to/file'
|
|
779
|
-
|
|
780
|
-
// Resolve relative paths
|
|
781
|
-
resolvePath('./config/../data/file.txt'); // '/data/file.txt'
|
|
782
|
-
resolvePath('/path/to/../file.txt'); // '/path/file.txt'
|
|
783
|
-
|
|
784
|
-
// Get file extension
|
|
785
|
-
extname('/path/to/file.txt'); // '.txt'
|
|
786
|
-
extname('/path/to/file'); // ''
|
|
787
|
-
extname('/path/to/file.name.ext'); // '.ext'
|
|
788
|
-
```
|
|
789
|
-
|
|
790
|
-
### Data Conversion
|
|
791
|
-
|
|
792
|
-
```typescript
|
|
793
|
-
import { convertBlobToUint8Array } from 'opfs-worker';
|
|
794
|
-
|
|
795
|
-
// Convert Blob to Uint8Array
|
|
796
|
-
const fileInput = document.getElementById('file') as HTMLInputElement;
|
|
797
|
-
const file = fileInput.files?.[0];
|
|
798
|
-
if (file) {
|
|
799
|
-
const data = await convertBlobToUint8Array(file);
|
|
800
|
-
await fs.writeFile('/uploaded-file', data);
|
|
801
|
-
}
|
|
802
|
-
```
|
|
803
|
-
|
|
804
|
-
### File System Utilities
|
|
805
|
-
|
|
806
|
-
```typescript
|
|
807
|
-
import { checkOPFSSupport, splitPath, joinPath } from 'opfs-worker';
|
|
808
|
-
|
|
809
|
-
// Check if browser supports OPFS
|
|
810
|
-
checkOPFSSupport(); // Throws error if not supported
|
|
811
|
-
|
|
812
|
-
// Path manipulation
|
|
813
|
-
splitPath('/path/to/file'); // ['path', 'to', 'file']
|
|
814
|
-
joinPath(['path', 'to', 'file']); // '/path/to/file'
|
|
815
|
-
```
|