-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathbasic.ts
More file actions
195 lines (166 loc) · 7.69 KB
/
basic.ts
File metadata and controls
195 lines (166 loc) · 7.69 KB
1
2
3
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
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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
/**
* Basic Usage Example
*
* Demonstrates:
* - Check OPFS support
* - Create directories
* - Write and read files
* - Copy and move files
* - List directory contents
* - Remove files and directories
*/
import * as fs from '../src/mod.ts';
const output = document.getElementById('output')!;
function log(message: string, isError = false): void {
const line = document.createElement('div');
line.className = isError ? 'error' : 'success';
line.textContent = message;
output.appendChild(line);
console.log(message);
}
async function runExample(): Promise<void> {
output.textContent = '';
// 1. Check OPFS support
log('=== Checking OPFS Support ===');
if (!fs.isOPFSSupported()) {
log('OPFS is not supported in this browser!', true);
return;
}
log('✓ OPFS is supported');
// 2. Clean up from previous runs
log('\n=== Cleanup ===');
await fs.remove('/example');
log('✓ Cleaned up /example directory');
// 3. Create directory structure (mkdir is recursive by default)
log('\n=== Creating Directories ===');
const mkdirResult = await fs.mkdir('/example/data');
mkdirResult.inspect(() => log('✓ Created /example/data'));
mkdirResult.inspectErr((err) => log(`✗ Failed to create directory: ${err.message}`, true));
// 4. Write files
log('\n=== Writing Files ===');
const writeResult = await fs.writeFile('/example/data/hello.txt', 'Hello, OPFS!');
writeResult.inspect(() => log('✓ Wrote /example/data/hello.txt'));
writeResult.inspectErr((err) => log(`✗ Failed to write file: ${err.message}`, true));
// Write JSON file
const jsonResult = await fs.writeJsonFile('/example/data/config.json', {
name: 'happy-opfs',
version: '1.0.0',
features: ['read', 'write', 'zip'],
});
jsonResult.inspect(() => log('✓ Wrote /example/data/config.json'));
jsonResult.inspectErr((err) => log(`✗ Failed to write JSON: ${err.message}`, true));
// 5. Read files
log('\n=== Reading Files ===');
const readResult = await fs.readTextFile('/example/data/hello.txt');
readResult.inspect((content) => log(`✓ Read hello.txt: "${content}"`));
readResult.inspectErr((err) => log(`✗ Failed to read file: ${err.message}`, true));
const jsonReadResult = await fs.readJsonFile<{ name: string; version: string; }>('/example/data/config.json');
jsonReadResult.inspect((data) => log(`✓ Read config.json: name=${data.name}, version=${data.version}`));
jsonReadResult.inspectErr((err) => log(`✗ Failed to read JSON: ${err.message}`, true));
// 6. Copy file
log('\n=== Copying Files ===');
const copyResult = await fs.copy('/example/data/hello.txt', '/example/data/backup.txt');
copyResult.inspect(() => log('✓ Copied hello.txt to backup.txt'));
copyResult.inspectErr((err) => log(`✗ Failed to copy file: ${err.message}`, true));
// 6.1 Copy directory with structure comparison
log('\n=== Copying Directory (Structure Comparison) ===');
// Create source directory structure
await fs.mkdir('/example/copyTest/subFolder');
await fs.writeFile('/example/copyTest/rootFile.txt', 'root content');
await fs.writeFile('/example/copyTest/subFolder/nestedFile.txt', 'nested content');
// Helper function to list directory structure
async function listStructure(dirPath: string): Promise<string[]> {
const entries: string[] = [];
const result = await fs.readDir(dirPath, { recursive: true });
if (result.isOk()) {
for await (const entry of result.unwrap()) {
const icon = fs.isFileHandle(entry.handle) ? '📄' : '📁';
entries.push(`${icon} ${entry.path}`);
}
}
return entries.sort();
}
// Show BEFORE structure
log('Before copy - /example/copyTest structure:');
const beforeEntries = await listStructure('/example/copyTest');
for (const entry of beforeEntries) {
log(` ${entry}`);
}
// Execute copy
const dirCopyResult = await fs.copy('/example/copyTest', '/example/copyTestDest');
dirCopyResult.inspect(() => log('✓ Copied /example/copyTest to /example/copyTestDest'));
dirCopyResult.inspectErr((err) => log(`✗ Failed to copy directory: ${err.message}`, true));
// Show AFTER structure
log('After copy - /example/copyTestDest structure:');
const afterEntries = await listStructure('/example/copyTestDest');
for (const entry of afterEntries) {
log(` ${entry}`);
}
// Verify: source folder name should NOT appear inside destination
const bugCheck = await fs.exists('/example/copyTestDest/copyTest');
if (bugCheck.isOk()) {
if (bugCheck.unwrap()) {
log('⚠ BUG: /example/copyTestDest/copyTest exists (should not!)', true);
} else {
log('✓ No bug: source folder name not duplicated in destination');
}
}
// 7. Move file
log('\n=== Moving Files ===');
const moveResult = await fs.move('/example/data/hello.txt', '/example/data/renamed.txt');
moveResult.inspect(() => log('✓ Moved hello.txt to renamed.txt'));
moveResult.inspectErr((err) => log(`✗ Failed to move file: ${err.message}`, true));
// 8. Check if file exists
log('\n=== Checking Existence ===');
const existsOldResult = await fs.exists('/example/data/hello.txt');
existsOldResult.inspect((exists) => log(`✓ hello.txt exists: ${exists}`));
const existsNewResult = await fs.exists('/example/data/renamed.txt');
existsNewResult.inspect((exists) => log(`✓ renamed.txt exists: ${exists}`));
// 9. Get file stats
log('\n=== File Stats ===');
const statResult = await fs.stat('/example/data/renamed.txt');
if (statResult.isOk()) {
const handle = statResult.unwrap();
log(`✓ renamed.txt stats:`);
log(` - name: ${handle.name}`);
log(` - kind: ${handle.kind}`);
if (fs.isFileHandle(handle)) {
const file = await handle.getFile();
log(` - size: ${file.size} bytes`);
log(` - type: ${file.type}`);
}
} else {
log(`✗ Failed to get stats: ${statResult.unwrapErr().message}`, true);
}
// 10. List directory contents
log('\n=== Directory Contents ===');
const readDirResult = await fs.readDir('/example/data');
if (readDirResult.isOk()) {
log(`✓ Contents of /example/data:`);
for await (const entry of readDirResult.unwrap()) {
const isFile = fs.isFileHandle(entry.handle);
log(` - ${entry.path} (${isFile ? 'file' : 'directory'})`);
}
} else {
log(`✗ Failed to read directory: ${readDirResult.unwrapErr().message}`, true);
}
// 11. Append to file
log('\n=== Appending to File ===');
const appendResult = await fs.appendFile('/example/data/renamed.txt', '\nAppended text!');
appendResult.inspect(() => log('✓ Appended to renamed.txt'));
appendResult.inspectErr((err) => log(`✗ Failed to append: ${err.message}`, true));
const appendedContent = await fs.readTextFile('/example/data/renamed.txt');
appendedContent.inspect((content) => log(`✓ New content: "${content}"`));
appendedContent.inspectErr((err) => log(`✗ Failed to read: ${err.message}`, true));
// 12. Clean up
log('\n=== Final Cleanup ===');
const removeResult = await fs.remove('/example');
removeResult.inspect(() => log('✓ Removed /example directory'));
removeResult.inspectErr((err) => log(`✗ Failed to remove: ${err.message}`, true));
log('\n=== Example Complete ===');
}
document.getElementById('run')!.addEventListener('click', () => {
runExample().catch((err) => {
log(`Unexpected error: ${err.message}`, true);
});
});