Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

improve CRDT error handling #1039

Merged
merged 8 commits into from
Sep 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions .github/workflows/fw-lite.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,7 @@ jobs:
dotnet build --configuration Release

- name: Dotnet test
working-directory: backend/FwLite/LcmCrdt.Tests
run: dotnet test --configuration Release --logger GitHubActions
run: dotnet test FwLiteOnly.slnf --configuration Release --logger GitHubActions

- name: Build viewer
working-directory: frontend/viewer
Expand Down
18 changes: 18 additions & 0 deletions FwLiteOnly.slnf
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"solution": {
"path": "LexBox.sln",
"projects": [
"backend\\FwLite\\MiniLcm\\MiniLcm.csproj",
"backend\\harmony\\src\\SIL.Harmony.Core\\SIL.Harmony.Core.csproj",
"backend\\harmony\\src\\SIL.Harmony\\SIL.Harmony.csproj",
"backend\\FwLite\\LcmCrdt\\LcmCrdt.csproj",
"backend\\FwLite\\LcmCrdt.Tests\\LcmCrdt.Tests.csproj",
"backend\\FWLite\\LocalWebApp\\LocalWebApp.csproj",
"backend\\FwLite\\FwLiteDesktop\\FwLiteDesktop.csproj",
"backend\\FWLite\\FwDataMiniLcmBridge\\FwDataMiniLcmBridge.csproj",
"backend\\FwLite\\FwDataMiniLcmBridge.Tests\\FwDataMiniLcmBridge.Tests.csproj",
"backend\\FWLite\\FwLiteProjectSync\\FwLiteProjectSync.csproj",
"backend\\FWLite\\FwLiteProjectSync.Tests\\FwLiteProjectSync.Tests.csproj",
]
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,18 @@

<ItemGroup>
<PackageReference Include="coverlet.collector" Version="6.0.0"/>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0"/>
<PackageReference Include="GitHubActionsTestLogger" Version="2.4.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.11.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="8.0.0"/>
<PackageReference Include="FluentAssertions" Version="6.12.0"/>
<PackageReference Include="xunit" Version="2.5.3"/>
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.3"/>
<PackageReference Include="xunit" Version="2.9.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" />
</ItemGroup>

Expand Down
19 changes: 12 additions & 7 deletions backend/FwLite/FwDataMiniLcmBridge.Tests/PartOfSpeechTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,27 +16,29 @@
_api = fixture.CreateApi(projectName);
_api.Should().NotBeNull();

var partOfSpeech = new PartOfSpeech()
var nounPos = new PartOfSpeech()
{
Id = Guid.NewGuid(), Name = { { "en", "new-part-of-speech" } }
Id = Guid.NewGuid(), Name = { { "en", "Noun" } }
};
await _api.CreatePartOfSpeech(partOfSpeech);
await _api.CreatePartOfSpeech(nounPos);

await _api.CreatePartOfSpeech(new() { Id = Guid.NewGuid(), Name = { { "en", "Verb" } } });

await _api.CreateEntry(new Entry()
{
Id = Guid.NewGuid(),
LexemeForm = {{"en", "new-lexeme-form"}},
LexemeForm = {{"en", "Apple"}},
Senses = new List<Sense>()
{
new Sense()
{
Gloss = {{"en", "new-sense-gloss"}},
PartOfSpeechId = partOfSpeech.Id
Gloss = {{"en", "Fruit"}},
PartOfSpeechId = nounPos.Id
}
}});
}

public async Task DisposeAsync()

Check warning on line 41 in backend/FwLite/FwDataMiniLcmBridge.Tests/PartOfSpeechTests.cs

View workflow job for this annotation

GitHub Actions / Build FW Lite and run tests

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.
{
_api.Dispose();
}
Expand All @@ -45,7 +47,10 @@
public async Task GetPartsOfSpeech_ReturnsAllPartsOfSpeech()
{
var partOfSpeeches = await _api.GetPartsOfSpeech().ToArrayAsync();
partOfSpeeches.Should().AllSatisfy(po => po.Id.Should().NotBe(Guid.Empty));
partOfSpeeches.Should()
.NotBeEmpty()
.And
.AllSatisfy(po => po.Id.Should().NotBe(Guid.Empty));
}

[Fact]
Expand Down
15 changes: 15 additions & 0 deletions backend/FwLite/FwDataMiniLcmBridge/Api/FwDataMiniLcmApi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@
throw new NotImplementedException();
}

public async IAsyncEnumerable<PartOfSpeech> GetPartsOfSpeech()

Check warning on line 170 in backend/FwLite/FwDataMiniLcmBridge/Api/FwDataMiniLcmApi.cs

View workflow job for this annotation

GitHub Actions / Build FW Lite and run tests

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

Check warning on line 170 in backend/FwLite/FwDataMiniLcmBridge/Api/FwDataMiniLcmApi.cs

View workflow job for this annotation

GitHub Actions / Publish FW Lite app for Linux

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

Check warning on line 170 in backend/FwLite/FwDataMiniLcmBridge/Api/FwDataMiniLcmApi.cs

View workflow job for this annotation

GitHub Actions / Publish FW Lite app for Linux

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

Check warning on line 170 in backend/FwLite/FwDataMiniLcmBridge/Api/FwDataMiniLcmApi.cs

View workflow job for this annotation

GitHub Actions / Publish FW Lite app for Mac

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

Check warning on line 170 in backend/FwLite/FwDataMiniLcmBridge/Api/FwDataMiniLcmApi.cs

View workflow job for this annotation

GitHub Actions / Publish FW Lite app for Mac

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

Check warning on line 170 in backend/FwLite/FwDataMiniLcmBridge/Api/FwDataMiniLcmApi.cs

View workflow job for this annotation

GitHub Actions / Publish FW Lite app

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

Check warning on line 170 in backend/FwLite/FwDataMiniLcmBridge/Api/FwDataMiniLcmApi.cs

View workflow job for this annotation

GitHub Actions / Publish FW Lite app

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.
{
foreach (var partOfSpeech in PartOfSpeechRepository.AllInstances().OrderBy(p => p.Name.BestAnalysisAlternative.Text))
{
Expand All @@ -175,7 +175,7 @@
}
}

public async Task CreatePartOfSpeech(PartOfSpeech partOfSpeech)

Check warning on line 178 in backend/FwLite/FwDataMiniLcmBridge/Api/FwDataMiniLcmApi.cs

View workflow job for this annotation

GitHub Actions / Build FW Lite and run tests

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

Check warning on line 178 in backend/FwLite/FwDataMiniLcmBridge/Api/FwDataMiniLcmApi.cs

View workflow job for this annotation

GitHub Actions / Publish FW Lite app for Linux

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

Check warning on line 178 in backend/FwLite/FwDataMiniLcmBridge/Api/FwDataMiniLcmApi.cs

View workflow job for this annotation

GitHub Actions / Publish FW Lite app for Linux

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

Check warning on line 178 in backend/FwLite/FwDataMiniLcmBridge/Api/FwDataMiniLcmApi.cs

View workflow job for this annotation

GitHub Actions / Publish FW Lite app for Mac

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

Check warning on line 178 in backend/FwLite/FwDataMiniLcmBridge/Api/FwDataMiniLcmApi.cs

View workflow job for this annotation

GitHub Actions / Publish FW Lite app for Mac

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

Check warning on line 178 in backend/FwLite/FwDataMiniLcmBridge/Api/FwDataMiniLcmApi.cs

View workflow job for this annotation

GitHub Actions / Publish FW Lite app

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

Check warning on line 178 in backend/FwLite/FwDataMiniLcmBridge/Api/FwDataMiniLcmApi.cs

View workflow job for this annotation

GitHub Actions / Publish FW Lite app

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.
{
if (partOfSpeech.Id == default) partOfSpeech.Id = Guid.NewGuid();
UndoableUnitOfWorkHelper.Do("Create Part of Speech",
Expand All @@ -189,7 +189,7 @@
});
}

public async IAsyncEnumerable<SemanticDomain> GetSemanticDomains()

Check warning on line 192 in backend/FwLite/FwDataMiniLcmBridge/Api/FwDataMiniLcmApi.cs

View workflow job for this annotation

GitHub Actions / Build FW Lite and run tests

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

Check warning on line 192 in backend/FwLite/FwDataMiniLcmBridge/Api/FwDataMiniLcmApi.cs

View workflow job for this annotation

GitHub Actions / Publish FW Lite app for Linux

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

Check warning on line 192 in backend/FwLite/FwDataMiniLcmBridge/Api/FwDataMiniLcmApi.cs

View workflow job for this annotation

GitHub Actions / Publish FW Lite app for Linux

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

Check warning on line 192 in backend/FwLite/FwDataMiniLcmBridge/Api/FwDataMiniLcmApi.cs

View workflow job for this annotation

GitHub Actions / Publish FW Lite app for Mac

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

Check warning on line 192 in backend/FwLite/FwDataMiniLcmBridge/Api/FwDataMiniLcmApi.cs

View workflow job for this annotation

GitHub Actions / Publish FW Lite app for Mac

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

Check warning on line 192 in backend/FwLite/FwDataMiniLcmBridge/Api/FwDataMiniLcmApi.cs

View workflow job for this annotation

GitHub Actions / Publish FW Lite app

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

Check warning on line 192 in backend/FwLite/FwDataMiniLcmBridge/Api/FwDataMiniLcmApi.cs

View workflow job for this annotation

GitHub Actions / Publish FW Lite app

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.
{
foreach (var semanticDomain in SemanticDomainRepository.AllInstances().OrderBy(p => p.Abbreviation.UiString))
{
Expand All @@ -202,7 +202,7 @@
}
}

public async Task CreateSemanticDomain(SemanticDomain semanticDomain)

Check warning on line 205 in backend/FwLite/FwDataMiniLcmBridge/Api/FwDataMiniLcmApi.cs

View workflow job for this annotation

GitHub Actions / Build FW Lite and run tests

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

Check warning on line 205 in backend/FwLite/FwDataMiniLcmBridge/Api/FwDataMiniLcmApi.cs

View workflow job for this annotation

GitHub Actions / Publish FW Lite app for Linux

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

Check warning on line 205 in backend/FwLite/FwDataMiniLcmBridge/Api/FwDataMiniLcmApi.cs

View workflow job for this annotation

GitHub Actions / Publish FW Lite app for Linux

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

Check warning on line 205 in backend/FwLite/FwDataMiniLcmBridge/Api/FwDataMiniLcmApi.cs

View workflow job for this annotation

GitHub Actions / Publish FW Lite app for Mac

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

Check warning on line 205 in backend/FwLite/FwDataMiniLcmBridge/Api/FwDataMiniLcmApi.cs

View workflow job for this annotation

GitHub Actions / Publish FW Lite app for Mac

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

Check warning on line 205 in backend/FwLite/FwDataMiniLcmBridge/Api/FwDataMiniLcmApi.cs

View workflow job for this annotation

GitHub Actions / Publish FW Lite app

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

Check warning on line 205 in backend/FwLite/FwDataMiniLcmBridge/Api/FwDataMiniLcmApi.cs

View workflow job for this annotation

GitHub Actions / Publish FW Lite app

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.
{
if (semanticDomain.Id == Guid.Empty) semanticDomain.Id = Guid.NewGuid();
UndoableUnitOfWorkHelper.Do("Create Semantic Domain",
Expand Down Expand Up @@ -285,7 +285,7 @@
return GetEntries(null, options);
}

public async IAsyncEnumerable<Entry> GetEntries(

Check warning on line 288 in backend/FwLite/FwDataMiniLcmBridge/Api/FwDataMiniLcmApi.cs

View workflow job for this annotation

GitHub Actions / Build FW Lite and run tests

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

Check warning on line 288 in backend/FwLite/FwDataMiniLcmBridge/Api/FwDataMiniLcmApi.cs

View workflow job for this annotation

GitHub Actions / Publish FW Lite app for Linux

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

Check warning on line 288 in backend/FwLite/FwDataMiniLcmBridge/Api/FwDataMiniLcmApi.cs

View workflow job for this annotation

GitHub Actions / Publish FW Lite app for Linux

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

Check warning on line 288 in backend/FwLite/FwDataMiniLcmBridge/Api/FwDataMiniLcmApi.cs

View workflow job for this annotation

GitHub Actions / Publish FW Lite app for Mac

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

Check warning on line 288 in backend/FwLite/FwDataMiniLcmBridge/Api/FwDataMiniLcmApi.cs

View workflow job for this annotation

GitHub Actions / Publish FW Lite app for Mac

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

Check warning on line 288 in backend/FwLite/FwDataMiniLcmBridge/Api/FwDataMiniLcmApi.cs

View workflow job for this annotation

GitHub Actions / Publish FW Lite app

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

Check warning on line 288 in backend/FwLite/FwDataMiniLcmBridge/Api/FwDataMiniLcmApi.cs

View workflow job for this annotation

GitHub Actions / Publish FW Lite app

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.
Func<ILexEntry, bool>? predicate, QueryOptions? options = null)
{
var entries = EntriesRepository.AllInstances();
Expand Down Expand Up @@ -415,11 +415,26 @@
internal void CreateSense(ILexEntry lexEntry, Sense sense)
{
var lexSense = LexSenseFactory.Create(sense.Id, lexEntry);
var msa = new SandboxGenericMSA() { MsaType = lexSense.GetDesiredMsaType() };
if (sense.PartOfSpeechId.HasValue && PartOfSpeechRepository.TryGetObject(sense.PartOfSpeechId.Value, out var pos))
{
msa.MainPOS = pos;
}
lexSense.SandboxMSA = msa;
ApplySenseToLexSense(sense, lexSense);
}

private void ApplySenseToLexSense(Sense sense, ILexSense lexSense)
{
if (lexSense.MorphoSyntaxAnalysisRA.GetPartOfSpeech()?.Guid != sense.PartOfSpeechId)
{
IPartOfSpeech? pos = null;
if (sense.PartOfSpeechId.HasValue)
{
pos = PartOfSpeechRepository.GetObject(sense.PartOfSpeechId.Value);
}
lexSense.MorphoSyntaxAnalysisRA.SetMsaPartOfSpeech(pos);
}
UpdateLcmMultiString(lexSense.Gloss, sense.Gloss);
UpdateLcmMultiString(lexSense.Definition, sense.Definition);
foreach (var senseSemanticDomain in sense.SemanticDomains)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ public static class MorphoSyntaxExtensions
{
public static void SetMsaPartOfSpeech(this IMoMorphSynAnalysis msa, IPartOfSpeech? pos)
{
ArgumentNullException.ThrowIfNull(msa);

switch (msa.ClassID)
{
case MoDerivAffMsaTags.kClassId:
Expand All @@ -31,6 +33,7 @@ public static void SetMsaPartOfSpeech(this IMoMorphSynAnalysis msa, IPartOfSpeec

public static IPartOfSpeech? GetPartOfSpeech(this IMoMorphSynAnalysis msa)
{
ArgumentNullException.ThrowIfNull(msa);
switch (msa.ClassID)
{
case MoDerivAffMsaTags.kClassId:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,19 @@

<ItemGroup>
<PackageReference Include="coverlet.collector" Version="6.0.0"/>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0"/>
<PackageReference Include="GitHubActionsTestLogger" Version="2.4.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.11.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="8.0.0"/>
<PackageReference Include="FluentAssertions" Version="6.12.0"/>
<PackageReference Include="Soenneker.Utils.AutoBogus" Version="2.1.278" />
<PackageReference Include="xunit" Version="2.5.3"/>
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.3"/>
<PackageReference Include="xunit" Version="2.9.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0"/>
</ItemGroup>

Expand Down
9 changes: 6 additions & 3 deletions backend/FwLite/LcmCrdt.Tests/LcmCrdt.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,14 @@
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="6.0.0"/>
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="8.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0"/>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.11.0" />
<PackageReference Include="FluentAssertions" Version="6.12.0"/>
<PackageReference Include="Soenneker.Utils.AutoBogus" Version="2.1.278" />
<PackageReference Include="xunit" Version="2.5.3"/>
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.3"/>
<PackageReference Include="xunit" Version="2.9.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="XunitXml.TestLogger" Version="3.1.20" />
<PackageReference Include="GitHubActionsTestLogger" Version="2.4.1">
<PrivateAssets>all</PrivateAssets>
Expand Down
16 changes: 12 additions & 4 deletions backend/FwLite/LocalWebApp/BackgroundSyncService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,17 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken)

private async Task<SyncResults> SyncProject(CrdtProject crdtProject)
{
await using var serviceScope = projectsService.CreateProjectScope(crdtProject);
await serviceScope.ServiceProvider.GetRequiredService<CurrentProjectService>().PopulateProjectDataCache();
var syncService = serviceScope.ServiceProvider.GetRequiredService<SyncService>();
return await syncService.ExecuteSync();
try
{
await using var serviceScope = projectsService.CreateProjectScope(crdtProject);
await serviceScope.ServiceProvider.GetRequiredService<CurrentProjectService>().PopulateProjectDataCache();
var syncService = serviceScope.ServiceProvider.GetRequiredService<SyncService>();
return await syncService.ExecuteSync();
}
catch (Exception e)
{
logger.LogError(e, "Error syncing project {ProjectId}", crdtProject.Name);
return new SyncResults([], [], false);
}
}
}
6 changes: 3 additions & 3 deletions backend/Testing/Testing.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,16 @@
<PackageReference Include="Microsoft.Extensions.Configuration" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Options" Version="8.0.2" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.11.0" />
<PackageReference Include="Microsoft.Playwright" Version="1.41.2" />
<PackageReference Include="Microsoft.Playwright.TestAdapter" Version="1.41.2" />
<PackageReference Include="Moq" Version="4.20.70" />
<PackageReference Include="Moq.Contrib.HttpClient" Version="1.4.0" />
<PackageReference Include="Shouldly" Version="4.2.1" />
<PackageReference Include="SIL.ChorusPlugin.LfMergeBridge" Version="4.1.0" />
<PackageReference Include="SIL.Core" Version="13.0.0-beta0074" />
<PackageReference Include="xunit" Version="2.6.6" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.6">
<PackageReference Include="xunit" Version="2.9.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.2">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
Expand Down
6 changes: 5 additions & 1 deletion frontend/https-proxy/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@
"name": "https-proxy",
"version": "0.0.1",
"private": true,
"packageManager": "pnpm@8.15.1",
"packageManager": "pnpm@9.1.2",
"engines": {
"node": ">=20",
"pnpm": ">=9"
},
"type": "module",
"scripts": {
"dev": "vite"
Expand Down
5 changes: 3 additions & 2 deletions frontend/viewer/package.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
{
"name": "viewer",
"private": true,
"packageManager": "pnpm@8.15.1",
"packageManager": "pnpm@9.1.2",
"engines": {
"node": ">=20"
"node": ">=20",
"pnpm": ">=9"
},
"version": "1.0.0",
"type": "module",
Expand Down
16 changes: 2 additions & 14 deletions frontend/viewer/src/CrdtProjectView.svelte
Original file line number Diff line number Diff line change
@@ -1,24 +1,12 @@
<script lang="ts">

import {HubConnectionBuilder, HubConnectionState} from '@microsoft/signalr';
import {onDestroy, setContext} from 'svelte';
import {SetupSignalR} from './lib/services/service-provider-signalr';
import ProjectView from './ProjectView.svelte';

export let projectName: string;
const connection = new HubConnectionBuilder()
.withUrl(`/api/hub/${projectName}/lexbox`)
.withAutomaticReconnect()
.build();
void connection.start()
.then(() => connected = (connection.state == HubConnectionState.Connected))
.catch(err => console.error(err));
onDestroy(() => connection.stop());
SetupSignalR(connection, {
const {connected, lexboxApi} = SetupSignalR(`/api/hub/${projectName}/lexbox`, {
history: true,
write: true,
feedback: true
});
let connected = false;
</script>
<ProjectView {projectName} isConnected={connected}></ProjectView>
<ProjectView {projectName} isConnected={$connected}></ProjectView>
38 changes: 6 additions & 32 deletions frontend/viewer/src/FwDataProjectView.svelte
Original file line number Diff line number Diff line change
@@ -1,50 +1,25 @@
<script lang="ts">

import {HubConnectionBuilder, HubConnectionState} from '@microsoft/signalr';
import {onDestroy, setContext} from 'svelte';
import {SetupSignalR} from './lib/services/service-provider-signalr';
import ProjectView from './ProjectView.svelte';
import {onDestroy} from 'svelte';
import {navigate} from 'svelte-routing';
import {AppNotification} from './lib/notifications/notifications';
import {CloseReason} from './lib/generated-signalr-client/TypedSignalR.Client/Lexbox.ClientServer.Hubs';
import {Entry} from './lib/mini-lcm';
import {useEventBus} from './lib/services/event-bus';

export let projectName: string;
const connection = new HubConnectionBuilder()
.withUrl(`/api/hub/${projectName}/fwdata`)
.withAutomaticReconnect()
.build();

function connect() {
void connection.start()
.then(() => connected = (connection.state == HubConnectionState.Connected))
.catch(err => {
console.error('Failed to start the connection:', err);
});
}
connect();
onDestroy(() => connection.stop());
connection.onclose(error => {
connected = false;
if (!error) return;
console.error('Connection closed:', error);
});
SetupSignalR(connection, {
const {connected, lexboxApi} = SetupSignalR(`/api/hub/${projectName}/fwdata`, {
history: false,
write: true,
openWithFlex: true,
feedback: true
},
(errorContext) => {
connected = false;
if (errorContext.error instanceof Error) {
let message = errorContext.error.message;
if (message.includes('The project is locked')) return; //handled via the project closed callback
AppNotification.display('Connection error: ' + message, 'error', 'long');
} else {
AppNotification.display('Unknown Connection error', 'error', 'long');
if (message.includes('The project is locked')) return {handled: true}; //handled via the project closed callback
}
return {handled: false};
}
);
onDestroy(useEventBus().onProjectClosed(reason => {
Expand All @@ -56,11 +31,10 @@
case CloseReason.Locked:
AppNotification.displayAction('The project is open in FieldWorks. Please close it and try again.', 'warning', {
label: 'Retry',
callback: () => connected = true
callback: () => $connected = true
});
break;
}
}));
let connected = false;
</script>
<ProjectView {projectName} isConnected={connected}></ProjectView>
<ProjectView {projectName} isConnected={$connected}></ProjectView>
Loading
Loading