From 8aa44c4df467adab56ab39a3ff83e9c7713659a7 Mon Sep 17 00:00:00 2001 From: Christiaan Landman Date: Thu, 20 Mar 2025 15:14:22 +0200 Subject: [PATCH 1/4] Preparing release setup and CI/CD. --- .github/workflows/dotnet-test.yml | 24 ++++ CHANGELOG.md | 10 ++ .../Client/PowerSyncDatabase.cs | 4 +- .../PowerSync.Common/PowerSync.Common.csproj | 21 +++- Tools/Setup/Setup.cs | 117 +++++------------- icon.png | Bin 0 -> 1840 bytes 6 files changed, 84 insertions(+), 92 deletions(-) create mode 100644 .github/workflows/dotnet-test.yml create mode 100644 CHANGELOG.md create mode 100644 icon.png diff --git a/.github/workflows/dotnet-test.yml b/.github/workflows/dotnet-test.yml new file mode 100644 index 0000000..7dc01c0 --- /dev/null +++ b/.github/workflows/dotnet-test.yml @@ -0,0 +1,24 @@ +name: Test Packages + +on: + push: + +jobs: + build: + name: Build and Test .NET Project + runs-on: windows-latest + + steps: + - name: Checkout Repository + uses: actions/checkout@v4 + + - name: Setup .NET SDK + uses: actions/setup-dotnet@v4 + with: + dotnet-version: '8.0' + + - name: Restore dependencies + run: dotnet restore + + - name: Run tests + run: dotnet test -v n \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..d1274a1 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,10 @@ +## 0.0.1 Pre-Alpha + +Introduce package. + +### Platform Support Added +* linux-arm64 +* linux-x64 +* osx-arm64 +* osx-x64 +* wind-x64 \ No newline at end of file diff --git a/PowerSync/PowerSync.Common/Client/PowerSyncDatabase.cs b/PowerSync/PowerSync.Common/Client/PowerSyncDatabase.cs index 69b69f7..e0618e5 100644 --- a/PowerSync/PowerSync.Common/Client/PowerSyncDatabase.cs +++ b/PowerSync/PowerSync.Common/Client/PowerSyncDatabase.cs @@ -573,7 +573,7 @@ public async Task WriteTransaction(Func> fn, DBLockO /// public Task Watch(string query, object[]? parameters, WatchHandler handler, SQLWatchOptions? options = null) { - var tcs = new TaskCompletionSource(); + var tcs = new TaskCompletionSource(); Task.Run(async () => { try @@ -603,7 +603,7 @@ public Task Watch(string query, object[]? parameters, WatchHandler handler Signal = options?.Signal, ThrottleMs = options?.ThrottleMs }); - tcs.SetResult(); + tcs.SetResult(true); } catch (Exception ex) { diff --git a/PowerSync/PowerSync.Common/PowerSync.Common.csproj b/PowerSync/PowerSync.Common/PowerSync.Common.csproj index 28610d8..f10832b 100644 --- a/PowerSync/PowerSync.Common/PowerSync.Common.csproj +++ b/PowerSync/PowerSync.Common/PowerSync.Common.csproj @@ -5,8 +5,17 @@ 12 enable enable + PowerSync.Common + PowerSync + powersync + Apache-2.0 + https://github.com/powersync-ja/powersync-dotnet + true + https://github.com/powersync-ja/powersync-dotnet/CHANGELOG.md + powersync local-first local-storage state-management offline sql db persistence sqlite sync + icon.png 0.0.1 - alpha + pre-alpha @@ -18,10 +27,20 @@ + PreserveNewest + + + + + + + + + diff --git a/Tools/Setup/Setup.cs b/Tools/Setup/Setup.cs index 6638217..5494705 100644 --- a/Tools/Setup/Setup.cs +++ b/Tools/Setup/Setup.cs @@ -1,8 +1,8 @@ using System; using System.IO; using System.Net.Http; -using System.Runtime.InteropServices; using System.Threading.Tasks; +using System.Collections.Generic; public class Setup { @@ -11,103 +11,42 @@ static async Task Main(string[] args) const string baseUrl = "https://github.com/powersync-ja/powersync-sqlite-core/releases/download/v0.3.8"; string powersyncCorePath = Path.Combine(AppContext.BaseDirectory, "../../../../..", "PowerSync/PowerSync.Common/"); - string rid = GetRuntimeIdentifier(); - string nativeDir = Path.Combine(powersyncCorePath, "runtimes", rid, "native"); - - Directory.CreateDirectory(nativeDir); - - string sqliteCoreFilename = GetLibraryForPlatform(); - string sqliteCorePath = Path.Combine(nativeDir, sqliteCoreFilename); + var runtimeIdentifiers = new Dictionary + { + { "osx-x64", ("libpowersync_x64.dylib", "libpowersync.dylib") }, + { "osx-arm64", ("libpowersync_aarch64.dylib", "libpowersync.dylib") }, + { "linux-x64", ("libpowersync_x64.so", "libpowersync.so") }, + { "linux-arm64", ("libpowersync_aarch64.so", "libpowersync.so") }, + { "win-x64", ("powersync_x64.dll", "powersync.dll") } + }; - try + foreach (var (rid, (originalFile, newFile)) in runtimeIdentifiers) { - await DownloadFile($"{baseUrl}/{sqliteCoreFilename}", sqliteCorePath); + string nativeDir = Path.Combine(powersyncCorePath, "runtimes", rid, "native"); + Directory.CreateDirectory(nativeDir); - string newFileName = GetFileNameForPlatform(); - string newFilePath = Path.Combine(nativeDir, newFileName); + string sqliteCorePath = Path.Combine(nativeDir, originalFile); + string newFilePath = Path.Combine(nativeDir, newFile); - if (File.Exists(sqliteCorePath)) + try { - File.Move(sqliteCorePath, newFilePath, overwrite: true); - Console.WriteLine($"File renamed successfully from {sqliteCoreFilename} to {newFileName}"); + await DownloadFile($"{baseUrl}/{originalFile}", sqliteCorePath); + + if (File.Exists(sqliteCorePath)) + { + File.Move(sqliteCorePath, newFilePath, overwrite: true); + Console.WriteLine($"File renamed successfully from {originalFile} to {newFile} in {nativeDir}"); + } + else + { + throw new IOException($"File {originalFile} does not exist."); + } } - else + catch (Exception ex) { - throw new IOException($"File {sqliteCoreFilename} does not exist."); + Console.Error.WriteLine($"Error processing {rid}: {ex.Message}"); } } - catch (Exception ex) - { - Console.Error.WriteLine($"Error: {ex.Message}"); - Environment.Exit(1); - } - } - - static string GetRuntimeIdentifier() - { - if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) - { - if (RuntimeInformation.ProcessArchitecture == Architecture.Arm64) - return "osx-arm64"; - else - return "osx-x64"; - } - if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) - { - if (RuntimeInformation.ProcessArchitecture == Architecture.Arm64) - return "linux-arm64"; - else - return "linux-x64"; - } - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - return "win-x64"; - } - throw new PlatformNotSupportedException("Unsupported platform."); - } - - static string GetFileNameForPlatform() - { - if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) - { - return "libpowersync.dylib"; - } - else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) - { - return "libpowersync.so"; - } - else if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - return "powersync.dll"; - } - else - { - throw new PlatformNotSupportedException("Unsupported platform."); - } - } - - static string GetLibraryForPlatform() - { - if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) - { - return RuntimeInformation.ProcessArchitecture == Architecture.Arm64 - ? "libpowersync_aarch64.dylib" - : "libpowersync_x64.dylib"; - } - else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) - { - return RuntimeInformation.ProcessArchitecture == Architecture.Arm64 - ? "libpowersync_aarch64.so" - : "libpowersync_x64.so"; - } - else if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - return "powersync_x64.dll"; - } - else - { - throw new PlatformNotSupportedException("Unsupported platform."); - } } static async Task DownloadFile(string url, string outputPath) diff --git a/icon.png b/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..1e6d62c8a990c6fbe4a294484cbc2ac9312342f5 GIT binary patch literal 1840 zcmV-02haG4P)sI+brhsf6fCs?3@tPn8X!&sv_L7fqqQ`JR_y3l zOQgv7pq+r!k%tOxutLL#j9BGSvBxKDd?BibN?4BgMckjJ>cL_W9kGsF$ z`903}{J!V>?n&8#t|@2=L6z`}cvm9cBjh%!MCDd0RaekMZ#wePLK0KC79n?NqDMZ& zH&G+QIL}N^+{AP;vC&m0SzF4JFo}nmYLd0{FiDui!%VdalK^IBOORZhsWvvIE1g^z z=a{Jp*@&l~md46NH7)goFza7#s+zOy!3ML-;btsmsyP6T!z6=QM3h*}QtWMX$QZNZf5#o2X!eJlYF}t~ z|0aGmKw1VBtI*Yc;AVZc(F_q!(|Ge~P9BuC71oBw=Z&Crg-EDyGm>sxOsLjE?3{O2K;P)iD%aKP}l-9*VMEc z`6r?RQnQ);BB`0eQT-}Ty(fePxADUbjGN223dWT)ZVnyiX+0$Zw0^|+nPPBZi2%uS zkxPEA8bV=FUqY&jq7vHLXl#lmT5mR?1YA?oYYaL~W#USP-zB`9ImY$}MMx!$>X*pB z8TSzJPA3#Qia9CWzt2^lS zMa@4FCzA$kU?F1{$Z73biKYwr9dj96U?f*&E)(WR{5Sm`zfTBny_4c^2$K#EtCzE4 z0m~Oq@m-oe5ZdeiB<_%(JuBYl0^ z!mf={TlEl%D=JKb_R0&i+?Q{`dplZxAmTS$zLt zBR9RBYO_xXb+9G-=QdJ|~?{T8b-O$Pc~7sY4vx%JH{( z`L_f@wK8@ZHBE|QwTh}(qI;UzS@Oi=G5t)|f2$dob^g`0}m z|4%NoGk+oTtJ%3zY^NVIa_>}fa>#WP2=cFEMxv>)rSA9hx0)W17Lgk|=e-_$KDh+D zHsEOs)ymCGnr*Djlg;d_7uu8*7XFOu3Yb;S$WcuBwixLPvTlQPUS4L=plQ*d=?YDI zX?`noYGzXUh|#9Y%ho5Q)9)=6KpJZExu?V!;OnxY>*B`Tr1O|+a5V{RNySt;QT zV$C`eqN%aXTW`v**U}lPm4XshH?ZUdmOW4PAISWQ7}j){clU;BC6##(N|T0qE_{yR z*VabeW|{GdC1M`}UVDRoA1Ag!bxp{sF}9UGCz{_+X9u@TmK)DC*Nf-65o8bKy@t?f zb(qPs1bg!f#L3m#%B27wpXRG0@p$Oy5Kmh>Pd>$mABpkze2dC*;jOEi>WAsB{C6VKyv3rgIMGZH$=Tk)qek(g`4ZqYf1=xOUbO#Kq%p%#L!Mew|bSZu|Uv#p%*4$NZ z6y>37bjuGYweN3S%!U>)?S8HrMC3PQqg^S#$TL|ohnJXF;;PhS z$*fu@8=RB5jli)pyOpH5X=P&4pgF35 zD`uiPw@I{Ul4C%e>zK=DO`@5ZG-&qNB+8mZVKz2s31H)lHHmUlwPa0FSA`A>z?7R| e`Ii9z0RR7}-D-AXWw25J0000 Date: Thu, 27 Mar 2025 09:04:25 +0200 Subject: [PATCH 2/4] Setup GH actions for testing and manual release. Added small flow for windows/.NET 4.8 --- .github/workflows/dev-packages.yml | 40 ++++++++++++++++ .github/workflows/release.yml | 39 +++++++++++++++ .../workflows/{dotnet-test.yml => test.yml} | 9 ++-- CHANGELOG.md | 10 ---- PowerSync/PowerSync.Common/CHANGELOG.md | 10 ++++ .../PowerSync.Common/PowerSync.Common.csproj | 12 +++-- PowerSync/PowerSync.Common/README.md | 14 ++++++ .../Utils/PowerSyncPathResolver.cs | 7 +++ README.md | 48 +++++++------------ .../PowerSyncDatabaseTransactionTests.cs | 20 ++++---- 10 files changed, 151 insertions(+), 58 deletions(-) create mode 100644 .github/workflows/dev-packages.yml create mode 100644 .github/workflows/release.yml rename .github/workflows/{dotnet-test.yml => test.yml} (67%) delete mode 100644 CHANGELOG.md create mode 100644 PowerSync/PowerSync.Common/CHANGELOG.md diff --git a/.github/workflows/dev-packages.yml b/.github/workflows/dev-packages.yml new file mode 100644 index 0000000..664f9fa --- /dev/null +++ b/.github/workflows/dev-packages.yml @@ -0,0 +1,40 @@ +# The version is pulled from the CHANGELOG.md file of the package. +# Add a `-dev.xxx` suffix to the version. +name: Create Dev Release + +on: workflow_dispatch + +jobs: + dev-release: + name: Publish Dev Packages + runs-on: windows-latest + + steps: + - name: Checkout Repository + uses: actions/checkout@v4 + + - name: Setup .NET SDK + uses: actions/setup-dotnet@v4 + with: + dotnet-version: '8.0' + + - name: Download PowerSync extension + run: dotnet run --project Tools/Setup + + - name: Restore dependencies + run: dotnet restore + + - name: Extract Version from CHANGELOG.md + id: extract_version + shell: bash + run: | + VERSION=$(awk '/^## [0-9]+\.[0-9]+\.[0-9]+/ {print $2; exit}' PowerSync/PowerSync.Common/CHANGELOG.md) + echo "Detected Version: $VERSION" + echo "VERSION=$VERSION" >> $GITHUB_ENV + + - name: Run Pack + run: dotnet pack -c Release -o ${{ github.workspace }}/output + + - name: Run Push + run: dotnet nuget push ${{ github.workspace }}\output\*.nupkg --source https://api.nuget.org/v3/index.json --api-key ${{ secrets.NUGET_API_KEY }} + \ No newline at end of file diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..6348fc3 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,39 @@ +# The version is pulled from the CHANGELOG.md file of the package. +name: Release + +on: workflow_dispatch + +jobs: + release: + name: Release + runs-on: windows-latest + + steps: + - name: Checkout Repository + uses: actions/checkout@v4 + + - name: Setup .NET SDK + uses: actions/setup-dotnet@v4 + with: + dotnet-version: '8.0' + + - name: Download PowerSync extension + run: dotnet run --project Tools/Setup + + - name: Restore dependencies + run: dotnet restore + + - name: Extract Version from CHANGELOG.md + id: extract_version + shell: bash + run: | + VERSION=$(awk '/^## [0-9]+\.[0-9]+\.[0-9]+/ {print $2; exit}' PowerSync/PowerSync.Common/CHANGELOG.md) + echo "Detected Version: $VERSION" + echo "VERSION=$VERSION" >> $GITHUB_ENV + + - name: Run Pack + run: dotnet pack -c Release -o ${{ github.workspace }}/output + + - name: Run Push + run: dotnet nuget push ${{ github.workspace }}\output\*.nupkg --source https://api.nuget.org/v3/index.json --api-key ${{ secrets.NUGET_API_KEY }} + \ No newline at end of file diff --git a/.github/workflows/dotnet-test.yml b/.github/workflows/test.yml similarity index 67% rename from .github/workflows/dotnet-test.yml rename to .github/workflows/test.yml index 7dc01c0..42f1e8f 100644 --- a/.github/workflows/dotnet-test.yml +++ b/.github/workflows/test.yml @@ -5,7 +5,7 @@ on: jobs: build: - name: Build and Test .NET Project + name: Test Packages runs-on: windows-latest steps: @@ -17,8 +17,11 @@ jobs: with: dotnet-version: '8.0' + - name: Download PowerSync extension + run: dotnet run --project Tools/Setup + - name: Restore dependencies run: dotnet restore - + - name: Run tests - run: dotnet test -v n \ No newline at end of file + run: dotnet test -v n --framework net8.0 \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md deleted file mode 100644 index d1274a1..0000000 --- a/CHANGELOG.md +++ /dev/null @@ -1,10 +0,0 @@ -## 0.0.1 Pre-Alpha - -Introduce package. - -### Platform Support Added -* linux-arm64 -* linux-x64 -* osx-arm64 -* osx-x64 -* wind-x64 \ No newline at end of file diff --git a/PowerSync/PowerSync.Common/CHANGELOG.md b/PowerSync/PowerSync.Common/CHANGELOG.md new file mode 100644 index 0000000..58e0c7f --- /dev/null +++ b/PowerSync/PowerSync.Common/CHANGELOG.md @@ -0,0 +1,10 @@ +## 0.0.2-alpha.1 + +- Introduce package. Support for Desktop .NET use cases. + +### Platform Runtime Support Added +* linux-arm64 +* linux-x64 +* osx-arm64 +* osx-x64 +* wind-x64 \ No newline at end of file diff --git a/PowerSync/PowerSync.Common/PowerSync.Common.csproj b/PowerSync/PowerSync.Common/PowerSync.Common.csproj index f10832b..4aab2a7 100644 --- a/PowerSync/PowerSync.Common/PowerSync.Common.csproj +++ b/PowerSync/PowerSync.Common/PowerSync.Common.csproj @@ -5,17 +5,20 @@ 12 enable enable + PowerSync.Common PowerSync.Common + PowerSync.Common is a package that enables local-first and real-time reactive apps with embedded SQLite for .NET clients PowerSync powersync Apache-2.0 - https://github.com/powersync-ja/powersync-dotnet + https://github.com/powersync-ja/powersync-dotnet + https://powersync.com true - https://github.com/powersync-ja/powersync-dotnet/CHANGELOG.md + https://github.com/powersync-ja/powersync-dotnet/PowerSync/PowerSync.Common/CHANGELOG.md powersync local-first local-storage state-management offline sql db persistence sqlite sync icon.png - 0.0.1 - pre-alpha + NU5100 + README.md @@ -42,5 +45,6 @@ + diff --git a/PowerSync/PowerSync.Common/README.md b/PowerSync/PowerSync.Common/README.md index 818a081..cb8c852 100644 --- a/PowerSync/PowerSync.Common/README.md +++ b/PowerSync/PowerSync.Common/README.md @@ -2,6 +2,20 @@ This package contains a .NET implementation of a PowerSync database connector and streaming sync bucket implementation. +## ⚠️ Project Status & Release Note + +This package is currently in an alpha state, intended strictly for testing. Expect breaking changes and instability as development continues. + +Do not rely on this package for production use. + +## Installation + +This package is published on [NuGet](https://www.nuget.org/packages/PowerSync.Common). + +```bash +dotnet add package PowerSync.Common --prerelease +``` + ## Usage ### Simple Query diff --git a/PowerSync/PowerSync.Common/Utils/PowerSyncPathResolver.cs b/PowerSync/PowerSync.Common/Utils/PowerSyncPathResolver.cs index 3e203d7..be382d8 100644 --- a/PowerSync/PowerSync.Common/Utils/PowerSyncPathResolver.cs +++ b/PowerSync/PowerSync.Common/Utils/PowerSyncPathResolver.cs @@ -6,6 +6,13 @@ public static class PowerSyncPathResolver { public static string GetNativeLibraryPath(string packagePath) { + + // .NET Framework 4.8 on Windows requires a different path (not supporting versions prior to this) + if (RuntimeInformation.FrameworkDescription.StartsWith(".NET Framework 4.8") && RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + return Path.Combine(AppContext.BaseDirectory, "powersync.dll"); + } + string rid = GetRuntimeIdentifier(); string nativeDir = Path.Combine(packagePath, "runtimes", rid, "native"); diff --git a/README.md b/README.md index fc1bd55..62b8233 100644 --- a/README.md +++ b/README.md @@ -8,14 +8,10 @@ _[PowerSync](https://www.powersync.com) is a sync engine for building local-firs `powersync-dotnet` is the monorepo for PowerSync .NET SDKs. -## ⚠️ Project Status & Release Note - -This package is part of a monorepo that is not yet officially released or published. It is currently in a pre-alpha state, intended strictly for closed testing. Expect breaking changes and instability as development continues. - -Do not rely on this package for production use. - ## Monorepo Structure: Packages +Packages are published to [NuGet](https://www.nuget.org/profiles/PowerSync). + - [PowerSync/Common](./PowerSync/Common/README.md) - Core package: .NET implementation of a PowerSync database connector and streaming sync bucket implementation. Packages meant for specific platforms will extend functionality of `Common`. @@ -54,6 +50,18 @@ This PowerSync SDK currently targets the following .NET versions: ``` + + and create a `IsExternalInit.cs` file in your project with the following contents: + + ```cs + using System.ComponentModel; + + namespace System.Runtime.CompilerServices + { + [EditorBrowsable(EditorBrowsableState.Never)] + internal class IsExternalInit { } + } + ``` ------- @@ -87,29 +95,7 @@ Run a specific test dotnet test -v n --framework net8.0 --filter "test-file-pattern" ``` -## Using the PowerSync.Common package in your project (temporary) -A NuGet package will be available soon, until then you clone this repo and follow these steps: - -Add the dependency to your project's .csproj: -```.xml - - - -``` - -Which assumes the following directory structure: -``` -code/ - powersync-dotnet (X) - ├── PowerSync/PowerSync.Common - │ ├── PowerSync.Common.csproj - │ ├── Class1.cs - │ └── Utils.cs - └── root.sln - - your-project - ├── demo - │ ├── Program.csproj - │ └── Program.cs - ├── root.sln +## Using the PowerSync.Common package in your project +```bash +dotnet add package PowerSync.Common --prerelease ``` \ No newline at end of file diff --git a/Tests/PowerSync/PowerSync.Common.Tests/Client/PowerSyncDatabaseTransactionTests.cs b/Tests/PowerSync/PowerSync.Common.Tests/Client/PowerSyncDatabaseTransactionTests.cs index 40e84b1..d9a1614 100644 --- a/Tests/PowerSync/PowerSync.Common.Tests/Client/PowerSyncDatabaseTransactionTests.cs +++ b/Tests/PowerSync/PowerSync.Common.Tests/Client/PowerSyncDatabaseTransactionTests.cs @@ -189,7 +189,7 @@ await db.Execute( [Fact(Timeout = 2000)] public async Task ReadWhileWriteIsRunningTest() { - var tcs = new TaskCompletionSource(); + var tcs = new TaskCompletionSource(); // This wont resolve or free until another connection free's it var writeTask = db.WriteLock(async context => @@ -200,7 +200,7 @@ public async Task ReadWhileWriteIsRunningTest() var readTask = db.ReadLock(async context => { // Read logic could execute here while writeLock is still open - tcs.SetResult(); + tcs.SetResult(true); await Task.CompletedTask; return 42; }); @@ -238,13 +238,13 @@ await db.WriteLock(async context => public async Task CallUpdateHookOnChangesTest() { var cts = new CancellationTokenSource(); - var result = new TaskCompletionSource(); + var result = new TaskCompletionSource(); db.OnChange(new WatchOnChangeHandler { OnChange = (x) => { - result.SetResult(); + result.SetResult(true); cts.Cancel(); return Task.CompletedTask; } @@ -261,7 +261,7 @@ public async Task CallUpdateHookOnChangesTest() [Fact(Timeout = 2000)] public async Task ReflectWriteTransactionUpdatesOnReadConnectionsTest() { - var watched = new TaskCompletionSource(); + var watched = new TaskCompletionSource(); var cts = new CancellationTokenSource(); await db.Watch("SELECT COUNT(*) as count FROM assets", null, new WatchHandler @@ -270,7 +270,7 @@ public async Task ReflectWriteTransactionUpdatesOnReadConnectionsTest() { if (x.First().count == 1) { - watched.SetResult(); + watched.SetResult(true); cts.Cancel(); } } @@ -292,7 +292,7 @@ public async Task ReflectWriteLockUpdatesOnReadConnectionsTest() { var numberOfAssets = 10_000; - var watched = new TaskCompletionSource(); + var watched = new TaskCompletionSource(); var cts = new CancellationTokenSource(); await db.Watch("SELECT COUNT(*) as count FROM assets", null, new WatchHandler @@ -301,7 +301,7 @@ public async Task ReflectWriteLockUpdatesOnReadConnectionsTest() { if (x.First().count == numberOfAssets) { - watched.SetResult(); + watched.SetResult(true); cts.Cancel(); } } @@ -324,12 +324,12 @@ await db.WriteLock(async tx => } [Fact(Timeout = 5000)] - public async Task Insert10000Records_CompleteWithinTimeLimitTest() + public async Task Insert1000Records_CompleteWithinTimeLimitTest() { var random = new Random(); var stopwatch = Stopwatch.StartNew(); - for (int i = 0; i < 10000; ++i) + for (int i = 0; i < 1000; ++i) { int n = random.Next(0, 100000); await db.Execute( From 0c181c495e59cefb17af0df23a4df419dafabb2e Mon Sep 17 00:00:00 2001 From: Christiaan Landman Date: Thu, 27 Mar 2025 11:38:34 +0200 Subject: [PATCH 3/4] Filtering on dev suffix for dev-packages release. Release flow will only work on a main branch call. --- .github/workflows/dev-packages.yml | 2 +- .github/workflows/release.yml | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/dev-packages.yml b/.github/workflows/dev-packages.yml index 664f9fa..a082f82 100644 --- a/.github/workflows/dev-packages.yml +++ b/.github/workflows/dev-packages.yml @@ -28,7 +28,7 @@ jobs: id: extract_version shell: bash run: | - VERSION=$(awk '/^## [0-9]+\.[0-9]+\.[0-9]+/ {print $2; exit}' PowerSync/PowerSync.Common/CHANGELOG.md) + VERSION=$(awk '/^## [0-9]+\.[0-9]+\.[0-9]+-dev(\.[0-9]+)?$/ {print $2; exit}' PowerSync/PowerSync.Common/CHANGELOG.md) echo "Detected Version: $VERSION" echo "VERSION=$VERSION" >> $GITHUB_ENV diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 6348fc3..cfbff30 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -7,6 +7,7 @@ jobs: release: name: Release runs-on: windows-latest + if: github.ref == 'refs/heads/main' steps: - name: Checkout Repository From f9842eee9570ef1d962e895601588cf0b6395d9a Mon Sep 17 00:00:00 2001 From: Christiaan Landman Date: Thu, 27 Mar 2025 13:15:26 +0200 Subject: [PATCH 4/4] Ensuring that RunListener/RunListenerAsync blocks until it has initialised. --- PowerSync/PowerSync.Common/Utils/EventStream.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/PowerSync/PowerSync.Common/Utils/EventStream.cs b/PowerSync/PowerSync.Common/Utils/EventStream.cs index 38afd48..671abcd 100644 --- a/PowerSync/PowerSync.Common/Utils/EventStream.cs +++ b/PowerSync/PowerSync.Common/Utils/EventStream.cs @@ -53,9 +53,11 @@ public CancellationTokenSource RunListenerAsync( Func callback) { var cts = new CancellationTokenSource(); + var started = new TaskCompletionSource(); _ = Task.Run(async () => { + started.SetResult(true); await foreach (var value in ListenAsync(cts.Token)) { await callback(value); @@ -63,6 +65,8 @@ public CancellationTokenSource RunListenerAsync( }, cts.Token); + started.Task.GetAwaiter().GetResult(); + return cts; } @@ -76,15 +80,19 @@ public IAsyncEnumerable ListenAsync(CancellationToken cancellationToken) public CancellationTokenSource RunListener(Action callback) { var cts = new CancellationTokenSource(); + var started = new TaskCompletionSource(); _ = Task.Run(() => { + started.SetResult(true); foreach (var value in Listen(cts.Token)) { callback(value); } }, cts.Token); + started.Task.GetAwaiter().GetResult(); + return cts; }