JSFiddle - React, Tailwind, and code Playground

HTML

<script src="https://raw.github.com/SteveSanderson/knockout.mapping/master/build/output/knockout.mapping-latest.js"></script>
<span data-bind="text: itemProtected"></span>
<button data-bind="click: commit">Commit</button>

JavaScript

//wrapper for an observable that protects value until committed
ko.protectedObservable = function(initialValue) {
    //private variables
    var _temp = initialValue;
    var _actual = ko.observable(initialValue);

    var result = ko.dependentObservable({
        read: _actual,
        write: function(newValue) {
            _temp = newValue;
        }
    });
    
    //commit the temporary value to our observable, if it is different
    result.commit = function() {
        if (_temp !== _actual()) {
            _actual(_temp);
        }
    };

    //notify subscribers to update their value with the original
    result.reset = function() {
        _actual.valueHasMutated();
        _temp = _actual();
    };

    return result;
};

ViewModel = function(data) {
   this.itemProtected = ko.protectedObservable();
   return ko.mapping.fromJS(data, {}, this);
}

ViewModel.prototype = {
    commit: function() {
        this.itemProtected.commit();
    }
};
    
var data = { itemProtected : "protected" };
ko.applyBindings(new ViewModel(data));