First half of replacing the stub text domain with a media collector. Nothing references this yet - the store is standalone and fully tested before anything depends on it. Blobs are addressed by SHA-256 and sharded two levels deep, so the same picture re-uploaded at a dozen addresses costs one file. Downloads stage in a sibling temp directory on the same volume and are promoted by rename, which is what keeps blobs/ free of truncated files: a crash leaves a stray .part that the next startup sweeps, never a half-image indistinguishable from a real one. The SQLite index holds provenance separately from content, so purging one source leaves blobs another source still references - that is what ref_count buys, and it is recomputed rather than incremented because the item upsert can replace a row pointing at a different blob. The seen_url journal deliberately outlives a purge: without that, the next run downloads again exactly what the user just deleted. Terminal outcomes are split from retryable ones so a flaky network does not permanently lose content. The showcase gives every item a dated, named path via hard links - a second name for one file, not a second file. Hard links are a filesystem privilege rather than a guarantee, so it degrades to copying and records which it achieved; the UI has to be able to admit that. Names suggested by the origin are treated as hostile: only the last path segment survives, Windows device names are pushed aside, and the extension comes from the sniffed kind, never from the remote. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
73 lines
3.7 KiB
XML
73 lines
3.7 KiB
XML
<Project>
|
|
<PropertyGroup>
|
|
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
|
|
<CentralPackageTransitivePinningEnabled>true</CentralPackageTransitivePinningEnabled>
|
|
</PropertyGroup>
|
|
|
|
<PropertyGroup Label="Version groups">
|
|
<!-- ReactiveUI.Avalonia versions in lockstep with Avalonia, so one knob moves both. -->
|
|
<AvaloniaVersion>12.1.1</AvaloniaVersion>
|
|
<ReactiveUIVersion>24.1.0</ReactiveUIVersion>
|
|
<ReactiveUIPrimitivesVersion>7.1.1</ReactiveUIPrimitivesVersion>
|
|
<MicrosoftExtensionsVersion>10.0.11</MicrosoftExtensionsVersion>
|
|
<!-- Ships on the EF Core release line, not the Extensions one. They happen to match today;
|
|
they will not always, so this is deliberately its own knob. -->
|
|
<MicrosoftDataSqliteVersion>10.0.11</MicrosoftDataSqliteVersion>
|
|
</PropertyGroup>
|
|
|
|
<ItemGroup Label="Avalonia">
|
|
<PackageVersion Include="Avalonia" Version="$(AvaloniaVersion)" />
|
|
<PackageVersion Include="Avalonia.Desktop" Version="$(AvaloniaVersion)" />
|
|
<PackageVersion Include="Avalonia.Fonts.Inter" Version="$(AvaloniaVersion)" />
|
|
<PackageVersion Include="Avalonia.Headless" Version="$(AvaloniaVersion)" />
|
|
<PackageVersion Include="Avalonia.Headless.XUnit" Version="$(AvaloniaVersion)" />
|
|
</ItemGroup>
|
|
|
|
<ItemGroup Label="Theme">
|
|
<PackageVersion Include="Semi.Avalonia" Version="12.1.0.1" />
|
|
</ItemGroup>
|
|
|
|
<ItemGroup Label="ReactiveUI">
|
|
<!-- Avalonia.ReactiveUI is deprecated; ReactiveUI.Avalonia is the maintained successor.
|
|
ReactiveUI 24 runs on the Primitives engine: RxVoid replaces Unit, ISequencer replaces
|
|
IScheduler, Signal<T> replaces Subject<T>. Classic operator names still resolve. -->
|
|
<PackageVersion Include="ReactiveUI" Version="$(ReactiveUIVersion)" />
|
|
<PackageVersion Include="ReactiveUI.Avalonia" Version="$(AvaloniaVersion)" />
|
|
<PackageVersion Include="ReactiveUI.Primitives" Version="$(ReactiveUIPrimitivesVersion)" />
|
|
<PackageVersion Include="ReactiveUI.SourceGenerators" Version="3.2.0" />
|
|
<PackageVersion Include="ReactiveUI.Testing" Version="$(ReactiveUIVersion)" />
|
|
</ItemGroup>
|
|
|
|
<ItemGroup Label="Microsoft.Extensions">
|
|
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="$(MicrosoftExtensionsVersion)" />
|
|
<PackageVersion
|
|
Include="Microsoft.Extensions.DependencyInjection.Abstractions"
|
|
Version="$(MicrosoftExtensionsVersion)"
|
|
/>
|
|
<PackageVersion Include="Microsoft.Extensions.Http" Version="$(MicrosoftExtensionsVersion)" />
|
|
<PackageVersion Include="Microsoft.Extensions.Logging" Version="$(MicrosoftExtensionsVersion)" />
|
|
<PackageVersion Include="Microsoft.Extensions.Logging.Abstractions" Version="$(MicrosoftExtensionsVersion)" />
|
|
</ItemGroup>
|
|
|
|
<ItemGroup Label="Data">
|
|
<!-- Not Microsoft.Data.Sqlite.Core: we want the bundled e_sqlite3 native, so nothing extra
|
|
has to be shipped per runtime identifier. -->
|
|
<PackageVersion Include="Microsoft.Data.Sqlite" Version="$(MicrosoftDataSqliteVersion)" />
|
|
</ItemGroup>
|
|
|
|
<ItemGroup Label="Logging">
|
|
<PackageVersion Include="Serilog" Version="4.4.0" />
|
|
<PackageVersion Include="Serilog.Extensions.Logging" Version="10.0.0" />
|
|
<PackageVersion Include="Serilog.Sinks.Console" Version="6.1.1" />
|
|
<PackageVersion Include="Serilog.Sinks.File" Version="7.0.0" />
|
|
</ItemGroup>
|
|
|
|
<ItemGroup Label="Testing">
|
|
<PackageVersion Include="coverlet.collector" Version="10.0.1" />
|
|
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="18.8.1" />
|
|
<PackageVersion Include="Shouldly" Version="4.3.0" />
|
|
<PackageVersion Include="xunit.v3" Version="3.2.2" />
|
|
<PackageVersion Include="xunit.runner.visualstudio" Version="3.1.5" />
|
|
</ItemGroup>
|
|
</Project>
|