Reflex-Based Web Monetization API - Hackathon Submission
Tags: gftwhackathon, webnative, chtml, scopedjs
Published: 2020-06-15 05:07:12

The Web Monetization API has seen a lot of integration patterns that are tuned to many of the current frontend frameworks and developer tools. With each pattern serving only a specific community, I decided to explore a vanilla-level technology for Web Monetization for the rest of the web.

## What I built
A [Reflex-based](https://docs.web-native.dev/reflex) Web Monetization API that is consumable as a **plain**, but **reactive** JavaScript object instead of an `EventTarget` interface. This is a new API that promises new foundational possibilities! [Here](https://dev.to/oxharris/reflex-based-web-monetization-api-5241) is my introductory DEV post to this project, where I explained key problems solved and a few use cases.

To highlight, the goal of this project is to provide a **minimalist API** that lets us implement web monetization with zero boiler plate.

```js
// You initialize a WebMonetization instance with a payment pointer
let monetization = WebMonetization.init('$ilp.example.com/me');
```

That instance object will now be a joy to consume! For example, instead of the mental stress of maintaining the relationship between the standard `document.monetization.state` property and its three state-change events (`monetizationpending`, `monetizationstart`, `monetizationstop`), we would simply observe this object's `.state` property directly.

```js
// Observe the state property live
Reflex.observe(monetization, 'state', newState => {
    console.log(newState); // pending, started, stopped
});
```

If we were to need dynamic start and stop of the payment stream, we wouldn't have to worry about dynamically creating and removing the appropriate `<meta>` tag. The `monetization.start()` and `monetization.stop()` methods automatically take care of that.

And what about tracking progress and deriving totals? The `monetization.progress` would come into play.

```js
// Observe the progress property live
Reflex.observe(monetization, 'progress', progressDetails => {
    console.log(progressDetails.currentTotal); // Totals since calling the instance's start() method
    console.log(progressDetails.sessionTotal); // Totals since initializing the instance
});
```

An observable object just gives us only properties to think about - in reading their values both statically and dynamically.

```js
// The totals at any given point in time
console.log(monetization.progress.currentTotal);

// The totals on the fly
Reflex.observe(monetization, 'progress', progressDetails => {
    console.log(monetization.progress.currentTotal);
});
```

Now, what's even more interesting is that in real life, we can do without observing anything! Observable objects like this are the perfect subjects for the [ScopedJS](https://docs.web-native.dev/chtml) technology! We can simply bind any elements to properties of these object to achieve any UI behaviour. ScopedJS's automatic observability will do the heavy-lifting of keeping everything in sync.

First we would make the WebMonetization instance available to scoped scripts.

```js
let ENV = window.WebNative.ScopedJS.ENV;
ENV.globals.monetization = monetization
```

And we could simply orchestrate behaviour in the document on the fly!

Here is an example taken from the [introductory post](https://dev.to/oxharris/reflex-based-web-monetization-api-5241) where we toggle the visibility of an exclusive section on the page by simply referencing the `monetization.state` property.

```js
<body>
    <div id="exclusive">
        This is exclusive content!
        <script type="text/scoped-js">
          // This statement will run as a reflex action
          // to each change in monetization.state
          this.classList.toggle('hidden', monetization.state !== 'started');
        </script>
    </div>
</body>
```
And as other examples in there show, we could go to weave-in more monetization logic as part of our UI's presentational logic.

### Submission Category: 
Foundational Technology

## Demo
The *project support* banner at [web-native.dev](https://web-native.dev) featuring Web Monetization was implemented using the Reflex-based Web Monetization API.

## Link to Code
This API is currently primarily documented in the [introductory post](https://dev.to/oxharris/reflex-based-web-monetization-api-5241). An official documentation will be arriving soon for the entire list of [Reflex-based components](https://docs.web-native.dev/reflex-components) at Web-Native.

Repository: {% github https://github.com/web-native/reflex-components %})

## How I built it 
I am creating this project as part of the [Web-Native project](https://web-native.dev) - a larger mission to make certain modern UI development techniques possible at platform level. With the Reflex-based monetization API now part of the Web-Native suite, we now have an all-native way to designing the UI.
+ **Write in Vanilla.** - Leave your markup in vanilla HTML - not even a template syntax is required. And yes! none of a framework code (`<IfWebMonetized>...</IfWebMonetized>`) that would look simple on the eyes but incur unnecessary tooling and engineering, and the inevitable  compile step.
    And, probably one of the most important advantages with a markup-level technology, this implementation makes code more universal! It lets us integrate seamlessly with other wonderful tools that *read* and *write* HTML. So, instead of the lock-in with an all-JS stack, a PHP backend that *spits out* HTML could be everything.
+ **Write your Logic.** - The Reflex-based monetization API is not some `<custom-element />` that would encapsulate only a **predetermined behaviour**. It works along with the [ScopedJS](https://docs.web-native.dev/chtml) foundational technology that provides platform-level capabilities for creating anything, offering more flexibility and control.
+ **Maintain the Modern UI Development Pattern.** - We simply cannot remember a time without **componentization** and **reactivity** anymore! Bringing the Web Monetization API to vanilla HTML does not trade these patterns either. What we get instead is **Web Monetization** plus **componentization** plus **reactivity** - all out of the realm of JavaScript files! (You may want to check out [CHTML](https://docs.web-native.dev/chtml) for the rest of the news.)

## Additional Resources/Info 
The overall theme of this project is provided by the [Web-Native](https://web-native.dev) project.