# kopecp/web-view2-demo_multiwersion architecture

> Architecture diagram of the GitHub repository kopecp/web-view2-demo_multiwersion, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-06-23). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/kopecp/web-view2-demo_multiwersion
- Repository: https://github.com/kopecp/web-view2-demo_multiwersion

## Overview

1. **Overall shape**
   This repo is a two-process demo architecture: a **Revit add-in** written in .NET and a separate **web application** in Vue 2. The add-in hosts the Revit-side runtime; the web app is the UI surface. They communicate through a local bridge, and the actual Revit actions are pushed into versioned, load-on-demand DLL packages.

2. **Revit add-in boundary**
   `RevitWebView2Demo` is the main executable add-in. It contains the Revit entry points, dockable window/WebView hosting, event handlers, and the runtime that loads and executes packages. This is the boundary that talks directly to Revit API and must respect Revit’s external event model.

3. **Shared contracts**
   `RevitWebView2Demo.Abstractions` defines the contract layer between the host and the packages. `IRevitPackageCommand` and `RevitPackageContext` establish the minimum interface and execution context needed so that package DLLs can be loaded independently without tight coupling to the host implementation.

4. **Versioned package subsystem**
   `RevitWebView2Demo.Packages.CreateSheet` and `RevitWebView2Demo.Packages.SelectElements` are sample Revit API packages. Each package has its own project and manifest, and is meant to be deployed as a separately versioned artifact rather than compiled into the host add-in. This is the key “plugin-of-plugins” boundary in the architecture.

5. **Package runtime inside the add-in**
   The `PackageRuntime` folder implements the dynamic loading pipeline:
   - manifest parsing and package metadata,
   - path validation,
   - assembly resolution,
   - loading package assemblies,
   - queueing/executing package requests,
   - returning execution results.
   
   This runtime is the mechanism that turns a web request into a live Revit API operation.

6. **Safety and isolation around package loading**
   `PackagePathGuard`, `PackageAssemblyResolver`, `PackageSourceMarker`, and related types show that package loading is intentionally constrained. The host validates where packages come from and controls resolution so the add-in does not blindly load arbitrary DLLs. This is an important architectural boundary because packages are externalized and versioned.

7. **Revit UI interaction model**
   Revit actions are mediated by event handlers such as `RevitWv2EventHandler`, `SelectExternalEventHandler`, and UI commands like `ShowWebViewDockCommand` / `ShowWebView2Window`. This reflects the Revit pattern where external events are used to marshal work back onto the Revit UI thread rather than calling API operations directly from the web bridge.

8. **Web-to-Revit communication layer**
   `BrowserBridge` contains the local messaging infrastructure: a server, message envelopes, and outbound message types. Its role is to carry commands and responses between the browser UI and the add-in. The README indicates a **local WebSocket bridge** is used, with a fallback path through registry relay.

9. **Registry relay as an alternate connection path**
   `RegistryRelay` is a secondary communication subsystem consisting of client, web connection, message types, and a command to inspect active connections. Architecturally, this is a discovery/relay mechanism that helps the browser and the add-in find each other locally without hard-wiring a single communication path.

10. **Web application**
    The `web` folder is a standalone Vue 2 application with routing, a Revit demo component, and a small utility layer for webview/connection integration. It is the user-facing control plane for triggering Revit operations, not the place where Revit API logic lives.

11. **Web server and published package registry**
    `web/server.js` and `web/revit-registry.js` provide the local HTTP/WebSocket-serving side for development and connection coordination. The `public/revit-packages/...` tree acts as a package registry: the packaged DLLs and their `package.json` manifests are published here so the add-in can fetch them at runtime.

12. **Build and packaging pipeline**
    `tools/PackRevitPackage.ps1` is the packaging step that turns a package DLL into the web-published artifact format. The repo’s architecture depends on this split: packages are built from the Revit-package projects, packed, then served from the web app’s public directory for runtime download.

13. **Deployment assumptions**
    The solution is explicitly tied to Windows, Autodesk Revit versions 2022/2024/2025, and local install paths for `RevitAPI.dll`/`RevitAPIUI.dll`. The add-in build copies artifacts into the user’s Revit add-ins folder, while the web app assumes a local dev server at `http://localhost:8080/` during development.

14. **End-to-end data flow**
    A typical request path is:
    web UI action → browser bridge / relay message → add-in receives request → package runtime resolves and loads the target versioned DLL → external event executes Revit API work → result returns back through the bridge to the web UI.
    This is the central architecture diagram to capture: UI, bridge, host runtime, and package execution are separate layers with explicit message passing between them.

Main entry points: [`RevitWebView2Demo/PackageRuntime/RevitPackageLoader.cs`](https://github.com/kopecp/web-view2-demo_multiwersion/blob/main/RevitWebView2Demo/PackageRuntime/RevitPackageLoader.cs) (Package runtime), [`web/src/App.vue`](https://github.com/kopecp/web-view2-demo_multiwersion/blob/main/web/src/App.vue) (Vue app), [`RevitWebView2Demo/BrowserBridge/BrowserBridgeServer.cs`](https://github.com/kopecp/web-view2-demo_multiwersion/blob/main/RevitWebView2Demo/BrowserBridge/BrowserBridgeServer.cs) (Browser bridge), [`RevitWebView2Demo/App.cs`](https://github.com/kopecp/web-view2-demo_multiwersion/blob/main/RevitWebView2Demo/App.cs) (Add-in host)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_host["Revit add-in"]
  node_host_app["Add-in host<br/>revit host<br/>[App.cs]"]
  node_host_ui["WebView UI<br/>revit ui"]
  node_host_cmds["UI commands<br/>revit commands"]
  node_host_events["External events<br/>revit event bridge"]
  node_host_bridge["Browser bridge<br/>websocket bridge"]
  node_host_registry["Registry relay<br/>connection relay<br/>[RegistryClient.cs]"]
  node_host_runtime["Package runtime<br/>package loader"]
  node_host_guard["Path guard<br/>loading safety"]
  node_host_resolver["Assembly resolver<br/>assembly resolution"]
  node_host_queue["Exec queue<br/>request queue"]
end

subgraph group_contracts["Contracts"]
  node_contracts_api["Package API<br/>abstractions"]
  node_contracts_ctx["Package context<br/>execution context"]
end

subgraph group_packages["Versioned packages"]
  node_pkg_sheet["Create Sheet<br/>revit package"]
  node_pkg_select["Select Elements<br/>revit package"]
end

subgraph group_web["Web app"]
  node_web_app["Vue app<br/>frontend app<br/>[App.vue]"]
  node_web_home["Demo view<br/>vue view<br/>[Home.vue]"]
  node_web_bridge["Webview utils<br/>client bridge<br/>[webview2.js]"]
  node_web_server["Local server<br/>dev server<br/>[server.js]"]
  node_web_registry["Registry service<br/>registry server<br/>[revit-registry.js]"]
  node_web_packages[("Package registry<br/>published artifacts<br/>[package.json]")]
end

subgraph group_tools["Packaging"]
  node_tool_pack["Pack script<br/>package packer"]
end

node_host_app -->|"hosts"| node_host_ui
node_host_app -->|"exposes"| node_host_cmds
node_host_cmds -->|"opens"| node_host_ui
node_host_ui -->|"connects"| node_host_bridge
node_host_bridge -->|"messages"| node_web_app
node_web_app -->|"renders"| node_web_home
node_web_app -->|"uses"| node_web_bridge
node_web_app -->|"served by"| node_web_server
node_web_server -->|"coordinates"| node_web_registry
node_web_registry -->|"relays"| node_host_registry
node_host_bridge -->|"dispatches"| node_host_runtime
node_host_runtime -->|"validates"| node_host_guard
node_host_runtime -->|"loads"| node_host_resolver
node_host_runtime -->|"queues"| node_host_queue
node_host_runtime -->|"depends on"| node_contracts_api
node_host_runtime -->|"provides"| node_contracts_ctx
node_host_runtime -->|"executes"| node_pkg_sheet
node_host_runtime -->|"executes"| node_pkg_select
node_pkg_sheet -->|"implements"| node_contracts_api
node_pkg_select -->|"implements"| node_contracts_api
node_pkg_sheet -->|"uses"| node_contracts_ctx
node_pkg_select -->|"uses"| node_contracts_ctx
node_host_app -->|"marshals"| node_host_events
node_host_events -->|"triggers"| node_host_runtime
node_host_registry -.->|"fallback"| node_host_bridge
node_web_packages -->|"published for"| node_host_runtime
node_tool_pack -->|"builds"| node_web_packages

click node_host_app "https://github.com/kopecp/web-view2-demo_multiwersion/blob/main/RevitWebView2Demo/App.cs"
click node_host_ui "https://github.com/kopecp/web-view2-demo_multiwersion/blob/main/RevitWebView2Demo/WebView2Window.xaml.cs"
click node_host_cmds "https://github.com/kopecp/web-view2-demo_multiwersion/blob/main/RevitWebView2Demo/ShowWebViewDockCommand.cs"
click node_host_events "https://github.com/kopecp/web-view2-demo_multiwersion/blob/main/RevitWebView2Demo/RevitWv2EventHandler.cs"
click node_host_bridge "https://github.com/kopecp/web-view2-demo_multiwersion/blob/main/RevitWebView2Demo/BrowserBridge/BrowserBridgeServer.cs"
click node_host_registry "https://github.com/kopecp/web-view2-demo_multiwersion/blob/main/RevitWebView2Demo/RegistryRelay/RegistryClient.cs"
click node_host_runtime "https://github.com/kopecp/web-view2-demo_multiwersion/blob/main/RevitWebView2Demo/PackageRuntime/RevitPackageLoader.cs"
click node_host_guard "https://github.com/kopecp/web-view2-demo_multiwersion/blob/main/RevitWebView2Demo/PackageRuntime/PackagePathGuard.cs"
click node_host_resolver "https://github.com/kopecp/web-view2-demo_multiwersion/blob/main/RevitWebView2Demo/PackageRuntime/PackageAssemblyResolver.cs"
click node_host_queue "https://github.com/kopecp/web-view2-demo_multiwersion/blob/main/RevitWebView2Demo/PackageRuntime/PackageExecutionQueueItem.cs"
click node_contracts_api "https://github.com/kopecp/web-view2-demo_multiwersion/blob/main/RevitWebView2Demo.Abstractions/IRevitPackageCommand.cs"
click node_contracts_ctx "https://github.com/kopecp/web-view2-demo_multiwersion/blob/main/RevitWebView2Demo.Abstractions/RevitPackageContext.cs"
click node_pkg_sheet "https://github.com/kopecp/web-view2-demo_multiwersion/blob/main/RevitWebView2Demo.Packages.CreateSheet/CreateSheetCommand.cs"
click node_pkg_select "https://github.com/kopecp/web-view2-demo_multiwersion/blob/main/RevitWebView2Demo.Packages.SelectElements/SelectElementsCommand.cs"
click node_web_app "https://github.com/kopecp/web-view2-demo_multiwersion/blob/main/web/src/App.vue"
click node_web_home "https://github.com/kopecp/web-view2-demo_multiwersion/blob/main/web/src/views/Home.vue"
click node_web_bridge "https://github.com/kopecp/web-view2-demo_multiwersion/blob/main/web/src/utils/webview2.js"
click node_web_server "https://github.com/kopecp/web-view2-demo_multiwersion/blob/main/web/server.js"
click node_web_registry "https://github.com/kopecp/web-view2-demo_multiwersion/blob/main/web/revit-registry.js"
click node_web_packages "https://github.com/kopecp/web-view2-demo_multiwersion/blob/main/web/public/revit-packages/create-sheet/1.0.0/package.json"
click node_tool_pack "https://github.com/kopecp/web-view2-demo_multiwersion/blob/main/tools/PackRevitPackage.ps1"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_host_app,node_host_ui,node_host_cmds,node_host_events,node_host_bridge,node_host_registry,node_host_runtime,node_host_guard,node_host_resolver,node_host_queue toneBlue
class node_contracts_api,node_contracts_ctx toneAmber
class node_pkg_sheet,node_pkg_select toneMint
class node_web_app,node_web_home,node_web_bridge,node_web_server,node_web_registry,node_web_packages toneRose
class node_tool_pack toneIndigo
```

## Components

### Revit add-in

Revit-hosted .NET boundary, UI, bridge, and package runtime.

- [Add-in host](https://github.com/kopecp/web-view2-demo_multiwersion/blob/main/RevitWebView2Demo/App.cs): revit host · Main executable add-in entry point and Revit integration boundary. · `RevitWebView2Demo/App.cs`
- [WebView UI](https://github.com/kopecp/web-view2-demo_multiwersion/blob/main/RevitWebView2Demo/WebView2Window.xaml.cs): revit ui · Dockable window and WebView2 window hosting for the browser surface. · `RevitWebView2Demo/WebView2Window.xaml.cs`
- [UI commands](https://github.com/kopecp/web-view2-demo_multiwersion/blob/main/RevitWebView2Demo/ShowWebViewDockCommand.cs): revit commands · Commands that open the WebView window and docked panel. · `RevitWebView2Demo/ShowWebViewDockCommand.cs`
- [External events](https://github.com/kopecp/web-view2-demo_multiwersion/blob/main/RevitWebView2Demo/RevitWv2EventHandler.cs): revit event bridge · External-event handlers that marshal work back onto the Revit UI thread. · `RevitWebView2Demo/RevitWv2EventHandler.cs`
- [Browser bridge](https://github.com/kopecp/web-view2-demo_multiwersion/blob/main/RevitWebView2Demo/BrowserBridge/BrowserBridgeServer.cs): websocket bridge · Local messaging layer between browser UI and the add-in. · `RevitWebView2Demo/BrowserBridge/BrowserBridgeServer.cs`
- [Registry relay](https://github.com/kopecp/web-view2-demo_multiwersion/blob/main/RevitWebView2Demo/RegistryRelay/RegistryClient.cs): connection relay · Alternate local discovery and connection path for the browser and add-in. · `RevitWebView2Demo/RegistryRelay/RegistryClient.cs`
- [Package runtime](https://github.com/kopecp/web-view2-demo_multiwersion/blob/main/RevitWebView2Demo/PackageRuntime/RevitPackageLoader.cs): package loader · Dynamic loading and execution pipeline for externalized Revit packages. · `RevitWebView2Demo/PackageRuntime/RevitPackageLoader.cs`
- [Path guard](https://github.com/kopecp/web-view2-demo_multiwersion/blob/main/RevitWebView2Demo/PackageRuntime/PackagePathGuard.cs): loading safety · Constrains package origins and validates load paths before execution. · `RevitWebView2Demo/PackageRuntime/PackagePathGuard.cs`
- [Assembly resolver](https://github.com/kopecp/web-view2-demo_multiwersion/blob/main/RevitWebView2Demo/PackageRuntime/PackageAssemblyResolver.cs): assembly resolution · Resolves package assemblies during load and execution. · `RevitWebView2Demo/PackageRuntime/PackageAssemblyResolver.cs`
- [Exec queue](https://github.com/kopecp/web-view2-demo_multiwersion/blob/main/RevitWebView2Demo/PackageRuntime/PackageExecutionQueueItem.cs): request queue · Queues package execution requests and returns results. · `RevitWebView2Demo/PackageRuntime/PackageExecutionQueueItem.cs`

### Contracts

Shared abstractions used by host and versioned packages.

- [Package API](https://github.com/kopecp/web-view2-demo_multiwersion/blob/main/RevitWebView2Demo.Abstractions/IRevitPackageCommand.cs): abstractions · Shared package contract interface for independently loaded commands. · `RevitWebView2Demo.Abstractions/IRevitPackageCommand.cs`
- [Package context](https://github.com/kopecp/web-view2-demo_multiwersion/blob/main/RevitWebView2Demo.Abstractions/RevitPackageContext.cs): execution context · Minimum execution context passed from host into packages. · `RevitWebView2Demo.Abstractions/RevitPackageContext.cs`

### Versioned packages

Load-on-demand Revit API package projects and their manifests.

- [Create Sheet](https://github.com/kopecp/web-view2-demo_multiwersion/blob/main/RevitWebView2Demo.Packages.CreateSheet/CreateSheetCommand.cs): revit package · Sample package that performs sheet creation via the Revit API. · `RevitWebView2Demo.Packages.CreateSheet/CreateSheetCommand.cs`
- [Select Elements](https://github.com/kopecp/web-view2-demo_multiwersion/blob/main/RevitWebView2Demo.Packages.SelectElements/SelectElementsCommand.cs): revit package · Sample package that drives element selection via the Revit API. · `RevitWebView2Demo.Packages.SelectElements/SelectElementsCommand.cs`

### Web app

Standalone Vue 2 control plane and local connection server.

- [Vue app](https://github.com/kopecp/web-view2-demo_multiwersion/blob/main/web/src/App.vue): frontend app · Standalone Vue 2 application used as the user-facing control plane. · `web/src/App.vue`
- [Demo view](https://github.com/kopecp/web-view2-demo_multiwersion/blob/main/web/src/views/Home.vue): vue view · Primary Revit demo view exposed by the web UI. · `web/src/views/Home.vue`
- [Webview utils](https://github.com/kopecp/web-view2-demo_multiwersion/blob/main/web/src/utils/webview2.js): client bridge · Client-side webview integration helpers for browser-to-host communication. · `web/src/utils/webview2.js`
- [Local server](https://github.com/kopecp/web-view2-demo_multiwersion/blob/main/web/server.js): dev server · Local HTTP/WebSocket serving and coordination for development. · `web/server.js`
- [Registry service](https://github.com/kopecp/web-view2-demo_multiwersion/blob/main/web/revit-registry.js): registry server · Web-side registry coordination for locating the host connection. · `web/revit-registry.js`
- [Package registry](https://github.com/kopecp/web-view2-demo_multiwersion/blob/main/web/public/revit-packages/create-sheet/1.0.0/package.json): published artifacts · Published package manifests and archives served to the host at runtime. · `web/public/revit-packages/create-sheet/1.0.0/package.json`

### Packaging

Build-time packaging step for publishing package artifacts.

- [Pack script](https://github.com/kopecp/web-view2-demo_multiwersion/blob/main/tools/PackRevitPackage.ps1): package packer · Build-time script that turns a package DLL into a web-published artifact. · `tools/PackRevitPackage.ps1`

## Connections

- Add-in host → WebView UI: hosts · The add-in creates and hosts the WebView2 UI surface.
- Add-in host → UI commands: exposes · Revit commands open the window or dockable panel.
- UI commands → WebView UI: opens · Commands launch the browser UI container.
- WebView UI → Browser bridge: connects · The webview UI attaches to the local browser bridge.
- Browser bridge → Vue app: messages · Browser messages carry commands and responses to the Vue app.
- Vue app → Demo view: renders · The main app routes to the demo view.
- Vue app → Webview utils: uses · Client helpers mediate webview communication.
- Vue app → Local server: served by · The app is hosted by the local dev server.
- Local server → Registry service: coordinates · Server-side coordination supports discovery and relay.
- Registry service → Registry relay: relays · Registry coordination helps the browser and add-in find each other.
- Browser bridge → Package runtime: dispatches · Incoming browser requests are routed into package execution.
- Package runtime → Path guard: validates · Package origins and paths are checked before load.
- Package runtime → Assembly resolver: loads · Assembly resolution is delegated during package loading.
- Package runtime → Exec queue: queues · Execution requests are queued and processed through the runtime.
- Package runtime → Package API: depends on · Loaded packages implement the shared command contract.
- Package runtime → Package context: provides · The host passes execution context into package commands.
- Package runtime → Create Sheet: executes · The runtime can load and run the Create Sheet package.
- Package runtime → Select Elements: executes · The runtime can load and run the Select Elements package.
- Create Sheet → Package API: implements · Package command follows the shared contract.
- Select Elements → Package API: implements · Package command follows the shared contract.
- Create Sheet → Package context: uses · Package work is driven by the host-provided context.
- Select Elements → Package context: uses · Package work is driven by the host-provided context.
- Add-in host → External events: marshals · Revit work is executed through external events.
- External events → Package runtime: triggers · External events trigger package execution on the Revit thread.
- Registry relay → Browser bridge: fallback · Registry relay acts as an alternate connection path.
- Package registry → Package runtime: published for · Published package artifacts are fetched by the host runtime.
- Pack script → Package registry: builds · The packaging script produces the published artifact format.
