Friday, April 17, 2015

A WeakMap Polyfill in 20 lines of code

In case you missed my yesterday post, we finally have a widely compatible cross engine poly for Object.getOwnPropertySymbols(obj).
What I've also tried to epxlain in the very same post, is that Symbol unlocks new patterns for "secret" properties definition, and the following little WeakMap is just one example on how symbols can be used to relate data we don't want to show in other common ways.

OK, maybe is not the most perfect polyfill we can have ... but you've got the idea on what could be done through Symbol variables ;-)

Thursday, April 16, 2015

Bringing Symbols to ES5

TL;DR After few tests, considerations, and some brainstorming, I've decided to push get-own-property-symbols to npm and make the code available for browsers too.
I know there was already a module, but in order to fix weird problems I know and probably only I can test, and in order to add Object.getOwnPropertySymbols too, a method that MUST exist the moment we have Symbol primitive in, I thought that having an alternative instead of replacing current ES6-Symbol module would have probably been a better option.

Before Symbols

Since ES5, JavaScript objects have the ability to somehow hide properties through non-enumerability.
var o = {};
Object.defineProperty(o, 'hidden', {value: 123});

for (var key in o) {
  // nothing will ever happen ...
}

Object.keys(o); // []
// empty Array
Another example of non enumerable property is the length of any Array.
In order to find these "hidden" properties, we need to use Object.getOwnPropertyNames.
var o = {};
Object.defineProperty(o, 'hidden', {value: 123});

Object.keys(o); // []
Object.getOwnPropertyNames(o); // ['hidden']
The convenience, when it comes to define properties in the ES5 way, is that we can always directly access a property, and simply writing it as it would be for o.hidden or o['any other property'].

Introducing Symbol([description]) Basics

Directly from the MDN page
A symbol is a unique and immutable data type and may be used as an identifier for object properties.
What else is unique and immutable in JavaScript? Any primitive string as example is, and symbols are indeed very similar to regular strings used as objects properties accessors.
var o = {};
var k = 'key';
var s = Symbol();

o[k] = 123;
o[s] = 456;

typeof k; // string
typeof s; // symbol <== !!!
If we'd like to compare normal properties with symbol properties, here a quick summary:
  • o[string] = value creates a configurable, writable, and enumerable property, while o[symbol] = value creates a non enumerable, configurable, and writable one
  • Object.keys(o) will return all enumerable properties, excluding then symbols, together with other non enumerable properties
  • Object.getOwnPropertyNames(o) will return all enumerable and non enumerable properties, still excluding symbols
  • both strings and symbols can be used to define properties and to retrieve properties descriptors
  • String() === String() but Symbol() !== Symbol(), and even using a descriptor, a symbol is always different from another one, unless Symbol.for('symbol name') is used, which is always the same symbol, providing the same label/name.

So ... What Are Symbols About ?

Here a quick list of benefits regarding the usage of symbols instead of regular strings:
  • symbols are great when it comes to create conflict free properties accessors, create your own Symbol in your closure and use it to set or read specific properties related to that closure
  • great also for globally shared, conflicts free, libraries and utilities behaviors, if some library exposes its Symbol.for('underscore'), as example, every method of such library, and every plugin defined elsewhere, could eventually read the associated data
  • symbols have zero interferences with most common libraries, since developers can easily ignore them and these won't be on their way via common ES3 or ES5 patterns
  • accordingly, symbols are usable to easily define even more hidden properties than what enumerable: false has done until now
Here a simple example on how we could link any kind of data to an object, and without needing a WeakMap:
function link(object, key, data) {
  var s = Symbol.for('@@link:' + key);
  return arguments.length === 2 ?
    object[s] : (object[s] = data);
}

// generic object
var view = {};

// generic node link
link(object, 'node', document.body);

// retrieve the node any time
var body = link(object, 'node');
Another useful example could be a simplified EventEmitter constructor:
var EventEmitter = (function (s) {'use strict';

  function EventEmitter() {
    this[s] = Object.create(null);
  }

  EventEmitter.prototype = {
    on: function (type, handler) {
      return (
        this[s][type] || (this[s][type]=[])
      ).push(handler) && this;
    },
    off: function (type, handler) {
      return this[s][type].splice(
        this[s][type].indexOf(handler), 1
      ) && this;
    },
    emit: function (type, err, ok) {
      return this[s][type].forEach(function (h) {
        h.call(this, err, ok);
      }) || this;
    }
  };

  return EventEmitter;

}(Symbol('event-emitter')));


// basic test
var log = console.log.bind(console);
var e = (new EventEmitter)
  .on('log', log)
  .emit('log', Math.random())
  .off('log', log);
Above example is probably the tiniest emitter implementation I could imagine ... and all thanks to Symbol, how sweet is that?
You can also implement a WeakMap polyfill in few lines of code.

Polyfill Caveats

Well, the first caveat is that Object.create(null) dictionaries, as well as those created via {__proto__:null}, will not work as expected. Symbols would be set as generic keys in there so, in case you need symbols, be aware of this limit and bear in mind all other shimms and polyfills have same limit.

The other biggest inconsistency with native Symbol is that typeof will return string and not symbol.
If we need to perform such check, here a little utility that can help:
var isSymbol = (function (cavy) {
  return function isSymbol(s) {
    switch (typeof s) {
      case 'symbol': return true;
      case 'string':
        cavy[s] = 1;
        var isit = Object.getOwnPropertyNames(cavy).indexOf(s) < 0;
        delete cavy[s];
        return isit;
      default: return false;
    }
  };
}({}));

isSymbol('');       // false
isSymbol(Symbol()); // true
These two are the most inconsistent points I have but the good news is: yayyyyyy, we've got Symbols in basically every bloody browser and JS engine!

Tuesday, April 14, 2015

After 2 weeks on Ubuntu phone ...

I've recently bought a BQ Aquaris E4.5 phone which features Ubuntu and has dual SIM ability.
This is a personal but honest review on the platform, rather than the phone itself, and what I believe should be improved to make it competitive.

The Pros

Let's start with the good parts from a user perspective POV, so that we can better understand the cons.

Nice design

The Aquaris E4.5 is a relatively cheap smart phone but it doesn't fell like that: the shape is simple and functional, materials feel OK and it's not like those huge phones where you need two hands to do anything 'cause too big (although if you have small hands like I do, you might end up with two hands anyway but it's OK).

Dual SIM

I travel a lot and I have two main SIM cards, a UK one and an Italian one. The UK one from three is IMO a must have in Europe for the simple reason you are not charged extra if you visit one of those 18 "feel at home" countries, including most European and also USA!
No extra charges on data roaming, which is a huge win. However, my Italian phone number is still very active and used, having no need to carry two phones and reach all I need from one device is a big win too.

The native part of Ubuntu OS is OK

The OS itself feels OK and it's a good "no need to RTFM" system. It's also often pleasant to discover its hidden, user experience oriented, functionalities.
There are few things done really well, original, and extremely practical like the top bar with top-to-bottom and left-to-right surfing, which aim is to provide access to a list of common features and info behind a freaking easy to use interface, you might find yourself surfing all the icons for minutes without a real need ... just because that feels right.

The battery is OK

Even handling dual sim 24/7, and considered how much of the OS is based on HTML5, JavaScript, and CSS, and how much functionality is brought by online mobile websites such here, facebook, and twitter, I'd say I'm quite happy about the battery consumption, and I was expecting a half-day lasting device, considering that's more or less how much first FirefoxOS phones were lasting at version 1.0.

Somehow snappier than FirefoxOS

Ubuntu OS is a hybrid one and the native part is very snappy. The Qt and QML platform has been showing muscles since about ever in the mobile world, I'm actually very happy this was the choice instead of Android Java one, 'cause while I never enjoyed writing and developing with Java, I've been freaking creative and productive with QML without any need to be a guru: you have native declarative UI powered by nice APIs and JavaScript logic.
Qt and QML also work already in any platform so if you want my suggestion: go and learn how to make apps in QML, you'll have a way bigger set of skills to re-sell in the market, you develop natively with ease, and you learn something already integrated in all the things.

Almost everything I need is there

The second thing that is missing these days is WhatsApp. However, thanks to Ubuntu phone I've discovered Telegram, and switched to it by default everywhere because it's fast, free, and available for Desktop too, even my Linux one. My friends and family? They installed Telegram too and never even noticed we were on a different app while exchanging messages.


There's not much else to say here, and I've already stretched my real feelings with previous pros ... it's time now to get real and discuss all the cons that made me think to go back to my old setup, which was a slow 2+ years ago old Lumia 620 and a not so powerful Android phone as companion for the other SIM ... yes, it has been that bad ...

The Cons

Even if as debut I have to say it's better than FirefoxOS one, I'm afraid there are too many problems no regular user would ever want to use it. No, I'm not being too hard, there are broken aspects of the entire HTML5 that is not even a Ubuntu phone fault, rather a reflection of how broken is the Web thanks to poorly developed services entirely based on broken User Agent sniffing.

The Web Is Broken

This is the thing number one: the amount of websites that redirected me to play.google.com store, offering me an Android App to download, are countless. Linkedin, Google itself with its calendar, reached through the native wrapper GMail App, ... this is not some wannabe/week-end web developer from the late 90's, these are biggest online brands and services I know. The fact I'm on a phone that uses like Android in its User Agent string, means that every bloody online service with an Android equivalent App will assume you are on Android and will redirected to the store. The store will fail at installing whatever app it is, no matter if you logged in correctly, it will just fail. Regular users will always be fooled by such broken experience, and they will be blamed as ignorant even if they have no fault.
Windows Phone has similar problem
Since IE Mobile decided to include common UA sniffed strings in its latest browser, in order to avoid discrimination based on UA sniffing, instead of features detections, I've been redirected or proposed to install Android apps there too. This is where the Web is failing big times these days: developers introducing poor practices in order to fulfill the need to install at all cost native apps. This is so annoying and it's ruining the mobile Web. I don't know when, where, or how companies will realize that having a link to the native app, instead of having a link to the arleady visited Mobile Web version, would be way more useful than all these problems they are causing to their own users behind all these broken assumptions. Please STOP DOING THIS, thank you Corporates!

Where the F*%K! is the Calendar

Going out with a mobile Operating System that does not have a basic, native, Calendar application, is like buying a calculator that doesn't have the % button: are you bloody kidding me? I'm not even talking about something fully integrated with Facebook, Google Calendar, or anything that advanced, I'm talking about a native, offline capable, calendar, in order to save events and/or read them!
Google Calendar as wrapped online App is not an option because there are part of the world where Internet is not available, and there are cases when somebody might fly somewhere else and cannot even organize itself ... this is ridiculous and it was also probably the main point I want to go back to any other option available. Can I develop one by my own? Sure ... also, is there some app in the store? Sure again, but I'd expect that in 2015 calendar would be the show-stopper, must have, App as natively integrated, developed, and maintained. Come on folks, put it there ASAP, thank you!
Update
Apparently there is a Calendar app developed by Canonical for Ubuntu core (not the Google one, just the Calendar one with number 28 on it).
I'm still puzzled on why this App hasn't been included by default in this OS ... PLEASE ADD IT, THANK YOU!

HTML5 Apps VS HTML5 Web

In the last 6 years I've been core developer for what's today known as m.here.com, the default (amazing) Map Application that powers FirefoxOS and Ubuntu Phone, I've worked a little bit on m.facebook.com, and worked on mobile.twitter.com. What I'm saying is that I'm proud HTML5 already made it, despite what the rest of the world says, and it works like a charm. However, while here Map, together with Gmail one, feels like a real native app, Facebook and Twitter are just a redirect to the browser, meaning the top URL bar will comes up and down all the time while scrolling your feeds and content. Annoying to say the least. The real problem though, is that there's no hardware button to go back so while Facebook nd Twitter are more friendly and easy to navigate when a back is meant, since the button is on the browser, Gmail, more than Here, is a very unfriendly App to use. If there's no previous button, you won't be able to go back.
HTML5 Apps sometimes badly integrated
If you receive a notification about an email, and you click the little icon on the right, because clicking the entire notification has surprisingly no effect whatsoever (WTF UX!), your GMail wrapped Web App will launch and you'll be right at the very beginning of the email, not at the last one, or the one you've been notified about. This is rather confusing and inconsistent with any other email app in this world.
I'm not saying this is Ubuntu Phone fault, I'm saying if you are offering by default HTML5 versions of an App, be sure that works as expected otherwise people will think your phone has something wrong, same way I am doing it here.
In case of here maps, the ability to share links and be right there where meant is a core feature, it works even via SMS so no problems there, but back to Twitter, as example, you'll find yourself in the browser again, instead of the native initial wrapper. All these inconsistencies are very confusing, I wish native Ubuntu wrappers were more like PhoneGap, exposing special abilities so that developers can create more native-like experiences.
Simply wrapping a mobile Web link might not be enough.

Scope hard to navigate

Maybe this is a "not so big" screen issue, but in scope there are too many possible swipes:
  • pull from the edge for notifications
  • pull from under the edge for updates
  • left and right from the pulled down notifications for notifications read
  • left and right on the screen for scopes sections
  • left and right on scope sections for horizontally scrolled content such news and stuff
  • right edge to left for tabs/app navigation
  • left edge to right for the main vertical bar
You'll inevitably fail at some point doing one action instead of another, I can bet on it whatever you want. I've had to "go back and re-try" many times that this navigation system started being a bit annoying. It's OK when it works as you expect, but it needs some fine tune or it will end up in an annoying experience, instead of an improved one.

Flight mode shenanigans

This comes from the core of the OS too the flight mode is full of surprises! If you have the Bluetooth off and you switch to Flight mode, you'll find the Bluetooth ON once you switch the flight mode off. This might look just like a simple bug from the surface, it scares the hell out of me, as developer, because it means Ubuntu Phone has a broken state-saving logic behind the scene. Flight mode should save the state of the phone before, and put it back after. Bluetooth is not the only thing broken ... but it's the most visible one.
As example, flight mode off and on broke the GPS state and it also randomly breaks main SIM network data. There's something terribly wrong behind this feature and form me the solution was to never use it, and switch the phone off and on instead.

Irony wants that the "once used master point to switch to Linux" motto is now the only way to be sure this phone works as expected. I've also missed few important calls and emails from the main SIM card because the phone was completely stuck only for the network part. To unlock the phone I had to turn it off and on ... I don't want to be worried that my phone is stuck at all ... I never want to be worried about this.
I'm sure these might be partially phone specifications problems, partially the fact Ubuntu Phone is at its debut ... but if there's one thing I expect from both Linux and a Phone is stability for the network part, end of discussion.

Randomly poor performance

Like I've said the native part is snappy, but sometimes it's very unusable. This is similar in not so powerful Android phones, when there are updates behind the scene and your App starts going 2FPS ... it happened to me while I was playing the Pathwind game installed by default. It's a simple nice game that could entertain but it's very easy to fail if the phone goes at snail speed for few seconds.

Notifications in the wrong spot

This the last point for this review: the notifications icon is in the worst spot ever. If you have the screen rotation locked, 2 SIMs where one shows for some reason Roaming all the time even if not roaming (no, I hope it's not roaming because I've set it as not roaming, why on earth I've the roaming icon always there ... I've honestly NO IDEA!) and you are on WiFi, with an alarm set, and the GPS icon also shown all the time for no actual interesting reason, your notifications icon will be on the very top left edge, the edge where the main OS Applications bar comes up too, and most of the time you have to fix your mistake in order to read them. The pattern I'm following now is pull down from the top edge center, and scroll left 'till the notification area. At first it was my "aha" moment, followed by "oh nice, cool" ... now it's just annoying and it takes ages, but it never fails, intent speaking.

As Summary

I've been using Android since version 1.5, iOS since version 5, Windows Phone since version 7, and FirefoxOS since version 1. I develop and test in all these devices and I've never felt in love with any of these. I had huge expectations from the Ubuntu phone due the respect I have for Canonical and the community behind Ubuntu, and the fact I'm a huge believer in Open Source and indeed everything I have and use daily is Open Source, including "my personal OS". Ubuntu could have been the missing Open Source part I've been looking for, when it comes to Smartphone. FirefoxOS is great but it still has too many constrains that come from the Web, like pointless security privileges needs I don't care when it comes to my phone. Ubuntu and its QML native ability goes beyond any Web based only App, providing the ability to do the hack I want as developer, instead of waiting for some standard to land or be promoted from Mozilla. QML is a huge possibility for developers, and a hybrid OS like this feels also better than Blackberry 10, which I also owned for a little while and honestly was a much better experience for 3 times the cost of this phone. Yet not the OS I was looking for.
I still have big expectations and hope they'll improve the OS and catch up with Apps soon ... for now though, I think I'll go back to my old configuration, and try again in 6 months.

Wednesday, March 25, 2015

Dart officially as Yet Another Transpiled Language

This is a great news for the Web: no more effort behind Dart VM, only to the language itself as transpiled to JavaScript.
This puts Dart as just another language like CoffeeScript, TypeScript, or any other that will desugar to JS.

Why this is good for the Web

The Web is far-far-far-far-away from being a perfect rock-solid platform, and simply the idea that every browser vendor should have put effort to create even more fragmentation on the Web due multiple integrated VMs has been worried me since the very first Dart announcement: thanks gosh it didn't make it!
On the other hand, having Dart only as transpiled langauge means there will be more effort in transpiled languages tools, including better integration and better debugging possibilities for Web developers ... and This Is Cool!

Update

While it's confirmed that Dart won't bother the Web with its VM anymore, the language and its VM will still work on the server and other places.

Toward ES.next Anyway

It wasn't just me noticing that in the last years Dart never impressed or show better muscles, and if it has to desugar to JS then I might be the only one here but how about we just learn JavaScript instead? OK, somebody probably liked Dart, as somebody likes TypeScript, CoffeeScript and others ... and this is a free world so do what you think is best for your projects, but also ... @AlwaysBetOnJS!

Tuesday, March 24, 2015

Ain't that fetch!

Update II
It turned out that Microsfot did what was the simplest way to provide Streams for developers, it simply used what was there already, and exposed within the readystatechange listener. That's a great, easy, and pragmatic solution for IE10 and above. I wish other vendors were like IE ... oh, irony!

Update I
Arthur Stolyar, aka @nekrtemplar, just explained in his gist why he's also disappointed about fetch. To cite his words:
I am not a "One particular high-profile JavaScript community member was unconvinced" or a spec's expert. I am a regular JavaScript/Front-end developer and this is how I see it from my point of view.
His technical explanation is even more detailed than mine so I suggest a read.
Chrome Canary is already exposing a fresh new Fetch API that has been empathized in this clarification post from @jaffathecake.
I've promised him I would have written a counter argument on why not everyone, or at least me, did applaud it.
I will try to answer point after point, providing also my point of view but before starting it's obligatory to underline that nobody is trying to block anything but hopefully the entire thing will be rolled out complete and ASAP with all details in.

Events VS Promises

The first provided example in Jake page talks about a massively improved API. It shows some basic XHR logic I'd like to reproduce under a different light:
var xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.responseType = 'json';
xhr.onload = () => console.log(xhr.response);
xhr.onerror = () => console.log("Booo");
xhr.send();
Above 5 lines of code have been described in the original, not arrow->function, example as some vomit to mop up 'cause the new thing looks way better:
fetch(url)
  .then(r => r.json())
  .then(data => console.log(data))
  .catch(e => console.log("Booo"))
;
The example ends up in a rather confusing block for ES7, not sure this is a "back to vomit" thing or not ...
(async() => {
  try {
    var response = await fetch(url);
    var data = await response.json();
    console.log(data);
  } catch (e) {
    console.log("Booo")
  }
})();
If we talk about lines of code, fetch wins, but if we talk about clarity of intent can I say XHR has the best?
  1. it's a GET, not a POST, PUT, HEAD, or others, it's clearly and explicitly a GET
  2. it comes with listeners, meaning it has onprogress included for bigger data
  3. it comes with .abort() as explicit intent, and the ability to add an onabort in order to react
I will come back to the latter point but here we have yet another competition between Events and Promises, when of course Promises, on top of events, can be used to generated simplified APIs, but comparing them is like comparing apples and oranges: Promises and Events are not mutually exclusive patterns, it's the exact contrary: these can be used together, and indeed, being events more suitable for recurring invocation of the same callback during some streaming operation, it's not that we can blame Events to have an ugly API there, we simply need them.
My point here is that wrapping XHR through a Promise was already possible and it has been done already so this does not seem to be a reason to applaud this latest API, no clap clap here, I am sorry, not for this.

It isn't done yet

When I've read this part:
What exists in Chrome today doesn't cover the full spec, and the spec doesn't cover all of the planned features. In some cases this is because they haven't been designed yet, in others it's because they're dependent on other in-progress specs.
I could not help myself thinking about a tweet of mine, posted few days ago:
@dfkaye what I think is that first few lines of any new proposed Standards body API should be about "what real-world problem is this solving"
So I'd like to understand if new APIs just come out "because" or if there are real reasons behind for pushing these out.
I am 100% sure that WHATWG does its best, it works hard as a group, and the aim is to provide top notch solutions for our daily needs, but honestly ... to quickly answer to the following Jake disappointment:
Bit of a rant: it bothers me that as developers, we preach iterative development and release, but when we're the customers of that approach the reaction is all too often "HOW DARE YOU PRESENT ME WITH SUCH INCOMPLETE IMPERFECTION".
The way I felt about this was rather like the following: (which is just a satiric parody in my mind)
  • Some guru at WHATWG: we need a better version of XHR
  • Her colleague: Totally, how should we start?
  • Some guru at WHATWG: let's think about a simplified entry-point API to start with
  • Her colleague: Totally, gotta Fetch em'all via Promises!!!
  • Some guru at WHATWG: well, actually something that .. you know ... Network, something cancelable by default ...
  • Her colleague: Totally, gotta Fetch em'all via Generators!!!
  • Some guru at WHATWG: ... yeah right ... let's stick with the first idea that breaks only the Promises principles in ES6 ... and re-iterate down the road
And again, the way I see that picture is like:


Because the thing has been planned from the scratch without breaks in mind!

Having the ability to stop a download, a streamed content, or an upload for the wrong image, should have been the very first thing to think about for a new Network based API, riight?
I am simply astonished the entry point for the new XHR replacement has already a somehow limited/broken heart since the beginning and for the entire ES6 era, because as far as I know native Promises cannot be canceled (yet, 'cause they will eventually ... they have to!)
I wonder then if this is really the right way to roll out new APIs ... so that we are forced to rush solutions in order to be able to improve also a core problem in Promise-land?
Where was the announcement that a new Network API based on Promise was coming? Have I missed that? The answer is probably yes, since it's even in the specification, but then can I say I wasn't again see that coming at all?

Developers VS Standards

To keep answering Jake disappointment, as a developer I want to trust that standard bodies will choose the right tool for the job.
I like all open channels, I like the iterative model, but I don't honestly have time to be the supervisor for everything so my apologies if I haven't read every single thing people paid to write out published.
As a developer, I'd also like to trust standard bodies that if I've learned something already, like the XHR Level 2 API, and if an API has already been updated for a nice to have upgrade as onload and onprogress were, maybe just a tiny extra update to bring onstreaming would have made such API even better and we could have let libraries and wrappers deal with the best approach to Promisify all the things and implement once de-facto standardized (obligatory mention to querySelectorAll indeed).
This is not me complaining about nicer, easier looking APIs, this is me wondering what's the rush about and why so many steps at once as in the Fetch API and everything else around it.

Not All Disappointing After All

I've hopefully explained why at the very beginning I could not believe to my eyes but also thanks to Jake I've understood there are surrounding parts that come somehow for free like Streams, readers, no-cors, ServiceWorkers integration ( through events and addEeventListener :trollface: ) and more.
I honestly wish Streams where usable directly as row level API and probably that's going to happen or it happened already, and now that I know about all these things around "just fecth" I can't wait for all this to be fully out and not just a little bit, 'cause as it is, it looks Promising (dehihihi) but it's not worth using it yet due limitations, specially on the current initial cancel-ability (partially in or partially buggy here and there).

About XHR: Yes, It Is Still Good!

If we had a time to improve it, that wouldn't be 16 years ago ... that was Microsoft, not XMLHttpRquest, so I am not sure why Jake said that in his blogpost since first working drafts seem to be dated 2006.
However, XHR has been revolutionary for the entire Web and it also made eventually people aware of how the internet was working: not everything is a GET, you could PUT, POST, HEAD, and it has been used to create everything cool today about Google services, social networks etc etc.
It's already easy to do what it can do, so I wouldn't say it has been simplified because of a .then.
I can also still upload and drop while uploading images in Gmail, or TweetDeck, or somewhere else and entirely through XHR. I can post data, show progress bars, I can fetch JSON and do CORS. I can do pretty much everything but controlling streams ... and you know what? I think XHR deserves a bit of extra respect.
I wouldn't spit on something that is almost 100% consistently adoptable these days and without libraries, when most of the people just used it to GET some JSON and nothing else (reasons Promise like based Ajax calls became popular, most developers use 10% of XHR ability) for the last 10 years.
Accordingly, if there is one thing I absolutely don't like about that post, is the following sentence:
XHR was an ugly baby and time has not been kind to it. It's 16 now. In a few years it'll be old enough to drink, and it's enough of a pain in the arse when it's sober.
Come on Jake, XHR is still amazing, easy as hell to use, and it still has a lot to offer: abortability with optional reaction through listeners, good integration with Form data, progression, multiple listeners so it can notify multiple "chains" and everything else we know and used for the last 16 years indeed. If it was that bad, I am pretty sure it would have disappeared way before, and the Web as we know would have probably been behind ... don't you think?
Cheers