Hako.SourceGenerator
1.0.12
See the version list below for details.
dotnet add package Hako.SourceGenerator --version 1.0.12
NuGet\Install-Package Hako.SourceGenerator -Version 1.0.12
<PackageReference Include="Hako.SourceGenerator" Version="1.0.12"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> </PackageReference>
<PackageVersion Include="Hako.SourceGenerator" Version="1.0.12" />
<PackageReference Include="Hako.SourceGenerator"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> </PackageReference>
paket add Hako.SourceGenerator --version 1.0.12
#r "nuget: Hako.SourceGenerator, 1.0.12"
#:package Hako.SourceGenerator@1.0.12
#addin nuget:?package=Hako.SourceGenerator&version=1.0.12
#tool nuget:?package=Hako.SourceGenerator&version=1.0.12
Hako.SourceGenerator
Source generator for creating JavaScript/TypeScript bindings from .NET code for the Hako JavaScript engine.
Installation
dotnet add package Hako.SourceGenerator
Requirements
Enable XML documentation generation in your project:
<PropertyGroup>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup>
Usage
Class Bindings
Expose .NET classes to JavaScript with [JSClass]:
using HakoJS.SourceGeneration;
namespace MyApp;
/// <summary>
/// A 2D vector
/// </summary>
[JSClass(Name = "Vector2")]
public partial class Vector2
{
[JSConstructor]
public Vector2(double x = 0, double y = 0)
{
X = x;
Y = y;
}
[JSProperty(Name = "x")]
public double X { get; set; }
[JSProperty(Name = "y")]
public double Y { get; set; }
[JSMethod(Name = "add")]
public Vector2 Add(Vector2 other)
{
return new Vector2(X + other.X, Y + other.Y);
}
[JSMethod(Name = "length")]
public double Length()
{
return Math.Sqrt(X * X + Y * Y);
}
[JSMethod(Name = "lerp", Static = true)]
public static Vector2 Lerp(Vector2 a, Vector2 b, double t = 0.5)
{
return new Vector2(
a.X + (b.X - a.X) * t,
a.Y + (b.Y - a.Y) * t
);
}
}
Module Bindings
Create JavaScript modules with static members using [JSModule]:
using HakoJS.SourceGeneration;
namespace MyApp;
/// <summary>
/// Math utility functions
/// </summary>
[JSModule(Name = "math")]
[JSModuleClass(ClassType = typeof(Vector2), ExportName = "Vector2")]
public partial class MathModule
{
[JSModuleValue(Name = "PI")]
public static double Pi => Math.PI;
[JSModuleMethod(Name = "sqrt")]
public static double Sqrt(double x) => Math.Sqrt(x);
}
Object Bindings
Marshal record types between .NET and JavaScript with [JSObject]:
using HakoJS.SourceGeneration;
namespace MyApp;
/// <summary>
/// User configuration
/// </summary>
[JSObject]
public partial record Config(
string Name,
int Port = 8080,
string? Host = null
);
Delegate Support
Records can include delegates that are marshaled as JavaScript functions:
using HakoJS.SourceGeneration;
using System;
using System.Threading.Tasks;
namespace MyApp;
[JSObject]
public partial record EventHandler(
string EventName,
Action<string> OnEvent,
Func<int, Task<bool>> Validator
);
Runtime Usage
After the source generator creates the bindings, register and use them at runtime:
Using Classes
using var runtime = Hako.Initialize<WasmtimeEngine>();
await Hako.Dispatcher.InvokeAsync(async () =>
{
var realm = runtime.CreateRealm();
// Register the class
realm.RegisterClass<Vector2>();
// Use from C#
var vector = new Vector2(3, 4);
using var jsValue = vector.ToJSValue(realm);
// Use from JavaScript
var result = await realm.EvalAsync(@"
const v = new Vector2(1, 2);
console.log(v.length());
v.add(new Vector2(3, 4));
", new RealmEvalOptions { Type = EvalType.Module });
});
Using Modules
// Register module
runtime.ConfigureModules()
.WithModule<MathModule>()
.Apply();
// Use from JavaScript
var result = await realm.EvalAsync(@"
import { PI, sqrt, Vector2 } from 'math';
console.log('PI:', PI);
console.log('sqrt(16):', sqrt(16));
const v = new Vector2(3, 4);
console.log(v.toString());
", new RealmEvalOptions { Type = EvalType.Module });
Using Records (JSObject)
// C# to JS
var config = new Config("test", 8080);
using var jsConfig = config.ToJSValue(realm);
using var jsObj = await realm.EvalAsync("({ name: 'test', port: 3000 })");
var csharpConfig = jsObj.As<Config>();
Console.WriteLine(csharpConfig); // Config { Name = test, Port = 3000, Host = }
// With delegates (must dispose to release captured JS functions)
using var jsHandler = await realm.EvalAsync(@"
({
eventName: 'click',
onEvent: (msg) => console.log(msg),
validator: async (n) => n > 0
})");
using var handler = HakoSandbox.EventHandler.FromJSValue(realm, jsHandler);
handler.OnEvent("test"); // Calls JS function
Generated Output
The source generator produces:
- C# binding code: Marshaling logic between .NET and JavaScript
- TypeScript definitions: Accessible via
YourType.TypeDefinitionproperty with complete type information
TypeScript definitions are automatically generated for all types with [JSClass], [JSObject], [JSModule], or
implementing IJSMarshalable<T>. XML documentation comments (///) are converted to JSDoc format in the definitions.
Supported Types
- Primitives:
string,bool,int,long,float,double, etc. - Arrays:
T[](primitive element types) - Byte buffers:
byte[]toArrayBuffer - Typed arrays:
Uint8ArrayValue,Int32ArrayValue,Float64ArrayValue, etc. - Custom types: Any type with
[JSClass]or[JSObject], or manually implementingIJSMarshalable<T> - Delegates:
Action<T>,Func<T>, named delegates to JavaScript functions (sync and async) - Nullable types:
T?toT | null - Optional parameters: Default values supported
Attributes
Class Attributes
[JSClass(Name)]: Expose class as JavaScript class[JSConstructor]: Mark constructor to expose (optional, uses default if not specified)[JSProperty(Name, Static, ReadOnly)]: Expose property to JavaScript[JSMethod(Name, Static)]: Expose method to JavaScript[JSIgnore]: Exclude member from JavaScript binding
Module Attributes
[JSModule(Name)]: Create JavaScript module from static class[JSModuleValue(Name)]: Expose static field/property as module export[JSModuleMethod(Name)]: Expose static method as module function[JSModuleClass(ClassType, ExportName)]: Export a JSClass from a module
Record Attributes
[JSObject]: Marshal record types to/from JavaScript objects[JSPropertyName(Name)]: Customize JavaScript property name for record parameters
Documentation
XML documentation comments (///) are automatically converted to JSDoc format in the generated TypeScript definitions.
See the main Hako documentation for complete usage and API reference
Learn more about Target Frameworks and .NET Standard.
-
.NETStandard 2.0
- Microsoft.CodeAnalysis.CSharp (>= 5.0.0-2.final)
- Microsoft.CodeAnalysis.CSharp.Workspaces (>= 5.0.0-2.final)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.