Skip to content

Commit 7799b27

Browse files
Changes Provider and Direct Comparison functionality (#245)
This PR aims to enhance changed elements react for: _Frontend Enhancements:_ 1. Provide consumers a way to inject their own changes and skip using the changed elements service altogether 2. Provide colorization overrides for any special customization logic 3. Provide a callback when changed instances are selected in the UI _Backend Enhancements:_ 1. Initial ChangesRpcInterface and ChangesRpcImpl which aim to allow using the Partial EC Change Unifier in a simplified way 2. The Rpc interface allows the app to provide relationships that they care about and marks any related changed ec instance with what relationships were affected that may drive the element for changes _Test App Changes:_ 1. The ChangesRpcInterface is used to supply changes to provide an example of usage for an app that may want specific relationships to be highlighted 2. Showcases how they could colorize changed instances based on the relationships that have changes The Rpc is being implemented temporarily as part of the test-app-backend, but we will aim to move it to a separate package (potentially [imodel-sync](https://github.com/iTwin/itwinjs-internal/tree/master/packages/clients/sync)) to be consumable by other applications. --------- Co-authored-by: Caleb German <Caleb.German@Bentley.com>
1 parent 55fc6dd commit 7799b27

40 files changed

+7106
-4092
lines changed

.changeset/wise-readers-jog.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
---
2+
"@itwin/changed-elements-react": minor
3+
---
4+
5+
_Frontend Enhancements:_
6+
7+
1. Provide consumers a way to inject their own changes and skip using the changed elements service altogether
8+
2. Provide colorization overrides for any special customization logic
9+
3. Provide a callback when changed instances are selected in the UI
10+
11+
_Backend Enhancements:_
12+
1. Initial ChangesRpcInterface and ChangesRpcImpl which aim to allow using the Partial EC Change Unifier in a simplified way
13+
2. The Rpc interface allows the app to provide relationships that they care about and marks any related changed ec instance with what relationships were affected that may drive the element for changes
14+
15+
See VersionCompare initialization options (`changesProvider`, `colorOverrideProvider` and `onInstancesSelected`) for more information.

.eslintrc.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
"root": true,
33
"extends": [
44
"eslint:recommended",
5+
"prettier",
56
"plugin:@typescript-eslint/recommended-type-checked"
67
],
78
"parser": "@typescript-eslint/parser",
@@ -16,6 +17,7 @@
1617
"no-alert": "warn",
1718
"no-empty": [ "warn", { "allowEmptyCatch": true } ],
1819
"no-eval": "error",
20+
"no-console": "off",
1921
"@typescript-eslint/comma-dangle": [
2022
"warn",
2123
{

.github/workflows/CI.yaml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,16 @@ jobs:
1515
with:
1616
fetch-depth: 0 # Fetch all history for all branches and tags
1717

18-
- name: Install pnpm
18+
- name: Install pnpm@10.12.4
1919
uses: pnpm/action-setup@v2
2020
with:
21-
version: 8
21+
version: 10.12.4
2222
run_install: false
2323

24-
- name: Use Node.js 20
24+
- name: Use Node.js 20.16.0
2525
uses: actions/setup-node@v3
2626
with:
27-
node-version: 20
27+
node-version: 20.16.0
2828
cache: "pnpm"
2929

3030
- name: Install dependencies

.github/workflows/dependabot-push.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ jobs:
2626

2727
# Install pnpm
2828
- name: Install pnpm
29-
run: npm install -g pnpm
29+
run: npm install -g pnpm@10.12.4
3030

3131
# Install dependencies
3232
- name: Install dependencies

.github/workflows/release-workflow.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ jobs:
2222
- name: Install pnpm
2323
uses: pnpm/action-setup@v2
2424
with:
25-
version: 8
25+
version: 10.12.4
2626
run_install: false
2727

2828
- name: Use Node.js 20

.prettierrc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"singleQuote": false,
3+
"trailingComma": "all",
4+
"printWidth": 150,
5+
"tabWidth": 2,
6+
"useTabs": false
7+
}

experiment.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
## Changed Elements React Experiment - Direct Comparison Workflow
2+
3+
### HYPOTHESIS:
4+
If we use changeset group processing without processing the changed elements, then the result of the direct processing will be produced faster and will resemble GitHub's diff functionality by displaying a flat list of changes.
5+
6+
### REASON FOR EXPERIMENT
7+
Changed elements undergo extensive processing to ensure a presentation-based summary of changes in an iModel. We aim to understand how a feature like Version Comparison would operate using raw changeset group results instead of presentation ruleset-based property path traversal. We expect faster loading times for Direct Comparison due to reduced processing, while still providing valuable output to the user.
8+
9+
### EXPERIMENT
10+
We conducted multiple experiments to confirm our hypothesis. The steps were:
11+
12+
1. Run the Version Compare V2 workflow (Post/Get/Display) for an iModel with an unprocessed job range. Record the time until the user can interact with the job-related information on the UI.
13+
2. Run the experimental Direct Comparison on the same unprocessed job version. Record the time until the user can interact with the job-related information on the UI.
14+
15+
#### Results Table
16+
We tested across three different iModels of varying sizes in the DEV region to draw better conclusions.
17+
18+
| Itwin | IModel | Number Of Changeset Processed (V2 / Direct Comparison) | V2 Processing Time till interaction in UI (ms) | V2 Number of Changed Elements Found | Direct Comparison Processing Time till interaction in UI (ms) | Direct Comparison Number of Changed Elements Found | % diff between V2 and Direct Processing |
19+
| -- | -- | -- | -- | -- | -- | -- | -- |
20+
| 1036c64d-7fbe-47fd-b03c-4ed7ad7fc829 | c87854bc-1197-4ed9-8d3d-ad9cb5fd1347 | 12 | 22133 | 5342 | 6536 | 28039 | 108.807% |
21+
| 1036c64d-7fbe-47fd-b03c-4ed7ad7fc829 | e657e0d6-fad1-4971-9c22-459bd400534b | 524 | 185067 | 109474 | 71375 | 314907 | 88.6688% |
22+
| 1036c64d-7fbe-47fd-b03c-4ed7ad7fc829 | b8571aeb-dc0b-405f-bf6b-42401af40dd1 | 23 | 109007 | 128803 | 26017 | 22348 | 122.926% |
23+
24+
### RESULTS SUMMARY
25+
The most salient findings of our testing:
26+
27+
1. On iModels with a vast amount of data to process, Direct Comparison is on average 106.8 % faster than V2 Comparison.
28+
2. The UI has more elements to process with the Direct Comparison workflow than with the V2 workflow.
29+
3. The larger the IModel/changeset range. The v2 processing is faster due to multiple agents used for processing.
30+
31+
### CONCLUSION
32+
This experiment proved that the Direct Comparison workflow is viable and may be preferable in some situations for larger iModels due to its processing speed. Direct Comparison may be an efficacious solution to long waiting times if the user does not require the full information provided by property traversal.

package.json

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,15 @@
88
"test:components": "npm test --prefix packages/changed-elements-react",
99
"cover": "run-p --silent cover:*",
1010
"cover:components": "npm run test:cover --prefix packages/changed-elements-react",
11-
"lint": "eslint '**/*.{ts,tsx}'",
11+
"lint": "eslint ./packages/**/src/**/*.{ts,tsx}",
1212
"typecheck": "run-p --silent typecheck:*",
1313
"typecheck:components": "npm run typecheck --prefix packages/changed-elements-react",
1414
"typecheck:backend": "npm run typecheck --prefix packages/test-app-backend",
1515
"typecheck:frontend": "npm run typecheck --prefix packages/test-app-frontend",
1616
"check": "changeset status"
1717
},
1818
"engines": {
19-
"pnpm": ">=8",
19+
"pnpm": ">=10",
2020
"npm": "<0",
2121
"node": ">=20"
2222
},
@@ -43,6 +43,16 @@
4343
"axios@<1.8.2": ">=1.8.2",
4444
"dompurify@<3.2.4": ">=3.2.4",
4545
"esbuild@<=0.24.2": ">=0.25.0"
46-
}
46+
},
47+
"onlyBuiltDependencies": [
48+
"@bentley/imodeljs-native",
49+
"@parcel/watcher",
50+
"@swc/core",
51+
"esbuild",
52+
"protobufjs"
53+
]
54+
},
55+
"devDependencies": {
56+
"eslint-config-prettier": "^10.1.5"
4757
}
4858
}

packages/changed-elements-react/public/locales/en/VersionCompare.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
"searchResults": "Search Results",
4747
"removed": "Removed",
4848
"modified": "Modified",
49+
"driven": "Driven by another change",
4950
"loading": "Loading...",
5051
"versions": "Versions",
5152
"version": "Version",
@@ -153,8 +154,10 @@
153154
"hiddenProperty": "Hidden Properties",
154155
"placement": "Placement",
155156
"indirect": "Indirect",
157+
"driven": "Driven",
156158
"modifiedIndirectly": "Children modified",
157159
"modelHasChanges": "Model has changed elements",
160+
"modelHasDrivenChanges": "Model was changed indirectly",
158161
"childrenModified": "Child elements were modified",
159162
"childrenChanges": "Children changes",
160163
"childrenAdded": "Children were added",

packages/changed-elements-react/src/NamedVersionSelector/useComparisonJobs.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,6 @@ export function useComparisonJobs(args: UseComparisonJobsArgs): UseComparisonJob
8787
job,
8888
watchJob: async function* (pollingIntervalMs: number, signal?: AbortSignal) {
8989
signal?.throwIfAborted();
90-
9190
while (job.status === "Queued" || job.status === "Started") {
9291
await new Promise((resolve) => setTimeout(resolve, pollingIntervalMs));
9392
const comparisonJob = await getComparisonJob({

0 commit comments

Comments
 (0)