Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 980342d566 | |||
| 55bc54c0b8 | |||
| e6397c301d | |||
| 74d40e40a9 | |||
| c81692ee5a | |||
| 7f50987201 |
@@ -54,7 +54,7 @@ jobs:
|
||||
run: dotnet test ${{ env.Solution }} --filter "(Category=Integration)&(Server!=Public)" --configuration Release --no-build --no-restore --verbosity=normal /p:AltCover=true /p:AltCoverAttributeFilter=ExcludeFromCodeCoverage
|
||||
|
||||
- name: Upload coverage reports to Codecov with GitHub Action
|
||||
uses: codecov/codecov-action@v5
|
||||
uses: codecov/codecov-action@v6
|
||||
continue-on-error: true
|
||||
with:
|
||||
fail_ci_if_error: true
|
||||
|
||||
@@ -42,7 +42,7 @@ jobs:
|
||||
run: dotnet pack ${{ env.Solution }} --configuration Release --no-build
|
||||
|
||||
- name: Upload coverage reports to Codecov with GitHub Action
|
||||
uses: codecov/codecov-action@v5
|
||||
uses: codecov/codecov-action@v6
|
||||
continue-on-error: true
|
||||
with:
|
||||
fail_ci_if_error: true
|
||||
|
||||
+1
-1
@@ -168,7 +168,7 @@ Target(
|
||||
|
||||
Target(
|
||||
PACK,
|
||||
dependsOn: [TEST],
|
||||
dependsOn: [BUILD],
|
||||
async () =>
|
||||
{
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup Label="Compiler Properties">
|
||||
<TargetFrameworks>netstandard2.0;net8.0</TargetFrameworks>
|
||||
<TargetFrameworks>net8.0</TargetFrameworks>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="Nugetspec Package Properties">
|
||||
<PackageId>Speckle.Automate.Sdk</PackageId>
|
||||
|
||||
@@ -1,368 +1,6 @@
|
||||
{
|
||||
"version": 2,
|
||||
"dependencies": {
|
||||
".NETStandard,Version=v2.0": {
|
||||
"Microsoft.SourceLink.GitHub": {
|
||||
"type": "Direct",
|
||||
"requested": "[8.0.0, )",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "G5q7OqtwIyGTkeIOAc3u2ZuV/kicQaec5EaRnc0pIeSnh9LUjj+PYQrJYBURvDt7twGl2PKA7nSN0kz1Zw5bnQ==",
|
||||
"dependencies": {
|
||||
"Microsoft.Build.Tasks.Git": "8.0.0",
|
||||
"Microsoft.SourceLink.Common": "8.0.0"
|
||||
}
|
||||
},
|
||||
"NETStandard.Library": {
|
||||
"type": "Direct",
|
||||
"requested": "[2.0.3, )",
|
||||
"resolved": "2.0.3",
|
||||
"contentHash": "st47PosZSHrjECdjeIzZQbzivYBJFv6P2nv4cj2ypdI204DO+vZ7l5raGMiX4eXMJ53RfOIg+/s4DHVZ54Nu2A==",
|
||||
"dependencies": {
|
||||
"Microsoft.NETCore.Platforms": "1.1.0"
|
||||
}
|
||||
},
|
||||
"Newtonsoft.Json.Schema": {
|
||||
"type": "Direct",
|
||||
"requested": "[4.0.1, )",
|
||||
"resolved": "4.0.1",
|
||||
"contentHash": "rbHUKp5WTIbqmLEeJ21nTTDGcfR0LA7bVMzm0bYc3yx6NFKiCIHzzvYbwA4Sqgs7+wNldc5nBlkbithWj8IZig==",
|
||||
"dependencies": {
|
||||
"Newtonsoft.Json": "13.0.3"
|
||||
}
|
||||
},
|
||||
"PolySharp": {
|
||||
"type": "Direct",
|
||||
"requested": "[1.15.0, )",
|
||||
"resolved": "1.15.0",
|
||||
"contentHash": "FbU0El+EEjdpuIX4iDbeS7ki1uzpJPx8vbqOzEtqnl1GZeAGJfq+jCbxeJL2y0EPnUNk8dRnnqR2xnYXg9Tf+g=="
|
||||
},
|
||||
"Speckle.InterfaceGenerator": {
|
||||
"type": "Direct",
|
||||
"requested": "[0.9.6, )",
|
||||
"resolved": "0.9.6",
|
||||
"contentHash": "HKH7tYrYYlCK1ct483hgxERAdVdMtl7gUKW9ijWXxA1UsYR4Z+TrRHYmzZ9qmpu1NnTycSrp005NYM78GDKV1w=="
|
||||
},
|
||||
"System.CommandLine": {
|
||||
"type": "Direct",
|
||||
"requested": "[2.0.0-beta4.22272.1, )",
|
||||
"resolved": "2.0.0-beta4.22272.1",
|
||||
"contentHash": "1uqED/q2H0kKoLJ4+hI2iPSBSEdTuhfCYADeJrAqERmiGQ2NNacYKRNEQ+gFbU4glgVyK8rxI+ZOe1onEtr/Pg==",
|
||||
"dependencies": {
|
||||
"System.Memory": "4.5.4"
|
||||
}
|
||||
},
|
||||
"System.Text.Json": {
|
||||
"type": "Direct",
|
||||
"requested": "[8.0.5, )",
|
||||
"resolved": "8.0.5",
|
||||
"contentHash": "0f1B50Ss7rqxXiaBJyzUu9bWFOO2/zSlifZ/UNMdiIpDYe4cY4LQQicP4nirK1OS31I43rn062UIJ1Q9bpmHpg==",
|
||||
"dependencies": {
|
||||
"Microsoft.Bcl.AsyncInterfaces": "8.0.0",
|
||||
"System.Buffers": "4.5.1",
|
||||
"System.Memory": "4.5.5",
|
||||
"System.Runtime.CompilerServices.Unsafe": "6.0.0",
|
||||
"System.Text.Encodings.Web": "8.0.0",
|
||||
"System.Threading.Tasks.Extensions": "4.5.4"
|
||||
}
|
||||
},
|
||||
"GraphQL.Client.Abstractions": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "h7uzWFORHZ+CCjwr/ThAyXMr0DPpzEANDa4Uo54wqCQ+j7qUKwqYTgOrb1W40sqbvNaZm9v/X7It31SUw0maHA==",
|
||||
"dependencies": {
|
||||
"GraphQL.Primitives": "6.0.0"
|
||||
}
|
||||
},
|
||||
"GraphQL.Client.Abstractions.Websocket": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "Nr9bPf8gIOvLuXpqEpqr9z9jslYFJOvd0feHth3/kPqeR3uMbjF5pjiwh4jxyMcxHdr8Pb6QiXkV3hsSyt0v7A==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client.Abstractions": "6.0.0"
|
||||
}
|
||||
},
|
||||
"GraphQL.Primitives": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "yg72rrYDapfsIUrul7aF6wwNnTJBOFvuA9VdDTQpPa8AlAriHbufeXYLBcodKjfUdkCnaiggX1U/nEP08Zb5GA=="
|
||||
},
|
||||
"Microsoft.Build.Tasks.Git": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "bZKfSIKJRXLTuSzLudMFte/8CempWjVamNUR5eHJizsy+iuOuO/k2gnh7W0dHJmYY0tBf+gUErfluCv5mySAOQ=="
|
||||
},
|
||||
"Microsoft.Data.Sqlite.Core": {
|
||||
"type": "Transitive",
|
||||
"resolved": "7.0.5",
|
||||
"contentHash": "FTerRmQPqHrCrnoUzhBu+E+1DNGwyrAMLqHkAqOOOu5pGfyMOj8qQUBxI/gDtWtG11p49UxSfWmBzRNlwZqfUg==",
|
||||
"dependencies": {
|
||||
"SQLitePCLRaw.core": "2.1.4"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Configuration": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "nOP8R1mVb/6mZtm2qgAJXn/LFm/2kMjHDAg/QJLFG6CuWYJtaD3p1BwQhufBVvRzL9ceJ/xF0SQ0qsI2GkDQAA==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Configuration.Abstractions": "2.2.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Configuration.Abstractions": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "65MrmXCziWaQFrI0UHkQbesrX5wTwf9XPjY5yFm/VkgJKFJ5gqvXRoXjIZcf2wLi5ZlwGz/oMYfyURVCWbM5iw==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Primitives": "2.2.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Configuration.Binder": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "vJ9xvOZCnUAIHcGC3SU35r3HKmHTVIeHzo6u/qzlHAqD8m6xv92MLin4oJntTvkpKxVX3vI1GFFkIQtU3AdlsQ==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Configuration": "2.2.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Logging.Abstractions": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "B2WqEox8o+4KUOpL7rZPyh6qYjik8tHi2tN8Z9jZkHzED8ElYgZa/h6K+xliB435SqUcWT290Fr2aa8BtZjn8A=="
|
||||
},
|
||||
"Microsoft.Extensions.Options": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "UpZLNLBpIZ0GTebShui7xXYh6DmBHjWM8NxGxZbdQh/bPZ5e6YswqI+bru6BnEL5eWiOdodsXtEz3FROcgi/qg==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Primitives": "2.2.0",
|
||||
"System.ComponentModel.Annotations": "4.5.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Primitives": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "azyQtqbm4fSaDzZHD/J+V6oWMFaf2tWP4WEGIYePLCMw3+b2RQdj9ybgbQyjCshcitQKQ4lEDOZjmSlTTrHxUg==",
|
||||
"dependencies": {
|
||||
"System.Memory": "4.5.1",
|
||||
"System.Runtime.CompilerServices.Unsafe": "4.5.1"
|
||||
}
|
||||
},
|
||||
"Microsoft.NETCore.Platforms": {
|
||||
"type": "Transitive",
|
||||
"resolved": "1.1.0",
|
||||
"contentHash": "kz0PEW2lhqygehI/d6XsPCQzD7ff7gUJaVGPVETX611eadGsA3A877GdSlU0LRVMCTH/+P3o2iDTak+S08V2+A=="
|
||||
},
|
||||
"Microsoft.NETCore.Targets": {
|
||||
"type": "Transitive",
|
||||
"resolved": "1.1.0",
|
||||
"contentHash": "aOZA3BWfz9RXjpzt0sRJJMjAscAUm3Hoa4UWAfceV9UTYxgwZ1lZt5nO2myFf+/jetYQo4uTP7zS8sJY67BBxg=="
|
||||
},
|
||||
"Microsoft.SourceLink.Common": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw=="
|
||||
},
|
||||
"Newtonsoft.Json": {
|
||||
"type": "Transitive",
|
||||
"resolved": "13.0.3",
|
||||
"contentHash": "HrC5BXdl00IP9zeV+0Z848QWPAoCr9P3bDEZguI+gkLcBKAOxix/tLEAAHC+UvDNPv4a2d18lOReHMOagPa+zQ=="
|
||||
},
|
||||
"SQLitePCLRaw.bundle_e_sqlite3": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.1.4",
|
||||
"contentHash": "EWI1olKDjFEBMJu0+3wuxwziIAdWDVMYLhuZ3Qs84rrz+DHwD00RzWPZCa+bLnHCf3oJwuFZIRsHT5p236QXww==",
|
||||
"dependencies": {
|
||||
"SQLitePCLRaw.lib.e_sqlite3": "2.1.4",
|
||||
"SQLitePCLRaw.provider.e_sqlite3": "2.1.4"
|
||||
}
|
||||
},
|
||||
"SQLitePCLRaw.core": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.1.4",
|
||||
"contentHash": "inBjvSHo9UDKneGNzfUfDjK08JzlcIhn1+SP5Y3m6cgXpCxXKCJDy6Mka7LpgSV+UZmKSnC8rTwB0SQ0xKu5pA==",
|
||||
"dependencies": {
|
||||
"System.Memory": "4.5.3"
|
||||
}
|
||||
},
|
||||
"SQLitePCLRaw.lib.e_sqlite3": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.1.4",
|
||||
"contentHash": "2C9Q9eX7CPLveJA0rIhf9RXAvu+7nWZu1A2MdG6SD/NOu26TakGgL1nsbc0JAspGijFOo3HoN79xrx8a368fBg=="
|
||||
},
|
||||
"SQLitePCLRaw.provider.e_sqlite3": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.1.4",
|
||||
"contentHash": "CSlb5dUp1FMIkez9Iv5EXzpeq7rHryVNqwJMWnpq87j9zWZexaEMdisDktMsnnrzKM6ahNrsTkjqNodTBPBxtQ==",
|
||||
"dependencies": {
|
||||
"SQLitePCLRaw.core": "2.1.4"
|
||||
}
|
||||
},
|
||||
"System.Buffers": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.5.1",
|
||||
"contentHash": "Rw7ijyl1qqRS0YQD/WycNst8hUUMgrMH4FCn1nNm27M4VxchZ1js3fVjQaANHO5f3sN4isvP4a+Met9Y4YomAg=="
|
||||
},
|
||||
"System.ComponentModel.Annotations": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.5.0",
|
||||
"contentHash": "UxYQ3FGUOtzJ7LfSdnYSFd7+oEv6M8NgUatatIN2HxNtDdlcvFAf+VIq4Of9cDMJEJC0aSRv/x898RYhB4Yppg=="
|
||||
},
|
||||
"System.Memory": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.5.5",
|
||||
"contentHash": "XIWiDvKPXaTveaB7HVganDlOCRoj03l+jrwNvcge/t8vhGYKvqV+dMv6G4SAX2NoNmN0wZfVPTAlFwZcZvVOUw==",
|
||||
"dependencies": {
|
||||
"System.Buffers": "4.5.1",
|
||||
"System.Numerics.Vectors": "4.4.0",
|
||||
"System.Runtime.CompilerServices.Unsafe": "4.5.3"
|
||||
}
|
||||
},
|
||||
"System.Numerics.Vectors": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.4.0",
|
||||
"contentHash": "UiLzLW+Lw6HLed1Hcg+8jSRttrbuXv7DANVj0DkL9g6EnnzbL75EB7EWsw5uRbhxd/4YdG8li5XizGWepmG3PQ=="
|
||||
},
|
||||
"System.Reactive": {
|
||||
"type": "Transitive",
|
||||
"resolved": "5.0.0",
|
||||
"contentHash": "erBZjkQHWL9jpasCE/0qKAryzVBJFxGHVBAvgRN1bzM0q2s1S4oYREEEL0Vb+1kA/6BKb5FjUZMp5VXmy+gzkQ==",
|
||||
"dependencies": {
|
||||
"System.Runtime.InteropServices.WindowsRuntime": "4.3.0",
|
||||
"System.Threading.Tasks.Extensions": "4.5.4"
|
||||
}
|
||||
},
|
||||
"System.Runtime": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.3.0",
|
||||
"contentHash": "JufQi0vPQ0xGnAczR13AUFglDyVYt4Kqnz1AZaiKZ5+GICq0/1MH/mO/eAJHt/mHW1zjKBJd7kV26SrxddAhiw==",
|
||||
"dependencies": {
|
||||
"Microsoft.NETCore.Platforms": "1.1.0",
|
||||
"Microsoft.NETCore.Targets": "1.1.0"
|
||||
}
|
||||
},
|
||||
"System.Runtime.CompilerServices.Unsafe": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "/iUeP3tq1S0XdNNoMz5C9twLSrM/TH+qElHkXWaPvuNOt+99G75NrV0OS2EqHx5wMN7popYjpc8oTjC1y16DLg=="
|
||||
},
|
||||
"System.Runtime.InteropServices.WindowsRuntime": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.3.0",
|
||||
"contentHash": "J4GUi3xZQLUBasNwZnjrffN8i5wpHrBtZoLG+OhRyGo/+YunMRWWtwoMDlUAIdmX0uRfpHIBDSV6zyr3yf00TA==",
|
||||
"dependencies": {
|
||||
"System.Runtime": "4.3.0"
|
||||
}
|
||||
},
|
||||
"System.Text.Encodings.Web": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "yev/k9GHAEGx2Rg3/tU6MQh4HGBXJs70y7j1LaM1i/ER9po+6nnQ6RRqTJn1E7Xu0fbIFK80Nh5EoODxrbxwBQ==",
|
||||
"dependencies": {
|
||||
"System.Buffers": "4.5.1",
|
||||
"System.Memory": "4.5.5",
|
||||
"System.Runtime.CompilerServices.Unsafe": "6.0.0"
|
||||
}
|
||||
},
|
||||
"System.Threading.Tasks.Extensions": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.5.4",
|
||||
"contentHash": "zteT+G8xuGu6mS+mzDzYXbzS7rd3K6Fjb9RiZlYlJPam2/hU7JCBZBVEcywNuR+oZ1ncTvc/cq0faRr3P01OVg==",
|
||||
"dependencies": {
|
||||
"System.Runtime.CompilerServices.Unsafe": "4.5.3"
|
||||
}
|
||||
},
|
||||
"speckle.objects": {
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "[1.0.0, )"
|
||||
}
|
||||
},
|
||||
"speckle.sdk": {
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "[6.0.0, )",
|
||||
"Microsoft.CSharp": "[4.7.0, )",
|
||||
"Microsoft.Data.Sqlite": "[7.0.5, )",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0, )",
|
||||
"Microsoft.Extensions.Logging": "[2.2.0, )",
|
||||
"Speckle.DoubleNumerics": "[4.1.0, )",
|
||||
"Speckle.Newtonsoft.Json": "[13.0.2, )",
|
||||
"Speckle.Sdk.Dependencies": "[1.0.0, )"
|
||||
}
|
||||
},
|
||||
"speckle.sdk.dependencies": {
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Bcl.AsyncInterfaces": "[9.0.4, )"
|
||||
}
|
||||
},
|
||||
"GraphQL.Client": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[6.0.0, )",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "8yPNBbuVBpTptivyAlak4GZvbwbUcjeQTL4vN1HKHRuOykZ4r7l5fcLS6vpyPyLn0x8FsL31xbOIKyxbmR9rbA==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client.Abstractions": "6.0.0",
|
||||
"GraphQL.Client.Abstractions.Websocket": "6.0.0",
|
||||
"System.Reactive": "5.0.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Bcl.AsyncInterfaces": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[9.0.4, )",
|
||||
"resolved": "9.0.4",
|
||||
"contentHash": "9VGI5kxIvrNG2mqLQZnUR6y/3fcnygD8eNpHR+CqfbnIXvea6nehnYknDKQTxZVPMpzpNca+7DxLBmpdB3q0Bw==",
|
||||
"dependencies": {
|
||||
"System.Threading.Tasks.Extensions": "4.5.4"
|
||||
}
|
||||
},
|
||||
"Microsoft.CSharp": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[4.7.0, )",
|
||||
"resolved": "4.7.0",
|
||||
"contentHash": "pTj+D3uJWyN3My70i2Hqo+OXixq3Os2D1nJ2x92FFo6sk8fYS1m1WLNTs0Dc1uPaViH0YvEEwvzddQ7y4rhXmA=="
|
||||
},
|
||||
"Microsoft.Data.Sqlite": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[7.0.5, )",
|
||||
"resolved": "7.0.5",
|
||||
"contentHash": "KGxbPeWsQMnmQy43DSBxAFtHz3l2JX8EWBSGUCvT3CuZ8KsuzbkqMIJMDOxWtG8eZSoCDI04aiVQjWuuV8HmSw==",
|
||||
"dependencies": {
|
||||
"Microsoft.Data.Sqlite.Core": "7.0.5",
|
||||
"SQLitePCLRaw.bundle_e_sqlite3": "2.1.4"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[2.2.0, )",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
|
||||
},
|
||||
"Microsoft.Extensions.Logging": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[2.2.0, )",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "Nxqhadc9FCmFHzU+fz3oc8sFlE6IadViYg8dfUdGzJZ2JUxnCsRghBhhOWdM4B2zSZqEc+0BjliBh/oNdRZuig==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Configuration.Binder": "2.2.0",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Options": "2.2.0"
|
||||
}
|
||||
},
|
||||
"Speckle.DoubleNumerics": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[4.1.0, )",
|
||||
"resolved": "4.1.0",
|
||||
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
|
||||
},
|
||||
"Speckle.Newtonsoft.Json": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[13.0.2, )",
|
||||
"resolved": "13.0.2",
|
||||
"contentHash": "g1BejUZwax5PRfL6xHgLEK23sqHWOgOj9hE7RvfRRlN00AGt8GnPYt8HedSK7UB3HiRW8zCA9Pn0iiYxCK24BA=="
|
||||
}
|
||||
},
|
||||
"net8.0": {
|
||||
"Microsoft.SourceLink.GitHub": {
|
||||
"type": "Direct",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup Label="Compiler Properties">
|
||||
<TargetFrameworks>netstandard2.0;net8.0</TargetFrameworks>
|
||||
<TargetFrameworks>net8.0</TargetFrameworks>
|
||||
<PolySharpExcludeGeneratedTypes>System.Runtime.CompilerServices.RequiresLocationAttribute</PolySharpExcludeGeneratedTypes>
|
||||
<Configurations>Debug;Release;Local</Configurations>
|
||||
</PropertyGroup>
|
||||
|
||||
@@ -1,315 +1,6 @@
|
||||
{
|
||||
"version": 2,
|
||||
"dependencies": {
|
||||
".NETStandard,Version=v2.0": {
|
||||
"Microsoft.SourceLink.GitHub": {
|
||||
"type": "Direct",
|
||||
"requested": "[8.0.0, )",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "G5q7OqtwIyGTkeIOAc3u2ZuV/kicQaec5EaRnc0pIeSnh9LUjj+PYQrJYBURvDt7twGl2PKA7nSN0kz1Zw5bnQ==",
|
||||
"dependencies": {
|
||||
"Microsoft.Build.Tasks.Git": "8.0.0",
|
||||
"Microsoft.SourceLink.Common": "8.0.0"
|
||||
}
|
||||
},
|
||||
"NETStandard.Library": {
|
||||
"type": "Direct",
|
||||
"requested": "[2.0.3, )",
|
||||
"resolved": "2.0.3",
|
||||
"contentHash": "st47PosZSHrjECdjeIzZQbzivYBJFv6P2nv4cj2ypdI204DO+vZ7l5raGMiX4eXMJ53RfOIg+/s4DHVZ54Nu2A==",
|
||||
"dependencies": {
|
||||
"Microsoft.NETCore.Platforms": "1.1.0"
|
||||
}
|
||||
},
|
||||
"PolySharp": {
|
||||
"type": "Direct",
|
||||
"requested": "[1.15.0, )",
|
||||
"resolved": "1.15.0",
|
||||
"contentHash": "FbU0El+EEjdpuIX4iDbeS7ki1uzpJPx8vbqOzEtqnl1GZeAGJfq+jCbxeJL2y0EPnUNk8dRnnqR2xnYXg9Tf+g=="
|
||||
},
|
||||
"Speckle.InterfaceGenerator": {
|
||||
"type": "Direct",
|
||||
"requested": "[0.9.6, )",
|
||||
"resolved": "0.9.6",
|
||||
"contentHash": "HKH7tYrYYlCK1ct483hgxERAdVdMtl7gUKW9ijWXxA1UsYR4Z+TrRHYmzZ9qmpu1NnTycSrp005NYM78GDKV1w=="
|
||||
},
|
||||
"GraphQL.Client.Abstractions": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "h7uzWFORHZ+CCjwr/ThAyXMr0DPpzEANDa4Uo54wqCQ+j7qUKwqYTgOrb1W40sqbvNaZm9v/X7It31SUw0maHA==",
|
||||
"dependencies": {
|
||||
"GraphQL.Primitives": "6.0.0"
|
||||
}
|
||||
},
|
||||
"GraphQL.Client.Abstractions.Websocket": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "Nr9bPf8gIOvLuXpqEpqr9z9jslYFJOvd0feHth3/kPqeR3uMbjF5pjiwh4jxyMcxHdr8Pb6QiXkV3hsSyt0v7A==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client.Abstractions": "6.0.0"
|
||||
}
|
||||
},
|
||||
"GraphQL.Primitives": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "yg72rrYDapfsIUrul7aF6wwNnTJBOFvuA9VdDTQpPa8AlAriHbufeXYLBcodKjfUdkCnaiggX1U/nEP08Zb5GA=="
|
||||
},
|
||||
"Microsoft.Build.Tasks.Git": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "bZKfSIKJRXLTuSzLudMFte/8CempWjVamNUR5eHJizsy+iuOuO/k2gnh7W0dHJmYY0tBf+gUErfluCv5mySAOQ=="
|
||||
},
|
||||
"Microsoft.Data.Sqlite.Core": {
|
||||
"type": "Transitive",
|
||||
"resolved": "7.0.5",
|
||||
"contentHash": "FTerRmQPqHrCrnoUzhBu+E+1DNGwyrAMLqHkAqOOOu5pGfyMOj8qQUBxI/gDtWtG11p49UxSfWmBzRNlwZqfUg==",
|
||||
"dependencies": {
|
||||
"SQLitePCLRaw.core": "2.1.4"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Configuration": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "nOP8R1mVb/6mZtm2qgAJXn/LFm/2kMjHDAg/QJLFG6CuWYJtaD3p1BwQhufBVvRzL9ceJ/xF0SQ0qsI2GkDQAA==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Configuration.Abstractions": "2.2.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Configuration.Abstractions": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "65MrmXCziWaQFrI0UHkQbesrX5wTwf9XPjY5yFm/VkgJKFJ5gqvXRoXjIZcf2wLi5ZlwGz/oMYfyURVCWbM5iw==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Primitives": "2.2.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Configuration.Binder": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "vJ9xvOZCnUAIHcGC3SU35r3HKmHTVIeHzo6u/qzlHAqD8m6xv92MLin4oJntTvkpKxVX3vI1GFFkIQtU3AdlsQ==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Configuration": "2.2.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Logging.Abstractions": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "B2WqEox8o+4KUOpL7rZPyh6qYjik8tHi2tN8Z9jZkHzED8ElYgZa/h6K+xliB435SqUcWT290Fr2aa8BtZjn8A=="
|
||||
},
|
||||
"Microsoft.Extensions.Options": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "UpZLNLBpIZ0GTebShui7xXYh6DmBHjWM8NxGxZbdQh/bPZ5e6YswqI+bru6BnEL5eWiOdodsXtEz3FROcgi/qg==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Primitives": "2.2.0",
|
||||
"System.ComponentModel.Annotations": "4.5.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Primitives": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "azyQtqbm4fSaDzZHD/J+V6oWMFaf2tWP4WEGIYePLCMw3+b2RQdj9ybgbQyjCshcitQKQ4lEDOZjmSlTTrHxUg==",
|
||||
"dependencies": {
|
||||
"System.Memory": "4.5.1",
|
||||
"System.Runtime.CompilerServices.Unsafe": "4.5.1"
|
||||
}
|
||||
},
|
||||
"Microsoft.NETCore.Platforms": {
|
||||
"type": "Transitive",
|
||||
"resolved": "1.1.0",
|
||||
"contentHash": "kz0PEW2lhqygehI/d6XsPCQzD7ff7gUJaVGPVETX611eadGsA3A877GdSlU0LRVMCTH/+P3o2iDTak+S08V2+A=="
|
||||
},
|
||||
"Microsoft.NETCore.Targets": {
|
||||
"type": "Transitive",
|
||||
"resolved": "1.1.0",
|
||||
"contentHash": "aOZA3BWfz9RXjpzt0sRJJMjAscAUm3Hoa4UWAfceV9UTYxgwZ1lZt5nO2myFf+/jetYQo4uTP7zS8sJY67BBxg=="
|
||||
},
|
||||
"Microsoft.SourceLink.Common": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw=="
|
||||
},
|
||||
"SQLitePCLRaw.bundle_e_sqlite3": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.1.4",
|
||||
"contentHash": "EWI1olKDjFEBMJu0+3wuxwziIAdWDVMYLhuZ3Qs84rrz+DHwD00RzWPZCa+bLnHCf3oJwuFZIRsHT5p236QXww==",
|
||||
"dependencies": {
|
||||
"SQLitePCLRaw.lib.e_sqlite3": "2.1.4",
|
||||
"SQLitePCLRaw.provider.e_sqlite3": "2.1.4"
|
||||
}
|
||||
},
|
||||
"SQLitePCLRaw.core": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.1.4",
|
||||
"contentHash": "inBjvSHo9UDKneGNzfUfDjK08JzlcIhn1+SP5Y3m6cgXpCxXKCJDy6Mka7LpgSV+UZmKSnC8rTwB0SQ0xKu5pA==",
|
||||
"dependencies": {
|
||||
"System.Memory": "4.5.3"
|
||||
}
|
||||
},
|
||||
"SQLitePCLRaw.lib.e_sqlite3": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.1.4",
|
||||
"contentHash": "2C9Q9eX7CPLveJA0rIhf9RXAvu+7nWZu1A2MdG6SD/NOu26TakGgL1nsbc0JAspGijFOo3HoN79xrx8a368fBg=="
|
||||
},
|
||||
"SQLitePCLRaw.provider.e_sqlite3": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.1.4",
|
||||
"contentHash": "CSlb5dUp1FMIkez9Iv5EXzpeq7rHryVNqwJMWnpq87j9zWZexaEMdisDktMsnnrzKM6ahNrsTkjqNodTBPBxtQ==",
|
||||
"dependencies": {
|
||||
"SQLitePCLRaw.core": "2.1.4"
|
||||
}
|
||||
},
|
||||
"System.Buffers": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.4.0",
|
||||
"contentHash": "AwarXzzoDwX6BgrhjoJsk6tUezZEozOT5Y9QKF94Gl4JK91I4PIIBkBco9068Y9/Dra8Dkbie99kXB8+1BaYKw=="
|
||||
},
|
||||
"System.ComponentModel.Annotations": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.5.0",
|
||||
"contentHash": "UxYQ3FGUOtzJ7LfSdnYSFd7+oEv6M8NgUatatIN2HxNtDdlcvFAf+VIq4Of9cDMJEJC0aSRv/x898RYhB4Yppg=="
|
||||
},
|
||||
"System.Memory": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.5.3",
|
||||
"contentHash": "3oDzvc/zzetpTKWMShs1AADwZjQ/36HnsufHRPcOjyRAAMLDlu2iD33MBI2opxnezcVUtXyqDXXjoFMOU9c7SA==",
|
||||
"dependencies": {
|
||||
"System.Buffers": "4.4.0",
|
||||
"System.Numerics.Vectors": "4.4.0",
|
||||
"System.Runtime.CompilerServices.Unsafe": "4.5.2"
|
||||
}
|
||||
},
|
||||
"System.Numerics.Vectors": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.4.0",
|
||||
"contentHash": "UiLzLW+Lw6HLed1Hcg+8jSRttrbuXv7DANVj0DkL9g6EnnzbL75EB7EWsw5uRbhxd/4YdG8li5XizGWepmG3PQ=="
|
||||
},
|
||||
"System.Reactive": {
|
||||
"type": "Transitive",
|
||||
"resolved": "5.0.0",
|
||||
"contentHash": "erBZjkQHWL9jpasCE/0qKAryzVBJFxGHVBAvgRN1bzM0q2s1S4oYREEEL0Vb+1kA/6BKb5FjUZMp5VXmy+gzkQ==",
|
||||
"dependencies": {
|
||||
"System.Runtime.InteropServices.WindowsRuntime": "4.3.0",
|
||||
"System.Threading.Tasks.Extensions": "4.5.4"
|
||||
}
|
||||
},
|
||||
"System.Runtime": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.3.0",
|
||||
"contentHash": "JufQi0vPQ0xGnAczR13AUFglDyVYt4Kqnz1AZaiKZ5+GICq0/1MH/mO/eAJHt/mHW1zjKBJd7kV26SrxddAhiw==",
|
||||
"dependencies": {
|
||||
"Microsoft.NETCore.Platforms": "1.1.0",
|
||||
"Microsoft.NETCore.Targets": "1.1.0"
|
||||
}
|
||||
},
|
||||
"System.Runtime.CompilerServices.Unsafe": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.5.3",
|
||||
"contentHash": "3TIsJhD1EiiT0w2CcDMN/iSSwnNnsrnbzeVHSKkaEgV85txMprmuO+Yq2AdSbeVGcg28pdNDTPK87tJhX7VFHw=="
|
||||
},
|
||||
"System.Runtime.InteropServices.WindowsRuntime": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.3.0",
|
||||
"contentHash": "J4GUi3xZQLUBasNwZnjrffN8i5wpHrBtZoLG+OhRyGo/+YunMRWWtwoMDlUAIdmX0uRfpHIBDSV6zyr3yf00TA==",
|
||||
"dependencies": {
|
||||
"System.Runtime": "4.3.0"
|
||||
}
|
||||
},
|
||||
"System.Threading.Tasks.Extensions": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.5.4",
|
||||
"contentHash": "zteT+G8xuGu6mS+mzDzYXbzS7rd3K6Fjb9RiZlYlJPam2/hU7JCBZBVEcywNuR+oZ1ncTvc/cq0faRr3P01OVg==",
|
||||
"dependencies": {
|
||||
"System.Runtime.CompilerServices.Unsafe": "4.5.3"
|
||||
}
|
||||
},
|
||||
"speckle.sdk": {
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "[6.0.0, )",
|
||||
"Microsoft.CSharp": "[4.7.0, )",
|
||||
"Microsoft.Data.Sqlite": "[7.0.5, )",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0, )",
|
||||
"Microsoft.Extensions.Logging": "[2.2.0, )",
|
||||
"Speckle.DoubleNumerics": "[4.1.0, )",
|
||||
"Speckle.Newtonsoft.Json": "[13.0.2, )",
|
||||
"Speckle.Sdk.Dependencies": "[1.0.0, )"
|
||||
}
|
||||
},
|
||||
"speckle.sdk.dependencies": {
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Bcl.AsyncInterfaces": "[9.0.4, )"
|
||||
}
|
||||
},
|
||||
"GraphQL.Client": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[6.0.0, )",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "8yPNBbuVBpTptivyAlak4GZvbwbUcjeQTL4vN1HKHRuOykZ4r7l5fcLS6vpyPyLn0x8FsL31xbOIKyxbmR9rbA==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client.Abstractions": "6.0.0",
|
||||
"GraphQL.Client.Abstractions.Websocket": "6.0.0",
|
||||
"System.Reactive": "5.0.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Bcl.AsyncInterfaces": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[9.0.4, )",
|
||||
"resolved": "9.0.4",
|
||||
"contentHash": "9VGI5kxIvrNG2mqLQZnUR6y/3fcnygD8eNpHR+CqfbnIXvea6nehnYknDKQTxZVPMpzpNca+7DxLBmpdB3q0Bw==",
|
||||
"dependencies": {
|
||||
"System.Threading.Tasks.Extensions": "4.5.4"
|
||||
}
|
||||
},
|
||||
"Microsoft.CSharp": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[4.7.0, )",
|
||||
"resolved": "4.7.0",
|
||||
"contentHash": "pTj+D3uJWyN3My70i2Hqo+OXixq3Os2D1nJ2x92FFo6sk8fYS1m1WLNTs0Dc1uPaViH0YvEEwvzddQ7y4rhXmA=="
|
||||
},
|
||||
"Microsoft.Data.Sqlite": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[7.0.5, )",
|
||||
"resolved": "7.0.5",
|
||||
"contentHash": "KGxbPeWsQMnmQy43DSBxAFtHz3l2JX8EWBSGUCvT3CuZ8KsuzbkqMIJMDOxWtG8eZSoCDI04aiVQjWuuV8HmSw==",
|
||||
"dependencies": {
|
||||
"Microsoft.Data.Sqlite.Core": "7.0.5",
|
||||
"SQLitePCLRaw.bundle_e_sqlite3": "2.1.4"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[2.2.0, )",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
|
||||
},
|
||||
"Microsoft.Extensions.Logging": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[2.2.0, )",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "Nxqhadc9FCmFHzU+fz3oc8sFlE6IadViYg8dfUdGzJZ2JUxnCsRghBhhOWdM4B2zSZqEc+0BjliBh/oNdRZuig==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Configuration.Binder": "2.2.0",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Options": "2.2.0"
|
||||
}
|
||||
},
|
||||
"Speckle.DoubleNumerics": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[4.1.0, )",
|
||||
"resolved": "4.1.0",
|
||||
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
|
||||
},
|
||||
"Speckle.Newtonsoft.Json": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[13.0.2, )",
|
||||
"resolved": "13.0.2",
|
||||
"contentHash": "g1BejUZwax5PRfL6xHgLEK23sqHWOgOj9hE7RvfRRlN00AGt8GnPYt8HedSK7UB3HiRW8zCA9Pn0iiYxCK24BA=="
|
||||
}
|
||||
},
|
||||
"net8.0": {
|
||||
"Microsoft.SourceLink.GitHub": {
|
||||
"type": "Direct",
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
using System.Buffers;
|
||||
using System.Text;
|
||||
using Microsoft.Extensions.ObjectPool;
|
||||
|
||||
namespace Speckle.Sdk.Dependencies;
|
||||
|
||||
public sealed class ArrayBufferWriterPooledObjectPolicy<T> : PooledObjectPolicy<ArrayBufferWriter<T>>
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the initial capacity of pooled <see cref="ArrayBufferWriter{T}"/> instances.
|
||||
/// </summary>
|
||||
/// <value>Defaults to <c>100</c>.</value>
|
||||
public int InitialCapacity { get; set; } = 100;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the maximum value for <see cref="StringBuilder.Capacity"/> that is allowed to be
|
||||
/// retained, when <see cref="Return(ArrayBufferWriter{T})"/> is invoked.
|
||||
/// </summary>
|
||||
/// <value>Defaults to <c>4096</c>.</value>
|
||||
public int MaximumRetainedCapacity { get; set; } = 4 * 1024;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override ArrayBufferWriter<T> Create()
|
||||
{
|
||||
return new ArrayBufferWriter<T>(InitialCapacity);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool Return(ArrayBufferWriter<T> obj)
|
||||
{
|
||||
if (obj.Capacity > MaximumRetainedCapacity)
|
||||
{
|
||||
// Too big. Discard this one.
|
||||
return false;
|
||||
}
|
||||
|
||||
obj.Clear();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
using System.Buffers;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Text;
|
||||
using Microsoft.Extensions.ObjectPool;
|
||||
@@ -24,6 +25,9 @@ public static class Pools
|
||||
public static Pool<StringBuilder> StringBuilders { get; } =
|
||||
new(new StringBuilderPooledObjectPolicy() { MaximumRetainedCapacity = 100 * 1024 * 1024 });
|
||||
|
||||
public static Pool<ArrayBufferWriter<byte>> ArrayBufferWriter { get; } =
|
||||
new(new ArrayBufferWriterPooledObjectPolicy<byte>() { MaximumRetainedCapacity = 100 * 1024 * 1024 });
|
||||
|
||||
private sealed class ObjectDictionaryPolicy<TKey, TValue> : IPooledObjectPolicy<Dictionary<TKey, TValue>>
|
||||
where TKey : notnull
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup Label="Compiler Properties">
|
||||
<TargetFrameworks>netstandard2.0;net8.0</TargetFrameworks>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<Configurations>Debug;Release;Local</Configurations>
|
||||
<ILRepackTargetConfigurations>Debug;Release;Local</ILRepackTargetConfigurations>
|
||||
<ILRepackRenameInternalized>true</ILRepackRenameInternalized>
|
||||
@@ -30,6 +30,7 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard2.0'">
|
||||
<PackageReference Include="Microsoft.Bcl.AsyncInterfaces" />
|
||||
<PackageReference Include="System.Text.Json" />
|
||||
</ItemGroup>
|
||||
<Target Name="BeforeILRepackPrepareBuild" BeforeTargets="ILRepackPrepareBuild">
|
||||
<ItemGroup>
|
||||
|
||||
@@ -1,167 +1,6 @@
|
||||
{
|
||||
"version": 2,
|
||||
"dependencies": {
|
||||
".NETStandard,Version=v2.0": {
|
||||
"ILRepack.FullAuto": {
|
||||
"type": "Direct",
|
||||
"requested": "[1.6.0, )",
|
||||
"resolved": "1.6.0",
|
||||
"contentHash": "34qp/HQ0XRIWCjtNGUOslJ6p9eNWqHXZQ+xx1iBCvXy3mj8tEiqIwRG+LubFyKCJITqMh5cpFvFl20/6+Dmy+g==",
|
||||
"dependencies": {
|
||||
"ILRepack": "2.0.33"
|
||||
}
|
||||
},
|
||||
"Microsoft.Bcl.AsyncInterfaces": {
|
||||
"type": "Direct",
|
||||
"requested": "[9.0.4, )",
|
||||
"resolved": "9.0.4",
|
||||
"contentHash": "9VGI5kxIvrNG2mqLQZnUR6y/3fcnygD8eNpHR+CqfbnIXvea6nehnYknDKQTxZVPMpzpNca+7DxLBmpdB3q0Bw==",
|
||||
"dependencies": {
|
||||
"System.Threading.Tasks.Extensions": "4.5.4"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.ObjectPool": {
|
||||
"type": "Direct",
|
||||
"requested": "[9.0.4, )",
|
||||
"resolved": "9.0.4",
|
||||
"contentHash": "G7p1k2xVZ+2aVANz0JdSiafr+AHDHeS1kF8+Y0ABbIsByd0erOL59IDXBs9vcdJf3pPV/murO0mbtr4k40QxWw=="
|
||||
},
|
||||
"Microsoft.SourceLink.GitHub": {
|
||||
"type": "Direct",
|
||||
"requested": "[8.0.0, )",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "G5q7OqtwIyGTkeIOAc3u2ZuV/kicQaec5EaRnc0pIeSnh9LUjj+PYQrJYBURvDt7twGl2PKA7nSN0kz1Zw5bnQ==",
|
||||
"dependencies": {
|
||||
"Microsoft.Build.Tasks.Git": "8.0.0",
|
||||
"Microsoft.SourceLink.Common": "8.0.0"
|
||||
}
|
||||
},
|
||||
"NETStandard.Library": {
|
||||
"type": "Direct",
|
||||
"requested": "[2.0.3, )",
|
||||
"resolved": "2.0.3",
|
||||
"contentHash": "st47PosZSHrjECdjeIzZQbzivYBJFv6P2nv4cj2ypdI204DO+vZ7l5raGMiX4eXMJ53RfOIg+/s4DHVZ54Nu2A==",
|
||||
"dependencies": {
|
||||
"Microsoft.NETCore.Platforms": "1.1.0"
|
||||
}
|
||||
},
|
||||
"Open.ChannelExtensions": {
|
||||
"type": "Direct",
|
||||
"requested": "[9.1.0, )",
|
||||
"resolved": "9.1.0",
|
||||
"contentHash": "D6c24vMGy1oZ06vmkD2/FNzWHK7ZIihuv2spDgYEeaUp+eobrILQnrNQKRoASFXD4JGfZ7nfvTM0e+AX79dt8Q==",
|
||||
"dependencies": {
|
||||
"Microsoft.Bcl.AsyncInterfaces": "9.0.4",
|
||||
"System.Collections.Immutable": "9.0.4",
|
||||
"System.Threading.Channels": "9.0.4"
|
||||
}
|
||||
},
|
||||
"Polly": {
|
||||
"type": "Direct",
|
||||
"requested": "[7.2.3, )",
|
||||
"resolved": "7.2.3",
|
||||
"contentHash": "DeCY0OFbNdNxsjntr1gTXHJ5pKUwYzp04Er2LLeN3g6pWhffsGuKVfMBLe1lw7x76HrPkLxKEFxBlpRxS2nDEQ=="
|
||||
},
|
||||
"Polly.Contrib.WaitAndRetry": {
|
||||
"type": "Direct",
|
||||
"requested": "[1.1.1, )",
|
||||
"resolved": "1.1.1",
|
||||
"contentHash": "1MUQLiSo4KDkQe6nzQRhIU05lm9jlexX5BVsbuw0SL82ynZ+GzAHQxJVDPVBboxV37Po3SG077aX8DuSy8TkaA=="
|
||||
},
|
||||
"Polly.Extensions.Http": {
|
||||
"type": "Direct",
|
||||
"requested": "[3.0.0, )",
|
||||
"resolved": "3.0.0",
|
||||
"contentHash": "drrG+hB3pYFY7w1c3BD+lSGYvH2oIclH8GRSehgfyP5kjnFnHKQuuBhuHLv+PWyFuaTDyk/vfRpnxOzd11+J8g==",
|
||||
"dependencies": {
|
||||
"Polly": "7.1.0"
|
||||
}
|
||||
},
|
||||
"PolySharp": {
|
||||
"type": "Direct",
|
||||
"requested": "[1.15.0, )",
|
||||
"resolved": "1.15.0",
|
||||
"contentHash": "FbU0El+EEjdpuIX4iDbeS7ki1uzpJPx8vbqOzEtqnl1GZeAGJfq+jCbxeJL2y0EPnUNk8dRnnqR2xnYXg9Tf+g=="
|
||||
},
|
||||
"Speckle.InterfaceGenerator": {
|
||||
"type": "Direct",
|
||||
"requested": "[0.9.6, )",
|
||||
"resolved": "0.9.6",
|
||||
"contentHash": "HKH7tYrYYlCK1ct483hgxERAdVdMtl7gUKW9ijWXxA1UsYR4Z+TrRHYmzZ9qmpu1NnTycSrp005NYM78GDKV1w=="
|
||||
},
|
||||
"System.Threading.Channels": {
|
||||
"type": "Direct",
|
||||
"requested": "[9.0.4, )",
|
||||
"resolved": "9.0.4",
|
||||
"contentHash": "4qBn2H6/aXBpE/Pm3wY5yusY/pEvQz99NlWHrTUji0qCmOdbhhjaALcpmbfW2ksxlPM6i6S+QFLkpOQdyfeKYQ==",
|
||||
"dependencies": {
|
||||
"Microsoft.Bcl.AsyncInterfaces": "9.0.4",
|
||||
"System.Threading.Tasks.Extensions": "4.5.4"
|
||||
}
|
||||
},
|
||||
"ILRepack": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.0.33",
|
||||
"contentHash": "xb2h1CsOepoYwdXEPui9VcQglwABQwNf9cccZbf+acarEzF5PUp8Xx71nFXIhOgEdm6wrxAoF6xAxK4m/XFRUQ=="
|
||||
},
|
||||
"Microsoft.Build.Tasks.Git": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "bZKfSIKJRXLTuSzLudMFte/8CempWjVamNUR5eHJizsy+iuOuO/k2gnh7W0dHJmYY0tBf+gUErfluCv5mySAOQ=="
|
||||
},
|
||||
"Microsoft.NETCore.Platforms": {
|
||||
"type": "Transitive",
|
||||
"resolved": "1.1.0",
|
||||
"contentHash": "kz0PEW2lhqygehI/d6XsPCQzD7ff7gUJaVGPVETX611eadGsA3A877GdSlU0LRVMCTH/+P3o2iDTak+S08V2+A=="
|
||||
},
|
||||
"Microsoft.SourceLink.Common": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw=="
|
||||
},
|
||||
"System.Buffers": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.5.1",
|
||||
"contentHash": "Rw7ijyl1qqRS0YQD/WycNst8hUUMgrMH4FCn1nNm27M4VxchZ1js3fVjQaANHO5f3sN4isvP4a+Met9Y4YomAg=="
|
||||
},
|
||||
"System.Collections.Immutable": {
|
||||
"type": "Transitive",
|
||||
"resolved": "9.0.4",
|
||||
"contentHash": "wfm2NgK22MmBe5qJjp52qzpkeDZKb4l9LbdubhZSehY1z4LS+lld6R+B+UQNb2AZRHu/QJlHxEUcRst5hIEejg==",
|
||||
"dependencies": {
|
||||
"System.Memory": "4.5.5",
|
||||
"System.Runtime.CompilerServices.Unsafe": "6.0.0"
|
||||
}
|
||||
},
|
||||
"System.Memory": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.5.5",
|
||||
"contentHash": "XIWiDvKPXaTveaB7HVganDlOCRoj03l+jrwNvcge/t8vhGYKvqV+dMv6G4SAX2NoNmN0wZfVPTAlFwZcZvVOUw==",
|
||||
"dependencies": {
|
||||
"System.Buffers": "4.5.1",
|
||||
"System.Numerics.Vectors": "4.4.0",
|
||||
"System.Runtime.CompilerServices.Unsafe": "4.5.3"
|
||||
}
|
||||
},
|
||||
"System.Numerics.Vectors": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.4.0",
|
||||
"contentHash": "UiLzLW+Lw6HLed1Hcg+8jSRttrbuXv7DANVj0DkL9g6EnnzbL75EB7EWsw5uRbhxd/4YdG8li5XizGWepmG3PQ=="
|
||||
},
|
||||
"System.Runtime.CompilerServices.Unsafe": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "/iUeP3tq1S0XdNNoMz5C9twLSrM/TH+qElHkXWaPvuNOt+99G75NrV0OS2EqHx5wMN7popYjpc8oTjC1y16DLg=="
|
||||
},
|
||||
"System.Threading.Tasks.Extensions": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.5.4",
|
||||
"contentHash": "zteT+G8xuGu6mS+mzDzYXbzS7rd3K6Fjb9RiZlYlJPam2/hU7JCBZBVEcywNuR+oZ1ncTvc/cq0faRr3P01OVg==",
|
||||
"dependencies": {
|
||||
"System.Runtime.CompilerServices.Unsafe": "4.5.3"
|
||||
}
|
||||
}
|
||||
},
|
||||
"net8.0": {
|
||||
"ILRepack.FullAuto": {
|
||||
"type": "Direct",
|
||||
|
||||
@@ -154,10 +154,10 @@ public sealed class Client : ISpeckleGraphQLClient, IClient
|
||||
activity?.SetStatus(SdkActivityStatusCode.Ok);
|
||||
return ret;
|
||||
}
|
||||
catch (Exception)
|
||||
catch (Exception ex)
|
||||
{
|
||||
activity?.SetStatus(SdkActivityStatusCode.Error);
|
||||
// Don't record exception as it's rethrown.
|
||||
activity?.RecordException(ex);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -142,59 +142,26 @@ public sealed class AccountManager(
|
||||
|
||||
/// <summary>
|
||||
/// Refetches the <paramref name="account"/> information, including <see cref="ServerInfo"/> and <see cref="UserInfo"/>
|
||||
/// If the <see cref="Account.token"/> looks to be expired, this function will also attempt to use the <see cref="Account.refreshToken"/> to refresh it.
|
||||
///
|
||||
/// Will only mutate <paramref name="account"/> in memory only, and only if successful.
|
||||
/// </summary>
|
||||
/// <seealso cref="UpdateAccount"/>
|
||||
/// <param name="account"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <exception cref="AggregateException">Thrown if</exception>
|
||||
/// <exception cref="GraphQLHttpRequestException"></exception>
|
||||
public async Task UpdateAccountInMemory(Account account, CancellationToken cancellationToken = default)
|
||||
{
|
||||
Uri url = account.serverInfo.migration?.movedTo ?? new(account.serverInfo.url);
|
||||
ActiveUserServerInfoResponse userServerInfo;
|
||||
|
||||
try
|
||||
ActiveUserServerInfoResponse userServerInfo = await accountFactory
|
||||
.GetUserServerInfo(url, account.token, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
if (userServerInfo.activeUser == null)
|
||||
{
|
||||
userServerInfo = await accountFactory
|
||||
.GetUserServerInfo(url, account.token, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
throw new SpeckleException("GraphQL response indicated that the ActiveUser could not be found");
|
||||
}
|
||||
catch (GraphQLHttpRequestException ex)
|
||||
{
|
||||
// Failed to fetch info, perhaps the token is expired?
|
||||
// Attempt to refresh it
|
||||
TokenExchangeResponse refreshTokenResponse;
|
||||
try
|
||||
{
|
||||
refreshTokenResponse = await authFlow
|
||||
.GetRefreshedToken(
|
||||
account.refreshToken.NotNull("No refresh token provided"),
|
||||
url,
|
||||
AuthApp.ConnectorsV3,
|
||||
cancellationToken
|
||||
)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
userServerInfo = await accountFactory
|
||||
.GetUserServerInfo(url, refreshTokenResponse.token, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
catch (OperationCanceledException) when (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
catch (Exception ex2)
|
||||
{
|
||||
throw new AggregateException("Failed to update account information", ex, ex2);
|
||||
}
|
||||
|
||||
account.token = refreshTokenResponse.token;
|
||||
account.refreshToken = refreshTokenResponse.refreshToken;
|
||||
logger.LogInformation(ex, "Account token has been refreshed");
|
||||
}
|
||||
account.userInfo = userServerInfo.activeUser.NotNull();
|
||||
account.userInfo = userServerInfo.activeUser;
|
||||
account.serverInfo = userServerInfo.serverInfo;
|
||||
//This is a bit gross, since id is not marked nullable
|
||||
//but this will force re-generate the id (e.g. if the user's email, or servers url has changed)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Diagnostics;
|
||||
using System.Diagnostics.Contracts;
|
||||
using System.Net;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Security.Cryptography;
|
||||
@@ -42,34 +43,45 @@ public sealed class AuthFlow(ISdkActivityFactory activityFactory, ISpeckleHttp s
|
||||
|
||||
Uri tokenEndpoint = new(serverUrl, "/oauth/token");
|
||||
string codeVerifier = GenerateCodeVerifier();
|
||||
string challenge;
|
||||
string codeChallengeMethod;
|
||||
var req = await client.GetAsync(tokenEndpoint, cancellationToken).ConfigureAwait(false);
|
||||
Uri authnVerify;
|
||||
using var req = await client.GetAsync(tokenEndpoint, cancellationToken).ConfigureAwait(false);
|
||||
bool useLegacyEndpoint = req.StatusCode != HttpStatusCode.OK;
|
||||
|
||||
if (useLegacyEndpoint)
|
||||
{
|
||||
challenge = codeVerifier;
|
||||
string challenge = codeVerifier; // Old endpoint only supports PKCE "plain" method
|
||||
authnVerify = new($"/authn/verify/{authApp.AppId}/{challenge}", UriKind.Relative);
|
||||
tokenEndpoint = new(serverUrl, "/auth/token");
|
||||
codeChallengeMethod = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
challenge = GenerateCodeChallenge(codeVerifier);
|
||||
codeChallengeMethod = "?code_challenge_method=S256";
|
||||
string challenge = GenerateCodeChallenge(codeVerifier);
|
||||
authnVerify = new($"/authn/verify/{authApp.AppId}/{challenge}?code_challenge_method=S256", UriKind.Relative);
|
||||
}
|
||||
|
||||
Uri endpoint = new(serverUrl, $"/authn/verify/{authApp.AppId}/{challenge}{codeChallengeMethod}");
|
||||
Uri endpoint = new(serverUrl, authnVerify);
|
||||
_ = Process.Start(new ProcessStartInfo(endpoint.ToString()) { UseShellExecute = true });
|
||||
string accessCode = await RunListenerWithTimeout(authApp.CallbackUrl, timeout, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
object body = useLegacyEndpoint
|
||||
? new
|
||||
{
|
||||
appId = authApp.AppId,
|
||||
appSecret = authApp.AppSecret,
|
||||
accessCode = accessCode,
|
||||
challenge = codeVerifier,
|
||||
}
|
||||
: new
|
||||
{
|
||||
appId = authApp.AppId,
|
||||
accessCode = accessCode,
|
||||
codeVerifier = codeVerifier,
|
||||
};
|
||||
|
||||
return await ExchangeAccessCodeForToken(
|
||||
client,
|
||||
accessCode,
|
||||
authApp,
|
||||
useLegacyEndpoint ? challenge : null,
|
||||
!useLegacyEndpoint ? codeVerifier : null,
|
||||
JsonConvert.SerializeObject(body, _serializerSettings),
|
||||
tokenEndpoint,
|
||||
cancellationToken
|
||||
)
|
||||
@@ -141,7 +153,7 @@ public sealed class AuthFlow(ISdkActivityFactory activityFactory, ISpeckleHttp s
|
||||
refreshToken = refreshToken,
|
||||
};
|
||||
|
||||
using var content = new StringContent(JsonConvert.SerializeObject(body));
|
||||
using var content = new StringContent(JsonConvert.SerializeObject(body, _serializerSettings));
|
||||
content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
|
||||
var response = await client
|
||||
.PostAsync(new Uri(serverUrl, "/auth/token"), content, cancellationToken)
|
||||
@@ -248,24 +260,12 @@ public sealed class AuthFlow(ISdkActivityFactory activityFactory, ISpeckleHttp s
|
||||
|
||||
private async Task<TokenExchangeResponse> ExchangeAccessCodeForToken(
|
||||
HttpClient client,
|
||||
string accessCode,
|
||||
AuthApp authApp,
|
||||
string? challenge,
|
||||
string? codeVerifier,
|
||||
string jsonContent,
|
||||
Uri tokenEndpoint,
|
||||
CancellationToken cancellationToken
|
||||
)
|
||||
{
|
||||
var body = new
|
||||
{
|
||||
appId = authApp.AppId,
|
||||
appSecret = authApp.AppSecret,
|
||||
accessCode = accessCode,
|
||||
challenge = challenge,
|
||||
codeVerifier = codeVerifier,
|
||||
};
|
||||
|
||||
using StringContent content = new(JsonConvert.SerializeObject(body, _serializerSettings));
|
||||
using StringContent content = new(jsonContent);
|
||||
content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
|
||||
|
||||
using HttpResponseMessage response = await client
|
||||
@@ -282,6 +282,7 @@ public sealed class AuthFlow(ISdkActivityFactory activityFactory, ISpeckleHttp s
|
||||
return JsonConvert.DeserializeObject<TokenExchangeResponse>(read, _serializerSettings).NotNull();
|
||||
}
|
||||
|
||||
[Pure]
|
||||
public static string GenerateCodeVerifier()
|
||||
{
|
||||
#if NET8_0_OR_GREATER
|
||||
@@ -296,6 +297,7 @@ public sealed class AuthFlow(ISdkActivityFactory activityFactory, ISpeckleHttp s
|
||||
return Base64UrlEncode(codeVerifierData);
|
||||
}
|
||||
|
||||
[Pure]
|
||||
public static string GenerateCodeChallenge(string codeVerifier)
|
||||
{
|
||||
#if NET8_0_OR_GREATER
|
||||
@@ -312,6 +314,7 @@ public sealed class AuthFlow(ISdkActivityFactory activityFactory, ISpeckleHttp s
|
||||
return Base64UrlEncode(challengeData);
|
||||
}
|
||||
|
||||
[Pure]
|
||||
private static string Base64UrlEncode(
|
||||
#if NET8_0_OR_GREATER
|
||||
ReadOnlySpan<byte> bytes
|
||||
|
||||
@@ -13,7 +13,9 @@ public sealed class DetachPropertyAttribute : Attribute
|
||||
/// <para>If set to true the default serialiser will persist it separately, and add a reference to the property's value in the original object.</para>
|
||||
/// <para>Only applies to properties of types derived from the Base class.</para>
|
||||
/// </summary>
|
||||
/// <param name="detachable">Whether to detach the property or not.</param>
|
||||
public DetachPropertyAttribute() { }
|
||||
|
||||
[Obsolete("detachable = false is no longer supported")]
|
||||
public DetachPropertyAttribute(bool detachable = true)
|
||||
{
|
||||
Detachable = detachable;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.IO.Compression;
|
||||
using System.Text;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Speckle.InterfaceGenerator;
|
||||
using Speckle.Sdk.Dependencies;
|
||||
@@ -46,6 +47,9 @@ public sealed class DiskStore
|
||||
return await _writeToDiskTask.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private readonly byte[] _newLineChar = [(byte)'\n'];
|
||||
private readonly byte[] _tabLineChar = [(byte)'\t'];
|
||||
|
||||
/// <summary>
|
||||
/// Reads from the Channel and streams the <see cref="UploadItem"/>s to a temporary file on disk.
|
||||
/// Will keep reading until <see cref="CompleteAsync"/> is called.
|
||||
@@ -61,16 +65,23 @@ public sealed class DiskStore
|
||||
{
|
||||
using var fileStream = new FileStream(tempFilePath, FileMode.Create, FileAccess.Write, FileShare.None);
|
||||
using var gzip = new GZipStream(fileStream, CompressionLevel.Optimal);
|
||||
using var writer = new StreamWriter(gzip);
|
||||
|
||||
await foreach (var item in _channel.ReadAllAsync(_cancellationToken).ConfigureAwait(false))
|
||||
{
|
||||
await writer.WriteLineAsync($"{item.Id}\t{item.SpeckleType}\t{item.Json}").ConfigureAwait(false);
|
||||
await gzip.WriteAsync(Encoding.UTF8.GetBytes(item.Id), _cancellationToken).ConfigureAwait(false);
|
||||
await gzip.WriteAsync(_tabLineChar, _cancellationToken).ConfigureAwait(false);
|
||||
await gzip.WriteAsync(Encoding.UTF8.GetBytes(item.SpeckleType), _cancellationToken).ConfigureAwait(false);
|
||||
await gzip.WriteAsync(_tabLineChar, _cancellationToken).ConfigureAwait(false);
|
||||
await gzip.WriteAsync(item.Json.WrittenMemory, _cancellationToken).ConfigureAwait(false);
|
||||
await gzip.WriteAsync(_newLineChar, _cancellationToken).ConfigureAwait(false);
|
||||
|
||||
item.Dispose();
|
||||
}
|
||||
|
||||
#if NET8_0_OR_GREATER
|
||||
await writer.FlushAsync(_cancellationToken).ConfigureAwait(false);
|
||||
await gzip.FlushAsync(_cancellationToken).ConfigureAwait(false);
|
||||
#else
|
||||
await writer.FlushAsync().ConfigureAwait(false);
|
||||
await gzip.FlushAsync().ConfigureAwait(false);
|
||||
#endif
|
||||
tempFile.FileInfo.Refresh();
|
||||
|
||||
|
||||
@@ -36,28 +36,21 @@ public sealed class SendPipeline : IDisposable
|
||||
_diskStore = diskStore;
|
||||
}
|
||||
|
||||
private UploadItem _lastItem;
|
||||
|
||||
public async Task<ObjectReference> Process(Base @base)
|
||||
{
|
||||
var results = _serializer.Serialize(@base).ToArray();
|
||||
var first = results.First();
|
||||
foreach (var item in results)
|
||||
foreach (var item in results.Reverse())
|
||||
{
|
||||
// we're not doing fire and forget here so that we get the backpressure from the uploader
|
||||
await _diskStore.PushAsync(item).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
// NOTE: this is important to keep track of. When we serialze an object, we get back a list of objects, with the first one being the original root.
|
||||
// In the case of the commit root object, this means the last object is not necessarily the root; we therefore need to manually track its existance here
|
||||
// and ensure it's the last one through in the uploader's stream. See WaitForUpload down below.
|
||||
_lastItem = first;
|
||||
return first.Reference;
|
||||
return results.First().Reference;
|
||||
}
|
||||
|
||||
public async Task WaitForUpload()
|
||||
{
|
||||
await _diskStore.PushAsync(_lastItem).ConfigureAwait(false);
|
||||
//await _diskStore.PushAsync(_lastItem).ConfigureAwait(false);
|
||||
using DisposableFile tempFile = await _diskStore.CompleteAsync().ConfigureAwait(false);
|
||||
|
||||
using Stream fileStreamUpload = new FileStream(
|
||||
|
||||
@@ -1,13 +1,10 @@
|
||||
using System.Collections;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Drawing;
|
||||
using System.Globalization;
|
||||
using System.Reflection;
|
||||
using Speckle.DoubleNumerics;
|
||||
using Speckle.Newtonsoft.Json;
|
||||
using Speckle.Sdk.Dependencies;
|
||||
using Speckle.Sdk.Helpers;
|
||||
using System.Text.Json;
|
||||
using Speckle.Sdk.Models;
|
||||
using Speckle.Sdk.Serialisation;
|
||||
using Matrix4x4 = Speckle.DoubleNumerics.Matrix4x4;
|
||||
|
||||
namespace Speckle.Sdk.Pipelines.Send;
|
||||
|
||||
@@ -31,7 +28,7 @@ internal sealed class Serializer
|
||||
yield break;
|
||||
}
|
||||
|
||||
var detachedObjects = new List<(Id, Json, Dictionary<string, int>, Base, string)>();
|
||||
var detachedObjects = new List<(Id, EfficientJson, Dictionary<string, int>, Base, string)>();
|
||||
var rootClosures = new Dictionary<string, int>();
|
||||
|
||||
var (rootId, rootJson) = SerializeBase(root, false, rootClosures, detachedObjects);
|
||||
@@ -68,13 +65,13 @@ internal sealed class Serializer
|
||||
continue;
|
||||
}
|
||||
|
||||
if (prop.IsDefined(typeof(JsonIgnoreAttribute), false))
|
||||
if (prop.IsDefined(typeof(Speckle.Newtonsoft.Json.JsonIgnoreAttribute), false))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var value = prop.GetValue(baseObj);
|
||||
var isDetachable = prop.GetCustomAttribute<DetachPropertyAttribute>(true)?.Detachable ?? false;
|
||||
var isDetachable = prop.IsDefined(typeof(DetachPropertyAttribute), true);
|
||||
|
||||
yield return new PropertyInfo(prop.Name, value, isDetachable);
|
||||
}
|
||||
@@ -96,107 +93,125 @@ internal sealed class Serializer
|
||||
}
|
||||
}
|
||||
|
||||
private (Id, Json) SerializeBase(
|
||||
private (Id, EfficientJson) SerializeBase(
|
||||
Base baseObj,
|
||||
bool forceDetach,
|
||||
Dictionary<string, int> closures,
|
||||
List<(Id, Json, Dictionary<string, int>, Base, string)> detachedObjects
|
||||
List<(Id, EfficientJson, Dictionary<string, int>, Base, string)> detachedObjects
|
||||
)
|
||||
{
|
||||
var childClosures = new Dictionary<string, int>();
|
||||
|
||||
var sb = Pools.StringBuilders.Get();
|
||||
try
|
||||
var efficientJson = new EfficientJson();
|
||||
using var jsonWriter = new Utf8JsonWriter(efficientJson.Buffer);
|
||||
|
||||
jsonWriter.WriteStartObject();
|
||||
|
||||
foreach (var prop in ExtractProperties(baseObj))
|
||||
{
|
||||
using var stringWriter = new StringWriter(sb);
|
||||
using var jsonWriter = new JsonTextWriter(stringWriter);
|
||||
using var idWriter = new SerializerIdWriter(jsonWriter);
|
||||
|
||||
idWriter.WriteStartObject();
|
||||
|
||||
foreach (var prop in ExtractProperties(baseObj))
|
||||
{
|
||||
idWriter.WritePropertyName(prop.Name);
|
||||
SerializeValue(prop.Value, idWriter, prop.IsDetachable, childClosures, detachedObjects);
|
||||
}
|
||||
|
||||
var (jsonForId, finalWriter) = idWriter.FinishIdWriter();
|
||||
var id = IdGenerator.ComputeId(jsonForId);
|
||||
|
||||
finalWriter.WritePropertyName("id");
|
||||
finalWriter.WriteValue(id.Value);
|
||||
|
||||
baseObj.id = id.Value;
|
||||
|
||||
if ((forceDetach || childClosures.Count > 0) && childClosures.Count > 0)
|
||||
{
|
||||
finalWriter.WritePropertyName("__closure");
|
||||
finalWriter.WriteStartObject();
|
||||
foreach (var kvp in childClosures)
|
||||
{
|
||||
finalWriter.WritePropertyName(kvp.Key);
|
||||
finalWriter.WriteValue(kvp.Value);
|
||||
}
|
||||
finalWriter.WriteEndObject();
|
||||
|
||||
foreach (var kvp in childClosures)
|
||||
{
|
||||
closures[kvp.Key] = closures.TryGetValue(kvp.Key, out var existing) ? existing + kvp.Value : kvp.Value;
|
||||
}
|
||||
}
|
||||
|
||||
finalWriter.WriteEndObject();
|
||||
finalWriter.Flush();
|
||||
|
||||
var json = new Json(stringWriter.ToString());
|
||||
return (id, json);
|
||||
jsonWriter.WritePropertyName(prop.Name);
|
||||
SerializeValue(prop.Value, jsonWriter, prop.IsDetachable, childClosures, detachedObjects);
|
||||
}
|
||||
finally
|
||||
|
||||
jsonWriter.Flush();
|
||||
var span = efficientJson.WrittenSpan;
|
||||
string id = IdGenerator.ComputeId(span);
|
||||
|
||||
jsonWriter.WriteString("id", id);
|
||||
|
||||
baseObj.id = id;
|
||||
|
||||
if ((forceDetach || childClosures.Count > 0) && childClosures.Count > 0)
|
||||
{
|
||||
Pools.StringBuilders.Return(sb);
|
||||
jsonWriter.WritePropertyName("__closure");
|
||||
jsonWriter.WriteStartObject();
|
||||
foreach (var kvp in childClosures)
|
||||
{
|
||||
jsonWriter.WriteNumber(kvp.Key, kvp.Value);
|
||||
}
|
||||
jsonWriter.WriteEndObject();
|
||||
|
||||
foreach (var kvp in childClosures)
|
||||
{
|
||||
closures[kvp.Key] = closures.TryGetValue(kvp.Key, out var existing) ? existing + kvp.Value : kvp.Value;
|
||||
}
|
||||
}
|
||||
|
||||
jsonWriter.WriteEndObject();
|
||||
jsonWriter.Flush();
|
||||
return (new(id), efficientJson);
|
||||
}
|
||||
|
||||
private void SerializeValue(
|
||||
object? value,
|
||||
JsonWriter writer,
|
||||
Utf8JsonWriter writer,
|
||||
bool isDetachable,
|
||||
Dictionary<string, int> closures,
|
||||
List<(Id, Json, Dictionary<string, int>, Base, string)> detachedObjects
|
||||
List<(Id, EfficientJson, Dictionary<string, int>, Base, string)> detachedObjects
|
||||
)
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case Enum:
|
||||
writer.WriteValue((int)value);
|
||||
case null:
|
||||
writer.WriteNullValue();
|
||||
return;
|
||||
case Guid g:
|
||||
writer.WriteValue(g.ToString());
|
||||
case string v:
|
||||
writer.WriteStringValue(v);
|
||||
return;
|
||||
case short i:
|
||||
writer.WriteNumberValue(i);
|
||||
return;
|
||||
case ushort i:
|
||||
writer.WriteNumberValue(i);
|
||||
return;
|
||||
case int i:
|
||||
writer.WriteNumberValue(i);
|
||||
return;
|
||||
case uint i:
|
||||
writer.WriteNumberValue(i);
|
||||
return;
|
||||
case long i:
|
||||
writer.WriteNumberValue(i);
|
||||
return;
|
||||
case ulong i:
|
||||
writer.WriteNumberValue(i);
|
||||
return;
|
||||
case bool b:
|
||||
writer.WriteBooleanValue(b);
|
||||
return;
|
||||
case float f:
|
||||
writer.WriteNumberValue(f);
|
||||
return;
|
||||
case double f:
|
||||
writer.WriteNumberValue(f);
|
||||
return;
|
||||
case decimal d:
|
||||
writer.WriteNumberValue(d);
|
||||
return;
|
||||
case Enum:
|
||||
writer.WriteNumberValue((int)value);
|
||||
return;
|
||||
case Color c:
|
||||
writer.WriteValue(c.ToArgb());
|
||||
return;
|
||||
case DateTime dt:
|
||||
writer.WriteValue(dt.ToString("o", CultureInfo.InvariantCulture));
|
||||
writer.WriteNumberValue(c.ToArgb());
|
||||
return;
|
||||
case Matrix4x4 md:
|
||||
writer.WriteStartArray();
|
||||
writer.WriteValue(md.M11);
|
||||
writer.WriteValue(md.M12);
|
||||
writer.WriteValue(md.M13);
|
||||
writer.WriteValue(md.M14);
|
||||
writer.WriteValue(md.M21);
|
||||
writer.WriteValue(md.M22);
|
||||
writer.WriteValue(md.M23);
|
||||
writer.WriteValue(md.M24);
|
||||
writer.WriteValue(md.M31);
|
||||
writer.WriteValue(md.M32);
|
||||
writer.WriteValue(md.M33);
|
||||
writer.WriteValue(md.M34);
|
||||
writer.WriteValue(md.M41);
|
||||
writer.WriteValue(md.M42);
|
||||
writer.WriteValue(md.M43);
|
||||
writer.WriteValue(md.M44);
|
||||
writer.WriteNumberValue(md.M11);
|
||||
writer.WriteNumberValue(md.M12);
|
||||
writer.WriteNumberValue(md.M13);
|
||||
writer.WriteNumberValue(md.M14);
|
||||
writer.WriteNumberValue(md.M21);
|
||||
writer.WriteNumberValue(md.M22);
|
||||
writer.WriteNumberValue(md.M23);
|
||||
writer.WriteNumberValue(md.M24);
|
||||
writer.WriteNumberValue(md.M31);
|
||||
writer.WriteNumberValue(md.M32);
|
||||
writer.WriteNumberValue(md.M33);
|
||||
writer.WriteNumberValue(md.M34);
|
||||
writer.WriteNumberValue(md.M41);
|
||||
writer.WriteNumberValue(md.M42);
|
||||
writer.WriteNumberValue(md.M43);
|
||||
writer.WriteNumberValue(md.M44);
|
||||
writer.WriteEndArray();
|
||||
return;
|
||||
// Handle ObjectReference before Base (since ObjectReference extends Base)
|
||||
@@ -204,10 +219,8 @@ internal sealed class Serializer
|
||||
case ObjectReference objRef:
|
||||
{
|
||||
writer.WriteStartObject();
|
||||
writer.WritePropertyName("speckle_type");
|
||||
writer.WriteValue("reference");
|
||||
writer.WritePropertyName("referencedId");
|
||||
writer.WriteValue(objRef.referencedId);
|
||||
writer.WriteString("speckle_type", "reference");
|
||||
writer.WriteString("referencedId", objRef.referencedId);
|
||||
writer.WriteEndObject();
|
||||
|
||||
// Propagate closure: add the referenced ID
|
||||
@@ -236,10 +249,8 @@ internal sealed class Serializer
|
||||
detachedObjects.Add((childId, childJson, childClosures, baseObj, baseObj.speckle_type));
|
||||
|
||||
writer.WriteStartObject();
|
||||
writer.WritePropertyName("speckle_type");
|
||||
writer.WriteValue("reference");
|
||||
writer.WritePropertyName("referencedId");
|
||||
writer.WriteValue(childId.Value);
|
||||
writer.WriteString("speckle_type", "reference");
|
||||
writer.WriteString("referencedId", childId.Value);
|
||||
writer.WriteEndObject();
|
||||
|
||||
closures[childId.Value] = closures.TryGetValue(childId.Value, out var existing) ? existing + 1 : 1;
|
||||
@@ -256,7 +267,7 @@ internal sealed class Serializer
|
||||
var inlineClosures = new Dictionary<string, int>();
|
||||
var (_, inlineJson) = SerializeBase(baseObj, false, inlineClosures, detachedObjects);
|
||||
|
||||
writer.WriteRawValue(inlineJson.Value);
|
||||
writer.WriteRawValue(inlineJson.WrittenSpan);
|
||||
|
||||
foreach (var kvp in inlineClosures)
|
||||
{
|
||||
@@ -296,56 +307,48 @@ internal sealed class Serializer
|
||||
default:
|
||||
// This case will handle primitives and `null`
|
||||
// Will throw JsonWriterException if not supported
|
||||
writer.WriteValue(value);
|
||||
return;
|
||||
throw new ArgumentOutOfRangeException(nameof(value), $"Unsupported type {value.GetType()}");
|
||||
}
|
||||
}
|
||||
|
||||
[SuppressMessage(
|
||||
"Reliability",
|
||||
"CA2000:Dispose objects before losing scope",
|
||||
Justification = "EfficientJson IDisposable is returned via UploadItem"
|
||||
)]
|
||||
private UploadItem ReferenceToUploadItem(ObjectReference existingRef)
|
||||
{
|
||||
var sb = Pools.StringBuilders.Get();
|
||||
try
|
||||
{
|
||||
using var stringWriter = new StringWriter(sb);
|
||||
using var jsonWriter = new JsonTextWriter(stringWriter);
|
||||
var refJson = new EfficientJson();
|
||||
using var jsonWriter = new Utf8JsonWriter(refJson.Buffer);
|
||||
|
||||
jsonWriter.WriteStartObject();
|
||||
jsonWriter.WriteString("speckle_type", "reference");
|
||||
jsonWriter.WriteString("referencedId", existingRef.referencedId);
|
||||
jsonWriter.WritePropertyName("__closure");
|
||||
|
||||
if (existingRef.closure != null && existingRef.closure.Count > 0)
|
||||
{
|
||||
jsonWriter.WriteStartObject();
|
||||
jsonWriter.WritePropertyName("speckle_type");
|
||||
jsonWriter.WriteValue("reference");
|
||||
jsonWriter.WritePropertyName("referencedId");
|
||||
jsonWriter.WriteValue(existingRef.referencedId);
|
||||
jsonWriter.WritePropertyName("__closure");
|
||||
|
||||
if (existingRef.closure != null && existingRef.closure.Count > 0)
|
||||
foreach (var kvp in existingRef.closure)
|
||||
{
|
||||
jsonWriter.WriteStartObject();
|
||||
foreach (var kvp in existingRef.closure)
|
||||
{
|
||||
jsonWriter.WritePropertyName(kvp.Key);
|
||||
jsonWriter.WriteValue(kvp.Value);
|
||||
}
|
||||
jsonWriter.WriteEndObject();
|
||||
jsonWriter.WritePropertyName(kvp.Key);
|
||||
jsonWriter.WriteNumberValue(kvp.Value);
|
||||
}
|
||||
else
|
||||
{
|
||||
jsonWriter.WriteNull();
|
||||
}
|
||||
|
||||
jsonWriter.WriteEndObject();
|
||||
jsonWriter.Flush();
|
||||
|
||||
var refJson = new Json(stringWriter.ToString());
|
||||
|
||||
return new UploadItem(
|
||||
existingRef.referencedId,
|
||||
refJson,
|
||||
existingRef.speckle_type,
|
||||
existingRef // Pass through the original ObjectReference
|
||||
);
|
||||
}
|
||||
finally
|
||||
else
|
||||
{
|
||||
Pools.StringBuilders.Return(sb);
|
||||
jsonWriter.WriteNullValue();
|
||||
}
|
||||
|
||||
jsonWriter.WriteEndObject();
|
||||
jsonWriter.Flush();
|
||||
|
||||
return new UploadItem(
|
||||
existingRef.referencedId,
|
||||
refJson,
|
||||
existingRef.speckle_type,
|
||||
existingRef // Pass through the original ObjectReference
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,63 +65,90 @@ public sealed class Uploader : IDisposable
|
||||
{
|
||||
using var a = _activity.Start("Get Presigned Url");
|
||||
|
||||
var signUri = new Uri($"projects/{_projectId}/modelingestion/{_ingestionId}/uploads/sign", UriKind.Relative);
|
||||
try
|
||||
{
|
||||
var signUri = new Uri($"projects/{_projectId}/modelingestion/{_ingestionId}/uploads/sign", UriKind.Relative);
|
||||
|
||||
using var signResponse = await _speckleClient.PostAsync(signUri, null, _cancellationToken).ConfigureAwait(false);
|
||||
signResponse.EnsureSuccessStatusCode();
|
||||
using var signResponse = await _speckleClient.PostAsync(signUri, null, _cancellationToken).ConfigureAwait(false);
|
||||
signResponse.EnsureSuccessStatusCode();
|
||||
|
||||
#if NET5_0_OR_GREATER
|
||||
string signResponseString = await signResponse.Content.ReadAsStringAsync(_cancellationToken).ConfigureAwait(false);
|
||||
string signResponseString = await signResponse
|
||||
.Content.ReadAsStringAsync(_cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
#else
|
||||
string signResponseString = await signResponse.Content.ReadAsStringAsync().ConfigureAwait(false);
|
||||
string signResponseString = await signResponse.Content.ReadAsStringAsync().ConfigureAwait(false);
|
||||
#endif
|
||||
PresignedUploadResponse presignedUpload =
|
||||
JsonConvert.DeserializeObject<PresignedUploadResponse>(signResponseString)
|
||||
?? throw new InvalidOperationException("Failed to get presigned upload URL");
|
||||
return presignedUpload;
|
||||
PresignedUploadResponse presignedUpload =
|
||||
JsonConvert.DeserializeObject<PresignedUploadResponse>(signResponseString)
|
||||
?? throw new InvalidOperationException("Failed to get presigned upload URL");
|
||||
return presignedUpload;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
a?.SetStatus(SdkActivityStatusCode.Error);
|
||||
a?.RecordException(ex);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<string> UploadToS3(Stream fileStream, PresignedUploadResponse presignedUploadResponse)
|
||||
{
|
||||
using var a = _activity.Start("Uploading file to pre-signed url");
|
||||
|
||||
Stream progressStream = new ProgressStream(fileStream, _progress);
|
||||
|
||||
using var streamContent = new StreamContent(progressStream);
|
||||
streamContent.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
|
||||
streamContent.Headers.ContentLength = fileStream.Length;
|
||||
|
||||
using var uploadRequest = new HttpRequestMessage(HttpMethod.Put, presignedUploadResponse.Url);
|
||||
foreach (var kvp in presignedUploadResponse.AdditionalRequestHeaders)
|
||||
try
|
||||
{
|
||||
uploadRequest.Headers.Add(kvp.Key, kvp.Value);
|
||||
Stream progressStream = new ProgressStream(fileStream, _progress);
|
||||
|
||||
using var streamContent = new StreamContent(progressStream);
|
||||
streamContent.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
|
||||
streamContent.Headers.ContentLength = fileStream.Length;
|
||||
|
||||
using var uploadRequest = new HttpRequestMessage(HttpMethod.Put, presignedUploadResponse.Url);
|
||||
foreach (var kvp in presignedUploadResponse.AdditionalRequestHeaders)
|
||||
{
|
||||
uploadRequest.Headers.Add(kvp.Key, kvp.Value);
|
||||
}
|
||||
|
||||
uploadRequest.Content = streamContent;
|
||||
|
||||
using var uploadResponse = await _s3Client
|
||||
.SendAsync(uploadRequest, HttpCompletionOption.ResponseHeadersRead, _cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
uploadResponse.EnsureSuccessStatusCode();
|
||||
|
||||
return BlobApiHelpers.ParseEtagHeader(uploadResponse.Headers);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
a?.SetStatus(SdkActivityStatusCode.Error);
|
||||
a?.RecordException(ex);
|
||||
throw;
|
||||
}
|
||||
|
||||
uploadRequest.Content = streamContent;
|
||||
|
||||
using var uploadResponse = await _s3Client
|
||||
.SendAsync(uploadRequest, HttpCompletionOption.ResponseHeadersRead, _cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
uploadResponse.EnsureSuccessStatusCode();
|
||||
|
||||
return BlobApiHelpers.ParseEtagHeader(uploadResponse.Headers);
|
||||
}
|
||||
|
||||
private async Task TriggerProcessing(TriggerUploadRequest request)
|
||||
{
|
||||
using var a = _activity.Start("Triggering Processing");
|
||||
try
|
||||
{
|
||||
Uri processUri = new($"projects/{_projectId}/modelingestion/{_ingestionId}/uploads/process", UriKind.Relative);
|
||||
string requestBody = JsonConvert.SerializeObject(request);
|
||||
using var content = new StringContent(requestBody, Encoding.UTF8, "application/json");
|
||||
|
||||
Uri processUri = new($"projects/{_projectId}/modelingestion/{_ingestionId}/uploads/process", UriKind.Relative);
|
||||
string requestBody = JsonConvert.SerializeObject(request);
|
||||
using var content = new StringContent(requestBody, Encoding.UTF8, "application/json");
|
||||
using HttpResponseMessage processResponse = await _speckleClient
|
||||
.PostAsync(processUri, content, _cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
using HttpResponseMessage processResponse = await _speckleClient
|
||||
.PostAsync(processUri, content, _cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
string body = await processResponse.Content.ReadAsStringAsync().ConfigureAwait(false);
|
||||
processResponse.EnsureSuccessStatusCode();
|
||||
string body = await processResponse.Content.ReadAsStringAsync().ConfigureAwait(false);
|
||||
processResponse.EnsureSuccessStatusCode();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
a?.SetStatus(SdkActivityStatusCode.Error);
|
||||
a?.RecordException(ex);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
|
||||
@@ -4,7 +4,11 @@ using Speckle.Sdk.Serialisation;
|
||||
|
||||
namespace Speckle.Sdk.Pipelines.Send;
|
||||
|
||||
public record UploadItem(string Id, Json Json, string SpeckleType, ObjectReference Reference);
|
||||
public sealed record UploadItem(string Id, EfficientJson Json, string SpeckleType, ObjectReference Reference)
|
||||
: IDisposable
|
||||
{
|
||||
public void Dispose() => Json.Dispose();
|
||||
}
|
||||
|
||||
internal record PresignedUploadResponse
|
||||
{
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Diagnostics.Contracts;
|
||||
using System.Security.Cryptography;
|
||||
using Speckle.Sdk.Common;
|
||||
using Speckle.Sdk.Models;
|
||||
|
||||
@@ -16,4 +17,20 @@ public static class IdGenerator
|
||||
#endif
|
||||
return new Id(hash);
|
||||
}
|
||||
|
||||
[Pure]
|
||||
public static string ComputeId(ReadOnlySpan<byte> input)
|
||||
{
|
||||
Span<byte> hash = stackalloc byte[SHA256.HashSizeInBytes];
|
||||
SHA256.HashData(input, hash);
|
||||
|
||||
Span<char> output = stackalloc char[32];
|
||||
|
||||
for (int i = 0, j = 0; j < 32; i += sizeof(byte), j += sizeof(char))
|
||||
{
|
||||
hash[i].TryFormat(output[j..], out _, "x2");
|
||||
}
|
||||
|
||||
return new string(output);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
namespace Speckle.Sdk.Serialisation;
|
||||
using System.Buffers;
|
||||
using Speckle.Sdk.Dependencies;
|
||||
|
||||
namespace Speckle.Sdk.Serialisation;
|
||||
|
||||
public readonly record struct SerializationResult(Json Json, Id? Id);
|
||||
|
||||
@@ -14,6 +17,26 @@ public readonly record struct Json
|
||||
public string Value { get; }
|
||||
}
|
||||
|
||||
public sealed class EfficientJson : IDisposable
|
||||
{
|
||||
private readonly ArrayBufferWriter<byte> _value;
|
||||
|
||||
public EfficientJson()
|
||||
{
|
||||
_value = Pools.ArrayBufferWriter.Get();
|
||||
}
|
||||
|
||||
internal IBufferWriter<byte> Buffer => _value;
|
||||
|
||||
public ReadOnlySpan<byte> WrittenSpan => _value.WrittenSpan;
|
||||
|
||||
public ReadOnlyMemory<byte> WrittenMemory => _value.WrittenMemory;
|
||||
|
||||
public int WrittenCount => _value.WrittenCount;
|
||||
|
||||
public void Dispose() => Pools.ArrayBufferWriter.Return(_value);
|
||||
}
|
||||
|
||||
public readonly record struct Id
|
||||
{
|
||||
public Id(string id)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup Label="Compiler Properties">
|
||||
<TargetFrameworks>netstandard2.0;net8.0</TargetFrameworks>
|
||||
<TargetFrameworks>net8.0</TargetFrameworks>
|
||||
<Configurations>Debug;Release;Local</Configurations>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
|
||||
@@ -1,302 +1,6 @@
|
||||
{
|
||||
"version": 2,
|
||||
"dependencies": {
|
||||
".NETStandard,Version=v2.0": {
|
||||
"GraphQL.Client": {
|
||||
"type": "Direct",
|
||||
"requested": "[6.0.0, )",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "8yPNBbuVBpTptivyAlak4GZvbwbUcjeQTL4vN1HKHRuOykZ4r7l5fcLS6vpyPyLn0x8FsL31xbOIKyxbmR9rbA==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client.Abstractions": "6.0.0",
|
||||
"GraphQL.Client.Abstractions.Websocket": "6.0.0",
|
||||
"System.Reactive": "5.0.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.CSharp": {
|
||||
"type": "Direct",
|
||||
"requested": "[4.7.0, )",
|
||||
"resolved": "4.7.0",
|
||||
"contentHash": "pTj+D3uJWyN3My70i2Hqo+OXixq3Os2D1nJ2x92FFo6sk8fYS1m1WLNTs0Dc1uPaViH0YvEEwvzddQ7y4rhXmA=="
|
||||
},
|
||||
"Microsoft.Data.Sqlite": {
|
||||
"type": "Direct",
|
||||
"requested": "[7.0.5, )",
|
||||
"resolved": "7.0.5",
|
||||
"contentHash": "KGxbPeWsQMnmQy43DSBxAFtHz3l2JX8EWBSGUCvT3CuZ8KsuzbkqMIJMDOxWtG8eZSoCDI04aiVQjWuuV8HmSw==",
|
||||
"dependencies": {
|
||||
"Microsoft.Data.Sqlite.Core": "7.0.5",
|
||||
"SQLitePCLRaw.bundle_e_sqlite3": "2.1.4"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": {
|
||||
"type": "Direct",
|
||||
"requested": "[2.2.0, )",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
|
||||
},
|
||||
"Microsoft.Extensions.Logging": {
|
||||
"type": "Direct",
|
||||
"requested": "[2.2.0, )",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "Nxqhadc9FCmFHzU+fz3oc8sFlE6IadViYg8dfUdGzJZ2JUxnCsRghBhhOWdM4B2zSZqEc+0BjliBh/oNdRZuig==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Configuration.Binder": "2.2.0",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Options": "2.2.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.SourceLink.GitHub": {
|
||||
"type": "Direct",
|
||||
"requested": "[8.0.0, )",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "G5q7OqtwIyGTkeIOAc3u2ZuV/kicQaec5EaRnc0pIeSnh9LUjj+PYQrJYBURvDt7twGl2PKA7nSN0kz1Zw5bnQ==",
|
||||
"dependencies": {
|
||||
"Microsoft.Build.Tasks.Git": "8.0.0",
|
||||
"Microsoft.SourceLink.Common": "8.0.0"
|
||||
}
|
||||
},
|
||||
"NETStandard.Library": {
|
||||
"type": "Direct",
|
||||
"requested": "[2.0.3, )",
|
||||
"resolved": "2.0.3",
|
||||
"contentHash": "st47PosZSHrjECdjeIzZQbzivYBJFv6P2nv4cj2ypdI204DO+vZ7l5raGMiX4eXMJ53RfOIg+/s4DHVZ54Nu2A==",
|
||||
"dependencies": {
|
||||
"Microsoft.NETCore.Platforms": "1.1.0"
|
||||
}
|
||||
},
|
||||
"PolySharp": {
|
||||
"type": "Direct",
|
||||
"requested": "[1.15.0, )",
|
||||
"resolved": "1.15.0",
|
||||
"contentHash": "FbU0El+EEjdpuIX4iDbeS7ki1uzpJPx8vbqOzEtqnl1GZeAGJfq+jCbxeJL2y0EPnUNk8dRnnqR2xnYXg9Tf+g=="
|
||||
},
|
||||
"Speckle.DoubleNumerics": {
|
||||
"type": "Direct",
|
||||
"requested": "[4.1.0, )",
|
||||
"resolved": "4.1.0",
|
||||
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
|
||||
},
|
||||
"Speckle.InterfaceGenerator": {
|
||||
"type": "Direct",
|
||||
"requested": "[0.9.6, )",
|
||||
"resolved": "0.9.6",
|
||||
"contentHash": "HKH7tYrYYlCK1ct483hgxERAdVdMtl7gUKW9ijWXxA1UsYR4Z+TrRHYmzZ9qmpu1NnTycSrp005NYM78GDKV1w=="
|
||||
},
|
||||
"Speckle.Newtonsoft.Json": {
|
||||
"type": "Direct",
|
||||
"requested": "[13.0.2, )",
|
||||
"resolved": "13.0.2",
|
||||
"contentHash": "g1BejUZwax5PRfL6xHgLEK23sqHWOgOj9hE7RvfRRlN00AGt8GnPYt8HedSK7UB3HiRW8zCA9Pn0iiYxCK24BA=="
|
||||
},
|
||||
"GraphQL.Client.Abstractions": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "h7uzWFORHZ+CCjwr/ThAyXMr0DPpzEANDa4Uo54wqCQ+j7qUKwqYTgOrb1W40sqbvNaZm9v/X7It31SUw0maHA==",
|
||||
"dependencies": {
|
||||
"GraphQL.Primitives": "6.0.0"
|
||||
}
|
||||
},
|
||||
"GraphQL.Client.Abstractions.Websocket": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "Nr9bPf8gIOvLuXpqEpqr9z9jslYFJOvd0feHth3/kPqeR3uMbjF5pjiwh4jxyMcxHdr8Pb6QiXkV3hsSyt0v7A==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client.Abstractions": "6.0.0"
|
||||
}
|
||||
},
|
||||
"GraphQL.Primitives": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "yg72rrYDapfsIUrul7aF6wwNnTJBOFvuA9VdDTQpPa8AlAriHbufeXYLBcodKjfUdkCnaiggX1U/nEP08Zb5GA=="
|
||||
},
|
||||
"Microsoft.Build.Tasks.Git": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "bZKfSIKJRXLTuSzLudMFte/8CempWjVamNUR5eHJizsy+iuOuO/k2gnh7W0dHJmYY0tBf+gUErfluCv5mySAOQ=="
|
||||
},
|
||||
"Microsoft.Data.Sqlite.Core": {
|
||||
"type": "Transitive",
|
||||
"resolved": "7.0.5",
|
||||
"contentHash": "FTerRmQPqHrCrnoUzhBu+E+1DNGwyrAMLqHkAqOOOu5pGfyMOj8qQUBxI/gDtWtG11p49UxSfWmBzRNlwZqfUg==",
|
||||
"dependencies": {
|
||||
"SQLitePCLRaw.core": "2.1.4"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Configuration": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "nOP8R1mVb/6mZtm2qgAJXn/LFm/2kMjHDAg/QJLFG6CuWYJtaD3p1BwQhufBVvRzL9ceJ/xF0SQ0qsI2GkDQAA==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Configuration.Abstractions": "2.2.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Configuration.Abstractions": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "65MrmXCziWaQFrI0UHkQbesrX5wTwf9XPjY5yFm/VkgJKFJ5gqvXRoXjIZcf2wLi5ZlwGz/oMYfyURVCWbM5iw==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Primitives": "2.2.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Configuration.Binder": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "vJ9xvOZCnUAIHcGC3SU35r3HKmHTVIeHzo6u/qzlHAqD8m6xv92MLin4oJntTvkpKxVX3vI1GFFkIQtU3AdlsQ==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Configuration": "2.2.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Logging.Abstractions": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "B2WqEox8o+4KUOpL7rZPyh6qYjik8tHi2tN8Z9jZkHzED8ElYgZa/h6K+xliB435SqUcWT290Fr2aa8BtZjn8A=="
|
||||
},
|
||||
"Microsoft.Extensions.Options": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "UpZLNLBpIZ0GTebShui7xXYh6DmBHjWM8NxGxZbdQh/bPZ5e6YswqI+bru6BnEL5eWiOdodsXtEz3FROcgi/qg==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Primitives": "2.2.0",
|
||||
"System.ComponentModel.Annotations": "4.5.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Primitives": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "azyQtqbm4fSaDzZHD/J+V6oWMFaf2tWP4WEGIYePLCMw3+b2RQdj9ybgbQyjCshcitQKQ4lEDOZjmSlTTrHxUg==",
|
||||
"dependencies": {
|
||||
"System.Memory": "4.5.1",
|
||||
"System.Runtime.CompilerServices.Unsafe": "4.5.1"
|
||||
}
|
||||
},
|
||||
"Microsoft.NETCore.Platforms": {
|
||||
"type": "Transitive",
|
||||
"resolved": "1.1.0",
|
||||
"contentHash": "kz0PEW2lhqygehI/d6XsPCQzD7ff7gUJaVGPVETX611eadGsA3A877GdSlU0LRVMCTH/+P3o2iDTak+S08V2+A=="
|
||||
},
|
||||
"Microsoft.NETCore.Targets": {
|
||||
"type": "Transitive",
|
||||
"resolved": "1.1.0",
|
||||
"contentHash": "aOZA3BWfz9RXjpzt0sRJJMjAscAUm3Hoa4UWAfceV9UTYxgwZ1lZt5nO2myFf+/jetYQo4uTP7zS8sJY67BBxg=="
|
||||
},
|
||||
"Microsoft.SourceLink.Common": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw=="
|
||||
},
|
||||
"SQLitePCLRaw.bundle_e_sqlite3": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.1.4",
|
||||
"contentHash": "EWI1olKDjFEBMJu0+3wuxwziIAdWDVMYLhuZ3Qs84rrz+DHwD00RzWPZCa+bLnHCf3oJwuFZIRsHT5p236QXww==",
|
||||
"dependencies": {
|
||||
"SQLitePCLRaw.lib.e_sqlite3": "2.1.4",
|
||||
"SQLitePCLRaw.provider.e_sqlite3": "2.1.4"
|
||||
}
|
||||
},
|
||||
"SQLitePCLRaw.core": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.1.4",
|
||||
"contentHash": "inBjvSHo9UDKneGNzfUfDjK08JzlcIhn1+SP5Y3m6cgXpCxXKCJDy6Mka7LpgSV+UZmKSnC8rTwB0SQ0xKu5pA==",
|
||||
"dependencies": {
|
||||
"System.Memory": "4.5.3"
|
||||
}
|
||||
},
|
||||
"SQLitePCLRaw.lib.e_sqlite3": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.1.4",
|
||||
"contentHash": "2C9Q9eX7CPLveJA0rIhf9RXAvu+7nWZu1A2MdG6SD/NOu26TakGgL1nsbc0JAspGijFOo3HoN79xrx8a368fBg=="
|
||||
},
|
||||
"SQLitePCLRaw.provider.e_sqlite3": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.1.4",
|
||||
"contentHash": "CSlb5dUp1FMIkez9Iv5EXzpeq7rHryVNqwJMWnpq87j9zWZexaEMdisDktMsnnrzKM6ahNrsTkjqNodTBPBxtQ==",
|
||||
"dependencies": {
|
||||
"SQLitePCLRaw.core": "2.1.4"
|
||||
}
|
||||
},
|
||||
"System.Buffers": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.4.0",
|
||||
"contentHash": "AwarXzzoDwX6BgrhjoJsk6tUezZEozOT5Y9QKF94Gl4JK91I4PIIBkBco9068Y9/Dra8Dkbie99kXB8+1BaYKw=="
|
||||
},
|
||||
"System.ComponentModel.Annotations": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.5.0",
|
||||
"contentHash": "UxYQ3FGUOtzJ7LfSdnYSFd7+oEv6M8NgUatatIN2HxNtDdlcvFAf+VIq4Of9cDMJEJC0aSRv/x898RYhB4Yppg=="
|
||||
},
|
||||
"System.Memory": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.5.3",
|
||||
"contentHash": "3oDzvc/zzetpTKWMShs1AADwZjQ/36HnsufHRPcOjyRAAMLDlu2iD33MBI2opxnezcVUtXyqDXXjoFMOU9c7SA==",
|
||||
"dependencies": {
|
||||
"System.Buffers": "4.4.0",
|
||||
"System.Numerics.Vectors": "4.4.0",
|
||||
"System.Runtime.CompilerServices.Unsafe": "4.5.2"
|
||||
}
|
||||
},
|
||||
"System.Numerics.Vectors": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.4.0",
|
||||
"contentHash": "UiLzLW+Lw6HLed1Hcg+8jSRttrbuXv7DANVj0DkL9g6EnnzbL75EB7EWsw5uRbhxd/4YdG8li5XizGWepmG3PQ=="
|
||||
},
|
||||
"System.Reactive": {
|
||||
"type": "Transitive",
|
||||
"resolved": "5.0.0",
|
||||
"contentHash": "erBZjkQHWL9jpasCE/0qKAryzVBJFxGHVBAvgRN1bzM0q2s1S4oYREEEL0Vb+1kA/6BKb5FjUZMp5VXmy+gzkQ==",
|
||||
"dependencies": {
|
||||
"System.Runtime.InteropServices.WindowsRuntime": "4.3.0",
|
||||
"System.Threading.Tasks.Extensions": "4.5.4"
|
||||
}
|
||||
},
|
||||
"System.Runtime": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.3.0",
|
||||
"contentHash": "JufQi0vPQ0xGnAczR13AUFglDyVYt4Kqnz1AZaiKZ5+GICq0/1MH/mO/eAJHt/mHW1zjKBJd7kV26SrxddAhiw==",
|
||||
"dependencies": {
|
||||
"Microsoft.NETCore.Platforms": "1.1.0",
|
||||
"Microsoft.NETCore.Targets": "1.1.0"
|
||||
}
|
||||
},
|
||||
"System.Runtime.CompilerServices.Unsafe": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.5.3",
|
||||
"contentHash": "3TIsJhD1EiiT0w2CcDMN/iSSwnNnsrnbzeVHSKkaEgV85txMprmuO+Yq2AdSbeVGcg28pdNDTPK87tJhX7VFHw=="
|
||||
},
|
||||
"System.Runtime.InteropServices.WindowsRuntime": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.3.0",
|
||||
"contentHash": "J4GUi3xZQLUBasNwZnjrffN8i5wpHrBtZoLG+OhRyGo/+YunMRWWtwoMDlUAIdmX0uRfpHIBDSV6zyr3yf00TA==",
|
||||
"dependencies": {
|
||||
"System.Runtime": "4.3.0"
|
||||
}
|
||||
},
|
||||
"System.Threading.Tasks.Extensions": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.5.4",
|
||||
"contentHash": "zteT+G8xuGu6mS+mzDzYXbzS7rd3K6Fjb9RiZlYlJPam2/hU7JCBZBVEcywNuR+oZ1ncTvc/cq0faRr3P01OVg==",
|
||||
"dependencies": {
|
||||
"System.Runtime.CompilerServices.Unsafe": "4.5.3"
|
||||
}
|
||||
},
|
||||
"speckle.sdk.dependencies": {
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Bcl.AsyncInterfaces": "[9.0.4, )"
|
||||
}
|
||||
},
|
||||
"Microsoft.Bcl.AsyncInterfaces": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[9.0.4, )",
|
||||
"resolved": "9.0.4",
|
||||
"contentHash": "9VGI5kxIvrNG2mqLQZnUR6y/3fcnygD8eNpHR+CqfbnIXvea6nehnYknDKQTxZVPMpzpNca+7DxLBmpdB3q0Bw==",
|
||||
"dependencies": {
|
||||
"System.Threading.Tasks.Extensions": "4.5.4"
|
||||
}
|
||||
}
|
||||
},
|
||||
"net8.0": {
|
||||
"GraphQL.Client": {
|
||||
"type": "Direct",
|
||||
|
||||
Reference in New Issue
Block a user