PardusLabs.JSVaporizer.NET.8
1.0.9.5
dotnet add package PardusLabs.JSVaporizer.NET.8 --version 1.0.9.5
NuGet\Install-Package PardusLabs.JSVaporizer.NET.8 -Version 1.0.9.5
<PackageReference Include="PardusLabs.JSVaporizer.NET.8" Version="1.0.9.5" />
<PackageVersion Include="PardusLabs.JSVaporizer.NET.8" Version="1.0.9.5" />
<PackageReference Include="PardusLabs.JSVaporizer.NET.8" />
paket add PardusLabs.JSVaporizer.NET.8 --version 1.0.9.5
#r "nuget: PardusLabs.JSVaporizer.NET.8, 1.0.9.5"
#addin nuget:?package=PardusLabs.JSVaporizer.NET.8&version=1.0.9.5
#tool nuget:?package=PardusLabs.JSVaporizer.NET.8&version=1.0.9.5
JSVaporizer & JSVNuFlexiArch
This repository provides a custom .NET WebAssembly interop layer (in the JSVaporizer
namespace) and a small component framework (in the JSVNuFlexiArch
namespace) for building interactive web UI entirely in C#. The code demonstrates how to directly call and expose JavaScript functions using [JSImport]
and [JSExport]
, while managing DOM elements, events, and state in C#.
Table of Contents
- Overview
- Architecture
- Key Features
- Usage
- Creating Custom Components
- Known Limitations / Caveats
- Contributing
- License
Overview
This project shows how to integrate .NET code with browser APIs via [JSExport]
and [JSImport]
, as well as how to implement a basic “component” system. JSVaporizer is the low-level library that calls or is called by JavaScript, while JSVNuFlexiArch provides:
- A small model for defining and rendering UI components (buttons, checkboxes, sliders, etc.).
- A “transformer” mechanism for converting JSON data into a component view and vice versa.
The code is particularly useful if you want to avoid a JavaScript-based front-end framework or the full Blazor stack, and instead manually manage DOM elements from C#.
Architecture
JSVaporizer (Interop Layer)
- Interop Classes
WasmElement
,WasmDocument
,WasmWindow
, etc. wrap DOM APIs using[JSImport("functionName", "moduleName")]
.WasmJSVEventHandlerPool
,WasmJSVGenericFuncPool
maintain dictionaries of C# delegates for event handling or generic function callbacks keyed by a string.
Element
Class- Manages references to browser DOM objects. Uses ephemeral
JSObject
references that are disposed once the element is attached to the DOM. Further calls use the element’sId
to look up a freshJSObject
.
- Manages references to browser DOM objects. Uses ephemeral
- Event Handling
- Events are registered via
AddEventListener(string eventType, string funcKey, EventHandlerCalledFromJS handler)
. - The event callback is passed from JS back to C# using
[JSExport]
, then triggers the appropriate function fromWasmJSVEventHandlerPool
.
- Events are registered via
JSVNuFlexiArch (Components)
JSVComponent
: An abstract base class representing a “component” with:- A
Metadata
object that stores key-value pairs (such as a unique prefix or the assembly-qualified type name). - Methods to render HTML (
Renderer.Render()
), update state (UpdateState()
), and retrieve state (GetState()
). - JSON serialization hooks to store/restore component data (
SerializeState()
/DeserializeState()
).
- A
- Renderers
- Components define how they generate DOM elements (labels, inputs, etc.) via classes like
JSVButtonRenderer
,JSVCheckboxRenderer
, etc. JSVComponentRenderer
handles the basic pattern of writing opening and closing<div>
tags, while a subclass’sRenderBody(...)
supplies the inner HTML.
- Components define how they generate DOM elements (labels, inputs, etc.) via classes like
- Concrete Components
JSVButton
: Renders a<button>
with an optional label.JSVCheckbox
: Renders an<input type="checkbox">
plus label.JSVSlider
: Renders an<input type="range">
plus label and displays the current numeric value.JSVTextDisplay
: Renders text inside a<span>
.JSVTextInput
: Renders an<input type="text">
plus an optional label.
Transformer Architecture
JSVTransformer
- An abstract class for taking a JSON string (a DTO) and turning it into a view representation, or converting the current view back into a DTO.
- Each transformer implements methods such as
JsonToDto(string dtoJson)
,DtoToView(string dtoJson, string? userInfoJson = null)
, andViewToDto()
. - A typical flow is:
- Load a JSON string.
- Convert it to a data object (
TransformerDto
). - Render or update a UI component.
- Capture changes from the UI back into a DTO.
TransformerDto
- A base or marker class for data objects used in transformation. Your custom transformers may define subclasses representing specific data structures.
TransformerRegistry
- Maintains a dictionary of transformers (
JSVTransformer
instances) keyed by a string (e.g., a name or identifier). - Allows you to look up the correct transformer at runtime (
transformerRegistry.Get(xFormerName)
) and invoke it. - Provides a static
Invoke(...)
method to load a transformer by name, runDtoToView(...)
, and return the resulting HTML or other data.
- Maintains a dictionary of transformers (
Key Features
Low-Level DOM Control
Read/write DOM properties (e.g.,.innerHTML
,.disabled
,.value
), manage attributes, and register/unregister event listeners entirely in C#.Events and Callbacks
The dictionary-based “pool” mechanism lets you register event listeners with unique “function keys,” bridging from JavaScript events back to C#.Ephemeral
JSObject
Usage
Minimizes memory usage by disposing of expensiveJSObject
references after each operation and re-fetching them by ID when needed.Customizable Components
Each component encapsulates its state in a data-transfer object (DTO) and can be easily extended or combined. State changes are reflected in the DOM and vice versa.Source-Generated JSON
Uses[JsonSerializable]
attributes for efficient serialization without reflection. Each component’s data DTO has its own generated context.Flexible Transformers
Implement your ownJSVTransformer
to handle custom data flows from JSON → component → JSON, using theTransformerRegistry
to retrieve and apply them on demand.
Usage
Prerequisites
- .NET 7 or higher SDK (for WebAssembly support and
[JSImport]
/[JSExport]
usage). - A compatible toolchain for .NET WebAssembly projects, such as a Blazor WebAssembly app or a console-like WASM app with the right build targets.
- A modern browser that supports WebAssembly.
Building and Running
- Clone or copy this repository into your local environment.
- Open the
.csproj
in Visual Studio, VS Code, or your preferred editor. - Build the project:
dotnet build
- If this is part of a Blazor WebAssembly app, run it:
dotnet run
- Open the site in your browser. The .NET → JavaScript bridging code should load automatically.
Basic Example
Suppose you want to create and render a JSVButton
:
// Example usage in a Blazor page or other .NET WASM entry point:
// 1. Create a unique name for the button.
string uniqueName = "MyFirstButton";
// 2. Instantiate the button.
JSVButton button = new JSVButton(uniqueName);
// 3. Render the button into a container element in the DOM.
bool appended = JSVComponentMaterializer.Render(uniqueName, button, "someContainerId", append: true);
// 4. Update the button’s state from a DTO.
var buttonDto = new ButtonDataDto { Label = "Click me!", Text = "Submit", IsDisabled = false };
button.UpdateState(buttonDto);
// 5. Optionally wire up additional events in the Initialize() method or manually.
In this snippet, the code uses your existing JSVComponentMaterializer.Render(...)
method to generate HTML for the button and place it into a DOM element with ID someContainerId
.
Creating Custom Components
- Inherit from
JSVComponent
. - Provide a constructor that sets up a unique prefix and assigns a renderer:
public class MyNewComponent : JSVComponent { public MyNewComponent(string uniqueName) { Renderer = new MyComponentRenderer(); // custom renderer Metadata.Add("UnqPrefix", uniqueName); Metadata.Add("CompTypeAQN", GetAssemblyQualifiedName()); // ... Additional setup ... } }
- Implement methods like
UpdateState(...)
andGetState()
to push or pull data from the DOM. - Create a renderer subclass that overrides
RenderBody(...)
:public class MyComponentRenderer : JSVComponentRenderer { protected override void RenderBody(JSVComponent tmpComp, HtmlContentBuilder htmlCB) { // Build the HTML for your component, e.g.: htmlCB.AppendHtml($"<div id=\"{...}\">Hello World</div>"); } }
- Use
[JsonSerializable]
attributes if you want a strongly typed DTO for your component’s state. - Test the component in your host application (e.g., a Blazor WASM app).
Known Limitations / Caveats
- Event Key Collisions: Each event listener is associated with a string
funcKey
. Make sure these keys remain unique or you could overwrite an existing handler. - Case-Sensitive Attributes: In the
Element
class, attributes must be lowercase, reflecting how browsers typically normalize attribute names. - Renaming IDs: Changing an element’s
id
at runtime is not supported because the library uses IDs to track DOM references. GetText()
Unimplemented: In some components (e.g.,JSVTextDisplay
), certain getter methods (GetText()
) are placeholders withNotImplementedException
. If you need that functionality, you’ll need to implement it.- Performance Overhead: Because ephemeral
JSObject
references are disposed after each usage, the code often re-fetches DOM elements by ID. This is simpler to manage but can be slower with frequent property reads/writes. - Transformer Keys: If you use multiple transformers, ensure your registry keys (the
xFormerRegistryKey
) are unique to avoid collisions inTransformerRegistry
.
Contributing
Contributions are welcome! If you find a bug or want to request a feature, please open an issue or submit a pull request. To contribute:
- Fork this repository.
- Create a new branch for your changes.
- Commit and push to your fork.
- Open a pull request describing the changes.
License
(If you have a specific open-source license, place it here. For example, MIT.)
This project is licensed under the MIT License. See the LICENSE
file for details.
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. |
-
net8.0
- Microsoft.AspNetCore.Html.Abstractions (>= 2.3.0)
- Microsoft.AspNetCore.Mvc.ViewFeatures (>= 2.3.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last updated |
---|---|---|
1.0.9.5 | 106 | a day ago |