diff --git a/.editorconfig b/.editorconfig
index 5778aea1..594617a8 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -318,7 +318,7 @@ indent_size = 2
tab_width = 2
# Verify settings
-[*.{received,verified}.{json}]
+[*.{received,verified}.{json,txt}]
charset = utf-8-bom
end_of_line = lf
indent_size = unset
diff --git a/.gitattributes b/.gitattributes
index d87a165f..a48dc2b0 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -5,4 +5,5 @@
*.txt text eol=crlf
# Verify
-*.verified.json text eol=lf working-tree-encoding=UTF-8
\ No newline at end of file
+*.verified.json text eol=lf working-tree-encoding=UTF-8
+*.verified.txt text eol=lf working-tree-encoding=UTF-8
diff --git a/Directory.Packages.props b/Directory.Packages.props
index 47940efc..8d641649 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -30,7 +30,7 @@
-
+
@@ -63,7 +63,7 @@
-
+
diff --git a/Speckle.Sdk.slnx b/Speckle.Sdk.slnx
index 2461b2a0..19022179 100644
--- a/Speckle.Sdk.slnx
+++ b/Speckle.Sdk.slnx
@@ -14,6 +14,7 @@
+
diff --git a/docker-compose-internal.yml b/docker-compose-internal.yml
index 11d2d9b6..34e1125b 100644
--- a/docker-compose-internal.yml
+++ b/docker-compose-internal.yml
@@ -5,21 +5,24 @@ services:
# Speckle Server dependencies
#######
postgres:
- image: "postgres:16.4-alpine3.20@sha256:d898b0b78a2627cb4ee63464a14efc9d296884f1b28c841b0ab7d7c42f1fffdf"
+ image: 'postgres:18.3-alpine3.23@sha256:54451ecb8ab38c24c3ec123f2fd501303a3a1856a5c66e98cecf2460d5e1e9d7'
restart: always
environment:
POSTGRES_DB: speckle
POSTGRES_USER: speckle
POSTGRES_PASSWORD: speckle
volumes:
- - ./.volumes/postgres-data:/var/lib/postgresql/data/
+ - ./.volumes/postgres-data:/var/lib/postgresql
+ - ./setup/db/10-docker_postgres_init.sql:/docker-entrypoint-initdb.d/10-docker_postgres_init.sql
+ - ./setup/db/11-docker_postgres_authentik_init.sql:/docker-entrypoint-initdb.d/11-docker_postgres_authentik_init.sql
+ command: postgres -c max_prepared_transactions=150
healthcheck:
- # the -U user has to match the POSTGRES_USER value
- test: ["CMD-SHELL", "pg_isready -U speckle"]
- interval: 5s
+ test: ["CMD-SHELL", "pg_isready -U speckle -d speckle"]
+ interval: 10s
timeout: 5s
- retries: 30
-
+ retries: 5
+ start_period: 20s
+
redis:
image: "valkey/valkey:8.1-alpine@sha256:0d27f0bca0249f61d060029a6aaf2e16b2c417d68d02a508e1dfb763fa2948b4"
restart: always
@@ -32,7 +35,7 @@ services:
retries: 30
minio:
- image: "minio/minio:RELEASE.2023-10-25T06-33-25Z"
+ image: "minio/minio:RELEASE.2025-09-07T16-13-09Z"
command: server /data --console-address ":9001"
restart: always
volumes:
@@ -102,8 +105,7 @@ services:
LOG_PRETTY: "true"
- FF_NEXT_GEN_FILE_IMPORTER_ENABLED: "true"
- FF_LARGE_FILE_IMPORTS_ENABLED: "true"
+ FF_DATA_MODULE_ENABLED: 'true'
networks:
default:
diff --git a/src/Speckle.Automate.Sdk/Speckle.Automate.Sdk.csproj b/src/Speckle.Automate.Sdk/Speckle.Automate.Sdk.csproj
index 68dd60df..533b2983 100644
--- a/src/Speckle.Automate.Sdk/Speckle.Automate.Sdk.csproj
+++ b/src/Speckle.Automate.Sdk/Speckle.Automate.Sdk.csproj
@@ -18,9 +18,12 @@
-
-
-
+
+
diff --git a/src/Speckle.Automate.Sdk/packages.lock.json b/src/Speckle.Automate.Sdk/packages.lock.json
index e7bc66d9..7f25b757 100644
--- a/src/Speckle.Automate.Sdk/packages.lock.json
+++ b/src/Speckle.Automate.Sdk/packages.lock.json
@@ -53,16 +53,17 @@
},
"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"
+ "requested": "[10.0.7, )",
+ "resolved": "10.0.7",
+ "contentHash": "F8Pu2QLUMeniVbtiyk7n7LCfFYxlcJ8ASaSwglJyq6dxa34iCQrikQszsgJClIJWuSWjcyhKkV7daAzYJqeVwA==",
+ "dependencies": {
+ "Microsoft.Bcl.AsyncInterfaces": "10.0.7",
+ "System.Buffers": "4.6.1",
+ "System.IO.Pipelines": "10.0.7",
+ "System.Memory": "4.6.3",
+ "System.Runtime.CompilerServices.Unsafe": "6.1.2",
+ "System.Text.Encodings.Web": "10.0.7",
+ "System.Threading.Tasks.Extensions": "4.6.3"
}
},
"GraphQL.Client.Abstractions": {
@@ -199,28 +200,38 @@
},
"System.Buffers": {
"type": "Transitive",
- "resolved": "4.5.1",
- "contentHash": "Rw7ijyl1qqRS0YQD/WycNst8hUUMgrMH4FCn1nNm27M4VxchZ1js3fVjQaANHO5f3sN4isvP4a+Met9Y4YomAg=="
+ "resolved": "4.6.1",
+ "contentHash": "N8GXpmiLMtljq7gwvyS+1QvKT/W2J8sNAvx+HVg4NGmsG/H+2k/y9QI23auLJRterrzCiDH+IWAw4V/GPwsMlw=="
},
"System.ComponentModel.Annotations": {
"type": "Transitive",
"resolved": "4.5.0",
"contentHash": "UxYQ3FGUOtzJ7LfSdnYSFd7+oEv6M8NgUatatIN2HxNtDdlcvFAf+VIq4Of9cDMJEJC0aSRv/x898RYhB4Yppg=="
},
+ "System.IO.Pipelines": {
+ "type": "Transitive",
+ "resolved": "10.0.7",
+ "contentHash": "LTxXYYKmRhPKWveYmfzuRTUnzsfY7CN+WOq6aTRgYE9vJ8BUvIWPCaSx4HxqBwXViTPSjR9cHDOVuVPuZGRR/Q==",
+ "dependencies": {
+ "System.Buffers": "4.6.1",
+ "System.Memory": "4.6.3",
+ "System.Threading.Tasks.Extensions": "4.6.3"
+ }
+ },
"System.Memory": {
"type": "Transitive",
- "resolved": "4.5.5",
- "contentHash": "XIWiDvKPXaTveaB7HVganDlOCRoj03l+jrwNvcge/t8vhGYKvqV+dMv6G4SAX2NoNmN0wZfVPTAlFwZcZvVOUw==",
+ "resolved": "4.6.3",
+ "contentHash": "qdcDOgnFZY40+Q9876JUHnlHu7bosOHX8XISRoH94fwk6hgaeQGSgfZd8srWRZNt5bV9ZW2TljcegDNxsf+96A==",
"dependencies": {
- "System.Buffers": "4.5.1",
- "System.Numerics.Vectors": "4.4.0",
- "System.Runtime.CompilerServices.Unsafe": "4.5.3"
+ "System.Buffers": "4.6.1",
+ "System.Numerics.Vectors": "4.6.1",
+ "System.Runtime.CompilerServices.Unsafe": "6.1.2"
}
},
"System.Numerics.Vectors": {
"type": "Transitive",
- "resolved": "4.4.0",
- "contentHash": "UiLzLW+Lw6HLed1Hcg+8jSRttrbuXv7DANVj0DkL9g6EnnzbL75EB7EWsw5uRbhxd/4YdG8li5XizGWepmG3PQ=="
+ "resolved": "4.6.1",
+ "contentHash": "sQxefTnhagrhoq2ReR0D/6K0zJcr9Hrd6kikeXsA1I8kOCboTavcUC4r7TSfpKFeE163uMuxZcyfO1mGO3EN8Q=="
},
"System.Reactive": {
"type": "Transitive",
@@ -233,8 +244,8 @@
},
"System.Runtime.CompilerServices.Unsafe": {
"type": "Transitive",
- "resolved": "6.0.0",
- "contentHash": "/iUeP3tq1S0XdNNoMz5C9twLSrM/TH+qElHkXWaPvuNOt+99G75NrV0OS2EqHx5wMN7popYjpc8oTjC1y16DLg=="
+ "resolved": "6.1.2",
+ "contentHash": "2hBr6zdbIBTDE3EhK7NSVNdX58uTK6iHW/P/Axmm9sl1xoGSLqDvMtpecn226TNwHByFokYwJmt/aQQNlO5CRw=="
},
"System.Runtime.InteropServices.WindowsRuntime": {
"type": "Transitive",
@@ -243,20 +254,20 @@
},
"System.Text.Encodings.Web": {
"type": "Transitive",
- "resolved": "8.0.0",
- "contentHash": "yev/k9GHAEGx2Rg3/tU6MQh4HGBXJs70y7j1LaM1i/ER9po+6nnQ6RRqTJn1E7Xu0fbIFK80Nh5EoODxrbxwBQ==",
+ "resolved": "10.0.7",
+ "contentHash": "WUH+viO8VDG8NpFKvOBwpeyKUiPOMz3kQpA6AKCD4b2NG1pBhyC4AwTb357iZmTxZDnkM4IsFnvzN8W8OKmsHg==",
"dependencies": {
- "System.Buffers": "4.5.1",
- "System.Memory": "4.5.5",
- "System.Runtime.CompilerServices.Unsafe": "6.0.0"
+ "System.Buffers": "4.6.1",
+ "System.Memory": "4.6.3",
+ "System.Runtime.CompilerServices.Unsafe": "6.1.2"
}
},
"System.Threading.Tasks.Extensions": {
"type": "Transitive",
- "resolved": "4.5.4",
- "contentHash": "zteT+G8xuGu6mS+mzDzYXbzS7rd3K6Fjb9RiZlYlJPam2/hU7JCBZBVEcywNuR+oZ1ncTvc/cq0faRr3P01OVg==",
+ "resolved": "4.6.3",
+ "contentHash": "7sCiwilJLYbTZELaKnc7RecBBXWXA+xMLQWZKWawBxYjp6DBlSE3v9/UcvKBvr1vv2tTOhipiogM8rRmxlhrVA==",
"dependencies": {
- "System.Runtime.CompilerServices.Unsafe": "4.5.3"
+ "System.Runtime.CompilerServices.Unsafe": "6.1.2"
}
},
"speckle.objects": {
@@ -273,9 +284,11 @@
"Microsoft.Data.Sqlite": "[7.0.5, )",
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Microsoft.Extensions.Logging": "[2.2.0, )",
+ "Microsoft.Extensions.ObjectPool": "[6.0.0, )",
"Speckle.DoubleNumerics": "[4.1.0, )",
"Speckle.Newtonsoft.Json": "[13.0.2, )",
- "Speckle.Sdk.Dependencies": "[1.0.0, )"
+ "Speckle.Sdk.Dependencies": "[1.0.0, )",
+ "System.Text.Json": "[5.0.2, )"
}
},
"speckle.sdk.dependencies": {
@@ -298,10 +311,10 @@
"Microsoft.Bcl.AsyncInterfaces": {
"type": "CentralTransitive",
"requested": "[9.0.4, )",
- "resolved": "9.0.4",
- "contentHash": "9VGI5kxIvrNG2mqLQZnUR6y/3fcnygD8eNpHR+CqfbnIXvea6nehnYknDKQTxZVPMpzpNca+7DxLBmpdB3q0Bw==",
+ "resolved": "10.0.7",
+ "contentHash": "g0Xp9A+B8jCf5pNIIhFOQXPJkte3D87shfTLY+ylwfSh22U5oQH6tvvmcUuqJvt/wtwKk0WdNp2OGEczHJlJdg==",
"dependencies": {
- "System.Threading.Tasks.Extensions": "4.5.4"
+ "System.Threading.Tasks.Extensions": "4.6.3"
}
},
"Microsoft.CSharp": {
@@ -341,6 +354,12 @@
"Microsoft.Extensions.Options": "2.2.0"
}
},
+ "Microsoft.Extensions.ObjectPool": {
+ "type": "CentralTransitive",
+ "requested": "[9.0.4, )",
+ "resolved": "6.0.0",
+ "contentHash": "7hR9FU0JJHOCLmn/Ary31pLLAhlzoMptBKs5CJmNUzD87dXjl+/NqVkyCTl6cT2JAfTK0G39HpvCOv1fhsX3BQ=="
+ },
"Speckle.DoubleNumerics": {
"type": "CentralTransitive",
"requested": "[4.1.0, )",
@@ -506,8 +525,8 @@
"dependencies": {
"GraphQL.Client": "[6.1.0, )",
"Microsoft.Data.Sqlite": "[10.0.0, )",
- "Microsoft.Extensions.DependencyInjection": "[10.0.0, )",
"Microsoft.Extensions.Logging": "[10.0.0, )",
+ "Microsoft.Extensions.ObjectPool": "[10.0.0, )",
"Speckle.DoubleNumerics": "[4.1.0, )",
"Speckle.Newtonsoft.Json": "[13.0.2, )",
"Speckle.Sdk.Dependencies": "[1.0.0, )"
@@ -558,6 +577,12 @@
"Microsoft.Extensions.Options": "10.0.0"
}
},
+ "Microsoft.Extensions.ObjectPool": {
+ "type": "CentralTransitive",
+ "requested": "[9.0.4, )",
+ "resolved": "10.0.0",
+ "contentHash": "bpeCq0IYmVLACyEUMzFIOQX+zZUElG1t+nu1lSxthe7B+1oNYking7b91305+jNB6iwojp9fqTY9O+Nh7ULQxg=="
+ },
"Speckle.DoubleNumerics": {
"type": "CentralTransitive",
"requested": "[4.1.0, )",
@@ -723,8 +748,8 @@
"dependencies": {
"GraphQL.Client": "[6.0.0, )",
"Microsoft.Data.Sqlite": "[7.0.5, )",
- "Microsoft.Extensions.DependencyInjection": "[8.0.0, )",
"Microsoft.Extensions.Logging": "[8.0.0, )",
+ "Microsoft.Extensions.ObjectPool": "[8.0.0, )",
"Speckle.DoubleNumerics": "[4.1.0, )",
"Speckle.Newtonsoft.Json": "[13.0.2, )",
"Speckle.Sdk.Dependencies": "[1.0.0, )"
@@ -774,6 +799,12 @@
"Microsoft.Extensions.Options": "8.0.0"
}
},
+ "Microsoft.Extensions.ObjectPool": {
+ "type": "CentralTransitive",
+ "requested": "[9.0.4, )",
+ "resolved": "8.0.0",
+ "contentHash": "4pm+XgxSukskwjzDDfSjG4KNUIOdFF2VaqZZDtTzoyQMOVSnlV6ZM8a9aVu5dg9LVZTB//utzSc8fOi0b0Mb2Q=="
+ },
"Speckle.DoubleNumerics": {
"type": "CentralTransitive",
"requested": "[4.1.0, )",
diff --git a/src/Speckle.Objects/packages.lock.json b/src/Speckle.Objects/packages.lock.json
index 7097b43c..3cdab5d0 100644
--- a/src/Speckle.Objects/packages.lock.json
+++ b/src/Speckle.Objects/packages.lock.json
@@ -162,8 +162,8 @@
},
"System.Buffers": {
"type": "Transitive",
- "resolved": "4.4.0",
- "contentHash": "AwarXzzoDwX6BgrhjoJsk6tUezZEozOT5Y9QKF94Gl4JK91I4PIIBkBco9068Y9/Dra8Dkbie99kXB8+1BaYKw=="
+ "resolved": "4.5.1",
+ "contentHash": "Rw7ijyl1qqRS0YQD/WycNst8hUUMgrMH4FCn1nNm27M4VxchZ1js3fVjQaANHO5f3sN4isvP4a+Met9Y4YomAg=="
},
"System.ComponentModel.Annotations": {
"type": "Transitive",
@@ -172,18 +172,18 @@
},
"System.Memory": {
"type": "Transitive",
- "resolved": "4.5.3",
- "contentHash": "3oDzvc/zzetpTKWMShs1AADwZjQ/36HnsufHRPcOjyRAAMLDlu2iD33MBI2opxnezcVUtXyqDXXjoFMOU9c7SA==",
+ "resolved": "4.5.4",
+ "contentHash": "1MbJTHS1lZ4bS4FmsJjnuGJOu88ZzTT2rLvrhW7Ygic+pC0NWA+3hgAen0HRdsocuQXCkUTdFn9yHJJhsijDXw==",
"dependencies": {
- "System.Buffers": "4.4.0",
+ "System.Buffers": "4.5.1",
"System.Numerics.Vectors": "4.4.0",
- "System.Runtime.CompilerServices.Unsafe": "4.5.2"
+ "System.Runtime.CompilerServices.Unsafe": "4.5.3"
}
},
"System.Numerics.Vectors": {
"type": "Transitive",
- "resolved": "4.4.0",
- "contentHash": "UiLzLW+Lw6HLed1Hcg+8jSRttrbuXv7DANVj0DkL9g6EnnzbL75EB7EWsw5uRbhxd/4YdG8li5XizGWepmG3PQ=="
+ "resolved": "4.5.0",
+ "contentHash": "QQTlPTl06J/iiDbJCiepZ4H//BVraReU4O4EoRw1U02H5TLUIT7xn3GnDp9AXPSlJUDyFs4uWjWafNX6WrAojQ=="
},
"System.Reactive": {
"type": "Transitive",
@@ -196,14 +196,23 @@
},
"System.Runtime.CompilerServices.Unsafe": {
"type": "Transitive",
- "resolved": "4.5.3",
- "contentHash": "3TIsJhD1EiiT0w2CcDMN/iSSwnNnsrnbzeVHSKkaEgV85txMprmuO+Yq2AdSbeVGcg28pdNDTPK87tJhX7VFHw=="
+ "resolved": "5.0.0",
+ "contentHash": "ZD9TMpsmYJLrxbbmdvhwt9YEgG5WntEnZ/d1eH8JBX9LBp+Ju8BSBhUGbZMNVHHomWo2KVImJhTDl2hIgw/6MA=="
},
"System.Runtime.InteropServices.WindowsRuntime": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "J4GUi3xZQLUBasNwZnjrffN8i5wpHrBtZoLG+OhRyGo/+YunMRWWtwoMDlUAIdmX0uRfpHIBDSV6zyr3yf00TA=="
},
+ "System.Text.Encodings.Web": {
+ "type": "Transitive",
+ "resolved": "5.0.1",
+ "contentHash": "KmJ+CJXizDofbq6mpqDoRRLcxgOd2z9X3XoFNULSbvbqVRZkFX3istvr+MUjL6Zw1RT+RNdoI4GYidIINtgvqQ==",
+ "dependencies": {
+ "System.Buffers": "4.5.1",
+ "System.Memory": "4.5.4"
+ }
+ },
"System.Threading.Tasks.Extensions": {
"type": "Transitive",
"resolved": "4.5.4",
@@ -220,9 +229,11 @@
"Microsoft.Data.Sqlite": "[7.0.5, )",
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Microsoft.Extensions.Logging": "[2.2.0, )",
+ "Microsoft.Extensions.ObjectPool": "[6.0.0, )",
"Speckle.DoubleNumerics": "[4.1.0, )",
"Speckle.Newtonsoft.Json": "[13.0.2, )",
- "Speckle.Sdk.Dependencies": "[1.0.0, )"
+ "Speckle.Sdk.Dependencies": "[1.0.0, )",
+ "System.Text.Json": "[5.0.2, )"
}
},
"speckle.sdk.dependencies": {
@@ -288,6 +299,12 @@
"Microsoft.Extensions.Options": "2.2.0"
}
},
+ "Microsoft.Extensions.ObjectPool": {
+ "type": "CentralTransitive",
+ "requested": "[9.0.4, )",
+ "resolved": "6.0.0",
+ "contentHash": "7hR9FU0JJHOCLmn/Ary31pLLAhlzoMptBKs5CJmNUzD87dXjl+/NqVkyCTl6cT2JAfTK0G39HpvCOv1fhsX3BQ=="
+ },
"Speckle.DoubleNumerics": {
"type": "CentralTransitive",
"requested": "[4.1.0, )",
@@ -299,6 +316,21 @@
"requested": "[13.0.2, )",
"resolved": "13.0.2",
"contentHash": "g1BejUZwax5PRfL6xHgLEK23sqHWOgOj9hE7RvfRRlN00AGt8GnPYt8HedSK7UB3HiRW8zCA9Pn0iiYxCK24BA=="
+ },
+ "System.Text.Json": {
+ "type": "CentralTransitive",
+ "requested": "[10.0.7, )",
+ "resolved": "5.0.2",
+ "contentHash": "I47dVIGiV6SfAyppphxqupertT/5oZkYLDCX6vC3HpOI4ZLjyoKAreUoem2ie6G0RbRuFrlqz/PcTQjfb2DOfQ==",
+ "dependencies": {
+ "Microsoft.Bcl.AsyncInterfaces": "5.0.0",
+ "System.Buffers": "4.5.1",
+ "System.Memory": "4.5.4",
+ "System.Numerics.Vectors": "4.5.0",
+ "System.Runtime.CompilerServices.Unsafe": "5.0.0",
+ "System.Text.Encodings.Web": "5.0.1",
+ "System.Threading.Tasks.Extensions": "4.5.4"
+ }
}
},
"net10.0": {
@@ -427,8 +459,8 @@
"dependencies": {
"GraphQL.Client": "[6.1.0, )",
"Microsoft.Data.Sqlite": "[10.0.0, )",
- "Microsoft.Extensions.DependencyInjection": "[10.0.0, )",
"Microsoft.Extensions.Logging": "[10.0.0, )",
+ "Microsoft.Extensions.ObjectPool": "[10.0.0, )",
"Speckle.DoubleNumerics": "[4.1.0, )",
"Speckle.Newtonsoft.Json": "[13.0.2, )",
"Speckle.Sdk.Dependencies": "[1.0.0, )"
@@ -479,6 +511,12 @@
"Microsoft.Extensions.Options": "10.0.0"
}
},
+ "Microsoft.Extensions.ObjectPool": {
+ "type": "CentralTransitive",
+ "requested": "[9.0.4, )",
+ "resolved": "10.0.0",
+ "contentHash": "bpeCq0IYmVLACyEUMzFIOQX+zZUElG1t+nu1lSxthe7B+1oNYking7b91305+jNB6iwojp9fqTY9O+Nh7ULQxg=="
+ },
"Speckle.DoubleNumerics": {
"type": "CentralTransitive",
"requested": "[4.1.0, )",
@@ -618,8 +656,8 @@
"dependencies": {
"GraphQL.Client": "[6.0.0, )",
"Microsoft.Data.Sqlite": "[7.0.5, )",
- "Microsoft.Extensions.DependencyInjection": "[8.0.0, )",
"Microsoft.Extensions.Logging": "[8.0.0, )",
+ "Microsoft.Extensions.ObjectPool": "[8.0.0, )",
"Speckle.DoubleNumerics": "[4.1.0, )",
"Speckle.Newtonsoft.Json": "[13.0.2, )",
"Speckle.Sdk.Dependencies": "[1.0.0, )"
@@ -669,6 +707,12 @@
"Microsoft.Extensions.Options": "8.0.0"
}
},
+ "Microsoft.Extensions.ObjectPool": {
+ "type": "CentralTransitive",
+ "requested": "[9.0.4, )",
+ "resolved": "8.0.0",
+ "contentHash": "4pm+XgxSukskwjzDDfSjG4KNUIOdFF2VaqZZDtTzoyQMOVSnlV6ZM8a9aVu5dg9LVZTB//utzSc8fOi0b0Mb2Q=="
+ },
"Speckle.DoubleNumerics": {
"type": "CentralTransitive",
"requested": "[4.1.0, )",
diff --git a/src/Speckle.Sdk/Api/Operations/Operations.Serialize.cs b/src/Speckle.Sdk/Api/Operations/Operations.Serialize.cs
index 075776f2..187e1433 100644
--- a/src/Speckle.Sdk/Api/Operations/Operations.Serialize.cs
+++ b/src/Speckle.Sdk/Api/Operations/Operations.Serialize.cs
@@ -2,6 +2,7 @@
using Speckle.Newtonsoft.Json;
using Speckle.Sdk.Logging;
using Speckle.Sdk.Models;
+using Speckle.Sdk.Pipelines.Send;
using Speckle.Sdk.Serialisation;
using Speckle.Sdk.Transports;
@@ -26,6 +27,20 @@ public string Serialize(Base value, CancellationToken cancellationToken = defaul
return serializer.Serialize(value);
}
+ ///
+ /// Serializes a given object using the new SendPipeline (System.Text.Json based) er
+ ///
+ /// The object to serializer
+ /// A json string representation of the object.
+ ///
+ /// TODO: Once we strip out the old send2 functionality, we can make this this the normal implementation
+ ///
+ public string SerializeNew(Base value)
+ {
+ var serializer = new Serializer();
+ return serializer.Serialize(value).First().Json.ToJsonString();
+ }
+
///
/// Note: if you want to pull an object from a Speckle Transport or Server,
/// please use
diff --git a/src/Speckle.Sdk/MemoryManagement/ArrayBufferWriterPooledObjectPolicy.cs b/src/Speckle.Sdk/MemoryManagement/ArrayBufferWriterPooledObjectPolicy.cs
new file mode 100644
index 00000000..6b0b1f10
--- /dev/null
+++ b/src/Speckle.Sdk/MemoryManagement/ArrayBufferWriterPooledObjectPolicy.cs
@@ -0,0 +1,39 @@
+using System.Buffers;
+using Microsoft.Extensions.ObjectPool;
+
+namespace Speckle.Sdk.MemoryManagement;
+
+public sealed class ArrayBufferWriterPooledObjectPolicy : PooledObjectPolicy>
+{
+ ///
+ /// Gets or sets the initial capacity of pooled instances.
+ ///
+ /// Defaults to 100.
+ public int InitialCapacity { get; set; } = 100;
+
+ ///
+ /// Gets or sets the maximum value for that is allowed to be
+ /// retained, when is invoked.
+ ///
+ /// Defaults to 4096.
+ public int MaximumRetainedCapacity { get; set; } = 4 * 1024;
+
+ ///
+ public override ArrayBufferWriter Create()
+ {
+ return new ArrayBufferWriter(InitialCapacity);
+ }
+
+ ///
+ public override bool Return(ArrayBufferWriter obj)
+ {
+ if (obj.Capacity > MaximumRetainedCapacity)
+ {
+ // Too big. Discard this one.
+ return false;
+ }
+
+ obj.Clear();
+ return true;
+ }
+}
diff --git a/src/Speckle.Sdk/MemoryManagement/Pools.cs b/src/Speckle.Sdk/MemoryManagement/Pools.cs
new file mode 100644
index 00000000..98beb433
--- /dev/null
+++ b/src/Speckle.Sdk/MemoryManagement/Pools.cs
@@ -0,0 +1,16 @@
+using System.Buffers;
+using Microsoft.Extensions.ObjectPool;
+
+namespace Speckle.Sdk.MemoryManagement;
+
+internal static class Pools
+{
+ public static ObjectPool> ArrayBufferWriter { get; } =
+ ObjectPool.Create(
+ new ArrayBufferWriterPooledObjectPolicy()
+ {
+ InitialCapacity = 512,
+ MaximumRetainedCapacity = 100 * 1024 * 1024,
+ }
+ );
+}
diff --git a/src/Speckle.Sdk/Models/Attributes.cs b/src/Speckle.Sdk/Models/Attributes.cs
index 808c24b8..0fec5d27 100644
--- a/src/Speckle.Sdk/Models/Attributes.cs
+++ b/src/Speckle.Sdk/Models/Attributes.cs
@@ -13,8 +13,13 @@ public sealed class DetachPropertyAttribute : Attribute
/// If set to true the default serialiser will persist it separately, and add a reference to the property's value in the original object.
/// Only applies to properties of types derived from the Base class.
///
- /// Whether to detach the property or not.
- public DetachPropertyAttribute(bool detachable = true)
+ public DetachPropertyAttribute()
+ {
+ Detachable = true;
+ }
+
+ [Obsolete("detachable = false is no longer supported")]
+ public DetachPropertyAttribute(bool detachable)
{
Detachable = detachable;
}
diff --git a/src/Speckle.Sdk/Models/Base.cs b/src/Speckle.Sdk/Models/Base.cs
index 1065e6b0..198d1189 100644
--- a/src/Speckle.Sdk/Models/Base.cs
+++ b/src/Speckle.Sdk/Models/Base.cs
@@ -57,9 +57,13 @@ public virtual string speckle_type
/// This method fully serialize the object and any referenced objects. This has a tangible cost and should be avoided.
/// Objects retrieved from a already have a property populated
/// The hash of a decomposed object differs from the hash of a non-decomposed object.
+ ///
///
/// If , will decompose the object in the process of hashing.
/// the resulting id (hash)
+ [Obsolete(
+ "The ID returned here matches the sends... It does not match the ids generated by the new serializer"
+ )]
public string GetId(bool decompose = false)
{
//TODO remove me
diff --git a/src/Speckle.Sdk/Models/DynamicBaseMemberType.cs b/src/Speckle.Sdk/Models/DynamicBaseMemberType.cs
index 4522b61e..c7e84478 100644
--- a/src/Speckle.Sdk/Models/DynamicBaseMemberType.cs
+++ b/src/Speckle.Sdk/Models/DynamicBaseMemberType.cs
@@ -17,7 +17,7 @@ public enum DynamicBaseMemberType
Dynamic = 2,
///
- /// The typed members flagged with attribute.
+ /// The typed members flagged with ObsoleteAttribute> attribute.
///
Obsolete = 4,
@@ -28,12 +28,12 @@ public enum DynamicBaseMemberType
SchemaComputed = 16,
///
- /// All the typed members, including ones with attributes.
+ /// All the typed members, including ones with ObsoleteAttribute attributes.
///
InstanceAll = Instance + Obsolete,
///
- /// All the members, including dynamic and instance members flagged with attributes
+ /// All the members, including dynamic and instance members flagged with ObsoleteAttribute attributes
///
All = InstanceAll + Dynamic,
}
diff --git a/src/Speckle.Sdk/Pipelines/Send/DiskStore.cs b/src/Speckle.Sdk/Pipelines/Send/DiskStore.cs
index 172de132..5c893d14 100644
--- a/src/Speckle.Sdk/Pipelines/Send/DiskStore.cs
+++ b/src/Speckle.Sdk/Pipelines/Send/DiskStore.cs
@@ -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 async Task CompleteAsync()
return await _writeToDiskTask.ConfigureAwait(false);
}
+ private readonly byte[] _newLineChar = [(byte)'\n'];
+ private readonly byte[] _tabLineChar = [(byte)'\t'];
+
///
/// Reads from the Channel and streams the s to a temporary file on disk.
/// Will keep reading until is called.
@@ -61,22 +65,32 @@ private async Task WriteFile()
{
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.WriteAsync(item.Id).ConfigureAwait(false);
- await writer.WriteAsync('\t').ConfigureAwait(false);
- await writer.WriteAsync(item.SpeckleType).ConfigureAwait(false);
- await writer.WriteAsync('\t').ConfigureAwait(false);
- await writer.WriteAsync(item.Json.Value).ConfigureAwait(false);
- await writer.WriteLineAsync().ConfigureAwait(false);
- }
-#if NET8_0_OR_GREATER
- await writer.FlushAsync(_cancellationToken).ConfigureAwait(false);
+ byte[] id = Encoding.UTF8.GetBytes(item.Id);
+ byte[] speckleType = Encoding.UTF8.GetBytes(item.SpeckleType);
+#if NET5_0_OR_GREATER
+ await gzip.WriteAsync(id, _cancellationToken).ConfigureAwait(false);
+ await gzip.WriteAsync(_tabLineChar, _cancellationToken).ConfigureAwait(false);
+ await gzip.WriteAsync(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);
#else
- await writer.FlushAsync().ConfigureAwait(false);
+ await gzip.WriteAsync(id, 0, id.Length, _cancellationToken).ConfigureAwait(false);
+ await gzip.WriteAsync(_tabLineChar, 0, _tabLineChar.Length, _cancellationToken).ConfigureAwait(false);
+ await gzip.WriteAsync(speckleType, 0, speckleType.Length, _cancellationToken).ConfigureAwait(false);
+ await gzip.WriteAsync(_tabLineChar, 0, _tabLineChar.Length, _cancellationToken).ConfigureAwait(false);
+ await gzip.WriteAsync(item.Json.GetInternalBuffer(), 0, item.Json.WrittenCount, _cancellationToken)
+ .ConfigureAwait(false);
+ await gzip.WriteAsync(_newLineChar, 0, _newLineChar.Length, _cancellationToken).ConfigureAwait(false);
#endif
+ item.Dispose();
+ }
+
+ await gzip.FlushAsync(_cancellationToken).ConfigureAwait(false);
+
tempFile.FileInfo.Refresh();
return tempFile;
diff --git a/src/Speckle.Sdk/Pipelines/Send/EfficientJson.cs b/src/Speckle.Sdk/Pipelines/Send/EfficientJson.cs
new file mode 100644
index 00000000..e25d48fc
--- /dev/null
+++ b/src/Speckle.Sdk/Pipelines/Send/EfficientJson.cs
@@ -0,0 +1,47 @@
+using System.Buffers;
+using System.Text;
+using System.Text.Json;
+using Speckle.Sdk.MemoryManagement;
+
+namespace Speckle.Sdk.Pipelines.Send;
+
+///
+/// Wrapper for a UTF8 Encoded array buffer
+/// More efficient to write JSON via than as s
+///
+///
+/// Mutability is exposed only internally via to
+/// For all other consumers this class is read-only.
+///
+public sealed class Utf8Json : IDisposable
+{
+ private readonly ArrayBufferWriter _value;
+ internal Utf8JsonWriter Writer { get; }
+
+ public Utf8Json()
+ {
+ _value = Pools.ArrayBufferWriter.Get();
+
+ Writer = new(_value);
+ }
+
+ internal IBufferWriter Buffer => _value;
+
+ public ReadOnlySpan WrittenSpan => _value.WrittenSpan;
+
+ public ReadOnlyMemory WrittenMemory => _value.WrittenMemory;
+
+#if NET5_0_OR_GREATER
+ public string ToJsonString() => Encoding.UTF8.GetString(WrittenSpan);
+#else
+ public byte[] GetInternalBuffer() => _value.InternalBuffer;
+
+ public void CheckAndResizeBuffer(int sizeHint) => _value.CheckAndResizeBuffer(sizeHint);
+
+ public string ToJsonString() => Encoding.UTF8.GetString(_value.InternalBuffer, 0, _value.WrittenCount);
+#endif
+
+ public int WrittenCount => _value.WrittenCount;
+
+ public void Dispose() => Pools.ArrayBufferWriter.Return(_value);
+}
diff --git a/src/Speckle.Sdk/Pipelines/Send/IdGenerator.cs b/src/Speckle.Sdk/Pipelines/Send/IdGenerator.cs
new file mode 100644
index 00000000..570f1c66
--- /dev/null
+++ b/src/Speckle.Sdk/Pipelines/Send/IdGenerator.cs
@@ -0,0 +1,52 @@
+using System.Diagnostics.CodeAnalysis;
+using System.Diagnostics.Contracts;
+using System.Security.Cryptography;
+using System.Text;
+
+namespace Speckle.Sdk.Pipelines.Send;
+
+public static class IdGenerator
+{
+ public const int ID_HEX_LENGTH_CHARS = 32;
+
+#if NET6_0_OR_GREATER
+ [Pure]
+ public static string ComputeId(ReadOnlySpan input)
+ {
+ Span hash = stackalloc byte[SHA256.HashSizeInBytes];
+ SHA256.HashData(input, hash);
+
+#if NET9_0_OR_GREATER
+ return Convert.ToHexStringLower(hash[..(SHA256.HashSizeInBytes / 2)]);
+#else
+ Span output = stackalloc char[ID_HEX_LENGTH_CHARS];
+
+ for (int i = 0, j = 0; j < ID_HEX_LENGTH_CHARS; i += sizeof(byte), j += sizeof(char))
+ {
+ hash[i].TryFormat(output[j..], out _, "x2");
+ }
+ return new string(output);
+#endif
+ }
+#endif
+
+ [Pure]
+ [SuppressMessage(
+ "Performance",
+ "CA1850:Prefer static \'HashData\' method over \'ComputeHash\'",
+ Justification = "We expose another overload with higher performance spans"
+ )]
+ public static string ComputeId(byte[] input, int offset, int count)
+ {
+ using var sha256 = SHA256.Create();
+ byte[] hash = sha256.ComputeHash(input, offset, count);
+
+ StringBuilder sb = new(64);
+ foreach (byte b in hash)
+ {
+ sb.Append(b.ToString("x2"));
+ }
+
+ return sb.ToString(0, ID_HEX_LENGTH_CHARS);
+ }
+}
diff --git a/src/Speckle.Sdk/Pipelines/Send/SendPipeline.cs b/src/Speckle.Sdk/Pipelines/Send/SendPipeline.cs
index 55613c6d..a55cbaff 100644
--- a/src/Speckle.Sdk/Pipelines/Send/SendPipeline.cs
+++ b/src/Speckle.Sdk/Pipelines/Send/SendPipeline.cs
@@ -1,4 +1,5 @@
using Speckle.InterfaceGenerator;
+using Speckle.Sdk.Api.GraphQL.Models;
using Speckle.Sdk.Credentials;
using Speckle.Sdk.Helpers;
using Speckle.Sdk.Models;
@@ -10,6 +11,24 @@ namespace Speckle.Sdk.Pipelines.Send;
public sealed class SendPipelineFactory(IUploaderFactory uploaderFactory, IDiskStoreFactory diskStoreFactory)
: ISendPipelineFactory
{
+ public SendPipeline CreateInstance(
+ ModelIngestion ingestion,
+ Account account,
+ IProgress uploadProgress,
+ CancellationToken cancellationToken
+ )
+ {
+ var uploader = uploaderFactory.CreateInstance(
+ ingestion.projectId,
+ ingestion.id,
+ account,
+ uploadProgress,
+ cancellationToken
+ );
+ var diskStore = diskStoreFactory.CreateInstance(cancellationToken);
+ return new SendPipeline(uploader, diskStore);
+ }
+
public SendPipeline CreateInstance(
string projectId,
string ingestionId,
@@ -27,32 +46,30 @@ CancellationToken cancellationToken
public sealed class SendPipeline : IDisposable
{
private readonly Serializer _serializer = new();
- private readonly Uploader _uploader;
- private readonly DiskStore _diskStore;
+ internal Uploader Uploader { get; }
+ internal DiskStore DiskStore { get; }
internal SendPipeline(Uploader uploader, DiskStore diskStore)
{
- _uploader = uploader;
- _diskStore = diskStore;
+ Uploader = uploader;
+ DiskStore = diskStore;
}
public async Task Process(Base @base)
{
var results = _serializer.Serialize(@base).ToArray();
- var first = results.First();
- // .Reverse ensures the root commit object is written last.
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);
+ await DiskStore.PushAsync(item).ConfigureAwait(false);
}
- return first.Reference;
+ return results.First().Reference;
}
public async Task WaitForUpload()
{
- using DisposableFile tempFile = await _diskStore.CompleteAsync().ConfigureAwait(false);
+ using DisposableFile tempFile = await DiskStore.CompleteAsync().ConfigureAwait(false);
using Stream fileStreamUpload = new FileStream(
tempFile.FileInfo.FullName,
@@ -61,8 +78,8 @@ public async Task WaitForUpload()
FileShare.Read
);
- await _uploader.Send(fileStreamUpload).ConfigureAwait(false);
+ await Uploader.Send(fileStreamUpload).ConfigureAwait(false);
}
- public void Dispose() => _uploader.Dispose();
+ public void Dispose() => Uploader.Dispose();
}
diff --git a/src/Speckle.Sdk/Pipelines/Send/Serializer.cs b/src/Speckle.Sdk/Pipelines/Send/Serializer.cs
index ed78ce73..eb960c64 100644
--- a/src/Speckle.Sdk/Pipelines/Send/Serializer.cs
+++ b/src/Speckle.Sdk/Pipelines/Send/Serializer.cs
@@ -1,13 +1,11 @@
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;
@@ -17,6 +15,9 @@ namespace Speckle.Sdk.Pipelines.Send;
/// into serialized JSON structures along with associated metadata, closures, and references.
/// Any reference objects coming through are being "passed through" serialized - they do not get double encoded.
///
+///
+/// Unlike previous SDK serializers, this one uses rather than
+///
internal sealed class Serializer
{
private readonly record struct PropertyInfo(string Name, object? Value, bool IsDetachable);
@@ -31,10 +32,12 @@ public IEnumerable Serialize(Base root)
yield break;
}
- var detachedObjects = new List<(Id, Json, Dictionary, Base, string)>();
+ var detachedObjects = new List<(Id, Utf8Json, Dictionary, Base, string)>();
var rootClosures = new Dictionary();
- var (rootId, rootJson) = SerializeBase(root, false, rootClosures, detachedObjects);
+ var rootJson = new Utf8Json();
+ using Utf8JsonWriter writer = rootJson.Writer;
+ Id rootId = SerializeBase(root, rootJson, false, rootClosures, detachedObjects);
var rootReference = new ObjectReference
{
@@ -68,13 +71,13 @@ private IEnumerable ExtractProperties(Base baseObj)
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(true)?.Detachable ?? false;
+ var isDetachable = prop.IsDefined(typeof(DetachPropertyAttribute), true);
yield return new PropertyInfo(prop.Name, value, isDetachable);
}
@@ -96,107 +99,166 @@ private IEnumerable ExtractProperties(Base baseObj)
}
}
- private (Id, Json) SerializeBase(
+ private Id SerializeBase(
Base baseObj,
+ Utf8Json utf8Json,
bool forceDetach,
Dictionary closures,
- List<(Id, Json, Dictionary, Base, string)> detachedObjects
+ List<(Id, Utf8Json, Dictionary, Base, string)> detachedObjects
)
{
var childClosures = new Dictionary();
+ var jsonWriter = utf8Json.Writer;
- var sb = Pools.StringBuilders.Get();
- try
- {
- using var stringWriter = new StringWriter(sb);
- using var jsonWriter = new JsonTextWriter(stringWriter);
- using var idWriter = new SerializerIdWriter(jsonWriter);
+ jsonWriter.Flush();
+ //The "start" of this inner object
+ int byteOffset = utf8Json.WrittenCount;
- idWriter.WriteStartObject();
+ jsonWriter.WriteStartObject();
- foreach (var prop in ExtractProperties(baseObj))
- {
- idWriter.WritePropertyName(prop.Name);
- SerializeValue(prop.Value, idWriter, prop.IsDetachable, childClosures, detachedObjects);
- }
+ foreach (var prop in ExtractProperties(baseObj))
+ {
+ jsonWriter.WritePropertyName(prop.Name);
+ SerializeValue(prop.Value, utf8Json, prop.IsDetachable, childClosures, detachedObjects);
+ }
- var (jsonForId, finalWriter) = idWriter.FinishIdWriter();
- var id = IdGenerator.ComputeId(jsonForId);
+ // We want to hash the json string now to calculate the id
+ // We don't want to allocate a separate buffer for it, as this wouldn't be memory efficient
+ jsonWriter.Flush();
- finalWriter.WritePropertyName("id");
- finalWriter.WriteValue(id.Value);
+#if NET6_0_OR_GREATER
+ string id = IdGenerator.ComputeId(utf8Json.WrittenSpan[byteOffset..]);
+#else
+ byte[] buffer = utf8Json.GetInternalBuffer();
+ string id = IdGenerator.ComputeId(buffer, byteOffset, utf8Json.WrittenCount - byteOffset);
+#endif
+ jsonWriter.WriteString("id", id);
- baseObj.id = id.Value;
+ baseObj.id = id;
- if ((forceDetach || childClosures.Count > 0) && childClosures.Count > 0)
+ if ((forceDetach || childClosures.Count > 0) && childClosures.Count > 0)
+ {
+ jsonWriter.WritePropertyName("__closure");
+ jsonWriter.WriteStartObject();
+ foreach (var kvp in childClosures)
{
- 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;
- }
+ jsonWriter.WriteNumber(kvp.Key, kvp.Value);
}
+ jsonWriter.WriteEndObject();
- finalWriter.WriteEndObject();
- finalWriter.Flush();
-
- var json = new Json(stringWriter.ToString());
- return (id, json);
- }
- finally
- {
- Pools.StringBuilders.Return(sb);
+ 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);
}
private void SerializeValue(
object? value,
- JsonWriter writer,
+ Utf8Json json,
bool isDetachable,
Dictionary closures,
- List<(Id, Json, Dictionary, Base, string)> detachedObjects
+ List<(Id, Utf8Json, Dictionary, Base, string)> detachedObjects
)
{
+ var writer = json.Writer;
switch (value)
{
- case Enum:
- writer.WriteValue((int)value);
+ case null:
+ writer.WriteNullValue();
+ return;
+ 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:
+ switch (f)
+ {
+ case float.PositiveInfinity:
+ writer.WriteStringValue("Infinity");
+ break;
+ case float.NegativeInfinity:
+ writer.WriteStringValue("-Infinity");
+ break;
+ case float.NaN:
+ writer.WriteStringValue("NaN");
+ break;
+ default:
+ writer.WriteNumberValue(f);
+ break;
+ }
+ return;
+ case double f:
+ switch (f)
+ {
+ case double.PositiveInfinity:
+ writer.WriteStringValue("Infinity");
+ break;
+ case double.NegativeInfinity:
+ writer.WriteStringValue("-Infinity");
+ break;
+ case double.NaN:
+ writer.WriteStringValue("NaN");
+ break;
+ default:
+ writer.WriteNumberValue(f);
+ break;
+ }
+ return;
+ case decimal d:
+ writer.WriteNumberValue(d);
return;
case Guid g:
- writer.WriteValue(g.ToString());
+ writer.WriteStringValue(g.ToString("D", CultureInfo.InvariantCulture));
return;
- case Color c:
- writer.WriteValue(c.ToArgb());
+ case Enum:
+ writer.WriteNumberValue((int)value);
return;
- case DateTime dt:
- writer.WriteValue(dt.ToString("o", CultureInfo.InvariantCulture));
+ case Color c:
+ 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 +266,8 @@ private void SerializeValue(
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
@@ -231,15 +291,16 @@ private void SerializeValue(
if (isDetachable)
{
var childClosures = new Dictionary();
- var (childId, childJson) = SerializeBase(baseObj, true, childClosures, detachedObjects);
+
+ var childJson = new Utf8Json();
+ using var innerWriter = childJson.Writer;
+ var childId = SerializeBase(baseObj, childJson, true, childClosures, detachedObjects);
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;
@@ -254,9 +315,7 @@ private void SerializeValue(
else
{
var inlineClosures = new Dictionary();
- var (_, inlineJson) = SerializeBase(baseObj, false, inlineClosures, detachedObjects);
-
- writer.WriteRawValue(inlineJson.Value);
+ _ = SerializeBase(baseObj, json, false, inlineClosures, detachedObjects);
foreach (var kvp in inlineClosures)
{
@@ -278,7 +337,7 @@ private void SerializeValue(
}
writer.WritePropertyName(key);
- SerializeValue(kvp.Value, writer, false, closures, detachedObjects);
+ SerializeValue(kvp.Value, json, false, closures, detachedObjects);
}
writer.WriteEndObject();
return;
@@ -288,64 +347,54 @@ private void SerializeValue(
writer.WriteStartArray();
foreach (var item in collection)
{
- SerializeValue(item, writer, isDetachable, closures, detachedObjects);
+ SerializeValue(item, json, isDetachable, closures, detachedObjects);
}
writer.WriteEndArray();
return;
}
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 Utf8Json();
+ using var jsonWriter = refJson.Writer;
- jsonWriter.WriteStartObject();
- jsonWriter.WritePropertyName("speckle_type");
- jsonWriter.WriteValue("reference");
- jsonWriter.WritePropertyName("referencedId");
- jsonWriter.WriteValue(existingRef.referencedId);
- jsonWriter.WritePropertyName("__closure");
+ 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();
- foreach (var kvp in existingRef.closure)
- {
- jsonWriter.WritePropertyName(kvp.Key);
- jsonWriter.WriteValue(kvp.Value);
- }
- jsonWriter.WriteEndObject();
- }
- else
+ if (existingRef.closure != null && existingRef.closure.Count > 0)
+ {
+ jsonWriter.WriteStartObject();
+ foreach (var kvp in existingRef.closure)
{
- jsonWriter.WriteNull();
+ jsonWriter.WritePropertyName(kvp.Key);
+ jsonWriter.WriteNumberValue(kvp.Value);
}
-
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
+ );
}
}
diff --git a/src/Speckle.Sdk/Pipelines/Send/UploaderDTOs.cs b/src/Speckle.Sdk/Pipelines/Send/UploaderDTOs.cs
index 11df1420..5e5bd023 100644
--- a/src/Speckle.Sdk/Pipelines/Send/UploaderDTOs.cs
+++ b/src/Speckle.Sdk/Pipelines/Send/UploaderDTOs.cs
@@ -1,10 +1,12 @@
using Speckle.Newtonsoft.Json;
using Speckle.Sdk.Models;
-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, Utf8Json Json, string SpeckleType, ObjectReference Reference) : IDisposable
+{
+ public void Dispose() => Json.Dispose();
+}
internal record PresignedUploadResponse
{
diff --git a/src/Speckle.Sdk/Polyfills/ArrayBufferWriterPolyfill.cs b/src/Speckle.Sdk/Polyfills/ArrayBufferWriterPolyfill.cs
new file mode 100644
index 00000000..0ea8aac7
--- /dev/null
+++ b/src/Speckle.Sdk/Polyfills/ArrayBufferWriterPolyfill.cs
@@ -0,0 +1,255 @@
+#if !NET5_0_OR_GREATER
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// ReSharper disable InconsistentNaming
+#pragma warning disable
+
+using System.Diagnostics;
+
+namespace System.Buffers
+{
+ ///
+ /// Represents a heap-based, array-backed output sink into which data can be written.
+ ///
+ public sealed class ArrayBufferWriter : IBufferWriter
+ {
+ // Copy of Array.MaxLength.
+ // Used by projects targeting .NET Framework.
+ private const int ArrayMaxLength = 0x7FFFFFC7;
+
+ private const int DefaultInitialBufferSize = 256;
+
+ private T[] _buffer;
+ private int _index;
+
+ ///
+ /// Creates an instance of an , in which data can be written to,
+ /// with the default initial capacity.
+ ///
+ public ArrayBufferWriter()
+ {
+ _buffer = Array.Empty();
+ _index = 0;
+ }
+
+ ///
+ /// Creates an instance of an , in which data can be written to,
+ /// with an initial capacity specified.
+ ///
+ /// The minimum capacity with which to initialize the underlying buffer.
+ ///
+ /// Thrown when is not positive (i.e. less than or equal to 0).
+ ///
+ public ArrayBufferWriter(int initialCapacity)
+ {
+ if (initialCapacity <= 0)
+ throw new ArgumentException(null, nameof(initialCapacity));
+
+ _buffer = new T[initialCapacity];
+ _index = 0;
+ }
+
+ ///
+ /// Returns the data written to the underlying buffer so far, as a .
+ ///
+ public ReadOnlyMemory WrittenMemory => _buffer.AsMemory(0, _index);
+
+ public T[] InternalBuffer => _buffer;
+
+ ///
+ /// Returns the data written to the underlying buffer so far, as a .
+ ///
+ public ReadOnlySpan WrittenSpan => _buffer.AsSpan(0, _index);
+
+ ///
+ /// Returns the amount of data written to the underlying buffer so far.
+ ///
+ public int WrittenCount => _index;
+
+ ///
+ /// Returns the total amount of space within the underlying buffer.
+ ///
+ public int Capacity => _buffer.Length;
+
+ ///
+ /// Returns the amount of space available that can still be written into without forcing the underlying buffer to grow.
+ ///
+ public int FreeCapacity => _buffer.Length - _index;
+
+ ///
+ /// Clears the data written to the underlying buffer.
+ ///
+ ///
+ ///
+ /// You must reset or clear the before trying to re-use it.
+ ///
+ ///
+ /// The method is faster since it only sets to zero the writer's index
+ /// while the method additionally zeroes the content of the underlying buffer.
+ ///
+ ///
+ ///
+ public void Clear()
+ {
+ Debug.Assert(_buffer.Length >= _index);
+ _buffer.AsSpan(0, _index).Clear();
+ _index = 0;
+ }
+
+ ///
+ /// Resets the data written to the underlying buffer without zeroing its content.
+ ///
+ ///
+ ///
+ /// You must reset or clear the before trying to re-use it.
+ ///
+ ///
+ /// If you reset the writer using the method, the underlying buffer will not be cleared.
+ ///
+ ///
+ ///
+ public void ResetWrittenCount() => _index = 0;
+
+ ///
+ /// Notifies that amount of data was written to the output /
+ ///
+ ///
+ /// Thrown when is negative.
+ ///
+ ///
+ /// Thrown when attempting to advance past the end of the underlying buffer.
+ ///
+ ///
+ /// You must request a new buffer after calling Advance to continue writing more data and cannot write to a previously acquired buffer.
+ ///
+ public void Advance(int count)
+ {
+ if (count < 0)
+ throw new ArgumentException(null, nameof(count));
+
+ if (_index > _buffer.Length - count)
+ ThrowInvalidOperationException_AdvancedTooFar(_buffer.Length);
+
+ _index += count;
+ }
+
+ ///
+ /// Returns a to write to that is at least the requested length (specified by ).
+ /// If no is provided (or it's equal to 0), some non-empty buffer is returned.
+ ///
+ ///
+ /// Thrown when is negative.
+ ///
+ ///
+ ///
+ /// This will never return an empty .
+ ///
+ ///
+ /// There is no guarantee that successive calls will return the same buffer or the same-sized buffer.
+ ///
+ ///
+ /// You must request a new buffer after calling Advance to continue writing more data and cannot write to a previously acquired buffer.
+ ///
+ ///
+ /// If you reset the writer using the method, this method may return a non-cleared .
+ ///
+ ///
+ /// If you clear the writer using the method, this method will return a with its content zeroed.
+ ///
+ ///
+ public Memory GetMemory(int sizeHint = 0)
+ {
+ CheckAndResizeBuffer(sizeHint);
+ Debug.Assert(_buffer.Length > _index);
+ return _buffer.AsMemory(_index);
+ }
+
+ ///
+ /// Returns a to write to that is at least the requested length (specified by ).
+ /// If no is provided (or it's equal to 0), some non-empty buffer is returned.
+ ///
+ ///
+ /// Thrown when is negative.
+ ///
+ ///
+ ///
+ /// This will never return an empty .
+ ///
+ ///
+ /// There is no guarantee that successive calls will return the same buffer or the same-sized buffer.
+ ///
+ ///
+ /// You must request a new buffer after calling Advance to continue writing more data and cannot write to a previously acquired buffer.
+ ///
+ ///
+ /// If you reset the writer using the method, this method may return a non-cleared .
+ ///
+ ///
+ /// If you clear the writer using the method, this method will return a with its content zeroed.
+ ///
+ ///
+ public Span GetSpan(int sizeHint = 0)
+ {
+ CheckAndResizeBuffer(sizeHint);
+ Debug.Assert(_buffer.Length > _index);
+ return _buffer.AsSpan(_index);
+ }
+
+ public void CheckAndResizeBuffer(int sizeHint)
+ {
+ if (sizeHint < 0)
+ throw new ArgumentException(nameof(sizeHint));
+
+ if (sizeHint == 0)
+ {
+ sizeHint = 1;
+ }
+
+ if (sizeHint > FreeCapacity)
+ {
+ int currentLength = _buffer.Length;
+
+ // Attempt to grow by the larger of the sizeHint and double the current size.
+ int growBy = Math.Max(sizeHint, currentLength);
+
+ if (currentLength == 0)
+ {
+ growBy = Math.Max(growBy, DefaultInitialBufferSize);
+ }
+
+ int newSize = currentLength + growBy;
+
+ if ((uint)newSize > int.MaxValue)
+ {
+ // Attempt to grow to ArrayMaxLength.
+ uint needed = (uint)(currentLength - FreeCapacity + sizeHint);
+ Debug.Assert(needed > currentLength);
+
+ if (needed > ArrayMaxLength)
+ {
+ ThrowOutOfMemoryException(needed);
+ }
+
+ newSize = ArrayMaxLength;
+ }
+
+ Array.Resize(ref _buffer, newSize);
+ }
+
+ Debug.Assert(FreeCapacity > 0 && FreeCapacity >= sizeHint);
+ }
+
+ private static void ThrowInvalidOperationException_AdvancedTooFar(int capacity)
+ {
+ throw new InvalidOperationException(
+ $"Cannot advance past the end of the buffer, which has a size of {capacity}."
+ );
+ }
+
+ private static void ThrowOutOfMemoryException(uint capacity)
+ {
+ throw new OutOfMemoryException($"The buffer cannot be grown beyond the maximum size of {capacity}.");
+ }
+ }
+}
+#endif
diff --git a/src/Speckle.Sdk/Serialisation/IdGenerator.cs b/src/Speckle.Sdk/Serialisation/IdGenerator.cs
index 0d33482e..4d34bb45 100644
--- a/src/Speckle.Sdk/Serialisation/IdGenerator.cs
+++ b/src/Speckle.Sdk/Serialisation/IdGenerator.cs
@@ -7,6 +7,7 @@ namespace Speckle.Sdk.Serialisation;
public static class IdGenerator
{
[Pure]
+ //Obsolete (serializer v2)
public static Id ComputeId(Json serialized)
{
#if NET6_0_OR_GREATER
diff --git a/src/Speckle.Sdk/Speckle.Sdk.csproj b/src/Speckle.Sdk/Speckle.Sdk.csproj
index 3b84c8dd..193699f6 100644
--- a/src/Speckle.Sdk/Speckle.Sdk.csproj
+++ b/src/Speckle.Sdk/Speckle.Sdk.csproj
@@ -26,13 +26,13 @@
-
+
-
+
@@ -41,12 +41,18 @@
-
+
+
+
+
+
+
+
diff --git a/src/Speckle.Sdk/packages.lock.json b/src/Speckle.Sdk/packages.lock.json
index 9762e1b9..58fb0eda 100644
--- a/src/Speckle.Sdk/packages.lock.json
+++ b/src/Speckle.Sdk/packages.lock.json
@@ -50,6 +50,12 @@
"Microsoft.Extensions.Options": "2.2.0"
}
},
+ "Microsoft.Extensions.ObjectPool": {
+ "type": "Direct",
+ "requested": "[6.0.0, )",
+ "resolved": "6.0.0",
+ "contentHash": "7hR9FU0JJHOCLmn/Ary31pLLAhlzoMptBKs5CJmNUzD87dXjl+/NqVkyCTl6cT2JAfTK0G39HpvCOv1fhsX3BQ=="
+ },
"Microsoft.SourceLink.GitHub": {
"type": "Direct",
"requested": "[8.0.0, )",
@@ -93,6 +99,21 @@
"resolved": "13.0.2",
"contentHash": "g1BejUZwax5PRfL6xHgLEK23sqHWOgOj9hE7RvfRRlN00AGt8GnPYt8HedSK7UB3HiRW8zCA9Pn0iiYxCK24BA=="
},
+ "System.Text.Json": {
+ "type": "Direct",
+ "requested": "[5.0.2, )",
+ "resolved": "5.0.2",
+ "contentHash": "I47dVIGiV6SfAyppphxqupertT/5oZkYLDCX6vC3HpOI4ZLjyoKAreUoem2ie6G0RbRuFrlqz/PcTQjfb2DOfQ==",
+ "dependencies": {
+ "Microsoft.Bcl.AsyncInterfaces": "5.0.0",
+ "System.Buffers": "4.5.1",
+ "System.Memory": "4.5.4",
+ "System.Numerics.Vectors": "4.5.0",
+ "System.Runtime.CompilerServices.Unsafe": "5.0.0",
+ "System.Text.Encodings.Web": "5.0.1",
+ "System.Threading.Tasks.Extensions": "4.5.4"
+ }
+ },
"GraphQL.Client.Abstractions": {
"type": "Transitive",
"resolved": "6.0.0",
@@ -222,8 +243,8 @@
},
"System.Buffers": {
"type": "Transitive",
- "resolved": "4.4.0",
- "contentHash": "AwarXzzoDwX6BgrhjoJsk6tUezZEozOT5Y9QKF94Gl4JK91I4PIIBkBco9068Y9/Dra8Dkbie99kXB8+1BaYKw=="
+ "resolved": "4.5.1",
+ "contentHash": "Rw7ijyl1qqRS0YQD/WycNst8hUUMgrMH4FCn1nNm27M4VxchZ1js3fVjQaANHO5f3sN4isvP4a+Met9Y4YomAg=="
},
"System.ComponentModel.Annotations": {
"type": "Transitive",
@@ -232,18 +253,18 @@
},
"System.Memory": {
"type": "Transitive",
- "resolved": "4.5.3",
- "contentHash": "3oDzvc/zzetpTKWMShs1AADwZjQ/36HnsufHRPcOjyRAAMLDlu2iD33MBI2opxnezcVUtXyqDXXjoFMOU9c7SA==",
+ "resolved": "4.5.4",
+ "contentHash": "1MbJTHS1lZ4bS4FmsJjnuGJOu88ZzTT2rLvrhW7Ygic+pC0NWA+3hgAen0HRdsocuQXCkUTdFn9yHJJhsijDXw==",
"dependencies": {
- "System.Buffers": "4.4.0",
+ "System.Buffers": "4.5.1",
"System.Numerics.Vectors": "4.4.0",
- "System.Runtime.CompilerServices.Unsafe": "4.5.2"
+ "System.Runtime.CompilerServices.Unsafe": "4.5.3"
}
},
"System.Numerics.Vectors": {
"type": "Transitive",
- "resolved": "4.4.0",
- "contentHash": "UiLzLW+Lw6HLed1Hcg+8jSRttrbuXv7DANVj0DkL9g6EnnzbL75EB7EWsw5uRbhxd/4YdG8li5XizGWepmG3PQ=="
+ "resolved": "4.5.0",
+ "contentHash": "QQTlPTl06J/iiDbJCiepZ4H//BVraReU4O4EoRw1U02H5TLUIT7xn3GnDp9AXPSlJUDyFs4uWjWafNX6WrAojQ=="
},
"System.Reactive": {
"type": "Transitive",
@@ -256,14 +277,23 @@
},
"System.Runtime.CompilerServices.Unsafe": {
"type": "Transitive",
- "resolved": "4.5.3",
- "contentHash": "3TIsJhD1EiiT0w2CcDMN/iSSwnNnsrnbzeVHSKkaEgV85txMprmuO+Yq2AdSbeVGcg28pdNDTPK87tJhX7VFHw=="
+ "resolved": "5.0.0",
+ "contentHash": "ZD9TMpsmYJLrxbbmdvhwt9YEgG5WntEnZ/d1eH8JBX9LBp+Ju8BSBhUGbZMNVHHomWo2KVImJhTDl2hIgw/6MA=="
},
"System.Runtime.InteropServices.WindowsRuntime": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "J4GUi3xZQLUBasNwZnjrffN8i5wpHrBtZoLG+OhRyGo/+YunMRWWtwoMDlUAIdmX0uRfpHIBDSV6zyr3yf00TA=="
},
+ "System.Text.Encodings.Web": {
+ "type": "Transitive",
+ "resolved": "5.0.1",
+ "contentHash": "KmJ+CJXizDofbq6mpqDoRRLcxgOd2z9X3XoFNULSbvbqVRZkFX3istvr+MUjL6Zw1RT+RNdoI4GYidIINtgvqQ==",
+ "dependencies": {
+ "System.Buffers": "4.5.1",
+ "System.Memory": "4.5.4"
+ }
+ },
"System.Threading.Tasks.Extensions": {
"type": "Transitive",
"resolved": "4.5.4",
@@ -311,15 +341,6 @@
"SQLitePCLRaw.core": "2.1.11"
}
},
- "Microsoft.Extensions.DependencyInjection": {
- "type": "Direct",
- "requested": "[10.0.0, )",
- "resolved": "10.0.0",
- "contentHash": "f0RBabswJq+gRu5a+hWIobrLWiUYPKMhCD9WO3sYBAdSy3FFH14LMvLVFZc2kPSCimBLxSuitUhsd6tb0TAY6A==",
- "dependencies": {
- "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.0"
- }
- },
"Microsoft.Extensions.Logging": {
"type": "Direct",
"requested": "[10.0.0, )",
@@ -331,6 +352,12 @@
"Microsoft.Extensions.Options": "10.0.0"
}
},
+ "Microsoft.Extensions.ObjectPool": {
+ "type": "Direct",
+ "requested": "[10.0.0, )",
+ "resolved": "10.0.0",
+ "contentHash": "bpeCq0IYmVLACyEUMzFIOQX+zZUElG1t+nu1lSxthe7B+1oNYking7b91305+jNB6iwojp9fqTY9O+Nh7ULQxg=="
+ },
"Microsoft.SourceLink.GitHub": {
"type": "Direct",
"requested": "[8.0.0, )",
@@ -465,6 +492,15 @@
},
"speckle.sdk.dependencies": {
"type": "Project"
+ },
+ "Microsoft.Extensions.DependencyInjection": {
+ "type": "CentralTransitive",
+ "requested": "[10.0.6, )",
+ "resolved": "10.0.0",
+ "contentHash": "f0RBabswJq+gRu5a+hWIobrLWiUYPKMhCD9WO3sYBAdSy3FFH14LMvLVFZc2kPSCimBLxSuitUhsd6tb0TAY6A==",
+ "dependencies": {
+ "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.0"
+ }
}
},
"net8.0": {
@@ -489,15 +525,6 @@
"SQLitePCLRaw.bundle_e_sqlite3": "2.1.4"
}
},
- "Microsoft.Extensions.DependencyInjection": {
- "type": "Direct",
- "requested": "[8.0.0, )",
- "resolved": "8.0.0",
- "contentHash": "V8S3bsm50ig6JSyrbcJJ8bW2b9QLGouz+G1miK3UTaOWmMtFwNNNzUf4AleyDWUmTrWMLNnFSLEQtxmxgNQnNQ==",
- "dependencies": {
- "Microsoft.Extensions.DependencyInjection.Abstractions": "8.0.0"
- }
- },
"Microsoft.Extensions.Logging": {
"type": "Direct",
"requested": "[8.0.0, )",
@@ -509,6 +536,12 @@
"Microsoft.Extensions.Options": "8.0.0"
}
},
+ "Microsoft.Extensions.ObjectPool": {
+ "type": "Direct",
+ "requested": "[8.0.0, )",
+ "resolved": "8.0.0",
+ "contentHash": "4pm+XgxSukskwjzDDfSjG4KNUIOdFF2VaqZZDtTzoyQMOVSnlV6ZM8a9aVu5dg9LVZTB//utzSc8fOi0b0Mb2Q=="
+ },
"Microsoft.SourceLink.GitHub": {
"type": "Direct",
"requested": "[8.0.0, )",
@@ -643,6 +676,15 @@
},
"speckle.sdk.dependencies": {
"type": "Project"
+ },
+ "Microsoft.Extensions.DependencyInjection": {
+ "type": "CentralTransitive",
+ "requested": "[10.0.6, )",
+ "resolved": "8.0.0",
+ "contentHash": "V8S3bsm50ig6JSyrbcJJ8bW2b9QLGouz+G1miK3UTaOWmMtFwNNNzUf4AleyDWUmTrWMLNnFSLEQtxmxgNQnNQ==",
+ "dependencies": {
+ "Microsoft.Extensions.DependencyInjection.Abstractions": "8.0.0"
+ }
}
}
}
diff --git a/tests/Speckle.Automate.Sdk.Integration/packages.lock.json b/tests/Speckle.Automate.Sdk.Integration/packages.lock.json
index ea487e10..9b359310 100644
--- a/tests/Speckle.Automate.Sdk.Integration/packages.lock.json
+++ b/tests/Speckle.Automate.Sdk.Integration/packages.lock.json
@@ -293,8 +293,8 @@
"dependencies": {
"GraphQL.Client": "[6.1.0, )",
"Microsoft.Data.Sqlite": "[10.0.0, )",
- "Microsoft.Extensions.DependencyInjection": "[10.0.0, )",
"Microsoft.Extensions.Logging": "[10.0.0, )",
+ "Microsoft.Extensions.ObjectPool": "[10.0.0, )",
"Speckle.DoubleNumerics": "[4.1.0, )",
"Speckle.Newtonsoft.Json": "[13.0.2, )",
"Speckle.Sdk.Dependencies": "[1.0.0, )"
@@ -367,6 +367,12 @@
"Microsoft.Extensions.Options": "10.0.0"
}
},
+ "Microsoft.Extensions.ObjectPool": {
+ "type": "CentralTransitive",
+ "requested": "[9.0.4, )",
+ "resolved": "10.0.0",
+ "contentHash": "bpeCq0IYmVLACyEUMzFIOQX+zZUElG1t+nu1lSxthe7B+1oNYking7b91305+jNB6iwojp9fqTY9O+Nh7ULQxg=="
+ },
"Moq": {
"type": "CentralTransitive",
"requested": "[4.20.72, )",
diff --git a/tests/Speckle.Objects.Tests.Unit/packages.lock.json b/tests/Speckle.Objects.Tests.Unit/packages.lock.json
index 26da497d..ebb5a57b 100644
--- a/tests/Speckle.Objects.Tests.Unit/packages.lock.json
+++ b/tests/Speckle.Objects.Tests.Unit/packages.lock.json
@@ -271,8 +271,8 @@
"dependencies": {
"GraphQL.Client": "[6.1.0, )",
"Microsoft.Data.Sqlite": "[10.0.0, )",
- "Microsoft.Extensions.DependencyInjection": "[10.0.0, )",
"Microsoft.Extensions.Logging": "[10.0.0, )",
+ "Microsoft.Extensions.ObjectPool": "[10.0.0, )",
"Speckle.DoubleNumerics": "[4.1.0, )",
"Speckle.Newtonsoft.Json": "[13.0.2, )",
"Speckle.Sdk.Dependencies": "[1.0.0, )"
@@ -332,6 +332,12 @@
"Microsoft.Extensions.Options": "10.0.0"
}
},
+ "Microsoft.Extensions.ObjectPool": {
+ "type": "CentralTransitive",
+ "requested": "[9.0.4, )",
+ "resolved": "10.0.0",
+ "contentHash": "bpeCq0IYmVLACyEUMzFIOQX+zZUElG1t+nu1lSxthe7B+1oNYking7b91305+jNB6iwojp9fqTY9O+Nh7ULQxg=="
+ },
"Moq": {
"type": "CentralTransitive",
"requested": "[4.20.72, )",
@@ -648,8 +654,8 @@
"dependencies": {
"GraphQL.Client": "[6.0.0, )",
"Microsoft.Data.Sqlite": "[7.0.5, )",
- "Microsoft.Extensions.DependencyInjection": "[8.0.0, )",
"Microsoft.Extensions.Logging": "[8.0.0, )",
+ "Microsoft.Extensions.ObjectPool": "[8.0.0, )",
"Speckle.DoubleNumerics": "[4.1.0, )",
"Speckle.Newtonsoft.Json": "[13.0.2, )",
"Speckle.Sdk.Dependencies": "[1.0.0, )"
@@ -708,6 +714,12 @@
"Microsoft.Extensions.Options": "8.0.0"
}
},
+ "Microsoft.Extensions.ObjectPool": {
+ "type": "CentralTransitive",
+ "requested": "[9.0.4, )",
+ "resolved": "8.0.0",
+ "contentHash": "4pm+XgxSukskwjzDDfSjG4KNUIOdFF2VaqZZDtTzoyQMOVSnlV6ZM8a9aVu5dg9LVZTB//utzSc8fOi0b0Mb2Q=="
+ },
"Moq": {
"type": "CentralTransitive",
"requested": "[4.20.72, )",
diff --git a/tests/Speckle.Sdk.Serialization.Testing/Speckle.Sdk.Serialization.Testing.csproj b/tests/Speckle.Sdk.Serialization.Testing/Speckle.Sdk.Serialization.Testing.csproj
index b3e8d99c..980f353c 100644
--- a/tests/Speckle.Sdk.Serialization.Testing/Speckle.Sdk.Serialization.Testing.csproj
+++ b/tests/Speckle.Sdk.Serialization.Testing/Speckle.Sdk.Serialization.Testing.csproj
@@ -1,7 +1,7 @@
Exe
- net8.0
+ net10.0
enable
enable
true
diff --git a/tests/Speckle.Sdk.Serialization.Testing/packages.lock.json b/tests/Speckle.Sdk.Serialization.Testing/packages.lock.json
index 01de9cb8..11a6ae77 100644
--- a/tests/Speckle.Sdk.Serialization.Testing/packages.lock.json
+++ b/tests/Speckle.Sdk.Serialization.Testing/packages.lock.json
@@ -1,7 +1,7 @@
{
"version": 2,
"dependencies": {
- "net8.0": {
+ "net10.0": {
"Microsoft.SourceLink.GitHub": {
"type": "Direct",
"requested": "[8.0.0, )",
@@ -26,8 +26,8 @@
},
"BenchmarkDotNet.Annotations": {
"type": "Transitive",
- "resolved": "0.14.0",
- "contentHash": "CUDCg6bgHrDzhjnA+IOBl5gAo8Y5hZ2YSs7MBXrYMlMKpBZqrD5ez0537uDveOkcf+YWAoK+S4sMcuWPbIz8bw=="
+ "resolved": "0.15.8",
+ "contentHash": "hfucY0ycAsB0SsoaZcaAp9oq5wlWBJcylvEJb9pmvdYUx6PD6S4mDiYnZWjdjAlLhIpe/xtGCwzORfzAzPqvzA=="
},
"CommandLineParser": {
"type": "Transitive",
@@ -41,29 +41,29 @@
},
"GraphQL.Client.Abstractions": {
"type": "Transitive",
- "resolved": "6.0.0",
- "contentHash": "h7uzWFORHZ+CCjwr/ThAyXMr0DPpzEANDa4Uo54wqCQ+j7qUKwqYTgOrb1W40sqbvNaZm9v/X7It31SUw0maHA==",
+ "resolved": "6.1.0",
+ "contentHash": "Za31wjKLEeROZYJmp0Lmj/TLQ1Yw6x6QM0JHABcuyMC3OSopr34ufayrtdxtbL1a3129FTVFKOFC0hcooSQoJQ==",
"dependencies": {
- "GraphQL.Primitives": "6.0.0"
+ "GraphQL.Primitives": "6.1.0"
}
},
"GraphQL.Client.Abstractions.Websocket": {
"type": "Transitive",
- "resolved": "6.0.0",
- "contentHash": "Nr9bPf8gIOvLuXpqEpqr9z9jslYFJOvd0feHth3/kPqeR3uMbjF5pjiwh4jxyMcxHdr8Pb6QiXkV3hsSyt0v7A==",
+ "resolved": "6.1.0",
+ "contentHash": "PjdG3q4MzPsa5NiBOBhuIRMRTo59der5bFmX2r1gSS3RIjytwpooxF2RffFCBh16sqbwuH1/dllDcNG+EJt1qA==",
"dependencies": {
- "GraphQL.Client.Abstractions": "6.0.0"
+ "GraphQL.Client.Abstractions": "6.1.0"
}
},
"GraphQL.Primitives": {
"type": "Transitive",
- "resolved": "6.0.0",
- "contentHash": "yg72rrYDapfsIUrul7aF6wwNnTJBOFvuA9VdDTQpPa8AlAriHbufeXYLBcodKjfUdkCnaiggX1U/nEP08Zb5GA=="
+ "resolved": "6.1.0",
+ "contentHash": "L8yQ70Wd9p8hMJvnmpgyZfr2R6Q7S0/lPyEBI1tacJa5XzsoJSVtHdmfsMaHyufwk03hlUsBXgNerAs66kxHdA=="
},
"Iced": {
"type": "Transitive",
- "resolved": "1.17.0",
- "contentHash": "8x+HCVTl/HHTGpscH3vMBhV8sknN/muZFw9s3TsI8SA6+c43cOTCi2+jE4KsU8pNLbJ++iF2ZFcpcXHXtDglnw=="
+ "resolved": "1.21.0",
+ "contentHash": "dv5+81Q1TBQvVMSOOOmRcjJmvWcX3BZPZsIq31+RLc5cNft0IHAyNlkdb7ZarOWG913PyBoFDsDXoCIlKmLclg=="
},
"Microsoft.Build.Tasks.Git": {
"type": "Transitive",
@@ -72,65 +72,57 @@
},
"Microsoft.CodeAnalysis.Analyzers": {
"type": "Transitive",
- "resolved": "3.3.3",
- "contentHash": "j/rOZtLMVJjrfLRlAMckJLPW/1rze9MT1yfWqSIbUPGRu1m1P0fuo9PmqapwsmePfGB5PJrudQLvmUOAMF0DqQ=="
+ "resolved": "3.11.0",
+ "contentHash": "v/EW3UE8/lbEYHoC2Qq7AR/DnmvpgdtAMndfQNmpuIMx/Mto8L5JnuCfdBYtgvalQOtfNCnxFejxuRrryvUTsg=="
},
"Microsoft.CodeAnalysis.Common": {
"type": "Transitive",
- "resolved": "4.1.0",
- "contentHash": "bNzTyxP3iD5FPFHfVDl15Y6/wSoI7e3MeV0lOaj9igbIKTjgrmuw6LoVJ06jUNFA7+KaDC/OIsStWl/FQJz6sQ==",
+ "resolved": "4.14.0",
+ "contentHash": "PC3tuwZYnC+idaPuoC/AZpEdwrtX7qFpmnrfQkgobGIWiYmGi5MCRtl5mx6QrfMGQpK78X2lfIEoZDLg/qnuHg==",
"dependencies": {
- "Microsoft.CodeAnalysis.Analyzers": "3.3.3",
- "System.Collections.Immutable": "5.0.0",
- "System.Memory": "4.5.4",
- "System.Reflection.Metadata": "5.0.0",
- "System.Runtime.CompilerServices.Unsafe": "5.0.0",
- "System.Text.Encoding.CodePages": "4.5.1",
- "System.Threading.Tasks.Extensions": "4.5.4"
+ "Microsoft.CodeAnalysis.Analyzers": "3.11.0"
}
},
"Microsoft.CodeAnalysis.CSharp": {
"type": "Transitive",
- "resolved": "4.1.0",
- "contentHash": "sbu6kDGzo9bfQxuqWpeEE7I9P30bSuZEnpDz9/qz20OU6pm79Z63+/BsAzO2e/R/Q97kBrpj647wokZnEVr97w==",
+ "resolved": "4.14.0",
+ "contentHash": "568a6wcTivauIhbeWcCwfWwIn7UV7MeHEBvFB2uzGIpM2OhJ4eM/FZ8KS0yhPoNxnSpjGzz7x7CIjTxhslojQA==",
"dependencies": {
- "Microsoft.CodeAnalysis.Common": "[4.1.0]"
+ "Microsoft.CodeAnalysis.Analyzers": "3.11.0",
+ "Microsoft.CodeAnalysis.Common": "[4.14.0]"
}
},
"Microsoft.Data.Sqlite.Core": {
"type": "Transitive",
- "resolved": "7.0.5",
- "contentHash": "FTerRmQPqHrCrnoUzhBu+E+1DNGwyrAMLqHkAqOOOu5pGfyMOj8qQUBxI/gDtWtG11p49UxSfWmBzRNlwZqfUg==",
+ "resolved": "10.0.0",
+ "contentHash": "wPKG/Ym6tSMCo06UOZXzVfeFGzawnOZrTba/R3PfK+RhNuNELZ9I7nFns4WGTtv2kKlrlmmErgJ+kgTXHaNdHg==",
"dependencies": {
- "SQLitePCLRaw.core": "2.1.4"
+ "SQLitePCLRaw.core": "2.1.11"
}
},
"Microsoft.Diagnostics.NETCore.Client": {
"type": "Transitive",
- "resolved": "0.2.251802",
- "contentHash": "bqnYl6AdSeboeN4v25hSukK6Odm6/54E3Y2B8rBvgqvAW0mF8fo7XNRVE2DMOG7Rk0fiuA079QIH28+V+W1Zdg==",
+ "resolved": "0.2.510501",
+ "contentHash": "juoqJYMDs+lRrrZyOkXXMImJHneCF23cuvO4waFRd2Ds7j+ZuGIPbJm0Y/zz34BdeaGiiwGWraMUlln05W1PCQ==",
"dependencies": {
- "Microsoft.Bcl.AsyncInterfaces": "1.1.0",
- "Microsoft.Extensions.Logging": "2.1.1"
+ "Microsoft.Extensions.Logging": "6.0.0"
}
},
"Microsoft.Diagnostics.Runtime": {
"type": "Transitive",
- "resolved": "2.2.332302",
- "contentHash": "Hp84ivxSKIMTBzYSATxmUsm3YSXHWivcwiRRbsydGmqujMUK8BAueLN0ssAVEOkOBmh0vjUBhrq7YcroT7VCug==",
+ "resolved": "3.1.512801",
+ "contentHash": "0lMUDr2oxNZa28D6NH5BuSQEe5T9tZziIkvkD44YkkCGQXPJqvFjLq5ZQq1hYLl3RjQJrY+hR0jFgap+EWPDTw==",
"dependencies": {
- "Microsoft.Diagnostics.NETCore.Client": "0.2.251802",
- "System.Collections.Immutable": "5.0.0",
- "System.Runtime.CompilerServices.Unsafe": "5.0.0"
+ "Microsoft.Diagnostics.NETCore.Client": "0.2.410101"
}
},
"Microsoft.Diagnostics.Tracing.TraceEvent": {
"type": "Transitive",
- "resolved": "3.1.8",
- "contentHash": "kl3UMrZKSeSEYZ8rt/GjLUQToREjgQABqfg6PzQBmSlYHTZOKE9ePEOS2xptROQ9SVvngg3QGX51TIT11iZ0wA==",
+ "resolved": "3.1.21",
+ "contentHash": "/OrJFKaojSR6TkUKtwh8/qA9XWNtxLrXMqvEb89dBSKCWjaGVTbKMYodIUgF5deCEtmd6GXuRerciXGl5bhZ7Q==",
"dependencies": {
- "Microsoft.Win32.Registry": "4.4.0",
- "System.Runtime.CompilerServices.Unsafe": "5.0.0"
+ "Microsoft.Diagnostics.NETCore.Client": "0.2.510501",
+ "System.Reflection.TypeExtensions": "4.7.0"
}
},
"Microsoft.DotNet.PlatformAbstractions": {
@@ -140,152 +132,98 @@
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "Transitive",
- "resolved": "8.0.0",
- "contentHash": "cjWrLkJXK0rs4zofsK4bSdg+jhDLTaxrkXu4gS6Y7MAlCvRyNNgwY/lJi5RDlQOnSZweHqoyvgvbdvQsRIW+hg=="
+ "resolved": "10.0.0",
+ "contentHash": "L3AdmZ1WOK4XXT5YFPEwyt0ep6l8lGIPs7F5OOBZc77Zqeo01Of7XXICy47628sdVl0v/owxYJTe86DTgFwKCA=="
},
"Microsoft.Extensions.Logging.Abstractions": {
"type": "Transitive",
- "resolved": "8.0.0",
- "contentHash": "arDBqTgFCyS0EvRV7O3MZturChstm50OJ0y9bDJvAcmEPJm0FFpFyjU/JLYyStNGGey081DvnQYlncNX5SJJGA==",
+ "resolved": "10.0.0",
+ "contentHash": "FU/IfjDfwaMuKr414SSQNTIti/69bHEMb+QKrskRb26oVqpx3lNFXMjs/RC9ZUuhBhcwDM2BwOgoMw+PZ+beqQ==",
"dependencies": {
- "Microsoft.Extensions.DependencyInjection.Abstractions": "8.0.0"
+ "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.0"
}
},
"Microsoft.Extensions.Options": {
"type": "Transitive",
- "resolved": "8.0.0",
- "contentHash": "JOVOfqpnqlVLUzINQ2fox8evY2SKLYJ3BV8QDe/Jyp21u1T7r45x/R/5QdteURMR5r01GxeJSBBUOCOyaNXA3g==",
+ "resolved": "10.0.0",
+ "contentHash": "8oCAgXOow5XDrY9HaXX1QmH3ORsyZO/ANVHBlhLyCeWTH5Sg4UuqZeOTWJi6484M+LqSx0RqQXDJtdYy2BNiLQ==",
"dependencies": {
- "Microsoft.Extensions.DependencyInjection.Abstractions": "8.0.0",
- "Microsoft.Extensions.Primitives": "8.0.0"
+ "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.0",
+ "Microsoft.Extensions.Primitives": "10.0.0"
}
},
"Microsoft.Extensions.Primitives": {
"type": "Transitive",
- "resolved": "8.0.0",
- "contentHash": "bXJEZrW9ny8vjMF1JV253WeLhpEVzFo1lyaZu1vQ4ZxWUlVvknZ/+ftFgVheLubb4eZPSwwxBeqS1JkCOjxd8g=="
- },
- "Microsoft.NETCore.Platforms": {
- "type": "Transitive",
- "resolved": "5.0.0",
- "contentHash": "VyPlqzH2wavqquTcYpkIIAQ6WdenuKoFN0BdYBbCWsclXacSOHNQn66Gt4z5NBqEYW0FAPm5rlvki9ZiCij5xQ=="
+ "resolved": "10.0.0",
+ "contentHash": "inRnbpCS0nwO/RuoZIAqxQUuyjaknOOnCEZB55KSMMjRhl0RQDttSmLSGsUJN3RQ3ocf5NDLFd2mOQViHqMK5w=="
},
"Microsoft.SourceLink.Common": {
"type": "Transitive",
"resolved": "8.0.0",
"contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw=="
},
- "Microsoft.Win32.Registry": {
+ "Perfolizer": {
"type": "Transitive",
- "resolved": "5.0.0",
- "contentHash": "dDoKi0PnDz31yAyETfRntsLArTlVAVzUzCIvvEDsDsucrl33Dl8pIJG06ePTJTI3tGpeyHS9Cq7Foc/s4EeKcg==",
+ "resolved": "0.6.1",
+ "contentHash": "CR1QmWg4XYBd1Pb7WseP+sDmV8nGPwvmowKynExTqr3OuckIGVMhvmN4LC5PGzfXqDlR295+hz/T7syA1CxEqA==",
"dependencies": {
- "System.Security.AccessControl": "5.0.0",
- "System.Security.Principal.Windows": "5.0.0"
+ "Pragmastat": "3.2.4"
}
},
- "Perfolizer": {
+ "Pragmastat": {
"type": "Transitive",
- "resolved": "0.3.17",
- "contentHash": "FQgtCoF2HFwvzKWulAwBS5BGLlh8pgbrJtOp47jyBwh2CW16juVtacN1azOA2BqdrJXkXTNLNRMo7ZlHHiuAnA=="
+ "resolved": "3.2.4",
+ "contentHash": "I5qFifWw/gaTQT52MhzjZpkm/JPlfjSeO/DTZJjO7+hTKI+0aGRgOgZ3NN6D96dDuuqbIAZSeA5RimtHjqrA2A=="
},
"SQLitePCLRaw.bundle_e_sqlite3": {
"type": "Transitive",
- "resolved": "2.1.4",
- "contentHash": "EWI1olKDjFEBMJu0+3wuxwziIAdWDVMYLhuZ3Qs84rrz+DHwD00RzWPZCa+bLnHCf3oJwuFZIRsHT5p236QXww==",
+ "resolved": "2.1.11",
+ "contentHash": "DC4nA7yWnf4UZdgJDF+9Mus4/cb0Y3Sfgi3gDnAoKNAIBwzkskNAbNbyu+u4atT0ruVlZNJfwZmwiEwE5oz9LQ==",
"dependencies": {
- "SQLitePCLRaw.lib.e_sqlite3": "2.1.4",
- "SQLitePCLRaw.provider.e_sqlite3": "2.1.4"
+ "SQLitePCLRaw.lib.e_sqlite3": "2.1.11",
+ "SQLitePCLRaw.provider.e_sqlite3": "2.1.11"
}
},
"SQLitePCLRaw.core": {
"type": "Transitive",
- "resolved": "2.1.4",
- "contentHash": "inBjvSHo9UDKneGNzfUfDjK08JzlcIhn1+SP5Y3m6cgXpCxXKCJDy6Mka7LpgSV+UZmKSnC8rTwB0SQ0xKu5pA==",
- "dependencies": {
- "System.Memory": "4.5.3"
- }
+ "resolved": "2.1.11",
+ "contentHash": "PK0GLFkfhZzLQeR3PJf71FmhtHox+U3vcY6ZtswoMjrefkB9k6ErNJEnwXqc5KgXDSjige2XXrezqS39gkpQKA=="
},
"SQLitePCLRaw.lib.e_sqlite3": {
"type": "Transitive",
- "resolved": "2.1.4",
- "contentHash": "2C9Q9eX7CPLveJA0rIhf9RXAvu+7nWZu1A2MdG6SD/NOu26TakGgL1nsbc0JAspGijFOo3HoN79xrx8a368fBg=="
+ "resolved": "2.1.11",
+ "contentHash": "Ev2ytaXiOlWZ4b3R67GZBsemTINslLD1DCJr2xiacpn4tbapu0Q4dHEzSvZSMnVWeE5nlObU3VZN2p81q3XOYQ=="
},
"SQLitePCLRaw.provider.e_sqlite3": {
"type": "Transitive",
- "resolved": "2.1.4",
- "contentHash": "CSlb5dUp1FMIkez9Iv5EXzpeq7rHryVNqwJMWnpq87j9zWZexaEMdisDktMsnnrzKM6ahNrsTkjqNodTBPBxtQ==",
+ "resolved": "2.1.11",
+ "contentHash": "Y/0ZkR+r0Cg3DQFuCl1RBnv/tmxpIZRU3HUvelPw6MVaKHwYYR8YNvgs0vuNuXCMvlyJ+Fh88U1D4tah1tt6qw==",
"dependencies": {
- "SQLitePCLRaw.core": "2.1.4"
+ "SQLitePCLRaw.core": "2.1.11"
}
},
"System.CodeDom": {
"type": "Transitive",
- "resolved": "5.0.0",
- "contentHash": "JPJArwA1kdj8qDAkY2XGjSWoYnqiM7q/3yRNkt6n28Mnn95MuEGkZXUbPBf7qc3IjwrGY5ttQon7yqHZyQJmOQ=="
- },
- "System.Collections.Immutable": {
- "type": "Transitive",
- "resolved": "5.0.0",
- "contentHash": "FXkLXiK0sVVewcso0imKQoOxjoPAj42R8HtjjbSjVPAzwDfzoyoznWxgA3c38LDbN9SJux1xXoXYAhz98j7r2g=="
+ "resolved": "9.0.5",
+ "contentHash": "cuzLM2MWutf9ZBEMPYYfd0DXwYdvntp7VCT6a/wvbKCa2ZuvGmW74xi+YBa2mrfEieAXqM4TNKlMmSnfAfpUoQ=="
},
"System.Management": {
"type": "Transitive",
- "resolved": "5.0.0",
- "contentHash": "MF1CHaRcC+MLFdnDthv4/bKWBZnlnSpkGqa87pKukQefgEdwtb9zFW6zs0GjPp73qtpYYg4q6PEKbzJbxCpKfw==",
+ "resolved": "9.0.5",
+ "contentHash": "n6o9PZm9p25+zAzC3/48K0oHnaPKTInRrxqFq1fi/5TPbMLjuoCm/h//mS3cUmSy+9AO1Z+qsC/Ilt/ZFatv5Q==",
"dependencies": {
- "Microsoft.NETCore.Platforms": "5.0.0",
- "Microsoft.Win32.Registry": "5.0.0",
- "System.CodeDom": "5.0.0"
+ "System.CodeDom": "9.0.5"
}
},
- "System.Memory": {
- "type": "Transitive",
- "resolved": "4.5.4",
- "contentHash": "1MbJTHS1lZ4bS4FmsJjnuGJOu88ZzTT2rLvrhW7Ygic+pC0NWA+3hgAen0HRdsocuQXCkUTdFn9yHJJhsijDXw=="
- },
"System.Reactive": {
"type": "Transitive",
- "resolved": "5.0.0",
- "contentHash": "erBZjkQHWL9jpasCE/0qKAryzVBJFxGHVBAvgRN1bzM0q2s1S4oYREEEL0Vb+1kA/6BKb5FjUZMp5VXmy+gzkQ=="
- },
- "System.Reflection.Metadata": {
- "type": "Transitive",
- "resolved": "5.0.0",
- "contentHash": "5NecZgXktdGg34rh1OenY1rFNDCI8xSjFr+Z4OU4cU06AQHUdRnIIEeWENu3Wl4YowbzkymAIMvi3WyK9U53pQ=="
- },
- "System.Runtime.CompilerServices.Unsafe": {
- "type": "Transitive",
- "resolved": "5.0.0",
- "contentHash": "ZD9TMpsmYJLrxbbmdvhwt9YEgG5WntEnZ/d1eH8JBX9LBp+Ju8BSBhUGbZMNVHHomWo2KVImJhTDl2hIgw/6MA=="
- },
- "System.Security.AccessControl": {
- "type": "Transitive",
- "resolved": "5.0.0",
- "contentHash": "dagJ1mHZO3Ani8GH0PHpPEe/oYO+rVdbQjvjJkBRNQkX4t0r1iaeGn8+/ybkSLEan3/slM0t59SVdHzuHf2jmw==",
- "dependencies": {
- "Microsoft.NETCore.Platforms": "5.0.0",
- "System.Security.Principal.Windows": "5.0.0"
- }
- },
- "System.Security.Principal.Windows": {
- "type": "Transitive",
- "resolved": "5.0.0",
- "contentHash": "t0MGLukB5WAVU9bO3MGzvlGnyJPgUlcwerXn1kzBRjwLKixT96XV0Uza41W49gVd8zEMFu9vQEFlv0IOrytICA=="
- },
- "System.Text.Encoding.CodePages": {
- "type": "Transitive",
- "resolved": "4.5.1",
- "contentHash": "4J2JQXbftjPMppIHJ7IC+VXQ9XfEagN92vZZNoG12i+zReYlim5dMoXFC1Zzg7tsnKDM7JPo5bYfFK4Jheq44w==",
- "dependencies": {
- "Microsoft.NETCore.Platforms": "2.1.2",
- "System.Runtime.CompilerServices.Unsafe": "4.5.2"
- }
+ "resolved": "6.0.0",
+ "contentHash": "31kfaW4ZupZzPsI5PVe77VhnvFF55qgma7KZr/E0iFTs6fmdhhG8j0mgEx620iLTey1EynOkEfnyTjtNEpJzGw=="
},
- "System.Threading.Tasks.Extensions": {
+ "System.Reflection.TypeExtensions": {
"type": "Transitive",
- "resolved": "4.5.4",
- "contentHash": "zteT+G8xuGu6mS+mzDzYXbzS7rd3K6Fjb9RiZlYlJPam2/hU7JCBZBVEcywNuR+oZ1ncTvc/cq0faRr3P01OVg=="
+ "resolved": "4.7.0",
+ "contentHash": "VybpaOQQhqE6siHppMktjfGBw1GCwvCqiufqmP8F1nj7fTUNtW35LOEt3UZTEsECfo+ELAl/9o9nJx3U91i7vA=="
},
"speckle.objects": {
"type": "Project",
@@ -296,10 +234,10 @@
"speckle.sdk": {
"type": "Project",
"dependencies": {
- "GraphQL.Client": "[6.0.0, )",
- "Microsoft.Data.Sqlite": "[7.0.5, )",
- "Microsoft.Extensions.DependencyInjection": "[8.0.0, )",
- "Microsoft.Extensions.Logging": "[8.0.0, )",
+ "GraphQL.Client": "[6.1.0, )",
+ "Microsoft.Data.Sqlite": "[10.0.0, )",
+ "Microsoft.Extensions.Logging": "[10.0.0, )",
+ "Microsoft.Extensions.ObjectPool": "[10.0.0, )",
"Speckle.DoubleNumerics": "[4.1.0, )",
"Speckle.Newtonsoft.Json": "[13.0.2, )",
"Speckle.Sdk.Dependencies": "[1.0.0, )"
@@ -311,75 +249,76 @@
"speckle.sdk.tests.performance": {
"type": "Project",
"dependencies": {
- "BenchmarkDotNet": "[0.14.0, )",
+ "BenchmarkDotNet": "[0.15.8, )",
"Speckle.Objects": "[1.0.0, )"
}
},
"BenchmarkDotNet": {
"type": "CentralTransitive",
- "requested": "[0.14.0, )",
- "resolved": "0.14.0",
- "contentHash": "eIPSDKi3oni734M1rt/XJAwGQQOIf9gLjRRKKJ0HuVy3vYd7gnmAIX1bTjzI9ZbAY/nPddgqqgM/TeBYitMCIg==",
+ "requested": "[0.15.8, )",
+ "resolved": "0.15.8",
+ "contentHash": "paCfrWxSeHqn3rUZc0spYXVFnHCF0nzRhG0nOLnyTjZYs8spsimBaaNmb3vwqvALKIplbYq/TF393vYiYSnh/Q==",
"dependencies": {
- "BenchmarkDotNet.Annotations": "0.14.0",
+ "BenchmarkDotNet.Annotations": "0.15.8",
"CommandLineParser": "2.9.1",
"Gee.External.Capstone": "2.3.0",
- "Iced": "1.17.0",
- "Microsoft.CodeAnalysis.CSharp": "4.1.0",
- "Microsoft.Diagnostics.Runtime": "2.2.332302",
- "Microsoft.Diagnostics.Tracing.TraceEvent": "3.1.8",
+ "Iced": "1.21.0",
+ "Microsoft.CodeAnalysis.CSharp": "4.14.0",
+ "Microsoft.Diagnostics.Runtime": "3.1.512801",
+ "Microsoft.Diagnostics.Tracing.TraceEvent": "3.1.21",
"Microsoft.DotNet.PlatformAbstractions": "3.1.6",
- "Perfolizer": "[0.3.17]",
- "System.Management": "5.0.0"
+ "Perfolizer": "[0.6.1]",
+ "System.Management": "9.0.5"
}
},
"GraphQL.Client": {
"type": "CentralTransitive",
"requested": "[6.1.0, )",
- "resolved": "6.0.0",
- "contentHash": "8yPNBbuVBpTptivyAlak4GZvbwbUcjeQTL4vN1HKHRuOykZ4r7l5fcLS6vpyPyLn0x8FsL31xbOIKyxbmR9rbA==",
+ "resolved": "6.1.0",
+ "contentHash": "oKliAxtNuZDMxO9079mjSbwA0YwhjXBzVnVPuNZ3HI4OllO++CcOLT30l90mM/fxCAMaa8GU4ZYMwD9YjLkyiw==",
"dependencies": {
- "GraphQL.Client.Abstractions": "6.0.0",
- "GraphQL.Client.Abstractions.Websocket": "6.0.0",
- "System.Reactive": "5.0.0"
+ "GraphQL.Client.Abstractions": "6.1.0",
+ "GraphQL.Client.Abstractions.Websocket": "6.1.0",
+ "System.Reactive": "6.0.0"
}
},
- "Microsoft.Bcl.AsyncInterfaces": {
- "type": "CentralTransitive",
- "requested": "[9.0.4, )",
- "resolved": "1.1.0",
- "contentHash": "1Am6l4Vpn3/K32daEqZI+FFr96OlZkgwK2LcT3pZ2zWubR5zTPW3/FkO1Rat9kb7oQOa4rxgl9LJHc5tspCWfg=="
- },
"Microsoft.Data.Sqlite": {
"type": "CentralTransitive",
"requested": "[7.0.5, )",
- "resolved": "7.0.5",
- "contentHash": "KGxbPeWsQMnmQy43DSBxAFtHz3l2JX8EWBSGUCvT3CuZ8KsuzbkqMIJMDOxWtG8eZSoCDI04aiVQjWuuV8HmSw==",
+ "resolved": "10.0.0",
+ "contentHash": "I/azQ5WjwoLvSlTyDydkhARPSjYJN8jkXRjR5D92OeyTLbTrQ1K93rgf6XU+HYWHZA6lBI9SUOfl69OqEHb4ow==",
"dependencies": {
- "Microsoft.Data.Sqlite.Core": "7.0.5",
- "SQLitePCLRaw.bundle_e_sqlite3": "2.1.4"
+ "Microsoft.Data.Sqlite.Core": "10.0.0",
+ "SQLitePCLRaw.bundle_e_sqlite3": "2.1.11",
+ "SQLitePCLRaw.core": "2.1.11"
}
},
"Microsoft.Extensions.DependencyInjection": {
"type": "CentralTransitive",
"requested": "[10.0.6, )",
- "resolved": "8.0.0",
- "contentHash": "V8S3bsm50ig6JSyrbcJJ8bW2b9QLGouz+G1miK3UTaOWmMtFwNNNzUf4AleyDWUmTrWMLNnFSLEQtxmxgNQnNQ==",
+ "resolved": "10.0.0",
+ "contentHash": "f0RBabswJq+gRu5a+hWIobrLWiUYPKMhCD9WO3sYBAdSy3FFH14LMvLVFZc2kPSCimBLxSuitUhsd6tb0TAY6A==",
"dependencies": {
- "Microsoft.Extensions.DependencyInjection.Abstractions": "8.0.0"
+ "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.0"
}
},
"Microsoft.Extensions.Logging": {
"type": "CentralTransitive",
"requested": "[10.0.6, )",
- "resolved": "8.0.0",
- "contentHash": "tvRkov9tAJ3xP51LCv3FJ2zINmv1P8Hi8lhhtcKGqM+ImiTCC84uOPEI4z8Cdq2C3o9e+Aa0Gw0rmrsJD77W+w==",
+ "resolved": "10.0.0",
+ "contentHash": "BStFkd5CcnEtarlcgYDBcFzGYCuuNMzPs02wN3WBsOFoYIEmYoUdAiU+au6opzoqfTYJsMTW00AeqDdnXH2CvA==",
"dependencies": {
- "Microsoft.Extensions.DependencyInjection": "8.0.0",
- "Microsoft.Extensions.Logging.Abstractions": "8.0.0",
- "Microsoft.Extensions.Options": "8.0.0"
+ "Microsoft.Extensions.DependencyInjection": "10.0.0",
+ "Microsoft.Extensions.Logging.Abstractions": "10.0.0",
+ "Microsoft.Extensions.Options": "10.0.0"
}
},
+ "Microsoft.Extensions.ObjectPool": {
+ "type": "CentralTransitive",
+ "requested": "[9.0.4, )",
+ "resolved": "10.0.0",
+ "contentHash": "bpeCq0IYmVLACyEUMzFIOQX+zZUElG1t+nu1lSxthe7B+1oNYking7b91305+jNB6iwojp9fqTY9O+Nh7ULQxg=="
+ },
"Speckle.DoubleNumerics": {
"type": "CentralTransitive",
"requested": "[4.1.0, )",
diff --git a/tests/Speckle.Sdk.Serialization.Tests/Pipelines/AttachedTests.cs b/tests/Speckle.Sdk.Serialization.Tests/Pipelines/AttachedTests.cs
new file mode 100644
index 00000000..d8a8af36
--- /dev/null
+++ b/tests/Speckle.Sdk.Serialization.Tests/Pipelines/AttachedTests.cs
@@ -0,0 +1,38 @@
+using Speckle.Objects.Geometry;
+using Speckle.Sdk.Host;
+using Speckle.Sdk.Models;
+using Speckle.Sdk.Pipelines.Send;
+
+namespace Speckle.Sdk.Serialization.Tests.Pipelines;
+
+public sealed class AttachedTests
+{
+ private readonly Serializer _sut;
+
+ public AttachedTests()
+ {
+ TypeLoader.ReInitialize(typeof(TestClass).Assembly, typeof(Polyline).Assembly);
+
+ _sut = new();
+ }
+
+ [Fact]
+ public void ExpectAttachedIdsToMatchBase()
+ {
+ string seed = Guid.NewGuid().ToString();
+ Base b0 = new() { ["data"] = seed };
+ UploadItem l0 = _sut.Serialize(b0).First();
+
+ Base b1 = new() { ["data"] = b0 };
+ UploadItem l1 = _sut.Serialize(b1).First();
+ string expectedLine1 = $"\"id\":\"{l0.Id}\"";
+ Assert.Contains(expectedLine1, l1.Json.ToJsonString());
+ Assert.Contains(seed, l1.Json.ToJsonString());
+
+ Base b2 = new() { ["data"] = b1 };
+ UploadItem l2 = _sut.Serialize(b2).First();
+ string expectedLine2 = $"\"id\":\"{l1.Id}\"";
+ Assert.Contains(expectedLine2, l2.Json.ToJsonString());
+ Assert.Contains(expectedLine2, l1.Json.ToJsonString());
+ }
+}
diff --git a/tests/Speckle.Sdk.Serialization.Tests/Pipelines/DataObjectTests.ValidateDataObject_type=Speckle.Objects.Data.ArcgisObject.verified.json b/tests/Speckle.Sdk.Serialization.Tests/Pipelines/DataObjectTests.ValidateDataObject_type=Speckle.Objects.Data.ArcgisObject.verified.json
new file mode 100644
index 00000000..83bf3b9c
--- /dev/null
+++ b/tests/Speckle.Sdk.Serialization.Tests/Pipelines/DataObjectTests.ValidateDataObject_type=Speckle.Objects.Data.ArcgisObject.verified.json
@@ -0,0 +1,10 @@
+{
+ "applicationId": null,
+ "displayValue": null,
+ "id": "84fd08f2480334d155b64a4cea455ed4",
+ "name": null,
+ "properties": null,
+ "speckle_type": "Objects.Data.DataObject:Objects.Data.ArcgisObject",
+ "type": null,
+ "units": null
+}
diff --git a/tests/Speckle.Sdk.Serialization.Tests/Pipelines/DataObjectTests.ValidateDataObject_type=Speckle.Objects.Data.ArchicadObject.verified.json b/tests/Speckle.Sdk.Serialization.Tests/Pipelines/DataObjectTests.ValidateDataObject_type=Speckle.Objects.Data.ArchicadObject.verified.json
new file mode 100644
index 00000000..73607522
--- /dev/null
+++ b/tests/Speckle.Sdk.Serialization.Tests/Pipelines/DataObjectTests.ValidateDataObject_type=Speckle.Objects.Data.ArchicadObject.verified.json
@@ -0,0 +1,11 @@
+{
+ "applicationId": null,
+ "displayValue": null,
+ "elements": null,
+ "id": "5445efeab75ef29d8792fdb6588bedf9",
+ "level": null,
+ "name": null,
+ "properties": null,
+ "speckle_type": "Objects.Data.DataObject:Objects.Data.ArchicadObject",
+ "type": null
+}
diff --git a/tests/Speckle.Sdk.Serialization.Tests/Pipelines/DataObjectTests.ValidateDataObject_type=Speckle.Objects.Data.Civil3dObject.verified.json b/tests/Speckle.Sdk.Serialization.Tests/Pipelines/DataObjectTests.ValidateDataObject_type=Speckle.Objects.Data.Civil3dObject.verified.json
new file mode 100644
index 00000000..1a9bd46f
--- /dev/null
+++ b/tests/Speckle.Sdk.Serialization.Tests/Pipelines/DataObjectTests.ValidateDataObject_type=Speckle.Objects.Data.Civil3dObject.verified.json
@@ -0,0 +1,12 @@
+{
+ "applicationId": null,
+ "baseCurves": null,
+ "displayValue": null,
+ "elements": null,
+ "id": "cd3224e98a0a994a944301f784c7b66f",
+ "name": null,
+ "properties": null,
+ "speckle_type": "Objects.Data.DataObject:Objects.Data.Civil3dObject",
+ "type": null,
+ "units": null
+}
diff --git a/tests/Speckle.Sdk.Serialization.Tests/Pipelines/DataObjectTests.ValidateDataObject_type=Speckle.Objects.Data.DataObject.verified.json b/tests/Speckle.Sdk.Serialization.Tests/Pipelines/DataObjectTests.ValidateDataObject_type=Speckle.Objects.Data.DataObject.verified.json
new file mode 100644
index 00000000..642a60c7
--- /dev/null
+++ b/tests/Speckle.Sdk.Serialization.Tests/Pipelines/DataObjectTests.ValidateDataObject_type=Speckle.Objects.Data.DataObject.verified.json
@@ -0,0 +1,8 @@
+{
+ "applicationId": null,
+ "displayValue": null,
+ "id": "ad1089e775e31c7da3bf915e76ce53de",
+ "name": null,
+ "properties": null,
+ "speckle_type": "Objects.Data.DataObject"
+}
diff --git a/tests/Speckle.Sdk.Serialization.Tests/Pipelines/DataObjectTests.ValidateDataObject_type=Speckle.Objects.Data.EtabsObject.verified.json b/tests/Speckle.Sdk.Serialization.Tests/Pipelines/DataObjectTests.ValidateDataObject_type=Speckle.Objects.Data.EtabsObject.verified.json
new file mode 100644
index 00000000..9cf062f8
--- /dev/null
+++ b/tests/Speckle.Sdk.Serialization.Tests/Pipelines/DataObjectTests.ValidateDataObject_type=Speckle.Objects.Data.EtabsObject.verified.json
@@ -0,0 +1,11 @@
+{
+ "applicationId": null,
+ "displayValue": null,
+ "elements": null,
+ "id": "ba6c6436f2bf9171de67a21161323ccd",
+ "name": null,
+ "properties": null,
+ "speckle_type": "Objects.Data.DataObject:Objects.Data.EtabsObject",
+ "type": null,
+ "units": null
+}
diff --git a/tests/Speckle.Sdk.Serialization.Tests/Pipelines/DataObjectTests.ValidateDataObject_type=Speckle.Objects.Data.NavisworksObject.verified.json b/tests/Speckle.Sdk.Serialization.Tests/Pipelines/DataObjectTests.ValidateDataObject_type=Speckle.Objects.Data.NavisworksObject.verified.json
new file mode 100644
index 00000000..6638484c
--- /dev/null
+++ b/tests/Speckle.Sdk.Serialization.Tests/Pipelines/DataObjectTests.ValidateDataObject_type=Speckle.Objects.Data.NavisworksObject.verified.json
@@ -0,0 +1,9 @@
+{
+ "applicationId": null,
+ "displayValue": null,
+ "id": "a8c00df968e0685b075d045fa0070d79",
+ "name": null,
+ "properties": null,
+ "speckle_type": "Objects.Data.DataObject:Objects.Data.NavisworksObject",
+ "units": null
+}
diff --git a/tests/Speckle.Sdk.Serialization.Tests/Pipelines/DataObjectTests.ValidateDataObject_type=Speckle.Objects.Data.RevitObject.verified.json b/tests/Speckle.Sdk.Serialization.Tests/Pipelines/DataObjectTests.ValidateDataObject_type=Speckle.Objects.Data.RevitObject.verified.json
new file mode 100644
index 00000000..0d37ba20
--- /dev/null
+++ b/tests/Speckle.Sdk.Serialization.Tests/Pipelines/DataObjectTests.ValidateDataObject_type=Speckle.Objects.Data.RevitObject.verified.json
@@ -0,0 +1,15 @@
+{
+ "applicationId": null,
+ "category": null,
+ "displayValue": null,
+ "elements": null,
+ "family": null,
+ "id": "db87304ee2d291bcb9270aa38c083c11",
+ "level": null,
+ "location": null,
+ "name": null,
+ "properties": null,
+ "speckle_type": "Objects.Data.DataObject:Objects.Data.RevitObject",
+ "type": null,
+ "units": null
+}
diff --git a/tests/Speckle.Sdk.Serialization.Tests/Pipelines/DataObjectTests.ValidateDataObject_type=Speckle.Objects.Data.TeklaObject.verified.json b/tests/Speckle.Sdk.Serialization.Tests/Pipelines/DataObjectTests.ValidateDataObject_type=Speckle.Objects.Data.TeklaObject.verified.json
new file mode 100644
index 00000000..cd86a3bb
--- /dev/null
+++ b/tests/Speckle.Sdk.Serialization.Tests/Pipelines/DataObjectTests.ValidateDataObject_type=Speckle.Objects.Data.TeklaObject.verified.json
@@ -0,0 +1,11 @@
+{
+ "applicationId": null,
+ "displayValue": null,
+ "elements": null,
+ "id": "5b2c676d86fce8b4f95f0020e4a8cfa1",
+ "name": null,
+ "properties": null,
+ "speckle_type": "Objects.Data.DataObject:Objects.Data.TeklaObject",
+ "type": null,
+ "units": null
+}
diff --git a/tests/Speckle.Sdk.Serialization.Tests/Pipelines/DataObjectTests.cs b/tests/Speckle.Sdk.Serialization.Tests/Pipelines/DataObjectTests.cs
new file mode 100644
index 00000000..e729abc5
--- /dev/null
+++ b/tests/Speckle.Sdk.Serialization.Tests/Pipelines/DataObjectTests.cs
@@ -0,0 +1,40 @@
+using Speckle.Objects.Data;
+using Speckle.Objects.Geometry;
+using Speckle.Sdk.Host;
+using Speckle.Sdk.Models;
+using Speckle.Sdk.Pipelines.Send;
+
+namespace Speckle.Sdk.Serialization.Tests.Pipelines;
+
+public class DataObjectTests
+{
+ private readonly Serializer _sut;
+
+ public DataObjectTests()
+ {
+ TypeLoader.ReInitialize(typeof(TestClass).Assembly, typeof(Polyline).Assembly);
+
+ _sut = new();
+ }
+
+ [Theory]
+ [InlineData(typeof(ArcgisObject))]
+ [InlineData(typeof(ArchicadObject))]
+ [InlineData(typeof(Civil3dObject))]
+ [InlineData(typeof(DataObject))]
+ [InlineData(typeof(EtabsObject))]
+ [InlineData(typeof(NavisworksObject))]
+ [InlineData(typeof(RevitObject))]
+ [InlineData(typeof(TeklaObject))]
+ public async Task ValidateDataObject(Type type)
+ {
+ Base myBase = (Base)(
+ Activator.CreateInstance(type) ?? throw new Exception("Could not create instance of " + type.Name)
+ );
+ IEnumerable result = _sut.Serialize(myBase);
+
+ var json = result.Last().Json.ToJsonString();
+
+ await VerifyJson(json).UseParameters(type);
+ }
+}
diff --git a/tests/Speckle.Sdk.Serialization.Tests/Pipelines/DetachedTests.CanSerialize_Attached.verified.json b/tests/Speckle.Sdk.Serialization.Tests/Pipelines/DetachedTests.CanSerialize_Attached.verified.json
new file mode 100644
index 00000000..ce2c3252
--- /dev/null
+++ b/tests/Speckle.Sdk.Serialization.Tests/Pipelines/DetachedTests.CanSerialize_Attached.verified.json
@@ -0,0 +1,51 @@
+{
+ "a9a10a300a32d8ce7bf87e478162377c": {
+ "applicationId": null,
+ "area": 0,
+ "bbox": null,
+ "closed": false,
+ "domain": {
+ "applicationId": null,
+ "end": 1,
+ "id": "85660a9f276d3f43500aedac0e4f7062",
+ "speckle_type": "Objects.Primitive.Interval",
+ "start": 0
+ },
+ "id": "a9a10a300a32d8ce7bf87e478162377c",
+ "length": 0,
+ "speckle_type": "Objects.Geometry.Polyline",
+ "units": "test",
+ "value": [
+ 3,
+ 4
+ ]
+ },
+ "ee7561f0adde3a349f99238b4aeab164": {
+ "__closure": {
+ "a9a10a300a32d8ce7bf87e478162377c": 1
+ },
+ "applicationId": "1",
+ "arr": null,
+ "attachedProp": {
+ "__closure": {
+ "a9a10a300a32d8ce7bf87e478162377c": 1
+ },
+ "applicationId": "4",
+ "id": "06b9162b0a85b85b498a92ef4e95492c",
+ "line": {
+ "referencedId": "a9a10a300a32d8ce7bf87e478162377c",
+ "speckle_type": "reference"
+ },
+ "name": "attachedProp",
+ "speckle_type": "Speckle.Core.Tests.Unit.Models.BaseTests+SamplePropBase2"
+ },
+ "crazyProp": null,
+ "detachedProp": null,
+ "detachedProp2": null,
+ "dynamicProp": 123,
+ "id": "ee7561f0adde3a349f99238b4aeab164",
+ "list": [],
+ "list2": null,
+ "speckle_type": "Speckle.Core.Tests.Unit.Models.BaseTests+SampleObjectBase2"
+ }
+}
diff --git a/tests/Speckle.Sdk.Serialization.Tests/Pipelines/DetachedTests.CanSerialize_Attached_2.verified.json b/tests/Speckle.Sdk.Serialization.Tests/Pipelines/DetachedTests.CanSerialize_Attached_2.verified.json
new file mode 100644
index 00000000..2ee5f727
--- /dev/null
+++ b/tests/Speckle.Sdk.Serialization.Tests/Pipelines/DetachedTests.CanSerialize_Attached_2.verified.json
@@ -0,0 +1,21 @@
+{
+ "1c8c3f02283a215451092973eccbd4db": {
+ "applicationId": "1",
+ "arr": null,
+ "attachedProp": {
+ "applicationId": "4",
+ "id": "fa1e5165dc1458a44e4684ce714f0d2b",
+ "line": null,
+ "name": "attachedProp",
+ "speckle_type": "Speckle.Core.Tests.Unit.Models.BaseTests+SamplePropBase2"
+ },
+ "crazyProp": null,
+ "detachedProp": null,
+ "detachedProp2": null,
+ "dynamicProp": 123,
+ "id": "1c8c3f02283a215451092973eccbd4db",
+ "list": [],
+ "list2": null,
+ "speckle_type": "Speckle.Core.Tests.Unit.Models.BaseTests+SampleObjectBase2"
+ }
+}
diff --git a/tests/Speckle.Sdk.Serialization.Tests/Pipelines/DetachedTests.CanSerialize_New_Detached.verified.json b/tests/Speckle.Sdk.Serialization.Tests/Pipelines/DetachedTests.CanSerialize_New_Detached.verified.json
new file mode 100644
index 00000000..f69a42a2
--- /dev/null
+++ b/tests/Speckle.Sdk.Serialization.Tests/Pipelines/DetachedTests.CanSerialize_New_Detached.verified.json
@@ -0,0 +1,30 @@
+{
+ "5053b39434bf2f35a388fe8e419ca181": {
+ "applicationId": null,
+ "id": "5053b39434bf2f35a388fe8e419ca181",
+ "name": "detachedProp",
+ "speckle_type": "Speckle.Core.Tests.Unit.Models.BaseTests+SamplePropBase"
+ },
+ "a8ec0370e21dd89402803fd450d2f58c": {
+ "__closure": {
+ "5053b39434bf2f35a388fe8e419ca181": 1
+ },
+ "applicationId": null,
+ "arr": null,
+ "attachedProp": {
+ "applicationId": null,
+ "id": "6e5c34adf929602ce78d559d71f53c01",
+ "name": "attachedProp",
+ "speckle_type": "Speckle.Core.Tests.Unit.Models.BaseTests+SamplePropBase"
+ },
+ "crazyProp": null,
+ "detachedProp": {
+ "referencedId": "5053b39434bf2f35a388fe8e419ca181",
+ "speckle_type": "reference"
+ },
+ "dynamicProp": 123,
+ "id": "a8ec0370e21dd89402803fd450d2f58c",
+ "list": [],
+ "speckle_type": "Speckle.Core.Tests.Unit.Models.BaseTests+SampleObjectBase"
+ }
+}
diff --git a/tests/Speckle.Sdk.Serialization.Tests/Pipelines/DetachedTests.CanSerialize_New_Detached2.verified.json b/tests/Speckle.Sdk.Serialization.Tests/Pipelines/DetachedTests.CanSerialize_New_Detached2.verified.json
new file mode 100644
index 00000000..4f9ff534
--- /dev/null
+++ b/tests/Speckle.Sdk.Serialization.Tests/Pipelines/DetachedTests.CanSerialize_New_Detached2.verified.json
@@ -0,0 +1,129 @@
+{
+ "0bd92b9bb0a61dfe13f2bd40ba918b4e": {
+ "__closure": {
+ "d601958e33a1473d1c068e0082afa630": 1
+ },
+ "applicationId": "2",
+ "id": "0bd92b9bb0a61dfe13f2bd40ba918b4e",
+ "line": {
+ "referencedId": "d601958e33a1473d1c068e0082afa630",
+ "speckle_type": "reference"
+ },
+ "name": "detachedProp",
+ "speckle_type": "Speckle.Core.Tests.Unit.Models.BaseTests+SamplePropBase2"
+ },
+ "54156930111d678f0228f957605fb95b": {
+ "applicationId": null,
+ "area": 0,
+ "bbox": null,
+ "closed": false,
+ "domain": {
+ "applicationId": null,
+ "end": 1,
+ "id": "85660a9f276d3f43500aedac0e4f7062",
+ "speckle_type": "Objects.Primitive.Interval",
+ "start": 0
+ },
+ "id": "54156930111d678f0228f957605fb95b",
+ "length": 0,
+ "speckle_type": "Objects.Geometry.Polyline",
+ "units": "test",
+ "value": [
+ 3,
+ 2
+ ]
+ },
+ "60e31bdb9c14fef6684746201dd42928": {
+ "__closure": {
+ "0bd92b9bb0a61dfe13f2bd40ba918b4e": 1,
+ "54156930111d678f0228f957605fb95b": 1,
+ "a9a10a300a32d8ce7bf87e478162377c": 1,
+ "d601958e33a1473d1c068e0082afa630": 1,
+ "db01a206aa71f203904ee8b7b3a52bd9": 1
+ },
+ "applicationId": "1",
+ "arr": null,
+ "attachedProp": {
+ "__closure": {
+ "a9a10a300a32d8ce7bf87e478162377c": 1
+ },
+ "applicationId": "4",
+ "id": "06b9162b0a85b85b498a92ef4e95492c",
+ "line": {
+ "referencedId": "a9a10a300a32d8ce7bf87e478162377c",
+ "speckle_type": "reference"
+ },
+ "name": "attachedProp",
+ "speckle_type": "Speckle.Core.Tests.Unit.Models.BaseTests+SamplePropBase2"
+ },
+ "crazyProp": null,
+ "detachedProp": {
+ "referencedId": "0bd92b9bb0a61dfe13f2bd40ba918b4e",
+ "speckle_type": "reference"
+ },
+ "detachedProp2": {
+ "referencedId": "db01a206aa71f203904ee8b7b3a52bd9",
+ "speckle_type": "reference"
+ },
+ "dynamicProp": 123,
+ "id": "60e31bdb9c14fef6684746201dd42928",
+ "list": [],
+ "list2": null,
+ "speckle_type": "Speckle.Core.Tests.Unit.Models.BaseTests+SampleObjectBase2"
+ },
+ "a9a10a300a32d8ce7bf87e478162377c": {
+ "applicationId": null,
+ "area": 0,
+ "bbox": null,
+ "closed": false,
+ "domain": {
+ "applicationId": null,
+ "end": 1,
+ "id": "85660a9f276d3f43500aedac0e4f7062",
+ "speckle_type": "Objects.Primitive.Interval",
+ "start": 0
+ },
+ "id": "a9a10a300a32d8ce7bf87e478162377c",
+ "length": 0,
+ "speckle_type": "Objects.Geometry.Polyline",
+ "units": "test",
+ "value": [
+ 3,
+ 4
+ ]
+ },
+ "d601958e33a1473d1c068e0082afa630": {
+ "applicationId": null,
+ "area": 0,
+ "bbox": null,
+ "closed": false,
+ "domain": {
+ "applicationId": null,
+ "end": 1,
+ "id": "85660a9f276d3f43500aedac0e4f7062",
+ "speckle_type": "Objects.Primitive.Interval",
+ "start": 0
+ },
+ "id": "d601958e33a1473d1c068e0082afa630",
+ "length": 0,
+ "speckle_type": "Objects.Geometry.Polyline",
+ "units": "test",
+ "value": [
+ 1,
+ 2
+ ]
+ },
+ "db01a206aa71f203904ee8b7b3a52bd9": {
+ "__closure": {
+ "54156930111d678f0228f957605fb95b": 1
+ },
+ "applicationId": "3",
+ "id": "db01a206aa71f203904ee8b7b3a52bd9",
+ "line": {
+ "referencedId": "54156930111d678f0228f957605fb95b",
+ "speckle_type": "reference"
+ },
+ "name": "detachedProp2",
+ "speckle_type": "Speckle.Core.Tests.Unit.Models.BaseTests+SamplePropBase2"
+ }
+}
diff --git a/tests/Speckle.Sdk.Serialization.Tests/Pipelines/DetachedTests.CanSerialize_New_Detached_With_DataChunks.verified.json b/tests/Speckle.Sdk.Serialization.Tests/Pipelines/DetachedTests.CanSerialize_New_Detached_With_DataChunks.verified.json
new file mode 100644
index 00000000..0b2c66be
--- /dev/null
+++ b/tests/Speckle.Sdk.Serialization.Tests/Pipelines/DetachedTests.CanSerialize_New_Detached_With_DataChunks.verified.json
@@ -0,0 +1,29 @@
+{
+ "a7e5385b37c09008c969d79c5f94fb6e": {
+ "applicationId": "1",
+ "arr": null,
+ "attachedProp": null,
+ "crazyProp": null,
+ "detachedProp": null,
+ "detachedProp2": null,
+ "dynamicProp": 123,
+ "id": "a7e5385b37c09008c969d79c5f94fb6e",
+ "list": [
+ 1,
+ 2,
+ 3,
+ 4,
+ 5,
+ 6,
+ 7,
+ 8,
+ 9,
+ 10
+ ],
+ "list2": [
+ 1,
+ 10
+ ],
+ "speckle_type": "Speckle.Core.Tests.Unit.Models.BaseTests+SampleObjectBase2"
+ }
+}
diff --git a/tests/Speckle.Sdk.Serialization.Tests/Pipelines/DetachedTests.CanSerialize_New_Detached_With_DataChunks2.verified.json b/tests/Speckle.Sdk.Serialization.Tests/Pipelines/DetachedTests.CanSerialize_New_Detached_With_DataChunks2.verified.json
new file mode 100644
index 00000000..77b8c0cf
--- /dev/null
+++ b/tests/Speckle.Sdk.Serialization.Tests/Pipelines/DetachedTests.CanSerialize_New_Detached_With_DataChunks2.verified.json
@@ -0,0 +1,32 @@
+{
+ "566c5fcf4a7d4aae446a53725703532f": {
+ "applicationId": "1",
+ "arr": [
+ 1,
+ 10
+ ],
+ "attachedProp": null,
+ "crazyProp": null,
+ "detachedProp": null,
+ "detachedProp2": null,
+ "dynamicProp": 123,
+ "id": "566c5fcf4a7d4aae446a53725703532f",
+ "list": [
+ 1,
+ 2,
+ 3,
+ 4,
+ 5,
+ 6,
+ 7,
+ 8,
+ 9,
+ 10
+ ],
+ "list2": [
+ 1,
+ 10
+ ],
+ "speckle_type": "Speckle.Core.Tests.Unit.Models.BaseTests+SampleObjectBase2"
+ }
+}
diff --git a/tests/Speckle.Sdk.Serialization.Tests/Pipelines/DetachedTests.GetPropertiesExpected_All.verified.json b/tests/Speckle.Sdk.Serialization.Tests/Pipelines/DetachedTests.GetPropertiesExpected_All.verified.json
new file mode 100644
index 00000000..d6a3a342
--- /dev/null
+++ b/tests/Speckle.Sdk.Serialization.Tests/Pipelines/DetachedTests.GetPropertiesExpected_All.verified.json
@@ -0,0 +1,31 @@
+{
+ "5053b39434bf2f35a388fe8e419ca181": {
+ "applicationId": null,
+ "id": "5053b39434bf2f35a388fe8e419ca181",
+ "name": "detachedProp",
+ "speckle_type": "Speckle.Core.Tests.Unit.Models.BaseTests+SamplePropBase"
+ },
+ "54488dc6efa222136302db51c12be359": {
+ "__closure": {
+ "5053b39434bf2f35a388fe8e419ca181": 1
+ },
+ "@prop2": 2,
+ "applicationId": null,
+ "arr": null,
+ "attachedProp": {
+ "applicationId": null,
+ "id": "6e5c34adf929602ce78d559d71f53c01",
+ "name": "attachedProp",
+ "speckle_type": "Speckle.Core.Tests.Unit.Models.BaseTests+SamplePropBase"
+ },
+ "crazyProp": null,
+ "detachedProp": {
+ "referencedId": "5053b39434bf2f35a388fe8e419ca181",
+ "speckle_type": "reference"
+ },
+ "dynamicProp": 123,
+ "id": "54488dc6efa222136302db51c12be359",
+ "list": [],
+ "speckle_type": "Speckle.Core.Tests.Unit.Models.BaseTests+SampleObjectBase"
+ }
+}
diff --git a/tests/Speckle.Sdk.Serialization.Tests/Pipelines/DetachedTests.GetPropertiesExpected_Detached.verified.json b/tests/Speckle.Sdk.Serialization.Tests/Pipelines/DetachedTests.GetPropertiesExpected_Detached.verified.json
new file mode 100644
index 00000000..d6a3a342
--- /dev/null
+++ b/tests/Speckle.Sdk.Serialization.Tests/Pipelines/DetachedTests.GetPropertiesExpected_Detached.verified.json
@@ -0,0 +1,31 @@
+{
+ "5053b39434bf2f35a388fe8e419ca181": {
+ "applicationId": null,
+ "id": "5053b39434bf2f35a388fe8e419ca181",
+ "name": "detachedProp",
+ "speckle_type": "Speckle.Core.Tests.Unit.Models.BaseTests+SamplePropBase"
+ },
+ "54488dc6efa222136302db51c12be359": {
+ "__closure": {
+ "5053b39434bf2f35a388fe8e419ca181": 1
+ },
+ "@prop2": 2,
+ "applicationId": null,
+ "arr": null,
+ "attachedProp": {
+ "applicationId": null,
+ "id": "6e5c34adf929602ce78d559d71f53c01",
+ "name": "attachedProp",
+ "speckle_type": "Speckle.Core.Tests.Unit.Models.BaseTests+SamplePropBase"
+ },
+ "crazyProp": null,
+ "detachedProp": {
+ "referencedId": "5053b39434bf2f35a388fe8e419ca181",
+ "speckle_type": "reference"
+ },
+ "dynamicProp": 123,
+ "id": "54488dc6efa222136302db51c12be359",
+ "list": [],
+ "speckle_type": "Speckle.Core.Tests.Unit.Models.BaseTests+SampleObjectBase"
+ }
+}
diff --git a/tests/Speckle.Sdk.Serialization.Tests/Pipelines/DetachedTests.cs b/tests/Speckle.Sdk.Serialization.Tests/Pipelines/DetachedTests.cs
new file mode 100644
index 00000000..b0d1e47a
--- /dev/null
+++ b/tests/Speckle.Sdk.Serialization.Tests/Pipelines/DetachedTests.cs
@@ -0,0 +1,182 @@
+using Speckle.Objects.Geometry;
+using Speckle.Sdk.Host;
+using Speckle.Sdk.Pipelines.Send;
+
+namespace Speckle.Sdk.Serialization.Tests.Pipelines;
+
+public class DetachedTests
+{
+ private readonly Serializer _sut;
+
+ public DetachedTests()
+ {
+ TypeLoader.ReInitialize(typeof(TestClass).Assembly, typeof(Polyline).Assembly);
+
+ _sut = new();
+ }
+
+ [Fact]
+ public async Task CanSerialize_New_Detached()
+ {
+ var myBase = new SampleObjectBase
+ {
+ ["dynamicProp"] = 123,
+ detachedProp = new SamplePropBase() { name = "detachedProp" },
+ attachedProp = new SamplePropBase() { name = "attachedProp" },
+ };
+
+ IEnumerable result = _sut.Serialize(myBase);
+
+ var objects = result.ToDictionary(x => x.Id, x => x.Json.ToJsonString());
+
+ await VerifyJsonDictionary(objects);
+ }
+
+ [Fact]
+ public async Task GetPropertiesExpected_Detached()
+ {
+ var @myBase = new SampleObjectBase
+ {
+ ["dynamicProp"] = 123,
+ ["@prop2"] = 2,
+ ["__prop3"] = 3,
+ detachedProp = new SamplePropBase() { name = "detachedProp" },
+ attachedProp = new SamplePropBase() { name = "attachedProp" },
+ };
+
+ IEnumerable result = _sut.Serialize(myBase);
+
+ var objects = result.ToDictionary(x => x.Id, x => x.Json.ToJsonString());
+
+ await VerifyJsonDictionary(objects);
+ }
+
+ [Fact]
+ public async Task GetPropertiesExpected_All()
+ {
+ var myBase = new SampleObjectBase
+ {
+ ["dynamicProp"] = 123,
+ ["@prop2"] = 2,
+ ["__prop3"] = 3,
+ detachedProp = new SamplePropBase() { name = "detachedProp" },
+ attachedProp = new SamplePropBase() { name = "attachedProp" },
+ };
+
+ IEnumerable result = _sut.Serialize(myBase);
+
+ var objects = result.ToDictionary(x => x.Id, x => x.Json.ToJsonString());
+
+ await VerifyJsonDictionary(objects);
+ }
+
+ [Fact]
+ public async Task CanSerialize_New_Detached2()
+ {
+ var myBase = new SampleObjectBase2
+ {
+ ["dynamicProp"] = 123,
+ applicationId = "1",
+ detachedProp = new SamplePropBase2()
+ {
+ name = "detachedProp",
+ applicationId = "2",
+ line = new Polyline() { units = "test", value = [1.0, 2.0] },
+ },
+ detachedProp2 = new SamplePropBase2()
+ {
+ name = "detachedProp2",
+ applicationId = "3",
+ line = new Polyline() { units = "test", value = [3.0, 2.0] },
+ },
+ attachedProp = new SamplePropBase2()
+ {
+ name = "attachedProp",
+ applicationId = "4",
+ line = new Polyline() { units = "test", value = [3.0, 4.0] },
+ },
+ };
+
+ IEnumerable result = _sut.Serialize(myBase);
+
+ var objects = result.ToDictionary(x => x.Id, x => x.Json.ToJsonString());
+
+ await VerifyJsonDictionary(objects);
+ }
+
+ [Fact]
+ public async Task CanSerialize_Attached()
+ {
+ var myBase = new SampleObjectBase2
+ {
+ ["dynamicProp"] = 123,
+ applicationId = "1",
+ attachedProp = new SamplePropBase2()
+ {
+ name = "attachedProp",
+ applicationId = "4",
+ line = new Polyline() { units = "test", value = [3.0, 4.0] },
+ },
+ };
+
+ IEnumerable result = _sut.Serialize(myBase);
+
+ var objects = result.ToDictionary(x => x.Id, x => x.Json.ToJsonString());
+
+ await VerifyJsonDictionary(objects);
+ }
+
+ [Fact]
+ public async Task CanSerialize_Attached_2()
+ {
+ var myBase = new SampleObjectBase2
+ {
+ ["dynamicProp"] = 123,
+ applicationId = "1",
+ attachedProp = new SamplePropBase2() { name = "attachedProp", applicationId = "4" },
+ };
+
+ IEnumerable result = _sut.Serialize(myBase);
+
+ var objects = result.ToDictionary(x => x.Id, x => x.Json.ToJsonString());
+
+ await VerifyJsonDictionary(objects);
+ }
+
+ [Fact]
+ public async Task CanSerialize_New_Detached_With_DataChunks()
+ {
+ var myBase = new SampleObjectBase2
+ {
+ ["dynamicProp"] = 123,
+ applicationId = "1",
+ list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
+ list2 = [1, 10],
+ };
+
+ IEnumerable result = _sut.Serialize(myBase);
+
+ var objects = result.ToDictionary(x => x.Id, x => x.Json.ToJsonString());
+
+ await VerifyJsonDictionary(objects);
+ }
+
+ [Fact]
+ public async Task CanSerialize_New_Detached_With_DataChunks2()
+ {
+ var myBase = new SampleObjectBase2
+ {
+ ["dynamicProp"] = 123,
+ applicationId = "1",
+ list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
+ list2 = [1, 10],
+ arr = [1, 10],
+ };
+
+ IEnumerable result = _sut.Serialize(myBase);
+
+ var objects = result.ToDictionary(x => x.Id, x => x.Json.ToJsonString());
+
+ await VerifyJsonDictionary(objects);
+ }
+}
diff --git a/tests/Speckle.Sdk.Serialization.Tests/AdditionalCancellationTests.Cancellation_Traversal.verified.json b/tests/Speckle.Sdk.Serialization.Tests/Send2/AdditionalCancellationTests.Cancellation_Traversal.verified.json
similarity index 100%
rename from tests/Speckle.Sdk.Serialization.Tests/AdditionalCancellationTests.Cancellation_Traversal.verified.json
rename to tests/Speckle.Sdk.Serialization.Tests/Send2/AdditionalCancellationTests.Cancellation_Traversal.verified.json
diff --git a/tests/Speckle.Sdk.Serialization.Tests/AdditionalCancellationTests.cs b/tests/Speckle.Sdk.Serialization.Tests/Send2/AdditionalCancellationTests.cs
similarity index 100%
rename from tests/Speckle.Sdk.Serialization.Tests/AdditionalCancellationTests.cs
rename to tests/Speckle.Sdk.Serialization.Tests/Send2/AdditionalCancellationTests.cs
diff --git a/tests/Speckle.Sdk.Serialization.Tests/CancellationSqLiteJsonCacheManager.cs b/tests/Speckle.Sdk.Serialization.Tests/Send2/CancellationSqLiteJsonCacheManager.cs
similarity index 100%
rename from tests/Speckle.Sdk.Serialization.Tests/CancellationSqLiteJsonCacheManager.cs
rename to tests/Speckle.Sdk.Serialization.Tests/Send2/CancellationSqLiteJsonCacheManager.cs
diff --git a/tests/Speckle.Sdk.Serialization.Tests/CancellationTests.Cancellation_Receive_Cache.verified.json b/tests/Speckle.Sdk.Serialization.Tests/Send2/CancellationTests.Cancellation_Receive_Cache.verified.json
similarity index 100%
rename from tests/Speckle.Sdk.Serialization.Tests/CancellationTests.Cancellation_Receive_Cache.verified.json
rename to tests/Speckle.Sdk.Serialization.Tests/Send2/CancellationTests.Cancellation_Receive_Cache.verified.json
diff --git a/tests/Speckle.Sdk.Serialization.Tests/CancellationTests.Cancellation_Receive_Deserialize.verified.json b/tests/Speckle.Sdk.Serialization.Tests/Send2/CancellationTests.Cancellation_Receive_Deserialize.verified.json
similarity index 100%
rename from tests/Speckle.Sdk.Serialization.Tests/CancellationTests.Cancellation_Receive_Deserialize.verified.json
rename to tests/Speckle.Sdk.Serialization.Tests/Send2/CancellationTests.Cancellation_Receive_Deserialize.verified.json
diff --git a/tests/Speckle.Sdk.Serialization.Tests/CancellationTests.Cancellation_Receive_Server.verified.json b/tests/Speckle.Sdk.Serialization.Tests/Send2/CancellationTests.Cancellation_Receive_Server.verified.json
similarity index 100%
rename from tests/Speckle.Sdk.Serialization.Tests/CancellationTests.Cancellation_Receive_Server.verified.json
rename to tests/Speckle.Sdk.Serialization.Tests/Send2/CancellationTests.Cancellation_Receive_Server.verified.json
diff --git a/tests/Speckle.Sdk.Serialization.Tests/CancellationTests.Cancellation_Save_Server.verified.json b/tests/Speckle.Sdk.Serialization.Tests/Send2/CancellationTests.Cancellation_Save_Server.verified.json
similarity index 100%
rename from tests/Speckle.Sdk.Serialization.Tests/CancellationTests.Cancellation_Save_Server.verified.json
rename to tests/Speckle.Sdk.Serialization.Tests/Send2/CancellationTests.Cancellation_Save_Server.verified.json
diff --git a/tests/Speckle.Sdk.Serialization.Tests/CancellationTests.Cancellation_Save_Sqlite.verified.json b/tests/Speckle.Sdk.Serialization.Tests/Send2/CancellationTests.Cancellation_Save_Sqlite.verified.json
similarity index 100%
rename from tests/Speckle.Sdk.Serialization.Tests/CancellationTests.Cancellation_Save_Sqlite.verified.json
rename to tests/Speckle.Sdk.Serialization.Tests/Send2/CancellationTests.Cancellation_Save_Sqlite.verified.json
diff --git a/tests/Speckle.Sdk.Serialization.Tests/CancellationTests.Cancellation_Serialize.verified.json b/tests/Speckle.Sdk.Serialization.Tests/Send2/CancellationTests.Cancellation_Serialize.verified.json
similarity index 100%
rename from tests/Speckle.Sdk.Serialization.Tests/CancellationTests.Cancellation_Serialize.verified.json
rename to tests/Speckle.Sdk.Serialization.Tests/Send2/CancellationTests.Cancellation_Serialize.verified.json
diff --git a/tests/Speckle.Sdk.Serialization.Tests/CancellationTests.cs b/tests/Speckle.Sdk.Serialization.Tests/Send2/CancellationTests.cs
similarity index 100%
rename from tests/Speckle.Sdk.Serialization.Tests/CancellationTests.cs
rename to tests/Speckle.Sdk.Serialization.Tests/Send2/CancellationTests.cs
diff --git a/tests/Speckle.Sdk.Serialization.Tests/ClosureParserTests.cs b/tests/Speckle.Sdk.Serialization.Tests/Send2/ClosureParserTests.cs
similarity index 100%
rename from tests/Speckle.Sdk.Serialization.Tests/ClosureParserTests.cs
rename to tests/Speckle.Sdk.Serialization.Tests/Send2/ClosureParserTests.cs
diff --git a/tests/Speckle.Sdk.Serialization.Tests/DataObjectTests.ValidateDataObject_type=Speckle.Objects.Data.ArcgisObject.verified.json b/tests/Speckle.Sdk.Serialization.Tests/Send2/DataObjectTests.ValidateDataObject_type=Speckle.Objects.Data.ArcgisObject.verified.json
similarity index 100%
rename from tests/Speckle.Sdk.Serialization.Tests/DataObjectTests.ValidateDataObject_type=Speckle.Objects.Data.ArcgisObject.verified.json
rename to tests/Speckle.Sdk.Serialization.Tests/Send2/DataObjectTests.ValidateDataObject_type=Speckle.Objects.Data.ArcgisObject.verified.json
diff --git a/tests/Speckle.Sdk.Serialization.Tests/DataObjectTests.ValidateDataObject_type=Speckle.Objects.Data.ArchicadObject.verified.json b/tests/Speckle.Sdk.Serialization.Tests/Send2/DataObjectTests.ValidateDataObject_type=Speckle.Objects.Data.ArchicadObject.verified.json
similarity index 100%
rename from tests/Speckle.Sdk.Serialization.Tests/DataObjectTests.ValidateDataObject_type=Speckle.Objects.Data.ArchicadObject.verified.json
rename to tests/Speckle.Sdk.Serialization.Tests/Send2/DataObjectTests.ValidateDataObject_type=Speckle.Objects.Data.ArchicadObject.verified.json
diff --git a/tests/Speckle.Sdk.Serialization.Tests/DataObjectTests.ValidateDataObject_type=Speckle.Objects.Data.Civil3dObject.verified.json b/tests/Speckle.Sdk.Serialization.Tests/Send2/DataObjectTests.ValidateDataObject_type=Speckle.Objects.Data.Civil3dObject.verified.json
similarity index 100%
rename from tests/Speckle.Sdk.Serialization.Tests/DataObjectTests.ValidateDataObject_type=Speckle.Objects.Data.Civil3dObject.verified.json
rename to tests/Speckle.Sdk.Serialization.Tests/Send2/DataObjectTests.ValidateDataObject_type=Speckle.Objects.Data.Civil3dObject.verified.json
diff --git a/tests/Speckle.Sdk.Serialization.Tests/DataObjectTests.ValidateDataObject_type=Speckle.Objects.Data.DataObject.verified.json b/tests/Speckle.Sdk.Serialization.Tests/Send2/DataObjectTests.ValidateDataObject_type=Speckle.Objects.Data.DataObject.verified.json
similarity index 100%
rename from tests/Speckle.Sdk.Serialization.Tests/DataObjectTests.ValidateDataObject_type=Speckle.Objects.Data.DataObject.verified.json
rename to tests/Speckle.Sdk.Serialization.Tests/Send2/DataObjectTests.ValidateDataObject_type=Speckle.Objects.Data.DataObject.verified.json
diff --git a/tests/Speckle.Sdk.Serialization.Tests/DataObjectTests.ValidateDataObject_type=Speckle.Objects.Data.EtabsObject.verified.json b/tests/Speckle.Sdk.Serialization.Tests/Send2/DataObjectTests.ValidateDataObject_type=Speckle.Objects.Data.EtabsObject.verified.json
similarity index 100%
rename from tests/Speckle.Sdk.Serialization.Tests/DataObjectTests.ValidateDataObject_type=Speckle.Objects.Data.EtabsObject.verified.json
rename to tests/Speckle.Sdk.Serialization.Tests/Send2/DataObjectTests.ValidateDataObject_type=Speckle.Objects.Data.EtabsObject.verified.json
diff --git a/tests/Speckle.Sdk.Serialization.Tests/DataObjectTests.ValidateDataObject_type=Speckle.Objects.Data.NavisworksObject.verified.json b/tests/Speckle.Sdk.Serialization.Tests/Send2/DataObjectTests.ValidateDataObject_type=Speckle.Objects.Data.NavisworksObject.verified.json
similarity index 100%
rename from tests/Speckle.Sdk.Serialization.Tests/DataObjectTests.ValidateDataObject_type=Speckle.Objects.Data.NavisworksObject.verified.json
rename to tests/Speckle.Sdk.Serialization.Tests/Send2/DataObjectTests.ValidateDataObject_type=Speckle.Objects.Data.NavisworksObject.verified.json
diff --git a/tests/Speckle.Sdk.Serialization.Tests/DataObjectTests.ValidateDataObject_type=Speckle.Objects.Data.RevitObject.verified.json b/tests/Speckle.Sdk.Serialization.Tests/Send2/DataObjectTests.ValidateDataObject_type=Speckle.Objects.Data.RevitObject.verified.json
similarity index 100%
rename from tests/Speckle.Sdk.Serialization.Tests/DataObjectTests.ValidateDataObject_type=Speckle.Objects.Data.RevitObject.verified.json
rename to tests/Speckle.Sdk.Serialization.Tests/Send2/DataObjectTests.ValidateDataObject_type=Speckle.Objects.Data.RevitObject.verified.json
diff --git a/tests/Speckle.Sdk.Serialization.Tests/DataObjectTests.ValidateDataObject_type=Speckle.Objects.Data.TeklaObject.verified.json b/tests/Speckle.Sdk.Serialization.Tests/Send2/DataObjectTests.ValidateDataObject_type=Speckle.Objects.Data.TeklaObject.verified.json
similarity index 100%
rename from tests/Speckle.Sdk.Serialization.Tests/DataObjectTests.ValidateDataObject_type=Speckle.Objects.Data.TeklaObject.verified.json
rename to tests/Speckle.Sdk.Serialization.Tests/Send2/DataObjectTests.ValidateDataObject_type=Speckle.Objects.Data.TeklaObject.verified.json
diff --git a/tests/Speckle.Sdk.Serialization.Tests/DataObjectTests.cs b/tests/Speckle.Sdk.Serialization.Tests/Send2/DataObjectTests.cs
similarity index 100%
rename from tests/Speckle.Sdk.Serialization.Tests/DataObjectTests.cs
rename to tests/Speckle.Sdk.Serialization.Tests/Send2/DataObjectTests.cs
diff --git a/tests/Speckle.Sdk.Serialization.Tests/DetachedTests.CanSerialize_Attached.verified.json b/tests/Speckle.Sdk.Serialization.Tests/Send2/DetachedTests.CanSerialize_Attached.verified.json
similarity index 100%
rename from tests/Speckle.Sdk.Serialization.Tests/DetachedTests.CanSerialize_Attached.verified.json
rename to tests/Speckle.Sdk.Serialization.Tests/Send2/DetachedTests.CanSerialize_Attached.verified.json
diff --git a/tests/Speckle.Sdk.Serialization.Tests/DetachedTests.CanSerialize_Attached_2.verified.json b/tests/Speckle.Sdk.Serialization.Tests/Send2/DetachedTests.CanSerialize_Attached_2.verified.json
similarity index 100%
rename from tests/Speckle.Sdk.Serialization.Tests/DetachedTests.CanSerialize_Attached_2.verified.json
rename to tests/Speckle.Sdk.Serialization.Tests/Send2/DetachedTests.CanSerialize_Attached_2.verified.json
diff --git a/tests/Speckle.Sdk.Serialization.Tests/DetachedTests.CanSerialize_New_Detached.verified.json b/tests/Speckle.Sdk.Serialization.Tests/Send2/DetachedTests.CanSerialize_New_Detached.verified.json
similarity index 100%
rename from tests/Speckle.Sdk.Serialization.Tests/DetachedTests.CanSerialize_New_Detached.verified.json
rename to tests/Speckle.Sdk.Serialization.Tests/Send2/DetachedTests.CanSerialize_New_Detached.verified.json
diff --git a/tests/Speckle.Sdk.Serialization.Tests/DetachedTests.CanSerialize_New_Detached2.verified.json b/tests/Speckle.Sdk.Serialization.Tests/Send2/DetachedTests.CanSerialize_New_Detached2.verified.json
similarity index 100%
rename from tests/Speckle.Sdk.Serialization.Tests/DetachedTests.CanSerialize_New_Detached2.verified.json
rename to tests/Speckle.Sdk.Serialization.Tests/Send2/DetachedTests.CanSerialize_New_Detached2.verified.json
diff --git a/tests/Speckle.Sdk.Serialization.Tests/DetachedTests.CanSerialize_New_Detached_With_DataChunks2.verified.json b/tests/Speckle.Sdk.Serialization.Tests/Send2/DetachedTests.CanSerialize_New_Detached_With_DataChunks2.verified.json
similarity index 100%
rename from tests/Speckle.Sdk.Serialization.Tests/DetachedTests.CanSerialize_New_Detached_With_DataChunks2.verified.json
rename to tests/Speckle.Sdk.Serialization.Tests/Send2/DetachedTests.CanSerialize_New_Detached_With_DataChunks2.verified.json
diff --git a/tests/Speckle.Sdk.Serialization.Tests/DetachedTests.CanSerialize_Old_Detached.verified.json b/tests/Speckle.Sdk.Serialization.Tests/Send2/DetachedTests.CanSerialize_Old_Detached.verified.json
similarity index 100%
rename from tests/Speckle.Sdk.Serialization.Tests/DetachedTests.CanSerialize_Old_Detached.verified.json
rename to tests/Speckle.Sdk.Serialization.Tests/Send2/DetachedTests.CanSerialize_Old_Detached.verified.json
diff --git a/tests/Speckle.Sdk.Serialization.Tests/DetachedTests.GetPropertiesExpected_All.verified.json b/tests/Speckle.Sdk.Serialization.Tests/Send2/DetachedTests.GetPropertiesExpected_All.verified.json
similarity index 100%
rename from tests/Speckle.Sdk.Serialization.Tests/DetachedTests.GetPropertiesExpected_All.verified.json
rename to tests/Speckle.Sdk.Serialization.Tests/Send2/DetachedTests.GetPropertiesExpected_All.verified.json
diff --git a/tests/Speckle.Sdk.Serialization.Tests/DetachedTests.GetPropertiesExpected_Detached.verified.json b/tests/Speckle.Sdk.Serialization.Tests/Send2/DetachedTests.GetPropertiesExpected_Detached.verified.json
similarity index 100%
rename from tests/Speckle.Sdk.Serialization.Tests/DetachedTests.GetPropertiesExpected_Detached.verified.json
rename to tests/Speckle.Sdk.Serialization.Tests/Send2/DetachedTests.GetPropertiesExpected_Detached.verified.json
diff --git a/tests/Speckle.Sdk.Serialization.Tests/DetachedTests.cs b/tests/Speckle.Sdk.Serialization.Tests/Send2/DetachedTests.cs
similarity index 100%
rename from tests/Speckle.Sdk.Serialization.Tests/DetachedTests.cs
rename to tests/Speckle.Sdk.Serialization.Tests/Send2/DetachedTests.cs
diff --git a/tests/Speckle.Sdk.Serialization.Tests/DummyCancellationSqLiteSendManager.cs b/tests/Speckle.Sdk.Serialization.Tests/Send2/DummyCancellationSqLiteSendManager.cs
similarity index 100%
rename from tests/Speckle.Sdk.Serialization.Tests/DummyCancellationSqLiteSendManager.cs
rename to tests/Speckle.Sdk.Serialization.Tests/Send2/DummyCancellationSqLiteSendManager.cs
diff --git a/tests/Speckle.Sdk.Serialization.Tests/ExceptionTests.Test_Exceptions_Cache.verified.json b/tests/Speckle.Sdk.Serialization.Tests/Send2/ExceptionTests.Test_Exceptions_Cache.verified.json
similarity index 100%
rename from tests/Speckle.Sdk.Serialization.Tests/ExceptionTests.Test_Exceptions_Cache.verified.json
rename to tests/Speckle.Sdk.Serialization.Tests/Send2/ExceptionTests.Test_Exceptions_Cache.verified.json
diff --git a/tests/Speckle.Sdk.Serialization.Tests/ExceptionTests.Test_Exceptions_Cache_ExceptionsAfter_10.verified.json b/tests/Speckle.Sdk.Serialization.Tests/Send2/ExceptionTests.Test_Exceptions_Cache_ExceptionsAfter_10.verified.json
similarity index 100%
rename from tests/Speckle.Sdk.Serialization.Tests/ExceptionTests.Test_Exceptions_Cache_ExceptionsAfter_10.verified.json
rename to tests/Speckle.Sdk.Serialization.Tests/Send2/ExceptionTests.Test_Exceptions_Cache_ExceptionsAfter_10.verified.json
diff --git a/tests/Speckle.Sdk.Serialization.Tests/ExceptionTests.Test_Exceptions_Receive_Cache_fileName=False.verified.json b/tests/Speckle.Sdk.Serialization.Tests/Send2/ExceptionTests.Test_Exceptions_Receive_Cache_fileName=False.verified.json
similarity index 100%
rename from tests/Speckle.Sdk.Serialization.Tests/ExceptionTests.Test_Exceptions_Receive_Cache_fileName=False.verified.json
rename to tests/Speckle.Sdk.Serialization.Tests/Send2/ExceptionTests.Test_Exceptions_Receive_Cache_fileName=False.verified.json
diff --git a/tests/Speckle.Sdk.Serialization.Tests/ExceptionTests.Test_Exceptions_Receive_Cache_fileName=True.verified.json b/tests/Speckle.Sdk.Serialization.Tests/Send2/ExceptionTests.Test_Exceptions_Receive_Cache_fileName=True.verified.json
similarity index 100%
rename from tests/Speckle.Sdk.Serialization.Tests/ExceptionTests.Test_Exceptions_Receive_Cache_fileName=True.verified.json
rename to tests/Speckle.Sdk.Serialization.Tests/Send2/ExceptionTests.Test_Exceptions_Receive_Cache_fileName=True.verified.json
diff --git a/tests/Speckle.Sdk.Serialization.Tests/ExceptionTests.Test_Exceptions_Receive_Server.verified.json b/tests/Speckle.Sdk.Serialization.Tests/Send2/ExceptionTests.Test_Exceptions_Receive_Server.verified.json
similarity index 100%
rename from tests/Speckle.Sdk.Serialization.Tests/ExceptionTests.Test_Exceptions_Receive_Server.verified.json
rename to tests/Speckle.Sdk.Serialization.Tests/Send2/ExceptionTests.Test_Exceptions_Receive_Server.verified.json
diff --git a/tests/Speckle.Sdk.Serialization.Tests/ExceptionTests.Test_Exceptions_Receive_Server_Skip_Both.verified.json b/tests/Speckle.Sdk.Serialization.Tests/Send2/ExceptionTests.Test_Exceptions_Receive_Server_Skip_Both.verified.json
similarity index 100%
rename from tests/Speckle.Sdk.Serialization.Tests/ExceptionTests.Test_Exceptions_Receive_Server_Skip_Both.verified.json
rename to tests/Speckle.Sdk.Serialization.Tests/Send2/ExceptionTests.Test_Exceptions_Receive_Server_Skip_Both.verified.json
diff --git a/tests/Speckle.Sdk.Serialization.Tests/ExceptionTests.Test_Exceptions_Upload.verified.json b/tests/Speckle.Sdk.Serialization.Tests/Send2/ExceptionTests.Test_Exceptions_Upload.verified.json
similarity index 100%
rename from tests/Speckle.Sdk.Serialization.Tests/ExceptionTests.Test_Exceptions_Upload.verified.json
rename to tests/Speckle.Sdk.Serialization.Tests/Send2/ExceptionTests.Test_Exceptions_Upload.verified.json
diff --git a/tests/Speckle.Sdk.Serialization.Tests/ExceptionTests.cs b/tests/Speckle.Sdk.Serialization.Tests/Send2/ExceptionTests.cs
similarity index 100%
rename from tests/Speckle.Sdk.Serialization.Tests/ExceptionTests.cs
rename to tests/Speckle.Sdk.Serialization.Tests/Send2/ExceptionTests.cs
diff --git a/tests/Speckle.Sdk.Serialization.Tests/ExplicitInterfaceTests.Test_ExtractAllProperties.verified.json b/tests/Speckle.Sdk.Serialization.Tests/Send2/ExplicitInterfaceTests.Test_ExtractAllProperties.verified.json
similarity index 100%
rename from tests/Speckle.Sdk.Serialization.Tests/ExplicitInterfaceTests.Test_ExtractAllProperties.verified.json
rename to tests/Speckle.Sdk.Serialization.Tests/Send2/ExplicitInterfaceTests.Test_ExtractAllProperties.verified.json
diff --git a/tests/Speckle.Sdk.Serialization.Tests/ExplicitInterfaceTests.Test_Json.verified.json b/tests/Speckle.Sdk.Serialization.Tests/Send2/ExplicitInterfaceTests.Test_Json.verified.json
similarity index 100%
rename from tests/Speckle.Sdk.Serialization.Tests/ExplicitInterfaceTests.Test_Json.verified.json
rename to tests/Speckle.Sdk.Serialization.Tests/Send2/ExplicitInterfaceTests.Test_Json.verified.json
diff --git a/tests/Speckle.Sdk.Serialization.Tests/ExplicitInterfaceTests.cs b/tests/Speckle.Sdk.Serialization.Tests/Send2/ExplicitInterfaceTests.cs
similarity index 100%
rename from tests/Speckle.Sdk.Serialization.Tests/ExplicitInterfaceTests.cs
rename to tests/Speckle.Sdk.Serialization.Tests/Send2/ExplicitInterfaceTests.cs
diff --git a/tests/Speckle.Sdk.Serialization.Tests/ExternalIdTests.ExternalIdTest_Detached.verified.json b/tests/Speckle.Sdk.Serialization.Tests/Send2/ExternalIdTests.ExternalIdTest_Detached.verified.json
similarity index 100%
rename from tests/Speckle.Sdk.Serialization.Tests/ExternalIdTests.ExternalIdTest_Detached.verified.json
rename to tests/Speckle.Sdk.Serialization.Tests/Send2/ExternalIdTests.ExternalIdTest_Detached.verified.json
diff --git a/tests/Speckle.Sdk.Serialization.Tests/ExternalIdTests.ExternalIdTest_Detached_Nested.verified.json b/tests/Speckle.Sdk.Serialization.Tests/Send2/ExternalIdTests.ExternalIdTest_Detached_Nested.verified.json
similarity index 100%
rename from tests/Speckle.Sdk.Serialization.Tests/ExternalIdTests.ExternalIdTest_Detached_Nested.verified.json
rename to tests/Speckle.Sdk.Serialization.Tests/Send2/ExternalIdTests.ExternalIdTest_Detached_Nested.verified.json
diff --git a/tests/Speckle.Sdk.Serialization.Tests/ExternalIdTests.ExternalIdTest_Detached_Nested_More.verified.json b/tests/Speckle.Sdk.Serialization.Tests/Send2/ExternalIdTests.ExternalIdTest_Detached_Nested_More.verified.json
similarity index 100%
rename from tests/Speckle.Sdk.Serialization.Tests/ExternalIdTests.ExternalIdTest_Detached_Nested_More.verified.json
rename to tests/Speckle.Sdk.Serialization.Tests/Send2/ExternalIdTests.ExternalIdTest_Detached_Nested_More.verified.json
diff --git a/tests/Speckle.Sdk.Serialization.Tests/ExternalIdTests.ExternalIdTest_Detached_Nested_More_Too.verified.json b/tests/Speckle.Sdk.Serialization.Tests/Send2/ExternalIdTests.ExternalIdTest_Detached_Nested_More_Too.verified.json
similarity index 100%
rename from tests/Speckle.Sdk.Serialization.Tests/ExternalIdTests.ExternalIdTest_Detached_Nested_More_Too.verified.json
rename to tests/Speckle.Sdk.Serialization.Tests/Send2/ExternalIdTests.ExternalIdTest_Detached_Nested_More_Too.verified.json
diff --git a/tests/Speckle.Sdk.Serialization.Tests/ExternalIdTests.cs b/tests/Speckle.Sdk.Serialization.Tests/Send2/ExternalIdTests.cs
similarity index 100%
rename from tests/Speckle.Sdk.Serialization.Tests/ExternalIdTests.cs
rename to tests/Speckle.Sdk.Serialization.Tests/Send2/ExternalIdTests.cs
diff --git a/tests/Speckle.Sdk.Serialization.Tests/Framework/ExceptionSendCacheManager.cs b/tests/Speckle.Sdk.Serialization.Tests/Send2/Framework/ExceptionSendCacheManager.cs
similarity index 100%
rename from tests/Speckle.Sdk.Serialization.Tests/Framework/ExceptionSendCacheManager.cs
rename to tests/Speckle.Sdk.Serialization.Tests/Send2/Framework/ExceptionSendCacheManager.cs
diff --git a/tests/Speckle.Sdk.Serialization.Tests/Framework/ExceptionServerObjectManager.cs b/tests/Speckle.Sdk.Serialization.Tests/Send2/Framework/ExceptionServerObjectManager.cs
similarity index 100%
rename from tests/Speckle.Sdk.Serialization.Tests/Framework/ExceptionServerObjectManager.cs
rename to tests/Speckle.Sdk.Serialization.Tests/Send2/Framework/ExceptionServerObjectManager.cs
diff --git a/tests/Speckle.Sdk.Serialization.Tests/Framework/TestFileManager.cs b/tests/Speckle.Sdk.Serialization.Tests/Send2/Framework/TestFileManager.cs
similarity index 100%
rename from tests/Speckle.Sdk.Serialization.Tests/Framework/TestFileManager.cs
rename to tests/Speckle.Sdk.Serialization.Tests/Send2/Framework/TestFileManager.cs
diff --git a/tests/Speckle.Sdk.Serialization.Tests/Framework/TestTransport.cs b/tests/Speckle.Sdk.Serialization.Tests/Send2/Framework/TestTransport.cs
similarity index 100%
rename from tests/Speckle.Sdk.Serialization.Tests/Framework/TestTransport.cs
rename to tests/Speckle.Sdk.Serialization.Tests/Send2/Framework/TestTransport.cs
diff --git a/tests/Speckle.Sdk.Serialization.Tests/Framework/TestTransport2.cs b/tests/Speckle.Sdk.Serialization.Tests/Send2/Framework/TestTransport2.cs
similarity index 100%
rename from tests/Speckle.Sdk.Serialization.Tests/Framework/TestTransport2.cs
rename to tests/Speckle.Sdk.Serialization.Tests/Send2/Framework/TestTransport2.cs
diff --git a/tests/Speckle.Sdk.Serialization.Tests/Global.cs b/tests/Speckle.Sdk.Serialization.Tests/Send2/Global.cs
similarity index 100%
rename from tests/Speckle.Sdk.Serialization.Tests/Global.cs
rename to tests/Speckle.Sdk.Serialization.Tests/Send2/Global.cs
diff --git a/tests/Speckle.Sdk.Serialization.Tests/Module.cs b/tests/Speckle.Sdk.Serialization.Tests/Send2/Module.cs
similarity index 100%
rename from tests/Speckle.Sdk.Serialization.Tests/Module.cs
rename to tests/Speckle.Sdk.Serialization.Tests/Send2/Module.cs
diff --git a/tests/Speckle.Sdk.Serialization.Tests/RevitObject.json.gz b/tests/Speckle.Sdk.Serialization.Tests/Send2/RevitObject.json.gz
similarity index 100%
rename from tests/Speckle.Sdk.Serialization.Tests/RevitObject.json.gz
rename to tests/Speckle.Sdk.Serialization.Tests/Send2/RevitObject.json.gz
diff --git a/tests/Speckle.Sdk.Serialization.Tests/SerializationTests.cs b/tests/Speckle.Sdk.Serialization.Tests/Send2/SerializationTests.cs
similarity index 100%
rename from tests/Speckle.Sdk.Serialization.Tests/SerializationTests.cs
rename to tests/Speckle.Sdk.Serialization.Tests/Send2/SerializationTests.cs
diff --git a/tests/Speckle.Sdk.Serialization.Tests/SerializationTypeTests.cs b/tests/Speckle.Sdk.Serialization.Tests/Send2/SerializationTypeTests.cs
similarity index 100%
rename from tests/Speckle.Sdk.Serialization.Tests/SerializationTypeTests.cs
rename to tests/Speckle.Sdk.Serialization.Tests/Send2/SerializationTypeTests.cs
diff --git a/tests/Speckle.Sdk.Serialization.Tests/ServerObjectManagerTests.DownloadObjects.verified.json b/tests/Speckle.Sdk.Serialization.Tests/Send2/ServerObjectManagerTests.DownloadObjects.verified.json
similarity index 100%
rename from tests/Speckle.Sdk.Serialization.Tests/ServerObjectManagerTests.DownloadObjects.verified.json
rename to tests/Speckle.Sdk.Serialization.Tests/Send2/ServerObjectManagerTests.DownloadObjects.verified.json
diff --git a/tests/Speckle.Sdk.Serialization.Tests/ServerObjectManagerTests.DownloadSingleObject.verified.json b/tests/Speckle.Sdk.Serialization.Tests/Send2/ServerObjectManagerTests.DownloadSingleObject.verified.json
similarity index 100%
rename from tests/Speckle.Sdk.Serialization.Tests/ServerObjectManagerTests.DownloadSingleObject.verified.json
rename to tests/Speckle.Sdk.Serialization.Tests/Send2/ServerObjectManagerTests.DownloadSingleObject.verified.json
diff --git a/tests/Speckle.Sdk.Serialization.Tests/ServerObjectManagerTests.HasObjects.verified.json b/tests/Speckle.Sdk.Serialization.Tests/Send2/ServerObjectManagerTests.HasObjects.verified.json
similarity index 100%
rename from tests/Speckle.Sdk.Serialization.Tests/ServerObjectManagerTests.HasObjects.verified.json
rename to tests/Speckle.Sdk.Serialization.Tests/Send2/ServerObjectManagerTests.HasObjects.verified.json
diff --git a/tests/Speckle.Sdk.Serialization.Tests/ServerObjectManagerTests.cs b/tests/Speckle.Sdk.Serialization.Tests/Send2/ServerObjectManagerTests.cs
similarity index 100%
rename from tests/Speckle.Sdk.Serialization.Tests/ServerObjectManagerTests.cs
rename to tests/Speckle.Sdk.Serialization.Tests/Send2/ServerObjectManagerTests.cs
diff --git a/tests/Speckle.Sdk.Serialization.Tests/Speckle.Sdk.Serialization.Tests.csproj b/tests/Speckle.Sdk.Serialization.Tests/Speckle.Sdk.Serialization.Tests.csproj
index 3afc3ddd..62f7e907 100644
--- a/tests/Speckle.Sdk.Serialization.Tests/Speckle.Sdk.Serialization.Tests.csproj
+++ b/tests/Speckle.Sdk.Serialization.Tests/Speckle.Sdk.Serialization.Tests.csproj
@@ -19,6 +19,6 @@
-
+
diff --git a/tests/Speckle.Sdk.Serialization.Tests/packages.lock.json b/tests/Speckle.Sdk.Serialization.Tests/packages.lock.json
index 5391cfa7..576bcdc9 100644
--- a/tests/Speckle.Sdk.Serialization.Tests/packages.lock.json
+++ b/tests/Speckle.Sdk.Serialization.Tests/packages.lock.json
@@ -300,8 +300,8 @@
"dependencies": {
"GraphQL.Client": "[6.1.0, )",
"Microsoft.Data.Sqlite": "[10.0.0, )",
- "Microsoft.Extensions.DependencyInjection": "[10.0.0, )",
"Microsoft.Extensions.Logging": "[10.0.0, )",
+ "Microsoft.Extensions.ObjectPool": "[10.0.0, )",
"Speckle.DoubleNumerics": "[4.1.0, )",
"Speckle.Newtonsoft.Json": "[13.0.2, )",
"Speckle.Sdk.Dependencies": "[1.0.0, )"
@@ -361,6 +361,12 @@
"Microsoft.Extensions.Options": "10.0.0"
}
},
+ "Microsoft.Extensions.ObjectPool": {
+ "type": "CentralTransitive",
+ "requested": "[9.0.4, )",
+ "resolved": "10.0.0",
+ "contentHash": "bpeCq0IYmVLACyEUMzFIOQX+zZUElG1t+nu1lSxthe7B+1oNYking7b91305+jNB6iwojp9fqTY9O+Nh7ULQxg=="
+ },
"Speckle.DoubleNumerics": {
"type": "CentralTransitive",
"requested": "[4.1.0, )",
diff --git a/tests/Speckle.Sdk.Testing/packages.lock.json b/tests/Speckle.Sdk.Testing/packages.lock.json
index 764913b1..07a369d1 100644
--- a/tests/Speckle.Sdk.Testing/packages.lock.json
+++ b/tests/Speckle.Sdk.Testing/packages.lock.json
@@ -240,8 +240,8 @@
"dependencies": {
"GraphQL.Client": "[6.1.0, )",
"Microsoft.Data.Sqlite": "[10.0.0, )",
- "Microsoft.Extensions.DependencyInjection": "[10.0.0, )",
"Microsoft.Extensions.Logging": "[10.0.0, )",
+ "Microsoft.Extensions.ObjectPool": "[10.0.0, )",
"Speckle.DoubleNumerics": "[4.1.0, )",
"Speckle.Newtonsoft.Json": "[13.0.2, )",
"Speckle.Sdk.Dependencies": "[1.0.0, )"
@@ -292,6 +292,12 @@
"Microsoft.Extensions.Options": "10.0.0"
}
},
+ "Microsoft.Extensions.ObjectPool": {
+ "type": "CentralTransitive",
+ "requested": "[9.0.4, )",
+ "resolved": "10.0.0",
+ "contentHash": "bpeCq0IYmVLACyEUMzFIOQX+zZUElG1t+nu1lSxthe7B+1oNYking7b91305+jNB6iwojp9fqTY9O+Nh7ULQxg=="
+ },
"Speckle.DoubleNumerics": {
"type": "CentralTransitive",
"requested": "[4.1.0, )",
@@ -544,8 +550,8 @@
"dependencies": {
"GraphQL.Client": "[6.0.0, )",
"Microsoft.Data.Sqlite": "[7.0.5, )",
- "Microsoft.Extensions.DependencyInjection": "[8.0.0, )",
"Microsoft.Extensions.Logging": "[8.0.0, )",
+ "Microsoft.Extensions.ObjectPool": "[8.0.0, )",
"Speckle.DoubleNumerics": "[4.1.0, )",
"Speckle.Newtonsoft.Json": "[13.0.2, )",
"Speckle.Sdk.Dependencies": "[1.0.0, )"
@@ -595,6 +601,12 @@
"Microsoft.Extensions.Options": "8.0.0"
}
},
+ "Microsoft.Extensions.ObjectPool": {
+ "type": "CentralTransitive",
+ "requested": "[9.0.4, )",
+ "resolved": "8.0.0",
+ "contentHash": "4pm+XgxSukskwjzDDfSjG4KNUIOdFF2VaqZZDtTzoyQMOVSnlV6ZM8a9aVu5dg9LVZTB//utzSc8fOi0b0Mb2Q=="
+ },
"Speckle.DoubleNumerics": {
"type": "CentralTransitive",
"requested": "[4.1.0, )",
diff --git a/tests/Speckle.Sdk.Tests.Integration/Api/GraphQL/Resources/ProjectResourceExceptionalTests.cs b/tests/Speckle.Sdk.Tests.Integration/Api/GraphQL/Resources/ProjectResourceExceptionalTests.cs
index 9bf8e835..208d7574 100644
--- a/tests/Speckle.Sdk.Tests.Integration/Api/GraphQL/Resources/ProjectResourceExceptionalTests.cs
+++ b/tests/Speckle.Sdk.Tests.Integration/Api/GraphQL/Resources/ProjectResourceExceptionalTests.cs
@@ -130,7 +130,10 @@ public async Task ProjectDelete_NonExistentProject()
await Sut.Delete(_testProject.id);
var ex = await Assert.ThrowsAsync(async () => _ = await Sut.Get(_testProject.id));
- ex.InnerExceptions.Single().Should().BeOfType();
+ Assert.Contains(
+ ex.InnerExceptions[0].GetType(),
+ new HashSet { typeof(SpeckleGraphQLStreamNotFoundException), typeof(SpeckleGraphQLForbiddenException) }
+ );
}
[Fact]
diff --git a/tests/Speckle.Sdk.Tests.Integration/Pipelines/Send/SendPipelineTests.SendConsistency.verified.txt b/tests/Speckle.Sdk.Tests.Integration/Pipelines/Send/SendPipelineTests.SendConsistency.verified.txt
new file mode 100644
index 00000000..dd31cc9b
--- /dev/null
+++ b/tests/Speckle.Sdk.Tests.Integration/Pipelines/Send/SendPipelineTests.SendConsistency.verified.txt
@@ -0,0 +1,2 @@
+8efe64322221afddffb675932ae27345 Base {"applicationId":null,"speckle_type":"Base","mux":"mux","qux":"qux","id":"8efe64322221afddffb675932ae27345"}
+18c55d4b2f2853d43648607cabd4b298 Base {"applicationId":null,"speckle_type":"Base","foo":"foo","bar":"bar","@baz":{"speckle_type":"reference","referencedId":"8efe64322221afddffb675932ae27345"},"id":"18c55d4b2f2853d43648607cabd4b298","__closure":{"8efe64322221afddffb675932ae27345":1}}
diff --git a/tests/Speckle.Sdk.Tests.Integration/Pipelines/Send/SendPipelineTests.SendNdjson.verified.txt b/tests/Speckle.Sdk.Tests.Integration/Pipelines/Send/SendPipelineTests.SendNdjson.verified.txt
new file mode 100644
index 00000000..dd31cc9b
--- /dev/null
+++ b/tests/Speckle.Sdk.Tests.Integration/Pipelines/Send/SendPipelineTests.SendNdjson.verified.txt
@@ -0,0 +1,2 @@
+8efe64322221afddffb675932ae27345 Base {"applicationId":null,"speckle_type":"Base","mux":"mux","qux":"qux","id":"8efe64322221afddffb675932ae27345"}
+18c55d4b2f2853d43648607cabd4b298 Base {"applicationId":null,"speckle_type":"Base","foo":"foo","bar":"bar","@baz":{"speckle_type":"reference","referencedId":"8efe64322221afddffb675932ae27345"},"id":"18c55d4b2f2853d43648607cabd4b298","__closure":{"8efe64322221afddffb675932ae27345":1}}
diff --git a/tests/Speckle.Sdk.Tests.Integration/Pipelines/Send/SendPipelineTests.cs b/tests/Speckle.Sdk.Tests.Integration/Pipelines/Send/SendPipelineTests.cs
new file mode 100644
index 00000000..b00c6d9f
--- /dev/null
+++ b/tests/Speckle.Sdk.Tests.Integration/Pipelines/Send/SendPipelineTests.cs
@@ -0,0 +1,156 @@
+using System.IO.Compression;
+using System.Text;
+using Microsoft.Extensions.DependencyInjection;
+using Speckle.Sdk.Api;
+using Speckle.Sdk.Api.GraphQL.Enums;
+using Speckle.Sdk.Api.GraphQL.Models;
+using Speckle.Sdk.Models;
+using Speckle.Sdk.Pipelines.Progress;
+using Speckle.Sdk.Pipelines.Send;
+
+namespace Speckle.Sdk.Tests.Integration.Pipelines.Send;
+
+[Trait("Server", "Internal")]
+public sealed class SendPipelineTests : IAsyncLifetime
+{
+ private Project _project;
+ private Model _model;
+ private IClient _client;
+
+ private ISendPipelineFactory _factory;
+
+ public async Task InitializeAsync()
+ {
+ var serviceProvider = TestServiceSetup.GetServiceProvider();
+ _factory = serviceProvider.GetRequiredService();
+
+ _client = await Fixtures.SeedUserWithClient();
+ _project = await _client.Project.Create(new("Blobber", "Flobber", ProjectVisibility.Private));
+ _model = await _client.Model.Create(new("Llobber", "Clobber", _project.id));
+ }
+
+ private static string ReadNdJsonGz(FileInfo file)
+ {
+ using FileStream fileStream = file.OpenRead();
+ using GZipStream gzipStream = new GZipStream(fileStream, CompressionMode.Decompress);
+ using StreamReader reader = new StreamReader(gzipStream, Encoding.UTF8);
+ return reader.ReadToEnd();
+ }
+
+ [Fact]
+ public async Task SendNdjson()
+ {
+ Base myObject = Fixtures.GenerateNestedObject();
+
+ var ingestion = await _client.Ingestion.Create(
+ new(_model.id, _project.id, "Starting send test", new("IntegrationTests", "0", null, null))
+ );
+
+ using SendPipeline sender = _factory.CreateInstance(
+ ingestion,
+ _client.Account,
+ new NullProgress(),
+ CancellationToken.None
+ );
+ await sender.Process(myObject);
+ var file = await sender.DiskStore.CompleteAsync();
+
+ string ndjson = ReadNdJsonGz(file.FileInfo);
+
+ await Verify(ndjson);
+ }
+
+ [Fact]
+ public async Task SerializeConsistency()
+ {
+ Base myObject = Fixtures.GenerateNestedObject();
+
+ var ingestion = await _client.Ingestion.Create(
+ new(_model.id, _project.id, "Starting send test", new("IntegrationTests", "0", null, null))
+ );
+
+ //SEND
+ ObjectReference firstSend;
+ using (
+ SendPipeline sender = _factory.CreateInstance(
+ ingestion,
+ _client.Account,
+ new NullProgress(),
+ CancellationToken.None
+ )
+ )
+ {
+ firstSend = await sender.Process(myObject);
+ await sender.WaitForUpload();
+ }
+
+ var secondIngestion = await _client.Ingestion.Create(
+ new(_model.id, _project.id, "Starting again", new("IntegrationTests", "0", null, null))
+ );
+
+ //SEND AGAIN!
+ ObjectReference secondSend;
+ using (
+ SendPipeline sender = _factory.CreateInstance(
+ secondIngestion,
+ _client.Account,
+ new NullProgress(),
+ CancellationToken.None
+ )
+ )
+ {
+ secondSend = await sender.Process(myObject);
+ await sender.WaitForUpload();
+ }
+
+ Assert.Equal(firstSend.referencedId, secondSend.referencedId);
+ }
+
+ [Fact]
+ public async Task SerializeInvalidDataThrows()
+ {
+ Base myObject = Fixtures.GenerateNestedObject();
+ myObject["invalidProp"] = new StringBuilder(); //Serializer does not support serializing this type
+
+ var ingestion = await _client.Ingestion.Create(
+ new(_model.id, _project.id, "Starting send test", new("IntegrationTests", "0", null, null))
+ );
+
+ await Assert.ThrowsAsync(async () =>
+ {
+ using SendPipeline sender = _factory.CreateInstance(
+ ingestion,
+ _client.Account,
+ new NullProgress(),
+ CancellationToken.None
+ );
+ await sender.Process(myObject);
+ await sender.WaitForUpload();
+ });
+ }
+
+ [Fact]
+ public async Task SendNoIngestionThrows()
+ {
+ Base myObject = Fixtures.GenerateNestedObject();
+
+ await Assert.ThrowsAsync(async () =>
+ {
+ using var sender = _factory.CreateInstance(
+ _project.id,
+ "not-a-real-ingestion",
+ _client.Account,
+ new NullProgress(),
+ CancellationToken.None
+ );
+ await sender.Process(myObject);
+ await sender.WaitForUpload();
+ });
+ }
+
+ public Task DisposeAsync()
+ {
+ _client?.Dispose();
+ return Task.CompletedTask;
+ }
+}
diff --git a/tests/Speckle.Sdk.Tests.Integration/Speckle.Sdk.Tests.Integration.csproj b/tests/Speckle.Sdk.Tests.Integration/Speckle.Sdk.Tests.Integration.csproj
index 768cc1fc..3d8c88f4 100644
--- a/tests/Speckle.Sdk.Tests.Integration/Speckle.Sdk.Tests.Integration.csproj
+++ b/tests/Speckle.Sdk.Tests.Integration/Speckle.Sdk.Tests.Integration.csproj
@@ -16,7 +16,4 @@
-
-
-
diff --git a/tests/Speckle.Sdk.Tests.Integration/packages.lock.json b/tests/Speckle.Sdk.Tests.Integration/packages.lock.json
index 573fe4c8..5aa9b01c 100644
--- a/tests/Speckle.Sdk.Tests.Integration/packages.lock.json
+++ b/tests/Speckle.Sdk.Tests.Integration/packages.lock.json
@@ -293,8 +293,8 @@
"dependencies": {
"GraphQL.Client": "[6.1.0, )",
"Microsoft.Data.Sqlite": "[10.0.0, )",
- "Microsoft.Extensions.DependencyInjection": "[10.0.0, )",
"Microsoft.Extensions.Logging": "[10.0.0, )",
+ "Microsoft.Extensions.ObjectPool": "[10.0.0, )",
"Speckle.DoubleNumerics": "[4.1.0, )",
"Speckle.Newtonsoft.Json": "[13.0.2, )",
"Speckle.Sdk.Dependencies": "[1.0.0, )"
@@ -345,6 +345,12 @@
"Microsoft.Extensions.Options": "10.0.0"
}
},
+ "Microsoft.Extensions.ObjectPool": {
+ "type": "CentralTransitive",
+ "requested": "[9.0.4, )",
+ "resolved": "10.0.0",
+ "contentHash": "bpeCq0IYmVLACyEUMzFIOQX+zZUElG1t+nu1lSxthe7B+1oNYking7b91305+jNB6iwojp9fqTY9O+Nh7ULQxg=="
+ },
"Moq": {
"type": "CentralTransitive",
"requested": "[4.20.72, )",
diff --git a/tests/Speckle.Sdk.Tests.Performance/Benchmarks/CryptSha256Hash.cs b/tests/Speckle.Sdk.Tests.Performance/Benchmarks/CryptSha256Hash.cs
index 645ce4c9..95fd432b 100644
--- a/tests/Speckle.Sdk.Tests.Performance/Benchmarks/CryptSha256Hash.cs
+++ b/tests/Speckle.Sdk.Tests.Performance/Benchmarks/CryptSha256Hash.cs
@@ -22,9 +22,11 @@ public string Sha256()
return Speckle.Sdk.Common.Sha256.GetString(testData);
}
+#if NET6_0_OR_GREATER
[Benchmark]
public string Sha256_Span()
{
return Speckle.Sdk.Common.Sha256.GetString(testData.AsSpan());
}
+#endif
}
diff --git a/tests/Speckle.Sdk.Tests.Performance/Benchmarks/PipelineSendTest.cs b/tests/Speckle.Sdk.Tests.Performance/Benchmarks/PipelineSendTest.cs
new file mode 100644
index 00000000..78e3c5bf
--- /dev/null
+++ b/tests/Speckle.Sdk.Tests.Performance/Benchmarks/PipelineSendTest.cs
@@ -0,0 +1,80 @@
+using BenchmarkDotNet.Attributes;
+using BenchmarkDotNet.Engines;
+using Microsoft.Extensions.DependencyInjection;
+using Speckle.Objects.Geometry;
+using Speckle.Sdk.Api;
+using Speckle.Sdk.Api.GraphQL.Models;
+using Speckle.Sdk.Credentials;
+using Speckle.Sdk.Models.Collections;
+using Speckle.Sdk.Pipelines.Progress;
+using Speckle.Sdk.Pipelines.Send;
+
+namespace Speckle.Sdk.Tests.Performance.Benchmarks;
+
+[MemoryDiagnoser]
+[SimpleJob(RunStrategy.Monitoring, 0, 0, 4)]
+#pragma warning disable CA1001
+public class PipelineSendTest
+#pragma warning restore CA1001
+{
+ private SendPipeline _sut;
+ private DiskStore _sutDiskStore;
+ private ServiceProvider _provider;
+ private Collection _testData;
+ private IOperations _operations;
+ private IClient _client;
+ private Project _targetProject;
+ private Model _targetModel;
+ private ModelIngestion _ingestion;
+ private readonly Uri _server_url = new("https://app.speckle.systems");
+
+ [GlobalSetup]
+ public async Task Setup()
+ {
+ var serviceCollection = new ServiceCollection();
+ serviceCollection.AddSpeckleSdk(new("Tests", "test"), "v3", assemblies: typeof(Mesh).Assembly);
+ _provider = serviceCollection.BuildServiceProvider();
+
+ var account = _provider.GetRequiredService().GetAccounts(_server_url).First();
+ _client = _provider.GetRequiredService().Create(account);
+ _operations = _provider.GetRequiredService();
+
+ _testData = (Collection)
+ await _operations.Receive2(_server_url, "bf5b49215c", "feff8c11a06597d3a7740738a55417d2", null, null, default);
+ }
+
+ [IterationSetup]
+ public void BeforeEach() => BeforeEachAsync().GetAwaiter().GetResult();
+
+ private async Task BeforeEachAsync()
+ {
+ _targetProject = await _client.Project.CreateInWorkspace(new(null, null, null, "27b0bb90c4"));
+ _targetModel = await _client.Model.Create(new("test", null, _targetProject.id));
+ _ingestion = await _client.Ingestion.Create(
+ new(_targetModel.id, _targetProject.id, "", new("perftest", "1", null, null), 7200)
+ );
+
+ _sut?.Dispose();
+ var uploader = _provider
+ .GetRequiredService()
+ .CreateInstance(
+ _targetProject.id,
+ _ingestion.id,
+ _client.Account,
+ new NullProgress(),
+ default
+ );
+ _sutDiskStore = _provider.GetRequiredService().CreateInstance(default);
+ _sut = new SendPipeline(uploader, _sutDiskStore);
+ }
+
+ [Benchmark]
+ public async Task SendToDisk()
+ {
+ foreach (var item in _testData.elements)
+ {
+ _ = await _sut.Process(item);
+ }
+ await _sutDiskStore.CompleteAsync();
+ }
+}
diff --git a/tests/Speckle.Sdk.Tests.Performance/Benchmarks/PipelineSerializerTest.cs b/tests/Speckle.Sdk.Tests.Performance/Benchmarks/PipelineSerializerTest.cs
new file mode 100644
index 00000000..8d5bf640
--- /dev/null
+++ b/tests/Speckle.Sdk.Tests.Performance/Benchmarks/PipelineSerializerTest.cs
@@ -0,0 +1,49 @@
+using BenchmarkDotNet.Attributes;
+using BenchmarkDotNet.Engines;
+using Microsoft.Extensions.DependencyInjection;
+using Speckle.Objects.Geometry;
+using Speckle.Sdk.Api;
+using Speckle.Sdk.Models.Collections;
+using Speckle.Sdk.Pipelines.Send;
+
+namespace Speckle.Sdk.Tests.Performance.Benchmarks;
+
+[MemoryDiagnoser]
+[SimpleJob(RunStrategy.Monitoring, 0, 0, 4)]
+public class PipelineSerializerTest
+{
+ private readonly Serializer _sut = new();
+ private ServiceProvider _provider;
+ private Collection _testData;
+
+ [GlobalSetup]
+ public async Task Setup()
+ {
+ var serviceCollection = new ServiceCollection();
+ serviceCollection.AddSpeckleSdk(new("Tests", "test"), "v3", assemblies: typeof(Mesh).Assembly);
+ _provider = serviceCollection.BuildServiceProvider();
+
+ var operations = _provider.GetRequiredService();
+ _testData = (Collection)
+ await operations.Receive2(
+ new("https://app.speckle.systems"),
+ "bf5b49215c",
+ "feff8c11a06597d3a7740738a55417d2",
+ null,
+ null,
+ default
+ );
+ }
+
+ [Benchmark]
+ public List Serialize()
+ {
+ List items = new(_testData.elements.Count);
+ foreach (var item in _testData.elements)
+ {
+ items.Add(_sut.Serialize(item).ToArray());
+ }
+
+ return items;
+ }
+}
diff --git a/tests/Speckle.Sdk.Tests.Performance/Benchmarks/Send123TestSendToServer.cs b/tests/Speckle.Sdk.Tests.Performance/Benchmarks/Send123TestSendToServer.cs
new file mode 100644
index 00000000..16b6552c
--- /dev/null
+++ b/tests/Speckle.Sdk.Tests.Performance/Benchmarks/Send123TestSendToServer.cs
@@ -0,0 +1,97 @@
+using BenchmarkDotNet.Attributes;
+using BenchmarkDotNet.Engines;
+using Microsoft.Extensions.DependencyInjection;
+using Speckle.Objects.Geometry;
+using Speckle.Sdk.Api;
+using Speckle.Sdk.Api.GraphQL.Models;
+using Speckle.Sdk.Credentials;
+using Speckle.Sdk.Models;
+using Speckle.Sdk.Models.Collections;
+using Speckle.Sdk.Pipelines.Progress;
+using Speckle.Sdk.Pipelines.Send;
+using Speckle.Sdk.Serialisation.V2.Send;
+using Speckle.Sdk.Transports;
+
+namespace Speckle.Sdk.Tests.Performance.Benchmarks;
+
+[MemoryDiagnoser]
+[SimpleJob(RunStrategy.Monitoring, 0, 0, 4)]
+#pragma warning disable CA1001
+public class SendToServerTest
+#pragma warning restore CA1001
+{
+ private SendPipeline _sut;
+ private ServiceProvider _provider;
+ private Collection _testData;
+ private IOperations _operations;
+ private IClient _client;
+ private ServerTransport _remoteTransport;
+ private ISendPipelineFactory _sendPipelineFactory;
+ private Project _targetProject;
+ private Model _targetModel;
+ private ModelIngestion _ingestion;
+ private readonly Uri _server_url = new("https://app.speckle.systems");
+
+ [GlobalSetup]
+ public async Task Setup()
+ {
+ var serviceCollection = new ServiceCollection();
+ serviceCollection.AddSpeckleSdk(new("Tests", "test"), "v3", assemblies: typeof(Mesh).Assembly);
+ _provider = serviceCollection.BuildServiceProvider();
+
+ var account = _provider.GetRequiredService().GetAccounts(_server_url).First();
+ _client = _provider.GetRequiredService().Create(account);
+ _operations = _provider.GetRequiredService();
+ _sendPipelineFactory = _provider.GetRequiredService();
+
+ _testData = (Collection)
+ await _operations.Receive2(_server_url, "bf5b49215c", "feff8c11a06597d3a7740738a55417d2", null, null, default);
+ }
+
+ [IterationSetup]
+ public void BeforeEach() => BeforeEachAsync().GetAwaiter().GetResult();
+
+ private async Task BeforeEachAsync()
+ {
+ _targetProject = await _client.Project.CreateInWorkspace(new(null, null, null, "27b0bb90c4"));
+ _targetModel = await _client.Model.Create(new("test", null, _targetProject.id));
+ _ingestion = await _client.Ingestion.Create(
+ new(_targetModel.id, _targetProject.id, "", new("perftest", "1", null, null), 7200)
+ );
+
+ _sut?.Dispose();
+ _sut = _sendPipelineFactory.CreateInstance(
+ _targetProject.id,
+ _ingestion.id,
+ _client.Account,
+ new NullProgress(),
+ default
+ );
+ _remoteTransport?.Dispose();
+ _remoteTransport = _provider
+ .GetRequiredService()
+ .Create(_client.Account, _targetProject.id);
+ }
+
+ [Benchmark]
+ public async Task Send3()
+ {
+ foreach (var item in _testData.elements)
+ {
+ _ = await _sut.Process(item);
+ }
+ await _sut.WaitForUpload();
+ }
+
+ [Benchmark]
+ public async Task Send2()
+ {
+ return await _operations.Send2(_server_url, _targetProject.id, _client.Account.token, _testData, null, default);
+ }
+
+ [Benchmark]
+ public async Task<(string rootObjId, IReadOnlyDictionary convertedReferences)> Send1()
+ {
+ return await _operations.Send(_testData, _remoteTransport, true);
+ }
+}
diff --git a/tests/Speckle.Sdk.Tests.Performance/Speckle.Sdk.Tests.Performance.csproj b/tests/Speckle.Sdk.Tests.Performance/Speckle.Sdk.Tests.Performance.csproj
index 9afb35d9..ccb6f8b2 100644
--- a/tests/Speckle.Sdk.Tests.Performance/Speckle.Sdk.Tests.Performance.csproj
+++ b/tests/Speckle.Sdk.Tests.Performance/Speckle.Sdk.Tests.Performance.csproj
@@ -1,15 +1,16 @@
Exe
- net8.0
+ net10.0
enable
disable
+ win-x64
true
-
+
diff --git a/tests/Speckle.Sdk.Tests.Performance/packages.lock.json b/tests/Speckle.Sdk.Tests.Performance/packages.lock.json
index 0eb1c685..639fd337 100644
--- a/tests/Speckle.Sdk.Tests.Performance/packages.lock.json
+++ b/tests/Speckle.Sdk.Tests.Performance/packages.lock.json
@@ -1,23 +1,23 @@
{
"version": 2,
"dependencies": {
- "net8.0": {
+ "net10.0": {
"BenchmarkDotNet": {
"type": "Direct",
- "requested": "[0.14.0, )",
- "resolved": "0.14.0",
- "contentHash": "eIPSDKi3oni734M1rt/XJAwGQQOIf9gLjRRKKJ0HuVy3vYd7gnmAIX1bTjzI9ZbAY/nPddgqqgM/TeBYitMCIg==",
+ "requested": "[0.15.8, )",
+ "resolved": "0.15.8",
+ "contentHash": "paCfrWxSeHqn3rUZc0spYXVFnHCF0nzRhG0nOLnyTjZYs8spsimBaaNmb3vwqvALKIplbYq/TF393vYiYSnh/Q==",
"dependencies": {
- "BenchmarkDotNet.Annotations": "0.14.0",
+ "BenchmarkDotNet.Annotations": "0.15.8",
"CommandLineParser": "2.9.1",
"Gee.External.Capstone": "2.3.0",
- "Iced": "1.17.0",
- "Microsoft.CodeAnalysis.CSharp": "4.1.0",
- "Microsoft.Diagnostics.Runtime": "2.2.332302",
- "Microsoft.Diagnostics.Tracing.TraceEvent": "3.1.8",
+ "Iced": "1.21.0",
+ "Microsoft.CodeAnalysis.CSharp": "4.14.0",
+ "Microsoft.Diagnostics.Runtime": "3.1.512801",
+ "Microsoft.Diagnostics.Tracing.TraceEvent": "3.1.21",
"Microsoft.DotNet.PlatformAbstractions": "3.1.6",
- "Perfolizer": "[0.3.17]",
- "System.Management": "5.0.0"
+ "Perfolizer": "[0.6.1]",
+ "System.Management": "9.0.5"
}
},
"Microsoft.SourceLink.GitHub": {
@@ -44,8 +44,8 @@
},
"BenchmarkDotNet.Annotations": {
"type": "Transitive",
- "resolved": "0.14.0",
- "contentHash": "CUDCg6bgHrDzhjnA+IOBl5gAo8Y5hZ2YSs7MBXrYMlMKpBZqrD5ez0537uDveOkcf+YWAoK+S4sMcuWPbIz8bw=="
+ "resolved": "0.15.8",
+ "contentHash": "hfucY0ycAsB0SsoaZcaAp9oq5wlWBJcylvEJb9pmvdYUx6PD6S4mDiYnZWjdjAlLhIpe/xtGCwzORfzAzPqvzA=="
},
"CommandLineParser": {
"type": "Transitive",
@@ -59,29 +59,29 @@
},
"GraphQL.Client.Abstractions": {
"type": "Transitive",
- "resolved": "6.0.0",
- "contentHash": "h7uzWFORHZ+CCjwr/ThAyXMr0DPpzEANDa4Uo54wqCQ+j7qUKwqYTgOrb1W40sqbvNaZm9v/X7It31SUw0maHA==",
+ "resolved": "6.1.0",
+ "contentHash": "Za31wjKLEeROZYJmp0Lmj/TLQ1Yw6x6QM0JHABcuyMC3OSopr34ufayrtdxtbL1a3129FTVFKOFC0hcooSQoJQ==",
"dependencies": {
- "GraphQL.Primitives": "6.0.0"
+ "GraphQL.Primitives": "6.1.0"
}
},
"GraphQL.Client.Abstractions.Websocket": {
"type": "Transitive",
- "resolved": "6.0.0",
- "contentHash": "Nr9bPf8gIOvLuXpqEpqr9z9jslYFJOvd0feHth3/kPqeR3uMbjF5pjiwh4jxyMcxHdr8Pb6QiXkV3hsSyt0v7A==",
+ "resolved": "6.1.0",
+ "contentHash": "PjdG3q4MzPsa5NiBOBhuIRMRTo59der5bFmX2r1gSS3RIjytwpooxF2RffFCBh16sqbwuH1/dllDcNG+EJt1qA==",
"dependencies": {
- "GraphQL.Client.Abstractions": "6.0.0"
+ "GraphQL.Client.Abstractions": "6.1.0"
}
},
"GraphQL.Primitives": {
"type": "Transitive",
- "resolved": "6.0.0",
- "contentHash": "yg72rrYDapfsIUrul7aF6wwNnTJBOFvuA9VdDTQpPa8AlAriHbufeXYLBcodKjfUdkCnaiggX1U/nEP08Zb5GA=="
+ "resolved": "6.1.0",
+ "contentHash": "L8yQ70Wd9p8hMJvnmpgyZfr2R6Q7S0/lPyEBI1tacJa5XzsoJSVtHdmfsMaHyufwk03hlUsBXgNerAs66kxHdA=="
},
"Iced": {
"type": "Transitive",
- "resolved": "1.17.0",
- "contentHash": "8x+HCVTl/HHTGpscH3vMBhV8sknN/muZFw9s3TsI8SA6+c43cOTCi2+jE4KsU8pNLbJ++iF2ZFcpcXHXtDglnw=="
+ "resolved": "1.21.0",
+ "contentHash": "dv5+81Q1TBQvVMSOOOmRcjJmvWcX3BZPZsIq31+RLc5cNft0IHAyNlkdb7ZarOWG913PyBoFDsDXoCIlKmLclg=="
},
"Microsoft.Build.Tasks.Git": {
"type": "Transitive",
@@ -90,65 +90,57 @@
},
"Microsoft.CodeAnalysis.Analyzers": {
"type": "Transitive",
- "resolved": "3.3.3",
- "contentHash": "j/rOZtLMVJjrfLRlAMckJLPW/1rze9MT1yfWqSIbUPGRu1m1P0fuo9PmqapwsmePfGB5PJrudQLvmUOAMF0DqQ=="
+ "resolved": "3.11.0",
+ "contentHash": "v/EW3UE8/lbEYHoC2Qq7AR/DnmvpgdtAMndfQNmpuIMx/Mto8L5JnuCfdBYtgvalQOtfNCnxFejxuRrryvUTsg=="
},
"Microsoft.CodeAnalysis.Common": {
"type": "Transitive",
- "resolved": "4.1.0",
- "contentHash": "bNzTyxP3iD5FPFHfVDl15Y6/wSoI7e3MeV0lOaj9igbIKTjgrmuw6LoVJ06jUNFA7+KaDC/OIsStWl/FQJz6sQ==",
+ "resolved": "4.14.0",
+ "contentHash": "PC3tuwZYnC+idaPuoC/AZpEdwrtX7qFpmnrfQkgobGIWiYmGi5MCRtl5mx6QrfMGQpK78X2lfIEoZDLg/qnuHg==",
"dependencies": {
- "Microsoft.CodeAnalysis.Analyzers": "3.3.3",
- "System.Collections.Immutable": "5.0.0",
- "System.Memory": "4.5.4",
- "System.Reflection.Metadata": "5.0.0",
- "System.Runtime.CompilerServices.Unsafe": "5.0.0",
- "System.Text.Encoding.CodePages": "4.5.1",
- "System.Threading.Tasks.Extensions": "4.5.4"
+ "Microsoft.CodeAnalysis.Analyzers": "3.11.0"
}
},
"Microsoft.CodeAnalysis.CSharp": {
"type": "Transitive",
- "resolved": "4.1.0",
- "contentHash": "sbu6kDGzo9bfQxuqWpeEE7I9P30bSuZEnpDz9/qz20OU6pm79Z63+/BsAzO2e/R/Q97kBrpj647wokZnEVr97w==",
+ "resolved": "4.14.0",
+ "contentHash": "568a6wcTivauIhbeWcCwfWwIn7UV7MeHEBvFB2uzGIpM2OhJ4eM/FZ8KS0yhPoNxnSpjGzz7x7CIjTxhslojQA==",
"dependencies": {
- "Microsoft.CodeAnalysis.Common": "[4.1.0]"
+ "Microsoft.CodeAnalysis.Analyzers": "3.11.0",
+ "Microsoft.CodeAnalysis.Common": "[4.14.0]"
}
},
"Microsoft.Data.Sqlite.Core": {
"type": "Transitive",
- "resolved": "7.0.5",
- "contentHash": "FTerRmQPqHrCrnoUzhBu+E+1DNGwyrAMLqHkAqOOOu5pGfyMOj8qQUBxI/gDtWtG11p49UxSfWmBzRNlwZqfUg==",
+ "resolved": "10.0.0",
+ "contentHash": "wPKG/Ym6tSMCo06UOZXzVfeFGzawnOZrTba/R3PfK+RhNuNELZ9I7nFns4WGTtv2kKlrlmmErgJ+kgTXHaNdHg==",
"dependencies": {
- "SQLitePCLRaw.core": "2.1.4"
+ "SQLitePCLRaw.core": "2.1.11"
}
},
"Microsoft.Diagnostics.NETCore.Client": {
"type": "Transitive",
- "resolved": "0.2.251802",
- "contentHash": "bqnYl6AdSeboeN4v25hSukK6Odm6/54E3Y2B8rBvgqvAW0mF8fo7XNRVE2DMOG7Rk0fiuA079QIH28+V+W1Zdg==",
+ "resolved": "0.2.510501",
+ "contentHash": "juoqJYMDs+lRrrZyOkXXMImJHneCF23cuvO4waFRd2Ds7j+ZuGIPbJm0Y/zz34BdeaGiiwGWraMUlln05W1PCQ==",
"dependencies": {
- "Microsoft.Bcl.AsyncInterfaces": "1.1.0",
- "Microsoft.Extensions.Logging": "2.1.1"
+ "Microsoft.Extensions.Logging": "6.0.0"
}
},
"Microsoft.Diagnostics.Runtime": {
"type": "Transitive",
- "resolved": "2.2.332302",
- "contentHash": "Hp84ivxSKIMTBzYSATxmUsm3YSXHWivcwiRRbsydGmqujMUK8BAueLN0ssAVEOkOBmh0vjUBhrq7YcroT7VCug==",
+ "resolved": "3.1.512801",
+ "contentHash": "0lMUDr2oxNZa28D6NH5BuSQEe5T9tZziIkvkD44YkkCGQXPJqvFjLq5ZQq1hYLl3RjQJrY+hR0jFgap+EWPDTw==",
"dependencies": {
- "Microsoft.Diagnostics.NETCore.Client": "0.2.251802",
- "System.Collections.Immutable": "5.0.0",
- "System.Runtime.CompilerServices.Unsafe": "5.0.0"
+ "Microsoft.Diagnostics.NETCore.Client": "0.2.410101"
}
},
"Microsoft.Diagnostics.Tracing.TraceEvent": {
"type": "Transitive",
- "resolved": "3.1.8",
- "contentHash": "kl3UMrZKSeSEYZ8rt/GjLUQToREjgQABqfg6PzQBmSlYHTZOKE9ePEOS2xptROQ9SVvngg3QGX51TIT11iZ0wA==",
+ "resolved": "3.1.21",
+ "contentHash": "/OrJFKaojSR6TkUKtwh8/qA9XWNtxLrXMqvEb89dBSKCWjaGVTbKMYodIUgF5deCEtmd6GXuRerciXGl5bhZ7Q==",
"dependencies": {
- "Microsoft.Win32.Registry": "4.4.0",
- "System.Runtime.CompilerServices.Unsafe": "5.0.0"
+ "Microsoft.Diagnostics.NETCore.Client": "0.2.510501",
+ "System.Reflection.TypeExtensions": "4.7.0"
}
},
"Microsoft.DotNet.PlatformAbstractions": {
@@ -158,152 +150,98 @@
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "Transitive",
- "resolved": "8.0.0",
- "contentHash": "cjWrLkJXK0rs4zofsK4bSdg+jhDLTaxrkXu4gS6Y7MAlCvRyNNgwY/lJi5RDlQOnSZweHqoyvgvbdvQsRIW+hg=="
+ "resolved": "10.0.0",
+ "contentHash": "L3AdmZ1WOK4XXT5YFPEwyt0ep6l8lGIPs7F5OOBZc77Zqeo01Of7XXICy47628sdVl0v/owxYJTe86DTgFwKCA=="
},
"Microsoft.Extensions.Logging.Abstractions": {
"type": "Transitive",
- "resolved": "8.0.0",
- "contentHash": "arDBqTgFCyS0EvRV7O3MZturChstm50OJ0y9bDJvAcmEPJm0FFpFyjU/JLYyStNGGey081DvnQYlncNX5SJJGA==",
+ "resolved": "10.0.0",
+ "contentHash": "FU/IfjDfwaMuKr414SSQNTIti/69bHEMb+QKrskRb26oVqpx3lNFXMjs/RC9ZUuhBhcwDM2BwOgoMw+PZ+beqQ==",
"dependencies": {
- "Microsoft.Extensions.DependencyInjection.Abstractions": "8.0.0"
+ "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.0"
}
},
"Microsoft.Extensions.Options": {
"type": "Transitive",
- "resolved": "8.0.0",
- "contentHash": "JOVOfqpnqlVLUzINQ2fox8evY2SKLYJ3BV8QDe/Jyp21u1T7r45x/R/5QdteURMR5r01GxeJSBBUOCOyaNXA3g==",
+ "resolved": "10.0.0",
+ "contentHash": "8oCAgXOow5XDrY9HaXX1QmH3ORsyZO/ANVHBlhLyCeWTH5Sg4UuqZeOTWJi6484M+LqSx0RqQXDJtdYy2BNiLQ==",
"dependencies": {
- "Microsoft.Extensions.DependencyInjection.Abstractions": "8.0.0",
- "Microsoft.Extensions.Primitives": "8.0.0"
+ "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.0",
+ "Microsoft.Extensions.Primitives": "10.0.0"
}
},
"Microsoft.Extensions.Primitives": {
"type": "Transitive",
- "resolved": "8.0.0",
- "contentHash": "bXJEZrW9ny8vjMF1JV253WeLhpEVzFo1lyaZu1vQ4ZxWUlVvknZ/+ftFgVheLubb4eZPSwwxBeqS1JkCOjxd8g=="
- },
- "Microsoft.NETCore.Platforms": {
- "type": "Transitive",
- "resolved": "5.0.0",
- "contentHash": "VyPlqzH2wavqquTcYpkIIAQ6WdenuKoFN0BdYBbCWsclXacSOHNQn66Gt4z5NBqEYW0FAPm5rlvki9ZiCij5xQ=="
+ "resolved": "10.0.0",
+ "contentHash": "inRnbpCS0nwO/RuoZIAqxQUuyjaknOOnCEZB55KSMMjRhl0RQDttSmLSGsUJN3RQ3ocf5NDLFd2mOQViHqMK5w=="
},
"Microsoft.SourceLink.Common": {
"type": "Transitive",
"resolved": "8.0.0",
"contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw=="
},
- "Microsoft.Win32.Registry": {
+ "Perfolizer": {
"type": "Transitive",
- "resolved": "5.0.0",
- "contentHash": "dDoKi0PnDz31yAyETfRntsLArTlVAVzUzCIvvEDsDsucrl33Dl8pIJG06ePTJTI3tGpeyHS9Cq7Foc/s4EeKcg==",
+ "resolved": "0.6.1",
+ "contentHash": "CR1QmWg4XYBd1Pb7WseP+sDmV8nGPwvmowKynExTqr3OuckIGVMhvmN4LC5PGzfXqDlR295+hz/T7syA1CxEqA==",
"dependencies": {
- "System.Security.AccessControl": "5.0.0",
- "System.Security.Principal.Windows": "5.0.0"
+ "Pragmastat": "3.2.4"
}
},
- "Perfolizer": {
+ "Pragmastat": {
"type": "Transitive",
- "resolved": "0.3.17",
- "contentHash": "FQgtCoF2HFwvzKWulAwBS5BGLlh8pgbrJtOp47jyBwh2CW16juVtacN1azOA2BqdrJXkXTNLNRMo7ZlHHiuAnA=="
+ "resolved": "3.2.4",
+ "contentHash": "I5qFifWw/gaTQT52MhzjZpkm/JPlfjSeO/DTZJjO7+hTKI+0aGRgOgZ3NN6D96dDuuqbIAZSeA5RimtHjqrA2A=="
},
"SQLitePCLRaw.bundle_e_sqlite3": {
"type": "Transitive",
- "resolved": "2.1.4",
- "contentHash": "EWI1olKDjFEBMJu0+3wuxwziIAdWDVMYLhuZ3Qs84rrz+DHwD00RzWPZCa+bLnHCf3oJwuFZIRsHT5p236QXww==",
+ "resolved": "2.1.11",
+ "contentHash": "DC4nA7yWnf4UZdgJDF+9Mus4/cb0Y3Sfgi3gDnAoKNAIBwzkskNAbNbyu+u4atT0ruVlZNJfwZmwiEwE5oz9LQ==",
"dependencies": {
- "SQLitePCLRaw.lib.e_sqlite3": "2.1.4",
- "SQLitePCLRaw.provider.e_sqlite3": "2.1.4"
+ "SQLitePCLRaw.lib.e_sqlite3": "2.1.11",
+ "SQLitePCLRaw.provider.e_sqlite3": "2.1.11"
}
},
"SQLitePCLRaw.core": {
"type": "Transitive",
- "resolved": "2.1.4",
- "contentHash": "inBjvSHo9UDKneGNzfUfDjK08JzlcIhn1+SP5Y3m6cgXpCxXKCJDy6Mka7LpgSV+UZmKSnC8rTwB0SQ0xKu5pA==",
- "dependencies": {
- "System.Memory": "4.5.3"
- }
+ "resolved": "2.1.11",
+ "contentHash": "PK0GLFkfhZzLQeR3PJf71FmhtHox+U3vcY6ZtswoMjrefkB9k6ErNJEnwXqc5KgXDSjige2XXrezqS39gkpQKA=="
},
"SQLitePCLRaw.lib.e_sqlite3": {
"type": "Transitive",
- "resolved": "2.1.4",
- "contentHash": "2C9Q9eX7CPLveJA0rIhf9RXAvu+7nWZu1A2MdG6SD/NOu26TakGgL1nsbc0JAspGijFOo3HoN79xrx8a368fBg=="
+ "resolved": "2.1.11",
+ "contentHash": "Ev2ytaXiOlWZ4b3R67GZBsemTINslLD1DCJr2xiacpn4tbapu0Q4dHEzSvZSMnVWeE5nlObU3VZN2p81q3XOYQ=="
},
"SQLitePCLRaw.provider.e_sqlite3": {
"type": "Transitive",
- "resolved": "2.1.4",
- "contentHash": "CSlb5dUp1FMIkez9Iv5EXzpeq7rHryVNqwJMWnpq87j9zWZexaEMdisDktMsnnrzKM6ahNrsTkjqNodTBPBxtQ==",
+ "resolved": "2.1.11",
+ "contentHash": "Y/0ZkR+r0Cg3DQFuCl1RBnv/tmxpIZRU3HUvelPw6MVaKHwYYR8YNvgs0vuNuXCMvlyJ+Fh88U1D4tah1tt6qw==",
"dependencies": {
- "SQLitePCLRaw.core": "2.1.4"
+ "SQLitePCLRaw.core": "2.1.11"
}
},
"System.CodeDom": {
"type": "Transitive",
- "resolved": "5.0.0",
- "contentHash": "JPJArwA1kdj8qDAkY2XGjSWoYnqiM7q/3yRNkt6n28Mnn95MuEGkZXUbPBf7qc3IjwrGY5ttQon7yqHZyQJmOQ=="
- },
- "System.Collections.Immutable": {
- "type": "Transitive",
- "resolved": "5.0.0",
- "contentHash": "FXkLXiK0sVVewcso0imKQoOxjoPAj42R8HtjjbSjVPAzwDfzoyoznWxgA3c38LDbN9SJux1xXoXYAhz98j7r2g=="
+ "resolved": "9.0.5",
+ "contentHash": "cuzLM2MWutf9ZBEMPYYfd0DXwYdvntp7VCT6a/wvbKCa2ZuvGmW74xi+YBa2mrfEieAXqM4TNKlMmSnfAfpUoQ=="
},
"System.Management": {
"type": "Transitive",
- "resolved": "5.0.0",
- "contentHash": "MF1CHaRcC+MLFdnDthv4/bKWBZnlnSpkGqa87pKukQefgEdwtb9zFW6zs0GjPp73qtpYYg4q6PEKbzJbxCpKfw==",
+ "resolved": "9.0.5",
+ "contentHash": "n6o9PZm9p25+zAzC3/48K0oHnaPKTInRrxqFq1fi/5TPbMLjuoCm/h//mS3cUmSy+9AO1Z+qsC/Ilt/ZFatv5Q==",
"dependencies": {
- "Microsoft.NETCore.Platforms": "5.0.0",
- "Microsoft.Win32.Registry": "5.0.0",
- "System.CodeDom": "5.0.0"
+ "System.CodeDom": "9.0.5"
}
},
- "System.Memory": {
- "type": "Transitive",
- "resolved": "4.5.4",
- "contentHash": "1MbJTHS1lZ4bS4FmsJjnuGJOu88ZzTT2rLvrhW7Ygic+pC0NWA+3hgAen0HRdsocuQXCkUTdFn9yHJJhsijDXw=="
- },
"System.Reactive": {
"type": "Transitive",
- "resolved": "5.0.0",
- "contentHash": "erBZjkQHWL9jpasCE/0qKAryzVBJFxGHVBAvgRN1bzM0q2s1S4oYREEEL0Vb+1kA/6BKb5FjUZMp5VXmy+gzkQ=="
- },
- "System.Reflection.Metadata": {
- "type": "Transitive",
- "resolved": "5.0.0",
- "contentHash": "5NecZgXktdGg34rh1OenY1rFNDCI8xSjFr+Z4OU4cU06AQHUdRnIIEeWENu3Wl4YowbzkymAIMvi3WyK9U53pQ=="
- },
- "System.Runtime.CompilerServices.Unsafe": {
- "type": "Transitive",
- "resolved": "5.0.0",
- "contentHash": "ZD9TMpsmYJLrxbbmdvhwt9YEgG5WntEnZ/d1eH8JBX9LBp+Ju8BSBhUGbZMNVHHomWo2KVImJhTDl2hIgw/6MA=="
- },
- "System.Security.AccessControl": {
- "type": "Transitive",
- "resolved": "5.0.0",
- "contentHash": "dagJ1mHZO3Ani8GH0PHpPEe/oYO+rVdbQjvjJkBRNQkX4t0r1iaeGn8+/ybkSLEan3/slM0t59SVdHzuHf2jmw==",
- "dependencies": {
- "Microsoft.NETCore.Platforms": "5.0.0",
- "System.Security.Principal.Windows": "5.0.0"
- }
- },
- "System.Security.Principal.Windows": {
- "type": "Transitive",
- "resolved": "5.0.0",
- "contentHash": "t0MGLukB5WAVU9bO3MGzvlGnyJPgUlcwerXn1kzBRjwLKixT96XV0Uza41W49gVd8zEMFu9vQEFlv0IOrytICA=="
- },
- "System.Text.Encoding.CodePages": {
- "type": "Transitive",
- "resolved": "4.5.1",
- "contentHash": "4J2JQXbftjPMppIHJ7IC+VXQ9XfEagN92vZZNoG12i+zReYlim5dMoXFC1Zzg7tsnKDM7JPo5bYfFK4Jheq44w==",
- "dependencies": {
- "Microsoft.NETCore.Platforms": "2.1.2",
- "System.Runtime.CompilerServices.Unsafe": "4.5.2"
- }
+ "resolved": "6.0.0",
+ "contentHash": "31kfaW4ZupZzPsI5PVe77VhnvFF55qgma7KZr/E0iFTs6fmdhhG8j0mgEx620iLTey1EynOkEfnyTjtNEpJzGw=="
},
- "System.Threading.Tasks.Extensions": {
+ "System.Reflection.TypeExtensions": {
"type": "Transitive",
- "resolved": "4.5.4",
- "contentHash": "zteT+G8xuGu6mS+mzDzYXbzS7rd3K6Fjb9RiZlYlJPam2/hU7JCBZBVEcywNuR+oZ1ncTvc/cq0faRr3P01OVg=="
+ "resolved": "4.7.0",
+ "contentHash": "VybpaOQQhqE6siHppMktjfGBw1GCwvCqiufqmP8F1nj7fTUNtW35LOEt3UZTEsECfo+ELAl/9o9nJx3U91i7vA=="
},
"speckle.objects": {
"type": "Project",
@@ -314,10 +252,10 @@
"speckle.sdk": {
"type": "Project",
"dependencies": {
- "GraphQL.Client": "[6.0.0, )",
- "Microsoft.Data.Sqlite": "[7.0.5, )",
- "Microsoft.Extensions.DependencyInjection": "[8.0.0, )",
- "Microsoft.Extensions.Logging": "[8.0.0, )",
+ "GraphQL.Client": "[6.1.0, )",
+ "Microsoft.Data.Sqlite": "[10.0.0, )",
+ "Microsoft.Extensions.Logging": "[10.0.0, )",
+ "Microsoft.Extensions.ObjectPool": "[10.0.0, )",
"Speckle.DoubleNumerics": "[4.1.0, )",
"Speckle.Newtonsoft.Json": "[13.0.2, )",
"Speckle.Sdk.Dependencies": "[1.0.0, )"
@@ -329,50 +267,51 @@
"GraphQL.Client": {
"type": "CentralTransitive",
"requested": "[6.1.0, )",
- "resolved": "6.0.0",
- "contentHash": "8yPNBbuVBpTptivyAlak4GZvbwbUcjeQTL4vN1HKHRuOykZ4r7l5fcLS6vpyPyLn0x8FsL31xbOIKyxbmR9rbA==",
+ "resolved": "6.1.0",
+ "contentHash": "oKliAxtNuZDMxO9079mjSbwA0YwhjXBzVnVPuNZ3HI4OllO++CcOLT30l90mM/fxCAMaa8GU4ZYMwD9YjLkyiw==",
"dependencies": {
- "GraphQL.Client.Abstractions": "6.0.0",
- "GraphQL.Client.Abstractions.Websocket": "6.0.0",
- "System.Reactive": "5.0.0"
+ "GraphQL.Client.Abstractions": "6.1.0",
+ "GraphQL.Client.Abstractions.Websocket": "6.1.0",
+ "System.Reactive": "6.0.0"
}
},
- "Microsoft.Bcl.AsyncInterfaces": {
- "type": "CentralTransitive",
- "requested": "[9.0.4, )",
- "resolved": "1.1.0",
- "contentHash": "1Am6l4Vpn3/K32daEqZI+FFr96OlZkgwK2LcT3pZ2zWubR5zTPW3/FkO1Rat9kb7oQOa4rxgl9LJHc5tspCWfg=="
- },
"Microsoft.Data.Sqlite": {
"type": "CentralTransitive",
"requested": "[7.0.5, )",
- "resolved": "7.0.5",
- "contentHash": "KGxbPeWsQMnmQy43DSBxAFtHz3l2JX8EWBSGUCvT3CuZ8KsuzbkqMIJMDOxWtG8eZSoCDI04aiVQjWuuV8HmSw==",
+ "resolved": "10.0.0",
+ "contentHash": "I/azQ5WjwoLvSlTyDydkhARPSjYJN8jkXRjR5D92OeyTLbTrQ1K93rgf6XU+HYWHZA6lBI9SUOfl69OqEHb4ow==",
"dependencies": {
- "Microsoft.Data.Sqlite.Core": "7.0.5",
- "SQLitePCLRaw.bundle_e_sqlite3": "2.1.4"
+ "Microsoft.Data.Sqlite.Core": "10.0.0",
+ "SQLitePCLRaw.bundle_e_sqlite3": "2.1.11",
+ "SQLitePCLRaw.core": "2.1.11"
}
},
"Microsoft.Extensions.DependencyInjection": {
"type": "CentralTransitive",
"requested": "[10.0.6, )",
- "resolved": "8.0.0",
- "contentHash": "V8S3bsm50ig6JSyrbcJJ8bW2b9QLGouz+G1miK3UTaOWmMtFwNNNzUf4AleyDWUmTrWMLNnFSLEQtxmxgNQnNQ==",
+ "resolved": "10.0.0",
+ "contentHash": "f0RBabswJq+gRu5a+hWIobrLWiUYPKMhCD9WO3sYBAdSy3FFH14LMvLVFZc2kPSCimBLxSuitUhsd6tb0TAY6A==",
"dependencies": {
- "Microsoft.Extensions.DependencyInjection.Abstractions": "8.0.0"
+ "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.0"
}
},
"Microsoft.Extensions.Logging": {
"type": "CentralTransitive",
"requested": "[10.0.6, )",
- "resolved": "8.0.0",
- "contentHash": "tvRkov9tAJ3xP51LCv3FJ2zINmv1P8Hi8lhhtcKGqM+ImiTCC84uOPEI4z8Cdq2C3o9e+Aa0Gw0rmrsJD77W+w==",
+ "resolved": "10.0.0",
+ "contentHash": "BStFkd5CcnEtarlcgYDBcFzGYCuuNMzPs02wN3WBsOFoYIEmYoUdAiU+au6opzoqfTYJsMTW00AeqDdnXH2CvA==",
"dependencies": {
- "Microsoft.Extensions.DependencyInjection": "8.0.0",
- "Microsoft.Extensions.Logging.Abstractions": "8.0.0",
- "Microsoft.Extensions.Options": "8.0.0"
+ "Microsoft.Extensions.DependencyInjection": "10.0.0",
+ "Microsoft.Extensions.Logging.Abstractions": "10.0.0",
+ "Microsoft.Extensions.Options": "10.0.0"
}
},
+ "Microsoft.Extensions.ObjectPool": {
+ "type": "CentralTransitive",
+ "requested": "[9.0.4, )",
+ "resolved": "10.0.0",
+ "contentHash": "bpeCq0IYmVLACyEUMzFIOQX+zZUElG1t+nu1lSxthe7B+1oNYking7b91305+jNB6iwojp9fqTY9O+Nh7ULQxg=="
+ },
"Speckle.DoubleNumerics": {
"type": "CentralTransitive",
"requested": "[4.1.0, )",
@@ -385,6 +324,26 @@
"resolved": "13.0.2",
"contentHash": "g1BejUZwax5PRfL6xHgLEK23sqHWOgOj9hE7RvfRRlN00AGt8GnPYt8HedSK7UB3HiRW8zCA9Pn0iiYxCK24BA=="
}
+ },
+ "net10.0/win-x64": {
+ "Gee.External.Capstone": {
+ "type": "Transitive",
+ "resolved": "2.3.0",
+ "contentHash": "2ap/rYmjtzCOT8hxrnEW/QeiOt+paD8iRrIcdKX0cxVwWLFa1e+JDBNeECakmccXrSFeBQuu5AV8SNkipFMMMw=="
+ },
+ "SQLitePCLRaw.lib.e_sqlite3": {
+ "type": "Transitive",
+ "resolved": "2.1.11",
+ "contentHash": "Ev2ytaXiOlWZ4b3R67GZBsemTINslLD1DCJr2xiacpn4tbapu0Q4dHEzSvZSMnVWeE5nlObU3VZN2p81q3XOYQ=="
+ },
+ "System.Management": {
+ "type": "Transitive",
+ "resolved": "9.0.5",
+ "contentHash": "n6o9PZm9p25+zAzC3/48K0oHnaPKTInRrxqFq1fi/5TPbMLjuoCm/h//mS3cUmSy+9AO1Z+qsC/Ilt/ZFatv5Q==",
+ "dependencies": {
+ "System.CodeDom": "9.0.5"
+ }
+ }
}
}
}
\ No newline at end of file
diff --git a/tests/Speckle.Sdk.Tests.Unit/Pipelines/Send/Serialization/IdGeneratorTests.cs b/tests/Speckle.Sdk.Tests.Unit/Pipelines/Send/Serialization/IdGeneratorTests.cs
new file mode 100644
index 00000000..3dea2d50
--- /dev/null
+++ b/tests/Speckle.Sdk.Tests.Unit/Pipelines/Send/Serialization/IdGeneratorTests.cs
@@ -0,0 +1,28 @@
+using System.Text;
+using Speckle.Sdk.Pipelines.Send;
+
+namespace Speckle.Sdk.Tests.Unit.Pipelines.Send.Serialization;
+
+public class IdGeneratorTests
+{
+ [Theory]
+ [InlineData("hello world", "b94d27b9934d3e08a52e52d7da7dabfa")]
+ [InlineData("test input", "9dfe6f15d1ab73af898739394fd22fd7")]
+ [InlineData("", "e3b0c44298fc1c149afbf4c8996fb924")]
+ [InlineData("hjlkasdfhkjladfkjhlasdflkhjasdflkhjasfdlhkjasfdlhjkafsdhlkfjads", "68bcfbbbd4cf06adf294e3e8d68b856c")]
+ public void ComputeId_BothOverloads_ReturnExpectedHashes(string input, string expectedHash)
+ {
+ // Arrange
+ byte[] bytes = Encoding.UTF8.GetBytes(input);
+
+ // Act
+ string spanResult = IdGenerator.ComputeId(bytes);
+ string arrayResult = IdGenerator.ComputeId(bytes, 0, bytes.Length);
+
+ // Assert
+ Assert.Equal(expectedHash, spanResult);
+ Assert.Equal(expectedHash, arrayResult);
+ Assert.Equal(32, expectedHash.Length);
+ Assert.Equal(32, IdGenerator.ID_HEX_LENGTH_CHARS);
+ }
+}
diff --git a/tests/Speckle.Sdk.Tests.Unit/Pipelines/Send/Serialization/JsonIgnoreAttributeTests.cs b/tests/Speckle.Sdk.Tests.Unit/Pipelines/Send/Serialization/JsonIgnoreAttributeTests.cs
new file mode 100644
index 00000000..d9049081
--- /dev/null
+++ b/tests/Speckle.Sdk.Tests.Unit/Pipelines/Send/Serialization/JsonIgnoreAttributeTests.cs
@@ -0,0 +1,124 @@
+using AwesomeAssertions;
+using Speckle.Newtonsoft.Json;
+using Speckle.Sdk.Host;
+using Speckle.Sdk.Models;
+using Speckle.Sdk.Pipelines.Send;
+
+namespace Speckle.Sdk.Tests.Unit.Pipelines.Send.Serialization;
+
+///
+/// Tests that the leads to properties being ignored both from the final JSON output,
+/// But also from the id calculation
+///
+[Collection(nameof(RequiresTypeLoaderCollection))]
+public sealed class JsonIgnoreRespected
+{
+ private readonly Serializer _sut = new();
+
+ public JsonIgnoreRespected()
+ {
+ TypeLoader.ReInitialize(typeof(Base).Assembly, typeof(IgnoreTest).Assembly);
+ }
+
+ public static IEnumerable