Skip to content

Commit 0cabd0b

Browse files
Merge pull request #16 from KristofferStrube/feature/filesystem-directory-is-now-a-pair-async-iterable
Removed implementations of `ValuesAsync` and made `FileSystemDirectoryHandle` implement `IPairAsyncIterable` which exposes methods for iterating the name-handle pairs in a directory.
2 parents 114ab97 + 6ff365e commit 0cabd0b

File tree

10 files changed

+81
-101
lines changed

10 files changed

+81
-101
lines changed

.EditorConfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ dotnet_diagnostic.IDE0039.severity = warning
4040
csharp_style_deconstructed_variable_declaration = true
4141
dotnet_diagnostic.IDE0042.severity = suggestion
4242
dotnet_style_prefer_conditional_expression_over_assignment = true
43-
dotnet_diagnostic.IDE0045.severity = warning
43+
dotnet_diagnostic.IDE0045.severity = silent
4444
dotnet_style_prefer_conditional_expression_over_return = false
4545
dotnet_diagnostic.IDE0046.severity = none
4646
dotnet_style_prefer_compound_assignment = true

samples/KristofferStrube.Blazor.FileSystem.WasmExample.Benchmarks/KristofferStrube.Blazor.FileSystem.WasmExample.Benchmarks.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
<PropertyGroup>
44
<OutputType>Exe</OutputType>
5-
<TargetFramework>net8.0</TargetFramework>
5+
<TargetFramework>net10.0</TargetFramework>
66
<ImplicitUsings>enable</ImplicitUsings>
77
<Nullable>enable</Nullable>
88
</PropertyGroup>

samples/KristofferStrube.Blazor.FileSystem.WasmExample/KristofferStrube.Blazor.FileSystem.WasmExample.csproj

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,18 @@
11
<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">
22

33
<PropertyGroup>
4-
<TargetFramework>net8.0</TargetFramework>
4+
<TargetFramework>net10.0</TargetFramework>
55
<Nullable>enable</Nullable>
66
<ImplicitUsings>enable</ImplicitUsings>
7+
<OverrideHtmlAssetPlaceholders>true</OverrideHtmlAssetPlaceholders>
78
</PropertyGroup>
89

910
<ItemGroup>
1011
<PackageReference Include="HtmlAgilityPack" Version="1.12.2" />
1112
<PackageReference Include="KristofferStrube.ActivityStreams" Version="0.2.4" />
1213
<PackageReference Include="MessagePack" Version="3.1.4" />
13-
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="8.0.20" />
14-
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="8.0.20" PrivateAssets="all" />
14+
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="10.0.0" />
15+
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="10.0.0" PrivateAssets="all" />
1516
<PackageReference Include="TG.Blazor.IndexedDB" Version="1.5.0-preview" />
1617
<PackageReference Include="System.Reactive.Linq" Version="5.0.0" />
1718
</ItemGroup>

samples/KristofferStrube.Blazor.FileSystem.WasmExample/Shared/ElementExplorer.razor.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using KristofferStrube.Blazor.WebIDL;
12
using Microsoft.AspNetCore.Components;
23

34
namespace KristofferStrube.Blazor.FileSystem.WasmExample.Shared;
@@ -13,7 +14,10 @@ protected override async Task OnParametersSetAsync()
1314
{
1415
if (Element is not FileSystemDirectoryHandleInProcess directoryHandle)
1516
return;
16-
children = (await directoryHandle.ValuesAsync()).ToList();
17+
18+
await using AsyncIterator<FileSystemHandle> iterator = await directoryHandle.ValuesAsync(disposePreviousValueWhenMovingToNextValue: false);
19+
20+
children = await iterator.Select(handle => (IFileSystemHandleInProcess)handle).ToListAsync();
1721
}
1822

1923
async Task Remove(IFileSystemHandleInProcess element)

samples/KristofferStrube.Blazor.FileSystem.WasmExample/wwwroot/css/app.css

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,3 +80,38 @@ a, .btn-link {
8080
.blazor-error-boundary::after {
8181
content: "An error has occurred."
8282
}
83+
84+
.loading-progress {
85+
position: relative;
86+
display: block;
87+
width: 8rem;
88+
height: 8rem;
89+
margin: 20vh auto 1rem auto;
90+
}
91+
92+
.loading-progress circle {
93+
fill: none;
94+
stroke: #e0e0e0;
95+
stroke-width: 0.6rem;
96+
transform-origin: 50% 50%;
97+
transform: rotate(-90deg);
98+
}
99+
100+
.loading-progress circle:last-child {
101+
stroke: #1b6ec2;
102+
stroke-dasharray: calc(3.141 * var(--blazor-load-percentage, 0%) * 0.8), 500%;
103+
transition: stroke-dasharray 0.05s ease-in-out;
104+
}
105+
106+
.loading-progress-text {
107+
position: absolute;
108+
text-align: center;
109+
font-weight: bold;
110+
inset: calc(20vh + 3.25rem) 0 auto 0.2rem;
111+
}
112+
113+
.loading-progress-text:after {
114+
content: var(--blazor-load-percentage-text, "Loading");
115+
}
116+
117+

samples/KristofferStrube.Blazor.FileSystem.WasmExample/wwwroot/index.html

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,20 +46,29 @@
4646
function getAttribute(object, attribute) { return object[attribute]; }
4747
function setAttribute(object, attribute, value) { object[attribute] = value; }
4848
</script>
49+
<link rel="preload" id="webassembly" />
4950
<link href="css/bootstrap/bootstrap.min.css" rel="stylesheet" />
5051
<link href="css/app.css" rel="stylesheet" />
5152
<link href="KristofferStrube.Blazor.FileSystem.WasmExample.styles.css" rel="stylesheet" />
53+
<script type="importmap"></script>
54+
<HeadOutlet />
5255
</head>
5356

5457
<body>
55-
<div id="app">Loading...</div>
58+
<div id="app">
59+
<svg class="loading-progress">
60+
<circle r="40%" cx="50%" cy="50%" />
61+
<circle r="40%" cx="50%" cy="50%" />
62+
</svg>
63+
<div class="loading-progress-text"></div>
64+
</div>
5665

5766
<div id="blazor-error-ui">
5867
An unhandled error has occurred.
5968
<a href="" class="reload">Reload</a>
6069
<a class="dismiss">🗙</a>
6170
</div>
62-
<script src="_framework/blazor.webassembly.js"></script>
71+
<script src="_framework/blazor.webassembly#[.{fingerprint}].js"></script>
6372
<script src="_content/TG.Blazor.IndexedDB/indexedDb.Blazor.js"></script>
6473
</body>
6574

src/KristofferStrube.Blazor.FileSystem/FileSystemDirectoryHandle.InProcess.cs

Lines changed: 0 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -43,49 +43,6 @@ protected FileSystemDirectoryHandleInProcess(IJSRuntime jSRuntime, IJSInProcessO
4343
/// <inheritdoc cref="IFileSystemHandle.GetNameAsync"/>
4444
public string Name => inProcessHelper.Invoke<string>("getAttribute", JSReference, "name");
4545

46-
/// <inheritdoc cref="FileSystemDirectoryHandle.ValuesAsync"/>
47-
public new async Task<IFileSystemHandleInProcess[]> ValuesAsync()
48-
{
49-
IJSObjectReference helper = await helperTask.Value;
50-
IJSObjectReference jSValues = await JSReference.InvokeAsync<IJSObjectReference>("values");
51-
IJSObjectReference jSEntries = await helper.InvokeAsync<IJSObjectReference>("arrayFrom", jSValues);
52-
int length = await helper.InvokeAsync<int>("size", jSEntries);
53-
return await Task.WhenAll(
54-
Enumerable
55-
.Range(0, length)
56-
.Select<int, Task<IFileSystemHandleInProcess>>(async i =>
57-
{
58-
await using FileSystemHandleInProcess fileSystemHandle = await FileSystemHandleInProcess.CreateAsync(
59-
JSRuntime,
60-
await jSEntries.InvokeAsync<IJSInProcessObjectReference>("at", i),
61-
new()
62-
{
63-
DisposesJSReference = false // We explicitly show that we don't expose the reference as it is used later.
64-
}
65-
);
66-
67-
FileSystemHandleKind kind = await fileSystemHandle.GetKindAsync();
68-
69-
if (kind is FileSystemHandleKind.File)
70-
{
71-
return await FileSystemFileHandleInProcess.CreateAsync(JSRuntime, fileSystemHandle.JSReference, new()
72-
{
73-
DisposesJSReference = true
74-
});
75-
}
76-
else
77-
{
78-
return await CreateAsync(JSRuntime, fileSystemHandle.JSReference, new()
79-
{
80-
DisposesJSReference = true
81-
});
82-
}
83-
}
84-
)
85-
.ToArray()
86-
);
87-
}
88-
8946
/// <inheritdoc cref="FileSystemDirectoryHandle.GetFileHandleAsync(string, FileSystemGetFileOptions?)"/>
9047
public new async Task<FileSystemFileHandleInProcess> GetFileHandleAsync(string name, FileSystemGetFileOptions? options = null)
9148
{

src/KristofferStrube.Blazor.FileSystem/FileSystemDirectoryHandle.cs

Lines changed: 1 addition & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ namespace KristofferStrube.Blazor.FileSystem;
88
/// </summary>
99
/// <remarks><see href="https://fs.spec.whatwg.org/#api-filesystemdirectoryhandle">See the API definition here</see>.</remarks>
1010
[IJSWrapperConverter]
11-
public class FileSystemDirectoryHandle : FileSystemHandle, IJSCreatable<FileSystemDirectoryHandle>
11+
public class FileSystemDirectoryHandle : FileSystemHandle, IJSCreatable<FileSystemDirectoryHandle>, IPairAsyncIterable<FileSystemDirectoryHandle, string, FileSystemHandle>
1212
{
1313
/// <inheritdoc/>
1414
public static new async Task<FileSystemDirectoryHandle> CreateAsync(IJSRuntime jSRuntime, IJSObjectReference jSReference)
@@ -25,51 +25,6 @@ public class FileSystemDirectoryHandle : FileSystemHandle, IJSCreatable<FileSyst
2525
/// <inheritdoc cref="CreateAsync(IJSRuntime, IJSObjectReference, CreationOptions)"/>
2626
protected FileSystemDirectoryHandle(IJSRuntime jSRuntime, IJSObjectReference jSReference, CreationOptions options) : base(jSRuntime, jSReference, options) { }
2727

28-
/// <summary>
29-
/// Gets all <see cref="FileSystemHandle"/>s in the directory.
30-
/// </summary>
31-
public async Task<IFileSystemHandle[]> ValuesAsync()
32-
{
33-
IJSObjectReference helper = await helperTask.Value;
34-
IJSObjectReference jSValues = await JSReference.InvokeAsync<IJSObjectReference>("values");
35-
IJSObjectReference jSEntries = await helper.InvokeAsync<IJSObjectReference>("arrayFrom", jSValues);
36-
int length = await helper.InvokeAsync<int>("size", jSEntries);
37-
return await Task.WhenAll(
38-
Enumerable
39-
.Range(0, length)
40-
.Select<int, Task<FileSystemHandle>>(async i =>
41-
{
42-
await using FileSystemHandle fileSystemHandle = await FileSystemHandle.CreateAsync(
43-
JSRuntime,
44-
await jSEntries.InvokeAsync<IJSObjectReference>("at", i),
45-
new()
46-
{
47-
DisposesJSReference = false // We explicitly show that we don't expose the reference as it is used later.
48-
}
49-
);
50-
51-
FileSystemHandleKind kind = await fileSystemHandle.GetKindAsync();
52-
53-
if (kind is FileSystemHandleKind.File)
54-
{
55-
return await FileSystemFileHandle.CreateAsync(JSRuntime, fileSystemHandle.JSReference, new()
56-
{
57-
DisposesJSReference = true
58-
});
59-
}
60-
else
61-
{
62-
return await CreateAsync(JSRuntime, fileSystemHandle.JSReference, new()
63-
{
64-
DisposesJSReference = true
65-
});
66-
}
67-
}
68-
)
69-
.ToArray()
70-
);
71-
}
72-
7328
/// <summary>
7429
/// Returns a handle for a file named <paramref name="name"/> in the directory entry locatable by directoryHandle’s locator.
7530
/// If <paramref name="options"/> defines that it should create the file then it will create it if it doesn't already exist.

src/KristofferStrube.Blazor.FileSystem/FileSystemHandle.cs

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,28 @@ public static async Task<FileSystemHandle> CreateAsync(IJSRuntime jSRuntime, IJS
1414
}
1515

1616
/// <inheritdoc/>
17-
public static Task<FileSystemHandle> CreateAsync(IJSRuntime jSRuntime, IJSObjectReference jSReference, CreationOptions options)
17+
public static async Task<FileSystemHandle> CreateAsync(IJSRuntime jSRuntime, IJSObjectReference jSReference, CreationOptions options)
1818
{
19-
return Task.FromResult(new FileSystemHandle(jSRuntime, jSReference, options));
19+
await using ValueReference handle = new(jSRuntime, jSReference, null, new() { DisposesJSReference = false });
20+
21+
if (jSReference is IJSInProcessObjectReference inProcessObjectReference)
22+
{
23+
handle.ValueMapper = new()
24+
{
25+
["filesystemdirectoryhandle"] = async () => await FileSystemDirectoryHandleInProcess.CreateAsync(jSRuntime, inProcessObjectReference, new() { DisposesJSReference = true }),
26+
["filesystemfilehandle"] = async () => await FileSystemFileHandleInProcess.CreateAsync(jSRuntime, inProcessObjectReference, new() { DisposesJSReference = true }),
27+
};
28+
}
29+
else
30+
{
31+
handle.ValueMapper = new()
32+
{
33+
["filesystemdirectoryhandle"] = async () => await FileSystemDirectoryHandle.CreateAsync(jSRuntime, jSReference, new() { DisposesJSReference = true }),
34+
["filesystemfilehandle"] = async () => await FileSystemFileHandle.CreateAsync(jSRuntime, jSReference, new() { DisposesJSReference = true }),
35+
};
36+
}
37+
38+
return (FileSystemHandle)(await handle.GetValueAsync())!;
2039
}
2140

2241
/// <inheritdoc cref="CreateAsync(IJSRuntime, IJSObjectReference, CreationOptions)"/>

src/KristofferStrube.Blazor.FileSystem/KristofferStrube.Blazor.FileSystem.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<Project Sdk="Microsoft.NET.Sdk.Razor">
22

33
<PropertyGroup>
4-
<TargetFrameworks>net7.0;net8.0</TargetFrameworks>
4+
<TargetFrameworks>net7.0;net8.0;net9.0;net10.0</TargetFrameworks>
55
<Nullable>enable</Nullable>
66
<ImplicitUsings>enable</ImplicitUsings>
77
<Title>Blazor File System API wrapper</Title>
@@ -34,7 +34,7 @@
3434
</ItemGroup>
3535

3636
<ItemGroup>
37-
<PackageReference Include="KristofferStrube.Blazor.FileAPI" Version="0.4.0" />
37+
<PackageReference Include="KristofferStrube.Blazor.FileAPI" Version="0.4.1" />
3838
</ItemGroup>
3939

4040
</Project>

0 commit comments

Comments
 (0)