The Bridge.NET team has been working overtime to ensure version 1.12 is packed full of important new features and fixes. We’re excited to announce the immediate availability of Bridge.NET 1.12.

Please download or install using NuGet.

> install-package bridge

For a full list of closed issues, please review in the GitHub Bridge repository. There’s a lot to cover, so let’s jump into Bridge 1.12.

Regex Support

In prior releases, Bridge provided great coverage of the JavaScript Regex API, including the JavaScript native test , search and replace functions.

While providing JavaScript Regex API coverage was excellent for porting JavaScript code into C#, it wasn’t the best if you were attempting to reuse existing C# Regex code with the Bridge compiler. The API support just wasn’t there and developers were forced to re-write C# code into the simpler JavaScript Regex engine, or just avoid porting altogether.

We have re-focused our efforts and are investing resources into ensuring the API and functionality coverage within Bridge is focused on supporting the C# API first.

Our ultimate goal is that you should be able to take any existing C# code supported by a .NET Portable Class Library and compile it directly to JavaScript using Bridge.NET, without making a single modification to the original C# source.

As of Bridge 1.12 we’ve taken a major step closer to that goal, and we’re thrilled to announce support for the .NET System.Text.RegularExpressions namespace, including the Match class, Named Capture Groups, MatchCollection and GroupCollection classes.

Including .NET Regular Expressions compiler support within Bridge 1.12 required focusing on two goals:

.NET System.Text.RegularExpressions API (classes and methods) .NET Regular Expressions Engine (logic)

The following sample matches any word that begins with the characters th and is not followed by an o . This sample also demonstrates the use of the Negative Character Group [^] functionality. The example is taken directly from Regular Expression Language - Quick Reference on MSDN.

Example (Deck)

The highlight feature of the new Regular Express support is Named Captured Groups.

The JavaScript Regex engine does not include named captured group functionality, so this is a big advantage for .NET developers and now with great support within Bridge, a whole new platform of opportunities for existing .NET code has been opened up.

Let’s have a look at a sample using C# Named Captured Groups.

Example (Deck)

The output from the above is:

The new Regex functionality is also well covered by more than 2200 new unit tests.

C# Regex features yet to be implemented are listed in Issue #1167.

The work for Regex support within Bridge was initiated by Issue #701.

Expanded .NET Regular Expressions support will be added in future releases, and please let us know if there’s something you really need and we’ll do our best to add support.

Long Type Support

Another core piece of .NET functionality that has been added with Bridge 1.12 is support for long and ulong.

We’re hearing whispers from the community of projects using Bridge to compile advanced .NET encryption and arithmetic projects into JavaScript, although lack of big number power was a limiting factor. Well, no more.

The goal was to perfectly mimic the native .NET behaviour, and we’re happy to say that Bridge 1.12 brings full support of long and ulong types (Issue #778). For references: MSDN long and ulong documentation.

Support for the checked and uncheсked keywords has also been included, as well as OverflowMode and CheckForOverflowUnderflow options. You can find thorough details on these features in Issue #1092.

The example below demonstrates some basic long operations.

Example (Deck)

The sample outputs:

-9223372036854775808

9223372036854775807

-1

6253480962446024716

0

Do you know a factorial of 13 cannot be calculated using the int type, because the result exceeds int.MaxValue. An int can only calculate a factorial up to 12 . The long type lets us go a little further - up to 20 .

The following sample demonstrates factorial calculations.

Example (Deck)

And outputs the following to the Console:

int.MaxValue: 2147483647

Factorial of 12: 479001600

Factorial of 13: 6227020800

long.MaxValue: 9223372036854775807

Factorial of 20: 2432902008176640000

Factorial of 21: -4249290049419214848

Decimal Support Enhancements

Decimal class support was added to Bridge in the 1.8 release, but it was time for an upgrade.

The underlying Decimal.js library has been improved, so we’ve included the latest v5 release (Issue #1039). Decimal.js CHANGELOG documents a nice list of fixes and enhancements which automatically flowed into Bridge with the upgrade.

One such enhancement is removal of the 15 digits limitation which was reported by our community. Bridge 1.12 fixes this problem and it felt great to inform the Bridge community of the fix.

WebSockets

It is always so exciting to receive pull requests from Bridge Community members, and we’ve had some amazing pull requests sent to us during this last cycle.

This time it was the GitHub user @Dia6lo who contributed support for the HTML5 WebSocket API (Issue #776). The pull request quality from @Dia6lo was very high and it was a pleasure to merge.

To test and demonstrate the WebSocket functionality we have recreated the websocket.org’s Echo Test Demo using Bridge. The full source code for the WebSocket demo is available if you want to explore, or test the demo itself online.

More WebSocket support is planned for the Bridge 1.13 release. In particular, the implementation of some entities within the System.Net.WebSockets namespace such as ClientWebSocket. Again, contributed by @Dia6lo via a pull request.

C# Random Class Support

Incorporating Random class support in Bridge 1.12 was a genuine proof of the C#-to-JavaScript compiler concept.

Working on the Random class support (Issue #1080) we ate our own dog food, i.e. we used Bridge as a tool to create a JavaScript implementation of C# Random class.

The requirement was to 100% match C# Random class API and the goal has been achieved, because we compiled the actual original C# Core source code into JavaScript.

The native C# Random classes unit tests were also incorporated into Bridge, ensuring 100% .NET API compatibility.

Instructions on how to compile .NET C# source code into high-quality JavaScript libraries with 100% .NET API compatibility are included in Issue #1118.

The following sample generates 1 million random numbers and displays their distribution. Our sample reproduces the original MSDN sample, except it’s now running in JavaScript, in the browser.

Example (Deck)

The following output was generated, although will vary each time the sample is run.

10.0 to 10.1: 100,603 (10.06 %)

10.1 to 10.2: 99,630 (9.96 %)

10.2 to 10.3: 100,008 (10.00 %)

10.3 to 10.4: 99,623 (9.96 %)

10.4 to 10.5: 99,769 (9.98 %)

10.5 to 10.6: 100,418 (10.04 %)

10.6 to 10.7: 99,879 (9.99 %)

10.7 to 10.8: 99,681 (9.97 %)

10.8 to 10.9: 99,854 (9.99 %)

10.9 to 11.0: 100,535 (10.05 %)

Credits to the active Bridge Community member @michaelcheers who submitted a pull request with an initial draft of the Random Class Support implementation. In the end we didn’t merge the pull request, but it pushed us to implement an alternative technique that we had been thinking about for a while.

Custom bridge.json Config Files

It is very important to be able to configure globally as much as possible and we keep adding features in this area. In particular with Bridge 1.12 we’ve added custom bridge.[Release|Debug|Any].json configuration support (Issue #1033).

This now means it is possible to configure custom bridge.json files for specific Build modes.

If your project has the default Release and Debug build modes, you can now define separate bridge.json files for each build mode, as well as a default bridge.json file for common configs of all build modes.

bridge.json

Common configurations applied to all build modes. bridge.Debug.json

Configuration only applied during Debug mode compilation. Takes precedence over the same settings if configured in bridge.json. bridge.Release.json

Configuration only applied during Release mode compilation. Takes precedence over the same settings if configured in bridge.json.

The config file name is case-sensitive. For example, if the build mode name is Release, the file name must be bridge.Release.json, and not bridge.release.json.

Let’s consider a scenario using two global bridge.json settings: output and generateDocumentation.

The output setting configures an output folder path for compiled JavaScript. In our scenario we don’t need to target different output folders based on build modes, therefore we can add as a common bridge.json setting.

The generateDocumentation setting is used to manage inclusion of JSDoc compatible documentation. In our scenario, the project requirements call for documentation to be generated with Release builds, therefore we add the setting to bridge.Release.json.

See the Global Configuration Knowledge Base article for all the available global Bridge Compiler settings.

The screenshot below demonstrates how the configuration files should look in our scenario.

Custom bridge.json files are not limited to Debug and Release build modes. If you have a custom build mode, for example Staging, just add a bridge.Staging.json file.

IE8 Dropped

As of Bridge 1.12, IE8 support has been dropped. Most JavaScript libraries have already dropped IE8, such as jQuery, React and Angular, as well as Microsoft itself, so we’re not really treading new ground here.

As we’re no longer being held back with legacy IE8 support, several significant performance enhancements within Bridge and an API cleanup were triggered by the removal of several hacks or restrictions. One of the nicest enhancements has been the replacement of inline Bridge.get() calls for static properties with a centralized Object.defineProperty definition. (Issue #1050).

Before officially dropping IE8, we polled the Bridge Community in our forums and GitHub, as well as on Twitter. The poll results were 94% for, and against 6%. The decision was obvious. Goodbye IE8.

New Enum Attribute Options

A recent feature request uncovered a lack of convenient settings in how to manage Enum constants that are emitted by the compiler.

By default Bridge follows JavaScript naming conventions in the compiled output and defaults to lowercase first characters of member names, such as: methods, fields, Enum constants.

The user’s requirement was to preserve the case of emitted Enum constants. There is an existing Name(false) attribute which is an easy solution, but it must be set on each Enum constant. Not a problem if an Enum has only a few options, but totally inconvenient and polluting if there are many.

Bridge 1.12 makes the task easier with introduction of Emit.NamePreserveCase. In the sample below you can see the difference between the old and new notations. ShapeOld and ShapeNew Enums produce the same JavaScript code, but the C# source code of ShapeNew is much cleaner.

In addition to Emit.NamePreserveCase, we’ve also added Emit.NameLowerCase and Emit.NameUpperCase options. This job was completed in Issue #1059.

5500+ New Unit Tests

5576 new unit tests has been added to the Bridge Test Project, a 70% increase from the 1.11 release.

The total amount of test assertions is now 13300. The more tests — the higher the quality. We ensure each bug fix and new feature added to Bridge is covered by unit tests, and this massive Unit Test collection will ensure backwards-compatibility as we move forward with our upcoming core compiler improvements.

Since the beginning of Bridge, the project has been under intensive development. Huge features are being added in a continual stream, and we’re regularly improving performance within the Bridge Core. The only guarantee these enhancements do not break something unforeseen is to have excellent unit test coverage.

On the team we have a dedicated member responsible for Continuous Integration and Quality Control. It’s a high priority for us, and helps provide the Bridge Community with a truly professional quality platform.

Live Bridge Enhancements

A couple of annoying bugs were fixed in Live Bridge. The bugs caused various weird issues, such as code samples compiling for some reason in Live Bridge, but not in Visual Studio. The problems were isolated and fixed.

While fixing these bugs we also improved rendering of errors if they’re thrown during compilation. Descriptive messages are now bubbled up to the output window which helps the developer isolate and correct syntax errors.

Thread.Sleep

A basic implementation of Thread.Sleep has been included in Bridge 1.12, mostly to simplify testing of C# code samples that mimic a long running process. Our implementation is probably better described as Thread Blocking, as it doesn’t actually reproduce the same functionality as Thread.Sleep within a C# application.

Example (Deck)

The following output was printed to the browsers console:

0

2000

You shouldn’t actually be using Thread.Sleep within your app. We’re only including within Bridge to provide C# API compatibility and mocking of the native C# functionality.

Need a deeper understanding of why Thread.Sleep is a bad idea? Read this.

PRO TIP: If you need to delay execution of a Method without blocking the thread, in native JavaScript a great option is using the setTimeout function. The following sample reproduces something similar to the Thread.Sleep sample above, but taking advantage of the non-thread blocking SetTimeout Method in C#.

Example (Deck)

The following output was printed to the browsers console:

0

Waiting…

2000

For more sophisticated API on delaying execution of a Method, please checkout the next section dedicated to the Timer class support.

We give you the tools, but cannot protect you from yourself. If you block the main thread (the only thread) in JavaScript, you’ll lock up the interface. This is bad.

Need asynchronous non-blocking operations? Experiment with SetTimeout, or dive into using the C# async and await actions that are fully supported within Bridge. Read more in our Asynchronous Programming Knowledge Base article, and check out the cool Async sample in Live Bridge.

Timer Support

Issue #1013 triggered an implementation of the System.Threading.Timer class which provides a mechanism for executing a Method at specified intervals.

Important Note: The native .NET System.Threading.Timer class is intended for use as a server-based or service component in a multi-threaded environment. Since JavaScript is a single-threaded environment, the Bridge Timer implementation is limited to a single thread and not intended to mimic multiple threading in any way.

That said, the Timer class is useful in the single-threaded environment. Delayed execution of a Method is a very common requirement and the Timer class provides a convenient and sophisticated API for the Bridge developers. Other than the single-threaded limitation, the Bridge Timer class exactly reproduces the .NET Timer API. The sample below demonstrates the API highlights, with instructions in the comments.

Example (Deck)

The sample Timer is initialized to trigger the callback Method every second. After 5 seconds, the interval is reconfigured to 2 seconds. If the Timer works more than 10 seconds it is stopped, then disposed. To monitor the callback Method executions we output the elapsed seconds on each execution proving the sample works as expected. You are welcome to test it Live.

Contributors

We want to extend a huge thanks to the Bridge.NET community for contributing code, ideas and energy to the project. The community is growing every day and we would like to point out a few community contribution highlights from the last development cycle.

A relatively new community member, @Dia6lo, stepped in with three amazing pull requests. HTML5 WebSocket API support has been merged into 1.12, as well as a fix for a couple Window.Location issues. One more pull request with an .NET WebSocket API implementation is slated for the next 1.13 release. @Dia6lo, thank you very much from all the Bridge Community!

One of the earliest adopters and biggest fans of Bridge, Dan Roberts (twitter, GitHub, Bridge forums) has contributed to the Bridge world an epic series of blog posts on writing React JS apps using Bridge: Part 1, Part 2, Part 3. We encourage everybody to learn more about Dan’s Bridge.React and ProductiveRage.Immutable libraries. Unleash the power of .NET and C# for React JS applications.

@michaelcheers, thank you very much for a nice pull request with a draft implementation of the C# Random class. It really helped us to introduce Random class support into Bridge.

Check out this epic bug report by @t-nelis. If @t-nelis or @ProductiveRage report a bug, we snap to attention. They’re always packed full of helpful explanations, implementation details and valued opinions. Thank You!

It’s so great when a community member helps other community member, as our active forum member @Suchiman did recently within this forum thread. Bridge is an open-source platform and we’re excited to see the community grow by building upon the successes of its members. @Suchiman also provided us with several excellent bug reports, suggestions, and helped with testing the fixes.

A big thanks also goes out to @Simon, @kcudnik, @danw, @michaelcheers and many others.

You’re Awesome!!!

Summary

Following the pattern of previous Bridge.NET releases, there was a lot packed into 1.12. Much more than we can document in a single blog post. For a complete list, please review the Closed Issues for details of all fixes and features.

Now get out there and Build Something™.