Topaz 1.0.2

Prefix Reserved
There is a newer version of this package available.
See the version list below for details.
dotnet add package Topaz --version 1.0.2                
NuGet\Install-Package Topaz -Version 1.0.2                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Topaz" Version="1.0.2" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Topaz --version 1.0.2                
#r "nuget: Topaz, 1.0.2"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install Topaz as a Cake Addin
#addin nuget:?package=Topaz&version=1.0.2

// Install Topaz as a Cake Tool
#tool nuget:?package=Topaz&version=1.0.2                

Topaz

Multithreaded Javascript Engine for .NET

Why another Javascript Engine?

  1. Existing Javascript Engines run scripts in single-thread. That is acceptable for desktop environments but not pleasing for server-side execution.

  2. I needed fine control in the language syntax and rules for my project. I could not find any engine that provides such features. For example, I want to turn off 'undefined' and treat all as 'null', or I want 'assignments without variable kind' scope to be in declaration scope but not in the global scope.

  3. Another important need is to turn off every null pointer exception including function call or member access of a 'null' object. These will ease the life of non-experienced developers to write scripts without putting everywhere question marks (condition operator, null checks) or getting annoying errors.

  4. I want minimum amount of overhead, no C++ marshaling and minimum memory usage.

  5. Lock free and high-performance implementation.

How is the performance of Topaz?

I have developed a server-side HTML page rendering application using Razor. After a while, I have realized Razor was not flexible for my microservice architecture and business needs.

Then I switched to ClearScript. Clearscript uses Google's v8 C++ engine using locks and marshaling everywhere which slows down things. I barely served 100 requests per second on my desktop. Moreover, memory consumption was too high: 800 MB for a couple of page rendering.

Then I switched to Jint. Jint is very successful in terms of performance (I get ~1600 page views per second) and memory consumption is also good. (~80 MB) Jint is excellent with its extreme support for Javascript native data structures. The only downside of Jint is it does not support parallel execution on even simple function calls. I had to lock my page request. That was not acceptable for my business.

Thanks to Sebastien Ros. He has written an excellent Esprima port which makes writing JS runtime a piece of cake.

So I decided to write my own!

This is how Topaz was born.

I hear you are saying tell me the numbers.

Here is the answer:

Topaz Performance on server-side rendering hits 3700 per second. Memory consumption is ~80MB. It is a good start. Topaz performs better than Jint in performance. Moreover, it supports multi-threading out of the box! The server-side rendering application that I wrote using Topaz surpasses Razor runtime rendering with x2 faster execution. Additionally, Razor initialization takes a few seconds that is annoying. Topaz is ready at first glance!

That is just the beginning. There is still room for performance improvements. Furthermore, a lot of features in the backlog are waiting for implementation.

Stay in touch.

How can I use Topaz?

Here is the Nuget Link.

Hello world application:

var engine = new TopazEngine();
engine.AddType(typeof(Console), "Console");
engine.SetValue("name", "Topaz");
engine.ExecuteScript(@"Console.WriteLine('Hello World, from ' + name)");

Async Http Get:

An example of fetching HTTP content without blocking executing thread.

var engine = new TopazEngine();
engine.AddType<HttpClient>("HttpClient");
engine.AddType(typeof(Console), "Console");
engine.AddType<Uri>("Uri");
var task = engine.ExecuteScriptAsync(@"
async function httpGet(url) {
    try {
        var httpClient = new HttpClient()
        var response = await httpClient.GetAsync(url)
        return await response.Content.ReadAsStringAsync()
    }
    catch (err) {
        Console.WriteLine('Caught Error:\n' + err)
    }
    finally {
        httpClient.Dispose();
    }
}
const html = await httpGet('http://example.com')
Console.WriteLine(html);
");
task.Wait();

Feature List:

  • for loops
  • for .. in iterators
  • for .. of iterators
  • switch case statement
  • functions
  • arrow functions
  • object destructring
  • array destructring
  • await
  • if else statements
  • while, do while statements
  • conditional statements
  • rest and spread elements (...)
  • template literals
  • tagged Template literals
  • try catch finally statement
  • throw statement
  • new expression (constructor)
  • static member and function call of CLR types
  • automatic type conversion for CLR calls
  • binary operators
  • unary operators
  • flow statements (break, continue, return)
  • optional chaining
  • typeof operator
  • instanceof operator
  • in operator

more is coming...

Despite the fact that the current feature set is more than enough for my needs, I am eager to improve this engine to support a lot more.

I appreciate any feedback and contributions to the project.

Topaz Engine Options:

  VarScopeBehavior: FunctionScope | DeclarationScope

  AssignmentWithoutDefinitionBehavior:
    DefineAsVarInExecutionScope |
    DefineAsVarInGlobalScope |
    DefineAsVarInFirstChildOfGlobalScope |
    DefineAsLetInExecutionScope |
    ThrowException

  NoUndefined: true | false

  AllowNullReferenceMemberAccess: true | false

  AllowUndefinedReferenceMemberAccess: true | false

  AllowUndefinedReferenceAccess: true | false
Product Compatible and additional computed target framework versions.
.NET net5.0 is compatible.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net5.0

    • No dependencies.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on Topaz:

Package Downloads
TopazView

TopazView is a lightweight view engine that utilizes the Topaz JavaScript Engine.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
1.4.1 72 11/14/2024
1.4.0 965 5/5/2024
1.3.9 1,360 1/1/2024
1.3.8.9 117 1/1/2024
1.3.8 133 12/24/2023
1.3.7.9 96 12/24/2023
1.3.7 159 10/10/2023
1.3.6 527 8/4/2023
1.3.5.1 137 8/4/2023
1.3.5 153 6/24/2023
1.3.4 263 6/11/2023
1.3.3 127 6/10/2023
1.3.2 269 6/8/2023
1.3.1 152 6/8/2023
1.3.0 227 3/12/2023
1.2.9 207 3/12/2023
1.2.8 315 12/3/2022
1.2.7 334 11/13/2022
1.2.6 329 11/13/2022
1.2.5 488 9/14/2022
1.2.4 505 3/23/2022
1.2.3 422 3/23/2022
1.2.2 381 11/14/2021
1.2.1 288 11/13/2021
1.2.0 337 11/13/2021
1.1.9 315 11/12/2021
1.1.8 344 11/12/2021
1.1.7 325 11/10/2021
1.1.6 307 11/9/2021
1.1.5 296 11/9/2021
1.1.4 302 11/8/2021
1.1.3 309 11/8/2021
1.1.2 345 11/7/2021
1.1.1 318 11/7/2021
1.1.0 330 11/7/2021
1.0.9 389 11/7/2021
1.0.8 345 11/4/2021
1.0.7 327 11/1/2021
1.0.6 366 11/1/2021
1.0.5 369 10/31/2021
1.0.4 359 10/31/2021
1.0.3 601 10/31/2021
1.0.2 539 10/29/2021
1.0.1 584 10/28/2021