Skip to content

Commit d9f3f84

Browse files
save
Signed-off-by: Nikola Hristov <Nikola@PlayForm.Cloud>
1 parent 3318da8 commit d9f3f84

2 files changed

Lines changed: 120 additions & 97 deletions

File tree

Documentation/GitHub/DeepDive.md

Lines changed: 56 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -312,27 +312,30 @@ Wind enables sophisticated custom service implementations:
312312

313313
```typescript
314314
// Advanced service implementation pattern
315-
import { Effect, Context, Layer } from "effect"
316-
import { DialogServiceTag } from "./Application/Dialog/Tag"
315+
import { Context, Effect, Layer } from "effect";
316+
317+
import { DialogServiceTag } from "./Application/Dialog/Tag";
317318

318319
// Custom service implementation
319320
class CustomDialogService {
320-
async showCustomDialog(options: CustomDialogOptions): Promise<URI[] | undefined> {
321-
return Effect.runPromise(
322-
Effect.flatMap(DialogServiceTag, (dialogService) =>
323-
Effect.tryPromise(() =>
324-
dialogService.showCustomDialog(options)
325-
)
326-
)
327-
)
328-
}
321+
async showCustomDialog(
322+
options: CustomDialogOptions,
323+
): Promise<URI[] | undefined> {
324+
return Effect.runPromise(
325+
Effect.flatMap(DialogServiceTag, (dialogService) =>
326+
Effect.tryPromise(() =>
327+
dialogService.showCustomDialog(options),
328+
),
329+
),
330+
);
331+
}
329332
}
330333

331334
// Service layer composition
332335
const CustomDialogLayer = Layer.effect(
333-
DialogServiceTag,
334-
Effect.succeed(new CustomDialogService())
335-
)
336+
DialogServiceTag,
337+
Effect.succeed(new CustomDialogService()),
338+
);
336339
```
337340

338341
### Performance Monitoring Integration
@@ -341,18 +344,18 @@ Wind supports comprehensive performance monitoring:
341344

342345
```typescript
343346
// Performance monitoring integration
344-
import { Metric, Effect } from "effect"
347+
import { Effect, Metric } from "effect";
345348

346-
const apiCallTimer = Metric.timer("wind_api_call_duration")
349+
const apiCallTimer = Metric.timer("wind_api_call_duration");
347350

348351
async function monitoredApiCall() {
349-
return Effect.runPromise(
350-
apiCallTimer(
351-
Effect.flatMap(DialogServiceTag, (service) =>
352-
Effect.tryPromise(() => service.showOpenDialog(options))
353-
)
354-
)
355-
)
352+
return Effect.runPromise(
353+
apiCallTimer(
354+
Effect.flatMap(DialogServiceTag, (service) =>
355+
Effect.tryPromise(() => service.showOpenDialog(options)),
356+
),
357+
),
358+
);
356359
}
357360
```
358361

@@ -362,25 +365,26 @@ Sophisticated error handling with Effect-TS:
362365

363366
```typescript
364367
// Comprehensive error handling pattern
365-
import { Effect, Either } from "effect"
366-
import { DialogProblem } from "./Application/Dialog/Error"
368+
import { Effect, Either } from "effect";
369+
370+
import { DialogProblem } from "./Application/Dialog/Error";
367371

368372
async function robustDialogOperation() {
369-
const result = await Effect.runPromise(
370-
Effect.either(
371-
Effect.flatMap(DialogServiceTag, (service) =>
372-
Effect.tryPromise({
373-
try: () => service.showOpenDialog(options),
374-
catch: (error) => new DialogProblem({ cause: error })
375-
})
376-
)
377-
)
378-
)
379-
380-
return Either.match(result, {
381-
onLeft: (error) => handleError(error),
382-
onRight: (uris) => handleSuccess(uris)
383-
})
373+
const result = await Effect.runPromise(
374+
Effect.either(
375+
Effect.flatMap(DialogServiceTag, (service) =>
376+
Effect.tryPromise({
377+
try: () => service.showOpenDialog(options),
378+
catch: (error) => new DialogProblem({ cause: error }),
379+
}),
380+
),
381+
),
382+
);
383+
384+
return Either.match(result, {
385+
onLeft: (error) => handleError(error),
386+
onRight: (uris) => handleSuccess(uris),
387+
});
384388
}
385389
```
386390

@@ -436,18 +440,20 @@ Sophisticated API security patterns:
436440

437441
```typescript
438442
// Secure API pattern implementation
439-
import { Effect } from "effect"
443+
import { Effect } from "effect";
440444

441445
class SecureAPIService {
442-
async secureOperation(input: unknown): Promise<Result> {
443-
return Effect.runPromise(
444-
Effect.flatMap(ValidationServiceTag, (validator) =>
445-
Effect.flatMap(validator.validateInput(input), (validated) =>
446-
Effect.tryPromise(() => this.executeSecureOperation(validated))
447-
)
448-
)
449-
)
450-
}
446+
async secureOperation(input: unknown): Promise<Result> {
447+
return Effect.runPromise(
448+
Effect.flatMap(ValidationServiceTag, (validator) =>
449+
Effect.flatMap(validator.validateInput(input), (validated) =>
450+
Effect.tryPromise(() =>
451+
this.executeSecureOperation(validated),
452+
),
453+
),
454+
),
455+
);
456+
}
451457
}
452458
```
453459

Source/FileSystem/README.md

Lines changed: 64 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@ Mountain-backed file system provider for VSCode browser workbench.
44

55
## Overview
66

7-
This service enables the VSCode browser workbench to access the file system through Mountain's Tauri IPC handlers. It implements a VSCode-like `IFileSystemProvider` interface that communicates with Mountain's file system operations.
7+
This service enables the VSCode browser workbench to access the file system
8+
through Mountain's Tauri IPC handlers. It implements a VSCode-like
9+
`IFileSystemProvider` interface that communicates with Mountain's file system
10+
operations.
811

912
## Architecture
1013

@@ -23,48 +26,52 @@ Native File System
2326
- **File Operations**: Read, write, delete, copy, move files
2427
- **Directory Operations**: List contents, create, remove directories
2528
- **Metadata**: Get file statistics (size, type, timestamps)
26-
- **URI Handling**: Convert between VSCode URIs (`file:///path/to/file`) and file system paths
29+
- **URI Handling**: Convert between VSCode URIs (`file:///path/to/file`) and
30+
file system paths
2731
- **Error Handling**: Comprehensive error types for different failure modes
28-
- **Effect-TS Integration**: Full Effect-TS pattern support for functional composition
32+
- **Effect-TS Integration**: Full Effect-TS pattern support for functional
33+
composition
2934

3035
## Mountain IPC Commands
3136

32-
The service invokes these Mountain IPC commands (defined in `Element/Mountain/Source/IPC/WindServiceHandlers.rs`):
37+
The service invokes these Mountain IPC commands (defined in
38+
`Element/Mountain/Source/IPC/WindServiceHandlers.rs`):
3339

34-
| Command | Description | Parameters |
35-
|---------|-------------|------------|
36-
| `file:read` | Read file contents | `path: string` |
37-
| `file:write` | Write file contents | `path: string`, `content: string` |
38-
| `file:stat` | Get file metadata | `path: string` |
39-
| `file:delete` | Delete file/directory | `path: string` |
40-
| `file:copy` | Copy file/directory | `source: string`, `destination: string` |
41-
| `file:move` | Move/rename file/directory | `source: string`, `destination: string` |
42-
| `file:mkdir` | Create directory | `path: string`, `recursive: boolean` |
43-
| `file:readdir` | List directory contents | `path: string` |
40+
| Command | Description | Parameters |
41+
| -------------- | -------------------------- | --------------------------------------- |
42+
| `file:read` | Read file contents | `path: string` |
43+
| `file:write` | Write file contents | `path: string`, `content: string` |
44+
| `file:stat` | Get file metadata | `path: string` |
45+
| `file:delete` | Delete file/directory | `path: string` |
46+
| `file:copy` | Copy file/directory | `source: string`, `destination: string` |
47+
| `file:move` | Move/rename file/directory | `source: string`, `destination: string` |
48+
| `file:mkdir` | Create directory | `path: string`, `recursive: boolean` |
49+
| `file:readdir` | List directory contents | `path: string` |
4450

4551
## Usage
4652

4753
### Basic Usage
4854

4955
```typescript
50-
import { FileSystemProviderTag } from "./FileSystem/index.js";
5156
import { Effect } from "effect";
5257

58+
import { FileSystemProviderTag } from "./FileSystem/index.js";
59+
5360
// Get the service
5461
const program = Effect.gen(function* () {
55-
const fs = yield* FileSystemProviderTag;
62+
const fs = yield* FileSystemProviderTag;
5663

57-
// Read a file
58-
const content = yield* fs.readFile("file:///path/to/file.txt");
59-
console.log(content);
64+
// Read a file
65+
const content = yield* fs.readFile("file:///path/to/file.txt");
66+
console.log(content);
6067

61-
// List directory
62-
const entries = yield* fs.readdir("file:///path/to/dir");
63-
console.log(entries);
68+
// List directory
69+
const entries = yield* fs.readdir("file:///path/to/dir");
70+
console.log(entries);
6471

65-
// Get file stats
66-
const stats = yield* fs.stat("file:///path/to/file.txt");
67-
console.log(stats);
72+
// Get file stats
73+
const stats = yield* fs.stat("file:///path/to/file.txt");
74+
console.log(stats);
6875
});
6976
```
7077

@@ -88,41 +95,49 @@ console.log(parsed.dirname()); // URI of "/path/to"
8895

8996
```typescript
9097
import {
91-
FileNotFoundError,
92-
FileExistsError,
93-
PermissionError,
94-
toFileSystemProviderError,
98+
FileExistsError,
99+
FileNotFoundError,
100+
PermissionError,
101+
toFileSystemProviderError,
95102
} from "./FileSystem/index.js";
96103

97104
try {
98-
// ...
105+
// ...
99106
} catch (error) {
100-
const fsError = toFileSystemProviderError(error, "readFile", "/path/to/file");
101-
102-
if (fsError instanceof FileNotFoundError) {
103-
console.log("File not found:", fsError.message);
104-
} else if (fsError instanceof PermissionError) {
105-
console.log("Permission denied:", fsError.message);
106-
}
107+
const fsError = toFileSystemProviderError(
108+
error,
109+
"readFile",
110+
"/path/to/file",
111+
);
112+
113+
if (fsError instanceof FileNotFoundError) {
114+
console.log("File not found:", fsError.message);
115+
} else if (fsError instanceof PermissionError) {
116+
console.log("Permission denied:", fsError.message);
117+
}
107118
}
108119
```
109120

110121
### Layer Composition
111122

112123
```typescript
113-
import { FileSystemProviderLive, FileSystemProviderTag } from "./FileSystem/index.js";
114124
import { Layer } from "effect";
125+
115126
import { IPCTauriLive } from "./Effect/IPC.js";
127+
import {
128+
FileSystemProviderLive,
129+
FileSystemProviderTag,
130+
} from "./FileSystem/index.js";
116131

117132
// Create the FileSystem layer
118133
const FileSystemLayer = FileSystemProviderLive.pipe(
119-
Layer.provide(IPCTauriLive),
134+
Layer.provide(IPCTauriLive),
120135
);
121136

122137
// Use in runtime
123138
const program = Effect.gen(function* () {
124-
const fs = yield* FileSystemProviderTag;
125-
// ...
139+
const fs = yield* FileSystemProviderTag;
140+
// ...
126141
}).pipe(Effect.provide(FileSystemLayer));
127142
```
128143

@@ -132,11 +147,11 @@ const program = Effect.gen(function* () {
132147
import { FileType } from "./FileSystem/index.js";
133148

134149
if (stats.type === FileType.File) {
135-
console.log("This is a file");
150+
console.log("This is a file");
136151
} else if (stats.type === FileType.Directory) {
137-
console.log("This is a directory");
152+
console.log("This is a directory");
138153
} else if (stats.type === FileType.SymbolicLink) {
139-
console.log("This is a symbolic link");
154+
console.log("This is a symbolic link");
140155
}
141156
```
142157

@@ -165,17 +180,19 @@ FileSystem/
165180
To integrate with the VSCode browser workbench:
166181

167182
1. Register the file system provider:
183+
168184
```typescript
169185
// In workbench initialization
170-
const fs = yield* FileSystemProviderTag;
171-
vscode.workspace.registerFileSystemProvider('file', fs);
186+
const fs = yield * FileSystemProviderTag;
187+
vscode.workspace.registerFileSystemProvider("file", fs);
172188
```
173189

174190
2. The workbench will automatically use this provider for all file operations.
175191

176192
## Future Enhancements
177193

178-
- **File Watching**: Implement `watch()` method for real-time file change notifications
194+
- **File Watching**: Implement `watch()` method for real-time file change
195+
notifications
179196
- **Binary File Support**: Add specialized binary file read/write operations
180197
- **Search**: Implement recursive file search functionality
181198
- **Permissions**: Add more granular permission checking

0 commit comments

Comments
 (0)